@foldspace_npm/harness 0.1.38 → 0.1.39

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.
package/CLAUDE.md CHANGED
@@ -779,7 +779,8 @@ Each of these cost a real build.
779
779
  callback, cancel, readyState)` decides which: a `render` that uses
780
780
  `callback`, `cancel` or `readyState` is an input card, and the agent waits
781
781
  until the card reports through one of them; one that uses none of them is
782
- a view card.
782
+ a view card. Foldspace's docs call these **read-only** and **input**
783
+ cards; they mean the same thing.
783
784
  - **A view card shows something** - an account, a list, deals at risk -
784
785
  with `render(data, host, header)`: no `callback`, no `cancel`. As soon as
785
786
  `render` returns, the agent gets "Shown to the user. The user has not
@@ -818,6 +819,14 @@ Each of these cost a real build.
818
819
  choice, as fields**, with the state (chosen, declined, cancelled, failed)
819
820
  and nothing about what to do next (**Rules**, 1). A view card needs no
820
821
  state of its own: the SDK tells the agent it was shown.
822
+ - **Never report a view card through `callback`.** Calling `callback(data)`
823
+ right after drawing (the old way to get a card's data to the agent) tells
824
+ the agent the user submitted that data, and it replies as if they had.
825
+ A view card takes `render(data, host, header)`, or calls
826
+ `readyState(value)` to send less than `execute` returned.
827
+ - **The agent only knows what the card reports, not what it draws.** A
828
+ figure or date on the card that is not in that data is unknown to the
829
+ agent, so put every fact a follow-up question could need in it.
821
830
  - **A failed or signed-out call is never drawn as zeros.** A signed-out response
822
831
  often looks like a valid empty one: a 200 with zeros, nulls or an empty list.
823
832
  Before you draw numbers, check that the response belongs to a signed-in user -
@@ -834,11 +843,8 @@ Each of these cost a real build.
834
843
  code, from the API's own numbers - in `execute` for a view card, since its
835
844
  result is what the agent gets - show them on the card, and hand the agent
836
845
  the same figures. In the action's Studio `instructions`, tell the agent to
837
- answer follow-up questions from the data it receives, to quote money and
838
- counts exactly as given, never to add them up itself (a model that adds up
839
- line items will eventually add them up wrong), and, right after a view
840
- card, to say one short sentence at most - never repeat what the card
841
- shows.
846
+ quote money and counts exactly as given and never to add them up itself (a
847
+ model that adds up line items will eventually add them up wrong).
842
848
  - **A card matches the panel, not the page.** The card sits in the agent's
843
849
  panel - white by default (the agent's theme: `backgroundColor #FFFFFF`,
844
850
  `primaryColor` for accents; a `darkTheme` when the panel is dark, and the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldspace_npm/harness",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "Build and verify portable Foldspace action artifacts against a live app.",
5
5
  "type": "module",
6
6
  "bin": {
package/recipes/README.md CHANGED
@@ -43,9 +43,10 @@ SDK's: `execute(params)` and
43
43
  `render(data, host, header, callback, cancel, readyState)`
44
44
  (<https://docs.foldspace.ai/guides/in-chat-ui/>), `foldspace.identify(context)`
45
45
  (<https://docs.foldspace.ai/start/user-context/>), and the harness runtime.
46
- Where the in-chat UI page says to set `awaitUserInput`, do not - the SDK waits
47
- when `render` uses `callback` or `cancel` (see the card bullet below). That
48
- page does not list `readyState`; CLAUDE.md describes it, and no recipe uses it.
46
+ Never set `awaitUserInput` - the SDK waits when `render` uses `callback`,
47
+ `cancel` or `readyState` (see the card bullet below). What the agent receives
48
+ for each is in CLAUDE.md (**Agentic UI components**); no recipe uses
49
+ `readyState` yet.
49
50
 
50
51
  Error handling is **not** taken from those builds. They predate `reason`: one
51
52
  turns every failure into "unexpected error", another reports a missing session
@@ -8,7 +8,7 @@ This card is the base layout. Copy it, then replace the `/__observe_me` routes w
8
8
 
9
9
  A view card: `render` takes no `callback` and the action sets no `awaitUserInput`. As soon as the card is drawn, the agent gets "Shown to the user. The user has not acted on it." plus exactly what `execute` returned - the account, the totals and every row behind the tabs, or the failure (`success: false`, `error` and `reason`) - and it answers questions about the account from that. So `execute` returns the overview the card draws and nothing else. One tab is on screen at a time; an empty tab says so. A signed-out or failed call is drawn with `renderFailure`, never as zeros. A 200 is signed out unless the account has both an id and a name.
10
10
 
11
- In Agent Studio: an action with key `show_account_overview` and one string parameter `accountId`, described as "The account's id. Never taken from the user's words: get it from `<lookup action key>`." Replace `<lookup action key>` with the key of this agent's action that returns account ids; if the agent has none, build that action first - `find-by-name` has the shape. Its `instructions`: "Answer follow-up questions about this account from the data you receive: quote money and counts exactly as given, and never add them up yourself. Right after the card, one short sentence at most - do not repeat what it shows. On a failure, the card already says why: say so in one short sentence and stop. No emoji."
11
+ In Agent Studio: an action with key `show_account_overview` and one string parameter `accountId`, described as "The account's id. Never taken from the user's words: get it from `<lookup action key>`." Replace `<lookup action key>` with the key of this agent's action that returns account ids; if the agent has none, build that action first - `find-by-name` has the shape. Its `instructions`: "Quote money and counts exactly as given, and never add them up yourself. No emoji."
12
12
 
13
13
  ## Adapt it
14
14
 
@@ -11,5 +11,5 @@
11
11
  }
12
12
  ],
13
13
  "confirmation_required": false,
14
- "instructions": "The result is the data the card was drawn from - every open deal, person and open case, not only the ones it lists - or a failure: success false, with the reason. Answer follow-up questions about this account from the data you receive: quote money and counts exactly as given, and never add them up yourself. Right after the card, one short sentence at most - do not repeat what it shows. On a failure, the card already says why: say so in one short sentence and stop. No emoji."
14
+ "instructions": "The result is the data the card was drawn from - every open deal, person and open case, not only the ones it lists - or a failure: success false, with the reason. Quote money and counts exactly as given, and never add them up yourself. No emoji."
15
15
  }
@@ -8,7 +8,7 @@ The app decides what "at risk" means, on the server. In that build it was: stall
8
8
 
9
9
  A view card: `render` takes no `callback` and the action sets no `awaitUserInput`. As soon as the card is drawn, the agent gets "Shown to the user. The user has not acted on it." plus exactly what `execute` returned - the count, the total, the average and the rows (no rows when the card says "No opportunities are at risk."), or the failure (`success: false`, `error` and `reason`). So `execute` returns what the card draws, with each row's id, and nothing else. The count, the total and the average are computed in code from the rows.
10
10
 
11
- In Agent Studio: an action with key `show_opportunities_at_risk` and no parameters. Its `instructions`: "Answer follow-up questions about these opportunities from the data you receive: quote money and counts exactly as given, and never add them up yourself. Right after the card, one short sentence at most - do not repeat what it shows. On a failure, the card already says why: say so in one short sentence and stop. No emoji."
11
+ In Agent Studio: an action with key `show_opportunities_at_risk` and no parameters. Its `instructions`: "Quote money and counts exactly as given, and never add them up yourself. No emoji."
12
12
 
13
13
  ## Adapt it
14
14
 
@@ -8,7 +8,7 @@ A view card: `render` takes no `callback` and the action sets no `awaitUserInput
8
8
 
9
9
  `brand.ts` here is a placeholder: keep the `agent/views/brand.ts` that `npx foldspace observe styles --write` wrote - it has every key the recipe cards read. If the project has none yet, run that command first; do not copy this one.
10
10
 
11
- In Agent Studio: an action with key `list_accounts` and no parameters. Its `instructions`: "Answer follow-up questions about these accounts from the data you receive: quote money and counts exactly as given, and never add them up yourself. Right after the card, one short sentence at most - do not repeat what it shows. On a failure, the card already says why: say so in one short sentence and stop. No emoji."
11
+ In Agent Studio: an action with key `list_accounts` and no parameters. Its `instructions`: "Quote money and counts exactly as given, and never add them up yourself. No emoji."
12
12
 
13
13
  ## Adapt it
14
14
 
@@ -586,7 +586,7 @@ export function ruleCardContract(sourceFile, relative, findings) {
586
586
  node: flag.name,
587
587
  file: relative,
588
588
  message:
589
- "A view card (render uses neither callback nor cancel) sets awaitUserInput: true. The chat panel ignores it, but in headless mode the agent then waits for a callback that never comes.",
589
+ "A view card (render uses none of callback, cancel or readyState) sets awaitUserInput: true. The chat panel ignores it, but in headless mode the agent then waits for a callback that never comes.",
590
590
  fix: "Remove awaitUserInput. A view card is reported to the agent as shown, with what execute returned.",
591
591
  }),
592
592
  );
@@ -600,7 +600,7 @@ export function ruleCardContract(sourceFile, relative, findings) {
600
600
  node: flag.name,
601
601
  file: relative,
602
602
  message:
603
- "A view card does not need awaitUserInput: render uses neither callback nor cancel, so the agent is told the card was shown, with what execute returned.",
603
+ "A view card does not need awaitUserInput: render uses none of callback, cancel or readyState, so the agent is told the card was shown, with what execute returned.",
604
604
  fix: "Remove awaitUserInput.",
605
605
  }),
606
606
  );