@lotics/cli 0.83.0 → 0.86.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 +11 -10
- package/dist/cli.js +39 -28
- package/dist/cli_dispatch.test.js +15 -2
- package/dist/client.d.ts +33 -4
- package/dist/client.js +16 -5
- package/dist/generate_app_workflows_dts.js +11 -2
- package/dist/generate_app_workflows_dts.test.js +3 -3
- package/dist/package_commands.d.ts +36 -34
- package/dist/package_commands.js +143 -44
- package/dist/package_commands.test.js +135 -2
- package/dist/src/cli.js +143 -58
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -227,7 +227,7 @@ lotics package config app_... --set show_done=false # edit a live inst
|
|
|
227
227
|
lotics uninstall app_... [--archive-tables] # remove an installation; workflows stop firing
|
|
228
228
|
lotics package doctor app_... # version pin vs latest + drift + local edits (exit 1 on findings)
|
|
229
229
|
lotics upgrade app_... # preview, then apply (additive; overlay preserved)
|
|
230
|
-
lotics upgrade apg_... # FLEET: upgrade EVERY org installation (clean ones apply; findings skip, exit 1)
|
|
230
|
+
lotics upgrade apg_... # APP package → FLEET: upgrade EVERY org installation (clean ones apply; findings skip, exit 1)
|
|
231
231
|
lotics upgrade app_... --resolve fields.deal.stage=recreate # resolve reported drift
|
|
232
232
|
lotics upgrade app_... --resolve queries.tasks=keep # consent for a local edit (or =revert)
|
|
233
233
|
lotics upgrade app_... --resolve template.quote=revert # a locally-edited template (clean ones auto-update; or =keep)
|
|
@@ -238,7 +238,7 @@ lotics package eject app_... # one-way: sever the package link
|
|
|
238
238
|
lotics workspace doctor # dangling schema references across the workspace (exit 1 on findings)
|
|
239
239
|
```
|
|
240
240
|
|
|
241
|
-
After the first publish **the origin is the master** — develop it in its workspace (`app pull` / `app deploy` / `app workflow set` / table tools), and `lotics app release` snapshots each version. Its **binding-aware re-extract** keeps aliases stable through the origin's current binding, so re-extraction never churns the upgrade diff (which is why extract-again is the loop, not a hazard).
|
|
241
|
+
After the first publish **the origin is the master** — develop it in its workspace (`app pull` / `app deploy` / `app workflow set` / table tools), and `lotics app release` snapshots each version. Its **binding-aware re-extract** keeps aliases stable through the origin's current binding, so re-extraction never churns the upgrade diff (which is why extract-again is the loop, not a hazard). Release is also the **bundled-knowledge declaration surface**: run from the app project, the manifest's `lotics.knowledge` (`[{alias,doc_id}]`) re-declares which docs the package bundles — an alias added ships as a new doc, a bound alias dropped surfaces to consumers as `removed` (archive|keep), a present one re-snapshots; a bare id from elsewhere reconstructs the current corpus from the pin (never drops it). So a published app package evolves its bundled docs across versions without ejecting.
|
|
242
242
|
|
|
243
243
|
### Content packages
|
|
244
244
|
|
|
@@ -257,15 +257,16 @@ lotics run release_content '{"package_id":"apg_...","changelog":"v2: revised SOP
|
|
|
257
257
|
lotics install apg_... # app OR content, shape-branched
|
|
258
258
|
lotics install apg_... --bind-to policy=kdc_... # adopt an existing doc as package-managed
|
|
259
259
|
|
|
260
|
-
# Discover installed content (
|
|
261
|
-
lotics package list-content # id · package · version (standalone content installs)
|
|
260
|
+
# Discover installed content (each row leads with the PACKAGE id)
|
|
261
|
+
lotics package list-content # package id · package · version (standalone content installs)
|
|
262
262
|
|
|
263
|
-
# Refresh
|
|
264
|
-
|
|
265
|
-
lotics upgrade
|
|
266
|
-
lotics upgrade
|
|
267
|
-
lotics upgrade
|
|
268
|
-
lotics
|
|
263
|
+
# Refresh this workspace's content install — addressed by PACKAGE id (one install per
|
|
264
|
+
# package per workspace, so the package id is the address; one gate over docs + templates)
|
|
265
|
+
lotics upgrade apg_... # CONTENT package → preview, then apply (this workspace's install)
|
|
266
|
+
lotics upgrade apg_... --resolve knowledge.policy=apply # a doc: apply|keep|archive|recreate|unbind
|
|
267
|
+
lotics upgrade apg_... --resolve template.quote=revert # a locally-edited template: revert|keep (clean ones auto-update)
|
|
268
|
+
lotics upgrade apg_... --apply-all # accept upstream for every doc + template (OVERWRITES local edits)
|
|
269
|
+
lotics uninstall apg_... --keep-content # remove the pin; keep docs + templates (default archives them)
|
|
269
270
|
```
|
|
270
271
|
|
|
271
272
|
A package's knowledge can also arrive **bundled with an app**. Upgrading such an app (`lotics upgrade <app_id>`) previews its bundled-knowledge changes alongside the plan and resolves them in the SAME namespaced grammar — `--resolve knowledge.<alias>=apply|keep|archive|recreate|unbind` (the flags pass to the server verbatim; no routing, no ambiguity), `--bind-to` consents an added-doc collision, `--apply-all` takes the package's version for every consent-requiring doc.
|
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, packageUninstall, packageListContent, packageConfig, packageShow, parseInstallConfigFlags, packageEject, packageDoctor, packageUpgrade,
|
|
17
|
+
import { packageInstall, packageUninstall, packageListContent, packageConfig, packageShow, parseInstallConfigFlags, packageEject, packageDoctor, packageUpgrade, packageUpgradeByPackageId, redirectContentPciForm, parseBindToFlags, appPublish, appRelease, appUnpublish, 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";
|
|
@@ -114,18 +114,19 @@ COMMANDS
|
|
|
114
114
|
Install a package (app: scaffolds/deploys/materializes,
|
|
115
115
|
--config sets its knobs; content: installs the doc corpus,
|
|
116
116
|
--bind-to consents to adopt a same-named doc on a collision)
|
|
117
|
-
lotics uninstall <app_id|
|
|
117
|
+
lotics uninstall <app_id|package_id> [--archive-tables] [--keep-content]
|
|
118
118
|
Uninstall — dispatched by id. App (app_id): archives
|
|
119
119
|
artifacts (+ --archive-tables also archives scaffolded
|
|
120
|
-
tables). Content (
|
|
121
|
-
unless --keep-content
|
|
122
|
-
lotics upgrade <app_id|
|
|
120
|
+
tables). Content package (apg_): archives its package-bound
|
|
121
|
+
docs unless --keep-content
|
|
122
|
+
lotics upgrade <app_id|package_id> [--version N] [--resolve <key>=... ] [--bind-to ...] [--apply-all]
|
|
123
123
|
Preview-then-apply an upgrade, dispatched by id. App
|
|
124
124
|
(app_id): refuses while any drift/modified/bundled-knowledge
|
|
125
|
-
finding lacks a --resolve.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
finding lacks a --resolve. Package (apg_): a CONTENT package
|
|
126
|
+
upgrades THIS workspace's install (--resolve
|
|
127
|
+
<alias>=apply|keep|archive|recreate|unbind); an APP package
|
|
128
|
+
FLEET-upgrades every installation across your org (clean
|
|
129
|
+
apply, findings skip). --apply-all accepts the package's version
|
|
129
130
|
lotics package doctor [app_id] Installation health: version pin vs latest, binding
|
|
130
131
|
drift, locally modified core, knowledge drift/edits
|
|
131
132
|
(exit 1 on findings)
|
|
@@ -135,7 +136,8 @@ COMMANDS
|
|
|
135
136
|
(re-deploys the pinned source as a bespoke app)
|
|
136
137
|
lotics package show <package_id> Registry metadata + version history
|
|
137
138
|
lotics package list-content List the workspace's content installations
|
|
138
|
-
(standalone content installs) —
|
|
139
|
+
(standalone content installs) — each row leads with
|
|
140
|
+
the package id for upgrade/uninstall
|
|
139
141
|
lotics package yank <package_id> <version> [--undo]
|
|
140
142
|
Refuse new installs/upgrades of a broken published
|
|
141
143
|
version (pinned installations keep running)
|
|
@@ -713,8 +715,8 @@ async function main() {
|
|
|
713
715
|
console.error("Usage (low-traffic consumer / registry ops — author verbs live on `lotics app`):");
|
|
714
716
|
console.error(" The high-traffic consumer verbs are top-level:");
|
|
715
717
|
console.error(" lotics install <package_id> [--version N] [--bind-to <alias>=<kdc_id>] [--config key=value ...] Install a package (app or content)");
|
|
716
|
-
console.error(" lotics uninstall <app_id|
|
|
717
|
-
console.error(" lotics upgrade <app_id|
|
|
718
|
+
console.error(" lotics uninstall <app_id|package_id> [--archive-tables] [--keep-content] Uninstall — dispatched by id (app vs content)");
|
|
719
|
+
console.error(" lotics upgrade <app_id|package_id> [--version N] [--resolve <key>=... ] [--bind-to ...] [--apply-all] Upgrade — app install / content install / whole app fleet (apg_)");
|
|
718
720
|
console.error(" lotics package doctor [app_id] Health: version pin vs latest + binding/knowledge drift");
|
|
719
721
|
console.error(" lotics package config <app_id> [--set key=value ...] Show or edit an installation's config knobs");
|
|
720
722
|
console.error(" lotics package eject <app_id> Sever an installation's package link");
|
|
@@ -902,12 +904,17 @@ async function main() {
|
|
|
902
904
|
if (command === "uninstall") {
|
|
903
905
|
const id = subcommand;
|
|
904
906
|
if (!id) {
|
|
905
|
-
console.error("Usage: lotics uninstall <app_id|
|
|
907
|
+
console.error("Usage: lotics uninstall <app_id|package_id> [--archive-tables] [--keep-content]");
|
|
906
908
|
console.error("Dispatched by id: an app installation (app_id; --archive-tables to also archive its " +
|
|
907
|
-
"scaffolded tables) or a
|
|
909
|
+
"scaffolded tables) or a content package (apg_ id from `lotics install` / " +
|
|
908
910
|
"lotics package list-content; --keep-content to retain its docs).");
|
|
909
911
|
process.exit(1);
|
|
910
912
|
}
|
|
913
|
+
// A `pci_` resource id is retired from human sight — redirect to the package-id form.
|
|
914
|
+
if (id.startsWith("pci_")) {
|
|
915
|
+
await redirectContentPciForm(client, id, "uninstall");
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
911
918
|
await packageUninstall(client, {
|
|
912
919
|
id,
|
|
913
920
|
keep_content: flags.keepContent,
|
|
@@ -918,9 +925,9 @@ async function main() {
|
|
|
918
925
|
if (command === "upgrade") {
|
|
919
926
|
const target = subcommand;
|
|
920
927
|
if (!target) {
|
|
921
|
-
console.error("Usage: lotics upgrade <app_id |
|
|
922
|
-
console.error("Dispatched by id: an app installation (app_id), a
|
|
923
|
-
"
|
|
928
|
+
console.error("Usage: lotics upgrade <app_id | package_id> [--version N] [--resolve <key>=... ...] [--bind-to ...] [--apply-all]");
|
|
929
|
+
console.error("Dispatched by id: an app installation (app_id), or a package id (apg_) — a CONTENT package " +
|
|
930
|
+
"upgrades this workspace's install; an APP package fleet-upgrades every installation across your org.");
|
|
924
931
|
process.exit(1);
|
|
925
932
|
}
|
|
926
933
|
let version;
|
|
@@ -931,22 +938,24 @@ async function main() {
|
|
|
931
938
|
process.exit(1);
|
|
932
939
|
}
|
|
933
940
|
}
|
|
934
|
-
// A
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
await packageFleetUpgrade(client, { package_id: target, version });
|
|
941
|
+
// A `pci_` resource id is retired from human sight — redirect to the package-id form.
|
|
942
|
+
if (target.startsWith("pci_")) {
|
|
943
|
+
await redirectContentPciForm(client, target, "upgrade");
|
|
938
944
|
return;
|
|
939
945
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
946
|
+
// A package id (apg_) is kind-branched: a content package upgrades THIS
|
|
947
|
+
// workspace's install; an app package fleet-upgrades the whole org.
|
|
948
|
+
if (target.startsWith("apg_")) {
|
|
949
|
+
await packageUpgradeByPackageId(client, {
|
|
950
|
+
package_id: target,
|
|
943
951
|
version,
|
|
944
952
|
resolve: flags.resolve,
|
|
945
|
-
|
|
953
|
+
bindTo: flags.bindTo,
|
|
946
954
|
applyAll: flags.applyAll,
|
|
947
955
|
});
|
|
948
956
|
return;
|
|
949
957
|
}
|
|
958
|
+
// Anything else is an app installation (addressed by its app id).
|
|
950
959
|
await packageUpgrade(client, {
|
|
951
960
|
app_id: target,
|
|
952
961
|
version,
|
|
@@ -1019,8 +1028,8 @@ async function main() {
|
|
|
1019
1028
|
// `lotics package <verb>` forms loudly with a redirect, never a silent no-op.
|
|
1020
1029
|
const movedVerbs = {
|
|
1021
1030
|
install: "lotics install <package_id>",
|
|
1022
|
-
uninstall: "lotics uninstall <app_id|
|
|
1023
|
-
upgrade: "lotics upgrade <app_id|
|
|
1031
|
+
uninstall: "lotics uninstall <app_id|package_id>",
|
|
1032
|
+
upgrade: "lotics upgrade <app_id|package_id>",
|
|
1024
1033
|
"fleet-upgrade": "lotics upgrade <package_id>",
|
|
1025
1034
|
};
|
|
1026
1035
|
if (subcommand !== undefined && subcommand in movedVerbs) {
|
|
@@ -1330,8 +1339,10 @@ async function main() {
|
|
|
1330
1339
|
console.log(JSON.stringify({ error: result.error }, null, 2));
|
|
1331
1340
|
}
|
|
1332
1341
|
else {
|
|
1342
|
+
// Execution errors (not-found, refusals) carry the server's message;
|
|
1343
|
+
// the input already passed schema validation, so no schema hint —
|
|
1344
|
+
// validation 400s bring the server's own hint via throwResponseError.
|
|
1333
1345
|
console.error(result.error);
|
|
1334
|
-
console.error(`\nHint: run "lotics tools ${toolName}" to see the expected input schema.`);
|
|
1335
1346
|
}
|
|
1336
1347
|
process.exit(1);
|
|
1337
1348
|
}
|
|
@@ -104,8 +104,8 @@ describe("lotics top-level consumer-verb dispatch", () => {
|
|
|
104
104
|
// bare invocation — reaching it fires before any network work.
|
|
105
105
|
const usageCases = [
|
|
106
106
|
["install", /Usage: lotics install <package_id>/],
|
|
107
|
-
["uninstall", /Usage: lotics uninstall <app_id\|
|
|
108
|
-
["upgrade", /Usage: lotics upgrade <app_id \|
|
|
107
|
+
["uninstall", /Usage: lotics uninstall <app_id\|package_id>/],
|
|
108
|
+
["upgrade", /Usage: lotics upgrade <app_id \| package_id>/],
|
|
109
109
|
];
|
|
110
110
|
for (const [verb, usage] of usageCases) {
|
|
111
111
|
it(`routes top-level "${verb}" to its handler (usage on missing id)`, () => {
|
|
@@ -115,6 +115,19 @@ describe("lotics top-level consumer-verb dispatch", () => {
|
|
|
115
115
|
expect(status).toBe(1);
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
|
+
// CLEAN BREAK: content installs are addressed by their PACKAGE id — an explicit
|
|
119
|
+
// `pci_` resource id must get a loud redirect to the package-id form. The redirect
|
|
120
|
+
// header prints SYNCHRONOUSLY (before the best-effort list-content resolution that
|
|
121
|
+
// spells out the exact command), so it is observable without a live registry; the
|
|
122
|
+
// process exits 1 either way (best-effort resolution fails on the fake key).
|
|
123
|
+
for (const verb of ["upgrade", "uninstall"]) {
|
|
124
|
+
it(`redirects an explicit pci_ id on "${verb}" to the package-id form`, () => {
|
|
125
|
+
const { status, stderr } = runCli([verb, "pci_dispatch_smoke_fake"]);
|
|
126
|
+
expect(stderr).toMatch(/addressed by their PACKAGE id now/);
|
|
127
|
+
expect(stderr).not.toMatch(/Unknown command/);
|
|
128
|
+
expect(status).toBe(1);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
118
131
|
});
|
|
119
132
|
describe("lotics app author-verb dispatch", () => {
|
|
120
133
|
// `app publish` (no id, empty cwd) must fail on the missing local app
|
package/dist/client.d.ts
CHANGED
|
@@ -542,31 +542,60 @@ export declare class LoticsClient {
|
|
|
542
542
|
/**
|
|
543
543
|
* Preview a release — the dry run behind `lotics app release`. Runs the
|
|
544
544
|
* binding-aware extract of the origin (aliases stable through the app's current
|
|
545
|
-
* binding) and reports the next version number, the new + changed aliases,
|
|
546
|
-
* any extract findings (an `error` blocks the
|
|
545
|
+
* binding) and reports the next version number, the new + changed aliases, the
|
|
546
|
+
* bundled-knowledge delta, and any extract findings (an `error` blocks the
|
|
547
|
+
* apply). An optional `knowledge` declaration (from the pulled app manifest)
|
|
548
|
+
* re-declares the bundle set — added/dropped/changed docs surface in the delta;
|
|
549
|
+
* omitted, the current corpus is reconstructed from the pin. No writes. Admin,
|
|
547
550
|
* owning-org only.
|
|
548
551
|
*/
|
|
549
|
-
previewPackageRelease(app_id: string
|
|
552
|
+
previewPackageRelease(app_id: string, opts?: {
|
|
553
|
+
/** alias → doc_id re-declaring the bundled-knowledge set (from the manifest). */
|
|
554
|
+
knowledge?: Array<{
|
|
555
|
+
alias: string;
|
|
556
|
+
doc_id: string;
|
|
557
|
+
}>;
|
|
558
|
+
}): Promise<{
|
|
550
559
|
package_id: string;
|
|
551
560
|
version: number;
|
|
552
561
|
added_aliases: string[];
|
|
553
562
|
changed_artifacts: string[];
|
|
563
|
+
/** Absent from a pre-declaration server (deploy skew) — treat as empty delta. */
|
|
564
|
+
knowledge?: {
|
|
565
|
+
added: string[];
|
|
566
|
+
removed: string[];
|
|
567
|
+
changed: string[];
|
|
568
|
+
};
|
|
554
569
|
findings: ExtractFinding[];
|
|
555
570
|
}>;
|
|
556
571
|
/**
|
|
557
572
|
* Release — snapshot the origin app into the next registry version. The server
|
|
558
573
|
* binding-aware-extracts it, repackages its deployed source + dist as the
|
|
559
574
|
* bundle, publishes the next `release`-channel version with the changelog, and
|
|
560
|
-
* re-pins the origin.
|
|
575
|
+
* re-pins the origin. An optional `knowledge` declaration re-declares the
|
|
576
|
+
* bundled-knowledge set (added/dropped/re-snapshotted docs; omitted preserves
|
|
577
|
+
* the current corpus). Error findings from extract surface as a 409; a
|
|
578
|
+
* missing/archived declared doc is a 400, a foreign-package doc a 409. Admin,
|
|
561
579
|
* owning-org only. Backs `lotics app release --yes`.
|
|
562
580
|
*/
|
|
563
581
|
releasePackage(app_id: string, body: {
|
|
564
582
|
changelog: string;
|
|
583
|
+
/** alias → doc_id re-declaring the bundled-knowledge set (from the manifest). */
|
|
584
|
+
knowledge?: Array<{
|
|
585
|
+
alias: string;
|
|
586
|
+
doc_id: string;
|
|
587
|
+
}>;
|
|
565
588
|
}): Promise<{
|
|
566
589
|
package_id: string;
|
|
567
590
|
version: number;
|
|
568
591
|
added_aliases: string[];
|
|
569
592
|
changed_artifacts: string[];
|
|
593
|
+
/** Absent from a pre-declaration server (deploy skew) — treat as empty delta. */
|
|
594
|
+
knowledge?: {
|
|
595
|
+
added: string[];
|
|
596
|
+
removed: string[];
|
|
597
|
+
changed: string[];
|
|
598
|
+
};
|
|
570
599
|
}>;
|
|
571
600
|
/**
|
|
572
601
|
* Dry-run preview of a first-release — the `GET` behind `lotics app publish`
|
package/dist/client.js
CHANGED
|
@@ -353,18 +353,29 @@ export class LoticsClient {
|
|
|
353
353
|
/**
|
|
354
354
|
* Preview a release — the dry run behind `lotics app release`. Runs the
|
|
355
355
|
* binding-aware extract of the origin (aliases stable through the app's current
|
|
356
|
-
* binding) and reports the next version number, the new + changed aliases,
|
|
357
|
-
* any extract findings (an `error` blocks the
|
|
356
|
+
* binding) and reports the next version number, the new + changed aliases, the
|
|
357
|
+
* bundled-knowledge delta, and any extract findings (an `error` blocks the
|
|
358
|
+
* apply). An optional `knowledge` declaration (from the pulled app manifest)
|
|
359
|
+
* re-declares the bundle set — added/dropped/changed docs surface in the delta;
|
|
360
|
+
* omitted, the current corpus is reconstructed from the pin. No writes. Admin,
|
|
358
361
|
* owning-org only.
|
|
359
362
|
*/
|
|
360
|
-
async previewPackageRelease(app_id) {
|
|
361
|
-
|
|
363
|
+
async previewPackageRelease(app_id, opts = {}) {
|
|
364
|
+
const params = new URLSearchParams();
|
|
365
|
+
if (opts.knowledge !== undefined && opts.knowledge.length > 0) {
|
|
366
|
+
params.set("knowledge", JSON.stringify(opts.knowledge));
|
|
367
|
+
}
|
|
368
|
+
const query = params.toString();
|
|
369
|
+
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/package-release${query ? `?${query}` : ""}`);
|
|
362
370
|
}
|
|
363
371
|
/**
|
|
364
372
|
* Release — snapshot the origin app into the next registry version. The server
|
|
365
373
|
* binding-aware-extracts it, repackages its deployed source + dist as the
|
|
366
374
|
* bundle, publishes the next `release`-channel version with the changelog, and
|
|
367
|
-
* re-pins the origin.
|
|
375
|
+
* re-pins the origin. An optional `knowledge` declaration re-declares the
|
|
376
|
+
* bundled-knowledge set (added/dropped/re-snapshotted docs; omitted preserves
|
|
377
|
+
* the current corpus). Error findings from extract surface as a 409; a
|
|
378
|
+
* missing/archived declared doc is a 400, a foreign-package doc a 409. Admin,
|
|
368
379
|
* owning-org only. Backs `lotics app release --yes`.
|
|
369
380
|
*/
|
|
370
381
|
async releasePackage(app_id, body) {
|
|
@@ -127,7 +127,12 @@ function inputDeclToTsType(decl) {
|
|
|
127
127
|
return null;
|
|
128
128
|
})
|
|
129
129
|
.filter((v) => v !== null);
|
|
130
|
-
|
|
130
|
+
// The literal union keeps autocomplete for hand-typed ids, but a package
|
|
131
|
+
// app addresses options through the runtime-resolved OPT map (typed
|
|
132
|
+
// string — consumer workspaces bind DIFFERENT concrete ids), so the
|
|
133
|
+
// input must also accept string. `(string & {})` widens without
|
|
134
|
+
// collapsing the union in intellisense.
|
|
135
|
+
const inner = literals.length > 0 ? `${literals.join(" | ")} | (string & {})` : "string";
|
|
131
136
|
return decl.multi === true ? `ReadonlyArray<${inner}>` : inner;
|
|
132
137
|
}
|
|
133
138
|
case "date_range":
|
|
@@ -193,7 +198,11 @@ function outputDeclToTsType(decl) {
|
|
|
193
198
|
? JSON.stringify(o.value)
|
|
194
199
|
: null)
|
|
195
200
|
.filter((v) => v !== null);
|
|
196
|
-
|
|
201
|
+
// Same widening on the READ side: a package app's runtime output value is
|
|
202
|
+
// the CONSUMER workspace's concrete opt_ id, not the origin's literal —
|
|
203
|
+
// exhaustive narrowing over origin literals would be unsound. `(string & {})`
|
|
204
|
+
// keeps autocomplete without lying about the value space.
|
|
205
|
+
const inner = literals.length > 0 ? `${literals.join(" | ")} | (string & {})` : "string";
|
|
197
206
|
return decl.multi === true ? `ReadonlyArray<${inner}>` : inner;
|
|
198
207
|
}
|
|
199
208
|
case "object": {
|
|
@@ -77,8 +77,8 @@ describe("generateAppWorkflowsDts", () => {
|
|
|
77
77
|
});
|
|
78
78
|
expect(dts).toContain("record_id: string;"); // required → NOT nullable
|
|
79
79
|
expect(dts).toContain("due?: string | null;"); // optional scalar → clearable
|
|
80
|
-
expect(dts).toContain('status?: "opt_done" | null;');
|
|
81
|
-
expect(dts).toContain('tags?: ReadonlyArray<"opt_a"> | null;'); // optional multi
|
|
80
|
+
expect(dts).toContain('status?: "opt_done" | (string & {}) | null;');
|
|
81
|
+
expect(dts).toContain('tags?: ReadonlyArray<"opt_a" | (string & {})> | null;'); // optional multi
|
|
82
82
|
// The object itself is a top-level optional → nullable; its NESTED optional
|
|
83
83
|
// field mirrors the backend's plain `.optional()` (no `| null`).
|
|
84
84
|
expect(dts).toContain("note?: string;");
|
|
@@ -94,7 +94,7 @@ describe("generateAppWorkflowsDts", () => {
|
|
|
94
94
|
},
|
|
95
95
|
},
|
|
96
96
|
});
|
|
97
|
-
expect(dts).toContain('owner: string; tags: ReadonlyArray<"a" | "b">');
|
|
97
|
+
expect(dts).toContain('owner: string; tags: ReadonlyArray<"a" | "b" | (string & {})>');
|
|
98
98
|
});
|
|
99
99
|
it("types a multi file input as ReadonlyArray<string>, single file as string", () => {
|
|
100
100
|
const dts = generateAppWorkflowsDts({
|
|
@@ -79,24 +79,28 @@ export declare function packageShow(client: LoticsClient, args: {
|
|
|
79
79
|
package_id: string;
|
|
80
80
|
}): Promise<void>;
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* drifted→recreate; template→revert) — an explicit bulk "take upstream" that
|
|
89
|
-
* discards local edits. `--resolve knowledge.<alias>=<value>` /
|
|
90
|
-
* `--resolve template.<alias>=revert|keep` and `--bind-to <alias>=<kdc_id>`
|
|
91
|
-
* resolve entries individually — the ONE namespaced grammar, passed to the
|
|
92
|
-
* server verbatim.
|
|
82
|
+
* CLEAN BREAK for an explicit `pci_` argument on `upgrade` / `uninstall`: the
|
|
83
|
+
* `pci_` resource id is retired from human sight — content installs are addressed
|
|
84
|
+
* by their PACKAGE id. Prints a loud redirect, best-effort resolving the `pci_`
|
|
85
|
+
* back to its package id (via list-content) so the exact command is spelled out.
|
|
86
|
+
* The header prints synchronously first, so the redirect is observable even when
|
|
87
|
+
* the best-effort resolution can't reach the registry.
|
|
93
88
|
*/
|
|
94
|
-
export declare function
|
|
95
|
-
|
|
89
|
+
export declare function redirectContentPciForm(client: LoticsClient, pci_id: string, verb: "upgrade" | "uninstall"): Promise<never>;
|
|
90
|
+
/**
|
|
91
|
+
* `lotics upgrade <apg_>` — the package-id upgrade path, kind-branched. `kind` is a
|
|
92
|
+
* DERIVED display hint (`contractHasAppSurface`): `'content'` means no app surface.
|
|
93
|
+
* - a CONTENT package upgrades THIS workspace's standalone content installation
|
|
94
|
+
* (resolved from the package id — the anchor is unique per workspace, so the
|
|
95
|
+
* `pci_` never surfaces), through the same content review gate.
|
|
96
|
+
* - an APP-surface package FLEET-upgrades every installation across the org
|
|
97
|
+
* (unchanged) — the resolve/bind/apply-all flags don't apply to a fleet run.
|
|
98
|
+
*/
|
|
99
|
+
export declare function packageUpgradeByPackageId(client: LoticsClient, args: {
|
|
100
|
+
package_id: string;
|
|
96
101
|
version?: number;
|
|
97
|
-
/** Raw `--resolve <alias>=<value>` flags, routed to knowledge/templates after the preview. */
|
|
98
102
|
resolve: string[];
|
|
99
|
-
|
|
103
|
+
bindTo: string[];
|
|
100
104
|
applyAll: boolean;
|
|
101
105
|
}): Promise<void>;
|
|
102
106
|
/** Parse repeated `--bind-to alias=kdc_id` flags into an alias → doc-id consent map. */
|
|
@@ -110,9 +114,11 @@ export declare function packageInstall(client: LoticsClient, args: {
|
|
|
110
114
|
config?: Record<string, string | number | boolean>;
|
|
111
115
|
}): Promise<void>;
|
|
112
116
|
/**
|
|
113
|
-
* `lotics uninstall <app_id|
|
|
114
|
-
* kinds, dispatched by the id form (mirrors `lotics upgrade`):
|
|
115
|
-
* - a `
|
|
117
|
+
* `lotics uninstall <app_id|package_id>` — ONE top-level command over both
|
|
118
|
+
* installation kinds, dispatched by the id form (mirrors `lotics upgrade`):
|
|
119
|
+
* - a package id (`apg_`) → THIS workspace's STANDALONE CONTENT installation
|
|
120
|
+
* (content installs are addressed by package id, UNIQUE per workspace, so the
|
|
121
|
+
* `pci_` resource id never surfaces): deletes the row and (unless
|
|
116
122
|
* `--keep-content`) archives its package-bound docs AND templates, listing each
|
|
117
123
|
* archived id.
|
|
118
124
|
* - anything else (an `app_id`) → an APP installation: archives its workflow
|
|
@@ -129,8 +135,9 @@ export declare function packageUninstall(client: LoticsClient, args: {
|
|
|
129
135
|
* `lotics package list-content` — list the selected workspace's STANDALONE
|
|
130
136
|
* content installations (an app-bundled corpus rides its app's
|
|
131
137
|
* `binding.knowledge` and shows on the Apps surface instead), each with its
|
|
132
|
-
* registry status. The
|
|
133
|
-
*
|
|
138
|
+
* registry status. The what-is-installed listing: each row leads with the PACKAGE
|
|
139
|
+
* id — the address for `lotics upgrade <package_id>` / `lotics uninstall
|
|
140
|
+
* <package_id>` (the `pci_` resource id stays hidden).
|
|
134
141
|
*/
|
|
135
142
|
export declare function packageListContent(client: LoticsClient): Promise<void>;
|
|
136
143
|
export declare function packageEject(client: LoticsClient, args: {
|
|
@@ -185,9 +192,15 @@ export declare function appPublish(client: LoticsClient, args: {
|
|
|
185
192
|
* § Promotion). The origin is the permanent working copy; a release binding-aware-
|
|
186
193
|
* extracts it (stable aliases), repackages its DEPLOYED source + dist as the
|
|
187
194
|
* bundle, publishes the next version, and re-pins the origin. Prints the preview
|
|
188
|
-
* first (next version, new + changed aliases,
|
|
189
|
-
* `--yes`, else exits 1 so a review step can't be
|
|
190
|
-
* blocks the apply.
|
|
195
|
+
* first (next version, new + changed aliases, the bundled-knowledge delta,
|
|
196
|
+
* findings); applies only with `--yes`, else exits 1 so a review step can't be
|
|
197
|
+
* skipped. An `error` finding blocks the apply.
|
|
198
|
+
*
|
|
199
|
+
* Run from the pulled app project, the manifest's `lotics.knowledge` (alias →
|
|
200
|
+
* doc_id) is the bundle DECLARATION — it re-declares which docs the package owns
|
|
201
|
+
* (add/drop/re-snapshot). Forwarded only when non-empty; empty (or a bare id from
|
|
202
|
+
* elsewhere) sends nothing, so the current corpus is reconstructed from the pin
|
|
203
|
+
* (never silently dropped).
|
|
191
204
|
*/
|
|
192
205
|
export declare function appRelease(client: LoticsClient, args: {
|
|
193
206
|
app_id?: string;
|
|
@@ -206,14 +219,3 @@ export declare function packageYank(client: LoticsClient, args: {
|
|
|
206
219
|
version: number;
|
|
207
220
|
undo: boolean;
|
|
208
221
|
}): Promise<void>;
|
|
209
|
-
/**
|
|
210
|
-
* `lotics upgrade <package_id> [--version N]` (fleet path) — bring every
|
|
211
|
-
* installation of the package across the caller's org to the target version.
|
|
212
|
-
* Hands-off applies only where the preview is clean; skipped/failed
|
|
213
|
-
* installations are reported per line and the process exits 1 so a release
|
|
214
|
-
* script can gate on "fleet fully current".
|
|
215
|
-
*/
|
|
216
|
-
export declare function packageFleetUpgrade(client: LoticsClient, args: {
|
|
217
|
-
package_id: string;
|
|
218
|
-
version?: number;
|
|
219
|
-
}): Promise<void>;
|