@lizard-build/cli 0.3.78 → 0.3.79
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/commands/workspace.d.ts +4 -3
- package/dist/commands/workspace.js +40 -7
- package/dist/commands/workspace.js.map +1 -1
- package/dist/lib/updater.d.ts +1 -1
- package/dist/lib/updater.js +1 -1
- package/package.json +1 -1
- package/src/commands/workspace.ts +43 -7
- package/src/lib/updater.ts +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
/**
|
|
3
|
-
* `lizard workspace` — create and
|
|
3
|
+
* `lizard workspace` — create, list, and delete workspaces.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Delete only removes empty workspaces (no projects, no sandboxes). Member
|
|
6
|
+
* management (invite/remove/rename) intentionally lives in the dashboard, not
|
|
7
|
+
* here, to keep the CLI surface narrow (Railway model).
|
|
7
8
|
*/
|
|
8
9
|
export declare function registerWorkspace(program: Command): void;
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { api, withQuery } from "../lib/api.js";
|
|
4
|
+
import { fetchWorkspaces, resolveWorkspace } from "../lib/picker.js";
|
|
5
|
+
import { isJSONMode, printJSON, table, success, info, isTTY } from "../lib/format.js";
|
|
5
6
|
/**
|
|
6
|
-
* `lizard workspace` — create and
|
|
7
|
+
* `lizard workspace` — create, list, and delete workspaces.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Delete only removes empty workspaces (no projects, no sandboxes). Member
|
|
10
|
+
* management (invite/remove/rename) intentionally lives in the dashboard, not
|
|
11
|
+
* here, to keep the CLI surface narrow (Railway model).
|
|
10
12
|
*/
|
|
11
13
|
export function registerWorkspace(program) {
|
|
12
14
|
const ws = program
|
|
13
15
|
.command("workspace")
|
|
14
|
-
.description("Create and
|
|
16
|
+
.description("Create, list, and delete workspaces");
|
|
15
17
|
ws.command("create")
|
|
16
18
|
.argument("<name>", "Workspace name")
|
|
17
19
|
.description("Create a new workspace")
|
|
@@ -46,5 +48,36 @@ export function registerWorkspace(program) {
|
|
|
46
48
|
w.isPersonal ? chalk.green("✓") : "",
|
|
47
49
|
]));
|
|
48
50
|
});
|
|
51
|
+
ws.command("rm")
|
|
52
|
+
.alias("delete")
|
|
53
|
+
.argument("<name-or-id>", "Workspace name, slug, or ID")
|
|
54
|
+
.description("Delete an empty workspace")
|
|
55
|
+
.option("-y, --yes", "Skip confirmation")
|
|
56
|
+
.action(async (nameOrId, opts) => {
|
|
57
|
+
const workspace = await resolveWorkspace(nameOrId);
|
|
58
|
+
if (workspace.isPersonal) {
|
|
59
|
+
throw new Error("Cannot delete your personal workspace.");
|
|
60
|
+
}
|
|
61
|
+
if (workspace.role !== "owner") {
|
|
62
|
+
throw new Error("Only the workspace owner can delete it.");
|
|
63
|
+
}
|
|
64
|
+
// Empty workspaces only. Check here for a clear message; the backend
|
|
65
|
+
// enforces the same via ?requireEmpty=true and also refuses if any
|
|
66
|
+
// sandbox remains (which the CLI can't count on its own).
|
|
67
|
+
const projectCount = workspace.projectCount ?? 0;
|
|
68
|
+
if (projectCount > 0) {
|
|
69
|
+
throw new Error(`Workspace "${workspace.name}" has ${projectCount} project(s). Delete them first, or use the dashboard to remove everything.`);
|
|
70
|
+
}
|
|
71
|
+
if (!opts.yes && isTTY() && !isJSONMode()) {
|
|
72
|
+
const ok = await p.confirm({ message: `Delete workspace ${chalk.bold(workspace.name)}?` });
|
|
73
|
+
if (p.isCancel(ok) || !ok)
|
|
74
|
+
process.exit(5);
|
|
75
|
+
}
|
|
76
|
+
await api.delete(withQuery(`/api/workspaces/${workspace.id}`, { requireEmpty: true }));
|
|
77
|
+
if (isJSONMode())
|
|
78
|
+
printJSON({ id: workspace.id, status: "deleted" });
|
|
79
|
+
else
|
|
80
|
+
success(`Workspace ${chalk.bold(workspace.name)} deleted`);
|
|
81
|
+
});
|
|
49
82
|
}
|
|
50
83
|
//# sourceMappingURL=workspace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/commands/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/commands/workspace.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/updater.d.ts
CHANGED
package/dist/lib/updater.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Readable } from "node:stream";
|
|
|
4
4
|
import { join, dirname } from "node:path";
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
|
-
export const CURRENT_VERSION = "0.3.
|
|
7
|
+
export const CURRENT_VERSION = "0.3.79";
|
|
8
8
|
const RELEASES_API = "https://api.github.com/repos/lizard-build/lizard-cli/releases/latest";
|
|
9
9
|
const RELEASE_BASE = "https://github.com/lizard-build/lizard-cli/releases/latest/download";
|
|
10
10
|
/** Minimum gap between background update checks. */
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
2
3
|
import { Command } from "commander";
|
|
3
|
-
import { api, type Workspace } from "../lib/api.js";
|
|
4
|
-
import { fetchWorkspaces } from "../lib/picker.js";
|
|
5
|
-
import { isJSONMode, printJSON, table, success, info } from "../lib/format.js";
|
|
4
|
+
import { api, withQuery, type Workspace } from "../lib/api.js";
|
|
5
|
+
import { fetchWorkspaces, resolveWorkspace } from "../lib/picker.js";
|
|
6
|
+
import { isJSONMode, printJSON, table, success, info, isTTY } from "../lib/format.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* `lizard workspace` — create and
|
|
9
|
+
* `lizard workspace` — create, list, and delete workspaces.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* Delete only removes empty workspaces (no projects, no sandboxes). Member
|
|
12
|
+
* management (invite/remove/rename) intentionally lives in the dashboard, not
|
|
13
|
+
* here, to keep the CLI surface narrow (Railway model).
|
|
12
14
|
*/
|
|
13
15
|
export function registerWorkspace(program: Command) {
|
|
14
16
|
const ws = program
|
|
15
17
|
.command("workspace")
|
|
16
|
-
.description("Create and
|
|
18
|
+
.description("Create, list, and delete workspaces");
|
|
17
19
|
|
|
18
20
|
ws.command("create")
|
|
19
21
|
.argument("<name>", "Workspace name")
|
|
@@ -58,4 +60,38 @@ export function registerWorkspace(program: Command) {
|
|
|
58
60
|
]),
|
|
59
61
|
);
|
|
60
62
|
});
|
|
63
|
+
|
|
64
|
+
ws.command("rm")
|
|
65
|
+
.alias("delete")
|
|
66
|
+
.argument("<name-or-id>", "Workspace name, slug, or ID")
|
|
67
|
+
.description("Delete an empty workspace")
|
|
68
|
+
.option("-y, --yes", "Skip confirmation")
|
|
69
|
+
.action(async (nameOrId: string, opts: { yes?: boolean }) => {
|
|
70
|
+
const workspace = await resolveWorkspace(nameOrId);
|
|
71
|
+
|
|
72
|
+
if (workspace.isPersonal) {
|
|
73
|
+
throw new Error("Cannot delete your personal workspace.");
|
|
74
|
+
}
|
|
75
|
+
if (workspace.role !== "owner") {
|
|
76
|
+
throw new Error("Only the workspace owner can delete it.");
|
|
77
|
+
}
|
|
78
|
+
// Empty workspaces only. Check here for a clear message; the backend
|
|
79
|
+
// enforces the same via ?requireEmpty=true and also refuses if any
|
|
80
|
+
// sandbox remains (which the CLI can't count on its own).
|
|
81
|
+
const projectCount = workspace.projectCount ?? 0;
|
|
82
|
+
if (projectCount > 0) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Workspace "${workspace.name}" has ${projectCount} project(s). Delete them first, or use the dashboard to remove everything.`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!opts.yes && isTTY() && !isJSONMode()) {
|
|
89
|
+
const ok = await p.confirm({ message: `Delete workspace ${chalk.bold(workspace.name)}?` });
|
|
90
|
+
if (p.isCancel(ok) || !ok) process.exit(5);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await api.delete(withQuery(`/api/workspaces/${workspace.id}`, { requireEmpty: true }));
|
|
94
|
+
if (isJSONMode()) printJSON({ id: workspace.id, status: "deleted" });
|
|
95
|
+
else success(`Workspace ${chalk.bold(workspace.name)} deleted`);
|
|
96
|
+
});
|
|
61
97
|
}
|
package/src/lib/updater.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { join, dirname } from "node:path";
|
|
|
5
5
|
import os from "node:os";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
|
|
8
|
-
export const CURRENT_VERSION = "0.3.
|
|
8
|
+
export const CURRENT_VERSION = "0.3.79";
|
|
9
9
|
const RELEASES_API = "https://api.github.com/repos/lizard-build/lizard-cli/releases/latest";
|
|
10
10
|
const RELEASE_BASE = "https://github.com/lizard-build/lizard-cli/releases/latest/download";
|
|
11
11
|
|