@agimon-ai/po-ui 0.0.0-alpha.0

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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/apiContracts.cjs +17 -0
  4. package/dist/apiContracts.cjs.map +1 -0
  5. package/dist/apiContracts.d.mts +53 -0
  6. package/dist/apiContracts.d.mts.map +1 -0
  7. package/dist/apiContracts.mjs +13 -0
  8. package/dist/apiContracts.mjs.map +1 -0
  9. package/dist/config.cjs +62 -0
  10. package/dist/config.d.mts +2 -0
  11. package/dist/config.mjs +2 -0
  12. package/dist/extensionName.cjs +59 -0
  13. package/dist/extensionName.cjs.map +1 -0
  14. package/dist/extensionName.d.mts +14 -0
  15. package/dist/extensionName.d.mts.map +1 -0
  16. package/dist/extensionName.mjs +54 -0
  17. package/dist/extensionName.mjs.map +1 -0
  18. package/dist/extensions/mcp-ui.mjs +46 -0
  19. package/dist/extensions/mcp-ui.mjs.map +1 -0
  20. package/dist/extensions/mcp.cjs +79 -0
  21. package/dist/extensions/mcp.cjs.map +1 -0
  22. package/dist/extensions/mcp.d.mts +5 -0
  23. package/dist/extensions/mcp.d.mts.map +1 -0
  24. package/dist/extensions/mcp.mjs +74 -0
  25. package/dist/extensions/mcp.mjs.map +1 -0
  26. package/dist/extensions/server.cjs +137 -0
  27. package/dist/extensions/server.cjs.map +1 -0
  28. package/dist/extensions/server.d.mts +5 -0
  29. package/dist/extensions/server.d.mts.map +1 -0
  30. package/dist/extensions/server.mjs +132 -0
  31. package/dist/extensions/server.mjs.map +1 -0
  32. package/dist/extensions/web.mjs +332 -0
  33. package/dist/extensions/web.mjs.map +1 -0
  34. package/dist/footer.cjs +26 -0
  35. package/dist/footer.d.mts +2 -0
  36. package/dist/footer.mjs +2 -0
  37. package/dist/harnessMetadata-CzsdGAxL.d.mts +21 -0
  38. package/dist/harnessMetadata-CzsdGAxL.d.mts.map +1 -0
  39. package/dist/harnessMetadata-DkMSJutN.mjs +25 -0
  40. package/dist/harnessMetadata-DkMSJutN.mjs.map +1 -0
  41. package/dist/harnessMetadata-Dw9Rb1nW.cjs +30 -0
  42. package/dist/harnessMetadata-Dw9Rb1nW.cjs.map +1 -0
  43. package/dist/harnessMetadata.cjs +3 -0
  44. package/dist/harnessMetadata.d.mts +2 -0
  45. package/dist/harnessMetadata.mjs +2 -0
  46. package/dist/index-Bx49wmE7.d.mts +30 -0
  47. package/dist/index-Bx49wmE7.d.mts.map +1 -0
  48. package/dist/index-Dpzvl-vg.d.mts +103 -0
  49. package/dist/index-Dpzvl-vg.d.mts.map +1 -0
  50. package/dist/index.cjs +12 -0
  51. package/dist/index.d.mts +8 -0
  52. package/dist/index.mjs +5 -0
  53. package/dist/leader.cjs +0 -0
  54. package/dist/leader.d.mts +2 -0
  55. package/dist/leader.mjs +1 -0
  56. package/dist/leaderRegistry.cjs +515 -0
  57. package/dist/leaderRegistry.cjs.map +1 -0
  58. package/dist/leaderRegistry.d.mts +59 -0
  59. package/dist/leaderRegistry.d.mts.map +1 -0
  60. package/dist/leaderRegistry.mjs +514 -0
  61. package/dist/leaderRegistry.mjs.map +1 -0
  62. package/dist/logSinkTelemetry.cjs +4 -0
  63. package/dist/logSinkTelemetry.d.mts +2 -0
  64. package/dist/logSinkTelemetry.mjs +2 -0
  65. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  66. package/dist/skills.cjs +38 -0
  67. package/dist/skills.d.mts +2 -0
  68. package/dist/skills.mjs +2 -0
  69. package/dist/telemetry--EgKB9ei.mjs +36 -0
  70. package/dist/telemetry--EgKB9ei.mjs.map +1 -0
  71. package/dist/telemetry-DMR6cIT1.cjs +47 -0
  72. package/dist/telemetry-DMR6cIT1.cjs.map +1 -0
  73. package/dist/theme-2wveit5V.cjs +166 -0
  74. package/dist/theme-2wveit5V.cjs.map +1 -0
  75. package/dist/theme-Byj_dBlT.mjs +134 -0
  76. package/dist/theme-Byj_dBlT.mjs.map +1 -0
  77. package/dist/theme.cjs +7 -0
  78. package/dist/theme.d.mts +2 -0
  79. package/dist/theme.mjs +2 -0
  80. package/dist/toolInventory.cjs +20 -0
  81. package/dist/toolInventory.d.mts +2 -0
  82. package/dist/toolInventory.mjs +2 -0
  83. package/dist/uiState-Binu4nUb.d.mts +40 -0
  84. package/dist/uiState-Binu4nUb.d.mts.map +1 -0
  85. package/dist/uiState-G_Pso-5i.mjs +57 -0
  86. package/dist/uiState-G_Pso-5i.mjs.map +1 -0
  87. package/dist/uiState-rUwgKslb.cjs +68 -0
  88. package/dist/uiState-rUwgKslb.cjs.map +1 -0
  89. package/dist/uiState.cjs +4 -0
  90. package/dist/uiState.d.mts +2 -0
  91. package/dist/uiState.mjs +2 -0
  92. package/package.json +196 -0
  93. package/themes/po-dark.json +88 -0
@@ -0,0 +1,332 @@
1
+ import { defineToolRenderer, defineWebPlugin } from "@agimon-ai/po-core/web";
2
+ import { MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, SyntaxLine, ToolPathLink, toolTone, useSyntaxLines } from "@agimon-ai/po-web-components";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ /** Pi's default output cap, the size its truncation warning names when details omit one. */
5
+ const DEFAULT_MAX_BYTES = 51200;
6
+ const KIBIBYTE = 1024;
7
+ function compactDetails(values) {
8
+ return values.filter((value) => value !== void 0 && value.length > 0);
9
+ }
10
+ function optionalCount(value, unit) {
11
+ return typeof value === "number" && Number.isFinite(value) ? `${value} ${unit}` : void 0;
12
+ }
13
+ function pathOrDot(value) {
14
+ return typeof value === "string" && value.length > 0 ? value : ".";
15
+ }
16
+ /** Pi's size formatter, so the web warning names the same figure the TUI does. */
17
+ function formatSize(bytes) {
18
+ if (bytes < KIBIBYTE) return `${bytes}B`;
19
+ if (bytes < KIBIBYTE * KIBIBYTE) return `${(bytes / KIBIBYTE).toFixed(1)}KB`;
20
+ return `${(bytes / (KIBIBYTE * KIBIBYTE)).toFixed(1)}MB`;
21
+ }
22
+ /** What the write call shows: the path, the content size, and a numbered preview of the file. */
23
+ function writeCallView(args, expanded) {
24
+ const content = typeof args.content === "string" ? args.content : "";
25
+ const path = typeof args.path === "string" ? args.path : "";
26
+ const size = `${content.length.toLocaleString("en-US")} chars`;
27
+ if (content.length === 0) return {
28
+ path,
29
+ size,
30
+ preview: [],
31
+ hidden: 0,
32
+ gutter: 1
33
+ };
34
+ const lines = content.replaceAll(" ", " ").replaceAll("\r\n", "\n").split("\n");
35
+ while (lines.at(-1) === "") lines.pop();
36
+ const visible = expanded ? lines : lines.slice(0, 10);
37
+ return {
38
+ path,
39
+ size,
40
+ preview: visible.map((text, index) => ({
41
+ number: index + 1,
42
+ text
43
+ })),
44
+ hidden: lines.length - visible.length,
45
+ gutter: String(visible.length).length
46
+ };
47
+ }
48
+ /** `pattern · path · N results`, as the find call heading lists them. */
49
+ function findCallView(args) {
50
+ return {
51
+ primary: typeof args.pattern === "string" ? args.pattern : "",
52
+ details: compactDetails([pathOrDot(args.path), optionalCount(args.limit, "results")])
53
+ };
54
+ }
55
+ /** `path · N entries`, as the ls call heading lists them. */
56
+ function lsCallView(args) {
57
+ return {
58
+ primary: pathOrDot(args.path),
59
+ details: compactDetails([optionalCount(args.limit, "entries")])
60
+ };
61
+ }
62
+ /** The result's text, from its blocks when the view exists and from the joined output otherwise. */
63
+ function resultText(result, output) {
64
+ if (result === null) return output;
65
+ return result.content.flatMap((block) => {
66
+ const record = typeof block === "object" && block !== null ? block : {};
67
+ return record.type === "text" && typeof record.text === "string" ? [record.text] : [];
68
+ }).join("\n");
69
+ }
70
+ /**
71
+ * A find or ls listing the way Pi's own renderer shows it: the lines,
72
+ * collapsed to twenty, and the limit warning its details carry. `limitKey`
73
+ * names the per-tool counter (resultLimitReached, entryLimitReached).
74
+ */
75
+ function listResultView(result, output, expanded, limitKey, limitUnit) {
76
+ const text = resultText(result, output).trim();
77
+ const all = text.length === 0 ? [] : text.split("\n");
78
+ const lines = expanded ? all : all.slice(0, 20);
79
+ const details = typeof result?.details === "object" && result.details !== null ? result.details : {};
80
+ const limit = details[limitKey];
81
+ const truncation = typeof details.truncation === "object" && details.truncation !== null ? details.truncation : void 0;
82
+ const warnings = [];
83
+ if (typeof limit === "number" && limit > 0) warnings.push(`${limit} ${limitUnit} limit`);
84
+ if (truncation?.truncated === true) warnings.push(`${formatSize(typeof truncation.maxBytes === "number" ? truncation.maxBytes : DEFAULT_MAX_BYTES)} limit`);
85
+ return {
86
+ lines,
87
+ hidden: all.length - lines.length,
88
+ truncated: warnings.length > 0 ? `[Truncated: ${warnings.join(", ")}]` : void 0
89
+ };
90
+ }
91
+ //#endregion
92
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ListingBody.tsx
93
+ /**
94
+ * The body shared by find and ls: Pi's listing lines, collapsed to twenty
95
+ * until the item expands, with the limit warning its details carry.
96
+ */
97
+ function ListingBody({ tool, limitKey, limitUnit, expanded, props }) {
98
+ const { result, output, running, isError } = props;
99
+ if (isError) return /* @__PURE__ */ jsxs(MessageItemBody, {
100
+ "data-testid": `tool-result-${tool}`,
101
+ className: "flex flex-col",
102
+ children: [/* @__PURE__ */ jsx(MessageItemStatus, {
103
+ tone: "error",
104
+ children: "failed"
105
+ }), /* @__PURE__ */ jsx("span", {
106
+ className: "whitespace-pre-wrap break-words text-doom-red",
107
+ children: resultText(result, output)
108
+ })]
109
+ });
110
+ if (result === null) return running ? /* @__PURE__ */ jsx(MessageItemBody, {
111
+ "data-testid": `tool-result-${tool}`,
112
+ children: /* @__PURE__ */ jsx(MessageItemStatus, {
113
+ tone: "running",
114
+ children: "running"
115
+ })
116
+ }) : null;
117
+ const view = listResultView(result, output, expanded, limitKey, limitUnit);
118
+ if (view.lines.length === 0 && view.truncated === void 0) return null;
119
+ return /* @__PURE__ */ jsxs(MessageItemBody, {
120
+ "data-testid": `tool-result-${tool}`,
121
+ className: "flex flex-col font-mono",
122
+ children: [
123
+ view.lines.map((line, index) => /* @__PURE__ */ jsx("span", {
124
+ className: "whitespace-pre-wrap break-words text-doom-text",
125
+ children: line
126
+ }, `${String(index)}-${line}`)),
127
+ view.hidden > 0 ? /* @__PURE__ */ jsxs(MessageItemStatus, {
128
+ expands: true,
129
+ children: [view.hidden, " more lines"]
130
+ }) : null,
131
+ view.truncated !== void 0 ? /* @__PURE__ */ jsx("span", {
132
+ className: "text-doom-yellow",
133
+ children: view.truncated
134
+ }) : null
135
+ ]
136
+ });
137
+ }
138
+ /** Whether the listing hides lines while collapsed, so the item can offer its toggle. */
139
+ function listingExpandable(props, limitKey, limitUnit) {
140
+ if (props.result === null || props.isError) return false;
141
+ return listResultView(props.result, props.output, false, limitKey, limitUnit).hidden > 0;
142
+ }
143
+ //#endregion
144
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/FindToolMessage.tsx
145
+ const LIMIT_KEY$1 = "resultLimitReached";
146
+ const LIMIT_UNIT$1 = "results";
147
+ /** The find tool's timeline item: `pattern · path · N results` over Pi's listing lines. */
148
+ function FindToolMessage(props) {
149
+ const view = findCallView(props.args);
150
+ return /* @__PURE__ */ jsx(MessageItem, {
151
+ tone: toolTone({
152
+ running: props.running,
153
+ isError: props.isError
154
+ }),
155
+ expandable: listingExpandable(props, LIMIT_KEY$1, LIMIT_UNIT$1),
156
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
157
+ title: "find",
158
+ children: /* @__PURE__ */ jsxs("span", {
159
+ "data-testid": "tool-call-find",
160
+ className: "flex min-w-0 flex-1 items-center gap-2",
161
+ children: [/* @__PURE__ */ jsx("span", {
162
+ className: "truncate text-doom-text",
163
+ children: view.primary
164
+ }), view.details.length > 0 ? /* @__PURE__ */ jsxs("span", {
165
+ className: "shrink-0 text-doom-faint",
166
+ children: ["· ", view.details.join(" · ")]
167
+ }) : null]
168
+ })
169
+ }), /* @__PURE__ */ jsx(ListingBody, {
170
+ tool: "find",
171
+ limitKey: LIMIT_KEY$1,
172
+ limitUnit: LIMIT_UNIT$1,
173
+ expanded,
174
+ props
175
+ })] })
176
+ });
177
+ }
178
+ //#endregion
179
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/find.web.tsx
180
+ var find_web_default = defineToolRenderer({ message: FindToolMessage });
181
+ //#endregion
182
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/LsToolMessage.tsx
183
+ const LIMIT_KEY = "entryLimitReached";
184
+ const LIMIT_UNIT = "entries";
185
+ /** The ls tool's timeline item: `path · N entries` over Pi's listing lines. */
186
+ function LsToolMessage(props) {
187
+ const view = lsCallView(props.args);
188
+ return /* @__PURE__ */ jsx(MessageItem, {
189
+ tone: toolTone({
190
+ running: props.running,
191
+ isError: props.isError
192
+ }),
193
+ expandable: listingExpandable(props, LIMIT_KEY, LIMIT_UNIT),
194
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
195
+ title: "ls",
196
+ children: /* @__PURE__ */ jsxs("span", {
197
+ "data-testid": "tool-call-ls",
198
+ className: "flex min-w-0 flex-1 items-center gap-2",
199
+ children: [/* @__PURE__ */ jsx("span", {
200
+ className: "truncate text-doom-text",
201
+ children: view.primary
202
+ }), view.details.length > 0 ? /* @__PURE__ */ jsxs("span", {
203
+ className: "shrink-0 text-doom-faint",
204
+ children: ["· ", view.details.join(" · ")]
205
+ }) : null]
206
+ })
207
+ }), /* @__PURE__ */ jsx(ListingBody, {
208
+ tool: "ls",
209
+ limitKey: LIMIT_KEY,
210
+ limitUnit: LIMIT_UNIT,
211
+ expanded,
212
+ props
213
+ })] })
214
+ });
215
+ }
216
+ //#endregion
217
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/ls.web.tsx
218
+ var ls_web_default = defineToolRenderer({ message: LsToolMessage });
219
+ //#endregion
220
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/WriteToolMessage.tsx
221
+ /**
222
+ * The numbered preview, coloured as the file it is about to become.
223
+ *
224
+ * Its own component so the highlighting hook has somewhere to live: the body
225
+ * around it is picked inside a render prop. The preview is a prefix of the
226
+ * content, so it parses as the file it came from up to wherever it was cut.
227
+ */
228
+ function WritePreview({ view, path }) {
229
+ const spans = useSyntaxLines(view.preview.map((line) => line.text).join("\n"), { path });
230
+ return /* @__PURE__ */ jsx(Fragment, { children: view.preview.map((line, index) => /* @__PURE__ */ jsxs("span", {
231
+ className: "flex gap-2",
232
+ children: [/* @__PURE__ */ jsx("span", {
233
+ className: "shrink-0 text-right text-doom-faint",
234
+ style: { width: `${String(view.gutter)}ch` },
235
+ children: line.number
236
+ }), /* @__PURE__ */ jsx(SyntaxLine, {
237
+ spans: spans?.[index],
238
+ text: line.text,
239
+ className: "min-w-0 whitespace-pre-wrap break-words text-doom-text"
240
+ })]
241
+ }, line.number)) });
242
+ }
243
+ /**
244
+ * The write tool's timeline item: `path · N chars` in the header. Pi's write
245
+ * result is silent on success, so the body shows the numbered preview the
246
+ * TUI folds into its call: ten lines, or all of them once the item expands.
247
+ * A failure shows the tool's message in red instead.
248
+ */
249
+ function WriteToolMessage({ args, result, output, running, isError, fileTabFor, openTransientTab }) {
250
+ const collapsed = writeCallView(args, false);
251
+ const tab = fileTabFor(collapsed.path);
252
+ return /* @__PURE__ */ jsx(MessageItem, {
253
+ tone: toolTone({
254
+ running,
255
+ isError
256
+ }),
257
+ expandable: collapsed.hidden > 0,
258
+ children: ({ expanded }) => {
259
+ const view = expanded ? writeCallView(args, true) : collapsed;
260
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
261
+ title: "write",
262
+ children: /* @__PURE__ */ jsxs("span", {
263
+ "data-testid": "tool-call-write",
264
+ className: "flex min-w-0 flex-1 items-center gap-2",
265
+ children: [/* @__PURE__ */ jsx(ToolPathLink, {
266
+ path: view.path,
267
+ ...tab === void 0 ? {} : { onOpen: () => openTransientTab(tab) }
268
+ }), /* @__PURE__ */ jsxs("span", {
269
+ className: "shrink-0 text-doom-faint",
270
+ children: ["· ", view.size]
271
+ })]
272
+ })
273
+ }), isError ? /* @__PURE__ */ jsxs(MessageItemBody, {
274
+ "data-testid": "tool-result-write",
275
+ className: "flex flex-col",
276
+ children: [/* @__PURE__ */ jsx(MessageItemStatus, {
277
+ tone: "error",
278
+ children: "failed"
279
+ }), /* @__PURE__ */ jsx("span", {
280
+ className: "whitespace-pre-wrap break-words text-doom-red",
281
+ children: resultText(result, output)
282
+ })]
283
+ }) : view.preview.length === 0 ? running ? /* @__PURE__ */ jsx(MessageItemBody, {
284
+ "data-testid": "tool-result-write",
285
+ children: /* @__PURE__ */ jsx(MessageItemStatus, {
286
+ tone: "running",
287
+ children: "running"
288
+ })
289
+ }) : null : /* @__PURE__ */ jsxs(MessageItemBody, {
290
+ "data-testid": "tool-result-write",
291
+ className: "flex flex-col font-mono",
292
+ children: [
293
+ /* @__PURE__ */ jsx(WritePreview, {
294
+ view,
295
+ path: view.path
296
+ }),
297
+ view.hidden > 0 ? /* @__PURE__ */ jsxs(MessageItemStatus, {
298
+ expands: true,
299
+ children: [view.hidden, " more lines"]
300
+ }) : null,
301
+ running ? /* @__PURE__ */ jsx(MessageItemStatus, {
302
+ tone: "running",
303
+ children: "running"
304
+ }) : null
305
+ ]
306
+ })] });
307
+ }
308
+ });
309
+ }
310
+ //#endregion
311
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/write.web.tsx
312
+ var write_web_default = defineToolRenderer({ message: WriteToolMessage });
313
+ //#endregion
314
+ //#region generated/web.ts
315
+ const via = (identity, value) => value === void 0 ? void 0 : {
316
+ ...identity,
317
+ ...value
318
+ };
319
+ const webPlugin = defineWebPlugin({
320
+ id: "builtin-tools",
321
+ session: { get toolRenderers() {
322
+ return [
323
+ via({ tools: ["find"] }, find_web_default),
324
+ via({ tools: ["ls"] }, ls_web_default),
325
+ via({ tools: ["write"] }, write_web_default)
326
+ ];
327
+ } }
328
+ });
329
+ //#endregion
330
+ export { webPlugin };
331
+
332
+ //# sourceMappingURL=web.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.mjs","names":["LIMIT_KEY","LIMIT_UNIT","toolFind","toolLs","toolWrite"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/builtinToolView.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ListingBody.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/FindToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/find.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/LsToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/ls.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/WriteToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/write.web.tsx","../../generated/web.ts"],"sourcesContent":["import type { ToolResultView } from '@agimon-ai/po-core/web';\n\n/** The TUI's collapsed budgets: ten preview lines for a write, twenty for a listing. */\nexport const WRITE_COLLAPSED_LINES = 10;\nexport const LIST_COLLAPSED_LINES = 20;\n/** Pi's default output cap, the size its truncation warning names when details omit one. */\nconst DEFAULT_MAX_BYTES = 50 * 1024;\nconst KIBIBYTE = 1024;\n\nexport interface NumberedLine {\n readonly number: number;\n readonly text: string;\n}\n\nexport interface WriteCallView {\n readonly path: string;\n /** `N chars`, the size the TUI's call heading shows. */\n readonly size: string;\n readonly preview: readonly NumberedLine[];\n readonly hidden: number;\n /** Widest shown line number, in characters. */\n readonly gutter: number;\n}\n\nexport interface SearchCallView {\n readonly primary: string;\n readonly details: readonly string[];\n}\n\nexport interface ListResultView {\n readonly lines: readonly string[];\n readonly hidden: number;\n /** Pi's `[Truncated: ...]` warning, when the listing hit a limit. */\n readonly truncated: string | undefined;\n}\n\nfunction compactDetails(values: ReadonlyArray<string | undefined>): string[] {\n return values.filter((value): value is string => value !== undefined && value.length > 0);\n}\n\nfunction optionalCount(value: unknown, unit: string): string | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? `${value} ${unit}` : undefined;\n}\n\nfunction pathOrDot(value: unknown): string {\n return typeof value === 'string' && value.length > 0 ? value : '.';\n}\n\n/** Pi's size formatter, so the web warning names the same figure the TUI does. */\nexport function formatSize(bytes: number): string {\n if (bytes < KIBIBYTE) return `${bytes}B`;\n if (bytes < KIBIBYTE * KIBIBYTE) return `${(bytes / KIBIBYTE).toFixed(1)}KB`;\n return `${(bytes / (KIBIBYTE * KIBIBYTE)).toFixed(1)}MB`;\n}\n\n/** What the write call shows: the path, the content size, and a numbered preview of the file. */\nexport function writeCallView(args: Readonly<Record<string, unknown>>, expanded: boolean): WriteCallView {\n const content = typeof args.content === 'string' ? args.content : '';\n const path = typeof args.path === 'string' ? args.path : '';\n const size = `${content.length.toLocaleString('en-US')} chars`;\n if (content.length === 0) return { path, size, preview: [], hidden: 0, gutter: 1 };\n const lines = content.replaceAll('\\t', ' ').replaceAll('\\r\\n', '\\n').split('\\n');\n while (lines.at(-1) === '') lines.pop();\n const visible = expanded ? lines : lines.slice(0, WRITE_COLLAPSED_LINES);\n const preview = visible.map((text, index) => ({ number: index + 1, text }));\n return { path, size, preview, hidden: lines.length - visible.length, gutter: String(visible.length).length };\n}\n\n/** `pattern · path · N results`, as the find call heading lists them. */\nexport function findCallView(args: Readonly<Record<string, unknown>>): SearchCallView {\n return {\n primary: typeof args.pattern === 'string' ? args.pattern : '',\n details: compactDetails([pathOrDot(args.path), optionalCount(args.limit, 'results')]),\n };\n}\n\n/** `path · N entries`, as the ls call heading lists them. */\nexport function lsCallView(args: Readonly<Record<string, unknown>>): SearchCallView {\n return { primary: pathOrDot(args.path), details: compactDetails([optionalCount(args.limit, 'entries')]) };\n}\n\n/** The result's text, from its blocks when the view exists and from the joined output otherwise. */\nexport function resultText(result: ToolResultView | null, output: string): string {\n if (result === null) return output;\n return result.content\n .flatMap((block) => {\n const record = typeof block === 'object' && block !== null ? (block as { type?: unknown; text?: unknown }) : {};\n return record.type === 'text' && typeof record.text === 'string' ? [record.text] : [];\n })\n .join('\\n');\n}\n\n/**\n * A find or ls listing the way Pi's own renderer shows it: the lines,\n * collapsed to twenty, and the limit warning its details carry. `limitKey`\n * names the per-tool counter (resultLimitReached, entryLimitReached).\n */\nexport function listResultView(\n result: ToolResultView | null,\n output: string,\n expanded: boolean,\n limitKey: string,\n limitUnit: string,\n): ListResultView {\n const text = resultText(result, output).trim();\n const all = text.length === 0 ? [] : text.split('\\n');\n const lines = expanded ? all : all.slice(0, LIST_COLLAPSED_LINES);\n const details =\n typeof result?.details === 'object' && result.details !== null ? (result.details as Record<string, unknown>) : {};\n const limit = details[limitKey];\n const truncation =\n typeof details.truncation === 'object' && details.truncation !== null\n ? (details.truncation as Record<string, unknown>)\n : undefined;\n const warnings: string[] = [];\n if (typeof limit === 'number' && limit > 0) warnings.push(`${limit} ${limitUnit} limit`);\n if (truncation?.truncated === true) {\n warnings.push(\n `${formatSize(typeof truncation.maxBytes === 'number' ? truncation.maxBytes : DEFAULT_MAX_BYTES)} limit`,\n );\n }\n return {\n lines,\n hidden: all.length - lines.length,\n truncated: warnings.length > 0 ? `[Truncated: ${warnings.join(', ')}]` : undefined,\n };\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport { MessageItemBody, MessageItemStatus } from '@agimon-ai/po-web-components';\n\nimport { listResultView, resultText } from '../_lib/builtinToolView';\n\n/**\n * The body shared by find and ls: Pi's listing lines, collapsed to twenty\n * until the item expands, with the limit warning its details carry.\n */\nexport function ListingBody({\n tool,\n limitKey,\n limitUnit,\n expanded,\n props,\n}: {\n tool: string;\n limitKey: string;\n limitUnit: string;\n expanded: boolean;\n props: ToolMessageRenderProps;\n}) {\n const { result, output, running, isError } = props;\n if (isError) {\n return (\n <MessageItemBody data-testid={`tool-result-${tool}`} className=\"flex flex-col\">\n <MessageItemStatus tone=\"error\">failed</MessageItemStatus>\n <span className=\"whitespace-pre-wrap break-words text-doom-red\">{resultText(result, output)}</span>\n </MessageItemBody>\n );\n }\n if (result === null) {\n return running ? (\n <MessageItemBody data-testid={`tool-result-${tool}`}>\n <MessageItemStatus tone=\"running\">running</MessageItemStatus>\n </MessageItemBody>\n ) : null;\n }\n const view = listResultView(result, output, expanded, limitKey, limitUnit);\n if (view.lines.length === 0 && view.truncated === undefined) return null;\n return (\n <MessageItemBody data-testid={`tool-result-${tool}`} className=\"flex flex-col font-mono\">\n {view.lines.map((line, index) => (\n <span key={`${String(index)}-${line}`} className=\"whitespace-pre-wrap break-words text-doom-text\">\n {line}\n </span>\n ))}\n {view.hidden > 0 ? <MessageItemStatus expands>{view.hidden} more lines</MessageItemStatus> : null}\n {view.truncated !== undefined ? <span className=\"text-doom-yellow\">{view.truncated}</span> : null}\n </MessageItemBody>\n );\n}\n\n/** Whether the listing hides lines while collapsed, so the item can offer its toggle. */\nexport function listingExpandable(props: ToolMessageRenderProps, limitKey: string, limitUnit: string): boolean {\n if (props.result === null || props.isError) return false;\n return listResultView(props.result, props.output, false, limitKey, limitUnit).hidden > 0;\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport { MessageItem, MessageItemHeader, toolTone } from '@agimon-ai/po-web-components';\n\nimport { findCallView } from '../_lib/builtinToolView';\nimport { ListingBody, listingExpandable } from './ListingBody';\n\nconst LIMIT_KEY = 'resultLimitReached';\nconst LIMIT_UNIT = 'results';\n\n/** The find tool's timeline item: `pattern · path · N results` over Pi's listing lines. */\nexport function FindToolMessage(props: ToolMessageRenderProps) {\n const view = findCallView(props.args);\n return (\n <MessageItem\n tone={toolTone({ running: props.running, isError: props.isError })}\n expandable={listingExpandable(props, LIMIT_KEY, LIMIT_UNIT)}\n >\n {({ expanded }) => (\n <>\n <MessageItemHeader title=\"find\">\n <span data-testid=\"tool-call-find\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className=\"truncate text-doom-text\">{view.primary}</span>\n {view.details.length > 0 ? (\n <span className=\"shrink-0 text-doom-faint\">· {view.details.join(' · ')}</span>\n ) : null}\n </span>\n </MessageItemHeader>\n <ListingBody tool=\"find\" limitKey={LIMIT_KEY} limitUnit={LIMIT_UNIT} expanded={expanded} props={props} />\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { FindToolMessage } from './_components/FindToolMessage';\n\nexport default defineToolRenderer({ message: FindToolMessage });\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport { MessageItem, MessageItemHeader, toolTone } from '@agimon-ai/po-web-components';\n\nimport { lsCallView } from '../_lib/builtinToolView';\nimport { ListingBody, listingExpandable } from './ListingBody';\n\nconst LIMIT_KEY = 'entryLimitReached';\nconst LIMIT_UNIT = 'entries';\n\n/** The ls tool's timeline item: `path · N entries` over Pi's listing lines. */\nexport function LsToolMessage(props: ToolMessageRenderProps) {\n const view = lsCallView(props.args);\n return (\n <MessageItem\n tone={toolTone({ running: props.running, isError: props.isError })}\n expandable={listingExpandable(props, LIMIT_KEY, LIMIT_UNIT)}\n >\n {({ expanded }) => (\n <>\n <MessageItemHeader title=\"ls\">\n <span data-testid=\"tool-call-ls\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className=\"truncate text-doom-text\">{view.primary}</span>\n {view.details.length > 0 ? (\n <span className=\"shrink-0 text-doom-faint\">· {view.details.join(' · ')}</span>\n ) : null}\n </span>\n </MessageItemHeader>\n <ListingBody tool=\"ls\" limitKey={LIMIT_KEY} limitUnit={LIMIT_UNIT} expanded={expanded} props={props} />\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { LsToolMessage } from './_components/LsToolMessage';\n\nexport default defineToolRenderer({ message: LsToolMessage });\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n SyntaxLine,\n ToolPathLink,\n toolTone,\n useSyntaxLines,\n} from '@agimon-ai/po-web-components';\n\nimport { resultText, type WriteCallView, writeCallView } from '../_lib/builtinToolView';\n\n/**\n * The numbered preview, coloured as the file it is about to become.\n *\n * Its own component so the highlighting hook has somewhere to live: the body\n * around it is picked inside a render prop. The preview is a prefix of the\n * content, so it parses as the file it came from up to wherever it was cut.\n */\nfunction WritePreview({ view, path }: { view: WriteCallView; path: string }) {\n const spans = useSyntaxLines(view.preview.map((line) => line.text).join('\\n'), { path });\n return (\n <>\n {view.preview.map((line, index) => (\n <span key={line.number} className=\"flex gap-2\">\n <span className=\"shrink-0 text-right text-doom-faint\" style={{ width: `${String(view.gutter)}ch` }}>\n {line.number}\n </span>\n <SyntaxLine\n spans={spans?.[index]}\n text={line.text}\n className=\"min-w-0 whitespace-pre-wrap break-words text-doom-text\"\n />\n </span>\n ))}\n </>\n );\n}\n\n/**\n * The write tool's timeline item: `path · N chars` in the header. Pi's write\n * result is silent on success, so the body shows the numbered preview the\n * TUI folds into its call: ten lines, or all of them once the item expands.\n * A failure shows the tool's message in red instead.\n */\nexport function WriteToolMessage({\n args,\n result,\n output,\n running,\n isError,\n fileTabFor,\n openTransientTab,\n}: ToolMessageRenderProps) {\n const collapsed = writeCallView(args, false);\n // The header names a file the tool is writing, so the reader can open it\n // rather than hunt for it; nothing installed to show files leaves it as text.\n const tab = fileTabFor(collapsed.path);\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={collapsed.hidden > 0}>\n {({ expanded }) => {\n const view = expanded ? writeCallView(args, true) : collapsed;\n return (\n <>\n <MessageItemHeader title=\"write\">\n <span data-testid=\"tool-call-write\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n <ToolPathLink\n path={view.path}\n {...(tab === undefined ? {} : { onOpen: () => openTransientTab(tab) })}\n />\n <span className=\"shrink-0 text-doom-faint\">· {view.size}</span>\n </span>\n </MessageItemHeader>\n {isError ? (\n <MessageItemBody data-testid=\"tool-result-write\" className=\"flex flex-col\">\n <MessageItemStatus tone=\"error\">failed</MessageItemStatus>\n <span className=\"whitespace-pre-wrap break-words text-doom-red\">{resultText(result, output)}</span>\n </MessageItemBody>\n ) : view.preview.length === 0 ? (\n running ? (\n <MessageItemBody data-testid=\"tool-result-write\">\n <MessageItemStatus tone=\"running\">running</MessageItemStatus>\n </MessageItemBody>\n ) : null\n ) : (\n <MessageItemBody data-testid=\"tool-result-write\" className=\"flex flex-col font-mono\">\n <WritePreview view={view} path={view.path} />\n {view.hidden > 0 ? <MessageItemStatus expands>{view.hidden} more lines</MessageItemStatus> : null}\n {running ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n </MessageItemBody>\n )}\n </>\n );\n }}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { WriteToolMessage } from './_components/WriteToolMessage';\n\nexport default defineToolRenderer({ message: WriteToolMessage });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport toolFind from '../src/extensions/workspaces/sessions/(frontend)/tool/find.web';\nimport toolLs from '../src/extensions/workspaces/sessions/(frontend)/tool/ls.web';\nimport toolWrite from '../src/extensions/workspaces/sessions/(frontend)/tool/write.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: 'builtin-tools',\n session: {\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['find'] }, toolFind), via({ tools: ['ls'] }, toolLs), via({ tools: ['write'] }, toolWrite)]; },\n },\n});\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _agimon_ai_po_core_footer = require("@agimon-ai/po-core/footer");
3
+ Object.defineProperty(exports, "FooterStatusItemSchema", {
4
+ enumerable: true,
5
+ get: function() {
6
+ return _agimon_ai_po_core_footer.FooterStatusItemSchema;
7
+ }
8
+ });
9
+ Object.defineProperty(exports, "FooterStatusPlacementSchema", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return _agimon_ai_po_core_footer.FooterStatusPlacementSchema;
13
+ }
14
+ });
15
+ Object.defineProperty(exports, "FooterTextColorSchema", {
16
+ enumerable: true,
17
+ get: function() {
18
+ return _agimon_ai_po_core_footer.FooterTextColorSchema;
19
+ }
20
+ });
21
+ Object.defineProperty(exports, "FooterTextSegmentSchema", {
22
+ enumerable: true,
23
+ get: function() {
24
+ return _agimon_ai_po_core_footer.FooterTextSegmentSchema;
25
+ }
26
+ });
@@ -0,0 +1,2 @@
1
+ import { DoomFooterContributionDefinition, DoomFooterContributionHandle, DoomFooterContributionValue, DoomFooterStatus, FooterStatusItem, FooterStatusItemSchema, FooterStatusPlacement, FooterStatusPlacementSchema, FooterTextColor, FooterTextColorSchema, FooterTextSegment, FooterTextSegmentSchema } from "@agimon-ai/po-core/footer";
2
+ export { type DoomFooterContributionDefinition, type DoomFooterContributionHandle, type DoomFooterContributionValue, type DoomFooterStatus, type FooterStatusItem, FooterStatusItemSchema, type FooterStatusPlacement, FooterStatusPlacementSchema, type FooterTextColor, FooterTextColorSchema, type FooterTextSegment, FooterTextSegmentSchema };
@@ -0,0 +1,2 @@
1
+ import { FooterStatusItemSchema, FooterStatusPlacementSchema, FooterTextColorSchema, FooterTextSegmentSchema } from "@agimon-ai/po-core/footer";
2
+ export { FooterStatusItemSchema, FooterStatusPlacementSchema, FooterTextColorSchema, FooterTextSegmentSchema };
@@ -0,0 +1,21 @@
1
+ //#region src/types/harnessMetadata.d.ts
2
+ /**
3
+ * The slice of harness state the header renders.
4
+ *
5
+ * A projection of the store rather than its own reader. This used to
6
+ * re-implement five of the state keys with its own list parser and its own
7
+ * default mode, which is two definitions of one protocol to keep in step.
8
+ */
9
+ interface DoomHarnessMetadata {
10
+ root?: string;
11
+ /** The one named major mode this session runs under. */
12
+ majorMode: string;
13
+ domains: string[];
14
+ /** The layer components the major mode resolved to. */
15
+ layers: string[];
16
+ profile?: string;
17
+ }
18
+ declare function readDoomHarnessMetadata(environment?: NodeJS.ProcessEnv): DoomHarnessMetadata;
19
+ //#endregion
20
+ export { readDoomHarnessMetadata as n, DoomHarnessMetadata as t };
21
+ //# sourceMappingURL=harnessMetadata-CzsdGAxL.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnessMetadata-CzsdGAxL.d.mts","names":[],"sources":["../src/types/harnessMetadata.ts"],"mappings":";;;;;;;;UAUiB;EACf;;EAEA;EACA;;EAEA;EACA;;iBAYc,wBAAwB,cAAa,OAAO,aAA2B"}
@@ -0,0 +1,25 @@
1
+ //#region src/types/harnessMetadata.ts
2
+ /**
3
+ * The slice of harness state the header renders.
4
+ *
5
+ * A projection of the store rather than its own reader. This used to
6
+ * re-implement five of the state keys with its own list parser and its own
7
+ * default mode, which is two definitions of one protocol to keep in step.
8
+ */
9
+ const DEFAULT_MAJOR_MODE = "copilot";
10
+ function parseList(value) {
11
+ return value ? value.split(",").map((item) => item.trim()).filter(Boolean) : [];
12
+ }
13
+ function readDoomHarnessMetadata(environment = process.env) {
14
+ return {
15
+ root: environment.PO_ROOT,
16
+ majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,
17
+ domains: parseList(environment.PO_DOMAINS),
18
+ layers: parseList(environment.PO_LAYERS),
19
+ profile: environment.PO_PROFILE?.trim() || void 0
20
+ };
21
+ }
22
+ //#endregion
23
+ export { readDoomHarnessMetadata as t };
24
+
25
+ //# sourceMappingURL=harnessMetadata-DkMSJutN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnessMetadata-DkMSJutN.mjs","names":[],"sources":["../src/types/harnessMetadata.ts"],"sourcesContent":["/**\n * The slice of harness state the header renders.\n *\n * A projection of the store rather than its own reader. This used to\n * re-implement five of the state keys with its own list parser and its own\n * default mode, which is two definitions of one protocol to keep in step.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\n\nexport interface DoomHarnessMetadata {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nexport function readDoomHarnessMetadata(environment: NodeJS.ProcessEnv = process.env): DoomHarnessMetadata {\n return {\n root: environment.PO_ROOT,\n majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,\n domains: parseList(environment.PO_DOMAINS),\n layers: parseList(environment.PO_LAYERS),\n profile: environment.PO_PROFILE?.trim() || undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,qBAAqB;AAY3B,SAAS,UAAU,OAAqC;CACtD,OAAO,QACH,MACG,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,IACjB,CAAC;AACP;AAEA,SAAgB,wBAAwB,cAAiC,QAAQ,KAA0B;CACzG,OAAO;EACL,MAAM,YAAY;EAClB,WAAW,YAAY,eAAe,KAAK,KAAK;EAChD,SAAS,UAAU,YAAY,UAAU;EACzC,QAAQ,UAAU,YAAY,SAAS;EACvC,SAAS,YAAY,YAAY,KAAK,KAAK,KAAA;CAC7C;AACF"}
@@ -0,0 +1,30 @@
1
+ //#region src/types/harnessMetadata.ts
2
+ /**
3
+ * The slice of harness state the header renders.
4
+ *
5
+ * A projection of the store rather than its own reader. This used to
6
+ * re-implement five of the state keys with its own list parser and its own
7
+ * default mode, which is two definitions of one protocol to keep in step.
8
+ */
9
+ const DEFAULT_MAJOR_MODE = "copilot";
10
+ function parseList(value) {
11
+ return value ? value.split(",").map((item) => item.trim()).filter(Boolean) : [];
12
+ }
13
+ function readDoomHarnessMetadata(environment = process.env) {
14
+ return {
15
+ root: environment.PO_ROOT,
16
+ majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,
17
+ domains: parseList(environment.PO_DOMAINS),
18
+ layers: parseList(environment.PO_LAYERS),
19
+ profile: environment.PO_PROFILE?.trim() || void 0
20
+ };
21
+ }
22
+ //#endregion
23
+ Object.defineProperty(exports, "readDoomHarnessMetadata", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return readDoomHarnessMetadata;
27
+ }
28
+ });
29
+
30
+ //# sourceMappingURL=harnessMetadata-Dw9Rb1nW.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnessMetadata-Dw9Rb1nW.cjs","names":[],"sources":["../src/types/harnessMetadata.ts"],"sourcesContent":["/**\n * The slice of harness state the header renders.\n *\n * A projection of the store rather than its own reader. This used to\n * re-implement five of the state keys with its own list parser and its own\n * default mode, which is two definitions of one protocol to keep in step.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\n\nexport interface DoomHarnessMetadata {\n root?: string;\n /** The one named major mode this session runs under. */\n majorMode: string;\n domains: string[];\n /** The layer components the major mode resolved to. */\n layers: string[];\n profile?: string;\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nexport function readDoomHarnessMetadata(environment: NodeJS.ProcessEnv = process.env): DoomHarnessMetadata {\n return {\n root: environment.PO_ROOT,\n majorMode: environment.PO_MAJOR_MODE?.trim() || DEFAULT_MAJOR_MODE,\n domains: parseList(environment.PO_DOMAINS),\n layers: parseList(environment.PO_LAYERS),\n profile: environment.PO_PROFILE?.trim() || undefined,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,qBAAqB;AAY3B,SAAS,UAAU,OAAqC;CACtD,OAAO,QACH,MACG,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,IACjB,CAAC;AACP;AAEA,SAAgB,wBAAwB,cAAiC,QAAQ,KAA0B;CACzG,OAAO;EACL,MAAM,YAAY;EAClB,WAAW,YAAY,eAAe,KAAK,KAAK;EAChD,SAAS,UAAU,YAAY,UAAU;EACzC,QAAQ,UAAU,YAAY,SAAS;EACvC,SAAS,YAAY,YAAY,KAAK,KAAK,KAAA;CAC7C;AACF"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_harnessMetadata = require("./harnessMetadata-Dw9Rb1nW.cjs");
3
+ exports.readDoomHarnessMetadata = require_harnessMetadata.readDoomHarnessMetadata;
@@ -0,0 +1,2 @@
1
+ import { n as readDoomHarnessMetadata, t as DoomHarnessMetadata } from "./harnessMetadata-CzsdGAxL.mjs";
2
+ export { type DoomHarnessMetadata, readDoomHarnessMetadata };
@@ -0,0 +1,2 @@
1
+ import { t as readDoomHarnessMetadata } from "./harnessMetadata-DkMSJutN.mjs";
2
+ export { readDoomHarnessMetadata };
@@ -0,0 +1,30 @@
1
+ import { DoomTelemetryOptions } from "@agimon-ai/po-telemetry";
2
+ //#region src/services/telemetry/index.d.ts
3
+ declare const UI_EVENT: {
4
+ readonly leaderContributionRejected: 'doom_pi_ui.leader_contribution_rejected';
5
+ readonly leaderCommandUnavailable: 'doom_pi_ui.leader_command_unavailable';
6
+ readonly leaderActionUnavailable: 'doom_pi_ui.leader_action_unavailable';
7
+ readonly themeApplyFailed: 'doom_pi_ui.theme_apply_failed';
8
+ readonly shellInstalled: 'doom_pi_ui.shell_installed';
9
+ readonly eventLoopStalled: 'doom_pi_ui.event_loop_stalled';
10
+ };
11
+ type UiEventName = (typeof UI_EVENT)[keyof typeof UI_EVENT];
12
+ type UiEventAttributes = Record<string, string | number | boolean>;
13
+ interface UiTelemetryOptions {
14
+ cwd?: string;
15
+ workspaceRoot?: string;
16
+ env?: NodeJS.ProcessEnv;
17
+ telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;
18
+ warn?: (message: string) => void;
19
+ }
20
+ interface UiTelemetry {
21
+ recordError(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;
22
+ recordWarning(event: UiEventName, error: unknown, attributes?: UiEventAttributes): Promise<void>;
23
+ recordEvent(event: UiEventName, attributes?: UiEventAttributes): Promise<void>;
24
+ flush(): Promise<void>;
25
+ shutdown(): Promise<void>;
26
+ }
27
+ declare function createUiTelemetry(options?: UiTelemetryOptions): UiTelemetry;
28
+ //#endregion
29
+ export { UiTelemetryOptions as a, UiTelemetry as i, UiEventAttributes as n, createUiTelemetry as o, UiEventName as r, UI_EVENT as t };
30
+ //# sourceMappingURL=index-Bx49wmE7.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Bx49wmE7.d.mts","names":[],"sources":["../src/services/telemetry/index.ts"],"mappings":";;cAKa;WACX;WACA;WACA;WACA;WACA;WACA;;KAGU,sBAAsB,uBAAuB;KAC7C,oBAAoB;UAEf;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;UAGO;EACf,YAAY,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACjF,cAAc,OAAO,aAAa,gBAAgB,aAAa,oBAAoB;EACnF,YAAY,OAAO,aAAa,aAAa,oBAAoB;EACjE,SAAS;EACT,YAAY;;iBAGE,kBAAkB,UAAS,qBAA0B"}