@gajae-code/coding-agent 0.3.0 → 0.3.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 (213) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +1 -1
  3. package/dist/types/async/job-manager.d.ts +7 -0
  4. package/dist/types/cli/args.d.ts +3 -1
  5. package/dist/types/commands/deep-interview.d.ts +3 -0
  6. package/dist/types/commands/launch.d.ts +6 -0
  7. package/dist/types/config/keybindings.d.ts +5 -0
  8. package/dist/types/config/model-profile-activation.d.ts +30 -0
  9. package/dist/types/config/model-profiles.d.ts +19 -0
  10. package/dist/types/config/model-registry.d.ts +8 -0
  11. package/dist/types/config/model-resolver.d.ts +1 -1
  12. package/dist/types/config/models-config-schema.d.ts +47 -0
  13. package/dist/types/config/settings-schema.d.ts +14 -4
  14. package/dist/types/debug/crash-diagnostics.d.ts +45 -0
  15. package/dist/types/debug/runtime-gauges.d.ts +6 -0
  16. package/dist/types/deep-interview/render-middleware.d.ts +1 -0
  17. package/dist/types/eval/py/executor.d.ts +2 -0
  18. package/dist/types/eval/py/kernel.d.ts +2 -0
  19. package/dist/types/exec/bash-executor.d.ts +10 -0
  20. package/dist/types/gjc-runtime/cli-write-receipt.d.ts +24 -0
  21. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -0
  22. package/dist/types/gjc-runtime/state-migrations.d.ts +9 -0
  23. package/dist/types/gjc-runtime/state-schema.d.ts +317 -0
  24. package/dist/types/gjc-runtime/state-writer.d.ts +10 -0
  25. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -1
  26. package/dist/types/gjc-runtime/workflow-command-ref.d.ts +43 -0
  27. package/dist/types/harness-control-plane/control-endpoint.d.ts +3 -2
  28. package/dist/types/hooks/skill-state.d.ts +21 -0
  29. package/dist/types/internal-urls/agent-protocol.d.ts +2 -2
  30. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  31. package/dist/types/internal-urls/registry-helpers.d.ts +8 -7
  32. package/dist/types/internal-urls/types.d.ts +4 -0
  33. package/dist/types/lsp/index.d.ts +10 -10
  34. package/dist/types/main.d.ts +10 -1
  35. package/dist/types/modes/bridge/auth.d.ts +12 -0
  36. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +9 -0
  37. package/dist/types/modes/bridge/bridge-mode.d.ts +44 -0
  38. package/dist/types/modes/bridge/bridge-ui-context.d.ts +88 -0
  39. package/dist/types/modes/bridge/event-stream.d.ts +8 -0
  40. package/dist/types/modes/components/custom-editor.d.ts +6 -0
  41. package/dist/types/modes/components/custom-provider-wizard.d.ts +10 -0
  42. package/dist/types/modes/components/jobs-overlay-model.d.ts +31 -0
  43. package/dist/types/modes/components/jobs-overlay.d.ts +30 -0
  44. package/dist/types/modes/components/model-selector.d.ts +6 -1
  45. package/dist/types/modes/components/provider-onboarding-selector.d.ts +1 -1
  46. package/dist/types/modes/components/status-line/types.d.ts +2 -0
  47. package/dist/types/modes/components/status-line.d.ts +2 -0
  48. package/dist/types/modes/controllers/input-controller.d.ts +1 -0
  49. package/dist/types/modes/controllers/selector-controller.d.ts +9 -0
  50. package/dist/types/modes/index.d.ts +1 -0
  51. package/dist/types/modes/interactive-mode.d.ts +1 -0
  52. package/dist/types/modes/jobs-observer.d.ts +57 -0
  53. package/dist/types/modes/rpc/host-tools.d.ts +1 -16
  54. package/dist/types/modes/rpc/host-uris.d.ts +1 -38
  55. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +20 -0
  56. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +2 -0
  57. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +24 -0
  58. package/dist/types/modes/shared/agent-wire/handshake.d.ts +46 -0
  59. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +16 -0
  60. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +17 -0
  61. package/dist/types/modes/shared/agent-wire/protocol.d.ts +44 -0
  62. package/dist/types/modes/shared/agent-wire/responses.d.ts +4 -0
  63. package/dist/types/modes/shared/agent-wire/scopes.d.ts +18 -0
  64. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +42 -0
  65. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +27 -0
  66. package/dist/types/modes/types.d.ts +2 -0
  67. package/dist/types/sdk.d.ts +3 -1
  68. package/dist/types/session/agent-session.d.ts +11 -1
  69. package/dist/types/skill-state/workflow-state-contract.d.ts +1 -2
  70. package/dist/types/skill-state/workflow-state-version.d.ts +3 -0
  71. package/dist/types/task/executor.d.ts +1 -0
  72. package/dist/types/task/id.d.ts +7 -0
  73. package/dist/types/task/index.d.ts +5 -0
  74. package/dist/types/task/receipt.d.ts +85 -0
  75. package/dist/types/task/spawn-gate.d.ts +38 -0
  76. package/dist/types/task/types.d.ts +143 -11
  77. package/dist/types/tools/cron.d.ts +6 -0
  78. package/dist/types/tools/hindsight-recall.d.ts +0 -2
  79. package/dist/types/tools/hindsight-reflect.d.ts +0 -2
  80. package/dist/types/tools/hindsight-retain.d.ts +0 -2
  81. package/dist/types/tools/index.d.ts +6 -4
  82. package/dist/types/tools/path-utils.d.ts +1 -0
  83. package/dist/types/tools/subagent.d.ts +15 -0
  84. package/package.json +7 -7
  85. package/scripts/build-binary.ts +7 -0
  86. package/src/async/job-manager.ts +36 -0
  87. package/src/cli/args.ts +19 -2
  88. package/src/commands/deep-interview.ts +1 -0
  89. package/src/commands/harness.ts +289 -19
  90. package/src/commands/launch.ts +10 -2
  91. package/src/commands/state.ts +2 -1
  92. package/src/commands/team.ts +22 -4
  93. package/src/config/keybindings.ts +6 -0
  94. package/src/config/model-profile-activation.ts +157 -0
  95. package/src/config/model-profiles.ts +155 -0
  96. package/src/config/model-registry.ts +19 -0
  97. package/src/config/model-resolver.ts +3 -2
  98. package/src/config/models-config-schema.ts +36 -0
  99. package/src/config/settings-schema.ts +16 -3
  100. package/src/dap/client.ts +17 -3
  101. package/src/debug/crash-diagnostics.ts +223 -0
  102. package/src/debug/runtime-gauges.ts +20 -0
  103. package/src/deep-interview/render-middleware.ts +6 -0
  104. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
  105. package/src/defaults/gjc/skills/ralplan/SKILL.md +31 -2
  106. package/src/defaults/gjc/skills/ultragoal/SKILL.md +39 -3
  107. package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +61 -0
  108. package/src/defaults/gjc-defaults.ts +7 -0
  109. package/src/eval/py/executor.ts +21 -1
  110. package/src/eval/py/kernel.ts +15 -0
  111. package/src/exec/bash-executor.ts +41 -0
  112. package/src/gjc-runtime/cli-write-receipt.ts +31 -0
  113. package/src/gjc-runtime/deep-interview-runtime.ts +69 -32
  114. package/src/gjc-runtime/ralplan-runtime.ts +213 -36
  115. package/src/gjc-runtime/state-migrations.ts +54 -7
  116. package/src/gjc-runtime/state-runtime.ts +461 -64
  117. package/src/gjc-runtime/state-schema.ts +192 -0
  118. package/src/gjc-runtime/state-writer.ts +32 -1
  119. package/src/gjc-runtime/team-runtime.ts +177 -105
  120. package/src/gjc-runtime/ultragoal-runtime.ts +231 -38
  121. package/src/gjc-runtime/workflow-command-ref.ts +239 -0
  122. package/src/gjc-runtime/workflow-manifest.generated.json +108 -4
  123. package/src/gjc-runtime/workflow-manifest.ts +3 -1
  124. package/src/harness-control-plane/control-endpoint.ts +19 -8
  125. package/src/harness-control-plane/owner.ts +57 -10
  126. package/src/harness-control-plane/state-machine.ts +2 -1
  127. package/src/hooks/skill-state.ts +176 -26
  128. package/src/internal-urls/agent-protocol.ts +68 -21
  129. package/src/internal-urls/artifact-protocol.ts +12 -17
  130. package/src/internal-urls/docs-index.generated.ts +8 -10
  131. package/src/internal-urls/registry-helpers.ts +19 -16
  132. package/src/internal-urls/types.ts +4 -0
  133. package/src/lsp/client.ts +18 -2
  134. package/src/main.ts +88 -6
  135. package/src/modes/bridge/auth.ts +41 -0
  136. package/src/modes/bridge/bridge-client-bridge.ts +47 -0
  137. package/src/modes/bridge/bridge-mode.ts +520 -0
  138. package/src/modes/bridge/bridge-ui-context.ts +200 -0
  139. package/src/modes/bridge/event-stream.ts +70 -0
  140. package/src/modes/components/custom-editor.ts +101 -0
  141. package/src/modes/components/custom-provider-wizard.ts +318 -0
  142. package/src/modes/components/hook-selector.ts +61 -18
  143. package/src/modes/components/jobs-overlay-model.ts +109 -0
  144. package/src/modes/components/jobs-overlay.ts +172 -0
  145. package/src/modes/components/model-selector.ts +108 -18
  146. package/src/modes/components/provider-onboarding-selector.ts +6 -1
  147. package/src/modes/components/status-line/presets.ts +7 -5
  148. package/src/modes/components/status-line/segments.ts +25 -0
  149. package/src/modes/components/status-line/types.ts +2 -0
  150. package/src/modes/components/status-line.ts +9 -1
  151. package/src/modes/controllers/extension-ui-controller.ts +39 -3
  152. package/src/modes/controllers/input-controller.ts +97 -9
  153. package/src/modes/controllers/selector-controller.ts +86 -1
  154. package/src/modes/index.ts +1 -0
  155. package/src/modes/interactive-mode.ts +27 -0
  156. package/src/modes/jobs-observer.ts +204 -0
  157. package/src/modes/rpc/host-tools.ts +1 -186
  158. package/src/modes/rpc/host-uris.ts +1 -235
  159. package/src/modes/rpc/rpc-client.ts +25 -10
  160. package/src/modes/rpc/rpc-mode.ts +12 -381
  161. package/src/modes/shared/agent-wire/command-dispatch.ts +341 -0
  162. package/src/modes/shared/agent-wire/command-validation.ts +131 -0
  163. package/src/modes/shared/agent-wire/event-envelope.ts +108 -0
  164. package/src/modes/shared/agent-wire/handshake.ts +117 -0
  165. package/src/modes/shared/agent-wire/host-tool-bridge.ts +194 -0
  166. package/src/modes/shared/agent-wire/host-uri-bridge.ts +236 -0
  167. package/src/modes/shared/agent-wire/protocol.ts +96 -0
  168. package/src/modes/shared/agent-wire/responses.ts +17 -0
  169. package/src/modes/shared/agent-wire/scopes.ts +89 -0
  170. package/src/modes/shared/agent-wire/ui-request-broker.ts +150 -0
  171. package/src/modes/shared/agent-wire/ui-result.ts +48 -0
  172. package/src/modes/types.ts +2 -0
  173. package/src/prompts/memories/consolidation.md +1 -1
  174. package/src/prompts/memories/read-path.md +6 -7
  175. package/src/prompts/memories/unavailable.md +2 -2
  176. package/src/prompts/tools/bash.md +1 -1
  177. package/src/prompts/tools/irc.md +1 -1
  178. package/src/prompts/tools/read.md +2 -2
  179. package/src/prompts/tools/recall.md +1 -0
  180. package/src/prompts/tools/reflect.md +1 -0
  181. package/src/prompts/tools/retain.md +1 -0
  182. package/src/prompts/tools/subagent.md +12 -7
  183. package/src/prompts/tools/task-summary.md +3 -9
  184. package/src/prompts/tools/task.md +5 -1
  185. package/src/sdk.ts +5 -1
  186. package/src/session/agent-session.ts +214 -38
  187. package/src/skill-state/deep-interview-mutation-guard.ts +23 -4
  188. package/src/skill-state/workflow-state-contract.ts +7 -4
  189. package/src/skill-state/workflow-state-version.ts +3 -0
  190. package/src/slash-commands/builtin-registry.ts +9 -1
  191. package/src/task/executor.ts +31 -5
  192. package/src/task/id.ts +33 -0
  193. package/src/task/index.ts +259 -67
  194. package/src/task/output-manager.ts +5 -4
  195. package/src/task/receipt.ts +297 -0
  196. package/src/task/render.ts +48 -131
  197. package/src/task/spawn-gate.ts +132 -0
  198. package/src/task/types.ts +48 -7
  199. package/src/tools/ask.ts +73 -33
  200. package/src/tools/ast-edit.ts +1 -0
  201. package/src/tools/ast-grep.ts +1 -0
  202. package/src/tools/bash.ts +1 -1
  203. package/src/tools/cron.ts +48 -0
  204. package/src/tools/find.ts +4 -1
  205. package/src/tools/hindsight-recall.ts +0 -2
  206. package/src/tools/hindsight-reflect.ts +0 -2
  207. package/src/tools/hindsight-retain.ts +0 -2
  208. package/src/tools/index.ts +6 -18
  209. package/src/tools/path-utils.ts +3 -2
  210. package/src/tools/read.ts +4 -3
  211. package/src/tools/search.ts +1 -0
  212. package/src/tools/skill.ts +6 -1
  213. package/src/tools/subagent.ts +237 -84
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Transport-neutral request/response broker for UI and permission surfaces.
3
+ *
4
+ * The bridge protocol has one authoritative responder per session. Requests are
5
+ * correlated by id, resolved exactly once, cancelled on timeout/disconnect, and
6
+ * protected by an owner token so observers cannot race approvals.
7
+ */
8
+ import { randomUUID } from "node:crypto";
9
+
10
+ export type UiRequestCancelReason = "timeout" | "abort" | "disconnect";
11
+
12
+ export interface UiRequestCancelled {
13
+ status: "cancelled";
14
+ reason: UiRequestCancelReason;
15
+ }
16
+
17
+ export type UiRequestResolution<TResponse> = TResponse | UiRequestCancelled;
18
+
19
+ export type UiBrokerResponseResult =
20
+ | { status: "accepted" }
21
+ | { status: "rejected"; code: "not_controller" | "already_resolved" | "unknown_request" };
22
+
23
+ export interface UiRequestBrokerOptions<TRequest> {
24
+ emitRequest: (correlationId: string, request: TRequest) => void;
25
+ }
26
+
27
+ export interface UiRequestOptions {
28
+ correlationId?: string;
29
+ timeoutMs?: number;
30
+ signal?: AbortSignal;
31
+ }
32
+
33
+ interface PendingRequest<TResponse> {
34
+ resolve: (value: UiRequestResolution<TResponse>) => void;
35
+ timer: Timer | undefined;
36
+ onAbort: (() => void) | undefined;
37
+ signal: AbortSignal | undefined;
38
+ }
39
+
40
+ /**
41
+ * Broker for one active session. v1 supports one controller token at a time;
42
+ * other clients may observe frames but cannot answer correlated requests.
43
+ */
44
+ export class UiRequestBroker<TRequest, TResponse> {
45
+ readonly #emitRequest: (correlationId: string, request: TRequest) => void;
46
+ #ownerToken: string | undefined;
47
+ #pending = new Map<string, PendingRequest<TResponse>>();
48
+ #resolved = new Set<string>();
49
+
50
+ constructor(options: UiRequestBrokerOptions<TRequest>) {
51
+ this.#emitRequest = options.emitRequest;
52
+ }
53
+
54
+ get ownerToken(): string | undefined {
55
+ return this.#ownerToken;
56
+ }
57
+
58
+ get pendingCount(): number {
59
+ return this.#pending.size;
60
+ }
61
+
62
+ claimController(ownerToken: string = randomUUID()): { status: "claimed"; ownerToken: string } | { status: "busy" } {
63
+ if (this.#ownerToken) return { status: "busy" };
64
+ this.#ownerToken = ownerToken;
65
+ return { status: "claimed", ownerToken: this.#ownerToken };
66
+ }
67
+
68
+ releaseController(ownerToken: string): boolean {
69
+ if (ownerToken !== this.#ownerToken) return false;
70
+ this.#ownerToken = undefined;
71
+ return true;
72
+ }
73
+
74
+ request(request: TRequest, options: UiRequestOptions = {}): Promise<UiRequestResolution<TResponse>> {
75
+ const correlationId = options.correlationId ?? randomUUID();
76
+ if (this.#pending.has(correlationId) || this.#resolved.has(correlationId)) {
77
+ throw new Error(`Duplicate UI request correlation id: ${correlationId}`);
78
+ }
79
+
80
+ const { promise, resolve } = Promise.withResolvers<UiRequestResolution<TResponse>>();
81
+ let timer: Timer | undefined;
82
+ let onAbort: (() => void) | undefined;
83
+ const settle = (value: UiRequestResolution<TResponse>) => {
84
+ const pending = this.#pending.get(correlationId);
85
+ if (!pending) return;
86
+ this.#pending.delete(correlationId);
87
+ this.#resolved.add(correlationId);
88
+ if (pending.timer) clearTimeout(pending.timer);
89
+ if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
90
+ pending.resolve(value);
91
+ };
92
+
93
+ if (options.timeoutMs !== undefined) {
94
+ timer = setTimeout(() => settle({ status: "cancelled", reason: "timeout" }), options.timeoutMs);
95
+ }
96
+ if (options.signal) {
97
+ onAbort = () => settle({ status: "cancelled", reason: "abort" });
98
+ if (options.signal.aborted) {
99
+ resolve({ status: "cancelled", reason: "abort" });
100
+ this.#resolved.add(correlationId);
101
+ return promise;
102
+ }
103
+ options.signal.addEventListener("abort", onAbort, { once: true });
104
+ }
105
+
106
+ this.#pending.set(correlationId, { resolve, timer, onAbort, signal: options.signal });
107
+ this.#emitRequest(correlationId, request);
108
+ return promise;
109
+ }
110
+
111
+ respond(correlationId: string, ownerToken: string, response: TResponse): UiBrokerResponseResult {
112
+ if (ownerToken !== this.#ownerToken) return { status: "rejected", code: "not_controller" };
113
+ const pending = this.#pending.get(correlationId);
114
+ if (!pending) {
115
+ return {
116
+ status: "rejected",
117
+ code: this.#resolved.has(correlationId) ? "already_resolved" : "unknown_request",
118
+ };
119
+ }
120
+ this.#pending.delete(correlationId);
121
+ this.#resolved.add(correlationId);
122
+ if (pending.timer) clearTimeout(pending.timer);
123
+ if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
124
+ pending.resolve(response);
125
+ return { status: "accepted" };
126
+ }
127
+
128
+ cancelAll(reason: UiRequestCancelReason): void {
129
+ for (const correlationId of [...this.#pending.keys()]) {
130
+ this.cancel(correlationId, reason);
131
+ }
132
+ }
133
+
134
+ cancel(correlationId: string, reason: UiRequestCancelReason): boolean {
135
+ const pending = this.#pending.get(correlationId);
136
+ if (!pending) return false;
137
+ this.#pending.delete(correlationId);
138
+ this.#resolved.add(correlationId);
139
+ if (pending.timer) clearTimeout(pending.timer);
140
+ if (pending.onAbort) pending.signal?.removeEventListener("abort", pending.onAbort);
141
+ pending.resolve({ status: "cancelled", reason });
142
+ return true;
143
+ }
144
+
145
+ disconnectController(ownerToken: string): boolean {
146
+ if (!this.releaseController(ownerToken)) return false;
147
+ this.cancelAll("disconnect");
148
+ return true;
149
+ }
150
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Typed UI/manipulation result semantics for bridge-capability handling.
3
+ *
4
+ * `unsupported` is distinct from both a real value and user cancellation. This
5
+ * prevents local-only or undeclared `ExtensionUIContext` surfaces from becoming
6
+ * silent no-ops that look like user intent.
7
+ */
8
+ export interface BridgeUiValue<TValue> {
9
+ status: "value";
10
+ value: TValue;
11
+ }
12
+
13
+ export interface BridgeUiCancelled {
14
+ status: "cancelled";
15
+ reason?: "user" | "timeout" | "abort" | "disconnect";
16
+ }
17
+
18
+ export interface BridgeUiUnsupported {
19
+ status: "unsupported";
20
+ capability: string;
21
+ reason: string;
22
+ }
23
+
24
+ export type BridgeUiResult<TValue> = BridgeUiValue<TValue> | BridgeUiCancelled | BridgeUiUnsupported;
25
+
26
+ export function uiValue<TValue>(value: TValue): BridgeUiValue<TValue> {
27
+ return { status: "value", value };
28
+ }
29
+
30
+ export function uiCancelled(reason?: BridgeUiCancelled["reason"]): BridgeUiCancelled {
31
+ return reason ? { status: "cancelled", reason } : { status: "cancelled" };
32
+ }
33
+
34
+ export function uiUnsupported(capability: string, reason: string): BridgeUiUnsupported {
35
+ return { status: "unsupported", capability, reason };
36
+ }
37
+
38
+ export function isUiUnsupported<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiUnsupported {
39
+ return result.status === "unsupported";
40
+ }
41
+
42
+ export function isUiCancelled<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiCancelled {
43
+ return result.status === "cancelled";
44
+ }
45
+
46
+ export function isUiValue<TValue>(result: BridgeUiResult<TValue>): result is BridgeUiValue<TValue> {
47
+ return result.status === "value";
48
+ }
@@ -147,6 +147,7 @@ export interface InteractiveModeContext {
147
147
  showStatus(message: string, options?: { dim?: boolean }): void;
148
148
  showError(message: string): void;
149
149
  showWarning(message: string): void;
150
+ notifyConfigChanged?: () => Promise<void> | void;
150
151
  showNewVersionNotification(newVersion: string): void;
151
152
  clearEditor(): void;
152
153
  updatePendingMessagesDisplay(): void;
@@ -249,6 +250,7 @@ export interface InteractiveModeContext {
249
250
  showHookConfirm(title: string, message: string): Promise<boolean>;
250
251
  showDebugSelector(): void;
251
252
  showSessionObserver(): void;
253
+ showJobsOverlay(): void;
252
254
  resetObserverRegistry(): void;
253
255
 
254
256
  // Input handling
@@ -1,5 +1,5 @@
1
1
  Memory consolidation agent.
2
- Memory root: memory://root
2
+ Memory backend: local private runtime state
3
3
  Input corpus (raw memories):
4
4
  {{raw_memories}}
5
5
  Input corpus (rollout summaries):
@@ -1,11 +1,10 @@
1
1
  # Memory Guidance
2
- Memory root: memory://root
2
+ Memory backend: local private runtime state
3
3
  Operational rules:
4
- 1) Read `memory://root/memory_summary.md` first.
5
- 2) If needed, inspect `memory://root/MEMORY.md` and `memory://root/skills/<name>/SKILL.md`.
6
- 3) Trust memory for heuristics and process context. Trust current repo files, runtime output, and user instruction for factual state and final decisions.
7
- 4) When memory changes your plan, cite the artifact path (e.g. `memory://root/skills/<name>/SKILL.md`) and pair it with current-repo evidence.
8
- 5) If memory disagrees with repo state or user instruction, prefer repo/user. Treat memory as stale. Proceed with corrected behavior, then update/regenerate memory artifacts.
9
- 6) Escalate confidence only after repository verification. Memory alone is NEVER sufficient proof.
4
+ 1) The memory summary below is already injected; do not try to call or invent a `memory` tool.
5
+ 2) Treat memory as heuristic process context. Trust current repo files, runtime output, and user instruction for factual state and final decisions.
6
+ 3) When memory changes your plan, pair it with current-repo evidence before acting.
7
+ 4) If memory disagrees with repo state or user instruction, prefer repo/user. Treat memory as stale. Proceed with corrected behavior, then update/regenerate memory artifacts through supported memory commands when available.
8
+ 5) Escalate confidence only after repository verification. Memory alone is NEVER sufficient proof.
10
9
  Memory summary:
11
10
  {{memory_summary}}
@@ -1,9 +1,9 @@
1
1
  # Memory Guidance
2
- Memory root: memory://root
2
+ Memory backend: local private runtime state
3
3
  Status: local memory is enabled, but no confirmed memory payload is available for this project yet.
4
4
 
5
5
  Operational rules:
6
6
  1) Do not claim that a user preference, fact, or instruction has been saved, remembered, or persisted unless a backend operation or a non-empty memory payload confirms it.
7
7
  2) If the user asks you to save or remember something now, explain that durable memory is not confirmed because local memory has no available payload/readback yet. You may use the instruction for the current session only.
8
- 3) If reading `memory://root` or `memory://root/memory_summary.md` fails, treat that as no confirmed memory, not as successful persistence.
8
+ 3) Do not try to call or invent a `memory` tool; local memory readback is unavailable in this session.
9
9
  4) The local backend consolidates prior session rollouts asynchronously; an empty payload is a degraded/unconfirmed state, not a successful save.
@@ -6,7 +6,7 @@ Executes bash command in shell session for terminal operations like git, bun, ca
6
6
  - Quote variable expansions like `"$NAME"` to preserve exact content
7
7
  - PTY mode is opt-in: set `pty: true` only when the command needs a real terminal (e.g. `sudo`, `ssh` requiring user input); default is `false`
8
8
  - Use `;` only when later commands should run regardless of earlier failures
9
- - Internal URIs (`agent://`, `artifact://`, `memory://`, `rule://`, `local://`) are auto-resolved to filesystem paths
9
+ - Internal URIs (`agent://`, `artifact://`, `rule://`, `local://`) are auto-resolved to filesystem paths
10
10
  {{#if asyncEnabled}}
11
11
  - Use `async: true` for long-running commands when you don't need immediate output; the call returns a background job ID and the result is delivered automatically as a follow-up.
12
12
  {{/if}}
@@ -24,7 +24,7 @@ These rules apply to both sending and replying.
24
24
  - **Do not quote the message you are replying to.** The sender already saw it; the TUI already renders it. Lead with the answer.
25
25
  - **Use IRC, not terminal tools, to learn about peers.** Do not `grep` artifacts, read other sessions' JSONL files, or shell-poke around to figure out what another agent is doing. DM them — they have the live answer and you do not.
26
26
  - **One round-trip is enough.** Replies arrive synchronously when the recipient is reachable. Do not follow up with "did you get my message?" — they did. If `delivered` is empty or the result was `failed`, the peer is unavailable; move on or report the blocker, do not retry in a loop.
27
- - **Stay terse.** A DM is a chat message, not a memo. One question per send when you can. Share file paths and artifacts via `local://` / `memory://` / `artifact://` URLs instead of pasting blobs.
27
+ - **Stay terse.** A DM is a chat message, not a memo. One question per send when you can. Share file paths and artifacts via `local://` / `artifact://` URLs instead of pasting blobs.
28
28
  - **Address peers by id.** Use the exact id from `op: "list"` (e.g. `0-AuthLoader`, `0-Main`). Do not invent friendly names.
29
29
  - **Do not IRC for things a tool would answer.** If a `read`, `grep`, or build command would resolve the question, do that first.
30
30
  - **When you receive an IRC message, answer it before continuing.** The recipient injects the question + your auto-reply into your history; address it directly, do not repeat it back to the user.
@@ -8,7 +8,7 @@ Read files, directories, archives, SQLite databases, images, documents, internal
8
8
 
9
9
  ## Parameters
10
10
 
11
- - `path` — required. Local path, internal URI (`agent://`, `artifact://`, `memory://`, `rule://`, `local://`), or URL. Append `:<sel>` for line ranges, raw mode, or special modes (e.g. `src/foo.ts:50-200`, `src/foo.ts:raw`, `db.sqlite:users:42`).
11
+ - `path` — required. Local path, internal URI (`agent://`, `artifact://`, `rule://`, `local://`), or URL. Append `:<sel>` for line ranges, raw mode, or special modes (e.g. `src/foo.ts:50-200`, `src/foo.ts:raw`, `db.sqlite:users:42`).
12
12
 
13
13
  ## Selectors
14
14
 
@@ -70,7 +70,7 @@ For `.sqlite`, `.sqlite3`, `.db`, `.db3`:
70
70
 
71
71
  # Internal URIs
72
72
 
73
- `agent://<id>`, `artifact://<id>`, `memory://root`, `rule://<name>`, and `local://<name>.md` resolve transparently and accept the same line selectors as filesystem paths. Use `artifact://<id>` to recover full output that a previous bash/eval/tool result spilled or truncated.
73
+ `agent://<id>`, `artifact://<id>`, `rule://<name>`, and `local://<name>.md` resolve transparently and accept the same line selectors as filesystem paths. Use `artifact://<id>` to recover full output that a previous bash/eval/tool result spilled or truncated.
74
74
 
75
75
  <critical>
76
76
  - You MUST use `read` for every file, directory, archive, and URL inspection. `cat`, `head`, `tail`, `less`, `more`, `ls`, `tar`, `unzip`, `curl`, `wget` are FORBIDDEN — any such bash call is a bug, regardless of how short or convenient it looks.
@@ -1,3 +1,4 @@
1
+ Compatibility-only legacy Hindsight helper. This prompt is retained for backend/tool-call compatibility and is not part of the public gajae-code coding harness tool surface.
1
2
  Search long-term memory for relevant information. Returns raw matching entries ranked by relevance.
2
3
 
3
4
  Use proactively — before answering questions about past conversations, user preferences, project decisions, or any topic where prior context would help accuracy. When in doubt, recall first.
@@ -1,3 +1,4 @@
1
+ Compatibility-only legacy Hindsight helper. This prompt is retained for backend/tool-call compatibility and is not part of the public gajae-code coding harness tool surface.
1
2
  Generate a synthesised answer by reasoning over long-term memory. Unlike `recall`, `reflect` blends relevant memories into a coherent response.
2
3
 
3
4
  Use for open-ended questions spanning many stored facts: "What do you know about this user?", "Summarize project decisions.", "What are my preferences for X?"
@@ -1,3 +1,4 @@
1
+ Compatibility-only legacy Hindsight helper. This prompt is retained for backend/tool-call compatibility and is not part of the public gajae-code coding harness tool surface.
1
2
  Store one or more facts in long-term memory for future sessions.
2
3
 
3
4
  Use for durable, reusable knowledge: user preferences, project decisions, architectural choices, anything that improves future responses.
@@ -2,19 +2,22 @@ Lists, inspects, awaits, pauses, resumes, steers, or cancels detached task subag
2
2
 
3
3
  Task launches return immediately. Use this tool when you need direct control over those running subagents. Prefer `subagent` for task subagents; generic `job` remains available for non-subagent jobs and compatibility fallback access.
4
4
 
5
+ `verbosity` controls output size: `receipt` (default) returns status metadata plus a single <=280-character result/error preview and an `agent://<id>` output ref when available; `preview` returns <=2000 characters; `full` returns <=12000 characters and requires explicit `ids`.
6
+
5
7
  # Operations
6
8
 
7
9
  ## `action: "list"`
8
- Snapshot your visible detached subagents, including `running`, `paused`, `queued`, and terminal subagents when retained.
10
+ Snapshot your visible detached subagents, including `running`, `paused`, `queued`, and terminal subagents when retained. Output is receipt-only by default; use `verbosity: "preview"` for a bounded preview or inspect explicit `ids` with `verbosity: "full"` when fuller retained text is necessary.
9
11
 
10
12
  ## `action: "inspect"`
11
- Inspect selected subagents by `ids`; omit `ids` to inspect current running subagents. Terminal subagents include final output when retained.
13
+ Inspect selected subagents by `ids`; omit `ids` to inspect current running subagents. Terminal subagents return receipt-only output by default, with an `agent://<id>` ref when a verified output artifact is available. `verbosity: "full"` requires explicit `ids`.
12
14
 
13
15
  ## `action: "await"`
14
16
  Wait for selected subagents by `ids`; omit `ids` to wait for current running subagents.
15
17
  - Always set `timeout_ms` when the result is not immediately required forever.
16
18
  - Await timeout only bounds this tool call's wait; it does not stop the subagent and is not a failure reason.
17
19
  - On timeout, inspect progress and keep doing independent work. Never cancel just because an await timed out; cancel only if the subagent has actually failed, gone off-track, or become unrecoverably wrong.
20
+ - Completed results are receipt-first by default: bounded preview plus `agent://<id>` output ref when available, not full retained output.
18
21
 
19
22
  ## `action: "pause"`
20
23
  Request a graceful safe-boundary pause for selected subagents by `ids`.
@@ -22,18 +25,20 @@ Request a graceful safe-boundary pause for selected subagents by `ids`.
22
25
  - A paused subagent keeps its session context and can be resumed later.
23
26
 
24
27
  ## `action: "resume"`
25
- Resume selected non-running subagents by `ids`.
26
- - Optional `message` is delivered into the resumed run.
28
+ Resume one subagent by `id` (preferred) or a single-item `ids` array.
29
+ - Optional `message` is delivered into that one resumed run.
27
30
  - Running subagents are a no-op and return their current status snapshot.
28
31
  - Terminal subagents require `message` to start a follow-up resume run; without `message`, the tool returns the current snapshot with guidance.
29
32
  - `paused` subagents resume from saved context; `queued` subagents are already waiting for capacity.
33
+ - Multiple targets are rejected because one global `message` must not broadcast to several subagents.
30
34
 
31
35
  ## `action: "steer"`
32
- Send a non-empty `message` to selected subagents by `ids`.
33
- - Running subagents receive the message through their live handle.
36
+ Send a non-empty `message` to one subagent by `id` (preferred) or a single-item `ids` array.
37
+ - A running subagent receives the message through its live handle.
34
38
  - Optional `pause: true` requests a safe-boundary pause after steering a running subagent.
35
39
  - `pause` only matters while the target is running.
36
- - Non-active subagents (`paused`, `queued`, or terminal) automatically resume with the message; `pause` is ignored for these targets.
40
+ - A non-active subagent (`paused`, `queued`, or terminal) automatically resumes with the message; `pause` is ignored for that target.
41
+ - Multiple targets are rejected because one global `message` must not broadcast to several subagents.
37
42
 
38
43
  ## `action: "cancel"`
39
44
  Stop selected subagents by `ids`, including running, paused, or queued subagents.
@@ -5,15 +5,9 @@
5
5
  <agent id="{{id}}" agent="{{agent}}">
6
6
  <status>{{status}}</status>
7
7
  {{#if meta}}<meta lines="{{meta.lineCount}}" size="{{meta.charSize}}" />{{/if}}
8
- {{#if truncated}}
9
- <preview full-path="agent://{{id}}">
10
- {{preview}}
11
- </preview>
12
- {{else}}
13
- <result>
14
- {{preview}}
15
- </result>
16
- {{/if}}
8
+ <synopsis{{#if outputUri}} ref="{{outputUri}}"{{/if}}>
9
+ {{synopsis}}
10
+ </synopsis>
17
11
  </agent>
18
12
  {{#unless @last}}
19
13
  ---
@@ -24,13 +24,17 @@ Subagents have no conversation history. Every fact, file path, and direction the
24
24
  - `.assignment`: complete self-contained instructions; one-liners and missing acceptance criteria are PROHIBITED
25
25
  {{#if contextEnabled}}- `context`: shared background prepended to every assignment; session-specific only{{/if}}
26
26
  {{#if contextEnabled}}
27
- - `.inheritContext` (optional): `true` requests a sanitized, bounded forked snapshot of the parent conversation for this task. Works only when the global `task.forkContext.enabled` setting is true and the target agent declares `forkContext: allowed`; otherwise the call is rejected. Bundled agents that support it: `executor`, `architect`. Use it when the subagent's value depends on what the parent has already established (architect reviewing code the parent has been discussing; executor continuing a mid-investigation handoff). Skip it for independent work — passing context the child will not use wastes tokens. The child runs under its own agent-specific system prompt and tool surface, so treat seeded tokens as full re-billing rather than a prefix-cache hit.
27
+ - `.inheritContext` (optional): fork-context mode for seeding the subagent with sanitized parent conversation. Omit it or set `"none"` for no copied context. `"receipt"` copies a minimal receipt-sized snapshot, `"last-turn"` copies only the latest exchange, `"bounded"` copies the bounded default snapshot, and `"full"` copies a larger snapshot up to the configured/model token cap. Non-`none` modes work only when global `task.forkContext.enabled` is true and the target agent declares `forkContext: allowed`; otherwise the call is rejected. Bundled agents that support it: `executor`, `architect`. Use inherited context only when the subagent's value depends on parent context; cloned tokens are billed to the child as fresh input and surfaced in task receipts as fork-context cloned-token accounting.
28
28
  {{/if}}
29
+ {{#if independentMode}}- `.inheritContext`: independent mode cannot inherit parent conversation. Omit it or set `"none"`; any non-`none` value is rejected before scheduling.{{/if}}
29
30
  {{#if customSchemaEnabled}}- `schema`: JTD schema for expected structured output (do not put format rules in assignments){{/if}}
31
+ - `spawnPlan` (optional): required before any batch with more than 4 tasks, and before a reviewer agent spawns `explore`; include whyParallel, whyNotLocal, independence, expectedReceiptShape, and maxInlineTokens.
30
32
  {{#if isolationEnabled}}- `isolated`: run in isolated env; use when tasks edit overlapping files{{/if}}
31
33
  </parameters>
32
34
 
33
35
  <rules>
36
+ - HARD runtime gate: calls with more than 4 tasks are rejected before any child launches unless `spawnPlan` is complete.
37
+ - Reviewer->explore gate: a `reviewer` spawning `explore` is rejected before launch unless `spawnPlan` is complete, even for a single task.
34
38
  - NEVER assign tasks to run project-wide build/test/lint. Caller verifies after the batch.
35
39
  - **Subagents do not verify, lint, or format.** Every assignment MUST instruct the subagent to skip all gates and formatters. You run them once at the end across the union of changed files — avoids redundant runs and racing formatter passes.
36
40
  {{#if ircEnabled}}
package/src/sdk.ts CHANGED
@@ -31,6 +31,7 @@ import {
31
31
  prompt,
32
32
  Snowflake,
33
33
  } from "@gajae-code/utils";
34
+
34
35
  import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled } from "./async";
35
36
  import { loadCapability } from "./capability";
36
37
  import { type Rule, ruleCapability, setActiveRules } from "./capability/rule";
@@ -288,7 +289,9 @@ export interface CreateAgentSessionOptions {
288
289
  requireYieldTool?: boolean;
289
290
  /** Task recursion depth (for subagent sessions). Default: 0 */
290
291
  taskDepth?: number;
291
- /** Parent Hindsight state to alias for subagent memory tools. */
292
+ /** Current role-agent type/name for nested task sessions. */
293
+ currentAgentType?: string;
294
+ /** Parent Hindsight state to alias for subagent private memory backend compatibility. */
292
295
  parentHindsightSessionState?: HindsightSessionState;
293
296
  /** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
294
297
  agentId?: string;
@@ -1158,6 +1161,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1158
1161
  outputSchema: options.outputSchema,
1159
1162
  requireYieldTool: options.requireYieldTool,
1160
1163
  taskDepth: options.taskDepth ?? 0,
1164
+ currentAgentType: options.currentAgentType,
1161
1165
  getSessionFile: () => sessionManager.getSessionFile() ?? null,
1162
1166
  getEvalKernelOwnerId: () => evalKernelOwnerId,
1163
1167
  assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),