fix(tools): carry the page query through appGetPage / appSendForm - #98
Conversation
AI ReviewAdds Checklist
DetailsU1 — Both commits follow the convention correctly.
U5 — Verified by checking out the PR branch in a disposable clone:
S2 — Path params in both ops ( S3 — No new tool functions were added; S4 — S5 — No manifest files ( Issues foundNo issues found. This review was generated automatically. A human maintainer should still make the merge decision. |
Review vs pong-server / control-cdu
// pages.ts:382
const { body, query } = req; // query === req.query (URL string)
// pages.ts:415
body: { ...body, query, context }, // req.query OVERWRITES body.querySince The real client confirms the contract: control-cdu Fix: change The |
Review catch (PR #98): pong-server's `sendScriptPage` reads `query` from the URL and spreads it AFTER the body — `body: { ...body, query, context }` (controlMain/api/applications/pages.ts:415) — so `req.query` overwrites whatever the caller put in `body.query`. On a POST with no query string `req.query` is `{}`, which means the body-borne query was silently clobbered and the per-session token/record id never reached the process. The real client (control-cdu `handleSubmitForm`) confirms the contract: it appends `query` to the URL and sends no `query` body key. - `appSendForm`'s `query` moves from InBody to InQueryMap — same transport as appGetPage. The description stays accurate: the handler still forwards it to the process as `body.query.*`; only the wire slot was wrong. - The subtest now asserts the query lands in the URL and that no `query` key is sent in the body (it would be overwritten anyway, so it would only mislead). - op.go's InQueryMap doc, the runtime SKILL.md and the CHANGELOG entry drop the "appSendForm puts it in the body" claim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Good catch — confirmed against pong-server and fixed in 37b675e.
// controlMain/api/applications/pages.ts:375, 415
const { body, query } = req;
body: { ...body, query, context }, // req.query wins over body.queryOn a POST with no query string Fastify gives Changes:
|
AI ReviewRe-review after synchronize: fixes Checklist
DetailsU1 — All three commits follow the convention:
U5 — Verified in a disposable clone of the PR branch (
S2 — Path params ( S3 — No new tool functions added; S4 — S5 — No manifest files ( S6 — No new tools added or renamed; only existing Issues foundNo issues found. Fixed since last review ✅
This review was generated automatically. A human maintainer should still make the merge decision. |
macOS drops .DS_Store into every directory that gets opened in Finder, and they were showing up as untracked noise in `git status` across the plugin tree. Ignore them repo-wide so they stop polluting diffs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A Smart Form page is stateless: a `302` answers `{nextPage, query}` and the
next page reads that query back as `body.query.*`. That is how an app carries
per-session state (a token, a card code) across navigation. Neither runtime
tool accepted a query, so a logged-in page could not be rendered at all —
driving one produced a cold page that read as a backend bug.
- `appGetPage` gains `query`, flattened into the URL query string exactly as
the renderer sends it.
- `appSendForm` gains `query` in the body, where the `/send` handler reads it.
- New `InQueryMap` param kind in `internal/tools/op.go` does the flattening.
Plain `InQuery` would have sent the whole object as one opaque value,
silently dropping the session; `InQueryMap` rejects a non-object and skips
blank keys / nil values (a nil would otherwise render as the literal
"null").
- `buttonId` / `buttonData` descriptions now state the submitOnChange
behaviour: the changed field's id arrives as `buttonId`, and only `select`
populates `buttonData`.
- `simulator-smart-forms-runtime` documents carrying `resp.query` forward.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review catch (PR #98): pong-server's `sendScriptPage` reads `query` from the URL and spreads it AFTER the body — `body: { ...body, query, context }` (controlMain/api/applications/pages.ts:415) — so `req.query` overwrites whatever the caller put in `body.query`. On a POST with no query string `req.query` is `{}`, which means the body-borne query was silently clobbered and the per-session token/record id never reached the process. The real client (control-cdu `handleSubmitForm`) confirms the contract: it appends `query` to the URL and sends no `query` body key. - `appSendForm`'s `query` moves from InBody to InQueryMap — same transport as appGetPage. The description stays accurate: the handler still forwards it to the process as `body.query.*`; only the wire slot was wrong. - The subtest now asserts the query lands in the URL and that no `query` key is sent in the body (it would be overwritten anyway, so it would only mislead). - op.go's InQueryMap doc, the runtime SKILL.md and the CHANGELOG entry drop the "appSendForm puts it in the body" claim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
37b675e to
1d1446a
Compare
Problem
A Smart Form page is stateless. A
302answers{nextPage, query}, and the next page reads thatquery back as
body.query.*— that is how an app carries per-session state (a token, a card code)across navigation.
Neither runtime tool accepted a query, so a logged-in page could not be rendered at all.
Driving one produced a cold page — empty fields,
—placeholders, an empty table — which reads asa backend bug rather than a missing argument.
Change
appGetPagegainsquery, flattened into the URL query string exactly as the renderersends it.
appSendFormgainsqueryin the body, where the/sendhandler reads it.InQueryMapparam kind (internal/tools/op.go). The keys are app-defined, so the tooltakes one object and flattens it. Plain
InQuerywould have sent the whole object as a singleopaque value, silently dropping the session.
InQueryMaprejects a non-object with a clearerror and skips blank keys / nil values — a nil would otherwise reach the backend as the literal
string
"null".buttonId/buttonDatadescriptions now state thesubmitOnChangebehaviour: the changedfield's id arrives as
buttonId, and onlyselectpopulatesbuttonData(radio/check/toggle/editsend{}, so the value is read fromdata).simulator-smart-forms-runtimedocuments carryingresp.queryforward across navigation,with the ✅ / ❌ pair.
.DS_Storeadded to.gitignore(separate commit).Tests
Four new subtests in
internal/tools/smartforms_test.go:query=key;
queryreturns an error result instead of being silently stringified;appSendFormcarriesqueryin the request body.Verification
make build,make vet,go test ./...(whole module) — all green.make discoveryproduces nodrift (no skill frontmatter changed).