@gajae-code/coding-agent 0.2.1 → 0.2.3

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 (153) hide show
  1. package/CHANGELOG.md +59 -1
  2. package/dist/types/cli/setup-cli.d.ts +1 -0
  3. package/dist/types/commands/contribution-prep.d.ts +18 -0
  4. package/dist/types/commands/deep-interview.d.ts +41 -0
  5. package/dist/types/commands/session.d.ts +24 -0
  6. package/dist/types/commands/setup.d.ts +3 -0
  7. package/dist/types/config/model-registry.d.ts +2 -2
  8. package/dist/types/config/models-config-schema.d.ts +17 -9
  9. package/dist/types/config/settings-schema.d.ts +37 -24
  10. package/dist/types/discovery/helpers.d.ts +2 -0
  11. package/dist/types/extensibility/extensions/types.d.ts +6 -0
  12. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +33 -0
  13. package/dist/types/gjc-runtime/goal-mode-request.d.ts +1 -1
  14. package/dist/types/gjc-runtime/launch-tmux.d.ts +12 -11
  15. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +25 -0
  16. package/dist/types/gjc-runtime/state-runtime.d.ts +13 -0
  17. package/dist/types/gjc-runtime/team-runtime.d.ts +37 -5
  18. package/dist/types/gjc-runtime/tmux-common.d.ts +41 -0
  19. package/dist/types/gjc-runtime/tmux-sessions.d.ts +17 -0
  20. package/dist/types/goals/runtime.d.ts +3 -9
  21. package/dist/types/goals/state.d.ts +3 -6
  22. package/dist/types/goals/tools/goal-tool.d.ts +1 -69
  23. package/dist/types/hooks/skill-state.d.ts +5 -0
  24. package/dist/types/memories/index.d.ts +1 -1
  25. package/dist/types/memory-backend/local-backend.d.ts +3 -3
  26. package/dist/types/modes/components/hook-selector.d.ts +7 -0
  27. package/dist/types/modes/components/settings-selector.d.ts +0 -2
  28. package/dist/types/modes/components/status-line/types.d.ts +0 -3
  29. package/dist/types/modes/components/status-line.d.ts +0 -3
  30. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  31. package/dist/types/modes/interactive-mode.d.ts +1 -12
  32. package/dist/types/modes/theme/defaults/index.d.ts +0 -2
  33. package/dist/types/modes/theme/theme.d.ts +1 -2
  34. package/dist/types/modes/types.d.ts +1 -7
  35. package/dist/types/modes/utils/context-usage.d.ts +6 -2
  36. package/dist/types/sdk.d.ts +6 -2
  37. package/dist/types/session/agent-session.d.ts +47 -1
  38. package/dist/types/session/contribution-prep.d.ts +47 -0
  39. package/dist/types/session/session-manager.d.ts +3 -0
  40. package/dist/types/setup/model-onboarding-guidance.d.ts +1 -0
  41. package/dist/types/setup/provider-onboarding.d.ts +29 -5
  42. package/dist/types/skill-state/active-state.d.ts +30 -1
  43. package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +6 -1
  44. package/dist/types/skill-state/initial-phase.d.ts +12 -0
  45. package/dist/types/skill-state/workflow-hud.d.ts +9 -4
  46. package/dist/types/skill-state/workflow-state-contract.d.ts +34 -0
  47. package/dist/types/task/executor.d.ts +2 -0
  48. package/dist/types/task/types.d.ts +11 -0
  49. package/dist/types/tools/index.d.ts +20 -1
  50. package/dist/types/tools/skill.d.ts +47 -0
  51. package/dist/types/utils/changelog.d.ts +18 -2
  52. package/package.json +7 -7
  53. package/src/cli/args.ts +3 -2
  54. package/src/cli/setup-cli.ts +26 -12
  55. package/src/cli.ts +7 -1
  56. package/src/commands/contribution-prep.ts +41 -0
  57. package/src/commands/deep-interview.ts +30 -23
  58. package/src/commands/launch.ts +10 -1
  59. package/src/commands/ralplan.ts +10 -22
  60. package/src/commands/session.ts +150 -0
  61. package/src/commands/setup.ts +2 -0
  62. package/src/commands/state.ts +15 -4
  63. package/src/commands/team.ts +23 -3
  64. package/src/config/model-registry.ts +10 -2
  65. package/src/config/models-config-schema.ts +120 -102
  66. package/src/config/settings-schema.ts +42 -25
  67. package/src/config.ts +1 -1
  68. package/src/defaults/gjc/skills/deep-interview/SKILL.md +32 -13
  69. package/src/defaults/gjc/skills/ralplan/SKILL.md +22 -2
  70. package/src/defaults/gjc/skills/team/SKILL.md +39 -7
  71. package/src/defaults/gjc/skills/ultragoal/SKILL.md +33 -25
  72. package/src/discovery/helpers.ts +24 -1
  73. package/src/eval/py/prelude.py +1 -1
  74. package/src/extensibility/extensions/types.ts +6 -0
  75. package/src/gjc-runtime/deep-interview-runtime.ts +546 -0
  76. package/src/gjc-runtime/goal-mode-request.ts +2 -19
  77. package/src/gjc-runtime/launch-tmux.ts +83 -43
  78. package/src/gjc-runtime/ralplan-runtime.ts +460 -0
  79. package/src/gjc-runtime/state-runtime.ts +731 -0
  80. package/src/gjc-runtime/team-runtime.ts +708 -52
  81. package/src/gjc-runtime/tmux-common.ts +119 -0
  82. package/src/gjc-runtime/tmux-sessions.ts +165 -0
  83. package/src/gjc-runtime/ultragoal-guard.ts +6 -3
  84. package/src/gjc-runtime/ultragoal-runtime.ts +5 -4
  85. package/src/goals/runtime.ts +38 -144
  86. package/src/goals/state.ts +36 -7
  87. package/src/goals/tools/goal-tool.ts +15 -172
  88. package/src/hooks/skill-state.ts +39 -18
  89. package/src/internal-urls/docs-index.generated.ts +5 -4
  90. package/src/internal-urls/memory-protocol.ts +3 -2
  91. package/src/main.ts +2 -3
  92. package/src/memories/index.ts +2 -1
  93. package/src/memory-backend/local-backend.ts +14 -6
  94. package/src/modes/components/hook-selector.ts +156 -1
  95. package/src/modes/components/settings-selector.ts +5 -12
  96. package/src/modes/components/skill-hud/render.ts +4 -0
  97. package/src/modes/components/status-line/segments.ts +5 -16
  98. package/src/modes/components/status-line/types.ts +0 -3
  99. package/src/modes/components/status-line.ts +0 -6
  100. package/src/modes/controllers/command-controller.ts +27 -4
  101. package/src/modes/controllers/extension-ui-controller.ts +1 -0
  102. package/src/modes/controllers/input-controller.ts +0 -15
  103. package/src/modes/controllers/selector-controller.ts +4 -11
  104. package/src/modes/interactive-mode.ts +18 -219
  105. package/src/modes/theme/defaults/dark-poimandres.json +0 -1
  106. package/src/modes/theme/defaults/light-poimandres.json +0 -1
  107. package/src/modes/theme/theme.ts +0 -6
  108. package/src/modes/types.ts +1 -7
  109. package/src/modes/utils/context-usage.ts +66 -17
  110. package/src/prompts/agents/architect.md +3 -0
  111. package/src/prompts/agents/executor.md +2 -0
  112. package/src/prompts/agents/frontmatter.md +1 -0
  113. package/src/prompts/goals/goal-continuation.md +1 -4
  114. package/src/prompts/goals/goal-mode-active.md +3 -5
  115. package/src/prompts/system/subagent-system-prompt.md +6 -0
  116. package/src/prompts/system/system-prompt.md +5 -7
  117. package/src/prompts/tools/goal.md +4 -4
  118. package/src/prompts/tools/skill.md +28 -0
  119. package/src/prompts/tools/task.md +3 -0
  120. package/src/sdk.ts +51 -11
  121. package/src/session/agent-session.ts +222 -21
  122. package/src/session/contribution-prep.ts +320 -0
  123. package/src/session/session-manager.ts +9 -1
  124. package/src/setup/model-onboarding-guidance.ts +6 -3
  125. package/src/setup/provider-onboarding.ts +177 -16
  126. package/src/skill-state/active-state.ts +188 -25
  127. package/src/skill-state/deep-interview-mutation-guard.ts +72 -21
  128. package/src/skill-state/initial-phase.ts +17 -0
  129. package/src/skill-state/workflow-hud.ts +23 -5
  130. package/src/skill-state/workflow-state-contract.ts +121 -0
  131. package/src/slash-commands/builtin-registry.ts +75 -25
  132. package/src/slash-commands/helpers/context-report.ts +123 -13
  133. package/src/task/agents.ts +1 -0
  134. package/src/task/commands.ts +1 -5
  135. package/src/task/executor.ts +9 -1
  136. package/src/task/index.ts +91 -4
  137. package/src/task/types.ts +6 -0
  138. package/src/tools/ask.ts +2 -0
  139. package/src/tools/gh.ts +212 -2
  140. package/src/tools/index.ts +25 -6
  141. package/src/tools/skill.ts +153 -0
  142. package/src/utils/changelog.ts +67 -44
  143. package/dist/types/commands/gjc-runtime-bridge.d.ts +0 -30
  144. package/dist/types/commands/question.d.ts +0 -7
  145. package/dist/types/modes/loop-limit.d.ts +0 -22
  146. package/src/commands/gjc-runtime-bridge.ts +0 -227
  147. package/src/commands/question.ts +0 -12
  148. package/src/modes/loop-limit.ts +0 -140
  149. package/src/prompts/commands/orchestrate.md +0 -49
  150. package/src/prompts/goals/goal-budget-limit.md +0 -16
  151. package/src/prompts/tools/create-goal.md +0 -3
  152. package/src/prompts/tools/get-goal.md +0 -3
  153. package/src/prompts/tools/update-goal.md +0 -3
@@ -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 {};
@@ -111,6 +111,8 @@ export interface SessionInitEntry extends SessionEntryBase {
111
111
  tools: string[];
112
112
  /** Output schema if structured output was requested */
113
113
  outputSchema?: unknown;
114
+ /** Fork-context seed metadata for subagent debugging/replay. */
115
+ forkContext?: unknown;
114
116
  }
115
117
  /** Mode change entry - tracks agent mode transitions (e.g. plan mode). */
116
118
  export interface ModeChangeEntry extends SessionEntryBase {
@@ -393,6 +395,7 @@ export declare class SessionManager {
393
395
  task: string;
394
396
  tools: string[];
395
397
  outputSchema?: unknown;
398
+ forkContext?: unknown;
396
399
  }): string;
397
400
  /** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */
398
401
  appendCompaction<T = unknown>(summary: string, shortSummary: string | undefined, firstKeptEntryId: string, tokensBefore: number, details?: T, fromExtension?: boolean, preserveData?: Record<string, unknown>): string;
@@ -1,4 +1,5 @@
1
1
  export declare const MODEL_ONBOARDING_API_PROVIDER_COMMAND = "/provider add --compat <openai|anthropic> --provider <id> --base-url <url> --api-key-env <ENV> --model <model>";
2
+ export declare const MODEL_ONBOARDING_PROVIDER_PRESET_COMMAND = "/provider add --preset <minimax|minimax-cn|glm>";
2
3
  export declare const MODEL_ONBOARDING_SETUP_COMMAND = "gjc setup provider";
3
4
  export declare const MODEL_ONBOARDING_OAUTH_COMMAND = "/provider login [provider-id] or /login [provider-id]";
4
5
  export declare function formatModelOnboardingGuidance(): string;
@@ -1,28 +1,52 @@
1
+ import { type ModelsConfig } from "../config/models-config-schema";
1
2
  export type ProviderCompatibility = "openai" | "anthropic";
3
+ export type ProviderSetupApi = "openai-responses" | "openai-completions" | "anthropic-messages";
2
4
  export interface ProviderSetupInput {
3
- compatibility: ProviderCompatibility;
4
- providerId: string;
5
- baseUrl: string;
5
+ compatibility?: ProviderCompatibility;
6
+ preset?: string;
7
+ providerId?: string;
8
+ baseUrl?: string;
6
9
  apiKey?: string;
7
10
  apiKeyEnv?: string;
8
- models: string[];
11
+ models?: string[];
9
12
  modelsPath?: string;
10
13
  force?: boolean;
11
14
  }
12
15
  export interface ProviderSetupResult {
13
16
  providerId: string;
14
17
  compatibility: ProviderCompatibility;
15
- api: "openai-responses" | "anthropic-messages";
18
+ api: ProviderSetupApi;
16
19
  baseUrl: string;
17
20
  modelIds: string[];
18
21
  modelsPath: string;
19
22
  redactedApiKey: string;
20
23
  credentialSource: "literal" | "env";
24
+ preset?: string;
25
+ presetName?: string;
26
+ }
27
+ type ProviderConfig = NonNullable<NonNullable<ModelsConfig["providers"]>[string]>;
28
+ type ProviderCompatConfig = NonNullable<ProviderConfig["compat"]>;
29
+ interface ProviderPreset {
30
+ id: string;
31
+ aliases: readonly string[];
32
+ name: string;
33
+ description: string;
34
+ compatibility: ProviderCompatibility;
35
+ api: ProviderSetupApi;
36
+ providerId: string;
37
+ baseUrl: string;
38
+ apiKeyEnv: string;
39
+ models: readonly string[];
40
+ compat?: ProviderCompatConfig;
21
41
  }
42
+ export declare const PROVIDER_PRESETS: readonly ProviderPreset[];
22
43
  export declare function getDefaultModelsPath(): string;
23
44
  export declare function normalizeProviderId(providerId: string): string;
24
45
  export declare function parseProviderCompatibility(value: string): ProviderCompatibility;
46
+ export declare function findProviderPreset(value: string | undefined): ProviderPreset | undefined;
47
+ export declare function formatProviderPresetList(): string;
25
48
  export declare function parseModelList(values: readonly string[]): string[];
26
49
  export declare function redactSecret(secret: string): string;
27
50
  export declare function addApiCompatibleProvider(input: ProviderSetupInput): Promise<ProviderSetupResult>;
28
51
  export declare function formatProviderSetupResult(result: ProviderSetupResult): string;
52
+ export {};
@@ -1,5 +1,5 @@
1
+ import type { WorkflowStateReceipt } from "./workflow-state-contract";
1
2
  export declare const SKILL_ACTIVE_STATE_FILE = "skill-active-state.json";
2
- export declare const SKILL_ACTIVE_STALE_MS: number;
3
3
  export declare const CANONICAL_GJC_WORKFLOW_SKILLS: readonly ["deep-interview", "ralplan", "ultragoal", "team"];
4
4
  export type CanonicalGjcWorkflowSkill = (typeof CANONICAL_GJC_WORKFLOW_SKILLS)[number];
5
5
  export type WorkflowHudSeverity = "info" | "warning" | "blocked" | "error" | "success";
@@ -17,6 +17,7 @@ export interface WorkflowHudSummary {
17
17
  severity?: WorkflowHudSeverity;
18
18
  updated_at?: string;
19
19
  }
20
+ export type { WorkflowStateReceipt } from "./workflow-state-contract";
20
21
  export interface SkillActiveEntry {
21
22
  skill: string;
22
23
  phase?: string;
@@ -28,6 +29,10 @@ export interface SkillActiveEntry {
28
29
  turn_id?: string;
29
30
  hud?: WorkflowHudSummary;
30
31
  stale?: boolean;
32
+ receipt?: WorkflowStateReceipt;
33
+ handoff_from?: string;
34
+ handoff_to?: string;
35
+ handoff_at?: string;
31
36
  }
32
37
  export interface SkillActiveState {
33
38
  version?: number;
@@ -59,6 +64,10 @@ export interface SyncSkillActiveStateOptions {
59
64
  nowIso?: string;
60
65
  source?: string;
61
66
  hud?: WorkflowHudSummary;
67
+ receipt?: WorkflowStateReceipt;
68
+ handoff_from?: string;
69
+ handoff_to?: string;
70
+ handoff_at?: string;
62
71
  }
63
72
  export declare function normalizeWorkflowHudSummary(raw: unknown): WorkflowHudSummary | undefined;
64
73
  export declare function isCanonicalGjcWorkflowSkill(skill: string): skill is CanonicalGjcWorkflowSkill;
@@ -67,3 +76,23 @@ export declare function normalizeSkillActiveState(raw: unknown): SkillActiveStat
67
76
  export declare function getSkillActiveStatePaths(cwd: string, sessionId?: string): SkillActiveStatePaths;
68
77
  export declare function readVisibleSkillActiveState(cwd: string, sessionId?: string): Promise<SkillActiveState | null>;
69
78
  export declare function syncSkillActiveState(options: SyncSkillActiveStateOptions): Promise<void>;
79
+ export interface ApplyHandoffOptions {
80
+ cwd: string;
81
+ caller: SyncSkillActiveStateOptions;
82
+ callee: SyncSkillActiveStateOptions;
83
+ /** Shared timestamp; falls back to new Date().toISOString(). */
84
+ nowIso?: string;
85
+ /** When true, read errors other than ENOENT propagate. */
86
+ strict?: boolean;
87
+ }
88
+ /**
89
+ * Atomically apply a workflow-skill handoff to both the session-scoped and
90
+ * root `skill-active-state.json` files in a single write per file.
91
+ *
92
+ * Write order: **session first, root last**. The session file is the
93
+ * source of truth for HUD; the root aggregate must never lead the session
94
+ * during a handoff window. Each file is rewritten once with caller demoted
95
+ * to `active:false` (preserving `handoff_to`/`handoff_at` lineage) and
96
+ * callee promoted to `active:true` (with `handoff_from`/`handoff_at`).
97
+ */
98
+ export declare function applyHandoffToActiveState(options: ApplyHandoffOptions): Promise<void>;
@@ -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 phase boundary: continue gathering context/questions/risks and emit a handoff/spec before code edits. Mutation tools and patch execution are blocked while deep-interview is active; finalize specs through `gjc deep-interview --write --stage final` or hand off to an execution phase.";
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>;
@@ -0,0 +1,12 @@
1
+ import type { CanonicalGjcWorkflowSkill } from "./active-state";
2
+ /**
3
+ * Canonical initial phase for each GJC workflow skill. Used by both
4
+ * `recordSkillActivation` (UserPromptSubmit hook seeding initial mode-state)
5
+ * and the `gjc state <caller> handoff --to <callee>` runtime when promoting
6
+ * the callee.
7
+ *
8
+ * Keeping this mapping in a neutral skill-state module avoids cycles between
9
+ * `gjc-runtime/state-runtime.ts` and `hooks/skill-state.ts` (which pulls in
10
+ * session-manager and ultragoal verification code).
11
+ */
12
+ export declare function initialPhaseForSkill(skill: CanonicalGjcWorkflowSkill | string): string;
@@ -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[];
@@ -10,6 +10,7 @@ import { Settings } from "../config/settings";
10
10
  import { type Skill } from "../extensibility/skills";
11
11
  import type { HindsightSessionState } from "../hindsight/state";
12
12
  import type { LocalProtocolOptions } from "../internal-urls";
13
+ import type { ForkContextSeed } from "../session/agent-session";
13
14
  import type { ArtifactManager } from "../session/artifacts";
14
15
  import type { AuthStorage } from "../session/auth-storage";
15
16
  import type { ContextFileEntry } from "../tools";
@@ -73,6 +74,7 @@ export interface ExecutorOptions {
73
74
  parentTelemetry?: AgentTelemetryConfig;
74
75
  /** Skills to autoload via sendCustomMessage before the first prompt */
75
76
  autoloadSkills?: Skill[];
77
+ forkContextSeed?: ForkContextSeed;
76
78
  }
77
79
  export interface YieldItem {
78
80
  data?: unknown;
@@ -5,6 +5,7 @@ import { type TaskSimpleMode } from "./simple-mode";
5
5
  import type { NestedRepoPatch } from "./worktree";
6
6
  /** Source of an agent definition */
7
7
  export type AgentSource = "bundled" | "user" | "project";
8
+ export type ForkContextPolicy = "forbidden" | "allowed";
8
9
  /** Maximum output bytes per agent */
9
10
  export declare const MAX_OUTPUT_BYTES: number;
10
11
  /** Maximum output lines per agent */
@@ -40,6 +41,7 @@ export declare const taskItemSchema: z.ZodObject<{
40
41
  id: z.ZodString;
41
42
  description: z.ZodString;
42
43
  assignment: z.ZodString;
44
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
43
45
  }, z.core.$strip>;
44
46
  export type TaskItem = z.infer<typeof taskItemSchema>;
45
47
  export declare const taskSchema: z.ZodObject<{
@@ -48,6 +50,7 @@ export declare const taskSchema: z.ZodObject<{
48
50
  id: z.ZodString;
49
51
  description: z.ZodString;
50
52
  assignment: z.ZodString;
53
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
51
54
  }, z.core.$strip>>;
52
55
  }, z.core.$strip>;
53
56
  export declare const taskSchemaNoIsolation: z.ZodObject<{
@@ -56,6 +59,7 @@ export declare const taskSchemaNoIsolation: z.ZodObject<{
56
59
  id: z.ZodString;
57
60
  description: z.ZodString;
58
61
  assignment: z.ZodString;
62
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
59
63
  }, z.core.$strip>>;
60
64
  }, z.core.$strip>;
61
65
  declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
@@ -64,6 +68,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
64
68
  id: z.ZodString;
65
69
  description: z.ZodString;
66
70
  assignment: z.ZodString;
71
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
67
72
  }, z.core.$strip>>;
68
73
  }, z.core.$strip>, z.ZodObject<{
69
74
  agent: z.ZodString;
@@ -71,6 +76,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
71
76
  id: z.ZodString;
72
77
  description: z.ZodString;
73
78
  assignment: z.ZodString;
79
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
74
80
  }, z.core.$strip>>;
75
81
  }, z.core.$strip>, z.ZodObject<{
76
82
  agent: z.ZodString;
@@ -78,6 +84,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
78
84
  id: z.ZodString;
79
85
  description: z.ZodString;
80
86
  assignment: z.ZodString;
87
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
81
88
  }, z.core.$strip>>;
82
89
  }, z.core.$strip>, z.ZodObject<{
83
90
  agent: z.ZodString;
@@ -85,6 +92,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
85
92
  id: z.ZodString;
86
93
  description: z.ZodString;
87
94
  assignment: z.ZodString;
95
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
88
96
  }, z.core.$strip>>;
89
97
  }, z.core.$strip>, z.ZodObject<{
90
98
  agent: z.ZodString;
@@ -92,6 +100,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
92
100
  id: z.ZodString;
93
101
  description: z.ZodString;
94
102
  assignment: z.ZodString;
103
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
95
104
  }, z.core.$strip>>;
96
105
  }, z.core.$strip>, z.ZodObject<{
97
106
  agent: z.ZodString;
@@ -99,6 +108,7 @@ declare const ALL_TASK_SCHEMAS: readonly [z.ZodObject<{
99
108
  id: z.ZodString;
100
109
  description: z.ZodString;
101
110
  assignment: z.ZodString;
111
+ inheritContext: z.ZodOptional<z.ZodBoolean>;
102
112
  }, z.core.$strip>>;
103
113
  }, z.core.$strip>];
104
114
  type DynamicTaskSchema = (typeof ALL_TASK_SCHEMAS)[number];
@@ -150,6 +160,7 @@ export interface AgentDefinition {
150
160
  blocking?: boolean;
151
161
  autoloadSkills?: string[];
152
162
  hide?: boolean;
163
+ forkContext?: ForkContextPolicy;
153
164
  source: AgentSource;
154
165
  filePath?: string;
155
166
  }
@@ -1,5 +1,5 @@
1
1
  import type { AgentTelemetryConfig, AgentTool } from "@gajae-code/agent-core";
2
- import type { ToolChoice } from "@gajae-code/ai";
2
+ import type { Model, ToolChoice } from "@gajae-code/ai";
3
3
  import type { PromptTemplate } from "../config/prompt-templates";
4
4
  import type { Settings } from "../config/settings";
5
5
  import type { Skill } from "../extensibility/skills";
@@ -7,10 +7,12 @@ import type { GoalModeState, GoalRuntime } from "../goals";
7
7
  import type { HindsightSessionState } from "../hindsight/state";
8
8
  import type { PlanModeState } from "../plan-mode/state";
9
9
  import type { AgentRegistry } from "../registry/agent-registry";
10
+ import type { ForkContextSeed, ForkContextSeedOptions } from "../session/agent-session";
10
11
  import type { ArtifactManager } from "../session/artifacts";
11
12
  import type { ClientBridge } from "../session/client-bridge";
12
13
  import type { CustomMessage } from "../session/messages";
13
14
  import type { ToolChoiceQueue } from "../session/tool-choice-queue";
15
+ import type { SkillActiveEntry } from "../skill-state/active-state";
14
16
  import type { AgentOutputManager } from "../task/output-manager";
15
17
  import type { DiscoverableTool, DiscoverableToolSearchIndex } from "../tool-discovery/tool-index";
16
18
  import type { EventBus } from "../utils/event-bus";
@@ -48,6 +50,7 @@ export * from "./resolve";
48
50
  export * from "./review";
49
51
  export * from "./search";
50
52
  export * from "./search-tool-bm25";
53
+ export * from "./skill";
51
54
  export * from "./ssh";
52
55
  export * from "./subagent";
53
56
  export * from "./todo-write";
@@ -77,6 +80,12 @@ export interface ToolSession {
77
80
  workspaceTree?: WorkspaceTree;
78
81
  /** Pre-loaded skills */
79
82
  skills?: Skill[];
83
+ /** Currently executing skill prompt, when this tool session is inside one. */
84
+ getActiveSkillState?: () => Pick<SkillActiveEntry, "skill" | "session_id"> | undefined;
85
+ /** Get the active skill prompt's current phase so the skill tool can apply
86
+ * its terminal-phase chain guard. Returns the raw phase string or undefined
87
+ * when no active skill (or accessor) is available. */
88
+ getActiveSkillPhase?: () => string | undefined;
80
89
  /** Pre-loaded prompt templates */
81
90
  promptTemplates?: PromptTemplate[];
82
91
  /** Whether LSP integrations are enabled */
@@ -122,6 +131,8 @@ export interface ToolSession {
122
131
  getSessionSpawns: () => string | null;
123
132
  /** Get resolved model string if explicitly set for this session */
124
133
  getModelString?: () => string | undefined;
134
+ /** Current model, when selected. */
135
+ model?: Model;
125
136
  /** Get the current session model string, regardless of how it was chosen */
126
137
  getActiveModelString?: () => string | undefined;
127
138
  /** Auth storage for passing to subagents (avoids re-discovery) */
@@ -204,9 +215,17 @@ export interface ToolSession {
204
215
  conflictHistory?: import("./conflict-detect").ConflictHistory;
205
216
  /** Queue a hidden message to be injected at the next agent turn. */
206
217
  queueDeferredMessage?(message: CustomMessage): void;
218
+ /** Dispatch a custom message through the active session. Used by the `skill`
219
+ * tool to dispatch another skill prompt same-turn after recording a handoff. */
220
+ sendCustomMessage?(message: Pick<CustomMessage, "customType" | "content" | "display" | "details" | "attribution">, options?: {
221
+ triggerTurn?: boolean;
222
+ deliverAs?: "steer" | "followUp" | "nextTurn";
223
+ }): Promise<void>;
207
224
  /** Get the active OpenTelemetry config so subagent dispatch can forward
208
225
  * the parent's tracer/hooks with the subagent's own identity stamped. */
209
226
  getTelemetry?: () => AgentTelemetryConfig | undefined;
227
+ /** Build a sanitized fork-context seed for task subagents. */
228
+ buildForkContextSeed?: (options: ForkContextSeedOptions) => Promise<ForkContextSeed>;
210
229
  }
211
230
  export type ToolFactory = (session: ToolSession) => Tool | null | Promise<Tool | null>;
212
231
  export type BuiltinToolLoadMode = "essential" | "discoverable";
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Skill Tool — agent-initiated skill chaining.
3
+ *
4
+ * Lets the agent hand off to another available skill in the current turn. The
5
+ * callee's SKILL.md is dispatched through the same custom-message path used by
6
+ * `/skill:<name>` typing, as a user-attribution message delivered same-turn
7
+ * (without `deliverAs: "nextTurn"`). Before dispatch, the tool calls
8
+ * `gjc state <caller> handoff --to <callee>` in-process via the state-runtime
9
+ * function so caller and callee mode-states plus `skill-active-state.json`
10
+ * transition atomically.
11
+ *
12
+ * Chaining is refused unless the caller's `current_phase` is in
13
+ * `{complete, completed, handoff, failed, cancelled, canceled, inactive}`. The
14
+ * agent declares readiness either by writing `current_phase: "handoff"` to its
15
+ * mode-state or by running the handoff verb directly.
16
+ */
17
+ import type { AgentTool, AgentToolResult } from "@gajae-code/agent-core";
18
+ import * as z from "zod/v4";
19
+ import type { ToolSession } from ".";
20
+ declare const skillSchema: z.ZodObject<{
21
+ name: z.ZodString;
22
+ args: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strip>;
24
+ type SkillToolInput = z.infer<typeof skillSchema>;
25
+ export interface SkillToolDetails {
26
+ name: string;
27
+ path: string;
28
+ args?: string;
29
+ lineCount: number;
30
+ }
31
+ export declare class SkillTool implements AgentTool<typeof skillSchema, SkillToolDetails> {
32
+ #private;
33
+ readonly name = "skill";
34
+ readonly label = "Skill";
35
+ readonly summary = "Chain into another available skill in the current turn";
36
+ readonly loadMode = "discoverable";
37
+ readonly description: string;
38
+ readonly parameters: z.ZodObject<{
39
+ name: z.ZodString;
40
+ args: z.ZodOptional<z.ZodString>;
41
+ }, z.core.$strip>;
42
+ readonly strict = true;
43
+ constructor(session: ToolSession);
44
+ static createIf(session: ToolSession): SkillTool | null;
45
+ execute(_toolCallId: string, input: SkillToolInput, signal?: AbortSignal): Promise<AgentToolResult<SkillToolDetails>>;
46
+ }
47
+ export {};
@@ -5,10 +5,26 @@ export interface ChangelogEntry {
5
5
  content: string;
6
6
  }
7
7
  /**
8
- * Parse changelog entries from CHANGELOG.md
9
- * Scans for ## lines and collects content until next ## or EOF
8
+ * Parse changelog entries from a CHANGELOG.md text body.
9
+ * Scans for ## lines and collects content until next ## or EOF.
10
+ * Pure and synchronous so it can be reused by the embedded display path.
11
+ */
12
+ export declare function parseChangelogContent(content: string): ChangelogEntry[];
13
+ /**
14
+ * Parse changelog entries from a CHANGELOG.md file on disk.
15
+ * Returns [] on ENOENT; logs and returns [] on other read/parse errors.
10
16
  */
11
17
  export declare function parseChangelog(changelogPath: string): Promise<ChangelogEntry[]>;
18
+ /**
19
+ * Return changelog entries from the CHANGELOG.md that shipped with this binary.
20
+ *
21
+ * The text is embedded at build time via `with { type: "text" }`, so the
22
+ * displayed changelog is deterministic across compiled binaries, source-tree
23
+ * dev runs, and `GJC_PACKAGE_DIR` / `PI_PACKAGE_DIR` overrides (which scope to
24
+ * optional package assets like docs/examples and do not influence the
25
+ * binary-identity changelog).
26
+ */
27
+ export declare function getDisplayChangelogEntries(): ChangelogEntry[];
12
28
  /**
13
29
  * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
14
30
  */
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.1",
4
+ "version": "0.2.3",
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.1",
52
- "@gajae-code/agent-core": "0.2.1",
53
- "@gajae-code/ai": "0.2.1",
54
- "@gajae-code/natives": "0.2.1",
55
- "@gajae-code/tui": "0.2.1",
56
- "@gajae-code/utils": "0.2.1",
51
+ "@gajae-code/stats": "0.2.3",
52
+ "@gajae-code/agent-core": "0.2.3",
53
+ "@gajae-code/ai": "0.2.3",
54
+ "@gajae-code/natives": "0.2.3",
55
+ "@gajae-code/tui": "0.2.3",
56
+ "@gajae-code/utils": "0.2.3",
57
57
  "@puppeteer/browsers": "^2.13.0",
58
58
  "@types/turndown": "5.0.6",
59
59
  "@xterm/headless": "^6.0.0",
package/src/cli/args.ts CHANGED
@@ -245,9 +245,10 @@ export function getExtraHelpText(): string {
245
245
  GJC_SLOW_MODEL - Override slow/reasoning model (see --slow)
246
246
  GJC_PLAN_MODEL - Override planning model (see --plan)
247
247
  GJC_NO_PTY - Disable PTY-based interactive bash execution
248
- --tmux - Launch interactive startup inside tmux
248
+ --tmux - Launch interactive startup inside a new tmux session
249
+ gjc session - List, inspect, create, remove, or attach tagged GJC-managed tmux sessions
249
250
  GJC_LAUNCH_POLICY - Launch policy for --tmux startup: tmux or direct
250
- GJC_TMUX_SESSION - tmux session name for default interactive startup (default: gajae_code)
251
+ GJC_TMUX_SESSION - Explicit tmux session name override for --tmux startup
251
252
 
252
253
  For complete environment variable reference, see:
253
254
  ${chalk.dim("docs/environment-variables.md")}