@dynamicagents/plugins 0.12.0 → 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.
- package/README.md +58 -77
- package/dist/browser/index.d.ts +0 -2
- package/dist/browser/index.js +21 -27
- package/dist/claude-code/cards.d.ts +53 -0
- package/dist/claude-code/cards.js +272 -0
- package/dist/claude-code/config.d.ts +28 -63
- package/dist/claude-code/config.js +0 -11
- package/dist/claude-code/egress.d.ts +8 -1
- package/dist/claude-code/egress.js +42 -4
- package/dist/claude-code/events.d.ts +106 -9
- package/dist/claude-code/events.js +201 -56
- package/dist/claude-code/github.d.ts +39 -0
- package/dist/claude-code/github.js +82 -0
- package/dist/claude-code/index.d.ts +16 -90
- package/dist/claude-code/index.js +14 -276
- package/dist/claude-code/model.d.ts +152 -0
- package/dist/claude-code/model.js +342 -0
- package/dist/claude-code/run.d.ts +209 -112
- package/dist/claude-code/run.js +339 -138
- package/dist/claude-code/session.d.ts +131 -0
- package/dist/claude-code/session.js +285 -0
- package/dist/claude-code/spec.d.ts +46 -0
- package/dist/claude-code/spec.js +83 -0
- package/dist/claude-code/verified.d.ts +15 -0
- package/dist/claude-code/verified.js +15 -0
- package/dist/computer/context.d.ts +1 -5
- package/dist/computer/context.js +7 -10
- package/dist/computer/file-lock.js +5 -4
- package/dist/computer/gate.d.ts +4 -4
- package/dist/computer/gate.js +5 -5
- package/dist/computer/index.d.ts +40 -258
- package/dist/computer/index.js +71 -324
- package/dist/computer/paths.d.ts +36 -16
- package/dist/computer/paths.js +42 -29
- package/dist/computer/proxy.d.ts +45 -0
- package/dist/computer/proxy.js +234 -0
- package/dist/computer/render.d.ts +1 -40
- package/dist/computer/render.js +2 -68
- package/dist/computer/tools-exec.js +12 -13
- package/dist/computer/tools-file.d.ts +9 -1
- package/dist/computer/tools-file.js +22 -82
- package/dist/computer/{tools-find.d.ts → tools-grep.d.ts} +1 -1
- package/dist/computer/tools-grep.js +129 -0
- package/dist/repo/checkout.d.ts +4 -5
- package/dist/repo/checkout.js +31 -8
- package/dist/repo/context.d.ts +35 -9
- package/dist/repo/context.js +101 -49
- package/dist/repo/index.d.ts +73 -28
- package/dist/repo/index.js +112 -96
- package/dist/repo/tools-checks.d.ts +3 -0
- package/dist/repo/tools-checks.js +112 -0
- package/dist/repo/tools-clone.js +1 -1
- package/dist/repo/tools-pr.d.ts +14 -0
- package/dist/repo/{tools-forge.js → tools-pr.js} +53 -36
- package/dist/repo/tools-review.d.ts +9 -0
- package/dist/repo/tools-review.js +67 -47
- package/dist/repo/tools-worktree.js +144 -60
- package/dist/repo/tools-worktrees.d.ts +12 -0
- package/dist/repo/tools-worktrees.js +48 -0
- package/dist/repo/url.d.ts +2 -2
- package/dist/repo/url.js +7 -7
- package/dist/scratch/index.d.ts +4 -4
- package/dist/scratch/index.js +12 -11
- package/dist/{computer → workspace}/advisory.d.ts +4 -4
- package/dist/{computer → workspace}/advisory.js +2 -2
- package/dist/{computer/host → workspace}/ca-trust.d.ts +8 -1
- package/dist/{computer/host → workspace}/ca-trust.js +12 -3
- package/dist/{computer/host → workspace}/container-fault.d.ts +3 -3
- package/dist/{computer/host → workspace}/container-fault.js +23 -8
- package/dist/workspace/exec.d.ts +94 -0
- package/dist/workspace/exec.js +153 -0
- package/dist/workspace/format.d.ts +36 -0
- package/dist/workspace/format.js +57 -0
- package/dist/{computer/host → workspace}/git-host.d.ts +21 -4
- package/dist/{computer/host → workspace}/git-host.js +72 -2
- package/dist/{computer/host → workspace}/git-identity.d.ts +1 -1
- package/dist/{computer/host → workspace}/git-identity.js +1 -1
- package/dist/workspace/index.d.ts +43 -47
- package/dist/workspace/index.js +52 -112
- package/dist/{computer/host → workspace}/install-job.d.ts +4 -4
- package/dist/{computer/host → workspace}/install-job.js +276 -176
- package/dist/{computer → workspace}/install.d.ts +8 -8
- package/dist/{computer → workspace}/install.js +3 -3
- package/dist/{computer/host/workspace.d.ts → workspace/object.d.ts} +105 -27
- package/dist/{computer/host/workspace.js → workspace/object.js} +217 -48
- package/dist/workspace/open.d.ts +95 -0
- package/dist/workspace/open.js +63 -0
- package/dist/workspace/read.d.ts +16 -0
- package/dist/workspace/read.js +22 -0
- package/dist/{computer → workspace}/shell.d.ts +5 -5
- package/dist/{computer → workspace}/shell.js +6 -6
- package/dist/{computer/host → workspace}/wake.d.ts +1 -1
- package/package.json +16 -36
- package/dist/arc-agi/analysis.d.ts +0 -322
- package/dist/arc-agi/analysis.js +0 -802
- package/dist/arc-agi/client.d.ts +0 -82
- package/dist/arc-agi/client.js +0 -113
- package/dist/arc-agi/game-tools.d.ts +0 -24
- package/dist/arc-agi/game-tools.js +0 -26
- package/dist/arc-agi/index.d.ts +0 -40
- package/dist/arc-agi/index.js +0 -175
- package/dist/arc-agi/main-agent.d.ts +0 -24
- package/dist/arc-agi/main-agent.js +0 -62
- package/dist/arc-agi/recipe.d.ts +0 -48
- package/dist/arc-agi/recipe.js +0 -97
- package/dist/arc-agi/scorecard.d.ts +0 -118
- package/dist/arc-agi/scorecard.js +0 -163
- package/dist/arc-agi/soul.d.ts +0 -29
- package/dist/arc-agi/soul.js +0 -79
- package/dist/arc-agi/store.d.ts +0 -153
- package/dist/arc-agi/store.js +0 -215
- package/dist/arc-agi/tools.d.ts +0 -36
- package/dist/arc-agi/tools.js +0 -574
- package/dist/arc-agi/types.d.ts +0 -211
- package/dist/arc-agi/types.js +0 -19
- package/dist/claude-code/recipe.d.ts +0 -53
- package/dist/claude-code/recipe.js +0 -100
- package/dist/computer/read.d.ts +0 -133
- package/dist/computer/read.js +0 -200
- package/dist/computer/tools-find.js +0 -216
- package/dist/recall/index.d.ts +0 -105
- package/dist/recall/index.js +0 -181
- package/dist/repo/tools-forge.d.ts +0 -4
- package/dist/triage/index.d.ts +0 -360
- package/dist/triage/index.js +0 -311
- /package/dist/{computer/host → workspace}/container-deps.d.ts +0 -0
- /package/dist/{computer/host → workspace}/container-deps.js +0 -0
- /package/dist/{computer/host → workspace}/sync.d.ts +0 -0
- /package/dist/{computer/host → workspace}/sync.js +0 -0
- /package/dist/{computer/host → workspace}/wake.js +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkspaceClient } from "@cloudflare/computer";
|
|
2
|
+
/**
|
|
3
|
+
* Does this path exist?
|
|
4
|
+
*
|
|
5
|
+
* `getWorkspace()` types `fs` as the in-process `WorkspaceFilesystem`, but the
|
|
6
|
+
* value on the far side of a Durable Object boundary is a
|
|
7
|
+
* `WorkspaceFilesystemStub`, which carries a few methods the local class does
|
|
8
|
+
* not — `exists` among them. So the fast path is asked for rather than cast to,
|
|
9
|
+
* and `stat` is the fallback for a host that hands back a local workspace.
|
|
10
|
+
*
|
|
11
|
+
* The fallback treats *any* `stat` failure as absence, which is the honest
|
|
12
|
+
* reading for a tool whose entire answer is a boolean: there is no error channel
|
|
13
|
+
* to distinguish "missing" from "unreadable", and the caller's next move — look
|
|
14
|
+
* somewhere else — is the same either way.
|
|
15
|
+
*/
|
|
16
|
+
export declare function pathExists(fs: WorkspaceClient["fs"], path: string): Promise<boolean>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does this path exist?
|
|
3
|
+
*
|
|
4
|
+
* `getWorkspace()` types `fs` as the in-process `WorkspaceFilesystem`, but the
|
|
5
|
+
* value on the far side of a Durable Object boundary is a
|
|
6
|
+
* `WorkspaceFilesystemStub`, which carries a few methods the local class does
|
|
7
|
+
* not — `exists` among them. So the fast path is asked for rather than cast to,
|
|
8
|
+
* and `stat` is the fallback for a host that hands back a local workspace.
|
|
9
|
+
*
|
|
10
|
+
* The fallback treats *any* `stat` failure as absence, which is the honest
|
|
11
|
+
* reading for a tool whose entire answer is a boolean: there is no error channel
|
|
12
|
+
* to distinguish "missing" from "unreadable", and the caller's next move — look
|
|
13
|
+
* somewhere else — is the same either way.
|
|
14
|
+
*/
|
|
15
|
+
export async function pathExists(fs, path) {
|
|
16
|
+
// Called as a method, never through `.call`: on an RPC stub `.call` is read as
|
|
17
|
+
// a remote method, and the stub it would pass as `this` cannot be serialised.
|
|
18
|
+
const remote = fs;
|
|
19
|
+
if (typeof remote.exists === "function")
|
|
20
|
+
return remote.exists(path);
|
|
21
|
+
return fs.stat(path).then(() => true, () => false);
|
|
22
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Run a command under {@link file://./
|
|
2
|
+
* Run a command under {@link file://./exec.ts WorkspaceClientConfig.shell} with its
|
|
3
3
|
* two output streams left as they are, or hand it back untouched when no shell
|
|
4
4
|
* is configured.
|
|
5
5
|
*
|
|
6
6
|
* This is the variant for a caller that **reads the result in code**: `stdout` is
|
|
7
7
|
* a data channel it compares or parses, and `stderr` is a separate diagnostic.
|
|
8
|
-
* {@link file://./
|
|
8
|
+
* {@link file://./exec.ts workspaceExec} is that caller, on behalf of
|
|
9
9
|
* `@dynamicagents/plugins/repo`, which asks git questions like
|
|
10
10
|
* `symbolic-ref --short refs/remotes/origin/HEAD` and `rev-list --count` and
|
|
11
11
|
* needs the answer alone.
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function withShell(command: string, shell: string | undefined): string;
|
|
21
21
|
/**
|
|
22
|
-
* Run a command under {@link file://./
|
|
22
|
+
* Run a command under {@link file://./exec.ts WorkspaceClientConfig.shell} with its
|
|
23
23
|
* two output streams merged into one transcript, in the order they were
|
|
24
24
|
* written.
|
|
25
25
|
*
|
|
26
26
|
* This is the variant for a caller whose consumer is **a model reading output**.
|
|
27
|
-
* `
|
|
27
|
+
* `bash` is that caller. A project's check is a chain — `wrangler types &&
|
|
28
28
|
* prettier && eslint && tsc` — and *which tool spoke last* is how you know which
|
|
29
29
|
* one failed. A stdout block and a separate stderr block destroy that ordering,
|
|
30
30
|
* and a model that wants it back re-runs the whole gate as
|
|
@@ -38,7 +38,7 @@ export declare function withShell(command: string, shell: string | undefined): s
|
|
|
38
38
|
*
|
|
39
39
|
* With no shell configured there is no wrapper process to redirect, so the
|
|
40
40
|
* command goes to the runtime untouched and the two streams arrive separate.
|
|
41
|
-
* That is not a gap: {@link file
|
|
41
|
+
* That is not a gap: {@link file://../computer/render.ts renderResult} renders them as a
|
|
42
42
|
* labelled `--- stderr ---` block for exactly this case. The transcript is the
|
|
43
43
|
* better answer, not the only supported one.
|
|
44
44
|
*/
|
|
@@ -23,20 +23,20 @@ import { shellQuote } from "@cloudflare/computer";
|
|
|
23
23
|
* truncated with both ends kept.
|
|
24
24
|
*
|
|
25
25
|
* Requires a shell that implements it — `bash`, `zsh`, `ksh`, not `sh`/dash. A
|
|
26
|
-
* host setting {@link file://./
|
|
26
|
+
* host setting {@link file://./exec.ts WorkspaceClientConfig.shell} is choosing that
|
|
27
27
|
* shell explicitly.
|
|
28
28
|
*/
|
|
29
29
|
function wrapped(command, shell) {
|
|
30
30
|
return `${shell} -o pipefail -c ${shellQuote(command)}`;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Run a command under {@link file://./
|
|
33
|
+
* Run a command under {@link file://./exec.ts WorkspaceClientConfig.shell} with its
|
|
34
34
|
* two output streams left as they are, or hand it back untouched when no shell
|
|
35
35
|
* is configured.
|
|
36
36
|
*
|
|
37
37
|
* This is the variant for a caller that **reads the result in code**: `stdout` is
|
|
38
38
|
* a data channel it compares or parses, and `stderr` is a separate diagnostic.
|
|
39
|
-
* {@link file://./
|
|
39
|
+
* {@link file://./exec.ts workspaceExec} is that caller, on behalf of
|
|
40
40
|
* `@dynamicagents/plugins/repo`, which asks git questions like
|
|
41
41
|
* `symbolic-ref --short refs/remotes/origin/HEAD` and `rev-list --count` and
|
|
42
42
|
* needs the answer alone.
|
|
@@ -52,12 +52,12 @@ export function withShell(command, shell) {
|
|
|
52
52
|
return shell ? wrapped(command, shell) : command;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* Run a command under {@link file://./
|
|
55
|
+
* Run a command under {@link file://./exec.ts WorkspaceClientConfig.shell} with its
|
|
56
56
|
* two output streams merged into one transcript, in the order they were
|
|
57
57
|
* written.
|
|
58
58
|
*
|
|
59
59
|
* This is the variant for a caller whose consumer is **a model reading output**.
|
|
60
|
-
* `
|
|
60
|
+
* `bash` is that caller. A project's check is a chain — `wrangler types &&
|
|
61
61
|
* prettier && eslint && tsc` — and *which tool spoke last* is how you know which
|
|
62
62
|
* one failed. A stdout block and a separate stderr block destroy that ordering,
|
|
63
63
|
* and a model that wants it back re-runs the whole gate as
|
|
@@ -71,7 +71,7 @@ export function withShell(command, shell) {
|
|
|
71
71
|
*
|
|
72
72
|
* With no shell configured there is no wrapper process to redirect, so the
|
|
73
73
|
* command goes to the runtime untouched and the two streams arrive separate.
|
|
74
|
-
* That is not a gap: {@link file
|
|
74
|
+
* That is not a gap: {@link file://../computer/render.ts renderResult} renders them as a
|
|
75
75
|
* labelled `--- stderr ---` block for exactly this case. The transcript is the
|
|
76
76
|
* better answer, not the only supported one.
|
|
77
77
|
*/
|
|
@@ -12,7 +12,7 @@ export type WorkspaceWakeHandlers = {
|
|
|
12
12
|
installRun: () => Promise<void>;
|
|
13
13
|
installWatch: () => Promise<void>;
|
|
14
14
|
idleReclaim: () => Promise<void>;
|
|
15
|
-
/** Start a cold container before a command needs it — see `./
|
|
15
|
+
/** Start a cold container before a command needs it — see `./object.ts`. */
|
|
16
16
|
containerWarm: () => Promise<void>;
|
|
17
17
|
containerIdle: (payload?: SyncDrainIntent) => Promise<void>;
|
|
18
18
|
syncRetry: (payload?: SyncDrainIntent) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamicagents/plugins",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Optional, composable capabilities for a Dynamic Agent:
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Optional, composable capabilities for a Dynamic Agent: browser rendering, a Linux container, git and pull requests, a scratchpad, and Claude Code sessions. One subpath per plugin, so a bundle grows only with what it imports.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
7
7
|
"cloudflare-workers",
|
|
8
8
|
"durable-objects",
|
|
9
9
|
"agents-sdk",
|
|
10
|
-
"arc-agi",
|
|
11
|
-
"vectorize",
|
|
12
10
|
"browser-rendering",
|
|
13
11
|
"containers",
|
|
14
12
|
"git",
|
|
@@ -32,26 +30,10 @@
|
|
|
32
30
|
"LICENSE"
|
|
33
31
|
],
|
|
34
32
|
"exports": {
|
|
35
|
-
"./arc-agi": {
|
|
36
|
-
"types": "./dist/arc-agi/index.d.ts",
|
|
37
|
-
"import": "./dist/arc-agi/index.js"
|
|
38
|
-
},
|
|
39
33
|
"./browser": {
|
|
40
34
|
"types": "./dist/browser/index.d.ts",
|
|
41
35
|
"import": "./dist/browser/index.js"
|
|
42
36
|
},
|
|
43
|
-
"./workspace": {
|
|
44
|
-
"types": "./dist/workspace/index.d.ts",
|
|
45
|
-
"import": "./dist/workspace/index.js"
|
|
46
|
-
},
|
|
47
|
-
"./recall": {
|
|
48
|
-
"types": "./dist/recall/index.d.ts",
|
|
49
|
-
"import": "./dist/recall/index.js"
|
|
50
|
-
},
|
|
51
|
-
"./triage": {
|
|
52
|
-
"types": "./dist/triage/index.d.ts",
|
|
53
|
-
"import": "./dist/triage/index.js"
|
|
54
|
-
},
|
|
55
37
|
"./repo": {
|
|
56
38
|
"types": "./dist/repo/index.d.ts",
|
|
57
39
|
"import": "./dist/repo/index.js"
|
|
@@ -64,6 +46,10 @@
|
|
|
64
46
|
"types": "./dist/claude-code/index.d.ts",
|
|
65
47
|
"import": "./dist/claude-code/index.js"
|
|
66
48
|
},
|
|
49
|
+
"./workspace": {
|
|
50
|
+
"types": "./dist/workspace/index.d.ts",
|
|
51
|
+
"import": "./dist/workspace/index.js"
|
|
52
|
+
},
|
|
67
53
|
"./computer": {
|
|
68
54
|
"types": "./dist/computer/index.d.ts",
|
|
69
55
|
"import": "./dist/computer/index.js"
|
|
@@ -80,29 +66,24 @@
|
|
|
80
66
|
"check": "npm run verify:peer-ranges && npm run verify:references && npm run types:check && prettier --check . && eslint . && tsc && npm run build && npm run verify:exports",
|
|
81
67
|
"test": "vitest run",
|
|
82
68
|
"test:watch": "vitest",
|
|
83
|
-
"test:record": "RECORD=1 vitest run recorded.spec.ts",
|
|
84
69
|
"verify:exports": "node scripts/verify-exports.mjs",
|
|
85
70
|
"verify:references": "node scripts/verify-references.mjs",
|
|
86
71
|
"verify:peer-ranges": "node scripts/verify-peer-ranges.mjs",
|
|
72
|
+
"probe:claude-code": "npm run build && node scripts/probe-claude-code.mjs",
|
|
87
73
|
"prepack": "npm run build && npm run verify:exports",
|
|
88
74
|
"prepublishOnly": "npm run check && npm test",
|
|
89
75
|
"prepare": "husky || true && npm run build"
|
|
90
76
|
},
|
|
91
77
|
"peerDependencies": {
|
|
92
|
-
"@cloudflare/computer": "^0.
|
|
93
|
-
"@cloudflare/
|
|
94
|
-
"@dynamicagents/core": ">=0.
|
|
78
|
+
"@cloudflare/computer": "^0.4.0",
|
|
79
|
+
"@cloudflare/think": ">=0.20.0 <0.21.0",
|
|
80
|
+
"@dynamicagents/core": ">=0.13.0 <0.14.0",
|
|
95
81
|
"@platformatic/vfs": "^0.4.0",
|
|
96
|
-
"agents": ">=0.
|
|
82
|
+
"agents": ">=0.26.0 <0.27.0",
|
|
97
83
|
"ai": "^7.0.88",
|
|
98
|
-
"drizzle-orm": ">=0.45.2",
|
|
99
|
-
"workers-ai-provider": "^4.0.0",
|
|
100
84
|
"zod": "^4.4.3"
|
|
101
85
|
},
|
|
102
86
|
"peerDependenciesMeta": {
|
|
103
|
-
"@cloudflare/shell": {
|
|
104
|
-
"optional": true
|
|
105
|
-
},
|
|
106
87
|
"@cloudflare/computer": {
|
|
107
88
|
"optional": true
|
|
108
89
|
},
|
|
@@ -111,15 +92,14 @@
|
|
|
111
92
|
}
|
|
112
93
|
},
|
|
113
94
|
"devDependencies": {
|
|
114
|
-
"@cloudflare/computer": "^0.
|
|
115
|
-
"@cloudflare/
|
|
116
|
-
"@platformatic/vfs": "^0.4.0",
|
|
95
|
+
"@cloudflare/computer": "^0.4.0",
|
|
96
|
+
"@cloudflare/think": "^0.20.0",
|
|
117
97
|
"@cloudflare/vitest-plugin": "^1.1.9",
|
|
118
|
-
"@dynamicagents/core": "^0.
|
|
98
|
+
"@dynamicagents/core": "^0.13.1",
|
|
99
|
+
"@platformatic/vfs": "^0.4.0",
|
|
119
100
|
"@types/node": "^26.5.1",
|
|
120
|
-
"agents": "^0.
|
|
101
|
+
"agents": "^0.26.0",
|
|
121
102
|
"ai": "^7.0.101",
|
|
122
|
-
"drizzle-orm": ">=0.45.2",
|
|
123
103
|
"eslint": "^10.10.0",
|
|
124
104
|
"husky": "^9.1.7",
|
|
125
105
|
"prettier": "^3.9.6",
|
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure grid-analysis helpers for ARC-AGI-3 frames. No I/O — every function is a
|
|
3
|
-
* deterministic transform of a 64×64 grid (color values 0–15), unit-tested in
|
|
4
|
-
* isolation. The tool family calls these to render compact observations for the
|
|
5
|
-
* model instead of dumping raw grids into context.
|
|
6
|
-
*
|
|
7
|
-
* Two rendering registers, deliberately kept apart:
|
|
8
|
-
*
|
|
9
|
-
* - **Prose** (diffs, shapes, histogram) names its colors: `blue->white` carries
|
|
10
|
-
* structure a bare `9->0` hides, and no tool input ever takes a color, so the
|
|
11
|
-
* index is never needed as an argument.
|
|
12
|
-
* - **Grids** ({@link renderGrid}, {@link renderRegion}) stay one character per
|
|
13
|
-
* cell and carry a {@link renderLegend} instead. One char per cell is the only
|
|
14
|
-
* reason a 64×64 board is legible at all; a named cell would be unreadable and
|
|
15
|
-
* cost ~50× the tokens.
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* The ARC-AGI-3 16-color palette, index → name.
|
|
19
|
-
*
|
|
20
|
-
* Source: `agents/templates/multimodal.py` in `arcprize/ARC-AGI-3-Agents` (ARC
|
|
21
|
-
* Prize's own agent template), which maps these indices to RGBA for multimodal
|
|
22
|
-
* play. Taken from there rather than assumed, because **ARC-AGI-3's palette is
|
|
23
|
-
* unrelated to ARC-AGI-1's**: here 0 is *white* and 1–5 are a greyscale ramp,
|
|
24
|
-
* where the familiar ARC-AGI-1 mapping would say 0=black, 1=blue, 2=red. Note
|
|
25
|
-
* that same repo carries a second, contradictory `COLOR_PALETTE` in
|
|
26
|
-
* `langgraph_thinking/vision.py` — that one is incomplete and does not match the
|
|
27
|
-
* engine; do not use it.
|
|
28
|
-
*
|
|
29
|
-
* The pairs matter to a player: 6/7 and 9/10 and 2/3 are related shades, which
|
|
30
|
-
* the names convey and the indices do not.
|
|
31
|
-
*/
|
|
32
|
-
export declare const COLOR_NAMES: readonly ["white", "off-white", "neutral-light", "neutral", "off-black", "black", "magenta", "magenta-light", "red", "blue", "blue-light", "yellow", "orange", "maroon", "green", "purple"];
|
|
33
|
-
/** Color 0 (white) — treated as background by {@link locateComponents}. */
|
|
34
|
-
export declare const BACKGROUND_COLOR = 0;
|
|
35
|
-
/**
|
|
36
|
-
* Name of a color index. An out-of-range value renders as `color <n>` rather
|
|
37
|
-
* than throwing: a malformed frame should degrade the wording, not fail the turn.
|
|
38
|
-
*/
|
|
39
|
-
export declare function colorName(color: number): string;
|
|
40
|
-
/** The current board: the LAST grid of a frame response's grid array. */
|
|
41
|
-
export declare function lastGrid(frame: number[][][]): number[][];
|
|
42
|
-
/**
|
|
43
|
-
* Bare hex rows, one char per cell, no labels — the round-trippable **storage**
|
|
44
|
-
* form, paired with {@link parseGrid}. Deliberately distinct from
|
|
45
|
-
* {@link renderGrid}, which adds a legend, rulers and row collapsing and so
|
|
46
|
-
* cannot be parsed back.
|
|
47
|
-
*/
|
|
48
|
-
export declare function serializeGrid(grid: number[][]): string;
|
|
49
|
-
/** Inverse of {@link serializeGrid}. */
|
|
50
|
-
export declare function parseGrid(hex: string): number[][];
|
|
51
|
-
export interface CellChange {
|
|
52
|
-
row: number;
|
|
53
|
-
col: number;
|
|
54
|
-
from: number;
|
|
55
|
-
to: number;
|
|
56
|
-
}
|
|
57
|
-
/** The rectangle enclosing a set of cells. */
|
|
58
|
-
export interface Box {
|
|
59
|
-
top: number;
|
|
60
|
-
left: number;
|
|
61
|
-
bottom: number;
|
|
62
|
-
right: number;
|
|
63
|
-
}
|
|
64
|
-
export interface GridDiff {
|
|
65
|
-
changed: number;
|
|
66
|
-
/** Up to `cap` changed cells (for a compact summary of a large change). */
|
|
67
|
-
cells: CellChange[];
|
|
68
|
-
/** Rectangle enclosing ALL changed cells (not just the capped ones). */
|
|
69
|
-
box: Box | null;
|
|
70
|
-
}
|
|
71
|
-
/** Cell-by-cell diff of two grids. `cap` bounds the returned cell list. */
|
|
72
|
-
export declare function diffGrids(a: number[][] | null, b: number[][], cap?: number): GridDiff;
|
|
73
|
-
/** `rows 3-5, cols 10-12` — or a single row/col rendered without the range. */
|
|
74
|
-
export declare function describeBox(box: Box): string;
|
|
75
|
-
/** `(3,10) blue->white` — one changed cell, colors named. */
|
|
76
|
-
export declare function describeCell(cell: CellChange): string;
|
|
77
|
-
/** Count of each color present, descending by count. */
|
|
78
|
-
export declare function colorHistogram(grid: number[][]): Array<{
|
|
79
|
-
color: number;
|
|
80
|
-
count: number;
|
|
81
|
-
}>;
|
|
82
|
-
/** One 4-connected same-color region, with where it sits and how big it is. */
|
|
83
|
-
export interface Component extends Box {
|
|
84
|
-
color: number;
|
|
85
|
-
size: number;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Every 4-connected same-color region, with its bounding box, largest first.
|
|
89
|
-
* Skips {@link BACKGROUND_COLOR}.
|
|
90
|
-
*
|
|
91
|
-
* The bounding boxes are the point: a rollup of counts alone tells the model
|
|
92
|
-
* *that* there are three shapes and never *where* they are, which leaves dumping
|
|
93
|
-
* the whole 64×64 grid as the only way to locate anything. The flood fill has to
|
|
94
|
-
* visit every cell regardless, so tracking min/max row/col is free.
|
|
95
|
-
*/
|
|
96
|
-
export declare function locateComponents(grid: number[][]): Component[];
|
|
97
|
-
/**
|
|
98
|
-
* How much of its bounding box a region actually occupies, 0–1.
|
|
99
|
-
*
|
|
100
|
-
* Every caller passes a {@link Component} from {@link locateComponents} or a
|
|
101
|
-
* {@link unionBox} of those, and a flood fill cannot produce `bottom < top`, so
|
|
102
|
-
* `area` is at least 1 and there is nothing to guard against dividing by.
|
|
103
|
-
*
|
|
104
|
-
* The result is deliberately **not** clamped into 0–1. An out-of-range value here
|
|
105
|
-
* could only mean a caller broke that invariant, and the way to learn that is a
|
|
106
|
-
* region classified absurdly, not a number quietly corrected into looking sane.
|
|
107
|
-
*/
|
|
108
|
-
export declare function fillRatio(box: Box, size: number): number;
|
|
109
|
-
/**
|
|
110
|
-
* A band of consecutive rows in which one color occupies exactly the same
|
|
111
|
-
* columns, and the column runs it occupies there.
|
|
112
|
-
*/
|
|
113
|
-
export interface SpanBand extends Pick<Box, "top" | "bottom"> {
|
|
114
|
-
/** Inclusive `[first, last]` column runs, left to right. */
|
|
115
|
-
cols: Array<[number, number]>;
|
|
116
|
-
/** Runs the cap dropped, so a truncated band never reads as a complete one. */
|
|
117
|
-
hidden: number;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Where one color sits, row band by row band — the view a bounding box cannot
|
|
121
|
-
* give for a maze, a frame, or any other structure that is mostly holes.
|
|
122
|
-
*
|
|
123
|
-
* Keyed by **color rather than component** on purpose. A wall that a doorway
|
|
124
|
-
* splits into three components is one thing to a player, and three boxes describe
|
|
125
|
-
* it worse than one span list does; the flood fill's notion of connectedness is an
|
|
126
|
-
* implementation detail here, not something the model should have to reassemble.
|
|
127
|
-
*
|
|
128
|
-
* Rows whose runs are identical collapse into one band, the same trick
|
|
129
|
-
* {@link renderGrid} uses — and for the same reason, since ARC boards are banded.
|
|
130
|
-
* On a real 64×64 maze it turns 64 rows into ~20 bands.
|
|
131
|
-
*/
|
|
132
|
-
export declare function colorSpans(grid: number[][], color: number): SpanBand[];
|
|
133
|
-
/**
|
|
134
|
-
* Runs named per band, one line each. Both caps exist to bound the render on a
|
|
135
|
-
* board this encoding suits badly — a checkerboard is 32 runs in every one of 64
|
|
136
|
-
* rows — and both announce themselves, so a clipped view is never mistaken for
|
|
137
|
-
* the whole of one.
|
|
138
|
-
*/
|
|
139
|
-
export declare function renderSpans(bands: SpanBand[]): string;
|
|
140
|
-
/**
|
|
141
|
-
* Named regions with their positions, largest first — the locational view.
|
|
142
|
-
*
|
|
143
|
-
* A bounding box describes a region only when the region roughly fills it. That
|
|
144
|
-
* holds for the movable pieces and fails for exactly the two things a route
|
|
145
|
-
* depends on: on a real `ls20` board the maze boxes as `off-black: rows 0-63,
|
|
146
|
-
* cols 0-63 (2129 cells)` and the floor as `neutral: rows 5-54, cols 9-58 (1354
|
|
147
|
-
* cells)`, both a shade over half-filled. The first says nothing; the second is
|
|
148
|
-
* worse, asserting a 50×50 open arena of which 46% is wall — and a play reading
|
|
149
|
-
* its route off those boxes walks into walls, then spends a dozen turns
|
|
150
|
-
* rebuilding the maze through 11×11 `region` peepholes.
|
|
151
|
-
*
|
|
152
|
-
* So a region that sprawls is rendered as {@link colorSpans} instead — every row
|
|
153
|
-
* band and the columns it occupies, which is the same fact at a resolution that
|
|
154
|
-
* can be acted on. Sprawl is judged per color and the whole color is then spanned
|
|
155
|
-
* at once, so a wall and the doorway splitting it read as one terrain layer rather
|
|
156
|
-
* than as two boxes that overlap everything.
|
|
157
|
-
*
|
|
158
|
-
* `cap` bounds the boxed list; anything beyond it is reported as a count so the
|
|
159
|
-
* model knows the view is truncated rather than complete.
|
|
160
|
-
*/
|
|
161
|
-
export declare function renderShapes(grid: number[][], cap?: number): string;
|
|
162
|
-
/**
|
|
163
|
-
* What became of one shape between two frames.
|
|
164
|
-
*
|
|
165
|
-
* The four cases are kept apart because only **one** of them answers the question
|
|
166
|
-
* an action asks — did anything move? Folding a counter ticking down into the
|
|
167
|
-
* same bucket as a step taken is exactly the mistake {@link diffGrids} cannot
|
|
168
|
-
* help making: in `ls20` every action shrinks a fuel bar by four cells, so a move
|
|
169
|
-
* into a wall reports "4 cells changed" and reads, to a model told that `0 cells
|
|
170
|
-
* changed` means blocked, as a move that worked. It spent eleven actions on that
|
|
171
|
-
* misreading. A wall is `moved: []` here, whatever else on the board ticked.
|
|
172
|
-
*/
|
|
173
|
-
export type ShapeChange = {
|
|
174
|
-
kind: "moved";
|
|
175
|
-
/** Where it was, with its color and cell count. */
|
|
176
|
-
from: Component;
|
|
177
|
-
/** Where it is now — same color and same cell count, by construction. */
|
|
178
|
-
to: Box;
|
|
179
|
-
dRow: number;
|
|
180
|
-
dCol: number;
|
|
181
|
-
}
|
|
182
|
-
/** Same color, still overlapping, different cell count — a bar, a trail, a fill. */
|
|
183
|
-
| {
|
|
184
|
-
kind: "resized";
|
|
185
|
-
from: Component;
|
|
186
|
-
to: Component;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Same footprint and same cell count, a different color — a repaint in place,
|
|
190
|
-
* which is what a click game does instead of moving anything.
|
|
191
|
-
*/
|
|
192
|
-
| {
|
|
193
|
-
kind: "recolored";
|
|
194
|
-
from: Component;
|
|
195
|
-
to: Component;
|
|
196
|
-
} | {
|
|
197
|
-
kind: "appeared";
|
|
198
|
-
shape: Component;
|
|
199
|
-
} | {
|
|
200
|
-
kind: "gone";
|
|
201
|
-
shape: Component;
|
|
202
|
-
};
|
|
203
|
-
export type MovedShape = Extract<ShapeChange, {
|
|
204
|
-
kind: "moved";
|
|
205
|
-
}>;
|
|
206
|
-
/**
|
|
207
|
-
* Two frames' shapes, matched. Split rather than one list because both consumers
|
|
208
|
-
* want the split: the renderer leads with movement, and a caller summing a batch
|
|
209
|
-
* accumulates only the moves.
|
|
210
|
-
*/
|
|
211
|
-
export interface ShapeDelta {
|
|
212
|
-
/** Every shape that travelled, largest first. */
|
|
213
|
-
moved: MovedShape[];
|
|
214
|
-
/** Resized, appeared and disappeared shapes, largest first. */
|
|
215
|
-
other: ShapeChange[];
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Above this many changed shapes, a frame is a repaint (a level change, a
|
|
219
|
-
* transform) rather than a board where things moved, and naming twenty shapes
|
|
220
|
-
* that all "appeared" says less than the cell diff does. {@link renderShapeDelta}
|
|
221
|
-
* declines, and its caller falls back.
|
|
222
|
-
*/
|
|
223
|
-
export declare const MAX_SHAPE_CHANGES = 10;
|
|
224
|
-
/**
|
|
225
|
-
* Match the shapes of two frames: what moved, what changed size, what came and
|
|
226
|
-
* went. Null when there is no earlier frame to compare against.
|
|
227
|
-
*
|
|
228
|
-
* Three passes, and the order is the whole design. Color **and** cell count
|
|
229
|
-
* first, because a rigid object that travelled keeps both — that pass is what
|
|
230
|
-
* finds a move, and its pairs are never reconsidered. Color alone second, over
|
|
231
|
-
* what is left, which is what a bar losing cells or a trail growing looks like.
|
|
232
|
-
* **Footprint** alone last, over what neither pass claimed, which is a shape that
|
|
233
|
-
* changed color without moving — see {@link matchRepaints}.
|
|
234
|
-
*/
|
|
235
|
-
export declare function diffShapes(before: number[][] | null, after: number[][]): ShapeDelta | null;
|
|
236
|
-
/** {@link diffShapes} over already-located components. Exported for tests. */
|
|
237
|
-
export declare function matchShapes(before: Component[], after: Component[]): ShapeDelta;
|
|
238
|
-
/** `down 5, left 10` — a displacement in board directions, zero terms dropped. */
|
|
239
|
-
export declare function describeShift(dRow: number, dCol: number): string;
|
|
240
|
-
/**
|
|
241
|
-
* One action's effect as movement: `nothing moved` when the board's objects
|
|
242
|
-
* stayed put, whatever a counter did alongside them.
|
|
243
|
-
*
|
|
244
|
-
* That phrase is spent carefully, because the soul teaches it as the signal for
|
|
245
|
-
* *blocked or refused*: it leads a step only when everything else the delta holds
|
|
246
|
-
* is a {@link ShapeChange} of kind `resized`, which is a counter or a bar doing
|
|
247
|
-
* its own bookkeeping. A step that repainted a block, or made one appear, changed
|
|
248
|
-
* the board — no object travelled, and reporting that as `nothing moved` tells a
|
|
249
|
-
* click game that twenty clicks which each toggled a 36-cell block were refused.
|
|
250
|
-
*
|
|
251
|
-
* Null means *this view has nothing to say* — either no shape can be paired
|
|
252
|
-
* across the frames, or so many changed that they are a repaint
|
|
253
|
-
* ({@link MAX_SHAPE_CHANGES}). Both leave the cell diff as the better witness, so
|
|
254
|
-
* the caller renders that instead rather than printing a confident "nothing
|
|
255
|
-
* moved" over a board that changed completely.
|
|
256
|
-
*/
|
|
257
|
-
export declare function renderShapeDelta(delta: ShapeDelta, cap?: number): string | null;
|
|
258
|
-
/** Where one shape ended up over a whole batch, and how many steps took it there. */
|
|
259
|
-
export interface ShapeTravel {
|
|
260
|
-
shape: Component;
|
|
261
|
-
dRow: number;
|
|
262
|
-
dCol: number;
|
|
263
|
-
/** Steps in which this shape moved at all. */
|
|
264
|
-
moves: number;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Fold one step's moves into a batch's running totals.
|
|
268
|
-
*
|
|
269
|
-
* Identity is *position*, not appearance. Boards carrying two identical shapes
|
|
270
|
-
* are the ordinary case, not the contrived one — a pair of blocks, a player and
|
|
271
|
-
* its twin — and summing them under one color-and-size key reports two shapes
|
|
272
|
-
* that passed each other as one shape that never moved, which is the single
|
|
273
|
-
* worst thing this line could say.
|
|
274
|
-
*
|
|
275
|
-
* Each entry is re-keyed to where its shape landed, which is exactly where the
|
|
276
|
-
* next step's diff will find it: the frames chain, step N's board being step
|
|
277
|
-
* N+1's starting board, so a position is a stable handle for as long as the
|
|
278
|
-
* shape keeps its color and size. Sources are cleared before any destination is
|
|
279
|
-
* written, so a shape sliding into the cell another just vacated inherits its
|
|
280
|
-
* own history rather than the vacater's.
|
|
281
|
-
*/
|
|
282
|
-
export declare function trackTravel(travels: Map<string, ShapeTravel>, moved: MovedShape[]): void;
|
|
283
|
-
/**
|
|
284
|
-
* A shape's net travel over a batch, counted in **moves** rather than cells.
|
|
285
|
-
*
|
|
286
|
-
* Cells are the misleading unit for a sequence: two presses that each slide a
|
|
287
|
-
* selector five cells are not "ten cells down", they are two moves of five, and a
|
|
288
|
-
* model reading the former will place itself ten cells from where it is. So the
|
|
289
|
-
* per-move stride is stated whenever the total divides by the moves that produced
|
|
290
|
-
* it — observed from the steps, never assumed.
|
|
291
|
-
*/
|
|
292
|
-
export declare function renderTravel(travel: ShapeTravel): string;
|
|
293
|
-
/** `0=white 9=blue b=yellow` — maps grid characters to names, present colors only. */
|
|
294
|
-
export declare function renderLegend(grid: number[][]): string;
|
|
295
|
-
/**
|
|
296
|
-
* The full board: a legend, a column ruler, then one labeled line per row —
|
|
297
|
-
* with **runs of identical rows collapsed** into a single `12-31 |` band.
|
|
298
|
-
*
|
|
299
|
-
* Labels exist because a model cannot reliably count to column 37 across 64
|
|
300
|
-
* undelimited characters; miscounting there costs a wrong click and two more
|
|
301
|
-
* turns. Collapsing exploits how banded ARC boards are without run-length
|
|
302
|
-
* encoding *within* a row, which would destroy the 2-D structure that this view
|
|
303
|
-
* exists to convey.
|
|
304
|
-
*/
|
|
305
|
-
export declare function renderGrid(grid: number[][]): string;
|
|
306
|
-
/**
|
|
307
|
-
* A localized view: a `radius`-cell square around (centerRow, centerCol), with
|
|
308
|
-
* **absolute** row and column labels. The labels are what make the view usable —
|
|
309
|
-
* an unlabeled block cannot be mapped back to a coordinate to click.
|
|
310
|
-
*
|
|
311
|
-
* The window is **clipped** on every side, never padded, which is what makes the
|
|
312
|
-
* header's `cols` anchor true: character `i` of a body line is column
|
|
313
|
-
* `firstCol + i`. Padding off-grid columns with spaces instead would shift that
|
|
314
|
-
* mapping by up to `radius` near the left edge.
|
|
315
|
-
*
|
|
316
|
-
* **The window is ruled, not just headed.** A model asked to place a cell in an
|
|
317
|
-
* 11-wide window counts the characters by hand and gets them wrong, then reasons
|
|
318
|
-
* on the columns it miscounted — so narrow is exactly where the ruler is needed.
|
|
319
|
-
* It steps at {@link REGION_RULER_STEP} rather than {@link renderGrid}'s tens,
|
|
320
|
-
* which a window this size can miss entirely.
|
|
321
|
-
*/
|
|
322
|
-
export declare function renderRegion(grid: number[][], centerRow: number, centerCol: number, radius?: number): string;
|