@midhunxavier/code-flow 0.0.0-stage → 0.1.0-preview.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +141 -2
- package/bin/codeflow.mjs +8 -0
- package/bin/launcher.mjs +127 -0
- package/dist/remote-host.json +1 -0
- package/licenses/inter.txt +92 -0
- package/licenses/preact.txt +21 -0
- package/licenses/signals-core.txt +21 -0
- package/licenses/signals.txt +21 -0
- package/licenses/typescript-notices.txt +193 -0
- package/licenses/typescript.txt +55 -0
- package/licenses/uqr.txt +22 -0
- package/licenses/xterm-fit.txt +19 -0
- package/licenses/xterm.txt +21 -0
- package/package.json +34 -4
- package/public/assets/changes-62ZIEQSN.js +1 -0
- package/public/assets/chunk-2PZVOKID.js +1 -0
- package/public/assets/chunk-4D5IENEB.js +1 -0
- package/public/assets/chunk-5SARP5MU.js +1 -0
- package/public/assets/chunk-63YLZ3PR.js +1 -0
- package/public/assets/chunk-7FUHKF2M.js +1 -0
- package/public/assets/chunk-APQEVJ2K.js +1 -0
- package/public/assets/chunk-CGOZQMEZ.js +2 -0
- package/public/assets/chunk-J4VYS3KV.js +2 -0
- package/public/assets/chunk-L7TUCIYF.js +1 -0
- package/public/assets/chunk-SIHDWM2Y.js +154 -0
- package/public/assets/chunk-TEJVYIKC.js +1 -0
- package/public/assets/code-browser-VB2HGZSG.js +4 -0
- package/public/assets/filtered-tasks-ES5CP4KV.js +1 -0
- package/public/assets/interactive-browser-7F5ZXRUV.js +7 -0
- package/public/assets/join-project-6RTFHNCA.js +1 -0
- package/public/assets/main-65EW73SB.js +1 -0
- package/public/assets/project-invitations-view-GMPWGWYM.js +1 -0
- package/public/assets/settings-UB5Q4AQM.js +9 -0
- package/public/assets/styles-18792BB4.css +32 -0
- package/public/assets/team-server-wizard-2GLDWS6D.js +8 -0
- package/public/assets/terminal-IWAIM4DE.js +62 -0
- package/public/assets.json +1 -0
- package/public/bundle-meta.json +1 -0
- package/public/docs/.nojekyll +0 -0
- package/public/docs/accessibility.html +19 -0
- package/public/docs/acp-agents.html +117 -0
- package/public/docs/agent-containers.html +79 -0
- package/public/docs/api.html +1130 -0
- package/public/docs/app.js +342 -0
- package/public/docs/application-improvements.html +275 -0
- package/public/docs/architecture-explorer.html +19 -0
- package/public/docs/architecture.html +149 -0
- package/public/docs/auto-team.html +148 -0
- package/public/docs/automations.html +109 -0
- package/public/docs/checkpoint-review.html +37 -0
- package/public/docs/code-hosts.html +35 -0
- package/public/docs/code-intelligence.html +35 -0
- package/public/docs/configuration.html +346 -0
- package/public/docs/context-inspection.html +23 -0
- package/public/docs/coordinated-changes.html +28 -0
- package/public/docs/deferred-runs.html +25 -0
- package/public/docs/dependency-discovery.html +19 -0
- package/public/docs/documentation.html +84 -0
- package/public/docs/dynamic-teams-evaluation.html +174 -0
- package/public/docs/dynamic-teams-implementation-plan.html +882 -0
- package/public/docs/dynamic-teams-implementation-review-1.html +141 -0
- package/public/docs/dynamic-teams-plan-review-0.html +204 -0
- package/public/docs/extensions.html +42 -0
- package/public/docs/external-sources.html +96 -0
- package/public/docs/filesystem-policy.html +26 -0
- package/public/docs/filtered-tasks.html +44 -0
- package/public/docs/font-license.txt +92 -0
- package/public/docs/getting-started.html +143 -0
- package/public/docs/github-review-threads.html +26 -0
- package/public/docs/github.html +157 -0
- package/public/docs/help.html +69 -0
- package/public/docs/index.html +88 -0
- package/public/docs/installation.html +80 -0
- package/public/docs/launch-profiles.html +48 -0
- package/public/docs/maintenance.html +60 -0
- package/public/docs/memory-claims.html +31 -0
- package/public/docs/memory-storage.html +58 -0
- package/public/docs/notifications.html +39 -0
- package/public/docs/patterns.html +195 -0
- package/public/docs/performance-results.html +210 -0
- package/public/docs/performance.html +166 -0
- package/public/docs/project-conventions.html +22 -0
- package/public/docs/project-first-navigation-plan.html +587 -0
- package/public/docs/project-teams-implementation-plan.html +772 -0
- package/public/docs/project-teams.html +129 -0
- package/public/docs/provider-compatibility.html +20 -0
- package/public/docs/releasing.html +65 -0
- package/public/docs/remote-workers.html +64 -0
- package/public/docs/review-inbox.html +26 -0
- package/public/docs/run-storage.html +23 -0
- package/public/docs/runs.html +141 -0
- package/public/docs/search.json +1 -0
- package/public/docs/security.html +133 -0
- package/public/docs/shared-projects.html +31 -0
- package/public/docs/ssh-projects.html +60 -0
- package/public/docs/style.css +768 -0
- package/public/docs/task-reruns.html +30 -0
- package/public/docs/team-collaboration.html +412 -0
- package/public/docs/verification.html +22 -0
- package/public/docs/vscode.html +53 -0
- package/public/docs/worker-permission-verification.html +131 -0
- package/public/index.html +17 -0
- package/scripts/check-node.mjs +7 -0
- package/scripts/codeflow.mjs +55 -0
- package/scripts/computer-use.swift +64 -0
- package/scripts/pty.py +273 -0
- package/src/acp-connections.js +110 -0
- package/src/adapters/acp-presets.js +37 -0
- package/src/adapters/acp-types.js +0 -0
- package/src/adapters/acp.js +328 -0
- package/src/adapters/agent-tools.js +28 -0
- package/src/adapters/agy-auth.js +67 -0
- package/src/adapters/agy-isolation.js +242 -0
- package/src/adapters/agy-tools.js +45 -0
- package/src/adapters/agy.js +326 -0
- package/src/adapters/claude-stream.js +58 -0
- package/src/adapters/claude.js +282 -0
- package/src/adapters/codex-app-server.js +555 -0
- package/src/adapters/codex.js +311 -0
- package/src/adapters/errors.js +57 -0
- package/src/adapters/index.js +91 -0
- package/src/adapters/managed-permissions.js +37 -0
- package/src/adapters/model-discovery.js +100 -0
- package/src/adapters/process.js +433 -0
- package/src/adapters/team-tools.js +103 -0
- package/src/adapters/types.js +0 -0
- package/src/agent-browser.js +688 -0
- package/src/agent-computer.js +88 -0
- package/src/agent-container.js +155 -0
- package/src/agent-team-definitions.js +131 -0
- package/src/agent-tool-client.mjs +79 -0
- package/src/agent-tools.js +296 -0
- package/src/approvals.js +134 -0
- package/src/architecture.js +456 -0
- package/src/assets.js +44 -0
- package/src/automation.js +901 -0
- package/src/browser-files.js +293 -0
- package/src/browser-ownership.js +150 -0
- package/src/certificate-renewal.js +75 -0
- package/src/chat-family.js +25 -0
- package/src/chat-handoff.js +87 -0
- package/src/checkpoint-review.js +72 -0
- package/src/checks.js +303 -0
- package/src/code-host-git.js +102 -0
- package/src/code-hosts-api.js +99 -0
- package/src/code-hosts.js +482 -0
- package/src/code-intelligence-worker.mjs +452 -0
- package/src/code-intelligence.js +141 -0
- package/src/collab/api.js +365 -0
- package/src/collab/checkpoints.js +198 -0
- package/src/collab/connections.js +139 -0
- package/src/collab/host-execution.js +347 -0
- package/src/collab/hub-client.js +210 -0
- package/src/collab/link-api.js +229 -0
- package/src/collab/link.js +595 -0
- package/src/collab/model.js +496 -0
- package/src/collab/runner.js +1014 -0
- package/src/collab/store.js +1452 -0
- package/src/collab/terminals.js +361 -0
- package/src/collaboration-reviews.js +116 -0
- package/src/config.js +48 -0
- package/src/context-budget.js +14 -0
- package/src/context-inspection.js +204 -0
- package/src/context.js +154 -0
- package/src/conventions.js +283 -0
- package/src/coordinated-api.js +247 -0
- package/src/deferred-launch.js +82 -0
- package/src/deferred-runs.js +515 -0
- package/src/dependency-health.js +35 -0
- package/src/diff.js +43 -0
- package/src/docs-help.js +316 -0
- package/src/doctor.js +232 -0
- package/src/documentation-changes.js +20 -0
- package/src/engine.js +5258 -0
- package/src/env.js +44 -0
- package/src/execution-budget.js +8 -0
- package/src/experience.js +50 -0
- package/src/extensions.js +144 -0
- package/src/filesystem-access.js +107 -0
- package/src/filesystem-policy.js +238 -0
- package/src/filtered-task-limits.js +93 -0
- package/src/filtered-tasks-api.js +53 -0
- package/src/filtered-tasks.js +576 -0
- package/src/frame-policy.js +66 -0
- package/src/fs.js +57 -0
- package/src/git.js +626 -0
- package/src/github-review-threads.js +181 -0
- package/src/github.js +538 -0
- package/src/http.js +69 -0
- package/src/improve-settings.js +38 -0
- package/src/improve.js +187 -0
- package/src/integrations.js +373 -0
- package/src/integrity.js +259 -0
- package/src/journey-api.js +77 -0
- package/src/journey-replay.js +65 -0
- package/src/journey-store.js +97 -0
- package/src/journeys.js +60 -0
- package/src/json.js +81 -0
- package/src/launch-profiles.js +292 -0
- package/src/learnings.js +80 -0
- package/src/local-app-url.js +19 -0
- package/src/log.js +39 -0
- package/src/maintenance.js +335 -0
- package/src/memory-analysis.js +182 -0
- package/src/memory-claims.js +153 -0
- package/src/memory-sqlite.js +236 -0
- package/src/memory.js +552 -0
- package/src/merge-validation.js +58 -0
- package/src/model-catalog.js +239 -0
- package/src/model-research.js +91 -0
- package/src/notes.js +176 -0
- package/src/notifications.js +413 -0
- package/src/patterns/auto-team-model.js +230 -0
- package/src/patterns/auto-team.js +816 -0
- package/src/patterns/council.js +199 -0
- package/src/patterns/debate.js +188 -0
- package/src/patterns/findings.js +141 -0
- package/src/patterns/index.js +21 -0
- package/src/patterns/loop.js +158 -0
- package/src/patterns/pipeline.js +125 -0
- package/src/patterns/prompts.js +181 -0
- package/src/patterns/race.js +147 -0
- package/src/patterns/schemas.js +40 -0
- package/src/patterns/solo.js +46 -0
- package/src/patterns/supervisor.js +235 -0
- package/src/patterns/task-draft.js +29 -0
- package/src/patterns/task-review.js +45 -0
- package/src/patterns/tdd.js +231 -0
- package/src/patterns/team-strategies.js +67 -0
- package/src/performance.js +43 -0
- package/src/persistence-status.js +35 -0
- package/src/phone-sessions.js +96 -0
- package/src/preview-overlay.js +392 -0
- package/src/preview.js +230 -0
- package/src/privacy.js +23 -0
- package/src/project-report.js +22 -0
- package/src/project-team-budget.js +22 -0
- package/src/project-team-model.js +225 -0
- package/src/project-team-policy.js +42 -0
- package/src/project-team-store.js +234 -0
- package/src/project-team-usage.js +24 -0
- package/src/project-teams-api.js +43 -0
- package/src/project-teams.js +644 -0
- package/src/projects.js +290 -0
- package/src/provider-eligibility.js +9 -0
- package/src/readiness.js +98 -0
- package/src/remote-tls.js +66 -0
- package/src/remote-workers/bundles.js +198 -0
- package/src/remote-workers/client.js +332 -0
- package/src/remote-workers/durability.js +37 -0
- package/src/remote-workers/protocol.js +68 -0
- package/src/remote-workers/stdio.js +138 -0
- package/src/remote-workers/worker.js +304 -0
- package/src/remote.js +204 -0
- package/src/repo-config.js +201 -0
- package/src/repo-coordination.js +725 -0
- package/src/repo-tree.js +106 -0
- package/src/repository-identity.js +13 -0
- package/src/retention-policy.js +466 -0
- package/src/review-inbox.js +38 -0
- package/src/routing.js +49 -0
- package/src/run-analysis.js +111 -0
- package/src/run-cold-store.js +231 -0
- package/src/run-environment.js +15 -0
- package/src/run-history.js +91 -0
- package/src/run-log.js +160 -0
- package/src/run-permissions.js +111 -0
- package/src/run-projection.js +77 -0
- package/src/run-recovery.js +53 -0
- package/src/run-status.js +56 -0
- package/src/serve.js +138 -0
- package/src/server.js +2871 -0
- package/src/shared-access.js +103 -0
- package/src/shared-accounts.js +381 -0
- package/src/shared-api.js +239 -0
- package/src/shell.js +346 -0
- package/src/ship.js +344 -0
- package/src/slots.js +74 -0
- package/src/snapshot.js +388 -0
- package/src/source-context.js +17 -0
- package/src/sse-writer.js +70 -0
- package/src/ssh-projects/bootstrap.mjs +95 -0
- package/src/ssh-projects/config.js +45 -0
- package/src/ssh-projects/gateway.js +143 -0
- package/src/ssh-projects/manager.js +320 -0
- package/src/ssh-projects/team-autostart.mjs +93 -0
- package/src/ssh-projects/team-remove.mjs +69 -0
- package/src/ssh-projects/team-status.mjs +39 -0
- package/src/ssh-projects/transport.js +133 -0
- package/src/stats.js +139 -0
- package/src/store.js +544 -0
- package/src/stream.js +91 -0
- package/src/sweeps.js +241 -0
- package/src/tailscale.js +101 -0
- package/src/task-draft.js +23 -0
- package/src/task-team.js +164 -0
- package/src/team-evaluation.js +243 -0
- package/src/team-mailbox.js +160 -0
- package/src/team-memory.js +84 -0
- package/src/team-rerun-graph.js +15 -0
- package/src/team-reruns.js +130 -0
- package/src/team-scheduler.js +121 -0
- package/src/team-steering.js +21 -0
- package/src/team-template-store.js +98 -0
- package/src/team-templates.js +117 -0
- package/src/team-tool-client.mjs +79 -0
- package/src/team-tools.js +235 -0
- package/src/teams.js +0 -0
- package/src/templates.js +62 -0
- package/src/transcript.js +134 -0
- package/src/verification-integrity.js +27 -0
- package/src/verification.js +183 -0
- package/src/watch.js +195 -0
- package/src/work-queue.js +47 -0
- package/src/workflow-control.js +83 -0
- package/src/workspace-api.js +207 -0
- package/src/workspace-changes.js +61 -0
- package/src/workspace.js +146 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{E as _,H as I,J as K,x as W}from"./chunk-63YLZ3PR.js";var l,o={state:"connecting"},O=new Set;function V(e){if(i)throw new Error("Configure stream sharing before subscribing");l=e&&/^[a-f0-9]{64}$/.test(e.channelKey)&&/^[a-f0-9]{32}$/.test(e.lockId)?{...e}:void 0}function Y(e){return O.add(e),e(o),()=>{O.delete(e)}}function f(e){o=typeof navigator<"u"&&navigator.onLine===!1?{...e,state:"offline"}:e;for(let t of O)t(o);i==="leader"&&m?.postMessage({kind:"state",state:o})}var b=new Map,z=1,i;function Z(e,t,r){i??U();let n=z++,a={topic:e,onData:t,cursor:r};return b.set(n,a),i==="follower"?w():A(n,{topic:e,cursor:()=>r?.(),deliver:t}),()=>{b.delete(n)&&(i==="follower"?w():J(n))}}var c=new Map,p=new Set,M=new Set,d,u="",C=!1,q=!1,g,x=0,T=!1;function A(e,t){if(c.set(e,t),d||g)return E();T||(T=!0,queueMicrotask(()=>{T=!1,!d&&!g&&$()}))}function J(e){c.delete(e)&&(M.delete(e),E())}function j(e,t){let r=t.cursor();return r?{id:e,topic:t.topic,after:r}:{id:e,topic:t.topic}}function $(){if(clearTimeout(g),g=void 0,d?.close(),u="",M.clear(),!c.size){d=void 0;return}f({...o,state:x?"reconnecting":"connecting"});let e=[...c].map(([r,n])=>j(r,n));p=new Set(e.map(r=>r.id));let t=new EventSource(_(`/api/stream?subs=${encodeURIComponent(JSON.stringify(e))}`));d=t,t.onmessage=r=>{if(d!==t)return;let n;try{n=JSON.parse(r.data)}catch{return}if(!n||!Number.isSafeInteger(n.s)||n.s<0||!n.d||typeof n.d!="object")return;let{s:a,d:s}=n;if(f({state:"connected",lastReceived:Date.now()}),a===0){s?.type==="hello"&&(u=s.client,x=0,E());return}s?.type==="error"&&(p.delete(a),M.add(a)),c.get(a)?.deliver(s)},t.onerror=()=>{d===t&&F()}}function F(){d?.close(),d=void 0,u="",f({...o,state:"reconnecting"}),clearTimeout(g);let e=[500,1e3,2e3,5e3][Math.min(x++,3)],t=async()=>{try{if(l){let r=await I("/api/auth/self");if(r.kind!=="owner"||r.streamSharing?.channelKey!==l.channelKey||r.streamSharing?.lockId!==l.lockId){location.reload();return}}await I("/api/health"),$()}catch{g=setTimeout(()=>void t(),5e3)}};g=setTimeout(()=>void t(),e)}function E(){q||(q=!0,queueMicrotask(()=>{q=!1,Q()}))}async function Q(){if(C||!u)return;let e=[...c].filter(([n])=>!p.has(n)&&!M.has(n)),t=[...p].filter(n=>!c.has(n));if(!e.length&&!t.length)return;C=!0;let r=u;for(let[n]of e)p.add(n);for(let n of t)p.delete(n);try{await K(`/api/stream/${r}`,{subscribe:e.map(([n,a])=>j(n,a)),unsubscribe:t})}catch(n){let a=n instanceof W?n.status:0;u===r&&(a===0||a===404||a>=500)&&F()}finally{C=!1,u&&E()}}var L="codeflow-stream",v="",y="",k=`${Date.now().toString(36)}${Math.random().toString(36).slice(2,10)}`,P=15e3,m,S=new Map;function U(){if(window.addEventListener("offline",()=>f({...o,state:"offline"})),window.addEventListener("online",()=>{f({...o,state:"reconnecting"}),i==="follower"?w():c.size&&$()}),!l||typeof BroadcastChannel!="function"||typeof navigator>"u"||!navigator.locks?.request){i="solo";return}v=`${L}:${l.channelKey}`,y=`${L}:${l.lockId}`,i="follower",m=new BroadcastChannel(v);let e=new BroadcastChannel(`${v}:${k}`);e.onmessage=t=>{t.data.s===0&&t.data.d?.type==="transport"?f(t.data.d.state):b.get(t.data.s)?.onData(t.data.d)},m.onmessage=t=>{let r=t.data;r.kind==="leader"?(f(r.state),i==="follower"&&w()):r.kind==="state"?i==="follower"&&f(r.state):i==="leader"&&N(r.window,r.kind==="subs"?r.subs:[])},navigator.locks.request(y,()=>(X(),new Promise(()=>{}))),navigator.locks.request(`${y}:${k}`,()=>new Promise(()=>{})),window.addEventListener("pagehide",()=>i==="follower"&&m?.postMessage({kind:"bye",window:k})),setInterval(()=>{if(i==="follower")w();else if(i==="leader")for(let[t,r]of S)Date.now()-r.seen>P*3&&N(t,[])},P)}function X(){i="leader";for(let[e,t]of b)c.set(e,{topic:t.topic,cursor:()=>t.cursor?.(),deliver:t.onData});$(),m.postMessage({kind:"leader",state:o})}var B=!1;function w(){B||(B=!0,queueMicrotask(()=>{B=!1,i==="follower"&&m.postMessage({kind:"subs",window:k,subs:[...b].map(([e,t])=>[e,t.topic,t.cursor?.()])})}))}function N(e,t){let r=S.get(e);if(!r){if(!t.length)return;r={ids:new Map,cursors:new Map,seen:0,out:new BroadcastChannel(`${v}:${e}`)},S.set(e,r),navigator.locks.request(`${y}:${e}`,()=>S.get(e)===r&&N(e,[]))}let n=r;n.out.postMessage({s:0,d:{type:"transport",state:o}}),n.seen=Date.now();let a=new Map(t.map(([s,h,D])=>[s,{topic:h,after:D}]));for(let[s,h]of n.ids)a.has(s)||(n.ids.delete(s),n.cursors.delete(s),J(h));for(let[s,{topic:h,after:D}]of a){if(n.cursors.set(s,D),n.ids.has(s))continue;let R=z++;n.ids.set(s,R),A(R,{topic:h,cursor:()=>n.cursors.get(s),deliver:H=>n.out.postMessage({s,d:H})})}n.ids.size||(n.out.close(),S.delete(e))}export{V as a,Y as b,Z as c};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{B as J,F as pe,G as M,y as ce}from"./chunk-SIHDWM2Y.js";import"./chunk-APQEVJ2K.js";import{e as B}from"./chunk-2PZVOKID.js";import"./chunk-5SARP5MU.js";import{$ as ie,L as re,X as ne,aa as le,ma as oe}from"./chunk-J4VYS3KV.js";import"./chunk-CGOZQMEZ.js";import"./chunk-4D5IENEB.js";import"./chunk-TEJVYIKC.js";import{H as w,J as H,K as te,N as d,S as se,T as ae,aa as R,d as X,da as e,h as i,i as I,j as Z,k as ee}from"./chunk-63YLZ3PR.js";var P=te("codeflow-file-drafts-v1"),ue=s=>/(^|\/)(?:\.env(?:\..*)?|.*\.(?:pem|key))$/.test(s);function de(){try{let s=JSON.parse(sessionStorage.getItem(P)??"[]");return Array.isArray(s)?s.filter(r=>!!r&&typeof r.folder=="string"&&typeof r.path=="string"&&typeof r.text=="string"&&typeof r.draft=="string"&&typeof r.hash=="string"&&Number.isFinite(r.at)&&r.at>Date.now()-864e5&&!ue(r.path)).slice(-10):[]}catch{return[]}}function fe(s,r){return de().find(f=>f.folder===s&&f.path===r)}function _(s,r,f,c=!1){try{let p=de().filter(m=>m.folder!==s||m.path!==r.path);if(ue(r.path))return sessionStorage.setItem(P,JSON.stringify(p)),"sensitive";if(JSON.stringify({...r,draft:f}).length>2e6)return"full";for(f!==r.text&&p.push({folder:s,...r,draft:f,at:Date.now(),mergeConflict:c});p.length>10||JSON.stringify(p).length>2e6;)p.shift();return sessionStorage.setItem(P,JSON.stringify(p)),"saved"}catch{return"full"}}function He({folder:s,initialPath:r,onClose:f,compact:c=!1}){let[p,m]=i("files"),[l,A]=i(!1),[q,L]=i(""),[x,he]=i(""),v=async t=>{if(!l){A(!0),L("");try{await t()}catch(n){L(n.message)}finally{A(!1)}}},[S,be]=i(""),[$,me]=i("text"),[ve,U]=i([]),[j,z]=i(""),[a,g]=i(null),[u,F]=i(null),h=a?.path??u?.path,[o,E]=i(""),[D,k]=i(!1),[K,T]=i(!1),[Y,Q]=i(""),[V,W]=i(""),[C,N]=i(!1);Z(()=>{a?.folder===s&&Q(_(s,a,o,C))},[s,a,C]),I(()=>{if(!a||o===a.text)return;let t=n=>{n.preventDefault(),n.returnValue=""};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[a,o]);let y=t=>v(async()=>{let n;try{n={...await w(`/api/workspace/file?repo=${d(s)}&path=${d(t)}`),folder:s}}catch(xe){let ke=await w(`/api/file?repo=${d(s)}&path=${d(t)}`);g(null),F({...ke,reason:xe.message});return}F(null);let b=fe(s,n.path);N(b?.mergeConflict===!0),g(b?{...n,text:b.text,hash:b.hash}:n),E(b?.draft??n.text),T(!!b&&b.hash!==n.hash),k(!1),W(""),b&&R("Recovered your unsaved draft for this tab. Review it before saving.",5e3)}),ge=()=>v(async()=>{if(!a)return;let t=await H("/api/workspace/merge-file",{repo:s,path:a.path,base:a.text,draft:o});g({...t.current,folder:s}),E(t.text),T(!1),k(!0),N(!t.clean),W(t.clean?"Independent edits merged. Review the result before saving.":`${t.conflicts} overlapping change(s). Edit the marked sections to preserve the intended result, then remove every conflict marker before saving.`)}),ye=()=>v(async()=>{if(a)try{let t=await H("/api/workspace/file",{repo:s,path:a.path,text:o,expectedHash:a.hash});g({...a,...t,text:o}),N(!1),k(!1),R("File saved")}catch(t){throw T(!0),t}}),O=ee();I(()=>{if(!r){O.current=void 0;return}!l&&O.current!==r&&(O.current=r,y(r))},[r,l]);let we=()=>v(async()=>{let t=await w(`/api/workspace/search?repo=${d(s)}&q=${d(S)}&mode=${$}`);U(t.hits),z(`${t.scanned} files inspected${t.truncated?" \xB7 results limited; narrow your query":""}`)}),G=()=>{g(null),F(null),f?.()};return e("section",{class:`code-browser ${c?"compact-files":""} ${h?"file-open":""}`,"aria-label":"Code browser",children:[c?e("header",{class:"files-heading",children:[h?e("button",{class:"btn ghost small","aria-label":"Back to the files",onClick:G,children:["\u2190 ",p==="search"?"Search":"Files"]}):e("div",{class:"segmented small",role:"group","aria-label":"File explorer view",children:[e("button",{"aria-pressed":p==="files",onClick:()=>m("files"),children:"Files"}),e("button",{"aria-pressed":p==="search",onClick:()=>m("search"),children:[e(B,{name:"search"}),"Search"]})]}),e("span",{class:"files-location",title:s,children:se(s)}),a&&o!==a.text?e("span",{class:"badge",children:"Unsaved"}):null]}):e("p",{class:"help code-scope",children:["Editing scope: ",e("code",{children:s||"Choose a repository"})]}),q?e("p",{class:"msg err",role:"alert",children:q}):null,l?e("p",{class:"help files-progress",role:"status",children:"Working\u2026"}):null,c?e("div",{class:"files-explorer",hidden:!!h||p!=="files",children:e(J,{root:s,onOpen:t=>{l||y(t)}})},"explorer"):e("details",{open:!h,children:[e("summary",{children:"Browse files"}),e(J,{root:s,onOpen:t=>{l||y(t)}})]}),h?e("div",{class:"files-actions settings-actions",children:[c?null:e("button",{class:"btn small",onClick:G,children:"Back to the files"}),re.value.view==="composer"&&s===oe.value?e("button",{class:"btn small",onClick:()=>ce({path:h,type:"file"}),children:"+ Task"}):null,e("button",{class:"btn small ghost",onClick:()=>{le.value=`About ${h}: `,ie(null),ne("chat")},children:[e(B,{name:"chat"}),"Ask about this file"]})]},"actions"):null,u?e("section",{"aria-label":"Read-only file preview",children:[e("h3",{class:"file-title",title:u.path,children:u.path}),e("p",{class:"help",children:["Read-only \xB7 ",ae(u.size)]}),e("details",{children:[e("summary",{children:"Preview details"}),e("p",{class:"help",children:u.reason})]}),u.binary?e("p",{children:"This is a binary file."}):e("pre",{class:"file-view",tabIndex:0,children:u.text?.split(`
|
|
2
|
+
`).slice(0,5e3).join(`
|
|
3
|
+
`)}),u.truncated||(u.text?.split(`
|
|
4
|
+
`).length??0)>5e3?e("p",{class:"help",children:"Showing a bounded preview; the rest of the file is omitted."}):null]}):null,e("div",{class:"files-search-tools",hidden:c&&(!!h||p!=="search"),children:[c?null:e("h2",{children:"Search and edit"}),e("form",{class:"wb-row",onSubmit:t=>{t.preventDefault(),we()},children:[e("select",{class:"field","aria-label":"Code search mode",value:$,onChange:t=>me(t.currentTarget.value),children:[e("option",{value:"text",children:"Text"}),e("option",{value:"symbols",children:"Declarations"}),e("option",{value:"semantic",children:"JavaScript/TypeScript symbols"})]}),e("input",{class:"field","aria-label":"Search code",disabled:!s||l,placeholder:$==="symbols"?"Function, class, or variable":"Search file contents",value:S,onInput:t=>be(t.currentTarget.value)}),e("button",{class:"btn",disabled:!s||l||!S.trim(),children:"Search"})]}),c?null:e("p",{class:"help",children:"Declaration search recognizes common forms in several languages. JavaScript/TypeScript symbols and references use an isolated TypeScript language service over bounded saved repository files; external libraries and compiler plugins are excluded."}),j?e("p",{class:"help",role:"status",children:j}):null,e("div",{class:"wb-hits",children:ve.map(t=>e("p",{children:[e("button",{class:"btn ghost wb-path",onClick:()=>y(t.path),children:[t.path,":",t.line," ",t.symbol??""]}),e("code",{children:t.text}),t.column?e("button",{class:"btn small",disabled:l,onClick:()=>v(async()=>{let n=await w(`/api/workspace/references?repo=${d(s)}&path=${d(t.path)}&line=${t.line}&column=${t.column}`);U(n.hits),z(`${n.hits.length} references in ${n.scanned} saved source files${n.truncated?" \xB7 results limited":""}. ${n.note}`)}),children:["Find references to ",t.symbol??`${t.path}:${t.line}`]}):null]},`${t.path}:${t.line}`))}),e("form",{class:"wb-row",onSubmit:t=>{t.preventDefault(),x.trim()&&y(x.trim())},children:[e("input",{class:"field","aria-label":"File to edit",disabled:!s||l,placeholder:"Open a file by path\u2026",value:x,onInput:t=>he(t.currentTarget.value)}),e("button",{class:"btn",disabled:l||!s||!x.trim(),children:"Open file"})]})]},"search"),a?e(X,{children:[e("h3",{class:"file-title",title:a.path,children:a.path}),e("textarea",{class:"field wb-editor","aria-label":"File contents",spellcheck:!1,disabled:l,value:o,onInput:t=>{let n=t.currentTarget.value;E(n),a.folder===s&&Q(_(s,a,n,C))}}),V?e("p",{class:"at-notice",role:"status",children:V}):null,e("div",{class:"wb-row file-save-actions",children:[e("button",{class:"btn primary",disabled:l||K||o===a.text||C&&/^(?:<<<<<<< |=======$|>>>>>>> |\|\|\|\|\|\|\| )/m.test(o),onClick:ye,children:"Save file"}),e("button",{class:"btn",onClick:()=>k(!D),children:D?"Hide comparison":"Preview changes"}),K?e("button",{class:"btn",onClick:ge,children:"Load current version and keep draft"}):null,c?null:e("button",{class:"btn",onClick:()=>M(a.path.split("/").pop()??"draft.txt",o,"text/plain"),children:"Export draft"})]}),D?e("div",{class:"wb-diff",children:[e("div",{children:[e("h4",{children:"Current file"}),e("pre",{children:a.text})]}),e("div",{children:[e("h4",{children:"Your draft"}),e("pre",{children:o})]})]}):null,e("details",{class:"file-edit-details",open:!c,children:[e("summary",{children:"Editing details"}),e("p",{class:"help",children:["Saving checks the loaded version and preserves concurrent edits. Files in active run worktrees cannot be edited here. ",Y==="sensitive"?"This credential filename is excluded from browser draft recovery; export your draft before leaving.":Y==="full"?"Browser draft storage is unavailable; export your draft before leaving.":"Unsaved drafts can be recovered in this browser tab for 24 hours."]}),c?e("button",{class:"btn small",onClick:()=>M(a.path.split("/").pop()??"draft.txt",o,"text/plain"),children:"Export draft"}):null]}),e(pe,{folder:s,paths:[a.path],refreshKey:a.hash},a.path)]}):null]})}export{He as CodeBrowser};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{H as S,N as c,a as M,d as j,da as e,h as s,i as $,k as C}from"./chunk-63YLZ3PR.js";var T=(g,k={})=>S(g,{method:"POST",body:JSON.stringify(k)});function te({projectId:g,repos:k}){let[I,q]=s(k[0]??""),[E,G]=s(""),[H,U]=s(""),[N,z]=s("claude"),[O,K]=s(!1),[A,Q]=s(10),[V,W]=s([]),[v,F]=s(""),[i,d]=s(null),[o,u]=s(null),[a,B]=s(!1),[L,h]=s(""),[J,y]=s(""),p=C(0),w=C(0),m=C(!1),f=C(v);f.current=v;let P=async(t=p.current,l=!1)=>{if(m.current&&!l)return;let n=++w.current,x=()=>t===p.current&&n===w.current,Y=await S(`/api/filtered-tasks?project=${c(g)}`);if(!x())return;W(Y);let R=f.current;if(R)try{let D=await S(`/api/filtered-tasks/${c(R)}`);x()&&R===f.current&&d(D)}catch(D){x()&&R===f.current&&(d(null),h(D.message))}};$(()=>{let t=++p.current;m.current=!1,B(!1),F(""),f.current="",d(null),u(null),h(""),q(k[0]??"");let l=M(()=>!m.current&&P(t),1500,n=>{t===p.current&&h(n.message)});return()=>{l(),m.current=!1,p.current++,w.current++}},[g]),$(()=>{w.current++,u(null),d(null),v&&P().catch(t=>h(t.message))},[v]);let b=async t=>{if(m.current)return;m.current=!0,w.current++;let l=p.current,n=()=>l===p.current;B(!0),h(""),y("");try{await t(n),n()&&await P(l,!0)}catch(x){n()&&h(x.message)}finally{n()&&(m.current=!1,B(!1))}},X=V.find(t=>t.id===v),r=i??X;return e("section",{class:"wb-card filtered-task-panel","aria-label":"Filtered Docker tasks",children:[e("h2",{children:"Filtered Docker task"}),e("p",{class:"help",children:"Run one manual provider turn against an isolated copy of policy-readable committed files. The container receives a fresh Git repository and no original Git history, host credentials or application memory. Current native, SSH and automated workflows remain paused under restrictions."}),e("p",{class:"help",children:"Use an explicitly prepared local image containing the selected CLI. Its immutable image ID is pinned before execution. The image must work with a read-only root filesystem, a fresh writable home and bounded scratch space; configure provider authentication deliberately inside the prepared runtime. No host authentication volume or cache is mounted. Network is off unless you explicitly enable inference access."}),e("form",{onSubmit:t=>{t.preventDefault(),b(async l=>{let n=await T("/api/filtered-tasks",{project:g,repo:I,task:E,agent:N,image:H,network:O,maxMinutes:A});l()&&(f.current=n.id,F(n.id),d(n),u(null),y("Filtered task started. Results require a separate explicit import."))})},children:[e("div",{class:"filtered-fields",children:[e("label",{class:"lbl",children:["Filtered task repository",e("select",{class:"field",value:I,disabled:a,onChange:t=>q(t.currentTarget.value),children:k.map(t=>e("option",{value:t,children:t}))})]}),e("label",{class:"lbl",children:["Filtered task provider",e("select",{class:"field",value:N,disabled:a,onChange:t=>z(t.currentTarget.value),children:[e("option",{value:"claude",children:"Claude Code"}),e("option",{value:"codex",children:"Codex"}),e("option",{value:"agy",children:"Antigravity"})]})]}),e("label",{class:"lbl",children:["Prepared filtered Docker image",e("input",{class:"field",value:H,required:!0,disabled:a,maxLength:200,placeholder:"prepared-provider:reviewed-version",onInput:t=>U(t.currentTarget.value)})]}),e("label",{class:"lbl",children:["Filtered task time limit (minutes)",e("input",{class:"field",type:"number",min:1,max:30,value:A,disabled:a,onInput:t=>Q(Number(t.currentTarget.value))})]})]}),e("label",{class:"lbl",children:["Filtered task instructions",e("textarea",{class:"field",rows:4,required:!0,maxLength:24e3,value:E,disabled:a,onInput:t=>G(t.currentTarget.value)})]}),e("label",{children:[e("input",{type:"checkbox",checked:O,disabled:a,onChange:t=>K(t.currentTarget.checked)})," Allow container network for inference"]}),e("p",{class:"help",children:"The source is the current committed revision. Uncommitted files are not copied. Readable files denied writes are mounted read-only; every changed output path is rechecked before an import. Exports are monitored for excessive files and disk use; polling is not an operating-system disk quota."}),e("div",{class:"filtered-actions",children:[e("button",{class:"btn primary",disabled:a||!I||!E.trim()||!H.trim(),children:"Start filtered Docker task"}),e("button",{class:"btn",type:"button",disabled:a,onClick:()=>void b(async()=>{await P()}),children:"Refresh filtered tasks"})]})]}),L?e("p",{class:"msg err",role:"alert",children:L}):null,J?e("p",{role:"status",class:"help",children:J}):null,e("label",{class:"lbl",children:["Saved filtered task",e("select",{class:"field",value:v,disabled:a,onChange:t=>F(t.currentTarget.value),children:[e("option",{value:"",children:"Choose a task"}),V.map(t=>e("option",{value:t.id,children:[t.status," \xB7 ",new Date(t.createdAt).toLocaleString()," \xB7 ",t.id.slice(-8)]},t.id))]})]}),r?e("article",{class:"wb-item filtered-task","aria-label":"Selected filtered task",children:[e("h3",{children:r.id}),e("p",{role:"status",children:["Filtered task status: ",r.status,r.containerStopped?" \xB7 daemon container stopped":" \xB7 daemon receipt not confirmed stopped"]}),i?e(j,{children:[e("p",{children:i.task}),e("p",{class:"help",children:["Source ",e("code",{children:i.sourceHead??"preparing"})," \xB7 ",i.exportedFiles," committed files \xB7 ",i.exportedBytes," bytes \xB7 image ",e("code",{children:i.imageId??"resolving"})]}),e("p",{class:"help",children:["Policy revisions: ",i.policyRevisions.map(t=>`${t.projectId}:${t.revision}`).join(", ")]}),i.error?e("p",{class:"msg err",children:i.error}):null,i.finalText?e("pre",{children:i.finalText}):null,i.events.length?e("details",{children:[e("summary",{children:["Provider status (",i.events.length,")"]}),i.events.slice(-20).map(t=>e("p",{children:t.text}))]}):null]}):null,e("div",{class:"filtered-actions",children:[e("button",{class:"btn",disabled:a||["importing","imported"].includes(r.status),onClick:()=>void b(async t=>{await T(`/api/filtered-tasks/${c(r.id)}/cancel`,{revision:r.revision}),t()&&(u(null),y("Owned daemon container absence confirmed."))}),children:"Cancel task and confirm container stopped"}),r.status==="completed"?e("button",{class:"btn",disabled:a,onClick:()=>void b(async t=>{let l=await T(`/api/filtered-tasks/${c(r.id)}/preview-import`);t()&&(u(l),d(l.job))}),children:"Preview allowed import"}):null,r.status==="unknown"&&r.importCommit?e("button",{class:"btn",disabled:a,onClick:()=>void b(async()=>{await T(`/api/filtered-tasks/${c(r.id)}/receipt`,{revision:r.revision})}),children:"Inspect interrupted import receipt"}):null,r.containerStopped&&["completed","failed","cancelled","imported"].includes(r.status)?e("button",{class:"btn",disabled:a,onClick:()=>void b(async t=>{await S(`/api/filtered-tasks/${c(r.id)}`,{method:"DELETE",body:JSON.stringify({revision:r.revision})}),t()&&(f.current="",F(""),d(null),u(null),y("Private task/export deleted; any imported review branch is preserved."))}),children:"Delete private task and export"}):null]}),r.importBranch?e("p",{class:"help",children:["Review branch: ",e("code",{children:r.importBranch})," \xB7 ",e("code",{children:r.importCommit}),". Original checkout and index remain unchanged."]}):null]}):null,o?e("section",{class:"filtered-changes wb-subsection","aria-label":"Filtered import preview",children:[e("h3",{children:"Review allowed changes before import"}),e("p",{class:"help",children:[o.importBehavior,". Source and result hashes, policy revisions, original file contents and index are checked again. No automatic merge, staging, retry or original checkout overwrite occurs."]}),o.changes.map(t=>e("details",{children:[e("summary",{children:[t.status," \xB7 ",t.path,t.binary?" \xB7 binary":"",t.truncated?" \xB7 preview truncated":""]}),e("p",{class:"help",children:["Before ",t.beforeHash??"absent"," \xB7 after ",t.afterHash??"absent"]}),t.before!==void 0?e(j,{children:[e("h4",{children:"Original committed content"}),e("pre",{children:t.before})]}):null,t.after!==void 0?e(j,{children:[e("h4",{children:"Filtered result"}),e("pre",{children:t.after})]}):null]})),e("div",{class:"filtered-actions",children:e("button",{class:"btn primary",disabled:a||!o.changes.length||r?.status!=="completed",onClick:()=>void b(async t=>{await T(`/api/filtered-tasks/${c(o.job.id)}/import`,{revision:o.job.revision,expectedHead:o.sourceHead,resultHash:o.resultHash}),t()&&(u(null),y("Allowed changes imported into a new review branch. Original checkout is unchanged."))}),children:"Import into new review branch"})})]}):null]})}export{te as FilteredTasksPanel};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{L as Ie,k as j,l as Re,m as Ee}from"./chunk-SIHDWM2Y.js";import"./chunk-APQEVJ2K.js";import{e as J,g as Se,l as Te,m as Me,n as Pe,o as Be}from"./chunk-2PZVOKID.js";import"./chunk-5SARP5MU.js";import{$ as de,I as ke,Na as xe,Oa as L,R as Ce,S as $e,Sa as X,Ta as G,Va as pe,X as ce,ca as ue}from"./chunk-J4VYS3KV.js";import"./chunk-CGOZQMEZ.js";import"./chunk-4D5IENEB.js";import"./chunk-TEJVYIKC.js";import{E as Z,H as _,J as ie,R as ye,aa as le,d as ae,da as t,h as w,i as M,k as $,p as ve}from"./chunk-63YLZ3PR.js";var me=r=>r<1024?`${r} B`:r<1024*1024?`${(r/1024).toFixed(1)} KB`:`${(r/1024/1024).toFixed(1)} MB`;function De({scope:r,chooser:s,downloads:a,send:c}){let[d,h]=w(!1),[v,T]=w(""),[p,g]=w(""),P=$();M(()=>(g(""),()=>P.current?.abort()),[s?.id]);let i=async n=>{if(!s||!n.length)return;let y=new AbortController;P.current=y,g("");try{if(s.directory){if(n.length>1e3||n.reduce((m,f)=>m+f.size,0)>500*1024*1024)throw new Error("Choose a folder with up to 1,000 files and 500 MB total.");if(n.some(m=>!m.webkitRelativePath))throw new Error("This browser did not provide folder paths. Choose a folder again.")}else if(n.length>20)throw new Error("Choose up to 20 files.");if(n.some(m=>m.size>100*1024*1024))throw new Error("Each file must be under 100 MB.");let o=[];for(let[m,f]of n.entries()){T(`Uploading ${m+1} of ${n.length}: ${f.webkitRelativePath||f.name}`);let C=await _(`/api/browser/uploads?scope=${encodeURIComponent(r)}&chooser=${encodeURIComponent(s.id)}&name=${encodeURIComponent(f.name)}${s.directory?`&relativePath=${encodeURIComponent(f.webkitRelativePath)}`:""}`,{method:"POST",headers:{"content-type":"application/octet-stream"},body:f,signal:y.signal});o.push(C.id)}await c({action:"upload",chooser:s.id,files:o})}catch(o){y.signal.aborted||g(o.message)}finally{T("")}},x=(n,y)=>void c({action:n,id:y}).catch(o=>g(o.message));return t("section",{class:"browser-transfers","aria-label":"Browser file transfers",children:[s?t("div",{class:"browser-upload","aria-label":"Website file upload",children:[t("div",{children:[t("strong",{children:s.directory?"Choose a folder for this website":"Choose files for this website"}),t("span",{class:"help",children:s.directory?"Up to 1,000 files \xB7 500 MB total \xB7 100 MB per file":`${s.mode==="selectMultiple"?"Multiple files allowed":"One file"} \xB7 up to 100 MB each`})]}),t("label",{class:`btn small${v?" disabled":""}`,children:["Choose ",s.directory?"folder":s.mode==="selectMultiple"?"files":"file",t("input",{type:"file","aria-label":s.directory?"Upload folder to website":"Upload files to website",...s.directory?{webkitdirectory:!0}:{},multiple:!s.directory&&s.mode==="selectMultiple",disabled:!!v,onChange:n=>{let y=Array.from(n.currentTarget.files??[]);n.currentTarget.value="",i(y)}},s.id)]}),t("button",{class:"btn small",onClick:()=>{P.current?.abort(),c({action:"cancel-upload",chooser:s.id}).catch(n=>g(n.message))},children:"Cancel"}),v?t("span",{class:"help",role:"status",children:v}):null]}):null,t("button",{class:"browser-download-toggle","aria-expanded":d,onClick:()=>h(!d),children:[t("span",{"aria-hidden":"true",children:[d?"\u25BE":"\u25B8"," \u2193"]})," Downloads ",t("span",{class:"help",children:[a.length,a.some(n=>n.state==="inProgress")?" \xB7 downloading\u2026":""]})]}),d?t("div",{class:"browser-downloads","aria-label":"Downloads",children:a.length?a.map(n=>t("div",{class:"browser-download","data-download-id":n.id,children:[t("div",{class:"browser-download-info",children:[t("strong",{title:n.name,children:n.name}),t("span",{class:"help",children:n.error||(n.state==="completed"?me(n.receivedBytes):n.state==="canceled"?"Canceled":`${me(n.receivedBytes)}${n.totalBytes?` of ${me(n.totalBytes)}`:""}`)}),n.state==="inProgress"?t("progress",{"aria-label":`Downloading ${n.name}`,max:n.totalBytes||void 0,value:n.totalBytes?n.receivedBytes:void 0}):null]}),n.state==="completed"?t("a",{class:"btn small",href:Z(`/api/browser/downloads/${encodeURIComponent(n.id)}?scope=${encodeURIComponent(r)}`),download:n.name,"aria-label":`Save ${n.name}`,children:"Save"}):null,t("button",{class:"icon-btn",title:n.state==="inProgress"?"Cancel download":"Remove download","aria-label":`${n.state==="inProgress"?"Cancel":"Remove"} ${n.name}`,onClick:()=>x(n.state==="inProgress"?"cancel-download":"remove-download",n.id),children:"\xD7"})]},n.id)):t("p",{class:"help",children:"Files you or an agent download will appear here."})}):null,p?t("div",{class:"msg err",role:"alert",children:p}):null]})}var he=ve({}),ge=r=>he.value[r]??{pins:[],console:[],capturing:0},A=(r,s)=>he.value={...he.value,[r]:s(ge(r))},F=new Map;function Le(r,s){s.type==="ready"?A(r,a=>({...a,ready:!0,document:s.document,capturing:0,pins:a.document===s.document?a.pins:a.pins.map(c=>({...c,gone:!0}))})):s.type==="record-action"?Re(r,s.action):s.type==="recording-warning"&&j.value?.page===r?j.value={...j.value,warning:String(s.text).slice(0,200)}:s.type==="console"?A(r,a=>({...a,console:[...a.console.slice(-299),{level:s.level,text:String(s.text).slice(0,2e3),at:s.at}]})):s.type==="pin-start"?A(r,a=>({...a,capturing:a.capturing+1})):s.type==="pin"&&A(r,a=>({...a,capturing:Math.max(0,a.capturing-1),pins:[...a.pins,{...s.pin,n:(a.pins.at(-1)?.n??0)+1,comment:""}]}))}function Ae({pageKey:r,url:s,width:a,send:c}){let[d,h]=w("off"),[v,T]=w(!1),p=n=>{h(n),c({type:"mode",mode:n}).catch(()=>{})},g=ge(r),P=g.console.filter(n=>n.level!=="warn").length,i=$(c);i.current=c,M(()=>{let n=y=>{i.current(y).catch(()=>{})};return F.set(r,n),n({type:"hello"}),()=>{n({type:"mode",mode:"off"}),n({type:"recording",active:!1}),F.get(r)===n&&F.delete(r)}},[r]),M(()=>{g.ready&&(c({type:"mode",mode:d}).catch(()=>{}),c({type:"recording",active:j.value?.page===r&&j.value.active}).catch(()=>{}))},[d,g.ready,j.value?.active]),M(()=>{c({type:"pins",pins:ze(g.pins)}).catch(()=>{})},[g.pins]);let x=L.value;return t(ae,{children:[t("div",{class:"browse-tools live-annotation-tools",children:[t("button",{class:"btn ghost small","aria-pressed":d==="pick",disabled:!g.ready,onClick:()=>p(d==="pick"?"off":"pick"),children:"Pick"}),t("button",{class:"btn ghost small","aria-pressed":d==="box",disabled:!g.ready,onClick:()=>p(d==="box"?"off":"box"),children:"Box"}),t("button",{class:"btn ghost small","aria-pressed":v,onClick:()=>T(!v),children:["Console",P?` \xB7 ${P}`:""]})]}),t(Ee,{pageKey:r,url:s,repository:x.repo,width:a,ready:g.ready===!0,toggle:n=>(h("off"),c({type:"recording",active:n}))},r),v?t(qe,{pageKey:r,lines:g.console}):null]})}function We({pageKey:r}){let s=ge(r);return s.pins.length||s.capturing?t(Ve,{scope:L.value,pageKey:r,state:s,onSent:()=>F.get(r)?.({type:"mode",mode:"off"})}):null}var ze=r=>r.filter(s=>s.source!=="snapshot").map(s=>({n:s.n,rect:s.rect,kind:s.kind})),Ne=r=>new Promise((s,a)=>{let c=new Image;c.onload=()=>s(c),c.onerror=()=>a(new Error("The snapshot couldn't be read")),c.src=r});async function He(r,s){try{let a=await Ne(r.image),c=Object.assign(document.createElement("canvas"),{width:r.width,height:r.height}),d=c.getContext("2d");d.drawImage(a,0,0);for(let h of s){d.strokeStyle="#2a9b72",d.lineWidth=3,d.strokeRect(h.rect.x+1.5,h.rect.y+1.5,Math.max(0,h.rect.w-3),Math.max(0,h.rect.h-3));let v=Math.min(r.width-14,h.rect.x+h.rect.w),T=Math.max(14,h.rect.y);d.fillStyle="#ffffff",d.beginPath(),d.arc(v,T,15,0,Math.PI*2),d.fill(),d.fillStyle="#343932",d.beginPath(),d.arc(v,T,13,0,Math.PI*2),d.fill(),d.fillStyle="#fbfaf6",d.font="600 14px Inter, system-ui, sans-serif",d.textAlign="center",d.textBaseline="middle",d.fillText(String(h.n),v,T+.5)}return c.toDataURL("image/png")}catch{return}}var Ke={error:"Error",warn:"Warn",network:"Net"};function qe({pageKey:r,lines:s}){return t("div",{class:"browse-console",children:[t("div",{class:"bc-head",children:[t("span",{class:"bc-title",children:"Console"}),t("span",{class:"help",children:"errors, warnings and failed requests since the page opened"}),t("span",{class:"spacer"}),t("button",{type:"button",class:"btn ghost small",disabled:!s.length,onClick:()=>A(r,a=>({...a,console:[]})),children:"Clear"})]}),t("div",{class:"bc-lines",children:s.length?s.map((a,c)=>t("div",{class:`bc-line ${a.level}`,children:[t("span",{class:"bc-level",children:Ke[a.level]}),t("span",{class:"bc-text",children:a.text})]},c)):t("div",{class:"help",children:"Nothing yet."})})]})}var Ye=["font-size","font-weight","color","background-color","padding","margin","border-radius","gap"];function Je(r){let s=[],a=d=>d.status==="done"||d.status==="running",c=r.run;if(c&&a(c)){s.push({key:`main:${c.id}`,label:"Main chat",sub:c.status==="running"?"To the team while it works":"A reply to the agent that built it"});for(let d of Ie(c))s.push({key:d.key,label:`Side chat: ${d.title}`,sub:"In this run's worktree"});Se(c)&&s.push({key:"side:new",label:"New side chat",sub:"A conversation of its own, in this run's worktree"})}for(let d of X.value.chats??[]){let h=ke.value.get(d);h&&a(h)&&s.push({key:`main:${h.id}`,label:`Chat: ${h.task.split(`
|
|
2
|
+
`)[0].slice(0,40)}`,sub:"A chat on its own branch"})}return s.push({key:"composer",label:"New run",sub:"The task of a new run, in the composer"}),s}function Xe(r,s,a,c){let d=r[0]?.url??"",h=i=>`pin-${a}-${i.n}.png`,v=r.map(i=>{let x=i.source==="snapshot"?`an area ${i.rect.w}\xD7${i.rect.h} at ${i.rect.x},${i.rect.y} on the snapshot${c?` (box ${i.n} on ${c.name})`:""}`:i.kind==="box"?`an area ${i.rect.w}\xD7${i.rect.h} at ${i.rect.x},${i.rect.y} (around \`${i.selector}\`)`:`\`${i.selector}\``,n=[`${i.n}. ${x}: ${i.comment.trim()||"(no comment)"}`];return i.url!==d&&n.push(` On: ${i.url}`),i.text&&n.push(` Text: "${i.text.slice(0,120)}"`),i.html&&n.push(` HTML: ${i.html.replace(/\s+/g," ").slice(0,240)}`),i.tried&&Object.values(i.tried).some(Boolean)&&n.push(` Tried in the browser: ${Object.entries(i.tried).filter(([,y])=>y).map(([y,o])=>`${y}: ${o}`).join("; ")}`),i.image&&n.push(` Snapshot: ${h(i)}`),n.join(`
|
|
3
|
+
`)}),T=s.filter(i=>i.level!=="warn").slice(-20),g=[c&&r.every(i=>i.source==="snapshot")?`From a snapshot of ${c.snap.url} (${c.snap.width}px wide${c.snap.full?", the whole page":""}, as a signed-out visitor sees it); the boxes are numbered on ${c.name}:`:d?`From the app in the browser (${d}${r[0]?`, ${r[0].viewport.w}px wide`:""}):`:"From the app in the browser:",...v,T.length?`Console errors and failed requests:
|
|
4
|
+
${T.map(i=>`- ${i.text.split(`
|
|
5
|
+
`)[0].slice(0,300)}`).join(`
|
|
6
|
+
`)}`:""].filter(Boolean).join(`
|
|
7
|
+
`),P=r.filter(i=>i.image).map(i=>{let x=i.image.replace(/^data:image\/png;base64,/,"");return{name:h(i),size:Math.round(x.length*3/4),data:x}});return{text:g,images:P}}var Ge=()=>Date.now().toString(36).slice(-6);function Ve({scope:r,pageKey:s,state:a,onSent:c}){let[d,h]=w(null),[v,T]=w(!1),p=a.console.filter(o=>o.level!=="warn"),g=Je(r),i=g.find(o=>o.key===X.value.sendTo)??g[0],x=(o,m)=>A(s,f=>({...f,pins:f.pins.map(C=>C.n===o?{...C,...m}:C)})),n=o=>{o.gone||F.get(s)?.({type:"reset",id:o.id}),A(s,m=>({...m,pins:m.pins.filter(f=>f.n!==o.n)}))},y=async o=>{let m=Ge(),f=a.pins.filter(S=>S.source==="snapshot"),C=f.length&&a.snap?await He(a.snap,f):void 0,z=C&&a.snap?{name:`snapshot-${m}.png`,snap:a.snap}:void 0,E=Xe(a.pins,v?p:[],m,z),W=E.text,N=C&&z?[{name:z.name,size:Math.round(C.length*3/4),data:C.replace(/^data:image\/png;base64,/,"")},...E.images]:E.images,K={to:o,text:W,images:N};G({sendTo:o});for(let S of a.pins)S.gone||F.get(s)?.({type:"reset",id:S.id});A(s,S=>({...S,pins:[]})),c();let q=xe.value?" in the main window":"";if(o.startsWith("main:")){let S=o.slice(5);r.run?.id===S?pe({view:"run",id:S},[K]):(ue(o,W,N),de(S),ce("chat")),le(`Added to the message box${r.run?.id===S?q:""}: add a line if you like, then send`)}else o.startsWith("side:")?(ue(o,W,N),de(o==="side:new"?null:o),ce("chat")):(pe({view:"composer"},[K]),le(`Added to the task in the composer${q}`))};return t("div",{class:"pins-tray",children:[t("div",{class:"pins-list",children:[a.pins.map(o=>t("div",{class:"pin-row",children:[t("span",{class:"pin-n",children:o.n}),t("div",{class:"pin-main",children:[t("div",{class:"pin-what",title:o.html??o.selector,children:[o.kind==="box"?t("span",{class:"pin-label",children:["Area ",o.rect.w,"\xD7",o.rect.h]}):t("span",{class:"pin-label pin-sel",children:o.selector}),o.image?t("img",{class:"pin-thumb",src:o.image,alt:`Snapshot of pin ${o.n}`}):t("span",{class:"help",children:" \xB7 no snapshot"})]}),t("input",{class:"field","aria-label":`What about pin ${o.n}?`,placeholder:"What's wrong, or what should change?",value:o.comment,onInput:m=>x(o.n,{comment:m.currentTarget.value})}),d===o.n&&o.kind==="element"&&!o.gone?t("div",{class:"adjust",children:Ye.map(m=>t("label",{class:"adj",children:[t("span",{children:m}),t("input",{class:"field mono",placeholder:o.styles?.[m]??"",value:o.tried?.[m]??"",onInput:f=>{let C={...o.tried,[m]:f.currentTarget.value};x(o.n,{tried:C}),F.get(s)?.({type:"adjust",id:o.id,styles:{[m]:f.currentTarget.value}})}})]},m))}):null]}),t("div",{class:"pin-actions",children:[o.kind==="element"?t("button",{type:"button",class:`btn ghost small ${d===o.n&&!o.gone?"on":""}`,disabled:o.gone,title:o.gone?"The page has loaded again since you picked this, so its element is gone":"Try style changes on the page; what you try goes with the pin",onClick:()=>h(d===o.n?null:o.n),children:"Adjust"}):null,t("button",{type:"button",class:"icon-btn","aria-label":`Remove pin ${o.n}`,title:"Remove",onClick:()=>n(o),children:t(J,{name:"close"})})]})]},o.n)),a.capturing?t("div",{class:"help",children:"Taking a snapshot\u2026"}):null]}),t("div",{class:"pins-actions",children:[p.length?t("label",{class:"check",children:[t("input",{type:"checkbox",checked:v,onChange:o=>T(o.currentTarget.checked)})," with ",p.length," console error",p.length===1?"":"s"]}):null,t("span",{class:"spacer"}),t(Me,{label:"Send to",icon:"chevron",title:"Send the pins somewhere else",children:o=>t(ae,{children:[t(Be,{children:"Send to"}),g.map(m=>t(Pe,{on:m.key===i.key,sub:m.sub,onClick:()=>{o(),y(m.key)},children:m.label},m.key))]})}),t("button",{type:"button",class:"btn primary small",disabled:!a.pins.length,onClick:()=>void y(i.key),children:["Add to ",i.key.startsWith("main:")&&i.label==="Main chat"?"main chat":i.key==="composer"?"a new run":i.label.toLowerCase().startsWith("side chat")?"side chat":i.label]})]})]})}var Oe=r=>(r.altKey?1:0)|(r.ctrlKey?2:0)|(r.metaKey?4:0)|(r.shiftKey?8:0);function yt(){return t(Qe,{},L.value.key)}function Qe(){let r=L.value.key,s=`/api/browser?scope=${encodeURIComponent(r)}`,a=Ce.value&&$e.value==="browser",[c,d]=w({user:!1,waiting:0}),[h,v]=w(!1),T=async e=>{v(!0);try{d(await ie(`/api/browser/control?scope=${encodeURIComponent(r)}`,{action:e}))}catch(u){E(u.message)}finally{v(!1)}},[p,g]=w(),[P,i]=w([]),x=$(!1);ye(e=>_("/api/serve").then(u=>e()&&i(u),()=>{}),5e3,[],a);let[n,y]=w(),[o,m]=w(),[f,C]=w(!1),[z,E]=w(""),[W,N]=w(""),[K,q]=w(""),[S,Ue]=w("full"),I=$(null),V=$(null),ee=$(null),te=$(null),be=$(0),ne=$(!1),H=$(),fe=$(Promise.resolve()),Y=$(!0);M(()=>(Y.current=!0,()=>{Y.current=!1}),[]);let B=e=>{let u=fe.current.catch(()=>{}).then(async()=>{if(Y.current)try{let l=await ie(s,e);return Y.current&&E(""),l}catch(l){throw Y.current&&E(l.message),l}});return fe.current=u.catch(()=>{}),u},R=(e,u={})=>{let l=e==="dialog"&&p?.selected?{tab:p.selected,view:p.view}:H.current;l&&B({action:e,tab:l.tab,view:l.view,...u}).catch(()=>{})};M(()=>{if(!a)return;let e=new EventSource(Z(`/api/browser/events?scope=${encodeURIComponent(r)}`));return e.onmessage=u=>{let l=JSON.parse(u.data);l.type==="control"?d(l):l.type==="state"?(g(l),C(!0),l.selected!==H.current?.tab&&(y(b=>b?.tab===l.selected?b:void 0),H.current=void 0,m(void 0))):l.type==="frame"?(y(l),C(!0)):l.type==="overlay"?Le(`${r}|${l.tab}`,l.message):l.type==="error"?E(l.message):l.type==="closed"&&(e.close(),C(!1),E("The browser session ended. Reopen the Browser panel to reconnect."))},e.onerror=()=>C(!1),()=>{e.close(),C(!1)}},[a,r]);let k=p?.tabs.find(e=>e.id===p.selected);M(()=>{ne.current||N(k?.url==="about:blank"?"":k?.url??""),k?.url&&k.url!=="about:blank"&&G({url:k.url},r)},[k?.url,k?.id]),M(()=>{q(p?.dialog?.defaultPrompt??"")},[p?.dialog?.message]),M(()=>{if(!n||!I.current)return;let e=!0,u=new Image;return u.onload=()=>{!e||!I.current||(I.current.width=u.width,I.current.height=u.height,I.current.getContext("2d").drawImage(u,0,0),I.current.dataset.frames=String(Number(I.current.dataset.frames??0)+1),H.current=n,m({tab:n.tab,view:n.view}))},u.src=`data:image/jpeg;base64,${n.data}`,()=>{e=!1}},[n]),M(()=>{if(!a||!V.current||!p?.selected)return;let e,u=()=>{clearTimeout(e),e=setTimeout(()=>{let b=V.current?.getBoundingClientRect();!b?.width||!b.height||B({action:"resize",width:Math.min(2560,Math.max(240,S==="phone"?390:S==="tablet"?768:Math.round(b.width))),height:Math.min(1600,Math.max(200,Math.round(b.height)))}).catch(()=>{})},100)},l=new ResizeObserver(u);return l.observe(V.current),u(),()=>{l.disconnect(),clearTimeout(e)}},[a,p?.selected,S]);let je=e=>{x.current=!0,B({action:"navigate",url:/^https?:\/\//i.test(e)?e:/^(localhost|127\.|\[::1\])/.test(e)?`http://${e}`:`https://${e}`}).catch(()=>{})},re=$(""),we=$(!1),D=X.value;M(()=>{if(!p?.selected)return;let e=D.browserRequest,u=D.pages?.find(U=>U.id===D.page)?.url??D.url??D.pages?.[0]?.url,l=e&&e.id!==D.browserHandled?e.id:!we.current&&k?.url==="about:blank"&&u?"restore":"";we.current=!0;let b=l==="restore"?u:e?.url;if(!l||!b||re.current===l)return;re.current=l;let O=p.tabs.find(U=>U.url===b);B(O?{action:"tabs",operation:"select",tab:O.id}:{action:"navigate",url:b}).then(()=>{e?.id===l&&G({browserHandled:l},r)},()=>{re.current=""})},[p?.selected,D.browserRequest?.id,k?.url]),M(()=>{if(x.current||!p?.selected||k?.url!=="about:blank"||D.url||D.browserRequest)return;let e=L.value.run?.worktrees.map(l=>l.path)??[L.value.repo],u=P.find(l=>l.status==="running"&&e.some(b=>b&&(l.cwd===b||l.cwd.startsWith(`${b}/`))));u&&(x.current=!0,B({action:"navigate",url:u.url}).catch(()=>{}))},[p?.selected,k?.url,P]);let Q=(e,u)=>{let l=H.current,b=I.current?.getBoundingClientRect();if(!l||!b)return;let O=Math.min(b.width/l.width,b.height/l.height),U=(e.clientX-b.x-(b.width-l.width*O)/2)/O,se=(e.clientY-b.y-(b.height-l.height*O)/2)/O;if(U<0||se<0||U>l.width||se>l.height)return;let oe=e instanceof WheelEvent;R("mouse",{type:u,x:U,y:se,button:oe||u==="mouseMoved"&&!e.buttons?"none":e.button===2?"right":e.button===1?"middle":"left",buttons:oe?0:e.buttons,clickCount:Math.max(1,Math.min(3,e.detail||1)),modifiers:Oe(e),...oe?{deltaX:Math.round(Math.max(-1e4,Math.min(1e4,e.deltaX))),deltaY:Math.round(Math.max(-1e4,Math.min(1e4,e.deltaY)))}:{}})},Fe=e=>{if(!(e.isComposing||["Shift","Control","Meta","Alt"].includes(e.key))){if((e.metaKey||e.ctrlKey)&&["l","r"].includes(e.key.toLowerCase())){e.preventDefault(),e.key.toLowerCase()==="l"?(te.current?.focus(),te.current?.select()):R("reload");return}if(!((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="v")){if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="c"){e.preventDefault(),e.stopPropagation();let u=H.current;u&&B({action:"selection",tab:u.tab,view:u.view}).then(l=>navigator.clipboard.writeText(l.text)).catch(l=>E(l.message));return}e.key.length===1&&!e.metaKey&&!e.ctrlKey&&!e.altKey||(e.preventDefault(),R("key",{key:e.key,code:e.code,keyCode:e.keyCode,modifiers:Oe(e)}),e.key==="Escape"?ee.current?.blur():e.stopPropagation())}}};return t("div",{class:"interactive-browser",children:[t(Te,{label:"Open pages",active:p?.selected,items:(p?.tabs??[]).map(e=>({key:e.id,label:e.url==="about:blank"?"New tab":e.title||e.url,title:e.url})),onPick:e=>void B({action:"tabs",operation:"select",tab:e}).catch(()=>{}),onClose:e=>void B({action:"tabs",operation:"close",tab:e}).catch(()=>{}),children:t("button",{class:"icon-btn","aria-label":"New browser tab",title:"New browser tab",onClick:()=>{x.current=!0,B({action:"tabs",operation:"new"}).catch(()=>{})},children:t(J,{name:"plus"})})}),t("form",{class:"live-browser-address",onSubmit:e=>{e.preventDefault(),ne.current=!1,W.trim()&&je(W.trim())},children:[t("button",{type:"button",class:"icon-btn","aria-label":"Back",onClick:()=>R("back"),children:t("span",{"aria-hidden":"true",children:"\u2190"})}),t("button",{type:"button",class:"icon-btn","aria-label":"Forward",onClick:()=>R("forward"),children:t("span",{"aria-hidden":"true",children:"\u2192"})}),t("button",{type:"button",class:"icon-btn","aria-label":"Reload",onClick:()=>R("reload"),children:t(J,{name:"refresh"})}),t("input",{ref:te,class:"field","aria-label":"Address",placeholder:"Enter a website address",value:W,onInput:e=>{ne.current=!0,N(e.currentTarget.value)}}),t("button",{class:"btn small",type:"submit",children:"Go"})]}),t("div",{class:"live-browser-toolbar",children:[t("span",{class:"help",role:"status",children:[f?c.user?"You have control":c.owner?`${c.owner} is using the browser`:"Live browser \xB7 shared with agents":"Connecting to Chrome\u2026",c.waiting?` \xB7 ${c.waiting} waiting`:""]}),t("button",{type:"button",class:"btn small",disabled:h,onClick:()=>void T(c.user?"release":"takeover"),children:h?"Handing over\u2026":c.user?"Let agents continue":"Take control"}),t("select",{class:"field","aria-label":"Browser viewport",value:S,onChange:e=>Ue(e.currentTarget.value),children:[t("option",{value:"full",children:"Fit panel"}),t("option",{value:"tablet",children:"Tablet"}),t("option",{value:"phone",children:"Phone"})]})]}),t(De,{scope:r,chooser:p?.chooser,downloads:p?.downloads??[],send:B}),z?t("div",{class:"msg err",role:"alert",children:z}):null,k&&/^https?:\/\//.test(k.url)?t(Ae,{pageKey:`${r}|${k.id}`,url:k.url,width:p.width,send:e=>B({action:"overlay",tab:k.id,message:e})},k.id):null,t("div",{class:"live-browser-surface",ref:V,children:[p?.dialog?t("form",{class:"live-browser-dialog","aria-label":"Website dialog",onSubmit:e=>{e.preventDefault(),R("dialog",{accept:!0,text:K})},children:[t("p",{children:p.dialog.message}),p.dialog.type==="prompt"?t("input",{class:"field","aria-label":"Website prompt",value:K,onInput:e=>q(e.currentTarget.value)}):null,t("button",{class:"btn primary",children:"OK"}),t("button",{type:"button",class:"btn",onClick:()=>R("dialog",{accept:!1}),children:"Cancel"})]}):null,t("canvas",{ref:I,hidden:!n,role:"img","aria-label":"Live browser page","data-tab":o?.tab,"data-view":o?.view,"data-frame-width":n?.width,"data-frame-height":n?.height,"data-ready":f&&o?.view===p?.view&&o?.tab===p?.selected,onContextMenu:e=>e.preventDefault(),onPointerDown:e=>{e.preventDefault(),ee.current?.focus({preventScroll:!0}),e.currentTarget.setPointerCapture(e.pointerId),Q(e,"mousePressed")},onPointerUp:e=>{Q(e,"mouseReleased"),e.currentTarget.hasPointerCapture(e.pointerId)&&e.currentTarget.releasePointerCapture(e.pointerId)},onPointerMove:e=>{(e.buttons||performance.now()-be.current>80)&&(be.current=performance.now(),Q(e,"mouseMoved"))},onWheel:e=>{e.preventDefault(),Q(e,"mouseWheel")}}),t("textarea",{ref:ee,class:"live-browser-keyboard","aria-label":"Type in browser page",autoComplete:"off",autoCapitalize:"off",spellcheck:!1,onKeyDown:Fe,onInput:e=>{if(e.isComposing)return;let u=e.currentTarget.value;e.currentTarget.value="",u&&R("text",{text:u})},onCompositionEnd:e=>{let u=e.currentTarget.value;e.currentTarget.value="",u&&R("text",{text:u})},onPaste:e=>{e.preventDefault();let u=e.clipboardData?.getData("text/plain");u&&R("text",{text:u})}}),n?null:t("div",{class:"live-browser-empty",children:f?"Open a website to start browsing":"Starting your browser\u2026"})]}),k?t(We,{pageKey:`${r}|${k.id}`}):null]})}export{yt as BrowserTab,Qe as InteractiveBrowser};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as g}from"./chunk-APQEVJ2K.js";import{b as k,c as h,d as S}from"./chunk-4D5IENEB.js";import{G as m,ba as C,d as u,da as e,h as t,i as j}from"./chunk-63YLZ3PR.js";function P({token:p}){let[n,I]=t(null),[y,s]=t(""),[i,l]=t(!1),[r,T]=t(!1),[b,x]=t(""),[f,E]=t(""),[v,d]=t(""),[a,J]=t(null),w=async()=>{l(!0),s("");try{I(await m("/api/auth/invitations/preview",{method:"POST",body:JSON.stringify({token:p})}))}catch(o){s(o.message)}finally{l(!1)}};j(()=>{w()},[p]);let L=async o=>{if(o.preventDefault(),!i){l(!0),s("");try{let c=await m("/api/auth/invitations/accept",{method:"POST",body:JSON.stringify({token:p,existing:r,username:b,displayName:f,password:v})});J(c),history.replaceState(null,"",`/#/team/project/${encodeURIComponent(c.projectId)}`)}catch(c){s(c.message)}finally{d(""),l(!1)}}};return e("main",{class:"shared-surface shared-login",children:e("div",{class:"shared-card join-project",children:[e("div",{class:"shared-brand",children:["code",e("span",{children:"-flow"})]}),a&&n?e(u,{children:[e("span",{class:"badge ok",children:"Connected to the project"}),e("h1",{children:["You\u2019re in ",n.project.name]}),e("p",{children:"Your account is ready. Open the board to see tasks, discuss work and review progress with your team."}),e("a",{class:"btn primary",href:`/#/team/project/${encodeURIComponent(a.projectId)}`,onClick:o=>{o.preventDefault(),location.reload()},children:"Open project board"}),S(a.user.roles[a.projectId],"contributor")?e("section",{class:"join-next",children:[e("h2",{children:"Want to run tasks on your computer?"}),e("ol",{children:[e("li",{children:"Open CodeFlow on the computer with your repository and signed-in coding agents."}),e("li",{children:"Choose Settings \u2192 Connections \u2192 Share access \u2192 Join a team."}),e("li",{children:"Paste the connection link below and sign in with the account you just used. Choose your local repository folder to start working."})]}),e("label",{children:["Your connection link",e("input",{class:"field mono",readOnly:!0,value:g(location.origin,a.user.username)})]}),e("button",{class:"btn",onClick:()=>void C(g(location.origin,a.user.username),"Connection link copied"),children:"Copy connection link"}),e("p",{class:"help",children:"The team server holds your shared board. Your computer runs the tasks you start there, using your own agent logins. This link contains no password or access token."})]}):null]}):e(u,{children:[e("h1",{children:n?`Join ${n.project.name}`:"Join a project"}),e("p",{class:"help",children:["Team server: ",e("code",{children:location.host})]}),n?e(u,{children:[e("p",{children:["You\u2019ll join as a ",e("b",{children:h(n.role)}),". ",h(n.role)," ",k[n.role],"."]}),e("p",{class:"help",children:["Access applies to ",n.project.name,". The owner manages any additional permission to run work or open terminals on the server."]}),e("form",{class:"shared-form",onSubmit:o=>void L(o),children:e("fieldset",{disabled:i,class:"team-setup-fields",children:[e("legend",{class:"sr-only",children:"Your account"}),e("label",{children:["Account option",e("select",{class:"field",value:r?"existing":"new",onChange:o=>{T(o.currentTarget.value==="existing"),d(""),s("")},children:[e("option",{value:"new",children:"Create my account"}),e("option",{value:"existing",children:"Sign in with an existing account"})]})]}),r?null:e("label",{children:["Your name",e("input",{class:"field",required:!0,maxLength:120,autoComplete:"name",value:f,onInput:o=>E(o.currentTarget.value)})]}),e("label",{children:["Username",e("input",{class:"field",required:!0,minLength:3,maxLength:64,autoComplete:"username",value:b,onInput:o=>x(o.currentTarget.value)})]}),e("label",{children:["Password",e("input",{class:"field",type:"password",required:!0,minLength:r?void 0:15,autoComplete:r?"current-password":"new-password",value:v,onInput:o=>d(o.currentTarget.value)})]}),r?null:e("p",{class:"help",children:"Choose at least 15 characters. Your teammates never see your password."}),e("button",{class:"btn primary",type:"submit",children:i?"Joining\u2026":"Join project"})]})})]}):i?e("p",{role:"status",children:"Checking your invitation\u2026"}):e("button",{class:"btn",onClick:()=>void w(),children:"Check invitation again"})]}),y?e("p",{class:"msg err",role:"alert",children:y}):null,a?null:e("p",{class:"help",children:["Already joined? ",e("a",{href:"/",children:"Sign in to your projects"}),". If the server is unreachable, connect to your team\u2019s Wi-Fi or Tailscale network and try again."]})]})})}export{P as JoinProject};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as k}from"./chunk-L7TUCIYF.js";import{I as Q,S as X,U as Z,Y as tt,Z as et,c as H,g as V,h as Y,i as q}from"./chunk-SIHDWM2Y.js";import"./chunk-APQEVJ2K.js";import"./chunk-2PZVOKID.js";import"./chunk-5SARP5MU.js";import{E as M,G as B,Ga as v,Jb as W,K as O,L as s,M as h,Ra as K,Wa as z,Yb as y,fc as _,hc as $,na as A,pc as J,rc as U,ub as N,vc as G,wa as D,xa as F,ya as I}from"./chunk-J4VYS3KV.js";import"./chunk-CGOZQMEZ.js";import"./chunk-4D5IENEB.js";import{a as x}from"./chunk-TEJVYIKC.js";import{D as w,F as j,G as P,H as d,L,Z as T,a as S,aa as C,d as E,da as o,g as n,h as R,i as b,o as p,r as u,w as g,y as m}from"./chunk-63YLZ3PR.js";var ot='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">%0A <circle cx="32" cy="32" r="30" fill="%231e1f1a" stroke="%233d4036" stroke-width="2"/>%0A <svg x="15" y="15" width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="%23ecebe4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">%0A <path d="M12 3l9 5-9 5-9-5zM3 13l9 5 9-5M3 17.5l9 5 9-5"/>%0A </svg>%0A</svg>%0A';var lt=Object.assign(document.createElement("link"),{rel:"icon",type:"image/svg+xml",href:ot});document.head.append(lt);H();window.addEventListener("hashchange",()=>{!m&&location.hash.startsWith("#/join/")&&location.reload()});var l=document.getElementById("root");l.addEventListener("click",e=>{if(e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;let r=e.target instanceof Element?e.target.closest(".md a[href]"):null;if(!r||!/^https?:\/\//i.test(r.href)||new URL(r.href).origin===location.origin)return;e.preventDefault();let i=s.value;K(r.href,i.view==="run"||i.view==="review"?i.id:void 0)});var rt=[1,2,5,10],it=0;function ct({message:e,seconds:r,onRetry:i}){let[a,c]=R(r);return b(()=>{if(a<=0)return i();let t=setTimeout(()=>c(a-1),1e3);return()=>clearTimeout(t)},[a]),o("div",{role:"alert",class:"boot-error",children:[o("h3",{children:"code-flow couldn't load"}),o("div",{class:"msg err",children:e}),o("p",{class:"help",children:a>0?`Trying again in ${a}s\u2026`:"Trying again\u2026"}),o("button",{class:"btn primary",disabled:a<=0,onClick:()=>c(0),children:"Retry now"}),m?o("a",{class:"btn",href:"/#/settings/connections/workspace",children:"Manage connections"}):null]})}async function at(){let e,r;try{if(location.hash.startsWith("#/join/")&&!m){let{JoinProject:nt}=await import("./join-project-6RTFHNCA.js");n(o(nt,{token:location.hash.slice(7)}),l);return}let t=await P("/api/auth/self");if(t.kind==="anonymous"){n(o(X,{}),l);return}if(t.kind==="shared"){n(o(E,{children:[o(Z,{identity:t}),o(Q,{})]}),l);return}await Y(),await j();let f=V.value.kind==="ssh"?await d("/api/auth/self"):t;x(f.streamSharing),[e,r]=await Promise.all([d("/api/agents"),d("/api/patterns")])}catch(t){let f=rt[Math.min(it,rt.length-1)];n(o(ct,{message:t.message,seconds:f,onRetry:()=>void at()},it++),l);return}M.value=e;for(let t of e)T[t.id]=t.displayName;B.value=r,O(),q(),s.value=h(),u(()=>{let t=g(s.value);w(t)&&(p(G),location.hash!==t&&!(t==="#/"&&!location.hash)&&(g(h(location.hash))===t?history.replaceState(null,"",t):history.pushState(null,"",t)))});let i=()=>{w(location.hash)&&(s.value=h())};window.addEventListener("popstate",i),window.addEventListener("hashchange",i),u(()=>{let t=s.value;!I.value||t.view!=="composer"||t.project===void 0||p(()=>{(t.project!==D.value||F.value)&&J(t.project,{stay:!0})})}),n(o(tt,{}),l),k(),z(),W(),N(),d("/api/templates").then(t=>$.value=t,t=>C(`Couldn't load the templates: ${t.message}`,5e3));let a=Promise.all([y(),v()]),c=L.get("repo");c&&await A(c,!1),await a,await U(),_(et),S(()=>Promise.all([y(),v()]),3e4)}at();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as T,y as L}from"./chunk-CGOZQMEZ.js";import{a as x,b as D,c as p}from"./chunk-4D5IENEB.js";import"./chunk-TEJVYIKC.js";import{G as I,H as C,N as P,ba as R,da as t,h as n,i as f}from"./chunk-63YLZ3PR.js";function Y({projects:r,projectId:s,prefix:y,address:j}){let u=(e,a)=>y!==void 0?I(y+e,a):C(e,a),[v,w]=n(s??r[0]?.id??""),[m,O]=n("contributor"),[E,H]=n([]),[d,U]=n(j??""),[b,l]=n(""),[i,h]=n(!1),[S,c]=n(""),[o,_]=n(null),[A,q]=n(Date.now());f(()=>{let e=setInterval(()=>q(Date.now()),3e4);return()=>clearInterval(e)},[]);let g=async()=>{try{let[e,a]=await Promise.all([u("/api/accounts/invitations"),u("/api/remote")]);H(e.invitations),U(a.enabled&&a.lan&&!a.lanError?L(a)??"":""),c("")}catch(e){c(e.message)}};f(()=>{g()},[y]),f(()=>{w(s??r[0]?.id??""),l("")},[s,r.map(e=>e.id).join(",")]);let F=async e=>{if(e.preventDefault(),!(i||!d||!v)){h(!0),c(""),l("");try{let a=await u("/api/accounts/invitations",{method:"POST",body:JSON.stringify({projectId:v,role:m})});_(a.invitation),l(`${d}/#/join/${a.token}`),await g()}catch(a){c(a.message)}finally{h(!1)}}},$=async e=>{h(!0),c("");try{await u(`/api/accounts/invitations/${P(e)}`,{method:"DELETE"}),o?.id===e&&l(""),await g()}catch(a){c(a.message)}finally{h(!1)}},k=E.filter(e=>(!s||e.projectId===s)&&!e.acceptedAt&&!e.revokedAt&&e.expiresAt>A);return t("section",{class:"settings-card project-invitations","aria-label":"Project invitations",children:[t("h3",{children:"Invite a teammate"}),t("p",{class:"help",children:"Share one link with one person. They choose their own password, or sign in with an existing account. Each invitation lasts 24 hours and can be used once."}),t("form",{class:"team-setup-fields",onSubmit:e=>void F(e),children:[t("label",{children:["Invite to project",t("select",{class:"field",value:v,disabled:i||!!s,onChange:e=>{w(e.currentTarget.value),l("")},children:[t("option",{value:"",disabled:!0,children:"Choose a project"}),r.filter(e=>!s||e.id===s).map(e=>t("option",{value:e.id,children:e.name},e.id))]})]}),t("label",{children:["Invitation role",t("select",{class:"field",value:m,disabled:i,onChange:e=>{O(e.currentTarget.value),l("")},children:x.map(e=>t("option",{value:e,children:p(e)},e))})]}),t("p",{class:"help",children:[p(m)," ",D[m],". Access applies only to this project. Server execution and terminals need separate owner grants."]}),d?t("p",{class:"help",children:["Team server: ",t("code",{children:d}),". Your teammate must be on the same Wi-Fi or permitted Tailscale network."]}):t("p",{class:"msg",role:"status",children:"Finish secure network access before inviting people. Use Host a team \u2192 Secure access, then refresh here."}),t("div",{class:"settings-actions",children:[t("button",{class:"btn primary",type:"submit",disabled:i||!d||!v,children:i?"Saving\u2026":"Create invitation"}),t("button",{class:"btn",type:"button",disabled:i,onClick:()=>void g(),children:"Refresh invitations"})]})]}),b&&o&&o.expiresAt>A&&!E.some(e=>e.id===o.id&&(e.acceptedAt||e.revokedAt))?t("div",{class:"invitation-result",role:"status",children:[t("b",{children:"Invitation ready"}),t("label",{children:["Invitation link",t("input",{class:"field mono",readOnly:!0,value:b})]}),t("div",{class:"phone-qr",children:[t(T,{text:b}),t("p",{class:"help",children:["For ",r.find(e=>e.id===o.projectId)?.name," \xB7 ",p(o.role),". Expires ",new Date(o.expiresAt).toLocaleString(),". Copy it now; this secret link cannot be recovered after leaving this page."]})]}),t("button",{class:"btn primary",onClick:()=>void R(b,"Invitation copied"),children:"Copy invitation link"})]}):null,k.length?t("details",{children:[t("summary",{children:["Pending invitations (",k.length,")"]}),t("ul",{class:"invitation-list",children:k.map(e=>t("li",{children:[t("span",{children:[r.find(a=>a.id===e.projectId)?.name??"Unavailable project"," \xB7 ",p(e.role),t("small",{class:"help",children:["Expires ",new Date(e.expiresAt).toLocaleString()]})]}),t("button",{class:"btn small",disabled:i,onClick:()=>void $(e.id),children:"Revoke invitation"})]},e.id))})]}):null,S?t("p",{class:"msg err",role:"alert",children:S}):null]})}export{Y as ProjectInvitations};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{a as Ge}from"./chunk-L7TUCIYF.js";import{A as Rt,C as It,D as Tt,E as xt,G as Dt,H as At,J as $t,T as jt,V as Nt,W as Lt,X as Ot,a as Xe,b as je,d as Ze,e as et,f as tt,g as Re,j as bt,n as Ue,o as oe,p as ft,q as gt,r as yt,s as he,t as wt,u as kt,v as Ct,w as St,x as Pt,z as Ie}from"./chunk-SIHDWM2Y.js";import"./chunk-APQEVJ2K.js";import{b as ge,c as Qe,e as te}from"./chunk-2PZVOKID.js";import{a as Be}from"./chunk-7FUHKF2M.js";import{a as Et}from"./chunk-5SARP5MU.js";import{Da as ot,E as ye,Eb as me,F as we,G as nt,H as st,Jb as Se,L as Ne,cb as ne,db as Le,dc as Pe,ec as Me,ga as at,ib as it,jc as ht,kb as rt,kc as vt,lb as pe,ma as Q,mb as ke,nb as lt,rb as ct,sa as _,tb as dt,ub as Ce,vb as ut,wb as Oe,xb as qe,yb as pt,zb as mt}from"./chunk-J4VYS3KV.js";import"./chunk-CGOZQMEZ.js";import"./chunk-4D5IENEB.js";import"./chunk-TEJVYIKC.js";import{H as D,J as O,L as ee,N,a as Ke,aa as J,d as T,da as e,h as o,i as $,j as Je,k as H,s as $e,t as Ye,x as ze}from"./chunk-63YLZ3PR.js";var Xt=Et(()=>import("./team-server-wizard-2GLDWS6D.js").then(t=>t.TeamServerWizard)),He=[{id:"workspace",label:"Work on another computer",description:"Open a complete workspace over SSH, with files, terminals and agents on that computer."},{id:"execution",label:"Delegate execution",description:"Send individual agent turns to a provisioned SSH worker while keeping this workspace here."},{id:"sharing",label:"Share access",description:"Open this computer from another device or collaborate with people."}];function qt({purpose:t="workspace"}){let u=["sharing","devices","join","host","manage"].includes(t),n=He.find(i=>i.id===(u?"sharing":t))??He[0],r=Re.value;return e("div",{class:"connections-hub",children:[e("nav",{class:"purpose-nav","aria-label":"Connection purpose",children:He.map(i=>e("a",{class:`btn ${n.id===i.id?"primary":""}`,href:`#/settings/connections/${i.id}`,"aria-current":n.id===i.id?"page":void 0,children:i.label}))}),e("p",{class:"help",children:n.description}),n.id==="workspace"?e(bt,{}):null,n.id==="execution"?e(T,{children:[e(Ct,{}),e("p",{class:"help",children:["To run shared tasks on a teammate\u2019s computer or grant host execution, configure ",e("a",{href:"#/settings/connections/manage",children:"Board and People under Share access"}),"."]})]}):null,n.id==="sharing"?e(T,{children:[e("nav",{class:"connection-journeys","aria-label":"Share access options",children:[{id:"devices",title:"Connect my devices",text:"Use your phone, tablet or another browser over Wi-Fi or Tailscale. Work stays on this computer."},{id:"join",title:"Join a team",text:"Open an invitation or connect to an existing team. Use your own account and local repositories."},{id:"host",title:"Host a team",text:"Set up a shared project on this computer or an SSH server, then invite your teammates."}].map(i=>e("a",{class:"connection-journey",href:`#/settings/connections/${i.id}`,"aria-current":t===i.id?"page":void 0,children:[e("b",{children:i.title}),e("span",{children:i.text}),e("span",{class:"connection-action",children:t===i.id?"Selected":"Get started \u2192"})]},i.id))}),t==="sharing"?e("section",{class:"settings-card",children:[e("h3",{children:"One project, a clear place to work"}),e("p",{children:"Connect your own devices to continue your work, or give teammates their own project access. A team server keeps tasks, reviews and handovers together; each person can connect their computer to run tasks with their own agents."}),e("p",{class:"help",children:"Wi-Fi works on the same local network. Tailscale connects permitted devices across networks. Keep the host awake and CodeFlow running."})]}):null,t==="devices"?r.kind==="local"?e(Be,{}):e("p",{class:"help",children:["Device access is configured on your local computer. ",r.kind==="ssh"?e("a",{href:"/#/settings/connections/devices",children:"Open local access settings"}):null]}):null,t==="join"?r.kind==="local"?e(Lt,{}):e("p",{class:"help",children:["Connect from CodeFlow on your own computer. ",e("a",{href:"/#/settings/connections/join",children:"Open local team connections"})]}):null,t==="host"&&r.kind!=="host"?e(Xt,{onClose:()=>{location.hash="#/settings/connections/sharing"}}):null,t==="host"&&r.kind==="host"?e("p",{class:"help",children:"Open CodeFlow on the server\u2019s owner computer to set up project access and invite teammates."}):null,e("a",{class:"btn small",href:"#/settings/connections/manage",children:"Manage existing connections and access"}),t==="manage"?e(T,{children:[r.kind==="local"?e(Be,{}):null,e("section",{class:"settings-card",children:[e("h3",{children:"People"}),e("p",{children:"Shared boards, reviews and handovers. Manage project membership in Project \u2192 More \u2192 People."}),e("label",{class:"checkpoint",children:[e("input",{type:"checkbox",checked:et.value,onChange:i=>tt(i.currentTarget.checked)}),e("span",{children:"Show Board in the app menu"})]}),e("p",{class:"help",children:"Show an unused Board shortcut in this browser. Configured collaboration remains visible; access is controlled by project roles and grants."})]}),e(T,{children:[e("a",{class:"btn",href:"#/team",children:r.kind==="ssh"?"Open computer board":"Open Board"}),e(Nt,{}),r.kind!=="ssh"?e(jt,{projects:_.value}):null]})]}):null]}):null]})}var Mt=[{id:"done",label:"Run finished"},{id:"failure",label:"Run or verification failed"},{id:"needs-attention",label:"A decision or answer is needed"}];function Ut(){let[t,u]=o([]),[n,r]=o([]),[i,v]=o(""),[y,w]=o(""),b=async()=>{let[s,f]=await Promise.all([D("/api/notifications"),D("/api/notifications/deliveries")]);u(s),r(f)};$(()=>{let s=!0,p=Ke(()=>Promise.all([D("/api/notifications"),D("/api/notifications/deliveries")]).then(([d,C])=>{s&&(u(d),r(C),v(""))},d=>{s&&v(d.message)}),1e4);return()=>{s=!1,p()}},[]);let l=async s=>{w(s.id);try{await O(`/api/notifications/deliveries/${s.id}/retry`),await b(),J("Notification retry queued")}catch(f){v(f.message)}finally{w("")}};return e("section",{class:"wb-card notifications-panel","aria-label":"Outbound notifications",children:[e("h2",{children:"Notifications"}),e("p",{children:"Choose a destination, the events to send and the projects it covers. Notifications include task titles, run IDs, workflow and result status."}),t.length?e("div",{class:"wb-list",children:t.map(s=>e(Zt,{destination:s,refresh:b},s.id))}):e("p",{class:"help",children:"Configure HTTPS webhook or Slack destinations with CODEFLOW_NOTIFICATIONS_FILE or CODEFLOW_NOTIFICATIONS_JSON on the server. New destinations start disabled."}),e("h3",{children:"Delivery history"}),e("p",{class:"help",children:"Keeps 200 deliveries. Temporary failures retry up to three times. A delivery interrupted by restart needs an explicit retry; the recipient may already have received it."}),n.length?e("div",{class:"table-wrap delivery-history",children:e("table",{class:"ins-table",children:[e("thead",{children:e("tr",{children:[e("th",{children:"Created"}),e("th",{children:"Destination"}),e("th",{children:"Event"}),e("th",{children:"Run"}),e("th",{children:"Status"}),e("th",{children:"Attempts"}),e("th",{children:"Action"})]})}),e("tbody",{children:n.map(s=>e("tr",{children:[e("td",{"data-label":"Created",children:new Date(s.createdAt).toLocaleString()}),e("td",{"data-label":"Destination",children:t.find(f=>f.id===s.target)?.name??s.target}),e("td",{"data-label":"Event",children:s.manual?"Manual test":Mt.find(f=>f.id===s.event)?.label??s.event}),e("td",{"data-label":"Run",children:s.teamId?e("a",{href:`#/project/${s.project}`,children:"Standing team"}):s.runId==="test"?"Test":e("a",{href:`#/run/${s.runId}`,children:s.runId})}),e("td",{"data-label":"Status",children:[e("span",{class:`badge${s.state==="delivered"?" ok":s.state==="failed"?" err":s.state==="sending"?" run":""}`,children:s.state.charAt(0).toUpperCase()+s.state.slice(1)}),s.httpStatus?` \xB7 HTTP ${s.httpStatus}`:"",s.reason?e("div",{class:"help",children:s.reason}):null,s.nextAttemptAt?e("div",{class:"help",children:["Next: ",new Date(s.nextAttemptAt).toLocaleTimeString()]}):null]}),e("td",{"data-label":"Attempts",children:[s.totalAttempts??s.attempts,s.retryCount?e("div",{class:"help",children:[s.retryCount," manual retries"]}):null]}),e("td",{"data-label":"Action",children:s.state==="failed"?e("button",{class:"btn small",disabled:!!y,onClick:()=>l(s),children:y===s.id?"Queuing\u2026":"Retry delivery"}):"\u2013"})]},s.id))})]})}):e("p",{class:"help",children:"No notifications have been queued."}),i?e("p",{class:"msg err",role:"alert",children:i}):null]})}function Zt({destination:t,refresh:u}){let[n,r]=o(t.settings),[i,v]=o(""),[y,w]=o("");$(()=>{r(t.settings)},[JSON.stringify(t.settings)]);let b=n.projects==="all"?[]:n.projects,l=[{id:"unassigned",name:"Without a project"},..._.value.map(p=>({id:p.id,name:p.name})),...b.filter(p=>p!=="unassigned"&&!_.value.some(d=>d.id===p)).map(p=>({id:p,name:`Unavailable project: ${p}`}))],s=async()=>{v("save"),w("");try{await O(`/api/notifications/${t.id}`,n),await u(),J("Notification settings saved")}catch(p){w(p.message)}finally{v("")}},f=async()=>{v("test"),w("");try{await O(`/api/notifications/${t.id}/test`),await u(),J("Test notification queued")}catch(p){w(p.message)}finally{v("")}};return e("article",{class:"wb-item notification-destination","aria-label":`Notification settings for ${t.name}`,children:[e("div",{class:"wb-item-head",children:[e("h3",{children:t.name}),e("span",{class:`badge${t.settings.enabled?" ok":""}`,children:t.settings.enabled?"Enabled":"Off"})]}),e("p",{class:"help",children:[t.protocol,t.host?` \xB7 ${t.host}`:""]}),t.available?t.configured?null:e("p",{class:"msg warn",children:"A valid HTTPS destination and its credentials are required on the server."}):e("p",{class:"msg err",children:"Saved notification state is unavailable. Check the server log before enabling delivery."}),e("label",{class:"check",children:[e("input",{type:"checkbox",checked:n.enabled,disabled:!t.available||!t.configured||!!i,onChange:p=>r({...n,enabled:p.currentTarget.checked})}),"Enable notifications to this destination"]}),e("fieldset",{disabled:!!i||!t.available,children:[e("legend",{children:"Events"}),Mt.map(p=>e("label",{class:"check",children:[e("input",{type:"checkbox",checked:n.events.includes(p.id),onChange:d=>r({...n,events:d.currentTarget.checked?[...n.events,p.id]:n.events.filter(C=>C!==p.id)})}),p.label]},p.id))]}),e("fieldset",{disabled:!!i||!t.available,children:[e("legend",{children:"Projects"}),e("label",{class:"check",children:[e("input",{type:"checkbox",checked:n.projects==="all",onChange:p=>r({...n,projects:p.currentTarget.checked?"all":[]})}),"All projects"]}),n.projects!=="all"?l.map(p=>e("label",{class:"check",children:[e("input",{type:"checkbox",checked:b.includes(p.id),onChange:d=>r({...n,projects:d.currentTarget.checked?[...b,p.id]:b.filter(C=>C!==p.id)})}),p.name]},p.id)):null]}),e("div",{class:"wb-actions",children:[e("button",{class:"btn primary",disabled:!!i||!t.available||n.enabled&&(!t.configured||!n.events.length||n.projects!=="all"&&!n.projects.length),onClick:s,children:i==="save"?"Saving\u2026":"Save notification settings"}),e("button",{class:"btn",disabled:!!i||!t.configured||!t.available,onClick:f,children:i==="test"?"Queuing\u2026":"Send test notification"})]}),t.dropped?e("p",{class:"msg warn",children:[t.dropped," events exceeded the queue limit."]}):null,t.lastError?e("p",{class:"msg warn",children:t.lastError}):null,y?e("p",{class:"msg err",role:"alert",children:y}):null]})}function Bt({onImport:t}){let[u,n]=o([]),[r,i]=o(""),[v,y]=o("issue"),[w,b]=o([]),[l,s]=o(),[f,p]=o(!1),[d,C]=o(""),[S,R]=o("");$(()=>{let h=!0;return D("/api/integrations").then(m=>{h&&(n(m),i(m[0]?.id??""))},m=>{h&&R(m.message)}),()=>{h=!1}},[]);let x=u.find(h=>h.id===r);$(()=>{b([]),s(void 0),p(!1),R(""),x&&!x.kinds.includes(v)&&y(x.kinds[0])},[r,v]);let A=async(h=!1)=>{if(!x)return;let m=r,P=v;C("list"),R("");try{let c=new URLSearchParams({kind:v});h&&l&&c.set("cursor",l);let k=await D(`/api/integrations/${encodeURIComponent(r)}/items?${c}`);m===r&&P===v&&(b(j=>[...new Map((h?[...j,...k.items]:k.items).map(q=>[`${q.kind}:${q.key}`,q])).values()]),s(k.nextCursor),p(k.truncated))}catch(c){R(c.message)}finally{C("")}},I=async h=>{C(h.key),R("");try{t(await O(`/api/integrations/${encodeURIComponent(r)}/import`,{kind:v,key:h.key}))}catch(m){R(m.message)}finally{C("")}};return e("section",{class:"wb-card sources-panel","aria-label":"External sources",children:[e("h2",{children:"External sources"}),e("p",{children:"Read issues and review requests from configured services, then attach a selected item to a task."}),e("p",{class:"help",children:"Imported text stays untrusted context. Review requests import descriptions and branch metadata; their code is not fetched automatically."}),u.length?e(T,{children:[e("div",{class:"wb-fields",children:[e("label",{children:["Integration",e("select",{class:"field","aria-label":"Source integration",value:r,disabled:!!d,onChange:h=>i(h.currentTarget.value),children:u.map(h=>e("option",{value:h.id,children:[h.name," \xB7 ",h.provider," \xB7 ",h.project]},h.id))})]}),e("label",{children:["Source type",e("select",{class:"field","aria-label":"External source type",value:v,disabled:!!d,onChange:h=>y(h.currentTarget.value),children:x?.kinds.map(h=>e("option",{value:h,children:h==="pr"?"Review requests":"Issues"},h))})]})]}),x?.configured?null:e("p",{class:"msg warn",children:"The server does not have credentials for this integration."}),e("button",{class:"btn",disabled:!x?.configured||!!d,onClick:()=>A(),children:d==="list"?"Loading\u2026":"Load sources"}),e("div",{class:"wb-list","aria-live":"polite",children:w.map(h=>e("article",{class:"wb-item source-item",children:[e("div",{class:"wb-item-head",children:[e("b",{children:[h.key," \xB7 ",h.title]}),h.state?e("span",{class:"badge",children:h.state.charAt(0).toUpperCase()+h.state.slice(1).toLowerCase()}):null]}),h.body?e("p",{class:"help",children:h.body.slice(0,400)}):null,e("div",{class:"wb-actions",children:[h.url?e("a",{class:"btn small",href:h.url,target:"_blank",rel:"noreferrer",children:"Open source"}):null,e("button",{class:"btn small primary",disabled:!!d,onClick:()=>I(h),children:d===h.key?"Importing\u2026":"Use as task context"})]})]},`${h.kind}:${h.key}`))}),l&&w.length<1e3?e("button",{class:"btn",disabled:!!d,onClick:()=>A(!0),children:"Load next page"}):null,f||l&&w.length>=1e3?e("p",{class:"help",children:"The listing reached its limit. Narrow the configured project or open the service to inspect additional items."}):null]}):e("p",{class:"help",children:"Configure sources with CODEFLOW_INTEGRATIONS_FILE or CODEFLOW_INTEGRATIONS_JSON on the server. Credentials come from server environment variables."}),S?e("p",{class:"msg err",role:"alert",children:S}):null]})}function Ht({projects:t=[]}){let[u,n]=o([]),[r,i]=o([]),[v,y]=o(""),[w,b]=o(""),[l,s]=o(""),[f,p]=o(""),[d,C]=o(),[S,R]=o(""),[x,A]=o(""),[I,h]=o(!1),[m,P]=o(""),[c,k]=o(""),[j,q]=o(""),[ie,z]=o("Review this pull request against its target; explain defects and make necessary fixes."),[X,V]=o(""),[re,F]=o("claude"),[L,Z]=o(""),[K,be]=o(""),[le,xe]=o(""),[ce,Ee]=o(""),[U,g]=o(),[E,De]=o(""),[fe,de]=o(""),[ae,zt]=o("main"),Ae=async()=>{let a=await D("/api/code-hosts");n(a.integrations),i(a.history),y(G=>G||a.integrations[0]?.id||"")};$(()=>{Ae().catch(a=>R(a.message))},[]);let M=async(a,G={})=>{if(!I){h(!0),R(""),A("");try{let B=await O(`/api/code-hosts/${a}`,G);a==="create-preview"?g(B):a.startsWith("history/")?A(B.detail):a==="preview"||a.endsWith("/fetch")?C(B):a.endsWith("/push-preview")?C(ue=>ue&&{...ue,push:B}):a.endsWith("/merge-preview")?C(ue=>ue&&{...ue,merge:B}):a.endsWith("/run")?(Z(B.id),A(`Review run started: ${B.id}`)):(A(B.detail??"Action confirmed. Refresh the provider preview before another action."),C(void 0),a.endsWith("/review")&&P(""),g(void 0)),await Ae()}catch(B){R(B.message)}finally{h(!1)}}},Ve=t.find(a=>a.id===f),W=!!d&&d.expiresAt<=Date.now();return e("section",{class:"wb-card code-hosts","aria-label":"GitLab and Bitbucket code hosts",children:[e("h2",{children:"GitLab and Bitbucket"}),e("p",{class:"help",children:"Fetch pinned PR code, inspect discussions, start an isolated review run and explicitly push a verified owned result. Merges validate the exact source plus target and use an atomic Git target lease. Direct push permission is required; PR closure is separate. Native queues and unsupported provider policies block merging."}),S?e("p",{class:"msg err",role:"alert",children:[S," Your draft is preserved. Unknown actions are never retried automatically."]}):null,x?e("p",{role:"status",children:x}):null,u.length?null:e("p",{class:"help",children:"Configure a GitLab or Bitbucket Cloud integration on the server using environment variable credential references. See docs/code-hosts.md."}),e("div",{class:"wb-fields",children:[e("label",{children:["Code host",e("select",{class:"field","aria-label":"Code host integration",value:v,onChange:a=>{y(a.currentTarget.value),C(void 0),g(void 0)},children:u.map(a=>e("option",{value:a.id,children:[a.name," \xB7 ",a.provider,a.configured?"":" \xB7 credentials unavailable"]},a.id))})]}),e("label",{children:["PR or merge request number",e("input",{class:"field","aria-label":"Code host PR number",inputMode:"numeric",value:w,onInput:a=>{b(a.currentTarget.value),C(void 0)}})]}),e("label",{children:["Project (optional)",e("select",{class:"field","aria-label":"Code host project",value:f,onChange:a=>{let G=a.currentTarget.value;p(G),s(t.find(B=>B.id===G)?.repos[0]??""),C(void 0)},children:[e("option",{value:"",children:"Standalone repository"}),t.map(a=>e("option",{value:a.id,children:a.name},a.id))]})]}),Ve?e("label",{children:["Local repository",e("select",{class:"field","aria-label":"Code host repository",value:l,onChange:a=>{s(a.currentTarget.value),C(void 0)},children:Ve.repos.map(a=>e("option",{value:a,children:a},a))})]}):e("label",{children:["Local Git repository",e("input",{class:"field","aria-label":"Code host repository",value:l,onInput:a=>{s(a.currentTarget.value),C(void 0)}})]})]}),e("div",{class:"wb-actions",children:e("button",{class:"btn small primary",disabled:I||!v||!w||!l,onClick:()=>M("preview",{integration:v,key:w,repo:l,...f?{project:f}:{}}),children:"Load pinned PR preview"})}),e("details",{children:[e("summary",{children:"Create a new PR from a verified owned result"}),e("label",{children:["Completed run ID",e("input",{class:"field","aria-label":"New PR owned run",value:L,onInput:a=>{Z(a.currentTarget.value),g(void 0)}})]}),e("label",{children:["Published result branch",e("input",{class:"field","aria-label":"New PR result branch",value:K,onInput:a=>{be(a.currentTarget.value),g(void 0)}})]}),e("label",{children:["Target branch",e("input",{class:"field","aria-label":"New PR target branch",value:ae,onInput:a=>{zt(a.currentTarget.value),g(void 0)}})]}),e("label",{children:["PR title",e("input",{class:"field","aria-label":"New PR title",maxLength:200,value:E,onInput:a=>{De(a.currentTarget.value),g(void 0)}})]}),e("label",{children:["PR body",e("textarea",{class:"field","aria-label":"New PR body",rows:4,maxLength:2e4,value:fe,onInput:a=>{de(a.currentTarget.value),g(void 0)}})]}),e("button",{class:"btn small",disabled:I||!v||!L||!K||!E.trim(),onClick:()=>M("create-preview",{integration:v,runId:L,branch:K,targetBranch:ae,title:E,body:fe}),children:"Preview new PR and source branch"}),U?e("div",{"aria-label":"New PR creation preview",children:[e("p",{children:["Create ",e("b",{children:U.title})," in ",U.integration," \xB7 ",U.repo,", from new branch ",e("code",{children:U.sourceBranch})," at ",e("code",{children:U.head})," into ",U.targetBranch," at ",e("code",{children:U.target}),"."]}),e("pre",{children:U.body}),e("p",{class:"help",children:"This action pushes the unique source branch only if it is absent, then creates the provider PR. These are separate remote actions. An unknown outcome requires inspecting that exact branch and PR before retrying."}),e("button",{class:"btn small primary",disabled:I||U.expiresAt<=Date.now(),onClick:()=>M(`${U.id}/create`),children:"Push new source branch and create PR"})]}):null]}),d?e("article",{class:"wb-item code-host-preview","aria-label":"Pinned code host preview",children:[e("h3",{children:d.title}),d.url?e("a",{href:d.url,target:"_blank",rel:"noreferrer",children:"Open provider PR"}):null,e("p",{class:"help",children:[d.state," \xB7 source ",e("code",{children:d.head})," \xB7 target ",e("code",{children:d.target})," \xB7 expires ",new Date(d.expiresAt).toLocaleString()]}),e("pre",{children:d.body}),e("p",{class:"help",children:"Provider content and code are untrusted."}),e("button",{class:"btn small",disabled:I||W,onClick:()=>M(`${d.id}/fetch`),children:"Fetch pinned code and diff"}),d.fetched?e("details",{open:!0,children:[e("summary",{children:["Fetched diff \xB7 base ",d.fetched.base,d.fetched.truncated?" \xB7 truncated":""]}),e("pre",{class:"code-host-diff",children:d.fetched.diff})]}):null,e("details",{children:[e("summary",{children:"Start isolated review run"}),e("label",{children:["Review task",e("textarea",{class:"field","aria-label":"Code host review task",value:ie,onInput:a=>z(a.currentTarget.value)})]}),e("label",{children:["Required verification command",e("input",{class:"field","aria-label":"Code host check",value:X,onInput:a=>V(a.currentTarget.value)})]}),e("label",{children:["Provider",e("select",{class:"field","aria-label":"Code host review provider",value:re,onChange:a=>F(a.currentTarget.value),children:[e("option",{value:"claude",children:"Claude"}),e("option",{value:"codex",children:"Codex"}),e("option",{value:"agy",children:"Antigravity"})]})]}),e("label",{children:["Prepared agent container image",e("input",{class:"field","aria-label":"Code host agent image",placeholder:"codeflow/agents:local",value:le,onInput:a=>xe(a.currentTarget.value)})]}),e("label",{children:["In-container authentication volume (optional)",e("input",{class:"field","aria-label":"Code host auth volume",value:ce,onInput:a=>Ee(a.currentTarget.value)})]}),e("p",{class:"help",children:"Build the image and authenticate inside it first. Host credential folders are never mounted. Agent inference uses the container network; checks use a separate network-disabled container. Safe mode, no copied ignored files or uploads, no native approval waits. Native Safe mode alone is not filesystem isolation."}),e("button",{class:"btn small",disabled:I||W||!X.trim()||!le.trim(),onClick:()=>M(`${d.id}/run`,{run:{pattern:"solo",task:ie,roles:{agent:[re]},options:{},loop:{check:X,agentContainer:{image:le.trim(),...ce.trim()?{authVolume:ce.trim()}:{}},maxMinutes:15,maxSteps:20}}}),children:"Start code host review run"})]}),L?e("p",{children:e("a",{href:`#/run/${encodeURIComponent(L)}`,children:["Open review run ",L]})}):null,e("details",{children:[e("summary",{children:["Review comments and discussions \xB7 ",d.discussions.length,d.discussionTruncated?" \xB7 incomplete, refresh provider UI for remaining discussion":""]}),e("label",{children:["Review comment",e("textarea",{class:"field","aria-label":"Code host review comment",rows:4,maxLength:2e4,value:m,onInput:a=>P(a.currentTarget.value)})]}),e("label",{children:["Inline new-file path (optional)",e("input",{class:"field","aria-label":"Code host inline path",value:c,onInput:a=>k(a.currentTarget.value)})]}),e("label",{children:["New-file line",e("input",{class:"field","aria-label":"Code host inline line",inputMode:"numeric",value:j,onInput:a=>q(a.currentTarget.value)})]}),e("button",{class:"btn small",disabled:I||W||!m.trim(),onClick:()=>M(`${d.id}/review`,{action:"comment",body:m,...c?{path:c,line:Number(j)}:{}}),children:"Publish commit-scoped review comment"}),d.provider==="gitlab"?e(T,{children:[e("button",{class:"btn small",disabled:I||W,onClick:()=>M(`${d.id}/review`,{action:"approve"}),children:"Approve exact GitLab source commit"}),e("button",{class:"btn small",disabled:I||W,onClick:()=>M(`${d.id}/review`,{action:"unapprove"}),children:"Remove my GitLab approval"})]}):e("p",{class:"help",children:"Bitbucket approvals lack a commit precondition. Use commit-scoped comments here or approve in the provider UI."}),d.discussions.map(a=>e("section",{class:"code-host-discussion",children:[e("p",{children:[a.path??"General discussion",a.line?`:${a.line}`:""," \xB7 ",a.resolved?"resolved":"open"]}),a.comments.map(G=>e("blockquote",{children:[e("b",{children:G.author}),e("p",{class:"code-host-comment",children:G.body})]},G.id)),e("button",{class:"btn small",disabled:I||W||!m.trim()||d.discussionTruncated,onClick:()=>M(`${d.id}/review`,{action:"reply",body:m,discussionId:a.id,revision:a.revision}),children:["Publish reply to ",a.id]}),a.canResolve?e("button",{class:"btn small",disabled:I||W||d.discussionTruncated,onClick:()=>M(`${d.id}/review`,{action:a.resolved?"reopen":"resolve",discussionId:a.id,revision:a.revision}),children:[a.resolved?"Reopen":"Resolve"," discussion ",a.id]}):null]},a.id))]}),e("details",{children:[e("summary",{children:"Push or merge a verified owned result"}),e("label",{children:["Completed review run ID",e("input",{class:"field","aria-label":"Code host owned run",value:L,onInput:a=>Z(a.currentTarget.value)})]}),e("label",{children:["Published result branch",e("input",{class:"field","aria-label":"Code host result branch",value:K,onInput:a=>be(a.currentTarget.value)})]}),e("button",{class:"btn small",disabled:I||W||!L||!K,onClick:()=>M(`${d.id}/push-preview`,{runId:L,branch:K}),children:"Preview exact result push"}),d.push?e("p",{children:["Push commit ",e("code",{children:d.push.commit})," to ",d.sourceBranch,", only if its current head remains ",e("code",{children:d.push.expected}),". ",e("button",{class:"btn small primary",disabled:I||W,onClick:()=>M(`${d.id}/push`,{planId:d.push.id}),children:"Push this pinned result"})]}):null,d.policy.allowed?e("p",{class:"help",children:"Provider policy permits previewing a pinned Git merge. Required checks are revalidated before the explicit action."}):e("ul",{children:d.policy.reasons.map(a=>e("li",{children:a},a))}),e("button",{class:"btn small",disabled:I||W||!L||!K||!d.policy.allowed,onClick:()=>M(`${d.id}/merge-preview`,{runId:L,branch:K}),children:"Validate exact source and target merge"}),d.merge?e("p",{children:["Validated source ",e("code",{children:d.merge.source})," + target ",e("code",{children:d.merge.target})," \u2192 tree ",e("code",{children:d.merge.tree}),". ",e("button",{class:"btn small primary",disabled:I||W,onClick:()=>M(`${d.id}/merge`,{planId:d.merge.id}),children:"Push pinned Git merge to target"})]}):null]})]}):null,e("details",{children:[e("summary",{children:["Explicit action history \xB7 ",r.length]}),e("button",{class:"btn small",disabled:I,onClick:()=>void Ae().catch(a=>R(a.message)),children:"Refresh code host history"}),e("ul",{children:r.map(a=>e("li",{children:[new Date(a.at).toLocaleString()," \xB7 ",a.integration," #",a.key," \xB7 ",a.kind,": ",a.status," \xB7 ",a.detail,a.commit?e(T,{children:[" \xB7 ",e("code",{children:a.commit})]}):null,a.sourceBranch?e(T,{children:[" \xB7 ",e("code",{children:a.sourceBranch})]}):null,a.target?e(T,{children:[" \xB7 observed target ",e("code",{children:a.target})]}):null,a.runId?e("a",{href:`#/run/${encodeURIComponent(a.runId)}`,children:[" \xB7 run ",a.runId]}):null,a.status==="unknown"?e("button",{class:"btn small",disabled:I,onClick:()=>M(`history/${a.id}/acknowledge`,{acknowledge:!0}),children:"I inspected this exact outcome; record manual inspection"}):null]},a.id))})]})]})}function Ft({projectId:t,repos:u}){let[n,r]=o(null),[i,v]=o(""),[y,w]=o(""),[b,l]=o(""),[s,f]=o(null),[p,d]=o(null),[C,S]=o(u[0]??""),[R,x]=o(null),[A,I]=o(null),[h,m]=o(""),[P,c]=o(""),[k,j]=o(!1),q=H(null),ie=H(null),z=H(0),X=H(0),V=`/api/projects/${N(t)}/conventions`,re=new TextEncoder().encode(i).length,F=!!n&&i!==n.text;$(()=>{let g=++z.current;return++X.current,r(null),v(""),w(""),f(null),d(null),x(null),I(null),j(!1),c(""),m("load"),S(u[0]??""),D(V).then(E=>{g===z.current&&(r(E),v(E.text),l(String(E.history[0]?.revision??"")),m(""))},E=>{g===z.current&&(c(E.message),m(""))}),()=>{z.current++,X.current++}},[t]),$(()=>{u.includes(C)||(S(u[0]??""),x(null),I(null))},[JSON.stringify(u)]),$(()=>{if(!F)return;let g=E=>{E.preventDefault(),E.returnValue=""};return window.addEventListener("beforeunload",g),()=>window.removeEventListener("beforeunload",g)},[F]),$(()=>{A&&!h&&ie.current?.focus()},[A,h]);let L=async(g,E)=>{if(h)return;let De=z.current,fe=++X.current;m(g),c("");let de=()=>De===z.current&&fe===X.current;try{await E(de)}catch(ae){de()&&(c(ae.message),ae instanceof ze&&ae.status===409&&["save","restore"].includes(g)&&j(!0),g==="publish"&&x(null))}finally{de()&&m("")}},Z=g=>{r(g),v(g.text),w(""),f(null),d(null),j(!1),l(String(g.revision)),x(null),I(null)},K=()=>L("save",async g=>{let E=await D(V,{method:"PUT",body:JSON.stringify({revision:n.revision,text:i,note:y})});g()&&(Z(E),J(`Saved private conventions revision ${E.revision}`),requestAnimationFrame(()=>{g()&&q.current?.focus()}))}),be=()=>L("compare",async g=>{let E=await D(V);g()&&d(E)}),le=()=>L("preview",async g=>{let E=await O(V+"/restore-preview",{version:Number(b)});g()&&f(E)}),xe=()=>L("restore",async g=>{let E=await O(V+"/restore",s);g()&&(Z(E),J(`Restored as new revision ${E.revision}`),requestAnimationFrame(()=>{g()&&q.current?.focus()}))}),ce=()=>L("inspect",async g=>{x(null);let E=await D(V+`/publication?repo=${N(C)}`);g()&&(x(E),I(null))}),Ee=()=>L("publish",async g=>{let E=await O(V+"/publish",{repo:C,revision:n.revision,sourceHash:R.sourceHash,head:R.head});g()&&(I(E),x(null),J("Conventions file staged; commit it to activate guidance",5e3))}),U=()=>{let g=URL.createObjectURL(new Blob([i],{type:"text/markdown;charset=utf-8"})),E=window.document.createElement("a");E.href=g,E.download="conventions-draft.md",E.click(),setTimeout(()=>URL.revokeObjectURL(g),1e3)};return e("section",{class:"wb-card project-conventions","aria-label":"Versioned project conventions",children:[e("h2",{children:"Project conventions"}),e("p",{class:"help",children:"Save shared guidance privately, review prior versions, then deliberately publish a saved revision to a project repository. Agents read only the committed repository file; private drafts and imported run text are never activated automatically."}),!n&&h?e("p",{role:"status",children:"Loading private conventions\u2026"}):null,n?e(T,{children:[e("label",{class:"lbl",for:`conventions-text-${N(t)}`,children:"Private conventions draft"}),e("textarea",{ref:q,id:`conventions-text-${N(t)}`,class:"field",value:i,disabled:!!h,onInput:g=>v(g.currentTarget.value),placeholder:"Describe coding, review, and verification conventions for this project."}),e("p",{class:"help",children:["Saved revision ",n.revision," \xB7 ",re.toLocaleString()," / 65,536 UTF-8 bytes",F?" \xB7 unsaved changes":"",". The latest 32 revisions are retained."]}),e("label",{class:"lbl",for:`conventions-note-${N(t)}`,children:"Revision note"}),e("input",{id:`conventions-note-${N(t)}`,class:"field",value:y,maxLength:500,disabled:!!h,onInput:g=>w(g.currentTarget.value),placeholder:"Why should this guidance change?"}),e("div",{class:"convention-actions",children:[e("button",{class:"btn primary",disabled:!!h||re>65536||!F&&!y.trim(),onClick:K,children:h==="save"?"Saving\u2026":"Save private revision"}),e("button",{class:"btn",disabled:!!h,onClick:U,children:"Export draft"}),F?e("button",{class:"btn",disabled:!!h,onClick:()=>{v(n.text),w("")},children:"Revert to saved draft"}):null]}),k?e("div",{class:"msg warn",children:[e("p",{children:"Your draft is preserved. Review the latest saved guidance before applying it."}),e("button",{class:"btn",disabled:!!h,onClick:be,children:"Compare latest revision"})]}):null,p?e("div",{children:[e("div",{class:"convention-compare",children:[e("div",{children:[e("h3",{children:["Latest saved revision ",p.revision]}),e("pre",{children:p.text||"Empty guidance"})]}),e("div",{children:[e("h3",{children:"Your draft"}),e("pre",{children:i||"Empty guidance"})]})]}),e("button",{class:"btn",disabled:!!h,onClick:()=>{r(p),d(null),j(!1),x(null),f(null),requestAnimationFrame(()=>q.current?.focus())},children:"Use latest revision as base and keep my draft"})]}):null,e("details",{children:[e("summary",{children:["Revision history (",n.history.length,")"]}),n.history.length?e(T,{children:[e("label",{class:"lbl",for:`conventions-version-${N(t)}`,children:"Saved conventions version"}),e("select",{id:`conventions-version-${N(t)}`,class:"field",value:b,disabled:!!h,onChange:g=>{l(g.currentTarget.value),f(null)},children:n.history.map(g=>e("option",{value:g.revision,children:["Revision ",g.revision," \xB7 ",new Date(g.at).toLocaleString(),g.note?` \xB7 ${g.note}`:""]},g.revision))}),e("div",{class:"convention-actions",children:e("button",{class:"btn",disabled:!!h||!b,onClick:le,children:"Preview saved revision"})}),s?e("div",{children:[e("h3",{children:["Preview revision ",s.version]}),e("pre",{children:s.text||"Empty guidance"}),e("p",{class:"help",children:["Restoring creates a new private revision. It does not publish or remove the current saved version.",F?" Save or revert your unsaved draft first.":""]}),e("button",{class:"btn",disabled:!!h||F||s.revision!==n.revision,onClick:xe,children:"Restore as new revision"})]}):null]}):e("p",{class:"help",children:"Save the first revision to start a history."})]}),e("h3",{class:"convention-publish",children:"Publish reviewed guidance"}),e("p",{class:"help",children:["Publishing writes and stages ",e("code",{children:".codeflow/conventions.md"}),". Commit the staged file yourself to activate guidance for future runs. The repository must belong to this project, be clean, and have no active code-flow work."]}),e("label",{class:"lbl",for:`conventions-repo-${N(t)}`,children:"Publish conventions to repository"}),e("select",{id:`conventions-repo-${N(t)}`,class:"field",value:C,disabled:!!h,onChange:g=>{S(g.currentTarget.value),x(null),I(null)},children:u.length?u.map(g=>e("option",{value:g,children:g},g)):e("option",{value:"",children:"This project has no repositories"})}),e("div",{class:"convention-actions",children:e("button",{class:"btn",disabled:!!h||!C||!n.revision,onClick:ce,children:h==="inspect"?"Inspecting\u2026":"Inspect repository file"})}),R?e("div",{children:[e("p",{class:"help",children:[R.clean?"Repository is clean":"Repository has changes; commit or save them before publishing"," \xB7 ",R.branch??"Detached HEAD"," \xB7 ",R.head.slice(0,12)," \xB7 ",R.tracked?"File is tracked":R.exists?"File exists outside tracking":"File will be created"]}),e("div",{class:"convention-compare",children:[e("div",{children:[e("h4",{children:"Current repository file"}),e("pre",{children:R.text||"No repository guidance"})]}),e("div",{children:[e("h4",{children:["Saved private revision ",n.revision]}),e("pre",{children:n.text||"Empty guidance"})]})]}),e("button",{class:"btn primary",disabled:!!h||F||!R.clean,onClick:Ee,children:h==="publish"?"Publishing\u2026":"Publish and stage file"}),F?e("p",{class:"help",children:"Save or revert your unsaved draft before publishing a saved revision."}):null]}):null,A?e("p",{class:"msg ok",role:"status",ref:ie,tabIndex:-1,children:["Revision ",A.revision," was staged at ",A.path,". Commit the file in the repository to activate it for future runs."]}):null]}):h?null:e("button",{class:"btn",onClick:()=>{L("reload",async g=>{let E=await D(V);g()&&Z(E)})},children:"Retry loading conventions"}),P?e("p",{class:"msg err",role:"alert",children:P}):null]})}function Wt({projectId:t,projectName:u}){let[n,r]=o(null),[i,v]=o("."),[y,w]=o(""),[b,l]=o("."),[s,f]=o(""),[p,d]=o(!1),[C,S]=o(""),[R,x]=o(""),A=H(0),I=H(t);I.current=t;let h=c=>{v(c.read.allow.join(`
|
|
2
|
+
`)),w(c.read.deny.join(`
|
|
3
|
+
`)),l(c.write.allow.join(`
|
|
4
|
+
`)),f(c.write.deny.join(`
|
|
5
|
+
`))},m=async c=>{let k=++A.current;d(!0),S("");try{let j=await D(`/api/projects/${N(t)}/filesystem-policy`);if(k!==A.current)return;r(j),c?h(j):x("Latest saved revision loaded; your draft is kept. Compare the saved rules before applying it.")}catch(j){k===A.current&&S(j.message)}finally{k===A.current&&d(!1)}};$(()=>(r(null),x(""),m(!0),()=>{A.current++}),[t]);let P=c=>c.split(/\r?\n/).map(k=>k.trim()).filter(Boolean);return e("section",{class:"wb-card filesystem-policy","aria-label":"Project filesystem policy",children:[e("h2",{children:["Filesystem policy",u?` \xB7 ${u}`:""]}),e("p",{class:"help",children:["Allow and deny literal repository paths, one per line. A path covers its directory descendants. Use ",e("code",{children:"."})," for the repository root; an empty allow list denies every path. Deny rules take precedence. Git internals, credential paths and symbolic escapes stay blocked in application file operations."]}),e("p",{class:"help",children:"Any custom restriction pauses all app-managed agent, terminal, setup, checks and service execution across projects because the current host, Docker and SSH backends cannot enforce a filtered filesystem boundary. Close terminals/services and wait for all executions and unresolved remote receipts to finish before applying a policy. Existing runs retain their pinned restrictions; start a new run after deliberately changing policy. Extensions are deferred on restricted startup; clearing policy requires a restart to load them."}),e("form",{onSubmit:async c=>{if(c.preventDefault(),!n||p)return;let k=t,j=++A.current;d(!0),S(""),x("");try{let q=await D(`/api/projects/${N(t)}/filesystem-policy`,{method:"PUT",body:JSON.stringify({revision:n.revision,read:{allow:P(i),deny:P(y)},write:{allow:P(b),deny:P(s)}})});if(k!==I.current||j!==A.current)return;r(q),h(q),x(`Filesystem policy revision ${q.revision} applied.`)}catch(q){k===I.current&&j===A.current&&S(q.message)}finally{k===I.current&&j===A.current&&d(!1)}},children:[e("fieldset",{disabled:p||!n,children:[e("legend",{children:"Project file access"}),e("div",{class:"filesystem-policy-grid",children:[e("label",{children:["Read allow paths",e("textarea",{class:"field",rows:4,value:i,onInput:c=>v(c.currentTarget.value)})]}),e("label",{children:["Read deny paths",e("textarea",{class:"field",rows:4,value:y,onInput:c=>w(c.currentTarget.value)})]}),e("label",{children:["Write allow paths",e("textarea",{class:"field",rows:4,value:b,onInput:c=>l(c.currentTarget.value)})]}),e("label",{children:["Write deny paths",e("textarea",{class:"field",rows:4,value:s,onInput:c=>f(c.currentTarget.value)})]})]})]}),e("div",{class:"filesystem-policy-actions",children:[e("button",{class:"btn primary",disabled:p||!n,type:"submit",children:p?"Applying\u2026":"Stop execution and apply policy"}),e("button",{class:"btn",type:"button",disabled:p,onClick:()=>void m(!1),children:"Reload saved policy and keep draft"}),e("button",{class:"btn",type:"button",disabled:p||!n,onClick:()=>{n&&h(n),x("Draft replaced with the saved policy.")},children:"Use saved policy"})]})]}),n?e("details",{children:[e("summary",{children:["Saved revision ",n.revision," \xB7 ",n.hash.slice(0,12)]}),e("pre",{class:"filesystem-policy-saved",children:JSON.stringify({read:n.read,write:n.write},null,2)})]}):null,C?e("p",{class:"msg err",role:"alert",children:[C," Your draft is kept."]}):null,R?e("p",{class:"help",role:"status",children:R}):null]})}function _t(){let[t,u]=o(),[n,r]=o("");return $(()=>{let i=!0;return D("/api/extensions").then(v=>{i&&u(v)},v=>{i&&r(v.message)}),()=>{i=!1}},[]),e("section",{class:"wb-card extensions-panel","aria-label":"Provider and workflow extensions",children:[e("h2",{children:"Provider and workflow extensions"}),e("p",{children:"Load explicitly configured, SHA-256 pinned local JavaScript bundles with API version negotiation. Loaded providers appear in team selection; workflows appear in New run."}),e("p",{class:"help",children:"Extensions are trusted server code with the server owner's permissions. Configure CODEFLOW_EXTENSIONS_FILE and restart after reviewing each bundle. Repository files cannot enable extensions. See docs/extensions.md for the contract and configuration example."}),t?e(T,{children:[e("dl",{class:"wb-kv",children:[e("dt",{children:"Host extension API"}),e("dd",{children:[t.api.major,".",t.api.minor]})]}),t.extensions.length?e("div",{class:"wb-list",children:t.extensions.map(i=>e("article",{class:"wb-item",children:[e("div",{class:"wb-item-head",children:[e("h3",{children:[i.id," ",i.version]}),e("span",{class:`badge ${i.error||i.state!=="loaded"?"err":"ok"}`,children:i.state.charAt(0).toUpperCase()+i.state.slice(1)})]}),e("dl",{class:"wb-kv",children:[e("dt",{children:"SHA-256"}),e("dd",{children:e("code",{children:i.sha256})}),i.api?e(T,{children:[e("dt",{children:"Negotiated API"}),e("dd",{children:[i.api.major,".",i.api.minor]})]}):null,e("dt",{children:"Providers"}),e("dd",{children:i.providers.join(", ")||"None"}),e("dt",{children:"Workflows"}),e("dd",{children:i.workflows.join(", ")||"None"})]}),i.error?e("p",{class:"msg err",role:"alert",children:i.error}):null]},i.id))}):e("p",{class:"help",children:"No extensions configured."})]}):null,n?e("p",{role:"alert",class:"msg err",children:n}):null]})}function Fe({projectId:t,repositories:u}){let[n,r]=o(""),i=u.includes(n)?n:u.includes(Q.value)?Q.value:u[0]??"",[v,y]=o("project"),w=t&&v==="project"?`composerLibrary:${t}`:"composerLibrary";return e("section",{class:"project-run-settings","aria-label":"Project run defaults",children:[e("h2",{children:"Run defaults"}),e("p",{class:"help",children:"Configure each repository once. New runs inherit these defaults; run options can override them. These preferences are saved in this browser for the current workspace."}),u.length>1?e("label",{class:"lbl",children:["Repository",e("select",{class:"field","aria-label":"Project settings repository",value:i,onChange:b=>r(b.currentTarget.value),children:u.map(b=>e("option",{value:b,children:b},b))})]}):null,i?e(en,{repository:i},i):e("p",{class:"help",children:"Add a repository to configure its defaults."}),Le.value?e(T,{children:[e("h2",{children:"Template library"}),e("p",{class:"help",children:"Use the Template library in New run for built-in tasks, saved workflows and complete run templates. Manage imports and older workflow revisions below."}),t?e("label",{class:"lbl",children:["Library",e("select",{class:"field","aria-label":"Library scope",value:v,onChange:b=>y(b.currentTarget.value),children:[e("option",{value:"project",children:"This project"}),e("option",{value:"personal",children:"Personal library (all projects)"})]})]}):null,e(kt,{libraryKey:w,p:Le.value},w)]}):null,t&&i?e($t,{projectId:t,repo:i},`${t}:${i}`):null]})}function en({repository:t}){let[u,n]=o(()=>St(t)),[r,i]=o({check:"",setup:""}),[v,y]=o(!0),[w,b]=o(""),[l,s]=o(!1),[f,p]=o(0);$(()=>{let S=!0;return y(!0),b(""),Promise.all([D(`/api/repo-config?repo=${N(t)}`),D(`/api/check?repo=${N(t)}`)]).then(([R,x])=>{S&&i({check:ee.get(`check:${t}`)??R.config.check??x.command??"",setup:ee.get(`setup:${t}`)??R.config.setup??x.setup??""})}).catch(R=>{S&&(i({check:ee.get(`check:${t}`)??"",setup:ee.get(`setup:${t}`)??""}),b(`Could not load repository defaults: ${R.message}`))}).finally(()=>{S&&y(!1)}),()=>{S=!1}},[t,f]);let d=S=>{n(S),s(!1)},C=()=>{ee.set(`check:${t}`,r.check),ee.set(`setup:${t}`,r.setup),Q.value===t&&(it.value=r.check,rt.value=r.setup),Pt(t,u),s(!0)};return e("div",{class:"project-default-fields",children:[e("p",{class:"help mono",children:t}),e("label",{class:"lbl",children:["Default check command",e("input",{class:"field mono","aria-label":"Default check command",disabled:v,value:r.check,placeholder:"e.g. npm test",onInput:S=>{i({...r,check:S.currentTarget.value}),s(!1)}})]}),e("label",{class:"lbl",children:["Worktree setup command",e("input",{class:"field mono","aria-label":"Worktree setup command",disabled:v,value:r.setup,placeholder:"e.g. npm ci",onInput:S=>{i({...r,setup:S.currentTarget.value}),s(!1)}})]}),e("label",{class:"lbl",children:["Default verification profile",e("select",{class:"field","aria-label":"Default verification profile",value:u.verification,onChange:S=>d({...u,verification:S.currentTarget.value}),children:[e("option",{value:"",children:"Single configured check"}),e("option",{value:"lightweight",children:"Lightweight"}),e("option",{value:"standard",children:"Standard"}),e("option",{value:"thorough",children:"Thorough"})]})]}),e("label",{class:"checkpoint",children:[e("input",{type:"checkbox",checked:u.container.enabled,onChange:S=>d({...u,container:{...u.container,enabled:S.currentTarget.checked}})}),e("span",{children:"Use Docker isolation by default"})]}),u.container.enabled?e(T,{children:[e("label",{class:"lbl",children:["Default container image",e("input",{class:"field mono","aria-label":"Default container image",value:u.container.image,onInput:S=>d({...u,container:{...u.container,image:S.currentTarget.value}})})]}),e("label",{class:"lbl",children:["Default authentication volume",e("input",{class:"field mono","aria-label":"Default authentication volume",value:u.container.authVolume,onInput:S=>d({...u,container:{...u.container,authVolume:S.currentTarget.value}})})]}),e("p",{class:"help",children:"Use a prebuilt image with compatible, authenticated provider CLIs. Host credentials are not mounted."})]}):null,e("div",{class:"settings-actions",children:[e("button",{class:"btn primary",disabled:v||!!w||u.container.enabled&&!u.container.image.trim(),onClick:C,children:"Save project defaults"}),l?e("span",{role:"status",children:"Project defaults saved."}):null]}),w?e("div",{class:"msg err",role:"alert",children:[w,e("button",{class:"btn",onClick:()=>p(f+1),children:"Retry loading defaults"})]}):null,e(wt,{repository:t,setup:r.setup,check:r.check,base:"",loading:v})]})}function Vt(){let[t,u]=o(null),[n,r]=o(""),[i,v]=o(!1),y=H(0),w=async()=>{let l=++y.current;v(!0),r("");try{let s=await D("/api/doctor/dependencies");l===y.current&&u(s)}catch(s){l===y.current&&r(s.message)}finally{l===y.current&&v(!1)}},b=t?.providers.filter(l=>l.installed&&l.compatible===!0&&l.signedIn===!0)??[];return e("section",{"aria-label":"Guided dependency discovery",class:"dependency-discovery",children:[e("h3",{children:"Check this computer"}),e("p",{class:"help",children:"Git and one compatible, signed-in provider are needed to run a team. Python terminals, browser snapshots and Docker isolation are optional. These checks read installed tools; they do not install software, sign in, pull images or change settings."}),e("button",{class:"btn",disabled:i,onClick:w,children:i?"Checking dependencies\u2026":t?"Check dependencies again":"Check all dependencies"}),n?e("p",{class:"msg err",role:"alert",children:n}):null,t?e("div",{class:"dependency-results",children:[e("p",{role:"status",children:[t.node.ok&&t.git.ok&&b.length?"Core tools are ready.":"Core tools need attention."," Checked ",new Date(t.checkedAt).toLocaleTimeString(),"."]}),e("h4",{children:"Required tools"}),e("ul",{class:"readiness-results",children:[e("li",{children:[e("span",{class:`badge ${t.node.ok?"ok":"err"}`,children:t.node.ok?"Ready":"Too old"}),e("span",{children:[e("b",{children:["Node.js ",t.node.version]}),t.node.ok?null:e("span",{class:"help",children:"Run code-flow with Node.js 22.13 or newer."})]})]}),e("li",{children:[e("span",{class:`badge ${t.git.ok?"ok":"err"}`,children:t.git.ok?"Ready":t.git.installed?"Too old":"Missing"}),e("span",{children:[e("b",{children:["Git ",t.git.version??""]}),t.git.warning?e("span",{class:"help",children:t.git.warning}):null]})]}),t.providers.map(l=>e("li",{children:[e("span",{class:`badge ${l.installed&&l.signedIn===!0&&l.compatible===!0?"ok":l.installed&&(l.compatible===!1||l.signedIn===!1)?"warn":""}`,children:l.installed?l.compatible===!1?"Incompatible":l.signedIn===!1?"Signed out":l.signedIn===null||l.compatible===void 0?"Unknown":"Ready":"Missing"}),e("span",{children:[e("b",{children:[l.name,l.version?` \xB7 ${l.version}`:""]}),l.fix?e("span",{class:"help",children:l.fix}):null,l.warnings?.map(s=>e("span",{class:"help",children:s},s))]})]},l.id))]}),e("h4",{children:"Optional tools"}),e("ul",{class:"readiness-results",children:t.optional.map(l=>e("li",{children:[e("span",{class:`badge ${l.ready?"ok":""}`,children:l.ready?"Ready":l.installed?"Unavailable":"Not installed"}),e("span",{children:[e("b",{children:[l.name,l.version?` \xB7 ${l.version}`:""]}),e("span",{class:"help",children:l.detail}),l.fix?e("span",{class:"help",children:l.fix}):null]})]},l.id))})]}):null]})}function Kt(){let t=yt.value,u=(n,r,i)=>{let v=t.providers;he({...t,providers:{...v,[n]:{...v[n],[r]:{...v[n]?.[r],...i}}}})};return e("section",{class:"settings-card","aria-label":"Prompt improvement",children:[e("h3",{children:"Prompt improvement"}),e("p",{class:"help",children:"Improve rewrites your task before you run it. It preserves your intent, clarifies the goal and completion criteria, and flags unclear details. Undo restores your original text."}),e("div",{class:"settings-row",children:[e("div",{children:[e("strong",{children:"Agent"}),e("p",{children:"Independent of your main task\u2019s agents. Uses your local CLI account and subscription."})]}),e("div",{class:"settings-row-control",children:e("select",{class:"field","aria-label":"Prompt improvement agent",value:t.agent,onChange:n=>he({...t,agent:n.currentTarget.value}),children:["auto",...Ue].map(n=>e("option",{value:n,children:oe[n]}))})})]}),e("p",{class:"help",children:t.agent==="auto"?"Auto prefers Claude Code, then Codex, then Antigravity, using installation and quota availability. Configure each provider\u2019s models below.":`${oe[t.agent]} will perform every rewrite. If it is unavailable, Improve shows an error without switching agents.`}),e("div",{class:"settings-row",children:[e("div",{children:[e("strong",{children:"Default mode"}),e("p",{children:"Quick uses your text only. Repo also reads a private snapshot of committed files; uncommitted changes are excluded."})]}),e("div",{class:"settings-row-control",children:e("select",{class:"field","aria-label":"Default improvement mode",value:t.defaultMode,onChange:n=>he({...t,defaultMode:n.currentTarget.value}),children:[e("option",{value:"quick",children:"Quick"}),e("option",{value:"repo",children:"Repo"})]})})]}),(t.agent==="auto"?Ue:[t.agent]).map(n=>{let r=st.value[n],i=r&&!("error"in r)?r:void 0,v=ye.value.find(y=>y.id===n)?.available;return e("fieldset",{class:"improve-provider",children:[e("legend",{children:[oe[n],v===!1?" \xB7 Not installed":""]}),["quick","repo"].map(y=>{let w=t.providers[n]?.[y]??{},b=ft(n,y),l=w.model??b.model??"",s=gt(n,l,i),f=`${y==="quick"?"Quick":"Repo"} model \xB7 ${oe[n]}`;return e("div",{class:"improve-model-row",children:[e("label",{children:[y==="quick"?"Quick model":"Repo model",i?.allowCustom===!1?e("select",{class:"field","aria-label":f,value:l,onChange:p=>u(n,y,{model:p.currentTarget.value,effort:void 0}),children:[e("option",{value:"",children:"CLI default"}),i.models.map(p=>e("option",{value:p.id,children:p.label}))]}):e(T,{children:[e("input",{class:"field","aria-label":f,list:`improve-${n}-${y}-models`,placeholder:"CLI default",value:l,maxLength:200,onInput:p=>u(n,y,{model:p.currentTarget.value,effort:void 0})}),e("datalist",{id:`improve-${n}-${y}-models`,children:i?.models.map(p=>e("option",{value:p.id,children:p.label}))})]})]}),e("label",{children:["Reasoning effort",e("select",{class:"field","aria-label":`${y==="quick"?"Quick":"Repo"} effort \xB7 ${oe[n]}`,disabled:!s.length,value:w.effort??"__recommended__",onChange:p=>u(n,y,{effort:p.currentTarget.value==="__recommended__"?void 0:p.currentTarget.value}),children:[e("option",{value:"__recommended__",children:s.length?`Improve default${b.effort&&s.includes(b.effort)?` \xB7 ${b.effort}`:""}`:"No effort choices"}),e("option",{value:"",children:"CLI default"}),w.effort&&!s.includes(w.effort)?e("option",{value:w.effort,children:[w.effort,i?" \xB7 unavailable for this model":" \xB7 loading choices"]}):null,s.map(p=>e("option",{value:p,children:p}))]})]})]},y)}),e("p",{class:"help",children:i?i.allowCustom?"Choose a suggested model or enter its model ID. Leave the model empty to use the CLI default.":"Choose a supported model or use the CLI default.":"Model choices are unavailable. You can enter a model ID; refresh providers to load supported effort choices."})]},n)}),e("div",{class:"settings-actions",children:[e("button",{class:"btn small",onClick:()=>he({agent:"auto",defaultMode:"quick",providers:{}}),children:"Reset Improve defaults"}),e("span",{class:"help",children:"Saved automatically in this browser for this workspace."})]}),e("p",{class:"help",children:"The note below your task shows which agent actually completed the rewrite. Improve does not implement the task."})]})}var We=[{key:"opencode",name:"OpenCode",command:"opencode",args:["acp"],install:"npm install -g opencode-ai",login:"opencode auth login",docs:"https://opencode.ai/docs/acp/"},{key:"kilo",name:"Kilo",command:"kilo",args:["acp"],install:"npm install -g @kilocode/cli",login:"kilo auth login",docs:"https://kilo.ai/docs/code-with-ai/platforms/cli-reference"},{key:"cline",name:"Cline",command:"cline",args:["--acp"],install:"npm install -g cline",login:"cline auth",docs:"https://docs.cline.bot/usage/acp",help:"Cline asks before edits and commands by default. Enable Ask me for tool permissions in the run\u2019s permissions controls to approve these requests."}];function Gt(t){return{id:`acp:${t.key}`,name:t.name,command:t.command,args:[...t.args],enabled:!0}}function Jt(){let[t,u]=o(),[n,r]=o(),[i,v]=o(""),[y,w]=o(!1),[b,l]=o(!1),[s,f]=o(""),[p,d]=o(),C=async()=>{try{u(await D("/api/acp-connections")),f("")}catch(c){f(c.message)}};$(()=>{C()},[]);let S=(c,k)=>{r(structuredClone(c)),v(c.args.join(`
|
|
6
|
+
`)),w(k),d(void 0),f("")},R=c=>{r(k=>k&&{...k,...c}),d(void 0)},x=()=>({...n,args:i?i.split(`
|
|
7
|
+
`):[]}),A=async c=>{l(!0),f("");try{await c()}catch(k){f(k.message)}finally{l(!1)}},I=async c=>{u(c),await we(),await Promise.all([Se(),Ce()])},h=async c=>{await I(await O("/api/acp-connections",{revision:t.revision,connection:c}))},m=async c=>{d(void 0),d({name:c.name,probe:await O("/api/acp-connections/check",{connection:c})})},P=We.find(c=>n?.id===`acp:${c.key}`);return e("section",{class:"settings-card","aria-label":"ACP connections",children:[e("h3",{children:"Connect another coding agent"}),e("p",{class:"help",children:"Connect OpenCode, Kilo, Cline or another CLI that supports Agent Client Protocol (ACP). Install and sign in through the CLI on this machine first."}),e("p",{class:"help",children:["ACP agents run with your host permissions and require ",e("a",{href:"#/settings/runs",children:"Full access"}),". SSH workers and containers are unavailable. Permission requests are declined unless the run enables interactive tool approvals; the CLI may also allow actions through its own settings."]}),e("div",{class:"settings-actions",children:[We.map(c=>e("button",{class:"btn",disabled:b||!t,onClick:()=>{let k=t?.connections.find(j=>j.id===`acp:${c.key}`);S(k??Gt(c),!!k)},children:["Connect ",c.name]},c.key)),e("button",{class:"btn",disabled:b||!t,onClick:()=>S({id:"acp:",name:"",command:"",args:[],enabled:!0},!1),children:"Add compatible CLI"}),e("button",{class:"btn",disabled:b,onClick:()=>void C(),children:"Reload connections"})]}),t?.connections.map(c=>e("article",{class:"wb-item",children:[e("div",{class:"wb-item-head",children:[e("strong",{children:c.name}),e("span",{class:"badge",children:c.enabled?"Enabled":"Disabled"})]}),e("p",{class:"help",children:e("code",{children:[c.command,...c.args].join(" ")})}),e("div",{class:"settings-actions",children:[e("button",{class:"btn small",disabled:b,onClick:()=>S(c,!0),"aria-label":`Edit ${c.name}`,children:"Edit"}),e("button",{class:"btn small",disabled:b,onClick:()=>void A(()=>m(c)),children:["Check ",c.name]}),e("button",{class:"btn small",disabled:b,onClick:()=>void A(()=>h({...c,enabled:!c.enabled})),children:[c.enabled?"Disable":"Enable"," ",c.name]}),e("button",{class:"btn small",disabled:b,onClick:()=>void A(async()=>{await I(await D(`/api/acp-connections/${N(c.id)}?revision=${t.revision}`,{method:"DELETE"})),n?.id===c.id&&r(void 0)}),children:["Remove ",c.name]})]})]},c.id)),n?e("form",{class:"acp-connection-form",onSubmit:c=>{c.preventDefault(),A(async()=>{let k=x();if(!y&&t?.connections.some(j=>j.id===k.id))throw new Error("That connection ID already exists. Edit the saved connection or choose another ID.");await h(k),r(void 0)})},children:[e("h4",{children:y?"Edit connection":"New connection"}),P?e("div",{class:"help",children:[e("p",{children:["Install: ",e("code",{children:P.install}),". Sign in: ",e("code",{children:P.login}),". ",e("a",{href:P.docs,target:"_blank",rel:"noopener noreferrer",children:[P.name," CLI documentation"]})]}),"help"in P?e("p",{children:P.help}):null]}):null,e("div",{class:"settings-grid",children:[e("label",{children:["Connection ID",e("input",{class:"field",disabled:b,"aria-label":"ACP connection ID",required:!0,pattern:"[a-z][a-z0-9-]{0,40}",maxLength:41,readOnly:y,value:n.id.slice(4),onInput:c=>R({id:`acp:${c.currentTarget.value}`})})]}),e("label",{children:["Name",e("input",{class:"field",disabled:b,"aria-label":"ACP connection name",required:!0,maxLength:100,value:n.name,onInput:c=>R({name:c.currentTarget.value})})]})]}),e("label",{class:"lbl",children:["Executable",e("input",{class:"field",disabled:b,"aria-label":"ACP executable",required:!0,maxLength:4e3,placeholder:"opencode or /absolute/path/to/agent",value:n.command,onInput:c=>R({command:c.currentTarget.value})})]}),e("label",{class:"lbl",children:["Arguments \xB7 one per line",e("textarea",{class:"field",disabled:b,"aria-label":"ACP arguments",rows:3,value:i,placeholder:"acp",onInput:c=>{v(c.currentTarget.value),d(void 0)}})]}),e("p",{class:"help",children:"Enter the executable separately from its arguments. Paths with spaces do not need quotes. Use the CLI\u2019s own login; do not put credentials in these fields."}),e("div",{class:"settings-actions",children:[e("button",{type:"button",class:"btn",disabled:b,onClick:()=>void A(()=>m(x())),children:b?"Working\u2026":"Check connection"}),e("button",{type:"submit",class:"btn primary",disabled:b||!t,children:"Save connection"}),e("button",{type:"button",class:"btn",disabled:b,onClick:()=>{r(void 0),d(void 0)},children:"Cancel"})]})]}):null,p?e("div",{class:"msg",role:"status",children:[e("strong",{children:[p.name,": connected"]}),e("p",{children:[p.probe.agent,p.probe.version?` ${p.probe.version}`:""," \xB7 ACP v1 \xB7 ",p.probe.catalog.models.length," models \xB7 Session resume ",p.probe.sessionResume?"available":"unavailable"]}),e("p",{class:"help",children:"Created a session without sending a prompt. Model access and inference have not been tested."})]}):null,s?e("p",{class:"msg err",role:"alert",children:s}):null]})}var _e={archivedRuns:"Archived run logs and recovery records",attachments:"Staged uploads and message attachments",memory:"Private and team memory from retired runs",worktrees:"Clean linked workspaces, keeping branches"},ve=Object.keys(_e),Qt=t=>t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KiB`:`${(t/(1024*1024)).toFixed(1)} MiB`,tn=t=>`'${t.replace(/'/g,"'''")}'`;function Yt({endpoint:t="/api/maintenance/retention"}){let[u,n]=o(null),[r,i]=o({archivedRuns:"",attachments:"",memory:"",worktrees:""}),[v,y]=o(""),[w,b]=o(""),[l,s]=o(null),[f,p]=o(!1),[d,C]=o(""),[S,R]=o(""),x=async()=>{let m=await D(t);n(m),i(Object.fromEntries(ve.map(P=>[P,m.days[P]===null?"":String(m.days[P])]))),y(m.keepRunIds.join(`
|
|
8
|
+
`)),b(m.keepMemoryIds.join(`
|
|
9
|
+
`)),C(""),s(null)};$(()=>{x().catch(m=>C(m.message))},[t]);let A=async()=>{if(!(!u||f)){p(!0),C(""),R("");try{let m=Object.fromEntries(ve.map(k=>[k,r[k].trim()?Number(r[k]):null]));if(ve.some(k=>m[k]!==null&&(!Number.isInteger(m[k])||m[k]<1||m[k]>36500)))throw new Error("Enter 1\u201336,500 days, or leave blank to keep that data.");let P=k=>[...new Set(k.split(/[\s,]+/).filter(Boolean))],c=await O(t,{expectedRevision:u.revision,days:m,keepRunIds:P(v),keepMemoryIds:P(w)});n(c),s(null),R("Retention settings saved. No data was deleted.")}catch(m){C(m.message)}finally{p(!1)}}},I=async()=>{if(!f){p(!0),C("");try{s(await O(t+"/preview",{}))}catch(m){C(m.message)}finally{p(!1)}}},h=()=>{if(!l)return;let m=new Blob([JSON.stringify(l,null,2)],{type:"application/json"}),P=URL.createObjectURL(m),c=document.createElement("a");c.href=P,c.download=`codeflow-retention-${new Date(l.createdAt).toISOString().replace(/[:.]/g,"-")}.json`,c.click(),setTimeout(()=>URL.revokeObjectURL(P),1e3)};return e("section",{class:"wb-card retention-panel","aria-label":"Data retention",children:[e("h2",{children:"Data retention"}),e("p",{class:"help",children:"Choose separate retention ages for application data. Blank fields keep that data. Saving settings never deletes anything; review a fixed preview and apply it with the server stopped."}),e("p",{class:"help",children:"Active, resumable, unarchived and pinned work is protected. Project knowledge requires individual review and is never bulk-deleted. Live memory provenance and child/deferred run references preserve their sources."}),u?e(T,{children:[e("div",{class:"wb-fields",children:ve.map(m=>e("label",{children:[_e[m]," \xB7 days",e("input",{class:"field","aria-label":`Retention days ${m}`,type:"number",min:1,max:36500,placeholder:"Keep indefinitely",value:r[m],onInput:P=>{i(c=>({...c,[m]:P.currentTarget.value})),R("")}})]},m))}),e("div",{class:"wb-fields",children:[e("label",{children:["Keep these run IDs \xB7 one per line",e("textarea",{class:"field",rows:2,"aria-label":"Retention protected run IDs",value:v,onInput:m=>y(m.currentTarget.value)})]}),e("label",{children:["Keep these memory IDs \xB7 one per line",e("textarea",{class:"field",rows:2,"aria-label":"Retention protected memory IDs",value:w,onInput:m=>b(m.currentTarget.value)})]})]}),e("div",{class:"wb-actions",children:[e("button",{class:"btn small primary",disabled:f,onClick:A,children:"Save retention settings"}),e("button",{class:"btn small",disabled:f,onClick:I,children:f?"Inspecting\u2026":"Preview saved retention policy"}),e("button",{class:"btn small",disabled:f,onClick:()=>void x().catch(m=>C(m.message)),children:"Reload saved settings"})]}),S?e("p",{class:"help",role:"status",children:S}):null]}):e("p",{class:"help",children:"Loading retention settings\u2026"}),d?e("p",{class:"msg err",role:"alert",children:[d," Your draft settings are preserved."]}):null,l?e("section",{class:"wb-subsection","aria-label":"Retention preview",children:[e("p",{class:"help",children:["Policy revision ",l.policyRevision," \xB7 preview ",new Date(l.createdAt).toLocaleString()," \xB7 expires ",new Date(l.expiresAt).toLocaleString(),". Known file bytes selected: ",Qt(l.summary.bytes),". Memory bodies are counted separately."]}),e("ul",{children:ve.map(m=>e("li",{children:[_e[m],": ",l.summary[m]," selected",l.cutoffs[m]===null?" \xB7 disabled":` \xB7 last updated before ${new Date(l.cutoffs[m]).toLocaleString()}`]},m))}),l.truncated?e("p",{class:"msg err",role:"alert",children:"This scan is incomplete or reached a limit and cannot be applied. Review the protected reasons and narrow the policy or repair the unreadable data."}):null,e("details",{children:[e("summary",{children:["Exact selected targets \xB7 ",l.targets.length]}),e("ul",{children:l.targets.map(m=>e("li",{children:[e("b",{children:m.kind})," \xB7 ",m.path??m.memory?.id??m.runId," \xB7 ",m.detail,m.files?e("ul",{children:m.files.map(P=>e("li",{children:[P.path," \xB7 ",Qt(P.bytes)," \xB7 ",e("code",{children:P.fingerprint})]},P.path))}):e("p",{class:"help",children:["Fingerprint: ",e("code",{children:m.fingerprint})]})]},m.id))})]}),e("details",{children:[e("summary",{children:["Protected data and scan limits \xB7 ",l.protected.length]}),e("ul",{children:l.protected.map((m,P)=>e("li",{children:[m.kind," \xB7 ",m.id,": ",m.reason]},P))})]}),e("p",{class:"help",children:["Manifest fingerprint: ",e("code",{children:l.fingerprint}),". Download after reviewing it, stop the server, then apply the downloaded file. Any policy, ownership or data change invalidates the preview. Workspaces are removed without force and Git branches are kept."]}),e("button",{class:"btn small",disabled:l.truncated,onClick:h,children:"Download reviewed retention plan"}),e("pre",{children:`npm run maintenance -- retention-policy --plan /path/to/downloaded-plan.json --apply --home ${tn(l.home)}`}),e("p",{class:"help",children:"The apply command takes the same exclusive lock as the server. An I/O failure after deletion starts is reported with the applied and remaining targets."})]}):null]})}function Vs({section:t="general",group:u}){let[n,r]=o(""),i=H(null);Je(()=>{r(""),document.getElementById("main-content")?.scrollTo({top:0})},[t,u]),$(()=>{let s=i.current,f=s?.querySelector("[aria-current='page']");!n&&s&&f&&s.scrollWidth>s.clientWidth&&(s.scrollLeft+=f.getBoundingClientRect().left-s.getBoundingClientRect().left-8)},[t,n]);let v=$e.find(s=>s.id===t),y=Ye(n),w=Re.value,b=It().length,l=s=>{r(""),Ne.value=s==="workspace"||s==="automations"||s==="insights"?{view:s}:{view:"settings",section:s}};return e("div",{class:`settings-page ${t==="workspace"||t==="insights"?"settings-tools":""}`,children:[e("header",{class:"settings-header",children:[e("div",{children:[e("div",{class:"eyebrow",children:"Your workspace, your way"}),e("h1",{children:"Settings"})]}),e("span",{class:"settings-scope",children:[e(te,{name:w.kind==="local"?"panel":"terminal"}),w.kind==="ssh"?w.name:w.kind==="host"?"Remote server":"This computer"]})]}),e("div",{class:"settings-layout",children:[e("aside",{class:"settings-sidebar",children:[e("div",{class:"settings-search",children:[e(te,{name:"search"}),e("input",{class:"field",type:"search","aria-label":"Search settings",placeholder:"Search settings\u2026",value:n,onInput:s=>r(s.currentTarget.value)})]}),e("nav",{ref:i,"aria-label":"Settings categories",children:["Preferences","Connections","Management"].map(s=>e("div",{class:"settings-nav-group",children:[e("div",{class:"settings-nav-label",children:s}),$e.filter(f=>f.group===s&&!["workspace","automations","insights"].includes(f.id)).map(f=>e("a",{class:`settings-nav-item ${t===f.id&&!n.trim()?"active":""}`,href:`#/settings/${f.id}`,title:f.id==="automations"&&b?`${b} runs need attention`:void 0,"aria-current":t===f.id&&!n.trim()?"page":void 0,onClick:()=>r(""),children:[e(te,{name:f.icon}),f.label,f.id==="automations"&&b?e("span",{class:"count","aria-hidden":"true",children:b}):null]},f.id))]},s))}),e("p",{class:"settings-nav-note",children:["A little more you.",e("br",{}),"A little less setup."]})]}),e("div",{class:"settings-content",children:n.trim()?e("section",{"aria-label":"Settings search results",children:[e("h2",{children:"Search settings"}),e("p",{class:"help",role:"status",children:[y.length," ",y.length===1?"category":"categories"," for \u201C",n.trim(),"\u201D"]}),y.length?y.map(s=>e("button",{class:"settings-result",onClick:()=>l(s.id),children:[e(te,{name:s.icon}),e("span",{children:[e("strong",{children:s.label}),e("span",{children:s.description})]}),e("span",{"aria-hidden":"true",children:"\u2192"})]},s.id)):e("div",{class:"settings-empty",children:[e(te,{name:"search"}),e("h3",{children:"No matching settings"}),e("p",{children:"Try \u201CSSH\u201D, \u201Cmodels\u201D, \u201Ctheme\u201D or \u201Cpermissions\u201D."}),e("button",{class:"btn",onClick:()=>r(""),children:"Clear search"})]})]}):e(T,{children:[e("div",{class:"settings-section-heading",children:[e("h2",{children:v.label}),e("p",{children:v.description})]}),e("div",{class:"settings-section-content",children:[t==="general"?e(nn,{}):null,t==="agents"?e(sn,{}):null,t==="runs"?e(an,{}):null,t==="connections"?e(qt,{purpose:u}):null,t==="notifications"?e(T,{children:[e(Y,{title:"Desktop notifications",children:[e(se,{title:"Run updates",description:"Notify when a run finishes or needs your attention, while you\u2019re away from it.",children:e("button",{class:"settings-switch",role:"switch","aria-label":"Desktop notifications","aria-checked":je(),onClick:()=>void Ze(!je()),children:e("span",{})})}),e("p",{class:"help",children:"Notification"in window?Xe.value==="denied"?"Notifications are blocked. Allow them in your browser\u2019s site permissions to enable this setting.":"This preference is saved in this browser for the current workspace.":"This browser doesn\u2019t support desktop notifications."})]}),e(Ut,{})]}):null,t==="integrations"?e(T,{children:[e(Bt,{onImport:s=>{vt.value=s,ht.value=null,pt(`Address ${s.provider} ${s.kind} ${s.key}: ${s.title}`),Ne.value={view:"composer"}}}),e(Ht,{projects:_.value})]}):null,t==="workspace"?e(At,{}):null,t==="insights"?e(xt,{group:u}):null,t==="automations"?e(Tt,{}):null,t==="projects"?e(on,{}):null,t==="extensions"?e(_t,{}):null,t==="data"?e(Yt,{}):null,t==="advanced"?e(rn,{}):null]},t)]})})]})]})}function Y({title:t,children:u}){return e("section",{class:"settings-card",children:[e("h3",{children:t}),u]})}function se({title:t,description:u,children:n}){return e("div",{class:"settings-row",children:[e("div",{children:[e("strong",{children:t}),e("p",{children:u})]}),e("div",{class:"settings-row-control",children:n})]})}function nn(){return e(T,{children:[e(Ot,{}),e(Y,{title:"Appearance",children:[e("p",{class:"help",children:"Choose a look. Your preference is saved in this browser and applies to every workspace."}),e("div",{class:"theme-options",role:"group","aria-label":"Appearance",children:["light","dark","system"].map(t=>e("button",{class:`theme-option ${ge.value===t?"selected":""}`,"aria-pressed":ge.value===t,onClick:()=>Qe(t),children:[e("span",{class:`theme-preview ${t}`,"aria-hidden":"true",children:[e("span",{}),e("span",{children:[e("i",{}),e("i",{}),e("i",{})]})]}),e("span",{children:[t==="system"?"System":t==="light"?"Light":"Dark",ge.value===t?e("span",{"aria-hidden":"true",children:"\u2713"}):null]})]},t))})]}),e(Y,{title:"Workspace preferences",children:[e(se,{title:"Group runs by",description:"Choose how runs are organized in the sidebar.",children:e("select",{class:"field","aria-label":"Group runs by",value:Pe.value.group,onChange:t=>Me({group:t.currentTarget.value}),children:[e("option",{value:"project",children:"Project"}),e("option",{value:"status",children:"Status"})]})}),e(se,{title:"Show archived runs",description:"Include archived work in your run list.",children:e("button",{class:"settings-switch",role:"switch","aria-label":"Show archived runs","aria-checked":Pe.value.archived,onClick:()=>Me({archived:!Pe.value.archived}),children:e("span",{})})}),e(se,{title:"Keyboard shortcuts",description:"Move around your workspace without leaving the keyboard.",children:e("button",{class:"btn small",onClick:()=>{at.value=!0},children:"View shortcuts"})})]}),e("div",{class:"settings-callout",children:[e(te,{name:"terminal"}),e("div",{children:[e("strong",{children:"Take your workspace further"}),e("p",{children:"Connect a VM and keep your projects and tools on your remote machine."}),e("a",{href:"#/settings/connections/workspace",children:["Set up an SSH connection ",e("span",{"aria-hidden":"true",children:"\u2192"})]})]})]})]})}function sn(){let[t,u]=o(!1);return e(T,{children:[e(Kt,{}),e(Jt,{}),e("details",{class:"settings",children:[e("summary",{children:"Check this computer"}),e("div",{class:"settings-body",children:e(Vt,{})})]}),e("p",{class:"help",children:"Saved model choices apply to new runs in this workspace. Project defaults and individual role overrides can take precedence. Sign in through each agent\u2019s CLI on the machine where it runs."}),e("div",{class:"settings-actions",children:[e("button",{class:"btn",disabled:t,onClick:async()=>{u(!0);try{await we(),await Promise.all([Se(),Ce()])}finally{u(!1)}},children:t?"Checking\u2026":"Refresh providers"}),e("button",{class:"btn",onClick:()=>{dt.value=!0},children:"Health & usage"})]}),ye.value.map(n=>{let r=ct.value?.find(i=>i.id===n.id);return e(Y,{title:n.displayName,children:[e("div",{class:"settings-provider-status",children:[e("span",{class:`badge ${r?.installed&&r.signedIn!==!1?"ok":""}`,children:r?r.installed?r.signedIn===!1?"Signed out":r.signedIn?"Signed in":"Installed \xB7 login unknown":"Not installed":"Checking health\u2026"}),e("span",{class:"help",children:r?.version})]}),n.available?e(Rt,{agent:n,used:!0}):e("p",{class:"help",children:"Install this CLI on the current machine to configure its models."}),r?.fix?e("p",{class:"msg warn",children:r.fix}):null]},n.id)})]})}function Te({label:t,value:u,min:n=1,max:r,step:i=1,optional:v=!1,save:y}){let[w,b]=o(u===void 0?"":String(u));return $(()=>b(u===void 0?"":String(u)),[u]),e("label",{children:[t,e("input",{class:"field",type:"number",min:n,max:r,step:i,required:!v,placeholder:v?"No ceiling":void 0,value:w,onInput:l=>b(l.currentTarget.value),onBlur:l=>{l.currentTarget.validity.valid&&(w||v)?y(w?Number(w):void 0):(b(u===void 0?"":String(u)),J(`Enter a valid value for ${t.toLowerCase()}`))}})]})}function an(){return e(T,{children:[e("p",{class:"help",children:"These are the composer\u2019s remembered choices for this browser and workspace. Changes also update your current draft; running work keeps its existing settings."}),e(Y,{title:"Workflow",children:[e(se,{title:"Default workflow",description:"The team pattern used for a new task.",children:e("select",{class:"field","aria-label":"Default workflow",value:ne.value,onChange:t=>mt(t.currentTarget.value),children:nt.value.map(t=>e("option",{value:t.id,children:t.name},t.id))})}),qe[ne.value]?e(se,{title:"Approve before building",description:`Pause so you can review ${qe[ne.value]}. This choice is remembered per workflow.`,children:e("button",{class:"settings-switch",role:"switch","aria-label":"Approve before building","aria-checked":Oe(ne.value),onClick:()=>ut(!Oe(ne.value),ne.value),children:e("span",{})})}):null]}),e(Y,{title:"Agent permissions",children:[e("label",{class:"sr-only",for:"settings-trust",children:"Agent permissions"}),e("select",{class:"field",id:"settings-trust",value:ke.value,onChange:t=>lt(t.currentTarget.value),children:Object.keys(Ie).map(t=>e("option",{value:t,children:Ie[t].label},t))}),e("p",{class:ke.value==="full"?"full-warn":"help",children:Ie[ke.value].help})]}),e(Y,{title:"Run limits",children:[e("p",{class:"help",children:"Stop when a limit is reached. Changes save when you leave a field."}),e("div",{class:"settings-grid",children:[e(Te,{label:"Minutes per run",value:pe.value.maxMinutes,max:720,save:t=>me({maxMinutes:t})}),e(Te,{label:"Agent steps per run",value:pe.value.maxSteps,max:200,save:t=>me({maxSteps:t})}),e(Te,{label:"Reported token ceiling",value:pe.value.maxTokens,optional:!0,save:t=>me({maxTokens:t})}),e(Te,{label:"API-equivalent cost ceiling ($)",value:pe.value.maxCostUsd,optional:!0,min:.01,step:.01,save:t=>me({maxCostUsd:t})})]}),e("p",{class:"help",children:"Usage ceilings depend on provider reports and are checked between operations. API-equivalent cost is not your subscription bill."})]}),e("p",{class:"help",children:["Repository setup, checks, branch names, team roles and per-run isolation are available in ",e("a",{href:"#/",children:"New run \u2192 Advanced agent settings"}),"."]})]})}function on(){let[t,u]=o(""),n=_.value.find(r=>r.id===t)??_.value.find(r=>r.repos.includes(Q.value))??_.value[0];return e(T,{children:[e(Y,{title:"Projects",children:e(se,{title:"Repositories",description:"Create projects and change their repositories.",children:e("button",{class:"btn small",onClick:()=>{ot.value=!0},children:"Manage projects"})})}),n?e(T,{children:[e("label",{class:"lbl",for:"settings-project",children:"Project"}),e("select",{id:"settings-project",class:"field",value:n.id,onChange:r=>u(r.currentTarget.value),children:_.value.map(r=>e("option",{value:r.id,children:r.name},r.id))}),e(Fe,{projectId:n.id,repositories:n.repos},n.id),e(Ft,{projectId:n.id,repos:n.repos},`conventions:${n.id}`),e(Wt,{projectId:n.id,projectName:n.name},`policy:${n.id}`)]}):e(T,{children:[e("p",{class:"help",children:"Create a project to configure its conventions and filesystem access."}),e(Fe,{repositories:Q.value?[Q.value]:[]})]}),e("p",{class:"help",children:["Manage people and project access in ",e("a",{href:"#/settings/connections/sharing",children:"Connections \u2192 Share access"}),"."]})]})}function rn(){let[t,u]=o(),[n,r]=o(!1),[i,v]=o("");return e(T,{children:[e(Y,{title:"Diagnostics",children:[e("p",{class:"help",children:"Collect versions, connection health, resource queues and recent logs for the current machine. Credential-like values are redacted before export."}),e("div",{class:"settings-actions",children:[e("button",{class:"btn",disabled:n,onClick:async()=>{r(!0),v("");try{u({...await D(`/api/diagnostics${Q.value?`?repo=${N(Q.value)}`:""}`),browserPerformance:Ge(),runtime:await D("/api/health")})}catch(y){v(y.message)}finally{r(!1)}},children:n?"Collecting\u2026":"Collect diagnostics"}),t?e("button",{class:"btn",onClick:()=>Dt("codeflow-diagnostics.json",JSON.stringify(t,null,2)),children:"Export diagnostics"}):null]}),t?e("details",{children:[e("summary",{children:"Collected diagnostics"}),e("pre",{children:JSON.stringify(t,null,2)})]}):null,i?e("p",{role:"alert",class:"msg err",children:i}):null]}),e(Y,{title:"Server configuration",children:[e("p",{class:"help",children:"Process settings such as the server port, data directory, concurrency, CLI paths and integration credentials are configured through environment variables when starting code-flow. Changes require a server restart."}),e("p",{class:"help",children:["Repository defaults live in ",e("code",{children:".codeflow/config.json"}),". Browser preferences are separate for each SSH workspace."]}),e("a",{href:"https://github.com/midhunxavier/code-flow/blob/main/docs/configuration.md",target:"_blank",rel:"noreferrer",children:"Configuration reference \u2197"})]})]})}export{Vs as SettingsView};
|