@agimon-ai/doompi-loop 0.0.1-alpha.74 → 0.0.1-alpha.76
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/package.json +6 -6
- package/dist/api-contracts.cjs +0 -7
- package/dist/api-contracts.d.cts +0 -2
- package/dist/api-contracts.d.mts +0 -2
- package/dist/api-contracts.mjs +0 -2
- package/dist/extensions/pi.cjs +0 -36
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.d.cts +0 -5
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/pi.d.mts +0 -5
- package/dist/extensions/pi.d.mts.map +0 -1
- package/dist/extensions/pi.mjs +0 -31
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/extensions/server.cjs +0 -51
- package/dist/extensions/server.cjs.map +0 -1
- package/dist/extensions/server.d.cts +0 -5
- package/dist/extensions/server.d.cts.map +0 -1
- package/dist/extensions/server.d.mts +0 -5
- package/dist/extensions/server.d.mts.map +0 -1
- package/dist/extensions/server.mjs +0 -46
- package/dist/extensions/server.mjs.map +0 -1
- package/dist/extensions/web.mjs +0 -228
- package/dist/extensions/web.mjs.map +0 -1
- package/dist/index.cjs +0 -0
- package/dist/index.d.cts +0 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -1
- package/dist/loopLaunchers.cjs +0 -5
- package/dist/loopLaunchers.d.cts +0 -2
- package/dist/loopLaunchers.d.mts +0 -2
- package/dist/loopLaunchers.mjs +0 -2
- package/dist/src/constants/loop.cjs +0 -12
- package/dist/src/constants/loop.cjs.map +0 -1
- package/dist/src/constants/loop.mjs +0 -9
- package/dist/src/constants/loop.mjs.map +0 -1
- package/dist/src/constants/piLoop.cjs +0 -16
- package/dist/src/constants/piLoop.cjs.map +0 -1
- package/dist/src/constants/piLoop.mjs +0 -11
- package/dist/src/constants/piLoop.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.cli.cjs +0 -26
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.cli.mjs +0 -26
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.cli.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.cli.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.server.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loop.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.cli.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.cli.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.server.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/loops.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-start.server.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-start.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-start.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/hook/session-start.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.cjs +0 -6
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.mjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs +0 -14
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs +0 -15
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs +0 -17
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs +0 -18
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs.map +0 -1
- package/dist/src/schemas/apiContracts.cjs +0 -13
- package/dist/src/schemas/apiContracts.cjs.map +0 -1
- package/dist/src/schemas/apiContracts.d.cts +0 -53
- package/dist/src/schemas/apiContracts.d.cts.map +0 -1
- package/dist/src/schemas/apiContracts.d.mts +0 -53
- package/dist/src/schemas/apiContracts.d.mts.map +0 -1
- package/dist/src/schemas/apiContracts.mjs +0 -13
- package/dist/src/schemas/apiContracts.mjs.map +0 -1
- package/dist/src/schemas/loopLaunchers.cjs +0 -17
- package/dist/src/schemas/loopLaunchers.cjs.map +0 -1
- package/dist/src/schemas/loopLaunchers.d.cts +0 -60
- package/dist/src/schemas/loopLaunchers.d.cts.map +0 -1
- package/dist/src/schemas/loopLaunchers.d.mts +0 -60
- package/dist/src/schemas/loopLaunchers.d.mts.map +0 -1
- package/dist/src/schemas/loopLaunchers.mjs +0 -15
- package/dist/src/schemas/loopLaunchers.mjs.map +0 -1
- package/dist/src/services/defaultLoopLauncher/index.cjs +0 -92
- package/dist/src/services/defaultLoopLauncher/index.cjs.map +0 -1
- package/dist/src/services/defaultLoopLauncher/index.mjs +0 -92
- package/dist/src/services/defaultLoopLauncher/index.mjs.map +0 -1
- package/dist/src/services/loopCommand/index.cjs +0 -15
- package/dist/src/services/loopCommand/index.cjs.map +0 -1
- package/dist/src/services/loopCommand/index.mjs +0 -15
- package/dist/src/services/loopCommand/index.mjs.map +0 -1
- package/dist/src/services/loopLaunchers/index.cjs +0 -180
- package/dist/src/services/loopLaunchers/index.cjs.map +0 -1
- package/dist/src/services/loopLaunchers/index.mjs +0 -180
- package/dist/src/services/loopLaunchers/index.mjs.map +0 -1
- package/dist/src/services/serverRuntime/index.cjs +0 -293
- package/dist/src/services/serverRuntime/index.cjs.map +0 -1
- package/dist/src/services/serverRuntime/index.mjs +0 -293
- package/dist/src/services/serverRuntime/index.mjs.map +0 -1
- package/dist/src/tui/leader.cjs +0 -36
- package/dist/src/tui/leader.cjs.map +0 -1
- package/dist/src/tui/leader.mjs +0 -36
- package/dist/src/tui/leader.mjs.map +0 -1
- package/dist/src/tui/loopListOverlay.cjs +0 -101
- package/dist/src/tui/loopListOverlay.cjs.map +0 -1
- package/dist/src/tui/loopListOverlay.mjs +0 -100
- package/dist/src/tui/loopListOverlay.mjs.map +0 -1
- package/dist/src/tui/loopRuntime.cjs +0 -256
- package/dist/src/tui/loopRuntime.cjs.map +0 -1
- package/dist/src/tui/loopRuntime.mjs +0 -256
- package/dist/src/tui/loopRuntime.mjs.map +0 -1
- package/dist/src/tui/startLoopOverlay.cjs +0 -71
- package/dist/src/tui/startLoopOverlay.cjs.map +0 -1
- package/dist/src/tui/startLoopOverlay.mjs +0 -70
- package/dist/src/tui/startLoopOverlay.mjs.map +0 -1
- package/dist/src/types/loopView.cjs +0 -19
- package/dist/src/types/loopView.cjs.map +0 -1
- package/dist/src/types/loopView.mjs +0 -18
- package/dist/src/types/loopView.mjs.map +0 -1
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import { ACTIVE_MODE_COLOR, MODE_STATUS_ID, NOTIFY_INFO_LEVEL, PACKAGE_SOURCE, STATUS_KEY } from "../constants/piLoop.mjs";
|
|
2
|
-
import { DOOM_LOOP_LAUNCHERS_SERVICE } from "../schemas/loopLaunchers.mjs";
|
|
3
|
-
import { createDefaultLoopLauncher } from "../services/defaultLoopLauncher/index.mjs";
|
|
4
|
-
import { createDoomLoopLaunchersService } from "../services/loopLaunchers/index.mjs";
|
|
5
|
-
import { LOOP_VIEW_STATUS_KEY, formatLoopStatusView } from "../types/loopView.mjs";
|
|
6
|
-
import { registerLeaderContribution } from "./leader.mjs";
|
|
7
|
-
import { openLoopListOverlay } from "./loopListOverlay.mjs";
|
|
8
|
-
import { openStartLoopOverlay } from "./startLoopOverlay.mjs";
|
|
9
|
-
import { defineMinorMode } from "@agimon-ai/doompi-minor-mode";
|
|
10
|
-
import { DOOM_CORDIS_SESSION_SERVICE } from "@agimon-ai/doompi-core/cordis-host";
|
|
11
|
-
import { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from "@agimon-ai/doompi-core/ui-hub";
|
|
12
|
-
//#region src/tui/loopRuntime.ts
|
|
13
|
-
const MODE_ACTION_START = "start";
|
|
14
|
-
const MODE_ACTION_STOP = "stop";
|
|
15
|
-
const SESSION_REPLACED_REASON = "Pi session replaced.";
|
|
16
|
-
const SESSION_SHUTDOWN_REASON = "Pi session shut down.";
|
|
17
|
-
function loopModeState(launchers, instances) {
|
|
18
|
-
const active = instances.length > 0;
|
|
19
|
-
return {
|
|
20
|
-
activation: active ? "active" : "inactive",
|
|
21
|
-
condition: instances.some(({ state }) => state === "starting" || state === "stopping") ? "queued" : "ready",
|
|
22
|
-
...active ? {
|
|
23
|
-
detail: `${instances.length} active`,
|
|
24
|
-
color: ACTIVE_MODE_COLOR
|
|
25
|
-
} : {},
|
|
26
|
-
actions: [...launchers.length > 0 ? [{
|
|
27
|
-
id: MODE_ACTION_START,
|
|
28
|
-
enabled: true
|
|
29
|
-
}] : [{
|
|
30
|
-
id: MODE_ACTION_START,
|
|
31
|
-
enabled: false,
|
|
32
|
-
disabledReason: "No loop launchers are registered."
|
|
33
|
-
}], ...active ? [{
|
|
34
|
-
id: MODE_ACTION_STOP,
|
|
35
|
-
enabled: true
|
|
36
|
-
}] : [{
|
|
37
|
-
id: MODE_ACTION_STOP,
|
|
38
|
-
enabled: false,
|
|
39
|
-
disabledReason: "No loops are active."
|
|
40
|
-
}]]
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
/** Install Loop state and external resources into its host-owned Cordis plugin fiber. */
|
|
44
|
-
function createLoopPiRuntime(pi) {
|
|
45
|
-
let active = true;
|
|
46
|
-
let activeSession;
|
|
47
|
-
let mode;
|
|
48
|
-
let disposeLeader;
|
|
49
|
-
const launchesInProgress = /* @__PURE__ */ new WeakSet();
|
|
50
|
-
const currentSession = (context) => {
|
|
51
|
-
const binding = activeSession;
|
|
52
|
-
if (!active || !binding || binding.context.sessionManager !== context.sessionManager || binding.hostSession.sessionId !== context.sessionManager.getSessionId()) return;
|
|
53
|
-
return binding;
|
|
54
|
-
};
|
|
55
|
-
const clearStatuses = (binding) => {
|
|
56
|
-
binding.context.ui?.setStatus(STATUS_KEY, void 0);
|
|
57
|
-
if (binding.context.mode !== "tui") binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, void 0);
|
|
58
|
-
};
|
|
59
|
-
const publishStatus = (binding) => {
|
|
60
|
-
if (!active || activeSession !== binding) return;
|
|
61
|
-
const instances = binding.launchers.listInstances();
|
|
62
|
-
binding.context.ui?.setStatus(STATUS_KEY, instances.length ? `loops: ${instances.length}` : void 0);
|
|
63
|
-
if (binding.context.mode !== "tui") binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, formatLoopStatusView(instances));
|
|
64
|
-
mode?.publish();
|
|
65
|
-
};
|
|
66
|
-
const defaultLauncher = createDefaultLoopLauncher(pi);
|
|
67
|
-
mode = defineMinorMode({
|
|
68
|
-
descriptor: {
|
|
69
|
-
source: PACKAGE_SOURCE,
|
|
70
|
-
id: MODE_STATUS_ID,
|
|
71
|
-
label: "Loop",
|
|
72
|
-
description: "Session-scoped recurring prompt loops.",
|
|
73
|
-
order: 60,
|
|
74
|
-
actions: [{
|
|
75
|
-
id: MODE_ACTION_START,
|
|
76
|
-
label: "Start",
|
|
77
|
-
description: "Start a loop with a registered launcher.",
|
|
78
|
-
contexts: ["tui", "headless"],
|
|
79
|
-
parameters: [{
|
|
80
|
-
name: "launcherId",
|
|
81
|
-
label: "Launcher",
|
|
82
|
-
kind: "string",
|
|
83
|
-
required: true,
|
|
84
|
-
minLength: 1
|
|
85
|
-
}, {
|
|
86
|
-
name: "instanceId",
|
|
87
|
-
label: "Instance ID",
|
|
88
|
-
kind: "string",
|
|
89
|
-
required: false,
|
|
90
|
-
minLength: 1
|
|
91
|
-
}]
|
|
92
|
-
}, {
|
|
93
|
-
id: MODE_ACTION_STOP,
|
|
94
|
-
label: "Stop",
|
|
95
|
-
description: "Stop one active loop instance.",
|
|
96
|
-
contexts: ["tui", "headless"],
|
|
97
|
-
parameters: [{
|
|
98
|
-
name: "instanceId",
|
|
99
|
-
label: "Instance ID",
|
|
100
|
-
kind: "string",
|
|
101
|
-
required: true,
|
|
102
|
-
minLength: 1
|
|
103
|
-
}, {
|
|
104
|
-
name: "reason",
|
|
105
|
-
label: "Reason",
|
|
106
|
-
kind: "string",
|
|
107
|
-
required: false,
|
|
108
|
-
minLength: 1
|
|
109
|
-
}]
|
|
110
|
-
}]
|
|
111
|
-
},
|
|
112
|
-
state: () => activeSession ? loopModeState(activeSession.launchers.listLaunchers(), activeSession.launchers.listInstances()) : loopModeState([], []),
|
|
113
|
-
async handleAction(_runtime, actionId, argumentsValue, { signal }) {
|
|
114
|
-
signal.throwIfAborted();
|
|
115
|
-
const binding = activeSession ? currentSession(activeSession.context) : void 0;
|
|
116
|
-
if (!binding) throw new Error("Loop launchers are unavailable for the active session.");
|
|
117
|
-
if (actionId === MODE_ACTION_START) {
|
|
118
|
-
const instance = await binding.launchers.launch(argumentsValue.launcherId, argumentsValue.instanceId ? { instanceId: argumentsValue.instanceId } : {});
|
|
119
|
-
if (activeSession !== binding) throw new Error("Loop action became stale.");
|
|
120
|
-
return { message: instance ? `Loop '${instance.instanceId}' started.` : "Loop launch was cancelled." };
|
|
121
|
-
}
|
|
122
|
-
if (actionId === MODE_ACTION_STOP) {
|
|
123
|
-
const stopped = await binding.launchers.stop(argumentsValue.instanceId, argumentsValue.reason ?? "Stopped through minor_mode.");
|
|
124
|
-
if (activeSession !== binding) throw new Error("Loop action became stale.");
|
|
125
|
-
return { message: stopped ? "Loop stopped." : "Loop instance was not active." };
|
|
126
|
-
}
|
|
127
|
-
throw new Error(`Unknown loop mode action: ${actionId}`);
|
|
128
|
-
}
|
|
129
|
-
}).createOwner(void 0);
|
|
130
|
-
return {
|
|
131
|
-
onAgentSettled: defaultLauncher.onAgentSettled,
|
|
132
|
-
services: [(cordis) => {
|
|
133
|
-
cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {
|
|
134
|
-
const dispose = registerLeaderContribution(requireDoomUiHub(uiContext));
|
|
135
|
-
disposeLeader = dispose;
|
|
136
|
-
return () => {
|
|
137
|
-
dispose();
|
|
138
|
-
if (disposeLeader === dispose) disposeLeader = void 0;
|
|
139
|
-
};
|
|
140
|
-
});
|
|
141
|
-
cordis.inject([DOOM_CORDIS_SESSION_SERVICE], async (sessionContext) => {
|
|
142
|
-
const hostSession = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE);
|
|
143
|
-
const launchers = createDoomLoopLaunchersService({
|
|
144
|
-
generation: `${hostSession.generation}:loop-launchers`,
|
|
145
|
-
createInstanceId: () => crypto.randomUUID(),
|
|
146
|
-
timestamp: () => (/* @__PURE__ */ new Date()).toISOString()
|
|
147
|
-
});
|
|
148
|
-
const binding = {
|
|
149
|
-
context: hostSession.context,
|
|
150
|
-
hostSession,
|
|
151
|
-
launchers
|
|
152
|
-
};
|
|
153
|
-
activeSession = binding;
|
|
154
|
-
const provider = cordis.plugin((providerContext) => {
|
|
155
|
-
providerContext.provide(DOOM_LOOP_LAUNCHERS_SERVICE, launchers);
|
|
156
|
-
});
|
|
157
|
-
let defaultRegistration;
|
|
158
|
-
let unsubscribe;
|
|
159
|
-
try {
|
|
160
|
-
defaultRegistration = defaultLauncher.register(hostSession.context, launchers);
|
|
161
|
-
unsubscribe = launchers.subscribe(() => publishStatus(binding));
|
|
162
|
-
publishStatus(binding);
|
|
163
|
-
} catch (error) {
|
|
164
|
-
if (activeSession === binding) activeSession = void 0;
|
|
165
|
-
await launchers.dispose(SESSION_REPLACED_REASON);
|
|
166
|
-
await provider.dispose();
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
return async () => {
|
|
170
|
-
if (activeSession === binding) activeSession = void 0;
|
|
171
|
-
unsubscribe();
|
|
172
|
-
clearStatuses(binding);
|
|
173
|
-
mode?.publish();
|
|
174
|
-
const cleanupErrors = [];
|
|
175
|
-
try {
|
|
176
|
-
await defaultRegistration.dispose(SESSION_REPLACED_REASON);
|
|
177
|
-
} catch (error) {
|
|
178
|
-
cleanupErrors.push(error);
|
|
179
|
-
}
|
|
180
|
-
try {
|
|
181
|
-
await launchers.dispose(SESSION_SHUTDOWN_REASON);
|
|
182
|
-
} catch (error) {
|
|
183
|
-
cleanupErrors.push(error);
|
|
184
|
-
}
|
|
185
|
-
try {
|
|
186
|
-
await provider.dispose();
|
|
187
|
-
} catch (error) {
|
|
188
|
-
cleanupErrors.push(error);
|
|
189
|
-
}
|
|
190
|
-
if (cleanupErrors.length > 0) throw new AggregateError(cleanupErrors, "Loop session cleanup failed.");
|
|
191
|
-
};
|
|
192
|
-
});
|
|
193
|
-
}],
|
|
194
|
-
handlers: {
|
|
195
|
-
async start(ctx, args) {
|
|
196
|
-
const binding = currentSession(ctx);
|
|
197
|
-
if (!binding) return;
|
|
198
|
-
if (launchesInProgress.has(binding)) {
|
|
199
|
-
ctx.ui.notify("A loop setup is already in progress.", NOTIFY_INFO_LEVEL);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
launchesInProgress.add(binding);
|
|
203
|
-
try {
|
|
204
|
-
const launchers = binding.launchers.listLaunchers();
|
|
205
|
-
if (!launchers.length) {
|
|
206
|
-
ctx.ui.notify("No loop launchers are registered for this session.", NOTIFY_INFO_LEVEL);
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
const argument = args.trim();
|
|
210
|
-
let launcherId;
|
|
211
|
-
if (argument) {
|
|
212
|
-
if (argument.split(/\s+/u).length !== 1) {
|
|
213
|
-
ctx.ui.notify("Usage: /loop [launcherId]", "error");
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
if (!launchers.some((launcher) => launcher.id === argument)) {
|
|
217
|
-
ctx.ui.notify(`Unknown loop launcher: ${argument}`, "error");
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
launcherId = argument;
|
|
221
|
-
} else {
|
|
222
|
-
launcherId = await openStartLoopOverlay(ctx, launchers);
|
|
223
|
-
if (activeSession !== binding || !launcherId) return;
|
|
224
|
-
}
|
|
225
|
-
const instance = await binding.launchers.launch(launcherId);
|
|
226
|
-
if (activeSession !== binding) return;
|
|
227
|
-
if (instance) ctx.ui.notify(`${instance.label ?? instance.launcherLabel} started.`, NOTIFY_INFO_LEVEL);
|
|
228
|
-
} catch (error) {
|
|
229
|
-
if (activeSession !== binding) return;
|
|
230
|
-
ctx.ui.notify(`Loop could not start: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
231
|
-
} finally {
|
|
232
|
-
launchesInProgress.delete(binding);
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
async list(ctx) {
|
|
236
|
-
const binding = currentSession(ctx);
|
|
237
|
-
if (!binding) return;
|
|
238
|
-
await openLoopListOverlay(ctx, binding.launchers);
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
minorModes: [mode],
|
|
242
|
-
onDispose() {
|
|
243
|
-
active = false;
|
|
244
|
-
const binding = activeSession;
|
|
245
|
-
activeSession = void 0;
|
|
246
|
-
if (binding) clearStatuses(binding);
|
|
247
|
-
mode?.publish();
|
|
248
|
-
disposeLeader?.();
|
|
249
|
-
disposeLeader = void 0;
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
//#endregion
|
|
254
|
-
export { createLoopPiRuntime };
|
|
255
|
-
|
|
256
|
-
//# sourceMappingURL=loopRuntime.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loopRuntime.mjs","names":[],"sources":["../../../src/tui/loopRuntime.ts"],"sourcesContent":["import { DOOM_CORDIS_SESSION_SERVICE, type DoomCordisSessionService } from '@agimon-ai/doompi-core/cordis-host';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeState } from '@agimon-ai/doompi-minor-mode';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n ACTIVE_MODE_COLOR,\n LOOPS_GROUP_ORDER,\n MODE_STATUS_ID,\n NOTIFY_INFO_LEVEL,\n PACKAGE_SOURCE,\n STATUS_KEY,\n} from '../constants/piLoop';\nimport {\n DOOM_LOOP_LAUNCHERS_SERVICE,\n type DoomLoopLaunchersService,\n type LoopInstanceSnapshot,\n type LoopLauncherRegistration,\n type LoopLauncherSummary,\n} from '../schemas/loopLaunchers';\nimport { createDefaultLoopLauncher } from '../services/defaultLoopLauncher';\nimport { createDoomLoopLaunchersService } from '../services/loopLaunchers';\nimport { formatLoopStatusView, LOOP_VIEW_STATUS_KEY } from '../types/loopView';\nimport { registerLeaderContribution } from './leader';\nimport { openLoopListOverlay } from './loopListOverlay';\nimport { openStartLoopOverlay } from './startLoopOverlay';\n\nconst MODE_ACTION_START = 'start';\nconst MODE_ACTION_STOP = 'stop';\nconst SESSION_REPLACED_REASON = 'Pi session replaced.';\nconst SESSION_SHUTDOWN_REASON = 'Pi session shut down.';\n\ninterface ActiveLoopSession {\n readonly context: ExtensionContext;\n readonly hostSession: DoomCordisSessionService;\n readonly launchers: DoomLoopLaunchersService;\n}\n\nfunction loopModeState(\n launchers: readonly LoopLauncherSummary[],\n instances: readonly LoopInstanceSnapshot[],\n): MinorModeState {\n const active = instances.length > 0;\n return {\n activation: active ? 'active' : 'inactive',\n condition: instances.some(({ state }) => state === 'starting' || state === 'stopping') ? 'queued' : 'ready',\n ...(active ? { detail: `${instances.length} active`, color: ACTIVE_MODE_COLOR } : {}),\n actions: [\n ...(launchers.length > 0\n ? [{ id: MODE_ACTION_START, enabled: true } as const]\n : [{ id: MODE_ACTION_START, enabled: false, disabledReason: 'No loop launchers are registered.' } as const]),\n ...(active\n ? [{ id: MODE_ACTION_STOP, enabled: true } as const]\n : [{ id: MODE_ACTION_STOP, enabled: false, disabledReason: 'No loops are active.' } as const]),\n ],\n };\n}\n\nimport type { LoopCommandHandlers } from '../types/loopCommand';\ninterface LoopPiRuntime {\n onAgentSettled(this: void): void;\n services: Array<(context: Context) => void>;\n handlers: LoopCommandHandlers;\n minorModes: MinorModeOwner[];\n onDispose(): void;\n}\n/** Install Loop state and external resources into its host-owned Cordis plugin fiber. */\nexport function createLoopPiRuntime(pi: ExtensionAPI): LoopPiRuntime {\n let active = true;\n let activeSession: ActiveLoopSession | undefined;\n let mode: MinorModeOwner | undefined;\n let disposeLeader: (() => void) | undefined;\n const launchesInProgress = new WeakSet<ActiveLoopSession>();\n\n const currentSession = (context: ExtensionContext): ActiveLoopSession | undefined => {\n const binding = activeSession;\n if (\n !active ||\n !binding ||\n binding.context.sessionManager !== context.sessionManager ||\n binding.hostSession.sessionId !== context.sessionManager.getSessionId()\n ) {\n return undefined;\n }\n return binding;\n };\n\n const clearStatuses = (binding: ActiveLoopSession): void => {\n binding.context.ui?.setStatus(STATUS_KEY, undefined);\n if (binding.context.mode !== 'tui') binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, undefined);\n };\n const publishStatus = (binding: ActiveLoopSession): void => {\n if (!active || activeSession !== binding) return;\n const instances = binding.launchers.listInstances();\n binding.context.ui?.setStatus(STATUS_KEY, instances.length ? `loops: ${instances.length}` : undefined);\n if (binding.context.mode !== 'tui') {\n binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, formatLoopStatusView(instances));\n }\n mode?.publish();\n };\n\n const defaultLauncher = createDefaultLoopLauncher(pi);\n\n mode = defineMinorMode({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: MODE_STATUS_ID,\n label: 'Loop',\n description: 'Session-scoped recurring prompt loops.',\n order: LOOPS_GROUP_ORDER,\n actions: [\n {\n id: MODE_ACTION_START,\n label: 'Start',\n description: 'Start a loop with a registered launcher.',\n contexts: ['tui', 'headless'],\n parameters: [\n { name: 'launcherId', label: 'Launcher', kind: 'string', required: true, minLength: 1 },\n { name: 'instanceId', label: 'Instance ID', kind: 'string', required: false, minLength: 1 },\n ],\n },\n {\n id: MODE_ACTION_STOP,\n label: 'Stop',\n description: 'Stop one active loop instance.',\n contexts: ['tui', 'headless'],\n parameters: [\n { name: 'instanceId', label: 'Instance ID', kind: 'string', required: true, minLength: 1 },\n { name: 'reason', label: 'Reason', kind: 'string', required: false, minLength: 1 },\n ],\n },\n ],\n },\n state: () =>\n activeSession\n ? loopModeState(activeSession.launchers.listLaunchers(), activeSession.launchers.listInstances())\n : loopModeState([], []),\n async handleAction(_runtime, actionId, argumentsValue, { signal }) {\n signal.throwIfAborted();\n const binding = activeSession ? currentSession(activeSession.context) : undefined;\n if (!binding) throw new Error('Loop launchers are unavailable for the active session.');\n if (actionId === MODE_ACTION_START) {\n const instance = await binding.launchers.launch(\n argumentsValue.launcherId as string,\n argumentsValue.instanceId ? { instanceId: argumentsValue.instanceId as string } : {},\n );\n if (activeSession !== binding) throw new Error('Loop action became stale.');\n return { message: instance ? `Loop '${instance.instanceId}' started.` : 'Loop launch was cancelled.' };\n }\n if (actionId === MODE_ACTION_STOP) {\n const stopped = await binding.launchers.stop(\n argumentsValue.instanceId as string,\n (argumentsValue.reason as string | undefined) ?? 'Stopped through minor_mode.',\n );\n if (activeSession !== binding) throw new Error('Loop action became stale.');\n return { message: stopped ? 'Loop stopped.' : 'Loop instance was not active.' };\n }\n throw new Error(`Unknown loop mode action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n onAgentSettled: defaultLauncher.onAgentSettled,\n services: [\n (cordis: Context) => {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const dispose = registerLeaderContribution(requireDoomUiHub(uiContext));\n disposeLeader = dispose;\n return () => {\n dispose();\n if (disposeLeader === dispose) disposeLeader = undefined;\n };\n });\n\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], async (sessionContext) => {\n const hostSession = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const launchers = createDoomLoopLaunchersService({\n generation: `${hostSession.generation}:loop-launchers`,\n createInstanceId: () => crypto.randomUUID(),\n timestamp: () => new Date().toISOString(),\n });\n const binding: ActiveLoopSession = { context: hostSession.context, hostSession, launchers };\n activeSession = binding;\n const provider = cordis.plugin((providerContext) => {\n providerContext.provide(DOOM_LOOP_LAUNCHERS_SERVICE, launchers);\n });\n\n let defaultRegistration: LoopLauncherRegistration;\n let unsubscribe: () => void;\n try {\n defaultRegistration = defaultLauncher.register(hostSession.context, launchers);\n unsubscribe = launchers.subscribe(() => publishStatus(binding));\n publishStatus(binding);\n } catch (error) {\n if (activeSession === binding) activeSession = undefined;\n await launchers.dispose(SESSION_REPLACED_REASON);\n await provider.dispose();\n throw error;\n }\n\n return async () => {\n if (activeSession === binding) activeSession = undefined;\n unsubscribe();\n clearStatuses(binding);\n mode?.publish();\n const cleanupErrors: unknown[] = [];\n try {\n await defaultRegistration.dispose(SESSION_REPLACED_REASON);\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n await launchers.dispose(SESSION_SHUTDOWN_REASON);\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n await provider.dispose();\n } catch (error) {\n cleanupErrors.push(error);\n }\n if (cleanupErrors.length > 0) throw new AggregateError(cleanupErrors, 'Loop session cleanup failed.');\n };\n });\n },\n ],\n handlers: {\n async start(ctx, args) {\n const binding = currentSession(ctx);\n if (!binding) return;\n if (launchesInProgress.has(binding)) {\n ctx.ui.notify('A loop setup is already in progress.', NOTIFY_INFO_LEVEL);\n return;\n }\n launchesInProgress.add(binding);\n try {\n const launchers = binding.launchers.listLaunchers();\n if (!launchers.length) {\n ctx.ui.notify('No loop launchers are registered for this session.', NOTIFY_INFO_LEVEL);\n return;\n }\n\n const argument = args.trim();\n let launcherId: string | undefined;\n if (argument) {\n if (argument.split(/\\s+/u).length !== 1) {\n ctx.ui.notify('Usage: /loop [launcherId]', 'error');\n return;\n }\n if (!launchers.some((launcher) => launcher.id === argument)) {\n ctx.ui.notify(`Unknown loop launcher: ${argument}`, 'error');\n return;\n }\n launcherId = argument;\n } else {\n launcherId = await openStartLoopOverlay(ctx, launchers);\n if (activeSession !== binding || !launcherId) return;\n }\n\n const instance = await binding.launchers.launch(launcherId);\n if (activeSession !== binding) return;\n if (instance) ctx.ui.notify(`${instance.label ?? instance.launcherLabel} started.`, NOTIFY_INFO_LEVEL);\n } catch (error) {\n if (activeSession !== binding) return;\n ctx.ui.notify(`Loop could not start: ${error instanceof Error ? error.message : String(error)}`, 'error');\n } finally {\n launchesInProgress.delete(binding);\n }\n },\n async list(ctx) {\n const binding = currentSession(ctx);\n if (!binding) return;\n await openLoopListOverlay(ctx, binding.launchers);\n },\n },\n minorModes: [mode],\n onDispose() {\n active = false;\n const binding = activeSession;\n activeSession = undefined;\n if (binding) clearStatuses(binding);\n mode?.publish();\n disposeLeader?.();\n disposeLeader = undefined;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
let _agimon_ai_doompi_ui_doom_overlay = require("@agimon-ai/doompi-ui/doom-overlay");
|
|
2
|
-
let _earendil_works_pi_tui = require("@earendil-works/pi-tui");
|
|
3
|
-
//#region src/tui/startLoopOverlay.ts
|
|
4
|
-
const EMPTY_MESSAGE = "No loop launchers are registered for this session.";
|
|
5
|
-
var StartLoopOverlay = class extends _agimon_ai_doompi_ui_doom_overlay.DoomOverlay {
|
|
6
|
-
launchers;
|
|
7
|
-
done;
|
|
8
|
-
selected = 0;
|
|
9
|
-
constructor(tui, theme, launchers, done) {
|
|
10
|
-
super(tui, theme);
|
|
11
|
-
this.launchers = launchers;
|
|
12
|
-
this.done = done;
|
|
13
|
-
}
|
|
14
|
-
handleInput(data) {
|
|
15
|
-
if ((0, _earendil_works_pi_tui.matchesKey)(data, "escape") || (0, _earendil_works_pi_tui.matchesKey)(data, "ctrl+c") || data === "q") {
|
|
16
|
-
this.done(void 0);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if ((0, _earendil_works_pi_tui.matchesKey)(data, "up") || data === "k") {
|
|
20
|
-
this.move(-1);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if ((0, _earendil_works_pi_tui.matchesKey)(data, "down") || data === "j") {
|
|
24
|
-
this.move(1);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if ((0, _earendil_works_pi_tui.matchesKey)(data, "enter")) this.done(this.launchers[this.selected]?.id);
|
|
28
|
-
}
|
|
29
|
-
getChrome() {
|
|
30
|
-
return {
|
|
31
|
-
title: "START LOOP",
|
|
32
|
-
breadcrumb: "SPC › l / loops › s / start",
|
|
33
|
-
footer: `${_agimon_ai_doompi_ui_doom_overlay.DOOM_NAVIGATION_KEYS.list} move · enter launch · esc close`,
|
|
34
|
-
footerHints: [
|
|
35
|
-
[_agimon_ai_doompi_ui_doom_overlay.DOOM_NAVIGATION_KEYS.list, "move"],
|
|
36
|
-
["enter", "launch"],
|
|
37
|
-
["esc", "close"]
|
|
38
|
-
],
|
|
39
|
-
accent: _agimon_ai_doompi_ui_doom_overlay.DOOM_OVERLAY_ACCENT
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
renderBody(width) {
|
|
43
|
-
if (!this.launchers.length) return [this.theme.fg("dim", EMPTY_MESSAGE)];
|
|
44
|
-
return this.launchers.flatMap((launcher, index) => {
|
|
45
|
-
const selected = index === this.selected;
|
|
46
|
-
const marker = selected ? this.theme.fg("accent", "▸") : " ";
|
|
47
|
-
const label = selected ? this.theme.bold(launcher.label) : launcher.label;
|
|
48
|
-
const lines = [`${marker} ${(0, _earendil_works_pi_tui.truncateToWidth)(label, Math.max(0, width - 2))}`];
|
|
49
|
-
if (launcher.description) lines.push(` ${this.theme.fg("dim", (0, _earendil_works_pi_tui.truncateToWidth)(launcher.description, Math.max(0, width - 4)))}`);
|
|
50
|
-
return lines;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
move(delta) {
|
|
54
|
-
if (!this.launchers.length) return;
|
|
55
|
-
this.selected = Math.max(0, Math.min(this.selected + delta, this.launchers.length - 1));
|
|
56
|
-
this.invalidate();
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
async function openStartLoopOverlay(ctx, launchers) {
|
|
60
|
-
if (ctx.mode !== "tui") {
|
|
61
|
-
const labels = launchers.map((launcher) => launcher.label);
|
|
62
|
-
const selected = await ctx.ui.select("Start loop", labels);
|
|
63
|
-
return launchers[labels.indexOf(selected ?? "")]?.id;
|
|
64
|
-
}
|
|
65
|
-
return ctx.ui.custom((tui, theme, _keybindings, done) => new StartLoopOverlay(tui, theme, launchers, done), _agimon_ai_doompi_ui_doom_overlay.DOOM_FULLSCREEN_UI_OPTIONS);
|
|
66
|
-
}
|
|
67
|
-
//#endregion
|
|
68
|
-
exports.StartLoopOverlay = StartLoopOverlay;
|
|
69
|
-
exports.openStartLoopOverlay = openStartLoopOverlay;
|
|
70
|
-
|
|
71
|
-
//# sourceMappingURL=startLoopOverlay.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"startLoopOverlay.cjs","names":["DoomOverlay","matchesKey","DOOM_NAVIGATION_KEYS","DOOM_OVERLAY_ACCENT","truncateToWidth","DOOM_FULLSCREEN_UI_OPTIONS"],"sources":["../../../src/tui/startLoopOverlay.ts"],"sourcesContent":["import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/doom-overlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { LoopLauncherSummary } from '../schemas/loopLaunchers';\n\nconst EMPTY_MESSAGE = 'No loop launchers are registered for this session.';\n\nexport class StartLoopOverlay extends DoomOverlay {\n private selected = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly launchers: readonly LoopLauncherSummary[],\n private readonly done: (result: string | undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c') || data === 'q') {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.move(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.move(1);\n return;\n }\n if (matchesKey(data, 'enter')) this.done(this.launchers[this.selected]?.id);\n }\n\n protected getChrome(): DoomOverlayChrome {\n return {\n title: 'START LOOP',\n breadcrumb: 'SPC › l / loops › s / start',\n footer: `${DOOM_NAVIGATION_KEYS.list} move · enter launch · esc close`,\n footerHints: [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n ['enter', 'launch'],\n ['esc', 'close'],\n ],\n accent: DOOM_OVERLAY_ACCENT,\n };\n }\n\n protected renderBody(width: number): string[] {\n if (!this.launchers.length) return [this.theme.fg('dim', EMPTY_MESSAGE)];\n return this.launchers.flatMap((launcher, index) => {\n const selected = index === this.selected;\n const marker = selected ? this.theme.fg('accent', '▸') : ' ';\n const label = selected ? this.theme.bold(launcher.label) : launcher.label;\n const lines = [`${marker} ${truncateToWidth(label, Math.max(0, width - 2))}`];\n if (launcher.description)\n lines.push(` ${this.theme.fg('dim', truncateToWidth(launcher.description, Math.max(0, width - 4)))}`);\n return lines;\n });\n }\n\n private move(delta: number): void {\n if (!this.launchers.length) return;\n this.selected = Math.max(0, Math.min(this.selected + delta, this.launchers.length - 1));\n this.invalidate();\n }\n}\n\nexport async function openStartLoopOverlay(\n ctx: ExtensionContext,\n launchers: readonly LoopLauncherSummary[],\n): Promise<string | undefined> {\n if (ctx.mode !== 'tui') {\n const labels = launchers.map((launcher) => launcher.label);\n const selected = await ctx.ui.select('Start loop', labels);\n return launchers[labels.indexOf(selected ?? '')]?.id;\n }\n return ctx.ui.custom<string | undefined>(\n (tui, theme, _keybindings, done) => new StartLoopOverlay(tui, theme, launchers, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":";;;AAaA,MAAM,gBAAgB;AAEtB,IAAa,mBAAb,cAAsCA,kCAAAA,YAAY;CAM7B;CACA;CANnB,WAAmB;CAEnB,YACE,KACA,OACA,WACA,MACA;EACA,MAAM,KAAK,KAAK;EAHC,KAAA,YAAA;EACA,KAAA,OAAA;CAGnB;CAEA,YAAY,MAAoB;EAC9B,KAAA,GAAIC,uBAAAA,WAAAA,CAAW,MAAM,QAAQ,MAAA,GAAKA,uBAAAA,WAAAA,CAAW,MAAM,QAAQ,KAAK,SAAS,KAAK;GAC5E,KAAK,KAAK,KAAA,CAAS;GACnB;EACF;EACA,KAAA,GAAIA,uBAAAA,WAAAA,CAAW,MAAM,IAAI,KAAK,SAAS,KAAK;GAC1C,KAAK,KAAK,EAAE;GACZ;EACF;EACA,KAAA,GAAIA,uBAAAA,WAAAA,CAAW,MAAM,MAAM,KAAK,SAAS,KAAK;GAC5C,KAAK,KAAK,CAAC;GACX;EACF;EACA,KAAA,GAAIA,uBAAAA,WAAAA,CAAW,MAAM,OAAO,GAAG,KAAK,KAAK,KAAK,UAAU,KAAK,SAAS,EAAE,EAAE;CAC5E;CAEA,YAAyC;EACvC,OAAO;GACL,OAAO;GACP,YAAY;GACZ,QAAQ,GAAGC,kCAAAA,qBAAqB,KAAK;GACrC,aAAa;IACX,CAACA,kCAAAA,qBAAqB,MAAM,MAAM;IAClC,CAAC,SAAS,QAAQ;IAClB,CAAC,OAAO,OAAO;GACjB;GACA,QAAQC,kCAAAA;EACV;CACF;CAEA,WAAqB,OAAyB;EAC5C,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO,CAAC,KAAK,MAAM,GAAG,OAAO,aAAa,CAAC;EACvE,OAAO,KAAK,UAAU,SAAS,UAAU,UAAU;GACjD,MAAM,WAAW,UAAU,KAAK;GAChC,MAAM,SAAS,WAAW,KAAK,MAAM,GAAG,UAAU,GAAG,IAAI;GACzD,MAAM,QAAQ,WAAW,KAAK,MAAM,KAAK,SAAS,KAAK,IAAI,SAAS;GACpE,MAAM,QAAQ,CAAC,GAAG,OAAO,IAAA,GAAGC,uBAAAA,gBAAAA,CAAgB,OAAO,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG;GAC5E,IAAI,SAAS,aACX,MAAM,KAAK,OAAO,KAAK,MAAM,GAAG,QAAA,GAAOA,uBAAAA,gBAAAA,CAAgB,SAAS,aAAa,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG;GACzG,OAAO;EACT,CAAC;CACH;CAEA,KAAa,OAAqB;EAChC,IAAI,CAAC,KAAK,UAAU,QAAQ;EAC5B,KAAK,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,WAAW,OAAO,KAAK,UAAU,SAAS,CAAC,CAAC;EACtF,KAAK,WAAW;CAClB;AACF;AAEA,eAAsB,qBACpB,KACA,WAC6B;CAC7B,IAAI,IAAI,SAAS,OAAO;EACtB,MAAM,SAAS,UAAU,KAAK,aAAa,SAAS,KAAK;EACzD,MAAM,WAAW,MAAM,IAAI,GAAG,OAAO,cAAc,MAAM;EACzD,OAAO,UAAU,OAAO,QAAQ,YAAY,EAAE,EAAE,EAAE;CACpD;CACA,OAAO,IAAI,GAAG,QACX,KAAK,OAAO,cAAc,SAAS,IAAI,iBAAiB,KAAK,OAAO,WAAW,IAAI,GACpFC,kCAAAA,0BACF;AACF"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { DOOM_FULLSCREEN_UI_OPTIONS, DOOM_NAVIGATION_KEYS, DOOM_OVERLAY_ACCENT, DoomOverlay } from "@agimon-ai/doompi-ui/doom-overlay";
|
|
2
|
-
import { matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
//#region src/tui/startLoopOverlay.ts
|
|
4
|
-
const EMPTY_MESSAGE = "No loop launchers are registered for this session.";
|
|
5
|
-
var StartLoopOverlay = class extends DoomOverlay {
|
|
6
|
-
launchers;
|
|
7
|
-
done;
|
|
8
|
-
selected = 0;
|
|
9
|
-
constructor(tui, theme, launchers, done) {
|
|
10
|
-
super(tui, theme);
|
|
11
|
-
this.launchers = launchers;
|
|
12
|
-
this.done = done;
|
|
13
|
-
}
|
|
14
|
-
handleInput(data) {
|
|
15
|
-
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c") || data === "q") {
|
|
16
|
-
this.done(void 0);
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (matchesKey(data, "up") || data === "k") {
|
|
20
|
-
this.move(-1);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (matchesKey(data, "down") || data === "j") {
|
|
24
|
-
this.move(1);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (matchesKey(data, "enter")) this.done(this.launchers[this.selected]?.id);
|
|
28
|
-
}
|
|
29
|
-
getChrome() {
|
|
30
|
-
return {
|
|
31
|
-
title: "START LOOP",
|
|
32
|
-
breadcrumb: "SPC › l / loops › s / start",
|
|
33
|
-
footer: `${DOOM_NAVIGATION_KEYS.list} move · enter launch · esc close`,
|
|
34
|
-
footerHints: [
|
|
35
|
-
[DOOM_NAVIGATION_KEYS.list, "move"],
|
|
36
|
-
["enter", "launch"],
|
|
37
|
-
["esc", "close"]
|
|
38
|
-
],
|
|
39
|
-
accent: DOOM_OVERLAY_ACCENT
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
renderBody(width) {
|
|
43
|
-
if (!this.launchers.length) return [this.theme.fg("dim", EMPTY_MESSAGE)];
|
|
44
|
-
return this.launchers.flatMap((launcher, index) => {
|
|
45
|
-
const selected = index === this.selected;
|
|
46
|
-
const marker = selected ? this.theme.fg("accent", "▸") : " ";
|
|
47
|
-
const label = selected ? this.theme.bold(launcher.label) : launcher.label;
|
|
48
|
-
const lines = [`${marker} ${truncateToWidth(label, Math.max(0, width - 2))}`];
|
|
49
|
-
if (launcher.description) lines.push(` ${this.theme.fg("dim", truncateToWidth(launcher.description, Math.max(0, width - 4)))}`);
|
|
50
|
-
return lines;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
move(delta) {
|
|
54
|
-
if (!this.launchers.length) return;
|
|
55
|
-
this.selected = Math.max(0, Math.min(this.selected + delta, this.launchers.length - 1));
|
|
56
|
-
this.invalidate();
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
async function openStartLoopOverlay(ctx, launchers) {
|
|
60
|
-
if (ctx.mode !== "tui") {
|
|
61
|
-
const labels = launchers.map((launcher) => launcher.label);
|
|
62
|
-
const selected = await ctx.ui.select("Start loop", labels);
|
|
63
|
-
return launchers[labels.indexOf(selected ?? "")]?.id;
|
|
64
|
-
}
|
|
65
|
-
return ctx.ui.custom((tui, theme, _keybindings, done) => new StartLoopOverlay(tui, theme, launchers, done), DOOM_FULLSCREEN_UI_OPTIONS);
|
|
66
|
-
}
|
|
67
|
-
//#endregion
|
|
68
|
-
export { StartLoopOverlay, openStartLoopOverlay };
|
|
69
|
-
|
|
70
|
-
//# sourceMappingURL=startLoopOverlay.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"startLoopOverlay.mjs","names":[],"sources":["../../../src/tui/startLoopOverlay.ts"],"sourcesContent":["import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/doom-overlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { LoopLauncherSummary } from '../schemas/loopLaunchers';\n\nconst EMPTY_MESSAGE = 'No loop launchers are registered for this session.';\n\nexport class StartLoopOverlay extends DoomOverlay {\n private selected = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly launchers: readonly LoopLauncherSummary[],\n private readonly done: (result: string | undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c') || data === 'q') {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.move(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.move(1);\n return;\n }\n if (matchesKey(data, 'enter')) this.done(this.launchers[this.selected]?.id);\n }\n\n protected getChrome(): DoomOverlayChrome {\n return {\n title: 'START LOOP',\n breadcrumb: 'SPC › l / loops › s / start',\n footer: `${DOOM_NAVIGATION_KEYS.list} move · enter launch · esc close`,\n footerHints: [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n ['enter', 'launch'],\n ['esc', 'close'],\n ],\n accent: DOOM_OVERLAY_ACCENT,\n };\n }\n\n protected renderBody(width: number): string[] {\n if (!this.launchers.length) return [this.theme.fg('dim', EMPTY_MESSAGE)];\n return this.launchers.flatMap((launcher, index) => {\n const selected = index === this.selected;\n const marker = selected ? this.theme.fg('accent', '▸') : ' ';\n const label = selected ? this.theme.bold(launcher.label) : launcher.label;\n const lines = [`${marker} ${truncateToWidth(label, Math.max(0, width - 2))}`];\n if (launcher.description)\n lines.push(` ${this.theme.fg('dim', truncateToWidth(launcher.description, Math.max(0, width - 4)))}`);\n return lines;\n });\n }\n\n private move(delta: number): void {\n if (!this.launchers.length) return;\n this.selected = Math.max(0, Math.min(this.selected + delta, this.launchers.length - 1));\n this.invalidate();\n }\n}\n\nexport async function openStartLoopOverlay(\n ctx: ExtensionContext,\n launchers: readonly LoopLauncherSummary[],\n): Promise<string | undefined> {\n if (ctx.mode !== 'tui') {\n const labels = launchers.map((launcher) => launcher.label);\n const selected = await ctx.ui.select('Start loop', labels);\n return launchers[labels.indexOf(selected ?? '')]?.id;\n }\n return ctx.ui.custom<string | undefined>(\n (tui, theme, _keybindings, done) => new StartLoopOverlay(tui, theme, launchers, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":";;;AAaA,MAAM,gBAAgB;AAEtB,IAAa,mBAAb,cAAsC,YAAY;CAM7B;CACA;CANnB,WAAmB;CAEnB,YACE,KACA,OACA,WACA,MACA;EACA,MAAM,KAAK,KAAK;EAHC,KAAA,YAAA;EACA,KAAA,OAAA;CAGnB;CAEA,YAAY,MAAoB;EAC9B,IAAI,WAAW,MAAM,QAAQ,KAAK,WAAW,MAAM,QAAQ,KAAK,SAAS,KAAK;GAC5E,KAAK,KAAK,KAAA,CAAS;GACnB;EACF;EACA,IAAI,WAAW,MAAM,IAAI,KAAK,SAAS,KAAK;GAC1C,KAAK,KAAK,EAAE;GACZ;EACF;EACA,IAAI,WAAW,MAAM,MAAM,KAAK,SAAS,KAAK;GAC5C,KAAK,KAAK,CAAC;GACX;EACF;EACA,IAAI,WAAW,MAAM,OAAO,GAAG,KAAK,KAAK,KAAK,UAAU,KAAK,SAAS,EAAE,EAAE;CAC5E;CAEA,YAAyC;EACvC,OAAO;GACL,OAAO;GACP,YAAY;GACZ,QAAQ,GAAG,qBAAqB,KAAK;GACrC,aAAa;IACX,CAAC,qBAAqB,MAAM,MAAM;IAClC,CAAC,SAAS,QAAQ;IAClB,CAAC,OAAO,OAAO;GACjB;GACA,QAAQ;EACV;CACF;CAEA,WAAqB,OAAyB;EAC5C,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO,CAAC,KAAK,MAAM,GAAG,OAAO,aAAa,CAAC;EACvE,OAAO,KAAK,UAAU,SAAS,UAAU,UAAU;GACjD,MAAM,WAAW,UAAU,KAAK;GAChC,MAAM,SAAS,WAAW,KAAK,MAAM,GAAG,UAAU,GAAG,IAAI;GACzD,MAAM,QAAQ,WAAW,KAAK,MAAM,KAAK,SAAS,KAAK,IAAI,SAAS;GACpE,MAAM,QAAQ,CAAC,GAAG,OAAO,GAAG,gBAAgB,OAAO,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG;GAC5E,IAAI,SAAS,aACX,MAAM,KAAK,OAAO,KAAK,MAAM,GAAG,OAAO,gBAAgB,SAAS,aAAa,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG;GACzG,OAAO;EACT,CAAC;CACH;CAEA,KAAa,OAAqB;EAChC,IAAI,CAAC,KAAK,UAAU,QAAQ;EAC5B,KAAK,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,WAAW,OAAO,KAAK,UAAU,SAAS,CAAC,CAAC;EACtF,KAAK,WAAW;CAClB;AACF;AAEA,eAAsB,qBACpB,KACA,WAC6B;CAC7B,IAAI,IAAI,SAAS,OAAO;EACtB,MAAM,SAAS,UAAU,KAAK,aAAa,SAAS,KAAK;EACzD,MAAM,WAAW,MAAM,IAAI,GAAG,OAAO,cAAc,MAAM;EACzD,OAAO,UAAU,OAAO,QAAQ,YAAY,EAAE,EAAE,EAAE;CACpD;CACA,OAAO,IAAI,GAAG,QACX,KAAK,OAAO,cAAc,SAAS,IAAI,iBAAiB,KAAK,OAAO,WAAW,IAAI,GACpF,0BACF;AACF"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
//#region src/types/loopView.ts
|
|
2
|
-
/** The browser-only status that carries active Loop instances into the activity dock. */
|
|
3
|
-
const LOOP_VIEW_STATUS_KEY = "doom-loop-instances";
|
|
4
|
-
new RegExp(String.raw`\u001b\[[0-9;]*m`, "gu");
|
|
5
|
-
/** Projects runtime snapshots into the JSON status consumed by the web plugin. */
|
|
6
|
-
function formatLoopStatusView(instances) {
|
|
7
|
-
if (instances.length === 0) return void 0;
|
|
8
|
-
return JSON.stringify(instances.map((instance) => ({
|
|
9
|
-
instanceId: instance.instanceId,
|
|
10
|
-
label: instance.label ?? instance.launcherLabel,
|
|
11
|
-
detail: instance.detail ?? instance.instanceId,
|
|
12
|
-
state: instance.state
|
|
13
|
-
})));
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
exports.LOOP_VIEW_STATUS_KEY = LOOP_VIEW_STATUS_KEY;
|
|
17
|
-
exports.formatLoopStatusView = formatLoopStatusView;
|
|
18
|
-
|
|
19
|
-
//# sourceMappingURL=loopView.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loopView.cjs","names":[],"sources":["../../../src/types/loopView.ts"],"sourcesContent":["/** The browser-only status that carries active Loop instances into the activity dock. */\nexport const LOOP_VIEW_STATUS_KEY = 'doom-loop-instances';\n\nexport type LoopStatusState = 'starting' | 'running' | 'stopping';\n\n/** The small, serializable Loop view the cockpit needs for one activity row. */\nexport interface LoopStatusItem {\n readonly instanceId: string;\n readonly label: string;\n readonly detail: string;\n readonly state: LoopStatusState;\n}\n\ninterface LoopStatusSource {\n readonly instanceId: string;\n readonly launcherLabel: string;\n readonly label?: string;\n readonly detail?: string;\n readonly state: LoopStatusState;\n}\n\nconst ANSI = new RegExp(String.raw`\\u001b\\[[0-9;]*m`, 'gu');\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isState(value: unknown): value is LoopStatusState {\n return value === 'starting' || value === 'running' || value === 'stopping';\n}\n\n/** Projects runtime snapshots into the JSON status consumed by the web plugin. */\nexport function formatLoopStatusView(instances: readonly LoopStatusSource[]): string | undefined {\n if (instances.length === 0) return undefined;\n return JSON.stringify(\n instances.map((instance) => ({\n instanceId: instance.instanceId,\n label: instance.label ?? instance.launcherLabel,\n detail: instance.detail ?? instance.instanceId,\n state: instance.state,\n })),\n );\n}\n\n/** Reads a Loop status without letting malformed session data crash the activity dock. */\nexport function parseLoopStatusView(raw: string | undefined): LoopStatusItem[] | undefined {\n if (raw === undefined) return undefined;\n const text = raw.replace(ANSI, '').trim();\n if (text === '') return undefined;\n\n try {\n const value: unknown = JSON.parse(text);\n if (!Array.isArray(value) || value.length === 0) return undefined;\n const items: LoopStatusItem[] = [];\n for (const item of value) {\n if (\n !isRecord(item) ||\n typeof item.instanceId !== 'string' ||\n item.instanceId.trim() === '' ||\n typeof item.label !== 'string' ||\n item.label.trim() === '' ||\n typeof item.detail !== 'string' ||\n !isState(item.state)\n ) {\n return undefined;\n }\n items.push({ instanceId: item.instanceId, label: item.label, detail: item.detail, state: item.state });\n }\n return items;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;AACA,MAAa,uBAAuB;AAoBvB,IAAI,OAAO,OAAO,GAAG,oBAAoB,IAAI;;AAW1D,SAAgB,qBAAqB,WAA4D;CAC/F,IAAI,UAAU,WAAW,GAAG,OAAO,KAAA;CACnC,OAAO,KAAK,UACV,UAAU,KAAK,cAAc;EAC3B,YAAY,SAAS;EACrB,OAAO,SAAS,SAAS,SAAS;EAClC,QAAQ,SAAS,UAAU,SAAS;EACpC,OAAO,SAAS;CAClB,EAAE,CACJ;AACF"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
//#region src/types/loopView.ts
|
|
2
|
-
/** The browser-only status that carries active Loop instances into the activity dock. */
|
|
3
|
-
const LOOP_VIEW_STATUS_KEY = "doom-loop-instances";
|
|
4
|
-
new RegExp(String.raw`\u001b\[[0-9;]*m`, "gu");
|
|
5
|
-
/** Projects runtime snapshots into the JSON status consumed by the web plugin. */
|
|
6
|
-
function formatLoopStatusView(instances) {
|
|
7
|
-
if (instances.length === 0) return void 0;
|
|
8
|
-
return JSON.stringify(instances.map((instance) => ({
|
|
9
|
-
instanceId: instance.instanceId,
|
|
10
|
-
label: instance.label ?? instance.launcherLabel,
|
|
11
|
-
detail: instance.detail ?? instance.instanceId,
|
|
12
|
-
state: instance.state
|
|
13
|
-
})));
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
export { LOOP_VIEW_STATUS_KEY, formatLoopStatusView };
|
|
17
|
-
|
|
18
|
-
//# sourceMappingURL=loopView.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loopView.mjs","names":[],"sources":["../../../src/types/loopView.ts"],"sourcesContent":["/** The browser-only status that carries active Loop instances into the activity dock. */\nexport const LOOP_VIEW_STATUS_KEY = 'doom-loop-instances';\n\nexport type LoopStatusState = 'starting' | 'running' | 'stopping';\n\n/** The small, serializable Loop view the cockpit needs for one activity row. */\nexport interface LoopStatusItem {\n readonly instanceId: string;\n readonly label: string;\n readonly detail: string;\n readonly state: LoopStatusState;\n}\n\ninterface LoopStatusSource {\n readonly instanceId: string;\n readonly launcherLabel: string;\n readonly label?: string;\n readonly detail?: string;\n readonly state: LoopStatusState;\n}\n\nconst ANSI = new RegExp(String.raw`\\u001b\\[[0-9;]*m`, 'gu');\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isState(value: unknown): value is LoopStatusState {\n return value === 'starting' || value === 'running' || value === 'stopping';\n}\n\n/** Projects runtime snapshots into the JSON status consumed by the web plugin. */\nexport function formatLoopStatusView(instances: readonly LoopStatusSource[]): string | undefined {\n if (instances.length === 0) return undefined;\n return JSON.stringify(\n instances.map((instance) => ({\n instanceId: instance.instanceId,\n label: instance.label ?? instance.launcherLabel,\n detail: instance.detail ?? instance.instanceId,\n state: instance.state,\n })),\n );\n}\n\n/** Reads a Loop status without letting malformed session data crash the activity dock. */\nexport function parseLoopStatusView(raw: string | undefined): LoopStatusItem[] | undefined {\n if (raw === undefined) return undefined;\n const text = raw.replace(ANSI, '').trim();\n if (text === '') return undefined;\n\n try {\n const value: unknown = JSON.parse(text);\n if (!Array.isArray(value) || value.length === 0) return undefined;\n const items: LoopStatusItem[] = [];\n for (const item of value) {\n if (\n !isRecord(item) ||\n typeof item.instanceId !== 'string' ||\n item.instanceId.trim() === '' ||\n typeof item.label !== 'string' ||\n item.label.trim() === '' ||\n typeof item.detail !== 'string' ||\n !isState(item.state)\n ) {\n return undefined;\n }\n items.push({ instanceId: item.instanceId, label: item.label, detail: item.detail, state: item.state });\n }\n return items;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;AACA,MAAa,uBAAuB;AAoBvB,IAAI,OAAO,OAAO,GAAG,oBAAoB,IAAI;;AAW1D,SAAgB,qBAAqB,WAA4D;CAC/F,IAAI,UAAU,WAAW,GAAG,OAAO,KAAA;CACnC,OAAO,KAAK,UACV,UAAU,KAAK,cAAc;EAC3B,YAAY,SAAS;EACrB,OAAO,SAAS,SAAS,SAAS;EAClC,QAAQ,SAAS,UAAU,SAAS;EACpC,OAAO,SAAS;CAClB,EAAE,CACJ;AACF"}
|