@agimon-ai/doompi-loop 0.0.1-alpha.9 → 0.0.1-alpha.90
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 +83 -21
- package/dist/apiContracts.cjs +17 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +13 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/extensions/pi.cjs +659 -1
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.mts +5 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +654 -1
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +369 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +364 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +331 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +0 -1
- package/dist/index.d.mts +2 -4
- package/dist/index.mjs +1 -1
- package/dist/loopLaunchers-Bciapxt0.d.mts +69 -0
- package/dist/loopLaunchers-Bciapxt0.d.mts.map +1 -0
- package/dist/loopLaunchers-BtcLH_xN.cjs +32 -0
- package/dist/loopLaunchers-BtcLH_xN.cjs.map +1 -0
- package/dist/loopLaunchers-cCniFbVA.mjs +15 -0
- package/dist/loopLaunchers-cCniFbVA.mjs.map +1 -0
- package/dist/loopLaunchers.cjs +5 -0
- package/dist/loopLaunchers.d.mts +2 -0
- package/dist/loopLaunchers.mjs +2 -0
- package/dist/loopView-BK4X_1UI.mjs +349 -0
- package/dist/loopView-BK4X_1UI.mjs.map +1 -0
- package/dist/loopView-C_OPuy8L.cjs +456 -0
- package/dist/loopView-C_OPuy8L.cjs.map +1 -0
- package/llms.txt +9 -0
- package/package.json +82 -14
- package/src/prompts/doompi-use-loop/SKILL.md +44 -0
- package/src/types/loopView.ts +73 -0
- package/dist/commands/loopCommand.cjs +0 -2
- package/dist/commands/loopCommand.cjs.map +0 -1
- package/dist/commands/loopCommand.mjs +0 -2
- package/dist/commands/loopCommand.mjs.map +0 -1
- package/dist/constants.cjs +0 -2
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.mjs +0 -2
- package/dist/constants.mjs.map +0 -1
- package/dist/defaultLauncher.cjs +0 -2
- package/dist/defaultLauncher.cjs.map +0 -1
- package/dist/defaultLauncher.d.cts +0 -10
- package/dist/defaultLauncher.d.cts.map +0 -1
- package/dist/defaultLauncher.d.mts +0 -10
- package/dist/defaultLauncher.d.mts.map +0 -1
- package/dist/defaultLauncher.mjs +0 -2
- package/dist/defaultLauncher.mjs.map +0 -1
- package/dist/extension.cjs +0 -2
- package/dist/extension.cjs.map +0 -1
- package/dist/extension.d.cts +0 -6
- package/dist/extension.d.cts.map +0 -1
- package/dist/extension.d.mts +0 -6
- package/dist/extension.d.mts.map +0 -1
- package/dist/extension.mjs +0 -2
- package/dist/extension.mjs.map +0 -1
- package/dist/extensions/pi.d.cts +0 -2
- package/dist/index.d.cts +0 -4
- package/dist/launcher.cjs +0 -2
- package/dist/launcher.cjs.map +0 -1
- package/dist/launcher.d.cts +0 -47
- package/dist/launcher.d.cts.map +0 -1
- package/dist/launcher.d.mts +0 -47
- package/dist/launcher.d.mts.map +0 -1
- package/dist/launcher.mjs +0 -2
- package/dist/launcher.mjs.map +0 -1
- package/dist/leader.cjs +0 -2
- package/dist/leader.cjs.map +0 -1
- package/dist/leader.mjs +0 -2
- package/dist/leader.mjs.map +0 -1
- package/dist/tui/loopListOverlay.cjs +0 -2
- package/dist/tui/loopListOverlay.cjs.map +0 -1
- package/dist/tui/loopListOverlay.mjs +0 -2
- package/dist/tui/loopListOverlay.mjs.map +0 -1
- package/dist/tui/startLoopOverlay.cjs +0 -2
- package/dist/tui/startLoopOverlay.cjs.map +0 -1
- package/dist/tui/startLoopOverlay.mjs +0 -2
- package/dist/tui/startLoopOverlay.mjs.map +0 -1
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { defineActivityGroup, defineFill, defineLeaderBinding, defineMinorModeFile, defineSlotFile, defineToolRenderer, defineWebPlugin } from "@agimon-ai/doompi-core/web";
|
|
2
|
+
import { Button, Dot, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, MessageLines, collapseLines, toolTone } from "@agimon-ai/doompi-web-components";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/types/loopView.ts
|
|
5
|
+
/** The browser-only status that carries active Loop instances into the activity dock. */
|
|
6
|
+
const LOOP_VIEW_STATUS_KEY = "doom-loop-instances";
|
|
7
|
+
const ANSI = new RegExp(String.raw`\u001b\[[0-9;]*m`, "gu");
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function isState(value) {
|
|
12
|
+
return value === "starting" || value === "running" || value === "stopping";
|
|
13
|
+
}
|
|
14
|
+
/** Reads a Loop status without letting malformed session data crash the activity dock. */
|
|
15
|
+
function parseLoopStatusView(raw) {
|
|
16
|
+
if (raw === void 0) return void 0;
|
|
17
|
+
const text = raw.replace(ANSI, "").trim();
|
|
18
|
+
if (text === "") return void 0;
|
|
19
|
+
try {
|
|
20
|
+
const value = JSON.parse(text);
|
|
21
|
+
if (!Array.isArray(value) || value.length === 0) return void 0;
|
|
22
|
+
const items = [];
|
|
23
|
+
for (const item of value) {
|
|
24
|
+
if (!isRecord(item) || typeof item.instanceId !== "string" || item.instanceId.trim() === "" || typeof item.label !== "string" || item.label.trim() === "" || typeof item.detail !== "string" || !isState(item.state)) return;
|
|
25
|
+
items.push({
|
|
26
|
+
instanceId: item.instanceId,
|
|
27
|
+
label: item.label,
|
|
28
|
+
detail: item.detail,
|
|
29
|
+
state: item.state
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return items;
|
|
33
|
+
} catch {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/extensions/workspaces/sessions/(frontend)/activity-group/loops.web.ts
|
|
39
|
+
var loops_web_default = defineActivityGroup({
|
|
40
|
+
keys: "l l",
|
|
41
|
+
statusKey: LOOP_VIEW_STATUS_KEY,
|
|
42
|
+
order: 40
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/_components/LoopsActivitySection.tsx
|
|
46
|
+
const MANAGE_COMMAND = "/loops";
|
|
47
|
+
const DEFAULT_LOOP_COMMAND = "/loop doompi.default";
|
|
48
|
+
/** Starts the built-in prompt loop without opening a generic launcher chooser. */
|
|
49
|
+
function DefaultLoopLauncher({ sessionId, sendSessionFrame }) {
|
|
50
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
51
|
+
variant: "subtle",
|
|
52
|
+
size: "xs",
|
|
53
|
+
"data-testid": "activity-loop-default-launch",
|
|
54
|
+
"aria-label": "launch default loop",
|
|
55
|
+
disabled: sessionId === null,
|
|
56
|
+
onClick: () => {
|
|
57
|
+
if (sessionId === null) return;
|
|
58
|
+
sendSessionFrame(sessionId, {
|
|
59
|
+
type: "prompt",
|
|
60
|
+
message: DEFAULT_LOOP_COMMAND
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
className: "text-2xs font-bold",
|
|
64
|
+
children: "default loop"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function toneOf(state) {
|
|
68
|
+
if (state === "running") return "green";
|
|
69
|
+
if (state === "stopping") return "orange";
|
|
70
|
+
return "yellow";
|
|
71
|
+
}
|
|
72
|
+
/** Renders active recurring prompts contributed to the Loop activity section. */
|
|
73
|
+
function LoopActivityItems({ statuses, sessionId, sendSessionFrame }) {
|
|
74
|
+
const raw = statuses[LOOP_VIEW_STATUS_KEY];
|
|
75
|
+
const loops = parseLoopStatusView(raw);
|
|
76
|
+
const unavailable = raw !== void 0 && raw.trim() !== "" && loops === void 0;
|
|
77
|
+
if (!loops && !unavailable) return null;
|
|
78
|
+
return loops ? /* @__PURE__ */ jsx("ul", {
|
|
79
|
+
"aria-label": "active loops",
|
|
80
|
+
className: "flex flex-col gap-1",
|
|
81
|
+
children: loops.map((loop) => /* @__PURE__ */ jsxs("li", {
|
|
82
|
+
"data-testid": `activity-loop-${loop.instanceId}`,
|
|
83
|
+
"data-loop-state": loop.state,
|
|
84
|
+
title: `${loop.label}: ${loop.detail}`,
|
|
85
|
+
className: "flex min-w-0 flex-col gap-0.5 px-1 py-0.5",
|
|
86
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
87
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Dot, {
|
|
90
|
+
tone: toneOf(loop.state),
|
|
91
|
+
pulse: loop.state !== "running"
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ jsx("span", {
|
|
94
|
+
className: "min-w-0 flex-1 truncate text-xs font-bold text-doom-hi",
|
|
95
|
+
children: loop.label
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ jsx("span", {
|
|
98
|
+
className: "shrink-0 text-2xs text-doom-faint",
|
|
99
|
+
children: loop.state
|
|
100
|
+
}),
|
|
101
|
+
/* @__PURE__ */ jsx(Button, {
|
|
102
|
+
variant: "subtle",
|
|
103
|
+
size: "xs",
|
|
104
|
+
"aria-label": `stop ${loop.label}`,
|
|
105
|
+
disabled: sessionId === null || loop.state === "stopping",
|
|
106
|
+
onClick: () => {
|
|
107
|
+
if (sessionId !== null) sendSessionFrame(sessionId, {
|
|
108
|
+
type: "prompt",
|
|
109
|
+
message: `/loops stop ${loop.instanceId}`
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
children: "stop"
|
|
113
|
+
})
|
|
114
|
+
]
|
|
115
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
116
|
+
className: "truncate pl-3 text-2xs text-doom-faint",
|
|
117
|
+
children: loop.detail
|
|
118
|
+
})]
|
|
119
|
+
}, loop.instanceId))
|
|
120
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
121
|
+
className: "px-1 text-xs text-doom-faint",
|
|
122
|
+
children: "loop status unavailable"
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/** Idle-safe Loop activity shell with extension registration and instance slots. */
|
|
126
|
+
function LoopsActivitySection({ sessionId, renderSlot, sendSessionFrame }) {
|
|
127
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
128
|
+
"data-testid": "activity-loop-instances",
|
|
129
|
+
className: "flex flex-col gap-2",
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ jsxs("div", {
|
|
132
|
+
className: "flex flex-wrap items-center gap-1",
|
|
133
|
+
children: [
|
|
134
|
+
/* @__PURE__ */ jsx(DefaultLoopLauncher, {
|
|
135
|
+
sessionId,
|
|
136
|
+
sendSessionFrame
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ jsx(Button, {
|
|
139
|
+
variant: "subtle",
|
|
140
|
+
size: "xs",
|
|
141
|
+
"data-testid": "activity-loop-cron-launch",
|
|
142
|
+
"aria-label": "launch cron loop",
|
|
143
|
+
disabled: sessionId === null,
|
|
144
|
+
onClick: () => {
|
|
145
|
+
if (sessionId !== null) sendSessionFrame(sessionId, {
|
|
146
|
+
type: "prompt",
|
|
147
|
+
message: "/loop doompi.cron"
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
className: "text-2xs font-bold",
|
|
151
|
+
children: "cron loop"
|
|
152
|
+
}),
|
|
153
|
+
/* @__PURE__ */ jsx(Button, {
|
|
154
|
+
variant: "subtle",
|
|
155
|
+
size: "xs",
|
|
156
|
+
"aria-label": "choose loop type",
|
|
157
|
+
disabled: sessionId === null,
|
|
158
|
+
onClick: () => {
|
|
159
|
+
if (sessionId !== null) sendSessionFrame(sessionId, {
|
|
160
|
+
type: "prompt",
|
|
161
|
+
message: "/loop"
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
className: "text-2xs font-bold",
|
|
165
|
+
children: "choose type"
|
|
166
|
+
}),
|
|
167
|
+
renderSlot("loop.registration")
|
|
168
|
+
]
|
|
169
|
+
}),
|
|
170
|
+
renderSlot("loop.items"),
|
|
171
|
+
/* @__PURE__ */ jsx(Button, {
|
|
172
|
+
variant: "subtle",
|
|
173
|
+
size: "xs",
|
|
174
|
+
"data-testid": "activity-loops-manage",
|
|
175
|
+
"aria-label": "manage loops",
|
|
176
|
+
disabled: sessionId === null,
|
|
177
|
+
onClick: () => {
|
|
178
|
+
if (sessionId === null) return;
|
|
179
|
+
sendSessionFrame(sessionId, {
|
|
180
|
+
type: "prompt",
|
|
181
|
+
message: MANAGE_COMMAND
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
className: "self-end text-2xs font-bold",
|
|
185
|
+
children: "manage"
|
|
186
|
+
})
|
|
187
|
+
]
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.web.tsx
|
|
192
|
+
var Instances_loop_items_web_default = defineFill({ component: LoopActivityItems });
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.web.tsx
|
|
195
|
+
var Loops_activity_loops_web_default = defineFill({ component: LoopsActivitySection });
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/extensions/workspaces/sessions/(frontend)/leader/list.web.ts
|
|
198
|
+
var list_web_default = defineLeaderBinding({
|
|
199
|
+
path: [{
|
|
200
|
+
key: "l",
|
|
201
|
+
label: "loops",
|
|
202
|
+
detail: "recurring prompt loops"
|
|
203
|
+
}, {
|
|
204
|
+
key: "l",
|
|
205
|
+
label: "list",
|
|
206
|
+
detail: "loops in this session"
|
|
207
|
+
}],
|
|
208
|
+
command: "loops"
|
|
209
|
+
});
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/extensions/workspaces/sessions/(frontend)/leader/start.web.ts
|
|
212
|
+
var start_web_default = defineLeaderBinding({
|
|
213
|
+
path: [{
|
|
214
|
+
key: "l",
|
|
215
|
+
label: "loops",
|
|
216
|
+
detail: "recurring prompt loops"
|
|
217
|
+
}, {
|
|
218
|
+
key: "s",
|
|
219
|
+
label: "start",
|
|
220
|
+
detail: "begin a recurring loop"
|
|
221
|
+
}],
|
|
222
|
+
command: "loop"
|
|
223
|
+
});
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/extensions/workspaces/sessions/(frontend)/mode/loop/mode.web.ts
|
|
226
|
+
var mode_web_default = defineMinorModeFile({
|
|
227
|
+
keys: "l l",
|
|
228
|
+
statusKey: "doom-loop",
|
|
229
|
+
order: 30
|
|
230
|
+
});
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/extensions/workspaces/sessions/(frontend)/slot/items.web.ts
|
|
233
|
+
var items_web_default = defineSlotFile({});
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/extensions/workspaces/sessions/(frontend)/slot/registration.web.ts
|
|
236
|
+
var registration_web_default = defineSlotFile({});
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_components/LoopToolCard.tsx
|
|
239
|
+
/** Loop tools share the same compact, expandable result presentation. */
|
|
240
|
+
function LoopToolCard({ toolName, result, running, isError }) {
|
|
241
|
+
const lines = result === void 0 ? [] : JSON.stringify(result, null, 2).split("\n").map((text) => ({
|
|
242
|
+
text,
|
|
243
|
+
tone: "text"
|
|
244
|
+
}));
|
|
245
|
+
return /* @__PURE__ */ jsx(MessageItem, {
|
|
246
|
+
tone: toolTone({
|
|
247
|
+
running,
|
|
248
|
+
isError
|
|
249
|
+
}),
|
|
250
|
+
expandable: lines.length > 8,
|
|
251
|
+
children: ({ expanded }) => {
|
|
252
|
+
const view = collapseLines(lines, 8, expanded);
|
|
253
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, { title: toolName }), /* @__PURE__ */ jsxs(MessageItemBody, { children: [
|
|
254
|
+
/* @__PURE__ */ jsx(MessageLines, { lines: view.shown }),
|
|
255
|
+
view.hidden > 0 ? /* @__PURE__ */ jsxs(MessageItemStatus, {
|
|
256
|
+
expands: true,
|
|
257
|
+
children: [view.hidden, " more lines"]
|
|
258
|
+
}) : null,
|
|
259
|
+
running ? /* @__PURE__ */ jsx(MessageItemStatus, {
|
|
260
|
+
tone: "running",
|
|
261
|
+
children: "running"
|
|
262
|
+
}) : null,
|
|
263
|
+
isError ? /* @__PURE__ */ jsx(MessageItemStatus, {
|
|
264
|
+
tone: "error",
|
|
265
|
+
children: "failed"
|
|
266
|
+
}) : null
|
|
267
|
+
] })] });
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/loop-list.web.tsx
|
|
273
|
+
var loop_list_web_default = defineToolRenderer({
|
|
274
|
+
tools: ["loop_list"],
|
|
275
|
+
message: LoopToolCard
|
|
276
|
+
});
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/loop-start.web.tsx
|
|
279
|
+
var loop_start_web_default = defineToolRenderer({
|
|
280
|
+
tools: ["loop_start"],
|
|
281
|
+
message: LoopToolCard
|
|
282
|
+
});
|
|
283
|
+
//#endregion
|
|
284
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/loop-stop.web.tsx
|
|
285
|
+
var loop_stop_web_default = defineToolRenderer({
|
|
286
|
+
tools: ["loop_stop"],
|
|
287
|
+
message: LoopToolCard
|
|
288
|
+
});
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region generated/web.ts
|
|
291
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
292
|
+
...identity,
|
|
293
|
+
...value
|
|
294
|
+
};
|
|
295
|
+
const webPlugin = defineWebPlugin({
|
|
296
|
+
id: "loop",
|
|
297
|
+
session: {
|
|
298
|
+
get activityGroups() {
|
|
299
|
+
return [via({ name: "loops" }, loops_web_default)];
|
|
300
|
+
},
|
|
301
|
+
get fills() {
|
|
302
|
+
return [via({
|
|
303
|
+
slot: "loop.items",
|
|
304
|
+
id: "instances"
|
|
305
|
+
}, Instances_loop_items_web_default), via({
|
|
306
|
+
slot: "activity.loops",
|
|
307
|
+
id: "loops"
|
|
308
|
+
}, Loops_activity_loops_web_default)];
|
|
309
|
+
},
|
|
310
|
+
get leaderBindings() {
|
|
311
|
+
return [via({ id: "loop.list" }, list_web_default), via({ id: "loop.start" }, start_web_default)];
|
|
312
|
+
},
|
|
313
|
+
get minorModes() {
|
|
314
|
+
return [via({ name: "loop" }, mode_web_default)];
|
|
315
|
+
},
|
|
316
|
+
get slots() {
|
|
317
|
+
return [via({ slot: "loop.items" }, items_web_default), via({ slot: "loop.registration" }, registration_web_default)];
|
|
318
|
+
},
|
|
319
|
+
get toolRenderers() {
|
|
320
|
+
return [
|
|
321
|
+
via({ tools: ["loop_list"] }, loop_list_web_default),
|
|
322
|
+
via({ tools: ["loop_start"] }, loop_start_web_default),
|
|
323
|
+
via({ tools: ["loop_stop"] }, loop_stop_web_default)
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
//#endregion
|
|
329
|
+
export { webPlugin };
|
|
330
|
+
|
|
331
|
+
//# sourceMappingURL=web.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.mjs","names":["activityGroupLoops","fillInstances","fillLoops","leaderList","leaderStart","modeLoop","slotItems","slotRegistration","toolLoopList","toolLoopStart","toolLoopStop"],"sources":["../../src/types/loopView.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/loops.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/LoopsActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/leader/list.web.ts","../../src/extensions/workspaces/sessions/(frontend)/leader/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/mode/loop/mode.web.ts","../../src/extensions/workspaces/sessions/(frontend)/slot/items.web.ts","../../src/extensions/workspaces/sessions/(frontend)/slot/registration.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/LoopToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/loop-list.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/loop-start.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/loop-stop.web.tsx","../../generated/web.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 {\n if (instances.length === 0) return '';\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","import { defineActivityGroup } from '@agimon-ai/doompi-core/web';\n\nimport { LOOP_VIEW_STATUS_KEY } from '../../../../../types/loopView';\n\nexport default defineActivityGroup({\n keys: 'l l',\n statusKey: LOOP_VIEW_STATUS_KEY,\n order: 40,\n});\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\nimport { Button, Dot, type DotTone } from '@agimon-ai/doompi-web-components';\n\nimport { LOOP_VIEW_STATUS_KEY, parseLoopStatusView, type LoopStatusState } from '../../../../../../types/loopView';\n\nconst MANAGE_COMMAND = '/loops';\nconst DEFAULT_LOOP_COMMAND = '/loop doompi.default';\n\n/** Starts the built-in prompt loop without opening a generic launcher chooser. */\nexport function DefaultLoopLauncher({\n sessionId,\n sendSessionFrame,\n}: Pick<WebPluginSlotProps, 'sessionId' | 'sendSessionFrame'>) {\n return (\n <Button\n variant=\"subtle\"\n size=\"xs\"\n data-testid=\"activity-loop-default-launch\"\n aria-label=\"launch default loop\"\n disabled={sessionId === null}\n onClick={() => {\n if (sessionId === null) return;\n sendSessionFrame(sessionId, { type: 'prompt', message: DEFAULT_LOOP_COMMAND });\n }}\n className=\"text-2xs font-bold\"\n >\n default loop\n </Button>\n );\n}\n\nfunction toneOf(state: LoopStatusState): DotTone {\n if (state === 'running') return 'green';\n if (state === 'stopping') return 'orange';\n return 'yellow';\n}\n\n/** Renders active recurring prompts contributed to the Loop activity section. */\nexport function LoopActivityItems({\n statuses,\n sessionId,\n sendSessionFrame,\n}: Pick<WebPluginSlotProps, 'statuses' | 'sessionId' | 'sendSessionFrame'>) {\n const raw = statuses[LOOP_VIEW_STATUS_KEY];\n const loops = parseLoopStatusView(raw);\n const unavailable = raw !== undefined && raw.trim() !== '' && loops === undefined;\n if (!loops && !unavailable) return null;\n\n return loops ? (\n <ul aria-label=\"active loops\" className=\"flex flex-col gap-1\">\n {loops.map((loop) => (\n <li\n key={loop.instanceId}\n data-testid={`activity-loop-${loop.instanceId}`}\n data-loop-state={loop.state}\n title={`${loop.label}: ${loop.detail}`}\n className=\"flex min-w-0 flex-col gap-0.5 px-1 py-0.5\"\n >\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <Dot tone={toneOf(loop.state)} pulse={loop.state !== 'running'} />\n <span className=\"min-w-0 flex-1 truncate text-xs font-bold text-doom-hi\">{loop.label}</span>\n <span className=\"shrink-0 text-2xs text-doom-faint\">{loop.state}</span>\n <Button\n variant=\"subtle\"\n size=\"xs\"\n aria-label={`stop ${loop.label}`}\n disabled={sessionId === null || loop.state === 'stopping'}\n onClick={() => {\n if (sessionId !== null)\n sendSessionFrame(sessionId, { type: 'prompt', message: `/loops stop ${loop.instanceId}` });\n }}\n >\n stop\n </Button>\n </span>\n <span className=\"truncate pl-3 text-2xs text-doom-faint\">{loop.detail}</span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"px-1 text-xs text-doom-faint\">loop status unavailable</p>\n );\n}\n\n/** Idle-safe Loop activity shell with extension registration and instance slots. */\nexport function LoopsActivitySection({ sessionId, renderSlot, sendSessionFrame }: WebPluginSlotProps) {\n return (\n <div data-testid=\"activity-loop-instances\" className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <DefaultLoopLauncher sessionId={sessionId} sendSessionFrame={sendSessionFrame} />\n <Button\n variant=\"subtle\"\n size=\"xs\"\n data-testid=\"activity-loop-cron-launch\"\n aria-label=\"launch cron loop\"\n disabled={sessionId === null}\n onClick={() => {\n if (sessionId !== null) sendSessionFrame(sessionId, { type: 'prompt', message: '/loop doompi.cron' });\n }}\n className=\"text-2xs font-bold\"\n >\n cron loop\n </Button>\n <Button\n variant=\"subtle\"\n size=\"xs\"\n aria-label=\"choose loop type\"\n disabled={sessionId === null}\n onClick={() => {\n if (sessionId !== null) sendSessionFrame(sessionId, { type: 'prompt', message: '/loop' });\n }}\n className=\"text-2xs font-bold\"\n >\n choose type\n </Button>\n {renderSlot('loop.registration')}\n </div>\n {renderSlot('loop.items')}\n <Button\n variant=\"subtle\"\n size=\"xs\"\n data-testid=\"activity-loops-manage\"\n aria-label=\"manage loops\"\n disabled={sessionId === null}\n onClick={() => {\n if (sessionId === null) return;\n sendSessionFrame(sessionId, { type: 'prompt', message: MANAGE_COMMAND });\n }}\n className=\"self-end text-2xs font-bold\"\n >\n manage\n </Button>\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { LoopActivityItems } from './_components/LoopsActivitySection';\n\nexport default defineFill({ component: LoopActivityItems });\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { LoopsActivitySection } from './_components/LoopsActivitySection';\n\nexport default defineFill({ component: LoopsActivitySection });\n","import { defineLeaderBinding } from '@agimon-ai/doompi-core/web';\n\nexport default defineLeaderBinding({\n path: [\n { key: 'l', label: 'loops', detail: 'recurring prompt loops' },\n { key: 'l', label: 'list', detail: 'loops in this session' },\n ],\n command: 'loops',\n});\n","import { defineLeaderBinding } from '@agimon-ai/doompi-core/web';\n\nexport default defineLeaderBinding({\n path: [\n { key: 'l', label: 'loops', detail: 'recurring prompt loops' },\n { key: 's', label: 'start', detail: 'begin a recurring loop' },\n ],\n command: 'loop',\n});\n","import { defineMinorModeFile } from '@agimon-ai/doompi-core/web';\n\nexport default defineMinorModeFile({ keys: 'l l', statusKey: 'doom-loop', order: 30 });\n","import { defineSlotFile } from '@agimon-ai/doompi-core/web';\n\nexport default defineSlotFile({});\n","import { defineSlotFile } from '@agimon-ai/doompi-core/web';\n\nexport default defineSlotFile({});\n","import type { ToolMessageRenderProps } from '@agimon-ai/doompi-core/web';\nimport {\n collapseLines,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n MessageLines,\n toolTone,\n} from '@agimon-ai/doompi-web-components';\n\n/** Loop tools share the same compact, expandable result presentation. */\nexport function LoopToolCard({ toolName, result, running, isError }: ToolMessageRenderProps) {\n const lines =\n result === undefined\n ? []\n : JSON.stringify(result, null, 2)\n .split('\\n')\n .map((text) => ({ text, tone: 'text' as const }));\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={lines.length > 8}>\n {({ expanded }) => {\n const view = collapseLines(lines, 8, expanded);\n return (\n <>\n <MessageItemHeader title={toolName} />\n <MessageItemBody>\n <MessageLines lines={view.shown} />\n {view.hidden > 0 ? <MessageItemStatus expands>{view.hidden} more lines</MessageItemStatus> : null}\n {running ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n {isError ? <MessageItemStatus tone=\"error\">failed</MessageItemStatus> : null}\n </MessageItemBody>\n </>\n );\n }}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { LoopToolCard } from './_components/LoopToolCard';\n\nexport default defineToolRenderer({ tools: ['loop_list'], message: LoopToolCard });\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { LoopToolCard } from './_components/LoopToolCard';\n\nexport default defineToolRenderer({ tools: ['loop_start'], message: LoopToolCard });\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { LoopToolCard } from './_components/LoopToolCard';\n\nexport default defineToolRenderer({ tools: ['loop_stop'], message: LoopToolCard });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport activityGroupLoops from '../src/extensions/workspaces/sessions/(frontend)/activity-group/loops.web';\nimport fillInstances from '../src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.web';\nimport fillLoops from '../src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.web';\nimport leaderList from '../src/extensions/workspaces/sessions/(frontend)/leader/list.web';\nimport leaderStart from '../src/extensions/workspaces/sessions/(frontend)/leader/start.web';\nimport modeLoop from '../src/extensions/workspaces/sessions/(frontend)/mode/loop/mode.web';\nimport slotItems from '../src/extensions/workspaces/sessions/(frontend)/slot/items.web';\nimport slotRegistration from '../src/extensions/workspaces/sessions/(frontend)/slot/registration.web';\nimport toolLoopList from '../src/extensions/workspaces/sessions/(frontend)/tool/loop-list.web';\nimport toolLoopStart from '../src/extensions/workspaces/sessions/(frontend)/tool/loop-start.web';\nimport toolLoopStop from '../src/extensions/workspaces/sessions/(frontend)/tool/loop-stop.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'loop',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'loops' }, activityGroupLoops)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'loop.items', id: 'instances' }, fillInstances), via({ slot: 'activity.loops', id: 'loops' }, fillLoops)]; },\n get leaderBindings(): WebPluginContributions['leaderBindings'] { return [via({ id: 'loop.list' }, leaderList), via({ id: 'loop.start' }, leaderStart)]; },\n get minorModes(): WebPluginContributions['minorModes'] { return [via({ name: 'loop' }, modeLoop)]; },\n get slots(): WebPluginContributions['slots'] { return [via({ slot: 'loop.items' }, slotItems), via({ slot: 'loop.registration' }, slotRegistration)]; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['loop_list'] }, toolLoopList), via({ tools: ['loop_start'] }, toolLoopStart), via({ tools: ['loop_stop'] }, toolLoopStop)]; },\n },\n});\n"],"mappings":";;;;;AACA,MAAa,uBAAuB;AAoBpC,MAAM,OAAO,IAAI,OAAO,OAAO,GAAG,oBAAoB,IAAI;AAE1D,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,OAA0C;CACzD,OAAO,UAAU,cAAc,UAAU,aAAa,UAAU;AAClE;;AAgBA,SAAgB,oBAAoB,KAAuD;CACzF,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAA;CAC9B,MAAM,OAAO,IAAI,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK;CACxC,IAAI,SAAS,IAAI,OAAO,KAAA;CAExB,IAAI;EACF,MAAM,QAAiB,KAAK,MAAM,IAAI;EACtC,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG,OAAO,KAAA;EACxD,MAAM,QAA0B,CAAC;EACjC,KAAK,MAAM,QAAQ,OAAO;GACxB,IACE,CAAC,SAAS,IAAI,KACd,OAAO,KAAK,eAAe,YAC3B,KAAK,WAAW,KAAK,MAAM,MAC3B,OAAO,KAAK,UAAU,YACtB,KAAK,MAAM,KAAK,MAAM,MACtB,OAAO,KAAK,WAAW,YACvB,CAAC,QAAQ,KAAK,KAAK,GAEnB;GAEF,MAAM,KAAK;IAAE,YAAY,KAAK;IAAY,OAAO,KAAK;IAAO,QAAQ,KAAK;IAAQ,OAAO,KAAK;GAAM,CAAC;EACvG;EACA,OAAO;CACT,QAAQ;EACN;CACF;AACF;;;ACpEA,IAAA,oBAAe,oBAAoB;CACjC,MAAM;CACN,WAAW;CACX,OAAO;AACT,CAAC;;;ACHD,MAAM,iBAAiB;AACvB,MAAM,uBAAuB;;AAG7B,SAAgB,oBAAoB,EAClC,WACA,oBAC6D;CAC7D,OACE,oBAAC,QAAD;EACE,SAAQ;EACR,MAAK;EACL,eAAY;EACZ,cAAW;EACX,UAAU,cAAc;EACxB,eAAe;GACb,IAAI,cAAc,MAAM;GACxB,iBAAiB,WAAW;IAAE,MAAM;IAAU,SAAS;GAAqB,CAAC;EAC/E;EACA,WAAU;EACX,UAAA;CAEO,CAAA;AAEZ;AAEA,SAAS,OAAO,OAAiC;CAC/C,IAAI,UAAU,WAAW,OAAO;CAChC,IAAI,UAAU,YAAY,OAAO;CACjC,OAAO;AACT;;AAGA,SAAgB,kBAAkB,EAChC,UACA,WACA,oBAC0E;CAC1E,MAAM,MAAM,SAAS;CACrB,MAAM,QAAQ,oBAAoB,GAAG;CACrC,MAAM,cAAc,QAAQ,KAAA,KAAa,IAAI,KAAK,MAAM,MAAM,UAAU,KAAA;CACxE,IAAI,CAAC,SAAS,CAAC,aAAa,OAAO;CAEnC,OAAO,QACL,oBAAC,MAAD;EAAI,cAAW;EAAe,WAAU;EACrC,UAAA,MAAM,KAAK,SACV,qBAAC,MAAD;GAEE,eAAa,iBAAiB,KAAK;GACnC,mBAAiB,KAAK;GACtB,OAAO,GAAG,KAAK,MAAM,IAAI,KAAK;GAC9B,WAAU;GALZ,UAAA,CAOE,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA;KACE,oBAAC,KAAD;MAAK,MAAM,OAAO,KAAK,KAAK;MAAG,OAAO,KAAK,UAAU;KAAY,CAAA;KACjE,oBAAC,QAAD;MAAM,WAAU;MAA0D,UAAA,KAAK;KAAY,CAAA;KAC3F,oBAAC,QAAD;MAAM,WAAU;MAAqC,UAAA,KAAK;KAAY,CAAA;KACtE,oBAAC,QAAD;MACE,SAAQ;MACR,MAAK;MACL,cAAY,QAAQ,KAAK;MACzB,UAAU,cAAc,QAAQ,KAAK,UAAU;MAC/C,eAAe;OACb,IAAI,cAAc,MAChB,iBAAiB,WAAW;QAAE,MAAM;QAAU,SAAS,eAAe,KAAK;OAAa,CAAC;MAC7F;MACD,UAAA;KAEO,CAAA;IACJ;GACN,CAAA,GAAA,oBAAC,QAAD;IAAM,WAAU;IAA0C,UAAA,KAAK;GAAa,CAAA,CAC1E;EAxBG,GAAA,KAAK,UAwBR,CACL;CACC,CAAA,IAEJ,oBAAC,KAAD;EAAG,WAAU;EAA+B,UAAA;CAA0B,CAAA;AAE1E;;AAGA,SAAgB,qBAAqB,EAAE,WAAW,YAAY,oBAAwC;CACpG,OACE,qBAAC,OAAD;EAAK,eAAY;EAA0B,WAAU;EAArD,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,qBAAD;MAAgC;MAA6B;KAAmB,CAAA;KAChF,oBAAC,QAAD;MACE,SAAQ;MACR,MAAK;MACL,eAAY;MACZ,cAAW;MACX,UAAU,cAAc;MACxB,eAAe;OACb,IAAI,cAAc,MAAM,iBAAiB,WAAW;QAAE,MAAM;QAAU,SAAS;OAAoB,CAAC;MACtG;MACA,WAAU;MACX,UAAA;KAEO,CAAA;KACR,oBAAC,QAAD;MACE,SAAQ;MACR,MAAK;MACL,cAAW;MACX,UAAU,cAAc;MACxB,eAAe;OACb,IAAI,cAAc,MAAM,iBAAiB,WAAW;QAAE,MAAM;QAAU,SAAS;OAAQ,CAAC;MAC1F;MACA,WAAU;MACX,UAAA;KAEO,CAAA;KACP,WAAW,mBAAmB;IAC5B;;GACJ,WAAW,YAAY;GACxB,oBAAC,QAAD;IACE,SAAQ;IACR,MAAK;IACL,eAAY;IACZ,cAAW;IACX,UAAU,cAAc;IACxB,eAAe;KACb,IAAI,cAAc,MAAM;KACxB,iBAAiB,WAAW;MAAE,MAAM;MAAU,SAAS;KAAe,CAAC;IACzE;IACA,WAAU;IACX,UAAA;GAEO,CAAA;EACL;;AAET;;;AClIA,IAAA,mCAAe,WAAW,EAAE,WAAW,kBAAkB,CAAC;;;ACA1D,IAAA,mCAAe,WAAW,EAAE,WAAW,qBAAqB,CAAC;;;ACF7D,IAAA,mBAAe,oBAAoB;CACjC,MAAM,CACJ;EAAE,KAAK;EAAK,OAAO;EAAS,QAAQ;CAAyB,GAC7D;EAAE,KAAK;EAAK,OAAO;EAAQ,QAAQ;CAAwB,CAC7D;CACA,SAAS;AACX,CAAC;;;ACND,IAAA,oBAAe,oBAAoB;CACjC,MAAM,CACJ;EAAE,KAAK;EAAK,OAAO;EAAS,QAAQ;CAAyB,GAC7D;EAAE,KAAK;EAAK,OAAO;EAAS,QAAQ;CAAyB,CAC/D;CACA,SAAS;AACX,CAAC;;;ACND,IAAA,mBAAe,oBAAoB;CAAE,MAAM;CAAO,WAAW;CAAa,OAAO;AAAG,CAAC;;;ACArF,IAAA,oBAAe,eAAe,CAAC,CAAC;;;ACAhC,IAAA,2BAAe,eAAe,CAAC,CAAC;;;;ACUhC,SAAgB,aAAa,EAAE,UAAU,QAAQ,SAAS,WAAmC;CAC3F,MAAM,QACJ,WAAW,KAAA,IACP,CAAC,IACD,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC,CAC5B,MAAM,IAAI,CAAC,CACX,KAAK,UAAU;EAAE;EAAM,MAAM;CAAgB,EAAE;CACxD,OACE,oBAAC,aAAD;EAAa,MAAM,SAAS;GAAE;GAAS;EAAQ,CAAC;EAAG,YAAY,MAAM,SAAS;EAC1E,WAAA,EAAE,eAAe;GACjB,MAAM,OAAO,cAAc,OAAO,GAAG,QAAQ;GAC7C,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,mBAAD,EAAmB,OAAO,SAAW,CAAA,GACrC,qBAAC,iBAAD,EAAA,UAAA;IACE,oBAAC,cAAD,EAAc,OAAO,KAAK,MAAQ,CAAA;IACjC,KAAK,SAAS,IAAI,qBAAC,mBAAD;KAAmB,SAAA;KAAnB,UAAA,CAA4B,KAAK,QAAO,aAA8B;IAAI,CAAA,IAAA;IAC5F,UAAU,oBAAC,mBAAD;KAAmB,MAAK;KAAU,UAAA;IAA0B,CAAA,IAAI;IAC1E,UAAU,oBAAC,mBAAD;KAAmB,MAAK;KAAQ,UAAA;IAAyB,CAAA,IAAI;GACzD,EAAA,CAAA,CACjB,EAAA,CAAA;EAEN;CACW,CAAA;AAEjB;;;ACjCA,IAAA,wBAAe,mBAAmB;CAAE,OAAO,CAAC,WAAW;CAAG,SAAS;AAAa,CAAC;;;ACAjF,IAAA,yBAAe,mBAAmB;CAAE,OAAO,CAAC,YAAY;CAAG,SAAS;AAAa,CAAC;;;ACAlF,IAAA,wBAAe,mBAAmB;CAAE,OAAO,CAAC,WAAW;CAAG,SAAS;AAAa,CAAC;;;ACWjF,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,gBAAgB;CACvC,IAAI;CACJ,SAAS;EACP,IAAI,iBAA2D;GAAE,OAAO,CAAC,IAAI,EAAE,MAAM,QAAQ,GAAGA,iBAAkB,CAAC;EAAG;EACtH,IAAI,QAAyC;GAAE,OAAO,CAAC,IAAI;IAAE,MAAM;IAAc,IAAI;GAAY,GAAGC,gCAAa,GAAG,IAAI;IAAE,MAAM;IAAkB,IAAI;GAAQ,GAAGC,gCAAS,CAAC;EAAG;EAC9K,IAAI,iBAA2D;GAAE,OAAO,CAAC,IAAI,EAAE,IAAI,YAAY,GAAGC,gBAAU,GAAG,IAAI,EAAE,IAAI,aAAa,GAAGC,iBAAW,CAAC;EAAG;EACxJ,IAAI,aAAmD;GAAE,OAAO,CAAC,IAAI,EAAE,MAAM,OAAO,GAAGC,gBAAQ,CAAC;EAAG;EACnG,IAAI,QAAyC;GAAE,OAAO,CAAC,IAAI,EAAE,MAAM,aAAa,GAAGC,iBAAS,GAAG,IAAI,EAAE,MAAM,oBAAoB,GAAGC,wBAAgB,CAAC;EAAG;EACtJ,IAAI,gBAAyD;GAAE,OAAO;IAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,GAAGC,qBAAY;IAAG,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,GAAGC,sBAAa;IAAG,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,GAAGC,qBAAY;GAAC;EAAG;CACnN;AACF,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./launcher.cjs"),t=require("./defaultLauncher.cjs"),n=require("./extension.cjs");exports.createDefaultLoopLauncher=t.createDefaultLoopLauncher,exports.createLoopLauncherClient=e.createLoopLauncherClient,exports.registerLoopExtension=n.registerLoopExtension,exports.registerLoopLauncher=e.registerLoopLauncher;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { DefaultLoopLauncher, createDefaultLoopLauncher } from "./defaultLauncher.mjs";
|
|
4
|
-
export { type DefaultLoopLauncher, type LoopInstanceSnapshot, type LoopLaunchRequest, type LoopLauncherClient, type LoopLauncherRegistration, type LoopLauncherSummary, type RegisterLoopLauncherOptions, type StoppableLoop, createDefaultLoopLauncher, createLoopLauncherClient, registerLoopExtension, registerLoopLauncher };
|
|
1
|
+
import { a as LoopLauncherDefinition, c as StoppableLoop, i as LoopLaunchRequest, n as DoomLoopLaunchersService, o as LoopLauncherRegistration, r as LoopInstanceSnapshot, s as LoopLauncherSummary } from "./loopLaunchers-Bciapxt0.mjs";
|
|
2
|
+
export type { DoomLoopLaunchersService, LoopInstanceSnapshot, LoopLaunchRequest, LoopLauncherDefinition, LoopLauncherRegistration, LoopLauncherSummary, StoppableLoop };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
//#region src/schemas/loopLaunchers.d.ts
|
|
3
|
+
/** Provider-owned Cordis service for session-scoped recurring-loop launchers. */
|
|
4
|
+
declare const DOOM_LOOP_LAUNCHERS_SERVICE = "doom/loop-launchers";
|
|
5
|
+
interface LoopLaunchRequest {
|
|
6
|
+
readonly instanceId: string;
|
|
7
|
+
readonly signal: AbortSignal;
|
|
8
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
9
|
+
/** False for agent calls: a launcher must never open an operator dialog. */
|
|
10
|
+
readonly interactive?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface StoppableLoop {
|
|
13
|
+
readonly instanceId: string;
|
|
14
|
+
readonly label?: string;
|
|
15
|
+
readonly detail?: string;
|
|
16
|
+
stop(reason?: string): void | Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
interface LoopLauncherSummary {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly source: string;
|
|
21
|
+
readonly label: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
/** JSON Schema for non-interactive launch configuration, validated by the launcher. */
|
|
24
|
+
readonly inputSchema?: Readonly<Record<string, unknown>>;
|
|
25
|
+
}
|
|
26
|
+
interface LoopInstanceSnapshot {
|
|
27
|
+
readonly instanceId: string;
|
|
28
|
+
readonly launcherId: string;
|
|
29
|
+
readonly launcherLabel: string;
|
|
30
|
+
readonly label?: string;
|
|
31
|
+
readonly detail?: string;
|
|
32
|
+
readonly state: 'starting' | 'running' | 'stopping';
|
|
33
|
+
readonly startedAt?: string;
|
|
34
|
+
}
|
|
35
|
+
interface LoopLauncherDefinition extends LoopLauncherSummary {
|
|
36
|
+
launch(request: LoopLaunchRequest): Promise<StoppableLoop | undefined>;
|
|
37
|
+
}
|
|
38
|
+
interface LoopLauncherRegistration {
|
|
39
|
+
readonly id: string;
|
|
40
|
+
readonly generation: string;
|
|
41
|
+
dispose(reason?: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/** Direct registrar/control seam owned and provided by doompi-loop. */
|
|
44
|
+
interface DoomLoopLaunchersService {
|
|
45
|
+
readonly generation: string;
|
|
46
|
+
register(definition: LoopLauncherDefinition): LoopLauncherRegistration;
|
|
47
|
+
listLaunchers(): readonly LoopLauncherSummary[];
|
|
48
|
+
listInstances(): readonly LoopInstanceSnapshot[];
|
|
49
|
+
subscribe(listener: () => void): () => void;
|
|
50
|
+
launch(launcherId: string, options?: {
|
|
51
|
+
instanceId?: string;
|
|
52
|
+
input?: Readonly<Record<string, unknown>>;
|
|
53
|
+
interactive?: boolean;
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
}): Promise<LoopInstanceSnapshot | undefined>;
|
|
56
|
+
stop(instanceId: string, reason?: string): Promise<boolean>;
|
|
57
|
+
stopAll(reason?: string): Promise<void>;
|
|
58
|
+
dispose(reason?: string): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
declare module '@deepseek-ai/cordis' {
|
|
61
|
+
interface Context {
|
|
62
|
+
'doom/loop-launchers': DoomLoopLaunchersService;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
declare function readDoomLoopLaunchers(context: Context): DoomLoopLaunchersService | undefined;
|
|
66
|
+
declare function requireDoomLoopLaunchers(context: Context): DoomLoopLaunchersService;
|
|
67
|
+
//#endregion
|
|
68
|
+
export { LoopLauncherDefinition as a, StoppableLoop as c, LoopLaunchRequest as i, readDoomLoopLaunchers as l, DoomLoopLaunchersService as n, LoopLauncherRegistration as o, LoopInstanceSnapshot as r, LoopLauncherSummary as s, DOOM_LOOP_LAUNCHERS_SERVICE as t, requireDoomLoopLaunchers as u };
|
|
69
|
+
//# sourceMappingURL=loopLaunchers-Bciapxt0.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopLaunchers-Bciapxt0.d.mts","names":[],"sources":["../src/schemas/loopLaunchers.ts"],"mappings":";;;cAGa;UAEI;WACN;WACA,QAAQ;WACR,QAAQ,SAAS;;WAEjB;;UAGM;WACN;WACA;WACA;EACT,KAAK,yBAAyB;;UAGf;WACN;WACA;WACA;WACA;;WAEA,cAAc,SAAS;;UAGjB;WACN;WACA;WACA;WACA;WACA;WACA;WACA;;UAGM,+BAA+B;EAC9C,OAAO,SAAS,oBAAoB,QAAQ;;UAG7B;WACN;WACA;EACT,QAAQ,kBAAkB;;;UAIX;WACN;EACT,SAAS,YAAY,yBAAyB;EAC9C,0BAA0B;EAC1B,0BAA0B;EAC1B,UAAU;EACV,OACE,oBACA;IACE;IACA,QAAQ,SAAS;IACjB;IACA,SAAS;MAEV,QAAQ;EACX,KAAK,oBAAoB,kBAAkB;EAC3C,QAAQ,kBAAkB;EAC1B,QAAQ,kBAAkB;;;YAIhB;IACR,uBAAuB;;;iBAIX,sBAAsB,SAAS,UAAU;iBAIzC,yBAAyB,SAAS,UAAU"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/schemas/loopLaunchers.ts
|
|
2
|
+
/** Provider-owned Cordis service for session-scoped recurring-loop launchers. */
|
|
3
|
+
const DOOM_LOOP_LAUNCHERS_SERVICE = "doom/loop-launchers";
|
|
4
|
+
function readDoomLoopLaunchers(context) {
|
|
5
|
+
return context.get(DOOM_LOOP_LAUNCHERS_SERVICE);
|
|
6
|
+
}
|
|
7
|
+
function requireDoomLoopLaunchers(context) {
|
|
8
|
+
const service = readDoomLoopLaunchers(context);
|
|
9
|
+
if (!service) throw new Error("Doom loop launchers are unavailable. Load @agimon-ai/doompi-loop.");
|
|
10
|
+
return service;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
Object.defineProperty(exports, "DOOM_LOOP_LAUNCHERS_SERVICE", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function() {
|
|
16
|
+
return DOOM_LOOP_LAUNCHERS_SERVICE;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "readDoomLoopLaunchers", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function() {
|
|
22
|
+
return readDoomLoopLaunchers;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "requireDoomLoopLaunchers", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function() {
|
|
28
|
+
return requireDoomLoopLaunchers;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=loopLaunchers-BtcLH_xN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopLaunchers-BtcLH_xN.cjs","names":[],"sources":["../src/schemas/loopLaunchers.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\n\n/** Provider-owned Cordis service for session-scoped recurring-loop launchers. */\nexport const DOOM_LOOP_LAUNCHERS_SERVICE = 'doom/loop-launchers';\n\nexport interface LoopLaunchRequest {\n readonly instanceId: string;\n readonly signal: AbortSignal;\n readonly input?: Readonly<Record<string, unknown>>;\n /** False for agent calls: a launcher must never open an operator dialog. */\n readonly interactive?: boolean;\n}\n\nexport interface StoppableLoop {\n readonly instanceId: string;\n readonly label?: string;\n readonly detail?: string;\n stop(reason?: string): void | Promise<void>;\n}\n\nexport interface LoopLauncherSummary {\n readonly id: string;\n readonly source: string;\n readonly label: string;\n readonly description?: string;\n /** JSON Schema for non-interactive launch configuration, validated by the launcher. */\n readonly inputSchema?: Readonly<Record<string, unknown>>;\n}\n\nexport interface LoopInstanceSnapshot {\n readonly instanceId: string;\n readonly launcherId: string;\n readonly launcherLabel: string;\n readonly label?: string;\n readonly detail?: string;\n readonly state: 'starting' | 'running' | 'stopping';\n readonly startedAt?: string;\n}\n\nexport interface LoopLauncherDefinition extends LoopLauncherSummary {\n launch(request: LoopLaunchRequest): Promise<StoppableLoop | undefined>;\n}\n\nexport interface LoopLauncherRegistration {\n readonly id: string;\n readonly generation: string;\n dispose(reason?: string): Promise<void>;\n}\n\n/** Direct registrar/control seam owned and provided by doompi-loop. */\nexport interface DoomLoopLaunchersService {\n readonly generation: string;\n register(definition: LoopLauncherDefinition): LoopLauncherRegistration;\n listLaunchers(): readonly LoopLauncherSummary[];\n listInstances(): readonly LoopInstanceSnapshot[];\n subscribe(listener: () => void): () => void;\n launch(\n launcherId: string,\n options?: {\n instanceId?: string;\n input?: Readonly<Record<string, unknown>>;\n interactive?: boolean;\n signal?: AbortSignal;\n },\n ): Promise<LoopInstanceSnapshot | undefined>;\n stop(instanceId: string, reason?: string): Promise<boolean>;\n stopAll(reason?: string): Promise<void>;\n dispose(reason?: string): Promise<void>;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'doom/loop-launchers': DoomLoopLaunchersService;\n }\n}\n\nexport function readDoomLoopLaunchers(context: Context): DoomLoopLaunchersService | undefined {\n return context.get(DOOM_LOOP_LAUNCHERS_SERVICE) as DoomLoopLaunchersService | undefined;\n}\n\nexport function requireDoomLoopLaunchers(context: Context): DoomLoopLaunchersService {\n const service = readDoomLoopLaunchers(context);\n if (!service) throw new Error('Doom loop launchers are unavailable. Load @agimon-ai/doompi-loop.');\n return service;\n}\n"],"mappings":";;AAGA,MAAa,8BAA8B;AAyE3C,SAAgB,sBAAsB,SAAwD;CAC5F,OAAO,QAAQ,IAAI,2BAA2B;AAChD;AAEA,SAAgB,yBAAyB,SAA4C;CACnF,MAAM,UAAU,sBAAsB,OAAO;CAC7C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,mEAAmE;CACjG,OAAO;AACT"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/schemas/loopLaunchers.ts
|
|
2
|
+
/** Provider-owned Cordis service for session-scoped recurring-loop launchers. */
|
|
3
|
+
const DOOM_LOOP_LAUNCHERS_SERVICE = "doom/loop-launchers";
|
|
4
|
+
function readDoomLoopLaunchers(context) {
|
|
5
|
+
return context.get(DOOM_LOOP_LAUNCHERS_SERVICE);
|
|
6
|
+
}
|
|
7
|
+
function requireDoomLoopLaunchers(context) {
|
|
8
|
+
const service = readDoomLoopLaunchers(context);
|
|
9
|
+
if (!service) throw new Error("Doom loop launchers are unavailable. Load @agimon-ai/doompi-loop.");
|
|
10
|
+
return service;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { readDoomLoopLaunchers as n, requireDoomLoopLaunchers as r, DOOM_LOOP_LAUNCHERS_SERVICE as t };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=loopLaunchers-cCniFbVA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopLaunchers-cCniFbVA.mjs","names":[],"sources":["../src/schemas/loopLaunchers.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\n\n/** Provider-owned Cordis service for session-scoped recurring-loop launchers. */\nexport const DOOM_LOOP_LAUNCHERS_SERVICE = 'doom/loop-launchers';\n\nexport interface LoopLaunchRequest {\n readonly instanceId: string;\n readonly signal: AbortSignal;\n readonly input?: Readonly<Record<string, unknown>>;\n /** False for agent calls: a launcher must never open an operator dialog. */\n readonly interactive?: boolean;\n}\n\nexport interface StoppableLoop {\n readonly instanceId: string;\n readonly label?: string;\n readonly detail?: string;\n stop(reason?: string): void | Promise<void>;\n}\n\nexport interface LoopLauncherSummary {\n readonly id: string;\n readonly source: string;\n readonly label: string;\n readonly description?: string;\n /** JSON Schema for non-interactive launch configuration, validated by the launcher. */\n readonly inputSchema?: Readonly<Record<string, unknown>>;\n}\n\nexport interface LoopInstanceSnapshot {\n readonly instanceId: string;\n readonly launcherId: string;\n readonly launcherLabel: string;\n readonly label?: string;\n readonly detail?: string;\n readonly state: 'starting' | 'running' | 'stopping';\n readonly startedAt?: string;\n}\n\nexport interface LoopLauncherDefinition extends LoopLauncherSummary {\n launch(request: LoopLaunchRequest): Promise<StoppableLoop | undefined>;\n}\n\nexport interface LoopLauncherRegistration {\n readonly id: string;\n readonly generation: string;\n dispose(reason?: string): Promise<void>;\n}\n\n/** Direct registrar/control seam owned and provided by doompi-loop. */\nexport interface DoomLoopLaunchersService {\n readonly generation: string;\n register(definition: LoopLauncherDefinition): LoopLauncherRegistration;\n listLaunchers(): readonly LoopLauncherSummary[];\n listInstances(): readonly LoopInstanceSnapshot[];\n subscribe(listener: () => void): () => void;\n launch(\n launcherId: string,\n options?: {\n instanceId?: string;\n input?: Readonly<Record<string, unknown>>;\n interactive?: boolean;\n signal?: AbortSignal;\n },\n ): Promise<LoopInstanceSnapshot | undefined>;\n stop(instanceId: string, reason?: string): Promise<boolean>;\n stopAll(reason?: string): Promise<void>;\n dispose(reason?: string): Promise<void>;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'doom/loop-launchers': DoomLoopLaunchersService;\n }\n}\n\nexport function readDoomLoopLaunchers(context: Context): DoomLoopLaunchersService | undefined {\n return context.get(DOOM_LOOP_LAUNCHERS_SERVICE) as DoomLoopLaunchersService | undefined;\n}\n\nexport function requireDoomLoopLaunchers(context: Context): DoomLoopLaunchersService {\n const service = readDoomLoopLaunchers(context);\n if (!service) throw new Error('Doom loop launchers are unavailable. Load @agimon-ai/doompi-loop.');\n return service;\n}\n"],"mappings":";;AAGA,MAAa,8BAA8B;AAyE3C,SAAgB,sBAAsB,SAAwD;CAC5F,OAAO,QAAQ,IAAI,2BAA2B;AAChD;AAEA,SAAgB,yBAAyB,SAA4C;CACnF,MAAM,UAAU,sBAAsB,OAAO;CAC7C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,mEAAmE;CACjG,OAAO;AACT"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_loopLaunchers = require("./loopLaunchers-BtcLH_xN.cjs");
|
|
3
|
+
exports.DOOM_LOOP_LAUNCHERS_SERVICE = require_loopLaunchers.DOOM_LOOP_LAUNCHERS_SERVICE;
|
|
4
|
+
exports.readDoomLoopLaunchers = require_loopLaunchers.readDoomLoopLaunchers;
|
|
5
|
+
exports.requireDoomLoopLaunchers = require_loopLaunchers.requireDoomLoopLaunchers;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as LoopLauncherDefinition, c as StoppableLoop, i as LoopLaunchRequest, l as readDoomLoopLaunchers, n as DoomLoopLaunchersService, o as LoopLauncherRegistration, r as LoopInstanceSnapshot, s as LoopLauncherSummary, t as DOOM_LOOP_LAUNCHERS_SERVICE, u as requireDoomLoopLaunchers } from "./loopLaunchers-Bciapxt0.mjs";
|
|
2
|
+
export { DOOM_LOOP_LAUNCHERS_SERVICE, type DoomLoopLaunchersService, type LoopInstanceSnapshot, type LoopLaunchRequest, type LoopLauncherDefinition, type LoopLauncherRegistration, type LoopLauncherSummary, type StoppableLoop, readDoomLoopLaunchers, requireDoomLoopLaunchers };
|