@united-workforce/cli 0.1.1 → 0.2.1-rc.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/dist/__tests__/adapter-json-roundtrip.test.js +4 -1
- package/dist/__tests__/adapter-json-roundtrip.test.js.map +1 -1
- package/dist/__tests__/current-role.test.js +15 -3
- package/dist/__tests__/current-role.test.js.map +1 -1
- package/dist/__tests__/moderator-evaluate.test.js +20 -4
- package/dist/__tests__/moderator-evaluate.test.js.map +1 -1
- package/dist/__tests__/prompt.test.js +30 -42
- package/dist/__tests__/prompt.test.js.map +1 -1
- package/dist/__tests__/step-timing.test.js +8 -2
- package/dist/__tests__/step-timing.test.js.map +1 -1
- package/dist/__tests__/thread-location.test.js +15 -3
- package/dist/__tests__/thread-location.test.js.map +1 -1
- package/dist/__tests__/thread-resume.test.js +21 -6
- package/dist/__tests__/thread-resume.test.js.map +1 -1
- package/dist/__tests__/thread-show-status.test.js +10 -2
- package/dist/__tests__/thread-show-status.test.js.map +1 -1
- package/dist/__tests__/thread-start-cwd-cli.test.js +5 -1
- package/dist/__tests__/thread-start-cwd-cli.test.js.map +1 -1
- package/dist/__tests__/thread-suspend-step.test.js +4 -1
- package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
- package/dist/__tests__/thread-suspended-display.test.js +12 -3
- package/dist/__tests__/thread-suspended-display.test.js.map +1 -1
- package/dist/__tests__/validate-semantic.test.js +29 -12
- package/dist/__tests__/validate-semantic.test.js.map +1 -1
- package/dist/__tests__/workflow-resolution.test.js +4 -1
- package/dist/__tests__/workflow-resolution.test.js.map +1 -1
- package/dist/cli.js +5 -17
- package/dist/cli.js.map +1 -1
- package/dist/commands/prompt.d.ts +3 -4
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +120 -43
- package/dist/commands/prompt.js.map +1 -1
- package/dist/commands/thread.d.ts.map +1 -1
- package/dist/commands/thread.js +3 -7
- package/dist/commands/thread.js.map +1 -1
- package/dist/moderator/__tests__/evaluate.test.js +12 -12
- package/dist/moderator/__tests__/evaluate.test.js.map +1 -1
- package/dist/moderator/evaluate.d.ts.map +1 -1
- package/dist/moderator/evaluate.js +1 -7
- package/dist/moderator/evaluate.js.map +1 -1
- package/dist/validate-semantic.d.ts.map +1 -1
- package/dist/validate-semantic.js +4 -12
- package/dist/validate-semantic.js.map +1 -1
- package/dist/validate.js +3 -3
- package/dist/validate.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/adapter-json-roundtrip.test.ts +4 -1
- package/src/__tests__/current-role.test.ts +15 -3
- package/src/__tests__/fixtures/e2e-count.workflow.yaml +2 -1
- package/src/__tests__/fixtures/e2e-linear.workflow.yaml +2 -1
- package/src/__tests__/fixtures/e2e-loop.workflow.yaml +2 -1
- package/src/__tests__/fixtures/e2e-mustache.workflow.yaml +2 -1
- package/src/__tests__/fixtures/e2e-suspend.workflow.yaml +2 -1
- package/src/__tests__/moderator-evaluate.test.ts +21 -4
- package/src/__tests__/prompt.test.ts +29 -46
- package/src/__tests__/step-timing.test.ts +8 -2
- package/src/__tests__/thread-location.test.ts +15 -3
- package/src/__tests__/thread-resume.test.ts +21 -6
- package/src/__tests__/thread-show-status.test.ts +10 -2
- package/src/__tests__/thread-start-cwd-cli.test.ts +5 -1
- package/src/__tests__/thread-suspend-step.test.ts +4 -1
- package/src/__tests__/thread-suspended-display.test.ts +12 -3
- package/src/__tests__/validate-semantic.test.ts +36 -16
- package/src/__tests__/workflow-resolution.test.ts +4 -1
- package/src/cli.ts +4 -20
- package/src/commands/prompt.ts +119 -44
- package/src/commands/thread.ts +3 -8
- package/src/moderator/__tests__/evaluate.test.ts +12 -12
- package/src/moderator/evaluate.ts +1 -6
- package/src/validate-semantic.ts +4 -13
- package/src/validate.ts +3 -3
|
@@ -57,10 +57,14 @@ roles:
|
|
|
57
57
|
$status: { type: string, enum: ["ready"] }
|
|
58
58
|
graph:
|
|
59
59
|
$START:
|
|
60
|
-
|
|
60
|
+
new:
|
|
61
61
|
role: planner
|
|
62
62
|
prompt: "Plan the work"
|
|
63
63
|
location: null
|
|
64
|
+
resume:
|
|
65
|
+
role: planner
|
|
66
|
+
prompt: "Resume the work"
|
|
67
|
+
location: null
|
|
64
68
|
planner:
|
|
65
69
|
ready:
|
|
66
70
|
role: $END
|
|
@@ -113,10 +117,14 @@ roles:
|
|
|
113
117
|
$status: { type: string, enum: ["ready"] }
|
|
114
118
|
graph:
|
|
115
119
|
$START:
|
|
116
|
-
|
|
120
|
+
new:
|
|
117
121
|
role: planner
|
|
118
122
|
prompt: "Plan"
|
|
119
123
|
location: null
|
|
124
|
+
resume:
|
|
125
|
+
role: planner
|
|
126
|
+
prompt: "Resume"
|
|
127
|
+
location: null
|
|
120
128
|
planner:
|
|
121
129
|
ready:
|
|
122
130
|
role: $END
|
|
@@ -156,10 +164,14 @@ roles:
|
|
|
156
164
|
$status: { type: string, enum: ["ready"] }
|
|
157
165
|
graph:
|
|
158
166
|
$START:
|
|
159
|
-
|
|
167
|
+
new:
|
|
160
168
|
role: planner
|
|
161
169
|
prompt: "Plan"
|
|
162
170
|
location: null
|
|
171
|
+
resume:
|
|
172
|
+
role: planner
|
|
173
|
+
prompt: "Resume"
|
|
174
|
+
location: null
|
|
163
175
|
planner:
|
|
164
176
|
ready:
|
|
165
177
|
role: $END
|
|
@@ -70,7 +70,10 @@ async function setupSuspendedThread(mode: MockAgentMode): Promise<{
|
|
|
70
70
|
},
|
|
71
71
|
},
|
|
72
72
|
graph: {
|
|
73
|
-
$START: {
|
|
73
|
+
$START: {
|
|
74
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
75
|
+
resume: { role: "worker", prompt: "Resume the work", location: null },
|
|
76
|
+
},
|
|
74
77
|
worker: {
|
|
75
78
|
needs_input: {
|
|
76
79
|
role: "$SUSPEND",
|
|
@@ -233,7 +236,10 @@ describe("uwf thread resume", () => {
|
|
|
233
236
|
},
|
|
234
237
|
},
|
|
235
238
|
graph: {
|
|
236
|
-
$START: {
|
|
239
|
+
$START: {
|
|
240
|
+
new: { role: "worker", prompt: "Start", location: null },
|
|
241
|
+
resume: { role: "worker", prompt: "Resume", location: null },
|
|
242
|
+
},
|
|
237
243
|
worker: { done: { role: "$END", prompt: "Done", location: null } },
|
|
238
244
|
},
|
|
239
245
|
});
|
|
@@ -479,7 +485,10 @@ describe("uwf thread resume - completed threads", () => {
|
|
|
479
485
|
},
|
|
480
486
|
},
|
|
481
487
|
graph: {
|
|
482
|
-
$START: {
|
|
488
|
+
$START: {
|
|
489
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
490
|
+
resume: { role: "worker", prompt: "Resume the work", location: null },
|
|
491
|
+
},
|
|
483
492
|
worker: { done: { role: "reviewer", prompt: "Review the work", location: null } },
|
|
484
493
|
reviewer: { done: { role: "$END", prompt: "Done", location: null } },
|
|
485
494
|
},
|
|
@@ -610,7 +619,7 @@ echo '${adapterJson}'
|
|
|
610
619
|
expect(cliOutput.done).toBe(false);
|
|
611
620
|
|
|
612
621
|
const capturedPrompt = await readFile(promptCapturePath, "utf8");
|
|
613
|
-
expect(capturedPrompt).toContain("
|
|
622
|
+
expect(capturedPrompt).toContain("Resume the work");
|
|
614
623
|
expect(capturedPrompt).toContain("Additional context");
|
|
615
624
|
|
|
616
625
|
const storeModule = await import("../store.js");
|
|
@@ -640,7 +649,10 @@ echo '${adapterJson}'
|
|
|
640
649
|
},
|
|
641
650
|
},
|
|
642
651
|
graph: {
|
|
643
|
-
$START: {
|
|
652
|
+
$START: {
|
|
653
|
+
new: { role: "worker", prompt: "Start", location: null },
|
|
654
|
+
resume: { role: "worker", prompt: "Resume", location: null },
|
|
655
|
+
},
|
|
644
656
|
worker: { done: { role: "$END", prompt: "Done", location: null } },
|
|
645
657
|
},
|
|
646
658
|
});
|
|
@@ -688,7 +700,10 @@ echo '${adapterJson}'
|
|
|
688
700
|
},
|
|
689
701
|
},
|
|
690
702
|
graph: {
|
|
691
|
-
$START: {
|
|
703
|
+
$START: {
|
|
704
|
+
new: { role: "worker", prompt: "Start", location: null },
|
|
705
|
+
resume: { role: "worker", prompt: "Resume", location: null },
|
|
706
|
+
},
|
|
692
707
|
worker: { done: { role: "$END", prompt: "Done", location: null } },
|
|
693
708
|
},
|
|
694
709
|
});
|
|
@@ -34,10 +34,14 @@ roles:
|
|
|
34
34
|
$status: { type: string, enum: ["ready"] }
|
|
35
35
|
graph:
|
|
36
36
|
$START:
|
|
37
|
-
|
|
37
|
+
new:
|
|
38
38
|
role: planner
|
|
39
39
|
prompt: "Plan the work"
|
|
40
40
|
location: null
|
|
41
|
+
resume:
|
|
42
|
+
role: planner
|
|
43
|
+
prompt: "Resume the work"
|
|
44
|
+
location: null
|
|
41
45
|
planner:
|
|
42
46
|
ready:
|
|
43
47
|
role: $END
|
|
@@ -66,10 +70,14 @@ roles:
|
|
|
66
70
|
question: { type: string }
|
|
67
71
|
graph:
|
|
68
72
|
$START:
|
|
69
|
-
|
|
73
|
+
new:
|
|
70
74
|
role: worker
|
|
71
75
|
prompt: "Start work"
|
|
72
76
|
location: null
|
|
77
|
+
resume:
|
|
78
|
+
role: worker
|
|
79
|
+
prompt: "Resume work"
|
|
80
|
+
location: null
|
|
73
81
|
worker:
|
|
74
82
|
needs_input:
|
|
75
83
|
role: $SUSPEND
|
|
@@ -57,10 +57,14 @@ roles:
|
|
|
57
57
|
$status: { type: string, enum: ["ready"] }
|
|
58
58
|
graph:
|
|
59
59
|
$START:
|
|
60
|
-
|
|
60
|
+
new:
|
|
61
61
|
role: planner
|
|
62
62
|
prompt: "Plan the work"
|
|
63
63
|
location: null
|
|
64
|
+
resume:
|
|
65
|
+
role: planner
|
|
66
|
+
prompt: "Resume the work"
|
|
67
|
+
location: null
|
|
64
68
|
planner:
|
|
65
69
|
ready:
|
|
66
70
|
role: $END
|
|
@@ -58,7 +58,10 @@ describe("suspend step CAS chain and threads.yaml metadata", () => {
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
graph: {
|
|
61
|
-
$START: {
|
|
61
|
+
$START: {
|
|
62
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
63
|
+
resume: { role: "worker", prompt: "Resume work", location: null },
|
|
64
|
+
},
|
|
62
65
|
worker: {
|
|
63
66
|
needs_input: {
|
|
64
67
|
role: "$SUSPEND",
|
|
@@ -55,7 +55,10 @@ describe("suspended thread display", () => {
|
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
graph: {
|
|
58
|
-
$START: {
|
|
58
|
+
$START: {
|
|
59
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
60
|
+
resume: { role: "worker", prompt: "Resume work", location: null },
|
|
61
|
+
},
|
|
59
62
|
worker: {
|
|
60
63
|
needs_input: {
|
|
61
64
|
role: "$SUSPEND",
|
|
@@ -162,7 +165,10 @@ describe("suspended thread display", () => {
|
|
|
162
165
|
},
|
|
163
166
|
},
|
|
164
167
|
graph: {
|
|
165
|
-
$START: {
|
|
168
|
+
$START: {
|
|
169
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
170
|
+
resume: { role: "worker", prompt: "Resume work", location: null },
|
|
171
|
+
},
|
|
166
172
|
worker: {
|
|
167
173
|
needs_input: {
|
|
168
174
|
role: "$SUSPEND",
|
|
@@ -248,7 +254,10 @@ describe("suspended thread display", () => {
|
|
|
248
254
|
},
|
|
249
255
|
},
|
|
250
256
|
graph: {
|
|
251
|
-
$START: {
|
|
257
|
+
$START: {
|
|
258
|
+
new: { role: "worker", prompt: "Start work", location: null },
|
|
259
|
+
resume: { role: "worker", prompt: "Resume work", location: null },
|
|
260
|
+
},
|
|
252
261
|
},
|
|
253
262
|
});
|
|
254
263
|
|
|
@@ -51,7 +51,10 @@ function makeWorkflow(overrides?: Partial<WorkflowPayload>): WorkflowPayload {
|
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
53
|
graph: {
|
|
54
|
-
$START: {
|
|
54
|
+
$START: {
|
|
55
|
+
new: { role: "writer", prompt: "Begin writing", location: null },
|
|
56
|
+
resume: { role: "writer", prompt: "Review previous output and continue", location: null },
|
|
57
|
+
},
|
|
55
58
|
writer: { done: { role: "reviewer", prompt: "Review this: {{{plan}}}", location: null } },
|
|
56
59
|
reviewer: {
|
|
57
60
|
approved: { role: "$END", prompt: "Done: {{{summary}}}", location: null },
|
|
@@ -135,27 +138,38 @@ describe("Suite 2: Graph Structure", () => {
|
|
|
135
138
|
expect(errors.some((e) => e.includes("$START must be defined in graph"))).toBe(true);
|
|
136
139
|
});
|
|
137
140
|
|
|
138
|
-
test("2.2 $START
|
|
141
|
+
test("2.2 $START missing resume edge", () => {
|
|
139
142
|
const wf = makeWorkflow();
|
|
140
143
|
wf.graph.$START = {
|
|
141
|
-
|
|
142
|
-
other: { role: "reviewer", prompt: "Also", location: null },
|
|
144
|
+
new: { role: "writer", prompt: "Begin", location: null },
|
|
143
145
|
};
|
|
144
146
|
const errors = validateWorkflow(wf);
|
|
145
147
|
expect(
|
|
146
|
-
errors.some((e) => e.includes('$START must have
|
|
148
|
+
errors.some((e) => e.includes('$START must have edges with statuses "new" and "resume"')),
|
|
147
149
|
).toBe(true);
|
|
148
150
|
});
|
|
149
151
|
|
|
150
|
-
test("2.3 $START
|
|
152
|
+
test("2.3 $START missing new edge", () => {
|
|
151
153
|
const wf = makeWorkflow();
|
|
152
|
-
wf.graph.$START = {
|
|
154
|
+
wf.graph.$START = {
|
|
155
|
+
resume: { role: "writer", prompt: "Resume", location: null },
|
|
156
|
+
};
|
|
153
157
|
const errors = validateWorkflow(wf);
|
|
154
158
|
expect(
|
|
155
|
-
errors.some((e) => e.includes('$START must have
|
|
159
|
+
errors.some((e) => e.includes('$START must have edges with statuses "new" and "resume"')),
|
|
156
160
|
).toBe(true);
|
|
157
161
|
});
|
|
158
162
|
|
|
163
|
+
test("2.3b $START with new and resume passes", () => {
|
|
164
|
+
const wf = makeWorkflow();
|
|
165
|
+
wf.graph.$START = {
|
|
166
|
+
new: { role: "writer", prompt: "Begin", location: null },
|
|
167
|
+
resume: { role: "writer", prompt: "Resume", location: null },
|
|
168
|
+
};
|
|
169
|
+
const errors = validateWorkflow(wf);
|
|
170
|
+
expect(errors.some((e) => e.includes("$START must have edges"))).toBe(false);
|
|
171
|
+
});
|
|
172
|
+
|
|
159
173
|
test("2.4 $END has outgoing edges", () => {
|
|
160
174
|
const wf = makeWorkflow();
|
|
161
175
|
wf.graph.$END = { _: { role: "writer", prompt: "Loop", location: null } };
|
|
@@ -193,15 +207,18 @@ describe("Suite 2: Graph Structure", () => {
|
|
|
193
207
|
});
|
|
194
208
|
|
|
195
209
|
describe("Suite 3: Status-Edge Consistency", () => {
|
|
196
|
-
test("3.1 user role using _ graph key is
|
|
210
|
+
test("3.1 user role using _ graph key is treated as an unknown status", () => {
|
|
211
|
+
// "_" is no longer special-cased — it's just a status key that does not
|
|
212
|
+
// match the role's $status enum, so it surfaces as extra/missing keys.
|
|
197
213
|
const wf = makeWorkflow();
|
|
198
214
|
wf.graph.writer = { _: { role: "reviewer", prompt: "Review", location: null } };
|
|
199
215
|
const errors = validateWorkflow(wf);
|
|
200
|
-
expect(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
216
|
+
expect(errors.some((e) => e.includes('role "writer" graph has extra status keys: _'))).toBe(
|
|
217
|
+
true,
|
|
218
|
+
);
|
|
219
|
+
expect(errors.some((e) => e.includes('role "writer" graph is missing status keys: done'))).toBe(
|
|
220
|
+
true,
|
|
221
|
+
);
|
|
205
222
|
});
|
|
206
223
|
|
|
207
224
|
test("3.2 user role graph key not matching $status enum", () => {
|
|
@@ -240,13 +257,16 @@ describe("Suite 3: Status-Edge Consistency", () => {
|
|
|
240
257
|
).toBe(true);
|
|
241
258
|
});
|
|
242
259
|
|
|
243
|
-
test("3.5 multi-exit role with _ key", () => {
|
|
260
|
+
test("3.5 multi-exit role with _ key is treated as an unknown status", () => {
|
|
244
261
|
const wf = makeWorkflow();
|
|
245
262
|
wf.graph.reviewer = { _: { role: "$END", prompt: "Done", location: null } };
|
|
246
263
|
const errors = validateWorkflow(wf);
|
|
264
|
+
expect(errors.some((e) => e.includes('role "reviewer" graph has extra status keys: _'))).toBe(
|
|
265
|
+
true,
|
|
266
|
+
);
|
|
247
267
|
expect(
|
|
248
268
|
errors.some((e) =>
|
|
249
|
-
e.includes('role "reviewer"
|
|
269
|
+
e.includes('role "reviewer" graph is missing status keys: approved, rejected'),
|
|
250
270
|
),
|
|
251
271
|
).toBe(true);
|
|
252
272
|
});
|
|
@@ -38,7 +38,10 @@ function makeMinimalPayload(name: string, description: string): WorkflowPayload
|
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
graph: {
|
|
41
|
-
$START: {
|
|
41
|
+
$START: {
|
|
42
|
+
new: { role: "worker", prompt: "start working", location: null },
|
|
43
|
+
resume: { role: "worker", prompt: "resume working", location: null },
|
|
44
|
+
},
|
|
42
45
|
worker: { done: { role: "$END", prompt: "done", location: null } },
|
|
43
46
|
},
|
|
44
47
|
};
|
package/src/cli.ts
CHANGED
|
@@ -8,9 +8,7 @@ import {
|
|
|
8
8
|
cmdPromptAdapterDeveloping,
|
|
9
9
|
cmdPromptBootstrap,
|
|
10
10
|
cmdPromptList,
|
|
11
|
-
cmdPromptSetup,
|
|
12
11
|
cmdPromptUsage,
|
|
13
|
-
cmdPromptUsageReference,
|
|
14
12
|
cmdPromptWorkflowAuthoring,
|
|
15
13
|
} from "./commands/prompt.js";
|
|
16
14
|
import { cmdSetup, cmdSetupInteractive } from "./commands/setup.js";
|
|
@@ -509,23 +507,16 @@ prompt.addHelpCommand(false);
|
|
|
509
507
|
|
|
510
508
|
prompt
|
|
511
509
|
.command("usage")
|
|
512
|
-
.description("Print the
|
|
510
|
+
.description("Print the usage reference (CLI guide + typical workflows)")
|
|
513
511
|
.action(() => {
|
|
514
512
|
console.log(cmdPromptUsage());
|
|
515
513
|
});
|
|
516
514
|
|
|
517
515
|
prompt
|
|
518
|
-
.command("
|
|
519
|
-
.description("Print setup instructions for installing
|
|
520
|
-
.action(() => {
|
|
521
|
-
console.log(cmdPromptSetup());
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
prompt
|
|
525
|
-
.command("usage-reference")
|
|
526
|
-
.description("Print the usage reference (CLI guide + typical workflows)")
|
|
516
|
+
.command("bootstrap")
|
|
517
|
+
.description("Print setup instructions for installing uwf skills")
|
|
527
518
|
.action(() => {
|
|
528
|
-
console.log(
|
|
519
|
+
console.log(cmdPromptBootstrap());
|
|
529
520
|
});
|
|
530
521
|
|
|
531
522
|
prompt
|
|
@@ -542,13 +533,6 @@ prompt
|
|
|
542
533
|
console.log(cmdPromptAdapterDeveloping());
|
|
543
534
|
});
|
|
544
535
|
|
|
545
|
-
prompt
|
|
546
|
-
.command("bootstrap")
|
|
547
|
-
.description("Print the bootstrap skill YAML for Hermes agents")
|
|
548
|
-
.action(() => {
|
|
549
|
-
console.log(cmdPromptBootstrap());
|
|
550
|
-
});
|
|
551
|
-
|
|
552
536
|
prompt
|
|
553
537
|
.command("list")
|
|
554
538
|
.description("List all available prompt names")
|
package/src/commands/prompt.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAdapterDevelopingReference,
|
|
3
|
-
generateBootstrapReference,
|
|
4
3
|
generateUsageReference,
|
|
5
4
|
generateWorkflowAuthoringReference,
|
|
5
|
+
VERSION,
|
|
6
6
|
} from "@united-workforce/util";
|
|
7
7
|
|
|
8
8
|
export {
|
|
9
9
|
generateAdapterDevelopingReference as cmdPromptAdapterDeveloping,
|
|
10
|
-
|
|
11
|
-
generateUsageReference as cmdPromptUsageReference,
|
|
10
|
+
generateUsageReference as cmdPromptUsage,
|
|
12
11
|
generateWorkflowAuthoringReference as cmdPromptWorkflowAuthoring,
|
|
13
12
|
};
|
|
14
13
|
|
|
@@ -16,66 +15,142 @@ const PROMPT_ENTRIES: ReadonlyArray<{ name: string; generate: () => string }> =
|
|
|
16
15
|
{ name: "usage", generate: generateUsageReference },
|
|
17
16
|
{ name: "workflow-authoring", generate: generateWorkflowAuthoringReference },
|
|
18
17
|
{ name: "adapter-developing", generate: generateAdapterDevelopingReference },
|
|
19
|
-
{ name: "bootstrap", generate: generateBootstrapReference },
|
|
20
18
|
];
|
|
21
19
|
|
|
22
20
|
export function cmdPromptList(): ReadonlyArray<string> {
|
|
23
21
|
return PROMPT_ENTRIES.map((e) => e.name);
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
export function
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
export function cmdPromptBootstrap(): string {
|
|
25
|
+
return `# uwf Bootstrap
|
|
26
|
+
|
|
27
|
+
Set up or upgrade uwf (United Workforce) — from zero to running your first workflow.
|
|
28
|
+
|
|
29
|
+
## Scenario A: Fresh Install
|
|
30
|
+
|
|
31
|
+
### Step 1 — Install CLI and agent adapter
|
|
32
|
+
|
|
33
|
+
\`\`\`bash
|
|
34
|
+
npm install -g @united-workforce/cli
|
|
35
|
+
uwf --version # should print ${VERSION}
|
|
36
|
+
\`\`\`
|
|
37
|
+
|
|
38
|
+
Install an agent adapter (at least one is required):
|
|
39
|
+
|
|
40
|
+
| Adapter | Install | When to use |
|
|
41
|
+
|---------|---------|-------------|
|
|
42
|
+
| uwf-hermes | \`npm install -g @united-workforce/agent-hermes\` | When your agent framework is Hermes Agent |
|
|
43
|
+
| uwf-claude-code | \`npm install -g @united-workforce/agent-claude-code\` | When using Claude Code CLI directly |
|
|
44
|
+
| uwf-builtin | \`npm install -g @united-workforce/agent-builtin\` | Lightweight built-in agent (no external dependency) |
|
|
45
|
+
|
|
46
|
+
Verify the adapter is installed: \`uwf-hermes --version\` (or whichever you chose).
|
|
47
|
+
|
|
48
|
+
### Step 2 — Configure provider and model
|
|
49
|
+
|
|
50
|
+
uwf needs an LLM provider to run agents. **Ask the user** for their provider, API key, and model, then run:
|
|
51
|
+
|
|
52
|
+
\`\`\`bash
|
|
53
|
+
uwf setup --provider <name> --base-url <url> --api-key <key> --model <model> [--agent <adapter>]
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
Preset providers (base-url is auto-filled when using a preset name):
|
|
57
|
+
openai, xai, openrouter, venice, dashscope, deepseek, siliconflow, volcengine, kimi, glm, stepfun, minimax, ollama
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
\`\`\`bash
|
|
61
|
+
uwf setup --provider openrouter --api-key sk-or-... --model anthropic/claude-sonnet-4 --agent uwf-hermes
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
If the user doesn't know what to choose, suggest \`openrouter\` with \`anthropic/claude-sonnet-4\` as a sensible default.
|
|
65
|
+
|
|
66
|
+
Config is saved to \`~/.uwf/config.yaml\`. Verify with \`cat ~/.uwf/config.yaml\`.
|
|
67
|
+
|
|
68
|
+
### Step 3 — Install skills
|
|
69
|
+
|
|
70
|
+
Run each command and create a skill from its output:
|
|
31
71
|
|
|
32
|
-
|
|
33
|
-
|
|
72
|
+
\`\`\`bash
|
|
73
|
+
uwf prompt usage # → save as skill "uwf-usage"
|
|
74
|
+
uwf prompt workflow-authoring # → save as skill "uwf-workflow-authoring"
|
|
75
|
+
uwf prompt adapter-developing # → save as skill "uwf-adapter-developing"
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
Each command outputs a complete SKILL.md with YAML frontmatter. Use your agent framework's skill creation API to save them (e.g. \`skill_manage(action='create', name='uwf-usage', content=<output>)\`).
|
|
79
|
+
|
|
80
|
+
Verify skills are installed by listing them (e.g. \`skills_list()\`) and confirming all three appear.
|
|
81
|
+
|
|
82
|
+
### Step 4 — Verify end-to-end
|
|
83
|
+
|
|
84
|
+
Run a quick smoke test with the built-in eval workflow:
|
|
34
85
|
|
|
35
|
-
|
|
36
|
-
|
|
86
|
+
\`\`\`bash
|
|
87
|
+
# Start a thread with the example workflow
|
|
88
|
+
uwf thread start examples/eval-simple.yaml -p "Hello, test run"
|
|
89
|
+
|
|
90
|
+
# Execute one step
|
|
91
|
+
uwf thread exec <thread-id>
|
|
92
|
+
|
|
93
|
+
# Check result
|
|
94
|
+
uwf thread show <thread-id>
|
|
95
|
+
\`\`\`
|
|
37
96
|
|
|
38
|
-
|
|
97
|
+
If the thread reaches \`$END\` or produces output, the setup is working.
|
|
39
98
|
|
|
40
|
-
|
|
41
|
-
\`\`\`bash
|
|
42
|
-
uwf --help
|
|
43
|
-
\`\`\`
|
|
44
|
-
If not installed: \`npm install -g @united-workforce/cli\`
|
|
99
|
+
## Scenario B: Upgrade from Previous Version
|
|
45
100
|
|
|
46
|
-
|
|
47
|
-
- Look for any existing uwf/workflow skill files in your skill directories
|
|
48
|
-
(e.g. \`~/.hermes/skills/uwf/SKILL.md\` or similar paths).
|
|
49
|
-
- If a skill exists, read its \`version\` from the YAML frontmatter.
|
|
50
|
-
- If the version matches the current CLI version (\`uwf --version\`), you're done — no update needed.
|
|
51
|
-
- If the version is older, **delete the old skill file** before proceeding.
|
|
101
|
+
### Step 1 — Update packages
|
|
52
102
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
\`\`\`
|
|
57
|
-
The bootstrap prompt already includes complete YAML frontmatter — no editing needed.
|
|
103
|
+
\`\`\`bash
|
|
104
|
+
npm install -g @united-workforce/cli@latest
|
|
105
|
+
uwf --version # should print ${VERSION}
|
|
58
106
|
|
|
59
|
-
|
|
107
|
+
# Also update your adapter(s)
|
|
108
|
+
npm install -g @united-workforce/agent-hermes@latest
|
|
109
|
+
\`\`\`
|
|
60
110
|
|
|
61
|
-
|
|
111
|
+
### Step 2 — Regenerate skills
|
|
62
112
|
|
|
63
|
-
|
|
113
|
+
Skill content is bundled with the CLI — always regenerate after upgrading:
|
|
64
114
|
|
|
65
115
|
\`\`\`bash
|
|
66
|
-
uwf prompt
|
|
67
|
-
uwf prompt
|
|
68
|
-
uwf prompt
|
|
69
|
-
uwf prompt adapter-developing > ~/.hermes/skills/uwf-adapter-developing/SKILL.md
|
|
70
|
-
uwf prompt bootstrap > ~/.hermes/skills/uwf/SKILL.md # bootstrap skill
|
|
116
|
+
uwf prompt usage # → update skill "uwf-usage"
|
|
117
|
+
uwf prompt workflow-authoring # → update skill "uwf-workflow-authoring"
|
|
118
|
+
uwf prompt adapter-developing # → update skill "uwf-adapter-developing"
|
|
71
119
|
\`\`\`
|
|
72
120
|
|
|
73
|
-
|
|
121
|
+
### Step 3 — Migrate workflow YAML files (if needed)
|
|
74
122
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
123
|
+
Check the changelog for breaking changes. Known migrations:
|
|
124
|
+
|
|
125
|
+
- **v0.2.0**: \`$START._\` → \`$START.new\` + \`$START.resume\`. All workflow YAML files must be updated:
|
|
126
|
+
\`\`\`yaml
|
|
127
|
+
# Before (v0.1.x)
|
|
128
|
+
$START:
|
|
129
|
+
_: { role: planner, prompt: "..." }
|
|
130
|
+
|
|
131
|
+
# After (v0.2.0+)
|
|
132
|
+
$START:
|
|
133
|
+
new: { role: planner, prompt: "..." }
|
|
134
|
+
resume: { role: planner, prompt: "Review previous run and continue." }
|
|
135
|
+
\`\`\`
|
|
136
|
+
|
|
137
|
+
Update all \`.workflow/\` and \`.workflows/\` YAML files in your projects. \`uwf workflow add\` will reject files with the old \`_\` syntax.
|
|
138
|
+
|
|
139
|
+
### Step 4 — Verify
|
|
140
|
+
|
|
141
|
+
\`\`\`bash
|
|
142
|
+
uwf thread start <your-workflow> -p "upgrade test"
|
|
143
|
+
uwf thread exec <thread-id>
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
## Available prompts
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
uwf prompt list # list available prompt names
|
|
150
|
+
uwf prompt usage # CLI usage guide
|
|
151
|
+
uwf prompt workflow-authoring # workflow YAML design guide
|
|
152
|
+
uwf prompt adapter-developing # building agent adapters
|
|
153
|
+
uwf prompt bootstrap # this guide
|
|
154
|
+
\`\`\`
|
|
80
155
|
`;
|
|
81
156
|
}
|
package/src/commands/thread.ts
CHANGED
|
@@ -911,7 +911,7 @@ function resolveEvaluateArgs(
|
|
|
911
911
|
chain: ChainState,
|
|
912
912
|
): { lastRole: string; lastOutput: EvaluateLastOutput } {
|
|
913
913
|
if (chain.headIsStart) {
|
|
914
|
-
return { lastRole: START_ROLE, lastOutput: { [STATUS_KEY]: "
|
|
914
|
+
return { lastRole: START_ROLE, lastOutput: { [STATUS_KEY]: "new" } };
|
|
915
915
|
}
|
|
916
916
|
|
|
917
917
|
const lastStep = chain.stepsNewestFirst[0];
|
|
@@ -1037,7 +1037,6 @@ function archiveThread(uwf: UwfStore, threadId: ThreadId, _workflow: CasRef, _he
|
|
|
1037
1037
|
completeThread(uwf.varStore, threadId, "completed");
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
1040
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: orchestration function with inherent branching
|
|
1041
1040
|
export async function cmdThreadResume(
|
|
1042
1041
|
storageRoot: string,
|
|
1043
1042
|
threadId: ThreadId,
|
|
@@ -1101,7 +1100,7 @@ export async function cmdThreadResume(
|
|
|
1101
1100
|
|
|
1102
1101
|
// status === "completed"
|
|
1103
1102
|
const workflow = loadWorkflowPayload(uwf, workflowHash);
|
|
1104
|
-
const startResult = evaluate(workflow.graph, START_ROLE, {});
|
|
1103
|
+
const startResult = evaluate(workflow.graph, START_ROLE, { [STATUS_KEY]: "resume" });
|
|
1105
1104
|
if (!startResult.ok) {
|
|
1106
1105
|
fail(`failed to evaluate $START: ${startResult.error.message}`);
|
|
1107
1106
|
}
|
|
@@ -1113,11 +1112,7 @@ export async function cmdThreadResume(
|
|
|
1113
1112
|
}
|
|
1114
1113
|
|
|
1115
1114
|
const startRole = startResult.value.role;
|
|
1116
|
-
const
|
|
1117
|
-
const completedResumePrompt =
|
|
1118
|
-
supplement !== null && supplement !== ""
|
|
1119
|
-
? `${completedPromptPrefix}\n\n${supplement}`
|
|
1120
|
-
: completedPromptPrefix;
|
|
1115
|
+
const completedResumePrompt = buildResumePrompt(startResult.value.prompt, supplement);
|
|
1121
1116
|
|
|
1122
1117
|
const updatedEntry = { ...entry, status: "idle" as const, completedAt: null };
|
|
1123
1118
|
setThread(uwf.varStore, threadId, updatedEntry);
|