@agimon-ai/po-loop 0.0.0-alpha.1 → 0.0.0-alpha.2

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.
@@ -0,0 +1,163 @@
1
+ import { defineActivityGroup, defineFill, defineNativePlugin, defineSlotFile } from "@agimon-ai/po-core/native";
2
+ import { View } from "react-native-unistyles/components/native/View";
3
+ import { Text } from "react-native-unistyles/components/native/Text";
4
+ import { Button, Dot, ListRow, fontOf } from "@agimon-ai/po-native-components";
5
+ import { useState } from "react";
6
+ import { StyleSheet } from "react-native-unistyles";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/types/loopView.ts
9
+ /** The browser-only status that carries active Loop instances into the activity dock. */
10
+ const LOOP_VIEW_STATUS_KEY = "doom-loop-instances";
11
+ const ANSI = new RegExp(String.raw`\u001b\[[0-9;]*m`, "gu");
12
+ function isRecord(value) {
13
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14
+ }
15
+ function isState(value) {
16
+ return value === "starting" || value === "running" || value === "stopping";
17
+ }
18
+ /** Reads a Loop status without letting malformed session data crash the activity dock. */
19
+ function parseLoopStatusView(raw) {
20
+ if (raw === void 0) return void 0;
21
+ const text = raw.replace(ANSI, "").trim();
22
+ if (text === "") return void 0;
23
+ try {
24
+ const value = JSON.parse(text);
25
+ if (!Array.isArray(value) || value.length === 0) return void 0;
26
+ const items = [];
27
+ for (const item of value) {
28
+ 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;
29
+ items.push({
30
+ instanceId: item.instanceId,
31
+ label: item.label,
32
+ detail: item.detail,
33
+ state: item.state
34
+ });
35
+ }
36
+ return items;
37
+ } catch {
38
+ return;
39
+ }
40
+ }
41
+ //#endregion
42
+ //#region src/extensions/workspaces/sessions/(frontend)/activity-group/loops.native.ts
43
+ var loops_native_default = defineActivityGroup({
44
+ keys: "l l",
45
+ statusKey: LOOP_VIEW_STATUS_KEY,
46
+ order: 40
47
+ });
48
+ //#endregion
49
+ //#region src/extensions/workspaces/sessions/(frontend)/fill/_components/LoopsActivitySection.native.tsx
50
+ /** Recurring prompts remain stoppable even after the mode is turned off. */
51
+ function LoopActivityItems({ statuses, sessionId, sendSessionFrame }) {
52
+ const [error, setError] = useState();
53
+ const raw = statuses[LOOP_VIEW_STATUS_KEY];
54
+ const loops = parseLoopStatusView(raw);
55
+ if (!loops) return raw?.trim() ? /* @__PURE__ */ jsx(Text, {
56
+ style: styles.meta,
57
+ children: "loop status unavailable"
58
+ }) : null;
59
+ return /* @__PURE__ */ jsxs(View, { children: [error ? /* @__PURE__ */ jsx(Text, {
60
+ style: styles.error,
61
+ children: error
62
+ }) : null, loops.map((loop) => /* @__PURE__ */ jsx(ListRow, {
63
+ leading: /* @__PURE__ */ jsx(Dot, { tone: loop.state === "running" ? "green" : loop.state === "stopping" ? "orange" : "yellow" }),
64
+ title: loop.label,
65
+ description: loop.detail,
66
+ trailing: /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(Text, {
67
+ style: styles.meta,
68
+ children: loop.state
69
+ }), /* @__PURE__ */ jsx(Button, {
70
+ variant: "ghost",
71
+ accessibilityLabel: `stop ${loop.label}`,
72
+ disabled: sessionId === null || loop.state === "stopping",
73
+ onPress: () => {
74
+ if (sessionId === null) return;
75
+ try {
76
+ sendSessionFrame(sessionId, {
77
+ type: "prompt",
78
+ message: `/loops stop ${loop.instanceId}`
79
+ });
80
+ setError(void 0);
81
+ } catch (failure) {
82
+ setError(failure instanceof Error ? failure.message : String(failure));
83
+ }
84
+ },
85
+ children: "stop"
86
+ })] })
87
+ }, loop.instanceId))] });
88
+ }
89
+ function LoopsActivitySection({ statuses, activeMinorModes, renderSlot }) {
90
+ const hint = !activeMinorModes?.includes("loop") ? "Activate loop minor mode to set loop or cron job." : parseLoopStatusView(statuses["doom-loop-instances"]) === void 0 ? "No loops yet. Ask the agent to set a loop or cron job." : void 0;
91
+ return /* @__PURE__ */ jsxs(View, {
92
+ testID: "activity-loop-instances",
93
+ style: styles.section,
94
+ children: [
95
+ renderSlot("loop.registration"),
96
+ renderSlot("loop.items"),
97
+ hint ? /* @__PURE__ */ jsx(Text, {
98
+ style: styles.meta,
99
+ children: hint
100
+ }) : null
101
+ ]
102
+ });
103
+ }
104
+ const styles = StyleSheet.create((theme) => ({
105
+ section: {
106
+ gap: theme.spacing(2),
107
+ uni__dependencies: [0]
108
+ },
109
+ error: {
110
+ fontSize: theme.fontSize.sm,
111
+ color: theme.colors.red,
112
+ uni__dependencies: [0]
113
+ },
114
+ meta: {
115
+ fontFamily: fontOf(theme.fontFamily.sans),
116
+ fontSize: theme.fontSize.sm,
117
+ lineHeight: theme.lineHeight.sm,
118
+ color: theme.colors.dim,
119
+ uni__dependencies: [0]
120
+ }
121
+ }));
122
+ //#endregion
123
+ //#region src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.native.tsx
124
+ var Instances_loop_items_native_default = defineFill({ component: LoopActivityItems });
125
+ //#endregion
126
+ //#region src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.native.tsx
127
+ var Loops_activity_loops_native_default = defineFill({ component: LoopsActivitySection });
128
+ //#endregion
129
+ //#region src/extensions/workspaces/sessions/(frontend)/slot/items.native.ts
130
+ var items_native_default = defineSlotFile({});
131
+ //#endregion
132
+ //#region src/extensions/workspaces/sessions/(frontend)/slot/registration.native.ts
133
+ var registration_native_default = defineSlotFile({});
134
+ //#endregion
135
+ //#region generated/native.ts
136
+ const via = (identity, value) => value === void 0 ? void 0 : {
137
+ ...identity,
138
+ ...value
139
+ };
140
+ const nativePlugin = defineNativePlugin({
141
+ id: "loop",
142
+ session: {
143
+ get activityGroups() {
144
+ return [via({ name: "loops" }, loops_native_default)];
145
+ },
146
+ get fills() {
147
+ return [via({
148
+ slot: "loop.items",
149
+ id: "instances"
150
+ }, Instances_loop_items_native_default), via({
151
+ slot: "activity.loops",
152
+ id: "loops"
153
+ }, Loops_activity_loops_native_default)];
154
+ },
155
+ get slots() {
156
+ return [via({ slot: "loop.items" }, items_native_default), via({ slot: "loop.registration" }, registration_native_default)];
157
+ }
158
+ }
159
+ });
160
+ //#endregion
161
+ export { nativePlugin };
162
+
163
+ //# sourceMappingURL=native.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.mjs","names":["WebPluginSlotProps","Button","Dot","ListRow","fontOf","PoNativeTheme","useState","StyleSheet","LOOP_VIEW_STATUS_KEY","parseLoopStatusView","LoopActivityItems","statuses","sessionId","sendSessionFrame","error","setError","raw","loops","trim","styles","meta","map","loop","instanceId","state","label","detail","type","message","undefined","failure","Error","String","LoopsActivitySection","activeMinorModes","renderSlot","hint","includes","section","create","theme","gap","spacing","uni__dependencies","fontSize","sm","color","colors","red","fontFamily","sans","lineHeight","dim","activityGroupLoops","fillInstances","fillLoops","slotItems","slotRegistration"],"sources":["../../src/types/loopView.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/loops.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/LoopsActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/slot/items.native.ts","../../src/extensions/workspaces/sessions/(frontend)/slot/registration.native.ts","../../generated/native.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/po-core/native';\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/po-core/native';\nimport { Button, Dot, ListRow, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useState } from 'react';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { LOOP_VIEW_STATUS_KEY, parseLoopStatusView } from '../../../../../../types/loopView';\n\n/** Recurring prompts remain stoppable even after the mode is turned off. */\nexport function LoopActivityItems({ statuses, sessionId, sendSessionFrame }: WebPluginSlotProps) {\n const [error, setError] = useState<string>();\n const raw = statuses[LOOP_VIEW_STATUS_KEY];\n const loops = parseLoopStatusView(raw);\n if (!loops) return raw?.trim() ? <Text style={styles.meta}>loop status unavailable</Text> : null;\n return (\n <View>\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {loops.map((loop) => (\n <ListRow\n key={loop.instanceId}\n leading={<Dot tone={loop.state === 'running' ? 'green' : loop.state === 'stopping' ? 'orange' : 'yellow'} />}\n title={loop.label}\n description={loop.detail}\n trailing={\n <View>\n <Text style={styles.meta}>{loop.state}</Text>\n <Button\n variant=\"ghost\"\n accessibilityLabel={`stop ${loop.label}`}\n disabled={sessionId === null || loop.state === 'stopping'}\n onPress={() => {\n if (sessionId === null) return;\n try {\n sendSessionFrame(sessionId, { type: 'prompt', message: `/loops stop ${loop.instanceId}` });\n setError(undefined);\n } catch (failure) {\n setError(failure instanceof Error ? failure.message : String(failure));\n }\n }}\n >\n stop\n </Button>\n </View>\n }\n />\n ))}\n </View>\n );\n}\n\nexport function LoopsActivitySection({ statuses, activeMinorModes, renderSlot }: WebPluginSlotProps) {\n const hint = !activeMinorModes?.includes('loop')\n ? 'Activate loop minor mode to set loop or cron job.'\n : parseLoopStatusView(statuses[LOOP_VIEW_STATUS_KEY]) === undefined\n ? 'No loops yet. Ask the agent to set a loop or cron job.'\n : undefined;\n return (\n <View testID=\"activity-loop-instances\" style={styles.section}>\n {renderSlot('loop.registration')}\n {renderSlot('loop.items')}\n {hint ? <Text style={styles.meta}>{hint}</Text> : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n section: { gap: theme.spacing(2) },\n error: { fontSize: theme.fontSize.sm, color: theme.colors.red },\n meta: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { LoopActivityItems } from './_components/LoopsActivitySection.native';\n\nexport default defineFill({ component: LoopActivityItems });\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { LoopsActivitySection } from './_components/LoopsActivitySection.native';\n\nexport default defineFill({ component: LoopsActivitySection });\n","import { defineSlotFile } from '@agimon-ai/po-core/native';\n\nexport default defineSlotFile({});\n","import { defineSlotFile } from '@agimon-ai/po-core/native';\n\nexport default defineSlotFile({});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport activityGroupLoops from '../src/extensions/workspaces/sessions/(frontend)/activity-group/loops.native';\nimport fillInstances from '../src/extensions/workspaces/sessions/(frontend)/fill/Instances.loop.items.native';\nimport fillLoops from '../src/extensions/workspaces/sessions/(frontend)/fill/Loops.activity.loops.native';\nimport slotItems from '../src/extensions/workspaces/sessions/(frontend)/slot/items.native';\nimport slotRegistration from '../src/extensions/workspaces/sessions/(frontend)/slot/registration.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\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 slots(): WebPluginContributions['slots'] { return [via({ slot: 'loop.items' }, slotItems), via({ slot: 'loop.registration' }, slotRegistration)]; },\n },\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-loop",
3
- "version": "0.0.0-alpha.1",
3
+ "version": "0.0.0-alpha.2",
4
4
  "description": "Session-scoped recurring prompt scheduler and loop controls for Pi coding agents.",
5
5
  "keywords": [
6
6
  "ai",
@@ -45,6 +45,9 @@
45
45
  "import": "./dist/index.mjs",
46
46
  "require": "./dist/index.cjs"
47
47
  },
48
+ "./extensions/native": {
49
+ "import": "./dist/extensions/native.mjs"
50
+ },
48
51
  "./extensions/server": {
49
52
  "types": "./dist/extensions/server.d.mts",
50
53
  "import": "./dist/extensions/server.mjs",
@@ -64,38 +67,61 @@
64
67
  "access": "public"
65
68
  },
66
69
  "dependencies": {
67
- "@agimon-ai/po-core": "0.0.0-alpha.1",
68
- "@agimon-ai/po-minor-mode": "0.0.0-alpha.1",
69
- "@agimon-ai/po-ui": "0.0.0-alpha.1",
70
- "@agimon-ai/po-web-components": "0.0.0-alpha.1",
70
+ "@agimon-ai/po-core": "0.0.0-alpha.2",
71
+ "@agimon-ai/po-minor-mode": "0.0.0-alpha.2",
72
+ "@agimon-ai/po-ui": "0.0.0-alpha.2",
73
+ "@agimon-ai/po-web-components": "0.0.0-alpha.2",
71
74
  "@deepseek-ai/cordis": "4.0.4",
72
75
  "croner": "10.0.1",
73
76
  "typebox": "1.3.34"
74
77
  },
75
78
  "devDependencies": {
76
- "@agimon-ai/po-build": "0.0.0-alpha.1",
77
- "@earendil-works/pi-coding-agent": "1.0.2",
79
+ "@agimon-ai/po-build": "0.0.0-alpha.2",
80
+ "@agimon-ai/po-native-components": "0.0.0-alpha.2",
81
+ "@earendil-works/pi-coding-agent": "1.2.0",
78
82
  "@types/node": "26.6.4",
79
83
  "@types/react": "19.3.0",
80
84
  "@types/react-dom": "19.3.0",
81
85
  "@vitest/coverage-v8": "5.0.3",
82
86
  "react": "19.3.0",
83
87
  "react-dom": "19.3.0",
88
+ "react-native": "0.86.3",
89
+ "react-native-unistyles": "3.5.2",
84
90
  "tsdown": "0.23.0",
85
91
  "typescript": "7.0.2",
86
92
  "vitest": "5.0.3"
87
93
  },
88
94
  "peerDependencies": {
89
- "@earendil-works/pi-coding-agent": "1.0.2"
95
+ "@agimon-ai/po-native-components": "0.0.0-alpha.2",
96
+ "@earendil-works/pi-coding-agent": "1.2.0",
97
+ "react-native": "0.86.3",
98
+ "react-native-unistyles": "3.5.2"
90
99
  },
91
100
  "peerDependenciesMeta": {
92
101
  "@earendil-works/pi-coding-agent": {
93
102
  "optional": true
103
+ },
104
+ "@agimon-ai/po-native-components": {
105
+ "optional": true
106
+ },
107
+ "react-native": {
108
+ "optional": true
109
+ },
110
+ "react-native-unistyles": {
111
+ "optional": true
94
112
  }
95
113
  },
96
114
  "engines": {
97
115
  "node": ">=24"
98
116
  },
117
+ "poNative": {
118
+ "pluginId": "loop",
119
+ "channels": [],
120
+ "client": "./dist/extensions/native.mjs",
121
+ "scopes": [
122
+ "session"
123
+ ]
124
+ },
99
125
  "poServer": {
100
126
  "entry": "./generated/server.ts",
101
127
  "dist": "./dist/extensions/server.mjs",
@@ -118,7 +144,7 @@
118
144
  "scripts": {
119
145
  "build": "tsdown",
120
146
  "test": "vitest --run",
121
- "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
147
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json && tsc --noEmit -p tsconfig.native.json",
122
148
  "lint": "oxlint . && oxfmt . --check",
123
149
  "fixcode": "oxlint . --fix && oxfmt ."
124
150
  }