@archon-claw/cli 0.5.1 → 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.
@@ -1 +1 @@
1
- import{u as t,r as n,i,j as e,b as d,C as l,X as x,d as u}from"./chat-input-D-F2IIDK.js";function m(){return e.jsxs("div",{className:"flex h-10 shrink-0 items-center justify-between border-b px-3",children:[e.jsx("span",{className:"text-sm font-semibold",children:"Archon Claw"}),e.jsx("button",{type:"button",className:"text-muted-foreground hover:bg-accent rounded p-1 transition-colors",onClick:()=>window.parent.postMessage({type:"archon-claw:request-close"},"*"),children:e.jsx(x,{className:"h-4 w-4"})})]})}function h(){const a=t(s=>s.setAgentId),o=t(s=>s.createSession),r=t(s=>s.activeSession());return n.useEffect(()=>{const c=new URLSearchParams(window.location.search).get("agentId");c&&a(c),i()},[a]),n.useEffect(()=>{r||o()},[r,o]),e.jsxs("div",{className:"flex h-dvh flex-col bg-background text-foreground",children:[e.jsx(m,{}),e.jsx(d,{}),e.jsx(l,{})]})}u.createRoot(document.getElementById("embed-root")).render(e.jsx(n.StrictMode,{children:e.jsx(h,{})}));
1
+ import{u as t,r as n,i,j as e,b as d,C as l,X as x,d as u}from"./chat-input-BNct1ILJ.js";function h(){return e.jsxs("div",{className:"flex h-10 shrink-0 items-center justify-between border-b px-3",children:[e.jsx("span",{className:"text-sm font-semibold",children:"Archon Claw"}),e.jsx("button",{type:"button",className:"text-muted-foreground hover:bg-accent rounded p-1 transition-colors",onClick:()=>window.parent.postMessage({type:"archon-claw:request-close"},"*"),children:e.jsx(x,{className:"h-4 w-4"})})]})}function m(){const a=t(s=>s.setAgentId),o=t(s=>s.createSession),r=t(s=>s.activeSession());return n.useEffect(()=>{const c=new URLSearchParams(window.location.search).get("agentId")??globalThis.__ARCHON_DEFAULT_AGENT__;c&&a(c),i()},[a]),n.useEffect(()=>{r||o()},[r,o]),e.jsxs("div",{className:"flex h-dvh flex-col bg-background text-foreground",children:[e.jsx(h,{}),e.jsx(d,{}),e.jsx(l,{})]})}u.createRoot(document.getElementById("embed-root")).render(e.jsx(n.StrictMode,{children:e.jsx(m,{})}));
@@ -1,4 +1,4 @@
1
- import{c as h,r as d,j as e,a as x,u as t,B as i,X as f,M as p,b,C as g,d as j}from"./chat-input-D-F2IIDK.js";/**
1
+ import{c as h,r as d,j as e,a as x,u as t,B as i,X as f,M as p,b,C as g,d as j}from"./chat-input-BNct1ILJ.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -13,4 +13,4 @@ import{c as h,r as d,j as e,a as x,u as t,B as i,X as f,M as p,b,C as g,d as j}f
13
13
  *
14
14
  * This source code is licensed under the ISC license.
15
15
  * See the LICENSE file in the root directory of this source tree.
16
- */const w=h("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);function N({content:o,children:a,side:n="top"}){const[l,r]=d.useState(!1),c={top:"bottom-full left-1/2 -translate-x-1/2 mb-2",bottom:"top-full left-1/2 -translate-x-1/2 mt-2",left:"right-full top-1/2 -translate-y-1/2 mr-2",right:"left-full top-1/2 -translate-y-1/2 ml-2"};return e.jsxs("div",{className:"relative inline-flex",onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),children:[a,l&&e.jsx("div",{className:x("absolute z-50 whitespace-nowrap rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md border border-border animate-in fade-in-0",c[n]),children:o})]})}function k(){const o=t(s=>s.sessions),a=t(s=>s.activeLocalId),n=t(s=>s.sidebarOpen),l=t(s=>s.setSidebarOpen),r=t(s=>s.createSession),c=t(s=>s.switchSession),m=t(s=>s.deleteSession);return e.jsxs(e.Fragment,{children:[n&&e.jsx("div",{className:"fixed inset-0 z-40 bg-black/60 md:hidden",onClick:()=>l(!1)}),e.jsxs("aside",{className:x("fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r border-border bg-secondary transition-transform duration-200 md:relative md:translate-x-0",n?"translate-x-0":"-translate-x-full"),children:[e.jsxs("div",{className:"flex h-14 items-center justify-between border-b border-border px-4",children:[e.jsx("h1",{className:"text-sm font-semibold text-foreground",children:"Archon Claw"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(N,{content:"New chat",side:"bottom",children:e.jsx(i,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:r,children:e.jsx(v,{className:"h-4 w-4"})})}),e.jsx(i,{variant:"ghost",size:"icon",className:"h-8 w-8 md:hidden",onClick:()=>l(!1),children:e.jsx(f,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-2",children:[o.length===0&&e.jsx("p",{className:"px-2 py-4 text-center text-xs text-muted-foreground",children:"No conversations yet"}),o.map(s=>e.jsxs("div",{className:x("group flex items-center gap-2 rounded-lg px-3 py-2 text-sm cursor-pointer transition-colors",s.localId===a?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:bg-accent"),onClick:()=>c(s.localId),children:[e.jsx(p,{className:"h-4 w-4 shrink-0"}),e.jsx("span",{className:"flex-1 truncate",children:s.title}),e.jsx(i,{variant:"ghost",size:"icon",className:"h-6 w-6 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity",onClick:u=>{u.stopPropagation(),m(s.localId)},children:e.jsx(w,{className:"h-3.5 w-3.5 text-muted-foreground hover:text-destructive"})})]},s.localId))]})]})]})}function S(){const o=t(n=>n.setSidebarOpen),a=t(n=>n.activeSession());return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex h-14 items-center gap-3 border-b border-border px-4",children:[e.jsx(i,{variant:"ghost",size:"icon",className:"md:hidden",onClick:()=>o(!0),children:e.jsx(y,{className:"h-5 w-5"})}),e.jsx("h2",{className:"truncate text-sm font-medium text-foreground",children:(a==null?void 0:a.title)??""})]}),e.jsx(b,{}),e.jsx(g,{})]})}function I(){const o=t(r=>r.setAgentId),a=t(r=>r.loadSessions),[n,l]=d.useState(!1);return d.useEffect(()=>{const c=new URLSearchParams(window.location.search).get("agentId");c&&o(c),a().then(()=>l(!0)).catch(()=>l(!0))},[o,a]),n?e.jsxs("div",{className:"flex h-dvh overflow-hidden bg-background text-foreground",children:[e.jsx(k,{}),e.jsx("main",{className:"flex-1 overflow-hidden",children:e.jsx(S,{})})]}):null}j.createRoot(document.getElementById("root")).render(e.jsx(d.StrictMode,{children:e.jsx(I,{})}));
16
+ */const N=h("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);function w({content:o,children:a,side:n="top"}){const[l,r]=d.useState(!1),c={top:"bottom-full left-1/2 -translate-x-1/2 mb-2",bottom:"top-full left-1/2 -translate-x-1/2 mt-2",left:"right-full top-1/2 -translate-y-1/2 mr-2",right:"left-full top-1/2 -translate-y-1/2 ml-2"};return e.jsxs("div",{className:"relative inline-flex",onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),children:[a,l&&e.jsx("div",{className:x("absolute z-50 whitespace-nowrap rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md border border-border animate-in fade-in-0",c[n]),children:o})]})}function k(){const o=t(s=>s.sessions),a=t(s=>s.activeLocalId),n=t(s=>s.sidebarOpen),l=t(s=>s.setSidebarOpen),r=t(s=>s.createSession),c=t(s=>s.switchSession),m=t(s=>s.deleteSession);return e.jsxs(e.Fragment,{children:[n&&e.jsx("div",{className:"fixed inset-0 z-40 bg-black/60 md:hidden",onClick:()=>l(!1)}),e.jsxs("aside",{className:x("fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r border-border bg-secondary transition-transform duration-200 md:relative md:translate-x-0",n?"translate-x-0":"-translate-x-full"),children:[e.jsxs("div",{className:"flex h-14 items-center justify-between border-b border-border px-4",children:[e.jsx("h1",{className:"text-sm font-semibold text-foreground",children:"Archon Claw"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(w,{content:"New chat",side:"bottom",children:e.jsx(i,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:r,children:e.jsx(v,{className:"h-4 w-4"})})}),e.jsx(i,{variant:"ghost",size:"icon",className:"h-8 w-8 md:hidden",onClick:()=>l(!1),children:e.jsx(f,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-2",children:[o.length===0&&e.jsx("p",{className:"px-2 py-4 text-center text-xs text-muted-foreground",children:"No conversations yet"}),o.map(s=>e.jsxs("div",{className:x("group flex items-center gap-2 rounded-lg px-3 py-2 text-sm cursor-pointer transition-colors",s.localId===a?"bg-background text-foreground shadow-sm":"text-muted-foreground hover:bg-accent"),onClick:()=>c(s.localId),children:[e.jsx(p,{className:"h-4 w-4 shrink-0"}),e.jsx("span",{className:"flex-1 truncate",children:s.title}),e.jsx(i,{variant:"ghost",size:"icon",className:"h-6 w-6 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity",onClick:u=>{u.stopPropagation(),m(s.localId)},children:e.jsx(N,{className:"h-3.5 w-3.5 text-muted-foreground hover:text-destructive"})})]},s.localId))]})]})]})}function S(){const o=t(n=>n.setSidebarOpen),a=t(n=>n.activeSession());return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex h-14 items-center gap-3 border-b border-border px-4",children:[e.jsx(i,{variant:"ghost",size:"icon",className:"md:hidden",onClick:()=>o(!0),children:e.jsx(y,{className:"h-5 w-5"})}),e.jsx("h2",{className:"truncate text-sm font-medium text-foreground",children:(a==null?void 0:a.title)??""})]}),e.jsx(b,{}),e.jsx(g,{})]})}function C(){const o=t(r=>r.setAgentId),a=t(r=>r.loadSessions),[n,l]=d.useState(!1);return d.useEffect(()=>{const c=new URLSearchParams(window.location.search).get("agentId")??globalThis.__ARCHON_DEFAULT_AGENT__;c&&o(c),a().then(()=>l(!0)).catch(()=>l(!0))},[o,a]),n?e.jsxs("div",{className:"flex h-dvh overflow-hidden bg-background text-foreground",children:[e.jsx(k,{}),e.jsx("main",{className:"flex-1 overflow-hidden",children:e.jsx(S,{})})]}):null}j.createRoot(document.getElementById("root")).render(e.jsx(d.StrictMode,{children:e.jsx(C,{})}));
@@ -4,9 +4,9 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Archon Claw Embed</title>
7
- <script type="module" crossorigin src="/assets/embed-XPDwGdtM.js"></script>
8
- <link rel="modulepreload" crossorigin href="/assets/chat-input-D-F2IIDK.js">
9
- <link rel="stylesheet" crossorigin href="/assets/chat-input-qoFFWtdQ.css">
7
+ <script type="module" crossorigin src="./assets/embed-D4R7hpA_.js"></script>
8
+ <link rel="modulepreload" crossorigin href="./assets/chat-input-BNct1ILJ.js">
9
+ <link rel="stylesheet" crossorigin href="./assets/chat-input-qoFFWtdQ.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="embed-root"></div>
@@ -4,9 +4,9 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Archon Claw</title>
7
- <script type="module" crossorigin src="/assets/main-DDb5hJ5F.js"></script>
8
- <link rel="modulepreload" crossorigin href="/assets/chat-input-D-F2IIDK.js">
9
- <link rel="stylesheet" crossorigin href="/assets/chat-input-qoFFWtdQ.css">
7
+ <script type="module" crossorigin src="./assets/main-C4meEBxF.js"></script>
8
+ <link rel="modulepreload" crossorigin href="./assets/chat-input-BNct1ILJ.js">
9
+ <link rel="stylesheet" crossorigin href="./assets/chat-input-qoFFWtdQ.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
package/dist/server.d.ts CHANGED
@@ -6,5 +6,9 @@ export interface AgentEntry {
6
6
  sessions: SessionStore;
7
7
  }
8
8
  type AgentResolver = Map<string, AgentEntry> | (() => Map<string, AgentEntry>);
9
- export declare function createServer(agents: AgentResolver, port: number): http.Server;
9
+ export declare function normalizeBasePath(raw?: string): string;
10
+ export interface ServerOptions {
11
+ basePath?: string;
12
+ }
13
+ export declare function createServer(agents: AgentResolver, port: number, options?: ServerOptions): http.Server;
10
14
  export {};
package/dist/server.js CHANGED
@@ -33,25 +33,40 @@ function resolveStaticFile(pathname) {
33
33
  }
34
34
  return null;
35
35
  }
36
- function serveStatic(res, pathname) {
36
+ function serveStatic(res, pathname, injection) {
37
37
  // Serve embed.html directly (not SPA fallback)
38
38
  if (pathname === "/embed.html" || pathname === "/embed") {
39
39
  const embedPath = resolveStaticFile("embed.html");
40
- return embedPath ? serveFile(res, embedPath) : false;
40
+ return embedPath ? serveFile(res, embedPath, injection) : false;
41
41
  }
42
42
  const resolved = resolveStaticFile(pathname);
43
43
  if (resolved)
44
- return serveFile(res, resolved);
44
+ return serveFile(res, resolved, path.extname(resolved) === ".html" ? injection : undefined);
45
45
  // SPA fallback
46
46
  const indexPath = resolveStaticFile("index.html");
47
- return indexPath ? serveFile(res, indexPath) : false;
47
+ return indexPath ? serveFile(res, indexPath, injection) : false;
48
48
  }
49
- function serveFile(res, filePath) {
49
+ function serveFile(res, filePath, injection) {
50
50
  if (!fs.existsSync(filePath))
51
51
  return false;
52
52
  const ext = path.extname(filePath);
53
53
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
54
54
  const content = fs.readFileSync(filePath);
55
+ // Inject runtime config into HTML responses
56
+ if (ext === ".html" && injection) {
57
+ const vars = [];
58
+ if (injection.basePath)
59
+ vars.push(`window.__ARCHON_BASE_PATH__=${JSON.stringify(injection.basePath)}`);
60
+ if (injection.defaultAgent)
61
+ vars.push(`window.__ARCHON_DEFAULT_AGENT__=${JSON.stringify(injection.defaultAgent)}`);
62
+ if (vars.length > 0) {
63
+ let html = content.toString("utf-8");
64
+ html = html.replace("<head>", `<head><script>${vars.join(";")}</script>`);
65
+ res.writeHead(200, { "Content-Type": contentType });
66
+ res.end(html);
67
+ return true;
68
+ }
69
+ }
55
70
  res.writeHead(200, { "Content-Type": contentType });
56
71
  res.end(content);
57
72
  return true;
@@ -96,12 +111,30 @@ function readBody(req) {
96
111
  });
97
112
  });
98
113
  }
99
- export function createServer(agents, port) {
114
+ export function normalizeBasePath(raw) {
115
+ if (!raw || raw === "/")
116
+ return "";
117
+ let p = raw;
118
+ if (!p.startsWith("/"))
119
+ p = "/" + p;
120
+ if (p.endsWith("/"))
121
+ p = p.slice(0, -1);
122
+ return p;
123
+ }
124
+ export function createServer(agents, port, options) {
100
125
  const resolveAgents = typeof agents === "function" ? agents : () => agents;
126
+ const basePath = normalizeBasePath(options?.basePath ?? process.env.BASE_PATH);
101
127
  const server = http.createServer(async (req, res) => {
102
128
  const agentMap = resolveAgents();
103
129
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
104
130
  const method = req.method ?? "GET";
131
+ // Strip basePath prefix from incoming URL if present (segment-boundary match)
132
+ if (basePath && url.pathname.startsWith(basePath)) {
133
+ const rest = url.pathname.slice(basePath.length);
134
+ if (rest === "" || rest.startsWith("/")) {
135
+ url.pathname = rest || "/";
136
+ }
137
+ }
105
138
  // CORS preflight
106
139
  if (method === "OPTIONS") {
107
140
  setCors(res);
@@ -304,10 +337,13 @@ export function createServer(agents, port) {
304
337
  return;
305
338
  }
306
339
  if (agentIds.length === 1) {
307
- const target = `${url.pathname === "/embed" ? "/embed.html" : url.pathname}?agentId=${encodeURIComponent(agentIds[0])}`;
308
- res.writeHead(302, { Location: target });
309
- res.end();
310
- return;
340
+ // Serve page directly with default agent injected no redirect
341
+ const injection = { defaultAgent: agentIds[0] };
342
+ if (basePath)
343
+ injection.basePath = basePath;
344
+ const servePath = isEmbed ? "/embed.html" : "/";
345
+ if (serveStatic(res, servePath, injection))
346
+ return;
311
347
  }
312
348
  // Multiple agents
313
349
  if (isEmbed) {
@@ -318,15 +354,24 @@ export function createServer(agents, port) {
318
354
  // Selection page for standalone UI
319
355
  const items = agentIds.map((id) => {
320
356
  const entry = agentMap.get(id);
321
- return `<a href="/?agentId=${encodeURIComponent(id)}" style="display:block;padding:16px 20px;margin:8px 0;border:1px solid #e2e8f0;border-radius:8px;text-decoration:none;color:inherit;transition:background .15s"><strong>${id}</strong><br><span style="color:#64748b;font-size:14px">${entry.config.tools.length} tools · ${Object.keys(entry.config.skills).length} skills</span></a>`;
357
+ return `<a href="${basePath}/?agentId=${encodeURIComponent(id)}" style="display:block;padding:16px 20px;margin:8px 0;border:1px solid #e2e8f0;border-radius:8px;text-decoration:none;color:inherit;transition:background .15s"><strong>${id}</strong><br><span style="color:#64748b;font-size:14px">${entry.config.tools.length} tools · ${Object.keys(entry.config.skills).length} skills</span></a>`;
322
358
  }).join("");
323
359
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
324
360
  res.end(`<!DOCTYPE html><html><head><title>Select Agent</title></head><body style="font-family:system-ui,-apple-system,sans-serif;max-width:480px;margin:80px auto;padding:0 20px"><h2 style="margin-bottom:24px">Select an agent</h2>${items}</body></html>`);
325
361
  return;
326
362
  }
327
363
  }
364
+ // Build injection config for static HTML
365
+ const injection = {};
366
+ if (basePath)
367
+ injection.basePath = basePath;
368
+ // When only one agent, always inject default so frontend doesn't need agentId in URL
369
+ const agentIds = [...agentMap.keys()];
370
+ if (agentIds.length === 1)
371
+ injection.defaultAgent = agentIds[0];
372
+ const hasInjection = Object.keys(injection).length > 0;
328
373
  // Static files (SPA fallback)
329
- if (method === "GET" && serveStatic(res, url.pathname))
374
+ if (method === "GET" && serveStatic(res, url.pathname, hasInjection ? injection : undefined))
330
375
  return;
331
376
  // 404
332
377
  json(res, 404, { error: "Not found" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archon-claw/cli",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,7 +21,7 @@
21
21
  "tsx": "^4.21.0",
22
22
  "typescript": "^5.9.3",
23
23
  "vitest": "^4.0.18",
24
- "@archon-claw/web": "0.1.1"
24
+ "@archon-claw/web": "0.2.0"
25
25
  },
26
26
  "dependencies": {
27
27
  "@modelcontextprotocol/sdk": "^1.27.1",
@@ -38,6 +38,7 @@
38
38
  "scripts": {
39
39
  "clean": "rm -rf dist",
40
40
  "build": "tsc -p tsconfig.build.json && cp -r ../web/dist dist/public",
41
+ "typecheck": "tsc --noEmit",
41
42
  "dev": "tsx src/cli.ts start examples/my-agent",
42
43
  "start": "node dist/cli.js",
43
44
  "test": "vitest run --exclude dist --exclude examples",