@foldspace_npm/harness 0.1.26 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CLAUDE.md +402 -204
  2. package/README.md +84 -36
  3. package/bin/ask.mjs +19 -9
  4. package/bin/attach.mjs +91 -56
  5. package/bin/badge.mjs +28 -8
  6. package/bin/cli.mjs +23 -6
  7. package/bin/inject.mjs +3 -4
  8. package/bin/observe.mjs +22 -6
  9. package/bin/published.mjs +141 -0
  10. package/package.json +6 -2
  11. package/recipes/INDEX.md +13 -8
  12. package/recipes/README.md +30 -7
  13. package/recipes/account-overview/README.md +6 -6
  14. package/recipes/account-overview/agent/actions/show_account_overview.ts +11 -16
  15. package/recipes/account-overview/agent/views/brand.ts +23 -14
  16. package/recipes/account-overview/agent/views/overview.ts +13 -17
  17. package/recipes/bottom-bar/README.md +12 -9
  18. package/recipes/bottom-bar/agent/bottomBar.ts +14 -12
  19. package/recipes/create-a-record/README.md +97 -0
  20. package/recipes/create-a-record/agent/actions/create_project.ts +26 -0
  21. package/recipes/create-a-record/agent/api/projects.ts +62 -0
  22. package/recipes/create-a-record/agent/projects.ts +145 -0
  23. package/recipes/create-a-record/agent/views/approval.ts +181 -0
  24. package/recipes/create-a-record/agent/views/brand.ts +35 -0
  25. package/recipes/create-a-record/agent/views/fields.ts +252 -0
  26. package/recipes/create-a-record/agent/views/project-card.ts +253 -0
  27. package/recipes/create-a-record/agent/views/steps.ts +92 -0
  28. package/recipes/create-a-record/fixtures/owners.ok.json +9 -0
  29. package/recipes/create-a-record/fixtures/project.created.json +1 -0
  30. package/recipes/create-a-record/fixtures/project.rejected.json +1 -0
  31. package/recipes/create-a-record/recipe.json +13 -0
  32. package/recipes/create-a-record/variants/actions/create_project.steps.ts +160 -0
  33. package/recipes/find-by-name/README.md +3 -1
  34. package/recipes/find-by-name/agent/actions/find_project_id.ts +1 -1
  35. package/recipes/lookup-then-view/README.md +73 -0
  36. package/recipes/lookup-then-view/agent/accounts.ts +174 -0
  37. package/recipes/lookup-then-view/agent/actions/find_account.ts +108 -0
  38. package/recipes/lookup-then-view/agent/actions/show_account_overview.ts +42 -0
  39. package/recipes/lookup-then-view/agent/api/accounts.ts +68 -0
  40. package/recipes/lookup-then-view/agent/views/account.ts +183 -0
  41. package/recipes/lookup-then-view/agent/views/brand.ts +35 -0
  42. package/recipes/lookup-then-view/agent/views/format.ts +73 -0
  43. package/recipes/lookup-then-view/agent/views/pick-one.ts +240 -0
  44. package/recipes/lookup-then-view/fixtures/accounts.json +319 -0
  45. package/recipes/lookup-then-view/fixtures/overview.ok.json +122 -0
  46. package/recipes/lookup-then-view/fixtures/overview.unsigned.json +14 -0
  47. package/recipes/lookup-then-view/recipe.json +11 -0
  48. package/recipes/lookup-then-view/studio/find_account.json +10 -0
  49. package/recipes/lookup-then-view/studio/show_account_overview.json +15 -0
  50. package/recipes/opportunities-at-risk/README.md +5 -5
  51. package/recipes/opportunities-at-risk/agent/actions/show_opportunities_at_risk.ts +9 -7
  52. package/recipes/opportunities-at-risk/agent/opportunities.ts +11 -10
  53. package/recipes/opportunities-at-risk/agent/views/at-risk.ts +1 -1
  54. package/recipes/opportunities-at-risk/agent/views/brand.ts +26 -15
  55. package/recipes/pick-from-a-list/README.md +7 -6
  56. package/recipes/pick-from-a-list/agent/actions/choose_project.ts +27 -12
  57. package/recipes/pick-from-a-list/agent/views/brand.ts +30 -9
  58. package/recipes/pick-from-a-list/agent/views/picker.ts +3 -3
  59. package/recipes/prepare-for-a-meeting/README.md +4 -4
  60. package/recipes/prepare-for-a-meeting/agent/actions/prepare_for_meeting.ts +3 -3
  61. package/recipes/records-list/README.md +6 -6
  62. package/recipes/records-list/agent/accounts.ts +3 -1
  63. package/recipes/records-list/agent/actions/list_accounts.ts +7 -7
  64. package/recipes/records-list/agent/views/brand.ts +26 -14
  65. package/recipes/server-rendered-forms/README.md +35 -0
  66. package/recipes/server-rendered-forms/agent/actions/create_record_via_form.ts +62 -0
  67. package/recipes/server-rendered-forms/agent/api/pages.ts +57 -0
  68. package/recipes/server-rendered-forms/agent/forms.ts +192 -0
  69. package/recipes/server-rendered-forms/fixtures/form.errors.html +9 -0
  70. package/recipes/server-rendered-forms/fixtures/form.html +17 -0
  71. package/recipes/server-rendered-forms/fixtures/list.html +9 -0
  72. package/recipes/server-rendered-forms/fixtures/record.html +4 -0
  73. package/recipes/server-rendered-forms/recipe.json +10 -0
  74. package/recipes/several-hosts/README.md +10 -13
  75. package/recipes/several-hosts/agent/hosts.ts +19 -136
  76. package/recipes/several-hosts/fixtures/wrong-page.json +6 -0
  77. package/recipes/several-hosts/recipe.json +3 -3
  78. package/recipes/swap-the-login-method/README.md +16 -5
  79. package/recipes/swap-the-login-method/agent/utils.ts +52 -3
  80. package/recipes/swap-the-login-method/variants/utils.cookies.ts +59 -6
  81. package/recipes/update-meeting-notes/README.md +10 -4
  82. package/recipes/update-meeting-notes/agent/actions/update_meeting_notes.ts +16 -5
  83. package/recipes/upload-contacts/README.md +5 -5
  84. package/recipes/upload-contacts/agent/actions/upload_contacts.ts +7 -7
  85. package/recipes/upload-contacts/agent/views/brand.ts +24 -14
  86. package/recipes/upload-contacts/agent/views/uploader.ts +28 -17
  87. package/recipes/who-is-the-user/README.md +7 -3
  88. package/src/ask-core.mjs +16 -4
  89. package/src/attach-daemon.mjs +9 -2
  90. package/src/attach-helpers.mjs +105 -0
  91. package/src/attach-preflight.mjs +34 -11
  92. package/src/badge-core.mjs +1 -1
  93. package/src/cdp-client.mjs +15 -19
  94. package/src/cdp-ownership.mjs +41 -20
  95. package/src/cli-help.mjs +7 -5
  96. package/src/cli-registry.mjs +102 -47
  97. package/src/diagnostics.mjs +1 -1
  98. package/src/init.mjs +5 -3
  99. package/src/keep-focus.mjs +17 -13
  100. package/src/lint/index.mjs +8 -1
  101. package/src/lint/rules.mjs +240 -43
  102. package/src/observe-core.mjs +163 -34
  103. package/src/published-core.mjs +392 -0
  104. package/src/region.mjs +1 -1
  105. package/src/runtime/agent.ts +16 -12
  106. package/src/runtime/http.ts +25 -15
  107. package/src/runtime/match.ts +1 -1
  108. package/src/runtime/render.ts +4 -4
  109. package/src/transports/README.md +2 -2
  110. package/src/upgrade.mjs +33 -10
  111. package/templates/agent-starter/CLAUDE.md +8 -5
  112. package/templates/agent-starter/README.md +32 -33
  113. package/templates/agent-starter/agent/actions/_example.ts +4 -4
  114. package/templates/agent-starter/agent/actions/index.ts +2 -2
  115. package/templates/agent-starter/agent/constants.ts +4 -3
  116. package/templates/agent-starter/agent/utils.ts +15 -18
  117. package/templates/agent-starter/claude-settings.json +2 -1
  118. package/templates/agent-starter/docs/app-profile.md +19 -14
  119. package/templates/agent-starter/foldspace.dev.json +1 -1
  120. package/recipes/several-hosts/fixtures/nav-record.json +0 -5
package/README.md CHANGED
@@ -12,12 +12,12 @@ else about how a builder runs differs between them; this does not.
12
12
 
13
13
  | | **A — local** *(today)* | **B — remote** *(designed, unbuilt)* |
14
14
  |---|---|---|
15
- | Who runs the agent | Claude Code on the builder's desktop | Claude Agent SDK in GCP |
16
- | Whose browser | an isolated Chrome the harness launches | the user's **own** Chrome |
15
+ | Where the build runs | Claude Code on the human's computer | Claude Agent SDK in GCP |
16
+ | Whose browser | an isolated Chrome the harness launches | the human's **own** Chrome |
17
17
  | How code reaches the page | harness CDP preparation | builder extension loads the cloud artifact |
18
18
  | Prerequisites | Claude Code, a client repo, Node, an isolated Chrome profile | the extension installed |
19
- | Session and cookies | in a profile the harness creates | the user's own, untouched |
20
- | Code and history | a git repo on the builder's machine | a workspace in the hosted environment |
19
+ | Session and cookies | in a profile the harness creates | the human's own, untouched |
20
+ | Code and history | a git repo on the human's computer | a workspace in the hosted environment |
21
21
 
22
22
  "Export to repo" moves a build from B to A — **and it is only a copy, not a
23
23
  rewrite, while `agent/` is identical in both.** Keeping it identical is the
@@ -29,7 +29,7 @@ constraint this package exists to protect.
29
29
  nothing more. Actions built in one track run unmodified in the other.
30
30
  - `agent/utils.ts` — configures and re-exports `@foldspace_npm/harness/runtime`
31
31
  - `foldspace build` — esbuild → `dist/index.js`
32
- - `foldspace deploy` — publish to `agent/actions/<env>/<productId>/<agentApiName>`
32
+ - `foldspace deploy` (Foldspace-internal) - uploads `dist/index.js` to `agent/actions/<env>/<productId>/<agentApiName>`
33
33
  - fixtures and tests
34
34
  - **the verb interface** below
35
35
 
@@ -95,7 +95,7 @@ Non-interactive / CI form:
95
95
 
96
96
  ```bash
97
97
  npx --yes @foldspace_npm/harness init foldspace-agent \
98
- --product-id FR8JUQZAQRZB \
98
+ --product-id <product-id> \
99
99
  --agent-key my-agent \
100
100
  --app-domain app.example.com \
101
101
  --name "My Agent"
@@ -105,7 +105,7 @@ When running directly from a harness checkout during development:
105
105
 
106
106
  ```bash
107
107
  node bin/cli.mjs init ../foldspace-agent \
108
- --product-id FR8JUQZAQRZB \
108
+ --product-id <product-id> \
109
109
  --agent-key my-agent \
110
110
  --app-domain app.example.com
111
111
  ```
@@ -115,8 +115,9 @@ not the sidecar directory name. `--agent-api-name` remains a deprecated alias
115
115
  for `--agent-key`. `--domain` remains a deprecated alias for `--app-domain`.
116
116
  `--name` is optional and defaults to the target directory
117
117
  name (`foldspace-agent` unless you pass a directory). The product ID must be
118
- the bare ID, not the `EU-…-1-1` SDK loader key. The app domain may be a hostname
119
- or an HTTP(S) URL without a port or path.
118
+ the bare ID, not the SDK key (the one that starts with `EU-`, in every
119
+ region). The app domain may be a hostname or an HTTP(S) URL without a port or
120
+ path.
120
121
 
121
122
  `--region us|eu` (default `us`) is the Foldspace region the account lives in.
122
123
  It is written to `foldspace.dev.json` as `region`, and picks the SDK the
@@ -131,9 +132,11 @@ initialize Git or overwrite files. On a TTY it can offer
131
132
  ```bash
132
133
  cd foldspace-agent
133
134
  npm install --ignore-scripts # if you skipped the install prompt
135
+ # before the first build, CLAUDE.md step 5: a code project's agent/ replaces the scaffold's
134
136
  npm run build
135
- npm run inject
136
- npm run attach
137
+ npm run inject # the human signs in in that window
138
+ npx foldspace observe wait-login
139
+ npx foldspace attach --daemon
137
140
  ```
138
141
 
139
142
  The generated npm scripts intentionally remain the normal project interface;
@@ -146,21 +149,21 @@ to that import with `foldspace upgrade --refresh-instructions`.
146
149
  ### Keep the harness current
147
150
 
148
151
  Tenant projects pin an exact `@foldspace_npm/harness` version. Publishing a
149
- newer package does not move them. Check, ask the user, then bump:
152
+ newer package does not move them. Check, ask the human, then bump:
150
153
 
151
154
  ```bash
152
155
  npx --yes @foldspace_npm/harness@latest upgrade --check
153
- foldspace upgrade --yes # only after the user agrees
156
+ foldspace upgrade --yes # only after the human agrees
154
157
  ```
155
158
 
156
159
  `--check` (and a non-interactive `upgrade` with no `--yes`) never installs.
157
- `--yes` rewrites the exact pin and runs `npm install --ignore-scripts`. Rebuild
158
- afterward; that is still not a deploy.
160
+ `--yes` writes the new exact version and runs `npm install --ignore-scripts`.
161
+ Rebuild afterward; that publishes nothing.
159
162
 
160
163
  `foldspace build` and `foldspace attach` run the same check before they start
161
164
  (`attach --status` and `--stop` do not). A project that is behind gets one line
162
165
  on stderr and carries on. A project on a **withdrawn** version (below) refuses
163
- to run and prints the reason. To build on it anyway, once the user has declined
166
+ to run and prints the reason. To build on it anyway, once the human has declined
164
167
  the upgrade:
165
168
 
166
169
  ```bash
@@ -200,13 +203,14 @@ To undo a withdrawal, deprecate with an empty message:
200
203
  npm deprecate @foldspace_npm/harness@0.1.14 ""
201
204
  ```
202
205
 
203
- **It is not instant.** Each project caches the registry's answer for 12 hours
204
- in `.foldspace-dev/harness-update.json`. A project that checked recently keeps
205
- its "fine" answer until that expires, so a withdrawal reaches every project
206
- within 12 hours. It only reaches projects on a harness version that has this
207
- check.
206
+ **It is not instant for `build` and `attach`.** They use the registry's answer
207
+ cached for 12 hours in `.foldspace-dev/harness-update.json`. `foldspace help
208
+ --json` (which the manual reads first) and `foldspace upgrade` ask the registry
209
+ each time and refresh that cache, so a withdrawal reaches a project at its next
210
+ session start, and within 12 hours otherwise. It only reaches projects on a
211
+ harness version that has this check.
208
212
 
209
- ### Lint handlers before they ship
213
+ ### Lint agent code before it ships
210
214
 
211
215
  `foldspace build` runs `foldspace lint` first. Errors skip bundling; warnings
212
216
  print and still produce `dist/index.js`.
@@ -218,12 +222,16 @@ foldspace lint --json
218
222
 
219
223
  v1 flags:
220
224
 
221
- - **error** `no-static-agent-prompt` — `execute` / chatterblock `callback` returning copilot instructions (`directive`, “tell the user”, …)
225
+ - **error** `no-static-agent-prompt` - `execute`, a card's `callback` or its `readyState` handing the agent instructions (`directive`, “tell the user”, …)
222
226
  - **error** `no-runtask-prompt` — `runTask({ data: { prompt } })` and the same keys; a customer API field named `prompt` is allowed
227
+ - **error** `card-contract` - `awaitUserInput: true` on a view card (its `render` uses no `callback`, `cancel` or `readyState`): the chat panel ignores it, but in headless mode the agent waits for a callback that never comes
228
+ - **error** `no-test-mode-in-bundle` - `armAllInstances(...)`, or `setTestMode(...)` with anything but a literal `false`, anywhere in `agent/`
229
+ - **warning** `card-contract` - any other `awaitUserInput` on a view card, `awaitUserInput` on an input card (not needed), or a `render` that declares `callback`, `cancel` or `readyState` and uses none of them (the SDK treats it as a view card)
223
230
  - **warning** `no-emoji` — emoji in handler or `agent/views` string literals
224
231
  - **warning** `registry-integrity` — duplicate keys, `{ execute }` not registered, registry value missing `execute`
225
232
 
226
- Put action instructions in Agent Studio or MCP. `foldspace lint` cannot see that copy.
233
+ Put action instructions in Agent Studio or with the Foldspace tools. `foldspace
234
+ lint` cannot see that copy.
227
235
 
228
236
  ### Runtime helpers
229
237
 
@@ -232,7 +240,10 @@ Tenant actions import from `agent/utils.ts`, which configures and re-exports
232
240
  runs in the customer's page — it is not a CLI command.
233
241
 
234
242
  `API_BASE` and `AUTH_SOURCE` stamp empty. Fill them from a captured XHR, not a
235
- guess. Custom auth headers stay a tenant override of one function in `utils.ts`.
243
+ guess. For auth that is not Bearer, follow
244
+ `recipes/swap-the-login-method/README.md`: for a custom header, copy its
245
+ `agent/utils.ts` over `agent/utils.ts`; for cookies with no token, its
246
+ `variants/utils.cookies.ts`.
236
247
 
237
248
  ### Choose an attach mode
238
249
 
@@ -242,21 +253,25 @@ guess. Custom auth headers stay a tenant override of one function in `utils.ts`.
242
253
  has an SDK without the configured agent.
243
254
 
244
255
  Use `foldspace help attach` for mode requirements, effects, and safety options.
245
- Coding agents should run `foldspace attach --daemon` so the invoking tool
256
+ Coding agents run `foldspace attach --daemon` so the invoking tool
246
257
  returns after `[lifecycle] inspect_registration:…`. Foreground attach remains
247
- the default for humans watching the terminal. `attach --status` and
258
+ the default for someone watching the terminal. `attach --status` and
248
259
  `attach --stop` inspect and tear down a daemon. Look at the customer's app with
249
- `foldspace observe`: it reads the same window, read-only, while attach runs.
260
+ `foldspace observe`: it reads the test window, read-only, while attach runs.
250
261
 
251
262
  ### Verify actions through the agent
252
263
 
253
264
  `foldspace attach` does not invoke action handlers directly. It loads the local
254
265
  artifact, verifies that the captured local registry matches the configured SDK
255
- agent — including an empty registry — and then observes action callbacks while
266
+ agent - including an empty registry - and then observes action calls while
256
267
  you exercise the normal agent experience. Named actions are not required to
257
268
  attach.
258
269
 
259
- Action output identifies SDK callbacks and local `execute`/`render` phases:
270
+ `npx foldspace ask "<question>" --retry 2` types the question into the agent's
271
+ panel and reports the reply, the card text and a screenshot, and - while attach
272
+ runs - whether execute and render ran.
273
+
274
+ Action output shows the SDK's action calls and local `execute`/`render` phases:
260
275
 
261
276
  ```text
262
277
  [actions] sdk:action show_account_360 executed
@@ -269,6 +284,36 @@ parameter values, results, and error messages are not. On detach, repeated page
269
284
  failures and bounded action observations are summarized. The observer and
270
285
  diagnostics are injected by the harness, so `dist/index.js` is not rewritten.
271
286
 
287
+ ### Check the published code
288
+
289
+ After the `deploy` tool in the Foldspace tools - not `foldspace deploy`, which
290
+ is for Foldspace staff only - publishes the code project to dev (or, with the
291
+ human's yes, to production), check it in the same test window. This needs a
292
+ site that loads this agent by itself: after `attach --bootstrap` or
293
+ `--replace` there is nothing to check yet.
294
+
295
+ ```bash
296
+ npx foldspace attach --stop # while attach runs the page serves your local build
297
+ npx foldspace published dev # this page's agent now loads the published dev code
298
+ npx foldspace ask "<the question>" --retry 2
299
+ npx foldspace attach --daemon # back to your local build before you build anything else
300
+ ```
301
+
302
+ `published` refuses while attach runs. It also refuses unless the page's own
303
+ Foldspace agent is this project's agent - the same product and Agent Key as
304
+ `foldspace.dev.json`, checked the way attach checks it. It changes only this
305
+ page's agent, through the SDK's `setConfiguration({ enableDebugLogs: true,
306
+ remoteActionsSettings: { enabled: true, environment: "DEV" | "PROD" } })`; a
307
+ reload puts the page back on what the agent loads normally. When code loads,
308
+ the SDK keeps any handler the agent already has over a new one of the same
309
+ name, so once the published code has loaded, its handlers are set over the
310
+ page's for every action it defines; the page keeps its own handlers for the
311
+ rest. An agent pinned to one version of its code, or loading code from its
312
+ own address, is refused: the window would not show what was published last.
313
+ Without attach, `ask` still reports the reply, the card text and a
314
+ screenshot; `handler.execute` and `handler.render` read "not tracked here
315
+ (published code)".
316
+
272
317
  ### Add the harness to an existing project
273
318
 
274
319
  ```bash
@@ -281,8 +326,7 @@ npm i -D @foldspace_npm/harness
281
326
  "build": "foldspace build",
282
327
  "inject": "foldspace inject",
283
328
  "attach": "foldspace attach",
284
- "attach:daemon": "foldspace attach --daemon",
285
- "deploy": "foldspace deploy"
329
+ "attach:daemon": "foldspace attach --daemon"
286
330
  } }
287
331
  ```
288
332
 
@@ -290,9 +334,13 @@ Every command resolves the **consuming** repo — `process.cwd()`, or
290
334
  `FOLDSPACE_PROJECT_DIR` so a hosted builder can point it at a workspace it
291
335
  controls. Config comes from the consumer's `foldspace.dev.json`.
292
336
 
293
- `foldspace deploy` is an explicit remote publication step that reads product
294
- and agent identity from the selected target in `foldspace.dev.json`. It requires
295
- local cloud credentials and is separate from local verification.
337
+ `foldspace deploy` is Foldspace-internal: it writes to Foldspace's own storage,
338
+ which no customer can write to. A coding agent never runs or offers it. With a
339
+ code project, a build session publishes the agent's code with the Foldspace
340
+ tools instead: `repo_write` saves it, and the `deploy` tool publishes it - to
341
+ dev after saying so, to production only on the human's yes - as the manual's
342
+ "Done, and what you say at the end" says. Without a code project, the
343
+ Foldspace team does it with the human.
296
344
 
297
345
  ---
298
346
 
@@ -306,7 +354,7 @@ and **neither had all five**:
306
354
  |---|---|
307
355
  | SDK load guard + retry | On an app with no `document.body` at document-start the append throws; the old guard tested for the stub, so nothing retried and the agent silently never loaded |
308
356
  | Worker release on auto-attach | Auto-attach pauses every worker until the attaching client releases it — the harness froze the app's own workers for the whole session |
309
- | `agentIds` enumeration | `agent({apiName})` returns the OVERLAY handle; arming it on an embedded copilot leaves real conversations untagged |
357
+ | `agentIds` enumeration | `agent({apiName})` returns the OVERLAY handle; arming it on an embedded agent leaves real conversations untagged |
310
358
  | `--test-mode` (off by default) | Test mode was armed unconditionally, hiding exactly what initial setup needs to see; now it is opt-in |
311
359
  | Honest badge | It asserted `TEST MODE` whether or not test mode was on |
312
360
 
package/bin/ask.mjs CHANGED
@@ -1,17 +1,23 @@
1
1
  #!/usr/bin/env node
2
- // foldspace ask — put a question to the visible assistant through its panel,
2
+ // foldspace ask - put a question to the visible agent through its panel,
3
3
  // exactly as a person would, and report what came back: the reply, any card,
4
4
  // what the handlers did, and a picture.
5
5
  //
6
- // It exists so the coding agent stops asking a non-technical customer to
7
- // "reload, try these two sentences and tell me what you saw".
6
+ // It exists so the coding agent stops asking the human to "reload, try these
7
+ // two sentences and tell me what you saw".
8
8
  //
9
- // node bin/ask.mjs "<question>" [--retry <n>] [--every <s>] [--timeout <s>] [--out <dir>]
9
+ // npx foldspace ask "<question>" [--retry <n>] [--every <s>] [--timeout <s>]
10
10
  //
11
11
  // Nothing here reaches into the SDK, patches fetch or injects into the panel:
12
12
  // it opens the panel, types into the composer, presses Enter and reads the
13
13
  // screen. --retry re-asks when no action fired, which covers the platform
14
14
  // taking up to a minute to pick up a newly published action; lagMs is that cost.
15
+ //
16
+ // What the handlers did comes from the attach daemon's log. Without a daemon
17
+ // (after `foldspace published`, the page runs published code) execute and
18
+ // render read "not tracked here (published code)", so only a card shows that
19
+ // an action fired: --retry re-asks whenever no card came back, even when an
20
+ // action that draws no card ran.
15
21
 
16
22
  import fs from "node:fs";
17
23
  import path from "node:path";
@@ -23,8 +29,9 @@ import {
23
29
  shouldRetry,
24
30
  squash,
25
31
  summarizeHandlerLog,
32
+ untrackedHandler,
26
33
  } from "../src/ask-core.mjs";
27
- import { ATTACH_DAEMON_LOG_FILE } from "../src/attach-daemon.mjs";
34
+ import { ATTACH_DAEMON_LOG_FILE, liveDaemon } from "../src/attach-daemon.mjs";
28
35
  import { CdpPage, parseArgs, printJson, sleep } from "../src/cdp-client.mjs";
29
36
  import { recordEvent } from "../src/session-events.mjs";
30
37
  import { withWorkingBadge } from "../src/badge-auto.mjs";
@@ -44,6 +51,7 @@ const outDir = flags.out
44
51
  ? path.resolve(projectDir, String(flags.out))
45
52
  : path.join(projectDir, ".foldspace-dev", "ask");
46
53
  const logFile = path.join(projectDir, ".foldspace-dev", ATTACH_DAEMON_LOG_FILE);
54
+ const tracked = Boolean(liveDaemon(projectDir));
47
55
 
48
56
  let page = null;
49
57
 
@@ -223,7 +231,7 @@ async function askOnce() {
223
231
  reply: reply.slice(0, 2000),
224
232
  cards: seen.cards.map((card) => card.slice(0, 2000)),
225
233
  hasCard: seen.cards.length > 0 || seen.newCardFrames > 0,
226
- handler: summarizeHandlerLog(logSince(logOffset)),
234
+ handler: tracked ? summarizeHandlerLog(logSince(logOffset)) : untrackedHandler(),
227
235
  };
228
236
  }
229
237
 
@@ -264,7 +272,7 @@ async function main() {
264
272
  {
265
273
  ok: false,
266
274
  reason:
267
- 'No question. Usage: foldspace ask "<question>" [--retry <n>] [--every <s>] [--timeout <s>] [--out <dir>]',
275
+ 'No question. Usage: foldspace ask "<question>" [--retry <n>] [--every <s>] [--timeout <s>]',
268
276
  },
269
277
  1,
270
278
  );
@@ -290,8 +298,10 @@ async function main() {
290
298
  ok: false,
291
299
  question,
292
300
  reason: state.frame
293
- ? "The assistant panel is on the page but never showed a composer."
294
- : "No assistant panel on this page. Run `foldspace attach --daemon` (add --bootstrap when the page has no Foldspace SDK), then ask again.",
301
+ ? "The agent panel is on the page but never showed a composer. Run `npx foldspace observe screenshot` and look at the page."
302
+ : tracked
303
+ ? "No agent panel on this page while attach runs. Read the lines under the last [lifecycle] line in .foldspace-dev/attach-daemon.log, then ask again."
304
+ : "No agent panel on this page. Run `npx foldspace attach --daemon`, follow what it says about the page, then ask again.",
295
305
  url,
296
306
  },
297
307
  1,