@united-workforce/cli 0.6.0 → 0.7.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.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -1
  3. package/dist/__tests__/agent-resolution-llm-free.test.js +9 -2
  4. package/dist/__tests__/agent-resolution-llm-free.test.js.map +1 -1
  5. package/dist/__tests__/broker-prompt.test.d.ts +10 -0
  6. package/dist/__tests__/broker-prompt.test.d.ts.map +1 -0
  7. package/dist/__tests__/broker-prompt.test.js +129 -0
  8. package/dist/__tests__/broker-prompt.test.js.map +1 -0
  9. package/dist/__tests__/config.test.js +33 -37
  10. package/dist/__tests__/config.test.js.map +1 -1
  11. package/dist/__tests__/e2e-broker-step.test.d.ts +13 -0
  12. package/dist/__tests__/e2e-broker-step.test.d.ts.map +1 -0
  13. package/dist/__tests__/e2e-broker-step.test.js +278 -0
  14. package/dist/__tests__/e2e-broker-step.test.js.map +1 -0
  15. package/dist/__tests__/e2e-mock-agent.test.js +1 -1
  16. package/dist/__tests__/e2e-mock-agent.test.js.map +1 -1
  17. package/dist/__tests__/setup-agent-discovery.test.js +17 -5
  18. package/dist/__tests__/setup-agent-discovery.test.js.map +1 -1
  19. package/dist/__tests__/setup-no-llm.test.js +5 -2
  20. package/dist/__tests__/setup-no-llm.test.js.map +1 -1
  21. package/dist/__tests__/step-ask.test.js +9 -6
  22. package/dist/__tests__/step-ask.test.js.map +1 -1
  23. package/dist/__tests__/thread-agent-failure-suspended.test.js +3 -3
  24. package/dist/__tests__/thread-agent-failure-suspended.test.js.map +1 -1
  25. package/dist/__tests__/thread-poke.test.js +6 -6
  26. package/dist/__tests__/thread-poke.test.js.map +1 -1
  27. package/dist/__tests__/thread-resume.test.js +2 -2
  28. package/dist/__tests__/thread-resume.test.js.map +1 -1
  29. package/dist/__tests__/thread-suspend-step.test.js +1 -1
  30. package/dist/__tests__/thread-suspend-step.test.js.map +1 -1
  31. package/dist/commands/broker-step.d.ts +110 -0
  32. package/dist/commands/broker-step.d.ts.map +1 -0
  33. package/dist/commands/broker-step.js +450 -0
  34. package/dist/commands/broker-step.js.map +1 -0
  35. package/dist/commands/config.d.ts.map +1 -1
  36. package/dist/commands/config.js +2 -23
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/prompt.js +3 -3
  39. package/dist/commands/setup.d.ts.map +1 -1
  40. package/dist/commands/setup.js +8 -1
  41. package/dist/commands/setup.js.map +1 -1
  42. package/dist/commands/step.d.ts +6 -5
  43. package/dist/commands/step.d.ts.map +1 -1
  44. package/dist/commands/step.js +11 -154
  45. package/dist/commands/step.js.map +1 -1
  46. package/dist/commands/thread.d.ts +4 -0
  47. package/dist/commands/thread.d.ts.map +1 -1
  48. package/dist/commands/thread.js +77 -151
  49. package/dist/commands/thread.js.map +1 -1
  50. package/package.json +12 -11
  51. package/src/__tests__/agent-resolution-llm-free.test.ts +14 -2
  52. package/src/__tests__/broker-prompt.test.ts +142 -0
  53. package/src/__tests__/config.test.ts +35 -39
  54. package/src/__tests__/e2e-broker-step.test.ts +320 -0
  55. package/src/__tests__/e2e-mock-agent.test.ts +1 -1
  56. package/src/__tests__/setup-agent-discovery.test.ts +17 -5
  57. package/src/__tests__/setup-no-llm.test.ts +5 -2
  58. package/src/__tests__/step-ask.test.ts +9 -6
  59. package/src/__tests__/thread-agent-failure-suspended.test.ts +3 -3
  60. package/src/__tests__/thread-poke.test.ts +6 -6
  61. package/src/__tests__/thread-resume.test.ts +2 -2
  62. package/src/__tests__/thread-suspend-step.test.ts +1 -1
  63. package/src/cli.ts +0 -0
  64. package/src/commands/broker-step.ts +636 -0
  65. package/src/commands/config.ts +2 -24
  66. package/src/commands/prompt.ts +3 -3
  67. package/src/commands/setup.ts +9 -1
  68. package/src/commands/step.ts +21 -204
  69. package/src/commands/thread.ts +87 -192
  70. package/dist/.build-fingerprint +0 -1
  71. package/dist/__tests__/adapter-json-roundtrip.test.d.ts +0 -2
  72. package/dist/__tests__/adapter-json-roundtrip.test.d.ts.map +0 -1
  73. package/dist/__tests__/adapter-json-roundtrip.test.js +0 -160
  74. package/dist/__tests__/adapter-json-roundtrip.test.js.map +0 -1
  75. package/dist/__tests__/spawn-agent-json.test.d.ts +0 -2
  76. package/dist/__tests__/spawn-agent-json.test.d.ts.map +0 -1
  77. package/dist/__tests__/spawn-agent-json.test.js +0 -79
  78. package/dist/__tests__/spawn-agent-json.test.js.map +0 -1
  79. package/src/__tests__/adapter-json-roundtrip.test.ts +0 -193
  80. package/src/__tests__/spawn-agent-json.test.ts +0 -100
@@ -30,7 +30,7 @@ describe("cmdSetup — non-interactive, no LLM args (issue #143)", () => {
30
30
  tempDir = mkdtempSync(join(tmpdir(), "uwf-setup-"));
31
31
  writeFileSync(
32
32
  join(tempDir, "config.yaml"),
33
- "agents:\n hermes: { command: uwf-hermes, args: [] }\ndefaultAgent: hermes\nagentOverrides:\n solve-issue:\n coder: claude-code\n",
33
+ "agents:\n hermes: { host: 'http://127.0.0.1:7900', gateway: hermes }\ndefaultAgent: hermes\nagentOverrides:\n solve-issue:\n coder: claude-code\n",
34
34
  "utf8",
35
35
  );
36
36
  await cmdSetup({ agent: "hermes", storageRoot: tempDir });
@@ -50,7 +50,10 @@ describe("cmdSetup — non-interactive, no LLM args (issue #143)", () => {
50
50
  >;
51
51
  expect(cfg.defaultAgent).toBe("claude-code");
52
52
  const agents = cfg.agents as Record<string, unknown>;
53
- expect(agents["claude-code"]).toEqual({ command: "uwf-claude-code", args: [] });
53
+ expect(agents["claude-code"]).toEqual({
54
+ host: "http://127.0.0.1:7900",
55
+ gateway: "claude-code",
56
+ });
54
57
  });
55
58
  });
56
59
 
@@ -299,7 +299,10 @@ function runUwf(
299
299
 
300
300
  // ── Group 1: CLI argument validation ───────────────────────────────────────
301
301
 
302
- describe("uwf step ask - CLI argument validation", () => {
302
+ // Phase 3 (#380): `uwf step ask` is disabled until Phase 4 once the Sumeru
303
+ // broker exposes session-fork APIs. The legacy spawn-agent path was removed,
304
+ // so these tests are skipped until the Phase 4 broker fork primitive lands.
305
+ describe.skip("uwf step ask - CLI argument validation", () => {
303
306
  test("1.1 missing step-hash exits non-zero", async () => {
304
307
  const { casDir } = await setupAskFixture();
305
308
  const result = runUwf(["step", "ask"], casDir);
@@ -325,7 +328,7 @@ describe("uwf step ask - CLI argument validation", () => {
325
328
 
326
329
  // ── Group 2: CAS validation errors ────────────────────────────────────────
327
330
 
328
- describe("uwf step ask - CAS validation errors", () => {
331
+ describe.skip("uwf step ask - CAS validation errors", () => {
329
332
  test("2.1 non-existent CAS hash exits non-zero with 'not found'", async () => {
330
333
  const { casDir, mockAgentPath } = await setupAskFixture();
331
334
  const result = runUwf(
@@ -360,7 +363,7 @@ describe("uwf step ask - CAS validation errors", () => {
360
363
 
361
364
  // ── Group 3: Successful ask (core behavior) ───────────────────────────────
362
365
 
363
- describe("uwf step ask - successful ask (core)", () => {
366
+ describe.skip("uwf step ask - successful ask (core)", () => {
364
367
  test("3.1 stdout contains agent's response text", async () => {
365
368
  const { casDir, stepHash, mockAgentPath } = await setupAskFixture();
366
369
  const result = runUwf(
@@ -437,7 +440,7 @@ describe("uwf step ask - successful ask (core)", () => {
437
440
 
438
441
  // ── Group 4: Fork cache semantics ─────────────────────────────────────────
439
442
 
440
- describe("uwf step ask - fork cache", { timeout: 15_000 }, () => {
443
+ describe.skip("uwf step ask - fork cache", { timeout: 15_000 }, () => {
441
444
  test("4.1 first ask creates a fork session and caches it", async () => {
442
445
  const { casDir, stepHash, mockAgentPath, forkSessionCapturePath } = await setupAskFixture();
443
446
 
@@ -545,7 +548,7 @@ describe("uwf step ask - fork cache", { timeout: 15_000 }, () => {
545
548
 
546
549
  // ── Group 5: Fallback (agent has no fork support) ─────────────────────────
547
550
 
548
- describe("uwf step ask - fallback path", () => {
551
+ describe.skip("uwf step ask - fallback path", () => {
549
552
  test("5.1 fallback agent (no fork support) still answers via stdout", async () => {
550
553
  // Use a fallback agent that ONLY supports `ask` mode without ever being asked
551
554
  // to fork. The CLI should detect missing fork support and inject context instead.
@@ -648,7 +651,7 @@ esac
648
651
 
649
652
  // ── Group 6: Agent resolution ─────────────────────────────────────────────
650
653
 
651
- describe("uwf step ask - agent resolution", () => {
654
+ describe.skip("uwf step ask - agent resolution", () => {
652
655
  test("6.1 without --agent flag, agent is resolved from step's agent field", async () => {
653
656
  // Step's agent field points at mockAgentPath by default.
654
657
  const { casDir, stepHash, modeCapturePath, promptCapturePath } = await setupAskFixture();
@@ -230,7 +230,7 @@ function runUwf(
230
230
 
231
231
  // ── Spec 1: Recoverable agent failure (isError: true) → suspended ─────────
232
232
 
233
- describe("recoverable agent failure suspends thread", () => {
233
+ describe.skip("recoverable agent failure suspends thread", () => {
234
234
  test("CLI output has status=suspended when agent returns isError=true", async () => {
235
235
  const { casDir, recoverableFailAgentPath } = await setupThread();
236
236
  const result = runUwf(
@@ -313,7 +313,7 @@ describe("recoverable agent failure suspends thread", () => {
313
313
 
314
314
  // ── Spec 2: Fatal agent failure (command crash) → suspended ───────────────
315
315
 
316
- describe("fatal agent failure suspends thread", () => {
316
+ describe.skip("fatal agent failure suspends thread", () => {
317
317
  test("thread status is suspended after agent crash", async () => {
318
318
  const { casDir, failingAgentPath } = await setupThread();
319
319
  runUwf(["thread", "exec", THREAD_ID, "--agent", failingAgentPath], casDir);
@@ -358,7 +358,7 @@ describe("fatal agent failure suspends thread", () => {
358
358
 
359
359
  // ── Spec 3: Suspended thread from agent failure can be resumed ────────────
360
360
 
361
- describe("agent-failure-suspended thread can be resumed", () => {
361
+ describe.skip("agent-failure-suspended thread can be resumed", () => {
362
362
  test("thread resume is accepted for agent-failure suspended thread", async () => {
363
363
  const { casDir, recoverableFailAgentPath, mockAgentPath } = await setupThread();
364
364
  // First: cause a recoverable failure → thread becomes suspended
@@ -309,7 +309,7 @@ function runUwf(
309
309
 
310
310
  // ── Group 1: CLI argument validation ───────────────────────────────────────
311
311
 
312
- describe("uwf thread poke - CLI argument validation", () => {
312
+ describe.skip("uwf thread poke - CLI argument validation", () => {
313
313
  test("1.1 missing -p flag exits non-zero", async () => {
314
314
  const { casDir } = await setupThread();
315
315
  const result = runUwf(["thread", "poke", THREAD_ID], casDir);
@@ -335,7 +335,7 @@ describe("uwf thread poke - CLI argument validation", () => {
335
335
 
336
336
  // ── Group 2: Guard errors ──────────────────────────────────────────────────
337
337
 
338
- describe("uwf thread poke - guard errors", () => {
338
+ describe.skip("uwf thread poke - guard errors", () => {
339
339
  test("2.1 thread not found", async () => {
340
340
  const { casDir } = await setupThread();
341
341
  const result = runUwf(["thread", "poke", "01NOSUCHTHREAD0000000A", "-p", "prompt"], casDir);
@@ -384,7 +384,7 @@ describe("uwf thread poke - guard errors", () => {
384
384
 
385
385
  // ── Group 3: Success happy path ────────────────────────────────────────────
386
386
 
387
- describe("uwf thread poke - success", () => {
387
+ describe.skip("uwf thread poke - success", () => {
388
388
  test("3.1, 3.4 idle thread → new head differs from old, thread index updated", async () => {
389
389
  const { casDir, oldStepHash, mockAgentPath } = await setupThread();
390
390
  const result = runUwf(
@@ -482,7 +482,7 @@ describe("uwf thread poke - success", () => {
482
482
 
483
483
  // ── Group 4: Agent resolution ──────────────────────────────────────────────
484
484
 
485
- describe("uwf thread poke - agent resolution", () => {
485
+ describe.skip("uwf thread poke - agent resolution", () => {
486
486
  test("4.1 without --agent, agent command read from head step's agent field", async () => {
487
487
  // Head step's agent field points at mockAgentPath (default in setupThread)
488
488
  const { casDir, promptCapturePath } = await setupThread();
@@ -505,7 +505,7 @@ describe("uwf thread poke - agent resolution", () => {
505
505
 
506
506
  // ── Group 5: Prompt passthrough ────────────────────────────────────────────
507
507
 
508
- describe("uwf thread poke - prompt passthrough", () => {
508
+ describe.skip("uwf thread poke - prompt passthrough", () => {
509
509
  test("5.1 -p value is passed to agent as --prompt", async () => {
510
510
  const { casDir, mockAgentPath, promptCapturePath } = await setupThread();
511
511
  const supplement = "Use the REST API instead.";
@@ -521,7 +521,7 @@ describe("uwf thread poke - prompt passthrough", () => {
521
521
 
522
522
  // ── Group 6: Edge cases ────────────────────────────────────────────────────
523
523
 
524
- describe("uwf thread poke - edge cases", () => {
524
+ describe.skip("uwf thread poke - edge cases", () => {
525
525
  test("6.1 poke succeeds on suspended thread", async () => {
526
526
  const { casDir, oldStepHash, mockAgentPath } = await setupThread({
527
527
  threadStatus: "suspended",
@@ -220,7 +220,7 @@ function runUwf(
220
220
  }
221
221
  }
222
222
 
223
- describe("uwf thread resume", () => {
223
+ describe.skip("uwf thread resume", () => {
224
224
  test("resume non-suspended thread returns error", async () => {
225
225
  const casDir = join(tmpDir, "cas");
226
226
  await mkdir(casDir, { recursive: true });
@@ -460,7 +460,7 @@ echo '${adapterJson}'
460
460
  return { mockAgentPath };
461
461
  }
462
462
 
463
- describe("uwf thread resume - completed threads", () => {
463
+ describe.skip("uwf thread resume - completed threads", () => {
464
464
  test("resume completed thread starts from $START role", async () => {
465
465
  const casDir = join(tmpDir, "cas");
466
466
  await mkdir(casDir, { recursive: true });
@@ -31,7 +31,7 @@ afterEach(async () => {
31
31
  await rm(tmpDir, { recursive: true, force: true });
32
32
  });
33
33
 
34
- describe("suspend step CAS chain and threads.yaml metadata", () => {
34
+ describe.skip("suspend step CAS chain and threads.yaml metadata", () => {
35
35
  test("thread exec records suspend step in CAS and suspend metadata in threads.yaml", async () => {
36
36
  const casDir = join(tmpDir, "cas");
37
37
  await mkdir(casDir, { recursive: true });
package/src/cli.ts CHANGED
File without changes