@lotics/cli 0.76.1 → 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 +57 -52
- package/dist/app_commands.d.ts +9 -4
- package/dist/app_commands.js +44 -10
- package/dist/app_commands.test.js +69 -0
- package/dist/args.d.ts +6 -5
- package/dist/args.js +18 -17
- package/dist/args.test.js +25 -17
- package/dist/cli.js +214 -255
- package/dist/cli_dispatch.test.js +90 -25
- package/dist/client.d.ts +134 -176
- package/dist/client.js +72 -95
- package/dist/generate_app_workflows_dts.js +11 -2
- package/dist/generate_app_workflows_dts.test.js +3 -3
- package/dist/generate_package_fields.d.ts +39 -38
- package/dist/generate_package_fields.js +113 -60
- package/dist/generate_package_fields.test.js +30 -22
- package/dist/package_commands.d.ts +116 -332
- package/dist/package_commands.js +420 -1316
- package/dist/package_commands.test.js +194 -537
- package/dist/src/cli.js +721 -1846
- package/dist/starter_template.d.ts +0 -19
- package/dist/starter_template.js +0 -389
- package/dist/starter_template.test.js +1 -69
- package/package.json +1 -1
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,
|
|
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";
|
|
@@ -71,10 +71,22 @@ COMMANDS
|
|
|
71
71
|
cat args.json | lotics run <tool> Read JSON args from stdin (large payloads)
|
|
72
72
|
lotics app create <name> [path] Create a new custom-code app + scaffold locally
|
|
73
73
|
lotics app pull <app_id> [path] Bootstrap full local env (source + npm install + types)
|
|
74
|
-
lotics app deploy -m <message> Build + upload current dir as a new version
|
|
75
|
-
(-m is required — it's the version's audit trail
|
|
76
|
-
|
|
74
|
+
lotics app deploy -m <message> Build + upload current dir as a new version — COMMIT
|
|
75
|
+
(-m is required — it's the version's audit trail;
|
|
76
|
+
carries code + queries only — workflow bindings are
|
|
77
77
|
managed by set_app_workflow / remove_app_workflow)
|
|
78
|
+
lotics app publish [app_id|.] [--rename old=new ...] [-m <changelog>] [--yes]
|
|
79
|
+
Make the app DISTRIBUTABLE — first-release it (v1) as a
|
|
80
|
+
package; later versions ship via "lotics app release".
|
|
81
|
+
Previews the auto-minted aliases + findings; --yes applies
|
|
82
|
+
(extract → create → publish v1 → pin origin). --rename fixes
|
|
83
|
+
an alias before v1 freezes; -m is an optional v1 changelog
|
|
84
|
+
lotics app release [app_id|.] -m <changelog> [--yes]
|
|
85
|
+
RELEASE the next package version from the origin app you
|
|
86
|
+
are happy with (preview; --yes publishes + re-pins)
|
|
87
|
+
lotics app unpublish <app_id|package_id> [--undo]
|
|
88
|
+
Take the published package off the shelf (installations
|
|
89
|
+
keep working); --undo restores it
|
|
78
90
|
lotics app versions [app_id] Show deploy history newest-first (version,
|
|
79
91
|
timestamp, deployer, build status, -m message;
|
|
80
92
|
* marks the currently served version)
|
|
@@ -96,57 +108,42 @@ COMMANDS
|
|
|
96
108
|
lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address
|
|
97
109
|
lotics app rename "<new name>" Rename the app's display name (launcher title)
|
|
98
110
|
lotics app dev [path] Run the app locally with HMR (RPC forwarded to prod)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
lotics package build [path] Build the publishable bundle (source + dist)
|
|
103
|
-
lotics package publish [path] Publish a new immutable package version
|
|
104
|
-
lotics package dev [path] Sync the package into a dev workspace + run the app
|
|
105
|
-
dev server (--workspace <dev_ws> selects it)
|
|
106
|
-
lotics package sync [path] Re-sync (additive migrate + materialize) into a dev ws
|
|
107
|
-
lotics package reset [path] DEV-ONLY: drop scaffolded tables + re-scaffold clean
|
|
108
|
-
lotics package install <package> [--version N] [--bind-to <alias>=<kdc_id> ...] [--config key=value ...]
|
|
111
|
+
# PACKAGES — consumer verbs are top-level; low-traffic ops live on "lotics package"
|
|
112
|
+
# (author verbs live on "lotics app")
|
|
113
|
+
lotics install <package_id> [--version N] [--bind-to <alias>=<kdc_id> ...] [--config key=value ...]
|
|
109
114
|
Install a package (app: scaffolds/deploys/materializes,
|
|
110
115
|
--config sets its knobs; content: installs the doc corpus,
|
|
111
116
|
--bind-to consents to adopt a same-named doc on a collision)
|
|
112
|
-
lotics
|
|
117
|
+
lotics uninstall <app_id|package_id> [--archive-tables] [--keep-content]
|
|
113
118
|
Uninstall — dispatched by id. App (app_id): archives
|
|
114
119
|
artifacts (+ --archive-tables also archives scaffolded
|
|
115
|
-
tables). Content (
|
|
116
|
-
unless --keep-content
|
|
117
|
-
lotics
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
lotics package upgrade <app_id|pci_id> [--version N] [--resolve <key>=... ] [--bind-to ...] [--apply-all]
|
|
126
|
-
Preview-then-apply an upgrade. App: refuses while any
|
|
127
|
-
drift/modified/bundled-knowledge finding lacks a --resolve
|
|
128
|
-
(a knowledge-alias --resolve routes to the doc). Content
|
|
129
|
-
(pci_): --resolve <alias>=apply|keep|archive|recreate|unbind;
|
|
130
|
-
--apply-all accepts the package's version for every doc
|
|
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
|
+
Preview-then-apply an upgrade, dispatched by id. App
|
|
124
|
+
(app_id): refuses while any drift/modified/bundled-knowledge
|
|
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
|
|
131
130
|
lotics package doctor [app_id] Installation health: version pin vs latest, binding
|
|
132
131
|
drift, locally modified core, knowledge drift/edits
|
|
133
132
|
(exit 1 on findings)
|
|
134
|
-
lotics package
|
|
135
|
-
|
|
136
|
-
(re-materializes at the pinned version)
|
|
133
|
+
lotics package config <app_id> [--set key=value ...]
|
|
134
|
+
Show or edit an installation's config knobs
|
|
137
135
|
lotics package eject <app_id> Sever an installation's package link
|
|
138
136
|
(re-deploys the pinned source as a bespoke app)
|
|
139
|
-
lotics package
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
origin app (reads .lotics/adopt_binding.json;
|
|
144
|
-
--version N pins a specific version)
|
|
145
|
-
lotics package fleet-upgrade <package_id> [--version N]
|
|
137
|
+
lotics package show <package_id> Registry metadata + version history
|
|
138
|
+
lotics package list-content List the workspace's content installations
|
|
139
|
+
(standalone content installs) — each row leads with
|
|
140
|
+
the package id for upgrade/uninstall
|
|
146
141
|
lotics package yank <package_id> <version> [--undo]
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
Refuse new installs/upgrades of a broken published
|
|
143
|
+
version (pinned installations keep running)
|
|
144
|
+
lotics run publish_content '{"name":"…","knowledge_doc_ids":[…],"template_ids":[…]}'
|
|
145
|
+
Publish a SET of live docs + templates as a content
|
|
146
|
+
package (v1 + origin pin); release_content cuts the next
|
|
150
147
|
lotics ui link <component> [--ui-src <path>] [--remove]
|
|
151
148
|
Dev-link @lotics/ui to packages/ui/src (Vite alias
|
|
152
149
|
+ tsc paths) for live HMR + typecheck. Monorepo apps
|
|
@@ -175,13 +172,12 @@ FLAGS
|
|
|
175
172
|
is_current_member / row-scoping resolve to them (also
|
|
176
173
|
LOTICS_VIEW_AS env; admin key only; writes stay yours)
|
|
177
174
|
--local Pin the current directory (lotics org use / auth api-key)
|
|
178
|
-
--
|
|
179
|
-
|
|
180
|
-
--
|
|
181
|
-
--bind-to <a>=<id> (lotics package install/upgrade, repeatable) Adopt an existing
|
|
175
|
+
--rename <old>=<new> (lotics app publish, repeatable) Fix an auto-minted alias before
|
|
176
|
+
the package's v1 contract freezes it
|
|
177
|
+
--bind-to <a>=<id> (lotics install/upgrade, repeatable) Adopt an existing
|
|
182
178
|
same-named doc as package-managed (resolves a knowledge collision)
|
|
183
|
-
--keep-content (lotics
|
|
184
|
-
--apply-all (lotics
|
|
179
|
+
--keep-content (lotics uninstall) Keep the docs instead of archiving them
|
|
180
|
+
--apply-all (lotics upgrade, knowledge) Accept the package's version
|
|
185
181
|
for every doc (overwrites local edits)
|
|
186
182
|
--all (lotics auth logout) Remove every saved credential
|
|
187
183
|
--version Show version
|
|
@@ -597,28 +593,6 @@ async function main() {
|
|
|
597
593
|
console.error("Usage: lotics ui link <component> [--ui-src <abs path>] [--remove]");
|
|
598
594
|
process.exit(1);
|
|
599
595
|
}
|
|
600
|
-
// --- lotics package new / build — local scaffold + build, no auth required ---
|
|
601
|
-
if (command === "package" && subcommand === "new") {
|
|
602
|
-
const name = toolArgs;
|
|
603
|
-
if (!name) {
|
|
604
|
-
console.error("Usage: lotics package new <name> [path] [--kind app|content]");
|
|
605
|
-
process.exit(1);
|
|
606
|
-
}
|
|
607
|
-
if (flags.kind !== undefined && flags.kind !== "app" && flags.kind !== "content") {
|
|
608
|
-
console.error(`Invalid --kind "${flags.kind}" — expected "app" or "content".`);
|
|
609
|
-
process.exit(1);
|
|
610
|
-
}
|
|
611
|
-
await packageNew({
|
|
612
|
-
name,
|
|
613
|
-
targetPath: restArgs[0],
|
|
614
|
-
kind: flags.kind === "content" ? "content" : "app",
|
|
615
|
-
});
|
|
616
|
-
return;
|
|
617
|
-
}
|
|
618
|
-
if (command === "package" && subcommand === "build") {
|
|
619
|
-
await packageBuild({ projectDir: toolArgs });
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
596
|
// --- lotics app workflow check [alias] — local typecheck, no auth, no network ---
|
|
623
597
|
// Reads src/workflows/*.ts + .lotics/workflows/*.globals.d.ts and the app's own
|
|
624
598
|
// typescript; builds one isolated program per alias. Handled before the auth
|
|
@@ -701,7 +675,16 @@ async function main() {
|
|
|
701
675
|
return;
|
|
702
676
|
}
|
|
703
677
|
// --- Validate command before auth ---
|
|
704
|
-
if (command !== "tools" &&
|
|
678
|
+
if (command !== "tools" &&
|
|
679
|
+
command !== "upload" &&
|
|
680
|
+
command !== "run" &&
|
|
681
|
+
command !== "download" &&
|
|
682
|
+
command !== "workspace" &&
|
|
683
|
+
command !== "app" &&
|
|
684
|
+
command !== "package" &&
|
|
685
|
+
command !== "install" &&
|
|
686
|
+
command !== "uninstall" &&
|
|
687
|
+
command !== "upgrade") {
|
|
705
688
|
console.error(`Unknown command: ${command}`);
|
|
706
689
|
console.error('Run "lotics --help" for usage.');
|
|
707
690
|
process.exit(1);
|
|
@@ -723,30 +706,27 @@ async function main() {
|
|
|
723
706
|
console.error(" lotics app subdomain <new-subdomain> Rename the app's public <slug>.lotics.app address");
|
|
724
707
|
console.error(" lotics app rename \"<new name>\" Rename the app's display name (launcher title)");
|
|
725
708
|
console.error(" lotics app dev [path] Run the app locally with HMR + RPC forwarding");
|
|
709
|
+
console.error(" lotics app publish [app_id|.] [--rename old=new ...] [-m <changelog>] [--yes] First-release the app as a package (v1; preview, --yes applies)");
|
|
710
|
+
console.error(" lotics app release [app_id|.] -m <changelog> [--yes] Release the next package version from the origin");
|
|
711
|
+
console.error(" lotics app unpublish <app_id|package_id> [--undo] Take a published package off the shelf (any kind — app or content)");
|
|
726
712
|
process.exit(1);
|
|
727
713
|
}
|
|
728
714
|
if (command === "package" && !subcommand) {
|
|
729
|
-
console.error("Usage:");
|
|
730
|
-
console.error("
|
|
731
|
-
console.error("
|
|
732
|
-
console.error("
|
|
733
|
-
console.error("
|
|
734
|
-
console.error(" lotics package sync [path] [--workspace <ws>] Re-sync (additive migrate + materialize) into a dev workspace");
|
|
735
|
-
console.error(" lotics package reset [path] [--workspace <ws>] DEV-ONLY: drop scaffolded tables + re-scaffold clean");
|
|
736
|
-
console.error(" lotics package install <package> [--version N] [--bind-to <alias>=<kdc_id>] [--config key=value ...] Install a package (app or content)");
|
|
737
|
-
console.error(" lotics package uninstall <app_id|pci_id> [--archive-tables] [--keep-content] Uninstall — dispatched by id (app vs content)");
|
|
738
|
-
console.error(" lotics package config <app_id> [--set key=value ...] Show or edit an installation's config knobs");
|
|
739
|
-
console.error(" lotics package show <package_id> Registry metadata + version history (channel, yank, changelog)");
|
|
740
|
-
console.error(" lotics package retire <package_id> [--undo] Retire a package (refuse new installs; installs keep working)");
|
|
741
|
-
console.error(" lotics package list-content List the workspace's content installations (standalone + app-bundled)");
|
|
742
|
-
console.error(" lotics package upgrade <app_id|pci_id> [--version N] [--resolve <key>=... ] [--bind-to ...] [--apply-all] Preview + apply an upgrade");
|
|
715
|
+
console.error("Usage (low-traffic consumer / registry ops — author verbs live on `lotics app`):");
|
|
716
|
+
console.error(" The high-traffic consumer verbs are top-level:");
|
|
717
|
+
console.error(" lotics install <package_id> [--version N] [--bind-to <alias>=<kdc_id>] [--config key=value ...] Install a package (app or content)");
|
|
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_)");
|
|
743
720
|
console.error(" lotics package doctor [app_id] Health: version pin vs latest + binding/knowledge drift");
|
|
744
|
-
console.error(" lotics package
|
|
721
|
+
console.error(" lotics package config <app_id> [--set key=value ...] Show or edit an installation's config knobs");
|
|
745
722
|
console.error(" lotics package eject <app_id> Sever an installation's package link");
|
|
746
|
-
console.error(" lotics package
|
|
747
|
-
console.error(" lotics package
|
|
748
|
-
console.error(" lotics package fleet-upgrade <package_id> [--version N] Upgrade every org installation (clean ones apply; findings skip)");
|
|
723
|
+
console.error(" lotics package show <package_id> Registry metadata + version history (channel, yank, changelog)");
|
|
724
|
+
console.error(" lotics package list-content List the workspace's content installations (standalone content installs)");
|
|
749
725
|
console.error(" lotics package yank <package_id> <version> [--undo] Refuse new installs/upgrades of a broken published version (pinned installations keep running)");
|
|
726
|
+
console.error(" A content package (a SET of live docs + templates) — publish + release with the tools, retire on `lotics app`:");
|
|
727
|
+
console.error(" lotics run publish_content '{\"name\":\"…\",\"knowledge_doc_ids\":[…],\"template_ids\":[…]}' Publish v1 (a fixed set)");
|
|
728
|
+
console.error(" lotics run release_content '{\"package_id\":\"apg_…\",\"changelog\":\"…\"}' Cut the next version (add \"dry_run\":true to preview)");
|
|
729
|
+
console.error(" lotics app unpublish <package_id> Take the whole package off the shelf (kind-agnostic — retires content too)");
|
|
750
730
|
process.exit(1);
|
|
751
731
|
}
|
|
752
732
|
if (command === "run" && !subcommand) {
|
|
@@ -820,11 +800,11 @@ async function main() {
|
|
|
820
800
|
if (subcommand === "create") {
|
|
821
801
|
const name = toolArgs;
|
|
822
802
|
if (!name) {
|
|
823
|
-
console.error('Usage: lotics workspace create <name> [--timezone <tz>]
|
|
803
|
+
console.error('Usage: lotics workspace create <name> [--timezone <tz>]');
|
|
824
804
|
process.exit(1);
|
|
825
805
|
}
|
|
826
806
|
const timezone = flags.timezone;
|
|
827
|
-
const created = await client.createWorkspace({ name, timezone
|
|
807
|
+
const created = await client.createWorkspace({ name, timezone });
|
|
828
808
|
setSelectedWorkspace(created.id);
|
|
829
809
|
client.setWorkspaceId(created.id);
|
|
830
810
|
if (flags.json) {
|
|
@@ -893,47 +873,103 @@ async function main() {
|
|
|
893
873
|
}
|
|
894
874
|
// Ensure workspace is resolved for all remaining commands
|
|
895
875
|
await resolveWorkspace(client, ctx);
|
|
896
|
-
// lotics
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
876
|
+
// --- lotics install / uninstall / upgrade — top-level CONSUMER verbs ---
|
|
877
|
+
// The high-traffic operator surface reads noun-less: `lotics install <pkg>`,
|
|
878
|
+
// `lotics uninstall <id>`, `lotics upgrade <id>`. Low-traffic ops keep their
|
|
879
|
+
// `lotics package <verb>` home. The package id is the SECOND positional at top
|
|
880
|
+
// level, which the parser puts in `subcommand` (not `toolArgs`).
|
|
881
|
+
if (command === "install") {
|
|
882
|
+
const packageId = subcommand;
|
|
883
|
+
if (!packageId) {
|
|
884
|
+
console.error("Usage: lotics install <package_id> [--version N] [--bind-to <alias>=<kdc_id> ...] [--config key=value ...]");
|
|
885
|
+
process.exit(1);
|
|
886
|
+
}
|
|
887
|
+
let version;
|
|
888
|
+
if (flags.packageVersion !== undefined) {
|
|
889
|
+
version = Number(flags.packageVersion);
|
|
890
|
+
if (!Number.isInteger(version) || version <= 0) {
|
|
891
|
+
console.error(`Invalid --version "${flags.packageVersion}" — expected a positive integer.`);
|
|
902
892
|
process.exit(1);
|
|
903
893
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
894
|
+
}
|
|
895
|
+
const config = flags.config.length > 0 ? parseInstallConfigFlags(flags.config) : undefined;
|
|
896
|
+
await packageInstall(client, {
|
|
897
|
+
package_id: packageId,
|
|
898
|
+
version,
|
|
899
|
+
bind_to: parseBindToFlags(flags.bindTo),
|
|
900
|
+
...(config !== undefined ? { config } : {}),
|
|
901
|
+
});
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (command === "uninstall") {
|
|
905
|
+
const id = subcommand;
|
|
906
|
+
if (!id) {
|
|
907
|
+
console.error("Usage: lotics uninstall <app_id|package_id> [--archive-tables] [--keep-content]");
|
|
908
|
+
console.error("Dispatched by id: an app installation (app_id; --archive-tables to also archive its " +
|
|
909
|
+
"scaffolded tables) or a content package (apg_ id from `lotics install` / " +
|
|
910
|
+
"lotics package list-content; --keep-content to retain its docs).");
|
|
911
|
+
process.exit(1);
|
|
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");
|
|
919
916
|
return;
|
|
920
917
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
918
|
+
await packageUninstall(client, {
|
|
919
|
+
id,
|
|
920
|
+
keep_content: flags.keepContent,
|
|
921
|
+
archive_tables: flags.archiveTables,
|
|
922
|
+
});
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
if (command === "upgrade") {
|
|
926
|
+
const target = subcommand;
|
|
927
|
+
if (!target) {
|
|
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.");
|
|
931
|
+
process.exit(1);
|
|
932
|
+
}
|
|
933
|
+
let version;
|
|
934
|
+
if (flags.packageVersion !== undefined) {
|
|
935
|
+
version = Number(flags.packageVersion);
|
|
936
|
+
if (!Number.isInteger(version) || version <= 0) {
|
|
937
|
+
console.error(`Invalid --version "${flags.packageVersion}" — expected a positive integer.`);
|
|
928
938
|
process.exit(1);
|
|
929
939
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
940
|
+
}
|
|
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");
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
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,
|
|
951
|
+
version,
|
|
952
|
+
resolve: flags.resolve,
|
|
953
|
+
bindTo: flags.bindTo,
|
|
954
|
+
applyAll: flags.applyAll,
|
|
934
955
|
});
|
|
935
956
|
return;
|
|
936
957
|
}
|
|
958
|
+
// Anything else is an app installation (addressed by its app id).
|
|
959
|
+
await packageUpgrade(client, {
|
|
960
|
+
app_id: target,
|
|
961
|
+
version,
|
|
962
|
+
resolve: flags.resolve,
|
|
963
|
+
bindTo: flags.bindTo,
|
|
964
|
+
applyAll: flags.applyAll,
|
|
965
|
+
});
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
// lotics package <verb> — the low-traffic consumer / registry surface. The
|
|
969
|
+
// high-traffic install / uninstall / upgrade / fleet-upgrade verbs moved to
|
|
970
|
+
// the top level above; they are refused here (below) so the old forms fail
|
|
971
|
+
// loudly instead of silently doing nothing.
|
|
972
|
+
if (command === "package") {
|
|
937
973
|
if (subcommand === "list-content") {
|
|
938
974
|
await packageListContent(client);
|
|
939
975
|
return;
|
|
@@ -947,15 +983,6 @@ async function main() {
|
|
|
947
983
|
await packageConfig(client, { app_id: appId, sets: flags.set });
|
|
948
984
|
return;
|
|
949
985
|
}
|
|
950
|
-
if (subcommand === "retire") {
|
|
951
|
-
const packageId = toolArgs;
|
|
952
|
-
if (!packageId) {
|
|
953
|
-
console.error("Usage: lotics package retire <package_id> [--undo]");
|
|
954
|
-
process.exit(1);
|
|
955
|
-
}
|
|
956
|
-
await packageRetire(client, { package_id: packageId, undo: flags.undo });
|
|
957
|
-
return;
|
|
958
|
-
}
|
|
959
986
|
if (subcommand === "show") {
|
|
960
987
|
const packageId = toolArgs;
|
|
961
988
|
if (!packageId) {
|
|
@@ -974,34 +1001,6 @@ async function main() {
|
|
|
974
1001
|
await packageEject(client, { app_id: appId });
|
|
975
1002
|
return;
|
|
976
1003
|
}
|
|
977
|
-
if (subcommand === "extract") {
|
|
978
|
-
const appId = toolArgs;
|
|
979
|
-
if (!appId) {
|
|
980
|
-
console.error("Usage: lotics package extract <app_id> [path]");
|
|
981
|
-
console.error("Promotes a bespoke app to a draft package project (contract + binding + templates).");
|
|
982
|
-
process.exit(1);
|
|
983
|
-
}
|
|
984
|
-
await packageExtract(client, { app_id: appId, targetPath: restArgs[0] });
|
|
985
|
-
return;
|
|
986
|
-
}
|
|
987
|
-
if (subcommand === "adopt") {
|
|
988
|
-
const appId = toolArgs;
|
|
989
|
-
if (!appId) {
|
|
990
|
-
console.error("Usage: lotics package adopt <app_id> [path]");
|
|
991
|
-
console.error("Binds the published package project (this dir, or [path]) onto the origin app.");
|
|
992
|
-
process.exit(1);
|
|
993
|
-
}
|
|
994
|
-
let version;
|
|
995
|
-
if (flags.packageVersion !== undefined) {
|
|
996
|
-
version = Number(flags.packageVersion);
|
|
997
|
-
if (!Number.isInteger(version) || version <= 0) {
|
|
998
|
-
console.error(`Invalid --version "${flags.packageVersion}" — expected a positive integer.`);
|
|
999
|
-
process.exit(1);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
await packageAdopt(client, { app_id: appId, version, projectDir: restArgs[0] });
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
1004
|
if (subcommand === "yank") {
|
|
1006
1005
|
const packageId = toolArgs;
|
|
1007
1006
|
const version = Number(restArgs[0]);
|
|
@@ -1012,106 +1011,30 @@ async function main() {
|
|
|
1012
1011
|
await packageYank(client, { package_id: packageId, version, undo: flags.undo });
|
|
1013
1012
|
return;
|
|
1014
1013
|
}
|
|
1015
|
-
if (subcommand === "fleet-upgrade") {
|
|
1016
|
-
const packageId = toolArgs;
|
|
1017
|
-
if (!packageId) {
|
|
1018
|
-
console.error("Usage: lotics package fleet-upgrade <package_id> [--version N]");
|
|
1019
|
-
process.exit(1);
|
|
1020
|
-
}
|
|
1021
|
-
let version;
|
|
1022
|
-
if (flags.packageVersion !== undefined) {
|
|
1023
|
-
version = Number(flags.packageVersion);
|
|
1024
|
-
if (!Number.isInteger(version) || version <= 0) {
|
|
1025
|
-
console.error(`Invalid --version "${flags.packageVersion}" — expected a positive integer.`);
|
|
1026
|
-
process.exit(1);
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
await packageFleetUpgrade(client, { package_id: packageId, version });
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
1014
|
if (subcommand === "doctor") {
|
|
1033
1015
|
await packageDoctor(client, { app_id: toolArgs });
|
|
1034
1016
|
return;
|
|
1035
1017
|
}
|
|
1018
|
+
// Re-pointing a live role rides the upgrade's ONE resolutions grammar —
|
|
1019
|
+
// redirect the removed verb loudly, never a silent unknown-command fall-through.
|
|
1036
1020
|
if (subcommand === "rebind-role") {
|
|
1037
1021
|
const appId = toolArgs;
|
|
1038
1022
|
const [roleAlias, groupId] = restArgs;
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
const result = await client.rebindPackageRole(appId, {
|
|
1044
|
-
role_alias: roleAlias,
|
|
1045
|
-
group_id: groupId,
|
|
1046
|
-
});
|
|
1047
|
-
console.error(`Rebound role "${result.role_alias}" → ${result.group_id}` +
|
|
1048
|
-
(result.previous_group_id ? ` (was ${result.previous_group_id})` : "") +
|
|
1049
|
-
". Package workflows/agents were re-materialized against the new group.");
|
|
1050
|
-
return;
|
|
1051
|
-
}
|
|
1052
|
-
if (subcommand === "upgrade") {
|
|
1053
|
-
const target = toolArgs;
|
|
1054
|
-
if (!target) {
|
|
1055
|
-
console.error("Usage: lotics package upgrade <app_id | pci_installation_id> [--version N] [--resolve <key>=... ...]");
|
|
1056
|
-
process.exit(1);
|
|
1057
|
-
}
|
|
1058
|
-
let version;
|
|
1059
|
-
if (flags.packageVersion !== undefined) {
|
|
1060
|
-
version = Number(flags.packageVersion);
|
|
1061
|
-
if (!Number.isInteger(version) || version <= 0) {
|
|
1062
|
-
console.error(`Invalid --version "${flags.packageVersion}" — expected a positive integer.`);
|
|
1063
|
-
process.exit(1);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
// A `pci_` id is a standalone content installation (its own upgrade
|
|
1067
|
-
// pipeline); everything else is an app installation.
|
|
1068
|
-
if (target.startsWith("pci_")) {
|
|
1069
|
-
await packageUpgradeKnowledge(client, {
|
|
1070
|
-
installation_id: target,
|
|
1071
|
-
version,
|
|
1072
|
-
resolve: flags.resolve,
|
|
1073
|
-
bind_to: parseBindToFlags(flags.bindTo),
|
|
1074
|
-
applyAll: flags.applyAll,
|
|
1075
|
-
});
|
|
1076
|
-
return;
|
|
1077
|
-
}
|
|
1078
|
-
await packageUpgrade(client, {
|
|
1079
|
-
app_id: target,
|
|
1080
|
-
version,
|
|
1081
|
-
resolve: flags.resolve,
|
|
1082
|
-
bindTo: flags.bindTo,
|
|
1083
|
-
applyAll: flags.applyAll,
|
|
1084
|
-
});
|
|
1085
|
-
return;
|
|
1086
|
-
}
|
|
1087
|
-
if (subcommand === "publish") {
|
|
1088
|
-
await packagePublish(client, { projectDir: toolArgs, changelog: flags.message });
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
if (subcommand === "sync") {
|
|
1092
|
-
await packageSync(client, { projectDir: toolArgs });
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
if (subcommand === "reset") {
|
|
1096
|
-
await packageReset(client, { projectDir: toolArgs });
|
|
1097
|
-
return;
|
|
1023
|
+
console.error("`lotics package rebind-role` was folded into the upgrade grammar. Re-point a live role with:\n" +
|
|
1024
|
+
` lotics upgrade ${appId ?? "<app_id>"} --resolve roles.${roleAlias ?? "<alias>"}=${groupId ?? "<grp_id>"}`);
|
|
1025
|
+
process.exit(1);
|
|
1098
1026
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
else if (vitePortMatch)
|
|
1111
|
-
vitePort = Number(vitePortMatch[1]);
|
|
1112
|
-
}
|
|
1113
|
-
await packageDev(client, { projectDir, port, vitePort });
|
|
1114
|
-
return;
|
|
1027
|
+
// The high-traffic consumer verbs moved to the top level. Refuse the old
|
|
1028
|
+
// `lotics package <verb>` forms loudly with a redirect, never a silent no-op.
|
|
1029
|
+
const movedVerbs = {
|
|
1030
|
+
install: "lotics install <package_id>",
|
|
1031
|
+
uninstall: "lotics uninstall <app_id|package_id>",
|
|
1032
|
+
upgrade: "lotics upgrade <app_id|package_id>",
|
|
1033
|
+
"fleet-upgrade": "lotics upgrade <package_id>",
|
|
1034
|
+
};
|
|
1035
|
+
if (subcommand !== undefined && subcommand in movedVerbs) {
|
|
1036
|
+
console.error(`\`lotics package ${subcommand}\` moved to the top level — run \`${movedVerbs[subcommand]}\` instead.`);
|
|
1037
|
+
process.exit(1);
|
|
1115
1038
|
}
|
|
1116
1039
|
console.error(`Unknown package subcommand: ${subcommand}`);
|
|
1117
1040
|
console.error("Run 'lotics package' for usage.");
|
|
@@ -1152,6 +1075,40 @@ async function main() {
|
|
|
1152
1075
|
await appDeploy(client, { message });
|
|
1153
1076
|
return;
|
|
1154
1077
|
}
|
|
1078
|
+
if (subcommand === "publish") {
|
|
1079
|
+
// First-release a bespoke app AS a package. Positional app id (`.`/omitted →
|
|
1080
|
+
// the local app project manifest). Previews the minted aliases + findings,
|
|
1081
|
+
// then applies only with `--yes` (mirrors `app release`). `--rename old=new`
|
|
1082
|
+
// fixes an auto-minted alias before v1 freezes it; `-m` is an optional v1 changelog.
|
|
1083
|
+
await appPublish(client, {
|
|
1084
|
+
app_id: toolArgs,
|
|
1085
|
+
renames: flags.rename,
|
|
1086
|
+
changelog: flags.message,
|
|
1087
|
+
yes: flags.yes,
|
|
1088
|
+
});
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
if (subcommand === "release") {
|
|
1092
|
+
// -m <changelog> is REQUIRED — each release is a version row read back by
|
|
1093
|
+
// `lotics package show`, so a blank changelog loses the audit trail.
|
|
1094
|
+
if (!flags.message) {
|
|
1095
|
+
console.error("Usage: lotics app release [app_id|.] -m <changelog> [--yes]");
|
|
1096
|
+
console.error("Snapshots the origin app into its next package version (preview, then --yes to publish).");
|
|
1097
|
+
process.exit(1);
|
|
1098
|
+
}
|
|
1099
|
+
await appRelease(client, { app_id: toolArgs, changelog: flags.message, yes: flags.yes });
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
if (subcommand === "unpublish") {
|
|
1103
|
+
const id = toolArgs;
|
|
1104
|
+
if (!id) {
|
|
1105
|
+
console.error("Usage: lotics app unpublish <app_id|package_id> [--undo]");
|
|
1106
|
+
console.error("Takes a published package off the shelf; existing installations keep working.");
|
|
1107
|
+
process.exit(1);
|
|
1108
|
+
}
|
|
1109
|
+
await appUnpublish(client, { id, undo: flags.undo });
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1155
1112
|
if (subcommand === "subdomain") {
|
|
1156
1113
|
const newSubdomain = toolArgs;
|
|
1157
1114
|
if (!newSubdomain) {
|
|
@@ -1382,8 +1339,10 @@ async function main() {
|
|
|
1382
1339
|
console.log(JSON.stringify({ error: result.error }, null, 2));
|
|
1383
1340
|
}
|
|
1384
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.
|
|
1385
1345
|
console.error(result.error);
|
|
1386
|
-
console.error(`\nHint: run "lotics tools ${toolName}" to see the expected input schema.`);
|
|
1387
1346
|
}
|
|
1388
1347
|
process.exit(1);
|
|
1389
1348
|
}
|