@lizard-build/cli 0.1.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.
Files changed (115) hide show
  1. package/dist/commands/add.d.ts +2 -0
  2. package/dist/commands/add.js +72 -0
  3. package/dist/commands/add.js.map +1 -0
  4. package/dist/commands/connect.d.ts +2 -0
  5. package/dist/commands/connect.js +117 -0
  6. package/dist/commands/connect.js.map +1 -0
  7. package/dist/commands/context.d.ts +2 -0
  8. package/dist/commands/context.js +71 -0
  9. package/dist/commands/context.js.map +1 -0
  10. package/dist/commands/deploy.d.ts +2 -0
  11. package/dist/commands/deploy.js +120 -0
  12. package/dist/commands/deploy.js.map +1 -0
  13. package/dist/commands/destroy.d.ts +2 -0
  14. package/dist/commands/destroy.js +51 -0
  15. package/dist/commands/destroy.js.map +1 -0
  16. package/dist/commands/git.d.ts +2 -0
  17. package/dist/commands/git.js +67 -0
  18. package/dist/commands/git.js.map +1 -0
  19. package/dist/commands/init.d.ts +2 -0
  20. package/dist/commands/init.js +107 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/link.d.ts +2 -0
  23. package/dist/commands/link.js +50 -0
  24. package/dist/commands/link.js.map +1 -0
  25. package/dist/commands/login.d.ts +7 -0
  26. package/dist/commands/login.js +123 -0
  27. package/dist/commands/login.js.map +1 -0
  28. package/dist/commands/logout.d.ts +2 -0
  29. package/dist/commands/logout.js +17 -0
  30. package/dist/commands/logout.js.map +1 -0
  31. package/dist/commands/logs.d.ts +2 -0
  32. package/dist/commands/logs.js +92 -0
  33. package/dist/commands/logs.js.map +1 -0
  34. package/dist/commands/open.d.ts +2 -0
  35. package/dist/commands/open.js +16 -0
  36. package/dist/commands/open.js.map +1 -0
  37. package/dist/commands/projects.d.ts +2 -0
  38. package/dist/commands/projects.js +28 -0
  39. package/dist/commands/projects.js.map +1 -0
  40. package/dist/commands/ps.d.ts +2 -0
  41. package/dist/commands/ps.js +52 -0
  42. package/dist/commands/ps.js.map +1 -0
  43. package/dist/commands/redeploy.d.ts +2 -0
  44. package/dist/commands/redeploy.js +69 -0
  45. package/dist/commands/redeploy.js.map +1 -0
  46. package/dist/commands/regions.d.ts +2 -0
  47. package/dist/commands/regions.js +23 -0
  48. package/dist/commands/regions.js.map +1 -0
  49. package/dist/commands/restart.d.ts +2 -0
  50. package/dist/commands/restart.js +21 -0
  51. package/dist/commands/restart.js.map +1 -0
  52. package/dist/commands/run.d.ts +2 -0
  53. package/dist/commands/run.js +33 -0
  54. package/dist/commands/run.js.map +1 -0
  55. package/dist/commands/secrets.d.ts +2 -0
  56. package/dist/commands/secrets.js +138 -0
  57. package/dist/commands/secrets.js.map +1 -0
  58. package/dist/commands/status.d.ts +2 -0
  59. package/dist/commands/status.js +51 -0
  60. package/dist/commands/status.js.map +1 -0
  61. package/dist/commands/update.d.ts +2 -0
  62. package/dist/commands/update.js +41 -0
  63. package/dist/commands/update.js.map +1 -0
  64. package/dist/commands/version.d.ts +2 -0
  65. package/dist/commands/version.js +37 -0
  66. package/dist/commands/version.js.map +1 -0
  67. package/dist/commands/whoami.d.ts +2 -0
  68. package/dist/commands/whoami.js +21 -0
  69. package/dist/commands/whoami.js.map +1 -0
  70. package/dist/index.d.ts +2 -0
  71. package/dist/index.js +151 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/lib/api.d.ts +19 -0
  74. package/dist/lib/api.js +114 -0
  75. package/dist/lib/api.js.map +1 -0
  76. package/dist/lib/auth.d.ts +23 -0
  77. package/dist/lib/auth.js +89 -0
  78. package/dist/lib/auth.js.map +1 -0
  79. package/dist/lib/config.d.ts +23 -0
  80. package/dist/lib/config.js +77 -0
  81. package/dist/lib/config.js.map +1 -0
  82. package/dist/lib/format.d.ts +11 -0
  83. package/dist/lib/format.js +86 -0
  84. package/dist/lib/format.js.map +1 -0
  85. package/install.sh +59 -0
  86. package/package.json +35 -0
  87. package/src/commands/add.ts +100 -0
  88. package/src/commands/connect.ts +145 -0
  89. package/src/commands/context.ts +93 -0
  90. package/src/commands/deploy.ts +153 -0
  91. package/src/commands/destroy.ts +51 -0
  92. package/src/commands/git.ts +80 -0
  93. package/src/commands/init.ts +139 -0
  94. package/src/commands/link.ts +63 -0
  95. package/src/commands/login.ts +158 -0
  96. package/src/commands/logout.ts +17 -0
  97. package/src/commands/logs.ts +104 -0
  98. package/src/commands/open.ts +17 -0
  99. package/src/commands/projects.ts +45 -0
  100. package/src/commands/ps.ts +80 -0
  101. package/src/commands/redeploy.ts +74 -0
  102. package/src/commands/regions.ts +38 -0
  103. package/src/commands/restart.ts +24 -0
  104. package/src/commands/run.ts +43 -0
  105. package/src/commands/secrets.ts +175 -0
  106. package/src/commands/status.ts +65 -0
  107. package/src/commands/update.ts +44 -0
  108. package/src/commands/version.ts +37 -0
  109. package/src/commands/whoami.ts +27 -0
  110. package/src/index.ts +168 -0
  111. package/src/lib/api.ts +134 -0
  112. package/src/lib/auth.ts +113 -0
  113. package/src/lib/config.ts +93 -0
  114. package/src/lib/format.ts +95 -0
  115. package/tsconfig.json +17 -0
@@ -0,0 +1,107 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import * as p from "@clack/prompts";
5
+ import { api } from "../lib/api.js";
6
+ import { findProjectConfig, saveProjectConfig, } from "../lib/config.js";
7
+ import { success, info, isJSONMode, printJSON, isTTY, } from "../lib/format.js";
8
+ /** Detect framework from files in cwd */
9
+ function detectFramework() {
10
+ const cwd = process.cwd();
11
+ const has = (f) => fs.existsSync(path.join(cwd, f));
12
+ if (has("next.config.js") || has("next.config.mjs") || has("next.config.ts"))
13
+ return { name: "Next.js", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
14
+ if (has("nuxt.config.ts") || has("nuxt.config.js"))
15
+ return { name: "Nuxt", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
16
+ if (has("remix.config.js") || has("remix.config.ts"))
17
+ return { name: "Remix", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
18
+ if (has("astro.config.mjs") || has("astro.config.ts"))
19
+ return { name: "Astro", port: 4321, buildCmd: "npm run build", startCmd: "npm start" };
20
+ if (has("vite.config.ts") || has("vite.config.js"))
21
+ return { name: "Vite", port: 3000, buildCmd: "npm run build", startCmd: "npm run preview" };
22
+ if (has("Dockerfile"))
23
+ return { name: "Docker", port: 8080, buildCmd: "", startCmd: "" };
24
+ if (has("go.mod"))
25
+ return { name: "Go", port: 8080, buildCmd: "go build -o app .", startCmd: "./app" };
26
+ if (has("requirements.txt") || has("pyproject.toml"))
27
+ return { name: "Python", port: 8000, buildCmd: "pip install -r requirements.txt", startCmd: "python app.py" };
28
+ if (has("package.json"))
29
+ return { name: "Node.js", port: 3000, buildCmd: "npm run build", startCmd: "npm start" };
30
+ return null;
31
+ }
32
+ function writeLizardToml(framework) {
33
+ const port = framework?.port ?? 3000;
34
+ const build = framework?.buildCmd ?? "";
35
+ const start = framework?.startCmd ?? "";
36
+ let toml = `# lizard.toml\n\n`;
37
+ if (build)
38
+ toml += `[build]\ncommand = "${build}"\n\n`;
39
+ toml += `[deploy]\nport = ${port}\n`;
40
+ if (start)
41
+ toml += `start_command = "${start}"\n`;
42
+ toml += `\n[resources]\ncpu = 1\nmemory = 512\n`;
43
+ const tomlPath = path.join(process.cwd(), "lizard.toml");
44
+ if (!fs.existsSync(tomlPath)) {
45
+ fs.writeFileSync(tomlPath, toml);
46
+ }
47
+ }
48
+ export function registerInit(program) {
49
+ program
50
+ .command("init")
51
+ .description("Create a new project and link current directory")
52
+ .option("--name <name>", "Project name")
53
+ .action(async (opts) => {
54
+ // Check if already initialized
55
+ const existing = findProjectConfig();
56
+ if (existing) {
57
+ throw new Error("Already initialized. Run `lizard link` to change project.");
58
+ }
59
+ // Detect framework
60
+ const framework = detectFramework();
61
+ if (framework && !isJSONMode()) {
62
+ info(`Detected framework: ${chalk.cyan(framework.name)}`);
63
+ }
64
+ // Get project name
65
+ let projectName = opts.name;
66
+ if (!projectName) {
67
+ if (!isTTY()) {
68
+ throw new Error("--name is required in non-interactive mode");
69
+ }
70
+ const result = await p.text({
71
+ message: "Project name",
72
+ defaultValue: path.basename(process.cwd()),
73
+ placeholder: path.basename(process.cwd()),
74
+ });
75
+ if (p.isCancel(result))
76
+ process.exit(5);
77
+ projectName = result;
78
+ }
79
+ // Create project via API
80
+ const project = await api.post("/api/projects", {
81
+ name: projectName,
82
+ });
83
+ // Save local config
84
+ saveProjectConfig({
85
+ projectId: project.id,
86
+ projectName: project.name,
87
+ });
88
+ // Write lizard.toml
89
+ writeLizardToml(framework);
90
+ if (isJSONMode()) {
91
+ printJSON({
92
+ projectId: project.id,
93
+ name: project.name,
94
+ framework: framework?.name,
95
+ });
96
+ }
97
+ else {
98
+ success(`Project "${chalk.bold(project.name)}" created`);
99
+ info(chalk.dim(" Linked to current directory"));
100
+ info(chalk.dim(" Config saved to .lizard/config.json"));
101
+ if (framework) {
102
+ info(chalk.dim(` lizard.toml created for ${framework.name}`));
103
+ }
104
+ }
105
+ });
106
+ }
107
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerLink(program: Command): void;
@@ -0,0 +1,50 @@
1
+ import chalk from "chalk";
2
+ import * as p from "@clack/prompts";
3
+ import { api } from "../lib/api.js";
4
+ import { saveProjectConfig, findProjectConfig } from "../lib/config.js";
5
+ import { success, isJSONMode, printJSON, isTTY } from "../lib/format.js";
6
+ export function registerLink(program) {
7
+ program
8
+ .command("link")
9
+ .description("Link current directory to an existing project")
10
+ .option("--project <id>", "Project ID")
11
+ .action(async (opts) => {
12
+ let projectId = opts.project;
13
+ let projectName;
14
+ if (!projectId) {
15
+ // Fetch projects and let user pick
16
+ const projects = await api.get("/api/projects");
17
+ if (projects.length === 0) {
18
+ throw new Error("No projects found. Run `lizard init` to create one.");
19
+ }
20
+ if (!isTTY()) {
21
+ throw new Error("Use --project <id> in non-interactive mode. Available: " +
22
+ projects.map((p) => `${p.name} (${p.id})`).join(", "));
23
+ }
24
+ const selected = await p.select({
25
+ message: "Select project",
26
+ options: projects.map((proj) => ({
27
+ value: proj.id,
28
+ label: proj.name,
29
+ hint: proj.id,
30
+ })),
31
+ });
32
+ if (p.isCancel(selected))
33
+ process.exit(5);
34
+ projectId = selected;
35
+ projectName = projects.find((p) => p.id === projectId)?.name;
36
+ }
37
+ const old = findProjectConfig();
38
+ saveProjectConfig({ projectId, projectName });
39
+ if (isJSONMode()) {
40
+ printJSON({ projectId, projectName });
41
+ }
42
+ else if (old?.projectId && old.projectId !== projectId) {
43
+ success(`Relinked to ${chalk.bold(projectName || projectId)} (was ${old.projectName || old.projectId})`);
44
+ }
45
+ else {
46
+ success(`Linked to ${chalk.bold(projectName || projectId)}`);
47
+ }
48
+ });
49
+ }
50
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQzE,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,WAA+B,CAAC;QAEpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,mCAAmC;YACnC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,CAAY,eAAe,CAAC,CAAC;YAC3D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,yDAAyD;oBACvD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxD,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;gBAC9B,OAAO,EAAE,gBAAgB;gBACzB,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC/B,KAAK,EAAE,IAAI,CAAC,EAAE;oBACd,KAAK,EAAE,IAAI,CAAC,IAAI;oBAChB,IAAI,EAAE,IAAI,CAAC,EAAE;iBACd,CAAC,CAAC;aACJ,CAAC,CAAC;YACH,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC1C,SAAS,GAAG,QAAkB,CAAC;YAC/B,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,IAAI,CAAC;QAC/D,CAAC;QAED,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,iBAAiB,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QAE9C,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACzD,OAAO,CACL,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,SAAS,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,SAAS,GAAG,CAChG,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Command } from "commander";
2
+ import { type Credentials } from "../lib/auth.js";
3
+ /**
4
+ * Perform the login flow. Used by the login command and by auto-login in requireAuth.
5
+ */
6
+ export declare function performLogin(): Promise<Credentials>;
7
+ export declare function registerLogin(program: Command): void;
@@ -0,0 +1,123 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { saveCredentials, openURL, } from "../lib/auth.js";
4
+ import { getBaseURL } from "../lib/api.js";
5
+ import { success, info, isJSONMode, printJSON } from "../lib/format.js";
6
+ const POLL_INTERVAL = 2000;
7
+ const SESSION_TIMEOUT = 300_000; // 5 min
8
+ /** Create a CLI login session on the server */
9
+ async function createSession() {
10
+ const res = await fetch(`${getBaseURL()}/api/auth/cli/session`, {
11
+ method: "POST",
12
+ headers: { "Content-Type": "application/json" },
13
+ });
14
+ if (!res.ok) {
15
+ throw new Error(`Failed to create login session: ${res.statusText}`);
16
+ }
17
+ return res.json();
18
+ }
19
+ /** Poll the server to check if the user completed login */
20
+ async function pollSession(sessionId, sessionSecret) {
21
+ const res = await fetch(`${getBaseURL()}/api/auth/cli/poll`, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({ sessionId, sessionSecret }),
25
+ });
26
+ if (!res.ok) {
27
+ throw new Error(`Poll failed: ${res.statusText}`);
28
+ }
29
+ return res.json();
30
+ }
31
+ /**
32
+ * Perform the login flow. Used by the login command and by auto-login in requireAuth.
33
+ */
34
+ export async function performLogin() {
35
+ // 1. Create session
36
+ const session = await createSession();
37
+ const loginURL = `${getBaseURL()}/auth/cli?session=${session.sessionId}`;
38
+ // 2. Try to open browser
39
+ const opened = await openURL(loginURL);
40
+ if (opened) {
41
+ info("Opening browser to log in...");
42
+ }
43
+ else {
44
+ info(`Open this URL in your browser to log in:\n ${chalk.cyan(loginURL)}`);
45
+ }
46
+ // 3. Poll until complete
47
+ const spinner = ora("Waiting for login...").start();
48
+ const deadline = Date.now() + SESSION_TIMEOUT;
49
+ while (Date.now() < deadline) {
50
+ await sleep(POLL_INTERVAL);
51
+ try {
52
+ const result = await pollSession(session.sessionId, session.sessionSecret);
53
+ if (result.status === "complete" && result.accessToken && result.user) {
54
+ spinner.stop();
55
+ const creds = {
56
+ accessToken: result.accessToken,
57
+ refreshToken: result.refreshToken,
58
+ userId: result.user.id,
59
+ username: result.user.username,
60
+ email: result.user.email,
61
+ avatarUrl: result.user.avatarUrl,
62
+ };
63
+ saveCredentials(creds);
64
+ if (isJSONMode()) {
65
+ printJSON({ username: creds.username, email: creds.email });
66
+ }
67
+ else {
68
+ success(`Logged in as ${chalk.bold(creds.username)}`);
69
+ }
70
+ return creds;
71
+ }
72
+ if (result.status === "expired") {
73
+ spinner.stop();
74
+ throw new Error("Login session expired. Please try again.");
75
+ }
76
+ }
77
+ catch (err) {
78
+ if (err.message?.includes("expired")) {
79
+ spinner.stop();
80
+ throw err;
81
+ }
82
+ // Network error — keep trying
83
+ }
84
+ }
85
+ spinner.stop();
86
+ throw new Error("Login timed out. Please try again.");
87
+ }
88
+ function sleep(ms) {
89
+ return new Promise((r) => setTimeout(r, ms));
90
+ }
91
+ export function registerLogin(program) {
92
+ program
93
+ .command("login")
94
+ .description("Log in to Lizard")
95
+ .option("--token <token>", "Authenticate with an API token")
96
+ .action(async (opts) => {
97
+ if (opts.token) {
98
+ // Direct token auth — validate it
99
+ const res = await fetch(`${getBaseURL()}/api/auth/me`, {
100
+ headers: { Authorization: `Bearer ${opts.token}` },
101
+ });
102
+ if (!res.ok)
103
+ throw new Error("Invalid token");
104
+ const user = (await res.json());
105
+ saveCredentials({
106
+ accessToken: opts.token,
107
+ userId: user.id,
108
+ username: user.username,
109
+ email: user.email,
110
+ avatarUrl: user.avatarUrl,
111
+ });
112
+ if (isJSONMode()) {
113
+ printJSON({ username: user.username });
114
+ }
115
+ else {
116
+ success(`Logged in as ${chalk.bold(user.username)}`);
117
+ }
118
+ return;
119
+ }
120
+ await performLogin();
121
+ });
122
+ }
123
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerLogout(program: Command): void;
@@ -0,0 +1,17 @@
1
+ import { clearCredentials } from "../lib/auth.js";
2
+ import { success, isJSONMode, printJSON } from "../lib/format.js";
3
+ export function registerLogout(program) {
4
+ program
5
+ .command("logout")
6
+ .description("Log out of Lizard")
7
+ .action(async () => {
8
+ clearCredentials();
9
+ if (isJSONMode()) {
10
+ printJSON({ status: "logged_out" });
11
+ }
12
+ else {
13
+ success("Logged out");
14
+ }
15
+ });
16
+ }
17
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,gBAAgB,EAAE,CAAC;QACnB,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,YAAY,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerLogs(program: Command): void;
@@ -0,0 +1,92 @@
1
+ import chalk from "chalk";
2
+ import { streamSSE, api } from "../lib/api.js";
3
+ import { resolveProjectId } from "../lib/config.js";
4
+ import { info, error } from "../lib/format.js";
5
+ export function registerLogs(program) {
6
+ program
7
+ .command("logs")
8
+ .description("Stream runtime logs")
9
+ .option("--build", "Show build logs instead of runtime")
10
+ .option("--service <id>", "Only show logs for a specific service")
11
+ .action(async (opts) => {
12
+ const projectId = resolveProjectId(program.opts().project);
13
+ if (opts.build) {
14
+ // Show build logs for the latest build
15
+ await showBuildLogs(opts.service, projectId);
16
+ return;
17
+ }
18
+ if (opts.service) {
19
+ // Stream logs for a specific app
20
+ info(chalk.dim("Streaming logs... (Ctrl+C to stop)\n"));
21
+ await streamSSE(`/api/apps/${opts.service}/logs`, (event, data) => {
22
+ if (event === "error") {
23
+ error(data);
24
+ return false;
25
+ }
26
+ printLogLine(data);
27
+ return true;
28
+ });
29
+ return;
30
+ }
31
+ // Stream all project logs
32
+ info(chalk.dim("Streaming project logs... (Ctrl+C to stop)\n"));
33
+ await streamSSE(`/api/projects/${projectId}/logs/stream`, (event, data) => {
34
+ if (event === "error") {
35
+ error(data);
36
+ return false;
37
+ }
38
+ printLogLine(data);
39
+ return true;
40
+ });
41
+ });
42
+ }
43
+ function printLogLine(data) {
44
+ try {
45
+ const parsed = JSON.parse(data);
46
+ if (parsed.service && parsed.line) {
47
+ const prefix = chalk.cyan(`[${parsed.service}]`);
48
+ process.stdout.write(`${prefix} ${parsed.line}\n`);
49
+ }
50
+ else if (parsed.line) {
51
+ process.stdout.write(parsed.line + "\n");
52
+ }
53
+ else if (parsed.message) {
54
+ process.stdout.write(parsed.message + "\n");
55
+ }
56
+ else if (typeof parsed === "string") {
57
+ process.stdout.write(parsed + "\n");
58
+ }
59
+ else {
60
+ process.stdout.write(data + "\n");
61
+ }
62
+ }
63
+ catch {
64
+ process.stdout.write(data + "\n");
65
+ }
66
+ }
67
+ async function showBuildLogs(serviceId, projectId) {
68
+ let appId = serviceId;
69
+ if (!appId) {
70
+ // Get first app in project
71
+ const data = await api.get(`/api/projects/${projectId}/services`);
72
+ if (!data.apps?.length) {
73
+ throw new Error("No apps in project");
74
+ }
75
+ appId = data.apps[0].id;
76
+ }
77
+ // Get latest build
78
+ const app = await api.get(`/api/apps/${appId}`);
79
+ if (!app.builds?.length) {
80
+ throw new Error("No builds found");
81
+ }
82
+ const buildId = app.builds[0].id;
83
+ info(chalk.dim(`Build ${buildId}\n`));
84
+ await streamSSE(`/api/builds/${buildId}/logs`, (event, data) => {
85
+ if (event === "done" || event === "error") {
86
+ return false;
87
+ }
88
+ printLogLine(data);
89
+ return true;
90
+ });
91
+ }
92
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerOpen(program: Command): void;
@@ -0,0 +1,16 @@
1
+ import open from "open";
2
+ import { resolveProjectId } from "../lib/config.js";
3
+ import { getBaseURL } from "../lib/api.js";
4
+ import { success } from "../lib/format.js";
5
+ export function registerOpen(program) {
6
+ program
7
+ .command("open")
8
+ .description("Open project in browser")
9
+ .action(async () => {
10
+ const projectId = resolveProjectId(program.opts().project);
11
+ const url = `${getBaseURL()}/projects/${projectId}`;
12
+ await open(url);
13
+ success("Opened in browser");
14
+ });
15
+ }
16
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,GAAG,UAAU,EAAE,aAAa,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerProjects(program: Command): void;
@@ -0,0 +1,28 @@
1
+ import { api } from "../lib/api.js";
2
+ import { isJSONMode, printJSON, table } from "../lib/format.js";
3
+ export function registerProjects(program) {
4
+ const proj = program
5
+ .command("project")
6
+ .description("Project management");
7
+ proj
8
+ .command("list")
9
+ .description("List all projects")
10
+ .action(async () => {
11
+ const projects = await api.get("/api/projects");
12
+ if (isJSONMode()) {
13
+ printJSON(projects);
14
+ return;
15
+ }
16
+ if (projects.length === 0) {
17
+ console.log("No projects. Run `lizard init` to create one.");
18
+ return;
19
+ }
20
+ table(["Name", "ID", "Role", "Members"], projects.map((p) => [
21
+ p.name,
22
+ p.id,
23
+ p.role || "owner",
24
+ String(p.memberCount || 1),
25
+ ]));
26
+ });
27
+ }
28
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWhE,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAErC,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,GAAG,CAAY,eAAe,CAAC,CAAC;QAE3D,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,KAAK,CACH,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EACjC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAClB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,IAAI,OAAO;YACjB,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;SAC3B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerPs(program: Command): void;
@@ -0,0 +1,52 @@
1
+ import chalk from "chalk";
2
+ import { api } from "../lib/api.js";
3
+ import { resolveProjectId } from "../lib/config.js";
4
+ import { isJSONMode, printJSON, table, statusColor, } from "../lib/format.js";
5
+ export function registerPs(program) {
6
+ program
7
+ .command("ps")
8
+ .description("List all services in the project")
9
+ .action(async () => {
10
+ const projectId = resolveProjectId(program.opts().project);
11
+ const data = await api.get(`/api/projects/${projectId}/services`);
12
+ const services = [];
13
+ for (const app of data.apps || []) {
14
+ services.push({
15
+ id: app.id,
16
+ name: app.name,
17
+ type: "app",
18
+ status: app.status,
19
+ domain: app.domain,
20
+ createdAt: app.createdAt,
21
+ });
22
+ }
23
+ for (const addon of data.addons || []) {
24
+ services.push({
25
+ id: addon.id,
26
+ name: addon.name || addon.addonType,
27
+ type: "addon",
28
+ addonType: addon.addonType,
29
+ status: addon.status,
30
+ hostname: addon.hostname,
31
+ createdAt: addon.createdAt,
32
+ });
33
+ }
34
+ if (isJSONMode()) {
35
+ printJSON(services);
36
+ return;
37
+ }
38
+ if (services.length === 0) {
39
+ console.log("No services. Use `lizard add` or `lizard deploy`.");
40
+ return;
41
+ }
42
+ table(["Name", "Type", "Status", "URL/Host"], services.map((s) => [
43
+ s.name,
44
+ s.addonType || s.type,
45
+ statusColor(s.status),
46
+ s.domain
47
+ ? `https://${s.domain}`
48
+ : s.hostname || chalk.dim("—"),
49
+ ]));
50
+ });
51
+ }
52
+ //# sourceMappingURL=ps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ps.js","sourceRoot":"","sources":["../../src/commands/ps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,SAAS,EACT,KAAK,EACL,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAa1B,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,IAAI,CAAC;SACb,WAAW,CAAC,kCAAkC,CAAC;SAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,iBAAiB,SAAS,WAAW,CACtC,CAAC;QAEF,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;QACL,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS;gBACnC,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC,QAAQ,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,KAAK,CACH,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,EACtC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAClB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI;YACrB,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;YACrB,CAAC,CAAC,MAAM;gBACN,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE;gBACvB,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;SACjC,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerRedeploy(program: Command): void;
@@ -0,0 +1,69 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import { api, streamSSE } from "../lib/api.js";
4
+ import { success, info, error, isJSONMode, printJSON } from "../lib/format.js";
5
+ export function registerRedeploy(program) {
6
+ program
7
+ .command("redeploy")
8
+ .argument("<id>", "Service ID to redeploy")
9
+ .description("Redeploy a service from latest build with current secrets")
10
+ .option("--detach", "Run in background")
11
+ .action(async (id, opts) => {
12
+ const spinner = ora("Starting redeploy...").start();
13
+ await api.post(`/api/apps/${id}/redeploy`);
14
+ spinner.stop();
15
+ if (opts.detach || isJSONMode()) {
16
+ if (isJSONMode()) {
17
+ printJSON({ id, status: "deploying" });
18
+ }
19
+ else {
20
+ success("Redeploy started");
21
+ info(chalk.dim(` Check status: lizard deploy-status ${id}`));
22
+ }
23
+ return;
24
+ }
25
+ // Stream build logs if not detached
26
+ info("Redeploying...");
27
+ // Poll for build
28
+ let buildId = null;
29
+ for (let i = 0; i < 30; i++) {
30
+ await new Promise((r) => setTimeout(r, 2000));
31
+ try {
32
+ const app = await api.get(`/api/apps/${id}`);
33
+ if (app.builds?.length) {
34
+ const latest = app.builds[0];
35
+ if (["building", "deploying", "running", "failed"].includes(latest.status)) {
36
+ buildId = latest.id;
37
+ break;
38
+ }
39
+ }
40
+ }
41
+ catch { }
42
+ }
43
+ if (buildId) {
44
+ await streamSSE(`/api/builds/${buildId}/logs`, (event, data) => {
45
+ if (event === "done" || event === "error") {
46
+ if (event === "error")
47
+ error(`Build failed: ${data}`);
48
+ return false;
49
+ }
50
+ try {
51
+ const parsed = JSON.parse(data);
52
+ process.stdout.write((parsed.line || data) + "\n");
53
+ }
54
+ catch {
55
+ process.stdout.write(data + "\n");
56
+ }
57
+ return true;
58
+ });
59
+ }
60
+ const app = await api.get(`/api/apps/${id}`);
61
+ if (app.status === "running") {
62
+ success(`Redeployed! ${app.domain ? chalk.cyan(`https://${app.domain}`) : ""}`);
63
+ }
64
+ else {
65
+ error("Redeploy failed");
66
+ }
67
+ });
68
+ }
69
+ //# sourceMappingURL=redeploy.js.map