Skip to content

[APPS-2958] Add: list each action call's static inputs in the debugBundle response - #610

Draft
tyffical wants to merge 1 commit into
tiffany.trinh/apps-2958-debug-bundle-action-listfrom
tiffany.trinh/apps-2958-debug-bundle-call-inputs
Draft

tyffical wants to merge 1 commit into
tiffany.trinh/apps-2958-debug-bundle-action-listfrom
tiffany.trinh/apps-2958-debug-bundle-call-inputs

Conversation

@tyffical

@tyffical tyffical commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Architecture

flowchart LR
    C["Action-catalog calls in the bundle"] --> L["listActionCalls: connectionId + static string inputs per call"]
    L --> R["debugBundle JSON: actions[].calls"]
    R --> G["Frame guard: copy own fields, check types"]
    G --> P["run-query bundle to the parent"]
Loading
interface DebugBundleActionCall {
    connectionId?: string;           // absent when the call sets none
    inputs: Record<string, string>;  // inline `inputs` keys that resolve to a string
}

interface DebugBundleAction {
    fqn: string;
    connectionIds: string[];         // unchanged
    calls: DebugBundleActionCall[];  // new: one entry per call site
}
  • Additive: fqn and connectionIds keep their values.
  • Listed: a string literal, a template without expressions, or a top-level string const, local or imported. An object member is left out, since an alias or a call can mutate a const object unseen.
  • Left out entirely: every input, when the options or inputs literal has a getter, setter, spread, computed key, or a toJSON, then or __proto__ key, since serializing or awaiting the call could rewrite any key.
  • No new exposure: every listed value is a literal already in the same response's code.

Changes

8 changes across protocol.ts, list-action-calls.ts, the string resolver, type-guards.ts, the client guard, dev-server.ts and tests
What changed File
Add DebugBundleActionCall and calls on DebugBundleAction packages/plugins/apps/src/backend/protocol.ts
List each call's connectionId and static string inputs; a spread, computed key, accessor, toJSON, then or __proto__ empties the inputs packages/plugins/apps/src/backend/ast-parsing/list-action-calls.ts
Add resolveStaticStringConstant, which doesn't follow object members packages/plugins/apps/src/backend/ast-parsing/static-string-resolution.ts
Move getStaticPropertyKey and hasExpressionValue here and read numeric literal keys packages/plugins/apps/src/backend/ast-parsing/type-guards.ts, extract-connection-ids-from-module-graph.ts
Copy each call's own fields only and check them before posting packages/plugins/apps/src/backend/client/guards.ts
Pass the module records to listActionCalls packages/plugins/apps/src/vite/dev-server.ts
Cover literal, const, imported const, template, dynamic, object-member, hook-key, duplicate and numeric inputs list-action-calls.test.ts
Cover the frame copy and the updated debugBundle shape dev-client.test.ts, post-message-transport.test.ts, dev-server.test.ts, dev-server.integration.test.ts

QA Instructions

yarn build:all
# Expected: exit 0 ✅ VERIFIED

yarn test:unit packages/plugins/apps/src/backend/ast-parsing/list-action-calls.test.ts
# Expected: Tests: 33 passed, 33 total ✅ VERIFIED

TMPDIR=<a dir under /private/tmp> yarn test:unit packages/plugins/apps/src --testPathIgnorePatterns network-guard
# Expected: Test Suites: 44 passed; Tests: 1016 passed ✅ VERIFIED (macOS needs a TMPDIR outside /var; CI on Linux doesn't)

yarn test:unit packages/plugins/apps/src/vite/network-guard.test.ts
# Expected: Tests: 129 passed, 129 total ✅ VERIFIED (run without TMPDIR set)

yarn lint && yarn typecheck:all && yarn cli integrity
# Expected: all exit 0, integrity leaves no extra changes ✅ VERIFIED
  • Real dev server: the integration test bundles the twoActions.backend.ts fixture through Vite and reads /__dd/debugBundle as JSON.
yarn test:unit packages/plugins/apps/src/vite/dev-server.integration.test.ts -t "Should list the actions a real backend file calls"
# Expected: passes, with http.request's calls: [{ connectionId: 'conn-http', inputs: { url: 'https://example.com', verb: 'GET' } }] ✅ VERIFIED
Fail-before
  • With list-action-calls.ts, guards.ts and dev-server.ts restored to the parent branch and the new tests kept, 42 tests in the five touched test files fail: every listActionCalls input case, the two dev-server actions expectations, the dev client's call-copy cases and the transport's call-copy cases.

Blast Radius

  • No feature flag. Risk: Low. Only the dev server's JSON debugBundle response and the framed bundle copy change.
  • The frame's guard drops a malformed action list as a whole; the bundle is still posted.

Documentation

🤖 Generated with Claude Code

@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-action-list branch from c8122aa to 19ec355 Compare October 23, 2026 05:20
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-call-inputs branch from 768c620 to 7e7153c Compare October 23, 2026 05:20
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-action-list branch from 19ec355 to 447c145 Compare October 23, 2026 14:53
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-call-inputs branch from 7e7153c to 2806fd6 Compare October 23, 2026 14:53
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-action-list branch from 447c145 to bc68d52 Compare October 23, 2026 15:59
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-call-inputs branch from 2806fd6 to 1d9a0d3 Compare October 23, 2026 15:59
…response

Each debugBundle action carries a calls list with one entry per call
site: its connectionId, when set, and the inline inputs keys whose value
the build resolves to a string from a literal, a template without
expressions or a const binding, such as http.request's url and verb. Any
other input is left out, so a consent prompt can show it as set when the
call runs. That includes an object member, since an alias or a call can
mutate a const object without the mutation walk seeing it. Every input is
left out when the options or inputs object literal has a getter, setter,
spread, computed key, or a toJSON, then or __proto__ key, since
serializing or awaiting the call could rewrite any key. A hook inherited
from a prototype or added by an executor wrapper isn't detected.

The dev client and the frame transport copy only the action list's own
fields, so an inherited fqn, connectionId or inputs key never survives,
and drop a list whose inputs are an array or hold a non-string value.
The static property-key and expression-value helpers live in
type-guards.ts, shared by the connection-ID extractor and the string
resolver, and read a numeric literal key as its string.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-action-list branch from bc68d52 to e881537 Compare October 23, 2026 16:22
@tyffical
tyffical force-pushed the tiffany.trinh/apps-2958-debug-bundle-call-inputs branch from 1d9a0d3 to 7649b0d Compare October 23, 2026 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant