@midhunxavier/code-flow 0.0.0-stage → 0.1.0-preview.1

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 (284) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -2
  3. package/bin/codeflow.mjs +8 -0
  4. package/bin/launcher.mjs +127 -0
  5. package/dist/remote-host.json +1 -0
  6. package/licenses/inter.txt +92 -0
  7. package/licenses/preact.txt +21 -0
  8. package/licenses/signals-core.txt +21 -0
  9. package/licenses/signals.txt +21 -0
  10. package/licenses/typescript-notices.txt +193 -0
  11. package/licenses/typescript.txt +55 -0
  12. package/licenses/uqr.txt +22 -0
  13. package/licenses/xterm-fit.txt +19 -0
  14. package/licenses/xterm.txt +21 -0
  15. package/package.json +34 -4
  16. package/public/assets/browser-7XI52A6V.js +8 -0
  17. package/public/assets/changes-EYFPASEI.js +1 -0
  18. package/public/assets/chunk-7H3ZLTKA.js +2 -0
  19. package/public/assets/chunk-L7TUCIYF.js +1 -0
  20. package/public/assets/chunk-LLMQG23J.js +163 -0
  21. package/public/assets/main-KIRM2OEK.js +1 -0
  22. package/public/assets/settings-QJZVW22Y.js +9 -0
  23. package/public/assets/styles-615EBB20.css +32 -0
  24. package/public/assets/terminal-A2FI2NAX.js +62 -0
  25. package/public/assets.json +1 -0
  26. package/public/bundle-meta.json +1 -0
  27. package/public/docs/.nojekyll +0 -0
  28. package/public/docs/accessibility.html +19 -0
  29. package/public/docs/acp-agents.html +117 -0
  30. package/public/docs/agent-containers.html +79 -0
  31. package/public/docs/api.html +1130 -0
  32. package/public/docs/app.js +342 -0
  33. package/public/docs/application-improvements.html +275 -0
  34. package/public/docs/architecture-explorer.html +19 -0
  35. package/public/docs/architecture.html +149 -0
  36. package/public/docs/auto-team.html +142 -0
  37. package/public/docs/automations.html +109 -0
  38. package/public/docs/checkpoint-review.html +37 -0
  39. package/public/docs/code-hosts.html +35 -0
  40. package/public/docs/code-intelligence.html +35 -0
  41. package/public/docs/configuration.html +346 -0
  42. package/public/docs/context-inspection.html +23 -0
  43. package/public/docs/coordinated-changes.html +28 -0
  44. package/public/docs/deferred-runs.html +25 -0
  45. package/public/docs/dependency-discovery.html +19 -0
  46. package/public/docs/documentation.html +84 -0
  47. package/public/docs/dynamic-teams-evaluation.html +174 -0
  48. package/public/docs/dynamic-teams-implementation-plan.html +882 -0
  49. package/public/docs/dynamic-teams-implementation-review-1.html +141 -0
  50. package/public/docs/dynamic-teams-plan-review-0.html +204 -0
  51. package/public/docs/extensions.html +42 -0
  52. package/public/docs/external-sources.html +96 -0
  53. package/public/docs/filesystem-policy.html +26 -0
  54. package/public/docs/filtered-tasks.html +44 -0
  55. package/public/docs/font-license.txt +92 -0
  56. package/public/docs/getting-started.html +118 -0
  57. package/public/docs/github-review-threads.html +26 -0
  58. package/public/docs/github.html +157 -0
  59. package/public/docs/help.html +69 -0
  60. package/public/docs/index.html +77 -0
  61. package/public/docs/installation.html +74 -0
  62. package/public/docs/launch-profiles.html +48 -0
  63. package/public/docs/maintenance.html +60 -0
  64. package/public/docs/memory-claims.html +31 -0
  65. package/public/docs/memory-storage.html +58 -0
  66. package/public/docs/notifications.html +39 -0
  67. package/public/docs/patterns.html +195 -0
  68. package/public/docs/performance-results.html +210 -0
  69. package/public/docs/performance.html +166 -0
  70. package/public/docs/project-conventions.html +22 -0
  71. package/public/docs/project-first-navigation-plan.html +587 -0
  72. package/public/docs/project-teams-implementation-plan.html +772 -0
  73. package/public/docs/project-teams.html +99 -0
  74. package/public/docs/provider-compatibility.html +20 -0
  75. package/public/docs/releasing.html +61 -0
  76. package/public/docs/remote-workers.html +64 -0
  77. package/public/docs/review-inbox.html +26 -0
  78. package/public/docs/run-storage.html +23 -0
  79. package/public/docs/runs.html +141 -0
  80. package/public/docs/search.json +1 -0
  81. package/public/docs/security.html +133 -0
  82. package/public/docs/shared-projects.html +31 -0
  83. package/public/docs/ssh-projects.html +60 -0
  84. package/public/docs/style.css +768 -0
  85. package/public/docs/task-reruns.html +30 -0
  86. package/public/docs/team-collaboration.html +379 -0
  87. package/public/docs/verification.html +22 -0
  88. package/public/docs/vscode.html +53 -0
  89. package/public/docs/worker-permission-verification.html +122 -0
  90. package/public/index.html +17 -0
  91. package/scripts/check-node.mjs +7 -0
  92. package/scripts/codeflow.mjs +55 -0
  93. package/scripts/pty.py +273 -0
  94. package/src/acp-connections.js +110 -0
  95. package/src/adapters/acp-presets.js +37 -0
  96. package/src/adapters/acp-types.js +0 -0
  97. package/src/adapters/acp.js +328 -0
  98. package/src/adapters/agy-auth.js +67 -0
  99. package/src/adapters/agy-isolation.js +223 -0
  100. package/src/adapters/agy.js +297 -0
  101. package/src/adapters/claude.js +220 -0
  102. package/src/adapters/codex-app-server.js +518 -0
  103. package/src/adapters/codex.js +299 -0
  104. package/src/adapters/errors.js +57 -0
  105. package/src/adapters/index.js +91 -0
  106. package/src/adapters/managed-permissions.js +37 -0
  107. package/src/adapters/model-discovery.js +100 -0
  108. package/src/adapters/process.js +418 -0
  109. package/src/adapters/team-tools.js +102 -0
  110. package/src/adapters/types.js +0 -0
  111. package/src/agent-container.js +155 -0
  112. package/src/approvals.js +121 -0
  113. package/src/architecture.js +456 -0
  114. package/src/assets.js +44 -0
  115. package/src/automation.js +901 -0
  116. package/src/certificate-renewal.js +75 -0
  117. package/src/chat-handoff.js +55 -0
  118. package/src/checkpoint-review.js +72 -0
  119. package/src/checks.js +303 -0
  120. package/src/code-host-git.js +102 -0
  121. package/src/code-hosts-api.js +99 -0
  122. package/src/code-hosts.js +482 -0
  123. package/src/code-intelligence-worker.mjs +452 -0
  124. package/src/code-intelligence.js +141 -0
  125. package/src/collab/api.js +365 -0
  126. package/src/collab/checkpoints.js +198 -0
  127. package/src/collab/connections.js +139 -0
  128. package/src/collab/host-execution.js +347 -0
  129. package/src/collab/hub-client.js +210 -0
  130. package/src/collab/link-api.js +229 -0
  131. package/src/collab/link.js +595 -0
  132. package/src/collab/model.js +496 -0
  133. package/src/collab/runner.js +1014 -0
  134. package/src/collab/store.js +1452 -0
  135. package/src/collab/terminals.js +361 -0
  136. package/src/collaboration-reviews.js +116 -0
  137. package/src/config.js +48 -0
  138. package/src/context-budget.js +14 -0
  139. package/src/context-inspection.js +204 -0
  140. package/src/context.js +154 -0
  141. package/src/conventions.js +283 -0
  142. package/src/coordinated-api.js +247 -0
  143. package/src/deferred-launch.js +82 -0
  144. package/src/deferred-runs.js +515 -0
  145. package/src/dependency-health.js +35 -0
  146. package/src/diff.js +43 -0
  147. package/src/docs-help.js +316 -0
  148. package/src/doctor.js +232 -0
  149. package/src/engine.js +4366 -0
  150. package/src/env.js +44 -0
  151. package/src/experience.js +50 -0
  152. package/src/extensions.js +144 -0
  153. package/src/filesystem-access.js +107 -0
  154. package/src/filesystem-policy.js +238 -0
  155. package/src/filtered-task-limits.js +93 -0
  156. package/src/filtered-tasks-api.js +53 -0
  157. package/src/filtered-tasks.js +576 -0
  158. package/src/fs.js +57 -0
  159. package/src/git.js +626 -0
  160. package/src/github-review-threads.js +181 -0
  161. package/src/github.js +538 -0
  162. package/src/http.js +69 -0
  163. package/src/improve-settings.js +38 -0
  164. package/src/improve.js +187 -0
  165. package/src/integrations.js +373 -0
  166. package/src/integrity.js +259 -0
  167. package/src/journey-api.js +77 -0
  168. package/src/journey-replay.js +65 -0
  169. package/src/journey-store.js +97 -0
  170. package/src/journeys.js +60 -0
  171. package/src/json.js +81 -0
  172. package/src/launch-profiles.js +292 -0
  173. package/src/learnings.js +80 -0
  174. package/src/log.js +39 -0
  175. package/src/maintenance.js +335 -0
  176. package/src/memory-analysis.js +182 -0
  177. package/src/memory-claims.js +153 -0
  178. package/src/memory-sqlite.js +236 -0
  179. package/src/memory.js +552 -0
  180. package/src/merge-validation.js +58 -0
  181. package/src/model-catalog.js +238 -0
  182. package/src/model-research.js +91 -0
  183. package/src/notes.js +176 -0
  184. package/src/notifications.js +413 -0
  185. package/src/patterns/auto-team-model.js +212 -0
  186. package/src/patterns/auto-team.js +659 -0
  187. package/src/patterns/council.js +199 -0
  188. package/src/patterns/debate.js +188 -0
  189. package/src/patterns/findings.js +141 -0
  190. package/src/patterns/index.js +19 -0
  191. package/src/patterns/loop.js +158 -0
  192. package/src/patterns/pipeline.js +125 -0
  193. package/src/patterns/prompts.js +181 -0
  194. package/src/patterns/race.js +147 -0
  195. package/src/patterns/schemas.js +40 -0
  196. package/src/patterns/solo.js +49 -0
  197. package/src/patterns/supervisor.js +235 -0
  198. package/src/patterns/task-draft.js +29 -0
  199. package/src/patterns/tdd.js +231 -0
  200. package/src/patterns/team-strategies.js +67 -0
  201. package/src/performance.js +43 -0
  202. package/src/persistence-status.js +35 -0
  203. package/src/phone-sessions.js +96 -0
  204. package/src/preview-overlay.js +383 -0
  205. package/src/preview.js +219 -0
  206. package/src/privacy.js +23 -0
  207. package/src/project-report.js +22 -0
  208. package/src/project-team-model.js +178 -0
  209. package/src/project-team-policy.js +42 -0
  210. package/src/project-team-store.js +213 -0
  211. package/src/project-teams-api.js +36 -0
  212. package/src/project-teams.js +551 -0
  213. package/src/projects.js +286 -0
  214. package/src/provider-eligibility.js +9 -0
  215. package/src/readiness.js +98 -0
  216. package/src/remote-tls.js +66 -0
  217. package/src/remote-workers/bundles.js +198 -0
  218. package/src/remote-workers/client.js +332 -0
  219. package/src/remote-workers/durability.js +37 -0
  220. package/src/remote-workers/protocol.js +68 -0
  221. package/src/remote-workers/stdio.js +138 -0
  222. package/src/remote-workers/worker.js +304 -0
  223. package/src/remote.js +204 -0
  224. package/src/repo-config.js +201 -0
  225. package/src/repo-coordination.js +732 -0
  226. package/src/repo-tree.js +106 -0
  227. package/src/retention-policy.js +466 -0
  228. package/src/review-inbox.js +38 -0
  229. package/src/routing.js +49 -0
  230. package/src/run-analysis.js +111 -0
  231. package/src/run-cold-store.js +231 -0
  232. package/src/run-environment.js +15 -0
  233. package/src/run-history.js +91 -0
  234. package/src/run-log.js +160 -0
  235. package/src/run-permissions.js +110 -0
  236. package/src/run-projection.js +75 -0
  237. package/src/run-recovery.js +53 -0
  238. package/src/run-status.js +54 -0
  239. package/src/serve.js +138 -0
  240. package/src/server.js +2738 -0
  241. package/src/shared-access.js +103 -0
  242. package/src/shared-accounts.js +301 -0
  243. package/src/shared-api.js +239 -0
  244. package/src/shell.js +346 -0
  245. package/src/ship.js +344 -0
  246. package/src/slots.js +74 -0
  247. package/src/snapshot.js +388 -0
  248. package/src/source-context.js +17 -0
  249. package/src/sse-writer.js +70 -0
  250. package/src/ssh-projects/bootstrap.mjs +95 -0
  251. package/src/ssh-projects/config.js +45 -0
  252. package/src/ssh-projects/gateway.js +143 -0
  253. package/src/ssh-projects/manager.js +320 -0
  254. package/src/ssh-projects/team-autostart.mjs +93 -0
  255. package/src/ssh-projects/team-remove.mjs +69 -0
  256. package/src/ssh-projects/team-status.mjs +39 -0
  257. package/src/ssh-projects/transport.js +116 -0
  258. package/src/stats.js +139 -0
  259. package/src/store.js +544 -0
  260. package/src/stream.js +91 -0
  261. package/src/sweeps.js +241 -0
  262. package/src/tailscale.js +101 -0
  263. package/src/task-draft.js +23 -0
  264. package/src/team-evaluation.js +242 -0
  265. package/src/team-mailbox.js +160 -0
  266. package/src/team-memory.js +84 -0
  267. package/src/team-rerun-graph.js +15 -0
  268. package/src/team-reruns.js +130 -0
  269. package/src/team-scheduler.js +121 -0
  270. package/src/team-template-store.js +98 -0
  271. package/src/team-templates.js +117 -0
  272. package/src/team-tool-client.mjs +79 -0
  273. package/src/team-tools.js +176 -0
  274. package/src/teams.js +0 -0
  275. package/src/templates.js +62 -0
  276. package/src/transcript.js +134 -0
  277. package/src/verification-integrity.js +27 -0
  278. package/src/verification.js +183 -0
  279. package/src/watch.js +195 -0
  280. package/src/work-queue.js +47 -0
  281. package/src/workflow-control.js +83 -0
  282. package/src/workspace-api.js +207 -0
  283. package/src/workspace-changes.js +61 -0
  284. package/src/workspace.js +146 -0
@@ -0,0 +1,342 @@
1
+ /* No framework, remote fonts, analytics or network services: the same files work on Pages. */
2
+ const $ = (selector) => document.querySelector(selector);
3
+ const getPreference = (key, fallback = null) => {
4
+ try {
5
+ return localStorage.getItem(key) ?? fallback;
6
+ } catch {
7
+ return fallback;
8
+ }
9
+ };
10
+ const setPreference = (key, value) => {
11
+ try {
12
+ localStorage.setItem(key, value);
13
+ } catch {}
14
+ };
15
+ const system = matchMedia("(prefers-color-scheme: dark)");
16
+ function applyTheme() {
17
+ const theme = getPreference("theme") || (system.matches ? "dark" : "light");
18
+ document.documentElement.dataset.theme = theme;
19
+ for (const source of document.querySelectorAll("source[data-dark]"))
20
+ source.media = theme === "dark" ? "all" : "not all";
21
+ }
22
+ applyTheme();
23
+ system.addEventListener("change", applyTheme);
24
+ window.addEventListener("storage", applyTheme);
25
+ $("#theme").onclick = () => {
26
+ setPreference(
27
+ "theme",
28
+ document.documentElement.dataset.theme === "dark" ? "light" : "dark",
29
+ );
30
+ applyTheme();
31
+ };
32
+ $("#menu").onclick = () => {
33
+ const open = $("#sidebar").classList.toggle("open");
34
+ $("#menu").setAttribute("aria-expanded", String(open));
35
+ };
36
+ document.addEventListener("keydown", (event) => {
37
+ if (event.key === "Escape") {
38
+ $("#sidebar").classList.remove("open");
39
+ $("#menu").setAttribute("aria-expanded", "false");
40
+ }
41
+ });
42
+ const activeLink = $(".sidebar [aria-current]");
43
+ if (activeLink)
44
+ $("#sidebar").scrollTop = Math.max(0, activeLink.offsetTop - 220);
45
+ for (const button of document.querySelectorAll("[data-close]"))
46
+ button.onclick = () => document.getElementById(button.dataset.close).close();
47
+ // Keep every method readable without JavaScript, then progressively enhance to tabs.
48
+ for (const picker of document.querySelectorAll("[data-install-picker]")) {
49
+ const tabs = [...picker.querySelectorAll('[role="tab"]')];
50
+ const activate = (tab, focus = false) => {
51
+ for (const candidate of tabs) {
52
+ const selected = candidate === tab;
53
+ candidate.setAttribute("aria-selected", String(selected));
54
+ candidate.tabIndex = selected ? 0 : -1;
55
+ document.getElementById(candidate.getAttribute("aria-controls")).hidden = !selected;
56
+ }
57
+ if (focus) tab.focus();
58
+ };
59
+ for (const [index, tab] of tabs.entries()) {
60
+ tab.onclick = () => activate(tab);
61
+ tab.onkeydown = (event) => {
62
+ let next;
63
+ if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
64
+ if (event.key === "ArrowLeft") next = tabs[(index + tabs.length - 1) % tabs.length];
65
+ if (event.key === "Home") next = tabs[0];
66
+ if (event.key === "End") next = tabs.at(-1);
67
+ if (next) { event.preventDefault(); activate(next, true); }
68
+ };
69
+ }
70
+ activate(tabs[0]);
71
+ }
72
+ for (const pre of document.querySelectorAll("pre")) {
73
+ const button = document.createElement("button");
74
+ button.className = "copy-code";
75
+ button.textContent = "Copy";
76
+ button.setAttribute("aria-label", "Copy code");
77
+ const code = pre.querySelector("code")?.textContent || pre.textContent;
78
+ button.onclick = async () => {
79
+ try {
80
+ await navigator.clipboard.writeText(code);
81
+ button.textContent = "Copied";
82
+ } catch {
83
+ button.textContent = "Select to copy";
84
+ }
85
+ setTimeout(() => (button.textContent = "Copy"), 1800);
86
+ };
87
+ pre.append(button);
88
+ }
89
+ let index;
90
+ async function search() {
91
+ const results = $("#search-results");
92
+ try {
93
+ index ??= await fetch("search.json").then((r) => {
94
+ if (!r.ok) throw Error();
95
+ return r.json();
96
+ });
97
+ const query = $("#search").value.trim().toLowerCase();
98
+ results.replaceChildren();
99
+ if (!query) {
100
+ results.textContent =
101
+ "Try “first run”, “SSH”, “verification” or “models”.";
102
+ return;
103
+ }
104
+ const words = query.split(/\s+/);
105
+ const matches = index
106
+ .map((doc) => ({
107
+ doc,
108
+ score: words.reduce(
109
+ (n, w) =>
110
+ n +
111
+ (doc.title.toLowerCase().includes(w) ? 15 : 0) +
112
+ (doc.body.toLowerCase().includes(w) ? 1 : 0),
113
+ 0,
114
+ ),
115
+ }))
116
+ .filter(({ doc }) =>
117
+ words.every((w) =>
118
+ (doc.title + " " + doc.body).toLowerCase().includes(w),
119
+ ),
120
+ )
121
+ .sort((a, b) => b.score - a.score)
122
+ .slice(0, 12);
123
+ if (!matches.length)
124
+ results.textContent =
125
+ "No matching guides. Try fewer words or use the guide navigation.";
126
+ for (const { doc } of matches) {
127
+ const a = document.createElement("a");
128
+ a.href = doc.id + ".html";
129
+ a.textContent = doc.title;
130
+ const small = document.createElement("small");
131
+ small.textContent = doc.group;
132
+ a.append(small);
133
+ results.append(a);
134
+ }
135
+ } catch {
136
+ results.textContent =
137
+ "Search could not load. Use the guide navigation or try again.";
138
+ index = undefined;
139
+ }
140
+ }
141
+ $("#open-search").onclick = () => {
142
+ $("#search-dialog").showModal();
143
+ $("#search").focus();
144
+ void search();
145
+ };
146
+ $("#search").oninput = () => void search();
147
+ document.addEventListener("keydown", (event) => {
148
+ if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
149
+ event.preventDefault();
150
+ if (!$("#search-dialog").open) $("#open-search").click();
151
+ }
152
+ });
153
+ // Only the application server enables the companion. The static build omits its controls.
154
+ const local = document.documentElement.dataset.localDocs === "true";
155
+ $("#back-app").hidden = !local;
156
+ if (local && $("#help-panel")) initializeCompanion();
157
+ function initializeCompanion() {
158
+ const panel = $("#help-panel");
159
+ const mobile = matchMedia("(max-width: 760px)");
160
+ const key = "codeflow-docs-chat-v1";
161
+ let saved = {};
162
+ try {
163
+ const raw = sessionStorage.getItem(key);
164
+ if (raw && raw.length < 300000) saved = JSON.parse(raw) || {};
165
+ } catch {}
166
+ let history = Array.isArray(saved.history) ? saved.history.filter(h =>
167
+ typeof h?.question === "string" && h.question.length <= 4000 &&
168
+ typeof h.answer === "string" && h.answer.length <= 12000).slice(-3) : [];
169
+ let messages = Array.isArray(saved.messages) ? saved.messages.filter(m =>
170
+ ["question", "answer"].includes(m?.kind) && typeof m.text === "string" &&
171
+ m.text.length <= 12000).slice(-12) : [];
172
+ let stop, initialized = false, initializing = false, generation = 0;
173
+ let opened = typeof saved.open === "boolean" ? saved.open : !mobile.matches;
174
+ $("#question").value = typeof saved.draft === "string" ? saved.draft.slice(0, 4000) : "";
175
+ function persist() {
176
+ try {
177
+ sessionStorage.setItem(key, JSON.stringify({ messages, history, draft: $("#question").value, open: opened }));
178
+ } catch {}
179
+ }
180
+ function layout() {
181
+ panel.hidden = !opened;
182
+ document.body.classList.toggle("help-open", opened);
183
+ $("#open-help").setAttribute("aria-expanded", String(opened));
184
+ for (const el of [$("#content"), $("#sidebar"), $(".on-page")])
185
+ el.inert = opened && mobile.matches;
186
+ }
187
+ function openHelp(focus = true) {
188
+ opened = true;
189
+ layout();
190
+ persist();
191
+ if (focus) $("#close-help").focus();
192
+ void connect();
193
+ }
194
+ function closeHelp() {
195
+ opened = false;
196
+ layout();
197
+ persist();
198
+ $("#open-help").focus();
199
+ }
200
+ function renderMessage(message) {
201
+ const node = document.createElement("div");
202
+ node.className = "message " + message.kind;
203
+ const label = document.createElement("strong");
204
+ label.className = "message-author";
205
+ label.textContent = message.kind === "question" ? "You" : "Code Flow";
206
+ const body = document.createElement("div");
207
+ body.textContent = message.text;
208
+ node.append(label, body);
209
+ if (Array.isArray(message.sources)) {
210
+ const list = document.createElement("div");
211
+ list.className = "sources";
212
+ for (const source of message.sources.slice(0, 5)) {
213
+ if (!/^[a-z\d-]{1,80}$/.test(source?.id) || typeof source.title !== "string") continue;
214
+ const link = document.createElement("a");
215
+ link.href = source.id + ".html";
216
+ link.textContent = source.title;
217
+ list.append(link);
218
+ }
219
+ node.append(list);
220
+ }
221
+ $("#help-messages").append(node);
222
+ }
223
+ function renderMessages() {
224
+ for (const node of document.querySelectorAll("#help-messages .message")) node.remove();
225
+ $("#chat-welcome").hidden = messages.length > 0;
226
+ messages.forEach(renderMessage);
227
+ $("#help-messages").scrollTop = $("#help-messages").scrollHeight;
228
+ }
229
+ function appendMessage(text, kind, sources = []) {
230
+ messages = [...messages, { text, kind, sources }].slice(-12);
231
+ renderMessages();
232
+ persist();
233
+ }
234
+ async function connect() {
235
+ if (initialized || initializing) return;
236
+ initializing = true;
237
+ $("#retry-help").hidden = true;
238
+ $("#help-status").textContent = "Checking your installed CLIs…";
239
+ try {
240
+ const response = await fetch("/api/docs-help");
241
+ const data = await response.json();
242
+ if (!response.ok) throw Error(data.error || "Open the owner app and sign in to use the companion.");
243
+ if (!data.agents.length) throw Error("No supported CLI found. Install and sign in to Claude Code, Codex or Antigravity, then retry.");
244
+ $("#help-agent").replaceChildren();
245
+ for (const agent of data.agents) {
246
+ const option = document.createElement("option");
247
+ option.value = agent.id;
248
+ option.textContent = agent.displayName;
249
+ $("#help-agent").append(option);
250
+ }
251
+ const agent = getPreference("docs-help-agent");
252
+ if (data.agents.some(a => a.id === agent)) $("#help-agent").value = agent;
253
+ $("#help-form").hidden = false;
254
+ $("#help-status").textContent = "Answers use your guides. Check the linked sources for details.";
255
+ initialized = true;
256
+ } catch (error) {
257
+ $("#help-status").textContent = error.message;
258
+ $("#retry-help").hidden = false;
259
+ } finally { initializing = false; }
260
+ }
261
+ $("#open-help").hidden = false;
262
+ $("#open-help").onclick = () => opened ? closeHelp() : openHelp();
263
+ $("#close-help").onclick = closeHelp;
264
+ $("#retry-help").onclick = () => void connect();
265
+ mobile.addEventListener("change", layout);
266
+ document.addEventListener("keydown", event => {
267
+ if (event.key === "Escape" && opened && !$("#search-dialog").open) closeHelp();
268
+ });
269
+ $("#question").oninput = persist;
270
+ $("#question").onkeydown = event => {
271
+ if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
272
+ event.preventDefault();
273
+ if (!stop) $("#help-form").requestSubmit();
274
+ }
275
+ };
276
+ $("#help-agent").onchange = () => setPreference("docs-help-agent", $("#help-agent").value);
277
+ for (const button of document.querySelectorAll("[data-question]"))
278
+ button.onclick = () => { $("#question").value = button.dataset.question; persist(); $("#question").focus(); };
279
+ $("#stop-help").onclick = () => stop?.abort();
280
+ function resetBusy() {
281
+ stop = undefined;
282
+ panel.removeAttribute("aria-busy");
283
+ $("#send-help").disabled = false;
284
+ $("#stop-help").hidden = true;
285
+ $("#help-agent").disabled = false;
286
+ }
287
+ $("#new-chat").onclick = () => {
288
+ generation++;
289
+ stop?.abort();
290
+ resetBusy();
291
+ messages = []; history = [];
292
+ $("#question").value = "";
293
+ renderMessages(); persist();
294
+ $("#help-status").textContent = initialized ? "A fresh conversation. What would you like to know?" : "Connect your CLI to start chatting.";
295
+ if (initialized) $("#question").focus();
296
+ };
297
+ window.addEventListener("pagehide", () => { persist(); stop?.abort(); });
298
+ $("#help-form").onsubmit = async event => {
299
+ event.preventDefault();
300
+ if (stop || !initialized) return;
301
+ const question = $("#question").value.trim();
302
+ if (!question) return;
303
+ const agent = $("#help-agent").value;
304
+ setPreference("docs-help-agent", agent);
305
+ let settings = {};
306
+ try { settings = JSON.parse(getPreference("agentSettings", "{}"))[agent] || {}; } catch {}
307
+ const controller = new AbortController();
308
+ const turn = ++generation;
309
+ stop = controller;
310
+ panel.setAttribute("aria-busy", "true");
311
+ $("#send-help").disabled = true;
312
+ $("#stop-help").hidden = false;
313
+ $("#help-agent").disabled = true;
314
+ $("#question").value = "";
315
+ appendMessage(question, "question");
316
+ $("#help-status").textContent = "Reading the guides with your CLI…";
317
+ try {
318
+ const response = await fetch("/api/docs-help", {
319
+ method: "POST", headers: { "content-type": "application/json" },
320
+ body: JSON.stringify({ question, agent, page: document.body.dataset.page, history,
321
+ settings: { model: settings.model, effort: settings.effort } }),
322
+ signal: controller.signal,
323
+ });
324
+ const data = await response.json();
325
+ if (turn !== generation) return;
326
+ if (!response.ok) throw Error(data.error || "The CLI could not answer. Try again.");
327
+ history = [...history, { question, answer: data.answer }].slice(-3);
328
+ appendMessage(data.answer, "answer", data.sources);
329
+ $("#help-status").textContent = "Continue with a follow-up or explore a source guide.";
330
+ } catch (error) {
331
+ if (turn !== generation) return;
332
+ $("#help-status").textContent = controller.signal.aborted ? "Stopped. You can ask again." : error.message;
333
+ $("#question").value ||= question;
334
+ persist();
335
+ } finally {
336
+ if (turn === generation) resetBusy();
337
+ }
338
+ };
339
+ renderMessages();
340
+ layout();
341
+ if (opened) openHelp(false);
342
+ }