@gajae-code/coding-agent 0.12.4 → 0.12.6

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 (139) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +4 -1
  3. package/dist/types/async/job-manager.d.ts +9 -1
  4. package/dist/types/eval/backend.d.ts +2 -2
  5. package/dist/types/exec/bash-executor.d.ts +10 -8
  6. package/dist/types/extensibility/extensions/runner.d.ts +9 -7
  7. package/dist/types/gjc-runtime/launch-tmux.d.ts +22 -3
  8. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  9. package/dist/types/gjc-runtime/team-launch.d.ts +3 -1
  10. package/dist/types/gjc-runtime/team-runtime.d.ts +14 -2
  11. package/dist/types/gjc-runtime/team-store.d.ts +0 -4
  12. package/dist/types/gjc-runtime/team-workers.d.ts +5 -0
  13. package/dist/types/gjc-runtime/tmux-common.d.ts +1 -0
  14. package/dist/types/gjc-runtime/tmux-provider-context.d.ts +57 -0
  15. package/dist/types/gjc-runtime/tmux-sessions.d.ts +8 -1
  16. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +3 -0
  17. package/dist/types/gjc-runtime/ultragoal-review-source.d.ts +83 -0
  18. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +57 -4
  19. package/dist/types/internal-urls/registry-helpers.d.ts +18 -0
  20. package/dist/types/modes/components/gjc-bundle-settings.d.ts +1 -0
  21. package/dist/types/modes/components/plugin-settings.d.ts +2 -0
  22. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  23. package/dist/types/sdk/broker/broker.d.ts +18 -0
  24. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +13 -0
  25. package/dist/types/sdk/broker/lifecycle.d.ts +1 -0
  26. package/dist/types/sdk/bus/chat-daemon-control.d.ts +5 -2
  27. package/dist/types/sdk/bus/index.d.ts +4 -0
  28. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -3
  29. package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -3
  30. package/dist/types/sdk/bus/topic-registry.d.ts +63 -3
  31. package/dist/types/sdk/host/host.d.ts +23 -2
  32. package/dist/types/sdk/host/reverse-leases.d.ts +7 -4
  33. package/dist/types/session/agent-session.d.ts +5 -4
  34. package/dist/types/session/artifacts.d.ts +8 -5
  35. package/dist/types/session/attempt-record-store.d.ts +19 -0
  36. package/dist/types/session/client-bridge.d.ts +14 -0
  37. package/dist/types/session/internal/managed-session-storage.d.ts +7 -23
  38. package/dist/types/session/messages.d.ts +4 -1
  39. package/dist/types/session/session-manager.d.ts +7 -5
  40. package/dist/types/session/session-storage.d.ts +8 -0
  41. package/dist/types/session/streaming-output.d.ts +32 -0
  42. package/dist/types/task/executor.d.ts +1 -1
  43. package/dist/types/task/index.d.ts +2 -1
  44. package/dist/types/task/receipt.d.ts +3 -0
  45. package/dist/types/task/types.d.ts +194 -0
  46. package/dist/types/task/worktree.d.ts +13 -6
  47. package/dist/types/tools/bash.d.ts +1 -1
  48. package/dist/types/tools/fetch.d.ts +3 -0
  49. package/dist/types/tools/output-meta.d.ts +37 -5
  50. package/dist/types/tools/subagent.d.ts +2 -0
  51. package/dist/types/tools/tool-result.d.ts +1 -0
  52. package/dist/types/utils/artifact-id.d.ts +2 -0
  53. package/dist/types/utils/git.d.ts +1 -0
  54. package/package.json +8 -8
  55. package/scripts/capture-sticky-viewport-showcase.ts +131 -5
  56. package/scripts/verify-gjc-sdk-canonicalization.ts +128 -183
  57. package/scripts/verify-sticky-viewport-showcase.ts +620 -93
  58. package/src/async/job-manager.ts +13 -5
  59. package/src/config/model-profiles.ts +8 -0
  60. package/src/config/settings-schema.ts +17 -3
  61. package/src/cursor.ts +20 -13
  62. package/src/defaults/gjc/skills/ultragoal/SKILL.md +5 -2
  63. package/src/eval/backend.ts +2 -2
  64. package/src/exec/bash-executor.ts +425 -151
  65. package/src/extensibility/extensions/runner.ts +80 -6
  66. package/src/extensibility/extensions/wrapper.ts +22 -15
  67. package/src/extensibility/runtime-skill-discovery.ts +4 -6
  68. package/src/gjc-runtime/launch-tmux.ts +309 -293
  69. package/src/gjc-runtime/managed-owner-supervisor.ts +6 -2
  70. package/src/gjc-runtime/psmux-detect.ts +52 -6
  71. package/src/gjc-runtime/team-launch.ts +50 -2
  72. package/src/gjc-runtime/team-runtime.ts +716 -251
  73. package/src/gjc-runtime/team-store.ts +25 -7
  74. package/src/gjc-runtime/team-workers.ts +161 -1
  75. package/src/gjc-runtime/tmux-common.ts +16 -4
  76. package/src/gjc-runtime/tmux-gc.ts +37 -5
  77. package/src/gjc-runtime/tmux-owner-isolation.ts +2 -0
  78. package/src/gjc-runtime/tmux-provider-context.ts +451 -0
  79. package/src/gjc-runtime/tmux-sessions.ts +409 -156
  80. package/src/gjc-runtime/ultragoal-change-set.ts +90 -44
  81. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +7 -0
  82. package/src/gjc-runtime/ultragoal-review-source.ts +378 -0
  83. package/src/gjc-runtime/ultragoal-runtime.ts +640 -159
  84. package/src/gjc-runtime/workflow-manifest.generated.json +40 -1
  85. package/src/gjc-runtime/workflow-manifest.ts +12 -0
  86. package/src/internal-urls/agent-protocol.ts +98 -38
  87. package/src/internal-urls/artifact-protocol.ts +28 -17
  88. package/src/internal-urls/docs-index.generated.ts +6 -6
  89. package/src/internal-urls/local-protocol.ts +39 -18
  90. package/src/internal-urls/registry-helpers.ts +62 -0
  91. package/src/modes/acp/acp-agent.ts +51 -13
  92. package/src/modes/acp/acp-client-bridge.ts +154 -11
  93. package/src/modes/components/gjc-bundle-settings.ts +2 -0
  94. package/src/modes/components/plugin-settings.ts +5 -0
  95. package/src/modes/components/settings-selector.ts +4 -0
  96. package/src/modes/controllers/selector-controller.ts +1 -0
  97. package/src/prompts/tools/bash.md +2 -2
  98. package/src/prompts/tools/monitor.md +4 -4
  99. package/src/sdk/acp/adapter.ts +200 -9
  100. package/src/sdk/broker/broker.ts +93 -10
  101. package/src/sdk/broker/lifecycle-ledger.ts +227 -11
  102. package/src/sdk/broker/lifecycle.ts +692 -98
  103. package/src/sdk/bus/chat-daemon-control.ts +33 -5
  104. package/src/sdk/bus/index.ts +347 -14
  105. package/src/sdk/bus/telegram-daemon-contract.ts +7 -3
  106. package/src/sdk/bus/telegram-daemon.ts +283 -44
  107. package/src/sdk/bus/topic-registry.ts +133 -10
  108. package/src/sdk/host/host.ts +187 -9
  109. package/src/sdk/host/reverse-leases.ts +249 -42
  110. package/src/sdk/session.ts +8 -6
  111. package/src/session/agent-session.ts +930 -354
  112. package/src/session/artifacts.ts +211 -74
  113. package/src/session/attempt-record-store.ts +106 -0
  114. package/src/session/client-bridge.ts +15 -0
  115. package/src/session/internal/managed-session-scope.ts +332 -198
  116. package/src/session/internal/managed-session-storage.ts +162 -450
  117. package/src/session/messages.ts +32 -7
  118. package/src/session/session-manager.ts +31 -28
  119. package/src/session/session-storage.ts +190 -53
  120. package/src/session/streaming-output.ts +198 -40
  121. package/src/task/executor.ts +5 -2
  122. package/src/task/index.ts +277 -64
  123. package/src/task/provider-retry-status.ts +4 -1
  124. package/src/task/receipt.ts +26 -2
  125. package/src/task/render.ts +42 -1
  126. package/src/task/types.ts +52 -0
  127. package/src/task/worktree.ts +122 -43
  128. package/src/tools/bash.ts +818 -239
  129. package/src/tools/eval.ts +99 -4
  130. package/src/tools/fetch.ts +77 -15
  131. package/src/tools/find.ts +7 -3
  132. package/src/tools/monitor.ts +7 -1
  133. package/src/tools/output-meta.ts +706 -116
  134. package/src/tools/search.ts +9 -4
  135. package/src/tools/subagent-render.ts +5 -2
  136. package/src/tools/subagent.ts +8 -0
  137. package/src/tools/tool-result.ts +1 -0
  138. package/src/utils/artifact-id.ts +6 -0
  139. package/src/utils/git.ts +2 -0
@@ -1421,13 +1421,6 @@ function braceBlockRange(contents: string, openingBrace: number): ShellRange | u
1421
1421
  return undefined;
1422
1422
  }
1423
1423
 
1424
- function scopeMatches<T extends RegExpMatchArray>(matches: T[], range: ShellRange): T[] {
1425
- return matches.filter(match => {
1426
- const index = match.index ?? -1;
1427
- return index >= range.start && index < range.end;
1428
- });
1429
- }
1430
-
1431
1424
  function findFunctionRange(contents: string, headerPattern: RegExp): ShellRange | undefined {
1432
1425
  const header = headerPattern.exec(contents);
1433
1426
  if (!header) return undefined;
@@ -1504,121 +1497,62 @@ function exactMemoryGuardSendKeysRanges(contents: string): ShellRange[] {
1504
1497
  ];
1505
1498
  }
1506
1499
  function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
1507
- // Scope the loop-dispatch counts to `startTmuxSession` so the second
1508
- // sanctioned call site (`relaunchWorkerPaneForMemoryGuard`, matched by
1509
- // `exactMemoryGuardSendKeysRanges`) does not read as a duplicate. Fixtures
1510
- // that carry the canonical shape without the enclosing function keep the
1511
- // original whole-file scope, so exact-match strictness is unchanged.
1512
- const mainFnRange = findFunctionRange(
1500
+ const executor =
1501
+ /function\s+executeTeamTmuxMutation\s*\([\s\S]*?\)\s*:\s*Bun\.SyncSubprocess<"pipe",\s*"pipe">\s*\{/.exec(
1502
+ contents,
1503
+ );
1504
+ const continuation = /async\s+function\s+continueStalledGjcTeamWorkers\s*\([^)]*\)\s*:\s*Promise<void>\s*\{/.exec(
1513
1505
  contents,
1514
- /async\s+function\s+startTmuxSession\s*\([\s\S]{0,600}?\)\s*:\s*Promise<GjcTeamWorker\[\]>\s*\{/,
1515
- ) ?? { start: 0, end: contents.length };
1516
- const guardMatches = scopeMatches([...contents.matchAll(/if\s*\(\s*useSendKeysFallback\s*\)\s*\{/g)], mainFnRange);
1517
- const payloadMatches = scopeMatches(
1518
- [
1519
- ...contents.matchAll(
1520
- /Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*workerCommand\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
1521
- ),
1522
- ],
1523
- mainFnRange,
1524
- );
1525
- const continuationPromptMatches = [
1526
- ...contents.matchAll(
1527
- /(?:const\s+GJC_TEAM_CONTINUATION_PROMPT\s*=\s*["']Continue only your current claimed GJC team task\. Re-read current GJC team state; do not replay prior output; report status\.["']\s*;|import\s*\{[\s\S]{0,1000}?\bGJC_TEAM_CONTINUATION_PROMPT\b[\s\S]{0,1000}?\}\s*from\s*["']\.\/team-workers["']\s*;)/g,
1528
- ),
1529
- ];
1530
- const continuationMatches = [
1531
- ...contents.matchAll(
1532
- /const\s+args\s*=\s*Object\.freeze\(\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*GJC_TEAM_CONTINUATION_PROMPT\s*,\s*["'];["']\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*["']Enter["']\s*,?\s*\]\s*\)\s*;\s*const\s+dispatch\s*=\s*gjcTeamRuntimeTestSeams\?\.continuationTmuxDispatch\s*\?\s*gjcTeamRuntimeTestSeams\.continuationTmuxDispatch\(config\.tmux_command\s*,\s*args\)\s*:\s*Bun\.spawnSync\(\[config\.tmux_command\s*,\s*\.\.\.args\]\s*,\s*\{\s*stdout\s*:\s*["']ignore["']\s*,\s*stderr\s*:\s*["']ignore["']\s*,\s*timeout\s*:\s*GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS\s*,?\s*\}\s*\)\s*;/g,
1533
- ),
1534
- ];
1535
- const enterMatches = scopeMatches(
1536
- [
1537
- ...contents.matchAll(
1538
- /const\s+sendKeys\s*=\s*Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*["']Enter["']\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
1539
- ),
1540
- ],
1541
- mainFnRange,
1542
- );
1543
- const fallbackPredicateMatches = [
1544
- ...contents.matchAll(
1545
- /function\s+shouldDispatchWorkerWithSendKeys\([^)]*\)\s*:\s*boolean\s*\{\s*return\s+platform\s*===\s*["']win32["']\s*\|\|\s*path\.basename\(tmuxCommand\)\.toLowerCase\(\)\s*===\s*["']psmux["']\s*;\s*\}/g,
1546
- ),
1547
- ];
1548
- const useFallbackMatches = scopeMatches(
1549
- [
1550
- ...contents.matchAll(
1551
- /const\s+useSendKeysFallback\s*=\s*shouldDispatchWorkerWithSendKeys\(config\.tmux_command\)\s*;/g,
1552
- ),
1553
- ],
1554
- mainFnRange,
1555
- );
1556
- const splitWorkerCommandMatches = scopeMatches(
1557
- [...contents.matchAll(/\.\.\.\(useSendKeysFallback\s*\?\s*\[\]\s*:\s*\[workerCommand\]\)\s*,/g)],
1558
- mainFnRange,
1559
1506
  );
1507
+ if (!executor || !continuation) return [];
1508
+
1509
+ const executorRange = braceBlockRange(contents, (executor.index ?? 0) + executor[0].lastIndexOf("{"));
1510
+ const continuationRange = braceBlockRange(contents, (continuation.index ?? 0) + continuation[0].lastIndexOf("{"));
1511
+ if (!executorRange || !continuationRange) return [];
1512
+
1513
+ const executorBody = contents.slice(executorRange.start, executorRange.end);
1514
+ const literalSend =
1515
+ /\?\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*operation\.paneId\s*,\s*operation\.text\s*\]/.exec(
1516
+ executorBody,
1517
+ );
1518
+ const keySend =
1519
+ /operation\.type\s*===\s*["']key-send["']\s*\?\s*\[\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*operation\.paneId\s*,\s*operation\.key\s*\]/.exec(
1520
+ executorBody,
1521
+ );
1522
+ const authorityChecks = executorBody.match(/assertGjcTmuxMutationAuthoritySync\(authority\)/g) ?? [];
1560
1523
  if (
1561
- guardMatches.length !== 1 ||
1562
- payloadMatches.length !== 1 ||
1563
- enterMatches.length !== 1 ||
1564
- continuationPromptMatches.length !== 1 ||
1565
- continuationMatches.length !== 1 ||
1566
- fallbackPredicateMatches.length !== 1 ||
1567
- useFallbackMatches.length !== 1 ||
1568
- splitWorkerCommandMatches.length !== 1
1524
+ !literalSend ||
1525
+ !keySend ||
1526
+ !executorBody.includes("const authority = teamProviderAuthority(config);") ||
1527
+ !executorBody.includes("assertTeamTmuxMutationPreproof(config, operation);") ||
1528
+ authorityChecks.length < 2 ||
1529
+ !executorBody.includes("Bun.spawnSync(")
1569
1530
  )
1570
1531
  return [];
1571
- const guardStart = guardMatches[0].index ?? 0;
1572
- const payloadStart = payloadMatches[0].index ?? 0;
1573
- const enterStart = enterMatches[0].index ?? 0;
1574
- const voidStart = contents.indexOf("void sendKeys.exitCode;", enterStart);
1532
+
1533
+ const continuationBody = contents.slice(continuationRange.start, continuationRange.end);
1534
+ const continuationArgs =
1535
+ /const\s+args\s*=\s*Object\.freeze\(\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*continuationPrompt\s*,\s*["'];["']\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*["']Enter["']\s*,?\s*\]\s*\)\s*;/.exec(
1536
+ continuationBody,
1537
+ );
1575
1538
  if (
1576
- (useFallbackMatches[0].index ?? 0) >= (splitWorkerCommandMatches[0].index ?? 0) ||
1577
- (splitWorkerCommandMatches[0].index ?? 0) >= guardStart ||
1578
- payloadStart >= enterStart ||
1579
- voidStart < enterStart
1580
- )
1581
- return [];
1582
- const guard = guardMatches[0];
1583
- const openingBrace = (guard.index ?? 0) + guard[0].lastIndexOf("{");
1584
- const range = braceBlockRange(contents, openingBrace);
1585
- const continuationFunction =
1586
- /async\s+function\s+continueStalledGjcTeamWorkers\s*\([^)]*\)\s*:\s*Promise<void>\s*\{/.exec(contents);
1587
- const monitorFence = /await\s+withGjcTeamTaskMutation\([\s\S]{0,500}?async\s+capability\s*=>\s*\{/.exec(contents);
1588
- if (!range || !continuationFunction || !monitorFence) return [];
1589
- const continuationOpeningBrace = (continuationFunction.index ?? 0) + continuationFunction[0].lastIndexOf("{");
1590
- const continuationRange = braceBlockRange(contents, continuationOpeningBrace);
1591
- const monitorOpeningBrace = (monitorFence.index ?? 0) + monitorFence[0].lastIndexOf("{");
1592
- const monitorRange = braceBlockRange(contents, monitorOpeningBrace);
1593
- if (!continuationRange || !monitorRange) return [];
1594
- const monitorBody = contents.slice(monitorRange.start, monitorRange.end);
1595
- const continuationCall = /await\s+continueStalledGjcTeamWorkers\s*\(/.exec(monitorBody);
1596
- const reconciliationCall = /await\s+reconcileGjcTeamStaleClaimsUnlocked\s*\(/.exec(monitorBody);
1597
- const continuationStart = continuationMatches[0].index ?? 0;
1598
- const finalValidationStart = contents.lastIndexOf("const revalidationReason =", continuationStart);
1599
- const skippedBranch = finalValidationStart === -1 ? "" : contents.slice(finalValidationStart, continuationStart);
1600
- if (
1601
- payloadStart < range.start ||
1602
- payloadStart >= range.end ||
1603
- enterStart < range.start ||
1604
- enterStart >= range.end ||
1605
- contents.indexOf("void sendKeys.exitCode;", enterStart) >= range.end ||
1606
- continuationStart < continuationRange.start ||
1607
- continuationStart >= continuationRange.end ||
1608
- finalValidationStart < continuationRange.start ||
1609
- !continuationCall ||
1610
- !reconciliationCall ||
1611
- (continuationCall.index ?? 0) >= (reconciliationCall.index ?? 0) ||
1612
- !/if\s*\(\s*revalidationReason\s*\)[\s\S]*?return\s*;/.test(skippedBranch)
1539
+ !continuationArgs ||
1540
+ !continuationBody.includes("const revalidationReason =") ||
1541
+ !continuationBody.includes("await createJsonNoClobber(") ||
1542
+ !continuationBody.includes('type: "literal-send"') ||
1543
+ !continuationBody.includes('type: "key-send"') ||
1544
+ !continuationBody.includes('deferredProof: "continuation-outcome"') ||
1545
+ /args\s*\.\s*(?:push|unshift|splice)\s*\(/.test(continuationBody)
1613
1546
  )
1614
1547
  return [];
1548
+
1549
+ const literalStart = executorRange.start + (literalSend.index ?? 0);
1550
+ const keyStart = executorRange.start + (keySend.index ?? 0);
1551
+ const argsStart = continuationRange.start + (continuationArgs.index ?? 0);
1615
1552
  return [
1616
- { start: payloadStart, end: payloadStart + payloadMatches[0][0].length },
1617
- { start: enterStart, end: enterStart + enterMatches[0][0].length },
1618
- {
1619
- start: continuationMatches[0].index ?? 0,
1620
- end: (continuationMatches[0].index ?? 0) + continuationMatches[0][0].length,
1621
- },
1553
+ { start: literalStart, end: literalStart + literalSend[0].length },
1554
+ { start: keyStart, end: keyStart + keySend[0].length },
1555
+ { start: argsStart, end: argsStart + continuationArgs[0].length },
1622
1556
  ];
1623
1557
  }
1624
1558
 
@@ -3219,47 +3153,68 @@ fi
3219
3153
  "tmux send-keys content injection is outside sanctioned process lifecycle",
3220
3154
  );
3221
3155
  const canonicalTeamRuntimeSendKeysFixture = `
3222
- async function continueStalledGjcTeamWorkers(): Promise<void> {
3223
- const revalidationReason = null;
3224
- if (revalidationReason) return;
3225
- function shouldDispatchWorkerWithSendKeys(tmuxCommand: string, platform: NodeJS.Platform = process.platform): boolean {
3226
- return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";
3227
- }
3228
- const useSendKeysFallback = shouldDispatchWorkerWithSendKeys(config.tmux_command);
3229
- const splitArgs = [...(useSendKeysFallback ? [] : [workerCommand]),];
3230
- if (useSendKeysFallback) {
3231
- Bun.spawnSync([config.tmux_command, "send-keys", "-l", "-t", paneId, workerCommand], {
3232
- stdout: "ignore",
3233
- stderr: "ignore",
3234
- });
3235
- const sendKeys = Bun.spawnSync([config.tmux_command, "send-keys", "-t", paneId, "Enter"], {
3236
- stdout: "ignore",
3237
- stderr: "ignore",
3238
- });
3239
- void sendKeys.exitCode;
3156
+ type TeamTmuxMutation =
3157
+ | { type: "literal-send"; paneId: string; text: string; deferredProof: "continuation-outcome" }
3158
+ | { type: "key-send"; paneId: string; key: string; deferredProof: "continuation-outcome" };
3159
+ function executeTeamTmuxMutation(
3160
+ config: GjcTeamConfig,
3161
+ operation: TeamTmuxMutation,
3162
+ ): Bun.SyncSubprocess<"pipe", "pipe"> {
3163
+ const authority = teamProviderAuthority(config);
3164
+ assertTeamTmuxMutationPreproof(config, operation);
3165
+ const args =
3166
+ operation.type === "literal-send"
3167
+ ? ["send-keys", "-l", "-t", operation.paneId, operation.text]
3168
+ : operation.type === "key-send"
3169
+ ? ["send-keys", "-t", operation.paneId, operation.key]
3170
+ : [];
3171
+ assertGjcTmuxMutationAuthoritySync(authority);
3172
+ const result = Bun.spawnSync(args);
3173
+ assertGjcTmuxMutationAuthoritySync(authority);
3174
+ return result;
3240
3175
  }
3241
- const GJC_TEAM_CONTINUATION_PROMPT = "Continue only your current claimed GJC team task. Re-read current GJC team state; do not replay prior output; report status.";
3242
- const GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS = 5_000;
3243
- const args = Object.freeze([
3244
- "send-keys",
3245
- "-l",
3246
- "-t",
3247
- worker.pane_id,
3248
- GJC_TEAM_CONTINUATION_PROMPT,
3249
- ";",
3250
- "send-keys",
3251
- "-t",
3252
- worker.pane_id,
3253
- "Enter",
3254
- ]);
3255
-
3256
- const dispatch = gjcTeamRuntimeTestSeams?.continuationTmuxDispatch
3257
- ? gjcTeamRuntimeTestSeams.continuationTmuxDispatch(config.tmux_command, args)
3258
- : Bun.spawnSync([config.tmux_command, ...args], {
3259
- stdout: "ignore",
3260
- stderr: "ignore",
3261
- timeout: GJC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS,
3262
- });
3176
+ async function continueStalledGjcTeamWorkers(): Promise<void> {
3177
+ const reservationPath = "reservation";
3178
+ const reservation = {};
3179
+ await createJsonNoClobber(
3180
+ reservationPath,
3181
+ reservation,
3182
+ stateWriterOptions(reservationPath, "state", "continuation-reservation"),
3183
+ );
3184
+ const continuationPrompt = "Continue only your current claimed GJC team task. Re-read current GJC team state; do not replay prior output; report status.";
3185
+ const revalidationReason = await validateGjcContinuationEligibility(dir, config, worker);
3186
+ if (revalidationReason) {
3187
+ return;
3188
+ }
3189
+ const args = Object.freeze([
3190
+ "send-keys",
3191
+ "-l",
3192
+ "-t",
3193
+ worker.pane_id,
3194
+ continuationPrompt,
3195
+ ";",
3196
+ "send-keys",
3197
+ "-t",
3198
+ worker.pane_id,
3199
+ "Enter",
3200
+ ]);
3201
+ const dispatch = gjcTeamRuntimeTestSeams?.continuationTmuxDispatch
3202
+ ? gjcTeamRuntimeTestSeams.continuationTmuxDispatch(config.tmux_command, args)
3203
+ : (() => {
3204
+ executeTeamTmuxMutation(config, {
3205
+ type: "literal-send",
3206
+ paneId: worker.pane_id!,
3207
+ text: continuationPrompt,
3208
+ deferredProof: "continuation-outcome",
3209
+ });
3210
+ return executeTeamTmuxMutation(config, {
3211
+ type: "key-send",
3212
+ paneId: worker.pane_id!,
3213
+ key: "Enter",
3214
+ deferredProof: "continuation-outcome",
3215
+ });
3216
+ })();
3217
+ void dispatch;
3263
3218
  }
3264
3219
  async function monitorGjcTeam(): Promise<void> {
3265
3220
  await withGjcTeamTaskMutation(taskStore(dir), async capability => {
@@ -3275,18 +3230,8 @@ async function monitorGjcTeam(): Promise<void> {
3275
3230
  await runSelfTestFixture(
3276
3231
  {
3277
3232
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3278
- "async function continueStalledGjcTeamWorkers(): Promise<void>",
3279
- "async function relocatedContinuation(): Promise<void>",
3280
- ),
3281
- },
3282
- 1,
3283
- "tmux send-keys content injection is outside sanctioned process lifecycle",
3284
- );
3285
- await runSelfTestFixture(
3286
- {
3287
- "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3288
- "if (revalidationReason) return;",
3289
- "if (revalidationReason) {}",
3233
+ "\tassertTeamTmuxMutationPreproof(config, operation);\n",
3234
+ "",
3290
3235
  ),
3291
3236
  },
3292
3237
  1,
@@ -3295,8 +3240,8 @@ async function monitorGjcTeam(): Promise<void> {
3295
3240
  await runSelfTestFixture(
3296
3241
  {
3297
3242
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3298
- "await continueStalledGjcTeamWorkers();",
3299
- "",
3243
+ "\tassertGjcTmuxMutationAuthoritySync(authority);\n\treturn result;",
3244
+ "\treturn result;",
3300
3245
  ),
3301
3246
  },
3302
3247
  1,
@@ -3305,8 +3250,8 @@ async function monitorGjcTeam(): Promise<void> {
3305
3250
  await runSelfTestFixture(
3306
3251
  {
3307
3252
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3308
- "await continueStalledGjcTeamWorkers();\n\t\tawait reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);",
3309
- "await reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);\n\t\tawait continueStalledGjcTeamWorkers();",
3253
+ "async function continueStalledGjcTeamWorkers(): Promise<void>",
3254
+ "async function relocatedContinuation(): Promise<void>",
3310
3255
  ),
3311
3256
  },
3312
3257
  1,
@@ -3315,8 +3260,8 @@ async function monitorGjcTeam(): Promise<void> {
3315
3260
  await runSelfTestFixture(
3316
3261
  {
3317
3262
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3318
- "const dispatch =",
3319
- 'args.push("forged");\nconst dispatch =',
3263
+ "if (revalidationReason) {\n\t\treturn;\n\t}",
3264
+ "if (revalidationReason) {}",
3320
3265
  ),
3321
3266
  },
3322
3267
  1,
@@ -3325,8 +3270,8 @@ async function monitorGjcTeam(): Promise<void> {
3325
3270
  await runSelfTestFixture(
3326
3271
  {
3327
3272
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3328
- "report status.",
3329
- "report injected status.",
3273
+ "await continueStalledGjcTeamWorkers();",
3274
+ "",
3330
3275
  ),
3331
3276
  },
3332
3277
  1,
@@ -3335,8 +3280,8 @@ async function monitorGjcTeam(): Promise<void> {
3335
3280
  await runSelfTestFixture(
3336
3281
  {
3337
3282
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3338
- 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";',
3339
- "return true;",
3283
+ "await continueStalledGjcTeamWorkers();\n\t\tawait reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);",
3284
+ "await reconcileGjcTeamStaleClaimsUnlocked(workerOrchestrationRuntime, teamName, dir, config, env, capability);\n\t\tawait continueStalledGjcTeamWorkers();",
3340
3285
  ),
3341
3286
  },
3342
3287
  1,
@@ -3345,8 +3290,8 @@ async function monitorGjcTeam(): Promise<void> {
3345
3290
  await runSelfTestFixture(
3346
3291
  {
3347
3292
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3348
- 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux";',
3349
- 'return platform === "win32" || path.basename(tmuxCommand).toLowerCase() === "psmux" || tmuxCommand === "tmux";',
3293
+ "const dispatch =",
3294
+ 'args.push("forged");\nconst dispatch =',
3350
3295
  ),
3351
3296
  },
3352
3297
  1,
@@ -3372,8 +3317,8 @@ async function monitorGjcTeam(): Promise<void> {
3372
3317
  await runSelfTestFixture(
3373
3318
  {
3374
3319
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3375
- 'GJC_TEAM_CONTINUATION_PROMPT,\n\t";",',
3376
- "`$" + "{GJC_TEAM_CONTINUATION_PROMPT}" + '`,\n\t";",',
3320
+ 'continuationPrompt,\n\t\t";",',
3321
+ "`$" + "{continuationPrompt}" + '`,\n\t\t";",',
3377
3322
  ),
3378
3323
  },
3379
3324
  1,
@@ -3382,8 +3327,8 @@ async function monitorGjcTeam(): Promise<void> {
3382
3327
  await runSelfTestFixture(
3383
3328
  {
3384
3329
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3385
- '"send-keys",\n\t"-l",\n\t"-t",\n\tworker.pane_id,\n\tGJC_TEAM_CONTINUATION_PROMPT,\n\t";",\n\t"send-keys",\n\t"-t",\n\tworker.pane_id,\n\t"Enter",',
3386
- '"send-keys", "-t", worker.pane_id, "Enter", ";", "send-keys", "-l", "-t", worker.pane_id, GJC_TEAM_CONTINUATION_PROMPT,',
3330
+ '"send-keys",\n\t\t"-l",\n\t\t"-t",\n\t\tworker.pane_id,\n\t\tcontinuationPrompt,\n\t\t";",\n\t\t"send-keys",\n\t\t"-t",\n\t\tworker.pane_id,\n\t\t"Enter",',
3331
+ '"send-keys", "-t", worker.pane_id, "Enter", ";", "send-keys", "-l", "-t", worker.pane_id, continuationPrompt,',
3387
3332
  ),
3388
3333
  },
3389
3334
  1,
@@ -3392,8 +3337,8 @@ async function monitorGjcTeam(): Promise<void> {
3392
3337
  await runSelfTestFixture(
3393
3338
  {
3394
3339
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts": canonicalTeamRuntimeSendKeysFixture.replace(
3395
- "Bun.spawnSync([config.tmux_command, ...args]",
3396
- 'Bun.spawnSync([config.tmux_command, "run-shell", ...args]',
3340
+ ": (() => {",
3341
+ ": Bun.spawnSync([config.tmux_command, ...args])",
3397
3342
  ),
3398
3343
  },
3399
3344
  1,