@agimon-ai/po-plan 0.0.0-alpha.98 → 0.0.0-alpha.99

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,4 +1,4 @@
1
- import { createApiClient, defineActivityGroup, defineFill, defineNativePlugin, defineToolRenderer, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
1
+ import { createApiClient, defineActivityGroup, defineFill, defineNativePlugin, defineSettingsSection, defineToolRenderer, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
2
2
  import { View } from "react-native-unistyles/components/native/View";
3
3
  import { Text } from "react-native-unistyles/components/native/Text";
4
4
  import { Button, ChevronDownIcon, ChevronRightIcon, ListRow, Markdown, MessageItem, MessageItemBody, MessageItemHeader, Panel, SegmentedControl, Textarea, fontOf, toolTone } from "@agimon-ai/po-native-components";
@@ -6,6 +6,127 @@ import { StyleSheet } from "react-native-unistyles";
6
6
  import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
7
7
  import { useEffect, useState } from "react";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/types/planSettings.ts
10
+ /**
11
+ * The planning settings, described once for both surfaces.
12
+ *
13
+ * The terminal panel and the cockpit settings page render the same five fields,
14
+ * and the one thing they must agree on is which config key each one writes. So
15
+ * the ids, labels and key paths live here rather than in either renderer.
16
+ *
17
+ * It lives under src/types because that is the one server root a browser bundle
18
+ * may read, which also means it may import nothing: pulling the config package
19
+ * in for the thinking levels would drag a node module into the page. They are
20
+ * spelled out instead, and a test asserts they still match the parser's.
21
+ */
22
+ const PLAN_CONFIG_SECTION_ID = "planning";
23
+ const PLANNING_PATH = ["modes", PLAN_CONFIG_SECTION_ID];
24
+ const MAIN_KEY = "main";
25
+ const SUBAGENTS_KEY = "subagents";
26
+ /** Both agents fall back to the session's own settings when left unset. */
27
+ const INHERIT_MODEL = "inherit the session model";
28
+ const INHERIT_THINKING = "inherit";
29
+ /** Mirrors PO_PLANNING_THINKING_LEVELS; pinned by planConfig's test. */
30
+ const PLAN_THINKING_LEVELS = [
31
+ "off",
32
+ "minimal",
33
+ "low",
34
+ "medium",
35
+ "high",
36
+ "xhigh",
37
+ "max"
38
+ ];
39
+ //#endregion
40
+ //#region src/extensions/(frontend)/_lib/planSettings.ts
41
+ /**
42
+ * The planning settings, as the cockpit's settings page renders them.
43
+ *
44
+ * Built from the same descriptor table the terminal panel uses, so the two
45
+ * surfaces cannot disagree about which config key a field writes. The host owns
46
+ * the scope switch and the writes; this only says what the fields are.
47
+ */
48
+ const planSettingsSection = {
49
+ id: PLAN_CONFIG_SECTION_ID,
50
+ label: "planning",
51
+ detail: "the models plan mode switches to, and where written plans land",
52
+ order: 30,
53
+ fields: [
54
+ {
55
+ id: "main.model",
56
+ label: "main model",
57
+ keyPath: [
58
+ ...PLANNING_PATH,
59
+ MAIN_KEY,
60
+ "model"
61
+ ],
62
+ placeholder: INHERIT_MODEL,
63
+ detail: "model the main agent switches to while plan mode is on.",
64
+ models: true
65
+ },
66
+ {
67
+ id: "main.thinking",
68
+ label: "main thinking",
69
+ keyPath: [
70
+ ...PLANNING_PATH,
71
+ MAIN_KEY,
72
+ "thinking"
73
+ ],
74
+ placeholder: INHERIT_THINKING,
75
+ detail: "thinking level appended to the main model while planning.",
76
+ options: PLAN_THINKING_LEVELS
77
+ },
78
+ {
79
+ id: "subagents.model",
80
+ label: "subagent model",
81
+ keyPath: [
82
+ ...PLANNING_PATH,
83
+ SUBAGENTS_KEY,
84
+ "model"
85
+ ],
86
+ placeholder: INHERIT_MODEL,
87
+ detail: "model forced onto delegated planning subagents.",
88
+ models: true
89
+ },
90
+ {
91
+ id: "subagents.thinking",
92
+ label: "subagent thinking",
93
+ keyPath: [
94
+ ...PLANNING_PATH,
95
+ SUBAGENTS_KEY,
96
+ "thinking"
97
+ ],
98
+ placeholder: INHERIT_THINKING,
99
+ detail: "thinking level appended to the subagent model.",
100
+ options: PLAN_THINKING_LEVELS
101
+ },
102
+ {
103
+ id: "plansdirectory",
104
+ label: "plans directory",
105
+ keyPath: [...PLANNING_PATH, "plansDirectory"],
106
+ placeholder: "~/.po/plans",
107
+ detail: "absolute, repo-relative, or under ~. written plans land here."
108
+ }
109
+ ].map((shape) => ({
110
+ id: shape.id,
111
+ label: shape.label,
112
+ kind: shape.models === true || shape.options !== void 0 ? "select" : "text",
113
+ keyPath: shape.keyPath,
114
+ detail: shape.detail,
115
+ placeholder: shape.placeholder,
116
+ ...shape.models === true ? { optionsFrom: "models" } : {},
117
+ ...shape.options === void 0 ? {} : { options: shape.options.map((option) => ({
118
+ value: option,
119
+ label: option
120
+ })) }
121
+ }))
122
+ };
123
+ //#endregion
124
+ //#region src/extensions/(frontend)/setting/plan.native.ts
125
+ var plan_native_default$3 = defineSettingsSection(planSettingsSection);
126
+ //#endregion
127
+ //#region src/extensions/workspaces/(frontend)/setting/plan.native.ts
128
+ var plan_native_default$2 = defineSettingsSection(planSettingsSection);
129
+ //#endregion
9
130
  //#region src/types/planApi.ts
10
131
  /**
11
132
  * Footer status key the session publishes once a plan exists, which is what
@@ -901,6 +1022,12 @@ const via = (identity, value) => value === void 0 ? void 0 : {
901
1022
  };
902
1023
  const nativePlugin = defineNativePlugin({
903
1024
  id: "plan",
1025
+ global: { get settingsSections() {
1026
+ return [via({ id: "plan" }, plan_native_default$3)];
1027
+ } },
1028
+ workspace: { get settingsSections() {
1029
+ return [via({ id: "plan" }, plan_native_default$2)];
1030
+ } },
904
1031
  session: {
905
1032
  get activityGroups() {
906
1033
  return [via({ name: "plan" }, plan_native_default$1)];
@@ -1 +1 @@
1
- {"version":3,"file":"native.mjs","names":["WebPluginSlotProps","Button","Markdown","SegmentedControl","Textarea","fontOf","PoNativeTheme","useEffect","useState","StyleSheet","PLAN_STATUS_KEY","PlanDetailView","fetchPlan","savePlan","PLAN_TAB_ID","PlanPanel","sessionId","statuses","closeTransientTab","fileTabFor","openTransientTab","detail","setDetail","error","setError","loading","setLoading","view","setView","draft","setDraft","saving","setSaving","note","setNote","revision","cancelled","then","result","ok","undefined","catch","failure","Error","message","String","save","unavailable","hash","refreshed","styles","panel","title","value","label","meta","reason","content","path","tab","actions","success","planTab","Parameters","id","create","theme","padding","spacing","gap","uni__dependencies","fontFamily","sans","fontSize","lg","lineHeight","fontWeight","color","colors","hi","sm","dim","mono","red","green","flexDirection","flexWrap","styles","WebPluginSlotProps","ListRow","fontOf","PoNativeTheme","StyleSheet","parsePlanStatus","PLAN_STATUS_KEY","planTab","PlanActivitySection","sessionId","statuses","openTransientTab","view","styles","meta","title","stamp","undefined","create","theme","fontFamily","sans","fontSize","sm","lineHeight","color","colors","dim","uni__dependencies","styles","ToolPromptRenderProps","Button","ChevronDownIcon","ChevronRightIcon","fontOf","Panel","PoNativeTheme","useState","StyleSheet","PlanReviewPrompt","dialog","answer","cancel","defaultExpanded","open","setOpen","styles","prompt","header","expanded","label","description","pending","scroll","content","title","options","map","option","index","footer","create","theme","flexShrink","margin","spacing","uni__dependencies","flexDirection","alignItems","justifyContent","paddingHorizontal","paddingVertical","borderRadius","marginLeft","fontFamily","sans","fontSize","sm","lineHeight","fontWeight","semibold","color","colors","dim","flexGrow","gap","paddingBottom","base","hi","padding","borderTopWidth","borderTopColor","styles","ToolMessageRenderProps","fontOf","MessageItem","MessageItemBody","MessageItemHeader","toolTone","PoNativeTheme","StyleSheet","LineTone","planCallSummary","planFailureReason","planResultLines","ToolLine","PlanToolMessage","toolName","args","result","running","isError","summary","collapsed","expanded","isPartial","full","reason","primary","detail","secondary","metadata","length","action","styles","undefined","sans","join","error","lines","map","entry","index","String","text","ToneLine","TONE_STYLE","tone","bold","indent","EvidenceGroup","label","values","evidenceGroups","groups","push","slice","trimStart","EvidenceBody","status","facts","evidence","group","value","create","theme","flex","flexDirection","alignItems","gap","spacing","minWidth","uni__dependencies","fontFamily","fontSize","base","lineHeight","flexShrink","maxWidth","color","colors","faint","paddingTop","borderTopWidth","borderTopColor","sm","fontWeight","semibold","dim","paddingLeft","red","hi","muted","success","green","warning","yellow","accent","blue","Readonly","Record","activityGroupPlan","fillPlan","toolPlan"],"sources":["../../src/types/planApi.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/planApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanReviewPrompt.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/planToolRender.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanToolMessage.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/plan.native.tsx","../../generated/native.ts"],"sourcesContent":["/**\n * The wire vocabulary this package's API shares with whatever calls it.\n *\n * It lives under src/types because that is the one server root a browser\n * bundle may read: the routes answer with these shapes and the cockpit plugin\n * reads them, so neither half can drift from the other. The paths themselves\n * are not here; they are declared once in `./apiRoutes`, which the Hono app\n * and the generated client both read.\n *\n * Two routes, and neither takes a path. A session has one current plan, so\n * `current` answers it and `content` takes the manual save back; the file they\n * act on is the one write_plan recorded, never one the page named. That is\n * also why there is nothing to escape here: a reader cannot address a second\n * file through these URLs.\n */\n\n/** Where a host mounts this package's API; the segment after /api/plugins/. */\nexport const API_BASE_PATH = 'plans';\n\n/**\n * Footer status key the session publishes once a plan exists, which is what\n * makes the cockpit's activity group appear at all. It outlives plan mode: the\n * plan is most worth reading while the agent implements it.\n */\nexport const PLAN_STATUS_KEY = 'po-plan-document';\n\n/** The selector contract shared by complete_plan and its cockpit composer prompt. */\nexport const PLAN_REVIEW_TITLE = 'Plan complete. What would you like to do?';\nexport const EXIT_PLAN_MODE_CHOICE = 'Exit plan mode and start implementation';\nexport const CONTINUE_PLANNING_CHOICE = 'Continue planning';\nexport const EXIT_PLAN_DECISION = 'exit';\nexport const CONTINUE_PLAN_DECISION = 'continue';\n\n/**\n * The label the reader sees paired with the decision the tool acts on. A headless\n * client answers with `value`, so a server plugin never has to recognise the wording; Pi's\n * own `ui.select` carries labels only, so its half maps the label back itself.\n */\nexport const PLAN_REVIEW_CHOICES = [\n { label: EXIT_PLAN_MODE_CHOICE, value: EXIT_PLAN_DECISION },\n { label: CONTINUE_PLANNING_CHOICE, value: CONTINUE_PLAN_DECISION },\n] as const;\n\n/** The same options as bare labels, which is all Pi's select and the composer prompt need. */\nexport const PLAN_REVIEW_OPTIONS = PLAN_REVIEW_CHOICES.map((choice) => choice.label);\n\n/** Between the plan's title and the stamp that marks a rewrite. */\nconst STATUS_SEPARATOR = ' · ';\n\n/** Strips the colour a session may have themed a status with. */\nconst ANSI = /\u001b\\[[0-9;]*m/gu;\n\n/** The status line the session publishes; the stamp changes on every write. */\nexport function formatPlanStatus(title: string, stamp: string): string {\n return `${title}${STATUS_SEPARATOR}${stamp}`;\n}\n\n/** What a reader gets out of the status line. */\nexport interface PlanStatusView {\n title: string;\n /** When the plan was last written, as the session worded it; empty when it said nothing. */\n stamp: string;\n}\n\n/**\n * Reading the status line back. Statuses reach a plugin raw, so the colour a\n * session may have added comes off here. A title can itself contain the\n * separator, so the stamp is taken from the last one rather than the first.\n */\nexport function parsePlanStatus(raw: string | undefined): PlanStatusView | undefined {\n if (raw === undefined) return undefined;\n const text = raw.replace(ANSI, '').trim();\n if (text === '') return undefined;\n const cut = text.lastIndexOf(STATUS_SEPARATOR);\n if (cut === -1) return { title: text, stamp: '' };\n return { title: text.slice(0, cut).trim(), stamp: text.slice(cut + STATUS_SEPARATOR.length).trim() };\n}\n\n/**\n * What write_plan recorded about this session's plan.\n *\n * The absolute path is the point of it: the extension resolves the plans\n * directory against the harness root, which no other process knows, so it\n * writes down where the plan landed rather than leaving the API to derive a\n * location it would sometimes get wrong.\n */\nexport interface PlanPointerRecord {\n path: string;\n title: string;\n writtenAt: string;\n planId?: string;\n}\n\n/** The plan as it stands on disk right now, which is what the source view edits. */\nexport interface PlanDetailView {\n path: string;\n title: string;\n writtenAt: string;\n planId?: string;\n content: string;\n /** sha256 of the content; the token a save hands back to prove it is not stale. */\n hash: string;\n /** True when the plan is missing or past the size cap, so `content` is empty. */\n unavailable: boolean;\n reason?: string;\n}\n\n/** What the save route takes. */\nexport interface PlanSaveRequest {\n /** The hash the reader loaded; a mismatch means the plan moved underneath them. */\n expectedHash: string;\n content: string;\n}\n\n/** What the save route answers with. */\nexport interface PlanSaveView {\n hash: string;\n}\n\n/** What a route reports when it refuses; the page shows `error` verbatim. */\nexport interface PlanErrorView {\n error: string;\n /** On a stale save, the hash the plan actually has now. */\n hash?: string;\n}\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\n\nimport { PLAN_STATUS_KEY } from '../../../../../types/planApi';\n\n// Keyed off the saved plan rather than the mode because the plan remains useful\n// while it is being implemented after the read-only mode exits.\nexport default defineActivityGroup({\n name: 'plan',\n keys: 'p e',\n statusKey: PLAN_STATUS_KEY,\n marksBackgroundWork: false,\n order: 25,\n});\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { PlanDetailView, PlanSaveView } from './planApi';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/workspaces/sessions/(backend)/api/plans/`, so the mount is\n * stated once, by the folder that creates it. The paths used to be written\n * here as helpers, again in the contract, and again inside every URL the page\n * built, and the copies were free to disagree.\n *\n * This is the one file the routes, the Hono app and the browser all read, so a\n * path cannot move on one side alone.\n *\n * Neither route takes a query or a path parameter: a session has one current\n * plan, so `current` answers it and `save` takes the manual write back.\n */\nconst routes = {\n current: {\n method: 'GET',\n path: '/current',\n response: undefined as unknown as ApiResponseOf<PlanDetailView>,\n },\n save: {\n method: 'PUT',\n path: '/content',\n response: undefined as unknown as ApiResponseOf<PlanSaveView>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'plans' at. */\nexport const apiScopes = ['session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'plans',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import { api } from '../../../../../../../generated/client.native';\nimport type { PlanDetailView } from '../../../../../../types/planApi';\n\n/**\n * The page's half of this package's session API: the current plan, and the\n * manual save.\n *\n * These are adapters now, not a transport. The generated client owns the URL\n * and the sealed transport with it, so nothing here spells a route or reaches\n * for `fetch`. What stays is this package's own vocabulary: which refusals the\n * reader is shown, and the stale-save contract the editor depends on.\n */\n\nconst UNREACHABLE = 'The session is unreachable.';\nconst NO_PLAN = 'This session has not written a plan yet.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The message a reader is shown: the route's own words, or why there were none. */\nfunction messageOf(result: { status: number; error: string }): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === '' ? `The session answered ${String(result.status)}.` : result.error;\n}\n\nexport type FetchPlanResult = { ok: true; detail: PlanDetailView } | { ok: false; error: string };\n\nexport async function fetchPlan(sessionId: string): Promise<FetchPlanResult> {\n const result = await api.session(sessionId).current();\n // A session that has written nothing answers 404, which is not a failure the\n // reader should be shown as one.\n if (result.status === 404) return { ok: false, error: result.ok || result.error === '' ? NO_PLAN : result.error };\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data)) return { ok: false, error: 'The session answered with no plan.' };\n return { ok: true, detail: result.data };\n}\n\nexport type SavePlanResult =\n | { ok: true; hash: string }\n /** The plan moved under the editor; `hash` is what it holds now. */\n | { ok: false; stale: true; error: string; hash?: string }\n | { ok: false; stale: false; error: string };\n\nexport async function savePlan(sessionId: string, expectedHash: string, content: string): Promise<SavePlanResult> {\n const result = await api.session(sessionId).save({ body: { expectedHash, content } });\n // The agent can rewrite the plan while a reader is still editing it. A moved\n // hash is the one refusal the editor recovers from, so it is read before the\n // generic failure.\n if (result.status === 409) {\n const data = result.ok ? undefined : result.data;\n const hash = isRecord(data) && typeof data.hash === 'string' ? data.hash : undefined;\n return {\n ok: false,\n stale: true,\n error: result.ok ? 'The plan changed since it was opened.' : messageOf(result),\n ...(hash === undefined ? {} : { hash }),\n };\n }\n if (!result.ok) return { ok: false, stale: false, error: messageOf(result) };\n return { ok: true, hash: isRecord(result.data) && typeof result.data.hash === 'string' ? result.data.hash : '' };\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, Markdown, SegmentedControl, Textarea, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useEffect, useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { PLAN_STATUS_KEY, type PlanDetailView } from '../../../../../../types/planApi';\nimport { fetchPlan, savePlan } from '../_lib/planApi.native';\n\nexport const PLAN_TAB_ID = 'plan-document';\n\n/** The saved plan, with edits guarded by its on-disk hash, never a caller-supplied path. */\nexport function PlanPanel({\n sessionId,\n statuses,\n closeTransientTab,\n fileTabFor,\n openTransientTab,\n}: WebPluginSlotProps) {\n const [detail, setDetail] = useState<PlanDetailView>();\n const [error, setError] = useState<string>();\n const [loading, setLoading] = useState(true);\n const [view, setView] = useState('preview');\n const [draft, setDraft] = useState<string>();\n const [saving, setSaving] = useState(false);\n const [note, setNote] = useState<string>();\n const revision = statuses[PLAN_STATUS_KEY];\n useEffect(() => {\n if (sessionId === null) return;\n let cancelled = false;\n void fetchPlan(sessionId)\n .then((result) => {\n if (cancelled) return;\n setLoading(false);\n if (result.ok) {\n setDetail(result.detail);\n setError(undefined);\n setDraft(undefined);\n setNote(undefined);\n } else {\n setDetail(undefined);\n setError(result.error);\n }\n })\n .catch((failure: unknown) => {\n if (!cancelled) {\n setLoading(false);\n setError(failure instanceof Error ? failure.message : String(failure));\n }\n });\n return () => {\n cancelled = true;\n };\n }, [sessionId, revision]);\n\n const save = async () => {\n if (sessionId === null || !detail || draft === undefined || detail.unavailable || saving) return;\n setSaving(true);\n try {\n const result = await savePlan(sessionId, detail.hash, draft);\n if (!result.ok) {\n setNote(result.error);\n return;\n }\n setNote('saved');\n const refreshed = await fetchPlan(sessionId);\n if (refreshed.ok) {\n setDetail(refreshed.detail);\n setDraft(undefined);\n } else setError(refreshed.error);\n } catch (failure) {\n setNote(failure instanceof Error ? failure.message : String(failure));\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <ScrollView contentContainerStyle={styles.panel} testID=\"plan-panel\">\n <Text style={styles.title}>{detail?.title ?? 'plan'}</Text>\n <SegmentedControl\n accessibilityLabel=\"plan view\"\n options={[\n { value: 'preview', label: 'preview' },\n { value: 'source', label: 'source' },\n ]}\n value={view}\n onValueChange={setView}\n />\n {sessionId === null ? (\n <Text style={styles.meta}>Select a session.</Text>\n ) : loading && !detail ? (\n <Text style={styles.meta}>reading this session's plan…</Text>\n ) : null}\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {detail ? (\n detail.unavailable ? (\n <Text style={styles.meta}>{detail.reason ?? 'this plan cannot be shown'}</Text>\n ) : view === 'preview' ? (\n <Markdown\n text={draft ?? detail.content}\n onFileLink={(path) => {\n const tab = fileTabFor(path);\n return tab ? () => openTransientTab(tab) : undefined;\n }}\n />\n ) : (\n <>\n <Textarea\n accessibilityLabel=\"plan source\"\n value={draft ?? detail.content}\n onChangeText={setDraft}\n numberOfLines={12}\n />\n <View style={styles.actions}>\n <Button variant=\"primary\" disabled={draft === undefined || saving} onPress={() => void save()}>\n save to disk\n </Button>\n {draft !== undefined ? (\n <Button variant=\"ghost\" onPress={() => setDraft(undefined)}>\n discard edits\n </Button>\n ) : null}\n </View>\n {note ? <Text style={note === 'saved' ? styles.success : styles.error}>{note}</Text> : null}\n </>\n )\n ) : null}\n {detail ? (\n <Text selectable style={styles.path}>\n {detail.path}\n </Text>\n ) : null}\n <Button variant=\"ghost\" onPress={() => closeTransientTab(PLAN_TAB_ID)}>\n close\n </Button>\n </ScrollView>\n );\n}\n\nexport function planTab(): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return { id: PLAN_TAB_ID, label: 'plan', panel: PlanPanel };\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n panel: { padding: theme.spacing(4), gap: theme.spacing(3) },\n title: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.lg,\n lineHeight: theme.lineHeight.lg,\n fontWeight: '600',\n color: theme.colors.hi,\n },\n meta: { fontSize: theme.fontSize.sm, lineHeight: theme.lineHeight.sm, color: theme.colors.dim },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontSize: theme.fontSize.sm, color: theme.colors.red },\n success: { fontSize: theme.fontSize.sm, color: theme.colors.green },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: theme.spacing(2) },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { ListRow, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { parsePlanStatus, PLAN_STATUS_KEY } from '../../../../../../types/planApi';\nimport { planTab } from './PlanPanel.native';\n\n/** The document row, not its group header, is the way into a saved plan. */\nexport function PlanActivitySection({ sessionId, statuses, openTransientTab }: WebPluginSlotProps) {\n const view = parsePlanStatus(statuses[PLAN_STATUS_KEY]);\n if (!view) return <Text style={styles.meta}>no plan written yet</Text>;\n return (\n <View testID=\"activity-plan\">\n <ListRow\n title={view.title}\n description={view.stamp || undefined}\n disabled={sessionId === null}\n onPress={() => {\n if (sessionId !== null) openTransientTab(planTab());\n }}\n />\n <Text style={styles.meta}>open to read or edit; the agent reads what you save.</Text>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n meta: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { PlanActivitySection } from './_components/PlanActivitySection.native';\n\nexport default defineFill({ slot: 'activity.plan', id: 'plan', component: PlanActivitySection });\n","import type { ToolPromptRenderProps } from '@agimon-ai/po-core/native';\nimport { Button, ChevronDownIcon, ChevronRightIcon, fontOf, Panel } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type {} from '../../../../../../types/unistyles.native';\n\nexport function PlanReviewPrompt({\n dialog,\n answer,\n cancel,\n defaultExpanded = true,\n}: ToolPromptRenderProps & { defaultExpanded?: boolean }) {\n const [open, setOpen] = useState(defaultExpanded);\n return (\n <Panel style={styles.prompt} testID=\"plan-review-prompt\" onAccessibilityEscape={cancel}>\n <Button\n variant=\"ghost\"\n size=\"card\"\n style={styles.header}\n accessibilityLabel={open ? 'Collapse plan review' : 'Expand plan review'}\n accessibilityState={{ expanded: open }}\n aria-expanded={open}\n onPress={() => setOpen(!open)}\n >\n <Text style={styles.label}>Plan review</Text>\n {!open ? <Text style={[styles.description, styles.pending]}>Awaiting decision</Text> : null}\n {open ? <ChevronDownIcon size={16} /> : <ChevronRightIcon size={16} />}\n </Button>\n {open ? (\n <>\n <ScrollView style={styles.scroll} contentContainerStyle={styles.content} keyboardShouldPersistTaps=\"handled\">\n <Text style={styles.title} accessibilityRole=\"header\">\n {dialog.title}\n </Text>\n <Text style={styles.description}>\n Review the plan in the conversation before choosing what happens next.\n </Text>\n {dialog.options.map((option, index) => (\n <Button\n key={option}\n variant=\"outline\"\n size=\"card\"\n testID={`plan-review-option-${index}`}\n onPress={() => answer(option)}\n >\n {option}\n </Button>\n ))}\n </ScrollView>\n <View style={styles.footer}>\n <Button variant=\"ghost\" size=\"card\" testID=\"plan-review-cancel\" onPress={cancel}>\n Cancel\n </Button>\n </View>\n </>\n ) : null}\n </Panel>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n prompt: { flexShrink: 1, margin: theme.spacing(4) },\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: theme.spacing(3),\n paddingVertical: theme.spacing(2),\n borderRadius: 0,\n },\n pending: { marginLeft: 'auto' },\n label: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.dim,\n },\n scroll: { flexGrow: 0, flexShrink: 1 },\n content: { gap: theme.spacing(3), paddingHorizontal: theme.spacing(3), paddingBottom: theme.spacing(3) },\n title: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.hi,\n },\n description: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n footer: {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n padding: theme.spacing(2),\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n },\n}));\n","import type { ToolPromptDialog, ToolResultView } from '@agimon-ai/po-core/web';\nimport type { MessageLine, MessageLineTone } from '@agimon-ai/po-web-components';\n\nimport { PLAN_REVIEW_OPTIONS, PLAN_REVIEW_TITLE } from '../../../../../../types/planApi';\n\n/**\n * Purpose-first summaries for the plan-mode tools. The TUI leaves these on\n * Pi's default shell, so the shapes here come straight from the tool\n * definitions in src/services/planServerSession/index.ts: write_plan and complete_plan\n * report through `details` (written, path, phase, exited), run_fable_plan\n * carries the broker result, and record_debug_evidence only confirms.\n */\n\nexport const PLAN_TOOL_NAMES = ['record_debug_evidence', 'run_fable_plan', 'write_plan', 'complete_plan'] as const;\n\n/** Claims only the selector opened by complete_plan, on either platform. */\nexport function claimsPlanReviewPrompt(dialog: ToolPromptDialog): boolean {\n return (\n dialog.method === 'select' &&\n dialog.title === PLAN_REVIEW_TITLE &&\n dialog.options.length === PLAN_REVIEW_OPTIONS.length &&\n PLAN_REVIEW_OPTIONS.every((option, index) => dialog.options[index] === option)\n );\n}\n\n/** The toned lines the shared MessageLines draws; the vocabulary is the components package's. */\nexport type LineTone = MessageLineTone;\n/** `label` names an evidence field the text leads with, so a layout can set it apart without parsing the text. */\nexport type ToolLine = MessageLine & { label?: string };\n\nexport interface PlanCallSummary {\n action: string;\n detail?: string;\n metadata: string[];\n}\n\nexport interface PlanRenderOptions {\n expanded: boolean;\n isError: boolean;\n isPartial: boolean;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nconst COLLAPSED_BODY_LINES = 12;\nconst PREVIEW_LENGTH = 72;\n\nconst EVIDENCE_LISTS: ReadonlyArray<[key: string, label: string]> = [\n ['logs', 'log'],\n ['correlatedTraceEvidence', 'trace'],\n ['processOutput', 'process output'],\n ['browserConsoleEvidence', 'console entry'],\n ['correlationIds', 'correlation id'],\n ['timestamps', 'timestamp'],\n ['verifiedFacts', 'verified fact'],\n ['hypotheses', 'hypothesis'],\n ['unavailableEvidence', 'unavailable item'],\n];\n\nconst PACKET_LISTS: ReadonlyArray<[key: string, label: string]> = [\n ['goal', 'goal'],\n ['constraints', 'constraint'],\n ['decisions', 'decision'],\n ['verifiedFindings', 'verified finding'],\n ['inferredFindings', 'inferred finding'],\n ['unresolvedQuestions', 'open question'],\n];\n\nfunction asRecord(value: unknown): JsonRecord | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as JsonRecord) : undefined;\n}\n\nfunction inlineText(value: string): string {\n let normalized = '';\n for (const character of value) {\n const code = character.codePointAt(0) ?? 0;\n normalized += code <= 31 || code === 127 ? ' ' : character;\n }\n return normalized.replace(/\\s+/gu, ' ').trim();\n}\n\nfunction readString(record: JsonRecord | undefined, key: string): string | undefined {\n const value = record?.[key];\n return typeof value === 'string' ? inlineText(value) || undefined : undefined;\n}\n\nfunction readNumber(record: JsonRecord | undefined, key: string): number | undefined {\n const value = record?.[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction listLength(record: JsonRecord, key: string): number {\n const value = record[key];\n return Array.isArray(value) ? value.length : 0;\n}\n\nfunction plural(count: number, singular: string): string {\n if (count === 1) return singular;\n if (singular.endsWith('y')) return `${singular.slice(0, -1)}ies`;\n return `${singular}s`;\n}\n\nfunction preview(value: string | undefined): string | undefined {\n if (!value) return undefined;\n return value.length > PREVIEW_LENGTH ? `${value.slice(0, PREVIEW_LENGTH - 3)}…` : value;\n}\n\nfunction countMetadata(args: JsonRecord, lists: ReadonlyArray<[string, string]>): string[] {\n return lists.flatMap(([key, label]) => {\n const count = listLength(args, key);\n return count > 0 ? [`${count} ${plural(count, label)}`] : [];\n });\n}\n\nfunction line(text: string, tone: LineTone, extra: Omit<ToolLine, 'text' | 'tone'> = {}): ToolLine {\n return { text, tone, ...extra };\n}\n\nfunction outputText(result: ToolResultView | null): string {\n if (!result) return '';\n return result.content\n .flatMap((item) => {\n const record = asRecord(item);\n return record?.type === 'text' && typeof record.text === 'string' ? [record.text] : [];\n })\n .join('\\n');\n}\n\nfunction bodyLines(text: string, expanded: boolean): ToolLine[] {\n const all = text\n .split('\\n')\n .map((entry) => entry.trimEnd())\n .filter((entry) => entry.length > 0);\n const shown = expanded ? all : all.slice(0, COLLAPSED_BODY_LINES);\n const lines = shown.map((entry) => line(entry, 'text'));\n if (all.length > shown.length) lines.push(line(`… ${all.length - shown.length} more lines`, 'dim'));\n return lines;\n}\n\n/** The header beside the tool name: what the call is for and how much it carries. */\nexport function planCallSummary(toolName: string, args: JsonRecord): PlanCallSummary {\n if (toolName === 'record_debug_evidence') {\n const issue = preview(readString(args, 'issue'));\n return {\n action: 'record evidence',\n ...(issue ? { detail: issue } : {}),\n metadata: countMetadata(args, EVIDENCE_LISTS),\n };\n }\n if (toolName === 'run_fable_plan') {\n const metadata = countMetadata(args, PACKET_LISTS);\n if (readString(args, 'currentPlan')) metadata.push('with current plan');\n return { action: 'fable draft', metadata };\n }\n if (toolName === 'write_plan') return { action: 'save plan', metadata: [] };\n const decision = readString(args, 'decision');\n return { action: decision ? `decide ${decision}` : 'request approval', metadata: [] };\n}\n\nfunction evidenceLines(args: JsonRecord, result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const recorded = asRecord(result?.details)?.recorded === true;\n const lines = [\n recorded\n ? line('✓ evidence recorded as planning context', 'success')\n : line(`○ ${inlineText(outputText(result)) || 'not recorded'}`, 'muted'),\n ];\n if (!options.expanded) return lines;\n const fields: ReadonlyArray<[string, string]> = [\n ['issue', 'issue'],\n ['expectedBehavior', 'expected'],\n ['reproductionAttempt', 'reproduction'],\n ['actualBehavior', 'actual'],\n ];\n for (const [key, label] of fields) {\n const value = readString(args, key);\n if (value) lines.push(line(`${label} ${value}`, 'text', { label }));\n }\n for (const [key, label] of EVIDENCE_LISTS) {\n const raw = args[key];\n const items = Array.isArray(raw) ? raw.filter((item): item is string => typeof item === 'string') : [];\n if (items.length === 0) continue;\n lines.push(line(plural(items.length, label), 'hi', { bold: true }));\n lines.push(...items.map((item) => line(inlineText(item), 'text', { indent: true })));\n }\n return lines;\n}\n\nfunction fableLines(result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const details = asRecord(result?.details);\n const text = outputText(result);\n if (details?.started !== true) {\n const code = readString(details, 'errorCode');\n return [line(`○ ${inlineText(text) || 'fable planning did not start'}${code ? ` · ${code}` : ''}`, 'muted')];\n }\n const status = readString(details, 'status') ?? 'unknown';\n const draft = typeof details?.draft === 'string' ? details.draft : undefined;\n const code = readString(details, 'errorCode');\n if (!draft) return [line(`✗ fable planning ${status}${code ? ` · ${code}` : ''}`, 'error')];\n const finished = status === 'completed';\n return [\n line(\n `${finished ? '✓' : '!'} fable draft · ${status}${code ? ` · ${code}` : ''}`,\n finished ? 'success' : 'warning',\n {\n bold: true,\n },\n ),\n ...bodyLines(draft, options.expanded),\n ];\n}\n\nfunction writeLines(result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const details = asRecord(result?.details);\n const path = readString(details, 'path');\n if (options.isPartial) {\n const phase = readString(details, 'phase') ?? 'checking';\n return [line(`◐ ${phase}${path ? ` ${path}` : ''}`, 'warning')];\n }\n const duration = readNumber(details, 'durationMs');\n if (details?.written === true) {\n return [line(`✓ wrote ${path ?? 'the plan'}${duration === undefined ? '' : ` · ${duration}ms`}`, 'success')];\n }\n const lines = [line(`○ ${inlineText(outputText(result)) || 'plan not written'}`, 'muted')];\n if (path) lines.push(line(`path ${path}`, 'dim'));\n return lines;\n}\n\nfunction completeLines(result: ToolResultView | null): ToolLine[] {\n const text = inlineText(outputText(result));\n if (asRecord(result?.details)?.exited === true) {\n return [line(`✓ plan mode exited${text ? ` · ${text}` : ''}`, 'success')];\n }\n return [line(`○ staying in plan mode${text ? ` · ${text}` : ''}`, 'muted')];\n}\n\n/** Why a plan tool call failed, as the tool said it on one line; empty when it said nothing. */\nexport function planFailureReason(result: ToolResultView | null): string {\n return inlineText(outputText(result));\n}\n\n/** The body of a plan tool card: the outcome line, plus the carried detail once expanded. */\nexport function planResultLines(\n toolName: string,\n args: JsonRecord,\n result: ToolResultView | null,\n options: PlanRenderOptions,\n): ToolLine[] {\n if (options.isError) {\n return [line(`✗ ${planFailureReason(result) || `${toolName} failed`}`, 'error')];\n }\n if (toolName === 'record_debug_evidence') return evidenceLines(args, result, options);\n if (toolName === 'run_fable_plan') {\n if (options.isPartial) return [line('◐ drafting with the local Fable broker', 'warning')];\n return fableLines(result, options);\n }\n if (toolName === 'write_plan') return writeLines(result, options);\n if (options.isPartial) return [line('◐ waiting for the review decision', 'warning')];\n return completeLines(result);\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/native';\nimport { fontOf, MessageItem, MessageItemBody, MessageItemHeader, toolTone } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport {\n type LineTone,\n planCallSummary,\n planFailureReason,\n planResultLines,\n type ToolLine,\n} from '../_lib/planToolRender';\n\n/**\n * The plan tools' timeline item on native, as the web's: the plan action as\n * the title, the issue and what the packet carries beside it on one line, and\n * the outcome line in the body (shown collapsed too, as the web does), with\n * the recorded evidence or the Fable draft once expanded. A failure shows only the tool's reason; the edge and icon say it failed.\n */\nexport function PlanToolMessage({ toolName, args, result, running, isError }: ToolMessageRenderProps) {\n const summary = planCallSummary(toolName, args);\n const collapsed = planResultLines(toolName, args, result, { expanded: false, isError, isPartial: running });\n const full = planResultLines(toolName, args, result, { expanded: true, isError, isPartial: running });\n const reason = isError ? planFailureReason(result) : '';\n // The issue is what the call is about, so it leads; the counts are the detail that yields first.\n const primary = summary.detail;\n const secondary = summary.metadata;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={!isError && full.length > collapsed.length}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={summary.action}>\n <View testID={`tool-call-${toolName}`} style={styles.summary}>\n {primary !== undefined ? (\n <Text numberOfLines={1} style={[styles.sans, styles.primary]}>\n {primary}\n </Text>\n ) : null}\n {secondary.length > 0 ? (\n <Text numberOfLines={1} style={[styles.sans, styles.secondary]}>\n {primary !== undefined ? `· ${secondary.join(' · ')}` : secondary.join(' · ')}\n </Text>\n ) : null}\n </View>\n </MessageItemHeader>\n {isError ? (\n reason.length > 0 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <Text selectable style={[styles.sans, styles.error]}>\n {reason}\n </Text>\n </MessageItemBody>\n ) : null\n ) : expanded && toolName === 'record_debug_evidence' && full.length > 1 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <EvidenceBody lines={full} />\n </MessageItemBody>\n ) : (expanded ? full : collapsed).length > 0 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <View style={styles.lines}>\n {(expanded ? full : collapsed).map((entry, index) => (\n <ToneLine key={`${String(index)}-${entry.text}`} entry={entry} />\n ))}\n </View>\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n\nfunction ToneLine({ entry }: { entry: ToolLine }) {\n return (\n <Text\n selectable\n style={[\n styles.sans,\n TONE_STYLE[entry.tone],\n entry.bold === true ? styles.bold : null,\n entry.indent === true ? styles.indent : null,\n ]}\n >\n {entry.text}\n </Text>\n );\n}\n\ninterface EvidenceGroup {\n label: string;\n values: string[];\n}\n\n/*\n * The shared lines name each evidence field in `label`, carry list labels as\n * bold lines, and list items as indented lines; the phone regroups them so\n * every label sits in one style above its values.\n */\nfunction evidenceGroups(lines: readonly ToolLine[]): EvidenceGroup[] {\n const groups: EvidenceGroup[] = [];\n for (const entry of lines) {\n if (entry.bold === true) groups.push({ label: entry.text, values: [] });\n else if (entry.indent === true && groups.length > 0) groups[groups.length - 1]?.values.push(entry.text);\n else if (entry.label !== undefined)\n groups.push({ label: entry.label, values: [entry.text.slice(entry.label.length).trimStart()] });\n else groups.push({ label: entry.text, values: [] });\n }\n return groups;\n}\n\n/** The expanded evidence: the outcome line, then each label over its values, set apart from the outcome. */\nfunction EvidenceBody({ lines }: { lines: readonly ToolLine[] }) {\n const [status, ...facts] = lines;\n return (\n <View style={styles.evidence}>\n {status !== undefined ? <ToneLine entry={status} /> : null}\n <View style={styles.facts}>\n {evidenceGroups(facts).map((group) => (\n <View key={group.label} style={styles.group}>\n <Text style={styles.label}>{group.label}</Text>\n {group.values.map((value, index) => (\n <Text key={`${String(index)}-${value}`} selectable style={[styles.sans, styles.text]}>\n {value}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n // One line on the title's row: the issue stays whole up to most of the row, the counts truncate first.\n summary: { flex: 1, flexDirection: 'row', alignItems: 'center', gap: theme.spacing(2), minWidth: 0 },\n sans: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n },\n primary: { flexShrink: 0, maxWidth: '70%', color: theme.colors.text },\n secondary: { flexShrink: 1, color: theme.colors.faint },\n lines: { gap: theme.spacing(0.5) },\n evidence: { gap: theme.spacing(3) },\n facts: {\n gap: theme.spacing(3),\n paddingTop: theme.spacing(3),\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n },\n group: { gap: theme.spacing(0.5) },\n label: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.dim,\n },\n bold: { fontWeight: theme.fontWeight.semibold },\n indent: { paddingLeft: theme.spacing(4) },\n error: { color: theme.colors.red },\n hi: { color: theme.colors.hi },\n text: { color: theme.colors.text },\n dim: { color: theme.colors.dim },\n muted: { color: theme.colors.faint },\n success: { color: theme.colors.green },\n warning: { color: theme.colors.yellow },\n accent: { color: theme.colors.blue },\n}));\n\n/** The line tones of the web's MessageLines, drawn with the same theme tokens. */\nconst TONE_STYLE: Readonly<Record<LineTone, object>> = {\n hi: styles.hi,\n text: styles.text,\n dim: styles.dim,\n muted: styles.muted,\n success: styles.success,\n error: styles.error,\n warning: styles.warning,\n accent: styles.accent,\n};\n","import { defineToolRenderer } from '@agimon-ai/po-core/native';\n\nimport { PlanReviewPrompt } from './_components/PlanReviewPrompt.native';\nimport { PlanToolMessage } from './_components/PlanToolMessage.native';\nimport { claimsPlanReviewPrompt, type PLAN_TOOL_NAMES } from './_lib/planToolRender';\n\n/*\n * The phone half of plan.web.tsx: one card for every plan tool. The names are\n * spelled out because the native renderer check reads only `.native.` files;\n * `satisfies` keeps them to the shared PLAN_TOOL_NAMES list.\n */\nexport default defineToolRenderer({\n tools: ['record_debug_evidence', 'run_fable_plan', 'write_plan', 'complete_plan'] satisfies Array<\n (typeof PLAN_TOOL_NAMES)[number]\n >,\n message: PlanToolMessage,\n prompt: { claims: claimsPlanReviewPrompt, component: PlanReviewPrompt },\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport activityGroupPlan from '../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.native';\nimport fillPlan from '../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.native';\nimport toolPlan from '../src/extensions/workspaces/sessions/(frontend)/tool/plan.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'plan',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'plan' }, activityGroupPlan)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'activity.plan', id: 'plan' }, fillPlan)]; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['plan'] }, toolPlan)]; },\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"native.mjs","names":["WebPluginSlotProps","Button","Markdown","SegmentedControl","Textarea","fontOf","PoNativeTheme","useEffect","useState","StyleSheet","PLAN_STATUS_KEY","PlanDetailView","fetchPlan","savePlan","PLAN_TAB_ID","PlanPanel","sessionId","statuses","closeTransientTab","fileTabFor","openTransientTab","detail","setDetail","error","setError","loading","setLoading","view","setView","draft","setDraft","saving","setSaving","note","setNote","revision","cancelled","then","result","ok","undefined","catch","failure","Error","message","String","save","unavailable","hash","refreshed","styles","panel","title","value","label","meta","reason","content","path","tab","actions","success","planTab","Parameters","id","create","theme","padding","spacing","gap","uni__dependencies","fontFamily","sans","fontSize","lg","lineHeight","fontWeight","color","colors","hi","sm","dim","mono","red","green","flexDirection","flexWrap","styles","WebPluginSlotProps","ListRow","fontOf","PoNativeTheme","StyleSheet","parsePlanStatus","PLAN_STATUS_KEY","planTab","PlanActivitySection","sessionId","statuses","openTransientTab","view","styles","meta","title","stamp","undefined","create","theme","fontFamily","sans","fontSize","sm","lineHeight","color","colors","dim","uni__dependencies","styles","ToolPromptRenderProps","Button","ChevronDownIcon","ChevronRightIcon","fontOf","Panel","PoNativeTheme","useState","StyleSheet","PlanReviewPrompt","dialog","answer","cancel","defaultExpanded","open","setOpen","styles","prompt","header","expanded","label","description","pending","scroll","content","title","options","map","option","index","footer","create","theme","flexShrink","margin","spacing","uni__dependencies","flexDirection","alignItems","justifyContent","paddingHorizontal","paddingVertical","borderRadius","marginLeft","fontFamily","sans","fontSize","sm","lineHeight","fontWeight","semibold","color","colors","dim","flexGrow","gap","paddingBottom","base","hi","padding","borderTopWidth","borderTopColor","styles","ToolMessageRenderProps","fontOf","MessageItem","MessageItemBody","MessageItemHeader","toolTone","PoNativeTheme","StyleSheet","LineTone","planCallSummary","planFailureReason","planResultLines","ToolLine","PlanToolMessage","toolName","args","result","running","isError","summary","collapsed","expanded","isPartial","full","reason","primary","detail","secondary","metadata","length","action","styles","undefined","sans","join","error","lines","map","entry","index","String","text","ToneLine","TONE_STYLE","tone","bold","indent","EvidenceGroup","label","values","evidenceGroups","groups","push","slice","trimStart","EvidenceBody","status","facts","evidence","group","value","create","theme","flex","flexDirection","alignItems","gap","spacing","minWidth","uni__dependencies","fontFamily","fontSize","base","lineHeight","flexShrink","maxWidth","color","colors","faint","paddingTop","borderTopWidth","borderTopColor","sm","fontWeight","semibold","dim","paddingLeft","red","hi","muted","success","green","warning","yellow","accent","blue","Readonly","Record","settingPlan","settingPlan2","activityGroupPlan","fillPlan","toolPlan"],"sources":["../../src/types/planSettings.ts","../../src/extensions/(frontend)/_lib/planSettings.ts","../../src/extensions/(frontend)/setting/plan.native.ts","../../src/extensions/workspaces/(frontend)/setting/plan.native.ts","../../src/types/planApi.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.native.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/planApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanReviewPrompt.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/planToolRender.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanToolMessage.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/plan.native.tsx","../../generated/native.ts"],"sourcesContent":["/**\n * The planning settings, described once for both surfaces.\n *\n * The terminal panel and the cockpit settings page render the same five fields,\n * and the one thing they must agree on is which config key each one writes. So\n * the ids, labels and key paths live here rather than in either renderer.\n *\n * It lives under src/types because that is the one server root a browser bundle\n * may read, which also means it may import nothing: pulling the config package\n * in for the thinking levels would drag a node module into the page. They are\n * spelled out instead, and a test asserts they still match the parser's.\n */\n\nexport const PLAN_CONFIG_SECTION_ID = 'planning';\nconst PLANNING_PATH = ['modes', PLAN_CONFIG_SECTION_ID] as const;\nconst MAIN_KEY = 'main';\nconst SUBAGENTS_KEY = 'subagents';\n\n/** Both agents fall back to the session's own settings when left unset. */\nconst INHERIT_MODEL = 'inherit the session model';\nconst INHERIT_THINKING = 'inherit';\n\n/** Mirrors PO_PLANNING_THINKING_LEVELS; pinned by planConfig's test. */\nexport const PLAN_THINKING_LEVELS: readonly string[] = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];\n\nexport interface PlanSettingShape {\n readonly id: string;\n readonly label: string;\n readonly keyPath: readonly string[];\n readonly placeholder: string;\n readonly detail: string;\n /** Present for a closed set; a renderer offers these rather than free text. */\n readonly options?: readonly string[];\n /** Offers the machine's authenticated models rather than free text. */\n readonly models?: boolean;\n}\n\nexport const PLAN_SETTING_SHAPES: readonly PlanSettingShape[] = [\n {\n id: 'main.model',\n label: 'main model',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'model the main agent switches to while plan mode is on.',\n models: true,\n },\n {\n id: 'main.thinking',\n label: 'main thinking',\n keyPath: [...PLANNING_PATH, MAIN_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'thinking level appended to the main model while planning.',\n options: PLAN_THINKING_LEVELS,\n },\n {\n id: 'subagents.model',\n label: 'subagent model',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'model'],\n placeholder: INHERIT_MODEL,\n detail: 'model forced onto delegated planning subagents.',\n models: true,\n },\n {\n id: 'subagents.thinking',\n label: 'subagent thinking',\n keyPath: [...PLANNING_PATH, SUBAGENTS_KEY, 'thinking'],\n placeholder: INHERIT_THINKING,\n detail: 'thinking level appended to the subagent model.',\n options: PLAN_THINKING_LEVELS,\n },\n {\n id: 'plansdirectory',\n label: 'plans directory',\n keyPath: [...PLANNING_PATH, 'plansDirectory'],\n placeholder: '~/.po/plans',\n detail: 'absolute, repo-relative, or under ~. written plans land here.',\n },\n];\n","import type { SettingsSectionContribution } from '@agimon-ai/po-core/web';\n\nimport { PLAN_CONFIG_SECTION_ID, PLAN_SETTING_SHAPES } from '../../../types/planSettings';\n\n/**\n * The planning settings, as the cockpit's settings page renders them.\n *\n * Built from the same descriptor table the terminal panel uses, so the two\n * surfaces cannot disagree about which config key a field writes. The host owns\n * the scope switch and the writes; this only says what the fields are.\n */\nexport const planSettingsSection: SettingsSectionContribution = {\n id: PLAN_CONFIG_SECTION_ID,\n label: 'planning',\n detail: 'the models plan mode switches to, and where written plans land',\n order: 30,\n fields: PLAN_SETTING_SHAPES.map((shape) => ({\n id: shape.id,\n label: shape.label,\n // A model field offers the machine's authenticated models, which only the\n // host can enumerate; the rest are a closed set or free text.\n kind: shape.models === true || shape.options !== undefined ? ('select' as const) : ('text' as const),\n keyPath: shape.keyPath,\n detail: shape.detail,\n placeholder: shape.placeholder,\n ...(shape.models === true ? { optionsFrom: 'models' as const } : {}),\n ...(shape.options === undefined\n ? {}\n : { options: shape.options.map((option) => ({ value: option, label: option })) }),\n })),\n};\n","import { defineSettingsSection } from '@agimon-ai/po-core/native';\n\nimport { planSettingsSection } from '../_lib/planSettings';\n\nexport default defineSettingsSection(planSettingsSection);\n","import { defineSettingsSection } from '@agimon-ai/po-core/native';\n\nimport { planSettingsSection } from '../../../(frontend)/_lib/planSettings';\n\nexport default defineSettingsSection(planSettingsSection);\n","/**\n * The wire vocabulary this package's API shares with whatever calls it.\n *\n * It lives under src/types because that is the one server root a browser\n * bundle may read: the routes answer with these shapes and the cockpit plugin\n * reads them, so neither half can drift from the other. The paths themselves\n * are not here; they are declared once in `./apiRoutes`, which the Hono app\n * and the generated client both read.\n *\n * Two routes, and neither takes a path. A session has one current plan, so\n * `current` answers it and `content` takes the manual save back; the file they\n * act on is the one write_plan recorded, never one the page named. That is\n * also why there is nothing to escape here: a reader cannot address a second\n * file through these URLs.\n */\n\n/** Where a host mounts this package's API; the segment after /api/plugins/. */\nexport const API_BASE_PATH = 'plans';\n\n/**\n * Footer status key the session publishes once a plan exists, which is what\n * makes the cockpit's activity group appear at all. It outlives plan mode: the\n * plan is most worth reading while the agent implements it.\n */\nexport const PLAN_STATUS_KEY = 'po-plan-document';\n\n/** The selector contract shared by complete_plan and its cockpit composer prompt. */\nexport const PLAN_REVIEW_TITLE = 'Plan complete. What would you like to do?';\nexport const EXIT_PLAN_MODE_CHOICE = 'Exit plan mode and start implementation';\nexport const CONTINUE_PLANNING_CHOICE = 'Continue planning';\nexport const EXIT_PLAN_DECISION = 'exit';\nexport const CONTINUE_PLAN_DECISION = 'continue';\n\n/**\n * The label the reader sees paired with the decision the tool acts on. A headless\n * client answers with `value`, so a server plugin never has to recognise the wording; Pi's\n * own `ui.select` carries labels only, so its half maps the label back itself.\n */\nexport const PLAN_REVIEW_CHOICES = [\n { label: EXIT_PLAN_MODE_CHOICE, value: EXIT_PLAN_DECISION },\n { label: CONTINUE_PLANNING_CHOICE, value: CONTINUE_PLAN_DECISION },\n] as const;\n\n/** The same options as bare labels, which is all Pi's select and the composer prompt need. */\nexport const PLAN_REVIEW_OPTIONS = PLAN_REVIEW_CHOICES.map((choice) => choice.label);\n\n/** Between the plan's title and the stamp that marks a rewrite. */\nconst STATUS_SEPARATOR = ' · ';\n\n/** Strips the colour a session may have themed a status with. */\nconst ANSI = /\u001b\\[[0-9;]*m/gu;\n\n/** The status line the session publishes; the stamp changes on every write. */\nexport function formatPlanStatus(title: string, stamp: string): string {\n return `${title}${STATUS_SEPARATOR}${stamp}`;\n}\n\n/** What a reader gets out of the status line. */\nexport interface PlanStatusView {\n title: string;\n /** When the plan was last written, as the session worded it; empty when it said nothing. */\n stamp: string;\n}\n\n/**\n * Reading the status line back. Statuses reach a plugin raw, so the colour a\n * session may have added comes off here. A title can itself contain the\n * separator, so the stamp is taken from the last one rather than the first.\n */\nexport function parsePlanStatus(raw: string | undefined): PlanStatusView | undefined {\n if (raw === undefined) return undefined;\n const text = raw.replace(ANSI, '').trim();\n if (text === '') return undefined;\n const cut = text.lastIndexOf(STATUS_SEPARATOR);\n if (cut === -1) return { title: text, stamp: '' };\n return { title: text.slice(0, cut).trim(), stamp: text.slice(cut + STATUS_SEPARATOR.length).trim() };\n}\n\n/**\n * What write_plan recorded about this session's plan.\n *\n * The absolute path is the point of it: the extension resolves the plans\n * directory against the harness root, which no other process knows, so it\n * writes down where the plan landed rather than leaving the API to derive a\n * location it would sometimes get wrong.\n */\nexport interface PlanPointerRecord {\n path: string;\n title: string;\n writtenAt: string;\n planId?: string;\n}\n\n/** The plan as it stands on disk right now, which is what the source view edits. */\nexport interface PlanDetailView {\n path: string;\n title: string;\n writtenAt: string;\n planId?: string;\n content: string;\n /** sha256 of the content; the token a save hands back to prove it is not stale. */\n hash: string;\n /** True when the plan is missing or past the size cap, so `content` is empty. */\n unavailable: boolean;\n reason?: string;\n}\n\n/** What the save route takes. */\nexport interface PlanSaveRequest {\n /** The hash the reader loaded; a mismatch means the plan moved underneath them. */\n expectedHash: string;\n content: string;\n}\n\n/** What the save route answers with. */\nexport interface PlanSaveView {\n hash: string;\n}\n\n/** What a route reports when it refuses; the page shows `error` verbatim. */\nexport interface PlanErrorView {\n error: string;\n /** On a stale save, the hash the plan actually has now. */\n hash?: string;\n}\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\n\nimport { PLAN_STATUS_KEY } from '../../../../../types/planApi';\n\n// Keyed off the saved plan rather than the mode because the plan remains useful\n// while it is being implemented after the read-only mode exits.\nexport default defineActivityGroup({\n name: 'plan',\n keys: 'p e',\n statusKey: PLAN_STATUS_KEY,\n marksBackgroundWork: false,\n order: 25,\n});\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type { PlanDetailView, PlanSaveView } from './planApi';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/workspaces/sessions/(backend)/api/plans/`, so the mount is\n * stated once, by the folder that creates it. The paths used to be written\n * here as helpers, again in the contract, and again inside every URL the page\n * built, and the copies were free to disagree.\n *\n * This is the one file the routes, the Hono app and the browser all read, so a\n * path cannot move on one side alone.\n *\n * Neither route takes a query or a path parameter: a session has one current\n * plan, so `current` answers it and `save` takes the manual write back.\n */\nconst routes = {\n current: {\n method: 'GET',\n path: '/current',\n response: undefined as unknown as ApiResponseOf<PlanDetailView>,\n },\n save: {\n method: 'PUT',\n path: '/content',\n response: undefined as unknown as ApiResponseOf<PlanSaveView>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'plans' at. */\nexport const apiScopes = ['session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'plans',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import { api } from '../../../../../../../generated/client.native';\nimport type { PlanDetailView } from '../../../../../../types/planApi';\n\n/**\n * The page's half of this package's session API: the current plan, and the\n * manual save.\n *\n * These are adapters now, not a transport. The generated client owns the URL\n * and the sealed transport with it, so nothing here spells a route or reaches\n * for `fetch`. What stays is this package's own vocabulary: which refusals the\n * reader is shown, and the stale-save contract the editor depends on.\n */\n\nconst UNREACHABLE = 'The session is unreachable.';\nconst NO_PLAN = 'This session has not written a plan yet.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The message a reader is shown: the route's own words, or why there were none. */\nfunction messageOf(result: { status: number; error: string }): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === '' ? `The session answered ${String(result.status)}.` : result.error;\n}\n\nexport type FetchPlanResult = { ok: true; detail: PlanDetailView } | { ok: false; error: string };\n\nexport async function fetchPlan(sessionId: string): Promise<FetchPlanResult> {\n const result = await api.session(sessionId).current();\n // A session that has written nothing answers 404, which is not a failure the\n // reader should be shown as one.\n if (result.status === 404) return { ok: false, error: result.ok || result.error === '' ? NO_PLAN : result.error };\n if (!result.ok) return { ok: false, error: messageOf(result) };\n if (!isRecord(result.data)) return { ok: false, error: 'The session answered with no plan.' };\n return { ok: true, detail: result.data };\n}\n\nexport type SavePlanResult =\n | { ok: true; hash: string }\n /** The plan moved under the editor; `hash` is what it holds now. */\n | { ok: false; stale: true; error: string; hash?: string }\n | { ok: false; stale: false; error: string };\n\nexport async function savePlan(sessionId: string, expectedHash: string, content: string): Promise<SavePlanResult> {\n const result = await api.session(sessionId).save({ body: { expectedHash, content } });\n // The agent can rewrite the plan while a reader is still editing it. A moved\n // hash is the one refusal the editor recovers from, so it is read before the\n // generic failure.\n if (result.status === 409) {\n const data = result.ok ? undefined : result.data;\n const hash = isRecord(data) && typeof data.hash === 'string' ? data.hash : undefined;\n return {\n ok: false,\n stale: true,\n error: result.ok ? 'The plan changed since it was opened.' : messageOf(result),\n ...(hash === undefined ? {} : { hash }),\n };\n }\n if (!result.ok) return { ok: false, stale: false, error: messageOf(result) };\n return { ok: true, hash: isRecord(result.data) && typeof result.data.hash === 'string' ? result.data.hash : '' };\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, Markdown, SegmentedControl, Textarea, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useEffect, useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { PLAN_STATUS_KEY, type PlanDetailView } from '../../../../../../types/planApi';\nimport { fetchPlan, savePlan } from '../_lib/planApi.native';\n\nexport const PLAN_TAB_ID = 'plan-document';\n\n/** The saved plan, with edits guarded by its on-disk hash, never a caller-supplied path. */\nexport function PlanPanel({\n sessionId,\n statuses,\n closeTransientTab,\n fileTabFor,\n openTransientTab,\n}: WebPluginSlotProps) {\n const [detail, setDetail] = useState<PlanDetailView>();\n const [error, setError] = useState<string>();\n const [loading, setLoading] = useState(true);\n const [view, setView] = useState('preview');\n const [draft, setDraft] = useState<string>();\n const [saving, setSaving] = useState(false);\n const [note, setNote] = useState<string>();\n const revision = statuses[PLAN_STATUS_KEY];\n useEffect(() => {\n if (sessionId === null) return;\n let cancelled = false;\n void fetchPlan(sessionId)\n .then((result) => {\n if (cancelled) return;\n setLoading(false);\n if (result.ok) {\n setDetail(result.detail);\n setError(undefined);\n setDraft(undefined);\n setNote(undefined);\n } else {\n setDetail(undefined);\n setError(result.error);\n }\n })\n .catch((failure: unknown) => {\n if (!cancelled) {\n setLoading(false);\n setError(failure instanceof Error ? failure.message : String(failure));\n }\n });\n return () => {\n cancelled = true;\n };\n }, [sessionId, revision]);\n\n const save = async () => {\n if (sessionId === null || !detail || draft === undefined || detail.unavailable || saving) return;\n setSaving(true);\n try {\n const result = await savePlan(sessionId, detail.hash, draft);\n if (!result.ok) {\n setNote(result.error);\n return;\n }\n setNote('saved');\n const refreshed = await fetchPlan(sessionId);\n if (refreshed.ok) {\n setDetail(refreshed.detail);\n setDraft(undefined);\n } else setError(refreshed.error);\n } catch (failure) {\n setNote(failure instanceof Error ? failure.message : String(failure));\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <ScrollView contentContainerStyle={styles.panel} testID=\"plan-panel\">\n <Text style={styles.title}>{detail?.title ?? 'plan'}</Text>\n <SegmentedControl\n accessibilityLabel=\"plan view\"\n options={[\n { value: 'preview', label: 'preview' },\n { value: 'source', label: 'source' },\n ]}\n value={view}\n onValueChange={setView}\n />\n {sessionId === null ? (\n <Text style={styles.meta}>Select a session.</Text>\n ) : loading && !detail ? (\n <Text style={styles.meta}>reading this session's plan…</Text>\n ) : null}\n {error ? (\n <Text accessibilityRole=\"alert\" style={styles.error}>\n {error}\n </Text>\n ) : null}\n {detail ? (\n detail.unavailable ? (\n <Text style={styles.meta}>{detail.reason ?? 'this plan cannot be shown'}</Text>\n ) : view === 'preview' ? (\n <Markdown\n text={draft ?? detail.content}\n onFileLink={(path) => {\n const tab = fileTabFor(path);\n return tab ? () => openTransientTab(tab) : undefined;\n }}\n />\n ) : (\n <>\n <Textarea\n accessibilityLabel=\"plan source\"\n value={draft ?? detail.content}\n onChangeText={setDraft}\n numberOfLines={12}\n />\n <View style={styles.actions}>\n <Button variant=\"primary\" disabled={draft === undefined || saving} onPress={() => void save()}>\n save to disk\n </Button>\n {draft !== undefined ? (\n <Button variant=\"ghost\" onPress={() => setDraft(undefined)}>\n discard edits\n </Button>\n ) : null}\n </View>\n {note ? <Text style={note === 'saved' ? styles.success : styles.error}>{note}</Text> : null}\n </>\n )\n ) : null}\n {detail ? (\n <Text selectable style={styles.path}>\n {detail.path}\n </Text>\n ) : null}\n <Button variant=\"ghost\" onPress={() => closeTransientTab(PLAN_TAB_ID)}>\n close\n </Button>\n </ScrollView>\n );\n}\n\nexport function planTab(): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n return { id: PLAN_TAB_ID, label: 'plan', panel: PlanPanel };\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n panel: { padding: theme.spacing(4), gap: theme.spacing(3) },\n title: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.lg,\n lineHeight: theme.lineHeight.lg,\n fontWeight: '600',\n color: theme.colors.hi,\n },\n meta: { fontSize: theme.fontSize.sm, lineHeight: theme.lineHeight.sm, color: theme.colors.dim },\n path: { fontFamily: fontOf(theme.fontFamily.mono), fontSize: theme.fontSize.sm, color: theme.colors.dim },\n error: { fontSize: theme.fontSize.sm, color: theme.colors.red },\n success: { fontSize: theme.fontSize.sm, color: theme.colors.green },\n actions: { flexDirection: 'row', flexWrap: 'wrap', gap: theme.spacing(2) },\n}));\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { ListRow, fontOf } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { parsePlanStatus, PLAN_STATUS_KEY } from '../../../../../../types/planApi';\nimport { planTab } from './PlanPanel.native';\n\n/** The document row, not its group header, is the way into a saved plan. */\nexport function PlanActivitySection({ sessionId, statuses, openTransientTab }: WebPluginSlotProps) {\n const view = parsePlanStatus(statuses[PLAN_STATUS_KEY]);\n if (!view) return <Text style={styles.meta}>no plan written yet</Text>;\n return (\n <View testID=\"activity-plan\">\n <ListRow\n title={view.title}\n description={view.stamp || undefined}\n disabled={sessionId === null}\n onPress={() => {\n if (sessionId !== null) openTransientTab(planTab());\n }}\n />\n <Text style={styles.meta}>open to read or edit; the agent reads what you save.</Text>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n meta: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { PlanActivitySection } from './_components/PlanActivitySection.native';\n\nexport default defineFill({ slot: 'activity.plan', id: 'plan', component: PlanActivitySection });\n","import type { ToolPromptRenderProps } from '@agimon-ai/po-core/native';\nimport { Button, ChevronDownIcon, ChevronRightIcon, fontOf, Panel } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useState } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type {} from '../../../../../../types/unistyles.native';\n\nexport function PlanReviewPrompt({\n dialog,\n answer,\n cancel,\n defaultExpanded = true,\n}: ToolPromptRenderProps & { defaultExpanded?: boolean }) {\n const [open, setOpen] = useState(defaultExpanded);\n return (\n <Panel style={styles.prompt} testID=\"plan-review-prompt\" onAccessibilityEscape={cancel}>\n <Button\n variant=\"ghost\"\n size=\"card\"\n style={styles.header}\n accessibilityLabel={open ? 'Collapse plan review' : 'Expand plan review'}\n accessibilityState={{ expanded: open }}\n aria-expanded={open}\n onPress={() => setOpen(!open)}\n >\n <Text style={styles.label}>Plan review</Text>\n {!open ? <Text style={[styles.description, styles.pending]}>Awaiting decision</Text> : null}\n {open ? <ChevronDownIcon size={16} /> : <ChevronRightIcon size={16} />}\n </Button>\n {open ? (\n <>\n <ScrollView style={styles.scroll} contentContainerStyle={styles.content} keyboardShouldPersistTaps=\"handled\">\n <Text style={styles.title} accessibilityRole=\"header\">\n {dialog.title}\n </Text>\n <Text style={styles.description}>\n Review the plan in the conversation before choosing what happens next.\n </Text>\n {dialog.options.map((option, index) => (\n <Button\n key={option}\n variant=\"outline\"\n size=\"card\"\n testID={`plan-review-option-${index}`}\n onPress={() => answer(option)}\n >\n {option}\n </Button>\n ))}\n </ScrollView>\n <View style={styles.footer}>\n <Button variant=\"ghost\" size=\"card\" testID=\"plan-review-cancel\" onPress={cancel}>\n Cancel\n </Button>\n </View>\n </>\n ) : null}\n </Panel>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n prompt: { flexShrink: 1, margin: theme.spacing(4) },\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: theme.spacing(3),\n paddingVertical: theme.spacing(2),\n borderRadius: 0,\n },\n pending: { marginLeft: 'auto' },\n label: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.dim,\n },\n scroll: { flexGrow: 0, flexShrink: 1 },\n content: { gap: theme.spacing(3), paddingHorizontal: theme.spacing(3), paddingBottom: theme.spacing(3) },\n title: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.hi,\n },\n description: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n footer: {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n padding: theme.spacing(2),\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n },\n}));\n","import type { ToolPromptDialog, ToolResultView } from '@agimon-ai/po-core/web';\nimport type { MessageLine, MessageLineTone } from '@agimon-ai/po-web-components';\n\nimport { PLAN_REVIEW_OPTIONS, PLAN_REVIEW_TITLE } from '../../../../../../types/planApi';\n\n/**\n * Purpose-first summaries for the plan-mode tools. The TUI leaves these on\n * Pi's default shell, so the shapes here come straight from the tool\n * definitions in src/services/planServerSession/index.ts: write_plan and complete_plan\n * report through `details` (written, path, phase, exited), run_fable_plan\n * carries the broker result, and record_debug_evidence only confirms.\n */\n\nexport const PLAN_TOOL_NAMES = ['record_debug_evidence', 'run_fable_plan', 'write_plan', 'complete_plan'] as const;\n\n/** Claims only the selector opened by complete_plan, on either platform. */\nexport function claimsPlanReviewPrompt(dialog: ToolPromptDialog): boolean {\n return (\n dialog.method === 'select' &&\n dialog.title === PLAN_REVIEW_TITLE &&\n dialog.options.length === PLAN_REVIEW_OPTIONS.length &&\n PLAN_REVIEW_OPTIONS.every((option, index) => dialog.options[index] === option)\n );\n}\n\n/** The toned lines the shared MessageLines draws; the vocabulary is the components package's. */\nexport type LineTone = MessageLineTone;\n/** `label` names an evidence field the text leads with, so a layout can set it apart without parsing the text. */\nexport type ToolLine = MessageLine & { label?: string };\n\nexport interface PlanCallSummary {\n action: string;\n detail?: string;\n metadata: string[];\n}\n\nexport interface PlanRenderOptions {\n expanded: boolean;\n isError: boolean;\n isPartial: boolean;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nconst COLLAPSED_BODY_LINES = 12;\nconst PREVIEW_LENGTH = 72;\n\nconst EVIDENCE_LISTS: ReadonlyArray<[key: string, label: string]> = [\n ['logs', 'log'],\n ['correlatedTraceEvidence', 'trace'],\n ['processOutput', 'process output'],\n ['browserConsoleEvidence', 'console entry'],\n ['correlationIds', 'correlation id'],\n ['timestamps', 'timestamp'],\n ['verifiedFacts', 'verified fact'],\n ['hypotheses', 'hypothesis'],\n ['unavailableEvidence', 'unavailable item'],\n];\n\nconst PACKET_LISTS: ReadonlyArray<[key: string, label: string]> = [\n ['goal', 'goal'],\n ['constraints', 'constraint'],\n ['decisions', 'decision'],\n ['verifiedFindings', 'verified finding'],\n ['inferredFindings', 'inferred finding'],\n ['unresolvedQuestions', 'open question'],\n];\n\nfunction asRecord(value: unknown): JsonRecord | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as JsonRecord) : undefined;\n}\n\nfunction inlineText(value: string): string {\n let normalized = '';\n for (const character of value) {\n const code = character.codePointAt(0) ?? 0;\n normalized += code <= 31 || code === 127 ? ' ' : character;\n }\n return normalized.replace(/\\s+/gu, ' ').trim();\n}\n\nfunction readString(record: JsonRecord | undefined, key: string): string | undefined {\n const value = record?.[key];\n return typeof value === 'string' ? inlineText(value) || undefined : undefined;\n}\n\nfunction readNumber(record: JsonRecord | undefined, key: string): number | undefined {\n const value = record?.[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction listLength(record: JsonRecord, key: string): number {\n const value = record[key];\n return Array.isArray(value) ? value.length : 0;\n}\n\nfunction plural(count: number, singular: string): string {\n if (count === 1) return singular;\n if (singular.endsWith('y')) return `${singular.slice(0, -1)}ies`;\n return `${singular}s`;\n}\n\nfunction preview(value: string | undefined): string | undefined {\n if (!value) return undefined;\n return value.length > PREVIEW_LENGTH ? `${value.slice(0, PREVIEW_LENGTH - 3)}…` : value;\n}\n\nfunction countMetadata(args: JsonRecord, lists: ReadonlyArray<[string, string]>): string[] {\n return lists.flatMap(([key, label]) => {\n const count = listLength(args, key);\n return count > 0 ? [`${count} ${plural(count, label)}`] : [];\n });\n}\n\nfunction line(text: string, tone: LineTone, extra: Omit<ToolLine, 'text' | 'tone'> = {}): ToolLine {\n return { text, tone, ...extra };\n}\n\nfunction outputText(result: ToolResultView | null): string {\n if (!result) return '';\n return result.content\n .flatMap((item) => {\n const record = asRecord(item);\n return record?.type === 'text' && typeof record.text === 'string' ? [record.text] : [];\n })\n .join('\\n');\n}\n\nfunction bodyLines(text: string, expanded: boolean): ToolLine[] {\n const all = text\n .split('\\n')\n .map((entry) => entry.trimEnd())\n .filter((entry) => entry.length > 0);\n const shown = expanded ? all : all.slice(0, COLLAPSED_BODY_LINES);\n const lines = shown.map((entry) => line(entry, 'text'));\n if (all.length > shown.length) lines.push(line(`… ${all.length - shown.length} more lines`, 'dim'));\n return lines;\n}\n\n/** The header beside the tool name: what the call is for and how much it carries. */\nexport function planCallSummary(toolName: string, args: JsonRecord): PlanCallSummary {\n if (toolName === 'record_debug_evidence') {\n const issue = preview(readString(args, 'issue'));\n return {\n action: 'record evidence',\n ...(issue ? { detail: issue } : {}),\n metadata: countMetadata(args, EVIDENCE_LISTS),\n };\n }\n if (toolName === 'run_fable_plan') {\n const metadata = countMetadata(args, PACKET_LISTS);\n if (readString(args, 'currentPlan')) metadata.push('with current plan');\n return { action: 'fable draft', metadata };\n }\n if (toolName === 'write_plan') return { action: 'save plan', metadata: [] };\n const decision = readString(args, 'decision');\n return { action: decision ? `decide ${decision}` : 'request approval', metadata: [] };\n}\n\nfunction evidenceLines(args: JsonRecord, result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const recorded = asRecord(result?.details)?.recorded === true;\n const lines = [\n recorded\n ? line('✓ evidence recorded as planning context', 'success')\n : line(`○ ${inlineText(outputText(result)) || 'not recorded'}`, 'muted'),\n ];\n if (!options.expanded) return lines;\n const fields: ReadonlyArray<[string, string]> = [\n ['issue', 'issue'],\n ['expectedBehavior', 'expected'],\n ['reproductionAttempt', 'reproduction'],\n ['actualBehavior', 'actual'],\n ];\n for (const [key, label] of fields) {\n const value = readString(args, key);\n if (value) lines.push(line(`${label} ${value}`, 'text', { label }));\n }\n for (const [key, label] of EVIDENCE_LISTS) {\n const raw = args[key];\n const items = Array.isArray(raw) ? raw.filter((item): item is string => typeof item === 'string') : [];\n if (items.length === 0) continue;\n lines.push(line(plural(items.length, label), 'hi', { bold: true }));\n lines.push(...items.map((item) => line(inlineText(item), 'text', { indent: true })));\n }\n return lines;\n}\n\nfunction fableLines(result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const details = asRecord(result?.details);\n const text = outputText(result);\n if (details?.started !== true) {\n const code = readString(details, 'errorCode');\n return [line(`○ ${inlineText(text) || 'fable planning did not start'}${code ? ` · ${code}` : ''}`, 'muted')];\n }\n const status = readString(details, 'status') ?? 'unknown';\n const draft = typeof details?.draft === 'string' ? details.draft : undefined;\n const code = readString(details, 'errorCode');\n if (!draft) return [line(`✗ fable planning ${status}${code ? ` · ${code}` : ''}`, 'error')];\n const finished = status === 'completed';\n return [\n line(\n `${finished ? '✓' : '!'} fable draft · ${status}${code ? ` · ${code}` : ''}`,\n finished ? 'success' : 'warning',\n {\n bold: true,\n },\n ),\n ...bodyLines(draft, options.expanded),\n ];\n}\n\nfunction writeLines(result: ToolResultView | null, options: PlanRenderOptions): ToolLine[] {\n const details = asRecord(result?.details);\n const path = readString(details, 'path');\n if (options.isPartial) {\n const phase = readString(details, 'phase') ?? 'checking';\n return [line(`◐ ${phase}${path ? ` ${path}` : ''}`, 'warning')];\n }\n const duration = readNumber(details, 'durationMs');\n if (details?.written === true) {\n return [line(`✓ wrote ${path ?? 'the plan'}${duration === undefined ? '' : ` · ${duration}ms`}`, 'success')];\n }\n const lines = [line(`○ ${inlineText(outputText(result)) || 'plan not written'}`, 'muted')];\n if (path) lines.push(line(`path ${path}`, 'dim'));\n return lines;\n}\n\nfunction completeLines(result: ToolResultView | null): ToolLine[] {\n const text = inlineText(outputText(result));\n if (asRecord(result?.details)?.exited === true) {\n return [line(`✓ plan mode exited${text ? ` · ${text}` : ''}`, 'success')];\n }\n return [line(`○ staying in plan mode${text ? ` · ${text}` : ''}`, 'muted')];\n}\n\n/** Why a plan tool call failed, as the tool said it on one line; empty when it said nothing. */\nexport function planFailureReason(result: ToolResultView | null): string {\n return inlineText(outputText(result));\n}\n\n/** The body of a plan tool card: the outcome line, plus the carried detail once expanded. */\nexport function planResultLines(\n toolName: string,\n args: JsonRecord,\n result: ToolResultView | null,\n options: PlanRenderOptions,\n): ToolLine[] {\n if (options.isError) {\n return [line(`✗ ${planFailureReason(result) || `${toolName} failed`}`, 'error')];\n }\n if (toolName === 'record_debug_evidence') return evidenceLines(args, result, options);\n if (toolName === 'run_fable_plan') {\n if (options.isPartial) return [line('◐ drafting with the local Fable broker', 'warning')];\n return fableLines(result, options);\n }\n if (toolName === 'write_plan') return writeLines(result, options);\n if (options.isPartial) return [line('◐ waiting for the review decision', 'warning')];\n return completeLines(result);\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/native';\nimport { fontOf, MessageItem, MessageItemBody, MessageItemHeader, toolTone } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport {\n type LineTone,\n planCallSummary,\n planFailureReason,\n planResultLines,\n type ToolLine,\n} from '../_lib/planToolRender';\n\n/**\n * The plan tools' timeline item on native, as the web's: the plan action as\n * the title, the issue and what the packet carries beside it on one line, and\n * the outcome line in the body (shown collapsed too, as the web does), with\n * the recorded evidence or the Fable draft once expanded. A failure shows only the tool's reason; the edge and icon say it failed.\n */\nexport function PlanToolMessage({ toolName, args, result, running, isError }: ToolMessageRenderProps) {\n const summary = planCallSummary(toolName, args);\n const collapsed = planResultLines(toolName, args, result, { expanded: false, isError, isPartial: running });\n const full = planResultLines(toolName, args, result, { expanded: true, isError, isPartial: running });\n const reason = isError ? planFailureReason(result) : '';\n // The issue is what the call is about, so it leads; the counts are the detail that yields first.\n const primary = summary.detail;\n const secondary = summary.metadata;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={!isError && full.length > collapsed.length}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={summary.action}>\n <View testID={`tool-call-${toolName}`} style={styles.summary}>\n {primary !== undefined ? (\n <Text numberOfLines={1} style={[styles.sans, styles.primary]}>\n {primary}\n </Text>\n ) : null}\n {secondary.length > 0 ? (\n <Text numberOfLines={1} style={[styles.sans, styles.secondary]}>\n {primary !== undefined ? `· ${secondary.join(' · ')}` : secondary.join(' · ')}\n </Text>\n ) : null}\n </View>\n </MessageItemHeader>\n {isError ? (\n reason.length > 0 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <Text selectable style={[styles.sans, styles.error]}>\n {reason}\n </Text>\n </MessageItemBody>\n ) : null\n ) : expanded && toolName === 'record_debug_evidence' && full.length > 1 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <EvidenceBody lines={full} />\n </MessageItemBody>\n ) : (expanded ? full : collapsed).length > 0 ? (\n <MessageItemBody testID={`tool-result-${toolName}`}>\n <View style={styles.lines}>\n {(expanded ? full : collapsed).map((entry, index) => (\n <ToneLine key={`${String(index)}-${entry.text}`} entry={entry} />\n ))}\n </View>\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n\nfunction ToneLine({ entry }: { entry: ToolLine }) {\n return (\n <Text\n selectable\n style={[\n styles.sans,\n TONE_STYLE[entry.tone],\n entry.bold === true ? styles.bold : null,\n entry.indent === true ? styles.indent : null,\n ]}\n >\n {entry.text}\n </Text>\n );\n}\n\ninterface EvidenceGroup {\n label: string;\n values: string[];\n}\n\n/*\n * The shared lines name each evidence field in `label`, carry list labels as\n * bold lines, and list items as indented lines; the phone regroups them so\n * every label sits in one style above its values.\n */\nfunction evidenceGroups(lines: readonly ToolLine[]): EvidenceGroup[] {\n const groups: EvidenceGroup[] = [];\n for (const entry of lines) {\n if (entry.bold === true) groups.push({ label: entry.text, values: [] });\n else if (entry.indent === true && groups.length > 0) groups[groups.length - 1]?.values.push(entry.text);\n else if (entry.label !== undefined)\n groups.push({ label: entry.label, values: [entry.text.slice(entry.label.length).trimStart()] });\n else groups.push({ label: entry.text, values: [] });\n }\n return groups;\n}\n\n/** The expanded evidence: the outcome line, then each label over its values, set apart from the outcome. */\nfunction EvidenceBody({ lines }: { lines: readonly ToolLine[] }) {\n const [status, ...facts] = lines;\n return (\n <View style={styles.evidence}>\n {status !== undefined ? <ToneLine entry={status} /> : null}\n <View style={styles.facts}>\n {evidenceGroups(facts).map((group) => (\n <View key={group.label} style={styles.group}>\n <Text style={styles.label}>{group.label}</Text>\n {group.values.map((value, index) => (\n <Text key={`${String(index)}-${value}`} selectable style={[styles.sans, styles.text]}>\n {value}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n // One line on the title's row: the issue stays whole up to most of the row, the counts truncate first.\n summary: { flex: 1, flexDirection: 'row', alignItems: 'center', gap: theme.spacing(2), minWidth: 0 },\n sans: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n },\n primary: { flexShrink: 0, maxWidth: '70%', color: theme.colors.text },\n secondary: { flexShrink: 1, color: theme.colors.faint },\n lines: { gap: theme.spacing(0.5) },\n evidence: { gap: theme.spacing(3) },\n facts: {\n gap: theme.spacing(3),\n paddingTop: theme.spacing(3),\n borderTopWidth: 1,\n borderTopColor: theme.colors['border-soft'],\n },\n group: { gap: theme.spacing(0.5) },\n label: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n fontWeight: theme.fontWeight.semibold,\n color: theme.colors.dim,\n },\n bold: { fontWeight: theme.fontWeight.semibold },\n indent: { paddingLeft: theme.spacing(4) },\n error: { color: theme.colors.red },\n hi: { color: theme.colors.hi },\n text: { color: theme.colors.text },\n dim: { color: theme.colors.dim },\n muted: { color: theme.colors.faint },\n success: { color: theme.colors.green },\n warning: { color: theme.colors.yellow },\n accent: { color: theme.colors.blue },\n}));\n\n/** The line tones of the web's MessageLines, drawn with the same theme tokens. */\nconst TONE_STYLE: Readonly<Record<LineTone, object>> = {\n hi: styles.hi,\n text: styles.text,\n dim: styles.dim,\n muted: styles.muted,\n success: styles.success,\n error: styles.error,\n warning: styles.warning,\n accent: styles.accent,\n};\n","import { defineToolRenderer } from '@agimon-ai/po-core/native';\n\nimport { PlanReviewPrompt } from './_components/PlanReviewPrompt.native';\nimport { PlanToolMessage } from './_components/PlanToolMessage.native';\nimport { claimsPlanReviewPrompt, type PLAN_TOOL_NAMES } from './_lib/planToolRender';\n\n/*\n * The phone half of plan.web.tsx: one card for every plan tool. The names are\n * spelled out because the native renderer check reads only `.native.` files;\n * `satisfies` keeps them to the shared PLAN_TOOL_NAMES list.\n */\nexport default defineToolRenderer({\n tools: ['record_debug_evidence', 'run_fable_plan', 'write_plan', 'complete_plan'] satisfies Array<\n (typeof PLAN_TOOL_NAMES)[number]\n >,\n message: PlanToolMessage,\n prompt: { claims: claimsPlanReviewPrompt, component: PlanReviewPrompt },\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport settingPlan from '../src/extensions/(frontend)/setting/plan.native';\nimport settingPlan2 from '../src/extensions/workspaces/(frontend)/setting/plan.native';\nimport activityGroupPlan from '../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.native';\nimport fillPlan from '../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.native';\nimport toolPlan from '../src/extensions/workspaces/sessions/(frontend)/tool/plan.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'plan',\n global: {\n get settingsSections(): WebPluginContributions['settingsSections'] { return [via({ id: 'plan' }, settingPlan)]; },\n },\n workspace: {\n get settingsSections(): WebPluginContributions['settingsSections'] { return [via({ id: 'plan' }, settingPlan2)]; },\n },\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'plan' }, activityGroupPlan)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'activity.plan', id: 'plan' }, fillPlan)]; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['plan'] }, toolPlan)]; },\n },\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-plan",
3
- "version": "0.0.0-alpha.98",
3
+ "version": "0.0.0-alpha.99",
4
4
  "description": "Reviewable Pi planning mode that removes file-editing tools and persists implementation plans.",
5
5
  "keywords": [
6
6
  "ai",
@@ -84,18 +84,18 @@
84
84
  "registry": "https://registry.npmjs.org/"
85
85
  },
86
86
  "dependencies": {
87
- "@agimon-ai/po-config": "0.0.0-alpha.98",
88
- "@agimon-ai/po-core": "0.0.0-alpha.98",
89
- "@agimon-ai/po-minor-mode": "0.0.0-alpha.98",
90
- "@agimon-ai/po-web-components": "0.0.0-alpha.98",
91
- "@agimon-ai/po-web-security": "0.0.0-alpha.98",
87
+ "@agimon-ai/po-config": "0.0.0-alpha.99",
88
+ "@agimon-ai/po-core": "0.0.0-alpha.99",
89
+ "@agimon-ai/po-minor-mode": "0.0.0-alpha.99",
90
+ "@agimon-ai/po-web-components": "0.0.0-alpha.99",
91
+ "@agimon-ai/po-web-security": "0.0.0-alpha.99",
92
92
  "@deepseek-ai/cordis": "4.0.5",
93
93
  "hono": "4.13.13",
94
94
  "typebox": "1.4.2"
95
95
  },
96
96
  "devDependencies": {
97
- "@agimon-ai/po-build": "0.0.0-alpha.98",
98
- "@agimon-ai/po-native-components": "0.0.0-alpha.98",
97
+ "@agimon-ai/po-build": "0.0.0-alpha.99",
98
+ "@agimon-ai/po-native-components": "0.0.0-alpha.99",
99
99
  "@earendil-works/pi-coding-agent": "1.4.0",
100
100
  "@tanstack/react-store": "0.11.2",
101
101
  "@tanstack/store": "0.11.2",
@@ -111,7 +111,7 @@
111
111
  "vitest": "5.0.4"
112
112
  },
113
113
  "peerDependencies": {
114
- "@agimon-ai/po-native-components": "0.0.0-alpha.98",
114
+ "@agimon-ai/po-native-components": "0.0.0-alpha.99",
115
115
  "@earendil-works/pi-coding-agent": "1.4.0",
116
116
  "react-native": "0.88.0",
117
117
  "react-native-unistyles": "^3.5.3"
@@ -151,6 +151,8 @@
151
151
  "channels": [],
152
152
  "client": "./dist/extensions/native.mjs",
153
153
  "scopes": [
154
+ "global",
155
+ "workspace",
154
156
  "session"
155
157
  ]
156
158
  },