@gajae-code/coding-agent 0.11.9 → 0.11.11

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 (150) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/dist/types/cli.d.ts +8 -1
  3. package/dist/types/config/model-profile-activation.d.ts +1 -0
  4. package/dist/types/config/model-profile-contract.d.ts +2 -0
  5. package/dist/types/config/model-registry.d.ts +2 -0
  6. package/dist/types/config/settings-schema.d.ts +57 -2
  7. package/dist/types/config/settings.d.ts +1 -0
  8. package/dist/types/extensibility/extensions/types.d.ts +21 -0
  9. package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
  10. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +60 -0
  11. package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
  12. package/dist/types/gjc-runtime/state-writer.d.ts +1 -0
  13. package/dist/types/modes/acp/acp-agent.d.ts +14 -9
  14. package/dist/types/modes/components/queue-pane.d.ts +8 -0
  15. package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
  16. package/dist/types/modes/components/welcome.d.ts +1 -0
  17. package/dist/types/modes/controllers/selector-controller.d.ts +16 -8
  18. package/dist/types/modes/interactive-mode.d.ts +5 -1
  19. package/dist/types/runtime/memory-domain.d.ts +9 -0
  20. package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
  21. package/dist/types/runtime/memory-guard.d.ts +39 -0
  22. package/dist/types/runtime/memory-limit.d.ts +11 -0
  23. package/dist/types/runtime-mcp/manager.d.ts +8 -0
  24. package/dist/types/sdk/acp/final-text.d.ts +19 -0
  25. package/dist/types/sdk/acp/mcp.d.ts +23 -0
  26. package/dist/types/sdk/broker/lifecycle.d.ts +2 -0
  27. package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
  28. package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
  29. package/dist/types/sdk/bus/index.d.ts +11 -2
  30. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
  31. package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
  32. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +14 -7
  33. package/dist/types/sdk/bus/telegram-daemon.d.ts +97 -8
  34. package/dist/types/sdk/host/control/operations.d.ts +1 -0
  35. package/dist/types/sdk/lifecycle-session.d.ts +10 -1
  36. package/dist/types/sdk/session.d.ts +7 -0
  37. package/dist/types/sdk/startup-capability.d.ts +6 -0
  38. package/dist/types/session/agent-session.d.ts +11 -11
  39. package/dist/types/session/fallback-chain-controller.d.ts +18 -2
  40. package/dist/types/session/internal/managed-session-scope.d.ts +28 -1
  41. package/dist/types/session/session-manager.d.ts +34 -0
  42. package/dist/types/task/executor.d.ts +6 -0
  43. package/dist/types/task/provider-retry-status.d.ts +13 -0
  44. package/dist/types/task/types.d.ts +39 -0
  45. package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
  46. package/dist/types/tools/index.d.ts +3 -1
  47. package/dist/types/tools/resource-gc.d.ts +19 -0
  48. package/package.json +8 -8
  49. package/scripts/generate-sdk-operation-inventory.ts +3 -0
  50. package/scripts/run-test-manifest.ts +6 -4
  51. package/src/cli/args.ts +14 -8
  52. package/src/cli/fast-help.ts +1 -1
  53. package/src/cli/notify-cli.ts +1 -0
  54. package/src/cli.ts +48 -2
  55. package/src/commands/sdk.ts +91 -7
  56. package/src/config/model-profile-activation.ts +1 -0
  57. package/src/config/model-profile-contract.ts +13 -0
  58. package/src/config/model-profiles.ts +31 -7
  59. package/src/config/model-registry.ts +4 -2
  60. package/src/config/settings-schema.ts +61 -2
  61. package/src/config/settings.ts +8 -0
  62. package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -2
  63. package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
  64. package/src/eval/js/tool-bridge.ts +1 -1
  65. package/src/extensibility/extensions/runner.ts +4 -0
  66. package/src/extensibility/extensions/types.ts +14 -0
  67. package/src/gjc-runtime/deep-interview-ambiguity.ts +16 -2
  68. package/src/gjc-runtime/deep-interview-draft.ts +2 -1
  69. package/src/gjc-runtime/deep-interview-recorder.ts +16 -1
  70. package/src/gjc-runtime/deep-interview-state.ts +25 -3
  71. package/src/gjc-runtime/linux-proc.ts +70 -36
  72. package/src/gjc-runtime/ralplan-runtime.ts +252 -1
  73. package/src/gjc-runtime/state-runtime.ts +48 -11
  74. package/src/gjc-runtime/state-writer.ts +1 -1
  75. package/src/hooks/skill-state.ts +23 -1
  76. package/src/internal-urls/docs-index.generated.ts +7 -7
  77. package/src/internal-urls/local-protocol.ts +23 -4
  78. package/src/modes/acp/acp-agent.ts +554 -60
  79. package/src/modes/acp/acp-event-mapper.ts +93 -6
  80. package/src/modes/components/model-selector.ts +15 -1
  81. package/src/modes/components/notifications-settings-editor.ts +1 -1
  82. package/src/modes/components/queue-pane.ts +55 -9
  83. package/src/modes/components/queued-message-selector.ts +53 -10
  84. package/src/modes/components/tool-status-header.ts +1 -4
  85. package/src/modes/components/welcome.ts +18 -3
  86. package/src/modes/controllers/command-controller.ts +4 -0
  87. package/src/modes/controllers/extension-ui-controller.ts +4 -10
  88. package/src/modes/controllers/input-controller.ts +44 -3
  89. package/src/modes/controllers/selector-controller.ts +38 -8
  90. package/src/modes/interactive-mode.ts +65 -26
  91. package/src/modes/runtime-init.ts +1 -0
  92. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  93. package/src/prompts/agents/architect.md +8 -1
  94. package/src/prompts/agents/critic.md +8 -1
  95. package/src/prompts/agents/executor.md +1 -1
  96. package/src/prompts/agents/planner.md +8 -1
  97. package/src/runtime/memory-domain.ts +66 -0
  98. package/src/runtime/memory-guard-contract.ts +73 -0
  99. package/src/runtime/memory-guard.ts +292 -0
  100. package/src/runtime/memory-limit.ts +50 -0
  101. package/src/runtime-mcp/manager.ts +26 -6
  102. package/src/sdk/acp/adapter.ts +8 -1
  103. package/src/sdk/acp/final-text.ts +40 -0
  104. package/src/sdk/acp/mcp.ts +26 -0
  105. package/src/sdk/broker/identity.ts +22 -12
  106. package/src/sdk/broker/lifecycle.ts +82 -1
  107. package/src/sdk/bus/chat-daemon-cli.ts +2 -2
  108. package/src/sdk/bus/chat-daemon-control.ts +4 -3
  109. package/src/sdk/bus/config.ts +1 -1
  110. package/src/sdk/bus/daemon-paths.ts +2 -0
  111. package/src/sdk/bus/index.ts +222 -27
  112. package/src/sdk/bus/notification-service.ts +19 -5
  113. package/src/sdk/bus/operator-runtime.ts +31 -5
  114. package/src/sdk/bus/rate-limit-pool.ts +8 -0
  115. package/src/sdk/bus/telegram-cli.ts +6 -13
  116. package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
  117. package/src/sdk/bus/telegram-daemon-contract.ts +15 -7
  118. package/src/sdk/bus/telegram-daemon-control.ts +14 -5
  119. package/src/sdk/bus/telegram-daemon.ts +1191 -164
  120. package/src/sdk/host/control/dispatch.ts +2 -0
  121. package/src/sdk/host/control/operations.ts +1 -0
  122. package/src/sdk/host/host.ts +2 -2
  123. package/src/sdk/lifecycle-session.ts +19 -3
  124. package/src/sdk/protocol/operation-inventory.generated.json +58 -0
  125. package/src/sdk/protocol/operation-registry.ts +1 -0
  126. package/src/sdk/session.ts +24 -1
  127. package/src/sdk/startup-capability.ts +6 -0
  128. package/src/session/agent-session.ts +290 -132
  129. package/src/session/fallback-chain-controller.ts +47 -8
  130. package/src/session/internal/managed-session-scope.ts +173 -127
  131. package/src/session/internal/native-publish-outcome.ts +8 -3
  132. package/src/session/session-manager.ts +608 -25
  133. package/src/skill-state/workflow-mutation-guard.ts +41 -7
  134. package/src/task/executor.ts +152 -42
  135. package/src/task/index.ts +2 -0
  136. package/src/task/provider-retry-status.ts +88 -0
  137. package/src/task/render.ts +45 -26
  138. package/src/task/types.ts +25 -11
  139. package/src/task/ultragoal-redteam-activation.ts +75 -0
  140. package/src/tools/bash-allowed-prefixes.ts +45 -1
  141. package/src/tools/index.ts +3 -1
  142. package/src/tools/resource-gc.ts +496 -120
  143. package/src/tools/subagent-render.ts +74 -16
  144. package/src/tools/subagent.ts +2 -0
  145. package/src/workflow/workflow-intent-diff.ts +4 -1
  146. package/vendor/insane-search/MANIFEST.json +4 -1
  147. package/vendor/insane-search/engine/bias_check.py +5 -0
  148. package/vendor/insane-search/engine/fetch_chain.py +67 -1
  149. package/vendor/insane-search/engine/transport.py +13 -2
  150. package/vendor/insane-search/engine/validators.py +4 -1
@@ -21,7 +21,7 @@ import * as fs from "node:fs";
21
21
  import * as path from "node:path";
22
22
  import { getAgentDir } from "@gajae-code/utils";
23
23
  import { tokenFingerprint } from "./config";
24
- import { type DaemonState, daemonPaths, isFreshLiveOwner } from "./telegram-daemon";
24
+ import { isFreshLiveOwner, readOwnerFreshnessSnapshot } from "./telegram-daemon";
25
25
  import { runTelegramReferenceClient } from "./telegram-reference";
26
26
 
27
27
  interface CliArgs {
@@ -134,17 +134,9 @@ function pidAlive(pid: number): boolean {
134
134
  }
135
135
  }
136
136
 
137
- function readDaemonState(): DaemonState | undefined {
138
- try {
139
- const raw = fs.readFileSync(daemonPaths(getAgentDir()).state, "utf8");
140
- return JSON.parse(raw) as DaemonState;
141
- } catch {
142
- return undefined;
143
- }
144
- }
145
-
146
- function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): boolean {
147
- const state = readDaemonState();
137
+ async function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): Promise<boolean> {
138
+ const snapshot = await readOwnerFreshnessSnapshot({ settings: { getAgentDir } as never });
139
+ const state = snapshot.state;
148
140
  if (!state) return false;
149
141
  return isFreshLiveOwner({
150
142
  state,
@@ -152,6 +144,7 @@ function activeDaemonOwnsToken(input: { botToken: string; chatId: string }): boo
152
144
  tokenFingerprint: tokenFingerprint(input.botToken),
153
145
  chatId: input.chatId,
154
146
  pidAlive,
147
+ effectiveHeartbeatAt: snapshot.effectiveHeartbeatAt,
155
148
  });
156
149
  }
157
150
 
@@ -176,7 +169,7 @@ async function main(): Promise<void> {
176
169
  }
177
170
 
178
171
  const chatId = args.chatId ?? process.env.GJC_TG_CHAT_ID ?? (await resolveChatId(botToken, apiBase));
179
- if (!args.force && activeDaemonOwnsToken({ botToken, chatId })) {
172
+ if (!args.force && (await activeDaemonOwnsToken({ botToken, chatId }))) {
180
173
  process.stderr.write(
181
174
  "an active gjc notifications daemon already owns this bot token; running a second poller will cause Telegram 409 conflicts. Re-run with --force to override.\n",
182
175
  );
@@ -14,6 +14,7 @@ import { daemonPaths, HEARTBEAT_TTL_MS } from "./daemon-paths";
14
14
  import {
15
15
  type DaemonState,
16
16
  readDaemonState,
17
+ readOwnerFreshnessSnapshot,
17
18
  type TelegramDaemonOptions,
18
19
  TelegramNotificationDaemon,
19
20
  } from "./telegram-daemon";
@@ -254,15 +255,19 @@ export async function runDaemonInternal(argv: string[], deps: RunDaemonInternalD
254
255
  if (!watchdogActive || watchdogTickInFlight || stopRequested) return;
255
256
  watchdogTickInFlight = true;
256
257
  try {
257
- const state = await readState(settings as Settings);
258
+ const snapshot = deps.readDaemonState
259
+ ? { state: await readState(settings as Settings), effectiveHeartbeatAt: undefined }
260
+ : await readOwnerFreshnessSnapshot({ settings: settings as Settings });
261
+ const state = snapshot.state;
262
+ const heartbeatAt = snapshot.effectiveHeartbeatAt ?? state?.heartbeatAt;
258
263
  if (!watchdogActive || !state) return;
259
264
  if (state.ownerId !== ownerId) {
260
265
  stopRequested = true;
261
266
  daemon.requestStop("stop");
262
267
  return;
263
268
  }
264
- if (lastHeartbeatAt === undefined || state.heartbeatAt !== lastHeartbeatAt) {
265
- lastHeartbeatAt = state.heartbeatAt;
269
+ if (lastHeartbeatAt === undefined || heartbeatAt !== lastHeartbeatAt) {
270
+ lastHeartbeatAt = heartbeatAt;
266
271
  stalledSince = now();
267
272
  return;
268
273
  }
@@ -7,12 +7,9 @@
7
7
  export const NOTIFICATION_PROTOCOL_VERSION = 3;
8
8
 
9
9
  /**
10
- * Operational generation the current daemon build speaks. Decoupled from
11
- * {@link NOTIFICATION_PROTOCOL_VERSION} (#2304): additive `tool_activity` /
12
- * `reasoning_summary` frames do not bump the wire protocol version, but a
13
- * freshly-upgraded host must still recognize an older, still-live daemon that
14
- * predates capability-gated frame enforcement and trigger a reload. Bump this
15
- * on every daemon-behavior change independent of the wire version.
10
+ * Guarded behavior-inventory version for the current daemon build. Bump this
11
+ * on every guarded daemon-behavior change independent of the wire version; it
12
+ * does not force a live daemon reload by itself.
16
13
  * The current development baseline already includes #2299's generation 4,
17
14
  * incarnation fencing in generation 5, owner-lock authority in generation 6,
18
15
  * identity-atomic transition markers in generation 7, stable signaling plus
@@ -40,5 +37,16 @@ export const NOTIFICATION_PROTOCOL_VERSION = 3;
40
37
  * cooldown and lazy Telegram topic lifecycle safeguards (#2956, #2960, #2984).
41
38
  * Generation 27 refreshes retained native path and process authority semantics.
42
39
  * Generation 28 rejects special files before retained native authority opens.
40
+ * Generation 29 adds serving-epoch compatibility, sidecar heartbeat, root GC,
41
+ * and Bot API cooldown structural fixes (#2956, #2960, #3048).
42
+ * Generation 30 adds opt-in tool activity delivery, closed lifecycle phases,
43
+ * and capability-versioned mixed-host compatibility.
43
44
  */
44
- export const DAEMON_GENERATION = 28;
45
+ export const DAEMON_GENERATION = 30;
46
+
47
+ /**
48
+ * Serving-compatibility boundary for daemon lifecycle requests. Epoch 1 covers
49
+ * all builds published before this field existed; epoch 2 covered generation 29;
50
+ * bump this to force serving convergence and reload of compatible live predecessors.
51
+ */
52
+ export const SERVING_EPOCH = 3;
@@ -40,6 +40,7 @@ import {
40
40
  readAttestedLegacyDaemonOwner,
41
41
  readDaemonRoots,
42
42
  readDaemonState,
43
+ readOwnerFreshnessSnapshot,
43
44
  spawnTelegramDaemonOwner,
44
45
  type TelegramDaemonDeps,
45
46
  type TelegramDaemonFs,
@@ -224,7 +225,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
224
225
  if (!configured) {
225
226
  return { kind: this.kind, configured: false, health: "not_configured", runtime };
226
227
  }
227
- const state = await readDaemonState(this.settings, this.fsImpl);
228
+ const snapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
229
+ const state = snapshot.state;
228
230
  const roots = await readDaemonRoots(this.settings, this.fsImpl);
229
231
  const health: DaemonHealth =
230
232
  !state || state.stoppedAt !== undefined || !this.pidAlive(state.pid)
@@ -236,6 +238,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
236
238
  chatId: cfg.chatId as string,
237
239
  pidAlive: this.pidAlive,
238
240
  pidIncarnation: this.deps.pidIncarnation,
241
+ effectiveHeartbeatAt: snapshot.effectiveHeartbeatAt,
239
242
  })
240
243
  ? "running"
241
244
  : "stale";
@@ -246,7 +249,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
246
249
  pid: state?.pid,
247
250
  ownerId: state?.ownerId,
248
251
  startedAt: state?.startedAt,
249
- heartbeatAt: state?.heartbeatAt,
252
+ heartbeatAt: snapshot.effectiveHeartbeatAt,
250
253
  roots,
251
254
  rootCount: roots.length,
252
255
  runtime,
@@ -480,7 +483,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
480
483
  const gracefulTimeoutMs = opts.gracefulTimeoutMs ?? DEFAULT_GRACEFUL_TIMEOUT_MS;
481
484
  const killTimeoutMs = opts.killTimeoutMs ?? DEFAULT_KILL_TIMEOUT_MS;
482
485
 
483
- const state = await readDaemonState(this.settings, this.fsImpl);
486
+ const ownerSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
487
+ const state = ownerSnapshot.state;
484
488
  const attestedLegacyOwner = attestedLegacyUpgrade
485
489
  ? await readAttestedLegacyDaemonOwner({
486
490
  settings: this.settings,
@@ -501,6 +505,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
501
505
  chatId,
502
506
  pidAlive: this.pidAlive,
503
507
  pidIncarnation: this.deps.pidIncarnation,
508
+ effectiveHeartbeatAt: ownerSnapshot.effectiveHeartbeatAt,
504
509
  }) &&
505
510
  isSignalableMatchingOwner({
506
511
  state,
@@ -628,7 +633,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
628
633
  let dead = await this.waitForPidDeath(oldPid, gracefulTimeoutMs);
629
634
  if (!dead) {
630
635
  // Old pid still alive after the cooperative SIGTERM. Inspect current ownership.
631
- const current = await readDaemonState(this.settings, this.fsImpl);
636
+ const currentSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
637
+ const current = currentSnapshot.state;
632
638
  const changedToLiveOwner =
633
639
  current !== undefined &&
634
640
  current.ownerId !== oldOwnerId &&
@@ -639,6 +645,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
639
645
  chatId,
640
646
  pidAlive: this.pidAlive,
641
647
  pidIncarnation: this.deps.pidIncarnation,
648
+ effectiveHeartbeatAt: currentSnapshot.effectiveHeartbeatAt,
642
649
  });
643
650
  if (changedToLiveOwner) {
644
651
  await this.clearOwnRequest(requestId);
@@ -701,7 +708,8 @@ export class TelegramDaemonController implements BuiltInDaemonController {
701
708
  warnings.push(...spawned.warnings);
702
709
  const after = await this.status();
703
710
  if (spawned.result === "attached") {
704
- const attachedState = await readDaemonState(this.settings, this.fsImpl);
711
+ const attachedSnapshot = await readOwnerFreshnessSnapshot({ settings: this.settings, fs: this.fsImpl });
712
+ const attachedState = attachedSnapshot.state;
705
713
  if (
706
714
  !isCurrentCompatibleOwner({
707
715
  state: attachedState,
@@ -710,6 +718,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
710
718
  chatId,
711
719
  pidAlive: this.pidAlive,
712
720
  pidIncarnation: this.deps.pidIncarnation,
721
+ effectiveHeartbeatAt: attachedSnapshot.effectiveHeartbeatAt,
713
722
  })
714
723
  ) {
715
724
  return this.result(