@lotics/cli 0.67.0 → 0.69.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.
- package/README.md +1 -0
- package/dist/args.d.ts +2 -0
- package/dist/args.js +5 -0
- package/dist/args.test.js +8 -0
- package/dist/cli.js +33 -1
- package/dist/client.d.ts +4 -0
- package/dist/client.js +3 -0
- package/dist/src/cli.js +53 -8
- package/dist/starter_template.js +13 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,6 +87,7 @@ Workspaces live inside the active org. If the org has more than one, select befo
|
|
|
87
87
|
lotics workspace # list workspaces in the active org (marks current)
|
|
88
88
|
lotics workspace select wks_... # set the workspace for the active scope (pin or profile)
|
|
89
89
|
lotics workspace create "Sales" # create a new workspace (admin only)
|
|
90
|
+
lotics workspace delete wks_... --yes # delete a workspace (admin only; soft delete, recoverable)
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
Single-workspace organizations auto-select on first use. The selection is remembered per org, so switching back lands where you left off.
|
package/dist/args.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export declare function parseArgs(argv: string[]): {
|
|
|
30
30
|
message?: string;
|
|
31
31
|
local: boolean;
|
|
32
32
|
all: boolean;
|
|
33
|
+
/** `--yes` (alias `-y`): confirm a destructive command (e.g. `workspace delete`) non-interactively. */
|
|
34
|
+
yes: boolean;
|
|
33
35
|
/** `--print-created` (alias `--report-effects`): print the honest post-run side-effect harvest. */
|
|
34
36
|
printCreated: boolean;
|
|
35
37
|
/** `--cleanup`: also delete the harvested created records (records only). */
|
package/dist/args.js
CHANGED
|
@@ -25,6 +25,7 @@ export function parseArgs(argv) {
|
|
|
25
25
|
message: undefined,
|
|
26
26
|
local: false,
|
|
27
27
|
all: false,
|
|
28
|
+
yes: false,
|
|
28
29
|
printCreated: false,
|
|
29
30
|
cleanup: false,
|
|
30
31
|
version: false,
|
|
@@ -80,6 +81,10 @@ export function parseArgs(argv) {
|
|
|
80
81
|
case "--all":
|
|
81
82
|
flags.all = true;
|
|
82
83
|
break;
|
|
84
|
+
case "--yes":
|
|
85
|
+
case "-y":
|
|
86
|
+
flags.yes = true;
|
|
87
|
+
break;
|
|
83
88
|
case "--print-created":
|
|
84
89
|
case "--report-effects":
|
|
85
90
|
flags.printCreated = true;
|
package/dist/args.test.js
CHANGED
|
@@ -63,6 +63,14 @@ describe("parseArgs", () => {
|
|
|
63
63
|
expect(parseArgs(["app", "workflow", "run", "wf"]).flags.cleanup).toBe(false);
|
|
64
64
|
expect(parseArgs(["app", "workflow", "run", "wf"]).flags.printCreated).toBe(false);
|
|
65
65
|
});
|
|
66
|
+
it("parses --yes and -y as the same boolean confirmation flag (default false)", () => {
|
|
67
|
+
expect(parseArgs(["workspace", "delete", "wsp_1", "--yes"]).flags.yes).toBe(true);
|
|
68
|
+
expect(parseArgs(["workspace", "delete", "wsp_1", "-y"]).flags.yes).toBe(true);
|
|
69
|
+
const r = parseArgs(["workspace", "delete", "wsp_1"]);
|
|
70
|
+
expect(r.flags.yes).toBe(false);
|
|
71
|
+
// The boolean flag does not consume the id positional.
|
|
72
|
+
expect(parseArgs(["workspace", "delete", "wsp_1", "--yes"]).toolArgs).toBe("wsp_1");
|
|
73
|
+
});
|
|
66
74
|
it("treats `org use <name>` as command / subcommand / positional", () => {
|
|
67
75
|
const r = parseArgs(["org", "use", "Acme Corp"]);
|
|
68
76
|
expect(r.command).toBe("org");
|
package/dist/cli.js
CHANGED
|
@@ -60,6 +60,7 @@ COMMANDS
|
|
|
60
60
|
lotics workspace List workspaces in the active org (marks current)
|
|
61
61
|
lotics workspace select <id> Switch to a different workspace
|
|
62
62
|
lotics workspace create <name> Create a new workspace (admin only)
|
|
63
|
+
lotics workspace delete <id> --yes Delete a workspace (admin only; soft delete, recoverable)
|
|
63
64
|
lotics tools List all available tools
|
|
64
65
|
lotics tools <name> Show tool description and input schema
|
|
65
66
|
lotics run <tool> '<json>' Execute a tool
|
|
@@ -688,10 +689,41 @@ async function main() {
|
|
|
688
689
|
}
|
|
689
690
|
return;
|
|
690
691
|
}
|
|
692
|
+
if (subcommand === "delete") {
|
|
693
|
+
const targetId = toolArgs;
|
|
694
|
+
if (!targetId) {
|
|
695
|
+
console.error('Usage: lotics workspace delete <workspace_id> --yes');
|
|
696
|
+
process.exit(1);
|
|
697
|
+
}
|
|
698
|
+
const target = workspaces.find((ws) => ws.id === targetId);
|
|
699
|
+
if (!target) {
|
|
700
|
+
console.error(`Workspace not found: ${targetId}\n\nAvailable workspaces:`);
|
|
701
|
+
printWorkspaceList(workspaces, currentWorkspaceId);
|
|
702
|
+
process.exit(1);
|
|
703
|
+
}
|
|
704
|
+
// Destructive + irreversible-looking to the user — require an explicit
|
|
705
|
+
// confirmation (this CLI is used non-interactively by agents and scripts).
|
|
706
|
+
if (!flags.yes) {
|
|
707
|
+
console.error(`This deletes workspace "${target.name}" (${target.id}) — every table, app, record, and template inside it becomes inaccessible (soft delete: retained and recoverable by an admin).`);
|
|
708
|
+
console.error(`Re-run with --yes to confirm: lotics workspace delete ${target.id} --yes`);
|
|
709
|
+
process.exit(1);
|
|
710
|
+
}
|
|
711
|
+
const deleted = await client.deleteWorkspace(target.id);
|
|
712
|
+
if (flags.json) {
|
|
713
|
+
console.log(JSON.stringify(deleted, null, 2));
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
console.error(`Deleted workspace: ${target.name} (${target.id})`);
|
|
717
|
+
if (currentWorkspaceId === target.id) {
|
|
718
|
+
console.error('This was your selected workspace — select another with "lotics workspace select <id>".');
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
691
723
|
// Default: list workspaces
|
|
692
724
|
if (subcommand && subcommand !== "list") {
|
|
693
725
|
console.error(`Unknown workspace subcommand: ${subcommand}`);
|
|
694
|
-
console.error('Usage: lotics workspace [list | select <id> | create <name>]');
|
|
726
|
+
console.error('Usage: lotics workspace [list | select <id> | create <name> | delete <id> --yes]');
|
|
695
727
|
process.exit(1);
|
|
696
728
|
}
|
|
697
729
|
if (flags.json) {
|
package/dist/client.d.ts
CHANGED
package/dist/client.js
CHANGED
|
@@ -142,6 +142,9 @@ export class LoticsClient {
|
|
|
142
142
|
async createWorkspace(body) {
|
|
143
143
|
return this.request("POST", "/v1/workspaces", body);
|
|
144
144
|
}
|
|
145
|
+
async deleteWorkspace(id) {
|
|
146
|
+
return this.request("DELETE", `/v1/workspaces/${encodeURIComponent(id)}`);
|
|
147
|
+
}
|
|
145
148
|
async login() {
|
|
146
149
|
return this.request("POST", "/v1/cli/login");
|
|
147
150
|
}
|
package/dist/src/cli.js
CHANGED
|
@@ -29704,6 +29704,9 @@ var LoticsClient = class {
|
|
|
29704
29704
|
async createWorkspace(body) {
|
|
29705
29705
|
return this.request("POST", "/v1/workspaces", body);
|
|
29706
29706
|
}
|
|
29707
|
+
async deleteWorkspace(id) {
|
|
29708
|
+
return this.request("DELETE", `/v1/workspaces/${encodeURIComponent(id)}`);
|
|
29709
|
+
}
|
|
29707
29710
|
async login() {
|
|
29708
29711
|
return this.request("POST", "/v1/cli/login");
|
|
29709
29712
|
}
|
|
@@ -30395,18 +30398,16 @@ function buildStarterTemplate(args) {
|
|
|
30395
30398
|
},
|
|
30396
30399
|
dependencies: {
|
|
30397
30400
|
"@lotics/app-sdk": sdkVersion,
|
|
30398
|
-
//
|
|
30399
|
-
//
|
|
30400
|
-
//
|
|
30401
|
-
|
|
30401
|
+
// The FilePreview engines (pdfjs-dist / @lotics/docx / @lotics/xlsx) are
|
|
30402
|
+
// NOT listed here: they ship as @lotics/ui dependencies (7.14.0+), so
|
|
30403
|
+
// every app gets them transitively — one version source, no skew. An app
|
|
30404
|
+
// that IMPORTS @lotics/docx or @lotics/xlsx directly (its own doc/excel
|
|
30405
|
+
// builders) declares its own dependency then.
|
|
30402
30406
|
"@lotics/ui": uiVersion,
|
|
30403
|
-
"@lotics/xlsx": "^0.1.0",
|
|
30404
30407
|
"@react-native-picker/picker": "^2.7.0",
|
|
30405
30408
|
"expo-image": "~3.0.9",
|
|
30406
30409
|
"lucide-react": "^0.562.0",
|
|
30407
30410
|
"lucide-react-native": "^0.562.0",
|
|
30408
|
-
// PDF preview engine for FilePreview/FileGalleryModal — also lazy-loaded.
|
|
30409
|
-
"pdfjs-dist": "^6.0.0",
|
|
30410
30411
|
react: "^19.0.0",
|
|
30411
30412
|
"react-dom": "^19.0.0",
|
|
30412
30413
|
"react-native": STARTER_REACT_NATIVE_VERSION,
|
|
@@ -30640,10 +30641,18 @@ export default defineConfig({
|
|
|
30640
30641
|
// the hooks dispatcher the instant a hook (useAgentRun / useQuery)
|
|
30641
30642
|
// runs in a rendered App tree.
|
|
30642
30643
|
"@lotics/app-sdk",
|
|
30644
|
+
// The /router subpath is a SEPARATE optimizer entry \u2014 without it,
|
|
30645
|
+
// AppRouter's BrowserRouter bundles apart from the app's
|
|
30646
|
+
// react-router hooks and the Router context never matches
|
|
30647
|
+
// ("useNavigate() may be used only in the context of a <Router>").
|
|
30648
|
+
"@lotics/app-sdk/router",
|
|
30643
30649
|
// react-router-dom (App's router) also ships compiled dist JS \u2014 pin it
|
|
30644
30650
|
// into the shared chunk so its hooks don't split the react instance
|
|
30645
30651
|
// ("Invalid hook call") when a test renders the routed App tree.
|
|
30646
30652
|
"react-router-dom",
|
|
30653
|
+
// v7: react-router-dom is a thin wrapper \u2014 the actual context
|
|
30654
|
+
// lives in react-router; both must ride the shared chunk.
|
|
30655
|
+
"react-router",
|
|
30647
30656
|
],
|
|
30648
30657
|
esbuildOptions: {
|
|
30649
30658
|
resolveExtensions: [".web.tsx", ".web.ts", ".web.js", ".tsx", ".ts", ".jsx", ".js", ".json"],
|
|
@@ -33166,6 +33175,7 @@ function parseArgs(argv) {
|
|
|
33166
33175
|
message: void 0,
|
|
33167
33176
|
local: false,
|
|
33168
33177
|
all: false,
|
|
33178
|
+
yes: false,
|
|
33169
33179
|
printCreated: false,
|
|
33170
33180
|
cleanup: false,
|
|
33171
33181
|
version: false,
|
|
@@ -33221,6 +33231,10 @@ function parseArgs(argv) {
|
|
|
33221
33231
|
case "--all":
|
|
33222
33232
|
flags.all = true;
|
|
33223
33233
|
break;
|
|
33234
|
+
case "--yes":
|
|
33235
|
+
case "-y":
|
|
33236
|
+
flags.yes = true;
|
|
33237
|
+
break;
|
|
33224
33238
|
case "--print-created":
|
|
33225
33239
|
case "--report-effects":
|
|
33226
33240
|
flags.printCreated = true;
|
|
@@ -49683,6 +49697,7 @@ COMMANDS
|
|
|
49683
49697
|
lotics workspace List workspaces in the active org (marks current)
|
|
49684
49698
|
lotics workspace select <id> Switch to a different workspace
|
|
49685
49699
|
lotics workspace create <name> Create a new workspace (admin only)
|
|
49700
|
+
lotics workspace delete <id> --yes Delete a workspace (admin only; soft delete, recoverable)
|
|
49686
49701
|
lotics tools List all available tools
|
|
49687
49702
|
lotics tools <name> Show tool description and input schema
|
|
49688
49703
|
lotics run <tool> '<json>' Execute a tool
|
|
@@ -50263,9 +50278,39 @@ Available workspaces:`);
|
|
|
50263
50278
|
}
|
|
50264
50279
|
return;
|
|
50265
50280
|
}
|
|
50281
|
+
if (subcommand === "delete") {
|
|
50282
|
+
const targetId = toolArgs;
|
|
50283
|
+
if (!targetId) {
|
|
50284
|
+
console.error("Usage: lotics workspace delete <workspace_id> --yes");
|
|
50285
|
+
process.exit(1);
|
|
50286
|
+
}
|
|
50287
|
+
const target = workspaces.find((ws) => ws.id === targetId);
|
|
50288
|
+
if (!target) {
|
|
50289
|
+
console.error(`Workspace not found: ${targetId}
|
|
50290
|
+
|
|
50291
|
+
Available workspaces:`);
|
|
50292
|
+
printWorkspaceList(workspaces, currentWorkspaceId);
|
|
50293
|
+
process.exit(1);
|
|
50294
|
+
}
|
|
50295
|
+
if (!flags.yes) {
|
|
50296
|
+
console.error(`This deletes workspace "${target.name}" (${target.id}) \u2014 every table, app, record, and template inside it becomes inaccessible (soft delete: retained and recoverable by an admin).`);
|
|
50297
|
+
console.error(`Re-run with --yes to confirm: lotics workspace delete ${target.id} --yes`);
|
|
50298
|
+
process.exit(1);
|
|
50299
|
+
}
|
|
50300
|
+
const deleted = await client.deleteWorkspace(target.id);
|
|
50301
|
+
if (flags.json) {
|
|
50302
|
+
console.log(JSON.stringify(deleted, null, 2));
|
|
50303
|
+
} else {
|
|
50304
|
+
console.error(`Deleted workspace: ${target.name} (${target.id})`);
|
|
50305
|
+
if (currentWorkspaceId === target.id) {
|
|
50306
|
+
console.error('This was your selected workspace \u2014 select another with "lotics workspace select <id>".');
|
|
50307
|
+
}
|
|
50308
|
+
}
|
|
50309
|
+
return;
|
|
50310
|
+
}
|
|
50266
50311
|
if (subcommand && subcommand !== "list") {
|
|
50267
50312
|
console.error(`Unknown workspace subcommand: ${subcommand}`);
|
|
50268
|
-
console.error("Usage: lotics workspace [list | select <id> | create <name>]");
|
|
50313
|
+
console.error("Usage: lotics workspace [list | select <id> | create <name> | delete <id> --yes]");
|
|
50269
50314
|
process.exit(1);
|
|
50270
50315
|
}
|
|
50271
50316
|
if (flags.json) {
|
package/dist/starter_template.js
CHANGED
|
@@ -80,18 +80,16 @@ export function buildStarterTemplate(args) {
|
|
|
80
80
|
},
|
|
81
81
|
dependencies: {
|
|
82
82
|
"@lotics/app-sdk": sdkVersion,
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
|
|
83
|
+
// The FilePreview engines (pdfjs-dist / @lotics/docx / @lotics/xlsx) are
|
|
84
|
+
// NOT listed here: they ship as @lotics/ui dependencies (7.14.0+), so
|
|
85
|
+
// every app gets them transitively — one version source, no skew. An app
|
|
86
|
+
// that IMPORTS @lotics/docx or @lotics/xlsx directly (its own doc/excel
|
|
87
|
+
// builders) declares its own dependency then.
|
|
87
88
|
"@lotics/ui": uiVersion,
|
|
88
|
-
"@lotics/xlsx": "^0.1.0",
|
|
89
89
|
"@react-native-picker/picker": "^2.7.0",
|
|
90
90
|
"expo-image": "~3.0.9",
|
|
91
91
|
"lucide-react": "^0.562.0",
|
|
92
92
|
"lucide-react-native": "^0.562.0",
|
|
93
|
-
// PDF preview engine for FilePreview/FileGalleryModal — also lazy-loaded.
|
|
94
|
-
"pdfjs-dist": "^6.0.0",
|
|
95
93
|
react: "^19.0.0",
|
|
96
94
|
"react-dom": "^19.0.0",
|
|
97
95
|
"react-native": STARTER_REACT_NATIVE_VERSION,
|
|
@@ -318,10 +316,18 @@ export default defineConfig({
|
|
|
318
316
|
// the hooks dispatcher the instant a hook (useAgentRun / useQuery)
|
|
319
317
|
// runs in a rendered App tree.
|
|
320
318
|
"@lotics/app-sdk",
|
|
319
|
+
// The /router subpath is a SEPARATE optimizer entry — without it,
|
|
320
|
+
// AppRouter's BrowserRouter bundles apart from the app's
|
|
321
|
+
// react-router hooks and the Router context never matches
|
|
322
|
+
// ("useNavigate() may be used only in the context of a <Router>").
|
|
323
|
+
"@lotics/app-sdk/router",
|
|
321
324
|
// react-router-dom (App's router) also ships compiled dist JS — pin it
|
|
322
325
|
// into the shared chunk so its hooks don't split the react instance
|
|
323
326
|
// ("Invalid hook call") when a test renders the routed App tree.
|
|
324
327
|
"react-router-dom",
|
|
328
|
+
// v7: react-router-dom is a thin wrapper — the actual context
|
|
329
|
+
// lives in react-router; both must ride the shared chunk.
|
|
330
|
+
"react-router",
|
|
325
331
|
],
|
|
326
332
|
esbuildOptions: {
|
|
327
333
|
resolveExtensions: [".web.tsx", ".web.ts", ".web.js", ".tsx", ".ts", ".jsx", ".js", ".json"],
|