@di-code/coding-agent 0.1.7 → 0.1.8
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/README.md +104 -46
- package/compositions/base.yml +54 -0
- package/compositions/interactive.yml +14 -0
- package/compositions/json.yml +6 -0
- package/compositions/print.yml +5 -0
- package/compositions/rpc.yml +12 -0
- package/compositions/webui.yml +9 -0
- package/dist/cli.d.ts +22 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +97 -3
- package/dist/cli.js.map +1 -1
- package/dist/composition-loader-entry.d.ts +11 -0
- package/dist/composition-loader-entry.d.ts.map +1 -0
- package/dist/composition-loader-entry.js +12 -0
- package/dist/composition-loader-entry.js.map +1 -0
- package/dist/compositions.d.ts +32 -0
- package/dist/compositions.d.ts.map +1 -0
- package/dist/compositions.js +173 -0
- package/dist/compositions.js.map +1 -0
- package/dist/core/session/session-manager.d.ts +9 -2
- package/dist/core/session/session-manager.d.ts.map +1 -1
- package/dist/core/session/session-manager.js +28 -0
- package/dist/core/session/session-manager.js.map +1 -1
- package/dist/core/session/session-storage.d.ts.map +1 -1
- package/dist/core/session/session-storage.js +20 -3
- package/dist/core/session/session-storage.js.map +1 -1
- package/dist/core/session/types.d.ts +11 -2
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/session/types.js.map +1 -1
- package/dist/core/session-tools.d.ts +5 -0
- package/dist/core/session-tools.d.ts.map +1 -0
- package/dist/core/session-tools.js +17 -0
- package/dist/core/session-tools.js.map +1 -0
- package/dist/core/session.d.ts +19 -7
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +71 -39
- package/dist/core/session.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -38
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +1 -207
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +1 -24
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -135
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +1 -26
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +1 -140
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +1 -23
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/file-search.d.ts +1 -13
- package/dist/core/tools/file-search.d.ts.map +1 -1
- package/dist/core/tools/file-search.js +1 -98
- package/dist/core/tools/file-search.js.map +1 -1
- package/dist/core/tools/glob.d.ts +1 -10
- package/dist/core/tools/glob.d.ts.map +1 -1
- package/dist/core/tools/glob.js +1 -43
- package/dist/core/tools/glob.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -12
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -66
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/load-skill.d.ts +1 -9
- package/dist/core/tools/load-skill.d.ts.map +1 -1
- package/dist/core/tools/load-skill.js +1 -21
- package/dist/core/tools/load-skill.js.map +1 -1
- package/dist/core/tools/path-boundary.d.ts +1 -4
- package/dist/core/tools/path-boundary.d.ts.map +1 -1
- package/dist/core/tools/path-boundary.js +1 -65
- package/dist/core/tools/path-boundary.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -16
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -131
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -16
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -44
- package/dist/core/tools/write.js.map +1 -1
- package/dist/entry.js +30 -28
- package/dist/entry.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/interactive/builtin.d.ts +17 -0
- package/dist/interactive/builtin.d.ts.map +1 -0
- package/dist/interactive/builtin.js +47 -0
- package/dist/interactive/builtin.js.map +1 -0
- package/dist/interactive/controller.d.ts +85 -0
- package/dist/interactive/controller.d.ts.map +1 -0
- package/dist/interactive/controller.js +211 -0
- package/dist/interactive/controller.js.map +1 -0
- package/dist/interactive/index.d.ts +3 -0
- package/dist/interactive/index.d.ts.map +1 -0
- package/dist/interactive/index.js +3 -0
- package/dist/interactive/index.js.map +1 -0
- package/dist/interactive-host-entry.d.ts +7 -0
- package/dist/interactive-host-entry.d.ts.map +1 -0
- package/dist/interactive-host-entry.js +123 -0
- package/dist/interactive-host-entry.js.map +1 -0
- package/dist/interactive-profile.d.ts +18 -0
- package/dist/interactive-profile.d.ts.map +1 -0
- package/dist/interactive-profile.js +290 -0
- package/dist/interactive-profile.js.map +1 -0
- package/dist/interactive-resources-entry.d.ts +7 -0
- package/dist/interactive-resources-entry.d.ts.map +1 -0
- package/dist/interactive-resources-entry.js +42 -0
- package/dist/interactive-resources-entry.js.map +1 -0
- package/dist/legacy-main.d.ts +39 -0
- package/dist/legacy-main.d.ts.map +1 -0
- package/dist/legacy-main.js +611 -0
- package/dist/legacy-main.js.map +1 -0
- package/dist/main.d.ts +15 -34
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +130 -518
- package/dist/main.js.map +1 -1
- package/dist/mcp/entries.d.ts +42 -0
- package/dist/mcp/entries.d.ts.map +1 -0
- package/dist/mcp/entries.js +98 -0
- package/dist/mcp/entries.js.map +1 -0
- package/dist/mcp-client-entry.d.ts +5 -0
- package/dist/mcp-client-entry.d.ts.map +1 -0
- package/dist/mcp-client-entry.js +6 -0
- package/dist/mcp-client-entry.js.map +1 -0
- package/dist/mcp-config-entry.d.ts +5 -0
- package/dist/mcp-config-entry.d.ts.map +1 -0
- package/dist/mcp-config-entry.js +6 -0
- package/dist/mcp-config-entry.js.map +1 -0
- package/dist/mcp-tools-entry.d.ts +5 -0
- package/dist/mcp-tools-entry.d.ts.map +1 -0
- package/dist/mcp-tools-entry.js +6 -0
- package/dist/mcp-tools-entry.js.map +1 -0
- package/dist/mcp-transport-entry.d.ts +5 -0
- package/dist/mcp-transport-entry.d.ts.map +1 -0
- package/dist/mcp-transport-entry.js +6 -0
- package/dist/mcp-transport-entry.js.map +1 -0
- package/dist/modes/interactive-entry.d.ts +18 -0
- package/dist/modes/interactive-entry.d.ts.map +1 -0
- package/dist/modes/interactive-entry.js +21 -0
- package/dist/modes/interactive-entry.js.map +1 -0
- package/dist/modes/interactive.d.ts +16 -6
- package/dist/modes/interactive.d.ts.map +1 -1
- package/dist/modes/interactive.js +81 -32
- package/dist/modes/interactive.js.map +1 -1
- package/dist/modes/json-entry.d.ts +13 -0
- package/dist/modes/json-entry.d.ts.map +1 -0
- package/dist/modes/json-entry.js +14 -0
- package/dist/modes/json-entry.js.map +1 -0
- package/dist/modes/json.d.ts +4 -1
- package/dist/modes/json.d.ts.map +1 -1
- package/dist/modes/json.js +3 -3
- package/dist/modes/json.js.map +1 -1
- package/dist/modes/print-entry.d.ts +10 -0
- package/dist/modes/print-entry.d.ts.map +1 -0
- package/dist/modes/print-entry.js +11 -0
- package/dist/modes/print-entry.js.map +1 -0
- package/dist/modes/tree-selector.d.ts.map +1 -1
- package/dist/modes/tree-selector.js +4 -0
- package/dist/modes/tree-selector.js.map +1 -1
- package/dist/plugin-dump-composition.d.ts +6 -0
- package/dist/plugin-dump-composition.d.ts.map +1 -0
- package/dist/plugin-dump-composition.js +7 -0
- package/dist/plugin-dump-composition.js.map +1 -0
- package/dist/plugin-inventory.d.ts +7 -0
- package/dist/plugin-inventory.d.ts.map +1 -0
- package/dist/plugin-inventory.js +8 -0
- package/dist/plugin-inventory.js.map +1 -0
- package/dist/plugin-manager.d.ts +6 -0
- package/dist/plugin-manager.d.ts.map +1 -0
- package/dist/plugin-manager.js +7 -0
- package/dist/plugin-manager.js.map +1 -0
- package/dist/plugin-trace.d.ts +6 -0
- package/dist/plugin-trace.d.ts.map +1 -0
- package/dist/plugin-trace.js +7 -0
- package/dist/plugin-trace.js.map +1 -0
- package/dist/plugins/dynamic-broker.d.ts +76 -0
- package/dist/plugins/dynamic-broker.d.ts.map +1 -0
- package/dist/plugins/dynamic-broker.js +852 -0
- package/dist/plugins/dynamic-broker.js.map +1 -0
- package/dist/plugins/profile.d.ts +15 -0
- package/dist/plugins/profile.d.ts.map +1 -0
- package/dist/plugins/profile.js +34 -0
- package/dist/plugins/profile.js.map +1 -0
- package/dist/plugins/runtime-host.d.ts +37 -0
- package/dist/plugins/runtime-host.d.ts.map +1 -0
- package/dist/plugins/runtime-host.js +95 -0
- package/dist/plugins/runtime-host.js.map +1 -0
- package/dist/plugins/trust.d.ts +8 -0
- package/dist/plugins/trust.d.ts.map +1 -0
- package/dist/plugins/trust.js +59 -0
- package/dist/plugins/trust.js.map +1 -0
- package/dist/project-trust-entry.d.ts +15 -0
- package/dist/project-trust-entry.d.ts.map +1 -0
- package/dist/project-trust-entry.js +15 -0
- package/dist/project-trust-entry.js.map +1 -0
- package/dist/rpc/client.d.ts +78 -6
- package/dist/rpc/client.d.ts.map +1 -1
- package/dist/rpc/client.js +172 -4
- package/dist/rpc/client.js.map +1 -1
- package/dist/rpc/dispatcher.d.ts +121 -0
- package/dist/rpc/dispatcher.d.ts.map +1 -0
- package/dist/rpc/dispatcher.js +994 -0
- package/dist/rpc/dispatcher.js.map +1 -0
- package/dist/rpc/index.d.ts +2 -0
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +2 -0
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/lifecycle.d.ts +6 -0
- package/dist/rpc/lifecycle.d.ts.map +1 -0
- package/dist/rpc/lifecycle.js +24 -0
- package/dist/rpc/lifecycle.js.map +1 -0
- package/dist/rpc/protocol.d.ts +112 -31
- package/dist/rpc/protocol.d.ts.map +1 -1
- package/dist/rpc/protocol.js +569 -117
- package/dist/rpc/protocol.js.map +1 -1
- package/dist/rpc/server-service.d.ts +7 -0
- package/dist/rpc/server-service.d.ts.map +1 -0
- package/dist/rpc/server-service.js +3 -0
- package/dist/rpc/server-service.js.map +1 -0
- package/dist/rpc/server.d.ts +16 -19
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +59 -115
- package/dist/rpc/server.js.map +1 -1
- package/dist/rpc-client-sdk-entry.d.ts +12 -0
- package/dist/rpc-client-sdk-entry.d.ts.map +1 -0
- package/dist/rpc-client-sdk-entry.js +11 -0
- package/dist/rpc-client-sdk-entry.js.map +1 -0
- package/dist/rpc-entry.js +50 -18
- package/dist/rpc-entry.js.map +1 -1
- package/dist/rpc-server-entry.d.ts +8 -0
- package/dist/rpc-server-entry.d.ts.map +1 -0
- package/dist/rpc-server-entry.js +67 -0
- package/dist/rpc-server-entry.js.map +1 -0
- package/dist/runtime/attachment-store.d.ts +13 -0
- package/dist/runtime/attachment-store.d.ts.map +1 -0
- package/dist/runtime/attachment-store.js +93 -0
- package/dist/runtime/attachment-store.js.map +1 -0
- package/dist/runtime/bootstrap.d.ts +14 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -0
- package/dist/runtime/bootstrap.js +29 -0
- package/dist/runtime/bootstrap.js.map +1 -0
- package/dist/runtime/interactive-host-service.d.ts +22 -0
- package/dist/runtime/interactive-host-service.d.ts.map +1 -0
- package/dist/runtime/interactive-host-service.js +2 -0
- package/dist/runtime/interactive-host-service.js.map +1 -0
- package/dist/runtime/interactive-resource-service.d.ts +11 -0
- package/dist/runtime/interactive-resource-service.d.ts.map +1 -0
- package/dist/runtime/interactive-resource-service.js +3 -0
- package/dist/runtime/interactive-resource-service.js.map +1 -0
- package/dist/runtime/plugin-inventory-entry.d.ts +5 -0
- package/dist/runtime/plugin-inventory-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-inventory-entry.js +18 -0
- package/dist/runtime/plugin-inventory-entry.js.map +1 -0
- package/dist/runtime/plugin-inventory-service.d.ts +8 -0
- package/dist/runtime/plugin-inventory-service.d.ts.map +1 -0
- package/dist/runtime/plugin-inventory-service.js +3 -0
- package/dist/runtime/plugin-inventory-service.js.map +1 -0
- package/dist/runtime/plugin-manager-entry.d.ts +20 -0
- package/dist/runtime/plugin-manager-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-manager-entry.js +96 -0
- package/dist/runtime/plugin-manager-entry.js.map +1 -0
- package/dist/runtime/plugin-observability-entry.d.ts +12 -0
- package/dist/runtime/plugin-observability-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-observability-entry.js +73 -0
- package/dist/runtime/plugin-observability-entry.js.map +1 -0
- package/dist/runtime/product-host.d.ts +91 -0
- package/dist/runtime/product-host.d.ts.map +1 -0
- package/dist/runtime/product-host.js +529 -0
- package/dist/runtime/product-host.js.map +1 -0
- package/dist/runtime/session-factory.d.ts +17 -0
- package/dist/runtime/session-factory.d.ts.map +1 -0
- package/dist/runtime/session-factory.js +75 -0
- package/dist/runtime/session-factory.js.map +1 -0
- package/dist/runtime/session-host.d.ts +152 -0
- package/dist/runtime/session-host.d.ts.map +1 -0
- package/dist/runtime/session-host.js +895 -0
- package/dist/runtime/session-host.js.map +1 -0
- package/dist/runtime-core-entry.d.ts +11 -0
- package/dist/runtime-core-entry.d.ts.map +1 -0
- package/dist/runtime-core-entry.js +9 -0
- package/dist/runtime-core-entry.js.map +1 -0
- package/dist/session-factory-entry.d.ts +7 -0
- package/dist/session-factory-entry.d.ts.map +1 -0
- package/dist/session-factory-entry.js +9 -0
- package/dist/session-factory-entry.js.map +1 -0
- package/dist/session-store-jsonl-entry.d.ts +7 -0
- package/dist/session-store-jsonl-entry.d.ts.map +1 -0
- package/dist/session-store-jsonl-entry.js +33 -0
- package/dist/session-store-jsonl-entry.js.map +1 -0
- package/dist/startup.d.ts +12 -1
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +106 -15
- package/dist/startup.js.map +1 -1
- package/dist/subagents/index.d.ts +2 -0
- package/dist/subagents/index.d.ts.map +1 -0
- package/dist/subagents/index.js +2 -0
- package/dist/subagents/index.js.map +1 -0
- package/dist/subagents/service.d.ts +50 -0
- package/dist/subagents/service.d.ts.map +1 -0
- package/dist/subagents/service.js +521 -0
- package/dist/subagents/service.js.map +1 -0
- package/dist/ui-host.d.ts +125 -0
- package/dist/ui-host.d.ts.map +1 -0
- package/dist/ui-host.js +275 -0
- package/dist/ui-host.js.map +1 -0
- package/dist/web/assets/index-BwfuGMvv.css +1 -0
- package/dist/web/assets/index-DPUaJqFJ.js +41 -0
- package/dist/web/assets/index-DPUaJqFJ.js.map +1 -0
- package/dist/web/index.html +14 -0
- package/dist/web-command.d.ts +11 -0
- package/dist/web-command.d.ts.map +1 -0
- package/dist/web-command.js +114 -0
- package/dist/web-command.js.map +1 -0
- package/dist/web-frontend.d.ts +73 -0
- package/dist/web-frontend.d.ts.map +1 -0
- package/dist/web-frontend.js +249 -0
- package/dist/web-frontend.js.map +1 -0
- package/dist/web.d.ts +254 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +740 -0
- package/dist/web.js.map +1 -0
- package/dist/webui-entry.d.ts +3 -0
- package/dist/webui-entry.d.ts.map +1 -0
- package/dist/webui-entry.js +73 -0
- package/dist/webui-entry.js.map +1 -0
- package/dist/webui.d.ts +91 -0
- package/dist/webui.d.ts.map +1 -0
- package/dist/webui.js +882 -0
- package/dist/webui.js.map +1 -0
- package/package.json +89 -8
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { InteractiveProjection } from "../modes/interactive-state.js";
|
|
2
|
+
/** Product-layer controller shared by the builtin TUI and future frontends. */
|
|
3
|
+
export class InteractiveController {
|
|
4
|
+
session;
|
|
5
|
+
sessionChoices;
|
|
6
|
+
runtimePluginHost;
|
|
7
|
+
projection = new InteractiveProjection();
|
|
8
|
+
listeners = new Set();
|
|
9
|
+
unsubscribeSession;
|
|
10
|
+
activeAbort;
|
|
11
|
+
promptActive = false;
|
|
12
|
+
switching = false;
|
|
13
|
+
compactionActive = false;
|
|
14
|
+
queue = [];
|
|
15
|
+
lastRetryInput;
|
|
16
|
+
disposed = false;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.session = options.session;
|
|
19
|
+
this.sessionChoices = [...(options.sessions ?? [])];
|
|
20
|
+
this.runtimePluginHost = options.runtimePluginHost;
|
|
21
|
+
this.projection.replaceTranscript(this.session.transcript);
|
|
22
|
+
this.projection.setUsage(this.session.usage);
|
|
23
|
+
this.subscribeSession();
|
|
24
|
+
}
|
|
25
|
+
get state() {
|
|
26
|
+
return {
|
|
27
|
+
...this.projection.state,
|
|
28
|
+
model: `${this.session.modelId}${this.session.thinkingLevel ? `(${this.session.thinkingLevel})` : ""}`,
|
|
29
|
+
provider: this.session.providerId,
|
|
30
|
+
sessionId: this.session.sessionId,
|
|
31
|
+
streaming: this.promptActive,
|
|
32
|
+
subagents: this.session.subagents?.list().map((run) => ({ id: run.id, status: run.status })) ?? [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Restricted panel data and result formatters supplied by active plugin scopes. */
|
|
36
|
+
get ui() {
|
|
37
|
+
return this.runtimePluginHost?.getUiContributions() ?? { panels: [], toolDetailRenderers: [] };
|
|
38
|
+
}
|
|
39
|
+
subscribe(listener) {
|
|
40
|
+
if (this.disposed)
|
|
41
|
+
throw new Error("Interactive controller is disposed.");
|
|
42
|
+
this.listeners.add(listener);
|
|
43
|
+
return { dispose: () => this.listeners.delete(listener) };
|
|
44
|
+
}
|
|
45
|
+
async submit(input) {
|
|
46
|
+
if (this.disposed)
|
|
47
|
+
throw new Error("Interactive controller is disposed.");
|
|
48
|
+
const text = typeof input === "string" ? input.trim() : input.text.trim();
|
|
49
|
+
if (!text)
|
|
50
|
+
return;
|
|
51
|
+
if (this.switching)
|
|
52
|
+
throw new Error("A session is opening; wait before submitting a prompt.");
|
|
53
|
+
if (this.compactionActive)
|
|
54
|
+
throw new Error("A compaction is running; wait before submitting a prompt.");
|
|
55
|
+
if (this.promptActive) {
|
|
56
|
+
this.queue.push(typeof input === "string" ? text : { ...input, text });
|
|
57
|
+
this.projection.setQueue(this.queue.map((item) => (typeof item === "string" ? item : item.text)));
|
|
58
|
+
this.emitState();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.promptActive = true;
|
|
62
|
+
this.activeAbort = new AbortController();
|
|
63
|
+
this.emitState();
|
|
64
|
+
try {
|
|
65
|
+
const result = typeof input === "string"
|
|
66
|
+
? await this.session.prompt(input, this.activeAbort.signal)
|
|
67
|
+
: await this.session.promptWithImages(input.text, input.images ?? [], this.activeAbort.signal);
|
|
68
|
+
if (result.stopReason === "error" || result.stopReason === "aborted") {
|
|
69
|
+
this.lastRetryInput = typeof input === "string" ? input : { ...input, images: [...(input.images ?? [])] };
|
|
70
|
+
this.projection.setError(result.errorMessage);
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
this.lastRetryInput = undefined;
|
|
74
|
+
}
|
|
75
|
+
catch (cause) {
|
|
76
|
+
this.lastRetryInput = typeof input === "string" ? input : { ...input, images: [...(input.images ?? [])] };
|
|
77
|
+
this.reportError(cause);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this.promptActive = false;
|
|
81
|
+
this.activeAbort = undefined;
|
|
82
|
+
this.emitState();
|
|
83
|
+
const next = this.queue.shift();
|
|
84
|
+
this.projection.setQueue(this.queue.map((item) => (typeof item === "string" ? item : item.text)));
|
|
85
|
+
if (next && !this.disposed)
|
|
86
|
+
void this.submit(next);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
steer(input) {
|
|
90
|
+
void this.steerAsync(input);
|
|
91
|
+
}
|
|
92
|
+
cancel() {
|
|
93
|
+
this.activeAbort?.abort();
|
|
94
|
+
}
|
|
95
|
+
async retry() {
|
|
96
|
+
if (!this.lastRetryInput)
|
|
97
|
+
throw new Error("There is no failed or cancelled prompt to retry.");
|
|
98
|
+
if (this.promptActive)
|
|
99
|
+
throw new Error("Cannot retry while a prompt is running.");
|
|
100
|
+
await this.submit(this.lastRetryInput);
|
|
101
|
+
}
|
|
102
|
+
async runCommand(name, args) {
|
|
103
|
+
if (!this.runtimePluginHost)
|
|
104
|
+
throw new Error(`Unknown plugin command: "${name}"`);
|
|
105
|
+
await this.runtimePluginHost.runCommand(name, args, this.session.sessionId);
|
|
106
|
+
}
|
|
107
|
+
selectModel(modelId) {
|
|
108
|
+
this.session.setModel(modelId);
|
|
109
|
+
this.emitState();
|
|
110
|
+
}
|
|
111
|
+
async openSession(sessionId) {
|
|
112
|
+
if (this.promptActive || this.switching)
|
|
113
|
+
throw new Error("Cannot switch sessions while a prompt is running.");
|
|
114
|
+
const choice = this.sessionChoices.find((item) => item.id === sessionId);
|
|
115
|
+
if (!choice)
|
|
116
|
+
throw new Error(`Unknown session: "${sessionId}"`);
|
|
117
|
+
this.switching = true;
|
|
118
|
+
try {
|
|
119
|
+
await this.session.disposeSubagents();
|
|
120
|
+
const next = await choice.open();
|
|
121
|
+
this.unsubscribeSession?.();
|
|
122
|
+
this.session = next;
|
|
123
|
+
this.projection.replaceTranscript(next.transcript);
|
|
124
|
+
this.projection.setUsage(next.usage);
|
|
125
|
+
this.subscribeSession();
|
|
126
|
+
this.emitState();
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
this.switching = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async createSession() {
|
|
133
|
+
await this.openSession("new-session");
|
|
134
|
+
}
|
|
135
|
+
async requestCompaction() {
|
|
136
|
+
if (this.promptActive || this.compactionActive)
|
|
137
|
+
throw new Error("Cannot compact while a prompt is running.");
|
|
138
|
+
this.compactionActive = true;
|
|
139
|
+
this.emitState();
|
|
140
|
+
try {
|
|
141
|
+
await this.session.compact();
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
this.compactionActive = false;
|
|
145
|
+
this.emitState();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
dispose() {
|
|
149
|
+
if (this.disposed)
|
|
150
|
+
return;
|
|
151
|
+
this.disposed = true;
|
|
152
|
+
this.activeAbort?.abort();
|
|
153
|
+
this.unsubscribeSession?.();
|
|
154
|
+
this.unsubscribeSession = undefined;
|
|
155
|
+
this.listeners.clear();
|
|
156
|
+
}
|
|
157
|
+
async disposeSubagents() {
|
|
158
|
+
await this.session.disposeSubagents();
|
|
159
|
+
}
|
|
160
|
+
async steerAsync(input) {
|
|
161
|
+
if (!this.promptActive) {
|
|
162
|
+
this.reportError(new Error("Steering is only available while a prompt is running."));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
if (typeof input === "string")
|
|
167
|
+
await this.session.steer(input);
|
|
168
|
+
else
|
|
169
|
+
await this.session.steerWithImages(input.text, input.images ?? []);
|
|
170
|
+
}
|
|
171
|
+
catch (cause) {
|
|
172
|
+
this.reportError(cause);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
subscribeSession() {
|
|
176
|
+
this.unsubscribeSession = this.session.subscribeSession((event) => {
|
|
177
|
+
if (event.type === "queue_update")
|
|
178
|
+
this.projection.setQueue(event.steering);
|
|
179
|
+
else if (event.type === "tree_navigated")
|
|
180
|
+
this.projection.replaceTranscript(this.session.transcript);
|
|
181
|
+
else if (event.type.startsWith("subagent_")) {
|
|
182
|
+
// Subagent state is read through the restricted controller projection above.
|
|
183
|
+
}
|
|
184
|
+
else
|
|
185
|
+
this.projection.apply(event);
|
|
186
|
+
this.emit({ type: "session_event", event });
|
|
187
|
+
this.emitState();
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
emitState() {
|
|
191
|
+
this.emit({ type: "state", state: this.state });
|
|
192
|
+
}
|
|
193
|
+
emit(event) {
|
|
194
|
+
for (const listener of this.listeners) {
|
|
195
|
+
try {
|
|
196
|
+
listener(event);
|
|
197
|
+
}
|
|
198
|
+
catch (cause) {
|
|
199
|
+
this.reportError(cause);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
reportError(cause) {
|
|
204
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
205
|
+
this.projection.setError(message);
|
|
206
|
+
for (const listener of this.listeners)
|
|
207
|
+
listener({ type: "diagnostic", message });
|
|
208
|
+
this.emitState();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/interactive/controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent } from \"@di-code/ai\";\nimport type { PluginUiContributions } from \"@di-code/plugin-runtime\";\nimport type { AgentSession, AgentSessionEvent } from \"../core/session.ts\";\nimport { InteractiveProjection, type InteractiveState } from \"../modes/interactive-state.ts\";\nimport type { CodingAgentPluginHost } from \"../plugins/runtime-host.ts\";\n\nexport type InteractiveInput = string | { readonly text: string; readonly images?: readonly ImageContent[] };\n\nexport interface InteractiveSessionChoice {\n\treadonly id: string;\n\treadonly label: string;\n\treadonly description?: string;\n\topen(): AgentSession | Promise<AgentSession>;\n}\n\nexport interface InteractiveControllerState extends InteractiveState {\n\treadonly model: string;\n\treadonly provider: string;\n\treadonly sessionId: string;\n\treadonly streaming: boolean;\n\t/** Child runs are host-owned and expose no Agent or Session internals to a frontend. */\n\treadonly subagents: readonly {\n\t\treadonly id: string;\n\t\treadonly status: import(\"@di-code/plugin-runtime\").SubagentStatus;\n\t}[];\n}\n\nexport type InteractiveViewEvent =\n\t| { readonly type: \"state\"; readonly state: InteractiveControllerState }\n\t| { readonly type: \"session_event\"; readonly event: AgentSessionEvent }\n\t| { readonly type: \"diagnostic\"; readonly message: string }\n\t| { readonly type: \"exit\"; readonly reason: \"user\" | \"error\" };\n\nexport type InteractiveControllerListener = (event: InteractiveViewEvent) => void;\n\nexport interface InteractiveControllerOptions {\n\treadonly session: AgentSession;\n\treadonly sessions?: readonly InteractiveSessionChoice[];\n\treadonly runtimePluginHost?: CodingAgentPluginHost;\n}\n\n/** Product-layer controller shared by the builtin TUI and future frontends. */\nexport class InteractiveController {\n\tprivate session: AgentSession;\n\tprivate readonly sessionChoices: readonly InteractiveSessionChoice[];\n\tprivate readonly runtimePluginHost?: CodingAgentPluginHost;\n\tprivate readonly projection = new InteractiveProjection();\n\tprivate readonly listeners = new Set<InteractiveControllerListener>();\n\tprivate unsubscribeSession?: () => void;\n\tprivate activeAbort?: AbortController;\n\tprivate promptActive = false;\n\tprivate switching = false;\n\tprivate compactionActive = false;\n\tprivate queue: InteractiveInput[] = [];\n\tprivate lastRetryInput?: InteractiveInput;\n\tprivate disposed = false;\n\n\tconstructor(options: InteractiveControllerOptions) {\n\t\tthis.session = options.session;\n\t\tthis.sessionChoices = [...(options.sessions ?? [])];\n\t\tthis.runtimePluginHost = options.runtimePluginHost;\n\t\tthis.projection.replaceTranscript(this.session.transcript);\n\t\tthis.projection.setUsage(this.session.usage);\n\t\tthis.subscribeSession();\n\t}\n\n\tget state(): InteractiveControllerState {\n\t\treturn {\n\t\t\t...this.projection.state,\n\t\t\tmodel: `${this.session.modelId}${this.session.thinkingLevel ? `(${this.session.thinkingLevel})` : \"\"}`,\n\t\t\tprovider: this.session.providerId,\n\t\t\tsessionId: this.session.sessionId,\n\t\t\tstreaming: this.promptActive,\n\t\t\tsubagents: this.session.subagents?.list().map((run) => ({ id: run.id, status: run.status })) ?? [],\n\t\t};\n\t}\n\n\t/** Restricted panel data and result formatters supplied by active plugin scopes. */\n\tget ui(): PluginUiContributions {\n\t\treturn this.runtimePluginHost?.getUiContributions() ?? { panels: [], toolDetailRenderers: [] };\n\t}\n\n\tsubscribe(listener: InteractiveControllerListener): { dispose(): void } {\n\t\tif (this.disposed) throw new Error(\"Interactive controller is disposed.\");\n\t\tthis.listeners.add(listener);\n\t\treturn { dispose: () => this.listeners.delete(listener) };\n\t}\n\n\tasync submit(input: InteractiveInput): Promise<void> {\n\t\tif (this.disposed) throw new Error(\"Interactive controller is disposed.\");\n\t\tconst text = typeof input === \"string\" ? input.trim() : input.text.trim();\n\t\tif (!text) return;\n\t\tif (this.switching) throw new Error(\"A session is opening; wait before submitting a prompt.\");\n\t\tif (this.compactionActive) throw new Error(\"A compaction is running; wait before submitting a prompt.\");\n\t\tif (this.promptActive) {\n\t\t\tthis.queue.push(typeof input === \"string\" ? text : { ...input, text });\n\t\t\tthis.projection.setQueue(this.queue.map((item) => (typeof item === \"string\" ? item : item.text)));\n\t\t\tthis.emitState();\n\t\t\treturn;\n\t\t}\n\t\tthis.promptActive = true;\n\t\tthis.activeAbort = new AbortController();\n\t\tthis.emitState();\n\t\ttry {\n\t\t\tconst result =\n\t\t\t\ttypeof input === \"string\"\n\t\t\t\t\t? await this.session.prompt(input, this.activeAbort.signal)\n\t\t\t\t\t: await this.session.promptWithImages(input.text, input.images ?? [], this.activeAbort.signal);\n\t\t\tif (result.stopReason === \"error\" || result.stopReason === \"aborted\") {\n\t\t\t\tthis.lastRetryInput = typeof input === \"string\" ? input : { ...input, images: [...(input.images ?? [])] };\n\t\t\t\tthis.projection.setError(result.errorMessage);\n\t\t\t} else this.lastRetryInput = undefined;\n\t\t} catch (cause) {\n\t\t\tthis.lastRetryInput = typeof input === \"string\" ? input : { ...input, images: [...(input.images ?? [])] };\n\t\t\tthis.reportError(cause);\n\t\t} finally {\n\t\t\tthis.promptActive = false;\n\t\t\tthis.activeAbort = undefined;\n\t\t\tthis.emitState();\n\t\t\tconst next = this.queue.shift();\n\t\t\tthis.projection.setQueue(this.queue.map((item) => (typeof item === \"string\" ? item : item.text)));\n\t\t\tif (next && !this.disposed) void this.submit(next);\n\t\t}\n\t}\n\n\tsteer(input: InteractiveInput): void {\n\t\tvoid this.steerAsync(input);\n\t}\n\n\tcancel(): void {\n\t\tthis.activeAbort?.abort();\n\t}\n\n\tasync retry(): Promise<void> {\n\t\tif (!this.lastRetryInput) throw new Error(\"There is no failed or cancelled prompt to retry.\");\n\t\tif (this.promptActive) throw new Error(\"Cannot retry while a prompt is running.\");\n\t\tawait this.submit(this.lastRetryInput);\n\t}\n\n\tasync runCommand(name: string, args: string): Promise<void> {\n\t\tif (!this.runtimePluginHost) throw new Error(`Unknown plugin command: \"${name}\"`);\n\t\tawait this.runtimePluginHost.runCommand(name, args, this.session.sessionId);\n\t}\n\n\tselectModel(modelId: string): void {\n\t\tthis.session.setModel(modelId);\n\t\tthis.emitState();\n\t}\n\n\tasync openSession(sessionId: string): Promise<void> {\n\t\tif (this.promptActive || this.switching) throw new Error(\"Cannot switch sessions while a prompt is running.\");\n\t\tconst choice = this.sessionChoices.find((item) => item.id === sessionId);\n\t\tif (!choice) throw new Error(`Unknown session: \"${sessionId}\"`);\n\t\tthis.switching = true;\n\t\ttry {\n\t\t\tawait this.session.disposeSubagents();\n\t\t\tconst next = await choice.open();\n\t\t\tthis.unsubscribeSession?.();\n\t\t\tthis.session = next;\n\t\t\tthis.projection.replaceTranscript(next.transcript);\n\t\t\tthis.projection.setUsage(next.usage);\n\t\t\tthis.subscribeSession();\n\t\t\tthis.emitState();\n\t\t} finally {\n\t\t\tthis.switching = false;\n\t\t}\n\t}\n\n\tasync createSession(): Promise<void> {\n\t\tawait this.openSession(\"new-session\");\n\t}\n\n\tasync requestCompaction(): Promise<void> {\n\t\tif (this.promptActive || this.compactionActive) throw new Error(\"Cannot compact while a prompt is running.\");\n\t\tthis.compactionActive = true;\n\t\tthis.emitState();\n\t\ttry {\n\t\t\tawait this.session.compact();\n\t\t} finally {\n\t\t\tthis.compactionActive = false;\n\t\t\tthis.emitState();\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.activeAbort?.abort();\n\t\tthis.unsubscribeSession?.();\n\t\tthis.unsubscribeSession = undefined;\n\t\tthis.listeners.clear();\n\t}\n\n\tasync disposeSubagents(): Promise<void> {\n\t\tawait this.session.disposeSubagents();\n\t}\n\n\tprivate async steerAsync(input: InteractiveInput): Promise<void> {\n\t\tif (!this.promptActive) {\n\t\t\tthis.reportError(new Error(\"Steering is only available while a prompt is running.\"));\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tif (typeof input === \"string\") await this.session.steer(input);\n\t\t\telse await this.session.steerWithImages(input.text, input.images ?? []);\n\t\t} catch (cause) {\n\t\t\tthis.reportError(cause);\n\t\t}\n\t}\n\n\tprivate subscribeSession(): void {\n\t\tthis.unsubscribeSession = this.session.subscribeSession((event) => {\n\t\t\tif (event.type === \"queue_update\") this.projection.setQueue(event.steering);\n\t\t\telse if (event.type === \"tree_navigated\") this.projection.replaceTranscript(this.session.transcript);\n\t\t\telse if (event.type.startsWith(\"subagent_\")) {\n\t\t\t\t// Subagent state is read through the restricted controller projection above.\n\t\t\t} else this.projection.apply(event);\n\t\t\tthis.emit({ type: \"session_event\", event });\n\t\t\tthis.emitState();\n\t\t});\n\t}\n\n\tprivate emitState(): void {\n\t\tthis.emit({ type: \"state\", state: this.state });\n\t}\n\n\tprivate emit(event: InteractiveViewEvent): void {\n\t\tfor (const listener of this.listeners) {\n\t\t\ttry {\n\t\t\t\tlistener(event);\n\t\t\t} catch (cause) {\n\t\t\t\tthis.reportError(cause);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate reportError(cause: unknown): void {\n\t\tconst message = cause instanceof Error ? cause.message : String(cause);\n\t\tthis.projection.setError(message);\n\t\tfor (const listener of this.listeners) listener({ type: \"diagnostic\", message });\n\t\tthis.emitState();\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interactive/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interactive/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC","sourcesContent":["export * from \"./builtin.ts\";\nexport * from \"./controller.ts\";\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PluginDefinition } from "@di-code/plugin-runtime";
|
|
2
|
+
/** Owns the interactive ProductHost and gives the presentation mode only its UiHost facade. */
|
|
3
|
+
export declare const apiVersion: 1;
|
|
4
|
+
export declare const name = "interactive-host";
|
|
5
|
+
export declare const version = "0.1.7";
|
|
6
|
+
export declare const apply: PluginDefinition["apply"];
|
|
7
|
+
//# sourceMappingURL=interactive-host-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-host-entry.d.ts","sourceRoot":"","sources":["../src/interactive-host-entry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AA6BhE,+FAA+F;AAC/F,eAAO,MAAM,UAAU,EAAG,CAAU,CAAC;AACrC,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,KAAK,EAAE,gBAAgB,CAAC,OAAO,CA6F3C,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { basename, extname, resolve } from "node:path";
|
|
2
|
+
import { commandRegistryKey, hostCommandRegistryKey, interactiveContextKey, keybindingRegistryKey, modeRegistryKey, } from "@di-code/builtins";
|
|
3
|
+
import { ProcessTerminal } from "@di-code/tui";
|
|
4
|
+
import { DEFAULT_LOCALE, translate } from "./i18n.js";
|
|
5
|
+
import { runInteractiveMode } from "./modes/interactive-entry.js";
|
|
6
|
+
import { runProviderOnboarding, shouldStartProviderOnboarding } from "./provider-onboarding.js";
|
|
7
|
+
import { createSessionHost } from "./runtime/session-host.js";
|
|
8
|
+
import { loadStartupConfiguration, resolveStartupRuntime } from "./startup.js";
|
|
9
|
+
function isInteractiveHostRequest(value) {
|
|
10
|
+
return (typeof value === "object" &&
|
|
11
|
+
value !== null &&
|
|
12
|
+
"command" in value &&
|
|
13
|
+
typeof value.command === "object" &&
|
|
14
|
+
value.command !== null &&
|
|
15
|
+
"mode" in value.command &&
|
|
16
|
+
value.command.mode === "interactive" &&
|
|
17
|
+
"cwd" in value &&
|
|
18
|
+
typeof value.cwd === "string" &&
|
|
19
|
+
"agentDir" in value &&
|
|
20
|
+
typeof value.agentDir === "string" &&
|
|
21
|
+
"projectTrusted" in value &&
|
|
22
|
+
typeof value.projectTrusted === "boolean" &&
|
|
23
|
+
"stderr" in value &&
|
|
24
|
+
typeof value.stderr === "function");
|
|
25
|
+
}
|
|
26
|
+
/** Owns the interactive ProductHost and gives the presentation mode only its UiHost facade. */
|
|
27
|
+
export const apiVersion = 1;
|
|
28
|
+
export const name = "interactive-host";
|
|
29
|
+
export const version = "0.1.7";
|
|
30
|
+
export const apply = (context, _config, fiber) => {
|
|
31
|
+
const registry = context.require(hostCommandRegistryKey);
|
|
32
|
+
const run = async (input, signal) => {
|
|
33
|
+
if (!isInteractiveHostRequest(input))
|
|
34
|
+
throw new TypeError("Interactive host request is invalid");
|
|
35
|
+
const request = input;
|
|
36
|
+
const configuration = await loadStartupConfiguration(request.cwd, process.env, request.agentDir);
|
|
37
|
+
const runtime = shouldStartProviderOnboarding(request.command, true, configuration)
|
|
38
|
+
? await runProviderOnboarding({ configuration, terminal: new ProcessTerminal(), agentDir: request.agentDir })
|
|
39
|
+
: resolveStartupRuntime(configuration.environment, configuration.providers, configuration.defaults);
|
|
40
|
+
if (!runtime)
|
|
41
|
+
return 0;
|
|
42
|
+
const host = await createSessionHost(context, {
|
|
43
|
+
cwd: request.cwd,
|
|
44
|
+
agentDir: request.agentDir,
|
|
45
|
+
projectTrusted: request.projectTrusted,
|
|
46
|
+
noSkills: request.command.noSkills,
|
|
47
|
+
noContextFiles: request.command.noContextFiles,
|
|
48
|
+
skillPaths: request.command.skillPaths,
|
|
49
|
+
provider: runtime.provider,
|
|
50
|
+
model: runtime.model,
|
|
51
|
+
signal,
|
|
52
|
+
...(request.command.sessionPath ? { initialSessionPath: resolve(request.cwd, request.command.sessionPath) } : {}),
|
|
53
|
+
});
|
|
54
|
+
if (!host.state().activeSession)
|
|
55
|
+
await host.createSession();
|
|
56
|
+
const ui = host.ui();
|
|
57
|
+
const sessions = await host.listSessions();
|
|
58
|
+
const activeId = host.state().activeSession?.id;
|
|
59
|
+
const sessionChoices = [
|
|
60
|
+
{
|
|
61
|
+
id: "new-session",
|
|
62
|
+
label: translate(configuration.locale ?? DEFAULT_LOCALE, "newSession"),
|
|
63
|
+
description: translate(configuration.locale ?? DEFAULT_LOCALE, "newSessionDescription"),
|
|
64
|
+
open: async () => {
|
|
65
|
+
await host.createSession();
|
|
66
|
+
return host.ui();
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
...sessions
|
|
70
|
+
.filter((item) => item.id !== activeId)
|
|
71
|
+
.map((item) => ({
|
|
72
|
+
id: item.displayId ?? item.id,
|
|
73
|
+
label: item.label || basename(item.id, extname(item.id)),
|
|
74
|
+
description: item.cwd,
|
|
75
|
+
open: async () => {
|
|
76
|
+
await host.openSession(item.id);
|
|
77
|
+
return host.ui();
|
|
78
|
+
},
|
|
79
|
+
})),
|
|
80
|
+
];
|
|
81
|
+
let mode;
|
|
82
|
+
let selectedTheme = "dark";
|
|
83
|
+
const unbind = context.require(interactiveContextKey).bind({
|
|
84
|
+
sessionChoices: () => sessionChoices,
|
|
85
|
+
cancel: () => mode?.cancelActivePrompt(),
|
|
86
|
+
retry: () => mode?.retryLastPrompt(),
|
|
87
|
+
theme: () => selectedTheme,
|
|
88
|
+
setTheme: (theme) => {
|
|
89
|
+
selectedTheme = theme;
|
|
90
|
+
},
|
|
91
|
+
keybindings: () => context.get(keybindingRegistryKey)?.snapshot(),
|
|
92
|
+
});
|
|
93
|
+
try {
|
|
94
|
+
let finish;
|
|
95
|
+
const finished = new Promise((resolveFinish) => {
|
|
96
|
+
finish = resolveFinish;
|
|
97
|
+
});
|
|
98
|
+
await context.require(modeRegistryKey).execute("interactive", {
|
|
99
|
+
run: () => (request.startInteractiveMode ?? runInteractiveMode)({
|
|
100
|
+
session: ui,
|
|
101
|
+
agentDir: request.agentDir,
|
|
102
|
+
locale: configuration.locale ?? DEFAULT_LOCALE,
|
|
103
|
+
commandRegistry: context.require(commandRegistryKey),
|
|
104
|
+
context: context.require(interactiveContextKey),
|
|
105
|
+
providerOnboarding: { configuration, agentDir: request.agentDir },
|
|
106
|
+
initialPrompt: request.command.prompt,
|
|
107
|
+
onCreated: (created) => {
|
|
108
|
+
mode = created;
|
|
109
|
+
},
|
|
110
|
+
onExit: () => finish?.(),
|
|
111
|
+
}),
|
|
112
|
+
}, signal);
|
|
113
|
+
await finished;
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
unbind();
|
|
118
|
+
await host.dispose();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
fiber.addDisposer(registry.register("interactive", run));
|
|
122
|
+
};
|
|
123
|
+
//# sourceMappingURL=interactive-host-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-host-entry.js","sourceRoot":"","sources":["../src/interactive-host-entry.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename, extname, resolve } from \"node:path\";\nimport {\n\tcommandRegistryKey,\n\thostCommandRegistryKey,\n\tinteractiveContextKey,\n\tkeybindingRegistryKey,\n\tmodeRegistryKey,\n} from \"@di-code/builtins\";\nimport type { PluginDefinition } from \"@di-code/plugin-runtime\";\nimport { ProcessTerminal } from \"@di-code/tui\";\nimport { DEFAULT_LOCALE, translate } from \"./i18n.ts\";\nimport { runInteractiveMode } from \"./modes/interactive-entry.ts\";\nimport { runProviderOnboarding, shouldStartProviderOnboarding } from \"./provider-onboarding.ts\";\nimport type { InteractiveHostRequest } from \"./runtime/interactive-host-service.ts\";\nimport { createSessionHost } from \"./runtime/session-host.ts\";\nimport { loadStartupConfiguration, resolveStartupRuntime } from \"./startup.ts\";\n\nfunction isInteractiveHostRequest(value: unknown): value is InteractiveHostRequest {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"command\" in value &&\n\t\ttypeof value.command === \"object\" &&\n\t\tvalue.command !== null &&\n\t\t\"mode\" in value.command &&\n\t\tvalue.command.mode === \"interactive\" &&\n\t\t\"cwd\" in value &&\n\t\ttypeof value.cwd === \"string\" &&\n\t\t\"agentDir\" in value &&\n\t\ttypeof value.agentDir === \"string\" &&\n\t\t\"projectTrusted\" in value &&\n\t\ttypeof value.projectTrusted === \"boolean\" &&\n\t\t\"stderr\" in value &&\n\t\ttypeof value.stderr === \"function\"\n\t);\n}\n\n/** Owns the interactive ProductHost and gives the presentation mode only its UiHost facade. */\nexport const apiVersion = 1 as const;\nexport const name = \"interactive-host\";\nexport const version = \"0.1.7\";\nexport const apply: PluginDefinition[\"apply\"] = (context, _config, fiber) => {\n\tconst registry = context.require(hostCommandRegistryKey);\n\tconst run = async (input: unknown, signal?: AbortSignal): Promise<number> => {\n\t\tif (!isInteractiveHostRequest(input)) throw new TypeError(\"Interactive host request is invalid\");\n\t\tconst request = input;\n\t\tconst configuration = await loadStartupConfiguration(request.cwd, process.env, request.agentDir);\n\t\tconst runtime = shouldStartProviderOnboarding(request.command, true, configuration)\n\t\t\t? await runProviderOnboarding({ configuration, terminal: new ProcessTerminal(), agentDir: request.agentDir })\n\t\t\t: resolveStartupRuntime(configuration.environment, configuration.providers, configuration.defaults);\n\t\tif (!runtime) return 0;\n\t\tconst host = await createSessionHost(context, {\n\t\t\tcwd: request.cwd,\n\t\t\tagentDir: request.agentDir,\n\t\t\tprojectTrusted: request.projectTrusted,\n\t\t\tnoSkills: request.command.noSkills,\n\t\t\tnoContextFiles: request.command.noContextFiles,\n\t\t\tskillPaths: request.command.skillPaths,\n\t\t\tprovider: runtime.provider,\n\t\t\tmodel: runtime.model,\n\t\t\tsignal,\n\t\t\t...(request.command.sessionPath ? { initialSessionPath: resolve(request.cwd, request.command.sessionPath) } : {}),\n\t\t});\n\t\tif (!host.state().activeSession) await host.createSession();\n\t\tconst ui = host.ui();\n\t\tconst sessions = await host.listSessions();\n\t\tconst activeId = host.state().activeSession?.id;\n\t\tconst sessionChoices = [\n\t\t\t{\n\t\t\t\tid: \"new-session\",\n\t\t\t\tlabel: translate(configuration.locale ?? DEFAULT_LOCALE, \"newSession\"),\n\t\t\t\tdescription: translate(configuration.locale ?? DEFAULT_LOCALE, \"newSessionDescription\"),\n\t\t\t\topen: async () => {\n\t\t\t\t\tawait host.createSession();\n\t\t\t\t\treturn host.ui();\n\t\t\t\t},\n\t\t\t},\n\t\t\t...sessions\n\t\t\t\t.filter((item) => item.id !== activeId)\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: item.displayId ?? item.id,\n\t\t\t\t\tlabel: item.label || basename(item.id, extname(item.id)),\n\t\t\t\t\tdescription: item.cwd,\n\t\t\t\t\topen: async () => {\n\t\t\t\t\t\tawait host.openSession(item.id);\n\t\t\t\t\t\treturn host.ui();\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t];\n\t\tlet mode: import(\"./modes/interactive.ts\").InteractiveMode | undefined;\n\t\tlet selectedTheme = \"dark\";\n\t\tconst unbind = context.require(interactiveContextKey).bind({\n\t\t\tsessionChoices: () => sessionChoices,\n\t\t\tcancel: () => mode?.cancelActivePrompt(),\n\t\t\tretry: () => mode?.retryLastPrompt(),\n\t\t\ttheme: () => selectedTheme,\n\t\t\tsetTheme: (theme) => {\n\t\t\t\tselectedTheme = theme;\n\t\t\t},\n\t\t\tkeybindings: () => context.get(keybindingRegistryKey)?.snapshot(),\n\t\t});\n\t\ttry {\n\t\t\tlet finish: (() => void) | undefined;\n\t\t\tconst finished = new Promise<void>((resolveFinish) => {\n\t\t\t\tfinish = resolveFinish;\n\t\t\t});\n\t\t\tawait context.require(modeRegistryKey).execute(\n\t\t\t\t\"interactive\",\n\t\t\t\t{\n\t\t\t\t\trun: () =>\n\t\t\t\t\t\t(request.startInteractiveMode ?? runInteractiveMode)({\n\t\t\t\t\t\t\tsession: ui,\n\t\t\t\t\t\t\tagentDir: request.agentDir,\n\t\t\t\t\t\t\tlocale: configuration.locale ?? DEFAULT_LOCALE,\n\t\t\t\t\t\t\tcommandRegistry: context.require(commandRegistryKey),\n\t\t\t\t\t\t\tcontext: context.require(interactiveContextKey),\n\t\t\t\t\t\t\tproviderOnboarding: { configuration, agentDir: request.agentDir },\n\t\t\t\t\t\t\tinitialPrompt: request.command.prompt,\n\t\t\t\t\t\t\tonCreated: (created) => {\n\t\t\t\t\t\t\t\tmode = created;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonExit: () => finish?.(),\n\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait finished;\n\t\t\treturn 0;\n\t\t} finally {\n\t\t\tunbind();\n\t\t\tawait host.dispose();\n\t\t}\n\t};\n\tfiber.addDisposer(registry.register(\"interactive\", run));\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PluginModule } from "@di-code/plugin-loader";
|
|
2
|
+
import { type RuntimeEvent } from "@di-code/plugin-runtime";
|
|
3
|
+
import { type InteractiveModeEntryOptions } from "./modes/interactive-entry.ts";
|
|
4
|
+
export interface InteractiveProfileOptions {
|
|
5
|
+
readonly stderr: (text: string) => void;
|
|
6
|
+
readonly allowedRoot?: string;
|
|
7
|
+
readonly agentDir?: string;
|
|
8
|
+
readonly isInteractiveTerminal: boolean;
|
|
9
|
+
readonly promptProjectTrust?: (cwd: string) => Promise<boolean>;
|
|
10
|
+
readonly onRuntimeEvent?: (event: RuntimeEvent) => void;
|
|
11
|
+
/** Test-only terminal boundary; production uses the composition-owned mode entry. */
|
|
12
|
+
readonly startInteractiveMode?: (options: InteractiveModeEntryOptions) => number;
|
|
13
|
+
/** Test-only module boundary; production uses the namespace composition importer. */
|
|
14
|
+
readonly importModule?: (name: string) => Promise<PluginModule>;
|
|
15
|
+
}
|
|
16
|
+
/** Starts interactive TUI through the default composition without importing legacy plugin or extension hosts. */
|
|
17
|
+
export declare function runInteractiveProfile(args: readonly string[], options: InteractiveProfileOptions): Promise<number>;
|
|
18
|
+
//# sourceMappingURL=interactive-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-profile.d.ts","sourceRoot":"","sources":["../src/interactive-profile.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2B,KAAK,YAAY,EAAqB,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAqB,KAAK,YAAY,EAAuB,MAAM,yBAAyB,CAAC;AAgBpG,OAAO,EAAE,KAAK,2BAA2B,EAAsB,MAAM,8BAA8B,CAAC;AAKpG,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxD,qFAAqF;IACrF,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,MAAM,CAAC;IACjF,qFAAqF;IACrF,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CAChE;AAgHD,iHAAiH;AACjH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,CA8KjB"}
|