@dynamicagents/plugins 0.11.1 → 0.13.0

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 (134) hide show
  1. package/README.md +59 -79
  2. package/dist/browser/index.d.ts +0 -2
  3. package/dist/browser/index.js +21 -27
  4. package/dist/claude-code/cards.d.ts +53 -0
  5. package/dist/claude-code/cards.js +272 -0
  6. package/dist/claude-code/config.d.ts +73 -31
  7. package/dist/claude-code/config.js +0 -2
  8. package/dist/claude-code/credentials.d.ts +21 -9
  9. package/dist/claude-code/credentials.js +43 -9
  10. package/dist/claude-code/egress.d.ts +15 -14
  11. package/dist/claude-code/egress.js +51 -14
  12. package/dist/claude-code/events.d.ts +153 -9
  13. package/dist/claude-code/events.js +289 -58
  14. package/dist/claude-code/github.d.ts +39 -0
  15. package/dist/claude-code/github.js +82 -0
  16. package/dist/claude-code/index.d.ts +24 -80
  17. package/dist/claude-code/index.js +19 -234
  18. package/dist/claude-code/model.d.ts +152 -0
  19. package/dist/claude-code/model.js +342 -0
  20. package/dist/claude-code/run.d.ts +283 -92
  21. package/dist/claude-code/run.js +620 -114
  22. package/dist/claude-code/session.d.ts +131 -0
  23. package/dist/claude-code/session.js +285 -0
  24. package/dist/claude-code/spec.d.ts +46 -0
  25. package/dist/claude-code/spec.js +83 -0
  26. package/dist/claude-code/verified.d.ts +15 -0
  27. package/dist/claude-code/verified.js +15 -0
  28. package/dist/computer/context.d.ts +19 -0
  29. package/dist/computer/context.js +222 -0
  30. package/dist/computer/file-lock.d.ts +5 -0
  31. package/dist/computer/file-lock.js +40 -0
  32. package/dist/computer/gate.d.ts +12 -12
  33. package/dist/computer/gate.js +12 -12
  34. package/dist/computer/index.d.ts +57 -255
  35. package/dist/computer/index.js +98 -1039
  36. package/dist/computer/paths.d.ts +47 -22
  37. package/dist/computer/paths.js +64 -49
  38. package/dist/computer/proxy.d.ts +45 -0
  39. package/dist/computer/proxy.js +234 -0
  40. package/dist/computer/render.d.ts +27 -38
  41. package/dist/computer/render.js +32 -65
  42. package/dist/computer/tools-exec.d.ts +3 -0
  43. package/dist/computer/tools-exec.js +268 -0
  44. package/dist/computer/tools-file.d.ts +12 -0
  45. package/dist/computer/tools-file.js +64 -0
  46. package/dist/computer/tools-grep.d.ts +3 -0
  47. package/dist/computer/tools-grep.js +129 -0
  48. package/dist/repo/checkout.d.ts +35 -6
  49. package/dist/repo/checkout.js +64 -6
  50. package/dist/repo/context.d.ts +135 -0
  51. package/dist/repo/context.js +582 -0
  52. package/dist/repo/index.d.ts +79 -57
  53. package/dist/repo/index.js +118 -1112
  54. package/dist/repo/tools-checks.d.ts +3 -0
  55. package/dist/repo/tools-checks.js +112 -0
  56. package/dist/repo/tools-clone.d.ts +4 -0
  57. package/dist/repo/tools-clone.js +192 -0
  58. package/dist/repo/tools-pr.d.ts +14 -0
  59. package/dist/repo/tools-pr.js +196 -0
  60. package/dist/repo/tools-review.d.ts +12 -0
  61. package/dist/repo/tools-review.js +393 -0
  62. package/dist/repo/tools-worktree.d.ts +4 -0
  63. package/dist/repo/tools-worktree.js +305 -0
  64. package/dist/repo/tools-worktrees.d.ts +12 -0
  65. package/dist/repo/tools-worktrees.js +48 -0
  66. package/dist/repo/url.d.ts +2 -2
  67. package/dist/repo/url.js +7 -7
  68. package/dist/scratch/index.d.ts +4 -4
  69. package/dist/scratch/index.js +12 -11
  70. package/dist/{computer → workspace}/advisory.d.ts +33 -20
  71. package/dist/{computer → workspace}/advisory.js +32 -7
  72. package/dist/workspace/ca-trust.d.ts +95 -0
  73. package/dist/workspace/ca-trust.js +312 -0
  74. package/dist/workspace/container-deps.d.ts +54 -0
  75. package/dist/workspace/container-deps.js +224 -0
  76. package/dist/workspace/container-fault.d.ts +38 -0
  77. package/dist/workspace/container-fault.js +73 -0
  78. package/dist/workspace/exec.d.ts +94 -0
  79. package/dist/workspace/exec.js +153 -0
  80. package/dist/workspace/format.d.ts +36 -0
  81. package/dist/workspace/format.js +57 -0
  82. package/dist/workspace/git-host.d.ts +79 -0
  83. package/dist/workspace/git-host.js +226 -0
  84. package/dist/workspace/git-identity.d.ts +57 -0
  85. package/dist/workspace/git-identity.js +147 -0
  86. package/dist/workspace/index.d.ts +43 -47
  87. package/dist/workspace/index.js +52 -112
  88. package/dist/workspace/install-job.d.ts +121 -0
  89. package/dist/workspace/install-job.js +866 -0
  90. package/dist/{computer → workspace}/install.d.ts +15 -19
  91. package/dist/{computer → workspace}/install.js +8 -11
  92. package/dist/workspace/object.d.ts +502 -0
  93. package/dist/workspace/object.js +1427 -0
  94. package/dist/workspace/open.d.ts +95 -0
  95. package/dist/workspace/open.js +63 -0
  96. package/dist/workspace/read.d.ts +16 -0
  97. package/dist/workspace/read.js +22 -0
  98. package/dist/workspace/shell.d.ts +45 -0
  99. package/dist/workspace/shell.js +80 -0
  100. package/dist/workspace/sync.d.ts +111 -0
  101. package/dist/workspace/sync.js +124 -0
  102. package/dist/workspace/wake.d.ts +19 -0
  103. package/dist/workspace/wake.js +10 -0
  104. package/package.json +28 -42
  105. package/dist/arc-agi/analysis.d.ts +0 -336
  106. package/dist/arc-agi/analysis.js +0 -829
  107. package/dist/arc-agi/client.d.ts +0 -82
  108. package/dist/arc-agi/client.js +0 -113
  109. package/dist/arc-agi/game-tools.d.ts +0 -25
  110. package/dist/arc-agi/game-tools.js +0 -26
  111. package/dist/arc-agi/index.d.ts +0 -42
  112. package/dist/arc-agi/index.js +0 -175
  113. package/dist/arc-agi/main-agent.d.ts +0 -27
  114. package/dist/arc-agi/main-agent.js +0 -65
  115. package/dist/arc-agi/recipe.d.ts +0 -51
  116. package/dist/arc-agi/recipe.js +0 -100
  117. package/dist/arc-agi/scorecard.d.ts +0 -118
  118. package/dist/arc-agi/scorecard.js +0 -163
  119. package/dist/arc-agi/soul.d.ts +0 -40
  120. package/dist/arc-agi/soul.js +0 -90
  121. package/dist/arc-agi/store.d.ts +0 -154
  122. package/dist/arc-agi/store.js +0 -216
  123. package/dist/arc-agi/tools.d.ts +0 -36
  124. package/dist/arc-agi/tools.js +0 -576
  125. package/dist/arc-agi/types.d.ts +0 -212
  126. package/dist/arc-agi/types.js +0 -19
  127. package/dist/claude-code/recipe.d.ts +0 -53
  128. package/dist/claude-code/recipe.js +0 -100
  129. package/dist/computer/read.d.ts +0 -137
  130. package/dist/computer/read.js +0 -203
  131. package/dist/recall/index.d.ts +0 -99
  132. package/dist/recall/index.js +0 -171
  133. package/dist/triage/index.d.ts +0 -355
  134. package/dist/triage/index.js +0 -302
@@ -1,100 +0,0 @@
1
- import { z } from "zod";
2
- import { ARC_GAME_SOUL } from "./soul.js";
3
- import { ARC_CAPABILITY, arcDelegationGuidance } from "./main-agent.js";
4
- /** Semantic Subtask type the decomposer emits for a "play this game" request. */
5
- export const ARC_GAME_TYPE = "arc-game";
6
- /**
7
- * Recipe for playing an ARC-AGI-3 game. Names no model, so it runs on whatever
8
- * pair its host agent is configured with; what distinguishes it is its tool
9
- * family, its soul, its context discipline, and
10
- * a turn budget twice the baseline — a play is a long sequence of cheap decisions,
11
- * and 20 turns bought roughly ten game actions once inspection was paid for.
12
- *
13
- * It used to be "the long recipe", budgeted at 1,000 turns on the reasoning that
14
- * 25 turns per chunk made 40 durable chunks. That arithmetic assumed a turn under
15
- * ten seconds. A turn here is a reasoning model plus an ARC HTTP round trip, so
16
- * real runs took 70-100 chunks, blew the per-branch cap, and were *failed* after
17
- * hours of unattended play rather than being asked to report. The budget is now
18
- * time and turns, both enforced directly, and a play ends through the graceful
19
- * summary — a terminal report with the metrics footer.
20
- *
21
- * - `historyWindow` bounds context, and it is now the model's *only* memory: the
22
- * workspace tools are gone (see below), so a plan that scrolls out of it is
23
- * gone. Note it counts *assistant messages* — one per tool call, not one per
24
- * game action — so a play spends it several times faster than the number
25
- * suggests.
26
- * - `reportMetrics` appends the turns/model-calls/wall-clock footer the user
27
- * asked to see.
28
- *
29
- * Tool family: `arc-game` alone (act/inspect against the ARC REST API, session
30
- * state kept in the workspace), code-validated by
31
- * `validateRecipe`/`buildRecipeTools`.
32
- *
33
- * It used to also carry `workspace`, on the theory that a small history window
34
- * needs a file store behind it. Two logged plays say otherwise: `ws_read` was
35
- * never called once, and the three `ws_write` calls between them were a
36
- * scratchpad for arithmetic — a use that costs a turn per note and now belongs in
37
- * `arc_act`'s `note` field, which costs none and stays in the model's own history.
38
- * The session file is unaffected: the family reaches the workspace through its
39
- * {@link file://../../agent/tools.ts ToolFamilyContext}, not through the tools the
40
- * model can see.
41
- */
42
- export const ARC_GAME_RECIPE = {
43
- key: ARC_GAME_TYPE,
44
- version: 1,
45
- // A recipe states no model, and `ResolvedRecipe` has no field to state one
46
- // with. Every recipe runs on the agent's own configured pair, which
47
- // `validateRecipe` stamps onto the `ValidatedRecipe` a runner consumes.
48
- soul: ARC_GAME_SOUL,
49
- toolFamilies: ["arc-game"],
50
- enabled: true,
51
- // Twice the baseline turns, and the largest number that keeps
52
- // `MAX_CHUNKS_PER_BRANCH` unreachable: a yielding chunk always advanced at least
53
- // one turn, so a run takes at most `maxTurns` chunks and the cap is 40. Asserted
54
- // in `test/agent/subtasks/subtask-types.spec.ts` — raising this past 39 is a
55
- // platform change, not a recipe one.
56
- //
57
- // `maxWallMs` deliberately stays at the 30-minute baseline. Measured turns run
58
- // ~15s but reach 165s, so time may well end a play before turn 39 does; both
59
- // ceilings end it the same way, through the graceful summary, so the cost of
60
- // guessing wrong here is a shorter play rather than lost work.
61
- limits: { maxTurns: 39 },
62
- // Counts assistant messages (tool calls), so an inspect + act cycle spends two
63
- // or three of these per game action; 12 left the model unable to see more than a
64
- // couple of moves back, which it answered by re-inspecting.
65
- //
66
- // Lowered from 32 because `elideToolOutputs` changed what a slot *costs*, not
67
- // how many there are: a turn that has aged past the detail window now carries
68
- // its reasoning and its `note` but not the board render that was nearly all of
69
- // its tokens. 32 was the compensation for losing the workspace tools, and the
70
- // thing it was compensating for — reach — is unaffected by the elision.
71
- historyWindow: 24,
72
- reportMetrics: true
73
- };
74
- /**
75
- * The arc-game type. Its one param is an id the model quotes back from a tool
76
- * result it already saw, so the contract is checkable before anything runs: a
77
- * play with no game cannot succeed, and refusing it here costs no model call.
78
- *
79
- * There is deliberately no `card_id`. Which scorecard a play runs on is not a
80
- * choice — the API auto-closes an idle card, so the live card is whichever one
81
- * was used recently — and the parent leases it per chunk (see
82
- * {@link file://./scorecard.ts}), handing it to the execution as runtime state.
83
- */
84
- export const ARC_GAME_SPEC = {
85
- key: ARC_GAME_TYPE,
86
- description: "Play one ARC-AGI-3 game.",
87
- params: z.object({
88
- game_id: z.string().min(1).describe("An exact game id from arc_list_games")
89
- }),
90
- paramsHelp: "requires param `game_id` (an exact id from `arc_list_games`)",
91
- // Everything the main agent is told about ARC is declared here, never written
92
- // inside a runtime — see {@link file://./main-agent.ts}. Both blocks live on
93
- // the *type* rather than on the plugin, because a plugin that declares a
94
- // subtask type has two places it could put a capability block and they are
95
- // rendered by different call sites: setting both makes the main agent read the
96
- // same advice twice per round, which is the exact drift these fields ended.
97
- capability: ARC_CAPABILITY,
98
- delegationGuidance: arcDelegationGuidance,
99
- recipe: ARC_GAME_RECIPE
100
- };
@@ -1,118 +0,0 @@
1
- import type { ArcClient } from "./client.js";
2
- import type { CookieJar, FrameResponse, Scorecard, ScorecardSummary } from "./types.js";
3
- /**
4
- * The `arc-game` recipe's scorecard policy: which card a play runs on, and what
5
- * that play scored.
6
- *
7
- * Neither is a model's decision any more. The ARC API auto-closes a card after
8
- * ~15 minutes idle, which makes the whole open/close lifecycle the *server's* —
9
- * so the only judgement left is arithmetic: a card used recently is still alive
10
- * and every concurrent play should share it; an older one is gone and a new card
11
- * has to be opened. That is {@link resolveScorecard}, run by the parent once per
12
- * durable chunk (a subagent facet has no DB, so it cannot own this).
13
- *
14
- * Because nothing closes a card, the score is *read* rather than returned:
15
- * `GET /api/scorecard/{card_id}` works on an open card, and
16
- * {@link gameScoreReport} appends the finished game's entry to its play's report.
17
- *
18
- * Handlers are exported separately from any tool wiring so they unit-test without
19
- * an LLM, and {@link ScorecardStore} is a narrow interface (`AgentDB.scorecards`
20
- * satisfies it structurally) so tests can pass an in-memory fake.
21
- */
22
- /**
23
- * How long a card stays reusable. Deliberately a minute short of the API's ~15
24
- * minute idle auto-close: the clock is bumped per durable chunk, and a chunk is
25
- * capped at `CHUNK_SOFT_MS` (4 minutes), so the margin only has to cover the gap
26
- * between two bumps — not a whole play.
27
- */
28
- export declare const SCORECARD_REUSE_MS: number;
29
- /** The slice of `AgentDB.scorecards` the scorecard policy needs. */
30
- export interface ScorecardStore {
31
- findRecent(since: number): Scorecard | null;
32
- get(cardId: string): Scorecard | null;
33
- open(cardId: string, cookies: CookieJar): Scorecard;
34
- setGuid(cardId: string, gameId: string, guid: string): void;
35
- touch(cardId: string): void;
36
- }
37
- export interface ArcScorecardDeps {
38
- store: ScorecardStore;
39
- client: ArcClient;
40
- }
41
- /** The resolved card a play runs on: its id, and the jar the API pinned to it. */
42
- export interface ResolvedScorecard {
43
- cardId: string;
44
- cookies: CookieJar;
45
- }
46
- /**
47
- * Lease a scorecard for a play: reuse the most recently used live card, or open a
48
- * new one. Either way the card's clock is restarted, so a play that keeps calling
49
- * this (once per chunk) keeps its own card alive for as long as it runs.
50
- *
51
- * `now` is injected so the window is testable at its boundary.
52
- */
53
- export declare function resolveScorecard(deps: ArcScorecardDeps, now?: number): Promise<ResolvedScorecard>;
54
- /** A play a subagent can join: the card, and the ARC session handle on it. */
55
- export interface ResolvedPlay extends ResolvedScorecard {
56
- /** The ARC play handle. Every ACTION is addressed to it. */
57
- guid: string;
58
- /**
59
- * The opening frame — present **only** on the call that minted the guid, and
60
- * absent on every later resolution of the same play. There is no ARC endpoint
61
- * that reads a board back, so this is the one chance to hand one over; a
62
- * subagent that joins later learns the board from its first ACTION instead.
63
- */
64
- frame?: FrameResponse;
65
- }
66
- /**
67
- * Resolve the play a Subtask runs: the leased card, plus the guid for this game
68
- * on it — reusing the recorded one, or RESETting **once** to mint it.
69
- *
70
- * This is the only RESET in the system. A guid is mintable only by RESET, and a
71
- * second RESET is a second run on the card: separately scored, with whatever the
72
- * first play reached left behind. Pinning one guid per (card, game) in the store
73
- * is what makes a re-dispatched Subtask, a lost workspace, or a later chunk
74
- * rejoin the play in progress instead of quietly starting another — so a
75
- * GAME_OVER stays the result this card recorded for this game.
76
- */
77
- export declare function resolvePlay(deps: ArcScorecardDeps, gameId: string, now?: number): Promise<ResolvedPlay>;
78
- /**
79
- * {@link resolvePlay} on a card the caller has **already** leased.
80
- *
81
- * Split out because resolving the card inside is a race the caller may have
82
- * gone to trouble to avoid: a host that collapses concurrent scorecard leases
83
- * onto one call (as the plugin does) would have that work bypassed entirely if
84
- * every play re-resolved its own card. Two plays for *different* games starting
85
- * together would then each find an empty ledger and each open a card, which is
86
- * exactly the shared-card behaviour the collapse exists to produce.
87
- */
88
- export declare function resolvePlayOn(deps: ArcScorecardDeps, card: ResolvedScorecard, gameId: string): Promise<ResolvedPlay>;
89
- /**
90
- * Exactly what a game's report may be built from — deliberately narrower than
91
- * {@link ScorecardSummary}, which also carries card-wide totals. Narrowing it
92
- * here makes quoting one of those totals as a game's own result a type error
93
- * rather than a judgement call, which is the mistake this guards.
94
- */
95
- export type GameScoreSource = Pick<ScorecardSummary, "card_id" | "environments">;
96
- /**
97
- * What one game scored on a card: its aggregate, then a line per play.
98
- *
99
- * Reads **only** the game's own `environments` entry. Every top-level field of
100
- * the response (`score`, `total_actions`, `total_levels_completed`, …) covers the
101
- * whole card, and since concurrent plays share a card by design, quoting one as
102
- * this game's result would be a straightforward mislabeling — verified against
103
- * the live API, where a card with two games reported both games' actions at the
104
- * top level.
105
- */
106
- export declare function renderGameScore(summary: GameScoreSource, gameId: string): string;
107
- /**
108
- * The finished play's score, as a line to append to its report — or null if it
109
- * cannot be read.
110
- *
111
- * Best-effort by contract: this runs *after* a play has already succeeded, so a
112
- * rate-limited or malformed score response must cost the run nothing. Every
113
- * failure is logged and swallowed.
114
- *
115
- * Reads with the card's stored jar rather than the play's: the play's jar drifted
116
- * across chunks, while the stored one is the session the API pinned the card to.
117
- */
118
- export declare function gameScoreReport(deps: ArcScorecardDeps, cardId: string, gameId: string): Promise<string | null>;
@@ -1,163 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * The `arc-game` recipe's scorecard policy: which card a play runs on, and what
4
- * that play scored.
5
- *
6
- * Neither is a model's decision any more. The ARC API auto-closes a card after
7
- * ~15 minutes idle, which makes the whole open/close lifecycle the *server's* —
8
- * so the only judgement left is arithmetic: a card used recently is still alive
9
- * and every concurrent play should share it; an older one is gone and a new card
10
- * has to be opened. That is {@link resolveScorecard}, run by the parent once per
11
- * durable chunk (a subagent facet has no DB, so it cannot own this).
12
- *
13
- * Because nothing closes a card, the score is *read* rather than returned:
14
- * `GET /api/scorecard/{card_id}` works on an open card, and
15
- * {@link gameScoreReport} appends the finished game's entry to its play's report.
16
- *
17
- * Handlers are exported separately from any tool wiring so they unit-test without
18
- * an LLM, and {@link ScorecardStore} is a narrow interface (`AgentDB.scorecards`
19
- * satisfies it structurally) so tests can pass an in-memory fake.
20
- */
21
- /**
22
- * How long a card stays reusable. Deliberately a minute short of the API's ~15
23
- * minute idle auto-close: the clock is bumped per durable chunk, and a chunk is
24
- * capped at `CHUNK_SOFT_MS` (4 minutes), so the margin only has to cover the gap
25
- * between two bumps — not a whole play.
26
- */
27
- export const SCORECARD_REUSE_MS = 14 * 60_000;
28
- /**
29
- * Lease a scorecard for a play: reuse the most recently used live card, or open a
30
- * new one. Either way the card's clock is restarted, so a play that keeps calling
31
- * this (once per chunk) keeps its own card alive for as long as it runs.
32
- *
33
- * `now` is injected so the window is testable at its boundary.
34
- */
35
- export async function resolveScorecard(deps, now = Date.now()) {
36
- const recent = deps.store.findRecent(now - SCORECARD_REUSE_MS);
37
- if (recent) {
38
- deps.store.touch(recent.cardId);
39
- return { cardId: recent.cardId, cookies: recent.cookies };
40
- }
41
- const { cardId, cookies } = await deps.client.openScorecard({});
42
- deps.store.open(cardId, cookies);
43
- return { cardId, cookies };
44
- }
45
- /**
46
- * Resolve the play a Subtask runs: the leased card, plus the guid for this game
47
- * on it — reusing the recorded one, or RESETting **once** to mint it.
48
- *
49
- * This is the only RESET in the system. A guid is mintable only by RESET, and a
50
- * second RESET is a second run on the card: separately scored, with whatever the
51
- * first play reached left behind. Pinning one guid per (card, game) in the store
52
- * is what makes a re-dispatched Subtask, a lost workspace, or a later chunk
53
- * rejoin the play in progress instead of quietly starting another — so a
54
- * GAME_OVER stays the result this card recorded for this game.
55
- */
56
- export async function resolvePlay(deps, gameId, now = Date.now()) {
57
- return resolvePlayOn(deps, await resolveScorecard(deps, now), gameId);
58
- }
59
- /**
60
- * {@link resolvePlay} on a card the caller has **already** leased.
61
- *
62
- * Split out because resolving the card inside is a race the caller may have
63
- * gone to trouble to avoid: a host that collapses concurrent scorecard leases
64
- * onto one call (as the plugin does) would have that work bypassed entirely if
65
- * every play re-resolved its own card. Two plays for *different* games starting
66
- * together would then each find an empty ledger and each open a card, which is
67
- * exactly the shared-card behaviour the collapse exists to produce.
68
- */
69
- export async function resolvePlayOn(deps, card, gameId) {
70
- const { cardId, cookies } = card;
71
- const recorded = deps.store.get(cardId)?.guids[gameId];
72
- if (recorded !== undefined)
73
- return { cardId, cookies, guid: recorded };
74
- const { frame, cookies: next } = await deps.client.reset({ gameId, cardId }, cookies);
75
- deps.store.setGuid(cardId, gameId, frame.guid);
76
- // `setGuid` keeps the first guid written, so losing a race to a concurrent
77
- // resolution means this RESET opened a play nobody will join. Hand back the
78
- // guid that won — and not this frame, which belongs to the abandoned play.
79
- const winner = deps.store.get(cardId)?.guids[gameId] ?? frame.guid;
80
- return winner === frame.guid
81
- ? { cardId, cookies: next, guid: frame.guid, frame }
82
- : { cardId, cookies: next, guid: winner };
83
- }
84
- /**
85
- * Loose on purpose: a field the API adds tomorrow must not turn a real result
86
- * into a parse error. The fields asserted here are the ones
87
- * {@link renderGameScore} actually renders.
88
- */
89
- const runSchema = z.looseObject({
90
- guid: z.string(),
91
- actions: z.number(),
92
- completed: z.boolean(),
93
- levels_completed: z.number(),
94
- resets: z.number(),
95
- score: z.number(),
96
- state: z.enum(["NOT_STARTED", "NOT_FINISHED", "WIN", "GAME_OVER"])
97
- });
98
- const environmentSchema = z.looseObject({
99
- id: z.string(),
100
- actions: z.number(),
101
- completed: z.boolean(),
102
- level_count: z.number(),
103
- levels_completed: z.number(),
104
- resets: z.number(),
105
- score: z.number(),
106
- runs: z.array(runSchema)
107
- });
108
- const summarySchema = z.looseObject({
109
- card_id: z.string(),
110
- environments: z.array(environmentSchema)
111
- });
112
- /**
113
- * What one game scored on a card: its aggregate, then a line per play.
114
- *
115
- * Reads **only** the game's own `environments` entry. Every top-level field of
116
- * the response (`score`, `total_actions`, `total_levels_completed`, …) covers the
117
- * whole card, and since concurrent plays share a card by design, quoting one as
118
- * this game's result would be a straightforward mislabeling — verified against
119
- * the live API, where a card with two games reported both games' actions at the
120
- * top level.
121
- */
122
- export function renderGameScore(summary, gameId) {
123
- // Match by id rather than taking the sole entry on trust: a mislabeled result
124
- // is worse than none.
125
- const env = summary.environments.find((e) => e.id === gameId);
126
- if (!env || env.runs.length === 0) {
127
- return `Scorecard ${summary.card_id} recorded no plays of ${gameId}.`;
128
- }
129
- const header = `Score for ${gameId} on scorecard ${summary.card_id}: ` +
130
- `${env.score} — ${env.levels_completed}/${env.level_count} levels, ` +
131
- `${env.actions} actions across ${env.runs.length} play(s)` +
132
- (env.completed ? " (completed)" : "") +
133
- ".";
134
- const plays = env.runs.map((run, index) => `- play ${index + 1}: ${run.state}, ${run.levels_completed} level(s), ` +
135
- `${run.actions} actions, score ${run.score}`);
136
- return `${header}\n${plays.join("\n")}`;
137
- }
138
- /**
139
- * The finished play's score, as a line to append to its report — or null if it
140
- * cannot be read.
141
- *
142
- * Best-effort by contract: this runs *after* a play has already succeeded, so a
143
- * rate-limited or malformed score response must cost the run nothing. Every
144
- * failure is logged and swallowed.
145
- *
146
- * Reads with the card's stored jar rather than the play's: the play's jar drifted
147
- * across chunks, while the stored one is the session the API pinned the card to.
148
- */
149
- export async function gameScoreReport(deps, cardId, gameId) {
150
- try {
151
- const card = deps.store.get(cardId);
152
- const { summary } = await deps.client.getScorecard(cardId, card?.cookies ?? {});
153
- return renderGameScore(summarySchema.parse(summary), gameId);
154
- }
155
- catch (err) {
156
- console.warn("[arc-game] scorecard read failed", {
157
- cardId,
158
- gameId,
159
- err: String(err)
160
- });
161
- return null;
162
- }
163
- }
@@ -1,40 +0,0 @@
1
- /**
2
- * The soul (system prompt) for the ARC-AGI-3 game-playing recipe. The domain
3
- * mechanics (sessions, cookies, frame analysis) live entirely in the `arc-game`
4
- * tool family; this prompt only tells the model how to play.
5
- *
6
- * It plays on a scorecard the parent leased for it. The game is a declared
7
- * Subtask param and the card is resolved runtime state, so the tools close over
8
- * both and the model never names, chooses, or copies either id.
9
- *
10
- * Three sections here are written against specific, logged failures rather than
11
- * against a theory of good play, and each says so where it sits:
12
- *
13
- * - **Memory** used to be workspace discipline ("write your notes to a file").
14
- * Two plays never read a note back, so the notes are gone and what replaces
15
- * them is `arc_act`'s `note` field, which costs no turn.
16
- * - **Finishing** used to ask for the rules "in prose", and got a final report
17
- * whose central claim its own last tool result contradicted. It now asks for
18
- * provenance: observed, inferred, or untested.
19
- * - **Inherited knowledge** is new. A play handed a route from an earlier play
20
- * executed it faithfully while the board disagreed, because nothing told it
21
- * that what it was given was a guess about a level nobody had finished.
22
- * - **Reading a step's result** used to teach one phrase, `nothing moved`, as the
23
- * whole vocabulary of a step that achieved nothing. That is a movement game's
24
- * vocabulary: a click game moves nothing ever, and the play that found this out
25
- * was told its every click had been "refused or blocked" while each was toggling
26
- * a 36-cell block. The registers are now named separately here and rendered
27
- * separately in {@link file://./analysis.ts}.
28
- * - **Where the views stand** was rewritten against measurements. It used to sell
29
- * `shapes` as cheap and `grid` as the expensive last resort; three logged plays
30
- * answered by calling `region` twelve times and `grid` not once, mapping a maze
31
- * through 11×11 peepholes because the one line `shapes` gave them for the wall
32
- * was its full-board bounding box. `shapes` now carries the terrain itself, and
33
- * the full grid of a real board is 35 collapsed lines — so the ordering here is
34
- * `shapes` for the map, `grid` for exact cells, `region` for fine detail only.
35
- * The batching section gained the step that follows from it: a route is checked
36
- * against those bands before it is sent. That check lives here rather than in
37
- * the tool because it is a judgement about the game's rules — what blocks what —
38
- * and a tool that made it would be guessing on the model's behalf.
39
- */
40
- export declare const ARC_GAME_SOUL: string;
@@ -1,90 +0,0 @@
1
- /**
2
- * The soul (system prompt) for the ARC-AGI-3 game-playing recipe. The domain
3
- * mechanics (sessions, cookies, frame analysis) live entirely in the `arc-game`
4
- * tool family; this prompt only tells the model how to play.
5
- *
6
- * It plays on a scorecard the parent leased for it. The game is a declared
7
- * Subtask param and the card is resolved runtime state, so the tools close over
8
- * both and the model never names, chooses, or copies either id.
9
- *
10
- * Three sections here are written against specific, logged failures rather than
11
- * against a theory of good play, and each says so where it sits:
12
- *
13
- * - **Memory** used to be workspace discipline ("write your notes to a file").
14
- * Two plays never read a note back, so the notes are gone and what replaces
15
- * them is `arc_act`'s `note` field, which costs no turn.
16
- * - **Finishing** used to ask for the rules "in prose", and got a final report
17
- * whose central claim its own last tool result contradicted. It now asks for
18
- * provenance: observed, inferred, or untested.
19
- * - **Inherited knowledge** is new. A play handed a route from an earlier play
20
- * executed it faithfully while the board disagreed, because nothing told it
21
- * that what it was given was a guess about a level nobody had finished.
22
- * - **Reading a step's result** used to teach one phrase, `nothing moved`, as the
23
- * whole vocabulary of a step that achieved nothing. That is a movement game's
24
- * vocabulary: a click game moves nothing ever, and the play that found this out
25
- * was told its every click had been "refused or blocked" while each was toggling
26
- * a 36-cell block. The registers are now named separately here and rendered
27
- * separately in {@link file://./analysis.ts}.
28
- * - **Where the views stand** was rewritten against measurements. It used to sell
29
- * `shapes` as cheap and `grid` as the expensive last resort; three logged plays
30
- * answered by calling `region` twelve times and `grid` not once, mapping a maze
31
- * through 11×11 peepholes because the one line `shapes` gave them for the wall
32
- * was its full-board bounding box. `shapes` now carries the terrain itself, and
33
- * the full grid of a real board is 35 collapsed lines — so the ordering here is
34
- * `shapes` for the map, `grid` for exact cells, `region` for fine detail only.
35
- * The batching section gained the step that follows from it: a route is checked
36
- * against those bands before it is sent. That check lives here rather than in
37
- * the tool because it is a judgement about the game's rules — what blocks what —
38
- * and a tool that made it would be guessing on the model's behalf.
39
- */
40
- export const ARC_GAME_SOUL = [
41
- "You are playing an ARC-AGI-3 game: a visual-reasoning puzzle on a 64×64 grid of colored cells. You discover the game's hidden rules by acting and observing, and progress through levels toward a win.",
42
- "",
43
- "# How to play",
44
- "1. Your game is already running — there is nothing to start. Which game you play, and on which scorecard, were decided before you began. Start with `arc_inspect` (`shapes` view) to see where everything is, or go straight to `arc_act` if you already know what to try. Either way the reply tells you the current level, the game state, and which actions are legal right now (`available_actions`). If `arc_inspect` says no board has arrived yet, the play was opened before you joined it: your first `arc_act` step is also how the board reaches you, so spend it on a direction you wanted to try anyway rather than on a probe.",
45
- "2. Call `arc_act` with the `steps` you want to take, in order. Actions: 1=up, 2=down, 3=left, 4=right, 5=interact/select, 6=click at an (x,y) coordinate (x and y are required for action 6 only), 7=undo.",
46
- "3. `arc_act` reports each step separately, in the register that step calls for: which shapes moved, from where to where and how far; which changed color where they stood, appeared, or vanished; `0 cells changed (no effect at all)` when the game refused the action outright; and `nothing moved` when objects stayed put while a counter or a bar ticked, which in a game you steer is a wall. Read `no shape travelled, but the board changed` as what it says — that action did something, and what it did is on the same line. After a batch you also get the net travel per shape, counted in moves rather than cells, and how many steps changed nothing at all. Trust those lines over your own arithmetic: where the report says you are is where you are.",
47
- "4. When you need to see the board itself, call `arc_inspect`. `shapes` is your map and the view to reach for: it lists every colored region with the rows and columns it occupies, and for the big sparse ones — walls, floors, frames, anything that is mostly holes — it gives the columns that color occupies in each band of rows, because a bounding box round a maze says nothing. `grid` is the whole board, one character per cell with a legend; it is not the expensive option it sounds like, since bands of identical rows collapse into one line, and it is the right call when you need exact cells. `region` is a labeled close-up around a point — use it to read fine detail, not to map a board a row band at a time. `histogram` is the color counts. Inspecting costs no game action, but it costs a turn out of your budget — and repeating a view of a board that has not changed tells you nothing, so the tool will say so instead of drawing it again. Inspect to answer a question you actually have; otherwise act.",
48
- "",
49
- "# Colors",
50
- "Results name colors rather than numbering them. Some are deliberately close relatives: magenta and magenta-light, blue and blue-light, neutral and neutral-light. Treat those as distinct colors that a game may well use as a pair. `white` is the usual background. In the `grid` view each cell is one character and the legend tells you which color it stands for — the `b` in the grid and the `yellow` in a diff can be the same color.",
51
- "A color that spreads thinly over a large area is described by the rows and columns it actually occupies rather than by one box: `too sparse for a box, so by row:` followed by a line per band of rows. Read those lines as the same kind of fact as a box, at the resolution you need to walk through it. The percentage in front of them is how much of that box the color really fills — a low one is your warning that the rest of the box is something else.",
52
- "",
53
- "# Batching actions",
54
- "`steps` accepts up to 8 actions. Batch the whole path you mean to walk — a batch is one turn where eight single steps are eight, and turns are the budget you will actually run out of. What a batch reports back is per step, so you lose no information by sending several at once: you see which of them moved something and which did not.",
55
- "- Send ONE step when you are still working out what an action even does, and the result will teach you. Send the whole route once you know the mechanics.",
56
- "- A batch runs to the end whatever happens: a step that hits a wall does not stop the ones after it, and each of them still costs an action. So batch a route you have reason to believe in, and read the idle steps and the net travel afterwards to find out where your belief was wrong.",
57
- "- Walk the route against the board before you send it. You know where you are and how far one action moves you, so every step of a planned batch lands on a row range and a column range — and the `shapes` view already told you, band by band, which color occupies those rows and columns. Check the destination of each step against that before you commit to it. Nothing will stop you sending a step into a wall, and the walls are not going to be mentioned unless you look them up.",
58
- "- A batch does stop early if an action is not available or the play ends; steps it did not send are listed as `not sent`, so trust that list rather than assuming all your steps ran.",
59
- "- Every step is a real move, and the game scores you against a human baseline number of actions. Actions spent on a guess that turns out wrong cost you score, whether you spent them one at a time or eight at once.",
60
- "",
61
- "# Strategy",
62
- "- Start by exploring: try single actions and watch what changes, to learn the mechanics before committing to a plan.",
63
- "- `available_actions` is the game's own declaration of what is legal — a keyboard-only game will never offer click, however long you wait. Do not spend actions probing for actions it has not offered; work with what it lists.",
64
- "- Look for structure: repeated shapes, symmetry, color regions, objects that move or transform when you act. Watch what moves *besides* the thing you are steering — a shape that travels with you, against you, or only when you act is a mechanic, and every moved shape is named in the result.",
65
- "- A step that did nothing is a real clue, not a failure: a wall, an edge, or a rule stopped that action. Two `nothing moved` or `0 cells changed` in the same direction means that direction is closed, and a third will be too. But judge that per game: in a game played by clicking, nothing was ever going to travel, so the useful distinction is between clicks that changed the board and clicks that changed not one cell.",
66
- "- If `levels_completed` goes up, your approach is working — keep going. If nothing changes across several tries, change tactics.",
67
- "- Undo (action 7) is cheap when a move looks like a mistake and undo is available.",
68
- "- You get ONE play, and it is the play you were handed — not one you can open. There is no restart: a WIN or a GAME_OVER is final, and it is the result your scorecard records for this game. So treat every action as spent for good — think before you act rather than counting on another attempt, and when the play ends, report what happened instead of trying to undo it.",
69
- "",
70
- "# The scorecard is not yours",
71
- "A scorecard was chosen for you, and you may be sharing it with other games being played right now. You have no tool to open, close, choose, or score a card — do not claim a score, and do not treat reaching WIN or GAME_OVER as something you must clean up. Your game's score is read from the card and appended to your report after you finish.",
72
- "",
73
- "# What you were told, and what you have seen",
74
- "Your task may hand you knowledge from an earlier play: a route, a map, what the colors mean. Treat it as a well-informed guess, not as fact. It came from a play that did not finish this level — that is why you are here — and levels get harder by adding elements nobody has seen yet, so a route that worked before can be wrong in ways whoever wrote it could not know. Check it against your own first result before you spend a batch on it, and when it turns out wrong, say so in your report: that correction is worth more to the next play than the route was.",
75
- "Your own results outrank everything else. If the board contradicts what you were told, or contradicts what you worked out three turns ago, the board is right.",
76
- "",
77
- "# Memory discipline (important)",
78
- "You do NOT keep your full history in view — only your most recent turns, and you have no file store: there is nowhere to write a note but into the play itself. Use `arc_act`'s `note` field for that. It costs no turn and no action, it rides along with a move you were making anyway, and it stays in your history where you can read it back. Put in it what you would otherwise forget: the rule you just confirmed, the route you are walking and which step of it you are on, what you have already ruled out.",
79
- "You also get your bearings back for free: after any gap in your turns, your next tool result opens by restating where you are — level, state, legal actions, and where every shape sits. So never spend a turn on `arc_inspect` just to re-orient after losing track. Inspect when you want a view you do not have — a close-up, the color counts, the full grid.",
80
- "",
81
- "# Finishing",
82
- "Your work ends when you have nothing useful left to try, or when your budget is exhausted. Your final report is the only thing that survives this play, and the next one will be planned from it — so write it as a handover, in plain text, with these parts:",
83
- "- **Outcome**: which game, the final state (report a GAME_OVER plainly — it is a real outcome, not a failure to hide), and how many levels you completed.",
84
- '- **Confirmed mechanics**: one line each, with the observation that confirmed it — "`right` moved the orange 5×5 five columns; walls report `nothing moved`". Only things a tool result actually showed you.',
85
- "- **Still unknown**: what you suspect but never tested, named as untested. A hypothesis you ran out of turns before checking belongs here, never among the mechanics.",
86
- "- **Where things are**: the geography of the level you reached, taken from your most recent view of it and not from memory.",
87
- "- **What to try next**, and what not to repeat.",
88
- "Two rules for the whole report. Give positions only from your latest view of the board — not from where you believed you were — and if you are stating something you inferred rather than watched happen, say that you inferred it. A confident wrong fact costs the next play more than an admitted gap does.",
89
- "Runtime metrics (turns taken, model calls, wall-clock time) and your game's score are appended automatically — do not invent either, and do not report a scorecard score yourself."
90
- ].join("\n");