{"version":3,"file":"web.mjs","names":["routes","settingPlan","settingPlan2","activityGroupPlan","fillPlan","leaderToggle","modePlan","toolPlan"],"sources":["../../src/types/planSettings.ts","../../src/extensions/(frontend)/_lib/planSettings.ts","../../src/extensions/(frontend)/setting/plan.web.ts","../../src/extensions/workspaces/(frontend)/setting/plan.web.ts","../../src/types/planApi.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.web.ts","../../src/types/apiRoutes.ts","../../generated/client.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_lib/planApi.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanPanel.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/PlanActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/leader/toggle.web.ts","../../src/extensions/workspaces/sessions/(frontend)/mode/plan/mode.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanReviewPrompt.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/planToolRender.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/PlanToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/plan.web.tsx","../../generated/web.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 DOOM_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: '~/.pi/plans',\n    detail: 'absolute, repo-relative, or under ~. written plans land here.',\n  },\n];\n","import type { SettingsSectionContribution } from '@agimon-ai/doompi-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/doompi-core/web';\n\nimport { planSettingsSection } from '../_lib/planSettings';\n\nexport default defineSettingsSection(planSettingsSection);\n","import { defineSettingsSection } from '@agimon-ai/doompi-core/web';\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 = 'doom-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 facet 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/doompi-core/web';\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 { apiResponse, defineApiRoutes } from '@agimon-ai/doompi-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 */\nexport default defineApiRoutes({\n  current: {\n    method: 'GET',\n    path: '/current',\n    response: apiResponse<PlanDetailView>(),\n  },\n  save: {\n    method: 'PUT',\n    path: '/content',\n    response: apiResponse<PlanSaveView>(),\n  },\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { createApiClient, sessionApiAddress } from '@agimon-ai/doompi-core/web';\nimport { sealedTransport } from '@agimon-ai/doompi-web-security/browser';\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: (input, init) => sealedTransport.fetch(input, init),\n  sessionAddress: sessionApiAddress,\n});\n","import { api } from '../../../../../../../generated/client';\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 { TransientTab, WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\nimport { Button, CodeEditor, Markdown } from '@agimon-ai/doompi-web-components';\nimport { useEffect, useState } from 'react';\n\nimport { PLAN_STATUS_KEY, type PlanDetailView } from '../../../../../../types/planApi';\nimport { fetchPlan, savePlan } from '../_lib/planApi';\n\n/**\n * The plan's tab: what the agent decided, and what the reader wants changed.\n *\n * Two views over the same file. A plan is read, not diffed, so preview is\n * where it opens; source is a real editor, line numbers and markdown colour\n * and all, because a reader who corrects a step themselves is cheaper than a\n * turn spent asking for it. The save goes to the plan file the\n * session recorded, and the next turn reads that file, so a correction made\n * here is the plan the agent implements.\n *\n * The tab is transient: it belongs to the session and the page, and closing it\n * is how it ends. It refetches whenever the session republishes its plan\n * status, which is what a rewrite by the agent looks like from here.\n */\n\ntype View = 'preview' | 'source';\n\n/** One tab per session; the plan is singular, so the id needs nothing else. */\nexport const PLAN_TAB_ID = 'plan-document';\n\n/** The one note that is not an error: anything else in that slot failed. */\nconst SAVED_NOTE = 'saved';\n\nexport function PlanPanel({ sessionId, statuses, closeTransientTab }: WebPluginSlotProps) {\n  const [detail, setDetail] = useState<PlanDetailView | undefined>(undefined);\n  const [error, setError] = useState<string | undefined>(undefined);\n  const [loading, setLoading] = useState(false);\n  const [view, setView] = useState<View>('preview');\n  const [draft, setDraft] = useState<string | undefined>(undefined);\n  const [saving, setSaving] = useState(false);\n  const [saveNote, setSaveNote] = useState<string | undefined>(undefined);\n\n  // One fetch per open, and again whenever the session republishes the status:\n  // its stamp changes on every write, which is the cheapest signal that the\n  // agent has revised the plan under the reader.\n  const revision = statuses[PLAN_STATUS_KEY] ?? '';\n  useEffect(() => {\n    if (sessionId === null) return;\n    let cancelled = false;\n    // The fetch below is the external system; this marks it in flight before it starts.\n    // oxlint-disable-next-line react/set-state-in-effect\n    setLoading(true);\n    void fetchPlan(sessionId).then((result) => {\n      if (cancelled) return;\n      setLoading(false);\n      if (result.ok) {\n        setDetail(result.detail);\n        setError(undefined);\n        // A rewrite invalidates an unsaved edit's baseline, so the editor goes\n        // back to what is on disk rather than offering a save that must fail.\n        setDraft(undefined);\n        setSaveNote(undefined);\n        return;\n      }\n      setDetail(undefined);\n      setError(result.error);\n    });\n    return () => {\n      cancelled = true;\n    };\n  }, [sessionId, revision]);\n\n  const content = draft ?? detail?.content ?? '';\n\n  const save = async (): Promise<void> => {\n    if (sessionId === null || detail === undefined || draft === undefined) return;\n    setSaving(true);\n    const result = await savePlan(sessionId, detail.hash, draft);\n    setSaving(false);\n    if (result.ok) {\n      setSaveNote(SAVED_NOTE);\n      setDraft(undefined);\n      const refreshed = await fetchPlan(sessionId);\n      if (refreshed.ok) setDetail(refreshed.detail);\n      else setError(refreshed.error);\n      return;\n    }\n    setSaveNote(result.error);\n  };\n\n  return (\n    <div data-testid=\"plan-panel\" className=\"flex min-h-0 flex-1 flex-col\">\n      <header className=\"flex shrink-0 items-center gap-2 border-b border-doom-border px-4 py-2\">\n        <span data-testid=\"plan-title\" className=\"min-w-0 flex-1 truncate text-sm font-bold text-doom-hi\">\n          {detail?.title ?? 'plan'}\n        </span>\n        <nav className=\"flex shrink-0 items-center gap-1\">\n          {(['preview', 'source'] as View[]).map((entry) => (\n            <Button\n              key={entry}\n              variant={view === entry ? 'outline' : 'ghost'}\n              size=\"xs\"\n              data-testid={`plan-view-${entry}`}\n              onClick={() => setView(entry)}\n              className=\"text-2xs\"\n            >\n              {entry}\n            </Button>\n          ))}\n        </nav>\n        <Button\n          variant=\"ghost\"\n          size=\"xs\"\n          data-testid=\"plan-close\"\n          onClick={() => closeTransientTab(PLAN_TAB_ID)}\n          className=\"shrink-0 text-2xs\"\n        >\n          close\n        </Button>\n      </header>\n\n      {loading && detail === undefined ? (\n        <p data-testid=\"plan-loading\" className=\"px-4 py-3 text-sm text-doom-faint\">\n          reading this session's plan…\n        </p>\n      ) : null}\n      {error === undefined ? null : (\n        <p data-testid=\"plan-error\" className=\"px-4 py-3 text-sm text-doom-red\">\n          {error}\n        </p>\n      )}\n\n      <div className=\"flex min-h-0 flex-1 flex-col\">\n        {detail === undefined ? null : detail.unavailable ? (\n          <p data-testid=\"plan-unavailable\" className=\"px-4 py-3 text-sm text-doom-faint\">\n            {detail.reason ?? 'this plan cannot be shown'}\n          </p>\n        ) : view === 'preview' ? (\n          <div\n            data-testid=\"plan-preview\"\n            className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-4 text-sm text-doom-text\"\n          >\n            <Markdown text={content} />\n          </div>\n        ) : (\n          <>\n            {/* The editor owns the scrolling: its gutter has to stay put while\n                the text moves, which an outer scroll container would break. */}\n            <CodeEditor\n              data-testid=\"plan-source\"\n              value={content}\n              path={detail.path}\n              onChange={setDraft}\n              className=\"min-h-0 flex-1\"\n            />\n            <div className=\"flex shrink-0 items-center gap-2 border-t border-doom-border px-3 py-2\">\n              <Button\n                variant=\"outline\"\n                size=\"xs\"\n                data-testid=\"plan-save\"\n                loading={saving}\n                disabled={draft === undefined || saving}\n                onClick={() => void save()}\n                className=\"text-2xs\"\n              >\n                save to disk\n              </Button>\n              {draft === undefined ? null : (\n                <Button\n                  variant=\"ghost\"\n                  size=\"xs\"\n                  data-testid=\"plan-revert\"\n                  onClick={() => setDraft(undefined)}\n                  className=\"text-2xs\"\n                >\n                  discard edits\n                </Button>\n              )}\n              {saveNote === undefined ? null : (\n                <span\n                  data-testid=\"plan-save-note\"\n                  className={saveNote === SAVED_NOTE ? 'text-2xs text-doom-green' : 'text-2xs text-doom-red'}\n                >\n                  {saveNote}\n                </span>\n              )}\n            </div>\n          </>\n        )}\n      </div>\n\n      {detail === undefined ? null : (\n        <footer data-testid=\"plan-source-path\" className=\"shrink-0 truncate border-t border-doom-border px-4 py-1.5\">\n          <span className=\"text-2xs text-doom-faint\">{detail.path}</span>\n        </footer>\n      )}\n    </div>\n  );\n}\n\n/** The transient tab the plan opens in; opening it again only focuses it. */\nexport function planTab(): TransientTab {\n  return { id: PLAN_TAB_ID, label: 'plan', panel: PlanPanel };\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\nimport { Button } from '@agimon-ai/doompi-web-components';\n\nimport { parsePlanStatus, PLAN_STATUS_KEY } from '../../../../../../types/planApi';\nimport { planTab } from './PlanPanel';\n\n/**\n * The plan group's body in the activity dock: the plan this session wrote, and\n * the way in.\n *\n * A plan is one document, so the group is one row rather than a list. The row\n * is the whole point of the group: a written plan the reader cannot open is a\n * path in a tool card, which is what this replaces.\n *\n * The session's status line carries the title and the time it was last\n * written, so the row says what the plan is and whether the agent has revised\n * it since the reader last looked, without the dock holding any state.\n */\nexport function PlanActivitySection({ sessionId, statuses, openTransientTab }: WebPluginSlotProps) {\n  const view = parsePlanStatus(statuses[PLAN_STATUS_KEY]);\n\n  if (view === undefined) {\n    return (\n      <p data-testid=\"activity-summary-plan\" className=\"px-1 text-xs text-doom-faint\">\n        no plan written yet\n      </p>\n    );\n  }\n\n  return (\n    <div data-testid=\"activity-plan\" className=\"flex flex-col gap-0.5\">\n      <Button\n        variant=\"ghost\"\n        size=\"card\"\n        data-testid=\"activity-plan-open\"\n        title={`open ${view.title}`}\n        disabled={sessionId === null}\n        onClick={() => {\n          if (sessionId === null) return;\n          openTransientTab(planTab());\n        }}\n        className=\"min-w-0 gap-0.5 rounded-md px-1 py-1 hover:bg-doom-panel\"\n      >\n        <span className=\"flex w-full min-w-0 items-center gap-1.5\">\n          <span\n            data-testid=\"activity-plan-title\"\n            className=\"min-w-0 flex-1 truncate text-left text-xs font-bold text-doom-hi\"\n          >\n            {view.title}\n          </span>\n          {view.stamp === '' ? null : (\n            <span data-testid=\"activity-plan-stamp\" className=\"shrink-0 text-2xs tabular-nums text-doom-faint\">\n              {view.stamp}\n            </span>\n          )}\n        </span>\n      </Button>\n      <p className=\"px-1 text-2xs leading-relaxed text-doom-faint\">\n        open to read or edit; the agent reads what you save.\n      </p>\n    </div>\n  );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { PlanActivitySection } from './_components/PlanActivitySection';\n\nexport default defineFill({ slot: 'activity.plan', id: 'plan', component: PlanActivitySection });\n","import { defineLeaderBinding } from '@agimon-ai/doompi-core/web';\n\nexport default defineLeaderBinding({\n  id: 'plan.toggle',\n  path: [\n    { key: 'p', label: 'plan', detail: 'read-only planning modes' },\n    { key: 'e', label: 'toggle', detail: 'enter or leave read-only planning' },\n  ],\n  command: 'minor plan',\n});\n","import { defineMinorModeFile } from '@agimon-ai/doompi-core/web';\n\nexport default defineMinorModeFile({ name: 'plan', keys: 'p e', statusKey: 'plan-mode', order: 20 });\n","import type { ToolPromptDialog, ToolPromptRenderProps } from '@agimon-ai/doompi-core/web';\nimport {\n  Button,\n  handleOptionListKey,\n  Kbd,\n  OptionList,\n  optionListHint,\n  SectionLabel,\n} from '@agimon-ai/doompi-web-components';\nimport { useEffect, useRef, useState } from 'react';\n\nimport { PLAN_REVIEW_OPTIONS, PLAN_REVIEW_TITLE } from '../../../../../../types/planApi';\n\n/** Claims only the selector opened by complete_plan, leaving unrelated extension dialogs alone. */\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/** Keeps plan approval in the composer so the conversation remains visible while the user decides. */\nexport function PlanReviewPrompt({ dialog, answer, cancel }: ToolPromptRenderProps) {\n  const [cursor, setCursor] = useState(0);\n  const frame = useRef<HTMLDivElement>(null);\n\n  useEffect(() => frame.current?.focus(), [dialog.id]);\n\n  return (\n    <div\n      ref={frame}\n      role=\"group\"\n      tabIndex={-1}\n      data-testid=\"plan-review-prompt\"\n      className=\"flex min-w-0 flex-col overflow-hidden outline-none\"\n      onKeyDown={(event) => {\n        if (event.key === 'Escape') {\n          event.preventDefault();\n          event.stopPropagation();\n          cancel();\n          return;\n        }\n        handleOptionListKey(event, {\n          options: dialog.options,\n          cursor,\n          onCursorChange: setCursor,\n          onSelect: answer,\n        });\n      }}\n    >\n      <div className=\"flex flex-col gap-1 px-3.5 pt-3 pb-2\">\n        <SectionLabel>plan review</SectionLabel>\n        <p className=\"text-base leading-relaxed text-doom-hi\">{dialog.title}</p>\n        <p className=\"text-sm leading-relaxed text-doom-dim\">\n          Review the plan in the conversation before choosing what happens next.\n        </p>\n      </div>\n\n      <OptionList\n        options={dialog.options}\n        cursor={cursor}\n        onCursorChange={setCursor}\n        onSelect={answer}\n        testIdPrefix=\"plan-review-option\"\n        className=\"max-h-48 px-3.5 pb-3\"\n      />\n\n      <div className=\"flex min-h-[34px] items-center gap-2 border-t border-doom-border-soft px-3.5 py-2\">\n        <span className=\"text-xs text-doom-faint\">\n          {optionListHint(dialog.options.length)} · <Kbd>esc</Kbd> cancels\n        </span>\n        <Button variant=\"outline\" size=\"sm\" data-testid=\"plan-review-cancel\" className=\"ml-auto\" onClick={cancel}>\n          cancel\n        </Button>\n      </div>\n    </div>\n  );\n}\n","import type { ToolResultView } from '@agimon-ai/doompi-core/web';\nimport type { MessageLine, MessageLineTone } from '@agimon-ai/doompi-web-components';\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/planMode.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/** The toned lines the shared MessageLines draws; the vocabulary is the components package's. */\nexport type LineTone = MessageLineTone;\nexport type ToolLine = MessageLine;\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'));\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/** 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    const text = inlineText(outputText(result));\n    return [line(`✗ ${text || `${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/doompi-core/web';\nimport {\n  MessageItem,\n  MessageItemBody,\n  MessageItemHeader,\n  MessageLines,\n  toolTone,\n} from '@agimon-ai/doompi-web-components';\n\nimport { planCallSummary, planResultLines } from '../_lib/planToolRender';\n\n/**\n * The plan tools' timeline item: the plan action, the issue or decision it\n * targets, and what the packet carries in the header; the outcome line, with\n * the recorded evidence or the Fable draft once expanded, in the body.\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  return (\n    <MessageItem tone={toolTone({ running, isError })} expandable={full.length > collapsed.length}>\n      {({ expanded }) => (\n        <>\n          <MessageItemHeader title={summary.action}>\n            <span\n              data-testid={`tool-call-${toolName}`}\n              title={[summary.detail, ...summary.metadata].filter(Boolean).join(' · ') || undefined}\n              className=\"min-w-0 flex-1 truncate text-doom-dim\"\n            >\n              {[summary.detail, ...summary.metadata].filter(Boolean).join(' · ')}\n            </span>\n          </MessageItemHeader>\n          {(expanded ? full : collapsed).length > 0 ? (\n            <MessageItemBody data-testid={`tool-result-${toolName}`}>\n              <MessageLines lines={expanded ? full : collapsed} />\n            </MessageItemBody>\n          ) : null}\n        </>\n      )}\n    </MessageItem>\n  );\n}\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { claimsPlanReviewPrompt, PlanReviewPrompt } from './_components/PlanReviewPrompt';\nimport { PlanToolMessage } from './_components/PlanToolMessage';\nimport { PLAN_TOOL_NAMES } from './_lib/planToolRender';\n\nexport default defineToolRenderer({\n  tools: [...PLAN_TOOL_NAMES],\n  message: PlanToolMessage,\n  prompt: { claims: claimsPlanReviewPrompt, component: PlanReviewPrompt },\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport settingPlan from '../src/extensions/(frontend)/setting/plan.web';\nimport settingPlan2 from '../src/extensions/workspaces/(frontend)/setting/plan.web';\nimport activityGroupPlan from '../src/extensions/workspaces/sessions/(frontend)/activity-group/plan.web';\nimport fillPlan from '../src/extensions/workspaces/sessions/(frontend)/fill/Plan.activity.plan.web';\nimport leaderToggle from '../src/extensions/workspaces/sessions/(frontend)/leader/toggle.web';\nimport modePlan from '../src/extensions/workspaces/sessions/(frontend)/mode/plan/mode.web';\nimport toolPlan from '../src/extensions/workspaces/sessions/(frontend)/tool/plan.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n  (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n  id: '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 leaderBindings(): WebPluginContributions['leaderBindings'] { return [via({ id: 'plan.toggle' }, leaderToggle)]; },\n    get minorModes(): WebPluginContributions['minorModes'] { return [via({ name: 'plan' }, modePlan)]; },\n    get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['plan'] }, toolPlan)]; },\n  },\n});\n"],"mappings":"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"}