@agent-native/core 0.4.2 → 0.4.4
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/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +9 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/application-state/emitter.d.ts +10 -0
- package/dist/application-state/emitter.d.ts.map +1 -0
- package/dist/application-state/emitter.js +18 -0
- package/dist/application-state/emitter.js.map +1 -0
- package/dist/application-state/handlers.d.ts +20 -0
- package/dist/application-state/handlers.d.ts.map +1 -0
- package/dist/application-state/handlers.js +94 -0
- package/dist/application-state/handlers.js.map +1 -0
- package/dist/application-state/index.d.ts +5 -0
- package/dist/application-state/index.d.ts.map +1 -0
- package/dist/application-state/index.js +9 -0
- package/dist/application-state/index.js.map +1 -0
- package/dist/application-state/script-helpers.d.ts +17 -0
- package/dist/application-state/script-helpers.d.ts.map +1 -0
- package/dist/application-state/script-helpers.js +28 -0
- package/dist/application-state/script-helpers.js.map +1 -0
- package/dist/application-state/store.d.ts +9 -0
- package/dist/application-state/store.d.ts.map +1 -0
- package/dist/application-state/store.js +93 -0
- package/dist/application-state/store.js.map +1 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +38 -24
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +53 -0
- package/dist/client/AgentPanel.d.ts.map +1 -0
- package/dist/client/AgentPanel.js +70 -0
- package/dist/client/AgentPanel.js.map +1 -0
- package/dist/client/AssistantChat.d.ts +27 -0
- package/dist/client/AssistantChat.d.ts.map +1 -0
- package/dist/client/AssistantChat.js +165 -0
- package/dist/client/AssistantChat.js.map +1 -0
- package/dist/client/ErrorBoundary.d.ts +4 -0
- package/dist/client/ErrorBoundary.d.ts.map +1 -0
- package/dist/client/ErrorBoundary.js +22 -0
- package/dist/client/ErrorBoundary.js.map +1 -0
- package/dist/client/MultiTabAssistantChat.d.ts +4 -0
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -0
- package/dist/client/MultiTabAssistantChat.js +125 -0
- package/dist/client/MultiTabAssistantChat.js.map +1 -0
- package/dist/client/ProductionAgentPanel.d.ts +3 -7
- package/dist/client/ProductionAgentPanel.d.ts.map +1 -1
- package/dist/client/ProductionAgentPanel.js +3 -118
- package/dist/client/ProductionAgentPanel.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts +10 -0
- package/dist/client/agent-chat-adapter.d.ts.map +1 -0
- package/dist/client/agent-chat-adapter.js +235 -0
- package/dist/client/agent-chat-adapter.js.map +1 -0
- package/dist/client/agent-chat.d.ts +9 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +11 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/index.d.ts +8 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +9 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +35 -0
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -0
- package/dist/client/terminal/AgentTerminal.js +346 -0
- package/dist/client/terminal/AgentTerminal.js.map +1 -0
- package/dist/client/terminal/index.d.ts +7 -0
- package/dist/client/terminal/index.d.ts.map +1 -0
- package/dist/client/terminal/index.js +7 -0
- package/dist/client/terminal/index.js.map +1 -0
- package/dist/client/use-agent-chat.d.ts +1 -1
- package/dist/client/use-agent-chat.d.ts.map +1 -1
- package/dist/client/use-agent-chat.js +1 -1
- package/dist/client/use-agent-chat.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts +6 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +4 -2
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/db/create-get-db.d.ts +3 -0
- package/dist/db/create-get-db.d.ts.map +1 -0
- package/dist/db/create-get-db.js +18 -0
- package/dist/db/create-get-db.js.map +1 -0
- package/dist/db/index.d.ts +2 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +7 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +35 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/oauth-tokens/index.d.ts +2 -0
- package/dist/oauth-tokens/index.d.ts.map +1 -0
- package/dist/oauth-tokens/index.js +2 -0
- package/dist/oauth-tokens/index.js.map +1 -0
- package/dist/oauth-tokens/store.d.ts +9 -0
- package/dist/oauth-tokens/store.d.ts.map +1 -0
- package/dist/oauth-tokens/store.js +90 -0
- package/dist/oauth-tokens/store.js.map +1 -0
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +31 -16
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +24 -8
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/schema.d.ts.map +1 -1
- package/dist/scripts/db/schema.js +56 -28
- package/dist/scripts/db/schema.js.map +1 -1
- package/dist/scripts/dev/index.d.ts +15 -0
- package/dist/scripts/dev/index.d.ts.map +1 -0
- package/dist/scripts/dev/index.js +118 -0
- package/dist/scripts/dev/index.js.map +1 -0
- package/dist/scripts/dev/list-files.d.ts +5 -0
- package/dist/scripts/dev/list-files.d.ts.map +1 -0
- package/dist/scripts/dev/list-files.js +102 -0
- package/dist/scripts/dev/list-files.js.map +1 -0
- package/dist/scripts/dev/read-file.d.ts +5 -0
- package/dist/scripts/dev/read-file.d.ts.map +1 -0
- package/dist/scripts/dev/read-file.js +68 -0
- package/dist/scripts/dev/read-file.js.map +1 -0
- package/dist/scripts/dev/search-files.d.ts +5 -0
- package/dist/scripts/dev/search-files.d.ts.map +1 -0
- package/dist/scripts/dev/search-files.js +133 -0
- package/dist/scripts/dev/search-files.js.map +1 -0
- package/dist/scripts/dev/shell.d.ts +5 -0
- package/dist/scripts/dev/shell.d.ts.map +1 -0
- package/dist/scripts/dev/shell.js +65 -0
- package/dist/scripts/dev/shell.js.map +1 -0
- package/dist/scripts/dev/write-file.d.ts +5 -0
- package/dist/scripts/dev/write-file.d.ts.map +1 -0
- package/dist/scripts/dev/write-file.js +50 -0
- package/dist/scripts/dev/write-file.js.map +1 -0
- package/dist/scripts/index.d.ts +1 -0
- package/dist/scripts/index.d.ts.map +1 -1
- package/dist/scripts/index.js +1 -0
- package/dist/scripts/index.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +43 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -0
- package/dist/server/agent-chat-plugin.js +92 -0
- package/dist/server/agent-chat-plugin.js.map +1 -0
- package/dist/server/auth-plugin.d.ts +6 -0
- package/dist/server/auth-plugin.d.ts.map +1 -0
- package/dist/server/auth-plugin.js +8 -0
- package/dist/server/auth-plugin.js.map +1 -0
- package/dist/server/auth.d.ts +18 -2
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +103 -46
- package/dist/server/auth.js.map +1 -1
- package/dist/server/create-server.d.ts +7 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +7 -1
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/default-watcher.d.ts +17 -0
- package/dist/server/default-watcher.d.ts.map +1 -0
- package/dist/server/default-watcher.js +37 -0
- package/dist/server/default-watcher.js.map +1 -0
- package/dist/server/file-sync-plugin.d.ts +7 -0
- package/dist/server/file-sync-plugin.d.ts.map +1 -0
- package/dist/server/file-sync-plugin.js +38 -0
- package/dist/server/file-sync-plugin.js.map +1 -0
- package/dist/server/google-auth-plugin.d.ts +22 -0
- package/dist/server/google-auth-plugin.d.ts.map +1 -0
- package/dist/server/google-auth-plugin.js +122 -0
- package/dist/server/google-auth-plugin.js.map +1 -0
- package/dist/server/index.d.ts +9 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +9 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/sse.d.ts +9 -4
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +19 -12
- package/dist/server/sse.js.map +1 -1
- package/dist/settings/handlers.d.ts +9 -0
- package/dist/settings/handlers.d.ts.map +1 -0
- package/dist/settings/handlers.js +29 -0
- package/dist/settings/handlers.js.map +1 -0
- package/dist/settings/index.d.ts +5 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +9 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/script-helpers.d.ts +9 -0
- package/dist/settings/script-helpers.d.ts.map +1 -0
- package/dist/settings/script-helpers.js +16 -0
- package/dist/settings/script-helpers.js.map +1 -0
- package/dist/settings/store.d.ts +7 -0
- package/dist/settings/store.d.ts.map +1 -0
- package/dist/settings/store.js +88 -0
- package/dist/settings/store.js.map +1 -0
- package/dist/settings/user-settings.d.ts +21 -0
- package/dist/settings/user-settings.d.ts.map +1 -0
- package/dist/settings/user-settings.js +35 -0
- package/dist/settings/user-settings.js.map +1 -0
- package/dist/tailwind.preset.js +1 -1
- package/dist/tailwind.preset.js.map +1 -1
- package/dist/terminal/cli-registry.d.ts +16 -0
- package/dist/terminal/cli-registry.d.ts.map +1 -0
- package/dist/terminal/cli-registry.js +42 -0
- package/dist/terminal/cli-registry.js.map +1 -0
- package/dist/terminal/index.d.ts +9 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +9 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/pty-server.d.ts +31 -0
- package/dist/terminal/pty-server.d.ts.map +1 -0
- package/dist/terminal/pty-server.js +252 -0
- package/dist/terminal/pty-server.js.map +1 -0
- package/dist/terminal/terminal-plugin.d.ts +23 -0
- package/dist/terminal/terminal-plugin.d.ts.map +1 -0
- package/dist/terminal/terminal-plugin.js +90 -0
- package/dist/terminal/terminal-plugin.js.map +1 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +19 -1
- package/dist/vite/client.js.map +1 -1
- package/dist/vite/dev-api-server.d.ts.map +1 -1
- package/dist/vite/dev-api-server.js +12 -0
- package/dist/vite/dev-api-server.js.map +1 -1
- package/package.json +50 -4
- package/src/templates/default/.agents/skills/create-skill/SKILL.md +1 -1
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +3 -3
- package/src/templates/default/.agents/skills/files-as-database/SKILL.md +82 -63
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -2
- package/src/templates/default/.agents/skills/scripts/SKILL.md +20 -17
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +2 -2
- package/src/templates/default/.agents/skills/sse-file-watcher/SKILL.md +49 -64
- package/src/templates/default/.ignore +0 -0
- package/src/templates/default/AGENTS.md +30 -55
- package/src/templates/default/app/global.css +95 -0
- package/src/templates/default/{client → app}/root.tsx +22 -9
- package/src/templates/default/app/routes/_index.tsx +62 -0
- package/src/templates/default/application-state/.gitkeep +0 -0
- package/src/templates/default/components.json +1 -1
- package/src/templates/default/data/sync-config.json +1 -0
- package/src/templates/default/package.json +2 -1
- package/src/templates/default/react-router.config.ts +1 -1
- package/src/templates/default/scripts/run.ts +1 -8
- package/src/templates/default/server/plugins/agent-chat.ts +1 -0
- package/src/templates/default/server/plugins/auth.ts +1 -5
- package/src/templates/default/server/plugins/file-sync.ts +1 -39
- package/src/templates/default/server/plugins/terminal.ts +1 -0
- package/src/templates/default/server/routes/api/events.get.ts +2 -6
- package/src/templates/default/server/routes/api/file-sync/status.get.ts +2 -11
- package/src/templates/default/tailwind.config.ts +1 -1
- package/src/templates/default/tsconfig.json +1 -1
- package/tsconfig.base.json +2 -2
- package/src/templates/default/client/App.tsx +0 -56
- package/src/templates/default/client/global.css +0 -75
- package/src/templates/default/client/routes/_index.tsx +0 -19
- package/src/templates/default/server/lib/watcher.ts +0 -21
- /package/src/templates/default/{client → app}/entry.client.tsx +0 -0
- /package/src/templates/default/{client → app}/entry.server.tsx +0 -0
- /package/src/templates/default/{client → app}/lib/utils.ts +0 -0
- /package/src/templates/default/{client → app}/routes.ts +0 -0
- /package/src/templates/default/{client → app}/vite-env.d.ts +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Registry — known AI coding CLIs and their metadata.
|
|
3
|
+
* Shared between the embedded terminal and the harness-cli.
|
|
4
|
+
*/
|
|
5
|
+
export interface CliEntry {
|
|
6
|
+
/** npm package name for npx fallback */
|
|
7
|
+
installPackage: string;
|
|
8
|
+
/** Env vars to strip when spawning (prevents nesting) */
|
|
9
|
+
stripEnv: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare const CLI_REGISTRY: Record<string, CliEntry>;
|
|
12
|
+
/** Check if a command name is in the CLI_REGISTRY allowlist */
|
|
13
|
+
export declare function isAllowedCommand(cmd: string): boolean;
|
|
14
|
+
/** Check if a CLI command exists on PATH (safe — no shell interpolation) */
|
|
15
|
+
export declare function commandExists(cmd: string): boolean;
|
|
16
|
+
//# sourceMappingURL=cli-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-registry.d.ts","sourceRoot":"","sources":["../../src/terminal/cli-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,QAAQ;IACvB,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAqBjD,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOlD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Registry — known AI coding CLIs and their metadata.
|
|
3
|
+
* Shared between the embedded terminal and the harness-cli.
|
|
4
|
+
*/
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
export const CLI_REGISTRY = {
|
|
7
|
+
claude: {
|
|
8
|
+
installPackage: "@anthropic-ai/claude-code",
|
|
9
|
+
stripEnv: ["CLAUDECODE", "CLAUDE_CODE_SESSION"],
|
|
10
|
+
},
|
|
11
|
+
codex: {
|
|
12
|
+
installPackage: "@openai/codex",
|
|
13
|
+
stripEnv: [],
|
|
14
|
+
},
|
|
15
|
+
gemini: {
|
|
16
|
+
installPackage: "@google/gemini-cli",
|
|
17
|
+
stripEnv: [],
|
|
18
|
+
},
|
|
19
|
+
opencode: {
|
|
20
|
+
installPackage: "opencode-ai",
|
|
21
|
+
stripEnv: [],
|
|
22
|
+
},
|
|
23
|
+
fusion: {
|
|
24
|
+
installPackage: "@builder.io/fusion",
|
|
25
|
+
stripEnv: [],
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/** Check if a command name is in the CLI_REGISTRY allowlist */
|
|
29
|
+
export function isAllowedCommand(cmd) {
|
|
30
|
+
return Object.hasOwn(CLI_REGISTRY, cmd);
|
|
31
|
+
}
|
|
32
|
+
/** Check if a CLI command exists on PATH (safe — no shell interpolation) */
|
|
33
|
+
export function commandExists(cmd) {
|
|
34
|
+
try {
|
|
35
|
+
const result = spawnSync("which", [cmd], { stdio: "ignore" });
|
|
36
|
+
return result.status === 0;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=cli-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-registry.js","sourceRoot":"","sources":["../../src/terminal/cli-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C,MAAM,CAAC,MAAM,YAAY,GAA6B;IACpD,MAAM,EAAE;QACN,cAAc,EAAE,2BAA2B;QAC3C,QAAQ,EAAE,CAAC,YAAY,EAAE,qBAAqB,CAAC;KAChD;IACD,KAAK,EAAE;QACL,cAAc,EAAE,eAAe;QAC/B,QAAQ,EAAE,EAAE;KACb;IACD,MAAM,EAAE;QACN,cAAc,EAAE,oBAAoB;QACpC,QAAQ,EAAE,EAAE;KACb;IACD,QAAQ,EAAE;QACR,cAAc,EAAE,aAAa;QAC7B,QAAQ,EAAE,EAAE;KACb;IACD,MAAM,EAAE;QACN,cAAc,EAAE,oBAAoB;QACpC,QAAQ,EAAE,EAAE;KACb;CACF,CAAC;AAEF,+DAA+D;AAC/D,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal — server-side exports
|
|
3
|
+
*
|
|
4
|
+
* PTY WebSocket server and Nitro plugin for the embedded agent terminal.
|
|
5
|
+
*/
|
|
6
|
+
export { createPtyWebSocketServer, type PtyServerOptions, type PtyServerResult, } from "./pty-server.js";
|
|
7
|
+
export { createTerminalPlugin, defaultTerminalPlugin, type TerminalPluginOptions, } from "./terminal-plugin.js";
|
|
8
|
+
export { CLI_REGISTRY, commandExists, isAllowedCommand, type CliEntry, } from "./cli-registry.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal — server-side exports
|
|
3
|
+
*
|
|
4
|
+
* PTY WebSocket server and Nitro plugin for the embedded agent terminal.
|
|
5
|
+
*/
|
|
6
|
+
export { createPtyWebSocketServer, } from "./pty-server.js";
|
|
7
|
+
export { createTerminalPlugin, defaultTerminalPlugin, } from "./terminal-plugin.js";
|
|
8
|
+
export { CLI_REGISTRY, commandExists, isAllowedCommand, } from "./cli-registry.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,wBAAwB,GAGzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,GAEjB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PTY WebSocket Server
|
|
3
|
+
*
|
|
4
|
+
* Creates an HTTP server with WebSocket support that spawns PTY processes
|
|
5
|
+
* for AI CLI tools. Each WebSocket connection gets its own PTY.
|
|
6
|
+
*
|
|
7
|
+
* Used by both the embedded AgentTerminal component and the CLI harness.
|
|
8
|
+
*/
|
|
9
|
+
import { type IncomingMessage, type Server as HttpServer } from "http";
|
|
10
|
+
export interface PtyServerOptions {
|
|
11
|
+
/** Working directory for PTY processes. Defaults to process.cwd() */
|
|
12
|
+
appDir?: string;
|
|
13
|
+
/** Default CLI command. Defaults to 'claude' */
|
|
14
|
+
command?: string;
|
|
15
|
+
/** Port to listen on. Defaults to 0 (random available port) */
|
|
16
|
+
port?: number;
|
|
17
|
+
/** Auth check for WebSocket upgrade requests. Return false to reject. */
|
|
18
|
+
authCheck?: (req: IncomingMessage) => boolean | Promise<boolean>;
|
|
19
|
+
/** Log prefix for console output. Defaults to '[terminal]' */
|
|
20
|
+
logPrefix?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PtyServerResult {
|
|
23
|
+
/** The underlying HTTP server */
|
|
24
|
+
server: HttpServer;
|
|
25
|
+
/** The actual port the server is listening on */
|
|
26
|
+
port: number;
|
|
27
|
+
/** Shut down the server and kill all PTY processes */
|
|
28
|
+
close: () => void;
|
|
29
|
+
}
|
|
30
|
+
export declare function createPtyWebSocketServer(options?: PtyServerOptions): Promise<PtyServerResult>;
|
|
31
|
+
//# sourceMappingURL=pty-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-server.d.ts","sourceRoot":"","sources":["../../src/terminal/pty-server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,MAAM,IAAI,UAAU,EAC1B,MAAM,MAAM,CAAC;AAUd,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAyR1B"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PTY WebSocket Server
|
|
3
|
+
*
|
|
4
|
+
* Creates an HTTP server with WebSocket support that spawns PTY processes
|
|
5
|
+
* for AI CLI tools. Each WebSocket connection gets its own PTY.
|
|
6
|
+
*
|
|
7
|
+
* Used by both the embedded AgentTerminal component and the CLI harness.
|
|
8
|
+
*/
|
|
9
|
+
import { createServer as createHttpServer, } from "http";
|
|
10
|
+
import os from "os";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import { CLI_REGISTRY, commandExists, isAllowedCommand, } from "./cli-registry.js";
|
|
14
|
+
export async function createPtyWebSocketServer(options = {}) {
|
|
15
|
+
const { appDir = process.cwd(), command: defaultCommand = "claude", port = 0, authCheck, logPrefix = "[terminal]", } = options;
|
|
16
|
+
// Dynamic imports for optional native dependencies
|
|
17
|
+
const { WebSocketServer, WebSocket } = await import("ws");
|
|
18
|
+
const pty = await import("node-pty");
|
|
19
|
+
const resolvedAppDir = path.resolve(appDir);
|
|
20
|
+
const shell = os.platform() === "win32" ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
21
|
+
const server = createHttpServer((req, res) => {
|
|
22
|
+
// CORS headers
|
|
23
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
24
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
25
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
26
|
+
if (req.method === "OPTIONS") {
|
|
27
|
+
res.writeHead(204);
|
|
28
|
+
res.end();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
res.writeHead(404);
|
|
32
|
+
res.end();
|
|
33
|
+
});
|
|
34
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
35
|
+
// Handle WebSocket upgrades with optional auth
|
|
36
|
+
server.on("upgrade", async (req, socket, head) => {
|
|
37
|
+
if (authCheck) {
|
|
38
|
+
try {
|
|
39
|
+
const allowed = await authCheck(req);
|
|
40
|
+
if (!allowed) {
|
|
41
|
+
socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
|
|
42
|
+
socket.destroy();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
socket.write("HTTP/1.1 500 Internal Server Error\r\n\r\n");
|
|
48
|
+
socket.destroy();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
53
|
+
wss.emit("connection", ws, req);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
// Track active PTY processes for cleanup
|
|
57
|
+
const activePtys = new Set();
|
|
58
|
+
wss.on("connection", (ws, req) => {
|
|
59
|
+
const url = new URL(req.url || "", `http://${req.headers.host}`);
|
|
60
|
+
const command = url.searchParams.get("command") || defaultCommand;
|
|
61
|
+
const extraFlags = url.searchParams.get("flags") || "";
|
|
62
|
+
console.log(`${logPrefix} WebSocket connected for command: ${command}`);
|
|
63
|
+
const sendStatus = (status, message) => {
|
|
64
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
65
|
+
ws.send(JSON.stringify({ type: "setup-status", status, message }));
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
// Validate command against allowlist to prevent injection
|
|
69
|
+
if (!isAllowedCommand(command)) {
|
|
70
|
+
sendStatus("not-found", `"${command}" is not a recognized CLI. Allowed: ${Object.keys(CLI_REGISTRY).join(", ")}`);
|
|
71
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
72
|
+
ws.close();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Reject flags containing shell metacharacters
|
|
76
|
+
if (extraFlags && /[;&|`$(){}\n\r<>]/.test(extraFlags)) {
|
|
77
|
+
sendStatus("failed", "Invalid flags: shell metacharacters not allowed");
|
|
78
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
79
|
+
ws.close();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Check if CLI is installed; if not, use npx to run it
|
|
83
|
+
let useNpx = false;
|
|
84
|
+
if (!commandExists(command)) {
|
|
85
|
+
const registry = CLI_REGISTRY[command];
|
|
86
|
+
if (registry?.installPackage) {
|
|
87
|
+
console.log(`${logPrefix} ${command} CLI not found, will use npx`);
|
|
88
|
+
useNpx = true;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
sendStatus("not-found", `"${command}" not found on PATH. Please install it manually.`);
|
|
92
|
+
if (ws.readyState === WebSocket.OPEN)
|
|
93
|
+
ws.close();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Build the command — use npx if CLI not found locally
|
|
98
|
+
const baseCommand = useNpx
|
|
99
|
+
? `npx --yes ${CLI_REGISTRY[command].installPackage}`
|
|
100
|
+
: command;
|
|
101
|
+
const fullCommand = extraFlags
|
|
102
|
+
? `${baseCommand} ${extraFlags}`
|
|
103
|
+
: baseCommand;
|
|
104
|
+
console.log(`${logPrefix} Spawning PTY: ${fullCommand}`);
|
|
105
|
+
// Build env, stripping CLI-specific nesting vars
|
|
106
|
+
const registry = CLI_REGISTRY[command];
|
|
107
|
+
const env = {
|
|
108
|
+
...process.env,
|
|
109
|
+
TERM: "xterm-256color",
|
|
110
|
+
};
|
|
111
|
+
if (registry) {
|
|
112
|
+
for (const v of registry.stripEnv)
|
|
113
|
+
delete env[v];
|
|
114
|
+
}
|
|
115
|
+
let ptyProcess;
|
|
116
|
+
try {
|
|
117
|
+
ptyProcess = pty.spawn(shell, ["-l", "-c", fullCommand], {
|
|
118
|
+
name: "xterm-256color",
|
|
119
|
+
cols: 120,
|
|
120
|
+
rows: 40,
|
|
121
|
+
cwd: resolvedAppDir,
|
|
122
|
+
env: env,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
console.error(`${logPrefix} Failed to spawn PTY:`, err);
|
|
127
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
128
|
+
ws.send(`\r\n\x1b[31m${logPrefix} Failed to spawn PTY: ${err}\x1b[0m\r\n`);
|
|
129
|
+
ws.close();
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
activePtys.add(ptyProcess);
|
|
134
|
+
console.log(`${logPrefix} PTY spawned (pid: ${ptyProcess.pid})`);
|
|
135
|
+
ptyProcess.onData((data) => {
|
|
136
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
137
|
+
ws.send(data);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
ptyProcess.onExit(({ exitCode }) => {
|
|
141
|
+
console.log(`${logPrefix} PTY exited with code ${exitCode}`);
|
|
142
|
+
activePtys.delete(ptyProcess);
|
|
143
|
+
if (exitCode === 127 && ws.readyState === WebSocket.OPEN) {
|
|
144
|
+
ws.send(JSON.stringify({
|
|
145
|
+
type: "setup-status",
|
|
146
|
+
status: "not-found",
|
|
147
|
+
message: `Command "${command}" not found. Please install it first.`,
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
151
|
+
ws.close();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
ws.on("message", (data) => {
|
|
155
|
+
const str = typeof data === "string" ? data : data.toString();
|
|
156
|
+
try {
|
|
157
|
+
const msg = JSON.parse(str);
|
|
158
|
+
if (msg.type === "builder.setEnvVars" &&
|
|
159
|
+
Array.isArray(msg.data?.vars)) {
|
|
160
|
+
const envPath = path.join(resolvedAppDir, ".env");
|
|
161
|
+
const vars = msg.data.vars;
|
|
162
|
+
// Validate env var names and sanitize values
|
|
163
|
+
const validKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
164
|
+
const sanitizedVars = vars.filter(({ key }) => {
|
|
165
|
+
if (!validKeyPattern.test(key)) {
|
|
166
|
+
console.warn(`${logPrefix} Rejected invalid env var key: ${key}`);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
});
|
|
171
|
+
let lines = [];
|
|
172
|
+
try {
|
|
173
|
+
lines = fs.readFileSync(envPath, "utf-8").split("\n");
|
|
174
|
+
}
|
|
175
|
+
catch { }
|
|
176
|
+
for (const { key, value } of sanitizedVars) {
|
|
177
|
+
// Strip newlines/null bytes to prevent line injection
|
|
178
|
+
const safeValue = value.replace(/[\r\n\0]/g, "");
|
|
179
|
+
// Quote values containing #, spaces, or quotes so dotenv parses correctly
|
|
180
|
+
const needsQuoting = /[# "']/.test(safeValue);
|
|
181
|
+
const quotedValue = needsQuoting
|
|
182
|
+
? `"${safeValue.replace(/"/g, '\\"')}"`
|
|
183
|
+
: safeValue;
|
|
184
|
+
const idx = lines.findIndex((l) => l.startsWith(`${key}=`));
|
|
185
|
+
const entry = `${key}=${quotedValue}`;
|
|
186
|
+
if (idx !== -1) {
|
|
187
|
+
lines[idx] = entry;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
lines.push(entry);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
194
|
+
lines.pop();
|
|
195
|
+
}
|
|
196
|
+
fs.writeFileSync(envPath, lines.join("\n") + "\n", "utf-8");
|
|
197
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
198
|
+
ws.send(JSON.stringify({
|
|
199
|
+
type: "env-vars-saved",
|
|
200
|
+
keys: sanitizedVars.map((v) => v.key),
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (msg.type === "resize" && msg.cols && msg.rows) {
|
|
206
|
+
ptyProcess.resize(msg.cols, msg.rows);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Not JSON — regular terminal input
|
|
212
|
+
}
|
|
213
|
+
ptyProcess.write(str);
|
|
214
|
+
});
|
|
215
|
+
ws.on("close", () => {
|
|
216
|
+
console.log(`${logPrefix} WebSocket closed, killing PTY`);
|
|
217
|
+
activePtys.delete(ptyProcess);
|
|
218
|
+
try {
|
|
219
|
+
ptyProcess.kill();
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Process may have already exited
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
return new Promise((resolve, reject) => {
|
|
227
|
+
server.once("error", (err) => {
|
|
228
|
+
reject(err);
|
|
229
|
+
});
|
|
230
|
+
server.listen(port, "127.0.0.1", () => {
|
|
231
|
+
const addr = server.address();
|
|
232
|
+
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
233
|
+
console.log(`${logPrefix} PTY WebSocket server on ws://localhost:${actualPort}/ws`);
|
|
234
|
+
resolve({
|
|
235
|
+
server,
|
|
236
|
+
port: actualPort,
|
|
237
|
+
close: () => {
|
|
238
|
+
for (const p of activePtys) {
|
|
239
|
+
try {
|
|
240
|
+
p.kill();
|
|
241
|
+
}
|
|
242
|
+
catch { }
|
|
243
|
+
}
|
|
244
|
+
activePtys.clear();
|
|
245
|
+
wss.close();
|
|
246
|
+
server.close();
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=pty-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-server.js","sourceRoot":"","sources":["../../src/terminal/pty-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro Plugin — Agent Terminal
|
|
3
|
+
*
|
|
4
|
+
* Starts a PTY WebSocket server alongside the app so the <AgentTerminal />
|
|
5
|
+
* component can connect to a real CLI. Mounts a discovery endpoint at
|
|
6
|
+
* /api/agent-terminal-info for the client component.
|
|
7
|
+
*
|
|
8
|
+
* Skips activation when running inside a harness (HARNESS_PORT is set).
|
|
9
|
+
*/
|
|
10
|
+
export interface TerminalPluginOptions {
|
|
11
|
+
/** CLI command to run. Defaults to AGENT_CLI_COMMAND env or 'claude' */
|
|
12
|
+
command?: string;
|
|
13
|
+
/** Port for the WebSocket server. Defaults to AGENT_TERMINAL_PORT env or auto-assigned */
|
|
14
|
+
port?: number;
|
|
15
|
+
/** Enable in production. Defaults to AGENT_TERMINAL_ENABLED env or false in prod */
|
|
16
|
+
enabledInProduction?: boolean;
|
|
17
|
+
/** Auth check for WebSocket connections in production */
|
|
18
|
+
authCheck?: (req: any) => boolean | Promise<boolean>;
|
|
19
|
+
}
|
|
20
|
+
export declare function createTerminalPlugin(options?: TerminalPluginOptions): (nitroApp: any) => Promise<void>;
|
|
21
|
+
/** Pre-configured terminal plugin with defaults */
|
|
22
|
+
export declare const defaultTerminalPlugin: (nitroApp: any) => Promise<void>;
|
|
23
|
+
//# sourceMappingURL=terminal-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-plugin.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,yDAAyD;IACzD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,IACxD,UAAU,GAAG,mBAkH5B;AAED,mDAAmD;AACnD,eAAO,MAAM,qBAAqB,aArHR,GAAG,kBAqH8B,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro Plugin — Agent Terminal
|
|
3
|
+
*
|
|
4
|
+
* Starts a PTY WebSocket server alongside the app so the <AgentTerminal />
|
|
5
|
+
* component can connect to a real CLI. Mounts a discovery endpoint at
|
|
6
|
+
* /api/agent-terminal-info for the client component.
|
|
7
|
+
*
|
|
8
|
+
* Skips activation when running inside a harness (HARNESS_PORT is set).
|
|
9
|
+
*/
|
|
10
|
+
import { defineEventHandler } from "h3";
|
|
11
|
+
export function createTerminalPlugin(options = {}) {
|
|
12
|
+
return async (nitroApp) => {
|
|
13
|
+
// Skip if running inside a harness
|
|
14
|
+
if (process.env.HARNESS_PORT) {
|
|
15
|
+
console.log("[terminal] Harness detected, skipping embedded terminal");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
19
|
+
const enabled = options.enabledInProduction ??
|
|
20
|
+
(process.env.AGENT_TERMINAL_ENABLED === "true" || !isProd);
|
|
21
|
+
if (!enabled) {
|
|
22
|
+
console.log("[terminal] Disabled in production (set AGENT_TERMINAL_ENABLED=true to enable)");
|
|
23
|
+
// Mount a disabled info endpoint
|
|
24
|
+
nitroApp.h3App.use("/api/agent-terminal-info", defineEventHandler(() => ({ available: false })));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Require authCheck in production to prevent unauthenticated shell access
|
|
28
|
+
if (isProd && !options.authCheck) {
|
|
29
|
+
console.error("[terminal] FATAL: authCheck is required when enabling the terminal in production. " +
|
|
30
|
+
"Pass an authCheck function to createTerminalPlugin().");
|
|
31
|
+
nitroApp.h3App.use("/api/agent-terminal-info", defineEventHandler(() => ({
|
|
32
|
+
available: false,
|
|
33
|
+
error: "Terminal requires authCheck in production",
|
|
34
|
+
})));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Skip if a PTY server is already running (prevents leak on HMR rebuild)
|
|
38
|
+
if (process.env.__AGENT_TERMINAL_RUNNING === "true") {
|
|
39
|
+
const existingPort = process.env.AGENT_TERMINAL_PORT;
|
|
40
|
+
console.log(`[terminal] PTY server already running on port ${existingPort}, skipping`);
|
|
41
|
+
nitroApp.h3App.use("/api/agent-terminal-info", defineEventHandler(() => ({
|
|
42
|
+
available: true,
|
|
43
|
+
wsPort: existingPort ? parseInt(existingPort, 10) : 0,
|
|
44
|
+
command: options.command || process.env.AGENT_CLI_COMMAND || "claude",
|
|
45
|
+
})));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const command = options.command || process.env.AGENT_CLI_COMMAND || "claude";
|
|
49
|
+
const port = options.port ??
|
|
50
|
+
(process.env.AGENT_TERMINAL_PORT
|
|
51
|
+
? parseInt(process.env.AGENT_TERMINAL_PORT, 10)
|
|
52
|
+
: 0);
|
|
53
|
+
try {
|
|
54
|
+
const { createPtyWebSocketServer } = await import("./pty-server.js");
|
|
55
|
+
const result = await createPtyWebSocketServer({
|
|
56
|
+
appDir: process.cwd(),
|
|
57
|
+
command,
|
|
58
|
+
port,
|
|
59
|
+
authCheck: isProd ? options.authCheck : undefined,
|
|
60
|
+
logPrefix: "[terminal]",
|
|
61
|
+
});
|
|
62
|
+
// Store port for other consumers and mark as running to prevent HMR duplication
|
|
63
|
+
process.env.AGENT_TERMINAL_PORT = String(result.port);
|
|
64
|
+
process.env.__AGENT_TERMINAL_RUNNING = "true";
|
|
65
|
+
// Mount discovery endpoint
|
|
66
|
+
nitroApp.h3App.use("/api/agent-terminal-info", defineEventHandler(() => ({
|
|
67
|
+
available: true,
|
|
68
|
+
wsPort: result.port,
|
|
69
|
+
command,
|
|
70
|
+
})));
|
|
71
|
+
// Cleanup on shutdown (use once to avoid listener leak on hot-reload)
|
|
72
|
+
const cleanup = () => result.close();
|
|
73
|
+
process.once("SIGTERM", cleanup);
|
|
74
|
+
process.once("SIGINT", cleanup);
|
|
75
|
+
console.log(`[terminal] Agent terminal ready (command: ${command}, port: ${result.port})`);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.error("[terminal] Failed to start PTY server:", err);
|
|
79
|
+
console.error("[terminal] Make sure node-pty is installed: pnpm add node-pty");
|
|
80
|
+
// Mount a fallback info endpoint
|
|
81
|
+
nitroApp.h3App.use("/api/agent-terminal-info", defineEventHandler(() => ({
|
|
82
|
+
available: false,
|
|
83
|
+
error: "PTY server failed to start",
|
|
84
|
+
})));
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Pre-configured terminal plugin with defaults */
|
|
89
|
+
export const defaultTerminalPlugin = createTerminalPlugin();
|
|
90
|
+
//# sourceMappingURL=terminal-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-plugin.js","sourceRoot":"","sources":["../../src/terminal/terminal-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAaxC,MAAM,UAAU,oBAAoB,CAAC,UAAiC,EAAE;IACtE,OAAO,KAAK,EAAE,QAAa,EAAE,EAAE;QAC7B,mCAAmC;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;QACrD,MAAM,OAAO,GACX,OAAO,CAAC,mBAAmB;YAC3B,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAE7D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CACT,+EAA+E,CAChF,CAAC;YACF,iCAAiC;YACjC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAChB,0BAA0B,EAC1B,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CACjD,CAAC;YACF,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CACX,oFAAoF;gBAClF,uDAAuD,CAC1D,CAAC;YACF,QAAQ,CAAC,KAAK,CAAC,GAAG,CAChB,0BAA0B,EAC1B,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACxB,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,2CAA2C;aACnD,CAAC,CAAC,CACJ,CAAC;YACF,OAAO;QACT,CAAC;QAED,yEAAyE;QACzE,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,MAAM,EAAE,CAAC;YACpD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YACrD,OAAO,CAAC,GAAG,CACT,iDAAiD,YAAY,YAAY,CAC1E,CAAC;YACF,QAAQ,CAAC,KAAK,CAAC,GAAG,CAChB,0BAA0B,EAC1B,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACxB,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,QAAQ;aACtE,CAAC,CAAC,CACJ,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,QAAQ,CAAC;QAC/D,MAAM,IAAI,GACR,OAAO,CAAC,IAAI;YACZ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB;gBAC9B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC;gBAC/C,CAAC,CAAC,CAAC,CAAC,CAAC;QAET,IAAI,CAAC;YACH,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAErE,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC;gBAC5C,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE;gBACrB,OAAO;gBACP,IAAI;gBACJ,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;gBACjD,SAAS,EAAE,YAAY;aACxB,CAAC,CAAC;YAEH,gFAAgF;YAChF,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,MAAM,CAAC;YAE9C,2BAA2B;YAC3B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAChB,0BAA0B,EAC1B,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACxB,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,MAAM,CAAC,IAAI;gBACnB,OAAO;aACR,CAAC,CAAC,CACJ,CAAC;YAEF,sEAAsE;YACtE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEhC,OAAO,CAAC,GAAG,CACT,6CAA6C,OAAO,WAAW,MAAM,CAAC,IAAI,GAAG,CAC9E,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CACX,+DAA+D,CAChE,CAAC;YAEF,iCAAiC;YACjC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAChB,0BAA0B,EAC1B,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACxB,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,4BAA4B;aACpC,CAAC,CAAC,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,mDAAmD;AACnD,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAqB/C,MAAM,WAAW,YAAY;IAC3B,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjD;AAmCD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,UAAU,CAyE1E"}
|
package/dist/vite/client.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
2
3
|
import { createRequire } from "module";
|
|
3
4
|
import { devApiServer } from "./dev-api-server.js";
|
|
4
5
|
const require = createRequire(import.meta.url);
|
|
6
|
+
/** Check if a package is installed in the project */
|
|
7
|
+
function hasDep(pkg, cwd) {
|
|
8
|
+
try {
|
|
9
|
+
const pkgJson = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf-8"));
|
|
10
|
+
return !!(pkgJson.dependencies?.[pkg] ||
|
|
11
|
+
pkgJson.devDependencies?.[pkg] ||
|
|
12
|
+
pkgJson.peerDependencies?.[pkg]);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
5
18
|
/**
|
|
6
19
|
* Vite plugin that prevents the built-in base middleware from redirecting
|
|
7
20
|
* "/" → "/app/" (or whatever the base is). When agent-native apps run with
|
|
@@ -92,9 +105,14 @@ export function defineConfig(options = {}) {
|
|
|
92
105
|
nitroPlugin?.(),
|
|
93
106
|
...(options.plugins ?? []),
|
|
94
107
|
].filter(Boolean),
|
|
108
|
+
optimizeDeps: {
|
|
109
|
+
include: hasDep("@agent-native/pinpoint", cwd)
|
|
110
|
+
? ["@agent-native/pinpoint/react"]
|
|
111
|
+
: [],
|
|
112
|
+
},
|
|
95
113
|
resolve: {
|
|
96
114
|
alias: {
|
|
97
|
-
"@": path.resolve(cwd, "./
|
|
115
|
+
"@": path.resolve(cwd, "./app"),
|
|
98
116
|
"@shared": path.resolve(cwd, "./shared"),
|
|
99
117
|
...options.aliases,
|
|
100
118
|
},
|
package/dist/vite/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-api-server.d.ts","sourceRoot":"","sources":["../../src/vite/dev-api-server.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAkIlD;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"dev-api-server.d.ts","sourceRoot":"","sources":["../../src/vite/dev-api-server.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAkIlD;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAyDrC"}
|
|
@@ -119,12 +119,24 @@ export function devApiServer() {
|
|
|
119
119
|
configureServer(server) {
|
|
120
120
|
const cwd = server.config.root || process.cwd();
|
|
121
121
|
const apiDir = path.join(cwd, "server/routes/api");
|
|
122
|
+
const serverDir = path.join(cwd, "server");
|
|
122
123
|
// Skip if no API routes directory exists
|
|
123
124
|
if (!fs.existsSync(apiDir))
|
|
124
125
|
return;
|
|
125
126
|
// Lazily initialize the H3 listener on first /api/ request.
|
|
126
127
|
// This avoids blocking server startup and ensures ssrLoadModule is ready.
|
|
127
128
|
let listenerPromise = null;
|
|
129
|
+
// Watch server/ directory for changes and invalidate the listener
|
|
130
|
+
// so it rebuilds on the next API request (no full restart needed).
|
|
131
|
+
if (fs.existsSync(serverDir)) {
|
|
132
|
+
const watcher = fs.watch(serverDir, { recursive: true }, (_, filename) => {
|
|
133
|
+
if (filename && filename.endsWith(".ts")) {
|
|
134
|
+
listenerPromise = null;
|
|
135
|
+
console.log(`[dev-api-server] Server file changed: ${filename} — will reload on next request`);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
server.httpServer?.on("close", () => watcher.close());
|
|
139
|
+
}
|
|
128
140
|
// Add middleware DIRECTLY (not via return) so it runs BEFORE
|
|
129
141
|
// Vite's internal middleware and React Router's SSR handler.
|
|
130
142
|
server.middlewares.use((req, res, next) => {
|