@gajae-code/coding-agent 0.8.1 → 0.8.2

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 (112) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/types/cli/completion-cli.d.ts +41 -0
  3. package/dist/types/cli/config-cli.d.ts +1 -0
  4. package/dist/types/cli/notify-cli.d.ts +7 -0
  5. package/dist/types/cli.d.ts +124 -1
  6. package/dist/types/commands/completion.d.ts +29 -0
  7. package/dist/types/commands/config.d.ts +3 -0
  8. package/dist/types/commands/deep-interview.d.ts +3 -0
  9. package/dist/types/config/file-lock.d.ts +7 -6
  10. package/dist/types/config/keybindings.d.ts +2 -2
  11. package/dist/types/config/model-profile-activation.d.ts +6 -0
  12. package/dist/types/config/settings.d.ts +8 -0
  13. package/dist/types/extensibility/extensions/runner.d.ts +2 -1
  14. package/dist/types/extensibility/extensions/types.d.ts +8 -0
  15. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +39 -0
  16. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +10 -1
  17. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -1
  18. package/dist/types/gjc-runtime/deep-interview-state.d.ts +12 -0
  19. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
  20. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
  21. package/dist/types/main.d.ts +4 -1
  22. package/dist/types/modes/components/model-selector.d.ts +4 -0
  23. package/dist/types/modes/components/queued-message-selector.d.ts +12 -0
  24. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  25. package/dist/types/modes/controllers/input-controller.d.ts +1 -3
  26. package/dist/types/modes/print-mode.d.ts +13 -1
  27. package/dist/types/modes/prompt-action-autocomplete.d.ts +1 -1
  28. package/dist/types/notifications/config.d.ts +8 -1
  29. package/dist/types/notifications/daemon-paths.d.ts +1 -0
  30. package/dist/types/notifications/index.d.ts +6 -3
  31. package/dist/types/notifications/lifecycle-commands.d.ts +11 -3
  32. package/dist/types/notifications/telegram-daemon.d.ts +15 -3
  33. package/dist/types/notifications/telegram-reference.d.ts +0 -5
  34. package/dist/types/runtime-api-key.d.ts +7 -0
  35. package/dist/types/session/agent-session.d.ts +10 -0
  36. package/dist/types/session/agent-storage.d.ts +1 -0
  37. package/dist/types/task/executor.d.ts +2 -0
  38. package/dist/types/tools/computer.d.ts +2 -2
  39. package/dist/types/workflow/workflow-intent-diff.d.ts +8 -2
  40. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +50 -0
  41. package/dist/types/workflow/workflow-intent-report-schema.d.ts +2 -0
  42. package/dist/types/workflow/workflow-intent-report.d.ts +48 -0
  43. package/package.json +7 -7
  44. package/src/cli/completion-cli.ts +234 -0
  45. package/src/cli/config-cli.ts +37 -9
  46. package/src/cli/fast-help.ts +1 -0
  47. package/src/cli/notify-cli.ts +91 -7
  48. package/src/cli.ts +3 -1
  49. package/src/commands/completion.ts +84 -0
  50. package/src/commands/config.ts +2 -0
  51. package/src/commands/deep-interview.ts +2 -1
  52. package/src/config/file-lock.ts +73 -34
  53. package/src/config/keybindings.ts +2 -2
  54. package/src/config/model-profile-activation.ts +65 -0
  55. package/src/config/model-registry.ts +14 -2
  56. package/src/config/settings.ts +22 -0
  57. package/src/coordinator-mcp/server.ts +34 -8
  58. package/src/defaults/gjc/skills/deep-interview/SKILL.md +38 -5
  59. package/src/defaults/gjc/skills/ralplan/SKILL.md +15 -11
  60. package/src/defaults/gjc/skills/team/SKILL.md +1 -1
  61. package/src/extensibility/extensions/runner.ts +2 -0
  62. package/src/extensibility/extensions/types.ts +9 -0
  63. package/src/gjc-runtime/deep-interview-ambiguity.ts +206 -0
  64. package/src/gjc-runtime/deep-interview-recorder.ts +62 -8
  65. package/src/gjc-runtime/deep-interview-runtime.ts +210 -2
  66. package/src/gjc-runtime/deep-interview-state.ts +13 -0
  67. package/src/gjc-runtime/session-state-sidecar.ts +59 -11
  68. package/src/gjc-runtime/state-runtime.ts +12 -2
  69. package/src/gjc-runtime/team-runtime.ts +23 -0
  70. package/src/gjc-runtime/ultragoal-runtime.ts +73 -19
  71. package/src/hooks/native-skill-hook.ts +29 -0
  72. package/src/internal-urls/docs-index.generated.ts +2 -2
  73. package/src/main.ts +52 -41
  74. package/src/modes/components/model-selector.ts +54 -11
  75. package/src/modes/components/queued-message-selector.ts +92 -0
  76. package/src/modes/components/settings-selector.ts +4 -0
  77. package/src/modes/components/welcome.ts +160 -44
  78. package/src/modes/controllers/command-controller.ts +1 -2
  79. package/src/modes/controllers/extension-ui-controller.ts +4 -10
  80. package/src/modes/controllers/input-controller.ts +179 -17
  81. package/src/modes/controllers/selector-controller.ts +122 -27
  82. package/src/modes/interactive-mode.ts +43 -16
  83. package/src/modes/print-mode.ts +43 -4
  84. package/src/modes/prompt-action-autocomplete.ts +21 -20
  85. package/src/modes/utils/hotkeys-markdown.ts +1 -0
  86. package/src/modes/utils/ui-helpers.ts +2 -2
  87. package/src/notifications/config.ts +9 -1
  88. package/src/notifications/daemon-paths.ts +2 -0
  89. package/src/notifications/index.ts +39 -9
  90. package/src/notifications/lifecycle-commands.ts +37 -7
  91. package/src/notifications/lifecycle-orchestrator.ts +19 -6
  92. package/src/notifications/telegram-daemon-control.ts +3 -1
  93. package/src/notifications/telegram-daemon.ts +217 -43
  94. package/src/notifications/telegram-reference.ts +0 -16
  95. package/src/prompts/system/system-prompt.md +3 -0
  96. package/src/prompts/tools/computer.md +2 -2
  97. package/src/runtime-api-key.ts +16 -0
  98. package/src/sdk.ts +20 -6
  99. package/src/session/agent-session.ts +225 -31
  100. package/src/session/agent-storage.ts +4 -0
  101. package/src/session/session-manager.ts +44 -2
  102. package/src/slash-commands/builtin-registry.ts +153 -71
  103. package/src/task/executor.ts +7 -4
  104. package/src/task/index.ts +9 -3
  105. package/src/task/output-manager.ts +16 -6
  106. package/src/task/receipt.ts +26 -7
  107. package/src/tools/computer.ts +246 -43
  108. package/src/tools/telegram-send.ts +6 -0
  109. package/src/workflow/workflow-intent-diff.ts +29 -6
  110. package/src/workflow/workflow-intent-report-consumer.ts +221 -0
  111. package/src/workflow/workflow-intent-report-schema.ts +129 -0
  112. package/src/workflow/workflow-intent-report.ts +135 -0
@@ -15,6 +15,19 @@ import * as os from "node:os";
15
15
  import type { SessionCloseTarget, SessionCreateTarget, SessionLifecycleResponse, SessionResumeTarget } from "./index";
16
16
 
17
17
  export type LifecycleCommandVerb = "session_create" | "session_close" | "session_resume";
18
+ function normalizeLifecycleCommandToken(
19
+ token: string,
20
+ ctx: { chatType?: string; botUsername?: string } = {},
21
+ ): string | undefined {
22
+ const at = token.indexOf("@");
23
+ const command = at === -1 ? token : token.slice(0, at);
24
+ if (!/^\/session_(create|close|resume|recent)\b/.test(command)) return undefined;
25
+ if (at === -1) return ctx.chatType === undefined || ctx.chatType === "private" ? command : undefined;
26
+
27
+ const botUsername = ctx.botUsername;
28
+ if (!botUsername || token.slice(at + 1).toLowerCase() !== botUsername.toLowerCase()) return undefined;
29
+ return command;
30
+ }
18
31
 
19
32
  /** A parsed, validated lifecycle command (transport identity added by caller). */
20
33
  export type ParsedLifecycleCommand =
@@ -36,10 +49,24 @@ const USAGE = [
36
49
  "/session_recent [create|resume]",
37
50
  ].join("\n");
38
51
 
39
- /** True when the text begins a /session_* command (cheap pre-gate). */
40
- export function isLifecycleCommandText(text: string | undefined): boolean {
52
+ /** True when the text begins with any /session_* token, regardless of addressability. */
53
+ export function isLifecycleCommandLikeText(text: string | undefined): boolean {
54
+ if (!text) return false;
55
+ const [token] = text.trim().split(/\s+/, 1);
56
+ if (!token) return false;
57
+ const at = token.indexOf("@");
58
+ const command = at === -1 ? token : token.slice(0, at);
59
+ return /^\/session_(create|close|resume|recent)\b/.test(command);
60
+ }
61
+
62
+ /** True when the text begins an addressable /session_* command (cheap pre-gate). */
63
+ export function isLifecycleCommandText(
64
+ text: string | undefined,
65
+ ctx: { chatType?: string; botUsername?: string } = {},
66
+ ): boolean {
41
67
  if (!text) return false;
42
- return /^\/session_(create|close|resume|recent)\b/.test(text.trim());
68
+ const [rawCommand] = text.trim().split(/\s+/, 1);
69
+ return normalizeLifecycleCommandToken(rawCommand ?? "", ctx) !== undefined;
43
70
  }
44
71
 
45
72
  /**
@@ -50,9 +77,14 @@ export function isLifecycleCommandText(text: string | undefined): boolean {
50
77
  * The caller MUST have already enforced paired-chat authorization; this function
51
78
  * performs grammar + target validation only.
52
79
  */
53
- export function parseLifecycleCommand(text: string | undefined): ParsedLifecycleCommand {
54
- if (!isLifecycleCommandText(text)) return { kind: "none" };
80
+ export function parseLifecycleCommand(
81
+ text: string | undefined,
82
+ ctx: { chatType?: string; botUsername?: string } = {},
83
+ ): ParsedLifecycleCommand {
55
84
  const raw = (text ?? "").trim();
85
+ const [rawCommand, ...args] = raw.split(/\s+/);
86
+ const command = normalizeLifecycleCommandToken(rawCommand ?? "", ctx);
87
+ if (command === undefined) return { kind: "none" };
56
88
 
57
89
  // MVP: reject any initial-prompt separator outright (no prompt handling yet).
58
90
  if (/\s--(\s|$)/.test(raw)) {
@@ -63,8 +95,6 @@ export function parseLifecycleCommand(text: string | undefined): ParsedLifecycle
63
95
  };
64
96
  }
65
97
 
66
- const [command, ...args] = raw.split(/\s+/);
67
-
68
98
  if (command === "/session_recent") {
69
99
  const which = args[0];
70
100
  if (which === undefined || which === "create" || which === "resume") {
@@ -252,7 +252,17 @@ export async function handleLifecycleRequest(
252
252
  return { status: "error", reason: "rate_limited", message: "create rate limit exceeded" };
253
253
  }
254
254
 
255
- // 4. Preallocate ids + write in_progress (fsynced) BEFORE any spawn.
255
+ // 4. Close is intentionally force-only until a graceful close contract exists.
256
+ if (frame.type === "session_close" && frame.force !== true) {
257
+ await deps.audit({ ...baseAudit, event: "rejected", reason: "invalid_target" });
258
+ return {
259
+ status: "error",
260
+ reason: "invalid_target",
261
+ message: "session_close requires force=true; graceful close is not supported",
262
+ };
263
+ }
264
+
265
+ // 5. Preallocate ids + write in_progress (fsynced) BEFORE any spawn.
256
266
  const lifecycleRequestId = frame.type === "session_create" ? frame.lifecycleRequestId : deps.newLifecycleRequestId();
257
267
  const intendedSessionId =
258
268
  frame.type === "session_create" ? frame.intendedSessionId || deps.newSessionId() : deps.newSessionId();
@@ -344,15 +354,18 @@ export async function handleLifecycleRequest(
344
354
  await deps.audit({ ...baseAudit, event: "success", sessionId: resumed.sessionId });
345
355
  return { status: "ok", entry, mode: resumed.mode };
346
356
  } catch (err) {
347
- // A side effect may have occurred; do not auto-respawn. Mark terminal
348
- // uncertain so a retry reconciles instead of duplicating.
357
+ // A side effect may have occurred; do not repeat it automatically. Mark
358
+ // terminal-uncertain so a retry reconciles instead of duplicating work.
359
+ let reason: LifecycleErrorReason = "terminal_uncertain";
360
+ if (frame.type === "session_create") reason = "spawn_failed";
361
+ if (frame.type === "session_close") reason = "close_refused";
349
362
  Object.assign(entry, {
350
363
  state: "terminal_uncertain",
351
364
  updatedAt: deps.now(),
352
- reason: "spawn_failed",
365
+ reason,
353
366
  });
354
367
  await deps.store.write(doc);
355
- await deps.audit({ ...baseAudit, event: "terminal_uncertain", reason: "spawn_failed" });
356
- return { status: "error", reason: "terminal_uncertain", message: `lifecycle effect failed: ${String(err)}` };
368
+ await deps.audit({ ...baseAudit, event: "terminal_uncertain", reason });
369
+ return { status: "error", reason: "terminal_uncertain", message: `${frame.type} effect failed: ${String(err)}` };
357
370
  }
358
371
  }
@@ -269,6 +269,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
269
269
  { settings: this.settings, roots, tokenFingerprint: fp, chatId },
270
270
  this.spawnDeps(),
271
271
  );
272
+ warnings.push(...spawned.warnings);
272
273
  const after = await this.status();
273
274
  return this.result(
274
275
  action,
@@ -351,6 +352,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
351
352
  { settings: this.settings, roots, tokenFingerprint: fp, chatId },
352
353
  this.spawnDeps(),
353
354
  );
355
+ warnings.push(...spawned.warnings);
354
356
  const after = await this.status();
355
357
  if (spawned.result === "attached") {
356
358
  // A live owner already exists; attaching to it is a valid running end-state.
@@ -360,7 +362,7 @@ export class TelegramDaemonController implements BuiltInDaemonController {
360
362
  }
361
363
  return this.result(
362
364
  action,
363
- spawned.result !== "disabled",
365
+ spawned.result !== "disabled" && spawned.result !== "blocked",
364
366
  `reloaded telegram daemon (${spawned.result})`,
365
367
  before,
366
368
  after,