@gajae-code/coding-agent 0.2.4 → 0.3.0

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 (266) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +1 -1
  3. package/dist/types/async/job-manager.d.ts +145 -2
  4. package/dist/types/commands/harness.d.ts +37 -0
  5. package/dist/types/config/settings-schema.d.ts +13 -3
  6. package/dist/types/config/settings.d.ts +3 -1
  7. package/dist/types/deep-interview/render-middleware.d.ts +5 -0
  8. package/dist/types/discovery/helpers.d.ts +1 -0
  9. package/dist/types/exec/bash-executor.d.ts +8 -1
  10. package/dist/types/extensibility/custom-tools/types.d.ts +1 -0
  11. package/dist/types/extensibility/extensions/types.d.ts +6 -0
  12. package/dist/types/extensibility/shared-events.d.ts +1 -0
  13. package/dist/types/gjc-runtime/restricted-role-agent-bash.d.ts +2 -0
  14. package/dist/types/gjc-runtime/state-graph.d.ts +4 -0
  15. package/dist/types/gjc-runtime/state-migrations.d.ts +24 -0
  16. package/dist/types/gjc-runtime/state-renderer.d.ts +65 -0
  17. package/dist/types/gjc-runtime/state-runtime.d.ts +2 -0
  18. package/dist/types/gjc-runtime/state-validation.d.ts +6 -0
  19. package/dist/types/gjc-runtime/state-writer.d.ts +137 -0
  20. package/dist/types/gjc-runtime/team-runtime.d.ts +81 -7
  21. package/dist/types/gjc-runtime/workflow-manifest.d.ts +54 -0
  22. package/dist/types/harness-control-plane/classifier.d.ts +13 -0
  23. package/dist/types/harness-control-plane/control-endpoint.d.ts +30 -0
  24. package/dist/types/harness-control-plane/finalize.d.ts +47 -0
  25. package/dist/types/harness-control-plane/frame-mapper.d.ts +29 -0
  26. package/dist/types/harness-control-plane/operate.d.ts +35 -0
  27. package/dist/types/harness-control-plane/owner.d.ts +46 -0
  28. package/dist/types/harness-control-plane/preserve.d.ts +19 -0
  29. package/dist/types/harness-control-plane/receipts.d.ts +88 -0
  30. package/dist/types/harness-control-plane/rpc-adapter.d.ts +66 -0
  31. package/dist/types/harness-control-plane/seams.d.ts +21 -0
  32. package/dist/types/harness-control-plane/session-lease.d.ts +65 -0
  33. package/dist/types/harness-control-plane/state-machine.d.ts +19 -0
  34. package/dist/types/harness-control-plane/storage.d.ts +53 -0
  35. package/dist/types/harness-control-plane/types.d.ts +162 -0
  36. package/dist/types/hooks/skill-keywords.d.ts +2 -1
  37. package/dist/types/hooks/skill-state.d.ts +2 -29
  38. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -1
  39. package/dist/types/modes/components/hook-selector.d.ts +1 -0
  40. package/dist/types/modes/components/skill-hud/render.d.ts +1 -1
  41. package/dist/types/modes/interactive-mode.d.ts +2 -0
  42. package/dist/types/modes/theme/defaults/index.d.ts +45 -9477
  43. package/dist/types/modes/theme/theme.d.ts +1 -5
  44. package/dist/types/modes/types.d.ts +2 -0
  45. package/dist/types/sdk.d.ts +4 -0
  46. package/dist/types/session/agent-session.d.ts +8 -0
  47. package/dist/types/session/streaming-output.d.ts +11 -0
  48. package/dist/types/skill-state/active-state.d.ts +3 -0
  49. package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +1 -1
  50. package/dist/types/skill-state/workflow-state-contract.d.ts +24 -0
  51. package/dist/types/task/executor.d.ts +3 -0
  52. package/dist/types/task/types.d.ts +56 -3
  53. package/dist/types/tools/bash-allowed-prefixes.d.ts +5 -0
  54. package/dist/types/tools/bash.d.ts +24 -0
  55. package/dist/types/tools/cron.d.ts +110 -0
  56. package/dist/types/tools/index.d.ts +4 -0
  57. package/dist/types/tools/monitor.d.ts +54 -0
  58. package/dist/types/tools/subagent.d.ts +11 -1
  59. package/dist/types/web/search/index.d.ts +1 -0
  60. package/dist/types/web/search/provider.d.ts +11 -4
  61. package/dist/types/web/search/providers/duckduckgo.d.ts +57 -0
  62. package/dist/types/web/search/types.d.ts +1 -1
  63. package/package.json +7 -7
  64. package/src/async/job-manager.ts +522 -6
  65. package/src/cli/agents-cli.ts +3 -0
  66. package/src/cli/auth-broker-cli.ts +1 -0
  67. package/src/cli/config-cli.ts +10 -2
  68. package/src/cli.ts +2 -0
  69. package/src/commands/harness.ts +592 -0
  70. package/src/commands/team.ts +36 -39
  71. package/src/config/settings-schema.ts +15 -2
  72. package/src/config/settings.ts +49 -7
  73. package/src/deep-interview/render-middleware.ts +366 -0
  74. package/src/defaults/gjc/skills/deep-interview/SKILL.md +9 -2
  75. package/src/defaults/gjc/skills/ralplan/SKILL.md +8 -4
  76. package/src/defaults/gjc/skills/team/SKILL.md +47 -21
  77. package/src/defaults/gjc/skills/ultragoal/SKILL.md +78 -11
  78. package/src/discovery/helpers.ts +5 -0
  79. package/src/eval/js/shared/rewrite-imports.ts +1 -2
  80. package/src/exec/bash-executor.ts +20 -9
  81. package/src/extensibility/custom-tools/types.ts +1 -0
  82. package/src/extensibility/extensions/types.ts +6 -0
  83. package/src/extensibility/shared-events.ts +1 -0
  84. package/src/gjc-runtime/deep-interview-runtime.ts +40 -21
  85. package/src/gjc-runtime/goal-mode-request.ts +11 -3
  86. package/src/gjc-runtime/ralplan-runtime.ts +27 -10
  87. package/src/gjc-runtime/restricted-role-agent-bash.ts +5 -0
  88. package/src/gjc-runtime/state-graph.ts +86 -0
  89. package/src/gjc-runtime/state-migrations.ts +132 -0
  90. package/src/gjc-runtime/state-renderer.ts +345 -0
  91. package/src/gjc-runtime/state-runtime.ts +733 -21
  92. package/src/gjc-runtime/state-validation.ts +49 -0
  93. package/src/gjc-runtime/state-writer.ts +718 -0
  94. package/src/gjc-runtime/team-runtime.ts +1083 -89
  95. package/src/gjc-runtime/ultragoal-runtime.ts +348 -19
  96. package/src/gjc-runtime/workflow-manifest.generated.json +1497 -0
  97. package/src/gjc-runtime/workflow-manifest.ts +425 -0
  98. package/src/harness-control-plane/classifier.ts +128 -0
  99. package/src/harness-control-plane/control-endpoint.ts +137 -0
  100. package/src/harness-control-plane/finalize.ts +222 -0
  101. package/src/harness-control-plane/frame-mapper.ts +286 -0
  102. package/src/harness-control-plane/operate.ts +225 -0
  103. package/src/harness-control-plane/owner.ts +553 -0
  104. package/src/harness-control-plane/preserve.ts +102 -0
  105. package/src/harness-control-plane/receipts.ts +216 -0
  106. package/src/harness-control-plane/rpc-adapter.ts +276 -0
  107. package/src/harness-control-plane/seams.ts +39 -0
  108. package/src/harness-control-plane/session-lease.ts +388 -0
  109. package/src/harness-control-plane/state-machine.ts +97 -0
  110. package/src/harness-control-plane/storage.ts +257 -0
  111. package/src/harness-control-plane/types.ts +214 -0
  112. package/src/hooks/skill-keywords.ts +4 -2
  113. package/src/hooks/skill-state.ts +25 -42
  114. package/src/internal-urls/docs-index.generated.ts +6 -4
  115. package/src/lsp/render.ts +1 -1
  116. package/src/modes/acp/acp-agent.ts +1 -1
  117. package/src/modes/acp/acp-client-bridge.ts +1 -1
  118. package/src/modes/components/agent-dashboard.ts +1 -1
  119. package/src/modes/components/assistant-message.ts +5 -1
  120. package/src/modes/components/diff.ts +2 -2
  121. package/src/modes/components/hook-selector.ts +72 -2
  122. package/src/modes/components/skill-hud/render.ts +7 -2
  123. package/src/modes/controllers/event-controller.ts +71 -6
  124. package/src/modes/controllers/extension-ui-controller.ts +6 -0
  125. package/src/modes/controllers/input-controller.ts +19 -3
  126. package/src/modes/controllers/selector-controller.ts +3 -2
  127. package/src/modes/interactive-mode.ts +21 -2
  128. package/src/modes/theme/defaults/index.ts +0 -196
  129. package/src/modes/theme/theme.ts +35 -35
  130. package/src/modes/types.ts +2 -0
  131. package/src/prompts/agents/architect.md +5 -1
  132. package/src/prompts/agents/critic.md +5 -1
  133. package/src/prompts/agents/executor.md +13 -0
  134. package/src/prompts/agents/frontmatter.md +1 -0
  135. package/src/prompts/agents/planner.md +5 -1
  136. package/src/prompts/tools/bash.md +9 -0
  137. package/src/prompts/tools/cron.md +25 -0
  138. package/src/prompts/tools/monitor.md +30 -0
  139. package/src/prompts/tools/subagent.md +33 -3
  140. package/src/runtime-mcp/oauth-flow.ts +4 -2
  141. package/src/sdk.ts +7 -0
  142. package/src/session/agent-session.ts +247 -38
  143. package/src/session/session-manager.ts +13 -1
  144. package/src/session/streaming-output.ts +21 -0
  145. package/src/skill-state/active-state.ts +222 -78
  146. package/src/skill-state/deep-interview-mutation-guard.ts +91 -13
  147. package/src/skill-state/initial-phase.ts +2 -0
  148. package/src/skill-state/workflow-state-contract.ts +26 -0
  149. package/src/task/agents.ts +1 -0
  150. package/src/task/executor.ts +51 -8
  151. package/src/task/index.ts +120 -8
  152. package/src/task/render.ts +6 -3
  153. package/src/task/types.ts +57 -3
  154. package/src/tools/ask.ts +28 -7
  155. package/src/tools/bash-allowed-prefixes.ts +169 -0
  156. package/src/tools/bash.ts +190 -29
  157. package/src/tools/browser/tab-worker.ts +1 -1
  158. package/src/tools/cron.ts +665 -0
  159. package/src/tools/index.ts +20 -2
  160. package/src/tools/monitor.ts +136 -0
  161. package/src/tools/subagent.ts +255 -64
  162. package/src/vim/engine.ts +3 -3
  163. package/src/web/search/index.ts +31 -18
  164. package/src/web/search/provider.ts +57 -12
  165. package/src/web/search/providers/duckduckgo.ts +279 -0
  166. package/src/web/search/types.ts +2 -0
  167. package/src/modes/theme/dark.json +0 -95
  168. package/src/modes/theme/defaults/alabaster.json +0 -93
  169. package/src/modes/theme/defaults/amethyst.json +0 -96
  170. package/src/modes/theme/defaults/anthracite.json +0 -93
  171. package/src/modes/theme/defaults/basalt.json +0 -91
  172. package/src/modes/theme/defaults/birch.json +0 -95
  173. package/src/modes/theme/defaults/dark-abyss.json +0 -91
  174. package/src/modes/theme/defaults/dark-arctic.json +0 -104
  175. package/src/modes/theme/defaults/dark-aurora.json +0 -95
  176. package/src/modes/theme/defaults/dark-catppuccin.json +0 -107
  177. package/src/modes/theme/defaults/dark-cavern.json +0 -91
  178. package/src/modes/theme/defaults/dark-copper.json +0 -95
  179. package/src/modes/theme/defaults/dark-cosmos.json +0 -90
  180. package/src/modes/theme/defaults/dark-cyberpunk.json +0 -102
  181. package/src/modes/theme/defaults/dark-dracula.json +0 -98
  182. package/src/modes/theme/defaults/dark-eclipse.json +0 -91
  183. package/src/modes/theme/defaults/dark-ember.json +0 -95
  184. package/src/modes/theme/defaults/dark-equinox.json +0 -90
  185. package/src/modes/theme/defaults/dark-forest.json +0 -96
  186. package/src/modes/theme/defaults/dark-github.json +0 -105
  187. package/src/modes/theme/defaults/dark-gruvbox.json +0 -112
  188. package/src/modes/theme/defaults/dark-lavender.json +0 -95
  189. package/src/modes/theme/defaults/dark-lunar.json +0 -89
  190. package/src/modes/theme/defaults/dark-midnight.json +0 -95
  191. package/src/modes/theme/defaults/dark-monochrome.json +0 -94
  192. package/src/modes/theme/defaults/dark-monokai.json +0 -98
  193. package/src/modes/theme/defaults/dark-nebula.json +0 -90
  194. package/src/modes/theme/defaults/dark-nord.json +0 -97
  195. package/src/modes/theme/defaults/dark-ocean.json +0 -101
  196. package/src/modes/theme/defaults/dark-one.json +0 -100
  197. package/src/modes/theme/defaults/dark-poimandres.json +0 -141
  198. package/src/modes/theme/defaults/dark-rainforest.json +0 -91
  199. package/src/modes/theme/defaults/dark-reef.json +0 -91
  200. package/src/modes/theme/defaults/dark-retro.json +0 -92
  201. package/src/modes/theme/defaults/dark-rose-pine.json +0 -96
  202. package/src/modes/theme/defaults/dark-sakura.json +0 -95
  203. package/src/modes/theme/defaults/dark-slate.json +0 -95
  204. package/src/modes/theme/defaults/dark-solarized.json +0 -97
  205. package/src/modes/theme/defaults/dark-solstice.json +0 -90
  206. package/src/modes/theme/defaults/dark-starfall.json +0 -91
  207. package/src/modes/theme/defaults/dark-sunset.json +0 -99
  208. package/src/modes/theme/defaults/dark-swamp.json +0 -90
  209. package/src/modes/theme/defaults/dark-synthwave.json +0 -103
  210. package/src/modes/theme/defaults/dark-taiga.json +0 -91
  211. package/src/modes/theme/defaults/dark-terminal.json +0 -95
  212. package/src/modes/theme/defaults/dark-tokyo-night.json +0 -101
  213. package/src/modes/theme/defaults/dark-tundra.json +0 -91
  214. package/src/modes/theme/defaults/dark-twilight.json +0 -91
  215. package/src/modes/theme/defaults/dark-volcanic.json +0 -91
  216. package/src/modes/theme/defaults/graphite.json +0 -92
  217. package/src/modes/theme/defaults/light-arctic.json +0 -107
  218. package/src/modes/theme/defaults/light-aurora-day.json +0 -91
  219. package/src/modes/theme/defaults/light-canyon.json +0 -91
  220. package/src/modes/theme/defaults/light-catppuccin.json +0 -106
  221. package/src/modes/theme/defaults/light-cirrus.json +0 -90
  222. package/src/modes/theme/defaults/light-coral.json +0 -95
  223. package/src/modes/theme/defaults/light-cyberpunk.json +0 -96
  224. package/src/modes/theme/defaults/light-dawn.json +0 -90
  225. package/src/modes/theme/defaults/light-dunes.json +0 -91
  226. package/src/modes/theme/defaults/light-eucalyptus.json +0 -95
  227. package/src/modes/theme/defaults/light-forest.json +0 -100
  228. package/src/modes/theme/defaults/light-frost.json +0 -95
  229. package/src/modes/theme/defaults/light-github.json +0 -115
  230. package/src/modes/theme/defaults/light-glacier.json +0 -91
  231. package/src/modes/theme/defaults/light-gruvbox.json +0 -108
  232. package/src/modes/theme/defaults/light-haze.json +0 -90
  233. package/src/modes/theme/defaults/light-honeycomb.json +0 -95
  234. package/src/modes/theme/defaults/light-lagoon.json +0 -91
  235. package/src/modes/theme/defaults/light-lavender.json +0 -95
  236. package/src/modes/theme/defaults/light-meadow.json +0 -91
  237. package/src/modes/theme/defaults/light-mint.json +0 -95
  238. package/src/modes/theme/defaults/light-monochrome.json +0 -101
  239. package/src/modes/theme/defaults/light-ocean.json +0 -99
  240. package/src/modes/theme/defaults/light-one.json +0 -99
  241. package/src/modes/theme/defaults/light-opal.json +0 -91
  242. package/src/modes/theme/defaults/light-orchard.json +0 -91
  243. package/src/modes/theme/defaults/light-paper.json +0 -95
  244. package/src/modes/theme/defaults/light-poimandres.json +0 -141
  245. package/src/modes/theme/defaults/light-prism.json +0 -90
  246. package/src/modes/theme/defaults/light-retro.json +0 -98
  247. package/src/modes/theme/defaults/light-sand.json +0 -95
  248. package/src/modes/theme/defaults/light-savanna.json +0 -91
  249. package/src/modes/theme/defaults/light-solarized.json +0 -102
  250. package/src/modes/theme/defaults/light-soleil.json +0 -90
  251. package/src/modes/theme/defaults/light-sunset.json +0 -99
  252. package/src/modes/theme/defaults/light-synthwave.json +0 -98
  253. package/src/modes/theme/defaults/light-tokyo-night.json +0 -111
  254. package/src/modes/theme/defaults/light-wetland.json +0 -91
  255. package/src/modes/theme/defaults/light-zenith.json +0 -89
  256. package/src/modes/theme/defaults/limestone.json +0 -94
  257. package/src/modes/theme/defaults/mahogany.json +0 -97
  258. package/src/modes/theme/defaults/marble.json +0 -93
  259. package/src/modes/theme/defaults/obsidian.json +0 -91
  260. package/src/modes/theme/defaults/onyx.json +0 -91
  261. package/src/modes/theme/defaults/pearl.json +0 -93
  262. package/src/modes/theme/defaults/porcelain.json +0 -91
  263. package/src/modes/theme/defaults/quartz.json +0 -96
  264. package/src/modes/theme/defaults/sandstone.json +0 -95
  265. package/src/modes/theme/defaults/titanium.json +0 -90
  266. package/src/modes/theme/light.json +0 -93
@@ -0,0 +1,137 @@
1
+ import * as fs from "node:fs/promises";
2
+ import type { SkillActiveEntry } from "../skill-state/active-state";
3
+ import { type AuditEntry, type CanonicalGjcWorkflowSkill, type WorkflowStateMutationOwner } from "../skill-state/workflow-state-contract";
4
+ /**
5
+ * Sole sanctioned project `.gjc/**` writer module (gate G1).
6
+ *
7
+ * All native `.gjc/**` filesystem mutations must route through these primitives.
8
+ * The primitives validate project `.gjc/**` ownership, create parent directories,
9
+ * and emit workflow receipts or audit entries where applicable by the caller's
10
+ * supplied mutation context. No lockfiles are used; isolation is by atomic rename,
11
+ * append, O_EXCL creates, conditional deletes, per-entry active-state files,
12
+ * and derived active-state snapshots.
13
+ * Transaction journals are per mutation id under `.gjc/state/transactions/`;
14
+ * they are recovery evidence only, never global locks or waiters, so stale
15
+ * journals do not block unrelated state reads or writes.
16
+ */
17
+ export type WriterCategory = "state" | "artifact" | "ledger" | "log" | "report" | "agents" | "prune" | "force" | "transaction";
18
+ export interface StateWriterReceiptContext {
19
+ cwd?: string;
20
+ skill: CanonicalGjcWorkflowSkill;
21
+ owner: WorkflowStateMutationOwner;
22
+ command: string;
23
+ sessionId?: string;
24
+ mutationId?: string;
25
+ nowIso?: string;
26
+ }
27
+ export interface StateWriterAuditContext {
28
+ cwd?: string;
29
+ category: WriterCategory;
30
+ verb: string;
31
+ owner: WorkflowStateMutationOwner;
32
+ skill?: CanonicalGjcWorkflowSkill | string;
33
+ mutationId?: string;
34
+ fromPhase?: string;
35
+ toPhase?: string;
36
+ forced?: boolean;
37
+ }
38
+ export interface WorkflowEnvelopeIntegrityMismatch {
39
+ path: string;
40
+ expected: string;
41
+ actual: string;
42
+ }
43
+ export interface WorkflowTransactionJournal {
44
+ version: 1;
45
+ mutation_id: string;
46
+ status: "pending" | "committed";
47
+ created_at: string;
48
+ updated_at: string;
49
+ caller?: CanonicalGjcWorkflowSkill;
50
+ callee?: CanonicalGjcWorkflowSkill;
51
+ paths: string[];
52
+ steps: string[];
53
+ }
54
+ export interface StateWriterOptions {
55
+ cwd?: string;
56
+ receipt?: StateWriterReceiptContext;
57
+ audit?: StateWriterAuditContext;
58
+ }
59
+ export interface DeleteIfOwnedOptions extends StateWriterOptions {
60
+ predicate?: (current: unknown) => boolean | Promise<boolean>;
61
+ }
62
+ export interface DeleteResult {
63
+ path: string;
64
+ deleted: boolean;
65
+ }
66
+ export interface ActiveSessionScope {
67
+ sessionId?: string;
68
+ }
69
+ export interface ActiveEntryWriteResult {
70
+ entryPath: string;
71
+ snapshotPath: string;
72
+ }
73
+ export interface HardPruneSelectorContext {
74
+ path: string;
75
+ value: unknown;
76
+ }
77
+ export interface GenericHardPruneTarget {
78
+ path: string;
79
+ category: WriterCategory | string;
80
+ }
81
+ export interface GenericHardPruneSelectorContext {
82
+ path: string;
83
+ category: WriterCategory | string;
84
+ stat: Awaited<ReturnType<typeof fs.stat>>;
85
+ readJson: () => Promise<unknown>;
86
+ }
87
+ export type GenericHardPruneSelector = (context: GenericHardPruneSelectorContext) => boolean | Promise<boolean>;
88
+ export interface ForceOverwriteOptions extends StateWriterOptions {
89
+ raw?: boolean;
90
+ }
91
+ export type HardPruneSelector = (context: HardPruneSelectorContext) => boolean | Promise<boolean>;
92
+ export declare class AlreadyExistsError extends Error {
93
+ readonly path: string;
94
+ constructor(path: string);
95
+ }
96
+ export declare function workflowEnvelopeContentSha256(value: unknown): string;
97
+ export declare function stampWorkflowEnvelopeChecksum<T>(value: T, filePath: string, computedAt?: string): T;
98
+ export declare function detectWorkflowEnvelopeIntegrityMismatch(filePath: string): Promise<WorkflowEnvelopeIntegrityMismatch | undefined>;
99
+ export declare function writeJsonAtomic(targetPath: string, value: unknown, options?: StateWriterOptions): Promise<string>;
100
+ export declare function writeWorkflowEnvelopeAtomic(targetPath: string, value: unknown, options?: StateWriterOptions): Promise<string>;
101
+ export declare function writeTextAtomic(targetPath: string, text: string, options?: StateWriterOptions): Promise<string>;
102
+ export declare function updateJsonAtomic<T = unknown>(targetPath: string, mutator: (current: T | undefined) => T | Promise<T>, options?: StateWriterOptions): Promise<string>;
103
+ export declare function appendJsonl(targetPath: string, entry: unknown, options?: StateWriterOptions): Promise<string>;
104
+ export declare function appendText(targetPath: string, text: string, options?: StateWriterOptions): Promise<string>;
105
+ export declare function createJsonNoClobber(targetPath: string, value: unknown, options?: StateWriterOptions): Promise<string>;
106
+ export declare function deleteIfOwned(targetPath: string, predicateOrOptions?: ((current: unknown) => boolean | Promise<boolean>) | DeleteIfOwnedOptions): Promise<DeleteResult>;
107
+ export declare function removeFileAudited(targetPath: string, options?: StateWriterOptions): Promise<DeleteResult>;
108
+ /**
109
+ * Active entry files under `.gjc/state/active/<skill>.json` and
110
+ * `.gjc/state/sessions/<id>/active/<skill>.json` are authoritative. The
111
+ * adjacent `skill-active-state.json` file is only a derived cache rebuilt from
112
+ * those entries, so concurrent snapshot rebuilds can race without losing any
113
+ * writer's per-skill state.
114
+ */
115
+ export declare function writeActiveEntry(cwd: string, sessionScope: string | ActiveSessionScope | undefined, skill: string, entry: SkillActiveEntry, options?: StateWriterOptions): Promise<string>;
116
+ export declare function removeActiveEntry(cwd: string, sessionScope: string | ActiveSessionScope | undefined, skill: string, options?: StateWriterOptions): Promise<DeleteResult>;
117
+ export declare function readActiveEntries(cwd: string, sessionScope?: string | ActiveSessionScope): Promise<SkillActiveEntry[]>;
118
+ export declare function rebuildActiveSnapshot(cwd: string, sessionScope?: string | ActiveSessionScope, options?: StateWriterOptions): Promise<string>;
119
+ export declare function mergeActiveState(cwd: string, sessionScope: string | ActiveSessionScope | undefined, skill: string, entry: SkillActiveEntry, options?: StateWriterOptions): Promise<ActiveEntryWriteResult>;
120
+ export declare function writeArtifact(targetPath: string, content: string, options?: StateWriterOptions): Promise<string>;
121
+ export declare function writeReport(targetPath: string, content: string, options?: StateWriterOptions): Promise<string>;
122
+ export declare function writeLogJsonl(targetPath: string, entry: unknown, options?: StateWriterOptions): Promise<string>;
123
+ export declare function softDelete(targetPath: string, meta: Record<string, unknown>, options?: StateWriterOptions): Promise<string>;
124
+ export declare function hardPruneJson(targetPaths: readonly string[], selector: HardPruneSelector, options?: StateWriterOptions): Promise<string[]>;
125
+ export declare function hardPrune(targets: readonly GenericHardPruneTarget[], selector: GenericHardPruneSelector, options?: StateWriterOptions): Promise<string[]>;
126
+ export declare function forceOverwrite(targetPath: string, rawValue: unknown, options?: ForceOverwriteOptions): Promise<string>;
127
+ export declare function appendAuditEntry(cwd: string, entry: AuditEntry): Promise<string>;
128
+ export declare function readWorkflowTransactionJournal(cwd: string, mutationId: string): Promise<WorkflowTransactionJournal | undefined>;
129
+ export declare function beginWorkflowTransactionJournal(input: {
130
+ cwd: string;
131
+ mutationId: string;
132
+ caller?: CanonicalGjcWorkflowSkill;
133
+ callee?: CanonicalGjcWorkflowSkill;
134
+ paths: string[];
135
+ }): Promise<string>;
136
+ export declare function updateWorkflowTransactionJournal(cwd: string, mutationId: string, patch: Partial<WorkflowTransactionJournal>): Promise<string>;
137
+ export declare function completeWorkflowTransactionJournal(cwd: string, mutationId: string): Promise<void>;
@@ -2,6 +2,8 @@ import type { WorkflowHudSummary } from "../skill-state/active-state";
2
2
  export type GjcTeamPhase = "starting" | "running" | "awaiting_integration" | "complete" | "failed" | "cancelled";
3
3
  export type GjcTeamTaskStatus = "pending" | "blocked" | "in_progress" | "completed" | "failed";
4
4
  export type GjcWorkerStatusState = "idle" | "working" | "blocked" | "done" | "failed" | "draining" | "unknown";
5
+ export type GjcTeamWorkerLifecycleState = "starting" | "ready" | "working" | "draining" | "stopped" | "failed" | "unknown";
6
+ export type GjcTeamShutdownMode = "graceful" | "force" | "abort";
5
7
  export declare const GJC_TEAM_DEFAULT_WORKERS = 3;
6
8
  export declare const GJC_TEAM_MAX_WORKERS = 20;
7
9
  export type GjcTeamWorkerCli = "gjc";
@@ -33,6 +35,25 @@ export interface GjcTeamTaskClaim {
33
35
  token: string;
34
36
  leased_until: string;
35
37
  }
38
+ export type GjcTeamTaskCompletionEvidenceKind = "command" | "inspection" | "artifact";
39
+ export type GjcTeamTaskCompletionEvidenceStatus = "passed" | "failed" | "not_run" | "verified" | "rejected";
40
+ export interface GjcTeamTaskCompletionEvidenceItem {
41
+ kind: GjcTeamTaskCompletionEvidenceKind;
42
+ status: GjcTeamTaskCompletionEvidenceStatus;
43
+ summary: string;
44
+ command?: string;
45
+ artifact?: string;
46
+ location?: string;
47
+ output?: string;
48
+ }
49
+ export interface GjcTeamTaskCompletionEvidence {
50
+ summary: string;
51
+ items: GjcTeamTaskCompletionEvidenceItem[];
52
+ files?: string[];
53
+ notes?: string;
54
+ recorded_by: string;
55
+ recorded_at: string;
56
+ }
36
57
  export interface GjcTeamTask {
37
58
  id: string;
38
59
  subject: string;
@@ -43,9 +64,13 @@ export interface GjcTeamTask {
43
64
  assignee?: string;
44
65
  owner?: string;
45
66
  result?: string;
67
+ completion_evidence?: GjcTeamTaskCompletionEvidence;
46
68
  error?: string;
47
69
  blocked_by?: string[];
48
70
  depends_on?: string[];
71
+ lane?: string;
72
+ required_role?: string;
73
+ allowed_roles?: string[];
49
74
  version: number;
50
75
  claim?: GjcTeamTaskClaim;
51
76
  created_at: string;
@@ -102,6 +127,22 @@ export interface GjcTeamMonitorSnapshot {
102
127
  integration_by_worker: Record<string, GjcTeamWorkerIntegrationState>;
103
128
  updated_at: string;
104
129
  }
130
+ export interface GjcTeamWorkerLifecycle {
131
+ worker: string;
132
+ lifecycle_state: GjcTeamWorkerLifecycleState;
133
+ worker_status_state: GjcWorkerStatusState;
134
+ pane_id?: string;
135
+ pid?: number;
136
+ started_at?: string;
137
+ updated_at: string;
138
+ stopped_at?: string;
139
+ stop_reason?: string;
140
+ shutdown_request_id?: string;
141
+ shutdown_requested_at?: string;
142
+ shutdown_acknowledged_at?: string;
143
+ shutdown_ack_status?: string;
144
+ shutdown_mode?: GjcTeamShutdownMode;
145
+ }
105
146
  export type GjcTeamNotificationDeliveryState = "pending" | "sent" | "queued" | "deferred" | "failed" | "delivered" | "acknowledged";
106
147
  export type GjcTeamPaneAttemptResult = "sent" | "queued" | "deferred" | "failed";
107
148
  export interface GjcTeamNotification {
@@ -139,9 +180,13 @@ export interface GjcTeamSnapshot {
139
180
  task_counts: Record<GjcTeamTaskStatus, number>;
140
181
  workers: GjcTeamWorker[];
141
182
  integration_by_worker?: Record<string, GjcTeamWorkerIntegrationState>;
183
+ worker_lifecycle_by_id: Record<string, GjcTeamWorkerLifecycle>;
142
184
  notification_summary: GjcTeamNotificationSummary;
143
185
  updated_at: string;
144
186
  }
187
+ export interface GjcTeamSnapshotOptions {
188
+ reconcileNotifications?: boolean;
189
+ }
145
190
  export interface GjcTeamStartOptions {
146
191
  workerCount: number;
147
192
  agentType: string;
@@ -159,6 +204,16 @@ export interface GjcTeamApiClaimResult {
159
204
  claim_token?: string;
160
205
  reason?: string;
161
206
  }
207
+ export type GjcTeamLivenessRecoveryReason = "claim_expired" | "stale_heartbeat" | "missing_pane" | "worker_lifecycle_failed" | "worker_lifecycle_stopped";
208
+ export interface GjcTeamRecoveredClaim {
209
+ task_id: string;
210
+ worker: string;
211
+ reasons: GjcTeamLivenessRecoveryReason[];
212
+ }
213
+ export interface GjcTeamLivenessRecoveryResult {
214
+ recovered_claims: GjcTeamRecoveredClaim[];
215
+ stale_workers: Record<string, GjcTeamLivenessRecoveryReason[]>;
216
+ }
162
217
  export interface GjcTeamMailboxMessage {
163
218
  message_id: string;
164
219
  from_worker: string;
@@ -181,6 +236,19 @@ export interface GjcTeamEvent {
181
236
  message?: string;
182
237
  data?: Record<string, unknown>;
183
238
  }
239
+ export interface GjcTeamTraceEvent {
240
+ schema_version: 1;
241
+ trace_id: string;
242
+ span_id: string;
243
+ source_event_id: string;
244
+ event_type: string;
245
+ ts: string;
246
+ worker?: string;
247
+ task_id?: string;
248
+ message?: string;
249
+ evidence_refs?: string[];
250
+ data?: Record<string, unknown>;
251
+ }
184
252
  interface WorkerStatusFile {
185
253
  state: GjcWorkerStatusState;
186
254
  current_task_id?: string;
@@ -202,8 +270,11 @@ export interface GjcWorkerIntegrationAttemptRequestResult {
202
270
  head?: string | null;
203
271
  status?: GjcWorkerCheckpointClassification["kind"];
204
272
  }
205
- export declare const GJC_TEAM_API_OPERATIONS: readonly ["send-message", "broadcast", "mailbox-list", "mailbox-mark-delivered", "mailbox-mark-notified", "notification-list", "notification-read", "notification-replay", "notification-mark-pane-attempt", "worker-startup-ack", "create-task", "read-task", "list-tasks", "update-task", "claim-task", "transition-task-status", "transition-task", "release-task-claim", "read-config", "read-manifest", "read-worker-status", "read-worker-heartbeat", "update-worker-heartbeat", "write-worker-inbox", "write-worker-identity", "append-event", "read-events", "await-event", "write-shutdown-request", "read-shutdown-ack", "read-monitor-snapshot", "write-monitor-snapshot", "read-task-approval", "write-task-approval"];
273
+ export declare const GJC_TEAM_API_OPERATIONS: readonly ["send-message", "broadcast", "mailbox-list", "mailbox-mark-delivered", "mailbox-mark-notified", "notification-list", "notification-read", "notification-replay", "notification-mark-pane-attempt", "worker-startup-ack", "create-task", "read-task", "list-tasks", "update-task", "claim-task", "transition-task-status", "transition-task", "release-task-claim", "read-config", "read-manifest", "read-worker-status", "update-worker-status", "read-worker-heartbeat", "recover-stale-claims", "update-worker-heartbeat", "write-worker-inbox", "write-worker-identity", "append-event", "read-events", "read-traces", "await-event", "write-shutdown-request", "read-shutdown-ack", "read-monitor-snapshot", "write-monitor-snapshot", "read-task-approval", "write-task-approval"];
206
274
  export declare function resolveGjcTeamStateRoot(cwd?: string, env?: NodeJS.ProcessEnv): string;
275
+ export declare function persistGjcTeamModeStateSummary(snapshot: GjcTeamSnapshot, cwd?: string): Promise<void>;
276
+ export declare function recoverGjcTeamStaleClaims(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamLivenessRecoveryResult>;
277
+ type GjcTeamTaskMetadataInput = Partial<Pick<GjcTeamTask, "owner" | "lane" | "required_role" | "allowed_roles" | "depends_on" | "blocked_by">>;
207
278
  export declare function resolveGjcTmuxCommand(env?: NodeJS.ProcessEnv): string;
208
279
  export declare function resolveGjcWorkerCommand(cwd?: string, env?: NodeJS.ProcessEnv): string;
209
280
  export type GjcWorkerCheckpointClassification = {
@@ -229,7 +300,8 @@ export declare function classifyGjcTeamCheckpointFiles(files: string[]): {
229
300
  };
230
301
  export declare function classifyWorkerCheckpointStatus(cwd: string): GjcWorkerCheckpointClassification;
231
302
  export declare function startGjcTeam(options: GjcTeamStartOptions): Promise<GjcTeamSnapshot>;
232
- export declare function readGjcTeamSnapshot(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamSnapshot>;
303
+ export declare function readGjcTeamSnapshot(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv, options?: GjcTeamSnapshotOptions): Promise<GjcTeamSnapshot>;
304
+ export declare function monitorGjcTeamSnapshot(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamSnapshot>;
233
305
  export declare function requestGjcWorkerIntegrationAttempt(cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcWorkerIntegrationAttemptRequestResult>;
234
306
  export declare function buildTeamHudSummary(snapshot: GjcTeamSnapshot, latestEvent?: GjcTeamEvent, latestMessage?: GjcTeamMailboxMessage): Promise<WorkflowHudSummary>;
235
307
  export declare function monitorGjcTeam(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamSnapshot>;
@@ -237,11 +309,11 @@ export declare function listGjcTeams(cwd?: string, env?: NodeJS.ProcessEnv): Pro
237
309
  export declare function shutdownGjcTeam(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamSnapshot>;
238
310
  export declare function listGjcTeamTasks(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask[]>;
239
311
  export declare function readGjcTeamTask(teamName: string, taskId: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask>;
240
- export declare function createGjcTeamTask(teamName: string, subject: string, description: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask>;
241
- export declare function updateGjcTeamTask(teamName: string, taskId: string, updates: Partial<Pick<GjcTeamTask, "subject" | "description" | "blocked_by" | "depends_on">>, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask>;
312
+ export declare function createGjcTeamTask(teamName: string, subject: string, description: string, cwd?: string, env?: NodeJS.ProcessEnv, taskOptions?: GjcTeamTaskMetadataInput): Promise<GjcTeamTask>;
313
+ export declare function updateGjcTeamTask(teamName: string, taskId: string, updates: Partial<Pick<GjcTeamTask, "subject" | "description" | "blocked_by" | "depends_on" | "lane" | "required_role" | "allowed_roles">>, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask>;
242
314
  export declare function claimGjcTeamTask(teamName: string, workerId: string, cwd?: string, env?: NodeJS.ProcessEnv, taskId?: string): Promise<GjcTeamApiClaimResult>;
243
- export declare function transitionGjcTeamTaskStatus(teamName: string, taskId: string, status: GjcTeamTaskStatus, cwd?: string, env?: NodeJS.ProcessEnv, claimToken?: string, workerId?: string, evidence?: string): Promise<GjcTeamTask>;
244
- export declare function transitionGjcTeamTask(teamName: string, taskId: string, status: GjcTeamTaskStatus | "complete", cwd?: string, env?: NodeJS.ProcessEnv, claimToken?: string): Promise<GjcTeamTask>;
315
+ export declare function transitionGjcTeamTaskStatus(teamName: string, taskId: string, status: GjcTeamTaskStatus, cwd?: string, env?: NodeJS.ProcessEnv, claimToken?: string, workerId?: string, completionEvidenceInput?: unknown): Promise<GjcTeamTask>;
316
+ export declare function transitionGjcTeamTask(teamName: string, taskId: string, status: GjcTeamTaskStatus | "complete", cwd?: string, env?: NodeJS.ProcessEnv, claimToken?: string, completionEvidenceInput?: unknown): Promise<GjcTeamTask>;
245
317
  export declare function releaseGjcTeamTaskClaim(teamName: string, taskId: string, claimToken: string, workerId: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTask>;
246
318
  export declare function replayGjcTeamNotifications(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<{
247
319
  notifications: GjcTeamNotification[];
@@ -252,6 +324,7 @@ export declare function broadcastGjcTeamMessage(teamName: string, fromWorker: st
252
324
  export declare function listGjcTeamMailbox(teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamMailboxMessage[]>;
253
325
  export declare function markGjcTeamMailboxMessage(teamName: string, worker: string, messageId: string, field: "delivered_at" | "notified_at", cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamMailboxMessage>;
254
326
  export declare function readGjcWorkerStatus(teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<WorkerStatusFile>;
327
+ export declare function updateGjcWorkerStatus(teamName: string, worker: string, status: GjcWorkerStatusState, cwd?: string, env?: NodeJS.ProcessEnv, currentTaskId?: string, reason?: string): Promise<WorkerStatusFile>;
255
328
  export declare function readGjcWorkerHeartbeat(teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<WorkerHeartbeatFile | null>;
256
329
  export declare function updateGjcWorkerHeartbeat(teamName: string, worker: string, heartbeat: WorkerHeartbeatFile, cwd?: string, env?: NodeJS.ProcessEnv): Promise<WorkerHeartbeatFile>;
257
330
  export declare function writeGjcWorkerInbox(teamName: string, worker: string, content: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<{
@@ -259,6 +332,7 @@ export declare function writeGjcWorkerInbox(teamName: string, worker: string, co
259
332
  }>;
260
333
  export declare function writeGjcWorkerIdentity(teamName: string, worker: GjcTeamWorker, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamWorker>;
261
334
  export declare function readGjcTeamEvents(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamEvent[]>;
335
+ export declare function readGjcTeamTraces(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamTraceEvent[]>;
262
336
  export declare function appendGjcTeamEvent(teamName: string, type: string, worker?: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamEvent>;
263
337
  export declare function awaitGjcTeamEvent(teamName: string, _timeoutMs?: number, cwd?: string, env?: NodeJS.ProcessEnv): Promise<{
264
338
  status: "event" | "timeout";
@@ -268,7 +342,7 @@ export declare function writeGjcMonitorSnapshot(teamName: string, snapshot: unkn
268
342
  export declare function readGjcMonitorSnapshot(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<unknown>;
269
343
  export declare function writeGjcTaskApproval(teamName: string, taskId: string, approval: Record<string, unknown>, cwd?: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown>>;
270
344
  export declare function readGjcTaskApproval(teamName: string, taskId: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown> | null>;
271
- export declare function writeGjcShutdownRequest(teamName: string, worker: string, requestedBy: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown>>;
345
+ export declare function writeGjcShutdownRequest(teamName: string, worker: string, requestedBy: string, cwd?: string, env?: NodeJS.ProcessEnv, requestId?: string, mode?: GjcTeamShutdownMode, requestedAt?: string): Promise<Record<string, unknown>>;
272
346
  export declare function readGjcShutdownAck(teamName: string, worker: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown> | null>;
273
347
  export declare function executeGjcTeamApiOperation(operation: string, input: Record<string, unknown>, cwd?: string, env?: NodeJS.ProcessEnv): Promise<unknown>;
274
348
  export declare function parseTeamLaunchArgs(argv: string[]): GjcTeamStartOptions;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * TypeScript is the authoritative source of truth for GJC workflow manifests.
3
+ * Any JSON manifest projection is derived from this module and must never be
4
+ * hand-edited.
5
+ */
6
+ import type { CanonicalGjcWorkflowSkill } from "../skill-state/active-state";
7
+ export interface WorkflowState {
8
+ id: string;
9
+ initial?: boolean;
10
+ terminal?: boolean;
11
+ }
12
+ export interface WorkflowTransition {
13
+ from: string;
14
+ to: string;
15
+ verb: string;
16
+ }
17
+ export interface WorkflowVerb {
18
+ name: string;
19
+ planned?: boolean;
20
+ /** Invocation surface that exposes this verb in the real CLI parser. */
21
+ surface?: "state-action" | "command-positional" | "command-flag";
22
+ }
23
+ export interface TypedArgSpec {
24
+ name: string;
25
+ type: "string" | "number" | "boolean" | "enum" | "object";
26
+ enumValues?: string[];
27
+ required?: boolean;
28
+ appliesToVerbs?: string[];
29
+ planned?: boolean;
30
+ }
31
+ export interface RetentionPolicy {
32
+ category: string;
33
+ keep?: number;
34
+ maxAgeDays?: number;
35
+ }
36
+ export interface SkillManifest {
37
+ skill: CanonicalGjcWorkflowSkill;
38
+ states: WorkflowState[];
39
+ initialState: string;
40
+ terminalStates: string[];
41
+ transitions: WorkflowTransition[];
42
+ verbs: WorkflowVerb[];
43
+ typedArgs: TypedArgSpec[];
44
+ retention: RetentionPolicy[];
45
+ hudFields: string[];
46
+ graphLabel: string;
47
+ }
48
+ export declare const WORKFLOW_MANIFEST: Record<CanonicalGjcWorkflowSkill, SkillManifest>;
49
+ export declare function getSkillManifest(skill: CanonicalGjcWorkflowSkill): SkillManifest;
50
+ export declare function isKnownWorkflowState(skill: CanonicalGjcWorkflowSkill, state: string): boolean;
51
+ export declare function isValidTransition(skill: CanonicalGjcWorkflowSkill, from: string, to: string): boolean;
52
+ export declare function listVerbs(skill: CanonicalGjcWorkflowSkill): string[];
53
+ export declare function typedArgsFor(skill: CanonicalGjcWorkflowSkill, verb: string): TypedArgSpec[];
54
+ export declare function serializeManifestProjection(): string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Deterministic recovery classifier (pure).
3
+ *
4
+ * Maps a bounded {@link Observation} + remaining retry budget to exactly one
5
+ * {@link RecoveryDecision}. Encodes the plan's hard data-loss invariants:
6
+ * - dirty deltas are NEVER `restart-clean`; they map to `restart-preserve-delta`.
7
+ * - unknown deltas are NEVER destructive; they map to `human-check`.
8
+ * - a deleted/mismatched worktree maps to `human-check` (never recreate over unknown data).
9
+ * `send-enter` is intentionally never emitted: it is unsupported for the gajae-code
10
+ * RPC adapter in v1 (no blind key injection).
11
+ */
12
+ import type { ClassifyInput, RecoveryDecision } from "./types";
13
+ export declare function classifyRecovery(input: ClassifyInput): RecoveryDecision;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Per-session control endpoint — a Unix domain socket served by the RuntimeOwner so
3
+ * stateless `gjc harness` CLI calls can route owner-routed primitives (submit, observe,
4
+ * recover, retire) to the live owner. One JSON request line in, one JSON response line out.
5
+ *
6
+ * The owner is the only listener; clients connect per call. When no socket is reachable
7
+ * the caller falls back to the no-owner behavior (read-only observe, owner-not-live submit).
8
+ *
9
+ * FIFO fallback (for platforms/paths where AF_UNIX is unavailable or path-length limited)
10
+ * is a documented seam tracked as an ADR follow-up.
11
+ */
12
+ export interface EndpointRequest {
13
+ verb: string;
14
+ input: Record<string, unknown>;
15
+ }
16
+ export type EndpointHandler = (req: EndpointRequest) => Promise<unknown>;
17
+ export declare class ControlServer {
18
+ #private;
19
+ readonly socketPath: string;
20
+ private readonly handler;
21
+ constructor(socketPath: string, handler: EndpointHandler);
22
+ listen(): Promise<void>;
23
+ close(): Promise<void>;
24
+ }
25
+ export declare class EndpointUnreachableError extends Error {
26
+ readonly socketPath: string;
27
+ constructor(socketPath: string);
28
+ }
29
+ /** Call the owner's control endpoint. Rejects with {@link EndpointUnreachableError} when no owner listens. */
30
+ export declare function callEndpoint(socketPath: string, req: EndpointRequest, timeoutMs?: number): Promise<unknown>;
@@ -0,0 +1,47 @@
1
+ export interface ValidationCommandSpec {
2
+ name: string;
3
+ command: string;
4
+ }
5
+ export interface ValidationRun {
6
+ exactCommand: string;
7
+ cwd: string;
8
+ exitStatus: number;
9
+ pass: boolean;
10
+ }
11
+ export interface FinalizeChecks {
12
+ runValidation(spec: ValidationCommandSpec): Promise<ValidationRun>;
13
+ resolveCommit(): Promise<string | null>;
14
+ commitOnBranch(commit: string, branch: string): Promise<boolean>;
15
+ prOrIssue(): Promise<{
16
+ prUrl: string | null;
17
+ issueArtifact: string | null;
18
+ }>;
19
+ }
20
+ export interface FinalizeOptions {
21
+ root: string;
22
+ sessionId: string;
23
+ workspace: string;
24
+ branch: string;
25
+ requireTests?: boolean;
26
+ requireCommit?: boolean;
27
+ requirePr?: boolean;
28
+ validationCommands?: ValidationCommandSpec[];
29
+ checks: FinalizeChecks;
30
+ clock?: () => number;
31
+ }
32
+ export interface FinalizeResult {
33
+ completed: boolean;
34
+ receiptPath: string | null;
35
+ validation: {
36
+ name: string;
37
+ valid: boolean;
38
+ exitStatus: number;
39
+ }[];
40
+ commitHash: string | null;
41
+ prUrl: string | null;
42
+ issueArtifact: string | null;
43
+ blockers: string[];
44
+ }
45
+ export declare function runFinalize(opts: FinalizeOptions): Promise<FinalizeResult>;
46
+ /** Real checks: git for commit/branch, gh for PR, Bun.spawn for validation commands. */
47
+ export declare function defaultFinalizeChecks(workspace: string): FinalizeChecks;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Pure mapping from `gjc --mode rpc` event frames (docs/rpc.md) to bounded owner event kinds
3
+ * and {@link ObservedSignal}s. The owner feeds raw frames through this mapper and emits the
4
+ * result via its single-writer #emit — the mapper itself performs NO IO and NO appends.
5
+ *
6
+ * Hard rule: evidence is BOUNDED — only ids, names, categories, statuses, cursors, timestamps,
7
+ * and short codes/messages. Never assistant text, message deltas, command output, or raw args.
8
+ */
9
+ import type { ObservedSignal } from "./types";
10
+ export interface MappedFrame {
11
+ /** Owner event kind (rpc_*). */
12
+ kind: string;
13
+ /** Bounded observed signal, or null when the frame carries no user-facing signal. */
14
+ signal: ObservedSignal | null;
15
+ /** Bounded evidence — ids/names/statuses/cursors/timestamps/short codes only. */
16
+ evidence: Record<string, unknown>;
17
+ /** Severity for the emitted event. */
18
+ severity: "info" | "warn" | "critical";
19
+ /** Never-drop frames (must be enqueued in order, never coalesced away). */
20
+ semantic: boolean;
21
+ /** Coalescing key for high-frequency non-semantic frames (message id / tool id); null otherwise. */
22
+ coalesceKey: string | null;
23
+ }
24
+ export declare function isTestRunnerTool(toolName?: unknown, command?: unknown): boolean;
25
+ /**
26
+ * Map a single RPC frame. Returns null for frames that carry no observability value
27
+ * (or that the adapter handles itself: `ready`, `response`).
28
+ */
29
+ export declare function mapRpcFrame(frame: Record<string, unknown>): MappedFrame | null;
@@ -0,0 +1,35 @@
1
+ import { type FinalizeChecks, type FinalizeResult, type ValidationCommandSpec } from "./finalize";
2
+ import { type PreserveResult } from "./preserve";
3
+ import { type HarnessRpc } from "./rpc-adapter";
4
+ import { type HarnessLifecycle, type Observation, type RecoveryClassification, type RetryBudget, type Severity } from "./types";
5
+ export interface OperateOptions {
6
+ root: string;
7
+ sessionId: string;
8
+ workspace: string;
9
+ branch: string;
10
+ rpc: HarnessRpc;
11
+ /** Factory used to (re)create the RPC subprocess on restart recovery. Defaults to reusing `rpc`. */
12
+ rpcFactory?: () => HarnessRpc;
13
+ /** Bounded observation provider (scripted in tests; real = git + rpc state). */
14
+ observe: () => Promise<Observation>;
15
+ /** Real dirty-worktree preservation; injectable for tests. Defaults to git stash/diff capture. */
16
+ preserve?: (workspace: string) => PreserveResult;
17
+ finalizeChecks: FinalizeChecks;
18
+ validationCommands?: ValidationCommandSpec[];
19
+ retryBudget?: Partial<RetryBudget>;
20
+ acceptanceTimeoutMs?: number;
21
+ maxIterations?: number;
22
+ /** Injected event emitter. Production owner calls must pass the lease-guarded single-writer #emit. */
23
+ emit: (severity: Severity, kind: string, evidence: Record<string, unknown>) => Promise<void>;
24
+ clock?: () => number;
25
+ }
26
+ export interface OperateResult {
27
+ completed: boolean;
28
+ lifecycle: HarnessLifecycle;
29
+ iterations: number;
30
+ classifications: RecoveryClassification[];
31
+ vanishReceiptIds: string[];
32
+ finalize?: FinalizeResult;
33
+ blockers: string[];
34
+ }
35
+ export declare function operate(goal: string, opts: OperateOptions): Promise<OperateResult>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * RuntimeOwner — the detached per-session process that makes live control honest.
3
+ *
4
+ * Responsibilities:
5
+ * - hold the {@link SessionLease} (single writer),
6
+ * - own the {@link HarnessRpc} subprocess (injected; real `GajaeCodeRpc` in prod, fake in tests),
7
+ * - serve owner-routed primitives over the {@link ControlServer} endpoint,
8
+ * - be the SOLE writer of the severity event stream,
9
+ * - heartbeat the lease.
10
+ *
11
+ * Stateless `gjc harness` CLI calls reach the owner via {@link resolveOwner} + the endpoint.
12
+ */
13
+ import { type FinalizeChecks, type ValidationCommandSpec } from "./finalize";
14
+ import type { HarnessRpc } from "./rpc-adapter";
15
+ import { type SessionLease } from "./session-lease";
16
+ export interface OwnerOptions {
17
+ root: string;
18
+ sessionId: string;
19
+ rpc: HarnessRpc;
20
+ ownerId?: string;
21
+ ttlMs?: number;
22
+ heartbeatMs?: number;
23
+ acceptanceTimeoutMs?: number;
24
+ clock?: () => number;
25
+ finalizeChecks?: FinalizeChecks;
26
+ validationCommands?: ValidationCommandSpec[];
27
+ }
28
+ export interface OwnerStartInfo {
29
+ ownerId: string;
30
+ socketPath: string;
31
+ leaseEpoch: number;
32
+ }
33
+ export declare class RuntimeOwner {
34
+ #private;
35
+ readonly ownerId: string;
36
+ constructor(opts: OwnerOptions);
37
+ start(): Promise<OwnerStartInfo>;
38
+ stop(): Promise<void>;
39
+ }
40
+ export interface ResolvedOwner {
41
+ live: boolean;
42
+ socketPath: string | null;
43
+ lease: SessionLease | null;
44
+ }
45
+ /** Determine whether a live owner currently holds the session (for CLI routing). */
46
+ export declare function resolveOwner(root: string, sessionId: string): Promise<ResolvedOwner>;
@@ -0,0 +1,19 @@
1
+ import type { GitDelta } from "./types";
2
+ export interface UntrackedEntry {
3
+ path: string;
4
+ size: number;
5
+ sha256: string;
6
+ }
7
+ export interface PreserveResult {
8
+ gitDelta: GitDelta;
9
+ trackedDiff: string;
10
+ trackedDiffSha256: string;
11
+ untrackedManifest: UntrackedEntry[];
12
+ stashRef: string | null;
13
+ snapshotComplete: boolean;
14
+ }
15
+ /**
16
+ * Capture + snapshot a (possibly dirty) worktree without mutating it. Safe to call on a clean
17
+ * tree (returns empty evidence). Never deletes, resets, or cleans.
18
+ */
19
+ export declare function preserveDirtyWorktree(workspace: string): PreserveResult;