@desplega.ai/agent-swarm 2.7.5 → 2.7.6
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/dist/{acp-adapter-g3ads55s.js → acp-adapter-bp91d37f.js} +4 -4
- package/dist/{actions-zwfykqqk.js → actions-yj0eeaqh.js} +18 -17
- package/dist/{amp-adapter-z3s0ssdt.js → amp-adapter-4pg9h34q.js} +1 -1
- package/dist/{app-vmp4fgep.js → app-909e97cr.js} +3 -3
- package/dist/{assistant-vwde653f.js → assistant-qdyb5fyy.js} +24 -22
- package/dist/{boot-reembed-375t7tbk.js → boot-reembed-fk0s9z18.js} +1 -1
- package/dist/{boot-reembed-gq9rcpnj.js → boot-reembed-gs1rzrnh.js} +1 -1
- package/dist/{boot-scrub-sweep-nd938kyf.js → boot-scrub-sweep-4qfd4kfx.js} +2 -2
- package/dist/{boot-seeds-aykx51v3.js → boot-seeds-yr00k13d.js} +4 -4
- package/dist/{boxd-k1j26g3h.js → boxd-vdmfssd9.js} +4 -4
- package/dist/{claude-adapter-8j4hm099.js → claude-adapter-qta1f1xn.js} +3 -3
- package/dist/{claude-managed-setup-0wyynpn1.js → claude-managed-setup-sc6j4dm0.js} +1 -1
- package/dist/{claude-sdk-session-q6wj5hmy.js → claude-sdk-session-zgrz6yvc.js} +9169 -9070
- package/dist/{cli-gjr2y2xk.js → cli-0agcv1v5.js} +4 -1
- package/dist/{cli-vqypxzh4.js → cli-0at8w34w.js} +7 -7
- package/dist/{cli-7a42nfy0.js → cli-0qatpy8q.js} +3 -3
- package/dist/{cli-p599f1qm.js → cli-0yv5z2pg.js} +1 -1
- package/dist/{cli-0gey5fzy.js → cli-386tyxxg.js} +2 -2
- package/dist/{cli-5pag6rmn.js → cli-3ypk9vk1.js} +1 -1
- package/dist/{cli-qxnf8z2z.js → cli-436532ck.js} +2 -2
- package/dist/{cli-z8eh3ex8.js → cli-4necwtsv.js} +4 -4
- package/dist/{cli-zh3fp8v2.js → cli-54t00gt8.js} +1 -1
- package/dist/{cli-hf6zt5m6.js → cli-69szn7w7.js} +17 -1
- package/dist/{cli-nn4d8dne.js → cli-89knwags.js} +2 -2
- package/dist/{cli-spknvxbq.js → cli-8bc1w0tw.js} +10 -10
- package/dist/{cli-rqkxrmgw.js → cli-8snvgs5r.js} +38 -13
- package/dist/{cli-rhw40jgb.js → cli-bjb3z51z.js} +2 -2
- package/dist/{cli-xtjhfmpc.js → cli-c60vetmm.js} +1 -1
- package/dist/{cli-0731hvbw.js → cli-decfb6v8.js} +2 -2
- package/dist/{cli-bhjt02p8.js → cli-drr5v6av.js} +1 -1
- package/dist/{cli-fqzx7gwa.js → cli-dxae2yg7.js} +2 -2
- package/dist/{cli-tqgg40ek.js → cli-e3r2neck.js} +8 -7
- package/dist/{cli-zppwg9p9.js → cli-ekwks2vs.js} +1 -1
- package/dist/{cli-nzxr556s.js → cli-es6va8jk.js} +26 -26
- package/dist/{cli-a47xy8eq.js → cli-faxe6thg.js} +1 -1
- package/dist/cli-gdhpcbhf.js +55 -0
- package/dist/{cli-82jg7fp9.js → cli-he5nxaa8.js} +1 -1
- package/dist/{cli-8veytvbh.js → cli-he9wchme.js} +1 -1
- package/dist/{cli-pywf3eh5.js → cli-hgaazk69.js} +1 -1
- package/dist/{cli-0bxqnvq9.js → cli-hr2e2fft.js} +28 -6
- package/dist/{cli-1ayk1eas.js → cli-k2gzwsj2.js} +135 -26
- package/dist/{cli-xbkdm710.js → cli-kqdg1bsb.js} +3 -3
- package/dist/cli-m2z8jagn.js +12078 -0
- package/dist/{cli-g61qxmge.js → cli-m48g6p95.js} +3 -3
- package/dist/{cli-7wspm5gm.js → cli-nhrvpaj7.js} +20 -4
- package/dist/{cli-afrrppsw.js → cli-nwj0ee2w.js} +2 -2
- package/dist/{cli-3h4nhjn8.js → cli-p5gp8pcx.js} +9 -7
- package/dist/{cli-rm6hqj3z.js → cli-pd7vagab.js} +33 -139
- package/dist/{cli-mjzynrse.js → cli-q0k1w5zd.js} +1 -1
- package/dist/{cli-8hs41zy2.js → cli-rmmmrjkd.js} +1 -1
- package/dist/{cli-kg8hchyg.js → cli-sa02jsqt.js} +1 -1
- package/dist/{cli-1338796d.js → cli-shpbx5ee.js} +142 -98
- package/dist/{cli-82ae98pz.js → cli-svj5090z.js} +2 -2
- package/dist/{cli-bnz7a7qf.js → cli-vvpx3gsx.js} +1 -1
- package/dist/{cli-mmwm7zbf.js → cli-w6dt9ged.js} +1 -1
- package/dist/{cli-wvaawacd.js → cli-waqbxg08.js} +5230 -66
- package/dist/{cli-j3jvnpe8.js → cli-wp9sp1qb.js} +1 -1
- package/dist/{cli-nmbmy64z.js → cli-xbbndvjy.js} +3 -3
- package/dist/{cli-vbyfwh92.js → cli-xds5f77d.js} +2 -2
- package/dist/{cli-7wcyk2s5.js → cli-xnqgpshy.js} +1 -1
- package/dist/{cli-rpm2sgv0.js → cli-xnrwazav.js} +19 -2
- package/dist/{cli-gf5hbmdr.js → cli-yjdgea32.js} +3 -3
- package/dist/{cli-mry0qzym.js → cli-yn4kxs06.js} +123 -10
- package/dist/{cli-hn9hxmz9.js → cli-yx4kfngt.js} +1 -1
- package/dist/{cli-y24sc29k.js → cli-yy3rhsdw.js} +30 -8
- package/dist/{cli-6s7vdcta.js → cli-zbbwez0r.js} +4 -4
- package/dist/{cli-z6jkx23q.js → cli-zm72anhg.js} +9 -9
- package/dist/cli.js +22 -21
- package/dist/{codex-adapter-q6k3gnyg.js → codex-adapter-ayd1fb6h.js} +2 -2
- package/dist/{codex-session-runner-3mwmk3d9.js → codex-session-runner-jesa32xc.js} +2 -2
- package/dist/{commands-evrenjn9.js → commands-hanewgf2.js} +9 -3
- package/dist/{controller-xjp8vswh.js → controller-dt1n3c1q.js} +8 -3
- package/dist/{controllers-connect-pp5jnxvc.js → controllers-connect-xx8x64n5.js} +20 -19
- package/dist/{cursor-adapter-yf47w4t0.js → cursor-adapter-9s4dwwdw.js} +1 -1
- package/dist/{db-zxpw6aht.js → db-3vttcbv4.js} +3 -3
- package/dist/{db-rgfsh91f.js → db-9dv0g1ab.js} +11 -3
- package/dist/{devtools-82fzqra8.js → devtools-qxfgbsqz.js} +1 -1
- package/dist/{dispatcher-smasgws7.js → dispatcher-tx9hd1sv.js} +17 -16
- package/dist/{docker-rrjhaqt9.js → docker-c1a3gqmf.js} +89 -22
- package/dist/{dsh-adapter-ftyy8dnp.js → dsh-adapter-007y4ejs.js} +1 -1
- package/dist/{e2b-qcaj675y.js → e2b-a19d28rz.js} +2 -2
- package/dist/{e2b-w1p0bnpm.js → e2b-we6hs6q5.js} +4 -4
- package/dist/{easter-egg-3d-yyts7p16.js → easter-egg-3d-rgbrqb8s.js} +1 -1
- package/dist/{embedding-space-1z0mbg95.js → embedding-space-ny1e2940.js} +6 -6
- package/dist/{embeddings-ygeg7tm7.js → embeddings-2t386t13.js} +1 -1
- package/dist/{execute-14qhqp4d.js → execute-pksh0ceh.js} +1 -1
- package/dist/{external-channel-ttgrs3sx.js → external-channel-phgmhmd7.js} +2 -2
- package/dist/{fx-adapter-gt6pncj2.js → fx-adapter-fy8rr921.js} +5 -5
- package/dist/{google-generative-ai-yvmdxyxa.js → google-generative-ai-8y3m3k4b.js} +1 -1
- package/dist/{google-vertex-jrtdh9gs.js → google-vertex-w3v98n7b.js} +1 -1
- package/dist/{grok-adapter-sm4m5k4g.js → grok-adapter-q0abvpaj.js} +5 -5
- package/dist/handlers-by3sfxyx.js +32 -0
- package/dist/{heartbeat-qahz4p62.js → heartbeat-kadyek8p.js} +20 -19
- package/dist/{hook-kj3d398m.js → hook-5zs3msf6.js} +2 -2
- package/dist/{hook-4fd5wq5w.js → hook-9k551xnj.js} +2 -2
- package/dist/{http-1ted0j1k.js → http-mhz9vw1f.js} +213 -80
- package/dist/index-4f2pvxae.js +37 -0
- package/dist/index-98gz7tmp.js +30 -0
- package/dist/{index-5rk6rfzr.js → index-fvzke5kx.js} +1 -1
- package/dist/index-k08z2cak.js +33 -0
- package/dist/{index-yqhz88yy.js → index-pxn30mse.js} +8 -8
- package/dist/{index-6rq3r5zb.js → index-q361cg2f.js} +1 -1
- package/dist/{index-7v51awbn.js → index-rvr00sg7.js} +20 -13
- package/dist/{index-q4b917zs.js → index-vdygbq10.js} +1 -1
- package/dist/{keepalive-6cf311t5.js → keepalive-w56f32cg.js} +3 -3
- package/dist/{lead-fjy418cw.js → lead-enq35nqp.js} +31 -30
- package/dist/{maintenance-a4bm1bmt.js → maintenance-7mdgxcea.js} +1 -1
- package/dist/{oauth-refresh-sweep-3h0dfw1k.js → oauth-refresh-sweep-29txy9vk.js} +2 -2
- package/dist/{onboard-myn5hraa.js → onboard-kpsrkarj.js} +4 -4
- package/dist/{opencode-adapter-p2nkb5am.js → opencode-adapter-j25vm3rr.js} +3 -3
- package/dist/{otel-impl-a1a0ef6b.js → otel-impl-6kkct7a8.js} +1 -1
- package/dist/{pi-mono-adapter-rzmpb72a.js → pi-mono-adapter-exhkzhn2.js} +4 -4
- package/dist/{pricing-refresh-83drrnxj.js → pricing-refresh-n2x7jh6k.js} +3 -3
- package/dist/{rbac-roles-s8y6ecb5.js → rbac-roles-81ypx6es.js} +1 -1
- package/dist/{rbac-roles-0fb6e7pj.js → rbac-roles-b5htkjby.js} +2 -2
- package/dist/{render-v2-twmbgrz4.js → render-v2-qn6jmpk4.js} +3 -3
- package/dist/{resume-zfqc36xj.js → resume-wd30wx23.js} +6 -6
- package/dist/{runtime-qwggdpqr.js → runtime-4hsg7h60.js} +1 -1
- package/dist/{session-access-sc9pn9da.js → session-access-5qvfevhk.js} +4 -4
- package/dist/{session-source-backfill-qh07xr8g.js → session-source-backfill-n1czavbr.js} +2 -2
- package/dist/{setup-4fr0m7a1.js → setup-dnb56qy5.js} +3 -3
- package/dist/{virtual-modules-fh4ha15b.js → virtual-modules-76xxv9fs.js} +2 -2
- package/dist/{work-objects-0wr8zxct.js → work-objects-4n21tfkm.js} +20 -19
- package/dist/{worker-follow-up-ktyyazyp.js → worker-follow-up-77hvzxww.js} +17 -16
- package/dist/{worker-0c5tyzqe.js → worker-gg1576j3.js} +31 -30
- package/openapi.json +93 -1
- package/package.json +8 -7
- package/src/be/db/script-runs.ts +23 -0
- package/src/be/db/tasks/read.ts +122 -3
- package/src/be/db-client.ts +8 -5
- package/src/be/db.ts +15 -4
- package/src/be/memory/providers/sqlite-store.ts +49 -12
- package/src/be/migrations/260_runtime_pool_cache.sql +20 -0
- package/src/be/migrations/262_session_visibility_indexes.sql +18 -0
- package/src/be/migrations/263_task_list_filter_index.sql +11 -0
- package/src/be/migrations/264_slack_thread_cover_index.sql +9 -0
- package/src/be/migrations/266_script_runs_source_task.sql +11 -0
- package/src/be/runtime-pools/cache-cleanup.ts +109 -0
- package/src/be/runtime-pools/db.ts +65 -6
- package/src/be/runtime-pools/remote-controller.ts +5 -0
- package/src/be/runtime-pools/supervisor.ts +33 -2
- package/src/be/scripts/typecheck.ts +22 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +5 -1
- package/src/commands/controller.ts +4 -0
- package/src/commands/entrypoint-api-readiness.ts +74 -0
- package/src/http/index.ts +1 -1
- package/src/http/list-total-cache.ts +14 -7
- package/src/http/memory.ts +38 -9
- package/src/http/script-runs.ts +174 -5
- package/src/http/status.ts +10 -2
- package/src/http/tasks.ts +4 -2
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/fx-adapter.ts +1 -1
- package/src/runtime-providers/controller-protocol.ts +14 -1
- package/src/runtime-providers/controller.ts +5 -0
- package/src/runtime-providers/docker.ts +108 -23
- package/src/runtime-providers/types.ts +16 -0
- package/src/script-workflows/workflow-ctx.ts +8 -0
- package/src/scripts-runtime/types/stdlib.d.ts +22 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +22 -0
- package/src/server-user.ts +1 -0
- package/src/slack/commands.ts +5 -1
- package/src/slack/handlers.ts +37 -2
- package/src/slack/left-threads.ts +27 -4
- package/src/tasks/follow-up-redelegation-guard.ts +155 -0
- package/src/tests/claude-artifacts-read-script.test.ts +209 -0
- package/src/tests/db-client.test.ts +21 -0
- package/src/tests/db-task-read-contract.test.ts +8 -2
- package/src/tests/db-task-write-contract.test.ts +5 -1
- package/src/tests/entrypoint-api-readiness.test.ts +416 -210
- package/src/tests/explicit-model-validation.test.ts +14 -8
- package/src/tests/follow-up-redelivery-guard.test.ts +432 -202
- package/src/tests/list-total-cache.test.ts +27 -2
- package/src/tests/memory-fts-populate.test.ts +11 -9
- package/src/tests/memory-retrieval-purge.test.ts +80 -0
- package/src/tests/migration-260-runtime-pool-cache.test.ts +118 -0
- package/src/tests/query-audit-plans.test.ts +27 -0
- package/src/tests/runtime-cache-cleanup.test.ts +367 -0
- package/src/tests/runtime-e2b-pools.test.ts +41 -0
- package/src/tests/runtime-pools-db.test.ts +98 -0
- package/src/tests/runtime-pools-http.test.ts +29 -0
- package/src/tests/runtime-providers-docker.test.ts +253 -0
- package/src/tests/runtime-remote-controller.test.ts +66 -2
- package/src/tests/runtime-supervisor.test.ts +66 -2
- package/src/tests/script-connections.test.ts +11 -0
- package/src/tests/script-runs-http.test.ts +684 -2
- package/src/tests/seed-scripts.test.ts +26 -0
- package/src/tests/slack-leave-thread.test.ts +145 -5
- package/src/tests/slack-render-v2-query-plans.test.ts +24 -2
- package/src/tests/status.test.ts +11 -0
- package/src/tests/tasks-readable-row.test.ts +155 -0
- package/src/tools/send-task.ts +35 -47
- package/src/tools/slack-leave-thread.ts +1 -1
- package/src/tools/task-dedup.ts +45 -21
- package/src/types.ts +38 -0
- package/templates/skills/composio-google-docs/content.md +10 -0
- package/templates/skills/script-workflows/content.md +19 -1
- package/templates/skills/swarm-docs/content.md +1 -0
- package/templates/skills/swarm-scripts/SKILL.md +2 -0
- package/templates/skills/swarm-scripts/content.md +2 -0
- package/dist/cli-dznrgaep.js +0 -30
- package/dist/cli-w3hcrxht.js +0 -6985
- package/dist/handlers-vwmba1m2.js +0 -31
- package/dist/index-5r71rf98.js +0 -32
- package/dist/index-anmwxs87.js +0 -29
- package/dist/index-spp0ra5c.js +0 -36
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* examples/claude-artifacts-read/claude-artifacts-read.sh must never write
|
|
3
|
+
* outside <outdir> and never replace a file with content that failed its
|
|
4
|
+
* sha256 check. A mock `claude` (CLAUDE_BIN) replays canned stream-json, so
|
|
5
|
+
* no network or auth is involved.
|
|
6
|
+
*/
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import {
|
|
10
|
+
lstat,
|
|
11
|
+
mkdir,
|
|
12
|
+
mkdtemp,
|
|
13
|
+
readdir,
|
|
14
|
+
readFile,
|
|
15
|
+
readlink,
|
|
16
|
+
rm,
|
|
17
|
+
symlink,
|
|
18
|
+
writeFile,
|
|
19
|
+
} from "node:fs/promises";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { join, resolve } from "node:path";
|
|
22
|
+
import { CHILD_PROCESS_TEST_BUDGET_MS, runChild } from "./test-proc";
|
|
23
|
+
|
|
24
|
+
const SCRIPT = resolve(
|
|
25
|
+
import.meta.dir,
|
|
26
|
+
"../../examples/claude-artifacts-read/claude-artifacts-read.sh",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const MOCK_CLAUDE = `#!/usr/bin/env bash
|
|
30
|
+
case "$2" in
|
|
31
|
+
*list_files*) cat "$MOCK_DIR/list.jsonl" ;;
|
|
32
|
+
*) cat "$MOCK_DIR/read.jsonl" ;;
|
|
33
|
+
esac
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const sha256 = (s: string) => createHash("sha256").update(s).digest("hex");
|
|
37
|
+
|
|
38
|
+
function toolResult(blocks: string[]): string {
|
|
39
|
+
return JSON.stringify({
|
|
40
|
+
type: "user",
|
|
41
|
+
message: {
|
|
42
|
+
content: [{ type: "tool_result", content: blocks.map((text) => ({ type: "text", text })) }],
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let root: string;
|
|
48
|
+
let out: string;
|
|
49
|
+
let outside: string;
|
|
50
|
+
let mockDir: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Stage a listing whose sha256 for each path is `listed` and a read that
|
|
54
|
+
* returns `served`, then run the script into `out`.
|
|
55
|
+
*/
|
|
56
|
+
async function run(files: { path: string; listed: string; served: string }[]) {
|
|
57
|
+
const init = JSON.stringify({
|
|
58
|
+
type: "system",
|
|
59
|
+
subtype: "init",
|
|
60
|
+
claude_code_version: "2.1.314",
|
|
61
|
+
tools: ["mcp__claude-artifacts__list_files", "mcp__claude-artifacts__read_file"],
|
|
62
|
+
});
|
|
63
|
+
const manifest = {
|
|
64
|
+
slug: "art_mock",
|
|
65
|
+
files: files.map((f) => ({
|
|
66
|
+
path: f.path,
|
|
67
|
+
content_type: "text/html",
|
|
68
|
+
size: f.listed.length,
|
|
69
|
+
sha256: sha256(f.listed),
|
|
70
|
+
})),
|
|
71
|
+
};
|
|
72
|
+
await writeFile(
|
|
73
|
+
join(mockDir, "list.jsonl"),
|
|
74
|
+
`${init}\n${toolResult([JSON.stringify(manifest)])}\n`,
|
|
75
|
+
);
|
|
76
|
+
const reads = files.map((f) =>
|
|
77
|
+
toolResult([
|
|
78
|
+
JSON.stringify({ path: f.path }),
|
|
79
|
+
`<untrusted-document-abc123>${f.served}</untrusted-document-abc123>`,
|
|
80
|
+
]),
|
|
81
|
+
);
|
|
82
|
+
await writeFile(join(mockDir, "read.jsonl"), `${init}\n${reads.join("\n")}\n`);
|
|
83
|
+
return runChild(["bash", SCRIPT, "https://claude.ai/artifact/mock", out], {
|
|
84
|
+
env: {
|
|
85
|
+
PATH: process.env.PATH,
|
|
86
|
+
HOME: root,
|
|
87
|
+
CLAUDE_BIN: join(mockDir, "claude"),
|
|
88
|
+
MOCK_DIR: mockDir,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
beforeEach(async () => {
|
|
94
|
+
root = await mkdtemp(join(tmpdir(), "claude-artifacts-read-"));
|
|
95
|
+
out = join(root, "out");
|
|
96
|
+
outside = join(root, "outside");
|
|
97
|
+
mockDir = join(root, "mock");
|
|
98
|
+
await mkdir(out);
|
|
99
|
+
await mkdir(outside);
|
|
100
|
+
await mkdir(mockDir);
|
|
101
|
+
await writeFile(join(mockDir, "claude"), MOCK_CLAUDE, { mode: 0o755 });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
afterEach(async () => {
|
|
105
|
+
await rm(root, { recursive: true, force: true });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe("claude-artifacts-read.sh", () => {
|
|
109
|
+
test(
|
|
110
|
+
"a sha256 mismatch leaves an existing file untouched",
|
|
111
|
+
async () => {
|
|
112
|
+
await mkdir(join(out, "project"));
|
|
113
|
+
await writeFile(join(out, "project/a.html"), "previous good copy");
|
|
114
|
+
|
|
115
|
+
const r = await run([
|
|
116
|
+
{ path: "project/a.html", listed: "real content", served: "truncated" },
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
expect(r.exitCode).toBe(1);
|
|
120
|
+
expect(r.stderr).toContain("sha256 mismatch: project/a.html");
|
|
121
|
+
expect(await readFile(join(out, "project/a.html"), "utf8")).toBe("previous good copy");
|
|
122
|
+
expect(await readdir(join(out, "project"))).toEqual(["a.html"]);
|
|
123
|
+
},
|
|
124
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
test(
|
|
128
|
+
"a sha256 mismatch never writes through a destination symlink",
|
|
129
|
+
async () => {
|
|
130
|
+
await writeFile(join(outside, "target.txt"), "external");
|
|
131
|
+
await symlink(join(outside, "target.txt"), join(out, "a.html"));
|
|
132
|
+
|
|
133
|
+
const r = await run([{ path: "a.html", listed: "real content", served: "truncated" }]);
|
|
134
|
+
|
|
135
|
+
expect(r.exitCode).toBe(1);
|
|
136
|
+
expect(await readFile(join(outside, "target.txt"), "utf8")).toBe("external");
|
|
137
|
+
},
|
|
138
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
test(
|
|
142
|
+
"a verified file is not written through a destination symlink",
|
|
143
|
+
async () => {
|
|
144
|
+
await writeFile(join(outside, "target.txt"), "external");
|
|
145
|
+
await symlink(join(outside, "target.txt"), join(out, "a.html"));
|
|
146
|
+
|
|
147
|
+
const r = await run([{ path: "a.html", listed: "real content", served: "real content" }]);
|
|
148
|
+
|
|
149
|
+
expect(r.exitCode).toBe(1);
|
|
150
|
+
expect(r.stderr).toContain("refused");
|
|
151
|
+
expect(await readFile(join(outside, "target.txt"), "utf8")).toBe("external");
|
|
152
|
+
expect(await readlink(join(out, "a.html"))).toBe(join(outside, "target.txt"));
|
|
153
|
+
},
|
|
154
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
test(
|
|
158
|
+
"a verified file is not written through a parent directory symlink",
|
|
159
|
+
async () => {
|
|
160
|
+
await symlink(outside, join(out, "project"));
|
|
161
|
+
|
|
162
|
+
const r = await run([
|
|
163
|
+
{ path: "project/a.html", listed: "real content", served: "real content" },
|
|
164
|
+
]);
|
|
165
|
+
|
|
166
|
+
expect(r.exitCode).toBe(1);
|
|
167
|
+
expect(r.stderr).toContain("refused");
|
|
168
|
+
expect(await readdir(outside)).toEqual([]);
|
|
169
|
+
},
|
|
170
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
test(
|
|
174
|
+
"manifest.json is not written through a symlink",
|
|
175
|
+
async () => {
|
|
176
|
+
await writeFile(join(outside, "target.json"), "external");
|
|
177
|
+
await symlink(join(outside, "target.json"), join(out, "manifest.json"));
|
|
178
|
+
|
|
179
|
+
const r = await run([{ path: "a.html", listed: "real content", served: "real content" }]);
|
|
180
|
+
|
|
181
|
+
expect(r.exitCode).toBe(1);
|
|
182
|
+
expect(await readFile(join(outside, "target.json"), "utf8")).toBe("external");
|
|
183
|
+
// The run stops before any artifact file is written.
|
|
184
|
+
await expect(lstat(join(out, "a.html"))).rejects.toThrow();
|
|
185
|
+
},
|
|
186
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
test(
|
|
190
|
+
"verified files and the manifest replace existing regular files",
|
|
191
|
+
async () => {
|
|
192
|
+
await mkdir(join(out, "project"));
|
|
193
|
+
await writeFile(join(out, "project/a.html"), "old");
|
|
194
|
+
await writeFile(join(out, "manifest.json"), "old");
|
|
195
|
+
|
|
196
|
+
const r = await run([
|
|
197
|
+
{ path: "project/a.html", listed: "real content", served: "real content" },
|
|
198
|
+
]);
|
|
199
|
+
|
|
200
|
+
expect(r.exitCode).toBe(0);
|
|
201
|
+
expect(r.stdout).toContain("ok: project/a.html");
|
|
202
|
+
expect(await readFile(join(out, "project/a.html"), "utf8")).toBe("real content");
|
|
203
|
+
expect(JSON.parse(await readFile(join(out, "manifest.json"), "utf8")).slug).toBe("art_mock");
|
|
204
|
+
expect(await readdir(join(out, "project"))).toEqual(["a.html"]);
|
|
205
|
+
expect((await lstat(join(out, "project/a.html"))).isFile()).toBe(true);
|
|
206
|
+
},
|
|
207
|
+
CHILD_PROCESS_TEST_BUDGET_MS,
|
|
208
|
+
);
|
|
209
|
+
});
|
|
@@ -475,6 +475,27 @@ describe("db-client slow statement warning", () => {
|
|
|
475
475
|
}
|
|
476
476
|
});
|
|
477
477
|
|
|
478
|
+
test("does not count a slow database open against the first statement", async () => {
|
|
479
|
+
// The first call opens the database (and applies migrations) through the
|
|
480
|
+
// client's getter. That cost is boot work, not the statement's.
|
|
481
|
+
let opened = false;
|
|
482
|
+
const lazy = createBunSqliteClient(() => {
|
|
483
|
+
if (!opened) {
|
|
484
|
+
opened = true;
|
|
485
|
+
Bun.sleepSync(150);
|
|
486
|
+
}
|
|
487
|
+
return raw;
|
|
488
|
+
});
|
|
489
|
+
const warn = spyOn(console, "warn").mockImplementation(() => {});
|
|
490
|
+
try {
|
|
491
|
+
await lazy.query("SELECT name FROM items");
|
|
492
|
+
expect(opened).toBe(true);
|
|
493
|
+
expect(slowWarnings(warn)).toHaveLength(0);
|
|
494
|
+
} finally {
|
|
495
|
+
warn.mockRestore();
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
|
|
478
499
|
test("does not log fast statements", async () => {
|
|
479
500
|
const warn = spyOn(console, "warn").mockImplementation(() => {});
|
|
480
501
|
try {
|
|
@@ -144,6 +144,7 @@ value:completeApprovalCancellationNotificationClaim
|
|
|
144
144
|
value:completeTask
|
|
145
145
|
value:computeContentHash
|
|
146
146
|
value:countActiveScriptRuns
|
|
147
|
+
value:countAgentDispatchesInThread
|
|
147
148
|
value:countAllMetrics
|
|
148
149
|
value:countAllPages
|
|
149
150
|
value:countKv
|
|
@@ -218,9 +219,10 @@ value:extensionAgentAssignmentError
|
|
|
218
219
|
value:failPendingResumeIfUnclaimed
|
|
219
220
|
value:failTask
|
|
220
221
|
value:findActiveTasksByVcs
|
|
221
|
-
value:
|
|
222
|
+
value:findCompletedTasksInThread
|
|
222
223
|
value:findExistingLinearTrackerContextWork
|
|
223
224
|
value:findRecentCancelledTaskInThread
|
|
225
|
+
value:findRecentFailedTaskInThread
|
|
224
226
|
value:findRecentSimilarTasks
|
|
225
227
|
value:findTaskByAgentMailThread
|
|
226
228
|
value:findTaskByGitHub
|
|
@@ -369,6 +371,7 @@ value:getScheduledTasks
|
|
|
369
371
|
value:getScriptRun
|
|
370
372
|
value:getScriptRunByIdempotencyKey
|
|
371
373
|
value:getScriptRunExecutionArgs
|
|
374
|
+
value:getScriptRunFollowUpGuard
|
|
372
375
|
value:getScriptRunJournalStep
|
|
373
376
|
value:getServiceByAgentAndName
|
|
374
377
|
value:getServiceById
|
|
@@ -561,6 +564,7 @@ value:setApiKeyName
|
|
|
561
564
|
value:setApiKeyPlan
|
|
562
565
|
value:setBudgetRefusalFollowUpTaskId
|
|
563
566
|
value:setFavorite
|
|
567
|
+
value:setScriptRunFollowUpGuard
|
|
564
568
|
value:setSlackMessageTracking
|
|
565
569
|
value:setUserFavorite
|
|
566
570
|
value:settleSupersededTaskDependents
|
|
@@ -622,10 +626,12 @@ type:PendingChatRelay
|
|
|
622
626
|
type:TaskFilters
|
|
623
627
|
value:SUPERSEDED_RESUME_REPAIR_WINDOW_MS
|
|
624
628
|
value:TASK_LINEAGE_LIMITS
|
|
629
|
+
value:countAgentDispatchesInThread
|
|
625
630
|
value:findActiveTasksByVcs
|
|
626
|
-
value:
|
|
631
|
+
value:findCompletedTasksInThread
|
|
627
632
|
value:findExistingLinearTrackerContextWork
|
|
628
633
|
value:findRecentCancelledTaskInThread
|
|
634
|
+
value:findRecentFailedTaskInThread
|
|
629
635
|
value:findTaskByGitHub
|
|
630
636
|
value:findTaskByVcs
|
|
631
637
|
value:getAgentCurrentTask
|
|
@@ -167,6 +167,7 @@ value:completeApprovalCancellationNotificationClaim
|
|
|
167
167
|
value:completeTask
|
|
168
168
|
value:computeContentHash
|
|
169
169
|
value:countActiveScriptRuns
|
|
170
|
+
value:countAgentDispatchesInThread
|
|
170
171
|
value:countAllMetrics
|
|
171
172
|
value:countAllPages
|
|
172
173
|
value:countKv
|
|
@@ -241,9 +242,10 @@ value:extensionAgentAssignmentError
|
|
|
241
242
|
value:failPendingResumeIfUnclaimed
|
|
242
243
|
value:failTask
|
|
243
244
|
value:findActiveTasksByVcs
|
|
244
|
-
value:
|
|
245
|
+
value:findCompletedTasksInThread
|
|
245
246
|
value:findExistingLinearTrackerContextWork
|
|
246
247
|
value:findRecentCancelledTaskInThread
|
|
248
|
+
value:findRecentFailedTaskInThread
|
|
247
249
|
value:findRecentSimilarTasks
|
|
248
250
|
value:findTaskByAgentMailThread
|
|
249
251
|
value:findTaskByGitHub
|
|
@@ -392,6 +394,7 @@ value:getScheduledTasks
|
|
|
392
394
|
value:getScriptRun
|
|
393
395
|
value:getScriptRunByIdempotencyKey
|
|
394
396
|
value:getScriptRunExecutionArgs
|
|
397
|
+
value:getScriptRunFollowUpGuard
|
|
395
398
|
value:getScriptRunJournalStep
|
|
396
399
|
value:getServiceByAgentAndName
|
|
397
400
|
value:getServiceById
|
|
@@ -584,6 +587,7 @@ value:setApiKeyName
|
|
|
584
587
|
value:setApiKeyPlan
|
|
585
588
|
value:setBudgetRefusalFollowUpTaskId
|
|
586
589
|
value:setFavorite
|
|
590
|
+
value:setScriptRunFollowUpGuard
|
|
587
591
|
value:setSlackMessageTracking
|
|
588
592
|
value:setUserFavorite
|
|
589
593
|
value:settleSupersededTaskDependents
|