@lotics/cli 0.74.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 +70 -4
- package/dist/cli_dispatch.test.d.ts +1 -0
- package/dist/cli_dispatch.test.js +90 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.js +41 -0
- package/dist/package_commands.d.ts +48 -0
- package/dist/package_commands.js +199 -6
- package/dist/src/cli.js +661 -9
- 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, } 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
|
|
@@ -124,6 +133,7 @@ COMMANDS
|
|
|
124
133
|
origin app (reads .lotics/adopt_binding.json;
|
|
125
134
|
--version N pins a specific version)
|
|
126
135
|
lotics package fleet-upgrade <package_id> [--version N]
|
|
136
|
+
lotics package yank <package_id> <version> [--undo]
|
|
127
137
|
Upgrade EVERY installation of the package across
|
|
128
138
|
your org: applies where the preview is clean,
|
|
129
139
|
skips + reports findings (exit 1 unless all current)
|
|
@@ -699,7 +709,11 @@ async function main() {
|
|
|
699
709
|
console.error(" lotics package dev [path] [--workspace <ws>] Sync into a dev workspace + run the app dev server");
|
|
700
710
|
console.error(" lotics package sync [path] [--workspace <ws>] Re-sync (additive migrate + materialize) into a dev workspace");
|
|
701
711
|
console.error(" lotics package reset [path] [--workspace <ws>] DEV-ONLY: drop scaffolded tables + re-scaffold clean");
|
|
702
|
-
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)");
|
|
703
717
|
console.error(" lotics package upgrade <app_id> [--version N] [--resolve ns.alias=recreate|<id>] Preview + apply an upgrade");
|
|
704
718
|
console.error(" lotics package doctor [app_id] Health: version pin vs latest + binding drift");
|
|
705
719
|
console.error(" lotics package rebind-role <app_id> <alias> <grp_id> Re-point a package role at another group");
|
|
@@ -707,6 +721,7 @@ async function main() {
|
|
|
707
721
|
console.error(" lotics package extract <app_id> [path] Promote a bespoke app to a draft package project");
|
|
708
722
|
console.error(" lotics package adopt <app_id> [path] Bind the published project onto the origin app");
|
|
709
723
|
console.error(" lotics package fleet-upgrade <package_id> [--version N] Upgrade every org installation (clean ones apply; findings skip)");
|
|
724
|
+
console.error(" lotics package yank <package_id> <version> [--undo] Refuse new installs/upgrades of a broken published version (pinned installations keep running)");
|
|
710
725
|
process.exit(1);
|
|
711
726
|
}
|
|
712
727
|
if (command === "run" && !subcommand) {
|
|
@@ -869,7 +884,48 @@ async function main() {
|
|
|
869
884
|
process.exit(1);
|
|
870
885
|
}
|
|
871
886
|
}
|
|
872
|
-
|
|
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 });
|
|
873
929
|
return;
|
|
874
930
|
}
|
|
875
931
|
if (subcommand === "eject") {
|
|
@@ -909,6 +965,16 @@ async function main() {
|
|
|
909
965
|
await packageAdopt(client, { app_id: appId, version, projectDir: restArgs[0] });
|
|
910
966
|
return;
|
|
911
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
|
+
}
|
|
912
978
|
if (subcommand === "fleet-upgrade") {
|
|
913
979
|
const packageId = toolArgs;
|
|
914
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
|
|
@@ -287,6 +335,17 @@ export declare class LoticsClient {
|
|
|
287
335
|
* per-installation consent flow. Backs `lotics package fleet-upgrade`.
|
|
288
336
|
* Admin-only; org-scoped (no workspace header needed).
|
|
289
337
|
*/
|
|
338
|
+
/**
|
|
339
|
+
* Yank / unyank a published package version — refuses NEW installs/upgrades/
|
|
340
|
+
* adopts targeting it; pinned installations keep running. Owner-org
|
|
341
|
+
* admin-only. Backs `lotics package yank`.
|
|
342
|
+
*/
|
|
343
|
+
yankAppPackageVersion(package_id: string, version: number, yanked: boolean): Promise<{
|
|
344
|
+
package_id: string;
|
|
345
|
+
version: number;
|
|
346
|
+
yanked_at: string | null;
|
|
347
|
+
latest_version: number;
|
|
348
|
+
}>;
|
|
290
349
|
fleetUpgradeAppPackage(package_id: string, body: {
|
|
291
350
|
version?: number;
|
|
292
351
|
}): Promise<{
|
|
@@ -335,9 +394,22 @@ export declare class LoticsClient {
|
|
|
335
394
|
description: string | null;
|
|
336
395
|
latest_version: number;
|
|
337
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;
|
|
338
400
|
created_at: string;
|
|
339
401
|
updated_at: string;
|
|
340
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
|
+
}>;
|
|
341
413
|
/**
|
|
342
414
|
* Publish a new immutable package version — multipart upload of the alias-keyed
|
|
343
415
|
* contract (JSON) + the prebuilt code bundle (a gzipped tarball carrying
|
|
@@ -349,6 +421,8 @@ export declare class LoticsClient {
|
|
|
349
421
|
contract: unknown;
|
|
350
422
|
bundle: Buffer;
|
|
351
423
|
changelog?: string | null;
|
|
424
|
+
/** 'dev' = dev-loop publish: pinned by the dev installation, never the installable latest. */
|
|
425
|
+
channel?: "release" | "dev";
|
|
352
426
|
}): Promise<{
|
|
353
427
|
id: string;
|
|
354
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
|
|
@@ -255,6 +282,14 @@ export class LoticsClient {
|
|
|
255
282
|
* per-installation consent flow. Backs `lotics package fleet-upgrade`.
|
|
256
283
|
* Admin-only; org-scoped (no workspace header needed).
|
|
257
284
|
*/
|
|
285
|
+
/**
|
|
286
|
+
* Yank / unyank a published package version — refuses NEW installs/upgrades/
|
|
287
|
+
* adopts targeting it; pinned installations keep running. Owner-org
|
|
288
|
+
* admin-only. Backs `lotics package yank`.
|
|
289
|
+
*/
|
|
290
|
+
async yankAppPackageVersion(package_id, version, yanked) {
|
|
291
|
+
return this.request("POST", `/v1/app-packages/${encodeURIComponent(package_id)}/versions/${version}/yank`, { yanked });
|
|
292
|
+
}
|
|
258
293
|
async fleetUpgradeAppPackage(package_id, body) {
|
|
259
294
|
return this.request("POST", `/v1/app-packages/${encodeURIComponent(package_id)}/fleet-upgrade`, body);
|
|
260
295
|
}
|
|
@@ -275,6 +310,10 @@ export class LoticsClient {
|
|
|
275
310
|
async getAppPackage(package_id) {
|
|
276
311
|
return this.request("GET", `/v1/app-packages/${encodeURIComponent(package_id)}`);
|
|
277
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
|
+
}
|
|
278
317
|
/**
|
|
279
318
|
* Publish a new immutable package version — multipart upload of the alias-keyed
|
|
280
319
|
* contract (JSON) + the prebuilt code bundle (a gzipped tarball carrying
|
|
@@ -288,6 +327,8 @@ export class LoticsClient {
|
|
|
288
327
|
formData.append("bundle", new Blob([new Uint8Array(args.bundle)], { type: "application/gzip" }), "bundle.tar.gz");
|
|
289
328
|
if (args.changelog)
|
|
290
329
|
formData.append("changelog", args.changelog);
|
|
330
|
+
if (args.channel)
|
|
331
|
+
formData.append("channel", args.channel);
|
|
291
332
|
const url = `${this.baseUrl}/v1/app-packages/${encodeURIComponent(package_id)}/versions`;
|
|
292
333
|
const response = await fetch(url, {
|
|
293
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,
|
|
@@ -220,6 +257,17 @@ export declare function packageAdopt(client: LoticsClient, args: {
|
|
|
220
257
|
* installations are reported per line and the process exits 1 so a release
|
|
221
258
|
* script can gate on "fleet fully current".
|
|
222
259
|
*/
|
|
260
|
+
/**
|
|
261
|
+
* `lotics package yank <package_id> <version> [--undo]` — mark a published
|
|
262
|
+
* version uninstallable (or restore it). New installs/upgrades/adopts refuse a
|
|
263
|
+
* yanked version and "latest" skips it; installations already pinned keep
|
|
264
|
+
* running. Owner-org admin-only.
|
|
265
|
+
*/
|
|
266
|
+
export declare function packageYank(client: LoticsClient, args: {
|
|
267
|
+
package_id: string;
|
|
268
|
+
version: number;
|
|
269
|
+
undo: boolean;
|
|
270
|
+
}): Promise<void>;
|
|
223
271
|
export declare function packageFleetUpgrade(client: LoticsClient, args: {
|
|
224
272
|
package_id: string;
|
|
225
273
|
version?: number;
|