@agimon-ai/doompi-loop 0.0.1-alpha.69 → 0.0.1-alpha.70
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-loop",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.70",
|
|
4
4
|
"description": "Session-scoped recurring prompt scheduler and loop controls for Pi coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@deepseek-ai/cordis": "4.0.2",
|
|
62
|
-
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.
|
|
63
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
64
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
65
|
-
"@agimon-ai/doompi-web-contracts": "0.0.1-alpha.
|
|
62
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.68",
|
|
63
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.69",
|
|
64
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.28",
|
|
65
|
+
"@agimon-ai/doompi-web-contracts": "0.0.1-alpha.31"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
@@ -3,6 +3,30 @@ import type { WebPluginSlotProps } from '@agimon-ai/doompi-web-contracts';
|
|
|
3
3
|
import { LOOP_VIEW_STATUS_KEY, parseLoopStatusView, type LoopStatusState } from '../../types/loopView.ts';
|
|
4
4
|
|
|
5
5
|
const MANAGE_COMMAND = '/loops';
|
|
6
|
+
const DEFAULT_LOOP_COMMAND = '/loop doompi.default';
|
|
7
|
+
|
|
8
|
+
/** Starts the built-in prompt loop without opening a generic launcher chooser. */
|
|
9
|
+
export function DefaultLoopLauncher({
|
|
10
|
+
sessionId,
|
|
11
|
+
sendSessionFrame,
|
|
12
|
+
}: Pick<WebPluginSlotProps, 'sessionId' | 'sendSessionFrame'>) {
|
|
13
|
+
return (
|
|
14
|
+
<Button
|
|
15
|
+
variant="subtle"
|
|
16
|
+
size="xs"
|
|
17
|
+
data-testid="activity-loop-default-launch"
|
|
18
|
+
aria-label="launch default loop"
|
|
19
|
+
disabled={sessionId === null}
|
|
20
|
+
onClick={() => {
|
|
21
|
+
if (sessionId === null) return;
|
|
22
|
+
sendSessionFrame(sessionId, { type: 'prompt', message: DEFAULT_LOOP_COMMAND });
|
|
23
|
+
}}
|
|
24
|
+
className="text-2xs font-bold"
|
|
25
|
+
>
|
|
26
|
+
default loop
|
|
27
|
+
</Button>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
6
30
|
|
|
7
31
|
function toneOf(state: LoopStatusState): DotTone {
|
|
8
32
|
if (state === 'running') return 'green';
|
|
@@ -11,7 +35,7 @@ function toneOf(state: LoopStatusState): DotTone {
|
|
|
11
35
|
}
|
|
12
36
|
|
|
13
37
|
/** Renders active recurring prompts contributed to the Loop activity section. */
|
|
14
|
-
export function LoopActivityItems({ statuses }: WebPluginSlotProps) {
|
|
38
|
+
export function LoopActivityItems({ statuses }: Pick<WebPluginSlotProps, 'statuses'>) {
|
|
15
39
|
const raw = statuses[LOOP_VIEW_STATUS_KEY];
|
|
16
40
|
const loops = parseLoopStatusView(raw);
|
|
17
41
|
const unavailable = raw !== undefined && raw.trim() !== '' && loops === undefined;
|
|
@@ -45,7 +69,10 @@ export function LoopActivityItems({ statuses }: WebPluginSlotProps) {
|
|
|
45
69
|
export function LoopsActivitySection({ sessionId, renderSlot, sendSessionFrame }: WebPluginSlotProps) {
|
|
46
70
|
return (
|
|
47
71
|
<div data-testid="activity-loop-instances" className="flex flex-col gap-2">
|
|
48
|
-
|
|
72
|
+
<div className="flex flex-wrap items-center gap-1">
|
|
73
|
+
<DefaultLoopLauncher sessionId={sessionId} sendSessionFrame={sendSessionFrame} />
|
|
74
|
+
{renderSlot('loop.registration')}
|
|
75
|
+
</div>
|
|
49
76
|
{renderSlot('loop.items')}
|
|
50
77
|
<Button
|
|
51
78
|
variant="subtle"
|
package/src/web/index.ts
CHANGED
|
@@ -7,11 +7,18 @@ import { LoopActivityItems, LoopsActivitySection } from './components/LoopsActiv
|
|
|
7
7
|
* while the activity dock shows each loop the active session is scheduling.
|
|
8
8
|
*/
|
|
9
9
|
const LOOPS_GROUP = { key: 'l', label: 'loops', detail: 'recurring prompt loops' };
|
|
10
|
+
const LOOPS_ACTIVITY_SOURCE = {
|
|
11
|
+
subscribe: () => () => undefined,
|
|
12
|
+
// Keeping the scheduler's launcher visible does not mean a result is pending.
|
|
13
|
+
isActive: (_sessionId: string | null) => false,
|
|
14
|
+
};
|
|
10
15
|
|
|
11
16
|
export const webPlugin = defineWebPlugin({
|
|
12
17
|
id: 'loop',
|
|
13
|
-
minorModes: [{ name: 'loop', keys: 'l l', statusKey: 'doom-loop', order: 30 }],
|
|
14
|
-
activityGroups: [
|
|
18
|
+
minorModes: [{ name: 'loop', keys: 'l l', statusKey: 'doom-loop', activityGroup: 'loops', order: 30 }],
|
|
19
|
+
activityGroups: [
|
|
20
|
+
{ name: 'loops', keys: 'l l', statusKey: LOOP_VIEW_STATUS_KEY, activeSource: LOOPS_ACTIVITY_SOURCE, order: 40 },
|
|
21
|
+
],
|
|
15
22
|
activitySections: [{ id: 'loops', component: LoopsActivitySection }],
|
|
16
23
|
slots: [defineSlot({ slot: 'loop.registration' }), defineSlot({ slot: 'loop.items' })],
|
|
17
24
|
fills: [{ slot: 'loop.items', id: 'instances', component: LoopActivityItems }],
|