@gajae-code/coding-agent 0.2.5 → 0.3.1
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.
- package/CHANGELOG.md +28 -0
- package/dist/types/async/job-manager.d.ts +91 -2
- package/dist/types/cli/args.d.ts +1 -1
- package/dist/types/commands/deep-interview.d.ts +3 -0
- package/dist/types/commands/harness.d.ts +37 -0
- package/dist/types/config/keybindings.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +10 -4
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/debug/crash-diagnostics.d.ts +45 -0
- package/dist/types/debug/runtime-gauges.d.ts +6 -0
- package/dist/types/deep-interview/render-middleware.d.ts +6 -0
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/eval/py/kernel.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +10 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -0
- package/dist/types/extensibility/extensions/types.d.ts +6 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -0
- package/dist/types/gjc-runtime/cli-write-receipt.d.ts +24 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -0
- package/dist/types/gjc-runtime/state-graph.d.ts +4 -0
- package/dist/types/gjc-runtime/state-migrations.d.ts +33 -0
- package/dist/types/gjc-runtime/state-renderer.d.ts +65 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +2 -0
- package/dist/types/gjc-runtime/state-schema.d.ts +317 -0
- package/dist/types/gjc-runtime/state-validation.d.ts +6 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +147 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +81 -7
- package/dist/types/gjc-runtime/workflow-command-ref.d.ts +43 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +54 -0
- package/dist/types/harness-control-plane/classifier.d.ts +13 -0
- package/dist/types/harness-control-plane/control-endpoint.d.ts +31 -0
- package/dist/types/harness-control-plane/finalize.d.ts +47 -0
- package/dist/types/harness-control-plane/frame-mapper.d.ts +29 -0
- package/dist/types/harness-control-plane/operate.d.ts +35 -0
- package/dist/types/harness-control-plane/owner.d.ts +46 -0
- package/dist/types/harness-control-plane/preserve.d.ts +19 -0
- package/dist/types/harness-control-plane/receipts.d.ts +88 -0
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +66 -0
- package/dist/types/harness-control-plane/seams.d.ts +21 -0
- package/dist/types/harness-control-plane/session-lease.d.ts +65 -0
- package/dist/types/harness-control-plane/state-machine.d.ts +19 -0
- package/dist/types/harness-control-plane/storage.d.ts +53 -0
- package/dist/types/harness-control-plane/types.d.ts +162 -0
- package/dist/types/hooks/skill-keywords.d.ts +2 -1
- package/dist/types/hooks/skill-state.d.ts +23 -29
- package/dist/types/internal-urls/agent-protocol.d.ts +2 -2
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/registry-helpers.d.ts +8 -7
- package/dist/types/internal-urls/types.d.ts +4 -0
- package/dist/types/lsp/index.d.ts +10 -10
- package/dist/types/modes/bridge/auth.d.ts +12 -0
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +9 -0
- package/dist/types/modes/bridge/bridge-mode.d.ts +44 -0
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +88 -0
- package/dist/types/modes/bridge/event-stream.d.ts +8 -0
- package/dist/types/modes/components/custom-editor.d.ts +6 -0
- package/dist/types/modes/components/hook-selector.d.ts +1 -0
- package/dist/types/modes/components/jobs-overlay-model.d.ts +31 -0
- package/dist/types/modes/components/jobs-overlay.d.ts +30 -0
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/status-line.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +8 -0
- package/dist/types/modes/index.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/jobs-observer.d.ts +57 -0
- package/dist/types/modes/rpc/host-tools.d.ts +1 -16
- package/dist/types/modes/rpc/host-uris.d.ts +1 -38
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +20 -0
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +2 -0
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +24 -0
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +46 -0
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +16 -0
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +17 -0
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +44 -0
- package/dist/types/modes/shared/agent-wire/responses.d.ts +4 -0
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +18 -0
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +42 -0
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +27 -0
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/sdk.d.ts +4 -0
- package/dist/types/session/agent-session.d.ts +19 -1
- package/dist/types/skill-state/active-state.d.ts +2 -0
- package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +1 -1
- package/dist/types/skill-state/workflow-state-contract.d.ts +25 -2
- package/dist/types/skill-state/workflow-state-version.d.ts +3 -0
- package/dist/types/task/executor.d.ts +3 -0
- package/dist/types/task/id.d.ts +7 -0
- package/dist/types/task/index.d.ts +5 -0
- package/dist/types/task/receipt.d.ts +85 -0
- package/dist/types/task/spawn-gate.d.ts +38 -0
- package/dist/types/task/types.d.ts +198 -14
- package/dist/types/tools/cron.d.ts +6 -0
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/subagent.d.ts +26 -1
- package/package.json +7 -7
- package/scripts/build-binary.ts +7 -0
- package/src/async/job-manager.ts +334 -6
- package/src/cli/args.ts +9 -2
- package/src/cli/auth-broker-cli.ts +1 -0
- package/src/cli/config-cli.ts +10 -2
- package/src/cli.ts +2 -0
- package/src/commands/deep-interview.ts +1 -0
- package/src/commands/harness.ts +862 -0
- package/src/commands/launch.ts +2 -2
- package/src/commands/state.ts +2 -1
- package/src/commands/team.ts +54 -39
- package/src/config/keybindings.ts +6 -0
- package/src/config/settings-schema.ts +13 -3
- package/src/config/settings.ts +5 -0
- package/src/dap/client.ts +17 -3
- package/src/debug/crash-diagnostics.ts +223 -0
- package/src/debug/runtime-gauges.ts +20 -0
- package/src/deep-interview/render-middleware.ts +372 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ralplan/SKILL.md +31 -2
- package/src/defaults/gjc/skills/team/SKILL.md +47 -21
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +106 -13
- package/src/eval/py/executor.ts +21 -1
- package/src/eval/py/kernel.ts +15 -0
- package/src/exec/bash-executor.ts +41 -0
- package/src/extensibility/custom-tools/types.ts +1 -0
- package/src/extensibility/extensions/types.ts +6 -0
- package/src/extensibility/shared-events.ts +1 -0
- package/src/gjc-runtime/cli-write-receipt.ts +31 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +98 -42
- package/src/gjc-runtime/goal-mode-request.ts +11 -3
- package/src/gjc-runtime/ralplan-runtime.ts +235 -43
- package/src/gjc-runtime/state-graph.ts +86 -0
- package/src/gjc-runtime/state-migrations.ts +179 -0
- package/src/gjc-runtime/state-renderer.ts +345 -0
- package/src/gjc-runtime/state-runtime.ts +1155 -46
- package/src/gjc-runtime/state-schema.ts +192 -0
- package/src/gjc-runtime/state-validation.ts +49 -0
- package/src/gjc-runtime/state-writer.ts +749 -0
- package/src/gjc-runtime/team-runtime.ts +1255 -189
- package/src/gjc-runtime/ultragoal-runtime.ts +460 -43
- package/src/gjc-runtime/workflow-command-ref.ts +239 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +1601 -0
- package/src/gjc-runtime/workflow-manifest.ts +427 -0
- package/src/harness-control-plane/classifier.ts +128 -0
- package/src/harness-control-plane/control-endpoint.ts +148 -0
- package/src/harness-control-plane/finalize.ts +222 -0
- package/src/harness-control-plane/frame-mapper.ts +286 -0
- package/src/harness-control-plane/operate.ts +225 -0
- package/src/harness-control-plane/owner.ts +600 -0
- package/src/harness-control-plane/preserve.ts +102 -0
- package/src/harness-control-plane/receipts.ts +216 -0
- package/src/harness-control-plane/rpc-adapter.ts +276 -0
- package/src/harness-control-plane/seams.ts +39 -0
- package/src/harness-control-plane/session-lease.ts +388 -0
- package/src/harness-control-plane/state-machine.ts +98 -0
- package/src/harness-control-plane/storage.ts +257 -0
- package/src/harness-control-plane/types.ts +214 -0
- package/src/hooks/skill-keywords.ts +4 -2
- package/src/hooks/skill-state.ts +197 -64
- package/src/internal-urls/agent-protocol.ts +68 -21
- package/src/internal-urls/artifact-protocol.ts +12 -17
- package/src/internal-urls/docs-index.generated.ts +3 -2
- package/src/internal-urls/registry-helpers.ts +19 -16
- package/src/internal-urls/types.ts +4 -0
- package/src/lsp/client.ts +18 -2
- package/src/main.ts +21 -5
- package/src/modes/bridge/auth.ts +41 -0
- package/src/modes/bridge/bridge-client-bridge.ts +47 -0
- package/src/modes/bridge/bridge-mode.ts +520 -0
- package/src/modes/bridge/bridge-ui-context.ts +200 -0
- package/src/modes/bridge/event-stream.ts +70 -0
- package/src/modes/components/assistant-message.ts +5 -1
- package/src/modes/components/custom-editor.ts +101 -0
- package/src/modes/components/hook-selector.ts +133 -20
- package/src/modes/components/jobs-overlay-model.ts +109 -0
- package/src/modes/components/jobs-overlay.ts +172 -0
- package/src/modes/components/status-line/presets.ts +7 -5
- package/src/modes/components/status-line/segments.ts +25 -0
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/status-line.ts +9 -1
- package/src/modes/controllers/event-controller.ts +71 -6
- package/src/modes/controllers/extension-ui-controller.ts +43 -1
- package/src/modes/controllers/input-controller.ts +105 -9
- package/src/modes/controllers/selector-controller.ts +31 -1
- package/src/modes/index.ts +1 -0
- package/src/modes/interactive-mode.ts +28 -0
- package/src/modes/jobs-observer.ts +204 -0
- package/src/modes/rpc/host-tools.ts +1 -186
- package/src/modes/rpc/host-uris.ts +1 -235
- package/src/modes/rpc/rpc-client.ts +25 -10
- package/src/modes/rpc/rpc-mode.ts +12 -381
- package/src/modes/shared/agent-wire/command-dispatch.ts +341 -0
- package/src/modes/shared/agent-wire/command-validation.ts +131 -0
- package/src/modes/shared/agent-wire/event-envelope.ts +108 -0
- package/src/modes/shared/agent-wire/handshake.ts +117 -0
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +194 -0
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +236 -0
- package/src/modes/shared/agent-wire/protocol.ts +96 -0
- package/src/modes/shared/agent-wire/responses.ts +17 -0
- package/src/modes/shared/agent-wire/scopes.ts +89 -0
- package/src/modes/shared/agent-wire/ui-request-broker.ts +150 -0
- package/src/modes/shared/agent-wire/ui-result.ts +48 -0
- package/src/modes/types.ts +2 -0
- package/src/prompts/agents/executor.md +13 -0
- package/src/prompts/tools/subagent.md +39 -4
- package/src/prompts/tools/task-summary.md +3 -9
- package/src/prompts/tools/task.md +5 -1
- package/src/sdk.ts +8 -0
- package/src/session/agent-session.ts +445 -71
- package/src/session/session-manager.ts +13 -1
- package/src/skill-state/active-state.ts +58 -65
- package/src/skill-state/deep-interview-mutation-guard.ts +114 -17
- package/src/skill-state/initial-phase.ts +2 -0
- package/src/skill-state/workflow-state-contract.ts +33 -4
- package/src/skill-state/workflow-state-version.ts +3 -0
- package/src/slash-commands/builtin-registry.ts +8 -0
- package/src/task/executor.ts +79 -13
- package/src/task/id.ts +33 -0
- package/src/task/index.ts +376 -74
- package/src/task/output-manager.ts +5 -4
- package/src/task/receipt.ts +297 -0
- package/src/task/render.ts +54 -134
- package/src/task/spawn-gate.ts +132 -0
- package/src/task/types.ts +104 -10
- package/src/tools/ask.ts +88 -27
- package/src/tools/ast-edit.ts +1 -0
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash.ts +1 -1
- package/src/tools/cron.ts +48 -0
- package/src/tools/find.ts +4 -1
- package/src/tools/index.ts +2 -0
- package/src/tools/path-utils.ts +3 -2
- package/src/tools/read.ts +1 -0
- package/src/tools/search.ts +1 -0
- package/src/tools/skill.ts +6 -1
- package/src/tools/subagent.ts +423 -79
|
@@ -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
|
+
}
|
package/src/modes/types.ts
CHANGED
|
@@ -109,6 +109,7 @@ export interface InteractiveModeContext {
|
|
|
109
109
|
retryLoader: Loader | undefined;
|
|
110
110
|
autoCompactionEscapeHandler?: () => void;
|
|
111
111
|
retryEscapeHandler?: () => void;
|
|
112
|
+
retryCountdownTimer?: ReturnType<typeof setInterval>;
|
|
112
113
|
unsubscribe?: () => void;
|
|
113
114
|
onInputCallback?: (input: SubmittedUserInput) => void;
|
|
114
115
|
optimisticUserMessageSignature: string | undefined;
|
|
@@ -248,6 +249,7 @@ export interface InteractiveModeContext {
|
|
|
248
249
|
showHookConfirm(title: string, message: string): Promise<boolean>;
|
|
249
250
|
showDebugSelector(): void;
|
|
250
251
|
showSessionObserver(): void;
|
|
252
|
+
showJobsOverlay(): void;
|
|
251
253
|
resetObserverRegistry(): void;
|
|
252
254
|
|
|
253
255
|
// Input handling
|
|
@@ -31,6 +31,19 @@ Explore just enough context, implement the smallest correct change, and leave co
|
|
|
31
31
|
5. Remove debug leftovers and report changed files plus evidence.
|
|
32
32
|
</execution_loop>
|
|
33
33
|
|
|
34
|
+
<ultragoal_red_team_mode>
|
|
35
|
+
This mode activates only when the assignment explicitly labels Executor as Ultragoal completion QA/red-team or asks for `executorQa` red-team evidence. Otherwise, preserve ordinary Executor behavior.
|
|
36
|
+
|
|
37
|
+
When active:
|
|
38
|
+
- Start from the approved plan/spec/acceptance criteria, then user-facing contracts, then implementation code only as supporting evidence. Treat plan/code mismatches as blockers.
|
|
39
|
+
- Exercise the real user-facing invocation rather than inspecting internals alone: GUI/web uses browser automation plus screenshot or image verdict; CLI uses logs or terminal transcripts; API/package uses external consumer or black-box tests through the public interface; algorithm/math uses boundary, property, adversarial, and failure-mode cases.
|
|
40
|
+
- Try to break the work with adversarial cases, not just happy-path confirmations.
|
|
41
|
+
- Report the QA matrix with the final field names `executorQa.contractCoverage`, `executorQa.surfaceEvidence`, `executorQa.adversarialCases`, and `executorQa.artifactRefs`.
|
|
42
|
+
- Include artifact refs for every executed surface and adversarial case: transcript ids, log paths, screenshots, image verdicts, test outputs, or other durable evidence.
|
|
43
|
+
- Use `status: "not_applicable"` only for rows in `executorQa.contractCoverage` and `executorQa.surfaceEvidence`; each not-applicable row requires `contractRef` plus `reason`. `executorQa.adversarialCases` rows cannot be not-applicable.
|
|
44
|
+
- Report blockers for any missing plan/spec/acceptance source, contract ambiguity, plan/code mismatch, untestable surface, failed adversarial case, shallow evidence, or missing artifact ref.
|
|
45
|
+
</ultragoal_red_team_mode>
|
|
46
|
+
|
|
34
47
|
<success_criteria>
|
|
35
48
|
- Requested behavior is implemented in the assigned scope.
|
|
36
49
|
- Modified files match existing style and contracts.
|
|
@@ -1,21 +1,56 @@
|
|
|
1
|
-
Lists, inspects, awaits, or cancels detached task subagents.
|
|
1
|
+
Lists, inspects, awaits, pauses, resumes, steers, or cancels detached task subagents.
|
|
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.
|
|
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
|
|
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.
|
|
21
|
+
|
|
22
|
+
## `action: "pause"`
|
|
23
|
+
Request a graceful safe-boundary pause for selected subagents by `ids`.
|
|
24
|
+
- Non-running subagents are a no-op and return their current status snapshot.
|
|
25
|
+
- A paused subagent keeps its session context and can be resumed later.
|
|
26
|
+
|
|
27
|
+
## `action: "resume"`
|
|
28
|
+
Resume one subagent by `id` (preferred) or a single-item `ids` array.
|
|
29
|
+
- Optional `message` is delivered into that one resumed run.
|
|
30
|
+
- Running subagents are a no-op and return their current status snapshot.
|
|
31
|
+
- Terminal subagents require `message` to start a follow-up resume run; without `message`, the tool returns the current snapshot with guidance.
|
|
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.
|
|
34
|
+
|
|
35
|
+
## `action: "steer"`
|
|
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.
|
|
38
|
+
- Optional `pause: true` requests a safe-boundary pause after steering a running subagent.
|
|
39
|
+
- `pause` only matters while the target is running.
|
|
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.
|
|
18
42
|
|
|
19
43
|
## `action: "cancel"`
|
|
20
|
-
Stop selected
|
|
44
|
+
Stop selected subagents by `ids`, including running, paused, or queued subagents.
|
|
21
45
|
- Use only when the subagent has actually failed, gone off-track, or become unrecoverably wrong; an await timeout alone is never a cancellation reason.
|
|
46
|
+
- Cancellation keeps the subagent session file for possible later context recovery.
|
|
47
|
+
|
|
48
|
+
# Statuses
|
|
49
|
+
|
|
50
|
+
- `running` — currently executing.
|
|
51
|
+
- `paused` — stopped at a safe boundary with resumable context.
|
|
52
|
+
- `queued` — resume requested and waiting for execution capacity.
|
|
53
|
+
- `completed` — finished successfully.
|
|
54
|
+
- `failed` — finished with an error.
|
|
55
|
+
- `cancelled` — stopped by cancellation.
|
|
56
|
+
- `not_found` — no visible subagent matches the requested id.
|
|
@@ -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
|
|
9
|
-
|
|
10
|
-
|
|
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): `
|
|
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,6 +289,8 @@ export interface CreateAgentSessionOptions {
|
|
|
288
289
|
requireYieldTool?: boolean;
|
|
289
290
|
/** Task recursion depth (for subagent sessions). Default: 0 */
|
|
290
291
|
taskDepth?: number;
|
|
292
|
+
/** Current role-agent type/name for nested task sessions. */
|
|
293
|
+
currentAgentType?: string;
|
|
291
294
|
/** Parent Hindsight state to alias for subagent memory tools. */
|
|
292
295
|
parentHindsightSessionState?: HindsightSessionState;
|
|
293
296
|
/** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
|
|
@@ -327,6 +330,8 @@ export interface CreateAgentSessionOptions {
|
|
|
327
330
|
forkContextSeed?: ForkContextSeed;
|
|
328
331
|
/** Optional provider state override. Fork-context children should omit this by default. */
|
|
329
332
|
providerSessionState?: Map<string, ProviderSessionState>;
|
|
333
|
+
/** Cooperative pause checkpoint passed through to Agent. */
|
|
334
|
+
shouldPause?: () => boolean;
|
|
330
335
|
}
|
|
331
336
|
|
|
332
337
|
/** Result from createAgentSession */
|
|
@@ -657,6 +662,7 @@ function createCustomToolsExtension(tools: CustomTool[]): ExtensionFactory {
|
|
|
657
662
|
reason: "auto_retry_start",
|
|
658
663
|
attempt: event.attempt,
|
|
659
664
|
maxAttempts: event.maxAttempts,
|
|
665
|
+
unbounded: event.unbounded,
|
|
660
666
|
delayMs: event.delayMs,
|
|
661
667
|
errorMessage: event.errorMessage,
|
|
662
668
|
},
|
|
@@ -1155,6 +1161,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1155
1161
|
outputSchema: options.outputSchema,
|
|
1156
1162
|
requireYieldTool: options.requireYieldTool,
|
|
1157
1163
|
taskDepth: options.taskDepth ?? 0,
|
|
1164
|
+
currentAgentType: options.currentAgentType,
|
|
1158
1165
|
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
1159
1166
|
getEvalKernelOwnerId: () => evalKernelOwnerId,
|
|
1160
1167
|
assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),
|
|
@@ -1797,6 +1804,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1797
1804
|
requestMaxRetries: retrySettings.requestMaxRetries,
|
|
1798
1805
|
streamMaxRetries: retrySettings.streamMaxRetries,
|
|
1799
1806
|
kimiApiFormat: settings.get("providers.kimiApiFormat") ?? "anthropic",
|
|
1807
|
+
shouldPause: options.shouldPause,
|
|
1800
1808
|
preferWebsockets: preferOpenAICodexWebsockets,
|
|
1801
1809
|
getToolContext: tc => toolContextStore.getContext(tc),
|
|
1802
1810
|
getApiKey: async provider => {
|