@adminide-stack/yantra-mobile 12.0.133 → 12.0.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/lib/features/apps/nativeAppHandoff.js +26 -2
  2. package/lib/features/apps/nativeAppHandoff.js.map +1 -1
  3. package/lib/features/chat/askUser.js +8 -1
  4. package/lib/features/chat/askUser.js.map +1 -1
  5. package/lib/features/chat/toolActivity.js +4 -2
  6. package/lib/features/chat/toolActivity.js.map +1 -1
  7. package/lib/features/webbuilder/components/ProjectChat.js +4 -1
  8. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  9. package/lib/hooks/useCdecliChannel.js +1 -1
  10. package/lib/hooks/useCdecliChannel.js.map +1 -1
  11. package/lib/hooks/useChatStream.js +15 -1
  12. package/lib/hooks/useChatStream.js.map +1 -1
  13. package/lib/screens/Chat/index.js +23 -2
  14. package/lib/screens/Chat/index.js.map +1 -1
  15. package/lib/screens/ChatHistory/index.js +18 -5
  16. package/lib/screens/ChatHistory/index.js.map +1 -1
  17. package/lib/screens/Home/components/ChatHistoryLanding.js +4 -2
  18. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  19. package/lib/screens/WebBuilderNative/runningBuilds.js +4 -1
  20. package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -1
  21. package/lib/screens/WebBuilderNative/siteLane.js +5 -0
  22. package/lib/screens/WebBuilderNative/siteLane.js.map +1 -0
  23. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +42 -2
  24. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
  25. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +54 -15
  26. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  27. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +1 -0
  28. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  29. package/package.json +2 -2
@@ -2,8 +2,32 @@ import {classifyIntentViaBrain}from'../../services/brainQuickReply.js';const NAT
2
2
  "local-services": "MainStack.LocalServicesNative",
3
3
  movies: "MainStack.MoviesNative",
4
4
  expenses: "MainStack.ExpensesNative",
5
- webbuilder: "MainStack.WebBuilderNative"
5
+ webbuilder: "MainStack.WebBuilderNative",
6
+ travel: "MainStack.TravelNative",
7
+ jobSearch: "MainStack.JobSearchNative",
8
+ resume: "MainStack.ResumeNative",
9
+ inbox: "MainStack.InboxNative",
10
+ notebook: "MainStack.StudyNative"
6
11
  };
12
+ const NATIVE_APP_CONNECTORS = {
13
+ "yantra-webbuilder": NATIVE_APP_ROUTES.webbuilder,
14
+ "yantra-flight-search": NATIVE_APP_ROUTES.travel,
15
+ "yantra-resortifi": NATIVE_APP_ROUTES.travel,
16
+ "yantra-job-search": NATIVE_APP_ROUTES.jobSearch,
17
+ "yantra-resume-builder": NATIVE_APP_ROUTES.resume,
18
+ "yantra-mailer-inbox": NATIVE_APP_ROUTES.inbox,
19
+ "yantra-notebook": NATIVE_APP_ROUTES.notebook,
20
+ "yantra-local-services": NATIVE_APP_ROUTES["local-services"],
21
+ "yantra-movies": NATIVE_APP_ROUTES.movies,
22
+ "yantra-expenses": NATIVE_APP_ROUTES.expenses
23
+ };
24
+ function nativeRouteForConnectors(connectors) {
25
+ for (const connector of connectors) {
26
+ const route = connector ? NATIVE_APP_CONNECTORS[connector] : void 0;
27
+ if (route) return route;
28
+ }
29
+ return null;
30
+ }
7
31
  const HANDOFF_MIN_CONFIDENCE = 0.8;
8
32
  const FOLLOWUP_HANDOFF_MIN_CONFIDENCE = 0.95;
9
33
  const CLASSIFY_TIMEOUT_MS = 2e3;
@@ -44,4 +68,4 @@ async function resolveNativeHandoff(text, opts) {
44
68
  } catch (e) {
45
69
  return null;
46
70
  }
47
- }export{FOLLOWUP_HANDOFF_MIN_CONFIDENCE,HANDOFF_MIN_CONFIDENCE,NATIVE_APP_ROUTES,classifyTypedAsk,nativeHandoffRoute,resolveNativeHandoff};//# sourceMappingURL=nativeAppHandoff.js.map
71
+ }export{FOLLOWUP_HANDOFF_MIN_CONFIDENCE,HANDOFF_MIN_CONFIDENCE,NATIVE_APP_CONNECTORS,NATIVE_APP_ROUTES,classifyTypedAsk,nativeHandoffRoute,nativeRouteForConnectors,resolveNativeHandoff};//# sourceMappingURL=nativeAppHandoff.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativeAppHandoff.js","sources":["../../../src/features/apps/nativeAppHandoff.ts"],"sourcesContent":["/**\n * A typed ask the brain routes to an app that has a native screen here opens\n * that screen, with the ask handed to its agent.\n *\n * The decision is the brain's: the same `yantra-brain` classify the web chat\n * runs (`/resources/yantra-brain-classify`, whose intent ids are the web\n * registry's app ids), gated the way the web intent router gates it - a first\n * turn needs the app's ordinary bar, a follow-up in a conversation needs\n * near-certainty. Nothing here reads the words of the ask. Opening the screen\n * is nativeAppNavigation's job, kept apart so this stays free of navigation.\n */\nimport { classifyIntentViaBrain, type BrainIntent } from '../../services/brainQuickReply';\n\n/** Brain intent (web registry app id) -> the native screen that serves it on the phone. */\nexport const NATIVE_APP_ROUTES: Readonly<Record<string, string>> = {\n 'local-services': 'MainStack.LocalServicesNative',\n movies: 'MainStack.MoviesNative',\n expenses: 'MainStack.ExpensesNative',\n webbuilder: 'MainStack.WebBuilderNative',\n};\n\n/** The web router's DEFAULT_MIN_CONFIDENCE and FOLLOWUP_MIN_CONFIDENCE (services/intentRouter.ts). */\nexport const HANDOFF_MIN_CONFIDENCE = 0.8;\nexport const FOLLOWUP_HANDOFF_MIN_CONFIDENCE = 0.95;\n\nconst CLASSIFY_TIMEOUT_MS = 2000;\nconst SHARED_FOR_MS = 30_000;\n\n/** The native route a classification opens, or null when it names no native app or is not sure enough. */\nexport function nativeHandoffRoute(intent: BrainIntent | null, opts: { followUp?: boolean } = {}): string | null {\n if (!intent) return null;\n const route = NATIVE_APP_ROUTES[intent.intent];\n if (!route || typeof intent.confidence !== 'number') return null;\n const bar = opts.followUp ? FOLLOWUP_HANDOFF_MIN_CONFIDENCE : HANDOFF_MIN_CONFIDENCE;\n return intent.confidence >= bar ? route : null;\n}\n\nconst shared = new Map<string, { at: number; verdict: Promise<BrainIntent | null> }>();\n\n/**\n * One brain classification per typed ask, shared by every hand-off check that\n * turn (Shop's and this one), so asking twice costs one request.\n */\nexport function classifyTypedAsk(text: string, now = Date.now()): Promise<BrainIntent | null> {\n const key = text.trim();\n if (!key) return Promise.resolve(null);\n for (const [k, entry] of shared) if (now - entry.at > SHARED_FOR_MS) shared.delete(k);\n const hit = shared.get(key);\n if (hit) return hit.verdict;\n const verdict = classifyIntentViaBrain(key, { timeoutMs: CLASSIFY_TIMEOUT_MS }).catch(() => null);\n const entry = { at: now, verdict };\n shared.set(key, entry);\n // A timeout or a failed call is not a verdict: the next check asks again.\n void verdict.then((answer) => {\n if (!answer && shared.get(key) === entry) shared.delete(key);\n });\n return verdict;\n}\n\n/** TEST-ONLY */\nexport function __resetTypedAskCache(): void {\n shared.clear();\n}\n\n/**\n * The native screen a typed ask belongs on, or null to keep it in chat. Build\n * and deep-search turns are modes the person chose, so they never leave chat.\n */\nexport async function resolveNativeHandoff(\n text: string,\n opts: { mode: 'chat' | 'deep-search' | 'build'; followUp?: boolean },\n): Promise<string | null> {\n if (opts.mode !== 'chat' || !text.trim()) return null;\n try {\n return nativeHandoffRoute(await classifyTypedAsk(text), { followUp: opts.followUp });\n } catch {\n return null;\n }\n}\n"],"names":["entry"],"mappings":"uEAcO,MAAM,iBAAsD,GAAA;AAAA,EACjE,gBAAkB,EAAA,+BAAA;AAAA,EAClB,MAAQ,EAAA,wBAAA;AAAA,EACR,QAAU,EAAA,0BAAA;AAAA,EACV,UAAY,EAAA;AACd;AAGO,MAAM,sBAAyB,GAAA;AAC/B,MAAM,+BAAkC,GAAA;AAC/C,MAAM,mBAAsB,GAAA,GAAA;AAC5B,MAAM,aAAgB,GAAA,GAAA;AAGf,SAAS,kBAAmB,CAAA,MAAA,EAA4B,IAE3D,GAAA,EAAmB,EAAA;AACrB,EAAI,IAAA,CAAC,QAAe,OAAA,IAAA;AACpB,EAAM,MAAA,KAAA,GAAQ,iBAAkB,CAAA,MAAA,CAAO,MAAM,CAAA;AAC7C,EAAA,IAAI,CAAC,KAAS,IAAA,OAAO,MAAO,CAAA,UAAA,KAAe,UAAiB,OAAA,IAAA;AAC5D,EAAM,MAAA,GAAA,GAAM,IAAK,CAAA,QAAA,GAAW,+BAAkC,GAAA,sBAAA;AAC9D,EAAO,OAAA,MAAA,CAAO,UAAc,IAAA,GAAA,GAAM,KAAQ,GAAA,IAAA;AAC5C;AACA,MAAM,MAAA,uBAAa,GAGhB,EAAA;AAMI,SAAS,gBAAiB,CAAA,IAAA,EAAc,GAAM,GAAA,IAAA,CAAK,KAAoC,EAAA;AAC5F,EAAM,MAAA,GAAA,GAAM,KAAK,IAAK,EAAA;AACtB,EAAA,IAAI,CAAC,GAAA,EAAY,OAAA,OAAA,CAAQ,QAAQ,IAAI,CAAA;AACrC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAGA,MAAK,CAAA,IAAK,MAAQ,EAAA,IAAI,GAAMA,GAAAA,MAAAA,CAAM,EAAK,GAAA,aAAA,EAAsB,MAAA,CAAA,MAAA,CAAO,CAAC,CAAA;AACpF,EAAM,MAAA,GAAA,GAAM,MAAO,CAAA,GAAA,CAAI,GAAG,CAAA;AAC1B,EAAI,IAAA,GAAA,SAAY,GAAI,CAAA,OAAA;AACpB,EAAM,MAAA,OAAA,GAAU,uBAAuB,GAAK,EAAA;AAAA,IAC1C,SAAW,EAAA;AAAA,GACZ,CAAA,CAAE,KAAM,CAAA,MAAM,IAAI,CAAA;AACnB,EAAA,MAAM,KAAQ,GAAA;AAAA,IACZ,EAAI,EAAA,GAAA;AAAA,IACJ;AAAA,GACF;AACA,EAAO,MAAA,CAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AAErB,EAAK,KAAA,OAAA,CAAQ,KAAK,CAAU,MAAA,KAAA;AAC1B,IAAI,IAAA,CAAC,UAAU,MAAO,CAAA,GAAA,CAAI,GAAG,CAAM,KAAA,KAAA,EAAc,MAAA,CAAA,MAAA,CAAO,GAAG,CAAA;AAAA,GAC5D,CAAA;AACD,EAAO,OAAA,OAAA;AACT;AAWsB,eAAA,oBAAA,CAAqB,MAAc,IAG9B,EAAA;AACzB,EAAA,IAAI,KAAK,IAAS,KAAA,MAAA,IAAU,CAAC,IAAK,CAAA,IAAA,IAAe,OAAA,IAAA;AACjD,EAAI,IAAA;AACF,IAAA,OAAO,kBAAmB,CAAA,MAAM,gBAAiB,CAAA,IAAI,CAAG,EAAA;AAAA,MACtD,UAAU,IAAK,CAAA;AAAA,KAChB,CAAA;AAAA,GACK,CAAA,OAAA,CAAA,EAAA;AACN,IAAO,OAAA,IAAA;AAAA;AAEX"}
1
+ {"version":3,"file":"nativeAppHandoff.js","sources":["../../../src/features/apps/nativeAppHandoff.ts"],"sourcesContent":["/**\n * A typed ask the brain routes to an app that has a native screen here opens\n * that screen, with the ask handed to its agent.\n *\n * The decision is the brain's: the same `yantra-brain` classify the web chat\n * runs (`/resources/yantra-brain-classify`, whose intent ids are the web\n * registry's app ids), gated the way the web intent router gates it - a first\n * turn needs the app's ordinary bar, a follow-up in a conversation needs\n * near-certainty. Nothing here reads the words of the ask. Opening the screen\n * is nativeAppNavigation's job, kept apart so this stays free of navigation.\n */\nimport { classifyIntentViaBrain, type BrainIntent } from '../../services/brainQuickReply';\n\n/**\n * Brain intent (web registry app id, `FEATURE_ROUTING` key) -> the native screen\n * that serves it on the phone. Every native app whose screen takes a handed-off\n * ask (`initialAgentQuery`) is here; Shop has its own hand-off (openShopNative).\n */\nexport const NATIVE_APP_ROUTES: Readonly<Record<string, string>> = {\n 'local-services': 'MainStack.LocalServicesNative',\n movies: 'MainStack.MoviesNative',\n expenses: 'MainStack.ExpensesNative',\n webbuilder: 'MainStack.WebBuilderNative',\n travel: 'MainStack.TravelNative',\n jobSearch: 'MainStack.JobSearchNative',\n resume: 'MainStack.ResumeNative',\n inbox: 'MainStack.InboxNative',\n notebook: 'MainStack.StudyNative',\n};\n\n/**\n * Connector -> the native screen whose agent works it. When the brain missed\n * an ask and the chat's own agent starts on one of these, the turn belongs in\n * that app (Chat hands it over mid-turn; see nativeRouteForConnectors).\n */\nexport const NATIVE_APP_CONNECTORS: Readonly<Record<string, string>> = {\n 'yantra-webbuilder': NATIVE_APP_ROUTES.webbuilder,\n 'yantra-flight-search': NATIVE_APP_ROUTES.travel,\n 'yantra-resortifi': NATIVE_APP_ROUTES.travel,\n 'yantra-job-search': NATIVE_APP_ROUTES.jobSearch,\n 'yantra-resume-builder': NATIVE_APP_ROUTES.resume,\n 'yantra-mailer-inbox': NATIVE_APP_ROUTES.inbox,\n 'yantra-notebook': NATIVE_APP_ROUTES.notebook,\n 'yantra-local-services': NATIVE_APP_ROUTES['local-services'],\n 'yantra-movies': NATIVE_APP_ROUTES.movies,\n 'yantra-expenses': NATIVE_APP_ROUTES.expenses,\n};\n\n/** The native screen for the first app connector a turn ran on, or null when it ran on none. */\nexport function nativeRouteForConnectors(connectors: Iterable<string | null | undefined>): string | null {\n for (const connector of connectors) {\n const route = connector ? NATIVE_APP_CONNECTORS[connector] : undefined;\n if (route) return route;\n }\n return null;\n}\n\n/** The web router's DEFAULT_MIN_CONFIDENCE and FOLLOWUP_MIN_CONFIDENCE (services/intentRouter.ts). */\nexport const HANDOFF_MIN_CONFIDENCE = 0.8;\nexport const FOLLOWUP_HANDOFF_MIN_CONFIDENCE = 0.95;\n\nconst CLASSIFY_TIMEOUT_MS = 2000;\nconst SHARED_FOR_MS = 30_000;\n\n/** The native route a classification opens, or null when it names no native app or is not sure enough. */\nexport function nativeHandoffRoute(intent: BrainIntent | null, opts: { followUp?: boolean } = {}): string | null {\n if (!intent) return null;\n const route = NATIVE_APP_ROUTES[intent.intent];\n if (!route || typeof intent.confidence !== 'number') return null;\n const bar = opts.followUp ? FOLLOWUP_HANDOFF_MIN_CONFIDENCE : HANDOFF_MIN_CONFIDENCE;\n return intent.confidence >= bar ? route : null;\n}\n\nconst shared = new Map<string, { at: number; verdict: Promise<BrainIntent | null> }>();\n\n/**\n * One brain classification per typed ask, shared by every hand-off check that\n * turn (Shop's and this one), so asking twice costs one request.\n */\nexport function classifyTypedAsk(text: string, now = Date.now()): Promise<BrainIntent | null> {\n const key = text.trim();\n if (!key) return Promise.resolve(null);\n for (const [k, entry] of shared) if (now - entry.at > SHARED_FOR_MS) shared.delete(k);\n const hit = shared.get(key);\n if (hit) return hit.verdict;\n const verdict = classifyIntentViaBrain(key, { timeoutMs: CLASSIFY_TIMEOUT_MS }).catch(() => null);\n const entry = { at: now, verdict };\n shared.set(key, entry);\n // A timeout or a failed call is not a verdict: the next check asks again.\n void verdict.then((answer) => {\n if (!answer && shared.get(key) === entry) shared.delete(key);\n });\n return verdict;\n}\n\n/** TEST-ONLY */\nexport function __resetTypedAskCache(): void {\n shared.clear();\n}\n\n/**\n * The native screen a typed ask belongs on, or null to keep it in chat. Build\n * and deep-search turns are modes the person chose, so they never leave chat.\n */\nexport async function resolveNativeHandoff(\n text: string,\n opts: { mode: 'chat' | 'deep-search' | 'build'; followUp?: boolean },\n): Promise<string | null> {\n if (opts.mode !== 'chat' || !text.trim()) return null;\n try {\n return nativeHandoffRoute(await classifyTypedAsk(text), { followUp: opts.followUp });\n } catch {\n return null;\n }\n}\n"],"names":["entry"],"mappings":"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"}
@@ -123,10 +123,17 @@ function pendingAskUser(messages) {
123
123
  const msg = messages[i];
124
124
  if (msg.role === "user") return null;
125
125
  const parsed = msg.role === "assistant" ? parseAskUser(msg.content) : null;
126
- if (parsed) return parsed;
126
+ if (parsed) return answeredAnywhere(parsed, messages) ? null : parsed;
127
127
  }
128
128
  return null;
129
129
  }
130
+ function answeredAnywhere(ask, messages) {
131
+ const prefixes = ask.questions.map((q) => `**${q.title.replace(/:\s*$/, "")}:**`);
132
+ return messages.some((m) => m.role === "user" && prefixes.some((prefix) => {
133
+ var _a;
134
+ return ((_a = m.content) != null ? _a : "").includes(prefix);
135
+ }));
136
+ }
130
137
  function formatAskUserAnswers(questions, answers) {
131
138
  return questions.map((q) => {
132
139
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"askUser.js","sources":["../../../src/features/chat/askUser.ts"],"sourcesContent":["/**\n * The `[ASK_USER]` clarifying-question protocol, mobile side (Clockbook #1643).\n *\n * cdecli emits the block itself — from Claude's AskUserQuestion and its own\n * ask_user_question tool — and PARKS the run until the answer arrives:\n *\n * [ASK_USER]{\"requestId\":\"ask-…\",\"questions\":[{\"id\":\"q1\",\"title\":\"Which\n * database?\",\"header\":\"Database\",\"options\":[{\"id\":\"o1\",\"label\":\"Postgres\",\n * \"detail\":\"…\"}],\"allowText\":true}]}[/ASK_USER]\n *\n * The reply is deliberately NOT a marker: answers are formatted into one visible\n * user message (`**Title:** answer` lines) and sent through the normal chat path,\n * so the producer needs no reply-protocol support. Only the question side is\n * structured.\n *\n * Deliberately a copy of the web's `responsePromptProtocol` rather than an\n * import — mobile is a separate bundle and shares no code with the web shell.\n * The reply side is plain text, so the two stay compatible without a shared\n * version.\n */\n\nexport interface AskUserOption {\n id: string;\n label: string;\n /** Secondary line under the label. */\n detail?: string;\n /** \"Something else\": focuses the free-text row instead of answering. */\n other?: boolean;\n}\n\nexport interface AskUserQuestion {\n id: string;\n /** Also the bold prefix of the formatted answer. */\n title: string;\n /** Short category eyebrow above the title, e.g. \"Database\". */\n header?: string;\n options?: AskUserOption[];\n /** Show the free-text row (default true). */\n allowText?: boolean;\n textPlaceholder?: string;\n /** Pick several options; the answer is sent as comma-joined labels. */\n multiSelect?: boolean;\n}\n\nexport interface AskUserPayload {\n requestId: string;\n questions: AskUserQuestion[];\n}\n\n/** Anything longer is a form, not a prompt — the web caps it the same way. */\nexport const MAX_ASK_USER_QUESTIONS = 4;\n\n// Not anchored: the channel layer may prepend a stream envelope or cost banner.\nconst ASK_USER_RE = /\\[ASK_USER\\]([\\s\\S]*?)\\[\\/ASK_USER\\]/;\nconst ASK_USER_OPEN_RE = /\\[ASK_USER\\]/;\n\nfunction unwrapJsonCandidate(inner: string): string {\n let s = inner.trim();\n const fence = /^```(?:json)?\\s*([\\s\\S]*?)\\s*```$/i.exec(s);\n if (fence) s = fence[1].trim();\n return s;\n}\n\n/** First complete `{...}` object in `s`, or null while the JSON is still streaming. */\nfunction parseJsonObject(s: string): unknown | null {\n const start = s.indexOf('{');\n if (start < 0) return null;\n let depth = 0;\n let inStr = false;\n let esc = false;\n for (let i = start; i < s.length; i++) {\n const c = s[i];\n if (inStr) {\n if (esc) {\n esc = false;\n continue;\n }\n if (c === '\\\\') {\n esc = true;\n continue;\n }\n if (c === '\"') inStr = false;\n continue;\n }\n if (c === '\"') {\n inStr = true;\n continue;\n }\n if (c === '{') depth += 1;\n else if (c === '}') {\n depth -= 1;\n if (depth === 0) {\n try {\n return JSON.parse(s.slice(start, i + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\nfunction normalizeQuestion(raw: unknown): AskUserQuestion | null {\n if (!raw || typeof raw !== 'object') return null;\n const q = raw as Record<string, unknown>;\n const id = typeof q.id === 'string' ? q.id : '';\n const title = typeof q.title === 'string' ? q.title : typeof q.question === 'string' ? q.question : '';\n if (!id || !title.trim()) return null;\n const options = Array.isArray(q.options)\n ? q.options.filter(\n (o): o is AskUserOption =>\n !!o &&\n typeof o === 'object' &&\n typeof (o as AskUserOption).id === 'string' &&\n typeof (o as AskUserOption).label === 'string',\n )\n : undefined;\n return {\n id,\n title: title.trim(),\n header: typeof q.header === 'string' ? q.header : undefined,\n options,\n allowText: q.allowText !== false,\n textPlaceholder: typeof q.textPlaceholder === 'string' ? q.textPlaceholder : undefined,\n multiSelect: q.multiSelect === true,\n };\n}\n\n/** Parse an `[ASK_USER]…[/ASK_USER]` message, or null if it isn't one. */\nexport function parseAskUser(raw: string | null | undefined): AskUserPayload | null {\n if (!raw?.trim()) return null;\n const tagged = ASK_USER_RE.exec(raw) ?? (ASK_USER_OPEN_RE.test(raw) ? /\\[ASK_USER\\]([\\s\\S]*)$/.exec(raw) : null);\n if (!tagged) return null;\n const parsed = parseJsonObject(unwrapJsonCandidate(tagged[1]));\n if (!parsed || typeof parsed !== 'object') return null;\n const body = parsed as { requestId?: unknown; questions?: unknown };\n if (typeof body.requestId !== 'string' || !Array.isArray(body.questions)) return null;\n const questions = body.questions\n .map(normalizeQuestion)\n .filter((q): q is AskUserQuestion => q !== null)\n .slice(0, MAX_ASK_USER_QUESTIONS);\n return questions.length ? { requestId: body.requestId, questions } : null;\n}\n\n/**\n * Remove every `[ASK_USER]` block, leaving the rest of the message intact.\n *\n * cdecli emits the block MID-turn and keeps streaming its reply into the SAME\n * message once the answer releases the parked run, so the block and the reply it\n * was asked for share one message. Hiding the whole message — which is what a\n * naive implementation does — would swallow that reply.\n *\n * An unclosed `[ASK_USER]` (still streaming) is also stripped so the raw JSON\n * never paints in the bubble the way it does on web after `stripAskUser`.\n */\nexport function stripAskUser(raw: string | null | undefined): string {\n if (!raw) return '';\n let stripped = raw.replace(new RegExp(ASK_USER_RE.source, 'g'), '');\n stripped = stripped.replace(/\\[ASK_USER\\][\\s\\S]*$/, '');\n if (stripped === raw) return raw;\n return stripped.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * Text around an `[ASK_USER]` marker. cdecli often speaks an intro *before* the\n * card (\"I'll need a couple more details…\") and streams the real reply *after*\n * the user answers. Once there is a user reply, the intro is stale.\n */\nexport function splitAskUserParts(raw: string | null | undefined): {\n before: string;\n after: string;\n hasMarker: boolean;\n} {\n if (!raw) return { before: '', after: '', hasMarker: false };\n const tagged = ASK_USER_RE.exec(raw);\n if (tagged && tagged.index !== undefined) {\n return {\n before: raw.slice(0, tagged.index).trim(),\n after: raw.slice(tagged.index + tagged[0].length).trim(),\n hasMarker: true,\n };\n }\n const open = raw.search(ASK_USER_OPEN_RE);\n if (open >= 0) {\n return { before: raw.slice(0, open).trim(), after: '', hasMarker: true };\n }\n return { before: '', after: '', hasMarker: false };\n}\n\n/**\n * Assistant prose to paint. After the user answers the card, drop the intro that\n * sat above `[ASK_USER]` so we don't re-ask for details already in the thread.\n */\nexport function displayAskUserAssistantText(raw: string | null | undefined, answered: boolean): string {\n const parts = splitAskUserParts(raw);\n if (!parts.hasMarker) return stripAskUser(raw);\n const keep = answered ? parts.after : [parts.before, parts.after].filter(Boolean).join('\\n\\n');\n return stripAskUser(keep || (answered ? '' : parts.before));\n}\n\n/**\n * The question still awaiting an answer: the last assistant block, unless the\n * user has already replied after it. Scanning backwards means a stale card from\n * earlier in the thread never reappears.\n */\nexport function pendingAskUser(messages: ReadonlyArray<{ role: string; content: string }>): AskUserPayload | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const parsed = msg.role === 'assistant' ? parseAskUser(msg.content) : null;\n if (parsed) return parsed;\n }\n return null;\n}\n\n/**\n * Fold the answers into the single visible reply message:\n *\n * **Which database?:** Postgres\n *\n * Skipped questions are omitted; an empty result means \"nothing to send\", which\n * the card treats as a dismiss.\n */\nexport function formatAskUserAnswers(questions: readonly AskUserQuestion[], answers: Record<string, string>): string {\n return questions\n .map((q) => {\n const answer = answers[q.id]?.trim();\n return answer ? `**${q.title.replace(/:\\s*$/, '')}:** ${answer}` : null;\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"askUser.js","sources":["../../../src/features/chat/askUser.ts"],"sourcesContent":["/**\n * The `[ASK_USER]` clarifying-question protocol, mobile side (Clockbook #1643).\n *\n * cdecli emits the block itself — from Claude's AskUserQuestion and its own\n * ask_user_question tool — and PARKS the run until the answer arrives:\n *\n * [ASK_USER]{\"requestId\":\"ask-…\",\"questions\":[{\"id\":\"q1\",\"title\":\"Which\n * database?\",\"header\":\"Database\",\"options\":[{\"id\":\"o1\",\"label\":\"Postgres\",\n * \"detail\":\"…\"}],\"allowText\":true}]}[/ASK_USER]\n *\n * The reply is deliberately NOT a marker: answers are formatted into one visible\n * user message (`**Title:** answer` lines) and sent through the normal chat path,\n * so the producer needs no reply-protocol support. Only the question side is\n * structured.\n *\n * Deliberately a copy of the web's `responsePromptProtocol` rather than an\n * import — mobile is a separate bundle and shares no code with the web shell.\n * The reply side is plain text, so the two stay compatible without a shared\n * version.\n */\n\nexport interface AskUserOption {\n id: string;\n label: string;\n /** Secondary line under the label. */\n detail?: string;\n /** \"Something else\": focuses the free-text row instead of answering. */\n other?: boolean;\n}\n\nexport interface AskUserQuestion {\n id: string;\n /** Also the bold prefix of the formatted answer. */\n title: string;\n /** Short category eyebrow above the title, e.g. \"Database\". */\n header?: string;\n options?: AskUserOption[];\n /** Show the free-text row (default true). */\n allowText?: boolean;\n textPlaceholder?: string;\n /** Pick several options; the answer is sent as comma-joined labels. */\n multiSelect?: boolean;\n}\n\nexport interface AskUserPayload {\n requestId: string;\n questions: AskUserQuestion[];\n}\n\n/** Anything longer is a form, not a prompt — the web caps it the same way. */\nexport const MAX_ASK_USER_QUESTIONS = 4;\n\n// Not anchored: the channel layer may prepend a stream envelope or cost banner.\nconst ASK_USER_RE = /\\[ASK_USER\\]([\\s\\S]*?)\\[\\/ASK_USER\\]/;\nconst ASK_USER_OPEN_RE = /\\[ASK_USER\\]/;\n\nfunction unwrapJsonCandidate(inner: string): string {\n let s = inner.trim();\n const fence = /^```(?:json)?\\s*([\\s\\S]*?)\\s*```$/i.exec(s);\n if (fence) s = fence[1].trim();\n return s;\n}\n\n/** First complete `{...}` object in `s`, or null while the JSON is still streaming. */\nfunction parseJsonObject(s: string): unknown | null {\n const start = s.indexOf('{');\n if (start < 0) return null;\n let depth = 0;\n let inStr = false;\n let esc = false;\n for (let i = start; i < s.length; i++) {\n const c = s[i];\n if (inStr) {\n if (esc) {\n esc = false;\n continue;\n }\n if (c === '\\\\') {\n esc = true;\n continue;\n }\n if (c === '\"') inStr = false;\n continue;\n }\n if (c === '\"') {\n inStr = true;\n continue;\n }\n if (c === '{') depth += 1;\n else if (c === '}') {\n depth -= 1;\n if (depth === 0) {\n try {\n return JSON.parse(s.slice(start, i + 1));\n } catch {\n return null;\n }\n }\n }\n }\n return null;\n}\n\nfunction normalizeQuestion(raw: unknown): AskUserQuestion | null {\n if (!raw || typeof raw !== 'object') return null;\n const q = raw as Record<string, unknown>;\n const id = typeof q.id === 'string' ? q.id : '';\n const title = typeof q.title === 'string' ? q.title : typeof q.question === 'string' ? q.question : '';\n if (!id || !title.trim()) return null;\n const options = Array.isArray(q.options)\n ? q.options.filter(\n (o): o is AskUserOption =>\n !!o &&\n typeof o === 'object' &&\n typeof (o as AskUserOption).id === 'string' &&\n typeof (o as AskUserOption).label === 'string',\n )\n : undefined;\n return {\n id,\n title: title.trim(),\n header: typeof q.header === 'string' ? q.header : undefined,\n options,\n allowText: q.allowText !== false,\n textPlaceholder: typeof q.textPlaceholder === 'string' ? q.textPlaceholder : undefined,\n multiSelect: q.multiSelect === true,\n };\n}\n\n/** Parse an `[ASK_USER]…[/ASK_USER]` message, or null if it isn't one. */\nexport function parseAskUser(raw: string | null | undefined): AskUserPayload | null {\n if (!raw?.trim()) return null;\n const tagged = ASK_USER_RE.exec(raw) ?? (ASK_USER_OPEN_RE.test(raw) ? /\\[ASK_USER\\]([\\s\\S]*)$/.exec(raw) : null);\n if (!tagged) return null;\n const parsed = parseJsonObject(unwrapJsonCandidate(tagged[1]));\n if (!parsed || typeof parsed !== 'object') return null;\n const body = parsed as { requestId?: unknown; questions?: unknown };\n if (typeof body.requestId !== 'string' || !Array.isArray(body.questions)) return null;\n const questions = body.questions\n .map(normalizeQuestion)\n .filter((q): q is AskUserQuestion => q !== null)\n .slice(0, MAX_ASK_USER_QUESTIONS);\n return questions.length ? { requestId: body.requestId, questions } : null;\n}\n\n/**\n * Remove every `[ASK_USER]` block, leaving the rest of the message intact.\n *\n * cdecli emits the block MID-turn and keeps streaming its reply into the SAME\n * message once the answer releases the parked run, so the block and the reply it\n * was asked for share one message. Hiding the whole message — which is what a\n * naive implementation does — would swallow that reply.\n *\n * An unclosed `[ASK_USER]` (still streaming) is also stripped so the raw JSON\n * never paints in the bubble the way it does on web after `stripAskUser`.\n */\nexport function stripAskUser(raw: string | null | undefined): string {\n if (!raw) return '';\n let stripped = raw.replace(new RegExp(ASK_USER_RE.source, 'g'), '');\n stripped = stripped.replace(/\\[ASK_USER\\][\\s\\S]*$/, '');\n if (stripped === raw) return raw;\n return stripped.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\n/**\n * Text around an `[ASK_USER]` marker. cdecli often speaks an intro *before* the\n * card (\"I'll need a couple more details…\") and streams the real reply *after*\n * the user answers. Once there is a user reply, the intro is stale.\n */\nexport function splitAskUserParts(raw: string | null | undefined): {\n before: string;\n after: string;\n hasMarker: boolean;\n} {\n if (!raw) return { before: '', after: '', hasMarker: false };\n const tagged = ASK_USER_RE.exec(raw);\n if (tagged && tagged.index !== undefined) {\n return {\n before: raw.slice(0, tagged.index).trim(),\n after: raw.slice(tagged.index + tagged[0].length).trim(),\n hasMarker: true,\n };\n }\n const open = raw.search(ASK_USER_OPEN_RE);\n if (open >= 0) {\n return { before: raw.slice(0, open).trim(), after: '', hasMarker: true };\n }\n return { before: '', after: '', hasMarker: false };\n}\n\n/**\n * Assistant prose to paint. After the user answers the card, drop the intro that\n * sat above `[ASK_USER]` so we don't re-ask for details already in the thread.\n */\nexport function displayAskUserAssistantText(raw: string | null | undefined, answered: boolean): string {\n const parts = splitAskUserParts(raw);\n if (!parts.hasMarker) return stripAskUser(raw);\n const keep = answered ? parts.after : [parts.before, parts.after].filter(Boolean).join('\\n\\n');\n return stripAskUser(keep || (answered ? '' : parts.before));\n}\n\n/**\n * The question still awaiting an answer: the last assistant block, unless the\n * user has already replied after it. Scanning backwards means a stale card from\n * earlier in the thread never reappears.\n */\nexport function pendingAskUser(messages: ReadonlyArray<{ role: string; content: string }>): AskUserPayload | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === 'user') return null;\n const parsed = msg.role === 'assistant' ? parseAskUser(msg.content) : null;\n if (parsed) return answeredAnywhere(parsed, messages) ? null : parsed;\n }\n return null;\n}\n\n/**\n * An answer sent while the asking turn was still open is saved BEFORE that\n * turn's reply (which carries the question and everything after it), so \"a user\n * message after the question\" misses it. The answer names its question\n * (`**Title:** answer`), so it is found wherever it sits.\n */\nfunction answeredAnywhere(ask: AskUserPayload, messages: ReadonlyArray<{ role: string; content: string }>): boolean {\n const prefixes = ask.questions.map((q) => `**${q.title.replace(/:\\s*$/, '')}:**`);\n return messages.some((m) => m.role === 'user' && prefixes.some((prefix) => (m.content ?? '').includes(prefix)));\n}\n\n/**\n * Fold the answers into the single visible reply message:\n *\n * **Which database?:** Postgres\n *\n * Skipped questions are omitted; an empty result means \"nothing to send\", which\n * the card treats as a dismiss.\n */\nexport function formatAskUserAnswers(questions: readonly AskUserQuestion[], answers: Record<string, string>): string {\n return questions\n .map((q) => {\n const answer = answers[q.id]?.trim();\n return answer ? `**${q.title.replace(/:\\s*$/, '')}:** ${answer}` : null;\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n"],"names":[],"mappings":"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"}
@@ -99,12 +99,14 @@ function humanizeToolLine(body) {
99
99
  for (const [re, label2] of CONNECTOR_LABELS) {
100
100
  if (re.test(connector)) return {
101
101
  label: label2,
102
- detail: prettifySlug(connector)
102
+ detail: prettifySlug(connector),
103
+ connector
103
104
  };
104
105
  }
105
106
  return {
106
107
  label: `Running ${prettifySlug(connector)}`,
107
- detail: sanitizeDetail(detailRaw)
108
+ detail: sanitizeDetail(detailRaw),
109
+ connector
108
110
  };
109
111
  }
110
112
  if (/^get[_-]?action[_-]?schema$/i.test(bareTool)) {
@@ -1 +1 @@
1
- {"version":3,"file":"toolActivity.js","sources":["../../../src/features/chat/toolActivity.ts"],"sourcesContent":["/**\n * Tool-activity parsing for the polished status timeline (mobile).\n *\n * A port of the web's `features/chat/toolActivity`, copied rather than imported:\n * mobile is a separate bundle and shares no code with the web shell. It is pure\n * string logic with no DOM or React dependency, so the two are kept in step by\n * having the same tests rather than by a shared module.\n *\n *\n * The cdecli/agent narrates tool use into the streamed assistant text as bare\n * rows, e.g.:\n *\n * ⚙ ToolSearch\n * ⚙ mcp__cdecli__execute_action — yantra-image-generation/Image\n *\n * Rendered raw, these read as debug noise. We parse them out of the prose into\n * structured steps that {@link ./ToolTimeline} renders as an animated,\n * collapsible timeline, and hand back the cleaned prose so the bubble shows only\n * the real answer.\n *\n * Parsing is deliberately conservative: a line only counts as tool activity when\n * it leads with the gear/wrench glyph the agent prefixes, or is a standalone\n * `mcp__…` invocation. Ordinary prose never matches, so a miss degrades to\n * \"leave the text as-is\" rather than eating real content.\n */\n\nexport interface ToolStep {\n /** Stable within a single parse pass — index-based, so identical tools don't collide. */\n id: string;\n /** Humanized present-tense label, e.g. \"Generating image\". */\n label: string;\n /** Optional detail, e.g. the connector slug or raw tool token. */\n detail?: string;\n /** The connector an execute_action row ran on (`yantra-computer`), when it was one. */\n connector?: string;\n /** 'running' only ever applies to the LAST step of an in-flight turn. */\n status: 'running' | 'done';\n /** How many times in a row this same step ran, when more than once. */\n count?: number;\n}\n\n/** The connector behind the user's cloud Computer - the one browser they can watch and take over. */\nexport const COMPUTER_CONNECTOR = 'yantra-computer';\n\n/** Whether any step of a turn ran on the user's Computer. */\nexport function usesComputer(steps: ToolStep[]): boolean {\n return steps.some((step) => step.connector === COMPUTER_CONNECTOR);\n}\n\n/** How many tool calls the steps stand for: a row that repeated counts every run. */\nexport function totalSteps(steps: readonly ToolStep[]): number {\n return steps.reduce((total, step) => total + (step.count ?? 1), 0);\n}\n\nexport interface ParsedToolActivity {\n steps: ToolStep[];\n /** Prose with every tool-activity line removed. */\n text: string;\n}\n\n// A tool-activity line: optional indent, a gear/wrench glyph (with optional\n// emoji variation selector), then the tool token + optional \"— detail\". The `m`\n// flag scopes ^/$ to each line; `u` so the glyph classes match correctly.\nconst GEAR_LINE_RE = /^[ \\t]*[⚙🔧\\u{1F6E0}]️?[ \\t]+(.+?)[ \\t]*$/u;\n// A bare MCP invocation on its own line — the agent sometimes omits the glyph.\n// `mcp__` is vanishingly unlikely in real prose, so this is safe to strip.\nconst BARE_MCP_LINE_RE = /^[ \\t]*(mcp__[^\\s].*?)[ \\t]*$/;\n// The glyph alone: a tool row whose name has not streamed in yet. It is not\n// prose, and painted as text it trails the answer as a stray gear.\nconst BARE_GEAR_LINE_RE = /^[ \\t]*[⚙🔧\\u{1F6E0}]️?[ \\t]*$/u;\n\n/** Known tool tokens → present-tense labels. Anything unmapped falls back to a humanized token. */\nconst TOOL_LABELS: Array<[RegExp, string]> = [\n [/^tool[_-]?search$/i, 'Searching tools'],\n [/^web[_-]?search$/i, 'Searching the web'],\n [/^web[_-]?scrape$/i, 'Reading a page'],\n [/^web[_-]?batch[_-]?scrape$/i, 'Reading pages'],\n [/^reddit[_-]?search$/i, 'Searching Reddit'],\n [/^x[_-]?search$/i, 'Searching X'],\n [/^youtube[_-]?search$/i, 'Searching YouTube'],\n [/^academic[_-]?search$/i, 'Searching papers'],\n [/^(yantra[_-]?)?github[_-]?search$/i, 'Searching GitHub'],\n [/^bash$/i, 'Running a command'],\n [/^grep$/i, 'Searching files'],\n [/^(str_replace_editor|edit|write)$/i, 'Editing files'],\n [/^read$/i, 'Reading files'],\n [/^search[_-]?connectors$/i, 'Finding the right tool'],\n [/^list[_-]?credentials$/i, 'Checking your saved logins'],\n];\n\n/**\n * The Computer's actions, by verb. The connector alone (\"Running computer\")\n * says nothing; what the person wants to know is that the agent is on their\n * browser and roughly what it is doing there.\n *\n * The agent names an action by its id (`YANTRA_COMPUTER_ACT`) about as often as\n * by its title (\"Act on the Computer Browser\"), and sometimes rewords the title\n * (\"Take a Screenshot on Computer\"), so each verb matches both.\n */\nconst COMPUTER_ACTION_LABELS: Array<[RegExp, string]> = [\n [/_(RESOLVE|STATUS|PROVIDERS)$|^(resolve\\b|computer status|list computer providers)/i, 'Finding your Computer'],\n [/_(CREATE|RESUME)$|^(create|resume) computer/i, 'Starting your Computer'],\n [/_BROWSE$|^browse\\b/i, 'Opening a page on your Computer'],\n [/_READ_PAGE$|^read the .*page$/i, 'Reading the page on your Computer'],\n [/_SCREENSHOT$|screenshot/i, 'Looking at your Computer screen'],\n [/_(ACT|INPUT)$|^(act on|send real input)\\b/i, 'Clicking and typing on your Computer'],\n [/_ATTACH_FILE$|^attach a file/i, 'Attaching a file on your Computer'],\n [/_(READ_FILE|WRITE_FILE)$|^(read|write) computer file/i, 'Working with files on your Computer'],\n [/_EXEC$|^run command/i, 'Running a command on your Computer'],\n];\n\n/** Connector slug → verb phrase for `execute_action — <connector>/<action>` rows. */\nconst CONNECTOR_LABELS: Array<[RegExp, string]> = [\n [/image[_-]?gen/i, 'Generating image'],\n [/video[_-]?gen/i, 'Generating video'],\n [/(audio|tts|speech|voice)/i, 'Generating audio'],\n [/search/i, 'Searching'],\n];\n\n/** Title-case a slug/token: \"yantra-image-generation\" → \"Yantra image generation\". */\nfunction prettifySlug(slug: string): string {\n const words = slug\n .replace(/^yantra[_-]/i, '')\n .replace(/[_-]+/g, ' ')\n .trim();\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : slug;\n}\n\n/** Shell / interpreter snippets the agent pastes after a bash/read row. */\nexport function isToolPayloadLine(line: string): boolean {\n const t = line.trim();\n if (!t) return false;\n if (/^```/.test(t)) return true;\n if (/^(import\\s+\\w+|from\\s+\\S+\\s+import)\\b/.test(t)) return true;\n if (/^(const|let|var)\\s+\\w+\\s*=/.test(t)) return true;\n if (/\\brequire\\s*\\(/.test(t)) return true;\n if (/^path\\s*=\\s*['\"`]/.test(t)) return true;\n if (/\\/(?:data\\/users\\/)?\\.cdecli-server\\b/.test(t)) return true;\n if (/^(mkdir|curl|chmod|rm |cp |mv |cat |echo |python3?\\b|node\\s+-e|npx |yarn |npm )\\b/.test(t)) return true;\n if (/^(fs\\.|JSON\\.parse|JSON\\.stringify)/.test(t)) return true;\n return false;\n}\n\nfunction looksLikeCommandDetail(detail: string): boolean {\n const t = detail.trim();\n if (!t) return false;\n if (isToolPayloadLine(t)) return true;\n if (/^(python3?|node|mkdir|curl|npx|bash|sh|zsh)\\b/.test(t)) return true;\n if (t.length > 72) return true;\n return false;\n}\n\nfunction sanitizeDetail(detail: string | undefined): string | undefined {\n if (!detail) return undefined;\n if (looksLikeCommandDetail(detail)) return undefined;\n return detail;\n}\n\nfunction stripUnfencedPayloadLines(chunk: string): string {\n return chunk\n .split('\\n')\n .filter((line) => !isToolPayloadLine(line))\n .join('\\n');\n}\n\n/**\n * Drop dumped tool scripts (unfenced bash/python after a gear row).\n * Never strip markdown fences — those are the answer's code examples.\n */\nexport function stripToolPayloads(text: string): string {\n const fenceRe = /```[\\s\\S]*?(?:```|$)/g;\n const out: string[] = [];\n let last = 0;\n for (let match = fenceRe.exec(text); match; match = fenceRe.exec(text)) {\n out.push(stripUnfencedPayloadLines(text.slice(last, match.index)));\n const block = match[0];\n const isToolDump = /\\/(?:data\\/users\\/)?\\.cdecli-server\\b/.test(block);\n const keepWidget = /\\bpropsComponent\\b/.test(block);\n if (!isToolDump || keepWidget) out.push(block);\n last = match.index + block.length;\n }\n out.push(stripUnfencedPayloadLines(text.slice(last)));\n return out\n .join('')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n}\n\n/**\n * Turn a raw tool row body into a { label, detail }. Handles the two shapes we\n * see: a bare tool name (\"ToolSearch\") and an MCP execute_action carrying a\n * \"connector/action\" detail after an em/en dash.\n */\nexport function humanizeToolLine(body: string): { label: string; detail?: string; connector?: string } {\n const trimmed = body.trim();\n\n // `mcp__cdecli__execute_action — yantra-image-generation/Image`\n const dashSplit = trimmed.split(/\\s+[—–-]\\s+/);\n const head = dashSplit[0]?.trim() ?? trimmed;\n const detailRaw = dashSplit.length > 1 ? dashSplit.slice(1).join(' — ').trim() : undefined;\n\n // Strip an `mcp__<server>__` prefix off the head token.\n const bareTool = head.replace(/^mcp__[^_]+__/i, '').replace(/^mcp__/i, '');\n\n // execute_action rows: the meaning is in the connector detail, not the verb.\n if (/^execute_action$/i.test(bareTool) && detailRaw) {\n const connector = detailRaw.split('/')[0]?.trim() ?? detailRaw;\n if (connector === COMPUTER_CONNECTOR) {\n const action = detailRaw.split('/')[1]?.trim() ?? '';\n const label = COMPUTER_ACTION_LABELS.find(([re]) => re.test(action))?.[1] ?? 'Using your Computer';\n return { label, detail: 'Computer', connector };\n }\n for (const [re, label] of CONNECTOR_LABELS) {\n if (re.test(connector)) return { label, detail: prettifySlug(connector) };\n }\n return { label: `Running ${prettifySlug(connector)}`, detail: sanitizeDetail(detailRaw) };\n }\n\n // `get_action_schema — yantra-computer/Act on the Computer Browser`: the agent reading\n // how to call an action. Plumbing - say which tool, not the action's raw title.\n if (/^get[_-]?action[_-]?schema$/i.test(bareTool)) {\n const connector = detailRaw?.split('/')[0]?.trim();\n if (!connector) return { label: 'Looking up a tool' };\n return {\n label: 'Looking up a tool',\n detail: connector === COMPUTER_CONNECTOR ? 'Computer' : prettifySlug(connector),\n };\n }\n\n for (const [re, label] of TOOL_LABELS) {\n if (re.test(bareTool)) return { label, detail: sanitizeDetail(detailRaw) };\n }\n\n // Generic fallback: prettify the token (camelCase / snake_case → spaced).\n const spaced = bareTool\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim();\n // Lowercase the WHOLE token, not just its first character: the split above\n // turns \"someNewTool\" into \"some New Tool\", and lowercasing only the head\n // left the label reading \"Running some New Tool\" mid-sentence.\n const label = spaced ? `Running ${spaced.toLowerCase()}` : 'Working';\n return { label, detail: sanitizeDetail(detailRaw) };\n}\n\n/**\n * Append a step, or count it on the row before when it is the same step again straight after\n * itself: twenty clicks on one page as twenty identical rows bury the answer and push the live\n * Computer view out of sight.\n */\nfunction addStep(steps: ToolStep[], { label, detail, connector }: Omit<ToolStep, 'id' | 'status'>): void {\n const previous = steps[steps.length - 1];\n if (previous && previous.label === label && previous.detail === detail && previous.connector === connector) {\n previous.count = (previous.count ?? 1) + 1;\n } else {\n steps.push({ id: `tool-${steps.length}`, label, detail, ...(connector && { connector }), status: 'done' });\n }\n}\n\n/**\n * Extract tool-activity rows from streamed/persisted assistant content.\n *\n * @param content raw assistant text\n * @param active when true the turn is still streaming, so the LAST step is\n * marked 'running'; otherwise every step is 'done'.\n */\nexport function parseToolActivity(content: string, active = false): ParsedToolActivity {\n if (!content) return { steps: [], text: content ?? '' };\n\n const steps: ToolStep[] = [];\n const kept: string[] = [];\n\n for (const line of content.split('\\n').filter((l) => !BARE_GEAR_LINE_RE.test(l))) {\n const gear = GEAR_LINE_RE.exec(line);\n const mcp = gear ? null : BARE_MCP_LINE_RE.exec(line);\n const body = gear?.[1] ?? mcp?.[1];\n if (body) addStep(steps, humanizeToolLine(body));\n else kept.push(line);\n }\n\n const joined = kept\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n // Payload stripping is only for dumps that follow tool rows. Applying it\n // to every assistant turn deleted fenced JS/bash examples from the bubble.\n const text = steps.length > 0 ? stripToolPayloads(joined) : joined;\n\n if (active && steps.length > 0) {\n steps[steps.length - 1].status = 'running';\n }\n\n return { steps, text };\n}\n"],"names":["label"],"mappings":";;;;;;;;;;;;;;;;;;;AA0CO,MAAM,kBAAqB,GAAA;AAQ3B,SAAS,WAAW,KAAoC,EAAA;AAC7D,EAAA,OAAO,KAAM,CAAA,MAAA,CAAO,CAAC,KAAA,EAAO,IAAM,KAAA;AAnDpC,IAAA,IAAA,EAAA;AAmDuC,IAAS,OAAA,KAAA,IAAA,CAAA,EAAA,GAAA,IAAA,CAAK,UAAL,IAAc,GAAA,EAAA,GAAA,CAAA,CAAA;AAAA,GAAA,EAAI,CAAC,CAAA;AACnE;AAUA,MAAM,YAAe,GAAA,4CAAA;AAGrB,MAAM,gBAAmB,GAAA,+BAAA;AAGzB,MAAM,iBAAoB,GAAA,iCAAA;AAG1B,MAAM,WAAuC,GAAA,CAAC,CAAC,oBAAA,EAAsB,iBAAiB,CAAA,EAAG,CAAC,mBAAA,EAAqB,mBAAmB,CAAA,EAAG,CAAC,mBAAA,EAAqB,gBAAgB,CAAA,EAAG,CAAC,6BAAA,EAA+B,eAAe,CAAA,EAAG,CAAC,sBAAA,EAAwB,kBAAkB,CAAA,EAAG,CAAC,iBAAA,EAAmB,aAAa,CAAA,EAAG,CAAC,uBAAA,EAAyB,mBAAmB,CAAA,EAAG,CAAC,wBAAA,EAA0B,kBAAkB,CAAA,EAAG,CAAC,oCAAA,EAAsC,kBAAkB,CAAA,EAAG,CAAC,SAAA,EAAW,mBAAmB,CAAA,EAAG,CAAC,SAAA,EAAW,iBAAiB,CAAA,EAAG,CAAC,oCAAA,EAAsC,eAAe,CAAA,EAAG,CAAC,SAAA,EAAW,eAAe,CAAA,EAAG,CAAC,0BAAA,EAA4B,wBAAwB,CAAA,EAAG,CAAC,yBAAA,EAA2B,4BAA4B,CAAC,CAAA;AAWxtB,MAAM,yBAAkD,CAAC,CAAC,oFAAsF,EAAA,uBAAuB,GAAG,CAAC,8CAAA,EAAgD,wBAAwB,CAAA,EAAG,CAAC,qBAAuB,EAAA,iCAAiC,CAAG,EAAA,CAAC,kCAAkC,mCAAmC,CAAA,EAAG,CAAC,0BAAA,EAA4B,iCAAiC,CAAG,EAAA,CAAC,4CAA8C,EAAA,sCAAsC,GAAG,CAAC,+BAAA,EAAiC,mCAAmC,CAAA,EAAG,CAAC,uDAAyD,EAAA,qCAAqC,GAAG,CAAC,sBAAA,EAAwB,oCAAoC,CAAC,CAAA;AAG5vB,MAAM,mBAA4C,CAAC,CAAC,gBAAkB,EAAA,kBAAkB,GAAG,CAAC,gBAAA,EAAkB,kBAAkB,CAAA,EAAG,CAAC,2BAA6B,EAAA,kBAAkB,GAAG,CAAC,SAAA,EAAW,WAAW,CAAC,CAAA;AAG9M,SAAS,aAAa,IAAsB,EAAA;AAC1C,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,OAAA,CAAQ,cAAgB,EAAA,EAAE,EAAE,OAAQ,CAAA,QAAA,EAAU,GAAG,CAAA,CAAE,IAAK,EAAA;AAC3E,EAAO,OAAA,KAAA,GAAQ,KAAM,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,aAAgB,GAAA,KAAA,CAAM,KAAM,CAAA,CAAC,CAAI,GAAA,IAAA;AAClE;AAGO,SAAS,kBAAkB,IAAuB,EAAA;AACvD,EAAM,MAAA,CAAA,GAAI,KAAK,IAAK,EAAA;AACpB,EAAI,IAAA,CAAC,GAAU,OAAA,KAAA;AACf,EAAA,IAAI,MAAO,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AAC3B,EAAA,IAAI,uCAAwC,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AAC5D,EAAA,IAAI,4BAA6B,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AACjD,EAAA,IAAI,gBAAiB,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AACrC,EAAA,IAAI,mBAAoB,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AACxC,EAAA,IAAI,uCAAwC,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AAC5D,EAAA,IAAI,mFAAoF,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AACxG,EAAA,IAAI,qCAAsC,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AAC1D,EAAO,OAAA,KAAA;AACT;AACA,SAAS,uBAAuB,MAAyB,EAAA;AACvD,EAAM,MAAA,CAAA,GAAI,OAAO,IAAK,EAAA;AACtB,EAAI,IAAA,CAAC,GAAU,OAAA,KAAA;AACf,EAAI,IAAA,iBAAA,CAAkB,CAAC,CAAA,EAAU,OAAA,IAAA;AACjC,EAAA,IAAI,+CAAgD,CAAA,IAAA,CAAK,CAAC,CAAA,EAAU,OAAA,IAAA;AACpE,EAAI,IAAA,CAAA,CAAE,MAAS,GAAA,EAAA,EAAW,OAAA,IAAA;AAC1B,EAAO,OAAA,KAAA;AACT;AACA,SAAS,eAAe,MAAgD,EAAA;AACtE,EAAI,IAAA,CAAC,QAAe,OAAA,MAAA;AACpB,EAAI,IAAA,sBAAA,CAAuB,MAAM,CAAA,EAAU,OAAA,MAAA;AAC3C,EAAO,OAAA,MAAA;AACT;AACA,SAAS,0BAA0B,KAAuB,EAAA;AACxD,EAAA,OAAO,KAAM,CAAA,KAAA,CAAM,IAAI,CAAA,CAAE,MAAO,CAAA,CAAA,IAAA,KAAQ,CAAC,iBAAA,CAAkB,IAAI,CAAC,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA;AAC7E;AAMO,SAAS,kBAAkB,IAAsB,EAAA;AACtD,EAAA,MAAM,OAAU,GAAA,uBAAA;AAChB,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,IAAI,IAAO,GAAA,CAAA;AACX,EAAS,KAAA,IAAA,KAAA,GAAQ,OAAQ,CAAA,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,KAAQ,GAAA,OAAA,CAAQ,IAAK,CAAA,IAAI,CAAG,EAAA;AACtE,IAAI,GAAA,CAAA,IAAA,CAAK,0BAA0B,IAAK,CAAA,KAAA,CAAM,MAAM,KAAM,CAAA,KAAK,CAAC,CAAC,CAAA;AACjE,IAAM,MAAA,KAAA,GAAQ,MAAM,CAAC,CAAA;AACrB,IAAM,MAAA,UAAA,GAAa,uCAAwC,CAAA,IAAA,CAAK,KAAK,CAAA;AACrE,IAAM,MAAA,UAAA,GAAa,oBAAqB,CAAA,IAAA,CAAK,KAAK,CAAA;AAClD,IAAA,IAAI,CAAC,UAAA,IAAc,UAAY,EAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AAC7C,IAAO,IAAA,GAAA,KAAA,CAAM,QAAQ,KAAM,CAAA,MAAA;AAAA;AAE7B,EAAA,GAAA,CAAI,KAAK,yBAA0B,CAAA,IAAA,CAAK,KAAM,CAAA,IAAI,CAAC,CAAC,CAAA;AACpD,EAAO,OAAA,GAAA,CAAI,KAAK,EAAE,CAAA,CAAE,QAAQ,SAAW,EAAA,MAAM,EAAE,IAAK,EAAA;AACtD;AAOO,SAAS,iBAAiB,IAI/B,EAAA;AAzJF,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA0JE,EAAM,MAAA,OAAA,GAAU,KAAK,IAAK,EAAA;AAG1B,EAAM,MAAA,SAAA,GAAY,OAAQ,CAAA,KAAA,CAAM,aAAa,CAAA;AAC7C,EAAA,MAAM,QAAO,EAAU,GAAA,CAAA,EAAA,GAAA,SAAA,CAAA,CAAC,CAAX,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAc,WAAd,IAAwB,GAAA,EAAA,GAAA,OAAA;AACrC,EAAA,MAAM,SAAY,GAAA,SAAA,CAAU,MAAS,GAAA,CAAA,GAAI,SAAU,CAAA,KAAA,CAAM,CAAC,CAAA,CAAE,IAAK,CAAA,UAAK,CAAE,CAAA,IAAA,EAAS,GAAA,MAAA;AAGjF,EAAM,MAAA,QAAA,GAAW,KAAK,OAAQ,CAAA,gBAAA,EAAkB,EAAE,CAAE,CAAA,OAAA,CAAQ,WAAW,EAAE,CAAA;AAGzE,EAAA,IAAI,mBAAoB,CAAA,IAAA,CAAK,QAAQ,CAAA,IAAK,SAAW,EAAA;AACnD,IAAM,MAAA,SAAA,GAAA,CAAY,qBAAU,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,KAAtB,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA,KAAzB,IAAmC,GAAA,EAAA,GAAA,SAAA;AACrD,IAAA,IAAI,cAAc,kBAAoB,EAAA;AACpC,MAAM,MAAA,MAAA,GAAA,CAAS,qBAAU,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA,KAAtB,IAAyB,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA,KAAzB,IAAmC,GAAA,EAAA,GAAA,EAAA;AAClD,MAAA,MAAMA,MAAQ,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,sBAAA,CAAuB,IAAK,CAAA,CAAC,CAAC,EAAE,CAAA,KAAM,EAAG,CAAA,IAAA,CAAK,MAAM,CAAC,CAArD,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAyD,OAAzD,IAA+D,GAAA,EAAA,GAAA,qBAAA;AAC7E,MAAO,OAAA;AAAA,QACL,KAAAA,EAAAA,MAAAA;AAAA,QACA,MAAQ,EAAA,UAAA;AAAA,QACR;AAAA,OACF;AAAA;AAEF,IAAA,KAAA,MAAW,CAAC,EAAA,EAAIA,MAAK,CAAA,IAAK,gBAAkB,EAAA;AAC1C,MAAA,IAAI,EAAG,CAAA,IAAA,CAAK,SAAS,CAAA,EAAU,OAAA;AAAA,QAC7B,KAAAA,EAAAA,MAAAA;AAAA,QACA,MAAA,EAAQ,aAAa,SAAS;AAAA,OAChC;AAAA;AAEF,IAAO,OAAA;AAAA,MACL,KAAO,EAAA,CAAA,QAAA,EAAW,YAAa,CAAA,SAAS,CAAC,CAAA,CAAA;AAAA,MACzC,MAAA,EAAQ,eAAe,SAAS;AAAA,KAClC;AAAA;AAKF,EAAI,IAAA,8BAAA,CAA+B,IAAK,CAAA,QAAQ,CAAG,EAAA;AACjD,IAAA,MAAM,SAAY,GAAA,CAAA,EAAA,GAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,KAAM,CAAA,GAAA,CAAA,CAAK,OAAtB,IAA0B,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,EAAA;AAC5C,IAAI,IAAA,CAAC,WAAkB,OAAA;AAAA,MACrB,KAAO,EAAA;AAAA,KACT;AACA,IAAO,OAAA;AAAA,MACL,KAAO,EAAA,mBAAA;AAAA,MACP,MAAQ,EAAA,SAAA,KAAc,kBAAqB,GAAA,UAAA,GAAa,aAAa,SAAS;AAAA,KAChF;AAAA;AAEF,EAAA,KAAA,MAAW,CAAC,EAAA,EAAIA,MAAK,CAAA,IAAK,WAAa,EAAA;AACrC,IAAA,IAAI,EAAG,CAAA,IAAA,CAAK,QAAQ,CAAA,EAAU,OAAA;AAAA,MAC5B,KAAAA,EAAAA,MAAAA;AAAA,MACA,MAAA,EAAQ,eAAe,SAAS;AAAA,KAClC;AAAA;AAIF,EAAM,MAAA,MAAA,GAAS,QAAS,CAAA,OAAA,CAAQ,iBAAmB,EAAA,OAAO,EAAE,OAAQ,CAAA,QAAA,EAAU,GAAG,CAAA,CAAE,IAAK,EAAA;AAIxF,EAAA,MAAM,QAAQ,MAAS,GAAA,CAAA,QAAA,EAAW,MAAO,CAAA,WAAA,EAAa,CAAK,CAAA,GAAA,SAAA;AAC3D,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,MAAA,EAAQ,eAAe,SAAS;AAAA,GAClC;AACF;AAOA,SAAS,QAAQ,KAAmB,EAAA;AAAA,EAClC,KAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA0C,EAAA;AApO1C,EAAA,IAAA,EAAA;AAqOE,EAAA,MAAM,QAAW,GAAA,KAAA,CAAM,KAAM,CAAA,MAAA,GAAS,CAAC,CAAA;AACvC,EAAI,IAAA,QAAA,IAAY,SAAS,KAAU,KAAA,KAAA,IAAS,SAAS,MAAW,KAAA,MAAA,IAAU,QAAS,CAAA,SAAA,KAAc,SAAW,EAAA;AAC1G,IAAA,QAAA,CAAS,KAAS,GAAA,CAAA,CAAA,EAAA,GAAA,QAAA,CAAS,KAAT,KAAA,IAAA,GAAA,EAAA,GAAkB,CAAK,IAAA,CAAA;AAAA,GACpC,MAAA;AACL,IAAA,KAAA,CAAM,IAAK,CAAA,aAAA,CAAA,cAAA,CAAA;AAAA,MACT,EAAA,EAAI,CAAQ,KAAA,EAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AAAA,MACxB,KAAA;AAAA,MACA;AAAA,KAAA,EACI,SAAa,IAAA;AAAA,MACf;AAAA,KALO,CAAA,EAAA;AAAA,MAOT,MAAQ,EAAA;AAAA,KACT,CAAA,CAAA;AAAA;AAEL;AASgB,SAAA,iBAAA,CAAkB,OAAiB,EAAA,MAAA,GAAS,KAA2B,EAAA;AA5PvF,EAAA,IAAA,EAAA;AA6PE,EAAI,IAAA,CAAC,SAAgB,OAAA;AAAA,IACnB,OAAO,EAAC;AAAA,IACR,MAAM,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA;AAAA,GACnB;AACA,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,KAAA,MAAW,IAAQ,IAAA,OAAA,CAAQ,KAAM,CAAA,IAAI,CAAE,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAC,iBAAkB,CAAA,IAAA,CAAK,CAAC,CAAC,CAAG,EAAA;AAC9E,IAAM,MAAA,IAAA,GAAO,YAAa,CAAA,IAAA,CAAK,IAAI,CAAA;AACnC,IAAA,MAAM,GAAM,GAAA,IAAA,GAAO,IAAO,GAAA,gBAAA,CAAiB,KAAK,IAAI,CAAA;AACpD,IAAA,MAAM,IAAO,GAAA,CAAA,EAAA,GAAA,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAO,CAAP,CAAA,KAAA,IAAA,GAAA,EAAA,GAAa,GAAM,IAAA,IAAA,GAAA,MAAA,GAAA,GAAA,CAAA,CAAA,CAAA;AAChC,IAAA,IAAI,IAAM,EAAA,OAAA,CAAQ,KAAO,EAAA,gBAAA,CAAiB,IAAI,CAAC,CAAA;AAAA,SAAO,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA;AAEtE,EAAM,MAAA,MAAA,GAAS,KAAK,IAAK,CAAA,IAAI,EAAE,OAAQ,CAAA,SAAA,EAAW,MAAM,CAAA,CAAE,IAAK,EAAA;AAG/D,EAAA,MAAM,OAAO,KAAM,CAAA,MAAA,GAAS,CAAI,GAAA,iBAAA,CAAkB,MAAM,CAAI,GAAA,MAAA;AAC5D,EAAI,IAAA,MAAA,IAAU,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA;AAC9B,IAAA,KAAA,CAAM,KAAM,CAAA,MAAA,GAAS,CAAC,CAAA,CAAE,MAAS,GAAA,SAAA;AAAA;AAEnC,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA;AAAA,GACF;AACF"}
1
+ {"version":3,"file":"toolActivity.js","sources":["../../../src/features/chat/toolActivity.ts"],"sourcesContent":["/**\n * Tool-activity parsing for the polished status timeline (mobile).\n *\n * A port of the web's `features/chat/toolActivity`, copied rather than imported:\n * mobile is a separate bundle and shares no code with the web shell. It is pure\n * string logic with no DOM or React dependency, so the two are kept in step by\n * having the same tests rather than by a shared module.\n *\n *\n * The cdecli/agent narrates tool use into the streamed assistant text as bare\n * rows, e.g.:\n *\n * ⚙ ToolSearch\n * ⚙ mcp__cdecli__execute_action — yantra-image-generation/Image\n *\n * Rendered raw, these read as debug noise. We parse them out of the prose into\n * structured steps that {@link ./ToolTimeline} renders as an animated,\n * collapsible timeline, and hand back the cleaned prose so the bubble shows only\n * the real answer.\n *\n * Parsing is deliberately conservative: a line only counts as tool activity when\n * it leads with the gear/wrench glyph the agent prefixes, or is a standalone\n * `mcp__…` invocation. Ordinary prose never matches, so a miss degrades to\n * \"leave the text as-is\" rather than eating real content.\n */\n\nexport interface ToolStep {\n /** Stable within a single parse pass — index-based, so identical tools don't collide. */\n id: string;\n /** Humanized present-tense label, e.g. \"Generating image\". */\n label: string;\n /** Optional detail, e.g. the connector slug or raw tool token. */\n detail?: string;\n /** The connector an execute_action row ran on (`yantra-computer`), when it was one. */\n connector?: string;\n /** 'running' only ever applies to the LAST step of an in-flight turn. */\n status: 'running' | 'done';\n /** How many times in a row this same step ran, when more than once. */\n count?: number;\n}\n\n/** The connector behind the user's cloud Computer - the one browser they can watch and take over. */\nexport const COMPUTER_CONNECTOR = 'yantra-computer';\n\n/** Whether any step of a turn ran on the user's Computer. */\nexport function usesComputer(steps: ToolStep[]): boolean {\n return steps.some((step) => step.connector === COMPUTER_CONNECTOR);\n}\n\n/** How many tool calls the steps stand for: a row that repeated counts every run. */\nexport function totalSteps(steps: readonly ToolStep[]): number {\n return steps.reduce((total, step) => total + (step.count ?? 1), 0);\n}\n\nexport interface ParsedToolActivity {\n steps: ToolStep[];\n /** Prose with every tool-activity line removed. */\n text: string;\n}\n\n// A tool-activity line: optional indent, a gear/wrench glyph (with optional\n// emoji variation selector), then the tool token + optional \"— detail\". The `m`\n// flag scopes ^/$ to each line; `u` so the glyph classes match correctly.\nconst GEAR_LINE_RE = /^[ \\t]*[⚙🔧\\u{1F6E0}]️?[ \\t]+(.+?)[ \\t]*$/u;\n// A bare MCP invocation on its own line — the agent sometimes omits the glyph.\n// `mcp__` is vanishingly unlikely in real prose, so this is safe to strip.\nconst BARE_MCP_LINE_RE = /^[ \\t]*(mcp__[^\\s].*?)[ \\t]*$/;\n// The glyph alone: a tool row whose name has not streamed in yet. It is not\n// prose, and painted as text it trails the answer as a stray gear.\nconst BARE_GEAR_LINE_RE = /^[ \\t]*[⚙🔧\\u{1F6E0}]️?[ \\t]*$/u;\n\n/** Known tool tokens → present-tense labels. Anything unmapped falls back to a humanized token. */\nconst TOOL_LABELS: Array<[RegExp, string]> = [\n [/^tool[_-]?search$/i, 'Searching tools'],\n [/^web[_-]?search$/i, 'Searching the web'],\n [/^web[_-]?scrape$/i, 'Reading a page'],\n [/^web[_-]?batch[_-]?scrape$/i, 'Reading pages'],\n [/^reddit[_-]?search$/i, 'Searching Reddit'],\n [/^x[_-]?search$/i, 'Searching X'],\n [/^youtube[_-]?search$/i, 'Searching YouTube'],\n [/^academic[_-]?search$/i, 'Searching papers'],\n [/^(yantra[_-]?)?github[_-]?search$/i, 'Searching GitHub'],\n [/^bash$/i, 'Running a command'],\n [/^grep$/i, 'Searching files'],\n [/^(str_replace_editor|edit|write)$/i, 'Editing files'],\n [/^read$/i, 'Reading files'],\n [/^search[_-]?connectors$/i, 'Finding the right tool'],\n [/^list[_-]?credentials$/i, 'Checking your saved logins'],\n];\n\n/**\n * The Computer's actions, by verb. The connector alone (\"Running computer\")\n * says nothing; what the person wants to know is that the agent is on their\n * browser and roughly what it is doing there.\n *\n * The agent names an action by its id (`YANTRA_COMPUTER_ACT`) about as often as\n * by its title (\"Act on the Computer Browser\"), and sometimes rewords the title\n * (\"Take a Screenshot on Computer\"), so each verb matches both.\n */\nconst COMPUTER_ACTION_LABELS: Array<[RegExp, string]> = [\n [/_(RESOLVE|STATUS|PROVIDERS)$|^(resolve\\b|computer status|list computer providers)/i, 'Finding your Computer'],\n [/_(CREATE|RESUME)$|^(create|resume) computer/i, 'Starting your Computer'],\n [/_BROWSE$|^browse\\b/i, 'Opening a page on your Computer'],\n [/_READ_PAGE$|^read the .*page$/i, 'Reading the page on your Computer'],\n [/_SCREENSHOT$|screenshot/i, 'Looking at your Computer screen'],\n [/_(ACT|INPUT)$|^(act on|send real input)\\b/i, 'Clicking and typing on your Computer'],\n [/_ATTACH_FILE$|^attach a file/i, 'Attaching a file on your Computer'],\n [/_(READ_FILE|WRITE_FILE)$|^(read|write) computer file/i, 'Working with files on your Computer'],\n [/_EXEC$|^run command/i, 'Running a command on your Computer'],\n];\n\n/** Connector slug → verb phrase for `execute_action — <connector>/<action>` rows. */\nconst CONNECTOR_LABELS: Array<[RegExp, string]> = [\n [/image[_-]?gen/i, 'Generating image'],\n [/video[_-]?gen/i, 'Generating video'],\n [/(audio|tts|speech|voice)/i, 'Generating audio'],\n [/search/i, 'Searching'],\n];\n\n/** Title-case a slug/token: \"yantra-image-generation\" → \"Yantra image generation\". */\nfunction prettifySlug(slug: string): string {\n const words = slug\n .replace(/^yantra[_-]/i, '')\n .replace(/[_-]+/g, ' ')\n .trim();\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : slug;\n}\n\n/** Shell / interpreter snippets the agent pastes after a bash/read row. */\nexport function isToolPayloadLine(line: string): boolean {\n const t = line.trim();\n if (!t) return false;\n if (/^```/.test(t)) return true;\n if (/^(import\\s+\\w+|from\\s+\\S+\\s+import)\\b/.test(t)) return true;\n if (/^(const|let|var)\\s+\\w+\\s*=/.test(t)) return true;\n if (/\\brequire\\s*\\(/.test(t)) return true;\n if (/^path\\s*=\\s*['\"`]/.test(t)) return true;\n if (/\\/(?:data\\/users\\/)?\\.cdecli-server\\b/.test(t)) return true;\n if (/^(mkdir|curl|chmod|rm |cp |mv |cat |echo |python3?\\b|node\\s+-e|npx |yarn |npm )\\b/.test(t)) return true;\n if (/^(fs\\.|JSON\\.parse|JSON\\.stringify)/.test(t)) return true;\n return false;\n}\n\nfunction looksLikeCommandDetail(detail: string): boolean {\n const t = detail.trim();\n if (!t) return false;\n if (isToolPayloadLine(t)) return true;\n if (/^(python3?|node|mkdir|curl|npx|bash|sh|zsh)\\b/.test(t)) return true;\n if (t.length > 72) return true;\n return false;\n}\n\nfunction sanitizeDetail(detail: string | undefined): string | undefined {\n if (!detail) return undefined;\n if (looksLikeCommandDetail(detail)) return undefined;\n return detail;\n}\n\nfunction stripUnfencedPayloadLines(chunk: string): string {\n return chunk\n .split('\\n')\n .filter((line) => !isToolPayloadLine(line))\n .join('\\n');\n}\n\n/**\n * Drop dumped tool scripts (unfenced bash/python after a gear row).\n * Never strip markdown fences — those are the answer's code examples.\n */\nexport function stripToolPayloads(text: string): string {\n const fenceRe = /```[\\s\\S]*?(?:```|$)/g;\n const out: string[] = [];\n let last = 0;\n for (let match = fenceRe.exec(text); match; match = fenceRe.exec(text)) {\n out.push(stripUnfencedPayloadLines(text.slice(last, match.index)));\n const block = match[0];\n const isToolDump = /\\/(?:data\\/users\\/)?\\.cdecli-server\\b/.test(block);\n const keepWidget = /\\bpropsComponent\\b/.test(block);\n if (!isToolDump || keepWidget) out.push(block);\n last = match.index + block.length;\n }\n out.push(stripUnfencedPayloadLines(text.slice(last)));\n return out\n .join('')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n}\n\n/**\n * Turn a raw tool row body into a { label, detail }. Handles the two shapes we\n * see: a bare tool name (\"ToolSearch\") and an MCP execute_action carrying a\n * \"connector/action\" detail after an em/en dash.\n */\nexport function humanizeToolLine(body: string): { label: string; detail?: string; connector?: string } {\n const trimmed = body.trim();\n\n // `mcp__cdecli__execute_action — yantra-image-generation/Image`\n const dashSplit = trimmed.split(/\\s+[—–-]\\s+/);\n const head = dashSplit[0]?.trim() ?? trimmed;\n const detailRaw = dashSplit.length > 1 ? dashSplit.slice(1).join(' — ').trim() : undefined;\n\n // Strip an `mcp__<server>__` prefix off the head token.\n const bareTool = head.replace(/^mcp__[^_]+__/i, '').replace(/^mcp__/i, '');\n\n // execute_action rows: the meaning is in the connector detail, not the verb.\n if (/^execute_action$/i.test(bareTool) && detailRaw) {\n const connector = detailRaw.split('/')[0]?.trim() ?? detailRaw;\n if (connector === COMPUTER_CONNECTOR) {\n const action = detailRaw.split('/')[1]?.trim() ?? '';\n const label = COMPUTER_ACTION_LABELS.find(([re]) => re.test(action))?.[1] ?? 'Using your Computer';\n return { label, detail: 'Computer', connector };\n }\n for (const [re, label] of CONNECTOR_LABELS) {\n if (re.test(connector)) return { label, detail: prettifySlug(connector), connector };\n }\n return { label: `Running ${prettifySlug(connector)}`, detail: sanitizeDetail(detailRaw), connector };\n }\n\n // `get_action_schema — yantra-computer/Act on the Computer Browser`: the agent reading\n // how to call an action. Plumbing - say which tool, not the action's raw title.\n if (/^get[_-]?action[_-]?schema$/i.test(bareTool)) {\n const connector = detailRaw?.split('/')[0]?.trim();\n if (!connector) return { label: 'Looking up a tool' };\n return {\n label: 'Looking up a tool',\n detail: connector === COMPUTER_CONNECTOR ? 'Computer' : prettifySlug(connector),\n };\n }\n\n for (const [re, label] of TOOL_LABELS) {\n if (re.test(bareTool)) return { label, detail: sanitizeDetail(detailRaw) };\n }\n\n // Generic fallback: prettify the token (camelCase / snake_case → spaced).\n const spaced = bareTool\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .trim();\n // Lowercase the WHOLE token, not just its first character: the split above\n // turns \"someNewTool\" into \"some New Tool\", and lowercasing only the head\n // left the label reading \"Running some New Tool\" mid-sentence.\n const label = spaced ? `Running ${spaced.toLowerCase()}` : 'Working';\n return { label, detail: sanitizeDetail(detailRaw) };\n}\n\n/**\n * Append a step, or count it on the row before when it is the same step again straight after\n * itself: twenty clicks on one page as twenty identical rows bury the answer and push the live\n * Computer view out of sight.\n */\nfunction addStep(steps: ToolStep[], { label, detail, connector }: Omit<ToolStep, 'id' | 'status'>): void {\n const previous = steps[steps.length - 1];\n if (previous && previous.label === label && previous.detail === detail && previous.connector === connector) {\n previous.count = (previous.count ?? 1) + 1;\n } else {\n steps.push({ id: `tool-${steps.length}`, label, detail, ...(connector && { connector }), status: 'done' });\n }\n}\n\n/**\n * Extract tool-activity rows from streamed/persisted assistant content.\n *\n * @param content raw assistant text\n * @param active when true the turn is still streaming, so the LAST step is\n * marked 'running'; otherwise every step is 'done'.\n */\nexport function parseToolActivity(content: string, active = false): ParsedToolActivity {\n if (!content) return { steps: [], text: content ?? '' };\n\n const steps: ToolStep[] = [];\n const kept: string[] = [];\n\n for (const line of content.split('\\n').filter((l) => !BARE_GEAR_LINE_RE.test(l))) {\n const gear = GEAR_LINE_RE.exec(line);\n const mcp = gear ? null : BARE_MCP_LINE_RE.exec(line);\n const body = gear?.[1] ?? mcp?.[1];\n if (body) addStep(steps, humanizeToolLine(body));\n else kept.push(line);\n }\n\n const joined = kept\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n // Payload stripping is only for dumps that follow tool rows. Applying it\n // to every assistant turn deleted fenced JS/bash examples from the bubble.\n const text = steps.length > 0 ? stripToolPayloads(joined) : joined;\n\n if (active && steps.length > 0) {\n steps[steps.length - 1].status = 'running';\n }\n\n return { steps, text };\n}\n"],"names":["label"],"mappings":"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"}
@@ -274,7 +274,10 @@ function ProjectChat({
274
274
  /* @__PURE__ */ jsx(Text, { style: [styles.emptyBody, {
275
275
  color: theme.muted
276
276
  }], children: build ? "Ask for new sections, another look, copy changes or fixes." : "Tell me what the site is for and I'll build it step by step." })
277
- ] }), ListFooterComponent: ask && onAnswerAsk && !dismissedAsks.includes(ask.requestId) ? /* @__PURE__ */ jsx(View, { style: styles.askCard, children: /* @__PURE__ */ jsx(AskUserCard, { payload: ask, isDark: theme.isDark, onAnswer: onAnswerAsk, onDismiss: () => setDismissedAsks((prev) => [...prev, ask.requestId]) }, ask.requestId) }) : null, renderItem: ({
277
+ ] }), ListFooterComponent: ask && onAnswerAsk && !dismissedAsks.includes(ask.requestId) ? /* @__PURE__ */ jsx(View, { style: styles.askCard, children: /* @__PURE__ */ jsx(AskUserCard, { payload: ask, isDark: theme.isDark, onAnswer: (formatted) => {
278
+ setDismissedAsks((prev) => [...prev, ask.requestId]);
279
+ onAnswerAsk(formatted);
280
+ }, onDismiss: () => setDismissedAsks((prev) => [...prev, ask.requestId]) }, ask.requestId) }) : null, renderItem: ({
278
281
  item
279
282
  }) => {
280
283
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectChat.js","sources":["../../../../src/features/webbuilder/components/ProjectChat.tsx"],"sourcesContent":["/**\n * A project's conversation, the way Manus shows an agent at work: what you\n * asked, then the agent's turn - its live steps (\"Working · 12s\" with each tool\n * it ran), what it says, and once there is a site, a live card of it with Open\n * preview and Publish. The composer stays at the bottom for the next change.\n */\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n ActivityIndicator,\n FlatList,\n Image,\n KeyboardAvoidingView,\n Platform,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport { AssistantMarkdown } from '../../chat/AssistantMarkdown';\nimport { ToolTimeline } from '../../chat/ToolTimeline';\nimport { parseToolActivity } from '../../chat/toolActivity';\nimport { AskUserCard } from '../../chat/AskUserCard';\nimport type { AskUserPayload } from '../../chat/askUser';\nimport type { AgentChatMessage } from '../../agent-chat';\nimport { displayHost } from '../buildFragments';\nimport type { WebBuilderBuild, WebBuilderBuilding } from '../types';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { DESKTOP_VIEWPORT_SCRIPT } from './PreviewFrame';\nimport { PreviewPlaceholder } from './PreviewPlaceholder';\nimport { webbuilderAgentSuggestions } from '../webbuilderPrompts';\n\ntype Row =\n | { kind: 'message'; id: string; message: AgentChatMessage }\n | { kind: 'live'; id: string }\n | { kind: 'site'; id: string };\n\nfunction elapsedLabel(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n return `${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, '0')}s`;\n}\n\nfunction useElapsed(startedAt: number | null): number {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!startedAt) return undefined;\n const timer = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(timer);\n }, [startedAt]);\n return startedAt ? Math.max(0, Math.floor((now - startedAt) / 1000)) : 0;\n}\n\nfunction UserBubble({ text, theme }: { text: string; theme: WebBuilderTheme }) {\n return (\n <View style={styles.userRow}>\n <View style={[styles.userBubble, { backgroundColor: theme.chip }]}>\n <Text style={[styles.userText, { color: theme.ink }]} selectable>\n {text}\n </Text>\n </View>\n </View>\n );\n}\n\nfunction AgentAvatar({ theme }: { theme: WebBuilderTheme }) {\n return (\n <View style={styles.agentHead}>\n <View style={[styles.agentMark, { backgroundColor: theme.accent }]}>\n <MaterialCommunityIcons name=\"creation\" size={14} color={theme.accentInk} />\n </View>\n <Text style={[styles.agentName, { color: theme.ink }]}>Web Builder</Text>\n </View>\n );\n}\n\nfunction AgentTurn({ content, active, theme }: { content: string; active: boolean; theme: WebBuilderTheme }) {\n const parsed = useMemo(() => parseToolActivity(content, active), [content, active]);\n return (\n <View style={styles.agentTurn}>\n <AgentAvatar theme={theme} />\n {parsed.steps.length ? <ToolTimeline steps={parsed.steps} active={active} isDark={theme.isDark} /> : null}\n {parsed.text ? <AssistantMarkdown text={parsed.text} streaming={active} isDark={theme.isDark} /> : null}\n </View>\n );\n}\n\nfunction LiveTurn({\n streaming,\n building,\n theme,\n}: {\n streaming: string | null;\n building: WebBuilderBuilding | null;\n theme: WebBuilderTheme;\n}) {\n const elapsed = useElapsed(building?.startedAt ?? null);\n const parsed = useMemo(() => parseToolActivity(streaming ?? '', true), [streaming]);\n const showStatus = !parsed.text && parsed.steps.length === 0;\n return (\n <View style={styles.agentTurn}>\n <AgentAvatar theme={theme} />\n {parsed.steps.length ? <ToolTimeline steps={parsed.steps} active isDark={theme.isDark} /> : null}\n {parsed.text ? <AssistantMarkdown text={parsed.text} streaming isDark={theme.isDark} /> : null}\n {showStatus ? (\n <View style={[styles.working, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <ActivityIndicator size=\"small\" color={theme.accent} />\n <Text style={[styles.workingText, { color: theme.ink }]} numberOfLines={2}>\n {building?.statusText || 'Thinking…'}\n </Text>\n {building ? (\n <Text style={[styles.workingTime, { color: theme.muted }]}>{elapsedLabel(elapsed)}</Text>\n ) : null}\n </View>\n ) : null}\n </View>\n );\n}\n\nfunction timeOf(ms: number): string {\n if (!ms) return '';\n const d = new Date(ms);\n return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;\n}\n\n/**\n * The site as it is now - Manus's app card: what it is and whether it is live,\n * a glimpse of the running page (laid out at desktop width and fitted, so it\n * reads as the site rather than a cropped corner), and the two ways forward.\n */\nfunction SiteCard({\n build,\n title,\n busy,\n onOpen,\n onPublish,\n onAsleep,\n theme,\n}: {\n build: WebBuilderBuild;\n title: string;\n busy: boolean;\n onOpen: () => void;\n onPublish: () => void;\n /** The live page answered 5xx: start bringing it back (web `ensurePreview` on open). */\n onAsleep?: () => void;\n theme: WebBuilderTheme;\n}) {\n const url = build.previewUrl;\n const [loaded, setLoaded] = useState(false);\n // A sandbox that slept or was reclaimed answers with the host's own error page\n // (E2B \"502 Sandbox not found\"); that page is never shown, the card says what it means.\n const [asleep, setAsleep] = useState(false);\n useEffect(() => {\n setLoaded(false);\n setAsleep(false);\n }, [url]);\n // During the agent's turn a 5xx means its dev server is still starting: check again\n // every 3 s and leave the sandbox to the agent; wake it only once the turn ends (web #431).\n const [recheck, setRecheck] = useState(0);\n useEffect(() => {\n if (!asleep) return undefined;\n if (!busy) {\n onAsleep?.();\n return undefined;\n }\n const timer = setTimeout(() => {\n setAsleep(false);\n setLoaded(false);\n setRecheck((n) => n + 1);\n }, 3_000);\n return () => clearTimeout(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [asleep, busy]);\n // Cover first, live page only without one - the web CreationTile's order. The\n // screenshot is instant and needs no awake sandbox, so it outlives the preview.\n const [coverFailed, setCoverFailed] = useState(false);\n useEffect(() => setCoverFailed(false), [build.coverUrl]);\n const cover = build.coverUrl && !coverFailed ? build.coverUrl : null;\n const status = build.liveUrl\n ? `Live · ${displayHost(build.liveUrl)}`\n : `Not published · ${timeOf(build.updatedAt)}`;\n return (\n <View\n style={[\n styles.site,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n >\n <Tap\n onPress={onOpen}\n accessibilityRole=\"button\"\n accessibilityLabel={`Open ${title}`}\n style={styles.siteHead}\n pressedStyle={DIM}\n >\n <View style={[styles.siteGlobe, { backgroundColor: build.liveUrl ? theme.good : theme.accent }]}>\n <MaterialCommunityIcons name=\"web\" size={24} color={theme.accentInk} />\n </View>\n <View style={styles.siteHeadText}>\n <Text style={[styles.siteTitle, { color: theme.ink }]} numberOfLines={1}>\n {title}\n </Text>\n <Text style={[styles.siteStatus, { color: theme.muted }]} numberOfLines={1}>\n {status}\n </Text>\n </View>\n </Tap>\n <Tap onPress={onOpen} accessibilityRole=\"button\" accessibilityLabel={`Open the preview of ${title}`}>\n <View\n style={[styles.siteView, { backgroundColor: theme.stage, borderColor: theme.border }]}\n pointerEvents=\"none\"\n >\n {cover ? (\n <Image\n source={{ uri: cover }}\n style={styles.siteCover}\n resizeMode=\"cover\"\n onError={() => setCoverFailed(true)}\n accessibilityIgnoresInvertColors\n />\n ) : null}\n {!cover && url ? (\n <WebView\n key={`${url}-${recheck}`}\n source={{ uri: url }}\n style={[styles.siteWeb, !loaded && styles.hidden]}\n scrollEnabled={false}\n javaScriptEnabled\n domStorageEnabled\n originWhitelist={['*']}\n scalesPageToFit\n injectedJavaScript={DESKTOP_VIEWPORT_SCRIPT}\n onLoadEnd={() => setLoaded(true)}\n onHttpError={(event) => {\n if (event.nativeEvent.statusCode >= 500) setAsleep(true);\n }}\n onError={() => setAsleep(true)}\n />\n ) : null}\n {!cover && asleep ? (\n <View style={[styles.siteLoading, { backgroundColor: theme.stage }]}>\n <PreviewPlaceholder theme={theme} compact />\n </View>\n ) : null}\n {!cover && !asleep && (!url || !loaded) ? (\n <View style={styles.siteLoading}>\n <ActivityIndicator color={theme.accent} />\n <Text style={[styles.siteLoadingText, { color: theme.muted }]}>Loading preview…</Text>\n </View>\n ) : null}\n {busy && (cover || (loaded && !asleep)) ? (\n <View style={[styles.siteBusy, { backgroundColor: theme.card }]}>\n <ActivityIndicator size=\"small\" color={theme.accent} />\n <Text style={[styles.siteBusyText, { color: theme.ink }]}>Updating…</Text>\n </View>\n ) : null}\n </View>\n </Tap>\n {build.origin === 'agent' && !build.liveUrl ? (\n <View style={[styles.siteNote, { backgroundColor: theme.warnSoft }]}>\n <MaterialCommunityIcons name=\"clock-outline\" size={15} color={theme.warn} />\n <Text style={[styles.siteNoteText, { color: theme.ink }]}>\n {build.snapshotId\n ? 'The preview lasts about an hour after the last change; a restore point is saved. Publish to keep it online.'\n : 'The preview lasts about an hour after the last change. Publish to keep it online.'}\n </Text>\n </View>\n ) : null}\n <View style={styles.siteFoot}>\n <Tap\n onPress={onOpen}\n accessibilityRole=\"button\"\n style={[styles.siteBtn, { backgroundColor: theme.chip }]}\n pressedStyle={DIM}\n testID=\"webbuilder-card-preview\"\n >\n <Text style={[styles.siteBtnText, { color: theme.ink }]}>Preview</Text>\n </Tap>\n <Tap\n onPress={onPublish}\n disabled={!build.sandboxId}\n accessibilityRole=\"button\"\n style={[styles.siteBtn, { backgroundColor: theme.ink }, !build.sandboxId && styles.disabled]}\n pressedStyle={DIM}\n testID=\"webbuilder-card-publish\"\n >\n <Text style={[styles.siteBtnText, { color: theme.card }]}>Publish</Text>\n </Tap>\n </View>\n </View>\n );\n}\n\nexport function ProjectChat({\n messages,\n streaming,\n busy,\n error,\n connected,\n building,\n build,\n siteTitle,\n onSend,\n onOpenPreview,\n onPublish,\n onPreviewAsleep,\n ask = null,\n onAnswerAsk,\n theme,\n bottomInset,\n}: {\n messages: AgentChatMessage[];\n streaming: string | null;\n busy: boolean;\n error: string | null;\n connected: boolean;\n building: WebBuilderBuilding | null;\n build: WebBuilderBuild | null;\n siteTitle: string;\n onSend: (text: string) => void;\n onOpenPreview: () => void;\n onPublish: () => void;\n /** The site card found the sandbox asleep or expired. */\n onPreviewAsleep?: () => void;\n /** The agent's question waiting for an answer (`[ASK_USER]`), shown as the question card. */\n ask?: AskUserPayload | null;\n /** Send the formatted answers as the reply (releases the agent's parked turn). */\n onAnswerAsk?: (formatted: string) => void;\n theme: WebBuilderTheme;\n bottomInset: number;\n}) {\n const [draft, setDraft] = useState('');\n // Questions the person closed without answering (the agent asks again if it needs to).\n const [dismissedAsks, setDismissedAsks] = useState<string[]>([]);\n const listRef = useRef<FlatList<Row>>(null);\n // Follow the conversation unless the person scrolled up to read; then offer a way back.\n const [atBottom, setAtBottom] = useState(true);\n const live = busy || Boolean(building);\n\n const rows = useMemo<Row[]>(() => {\n const out: Row[] = messages.map((m) => ({ kind: 'message', id: m.id, message: m }));\n if (build) out.push({ kind: 'site', id: `site-${build.key}` });\n if (live) out.push({ kind: 'live', id: 'live' });\n return out;\n }, [messages, build, live]);\n\n useEffect(() => {\n if (!atBottom) return undefined;\n const timer = setTimeout(() => listRef.current?.scrollToEnd({ animated: true }), 80);\n return () => clearTimeout(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rows.length, streaming]);\n\n const send = (text: string) => {\n const words = text.trim();\n if (!words) return;\n onSend(words);\n setDraft('');\n };\n\n const suggestions = messages.length === 0 && !live ? webbuilderAgentSuggestions(Boolean(build), siteTitle) : [];\n\n return (\n <KeyboardAvoidingView\n style={styles.fill}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n keyboardVerticalOffset={Platform.OS === 'ios' ? 96 : 0}\n >\n <FlatList\n ref={listRef}\n data={rows}\n keyExtractor={(row) => row.id}\n contentContainerStyle={styles.list}\n keyboardShouldPersistTaps=\"handled\"\n scrollEventThrottle={100}\n onScroll={(event) => {\n const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent;\n setAtBottom(layoutMeasurement.height + contentOffset.y >= contentSize.height - 48);\n }}\n ListEmptyComponent={\n <View style={styles.empty}>\n <View style={[styles.emptyMark, { backgroundColor: theme.accentSoft }]}>\n <MaterialCommunityIcons name=\"creation\" size={26} color={theme.accent} />\n </View>\n <Text style={[styles.emptyTitle, { color: theme.ink }]}>\n {build ? `What should change on ${siteTitle}?` : 'Describe your idea'}\n </Text>\n <Text style={[styles.emptyBody, { color: theme.muted }]}>\n {build\n ? 'Ask for new sections, another look, copy changes or fixes.'\n : \"Tell me what the site is for and I'll build it step by step.\"}\n </Text>\n </View>\n }\n ListFooterComponent={\n ask && onAnswerAsk && !dismissedAsks.includes(ask.requestId) ? (\n <View style={styles.askCard}>\n <AskUserCard\n key={ask.requestId}\n payload={ask}\n isDark={theme.isDark}\n onAnswer={onAnswerAsk}\n onDismiss={() => setDismissedAsks((prev) => [...prev, ask.requestId])}\n />\n </View>\n ) : null\n }\n renderItem={({ item }) => {\n if (item.kind === 'live')\n return <LiveTurn streaming={streaming} building={building} theme={theme} />;\n if (item.kind === 'site' && build) {\n return (\n <SiteCard\n build={build}\n title={siteTitle}\n busy={live}\n onOpen={onOpenPreview}\n onPublish={onPublish}\n onAsleep={onPreviewAsleep}\n theme={theme}\n />\n );\n }\n if (item.kind !== 'message') return null;\n const m = item.message;\n if (m.role === 'user') return <UserBubble text={m.displayContent ?? m.content} theme={theme} />;\n return <AgentTurn content={m.content} active={false} theme={theme} />;\n }}\n />\n\n {!atBottom ? (\n <Tap\n onPress={() => {\n setAtBottom(true);\n listRef.current?.scrollToEnd({ animated: true });\n }}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Jump to the latest\"\n style={[\n styles.jump,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"arrow-down\" size={20} color={theme.ink} />\n </Tap>\n ) : null}\n\n {suggestions.length ? (\n <View style={styles.suggestions}>\n {suggestions.slice(0, 3).map((s) => (\n <Tap\n key={s.id}\n onPress={() => send(s.prompt ?? s.label)}\n accessibilityRole=\"button\"\n style={[styles.suggestion, { backgroundColor: theme.card, borderColor: theme.border }]}\n pressedStyle={DIM}\n >\n <Text style={[styles.suggestionText, { color: theme.ink }]} numberOfLines={1}>\n {s.label}\n </Text>\n </Tap>\n ))}\n </View>\n ) : null}\n\n {error ? (\n <View style={[styles.error, { backgroundColor: theme.critSoft }]}>\n <MaterialCommunityIcons name=\"alert-circle-outline\" size={16} color={theme.crit} />\n <Text style={[styles.errorText, { color: theme.crit }]}>{error}</Text>\n </View>\n ) : null}\n\n <View\n style={[\n styles.composerDock,\n { backgroundColor: theme.screen, paddingBottom: Math.max(bottomInset, 10) },\n ]}\n >\n <View\n style={[\n styles.composer,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n >\n <TextInput\n value={draft}\n onChangeText={setDraft}\n placeholder=\"Message Web Builder\"\n placeholderTextColor={theme.faint}\n multiline\n style={[styles.input, { color: theme.ink }]}\n accessibilityLabel=\"Message the agent\"\n testID=\"webbuilder-chat-input\"\n />\n <Tap\n onPress={() => send(draft)}\n disabled={!draft.trim() || !connected}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Send\"\n style={[\n styles.send,\n { backgroundColor: draft.trim() && connected ? theme.accent : theme.chip },\n ]}\n pressedStyle={DIM}\n testID=\"webbuilder-chat-send\"\n >\n <MaterialCommunityIcons\n name=\"arrow-up\"\n size={20}\n color={draft.trim() && connected ? theme.accentInk : theme.faint}\n />\n </Tap>\n </View>\n {!connected ? (\n <Text style={[styles.connecting, { color: theme.muted }]}>Connecting to Web Builder…</Text>\n ) : null}\n </View>\n </KeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n askCard: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 12 },\n fill: { flex: 1 },\n list: { paddingHorizontal: 16, paddingTop: 16, paddingBottom: 12, gap: 18, flexGrow: 1 },\n userRow: { alignItems: 'flex-end' },\n userBubble: {\n maxWidth: '86%',\n paddingHorizontal: 14,\n paddingVertical: 10,\n borderRadius: 20,\n borderBottomRightRadius: 6,\n },\n userText: { fontSize: 16, lineHeight: 22 },\n agentTurn: { gap: 8 },\n agentHead: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n agentMark: { width: 24, height: 24, borderRadius: 8, alignItems: 'center', justifyContent: 'center' },\n agentName: { fontSize: 14, fontWeight: '700' },\n working: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n alignSelf: 'flex-start',\n maxWidth: '100%',\n paddingHorizontal: 14,\n paddingVertical: 10,\n borderRadius: 14,\n borderWidth: StyleSheet.hairlineWidth,\n },\n workingText: { flexShrink: 1, fontSize: 14, fontWeight: '600' },\n workingTime: { fontSize: 13, fontVariant: ['tabular-nums'] },\n site: {\n borderRadius: 22,\n borderWidth: StyleSheet.hairlineWidth,\n overflow: 'hidden',\n shadowOpacity: 0.06,\n shadowRadius: 14,\n shadowOffset: { width: 0, height: 4 },\n elevation: 2,\n },\n siteHead: { flexDirection: 'row', alignItems: 'center', gap: 14, padding: 16 },\n siteGlobe: { width: 48, height: 48, borderRadius: 14, alignItems: 'center', justifyContent: 'center' },\n siteHeadText: { flex: 1, gap: 2 },\n siteTitle: { fontSize: 18, fontWeight: '700', letterSpacing: -0.2 },\n siteStatus: { fontSize: 14 },\n siteView: {\n height: 240,\n borderTopWidth: StyleSheet.hairlineWidth,\n borderBottomWidth: StyleSheet.hairlineWidth,\n overflow: 'hidden',\n },\n siteWeb: { flex: 1, backgroundColor: 'transparent' },\n siteCover: { ...StyleSheet.absoluteFillObject, width: '100%', height: '100%' },\n hidden: { opacity: 0 },\n siteLoading: { ...StyleSheet.absoluteFillObject, alignItems: 'center', justifyContent: 'center', gap: 8 },\n siteLoadingText: { fontSize: 13 },\n siteBusy: {\n position: 'absolute',\n top: 10,\n right: 10,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n paddingHorizontal: 10,\n paddingVertical: 6,\n borderRadius: 999,\n },\n siteBusyText: { fontSize: 12, fontWeight: '600' },\n siteNote: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n marginHorizontal: 14,\n marginTop: 12,\n paddingHorizontal: 12,\n paddingVertical: 9,\n borderRadius: 12,\n },\n siteNoteText: { flex: 1, fontSize: 13, lineHeight: 18 },\n siteFoot: { flexDirection: 'row', gap: 10, padding: 14 },\n siteBtn: { flex: 1, height: 46, borderRadius: 23, alignItems: 'center', justifyContent: 'center' },\n siteBtnText: { fontSize: 16, fontWeight: '700' },\n disabled: { opacity: 0.35 },\n empty: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 32, gap: 8 },\n emptyMark: {\n width: 56,\n height: 56,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 6,\n },\n emptyTitle: { fontSize: 18, fontWeight: '700', textAlign: 'center' },\n emptyBody: { fontSize: 14, lineHeight: 20, textAlign: 'center' },\n suggestions: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, paddingHorizontal: 16, paddingBottom: 8 },\n suggestion: { paddingHorizontal: 14, paddingVertical: 8, borderRadius: 999, borderWidth: StyleSheet.hairlineWidth },\n suggestionText: { fontSize: 14, fontWeight: '500' },\n error: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n marginHorizontal: 16,\n marginBottom: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n borderRadius: 12,\n },\n errorText: { flex: 1, fontSize: 13, lineHeight: 18 },\n composerDock: { paddingHorizontal: 14, paddingTop: 8 },\n composer: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 8,\n minHeight: 58,\n borderRadius: 29,\n borderWidth: StyleSheet.hairlineWidth,\n paddingLeft: 18,\n paddingRight: 8,\n paddingVertical: 8,\n shadowOpacity: 0.1,\n shadowRadius: 18,\n shadowOffset: { width: 0, height: 6 },\n elevation: 6,\n },\n jump: {\n position: 'absolute',\n right: 16,\n bottom: 104,\n width: 44,\n height: 44,\n borderRadius: 22,\n borderWidth: StyleSheet.hairlineWidth,\n alignItems: 'center',\n justifyContent: 'center',\n shadowOpacity: 0.12,\n shadowRadius: 10,\n shadowOffset: { width: 0, height: 4 },\n elevation: 4,\n },\n input: { flex: 1, fontSize: 17, lineHeight: 22, maxHeight: 120, paddingTop: 10, paddingBottom: 10 },\n send: { width: 42, height: 42, borderRadius: 21, alignItems: 'center', justifyContent: 'center' },\n connecting: { fontSize: 12, textAlign: 'center', marginTop: 6 },\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAkCA,SAAS,aAAa,OAAyB,EAAA;AAC7C,EAAA,IAAI,OAAU,GAAA,EAAA,EAAW,OAAA,CAAA,EAAG,OAAO,CAAA,CAAA,CAAA;AACnC,EAAA,OAAO,CAAG,EAAA,IAAA,CAAK,KAAM,CAAA,OAAA,GAAU,EAAE,CAAC,CAAA,EAAA,EAAK,MAAO,CAAA,OAAA,GAAU,EAAE,CAAA,CAAE,QAAS,CAAA,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA,CAAA;AAC9E;AACA,SAAS,WAAW,SAAkC,EAAA;AACpD,EAAM,MAAA,CAAC,KAAK,MAAM,CAAA,GAAI,SAAS,MAAM,IAAA,CAAK,KAAK,CAAA;AAC/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,CAAC,WAAkB,OAAA,MAAA;AACvB,IAAM,MAAA,KAAA,GAAQ,YAAY,MAAM,MAAA,CAAO,KAAK,GAAI,EAAC,GAAG,GAAI,CAAA;AACxD,IAAO,OAAA,MAAM,cAAc,KAAK,CAAA;AAAA,GAClC,EAAG,CAAC,SAAS,CAAC,CAAA;AACd,EAAO,OAAA,SAAA,GAAY,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,IAAA,CAAK,OAAO,GAAM,GAAA,SAAA,IAAa,GAAI,CAAC,CAAI,GAAA,CAAA;AACzE;AACA,SAAS,UAAW,CAAA;AAAA,EAClB,IAAA;AAAA,EACA;AACF,CAGG,EAAA;AACD,EAAO,uBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,MAAO,CAAA,OAAA,EACjB,8BAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,UAAY,EAAA;AAAA,IACvC,iBAAiB,KAAM,CAAA;AAAA,GACxB,CACW,EAAA,QAAA,kBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,IACvC,OAAO,KAAM,CAAA;AAAA,GACd,CAAG,EAAA,UAAA,EAAU,IACC,EAAA,QAAA,EAAA,IAAA,EACL,GACJ,CACJ,EAAA,CAAA;AACR;AACA,SAAS,WAAY,CAAA;AAAA,EACnB;AACF,CAEG,EAAA;AACD,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,SACjB,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,MACtC,iBAAiB,KAAM,CAAA;AAAA,KACxB,CACW,EAAA,QAAA,kBAAA,GAAA,CAAC,sBAAuB,EAAA,EAAA,IAAA,EAAK,UAAW,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,SAAA,EAAW,CAC9E,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,MACtC,OAAO,KAAM,CAAA;AAAA,KACd,GAAG,QAAW,EAAA,aAAA,EAAA;AAAA,GACX,EAAA,CAAA;AACR;AACA,SAAS,SAAU,CAAA;AAAA,EACjB,OAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAIG,EAAA;AACD,EAAM,MAAA,MAAA,GAAS,OAAQ,CAAA,MAAM,iBAAkB,CAAA,OAAA,EAAS,MAAM,CAAG,EAAA,CAAC,OAAS,EAAA,MAAM,CAAC,CAAA;AAClF,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,SACjB,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,eAAY,KAAc,EAAA,CAAA;AAAA,IAC1B,MAAO,CAAA,KAAA,CAAM,MAAS,mBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,KAAA,EAAO,MAAO,CAAA,KAAA,EAAO,MAAgB,EAAA,MAAA,EAAQ,KAAM,CAAA,MAAA,EAAQ,CAAK,GAAA,IAAA;AAAA,IACpG,MAAO,CAAA,IAAA,mBAAQ,GAAA,CAAA,iBAAA,EAAA,EAAkB,IAAM,EAAA,MAAA,CAAO,IAAM,EAAA,SAAA,EAAW,MAAQ,EAAA,MAAA,EAAQ,KAAM,CAAA,MAAA,EAAQ,CAAK,GAAA;AAAA,GACvG,EAAA,CAAA;AACR;AACA,SAAS,QAAS,CAAA;AAAA,EAChB,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAIG,EAAA;AA1GH,EAAA,IAAA,EAAA;AA2GE,EAAA,MAAM,OAAU,GAAA,UAAA,CAAA,CAAW,EAAU,GAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAA,SAAA,KAAV,YAAuB,IAAI,CAAA;AACtD,EAAM,MAAA,MAAA,GAAS,OAAQ,CAAA,MAAM,iBAAkB,CAAA,SAAA,IAAA,IAAA,GAAA,SAAA,GAAa,IAAI,IAAI,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAClF,EAAA,MAAM,aAAa,CAAC,MAAA,CAAO,IAAQ,IAAA,MAAA,CAAO,MAAM,MAAW,KAAA,CAAA;AAC3D,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,SACjB,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,eAAY,KAAc,EAAA,CAAA;AAAA,IAC1B,MAAO,CAAA,KAAA,CAAM,MAAS,mBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,KAAA,EAAO,MAAO,CAAA,KAAA,EAAO,MAAM,EAAA,IAAA,EAAC,MAAQ,EAAA,KAAA,CAAM,QAAQ,CAAK,GAAA,IAAA;AAAA,IAC3F,MAAO,CAAA,IAAA,mBAAQ,GAAA,CAAA,iBAAA,EAAA,EAAkB,IAAM,EAAA,MAAA,CAAO,IAAM,EAAA,SAAA,EAAS,IAAC,EAAA,MAAA,EAAQ,KAAM,CAAA,MAAA,EAAQ,CAAK,GAAA,IAAA;AAAA,IACzF,6BAAc,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,OAAS,EAAA;AAAA,MAClD,iBAAiB,KAAM,CAAA,IAAA;AAAA,MACvB,aAAa,KAAM,CAAA;AAAA,KACpB,CACe,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,IAAA,EAAK,OAAQ,EAAA,KAAA,EAAO,MAAM,MAAQ,EAAA,CAAA;AAAA,sBACpD,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAC9C,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,aAAA,EAAe,CACA,EAAA,QAAA,EAAA,CAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,eAAc,gBAC7B,EAAA,CAAA;AAAA,MACC,2BAAY,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAC1D,OAAO,KAAM,CAAA;AAAA,OACd,CAAA,EAAI,QAAa,EAAA,YAAA,CAAA,OAAO,GAAE,CAAU,GAAA;AAAA,KAAA,EAC3B,CAAU,GAAA;AAAA,GAClB,EAAA,CAAA;AACR;AACA,SAAS,OAAO,EAAoB,EAAA;AAClC,EAAI,IAAA,CAAC,IAAW,OAAA,EAAA;AAChB,EAAM,MAAA,CAAA,GAAI,IAAI,IAAA,CAAK,EAAE,CAAA;AACrB,EAAA,OAAO,GAAG,MAAO,CAAA,CAAA,CAAE,UAAU,CAAA,CAAE,SAAS,CAAG,EAAA,GAAG,CAAC,CAAI,CAAA,EAAA,MAAA,CAAO,EAAE,UAAW,EAAC,EAAE,QAAS,CAAA,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAC5F;AAOA,SAAS,QAAS,CAAA;AAAA,EAChB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CASG,EAAA;AACD,EAAA,MAAM,MAAM,KAAM,CAAA,UAAA;AAClB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAG1C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAC1C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,KAAK,CAAA;AACf,IAAA,SAAA,CAAU,KAAK,CAAA;AAAA,GACjB,EAAG,CAAC,GAAG,CAAC,CAAA;AAGR,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,CAAC,CAAA;AACxC,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,CAAC,QAAe,OAAA,MAAA;AACpB,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,EAAA;AACA,MAAO,OAAA,MAAA;AAAA;AAET,IAAM,MAAA,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,SAAA,CAAU,KAAK,CAAA;AACf,MAAA,SAAA,CAAU,KAAK,CAAA;AACf,MAAW,UAAA,CAAA,CAAA,CAAA,KAAK,IAAI,CAAC,CAAA;AAAA,OACpB,GAAK,CAAA;AACR,IAAO,OAAA,MAAM,aAAa,KAAK,CAAA;AAAA,GAE9B,EAAA,CAAC,MAAQ,EAAA,IAAI,CAAC,CAAA;AAGjB,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,SAAA,CAAU,MAAM,cAAe,CAAA,KAAK,GAAG,CAAC,KAAA,CAAM,QAAQ,CAAC,CAAA;AACvD,EAAA,MAAM,QAAQ,KAAM,CAAA,QAAA,IAAY,CAAC,WAAA,GAAc,MAAM,QAAW,GAAA,IAAA;AAChE,EAAA,MAAM,MAAS,GAAA,KAAA,CAAM,OAAU,GAAA,CAAA,UAAA,EAAU,WAAY,CAAA,KAAA,CAAM,OAAO,CAAC,CAAK,CAAA,GAAA,CAAA,mBAAA,EAAmB,MAAO,CAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AAClH,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,IAChC,iBAAiB,KAAM,CAAA,IAAA;AAAA,IACvB,aAAa,KAAM,CAAA,MAAA;AAAA,IACnB,WAAA,EAAa,KAAM,CAAA,MAAA,GAAS,MAAS,GAAA;AAAA,GACtC,CACS,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAI,EAAA,EAAA,OAAA,EAAS,MAAQ,EAAA,iBAAA,EAAkB,QAAS,EAAA,kBAAA,EAAoB,CAAQ,KAAA,EAAA,KAAK,CAAI,CAAA,EAAA,KAAA,EAAO,MAAO,CAAA,QAAA,EAAU,cAAc,GACxH,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,QACxC,eAAiB,EAAA,KAAA,CAAM,OAAU,GAAA,KAAA,CAAM,OAAO,KAAM,CAAA;AAAA,OACrD,CACa,EAAA,QAAA,kBAAA,GAAA,CAAC,sBAAuB,EAAA,EAAA,IAAA,EAAK,KAAM,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,SAAA,EAAW,CACzE,EAAA,CAAA;AAAA,sBACC,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,YAChB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,UAC1C,OAAO,KAAM,CAAA;AAAA,SACd,CAAA,EAAG,aAAe,EAAA,CAAA,EACF,QACL,EAAA,KAAA,EAAA,CAAA;AAAA,wBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,UAC3C,OAAO,KAAM,CAAA;AAAA,SACd,CAAA,EAAG,aAAe,EAAA,CAAA,EACF,QACL,EAAA,MAAA,EAAA;AAAA,OACJ,EAAA;AAAA,KACJ,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,GAAA,EAAA,EAAI,OAAS,EAAA,MAAA,EAAQ,mBAAkB,QAAS,EAAA,kBAAA,EAAoB,CAAuB,oBAAA,EAAA,KAAK,IAC7F,QAAC,kBAAA,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,MACvC,iBAAiB,KAAM,CAAA,KAAA;AAAA,MACvB,aAAa,KAAM,CAAA;AAAA,KACpB,CAAG,EAAA,aAAA,EAAc,MACH,EAAA,QAAA,EAAA;AAAA,MAAQ,KAAA,mBAAA,GAAA,CAAC,SAAM,MAAQ,EAAA;AAAA,QAClC,GAAK,EAAA;AAAA,OACJ,EAAA,KAAA,EAAO,MAAO,CAAA,SAAA,EAAW,UAAW,EAAA,OAAA,EAAQ,OAAS,EAAA,MAAM,cAAe,CAAA,IAAI,CAAG,EAAA,gCAAA,EAAgC,MAAC,CAAK,GAAA,IAAA;AAAA,MAC7G,CAAC,KAAA,IAAS,GAAM,mBAAA,GAAA,CAAC,WAAkC,MAAQ,EAAA;AAAA,QACtE,GAAK,EAAA;AAAA,OACJ,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,OAAS,EAAA,CAAC,MAAU,IAAA,MAAA,CAAO,MAAM,CAAA,EAAG,aAAe,EAAA,KAAA,EAAO,mBAAiB,IAAC,EAAA,iBAAA,EAAiB,IAAC,EAAA,eAAA,EAAiB,CAAC,GAAG,CAAG,EAAA,eAAA,EAAe,IAAC,EAAA,kBAAA,EAAoB,uBAAyB,EAAA,SAAA,EAAW,MAAM,SAAA,CAAU,IAAI,CAAA,EAAG,aAAa,CAAS,KAAA,KAAA;AAC3P,QAAA,IAAI,KAAM,CAAA,WAAA,CAAY,UAAc,IAAA,GAAA,YAAe,IAAI,CAAA;AAAA,OACzD,EAAG,OAAS,EAAA,MAAM,SAAU,CAAA,IAAI,CAJW,EAAA,EAAA,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,OAAO,CAAA,CAIzB,CAAK,GAAA,IAAA;AAAA,MAC3B,CAAC,SAAS,MAAS,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAChE,iBAAiB,KAAM,CAAA;AAAA,OACxB,GACmB,QAAC,kBAAA,GAAA,CAAA,kBAAA,EAAA,EAAmB,OAAc,OAAO,EAAA,IAAA,EAAC,GAC9C,CAAU,GAAA,IAAA;AAAA,MACb,CAAC,KAAA,IAAS,CAAC,MAAA,KAAW,CAAC,GAAA,IAAO,CAAC,MAAA,CAAA,mBAAW,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,WACtD,EAAA,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,iBAAA,EAAA,EAAkB,KAAO,EAAA,KAAA,CAAM,MAAQ,EAAA,CAAA;AAAA,wBACvC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,eAAiB,EAAA;AAAA,UACtD,OAAO,KAAM,CAAA;AAAA,SACd,GAAG,QAAgB,EAAA,uBAAA,EAAA;AAAA,OAAA,EACN,CAAU,GAAA,IAAA;AAAA,MACb,IAAA,KAAS,KAAS,IAAA,MAAA,IAAU,CAAC,MAAA,CAAA,wBAAW,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QACjF,iBAAiB,KAAM,CAAA;AAAA,OACxB,CACmB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,iBAAkB,EAAA,EAAA,IAAA,EAAK,OAAQ,EAAA,KAAA,EAAO,MAAM,MAAQ,EAAA,CAAA;AAAA,wBACpD,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,UACnD,OAAO,KAAM,CAAA;AAAA,SACd,GAAG,QAAS,EAAA,gBAAA,EAAA;AAAA,OAAA,EACC,CAAU,GAAA;AAAA,KAAA,EAClB,CACJ,EAAA,CAAA;AAAA,IACC,KAAA,CAAM,MAAW,KAAA,OAAA,IAAW,CAAC,KAAA,CAAM,OAAU,mBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,MACnF,iBAAiB,KAAM,CAAA;AAAA,KACxB,CACe,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,eAAA,EAAgB,MAAM,EAAI,EAAA,KAAA,EAAO,MAAM,IAAM,EAAA,CAAA;AAAA,sBACzE,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,QAC/C,OAAO,KAAM,CAAA;AAAA,OACd,CAAA,EACkB,QAAM,EAAA,KAAA,CAAA,UAAA,GAAa,gHAAgH,mFACxI,EAAA;AAAA,KAAA,EACJ,CAAU,GAAA,IAAA;AAAA,oBACb,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,QAChB,EAAA,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,GAAA,EAAA,EAAI,SAAS,MAAQ,EAAA,iBAAA,EAAkB,UAAS,KAAO,EAAA,CAAC,OAAO,OAAS,EAAA;AAAA,QACjF,iBAAiB,KAAM,CAAA;AAAA,OACxB,CAAG,EAAA,YAAA,EAAc,GAAK,EAAA,MAAA,EAAO,yBAChB,EAAA,QAAA,kBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,WAAa,EAAA;AAAA,QAC5C,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,QAAA,EAAA,SAAA,EAAO,CACH,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,GAAA,EAAA,EAAI,OAAS,EAAA,SAAA,EAAW,QAAU,EAAA,CAAC,KAAM,CAAA,SAAA,EAAW,iBAAkB,EAAA,QAAA,EAAS,KAAO,EAAA,CAAC,OAAO,OAAS,EAAA;AAAA,QAChH,iBAAiB,KAAM,CAAA;AAAA,SACtB,CAAC,KAAA,CAAM,SAAa,IAAA,MAAA,CAAO,QAAQ,CAAG,EAAA,YAAA,EAAc,GAAK,EAAA,MAAA,EAAO,2BACrD,QAAC,kBAAA,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QAC5C,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,QAAA,EAAA,SAAA,EAAO,CACH,EAAA;AAAA,KACJ,EAAA;AAAA,GACJ,EAAA,CAAA;AACR;AACO,SAAS,WAAY,CAAA;AAAA,EAC1B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,GAAM,GAAA,IAAA;AAAA,EACN,WAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAoBG,EAAA;AACD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AAErC,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AAC/D,EAAM,MAAA,OAAA,GAAU,OAAsB,IAAI,CAAA;AAE1C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,IAAI,CAAA;AAC7C,EAAM,MAAA,IAAA,GAAO,IAAQ,IAAA,OAAA,CAAQ,QAAQ,CAAA;AACrC,EAAM,MAAA,IAAA,GAAO,QAAe,MAAM;AAChC,IAAM,MAAA,GAAA,GAAa,QAAS,CAAA,GAAA,CAAI,CAAM,CAAA,MAAA;AAAA,MACpC,IAAM,EAAA,SAAA;AAAA,MACN,IAAI,CAAE,CAAA,EAAA;AAAA,MACN,OAAS,EAAA;AAAA,KACT,CAAA,CAAA;AACF,IAAI,IAAA,KAAA,MAAW,IAAK,CAAA;AAAA,MAClB,IAAM,EAAA,MAAA;AAAA,MACN,EAAA,EAAI,CAAQ,KAAA,EAAA,KAAA,CAAM,GAAG,CAAA;AAAA,KACtB,CAAA;AACD,IAAI,IAAA,IAAA,MAAU,IAAK,CAAA;AAAA,MACjB,IAAM,EAAA,MAAA;AAAA,MACN,EAAI,EAAA;AAAA,KACL,CAAA;AACD,IAAO,OAAA,GAAA;AAAA,GACN,EAAA,CAAC,QAAU,EAAA,KAAA,EAAO,IAAI,CAAC,CAAA;AAC1B,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,CAAC,UAAiB,OAAA,MAAA;AACtB,IAAM,MAAA,KAAA,GAAQ,WAAW,MAAG;AApVhC,MAAA,IAAA,EAAA;AAoVmC,MAAQ,OAAA,CAAA,EAAA,GAAA,OAAA,CAAA,OAAA,KAAR,mBAAiB,WAAY,CAAA;AAAA,QAC1D,QAAU,EAAA;AAAA,OACZ,CAAA;AAAA,KAAA,EAAI,EAAE,CAAA;AACN,IAAO,OAAA,MAAM,aAAa,KAAK,CAAA;AAAA,GAE9B,EAAA,CAAC,IAAK,CAAA,MAAA,EAAQ,SAAS,CAAC,CAAA;AAC3B,EAAM,MAAA,IAAA,GAAO,CAAC,IAAiB,KAAA;AAC7B,IAAM,MAAA,KAAA,GAAQ,KAAK,IAAK,EAAA;AACxB,IAAA,IAAI,CAAC,KAAO,EAAA;AACZ,IAAA,MAAA,CAAO,KAAK,CAAA;AACZ,IAAA,QAAA,CAAS,EAAE,CAAA;AAAA,GACb;AACA,EAAA,MAAM,WAAc,GAAA,QAAA,CAAS,MAAW,KAAA,CAAA,IAAK,CAAC,IAAA,GAAO,0BAA2B,CAAA,OAAA,CAAQ,KAAK,CAAA,EAAG,SAAS,CAAA,GAAI,EAAC;AAC9G,EAAA,4BAAQ,oBAAqB,EAAA,EAAA,KAAA,EAAO,MAAO,CAAA,IAAA,EAAM,UAAU,QAAS,CAAA,EAAA,KAAO,KAAQ,GAAA,SAAA,GAAY,QAAW,sBAAwB,EAAA,QAAA,CAAS,EAAO,KAAA,KAAA,GAAQ,KAAK,CACrJ,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAS,GAAK,EAAA,OAAA,EAAS,IAAM,EAAA,IAAA,EAAM,cAAc,CAAO,GAAA,KAAA,GAAA,CAAI,EAAI,EAAA,qBAAA,EAAuB,OAAO,IAAM,EAAA,yBAAA,EAA0B,WAAU,mBAAqB,EAAA,GAAA,EAAK,UAAU,CAAS,KAAA,KAAA;AAC5L,MAAM,MAAA;AAAA,QACJ,iBAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA,UACE,KAAM,CAAA,WAAA;AACV,MAAA,WAAA,CAAY,kBAAkB,MAAS,GAAA,aAAA,CAAc,CAAK,IAAA,WAAA,CAAY,SAAS,EAAE,CAAA;AAAA,OAChF,kBAAoB,kBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,OAAO,KACvB,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,QAChD,iBAAiB,KAAM,CAAA;AAAA,OACxB,CACqB,EAAA,QAAA,kBAAA,GAAA,CAAC,sBAAuB,EAAA,EAAA,IAAA,EAAK,UAAW,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,MAAA,EAAQ,CAC3E,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,QACjD,OAAO,KAAM,CAAA;AAAA,OACd,CACsB,EAAA,QAAA,EAAA,KAAA,GAAQ,CAAyB,sBAAA,EAAA,SAAS,MAAM,oBACrD,EAAA,CAAA;AAAA,sBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,QAChD,OAAO,KAAM,CAAA;AAAA,OACd,CAAA,EACsB,QAAQ,EAAA,KAAA,GAAA,4DAAA,GAA+D,8DAC5E,EAAA;AAAA,KAAA,EACJ,GAAS,mBAAqB,EAAA,GAAA,IAAO,eAAe,CAAC,aAAA,CAAc,SAAS,GAAI,CAAA,SAAS,CAAI,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,MAAA,CAAO,SACzG,QAAC,kBAAA,GAAA,CAAA,WAAA,EAAA,EAAgC,SAAS,GAAK,EAAA,MAAA,EAAQ,KAAM,CAAA,MAAA,EAAQ,UAAU,WAAa,EAAA,SAAA,EAAW,MAAM,gBAAiB,CAAA,CAAA,IAAA,KAAQ,CAAC,GAAG,IAAA,EAAM,IAAI,SAAS,CAAC,KAA5I,GAAI,CAAA,SAA2I,GACrK,CAAU,GAAA,IAAA,EAAM,YAAY,CAAC;AAAA,MAC/C;AAAA,KACI,KAAA;AA7XV,MAAA,IAAA,EAAA;AA8XM,MAAI,IAAA,IAAA,CAAK,SAAS,MAAQ,EAAA,2BAAQ,QAAS,EAAA,EAAA,SAAA,EAAsB,UAAoB,KAAc,EAAA,CAAA;AACnG,MAAI,IAAA,IAAA,CAAK,IAAS,KAAA,MAAA,IAAU,KAAO,EAAA;AACjC,QAAA,uBAAQ,GAAA,CAAA,QAAA,EAAA,EAAS,KAAc,EAAA,KAAA,EAAO,SAAW,EAAA,IAAA,EAAM,IAAM,EAAA,MAAA,EAAQ,aAAe,EAAA,SAAA,EAAsB,QAAU,EAAA,eAAA,EAAiB,KAAc,EAAA,CAAA;AAAA;AAErJ,MAAI,IAAA,IAAA,CAAK,IAAS,KAAA,SAAA,EAAkB,OAAA,IAAA;AACpC,MAAA,MAAM,IAAI,IAAK,CAAA,OAAA;AACf,MAAA,IAAI,CAAE,CAAA,IAAA,KAAS,MAAQ,EAAA,uBAAQ,GAAA,CAAA,UAAA,EAAA,EAAW,IAAM,EAAA,CAAA,EAAA,GAAA,CAAA,CAAE,cAAF,KAAA,IAAA,GAAA,EAAA,GAAoB,CAAE,CAAA,OAAA,EAAS,KAAc,EAAA,CAAA;AAC7F,MAAA,2BAAQ,SAAU,EAAA,EAAA,OAAA,EAAS,EAAE,OAAS,EAAA,MAAA,EAAQ,OAAO,KAAc,EAAA,CAAA;AAAA,KAClE,EAAA,CAAA;AAAA,IAEM,CAAC,QAAA,mBAAY,GAAA,CAAA,GAAA,EAAA,EAAI,SAAS,MAAM;AAxY7C,MAAA,IAAA,EAAA;AAyYM,MAAA,WAAA,CAAY,IAAI,CAAA;AAChB,MAAQ,CAAA,EAAA,GAAA,OAAA,CAAA,OAAA,KAAR,mBAAiB,WAAY,CAAA;AAAA,QAC3B,QAAU,EAAA;AAAA,OACZ,CAAA;AAAA,KACF,EAAG,mBAAkB,QAAS,EAAA,kBAAA,EAAmB,sBAAqB,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,MACzF,iBAAiB,KAAM,CAAA,IAAA;AAAA,MACvB,aAAa,KAAM,CAAA,MAAA;AAAA,MACnB,WAAA,EAAa,KAAM,CAAA,MAAA,GAAS,MAAS,GAAA;AAAA,KACtC,CAAA,EAAG,YAAc,EAAA,GAAA,EACF,8BAAC,sBAAuB,EAAA,EAAA,IAAA,EAAK,YAAa,EAAA,IAAA,EAAM,EAAI,EAAA,KAAA,EAAO,KAAM,CAAA,GAAA,EAAK,GAC1E,CAAS,GAAA,IAAA;AAAA,IAEZ,YAAY,MAAS,mBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,OAAO,WACjC,EAAA,QAAA,EAAA,WAAA,CAAY,KAAM,CAAA,CAAA,EAAG,CAAC,CAAE,CAAA,GAAA,CAAI,uBAAM,GAAA,CAAA,GAAA,EAAA,EAAe,SAAS,MAAG;AAtZlF,MAAA,IAAA,EAAA;AAsZqF,MAAA,OAAA,IAAA,CAAA,CAAK,EAAE,GAAA,CAAA,CAAA,MAAA,KAAF,IAAY,GAAA,EAAA,GAAA,CAAA,CAAE,KAAK,CAAA;AAAA,KAAA,EAAG,iBAAkB,EAAA,QAAA,EAAS,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,MAC9J,iBAAiB,KAAM,CAAA,IAAA;AAAA,MACvB,aAAa,KAAM,CAAA;AAAA,KACpB,GAAG,YAAc,EAAA,GAAA,EACI,8BAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,cAAgB,EAAA;AAAA,MACvD,OAAO,KAAM,CAAA;AAAA,KACd,CAAG,EAAA,aAAA,EAAe,CACM,EAAA,QAAA,EAAA,CAAA,CAAE,KACP,EAAA,CAAA,EAAA,EARoC,CAAE,CAAA,EAS1C,CAAM,CAAA,EACd,CAAU,GAAA,IAAA;AAAA,IAEb,wBAAS,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,MAC3C,iBAAiB,KAAM,CAAA;AAAA,KACxB,CACe,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,sBAAA,EAAuB,MAAM,EAAI,EAAA,KAAA,EAAO,MAAM,IAAM,EAAA,CAAA;AAAA,sBAChF,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,SAAW,EAAA;AAAA,QAC5C,OAAO,KAAM,CAAA;AAAA,OACd,GAAI,QAAM,EAAA,KAAA,EAAA;AAAA,KAAA,EACD,CAAU,GAAA,IAAA;AAAA,oBAEb,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,YAAc,EAAA;AAAA,MACzC,iBAAiB,KAAM,CAAA,MAAA;AAAA,MACvB,aAAe,EAAA,IAAA,CAAK,GAAI,CAAA,WAAA,EAAa,EAAE;AAAA,KACxC,CACW,EAAA,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAU,EAAA;AAAA,QACvC,iBAAiB,KAAM,CAAA,IAAA;AAAA,QACvB,aAAa,KAAM,CAAA,MAAA;AAAA,QACnB,WAAA,EAAa,KAAM,CAAA,MAAA,GAAS,MAAS,GAAA;AAAA,OACtC,CACa,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAU,EAAA,EAAA,KAAA,EAAO,KAAO,EAAA,YAAA,EAAc,UAAU,WAAY,EAAA,qBAAA,EAAsB,oBAAsB,EAAA,KAAA,CAAM,OAAO,SAAS,EAAA,IAAA,EAAC,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,UAChK,OAAO,KAAM,CAAA;AAAA,SACd,CAAA,EAAG,kBAAmB,EAAA,mBAAA,EAAoB,QAAO,uBAAwB,EAAA,CAAA;AAAA,wBAC9D,GAAA,CAAC,OAAI,OAAS,EAAA,MAAM,KAAK,KAAK,CAAA,EAAG,UAAU,CAAC,KAAA,CAAM,MAAU,IAAA,CAAC,WAAW,iBAAkB,EAAA,QAAA,EAAS,oBAAmB,MAAO,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,IAAM,EAAA;AAAA,UAC5J,iBAAiB,KAAM,CAAA,IAAA,MAAU,SAAY,GAAA,KAAA,CAAM,SAAS,KAAM,CAAA;AAAA,SACnE,GAAG,YAAc,EAAA,GAAA,EAAK,QAAO,sBACd,EAAA,QAAA,kBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,UAAA,EAAW,MAAM,EAAI,EAAA,KAAA,EAAO,MAAM,IAAK,EAAA,IAAK,YAAY,KAAM,CAAA,SAAA,GAAY,KAAM,CAAA,KAAA,EAAO,CACxH,EAAA;AAAA,OACJ,EAAA,CAAA;AAAA,MACC,CAAC,SAAY,mBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,CAAC,OAAO,UAAY,EAAA;AAAA,QACvD,OAAO,KAAM,CAAA;AAAA,OACd,CAAG,EAAA,QAAA,EAAA,iCAAA,EAA0B,CAAU,GAAA;AAAA,KAClC,EAAA;AAAA,GACJ,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,OAAS,EAAA;AAAA,IACP,iBAAmB,EAAA,EAAA;AAAA,IACnB,UAAY,EAAA,CAAA;AAAA,IACZ,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,iBAAmB,EAAA,EAAA;AAAA,IACnB,UAAY,EAAA,EAAA;AAAA,IACZ,aAAe,EAAA,EAAA;AAAA,IACf,GAAK,EAAA,EAAA;AAAA,IACL,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,OAAS,EAAA;AAAA,IACP,UAAY,EAAA;AAAA,GACd;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,KAAA;AAAA,IACV,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,YAAc,EAAA,EAAA;AAAA,IACd,uBAAyB,EAAA;AAAA,GAC3B;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,SAAW,EAAA;AAAA,IACT,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,CAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,OAAS,EAAA;AAAA,IACP,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,EAAA;AAAA,IACL,SAAW,EAAA,YAAA;AAAA,IACX,QAAU,EAAA,MAAA;AAAA,IACV,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,YAAc,EAAA,EAAA;AAAA,IACd,aAAa,UAAW,CAAA;AAAA,GAC1B;AAAA,EACA,WAAa,EAAA;AAAA,IACX,UAAY,EAAA,CAAA;AAAA,IACZ,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,WAAA,EAAa,CAAC,cAAc;AAAA,GAC9B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,YAAc,EAAA,EAAA;AAAA,IACd,aAAa,UAAW,CAAA,aAAA;AAAA,IACxB,QAAU,EAAA,QAAA;AAAA,IACV,aAAe,EAAA,IAAA;AAAA,IACf,YAAc,EAAA,EAAA;AAAA,IACd,YAAc,EAAA;AAAA,MACZ,KAAO,EAAA,CAAA;AAAA,MACP,MAAQ,EAAA;AAAA,KACV;AAAA,IACA,SAAW,EAAA;AAAA,GACb;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,EAAA;AAAA,IACL,OAAS,EAAA;AAAA,GACX;AAAA,EACA,SAAW,EAAA;AAAA,IACT,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,IAAM,EAAA,CAAA;AAAA,IACN,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,QAAU,EAAA;AAAA,IACR,MAAQ,EAAA,GAAA;AAAA,IACR,gBAAgB,UAAW,CAAA,aAAA;AAAA,IAC3B,mBAAmB,UAAW,CAAA,aAAA;AAAA,IAC9B,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,OAAS,EAAA;AAAA,IACP,IAAM,EAAA,CAAA;AAAA,IACN,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,SAAA,EAAW,aACN,CAAA,cAAA,CAAA,EAAA,EAAA,UAAA,CAAW,kBADL,CAAA,EAAA;AAAA,IAET,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACV,CAAA;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,OAAS,EAAA;AAAA,GACX;AAAA,EACA,WAAA,EAAa,aACR,CAAA,cAAA,CAAA,EAAA,EAAA,UAAA,CAAW,kBADH,CAAA,EAAA;AAAA,IAEX,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,GAAK,EAAA;AAAA,GACP,CAAA;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,UAAA;AAAA,IACV,GAAK,EAAA,EAAA;AAAA,IACL,KAAO,EAAA,EAAA;AAAA,IACP,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,CAAA;AAAA,IACjB,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,YAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,gBAAkB,EAAA,EAAA;AAAA,IAClB,SAAW,EAAA,EAAA;AAAA,IACX,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,CAAA;AAAA,IACjB,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,GAAK,EAAA,EAAA;AAAA,IACL,OAAS,EAAA;AAAA,GACX;AAAA,EACA,OAAS,EAAA;AAAA,IACP,IAAM,EAAA,CAAA;AAAA,IACN,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,WAAa,EAAA;AAAA,IACX,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,OAAS,EAAA;AAAA,GACX;AAAA,EACA,KAAO,EAAA;AAAA,IACL,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,iBAAmB,EAAA,EAAA;AAAA,IACnB,GAAK,EAAA;AAAA,GACP;AAAA,EACA,SAAW,EAAA;AAAA,IACT,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,SAAW,EAAA;AAAA,GACb;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,EAAA;AAAA,IACZ,SAAW,EAAA;AAAA,GACb;AAAA,EACA,WAAa,EAAA;AAAA,IACX,aAAe,EAAA,KAAA;AAAA,IACf,QAAU,EAAA,MAAA;AAAA,IACV,GAAK,EAAA,CAAA;AAAA,IACL,iBAAmB,EAAA,EAAA;AAAA,IACnB,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,CAAA;AAAA,IACjB,YAAc,EAAA,GAAA;AAAA,IACd,aAAa,UAAW,CAAA;AAAA,GAC1B;AAAA,EACA,cAAgB,EAAA;AAAA,IACd,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,KAAO,EAAA;AAAA,IACL,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,YAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,gBAAkB,EAAA,EAAA;AAAA,IAClB,YAAc,EAAA,CAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA;AAAA,GACd;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,iBAAmB,EAAA,EAAA;AAAA,IACnB,UAAY,EAAA;AAAA,GACd;AAAA,EACA,QAAU,EAAA;AAAA,IACR,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,UAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,SAAW,EAAA,EAAA;AAAA,IACX,YAAc,EAAA,EAAA;AAAA,IACd,aAAa,UAAW,CAAA,aAAA;AAAA,IACxB,WAAa,EAAA,EAAA;AAAA,IACb,YAAc,EAAA,CAAA;AAAA,IACd,eAAiB,EAAA,CAAA;AAAA,IACjB,aAAe,EAAA,GAAA;AAAA,IACf,YAAc,EAAA,EAAA;AAAA,IACd,YAAc,EAAA;AAAA,MACZ,KAAO,EAAA,CAAA;AAAA,MACP,MAAQ,EAAA;AAAA,KACV;AAAA,IACA,SAAW,EAAA;AAAA,GACb;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,QAAU,EAAA,UAAA;AAAA,IACV,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,GAAA;AAAA,IACR,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,aAAa,UAAW,CAAA,aAAA;AAAA,IACxB,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,aAAe,EAAA,IAAA;AAAA,IACf,YAAc,EAAA,EAAA;AAAA,IACd,YAAc,EAAA;AAAA,MACZ,KAAO,EAAA,CAAA;AAAA,MACP,MAAQ,EAAA;AAAA,KACV;AAAA,IACA,SAAW,EAAA;AAAA,GACb;AAAA,EACA,KAAO,EAAA;AAAA,IACL,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,EAAA;AAAA,IACZ,SAAW,EAAA,GAAA;AAAA,IACX,UAAY,EAAA,EAAA;AAAA,IACZ,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,SAAW,EAAA;AAAA;AAEf,CAAC,CAAA"}
1
+ {"version":3,"file":"ProjectChat.js","sources":["../../../../src/features/webbuilder/components/ProjectChat.tsx"],"sourcesContent":["/**\n * A project's conversation, the way Manus shows an agent at work: what you\n * asked, then the agent's turn - its live steps (\"Working · 12s\" with each tool\n * it ran), what it says, and once there is a site, a live card of it with Open\n * preview and Publish. The composer stays at the bottom for the next change.\n */\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n ActivityIndicator,\n FlatList,\n Image,\n KeyboardAvoidingView,\n Platform,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport { AssistantMarkdown } from '../../chat/AssistantMarkdown';\nimport { ToolTimeline } from '../../chat/ToolTimeline';\nimport { parseToolActivity } from '../../chat/toolActivity';\nimport { AskUserCard } from '../../chat/AskUserCard';\nimport type { AskUserPayload } from '../../chat/askUser';\nimport type { AgentChatMessage } from '../../agent-chat';\nimport { displayHost } from '../buildFragments';\nimport type { WebBuilderBuild, WebBuilderBuilding } from '../types';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { DESKTOP_VIEWPORT_SCRIPT } from './PreviewFrame';\nimport { PreviewPlaceholder } from './PreviewPlaceholder';\nimport { webbuilderAgentSuggestions } from '../webbuilderPrompts';\n\ntype Row =\n | { kind: 'message'; id: string; message: AgentChatMessage }\n | { kind: 'live'; id: string }\n | { kind: 'site'; id: string };\n\nfunction elapsedLabel(seconds: number): string {\n if (seconds < 60) return `${seconds}s`;\n return `${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, '0')}s`;\n}\n\nfunction useElapsed(startedAt: number | null): number {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!startedAt) return undefined;\n const timer = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(timer);\n }, [startedAt]);\n return startedAt ? Math.max(0, Math.floor((now - startedAt) / 1000)) : 0;\n}\n\nfunction UserBubble({ text, theme }: { text: string; theme: WebBuilderTheme }) {\n return (\n <View style={styles.userRow}>\n <View style={[styles.userBubble, { backgroundColor: theme.chip }]}>\n <Text style={[styles.userText, { color: theme.ink }]} selectable>\n {text}\n </Text>\n </View>\n </View>\n );\n}\n\nfunction AgentAvatar({ theme }: { theme: WebBuilderTheme }) {\n return (\n <View style={styles.agentHead}>\n <View style={[styles.agentMark, { backgroundColor: theme.accent }]}>\n <MaterialCommunityIcons name=\"creation\" size={14} color={theme.accentInk} />\n </View>\n <Text style={[styles.agentName, { color: theme.ink }]}>Web Builder</Text>\n </View>\n );\n}\n\nfunction AgentTurn({ content, active, theme }: { content: string; active: boolean; theme: WebBuilderTheme }) {\n const parsed = useMemo(() => parseToolActivity(content, active), [content, active]);\n return (\n <View style={styles.agentTurn}>\n <AgentAvatar theme={theme} />\n {parsed.steps.length ? <ToolTimeline steps={parsed.steps} active={active} isDark={theme.isDark} /> : null}\n {parsed.text ? <AssistantMarkdown text={parsed.text} streaming={active} isDark={theme.isDark} /> : null}\n </View>\n );\n}\n\nfunction LiveTurn({\n streaming,\n building,\n theme,\n}: {\n streaming: string | null;\n building: WebBuilderBuilding | null;\n theme: WebBuilderTheme;\n}) {\n const elapsed = useElapsed(building?.startedAt ?? null);\n const parsed = useMemo(() => parseToolActivity(streaming ?? '', true), [streaming]);\n const showStatus = !parsed.text && parsed.steps.length === 0;\n return (\n <View style={styles.agentTurn}>\n <AgentAvatar theme={theme} />\n {parsed.steps.length ? <ToolTimeline steps={parsed.steps} active isDark={theme.isDark} /> : null}\n {parsed.text ? <AssistantMarkdown text={parsed.text} streaming isDark={theme.isDark} /> : null}\n {showStatus ? (\n <View style={[styles.working, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <ActivityIndicator size=\"small\" color={theme.accent} />\n <Text style={[styles.workingText, { color: theme.ink }]} numberOfLines={2}>\n {building?.statusText || 'Thinking…'}\n </Text>\n {building ? (\n <Text style={[styles.workingTime, { color: theme.muted }]}>{elapsedLabel(elapsed)}</Text>\n ) : null}\n </View>\n ) : null}\n </View>\n );\n}\n\nfunction timeOf(ms: number): string {\n if (!ms) return '';\n const d = new Date(ms);\n return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;\n}\n\n/**\n * The site as it is now - Manus's app card: what it is and whether it is live,\n * a glimpse of the running page (laid out at desktop width and fitted, so it\n * reads as the site rather than a cropped corner), and the two ways forward.\n */\nfunction SiteCard({\n build,\n title,\n busy,\n onOpen,\n onPublish,\n onAsleep,\n theme,\n}: {\n build: WebBuilderBuild;\n title: string;\n busy: boolean;\n onOpen: () => void;\n onPublish: () => void;\n /** The live page answered 5xx: start bringing it back (web `ensurePreview` on open). */\n onAsleep?: () => void;\n theme: WebBuilderTheme;\n}) {\n const url = build.previewUrl;\n const [loaded, setLoaded] = useState(false);\n // A sandbox that slept or was reclaimed answers with the host's own error page\n // (E2B \"502 Sandbox not found\"); that page is never shown, the card says what it means.\n const [asleep, setAsleep] = useState(false);\n useEffect(() => {\n setLoaded(false);\n setAsleep(false);\n }, [url]);\n // During the agent's turn a 5xx means its dev server is still starting: check again\n // every 3 s and leave the sandbox to the agent; wake it only once the turn ends (web #431).\n const [recheck, setRecheck] = useState(0);\n useEffect(() => {\n if (!asleep) return undefined;\n if (!busy) {\n onAsleep?.();\n return undefined;\n }\n const timer = setTimeout(() => {\n setAsleep(false);\n setLoaded(false);\n setRecheck((n) => n + 1);\n }, 3_000);\n return () => clearTimeout(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [asleep, busy]);\n // Cover first, live page only without one - the web CreationTile's order. The\n // screenshot is instant and needs no awake sandbox, so it outlives the preview.\n const [coverFailed, setCoverFailed] = useState(false);\n useEffect(() => setCoverFailed(false), [build.coverUrl]);\n const cover = build.coverUrl && !coverFailed ? build.coverUrl : null;\n const status = build.liveUrl\n ? `Live · ${displayHost(build.liveUrl)}`\n : `Not published · ${timeOf(build.updatedAt)}`;\n return (\n <View\n style={[\n styles.site,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n >\n <Tap\n onPress={onOpen}\n accessibilityRole=\"button\"\n accessibilityLabel={`Open ${title}`}\n style={styles.siteHead}\n pressedStyle={DIM}\n >\n <View style={[styles.siteGlobe, { backgroundColor: build.liveUrl ? theme.good : theme.accent }]}>\n <MaterialCommunityIcons name=\"web\" size={24} color={theme.accentInk} />\n </View>\n <View style={styles.siteHeadText}>\n <Text style={[styles.siteTitle, { color: theme.ink }]} numberOfLines={1}>\n {title}\n </Text>\n <Text style={[styles.siteStatus, { color: theme.muted }]} numberOfLines={1}>\n {status}\n </Text>\n </View>\n </Tap>\n <Tap onPress={onOpen} accessibilityRole=\"button\" accessibilityLabel={`Open the preview of ${title}`}>\n <View\n style={[styles.siteView, { backgroundColor: theme.stage, borderColor: theme.border }]}\n pointerEvents=\"none\"\n >\n {cover ? (\n <Image\n source={{ uri: cover }}\n style={styles.siteCover}\n resizeMode=\"cover\"\n onError={() => setCoverFailed(true)}\n accessibilityIgnoresInvertColors\n />\n ) : null}\n {!cover && url ? (\n <WebView\n key={`${url}-${recheck}`}\n source={{ uri: url }}\n style={[styles.siteWeb, !loaded && styles.hidden]}\n scrollEnabled={false}\n javaScriptEnabled\n domStorageEnabled\n originWhitelist={['*']}\n scalesPageToFit\n injectedJavaScript={DESKTOP_VIEWPORT_SCRIPT}\n onLoadEnd={() => setLoaded(true)}\n onHttpError={(event) => {\n if (event.nativeEvent.statusCode >= 500) setAsleep(true);\n }}\n onError={() => setAsleep(true)}\n />\n ) : null}\n {!cover && asleep ? (\n <View style={[styles.siteLoading, { backgroundColor: theme.stage }]}>\n <PreviewPlaceholder theme={theme} compact />\n </View>\n ) : null}\n {!cover && !asleep && (!url || !loaded) ? (\n <View style={styles.siteLoading}>\n <ActivityIndicator color={theme.accent} />\n <Text style={[styles.siteLoadingText, { color: theme.muted }]}>Loading preview…</Text>\n </View>\n ) : null}\n {busy && (cover || (loaded && !asleep)) ? (\n <View style={[styles.siteBusy, { backgroundColor: theme.card }]}>\n <ActivityIndicator size=\"small\" color={theme.accent} />\n <Text style={[styles.siteBusyText, { color: theme.ink }]}>Updating…</Text>\n </View>\n ) : null}\n </View>\n </Tap>\n {build.origin === 'agent' && !build.liveUrl ? (\n <View style={[styles.siteNote, { backgroundColor: theme.warnSoft }]}>\n <MaterialCommunityIcons name=\"clock-outline\" size={15} color={theme.warn} />\n <Text style={[styles.siteNoteText, { color: theme.ink }]}>\n {build.snapshotId\n ? 'The preview lasts about an hour after the last change; a restore point is saved. Publish to keep it online.'\n : 'The preview lasts about an hour after the last change. Publish to keep it online.'}\n </Text>\n </View>\n ) : null}\n <View style={styles.siteFoot}>\n <Tap\n onPress={onOpen}\n accessibilityRole=\"button\"\n style={[styles.siteBtn, { backgroundColor: theme.chip }]}\n pressedStyle={DIM}\n testID=\"webbuilder-card-preview\"\n >\n <Text style={[styles.siteBtnText, { color: theme.ink }]}>Preview</Text>\n </Tap>\n <Tap\n onPress={onPublish}\n disabled={!build.sandboxId}\n accessibilityRole=\"button\"\n style={[styles.siteBtn, { backgroundColor: theme.ink }, !build.sandboxId && styles.disabled]}\n pressedStyle={DIM}\n testID=\"webbuilder-card-publish\"\n >\n <Text style={[styles.siteBtnText, { color: theme.card }]}>Publish</Text>\n </Tap>\n </View>\n </View>\n );\n}\n\nexport function ProjectChat({\n messages,\n streaming,\n busy,\n error,\n connected,\n building,\n build,\n siteTitle,\n onSend,\n onOpenPreview,\n onPublish,\n onPreviewAsleep,\n ask = null,\n onAnswerAsk,\n theme,\n bottomInset,\n}: {\n messages: AgentChatMessage[];\n streaming: string | null;\n busy: boolean;\n error: string | null;\n connected: boolean;\n building: WebBuilderBuilding | null;\n build: WebBuilderBuild | null;\n siteTitle: string;\n onSend: (text: string) => void;\n onOpenPreview: () => void;\n onPublish: () => void;\n /** The site card found the sandbox asleep or expired. */\n onPreviewAsleep?: () => void;\n /** The agent's question waiting for an answer (`[ASK_USER]`), shown as the question card. */\n ask?: AskUserPayload | null;\n /** Send the formatted answers as the reply (releases the agent's parked turn). */\n onAnswerAsk?: (formatted: string) => void;\n theme: WebBuilderTheme;\n bottomInset: number;\n}) {\n const [draft, setDraft] = useState('');\n // Questions the person closed without answering (the agent asks again if it needs to).\n const [dismissedAsks, setDismissedAsks] = useState<string[]>([]);\n const listRef = useRef<FlatList<Row>>(null);\n // Follow the conversation unless the person scrolled up to read; then offer a way back.\n const [atBottom, setAtBottom] = useState(true);\n const live = busy || Boolean(building);\n\n const rows = useMemo<Row[]>(() => {\n const out: Row[] = messages.map((m) => ({ kind: 'message', id: m.id, message: m }));\n if (build) out.push({ kind: 'site', id: `site-${build.key}` });\n if (live) out.push({ kind: 'live', id: 'live' });\n return out;\n }, [messages, build, live]);\n\n useEffect(() => {\n if (!atBottom) return undefined;\n const timer = setTimeout(() => listRef.current?.scrollToEnd({ animated: true }), 80);\n return () => clearTimeout(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rows.length, streaming]);\n\n const send = (text: string) => {\n const words = text.trim();\n if (!words) return;\n onSend(words);\n setDraft('');\n };\n\n const suggestions = messages.length === 0 && !live ? webbuilderAgentSuggestions(Boolean(build), siteTitle) : [];\n\n return (\n <KeyboardAvoidingView\n style={styles.fill}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n keyboardVerticalOffset={Platform.OS === 'ios' ? 96 : 0}\n >\n <FlatList\n ref={listRef}\n data={rows}\n keyExtractor={(row) => row.id}\n contentContainerStyle={styles.list}\n keyboardShouldPersistTaps=\"handled\"\n scrollEventThrottle={100}\n onScroll={(event) => {\n const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent;\n setAtBottom(layoutMeasurement.height + contentOffset.y >= contentSize.height - 48);\n }}\n ListEmptyComponent={\n <View style={styles.empty}>\n <View style={[styles.emptyMark, { backgroundColor: theme.accentSoft }]}>\n <MaterialCommunityIcons name=\"creation\" size={26} color={theme.accent} />\n </View>\n <Text style={[styles.emptyTitle, { color: theme.ink }]}>\n {build ? `What should change on ${siteTitle}?` : 'Describe your idea'}\n </Text>\n <Text style={[styles.emptyBody, { color: theme.muted }]}>\n {build\n ? 'Ask for new sections, another look, copy changes or fixes.'\n : \"Tell me what the site is for and I'll build it step by step.\"}\n </Text>\n </View>\n }\n ListFooterComponent={\n ask && onAnswerAsk && !dismissedAsks.includes(ask.requestId) ? (\n <View style={styles.askCard}>\n <AskUserCard\n key={ask.requestId}\n payload={ask}\n isDark={theme.isDark}\n onAnswer={(formatted) => {\n // Answered: the card goes, as in the main chat.\n setDismissedAsks((prev) => [...prev, ask.requestId]);\n onAnswerAsk(formatted);\n }}\n onDismiss={() => setDismissedAsks((prev) => [...prev, ask.requestId])}\n />\n </View>\n ) : null\n }\n renderItem={({ item }) => {\n if (item.kind === 'live')\n return <LiveTurn streaming={streaming} building={building} theme={theme} />;\n if (item.kind === 'site' && build) {\n return (\n <SiteCard\n build={build}\n title={siteTitle}\n busy={live}\n onOpen={onOpenPreview}\n onPublish={onPublish}\n onAsleep={onPreviewAsleep}\n theme={theme}\n />\n );\n }\n if (item.kind !== 'message') return null;\n const m = item.message;\n if (m.role === 'user') return <UserBubble text={m.displayContent ?? m.content} theme={theme} />;\n return <AgentTurn content={m.content} active={false} theme={theme} />;\n }}\n />\n\n {!atBottom ? (\n <Tap\n onPress={() => {\n setAtBottom(true);\n listRef.current?.scrollToEnd({ animated: true });\n }}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Jump to the latest\"\n style={[\n styles.jump,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"arrow-down\" size={20} color={theme.ink} />\n </Tap>\n ) : null}\n\n {suggestions.length ? (\n <View style={styles.suggestions}>\n {suggestions.slice(0, 3).map((s) => (\n <Tap\n key={s.id}\n onPress={() => send(s.prompt ?? s.label)}\n accessibilityRole=\"button\"\n style={[styles.suggestion, { backgroundColor: theme.card, borderColor: theme.border }]}\n pressedStyle={DIM}\n >\n <Text style={[styles.suggestionText, { color: theme.ink }]} numberOfLines={1}>\n {s.label}\n </Text>\n </Tap>\n ))}\n </View>\n ) : null}\n\n {error ? (\n <View style={[styles.error, { backgroundColor: theme.critSoft }]}>\n <MaterialCommunityIcons name=\"alert-circle-outline\" size={16} color={theme.crit} />\n <Text style={[styles.errorText, { color: theme.crit }]}>{error}</Text>\n </View>\n ) : null}\n\n <View\n style={[\n styles.composerDock,\n { backgroundColor: theme.screen, paddingBottom: Math.max(bottomInset, 10) },\n ]}\n >\n <View\n style={[\n styles.composer,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#1c1917',\n },\n ]}\n >\n <TextInput\n value={draft}\n onChangeText={setDraft}\n placeholder=\"Message Web Builder\"\n placeholderTextColor={theme.faint}\n multiline\n style={[styles.input, { color: theme.ink }]}\n accessibilityLabel=\"Message the agent\"\n testID=\"webbuilder-chat-input\"\n />\n <Tap\n onPress={() => send(draft)}\n disabled={!draft.trim() || !connected}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Send\"\n style={[\n styles.send,\n { backgroundColor: draft.trim() && connected ? theme.accent : theme.chip },\n ]}\n pressedStyle={DIM}\n testID=\"webbuilder-chat-send\"\n >\n <MaterialCommunityIcons\n name=\"arrow-up\"\n size={20}\n color={draft.trim() && connected ? theme.accentInk : theme.faint}\n />\n </Tap>\n </View>\n {!connected ? (\n <Text style={[styles.connecting, { color: theme.muted }]}>Connecting to Web Builder…</Text>\n ) : null}\n </View>\n </KeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n askCard: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 12 },\n fill: { flex: 1 },\n list: { paddingHorizontal: 16, paddingTop: 16, paddingBottom: 12, gap: 18, flexGrow: 1 },\n userRow: { alignItems: 'flex-end' },\n userBubble: {\n maxWidth: '86%',\n paddingHorizontal: 14,\n paddingVertical: 10,\n borderRadius: 20,\n borderBottomRightRadius: 6,\n },\n userText: { fontSize: 16, lineHeight: 22 },\n agentTurn: { gap: 8 },\n agentHead: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n agentMark: { width: 24, height: 24, borderRadius: 8, alignItems: 'center', justifyContent: 'center' },\n agentName: { fontSize: 14, fontWeight: '700' },\n working: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n alignSelf: 'flex-start',\n maxWidth: '100%',\n paddingHorizontal: 14,\n paddingVertical: 10,\n borderRadius: 14,\n borderWidth: StyleSheet.hairlineWidth,\n },\n workingText: { flexShrink: 1, fontSize: 14, fontWeight: '600' },\n workingTime: { fontSize: 13, fontVariant: ['tabular-nums'] },\n site: {\n borderRadius: 22,\n borderWidth: StyleSheet.hairlineWidth,\n overflow: 'hidden',\n shadowOpacity: 0.06,\n shadowRadius: 14,\n shadowOffset: { width: 0, height: 4 },\n elevation: 2,\n },\n siteHead: { flexDirection: 'row', alignItems: 'center', gap: 14, padding: 16 },\n siteGlobe: { width: 48, height: 48, borderRadius: 14, alignItems: 'center', justifyContent: 'center' },\n siteHeadText: { flex: 1, gap: 2 },\n siteTitle: { fontSize: 18, fontWeight: '700', letterSpacing: -0.2 },\n siteStatus: { fontSize: 14 },\n siteView: {\n height: 240,\n borderTopWidth: StyleSheet.hairlineWidth,\n borderBottomWidth: StyleSheet.hairlineWidth,\n overflow: 'hidden',\n },\n siteWeb: { flex: 1, backgroundColor: 'transparent' },\n siteCover: { ...StyleSheet.absoluteFillObject, width: '100%', height: '100%' },\n hidden: { opacity: 0 },\n siteLoading: { ...StyleSheet.absoluteFillObject, alignItems: 'center', justifyContent: 'center', gap: 8 },\n siteLoadingText: { fontSize: 13 },\n siteBusy: {\n position: 'absolute',\n top: 10,\n right: 10,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n paddingHorizontal: 10,\n paddingVertical: 6,\n borderRadius: 999,\n },\n siteBusyText: { fontSize: 12, fontWeight: '600' },\n siteNote: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n marginHorizontal: 14,\n marginTop: 12,\n paddingHorizontal: 12,\n paddingVertical: 9,\n borderRadius: 12,\n },\n siteNoteText: { flex: 1, fontSize: 13, lineHeight: 18 },\n siteFoot: { flexDirection: 'row', gap: 10, padding: 14 },\n siteBtn: { flex: 1, height: 46, borderRadius: 23, alignItems: 'center', justifyContent: 'center' },\n siteBtnText: { fontSize: 16, fontWeight: '700' },\n disabled: { opacity: 0.35 },\n empty: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 32, gap: 8 },\n emptyMark: {\n width: 56,\n height: 56,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 6,\n },\n emptyTitle: { fontSize: 18, fontWeight: '700', textAlign: 'center' },\n emptyBody: { fontSize: 14, lineHeight: 20, textAlign: 'center' },\n suggestions: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, paddingHorizontal: 16, paddingBottom: 8 },\n suggestion: { paddingHorizontal: 14, paddingVertical: 8, borderRadius: 999, borderWidth: StyleSheet.hairlineWidth },\n suggestionText: { fontSize: 14, fontWeight: '500' },\n error: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n marginHorizontal: 16,\n marginBottom: 8,\n paddingHorizontal: 12,\n paddingVertical: 10,\n borderRadius: 12,\n },\n errorText: { flex: 1, fontSize: 13, lineHeight: 18 },\n composerDock: { paddingHorizontal: 14, paddingTop: 8 },\n composer: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 8,\n minHeight: 58,\n borderRadius: 29,\n borderWidth: StyleSheet.hairlineWidth,\n paddingLeft: 18,\n paddingRight: 8,\n paddingVertical: 8,\n shadowOpacity: 0.1,\n shadowRadius: 18,\n shadowOffset: { width: 0, height: 6 },\n elevation: 6,\n },\n jump: {\n position: 'absolute',\n right: 16,\n bottom: 104,\n width: 44,\n height: 44,\n borderRadius: 22,\n borderWidth: StyleSheet.hairlineWidth,\n alignItems: 'center',\n justifyContent: 'center',\n shadowOpacity: 0.12,\n shadowRadius: 10,\n shadowOffset: { width: 0, height: 4 },\n elevation: 4,\n },\n input: { flex: 1, fontSize: 17, lineHeight: 22, maxHeight: 120, paddingTop: 10, paddingBottom: 10 },\n send: { width: 42, height: 42, borderRadius: 21, alignItems: 'center', justifyContent: 'center' },\n connecting: { fontSize: 12, textAlign: 'center', marginTop: 6 },\n});\n"],"names":[],"mappings":"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"}
@@ -298,7 +298,7 @@ function useCdecliChannel(isConnected, accountId, channelId, callbacks, model, s
298
298
  quickReplyShownRef.current = false;
299
299
  preResponseRef.current = null;
300
300
  const turn = ++turnSeqRef.current;
301
- if (media.length === 0 && !isConnectorReply(text)) {
301
+ if (media.length === 0 && !isConnectorReply(text) && !turnOptions.answersAsk) {
302
302
  void quickReplyViaBrain(text).then((answer) => {
303
303
  var _a2, _b;
304
304
  if (!answer) return;