@anhlp/alp-paseo 0.0.0-beta.2 → 0.0.1-beta.3

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.
@@ -7806,7 +7806,7 @@ var require_content_type = __commonJS({
7806
7806
  import { createHash as createHash5 } from "node:crypto";
7807
7807
 
7808
7808
  // alp-plugin-client:plugin-client
7809
- var plugin_client_default = { "id": "alp-provider", "requirements": { "paseo": ">=0.11.1 <0.12.0" }, "factory": '(function(require){const module={exports:{}};const exports=module.exports;var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === "object" || typeof from === "function") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { value: from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\nvar __async = (__this, __arguments, generator) => {\n return new Promise((resolve, reject) => {\n var fulfilled = (value) => {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n };\n var rejected = (value) => {\n try {\n step(generator.throw(value));\n } catch (e) {\n reject(e);\n }\n };\n var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);\n step((generator = generator.apply(__this, __arguments)).next());\n });\n};\n\n// integrations/paseo/index.client.tsx\nvar index_client_exports = {};\n__export(index_client_exports, {\n default: () => contribute\n});\nmodule.exports = __toCommonJS(index_client_exports);\n\n// integrations/paseo/client/tasks-panel.tsx\nvar import_client = require("@getpaseo/plugin/client");\nvar import_react_native = require("@getpaseo/plugin/client/react-native");\nvar import_react = require("react");\nvar import_react_native2 = require("react-native");\n\n// integrations/paseo/shared/tasks.ts\nvar import_plugin = require("@getpaseo/plugin");\nvar import_zod = require("zod");\nvar TaskRowSchema = import_zod.z.object({\n id: import_zod.z.string(),\n title: import_zod.z.string(),\n type: import_zod.z.string(),\n priority: import_zod.z.number(),\n status: import_zod.z.enum(["open", "in_progress", "review", "closed"]),\n parent: import_zod.z.string().optional(),\n assignee: import_zod.z.string().optional(),\n ready: import_zod.z.boolean(),\n /** Open tasks that must close first, including those of ancestors. */\n blockedBy: import_zod.z.array(import_zod.z.string()).optional(),\n /** Open gates, as labels. */\n waits: import_zod.z.array(import_zod.z.string()).optional(),\n /** Open human gates of this task: the user approves them here. */\n approvals: import_zod.z.array(import_zod.z.object({ gate: import_zod.z.string(), note: import_zod.z.string() })).optional(),\n handoff: import_zod.z.object({ outcome: import_zod.z.string(), summary: import_zod.z.string(), agent: import_zod.z.string().optional() }).optional(),\n closed: import_zod.z.object({ reason: import_zod.z.string(), summary: import_zod.z.string().optional(), at: import_zod.z.string() }).optional(),\n /** What the task is about, for its detail view; at most 4000 characters. */\n description: import_zod.z.string().optional(),\n labels: import_zod.z.array(import_zod.z.string()).optional(),\n paths: import_zod.z.array(import_zod.z.string()).optional(),\n /** An epic or parent task: how many of its children are closed. */\n progress: import_zod.z.object({ done: import_zod.z.number(), total: import_zod.z.number() }).optional(),\n createdAt: import_zod.z.string().optional(),\n updatedAt: import_zod.z.string()\n});\nvar Directory = import_zod.z.string().min(1);\nvar tasksList = (0, import_plugin.defineRpc)({\n name: "alp.tasks.list",\n input: import_zod.z.object({ directory: Directory }),\n output: import_zod.z.object({\n /** The ALP project containing the directory, or null when there is none. */\n projectRoot: import_zod.z.string().nullable(),\n tasks: import_zod.z.array(TaskRowSchema),\n unreadable: import_zod.z.array(import_zod.z.object({ file: import_zod.z.string(), error: import_zod.z.string() })),\n /** By provider session id: the tasks that session\'s tree worked on (ALPD \xA755). */\n sessions: import_zod.z.record(import_zod.z.string(), import_zod.z.array(import_zod.z.string())).optional()\n })\n});\nvar tasksAdd = (0, import_plugin.defineRpc)({\n name: "alp.tasks.add",\n input: import_zod.z.object({ directory: Directory, title: import_zod.z.string().trim().min(1).max(200), priority: import_zod.z.number().int().min(0).max(4).optional() }),\n output: import_zod.z.object({ id: import_zod.z.string() })\n});\nvar tasksChange = (0, import_plugin.defineRpc)({\n name: "alp.tasks.change",\n input: import_zod.z.object({\n directory: Directory,\n id: import_zod.z.string().min(1),\n action: import_zod.z.enum(["close", "reopen", "approve"]),\n /** For approve: the human gate. */\n gate: import_zod.z.string().optional(),\n note: import_zod.z.string().max(2e3).optional()\n }),\n /** landed: the first line of the report when the close landed an epic. */\n output: import_zod.z.object({ id: import_zod.z.string(), status: import_zod.z.string(), landed: import_zod.z.string().optional() })\n});\nvar rank = (a, b) => a.priority - b.priority || a.id.localeCompare(b.id);\nfunction boardSections(tasks, closedLimit = 20) {\n const open = tasks.filter((task) => task.status !== "closed");\n const sections = [\n { key: "approve", title: "Waiting for your approval", tasks: open.filter((task) => task.approvals?.length).sort(rank) },\n { key: "review", title: "In review", tasks: open.filter((task) => task.status === "review").sort(rank) },\n { key: "progress", title: "In progress", tasks: open.filter((task) => task.status === "in_progress").sort(rank) },\n { key: "ready", title: "Ready", tasks: open.filter((task) => task.ready).sort(rank) },\n { key: "waiting", title: "Blocked or waiting", tasks: open.filter((task) => task.status === "open" && !task.ready && !task.approvals?.length && task.type !== "epic").sort(rank) },\n { key: "epics", title: "Epics", tasks: open.filter((task) => task.type === "epic" && !task.approvals?.length).sort(rank) },\n { key: "closed", title: "Closed", tasks: tasks.filter((task) => task.status === "closed").sort((a, b) => (b.closed?.at ?? b.updatedAt).localeCompare(a.closed?.at ?? a.updatedAt)).slice(0, closedLimit) }\n ];\n return sections.filter((section) => section.tasks.length);\n}\n\n// integrations/paseo/client/tasks-panel.tsx\nvar import_jsx_runtime = require("react/jsx-runtime");\nvar POLL_MS = 5e3;\nvar SPLIT_FROM = 820;\nfunction TasksPanel({ theme, layout, workspaceId }) {\n const directory = (0, import_client.useWorkspace)(workspaceId, (workspace) => workspace.directory || workspace.projectRootPath);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskBoard, { theme, compact: layout.compact, directory, ...useTasks(directory) });\n}\nfunction TasksScreen({ theme, layout, params }) {\n const directory = params.directory || null;\n const tasks = useTasks(directory);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n TaskBoard,\n {\n theme,\n compact: layout.compact,\n directory,\n ...tasks,\n initial: params.taskId ? { selected: params.taskId } : void 0\n },\n params.taskId ?? ""\n );\n}\nfunction useTasks(directory) {\n const list = (0, import_client.useRpc)(tasksList);\n const add = (0, import_client.useRpc)(tasksAdd);\n const change = (0, import_client.useRpc)(tasksChange);\n const toast = (0, import_react_native.useToast)();\n const [data, setData] = (0, import_react.useState)(null);\n const [error, setError] = (0, import_react.useState)(null);\n const [tick, setTick] = (0, import_react.useState)(0);\n const refresh = (0, import_react.useCallback)(() => setTick((value) => value + 1), []);\n (0, import_react.useEffect)(() => {\n if (!directory) return;\n let live = true;\n const load = () => list({ directory }).then((result) => {\n if (live) {\n setData(result);\n setError(null);\n }\n }).catch((cause) => {\n if (live) setError(cause instanceof Error ? cause.message : String(cause));\n });\n void load();\n const timer = setInterval(load, POLL_MS);\n return () => {\n live = false;\n clearInterval(timer);\n };\n }, [directory, list, tick]);\n const onAdd = (0, import_react.useCallback)((title, priority) => __async(null, null, function* () {\n if (!directory) return false;\n try {\n const { id } = yield add({ directory, title, priority });\n toast.show(`Added ${id}`, { variant: "success" });\n refresh();\n return true;\n } catch (cause) {\n toast.error(cause instanceof Error ? cause.message : String(cause));\n return false;\n }\n }), [add, directory, refresh, toast]);\n const onAction = (0, import_react.useCallback)((_0) => __async(null, [_0], function* ({ id, action, gate }) {\n if (!directory) return;\n try {\n const { landed } = yield change({ directory, id, action, ...gate ? { gate } : {} });\n toast.show(landed ?? (action === "approve" ? `Approved ${id}` : action === "close" ? `Closed ${id}` : `Reopened ${id}`), { variant: "success" });\n refresh();\n } catch (cause) {\n toast.error(cause instanceof Error ? cause.message : String(cause));\n }\n }), [change, directory, refresh, toast]);\n return { projectRoot: data?.projectRoot ?? null, tasks: data?.tasks ?? null, unreadable: data?.unreadable.length ?? 0, error, onAdd, onAction, onRefresh: refresh };\n}\nvar PRIORITIES = [0, 1, 2, 3, 4];\nvar TYPE_ICONS = { bug: "Bug", feature: "Sparkles", task: "SquareCheck", chore: "Wrench", epic: "Target" };\nvar hovered = (state) => !!state.hovered;\nfunction age(iso, now = Date.now()) {\n if (!iso) return "";\n const minutes = Math.max(0, Math.floor((now - Date.parse(iso)) / 6e4));\n if (minutes < 60) return `${minutes}m`;\n if (minutes < 60 * 24) return `${Math.floor(minutes / 60)}h`;\n if (minutes < 60 * 24 * 14) return `${Math.floor(minutes / 1440)}d`;\n return `${Math.floor(minutes / 10080)}w`;\n}\nfunction stateOf(task) {\n if (task.status === "closed") return "closed";\n if (task.approvals?.length) return "approve";\n if (task.status === "review") return "review";\n if (task.status === "in_progress") return "progress";\n if (task.type === "epic") return task.progress?.done ? "progress" : "ready";\n return task.ready ? "ready" : "blocked";\n}\nvar STATE_LABELS = { approve: "Needs approval", review: "In review", progress: "In progress", ready: "Ready", blocked: "Blocked", closed: "Closed" };\nfunction filterTasks(tasks, filter, query) {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean);\n return tasks.filter((task) => {\n if (filter === "open" && task.status === "closed") return false;\n if (filter === "ready" && !(task.ready && task.status !== "closed")) return false;\n if (filter === "closed" && task.status !== "closed") return false;\n const text = [task.id, task.title, task.type, task.assignee ?? "", ...task.labels ?? []].join(" ").toLowerCase();\n return words.every((word) => text.includes(word));\n });\n}\nfunction TaskBoard({ theme, compact, directory, projectRoot, tasks, unreadable, error, onAdd, onAction, onRefresh, initial }) {\n const styles = (0, import_react.useMemo)(() => makeStyles(theme, compact), [theme, compact]);\n const [view, setView] = (0, import_react.useState)(initial?.view ?? "list");\n const [filter, setFilter] = (0, import_react.useState)(initial?.filter ?? "open");\n const [query, setQuery] = (0, import_react.useState)("");\n const [selected, setSelected] = (0, import_react.useState)(initial?.selected ?? null);\n const [composing, setComposing] = (0, import_react.useState)(false);\n const [width, setWidth] = (0, import_react.useState)(initial?.width ?? 0);\n const shown = (0, import_react.useMemo)(() => tasks ? filterTasks(tasks, filter, query) : [], [tasks, filter, query]);\n const task = selected ? tasks?.find((candidate) => candidate.id === selected) ?? null : null;\n const split = !!task && width >= SPLIT_FROM;\n const counts = (0, import_react.useMemo)(() => ({\n open: (tasks ?? []).filter((entry) => entry.status !== "closed").length,\n ready: (tasks ?? []).filter((entry) => entry.ready && entry.status !== "closed").length,\n closed: (tasks ?? []).filter((entry) => entry.status === "closed").length,\n all: (tasks ?? []).length\n }), [tasks]);\n if (!directory) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.muted, children: "This view needs a workspace." }) });\n const open = (id) => setSelected(id);\n const detail = task ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskDetail, { theme, styles, task, tasks: tasks ?? [], onBack: () => setSelected(null), onOpen: open, onAction }) : null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.screen, onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbar, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbarRow, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.title, children: "Tasks" }),\n tasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.count, children: [\n counts.open,\n " open"\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { flex: 1 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n Segmented,\n {\n theme,\n styles,\n value: view,\n onChange: (value) => {\n setView(value);\n setSelected(null);\n },\n options: [{ key: "list", label: "List", icon: "List" }, { key: "board", label: "Board", icon: "Columns3" }, { key: "epics", label: "Epics", icon: "Target" }]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "RefreshCw", label: "Refresh", onPress: onRefresh }),\n projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "Plus", label: "New task", onPress: () => setComposing(!composing), primary: true }) : null\n ] }),\n projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbarRow, children: [\n ["open", "ready", "closed", "all"].map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Show ${key}`, accessibilityState: { selected: filter === key }, onPress: () => setFilter(key), style: [styles.filter, filter === key ? styles.filterOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: filter === key ? styles.filterTextOn : styles.filterText, children: [\n key[0].toUpperCase() + key.slice(1),\n " ",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.filterCount, children: counts[key] })\n ] }) }, key)),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.search, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: "Search", size: 14, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.TextInput, { style: styles.searchInput, value: query, onChangeText: setQuery, placeholder: "Filter by id, title, label, agent", placeholderTextColor: theme.colors.foregroundMuted, accessibilityLabel: "Filter tasks" })\n ] })\n ] }) : null,\n composing && projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Composer, { theme, styles, onAdd: (title, priority) => __async(null, null, function* () {\n const added = yield onAdd(title, priority);\n if (added) setComposing(false);\n return added;\n }) }) : null\n ] }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.danger, styles.pad], children: error }) : null,\n tasks === null && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.muted, styles.pad], children: "Loading tasks\\u2026" }) : null,\n tasks !== null && projectRoot === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: [styles.muted, styles.pad], children: [\n directory,\n " is not an ALP project. Run alp init to start one."\n ] }) : null,\n projectRoot && tasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.body, children: [\n !task || split ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: [styles.pane, split ? styles.paneList : null], children: [\n unreadable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: [styles.warning, styles.pad], children: [\n unreadable,\n " unreadable task ",\n unreadable === 1 ? "file" : "files",\n " in ",\n projectRoot,\n "/.alp/tasks"\n ] }) : null,\n !tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No tasks yet. Add one here, with alp task add, or ask main to plan the work." }) : null,\n tasks.length && !shown.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No tasks match." }) : null,\n shown.length && view === "list" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListView, { theme, styles, tasks: shown, selected, onOpen: open, onAction }) : null,\n shown.length && view === "board" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BoardView, { theme, styles, tasks: shown, onOpen: open }) : null,\n view === "epics" && tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EpicsView, { theme, styles, tasks, shown, onOpen: open }) : null\n ] }) : null,\n detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.pane, split ? styles.paneDetail : null], children: detail }) : null\n ] }) : null\n ] });\n}\nfunction Segmented({ theme, styles, value, options, onChange }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.segmented, children: options.map((option) => {\n const on = option.key === value;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "tab", accessibilityLabel: option.label, accessibilityState: { selected: on }, onPress: () => onChange(option.key), style: [styles.segment, on ? styles.segmentOn : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: option.icon, size: 13, color: on ? theme.colors.foreground : theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: on ? styles.segmentTextOn : styles.segmentText, children: option.label })\n ] }, option.key);\n }) });\n}\nfunction IconButton({ theme, icon, label, onPress, primary }) {\n const { colors } = theme;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_react_native2.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: label,\n onPress,\n style: (state) => ({ padding: 7, borderRadius: 8, backgroundColor: primary ? colors.accent : hovered(state) ? colors.surface2 : "transparent" }),\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: icon, size: 15, color: primary ? colors.accentForeground : colors.foregroundMuted })\n }\n );\n}\nfunction Composer({ theme, styles, onAdd }) {\n const [title, setTitle] = (0, import_react.useState)("");\n const [priority, setPriority] = (0, import_react.useState)(2);\n const submit = () => __async(null, null, function* () {\n const text = title.trim();\n if (text && (yield onAdd(text, priority))) setTitle("");\n });\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.composer, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.TextInput, { style: styles.input, value: title, onChangeText: setTitle, onSubmitEditing: submit, placeholder: "Add a task for main", placeholderTextColor: theme.colors.foregroundMuted, accessibilityLabel: "New task title", autoFocus: true }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.priorities, children: PRIORITIES.map((value) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Priority ${value}`, onPress: () => setPriority(value), style: [styles.chip, value === priority ? styles.chipOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: value === priority ? styles.chipTextOn : styles.chipText, children: [\n "P",\n value\n ] }) }, value)) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", onPress: submit, style: styles.button, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.buttonText, children: "Add" }) })\n ] });\n}\nfunction Empty({ styles, text }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.muted, children: text }) });\n}\nfunction Priority({ theme, value }) {\n const { colors } = theme;\n const color = value === 0 ? colors.statusDanger : value === 1 ? colors.statusWarning : colors.foregroundMuted;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { alignSelf: "flex-start", borderRadius: 4, borderWidth: 1, borderColor: value <= 1 ? color : colors.border, paddingHorizontal: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: { color, fontSize: 10.5, fontWeight: "600", fontVariant: ["tabular-nums"] }, children: [\n "P",\n value\n ] }) });\n}\nfunction StateDot({ theme, task }) {\n const { colors } = theme;\n const state = stateOf(task);\n const color = state === "approve" ? colors.statusWarning : state === "review" ? colors.accent : state === "progress" ? colors.statusWarning : state === "ready" ? colors.statusSuccess : state === "blocked" ? colors.statusDanger : colors.border;\n const ring = state === "progress" || state === "closed";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { accessibilityLabel: STATE_LABELS[state], style: { width: 9, height: 9, borderRadius: 5, borderWidth: ring ? 2 : 0, borderColor: color, backgroundColor: ring ? "transparent" : color } });\n}\nfunction TaskLine({ theme, styles, task, selected, onOpen }) {\n const meta = [\n task.blockedBy?.length ? `after ${task.blockedBy.join(", ")}` : "",\n // Gates waiting for the user show with their Approve instead.\n task.waits?.length && !task.approvals?.length ? `waits on ${task.waits.join("; ")}` : "",\n task.parent ? `in ${task.parent}` : ""\n ].filter(Boolean).join(" \\xB7 ");\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${task.id}`, onPress: () => onOpen(task.id), style: (state) => [styles.line, selected ? styles.lineOn : hovered(state) ? styles.lineHover : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.lineTitle, numberOfLines: 1, children: task.title }),\n task.assignee ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.assignee, numberOfLines: 1, children: [\n "@",\n task.assignee\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.age, children: age(task.status === "closed" ? task.closed?.at : task.updatedAt) })\n ] }),\n meta || task.labels?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineMeta, children: [\n meta ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, numberOfLines: 1, children: meta }) : null,\n (task.labels ?? []).map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label))\n ] }) : null\n ] });\n}\nvar SECTION_ICONS = { approve: "Hand", review: "Eye", progress: "LoaderCircle", ready: "CircleCheck", waiting: "CircleSlash", epics: "Target", closed: "CircleDashed" };\nfunction ListView({ theme, styles, tasks, selected, onOpen, onAction }) {\n const sections = (0, import_react.useMemo)(() => boardSections(tasks), [tasks]);\n const [hidden, setHidden] = (0, import_react.useState)({});\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { contentContainerStyle: styles.listContent, children: sections.map((section) => {\n const collapsed = hidden[section.key] ?? false;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.group, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `${collapsed ? "Show" : "Hide"} ${section.title}`, onPress: () => setHidden((current) => ({ ...current, [section.key]: !collapsed })), style: styles.groupHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: collapsed ? "ChevronRight" : "ChevronDown", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: SECTION_ICONS[section.key] ?? "Circle", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupTitle, children: section.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupCount, children: section.tasks.length })\n ] }),\n !collapsed ? section.tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task, selected: task.id === selected, onOpen }),\n section.key === "approve" ? task.approvals.map((approval) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.inlineAction, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, numberOfLines: 2, children: approval.note || "Waiting for your approval" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Approve", primary: true, onPress: () => onAction({ id: task.id, action: "approve", gate: approval.gate }) })\n ] }, approval.gate)) : null\n ] }, `${section.key}-${task.id}`)) : null\n ] }, section.key);\n }) });\n}\nvar COLUMNS = [\n { key: "approve", title: "Needs approval" },\n { key: "blocked", title: "Blocked" },\n { key: "ready", title: "Ready" },\n { key: "progress", title: "In progress" },\n { key: "review", title: "In review" },\n { key: "closed", title: "Closed" }\n];\nfunction BoardView({ theme, styles, tasks, onOpen }) {\n const columns = COLUMNS.map((column) => ({ ...column, tasks: tasks.filter((task) => task.type !== "epic" && stateOf(task) === column.key) })).filter((column) => column.tasks.length || ["blocked", "ready", "progress"].includes(column.key));\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, contentContainerStyle: styles.board, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.column, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.columnHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task: { status: column.key === "closed" ? "closed" : column.key === "review" ? "review" : column.key === "progress" ? "in_progress" : "open", ready: column.key === "ready", approvals: column.key === "approve" ? [{ gate: "", note: "" }] : void 0 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.columnTitle, children: column.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupCount, children: column.tasks.length })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.ScrollView, { contentContainerStyle: styles.columnBody, children: [\n column.tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${task.id}`, onPress: () => onOpen(task.id), style: (state) => [styles.card, hovered(state) ? styles.cardHover : null, column.key === "blocked" ? styles.cardBlocked : column.key === "ready" ? styles.cardReady : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 12, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { flex: 1 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.age, children: age(task.updatedAt) })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.cardTitle, numberOfLines: 3, children: task.title }),\n task.assignee ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.assignee, numberOfLines: 1, children: [\n "@",\n task.assignee\n ] }) : null,\n task.blockedBy?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.blocked, numberOfLines: 1, children: [\n "after ",\n task.blockedBy.join(", ")\n ] }) : null,\n task.labels?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.cardLabels, children: task.labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label)) }) : null\n ] }, task.id)),\n !column.tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.small, styles.pad], children: "Nothing here" }) : null\n ] })\n ] }, column.key)) });\n}\nfunction EpicsView({ theme, styles, tasks, shown, onOpen }) {\n const epics = shown.filter((task) => task.type === "epic" || task.progress);\n const [opened, setOpened] = (0, import_react.useState)({});\n if (!epics.length) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No epics here. An epic is a task other tasks name as their parent." });\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { contentContainerStyle: styles.listContent, children: epics.map((epic) => {\n const children = tasks.filter((task) => task.parent === epic.id);\n const done = epic.progress?.done ?? 0;\n const total = epic.progress?.total ?? 0;\n const expanded = opened[epic.id] ?? epic.status !== "closed";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.epic, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${epic.id}`, onPress: () => onOpen(epic.id), style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task: epic }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: "Target", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: epic.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: epic.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.lineTitle, numberOfLines: 1, children: epic.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.progressText, children: [\n done,\n "/",\n total\n ] })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.progressTrack, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.progressFill, { width: `${total ? Math.round(done / total * 100) : 0}%` }] }) }),\n children.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `${expanded ? "Hide" : "Show"} the tasks of ${epic.id}`, onPress: () => setOpened((current) => ({ ...current, [epic.id]: !expanded })), style: styles.treeToggle, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: expanded ? "ChevronDown" : "ChevronRight", size: 12, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.small, children: [\n children.length,\n " ",\n children.length === 1 ? "task" : "tasks"\n ] })\n ] }) : null,\n expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.tree, children: children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task: child, selected: false, onOpen }, child.id)) }) : null\n ] }, epic.id);\n }) });\n}\nfunction SmallButton({ styles, label, onPress, primary, danger }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", onPress, style: [styles.smallButton, primary ? styles.smallButtonPrimary : null, danger ? styles.smallButtonDanger : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: primary ? styles.smallButtonTextPrimary : danger ? styles.smallButtonTextDanger : styles.smallButtonText, children: label }) });\n}\nfunction TaskDetail({ theme, styles, task, tasks, onBack, onOpen, onAction }) {\n const state = stateOf(task);\n const children = tasks.filter((entry) => entry.parent === task.id);\n const blocks = tasks.filter((entry) => entry.blockedBy?.includes(task.id) && entry.status !== "closed");\n const field = (label, value) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.field, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.fieldLabel, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.fieldValue, children: typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: value }) : value })\n ] });\n const link = (id) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "link", accessibilityLabel: `Open ${id}`, onPress: () => onOpen(id), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.link, children: id }) }, id);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.ScrollView, { contentContainerStyle: styles.detail, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.detailHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "ArrowLeft", label: "Back to the list", onPress: onBack }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.statePill, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, children: STATE_LABELS[state] })\n ] })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.detailTitle, children: task.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.fields, children: [\n field("Type", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.inline, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.type })\n ] })),\n field("Priority", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority })),\n task.assignee ? field("Assignee", `@${task.assignee}`) : null,\n task.parent ? field("Parent", link(task.parent)) : null,\n task.blockedBy?.length ? field("Blocked by", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: task.blockedBy.map(link) })) : null,\n blocks.length ? field("Blocks", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: blocks.map((entry) => link(entry.id)) })) : null,\n task.waits?.length ? field("Waits on", task.waits.join("; ")) : null,\n task.labels?.length ? field("Labels", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: task.labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label)) })) : null,\n task.paths?.length ? field("Paths", task.paths.join(", ")) : null,\n task.progress ? field("Progress", `${task.progress.done} of ${task.progress.total} closed`) : null,\n task.createdAt ? field("Created", `${age(task.createdAt)} ago`) : null,\n field("Updated", `${age(task.updatedAt)} ago`)\n ] }),\n task.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.boxTitle, children: "Description" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.description })\n ] }) : null,\n task.handoff ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Handoff \\xB7 ",\n task.handoff.outcome,\n task.handoff.agent ? ` from ${task.handoff.agent}` : ""\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.handoff.summary })\n ] }) : null,\n task.closed ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Closed \\xB7 ",\n task.closed.reason\n ] }),\n task.closed.summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.closed.summary }) : null\n ] }) : null,\n children.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Tasks \\xB7 ",\n children.filter((child) => child.status === "closed").length,\n "/",\n children.length,\n " closed"\n ] }),\n children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task: child, selected: false, onOpen }, child.id))\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.detailActions, children: [\n (task.approvals ?? []).map((approval) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, primary: true, label: `Approve${approval.note ? `: ${approval.note.slice(0, 40)}` : ""}`, onPress: () => onAction({ id: task.id, action: "approve", gate: approval.gate }) }, approval.gate)),\n state === "review" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, primary: true, label: "Accept and close", onPress: () => onAction({ id: task.id, action: "close" }) }) : null,\n task.status !== "closed" && state !== "review" && task.type !== "epic" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Close", onPress: () => onAction({ id: task.id, action: "close" }) }) : null,\n task.status === "closed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Reopen", onPress: () => onAction({ id: task.id, action: "reopen" }) }) : null\n ] })\n ] });\n}\nfunction makeStyles(theme, compact) {\n const { colors } = theme;\n const mono = { fontFamily: "monospace", fontVariant: ["tabular-nums"] };\n return {\n screen: { flex: 1, backgroundColor: colors.surface0 },\n pad: { paddingHorizontal: compact ? 12 : 16, paddingVertical: 8 },\n toolbar: { paddingHorizontal: compact ? 12 : 16, paddingTop: 12, paddingBottom: 10, gap: 10, borderBottomWidth: 1, borderBottomColor: colors.border },\n toolbarRow: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },\n title: { color: colors.foreground, fontSize: 15, fontWeight: "600" },\n count: { color: colors.foregroundMuted, fontSize: 12, marginLeft: 4 },\n segmented: { flexDirection: "row", backgroundColor: colors.surface1, borderRadius: 8, borderWidth: 1, borderColor: colors.border, padding: 2 },\n segment: { flexDirection: "row", alignItems: "center", gap: 5, paddingHorizontal: 8, paddingVertical: 4, borderRadius: 6 },\n segmentOn: { backgroundColor: colors.surface0, shadowColor: "#000", shadowOpacity: 0.08, shadowRadius: 2 },\n segmentText: { color: colors.foregroundMuted, fontSize: 12 },\n segmentTextOn: { color: colors.foreground, fontSize: 12, fontWeight: "600" },\n filter: { paddingHorizontal: 9, paddingVertical: 4, borderRadius: 999, borderWidth: 1, borderColor: colors.border },\n filterOn: { backgroundColor: colors.foreground, borderColor: colors.foreground },\n filterText: { color: colors.foreground, fontSize: 12 },\n filterTextOn: { color: colors.surface0, fontSize: 12, fontWeight: "600" },\n filterCount: { opacity: 0.6, fontSize: 11 },\n search: { flex: 1, minWidth: 160, flexDirection: "row", alignItems: "center", gap: 6, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 8, backgroundColor: colors.surface1 },\n searchInput: { flex: 1, minWidth: 0, color: colors.foreground, fontSize: 12.5, paddingVertical: 6 },\n composer: { flexDirection: compact ? "column" : "row", gap: 8, alignItems: compact ? "stretch" : "center" },\n input: { flex: compact ? void 0 : 1, minWidth: 0, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 7, backgroundColor: colors.surface1 },\n priorities: { flexDirection: "row", gap: 4 },\n chip: { paddingHorizontal: 7, paddingVertical: 5, borderRadius: 6, borderWidth: 1, borderColor: colors.border },\n chipOn: { backgroundColor: colors.accent, borderColor: colors.accent },\n chipText: { color: colors.foregroundMuted, fontSize: 12 },\n chipTextOn: { color: colors.accentForeground, fontSize: 12 },\n button: { paddingHorizontal: 12, paddingVertical: 7, borderRadius: 8, backgroundColor: colors.accent },\n buttonText: { color: colors.accentForeground, fontWeight: "600" },\n body: { flex: 1, flexDirection: "row" },\n pane: { flex: 1, minWidth: 0 },\n paneList: { flex: 2, borderRightWidth: 1, borderRightColor: colors.border },\n paneDetail: { flex: 3 },\n empty: { margin: 16, borderWidth: 1, borderStyle: "dashed", borderColor: colors.border, borderRadius: 10, padding: 24, alignItems: "center" },\n listContent: { paddingVertical: 6 },\n group: { marginBottom: 4 },\n groupHeader: { flexDirection: "row", alignItems: "center", gap: 6, paddingHorizontal: compact ? 10 : 14, paddingVertical: 7 },\n groupTitle: { color: colors.foregroundMuted, fontSize: 11.5, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.4 },\n groupCount: { color: colors.foregroundMuted, fontSize: 11, opacity: 0.8 },\n line: { paddingHorizontal: compact ? 10 : 14, paddingVertical: 7, gap: 3, borderLeftWidth: 2, borderLeftColor: "transparent" },\n lineOn: { backgroundColor: colors.surface2, borderLeftColor: colors.accent },\n lineHover: { backgroundColor: colors.surface1 },\n lineTop: { flexDirection: "row", alignItems: "center", gap: 7 },\n lineTitle: { flex: 1, minWidth: 0, color: colors.foreground, fontSize: 13 },\n lineMeta: { flexDirection: "row", flexWrap: "wrap", gap: 6, paddingLeft: 16 },\n id: { color: colors.foregroundMuted, fontSize: 11.5, ...mono },\n age: { color: colors.foregroundMuted, fontSize: 11, ...mono },\n assignee: { color: colors.accent, fontSize: 11.5, maxWidth: 110 },\n label: { color: colors.foregroundMuted, fontSize: 11, backgroundColor: colors.surface2, borderRadius: 4, paddingHorizontal: 5, paddingVertical: 1 },\n inlineAction: { flexDirection: "row", alignItems: "center", gap: 10, paddingLeft: compact ? 26 : 30, paddingRight: 14, paddingBottom: 8 },\n board: { padding: 12, gap: 10, alignItems: "flex-start" },\n column: { width: 248, backgroundColor: colors.surface1, borderRadius: 10, borderWidth: 1, borderColor: colors.border, maxHeight: 640 },\n columnHeader: { flexDirection: "row", alignItems: "center", gap: 7, paddingHorizontal: 12, paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: colors.border },\n columnTitle: { flex: 1, color: colors.foreground, fontSize: 12.5, fontWeight: "600" },\n columnBody: { padding: 8, gap: 8 },\n card: { backgroundColor: colors.surface0, borderRadius: 8, borderWidth: 1, borderColor: colors.border, borderLeftWidth: 3, padding: 10, gap: 5 },\n cardHover: { borderColor: colors.foregroundMuted },\n cardBlocked: { borderLeftColor: colors.statusDanger },\n cardReady: { borderLeftColor: colors.statusSuccess },\n cardLabels: { flexDirection: "row", flexWrap: "wrap", gap: 6 },\n blocked: { color: colors.statusDanger, fontSize: 11.5 },\n cardTitle: { color: colors.foreground, fontSize: 13, lineHeight: 18 },\n epic: { marginHorizontal: compact ? 10 : 14, marginVertical: 6, padding: 12, borderRadius: 10, borderWidth: 1, borderColor: colors.border, backgroundColor: colors.surface1, gap: 8 },\n progressTrack: { height: 6, borderRadius: 3, backgroundColor: colors.surface2, overflow: "hidden" },\n progressFill: { height: 6, borderRadius: 3, backgroundColor: colors.statusSuccess },\n progressText: { color: colors.foregroundMuted, fontSize: 11.5, ...mono },\n treeToggle: { flexDirection: "row", alignItems: "center", gap: 4 },\n tree: { marginLeft: 6, borderLeftWidth: 1, borderLeftColor: colors.border, backgroundColor: colors.surface0, borderRadius: 6 },\n detail: { padding: compact ? 12 : 18, gap: 14 },\n detailHeader: { flexDirection: "row", alignItems: "center", gap: 8 },\n statePill: { flexDirection: "row", alignItems: "center", gap: 6, borderWidth: 1, borderColor: colors.border, borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },\n detailTitle: { color: colors.foreground, fontSize: 17, fontWeight: "600", lineHeight: 23 },\n fields: { borderWidth: 1, borderColor: colors.border, borderRadius: 10, overflow: "hidden" },\n field: { flexDirection: "row", alignItems: "center", gap: 12, paddingHorizontal: 12, paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: colors.border },\n fieldLabel: { width: 84, color: colors.foregroundMuted, fontSize: 12 },\n fieldValue: { flex: 1, minWidth: 0 },\n inline: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },\n box: { borderRadius: 10, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, padding: 12, gap: 6 },\n boxTitle: { color: colors.foregroundMuted, fontSize: 11.5, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.4 },\n detailActions: { flexDirection: "row", gap: 8, flexWrap: "wrap" },\n smallButton: { paddingHorizontal: 10, paddingVertical: 6, borderRadius: 7, borderWidth: 1, borderColor: colors.border, backgroundColor: colors.surface1 },\n smallButtonPrimary: { backgroundColor: colors.accent, borderColor: colors.accent },\n smallButtonDanger: { borderColor: colors.statusDanger },\n smallButtonText: { color: colors.foreground, fontSize: 12.5, fontWeight: "500" },\n smallButtonTextPrimary: { color: colors.accentForeground, fontSize: 12.5, fontWeight: "600" },\n smallButtonTextDanger: { color: colors.statusDanger, fontSize: 12.5 },\n text: { color: colors.foreground, fontSize: 13, lineHeight: 19 },\n small: { color: colors.foregroundMuted, fontSize: 12 },\n muted: { color: colors.foregroundMuted, fontSize: 13 },\n danger: { color: colors.statusDanger, fontSize: 13 },\n warning: { color: colors.statusWarning, fontSize: 12 },\n link: { color: colors.accent, fontSize: 13, ...mono }\n };\n}\n\n// integrations/paseo/client/task-pills.ts\nvar TASKS_SCREEN = "alp-tasks";\nvar POLL_MS2 = 2e4;\nvar MENU_LIMIT = 8;\nvar PAGE = 200;\nfunction tasksScreen(workspaceId, directory, taskId) {\n return { screenId: TASKS_SCREEN, params: { workspaceId, directory, ...taskId ? { taskId } : {} } };\n}\nvar ORDER = ["approve", "review", "progress", "ready", "blocked"];\nvar STATES = {\n approve: { label: "Approve", icon: "Hand" },\n review: { label: "Review", icon: "Eye" },\n progress: { label: "In progress", icon: "LoaderCircle" },\n ready: { label: "Ready", icon: "CircleCheck" },\n blocked: { label: "Blocked", icon: "CircleSlash" },\n closed: { label: "Done", icon: "CheckCheck" }\n};\nfunction sessionWork(board, sessions = []) {\n const ids = sessions.map((id) => board?.sessions?.[id]).find(Boolean) ?? [];\n const index = new Map((board?.tasks ?? []).map((task) => [task.id, task]));\n return ids.flatMap((id) => index.has(id) ? [{ task: index.get(id), state: stateOf(index.get(id)) }] : []);\n}\nfunction menuTasks(tasks) {\n return tasks.filter((task) => task.status !== "closed" && task.type !== "epic").map((task) => ({ task, state: stateOf(task) })).sort((a, b) => ORDER.indexOf(a.state) - ORDER.indexOf(b.state) || a.task.priority - b.task.priority || a.task.id.localeCompare(b.task.id));\n}\nfunction taskButton(board, open, sessions = []) {\n const listed = board ? menuTasks(board.tasks) : [];\n const worked = sessionWork(board, sessions);\n const done = worked.filter((entry2) => entry2.state === "closed").length;\n const mine = new Set(worked.map((entry2) => entry2.task.id));\n const shown = [...worked, ...listed.filter((entry2) => !mine.has(entry2.task.id))];\n const entry = ({ task, state }, index) => ({\n kind: "item",\n id: `task-${index}`,\n title: `${STATES[state].label} \\xB7 ${task.title}`,\n icon: STATES[state].icon,\n behavior: { kind: "action", onPress: () => open(task.id) }\n });\n const items = shown.slice(0, MENU_LIMIT).map(entry);\n if (worked.length && items.length > worked.length) items.splice(worked.length, 0, { kind: "separator", id: "session-end" });\n if (items.length) items.push({ kind: "separator", id: "tasks-end" });\n const more = shown.length - MENU_LIMIT;\n items.push({ kind: "item", id: "all-tasks", title: more > 0 ? `All tasks (${more} more)` : "All tasks", icon: "ListTodo", behavior: { kind: "action", onPress: () => open() } });\n return {\n title: worked.length ? `ALP tasks: ${done} of ${worked.length} done in this session, ${listed.length} open` : listed.length ? `ALP tasks: ${listed.length} open` : "ALP tasks",\n icon: "ListTodo",\n label: worked.length ? `Tasks \\xB7 ${done}/${worked.length}` : listed.length ? `Tasks \\xB7 ${listed.length}` : "Tasks",\n visible: board?.projectRoot !== null,\n behavior: { kind: "menu", items }\n };\n}\nfunction signature(board, sessions) {\n return JSON.stringify(board && [board.projectRoot !== null, [...sessionWork(board, sessions), ...menuTasks(board.tasks)].map(({ task, state }) => [task.id, state, task.title])]);\n}\nfunction addTaskPills(client) {\n const agents = /* @__PURE__ */ new Map();\n const directories = /* @__PURE__ */ new Map();\n const boards = /* @__PURE__ */ new Map();\n const pills = /* @__PURE__ */ new Map();\n let subscription = null;\n let stopped = false;\n let retry;\n let polling = false;\n let again = false;\n const opener = (agent, directory) => (taskId) => client.openScreen(tasksScreen(agent.workspaceId, directory, taskId));\n const directoryOf = (agent) => {\n let found = directories.get(agent.workspaceId);\n if (!found) {\n found = client.paseo.workspaces.ref(agent.workspaceId).refresh().then((workspace) => workspace?.workspaceDirectory || workspace?.projectRootPath || agent.cwd).catch(() => {\n directories.delete(agent.workspaceId);\n return agent.cwd;\n });\n directories.set(agent.workspaceId, found);\n }\n return found;\n };\n const show = (agent) => __async(null, null, function* () {\n const directory = yield directoryOf(agent);\n if (stopped || pills.has(agent.id) || agents.get(agent.id) !== agent) return;\n const board = boards.get(directory) ?? null;\n try {\n const registration = client.addComposerPill({ id: "alp-tasks", workspaceId: agent.workspaceId, agentId: agent.id, button: taskButton(board, opener(agent, directory), agent.sessions) });\n pills.set(agent.id, { agent, directory, registration, signature: signature(board, agent.sessions) });\n } catch {\n return;\n }\n if (!board) void poll();\n });\n const hide = (id) => {\n agents.delete(id);\n pills.get(id)?.registration.remove();\n pills.delete(id);\n };\n const accept = (snapshot) => {\n const known = agents.get(snapshot.id);\n if (snapshot.provider !== "alp" || !snapshot.workspaceId || snapshot.archivedAt) {\n if (known) hide(snapshot.id);\n return;\n }\n const sessions = [snapshot.persistence?.sessionId, snapshot.id].filter((id) => Boolean(id));\n if (known?.workspaceId === snapshot.workspaceId && known.sessions.join() === sessions.join()) return;\n if (known) hide(snapshot.id);\n const agent = { id: snapshot.id, workspaceId: snapshot.workspaceId, cwd: snapshot.cwd, sessions };\n agents.set(agent.id, agent);\n void show(agent);\n };\n const load = (page) => __async(null, null, function* () {\n const seen = /* @__PURE__ */ new Set();\n for (let current = page; ; ) {\n for (const { agent } of current.entries) {\n seen.add(agent.id);\n accept(agent);\n }\n const cursor = current.pageInfo.nextCursor;\n if (!current.pageInfo.hasMore || !cursor || stopped) break;\n current = yield client.paseo.agents.list({ scope: "active", page: { limit: PAGE, cursor } });\n }\n for (const id of [...agents.keys()]) if (!seen.has(id)) hide(id);\n });\n const watch = () => __async(null, null, function* () {\n try {\n const first = yield client.paseo.agents.list({ scope: "active", page: { limit: PAGE }, subscribe: {} });\n if (stopped) {\n void first.subscription.release().catch(() => {\n });\n return;\n }\n subscription = first.subscription;\n first.subscription.subscribe({\n snapshot: (snapshot) => {\n void load(snapshot).catch(() => {\n });\n },\n update: (message2) => {\n if (message2.type !== "agent_update") return;\n if (message2.payload.kind === "remove") hide(message2.payload.agentId);\n else accept(message2.payload.agent);\n }\n });\n } catch {\n if (!stopped) retry = setTimeout(() => void watch(), POLL_MS2);\n }\n });\n const poll = () => __async(null, null, function* () {\n if (polling) {\n again = true;\n return;\n }\n polling = true;\n try {\n const shown = new Set([...pills.values()].map((pill) => pill.directory));\n for (const directory of shown) {\n if (stopped) return;\n try {\n boards.set(directory, yield client.rpc(tasksList, { directory }));\n } catch {\n continue;\n }\n for (const pill of pills.values()) if (pill.directory === directory) render(pill);\n }\n for (const directory of [...boards.keys()]) if (!shown.has(directory)) boards.delete(directory);\n } finally {\n polling = false;\n if (again && !stopped) {\n again = false;\n void poll();\n }\n }\n });\n const render = (pill) => {\n const board = boards.get(pill.directory) ?? null;\n const next = signature(board, pill.agent.sessions);\n if (next === pill.signature) return;\n pill.signature = next;\n pill.registration.update(taskButton(board, opener(pill.agent, pill.directory), pill.agent.sessions));\n };\n const timer = setInterval(() => void poll(), POLL_MS2);\n void watch();\n return () => {\n stopped = true;\n clearInterval(timer);\n if (retry !== void 0) clearTimeout(retry);\n for (const id of [...pills.keys()]) hide(id);\n void subscription?.release().catch(() => {\n });\n };\n}\n\n// integrations/paseo/client/team-model-settings.tsx\nvar import_react3 = require("react");\nvar import_react_native5 = require("react-native");\nvar import_client2 = require("@getpaseo/plugin/client");\nvar import_ui = require("@getpaseo/plugin/client/ui");\n\n// integrations/paseo/shared/library.ts\nvar import_plugin2 = require("@getpaseo/plugin");\nvar import_zod2 = require("zod");\nvar Directory2 = import_zod2.z.string().min(1).optional();\nvar KindSchema = import_zod2.z.enum(["agents", "skills", "mcp", "hooks", "teams", "providers"]);\nvar ScopeSchema = import_zod2.z.enum(["library", "project"]);\nvar Name = import_zod2.z.string().regex(/^[\\w.-]+$/).refine((name) => name !== "." && name !== "..");\nvar Source = import_zod2.z.enum(["builtin", "library", "project"]);\nvar EntryRowSchema = import_zod2.z.object({\n name: import_zod2.z.string(),\n source: Source,\n overrides: Source.optional(),\n path: import_zod2.z.string().optional(),\n description: import_zod2.z.string().optional(),\n usedBy: import_zod2.z.array(import_zod2.z.string()).optional()\n});\nvar libraryList = (0, import_plugin2.defineRpc)({\n name: "alp.library.list",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema }),\n output: import_zod2.z.object({\n projectRoot: import_zod2.z.string().nullable(),\n library: import_zod2.z.string(),\n entries: import_zod2.z.array(EntryRowSchema),\n /**\n * Set when the library can only be looked at from here (ALP remote mode): why, and where to\n * change it. `unlisted` says why there are no entries at all (no granted workspace open).\n */\n readOnly: import_zod2.z.object({ reason: import_zod2.z.string(), unlisted: import_zod2.z.string().optional() }).optional()\n })\n});\nvar libraryGet = (0, import_plugin2.defineRpc)({\n name: "alp.library.get",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, name: Name, scope: ScopeSchema.optional() }),\n output: import_zod2.z.object({\n kind: KindSchema,\n name: import_zod2.z.string(),\n source: Source,\n overrides: Source.optional(),\n content: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),\n /** Pass back with a save or delete; a different current revision refuses it. */\n revision: import_zod2.z.string().nullable(),\n usedBy: import_zod2.z.array(import_zod2.z.string()),\n /** Agents: the skills the library gives it by name (role-skills.json). */\n librarySkills: import_zod2.z.array(import_zod2.z.string()).optional()\n })\n});\nvar librarySkills = (0, import_plugin2.defineRpc)({\n name: "alp.library.skills",\n input: import_zod2.z.object({ agent: Name, skills: import_zod2.z.array(Name) }),\n output: import_zod2.z.object({ skills: import_zod2.z.array(import_zod2.z.string()) })\n});\nvar librarySave = (0, import_plugin2.defineRpc)({\n name: "alp.library.save",\n input: import_zod2.z.object({\n directory: Directory2,\n kind: KindSchema,\n name: Name,\n scope: ScopeSchema,\n content: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),\n /** null creates; a string replaces that revision; omitted overwrites. */\n revision: import_zod2.z.string().nullable().optional()\n }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable(), syncedProjects: import_zod2.z.number().int().nonnegative().optional(), syncErrors: import_zod2.z.array(import_zod2.z.string()).optional() })\n});\nvar libraryDelete = (0, import_plugin2.defineRpc)({\n name: "alp.library.delete",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, name: Name, scope: ScopeSchema, revision: import_zod2.z.string().optional() }),\n /** now: the layer that applies again after removing an override. */\n output: import_zod2.z.object({ removed: import_zod2.z.boolean(), now: Source.optional() })\n});\nvar libraryDuplicate = (0, import_plugin2.defineRpc)({\n name: "alp.library.duplicate",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, from: Name, to: Name, scope: ScopeSchema }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable() })\n});\nvar libraryRename = (0, import_plugin2.defineRpc)({\n name: "alp.library.rename",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, from: Name, to: Name, scope: ScopeSchema }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable() })\n});\nvar libraryTest = (0, import_plugin2.defineRpc)({\n name: "alp.library.test",\n input: import_zod2.z.object({ directory: Directory2, kind: import_zod2.z.enum(["mcp", "hooks", "providers"]), name: Name, scope: ScopeSchema.optional() }),\n output: import_zod2.z.object({\n ok: import_zod2.z.boolean(),\n /** MCP: the server and its tools. */\n server: import_zod2.z.object({ name: import_zod2.z.string().optional(), version: import_zod2.z.string().optional() }).optional(),\n tools: import_zod2.z.array(import_zod2.z.object({ name: import_zod2.z.string(), description: import_zod2.z.string().optional() })).optional(),\n /** Hooks: how the sample run went. */\n exitCode: import_zod2.z.number().nullable().optional(),\n signal: import_zod2.z.string().nullable().optional(),\n timedOut: import_zod2.z.boolean().optional(),\n wouldBlock: import_zod2.z.boolean().optional(),\n stdout: import_zod2.z.string().optional(),\n stderr: import_zod2.z.string().optional(),\n durationMs: import_zod2.z.number().optional(),\n /** Providers: who the ACP agent says it is, and what it supports. */\n protocolVersion: import_zod2.z.number().optional(),\n agent: import_zod2.z.object({ name: import_zod2.z.string().optional(), title: import_zod2.z.string().optional(), version: import_zod2.z.string().optional() }).optional(),\n loadSession: import_zod2.z.boolean().optional(),\n mcpHttp: import_zod2.z.boolean().optional(),\n authMethods: import_zod2.z.array(import_zod2.z.string()).optional()\n })\n});\nvar LanguageSettingSchema = import_zod2.z.object({\n language: import_zod2.z.string().nullable(),\n applies: import_zod2.z.string(),\n default: import_zod2.z.string(),\n /** Why it cannot be changed from here (ALP remote mode). */\n readOnly: import_zod2.z.string().optional()\n});\nvar languageGet = (0, import_plugin2.defineRpc)({\n name: "alp.settings.language.get",\n input: import_zod2.z.object({}),\n output: LanguageSettingSchema\n});\nvar languageSet = (0, import_plugin2.defineRpc)({\n name: "alp.settings.language.set",\n input: import_zod2.z.object({ language: import_zod2.z.string().trim().min(1).max(40).nullable() }),\n output: LanguageSettingSchema\n});\nvar libraryModels = (0, import_plugin2.defineRpc)({\n name: "alp.library.models",\n input: import_zod2.z.object({}),\n output: import_zod2.z.object({ models: import_zod2.z.array(import_zod2.z.object({ id: import_zod2.z.string(), label: import_zod2.z.string(), efforts: import_zod2.z.array(import_zod2.z.string()), effort: import_zod2.z.string().optional() })) })\n});\n\n// integrations/paseo/shared/team-models.ts\nvar MODEL_PRESETS = [\n { label: "Claude only", value: "claude" },\n { label: "Codex only", value: "codex" },\n { label: "OpenCode only", value: "opencode" },\n { label: "Antigravity only", value: "antigravity" },\n { label: "Mix \\xB7 Claude + Codex", value: "mix" }\n];\nfunction presetTeamModels(team, preset, models) {\n const next = JSON.parse(JSON.stringify(team));\n const find = (provider) => models.find((model) => provider === "opencode" ? model.id === "acp:opencode" || model.id.startsWith("acp:opencode/") : model.id.startsWith(`${provider}:`));\n const primary = find(preset === "mix" ? "claude" : preset);\n const secondary = preset === "mix" ? find("codex") : primary;\n if (!primary || !secondary) throw new Error("No models available for this preset. Configure the provider in Settings first.");\n const assign = (target, model) => {\n target.model = model.id;\n if (model.effort) target.thinking = model.effort;\n else delete target.thinking;\n };\n for (const [name, member] of Object.entries(next.members ?? {})) {\n if (name !== "oracle") assign(member, name === next.main ? primary : secondary);\n }\n if (next.supervisor) assign(next.supervisor, secondary);\n if (next.members?.oracle) {\n next.oracleModels = [.../* @__PURE__ */ new Set([primary.id, secondary.id])];\n next.oracleThinking = Object.fromEntries([primary, secondary].filter((model) => model.effort).map((model) => [model.id, model.effort]));\n }\n next.modelSetup = { mode: "default", preset };\n return next;\n}\nfunction modelSetupFor(team, models) {\n if (team.modelSetup) return team.modelSetup;\n for (const { value } of MODEL_PRESETS) {\n let expected;\n try {\n expected = presetTeamModels(team, value, models);\n } catch {\n continue;\n }\n const same = (a, b) => a.model === b.model && a.thinking === b.thinking;\n if (!Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").every(([name, member]) => same(member, expected.members[name]))) continue;\n if (team.supervisor && !same(team.supervisor, expected.supervisor)) continue;\n if (team.members?.oracle && (JSON.stringify(team.oracleModels) !== JSON.stringify(expected.oracleModels) || expected.oracleModels.some((id) => (team.oracleThinking?.[id] ?? team.oracleThinking?.[id.split(":")[0]]) !== expected.oracleThinking?.[id]))) continue;\n return { mode: "default", preset: value };\n }\n return { mode: "custom" };\n}\n\n// integrations/paseo/client/side-nav.tsx\nvar import_react_native3 = require("@getpaseo/plugin/client/react-native");\nvar import_react2 = require("react");\nvar import_react_native4 = require("react-native");\nvar import_jsx_runtime2 = require("react/jsx-runtime");\nvar hovered2 = (state) => !!state.hovered;\nvar COLLAPSE_BELOW = 640;\nvar EXPANDED = 216;\nvar COLLAPSED = 52;\nfunction SideNavLayout(props) {\n const { theme, compact, groups, active, onSelect } = props;\n const styles = (0, import_react2.useMemo)(() => layoutStyles(theme), [theme]);\n const [width, setWidth] = (0, import_react2.useState)(0);\n const [choice, setChoice] = (0, import_react2.useState)(props.initialCollapsed);\n const [open, setOpen] = (0, import_react2.useState)(false);\n const collapsed = choice ?? (width > 0 && width < COLLAPSE_BELOW);\n const select = (item, child) => {\n onSelect(item, child);\n setOpen(false);\n };\n const aside = (mode) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(\n Aside,\n {\n styles,\n theme,\n title: props.title,\n subtitle: props.subtitle,\n groups,\n active,\n onSelect: select,\n collapsed: mode === "fixed" && collapsed,\n onToggle: mode === "fixed" ? () => setChoice(!collapsed) : () => setOpen(false),\n overlay: mode === "overlay"\n }\n );\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: props.embedded ? { width: "100%" } : styles.root, onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [\n !props.embedded && !compact ? aside("fixed") : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: props.embedded ? { minWidth: 0 } : styles.main, children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.header, props.embedded ? { paddingHorizontal: 0, paddingTop: 0 } : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.headerRow, children: [\n compact && !props.embedded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: "Open navigation", onPress: () => setOpen(true), style: styles.iconButton, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: "Menu", size: 18, color: theme.colors.foreground }) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.crumbs, children: [\n props.breadcrumb.map((part, index) => [\n index ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.crumbSeparator, children: "/" }, `separator-${index}`) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: index === props.breadcrumb.length - 1 ? styles.crumbCurrent : styles.crumb, numberOfLines: 1, children: part }, `${index}-${part}`)\n ]),\n props.badges\n ] }),\n props.actions ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.actions, children: props.actions }) : null\n ] }),\n props.tabs?.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.tabs, children: props.tabs.map((tab) => {\n const on = tab.key === props.tab;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "tab", accessibilityLabel: tab.label, accessibilityState: { selected: on }, onPress: () => props.onTab?.(tab.key), style: [styles.tab, on ? styles.tabOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.Text, { style: on ? styles.tabTextOn : styles.tabText, children: [\n tab.label,\n tab.count !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.tabCount, children: ` ${tab.count}` }) : null\n ] }) }, tab.key);\n }) }) : null\n ] }),\n props.embedded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.bodyContent, { paddingHorizontal: 0 }], children: props.children }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { style: styles.body, contentContainerStyle: styles.bodyContent, children: props.children }),\n props.footer ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.footer, props.embedded ? { paddingHorizontal: 0 } : null], children: props.footer }) : null\n ] }),\n !props.embedded && compact && open ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.overlay, children: [\n aside("overlay"),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: "Close navigation", onPress: () => setOpen(false), style: styles.scrim })\n ] }) : null\n ] });\n}\nfunction Aside({ styles, theme, title, subtitle, groups, active, onSelect, collapsed, onToggle, overlay }) {\n const { colors } = theme;\n const [opened, setOpened] = (0, import_react2.useState)({});\n const tone = (value) => value === "accent" ? colors.accent : value === "warning" ? colors.statusWarning : colors.border;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.aside, { width: collapsed ? COLLAPSED : EXPANDED }, overlay ? styles.asideOverlay : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.asideHeader, collapsed ? styles.asideHeaderCollapsed : null], children: [\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.asideTitleBox, children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.asideTitle, numberOfLines: 1, children: title }),\n subtitle ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.asideSubtitle, numberOfLines: 1, children: subtitle }) : null\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: overlay ? "Close navigation" : collapsed ? "Expand navigation" : "Collapse navigation", onPress: onToggle, style: styles.iconButton, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: overlay ? "X" : collapsed ? "PanelLeftOpen" : "PanelLeftClose", size: 16, color: colors.foregroundMuted }) })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { contentContainerStyle: styles.asideList, children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.group, children: [\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.groupLabel, children: group.label }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.groupRule }),\n group.items.map((item) => {\n const selected = active.item === item.key;\n const expanded = !collapsed && (opened[item.key] ?? selected) && !!item.children?.length;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: item.label,\n accessibilityState: { selected: selected && !active.child },\n onPress: () => {\n onSelect(item.key);\n setOpened((current) => ({ ...current, [item.key]: true }));\n },\n style: (state) => [styles.item, collapsed ? styles.itemCollapsed : null, selected ? styles.itemOn : hovered2(state) ? styles.itemHover : null],\n children: [\n selected ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.itemBar }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: item.icon, size: 16, color: selected ? colors.accent : colors.foregroundMuted }),\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles.itemLabel, selected ? styles.itemLabelOn : null], numberOfLines: 1, children: item.label }) : null,\n !collapsed && item.count !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.count, children: item.count }) : null,\n !collapsed && item.children?.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: `${expanded ? "Hide" : "Show"} ${item.label}`, hitSlop: 8, onPress: () => setOpened((current) => ({ ...current, [item.key]: !expanded })), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: expanded ? "ChevronDown" : "ChevronRight", size: 14, color: colors.foregroundMuted }) }) : null\n ]\n }\n ),\n expanded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.children, children: item.children.map((child) => {\n const on = selected && active.child === child.key;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: `${item.label} ${child.label}`,\n accessibilityState: { selected: on },\n onPress: () => onSelect(item.key, child.key),\n style: (state) => [styles.child, on ? styles.childOn : hovered2(state) ? styles.itemHover : null],\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.dot, { backgroundColor: tone(child.tone) }] }),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles.childLabel, on ? styles.itemLabelOn : null], numberOfLines: 1, children: child.label }),\n child.hint ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.childHint, numberOfLines: 1, children: child.hint }) : null\n ]\n },\n child.key\n );\n }) }) : null\n ] }, item.key);\n })\n ] }, group.key)) })\n ] });\n}\nfunction Pill({ theme, label, tone = "muted" }) {\n const { colors } = theme;\n const color = tone === "accent" ? colors.accent : tone === "success" ? colors.statusSuccess : tone === "warning" ? colors.statusWarning : tone === "danger" ? colors.statusDanger : colors.foregroundMuted;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: { borderRadius: 999, borderWidth: 1, borderColor: tone === "muted" ? colors.border : color, paddingHorizontal: 7, paddingVertical: 1, alignSelf: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: { color, fontSize: 11, fontWeight: "500" }, children: label }) });\n}\nfunction Button({ theme, label, onPress, kind = "plain", icon, disabled, accessibilityLabel }) {\n const { colors } = theme;\n const color = kind === "primary" ? colors.accentForeground : kind === "danger" ? colors.statusDanger : colors.foreground;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: accessibilityLabel ?? label,\n disabled,\n onPress,\n style: (state) => ({\n flexDirection: "row",\n alignItems: "center",\n gap: 6,\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 7,\n opacity: disabled ? 0.5 : 1,\n backgroundColor: kind === "primary" ? colors.accent : hovered2(state) ? colors.surface2 : colors.surface1,\n borderWidth: kind === "primary" ? 0 : 1,\n borderColor: kind === "danger" ? colors.statusDanger : colors.border\n }),\n children: [\n icon ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: icon, size: 14, color }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: { color, fontSize: 13, fontWeight: kind === "primary" ? "600" : "500" }, children: label })\n ]\n }\n );\n}\nfunction layoutStyles(theme) {\n const { colors } = theme;\n return {\n root: { flex: 1, flexDirection: "row", backgroundColor: colors.surface0, minHeight: 560, borderWidth: 1, borderColor: colors.border, borderRadius: 12, overflow: "hidden" },\n aside: { backgroundColor: colors.surface1, borderRightWidth: 1, borderRightColor: colors.border },\n asideOverlay: { height: "100%", shadowColor: "#000", shadowOpacity: 0.2, shadowRadius: 16 },\n asideHeader: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 12, paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: colors.border, gap: 8 },\n asideHeaderCollapsed: { justifyContent: "center", paddingHorizontal: 0 },\n asideTitleBox: { flex: 1, minWidth: 0 },\n asideTitle: { color: colors.foreground, fontSize: 14, fontWeight: "600" },\n asideSubtitle: { color: colors.foregroundMuted, fontSize: 11, marginTop: 1 },\n asideList: { paddingVertical: 8, gap: 10 },\n group: { gap: 1 },\n groupLabel: { color: colors.foregroundMuted, fontSize: 11, fontWeight: "600", letterSpacing: 0.4, textTransform: "uppercase", paddingHorizontal: 14, paddingBottom: 4 },\n groupRule: { height: 1, backgroundColor: colors.border, marginHorizontal: 12, marginBottom: 4 },\n item: { flexDirection: "row", alignItems: "center", gap: 10, marginHorizontal: 6, paddingHorizontal: 8, paddingVertical: 7, borderRadius: 7 },\n itemCollapsed: { justifyContent: "center", paddingHorizontal: 0 },\n itemOn: { backgroundColor: colors.surface2 },\n itemHover: { backgroundColor: colors.surface2 },\n itemBar: { position: "absolute", left: -6, top: 6, bottom: 6, width: 3, borderRadius: 2, backgroundColor: colors.accent },\n itemLabel: { flex: 1, color: colors.foreground, fontSize: 13 },\n itemLabelOn: { color: colors.foreground, fontWeight: "600" },\n count: { color: colors.foregroundMuted, fontSize: 11, fontVariant: ["tabular-nums"] },\n children: { marginLeft: 22, borderLeftWidth: 1, borderLeftColor: colors.border, marginVertical: 2, paddingLeft: 4 },\n child: { flexDirection: "row", alignItems: "center", gap: 8, marginRight: 6, paddingHorizontal: 8, paddingVertical: 5, borderRadius: 6 },\n childOn: { backgroundColor: colors.surface2 },\n childLabel: { flex: 1, color: colors.foreground, fontSize: 12.5 },\n childHint: { color: colors.foregroundMuted, fontSize: 11 },\n dot: { width: 6, height: 6, borderRadius: 3 },\n main: { flex: 1, minWidth: 0 },\n header: { borderBottomWidth: 1, borderBottomColor: colors.border, paddingHorizontal: 20, paddingTop: 14, gap: 10 },\n headerRow: { flexDirection: "row", alignItems: "center", gap: 10, minHeight: 32 },\n crumbs: { flex: 1, minWidth: 0, flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" },\n crumb: { color: colors.foregroundMuted, fontSize: 13 },\n crumbSeparator: { color: colors.foregroundMuted, fontSize: 13, opacity: 0.6 },\n crumbCurrent: { color: colors.foreground, fontSize: 16, fontWeight: "600" },\n actions: { flexDirection: "row", gap: 8, alignItems: "center" },\n tabs: { flexDirection: "row", gap: 4 },\n tab: { paddingHorizontal: 10, paddingVertical: 8, borderBottomWidth: 2, borderBottomColor: "transparent" },\n tabOn: { borderBottomColor: colors.accent },\n tabText: { color: colors.foregroundMuted, fontSize: 13 },\n tabTextOn: { color: colors.foreground, fontSize: 13, fontWeight: "600" },\n tabCount: { color: colors.foregroundMuted, fontSize: 11 },\n body: { flex: 1 },\n bodyContent: { padding: 20, gap: 16 },\n footer: { flexDirection: "row", alignItems: "center", gap: 10, paddingHorizontal: 20, paddingVertical: 12, borderTopWidth: 1, borderTopColor: colors.border, backgroundColor: colors.surface1 },\n iconButton: { padding: 6, borderRadius: 6 },\n overlay: { position: "absolute", left: 0, top: 0, right: 0, bottom: 0, flexDirection: "row" },\n scrim: { flex: 1, backgroundColor: "rgba(0,0,0,0.25)" }\n };\n}\n\n// integrations/paseo/client/team-model-settings.tsx\nvar import_jsx_runtime3 = require("react/jsx-runtime");\nvar clone = (team) => JSON.parse(JSON.stringify(team));\nfunction TeamModelSettings({ team, theme, onChange }) {\n const readModels = (0, import_client2.useRpc)(libraryModels);\n const [models, setModels] = (0, import_react3.useState)([]);\n const [error, setError] = (0, import_react3.useState)("");\n const [customFields, setCustomFields] = (0, import_react3.useState)({});\n const setup = modelSetupFor(team, models);\n const mode = setup.mode;\n const preset = setup.preset ?? "mix";\n (0, import_react3.useEffect)(() => {\n let live = true;\n readModels({}).then((result) => {\n if (live) {\n setModels(result.models);\n setError("");\n }\n }).catch((cause) => {\n if (live) setError(String(cause.message ?? cause));\n });\n return () => {\n live = false;\n };\n }, [readModels]);\n const edit = (work) => {\n const next = clone(team);\n next.modelSetup = { mode: "custom" };\n work(next);\n onChange(next);\n setError("");\n };\n const selectPreset = (value) => {\n try {\n onChange(presetTeamModels(team, value, models));\n setCustomFields({});\n setError("");\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n };\n const chooseModel = (label, value, set) => {\n const known = models.find((model) => model.id === value);\n const options = [...label.startsWith("oracle-") ? [] : [{ label: "Inherit", value: "" }], ...models.map((model) => ({ value: model.id, label: model.label }))];\n if (value && !known) options.push({ label: value, value });\n options.push({ label: "Custom model ID", value: "__custom" });\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Model", value: customFields[label] ? "__custom" : value, options, onValueChange: (id) => {\n setCustomFields((previous) => ({ ...previous, [label]: id === "__custom" }));\n if (id !== "__custom") edit((next) => set(next, id, models.find((model) => model.id === id)?.effort));\n } }),\n customFields[label] || value && !known ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsInput, { label: "Custom model ID", hint: "claude:model, codex:model, antigravity:model or acp:provider/model", initialValue: value, onChangeText: (id) => edit((next) => set(next, id.trim())) }, `${label}-custom`) : null\n ] });\n };\n const effort = (model, value, set) => {\n const known = models.find((choice) => choice.id === model);\n const values = known ? known.efforts : ["none", "off", "low", "medium", "high", "xhigh", "max", "ultra", "ultracode"];\n const options = [{ label: "Inherit", value: "" }, ...[.../* @__PURE__ */ new Set([...values, ...value ? [value] : []])].map((value2) => ({ label: value2, value: value2 }))];\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Effort", value, options, onValueChange: (value2) => edit((next) => set(next, value2)) });\n };\n const assign = (target, id, thinking) => {\n if (id) target.model = id;\n else delete target.model;\n if (thinking) target.thinking = thinking;\n else delete target.thinking;\n };\n const setEffort = (target, value) => {\n if (value) target.thinking = value;\n else delete target.thinking;\n };\n const lenses = team.oracleModels ?? ["claude:claude-fable-5-1", "codex:gpt-6-astra"];\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Model setup", children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Mode", value: mode, options: [{ label: "Default presets", value: "default" }, { label: "Custom", value: "custom" }], onValueChange: (value) => value === "default" ? selectPreset(preset) : edit(() => {\n }) }),\n mode === "default" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Preset", value: preset, options: MODEL_PRESETS, onValueChange: selectPreset }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Save with template", hint: "Save writes these model choices into settings.json for this team immediately. Project template overrides still apply to Host templates." }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { accessibilityRole: "alert", style: { color: theme?.colors.statusDanger }, children: error }) : null\n ] }),\n mode === "default" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Preset models", children: [\n Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").map(([name, member]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: name, hint: member.model }, name)),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Supervisor", hint: team.supervisor.model }) : null,\n team.members?.oracle ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Oracle", hint: lenses.join(", ") }) : null\n ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react3.Fragment, { children: [\n Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").map(([name, member]) => {\n const config = member;\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: name === team.main ? `${name} \\xB7 main` : name, children: [\n chooseModel(name, config.model ?? "", (next, id, effort2) => assign(next.members[name], id, effort2)),\n effort(config.model ?? team.members[team.main]?.model ?? "", config.thinking ?? "", (next, value) => setEffort(next.members[name], value))\n ] }, name);\n }),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Supervisor", children: [\n chooseModel("supervisor", team.supervisor.model ?? "", (next, id, effort2) => assign(next.supervisor, id, effort2)),\n effort(team.supervisor.model ?? "", team.supervisor.thinking ?? "", (next, value) => setEffort(next.supervisor, value))\n ] }) : null,\n team.members?.oracle ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n lenses.map((id, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: `Oracle ${index + 1}`, children: [\n chooseModel(`oracle-${index}`, id, (next, value, effort2) => {\n next.oracleModels = [...lenses];\n next.oracleModels[index] = value;\n next.oracleThinking ?? (next.oracleThinking = {});\n delete next.oracleThinking[id];\n if (effort2) next.oracleThinking[value] = effort2;\n }),\n effort(id, team.oracleThinking?.[id] ?? team.oracleThinking?.[id.split(":")[0]] ?? "", (next, value) => {\n next.oracleThinking ?? (next.oracleThinking = {});\n delete next.oracleThinking[id.split(":")[0]];\n if (value) next.oracleThinking[id] = value;\n else delete next.oracleThinking[id];\n }),\n theme && lenses.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { theme, label: "Remove model", onPress: () => edit((next) => {\n next.oracleModels = lenses.filter((_, i) => i !== index);\n }) }) : null\n ] }, index)),\n theme ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { theme, label: "Add oracle model", onPress: () => edit((next) => {\n next.oracleModels = [...lenses, ""];\n setCustomFields((previous) => ({ ...previous, [`oracle-${lenses.length}`]: true }));\n }) }) : null\n ] }) : null\n ] }, "custom-models"),\n JSON.stringify(team).includes("antigravity:") ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSection, { title: "Antigravity", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Advisory roles", hint: \'Reviewer, Oracle and Supervisor require readOnlyMode: "instructions" in the Antigravity provider. Review copies and custom permission rules are unsupported.\' }) }) : null\n ] });\n}\n\n// integrations/paseo/client/library.tsx\nvar import_client3 = require("@getpaseo/plugin/client");\nvar import_react_native6 = require("@getpaseo/plugin/client/react-native");\nvar import_ui2 = require("@getpaseo/plugin/client/ui");\nvar import_react4 = require("react");\nvar import_react_native7 = require("react-native");\nvar import_jsx_runtime4 = require("react/jsx-runtime");\nvar KINDS = [\n { kind: "teams", title: "Teams", one: "team", icon: "Users", group: "Organisation" },\n { kind: "agents", title: "Agents", one: "agent", icon: "Bot", group: "Organisation" },\n { kind: "skills", title: "Skills", one: "skill", icon: "BookOpen", group: "Capabilities" },\n { kind: "mcp", title: "MCP servers", one: "MCP server", icon: "Plug", group: "Capabilities" },\n { kind: "hooks", title: "Hooks", one: "hook", icon: "Webhook", group: "Capabilities" },\n // ACP agents (ALPD \xA746): in the library only, so the project panel leaves them out.\n { kind: "providers", title: "Providers", one: "provider", icon: "Cpu", group: "Runtimes" }\n];\nvar shownIn = (scope) => KINDS.filter((item) => scope === "library" || item.kind !== "providers");\nvar kindOf = (kind) => KINDS.find((item) => item.kind === kind);\nvar HOOK_EVENTS = ["session.start", "turn.end", "assignment.start", "assignment.end", "handoff", "task.close", "merge"];\nvar BLOCKING_EVENTS = ["handoff", "task.close", "merge"];\nvar ROLES = ["lead", "peer", "advisor", "reviewer"];\nvar MODES = ["", "read-only", "workspace-write", "full-access"];\nvar NAME = /^[\\w.-]+$/;\nvar clone2 = (value) => JSON.parse(JSON.stringify(value));\nvar message = (cause) => cause instanceof Error ? cause.message : String(cause);\nvar sourceLabel = (source) => source === "builtin" ? "built-in" : source;\nvar sourceTone = (source) => source === "project" ? "warning" : source === "library" ? "accent" : "muted";\nvar LANGUAGES = [\n { label: "Ti\\u1EBFng Vi\\u1EC7t", value: "Vietnamese" },\n { label: "English", value: "English" },\n { label: "\\u65E5\\u672C\\u8A9E", value: "Japanese" },\n { label: "\\uD55C\\uAD6D\\uC5B4", value: "Korean" },\n { label: "\\u4E2D\\u6587", value: "Chinese" },\n { label: "Fran\\xE7ais", value: "French" },\n { label: "Deutsch", value: "German" },\n { label: "Espa\\xF1ol", value: "Spanish" }\n];\nfunction LibrarySettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library" });\n}\nfunction TeamsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "teams", embedded: true });\n}\nfunction AgentsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "agents", embedded: true });\n}\nfunction SkillsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "skills", embedded: true });\n}\nfunction HooksSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "hooks", embedded: true });\n}\nfunction McpSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "mcp", embedded: true });\n}\nfunction ProjectLibraryPanel({ theme, layout, workspaceId }) {\n const directory = (0, import_client3.useWorkspace)(workspaceId, (workspace) => workspace.directory || workspace.projectRootPath);\n if (!directory) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: { padding: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: { color: theme.colors.foregroundMuted }, children: "This panel needs a workspace." }) });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "project", directory });\n}\nfunction LibraryManager({ theme, compact, scope, directory, embedded = false, initialKind = "teams" }) {\n const list = (0, import_client3.useRpc)(libraryList);\n const get = (0, import_client3.useRpc)(libraryGet);\n const save = (0, import_client3.useRpc)(librarySave);\n const remove = (0, import_client3.useRpc)(libraryDelete);\n const duplicate = (0, import_client3.useRpc)(libraryDuplicate);\n const probe = (0, import_client3.useRpc)(libraryTest);\n const give = (0, import_client3.useRpc)(librarySkills);\n const readLanguage = (0, import_client3.useRpc)(languageGet);\n const writeLanguage = (0, import_client3.useRpc)(languageSet);\n const toast = (0, import_react_native6.useToast)();\n const [language, setLanguageState] = (0, import_react4.useState)(null);\n const [lists, setLists] = (0, import_react4.useState)({});\n const [where, setWhere] = (0, import_react4.useState)(null);\n const [error, setError] = (0, import_react4.useState)(null);\n const [selection, setSelection] = (0, import_react4.useState)({ kind: initialKind });\n const [entry, setEntry] = (0, import_react4.useState)(null);\n const [tick, setTick] = (0, import_react4.useState)(0);\n const refresh = (0, import_react4.useCallback)(() => setTick((value) => value + 1), []);\n const base = directory ? { directory } : {};\n (0, import_react4.useEffect)(() => {\n let live = true;\n Promise.all(KINDS.map(({ kind }) => list({ ...base, kind }).then((result) => [kind, result]))).then((results) => {\n if (!live) return;\n setLists(Object.fromEntries(results.map(([kind, result]) => [kind, result.entries])));\n setWhere({ projectRoot: results[0][1].projectRoot, library: results[0][1].library, ...results[0][1].readOnly ? { readOnly: results[0][1].readOnly } : {} });\n setError(null);\n }).catch((cause) => {\n if (live) setError(message(cause));\n });\n return () => {\n live = false;\n };\n }, [list, directory, tick]);\n (0, import_react4.useEffect)(() => {\n if (scope !== "library") return;\n let live = true;\n readLanguage({}).then((result) => {\n if (live) setLanguageState(result);\n }).catch((cause) => {\n if (live) setError(message(cause));\n });\n return () => {\n live = false;\n };\n }, [readLanguage, scope, tick]);\n (0, import_react4.useEffect)(() => {\n if (!selection.name || selection.creating) {\n setEntry(null);\n return;\n }\n let live = true;\n get({ ...base, kind: selection.kind, name: selection.name }).then((result) => {\n if (live) setEntry(result);\n }).catch((cause) => {\n if (live) {\n toast.error(message(cause));\n setSelection({ kind: selection.kind });\n }\n });\n return () => {\n live = false;\n };\n }, [selection, get, directory, tick]);\n const run = (0, import_react4.useCallback)((work, done) => __async(null, null, function* () {\n try {\n yield work();\n toast.show(done, { variant: "success" });\n refresh();\n return true;\n } catch (cause) {\n toast.error(message(cause));\n return false;\n }\n }), [toast, refresh]);\n const actions = {\n select: (next) => setSelection(next),\n duplicate: (kind, from, to) => run(() => duplicate({ ...base, kind, from, to, scope }), `Copied ${from} to ${to}`),\n // In the project panel: copy what applies into .alp/, or drop the project\'s copy.\n override: (kind, name) => run(() => duplicate({ ...base, kind, from: name, to: name, scope: "project" }), `${name} is now overridden in this project`),\n useLibrary: (kind, name) => run(() => remove({ ...base, kind, name, scope: "project" }), `${name} follows the library again`),\n save: (kind, name, content, revision, creating) => __async(null, null, function* () {\n try {\n const result = yield save({ ...base, kind, name, scope, content, revision });\n const synced = result.syncedProjects ?? 0;\n toast.show(`Saved ${name}${synced ? ` \\xB7 Updated settings in ${synced} project${synced === 1 ? "" : "s"}` : ""}`, { variant: "success" });\n if (result.syncErrors?.length) toast.error(`Template saved, but some project settings could not be updated: ${result.syncErrors.join("; ")}`);\n refresh();\n if (creating) setSelection({ kind, name });\n return true;\n } catch (cause) {\n toast.error(message(cause));\n return false;\n }\n }),\n giveSkills: (agent, skills) => run(() => give({ agent, skills }), `Saved the skills of ${agent}`),\n setLanguage: (next) => run(() => writeLanguage({ language: next }), next ? `Agents now write to you in ${next}` : "Agents write to you in the default language again"),\n remove: (kind, name, revision) => __async(null, null, function* () {\n const removed = yield run(() => remove({ ...base, kind, name, scope, ...revision ? { revision } : {} }), `Removed ${name}`);\n if (removed) setSelection({ kind });\n return removed;\n }),\n test: (kind, name) => __async(null, null, function* () {\n try {\n return yield probe({ ...base, kind, name });\n } catch (cause) {\n toast.error(message(cause));\n return null;\n }\n })\n };\n const shown = selection.name && !selection.creating && entry?.name !== selection.name ? { kind: selection.kind } : selection;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryWorkspace, { theme, compact, scope, where, lists, error, selection: shown, entry: shown.name ? entry : null, actions, language, embedded });\n}\nfunction navGroups(scope, lists, readOnly = false) {\n const groups = scope === "library" ? [{ key: "General", label: "General", items: [{ key: "language", label: "Language", icon: "Languages" }] }] : [];\n for (const item of shownIn(scope)) {\n let group = groups.find((candidate) => candidate.label === item.group);\n if (!group) groups.push(group = { key: item.group, label: item.group, items: [] });\n const rows = lists[item.kind];\n group.items.push({\n key: item.kind,\n label: item.title,\n icon: item.icon,\n ...rows ? { count: rows.length } : {},\n // A read-only library\'s entries cannot be opened, so the aside lists kinds only.\n children: readOnly ? [] : (rows ?? []).map((row) => ({ key: row.name, label: row.name, tone: sourceTone(row.source) }))\n });\n }\n return groups;\n}\nfunction LibraryWorkspace({ theme, compact, scope, where, lists, error, selection, entry, actions, initialCollapsed, language, embedded }) {\n const styles = (0, import_react4.useMemo)(() => makeStyles2(theme, compact), [theme, compact]);\n const title = scope === "library" ? "ALP library" : "ALP project";\n const subtitle = scope === "library" ? where?.library : where?.projectRoot ?? void 0;\n const groups = navGroups(scope, lists, !!where?.readOnly);\n const onSelect = (kind2, name) => actions.select(kind2 === "language" ? { kind: kind2 } : { kind: kind2, ...name ? { name } : {} });\n if (scope === "project" && where?.readOnly?.unlisted) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: where.readOnly.unlisted }) });\n }\n if (scope === "project" && where && !where.projectRoot) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "This workspace is not an ALP project. Run alp init to start one." }) });\n }\n if (selection.kind === "language") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LanguageSettings, { theme, compact, language: language ?? null, error, actions, layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }, styles });\n }\n const kind = kindOf(selection.kind);\n if (selection.name || selection.creating) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n EntryEditor,\n {\n theme,\n compact,\n scope,\n kind: selection.kind,\n entry: selection.creating ? null : entry,\n lists,\n actions,\n layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }\n },\n `${selection.kind}/${selection.name ?? "new"}/${entry?.revision ?? "new"}/${(entry?.librarySkills ?? []).join(",")}`\n );\n }\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(KindOverview, { theme, compact, scope, kind: kind.kind, rows: lists[kind.kind], error, where, actions, layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }, styles });\n}\nvar OTHER = "other";\nfunction LanguageSettings({ theme, compact, language, error, actions, layout, styles }) {\n const named = language && LANGUAGES.some((option) => option.value === language.applies);\n const [choice, setChoice] = (0, import_react4.useState)(null);\n const [typed, setTyped] = (0, import_react4.useState)("");\n const shown = choice ?? (language ? named ? language.applies : OTHER : "");\n const typedValid = typed.trim().length > 0 && typed.trim().length <= 40;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: "language" },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: ["Library", "Language"],\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "The language you read. Main writes its replies, questions, approval requests and task titles in it, other agents put their questions to you in it, and ALP asks for approvals and writes its notices in it. Agents may talk among themselves in any language." }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.danger, children: error }) : null,\n !language && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Loading\\u2026" }) : null,\n language?.readOnly ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Language", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.name, children: [\n language.applies,\n language.language ? "" : " (default)"\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: language.readOnly })\n ] }) : !language ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Language", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSelect,\n {\n label: "Language",\n hint: language.language ? `Set in your settings.json` : `Not set: ${language.default} applies`,\n value: shown,\n options: [...LANGUAGES, { label: named || !language.language ? "Other\\u2026" : `${language.applies} (other)`, value: OTHER }],\n onValueChange: (value) => __async(null, null, function* () {\n setChoice(value);\n if (value !== OTHER && (yield actions.setLanguage(value))) setChoice(null);\n })\n }\n ),\n shown === OTHER ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Other language", hint: "Its name in English, such as Thai or Indonesian", initialValue: named ? "" : language.language ?? "", placeholder: "Thai", onChangeText: setTyped }) : null,\n shown === OTHER ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: "Use this language", actionLabel: "Save", disabled: !typedValid, onPress: () => __async(null, null, function* () {\n if (typedValid && (yield actions.setLanguage(typed.trim()))) setChoice(null);\n }) }) : null,\n language.language ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: `Use the default (${language.default})`, hint: "Removes the setting", actionLabel: "Reset", onPress: () => __async(null, null, function* () {\n if (yield actions.setLanguage(null)) setChoice(null);\n }) }) : null\n ] })\n ]\n }\n );\n}\nvar SOURCES = [{ key: "all", label: "All" }, { key: "builtin", label: "Built-in" }, { key: "library", label: "Library" }, { key: "project", label: "Project" }];\nfunction KindOverview({ theme, compact, scope, kind, rows, error, where, actions, layout, styles }) {\n const { title, one } = kindOf(kind);\n const [filter, setFilter] = (0, import_react4.useState)("all");\n const [copying, setCopying] = (0, import_react4.useState)(null);\n const [copyName, setCopyName] = (0, import_react4.useState)("");\n const tabs = SOURCES.map((source) => ({ ...source, count: (rows ?? []).filter((row) => source.key === "all" || row.source === source.key).length })).filter((tab) => tab.key === "all" || tab.count);\n const shown = (rows ?? []).filter((row) => filter === "all" || row.source === filter);\n const readOnly = where?.readOnly;\n const intro = readOnly ? `The ${title.toLowerCase()} ${scope === "project" ? "this project uses on the ALP host" : "of the ALP host"}, by name.` : kind === "providers" ? "Agents that speak the Agent Client Protocol. They live in your library only." : scope === "library" ? "Every project uses your library. Built-ins follow ALP updates; saving one makes your own copy of that name." : "What this project overrides. Override an entry to change it here only; Use library drops the project\'s copy.";\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: kind },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: layout.embedded ? [] : [scope === "library" ? "Library" : "Project", title],\n tabs,\n tab: filter,\n onTab: setFilter,\n actions: readOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", icon: "Plus", label: `New ${one}`, onPress: () => actions.select({ kind, creating: true }) }),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: intro }),\n readOnly ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: readOnly.reason }) : null,\n error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.danger, children: error }) : null,\n !rows && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Loading\\u2026" }) : null,\n readOnly?.unlisted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: readOnly.unlisted }) }) : rows && !shown.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n "No ",\n title.toLowerCase(),\n " ",\n filter === "all" ? "yet" : `from the ${sourceLabel(filter)}`,\n "."\n ] }) }) : null,\n shown.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.table, children: shown.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: [styles.tableRow, index ? styles.tableRowRule : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Pressable, { accessibilityRole: readOnly ? void 0 : "button", accessibilityLabel: `${readOnly ? "" : "Open "}${one} ${row.name}`, disabled: !!readOnly, onPress: () => actions.select({ kind, name: row.name }), style: styles.rowMain, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.rowTitle, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.name, children: row.name }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: sourceLabel(row.source), tone: sourceTone(row.source) }),\n row.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: `overrides ${sourceLabel(row.overrides)}` }) : null\n ] }),\n row.description ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, numberOfLines: 2, children: row.description }) : null,\n row.usedBy?.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, numberOfLines: 1, children: [\n "Used by ",\n row.usedBy.join(", ")\n ] }) : null\n ] }),\n readOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: [styles.rowActions, compact ? styles.rowActionsCompact : null], children: [\n scope === "project" && row.source === "project" && row.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Use library", onPress: () => actions.useLibrary(kind, row.name) }) : null,\n scope === "project" && row.source !== "project" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Override in this project", onPress: () => actions.override(kind, row.name) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, icon: "Copy", label: "Duplicate", accessibilityLabel: `Duplicate ${one} ${row.name}`, onPress: () => {\n setCopying(row.name);\n setCopyName(`${row.name}-copy`);\n } })\n ] }),\n copying === row.name ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.copyRow, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.TextInput, { style: styles.input, value: copyName, onChangeText: setCopyName, accessibilityLabel: "Name of the copy", placeholder: "Name of the copy", placeholderTextColor: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", label: "Copy", onPress: () => __async(null, null, function* () {\n if (NAME.test(copyName) && (yield actions.duplicate(kind, row.name, copyName))) setCopying(null);\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Cancel", onPress: () => setCopying(null) })\n ] }) : null\n ] }, row.name)) }) : null\n ]\n }\n );\n}\nfunction blank(kind, name = "new") {\n if (kind === "agents") return { instructions: `# ${name}\n\nDescribe what this agent does, and how.\n`, config: {} };\n if (kind === "skills") return { body: `---\nname: ${name}\ndescription: When to use this skill.\n---\n\n# ${name}\n\nSteps and checks.\n` };\n if (kind === "mcp") return { server: { command: "" } };\n if (kind === "hooks") return { hook: { event: "handoff", command: "", blocking: false } };\n if (kind === "providers") return { provider: { kind: "acp", label: name, command: "" } };\n return { team: { label: name, main: "main", members: { main: {} }, delegation: {}, supervisor: false }, houseRules: "" };\n}\nfunction entryTabs(kind, saved) {\n const tabs = {\n agents: [["general", "General"], ["instructions", "Instructions"], ["capabilities", "Skills, MCP & hooks"]],\n teams: [["models", "Models & effort"], ["general", "General"], ["members", "Members"], ["delegation", "Delegation"], ["supervisor", "Supervisor"], ["rules", "House rules"]],\n skills: [["body", "SKILL.md"]],\n mcp: [["server", "Server"], ["test", "Test"]],\n hooks: [["hook", "Hook"], ["test", "Test"]],\n providers: [["agent", "ACP agent"], ["test", "Test"]]\n };\n return tabs[kind].filter(([key]) => key !== "test" || saved).map(([key, label]) => ({ key, label }));\n}\nfunction EntryEditor({ theme, compact, scope, kind, entry, lists, actions, layout, initialTab }) {\n const styles = (0, import_react4.useMemo)(() => makeStyles2(theme, compact), [theme, compact]);\n const { one, title } = kindOf(kind);\n const tabs = entryTabs(kind, !!entry);\n const [tab, setTab] = (0, import_react4.useState)(initialTab && tabs.some((candidate) => candidate.key === initialTab) ? initialTab : tabs[0].key);\n const [name, setName] = (0, import_react4.useState)(entry?.name ?? "");\n const original = (0, import_react4.useMemo)(() => clone2(entry?.content ?? blank(kind)), [entry, kind]);\n const [content, setContent] = (0, import_react4.useState)(() => clone2(original));\n const [result, setResult] = (0, import_react4.useState)(null);\n const own = entry?.source === scope;\n const update = (change) => setContent((current) => {\n const draft = clone2(current);\n change(draft);\n return draft;\n });\n const valid = NAME.test(name);\n const changed = !entry || JSON.stringify(content) !== JSON.stringify(original);\n const givenOriginal = (0, import_react4.useMemo)(() => entry?.librarySkills ?? [], [entry]);\n const [given, setGiven] = (0, import_react4.useState)(givenOriginal);\n const givesSkills = kind === "agents" && scope === "library";\n const givenChanged = givesSkills && [...given].sort().join() !== [...givenOriginal].sort().join();\n const dirty = changed || givenChanged;\n const onSave = () => __async(null, null, function* () {\n if (!valid) return;\n if (changed && !(yield actions.save(kind, name, content, own ? entry.revision : null, !entry))) return;\n if (givenChanged) yield actions.giveSkills(name, given);\n });\n const note = entry ? entry.source === "builtin" ? `Built into ALP. Saving makes ${scope === "library" ? "your library\'s" : "this project\'s"} own ${entry.name}, which overrides it.` : own ? `In ${scope === "library" ? "your library" : "this project"}${entry.overrides ? `; overrides the ${sourceLabel(entry.overrides)} one` : ""}.` : `From the ${sourceLabel(entry.source)}. Saving makes this project\'s own copy.` : null;\n const form = { content, update, lists, styles, theme };\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: kind, ...entry ? { child: entry.name } : {} },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: [title, entry ? entry.name : `New ${one}`],\n badges: entry ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: sourceLabel(entry.source), tone: sourceTone(entry.source) }),\n entry.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: `overrides ${sourceLabel(entry.overrides)}` }) : null\n ] }) : null,\n actions: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, icon: "ArrowLeft", label: `All ${title.toLowerCase()}`, onPress: () => actions.select({ kind }) }),\n tabs,\n tab,\n onTab: setTab,\n footer: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", label: entry && entry.source === "builtin" && (changed || !givenChanged) ? "Save as my own" : "Save", disabled: !valid || !dirty, onPress: () => {\n void onSave();\n } }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: !valid ? "Name the entry first" : dirty ? "Unsaved changes" : own ? "Saved" : "No changes" }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: { flex: 1 } }),\n entry && own ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "danger", label: entry.overrides ? `Remove (the ${sourceLabel(entry.overrides)} one applies again)` : "Remove", onPress: () => actions.remove(kind, entry.name, entry.revision) }) : null\n ] }),\n children: [\n note || entry?.usedBy.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.banner, children: [\n note ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.bannerText, children: note }) : null,\n entry?.usedBy.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, children: [\n "Used by ",\n entry.usedBy.join(", "),\n "."\n ] }) : null\n ] }) : null,\n !entry && tab === tabs[0].key ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSection, { title: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Name", hint: "Letters, digits, \'.\', \'_\' or \'-\'", error: name && !valid ? "Not a valid name" : null, initialValue: name, onChangeText: setName }) }) : null,\n kind === "agents" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentForm, { ...form, tab, given: entry?.librarySkills ?? [], ...givesSkills ? { draftGiven: given, setGiven } : {} }) : null,\n kind === "teams" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamForm, { ...form, tab }) : null,\n kind === "skills" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.body ?? "", onChange: (text) => update((draft) => {\n draft.body = text;\n }), styles, theme, label: "SKILL.md", tall: true }) : null,\n kind === "mcp" && tab === "server" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(McpForm, { content, update }) : null,\n kind === "hooks" && tab === "hook" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HookForm, { content, update, lists }) : null,\n kind === "providers" && tab === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ProviderForm, { content, update }) : null,\n tab === "test" && entry ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Test", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: kind === "mcp" ? "Start the server and list its tools" : kind === "providers" ? "Start the agent and ask what it supports" : "Run once with a sample event", hint: "The test runs what is saved.", actionLabel: "Test", onPress: () => __async(null, null, function* () {\n return setResult(yield actions.test(kind, entry.name));\n }) }),\n result ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TestResult, { kind, result, styles }) : null\n ] }) : null\n ]\n }\n );\n}\nvar names = (lists, kind) => (lists[kind] ?? []).map((row) => row.name);\nvar toggle = (list, name, on) => {\n const set = new Set(list ?? []);\n if (on) set.add(name);\n else set.delete(name);\n return [...set];\n};\nvar setOrDelete = (target, key, value) => {\n if (value === "" || value === void 0 || Array.isArray(value) && !value.length) delete target[key];\n else target[key] = value;\n};\nvar CONTEXT_SIZES = [2e5, 4e5, 6e5, 1e6];\nvar contextOptions = (current) => [\n { label: "Auto (the model\'s)", value: "" },\n ...[.../* @__PURE__ */ new Set([...CONTEXT_SIZES, ...typeof current === "number" ? [current] : []])].sort((a, b) => a - b).map((tokens) => ({ label: tokens >= 1e6 ? `${tokens / 1e6}M tokens` : `${Math.round(tokens / 1e3)}k tokens`, value: String(tokens) }))\n];\nfunction AgentForm({ content, update, lists, styles, theme, tab, given = [], draftGiven, setGiven }) {\n const config = content.config ?? {};\n const field = (key) => (text) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, key, text.trim());\n });\n const show = (key) => !tab || tab === key;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n show("general") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Agent", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: config.description ?? "", onChangeText: field("description") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Provider", hint: "The team or project settings may choose another", value: config.provider ?? "", options: [{ label: "Default", value: "" }, { label: "Codex", value: "codex" }, { label: "Claude Code", value: "claude" }, ...names(lists, "providers").map((provider) => ({ label: `${provider} (ACP)`, value: provider }))], onValueChange: field("provider") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Model", hint: "Such as claude:claude-sonnet-5-5, codex:gpt-6-sol or acp:gemini", initialValue: config.model ?? "", onChangeText: field("model") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Thinking", hint: "Effort, such as low, medium or high", initialValue: config.thinking ?? "", onChangeText: field("thinking") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSelect,\n {\n label: "Context",\n hint: "How much context it works with before the runtime compacts it",\n value: typeof config.context === "number" ? String(config.context) : "",\n options: contextOptions(config.context),\n onValueChange: (value) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, "context", value ? Number(value) : "");\n })\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Default mode", value: config.mode ?? "", options: MODES.map((mode) => ({ label: mode || "As its requester chooses", value: mode })), onValueChange: field("mode") })\n ] }) : null,\n show("instructions") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.instructions ?? "", onChange: (text) => update((draft) => {\n draft.instructions = text;\n }), styles, theme, label: "AGENT.md", tall: true }) : null,\n show("capabilities") ? ["skills", "mcp", "hooks"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: kindOf(kind).title, children: [\n !names(lists, kind).length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: `No ${kindOf(kind).title.toLowerCase()} to choose from yet` }) : null,\n names(lists, kind).map((name) => {\n const own = (config[kind] ?? []).includes(name);\n const configToggle = (on) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, kind, toggle(draft.config[kind], name, on));\n });\n if (kind !== "skills") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, value: own, onValueChange: configToggle }, name);\n if (setGiven) {\n const library = (draftGiven ?? given).includes(name);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSwitch,\n {\n label: name,\n hint: given.includes(name) ? "Default for this agent" : void 0,\n value: library || own,\n onValueChange: (on) => {\n setGiven(toggle(draftGiven ?? given, name, on));\n if (!on && own) configToggle(false);\n }\n },\n name\n );\n }\n if (given.includes(name)) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, hint: "Given by your library; change it in Settings \\u2192 ALP", value: true, disabled: true, onValueChange: () => {\n } }, name);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, value: own, onValueChange: configToggle }, name);\n })\n ] }, kind)) : null\n ] });\n}\nfunction withMember(team, agent, on) {\n const next = clone2(team);\n next.members ?? (next.members = {});\n next.delegation ?? (next.delegation = {});\n if (on) {\n next.members[agent] = { role: "peer" };\n return next;\n }\n delete next.members[agent];\n delete next.delegation[agent];\n for (const owner of Object.keys(next.delegation)) {\n next.delegation[owner] = next.delegation[owner].filter((target) => target !== agent);\n if (!next.delegation[owner].length) delete next.delegation[owner];\n }\n return next;\n}\nfunction withDelegation(team, owner, target, on) {\n const next = clone2(team);\n next.delegation ?? (next.delegation = {});\n const targets = toggle(next.delegation[owner], target, on);\n if (targets.length) next.delegation[owner] = targets;\n else delete next.delegation[owner];\n return next;\n}\nvar EFFORTS = ["", "none", "low", "medium", "high", "xhigh", "max"];\nvar effortOptions = EFFORTS.map((value) => ({ label: value || "Inherit", value }));\nfunction TeamModels({ content, update, theme }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamModelSettings, { team: content.team ?? {}, theme, onChange: (next) => update((draft) => {\n draft.team = next;\n }) });\n}\nfunction TeamForm({ content, update, lists, styles, theme, tab }) {\n const show = (key) => !tab || tab === key;\n const team = content.team ?? {};\n const agents = names(lists, "agents");\n const members = Object.keys(team.members ?? {});\n const others = members.filter((member) => member !== team.main);\n const cycle = delegationCycle(team.delegation ?? {});\n const text = (key) => (value) => update((draft) => {\n setOrDelete(draft.team, key, value.trim());\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n show("models") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamModels, { content, update, lists, styles, theme }) : null,\n show("general") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Team", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Label", hint: "Shown in the model picker", initialValue: team.label ?? "", onChangeText: text("label") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: team.description ?? "", onChangeText: text("description") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Most peers at once", initialValue: team.maxPeers === void 0 ? "" : String(team.maxPeers), onChangeText: (value) => update((draft) => {\n setOrDelete(draft.team, "maxPeers", value.trim() ? Number(value) : "");\n }) })\n ] }) : null,\n show("members") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: [team.main, ...agents.filter((agent) => agent !== team.main && agent !== team.supervisor?.agent)].filter(Boolean).map((agent) => {\n const member = team.members?.[agent];\n const main = agent === team.main;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: main ? `${agent} \\xB7 main` : agent, info: main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: "The agent you talk with." }) : void 0, children: [\n !main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "In this team", value: !!member, onValueChange: (on) => update((draft) => {\n draft.team = withMember(draft.team, agent, on);\n }) }) : null,\n member && !main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Role", value: member.role ?? "peer", options: ROLES.map((role) => ({ label: role, value: role })), onValueChange: (role) => update((draft) => {\n draft.team.members[agent].role = role;\n }) }) : null\n ] }, agent);\n }) }) : null,\n show("delegation") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n cycle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.danger, children: [\n "Cycle at ",\n cycle,\n ": ALP refuses it"\n ] }) : null,\n members.map((owner) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: `${owner} may delegate to`, info: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: (team.delegation?.[owner] ?? []).join(", ") || "no one" }), children: [\n others.filter((target) => target !== owner).map((target) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: target, value: (team.delegation?.[owner] ?? []).includes(target), onValueChange: (on) => update((draft) => {\n draft.team = withDelegation(draft.team, owner, target, on);\n }) }, `${owner}-${target}`)),\n !others.filter((target) => target !== owner).length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: "No other members" }) : null\n ] }, owner))\n ] }) : null,\n show("supervisor") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Supervisor", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "Review main\'s process after each turn", value: !!team.supervisor, onValueChange: (on) => update((draft) => {\n draft.team.supervisor = on ? { agent: "supervisor" } : false;\n }) }),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Supervisor agent", value: team.supervisor.agent, options: agents.filter((agent) => !members.includes(agent)).map((agent) => ({ label: agent, value: agent })), onValueChange: (agent) => update((draft) => {\n draft.team.supervisor.agent = agent;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: "Model & effort", hint: "Configure in Models & effort" })\n ] }) : null\n ] }) : null,\n show("rules") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.houseRules ?? "", onChange: (value) => update((draft) => {\n draft.houseRules = value;\n }), styles, theme, label: "House rules", placeholder: "The team\'s rules and process, which every member reads (HOUSE_RULES.md)", tall: true }) : null\n ] });\n}\nfunction delegationCycle(graph) {\n const visiting = /* @__PURE__ */ new Set();\n const done = /* @__PURE__ */ new Set();\n const visit = (owner) => {\n if (visiting.has(owner)) return owner;\n if (done.has(owner)) return null;\n visiting.add(owner);\n for (const target of graph[owner] ?? []) {\n const found = visit(target);\n if (found) return found;\n }\n visiting.delete(owner);\n done.add(owner);\n return null;\n };\n for (const owner of Object.keys(graph)) {\n const found = visit(owner);\n if (found) return found;\n }\n return null;\n}\nvar lines = (text) => text.split("\\n").map((line) => line.trim()).filter(Boolean);\nvar pairs = (text) => Object.fromEntries(lines(text).filter((line) => line.includes("=")).map((line) => [line.slice(0, line.indexOf("=")).trim(), line.slice(line.indexOf("=") + 1).trim()]));\nvar unpairs = (map) => Object.entries(map ?? {}).map(([key, value]) => `${key}=${value}`).join("\\n");\nfunction McpForm({ content, update }) {\n const server = content.server ?? {};\n const http = server.url !== void 0;\n const set = (key, value) => update((draft) => {\n setOrDelete(draft.server, key, value);\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Server", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Transport", value: http ? "http" : "stdio", options: [{ label: "Command (stdio)", value: "stdio" }, { label: "URL (HTTP)", value: "http" }], onValueChange: (kind) => update((draft) => {\n draft.server = kind === "http" ? { url: "" } : { command: "" };\n }) }),\n http ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "URL", initialValue: server.url ?? "", onChangeText: (value) => update((draft) => {\n draft.server.url = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Headers", hint: "Name=value, separated by \';\'", initialValue: unpairs(server.headers).replaceAll("\\n", "; "), onChangeText: (value) => set("headers", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) })\n ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", initialValue: server.command ?? "", onChangeText: (value) => update((draft) => {\n draft.server.command = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Arguments", hint: "Separated by spaces", initialValue: (server.args ?? []).join(" "), onChangeText: (value) => set("args", value.split(/\\s+/).filter(Boolean)) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Environment", hint: "NAME=value, separated by \';\'", initialValue: unpairs(server.env).replaceAll("\\n", "; "), onChangeText: (value) => set("env", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Working directory", hint: "Relative to the mcp directory", initialValue: server.cwd ?? "", onChangeText: (value) => set("cwd", value.trim()) })\n ] })\n ] });\n}\nfunction ProviderForm({ content, update }) {\n const provider = content.provider ?? {};\n const set = (key, value) => update((draft) => {\n draft.provider ?? (draft.provider = { kind: "acp" });\n setOrDelete(draft.provider, key, value);\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "ACP agent", info: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { children: "Any agent that speaks the Agent Client Protocol on stdio. ALP answers its permission requests by the session\'s mode; it cannot steer it mid-turn or sandbox its commands." }), children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Label", initialValue: provider.label ?? "", onChangeText: (value) => set("label", value.trim()) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: provider.description ?? "", onChangeText: (value) => set("description", value.trim()) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", hint: "Such as gemini, or an absolute path", initialValue: provider.command ?? "", onChangeText: (value) => update((draft) => {\n draft.provider.command = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Arguments", hint: "Separated by spaces, such as --experimental-acp", initialValue: (provider.args ?? []).join(" "), onChangeText: (value) => set("args", value.split(/\\s+/).filter(Boolean)) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Environment", hint: "NAME=value, separated by \';\'", initialValue: unpairs(provider.env).replaceAll("\\n", "; "), onChangeText: (value) => set("env", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Models", hint: "Ids the agent offers, separated by \',\'; empty lets any through", initialValue: (provider.models ?? []).map((model) => model.id).join(", "), onChangeText: (value) => set("models", value.split(",").map((id) => id.trim()).filter(Boolean).map((id) => (provider.models ?? []).find((model) => model.id === id) ?? { id })) })\n ] });\n}\nfunction HookForm({ content, update, lists }) {\n const hook = content.hook ?? {};\n const set = (key, value) => update((draft) => {\n setOrDelete(draft.hook, key, value);\n });\n const blocking = BLOCKING_EVENTS.includes(hook.event);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Hook", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Event", value: hook.event ?? "handoff", options: HOOK_EVENTS.map((event) => ({ label: event, value: event })), onValueChange: (event) => update((draft) => {\n draft.hook.event = event;\n if (!BLOCKING_EVENTS.includes(event)) delete draft.hook.blocking;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", hint: "Runs in the session\'s directory; the event arrives as JSON on stdin", initialValue: hook.command ?? "", onChangeText: (value) => update((draft) => {\n draft.hook.command = value;\n }) }),\n blocking ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "Block the action when it fails", hint: "Its stderr becomes the reason the agent reads", value: !!hook.blocking, onValueChange: (on) => set("blocking", on || void 0) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Timeout (seconds)", initialValue: hook.timeoutSec === void 0 ? "" : String(hook.timeoutSec), onChangeText: (value) => set("timeoutSec", value.trim() ? Number(value) : "") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Only for agent", value: hook.match?.agent ?? "", options: [{ label: "Every agent", value: "" }, ...names(lists, "agents").map((agent) => ({ label: agent, value: agent }))], onValueChange: (agent) => update((draft) => {\n var _a;\n (_a = draft.hook).match ?? (_a.match = {});\n setOrDelete(draft.hook.match, "agent", agent);\n if (!Object.keys(draft.hook.match).length) delete draft.hook.match;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Only for tasks labeled", initialValue: hook.match?.label ?? "", onChangeText: (label) => update((draft) => {\n var _a;\n (_a = draft.hook).match ?? (_a.match = {});\n setOrDelete(draft.hook.match, "label", label.trim());\n if (!Object.keys(draft.hook.match).length) delete draft.hook.match;\n }) })\n ] });\n}\nfunction TestResult({ kind, result, styles }) {\n if (kind === "providers") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.success, children: [\n result.agent?.title ?? result.agent?.name ?? "The agent",\n result.agent?.version ? ` ${result.agent.version}` : "",\n " speaks ACP ",\n result.protocolVersion\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n result.loadSession ? "Resumes sessions" : "Cannot resume sessions",\n result.mcpHttp ? "; takes HTTP MCP servers" : "; takes stdio MCP servers only",\n result.authMethods?.length ? `; signs in with ${result.authMethods.join(", ")}` : ""\n ] })\n ] });\n }\n if (kind === "mcp") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.success, children: [\n result.server?.name ?? "The server",\n result.server?.version ? ` ${result.server.version}` : "",\n " offers ",\n result.tools?.length ?? 0,\n " tools"\n ] }),\n (result.tools ?? []).map((tool) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n tool.name,\n tool.description ? ` \\u2014 ${tool.description.split("\\n")[0]}` : ""\n ] }, tool.name))\n ] });\n }\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: result.ok ? styles.success : styles.danger, children: [\n result.timedOut ? "Timed out" : `Exit ${result.exitCode ?? result.signal}`,\n " in ",\n result.durationMs,\n " ms",\n result.wouldBlock ? "; as a blocking hook it would refuse the action" : ""\n ] }),\n result.stdout ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.code, children: result.stdout }) : null,\n result.stderr ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.code, children: result.stderr }) : null\n ] });\n}\nfunction Multiline({ value, onChange, styles, theme, label, placeholder, tall }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.TextInput, { style: [styles.multiline, tall ? styles.tall : null], value, onChangeText: onChange, multiline: true, accessibilityLabel: label, placeholder: placeholder ?? label, placeholderTextColor: theme.colors.foregroundMuted });\n}\nfunction makeStyles2(theme, compact) {\n const { colors } = theme;\n return {\n screen: { flex: 1, backgroundColor: colors.surface0, padding: compact ? 12 : 20 },\n muted: { color: colors.foregroundMuted, fontSize: 13, lineHeight: 19 },\n small: { color: colors.foregroundMuted, fontSize: 12 },\n danger: { color: colors.statusDanger, fontSize: 13 },\n success: { color: colors.statusSuccess, fontSize: 13 },\n name: { color: colors.foreground, fontSize: 14, fontWeight: "600" },\n empty: { borderWidth: 1, borderStyle: "dashed", borderColor: colors.border, borderRadius: 10, padding: 24, alignItems: "center" },\n table: { borderWidth: 1, borderColor: colors.border, borderRadius: 10, backgroundColor: colors.surface1, overflow: "hidden" },\n tableRow: { flexDirection: compact ? "column" : "row", flexWrap: "wrap", alignItems: compact ? "stretch" : "center", gap: 10, paddingHorizontal: 14, paddingVertical: 12 },\n tableRowRule: { borderTopWidth: 1, borderTopColor: colors.border },\n rowMain: { flex: 1, minWidth: 0, gap: 3 },\n rowTitle: { flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" },\n rowActions: { flexDirection: "row", gap: 8, alignItems: "center" },\n rowActionsCompact: { flexWrap: "wrap" },\n copyRow: { flexBasis: "100%", flexDirection: "row", gap: 8, alignItems: "center" },\n input: { flex: 1, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 7, backgroundColor: colors.surface0 },\n banner: { borderRadius: 10, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, paddingHorizontal: 14, paddingVertical: 10, gap: 4 },\n bannerText: { color: colors.foreground, fontSize: 13 },\n multiline: { minHeight: 160, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 10, padding: 12, fontFamily: "monospace", fontSize: 13, lineHeight: 19, backgroundColor: colors.surface1, textAlignVertical: "top" },\n tall: { minHeight: 420 },\n code: { color: colors.foreground, fontFamily: "monospace", fontSize: 12 }\n };\n}\n\n// integrations/paseo/client/usage.tsx\nvar import_client4 = require("@getpaseo/plugin/client");\nvar import_react_native8 = require("@getpaseo/plugin/client/react-native");\nvar import_react5 = require("react");\nvar import_react_native9 = require("react-native");\n\n// integrations/paseo/shared/usage.ts\nvar import_plugin3 = require("@getpaseo/plugin");\nvar import_zod3 = require("zod");\nvar Pause = import_zod3.z.object({ reason: import_zod3.z.string(), since: import_zod3.z.string(), resetsAt: import_zod3.z.string().optional() });\nvar usageGet = (0, import_plugin3.defineRpc)({\n name: "alp.usage.get",\n input: import_zod3.z.object({ refresh: import_zod3.z.boolean().optional() }),\n output: import_zod3.z.object({\n providers: import_zod3.z.array(import_zod3.z.object({\n runtime: import_zod3.z.enum(["codex", "claude"]),\n available: import_zod3.z.boolean(),\n checkedAt: import_zod3.z.string(),\n plan: import_zod3.z.string().nullable(),\n limited: import_zod3.z.boolean(),\n windows: import_zod3.z.array(import_zod3.z.object({ name: import_zod3.z.string(), usedPercent: import_zod3.z.number().nullable(), resetsAt: import_zod3.z.string().nullable() })),\n pause: Pause.nullable(),\n parked: import_zod3.z.number()\n }))\n })\n});\n\n// integrations/paseo/client/usage.tsx\nvar import_jsx_runtime5 = require("react/jsx-runtime");\nfunction UsageScreen({ theme, layout }) {\n const read = (0, import_client4.useRpc)(usageGet);\n const [data, setData] = (0, import_react5.useState)(null);\n const [error, setError] = (0, import_react5.useState)(null);\n const [loading, setLoading] = (0, import_react5.useState)(true);\n const [tick, setTick] = (0, import_react5.useState)(0);\n const forceRefresh = (0, import_react5.useRef)(false);\n (0, import_react5.useEffect)(() => {\n let live = true;\n setLoading(true);\n const refresh = forceRefresh.current;\n forceRefresh.current = false;\n read({ refresh }).then((result) => {\n if (live) {\n setData(result);\n setError(null);\n }\n }).catch((cause) => {\n if (live) setError(cause instanceof Error ? cause.message : String(cause));\n }).finally(() => {\n if (live) setLoading(false);\n });\n return () => {\n live = false;\n };\n }, [read, tick]);\n (0, import_react5.useEffect)(() => {\n const timer = setInterval(() => setTick((value) => value + 1), 6e4);\n return () => clearInterval(timer);\n }, []);\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UsageView, { theme, compact: layout.compact, data, loading, error, onRefresh: () => {\n forceRefresh.current = true;\n setTick((value) => value + 1);\n } });\n}\nfunction dateLabel(value) {\n const date = new Date(value);\n return Number.isFinite(date.getTime()) ? date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" }) : "Unknown";\n}\nfunction resetLabel(value, now) {\n if (!value) return "Reset time unavailable";\n const minutes = Math.ceil((Date.parse(value) - now) / 6e4);\n if (minutes <= 0) return "Reset time passed \\xB7 awaiting provider update";\n const duration = minutes >= 1440 ? `${Math.floor(minutes / 1440)}d ${Math.floor(minutes % 1440 / 60)}h` : minutes >= 60 ? `${Math.floor(minutes / 60)}h ${minutes % 60}m` : `${minutes}m`;\n return `Resets in ${duration} \\xB7 ${dateLabel(value)}`;\n}\nfunction UsageView({ theme, compact, data, loading, error, onRefresh, now = Date.now() }) {\n const { colors } = theme;\n const muted = { color: colors.foregroundMuted, fontSize: 13, lineHeight: 20 };\n const providers = data?.providers ?? [];\n const parked = providers.reduce((sum, provider) => sum + provider.parked, 0);\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native8.ScrollView, { contentContainerStyle: { padding: compact ? 16 : 28, gap: 24 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityRole: "header", style: { color: colors.foreground, fontSize: 28, fontWeight: "600", letterSpacing: -0.7 }, children: "Usage" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { theme, label: loading ? "Refreshing\\u2026" : "Refresh", icon: "RefreshCw", disabled: loading, onPress: onRefresh, accessibilityLabel: "Refresh usage" })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Your provider limits, reset windows and paused work in one place." })\n ] }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { accessibilityRole: "alert", style: { padding: 14, borderWidth: 1, borderColor: colors.statusDanger, borderRadius: 10, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.statusDanger, fontWeight: "600" }, children: "Could not refresh usage" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: error }),\n data ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Showing the last received data." }) : null\n ] }) : null,\n parked > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { padding: 14, backgroundColor: colors.surface1, borderLeftWidth: 3, borderLeftColor: colors.statusWarning, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: { color: colors.foreground, fontWeight: "600" }, children: [\n parked,\n " ",\n parked === 1 ? "assignment waiting" : "assignments waiting"\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Parked work stays saved while its runtime is paused." })\n ] }) : null,\n !data && loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityLiveRegion: "polite", style: muted, children: "Checking Codex and Claude usage\\u2026" }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { style: { flexDirection: compact ? "column" : "row", flexWrap: "wrap", gap: 16 }, children: providers.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProviderCard, { theme, provider, compact, now }, provider.runtime)) }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { borderTopWidth: 1, borderTopColor: colors.border, paddingTop: 16, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Account limits reported by each provider, shared with usage outside ALP." }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { ...muted, fontSize: 12 }, children: "Updates every minute while this screen is open. Readings are cached for up to 30 seconds. This is not a billing or token-spend report." })\n ] })\n ] });\n}\nfunction ProviderCard({ theme, provider, compact, now }) {\n const { colors } = theme;\n const status = provider.pause ? "Paused" : !provider.available ? "Unavailable" : provider.limited ? "Limit reached" : "Available";\n const tone = provider.pause || provider.limited ? "warning" : provider.available ? "success" : "muted";\n const muted = { color: colors.foregroundMuted, fontSize: 12, lineHeight: 18 };\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexGrow: 1, flexBasis: compact ? "auto" : 320, width: compact ? "100%" : void 0, minWidth: 0, padding: 20, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, borderRadius: 14, gap: 20 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityRole: "header", style: { color: colors.foreground, fontSize: 20, fontWeight: "600" }, children: provider.runtime === "codex" ? "Codex" : "Claude" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: provider.plan ? `${provider.plan} plan` : "Plan not reported" })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Pill, { theme, label: status, tone })\n ] }),\n provider.pause ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 5 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.statusWarning, fontSize: 13 }, children: provider.pause.reason }),\n provider.pause.resetsAt ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: resetLabel(provider.pause.resetsAt, now) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: muted, children: [\n provider.parked,\n " ",\n provider.parked === 1 ? "assignment parked" : "assignments parked"\n ] })\n ] }) : null,\n !provider.available ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8, paddingVertical: 16 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native8.Icon, { name: "CircleHelp", size: 22, color: colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.foreground, fontSize: 14, fontWeight: "500" }, children: "Usage is not available" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "The provider did not return usage data. Check that its CLI is installed and signed in, then refresh." })\n ] }) : provider.windows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "The provider has not reported any usage windows." }) : provider.windows.map((window, index) => {\n const used = window.usedPercent;\n const color = used === null ? colors.foregroundMuted : used >= 95 ? colors.statusDanger : used >= 80 ? colors.statusWarning : colors.accent;\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.foreground, fontSize: 13, flex: 1, textTransform: "capitalize" }, children: window.name }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color, fontSize: 25, fontWeight: "600", fontVariant: ["tabular-nums"] }, children: used === null ? "\\u2014" : `${Math.round(used)}%` })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { accessibilityRole: "progressbar", accessibilityLabel: `${window.name} used`, accessibilityValue: used === null ? { text: "Usage unknown" } : { min: 0, max: 100, now: used }, style: { height: 6, backgroundColor: colors.surface2, borderRadius: 3, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { style: { height: 6, width: `${used ?? 0}%`, backgroundColor: color, borderRadius: 3 } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: used === null ? "Usage percentage unavailable" : `${Math.round(100 - used)}% remaining` }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: resetLabel(window.resetsAt, now) })\n ] }, `${window.name}-${index}`);\n }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: { ...muted, borderTopWidth: 1, borderTopColor: colors.border, paddingTop: 12 }, children: [\n "Checked ",\n dateLabel(provider.checkedAt)\n ] })\n ] });\n}\n\n// integrations/paseo/index.client.tsx\nfunction contribute(client) {\n const removePanel = client.addWorkspacePanel({ id: "alp-tasks", title: "Tasks", icon: "ListTodo", context: "workspace", Component: TasksPanel });\n const removeScreen = client.addScreen({ id: TASKS_SCREEN, title: (params) => params.taskId ? `ALP task ${params.taskId}` : "ALP tasks", Component: TasksScreen });\n const removePills = addTaskPills(client);\n const removeCommand = client.addCommandCenterItem({\n id: "alp-open-tasks",\n title: "Open ALP tasks",\n icon: "ListTodo",\n keywords: ["tasks", "todo", "alp"],\n context: "workspace",\n onSelect({ openPanel }) {\n openPanel("alp-tasks");\n }\n });\n const removeScreenCommand = client.addCommandCenterItem({\n id: "alp-open-tasks-screen",\n title: "Open ALP tasks full screen",\n icon: "ListTodo",\n keywords: ["tasks", "todo", "alp", "phone"],\n context: "workspace",\n onSelect({ workspace, openScreen }) {\n openScreen(tasksScreen(workspace.id, workspace.directory || workspace.projectRootPath));\n }\n });\n const removeSlash = client.addSlashCommand({\n name: "alp-tasks",\n description: "Open the ALP tasks of this project",\n argumentHint: "[task id]",\n context: "agent",\n onSubmit({ workspace, args, openScreen }) {\n openScreen(tasksScreen(workspace.id, workspace.directory || workspace.projectRootPath, args.trim() || void 0));\n }\n });\n const removeSettings = client.addSettingsScreen({ id: "alp-settings", title: "ALP", icon: "Bot", Component: LibrarySettings });\n const removeHostSettings = [\n { id: "alp-templates", title: "Templates", icon: "Users", Component: TeamsSettings },\n { id: "alp-agents", title: "Agents", icon: "Bot", Component: AgentsSettings },\n { id: "alp-skills", title: "Skills", icon: "BookOpen", Component: SkillsSettings },\n { id: "alp-hooks", title: "Hooks", icon: "Webhook", Component: HooksSettings },\n { id: "alp-mcp", title: "MCP servers", icon: "Plug", Component: McpSettings }\n ].map((screen) => client.addSettingsScreen(screen));\n const removeUsage = client.addSettingsScreen({ id: "alp-usage", title: "Usage", icon: "ChartNoAxesCombined", Component: UsageScreen });\n const removeUsagePanel = client.addWorkspacePanel({ id: "alp-usage", title: "Usage", icon: "ChartNoAxesCombined", context: "workspace", Component: UsageScreen });\n const removeProject = client.addWorkspacePanel({ id: "alp-project", title: "ALP project", icon: "Bot", context: "workspace", Component: ProjectLibraryPanel });\n return () => {\n removePanel();\n removeScreen();\n removePills();\n removeCommand();\n removeScreenCommand();\n removeSlash();\n removeSettings();\n removeHostSettings.forEach((remove) => remove());\n removeProject();\n removeUsage();\n removeUsagePanel();\n };\n}\n\nreturn module.exports;})' };
7809
+ var plugin_client_default = { "id": "alp-provider", "requirements": { "paseo": ">=0.11.1 <0.13.0" }, "factory": '(function(require){const module={exports:{}};const exports=module.exports;var __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === "object" || typeof from === "function") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { value: from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\nvar __async = (__this, __arguments, generator) => {\n return new Promise((resolve, reject) => {\n var fulfilled = (value) => {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n };\n var rejected = (value) => {\n try {\n step(generator.throw(value));\n } catch (e) {\n reject(e);\n }\n };\n var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);\n step((generator = generator.apply(__this, __arguments)).next());\n });\n};\n\n// integrations/paseo/index.client.tsx\nvar index_client_exports = {};\n__export(index_client_exports, {\n default: () => contribute\n});\nmodule.exports = __toCommonJS(index_client_exports);\n\n// integrations/paseo/client/tasks-panel.tsx\nvar import_client = require("@getpaseo/plugin/client");\nvar import_react_native = require("@getpaseo/plugin/client/react-native");\nvar import_react = require("react");\nvar import_react_native2 = require("react-native");\n\n// integrations/paseo/shared/tasks.ts\nvar import_plugin = require("@getpaseo/plugin");\nvar import_zod = require("zod");\nvar TaskRowSchema = import_zod.z.object({\n id: import_zod.z.string(),\n title: import_zod.z.string(),\n type: import_zod.z.string(),\n priority: import_zod.z.number(),\n status: import_zod.z.enum(["open", "in_progress", "review", "closed"]),\n parent: import_zod.z.string().optional(),\n assignee: import_zod.z.string().optional(),\n ready: import_zod.z.boolean(),\n /** Open tasks that must close first, including those of ancestors. */\n blockedBy: import_zod.z.array(import_zod.z.string()).optional(),\n /** Open gates, as labels. */\n waits: import_zod.z.array(import_zod.z.string()).optional(),\n /** Open human gates of this task: the user approves them here. */\n approvals: import_zod.z.array(import_zod.z.object({ gate: import_zod.z.string(), note: import_zod.z.string() })).optional(),\n handoff: import_zod.z.object({ outcome: import_zod.z.string(), summary: import_zod.z.string(), agent: import_zod.z.string().optional() }).optional(),\n closed: import_zod.z.object({ reason: import_zod.z.string(), summary: import_zod.z.string().optional(), at: import_zod.z.string() }).optional(),\n /** What the task is about, for its detail view; at most 4000 characters. */\n description: import_zod.z.string().optional(),\n labels: import_zod.z.array(import_zod.z.string()).optional(),\n paths: import_zod.z.array(import_zod.z.string()).optional(),\n /** An epic or parent task: how many of its children are closed. */\n progress: import_zod.z.object({ done: import_zod.z.number(), total: import_zod.z.number() }).optional(),\n createdAt: import_zod.z.string().optional(),\n updatedAt: import_zod.z.string()\n});\nvar Directory = import_zod.z.string().min(1);\nvar tasksList = (0, import_plugin.defineRpc)({\n name: "alp.tasks.list",\n input: import_zod.z.object({ directory: Directory }),\n output: import_zod.z.object({\n /** The ALP project containing the directory, or null when there is none. */\n projectRoot: import_zod.z.string().nullable(),\n tasks: import_zod.z.array(TaskRowSchema),\n unreadable: import_zod.z.array(import_zod.z.object({ file: import_zod.z.string(), error: import_zod.z.string() })),\n /** By provider session id: the tasks that session\'s tree worked on (ALPD \xA755). */\n sessions: import_zod.z.record(import_zod.z.string(), import_zod.z.array(import_zod.z.string())).optional()\n })\n});\nvar tasksAdd = (0, import_plugin.defineRpc)({\n name: "alp.tasks.add",\n input: import_zod.z.object({ directory: Directory, title: import_zod.z.string().trim().min(1).max(200), priority: import_zod.z.number().int().min(0).max(4).optional() }),\n output: import_zod.z.object({ id: import_zod.z.string() })\n});\nvar tasksChange = (0, import_plugin.defineRpc)({\n name: "alp.tasks.change",\n input: import_zod.z.object({\n directory: Directory,\n id: import_zod.z.string().min(1),\n action: import_zod.z.enum(["close", "reopen", "approve"]),\n /** For approve: the human gate. */\n gate: import_zod.z.string().optional(),\n note: import_zod.z.string().max(2e3).optional()\n }),\n /** landed: the first line of the report when the close landed an epic. */\n output: import_zod.z.object({ id: import_zod.z.string(), status: import_zod.z.string(), landed: import_zod.z.string().optional() })\n});\nvar rank = (a, b) => a.priority - b.priority || a.id.localeCompare(b.id);\nfunction boardSections(tasks, closedLimit = 20) {\n const open = tasks.filter((task) => task.status !== "closed");\n const sections = [\n { key: "approve", title: "Waiting for your approval", tasks: open.filter((task) => task.approvals?.length).sort(rank) },\n { key: "review", title: "In review", tasks: open.filter((task) => task.status === "review").sort(rank) },\n { key: "progress", title: "In progress", tasks: open.filter((task) => task.status === "in_progress").sort(rank) },\n { key: "ready", title: "Ready", tasks: open.filter((task) => task.ready).sort(rank) },\n { key: "waiting", title: "Blocked or waiting", tasks: open.filter((task) => task.status === "open" && !task.ready && !task.approvals?.length && task.type !== "epic").sort(rank) },\n { key: "epics", title: "Epics", tasks: open.filter((task) => task.type === "epic" && !task.approvals?.length).sort(rank) },\n { key: "closed", title: "Closed", tasks: tasks.filter((task) => task.status === "closed").sort((a, b) => (b.closed?.at ?? b.updatedAt).localeCompare(a.closed?.at ?? a.updatedAt)).slice(0, closedLimit) }\n ];\n return sections.filter((section) => section.tasks.length);\n}\n\n// integrations/paseo/client/tasks-panel.tsx\nvar import_jsx_runtime = require("react/jsx-runtime");\nvar POLL_MS = 5e3;\nvar SPLIT_FROM = 820;\nfunction TasksPanel({ theme, layout, workspaceId }) {\n const directory = (0, import_client.useWorkspace)(workspaceId, (workspace) => workspace.directory || workspace.projectRootPath);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskBoard, { theme, compact: layout.compact, directory, ...useTasks(directory) });\n}\nfunction TasksScreen({ theme, layout, params }) {\n const directory = params.directory || null;\n const tasks = useTasks(directory);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n TaskBoard,\n {\n theme,\n compact: layout.compact,\n directory,\n ...tasks,\n initial: params.taskId ? { selected: params.taskId } : void 0\n },\n params.taskId ?? ""\n );\n}\nfunction useTasks(directory) {\n const list = (0, import_client.useRpc)(tasksList);\n const add = (0, import_client.useRpc)(tasksAdd);\n const change = (0, import_client.useRpc)(tasksChange);\n const toast = (0, import_react_native.useToast)();\n const [data, setData] = (0, import_react.useState)(null);\n const [error, setError] = (0, import_react.useState)(null);\n const [tick, setTick] = (0, import_react.useState)(0);\n const refresh = (0, import_react.useCallback)(() => setTick((value) => value + 1), []);\n (0, import_react.useEffect)(() => {\n if (!directory) return;\n let live = true;\n const load = () => list({ directory }).then((result) => {\n if (live) {\n setData(result);\n setError(null);\n }\n }).catch((cause) => {\n if (live) setError(cause instanceof Error ? cause.message : String(cause));\n });\n void load();\n const timer = setInterval(load, POLL_MS);\n return () => {\n live = false;\n clearInterval(timer);\n };\n }, [directory, list, tick]);\n const onAdd = (0, import_react.useCallback)((title, priority) => __async(null, null, function* () {\n if (!directory) return false;\n try {\n const { id } = yield add({ directory, title, priority });\n toast.show(`Added ${id}`, { variant: "success" });\n refresh();\n return true;\n } catch (cause) {\n toast.error(cause instanceof Error ? cause.message : String(cause));\n return false;\n }\n }), [add, directory, refresh, toast]);\n const onAction = (0, import_react.useCallback)((_0) => __async(null, [_0], function* ({ id, action, gate }) {\n if (!directory) return;\n try {\n const { landed } = yield change({ directory, id, action, ...gate ? { gate } : {} });\n toast.show(landed ?? (action === "approve" ? `Approved ${id}` : action === "close" ? `Closed ${id}` : `Reopened ${id}`), { variant: "success" });\n refresh();\n } catch (cause) {\n toast.error(cause instanceof Error ? cause.message : String(cause));\n }\n }), [change, directory, refresh, toast]);\n return { projectRoot: data?.projectRoot ?? null, tasks: data?.tasks ?? null, unreadable: data?.unreadable.length ?? 0, error, onAdd, onAction, onRefresh: refresh };\n}\nvar PRIORITIES = [0, 1, 2, 3, 4];\nvar TYPE_ICONS = { bug: "Bug", feature: "Sparkles", task: "SquareCheck", chore: "Wrench", epic: "Target" };\nvar hovered = (state) => !!state.hovered;\nfunction age(iso, now = Date.now()) {\n if (!iso) return "";\n const minutes = Math.max(0, Math.floor((now - Date.parse(iso)) / 6e4));\n if (minutes < 60) return `${minutes}m`;\n if (minutes < 60 * 24) return `${Math.floor(minutes / 60)}h`;\n if (minutes < 60 * 24 * 14) return `${Math.floor(minutes / 1440)}d`;\n return `${Math.floor(minutes / 10080)}w`;\n}\nfunction stateOf(task) {\n if (task.status === "closed") return "closed";\n if (task.approvals?.length) return "approve";\n if (task.status === "review") return "review";\n if (task.status === "in_progress") return "progress";\n if (task.type === "epic") return task.progress?.done ? "progress" : "ready";\n return task.ready ? "ready" : "blocked";\n}\nvar STATE_LABELS = { approve: "Needs approval", review: "In review", progress: "In progress", ready: "Ready", blocked: "Blocked", closed: "Closed" };\nfunction filterTasks(tasks, filter, query) {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean);\n return tasks.filter((task) => {\n if (filter === "open" && task.status === "closed") return false;\n if (filter === "ready" && !(task.ready && task.status !== "closed")) return false;\n if (filter === "closed" && task.status !== "closed") return false;\n const text = [task.id, task.title, task.type, task.assignee ?? "", ...task.labels ?? []].join(" ").toLowerCase();\n return words.every((word) => text.includes(word));\n });\n}\nfunction TaskBoard({ theme, compact, directory, projectRoot, tasks, unreadable, error, onAdd, onAction, onRefresh, initial }) {\n const styles = (0, import_react.useMemo)(() => makeStyles(theme, compact), [theme, compact]);\n const [view, setView] = (0, import_react.useState)(initial?.view ?? "list");\n const [filter, setFilter] = (0, import_react.useState)(initial?.filter ?? "open");\n const [query, setQuery] = (0, import_react.useState)("");\n const [selected, setSelected] = (0, import_react.useState)(initial?.selected ?? null);\n const [composing, setComposing] = (0, import_react.useState)(false);\n const [width, setWidth] = (0, import_react.useState)(initial?.width ?? 0);\n const shown = (0, import_react.useMemo)(() => tasks ? filterTasks(tasks, filter, query) : [], [tasks, filter, query]);\n const task = selected ? tasks?.find((candidate) => candidate.id === selected) ?? null : null;\n const split = !!task && width >= SPLIT_FROM;\n const counts = (0, import_react.useMemo)(() => ({\n open: (tasks ?? []).filter((entry) => entry.status !== "closed").length,\n ready: (tasks ?? []).filter((entry) => entry.ready && entry.status !== "closed").length,\n closed: (tasks ?? []).filter((entry) => entry.status === "closed").length,\n all: (tasks ?? []).length\n }), [tasks]);\n if (!directory) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.muted, children: "This view needs a workspace." }) });\n const open = (id) => setSelected(id);\n const detail = task ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskDetail, { theme, styles, task, tasks: tasks ?? [], onBack: () => setSelected(null), onOpen: open, onAction }) : null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.screen, onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbar, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbarRow, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.title, children: "Tasks" }),\n tasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.count, children: [\n counts.open,\n " open"\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { flex: 1 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n Segmented,\n {\n theme,\n styles,\n value: view,\n onChange: (value) => {\n setView(value);\n setSelected(null);\n },\n options: [{ key: "list", label: "List", icon: "List" }, { key: "board", label: "Board", icon: "Columns3" }, { key: "epics", label: "Epics", icon: "Target" }]\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "RefreshCw", label: "Refresh", onPress: onRefresh }),\n projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "Plus", label: "New task", onPress: () => setComposing(!composing), primary: true }) : null\n ] }),\n projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.toolbarRow, children: [\n ["open", "ready", "closed", "all"].map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Show ${key}`, accessibilityState: { selected: filter === key }, onPress: () => setFilter(key), style: [styles.filter, filter === key ? styles.filterOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: filter === key ? styles.filterTextOn : styles.filterText, children: [\n key[0].toUpperCase() + key.slice(1),\n " ",\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.filterCount, children: counts[key] })\n ] }) }, key)),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.search, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: "Search", size: 14, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.TextInput, { style: styles.searchInput, value: query, onChangeText: setQuery, placeholder: "Filter by id, title, label, agent", placeholderTextColor: theme.colors.foregroundMuted, accessibilityLabel: "Filter tasks" })\n ] })\n ] }) : null,\n composing && projectRoot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Composer, { theme, styles, onAdd: (title, priority) => __async(null, null, function* () {\n const added = yield onAdd(title, priority);\n if (added) setComposing(false);\n return added;\n }) }) : null\n ] }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.danger, styles.pad], children: error }) : null,\n tasks === null && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.muted, styles.pad], children: "Loading tasks\\u2026" }) : null,\n tasks !== null && projectRoot === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: [styles.muted, styles.pad], children: [\n directory,\n " is not an ALP project. Run alp init to start one."\n ] }) : null,\n projectRoot && tasks ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.body, children: [\n !task || split ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: [styles.pane, split ? styles.paneList : null], children: [\n unreadable ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: [styles.warning, styles.pad], children: [\n unreadable,\n " unreadable task ",\n unreadable === 1 ? "file" : "files",\n " in ",\n projectRoot,\n "/.alp/tasks"\n ] }) : null,\n !tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No tasks yet. Add one here, with alp task add, or ask main to plan the work." }) : null,\n tasks.length && !shown.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No tasks match." }) : null,\n shown.length && view === "list" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListView, { theme, styles, tasks: shown, selected, onOpen: open, onAction }) : null,\n shown.length && view === "board" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BoardView, { theme, styles, tasks: shown, onOpen: open }) : null,\n view === "epics" && tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EpicsView, { theme, styles, tasks, shown, onOpen: open }) : null\n ] }) : null,\n detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.pane, split ? styles.paneDetail : null], children: detail }) : null\n ] }) : null\n ] });\n}\nfunction Segmented({ theme, styles, value, options, onChange }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.segmented, children: options.map((option) => {\n const on = option.key === value;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "tab", accessibilityLabel: option.label, accessibilityState: { selected: on }, onPress: () => onChange(option.key), style: [styles.segment, on ? styles.segmentOn : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: option.icon, size: 13, color: on ? theme.colors.foreground : theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: on ? styles.segmentTextOn : styles.segmentText, children: option.label })\n ] }, option.key);\n }) });\n}\nfunction IconButton({ theme, icon, label, onPress, primary }) {\n const { colors } = theme;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n import_react_native2.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: label,\n onPress,\n style: (state) => ({ padding: 7, borderRadius: 8, backgroundColor: primary ? colors.accent : hovered(state) ? colors.surface2 : "transparent" }),\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: icon, size: 15, color: primary ? colors.accentForeground : colors.foregroundMuted })\n }\n );\n}\nfunction Composer({ theme, styles, onAdd }) {\n const [title, setTitle] = (0, import_react.useState)("");\n const [priority, setPriority] = (0, import_react.useState)(2);\n const submit = () => __async(null, null, function* () {\n const text = title.trim();\n if (text && (yield onAdd(text, priority))) setTitle("");\n });\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.composer, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.TextInput, { style: styles.input, value: title, onChangeText: setTitle, onSubmitEditing: submit, placeholder: "Add a task for main", placeholderTextColor: theme.colors.foregroundMuted, accessibilityLabel: "New task title", autoFocus: true }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.priorities, children: PRIORITIES.map((value) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Priority ${value}`, onPress: () => setPriority(value), style: [styles.chip, value === priority ? styles.chipOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: value === priority ? styles.chipTextOn : styles.chipText, children: [\n "P",\n value\n ] }) }, value)) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", onPress: submit, style: styles.button, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.buttonText, children: "Add" }) })\n ] });\n}\nfunction Empty({ styles, text }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.muted, children: text }) });\n}\nfunction Priority({ theme, value }) {\n const { colors } = theme;\n const color = value === 0 ? colors.statusDanger : value === 1 ? colors.statusWarning : colors.foregroundMuted;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { alignSelf: "flex-start", borderRadius: 4, borderWidth: 1, borderColor: value <= 1 ? color : colors.border, paddingHorizontal: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: { color, fontSize: 10.5, fontWeight: "600", fontVariant: ["tabular-nums"] }, children: [\n "P",\n value\n ] }) });\n}\nfunction StateDot({ theme, task }) {\n const { colors } = theme;\n const state = stateOf(task);\n const color = state === "approve" ? colors.statusWarning : state === "review" ? colors.accent : state === "progress" ? colors.statusWarning : state === "ready" ? colors.statusSuccess : state === "blocked" ? colors.statusDanger : colors.border;\n const ring = state === "progress" || state === "closed";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { accessibilityLabel: STATE_LABELS[state], style: { width: 9, height: 9, borderRadius: 5, borderWidth: ring ? 2 : 0, borderColor: color, backgroundColor: ring ? "transparent" : color } });\n}\nfunction TaskLine({ theme, styles, task, selected, onOpen }) {\n const meta = [\n task.blockedBy?.length ? `after ${task.blockedBy.join(", ")}` : "",\n // Gates waiting for the user show with their Approve instead.\n task.waits?.length && !task.approvals?.length ? `waits on ${task.waits.join("; ")}` : "",\n task.parent ? `in ${task.parent}` : ""\n ].filter(Boolean).join(" \\xB7 ");\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${task.id}`, onPress: () => onOpen(task.id), style: (state) => [styles.line, selected ? styles.lineOn : hovered(state) ? styles.lineHover : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.lineTitle, numberOfLines: 1, children: task.title }),\n task.assignee ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.assignee, numberOfLines: 1, children: [\n "@",\n task.assignee\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.age, children: age(task.status === "closed" ? task.closed?.at : task.updatedAt) })\n ] }),\n meta || task.labels?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineMeta, children: [\n meta ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, numberOfLines: 1, children: meta }) : null,\n (task.labels ?? []).map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label))\n ] }) : null\n ] });\n}\nvar SECTION_ICONS = { approve: "Hand", review: "Eye", progress: "LoaderCircle", ready: "CircleCheck", waiting: "CircleSlash", epics: "Target", closed: "CircleDashed" };\nfunction ListView({ theme, styles, tasks, selected, onOpen, onAction }) {\n const sections = (0, import_react.useMemo)(() => boardSections(tasks), [tasks]);\n const [hidden, setHidden] = (0, import_react.useState)({});\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { contentContainerStyle: styles.listContent, children: sections.map((section) => {\n const collapsed = hidden[section.key] ?? false;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.group, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `${collapsed ? "Show" : "Hide"} ${section.title}`, onPress: () => setHidden((current) => ({ ...current, [section.key]: !collapsed })), style: styles.groupHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: collapsed ? "ChevronRight" : "ChevronDown", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: SECTION_ICONS[section.key] ?? "Circle", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupTitle, children: section.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupCount, children: section.tasks.length })\n ] }),\n !collapsed ? section.tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task, selected: task.id === selected, onOpen }),\n section.key === "approve" ? task.approvals.map((approval) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.inlineAction, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, numberOfLines: 2, children: approval.note || "Waiting for your approval" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Approve", primary: true, onPress: () => onAction({ id: task.id, action: "approve", gate: approval.gate }) })\n ] }, approval.gate)) : null\n ] }, `${section.key}-${task.id}`)) : null\n ] }, section.key);\n }) });\n}\nvar COLUMNS = [\n { key: "approve", title: "Needs approval" },\n { key: "blocked", title: "Blocked" },\n { key: "ready", title: "Ready" },\n { key: "progress", title: "In progress" },\n { key: "review", title: "In review" },\n { key: "closed", title: "Closed" }\n];\nfunction BoardView({ theme, styles, tasks, onOpen }) {\n const columns = COLUMNS.map((column) => ({ ...column, tasks: tasks.filter((task) => task.type !== "epic" && stateOf(task) === column.key) })).filter((column) => column.tasks.length || ["blocked", "ready", "progress"].includes(column.key));\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { horizontal: true, contentContainerStyle: styles.board, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.column, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.columnHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task: { status: column.key === "closed" ? "closed" : column.key === "review" ? "review" : column.key === "progress" ? "in_progress" : "open", ready: column.key === "ready", approvals: column.key === "approve" ? [{ gate: "", note: "" }] : void 0 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.columnTitle, children: column.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.groupCount, children: column.tasks.length })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.ScrollView, { contentContainerStyle: styles.columnBody, children: [\n column.tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${task.id}`, onPress: () => onOpen(task.id), style: (state) => [styles.card, hovered(state) ? styles.cardHover : null, column.key === "blocked" ? styles.cardBlocked : column.key === "ready" ? styles.cardReady : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 12, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: { flex: 1 } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.age, children: age(task.updatedAt) })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.cardTitle, numberOfLines: 3, children: task.title }),\n task.assignee ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.assignee, numberOfLines: 1, children: [\n "@",\n task.assignee\n ] }) : null,\n task.blockedBy?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.blocked, numberOfLines: 1, children: [\n "after ",\n task.blockedBy.join(", ")\n ] }) : null,\n task.labels?.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.cardLabels, children: task.labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label)) }) : null\n ] }, task.id)),\n !column.tasks.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: [styles.small, styles.pad], children: "Nothing here" }) : null\n ] })\n ] }, column.key)) });\n}\nfunction EpicsView({ theme, styles, tasks, shown, onOpen }) {\n const epics = shown.filter((task) => task.type === "epic" || task.progress);\n const [opened, setOpened] = (0, import_react.useState)({});\n if (!epics.length) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Empty, { styles, text: "No epics here. An epic is a task other tasks name as their parent." });\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.ScrollView, { contentContainerStyle: styles.listContent, children: epics.map((epic) => {\n const children = tasks.filter((task) => task.parent === epic.id);\n const done = epic.progress?.done ?? 0;\n const total = epic.progress?.total ?? 0;\n const expanded = opened[epic.id] ?? epic.status !== "closed";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.epic, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${epic.id}`, onPress: () => onOpen(epic.id), style: styles.lineTop, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task: epic }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: "Target", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: epic.priority }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: epic.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.lineTitle, numberOfLines: 1, children: epic.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.progressText, children: [\n done,\n "/",\n total\n ] })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.progressTrack, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: [styles.progressFill, { width: `${total ? Math.round(done / total * 100) : 0}%` }] }) }),\n children.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `${expanded ? "Hide" : "Show"} the tasks of ${epic.id}`, onPress: () => setOpened((current) => ({ ...current, [epic.id]: !expanded })), style: styles.treeToggle, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: expanded ? "ChevronDown" : "ChevronRight", size: 12, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.small, children: [\n children.length,\n " ",\n children.length === 1 ? "task" : "tasks"\n ] })\n ] }) : null,\n expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.tree, children: children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task: child, selected: false, onOpen }, child.id)) }) : null\n ] }, epic.id);\n }) });\n}\nfunction SmallButton({ styles, label, onPress, primary, danger }) {\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", onPress, style: [styles.smallButton, primary ? styles.smallButtonPrimary : null, danger ? styles.smallButtonDanger : null], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: primary ? styles.smallButtonTextPrimary : danger ? styles.smallButtonTextDanger : styles.smallButtonText, children: label }) });\n}\nfunction TaskDetail({ theme, styles, task, tasks, onBack, onOpen, onAction }) {\n const state = stateOf(task);\n const children = tasks.filter((entry) => entry.parent === task.id);\n const blocks = tasks.filter((entry) => entry.blockedBy?.includes(task.id) && entry.status !== "closed");\n const field = (label, value) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.field, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.fieldLabel, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.fieldValue, children: typeof value === "string" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: value }) : value })\n ] });\n const link = (id) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { accessibilityRole: "link", accessibilityLabel: `Open ${id}`, onPress: () => onOpen(id), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.link, children: id }) }, id);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.ScrollView, { contentContainerStyle: styles.detail, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.detailHeader, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconButton, { theme, icon: "ArrowLeft", label: "Back to the list", onPress: onBack }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.id, children: task.id }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.statePill, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateDot, { theme, task }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.small, children: STATE_LABELS[state] })\n ] })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.detailTitle, children: task.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.fields, children: [\n field("Type", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.inline, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Icon, { name: TYPE_ICONS[task.type] ?? "SquareCheck", size: 13, color: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.type })\n ] })),\n field("Priority", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Priority, { theme, value: task.priority })),\n task.assignee ? field("Assignee", `@${task.assignee}`) : null,\n task.parent ? field("Parent", link(task.parent)) : null,\n task.blockedBy?.length ? field("Blocked by", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: task.blockedBy.map(link) })) : null,\n blocks.length ? field("Blocks", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: blocks.map((entry) => link(entry.id)) })) : null,\n task.waits?.length ? field("Waits on", task.waits.join("; ")) : null,\n task.labels?.length ? field("Labels", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: styles.inline, children: task.labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.label, children: [\n "#",\n label\n ] }, label)) })) : null,\n task.paths?.length ? field("Paths", task.paths.join(", ")) : null,\n task.progress ? field("Progress", `${task.progress.done} of ${task.progress.total} closed`) : null,\n task.createdAt ? field("Created", `${age(task.createdAt)} ago`) : null,\n field("Updated", `${age(task.updatedAt)} ago`)\n ] }),\n task.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.boxTitle, children: "Description" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.description })\n ] }) : null,\n task.handoff ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Handoff \\xB7 ",\n task.handoff.outcome,\n task.handoff.agent ? ` from ${task.handoff.agent}` : ""\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.handoff.summary })\n ] }) : null,\n task.closed ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Closed \\xB7 ",\n task.closed.reason\n ] }),\n task.closed.summary ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: styles.text, children: task.closed.summary }) : null\n ] }) : null,\n children.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.box, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.Text, { style: styles.boxTitle, children: [\n "Tasks \\xB7 ",\n children.filter((child) => child.status === "closed").length,\n "/",\n children.length,\n " closed"\n ] }),\n children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TaskLine, { theme, styles, task: child, selected: false, onOpen }, child.id))\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: styles.detailActions, children: [\n (task.approvals ?? []).map((approval) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, primary: true, label: `Approve${approval.note ? `: ${approval.note.slice(0, 40)}` : ""}`, onPress: () => onAction({ id: task.id, action: "approve", gate: approval.gate }) }, approval.gate)),\n state === "review" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, primary: true, label: "Accept and close", onPress: () => onAction({ id: task.id, action: "close" }) }) : null,\n task.status !== "closed" && state !== "review" && task.type !== "epic" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Close", onPress: () => onAction({ id: task.id, action: "close" }) }) : null,\n task.status === "closed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SmallButton, { styles, label: "Reopen", onPress: () => onAction({ id: task.id, action: "reopen" }) }) : null\n ] })\n ] });\n}\nfunction makeStyles(theme, compact) {\n const { colors } = theme;\n const mono = { fontFamily: "monospace", fontVariant: ["tabular-nums"] };\n return {\n screen: { flex: 1, backgroundColor: colors.surface0 },\n pad: { paddingHorizontal: compact ? 12 : 16, paddingVertical: 8 },\n toolbar: { paddingHorizontal: compact ? 12 : 16, paddingTop: 12, paddingBottom: 10, gap: 10, borderBottomWidth: 1, borderBottomColor: colors.border },\n toolbarRow: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },\n title: { color: colors.foreground, fontSize: 15, fontWeight: "600" },\n count: { color: colors.foregroundMuted, fontSize: 12, marginLeft: 4 },\n segmented: { flexDirection: "row", backgroundColor: colors.surface1, borderRadius: 8, borderWidth: 1, borderColor: colors.border, padding: 2 },\n segment: { flexDirection: "row", alignItems: "center", gap: 5, paddingHorizontal: 8, paddingVertical: 4, borderRadius: 6 },\n segmentOn: { backgroundColor: colors.surface0, shadowColor: "#000", shadowOpacity: 0.08, shadowRadius: 2 },\n segmentText: { color: colors.foregroundMuted, fontSize: 12 },\n segmentTextOn: { color: colors.foreground, fontSize: 12, fontWeight: "600" },\n filter: { paddingHorizontal: 9, paddingVertical: 4, borderRadius: 999, borderWidth: 1, borderColor: colors.border },\n filterOn: { backgroundColor: colors.foreground, borderColor: colors.foreground },\n filterText: { color: colors.foreground, fontSize: 12 },\n filterTextOn: { color: colors.surface0, fontSize: 12, fontWeight: "600" },\n filterCount: { opacity: 0.6, fontSize: 11 },\n search: { flex: 1, minWidth: 160, flexDirection: "row", alignItems: "center", gap: 6, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 8, backgroundColor: colors.surface1 },\n searchInput: { flex: 1, minWidth: 0, color: colors.foreground, fontSize: 12.5, paddingVertical: 6 },\n composer: { flexDirection: compact ? "column" : "row", gap: 8, alignItems: compact ? "stretch" : "center" },\n input: { flex: compact ? void 0 : 1, minWidth: 0, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 7, backgroundColor: colors.surface1 },\n priorities: { flexDirection: "row", gap: 4 },\n chip: { paddingHorizontal: 7, paddingVertical: 5, borderRadius: 6, borderWidth: 1, borderColor: colors.border },\n chipOn: { backgroundColor: colors.accent, borderColor: colors.accent },\n chipText: { color: colors.foregroundMuted, fontSize: 12 },\n chipTextOn: { color: colors.accentForeground, fontSize: 12 },\n button: { paddingHorizontal: 12, paddingVertical: 7, borderRadius: 8, backgroundColor: colors.accent },\n buttonText: { color: colors.accentForeground, fontWeight: "600" },\n body: { flex: 1, flexDirection: "row" },\n pane: { flex: 1, minWidth: 0 },\n paneList: { flex: 2, borderRightWidth: 1, borderRightColor: colors.border },\n paneDetail: { flex: 3 },\n empty: { margin: 16, borderWidth: 1, borderStyle: "dashed", borderColor: colors.border, borderRadius: 10, padding: 24, alignItems: "center" },\n listContent: { paddingVertical: 6 },\n group: { marginBottom: 4 },\n groupHeader: { flexDirection: "row", alignItems: "center", gap: 6, paddingHorizontal: compact ? 10 : 14, paddingVertical: 7 },\n groupTitle: { color: colors.foregroundMuted, fontSize: 11.5, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.4 },\n groupCount: { color: colors.foregroundMuted, fontSize: 11, opacity: 0.8 },\n line: { paddingHorizontal: compact ? 10 : 14, paddingVertical: 7, gap: 3, borderLeftWidth: 2, borderLeftColor: "transparent" },\n lineOn: { backgroundColor: colors.surface2, borderLeftColor: colors.accent },\n lineHover: { backgroundColor: colors.surface1 },\n lineTop: { flexDirection: "row", alignItems: "center", gap: 7 },\n lineTitle: { flex: 1, minWidth: 0, color: colors.foreground, fontSize: 13 },\n lineMeta: { flexDirection: "row", flexWrap: "wrap", gap: 6, paddingLeft: 16 },\n id: { color: colors.foregroundMuted, fontSize: 11.5, ...mono },\n age: { color: colors.foregroundMuted, fontSize: 11, ...mono },\n assignee: { color: colors.accent, fontSize: 11.5, maxWidth: 110 },\n label: { color: colors.foregroundMuted, fontSize: 11, backgroundColor: colors.surface2, borderRadius: 4, paddingHorizontal: 5, paddingVertical: 1 },\n inlineAction: { flexDirection: "row", alignItems: "center", gap: 10, paddingLeft: compact ? 26 : 30, paddingRight: 14, paddingBottom: 8 },\n board: { padding: 12, gap: 10, alignItems: "flex-start" },\n column: { width: 248, backgroundColor: colors.surface1, borderRadius: 10, borderWidth: 1, borderColor: colors.border, maxHeight: 640 },\n columnHeader: { flexDirection: "row", alignItems: "center", gap: 7, paddingHorizontal: 12, paddingVertical: 10, borderBottomWidth: 1, borderBottomColor: colors.border },\n columnTitle: { flex: 1, color: colors.foreground, fontSize: 12.5, fontWeight: "600" },\n columnBody: { padding: 8, gap: 8 },\n card: { backgroundColor: colors.surface0, borderRadius: 8, borderWidth: 1, borderColor: colors.border, borderLeftWidth: 3, padding: 10, gap: 5 },\n cardHover: { borderColor: colors.foregroundMuted },\n cardBlocked: { borderLeftColor: colors.statusDanger },\n cardReady: { borderLeftColor: colors.statusSuccess },\n cardLabels: { flexDirection: "row", flexWrap: "wrap", gap: 6 },\n blocked: { color: colors.statusDanger, fontSize: 11.5 },\n cardTitle: { color: colors.foreground, fontSize: 13, lineHeight: 18 },\n epic: { marginHorizontal: compact ? 10 : 14, marginVertical: 6, padding: 12, borderRadius: 10, borderWidth: 1, borderColor: colors.border, backgroundColor: colors.surface1, gap: 8 },\n progressTrack: { height: 6, borderRadius: 3, backgroundColor: colors.surface2, overflow: "hidden" },\n progressFill: { height: 6, borderRadius: 3, backgroundColor: colors.statusSuccess },\n progressText: { color: colors.foregroundMuted, fontSize: 11.5, ...mono },\n treeToggle: { flexDirection: "row", alignItems: "center", gap: 4 },\n tree: { marginLeft: 6, borderLeftWidth: 1, borderLeftColor: colors.border, backgroundColor: colors.surface0, borderRadius: 6 },\n detail: { padding: compact ? 12 : 18, gap: 14 },\n detailHeader: { flexDirection: "row", alignItems: "center", gap: 8 },\n statePill: { flexDirection: "row", alignItems: "center", gap: 6, borderWidth: 1, borderColor: colors.border, borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },\n detailTitle: { color: colors.foreground, fontSize: 17, fontWeight: "600", lineHeight: 23 },\n fields: { borderWidth: 1, borderColor: colors.border, borderRadius: 10, overflow: "hidden" },\n field: { flexDirection: "row", alignItems: "center", gap: 12, paddingHorizontal: 12, paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: colors.border },\n fieldLabel: { width: 84, color: colors.foregroundMuted, fontSize: 12 },\n fieldValue: { flex: 1, minWidth: 0 },\n inline: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },\n box: { borderRadius: 10, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, padding: 12, gap: 6 },\n boxTitle: { color: colors.foregroundMuted, fontSize: 11.5, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.4 },\n detailActions: { flexDirection: "row", gap: 8, flexWrap: "wrap" },\n smallButton: { paddingHorizontal: 10, paddingVertical: 6, borderRadius: 7, borderWidth: 1, borderColor: colors.border, backgroundColor: colors.surface1 },\n smallButtonPrimary: { backgroundColor: colors.accent, borderColor: colors.accent },\n smallButtonDanger: { borderColor: colors.statusDanger },\n smallButtonText: { color: colors.foreground, fontSize: 12.5, fontWeight: "500" },\n smallButtonTextPrimary: { color: colors.accentForeground, fontSize: 12.5, fontWeight: "600" },\n smallButtonTextDanger: { color: colors.statusDanger, fontSize: 12.5 },\n text: { color: colors.foreground, fontSize: 13, lineHeight: 19 },\n small: { color: colors.foregroundMuted, fontSize: 12 },\n muted: { color: colors.foregroundMuted, fontSize: 13 },\n danger: { color: colors.statusDanger, fontSize: 13 },\n warning: { color: colors.statusWarning, fontSize: 12 },\n link: { color: colors.accent, fontSize: 13, ...mono }\n };\n}\n\n// integrations/paseo/client/task-pills.ts\nvar TASKS_SCREEN = "alp-tasks";\nvar POLL_MS2 = 2e4;\nvar MENU_LIMIT = 8;\nvar PAGE = 200;\nfunction tasksScreen(workspaceId, directory, taskId) {\n return { screenId: TASKS_SCREEN, params: { workspaceId, directory, ...taskId ? { taskId } : {} } };\n}\nvar ORDER = ["approve", "review", "progress", "ready", "blocked"];\nvar STATES = {\n approve: { label: "Approve", icon: "Hand" },\n review: { label: "Review", icon: "Eye" },\n progress: { label: "In progress", icon: "LoaderCircle" },\n ready: { label: "Ready", icon: "CircleCheck" },\n blocked: { label: "Blocked", icon: "CircleSlash" },\n closed: { label: "Done", icon: "CheckCheck" }\n};\nfunction sessionWork(board, sessions = []) {\n const ids = sessions.map((id) => board?.sessions?.[id]).find(Boolean) ?? [];\n const index = new Map((board?.tasks ?? []).map((task) => [task.id, task]));\n return ids.flatMap((id) => index.has(id) ? [{ task: index.get(id), state: stateOf(index.get(id)) }] : []);\n}\nfunction menuTasks(tasks) {\n return tasks.filter((task) => task.status !== "closed" && task.type !== "epic").map((task) => ({ task, state: stateOf(task) })).sort((a, b) => ORDER.indexOf(a.state) - ORDER.indexOf(b.state) || a.task.priority - b.task.priority || a.task.id.localeCompare(b.task.id));\n}\nfunction taskButton(board, open, sessions = []) {\n const listed = board ? menuTasks(board.tasks) : [];\n const worked = sessionWork(board, sessions);\n const done = worked.filter((entry2) => entry2.state === "closed").length;\n const mine = new Set(worked.map((entry2) => entry2.task.id));\n const shown = [...worked, ...listed.filter((entry2) => !mine.has(entry2.task.id))];\n const entry = ({ task, state }, index) => ({\n kind: "item",\n id: `task-${index}`,\n title: `${STATES[state].label} \\xB7 ${task.title}`,\n icon: STATES[state].icon,\n behavior: { kind: "action", onPress: () => open(task.id) }\n });\n const items = shown.slice(0, MENU_LIMIT).map(entry);\n if (worked.length && items.length > worked.length) items.splice(worked.length, 0, { kind: "separator", id: "session-end" });\n if (items.length) items.push({ kind: "separator", id: "tasks-end" });\n const more = shown.length - MENU_LIMIT;\n items.push({ kind: "item", id: "all-tasks", title: more > 0 ? `All tasks (${more} more)` : "All tasks", icon: "ListTodo", behavior: { kind: "action", onPress: () => open() } });\n return {\n title: worked.length ? `ALP tasks: ${done} of ${worked.length} done in this session, ${listed.length} open` : listed.length ? `ALP tasks: ${listed.length} open` : "ALP tasks",\n icon: "ListTodo",\n label: worked.length ? `Tasks \\xB7 ${done}/${worked.length}` : listed.length ? `Tasks \\xB7 ${listed.length}` : "Tasks",\n visible: board?.projectRoot !== null,\n behavior: { kind: "menu", items }\n };\n}\nfunction signature(board, sessions) {\n return JSON.stringify(board && [board.projectRoot !== null, [...sessionWork(board, sessions), ...menuTasks(board.tasks)].map(({ task, state }) => [task.id, state, task.title])]);\n}\nfunction addTaskPills(client) {\n const agents = /* @__PURE__ */ new Map();\n const directories = /* @__PURE__ */ new Map();\n const boards = /* @__PURE__ */ new Map();\n const pills = /* @__PURE__ */ new Map();\n let subscription = null;\n let stopped = false;\n let retry;\n let polling = false;\n let again = false;\n const opener = (agent, directory) => (taskId) => client.openScreen(tasksScreen(agent.workspaceId, directory, taskId));\n const directoryOf = (agent) => {\n let found = directories.get(agent.workspaceId);\n if (!found) {\n found = client.paseo.workspaces.ref(agent.workspaceId).refresh().then((workspace) => workspace?.workspaceDirectory || workspace?.projectRootPath || agent.cwd).catch(() => {\n directories.delete(agent.workspaceId);\n return agent.cwd;\n });\n directories.set(agent.workspaceId, found);\n }\n return found;\n };\n const show = (agent) => __async(null, null, function* () {\n const directory = yield directoryOf(agent);\n if (stopped || pills.has(agent.id) || agents.get(agent.id) !== agent) return;\n const board = boards.get(directory) ?? null;\n try {\n const registration = client.addComposerPill({ id: "alp-tasks", workspaceId: agent.workspaceId, agentId: agent.id, button: taskButton(board, opener(agent, directory), agent.sessions) });\n pills.set(agent.id, { agent, directory, registration, signature: signature(board, agent.sessions) });\n } catch {\n return;\n }\n if (!board) void poll();\n });\n const hide = (id) => {\n agents.delete(id);\n pills.get(id)?.registration.remove();\n pills.delete(id);\n };\n const accept = (snapshot) => {\n const known = agents.get(snapshot.id);\n if (snapshot.provider !== "alp" || !snapshot.workspaceId || snapshot.archivedAt) {\n if (known) hide(snapshot.id);\n return;\n }\n const sessions = [snapshot.persistence?.sessionId, snapshot.id].filter((id) => Boolean(id));\n if (known?.workspaceId === snapshot.workspaceId && known.sessions.join() === sessions.join()) return;\n if (known) hide(snapshot.id);\n const agent = { id: snapshot.id, workspaceId: snapshot.workspaceId, cwd: snapshot.cwd, sessions };\n agents.set(agent.id, agent);\n void show(agent);\n };\n const load = (page) => __async(null, null, function* () {\n const seen = /* @__PURE__ */ new Set();\n for (let current = page; ; ) {\n for (const { agent } of current.entries) {\n seen.add(agent.id);\n accept(agent);\n }\n const cursor = current.pageInfo.nextCursor;\n if (!current.pageInfo.hasMore || !cursor || stopped) break;\n current = yield client.paseo.agents.list({ scope: "active", page: { limit: PAGE, cursor } });\n }\n for (const id of [...agents.keys()]) if (!seen.has(id)) hide(id);\n });\n const watch = () => __async(null, null, function* () {\n try {\n const first = yield client.paseo.agents.list({ scope: "active", page: { limit: PAGE }, subscribe: {} });\n if (stopped) {\n void first.subscription.release().catch(() => {\n });\n return;\n }\n subscription = first.subscription;\n first.subscription.subscribe({\n snapshot: (snapshot) => {\n void load(snapshot).catch(() => {\n });\n },\n update: (message2) => {\n if (message2.type !== "agent_update") return;\n if (message2.payload.kind === "remove") hide(message2.payload.agentId);\n else accept(message2.payload.agent);\n }\n });\n } catch {\n if (!stopped) retry = setTimeout(() => void watch(), POLL_MS2);\n }\n });\n const poll = () => __async(null, null, function* () {\n if (polling) {\n again = true;\n return;\n }\n polling = true;\n try {\n const shown = new Set([...pills.values()].map((pill) => pill.directory));\n for (const directory of shown) {\n if (stopped) return;\n try {\n boards.set(directory, yield client.rpc(tasksList, { directory }));\n } catch {\n continue;\n }\n for (const pill of pills.values()) if (pill.directory === directory) render(pill);\n }\n for (const directory of [...boards.keys()]) if (!shown.has(directory)) boards.delete(directory);\n } finally {\n polling = false;\n if (again && !stopped) {\n again = false;\n void poll();\n }\n }\n });\n const render = (pill) => {\n const board = boards.get(pill.directory) ?? null;\n const next = signature(board, pill.agent.sessions);\n if (next === pill.signature) return;\n pill.signature = next;\n pill.registration.update(taskButton(board, opener(pill.agent, pill.directory), pill.agent.sessions));\n };\n const timer = setInterval(() => void poll(), POLL_MS2);\n void watch();\n return () => {\n stopped = true;\n clearInterval(timer);\n if (retry !== void 0) clearTimeout(retry);\n for (const id of [...pills.keys()]) hide(id);\n void subscription?.release().catch(() => {\n });\n };\n}\n\n// integrations/paseo/client/team-model-settings.tsx\nvar import_react3 = require("react");\nvar import_react_native5 = require("react-native");\nvar import_client2 = require("@getpaseo/plugin/client");\nvar import_ui = require("@getpaseo/plugin/client/ui");\n\n// integrations/paseo/shared/library.ts\nvar import_plugin2 = require("@getpaseo/plugin");\nvar import_zod2 = require("zod");\nvar Directory2 = import_zod2.z.string().min(1).optional();\nvar KindSchema = import_zod2.z.enum(["agents", "skills", "mcp", "hooks", "teams", "providers"]);\nvar ScopeSchema = import_zod2.z.enum(["library", "project"]);\nvar Name = import_zod2.z.string().regex(/^[\\w.-]+$/).refine((name) => name !== "." && name !== "..");\nvar Source = import_zod2.z.enum(["builtin", "library", "project"]);\nvar EntryRowSchema = import_zod2.z.object({\n name: import_zod2.z.string(),\n source: Source,\n overrides: Source.optional(),\n path: import_zod2.z.string().optional(),\n description: import_zod2.z.string().optional(),\n usedBy: import_zod2.z.array(import_zod2.z.string()).optional()\n});\nvar libraryList = (0, import_plugin2.defineRpc)({\n name: "alp.library.list",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema }),\n output: import_zod2.z.object({\n projectRoot: import_zod2.z.string().nullable(),\n library: import_zod2.z.string(),\n entries: import_zod2.z.array(EntryRowSchema),\n /**\n * Set when the library can only be looked at from here (ALP remote mode): why, and where to\n * change it. `unlisted` says why there are no entries at all (no granted workspace open).\n */\n readOnly: import_zod2.z.object({ reason: import_zod2.z.string(), unlisted: import_zod2.z.string().optional() }).optional()\n })\n});\nvar libraryGet = (0, import_plugin2.defineRpc)({\n name: "alp.library.get",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, name: Name, scope: ScopeSchema.optional() }),\n output: import_zod2.z.object({\n kind: KindSchema,\n name: import_zod2.z.string(),\n source: Source,\n overrides: Source.optional(),\n content: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),\n /** Pass back with a save or delete; a different current revision refuses it. */\n revision: import_zod2.z.string().nullable(),\n usedBy: import_zod2.z.array(import_zod2.z.string()),\n /** Agents: the skills the library gives it by name (role-skills.json). */\n librarySkills: import_zod2.z.array(import_zod2.z.string()).optional(),\n /** ALP remote mode: JSON Pointers of the values `content` holds as a secret marker, not as the value. */\n secrets: import_zod2.z.array(import_zod2.z.string()).optional()\n })\n});\nvar librarySkills = (0, import_plugin2.defineRpc)({\n name: "alp.library.skills",\n input: import_zod2.z.object({ agent: Name, skills: import_zod2.z.array(Name) }),\n output: import_zod2.z.object({ skills: import_zod2.z.array(import_zod2.z.string()) })\n});\nvar librarySave = (0, import_plugin2.defineRpc)({\n name: "alp.library.save",\n input: import_zod2.z.object({\n directory: Directory2,\n kind: KindSchema,\n name: Name,\n scope: ScopeSchema,\n content: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()),\n /** null creates; a string replaces that revision; omitted overwrites. */\n revision: import_zod2.z.string().nullable().optional()\n }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable(), syncedProjects: import_zod2.z.number().int().nonnegative().optional(), syncErrors: import_zod2.z.array(import_zod2.z.string()).optional() })\n});\nvar libraryDelete = (0, import_plugin2.defineRpc)({\n name: "alp.library.delete",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, name: Name, scope: ScopeSchema, revision: import_zod2.z.string().optional() }),\n /** now: the layer that applies again after removing an override. */\n output: import_zod2.z.object({ removed: import_zod2.z.boolean(), now: Source.optional() })\n});\nvar libraryDuplicate = (0, import_plugin2.defineRpc)({\n name: "alp.library.duplicate",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, from: Name, to: Name, scope: ScopeSchema }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable() })\n});\nvar libraryRename = (0, import_plugin2.defineRpc)({\n name: "alp.library.rename",\n input: import_zod2.z.object({ directory: Directory2, kind: KindSchema, from: Name, to: Name, scope: ScopeSchema }),\n output: import_zod2.z.object({ revision: import_zod2.z.string().nullable() })\n});\nvar libraryTest = (0, import_plugin2.defineRpc)({\n name: "alp.library.test",\n input: import_zod2.z.object({ directory: Directory2, kind: import_zod2.z.enum(["mcp", "hooks", "providers"]), name: Name, scope: ScopeSchema.optional() }),\n output: import_zod2.z.object({\n ok: import_zod2.z.boolean(),\n /** MCP: the server and its tools. */\n server: import_zod2.z.object({ name: import_zod2.z.string().optional(), version: import_zod2.z.string().optional() }).optional(),\n tools: import_zod2.z.array(import_zod2.z.object({ name: import_zod2.z.string(), description: import_zod2.z.string().optional() })).optional(),\n /** Hooks: how the sample run went. */\n exitCode: import_zod2.z.number().nullable().optional(),\n signal: import_zod2.z.string().nullable().optional(),\n timedOut: import_zod2.z.boolean().optional(),\n wouldBlock: import_zod2.z.boolean().optional(),\n stdout: import_zod2.z.string().optional(),\n stderr: import_zod2.z.string().optional(),\n durationMs: import_zod2.z.number().optional(),\n /** Providers: who the ACP agent says it is, and what it supports. */\n protocolVersion: import_zod2.z.number().optional(),\n agent: import_zod2.z.object({ name: import_zod2.z.string().optional(), title: import_zod2.z.string().optional(), version: import_zod2.z.string().optional() }).optional(),\n loadSession: import_zod2.z.boolean().optional(),\n mcpHttp: import_zod2.z.boolean().optional(),\n authMethods: import_zod2.z.array(import_zod2.z.string()).optional()\n })\n});\nvar LanguageSettingSchema = import_zod2.z.object({\n language: import_zod2.z.string().nullable(),\n applies: import_zod2.z.string(),\n default: import_zod2.z.string(),\n /** Why it cannot be changed from here (ALP remote mode). */\n readOnly: import_zod2.z.string().optional()\n});\nvar languageGet = (0, import_plugin2.defineRpc)({\n name: "alp.settings.language.get",\n input: import_zod2.z.object({}),\n output: LanguageSettingSchema\n});\nvar languageSet = (0, import_plugin2.defineRpc)({\n name: "alp.settings.language.set",\n input: import_zod2.z.object({ language: import_zod2.z.string().trim().min(1).max(40).nullable() }),\n output: LanguageSettingSchema\n});\nvar libraryModels = (0, import_plugin2.defineRpc)({\n name: "alp.library.models",\n input: import_zod2.z.object({}),\n output: import_zod2.z.object({ models: import_zod2.z.array(import_zod2.z.object({ id: import_zod2.z.string(), label: import_zod2.z.string(), efforts: import_zod2.z.array(import_zod2.z.string()), effort: import_zod2.z.string().optional() })) })\n});\n\n// integrations/paseo/shared/team-models.ts\nvar MODEL_PRESETS = [\n { label: "Claude only", value: "claude" },\n { label: "Codex only", value: "codex" },\n { label: "OpenCode only", value: "opencode" },\n { label: "Antigravity only", value: "antigravity" },\n { label: "Mix \\xB7 Claude + Codex", value: "mix" }\n];\nfunction presetTeamModels(team, preset, models) {\n const next = JSON.parse(JSON.stringify(team));\n const find = (provider) => models.find((model) => provider === "opencode" ? model.id === "acp:opencode" || model.id.startsWith("acp:opencode/") : model.id.startsWith(`${provider}:`));\n const primary = find(preset === "mix" ? "claude" : preset);\n const secondary = preset === "mix" ? find("codex") : primary;\n if (!primary || !secondary) throw new Error("No models available for this preset. Configure the provider in Settings first.");\n const assign = (target, model) => {\n target.model = model.id;\n if (model.effort) target.thinking = model.effort;\n else delete target.thinking;\n };\n for (const [name, member] of Object.entries(next.members ?? {})) {\n if (name !== "oracle") assign(member, name === next.main ? primary : secondary);\n }\n if (next.supervisor) assign(next.supervisor, secondary);\n if (next.members?.oracle) {\n next.oracleModels = [.../* @__PURE__ */ new Set([primary.id, secondary.id])];\n next.oracleThinking = Object.fromEntries([primary, secondary].filter((model) => model.effort).map((model) => [model.id, model.effort]));\n }\n next.modelSetup = { mode: "default", preset };\n return next;\n}\nfunction modelSetupFor(team, models) {\n if (team.modelSetup) return team.modelSetup;\n for (const { value } of MODEL_PRESETS) {\n let expected;\n try {\n expected = presetTeamModels(team, value, models);\n } catch {\n continue;\n }\n const same = (a, b) => a.model === b.model && a.thinking === b.thinking;\n if (!Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").every(([name, member]) => same(member, expected.members[name]))) continue;\n if (team.supervisor && !same(team.supervisor, expected.supervisor)) continue;\n if (team.members?.oracle && (JSON.stringify(team.oracleModels) !== JSON.stringify(expected.oracleModels) || expected.oracleModels.some((id) => (team.oracleThinking?.[id] ?? team.oracleThinking?.[id.split(":")[0]]) !== expected.oracleThinking?.[id]))) continue;\n return { mode: "default", preset: value };\n }\n return { mode: "custom" };\n}\n\n// integrations/paseo/client/side-nav.tsx\nvar import_react_native3 = require("@getpaseo/plugin/client/react-native");\nvar import_react2 = require("react");\nvar import_react_native4 = require("react-native");\nvar import_jsx_runtime2 = require("react/jsx-runtime");\nvar hovered2 = (state) => !!state.hovered;\nvar COLLAPSE_BELOW = 640;\nvar EXPANDED = 216;\nvar COLLAPSED = 52;\nfunction SideNavLayout(props) {\n const { theme, compact, groups, active, onSelect } = props;\n const styles = (0, import_react2.useMemo)(() => layoutStyles(theme), [theme]);\n const [width, setWidth] = (0, import_react2.useState)(0);\n const [choice, setChoice] = (0, import_react2.useState)(props.initialCollapsed);\n const [open, setOpen] = (0, import_react2.useState)(false);\n const collapsed = choice ?? (width > 0 && width < COLLAPSE_BELOW);\n const select = (item, child) => {\n onSelect(item, child);\n setOpen(false);\n };\n const aside = (mode) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(\n Aside,\n {\n styles,\n theme,\n title: props.title,\n subtitle: props.subtitle,\n groups,\n active,\n onSelect: select,\n collapsed: mode === "fixed" && collapsed,\n onToggle: mode === "fixed" ? () => setChoice(!collapsed) : () => setOpen(false),\n overlay: mode === "overlay"\n }\n );\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: props.embedded ? { width: "100%" } : styles.root, onLayout: (event) => setWidth(event.nativeEvent.layout.width), children: [\n !props.embedded && !compact ? aside("fixed") : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: props.embedded ? { minWidth: 0 } : styles.main, children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.header, props.embedded ? { paddingHorizontal: 0, paddingTop: 0 } : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.headerRow, children: [\n compact && !props.embedded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: "Open navigation", onPress: () => setOpen(true), style: styles.iconButton, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: "Menu", size: 18, color: theme.colors.foreground }) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.crumbs, children: [\n props.breadcrumb.map((part, index) => [\n index ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.crumbSeparator, children: "/" }, `separator-${index}`) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: index === props.breadcrumb.length - 1 ? styles.crumbCurrent : styles.crumb, numberOfLines: 1, children: part }, `${index}-${part}`)\n ]),\n props.badges\n ] }),\n props.actions ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.actions, children: props.actions }) : null\n ] }),\n props.tabs?.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: styles.tabs, children: props.tabs.map((tab) => {\n const on = tab.key === props.tab;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "tab", accessibilityLabel: tab.label, accessibilityState: { selected: on }, onPress: () => props.onTab?.(tab.key), style: [styles.tab, on ? styles.tabOn : null], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.Text, { style: on ? styles.tabTextOn : styles.tabText, children: [\n tab.label,\n tab.count !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.tabCount, children: ` ${tab.count}` }) : null\n ] }) }, tab.key);\n }) }) : null\n ] }),\n props.embedded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.bodyContent, { paddingHorizontal: 0 }], children: props.children }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { style: styles.body, contentContainerStyle: styles.bodyContent, children: props.children }),\n props.footer ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.footer, props.embedded ? { paddingHorizontal: 0 } : null], children: props.footer }) : null\n ] }),\n !props.embedded && compact && open ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.overlay, children: [\n aside("overlay"),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: "Close navigation", onPress: () => setOpen(false), style: styles.scrim })\n ] }) : null\n ] });\n}\nfunction Aside({ styles, theme, title, subtitle, groups, active, onSelect, collapsed, onToggle, overlay }) {\n const { colors } = theme;\n const [opened, setOpened] = (0, import_react2.useState)({});\n const tone = (value) => value === "accent" ? colors.accent : value === "warning" ? colors.statusWarning : colors.border;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.aside, { width: collapsed ? COLLAPSED : EXPANDED }, overlay ? styles.asideOverlay : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: [styles.asideHeader, collapsed ? styles.asideHeaderCollapsed : null], children: [\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.asideTitleBox, children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.asideTitle, numberOfLines: 1, children: title }),\n subtitle ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.asideSubtitle, numberOfLines: 1, children: subtitle }) : null\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: overlay ? "Close navigation" : collapsed ? "Expand navigation" : "Collapse navigation", onPress: onToggle, style: styles.iconButton, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: overlay ? "X" : collapsed ? "PanelLeftOpen" : "PanelLeftClose", size: 16, color: colors.foregroundMuted }) })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.ScrollView, { contentContainerStyle: styles.asideList, children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles.group, children: [\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.groupLabel, children: group.label }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.groupRule }),\n group.items.map((item) => {\n const selected = active.item === item.key;\n const expanded = !collapsed && (opened[item.key] ?? selected) && !!item.children?.length;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: item.label,\n accessibilityState: { selected: selected && !active.child },\n onPress: () => {\n onSelect(item.key);\n setOpened((current) => ({ ...current, [item.key]: true }));\n },\n style: (state) => [styles.item, collapsed ? styles.itemCollapsed : null, selected ? styles.itemOn : hovered2(state) ? styles.itemHover : null],\n children: [\n selected ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.itemBar }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: item.icon, size: 16, color: selected ? colors.accent : colors.foregroundMuted }),\n !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles.itemLabel, selected ? styles.itemLabelOn : null], numberOfLines: 1, children: item.label }) : null,\n !collapsed && item.count !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.count, children: item.count }) : null,\n !collapsed && item.children?.length ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Pressable, { accessibilityRole: "button", accessibilityLabel: `${expanded ? "Hide" : "Show"} ${item.label}`, hitSlop: 8, onPress: () => setOpened((current) => ({ ...current, [item.key]: !expanded })), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: expanded ? "ChevronDown" : "ChevronRight", size: 14, color: colors.foregroundMuted }) }) : null\n ]\n }\n ),\n expanded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles.children, children: item.children.map((child) => {\n const on = selected && active.child === child.key;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: `${item.label} ${child.label}`,\n accessibilityState: { selected: on },\n onPress: () => onSelect(item.key, child.key),\n style: (state) => [styles.child, on ? styles.childOn : hovered2(state) ? styles.itemHover : null],\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: [styles.dot, { backgroundColor: tone(child.tone) }] }),\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles.childLabel, on ? styles.itemLabelOn : null], numberOfLines: 1, children: child.label }),\n child.hint ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles.childHint, numberOfLines: 1, children: child.hint }) : null\n ]\n },\n child.key\n );\n }) }) : null\n ] }, item.key);\n })\n ] }, group.key)) })\n ] });\n}\nfunction Pill({ theme, label, tone = "muted" }) {\n const { colors } = theme;\n const color = tone === "accent" ? colors.accent : tone === "success" ? colors.statusSuccess : tone === "warning" ? colors.statusWarning : tone === "danger" ? colors.statusDanger : colors.foregroundMuted;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: { borderRadius: 999, borderWidth: 1, borderColor: tone === "muted" ? colors.border : color, paddingHorizontal: 7, paddingVertical: 1, alignSelf: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: { color, fontSize: 11, fontWeight: "500" }, children: label }) });\n}\nfunction Button({ theme, label, onPress, kind = "plain", icon, disabled, accessibilityLabel }) {\n const { colors } = theme;\n const color = kind === "primary" ? colors.accentForeground : kind === "danger" ? colors.statusDanger : colors.foreground;\n return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(\n import_react_native4.Pressable,\n {\n accessibilityRole: "button",\n accessibilityLabel: accessibilityLabel ?? label,\n disabled,\n onPress,\n style: (state) => ({\n flexDirection: "row",\n alignItems: "center",\n gap: 6,\n borderRadius: 8,\n paddingHorizontal: 12,\n paddingVertical: 7,\n opacity: disabled ? 0.5 : 1,\n backgroundColor: kind === "primary" ? colors.accent : hovered2(state) ? colors.surface2 : colors.surface1,\n borderWidth: kind === "primary" ? 0 : 1,\n borderColor: kind === "danger" ? colors.statusDanger : colors.border\n }),\n children: [\n icon ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Icon, { name: icon, size: 14, color }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: { color, fontSize: 13, fontWeight: kind === "primary" ? "600" : "500" }, children: label })\n ]\n }\n );\n}\nfunction layoutStyles(theme) {\n const { colors } = theme;\n return {\n root: { flex: 1, flexDirection: "row", backgroundColor: colors.surface0, minHeight: 560, borderWidth: 1, borderColor: colors.border, borderRadius: 12, overflow: "hidden" },\n aside: { backgroundColor: colors.surface1, borderRightWidth: 1, borderRightColor: colors.border },\n asideOverlay: { height: "100%", shadowColor: "#000", shadowOpacity: 0.2, shadowRadius: 16 },\n asideHeader: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 12, paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: colors.border, gap: 8 },\n asideHeaderCollapsed: { justifyContent: "center", paddingHorizontal: 0 },\n asideTitleBox: { flex: 1, minWidth: 0 },\n asideTitle: { color: colors.foreground, fontSize: 14, fontWeight: "600" },\n asideSubtitle: { color: colors.foregroundMuted, fontSize: 11, marginTop: 1 },\n asideList: { paddingVertical: 8, gap: 10 },\n group: { gap: 1 },\n groupLabel: { color: colors.foregroundMuted, fontSize: 11, fontWeight: "600", letterSpacing: 0.4, textTransform: "uppercase", paddingHorizontal: 14, paddingBottom: 4 },\n groupRule: { height: 1, backgroundColor: colors.border, marginHorizontal: 12, marginBottom: 4 },\n item: { flexDirection: "row", alignItems: "center", gap: 10, marginHorizontal: 6, paddingHorizontal: 8, paddingVertical: 7, borderRadius: 7 },\n itemCollapsed: { justifyContent: "center", paddingHorizontal: 0 },\n itemOn: { backgroundColor: colors.surface2 },\n itemHover: { backgroundColor: colors.surface2 },\n itemBar: { position: "absolute", left: -6, top: 6, bottom: 6, width: 3, borderRadius: 2, backgroundColor: colors.accent },\n itemLabel: { flex: 1, color: colors.foreground, fontSize: 13 },\n itemLabelOn: { color: colors.foreground, fontWeight: "600" },\n count: { color: colors.foregroundMuted, fontSize: 11, fontVariant: ["tabular-nums"] },\n children: { marginLeft: 22, borderLeftWidth: 1, borderLeftColor: colors.border, marginVertical: 2, paddingLeft: 4 },\n child: { flexDirection: "row", alignItems: "center", gap: 8, marginRight: 6, paddingHorizontal: 8, paddingVertical: 5, borderRadius: 6 },\n childOn: { backgroundColor: colors.surface2 },\n childLabel: { flex: 1, color: colors.foreground, fontSize: 12.5 },\n childHint: { color: colors.foregroundMuted, fontSize: 11 },\n dot: { width: 6, height: 6, borderRadius: 3 },\n main: { flex: 1, minWidth: 0 },\n header: { borderBottomWidth: 1, borderBottomColor: colors.border, paddingHorizontal: 20, paddingTop: 14, gap: 10 },\n headerRow: { flexDirection: "row", alignItems: "center", gap: 10, minHeight: 32 },\n crumbs: { flex: 1, minWidth: 0, flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" },\n crumb: { color: colors.foregroundMuted, fontSize: 13 },\n crumbSeparator: { color: colors.foregroundMuted, fontSize: 13, opacity: 0.6 },\n crumbCurrent: { color: colors.foreground, fontSize: 16, fontWeight: "600" },\n actions: { flexDirection: "row", gap: 8, alignItems: "center" },\n tabs: { flexDirection: "row", gap: 4 },\n tab: { paddingHorizontal: 10, paddingVertical: 8, borderBottomWidth: 2, borderBottomColor: "transparent" },\n tabOn: { borderBottomColor: colors.accent },\n tabText: { color: colors.foregroundMuted, fontSize: 13 },\n tabTextOn: { color: colors.foreground, fontSize: 13, fontWeight: "600" },\n tabCount: { color: colors.foregroundMuted, fontSize: 11 },\n body: { flex: 1 },\n bodyContent: { padding: 20, gap: 16 },\n footer: { flexDirection: "row", alignItems: "center", gap: 10, paddingHorizontal: 20, paddingVertical: 12, borderTopWidth: 1, borderTopColor: colors.border, backgroundColor: colors.surface1 },\n iconButton: { padding: 6, borderRadius: 6 },\n overlay: { position: "absolute", left: 0, top: 0, right: 0, bottom: 0, flexDirection: "row" },\n scrim: { flex: 1, backgroundColor: "rgba(0,0,0,0.25)" }\n };\n}\n\n// integrations/paseo/client/team-model-settings.tsx\nvar import_jsx_runtime3 = require("react/jsx-runtime");\nvar clone = (team) => JSON.parse(JSON.stringify(team));\nfunction TeamModelSettings({ team, theme, onChange }) {\n const readModels = (0, import_client2.useRpc)(libraryModels);\n const [models, setModels] = (0, import_react3.useState)([]);\n const [error, setError] = (0, import_react3.useState)("");\n const [customFields, setCustomFields] = (0, import_react3.useState)({});\n const setup = modelSetupFor(team, models);\n const mode = setup.mode;\n const preset = setup.preset ?? "mix";\n (0, import_react3.useEffect)(() => {\n let live = true;\n readModels({}).then((result) => {\n if (live) {\n setModels(result.models);\n setError("");\n }\n }).catch((cause) => {\n if (live) setError(String(cause.message ?? cause));\n });\n return () => {\n live = false;\n };\n }, [readModels]);\n const edit = (work) => {\n const next = clone(team);\n next.modelSetup = { mode: "custom" };\n work(next);\n onChange(next);\n setError("");\n };\n const selectPreset = (value) => {\n try {\n onChange(presetTeamModels(team, value, models));\n setCustomFields({});\n setError("");\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n };\n const chooseModel = (label, value, set) => {\n const known = models.find((model) => model.id === value);\n const options = [...label.startsWith("oracle-") ? [] : [{ label: "Inherit", value: "" }], ...models.map((model) => ({ value: model.id, label: model.label }))];\n if (value && !known) options.push({ label: value, value });\n options.push({ label: "Custom model ID", value: "__custom" });\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Model", value: customFields[label] ? "__custom" : value, options, onValueChange: (id) => {\n setCustomFields((previous) => ({ ...previous, [label]: id === "__custom" }));\n if (id !== "__custom") edit((next) => set(next, id, models.find((model) => model.id === id)?.effort));\n } }),\n customFields[label] || value && !known ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsInput, { label: "Custom model ID", hint: "claude:model, codex:model, antigravity:model or acp:provider/model", initialValue: value, onChangeText: (id) => edit((next) => set(next, id.trim())) }, `${label}-custom`) : null\n ] });\n };\n const effort = (model, value, set) => {\n const known = models.find((choice) => choice.id === model);\n const values = known ? known.efforts : ["none", "off", "low", "medium", "high", "xhigh", "max", "ultra", "ultracode"];\n const options = [{ label: "Inherit", value: "" }, ...[.../* @__PURE__ */ new Set([...values, ...value ? [value] : []])].map((value2) => ({ label: value2, value: value2 }))];\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Effort", value, options, onValueChange: (value2) => edit((next) => set(next, value2)) });\n };\n const assign = (target, id, thinking) => {\n if (id) target.model = id;\n else delete target.model;\n if (thinking) target.thinking = thinking;\n else delete target.thinking;\n };\n const setEffort = (target, value) => {\n if (value) target.thinking = value;\n else delete target.thinking;\n };\n const lenses = team.oracleModels ?? ["claude:claude-fable-5-1", "codex:gpt-6-astra"];\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Model setup", children: [\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Mode", value: mode, options: [{ label: "Default presets", value: "default" }, { label: "Custom", value: "custom" }], onValueChange: (value) => value === "default" ? selectPreset(preset) : edit(() => {\n }) }),\n mode === "default" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSelect, { label: "Preset", value: preset, options: MODEL_PRESETS, onValueChange: selectPreset }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Save with template", hint: "Save writes these model choices into settings.json for this team immediately. Project template overrides still apply to Host templates." }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { accessibilityRole: "alert", style: { color: theme?.colors.statusDanger }, children: error }) : null\n ] }),\n mode === "default" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Preset models", children: [\n Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").map(([name, member]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: name, hint: member.model }, name)),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Supervisor", hint: team.supervisor.model }) : null,\n team.members?.oracle ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Oracle", hint: lenses.join(", ") }) : null\n ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react3.Fragment, { children: [\n Object.entries(team.members ?? {}).filter(([name]) => name !== "oracle").map(([name, member]) => {\n const config = member;\n return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: name === team.main ? `${name} \\xB7 main` : name, children: [\n chooseModel(name, config.model ?? "", (next, id, effort2) => assign(next.members[name], id, effort2)),\n effort(config.model ?? team.members[team.main]?.model ?? "", config.thinking ?? "", (next, value) => setEffort(next.members[name], value))\n ] }, name);\n }),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: "Supervisor", children: [\n chooseModel("supervisor", team.supervisor.model ?? "", (next, id, effort2) => assign(next.supervisor, id, effort2)),\n effort(team.supervisor.model ?? "", team.supervisor.thinking ?? "", (next, value) => setEffort(next.supervisor, value))\n ] }) : null,\n team.members?.oracle ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [\n lenses.map((id, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui.SettingsSection, { title: `Oracle ${index + 1}`, children: [\n chooseModel(`oracle-${index}`, id, (next, value, effort2) => {\n next.oracleModels = [...lenses];\n next.oracleModels[index] = value;\n next.oracleThinking ?? (next.oracleThinking = {});\n delete next.oracleThinking[id];\n if (effort2) next.oracleThinking[value] = effort2;\n }),\n effort(id, team.oracleThinking?.[id] ?? team.oracleThinking?.[id.split(":")[0]] ?? "", (next, value) => {\n next.oracleThinking ?? (next.oracleThinking = {});\n delete next.oracleThinking[id.split(":")[0]];\n if (value) next.oracleThinking[id] = value;\n else delete next.oracleThinking[id];\n }),\n theme && lenses.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { theme, label: "Remove model", onPress: () => edit((next) => {\n next.oracleModels = lenses.filter((_, i) => i !== index);\n }) }) : null\n ] }, index)),\n theme ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { theme, label: "Add oracle model", onPress: () => edit((next) => {\n next.oracleModels = [...lenses, ""];\n setCustomFields((previous) => ({ ...previous, [`oracle-${lenses.length}`]: true }));\n }) }) : null\n ] }) : null\n ] }, "custom-models"),\n JSON.stringify(team).includes("antigravity:") ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsSection, { title: "Antigravity", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ui.SettingsRow, { label: "Advisory roles", hint: \'Reviewer, Oracle and Supervisor require readOnlyMode: "instructions" in the Antigravity provider. Review copies and custom permission rules are unsupported.\' }) }) : null\n ] });\n}\n\n// integrations/paseo/client/library.tsx\nvar import_client3 = require("@getpaseo/plugin/client");\nvar import_react_native6 = require("@getpaseo/plugin/client/react-native");\nvar import_ui2 = require("@getpaseo/plugin/client/ui");\nvar import_react4 = require("react");\nvar import_react_native7 = require("react-native");\nvar import_jsx_runtime4 = require("react/jsx-runtime");\nvar KINDS = [\n { kind: "teams", title: "Teams", one: "team", icon: "Users", group: "Organisation" },\n { kind: "agents", title: "Agents", one: "agent", icon: "Bot", group: "Organisation" },\n { kind: "skills", title: "Skills", one: "skill", icon: "BookOpen", group: "Capabilities" },\n { kind: "mcp", title: "MCP servers", one: "MCP server", icon: "Plug", group: "Capabilities" },\n { kind: "hooks", title: "Hooks", one: "hook", icon: "Webhook", group: "Capabilities" },\n // ACP agents (ALPD \xA746): in the library only, so the project panel leaves them out.\n { kind: "providers", title: "Providers", one: "provider", icon: "Cpu", group: "Runtimes" }\n];\nvar shownIn = (scope) => KINDS.filter((item) => scope === "library" || item.kind !== "providers");\nvar kindOf = (kind) => KINDS.find((item) => item.kind === kind);\nvar HOOK_EVENTS = ["session.start", "turn.end", "assignment.start", "assignment.end", "handoff", "task.close", "merge"];\nvar BLOCKING_EVENTS = ["handoff", "task.close", "merge"];\nvar ROLES = ["lead", "peer", "advisor", "reviewer"];\nvar MODES = ["", "read-only", "workspace-write", "full-access"];\nvar NAME = /^[\\w.-]+$/;\nvar clone2 = (value) => JSON.parse(JSON.stringify(value));\nvar message = (cause) => cause instanceof Error ? cause.message : String(cause);\nvar sourceLabel = (source) => source === "builtin" ? "built-in" : source;\nvar sourceTone = (source) => source === "project" ? "warning" : source === "library" ? "accent" : "muted";\nvar LANGUAGES = [\n { label: "Ti\\u1EBFng Vi\\u1EC7t", value: "Vietnamese" },\n { label: "English", value: "English" },\n { label: "\\u65E5\\u672C\\u8A9E", value: "Japanese" },\n { label: "\\uD55C\\uAD6D\\uC5B4", value: "Korean" },\n { label: "\\u4E2D\\u6587", value: "Chinese" },\n { label: "Fran\\xE7ais", value: "French" },\n { label: "Deutsch", value: "German" },\n { label: "Espa\\xF1ol", value: "Spanish" }\n];\nfunction LibrarySettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library" });\n}\nfunction TeamsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "teams", embedded: true });\n}\nfunction AgentsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "agents", embedded: true });\n}\nfunction SkillsSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "skills", embedded: true });\n}\nfunction HooksSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "hooks", embedded: true });\n}\nfunction McpSettings({ theme, layout }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "library", initialKind: "mcp", embedded: true });\n}\nfunction ProjectLibraryPanel({ theme, layout, workspaceId }) {\n const directory = (0, import_client3.useWorkspace)(workspaceId, (workspace) => workspace.directory || workspace.projectRootPath);\n if (!directory) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: { padding: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: { color: theme.colors.foregroundMuted }, children: "This panel needs a workspace." }) });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryManager, { theme, compact: layout.compact, scope: "project", directory });\n}\nfunction LibraryManager({ theme, compact, scope, directory, embedded = false, initialKind = "teams" }) {\n const list = (0, import_client3.useRpc)(libraryList);\n const get = (0, import_client3.useRpc)(libraryGet);\n const save = (0, import_client3.useRpc)(librarySave);\n const remove = (0, import_client3.useRpc)(libraryDelete);\n const duplicate = (0, import_client3.useRpc)(libraryDuplicate);\n const probe = (0, import_client3.useRpc)(libraryTest);\n const give = (0, import_client3.useRpc)(librarySkills);\n const readLanguage = (0, import_client3.useRpc)(languageGet);\n const writeLanguage = (0, import_client3.useRpc)(languageSet);\n const toast = (0, import_react_native6.useToast)();\n const [language, setLanguageState] = (0, import_react4.useState)(null);\n const [lists, setLists] = (0, import_react4.useState)({});\n const [where, setWhere] = (0, import_react4.useState)(null);\n const [error, setError] = (0, import_react4.useState)(null);\n const [selection, setSelection] = (0, import_react4.useState)({ kind: initialKind });\n const [entry, setEntry] = (0, import_react4.useState)(null);\n const [tick, setTick] = (0, import_react4.useState)(0);\n const refresh = (0, import_react4.useCallback)(() => setTick((value) => value + 1), []);\n const base = directory ? { directory } : {};\n (0, import_react4.useEffect)(() => {\n let live = true;\n Promise.all(KINDS.map(({ kind }) => list({ ...base, kind }).then((result) => [kind, result]))).then((results) => {\n if (!live) return;\n setLists(Object.fromEntries(results.map(([kind, result]) => [kind, result.entries])));\n setWhere({ projectRoot: results[0][1].projectRoot, library: results[0][1].library, ...results[0][1].readOnly ? { readOnly: results[0][1].readOnly } : {} });\n setError(null);\n }).catch((cause) => {\n if (live) setError(message(cause));\n });\n return () => {\n live = false;\n };\n }, [list, directory, tick]);\n (0, import_react4.useEffect)(() => {\n if (scope !== "library") return;\n let live = true;\n readLanguage({}).then((result) => {\n if (live) setLanguageState(result);\n }).catch((cause) => {\n if (live) setError(message(cause));\n });\n return () => {\n live = false;\n };\n }, [readLanguage, scope, tick]);\n (0, import_react4.useEffect)(() => {\n if (!selection.name || selection.creating) {\n setEntry(null);\n return;\n }\n let live = true;\n get({ ...base, kind: selection.kind, name: selection.name }).then((result) => {\n if (live) setEntry(result);\n }).catch((cause) => {\n if (live) {\n toast.error(message(cause));\n setSelection({ kind: selection.kind });\n }\n });\n return () => {\n live = false;\n };\n }, [selection, get, directory, tick]);\n const run = (0, import_react4.useCallback)((work, done) => __async(null, null, function* () {\n try {\n yield work();\n toast.show(done, { variant: "success" });\n refresh();\n return true;\n } catch (cause) {\n toast.error(message(cause));\n return false;\n }\n }), [toast, refresh]);\n const actions = {\n select: (next) => setSelection(next),\n duplicate: (kind, from, to) => run(() => duplicate({ ...base, kind, from, to, scope }), `Copied ${from} to ${to}`),\n // In the project panel: copy what applies into .alp/, or drop the project\'s copy.\n override: (kind, name) => run(() => duplicate({ ...base, kind, from: name, to: name, scope: "project" }), `${name} is now overridden in this project`),\n useLibrary: (kind, name) => run(() => remove({ ...base, kind, name, scope: "project" }), `${name} follows the library again`),\n save: (kind, name, content, revision, creating) => __async(null, null, function* () {\n try {\n const result = yield save({ ...base, kind, name, scope, content, revision });\n const synced = result.syncedProjects ?? 0;\n toast.show(`Saved ${name}${synced ? ` \\xB7 Updated settings in ${synced} project${synced === 1 ? "" : "s"}` : ""}`, { variant: "success" });\n if (result.syncErrors?.length) toast.error(`Template saved, but some project settings could not be updated: ${result.syncErrors.join("; ")}`);\n refresh();\n if (creating) setSelection({ kind, name });\n return true;\n } catch (cause) {\n toast.error(message(cause));\n return false;\n }\n }),\n giveSkills: (agent, skills) => run(() => give({ agent, skills }), `Saved the skills of ${agent}`),\n setLanguage: (next) => run(() => writeLanguage({ language: next }), next ? `Agents now write to you in ${next}` : "Agents write to you in the default language again"),\n remove: (kind, name, revision) => __async(null, null, function* () {\n const removed = yield run(() => remove({ ...base, kind, name, scope, ...revision ? { revision } : {} }), `Removed ${name}`);\n if (removed) setSelection({ kind });\n return removed;\n }),\n test: (kind, name) => __async(null, null, function* () {\n try {\n return yield probe({ ...base, kind, name });\n } catch (cause) {\n toast.error(message(cause));\n return null;\n }\n })\n };\n const shown = selection.name && !selection.creating && entry?.name !== selection.name ? { kind: selection.kind } : selection;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LibraryWorkspace, { theme, compact, scope, where, lists, error, selection: shown, entry: shown.name ? entry : null, actions, language, embedded });\n}\nfunction navGroups(scope, lists) {\n const groups = scope === "library" ? [{ key: "General", label: "General", items: [{ key: "language", label: "Language", icon: "Languages" }] }] : [];\n for (const item of shownIn(scope)) {\n let group = groups.find((candidate) => candidate.label === item.group);\n if (!group) groups.push(group = { key: item.group, label: item.group, items: [] });\n const rows = lists[item.kind];\n group.items.push({\n key: item.kind,\n label: item.title,\n icon: item.icon,\n ...rows ? { count: rows.length } : {},\n children: (rows ?? []).map((row) => ({ key: row.name, label: row.name, tone: sourceTone(row.source) }))\n });\n }\n return groups;\n}\nfunction LibraryWorkspace({ theme, compact, scope, where, lists, error, selection, entry, actions, initialCollapsed, language, embedded }) {\n const styles = (0, import_react4.useMemo)(() => makeStyles2(theme, compact), [theme, compact]);\n const title = scope === "library" ? "ALP library" : "ALP project";\n const subtitle = scope === "library" ? where?.library : where?.projectRoot ?? void 0;\n const groups = navGroups(scope, lists);\n const onSelect = (kind2, name) => actions.select(kind2 === "language" ? { kind: kind2 } : { kind: kind2, ...name ? { name } : {} });\n if (scope === "project" && where?.readOnly?.unlisted) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: where.readOnly.unlisted }) });\n }\n if (scope === "project" && where && !where.projectRoot) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.screen, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "This workspace is not an ALP project. Run alp init to start one." }) });\n }\n if (selection.kind === "language") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LanguageSettings, { theme, compact, language: language ?? null, error, actions, layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }, styles });\n }\n const kind = kindOf(selection.kind);\n if (where?.readOnly && (selection.name || selection.creating)) {\n const viewed = !where.readOnly.unlisted && entry && entry.name === selection.name && entry.kind === selection.kind ? entry : null;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title,\n subtitle,\n groups,\n active: { item: selection.kind, ...selection.name ? { child: selection.name } : {} },\n onSelect,\n initialCollapsed,\n embedded,\n breadcrumb: [kind.title, selection.name ?? "Read only"],\n badges: viewed ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: sourceLabel(viewed.source), tone: sourceTone(viewed.source) }) : null,\n actions: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, icon: "ArrowLeft", label: `All ${kind.title.toLowerCase()}`, onPress: () => actions.select({ kind: selection.kind }) }),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: where.readOnly.reason }),\n error || where.readOnly.unlisted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: error ?? where.readOnly.unlisted }) : selection.creating ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Create entries on the ALP host." }) : !viewed ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Loading\\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n viewed.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, children: [\n "Overrides ",\n sourceLabel(viewed.overrides),\n "."\n ] }) : null,\n viewed.usedBy.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, children: [\n "Used by ",\n viewed.usedBy.join(", "),\n "."\n ] }) : null,\n viewed.librarySkills?.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, children: [\n "Library skills: ",\n viewed.librarySkills.join(", "),\n "."\n ] }) : null,\n viewed.secrets?.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n "Secrets hidden: ",\n viewed.secrets.join(", "),\n ". Secret markers stand for values kept on the ALP host."\n ] }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { selectable: true, style: styles.small, children: JSON.stringify(viewed.content, null, 2) })\n ] })\n ]\n }\n );\n }\n if (selection.name || selection.creating) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n EntryEditor,\n {\n theme,\n compact,\n scope,\n kind: selection.kind,\n entry: selection.creating ? null : entry,\n lists,\n actions,\n layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }\n },\n `${selection.kind}/${selection.name ?? "new"}/${entry?.revision ?? "new"}/${(entry?.librarySkills ?? []).join(",")}`\n );\n }\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(KindOverview, { theme, compact, scope, kind: kind.kind, rows: lists[kind.kind], error, where, actions, layout: { title, subtitle, groups, onSelect, initialCollapsed, embedded }, styles });\n}\nvar OTHER = "other";\nfunction LanguageSettings({ theme, compact, language, error, actions, layout, styles }) {\n const named = language && LANGUAGES.some((option) => option.value === language.applies);\n const [choice, setChoice] = (0, import_react4.useState)(null);\n const [typed, setTyped] = (0, import_react4.useState)("");\n const shown = choice ?? (language ? named ? language.applies : OTHER : "");\n const typedValid = typed.trim().length > 0 && typed.trim().length <= 40;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: "language" },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: ["Library", "Language"],\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "The language you read. Main writes its replies, questions, approval requests and task titles in it, other agents put their questions to you in it, and ALP asks for approvals and writes its notices in it. Agents may talk among themselves in any language." }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.danger, children: error }) : null,\n !language && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Loading\\u2026" }) : null,\n language?.readOnly ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Language", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.name, children: [\n language.applies,\n language.language ? "" : " (default)"\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: language.readOnly })\n ] }) : !language ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Language", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSelect,\n {\n label: "Language",\n hint: language.language ? `Set in your settings.json` : `Not set: ${language.default} applies`,\n value: shown,\n options: [...LANGUAGES, { label: named || !language.language ? "Other\\u2026" : `${language.applies} (other)`, value: OTHER }],\n onValueChange: (value) => __async(null, null, function* () {\n setChoice(value);\n if (value !== OTHER && (yield actions.setLanguage(value))) setChoice(null);\n })\n }\n ),\n shown === OTHER ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Other language", hint: "Its name in English, such as Thai or Indonesian", initialValue: named ? "" : language.language ?? "", placeholder: "Thai", onChangeText: setTyped }) : null,\n shown === OTHER ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: "Use this language", actionLabel: "Save", disabled: !typedValid, onPress: () => __async(null, null, function* () {\n if (typedValid && (yield actions.setLanguage(typed.trim()))) setChoice(null);\n }) }) : null,\n language.language ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: `Use the default (${language.default})`, hint: "Removes the setting", actionLabel: "Reset", onPress: () => __async(null, null, function* () {\n if (yield actions.setLanguage(null)) setChoice(null);\n }) }) : null\n ] })\n ]\n }\n );\n}\nvar SOURCES = [{ key: "all", label: "All" }, { key: "builtin", label: "Built-in" }, { key: "library", label: "Library" }, { key: "project", label: "Project" }];\nfunction KindOverview({ theme, compact, scope, kind, rows, error, where, actions, layout, styles }) {\n const { title, one } = kindOf(kind);\n const [filter, setFilter] = (0, import_react4.useState)("all");\n const [copying, setCopying] = (0, import_react4.useState)(null);\n const [copyName, setCopyName] = (0, import_react4.useState)("");\n const tabs = SOURCES.map((source) => ({ ...source, count: (rows ?? []).filter((row) => source.key === "all" || row.source === source.key).length })).filter((tab) => tab.key === "all" || tab.count);\n const shown = (rows ?? []).filter((row) => filter === "all" || row.source === filter);\n const readOnly = where?.readOnly;\n const intro = readOnly ? `The ${title.toLowerCase()} ${scope === "project" ? "this project uses on the ALP host" : "of the ALP host"}, by name.` : kind === "providers" ? "Agents that speak the Agent Client Protocol. They live in your library only." : scope === "library" ? "Every project uses your library. Built-ins follow ALP updates; saving one makes your own copy of that name." : "What this project overrides. Override an entry to change it here only; Use library drops the project\'s copy.";\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: kind },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: layout.embedded ? [] : [scope === "library" ? "Library" : "Project", title],\n tabs,\n tab: filter,\n onTab: setFilter,\n actions: readOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", icon: "Plus", label: `New ${one}`, onPress: () => actions.select({ kind, creating: true }) }),\n children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: intro }),\n readOnly ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: readOnly.reason }) : null,\n error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.danger, children: error }) : null,\n !rows && !error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: "Loading\\u2026" }) : null,\n readOnly?.unlisted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, children: readOnly.unlisted }) }) : rows && !shown.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.empty, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n "No ",\n title.toLowerCase(),\n " ",\n filter === "all" ? "yet" : `from the ${sourceLabel(filter)}`,\n "."\n ] }) }) : null,\n shown.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles.table, children: shown.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: [styles.tableRow, index ? styles.tableRowRule : null], children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Pressable, { accessibilityRole: "button", accessibilityLabel: `Open ${one} ${row.name}`, onPress: () => actions.select({ kind, name: row.name }), style: styles.rowMain, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.rowTitle, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.name, children: row.name }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: sourceLabel(row.source), tone: sourceTone(row.source) }),\n row.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: `overrides ${sourceLabel(row.overrides)}` }) : null\n ] }),\n row.description ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.muted, numberOfLines: 2, children: row.description }) : null,\n row.usedBy?.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, numberOfLines: 1, children: [\n "Used by ",\n row.usedBy.join(", ")\n ] }) : null\n ] }),\n readOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: [styles.rowActions, compact ? styles.rowActionsCompact : null], children: [\n scope === "project" && row.source === "project" && row.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Use library", onPress: () => actions.useLibrary(kind, row.name) }) : null,\n scope === "project" && row.source !== "project" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Override in this project", onPress: () => actions.override(kind, row.name) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, icon: "Copy", label: "Duplicate", accessibilityLabel: `Duplicate ${one} ${row.name}`, onPress: () => {\n setCopying(row.name);\n setCopyName(`${row.name}-copy`);\n } })\n ] }),\n copying === row.name ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.copyRow, children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.TextInput, { style: styles.input, value: copyName, onChangeText: setCopyName, accessibilityLabel: "Name of the copy", placeholder: "Name of the copy", placeholderTextColor: theme.colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", label: "Copy", onPress: () => __async(null, null, function* () {\n if (NAME.test(copyName) && (yield actions.duplicate(kind, row.name, copyName))) setCopying(null);\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, label: "Cancel", onPress: () => setCopying(null) })\n ] }) : null\n ] }, row.name)) }) : null\n ]\n }\n );\n}\nfunction blank(kind, name = "new") {\n if (kind === "agents") return { instructions: `# ${name}\n\nDescribe what this agent does, and how.\n`, config: {} };\n if (kind === "skills") return { body: `---\nname: ${name}\ndescription: When to use this skill.\n---\n\n# ${name}\n\nSteps and checks.\n` };\n if (kind === "mcp") return { server: { command: "" } };\n if (kind === "hooks") return { hook: { event: "handoff", command: "", blocking: false } };\n if (kind === "providers") return { provider: { kind: "acp", label: name, command: "" } };\n return { team: { label: name, main: "main", members: { main: {} }, delegation: {}, supervisor: false }, houseRules: "" };\n}\nfunction entryTabs(kind, saved) {\n const tabs = {\n agents: [["general", "General"], ["instructions", "Instructions"], ["capabilities", "Skills, MCP & hooks"]],\n teams: [["models", "Models & effort"], ["general", "General"], ["members", "Members"], ["delegation", "Delegation"], ["supervisor", "Supervisor"], ["rules", "House rules"]],\n skills: [["body", "SKILL.md"]],\n mcp: [["server", "Server"], ["test", "Test"]],\n hooks: [["hook", "Hook"], ["test", "Test"]],\n providers: [["agent", "ACP agent"], ["test", "Test"]]\n };\n return tabs[kind].filter(([key]) => key !== "test" || saved).map(([key, label]) => ({ key, label }));\n}\nfunction EntryEditor({ theme, compact, scope, kind, entry, lists, actions, layout, initialTab }) {\n const styles = (0, import_react4.useMemo)(() => makeStyles2(theme, compact), [theme, compact]);\n const { one, title } = kindOf(kind);\n const tabs = entryTabs(kind, !!entry);\n const [tab, setTab] = (0, import_react4.useState)(initialTab && tabs.some((candidate) => candidate.key === initialTab) ? initialTab : tabs[0].key);\n const [name, setName] = (0, import_react4.useState)(entry?.name ?? "");\n const original = (0, import_react4.useMemo)(() => clone2(entry?.content ?? blank(kind)), [entry, kind]);\n const [content, setContent] = (0, import_react4.useState)(() => clone2(original));\n const [result, setResult] = (0, import_react4.useState)(null);\n const own = entry?.source === scope;\n const update = (change) => setContent((current) => {\n const draft = clone2(current);\n change(draft);\n return draft;\n });\n const valid = NAME.test(name);\n const changed = !entry || JSON.stringify(content) !== JSON.stringify(original);\n const givenOriginal = (0, import_react4.useMemo)(() => entry?.librarySkills ?? [], [entry]);\n const [given, setGiven] = (0, import_react4.useState)(givenOriginal);\n const givesSkills = kind === "agents" && scope === "library";\n const givenChanged = givesSkills && [...given].sort().join() !== [...givenOriginal].sort().join();\n const dirty = changed || givenChanged;\n const onSave = () => __async(null, null, function* () {\n if (!valid) return;\n if (changed && !(yield actions.save(kind, name, content, own ? entry.revision : null, !entry))) return;\n if (givenChanged) yield actions.giveSkills(name, given);\n });\n const note = entry ? entry.source === "builtin" ? `Built into ALP. Saving makes ${scope === "library" ? "your library\'s" : "this project\'s"} own ${entry.name}, which overrides it.` : own ? `In ${scope === "library" ? "your library" : "this project"}${entry.overrides ? `; overrides the ${sourceLabel(entry.overrides)} one` : ""}.` : `From the ${sourceLabel(entry.source)}. Saving makes this project\'s own copy.` : null;\n const form = { content, update, lists, styles, theme };\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(\n SideNavLayout,\n {\n theme,\n compact,\n title: layout.title,\n subtitle: layout.subtitle,\n groups: layout.groups,\n active: { item: kind, ...entry ? { child: entry.name } : {} },\n onSelect: layout.onSelect,\n initialCollapsed: layout.initialCollapsed,\n embedded: layout.embedded,\n breadcrumb: [title, entry ? entry.name : `New ${one}`],\n badges: entry ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: sourceLabel(entry.source), tone: sourceTone(entry.source) }),\n entry.overrides ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Pill, { theme, label: `overrides ${sourceLabel(entry.overrides)}` }) : null\n ] }) : null,\n actions: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, icon: "ArrowLeft", label: `All ${title.toLowerCase()}`, onPress: () => actions.select({ kind }) }),\n tabs,\n tab,\n onTab: setTab,\n footer: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "primary", label: entry && entry.source === "builtin" && (changed || !givenChanged) ? "Save as my own" : "Save", disabled: !valid || !dirty, onPress: () => {\n void onSave();\n } }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: !valid ? "Name the entry first" : dirty ? "Unsaved changes" : own ? "Saved" : "No changes" }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: { flex: 1 } }),\n entry && own ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Button, { theme, kind: "danger", label: entry.overrides ? `Remove (the ${sourceLabel(entry.overrides)} one applies again)` : "Remove", onPress: () => actions.remove(kind, entry.name, entry.revision) }) : null\n ] }),\n children: [\n note || entry?.usedBy.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles.banner, children: [\n note ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.bannerText, children: note }) : null,\n entry?.usedBy.length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.small, children: [\n "Used by ",\n entry.usedBy.join(", "),\n "."\n ] }) : null\n ] }) : null,\n !entry && tab === tabs[0].key ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSection, { title: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Name", hint: "Letters, digits, \'.\', \'_\' or \'-\'", error: name && !valid ? "Not a valid name" : null, initialValue: name, onChangeText: setName }) }) : null,\n kind === "agents" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentForm, { ...form, tab, given: entry?.librarySkills ?? [], ...givesSkills ? { draftGiven: given, setGiven } : {} }) : null,\n kind === "teams" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamForm, { ...form, tab }) : null,\n kind === "skills" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.body ?? "", onChange: (text) => update((draft) => {\n draft.body = text;\n }), styles, theme, label: "SKILL.md", tall: true }) : null,\n kind === "mcp" && tab === "server" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(McpForm, { content, update }) : null,\n kind === "hooks" && tab === "hook" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HookForm, { content, update, lists }) : null,\n kind === "providers" && tab === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ProviderForm, { content, update }) : null,\n tab === "test" && entry ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Test", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsAction, { label: kind === "mcp" ? "Start the server and list its tools" : kind === "providers" ? "Start the agent and ask what it supports" : "Run once with a sample event", hint: "The test runs what is saved.", actionLabel: "Test", onPress: () => __async(null, null, function* () {\n return setResult(yield actions.test(kind, entry.name));\n }) }),\n result ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TestResult, { kind, result, styles }) : null\n ] }) : null\n ]\n }\n );\n}\nvar names = (lists, kind) => (lists[kind] ?? []).map((row) => row.name);\nvar toggle = (list, name, on) => {\n const set = new Set(list ?? []);\n if (on) set.add(name);\n else set.delete(name);\n return [...set];\n};\nvar setOrDelete = (target, key, value) => {\n if (value === "" || value === void 0 || Array.isArray(value) && !value.length) delete target[key];\n else target[key] = value;\n};\nvar CONTEXT_SIZES = [2e5, 4e5, 6e5, 1e6];\nvar contextOptions = (current) => [\n { label: "Auto (the model\'s)", value: "" },\n ...[.../* @__PURE__ */ new Set([...CONTEXT_SIZES, ...typeof current === "number" ? [current] : []])].sort((a, b) => a - b).map((tokens) => ({ label: tokens >= 1e6 ? `${tokens / 1e6}M tokens` : `${Math.round(tokens / 1e3)}k tokens`, value: String(tokens) }))\n];\nfunction AgentForm({ content, update, lists, styles, theme, tab, given = [], draftGiven, setGiven }) {\n const config = content.config ?? {};\n const field = (key) => (text) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, key, text.trim());\n });\n const show = (key) => !tab || tab === key;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n show("general") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Agent", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: config.description ?? "", onChangeText: field("description") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Provider", hint: "The team or project settings may choose another", value: config.provider ?? "", options: [{ label: "Default", value: "" }, { label: "Codex", value: "codex" }, { label: "Claude Code", value: "claude" }, ...names(lists, "providers").map((provider) => ({ label: `${provider} (ACP)`, value: provider }))], onValueChange: field("provider") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Model", hint: "Such as claude:claude-sonnet-5-5, codex:gpt-6-sol or acp:gemini", initialValue: config.model ?? "", onChangeText: field("model") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Thinking", hint: "Effort, such as low, medium or high", initialValue: config.thinking ?? "", onChangeText: field("thinking") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSelect,\n {\n label: "Context",\n hint: "How much context it works with before the runtime compacts it",\n value: typeof config.context === "number" ? String(config.context) : "",\n options: contextOptions(config.context),\n onValueChange: (value) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, "context", value ? Number(value) : "");\n })\n }\n ),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Default mode", value: config.mode ?? "", options: MODES.map((mode) => ({ label: mode || "As its requester chooses", value: mode })), onValueChange: field("mode") })\n ] }) : null,\n show("instructions") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.instructions ?? "", onChange: (text) => update((draft) => {\n draft.instructions = text;\n }), styles, theme, label: "AGENT.md", tall: true }) : null,\n show("capabilities") ? ["skills", "mcp", "hooks"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: kindOf(kind).title, children: [\n !names(lists, kind).length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: `No ${kindOf(kind).title.toLowerCase()} to choose from yet` }) : null,\n names(lists, kind).map((name) => {\n const own = (config[kind] ?? []).includes(name);\n const configToggle = (on) => update((draft) => {\n draft.config ?? (draft.config = {});\n setOrDelete(draft.config, kind, toggle(draft.config[kind], name, on));\n });\n if (kind !== "skills") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, value: own, onValueChange: configToggle }, name);\n if (setGiven) {\n const library = (draftGiven ?? given).includes(name);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(\n import_ui2.SettingsSwitch,\n {\n label: name,\n hint: given.includes(name) ? "Default for this agent" : void 0,\n value: library || own,\n onValueChange: (on) => {\n setGiven(toggle(draftGiven ?? given, name, on));\n if (!on && own) configToggle(false);\n }\n },\n name\n );\n }\n if (given.includes(name)) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, hint: "Given by your library; change it in Settings \\u2192 ALP", value: true, disabled: true, onValueChange: () => {\n } }, name);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: name, value: own, onValueChange: configToggle }, name);\n })\n ] }, kind)) : null\n ] });\n}\nfunction withMember(team, agent, on) {\n const next = clone2(team);\n next.members ?? (next.members = {});\n next.delegation ?? (next.delegation = {});\n if (on) {\n next.members[agent] = { role: "peer" };\n return next;\n }\n delete next.members[agent];\n delete next.delegation[agent];\n for (const owner of Object.keys(next.delegation)) {\n next.delegation[owner] = next.delegation[owner].filter((target) => target !== agent);\n if (!next.delegation[owner].length) delete next.delegation[owner];\n }\n return next;\n}\nfunction withDelegation(team, owner, target, on) {\n const next = clone2(team);\n next.delegation ?? (next.delegation = {});\n const targets = toggle(next.delegation[owner], target, on);\n if (targets.length) next.delegation[owner] = targets;\n else delete next.delegation[owner];\n return next;\n}\nvar EFFORTS = ["", "none", "low", "medium", "high", "xhigh", "max"];\nvar effortOptions = EFFORTS.map((value) => ({ label: value || "Inherit", value }));\nfunction TeamModels({ content, update, theme }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamModelSettings, { team: content.team ?? {}, theme, onChange: (next) => update((draft) => {\n draft.team = next;\n }) });\n}\nfunction TeamForm({ content, update, lists, styles, theme, tab }) {\n const show = (key) => !tab || tab === key;\n const team = content.team ?? {};\n const agents = names(lists, "agents");\n const members = Object.keys(team.members ?? {});\n const others = members.filter((member) => member !== team.main);\n const cycle = delegationCycle(team.delegation ?? {});\n const text = (key) => (value) => update((draft) => {\n setOrDelete(draft.team, key, value.trim());\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n show("models") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TeamModels, { content, update, lists, styles, theme }) : null,\n show("general") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Team", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Label", hint: "Shown in the model picker", initialValue: team.label ?? "", onChangeText: text("label") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: team.description ?? "", onChangeText: text("description") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Most peers at once", initialValue: team.maxPeers === void 0 ? "" : String(team.maxPeers), onChangeText: (value) => update((draft) => {\n setOrDelete(draft.team, "maxPeers", value.trim() ? Number(value) : "");\n }) })\n ] }) : null,\n show("members") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: [team.main, ...agents.filter((agent) => agent !== team.main && agent !== team.supervisor?.agent)].filter(Boolean).map((agent) => {\n const member = team.members?.[agent];\n const main = agent === team.main;\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: main ? `${agent} \\xB7 main` : agent, info: main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: "The agent you talk with." }) : void 0, children: [\n !main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "In this team", value: !!member, onValueChange: (on) => update((draft) => {\n draft.team = withMember(draft.team, agent, on);\n }) }) : null,\n member && !main ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Role", value: member.role ?? "peer", options: ROLES.map((role) => ({ label: role, value: role })), onValueChange: (role) => update((draft) => {\n draft.team.members[agent].role = role;\n }) }) : null\n ] }, agent);\n }) }) : null,\n show("delegation") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n cycle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.danger, children: [\n "Cycle at ",\n cycle,\n ": ALP refuses it"\n ] }) : null,\n members.map((owner) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: `${owner} may delegate to`, info: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.small, children: (team.delegation?.[owner] ?? []).join(", ") || "no one" }), children: [\n others.filter((target) => target !== owner).map((target) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: target, value: (team.delegation?.[owner] ?? []).includes(target), onValueChange: (on) => update((draft) => {\n draft.team = withDelegation(draft.team, owner, target, on);\n }) }, `${owner}-${target}`)),\n !others.filter((target) => target !== owner).length ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: "No other members" }) : null\n ] }, owner))\n ] }) : null,\n show("supervisor") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Supervisor", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "Review main\'s process after each turn", value: !!team.supervisor, onValueChange: (on) => update((draft) => {\n draft.team.supervisor = on ? { agent: "supervisor" } : false;\n }) }),\n team.supervisor ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Supervisor agent", value: team.supervisor.agent, options: agents.filter((agent) => !members.includes(agent)).map((agent) => ({ label: agent, value: agent })), onValueChange: (agent) => update((draft) => {\n draft.team.supervisor.agent = agent;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsRow, { label: "Model & effort", hint: "Configure in Models & effort" })\n ] }) : null\n ] }) : null,\n show("rules") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Multiline, { value: content.houseRules ?? "", onChange: (value) => update((draft) => {\n draft.houseRules = value;\n }), styles, theme, label: "House rules", placeholder: "The team\'s rules and process, which every member reads (HOUSE_RULES.md)", tall: true }) : null\n ] });\n}\nfunction delegationCycle(graph) {\n const visiting = /* @__PURE__ */ new Set();\n const done = /* @__PURE__ */ new Set();\n const visit = (owner) => {\n if (visiting.has(owner)) return owner;\n if (done.has(owner)) return null;\n visiting.add(owner);\n for (const target of graph[owner] ?? []) {\n const found = visit(target);\n if (found) return found;\n }\n visiting.delete(owner);\n done.add(owner);\n return null;\n };\n for (const owner of Object.keys(graph)) {\n const found = visit(owner);\n if (found) return found;\n }\n return null;\n}\nvar lines = (text) => text.split("\\n").map((line) => line.trim()).filter(Boolean);\nvar pairs = (text) => Object.fromEntries(lines(text).filter((line) => line.includes("=")).map((line) => [line.slice(0, line.indexOf("=")).trim(), line.slice(line.indexOf("=") + 1).trim()]));\nvar unpairs = (map) => Object.entries(map ?? {}).map(([key, value]) => `${key}=${value}`).join("\\n");\nfunction McpForm({ content, update }) {\n const server = content.server ?? {};\n const http = server.url !== void 0;\n const set = (key, value) => update((draft) => {\n setOrDelete(draft.server, key, value);\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Server", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Transport", value: http ? "http" : "stdio", options: [{ label: "Command (stdio)", value: "stdio" }, { label: "URL (HTTP)", value: "http" }], onValueChange: (kind) => update((draft) => {\n draft.server = kind === "http" ? { url: "" } : { command: "" };\n }) }),\n http ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "URL", initialValue: server.url ?? "", onChangeText: (value) => update((draft) => {\n draft.server.url = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Headers", hint: "Name=value, separated by \';\'", initialValue: unpairs(server.headers).replaceAll("\\n", "; "), onChangeText: (value) => set("headers", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) })\n ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", initialValue: server.command ?? "", onChangeText: (value) => update((draft) => {\n draft.server.command = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Arguments", hint: "Separated by spaces", initialValue: (server.args ?? []).join(" "), onChangeText: (value) => set("args", value.split(/\\s+/).filter(Boolean)) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Environment", hint: "NAME=value, separated by \';\'", initialValue: unpairs(server.env).replaceAll("\\n", "; "), onChangeText: (value) => set("env", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Working directory", hint: "Relative to the mcp directory", initialValue: server.cwd ?? "", onChangeText: (value) => set("cwd", value.trim()) })\n ] })\n ] });\n}\nfunction ProviderForm({ content, update }) {\n const provider = content.provider ?? {};\n const set = (key, value) => update((draft) => {\n draft.provider ?? (draft.provider = { kind: "acp" });\n setOrDelete(draft.provider, key, value);\n });\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "ACP agent", info: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { children: "Any agent that speaks the Agent Client Protocol on stdio. ALP answers its permission requests by the session\'s mode; it cannot steer it mid-turn or sandbox its commands." }), children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Label", initialValue: provider.label ?? "", onChangeText: (value) => set("label", value.trim()) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Description", initialValue: provider.description ?? "", onChangeText: (value) => set("description", value.trim()) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", hint: "Such as gemini, or an absolute path", initialValue: provider.command ?? "", onChangeText: (value) => update((draft) => {\n draft.provider.command = value.trim();\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Arguments", hint: "Separated by spaces, such as --experimental-acp", initialValue: (provider.args ?? []).join(" "), onChangeText: (value) => set("args", value.split(/\\s+/).filter(Boolean)) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Environment", hint: "NAME=value, separated by \';\'", initialValue: unpairs(provider.env).replaceAll("\\n", "; "), onChangeText: (value) => set("env", Object.keys(pairs(value.replaceAll(";", "\\n"))).length ? pairs(value.replaceAll(";", "\\n")) : void 0) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Models", hint: "Ids the agent offers, separated by \',\'; empty lets any through", initialValue: (provider.models ?? []).map((model) => model.id).join(", "), onChangeText: (value) => set("models", value.split(",").map((id) => id.trim()).filter(Boolean).map((id) => (provider.models ?? []).find((model) => model.id === id) ?? { id })) })\n ] });\n}\nfunction HookForm({ content, update, lists }) {\n const hook = content.hook ?? {};\n const set = (key, value) => update((draft) => {\n setOrDelete(draft.hook, key, value);\n });\n const blocking = BLOCKING_EVENTS.includes(hook.event);\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ui2.SettingsSection, { title: "Hook", children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Event", value: hook.event ?? "handoff", options: HOOK_EVENTS.map((event) => ({ label: event, value: event })), onValueChange: (event) => update((draft) => {\n draft.hook.event = event;\n if (!BLOCKING_EVENTS.includes(event)) delete draft.hook.blocking;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Command", hint: "Runs in the session\'s directory; the event arrives as JSON on stdin", initialValue: hook.command ?? "", onChangeText: (value) => update((draft) => {\n draft.hook.command = value;\n }) }),\n blocking ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSwitch, { label: "Block the action when it fails", hint: "Its stderr becomes the reason the agent reads", value: !!hook.blocking, onValueChange: (on) => set("blocking", on || void 0) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Timeout (seconds)", initialValue: hook.timeoutSec === void 0 ? "" : String(hook.timeoutSec), onChangeText: (value) => set("timeoutSec", value.trim() ? Number(value) : "") }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsSelect, { label: "Only for agent", value: hook.match?.agent ?? "", options: [{ label: "Every agent", value: "" }, ...names(lists, "agents").map((agent) => ({ label: agent, value: agent }))], onValueChange: (agent) => update((draft) => {\n var _a;\n (_a = draft.hook).match ?? (_a.match = {});\n setOrDelete(draft.hook.match, "agent", agent);\n if (!Object.keys(draft.hook.match).length) delete draft.hook.match;\n }) }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ui2.SettingsInput, { label: "Only for tasks labeled", initialValue: hook.match?.label ?? "", onChangeText: (label) => update((draft) => {\n var _a;\n (_a = draft.hook).match ?? (_a.match = {});\n setOrDelete(draft.hook.match, "label", label.trim());\n if (!Object.keys(draft.hook.match).length) delete draft.hook.match;\n }) })\n ] });\n}\nfunction TestResult({ kind, result, styles }) {\n if (kind === "providers") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.success, children: [\n result.agent?.title ?? result.agent?.name ?? "The agent",\n result.agent?.version ? ` ${result.agent.version}` : "",\n " speaks ACP ",\n result.protocolVersion\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n result.loadSession ? "Resumes sessions" : "Cannot resume sessions",\n result.mcpHttp ? "; takes HTTP MCP servers" : "; takes stdio MCP servers only",\n result.authMethods?.length ? `; signs in with ${result.authMethods.join(", ")}` : ""\n ] })\n ] });\n }\n if (kind === "mcp") {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.success, children: [\n result.server?.name ?? "The server",\n result.server?.version ? ` ${result.server.version}` : "",\n " offers ",\n result.tools?.length ?? 0,\n " tools"\n ] }),\n (result.tools ?? []).map((tool) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: styles.muted, children: [\n tool.name,\n tool.description ? ` \\u2014 ${tool.description.split("\\n")[0]}` : ""\n ] }, tool.name))\n ] });\n }\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: result.ok ? styles.success : styles.danger, children: [\n result.timedOut ? "Timed out" : `Exit ${result.exitCode ?? result.signal}`,\n " in ",\n result.durationMs,\n " ms",\n result.wouldBlock ? "; as a blocking hook it would refuse the action" : ""\n ] }),\n result.stdout ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.code, children: result.stdout }) : null,\n result.stderr ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles.code, children: result.stderr }) : null\n ] });\n}\nfunction Multiline({ value, onChange, styles, theme, label, placeholder, tall }) {\n return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.TextInput, { style: [styles.multiline, tall ? styles.tall : null], value, onChangeText: onChange, multiline: true, accessibilityLabel: label, placeholder: placeholder ?? label, placeholderTextColor: theme.colors.foregroundMuted });\n}\nfunction makeStyles2(theme, compact) {\n const { colors } = theme;\n return {\n screen: { flex: 1, backgroundColor: colors.surface0, padding: compact ? 12 : 20 },\n muted: { color: colors.foregroundMuted, fontSize: 13, lineHeight: 19 },\n small: { color: colors.foregroundMuted, fontSize: 12 },\n danger: { color: colors.statusDanger, fontSize: 13 },\n success: { color: colors.statusSuccess, fontSize: 13 },\n name: { color: colors.foreground, fontSize: 14, fontWeight: "600" },\n empty: { borderWidth: 1, borderStyle: "dashed", borderColor: colors.border, borderRadius: 10, padding: 24, alignItems: "center" },\n table: { borderWidth: 1, borderColor: colors.border, borderRadius: 10, backgroundColor: colors.surface1, overflow: "hidden" },\n tableRow: { flexDirection: compact ? "column" : "row", flexWrap: "wrap", alignItems: compact ? "stretch" : "center", gap: 10, paddingHorizontal: 14, paddingVertical: 12 },\n tableRowRule: { borderTopWidth: 1, borderTopColor: colors.border },\n rowMain: { flex: 1, minWidth: 0, gap: 3 },\n rowTitle: { flexDirection: "row", alignItems: "center", gap: 8, flexWrap: "wrap" },\n rowActions: { flexDirection: "row", gap: 8, alignItems: "center" },\n rowActionsCompact: { flexWrap: "wrap" },\n copyRow: { flexBasis: "100%", flexDirection: "row", gap: 8, alignItems: "center" },\n input: { flex: 1, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 10, paddingVertical: 7, backgroundColor: colors.surface0 },\n banner: { borderRadius: 10, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, paddingHorizontal: 14, paddingVertical: 10, gap: 4 },\n bannerText: { color: colors.foreground, fontSize: 13 },\n multiline: { minHeight: 160, color: colors.foreground, borderWidth: 1, borderColor: colors.border, borderRadius: 10, padding: 12, fontFamily: "monospace", fontSize: 13, lineHeight: 19, backgroundColor: colors.surface1, textAlignVertical: "top" },\n tall: { minHeight: 420 },\n code: { color: colors.foreground, fontFamily: "monospace", fontSize: 12 }\n };\n}\n\n// integrations/paseo/client/usage.tsx\nvar import_client4 = require("@getpaseo/plugin/client");\nvar import_react_native8 = require("@getpaseo/plugin/client/react-native");\nvar import_react5 = require("react");\nvar import_react_native9 = require("react-native");\n\n// integrations/paseo/shared/usage.ts\nvar import_plugin3 = require("@getpaseo/plugin");\nvar import_zod3 = require("zod");\nvar Pause = import_zod3.z.object({ reason: import_zod3.z.string(), since: import_zod3.z.string(), resetsAt: import_zod3.z.string().optional() });\nvar usageGet = (0, import_plugin3.defineRpc)({\n name: "alp.usage.get",\n input: import_zod3.z.object({ refresh: import_zod3.z.boolean().optional() }),\n output: import_zod3.z.object({\n providers: import_zod3.z.array(import_zod3.z.object({\n runtime: import_zod3.z.enum(["codex", "claude"]),\n available: import_zod3.z.boolean(),\n checkedAt: import_zod3.z.string(),\n plan: import_zod3.z.string().nullable(),\n limited: import_zod3.z.boolean(),\n windows: import_zod3.z.array(import_zod3.z.object({ name: import_zod3.z.string(), usedPercent: import_zod3.z.number().nullable(), resetsAt: import_zod3.z.string().nullable() })),\n pause: Pause.nullable(),\n parked: import_zod3.z.number()\n }))\n })\n});\n\n// integrations/paseo/client/usage.tsx\nvar import_jsx_runtime5 = require("react/jsx-runtime");\nfunction UsageScreen({ theme, layout }) {\n const read = (0, import_client4.useRpc)(usageGet);\n const [data, setData] = (0, import_react5.useState)(null);\n const [error, setError] = (0, import_react5.useState)(null);\n const [loading, setLoading] = (0, import_react5.useState)(true);\n const [tick, setTick] = (0, import_react5.useState)(0);\n const forceRefresh = (0, import_react5.useRef)(false);\n (0, import_react5.useEffect)(() => {\n let live = true;\n setLoading(true);\n const refresh = forceRefresh.current;\n forceRefresh.current = false;\n read({ refresh }).then((result) => {\n if (live) {\n setData(result);\n setError(null);\n }\n }).catch((cause) => {\n if (live) setError(cause instanceof Error ? cause.message : String(cause));\n }).finally(() => {\n if (live) setLoading(false);\n });\n return () => {\n live = false;\n };\n }, [read, tick]);\n (0, import_react5.useEffect)(() => {\n const timer = setInterval(() => setTick((value) => value + 1), 6e4);\n return () => clearInterval(timer);\n }, []);\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UsageView, { theme, compact: layout.compact, data, loading, error, onRefresh: () => {\n forceRefresh.current = true;\n setTick((value) => value + 1);\n } });\n}\nfunction dateLabel(value) {\n const date = new Date(value);\n return Number.isFinite(date.getTime()) ? date.toLocaleString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" }) : "Unknown";\n}\nfunction resetLabel(value, now) {\n if (!value) return "Reset time unavailable";\n const minutes = Math.ceil((Date.parse(value) - now) / 6e4);\n if (minutes <= 0) return "Reset time passed \\xB7 awaiting provider update";\n const duration = minutes >= 1440 ? `${Math.floor(minutes / 1440)}d ${Math.floor(minutes % 1440 / 60)}h` : minutes >= 60 ? `${Math.floor(minutes / 60)}h ${minutes % 60}m` : `${minutes}m`;\n return `Resets in ${duration} \\xB7 ${dateLabel(value)}`;\n}\nfunction UsageView({ theme, compact, data, loading, error, onRefresh, now = Date.now() }) {\n const { colors } = theme;\n const muted = { color: colors.foregroundMuted, fontSize: 13, lineHeight: 20 };\n const providers = data?.providers ?? [];\n const parked = providers.reduce((sum, provider) => sum + provider.parked, 0);\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native8.ScrollView, { contentContainerStyle: { padding: compact ? 16 : 28, gap: 24 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityRole: "header", style: { color: colors.foreground, fontSize: 28, fontWeight: "600", letterSpacing: -0.7 }, children: "Usage" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { theme, label: loading ? "Refreshing\\u2026" : "Refresh", icon: "RefreshCw", disabled: loading, onPress: onRefresh, accessibilityLabel: "Refresh usage" })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Your provider limits, reset windows and paused work in one place." })\n ] }),\n error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { accessibilityRole: "alert", style: { padding: 14, borderWidth: 1, borderColor: colors.statusDanger, borderRadius: 10, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.statusDanger, fontWeight: "600" }, children: "Could not refresh usage" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: error }),\n data ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Showing the last received data." }) : null\n ] }) : null,\n parked > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { padding: 14, backgroundColor: colors.surface1, borderLeftWidth: 3, borderLeftColor: colors.statusWarning, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: { color: colors.foreground, fontWeight: "600" }, children: [\n parked,\n " ",\n parked === 1 ? "assignment waiting" : "assignments waiting"\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Parked work stays saved while its runtime is paused." })\n ] }) : null,\n !data && loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityLiveRegion: "polite", style: muted, children: "Checking Codex and Claude usage\\u2026" }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { style: { flexDirection: compact ? "column" : "row", flexWrap: "wrap", gap: 16 }, children: providers.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ProviderCard, { theme, provider, compact, now }, provider.runtime)) }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { borderTopWidth: 1, borderTopColor: colors.border, paddingTop: 16, gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "Account limits reported by each provider, shared with usage outside ALP." }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { ...muted, fontSize: 12 }, children: "Updates every minute while this screen is open. Readings are cached for up to 30 seconds. This is not a billing or token-spend report." })\n ] })\n ] });\n}\nfunction ProviderCard({ theme, provider, compact, now }) {\n const { colors } = theme;\n const status = provider.pause ? "Paused" : !provider.available ? "Unavailable" : provider.limited ? "Limit reached" : "Available";\n const tone = provider.pause || provider.limited ? "warning" : provider.available ? "success" : "muted";\n const muted = { color: colors.foregroundMuted, fontSize: 12, lineHeight: 18 };\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexGrow: 1, flexBasis: compact ? "auto" : 320, width: compact ? "100%" : void 0, minWidth: 0, padding: 20, backgroundColor: colors.surface1, borderWidth: 1, borderColor: colors.border, borderRadius: 14, gap: 20 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { accessibilityRole: "header", style: { color: colors.foreground, fontSize: 20, fontWeight: "600" }, children: provider.runtime === "codex" ? "Codex" : "Claude" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: provider.plan ? `${provider.plan} plan` : "Plan not reported" })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Pill, { theme, label: status, tone })\n ] }),\n provider.pause ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 5 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.statusWarning, fontSize: 13 }, children: provider.pause.reason }),\n provider.pause.resetsAt ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: resetLabel(provider.pause.resetsAt, now) }) : null,\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: muted, children: [\n provider.parked,\n " ",\n provider.parked === 1 ? "assignment parked" : "assignments parked"\n ] })\n ] }) : null,\n !provider.available ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8, paddingVertical: 16 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native8.Icon, { name: "CircleHelp", size: 22, color: colors.foregroundMuted }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.foreground, fontSize: 14, fontWeight: "500" }, children: "Usage is not available" }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "The provider did not return usage data. Check that its CLI is installed and signed in, then refresh." })\n ] }) : provider.windows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: "The provider has not reported any usage windows." }) : provider.windows.map((window, index) => {\n const used = window.usedPercent;\n const color = used === null ? colors.foregroundMuted : used >= 95 ? colors.statusDanger : used >= 80 ? colors.statusWarning : colors.accent;\n return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { gap: 8 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color: colors.foreground, fontSize: 13, flex: 1, textTransform: "capitalize" }, children: window.name }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: { color, fontSize: 25, fontWeight: "600", fontVariant: ["tabular-nums"] }, children: used === null ? "\\u2014" : `${Math.round(used)}%` })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { accessibilityRole: "progressbar", accessibilityLabel: `${window.name} used`, accessibilityValue: used === null ? { text: "Usage unknown" } : { min: 0, max: 100, now: used }, style: { height: 6, backgroundColor: colors.surface2, borderRadius: 3, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.View, { style: { height: 6, width: `${used ?? 0}%`, backgroundColor: color, borderRadius: 3 } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: used === null ? "Usage percentage unavailable" : `${Math.round(100 - used)}% remaining` }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native9.Text, { style: muted, children: resetLabel(window.resetsAt, now) })\n ] }, `${window.name}-${index}`);\n }),\n /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native9.Text, { style: { ...muted, borderTopWidth: 1, borderTopColor: colors.border, paddingTop: 12 }, children: [\n "Checked ",\n dateLabel(provider.checkedAt)\n ] })\n ] });\n}\n\n// integrations/paseo/index.client.tsx\nfunction contribute(client) {\n const removePanel = client.addWorkspacePanel({ id: "alp-tasks", title: "Tasks", icon: "ListTodo", context: "workspace", Component: TasksPanel });\n const removeScreen = client.addScreen({ id: TASKS_SCREEN, title: (params) => params.taskId ? `ALP task ${params.taskId}` : "ALP tasks", Component: TasksScreen });\n const removePills = addTaskPills(client);\n const removeCommand = client.addCommandCenterItem({\n id: "alp-open-tasks",\n title: "Open ALP tasks",\n icon: "ListTodo",\n keywords: ["tasks", "todo", "alp"],\n context: "workspace",\n onSelect({ openPanel }) {\n openPanel("alp-tasks");\n }\n });\n const removeScreenCommand = client.addCommandCenterItem({\n id: "alp-open-tasks-screen",\n title: "Open ALP tasks full screen",\n icon: "ListTodo",\n keywords: ["tasks", "todo", "alp", "phone"],\n context: "workspace",\n onSelect({ workspace, openScreen }) {\n openScreen(tasksScreen(workspace.id, workspace.directory || workspace.projectRootPath));\n }\n });\n const removeSlash = client.addSlashCommand({\n name: "alp-tasks",\n description: "Open the ALP tasks of this project",\n argumentHint: "[task id]",\n context: "agent",\n onSubmit({ workspace, args, openScreen }) {\n openScreen(tasksScreen(workspace.id, workspace.directory || workspace.projectRootPath, args.trim() || void 0));\n }\n });\n const removeSettings = client.addSettingsScreen({ id: "alp-settings", title: "ALP", icon: "Bot", Component: LibrarySettings });\n const removeHostSettings = [\n { id: "alp-templates", title: "Templates", icon: "Users", Component: TeamsSettings },\n { id: "alp-agents", title: "Agents", icon: "Bot", Component: AgentsSettings },\n { id: "alp-skills", title: "Skills", icon: "BookOpen", Component: SkillsSettings },\n { id: "alp-hooks", title: "Hooks", icon: "Webhook", Component: HooksSettings },\n { id: "alp-mcp", title: "MCP servers", icon: "Plug", Component: McpSettings }\n ].map((screen) => client.addSettingsScreen(screen));\n const removeUsage = client.addSettingsScreen({ id: "alp-usage", title: "Usage", icon: "ChartNoAxesCombined", Component: UsageScreen });\n const removeUsagePanel = client.addWorkspacePanel({ id: "alp-usage", title: "Usage", icon: "ChartNoAxesCombined", context: "workspace", Component: UsageScreen });\n const removeProject = client.addWorkspacePanel({ id: "alp-project", title: "ALP project", icon: "Bot", context: "workspace", Component: ProjectLibraryPanel });\n return () => {\n removePanel();\n removeScreen();\n removePills();\n removeCommand();\n removeScreenCommand();\n removeSlash();\n removeSettings();\n removeHostSettings.forEach((remove) => remove());\n removeProject();\n removeUsage();\n removeUsagePanel();\n };\n}\n\nreturn module.exports;})' };
7810
7810
 
7811
7811
  // packages/core/src/template-path.js
7812
7812
  import { existsSync } from "node:fs";
@@ -8691,7 +8691,7 @@ function launchCommand(command, args = [], env = process.env) {
8691
8691
  }
8692
8692
 
8693
8693
  // packages/core/src/library-edit.js
8694
- import { mkdir as mkdir2, rename as rename3, rm as rm3, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
8694
+ import { lstat as lstat3, mkdir as mkdir2, readdir as readdir4, rename as rename3, rm as rm3, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
8695
8695
  import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
8696
8696
  import path8 from "node:path";
8697
8697
 
@@ -8747,6 +8747,42 @@ function base(scope, { root, library }, kind) {
8747
8747
  return fail3("INVALID_SCOPE", `Scope must be library or project, not '${scope}'`);
8748
8748
  }
8749
8749
  var revisionOf = (content) => content === void 0 ? null : createHash2("sha256").update(JSON.stringify(content)).digest("hex").slice(0, 16);
8750
+ function assertProjectDataContent(kind, content) {
8751
+ const deny = () => fail3("UNSAFE_LIBRARY_WRITE", "Project-data writes allow only instruction entries and non-executable agent configuration");
8752
+ if (!object6(content) || !["agents", "skills"].includes(kind)) deny();
8753
+ const keys2 = kind === "skills" ? ["body"] : ["instructions", "config"];
8754
+ if (Object.keys(content).some((key) => !keys2.includes(key))) deny();
8755
+ const text = kind === "skills" ? content.body : content.instructions;
8756
+ if (typeof text !== "string" || !text.trim()) deny();
8757
+ if (content.config !== void 0) {
8758
+ const config2 = content.config;
8759
+ if (!object6(config2)) deny();
8760
+ const allowed = ["description", "model", "thinking", "context", "autocompact"];
8761
+ if (Object.keys(config2).some((key) => !allowed.includes(key))) deny();
8762
+ for (const key of ["description", "thinking"]) if (config2[key] !== void 0 && typeof config2[key] !== "string") deny();
8763
+ if (config2.model !== void 0 && (typeof config2.model !== "string" || !/^(codex|claude):[^\s/\\:]{1,240}$/.test(config2.model))) deny();
8764
+ for (const key of ["context", "autocompact"]) if (config2[key] !== void 0 && !(typeof config2[key] === "string" || typeof config2[key] === "number" && Number.isFinite(config2[key]))) deny();
8765
+ }
8766
+ }
8767
+ async function projectDataEntry(kind, name, { scope, root, library, templates: templates2 }) {
8768
+ if (scope !== "project" || !root || !["agents", "skills"].includes(kind)) fail3("UNSAFE_LIBRARY_WRITE", "Project-data writes require project scope and agents or skills");
8769
+ nameOf(name);
8770
+ const directory = base(scope, { root, library }, kind);
8771
+ await safeEntryPaths(directory, kind, name);
8772
+ const found = await layers(kind, name, { root, library, templates: templates2 });
8773
+ if (found.library !== void 0 || found.builtin !== void 0) fail3("UNSAFE_LIBRARY_WRITE", "Project-data writes cannot shadow or reveal a library or built-in entry");
8774
+ if (found.project !== void 0) assertProjectDataContent(kind, found.project);
8775
+ const owned = path8.join(directory, kind, name);
8776
+ const files = await readdir4(owned).catch((error51) => {
8777
+ if (error51.code === "ENOENT") return [];
8778
+ throw error51;
8779
+ });
8780
+ const allowed = new Set(FILES[kind](name).map(([file2]) => path8.basename(file2)));
8781
+ for (const file2 of files) {
8782
+ const info = await lstat3(path8.join(owned, file2));
8783
+ if (!allowed.has(file2) || !info.isFile() || info.isSymbolicLink() || info.nlink !== 1) fail3("UNSAFE_LIBRARY_WRITE", "Project-data entries cannot contain sidecars, links or executable assets");
8784
+ }
8785
+ }
8750
8786
  async function safeEntryPaths(directory, kind, name) {
8751
8787
  for (const [file2] of FILES[kind](name)) {
8752
8788
  await assertNoSymlinks(directory, path8.join(kind, file2));
@@ -8944,9 +8980,13 @@ async function writeAtomic(file2, text) {
8944
8980
  await moveFile(temporary, file2);
8945
8981
  }
8946
8982
  var exists = (target) => stat2(target).then(() => true, () => false);
8947
- async function saveEntry(kind, name, content, { scope, root, library, templates: templates2, revision } = {}) {
8983
+ async function saveEntry(kind, name, content, { scope, root, library, templates: templates2, revision, policy } = {}) {
8948
8984
  kindOf(kind);
8949
8985
  nameOf(name);
8986
+ if (policy === "project-data") {
8987
+ assertProjectDataContent(kind, content);
8988
+ await projectDataEntry(kind, name, { scope, root, library, templates: templates2 });
8989
+ }
8950
8990
  const directory = base(scope, { root, library }, kind);
8951
8991
  await safeEntryPaths(directory, kind, name);
8952
8992
  await check(kind, name, content, { scope, root, library, templates: templates2 });
@@ -8968,9 +9008,10 @@ async function saveEntry(kind, name, content, { scope, root, library, templates:
8968
9008
  }
8969
9009
  return { revision: revisionOf(await readLayer(kind, name, directory)) };
8970
9010
  }
8971
- async function deleteEntry(kind, name, { scope, root, library, templates: templates2, revision } = {}) {
9011
+ async function deleteEntry(kind, name, { scope, root, library, templates: templates2, revision, policy } = {}) {
8972
9012
  kindOf(kind);
8973
9013
  nameOf(name);
9014
+ if (policy === "project-data") await projectDataEntry(kind, name, { scope, root, library, templates: templates2 });
8974
9015
  const directory = base(scope, { root, library }, kind);
8975
9016
  const current = await readLayer(kind, name, directory);
8976
9017
  if (current === void 0) fail3("NOT_FOUND", `No ${kind} entry '${name}' in the ${scope}`);
@@ -8986,14 +9027,25 @@ async function deleteEntry(kind, name, { scope, root, library, templates: templa
8986
9027
  const now2 = scope === "project" && found.library !== void 0 ? "library" : "builtin";
8987
9028
  return { removed: true, ...fallback !== void 0 ? { now: now2 } : {} };
8988
9029
  }
8989
- async function duplicateEntry(kind, from, to, { scope, root, library, templates: templates2 } = {}) {
9030
+ async function duplicateEntry(kind, from, to, { scope, root, library, templates: templates2, policy } = {}) {
9031
+ kindOf(kind);
9032
+ nameOf(from);
9033
+ nameOf(to);
9034
+ if (policy === "project-data") {
9035
+ await projectDataEntry(kind, from, { scope, root, library, templates: templates2 });
9036
+ await projectDataEntry(kind, to, { scope, root, library, templates: templates2 });
9037
+ }
8990
9038
  const { content } = await getEntry(kind, from, { root, library, templates: templates2 });
8991
- return saveEntry(kind, to, structuredClone(content), { scope, root, library, templates: templates2, revision: null });
9039
+ return saveEntry(kind, to, structuredClone(content), { scope, root, library, templates: templates2, revision: null, policy });
8992
9040
  }
8993
- async function renameEntry(kind, from, to, { scope, root, library, templates: templates2 } = {}) {
9041
+ async function renameEntry(kind, from, to, { scope, root, library, templates: templates2, policy } = {}) {
8994
9042
  kindOf(kind);
8995
9043
  nameOf(from);
8996
9044
  nameOf(to);
9045
+ if (policy === "project-data") {
9046
+ await projectDataEntry(kind, from, { scope, root, library, templates: templates2 });
9047
+ await projectDataEntry(kind, to, { scope, root, library, templates: templates2 });
9048
+ }
8997
9049
  const directory = base(scope, { root, library }, kind);
8998
9050
  const content = await readLayer(kind, from, directory);
8999
9051
  if (content === void 0) fail3("NOT_FOUND", `No ${kind} entry '${from}' in the ${scope}`);
@@ -9366,8 +9418,8 @@ async function testEntry(kind, name, { root, library, templates: templates2, sco
9366
9418
  }
9367
9419
 
9368
9420
  // packages/client/src/index.js
9369
- import { createHash as createHash3 } from "node:crypto";
9370
- import { open, readFile as readFile4, realpath, stat as stat3, lstat as lstat3, mkdir as mkdir3, readlink, unlink } from "node:fs/promises";
9421
+ import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
9422
+ import { open, readFile as readFile4, writeFile as writeFile4, realpath, stat as stat3, lstat as lstat4, mkdir as mkdir3, readlink, unlink, readdir as readdir5, rename as rename4, rmdir, link } from "node:fs/promises";
9371
9423
  import net from "node:net";
9372
9424
  import os2 from "node:os";
9373
9425
  import path10 from "node:path";
@@ -9499,7 +9551,7 @@ var AlpRpcError = class extends Error {
9499
9551
  };
9500
9552
  var ERROR = Object.freeze({ failed: 1e3, notFound: 1001, forbidden: 1003, conflict: 1004, unavailable: 1005, protocol: 1006 });
9501
9553
  var RPC_ERROR = Object.freeze({ parseError: -32700, invalidRequest: -32600, methodNotFound: -32601, invalidParams: -32602 });
9502
- var CAPABILITY = Object.freeze({ attachAfter: "attach.after", promptReceipts: "prompt.receipts", extensionMethods: "extension.methods", team: "team", task: "task", library: "library", settingsLanguage: "settings.language", sessionListPage: "session.list.page", questionWatch: "question.watch", questionWatchTurns: "question.watch.turns", workspaceFiles: "workspace.files", workspaceFilesRead: "workspace.files.read", promptImages: "prompt.images" });
9554
+ var CAPABILITY = Object.freeze({ attachAfter: "attach.after", promptReceipts: "prompt.receipts", extensionMethods: "extension.methods", team: "team", task: "task", library: "library", libraryProjectWrite: "library.project.write", settingsLanguage: "settings.language", sessionListPage: "session.list.page", questionWatch: "question.watch", questionWatchTurns: "question.watch.turns", workspaceFiles: "workspace.files", workspaceFilesRead: "workspace.files.read", promptImages: "prompt.images" });
9503
9555
  var PROMPT_IMAGES = Object.freeze({ mimeTypes: Object.freeze(["image/png", "image/jpeg", "image/gif", "image/webp"]), maxCount: 8, maxBytes: 5 * 1024 * 1024, maxTotalBytes: 11 * 1024 * 1024 });
9504
9556
  var RPC_METHODS = Object.freeze(["assignment.recall", "board.list", "catalog.get", "daemon.hello", "daemon.pause", "daemon.pauses", "daemon.resume", "daemon.shutdown", "daemon.status", "daemon.usage", "extension.register", "extension.unregister", "library.delete", "library.duplicate", "library.get", "library.list", "library.models", "library.rename", "library.save", "library.skills.set", "question.answer", "question.list", "question.watch", "session.archive", "session.attach", "session.close", "session.configure", "session.create", "session.get", "session.interrupt", "session.list", "session.log", "session.message", "session.preview", "session.prompt", "session.release", "session.rename", "session.status", "settings.language.get", "settings.language.set", "task.create", "task.gate.resolve", "task.list", "task.update", "team.list", "workspace.files.list", "workspace.files.read", "workspace.files.search"]);
9505
9557
  var WORKSPACE_FILES = Object.freeze({ maxReadBytes: 1024 * 1024, maxListEntries: 1e3, maxPathLength: 4096 });
@@ -9971,7 +10023,7 @@ async function assertSafeAncestors(directory) {
9971
10023
  continue;
9972
10024
  }
9973
10025
  const candidate = path10.join(current, part);
9974
- const info = await lstat3(candidate).catch((error51) => {
10026
+ const info = await lstat4(candidate).catch((error51) => {
9975
10027
  if (error51.code !== "ENOENT") throw error51;
9976
10028
  });
9977
10029
  if (!info) {
@@ -9996,7 +10048,7 @@ async function assertSafeAncestors(directory) {
9996
10048
  async function assertPrivateDirectory(directory, { create = false } = {}) {
9997
10049
  await assertSafeAncestors(directory);
9998
10050
  if (create) await mkdir3(directory, { recursive: true, mode: 448 });
9999
- const info = await lstat3(directory);
10051
+ const info = await lstat4(directory);
10000
10052
  if (!info.isDirectory() || info.isSymbolicLink()) throw new Error("IPC requires a private directory, not a symlink");
10001
10053
  if (process.platform !== "win32" && (info.uid !== process.getuid?.() || (info.mode & 63) !== 0)) {
10002
10054
  throw new Error("IPC directory must be owned by the current user with private permissions (0700)");
@@ -10005,7 +10057,7 @@ async function assertPrivateDirectory(directory, { create = false } = {}) {
10005
10057
  async function assertPrivateSocket(socketPath) {
10006
10058
  if (process.platform === "win32") return;
10007
10059
  await assertPrivateDirectory(path10.dirname(socketPath));
10008
- const info = await lstat3(socketPath);
10060
+ const info = await lstat4(socketPath);
10009
10061
  if (!info.isSocket() || info.uid !== process.getuid?.() || (info.mode & 63) !== 0) {
10010
10062
  throw new Error("IPC socket must be owned by the current user with private permissions (0600)");
10011
10063
  }
@@ -10055,8 +10107,8 @@ async function connect(socketPath, client2 = { name: "alp", version: "0" }, opti
10055
10107
  }
10056
10108
 
10057
10109
  // packages/core/src/user-settings.js
10058
- import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
10059
- import { randomUUID as randomUUID3 } from "node:crypto";
10110
+ import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
10111
+ import { randomUUID as randomUUID4 } from "node:crypto";
10060
10112
  import path11 from "node:path";
10061
10113
  var DEFAULT_LANGUAGE = "Vietnamese";
10062
10114
  var LANGUAGE_CHARS = 40;
@@ -10092,8 +10144,8 @@ async function setLanguage(home, language) {
10092
10144
  else next.language = language.trim();
10093
10145
  validateUserSettings(next, file2);
10094
10146
  await mkdir4(home, { recursive: true, mode: 448 });
10095
- const temporary = `${file2}.${randomUUID3().slice(0, 8)}.tmp`;
10096
- await writeFile4(temporary, JSON.stringify(next, null, 2) + "\n");
10147
+ const temporary = `${file2}.${randomUUID4().slice(0, 8)}.tmp`;
10148
+ await writeFile5(temporary, JSON.stringify(next, null, 2) + "\n");
10097
10149
  await moveFile(temporary, file2);
10098
10150
  return languageSetting(home);
10099
10151
  }
@@ -10105,8 +10157,8 @@ var templates_default = { "ALP.md": "# ALP project instructions\n\n## Working re
10105
10157
  var PIN_KINDS = ["claim", "decision", "finding"];
10106
10158
 
10107
10159
  // packages/core/src/tasks.js
10108
- import { mkdir as mkdir5, readFile as readFile6, readdir as readdir4, rmdir, stat as stat4, writeFile as writeFile5 } from "node:fs/promises";
10109
- import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
10160
+ import { mkdir as mkdir5, readFile as readFile6, readdir as readdir6, rmdir as rmdir2, stat as stat4, writeFile as writeFile6 } from "node:fs/promises";
10161
+ import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
10110
10162
  import path12 from "node:path";
10111
10163
  var TASKS_DIR = ".alp/tasks";
10112
10164
  var TASK_TYPES = ["task", "bug", "feature", "chore", "epic"];
@@ -10139,7 +10191,7 @@ async function taskNames(projectRoot) {
10139
10191
  await assertNoSymlinks(scope, "tasks");
10140
10192
  let names;
10141
10193
  try {
10142
- names = await readdir4(tasksDir(projectRoot));
10194
+ names = await readdir6(tasksDir(projectRoot));
10143
10195
  } catch (error51) {
10144
10196
  if (error51.code === "ENOENT") return [];
10145
10197
  throw error51;
@@ -10309,7 +10361,7 @@ async function locked(projectRoot, work) {
10309
10361
  if (error51.code !== "EEXIST") throw error51;
10310
10362
  const age = await stat4(lock).then((info) => Date.now() - info.mtimeMs, () => 0);
10311
10363
  if (age > LOCK_STALE_MS) {
10312
- await rmdir(lock).catch(() => {
10364
+ await rmdir2(lock).catch(() => {
10313
10365
  });
10314
10366
  continue;
10315
10367
  }
@@ -10320,7 +10372,7 @@ async function locked(projectRoot, work) {
10320
10372
  try {
10321
10373
  return await work();
10322
10374
  } finally {
10323
- await rmdir(lock).catch(() => {
10375
+ await rmdir2(lock).catch(() => {
10324
10376
  });
10325
10377
  }
10326
10378
  });
@@ -10329,15 +10381,15 @@ async function locked(projectRoot, work) {
10329
10381
  }
10330
10382
  async function prepare(dir) {
10331
10383
  await mkdir5(dir, { recursive: true });
10332
- await writeFile5(path12.join(dir, ".gitignore"), GITIGNORE, { flag: "wx" }).catch((error51) => {
10384
+ await writeFile6(path12.join(dir, ".gitignore"), GITIGNORE, { flag: "wx" }).catch((error51) => {
10333
10385
  if (error51.code !== "EEXIST") throw error51;
10334
10386
  });
10335
10387
  }
10336
10388
  async function save(projectRoot, task) {
10337
10389
  const file2 = taskFile(projectRoot, task.id);
10338
10390
  await assertNoSymlinks(path12.join(path12.resolve(projectRoot), ".alp"), path12.join("tasks", `${task.id}.json`));
10339
- const temporary = `${file2}.${randomUUID4().slice(0, 8)}.tmp`;
10340
- await writeFile5(temporary, JSON.stringify(task, null, 2) + "\n");
10391
+ const temporary = `${file2}.${randomUUID5().slice(0, 8)}.tmp`;
10392
+ await writeFile6(temporary, JSON.stringify(task, null, 2) + "\n");
10341
10393
  await moveFile(temporary, file2);
10342
10394
  return task;
10343
10395
  }
@@ -10348,7 +10400,7 @@ function newId(tasks, title, parent) {
10348
10400
  const used = tasks.filter((task) => task.id.startsWith(prefix) && !task.id.slice(prefix.length).includes(".")).map((task) => Number(task.id.slice(prefix.length)));
10349
10401
  return `${prefix}${Math.max(0, ...used) + 1}`;
10350
10402
  }
10351
- const hash2 = createHash4("sha256").update(`${title}\0${now()}\0${randomUUID4()}`).digest("hex");
10403
+ const hash2 = createHash4("sha256").update(`${title}\0${now()}\0${randomUUID5()}`).digest("hex");
10352
10404
  for (let length = 4; length <= 12; length++) if (!taken.has(`t-${hash2.slice(0, length)}`)) return `t-${hash2.slice(0, length)}`;
10353
10405
  return fail4("INVALID_TASK", "Could not choose a free task id");
10354
10406
  }
@@ -25069,12 +25121,14 @@ var toolShapes = {
25069
25121
  body: external_exports.string().min(1).max(2e4),
25070
25122
  roles: external_exports.array(external_exports.string().min(1)).min(1).max(10),
25071
25123
  lessons: external_exports.array(external_exports.string().min(1).max(600)).max(50).optional(),
25072
- replace: external_exports.boolean().optional()
25124
+ replace: external_exports.boolean().optional(),
25125
+ requestId: external_exports.string().min(1).max(100).optional()
25073
25126
  },
25074
25127
  alp_issue: {
25075
25128
  action: external_exports.enum(["search", "create", "comment"]),
25076
25129
  target: external_exports.enum(["project", "alp"]),
25077
25130
  query: external_exports.string().min(1).max(200).optional(),
25131
+ requestId: external_exports.string().min(1).max(100).optional(),
25078
25132
  title: external_exports.string().min(1).max(200).optional(),
25079
25133
  body: external_exports.string().min(1).max(2e4).optional(),
25080
25134
  issue: external_exports.number().int().positive().optional(),
@@ -27284,7 +27338,9 @@ var libraryGet = defineRpc2({
27284
27338
  revision: external_exports.string().nullable(),
27285
27339
  usedBy: external_exports.array(external_exports.string()),
27286
27340
  /** Agents: the skills the library gives it by name (role-skills.json). */
27287
- librarySkills: external_exports.array(external_exports.string()).optional()
27341
+ librarySkills: external_exports.array(external_exports.string()).optional(),
27342
+ /** ALP remote mode: JSON Pointers of the values `content` holds as a secret marker, not as the value. */
27343
+ secrets: external_exports.array(external_exports.string()).optional()
27288
27344
  })
27289
27345
  });
27290
27346
  var librarySkills2 = defineRpc2({