@gajae-code/coding-agent 0.7.8 → 0.7.10

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 (92) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +8 -0
  3. package/dist/types/config/keybindings.d.ts +1 -1
  4. package/dist/types/config/model-profile-activation.d.ts +19 -2
  5. package/dist/types/config/model-profiles.d.ts +1 -0
  6. package/dist/types/config/model-registry.d.ts +4 -0
  7. package/dist/types/config/settings-schema.d.ts +12 -3
  8. package/dist/types/extensibility/extensions/types.d.ts +11 -0
  9. package/dist/types/gjc-runtime/launch-tmux.d.ts +19 -3
  10. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +7 -1
  11. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +0 -4
  12. package/dist/types/modes/components/hook-input.d.ts +1 -0
  13. package/dist/types/modes/components/hook-selector.d.ts +5 -0
  14. package/dist/types/modes/components/model-selector.d.ts +9 -0
  15. package/dist/types/modes/components/status-line.d.ts +3 -0
  16. package/dist/types/modes/controllers/extension-ui-controller.d.ts +3 -1
  17. package/dist/types/modes/interactive-mode.d.ts +3 -1
  18. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +41 -7
  19. package/dist/types/modes/types.d.ts +3 -1
  20. package/dist/types/notifications/daemon-paths.d.ts +9 -0
  21. package/dist/types/notifications/html-format.d.ts +2 -0
  22. package/dist/types/notifications/recent-activity.d.ts +5 -1
  23. package/dist/types/notifications/telegram-daemon-cli.d.ts +8 -2
  24. package/dist/types/notifications/telegram-daemon-control.d.ts +8 -0
  25. package/dist/types/notifications/telegram-daemon.d.ts +1 -10
  26. package/dist/types/notifications/telegram-reference.d.ts +4 -0
  27. package/dist/types/notifications/threaded-render.d.ts +1 -0
  28. package/dist/types/tools/ask.d.ts +26 -0
  29. package/dist/types/tools/ultragoal-ask-guard.d.ts +9 -2
  30. package/dist/types/utils/cmux-workspace.d.ts +23 -0
  31. package/dist/types/web/search/index.d.ts +1 -1
  32. package/dist/types/web/search/provider.d.ts +5 -0
  33. package/dist/types/web/search/render.d.ts +1 -0
  34. package/package.json +7 -7
  35. package/src/cli/notify-cli.ts +1 -1
  36. package/src/cli/web-search-cli.ts +3 -2
  37. package/src/cli.ts +1 -0
  38. package/src/config/keybindings.ts +1 -1
  39. package/src/config/model-profile-activation.ts +92 -11
  40. package/src/config/model-profiles.ts +15 -2
  41. package/src/config/model-registry.ts +81 -5
  42. package/src/config/settings-schema.ts +14 -3
  43. package/src/coordinator-mcp/server.ts +4 -2
  44. package/src/deep-interview/render-middleware.ts +1 -0
  45. package/src/defaults/gjc/skills/deep-interview/SKILL.md +40 -8
  46. package/src/defaults/gjc/skills/ralplan/SKILL.md +14 -7
  47. package/src/defaults/gjc/skills/ultragoal/SKILL.md +37 -112
  48. package/src/extensibility/extensions/types.ts +11 -0
  49. package/src/gjc-runtime/deep-interview-runtime.ts +1 -1
  50. package/src/gjc-runtime/launch-tmux.ts +366 -48
  51. package/src/gjc-runtime/team-runtime.ts +69 -4
  52. package/src/gjc-runtime/ultragoal-guard.ts +150 -24
  53. package/src/gjc-runtime/ultragoal-runtime.ts +16 -124
  54. package/src/gjc-runtime/workflow-manifest.generated.json +0 -8
  55. package/src/gjc-runtime/workflow-manifest.ts +0 -1
  56. package/src/hooks/skill-state.ts +33 -73
  57. package/src/internal-urls/docs-index.generated.ts +8 -7
  58. package/src/modes/components/custom-model-preset-wizard.ts +2 -4
  59. package/src/modes/components/hook-editor.ts +7 -4
  60. package/src/modes/components/hook-input.ts +4 -0
  61. package/src/modes/components/hook-selector.ts +21 -3
  62. package/src/modes/components/model-selector.ts +84 -13
  63. package/src/modes/components/settings-selector.ts +83 -24
  64. package/src/modes/components/status-line/presets.ts +11 -0
  65. package/src/modes/components/status-line/segments.ts +10 -2
  66. package/src/modes/components/status-line.ts +1 -0
  67. package/src/modes/controllers/extension-ui-controller.ts +20 -2
  68. package/src/modes/controllers/selector-controller.ts +130 -7
  69. package/src/modes/interactive-mode.ts +7 -2
  70. package/src/modes/shared/agent-wire/deep-interview-gate.ts +64 -13
  71. package/src/modes/types.ts +6 -1
  72. package/src/notifications/daemon-paths.ts +22 -0
  73. package/src/notifications/html-format.ts +75 -1
  74. package/src/notifications/index.ts +12 -1
  75. package/src/notifications/recent-activity.ts +32 -8
  76. package/src/notifications/telegram-daemon-cli.ts +13 -4
  77. package/src/notifications/telegram-daemon-control.ts +9 -0
  78. package/src/notifications/telegram-daemon.ts +69 -45
  79. package/src/notifications/telegram-reference.ts +36 -14
  80. package/src/notifications/threaded-render.ts +14 -6
  81. package/src/prompts/system/system-prompt.md +10 -1
  82. package/src/sdk.ts +13 -6
  83. package/src/session/agent-session.ts +10 -1
  84. package/src/tools/ask.ts +147 -17
  85. package/src/tools/eval.ts +2 -2
  86. package/src/tools/render-utils.ts +2 -0
  87. package/src/tools/ultragoal-ask-guard.ts +39 -5
  88. package/src/utils/cmux-workspace.ts +106 -0
  89. package/src/utils/title-generator.ts +2 -0
  90. package/src/web/search/index.ts +22 -10
  91. package/src/web/search/provider.ts +15 -0
  92. package/src/web/search/render.ts +3 -0
@@ -11,8 +11,7 @@ import {
11
11
  writeGuardedJsonAtomic,
12
12
  writeGuardedWorkflowEnvelopeAtomic,
13
13
  } from "../gjc-runtime/state-writer";
14
- import { isUltragoalBypassPrompt, readUltragoalVerificationState } from "../gjc-runtime/ultragoal-guard";
15
- import { getUltragoalRunCompletionState, readUltragoalPlan } from "../gjc-runtime/ultragoal-runtime";
14
+ import { isUltragoalBypassPrompt, verifyUltragoalDurableCompletionState } from "../gjc-runtime/ultragoal-guard";
16
15
  import { buildSessionContext, loadEntriesFromFile, type SessionEntry } from "../session/session-manager";
17
16
  import {
18
17
  readVisibleSkillActiveState as readCanonicalVisibleSkillActiveState,
@@ -565,6 +564,10 @@ function modeStateReleasesStop(state: ModeState | null, handoffRequired: boolean
565
564
  return false;
566
565
  }
567
566
 
567
+ function ultragoalDurableCompletionReleasesStop(state: string): boolean {
568
+ return state === "inactive" || state === "active_verified_complete";
569
+ }
570
+
568
571
  /**
569
572
  * Cross-file coherence guard for a mode-state that claims it releases the Stop
570
573
  * block. `modeStateReleasesStop` trusts a single mode-state file; if any writer
@@ -577,18 +580,15 @@ function modeStateReleasesStop(state: ModeState | null, handoffRequired: boolean
577
580
  * cheap and read-only — ultragoal reads the durable plan; skills without an
578
581
  * independent durable source release as before.
579
582
  */
580
- async function detectStaleModeStateRelease(skill: GjcWorkflowSkill, cwd: string): Promise<string | null> {
581
- if (skill === "ultragoal") {
582
- const plan = await readUltragoalPlan(cwd);
583
- if (!plan) return null;
584
- const runState = getUltragoalRunCompletionState(plan);
585
- if (runState.incompleteGoals.length > 0) {
586
- return `the durable Ultragoal plan still has incomplete required goals (${runState.incompleteGoals
587
- .map(goal => goal.id)
588
- .join(", ")}); run \`gjc ultragoal complete-goals\` to continue`;
589
- }
590
- }
591
- return null;
583
+ async function detectStaleModeStateRelease(
584
+ skill: GjcWorkflowSkill,
585
+ cwd: string,
586
+ sessionId?: string | null,
587
+ ): Promise<string | null> {
588
+ if (skill !== "ultragoal") return null;
589
+ const diagnostic = await verifyUltragoalDurableCompletionState({ cwd, sessionId });
590
+ if (ultragoalDurableCompletionReleasesStop(diagnostic.state)) return null;
591
+ return `${diagnostic.message} Run \`gjc ultragoal complete-goals\` to continue, or checkpoint a finished story with \`gjc ultragoal checkpoint --status complete --quality-gate-json <file>\`, before stopping`;
592
592
  }
593
593
 
594
594
  /**
@@ -663,19 +663,6 @@ function stateMatchesContext(state: ModeState, sessionId?: string, threadId?: st
663
663
  return true;
664
664
  }
665
665
 
666
- async function readCurrentGoalObjectiveFromSessionFile(sessionFile: string | undefined): Promise<string | null> {
667
- const trimmed = sessionFile?.trim();
668
- if (!trimmed) return null;
669
- const entries = (await loadEntriesFromFile(trimmed)).filter(
670
- (entry): entry is SessionEntry => entry.type !== "session",
671
- );
672
- const context = buildSessionContext(entries);
673
- const goal = context.modeData?.goal;
674
- if (typeof goal !== "object" || goal === null) return null;
675
- const objective = (goal as { objective?: unknown }).objective;
676
- return typeof objective === "string" && objective.trim().length > 0 ? objective.trim() : null;
677
- }
678
-
679
666
  async function readLatestAssistantTextFromSessionFile(sessionFile: string | undefined): Promise<string | null> {
680
667
  const trimmed = sessionFile?.trim();
681
668
  if (!trimmed) return null;
@@ -730,34 +717,18 @@ export async function buildActiveUltragoalPromptContext(input: UserPromptSubmitS
730
717
  if (!stateMatchesContext(visibleModeState.state, resolvedSessionId, input.threadId)) return null;
731
718
 
732
719
  const phase = String(visibleModeState.state.current_phase ?? "active");
733
- const stateObjective =
734
- typeof visibleModeState.state.objective === "string"
735
- ? visibleModeState.state.objective
736
- : typeof visibleModeState.state.gjcObjective === "string"
737
- ? visibleModeState.state.gjcObjective
738
- : "";
739
- const sessionObjective = await readCurrentGoalObjectiveFromSessionFile(input.sessionFile);
740
720
  const normalizedPrompt = input.prompt?.replace(/\\?"/g, '"');
741
721
  const isBypassPrompt = Boolean(
742
722
  (normalizedPrompt && isUltragoalBypassPrompt(normalizedPrompt)) ||
743
723
  (input.prompt && /goal[\s\S]{0,80}complete/i.test(input.prompt)),
744
724
  );
745
725
  if (isBypassPrompt) {
746
- const objectives = [sessionObjective, stateObjective].filter(
747
- (value): value is string => typeof value === "string" && value.trim().length > 0,
748
- );
749
- if (objectives.length === 0) {
750
- return "BLOCK_ULTRAGOAL_COMPLETION: Active Ultragoal completion is blocked until a current GJC goal objective can be verified. Use durable blocker work or run strict `gjc ultragoal checkpoint --status complete --quality-gate-json <file> --gjc-goal-json <file>` before completion.";
751
- }
752
- for (const objective of objectives) {
753
- const diagnostic = await readUltragoalVerificationState({
754
- cwd: input.cwd,
755
- currentGoal: { objective },
756
- });
757
- if (diagnostic.state === "unrelated_goal") continue;
758
- if (!["inactive", "active_verified_complete"].includes(diagnostic.state)) {
759
- return `BLOCK_ULTRAGOAL_COMPLETION: ${diagnostic.message} Use durable blocker work or run strict \`gjc ultragoal checkpoint --status complete --quality-gate-json <file> --gjc-goal-json <file>\` before completion.`;
760
- }
726
+ const diagnostic = await verifyUltragoalDurableCompletionState({
727
+ cwd: input.cwd,
728
+ sessionId: resolvedSessionId,
729
+ });
730
+ if (!ultragoalDurableCompletionReleasesStop(diagnostic.state)) {
731
+ return `BLOCK_ULTRAGOAL_COMPLETION: ${diagnostic.message} Use durable blocker work or run strict \`gjc ultragoal checkpoint --status complete --quality-gate-json <file>\` before completion.`;
761
732
  }
762
733
  }
763
734
  return `Ultragoal is active (phase: ${phase}; state: ${visibleModeState.statePath}). If the user prompt is a steering request, use \`gjc ultragoal steer\` to add or steer subgoals. Normal prose should not mutate Ultragoal state.`;
@@ -818,7 +789,7 @@ export async function buildSkillStopOutput(input: StopHookInput): Promise<Record
818
789
  // authoritative durable state. If a stale/incoherent mode-state would
819
790
  // release while the plan/ledger still shows pending work, block instead
820
791
  // of trusting the single file (see #659).
821
- const staleRelease = await detectStaleModeStateRelease(entry.skill, input.cwd);
792
+ const staleRelease = await detectStaleModeStateRelease(entry.skill, input.cwd, resolvedSessionId);
822
793
  if (staleRelease) {
823
794
  const coherenceMessage = `GJC skill "${entry.skill}" mode-state reports it released the Stop block (${modeStatePath(input.cwd, entry.skill, resolvedSessionId)}), but ${staleRelease}. The mode-state is incoherent with authoritative durable state; finish or explicitly clear the pending work before stopping.`;
824
795
  return {
@@ -847,29 +818,18 @@ export async function buildSkillStopOutput(input: StopHookInput): Promise<Record
847
818
  const phase = String(modeState?.current_phase ?? entry.phase ?? skillState.phase ?? "active");
848
819
  const statePath = modeStatePath(input.cwd, entry.skill, resolvedSessionId);
849
820
  if (entry.skill === "ultragoal") {
850
- const objective =
851
- (await readCurrentGoalObjectiveFromSessionFile(input.sessionFile)) ??
852
- (typeof modeState?.objective === "string"
853
- ? modeState.objective
854
- : typeof modeState?.gjcObjective === "string"
855
- ? modeState.gjcObjective
856
- : "");
857
- if (objective) {
858
- const diagnostic = await readUltragoalVerificationState({
859
- cwd: input.cwd,
860
- currentGoal: { objective },
861
- });
862
- if (diagnostic.state === "active_verified_complete") continue;
863
- if (!["inactive", "unrelated_goal"].includes(diagnostic.state)) {
864
- const ultragoalMessage = `GJC ultragoal verification is blocking stop: ${diagnostic.message} Run strict checkpoint verification or record review blockers before stopping.`;
865
- return {
866
- decision: "block",
867
- reason: ultragoalMessage,
868
- stopReason: `gjc_ultragoal_verification_${diagnostic.state}`,
869
- systemMessage: ultragoalMessage,
870
- };
871
- }
872
- }
821
+ const diagnostic = await verifyUltragoalDurableCompletionState({
822
+ cwd: input.cwd,
823
+ sessionId: resolvedSessionId,
824
+ });
825
+ if (ultragoalDurableCompletionReleasesStop(diagnostic.state)) continue;
826
+ const ultragoalMessage = `GJC ultragoal verification is blocking stop: ${diagnostic.message} Run \`gjc ultragoal checkpoint --status complete --quality-gate-json <file>\` or record review blockers before stopping.`;
827
+ return {
828
+ decision: "block",
829
+ reason: ultragoalMessage,
830
+ stopReason: `gjc_ultragoal_verification_${diagnostic.state}`,
831
+ systemMessage: ultragoalMessage,
832
+ };
873
833
  }
874
834
  const systemMessage = handoffRequired
875
835
  ? buildHandoffForceAskMessage(entry.skill, phase, statePath)