@united-workforce/cli 0.3.0 → 0.5.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 +45 -11
- package/dist/.build-fingerprint +1 -0
- package/dist/__tests__/adapter-json-roundtrip.test.js +17 -7
- package/dist/__tests__/adapter-json-roundtrip.test.js.map +1 -1
- package/dist/__tests__/agent-resolution-llm-free.test.d.ts +2 -0
- package/dist/__tests__/agent-resolution-llm-free.test.d.ts.map +1 -0
- package/dist/__tests__/agent-resolution-llm-free.test.js +30 -0
- package/dist/__tests__/agent-resolution-llm-free.test.js.map +1 -0
- package/dist/__tests__/build-step-entry.test.d.ts +2 -0
- package/dist/__tests__/build-step-entry.test.d.ts.map +1 -0
- package/dist/__tests__/build-step-entry.test.js +173 -0
- package/dist/__tests__/build-step-entry.test.js.map +1 -0
- package/dist/__tests__/clear-thread-failed-attempts.test.d.ts +2 -0
- package/dist/__tests__/clear-thread-failed-attempts.test.d.ts.map +1 -0
- package/dist/__tests__/clear-thread-failed-attempts.test.js +93 -0
- package/dist/__tests__/clear-thread-failed-attempts.test.js.map +1 -0
- package/dist/__tests__/concurrency.test.d.ts +2 -0
- package/dist/__tests__/concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/concurrency.test.js +196 -0
- package/dist/__tests__/concurrency.test.js.map +1 -0
- package/dist/__tests__/config.test.js +26 -302
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/current-role.test.js +7 -6
- package/dist/__tests__/current-role.test.js.map +1 -1
- package/dist/__tests__/e2e-mock-agent.test.js +43 -30
- package/dist/__tests__/e2e-mock-agent.test.js.map +1 -1
- package/dist/__tests__/format-text-default.test.d.ts +2 -0
- package/dist/__tests__/format-text-default.test.d.ts.map +1 -0
- package/dist/__tests__/format-text-default.test.js +43 -0
- package/dist/__tests__/format-text-default.test.js.map +1 -0
- package/dist/__tests__/format-text-registry.test.d.ts +2 -0
- package/dist/__tests__/format-text-registry.test.d.ts.map +1 -0
- package/dist/__tests__/format-text-registry.test.js +158 -0
- package/dist/__tests__/format-text-registry.test.js.map +1 -0
- package/dist/__tests__/issue-180-workflow-ref-removed.test.d.ts +2 -0
- package/dist/__tests__/issue-180-workflow-ref-removed.test.d.ts.map +1 -0
- package/dist/__tests__/issue-180-workflow-ref-removed.test.js +40 -0
- package/dist/__tests__/issue-180-workflow-ref-removed.test.js.map +1 -0
- package/dist/__tests__/log-text-renderer.test.d.ts +2 -0
- package/dist/__tests__/log-text-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/log-text-renderer.test.js +265 -0
- package/dist/__tests__/log-text-renderer.test.js.map +1 -0
- package/dist/__tests__/moderator-evaluate.test.js +9 -50
- package/dist/__tests__/moderator-evaluate.test.js.map +1 -1
- package/dist/__tests__/output-mapper-thread-list-startedat.test.d.ts +2 -0
- package/dist/__tests__/output-mapper-thread-list-startedat.test.d.ts.map +1 -0
- package/dist/__tests__/output-mapper-thread-list-startedat.test.js +102 -0
- package/dist/__tests__/output-mapper-thread-list-startedat.test.js.map +1 -0
- package/dist/__tests__/output-mapper-workflow-add.test.d.ts +2 -0
- package/dist/__tests__/output-mapper-workflow-add.test.d.ts.map +1 -0
- package/dist/__tests__/output-mapper-workflow-add.test.js +22 -0
- package/dist/__tests__/output-mapper-workflow-add.test.js.map +1 -0
- package/dist/__tests__/pid-recycling.test.d.ts +2 -0
- package/dist/__tests__/pid-recycling.test.d.ts.map +1 -0
- package/dist/__tests__/pid-recycling.test.js +273 -0
- package/dist/__tests__/pid-recycling.test.js.map +1 -0
- package/dist/__tests__/prompt.test.js +365 -2
- package/dist/__tests__/prompt.test.js.map +1 -1
- package/dist/__tests__/resolve-head-hash.test.js +12 -4
- package/dist/__tests__/resolve-head-hash.test.js.map +1 -1
- package/dist/__tests__/setup-agent-discovery.test.js +21 -30
- package/dist/__tests__/setup-agent-discovery.test.js.map +1 -1
- package/dist/__tests__/setup-complexity.test.js +2 -168
- package/dist/__tests__/setup-complexity.test.js.map +1 -1
- package/dist/__tests__/setup-no-llm.test.d.ts +2 -0
- package/dist/__tests__/setup-no-llm.test.d.ts.map +1 -0
- package/dist/__tests__/setup-no-llm.test.js +52 -0
- package/dist/__tests__/setup-no-llm.test.js.map +1 -0
- package/dist/__tests__/solve-issue-tea-worktree.test.js +27 -28
- package/dist/__tests__/solve-issue-tea-worktree.test.js.map +1 -1
- package/dist/__tests__/step-ask.test.d.ts +2 -0
- package/dist/__tests__/step-ask.test.d.ts.map +1 -0
- package/dist/__tests__/step-ask.test.js +507 -0
- package/dist/__tests__/step-ask.test.js.map +1 -0
- package/dist/__tests__/step-show-json.test.js +1 -0
- package/dist/__tests__/step-show-json.test.js.map +1 -1
- package/dist/__tests__/step-timing.test.js +2 -0
- package/dist/__tests__/step-timing.test.js.map +1 -1
- package/dist/__tests__/store-global-cas.test.js +2 -2
- package/dist/__tests__/store-global-cas.test.js.map +1 -1
- package/dist/__tests__/store-unified-threads.test.js +28 -26
- package/dist/__tests__/store-unified-threads.test.js.map +1 -1
- package/dist/__tests__/thread-cancel-status.test.js +25 -19
- package/dist/__tests__/thread-cancel-status.test.js.map +1 -1
- package/dist/__tests__/thread-cancel-text-renderer.test.d.ts +2 -0
- package/dist/__tests__/thread-cancel-text-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/thread-cancel-text-renderer.test.js +110 -0
- package/dist/__tests__/thread-cancel-text-renderer.test.js.map +1 -0
- package/dist/__tests__/thread-list-filters.test.js +354 -17
- package/dist/__tests__/thread-list-filters.test.js.map +1 -1
- package/dist/__tests__/thread-list-template-ms-date.test.d.ts +2 -0
- package/dist/__tests__/thread-list-template-ms-date.test.d.ts.map +1 -0
- package/dist/__tests__/thread-list-template-ms-date.test.js +102 -0
- package/dist/__tests__/thread-list-template-ms-date.test.js.map +1 -0
- package/dist/__tests__/thread-list-workflow-corrupt.test.d.ts +2 -0
- package/dist/__tests__/thread-list-workflow-corrupt.test.d.ts.map +1 -0
- package/dist/__tests__/thread-list-workflow-corrupt.test.js +157 -0
- package/dist/__tests__/thread-list-workflow-corrupt.test.js.map +1 -0
- package/dist/__tests__/thread-poke.test.d.ts +2 -0
- package/dist/__tests__/thread-poke.test.d.ts.map +1 -0
- package/dist/__tests__/thread-poke.test.js +422 -0
- package/dist/__tests__/thread-poke.test.js.map +1 -0
- package/dist/__tests__/thread-read-xml-tags.test.js +10 -9
- package/dist/__tests__/thread-read-xml-tags.test.js.map +1 -1
- package/dist/__tests__/thread-resume.test.js +21 -15
- package/dist/__tests__/thread-resume.test.js.map +1 -1
- package/dist/__tests__/thread-show-status.test.js +17 -28
- package/dist/__tests__/thread-show-status.test.js.map +1 -1
- package/dist/__tests__/thread-start-cwd-cli.test.js +15 -3
- package/dist/__tests__/thread-start-cwd-cli.test.js.map +1 -1
- package/dist/__tests__/thread-stop-text-renderer.test.d.ts +2 -0
- package/dist/__tests__/thread-stop-text-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/thread-stop-text-renderer.test.js +148 -0
- package/dist/__tests__/thread-stop-text-renderer.test.js.map +1 -0
- package/dist/__tests__/thread-suspend-step.test.js +13 -16
- package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
- package/dist/__tests__/thread-suspended-display.test.js +10 -22
- package/dist/__tests__/thread-suspended-display.test.js.map +1 -1
- package/dist/__tests__/thread-test-helpers.d.ts +7 -0
- package/dist/__tests__/thread-test-helpers.d.ts.map +1 -1
- package/dist/__tests__/thread-test-helpers.js +13 -0
- package/dist/__tests__/thread-test-helpers.js.map +1 -1
- package/dist/__tests__/thread.test.js +15 -13
- package/dist/__tests__/thread.test.js.map +1 -1
- package/dist/__tests__/validate-semantic.test.js +105 -23
- package/dist/__tests__/validate-semantic.test.js.map +1 -1
- package/dist/__tests__/workflow-list-recursive.test.d.ts +2 -0
- package/dist/__tests__/workflow-list-recursive.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-list-recursive.test.js +286 -0
- package/dist/__tests__/workflow-list-recursive.test.js.map +1 -0
- package/dist/__tests__/workflow-resolution.test.js +46 -28
- package/dist/__tests__/workflow-resolution.test.js.map +1 -1
- package/dist/__tests__/workflow-show-resolution.test.d.ts +2 -0
- package/dist/__tests__/workflow-show-resolution.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-show-resolution.test.js +213 -0
- package/dist/__tests__/workflow-show-resolution.test.js.map +1 -0
- package/dist/__tests__/workflow-validate.test.d.ts +2 -0
- package/dist/__tests__/workflow-validate.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-validate.test.js +707 -0
- package/dist/__tests__/workflow-validate.test.js.map +1 -0
- package/dist/__tests__/write-envelope.test.d.ts +2 -0
- package/dist/__tests__/write-envelope.test.d.ts.map +1 -0
- package/dist/__tests__/write-envelope.test.js +201 -0
- package/dist/__tests__/write-envelope.test.js.map +1 -0
- package/dist/background/background.d.ts +22 -1
- package/dist/background/background.d.ts.map +1 -1
- package/dist/background/background.js +83 -6
- package/dist/background/background.js.map +1 -1
- package/dist/background/index.d.ts +1 -1
- package/dist/background/index.d.ts.map +1 -1
- package/dist/background/index.js +1 -1
- package/dist/background/index.js.map +1 -1
- package/dist/background/types.d.ts +1 -0
- package/dist/background/types.d.ts.map +1 -1
- package/dist/cli.js +120 -62
- package/dist/cli.js.map +1 -1
- package/dist/commands/config.d.ts +3 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +17 -31
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +57 -31
- package/dist/commands/prompt.js.map +1 -1
- package/dist/commands/setup.d.ts +12 -39
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +72 -303
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/step.d.ts +44 -1
- package/dist/commands/step.d.ts.map +1 -1
- package/dist/commands/step.js +255 -11
- package/dist/commands/step.js.map +1 -1
- package/dist/commands/thread.d.ts +16 -3
- package/dist/commands/thread.d.ts.map +1 -1
- package/dist/commands/thread.js +423 -142
- package/dist/commands/thread.js.map +1 -1
- package/dist/commands/workflow.d.ts +9 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +126 -6
- package/dist/commands/workflow.js.map +1 -1
- package/dist/concurrency/concurrency.d.ts +34 -0
- package/dist/concurrency/concurrency.d.ts.map +1 -0
- package/dist/concurrency/concurrency.js +216 -0
- package/dist/concurrency/concurrency.js.map +1 -0
- package/dist/concurrency/index.d.ts +3 -0
- package/dist/concurrency/index.d.ts.map +1 -0
- package/dist/concurrency/index.js +2 -0
- package/dist/concurrency/index.js.map +1 -0
- package/dist/concurrency/types.d.ts +19 -0
- package/dist/concurrency/types.d.ts.map +1 -0
- package/dist/concurrency/types.js +2 -0
- package/dist/concurrency/types.js.map +1 -0
- package/dist/format.d.ts +69 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +198 -1
- package/dist/format.js.map +1 -1
- package/dist/moderator/__tests__/evaluate.test.js +31 -17
- package/dist/moderator/__tests__/evaluate.test.js.map +1 -1
- package/dist/moderator/evaluate.d.ts.map +1 -1
- package/dist/moderator/evaluate.js +4 -16
- package/dist/moderator/evaluate.js.map +1 -1
- package/dist/moderator/index.d.ts +1 -2
- package/dist/moderator/index.d.ts.map +1 -1
- package/dist/moderator/index.js +0 -1
- package/dist/moderator/index.js.map +1 -1
- package/dist/moderator/types.d.ts +6 -10
- package/dist/moderator/types.d.ts.map +1 -1
- package/dist/moderator/types.js +1 -3
- package/dist/moderator/types.js.map +1 -1
- package/dist/output-mappers.d.ts +122 -0
- package/dist/output-mappers.d.ts.map +1 -0
- package/dist/output-mappers.js +134 -0
- package/dist/output-mappers.js.map +1 -0
- package/dist/schemas.d.ts +6 -1
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +34 -5
- package/dist/schemas.js.map +1 -1
- package/dist/store.d.ts +28 -9
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +75 -16
- package/dist/store.js.map +1 -1
- package/dist/text-renderers.d.ts +30 -0
- package/dist/text-renderers.d.ts.map +1 -0
- package/dist/text-renderers.js +251 -0
- package/dist/text-renderers.js.map +1 -0
- package/dist/validate-semantic.d.ts.map +1 -1
- package/dist/validate-semantic.js +95 -61
- package/dist/validate-semantic.js.map +1 -1
- package/dist/validate.d.ts +6 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +24 -0
- package/dist/validate.js.map +1 -1
- package/examples/brainstorm.yaml +130 -0
- package/examples/debate.yaml +169 -0
- package/examples/socratic-questioning.yaml +112 -0
- package/package.json +9 -10
- package/src/__tests__/adapter-json-roundtrip.test.ts +16 -7
- package/src/__tests__/agent-resolution-llm-free.test.ts +39 -0
- package/src/__tests__/build-step-entry.test.ts +203 -0
- package/src/__tests__/clear-thread-failed-attempts.test.ts +122 -0
- package/src/__tests__/concurrency.test.ts +266 -0
- package/src/__tests__/config.test.ts +33 -321
- package/src/__tests__/current-role.test.ts +7 -6
- package/src/__tests__/e2e-mock-agent.test.ts +65 -30
- package/src/__tests__/fixtures/e2e-count.workflow.yaml +1 -0
- package/src/__tests__/fixtures/e2e-linear.workflow.yaml +1 -0
- package/src/__tests__/fixtures/{e2e-mustache.workflow.yaml → e2e-liquid.workflow.yaml} +3 -2
- package/src/__tests__/fixtures/e2e-loop.workflow.yaml +1 -0
- package/src/__tests__/fixtures/e2e-suspend.mock.yaml +2 -2
- package/src/__tests__/fixtures/e2e-suspend.workflow.yaml +6 -10
- package/src/__tests__/format-text-default.test.ts +49 -0
- package/src/__tests__/format-text-registry.test.ts +173 -0
- package/src/__tests__/issue-180-workflow-ref-removed.test.ts +43 -0
- package/src/__tests__/log-text-renderer.test.ts +294 -0
- package/src/__tests__/moderator-evaluate.test.ts +9 -52
- package/src/__tests__/output-mapper-thread-list-startedat.test.ts +124 -0
- package/src/__tests__/output-mapper-workflow-add.test.ts +24 -0
- package/src/__tests__/pid-recycling.test.ts +329 -0
- package/src/__tests__/prompt.test.ts +443 -2
- package/src/__tests__/resolve-head-hash.test.ts +11 -4
- package/src/__tests__/setup-agent-discovery.test.ts +26 -51
- package/src/__tests__/setup-complexity.test.ts +1 -203
- package/src/__tests__/setup-no-llm.test.ts +68 -0
- package/src/__tests__/solve-issue-tea-worktree.test.ts +27 -31
- package/src/__tests__/step-ask.test.ts +677 -0
- package/src/__tests__/step-show-json.test.ts +1 -0
- package/src/__tests__/step-timing.test.ts +2 -0
- package/src/__tests__/store-global-cas.test.ts +2 -2
- package/src/__tests__/store-unified-threads.test.ts +30 -27
- package/src/__tests__/thread-cancel-status.test.ts +27 -20
- package/src/__tests__/thread-cancel-text-renderer.test.ts +125 -0
- package/src/__tests__/thread-list-filters.test.ts +443 -17
- package/src/__tests__/thread-list-template-ms-date.test.ts +110 -0
- package/src/__tests__/thread-list-workflow-corrupt.test.ts +198 -0
- package/src/__tests__/thread-poke.test.ts +554 -0
- package/src/__tests__/thread-read-xml-tags.test.ts +9 -11
- package/src/__tests__/thread-resume.test.ts +20 -15
- package/src/__tests__/thread-show-status.test.ts +17 -29
- package/src/__tests__/thread-start-cwd-cli.test.ts +15 -3
- package/src/__tests__/thread-stop-text-renderer.test.ts +168 -0
- package/src/__tests__/thread-suspend-step.test.ts +13 -16
- package/src/__tests__/thread-suspended-display.test.ts +10 -22
- package/src/__tests__/thread-test-helpers.ts +15 -1
- package/src/__tests__/thread.test.ts +14 -14
- package/src/__tests__/validate-semantic.test.ts +118 -33
- package/src/__tests__/workflow-list-recursive.test.ts +370 -0
- package/src/__tests__/workflow-resolution.test.ts +48 -29
- package/src/__tests__/workflow-show-resolution.test.ts +286 -0
- package/src/__tests__/workflow-validate.test.ts +828 -0
- package/src/__tests__/write-envelope.test.ts +257 -0
- package/src/background/background.ts +88 -6
- package/src/background/index.ts +2 -0
- package/src/background/types.ts +1 -0
- package/src/cli.ts +184 -77
- package/src/commands/config.ts +16 -33
- package/src/commands/prompt.ts +57 -31
- package/src/commands/setup.ts +80 -358
- package/src/commands/step.ts +339 -12
- package/src/commands/thread.ts +511 -171
- package/src/commands/workflow.ts +155 -4
- package/src/concurrency/concurrency.ts +245 -0
- package/src/concurrency/index.ts +10 -0
- package/src/concurrency/types.ts +19 -0
- package/src/format.ts +282 -2
- package/src/moderator/__tests__/evaluate.test.ts +34 -17
- package/src/moderator/evaluate.ts +5 -17
- package/src/moderator/index.ts +1 -6
- package/src/moderator/types.ts +6 -14
- package/src/output-mappers.ts +254 -0
- package/src/schemas.ts +51 -5
- package/src/store.ts +86 -20
- package/src/text-renderers.ts +355 -0
- package/src/validate-semantic.ts +125 -73
- package/src/validate.ts +27 -0
- package/dist/__tests__/setup-validate.test.d.ts +0 -2
- package/dist/__tests__/setup-validate.test.d.ts.map +0 -1
- package/dist/__tests__/setup-validate.test.js +0 -108
- package/dist/__tests__/setup-validate.test.js.map +0 -1
- package/src/__tests__/setup-validate.test.ts +0 -148
- /package/src/__tests__/fixtures/{e2e-mustache.mock.yaml → e2e-liquid.mock.yaml} +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import type { CasRef, ThreadId } from "@united-workforce/protocol";
|
|
5
|
+
import { createThreadIndexEntry } from "@united-workforce/protocol";
|
|
6
|
+
import { generateUlid } from "@united-workforce/util";
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
8
|
+
import { cmdThreadList } from "../commands/thread.js";
|
|
9
|
+
import type { UwfStore } from "../store.js";
|
|
10
|
+
import { completeThread as completeThreadInStore, setThread } from "../store.js";
|
|
11
|
+
import { makeUwfStore } from "./thread-test-helpers.js";
|
|
12
|
+
|
|
13
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
async function createTestWorkflow(uwf: UwfStore): Promise<CasRef> {
|
|
16
|
+
const workflowPayload = {
|
|
17
|
+
name: "test-workflow",
|
|
18
|
+
roles: {
|
|
19
|
+
role1: {
|
|
20
|
+
goal: "test goal",
|
|
21
|
+
outputSchema: { type: "object" as const, properties: {} },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
graph: { start: "role1" },
|
|
25
|
+
conditions: {},
|
|
26
|
+
};
|
|
27
|
+
return await uwf.store.cas.put(uwf.schemas.workflow, workflowPayload);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function createTestThread(
|
|
31
|
+
uwf: UwfStore,
|
|
32
|
+
storageRoot: string,
|
|
33
|
+
workflowHash: CasRef,
|
|
34
|
+
timestamp: number,
|
|
35
|
+
): Promise<ThreadId> {
|
|
36
|
+
const threadId = generateUlid(timestamp) as ThreadId;
|
|
37
|
+
const startPayload = {
|
|
38
|
+
workflow: workflowHash,
|
|
39
|
+
prompt: "test prompt",
|
|
40
|
+
cwd: storageRoot,
|
|
41
|
+
};
|
|
42
|
+
const headHash = await uwf.store.cas.put(uwf.schemas.startNode, startPayload);
|
|
43
|
+
setThread(uwf.varStore, threadId, createThreadIndexEntry(headHash));
|
|
44
|
+
return threadId;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ── test setup ────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
let tmpDir: string;
|
|
50
|
+
let savedOcasHome: string | undefined;
|
|
51
|
+
|
|
52
|
+
beforeEach(async () => {
|
|
53
|
+
savedOcasHome = process.env.OCAS_HOME;
|
|
54
|
+
tmpDir = await mkdtemp(join(tmpdir(), "thread-list-workflow-corrupt-test-"));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
afterEach(async () => {
|
|
58
|
+
if (savedOcasHome === undefined) {
|
|
59
|
+
delete process.env.OCAS_HOME;
|
|
60
|
+
} else {
|
|
61
|
+
process.env.OCAS_HOME = savedOcasHome;
|
|
62
|
+
}
|
|
63
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ── issue #326: loadWorkflowPayload throws instead of process.exit ───────────
|
|
67
|
+
|
|
68
|
+
describe("loadWorkflowPayload throws on error (#326)", () => {
|
|
69
|
+
test("active thread with missing workflow CAS node appears as corrupt", async () => {
|
|
70
|
+
const uwf = await makeUwfStore(tmpDir);
|
|
71
|
+
const workflowHash = await createTestWorkflow(uwf);
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
|
|
74
|
+
// Create a valid thread
|
|
75
|
+
const validId = await createTestThread(uwf, tmpDir, workflowHash, now);
|
|
76
|
+
|
|
77
|
+
// Create a thread with a different workflow, then delete it
|
|
78
|
+
const otherWorkflowPayload = {
|
|
79
|
+
name: "other-workflow",
|
|
80
|
+
roles: {
|
|
81
|
+
role1: {
|
|
82
|
+
goal: "other goal",
|
|
83
|
+
outputSchema: { type: "object" as const, properties: {} },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
graph: { start: "role1" },
|
|
87
|
+
conditions: {},
|
|
88
|
+
};
|
|
89
|
+
const otherWorkflowHash = await uwf.store.cas.put(uwf.schemas.workflow, otherWorkflowPayload);
|
|
90
|
+
const corruptId = await createTestThread(uwf, tmpDir, otherWorkflowHash, now + 1000);
|
|
91
|
+
|
|
92
|
+
// Delete the other workflow CAS node — start node still exists but workflow ref dangles
|
|
93
|
+
uwf.store.cas.delete(otherWorkflowHash);
|
|
94
|
+
|
|
95
|
+
// thread list should NOT crash — corrupt thread appears with status: "corrupt"
|
|
96
|
+
const result = await cmdThreadList(tmpDir, null, null, null, null, null, true);
|
|
97
|
+
|
|
98
|
+
expect(result.length).toBe(2);
|
|
99
|
+
|
|
100
|
+
const validItem = result.find((r) => r.thread === validId);
|
|
101
|
+
expect(validItem).toBeDefined();
|
|
102
|
+
expect(validItem!.status).toBe("idle");
|
|
103
|
+
|
|
104
|
+
const corruptItem = result.find((r) => r.thread === corruptId);
|
|
105
|
+
expect(corruptItem).toBeDefined();
|
|
106
|
+
expect(corruptItem!.status).toBe("corrupt");
|
|
107
|
+
expect(corruptItem!.statusDisplay).toBe("corrupt");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("active thread with wrong-type workflow CAS node appears as corrupt", async () => {
|
|
111
|
+
const uwf = await makeUwfStore(tmpDir);
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
|
|
114
|
+
// Create a valid workflow and thread
|
|
115
|
+
const workflowHash = await createTestWorkflow(uwf);
|
|
116
|
+
const validId = await createTestThread(uwf, tmpDir, workflowHash, now);
|
|
117
|
+
|
|
118
|
+
// Create a non-workflow CAS node (text type) and use its hash as a workflow ref
|
|
119
|
+
const wrongTypeHash = await uwf.store.cas.put(uwf.schemas.text, "not a workflow");
|
|
120
|
+
|
|
121
|
+
// Create a thread whose start node points to the wrong-type CAS node
|
|
122
|
+
const corruptId = generateUlid(now + 1000) as ThreadId;
|
|
123
|
+
const startPayload = {
|
|
124
|
+
workflow: wrongTypeHash,
|
|
125
|
+
prompt: "corrupt thread with wrong type workflow",
|
|
126
|
+
cwd: tmpDir,
|
|
127
|
+
};
|
|
128
|
+
const headHash = await uwf.store.cas.put(uwf.schemas.startNode, startPayload);
|
|
129
|
+
setThread(uwf.varStore, corruptId, createThreadIndexEntry(headHash));
|
|
130
|
+
|
|
131
|
+
// thread list should NOT crash — wrong-type thread appears as corrupt
|
|
132
|
+
const result = await cmdThreadList(tmpDir, null, null, null, null, null, true);
|
|
133
|
+
|
|
134
|
+
expect(result.length).toBe(2);
|
|
135
|
+
|
|
136
|
+
const validItem = result.find((r) => r.thread === validId);
|
|
137
|
+
expect(validItem).toBeDefined();
|
|
138
|
+
expect(validItem!.status).toBe("idle");
|
|
139
|
+
|
|
140
|
+
const corruptItem = result.find((r) => r.thread === corruptId);
|
|
141
|
+
expect(corruptItem).toBeDefined();
|
|
142
|
+
expect(corruptItem!.status).toBe("corrupt");
|
|
143
|
+
expect(corruptItem!.statusDisplay).toBe("corrupt");
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("completed thread with missing workflow CAS node retains stored status with --all", async () => {
|
|
147
|
+
const uwf = await makeUwfStore(tmpDir);
|
|
148
|
+
const now = Date.now();
|
|
149
|
+
|
|
150
|
+
// Create two separate workflows so we can corrupt one without affecting the other
|
|
151
|
+
const activeWorkflowHash = await createTestWorkflow(uwf);
|
|
152
|
+
const completedWorkflowPayload = {
|
|
153
|
+
name: "completed-workflow",
|
|
154
|
+
roles: {
|
|
155
|
+
role1: {
|
|
156
|
+
goal: "completed goal",
|
|
157
|
+
outputSchema: { type: "object" as const, properties: {} },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
graph: { start: "role1" },
|
|
161
|
+
conditions: {},
|
|
162
|
+
};
|
|
163
|
+
const completedWorkflowHash = await uwf.store.cas.put(
|
|
164
|
+
uwf.schemas.workflow,
|
|
165
|
+
completedWorkflowPayload,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
// Create a valid active thread
|
|
169
|
+
const activeId = await createTestThread(uwf, tmpDir, activeWorkflowHash, now);
|
|
170
|
+
|
|
171
|
+
// Create a thread and complete it
|
|
172
|
+
const completedId = await createTestThread(uwf, tmpDir, completedWorkflowHash, now + 1000);
|
|
173
|
+
completeThreadInStore(uwf.varStore, completedId, "end");
|
|
174
|
+
|
|
175
|
+
// Delete only the completed thread's workflow CAS node
|
|
176
|
+
uwf.store.cas.delete(completedWorkflowHash);
|
|
177
|
+
|
|
178
|
+
// thread list --all should NOT crash
|
|
179
|
+
const result = await cmdThreadList(tmpDir, null, null, null, null, null, true);
|
|
180
|
+
|
|
181
|
+
expect(result.length).toBe(2);
|
|
182
|
+
|
|
183
|
+
// Active thread is still valid (its workflow exists)
|
|
184
|
+
const activeItem = result.find((r) => r.thread === activeId);
|
|
185
|
+
expect(activeItem).toBeDefined();
|
|
186
|
+
expect(activeItem!.status).toBe("idle");
|
|
187
|
+
|
|
188
|
+
// Completed thread retains its stored status — collectCompletedThreads only calls
|
|
189
|
+
// resolveWorkflowFromHead (returns ref from start node) and never loads the workflow CAS node
|
|
190
|
+
const completedItem = result.find((r) => r.thread === completedId);
|
|
191
|
+
expect(completedItem).toBeDefined();
|
|
192
|
+
expect(completedItem!.status).toBe("end");
|
|
193
|
+
expect(completedItem!.statusDisplay).toBe("end");
|
|
194
|
+
// workflowName is null because the workflow ref won't match a registry entry
|
|
195
|
+
// (the deleted workflow was never registered)
|
|
196
|
+
expect(completedItem!.workflowName).toBeNull();
|
|
197
|
+
});
|
|
198
|
+
});
|