@akira-tl/forgerelay 0.5.6 → 0.6.0
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/CHANGELOG.md +43 -0
- package/README.md +7 -3
- package/capabilities/host-integration/GUIDE.md +15 -9
- package/dist/activity/host-turn-store.js +9 -7
- package/dist/activity/lifecycle.js +1 -1
- package/dist/activity/mcp-query-tools.js +110 -18
- package/dist/activity/query-service.js +4 -4
- package/dist/activity/ui/contract.js +2 -0
- package/dist/cli.js +47 -32
- package/dist/config.js +31 -3
- package/dist/db/migrations.js +30 -0
- package/dist/db/schema.js +2 -0
- package/dist/logger.js +6 -5
- package/dist/lsp/test-support/server-fixture.js +1 -1
- package/dist/mcp/server-instructions.js +7 -6
- package/dist/mcp-app-template.js +108 -12
- package/dist/oauth/public-url.js +14 -0
- package/dist/oauth/router.js +49 -0
- package/dist/process-sessions.js +2 -1
- package/dist/request-meta.js +4 -0
- package/dist/server.js +250 -84
- package/dist/skills.js +58 -1
- package/dist/ui/.vite/manifest.json +360 -312
- package/dist/ui/activity-panel-app.html +17 -0
- package/dist/ui/assets/activity-panel-app-CjZVvVNc.js +2 -0
- package/dist/ui/assets/angular-html-BkgDQl-G.js +1 -0
- package/dist/ui/assets/{angular-ts-BwPE8YDt.js → angular-ts-Bxh4-O1-.js} +1 -1
- package/dist/ui/assets/{apl-CGbONVvU.js → apl-BmYHKQ6m.js} +1 -1
- package/dist/ui/assets/{astro-DIAPy7cj.js → astro-C51vqDKq.js} +1 -1
- package/dist/ui/assets/{blade-Cgtd19Ky.js → blade-CdhVsmwq.js} +1 -1
- package/dist/ui/assets/c-IBzBpxAO.js +1 -0
- package/dist/ui/assets/chunk-EyZ2wyi3.js +1 -0
- package/dist/ui/assets/{cobol-G-7HLVKW.js → cobol-Cf6azoN_.js} +1 -1
- package/dist/ui/assets/{coffee-DQFyKxEB.js → coffee-vVdGzlmt.js} +1 -1
- package/dist/ui/assets/cpp-CVHeO-Jk.js +1 -0
- package/dist/ui/assets/{crystal-DuiWhEO3.js → crystal-5UZy6KIX.js} +1 -1
- package/dist/ui/assets/css-DEfus9J5.js +1 -0
- package/dist/ui/assets/{edge-COkalhFi.js → edge-CESgo4ia.js} +1 -1
- package/dist/ui/assets/{elixir-cdlzbYR1.js → elixir-9FKfw4cJ.js} +1 -1
- package/dist/ui/assets/{elm-ZwDYuYpb.js → elm-Dv7A0aLa.js} +1 -1
- package/dist/ui/assets/{erb-C8WG9TtC.js → erb-DHFmDvM0.js} +1 -1
- package/dist/ui/assets/{git-rebase-CMlDVJBT.js → git-rebase-utbU6CzV.js} +1 -1
- package/dist/ui/assets/{glimmer-js-DeLOQlol.js → glimmer-js-t2kiCkyB.js} +1 -1
- package/dist/ui/assets/{glimmer-ts-DTEM04TK.js → glimmer-ts-F0Jv5okV.js} +1 -1
- package/dist/ui/assets/glsl-_ooCjaeB.js +1 -0
- package/dist/ui/assets/graphql-B9LqP-cY.js +1 -0
- package/dist/ui/assets/{hack-C14sh6Lh.js → hack-8yjdbaSA.js} +1 -1
- package/dist/ui/assets/haml-BU5EoZBn.js +1 -0
- package/dist/ui/assets/{handlebars-eS-J0O-M.js → handlebars-BBFEg4Lo.js} +1 -1
- package/dist/ui/assets/{heavy-payload-BKB0QDOI.js → heavy-payload-vGgBRvNX.js} +1 -1
- package/dist/ui/assets/html-D-C6YZk4.js +1 -0
- package/dist/ui/assets/{html-derivative-BlVZU2id.js → html-derivative-DJAQcZyc.js} +1 -1
- package/dist/ui/assets/{http-BmbZzA5x.js → http-Dg5LSYRK.js} +1 -1
- package/dist/ui/assets/{hurl-Dnd_YpOD.js → hurl-Y5uYzMZR.js} +1 -1
- package/dist/ui/assets/java-ppHvycj5.js +1 -0
- package/dist/ui/assets/javascript-DDTjKLlQ.js +1 -0
- package/dist/ui/assets/{jinja-DTvkZdHA.js → jinja-Bt30h8Ik.js} +1 -1
- package/dist/ui/assets/{jison-DUJG-tmh.js → jison-D5uZ1Nyo.js} +1 -1
- package/dist/ui/assets/json-Cw91r8h1.js +1 -0
- package/dist/ui/assets/jsx-04X2FT_1.js +1 -0
- package/dist/ui/assets/{julia-P5B4pHFa.js → julia-76hRaaGz.js} +1 -1
- package/dist/ui/assets/{just-DYaoh7C6.js → just-CDE7W0vW.js} +1 -1
- package/dist/ui/assets/{latex-CI5lnkWV.js → latex-CVO2Byab.js} +1 -1
- package/dist/ui/assets/{liquid-D3LnAs_z.js → liquid-CA-AS3EX.js} +1 -1
- package/dist/ui/assets/lua-CiyBp52Y.js +1 -0
- package/dist/ui/assets/{marko-CRDrjqfS.js → marko-_BWrPfny.js} +1 -1
- package/dist/ui/assets/{mdc-ZzwgmJVn.js → mdc-PyJv85eS.js} +1 -1
- package/dist/ui/assets/{nginx-BAvFXGSV.js → nginx-DAWVw8yu.js} +1 -1
- package/dist/ui/assets/{nim-BHIFawe9.js → nim-CKE1dzpU.js} +1 -1
- package/dist/ui/assets/{perl-C_f5AnLa.js → perl-BBhWva19.js} +1 -1
- package/dist/ui/assets/{php-DDqpegL5.js → php-ChIeaAoF.js} +1 -1
- package/dist/ui/assets/{pug-CSaAZXyd.js → pug-CMgI5afi.js} +1 -1
- package/dist/ui/assets/{qml-CNHvRs_z.js → qml-CjxTkcFH.js} +1 -1
- package/dist/ui/assets/r-DfFga4si.js +1 -0
- package/dist/ui/assets/{razor-BDfAPy7I.js → razor-i4DbHr8p.js} +1 -1
- package/dist/ui/assets/regexp-iC9_nbSI.js +1 -0
- package/dist/ui/assets/{review-payload-D7GIdYDj.js → review-payload-4erWKckt.js} +1 -1
- package/dist/ui/assets/{rst-BzPP2gle.js → rst-oy_97Kl4.js} +1 -1
- package/dist/ui/assets/{ruby-CQjzokzX.js → ruby-C5zYZIyl.js} +1 -1
- package/dist/ui/assets/{sas-Bp37KGr7.js → sas-BnMEh2S3.js} +1 -1
- package/dist/ui/assets/{scrollbar-HUMBdLLK.js → scrollbar-CaOPzUJd.js} +6 -6
- package/dist/ui/assets/scss-BfZXsAWQ.js +1 -0
- package/dist/ui/assets/shellscript-BC2srNaB.js +1 -0
- package/dist/ui/assets/{shellsession-CNc62UhY.js → shellsession-BpE5o7_3.js} +1 -1
- package/dist/ui/assets/{soy-CF44SpBo.js → soy-COesmhTY.js} +1 -1
- package/dist/ui/assets/sql-Ccv_yeUm.js +1 -0
- package/dist/ui/assets/{stata-DVeMA68W.js → stata-CGQEuSZq.js} +1 -1
- package/dist/ui/assets/{surrealql-52sF96Yv.js → surrealql-Bz4JbU-9.js} +1 -1
- package/dist/ui/assets/{svelte-ydwT7UbF.js → svelte-1jM2ejXj.js} +1 -1
- package/dist/ui/assets/{templ-BXcoVoGh.js → templ-C-VwELcp.js} +1 -1
- package/dist/ui/assets/{tex-COsYFp7O.js → tex-t1rUiQCm.js} +1 -1
- package/dist/ui/assets/{ts-tags-CF--LE1s.js → ts-tags-Bewoa6pS.js} +1 -1
- package/dist/ui/assets/tsx-CTXzrBkN.js +1 -0
- package/dist/ui/assets/{twig-YoM-DiI5.js → twig-DVg-vELl.js} +1 -1
- package/dist/ui/assets/typescript--ElHoFkw.js +1 -0
- package/dist/ui/assets/{vue-html-CPdGGk4T.js → vue-html-BHtJ8geX.js} +1 -1
- package/dist/ui/assets/{vue-vine-B5bjgk0a.js → vue-vine-CNSGAWwc.js} +1 -1
- package/dist/ui/assets/{vue-B5LDEy4l.js → vue-wPQ7UlMy.js} +1 -1
- package/dist/ui/assets/workspace-app-CcrHAUIn.css +1 -0
- package/dist/ui/assets/workspace-app-DJmkPYJC.js +1 -0
- package/dist/ui/assets/workspace-app-DkAiSl_0.js +111 -0
- package/dist/ui/assets/workspace-app-QyauBrJX.js +5 -0
- package/dist/ui/assets/workspace-lifecycle-app-BIXEo53I.js +1 -0
- package/dist/ui/assets/xml-JnmX6vyS.js +1 -0
- package/dist/ui/assets/{xsl-wls_CEK_.js → xsl-3_vJ27aE.js} +1 -1
- package/dist/ui/assets/yaml-OAcZkP-w.js +1 -0
- package/dist/ui/workspace-app.html +5 -2
- package/dist/ui/workspace-lifecycle-app.html +18 -0
- package/dist/workspaces.js +11 -0
- package/docs/configuration.md +36 -4
- package/docs/debugging.md +75 -17
- package/docs/gotchas.md +15 -9
- package/docs/setup.md +24 -10
- package/package.json +4 -3
- package/scripts/debug/accept.mjs +79 -27
- package/scripts/debug/host/run.sh +180 -0
- package/scripts/debug/host/serve.mjs +64 -0
- package/scripts/debug/runtime.mjs +57 -2
- package/scripts/debug/runtime.test.mjs +74 -0
- package/scripts/debug/serve.mjs +4 -5
- package/scripts/dev-server.mjs +32 -3
- package/scripts/release/release-gate.test.mjs +43 -0
- package/scripts/release/release-version.test.mjs +107 -0
- package/scripts/release-parity.mjs +70 -46
- package/scripts/release-proof.mjs +2 -2
- package/scripts/release-proof.test.mjs +18 -0
- package/scripts/release-version.mjs +17 -8
- package/dist/ui/assets/angular-html-BT2Z6jee.js +0 -1
- package/dist/ui/assets/c-acnvZ8tm.js +0 -1
- package/dist/ui/assets/cpp-UyrmHXan.js +0 -1
- package/dist/ui/assets/css-D_WCbY6m.js +0 -1
- package/dist/ui/assets/glsl-IJV4SB-M.js +0 -1
- package/dist/ui/assets/graphql-PM-WDnoB.js +0 -1
- package/dist/ui/assets/haml-B_5nS6Kx.js +0 -1
- package/dist/ui/assets/html-C3TPjrC5.js +0 -1
- package/dist/ui/assets/java-ne9HdIVn.js +0 -1
- package/dist/ui/assets/javascript-DpHT58rr.js +0 -1
- package/dist/ui/assets/json-DJmnBdxW.js +0 -1
- package/dist/ui/assets/jsx-BclJnZnN.js +0 -1
- package/dist/ui/assets/lua-dZC7ZQIY.js +0 -1
- package/dist/ui/assets/r-CAfoQND2.js +0 -1
- package/dist/ui/assets/regexp-Mug5jltQ.js +0 -1
- package/dist/ui/assets/scss-C_Z1DYnw.js +0 -1
- package/dist/ui/assets/shellscript-CLfJpn3I.js +0 -1
- package/dist/ui/assets/sql-CYnzfiQ1.js +0 -1
- package/dist/ui/assets/tsx-DLBt2-2f.js +0 -1
- package/dist/ui/assets/typescript-Ce9JGkNI.js +0 -1
- package/dist/ui/assets/workspace-app-Cm9EX5x4.js +0 -117
- package/dist/ui/assets/workspace-app-DHvE2ojW.css +0 -1
- package/dist/ui/assets/xml-Cun8xb0T.js +0 -1
- package/dist/ui/assets/yaml-BxuXn9OL.js +0 -1
- package/scripts/release/tag-local-ci.mjs +0 -144
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./heavy-payload-vGgBRvNX.js","./scrollbar-CaOPzUJd.js","./chunk-EyZ2wyi3.js","./workspace-app-DkAiSl_0.js","./workspace-app-CcrHAUIn.css","./review-payload-4erWKckt.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{a as e,c as t,d as n,i as r,l as i,n as a,o,s,t as c,u as l}from"./workspace-app-DkAiSl_0.js";function u(e){return e===`open_workspace`||e===`close_workspace`||e===`capability`||e===`apply_patch`||e===`exec_command`||e===`write_stdin`||e===`read`||e===`write`||e===`edit`||e===`rename`||e===`delete`||e===`grep`||e===`glob`||e===`ls`||e===`bash`}function d(e){return e===`read`}function f(e){return e===`write`}function p(e){return e===`edit`}function m(e){return e===`apply_patch`}function ee(e){return e===`bash`||e===`exec_command`||e===`write_stdin`}function h(e){return e.tool===`capability`&&e.capabilityName===`review.changes`}function te(e){return!!(e&&typeof e==`object`)}function ne(e){return e?.content?.map(e=>e.type===`text`?e.text??``:`[${e.mimeType??`image`} image payload]`).filter(Boolean).join(`
|
|
3
|
+
|
|
4
|
+
`)??``}function g(e,t){let n=e?.[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}function _(e){return e.tool===`open_workspace`?Number(e.summary?.agentsFiles??0)>0||Number(e.summary?.skills??0)>0||Number(e.summary?.agentProviders??0)>0||Number(e.summary?.agents??0)>0||!!e.agentsFiles?.length||!!e.availableAgentsFiles?.length||!!e.skills?.length||!!e.agentProviders?.length||!!e.agents?.length||!!e.worktree||!!e.instruction:h(e)?!!(e.files?.length||e.payload?.patch):m(e.tool)?!!e.payload?.patch:!!e.payload}function re(e){return e.tool===`open_workspace`||h(e)?_(e):m(e.tool)?e.files?.length===1&&_(e):!1}var ie={added:`Added`,edited:`Edited`,deleted:`Deleted`,renamed:`Renamed`,"renamed-edited":`Renamed and edited`};function ae(e,t={}){let n=e.files??[],r=le(n);if(r===0)return{title:t.emptyTitle??`Applied patch`,tone:`edit`};let i=new Set(n.map(v)),a=i.size===1?[...i][0]:void 0,o={title:ue(a,r),tone:de(a)};return a&&a!==`unknown`&&(o.iconKind=a),o}function v(e){switch(e.operation){case`add`:return`added`;case`update`:return`edited`;case`delete`:return`deleted`;case`move`:return`renamed`}switch(e.type){case`new`:return`added`;case`change`:return`edited`;case`deleted`:return`deleted`;case`rename-pure`:return`renamed`;case`rename-changed`:return`renamed-edited`;default:return`unknown`}}function oe(e,t,n){let r=v(t);if(r!==`edited`&&r!==`unknown`)return r;let i=e[n];return i?.operation===`move`&&(!t.path||i.path===t.path)||e.find(e=>e.operation===`move`&&e.path===t.path&&(!t.previousPath||e.previousPath===t.previousPath))?`renamed`:r===`edited`?`edited`:i?v(i):`unknown`}function y(e){let t=e.path??e.previousPath;if(!t)return;let n=e.previousPath;if(!n||n===t)return{current:t,title:t};let r=x(n)===x(t);return{current:r?S(t):t,previous:r?S(n):n,title:`${n} → ${t}`}}function se(e,t,n){let r=e[n],i=(r?.path===t.path?r:e.find(e=>e.path===t.path&&(!t.previousPath||!e.previousPath||e.previousPath===t.previousPath)))??r;return y({path:t.path??i?.path,previousPath:t.previousPath??i?.previousPath})}function ce(e){return e===`unknown`?`Changed`:ie[e]}function le(e){let t=new Set,n=0;for(let r of e){let e=r.path??r.previousPath;e?t.add(e):n+=1}return t.size+n}function ue(e,t){return e&&e!==`unknown`?`${ie[e]} ${t} ${b(t)}`:`Changed ${t} ${b(t)}`}function de(e){return e===`added`?`write`:e===`deleted`?`delete`:`edit`}function b(e){return e===1?`file`:`files`}function x(e){let t=Math.max(e.lastIndexOf(`/`),e.lastIndexOf(`\\`));return t===-1?``:e.slice(0,t)}function S(e){let t=Math.max(e.lastIndexOf(`/`),e.lastIndexOf(`\\`));return t===-1?e:e.slice(t+1)}function fe(e){switch(e.tool){case`open_workspace`:return{icon:e.mode===`worktree`?o.gitBranch:o.folderOpen,title:he(e),label:e.root??e.path,tone:`workspace`};case`close_workspace`:return{icon:e.mode===`worktree`?o.gitBranch:o.folderOpen,title:`Closed workspace`,label:e.sourceRoot??e.root??e.path??e.workspaceId,tone:`workspace`};case`read`:return{icon:o.readFile,title:`Read file`,label:e.path,tone:`read`};case`write`:return{icon:o.writeFile,title:`Wrote file`,label:e.path,tone:`write`};case`edit`:return{icon:o.editFile,title:`Edited file`,label:e.path,tone:`edit`};case`rename`:return{icon:o.editFile,title:`Renamed path`,label:e.path,tone:`edit`};case`delete`:return{icon:o.deleteFile,title:`Deleted path`,label:e.path,tone:`delete`};case`apply_patch`:{let t=ae(e);return{icon:me(t.iconKind),title:t.title,label:C(e),tone:t.tone}}case`grep`:return{icon:o.search,title:`Searched files`,label:ge(e),tone:`search`};case`glob`:return{icon:o.files,title:`Found files`,label:ge(e),tone:`search`};case`ls`:return{icon:o.folderTree,title:`Listed directory`,label:e.path,tone:`directory`};case`bash`:case`exec_command`:return{icon:o.terminalSquare,title:_e(e,`command`),label:w(e),tone:`shell`,state:ve(e)};case`write_stdin`:return{icon:o.terminal,title:_e(e,`process`),label:w(e),tone:`shell`,state:ve(e)};case`capability`:if(h(e)){let t=ae(e,{emptyTitle:`Changes ready`}),n=e.files?.length??0;return{icon:o.diff,title:n>0||e.payload?.patch?t.title:`No changes`,label:C(e),tone:`review`}}return{icon:o.skills,title:e.capabilityName?`Capability: ${e.capabilityName}`:`Capability completed`,tone:`workspace`}}}function pe(e){let t=e.summary??{};if(h(e)||m(e.tool)||p(e.tool)||f(e.tool))return{kind:`diff`,additions:g(t,`additions`)??0,removals:g(t,`removals`)??0};if(e.tool===`open_workspace`){let e=[T(g(t,`agentsFiles`),`instruction`),T(g(t,`skills`),`skill`)].filter(e=>!!e);return e.length>0?{kind:`text`,text:e.join(` · `)}:{kind:`empty`}}if(ee(e.tool)){let e=[T(g(t,`lines`),`line`),ye(g(t,`wallTimeMs`))].filter(e=>!!e);return e.length>0?{kind:`text`,text:e.join(` · `)}:{kind:`empty`}}if(e.tool===`grep`||e.tool===`read`||e.tool===`ls`){let e=T(g(t,`lines`),`line`);return e?{kind:`text`,text:e}:{kind:`empty`}}return{kind:`empty`}}function me(e){return e===`added`?o.writeFile:e===`deleted`?o.deleteFile:e===`renamed`||e===`renamed-edited`?o.files:o.editFile}function he(e){return`${e.workspaceReused?`Reused`:`Opened`} workspace`}function C(e){if(e.files?.length===1)return y(e.files[0])?.title??e.path}function ge(e){let t=e.summary?.pattern,n=e.summary?.scope;return typeof t==`string`?typeof n==`string`&&n!==`.`?`${t} in ${n}`:t:e.path}function _e(e,t){if(e.summary?.running===!0)return t===`command`?`Command running`:`Process running`;let n=g(e.summary,`exitCode`);return n!==void 0&&n!==0?t===`command`?`Command failed`:`Process failed`:t===`command`?`Ran command`:`Process finished`}function ve(e){if(e.summary?.running===!0)return`running`;let t=g(e.summary,`exitCode`);return t!==void 0&&t!==0?`error`:t===0?`success`:void 0}function w(e){let t=e.summary?.command;if(typeof t==`string`)return t;let n=e.summary?.sessionId;return typeof n==`number`||typeof n==`string`?`Session ${String(n)}`:e.path}function T(e,t){if(e!==void 0)return`${e} ${t}${e===1?``:`s`}`}function ye(e){if(e!==void 0)return e<1e3?`${Math.round(e)}ms`:`${(e/1e3).toFixed(+(e<1e4))}s`}var E=null,D=!1,O=null,k,A=null,j=!1,M=!1,N=null,P=null,F=null,I=null,L=!1,R=document.querySelector(`#app`);if(!R)throw Error(`Missing #app root element.`);var z=R,B=new c(z);be();async function be(){H(),E=new i({name:`forgerelay-tool-cards`,version:`0.1.0`},{}),E.ontoolresult=e=>{let t=a(B.active,e.structuredContent);if(t===`activity`&&B.accept(e)){A=null,j=!1,M=!1,I=null,L=!1,N=null,H();return}if(t===`preserve-panel`)return;let n=Re(e),r=Le(e),i=r?{...n,...r}:n,o=Ie(e);if(!o||!te(i)){A=null,j=!1,M=!1,I=null,L=!1,N=`No result card is available for this tool result.`,H();return}let s={...i,tool:o};A=s,j=re(s),M=!1,I=null,L=!1,N=null,H()},E.onhostcontextchanged=e=>{k={...k,...e},V(),B.active?B.render():A?.tool!==`open_workspace`&&W()},E.onteardown=async()=>(D=!1,B.detach(),G(),{});try{await E.connect();let e=E.getHostContext();e&&(k=e),V(),D=!0,B.attach(E)}catch(e){O=e instanceof Error?e.message:String(e)}H()}function V(){k?.theme&&l(k.theme),k?.styles?.variables&&t(k.styles.variables),k?.styles?.css?.fonts&&s(k.styles.css.fonts);let e=k?.safeAreaInsets;e&&(document.body.style.padding=`${e.top}px ${e.right}px ${e.bottom}px ${e.left}px`)}function H(){if(G(),O){U(O,`error`);return}if(!D){U(`Connecting to host...`);return}if(B.render())return;if(!A){U(N??`Waiting for a tool result.`,N?`error`:`muted`);return}let t=fe(A);if(h(A)){Ce(A,t);return}let n=_(A),r=$(`main`,{className:`shell`}),i=$(`section`,{className:Te(t)}),a=$(`button`,{className:`tool-header`,type:`button`,ariaExpanded:String(j),disabled:!n});n&&a.addEventListener(`click`,()=>{j=!j,H()});let o=$(`span`,{className:`tool-icon`,ariaHidden:`true`});o.append(e(t.icon));let s=$(`span`,{className:`tool-main`}),c=$(`span`,{className:`tool-title`,text:t.title});if(s.append(c),t.label&&s.append($(`span`,{className:`tool-label`,text:t.label,title:t.label})),a.append(o,s,J(A),we(j,n)),i.append(a),j){let e=$(`div`,{className:`tool-body`});F=e,i.append(e)}r.append(i),z.replaceChildren(r),W()}function U(e,t=`muted`){let n=$(`main`,{className:`shell`});n.append($(`section`,{className:`empty ${t}`,text:e})),z.replaceChildren(n)}async function W(){if(!A||!F||!j)return;let e=F;if(N){q(e,N,`error`);return}if(A.tool===`open_workspace`){Ee(e,A);return}if(xe(A)){if(P){P.update({card:A,hostContext:k,errorMessage:N});return}Y(e,!0);try{let{mountHeavyPayload:t}=await n(async()=>{let{mountHeavyPayload:e}=await import(`./heavy-payload-vGgBRvNX.js`);return{mountHeavyPayload:e}},__vite__mapDeps([0,1,2,3,4]),import.meta.url);if(e!==F||!j||!A)return;Y(e,!1),P=t(e,{card:A,hostContext:k,errorMessage:N})}catch(t){if(e!==F||!j)return;Y(e,!1),q(e,t instanceof Error?t.message:`Unable to load details.`,`error`)}return}if(h(A)||m(A.tool)){let t=h(A)&&!M?Math.max(3,(A.files??[]).slice(0,3).length):void 0;if(P){P.update({card:A,hostContext:k,errorMessage:N,visibleFileCount:t});return}q(e,h(A)?`Loading review...`:`Loading diff...`);let{mountReviewPayload:r}=await n(async()=>{let{mountReviewPayload:e}=await import(`./review-payload-4erWKckt.js`);return{mountReviewPayload:e}},__vite__mapDeps([5,1,2,3,4]),import.meta.url);if(e!==F||!A)return;P=r(e,{card:A,hostContext:k,errorMessage:N,visibleFileCount:t});return}let t=ne(A.payload);if(!t){q(e,`No details available.`);return}Se(e,t,A.tool)}function xe(e){return d(e.tool)||p(e.tool)||f(e.tool)}function G(){K(),P=null,F=null}function K(){P?.unmount(),P=null}function q(e,t,n=`muted`){K(),e.replaceChildren($(`div`,{className:`status ${n}`,text:t}))}function Se(e,t,n){K(),e.replaceChildren($(`pre`,{className:`text-payload pretty-scrollbar ${n}`,text:t}))}function J(e){let t=pe(e);if(t.kind===`diff`){let e=$(`span`,{className:`stats`});return e.setAttribute(`aria-label`,`Diff statistics`),e.append($(`span`,{className:`add`,text:`+${String(t.additions)}`}),$(`span`,{className:`remove`,text:`-${String(t.removals)}`})),e}let n=$(`span`,{className:`header-meta ${t.kind===`empty`?`empty`:``}`,text:t.kind===`text`?t.text:``});return t.kind===`empty`&&n.setAttribute(`aria-hidden`,`true`),n}function Ce(t,n){G();let r=t.files??[],i=M?r:r.slice(0,3),a=Math.max(0,r.length-i.length),o=_(t),s=$(`main`,{className:`shell`}),c=$(`section`,{className:Te(n)}),l=$(`button`,{className:`tool-header review-header`,type:`button`,ariaExpanded:String(j),disabled:!o});o&&l.addEventListener(`click`,()=>{j=!j,H()});let u=$(`span`,{className:`tool-icon`,ariaHidden:`true`});u.append(e(n.icon));let d=$(`span`,{className:`tool-main review-title-group`});if(d.append($(`span`,{className:`tool-title`,text:n.title})),n.label&&d.append($(`span`,{className:`tool-label`,text:n.label,title:n.label})),l.append(u,d,J(t),we(j,o)),c.append(l),j){let e=$(`div`,{className:`review-summary`}),t=$(`div`,{className:`review-payload`});if(F=t,e.append(t),a>0){let t=$(`button`,{className:`review-more`,type:`button`,text:`Show ${a} more ${a===1?`file`:`files`}`});t.addEventListener(`click`,()=>{M=!0,H()}),e.append(t)}c.append(e)}s.append(c),z.replaceChildren(s),W()}function we(t,n){let r=$(`span`,{className:n?`chevron ${t?`expanded`:``}`:`chevron`,ariaHidden:`true`});return n&&r.append(e(o.chevronDown)),r}function Te(e){return[`tool-card`,e.tone,e.state?`state-${e.state}`:void 0].filter(Boolean).join(` `)}function Y(t,n){let r=t.previousElementSibling,i=r?.querySelector(`.chevron`);if(!i)return;i.classList.toggle(`loading`,n),i.replaceChildren(e(n?o.loading:o.chevronDown));let a=r instanceof HTMLButtonElement?r:null;a&&a.setAttribute(`aria-busy`,String(n))}function Ee(t,n){K();let i=$(`div`,{className:`workspace-details pretty-scrollbar`}),a=$(`div`,{className:`workspace-rows`}),s=n.worktree;if(s){let t=[s.baseRef,s.baseSha?.slice(0,8)].filter(e=>!!e).join(` · `)||`Worktree`,n=$(`span`,{className:`workspace-base-value`});if(n.append($(`span`,{className:`workspace-value`,text:t,title:t})),s.dirtySource){let t=$(`span`,{className:`workspace-base-warning`,title:`The source checkout had uncommitted changes when this worktree was created. Those changes are not included here.`,ariaLabel:`Source checkout changes are not included in this worktree`});t.append(e(o.warning,`workspace-base-warning-svg`)),n.append(t)}Z(a,`Base`,n,o.base),s.branch&&X(a,`Worktree branch`,s.branch,o.gitBranch,!1),s.targetBranch&&X(a,`Merge target`,s.targetBranch,o.gitBranch,!1)}n.sourceRoot&&n.sourceRoot!==n.root&&X(a,`Source checkout`,n.sourceRoot,o.sourceCheckout,!0),De(a,n.agentsFiles??[],n.availableAgentsFiles??[]);let c=n.skills??[];c.length>0&&Pe(a,c);let l=n.agentProviders??[],u=(n.agents??[]).map(e=>{let t=e.name??`Unnamed agent`,n=e.provider?.trim(),i=e.providerAvailable===!1,a=[e.description,n?`Provider: ${n}`:void 0,e.model?`Model: ${e.model}`:void 0,e.thinking?`Thinking: ${e.thinking}`:void 0,i?e.providerUnavailableReason??`Provider unavailable`:void 0].filter(e=>!!e).join(`
|
|
5
|
+
`);return{label:t,logo:n?r(n):void 0,profile:!0,tone:i?`muted`:void 0,title:a||void 0}}),d=l.map(e=>{let t=e.name?.trim()||`Unknown provider`,n=e.available===!1,i=r(t);return{label:t,logo:i,bareLogo:!!i,ariaLabel:t,tone:n?`muted`:void 0,title:n?e.reason??`Provider unavailable`:t}});if(u.length>0){let e=Q([...u,...d]);e.classList.add(`workspace-agents-list`),Z(a,`Agents`,e,o.agents,`workspace-agents-row`)}else d.length>0&&Ne(a,`Providers`,d,o.providers);a.childElementCount>0&&i.append(a),i.childElementCount===0&&i.append($(`div`,{className:`status muted`,text:`No workspace details available.`})),t.replaceChildren(i)}function De(e,t,n){let r=[],i=new Set;for(let[e,n]of t.entries())r.push({key:`loaded:${e}`,path:n.path,label:n.path??`Loaded instructions`,content:n.content,status:`loaded`}),n.path&&i.add(n.path);let a=[];for(let[e,t]of n.entries())t.path&&i.has(t.path)||a.push({key:`available:${e}`,path:t.path,label:t.path??`Nested instructions`,status:`available`});if(r.length===0&&a.length===0)return;let s=Oe(L?[...r,...a]:r);if(a.length>0){let e=L,t=$(`button`,{className:`workspace-instructions-toggle`,type:`button`,text:e?`Show less`:`View all`,ariaLabel:e?`Show only loaded instruction files`:`View all ${a.length} available instruction files`,ariaExpanded:String(e)});t.addEventListener(`click`,()=>{L=!L,L||(I=null),H()}),s.append(t)}let c=$(`div`,{className:`workspace-instructions-content`});c.append(s),Z(e,`Instructions`,c,o.instructions,`workspace-instructions-row`)}function Oe(t){let n=$(`span`,{className:`workspace-instruction-list`});for(let r of t){let t=$(`span`,{className:`workspace-instruction-item`});t.dataset.instructionKey=r.key;let i=r.status===`loaded`&&r.content!==void 0,a=$(i?`button`:`span`,{className:`workspace-instruction-header${i?` interactive`:``}`,type:i?`button`:void 0,ariaLabel:i?`View ${r.label}`:void 0,ariaExpanded:i?`false`:void 0}),s=$(`span`,{className:`workspace-instruction-text`}),c=Me(r.label);if(s.append($(`span`,{className:`workspace-instruction-name`,text:c})),r.path&&r.path!==c&&s.append($(`span`,{className:`workspace-instruction-path`,text:r.path,title:r.path})),a.append(Ae(r.status),s),i){let i=$(`span`,{className:`workspace-instruction-chevron`,ariaHidden:`true`});i.append(e(o.chevronDown,`workspace-instruction-chevron-svg`)),a.append(i),a.addEventListener(`click`,()=>{I=I===r.key?null:r.key,ke(n)});let s=$(`pre`,{className:`workspace-instruction-preview pretty-scrollbar`,text:r.content});s.hidden=!0,t.append(a,s)}else t.append(a);n.append(t)}return ke(n),n}function ke(e){for(let t of e.querySelectorAll(`.workspace-instruction-item`)){let e=t.dataset.instructionKey===I;t.classList.toggle(`expanded`,e),t.querySelector(`.workspace-instruction-header.interactive`)?.setAttribute(`aria-expanded`,String(e));let n=t.querySelector(`.workspace-instruction-preview`);n&&(n.hidden=!e)}}function Ae(t){let n=je(t),r=$(`span`,{className:`workspace-instruction-status ${t}`,title:n,ariaLabel:n});return r.setAttribute(`role`,`img`),r.append(e(t===`loaded`?o.instructionLoaded:o.instructionAvailable,`workspace-instruction-status-svg`)),r}function je(e){return e===`loaded`?`Loaded into the current workspace context`:`Available for a nested directory`}function Me(e){return e.replaceAll(`\\`,`/`).split(`/`).filter(Boolean).at(-1)??e}function X(e,t,n,r,i=!1){Z(e,t,$(`span`,{className:`workspace-value${i?` mono`:``}`,text:n,title:n}),r)}function Ne(e,t,n,r){Z(e,t,Q(n),r)}function Z(e,t,n,r,i){let a=$(`div`,{className:[`workspace-row`,i].filter(Boolean).join(` `)});a.append(Fe(r),$(`span`,{className:`workspace-key`,text:t}),n),e.append(a)}function Pe(e,t){let n=Q(t.map(e=>({label:e.name??`Unnamed skill`,title:e.description||void 0})));n.classList.add(`workspace-skills-list`),Z(e,`Skills`,n,o.skills,`workspace-skills-row`)}function Fe(t){let n=$(`span`,{className:`workspace-row-icon`,ariaHidden:`true`});return n.append(e(t,`workspace-row-icon-svg`)),n}function Q(e){let t=$(`span`,{className:`workspace-chip-list`});for(let n of e){let e=!!(n.bareLogo&&n.logo),r=$(`span`,{className:[e?`workspace-provider-logo`:n.profile?`workspace-agent-profile`:`workspace-chip`,n.tone].filter(Boolean).join(` `),title:n.title});if(e&&(r.setAttribute(`role`,`img`),r.setAttribute(`aria-label`,n.ariaLabel??n.label)),n.logo){let t=document.createElement(`img`);t.className=e?`workspace-provider-logo-image`:n.profile?`workspace-agent-profile-logo`:`workspace-chip-logo`,t.src=n.logo,t.alt=``,t.setAttribute(`aria-hidden`,`true`),r.append(t)}e||r.append($(`span`,{className:`workspace-chip-label`,text:n.label})),t.append(r)}return t}function Ie(e){let t=e._meta?.tool;return u(t)?t:void 0}function Le(e){let t=e._meta?.card;return t&&typeof t==`object`?t:void 0}function Re(e){return e.structuredContent}function $(e,t={}){let n=document.createElement(e);return t.className&&(n.className=t.className),t.text!==void 0&&(n.textContent=t.text),t.type!==void 0&&`type`in n&&n.setAttribute(`type`,t.type),t.title!==void 0&&(n.title=t.title),t.ariaHidden!==void 0&&n.setAttribute(`aria-hidden`,t.ariaHidden),t.ariaLabel!==void 0&&n.setAttribute(`aria-label`,t.ariaLabel),t.ariaExpanded!==void 0&&n.setAttribute(`aria-expanded`,t.ariaExpanded),t.disabled!==void 0&&`disabled`in n&&(n.disabled=t.disabled),n}export{d as a,g as c,p as i,oe as n,f as o,se as r,ne as s,ce as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./workspace-app-DkAiSl_0.js";import"./workspace-app-QyauBrJX.js";document.documentElement.dataset.forgerelayApp=`workspace-lifecycle-compatibility`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./chunk-EyZ2wyi3.js";import{t}from"./java-ppHvycj5.js";var n=e({default:()=>i}),r=Object.freeze(JSON.parse(`{"displayName":"XML","name":"xml","patterns":[{"begin":"(<\\\\?)\\\\s*([-0-9A-Z_a-z]+)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.xml"}},"end":"(\\\\?>)","name":"meta.tag.preprocessor.xml","patterns":[{"match":" ([-A-Za-z]+)","name":"entity.other.attribute-name.xml"},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},{"begin":"(<!)(DOCTYPE)\\\\s+([:A-Z_a-z][-.0-:A-Z_a-z]*)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"keyword.other.doctype.xml"},"3":{"name":"variable.language.documentroot.xml"}},"end":"\\\\s*(>)","name":"meta.tag.sgml.doctype.xml","patterns":[{"include":"#internalSubset"}]},{"include":"#comments"},{"begin":"(<)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(?=(\\\\s[^>]*)?></\\\\2>)","beginCaptures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.xml"},"3":{"name":"entity.name.tag.namespace.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(>)(</)((?:([-0-9A-Z_a-z]+)(:))?([-0-:A-Z_a-z]+))(>)","endCaptures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"punctuation.definition.tag.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"entity.name.tag.namespace.xml"},"5":{"name":"punctuation.separator.namespace.xml"},"6":{"name":"entity.name.tag.localname.xml"},"7":{"name":"punctuation.definition.tag.xml"}},"name":"meta.tag.no-content.xml","patterns":[{"include":"#tagStuff"}]},{"begin":"(</?)(?:([-.\\\\w]+)((:)))?([-.:\\\\w]+)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.namespace.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(/?>)","name":"meta.tag.xml","patterns":[{"include":"#tagStuff"}]},{"include":"#entity"},{"include":"#bare-ampersand"},{"begin":"<%@","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.xml"}},"end":"%>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.xml"}},"name":"source.java-props.embedded.xml","patterns":[{"match":"page|include|taglib","name":"keyword.other.page-props.xml"}]},{"begin":"<%[!=]?(?!--)","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.xml"}},"end":"(?!--)%>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.xml"}},"name":"source.java.embedded.xml","patterns":[{"include":"source.java"}]},{"begin":"<!\\\\[CDATA\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"]]>","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.unquoted.cdata.xml"}],"repository":{"EntityDecl":{"begin":"(<!)(ENTITY)\\\\s+(%\\\\s+)?([:A-Z_a-z][-.0-:A-Z_a-z]*)(\\\\s+(?:SYSTEM|PUBLIC)\\\\s+)?","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"keyword.other.entity.xml"},"3":{"name":"punctuation.definition.entity.xml"},"4":{"name":"variable.language.entity.xml"},"5":{"name":"keyword.other.entitytype.xml"}},"end":"(>)","patterns":[{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},"bare-ampersand":{"match":"&","name":"invalid.illegal.bad-ampersand.xml"},"comments":{"patterns":[{"begin":"<%--","captures":{"0":{"name":"punctuation.definition.comment.xml"},"end":"--%>","name":"comment.block.xml"}},{"begin":"<!--","captures":{"0":{"name":"punctuation.definition.comment.xml"}},"end":"-->","name":"comment.block.xml","patterns":[{"begin":"--(?!>)","captures":{"0":{"name":"invalid.illegal.bad-comments-or-CDATA.xml"}}}]}]},"doublequotedString":{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.double.xml","patterns":[{"include":"#entity"},{"include":"#bare-ampersand"}]},"entity":{"captures":{"1":{"name":"punctuation.definition.constant.xml"},"3":{"name":"punctuation.definition.constant.xml"}},"match":"(&)([:A-Z_a-z][-.0-:A-Z_a-z]*|#[0-9]+|#x\\\\h+)(;)","name":"constant.character.entity.xml"},"internalSubset":{"begin":"(\\\\[)","captures":{"1":{"name":"punctuation.definition.constant.xml"}},"end":"(])","name":"meta.internalsubset.xml","patterns":[{"include":"#EntityDecl"},{"include":"#parameterEntity"},{"include":"#comments"}]},"parameterEntity":{"captures":{"1":{"name":"punctuation.definition.constant.xml"},"3":{"name":"punctuation.definition.constant.xml"}},"match":"(%)([:A-Z_a-z][-.0-:A-Z_a-z]*)(;)","name":"constant.character.parameter-entity.xml"},"singlequotedString":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.single.xml","patterns":[{"include":"#entity"},{"include":"#bare-ampersand"}]},"tagStuff":{"patterns":[{"captures":{"1":{"name":"entity.other.attribute-name.namespace.xml"},"2":{"name":"entity.other.attribute-name.xml"},"3":{"name":"punctuation.separator.namespace.xml"},"4":{"name":"entity.other.attribute-name.localname.xml"}},"match":"(?:^|\\\\s+)(?:([-.\\\\w]+)((:)))?([-.:\\\\w]+)\\\\s*="},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]}},"scopeName":"text.xml","embeddedLangs":["java"]}`)),i=[...t,r];export{n,i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./xml-
|
|
1
|
+
import{t as e}from"./xml-JnmX6vyS.js";var t=Object.freeze(JSON.parse(`{"displayName":"XSL","name":"xsl","patterns":[{"begin":"(<)(xsl)((:))(template)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.namespace.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(>)","name":"meta.tag.xml.template","patterns":[{"captures":{"1":{"name":"entity.other.attribute-name.namespace.xml"},"2":{"name":"entity.other.attribute-name.xml"},"3":{"name":"punctuation.separator.namespace.xml"},"4":{"name":"entity.other.attribute-name.localname.xml"}},"match":" (?:([-0-9A-Z_a-z]+)((:)))?([-A-Za-z]+)"},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},{"include":"text.xml"}],"repository":{"doublequotedString":{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.double.xml"},"singlequotedString":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.single.xml"}},"scopeName":"text.xml.xsl","embeddedLangs":["xml"]}`)),n=[...e,t];export{n as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./chunk-EyZ2wyi3.js";var t=e({default:()=>n}),n=[Object.freeze(JSON.parse(`{"displayName":"YAML","fileTypes":["yaml","yml","rviz","reek","clang-format","yaml-tmlanguage","syntax","sublime-syntax"],"firstLineMatch":"^%YAML( ?1.\\\\d+)?","name":"yaml","patterns":[{"include":"#comment"},{"include":"#property"},{"include":"#directive"},{"match":"^---","name":"entity.other.document.begin.yaml"},{"match":"^\\\\.{3}","name":"entity.other.document.end.yaml"},{"include":"#node"}],"repository":{"block-collection":{"patterns":[{"include":"#block-sequence"},{"include":"#block-mapping"}]},"block-mapping":{"patterns":[{"include":"#block-pair"}]},"block-node":{"patterns":[{"include":"#prototype"},{"include":"#block-scalar"},{"include":"#block-collection"},{"include":"#flow-scalar-plain-out"},{"include":"#flow-node"}]},"block-pair":{"patterns":[{"begin":"\\\\?","beginCaptures":{"1":{"name":"punctuation.definition.key-value.begin.yaml"}},"end":"(?=\\\\?)|^ *(:)|(:)","endCaptures":{"1":{"name":"punctuation.separator.key-value.mapping.yaml"},"2":{"name":"invalid.illegal.expected-newline.yaml"}},"name":"meta.block-mapping.yaml","patterns":[{"include":"#block-node"}]},{"begin":"(?=(?:[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?]\\\\S)([^:\\\\s]|:\\\\S|\\\\s+(?![#\\\\s]))*\\\\s*:(\\\\s|$))","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$))","patterns":[{"include":"#flow-scalar-plain-out-implicit-type"},{"begin":"[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?]\\\\S","beginCaptures":{"0":{"name":"entity.name.tag.yaml"}},"contentName":"entity.name.tag.yaml","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$))","name":"string.unquoted.plain.out.yaml"}]},{"match":":(?=\\\\s|$)","name":"punctuation.separator.key-value.mapping.yaml"}]},"block-scalar":{"begin":"(?:(\\\\|)|(>))([1-9])?([-+])?(.*\\\\n?)","beginCaptures":{"1":{"name":"keyword.control.flow.block-scalar.literal.yaml"},"2":{"name":"keyword.control.flow.block-scalar.folded.yaml"},"3":{"name":"constant.numeric.indentation-indicator.yaml"},"4":{"name":"storage.modifier.chomping-indicator.yaml"},"5":{"patterns":[{"include":"#comment"},{"match":".+","name":"invalid.illegal.expected-comment-or-newline.yaml"}]}},"end":"^(?=\\\\S)|(?!\\\\G)","patterns":[{"begin":"^( +)(?! )","end":"^(?!\\\\1|\\\\s*$)","name":"string.unquoted.block.yaml"}]},"block-sequence":{"match":"(-)(?!\\\\S)","name":"punctuation.definition.block.sequence.item.yaml"},"comment":{"begin":"(?:^([\\\\t ]*)|[\\\\t ]+)(?=#\\\\p{print}*$)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.yaml"}},"end":"(?!\\\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.yaml"}},"end":"\\\\n","name":"comment.line.number-sign.yaml"}]},"directive":{"begin":"^%","beginCaptures":{"0":{"name":"punctuation.definition.directive.begin.yaml"}},"end":"(?=$|[\\\\t ]+($|#))","name":"meta.directive.yaml","patterns":[{"captures":{"1":{"name":"keyword.other.directive.yaml.yaml"},"2":{"name":"constant.numeric.yaml-version.yaml"}},"match":"\\\\G(YAML)[\\\\t ]+(\\\\d+\\\\.\\\\d+)"},{"captures":{"1":{"name":"keyword.other.directive.tag.yaml"},"2":{"name":"storage.type.tag-handle.yaml"},"3":{"name":"support.type.tag-prefix.yaml"}},"match":"\\\\G(TAG)(?:[\\\\t ]+(!(?:[-0-9A-Za-z]*!)?)(?:[\\\\t ]+(!(?:%\\\\h{2}|[]!#$\\\\&-;=?-\\\\[_a-z~])*|(?![]!,\\\\[{}])(?:%\\\\h{2}|[]!#$\\\\&-;=?-\\\\[_a-z~])+))?)?"},{"captures":{"1":{"name":"support.other.directive.reserved.yaml"},"2":{"name":"string.unquoted.directive-name.yaml"},"3":{"name":"string.unquoted.directive-parameter.yaml"}},"match":"\\\\G(\\\\w+)(?:[\\\\t ]+(\\\\w+)(?:[\\\\t ]+(\\\\w+))?)?"},{"match":"\\\\S+","name":"invalid.illegal.unrecognized.yaml"}]},"flow-alias":{"captures":{"1":{"name":"keyword.control.flow.alias.yaml"},"2":{"name":"punctuation.definition.alias.yaml"},"3":{"name":"variable.other.alias.yaml"},"4":{"name":"invalid.illegal.character.anchor.yaml"}},"match":"((\\\\*))([^],/\\\\[{}\\\\s]+)([^],}\\\\s]\\\\S*)?"},"flow-collection":{"patterns":[{"include":"#flow-sequence"},{"include":"#flow-mapping"}]},"flow-mapping":{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.mapping.begin.yaml"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.mapping.end.yaml"}},"name":"meta.flow-mapping.yaml","patterns":[{"include":"#prototype"},{"match":",","name":"punctuation.separator.mapping.yaml"},{"include":"#flow-pair"}]},"flow-node":{"patterns":[{"include":"#prototype"},{"include":"#flow-alias"},{"include":"#flow-collection"},{"include":"#flow-scalar"}]},"flow-pair":{"patterns":[{"begin":"\\\\?","beginCaptures":{"0":{"name":"punctuation.definition.key-value.begin.yaml"}},"end":"(?=[],}])","name":"meta.flow-pair.explicit.yaml","patterns":[{"include":"#prototype"},{"include":"#flow-pair"},{"include":"#flow-node"},{"begin":":(?=\\\\s|$|[],\\\\[{}])","beginCaptures":{"0":{"name":"punctuation.separator.key-value.mapping.yaml"}},"end":"(?=[],}])","patterns":[{"include":"#flow-value"}]}]},{"begin":"(?=(?:[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?][^],\\\\[{}\\\\s])([^],:\\\\[{}\\\\s]|:[^],\\\\[{}\\\\s]|\\\\s+(?![#\\\\s]))*\\\\s*:(\\\\s|$))","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$)|\\\\s*:[],\\\\[{}]|\\\\s*[],\\\\[{}])","name":"meta.flow-pair.key.yaml","patterns":[{"include":"#flow-scalar-plain-in-implicit-type"},{"begin":"[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?][^],\\\\[{}\\\\s]","beginCaptures":{"0":{"name":"entity.name.tag.yaml"}},"contentName":"entity.name.tag.yaml","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$)|\\\\s*:[],\\\\[{}]|\\\\s*[],\\\\[{}])","name":"string.unquoted.plain.in.yaml"}]},{"include":"#flow-node"},{"begin":":(?=\\\\s|$|[],\\\\[{}])","captures":{"0":{"name":"punctuation.separator.key-value.mapping.yaml"}},"end":"(?=[],}])","name":"meta.flow-pair.yaml","patterns":[{"include":"#flow-value"}]}]},"flow-scalar":{"patterns":[{"include":"#flow-scalar-double-quoted"},{"include":"#flow-scalar-single-quoted"},{"include":"#flow-scalar-plain-in"}]},"flow-scalar-double-quoted":{"begin":"\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.yaml"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.yaml"}},"name":"string.quoted.double.yaml","patterns":[{"match":"\\\\\\\\([ \\"/0LN\\\\\\\\_abefnprtv]|x\\\\d\\\\d|u\\\\d{4}|U\\\\d{8})","name":"constant.character.escape.yaml"},{"match":"\\\\\\\\\\\\n","name":"constant.character.escape.double-quoted.newline.yaml"}]},"flow-scalar-plain-in":{"patterns":[{"include":"#flow-scalar-plain-in-implicit-type"},{"begin":"[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?][^],\\\\[{}\\\\s]","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$)|\\\\s*:[],\\\\[{}]|\\\\s*[],\\\\[{}])","name":"string.unquoted.plain.in.yaml"}]},"flow-scalar-plain-in-implicit-type":{"patterns":[{"captures":{"1":{"name":"constant.language.null.yaml"},"2":{"name":"constant.language.boolean.yaml"},"3":{"name":"constant.numeric.integer.yaml"},"4":{"name":"constant.numeric.float.yaml"},"5":{"name":"constant.other.timestamp.yaml"},"6":{"name":"constant.language.value.yaml"},"7":{"name":"constant.language.merge.yaml"}},"match":"(?:(null|Null|NULL|~)|([Yy]|yes|Yes|YES|[Nn]|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)|([-+]?0b[01_]+|[-+]?0[0-7_]+|[-+]?(?:0|[1-9][0-9_]*)|[-+]?0x[_\\\\h]+|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)|([-+]?(?:[0-9][0-9_]*)?\\\\.[.0-9]*(?:[Ee][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\\\.[0-9_]*|[-+]?\\\\.(?:inf|Inf|INF)|\\\\.(?:nan|NaN|NAN))|(\\\\d{4}-\\\\d{2}-\\\\d{2}|\\\\d{4}-\\\\d{1,2}-\\\\d{1,2}(?:[Tt]|[\\\\t ]+)\\\\d{1,2}:\\\\d{2}:\\\\d{2}(?:\\\\.\\\\d*)?(?:[\\\\t ]*Z|[-+]\\\\d{1,2}(?::\\\\d{1,2})?)?)|(=)|(<<))(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$)|\\\\s*:[],\\\\[{}]|\\\\s*[],\\\\[{}])"}]},"flow-scalar-plain-out":{"patterns":[{"include":"#flow-scalar-plain-out-implicit-type"},{"begin":"[^-\\\\]!\\"#%\\\\&'*,:>?@\\\\[\`{|}\\\\s]|[-:?]\\\\S","end":"(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$))","name":"string.unquoted.plain.out.yaml"}]},"flow-scalar-plain-out-implicit-type":{"patterns":[{"captures":{"1":{"name":"constant.language.null.yaml"},"2":{"name":"constant.language.boolean.yaml"},"3":{"name":"constant.numeric.integer.yaml"},"4":{"name":"constant.numeric.float.yaml"},"5":{"name":"constant.other.timestamp.yaml"},"6":{"name":"constant.language.value.yaml"},"7":{"name":"constant.language.merge.yaml"}},"match":"(?:(null|Null|NULL|~)|([Yy]|yes|Yes|YES|[Nn]|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)|([-+]?0b[01_]+|[-+]?0[0-7_]+|[-+]?(?:0|[1-9][0-9_]*)|[-+]?0x[_\\\\h]+|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)|([-+]?(?:[0-9][0-9_]*)?\\\\.[.0-9]*(?:[Ee][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\\\.[0-9_]*|[-+]?\\\\.(?:inf|Inf|INF)|\\\\.(?:nan|NaN|NAN))|(\\\\d{4}-\\\\d{2}-\\\\d{2}|\\\\d{4}-\\\\d{1,2}-\\\\d{1,2}(?:[Tt]|[\\\\t ]+)\\\\d{1,2}:\\\\d{2}:\\\\d{2}(?:\\\\.\\\\d*)?(?:[\\\\t ]*Z|[-+]\\\\d{1,2}(?::\\\\d{1,2})?)?)|(=)|(<<))(?=\\\\s*$|\\\\s+#|\\\\s*:(\\\\s|$))"}]},"flow-scalar-single-quoted":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.yaml"}},"end":"'(?!')","endCaptures":{"0":{"name":"punctuation.definition.string.end.yaml"}},"name":"string.quoted.single.yaml","patterns":[{"match":"''","name":"constant.character.escape.single-quoted.yaml"}]},"flow-sequence":{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.sequence.begin.yaml"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.sequence.end.yaml"}},"name":"meta.flow-sequence.yaml","patterns":[{"include":"#prototype"},{"match":",","name":"punctuation.separator.sequence.yaml"},{"include":"#flow-pair"},{"include":"#flow-node"}]},"flow-value":{"patterns":[{"begin":"\\\\G(?![],}])","end":"(?=[],}])","name":"meta.flow-pair.value.yaml","patterns":[{"include":"#flow-node"}]}]},"node":{"patterns":[{"include":"#block-node"}]},"property":{"begin":"(?=[!\\\\&])","end":"(?!\\\\G)","name":"meta.property.yaml","patterns":[{"captures":{"1":{"name":"keyword.control.property.anchor.yaml"},"2":{"name":"punctuation.definition.anchor.yaml"},"3":{"name":"entity.name.type.anchor.yaml"},"4":{"name":"invalid.illegal.character.anchor.yaml"}},"match":"\\\\G((&))([^],/\\\\[{}\\\\s]+)(\\\\S+)?"},{"match":"\\\\G!(?:<(?:%\\\\h{2}|[]!#$\\\\&-;=?-\\\\[_a-z~])+>|(?:[-0-9A-Za-z]*!)?(?:%\\\\h{2}|[#$\\\\&-+\\\\--;=?-Z_a-z~])+|)(?=[\\\\t ]|$)","name":"storage.type.tag-handle.yaml"},{"match":"\\\\S+","name":"invalid.illegal.tag-handle.yaml"}]},"prototype":{"patterns":[{"include":"#comment"},{"include":"#property"}]}},"scopeName":"source.yaml","aliases":["yml"]}`))];export{t as n,n as t};
|
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>ForgeRelay Diff</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/workspace-app-
|
|
8
|
-
<link rel="
|
|
7
|
+
<script type="module" crossorigin src="./assets/workspace-app-DJmkPYJC.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="./assets/chunk-EyZ2wyi3.js">
|
|
9
|
+
<link rel="modulepreload" crossorigin href="./assets/workspace-app-DkAiSl_0.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="./assets/workspace-app-QyauBrJX.js">
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/workspace-app-CcrHAUIn.css">
|
|
9
12
|
</head>
|
|
10
13
|
<body>
|
|
11
14
|
<main id="app" class="shell">
|
|
@@ -0,0 +1,18 @@
|
|
|
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.0" />
|
|
6
|
+
<title>ForgeRelay Workspace Lifecycle</title>
|
|
7
|
+
<script type="module" crossorigin src="./assets/workspace-lifecycle-app-BIXEo53I.js"></script>
|
|
8
|
+
<link rel="modulepreload" crossorigin href="./assets/chunk-EyZ2wyi3.js">
|
|
9
|
+
<link rel="modulepreload" crossorigin href="./assets/workspace-app-DkAiSl_0.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="./assets/workspace-app-QyauBrJX.js">
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/workspace-app-CcrHAUIn.css">
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<main id="app" class="shell">
|
|
15
|
+
<section class="empty">Waiting for a workspace result.</section>
|
|
16
|
+
</main>
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
package/dist/workspaces.js
CHANGED
|
@@ -713,6 +713,17 @@ export class WorkspaceRegistry {
|
|
|
713
713
|
return absolutePath;
|
|
714
714
|
}
|
|
715
715
|
resolveReadPath(workspace, inputPath) {
|
|
716
|
+
if (inputPath.startsWith("skills://")) {
|
|
717
|
+
const skillRead = resolveSkillReadPath(workspace.skills, workspace.activatedSkillDirs, inputPath);
|
|
718
|
+
if (!skillRead) {
|
|
719
|
+
throw new Error(`Skill resource is not readable before its skill is loaded: ${inputPath}. Read skills://<name> first.`);
|
|
720
|
+
}
|
|
721
|
+
return {
|
|
722
|
+
absolutePath: skillRead.absolutePath,
|
|
723
|
+
readRoots: [workspace.root, skillRead.skill.baseDir],
|
|
724
|
+
skillRead,
|
|
725
|
+
};
|
|
726
|
+
}
|
|
716
727
|
try {
|
|
717
728
|
return {
|
|
718
729
|
absolutePath: this.resolvePath(workspace, inputPath),
|
package/docs/configuration.md
CHANGED
|
@@ -30,7 +30,7 @@ npx @akira-tl/forgerelay init
|
|
|
30
30
|
npx @akira-tl/forgerelay serve
|
|
31
31
|
npx @akira-tl/forgerelay doctor
|
|
32
32
|
npx @akira-tl/forgerelay config get
|
|
33
|
-
npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com
|
|
33
|
+
npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com/forgerelay/main,https://forge-alt.example.com/relay
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Environment variable compatibility
|
|
@@ -55,7 +55,7 @@ When both are present, `FORGERELAY_*` wins.
|
|
|
55
55
|
| `HOST` | Local bind host. Defaults to `127.0.0.1`. |
|
|
56
56
|
| `PORT` | Local port. Defaults to `7676`. |
|
|
57
57
|
| `FORGERELAY_ALLOWED_ROOTS` | Comma-separated roots that workspaces may open. |
|
|
58
|
-
| `FORGERELAY_PUBLIC_BASE_URL` |
|
|
58
|
+
| `FORGERELAY_PUBLIC_BASE_URL` | One public base URL or a comma-separated list. Each URL may include its own routed path prefix; the first URL is canonical. All configured hostnames are added to the derived Host-header allowlist. |
|
|
59
59
|
| `FORGERELAY_ALLOWED_HOSTS` | Optional Host-header allowlist override. |
|
|
60
60
|
| `FORGERELAY_OAUTH_OWNER_TOKEN` | Owner password. Must be at least 16 characters. |
|
|
61
61
|
| `FORGERELAY_STATE_DIR` | SQLite state directory. New default: `~/.local/share/forgerelay`. |
|
|
@@ -63,6 +63,31 @@ When both are present, `FORGERELAY_*` wins.
|
|
|
63
63
|
| `FORGERELAY_WORKFLOW_INSTRUCTIONS` | Replace the built-in workflow policy while retaining the capability contract. |
|
|
64
64
|
| `FORGERELAY_APPEND_INSTRUCTIONS` | Append project/operator workflow policy. |
|
|
65
65
|
|
|
66
|
+
### Routed and multi-origin public deployments
|
|
67
|
+
|
|
68
|
+
`publicBaseUrl` stays the single deployment setting. Persist one URL as a string,
|
|
69
|
+
or multiple URLs as an array:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"publicBaseUrl": [
|
|
74
|
+
"https://forge.example.com/forgerelay/main",
|
|
75
|
+
"https://forge-alt.example.com/relay"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Each entry keeps its own route prefix. The first URL is canonical and is used for
|
|
81
|
+
generated OAuth/MCP URLs; every configured hostname is included in the derived
|
|
82
|
+
Host-header allowlist. MCP App `_meta.ui.domain` uses the canonical URL's origin,
|
|
83
|
+
while CSP resource/connect entries include every full public base URL. The full
|
|
84
|
+
ordered `publicBaseUrl` list also participates in the MCP App resource cache
|
|
85
|
+
identity, so changing any domain or route produces a new `ui://` resource URI.
|
|
86
|
+
|
|
87
|
+
A single persisted string remains fully supported, so existing configs require no
|
|
88
|
+
migration. For environment configuration, use a comma-separated list in
|
|
89
|
+
`FORGERELAY_PUBLIC_BASE_URL`.
|
|
90
|
+
|
|
66
91
|
If an existing legacy state/worktree directory is present and the new default is
|
|
67
92
|
not, ForgeRelay reuses the legacy location rather than orphaning stored state.
|
|
68
93
|
Persisted `stateDir` and `worktreeRoot` values in `config.json` also continue to
|
|
@@ -334,10 +359,17 @@ regular Agent workflows should use the single `bash` process lifecycle.
|
|
|
334
359
|
|
|
335
360
|
| Value | Behavior |
|
|
336
361
|
| --- | --- |
|
|
337
|
-
| `full` | Default. Attach
|
|
338
|
-
| `changes` | Attach
|
|
362
|
+
| `full` | Default. Attach the single ForgeRelay Panel through `activity_panel(workspaceId)`; ordinary work tools remain data-only. |
|
|
363
|
+
| `changes` | Attach the same ForgeRelay Panel while retaining change-review checkpoint behavior. |
|
|
339
364
|
| `off` | Disable widget UI. |
|
|
340
365
|
|
|
366
|
+
The Workspace Summary in the ForgeRelay Panel is always visible. While a Host Turn has no Activity, the Activity section is not rendered. After the first Activity appears, the Activity Panel starts collapsed by default. Set
|
|
367
|
+
`FORGERELAY_ACTIVITY_PANEL_EXPANDED=1` to start each new Host Turn expanded once Activity is present. The
|
|
368
|
+
same preference may be persisted as `activityPanelExpanded: true` in
|
|
369
|
+
`~/.forgerelay/config.json`; an explicit environment variable overrides the
|
|
370
|
+
persisted value. The preference is delivered only to the MCP App and does not
|
|
371
|
+
change the Activity snapshot/query contract.
|
|
372
|
+
|
|
341
373
|
## Lifecycle hooks
|
|
342
374
|
|
|
343
375
|
Hooks v1 是自动生命周期规则。规则由用户或 Agent 主动写入;命中后 ForgeRelay 直接执行,不再增加批准步骤。
|
package/docs/debugging.md
CHANGED
|
@@ -13,8 +13,17 @@ npm run dev
|
|
|
13
13
|
|
|
14
14
|
`npm run debug:serve` is an explicit alias for the same command.
|
|
15
15
|
|
|
16
|
-
The debug launcher uses
|
|
17
|
-
|
|
16
|
+
The interactive debug launcher uses one dedicated persisted configuration at:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
~/.forgerelay/debug/config.json
|
|
20
|
+
~/.forgerelay/debug/auth.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
That configuration is independent from the normal `~/.forgerelay` production
|
|
24
|
+
configuration. Keep the debug public URL, allowed Hosts, roots, runtime state,
|
|
25
|
+
and Owner password there instead of relying on launcher-generated overrides. The
|
|
26
|
+
launcher binds according to that config; the standard local debug setup uses:
|
|
18
27
|
|
|
19
28
|
```text
|
|
20
29
|
http://127.0.0.1:7677
|
|
@@ -29,17 +38,63 @@ http://127.0.0.1:7677/.well-known/oauth-authorization-server
|
|
|
29
38
|
http://127.0.0.1:7677/mcp
|
|
30
39
|
```
|
|
31
40
|
|
|
32
|
-
The debug server watches `src/` and restarts after source changes.
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
The debug server watches `src/` and restarts after source changes. Its Owner
|
|
42
|
+
password comes from `~/.forgerelay/debug/auth.json`, so stopping and restarting
|
|
43
|
+
7677 does not change Host credentials. If the debug endpoint should share the
|
|
44
|
+
production Owner password, copy that value once into the debug `auth.json`; the
|
|
45
|
+
launcher does not synchronize or rotate credentials implicitly.
|
|
46
|
+
|
|
47
|
+
To relocate the entire interactive debug config explicitly, use:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
FORGERELAY_DEBUG_CONFIG_DIR=/path/to/debug-config npm run dev
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Run a local MCP Apps Host
|
|
35
54
|
|
|
36
|
-
|
|
55
|
+
Use MCP Inspector as the fast local Host for MCP App/resource iteration:
|
|
37
56
|
|
|
38
57
|
```bash
|
|
39
|
-
|
|
58
|
+
./scripts/debug/host/run.sh
|
|
40
59
|
```
|
|
41
60
|
|
|
42
|
-
|
|
61
|
+
This launcher starts two owned processes and stops both when it exits:
|
|
62
|
+
|
|
63
|
+
1. ForgeRelay on `127.0.0.1:7677`, using the persisted interactive debug Owner password while forcing the advertised public base URL back to loopback and enabling `widgets=full`;
|
|
64
|
+
2. MCP Inspector Web plus its MCP Apps sandbox, pinned by default to `@modelcontextprotocol/inspector@2.3.0`.
|
|
65
|
+
|
|
66
|
+
The launcher prints and, when supported, opens an Inspector deep link gated by the
|
|
67
|
+
per-run Inspector token. That deep link targets the local ForgeRelay `/mcp`
|
|
68
|
+
endpoint directly, so the browser can complete ForgeRelay OAuth and then inspect
|
|
69
|
+
App tools/resources without a public tunnel or ChatGPT refresh cycle. Inspector
|
|
70
|
+
tokens are redacted from `logs/debug-host-inspector.log`; the ForgeRelay side is
|
|
71
|
+
written to `logs/debug-host-server.log`.
|
|
72
|
+
|
|
73
|
+
The canonical ports are:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
ForgeRelay MCP 7677
|
|
77
|
+
Inspector Web 6274
|
|
78
|
+
Inspector App sandbox 6275
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The launcher never kills or silently reuses an existing listener on those ports.
|
|
82
|
+
A temporary ForgeRelay collision can be avoided for an isolated local check with
|
|
83
|
+
`FORGERELAY_DEBUG_HOST_PORT=<port>`; the repository's canonical debug port remains
|
|
84
|
+
`7677`. Inspector ports can similarly be overridden with
|
|
85
|
+
`MCP_INSPECTOR_CLIENT_PORT` and `MCP_INSPECTOR_SANDBOX_PORT`.
|
|
86
|
+
|
|
87
|
+
MCP Inspector v2 requires Node `>=22.19`. On this development setup its Web client
|
|
88
|
+
can crash in the current Node 26 runtime through a native dependency, while Node
|
|
89
|
+
24 is stable. When the current Node major is 25 or newer, the launcher therefore
|
|
90
|
+
uses the newest installed NVM Node 24 runtime for Inspector when one is available;
|
|
91
|
+
ForgeRelay itself remains on the project's current Node runtime. Override this
|
|
92
|
+
selection explicitly with `MCP_INSPECTOR_NODE_DIR=/path/to/node/bin` when needed.
|
|
93
|
+
|
|
94
|
+
This local Host is the normal fast feedback path for MCP schema, OAuth, resources,
|
|
95
|
+
App rendering, and App-to-server tool calls. It does not replace final ChatGPT Web
|
|
96
|
+
acceptance for ChatGPT-specific iframe lifetime, caching, or Host notification
|
|
97
|
+
behavior.
|
|
43
98
|
|
|
44
99
|
## Run the end-to-end acceptance
|
|
45
100
|
|
|
@@ -47,8 +102,10 @@ Do not use that variable for a publicly reachable ForgeRelay deployment.
|
|
|
47
102
|
npm run debug:accept
|
|
48
103
|
```
|
|
49
104
|
|
|
50
|
-
The acceptance runner starts its own ForgeRelay
|
|
51
|
-
|
|
105
|
+
The acceptance runner starts its own fully isolated ForgeRelay fixture on
|
|
106
|
+
`127.0.0.1:7677`, with its own generated Owner password and checked-in debug
|
|
107
|
+
configuration. It sends real HTTP requests with `curl` and shuts the server down
|
|
108
|
+
when it finishes.
|
|
52
109
|
It refuses to start when port `7677` is already occupied so it cannot
|
|
53
110
|
accidentally validate an older debug process.
|
|
54
111
|
|
|
@@ -100,16 +157,17 @@ console.
|
|
|
100
157
|
|
|
101
158
|
## Debug configuration
|
|
102
159
|
|
|
103
|
-
The checked-in
|
|
160
|
+
The checked-in acceptance-fixture configuration is:
|
|
104
161
|
|
|
105
162
|
```text
|
|
106
163
|
scripts/debug/config.json
|
|
107
164
|
```
|
|
108
165
|
|
|
109
|
-
It deliberately contains no Owner password.
|
|
110
|
-
|
|
166
|
+
It deliberately contains no Owner password. `debug:accept` generates an isolated
|
|
167
|
+
credential and passes it through the environment. Interactive `debug:serve` does
|
|
168
|
+
not use this fixture config; it uses `~/.forgerelay/debug` instead.
|
|
111
169
|
|
|
112
|
-
The
|
|
170
|
+
The acceptance fixture enables all Hooks v1 events with the local recorder at:
|
|
113
171
|
|
|
114
172
|
```text
|
|
115
173
|
scripts/debug/hook-recorder.mjs
|
|
@@ -144,9 +202,9 @@ Acceptance runner 每次都会重建自己的 `acceptance/` 子目录。除了
|
|
|
144
202
|
The debug workflow is intentionally explicit rather than hidden in ad-hoc shell
|
|
145
203
|
commands:
|
|
146
204
|
|
|
147
|
-
- `scripts/debug/config.json` —
|
|
148
|
-
- `scripts/debug/runtime.mjs` — shared paths
|
|
149
|
-
- `scripts/debug/serve.mjs` — watched
|
|
205
|
+
- `scripts/debug/config.json` — isolated acceptance-fixture configuration and hook setup;
|
|
206
|
+
- `scripts/debug/runtime.mjs` — shared paths plus persisted interactive-debug and isolated acceptance environments;
|
|
207
|
+
- `scripts/debug/serve.mjs` — watched 7677 launcher that uses `~/.forgerelay/debug`;
|
|
150
208
|
- `scripts/debug/accept.mjs` — real HTTP/OAuth/MCP acceptance runner;
|
|
151
209
|
- `scripts/debug/hook-recorder.mjs` — sanitized JSONL lifecycle recorder.
|
|
152
210
|
|
package/docs/gotchas.md
CHANGED
|
@@ -49,40 +49,46 @@ FORGERELAY_CONFIG_DIR="$HOME/.forgerelay" forgerelay init
|
|
|
49
49
|
Do not delete the old directory until you have confirmed which persisted state,
|
|
50
50
|
worktrees, skills, and profiles you still need.
|
|
51
51
|
|
|
52
|
-
## Public URL includes `/mcp`
|
|
52
|
+
## Public base URL includes `/mcp`
|
|
53
53
|
|
|
54
|
-
Store the public
|
|
54
|
+
Store the public base URL *before* the final `/mcp`. A routed deployment keeps
|
|
55
|
+
its route inside the URL:
|
|
55
56
|
|
|
56
57
|
```text
|
|
57
|
-
https://your-tunnel-host.example.com
|
|
58
|
+
publicBaseUrl: https://your-tunnel-host.example.com/forgerelay/main
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
The MCP client uses:
|
|
61
|
+
The MCP client then uses:
|
|
61
62
|
|
|
62
63
|
```text
|
|
63
|
-
https://your-tunnel-host.example.com/mcp
|
|
64
|
+
https://your-tunnel-host.example.com/forgerelay/main/mcp
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
Fix
|
|
67
|
+
Fix persisted routing with:
|
|
67
68
|
|
|
68
69
|
```bash
|
|
69
|
-
forgerelay config set publicBaseUrl https://your-tunnel-host.example.com
|
|
70
|
+
forgerelay config set publicBaseUrl https://your-tunnel-host.example.com/forgerelay/main
|
|
70
71
|
```
|
|
71
72
|
|
|
73
|
+
Do not include the final `/mcp` in `publicBaseUrl`.
|
|
74
|
+
|
|
72
75
|
## Tunnel URL changed
|
|
73
76
|
|
|
74
77
|
For one run:
|
|
75
78
|
|
|
76
79
|
```bash
|
|
77
|
-
FORGERELAY_PUBLIC_BASE_URL="https://new-tunnel.example.com" forgerelay serve
|
|
80
|
+
FORGERELAY_PUBLIC_BASE_URL="https://new-tunnel.example.com/forgerelay/main" forgerelay serve
|
|
78
81
|
```
|
|
79
82
|
|
|
80
83
|
For a stable URL:
|
|
81
84
|
|
|
82
85
|
```bash
|
|
83
|
-
forgerelay config set publicBaseUrl https://forge.example.com
|
|
86
|
+
forgerelay config set publicBaseUrl https://forge.example.com/forgerelay/main
|
|
84
87
|
```
|
|
85
88
|
|
|
89
|
+
When multiple public entries are valid, configure them as a list (or a
|
|
90
|
+
comma-separated environment/CLI value); each entry may use a different route.
|
|
91
|
+
|
|
86
92
|
## Host-header or 403 problems
|
|
87
93
|
|
|
88
94
|
Run:
|
package/docs/setup.md
CHANGED
|
@@ -22,8 +22,8 @@ Run:
|
|
|
22
22
|
npx @akira-tl/forgerelay init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The setup flow asks for the allowed project roots, local port,
|
|
26
|
-
|
|
25
|
+
The setup flow asks for the allowed project roots, local port, public domains,
|
|
26
|
+
and an optional routed path prefix.
|
|
27
27
|
|
|
28
28
|
### Project roots
|
|
29
29
|
|
|
@@ -59,16 +59,23 @@ Point your tunnel or reverse proxy at:
|
|
|
59
59
|
http://127.0.0.1:7676
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
Enter
|
|
62
|
+
Enter one or more public base URLs. Each URL may include its own route prefix;
|
|
63
|
+
the first URL is canonical:
|
|
63
64
|
|
|
64
65
|
```text
|
|
65
|
-
https://your-tunnel-host.example.com
|
|
66
|
+
https://your-tunnel-host.example.com/forgerelay/main
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
For multiple public entries, separate them with commas during setup:
|
|
69
70
|
|
|
70
71
|
```text
|
|
71
|
-
https://
|
|
72
|
+
https://forge.example.com/forgerelay/main, https://forge-alt.example.com/relay
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Configure the MCP client with the canonical base URL plus `/mcp`:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
https://your-tunnel-host.example.com/forgerelay/main/mcp
|
|
72
79
|
```
|
|
73
80
|
|
|
74
81
|
## Start the server
|
|
@@ -77,17 +84,24 @@ https://your-tunnel-host.example.com/mcp
|
|
|
77
84
|
npx @akira-tl/forgerelay serve
|
|
78
85
|
```
|
|
79
86
|
|
|
80
|
-
For a one-run public
|
|
87
|
+
For a one-run public deployment override:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
FORGERELAY_PUBLIC_BASE_URL="https://new-tunnel.example.com/forgerelay/main" \
|
|
91
|
+
npx @akira-tl/forgerelay serve
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
For multiple one-run URLs, use a comma-separated list:
|
|
81
95
|
|
|
82
96
|
```bash
|
|
83
|
-
FORGERELAY_PUBLIC_BASE_URL="https://
|
|
97
|
+
FORGERELAY_PUBLIC_BASE_URL="https://forge.example.com/forgerelay/main,https://forge-alt.example.com/relay" \
|
|
84
98
|
npx @akira-tl/forgerelay serve
|
|
85
99
|
```
|
|
86
100
|
|
|
87
|
-
For a stable public
|
|
101
|
+
For a stable public deployment:
|
|
88
102
|
|
|
89
103
|
```bash
|
|
90
|
-
npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com
|
|
104
|
+
npx @akira-tl/forgerelay config set publicBaseUrl https://forge.example.com/forgerelay/main,https://forge-alt.example.com/relay
|
|
91
105
|
npx @akira-tl/forgerelay serve
|
|
92
106
|
```
|
|
93
107
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akira-tl/forgerelay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Local development control plane for MCP coding agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/Akira-TL/forgerelay#readme",
|
|
@@ -44,15 +44,16 @@
|
|
|
44
44
|
"release:parity": "node scripts/release-parity.mjs",
|
|
45
45
|
"postinstall": "node scripts/fix-node-pty-permissions.mjs",
|
|
46
46
|
"start": "node dist/cli.js serve",
|
|
47
|
-
"test": "node --test scripts/release-proof.test.mjs && tsx src/config.test.ts && tsx src/lsp/language-server-config.test.ts && tsx src/lsp/normalization/hover.test.ts && tsx src/lsp/references.server.test.ts && tsx src/lsp/operations/document-symbols.server.test.ts && tsx src/lsp/operations/workspace-symbols.server.test.ts && tsx src/lsp/operations/diagnostics-push.server.test.ts && tsx src/lsp/operations/diagnostics-pull.server.test.ts && tsx src/lsp/operations/request-hardening.server.test.ts && tsx src/lsp/operations/recovery.server.test.ts && tsx src/lsp/operations/lifecycle.server.test.ts && tsx src/lsp/runtime/semantic-requests.test.ts && tsx src/logger.test.ts && tsx src/proxy-trust.test.ts && tsx src/mcp-app-template.test.ts && tsx src/hooks.test.ts && tsx src/capability-registry.test.ts && tsx src/mcp/server-instructions.test.ts && tsx src/request-meta.test.ts && tsx src/incoming-artifacts.test.ts && tsx src/artifact-download.test.ts && tsx src/ui/card-types.test.ts && tsx src/ui/patch-display.test.ts && tsx src/ui/tool-display.test.ts && tsx src/apply-patch.test.ts && tsx src/process-platform.test.ts && tsx src/process-sessions.test.ts && tsx src/mcp-sessions.test.ts && tsx src/server-shutdown.test.ts && tsx src/local-agent-runtime.test.ts && tsx src/local-agent-adapters.test.ts && tsx src/local-agent-availability.test.ts && tsx src/local-agent-profiles.test.ts && tsx src/local-agent-targets.test.ts && tsx src/local-agent-store.test.ts && tsx src/roots.test.ts && tsx src/file-mutations.test.ts && tsx src/operations/edit-preflight.test.ts && tsx src/skills.test.ts && tsx src/db/migrations.test.ts && tsx src/workspace-store.test.ts && tsx src/activity/audit-store.test.ts && tsx src/activity/bash-output-store.test.ts && tsx src/activity/lifecycle.test.ts && tsx src/activity/query-service.test.ts && tsx src/operations/core-operation-executor.test.ts && tsx src/operations/bulk-mutation.test.ts && tsx src/operations/batch/scheduler.test.ts && tsx src/operations/batch/executor-policy.test.ts && tsx src/workspaces.test.ts && tsx src/workspace-conversation.test.ts && tsx src/review-checkpoints.test.ts && tsx src/lsp/code-intelligence.server.test.ts && tsx src/server.test.ts && tsx src/oauth-store.test.ts && tsx src/cli.test.ts",
|
|
47
|
+
"test": "node --test scripts/debug/runtime.test.mjs scripts/release-proof.test.mjs scripts/release/release-gate.test.mjs scripts/release/release-version.test.mjs && tsx src/oauth/router.test.ts && tsx src/config.test.ts && tsx src/lsp/language-server-config.test.ts && tsx src/lsp/normalization/hover.test.ts && tsx src/lsp/references.server.test.ts && tsx src/lsp/operations/document-symbols.server.test.ts && tsx src/lsp/operations/workspace-symbols.server.test.ts && tsx src/lsp/operations/diagnostics-push.server.test.ts && tsx src/lsp/operations/diagnostics-pull.server.test.ts && tsx src/lsp/operations/request-hardening.server.test.ts && tsx src/lsp/operations/recovery.server.test.ts && tsx src/lsp/operations/lifecycle.server.test.ts && tsx src/lsp/runtime/semantic-requests.test.ts && tsx src/logger.test.ts && tsx src/proxy-trust.test.ts && tsx src/mcp-app-template.test.ts && tsx src/hooks.test.ts && tsx src/capability-registry.test.ts && tsx src/mcp/server-instructions.test.ts && tsx src/request-meta.test.ts && tsx src/incoming-artifacts.test.ts && tsx src/artifact-download.test.ts && tsx src/ui/card-types.test.ts && tsx src/ui/workspace-lifecycle-app.test.ts && tsx src/ui/activity/model.test.ts && tsx src/ui/patch-display.test.ts && tsx src/ui/tool-display.test.ts && tsx src/apply-patch.test.ts && tsx src/process-platform.test.ts && tsx src/process-sessions.test.ts && tsx src/mcp-sessions.test.ts && tsx src/server-shutdown.test.ts && tsx src/local-agent-runtime.test.ts && tsx src/local-agent-adapters.test.ts && tsx src/local-agent-availability.test.ts && tsx src/local-agent-profiles.test.ts && tsx src/local-agent-targets.test.ts && tsx src/local-agent-store.test.ts && tsx src/roots.test.ts && tsx src/file-mutations.test.ts && tsx src/operations/edit-preflight.test.ts && tsx src/skills.test.ts && tsx src/db/migrations.test.ts && tsx src/workspace-store.test.ts && tsx src/activity/audit-store.test.ts && tsx src/activity/bash-output-store.test.ts && tsx src/activity/lifecycle.test.ts && tsx src/activity/query-service.test.ts && tsx src/operations/core-operation-executor.test.ts && tsx src/operations/bulk-mutation.test.ts && tsx src/operations/batch/scheduler.test.ts && tsx src/operations/batch/executor-policy.test.ts && tsx src/workspaces.test.ts && tsx src/workspace-conversation.test.ts && tsx src/review-checkpoints.test.ts && tsx src/lsp/code-intelligence.server.test.ts && npm run build:app && tsx src/server.test.ts && tsx src/oauth-store.test.ts && tsx src/cli.test.ts",
|
|
48
48
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
49
49
|
"release:check": "node scripts/release-version.mjs check",
|
|
50
50
|
"release:tag-check": "node scripts/release-version.mjs tag",
|
|
51
|
+
"release:prepare": "node scripts/release-version.mjs prepare",
|
|
51
52
|
"release:next": "node scripts/release-version.mjs next patch",
|
|
52
53
|
"release:patch": "node scripts/release-version.mjs next patch",
|
|
53
54
|
"release:minor": "node scripts/release-version.mjs next minor",
|
|
54
55
|
"release:major": "node scripts/release-version.mjs next major",
|
|
55
|
-
"release:verify": "npm run release:
|
|
56
|
+
"release:verify": "npm run release:parity && node scripts/release-proof.mjs write"
|
|
56
57
|
},
|
|
57
58
|
"keywords": [
|
|
58
59
|
"mcp",
|