@gajae-code/coding-agent 0.2.0 → 0.2.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 (114) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/dist/types/cli/skills-cli.d.ts +9 -0
  3. package/dist/types/commands/contribution-prep.d.ts +18 -0
  4. package/dist/types/commands/session.d.ts +24 -0
  5. package/dist/types/commands/skills.d.ts +26 -0
  6. package/dist/types/config/model-registry.d.ts +33 -4
  7. package/dist/types/config/models-config-schema.d.ts +52 -5
  8. package/dist/types/config/settings-schema.d.ts +1 -24
  9. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +15 -0
  10. package/dist/types/gjc-runtime/goal-mode-request.d.ts +1 -1
  11. package/dist/types/gjc-runtime/launch-tmux.d.ts +12 -11
  12. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +25 -0
  13. package/dist/types/gjc-runtime/state-runtime.d.ts +13 -0
  14. package/dist/types/gjc-runtime/team-runtime.d.ts +37 -5
  15. package/dist/types/gjc-runtime/tmux-common.d.ts +41 -0
  16. package/dist/types/gjc-runtime/tmux-sessions.d.ts +17 -0
  17. package/dist/types/goals/runtime.d.ts +3 -9
  18. package/dist/types/goals/state.d.ts +3 -6
  19. package/dist/types/goals/tools/goal-tool.d.ts +1 -69
  20. package/dist/types/modes/components/model-selector.d.ts +21 -1
  21. package/dist/types/modes/components/status-line/types.d.ts +0 -3
  22. package/dist/types/modes/components/status-line.d.ts +0 -3
  23. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  24. package/dist/types/modes/interactive-mode.d.ts +1 -12
  25. package/dist/types/modes/theme/defaults/index.d.ts +0 -2
  26. package/dist/types/modes/theme/theme.d.ts +1 -2
  27. package/dist/types/modes/types.d.ts +1 -7
  28. package/dist/types/session/agent-session.d.ts +2 -0
  29. package/dist/types/session/contribution-prep.d.ts +47 -0
  30. package/dist/types/skill-state/active-state.d.ts +4 -0
  31. package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +6 -1
  32. package/dist/types/skill-state/workflow-hud.d.ts +9 -4
  33. package/dist/types/skill-state/workflow-state-contract.d.ts +34 -0
  34. package/dist/types/slash-commands/builtin-registry.d.ts +1 -0
  35. package/package.json +7 -7
  36. package/src/cli/args.ts +17 -2
  37. package/src/cli/skills-cli.ts +88 -0
  38. package/src/cli.ts +7 -1
  39. package/src/commands/contribution-prep.ts +41 -0
  40. package/src/commands/deep-interview.ts +6 -22
  41. package/src/commands/launch.ts +10 -1
  42. package/src/commands/ralplan.ts +10 -22
  43. package/src/commands/session.ts +150 -0
  44. package/src/commands/skills.ts +48 -0
  45. package/src/commands/state.ts +14 -4
  46. package/src/commands/team.ts +23 -3
  47. package/src/commit/agentic/index.ts +1 -0
  48. package/src/commit/pipeline.ts +1 -0
  49. package/src/config/model-registry.ts +269 -10
  50. package/src/config/models-config-schema.ts +124 -88
  51. package/src/config/settings-schema.ts +1 -25
  52. package/src/config.ts +1 -1
  53. package/src/defaults/gjc/skills/deep-interview/SKILL.md +14 -13
  54. package/src/defaults/gjc/skills/ralplan/SKILL.md +14 -2
  55. package/src/defaults/gjc/skills/team/SKILL.md +29 -7
  56. package/src/defaults/gjc/skills/ultragoal/SKILL.md +23 -25
  57. package/src/eval/py/prelude.py +1 -1
  58. package/src/gjc-runtime/deep-interview-runtime.ts +279 -0
  59. package/src/gjc-runtime/goal-mode-request.ts +2 -19
  60. package/src/gjc-runtime/launch-tmux.ts +83 -43
  61. package/src/gjc-runtime/ralplan-runtime.ts +460 -0
  62. package/src/gjc-runtime/state-runtime.ts +562 -0
  63. package/src/gjc-runtime/team-runtime.ts +708 -52
  64. package/src/gjc-runtime/tmux-common.ts +119 -0
  65. package/src/gjc-runtime/tmux-sessions.ts +165 -0
  66. package/src/gjc-runtime/ultragoal-guard.ts +6 -3
  67. package/src/gjc-runtime/ultragoal-runtime.ts +5 -4
  68. package/src/goals/runtime.ts +38 -144
  69. package/src/goals/state.ts +36 -7
  70. package/src/goals/tools/goal-tool.ts +15 -172
  71. package/src/hooks/skill-state.ts +31 -12
  72. package/src/internal-urls/docs-index.generated.ts +4 -3
  73. package/src/main.ts +10 -1
  74. package/src/modes/components/model-selector.ts +109 -28
  75. package/src/modes/components/skill-hud/render.ts +4 -0
  76. package/src/modes/components/status-line/segments.ts +5 -16
  77. package/src/modes/components/status-line/types.ts +0 -3
  78. package/src/modes/components/status-line.ts +0 -6
  79. package/src/modes/controllers/command-controller.ts +25 -1
  80. package/src/modes/controllers/input-controller.ts +0 -15
  81. package/src/modes/controllers/selector-controller.ts +42 -2
  82. package/src/modes/interactive-mode.ts +18 -219
  83. package/src/modes/theme/defaults/dark-poimandres.json +0 -1
  84. package/src/modes/theme/defaults/light-poimandres.json +0 -1
  85. package/src/modes/theme/theme.ts +0 -6
  86. package/src/modes/types.ts +1 -7
  87. package/src/prompts/goals/goal-continuation.md +1 -4
  88. package/src/prompts/goals/goal-mode-active.md +3 -5
  89. package/src/prompts/system/system-prompt.md +5 -7
  90. package/src/prompts/tools/goal.md +4 -4
  91. package/src/sdk.ts +2 -1
  92. package/src/session/agent-session.ts +18 -0
  93. package/src/session/contribution-prep.ts +320 -0
  94. package/src/setup/provider-onboarding.ts +2 -0
  95. package/src/skill-state/active-state.ts +38 -0
  96. package/src/skill-state/deep-interview-mutation-guard.ts +88 -24
  97. package/src/skill-state/workflow-hud.ts +23 -5
  98. package/src/skill-state/workflow-state-contract.ts +121 -0
  99. package/src/slash-commands/acp-builtins.ts +11 -2
  100. package/src/slash-commands/builtin-registry.ts +40 -13
  101. package/src/task/commands.ts +1 -5
  102. package/src/tools/gh.ts +212 -2
  103. package/src/tools/index.ts +2 -5
  104. package/dist/types/commands/gjc-runtime-bridge.d.ts +0 -30
  105. package/dist/types/commands/question.d.ts +0 -7
  106. package/dist/types/modes/loop-limit.d.ts +0 -22
  107. package/src/commands/gjc-runtime-bridge.ts +0 -227
  108. package/src/commands/question.ts +0 -12
  109. package/src/modes/loop-limit.ts +0 -140
  110. package/src/prompts/commands/orchestrate.md +0 -49
  111. package/src/prompts/goals/goal-budget-limit.md +0 -16
  112. package/src/prompts/tools/create-goal.md +0 -3
  113. package/src/prompts/tools/get-goal.md +0 -3
  114. package/src/prompts/tools/update-goal.md +0 -3
@@ -0,0 +1,17 @@
1
+ export interface GjcTmuxSessionStatus {
2
+ name: string;
3
+ attached: boolean;
4
+ windows: number;
5
+ panes: number;
6
+ bindings: string;
7
+ createdAt: string;
8
+ branch?: string;
9
+ branchSlug?: string;
10
+ project?: string;
11
+ }
12
+ export declare function listGjcTmuxSessions(env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus[];
13
+ export declare function findGjcTmuxSessionByBranch(branch: string, env?: NodeJS.ProcessEnv, project?: string | null): GjcTmuxSessionStatus | undefined;
14
+ export declare function statusGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus;
15
+ export declare function createGjcTmuxSession(env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus;
16
+ export declare function removeGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): GjcTmuxSessionStatus;
17
+ export declare function attachGjcTmuxSession(sessionName: string, env?: NodeJS.ProcessEnv): never;
@@ -1,4 +1,4 @@
1
- import type { Goal, GoalBudgetSteering, GoalModeState, GoalRuntimeEvent, GoalTokenUsage } from "./state";
1
+ import { type Goal, type GoalModeState, type GoalRuntimeEvent, type GoalTokenUsage } from "./state";
2
2
  export interface GoalRuntimeHost {
3
3
  getState(): GoalModeState | undefined;
4
4
  setState(state: GoalModeState | undefined): void;
@@ -24,16 +24,13 @@ export interface GoalWallClockSnapshot {
24
24
  export interface GoalRuntimeSnapshot {
25
25
  turnSnapshot?: GoalTurnSnapshot;
26
26
  wallClock: GoalWallClockSnapshot;
27
- budgetReportedFor?: string;
28
27
  }
29
- export type GoalPromptKind = "active" | "continuation" | "budget-limit";
30
- export declare function remainingTokens(goal: Goal | null | undefined): number | null;
28
+ export type GoalPromptKind = "active" | "continuation";
31
29
  export declare function escapeXmlText(input: string): string;
32
30
  export declare function renderTrustedObjective(objective: string): string;
33
31
  export declare function validateGoalObjective(objective: string, op: "create" | "replace"): string;
34
32
  export declare function goalTokenDelta(current: GoalTokenUsage, baseline: GoalTokenUsage): number;
35
33
  export declare function renderGoalPrompt(kind: GoalPromptKind, goal: Goal): string;
36
- export declare function completionBudgetReport(goal: Goal): string | null;
37
34
  export declare class GoalRuntime {
38
35
  #private;
39
36
  constructor(host: GoalRuntimeHost);
@@ -49,15 +46,12 @@ export declare class GoalRuntime {
49
46
  reason?: "interrupted" | "internal";
50
47
  }): Promise<void>;
51
48
  onThreadResumed(): Promise<GoalModeState | undefined>;
52
- onBudgetMutated(newBudget: number | undefined): Promise<GoalModeState | undefined>;
53
- flushUsage(steering: GoalBudgetSteering, currentUsage?: GoalTokenUsage): Promise<void>;
49
+ flushUsage(currentUsage?: GoalTokenUsage): Promise<void>;
54
50
  createGoal(input: {
55
51
  objective: string;
56
- tokenBudget?: number;
57
52
  }): Promise<GoalModeState>;
58
53
  replaceGoal(input: {
59
54
  objective: string;
60
- tokenBudget?: number;
61
55
  }): Promise<GoalModeState>;
62
56
  resumeGoal(): Promise<GoalModeState>;
63
57
  pauseGoal(): Promise<GoalModeState | undefined>;
@@ -1,10 +1,9 @@
1
1
  import type { UsageStatistics } from "../session/session-manager";
2
- export type GoalStatus = "active" | "paused" | "budget-limited" | "complete" | "dropped";
2
+ export type GoalStatus = "active" | "paused" | "complete" | "dropped";
3
3
  export interface Goal {
4
4
  id: string;
5
5
  objective: string;
6
6
  status: GoalStatus;
7
- tokenBudget?: number;
8
7
  tokensUsed: number;
9
8
  timeUsedSeconds: number;
10
9
  createdAt: number;
@@ -19,8 +18,6 @@ export interface GoalModeState {
19
18
  export interface GoalToolDetails {
20
19
  op: "create" | "get" | "complete" | "resume" | "drop";
21
20
  goal?: Goal | null;
22
- remainingTokens?: number | null;
23
- completionBudgetReport?: string | null;
24
21
  }
25
22
  export type GoalRuntimeEvent = {
26
23
  type: "goal_updated";
@@ -31,5 +28,5 @@ export type GoalRuntimeEvent = {
31
28
  prompt: string;
32
29
  };
33
30
  export type GoalTokenUsage = Pick<UsageStatistics, "input" | "output" | "cacheRead" | "cacheWrite">;
34
- export type GoalBudgetSteering = "allowed" | "suppressed";
35
- export type GoalTerminalMetricEmission = "emit" | "suppress";
31
+ export declare function normalizeGoal(candidate: unknown): Goal | null;
32
+ export declare function normalizeGoalModeState(candidate: GoalModeState | undefined): GoalModeState | undefined;
@@ -14,31 +14,12 @@ declare const goalSchema: z.ZodObject<{
14
14
  resume: "resume";
15
15
  }>;
16
16
  objective: z.ZodOptional<z.ZodString>;
17
- token_budget: z.ZodOptional<z.ZodNumber>;
18
- }, z.core.$strip>;
19
- declare const getGoalSchema: z.ZodObject<{}, z.core.$strip>;
20
- declare const createGoalSchema: z.ZodObject<{
21
- objective: z.ZodString;
22
- token_budget: z.ZodOptional<z.ZodNumber>;
23
- }, z.core.$strip>;
24
- declare const updateGoalSchema: z.ZodObject<{
25
- status: z.ZodEnum<{
26
- complete: "complete";
27
- dropped: "dropped";
28
- }>;
29
17
  }, z.core.$strip>;
30
18
  export type GoalToolInput = z.infer<typeof goalSchema>;
31
- export type GetGoalToolInput = z.infer<typeof getGoalSchema>;
32
- export type CreateGoalToolInput = z.infer<typeof createGoalSchema>;
33
- export type UpdateGoalToolInput = z.infer<typeof updateGoalSchema>;
34
19
  export interface GoalToolResponse {
35
20
  goal: Goal | null;
36
- remainingTokens: number | null;
37
- completionBudgetReport: string | null;
38
21
  }
39
- export declare function buildGoalToolResponse(goal: Goal | null | undefined, options?: {
40
- includeCompletionReport?: boolean;
41
- }): GoalToolResponse;
22
+ export declare function buildGoalToolResponse(goal: Goal | null | undefined): GoalToolResponse;
42
23
  export declare class GoalTool implements AgentTool<typeof goalSchema, GoalToolDetails> {
43
24
  #private;
44
25
  readonly name = "goal";
@@ -54,64 +35,15 @@ export declare class GoalTool implements AgentTool<typeof goalSchema, GoalToolDe
54
35
  resume: "resume";
55
36
  }>;
56
37
  objective: z.ZodOptional<z.ZodString>;
57
- token_budget: z.ZodOptional<z.ZodNumber>;
58
38
  }, z.core.$strip>;
59
39
  readonly strict = true;
60
40
  readonly intent: "omit";
61
41
  constructor(session: ToolSession);
62
42
  execute(_toolCallId: string, params: GoalToolInput, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<GoalToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<GoalToolDetails>>;
63
43
  }
64
- export declare class GetGoalTool implements AgentTool<typeof getGoalSchema, GoalToolDetails> {
65
- #private;
66
- readonly name = "get_goal";
67
- readonly label = "Get Goal";
68
- readonly loadMode: "essential";
69
- readonly description: string;
70
- readonly parameters: z.ZodObject<{}, z.core.$strip>;
71
- readonly strict = true;
72
- readonly intent: "omit";
73
- static createIf(session: ToolSession): GetGoalTool | null;
74
- constructor(session: ToolSession);
75
- execute(_toolCallId: string, _params: GetGoalToolInput, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<GoalToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<GoalToolDetails>>;
76
- }
77
- export declare class CreateGoalTool implements AgentTool<typeof createGoalSchema, GoalToolDetails> {
78
- #private;
79
- readonly name = "create_goal";
80
- readonly label = "Create Goal";
81
- readonly loadMode: "essential";
82
- readonly description: string;
83
- readonly parameters: z.ZodObject<{
84
- objective: z.ZodString;
85
- token_budget: z.ZodOptional<z.ZodNumber>;
86
- }, z.core.$strip>;
87
- readonly strict = true;
88
- readonly intent: "omit";
89
- static createIf(session: ToolSession): CreateGoalTool | null;
90
- constructor(session: ToolSession);
91
- execute(_toolCallId: string, params: CreateGoalToolInput, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<GoalToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<GoalToolDetails>>;
92
- }
93
- export declare class UpdateGoalTool implements AgentTool<typeof updateGoalSchema, GoalToolDetails> {
94
- #private;
95
- readonly name = "update_goal";
96
- readonly label = "Update Goal";
97
- readonly loadMode: "essential";
98
- readonly description: string;
99
- readonly parameters: z.ZodObject<{
100
- status: z.ZodEnum<{
101
- complete: "complete";
102
- dropped: "dropped";
103
- }>;
104
- }, z.core.$strip>;
105
- readonly strict = true;
106
- readonly intent: "omit";
107
- static createIf(session: ToolSession): UpdateGoalTool | null;
108
- constructor(session: ToolSession);
109
- execute(_toolCallId: string, params: UpdateGoalToolInput, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<GoalToolDetails>, _context?: AgentToolContext): Promise<AgentToolResult<GoalToolDetails>>;
110
- }
111
44
  interface GoalRenderArgs {
112
45
  op?: GoalToolInput["op"];
113
46
  objective?: string;
114
- token_budget?: number;
115
47
  }
116
48
  export declare const goalToolRenderer: {
117
49
  renderCall(args: GoalRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
@@ -5,6 +5,26 @@ import type { GjcModelAssignmentTargetId, ModelRegistry } from "../../config/mod
5
5
  import { type ScopedModelSelection } from "../../config/model-resolver";
6
6
  import type { Settings } from "../../config/settings";
7
7
  type ScopedModelItem = ScopedModelSelection;
8
+ export interface ModelAssignmentPreset {
9
+ id: "openai-codex";
10
+ label: string;
11
+ description: string;
12
+ assignments: Partial<Record<GjcModelAssignmentTargetId, ThinkingLevel>>;
13
+ }
14
+ export type ModelSelectorSelection = {
15
+ kind: "assignment";
16
+ model: Model;
17
+ role: GjcModelAssignmentTargetId | null;
18
+ thinkingLevel?: ThinkingLevel;
19
+ selector?: string;
20
+ } | {
21
+ kind: "preset";
22
+ model: Model;
23
+ selector: string;
24
+ preset: ModelAssignmentPreset;
25
+ assignments: Record<GjcModelAssignmentTargetId, ThinkingLevel>;
26
+ };
27
+ type RoleSelectCallback = (selection: ModelSelectorSelection) => void;
8
28
  /**
9
29
  * Component that renders a canonical model selector with provider tabs.
10
30
  * - Tab/Arrow Left/Right: Switch between provider tabs
@@ -14,7 +34,7 @@ type ScopedModelItem = ScopedModelSelection;
14
34
  */
15
35
  export declare class ModelSelectorComponent extends Container {
16
36
  #private;
17
- constructor(tui: TUI, _currentModel: Model | undefined, settings: Settings, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: (model: Model, role: GjcModelAssignmentTargetId | null, thinkingLevel?: ThinkingLevel, selector?: string) => void, onCancel: () => void, options?: {
37
+ constructor(tui: TUI, _currentModel: Model | undefined, settings: Settings, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: RoleSelectCallback, onCancel: () => void, options?: {
18
38
  temporaryOnly?: boolean;
19
39
  initialSearchInput?: string;
20
40
  });
@@ -11,9 +11,6 @@ export interface SegmentContext {
11
11
  enabled: boolean;
12
12
  paused: boolean;
13
13
  } | null;
14
- loopMode: {
15
- enabled: boolean;
16
- } | null;
17
14
  goalMode: {
18
15
  enabled: boolean;
19
16
  paused: boolean;
@@ -44,9 +44,6 @@ export declare class StatusLineComponent implements Component {
44
44
  enabled: boolean;
45
45
  paused: boolean;
46
46
  } | undefined): void;
47
- setLoopModeStatus(status: {
48
- enabled: boolean;
49
- } | undefined): void;
50
47
  setGoalModeStatus(status: {
51
48
  enabled: boolean;
52
49
  paused: boolean;
@@ -32,5 +32,6 @@ export declare class CommandController {
32
32
  handleSkillCommand(skillPath: string, args: string): Promise<void>;
33
33
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
34
34
  handleHandoffCommand(customInstructions?: string): Promise<void>;
35
+ handleContributionPrepCommand(customInstructions?: string): Promise<void>;
35
36
  }
36
37
  export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
@@ -23,7 +23,6 @@ import type { HookInputComponent } from "./components/hook-input";
23
23
  import type { HookSelectorComponent } from "./components/hook-selector";
24
24
  import { StatusLineComponent } from "./components/status-line";
25
25
  import type { ToolExecutionHandle } from "./components/tool-execution";
26
- import { type LoopLimitRuntime } from "./loop-limit";
27
26
  import { OAuthManualInputManager } from "./oauth-manual-input";
28
27
  import type { Theme } from "./theme/theme";
29
28
  import type { CompactionQueuedMessage, InteractiveModeContext, SubmittedUserInput, TodoItem, TodoPhase } from "./types";
@@ -69,9 +68,6 @@ export declare class InteractiveMode implements InteractiveModeContext {
69
68
  goalModeEnabled: boolean;
70
69
  goalModePaused: boolean;
71
70
  planModePlanFilePath: string | undefined;
72
- loopModeEnabled: boolean;
73
- loopPrompt: string | undefined;
74
- loopLimit: LoopLimitRuntime | undefined;
75
71
  todoPhases: TodoPhase[];
76
72
  hideThinkingBlock: boolean;
77
73
  pendingImages: ImageContent[];
@@ -111,14 +107,6 @@ export declare class InteractiveMode implements InteractiveModeContext {
111
107
  /** Reload slash commands and autocomplete for the provided working directory. */
112
108
  refreshSlashCommandState(cwd?: string): Promise<void>;
113
109
  getUserInput(): Promise<SubmittedUserInput>;
114
- disableLoopMode(message?: string): void;
115
- /**
116
- * Pause the loop without exiting it: drops the captured prompt and any
117
- * pending auto-resubmit. Loop mode stays enabled — the next prompt the
118
- * user submits becomes the new loop prompt and resumes iteration.
119
- */
120
- pauseLoop(): void;
121
- handleLoopCommand(args?: string): Promise<void>;
122
110
  recordLocalSubmission(text: string, imageCount?: number): () => void;
123
111
  withLocalSubmission<T>(text: string, fn: () => Promise<T>, options?: {
124
112
  imageCount?: number;
@@ -208,6 +196,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
208
196
  handleSSHCommand(text: string): Promise<void>;
209
197
  handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
210
198
  handleHandoffCommand(customInstructions?: string): Promise<void>;
199
+ handleContributionPrepCommand(customInstructions?: string): Promise<void>;
211
200
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
212
201
  openInBrowser(urlOrPath: string): void;
213
202
  showSettingsSelector(): void;
@@ -2921,7 +2921,6 @@ export declare const defaultThemes: {
2921
2921
  "icon.plan": string;
2922
2922
  "icon.goal": string;
2923
2923
  "icon.pause": string;
2924
- "icon.loop": string;
2925
2924
  "icon.folder": string;
2926
2925
  "icon.scratchFolder": string;
2927
2926
  "icon.pi": string;
@@ -7439,7 +7438,6 @@ export declare const defaultThemes: {
7439
7438
  "icon.plan": string;
7440
7439
  "icon.goal": string;
7441
7440
  "icon.pause": string;
7442
- "icon.loop": string;
7443
7441
  "icon.folder": string;
7444
7442
  "icon.scratchFolder": string;
7445
7443
  "icon.pi": string;
@@ -6,7 +6,7 @@ export type SymbolPreset = "unicode" | "nerd" | "ascii";
6
6
  /**
7
7
  * All available symbol keys organized by category.
8
8
  */
9
- export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "checkbox.checked" | "checkbox.unchecked" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
9
+ export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.folder" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.agents" | "icon.cache" | "icon.input" | "icon.output" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "checkbox.checked" | "checkbox.unchecked" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.editing" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers";
10
10
  export type SpinnerType = "status" | "activity";
11
11
  export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
12
12
  /** Check if a string is a valid ThemeColor value */
@@ -110,7 +110,6 @@ export declare class Theme {
110
110
  plan: string;
111
111
  goal: string;
112
112
  pause: string;
113
- loop: string;
114
113
  folder: string;
115
114
  scratchFolder: string;
116
115
  file: string;
@@ -22,7 +22,6 @@ import type { HookInputComponent } from "./components/hook-input";
22
22
  import type { HookSelectorComponent } from "./components/hook-selector";
23
23
  import type { StatusLineComponent } from "./components/status-line";
24
24
  import type { ToolExecutionHandle } from "./components/tool-execution";
25
- import type { LoopLimitRuntime } from "./loop-limit";
26
25
  import type { OAuthManualInputManager } from "./oauth-manual-input";
27
26
  import type { Theme } from "./theme/theme";
28
27
  export type CompactionQueuedMessage = {
@@ -76,9 +75,6 @@ export interface InteractiveModeContext {
76
75
  planModeEnabled: boolean;
77
76
  goalModeEnabled: boolean;
78
77
  goalModePaused: boolean;
79
- loopModeEnabled: boolean;
80
- loopPrompt?: string;
81
- loopLimit?: LoopLimitRuntime;
82
78
  planModePlanFilePath?: string;
83
79
  hideThinkingBlock: boolean;
84
80
  pendingImages: ImageContent[];
@@ -203,6 +199,7 @@ export interface InteractiveModeContext {
203
199
  handleSSHCommand(text: string): Promise<void>;
204
200
  handleCompactCommand(customInstructions?: string): Promise<CompactionOutcome>;
205
201
  handleHandoffCommand(customInstructions?: string): Promise<void>;
202
+ handleContributionPrepCommand(customInstructions?: string): Promise<void>;
206
203
  handleMoveCommand(targetPath: string): Promise<void>;
207
204
  handleRenameCommand(title: string): Promise<void>;
208
205
  handleMemoryCommand(text: string): Promise<void>;
@@ -249,9 +246,6 @@ export interface InteractiveModeContext {
249
246
  registerExtensionShortcuts(): void;
250
247
  handlePlanModeCommand(initialPrompt?: string): Promise<void>;
251
248
  handleGoalModeCommand(rest?: string): Promise<void>;
252
- handleLoopCommand(args?: string): Promise<void>;
253
- disableLoopMode(): void;
254
- pauseLoop(): void;
255
249
  handlePlanApproval(details: PlanApprovalDetails): Promise<void>;
256
250
  initHooksAndCustomTools(): Promise<void>;
257
251
  emitCustomToolSessionEvent(reason: "start" | "switch" | "branch" | "tree" | "shutdown", previousSessionFile?: string): Promise<void>;
@@ -42,6 +42,7 @@ import { type DiscoverableTool, type DiscoverableToolSearchIndex } from "../tool
42
42
  import type { CheckpointState } from "../tools/checkpoint";
43
43
  import { type TodoItem, type TodoPhase } from "../tools/todo-write";
44
44
  import type { ClientBridge } from "./client-bridge";
45
+ import { type ContributionPrepOptions, type ContributionPrepResult } from "./contribution-prep";
45
46
  import { type CustomMessage } from "./messages";
46
47
  import type { BranchSummaryEntry, NewSessionOptions, SessionContext, SessionManager } from "./session-manager";
47
48
  import { ToolChoiceQueue } from "./tool-choice-queue";
@@ -696,6 +697,7 @@ export declare class AgentSession {
696
697
  * @returns The handoff document text, or undefined if cancelled/failed
697
698
  */
698
699
  handoff(customInstructions?: string, options?: SessionHandoffOptions): Promise<HandoffResult | undefined>;
700
+ prepareContributionPrep(options?: ContributionPrepOptions): Promise<ContributionPrepResult>;
699
701
  /**
700
702
  * Toggle auto-compaction setting.
701
703
  */
@@ -0,0 +1,47 @@
1
+ import type { AgentMessage } from "@gajae-code/agent-core";
2
+ export declare const CONTRIBUTION_PREP_SCHEMA_VERSION = 1;
3
+ export interface ContributionPrepArtifact {
4
+ path: string;
5
+ description: string;
6
+ }
7
+ export interface ContributionPrepManifest {
8
+ schema_version: number;
9
+ source_session_id: string;
10
+ created_at: string;
11
+ cwd: string;
12
+ git_head: string | null;
13
+ changed_files: string[];
14
+ artifacts: ContributionPrepArtifact[];
15
+ redactions: string[];
16
+ recommended_output: string[];
17
+ worker_prompt_path: string;
18
+ }
19
+ export interface ContributionPrepResult {
20
+ manifestPath: string;
21
+ workerPromptPath: string;
22
+ artifactDir: string;
23
+ changedFiles: string[];
24
+ spawned: boolean;
25
+ }
26
+ export interface ContributionPrepOptions {
27
+ customInstructions?: string;
28
+ spawnWorker?: boolean;
29
+ artifactRoot?: string;
30
+ now?: Date;
31
+ spawn?: (args: string[], cwd: string, shell: boolean) => Promise<void>;
32
+ }
33
+ export interface ContributionPrepContext {
34
+ sessionId: string;
35
+ cwd: string;
36
+ sessionFile?: string;
37
+ messages: AgentMessage[];
38
+ customInstructions?: string;
39
+ now?: Date;
40
+ }
41
+ interface RedactionState {
42
+ labels: Set<string>;
43
+ }
44
+ export declare function redactContributionPrepText(text: string, cwd: string, state?: RedactionState): string;
45
+ export declare function buildContributionPrepWorkerPrompt(manifestPath: string): string;
46
+ export declare function prepareContributionPrep(context: ContributionPrepContext, options?: ContributionPrepOptions): Promise<ContributionPrepResult>;
47
+ export {};
@@ -1,3 +1,4 @@
1
+ import type { WorkflowStateReceipt } from "./workflow-state-contract";
1
2
  export declare const SKILL_ACTIVE_STATE_FILE = "skill-active-state.json";
2
3
  export declare const SKILL_ACTIVE_STALE_MS: number;
3
4
  export declare const CANONICAL_GJC_WORKFLOW_SKILLS: readonly ["deep-interview", "ralplan", "ultragoal", "team"];
@@ -17,6 +18,7 @@ export interface WorkflowHudSummary {
17
18
  severity?: WorkflowHudSeverity;
18
19
  updated_at?: string;
19
20
  }
21
+ export type { WorkflowStateReceipt } from "./workflow-state-contract";
20
22
  export interface SkillActiveEntry {
21
23
  skill: string;
22
24
  phase?: string;
@@ -28,6 +30,7 @@ export interface SkillActiveEntry {
28
30
  turn_id?: string;
29
31
  hud?: WorkflowHudSummary;
30
32
  stale?: boolean;
33
+ receipt?: WorkflowStateReceipt;
31
34
  }
32
35
  export interface SkillActiveState {
33
36
  version?: number;
@@ -59,6 +62,7 @@ export interface SyncSkillActiveStateOptions {
59
62
  nowIso?: string;
60
63
  source?: string;
61
64
  hud?: WorkflowHudSummary;
65
+ receipt?: WorkflowStateReceipt;
62
66
  }
63
67
  export declare function normalizeWorkflowHudSummary(raw: unknown): WorkflowHudSummary | undefined;
64
68
  export declare function isCanonicalGjcWorkflowSkill(skill: string): skill is CanonicalGjcWorkflowSkill;
@@ -1,5 +1,6 @@
1
1
  import type { AgentTool } from "@gajae-code/agent-core";
2
- export declare const DEEP_INTERVIEW_MUTATION_BLOCK_MESSAGE = "Deep-interview is active; either continue interviewing with `ask`, or write/finalize the pending spec under `.gjc/specs/` / update state under `.gjc/state/`. Do not edit product code until explicit execution approval.";
2
+ export declare const DEEP_INTERVIEW_MUTATION_BLOCK_MESSAGE = "Deep-interview is active; continue interviewing with `ask`, write/finalize pending specs through the required GJC workflow CLI, or use an explicit force override. Direct `.gjc/` and product-code edits are blocked until explicit execution approval.";
3
+ export declare const WORKFLOW_STATE_MUTATION_BLOCK_MESSAGE = "Workflow state JSON is runtime-owned. Use `gjc state <skill> read|write --input '<json>'` for deep-interview, ralplan, ultragoal, and team. Planning artifacts under `.gjc/specs/` and `.gjc/plans/` remain allowed.";
3
4
  type ToolWithEditMode = AgentTool & {
4
5
  mode?: unknown;
5
6
  customWireName?: unknown;
@@ -10,18 +11,22 @@ export interface DeepInterviewMutationGuardInput {
10
11
  threadId?: string;
11
12
  tool: ToolWithEditMode;
12
13
  args: unknown;
14
+ forceOverride?: boolean;
15
+ enforceWorkflowState?: boolean;
13
16
  }
14
17
  export interface DeepInterviewMutationDecision {
15
18
  blocked: boolean;
16
19
  message?: string;
17
20
  targets: string[];
18
21
  reason?: string;
22
+ command?: string;
19
23
  }
20
24
  export declare function assertDeepInterviewMutationRawPathsAllowed(input: {
21
25
  cwd: string;
22
26
  sessionId?: string;
23
27
  threadId?: string;
24
28
  rawPaths: string[];
29
+ forceOverride?: boolean;
25
30
  }): Promise<void>;
26
31
  export declare function getDeepInterviewMutationDecision(input: DeepInterviewMutationGuardInput): Promise<DeepInterviewMutationDecision>;
27
32
  export declare function assertDeepInterviewMutationAllowed(input: DeepInterviewMutationGuardInput): Promise<void>;
@@ -1,5 +1,10 @@
1
1
  import type { WorkflowHudSummary } from "./active-state";
2
- interface DeepInterviewHudState {
2
+ interface WorkflowGateHudState {
3
+ approvalStatus?: string;
4
+ blockedReason?: string;
5
+ nextAction?: string;
6
+ }
7
+ interface DeepInterviewHudState extends WorkflowGateHudState {
3
8
  phase?: string;
4
9
  ambiguity?: number;
5
10
  threshold?: number;
@@ -9,7 +14,7 @@ interface DeepInterviewHudState {
9
14
  specStatus?: string;
10
15
  updatedAt?: string;
11
16
  }
12
- interface RalplanHudState {
17
+ interface RalplanHudState extends WorkflowGateHudState {
13
18
  stage?: string;
14
19
  waiting?: string;
15
20
  iteration?: number;
@@ -23,7 +28,7 @@ interface UltragoalLikeGoal {
23
28
  title: string;
24
29
  status: string;
25
30
  }
26
- interface UltragoalHudState {
31
+ interface UltragoalHudState extends WorkflowGateHudState {
27
32
  status: string;
28
33
  currentGoal?: UltragoalLikeGoal;
29
34
  counts: Record<string, number>;
@@ -39,7 +44,7 @@ interface TeamHudWorker {
39
44
  id: string;
40
45
  status?: string;
41
46
  }
42
- interface TeamHudState {
47
+ interface TeamHudState extends WorkflowGateHudState {
43
48
  phase: string;
44
49
  task_total: number;
45
50
  task_counts: Record<string, number>;
@@ -0,0 +1,34 @@
1
+ import { type CanonicalGjcWorkflowSkill } from "./active-state";
2
+ export type { CanonicalGjcWorkflowSkill };
3
+ export declare const WORKFLOW_STATE_RECEIPT_VERSION = 1;
4
+ export declare const WORKFLOW_STATE_RECEIPT_FRESH_MS: number;
5
+ export type WorkflowStateMutationOwner = "gjc-state-cli" | "gjc-runtime" | "gjc-hook";
6
+ export type WorkflowStateReceiptStatus = "fresh" | "stale";
7
+ export interface WorkflowStateReceipt {
8
+ version: 1;
9
+ skill: CanonicalGjcWorkflowSkill;
10
+ owner: WorkflowStateMutationOwner;
11
+ command: string;
12
+ state_path: string;
13
+ storage_path: string;
14
+ mutated_at: string;
15
+ fresh_until: string;
16
+ status: WorkflowStateReceiptStatus;
17
+ mutation_id: string;
18
+ }
19
+ export declare function workflowModeStateFileName(skill: CanonicalGjcWorkflowSkill): string;
20
+ export declare function workflowStateStoragePath(cwd: string, skill: CanonicalGjcWorkflowSkill, sessionId?: string): string;
21
+ export declare function workflowActiveStatePath(cwd: string, sessionId?: string): string;
22
+ export declare function buildWorkflowStateReceipt(input: {
23
+ cwd: string;
24
+ skill: CanonicalGjcWorkflowSkill;
25
+ owner: WorkflowStateMutationOwner;
26
+ command: string;
27
+ sessionId?: string;
28
+ nowIso?: string;
29
+ mutationId?: string;
30
+ }): WorkflowStateReceipt;
31
+ export declare function workflowReceiptStatus(receipt: WorkflowStateReceipt | undefined, nowMs?: number): WorkflowStateReceiptStatus | undefined;
32
+ export declare function canonicalWorkflowSkill(value: string): CanonicalGjcWorkflowSkill | null;
33
+ export declare function sanctionedWorkflowStateCommand(skill: CanonicalGjcWorkflowSkill): string;
34
+ export declare function describeWorkflowStateContract(skill: CanonicalGjcWorkflowSkill): string[];
@@ -2,6 +2,7 @@ import type { BuiltinSlashCommand, ParsedSlashCommand, SlashCommandResult, Slash
2
2
  export type { BuiltinSlashCommand, SubcommandDef } from "./types";
3
3
  /** TUI-specific runtime accepted by `executeBuiltinSlashCommand`. */
4
4
  export type BuiltinSlashCommandRuntime = TuiSlashCommandRuntime;
5
+ export declare function formatUnknownBuiltinSlashCommandDiagnostic(commandName: string): string | undefined;
5
6
  /** Builtin command metadata used for slash-command autocomplete and help text. */
6
7
  export declare const BUILTIN_SLASH_COMMAND_DEFS: ReadonlyArray<BuiltinSlashCommand>;
7
8
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/coding-agent",
4
- "version": "0.2.0",
4
+ "version": "0.2.2",
5
5
  "description": "Gajae Code CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://gaebal-gajae.dev",
7
7
  "author": "Yeachan-Heo",
@@ -48,12 +48,12 @@
48
48
  "@agentclientprotocol/sdk": "0.21.0",
49
49
  "@babel/parser": "^7.29.3",
50
50
  "@mozilla/readability": "^0.6.0",
51
- "@gajae-code/stats": "0.2.0",
52
- "@gajae-code/agent-core": "0.2.0",
53
- "@gajae-code/ai": "0.2.0",
54
- "@gajae-code/natives": "0.2.0",
55
- "@gajae-code/tui": "0.2.0",
56
- "@gajae-code/utils": "0.2.0",
51
+ "@gajae-code/stats": "0.2.2",
52
+ "@gajae-code/agent-core": "0.2.2",
53
+ "@gajae-code/ai": "0.2.2",
54
+ "@gajae-code/natives": "0.2.2",
55
+ "@gajae-code/tui": "0.2.2",
56
+ "@gajae-code/utils": "0.2.2",
57
57
  "@puppeteer/browsers": "^2.13.0",
58
58
  "@types/turndown": "5.0.6",
59
59
  "@xterm/headless": "^6.0.0",