agent-stage 0.2.14 → 0.2.17

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.
Files changed (68) hide show
  1. package/dist/commands/guide.js +5 -5
  2. package/dist/commands/init.d.ts +1 -1
  3. package/dist/commands/init.js +94 -138
  4. package/dist/commands/page/add.js +5 -40
  5. package/dist/commands/run/exec.js +1 -1
  6. package/dist/commands/run/inspect.js +1 -1
  7. package/dist/commands/run/watch.js +1 -1
  8. package/dist/commands/serve.d.ts +2 -0
  9. package/dist/commands/serve.js +238 -0
  10. package/dist/commands/status.d.ts +1 -1
  11. package/dist/commands/status.js +41 -40
  12. package/dist/commands/stop.d.ts +1 -1
  13. package/dist/commands/stop.js +26 -44
  14. package/dist/index.js +16 -30
  15. package/dist/utils/agent-helper.js +5 -5
  16. package/dist/utils/paths.js +5 -5
  17. package/dist/utils/tunnel.d.ts +1 -1
  18. package/dist/utils/tunnel.js +1 -1
  19. package/package.json +8 -5
  20. package/dist/commands/dev/index.d.ts +0 -2
  21. package/dist/commands/dev/index.js +0 -11
  22. package/dist/commands/dev/init.d.ts +0 -2
  23. package/dist/commands/dev/init.js +0 -215
  24. package/dist/commands/dev/start.d.ts +0 -2
  25. package/dist/commands/dev/start.js +0 -145
  26. package/dist/commands/dev/status.d.ts +0 -2
  27. package/dist/commands/dev/status.js +0 -55
  28. package/dist/commands/dev/stop.d.ts +0 -2
  29. package/dist/commands/dev/stop.js +0 -45
  30. package/dist/commands/exec.d.ts +0 -2
  31. package/dist/commands/exec.js +0 -75
  32. package/dist/commands/inspect.d.ts +0 -2
  33. package/dist/commands/inspect.js +0 -62
  34. package/dist/commands/ls.d.ts +0 -2
  35. package/dist/commands/ls.js +0 -132
  36. package/dist/commands/restart.d.ts +0 -2
  37. package/dist/commands/restart.js +0 -90
  38. package/dist/commands/rm-page.d.ts +0 -2
  39. package/dist/commands/rm-page.js +0 -32
  40. package/dist/commands/start.d.ts +0 -2
  41. package/dist/commands/start.js +0 -82
  42. package/dist/commands/watch.d.ts +0 -2
  43. package/dist/commands/watch.js +0 -54
  44. package/template/components.json +0 -17
  45. package/template/index.html +0 -13
  46. package/template/package.json +0 -41
  47. package/template/postcss.config.js +0 -6
  48. package/template/src/components/PageRenderer.tsx +0 -108
  49. package/template/src/components/bridge-state-provider.tsx +0 -87
  50. package/template/src/components/ui/button.tsx +0 -55
  51. package/template/src/components/ui/card.tsx +0 -78
  52. package/template/src/components/ui/input.tsx +0 -24
  53. package/template/src/index.css +0 -59
  54. package/template/src/lib/bridge.ts +0 -53
  55. package/template/src/lib/utils.ts +0 -6
  56. package/template/src/main.tsx +0 -23
  57. package/template/src/pages/counter/store.json +0 -8
  58. package/template/src/pages/counter/ui.json +0 -108
  59. package/template/src/pages/test-page/store.json +0 -8
  60. package/template/src/routeTree.gen.ts +0 -77
  61. package/template/src/routes/__root.tsx +0 -11
  62. package/template/src/routes/counter.tsx +0 -19
  63. package/template/src/routes/index.tsx +0 -46
  64. package/template/src/vite-env.d.ts +0 -1
  65. package/template/tailwind.config.js +0 -53
  66. package/template/tsconfig.json +0 -25
  67. package/template/tsconfig.node.json +0 -11
  68. package/template/vite.config.ts +0 -22
@@ -0,0 +1,238 @@
1
+ import { Command } from "commander";
2
+ import * as p from "@clack/prompts";
3
+ import consola from "consola";
4
+ import c from "picocolors";
5
+ import { spawn } from "node:child_process";
6
+ import { createRequire } from "node:module";
7
+ import { createServer } from "node:net";
8
+ import { execa } from "execa";
9
+ import { existsSync } from "fs";
10
+ import { dirname, join } from "pathe";
11
+ import { getWorkspaceDir, isInitialized, readRuntimeConfig, saveRuntimeConfig, } from "../utils/paths.js";
12
+ import { canStartTunnel, startTunnel, printTunnelInfo } from "../utils/tunnel.js";
13
+ import { checkCloudflared, printInstallInstructions } from "../utils/cloudflared.js";
14
+ const require = createRequire(import.meta.url);
15
+ async function ensurePortAvailable(port, host) {
16
+ await new Promise((resolve, reject) => {
17
+ const probe = createServer();
18
+ probe.once("error", (error) => {
19
+ probe.close();
20
+ if (error.code === "EADDRINUSE") {
21
+ reject(new Error(`Port ${port} is already in use`));
22
+ return;
23
+ }
24
+ reject(error);
25
+ });
26
+ probe.listen(port, host, () => {
27
+ probe.close((error) => {
28
+ if (error) {
29
+ reject(error);
30
+ return;
31
+ }
32
+ resolve();
33
+ });
34
+ });
35
+ });
36
+ }
37
+ async function waitForRuntimeReady(port, pageId, timeoutMs = 5000) {
38
+ const start = Date.now();
39
+ let lastError = null;
40
+ while (Date.now() - start < timeoutMs) {
41
+ try {
42
+ const response = await fetch(`http://127.0.0.1:${port}/health`, {
43
+ signal: AbortSignal.timeout(500),
44
+ });
45
+ if (response.ok) {
46
+ const health = (await response.json());
47
+ if (health.ok === true && health.pageId === pageId) {
48
+ return;
49
+ }
50
+ lastError = new Error("runtime health mismatch");
51
+ }
52
+ else {
53
+ lastError = new Error(`health returned ${response.status}`);
54
+ }
55
+ }
56
+ catch (error) {
57
+ lastError = error;
58
+ }
59
+ await new Promise((resolve) => setTimeout(resolve, 200));
60
+ }
61
+ throw lastError instanceof Error
62
+ ? lastError
63
+ : new Error("Runtime health check timed out");
64
+ }
65
+ function resolveRenderServeBin() {
66
+ const override = process.env.AGENTSTAGE_RENDER_SERVE_BIN;
67
+ if (override) {
68
+ return override;
69
+ }
70
+ try {
71
+ const serveModulePath = require.resolve("@agentstage/render/serve");
72
+ const candidate = join(dirname(serveModulePath), "serve-cli.js");
73
+ if (existsSync(candidate)) {
74
+ return candidate;
75
+ }
76
+ }
77
+ catch {
78
+ // ignore resolution failure
79
+ }
80
+ return null;
81
+ }
82
+ async function waitForRuntimeProcessOrReady(subprocess, ready) {
83
+ let onError = null;
84
+ let onExit = null;
85
+ const exited = new Promise((_, reject) => {
86
+ onError = (error) => {
87
+ reject(error);
88
+ };
89
+ onExit = (code, signal) => {
90
+ const detail = code !== null ? `code ${code}` : `signal ${signal ?? "unknown"}`;
91
+ reject(new Error(`Runtime process exited before becoming ready (${detail})`));
92
+ };
93
+ subprocess.once("error", onError);
94
+ subprocess.once("exit", onExit);
95
+ });
96
+ try {
97
+ await Promise.race([ready, exited]);
98
+ }
99
+ finally {
100
+ if (onError) {
101
+ subprocess.off("error", onError);
102
+ }
103
+ if (onExit) {
104
+ subprocess.off("exit", onExit);
105
+ }
106
+ }
107
+ }
108
+ export const serveCommand = new Command("serve")
109
+ .description("Serve a single page runtime (Bun required)")
110
+ .argument("<pageId>", "Page id to serve")
111
+ .option("-p, --port <port>", "Port to run the server on", "3000")
112
+ .option("--host <host>", "Host to bind", "0.0.0.0")
113
+ .option("-t, --tunnel", "Expose server to internet via Cloudflare Tunnel", false)
114
+ .option("--open", "Open browser automatically", false)
115
+ .action(async (pageId, options) => {
116
+ if (!isInitialized()) {
117
+ consola.error("Project not initialized. Please run `agentstage init` first.");
118
+ process.exit(1);
119
+ }
120
+ if (!/^[a-z0-9-]+$/.test(pageId)) {
121
+ consola.error("Invalid pageId. Allowed: lowercase letters, numbers, hyphen");
122
+ process.exit(1);
123
+ }
124
+ const workspaceDir = await getWorkspaceDir();
125
+ const port = Number.parseInt(String(options.port), 10);
126
+ const host = String(options.host || "0.0.0.0");
127
+ if (!Number.isFinite(port) || port <= 0 || port > 65535) {
128
+ consola.error(`Invalid port: ${options.port}`);
129
+ process.exit(1);
130
+ }
131
+ const pageUiPath = join(workspaceDir, "pages", pageId, "ui.json");
132
+ if (!existsSync(pageUiPath)) {
133
+ consola.error(`Page "${pageId}" not found: ${pageUiPath}`);
134
+ process.exit(1);
135
+ }
136
+ try {
137
+ await execa("bun", ["--version"], { stdio: "pipe" });
138
+ }
139
+ catch {
140
+ consola.error("Bun is required but not found.");
141
+ consola.info("Install Bun: https://bun.sh/docs/installation");
142
+ process.exit(1);
143
+ }
144
+ const serveBin = resolveRenderServeBin();
145
+ if (!serveBin) {
146
+ consola.error("Cannot resolve @agentstage/render serve runtime entry.");
147
+ process.exit(1);
148
+ }
149
+ const existingConfig = await readRuntimeConfig();
150
+ if (existingConfig) {
151
+ try {
152
+ process.kill(existingConfig.pid, 0);
153
+ consola.warn(`Runtime is already running (PID: ${existingConfig.pid}, Port: ${existingConfig.port})`);
154
+ console.log(` Web: ${c.cyan(`http://localhost:${existingConfig.port}`)}`);
155
+ if (existingConfig.tunnelUrl) {
156
+ console.log(` Public: ${c.cyan(c.underline(existingConfig.tunnelUrl))}`);
157
+ }
158
+ console.log(` Bridge: ${c.cyan(`ws://localhost:${existingConfig.port}/_bridge`)}`);
159
+ return;
160
+ }
161
+ catch {
162
+ // stale runtime config
163
+ }
164
+ }
165
+ await ensurePortAvailable(port, host);
166
+ let tunnelUrl;
167
+ if (options.tunnel) {
168
+ const canTunnel = await canStartTunnel();
169
+ if (!canTunnel) {
170
+ const info = await checkCloudflared();
171
+ printInstallInstructions(info);
172
+ consola.error("Cannot start with --tunnel: cloudflared not installed");
173
+ process.exit(1);
174
+ }
175
+ }
176
+ const s = p.spinner();
177
+ s.start(`Starting page runtime (${pageId})...`);
178
+ try {
179
+ const subprocess = spawn("bun", [
180
+ serveBin,
181
+ "--workspace",
182
+ workspaceDir,
183
+ "--page",
184
+ pageId,
185
+ "--port",
186
+ String(port),
187
+ "--host",
188
+ host,
189
+ ], {
190
+ cwd: workspaceDir,
191
+ detached: true,
192
+ stdio: "ignore",
193
+ });
194
+ if (!subprocess.pid) {
195
+ throw new Error("Failed to start runtime process");
196
+ }
197
+ subprocess.unref();
198
+ if (options.tunnel) {
199
+ s.message("Starting Cloudflare Tunnel...");
200
+ const tunnel = await startTunnel(port);
201
+ tunnelUrl = tunnel.url;
202
+ }
203
+ await waitForRuntimeProcessOrReady(subprocess, waitForRuntimeReady(port, pageId));
204
+ const config = {
205
+ pid: subprocess.pid,
206
+ port,
207
+ startedAt: new Date().toISOString(),
208
+ tunnelUrl,
209
+ };
210
+ await saveRuntimeConfig(config);
211
+ s.stop(`Runtime started (${pageId})`);
212
+ console.log();
213
+ consola.success("Agentstage runtime is running");
214
+ console.log(` Page: ${c.cyan(pageId)}`);
215
+ console.log(` Web: ${c.cyan(`http://localhost:${port}`)}`);
216
+ if (tunnelUrl) {
217
+ printTunnelInfo(tunnelUrl);
218
+ }
219
+ console.log(` Bridge: ${c.cyan(`ws://localhost:${port}/_bridge`)}`);
220
+ console.log(` Workspace: ${c.gray(workspaceDir)}`);
221
+ console.log();
222
+ if (options.open) {
223
+ const openUrl = tunnelUrl || `http://localhost:${port}`;
224
+ try {
225
+ await execa("open", [openUrl]);
226
+ }
227
+ catch {
228
+ // ignore open errors
229
+ }
230
+ }
231
+ }
232
+ catch (error) {
233
+ s.stop("Failed to start runtime");
234
+ const message = error instanceof Error ? error.message : "Unknown error";
235
+ consola.error(message);
236
+ process.exit(1);
237
+ }
238
+ });
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const statusCommand: Command;
@@ -1,52 +1,53 @@
1
- import { Command } from 'commander';
2
- import consola from 'consola';
3
- import c from 'picocolors';
4
- import { getWorkspaceDir, readRuntimeConfig, isInitialized } from '../utils/paths.js';
5
- function isRunning(pid) {
6
- try {
7
- process.kill(pid, 0);
8
- return true;
9
- }
10
- catch {
11
- return false;
12
- }
13
- }
14
- export const statusCommand = new Command('status')
15
- .description('Show the Agentstage Runtime status')
1
+ import { Command } from "commander";
2
+ import consola from "consola";
3
+ import c from "picocolors";
4
+ import { readRuntimeConfig, isInitialized, getWorkspaceDir, } from "../utils/paths.js";
5
+ import { checkCloudflared } from "../utils/cloudflared.js";
6
+ export const statusCommand = new Command("status")
7
+ .description("Check the Agentstage Runtime status")
16
8
  .action(async () => {
17
- // 1. 检查是否已初始化
18
9
  if (!isInitialized()) {
19
- consola.error('Project not initialized. Please run `agentstage init` first.');
10
+ consola.error("Project not initialized. Please run `agentstage init` first.");
20
11
  process.exit(1);
21
12
  }
22
13
  const workspaceDir = await getWorkspaceDir();
23
- console.log();
24
- console.log(c.bold('Agentstage Runtime'));
25
- console.log(c.gray('─'.repeat(40)));
26
- console.log(`Workspace: ${c.cyan(workspaceDir)}`);
27
- // 2. 读取运行时配置
28
14
  const config = await readRuntimeConfig();
29
- if (!config) {
30
- console.log(`Status: ${c.red('●')} Stopped`);
31
- console.log();
32
- console.log(c.gray('Run `agentstage start` to start the runtime.'));
33
- console.log();
34
- return;
15
+ console.log();
16
+ console.log(c.bold("Workspace:"), c.cyan(workspaceDir));
17
+ console.log();
18
+ const cloudflared = await checkCloudflared();
19
+ console.log(c.bold("Cloudflare Tunnel:"));
20
+ if (cloudflared.installed) {
21
+ console.log(` Status: ${c.green("✓ installed")}`);
22
+ console.log(` Version: ${c.gray(cloudflared.version || "unknown")}`);
23
+ }
24
+ else {
25
+ console.log(` Status: ${c.yellow("✗ not installed")}`);
26
+ console.log(` Install: ${c.gray(cloudflared.installCommand)}`);
35
27
  }
36
- // 3. 检查进程是否存活
37
- const running = isRunning(config.pid);
38
- if (running) {
39
- console.log(`Status: ${c.green('●')} Running`);
40
- console.log(`PID: ${config.pid}`);
41
- console.log(`Port: ${config.port}`);
42
- console.log(`Started: ${new Date(config.startedAt).toLocaleString()}`);
43
- console.log(`Web: ${c.cyan(`http://localhost:${config.port}`)}`);
44
- console.log(`Bridge: ${c.cyan(`ws://localhost:${config.port}/_bridge`)}`);
28
+ console.log();
29
+ console.log(c.bold("Runtime:"));
30
+ if (!config) {
31
+ console.log(` Status: ${c.gray("stopped")}`);
45
32
  }
46
33
  else {
47
- console.log(`Status: ${c.yellow('●')} Dead (PID file exists but process not found)`);
48
- console.log();
49
- console.log(c.gray('Run `agentstage start` to restart the runtime.'));
34
+ try {
35
+ process.kill(config.pid, 0);
36
+ console.log(` Status: ${c.green("running")}`);
37
+ console.log(` PID: ${c.gray(config.pid)}`);
38
+ console.log(` Port: ${c.cyan(config.port)}`);
39
+ console.log(` Local: ${c.cyan(`http://localhost:${config.port}`)}`);
40
+ if (config.tunnelUrl) {
41
+ console.log(` Public: ${c.cyan(c.underline(config.tunnelUrl))}`);
42
+ }
43
+ console.log(` Bridge: ${c.cyan(`ws://localhost:${config.port}/_bridge`)}`);
44
+ console.log(` Started: ${c.gray(new Date(config.startedAt).toLocaleString())}`);
45
+ }
46
+ catch {
47
+ console.log(` Status: ${c.yellow("stale (process not found)")}`);
48
+ console.log(` Last PID: ${c.gray(config.pid)}`);
49
+ console.log(` Last Port: ${c.gray(config.port)}`);
50
+ }
50
51
  }
51
52
  console.log();
52
53
  });
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const stopCommand: Command;
@@ -1,58 +1,40 @@
1
- import { Command } from 'commander';
2
- import consola from 'consola';
3
- import { unlink } from 'fs/promises';
4
- import { existsSync } from 'fs';
5
- import { getPidFile, readRuntimeConfig, removeRuntimeConfig, isInitialized } from '../utils/paths.js';
6
- async function killProcess(pid) {
7
- try {
8
- process.kill(pid, 'SIGTERM');
9
- let attempts = 0;
10
- while (attempts < 10) {
11
- await new Promise(r => setTimeout(r, 500));
12
- try {
13
- process.kill(pid, 0);
14
- attempts++;
15
- }
16
- catch {
17
- break;
18
- }
19
- }
20
- if (attempts >= 10) {
21
- process.kill(pid, 'SIGKILL');
22
- }
23
- }
24
- catch (error) {
25
- if (error.code !== 'ESRCH')
26
- throw error;
27
- }
28
- }
29
- export const stopCommand = new Command('stop')
30
- .description('Stop the Agentstage Runtime')
1
+ import { Command } from "commander";
2
+ import consola from "consola";
3
+ import c from "picocolors";
4
+ import { readRuntimeConfig, removeRuntimeConfig, isInitialized, } from "../utils/paths.js";
5
+ export const stopCommand = new Command("stop")
6
+ .description("Stop the Agentstage Runtime")
31
7
  .action(async () => {
32
- // 1. 检查是否已初始化
33
8
  if (!isInitialized()) {
34
- consola.error('Project not initialized. Please run `agentstage init` first.');
9
+ consola.error("Project not initialized. Please run `agentstage init` first.");
35
10
  process.exit(1);
36
11
  }
37
- // 2. 读取运行时配置
38
12
  const config = await readRuntimeConfig();
39
13
  if (!config) {
40
- consola.info('Runtime is not running');
14
+ consola.warn("Runtime is not running");
41
15
  return;
42
16
  }
43
- // 3. 停止进程
44
17
  try {
45
- await killProcess(config.pid);
18
+ process.kill(config.pid, 0);
19
+ process.kill(config.pid, "SIGTERM");
20
+ await new Promise((resolve) => setTimeout(resolve, 1000));
21
+ try {
22
+ process.kill(config.pid, 0);
23
+ process.kill(config.pid, "SIGKILL");
24
+ }
25
+ catch {
26
+ // process already stopped
27
+ }
46
28
  await removeRuntimeConfig();
47
- // 兼容旧版本:删除 pid 文件
48
- const pidFile = await getPidFile();
49
- if (existsSync(pidFile)) {
50
- await unlink(pidFile).catch(() => { });
29
+ consola.success("Runtime stopped");
30
+ console.log(` PID: ${c.gray(config.pid)}`);
31
+ console.log(` Port: ${c.gray(config.port)}`);
32
+ if (config.tunnelUrl) {
33
+ console.log(` Tunnel: ${c.gray(config.tunnelUrl)}`);
51
34
  }
52
- consola.success('Runtime stopped');
53
35
  }
54
- catch (error) {
55
- consola.error('Failed to stop runtime:', error.message);
56
- process.exit(1);
36
+ catch {
37
+ await removeRuntimeConfig();
38
+ consola.info("Runtime was not running (stale config cleaned up)");
57
39
  }
58
40
  });
package/dist/index.js CHANGED
@@ -7,48 +7,34 @@ import { dirname, join } from 'pathe';
7
7
  // Read version from package.json
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
9
  const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
10
- import { devCommand } from './commands/dev/index.js';
10
+ import { initCommand } from './commands/init.js';
11
+ import { stopCommand } from './commands/stop.js';
12
+ import { statusCommand } from './commands/status.js';
11
13
  import { pageCommand } from './commands/page/index.js';
12
14
  import { runCommand } from './commands/run/index.js';
13
15
  import { guideCommand } from './commands/guide.js';
14
16
  import { cleanupCommand } from './commands/cleanup.js';
15
17
  import { componentsCommand } from './commands/components.js';
16
18
  import { doctorCommand } from './commands/doctor.js';
17
- import { execCommand } from './commands/exec.js';
18
- import { initCommand } from './commands/init.js';
19
- import { inspectCommand } from './commands/inspect.js';
20
- import { lsCommand } from './commands/ls.js';
21
- import { restartCommand } from './commands/restart.js';
22
- import { rmPageCommand } from './commands/rm-page.js';
23
- import { startCommand } from './commands/start.js';
24
- import { statusCommand } from './commands/status.js';
25
- import { stopCommand } from './commands/stop.js';
26
19
  import { verifyCommand } from './commands/verify.js';
27
- import { watchCommand } from './commands/watch.js';
20
+ import { serveCommand } from './commands/serve.js';
28
21
  const program = new Command();
29
22
  program
30
23
  .name('agentstage')
31
24
  .description('Agent UI Stage CLI - Create interactive UI for AI agents')
32
25
  .version(pkg.version);
33
- // Register all commands
34
- program.addCommand(devCommand);
35
- program.addCommand(pageCommand);
36
- program.addCommand(runCommand);
37
- program.addCommand(guideCommand);
38
- program.addCommand(cleanupCommand);
39
- program.addCommand(componentsCommand);
40
- program.addCommand(doctorCommand);
41
- program.addCommand(execCommand);
42
- program.addCommand(initCommand);
43
- program.addCommand(inspectCommand);
44
- program.addCommand(lsCommand);
45
- program.addCommand(restartCommand);
46
- program.addCommand(rmPageCommand);
47
- program.addCommand(startCommand);
48
- program.addCommand(statusCommand);
49
- program.addCommand(stopCommand);
50
- program.addCommand(verifyCommand);
51
- program.addCommand(watchCommand);
26
+ // Register commands
27
+ program.addCommand(initCommand); // init
28
+ program.addCommand(serveCommand); // serve <pageId>
29
+ program.addCommand(stopCommand); // stop
30
+ program.addCommand(statusCommand); // status
31
+ program.addCommand(pageCommand); // page add/rm/ls/manifest
32
+ program.addCommand(runCommand); // run get-state/set-state/exec/inspect/watch
33
+ program.addCommand(guideCommand); // guide
34
+ program.addCommand(cleanupCommand); // cleanup
35
+ program.addCommand(componentsCommand); // components
36
+ program.addCommand(doctorCommand); // doctor
37
+ program.addCommand(verifyCommand); // verify
52
38
  // Error handling
53
39
  program.exitOverride();
54
40
  try {
@@ -53,17 +53,17 @@ const errorGuides = {
53
53
  // 运行时相关
54
54
  'runtime_not_running': {
55
55
  message: 'Runtime is not running',
56
- cause: 'The development server is not started',
57
- fix: 'Start the dev server in another terminal',
58
- example: 'agentstage dev start',
59
- relatedCommands: ['dev start', 'dev status']
56
+ cause: 'The runtime process is not started',
57
+ fix: 'Start a page runtime in another terminal',
58
+ example: 'agentstage serve <pageId>',
59
+ relatedCommands: ['serve', 'status']
60
60
  },
61
61
  'page_not_connected': {
62
62
  message: 'Page is not connected',
63
63
  cause: 'Using --live flag but page is not open in browser',
64
64
  fix: 'Either remove --live, or open the page in browser first',
65
65
  example: '# Option 1: File-only update\nagentstage run set-state mypage \'{...}\'\n\n# Option 2: Open page first\n# Then use --live',
66
- relatedCommands: ['run set-state', 'dev start']
66
+ relatedCommands: ['run set-state', 'serve']
67
67
  },
68
68
  // 路径遍历(安全)
69
69
  'path_traversal_detected': {
@@ -52,15 +52,15 @@ export async function getPidFile() {
52
52
  */
53
53
  export async function getPagesDir() {
54
54
  const workspace = await getWorkspaceDir();
55
- // New Vite template structure (src/routes for TanStack Router)
56
- if (existsSync(join(workspace, 'src', 'routes'))) {
57
- return join(workspace, 'src', 'pages');
55
+ // New runtime data structure
56
+ if (existsSync(join(workspace, 'pages'))) {
57
+ return join(workspace, 'pages');
58
58
  }
59
- // Legacy Vite template structure
59
+ // Legacy template structure fallback
60
60
  if (existsSync(join(workspace, 'src', 'pages'))) {
61
61
  return join(workspace, 'src', 'pages');
62
62
  }
63
- throw new Error('Routes directory not found at src/routes');
63
+ throw new Error('Pages directory not found at pages/');
64
64
  }
65
65
  // 运行时配置文件路径
66
66
  export async function getRuntimeConfigFile() {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Cloudflare Tunnel management for exposing local dev server
2
+ * Cloudflare Tunnel management for exposing local runtime server
3
3
  */
4
4
  export interface Tunnel {
5
5
  /** Public URL assigned by Cloudflare */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Cloudflare Tunnel management for exposing local dev server
2
+ * Cloudflare Tunnel management for exposing local runtime server
3
3
  */
4
4
  import { spawn } from 'child_process';
5
5
  import { findCloudflared } from './cloudflared.js';
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "agent-stage",
3
- "version": "0.2.14",
3
+ "version": "0.2.17",
4
4
  "files": [
5
- "dist",
6
- "template"
5
+ "dist"
7
6
  ],
8
7
  "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/parkgogogo/agent-stage"
11
+ },
9
12
  "bin": {
10
13
  "agent-stage": "./dist/index.js"
11
14
  },
@@ -16,8 +19,8 @@
16
19
  "execa": "^9.3.1",
17
20
  "pathe": "^1.1.2",
18
21
  "picocolors": "^1.1.1",
19
- "@agentstage/bridge": "0.1.2",
20
- "@agentstage/render": "0.2.2"
22
+ "@agentstage/render": "0.2.5",
23
+ "@agentstage/bridge": "0.1.3"
21
24
  },
22
25
  "devDependencies": {
23
26
  "@types/node": "^22.13.5",
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const devCommand: Command;
@@ -1,11 +0,0 @@
1
- import { Command } from 'commander';
2
- import { devInitCommand } from './init.js';
3
- import { devStartCommand } from './start.js';
4
- import { devStopCommand } from './stop.js';
5
- import { devStatusCommand } from './status.js';
6
- export const devCommand = new Command('dev')
7
- .description('Development commands for Agentstage')
8
- .addCommand(devInitCommand)
9
- .addCommand(devStartCommand)
10
- .addCommand(devStopCommand)
11
- .addCommand(devStatusCommand);
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare const devInitCommand: Command;