@lotics/cli 0.75.0 → 0.76.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 +5 -0
- package/dist/app_commands.d.ts +16 -0
- package/dist/app_commands.js +1 -1
- package/dist/args.d.ts +8 -0
- package/dist/args.js +26 -0
- package/dist/cli.js +68 -14
- package/dist/cli_dispatch.test.d.ts +1 -0
- package/dist/cli_dispatch.test.js +90 -0
- package/dist/client.d.ts +63 -0
- package/dist/client.js +33 -0
- package/dist/package_commands.d.ts +37 -0
- package/dist/package_commands.js +182 -6
- package/dist/src/cli.js +636 -19
- package/dist/starter_template.d.ts +19 -0
- package/dist/starter_template.js +389 -0
- package/dist/starter_template.test.js +69 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,7 +210,12 @@ lotics package sync --workspace wsp_dev # migrate the dev installation only
|
|
|
210
210
|
lotics package reset --workspace wsp_dev # DEV-ONLY: drop scaffolded tables, re-scaffold clean
|
|
211
211
|
|
|
212
212
|
# Operate installations (workspace admin)
|
|
213
|
+
lotics package show apg_... # registry metadata + version history (trust badge, channel, yank)
|
|
213
214
|
lotics package install apg_... --version 2 # scaffold + materialize + deploy + pin
|
|
215
|
+
lotics package install apg_... --config heading="Ops board" # per-knob overrides over contract defaults
|
|
216
|
+
lotics package config app_... --set show_done=false # edit a live installation's config (partial merge)
|
|
217
|
+
lotics package uninstall app_... [--archive-tables] # remove an installation; workflows stop firing
|
|
218
|
+
lotics package retire apg_... [--undo] # owner-org: refuse NEW installs (existing keep working + upgrading)
|
|
214
219
|
lotics package doctor app_... # version pin vs latest + drift + local edits (exit 1 on findings)
|
|
215
220
|
lotics package rebind-role app_... <alias> <grp_id> # re-point a package role at another group (re-materializes)
|
|
216
221
|
lotics package upgrade app_... # preview, then apply (additive; overlay preserved)
|
package/dist/app_commands.d.ts
CHANGED
|
@@ -117,6 +117,22 @@ export declare function runNpm(args: string[], cwd: string): Promise<void>;
|
|
|
117
117
|
* the author fixes the config.
|
|
118
118
|
*/
|
|
119
119
|
export declare function ensureAppTsconfig(projectDir: string): void;
|
|
120
|
+
/**
|
|
121
|
+
* Write the three `.lotics/app_{workflows,queries,agents}.d.ts` companions from
|
|
122
|
+
* the manifest's maps, then heal the app's tsconfig so they actually load. Called
|
|
123
|
+
* from `app create / pull / dev / deploy / codegen`, so the augmented `AppWorkflows`
|
|
124
|
+
* / `AppQueries` / `AppAgents` types stay in sync with the manifest.
|
|
125
|
+
*
|
|
126
|
+
* The heal is at the write boundary on purpose: a `.d.ts` written but not loaded is
|
|
127
|
+
* useless (a bare `.lotics` include is skipped by TypeScript's include-glob walk and
|
|
128
|
+
* loads zero of them), so `ensureAppTsconfig` couples "wrote the types" with "the
|
|
129
|
+
* program can see them" — no caller can do one without the other.
|
|
130
|
+
*/
|
|
131
|
+
export declare function writeAppDts(projectDir: string, manifest: {
|
|
132
|
+
workflows?: Record<string, AppWorkflowDeclaration>;
|
|
133
|
+
queries?: Record<string, AppQueryDeclaration>;
|
|
134
|
+
agents?: Record<string, AppAgentDeclaration>;
|
|
135
|
+
}): string[];
|
|
120
136
|
/**
|
|
121
137
|
* `lotics app codegen [path]` — regenerate every `.lotics/` artifact from the
|
|
122
138
|
* manifest + workspace schema, WITHOUT a deploy. The `.d.ts` companions are
|
package/dist/app_commands.js
CHANGED
|
@@ -386,7 +386,7 @@ export function ensureAppTsconfig(projectDir) {
|
|
|
386
386
|
* loads zero of them), so `ensureAppTsconfig` couples "wrote the types" with "the
|
|
387
387
|
* program can see them" — no caller can do one without the other.
|
|
388
388
|
*/
|
|
389
|
-
function writeAppDts(projectDir, manifest) {
|
|
389
|
+
export function writeAppDts(projectDir, manifest) {
|
|
390
390
|
const dotLotics = path.join(projectDir, ".lotics");
|
|
391
391
|
fs.mkdirSync(dotLotics, { recursive: true });
|
|
392
392
|
const written = [
|
package/dist/args.d.ts
CHANGED
|
@@ -53,6 +53,14 @@ export declare function parseArgs(argv: string[]): {
|
|
|
53
53
|
* `keep`.
|
|
54
54
|
*/
|
|
55
55
|
resolve: string[];
|
|
56
|
+
/** `--config key=value` (repeatable): per-knob config overrides at `package install`. */
|
|
57
|
+
config: string[];
|
|
58
|
+
/** `--set key=value` (repeatable): per-knob config edits at `package config`. */
|
|
59
|
+
set: string[];
|
|
60
|
+
/** `--archive-tables`: also archive the scaffolded tables at `package uninstall`. */
|
|
61
|
+
archiveTables: boolean;
|
|
62
|
+
/** `--undo`: reverse a `package retire` / `package yank`. */
|
|
63
|
+
undo: boolean;
|
|
56
64
|
version: boolean;
|
|
57
65
|
help: boolean;
|
|
58
66
|
};
|
package/dist/args.js
CHANGED
|
@@ -31,6 +31,10 @@ export function parseArgs(argv) {
|
|
|
31
31
|
cleanup: false,
|
|
32
32
|
packageVersion: undefined,
|
|
33
33
|
resolve: [],
|
|
34
|
+
config: [],
|
|
35
|
+
set: [],
|
|
36
|
+
archiveTables: false,
|
|
37
|
+
undo: false,
|
|
34
38
|
version: false,
|
|
35
39
|
help: false,
|
|
36
40
|
};
|
|
@@ -106,6 +110,28 @@ export function parseArgs(argv) {
|
|
|
106
110
|
flags.resolve.push(value);
|
|
107
111
|
break;
|
|
108
112
|
}
|
|
113
|
+
case "--config": {
|
|
114
|
+
const value = argv[++i];
|
|
115
|
+
if (value === undefined || value.startsWith("-")) {
|
|
116
|
+
throw new Error("--config requires a value: key=value (repeatable).");
|
|
117
|
+
}
|
|
118
|
+
flags.config.push(value);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case "--set": {
|
|
122
|
+
const value = argv[++i];
|
|
123
|
+
if (value === undefined || value.startsWith("-")) {
|
|
124
|
+
throw new Error("--set requires a value: key=value (repeatable).");
|
|
125
|
+
}
|
|
126
|
+
flags.set.push(value);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case "--archive-tables":
|
|
130
|
+
flags.archiveTables = true;
|
|
131
|
+
break;
|
|
132
|
+
case "--undo":
|
|
133
|
+
flags.undo = true;
|
|
134
|
+
break;
|
|
109
135
|
case "--version":
|
|
110
136
|
case "-v": {
|
|
111
137
|
// Inside a `package` command, `--version` carries a value (the
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import { LoticsClient, API_BASE_URL } from "./client.js";
|
|
|
14
14
|
import { resolveContext, deleteConfig, getConfigPath, loadGlobalConfig, saveGlobalConfig, loadLocalConfig, upsertProfile, removeProfile, setActiveOrg, setSelectedWorkspace, resolveProfileByNameOrId, checkForUpdate, } from "./config.js";
|
|
15
15
|
import { VERSION } from "./version.js";
|
|
16
16
|
import { appCreate, appPull, appDeploy, appDev, appSetSubdomain, appRename, appVersions, appCodegen, appExecuteWorkflow, appWorkflowSet, appWorkflowPull, appWorkflowCheck, appQuerySet, appUiLink, } from "./app_commands.js";
|
|
17
|
-
import { packageInstall, packageEject, packageDoctor, packageUpgrade, parseResolveFlags, packageNew, packageBuild, packagePublish, packageDev, packageSync, packageReset, packageExtract, packageAdopt, packageFleetUpgrade, packageYank, } from "./package_commands.js";
|
|
17
|
+
import { packageInstall, packageUninstall, packageConfig, packageRetire, packageShow, parseInstallConfigFlags, packageEject, packageDoctor, packageUpgrade, parseResolveFlags, packageNew, packageBuild, packagePublish, packageDev, packageSync, packageReset, packageExtract, packageAdopt, packageFleetUpgrade, packageYank, } from "./package_commands.js";
|
|
18
18
|
import { parseArgs } from "./args.js";
|
|
19
19
|
import { ingestJsonArgs } from "./inputs.js";
|
|
20
20
|
import { runXlsxCommand } from "./xlsx.js";
|
|
@@ -103,9 +103,18 @@ COMMANDS
|
|
|
103
103
|
dev server (--workspace <dev_ws> selects it)
|
|
104
104
|
lotics package sync [path] Re-sync (additive migrate + materialize) into a dev ws
|
|
105
105
|
lotics package reset [path] DEV-ONLY: drop scaffolded tables + re-scaffold clean
|
|
106
|
-
lotics package install <package> [--version N]
|
|
106
|
+
lotics package install <package> [--version N] [--config key=value ...]
|
|
107
107
|
Install an app package into this workspace
|
|
108
108
|
(scaffolds the data model + deploys + materializes)
|
|
109
|
+
lotics package uninstall <app_id> [--archive-tables]
|
|
110
|
+
Remove an installation (archives artifacts; with the
|
|
111
|
+
flag also archives the scaffolded tables it created)
|
|
112
|
+
lotics package config <app_id> [--set key=value ...]
|
|
113
|
+
Show or edit an installation's config knobs
|
|
114
|
+
lotics package show <package_id> Registry metadata + version history
|
|
115
|
+
lotics package retire <package_id> [--undo]
|
|
116
|
+
Retire a package (refuse new installs, hide from other
|
|
117
|
+
orgs); existing installations keep working + upgrade
|
|
109
118
|
lotics package upgrade <app_id> [--version N] [--resolve <key>=recreate|revert|keep|<id> ...]
|
|
110
119
|
Preview-then-apply a package upgrade; refuses while
|
|
111
120
|
any drift/modified finding lacks a --resolve, and
|
|
@@ -700,7 +709,11 @@ async function main() {
|
|
|
700
709
|
console.error(" lotics package dev [path] [--workspace <ws>] Sync into a dev workspace + run the app dev server");
|
|
701
710
|
console.error(" lotics package sync [path] [--workspace <ws>] Re-sync (additive migrate + materialize) into a dev workspace");
|
|
702
711
|
console.error(" lotics package reset [path] [--workspace <ws>] DEV-ONLY: drop scaffolded tables + re-scaffold clean");
|
|
703
|
-
console.error(" lotics package install <package> [--version N] Install a package into this workspace");
|
|
712
|
+
console.error(" lotics package install <package> [--version N] [--config key=value ...] Install a package into this workspace");
|
|
713
|
+
console.error(" lotics package uninstall <app_id> [--archive-tables] Remove an installation (opt-in table archival)");
|
|
714
|
+
console.error(" lotics package config <app_id> [--set key=value ...] Show or edit an installation's config knobs");
|
|
715
|
+
console.error(" lotics package show <package_id> Registry metadata + version history (channel, yank, changelog)");
|
|
716
|
+
console.error(" lotics package retire <package_id> [--undo] Retire a package (refuse new installs; installs keep working)");
|
|
704
717
|
console.error(" lotics package upgrade <app_id> [--version N] [--resolve ns.alias=recreate|<id>] Preview + apply an upgrade");
|
|
705
718
|
console.error(" lotics package doctor [app_id] Health: version pin vs latest + binding drift");
|
|
706
719
|
console.error(" lotics package rebind-role <app_id> <alias> <grp_id> Re-point a package role at another group");
|
|
@@ -738,16 +751,6 @@ async function main() {
|
|
|
738
751
|
const { client, ctx } = requireClient(flags);
|
|
739
752
|
// lotics workspace / lotics workspace list / lotics workspace select <id>
|
|
740
753
|
if (command === "workspace") {
|
|
741
|
-
if (subcommand === "yank") {
|
|
742
|
-
const [packageId, versionRaw, maybeUndo] = toolArgs ? toolArgs.split(/\s+/) : [];
|
|
743
|
-
const version = Number(versionRaw);
|
|
744
|
-
if (!packageId || !Number.isInteger(version) || version <= 0) {
|
|
745
|
-
console.error("Usage: lotics package yank <package_id> <version> [--undo]");
|
|
746
|
-
process.exit(1);
|
|
747
|
-
}
|
|
748
|
-
await packageYank(client, { package_id: packageId, version, undo: maybeUndo === "--undo" });
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
754
|
if (subcommand === "doctor") {
|
|
752
755
|
// The workspace command family runs before the global workspace
|
|
753
756
|
// resolution — doctor needs the same first-workspace fallback every
|
|
@@ -881,7 +884,48 @@ async function main() {
|
|
|
881
884
|
process.exit(1);
|
|
882
885
|
}
|
|
883
886
|
}
|
|
884
|
-
|
|
887
|
+
const config = flags.config.length > 0 ? parseInstallConfigFlags(flags.config) : undefined;
|
|
888
|
+
await packageInstall(client, {
|
|
889
|
+
package_id: packageId,
|
|
890
|
+
version,
|
|
891
|
+
...(config !== undefined ? { config } : {}),
|
|
892
|
+
});
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
if (subcommand === "uninstall") {
|
|
896
|
+
const appId = toolArgs;
|
|
897
|
+
if (!appId) {
|
|
898
|
+
console.error("Usage: lotics package uninstall <app_id> [--archive-tables]");
|
|
899
|
+
process.exit(1);
|
|
900
|
+
}
|
|
901
|
+
await packageUninstall(client, { app_id: appId, archive_tables: flags.archiveTables });
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (subcommand === "config") {
|
|
905
|
+
const appId = toolArgs;
|
|
906
|
+
if (!appId) {
|
|
907
|
+
console.error("Usage: lotics package config <app_id> [--set key=value ...]");
|
|
908
|
+
process.exit(1);
|
|
909
|
+
}
|
|
910
|
+
await packageConfig(client, { app_id: appId, sets: flags.set });
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (subcommand === "retire") {
|
|
914
|
+
const packageId = toolArgs;
|
|
915
|
+
if (!packageId) {
|
|
916
|
+
console.error("Usage: lotics package retire <package_id> [--undo]");
|
|
917
|
+
process.exit(1);
|
|
918
|
+
}
|
|
919
|
+
await packageRetire(client, { package_id: packageId, undo: flags.undo });
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
if (subcommand === "show") {
|
|
923
|
+
const packageId = toolArgs;
|
|
924
|
+
if (!packageId) {
|
|
925
|
+
console.error("Usage: lotics package show <package_id>");
|
|
926
|
+
process.exit(1);
|
|
927
|
+
}
|
|
928
|
+
await packageShow(client, { package_id: packageId });
|
|
885
929
|
return;
|
|
886
930
|
}
|
|
887
931
|
if (subcommand === "eject") {
|
|
@@ -921,6 +965,16 @@ async function main() {
|
|
|
921
965
|
await packageAdopt(client, { app_id: appId, version, projectDir: restArgs[0] });
|
|
922
966
|
return;
|
|
923
967
|
}
|
|
968
|
+
if (subcommand === "yank") {
|
|
969
|
+
const packageId = toolArgs;
|
|
970
|
+
const version = Number(restArgs[0]);
|
|
971
|
+
if (!packageId || !Number.isInteger(version) || version <= 0) {
|
|
972
|
+
console.error("Usage: lotics package yank <package_id> <version> [--undo]");
|
|
973
|
+
process.exit(1);
|
|
974
|
+
}
|
|
975
|
+
await packageYank(client, { package_id: packageId, version, undo: flags.undo });
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
924
978
|
if (subcommand === "fleet-upgrade") {
|
|
925
979
|
const packageId = toolArgs;
|
|
926
980
|
if (!packageId) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch smoke test over the BUILT CLI artifact — every `package` subcommand
|
|
3
|
+
* must route to its own handler, proven by its usage/refusal line appearing on
|
|
4
|
+
* a bare invocation. The dispatch in cli.ts is one hand-rolled argv walk with
|
|
5
|
+
* subcommand names repeated across command families (`doctor` exists in both
|
|
6
|
+
* `workspace` and `package`) and split positional conventions (`toolArgs` +
|
|
7
|
+
* `restArgs`), and nothing else tests it: `package yank` shipped dispatched
|
|
8
|
+
* inside the WORKSPACE family and surfaced only on the first live invocation.
|
|
9
|
+
*
|
|
10
|
+
* The fake API key satisfies `requireClient` (client construction is offline);
|
|
11
|
+
* every asserted path exits before any network call. Spawns run in an empty
|
|
12
|
+
* temp cwd so path-defaulting subcommands fail on the missing project file —
|
|
13
|
+
* which equally proves their dispatch reached the right handler.
|
|
14
|
+
*/
|
|
15
|
+
import { beforeAll, describe, expect, it } from "vitest";
|
|
16
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import os from "node:os";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
22
|
+
const cliBin = path.join(packageRoot, "dist", "src", "cli.js");
|
|
23
|
+
const emptyCwd = fs.mkdtempSync(path.join(os.tmpdir(), "lotics-cli-dispatch-"));
|
|
24
|
+
function runCli(args) {
|
|
25
|
+
const result = spawnSync(process.execPath, [cliBin, ...args], {
|
|
26
|
+
cwd: emptyCwd,
|
|
27
|
+
env: {
|
|
28
|
+
...process.env,
|
|
29
|
+
LOTICS_API_KEY: "ltk_dispatch_smoke_fake_key_never_used_on_wire",
|
|
30
|
+
// A pinned (fake) workspace skips the pre-dispatch auto-resolution,
|
|
31
|
+
// which would otherwise hit the network (`listWorkspaces`) before any
|
|
32
|
+
// usage gate. Nothing below ever reaches the wire.
|
|
33
|
+
LOTICS_WORKSPACE: "wsp_dispatch_smoke_fake",
|
|
34
|
+
LOTICS_ORG: "",
|
|
35
|
+
},
|
|
36
|
+
encoding: "utf-8",
|
|
37
|
+
timeout: 30_000,
|
|
38
|
+
});
|
|
39
|
+
return { status: result.status, stderr: result.stderr ?? "" };
|
|
40
|
+
}
|
|
41
|
+
beforeAll(() => {
|
|
42
|
+
// Bundle the real artifact from src (esbuild only — no tsgo; vitest's
|
|
43
|
+
// transform already type-agnostic). ~1s.
|
|
44
|
+
execFileSync(process.execPath, ["scripts/build_cli.mjs"], { cwd: packageRoot });
|
|
45
|
+
}, 120_000);
|
|
46
|
+
describe("lotics package <subcommand> dispatch", () => {
|
|
47
|
+
// Positional-requiring subcommands: a bare invocation must print the
|
|
48
|
+
// subcommand's OWN usage line — reaching it proves family routing AND that
|
|
49
|
+
// the usage gate fires before any network/filesystem work.
|
|
50
|
+
const usageCases = [
|
|
51
|
+
["install", /Usage: lotics package install/],
|
|
52
|
+
["uninstall", /Usage: lotics package uninstall/],
|
|
53
|
+
["config", /Usage: lotics package config/],
|
|
54
|
+
["retire", /Usage: lotics package retire <package_id>/],
|
|
55
|
+
["show", /Usage: lotics package show <package_id>/],
|
|
56
|
+
["upgrade", /Usage: lotics package upgrade/],
|
|
57
|
+
["yank", /Usage: lotics package yank <package_id> <version>/],
|
|
58
|
+
["rebind-role", /Usage: lotics package rebind-role/],
|
|
59
|
+
["fleet-upgrade", /Usage: lotics package fleet-upgrade/],
|
|
60
|
+
["extract", /Usage: lotics package extract/],
|
|
61
|
+
["adopt", /Usage: lotics package adopt/],
|
|
62
|
+
["new", /Usage: lotics package new/],
|
|
63
|
+
];
|
|
64
|
+
for (const [sub, usage] of usageCases) {
|
|
65
|
+
it(`routes "package ${sub}" to its handler (usage on missing args)`, () => {
|
|
66
|
+
const { status, stderr } = runCli(["package", sub]);
|
|
67
|
+
expect(stderr).toMatch(usage);
|
|
68
|
+
expect(stderr).not.toMatch(/Unknown package subcommand/);
|
|
69
|
+
expect(status).toBe(1);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Path-defaulting subcommands: in an empty cwd they must fail on the missing
|
|
73
|
+
// package project — their handler's message, not the dispatcher's. (`sync`
|
|
74
|
+
// is excluded: it validates the dev workspace over the network BEFORE
|
|
75
|
+
// reading the project, so it can't be smoke-tested offline.)
|
|
76
|
+
const projectCases = ["build", "publish"];
|
|
77
|
+
for (const sub of projectCases) {
|
|
78
|
+
it(`routes "package ${sub}" to its handler (missing project in empty cwd)`, () => {
|
|
79
|
+
const { status, stderr } = runCli(["package", sub]);
|
|
80
|
+
expect(stderr).toMatch(/No package\.json in|not a package project/);
|
|
81
|
+
expect(stderr).not.toMatch(/Unknown package subcommand/);
|
|
82
|
+
expect(status).toBe(1);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
it("still rejects a genuinely unknown subcommand", () => {
|
|
86
|
+
const { status, stderr } = runCli(["package", "frobnicate"]);
|
|
87
|
+
expect(stderr).toMatch(/Unknown package subcommand/);
|
|
88
|
+
expect(status).toBe(1);
|
|
89
|
+
});
|
|
90
|
+
});
|
package/dist/client.d.ts
CHANGED
|
@@ -200,6 +200,16 @@ export declare class LoticsClient {
|
|
|
200
200
|
* through the `context` op for production parity.
|
|
201
201
|
*/
|
|
202
202
|
config?: Record<string, string | number | boolean> | null;
|
|
203
|
+
/** Package registry id this app was installed from; null for a bespoke/ejected app. */
|
|
204
|
+
package_id?: string | null;
|
|
205
|
+
/** The installed package version (upgrade pin); null for a bespoke/ejected app. */
|
|
206
|
+
package_version?: number | null;
|
|
207
|
+
/**
|
|
208
|
+
* Package install join — per-namespace alias→id maps (entities/fields/
|
|
209
|
+
* options/templates/roles) plus the `workflows` artifact registry. Null for
|
|
210
|
+
* a bespoke app. Used to preview what `package uninstall` will archive.
|
|
211
|
+
*/
|
|
212
|
+
binding?: Record<string, Record<string, string>> | null;
|
|
203
213
|
}>;
|
|
204
214
|
createApp(body: {
|
|
205
215
|
name: string;
|
|
@@ -219,6 +229,7 @@ export declare class LoticsClient {
|
|
|
219
229
|
*/
|
|
220
230
|
installAppPackage(package_id: string, body: {
|
|
221
231
|
version?: number;
|
|
232
|
+
config?: Record<string, string | number | boolean>;
|
|
222
233
|
}): Promise<{
|
|
223
234
|
id: string;
|
|
224
235
|
name: string;
|
|
@@ -227,6 +238,43 @@ export declare class LoticsClient {
|
|
|
227
238
|
package_version: number | null;
|
|
228
239
|
current_version_id: string | null;
|
|
229
240
|
}>;
|
|
241
|
+
/**
|
|
242
|
+
* Uninstall a package installation (backs `lotics package uninstall`). Does
|
|
243
|
+
* everything DELETE does plus archives the installation's lifecycle
|
|
244
|
+
* artifacts; with `archive_tables` it also archives the scaffolded entity
|
|
245
|
+
* tables — refused server-side unless this installation created them
|
|
246
|
+
* (provenance) and nothing else references them. Admin-only.
|
|
247
|
+
*/
|
|
248
|
+
uninstallAppPackage(app_id: string, body: {
|
|
249
|
+
archive_tables: boolean;
|
|
250
|
+
}): Promise<{
|
|
251
|
+
id: string;
|
|
252
|
+
uninstalled: boolean;
|
|
253
|
+
archived_table_ids: string[];
|
|
254
|
+
}>;
|
|
255
|
+
/**
|
|
256
|
+
* Partial-merge a package installation's config (backs `lotics package config
|
|
257
|
+
* --set`). Only the provided keys change; validated against the installed
|
|
258
|
+
* contract. Returns the full effective config. Admin-only.
|
|
259
|
+
*/
|
|
260
|
+
updateAppPackageConfig(app_id: string, body: {
|
|
261
|
+
config: Record<string, string | number | boolean>;
|
|
262
|
+
}): Promise<{
|
|
263
|
+
config: Record<string, string | number | boolean>;
|
|
264
|
+
}>;
|
|
265
|
+
/**
|
|
266
|
+
* Retire (or `undo` un-retire) a registry package (backs `lotics package
|
|
267
|
+
* retire`). Retiring refuses NEW installs and hides the package from
|
|
268
|
+
* non-owning orgs; existing installations keep working and may still upgrade.
|
|
269
|
+
* Owner-org admin-only.
|
|
270
|
+
*/
|
|
271
|
+
retireAppPackage(package_id: string, body: {
|
|
272
|
+
undo: boolean;
|
|
273
|
+
}): Promise<{
|
|
274
|
+
id: string;
|
|
275
|
+
name: string;
|
|
276
|
+
retired_at: string | null;
|
|
277
|
+
}>;
|
|
230
278
|
/**
|
|
231
279
|
* Eject an installation from its package — re-deploy the pinned version's
|
|
232
280
|
* source as a workspace-owned app version, then sever the package link
|
|
@@ -346,9 +394,22 @@ export declare class LoticsClient {
|
|
|
346
394
|
description: string | null;
|
|
347
395
|
latest_version: number;
|
|
348
396
|
is_official: boolean;
|
|
397
|
+
retired_at: string | null;
|
|
398
|
+
/** Absent from a pre-deploy server — treat undefined as not-owned (the badge under-claims, never over-claims). */
|
|
399
|
+
owned_by_caller?: boolean;
|
|
349
400
|
created_at: string;
|
|
350
401
|
updated_at: string;
|
|
351
402
|
}>;
|
|
403
|
+
/** Version history newest-first (no contract payloads) — backs `lotics package show`. Admin-only. */
|
|
404
|
+
listAppPackageVersions(package_id: string): Promise<{
|
|
405
|
+
versions: Array<{
|
|
406
|
+
version: number;
|
|
407
|
+
changelog: string | null;
|
|
408
|
+
channel: "release" | "dev";
|
|
409
|
+
yanked_at: string | null;
|
|
410
|
+
created_at: string;
|
|
411
|
+
}>;
|
|
412
|
+
}>;
|
|
352
413
|
/**
|
|
353
414
|
* Publish a new immutable package version — multipart upload of the alias-keyed
|
|
354
415
|
* contract (JSON) + the prebuilt code bundle (a gzipped tarball carrying
|
|
@@ -360,6 +421,8 @@ export declare class LoticsClient {
|
|
|
360
421
|
contract: unknown;
|
|
361
422
|
bundle: Buffer;
|
|
362
423
|
changelog?: string | null;
|
|
424
|
+
/** 'dev' = dev-loop publish: pinned by the dev installation, never the installable latest. */
|
|
425
|
+
channel?: "release" | "dev";
|
|
363
426
|
}): Promise<{
|
|
364
427
|
id: string;
|
|
365
428
|
package_id: string;
|
package/dist/client.js
CHANGED
|
@@ -212,6 +212,33 @@ export class LoticsClient {
|
|
|
212
212
|
async installAppPackage(package_id, body) {
|
|
213
213
|
return this.request("POST", `/v1/app-packages/${encodeURIComponent(package_id)}/installations`, body);
|
|
214
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Uninstall a package installation (backs `lotics package uninstall`). Does
|
|
217
|
+
* everything DELETE does plus archives the installation's lifecycle
|
|
218
|
+
* artifacts; with `archive_tables` it also archives the scaffolded entity
|
|
219
|
+
* tables — refused server-side unless this installation created them
|
|
220
|
+
* (provenance) and nothing else references them. Admin-only.
|
|
221
|
+
*/
|
|
222
|
+
async uninstallAppPackage(app_id, body) {
|
|
223
|
+
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/uninstall`, body);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Partial-merge a package installation's config (backs `lotics package config
|
|
227
|
+
* --set`). Only the provided keys change; validated against the installed
|
|
228
|
+
* contract. Returns the full effective config. Admin-only.
|
|
229
|
+
*/
|
|
230
|
+
async updateAppPackageConfig(app_id, body) {
|
|
231
|
+
return this.request("PATCH", `/v1/apps/${encodeURIComponent(app_id)}/package-config`, body);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Retire (or `undo` un-retire) a registry package (backs `lotics package
|
|
235
|
+
* retire`). Retiring refuses NEW installs and hides the package from
|
|
236
|
+
* non-owning orgs; existing installations keep working and may still upgrade.
|
|
237
|
+
* Owner-org admin-only.
|
|
238
|
+
*/
|
|
239
|
+
async retireAppPackage(package_id, body) {
|
|
240
|
+
return this.request("POST", `/v1/app-packages/${encodeURIComponent(package_id)}/retire`, body);
|
|
241
|
+
}
|
|
215
242
|
/**
|
|
216
243
|
* Eject an installation from its package — re-deploy the pinned version's
|
|
217
244
|
* source as a workspace-owned app version, then sever the package link
|
|
@@ -283,6 +310,10 @@ export class LoticsClient {
|
|
|
283
310
|
async getAppPackage(package_id) {
|
|
284
311
|
return this.request("GET", `/v1/app-packages/${encodeURIComponent(package_id)}`);
|
|
285
312
|
}
|
|
313
|
+
/** Version history newest-first (no contract payloads) — backs `lotics package show`. Admin-only. */
|
|
314
|
+
async listAppPackageVersions(package_id) {
|
|
315
|
+
return this.request("GET", `/v1/app-packages/${encodeURIComponent(package_id)}/versions`);
|
|
316
|
+
}
|
|
286
317
|
/**
|
|
287
318
|
* Publish a new immutable package version — multipart upload of the alias-keyed
|
|
288
319
|
* contract (JSON) + the prebuilt code bundle (a gzipped tarball carrying
|
|
@@ -296,6 +327,8 @@ export class LoticsClient {
|
|
|
296
327
|
formData.append("bundle", new Blob([new Uint8Array(args.bundle)], { type: "application/gzip" }), "bundle.tar.gz");
|
|
297
328
|
if (args.changelog)
|
|
298
329
|
formData.append("changelog", args.changelog);
|
|
330
|
+
if (args.channel)
|
|
331
|
+
formData.append("channel", args.channel);
|
|
299
332
|
const url = `${this.baseUrl}/v1/app-packages/${encodeURIComponent(package_id)}/versions`;
|
|
300
333
|
const response = await fetch(url, {
|
|
301
334
|
method: "POST",
|
|
@@ -176,13 +176,50 @@ export declare function packageUpgrade(client: LoticsClient, args: {
|
|
|
176
176
|
version?: number;
|
|
177
177
|
resolutions: Record<string, UpgradeResolutionValue>;
|
|
178
178
|
}): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* `lotics package show <package_id>` — registry metadata + version history
|
|
181
|
+
* (trust badge, retirement, per-version channel/yank/changelog). The read
|
|
182
|
+
* surface for "what is this package and what shipped when".
|
|
183
|
+
*/
|
|
184
|
+
export declare function packageShow(client: LoticsClient, args: {
|
|
185
|
+
package_id: string;
|
|
186
|
+
}): Promise<void>;
|
|
179
187
|
export declare function packageInstall(client: LoticsClient, args: {
|
|
180
188
|
package_id: string;
|
|
181
189
|
version?: number;
|
|
190
|
+
config?: Record<string, string | number | boolean>;
|
|
182
191
|
}): Promise<void>;
|
|
183
192
|
export declare function packageEject(client: LoticsClient, args: {
|
|
184
193
|
app_id: string;
|
|
185
194
|
}): Promise<void>;
|
|
195
|
+
/** `--config key=value` (install): inferred types, server-validated. */
|
|
196
|
+
export declare function parseInstallConfigFlags(config: string[]): Record<string, string | number | boolean>;
|
|
197
|
+
/**
|
|
198
|
+
* `lotics package config <app_id>` — show the installation's effective config;
|
|
199
|
+
* with `--set key=value` (repeatable) partial-merge edits, each value parsed by
|
|
200
|
+
* the knob's current type. No `--set` prints the values.
|
|
201
|
+
*/
|
|
202
|
+
export declare function packageConfig(client: LoticsClient, args: {
|
|
203
|
+
app_id: string;
|
|
204
|
+
sets: string[];
|
|
205
|
+
}): Promise<void>;
|
|
206
|
+
/**
|
|
207
|
+
* `lotics package uninstall <app_id> [--archive-tables]` — remove a package
|
|
208
|
+
* installation. Prints what will be archived (workflow artifacts, plus the
|
|
209
|
+
* scaffolded tables when the flag is set), then uninstalls.
|
|
210
|
+
*/
|
|
211
|
+
export declare function packageUninstall(client: LoticsClient, args: {
|
|
212
|
+
app_id: string;
|
|
213
|
+
archive_tables: boolean;
|
|
214
|
+
}): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* `lotics package retire <package_id> [--undo]` — retire (or un-retire) a
|
|
217
|
+
* registry package. Owner-org admin-only.
|
|
218
|
+
*/
|
|
219
|
+
export declare function packageRetire(client: LoticsClient, args: {
|
|
220
|
+
package_id: string;
|
|
221
|
+
undo: boolean;
|
|
222
|
+
}): Promise<void>;
|
|
186
223
|
/**
|
|
187
224
|
* `lotics package extract <app_id> [path]` — promote a bespoke app to a DRAFT
|
|
188
225
|
* package project (docs/app_packages.md § Promotion). Calls the extract read,
|