@agimon-ai/po-codemode 0.0.1-alpha.13 → 0.0.1-alpha.15

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.
@@ -1,5 +1,5 @@
1
- import { defineToolRenderer, defineWebPlugin, toolResultTextLines } from "@agimon-ai/po-core/web";
2
- import { CodeBlock, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, toolTone } from "@agimon-ai/po-web-components";
1
+ import { defineToolRenderer, defineWebPlugin } from "@agimon-ai/po-core/web";
2
+ import { CodeBlock, Markdown, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, toolTone } from "@agimon-ai/po-web-components";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts
5
5
  /** Tool names this package registers (registerTool's `name`). */
@@ -10,6 +10,7 @@ const ARGS_MAX = 160;
10
10
  const CALLS_MAX = 50;
11
11
  const IMAGE_TYPES = /^image\/(?:png|jpeg|webp|gif)$/u;
12
12
  const SAVED_LINE = /^Saved as (\S+) \((.+)\)$/u;
13
+ const DOCUMENT_LINE = /^(?:#{1,6} |```)/mu;
13
14
  function record(value) {
14
15
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
15
16
  }
@@ -60,29 +61,34 @@ function execResultView(result) {
60
61
  images: []
61
62
  };
62
63
  let saved;
63
- const content = [];
64
+ const texts = [];
65
+ const images = [];
64
66
  for (const block of result.content) {
65
- const text = record(block)?.type === "text" ? record(block)?.text : void 0;
66
- const match = typeof text === "string" ? SAVED_LINE.exec(text.trim()) : null;
67
- if (match?.[1] !== void 0 && match[2] !== void 0) saved = {
68
- id: match[1],
69
- path: match[2]
70
- };
71
- else content.push(block);
67
+ const item = record(block);
68
+ if (item?.type === "text" && typeof item.text === "string") {
69
+ const match = SAVED_LINE.exec(item.text.trim());
70
+ if (match?.[1] !== void 0 && match[2] !== void 0) saved = {
71
+ id: match[1],
72
+ path: match[2]
73
+ };
74
+ else texts.push(item.text);
75
+ } else if (item?.type === "image" && typeof item.data === "string" && typeof item.mimeType === "string" && IMAGE_TYPES.test(item.mimeType)) images.push({
76
+ mimeType: item.mimeType,
77
+ data: item.data
78
+ });
72
79
  }
73
- const images = content.flatMap((block) => {
74
- const image = record(block);
75
- return image?.type === "image" && typeof image.data === "string" && typeof image.mimeType === "string" && IMAGE_TYPES.test(image.mimeType) ? [{
76
- mimeType: image.mimeType,
77
- data: image.data
78
- }] : [];
79
- });
80
+ const lines = texts.join("\n").replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll(" ", " ").split("\n");
81
+ while (lines.length > 0 && lines.at(-1)?.trim() === "") lines.pop();
80
82
  return {
81
- lines: toolResultTextLines(content),
83
+ lines,
82
84
  ...saved === void 0 ? {} : { saved },
83
85
  images
84
86
  };
85
87
  }
88
+ /** Whether result text is a document, such as a report or a mermaid diagram, to draw rather than print. */
89
+ function readsAsDocument(text) {
90
+ return DOCUMENT_LINE.test(text);
91
+ }
86
92
  /** The header line for discover: what was asked for. */
87
93
  function discoverSummary(args) {
88
94
  if (typeof args.namespace === "string" && args.namespace !== "") return args.namespace;
@@ -145,133 +151,224 @@ function ToolSection({ label, children }) {
145
151
  }
146
152
  //#endregion
147
153
  //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx
154
+ /** The tree's elbow: a short branch from the rail to the item it leads to. */
155
+ const BRANCH = "relative before:absolute before:top-[1.125rem] before:-left-4 before:w-3 before:border-t before:border-po-border-soft";
156
+ const SUMMARY = "flex min-h-6 cursor-pointer list-none items-center gap-x-2 gap-y-0.5 [&::-webkit-details-marker]:hidden";
157
+ /** The folding mark at the end of a summary; it turns when the section opens. */
158
+ function Chevron() {
159
+ return /* @__PURE__ */ jsx("span", {
160
+ "aria-hidden": true,
161
+ className: "w-3 shrink-0 text-center text-po-dim transition-transform group-open:rotate-90",
162
+ children: "›"
163
+ });
164
+ }
165
+ /** Pictures and documents stay on screen whether or not their section is open: they are the point of the call. */
166
+ function Visuals({ text, images, label }) {
167
+ return /* @__PURE__ */ jsxs(Fragment, { children: [readsAsDocument(text) ? /* @__PURE__ */ jsx("div", {
168
+ "data-testid": "tool-output-document",
169
+ className: "max-h-96 overflow-auto text-sm",
170
+ children: /* @__PURE__ */ jsx(Markdown, { text })
171
+ }) : null, images.map((image, index) => /* @__PURE__ */ jsx("img", {
172
+ src: `data:${image.mimeType};base64,${image.data}`,
173
+ alt: `${label} image ${String(index + 1)}`,
174
+ "data-testid": "tool-output-image",
175
+ className: "max-h-48 max-w-full self-start rounded-md border border-po-border-soft"
176
+ }, `${image.mimeType}-${String(index)}`))] });
177
+ }
178
+ /** One call on the rail. It opens to its whole args and result; its pictures and documents show either way. */
148
179
  function CallRow({ call }) {
149
- const args = callArgsSummary(call.args);
180
+ const view = execResultView(call.result ?? null);
181
+ const text = view.lines.join("\n");
182
+ const printed = text !== "" && !readsAsDocument(text);
183
+ const opens = Object.keys(call.args).length > 0 || printed;
184
+ const head = /* @__PURE__ */ jsxs(Fragment, { children: [
185
+ /* @__PURE__ */ jsx("span", {
186
+ className: "shrink-0 truncate font-mono font-semibold text-po-text max-sm:basis-full",
187
+ children: call.name
188
+ }),
189
+ /* @__PURE__ */ jsx("span", {
190
+ className: "min-w-0 flex-1 truncate font-mono text-po-dim group-open:invisible",
191
+ children: callArgsSummary(call.args)
192
+ }),
193
+ /* @__PURE__ */ jsx("span", {
194
+ "aria-hidden": true,
195
+ className: `w-3 shrink-0 text-center ${call.ok ? "text-po-green" : "text-po-red"}`,
196
+ children: call.ok ? "✓" : "✗"
197
+ }),
198
+ /* @__PURE__ */ jsx("span", {
199
+ className: "sr-only",
200
+ children: call.ok ? "completed" : "failed"
201
+ }),
202
+ /* @__PURE__ */ jsxs("span", {
203
+ className: "w-16 shrink-0 text-right tabular-nums text-po-dim",
204
+ children: [call.ms, " ms"]
205
+ })
206
+ ] });
150
207
  return /* @__PURE__ */ jsxs("div", {
151
208
  "data-testid": "exec-call",
152
- className: "flex flex-col gap-0.5",
153
- children: [/* @__PURE__ */ jsxs("div", {
154
- className: "flex items-center gap-2 text-sm",
155
- children: [
156
- /* @__PURE__ */ jsx("span", {
157
- className: "shrink-0 font-mono text-po-text",
158
- children: call.name
159
- }),
160
- /* @__PURE__ */ jsx("span", {
161
- className: "min-w-0 flex-1 truncate font-mono text-po-dim",
162
- children: args
163
- }),
164
- /* @__PURE__ */ jsx("span", {
165
- "aria-hidden": true,
166
- className: `w-3 shrink-0 text-center ${call.ok ? "text-po-green" : "text-po-red"}`,
167
- children: call.ok ? "✓" : "✗"
168
- }),
169
- /* @__PURE__ */ jsxs("span", {
170
- className: "w-16 shrink-0 text-right tabular-nums text-po-dim",
171
- children: [call.ms, " ms"]
172
- })
173
- ]
174
- }), call.error === void 0 ? null : /* @__PURE__ */ jsx("p", {
175
- className: "pl-5 text-sm break-words text-po-red",
176
- children: call.error
177
- })]
209
+ className: "flex flex-col gap-2 rounded-lg border border-po-border-soft px-3 py-2",
210
+ children: [
211
+ opens ? /* @__PURE__ */ jsxs("details", {
212
+ className: "group text-sm",
213
+ children: [/* @__PURE__ */ jsxs("summary", {
214
+ className: `${SUMMARY} flex-wrap`,
215
+ children: [head, /* @__PURE__ */ jsx(Chevron, {})]
216
+ }), /* @__PURE__ */ jsxs("div", {
217
+ className: "mt-2 flex flex-col gap-2",
218
+ children: [Object.keys(call.args).length > 0 ? /* @__PURE__ */ jsx(CodeBlock, {
219
+ text: JSON.stringify(call.args, null, 2),
220
+ className: "language-json"
221
+ }) : null, printed ? /* @__PURE__ */ jsx("pre", {
222
+ "data-testid": "exec-call-output",
223
+ className: "max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap text-po-text",
224
+ children: text
225
+ }) : null]
226
+ })]
227
+ }) : /* @__PURE__ */ jsx("div", {
228
+ className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-sm",
229
+ children: head
230
+ }),
231
+ call.error === void 0 ? null : /* @__PURE__ */ jsx("p", {
232
+ className: "text-sm break-words text-po-red",
233
+ children: call.error
234
+ }),
235
+ /* @__PURE__ */ jsx(Visuals, {
236
+ text,
237
+ images: view.images,
238
+ label: call.name
239
+ })
240
+ ]
178
241
  });
179
242
  }
180
- function Calls({ calls, renderTool }) {
181
- return /* @__PURE__ */ jsx("ul", {
243
+ /** The script's outcome as the tree's last leaf: one line until opened, the whole text after; visuals always. */
244
+ function Returned({ result, isError }) {
245
+ const view = execResultView(result);
246
+ const text = view.lines.join("\n");
247
+ const label = isError ? "Error" : "Returned";
248
+ const ink = isError ? "text-po-red" : "text-po-text";
249
+ return /* @__PURE__ */ jsxs("div", {
250
+ "data-testid": `tool-result-${execToolName}`,
182
251
  className: "flex flex-col gap-2",
183
- children: calls.map((call, index) => {
184
- const card = call.tool === void 0 || renderTool === void 0 ? null : renderTool({
185
- toolName: call.tool,
186
- args: call.args,
187
- result: call.result ?? null,
188
- isError: !call.ok
189
- });
190
- return /* @__PURE__ */ jsx("li", { children: card ?? /* @__PURE__ */ jsx(CallRow, { call }) }, `${String(index)}-${call.name}`);
191
- })
252
+ children: [view.lines.length === 0 ? /* @__PURE__ */ jsx("p", {
253
+ className: "text-sm text-po-dim",
254
+ children: isError ? "Failed with no output." : "Returned nothing."
255
+ }) : readsAsDocument(text) ? /* @__PURE__ */ jsx("p", {
256
+ className: "text-sm font-semibold text-po-dim",
257
+ children: label
258
+ }) : /* @__PURE__ */ jsxs("details", {
259
+ open: isError,
260
+ className: "group text-sm",
261
+ children: [/* @__PURE__ */ jsxs("summary", {
262
+ className: `${SUMMARY} text-po-dim hover:text-po-blue`,
263
+ children: [
264
+ /* @__PURE__ */ jsx("span", {
265
+ className: "shrink-0 font-semibold",
266
+ children: label
267
+ }),
268
+ /* @__PURE__ */ jsx("span", {
269
+ className: `min-w-0 flex-1 truncate font-mono group-open:hidden ${ink}`,
270
+ children: view.lines.join(" ")
271
+ }),
272
+ /* @__PURE__ */ jsx(Chevron, {})
273
+ ]
274
+ }), /* @__PURE__ */ jsx("pre", {
275
+ "data-testid": "tool-output",
276
+ className: `mt-1 max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${ink}`,
277
+ children: text
278
+ })]
279
+ }), /* @__PURE__ */ jsx(Visuals, {
280
+ text,
281
+ images: view.images,
282
+ label: "Script"
283
+ })]
192
284
  });
193
285
  }
194
286
  /**
195
- * The exec tool's timeline item. It stays folded until opened: the script is the
196
- * point of the call, so opening shows the code, every namespace call it made
197
- * (as the owning tool's card when one exists), then what it returned.
287
+ * The exec tool's timeline item. The calls the script made hang under it as a
288
+ * tree, each as the owning tool's own card when one exists, with what the
289
+ * script returned as the last leaf. Opening the item shows the script itself.
198
290
  */
199
291
  function ExecToolCard({ args, result, running, isError, defaultExpanded = false, renderTool }) {
200
292
  const code = execCode(args);
201
- const view = execResultView(result);
293
+ const saved = execResultView(result).saved;
202
294
  const calls = execCalls(result?.details);
295
+ const failed = calls.filter((call) => !call.ok).length;
296
+ const settled = !running || result !== null;
203
297
  return /* @__PURE__ */ jsx(MessageItem, {
204
298
  tone: toolTone({
205
299
  running,
206
300
  isError
207
301
  }),
208
- expandable: true,
302
+ expandable: code !== "",
209
303
  defaultExpanded,
210
- children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(MessageItemHeader, {
211
- title: execToolName,
212
- children: [/* @__PURE__ */ jsx("span", {
213
- "data-testid": `tool-call-${execToolName}`,
214
- className: "min-w-0 flex-1 truncate text-po-text",
215
- children: execSummary(args)
216
- }), calls.length > 0 ? /* @__PURE__ */ jsxs("span", {
217
- className: "shrink-0 text-sm text-po-dim",
218
- children: [
219
- calls.length,
220
- " ",
221
- calls.length === 1 ? "call" : "calls"
222
- ]
223
- }) : null]
224
- }), expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
225
- "data-testid": `tool-result-${execToolName}`,
226
- className: "flex flex-col gap-4",
227
- children: [
228
- code === "" ? null : /* @__PURE__ */ jsx(ToolSection, {
304
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [
305
+ /* @__PURE__ */ jsxs(MessageItemHeader, {
306
+ title: execToolName,
307
+ children: [/* @__PURE__ */ jsx("span", {
308
+ "data-testid": `tool-call-${execToolName}`,
309
+ className: "min-w-0 flex-1 truncate text-po-text",
310
+ children: execSummary(args)
311
+ }), calls.length > 0 ? /* @__PURE__ */ jsxs("span", {
312
+ className: "shrink-0 text-sm text-po-dim",
313
+ children: [
314
+ calls.length,
315
+ " ",
316
+ calls.length === 1 ? "call" : "calls",
317
+ failed > 0 ? /* @__PURE__ */ jsxs("span", {
318
+ className: "text-po-red",
319
+ children: [
320
+ ", ",
321
+ failed,
322
+ " failed"
323
+ ]
324
+ }) : null
325
+ ]
326
+ }) : null]
327
+ }),
328
+ expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
329
+ className: "flex flex-col gap-2",
330
+ children: [/* @__PURE__ */ jsx(ToolSection, {
229
331
  label: "Code",
230
332
  children: /* @__PURE__ */ jsx(CodeBlock, {
231
333
  text: code,
232
334
  className: "language-ts"
233
335
  })
234
- }),
235
- calls.length === 0 ? null : /* @__PURE__ */ jsx(ToolSection, {
236
- label: "Calls",
237
- children: /* @__PURE__ */ jsx(Calls, {
238
- calls,
239
- renderTool
240
- })
241
- }),
242
- running && view.lines.length === 0 ? /* @__PURE__ */ jsx(MessageItemStatus, {
243
- tone: "running",
244
- children: "running"
245
- }) : /* @__PURE__ */ jsxs(ToolSection, {
246
- label: isError ? "Error" : "Result",
247
- children: [
248
- view.lines.length === 0 && view.images.length === 0 ? /* @__PURE__ */ jsx("p", {
249
- className: "text-sm text-po-dim",
250
- children: "No output."
251
- }) : null,
252
- view.lines.length === 0 ? null : /* @__PURE__ */ jsx("pre", {
253
- "data-testid": "tool-output",
254
- className: `max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? "text-po-red" : "text-po-text"}`,
255
- children: view.lines.join("\n")
256
- }),
257
- view.images.map((image, index) => /* @__PURE__ */ jsx("img", {
258
- src: `data:${image.mimeType};base64,${image.data}`,
259
- alt: `Script image ${String(index + 1)}`,
260
- "data-testid": "tool-output-image",
261
- className: "max-h-96 max-w-full self-start rounded-md border border-po-border-soft"
262
- }, `${image.mimeType}-${String(index)}`))
263
- ]
264
- }),
265
- view.saved === void 0 ? null : /* @__PURE__ */ jsxs("p", {
336
+ }), saved === void 0 ? null : /* @__PURE__ */ jsxs("p", {
266
337
  className: "text-sm text-po-dim",
267
- title: view.saved.path,
338
+ title: saved.path,
268
339
  children: ["Saved as ", /* @__PURE__ */ jsx("span", {
269
340
  className: "font-mono text-po-text",
270
- children: view.saved.id
341
+ children: saved.id
271
342
  })]
272
- })
273
- ]
274
- }) : null] })
343
+ })]
344
+ }) : null,
345
+ settled ? /* @__PURE__ */ jsxs("ol", {
346
+ "aria-label": "Script calls",
347
+ className: "mx-4 mb-3 flex flex-col gap-2 border-l border-po-border-soft pl-4 sm:ml-[2.125rem]",
348
+ children: [calls.map((call, index) => {
349
+ const card = call.tool === void 0 || renderTool === void 0 ? null : renderTool({
350
+ toolName: call.tool,
351
+ args: call.args,
352
+ result: call.result ?? null,
353
+ isError: !call.ok
354
+ });
355
+ return /* @__PURE__ */ jsx("li", {
356
+ className: `${BRANCH} flex flex-col gap-2`,
357
+ children: card === null ? /* @__PURE__ */ jsx(CallRow, { call }) : /* @__PURE__ */ jsxs(Fragment, { children: [card, /* @__PURE__ */ jsx(Visuals, {
358
+ text: "",
359
+ images: execResultView(call.result ?? null).images,
360
+ label: call.name
361
+ })] })
362
+ }, `${String(index)}-${call.name}`);
363
+ }), /* @__PURE__ */ jsx("li", {
364
+ className: BRANCH,
365
+ children: /* @__PURE__ */ jsx(Returned, {
366
+ result,
367
+ isError
368
+ })
369
+ })]
370
+ }) : null
371
+ ] })
275
372
  });
276
373
  }
277
374
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"web.mjs","names":["toolDiscover","toolExec"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx","../../generated/web.ts"],"sourcesContent":["import { type ToolResultView, toolResultTextLines } from '@agimon-ai/po-core/web';\n\n/** Tool names this package registers (registerTool's `name`). */\nexport const execToolName = 'exec' as const;\nexport const discoverToolName = 'discover' as const;\n\nconst SUMMARY_MAX = 120;\nconst ARGS_MAX = 160;\nconst CALLS_MAX = 50;\nconst IMAGE_TYPES = /^image\\/(?:png|jpeg|webp|gif)$/u;\nconst SAVED_LINE = /^Saved as (\\S+) \\((.+)\\)$/u;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction clip(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n}\n\n/** The script the call ran, exactly as the agent wrote it. */\nexport function execCode(args: Readonly<Record<string, unknown>>): string {\n return typeof args.code === 'string' ? args.code : '';\n}\n\n/** The header line: the script's first line, with a leading `//` comment marker dropped. */\nexport function execSummary(args: Readonly<Record<string, unknown>>): string {\n const first = execCode(args)\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => line !== '');\n if (first === undefined) return 'script';\n return clip(first.replace(/^\\/\\/+\\s*/u, ''), SUMMARY_MAX);\n}\n\n/** One namespace call the script made, as exec reports it in the result's details. */\nexport interface ExecCall {\n /** The member called, such as `browser.click` or `mcp.github.search_issues`. */\n name: string;\n args: Record<string, unknown>;\n ok: boolean;\n ms: number;\n /** The tool name whose own card shows this call, when another package has one. */\n tool?: string;\n error?: string;\n result?: ToolResultView;\n}\n\nfunction callOf(value: unknown): ExecCall | undefined {\n const call = record(value);\n if (call === undefined || typeof call.name !== 'string' || call.name === '') return undefined;\n const result = record(call.result);\n return {\n name: call.name,\n args: record(call.args) ?? {},\n ok: call.ok !== false,\n ms: typeof call.ms === 'number' && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,\n ...(typeof call.tool === 'string' && call.tool !== '' ? { tool: call.tool } : {}),\n ...(typeof call.error === 'string' && call.error !== '' ? { error: call.error } : {}),\n ...(result !== undefined && Array.isArray(result.content)\n ? { result: { content: result.content, details: result.details } }\n : {}),\n };\n}\n\n/** The nested calls recorded in a result's details; anything malformed is skipped. */\nexport function execCalls(details: unknown): ExecCall[] {\n const calls = record(details)?.calls;\n if (!Array.isArray(calls)) return [];\n return calls\n .slice(0, CALLS_MAX)\n .map(callOf)\n .filter((call): call is ExecCall => call !== undefined);\n}\n\n/** A call's arguments on one line, for a row that has no card of its own. */\nexport function callArgsSummary(args: Readonly<Record<string, unknown>>): string {\n return Object.keys(args).length === 0 ? '' : clip(JSON.stringify(args), ARGS_MAX);\n}\n\nexport interface ExecImage {\n mimeType: string;\n data: string;\n}\n\nexport interface ExecResultView {\n lines: string[];\n /** The saved-script footer exec appends: the id to import it by, and where it lives. */\n saved?: { id: string; path: string };\n images: ExecImage[];\n}\n\n/** What a result holds, with the saved-script footer and the pictures taken out of the text. */\nexport function execResultView(result: ToolResultView | null): ExecResultView {\n if (result === null) return { lines: [], images: [] };\n let saved: ExecResultView['saved'];\n const content: unknown[] = [];\n for (const block of result.content) {\n const text = record(block)?.type === 'text' ? record(block)?.text : undefined;\n const match = typeof text === 'string' ? SAVED_LINE.exec(text.trim()) : null;\n if (match?.[1] !== undefined && match[2] !== undefined) saved = { id: match[1], path: match[2] };\n else content.push(block);\n }\n const images = content.flatMap((block): ExecImage[] => {\n const image = record(block);\n return image?.type === 'image' &&\n typeof image.data === 'string' &&\n typeof image.mimeType === 'string' &&\n IMAGE_TYPES.test(image.mimeType)\n ? [{ mimeType: image.mimeType, data: image.data }]\n : [];\n });\n return { lines: toolResultTextLines(content), ...(saved === undefined ? {} : { saved }), images };\n}\n\n/** The header line for discover: what was asked for. */\nexport function discoverSummary(args: Readonly<Record<string, unknown>>): string {\n if (typeof args.namespace === 'string' && args.namespace !== '') return args.namespace;\n if (typeof args.query === 'string' && args.query !== '') return `find \"${clip(args.query, SUMMARY_MAX)}\"`;\n return 'namespaces and scripts';\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport { discoverSummary, discoverToolName } from '../_lib/execToolView';\n\nexport type DiscoverToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\n/** The discover tool's timeline item: folded to what was asked for, open to what came back. */\nexport function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }: DiscoverToolCardProps) {\n const declarations = typeof args.namespace === 'string' && args.namespace !== '' && !isError;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={discoverToolName}>\n <span data-testid={`tool-call-${discoverToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {discoverSummary(args)}\n </span>\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${discoverToolName}`} className=\"flex flex-col gap-2\">\n {running && output === '' ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n {output === '' ? null : declarations ? (\n <div className=\"max-h-96 overflow-auto\">\n <CodeBlock text={output} className=\"language-ts\" />\n </div>\n ) : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {output}\n </pre>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { DiscoverToolCard } from './_components/DiscoverToolCard';\n\nexport default defineToolRenderer({ message: DiscoverToolCard });\n","import type { ReactNode } from 'react';\n\n/** A labelled part of an expanded card body. */\nexport function ToolSection({ label, children }: { label: string; children: ReactNode }) {\n return (\n <section className=\"flex flex-col gap-1.5\">\n <h4 className=\"text-sm font-medium text-po-dim\">{label}</h4>\n {children}\n </section>\n );\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport {\n callArgsSummary,\n execCalls,\n execCode,\n execResultView,\n execSummary,\n execToolName,\n type ExecCall,\n} from '../_lib/execToolView';\nimport { ToolSection } from './ToolSection';\n\n/** Draws another tool's own card for a nested call, or nothing when no package owns one. */\nexport type RenderNestedTool = NonNullable<ToolMessageRenderProps['renderTool']>;\n\nexport type ExecToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\nfunction CallRow({ call }: { call: ExecCall }) {\n const args = callArgsSummary(call.args);\n return (\n <div data-testid=\"exec-call\" className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-center gap-2 text-sm\">\n <span className=\"shrink-0 font-mono text-po-text\">{call.name}</span>\n <span className=\"min-w-0 flex-1 truncate font-mono text-po-dim\">{args}</span>\n <span aria-hidden className={`w-3 shrink-0 text-center ${call.ok ? 'text-po-green' : 'text-po-red'}`}>\n {call.ok ? '✓' : '✗'}\n </span>\n <span className=\"w-16 shrink-0 text-right tabular-nums text-po-dim\">{call.ms} ms</span>\n </div>\n {call.error === undefined ? null : <p className=\"pl-5 text-sm break-words text-po-red\">{call.error}</p>}\n </div>\n );\n}\n\nfunction Calls({ calls, renderTool }: { calls: readonly ExecCall[]; renderTool: RenderNestedTool | undefined }) {\n return (\n <ul className=\"flex flex-col gap-2\">\n {calls.map((call, index) => {\n const card =\n call.tool === undefined || renderTool === undefined\n ? null\n : renderTool({\n toolName: call.tool,\n args: call.args,\n result: call.result ?? null,\n isError: !call.ok,\n });\n return <li key={`${String(index)}-${call.name}`}>{card ?? <CallRow call={call} />}</li>;\n })}\n </ul>\n );\n}\n\n/**\n * The exec tool's timeline item. It stays folded until opened: the script is the\n * point of the call, so opening shows the code, every namespace call it made\n * (as the owning tool's card when one exists), then what it returned.\n */\nexport function ExecToolCard({\n args,\n result,\n running,\n isError,\n defaultExpanded = false,\n renderTool,\n}: ExecToolCardProps) {\n const code = execCode(args);\n const view = execResultView(result);\n const calls = execCalls(result?.details);\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={execToolName}>\n <span data-testid={`tool-call-${execToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {execSummary(args)}\n </span>\n {calls.length > 0 ? (\n <span className=\"shrink-0 text-sm text-po-dim\">\n {calls.length} {calls.length === 1 ? 'call' : 'calls'}\n </span>\n ) : null}\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${execToolName}`} className=\"flex flex-col gap-4\">\n {code === '' ? null : (\n <ToolSection label=\"Code\">\n <CodeBlock text={code} className=\"language-ts\" />\n </ToolSection>\n )}\n {calls.length === 0 ? null : (\n <ToolSection label=\"Calls\">\n <Calls calls={calls} renderTool={renderTool} />\n </ToolSection>\n )}\n {running && view.lines.length === 0 ? (\n <MessageItemStatus tone=\"running\">running</MessageItemStatus>\n ) : (\n <ToolSection label={isError ? 'Error' : 'Result'}>\n {view.lines.length === 0 && view.images.length === 0 ? (\n <p className=\"text-sm text-po-dim\">No output.</p>\n ) : null}\n {view.lines.length === 0 ? null : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {view.lines.join('\\n')}\n </pre>\n )}\n {view.images.map((image, index) => (\n <img\n key={`${image.mimeType}-${String(index)}`}\n src={`data:${image.mimeType};base64,${image.data}`}\n alt={`Script image ${String(index + 1)}`}\n data-testid=\"tool-output-image\"\n className=\"max-h-96 max-w-full self-start rounded-md border border-po-border-soft\"\n />\n ))}\n </ToolSection>\n )}\n {view.saved === undefined ? null : (\n <p className=\"text-sm text-po-dim\" title={view.saved.path}>\n Saved as <span className=\"font-mono text-po-text\">{view.saved.id}</span>\n </p>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { ExecToolCard } from './_components/ExecToolCard';\n\nexport default defineToolRenderer({ message: ExecToolCard });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport toolDiscover from '../src/extensions/workspaces/sessions/(frontend)/tool/discover.web';\nimport toolExec from '../src/extensions/workspaces/sessions/(frontend)/tool/exec.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: 'codemode',\n session: {\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['discover'] }, toolDiscover), via({ tools: ['exec'] }, toolExec)]; },\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"web.mjs","names":["toolDiscover","toolExec"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx","../../generated/web.ts"],"sourcesContent":["// Imports nothing at runtime: the web and native cards share it, and the native\n// bundle may not load the web contract.\nimport type { ToolResultView } from '@agimon-ai/po-core/web';\n\n/** Tool names this package registers (registerTool's `name`). */\nexport const execToolName = 'exec' as const;\nexport const discoverToolName = 'discover' as const;\n\nconst SUMMARY_MAX = 120;\nconst ARGS_MAX = 160;\nconst CALLS_MAX = 50;\nconst IMAGE_TYPES = /^image\\/(?:png|jpeg|webp|gif)$/u;\nconst SAVED_LINE = /^Saved as (\\S+) \\((.+)\\)$/u;\n// A heading or a fence starts a line of Markdown, never one of JSON or a log.\nconst DOCUMENT_LINE = /^(?:#{1,6} |```)/mu;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction clip(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n}\n\n/** The script the call ran, exactly as the agent wrote it. */\nexport function execCode(args: Readonly<Record<string, unknown>>): string {\n return typeof args.code === 'string' ? args.code : '';\n}\n\n/** The header line: the script's first line, with a leading `//` comment marker dropped. */\nexport function execSummary(args: Readonly<Record<string, unknown>>): string {\n const first = execCode(args)\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => line !== '');\n if (first === undefined) return 'script';\n return clip(first.replace(/^\\/\\/+\\s*/u, ''), SUMMARY_MAX);\n}\n\n/** One namespace call the script made, as exec reports it in the result's details. */\nexport interface ExecCall {\n /** The member called, such as `browser.click` or `mcp.github.search_issues`. */\n name: string;\n args: Record<string, unknown>;\n ok: boolean;\n ms: number;\n /** The tool name whose own card shows this call, when another package has one. */\n tool?: string;\n error?: string;\n result?: ToolResultView;\n}\n\nfunction callOf(value: unknown): ExecCall | undefined {\n const call = record(value);\n if (call === undefined || typeof call.name !== 'string' || call.name === '') return undefined;\n const result = record(call.result);\n return {\n name: call.name,\n args: record(call.args) ?? {},\n ok: call.ok !== false,\n ms: typeof call.ms === 'number' && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,\n ...(typeof call.tool === 'string' && call.tool !== '' ? { tool: call.tool } : {}),\n ...(typeof call.error === 'string' && call.error !== '' ? { error: call.error } : {}),\n ...(result !== undefined && Array.isArray(result.content)\n ? { result: { content: result.content, details: result.details } }\n : {}),\n };\n}\n\n/** The nested calls recorded in a result's details; anything malformed is skipped. */\nexport function execCalls(details: unknown): ExecCall[] {\n const calls = record(details)?.calls;\n if (!Array.isArray(calls)) return [];\n return calls\n .slice(0, CALLS_MAX)\n .map(callOf)\n .filter((call): call is ExecCall => call !== undefined);\n}\n\n/** A call's arguments on one line, for a row that has no card of its own. */\nexport function callArgsSummary(args: Readonly<Record<string, unknown>>): string {\n return Object.keys(args).length === 0 ? '' : clip(JSON.stringify(args), ARGS_MAX);\n}\n\nexport interface ExecImage {\n mimeType: string;\n data: string;\n}\n\nexport interface ExecResultView {\n lines: string[];\n /** The saved-script footer exec appends: the id to import it by, and where it lives. */\n saved?: { id: string; path: string };\n images: ExecImage[];\n}\n\n/** What a result holds, with the saved-script footer and the pictures taken out of the text. */\nexport function execResultView(result: ToolResultView | null): ExecResultView {\n if (result === null) return { lines: [], images: [] };\n let saved: ExecResultView['saved'];\n const texts: string[] = [];\n const images: ExecImage[] = [];\n for (const block of result.content) {\n const item = record(block);\n if (item?.type === 'text' && typeof item.text === 'string') {\n const match = SAVED_LINE.exec(item.text.trim());\n if (match?.[1] !== undefined && match[2] !== undefined) saved = { id: match[1], path: match[2] };\n else texts.push(item.text);\n } else if (\n item?.type === 'image' &&\n typeof item.data === 'string' &&\n typeof item.mimeType === 'string' &&\n IMAGE_TYPES.test(item.mimeType)\n ) {\n images.push({ mimeType: item.mimeType, data: item.data });\n }\n }\n // As po-core's toolResultTextLines: CRLF folded, tabs widened, trailing blank lines dropped.\n const lines = texts.join('\\n').replaceAll('\\r\\n', '\\n').replaceAll('\\r', '\\n').replaceAll('\\t', ' ').split('\\n');\n while (lines.length > 0 && lines.at(-1)?.trim() === '') lines.pop();\n return { lines, ...(saved === undefined ? {} : { saved }), images };\n}\n\n/** Whether result text is a document, such as a report or a mermaid diagram, to draw rather than print. */\nexport function readsAsDocument(text: string): boolean {\n return DOCUMENT_LINE.test(text);\n}\n\n/** The header line for discover: what was asked for. */\nexport function discoverSummary(args: Readonly<Record<string, unknown>>): string {\n if (typeof args.namespace === 'string' && args.namespace !== '') return args.namespace;\n if (typeof args.query === 'string' && args.query !== '') return `find \"${clip(args.query, SUMMARY_MAX)}\"`;\n return 'namespaces and scripts';\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport { discoverSummary, discoverToolName } from '../_lib/execToolView';\n\nexport type DiscoverToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\n/** The discover tool's timeline item: folded to what was asked for, open to what came back. */\nexport function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }: DiscoverToolCardProps) {\n const declarations = typeof args.namespace === 'string' && args.namespace !== '' && !isError;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={discoverToolName}>\n <span data-testid={`tool-call-${discoverToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {discoverSummary(args)}\n </span>\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${discoverToolName}`} className=\"flex flex-col gap-2\">\n {running && output === '' ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n {output === '' ? null : declarations ? (\n <div className=\"max-h-96 overflow-auto\">\n <CodeBlock text={output} className=\"language-ts\" />\n </div>\n ) : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {output}\n </pre>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { DiscoverToolCard } from './_components/DiscoverToolCard';\n\nexport default defineToolRenderer({ message: DiscoverToolCard });\n","import type { ReactNode } from 'react';\n\n/** A labelled part of an expanded card body. */\nexport function ToolSection({ label, children }: { label: string; children: ReactNode }) {\n return (\n <section className=\"flex flex-col gap-1.5\">\n <h4 className=\"text-sm font-medium text-po-dim\">{label}</h4>\n {children}\n </section>\n );\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n Markdown,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport {\n callArgsSummary,\n execCalls,\n execCode,\n execResultView,\n execSummary,\n execToolName,\n readsAsDocument,\n type ExecCall,\n type ExecImage,\n} from '../_lib/execToolView';\nimport { ToolSection } from './ToolSection';\n\n/** Draws another tool's own card for a nested call, or nothing when no package owns one. */\nexport type RenderNestedTool = NonNullable<ToolMessageRenderProps['renderTool']>;\n\nexport type ExecToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\n/** The tree's elbow: a short branch from the rail to the item it leads to. */\nconst BRANCH =\n 'relative before:absolute before:top-[1.125rem] before:-left-4 before:w-3 before:border-t before:border-po-border-soft';\n\nconst SUMMARY =\n 'flex min-h-6 cursor-pointer list-none items-center gap-x-2 gap-y-0.5 [&::-webkit-details-marker]:hidden';\n\n/** The folding mark at the end of a summary; it turns when the section opens. */\nfunction Chevron() {\n return (\n <span aria-hidden className=\"w-3 shrink-0 text-center text-po-dim transition-transform group-open:rotate-90\">\n ›\n </span>\n );\n}\n\n/** Pictures and documents stay on screen whether or not their section is open: they are the point of the call. */\nfunction Visuals({ text, images, label }: { text: string; images: readonly ExecImage[]; label: string }) {\n return (\n <>\n {readsAsDocument(text) ? (\n <div data-testid=\"tool-output-document\" className=\"max-h-96 overflow-auto text-sm\">\n <Markdown text={text} />\n </div>\n ) : null}\n {images.map((image, index) => (\n <img\n key={`${image.mimeType}-${String(index)}`}\n src={`data:${image.mimeType};base64,${image.data}`}\n alt={`${label} image ${String(index + 1)}`}\n data-testid=\"tool-output-image\"\n className=\"max-h-48 max-w-full self-start rounded-md border border-po-border-soft\"\n />\n ))}\n </>\n );\n}\n\n/** One call on the rail. It opens to its whole args and result; its pictures and documents show either way. */\nfunction CallRow({ call }: { call: ExecCall }) {\n const view = execResultView(call.result ?? null);\n const text = view.lines.join('\\n');\n const printed = text !== '' && !readsAsDocument(text);\n const opens = Object.keys(call.args).length > 0 || printed;\n const head = (\n <>\n <span className=\"shrink-0 truncate font-mono font-semibold text-po-text max-sm:basis-full\">{call.name}</span>\n <span className=\"min-w-0 flex-1 truncate font-mono text-po-dim group-open:invisible\">\n {callArgsSummary(call.args)}\n </span>\n <span aria-hidden className={`w-3 shrink-0 text-center ${call.ok ? 'text-po-green' : 'text-po-red'}`}>\n {call.ok ? '✓' : '✗'}\n </span>\n <span className=\"sr-only\">{call.ok ? 'completed' : 'failed'}</span>\n <span className=\"w-16 shrink-0 text-right tabular-nums text-po-dim\">{call.ms} ms</span>\n </>\n );\n return (\n <div data-testid=\"exec-call\" className=\"flex flex-col gap-2 rounded-lg border border-po-border-soft px-3 py-2\">\n {opens ? (\n <details className=\"group text-sm\">\n <summary className={`${SUMMARY} flex-wrap`}>\n {head}\n <Chevron />\n </summary>\n <div className=\"mt-2 flex flex-col gap-2\">\n {Object.keys(call.args).length > 0 ? (\n <CodeBlock text={JSON.stringify(call.args, null, 2)} className=\"language-json\" />\n ) : null}\n {printed ? (\n <pre\n data-testid=\"exec-call-output\"\n className=\"max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap text-po-text\"\n >\n {text}\n </pre>\n ) : null}\n </div>\n </details>\n ) : (\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5 text-sm\">{head}</div>\n )}\n {call.error === undefined ? null : <p className=\"text-sm break-words text-po-red\">{call.error}</p>}\n <Visuals text={text} images={view.images} label={call.name} />\n </div>\n );\n}\n\n/** The script's outcome as the tree's last leaf: one line until opened, the whole text after; visuals always. */\nfunction Returned({ result, isError }: { result: ExecToolCardProps['result']; isError: boolean }) {\n const view = execResultView(result);\n const text = view.lines.join('\\n');\n const label = isError ? 'Error' : 'Returned';\n const ink = isError ? 'text-po-red' : 'text-po-text';\n return (\n <div data-testid={`tool-result-${execToolName}`} className=\"flex flex-col gap-2\">\n {view.lines.length === 0 ? (\n <p className=\"text-sm text-po-dim\">{isError ? 'Failed with no output.' : 'Returned nothing.'}</p>\n ) : readsAsDocument(text) ? (\n <p className=\"text-sm font-semibold text-po-dim\">{label}</p>\n ) : (\n <details open={isError} className=\"group text-sm\">\n <summary className={`${SUMMARY} text-po-dim hover:text-po-blue`}>\n <span className=\"shrink-0 font-semibold\">{label}</span>\n <span className={`min-w-0 flex-1 truncate font-mono group-open:hidden ${ink}`}>{view.lines.join(' ')}</span>\n <Chevron />\n </summary>\n <pre\n data-testid=\"tool-output\"\n className={`mt-1 max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${ink}`}\n >\n {text}\n </pre>\n </details>\n )}\n <Visuals text={text} images={view.images} label=\"Script\" />\n </div>\n );\n}\n\n/**\n * The exec tool's timeline item. The calls the script made hang under it as a\n * tree, each as the owning tool's own card when one exists, with what the\n * script returned as the last leaf. Opening the item shows the script itself.\n */\nexport function ExecToolCard({\n args,\n result,\n running,\n isError,\n defaultExpanded = false,\n renderTool,\n}: ExecToolCardProps) {\n const code = execCode(args);\n const saved = execResultView(result).saved;\n const calls = execCalls(result?.details);\n const failed = calls.filter((call) => !call.ok).length;\n const settled = !running || result !== null;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={code !== ''} defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={execToolName}>\n <span data-testid={`tool-call-${execToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {execSummary(args)}\n </span>\n {calls.length > 0 ? (\n <span className=\"shrink-0 text-sm text-po-dim\">\n {calls.length} {calls.length === 1 ? 'call' : 'calls'}\n {failed > 0 ? <span className=\"text-po-red\">, {failed} failed</span> : null}\n </span>\n ) : null}\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody className=\"flex flex-col gap-2\">\n <ToolSection label=\"Code\">\n <CodeBlock text={code} className=\"language-ts\" />\n </ToolSection>\n {saved === undefined ? null : (\n <p className=\"text-sm text-po-dim\" title={saved.path}>\n Saved as <span className=\"font-mono text-po-text\">{saved.id}</span>\n </p>\n )}\n </MessageItemBody>\n ) : null}\n {settled ? (\n <ol\n aria-label=\"Script calls\"\n className=\"mx-4 mb-3 flex flex-col gap-2 border-l border-po-border-soft pl-4 sm:ml-[2.125rem]\"\n >\n {calls.map((call, index) => {\n const card =\n call.tool === undefined || renderTool === undefined\n ? null\n : renderTool({\n toolName: call.tool,\n args: call.args,\n result: call.result ?? null,\n isError: !call.ok,\n });\n // ponytail: another tool's card folds as it likes, so its pictures are repeated under it and\n // may show twice while it is open; drop this once cards keep pictures visible when folded.\n return (\n <li key={`${String(index)}-${call.name}`} className={`${BRANCH} flex flex-col gap-2`}>\n {card === null ? (\n <CallRow call={call} />\n ) : (\n <>\n {card}\n <Visuals text=\"\" images={execResultView(call.result ?? null).images} label={call.name} />\n </>\n )}\n </li>\n );\n })}\n <li className={BRANCH}>\n <Returned result={result} isError={isError} />\n </li>\n </ol>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { ExecToolCard } from './_components/ExecToolCard';\n\nexport default defineToolRenderer({ message: ExecToolCard });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport toolDiscover from '../src/extensions/workspaces/sessions/(frontend)/tool/discover.web';\nimport toolExec from '../src/extensions/workspaces/sessions/(frontend)/tool/exec.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: 'codemode',\n session: {\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['discover'] }, toolDiscover), via({ tools: ['exec'] }, toolExec)]; },\n },\n});\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_codemodeTools = require("./codemodeTools-A-6aAXeW.cjs");
2
+ const require_codemodeTools = require("./codemodeTools-DS37CHwZ.cjs");
3
3
  exports.createCodemodeRegistry = require_codemodeTools.createCodemodeRegistry;
4
4
  exports.createCodemodeTools = require_codemodeTools.createCodemodeTools;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;cAWd,0BAAwB,KAAA;;;;cAYxB,sBAAoB,KAAA;;;;;;;UC9BhB;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;UCwC5C;WACN,UAAU;;WAEV,eAAe;;WAEf,UAAU;WACV,YAAY;WACZ,SAAS;WACT;;UAGM;WACN,UAAU,sBAAsB;WAChC,MAAM,sBAAsB;WAC5B,gBAAgB,sBAAsB;WACtC,YAAY,sBAAsB;WAClC,gBAAgB;EACzB,WAAW;;;wBA0KG,sBACd,UACA,SACA,SACA,KACA,QAAQ,iBACR,sBACC,uBAAuB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;cAWd,0BAAwB,KAAA;;;;cAYxB,sBAAoB,KAAA;;;;;;;UC9BhB;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;UCwC5C;WACN,UAAU;;WAEV,eAAe;;WAEf,UAAU;WACV,YAAY;WACZ,SAAS;WACT;;UAGM;WACN,UAAU,sBAAsB;WAChC,MAAM,sBAAsB;WAC5B,gBAAgB,sBAAsB;WACtC,YAAY,sBAAsB;WAClC,gBAAgB;EACzB,WAAW;;;wBA+MG,sBACd,UACA,SACA,SACA,KACA,QAAQ,iBACR,sBACC,uBAAuB"}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-gfHLLrAt.mjs";
1
+ export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-D8hq2sv2.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-codemode",
3
- "version": "0.0.1-alpha.13",
3
+ "version": "0.0.1-alpha.15",
4
4
  "description": "Code mode for Po sessions: discover and exec over namespaces other packages contribute",
5
5
  "keywords": [
6
6
  "ai",
@@ -38,6 +38,9 @@
38
38
  "import": "./dist/apiContracts.mjs",
39
39
  "require": "./dist/apiContracts.cjs"
40
40
  },
41
+ "./extensions/native": {
42
+ "import": "./dist/extensions/native.mjs"
43
+ },
41
44
  "./extensions/server": {
42
45
  "types": "./dist/extensions/server.d.mts",
43
46
  "import": "./dist/extensions/server.mjs",
@@ -52,38 +55,61 @@
52
55
  "access": "public"
53
56
  },
54
57
  "dependencies": {
55
- "@agimon-ai/po-config": "0.0.0-alpha.40",
56
- "@agimon-ai/po-core": "0.0.0-alpha.40",
57
- "@agimon-ai/po-web-components": "0.0.0-alpha.40",
58
+ "@agimon-ai/po-config": "0.0.0-alpha.42",
59
+ "@agimon-ai/po-core": "0.0.0-alpha.42",
60
+ "@agimon-ai/po-web-components": "0.0.0-alpha.42",
58
61
  "@deepseek-ai/cordis": "4.0.5",
59
62
  "react": "19.3.1",
60
63
  "typebox": "1.4.2"
61
64
  },
62
65
  "devDependencies": {
63
- "@agimon-ai/po-build": "0.0.0-alpha.40",
64
- "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.40",
65
- "@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.40",
66
- "@earendil-works/pi-coding-agent": "1.3.0",
66
+ "@agimon-ai/po-build": "0.0.0-alpha.42",
67
+ "@agimon-ai/po-native-components": "0.0.0-alpha.42",
68
+ "@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.42",
69
+ "@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.42",
70
+ "@earendil-works/pi-coding-agent": "1.4.0",
67
71
  "@types/node": "26.6.5",
68
72
  "@types/react": "19.3.0",
69
73
  "@types/react-dom": "19.3.0",
70
74
  "@vitest/coverage-v8": "5.0.4",
71
75
  "react-dom": "19.3.1",
76
+ "react-native": "0.88.0",
77
+ "react-native-unistyles": "3.5.3",
72
78
  "tsdown": "0.23.1",
73
79
  "typescript": "7.0.2",
74
80
  "vitest": "5.0.4"
75
81
  },
76
82
  "peerDependencies": {
77
- "@earendil-works/pi-coding-agent": "1.3.0"
83
+ "@agimon-ai/po-native-components": "0.0.0-alpha.42",
84
+ "@earendil-works/pi-coding-agent": "1.4.0",
85
+ "react-native": "0.88.0",
86
+ "react-native-unistyles": "^3.5.3"
78
87
  },
79
88
  "peerDependenciesMeta": {
89
+ "@agimon-ai/po-native-components": {
90
+ "optional": true
91
+ },
80
92
  "@earendil-works/pi-coding-agent": {
81
93
  "optional": true
94
+ },
95
+ "react-native": {
96
+ "optional": true
97
+ },
98
+ "react-native-unistyles": {
99
+ "optional": true
82
100
  }
83
101
  },
84
102
  "engines": {
85
103
  "node": ">=24"
86
104
  },
105
+ "poNative": {
106
+ "pluginId": "codemode",
107
+ "channels": [],
108
+ "client": "./dist/extensions/native.mjs",
109
+ "scopes": [
110
+ "session"
111
+ ]
112
+ },
87
113
  "poServer": {
88
114
  "entry": "./generated/server.ts",
89
115
  "dist": "./dist/extensions/server.mjs",
@@ -111,7 +137,7 @@
111
137
  "scripts": {
112
138
  "build": "tsdown",
113
139
  "test": "vitest --run",
114
- "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
140
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json && tsc --noEmit -p tsconfig.native.json",
115
141
  "lint": "oxlint . && oxfmt . --check",
116
142
  "fixcode": "oxlint . --fix && oxfmt ."
117
143
  }