@gajae-code/coding-agent 0.15.6 → 0.16.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 (167) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/types/cli/args.d.ts +2 -0
  3. package/dist/types/cli/root-flags.d.ts +14 -0
  4. package/dist/types/cli/update-cli.d.ts +13 -0
  5. package/dist/types/cli.d.ts +7 -0
  6. package/dist/types/commands/launch.d.ts +10 -0
  7. package/dist/types/config/autorouting-tier-map.d.ts +24 -0
  8. package/dist/types/config/file-lock.d.ts +5 -0
  9. package/dist/types/config/model-registry.d.ts +6 -0
  10. package/dist/types/config/settings-schema.d.ts +10 -1
  11. package/dist/types/config/settings.d.ts +2 -0
  12. package/dist/types/coordinator-mcp/projection-scan.d.ts +8 -0
  13. package/dist/types/crash/record-loader.d.ts +15 -0
  14. package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
  15. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
  16. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +66 -1
  17. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
  18. package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
  19. package/dist/types/master-mode/context.d.ts +21 -0
  20. package/dist/types/master-mode/first-request.d.ts +34 -0
  21. package/dist/types/master-mode/snapshot.d.ts +32 -0
  22. package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
  23. package/dist/types/modes/components/oauth-selector.d.ts +1 -0
  24. package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
  25. package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
  26. package/dist/types/modes/components/status-line/segments.d.ts +10 -0
  27. package/dist/types/modes/print-mode.d.ts +17 -0
  28. package/dist/types/modes/ui-language.d.ts +7 -1
  29. package/dist/types/sdk/broker/broker.d.ts +77 -1
  30. package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
  31. package/dist/types/sdk/broker/index.d.ts +3 -0
  32. package/dist/types/sdk/broker/lifecycle.d.ts +26 -0
  33. package/dist/types/sdk/broker/master-capability.d.ts +10 -0
  34. package/dist/types/sdk/broker/session-index.d.ts +40 -11
  35. package/dist/types/sdk/broker/session-scope.d.ts +72 -0
  36. package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
  37. package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
  38. package/dist/types/sdk/broker/state-version.d.ts +4 -1
  39. package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
  40. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
  41. package/dist/types/sdk/bus/index.d.ts +6 -0
  42. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  43. package/dist/types/sdk/cli/index.d.ts +1 -0
  44. package/dist/types/sdk/cli/master-cli.d.ts +63 -0
  45. package/dist/types/sdk/cli/rows.d.ts +4 -3
  46. package/dist/types/sdk/cli/session-cli.d.ts +18 -2
  47. package/dist/types/sdk/client/client.d.ts +3 -2
  48. package/dist/types/sdk/host/control/dispatch.d.ts +10 -0
  49. package/dist/types/sdk/host/control/index.d.ts +1 -1
  50. package/dist/types/sdk/host/control/operations.d.ts +2 -0
  51. package/dist/types/sdk/host/control/runtime-gate.d.ts +21 -7
  52. package/dist/types/sdk/host/host.d.ts +10 -0
  53. package/dist/types/sdk/host/session-runtime.d.ts +52 -0
  54. package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
  55. package/dist/types/sdk/lifecycle/service.d.ts +15 -3
  56. package/dist/types/sdk/lifecycle-session.d.ts +2 -0
  57. package/dist/types/sdk/router/session-router.d.ts +2 -0
  58. package/dist/types/sdk/session.d.ts +16 -0
  59. package/dist/types/sdk/startup-capability.d.ts +2 -1
  60. package/dist/types/session/agent-session.d.ts +5 -0
  61. package/dist/types/session/credential-store-errors.d.ts +1 -0
  62. package/dist/types/session/session-manager.d.ts +65 -0
  63. package/dist/types/session/yield-queue.d.ts +5 -4
  64. package/dist/types/setup/frictionless-onboarding.d.ts +1 -0
  65. package/dist/types/tools/bash.d.ts +4 -0
  66. package/dist/types/tools/gh.d.ts +8 -0
  67. package/dist/types/tools/index.d.ts +4 -0
  68. package/package.json +7 -7
  69. package/scripts/generate-sdk-operation-inventory.ts +6 -0
  70. package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
  71. package/src/cli/accounts-cli.ts +9 -5
  72. package/src/cli/args.ts +17 -0
  73. package/src/cli/fast-help.ts +1 -0
  74. package/src/cli/root-flags.ts +5 -0
  75. package/src/cli/update-cli.ts +77 -11
  76. package/src/commands/launch.ts +86 -18
  77. package/src/commands/sdk.ts +113 -21
  78. package/src/config/autorouting-tier-map.ts +12 -0
  79. package/src/config/file-lock.ts +158 -83
  80. package/src/config/model-preset-registry.ts +1 -5
  81. package/src/config/model-profiles.ts +5 -5
  82. package/src/config/model-registry.ts +23 -0
  83. package/src/config/model-resolver.ts +5 -0
  84. package/src/config/settings-schema.ts +8 -1
  85. package/src/config/settings.ts +5 -0
  86. package/src/coordinator-mcp/projection-scan.ts +21 -0
  87. package/src/coordinator-mcp/question-state.ts +9 -11
  88. package/src/coordinator-mcp/server.ts +94 -20
  89. package/src/crash/index-store.ts +2 -0
  90. package/src/crash/record-loader.ts +10 -0
  91. package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
  92. package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
  93. package/src/gjc-runtime/session-state-lock.ts +79 -6
  94. package/src/gjc-runtime/session-state-sidecar.ts +929 -23
  95. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
  96. package/src/gjc-runtime/tmux-owner-isolation.ts +2 -2
  97. package/src/gjc-runtime/tmux-sessions.ts +252 -13
  98. package/src/hooks/skill-state.ts +6 -0
  99. package/src/internal-urls/docs-index.generated.ts +7 -7
  100. package/src/internal-urls/issue-pr-protocol.ts +4 -2
  101. package/src/main.ts +57 -2
  102. package/src/master-mode/context.ts +50 -0
  103. package/src/master-mode/first-request.ts +65 -0
  104. package/src/master-mode/snapshot.ts +205 -0
  105. package/src/modes/acp/acp-agent.ts +605 -156
  106. package/src/modes/components/footer.ts +4 -2
  107. package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
  108. package/src/modes/components/oauth-selector.ts +6 -1
  109. package/src/modes/components/settings-selector.ts +1 -0
  110. package/src/modes/components/status-line/model-name.ts +53 -0
  111. package/src/modes/components/status-line/priority-row.ts +107 -0
  112. package/src/modes/components/status-line/segments.ts +23 -9
  113. package/src/modes/components/tool-status-header.ts +151 -15
  114. package/src/modes/controllers/input-controller.ts +28 -0
  115. package/src/modes/controllers/selector-controller.ts +191 -96
  116. package/src/modes/print-mode.ts +64 -0
  117. package/src/modes/ui-language.ts +49 -2
  118. package/src/prompts/system/master-mode.md +28 -0
  119. package/src/sdk/broker/broker.ts +1636 -26
  120. package/src/sdk/broker/endpoint-authority.ts +86 -0
  121. package/src/sdk/broker/ensure.ts +5 -0
  122. package/src/sdk/broker/index.ts +3 -0
  123. package/src/sdk/broker/lifecycle.ts +186 -41
  124. package/src/sdk/broker/master-capability.ts +232 -0
  125. package/src/sdk/broker/session-index.ts +121 -17
  126. package/src/sdk/broker/session-scope.ts +272 -0
  127. package/src/sdk/broker/spawn-authority.ts +1031 -0
  128. package/src/sdk/broker/spawn-substrate.ts +548 -0
  129. package/src/sdk/broker/state-version.ts +26 -14
  130. package/src/sdk/broker/transport.ts +1 -0
  131. package/src/sdk/broker/worktree-occupancy.ts +90 -0
  132. package/src/sdk/bus/chat-daemon-control.ts +5 -2
  133. package/src/sdk/bus/chat-daemon-runtime.ts +35 -4
  134. package/src/sdk/bus/index.ts +51 -4
  135. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  136. package/src/sdk/cli/index.ts +1 -0
  137. package/src/sdk/cli/master-cli.ts +259 -0
  138. package/src/sdk/cli/rows.ts +11 -8
  139. package/src/sdk/cli/session-cli.ts +264 -5
  140. package/src/sdk/client/client.ts +14 -8
  141. package/src/sdk/host/control/dispatch.ts +99 -38
  142. package/src/sdk/host/control/index.ts +2 -0
  143. package/src/sdk/host/control/operations.ts +2 -0
  144. package/src/sdk/host/control/runtime-gate.ts +203 -11
  145. package/src/sdk/host/host.ts +27 -2
  146. package/src/sdk/host/session-runtime.test.ts +210 -6
  147. package/src/sdk/host/session-runtime.ts +291 -49
  148. package/src/sdk/lifecycle/broker-client.ts +28 -0
  149. package/src/sdk/lifecycle/service.ts +279 -20
  150. package/src/sdk/lifecycle-session.ts +10 -2
  151. package/src/sdk/protocol/operation-inventory.generated.json +51 -0
  152. package/src/sdk/protocol/operation-registry.ts +13 -3
  153. package/src/sdk/router/session-router.ts +67 -59
  154. package/src/sdk/session.ts +357 -155
  155. package/src/sdk/startup-capability.ts +1 -0
  156. package/src/session/agent-session.ts +640 -103
  157. package/src/session/blob-store.ts +15 -5
  158. package/src/session/credential-store-errors.ts +2 -0
  159. package/src/session/internal/managed-session-storage.ts +153 -78
  160. package/src/session/session-manager.ts +337 -24
  161. package/src/session/yield-queue.ts +24 -10
  162. package/src/setup/frictionless-onboarding.ts +2 -0
  163. package/src/telemetry/events.ts +1138 -12
  164. package/src/tools/bash.ts +256 -42
  165. package/src/tools/gh.ts +104 -48
  166. package/src/tools/github-cache.ts +2 -2
  167. package/src/tools/index.ts +4 -0
@@ -39,6 +39,7 @@ const LOCK_ACQUIRE_RETRY_MS = 5;
39
39
  const LOCK_ACQUIRE_MAX_RETRY_MS = 100;
40
40
  const LOCK_ACQUIRE_TIMEOUT_MS = 2_000;
41
41
  const LOCK_STALE_MS = 30_000;
42
+ const RELEASED_TRANSITION_GRACE_MS = 1_000;
42
43
 
43
44
  interface LockRetryBudget {
44
45
  startedAt: number;
@@ -1308,7 +1309,13 @@ async function acquireOwnerLock(
1308
1309
  } catch {
1309
1310
  throw error;
1310
1311
  }
1311
- if (!validLockOwner(observed) || observed.released !== true) throw error;
1312
+ if (!validLockOwner(observed)) throw error;
1313
+ if (observed.released !== true) {
1314
+ if (await lockOwnerIsAlive(observed)) throw error;
1315
+ const removed = exactUnlinkOwnerRecord(file, current, quarantineName);
1316
+ if (removed !== "removed" && removed !== "absent") throw error;
1317
+ return await createOwnerLock(file, owner, quarantineName);
1318
+ }
1312
1319
  try {
1313
1320
  return await rewriteHeldOwnerRecord(file, current, owner);
1314
1321
  } catch (error) {
@@ -1330,7 +1337,10 @@ async function acquireOwnerLock(
1330
1337
  *
1331
1338
  * Stale-owner reclaim still uses the native identity-bound detach protocol because no live
1332
1339
  * owner or transition claim can vouch for that pathname. A mismatch here likewise leaves a
1333
- * successor strictly alone.
1340
+ * successor strictly alone. A released tombstone is reclaimable on every platform when its
1341
+ * owner host is this installation and the transition directory is proven empty and unchanged:
1342
+ * the tombstone is the release marker, while the directory generation binds that marker to
1343
+ * the exact claim that release failed to remove.
1334
1344
  */
1335
1345
  async function releaseOwnerLock(file: string, held: LockOwnerSnapshot): Promise<void> {
1336
1346
  let owner: unknown;
@@ -1549,7 +1559,7 @@ async function releaseTransitionClaim(
1549
1559
  }
1550
1560
 
1551
1561
  async function reclaimStaleTransitionClaim(transitionDir: string, quarantineName: string): Promise<void> {
1552
- const stat = await fs.lstat(transitionDir).catch(() => null);
1562
+ const stat = await fs.lstat(transitionDir, { bigint: true }).catch(() => null);
1553
1563
  if (!stat) return;
1554
1564
  // Regular-file claims belong to the superseded protocol. They retain the old
1555
1565
  // exact-identity stale path; released PID-1 tombstones deliberately require
@@ -1566,9 +1576,72 @@ async function reclaimStaleTransitionClaim(transitionDir: string, quarantineName
1566
1576
  return;
1567
1577
  }
1568
1578
  if (!stat.isDirectory()) throw new SessionStateLockUnavailableError();
1569
- // No portable operation can atomically prove that this directory + sibling
1570
- // sidecar are still the dead claim two concurrent reclaimers inspected. A
1571
- // crashed atomic claim therefore stays fail-closed for explicit recovery.
1579
+ const ownerSnapshot = await captureRegularLockOwner(`${transitionDir}.owner`);
1580
+ if (!ownerSnapshot) return;
1581
+ let owner: unknown;
1582
+ try {
1583
+ owner = JSON.parse(ownerSnapshot.bytes);
1584
+ } catch {
1585
+ return;
1586
+ }
1587
+ if (!validLockOwner(owner)) return;
1588
+ if (owner.released === true) {
1589
+ // A released record is safe only when it is qualified by this installation.
1590
+ // Never let a shared-volume tombstone, an absent identity, or a legacy foreign
1591
+ // identity authorize removal of a claim this process cannot own.
1592
+ if (owner.owner_host_id === undefined) return;
1593
+ const currentHost = await currentOwnerHostId();
1594
+ const legacyHost = await currentLegacyOwnerHostId();
1595
+ if (owner.owner_host_id !== currentHost && owner.owner_host_id !== legacyHost) return;
1596
+ if (Date.now() - Number(ownerSnapshot.mtimeNs / 1_000_000n) < RELEASED_TRANSITION_GRACE_MS) return;
1597
+ } else {
1598
+ if (process.platform !== "win32") return;
1599
+ if (await lockOwnerIsAlive(owner)) return;
1600
+ }
1601
+ const generation = transitionGenerationFromStat(stat);
1602
+ const nativePath = await canonicalOwnedTransitionPath(transitionDir).catch(() => null);
1603
+ if (!nativePath) return;
1604
+ const captured = nativeSessionStateLock().snapshotDirectoryTree(nativePath);
1605
+ if (!captured.ok || !captured.snapshot) return;
1606
+ const root = captured.snapshot.entries.find(entry => entry.relativePath === "");
1607
+ if (
1608
+ !root ||
1609
+ root.kind !== "directory" ||
1610
+ root.dev !== String(generation.dev) ||
1611
+ root.ino !== String(generation.ino) ||
1612
+ root.nlink !== String(generation.nlink) ||
1613
+ root.mtimeNs !== String(generation.mtimeNs) ||
1614
+ root.ctimeNs !== String(generation.ctimeNs)
1615
+ )
1616
+ return;
1617
+ if (captured.snapshot.entries.length !== 1) return;
1618
+ const removed = nativeSessionStateLock().exactRemoveDirectoryTree(nativePath, captured.snapshot);
1619
+ if (removed.ok || removed.code === "not_found") {
1620
+ const ownerRemoval = exactUnlinkOwnerRecord(`${transitionDir}.owner`, ownerSnapshot, quarantineName);
1621
+ if (ownerRemoval !== "removed" && ownerRemoval !== "absent") return;
1622
+ return;
1623
+ }
1624
+ if (
1625
+ removed.code === "cleanup_pending" &&
1626
+ removed.payloadDurable === true &&
1627
+ removed.detachedPath === `${nativePath}.removing` &&
1628
+ removed.retainedSuccessorPath === undefined &&
1629
+ removed.retainedUnknownPath === undefined &&
1630
+ removed.retainedPlaceholderPath === undefined
1631
+ ) {
1632
+ // The captured claim is proven empty, so the native detach receipt leaves an
1633
+ // empty directory at detachedPath. Remove that exact directory directly: calling
1634
+ // the detach primitive again would deterministically create a second `.removing`
1635
+ // collision on POSIX. rmdir never follows a directory's contents and refuses if a
1636
+ // successor populated the detached path.
1637
+ await removeTransitionDir(removed.detachedPath);
1638
+ const ownerRemoval = exactUnlinkOwnerRecord(`${transitionDir}.owner`, ownerSnapshot, quarantineName);
1639
+ if (ownerRemoval !== "removed" && ownerRemoval !== "absent") return;
1640
+ return;
1641
+ }
1642
+ throw new SessionStateLockUnavailableError(
1643
+ new Error(`Stale transition claim could not be reclaimed (${removed.code ?? "unknown"}).`),
1644
+ );
1572
1645
  }
1573
1646
 
1574
1647
  /** Run one pathname transition under an atomic `mkdir`/`rmdir` claim. */