oh-my-copilot 5.8.0 → 5.8.1

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 (98) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +1 -0
  4. package/bridge/__pycache__/gyoshu_bridge.cpython-312.pyc +0 -0
  5. package/bridge/claude-md-coordinator.cjs +2 -2
  6. package/bridge/cli.cjs +120 -13
  7. package/bridge/runtime-cli.cjs +5 -4
  8. package/bridge/team-mcp.cjs +4 -3
  9. package/bridge/team.js +5 -4
  10. package/dist/__tests__/hud/effort.test.d.ts +2 -0
  11. package/dist/__tests__/hud/effort.test.d.ts.map +1 -0
  12. package/dist/__tests__/hud/effort.test.js +24 -0
  13. package/dist/__tests__/hud/effort.test.js.map +1 -0
  14. package/dist/__tests__/hud/transcript-task-tools.test.d.ts +2 -0
  15. package/dist/__tests__/hud/transcript-task-tools.test.d.ts.map +1 -0
  16. package/dist/__tests__/hud/transcript-task-tools.test.js +174 -0
  17. package/dist/__tests__/hud/transcript-task-tools.test.js.map +1 -0
  18. package/dist/__tests__/hud/watch-mode-init.test.js +1 -0
  19. package/dist/__tests__/hud/watch-mode-init.test.js.map +1 -1
  20. package/dist/__tests__/hud-cache-wrapper-4237.test.d.ts +2 -0
  21. package/dist/__tests__/hud-cache-wrapper-4237.test.d.ts.map +1 -0
  22. package/dist/__tests__/hud-cache-wrapper-4237.test.js +232 -0
  23. package/dist/__tests__/hud-cache-wrapper-4237.test.js.map +1 -0
  24. package/dist/__tests__/hud-cache-wrapper.test.js +2 -2
  25. package/dist/__tests__/hud-cache-wrapper.test.js.map +1 -1
  26. package/dist/__tests__/keyword-detector-echo-guard.test.js +27 -0
  27. package/dist/__tests__/keyword-detector-echo-guard.test.js.map +1 -1
  28. package/dist/__tests__/session-end-process-exit.test.js +61 -67
  29. package/dist/__tests__/session-end-process-exit.test.js.map +1 -1
  30. package/dist/cli/__tests__/team.test.js +42 -50
  31. package/dist/cli/__tests__/team.test.js.map +1 -1
  32. package/dist/hooks/autopilot/enforcement.d.ts +1 -0
  33. package/dist/hooks/autopilot/enforcement.d.ts.map +1 -1
  34. package/dist/hooks/autopilot/enforcement.js +6 -1
  35. package/dist/hooks/autopilot/enforcement.js.map +1 -1
  36. package/dist/hooks/persistent-mode/__tests__/ralph-hard-max-script.test.d.ts +7 -0
  37. package/dist/hooks/persistent-mode/__tests__/ralph-hard-max-script.test.d.ts.map +1 -0
  38. package/dist/hooks/persistent-mode/__tests__/ralph-hard-max-script.test.js +138 -0
  39. package/dist/hooks/persistent-mode/__tests__/ralph-hard-max-script.test.js.map +1 -0
  40. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +61 -0
  41. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
  42. package/dist/hooks/session-end/__tests__/wiki-foreground-bootstrap.test.d.ts +9 -0
  43. package/dist/hooks/session-end/__tests__/wiki-foreground-bootstrap.test.d.ts.map +1 -0
  44. package/dist/hooks/session-end/__tests__/wiki-foreground-bootstrap.test.js +87 -0
  45. package/dist/hooks/session-end/__tests__/wiki-foreground-bootstrap.test.js.map +1 -0
  46. package/dist/hooks/session-end/index.d.ts +2 -2
  47. package/dist/hooks/session-end/index.d.ts.map +1 -1
  48. package/dist/hooks/session-end/index.js +2 -2
  49. package/dist/hooks/session-end/index.js.map +1 -1
  50. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts +6 -4
  51. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts.map +1 -1
  52. package/dist/hooks/session-end/wiki-foreground-bootstrap.js +8 -5
  53. package/dist/hooks/session-end/wiki-foreground-bootstrap.js.map +1 -1
  54. package/dist/hud/elements/effort.d.ts +12 -0
  55. package/dist/hud/elements/effort.d.ts.map +1 -0
  56. package/dist/hud/elements/effort.js +30 -0
  57. package/dist/hud/elements/effort.js.map +1 -0
  58. package/dist/hud/elements/index.d.ts +1 -0
  59. package/dist/hud/elements/index.d.ts.map +1 -1
  60. package/dist/hud/elements/index.js +1 -0
  61. package/dist/hud/elements/index.js.map +1 -1
  62. package/dist/hud/index.d.ts.map +1 -1
  63. package/dist/hud/index.js +2 -1
  64. package/dist/hud/index.js.map +1 -1
  65. package/dist/hud/render.d.ts.map +1 -1
  66. package/dist/hud/render.js +6 -0
  67. package/dist/hud/render.js.map +1 -1
  68. package/dist/hud/stdin.d.ts +1 -0
  69. package/dist/hud/stdin.d.ts.map +1 -1
  70. package/dist/hud/stdin.js +3 -0
  71. package/dist/hud/stdin.js.map +1 -1
  72. package/dist/hud/transcript.d.ts.map +1 -1
  73. package/dist/hud/transcript.js +81 -2
  74. package/dist/hud/transcript.js.map +1 -1
  75. package/dist/hud/types.d.ts +7 -0
  76. package/dist/hud/types.d.ts.map +1 -1
  77. package/dist/hud/types.js +7 -1
  78. package/dist/hud/types.js.map +1 -1
  79. package/dist/team/__tests__/tmux-session.create-team.test.js +7 -0
  80. package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -1
  81. package/dist/team/runtime-v2.d.ts +2 -2
  82. package/dist/team/runtime-v2.js +6 -6
  83. package/dist/team/runtime-v2.js.map +1 -1
  84. package/dist/team/tmux-session.d.ts.map +1 -1
  85. package/dist/team/tmux-session.js +4 -3
  86. package/dist/team/tmux-session.js.map +1 -1
  87. package/docs/CLAUDE.md +1 -1
  88. package/docs/MIGRATION.md +20 -0
  89. package/docs/REFERENCE.md +1 -1
  90. package/package.json +2 -2
  91. package/plugin.json +1 -1
  92. package/scripts/keyword-detector.mjs +11 -2
  93. package/scripts/lib/hud-cache-wrapper.sh +46 -1
  94. package/scripts/persistent-mode.cjs +6 -1
  95. package/scripts/persistent-mode.mjs +118 -37
  96. package/scripts/wiki-session-end.mjs +17 -4
  97. package/skills/hud/SKILL.md +2 -0
  98. package/templates/hooks/persistent-mode.mjs +138 -0
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "oh-my-copilot",
11
11
  "description": "Multi-agent orchestration for GitHub Copilot CLI with intelligent model routing across agents and skills. Zero learning curve. Maximum power.",
12
- "version": "5.8.0",
12
+ "version": "5.8.1",
13
13
  "author": {
14
14
  "name": "Robin Norberg"
15
15
  },
@@ -25,5 +25,5 @@
25
25
  ]
26
26
  }
27
27
  ],
28
- "version": "5.8.0"
28
+ "version": "5.8.1"
29
29
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "5.8.0",
3
+ "version": "5.8.1",
4
4
  "description": "Multi-agent orchestration system for GitHub Copilot CLI",
5
5
  "author": {
6
6
  "name": "oh-my-copilot contributors"
package/README.md CHANGED
@@ -28,6 +28,7 @@
28
28
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
29
29
  <br/>This work is based on [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode) by Yeachan Heo, but with a Copilot CLI focus.
30
30
 
31
+ > **v5.8.1** ports upstream oh-my-claudecode `dev` through ef9a44f0e: a cheaper HUD cache wrapper, HUD support for `TaskCreate`/`TaskUpdate` todos and an effort-level element, a pasted-echo autopilot fix, a detached-session format fix, and ralph's `hardMaxIterations` enforced in the Stop hook scripts ([migration note](docs/MIGRATION.md#v580--v581-ralph-hard-max-in-the-stop-hook)).
31
32
  > **v5.8.0** adds an experimental headless team transport (`omg team --transport sdk`), factory chains and faster hooks on Copilot, and a Copilot smoke job in CI ([migration note](docs/MIGRATION.md#v570--v580-sdk-team-transport)).
32
33
  > **v5.7.0** adds `omg smoke copilot` and the `host_smoke` MCP tool, a headless smoke check against the real Copilot CLI ([migration note](docs/MIGRATION.md#v562--v570-smoke-harness)).
33
34
  > **v5.6.1** brings the software factory, headless intake and `omg ralph afk` to Copilot under a scoped AFK permission profile ([upgrade guide](docs/MIGRATION.md#v550--v561-fork-upgrade-guide)).
@@ -875,8 +875,8 @@ function executeClaudeMdTransaction(request) {
875
875
 
876
876
  // src/cli/claude-md-coordinator.ts
877
877
  var CLAUDE_MD_COORDINATOR_SCHEMA_VERSION = 1;
878
- var COMPILED_ENGINE_VERSION = true ? "5.8.0" : "";
879
- var COMPILED_SOURCE_SHA256 = true ? "7d80e15df2a28f9247459896f94423931332241e752a9ac45a020968970266bb" : "";
878
+ var COMPILED_ENGINE_VERSION = true ? "5.8.1" : "";
879
+ var COMPILED_SOURCE_SHA256 = true ? "2e0c81fe8ac2051c47a330c9a7c5c1f640cd969e2e40b3ba38192b6b68f209f3" : "";
880
880
  function runClaudeMdCoordinatorHandshake() {
881
881
  if (!COMPILED_ENGINE_VERSION || !COMPILED_SOURCE_SHA256) {
882
882
  return { exitCode: 2, response: coordinatorError(2, "Coordinator build handshake is unavailable") };
package/bridge/cli.cjs CHANGED
@@ -62307,6 +62307,7 @@ var init_types9 = __esm({
62307
62307
  main: [
62308
62308
  "omcLabel",
62309
62309
  "model",
62310
+ "effort",
62310
62311
  "claudeLabel",
62311
62312
  "enterpriseCost",
62312
62313
  "rateLimits",
@@ -62353,6 +62354,8 @@ var init_types9 = __esm({
62353
62354
  // Show only when Claude Code statusline stdin provides a model
62354
62355
  modelFormat: "versioned",
62355
62356
  // Preserve model version by default
62357
+ effort: true,
62358
+ // Show effort level when Claude Code statusline stdin provides one
62356
62359
  omcLabel: true,
62357
62360
  updateNotification: true,
62358
62361
  // Preserve existing update prompt behavior by default
@@ -62431,6 +62434,7 @@ var init_types9 = __esm({
62431
62434
  gitInfoPosition: "above",
62432
62435
  model: true,
62433
62436
  modelFormat: "versioned",
62437
+ effort: true,
62434
62438
  omcLabel: true,
62435
62439
  updateNotification: true,
62436
62440
  rateLimits: true,
@@ -62477,6 +62481,7 @@ var init_types9 = __esm({
62477
62481
  gitInfoPosition: "above",
62478
62482
  model: true,
62479
62483
  modelFormat: "versioned",
62484
+ effort: true,
62480
62485
  omcLabel: true,
62481
62486
  updateNotification: true,
62482
62487
  rateLimits: true,
@@ -62524,6 +62529,7 @@ var init_types9 = __esm({
62524
62529
  gitInfoPosition: "above",
62525
62530
  model: true,
62526
62531
  modelFormat: "versioned",
62532
+ effort: true,
62527
62533
  omcLabel: true,
62528
62534
  updateNotification: true,
62529
62535
  rateLimits: true,
@@ -62571,6 +62577,7 @@ var init_types9 = __esm({
62571
62577
  gitInfoPosition: "above",
62572
62578
  model: true,
62573
62579
  modelFormat: "versioned",
62580
+ effort: true,
62574
62581
  omcLabel: true,
62575
62582
  updateNotification: true,
62576
62583
  rateLimits: false,
@@ -62617,6 +62624,7 @@ var init_types9 = __esm({
62617
62624
  gitInfoPosition: "above",
62618
62625
  model: true,
62619
62626
  modelFormat: "versioned",
62627
+ effort: true,
62620
62628
  omcLabel: true,
62621
62629
  updateNotification: true,
62622
62630
  rateLimits: true,
@@ -67743,12 +67751,11 @@ function isOrphanedRoutingEchoState(state) {
67743
67751
  const promptText = [
67744
67752
  stateRecord.originalIdea,
67745
67753
  stateRecord.original_idea,
67754
+ stateRecord.original_prompt,
67746
67755
  stateRecord.prompt,
67747
67756
  stateRecord.task_description
67748
67757
  ].filter((value) => typeof value === "string").join("\n").trim();
67749
- return /^\[MAGIC KEYWORDS?(?: DETECTED)?:\s*AUTOPILOT\s*\]\s*$/i.test(
67750
- promptText
67751
- );
67758
+ return /^\[MAGIC KEYWORDS?(?: DETECTED)?:\s*AUTOPILOT\s*\]\s*$/i.test(promptText) || promptText === PASTED_ECHO_PROMPT_SENTINEL;
67752
67759
  }
67753
67760
  function getNextPhase(current) {
67754
67761
  switch (current) {
@@ -68138,7 +68145,7 @@ function detectPipelineSignal(sessionId, signal) {
68138
68145
  }
68139
68146
  return false;
68140
68147
  }
68141
- var import_fs67, import_path78, SIGNAL_PATTERNS, AWAITING_CONFIRMATION_TTL_MS2;
68148
+ var import_fs67, import_path78, SIGNAL_PATTERNS, AWAITING_CONFIRMATION_TTL_MS2, PASTED_ECHO_PROMPT_SENTINEL;
68142
68149
  var init_enforcement = __esm({
68143
68150
  "src/hooks/autopilot/enforcement.ts"() {
68144
68151
  "use strict";
@@ -68165,6 +68172,7 @@ var init_enforcement = __esm({
68165
68172
  TRANSITION_TO_VALIDATION: /TRANSITION_TO_VALIDATION/i
68166
68173
  };
68167
68174
  AWAITING_CONFIRMATION_TTL_MS2 = 2 * 60 * 1e3;
68175
+ PASTED_ECHO_PROMPT_SENTINEL = "(prompt omitted: pasted system echo)";
68168
68176
  }
68169
68177
  });
68170
68178
 
@@ -77533,18 +77541,18 @@ var init_session_hooks = __esm({
77533
77541
  });
77534
77542
 
77535
77543
  // src/hooks/session-end/wiki-foreground-bootstrap.ts
77536
- async function processWikiSessionEnd(input) {
77544
+ async function publishWikiSessionEndBootstrap(input) {
77537
77545
  const directory = resolveToWorktreeRoot(input.cwd);
77538
77546
  const intent = buildWikiSessionEndCaptureIntent({ cwd: directory, session_id: input.session_id });
77539
77547
  sealWikiManifest(directory, input.session_id, intent ? { ...intent } : void 0);
77540
- spawnSessionEndWorker({ directory, sessionId: input.session_id });
77548
+ const { spawnSessionEndWorker: spawnSessionEndWorker2 } = await Promise.resolve().then(() => (init_worker(), worker_exports));
77549
+ spawnSessionEndWorker2({ directory, sessionId: input.session_id });
77541
77550
  return { continue: true };
77542
77551
  }
77543
77552
  var init_wiki_foreground_bootstrap = __esm({
77544
77553
  "src/hooks/session-end/wiki-foreground-bootstrap.ts"() {
77545
77554
  "use strict";
77546
77555
  init_cleanup_manifest();
77547
- init_worker();
77548
77556
  init_session_hooks();
77549
77557
  init_worktree_paths();
77550
77558
  }
@@ -84620,12 +84628,13 @@ async function createTeamSession(teamName, workerCount, cwd2, options = {}) {
84620
84628
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
84621
84629
  });
84622
84630
  const detachedPaneShell = workerPaneShellCommand();
84631
+ const detachedFormat = "#S:#{window_index} #{pane_id} #{socket_path} #{pid}";
84623
84632
  const detachedArgs = [
84624
84633
  "new-session",
84625
84634
  "-d",
84626
84635
  "-P",
84627
84636
  "-F",
84628
- "#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
84637
+ detachedFormat,
84629
84638
  "-s",
84630
84639
  detachedSessionName,
84631
84640
  "-c",
@@ -84661,7 +84670,7 @@ async function createTeamSession(teamName, workerCount, cwd2, options = {}) {
84661
84670
  try {
84662
84671
  detachedResult = await runPaneCreationCommand(
84663
84672
  existingDetachedIdentity,
84664
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
84673
+ tmuxCommandString(detachedArgs, [detachedFormat]),
84665
84674
  detachedPaneShell
84666
84675
  );
84667
84676
  } catch (error2) {
@@ -84724,7 +84733,7 @@ async function createTeamSession(teamName, workerCount, cwd2, options = {}) {
84724
84733
  freshDetachedServerIdentity = tmuxServerIdentity;
84725
84734
  detachedResult = await runPaneCreationCommand(
84726
84735
  tmuxServerIdentity,
84727
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
84736
+ tmuxCommandString(detachedArgs, [detachedFormat]),
84728
84737
  detachedPaneShell
84729
84738
  );
84730
84739
  } catch (error2) {
@@ -96307,7 +96316,7 @@ async function cleanupStaleReservations(teamName, cwd2) {
96307
96316
  if (!(owner && typeof owner === "object" && !Array.isArray(owner) && "pid" in owner && "process_started_at" in owner)) {
96308
96317
  return;
96309
96318
  }
96310
- if (reservation2.phase === "active") return;
96319
+ if (reservation2.phase !== "pending") return;
96311
96320
  const ownerRecord = owner;
96312
96321
  if (isProcessIdentityDead(ownerRecord)) {
96313
96322
  await (0, import_promises26.unlink)(reservationPath2);
@@ -98698,7 +98707,7 @@ __export(session_end_exports, {
98698
98707
  prepareSessionEndWorkerInput: () => prepareSessionEndWorkerInput,
98699
98708
  processSessionEnd: () => processSessionEnd,
98700
98709
  processSessionEndCleanupWorker: () => processSessionEndCleanupWorker,
98701
- processWikiSessionEnd: () => processWikiSessionEnd,
98710
+ processWikiSessionEnd: () => publishWikiSessionEndBootstrap,
98702
98711
  recordSessionMetrics: () => recordSessionMetrics,
98703
98712
  resolveSessionEndCleanupBudgetMs: () => resolveSessionEndCleanupBudgetMs,
98704
98713
  runForegroundSessionEndCleanup: () => runForegroundSessionEndCleanup,
@@ -108638,6 +108647,9 @@ function getModelId(stdin) {
108638
108647
  const modelId = stdin.model?.id?.trim();
108639
108648
  return modelId || null;
108640
108649
  }
108650
+ function getEffortLevel(stdin) {
108651
+ return stdin.effort?.level?.trim() || null;
108652
+ }
108641
108653
  function getModelName(stdin) {
108642
108654
  const displayName = stdin.model?.display_name?.trim();
108643
108655
  return displayName || getModelId(stdin);
@@ -114481,6 +114493,14 @@ var init_agent_kind = __esm({
114481
114493
  });
114482
114494
 
114483
114495
  // src/hud/transcript.ts
114496
+ function getTaskToolState(latestTodos) {
114497
+ let state = taskToolStates.get(latestTodos);
114498
+ if (!state) {
114499
+ state = { pendingCreates: /* @__PURE__ */ new Map(), byId: /* @__PURE__ */ new Map() };
114500
+ taskToolStates.set(latestTodos, state);
114501
+ }
114502
+ return state;
114503
+ }
114484
114504
  async function parseTranscript(transcriptPath, options) {
114485
114505
  pendingPermissionMap.clear();
114486
114506
  const result = {
@@ -114683,6 +114703,16 @@ function readTailLines(filePath, fileSize, maxBytes) {
114683
114703
  }
114684
114704
  return lines;
114685
114705
  }
114706
+ function extractTaskIdFromTaskCreateResult(content) {
114707
+ let text = "";
114708
+ if (typeof content === "string") {
114709
+ text = content;
114710
+ } else if (Array.isArray(content)) {
114711
+ text = content.map((b) => typeof b?.text === "string" ? b.text : "").join("\n");
114712
+ }
114713
+ const match = /Task #([^\s:]+) created/.exec(text);
114714
+ return match ? match[1] : null;
114715
+ }
114686
114716
  function extractBackgroundAgentId(content) {
114687
114717
  const text = typeof content === "string" ? content : content.find((c) => c.type === "text")?.text || "";
114688
114718
  const match = text.match(/agentId:\s*([a-zA-Z0-9]+)/);
@@ -114835,6 +114865,7 @@ function processEntry(entry2, agentMap, latestTodos, result, maxAgentMapSize = 5
114835
114865
  const input = block.input;
114836
114866
  if (input?.todos && Array.isArray(input.todos)) {
114837
114867
  latestTodos.length = 0;
114868
+ taskToolStates.get(latestTodos)?.byId.clear();
114838
114869
  latestTodos.push(
114839
114870
  ...input.todos.map((t) => ({
114840
114871
  content: t.content,
@@ -114843,6 +114874,33 @@ function processEntry(entry2, agentMap, latestTodos, result, maxAgentMapSize = 5
114843
114874
  }))
114844
114875
  );
114845
114876
  }
114877
+ } else if (block.name === "TaskCreate" || block.name === "proxy_TaskCreate") {
114878
+ const input = block.input;
114879
+ if (block.id && typeof input?.subject === "string" && input.subject) {
114880
+ getTaskToolState(latestTodos).pendingCreates.set(block.id, {
114881
+ content: input.subject,
114882
+ status: "pending",
114883
+ ...input.activeForm ? { activeForm: input.activeForm } : {}
114884
+ });
114885
+ }
114886
+ } else if (block.name === "TaskUpdate" || block.name === "proxy_TaskUpdate") {
114887
+ const input = block.input;
114888
+ const taskId = input?.taskId == null ? "" : String(input.taskId);
114889
+ const state = getTaskToolState(latestTodos);
114890
+ const item = taskId ? state.byId.get(taskId) : void 0;
114891
+ if (input && item) {
114892
+ if (input.status === "deleted") {
114893
+ const idx = latestTodos.indexOf(item);
114894
+ if (idx >= 0) latestTodos.splice(idx, 1);
114895
+ state.byId.delete(taskId);
114896
+ } else {
114897
+ if (input.status && TASK_STATUSES.has(input.status)) {
114898
+ item.status = input.status;
114899
+ }
114900
+ if (typeof input.subject === "string" && input.subject) item.content = input.subject;
114901
+ if (typeof input.activeForm === "string" && input.activeForm) item.activeForm = input.activeForm;
114902
+ }
114903
+ }
114846
114904
  } else if (block.name === "Skill" || block.name === "proxy_Skill") {
114847
114905
  result.skillCallCount++;
114848
114906
  const input = block.input;
@@ -114873,6 +114931,19 @@ function processEntry(entry2, agentMap, latestTodos, result, maxAgentMapSize = 5
114873
114931
  trackedTool.status = isError ? "failure" : "success";
114874
114932
  }
114875
114933
  }
114934
+ const taskState = taskToolStates.get(latestTodos);
114935
+ const pendingTask = taskState?.pendingCreates.get(block.tool_use_id);
114936
+ if (taskState && pendingTask) {
114937
+ taskState.pendingCreates.delete(block.tool_use_id);
114938
+ const taskId = block.is_error || !block.content ? null : extractTaskIdFromTaskCreateResult(block.content);
114939
+ if (taskId) {
114940
+ const previous = taskState.byId.get(taskId);
114941
+ const prevIdx = previous ? latestTodos.indexOf(previous) : -1;
114942
+ if (prevIdx >= 0) latestTodos.splice(prevIdx, 1);
114943
+ taskState.byId.set(taskId, pendingTask);
114944
+ latestTodos.push(pendingTask);
114945
+ }
114946
+ }
114876
114947
  const agent = agentMap.get(block.tool_use_id);
114877
114948
  if (agent) {
114878
114949
  const blockContent = block.content;
@@ -114934,7 +115005,7 @@ function extractLastRequestTokenUsage(usage) {
114934
115005
  function getNumericUsageValue(value) {
114935
115006
  return typeof value === "number" && Number.isFinite(value) ? value : null;
114936
115007
  }
114937
- var import_fs151, import_readline5, import_path182, MAX_TAIL_BYTES, MAX_AGENT_MAP_SIZE, MAX_RECENT_TOOLS, RECENT_TOOLS_SKIP, PERMISSION_TOOLS, PERMISSION_THRESHOLD_MS, pendingPermissionMap, THINKING_PART_TYPES2, THINKING_RECENCY_MS, transcriptCache, TRANSCRIPT_CACHE_MAX_SIZE;
115008
+ var import_fs151, import_readline5, import_path182, MAX_TAIL_BYTES, MAX_AGENT_MAP_SIZE, MAX_RECENT_TOOLS, RECENT_TOOLS_SKIP, PERMISSION_TOOLS, PERMISSION_THRESHOLD_MS, pendingPermissionMap, taskToolStates, TASK_STATUSES, THINKING_PART_TYPES2, THINKING_RECENCY_MS, transcriptCache, TRANSCRIPT_CACHE_MAX_SIZE;
114938
115009
  var init_transcript = __esm({
114939
115010
  "src/hud/transcript.ts"() {
114940
115011
  "use strict";
@@ -114970,6 +115041,8 @@ var init_transcript = __esm({
114970
115041
  ];
114971
115042
  PERMISSION_THRESHOLD_MS = 3e3;
114972
115043
  pendingPermissionMap = /* @__PURE__ */ new Map();
115044
+ taskToolStates = /* @__PURE__ */ new WeakMap();
115045
+ TASK_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress", "completed"]);
114973
115046
  THINKING_PART_TYPES2 = ["thinking", "reasoning"];
114974
115047
  THINKING_RECENCY_MS = 3e4;
114975
115048
  transcriptCache = /* @__PURE__ */ new Map();
@@ -115324,6 +115397,9 @@ function red(text) {
115324
115397
  function cyan(text) {
115325
115398
  return `${CYAN}${text}${RESET}`;
115326
115399
  }
115400
+ function magenta(text) {
115401
+ return `${MAGENTA}${text}${RESET}`;
115402
+ }
115327
115403
  function dim(text) {
115328
115404
  return `${DIM}${text}${RESET}`;
115329
115405
  }
@@ -116871,6 +116947,31 @@ var init_model = __esm({
116871
116947
  }
116872
116948
  });
116873
116949
 
116950
+ // src/hud/elements/effort.ts
116951
+ function renderEffort(level) {
116952
+ if (!level) return null;
116953
+ const label = `effort:${level}`;
116954
+ switch (level) {
116955
+ case "low":
116956
+ return dim(label);
116957
+ case "high":
116958
+ return yellow(label);
116959
+ case "xhigh":
116960
+ return magenta(label);
116961
+ case "max":
116962
+ return bold(magenta(label));
116963
+ case "medium":
116964
+ default:
116965
+ return cyan(label);
116966
+ }
116967
+ }
116968
+ var init_effort = __esm({
116969
+ "src/hud/elements/effort.ts"() {
116970
+ "use strict";
116971
+ init_colors();
116972
+ }
116973
+ });
116974
+
116874
116975
  // src/hud/elements/api-key-source.ts
116875
116976
  function settingsFileHasApiKey(filePath) {
116876
116977
  try {
@@ -117224,6 +117325,10 @@ async function render(context, config2) {
117224
117325
  );
117225
117326
  if (modelElement) rendered.set("model", modelElement);
117226
117327
  }
117328
+ if (enabledElements.effort) {
117329
+ const effortElement = renderEffort(context.effortLevel);
117330
+ if (effortElement) rendered.set("effort", effortElement);
117331
+ }
117227
117332
  if (enabledElements.updateNotification !== false && context.claudeCodeUpdateAvailable) {
117228
117333
  const versionTag = context.claudeCodeVersion ? `#${context.claudeCodeVersion}` : "";
117229
117334
  rendered.set(
@@ -117535,6 +117640,7 @@ var init_render = __esm({
117535
117640
  init_git();
117536
117641
  init_multi_repo();
117537
117642
  init_model();
117643
+ init_effort();
117538
117644
  init_api_key_source();
117539
117645
  init_call_counts();
117540
117646
  init_context_warning();
@@ -117999,6 +118105,7 @@ async function mainImpl(watchMode = false, skipInit = false) {
117999
118105
  contextDisplayScope: currentSessionId ?? cwd2,
118000
118106
  modelName: getModelName(stdin),
118001
118107
  modelId: getModelId(stdin),
118108
+ effortLevel: getEffortLevel(stdin),
118002
118109
  ralph,
118003
118110
  ultrawork: null,
118004
118111
  prd,
@@ -11560,12 +11560,13 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11560
11560
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
11561
11561
  });
11562
11562
  const detachedPaneShell = workerPaneShellCommand();
11563
+ const detachedFormat = "#S:#{window_index} #{pane_id} #{socket_path} #{pid}";
11563
11564
  const detachedArgs = [
11564
11565
  "new-session",
11565
11566
  "-d",
11566
11567
  "-P",
11567
11568
  "-F",
11568
- "#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
11569
+ detachedFormat,
11569
11570
  "-s",
11570
11571
  detachedSessionName,
11571
11572
  "-c",
@@ -11601,7 +11602,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11601
11602
  try {
11602
11603
  detachedResult = await runPaneCreationCommand(
11603
11604
  existingDetachedIdentity,
11604
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
11605
+ tmuxCommandString(detachedArgs, [detachedFormat]),
11605
11606
  detachedPaneShell
11606
11607
  );
11607
11608
  } catch (error) {
@@ -11664,7 +11665,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
11664
11665
  freshDetachedServerIdentity = tmuxServerIdentity;
11665
11666
  detachedResult = await runPaneCreationCommand(
11666
11667
  tmuxServerIdentity,
11667
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
11668
+ tmuxCommandString(detachedArgs, [detachedFormat]),
11668
11669
  detachedPaneShell
11669
11670
  );
11670
11671
  } catch (error) {
@@ -22173,7 +22174,7 @@ async function cleanupStaleReservations(teamName, cwd) {
22173
22174
  if (!(owner && typeof owner === "object" && !Array.isArray(owner) && "pid" in owner && "process_started_at" in owner)) {
22174
22175
  return;
22175
22176
  }
22176
- if (reservation.phase === "active") return;
22177
+ if (reservation.phase !== "pending") return;
22177
22178
  const ownerRecord = owner;
22178
22179
  if (isProcessIdentityDead(ownerRecord)) {
22179
22180
  await (0, import_promises19.unlink)(reservationPath2);
@@ -15012,12 +15012,13 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15012
15012
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
15013
15013
  });
15014
15014
  const detachedPaneShell = workerPaneShellCommand();
15015
+ const detachedFormat = "#S:#{window_index} #{pane_id} #{socket_path} #{pid}";
15015
15016
  const detachedArgs = [
15016
15017
  "new-session",
15017
15018
  "-d",
15018
15019
  "-P",
15019
15020
  "-F",
15020
- "#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
15021
+ detachedFormat,
15021
15022
  "-s",
15022
15023
  detachedSessionName,
15023
15024
  "-c",
@@ -15053,7 +15054,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15053
15054
  try {
15054
15055
  detachedResult = await runPaneCreationCommand(
15055
15056
  existingDetachedIdentity,
15056
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
15057
+ tmuxCommandString(detachedArgs, [detachedFormat]),
15057
15058
  detachedPaneShell
15058
15059
  );
15059
15060
  } catch (error2) {
@@ -15116,7 +15117,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
15116
15117
  freshDetachedServerIdentity = tmuxServerIdentity;
15117
15118
  detachedResult = await runPaneCreationCommand(
15118
15119
  tmuxServerIdentity,
15119
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
15120
+ tmuxCommandString(detachedArgs, [detachedFormat]),
15120
15121
  detachedPaneShell
15121
15122
  );
15122
15123
  } catch (error2) {
package/bridge/team.js CHANGED
@@ -13174,12 +13174,13 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
13174
13174
  ...tmuxServerIdentity ? { tmuxServerIdentity: { ...tmuxServerIdentity } } : {}
13175
13175
  });
13176
13176
  const detachedPaneShell = workerPaneShellCommand();
13177
+ const detachedFormat = "#S:#{window_index} #{pane_id} #{socket_path} #{pid}";
13177
13178
  const detachedArgs = [
13178
13179
  "new-session",
13179
13180
  "-d",
13180
13181
  "-P",
13181
13182
  "-F",
13182
- "#S:#{window_index} #{pane_id} #{socket_path} #{pid}",
13183
+ detachedFormat,
13183
13184
  "-s",
13184
13185
  detachedSessionName,
13185
13186
  "-c",
@@ -13215,7 +13216,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
13215
13216
  try {
13216
13217
  detachedResult = await runPaneCreationCommand(
13217
13218
  existingDetachedIdentity,
13218
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
13219
+ tmuxCommandString(detachedArgs, [detachedFormat]),
13219
13220
  detachedPaneShell
13220
13221
  );
13221
13222
  } catch (error) {
@@ -13278,7 +13279,7 @@ async function createTeamSession(teamName, workerCount, cwd, options = {}) {
13278
13279
  freshDetachedServerIdentity = tmuxServerIdentity;
13279
13280
  detachedResult = await runPaneCreationCommand(
13280
13281
  tmuxServerIdentity,
13281
- tmuxCommandString(detachedArgs, ["#S:0 #{pane_id} #{socket_path} #{pid}"]),
13282
+ tmuxCommandString(detachedArgs, [detachedFormat]),
13282
13283
  detachedPaneShell
13283
13284
  );
13284
13285
  } catch (error) {
@@ -23263,7 +23264,7 @@ async function cleanupStaleReservations(teamName, cwd) {
23263
23264
  if (!(owner && typeof owner === "object" && !Array.isArray(owner) && "pid" in owner && "process_started_at" in owner)) {
23264
23265
  return;
23265
23266
  }
23266
- if (reservation.phase === "active") return;
23267
+ if (reservation.phase !== "pending") return;
23267
23268
  const ownerRecord = owner;
23268
23269
  if (isProcessIdentityDead(ownerRecord)) {
23269
23270
  await unlink7(reservationPath2);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=effort.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effort.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/hud/effort.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { bold, cyan, dim, magenta, yellow } from '../../hud/colors.js';
3
+ import { renderEffort } from '../../hud/elements/effort.js';
4
+ import { getEffortLevel } from '../../hud/stdin.js';
5
+ describe('effort element', () => {
6
+ it('reads the effort level from stdin', () => {
7
+ expect(getEffortLevel({ effort: { level: 'xhigh' } })).toBe('xhigh');
8
+ expect(getEffortLevel({ effort: { level: ' ' } })).toBeNull();
9
+ expect(getEffortLevel({})).toBeNull();
10
+ });
11
+ it('returns null when no level is available', () => {
12
+ expect(renderEffort(null)).toBeNull();
13
+ expect(renderEffort(undefined)).toBeNull();
14
+ });
15
+ it('colors the level by intensity', () => {
16
+ expect(renderEffort('low')).toBe(dim('effort:low'));
17
+ expect(renderEffort('medium')).toBe(cyan('effort:medium'));
18
+ expect(renderEffort('high')).toBe(yellow('effort:high'));
19
+ expect(renderEffort('xhigh')).toBe(magenta('effort:xhigh'));
20
+ expect(renderEffort('max')).toBe(bold(magenta('effort:max')));
21
+ expect(renderEffort('future-level')).toBe(cyan('effort:future-level'));
22
+ });
23
+ });
24
+ //# sourceMappingURL=effort.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effort.test.js","sourceRoot":"","sources":["../../../src/__tests__/hud/effort.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/D,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAC3D,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transcript-task-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-task-tools.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/hud/transcript-task-tools.test.ts"],"names":[],"mappings":""}