runspur 0.0.0-stage → 0.1.2

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.
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,24 @@
1
- {
2
- "name": "runspur",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
1
+ {
2
+ "name": "runspur",
3
+ "version": "0.1.2",
4
+ "description": "Runspur Agent scheduler and local browser panel for Windows x64",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ohmacemace/runspur.git"
9
+ },
10
+ "os": [
11
+ "win32"
12
+ ],
13
+ "cpu": [
14
+ "x64"
15
+ ],
16
+ "bin": {
17
+ "runspur": "native/runspur.exe"
18
+ },
19
+ "files": [
20
+ "native/*.exe",
21
+ "web/",
22
+ "THIRD_PARTY_NOTICES.txt"
23
+ ]
6
24
  }
@@ -0,0 +1 @@
1
+ async function e(e,t={},n){return window.__TAURI_INTERNALS__.invoke(e,t,n)}export{e as invoke};
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
2
+ <rect x="24" y="24" width="464" height="464" rx="98" fill="#18231d"/>
3
+ <rect x="32" y="32" width="448" height="448" rx="91" fill="none" stroke="#557767" stroke-width="8"/>
4
+ <path d="M140 374V138h164l65 65-65 65h-66l132 106M238 203h64" fill="none" stroke="#a4e3bb" stroke-width="32" stroke-linecap="square" stroke-linejoin="round"/>
5
+ </svg>
@@ -0,0 +1 @@
1
+ (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=`modulepreload`,t=function(e){return`/`+e},n={},r=function(e){return e.pathname.endsWith(`.css`)},i=function(e,t,n){if(t in e)return e[t];let r=n();if(!r){e[t]=void 0;return}let i=r.then(()=>{e[t]=void 0},n=>{throw e[t]=void 0,n});return e[t]=i,i},a=function(a,o,s){let c=Promise.resolve();if(o&&o.length>0){let a,l=document.querySelector(`meta[property=csp-nonce]`),u=l?.nonce||l?.getAttribute(`nonce`);function d(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function f(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}c=d(o.map(o=>{o=t(o,s);let c=f(o),l=r(c);return i(n,c.href,()=>{if(a===void 0){a={all:new Set,styles:new Set};let e=document.getElementsByTagName(`link`);for(let t=e.length-1;t>=0;t--){let n=e[t];a.all.add(n.href),n.rel===`stylesheet`&&a.styles.add(n.href)}}if((l?a.styles:a.all).has(c.href))return;let t=document.createElement(`link`);if(t.rel=l?`stylesheet`:e,l||(t.as=`script`),t.crossOrigin=``,t.href=c.href,u&&t.setAttribute(`nonce`,u),document.head.appendChild(t),l)return new Promise((e,n)=>{let r=i=>{t.removeEventListener(`load`,r),t.removeEventListener(`error`,r),i.type===`error`?n(Error(`Unable to preload CSS for ${c}`)):e(i)};t.addEventListener(`load`,r),t.addEventListener(`error`,r)})})}).filter(e=>e!==void 0))}function l(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return c.then(e=>{for(let t of e||[])t.status===`rejected`&&l(t.reason);return a().catch(l)})},o=`runspur.tui.token`,s=/^[0-9a-f]{64}$/i,c=`__TAURI_INTERNALS__`in window;function l(){let{hash:e,pathname:t,search:n}=window.location,r=new URLSearchParams(e.slice(1)).get(`token`);if(e&&window.history.replaceState(window.history.state,``,t+n),r!==null&&!s.test(r))return null;try{if(r!==null)window.sessionStorage.setItem(o,r);else{let e=window.sessionStorage.getItem(o);return e!==null&&s.test(e)?e:null}}catch{}return r}var u=c?null:l();async function d(e,t={}){if(c){let{invoke:n}=await a(async()=>{let{invoke:e}=await import(`./core-CwxXejkd.js`);return{invoke:e}},[]);return n(e,t)}if(u===null)throw Error("Open the Runspur browser panel with `runspur tui`.");let n=await fetch(`/api/${encodeURIComponent(e)}`,{method:`POST`,credentials:`omit`,redirect:`error`,headers:{Authorization:`Bearer ${u}`,"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(typeof e?.error==`string`?e.error:`Runspur returned HTTP ${n.status}.`)}return n.json()}function f(e){let t=document.getElementById(e);if(!t)throw Error(`Missing element: ${e}`);return t}function p(e,t,n){let r=document.createElement(e);return r.textContent=t,n&&(r.className=n),r}function m(e){return e.startsWith(`\\\\?\\UNC\\`)?`\\\\${e.slice(8)}`:e.startsWith(`\\\\?\\`)?e.slice(4):e}function h(e,t,n){e.textContent=n?[t(n.message),n.detail].filter(Boolean).join(` `):``,e.dataset.error=String(!!n?.detail)}var g={queued:`queued`,starting:`startingTask`,running:`runningTask`,waiting_approval:`waitingApproval`,succeeded:`succeeded`,failed:`failed`,canceled:`canceled`,timed_out:`timedOut`},_={not_ready:`notReady`,pending:`pending`,sending:`sending`,accepted_by_transport:`acceptedByTransport`,acknowledged_by_parent:`acknowledgedByParent`,held:`held`,refused:`refused`,retry_wait:`retryWait`,orphaned:`orphaned`,uncertain:`uncertain`};function v(e){let t=f(`history`),n=f(`history-project`),r=f(`history-session`),i=f(`refresh-history`),a=f(`load-sessions`),o=f(`resume-claude-session`),s=f(`load-history`),l=f(`history-list`),u=f(`task-detail`),m=f(`task-content`),v=!1,y=!1,b=!1,x=!1,S=0,C=0,w=[],T=[],E=[],D=``,O=``,k=null,A=null,j=``,M,N,P;function F(){if(!c||!D||!O)return;let e=w.find(({config:e})=>e.project_id===D);if(e?.main_agent_kind!==`claude_print`)return;let t=T.find(({origin_id:e})=>e===O);if(t?.adapter_id===`claude_code_managed`&&t.transport!==`native_inbox`&&t.session_id)return{root:e.root,resume:t.session_id}}function I(e){return new Intl.DateTimeFormat(document.documentElement.lang,{dateStyle:`medium`,timeStyle:`short`}).format(e)}function L(){if(f(`history-inspector`).hidden=E.length===0&&!j,f(`task-empty`).hidden=!!j,u.hidden=!j,h(f(`task-notice`),e,P),m.replaceChildren(),!M)return;let{task:t,prompt:n,origin_id:r,session_id:i,timeout_seconds:a}=M,o=p(`dl`,``,`task-readout`),s=(t,n)=>{if(n==null||n===``)return;let r=document.createElement(`div`);r.append(p(`dt`,e(t)),p(`dd`,String(n))),o.append(r)};if(s(`filterProject`,w.find(({config:e})=>e.project_id===t.project_id)?.config.name??t.project_id),s(`sessionId`,i),s(`originId`,r),s(`taskId`,t.task_id),s(`worker`,t.worker_profile_id),s(`execution`,e(g[t.execution_state])),s(`delivery`,e(_[t.delivery_state])),s(`queuedAt`,I(t.created_at_ms)),s(`startedAt`,t.started_at_ms==null?null:I(t.started_at_ms)),s(`finishedAt`,t.finished_at_ms==null?null:I(t.finished_at_ms)),s(`timeout`,new Intl.NumberFormat(document.documentElement.lang,{style:`unit`,unit:`second`}).format(a)),s(`deliveryId`,t.delivery_id),s(`parentTurnId`,t.parent_turn_id),s(`deliveryError`,t.delivery_error),t.result&&(s(`exitCode`,t.result.exit_code),s(`errorClass`,t.result.error_class)),m.append(o,p(`h3`,e(`prompt`)),p(`pre`,n,`task-text`)),m.append(p(`h3`,e(`result`))),!t.result)m.append(p(`p`,e(`noResult`)));else{m.append(p(`pre`,t.result.summary,`task-text`));for(let[n,r]of[[`verification`,t.result.verification.map(({description:e,outcome:t})=>`${e} · ${t}`)],[`artifacts`,t.result.artifact_refs]]){if(r.length===0)continue;let t=p(`ul`,``,`task-result-list`);t.append(...r.map(e=>p(`li`,e))),m.append(p(`h3`,e(n)),t)}}}function R(){n.replaceChildren(new Option(e(`allProjects`),``),...w.map(({config:e})=>new Option(e.name,e.project_id))),n.value=D;let t=D?T.length||O?`allSessions`:`noSessions`:`chooseProjectForSessions`;r.replaceChildren(new Option(e(t),``),...T.map(({origin_id:e,adapter_id:t,session_id:n,task_count:r,transport:i})=>new Option(`${n} · ${i===`native_inbox`?`Claude Code`:t} · ${r}`,e))),O&&!T.some(({origin_id:e})=>e===O)&&r.add(new Option(O,O)),r.value=O,n.disabled=i.disabled=!v||y,r.disabled=!v||y||!D||r.options.length<2,a.hidden=k==null,s.hidden=A==null,a.disabled=s.disabled=!v||y,o.hidden=!F(),o.disabled=!v||y||b,h(f(`history-notice`),e,v?N:{message:`schedulerNeeded`}),l.replaceChildren(...E.map(t=>{let n=p(`button`,``,`entry-button dispatch-entry`);return n.type=`button`,n.disabled=y,n.dataset.taskId=t.task_id,n.setAttribute(`aria-pressed`,String(t.task_id===j)),n.append(p(`strong`,t.worker_profile_id),p(`span`,`${e(g[t.execution_state])} · ${e(_[t.delivery_state])}`),p(`span`,I(t.created_at_ms))),n.addEventListener(`click`,()=>{z(t.task_id)}),n})),v&&!y&&!N&&E.length===0&&l.append(p(`p`,e(`noDispatches`),`empty-state`)),L()}async function z(e){let t=++C;j=e,M=void 0,P={message:`loading`};for(let t of l.querySelectorAll(`button`))t.setAttribute(`aria-pressed`,String(t.dataset.taskId===e));L();try{let n=await d(`query_task_detail`,{taskId:e});if(t!==C)return;M=n,P=void 0}catch(e){if(t!==C)return;P={message:`taskError`,detail:String(e)}}L()}function B(){C++,j=``,M=void 0,P=void 0}async function V(t){if(!v||y&&t!==`project`)return;let n=++S;y=!0,N={message:`loading`},(t===`project`||t===`session`)&&(E=[],A=null,B()),t===`project`&&(T=[],k=null),R();try{if(t===`refresh`){let e=await d(`projects_list`);if(n!==S)return;w=e}if(D&&(t===`refresh`||t===`project`||t===`olderSessions`)){let r=t===`olderSessions`,i=await d(`query_sessions`,{projectId:D,before:r?k:null,limit:25});if(n!==S)return;if(i.items.some(({origin_id:e})=>!e))throw Error(e(`originServiceUpgrade`));T=r?T.concat(i.items):i.items,k=i.next_cursor}if(t!==`olderSessions`){let e=t===`olderTasks`,r=await d(`query_task_history`,{projectId:D||null,originId:O||null,before:e?A:null,limit:25});if(n!==S)return;E=e?E.concat(r.items):r.items,A=r.next_cursor}N=void 0,x=!0}catch(e){if(n!==S)return;N={message:`historyError`,detail:String(e)}}finally{n===S&&(y=!1,R())}!N&&t===`refresh`&&j&&z(j)}function H(e){D=e,O=``,V(`project`)}n.addEventListener(`change`,()=>H(n.value)),r.addEventListener(`change`,()=>{O=r.value,V(`session`)}),i.addEventListener(`click`,()=>{V(`refresh`)}),a.addEventListener(`click`,()=>{V(`olderSessions`)}),s.addEventListener(`click`,()=>{V(`olderTasks`)}),o.addEventListener(`click`,async()=>{let e=F();if(e&&v&&!y&&!b){b=!0,N=void 0,R();try{await d(`launch_claude_project`,e)}catch(e){N={message:`resumeClaudeError`,detail:String(e)}}finally{b=!1,R()}}});function U(){x||V(`refresh`)}return{render:R,open:U,selectProject:H,setProjects(e){w=e,R()},setReady(e){v!==e&&(v=e,v||(S++,y=x=!1,w=[],T=[],E=[],D=O=``,k=A=null,B()),R(),t.hidden||U())}}}var y={en:{overview:`Overview`,settings:`Settings`,application:`Application`,language:`Language`,languageHint:`Choose the language used by Runspur.`,systemLanguage:`Use system language`,localScheduler:`Local scheduler`,refresh:`Refresh`,serviceVersion:`Service version`,protocol:`Protocol`,workers:`Active workers`,development:`Development`,checking:`Checking connection`,starting:`Starting scheduler`,stopping:`Stopping scheduler`,running:`Scheduler running`,runningDetail:`The local scheduler is responding.`,offline:`Scheduler offline`,offlineDetail:`Start the local Runspur scheduler to continue.`,railReady:`Scheduler ready`,railOffline:`Scheduler offline`,railError:`Connection error`,railPending:`Connecting`,connectionError:`Connection error`,technicalDetails:`Technical details`,start:`Start scheduler`,stop:`Stop scheduler`,retry:`Retry startup`,saving:`Saving…`,saved:`Saved.`,preferencesReadError:`Could not read preferences.`,preferencesWriteError:`Could not save preferences.`,projects:`Projects`,projectsIntro:`Manage project integrations and dispatch history.`,chooseProject:`Add project`,configureProject:`Edit configuration`,projectEditTitle:`Edit project configuration`,projectAlreadyConnected:`This folder is already connected. Saving will update the existing project.`,registeredProjects:`Registered projects`,noProjects:`No projects yet`,projectEmpty:`Choose a folder to configure its agents and track its dispatches here.`,backToProjects:`Back to projects`,projectSetup:`Setup`,projectConfiguration:`Configure`,projectReview:`Review`,editProject:`Edit configuration`,projectFolder:`Project folder`,projectName:`Project name`,parentAgent:`Main agent`,workerAgents:`Worker agents`,workerWritePolicy:`Worker file access`,workerAccessHint:`Worker changes are collected for review.`,workersReadOnlyHint:`The selected workers are read-only. Project write policies apply to workers that support editing.`,codexReadOnlyHint:`Codex workers run in read-only mode under every project policy.`,workerReadOnly:`Read only`,workerReadOnlyHint:`Inspect project files and report findings.`,workerScopedWrite:`Specified files`,workerScopedWriteHint:`Edit task-listed files in an isolated workspace.`,workerProjectWrite:`Project-wide text edits`,workerProjectWriteHint:`Edit text across an isolated project workspace.`,integrationScope:`Confirm to save the project manifest, Skill and main agent configuration.`,previewProject:`Preview integration`,projectManifest:`Project manifest`,projectSkill:`Skill`,projectMcp:`Runspur MCP entry`,projectClaudeHook:`Claude Code project hook`,projectDeveloperInstructions:`Runspur developer instructions`,projectCleanup:`Previous integration entries to remove`,applyProject:`Confirm and connect`,saveProjectChanges:`Save changes`,refreshAgents:`Refresh agents`,noWorkers:`No supported worker detected. Install a worker and refresh agents.`,chooseWorker:`Select at least one available worker agent.`,missingWorker:`Unavailable`,projectSaved:`Project saved. MCP and Skill files installed. Reload the project in the main agent host to use them.`,projectUpdated:`Project configuration updated. Open a new conversation to use the updated Skill and tools.`,projectSavedNativeClaude:`Project saved. Run claude in this folder to start a new Runspur-enabled conversation.`,projectLoadError:`Could not load project configuration.`,projectPreviewError:`Could not prepare the project integration preview.`,projectDifferentState:`This project is connected to a different Runspur data directory. Open it with the Runspur instance that originally connected it.`,projectSaveError:`Could not save the project integration.`,projectBrowseError:`Could not open the folder picker.`,agentLoadError:`Could not detect agents.`,projectsLoadError:`Could not load registered projects.`,loading:`Loading…`,schedulerNeeded:`Start the local scheduler in Overview to continue.`,history:`Dispatch history`,historyIntro:`Inspect each dispatch, its execution, and delivery back to the main agent.`,filterProject:`Project`,filterSession:`Session`,allProjects:`All projects`,allSessions:`All sessions`,chooseProjectForSessions:`Select a project to see its sessions`,noSessions:`No sessions with dispatches`,olderSessions:`Load older sessions`,resumeClaudeSession:`Resume Claude session`,resumeClaudeError:`Could not resume the selected Claude session.`,dispatches:`Dispatches`,noDispatches:`No dispatches match this view.`,olderDispatches:`Load older dispatches`,taskEmpty:`Select a dispatch to see its prompt, result, and delivery details.`,dispatchDetails:`Dispatch details`,cancelTask:`Cancel dispatch`,cancelPending:`Cancellation requested.`,cancelError:`Could not cancel this dispatch.`,historyError:`Could not load dispatch history.`,taskError:`Could not load this dispatch.`,execution:`Execution`,delivery:`Delivery`,taskId:`Dispatch ID`,deliveryId:`Delivery ID`,sessionId:`Origin session`,originId:`Runspur origin ID`,originServiceUpgrade:`Update the running Runspur service to filter by conversation.`,parentTurnId:`Main agent turn`,worker:`Worker`,queuedAt:`Dispatched`,startedAt:`Started`,finishedAt:`Finished`,duration:`Duration`,timeout:`Time limit`,prompt:`Prompt`,result:`Result`,noResult:`Result pending.`,exitCode:`Exit code`,errorClass:`Error category`,verification:`Verification`,artifacts:`Artifacts`,deliveryError:`Delivery details`,queued:`Queued`,startingTask:`Starting`,runningTask:`Running`,waitingApproval:`Waiting for approval`,succeeded:`Succeeded`,failed:`Failed`,canceled:`Canceled`,timedOut:`Timed out`,notReady:`Not ready`,pending:`Pending`,sending:`Sending`,acceptedByTransport:`Received by host`,acknowledgedByParent:`Acknowledged by main agent`,held:`On hold`,refused:`Refused`,retryWait:`Waiting to retry`,orphaned:`Origin unavailable`,uncertain:`Uncertain`},"zh-CN":{overview:`概览`,settings:`设置`,application:`应用`,language:`语言`,languageHint:`选择 Runspur 使用的界面语言。`,systemLanguage:`跟随系统`,localScheduler:`本地调度器`,refresh:`刷新`,serviceVersion:`服务版本`,protocol:`协议版本`,workers:`运行中的子 Agent`,development:`开发版`,checking:`正在检查连接`,starting:`正在启动调度器`,stopping:`正在停止调度器`,running:`调度器正在运行`,runningDetail:`本地调度器已响应。`,offline:`调度器未运行`,offlineDetail:`启动本地 Runspur 调度器后可继续。`,railReady:`调度器已就绪`,railOffline:`调度器未运行`,railError:`连接出错`,railPending:`正在连接`,connectionError:`连接出错`,technicalDetails:`技术详情`,start:`启动调度器`,stop:`停止调度器`,retry:`重试启动`,saving:`正在保存…`,saved:`已保存。`,preferencesReadError:`无法读取设置。`,preferencesWriteError:`无法保存设置。`,projects:`项目`,projectsIntro:`管理项目接入和调度历史。`,chooseProject:`添加项目`,configureProject:`编辑配置`,projectEditTitle:`编辑项目配置`,projectAlreadyConnected:`此目录已接入。保存后将更新现有项目的配置。`,registeredProjects:`已登记项目`,noProjects:`暂无项目`,projectEmpty:`选择项目目录,配置 Agent 后即可在这里查看调度记录。`,backToProjects:`返回项目`,projectSetup:`接入步骤`,projectConfiguration:`配置`,projectReview:`确认`,editProject:`返回修改`,projectFolder:`项目目录`,projectName:`项目名称`,parentAgent:`主 Agent`,workerAgents:`子 Agent`,workerWritePolicy:`子 Agent 文件权限`,workerAccessHint:`子 Agent 的改动会保留供审查。`,workersReadOnlyHint:`所选子 Agent 均为只读。项目写入设置适用于支持编辑的子 Agent。`,codexReadOnlyHint:`无论项目采用哪种写入设置,Codex 子 Agent 都以只读方式运行。`,workerReadOnly:`只读`,workerReadOnlyHint:`查看项目文件并汇报结果。`,workerScopedWrite:`指定文件写入`,workerScopedWriteHint:`在隔离工作区修改每次任务指定的文件。`,workerProjectWrite:`项目内写入`,workerProjectWriteHint:`在隔离的项目工作区修改文本文件。`,integrationScope:`确认后将保存项目清单、Skill 和主 Agent 配置。`,previewProject:`预览接入配置`,projectManifest:`项目清单`,projectSkill:`Skill`,projectMcp:`Runspur MCP 条目`,projectClaudeHook:`Claude Code 项目 Hook`,projectDeveloperInstructions:`Runspur 开发者指令`,projectCleanup:`将移除的旧接入条目`,applyProject:`确认接入`,saveProjectChanges:`保存修改`,refreshAgents:`刷新 Agent`,noWorkers:`暂未检测到可用的子 Agent。安装后可重新检测。`,chooseWorker:`请至少选择一个可用的子 Agent。`,missingWorker:`不可用`,projectSaved:`项目已保存,MCP 和 Skill 已安装。请在主 Agent 宿主中重新加载此项目。`,projectUpdated:`项目配置已更新。请在主 Agent 中开新会话使用更新后的 Skill 和工具。`,projectSavedNativeClaude:`项目配置已保存。在此目录运行 claude,即可开启支持 Runspur 的新会话。`,projectLoadError:`无法读取项目配置。`,projectPreviewError:`无法生成项目接入预览。`,projectDifferentState:`这个项目已接入另一套 Runspur 数据。请用原先接入项目的 Runspur 实例打开。`,projectSaveError:`无法保存项目集成。`,projectBrowseError:`无法打开目录选择器。`,agentLoadError:`无法检测 Agent。`,projectsLoadError:`无法读取已登记的项目。`,loading:`正在加载…`,schedulerNeeded:`请先在概览中启动本地调度器。`,history:`调度历史`,historyIntro:`查看每次调度的执行过程与回传状态。`,filterProject:`项目`,filterSession:`会话`,allProjects:`所有项目`,allSessions:`所有会话`,chooseProjectForSessions:`选择项目后可查看会话`,noSessions:`暂无派发记录的会话`,olderSessions:`加载更早的会话`,dispatches:`调度记录`,noDispatches:`当前视图没有调度记录。`,olderDispatches:`加载更早的记录`,taskEmpty:`选择一条调度记录,查看提示词、结果和回传详情。`,dispatchDetails:`调度详情`,cancelTask:`取消调度`,cancelPending:`已请求取消。`,cancelError:`无法取消此调度。`,resumeClaudeSession:`继续 Claude 会话`,resumeClaudeError:`无法继续选中的 Claude 会话。`,historyError:`无法读取调度历史。`,taskError:`无法读取此调度。`,execution:`执行状态`,delivery:`回传状态`,taskId:`调度 ID`,deliveryId:`回传 ID`,sessionId:`发起会话`,originId:`Runspur 原会话 ID`,originServiceUpgrade:`请更新正在运行的 Runspur 服务以按会话筛选。`,parentTurnId:`主 Agent 回合`,worker:`子 Agent`,queuedAt:`派发时间`,startedAt:`开始时间`,finishedAt:`结束时间`,duration:`耗时`,timeout:`超时限制`,prompt:`提示词`,result:`结果`,noResult:`正在等待结果。`,exitCode:`退出码`,errorClass:`错误类别`,verification:`验收信息`,artifacts:`产物`,deliveryError:`回传详情`,queued:`排队中`,startingTask:`启动中`,runningTask:`运行中`,waitingApproval:`等待授权`,succeeded:`成功`,failed:`失败`,canceled:`已取消`,timedOut:`超时`,notReady:`尚未就绪`,pending:`等待中`,sending:`回传中`,acceptedByTransport:`宿主已接收`,acknowledgedByParent:`主 Agent 已确认`,held:`暂缓`,refused:`已拒绝`,retryWait:`等待重试`,orphaned:`发起会话不可用`,uncertain:`状态不确定`}};function b(e,t){return e===`system`?t.toLowerCase().split(`-`)[0]===`zh`?`zh-CN`:`en`:e}var x={codex_desktop:`codex`,codex_exec:`codex`,claude_print:`claude`},S={read_only:{label:`workerReadOnly`,detail:`workerReadOnlyHint`},workspace_write:{label:`workerScopedWrite`,detail:`workerScopedWriteHint`},project_write:{label:`workerProjectWrite`,detail:`workerProjectWriteHint`}};function C(e){return e.allow_project_write?`project_write`:e.allow_workspace_write?`workspace_write`:`read_only`}var w={skill:`projectSkill`,runspur_scheduler:`projectMcp`,developer_instructions:`projectDeveloperInstructions`,claude_origin_hook:`projectClaudeHook`};function T(e,t){let n=t instanceof Error?t.message:String(t),r=`[runspur_state_conflict]`;return n.includes(r)?{message:`projectDifferentState`,detail:n.replace(r,``).trim()}:{message:e,detail:n}}function E(e,t,n){let r=f(`projects`),i=f(`choose-project`),a=f(`close-project-setup`),o=f(`project-list`),s=f(`project-form`),c=f(`project-root`),l=f(`project-name`),u=f(`parent-agent`),g=f(`worker-agents`),_=Array.from(f(`worker-file-access`).querySelectorAll(`input`)),v=f(`preview-project`),y=f(`project-preview`),b=f(`preview-hook`),E=f(`edit-project`),D=f(`apply-project`),O=f(`refresh-agents`),k=f(`project-setup-feedback`),A=f(`project-setup-message`),j=f(`project-setup-details`),M=f(`project-setup-error`),N=f(`project-feedback`),P=[],F=[],I,L,R=!1,z=!1,B=!1,V,H,U=()=>F.filter(e=>e.parent);function W(e,t){let n=F.find(e=>e.profile_id===t);return n!==void 0&&x[e.kind]===x[n.kind]}let G=()=>F.filter(e=>e.worker&&!W(e,I?.main_agent_profile_id));function K(e,t){let n=[[`codex_desktop`,`codex-desktop`,`Codex`],[`codex_exec`,`codex-cli`,`Codex`],[`claude_print`,`claude-cli`,`Claude Code`]].find(([n,r])=>t===void 0?r===e:n===t);if(!n)return e;let[,r,i]=n;return e===r?i:`${i} · ${e}`}function q(e){return K(e,F.find(t=>t.profile_id===e)?.kind)}function J(){i.disabled=z||!R,a.disabled=E.disabled=z,O.disabled=z||!R,l.disabled=u.disabled=!R||z;let t=I?.worker_profile_ids.map(e=>F.find(t=>t.profile_id===e)?.kind)??[],n=t.length>0&&t.every(e=>e===`codex_exec`);I&&n&&(I.allow_workspace_write=!1,I.allow_project_write=!1),_.forEach(e=>{e.checked=I?e.value===C(I):!1,e.disabled=!R||z||n&&e.value!==`read_only`});let r=t.includes(`codex_exec`)?`codexReadOnlyHint`:`workerAccessHint`,o=e(n?`workersReadOnlyHint`:r),s=f(`worker-access-hint`);s.textContent!==o&&(s.textContent=o),g.querySelectorAll(`input`).forEach(e=>{e.disabled=!R||z});let c=I&&I.name.trim()&&I.worker_profile_ids.length>0&&U().some(e=>e.profile_id===I?.main_agent_profile_id)&&I.worker_profile_ids.every(e=>G().some(t=>t.profile_id===e));f(`worker-hint`).hidden=!I||G().length===0||I.worker_profile_ids.length>0,v.disabled=z||!R||!c,D.disabled=v.disabled||!L}function Y(){s.hidden=!I||!!L,y.hidden=!L,b.hidden=!L?.hook_path,b.hidden&&(b.open=!1),L?(f(`configure-step`).removeAttribute(`aria-current`),f(`review-step`).setAttribute(`aria-current`,`step`)):(f(`configure-step`).setAttribute(`aria-current`,`step`),f(`review-step`).removeAttribute(`aria-current`),f(`preview-skill`).open=!1,f(`preview-mcp`).open=!1);let t=L?S[C(L)]:void 0;f(`preview-name`).textContent=L&&I?I.name.trim():``,f(`preview-parent`).textContent=L&&I?q(I.main_agent_profile_id):``,f(`preview-workers`).textContent=L&&I?I.worker_profile_ids.map(q).join(`, `):``;for(let[e,t]of[[`preview-manifest`,L?.manifest_path],[`preview-skill-path`,L?.skill_path],[`preview-mcp-path`,L?.mcp_path],[`preview-hook-path`,L?.hook_path]]){let n=t?m(t):``,r=f(e);r.textContent=r.title=n}f(`preview-write-policy`).textContent=t?e(t.label):``,f(`preview-write-detail`).textContent=t?e(t.detail):``,f(`preview-skill-content`).textContent=L?.skill_content??``,f(`preview-mcp-content`).textContent=L?.mcp_content??``,f(`preview-hook-content`).textContent=L?.hook_content??``;let n=L?.cleanup??[];f(`preview-cleanup`).hidden=n.length===0,f(`preview-cleanup-items`).replaceChildren(...n.map(({path:t,entry:n})=>{let r=p(`div`,``,`preview-file`),i=w[n],a=p(`code`,m(t));return a.title=a.textContent,r.append(p(`strong`,i?e(i):n),a),r}))}function X(){L=void 0,H=void 0,Y(),Z(),J()}function Z(){let t=I?R?H:{message:`schedulerNeeded`}:void 0,n=t?.detail??``;M.textContent!==n&&(j.open=!1),k.hidden=!t,k.dataset.error=String(!!n),A.textContent=t?e(t.message):``,j.hidden=!n,M.textContent=n,N.dataset.complete=String(!I&&(H?.message===`projectSaved`||H?.message===`projectUpdated`||H?.message===`projectSavedNativeClaude`)),h(N,e,I?void 0:H)}function Q(){if(o.replaceChildren(...P.map(t=>{let r=p(`div`,``,`project-row`),i=p(`button`,``,`dispatch-entry`);i.type=`button`,i.disabled=z||!R,i.append(p(`strong`,t.config.name),p(`span`,m(t.root))),i.addEventListener(`click`,()=>n(t.config.project_id));let a=p(`button`,e(`configureProject`),`text-button`);return a.type=`button`,a.disabled=z||!R,a.setAttribute(`aria-label`,`${e(`configureProject`)} · ${m(t.root)}`),a.addEventListener(`click`,()=>{te(t.root)}),r.append(i,a),r})),f(`project-home`).hidden=!!I,f(`project-setup`).hidden=!I,f(`project-empty`).hidden=!R||z||!!V||P.length>0,I){f(`project-setup-title`).textContent=e(I.registered?`projectEditTitle`:`chooseProject`),f(`project-registered-note`).hidden=!I.registered,D.textContent=e(I.registered?`saveProjectChanges`:`applyProject`),c.textContent=m(I.root),l.value=I.name;let t=U(),n=I.main_agent_profile_id,r=t.map(({profile_id:e,kind:t})=>new Option(K(e,t),e));n&&!t.some(e=>e.profile_id===n)&&r.unshift(new Option(`${K(n)} · ${e(`missingWorker`)}`,n)),u.replaceChildren(...r),u.value=n;let i=G(),a=I.worker_profile_ids.filter(e=>!i.some(t=>t.profile_id===e)),o=i.map(({profile_id:e,kind:t})=>({id:e,caption:K(e,t)}));for(let t of a)o.push({id:t,caption:`${K(t)} · ${e(`missingWorker`)}`});g.replaceChildren(...o.map(({id:e,caption:t})=>{let n=p(`label`,``,`worker-option`),r=document.createElement(`input`);return r.type=`checkbox`,r.value=e,r.checked=I?.worker_profile_ids.includes(e)??!1,r.addEventListener(`change`,()=>{I&&(I.worker_profile_ids=Array.from(g.querySelectorAll(`input:checked`),e=>e.value),X())}),n.append(r,p(`span`,t)),n})),i.length===0&&g.append(p(`p`,e(`noWorkers`),`empty-state`))}h(f(`projects-notice`),e,R?V:{message:`schedulerNeeded`}),Z(),Y(),J()}async function $(){if(!(!R||z||B)){z=!0,V={message:`loading`},Q();try{P=await d(`projects_list`),t(P),V=void 0,B=!0}catch(e){V={message:`projectsLoadError`,detail:String(e)}}finally{z=!1,Q()}}}async function ee(){try{if(F=await d(`agent_profiles`),I){I.main_agent_profile_id||(I.main_agent_profile_id=U()[0]?.profile_id??``);let e=G();I.worker_profile_ids=I.worker_profile_ids.filter(t=>e.some(e=>e.profile_id===t))}}catch(e){H={message:`agentLoadError`,detail:String(e)}}}async function te(e){if(z||!R)return;z=!0,H=void 0,V={message:`loading`},Q();let t=!e;try{let n=e??await d(`choose_project_folder`);t=!1,n&&(I=await d(`project_read`,{root:n}),L=void 0,F=[],await ee()),V=void 0}catch(e){V={message:t?`projectBrowseError`:`projectLoadError`,detail:String(e)}}finally{z=!1,Q(),I&&!V&&l.focus()}}i.addEventListener(`click`,()=>{te()}),a.addEventListener(`click`,()=>{I=void 0,L=void 0,H=void 0,Q(),i.focus()}),E.addEventListener(`click`,()=>{X(),l.focus()}),l.addEventListener(`input`,()=>{I&&(I.name=l.value),X()}),u.addEventListener(`change`,()=>{if(!I)return;let e=u.value;I.main_agent_profile_id=e,I.worker_profile_ids=I.worker_profile_ids.filter(t=>{let n=F.find(e=>e.profile_id===t);return!n||!W(n,e)}),L=void 0,H=void 0,Q()});for(let e of _)e.addEventListener(`change`,()=>{I&&e.checked&&(I.allow_workspace_write=e.value!==`read_only`,I.allow_project_write=e.value===`project_write`,X())});return O.addEventListener(`click`,async()=>{!z&&R&&(z=!0,L=void 0,H={message:`loading`},Q(),await ee(),H?.message===`loading`&&(H=void 0),z=!1,Q())}),s.addEventListener(`submit`,async e=>{if(e.preventDefault(),I&&!v.disabled){z=!0,L=void 0,H={message:`loading`},Q();try{let e=await d(`project_preview`,{input:{...I,name:I.name.trim()}});R&&(L=e),H=void 0}catch(e){H=T(`projectPreviewError`,e)}finally{z=!1,Q(),L?f(`preview-title`).focus():H?.detail&&k.focus()}}}),D.addEventListener(`click`,async()=>{if(!L||!I||D.disabled)return;let e=L.token,n=!!L.hook_path,r=I.registered;L=void 0,z=!0,H={message:`saving`},Q();try{let i=await d(`project_apply`,{token:e});i.main_agent_kind=F.find(e=>e.profile_id===i.config.main_agent_profile_id)?.kind,P=[...P.filter(e=>e.config.project_id!==i.config.project_id),i],P.sort((e,t)=>e.config.name.localeCompare(t.config.name)),t(P),I=void 0,H={message:n?`projectSavedNativeClaude`:r?`projectUpdated`:`projectSaved`}}catch(e){H=T(`projectSaveError`,e)}finally{z=!1,Q(),I?H?.detail&&k.focus():i.focus()}}),{render:Q,refresh:$,setReady(e){R!==e&&(R=e,R||(B=!1,L=void 0),Q(),r.hidden||$())}}}var D=f(`status`),O=f(`detail`),k=f(`indicator`),A=f(`channel`),j=f(`refresh`),M=f(`start`),N=f(`stop`),P=f(`language-setting`),F=f(`settings-message`),I,L=b(`system`,navigator.language),R,z,B,V,H=e=>y[L][e],U=v(H),W=E(H,U.setProjects,e=>{U.selectProject(e),Y(`history`)});function G(e){return`${H(`technicalDetails`)} — ${e}`}function K(){let e=R?.status===`ready`?R.health:void 0,t=R?.channel===`development`;A.hidden=!t,A.textContent=t?H(`development`):``,f(`version`).textContent=e?.version??`—`,f(`protocol`).textContent=e?.protocol_version.toString()??`—`,f(`workers`).textContent=e?.active_workers.toString()??`—`;let n=B??(R?.status===`error`?R.detail:void 0),r=z?`pending`:n?`error`:R?.status??`pending`;k.dataset.status=r;let i={ready:`railReady`,offline:`railOffline`,error:`railError`,pending:`railPending`};switch(f(`rail-status`).textContent=H(i[r]),M.hidden=r===`ready`||r===`pending`,M.textContent=H(r===`error`?`retry`:`start`),N.hidden=c||r!==`ready`,r){case`pending`:D.textContent=H(z===`start_service`?`starting`:z===`stop_service`?`stopping`:`checking`),O.textContent=``;break;case`ready`:D.textContent=H(`running`),O.textContent=H(`runningDetail`);break;case`offline`:D.textContent=H(`offline`),O.textContent=H(`offlineDetail`);break;case`error`:D.textContent=H(`connectionError`),O.textContent=n?G(n):``}}async function q(e){z=e,j.disabled=M.disabled=N.disabled=!0,K();try{R=await d(e),B=void 0}catch(e){R=void 0,B=String(e)}finally{z=void 0,j.disabled=M.disabled=N.disabled=!1,K();let e=R?.status===`ready`;U.setReady(e),W.setReady(e)}}j.addEventListener(`click`,()=>{q(`service_status`)}),M.addEventListener(`click`,()=>{q(`start_service`)}),c||N.addEventListener(`click`,()=>{q(`stop_service`)});var J=[`projects`,`history`,`overview`,`settings`];function Y(e){for(let t of J){f(t).hidden=t!==e;let n=f(`${t}-nav`);t===e?n.setAttribute(`aria-current`,`page`):n.removeAttribute(`aria-current`)}e===`history`&&U.open(),e===`projects`&&W.refresh()}for(let e of J)f(`${e}-nav`).addEventListener(`click`,()=>Y(e));function X(){F.textContent=V?`${H(V.message)}${V.detail?` ${G(V.detail)}`:``}`:``}function Z(e){L=b(e,navigator.language),document.documentElement.lang=L;for(let e of document.querySelectorAll(`[data-i18n]`))e.textContent=H(e.dataset.i18n);for(let e of document.querySelectorAll(`[data-i18n-label]`))e.setAttribute(`aria-label`,H(e.dataset.i18nLabel));K(),X(),U.render(),W.render()}function Q(e){P.value=e.language,Z(e.language)}async function $(e){if(I){P.disabled=!0,V={message:`saving`},Q(e);try{await d(`set_preferences`,{preferences:e}),I=e,V={message:`saved`}}catch(e){V={message:`preferencesWriteError`,detail:String(e)},Q(I)}finally{P.disabled=!1,X()}}}P.addEventListener(`change`,()=>{$({language:P.value})});async function ee(){let e=q(`start_service`);try{I=await d(`get_preferences`),Q(I),P.disabled=!1}catch(e){V={message:`preferencesReadError`,detail:String(e)},X()}await e}Z(`system`),ee();
@@ -0,0 +1 @@
1
+ :root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;color:#25283a;--canvas:#fdfcfa;--rail:#efedf3;--surface:#f5f4f8;--quiet:#646879;--line:#dedde5;--accent:#4945a9;--accent-hover:#38358e;--accent-wash:#e8e5f7;--error:#a43236;background:#fdfcfa;height:100%;font:14px/1.5 Segoe UI,system-ui,sans-serif}*{box-sizing:border-box}body{height:100%;margin:0;overflow:hidden}.app-shell{grid-template:minmax(0,1fr)/188px minmax(0,1fr);height:100%;display:grid}[hidden]{display:none!important}.app-header{border-right:1px solid var(--line);background:var(--rail);flex-direction:column;grid-area:1/1;gap:25px;min-height:0;padding:25px 14px 16px;display:flex;overflow-y:auto}.wordmark{letter-spacing:-.025em;align-items:center;gap:9px;padding:0 6px;font-size:17px;font-weight:670;display:flex}.brand-icon{background:var(--accent);border-radius:8px;flex:none;width:30px;height:30px}.brand-icon path{fill:none;stroke:#fff;stroke-width:2px;stroke-linecap:square;stroke-linejoin:round}.app-header nav{gap:3px;display:grid}.app-header .nav-button{min-height:40px;color:var(--quiet);text-align:left;background:0 0;align-items:center;gap:9px;padding:7px 9px;font-weight:600;display:flex}.app-header .nav-button:not([aria-current=page]):hover:not(:disabled){color:#25283a;background:#e5e3ec}.app-header .nav-button[aria-current=page]{background:var(--accent-wash);color:var(--accent)}.nav-button svg,.add-button svg,.text-button svg,.empty-icon svg{fill:none;stroke:currentColor;stroke-width:1.6px;stroke-linecap:round;stroke-linejoin:round;flex:none;width:18px;height:18px}.header-status{border-top:1px solid var(--line);align-items:flex-start;gap:9px;margin-top:auto;padding:13px 6px 0;display:flex}.rail-status,.channel{font-size:12px;display:block}.rail-status{font-weight:600}.channel{color:var(--quiet)}.indicator{background:#85889a;border-radius:50%;flex:none;width:7px;height:7px;margin-top:6px;transition:background-color .16s}.indicator[data-status=ready]{background:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}.indicator[data-status=error]{background:var(--error)}.indicator[data-status=pending]{animation:1s infinite alternate pulse}main{scrollbar-gutter:stable;grid-area:1/2;min-width:0;min-height:0;padding:36px 37px 32px;overflow-y:auto}main>section{max-width:950px;margin-inline:auto;animation:.18s ease-out both enter}.section-heading{justify-content:space-between;align-items:center;gap:16px;margin-bottom:24px;display:flex}.section-heading>div{min-width:0}h1{letter-spacing:-.045em;margin:0;font-size:33px;font-weight:680;line-height:1.16}h2{margin:0 0 8px;font-size:16px;font-weight:650}h3{margin:0;font-size:14px;font-weight:650}p{color:var(--quiet);margin:5px 0 0}strong{font-weight:650}button{background:var(--accent);color:#fff;cursor:pointer;white-space:nowrap;border:1px solid #0000;border-radius:6px;min-height:35px;padding:6px 12px;font:600 13px/1.4 Segoe UI,system-ui,sans-serif;transition:background-color .15s,border-color .15s,color .15s}button:hover:not(:disabled){background:var(--accent-hover)}button.secondary{color:inherit;background:var(--canvas);border-color:var(--line)}button.secondary:hover:not(:disabled){background:var(--surface);border-color:#c9c7d7}button:disabled{opacity:.5;cursor:default}button:focus-visible,input:focus-visible,select:focus-visible,summary:focus-visible,pre:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.add-button,.text-button{align-items:center;gap:6px;display:inline-flex}button.text-button{color:var(--accent);background:0 0}button.text-button:hover:not(:disabled){background:var(--accent-wash)}#close-project-setup{min-height:29px;color:var(--quiet);margin:-5px 0 5px -7px;padding-inline:7px}#close-project-setup:hover:not(:disabled){color:var(--accent)}#close-project-setup svg{width:16px;height:16px}.list-heading{border-bottom:1px solid var(--line);color:var(--quiet);margin:0;padding:10px 0;font-size:13px}.entry-list{display:grid}.dispatch-entry{border:0;border-bottom:1px solid var(--line);text-align:left;white-space:normal;overflow-wrap:anywhere;min-width:0;color:inherit;background:0 0;border-radius:0;gap:3px;padding:10px 25px 10px 9px;display:grid;position:relative}.dispatch-entry:after{border:solid var(--quiet);content:"";border-width:1px 1px 0 0;width:5px;height:5px;position:absolute;top:50%;right:8px;transform:translateY(-50%)rotate(45deg)}.dispatch-entry:hover:not(:disabled),.dispatch-entry[aria-pressed=true]{color:inherit;background:var(--accent-wash)}.dispatch-entry span{color:var(--quiet);font-size:12px;font-weight:400}.project-row{border-bottom:1px solid var(--line);grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;display:grid}.project-row .dispatch-entry{border-bottom:0;padding:12px 30px 12px 9px}.project-empty{text-align:center;border-bottom:1px solid var(--line);align-content:center;justify-items:center;min-height:208px;padding:28px 18px;display:grid}.project-empty h3{margin-top:11px;font-size:16px}.project-empty p{max-width:36ch}.empty-icon{width:43px;height:43px;color:var(--accent);background:var(--accent-wash);border-radius:11px;place-items:center;display:grid}.empty-icon svg{width:23px;height:23px}.notice,.settings-message{min-height:1.5em;font-size:13px}.notice:empty,.settings-message:empty{display:none}.notice[data-error=true]{color:var(--error);overflow-wrap:anywhere}#projects-notice{margin:-10px 0 11px}#project-feedback{margin-top:14px}#project-feedback[data-complete=true]{border-left:2px solid var(--accent);background:var(--accent-wash);color:var(--accent-hover);padding:9px 12px}.setup-feedback{border-left:2px solid var(--accent);background:var(--surface);margin-bottom:16px;padding:9px 13px}.setup-feedback[data-error=true]{border-color:var(--error);background:#f9efef}.setup-feedback p{color:inherit;margin:0;font-weight:600}.setup-feedback summary{color:var(--quiet);cursor:pointer;margin-top:5px;font-size:13px}.setup-feedback code{color:var(--quiet);overflow-wrap:anywhere;margin-top:4px;display:block}.project-setup-header{margin-bottom:20px}.setup-titlebar{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 15px;display:flex}.setup-steps{align-items:center;gap:11px;margin:0;padding:0;list-style:none;display:flex}.setup-steps li{color:var(--quiet);align-items:center;gap:5px;font-size:12px;display:inline-flex}.setup-steps li+li:before{content:"";border-top:1px solid var(--line);width:13px;margin-right:4px}.setup-steps li b{font-weight:600}.setup-steps li span{background:var(--surface);border-radius:50%;place-items:center;width:20px;height:20px;transition:background-color .15s;display:inline-grid}.setup-steps li[aria-current=step]{color:var(--accent)}.setup-steps li[aria-current=step] span{background:var(--accent);color:#fff}.project-location{background:var(--surface);border-radius:7px;grid-template-columns:22px minmax(0,1fr);align-items:center;gap:9px;margin-top:11px;padding:8px 11px;display:grid}.project-location svg{width:18px;height:18px;color:var(--accent);fill:none;stroke:currentColor;stroke-width:1.5px;stroke-linecap:round;stroke-linejoin:round}.project-location span{color:var(--quiet);font-size:11px;font-weight:650;display:block}.project-location code{overflow-wrap:anywhere;font:12px/1.45 Consolas,monospace;display:block}.project-fields{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);gap:13px;display:grid}#project-form .field{gap:4px;min-width:0;display:grid}#project-form .field label,.history-filter>span{color:var(--quiet);font-size:13px;font-weight:600}#project-form .field input,select{background:var(--canvas);min-width:0;min-height:34px;color:inherit;font:inherit;border:1px solid #c9c7d7;border-radius:6px;padding:5px 9px}#project-form .field input,#project-form .field select{min-height:40px}.project-workers{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:8px;margin:16px 0 18px;display:grid}.project-workers .text-button{min-height:27px;margin-right:-7px;padding:3px 7px;font-size:12px}.worker-picker,.permission-group{border:0;min-width:0;margin:0;padding:0}.worker-picker legend,.permission-group legend{padding:0;font-weight:650}#worker-agents{flex-wrap:wrap;gap:2px 15px;display:flex}.worker-option{overflow-wrap:anywhere;cursor:pointer;align-items:center;gap:6px;min-width:0;padding:4px 0;display:flex}.worker-option input,.permission-option input{width:16px;height:16px;accent-color:var(--accent);flex:none;margin:0}#worker-hint{font-size:12px}.permission-group>p{margin:1px 0 7px;font-size:12px}.permission-options{border:1px solid var(--line);border-radius:7px}.permission-option{cursor:pointer;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:11px;padding:10px 13px;transition:background-color .15s;display:grid}.permission-option:first-child{border-radius:6px 6px 0 0}.permission-option:last-child{border-radius:0 0 6px 6px}.permission-option+.permission-option{border-top:1px solid var(--line)}.permission-option:hover:not(:has(input:disabled)){background:var(--surface)}.permission-option:has(input:disabled){cursor:default}.permission-option:has(input:checked){background:var(--accent-wash)}.permission-option strong,.permission-option small{display:block}.permission-option small{color:var(--quiet);font-size:12px}.setup-actions{border-top:1px solid var(--line);flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:12px;padding:10px 0 2px;display:flex}.actions{margin-top:12px}.actions:not(:has(>:not([hidden]))){display:none}#project-form,#project-preview{animation:.16s ease-out both enter}#project-preview h2{margin-bottom:2px}#project-preview h2:focus{outline:none}#project-preview>p{margin-top:2px}.review-summary{background:var(--surface);border-radius:7px;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px 14px;margin:10px 0;padding:9px 11px;display:grid}.review-summary dd{margin-top:1px;font-family:inherit;font-weight:650}.review-summary dd small{color:var(--quiet);font-size:12px;font-weight:400;display:block}.preview-files{border-top:1px solid var(--line);margin-top:12px}.preview-cleanup{margin-top:12px}.preview-cleanup .preview-files{margin-top:4px}.preview-file,.preview-files details{border-bottom:1px solid var(--line)}.preview-file,.preview-files summary{padding:7px 0}.preview-files summary{cursor:pointer;padding-right:19px;list-style:none;position:relative}.preview-files summary::-webkit-details-marker{display:none}.preview-files summary:after{content:"";border:solid var(--quiet);border-width:0 1px 1px 0;width:5px;height:5px;transition:transform .15s;position:absolute;top:15px;right:5px;transform:rotate(45deg)}.preview-files details[open] summary:after{transform:rotate(225deg)}.preview-files summary:hover{color:var(--accent)}.preview-files strong,.preview-files code{display:block}.preview-files code{overflow-wrap:anywhere;color:var(--quiet);font:12px/1.4 Consolas,monospace}#project-preview .task-text{max-height:175px;margin-bottom:8px}.preview-files details[open] .task-text{animation:.15s ease-out both enter}.history-tools{border-bottom:1px solid var(--line);grid-template-columns:minmax(0,1fr) minmax(0,1.6fr) auto;align-items:end;gap:9px;padding-bottom:14px;display:grid}.history-filter{gap:3px;min-width:0;display:grid}.history-filter select{width:100%;font-size:13px}#resume-claude-session{grid-column:2;justify-self:start;min-height:25px;margin:-4px 0 0 -7px;padding:3px 7px;font-size:12px}.workspace-grid{grid-template-columns:minmax(150px,1fr) minmax(0,1.8fr);gap:21px;margin-top:16px;display:grid}.workspace-grid:has(.detail-pane[hidden]){grid-template-columns:1fr}.detail-pane{border-left:1px solid var(--line);min-width:0;padding-left:20px}.empty-state{padding:10px 0}.load-more{margin-top:9px}.task-heading{margin-bottom:0}.task-readout{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 15px;margin:7px 0 15px;display:grid}dt{color:var(--quiet);font-size:12px}dd{overflow-wrap:anywhere;margin:3px 0 0;font-family:Consolas,monospace}#task-content h3{margin:12px 0 4px}.task-text{background:var(--surface);border:1px solid var(--line);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:5px;max-height:360px;margin:0;padding:8px 10px;font:12px/1.5 Consolas,monospace;overflow:auto}.task-result-list{overflow-wrap:anywhere;margin:0;padding-left:20px}.connection{border-bottom:1px solid var(--line);padding:10px 0 17px}.connection-status{font-size:16px}.readout{grid-template-columns:repeat(3,minmax(0,1fr));margin:0;display:grid}.readout>div{border-bottom:1px solid var(--line);padding:12px 10px 12px 0}.setting-row{border-block:1px solid var(--line);justify-content:space-between;align-items:center;gap:18px;padding:12px 0;display:flex}.setting-row label{font-weight:600}.setting-row p{font-size:13px}.setting-row select{min-width:144px;max-width:50%}.setting-row+h2{margin-top:25px}.settings-message{margin-top:10px}@keyframes enter{0%{opacity:0;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse{0%{opacity:.4}to{opacity:1}}@media (width<=740px){.app-shell{grid-template-columns:148px minmax(0,1fr)}.app-header{gap:19px;padding-inline:8px}.app-header .nav-button{gap:6px;padding-inline:6px}.nav-button svg{width:16px;height:16px}main{padding:23px 21px 25px}h1{font-size:29px}.section-heading{gap:10px}.history-tools{grid-template-columns:repeat(2,minmax(0,1fr))}.history-tools>button{justify-self:start}.workspace-grid{grid-template-columns:1fr;gap:14px}.detail-pane{border-left:0;border-top:1px solid var(--line);padding:12px 0 0}}@media (width<=680px){.project-setup-header{margin-bottom:13px}.project-fields,.review-summary{column-gap:9px}.setup-steps{gap:7px}.setup-steps li+li:before{width:8px;margin-right:2px}}@media (height<=560px){main:has(>#projects:not([hidden]) #project-setup:not([hidden])){padding-block:15px 12px}#close-project-setup{min-height:24px;margin-bottom:3px}.project-setup-header{margin-bottom:10px}.setup-titlebar h1{font-size:26px}.project-location{margin-top:8px;padding-block:6px}#project-form .field input,#project-form .field select{min-height:34px}.project-workers{margin:9px 0 11px}.permission-option{padding-block:4px}.review-summary{row-gap:5px;padding-block:7px}.preview-files{margin-top:8px}.preview-file,.preview-files summary{padding-block:5px}.preview-files code{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.setup-actions{margin-top:8px;padding-top:8px}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none!important;animation:none!important}}
package/web/index.html ADDED
@@ -0,0 +1,274 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <link rel="icon" type="image/svg+xml" href="/assets/icon-GvZv3lcu.svg" />
7
+ <title>Runspur</title>
8
+ <script type="module" crossorigin src="/assets/index-BOjpYd69.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-WDh3hQ5S.css">
10
+ </head>
11
+ <body>
12
+ <div class="app-shell">
13
+ <header class="app-header">
14
+ <div class="wordmark">
15
+ <svg class="brand-icon" viewBox="0 0 32 32" aria-hidden="true">
16
+ <path d="M9 23V9h10l4 4-4 4h-4l8 6M15 13h4" />
17
+ </svg>
18
+ <span>Runspur</span>
19
+ </div>
20
+ <nav aria-label="Runspur">
21
+ <button id="projects-nav" class="nav-button" type="button" aria-current="page">
22
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 7V5h6l2 2h9v12H3Z" /></svg>
23
+ <span data-i18n="projects">Projects</span>
24
+ </button>
25
+ <button id="history-nav" class="nav-button" type="button">
26
+ <svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8" /><path d="M12 7.5V12l3 2" /></svg>
27
+ <span data-i18n="history">Dispatch history</span>
28
+ </button>
29
+ <button id="overview-nav" class="nav-button" type="button">
30
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 13h4l3-6 4 10 3-4h4" /></svg>
31
+ <span data-i18n="overview">Overview</span>
32
+ </button>
33
+ <button id="settings-nav" class="nav-button" type="button">
34
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16M8 5v4m8 1v4m-5 1v4" /></svg>
35
+ <span data-i18n="settings">Settings</span>
36
+ </button>
37
+ </nav>
38
+ <div class="header-status" aria-live="polite">
39
+ <span id="indicator" class="indicator" aria-hidden="true"></span>
40
+ <div>
41
+ <span id="rail-status" class="rail-status">Connecting</span>
42
+ <span class="channel" id="channel" hidden></span>
43
+ </div>
44
+ </div>
45
+ </header>
46
+
47
+ <main>
48
+ <section id="projects" aria-label="Projects" data-i18n-label="projects">
49
+ <div id="project-home">
50
+ <div class="section-heading">
51
+ <div>
52
+ <h1 id="projects-title" data-i18n="projects">Projects</h1>
53
+ <p data-i18n="projectsIntro">Manage project integrations and dispatch history.</p>
54
+ </div>
55
+ <button id="choose-project" type="button" class="add-button" disabled>
56
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
57
+ <span data-i18n="chooseProject">Add project</span>
58
+ </button>
59
+ </div>
60
+ <p id="projects-notice" class="notice" aria-live="polite"></p>
61
+ <h2 class="list-heading" data-i18n="registeredProjects">Registered projects</h2>
62
+ <div id="project-list" class="entry-list project-list"></div>
63
+ <div id="project-empty" class="project-empty" hidden>
64
+ <span class="empty-icon" aria-hidden="true">
65
+ <svg viewBox="0 0 24 24"><path d="M3 7V5h6l2 2h9v12H3Z" /></svg>
66
+ </span>
67
+ <h3 data-i18n="noProjects">No projects yet</h3>
68
+ <p data-i18n="projectEmpty">Choose a folder to configure its agents and track its dispatches here.</p>
69
+ </div>
70
+ </div>
71
+ <section id="project-setup" aria-labelledby="project-setup-title" hidden>
72
+ <header class="project-setup-header">
73
+ <button id="close-project-setup" class="text-button" type="button">
74
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="m13 6-6 6 6 6M7 12h13" /></svg>
75
+ <span data-i18n="backToProjects">Back to projects</span>
76
+ </button>
77
+ <div class="setup-titlebar">
78
+ <h1 id="project-setup-title">Add project</h1>
79
+ <ol class="setup-steps" aria-label="Setup" data-i18n-label="projectSetup">
80
+ <li id="configure-step" aria-current="step"><span aria-hidden="true">1</span><b data-i18n="projectConfiguration">Configure</b></li>
81
+ <li id="review-step"><span aria-hidden="true">2</span><b data-i18n="projectReview">Review</b></li>
82
+ </ol>
83
+ </div>
84
+ <div class="project-location">
85
+ <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 7V5h6l2 2h9v12H3Z" /></svg>
86
+ <div>
87
+ <span data-i18n="projectFolder">Project folder</span>
88
+ <code id="project-root"></code>
89
+ </div>
90
+ </div>
91
+ <p id="project-registered-note" class="notice" data-i18n="projectAlreadyConnected" hidden>This folder is already connected. Saving will update the existing project.</p>
92
+ </header>
93
+ <div id="project-setup-feedback" class="setup-feedback" tabindex="-1" hidden>
94
+ <p id="project-setup-message" aria-live="polite"></p>
95
+ <details id="project-setup-details" hidden>
96
+ <summary data-i18n="technicalDetails">Technical details</summary>
97
+ <code id="project-setup-error"></code>
98
+ </details>
99
+ </div>
100
+ <form id="project-form" hidden>
101
+ <div class="project-fields">
102
+ <div class="field">
103
+ <label for="project-name" data-i18n="projectName">Project name</label>
104
+ <input id="project-name" type="text" required />
105
+ </div>
106
+ <div class="field">
107
+ <label for="parent-agent" data-i18n="parentAgent">Main agent</label>
108
+ <select id="parent-agent" required></select>
109
+ </div>
110
+ </div>
111
+ <div class="project-workers">
112
+ <fieldset class="worker-picker" aria-describedby="worker-hint">
113
+ <legend data-i18n="workerAgents">Worker agents</legend>
114
+ <div id="worker-agents"></div>
115
+ <p id="worker-hint" data-i18n="chooseWorker" hidden>Select at least one available worker agent.</p>
116
+ </fieldset>
117
+ <button id="refresh-agents" type="button" class="text-button" data-i18n="refreshAgents">Refresh agents</button>
118
+ </div>
119
+ <fieldset id="worker-file-access" class="permission-group" aria-describedby="worker-access-hint">
120
+ <legend data-i18n="workerWritePolicy">Worker file access</legend>
121
+ <p id="worker-access-hint" data-i18n="workerAccessHint" aria-live="polite">Worker changes are collected for review.</p>
122
+ <div class="permission-options">
123
+ <label class="permission-option">
124
+ <input type="radio" name="worker-access" value="read_only" checked aria-labelledby="read-only-label" aria-describedby="read-only-hint" />
125
+ <span><strong id="read-only-label" data-i18n="workerReadOnly">Read only</strong><small id="read-only-hint" data-i18n="workerReadOnlyHint">Inspect project files and report findings.</small></span>
126
+ </label>
127
+ <label class="permission-option">
128
+ <input type="radio" name="worker-access" value="workspace_write" aria-labelledby="scoped-write-label" aria-describedby="scoped-write-hint" />
129
+ <span><strong id="scoped-write-label" data-i18n="workerScopedWrite">Specified files</strong><small id="scoped-write-hint" data-i18n="workerScopedWriteHint">Edit task-listed files in an isolated workspace.</small></span>
130
+ </label>
131
+ <label class="permission-option">
132
+ <input type="radio" name="worker-access" value="project_write" aria-labelledby="project-write-label" aria-describedby="project-write-hint" />
133
+ <span><strong id="project-write-label" data-i18n="workerProjectWrite">Project-wide text edits</strong><small id="project-write-hint" data-i18n="workerProjectWriteHint">Edit text across an isolated project workspace.</small></span>
134
+ </label>
135
+ </div>
136
+ </fieldset>
137
+ <div class="setup-actions">
138
+ <button id="preview-project" type="submit" data-i18n="previewProject">Preview integration</button>
139
+ </div>
140
+ </form>
141
+ <section id="project-preview" aria-labelledby="preview-title" hidden>
142
+ <h2 id="preview-title" data-i18n="previewProject" tabindex="-1">Preview integration</h2>
143
+ <p data-i18n="integrationScope">Confirm to save the project manifest, Skill and main agent configuration.</p>
144
+ <dl class="review-summary">
145
+ <div><dt data-i18n="projectName">Project name</dt><dd id="preview-name"></dd></div>
146
+ <div><dt data-i18n="parentAgent">Main agent</dt><dd id="preview-parent"></dd></div>
147
+ <div><dt data-i18n="workerAgents">Worker agents</dt><dd id="preview-workers"></dd></div>
148
+ <div>
149
+ <dt data-i18n="workerWritePolicy">Worker file access</dt>
150
+ <dd><span id="preview-write-policy"></span><small id="preview-write-detail"></small></dd>
151
+ </div>
152
+ </dl>
153
+ <div class="preview-files">
154
+ <div class="preview-file">
155
+ <strong data-i18n="projectManifest">Project manifest</strong>
156
+ <code id="preview-manifest"></code>
157
+ </div>
158
+ <details id="preview-skill">
159
+ <summary>
160
+ <strong data-i18n="projectSkill">Skill</strong>
161
+ <code id="preview-skill-path"></code>
162
+ </summary>
163
+ <pre id="preview-skill-content" class="task-text" tabindex="0"></pre>
164
+ </details>
165
+ <details id="preview-mcp">
166
+ <summary>
167
+ <strong data-i18n="projectMcp">Runspur MCP entry</strong>
168
+ <code id="preview-mcp-path"></code>
169
+ </summary>
170
+ <pre id="preview-mcp-content" class="task-text" tabindex="0"></pre>
171
+ </details>
172
+ <details id="preview-hook" hidden>
173
+ <summary>
174
+ <strong data-i18n="projectClaudeHook">Claude Code project hook</strong>
175
+ <code id="preview-hook-path"></code>
176
+ </summary>
177
+ <pre id="preview-hook-content" class="task-text" tabindex="0"></pre>
178
+ </details>
179
+ </div>
180
+ <section id="preview-cleanup" class="preview-cleanup" aria-labelledby="preview-cleanup-title" hidden>
181
+ <h3 id="preview-cleanup-title" data-i18n="projectCleanup">Previous integration entries to remove</h3>
182
+ <div id="preview-cleanup-items" class="preview-files"></div>
183
+ </section>
184
+ <div class="setup-actions">
185
+ <button id="edit-project" class="secondary" type="button" data-i18n="editProject">Edit configuration</button>
186
+ <button id="apply-project" type="button">Confirm and connect</button>
187
+ </div>
188
+ </section>
189
+ </section>
190
+ <p id="project-feedback" class="notice" aria-live="polite"></p>
191
+ </section>
192
+ <section id="history" aria-labelledby="history-title" hidden>
193
+ <div class="section-heading">
194
+ <div>
195
+ <h1 id="history-title" data-i18n="history">Dispatch history</h1>
196
+ <p data-i18n="historyIntro">Inspect each dispatch, its execution, and delivery back to the main agent.</p>
197
+ </div>
198
+ <button id="refresh-history" class="secondary" type="button" data-i18n="refresh">Refresh</button>
199
+ </div>
200
+ <div class="history-tools">
201
+ <label class="history-filter" for="history-project">
202
+ <span data-i18n="filterProject">Project</span>
203
+ <select id="history-project" disabled></select>
204
+ </label>
205
+ <label class="history-filter" for="history-session">
206
+ <span data-i18n="filterSession">Session</span>
207
+ <select id="history-session" disabled></select>
208
+ </label>
209
+ <button id="load-sessions" class="secondary" type="button" data-i18n="olderSessions" hidden>Load older sessions</button>
210
+ <button id="resume-claude-session" class="text-button" type="button" data-i18n="resumeClaudeSession" hidden>Resume Claude session</button>
211
+ </div>
212
+ <p id="history-notice" class="notice" aria-live="polite"></p>
213
+ <div class="workspace-grid history-grid">
214
+ <div class="master-pane">
215
+ <h2 data-i18n="dispatches">Dispatches</h2>
216
+ <div id="history-list" class="entry-list"></div>
217
+ <button id="load-history" class="secondary load-more" type="button" data-i18n="olderDispatches" hidden>Load older dispatches</button>
218
+ </div>
219
+ <div class="detail-pane" id="history-inspector" hidden>
220
+ <p id="task-empty" class="empty-state" data-i18n="taskEmpty">Select a dispatch to see its prompt, result, and delivery details.</p>
221
+ <article id="task-detail" hidden>
222
+ <div class="section-heading task-heading">
223
+ <h2 data-i18n="dispatchDetails">Dispatch details</h2>
224
+ <button id="cancel-task" class="secondary danger" type="button" data-i18n="cancelTask" hidden>Cancel dispatch</button>
225
+ </div>
226
+ <p id="task-notice" class="notice" aria-live="polite"></p>
227
+ <div id="task-content"></div>
228
+ </article>
229
+ </div>
230
+ </div>
231
+ </section>
232
+ <section id="overview" aria-labelledby="scheduler-title" hidden>
233
+ <div class="section-heading">
234
+ <h1 id="scheduler-title" data-i18n="localScheduler">Local scheduler</h1>
235
+ <button id="refresh" class="secondary" type="button" data-i18n="refresh" disabled>Refresh</button>
236
+ </div>
237
+ <div class="connection" aria-live="polite">
238
+ <div class="connection-status">
239
+ <strong id="status">Checking connection</strong>
240
+ </div>
241
+ <p id="detail">Checking the local Runspur scheduler.</p>
242
+ </div>
243
+ <dl class="readout">
244
+ <div><dt data-i18n="serviceVersion">Service version</dt><dd id="version">—</dd></div>
245
+ <div><dt data-i18n="protocol">Protocol</dt><dd id="protocol">—</dd></div>
246
+ <div><dt data-i18n="workers">Active workers</dt><dd id="workers">—</dd></div>
247
+ </dl>
248
+ <div class="actions">
249
+ <button id="start" type="button" hidden>Start scheduler</button>
250
+ <button id="stop" class="secondary" type="button" data-i18n="stop" hidden>Stop scheduler</button>
251
+ </div>
252
+ </section>
253
+ <section id="settings" aria-labelledby="settings-title" hidden>
254
+ <div class="section-heading">
255
+ <h1 id="settings-title" data-i18n="settings">Settings</h1>
256
+ </div>
257
+ <h2 data-i18n="application">Application</h2>
258
+ <div class="setting-row">
259
+ <div>
260
+ <label for="language-setting" data-i18n="language">Language</label>
261
+ <p id="language-hint" data-i18n="languageHint">Choose the language used by Runspur.</p>
262
+ </div>
263
+ <select id="language-setting" aria-describedby="language-hint" disabled>
264
+ <option value="system" data-i18n="systemLanguage">Use system language</option>
265
+ <option value="en" lang="en">English</option>
266
+ <option value="zh-CN" lang="zh-CN">简体中文</option>
267
+ </select>
268
+ </div>
269
+ <p id="settings-message" class="settings-message" aria-live="polite"></p>
270
+ </section>
271
+ </main>
272
+ </div>
273
+ </body>
274
+ </html>