@vpxa/aikit 0.1.161 → 0.1.162

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.161",
3
+ "version": "0.1.162",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- import{t as e}from"./curated-manager-BkSgtNC2.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),process.on(`uncaughtException`,e=>{d.error(`Uncaught exception — exiting`,c(e)),process.exit(1)}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-D4z6-EcI.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-gbC5Wmr9.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server--D-DJ9_g.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,l,s.aikit.store),n=s.aikit.store;g=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-D4z6-EcI.js`),import(`./server--D-DJ9_g.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{d.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=f.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`smart`?h.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
1
+ import{t as e}from"./curated-manager-BkSgtNC2.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),process.on(`uncaughtException`,e=>{d.error(`Uncaught exception — exiting`,c(e)),process.exit(1)}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-D4z6-EcI.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-gbC5Wmr9.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-DLkC-unR.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,l,s.aikit.store),n=s.aikit.store;g=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-D4z6-EcI.js`),import(`./server-DLkC-unR.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(async()=>{d.info(`Auto-shutdown: no activity for 30 minutes — shutting down gracefully`);try{let e=f.aikit;e&&await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}catch{}process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`smart`?h.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
@@ -238,7 +238,7 @@ Complements: \`symbol\` (single lookup), \`trace\` (call-chain AST), \`blast_rad
238
238
  { path: 'docs/api.md', title: 'API Reference', status: 'stale' },
239
239
  ],
240
240
  },
241
- }`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`}].map(e=>[e.type,{...e}]));function Pl(){let e={};for(let[t,n]of Nl)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const Fl=1024,Il=new Set([`user-closed`,`host-dismissed`,`replaced`]);function Ll(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function J(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function Rl(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function zl(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`utf8`),r=Buffer.from(t,`utf8`);return n.length===r.length?oe(n,r):!1}function Bl(e,t){let n=e.headers.origin;if(n!=null)return n===t;let r=e.headers.referer;return r==null?!1:r.startsWith(t)}function Vl(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function Hl(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function Ul(e){return Array.isArray(e)&&e.length>Fl?`Selection exceeds ${Fl} items (got ${e.length})`:null}function Wl(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return q(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=Ll(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function Gl(e,t){let n=ie(16).toString(`hex`),r=!1,i=!1,a,o,s=new Promise(e=>{o=e}),c=e=>r?a??e:(r=!0,a=e,o?.(e),e);return{nonce:n,promise:s,settleTimeout(e){return c({kind:`timeout`,waitedMs:e})},settleCancelled(e){return c({kind:`cancelled`,reason:e})},settleError(e,t,n){return c(q(e,t,n))},async handle(r,a,o){if(!Vl(r)){let e=c(q(`INVALID_CONTENT_TYPE`,`Content-Type must be application/json`));return J(a,415,{ok:!1,error:`unsupported-media-type`},o),e}if(!Bl(r,o)){let e=c(q(`INVALID_ORIGIN`,`Unexpected callback origin: ${r.headers.origin??r.headers.referer??`(missing)`}`));return J(a,403,{ok:!1,error:`invalid-origin`},o),e}let s=``;try{s=await Rl(r)}catch(e){let t=c(q(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return J(a,413,{ok:!1,error:`payload-too-large`},o),t}let l;try{let e=JSON.parse(s);if(!Ll(e))throw Error(`Callback payload must be an object`);l=e}catch(e){let t=c(q(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return J(a,400,{ok:!1,error:`invalid-json`},o),t}if(i){let e=q(`NONCE_CONSUMED`,`Nonce has already been used`);return J(a,403,{ok:!1,error:`nonce-consumed`},o),e}if(!zl(typeof l.nonce==`string`?l.nonce:``,n)){let e=c(q(`INVALID_NONCE`,`Callback nonce did not match`));return J(a,403,{ok:!1,error:`invalid-nonce`},o),e}i=!0;let u=Ul(l.selection);if(u){let e=c(q(`SELECTION_TOO_LARGE`,u));return J(a,413,{ok:!1,error:`selection-too-large`},o),e}if(Ll(l.formData)){let e=Hl(l.formData);if(e){let t=c(q(`PAYLOAD_FIELD_TOO_LARGE`,e));return J(a,413,{ok:!1,error:`field-too-large`},o),t}}if(l.kind===`cancelled`){let e=typeof l.reason==`string`?l.reason:``;if(!Il.has(e)){let t=c(q(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return J(a,400,{ok:!1,error:`invalid-cancel-reason`},o),t}let t=c({kind:`cancelled`,reason:e});return J(a,200,{ok:!0,kind:`cancelled`},o),t}let d=c(Wl(l,e,t));return J(a,d.kind===`error`?400:200,{ok:d.kind!==`error`,kind:d.kind},o),d}}}const Kl=new Map;function ql(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,`\\$&`)}function Jl(e){let t=`(?=[^>]*\\bid=['"]${ql(e)}['"])`;return RegExp(`(<script\\b(?=[^>]*\\btype=['"]application\\/json['"])${t}[^>]*>)[\\s\\S]*?(<\/script>)`,`i`)}function Yl(e){Kl.has(e.id)&&console.warn(`[viewer-registry] Overwriting viewer template "${e.id}"`),Kl.set(e.id,e)}function Xl(e){return Kl.get(e)}function Zl(e){return typeof e==`string`&&Kl.has(e)}function Ql(){return[...Kl.values()]}function $l(e,t,n,r){let i=Jl(n);if(!i.test(e))throw Error(`No <script type="application/json" id="${n}"> found in template`);let a=r?r(t):t,o=JSON.stringify(a??null).replace(/<\/script/gi,`<\\/script`);return e.replace(i,`$1\n${o}\n$2`)}const Y=import.meta.dirname??h(x(import.meta.url)),eu={type:`object`,properties:{title:{type:`string`},description:{type:`string`},layout:{type:`object`,properties:{direction:{type:`string`},spacing:{type:`number`},layerSpacing:{type:`number`}}},nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},type:{type:`string`,enum:[`person`,`system`,`container`,`component`,`database`,`queue`,`external`,`boundary`]},label:{type:`string`},technology:{type:`string`},icon:{type:`string`},description:{type:`string`}},required:[`id`,`type`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},style:{type:`string`,enum:[`sync`,`async`,`dashed`,`dotted`,`solid`]}},required:[`source`,`target`]},default:[]}},required:[`nodes`]},tu={type:`object`,properties:{nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`start-end`,`manual`,`automated`,`integration`,`decision`,`prerequisite`]},description:{type:`string`}},required:[`id`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`standard`,`loop-back`,`exception`]}},required:[`source`,`target`]}}},required:[`nodes`]},nu={type:`object`,properties:{title:{type:`string`},description:{type:`string`},phases:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},outcome:{type:`string`},batches:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},order:{type:`number`},parallel:{type:`boolean`},label:{type:`string`},tasks:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},title:{type:`string`},agent:{type:`string`},files:{type:`array`,items:{type:`string`},default:[]},status:{type:`string`,enum:[`pending`,`in-progress`,`done`,`blocked`]},dependsOn:{type:`array`,items:{type:`string`},default:[]}},required:[`id`,`title`]},default:[]}},required:[`id`,`tasks`]},default:[]}},required:[`id`,`label`,`batches`]}}},required:[`phases`]};function ru(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function iu(e,t){return ru(t)?{...t,kind:e}:{kind:e}}function au(e){let t=[...e===`canvas.html`?[_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`)]:[],_(Y,`..`,`..`,`..`,`viewers`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`static`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,e),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,e),_(Y,`..`,`viewers`,`dist`,e),_(Y,`..`,`viewers`,e)];for(let e of t)try{return c(e,`utf8`)}catch{}throw Error(`Viewer HTML not found: ${e}. Searched: ${t.join(`, `)}`)}let ou,su,cu,lu,uu,du;function fu(){return ou??=au(`c4-viewer.html`),ou}function pu(){return su??=au(`tour-viewer.html`),su}function mu(){return cu??=au(`canvas.html`),cu}function hu(){return lu??=au(`architecture-static.html`),lu}function gu(){return uu??=au(`process-flow-static.html`),uu}function _u(){return du??=au(`task-plan-static.html`),du}function vu(){Yl({id:`c4@1`,label:`C4 Architecture Diagram`,description:`Interactive C4 architecture diagram with zoom, pan, and ELK auto-layout`,inputSchema:eu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:fu}),Yl({id:`c4-static@1`,label:`C4 Architecture Diagram (Static)`,description:`Static SVG architecture diagram for inline rendering`,inputSchema:eu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:hu}),Yl({id:`tour@1`,label:`Code Tour Viewer`,description:`Interactive code tour with step navigation and dependency graph`,inputSchema:{type:`object`,properties:{title:{type:`string`},description:{type:`string`},estimatedTime:{type:`string`},steps:{type:`array`,items:{type:`object`,properties:{stepNumber:{type:`number`},id:{type:`string`},title:{type:`string`},file:{type:`string`},explanation:{type:`string`},description:{type:`string`},learnsConcept:{type:`string`},duration:{type:`string`},line:{type:`number`},code:{type:`string`}},required:[`id`,`title`]}},dependencies:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`}},required:[`source`,`target`]},default:[]}},required:[`steps`]},injectId:`tour-data`,supportedTransports:[`browser`],resolveHtml:pu}),Yl({id:`process-flow-static@1`,label:`Process Flow Diagram (Static)`,description:`Static SVG process flow diagram for inline rendering`,inputSchema:tu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:gu}),Yl({id:`task-plan-static@1`,label:`Task Execution Plan (Static)`,description:`Static SVG task execution plan for inline rendering`,inputSchema:nu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:_u}),Yl({id:`task-plan@1`,label:`Task Execution Plan (Interactive)`,description:`Interactive task execution plan with ReactFlow, phase grouping, and dependency edges`,inputSchema:nu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:mu,transformData:e=>iu(`task-plan`,e)}),Yl({id:`process-flow@1`,label:`Process Flow Diagram (Interactive)`,description:`Interactive process flow diagram with ReactFlow`,inputSchema:tu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:mu,transformData:e=>iu(`process-flow`,e)})}function yu(){let e=new zn;for(let t of Hn.list())e.register(t);return e.register(Vn),e.register(Kn),e.register(qn),e.register(Un),e}function bu(e,t){return e?.supportedTransports.includes(t)??!1}const xu=yu();function Su(e){if(e.template)return xu.get(e.template)}function Cu(e){if((e.actions?.length??0)>0)return!0;if(e.template&&Zl(e.template)){let t=Xl(e.template);return t?.supportedTransports.includes(`browser`)===!0&&!t.supportedTransports.includes(`mcp-app`)}let t=Su(e);return bu(t,`browser`)&&!bu(t,`mcp-app`)}vu();function wu(){let e;return()=>{if(e!==void 0)return e;try{e=c(a(import.meta.url).resolve(`mermaid/dist/mermaid.min.js`),`utf-8`)}catch{e=``}return e}}const Tu={id:`mermaid`,cdn:`https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js`,initScript:`window.__aikit_initMermaid = function() {
241
+ }`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`}].map(e=>[e.type,{...e}]));function Pl(){let e={};for(let[t,n]of Nl)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}const Fl=1024,Il=new Set([`user-closed`,`host-dismissed`,`replaced`]);function Ll(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function J(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function Rl(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function zl(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`utf8`),r=Buffer.from(t,`utf8`);return n.length===r.length?oe(n,r):!1}function Bl(e,t){let n=e.headers.origin;if(n!=null)return n===t;let r=e.headers.referer;return r==null?!1:r.startsWith(t)}function Vl(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function Hl(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function Ul(e){return Array.isArray(e)&&e.length>Fl?`Selection exceeds ${Fl} items (got ${e.length})`:null}function Wl(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return q(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=Ll(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function Gl(e,t){let n=ie(16).toString(`hex`),r=!1,i=!1,a,o,s=new Promise(e=>{o=e}),c=e=>r?a??e:(r=!0,a=e,o?.(e),e);return{nonce:n,promise:s,settleTimeout(e){return c({kind:`timeout`,waitedMs:e})},settleCancelled(e){return c({kind:`cancelled`,reason:e})},settleError(e,t,n){return c(q(e,t,n))},async handle(r,a,o){if(!Vl(r)){let e=c(q(`INVALID_CONTENT_TYPE`,`Content-Type must be application/json`));return J(a,415,{ok:!1,error:`unsupported-media-type`},o),e}if(!Bl(r,o)){let e=c(q(`INVALID_ORIGIN`,`Unexpected callback origin: ${r.headers.origin??r.headers.referer??`(missing)`}`));return J(a,403,{ok:!1,error:`invalid-origin`},o),e}let s=``;try{s=await Rl(r)}catch(e){let t=c(q(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return J(a,413,{ok:!1,error:`payload-too-large`},o),t}let l;try{let e=JSON.parse(s);if(!Ll(e))throw Error(`Callback payload must be an object`);l=e}catch(e){let t=c(q(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return J(a,400,{ok:!1,error:`invalid-json`},o),t}if(i){let e=q(`NONCE_CONSUMED`,`Nonce has already been used`);return J(a,403,{ok:!1,error:`nonce-consumed`},o),e}if(!zl(typeof l.nonce==`string`?l.nonce:``,n)){let e=c(q(`INVALID_NONCE`,`Callback nonce did not match`));return J(a,403,{ok:!1,error:`invalid-nonce`},o),e}i=!0;let u=Ul(l.selection);if(u){let e=c(q(`SELECTION_TOO_LARGE`,u));return J(a,413,{ok:!1,error:`selection-too-large`},o),e}if(Ll(l.formData)){let e=Hl(l.formData);if(e){let t=c(q(`PAYLOAD_FIELD_TOO_LARGE`,e));return J(a,413,{ok:!1,error:`field-too-large`},o),t}}if(l.kind===`cancelled`){let e=typeof l.reason==`string`?l.reason:``;if(!Il.has(e)){let t=c(q(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return J(a,400,{ok:!1,error:`invalid-cancel-reason`},o),t}let t=c({kind:`cancelled`,reason:e});return J(a,200,{ok:!0,kind:`cancelled`},o),t}let d=c(Wl(l,e,t));return J(a,d.kind===`error`?400:200,{ok:d.kind!==`error`,kind:d.kind},o),d}}}const Kl=new Map;function ql(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,`\\$&`)}function Jl(e){let t=`(?=[^>]*\\bid=['"]${ql(e)}['"])`;return RegExp(`(<script\\b(?=[^>]*\\btype=['"]application\\/json['"])${t}[^>]*>)[\\s\\S]*?(<\/script>)`,`i`)}function Yl(e){Kl.has(e.id)&&console.warn(`[viewer-registry] Overwriting viewer template "${e.id}"`),Kl.set(e.id,e)}function Xl(e){return Kl.get(e)}function Zl(e){return typeof e==`string`&&Kl.has(e)}function Ql(){return[...Kl.values()]}function $l(e,t,n,r){let i=Jl(n);if(!i.test(e))throw Error(`No <script type="application/json" id="${n}"> found in template`);let a=r?r(t):t,o=JSON.stringify(a??null).replace(/<\/script/gi,`<\\/script`).replace(/<script/gi,`\\u003Cscript`).replace(/-->/g,`--\\u003E`).replace(/<!--/g,`\\u003C!--`);return e.replace(i,`$1\n${o}\n$2`)}const Y=import.meta.dirname??h(x(import.meta.url)),eu={type:`object`,properties:{title:{type:`string`},description:{type:`string`},layout:{type:`object`,properties:{direction:{type:`string`},spacing:{type:`number`},layerSpacing:{type:`number`}}},nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},type:{type:`string`,enum:[`person`,`system`,`container`,`component`,`database`,`queue`,`external`,`boundary`]},label:{type:`string`},technology:{type:`string`},icon:{type:`string`},description:{type:`string`}},required:[`id`,`type`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},style:{type:`string`,enum:[`sync`,`async`,`dashed`,`dotted`,`solid`]}},required:[`source`,`target`]},default:[]}},required:[`nodes`]},tu={type:`object`,properties:{nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`start-end`,`manual`,`automated`,`integration`,`decision`,`prerequisite`]},description:{type:`string`}},required:[`id`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`standard`,`loop-back`,`exception`]}},required:[`source`,`target`]}}},required:[`nodes`]},nu={type:`object`,properties:{title:{type:`string`},description:{type:`string`},phases:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},outcome:{type:`string`},batches:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},order:{type:`number`},parallel:{type:`boolean`},label:{type:`string`},tasks:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},title:{type:`string`},agent:{type:`string`},files:{type:`array`,items:{type:`string`},default:[]},status:{type:`string`,enum:[`pending`,`in-progress`,`done`,`blocked`]},dependsOn:{type:`array`,items:{type:`string`},default:[]}},required:[`id`,`title`]},default:[]}},required:[`id`,`tasks`]},default:[]}},required:[`id`,`label`,`batches`]}}},required:[`phases`]};function ru(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function iu(e,t){return ru(t)?{...t,kind:e}:{kind:e}}function au(e){let t=[...e===`canvas.html`?[_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`)]:[],_(Y,`..`,`..`,`..`,`viewers`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`static`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),_(Y,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,e),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),_(Y,`..`,`..`,`scaffold`,`general`,`viewers`,e),_(Y,`..`,`viewers`,`dist`,e),_(Y,`..`,`viewers`,e)];for(let e of t)try{return c(e,`utf8`)}catch{}throw Error(`Viewer HTML not found: ${e}. Searched: ${t.join(`, `)}`)}let ou,su,cu,lu,uu,du;function fu(){return ou??=au(`c4-viewer.html`),ou}function pu(){return su??=au(`tour-viewer.html`),su}function mu(){return cu??=au(`canvas.html`),cu}function hu(){return lu??=au(`architecture-static.html`),lu}function gu(){return uu??=au(`process-flow-static.html`),uu}function _u(){return du??=au(`task-plan-static.html`),du}function vu(){Yl({id:`c4@1`,label:`C4 Architecture Diagram`,description:`Interactive C4 architecture diagram with zoom, pan, and ELK auto-layout`,inputSchema:eu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:fu}),Yl({id:`c4-static@1`,label:`C4 Architecture Diagram (Static)`,description:`Static SVG architecture diagram for inline rendering`,inputSchema:eu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:hu}),Yl({id:`tour@1`,label:`Code Tour Viewer`,description:`Interactive code tour with step navigation and dependency graph`,inputSchema:{type:`object`,properties:{title:{type:`string`},description:{type:`string`},estimatedTime:{type:`string`},steps:{type:`array`,items:{type:`object`,properties:{stepNumber:{type:`number`},id:{type:`string`},title:{type:`string`},file:{type:`string`},explanation:{type:`string`},description:{type:`string`},learnsConcept:{type:`string`},duration:{type:`string`},line:{type:`number`},code:{type:`string`}},required:[`id`,`title`]}},dependencies:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`}},required:[`source`,`target`]},default:[]}},required:[`steps`]},injectId:`tour-data`,supportedTransports:[`browser`],resolveHtml:pu}),Yl({id:`process-flow-static@1`,label:`Process Flow Diagram (Static)`,description:`Static SVG process flow diagram for inline rendering`,inputSchema:tu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:gu}),Yl({id:`task-plan-static@1`,label:`Task Execution Plan (Static)`,description:`Static SVG task execution plan for inline rendering`,inputSchema:nu,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:_u}),Yl({id:`task-plan@1`,label:`Task Execution Plan (Interactive)`,description:`Interactive task execution plan with ReactFlow, phase grouping, and dependency edges`,inputSchema:nu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:mu,transformData:e=>iu(`task-plan`,e)}),Yl({id:`process-flow@1`,label:`Process Flow Diagram (Interactive)`,description:`Interactive process flow diagram with ReactFlow`,inputSchema:tu,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:mu,transformData:e=>iu(`process-flow`,e)})}function yu(){let e=new zn;for(let t of Hn.list())e.register(t);return e.register(Vn),e.register(Kn),e.register(qn),e.register(Un),e}function bu(e,t){return e?.supportedTransports.includes(t)??!1}const xu=yu();function Su(e){if(e.template)return xu.get(e.template)}function Cu(e){if((e.actions?.length??0)>0)return!0;if(e.template&&Zl(e.template)){let t=Xl(e.template);return t?.supportedTransports.includes(`browser`)===!0&&!t.supportedTransports.includes(`mcp-app`)}let t=Su(e);return bu(t,`browser`)&&!bu(t,`mcp-app`)}vu();function wu(){let e;return()=>{if(e!==void 0)return e;try{e=c(a(import.meta.url).resolve(`mermaid/dist/mermaid.min.js`),`utf-8`)}catch{e=``}return e}}const Tu={id:`mermaid`,cdn:`https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js`,initScript:`window.__aikit_initMermaid = function() {
242
242
  if (typeof mermaid === 'undefined') return;
243
243
  if (document.readyState === 'loading') {
244
244
  document.addEventListener('DOMContentLoaded', window.__aikit_initMermaid);
@@ -34,7 +34,7 @@
34
34
  --dt-text-primary: #0f172a;
35
35
  --dt-text-secondary: #64748b;
36
36
  --dt-border: #e2e8f0;
37
- --dt-grid: #f1f5f9;
37
+ --dt-grid: rgba(148, 163, 184, 0.12);
38
38
  --dt-shadow: rgba(148, 163, 184, 0.24);
39
39
  --dt-toolbar-bg: rgba(255, 255, 255, 0.88);
40
40
  --dt-button-bg: rgba(248, 250, 252, 0.96);
@@ -52,7 +52,7 @@
52
52
  --dt-text-primary: #0f172a;
53
53
  --dt-text-secondary: #64748b;
54
54
  --dt-border: #e2e8f0;
55
- --dt-grid: #f1f5f9;
55
+ --dt-grid: rgba(148, 163, 184, 0.12);
56
56
  --dt-shadow: rgba(148, 163, 184, 0.24);
57
57
  --dt-toolbar-bg: rgba(255, 255, 255, 0.88);
58
58
  --dt-button-bg: rgba(248, 250, 252, 0.96);
@@ -149,7 +149,11 @@
149
149
  min-height: calc(100vh - 5.5rem);
150
150
  border: 1px solid var(--dt-border);
151
151
  border-radius: 24px;
152
- background: var(--dt-panel-bg);
152
+ background:
153
+ linear-gradient(var(--dt-grid) 1px, transparent 1px),
154
+ linear-gradient(90deg, var(--dt-grid) 1px, transparent 1px),
155
+ var(--dt-panel-bg);
156
+ background-size: 40px 40px, 40px 40px, 100% 100%;
153
157
  overflow: hidden;
154
158
  box-shadow: 0 24px 60px var(--dt-shadow);
155
159
  }
@@ -554,19 +558,6 @@
554
558
 
555
559
  function renderDefs() {
556
560
  const defs = node('defs');
557
- const pattern = node('pattern', {
558
- id: 'grid',
559
- width: 40,
560
- height: 40,
561
- patternUnits: 'userSpaceOnUse',
562
- });
563
- pattern.appendChild(node('path', {
564
- d: 'M 40 0 L 0 0 0 40',
565
- fill: 'none',
566
- stroke: cssValue('--dt-grid'),
567
- 'stroke-width': 1,
568
- }));
569
- defs.appendChild(pattern);
570
561
 
571
562
  const marker = node('marker', {
572
563
  id: 'arrow',
@@ -813,7 +804,6 @@
813
804
  svg.setAttribute('aria-label', (raw.title || 'Architecture diagram') + ' with ' + model.nodes.length + ' nodes');
814
805
 
815
806
  svg.appendChild(renderDefs());
816
- svg.appendChild(node('rect', { x: 0, y: 0, width, height, fill: 'url(#grid)' }));
817
807
 
818
808
  const title = node('title', { id: 'diagram-title' }, raw.title || 'Architecture diagram');
819
809
  const description = node('desc', { id: 'diagram-description' }, raw.description || 'Static architecture diagram rendered with SVG');
@@ -42,7 +42,7 @@
42
42
  --dt-text-primary: #0f172a;
43
43
  --dt-text-secondary: #64748b;
44
44
  --dt-border: #e2e8f0;
45
- --dt-grid: #f1f5f9;
45
+ --dt-grid: rgba(148, 163, 184, 0.12);
46
46
  --dt-shadow: rgba(148, 163, 184, 0.24);
47
47
  --dt-toolbar-bg: rgba(255, 255, 255, 0.88);
48
48
  --dt-button-bg: rgba(248, 250, 252, 0.96);
@@ -59,7 +59,7 @@
59
59
  --dt-text-primary: #0f172a;
60
60
  --dt-text-secondary: #64748b;
61
61
  --dt-border: #e2e8f0;
62
- --dt-grid: #f1f5f9;
62
+ --dt-grid: rgba(148, 163, 184, 0.12);
63
63
  --dt-shadow: rgba(148, 163, 184, 0.24);
64
64
  --dt-toolbar-bg: rgba(255, 255, 255, 0.88);
65
65
  --dt-button-bg: rgba(248, 250, 252, 0.96);
@@ -155,7 +155,11 @@
155
155
  min-height: calc(100vh - 5.5rem);
156
156
  border: 1px solid var(--dt-border);
157
157
  border-radius: 24px;
158
- background: var(--dt-panel-bg);
158
+ background:
159
+ linear-gradient(var(--dt-grid) 1px, transparent 1px),
160
+ linear-gradient(90deg, var(--dt-grid) 1px, transparent 1px),
161
+ var(--dt-panel-bg);
162
+ background-size: 40px 40px, 40px 40px, 100% 100%;
159
163
  overflow: hidden;
160
164
  box-shadow: 0 24px 60px var(--dt-shadow);
161
165
  }
@@ -659,20 +663,6 @@
659
663
  function renderDefs() {
660
664
  const defs = node('defs');
661
665
 
662
- const pattern = node('pattern', {
663
- id: 'grid',
664
- width: 40,
665
- height: 40,
666
- patternUnits: 'userSpaceOnUse',
667
- });
668
- pattern.appendChild(node('path', {
669
- d: 'M 40 0 L 0 0 0 40',
670
- fill: 'none',
671
- stroke: cssValue('--dt-grid'),
672
- 'stroke-width': 1,
673
- }));
674
- defs.appendChild(pattern);
675
-
676
666
  const marker = node('marker', {
677
667
  id: 'arrow',
678
668
  viewBox: '0 0 10 10',
@@ -1020,7 +1010,6 @@
1020
1010
  svg.setAttribute('viewBox', '0 0 ' + layoutResult.width + ' ' + layoutResult.height);
1021
1011
  svg.setAttribute('aria-label', model.title + ' with ' + totalTasks + ' tasks');
1022
1012
  svg.appendChild(renderDefs());
1023
- svg.appendChild(node('rect', { x: 0, y: 0, width: layoutResult.width, height: layoutResult.height, fill: 'url(#grid)' }));
1024
1013
  svg.appendChild(node('title', { id: 'diagram-title' }, model.title || 'Task execution plan'));
1025
1014
  svg.appendChild(node('desc', { id: 'diagram-description' }, model.description || 'Static task execution plan rendered with SVG'));
1026
1015