@stigmer/runner 3.40.0 → 3.41.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 +3 -1
- package/dist/.build-fingerprint +1 -1
- package/dist/__test-utils__/execution-record-fixture.d.ts +2 -1
- package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
- package/dist/activities/call-agent.js +1 -1
- package/dist/activities/discover-mcp-server.d.ts +7 -1
- package/dist/activities/discover-mcp-server.js +13 -29
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +4 -2
- package/dist/activities/execute-cursor/__test-utils__/fold.js +3 -4
- package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +1 -0
- package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
- package/dist/activities/execute-cursor/approval-policy.d.ts +1 -29
- package/dist/activities/execute-cursor/approval-policy.js +11 -35
- package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
- package/dist/activities/execute-cursor/boundary-rows.js +4 -4
- package/dist/activities/execute-cursor/boundary-rows.js.map +1 -1
- package/dist/activities/execute-cursor/translator.d.ts +12 -17
- package/dist/activities/execute-cursor/translator.js +13 -30
- package/dist/activities/execute-cursor/translator.js.map +1 -1
- package/dist/activities/execute-cursor/turn-stream.js +4 -2
- package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +11 -1
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -3
- package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
- package/dist/activities/execute-deep-agent/inline-publisher.d.ts +33 -2
- package/dist/activities/execute-deep-agent/inline-publisher.js +33 -7
- package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
- package/dist/activities/execute-deep-agent/platform-route.d.ts +48 -13
- package/dist/activities/execute-deep-agent/platform-route.js +87 -19
- package/dist/activities/execute-deep-agent/platform-route.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +70 -35
- package/dist/activities/execute-deep-agent/prompt-builder.js +70 -55
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +20 -3
- package/dist/activities/execute-deep-agent/streaming-side-effects.js +26 -4
- package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
- package/dist/activities/execute-deep-agent/translator.d.ts +5 -4
- package/dist/activities/execute-deep-agent/translator.js +5 -4
- package/dist/activities/execute-deep-agent/translator.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-settle.js +6 -6
- package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-setup.d.ts +18 -13
- package/dist/activities/execute-deep-agent/turn-setup.js +42 -36
- package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn-stream.d.ts +10 -6
- package/dist/activities/execute-deep-agent/turn-stream.js +6 -16
- package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
- package/dist/activities/execute-deep-agent/turn.d.ts +4 -1
- package/dist/activities/execute-deep-agent/turn.js +15 -6
- package/dist/activities/execute-deep-agent/turn.js.map +1 -1
- package/dist/activities/workflow-event-activities.js +2 -0
- package/dist/activities/workflow-event-activities.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/exit-backstop.d.ts +64 -0
- package/dist/exit-backstop.js +79 -0
- package/dist/exit-backstop.js.map +1 -0
- package/dist/harness/terminal-table.d.ts +12 -5
- package/dist/harness/terminal-table.js +13 -13
- package/dist/harness/terminal-table.js.map +1 -1
- package/dist/harness/transcript/builder.d.ts +21 -0
- package/dist/harness/transcript/builder.js +53 -31
- package/dist/harness/transcript/builder.js.map +1 -1
- package/dist/harness/transcript/events.d.ts +22 -26
- package/dist/harness/transcript/events.js +6 -5
- package/dist/harness/transcript/events.js.map +1 -1
- package/dist/harness/turn-context.d.ts +3 -1
- package/dist/harness/turn-context.js +5 -3
- package/dist/harness/turn-context.js.map +1 -1
- package/dist/main.js +10 -4
- package/dist/main.js.map +1 -1
- package/dist/middleware/cost-advisory.d.ts +6 -3
- package/dist/middleware/cost-advisory.js +6 -3
- package/dist/middleware/cost-advisory.js.map +1 -1
- package/dist/middleware/execution-budget.d.ts +22 -7
- package/dist/middleware/execution-budget.js +57 -35
- package/dist/middleware/execution-budget.js.map +1 -1
- package/dist/middleware/index.d.ts +10 -7
- package/dist/middleware/index.js +10 -7
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/types.d.ts +6 -1
- package/dist/runner-manager.js +3 -2
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.d.ts +25 -0
- package/dist/runner.js +41 -14
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +23 -13
- package/dist/shared/approval-policy.js +47 -14
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/caller-identity.d.ts +4 -5
- package/dist/shared/caller-identity.js +4 -5
- package/dist/shared/caller-identity.js.map +1 -1
- package/dist/shared/channel-attachment.js +3 -2
- package/dist/shared/channel-attachment.js.map +1 -1
- package/dist/shared/connect-backfill.d.ts +2 -1
- package/dist/shared/connect-backfill.js +2 -2
- package/dist/shared/connect-backfill.js.map +1 -1
- package/dist/shared/mcp-resolver.d.ts +10 -1
- package/dist/shared/mcp-resolver.js +11 -2
- package/dist/shared/mcp-resolver.js.map +1 -1
- package/dist/shared/memory-attachment.js +3 -2
- package/dist/shared/memory-attachment.js.map +1 -1
- package/dist/shared/model-error.d.ts +25 -3
- package/dist/shared/model-error.js +78 -10
- package/dist/shared/model-error.js.map +1 -1
- package/dist/shared/platform-server-address.d.ts +71 -0
- package/dist/shared/platform-server-address.js +103 -0
- package/dist/shared/platform-server-address.js.map +1 -0
- package/dist/shared/prompt-sections.d.ts +6 -28
- package/dist/shared/prompt-sections.js +6 -35
- package/dist/shared/prompt-sections.js.map +1 -1
- package/dist/shared/skill-resolver.d.ts +2 -3
- package/dist/shared/skill-resolver.js +2 -3
- package/dist/shared/skill-resolver.js.map +1 -1
- package/dist/shared/synthesized-attachment.d.ts +0 -5
- package/dist/shared/synthesized-attachment.js +0 -12
- package/dist/shared/synthesized-attachment.js.map +1 -1
- package/dist/shared/tool-rounds.d.ts +51 -23
- package/dist/shared/tool-rounds.js +67 -24
- package/dist/shared/tool-rounds.js.map +1 -1
- package/dist/shared/workspace/platform-dir.d.ts +15 -0
- package/dist/shared/workspace/platform-dir.js +18 -1
- package/dist/shared/workspace/platform-dir.js.map +1 -1
- package/dist/shared/workspace/sources/git.js +13 -6
- package/dist/shared/workspace/sources/git.js.map +1 -1
- package/dist/shared/workspace/stigmer-link.d.ts +21 -14
- package/dist/shared/workspace/stigmer-link.js +91 -29
- package/dist/shared/workspace/stigmer-link.js.map +1 -1
- package/dist/tools/url-guard.d.ts +5 -1
- package/dist/tools/url-guard.js +9 -2
- package/dist/tools/url-guard.js.map +1 -1
- package/dist/worker.d.ts +11 -2
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/dist/workflow-engine/tasks/human-input.d.ts +16 -0
- package/dist/workflow-engine/tasks/human-input.js +79 -37
- package/dist/workflow-engine/tasks/human-input.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +14 -4
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/call-agent-orchestrator.d.ts +13 -0
- package/dist/workflows/call-agent-orchestrator.js.map +1 -1
- package/dist/workflows/engine-core.d.ts +25 -0
- package/dist/workflows/engine-core.js.map +1 -1
- package/dist/workflows/execute-from-execution.d.ts +3 -0
- package/dist/workflows/execute-from-execution.js.map +1 -1
- package/dist/workflows/human-input-orchestrator.d.ts +9 -12
- package/dist/workflows/human-input-orchestrator.js +12 -44
- package/dist/workflows/human-input-orchestrator.js.map +1 -1
- package/package.json +5 -5
- package/src/__test-utils__/config-fixture.ts +1 -0
- package/src/__test-utils__/execution-record-fixture.ts +2 -1
- package/src/__test-utils__/harness-contract/runtime-contract.ts +5 -3
- package/src/__test-utils__/test-gate.ts +8 -0
- package/src/__tests__/exit-backstop.test.ts +91 -0
- package/src/__tests__/golden-e2e.test.ts +80 -62
- package/src/__tests__/history-encryption-e2e.test.ts +51 -27
- package/src/__tests__/runner.test.ts +60 -2
- package/src/activities/__tests__/classify-tool-approvals.test.ts +1 -0
- package/src/activities/__tests__/discover-mcp-server.hang.test.ts +5 -1
- package/src/activities/__tests__/discover-mcp-server.test.ts +90 -49
- package/src/activities/__tests__/workflow-event-activities.test.ts +28 -7
- package/src/activities/call-agent.ts +1 -1
- package/src/activities/discover-mcp-server.ts +27 -37
- package/src/activities/execute-cursor/__test-utils__/fold.ts +6 -4
- package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +1 -0
- package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +4 -29
- package/src/activities/execute-cursor/__tests__/hermetic/bypassed-tool-call.test.ts +120 -0
- package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -5
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +0 -3
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +0 -2
- package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +0 -3
- package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +9 -7
- package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +6 -1
- package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +8 -11
- package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +1 -3
- package/src/activities/execute-cursor/__tests__/translator.test.ts +68 -15
- package/src/activities/execute-cursor/approval-policy.ts +11 -36
- package/src/activities/execute-cursor/boundary-rows.ts +3 -3
- package/src/activities/execute-cursor/translator.ts +15 -32
- package/src/activities/execute-cursor/turn-stream.ts +4 -1
- package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +33 -2
- package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +1 -27
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +26 -30
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +1 -26
- package/src/activities/execute-deep-agent/__tests__/goldens/user-message.everything.md +36 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +4 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +8 -73
- package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
- package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +17 -0
- package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +86 -26
- package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +9 -5
- package/src/activities/execute-deep-agent/__tests__/hermetic/thrown-turn-drains-publishes.test.ts +159 -0
- package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +84 -0
- package/src/activities/execute-deep-agent/__tests__/platform-route.test.ts +47 -10
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +127 -199
- package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +31 -26
- package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +34 -0
- package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +13 -5
- package/src/activities/execute-deep-agent/inline-publisher.ts +47 -7
- package/src/activities/execute-deep-agent/platform-route.ts +109 -20
- package/src/activities/execute-deep-agent/prompt-builder.ts +104 -92
- package/src/activities/execute-deep-agent/streaming-side-effects.ts +27 -4
- package/src/activities/execute-deep-agent/translator.ts +5 -4
- package/src/activities/execute-deep-agent/turn-settle.ts +6 -6
- package/src/activities/execute-deep-agent/turn-setup.ts +43 -38
- package/src/activities/execute-deep-agent/turn-stream.ts +15 -22
- package/src/activities/execute-deep-agent/turn.ts +16 -7
- package/src/activities/workflow-event-activities.ts +2 -0
- package/src/config.ts +11 -0
- package/src/exit-backstop.ts +97 -0
- package/src/harness/README.md +5 -5
- package/src/harness/terminal-table.ts +13 -13
- package/src/harness/transcript/__tests__/builder.test.ts +93 -21
- package/src/harness/transcript/builder.ts +53 -30
- package/src/harness/transcript/events.ts +22 -27
- package/src/harness/turn-context.ts +5 -3
- package/src/main.ts +9 -5
- package/src/middleware/__tests__/execution-budget.test.ts +181 -103
- package/src/middleware/cost-advisory.ts +6 -3
- package/src/middleware/execution-budget.ts +60 -34
- package/src/middleware/index.ts +10 -7
- package/src/middleware/types.ts +6 -1
- package/src/runner-manager.ts +3 -2
- package/src/runner.ts +57 -15
- package/src/shared/__tests__/approval-policy.test.ts +41 -0
- package/src/shared/__tests__/artifact-storage.test.ts +1 -0
- package/src/shared/__tests__/connect-backfill.test.ts +15 -11
- package/src/shared/__tests__/mcp-resolver.test.ts +72 -10
- package/src/shared/__tests__/model-error.test.ts +71 -3
- package/src/shared/__tests__/platform-server-address.test.ts +122 -0
- package/src/shared/__tests__/prompt-sections.test.ts +2 -54
- package/src/shared/__tests__/tool-rounds.test.ts +64 -14
- package/src/shared/approval-policy.ts +57 -14
- package/src/shared/caller-identity.ts +4 -5
- package/src/shared/channel-attachment.ts +2 -2
- package/src/shared/connect-backfill.ts +5 -1
- package/src/shared/mcp-resolver.ts +11 -1
- package/src/shared/memory-attachment.ts +2 -2
- package/src/shared/model-error.ts +87 -9
- package/src/shared/platform-server-address.ts +123 -0
- package/src/shared/prompt-sections.ts +6 -55
- package/src/shared/skill-resolver.ts +2 -3
- package/src/shared/synthesized-attachment.ts +0 -12
- package/src/shared/tool-rounds.ts +70 -24
- package/src/shared/workspace/__tests__/git-source.test.ts +11 -5
- package/src/shared/workspace/__tests__/stigmer-link.test.ts +107 -10
- package/src/shared/workspace/platform-dir.ts +19 -1
- package/src/shared/workspace/sources/git.ts +14 -8
- package/src/shared/workspace/stigmer-link.ts +99 -29
- package/src/tools/__tests__/url-guard.test.ts +19 -1
- package/src/tools/url-guard.ts +9 -1
- package/src/worker.ts +12 -2
- package/src/workflow-engine/__tests__/golden-execution.test.ts +2 -1
- package/src/workflow-engine/__tests__/loader.test.ts +1 -1
- package/src/workflow-engine/__tests__/tasks/human-input.test.ts +133 -57
- package/src/workflow-engine/tasks/human-input.ts +92 -42
- package/src/workflow-engine/types.ts +16 -4
- package/src/workflows/call-agent-orchestrator.ts +7 -0
- package/src/workflows/engine-core.ts +18 -0
- package/src/workflows/execute-from-execution.ts +2 -1
- package/src/workflows/human-input-orchestrator.ts +15 -56
- package/dist/shared/skill-relevance.d.ts +0 -65
- package/dist/shared/skill-relevance.js +0 -175
- package/dist/shared/skill-relevance.js.map +0 -1
- package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +0 -146
- package/src/shared/__tests__/skill-relevance.test.ts +0 -292
- package/src/shared/skill-relevance.ts +0 -222
|
@@ -6,6 +6,7 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { create } from "@bufbuild/protobuf";
|
|
7
7
|
import { type AgentExecutionStatus, AgentExecutionStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
8
8
|
import { ExecutionArtifactKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
9
|
+
import { ExecutionArtifactSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
|
|
9
10
|
import { InlinePublisher } from "../inline-publisher.js";
|
|
10
11
|
import { TranscriptBuilder } from "../../../harness/transcript/builder.js";
|
|
11
12
|
import { LocalWorkspaceBackend } from "../../../shared/workspace/local-backend.js";
|
|
@@ -71,6 +72,7 @@ describe("InlinePublisher", () => {
|
|
|
71
72
|
workspaceBackend: backend,
|
|
72
73
|
artifactStorage: storage,
|
|
73
74
|
artifacts: sb,
|
|
75
|
+
record: status,
|
|
74
76
|
executionId: "exec-123",
|
|
75
77
|
});
|
|
76
78
|
});
|
|
@@ -97,6 +99,25 @@ describe("InlinePublisher", () => {
|
|
|
97
99
|
expect(status.artifacts[0].sandboxPath).toBe("src/main.ts");
|
|
98
100
|
});
|
|
99
101
|
|
|
102
|
+
it("stamps createdAt when the publish is asked for, never when the upload returns", async () => {
|
|
103
|
+
// The stream asks for the publish as it folds the write's finish, and the
|
|
104
|
+
// upload runs on beside the stream; a slow store must not move the stamp.
|
|
105
|
+
vi.useFakeTimers({ toFake: ["Date"], now: Date.UTC(2026, 0, 1) });
|
|
106
|
+
try {
|
|
107
|
+
const askedAt = new Date().toISOString();
|
|
108
|
+
vi.mocked(storage.upload).mockImplementationOnce(async (key: string) => {
|
|
109
|
+
vi.setSystemTime(Date.now() + 5_000);
|
|
110
|
+
return key;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await publisher.publish("src/main.ts");
|
|
114
|
+
|
|
115
|
+
expect(status.artifacts[0].createdAt).toBe(askedAt);
|
|
116
|
+
} finally {
|
|
117
|
+
vi.useRealTimers();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
100
121
|
it("deduplicates by path + content hash", async () => {
|
|
101
122
|
await publisher.publish("src/main.ts");
|
|
102
123
|
await publisher.publish("src/main.ts");
|
|
@@ -124,6 +145,64 @@ describe("InlinePublisher", () => {
|
|
|
124
145
|
expect(publisher.publishedPaths.has("src/main.ts")).toBe(true);
|
|
125
146
|
});
|
|
126
147
|
|
|
148
|
+
// A reinvocation seeds the earlier turns' rows onto the status before the
|
|
149
|
+
// turn's publisher exists; the safety net then asks for those paths again.
|
|
150
|
+
describe("against rows the status already lists (stigmer/stigmer#1448)", () => {
|
|
151
|
+
function seedRow(sandboxPath: string, content: string): void {
|
|
152
|
+
status.artifacts.push(create(ExecutionArtifactSchema, {
|
|
153
|
+
name: sandboxPath.split("/").at(-1) ?? sandboxPath,
|
|
154
|
+
sandboxPath,
|
|
155
|
+
kind: ExecutionArtifactKind.FILE,
|
|
156
|
+
storageKey: `artifacts/exec-123/${sandboxPath.split("/").at(-1)}`,
|
|
157
|
+
contentHash: sha256(content),
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
it("uploads nothing for a file whose bytes the status already lists, and counts it as brought up to date", async () => {
|
|
162
|
+
seedRow("src/main.ts", "console.log('hello');");
|
|
163
|
+
const seeded = status.artifacts[0];
|
|
164
|
+
|
|
165
|
+
await publisher.publish("src/main.ts");
|
|
166
|
+
|
|
167
|
+
expect(storage.uploadedKeys, "the unchanged file is not sent again").toEqual([]);
|
|
168
|
+
expect(status.artifacts, "the seeded row is kept as it was").toEqual([seeded]);
|
|
169
|
+
expect(publisher.publishedPaths.has("src/main.ts")).toBe(true);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("uploads and replaces the row when the file changed since the status listed it", async () => {
|
|
173
|
+
seedRow("src/main.ts", "an earlier turn's bytes");
|
|
174
|
+
|
|
175
|
+
await publisher.publish("src/main.ts");
|
|
176
|
+
|
|
177
|
+
expect(storage.uploadedKeys).toEqual(["artifacts/exec-123/main.ts"]);
|
|
178
|
+
expect(status.artifacts).toHaveLength(1);
|
|
179
|
+
expect(status.artifacts[0].contentHash).toBe(sha256("console.log('hello');"));
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("still reads the file, so a rewrite made outside a write tool is caught", async () => {
|
|
183
|
+
seedRow("src/main.ts", "console.log('hello');");
|
|
184
|
+
|
|
185
|
+
await publisher.publish("src/main.ts");
|
|
186
|
+
|
|
187
|
+
expect(backend.readFile).toHaveBeenCalledWith("src/main.ts");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("leaves an earlier turn's path out of publishedPaths until this turn checks it", () => {
|
|
191
|
+
seedRow("src/main.ts", "console.log('hello');");
|
|
192
|
+
|
|
193
|
+
expect(publisher.publishedPaths.size).toBe(0);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("uploads a file the status lists under another path", async () => {
|
|
197
|
+
seedRow("docs/main.ts", "console.log('hello');");
|
|
198
|
+
|
|
199
|
+
await publisher.publish("src/main.ts");
|
|
200
|
+
|
|
201
|
+
expect(storage.uploadedKeys).toEqual(["artifacts/exec-123/main.ts"]);
|
|
202
|
+
expect(status.artifacts.map((a) => a.sandboxPath)).toEqual(["docs/main.ts", "src/main.ts"]);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
127
206
|
it("swallows errors without throwing (fire-and-forget)", async () => {
|
|
128
207
|
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
129
208
|
const failBackend = mockWorkspaceBackend({});
|
|
@@ -132,6 +211,7 @@ describe("InlinePublisher", () => {
|
|
|
132
211
|
workspaceBackend: failBackend,
|
|
133
212
|
artifactStorage: storage,
|
|
134
213
|
artifacts: sb,
|
|
214
|
+
record: status,
|
|
135
215
|
executionId: "exec-err",
|
|
136
216
|
});
|
|
137
217
|
|
|
@@ -176,6 +256,7 @@ describe("InlinePublisher", () => {
|
|
|
176
256
|
workspaceBackend: secretBackend,
|
|
177
257
|
artifactStorage: storage,
|
|
178
258
|
artifacts: sb,
|
|
259
|
+
record: status,
|
|
179
260
|
executionId: "exec-secret",
|
|
180
261
|
});
|
|
181
262
|
|
|
@@ -193,6 +274,7 @@ describe("InlinePublisher", () => {
|
|
|
193
274
|
workspaceBackend: jsonBackend,
|
|
194
275
|
artifactStorage: storage,
|
|
195
276
|
artifacts: sb,
|
|
277
|
+
record: status,
|
|
196
278
|
executionId: "exec-ct",
|
|
197
279
|
});
|
|
198
280
|
|
|
@@ -221,6 +303,7 @@ describe("InlinePublisher with LocalWorkspaceBackend (disk-backed)", () => {
|
|
|
221
303
|
workspaceBackend: backend,
|
|
222
304
|
artifactStorage: storage,
|
|
223
305
|
artifacts: sb,
|
|
306
|
+
record: status,
|
|
224
307
|
executionId: "exec-disk",
|
|
225
308
|
});
|
|
226
309
|
|
|
@@ -250,6 +333,7 @@ describe("InlinePublisher with LocalWorkspaceBackend (disk-backed)", () => {
|
|
|
250
333
|
workspaceBackend: backend,
|
|
251
334
|
artifactStorage: storage,
|
|
252
335
|
artifacts: sb,
|
|
336
|
+
record: status,
|
|
253
337
|
executionId: "exec-miss",
|
|
254
338
|
});
|
|
255
339
|
|
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
// builds (`createCasCaptureBackend` + `mountPlatformRoute`, parent and
|
|
4
4
|
// sub-agents alike). The stock virtual-rooted backend refuses to follow the
|
|
5
5
|
// workspace link out of the root; the route mounts the platform dir instead,
|
|
6
|
-
// read-only, on the turns the link exists
|
|
6
|
+
// read-only, on the turns the link exists, and an empty route on every other
|
|
7
|
+
// turn. What is pinned:
|
|
7
8
|
// - the stock backend's refusal (why the route exists);
|
|
8
9
|
// - reads, listings and search through the route, for the shell-capable and
|
|
9
10
|
// the plan-mode backend, with `execute` kept exactly where it was;
|
|
10
11
|
// - every mutation through the route refused, and a root delete refused
|
|
11
12
|
// before it touches the workspace or the platform dir;
|
|
12
|
-
// -
|
|
13
|
+
// - on a turn without the link, `.stigmer/` still the platform's: nothing
|
|
14
|
+
// readable, every write refused and nothing created in the workspace (the
|
|
15
|
+
// write that used to make a real directory there, #1123), and the root
|
|
16
|
+
// listing without it.
|
|
13
17
|
|
|
14
18
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
15
|
-
import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
19
|
+
import { lstat, mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
16
20
|
import { tmpdir } from "node:os";
|
|
17
21
|
import { join } from "node:path";
|
|
18
22
|
import { FilesystemBackend, isSandboxBackend } from "deepagents";
|
|
@@ -120,23 +124,56 @@ describe("platform route", () => {
|
|
|
120
124
|
});
|
|
121
125
|
});
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
describe.each(["shell", "plan"] as const)("the %s backend on a turn without the link", (mode) => {
|
|
128
|
+
it("refuses every write under .stigmer/ and creates nothing in the workspace", async () => {
|
|
129
|
+
const backend = v2(await productionBackend(mode));
|
|
130
|
+
expect(backend).toBeInstanceOf(PlatformRoutedBackend);
|
|
131
|
+
expect((await backend.write(`${PLATFORM_ROUTE_PREFIX}notes/draft.md`, "x")).error).toMatch(/read-only/);
|
|
132
|
+
expect((await backend.edit(`/${SKILL}`, "My Skill", "Your Skill")).error).toMatch(/read-only/);
|
|
133
|
+
const uploads = (await backend.uploadFiles!([[`${PLATFORM_ROUTE_PREFIX}up.bin`, new Uint8Array([1])]])) ?? [];
|
|
134
|
+
expect(uploads.map((u) => u.error)).toEqual(["permission_denied"]);
|
|
135
|
+
await expect(lstat(join(workspaceDir, ".stigmer")), "no real directory in the user's tree").rejects.toMatchObject({
|
|
136
|
+
code: "ENOENT",
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("exposes nothing of the platform dir, which still holds earlier turns' content", async () => {
|
|
141
|
+
const backend = v2(await productionBackend(mode));
|
|
142
|
+
expect((await backend.read(`/${SKILL}`)).error).toMatch(/no platform content/);
|
|
143
|
+
expect((await backend.ls(PLATFORM_ROUTE_PREFIX)).error).toMatch(/no platform content/);
|
|
144
|
+
const found = (await backend.glob("**/SKILL.md", "/")).files ?? [];
|
|
145
|
+
expect(found).toEqual([]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("lists the workspace at the root without .stigmer/", async () => {
|
|
149
|
+
const backend = v2(await productionBackend(mode));
|
|
150
|
+
const root = ((await backend.ls("/")).files ?? []).map((f) => f.path);
|
|
151
|
+
expect(root).toContain("/main.go");
|
|
152
|
+
expect(root).not.toContain(PLATFORM_ROUTE_PREFIX);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("keeps `execute` exactly where the workspace backend had it", async () => {
|
|
156
|
+
const backend = await productionBackend(mode);
|
|
157
|
+
expect(isSandboxBackend(backend)).toBe(mode === "shell");
|
|
158
|
+
});
|
|
127
159
|
});
|
|
128
160
|
|
|
129
|
-
it("
|
|
161
|
+
it("exposes nothing when the link points somewhere else", async () => {
|
|
130
162
|
const other = await mkdtemp(join(tmpdir(), "platform-route-other-"));
|
|
131
163
|
try {
|
|
132
164
|
await ensureStigmerSymlink(workspaceDir, other);
|
|
133
|
-
const
|
|
134
|
-
expect(await
|
|
165
|
+
const backend = v2(await productionBackend("plan"));
|
|
166
|
+
expect((await backend.read(`/${SKILL}`)).error).toMatch(/no platform content/);
|
|
135
167
|
} finally {
|
|
136
168
|
await rm(other, { recursive: true, force: true });
|
|
137
169
|
}
|
|
138
170
|
});
|
|
139
171
|
|
|
172
|
+
it("mounts nothing for a session without a platform dir", async () => {
|
|
173
|
+
const workspace = await createCasCaptureBackend({ rootDir: workspaceDir, observer: observer(), shellEnv: {} });
|
|
174
|
+
expect(await mountPlatformRoute(workspace, { workspaceDir, platformDir: undefined })).toBe(workspace);
|
|
175
|
+
});
|
|
176
|
+
|
|
140
177
|
it("a workspace entry of its own is untouched by the route", async () => {
|
|
141
178
|
await mkdir(join(workspaceDir, "src"));
|
|
142
179
|
await writeFile(join(workspaceDir, "src/a.ts"), "export {};\n");
|