@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
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { generatePackageAppFields } from "./generate_package_fields.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
roles:
|
|
3
|
+
// A live installation binding — fully-qualified alias → concrete id. The
|
|
4
|
+
// generator sources the alias SET here (never a contract file); the emitted
|
|
5
|
+
// module resolves the SAME keys through `getAppBinding()` at runtime.
|
|
6
|
+
const binding = {
|
|
7
|
+
fields: {
|
|
8
|
+
"tasks.title": "fld_title",
|
|
9
|
+
"tasks.status": "fld_status",
|
|
10
|
+
"projects.name": "fld_name",
|
|
11
|
+
},
|
|
12
|
+
options: {
|
|
13
|
+
"tasks.status:to_do": "opt_todo",
|
|
14
|
+
"tasks.status:doing": "opt_doing",
|
|
15
|
+
"tasks.status:done": "opt_done",
|
|
16
|
+
},
|
|
17
|
+
roles: { approver: "grp_approver" },
|
|
18
18
|
};
|
|
19
19
|
describe("generatePackageAppFields", () => {
|
|
20
|
-
it("emits runtime-resolved F/OPT/ROLE keyed by
|
|
21
|
-
const src = generatePackageAppFields(
|
|
20
|
+
it("emits runtime-resolved F/OPT/ROLE keyed by the binding's aliases", () => {
|
|
21
|
+
const src = generatePackageAppFields(binding);
|
|
22
22
|
// Resolves through the SDK binding at module load (top-level await).
|
|
23
23
|
expect(src).toContain('import { getAppBinding } from "@lotics/app-sdk";');
|
|
24
24
|
expect(src).toContain("const binding = await getAppBinding();");
|
|
@@ -31,21 +31,29 @@ describe("generatePackageAppFields", () => {
|
|
|
31
31
|
expect(src).toContain('to_do: bound(binding.options, "tasks.status:to_do", "option")');
|
|
32
32
|
expect(src).toContain('done: bound(binding.options, "tasks.status:done", "option")');
|
|
33
33
|
expect(src).not.toContain('"tasks.title:');
|
|
34
|
-
// ROLE map from
|
|
34
|
+
// ROLE map from the binding's roles.
|
|
35
35
|
expect(src).toContain('approver: bound(binding.roles, "approver", "role")');
|
|
36
36
|
// No concrete id in any VALUE position — the module is workspace-agnostic.
|
|
37
37
|
// (Doc comments legitimately name the id prefixes, so match quoted ids.)
|
|
38
38
|
expect(src).not.toMatch(/"(fld|opt|tbl|grp)_/);
|
|
39
39
|
});
|
|
40
|
-
it("emits valid empty maps for an empty
|
|
41
|
-
const src = generatePackageAppFields({});
|
|
40
|
+
it("emits valid empty maps for an empty binding", () => {
|
|
41
|
+
const src = generatePackageAppFields({ fields: {}, options: {}, roles: {} });
|
|
42
42
|
expect(src).toContain("export const F = {} as const;");
|
|
43
43
|
expect(src).toContain("export const OPT = {} as const;");
|
|
44
44
|
expect(src).toContain("export const ROLE = {} as const;");
|
|
45
45
|
// Still imports the SDK so the module shape is uniform.
|
|
46
46
|
expect(src).toContain("const binding = await getAppBinding();");
|
|
47
47
|
});
|
|
48
|
-
it("
|
|
49
|
-
|
|
48
|
+
it("quotes an alias that is not a valid identifier", () => {
|
|
49
|
+
const src = generatePackageAppFields({
|
|
50
|
+
fields: { "tasks.2nd_field": "fld_x" },
|
|
51
|
+
options: {},
|
|
52
|
+
roles: {},
|
|
53
|
+
});
|
|
54
|
+
expect(src).toContain('"2nd_field": bound(binding.fields, "tasks.2nd_field", "field")');
|
|
55
|
+
});
|
|
56
|
+
it("is deterministic — same binding, same bytes", () => {
|
|
57
|
+
expect(generatePackageAppFields(binding)).toBe(generatePackageAppFields(binding));
|
|
50
58
|
});
|
|
51
59
|
});
|
|
@@ -1,262 +1,46 @@
|
|
|
1
|
-
import { LoticsClient, type
|
|
2
|
-
import { type
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
28
|
-
*
|
|
29
|
-
* (the bytes ride in `source.tar.gz`, like a knowledge doc's content) — then
|
|
30
|
-
* `foldTemplateShasIntoContract` computes each `content_sha256`. This is how a
|
|
31
|
-
* CONTENT package declares standalone templates (an app package authors them in
|
|
32
|
-
* `contract.json` directly). Round-trips through the manifest so a manifest write
|
|
33
|
-
* never drops it.
|
|
34
|
-
*/
|
|
35
|
-
interface PackageTemplateManifestEntry {
|
|
36
|
-
name: string;
|
|
37
|
-
type: PackageTemplateKind;
|
|
38
|
-
/** The template file's name within the project's `templates/` dir. */
|
|
39
|
-
file: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* The `package.json#lotics.package` block of a package project. `id` is null
|
|
43
|
-
* until the first publish (which creates the registry package); `version` tracks
|
|
44
|
-
* the latest version this project has published; `dev` maps a dev workspace id to
|
|
45
|
-
* the installation it scaffold-syncs into.
|
|
46
|
-
*/
|
|
47
|
-
/** A package project's kind — mirrors the registry `packages.kind` (immutable after create). */
|
|
48
|
-
export type PackageKind = "app" | "content";
|
|
49
|
-
interface PackageManifest {
|
|
50
|
-
id: string | null;
|
|
51
|
-
name: string;
|
|
52
|
-
description: string | null;
|
|
53
|
-
/**
|
|
54
|
-
* 'app' (the full materialized blueprint) | 'content' (a standalone content
|
|
55
|
-
* package). Threaded to `createPackage` on first publish and used locally to
|
|
56
|
-
* gate the build (a content package has no app source to compile). Defaults to
|
|
57
|
-
* 'app' for a manifest written before content packaging.
|
|
58
|
-
*/
|
|
59
|
-
kind: PackageKind;
|
|
60
|
-
version: number | null;
|
|
61
|
-
/** alias → knowledge-doc authoring metadata (content in `knowledge/<alias>.md`). */
|
|
62
|
-
knowledge: Record<string, PackageKnowledgeManifestEntry>;
|
|
63
|
-
/** alias → document-template authoring metadata (file in `templates/<file>`). */
|
|
64
|
-
templates: Record<string, PackageTemplateManifestEntry>;
|
|
65
|
-
/**
|
|
66
|
-
* Doc NAMES the package's agents route to but the package does not own —
|
|
67
|
-
* install/health WARN when a name has no doc in the workspace. Lives under
|
|
68
|
-
* `lotics.package` (one coherent home for everything package-related), NOT a
|
|
69
|
-
* sibling of it.
|
|
70
|
-
*/
|
|
71
|
-
knowledge_expects: string[];
|
|
72
|
-
dev: Record<string, PackageDevInstallation>;
|
|
73
|
-
}
|
|
74
|
-
interface PackageProjectFile {
|
|
75
|
-
/** Parsed package.json, carrying the `lotics.package` manifest under `lotics`. */
|
|
76
|
-
pkgJson: Record<string, unknown>;
|
|
77
|
-
manifest: PackageManifest;
|
|
78
|
-
}
|
|
79
|
-
/** Read the package project's manifest, failing loud when the dir isn't one. */
|
|
80
|
-
export declare function readPackageProject(projectDir: string): PackageProjectFile;
|
|
81
|
-
/** Persist an updated manifest back into the project's package.json (atomic write). */
|
|
82
|
-
export declare function writePackageManifest(projectDir: string, project: PackageProjectFile): void;
|
|
83
|
-
/**
|
|
84
|
-
* The package.json to ship INSIDE `source.tar.gz`: the on-disk manifest with the
|
|
85
|
-
* author-local `lotics.package.dev` map stripped. `dev` is the author's private
|
|
86
|
-
* dev-workspace → installation bookkeeping; it must never reach a consumer (every
|
|
87
|
-
* install carries the source, and `lotics app pull` ejects it). Returns a
|
|
88
|
-
* sanitized copy — the on-disk package.json is left untouched. `id`/`name`/
|
|
89
|
-
* `description`/`version` are the package's stable identity and stay.
|
|
90
|
-
*/
|
|
91
|
-
export declare function sanitizePackageJsonForSource(pkgJson: Record<string, unknown>): Record<string, unknown>;
|
|
92
|
-
/**
|
|
93
|
-
* Transform an app project's package.json (the source archive `lotics app pull`
|
|
94
|
-
* downloads, carrying the `lotics.app_id`/`workspace_id` app manifest) into a
|
|
95
|
-
* package project's `PackageProjectFile`: the app manifest is stripped ENTIRELY
|
|
96
|
-
* and a fresh, unpublished `lotics.package` manifest (id/version null) is
|
|
97
|
-
* grafted. Pure — returns a new value, never mutates the input;
|
|
98
|
-
* `writePackageManifest` writes it (atomic). The bespoke→package promotion's
|
|
99
|
-
* manifest inversion.
|
|
100
|
-
*/
|
|
101
|
-
export declare function draftPackageProjectFromApp(appPkgJson: Record<string, unknown>, args: {
|
|
102
|
-
name: string;
|
|
103
|
-
description: string | null;
|
|
104
|
-
}): PackageProjectFile;
|
|
105
|
-
/**
|
|
106
|
-
* Parse + validate `.lotics/adopt_binding.json` against the app being adopted.
|
|
107
|
-
* REFUSES a pin recorded for a different app: a binding maps ONE workspace's
|
|
108
|
-
* concrete ids, so replaying it onto another app would bind the wrong objects.
|
|
109
|
-
* Pure; the CLI never interprets the binding, only round-trips it to the server.
|
|
110
|
-
*/
|
|
111
|
-
export declare function parseAdoptBindingFile(raw: unknown, expectedAppId: string): {
|
|
112
|
-
app_id: string;
|
|
113
|
-
workspace_id: string;
|
|
114
|
-
binding: PackageBinding;
|
|
115
|
-
knowledge_binding: Record<string, string>;
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* Render an extraction report grouped by severity (errors, then warnings, then
|
|
119
|
-
* info), one ` [<severity>] <area>: <message>` line each, and classify whether
|
|
120
|
-
* any `error` finding is present. An `error` ⇒ the draft is not publishable
|
|
121
|
-
* as-is, so `lotics package extract` exits non-zero. Pure — the command prints
|
|
122
|
-
* `lines` to stderr and gates on `hasError`.
|
|
1
|
+
import { LoticsClient, type ExtractFinding } from "./client.js";
|
|
2
|
+
import { type UpgradeResolutions } from "@lotics/shared/schemas/packages";
|
|
3
|
+
/**
|
|
4
|
+
* Read the local APP project's manifest (`package.json#lotics.app_id` +
|
|
5
|
+
* `lotics.knowledge`) — what `lotics app pull` writes. `lotics app publish` /
|
|
6
|
+
* `release` run from a pulled app project resolve the app id from it, and
|
|
7
|
+
* `publish` forwards the package-managed knowledge declaration to the server
|
|
8
|
+
* (agents reference docs by free text, so the author declares which the package
|
|
9
|
+
* owns). Returns null when the dir has no package.json. `app_id` is null when the
|
|
10
|
+
* manifest is a package/non-app project.
|
|
11
|
+
*/
|
|
12
|
+
export declare function readLocalAppManifest(projectDir: string): {
|
|
13
|
+
app_id: string | null;
|
|
14
|
+
knowledge: Array<{
|
|
15
|
+
alias: string;
|
|
16
|
+
doc_id: string;
|
|
17
|
+
}>;
|
|
18
|
+
} | null;
|
|
19
|
+
/** Parse repeated `--rename old=new` flags into `{ from, to }[]` (first-publish alias fixes). */
|
|
20
|
+
export declare function parseRenameFlags(renames: string[]): Array<{
|
|
21
|
+
from: string;
|
|
22
|
+
to: string;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Render a package-extract report grouped by severity (errors, then warnings,
|
|
26
|
+
* then info), one ` [<severity>] <area>: <message>` line each, and classify
|
|
27
|
+
* whether any `error` finding is present. Shared by the release preview display.
|
|
28
|
+
* Pure — the command prints `lines` to stderr and gates on `hasError`.
|
|
123
29
|
*/
|
|
124
30
|
export declare function formatExtractReport(report: ExtractFinding[]): {
|
|
125
31
|
lines: string[];
|
|
126
32
|
hasError: boolean;
|
|
127
33
|
};
|
|
128
34
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* contract.json. The content files themselves ride in `source.tar.gz`
|
|
137
|
-
* automatically: `knowledge/` is a top-level dir, so `stagePackageSource` copies
|
|
138
|
-
* it like any other source (the same mechanism that carries template bytes). Pure
|
|
139
|
-
* w.r.t. `contract` — returns a new object; the server re-validates the folded
|
|
140
|
-
* namespace at publish.
|
|
141
|
-
*/
|
|
142
|
-
export declare function foldKnowledgeIntoContract(projectDir: string, project: PackageProjectFile, contract: Record<string, unknown>): Record<string, unknown>;
|
|
143
|
-
/**
|
|
144
|
-
* Fold a CONTENT package's manifest-declared templates into its contract before
|
|
145
|
-
* publish: per `lotics.package.templates` alias, an INLINE kind (html/email) reads
|
|
146
|
-
* `templates/<file>` into the contract template's `content`; a FILE-BACKED kind
|
|
147
|
-
* (excel/word/pdf-form) records `bytes_ref: templates/<file>` (the bytes ride in
|
|
148
|
-
* `source.tar.gz` — `templates/` is a top-level dir `stagePackageSource` copies,
|
|
149
|
-
* the same mechanism that carries knowledge content + app-package template bytes).
|
|
150
|
-
* The per-template `content_sha256` is NOT computed here — `foldTemplateShasIntoContract`
|
|
151
|
-
* runs after and derives it (inline: the utf-8 content; file-backed: the file bytes).
|
|
152
|
-
*
|
|
153
|
-
* Appends to any templates the contract already declares (an app package authors
|
|
154
|
-
* templates in `contract.json` directly; the manifest path is how a content
|
|
155
|
-
* package — with no `contract.json` templates — declares them). An alias in BOTH
|
|
156
|
-
* is a loud error. Pure w.r.t. `contract` — returns a new object.
|
|
157
|
-
*/
|
|
158
|
-
export declare function foldTemplatesIntoContract(projectDir: string, project: PackageProjectFile, contract: unknown): Record<string, unknown>;
|
|
159
|
-
/**
|
|
160
|
-
* Fold a freshly-computed `content_sha256` into every template of a package
|
|
161
|
-
* contract before publish — the modified-detection reference the install/upgrade
|
|
162
|
-
* flow compares live content against. Like knowledge's sha (foldKnowledge…), it
|
|
163
|
-
* can't be hand-authored: an INLINE template's sha covers its utf-8 `content`; a
|
|
164
|
-
* FILE-BACKED template's sha covers the `bytes_ref` file's bytes (the same bytes
|
|
165
|
-
* that ride in `source.tar.gz` and install stores verbatim). Always recomputed
|
|
166
|
-
* (never trusted from contract.json), so the published contract's sha is exact.
|
|
167
|
-
* Pure w.r.t. `contract` — returns a new object; the server re-validates.
|
|
168
|
-
*/
|
|
169
|
-
export declare function foldTemplateShasIntoContract(projectDir: string, contract: Record<string, unknown>): Record<string, unknown>;
|
|
170
|
-
/**
|
|
171
|
-
* Copy the project's source tree into `sourceStage` with explicit TOP-LEVEL
|
|
172
|
-
* excludes, writing a sanitized `package.json` in place of the on-disk one.
|
|
173
|
-
* Deliberately not tar `--exclude` flags: those match at any depth (a nested
|
|
174
|
-
* `templates/dist/` would be silently dropped) and GNU tar vs bsdtar (macOS)
|
|
175
|
-
* disagree on `./`-prefixed patterns, which broke the sanitized-package.json
|
|
176
|
-
* graft on macOS.
|
|
177
|
-
*/
|
|
178
|
-
export declare function stagePackageSource(projectDir: string, sourceStage: string): void;
|
|
179
|
-
/** The minimal, valid starting contract a `package new` scaffold ships. */
|
|
180
|
-
export declare function starterContract(name: string): Record<string, unknown>;
|
|
181
|
-
/**
|
|
182
|
-
* `lotics package new <name> [path] [--kind content]` — scaffold a package
|
|
183
|
-
* project. An `app` package reuses the app starter (Vite+React+TS) for the code
|
|
184
|
-
* surface, swaps its app manifest for a package manifest, and adds a starter
|
|
185
|
-
* `contract.json`; a `content` package scaffolds a docs-only corpus (no app
|
|
186
|
-
* source). The project publishes with `lotics package publish`.
|
|
187
|
-
*/
|
|
188
|
-
export declare function packageNew(args: {
|
|
189
|
-
name: string;
|
|
190
|
-
targetPath?: string;
|
|
191
|
-
kind?: PackageKind;
|
|
192
|
-
}): Promise<void>;
|
|
193
|
-
/**
|
|
194
|
-
* `lotics package build [path]` — build the publishable bundle and write it to
|
|
195
|
-
* `bundle.tar.gz` in the project. Mostly a local sanity check / CI artifact;
|
|
196
|
-
* `publish` and `dev`/`sync` build the bundle in memory directly.
|
|
197
|
-
*/
|
|
198
|
-
export declare function packageBuild(args: {
|
|
199
|
-
projectDir?: string;
|
|
200
|
-
}): Promise<void>;
|
|
201
|
-
/**
|
|
202
|
-
* `lotics package publish [path] [-m <changelog>]` — publish a new version.
|
|
203
|
-
*/
|
|
204
|
-
export declare function packagePublish(client: LoticsClient, args: {
|
|
205
|
-
projectDir?: string;
|
|
206
|
-
changelog?: string;
|
|
207
|
-
}): Promise<void>;
|
|
208
|
-
/**
|
|
209
|
-
* Fail loud unless `workspace` is a throwaway dev workspace. The dev/sync
|
|
210
|
-
* scaffold path publishes a new version and scaffold-installs package tables into
|
|
211
|
-
* the resolved workspace, so the target MUST be a dev workspace — this mirrors
|
|
212
|
-
* the server-side `package reset` gate so a forgotten `--workspace` (prod
|
|
213
|
-
* selected) can never scaffold package tables into prod. Fails closed: an absent
|
|
214
|
-
* `is_dev` (a server that doesn't yet serialize it) is treated as non-dev.
|
|
215
|
-
*/
|
|
216
|
-
export declare function assertDevWorkspace(workspace: {
|
|
217
|
-
id: string;
|
|
218
|
-
name: string;
|
|
219
|
-
is_dev?: boolean;
|
|
220
|
-
}): void;
|
|
221
|
-
/**
|
|
222
|
-
* `lotics package sync [path]` — re-run the scaffold-sync into the dev workspace
|
|
223
|
-
* (the continuous loop: edit contract → sync additively migrates + re-materializes).
|
|
224
|
-
*/
|
|
225
|
-
export declare function packageSync(client: LoticsClient, args: {
|
|
226
|
-
projectDir?: string;
|
|
227
|
-
}): Promise<void>;
|
|
228
|
-
/**
|
|
229
|
-
* `lotics package dev [path] [--workspace <dev_ws>] [--view-as <member>]` —
|
|
230
|
-
* scaffold-sync the package into the dev workspace, then run the existing app
|
|
231
|
-
* dev server against the resulting installation (HMR over the local source, RPC
|
|
232
|
-
* forwarded to the live installation). The inner loop: edit contract → re-run to
|
|
233
|
-
* sync; edit code → hot reload.
|
|
234
|
-
*/
|
|
235
|
-
export declare function packageDev(client: LoticsClient, args: {
|
|
236
|
-
projectDir?: string;
|
|
237
|
-
port?: number;
|
|
238
|
-
vitePort?: number;
|
|
239
|
-
}): Promise<void>;
|
|
240
|
-
/**
|
|
241
|
-
* `lotics package reset [path]` — DEV-ONLY, hard-gated. Drops the dev
|
|
242
|
-
* installation's package-owned scaffolded tables and re-scaffolds them clean. The
|
|
243
|
-
* backend refuses any workspace not flagged as a dev workspace, so this can never
|
|
244
|
-
* erase a real workspace's data. The dev installation is resolved from the
|
|
245
|
-
* project manifest's pin for the selected workspace.
|
|
246
|
-
*/
|
|
247
|
-
export declare function packageReset(client: LoticsClient, args: {
|
|
248
|
-
projectDir?: string;
|
|
249
|
-
}): Promise<void>;
|
|
250
|
-
export type UpgradeResolutionValue = "recreate" | "revert" | "keep" | {
|
|
251
|
-
bind_to: string;
|
|
252
|
-
};
|
|
253
|
-
/**
|
|
254
|
-
* Parse repeated `--resolve <key>=<value>` flags. Drift entries
|
|
255
|
-
* (`<namespace>.<alias>`) take `recreate` or an existing id; modified
|
|
256
|
-
* artifacts (`<kind>.<alias>`) take `revert` or `keep`. Any other value is a
|
|
257
|
-
* bind_to id; the server validates value-kind against what the key resolves.
|
|
35
|
+
* Parse repeated `--resolve <key>=<value>` flags into the ONE namespaced
|
|
36
|
+
* resolutions map every upgrade wire takes. Keys pass through verbatim — a
|
|
37
|
+
* drifted binding entry (`<namespace>.<alias>`), a modified artifact
|
|
38
|
+
* (`<kind>.<alias>`), a bundled/standalone knowledge doc (`knowledge.<alias>`),
|
|
39
|
+
* or a live-role re-point (`roles.<alias>`). A value that is one of the
|
|
40
|
+
* resolution verbs stays a verb; anything else is a `{ bind_to }` id. The
|
|
41
|
+
* server validates value-kind against what each key resolves.
|
|
258
42
|
*/
|
|
259
|
-
export declare function parseResolveFlags(resolve: string[]):
|
|
43
|
+
export declare function parseResolveFlags(resolve: string[]): UpgradeResolutions;
|
|
260
44
|
/**
|
|
261
45
|
* Health check: version pin vs. registry latest + binding drift. Exits
|
|
262
46
|
* non-zero when drift is found so scripts can gate on it.
|
|
@@ -270,11 +54,13 @@ export declare function packageDoctor(client: LoticsClient, args: {
|
|
|
270
54
|
* the exact --resolve syntax) while any binding drift, modified core artifact, or
|
|
271
55
|
* consent-requiring bundled-knowledge doc lacks a resolution.
|
|
272
56
|
*
|
|
273
|
-
* `--resolve`
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
57
|
+
* `--resolve` speaks ONE namespaced grammar, passed to the server verbatim: a
|
|
58
|
+
* drifted binding entry (`<namespace>.<alias>`), a modified artifact
|
|
59
|
+
* (`<kind>.<alias>`), a bundled knowledge doc (`knowledge.<alias>` —
|
|
60
|
+
* apply|keep|archive|recreate|unbind), or a live-role re-point
|
|
61
|
+
* (`roles.<alias>=<grp_id>`). `--bind-to` consents an added-knowledge-doc name
|
|
62
|
+
* collision; `--apply-all` accepts the package's version for every
|
|
63
|
+
* consent-requiring knowledge doc (overwriting local edits).
|
|
278
64
|
*/
|
|
279
65
|
export declare function packageUpgrade(client: LoticsClient, args: {
|
|
280
66
|
app_id: string;
|
|
@@ -293,50 +79,28 @@ export declare function packageShow(client: LoticsClient, args: {
|
|
|
293
79
|
package_id: string;
|
|
294
80
|
}): Promise<void>;
|
|
295
81
|
/**
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
* `<kind>.<alias>` modified core, or a key the server validates). A key that is
|
|
303
|
-
* BOTH a knowledge alias and a core-artifact key is ambiguous — throw rather than
|
|
304
|
-
* guess which the operator meant.
|
|
305
|
-
*/
|
|
306
|
-
export declare function routeAppUpgradeResolve(resolve: string[], knowledgeEntries: KnowledgeUpgradeEntry[], coreKeys: ReadonlySet<string>): {
|
|
307
|
-
coreResolve: string[];
|
|
308
|
-
knowledgeResolutions: Record<string, KnowledgeResolution>;
|
|
309
|
-
};
|
|
310
|
-
/**
|
|
311
|
-
* Route a STANDALONE content upgrade's shared `--resolve <alias>=<value>` flags
|
|
312
|
-
* into the knowledge vs templates buckets by matching each alias against the two
|
|
313
|
-
* preview namespaces. A doc alias takes apply|keep|archive|recreate|unbind; a
|
|
314
|
-
* template alias takes revert|keep. An alias present in BOTH namespaces is
|
|
315
|
-
* ambiguous → loud error (no guess). An alias in NEITHER → error. The value is
|
|
316
|
-
* validated against the namespace it routes to. Exported for testing.
|
|
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.
|
|
317
88
|
*/
|
|
318
|
-
export declare function
|
|
319
|
-
knowledge: Record<string, KnowledgeResolution>;
|
|
320
|
-
templates: Record<string, ModificationResolution>;
|
|
321
|
-
};
|
|
89
|
+
export declare function redirectContentPciForm(client: LoticsClient, pci_id: string, verb: "upgrade" | "uninstall"): Promise<never>;
|
|
322
90
|
/**
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
* discards local edits. `--resolve <alias>=<value>` and `--bind-to <alias>=<kdc_id>`
|
|
331
|
-
* resolve entries individually (`--resolve` is routed to the right namespace by
|
|
332
|
-
* matching the alias against the preview).
|
|
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.
|
|
333
98
|
*/
|
|
334
|
-
export declare function
|
|
335
|
-
|
|
99
|
+
export declare function packageUpgradeByPackageId(client: LoticsClient, args: {
|
|
100
|
+
package_id: string;
|
|
336
101
|
version?: number;
|
|
337
|
-
/** Raw `--resolve <alias>=<value>` flags, routed to knowledge/templates after the preview. */
|
|
338
102
|
resolve: string[];
|
|
339
|
-
|
|
103
|
+
bindTo: string[];
|
|
340
104
|
applyAll: boolean;
|
|
341
105
|
}): Promise<void>;
|
|
342
106
|
/** Parse repeated `--bind-to alias=kdc_id` flags into an alias → doc-id consent map. */
|
|
@@ -350,9 +114,11 @@ export declare function packageInstall(client: LoticsClient, args: {
|
|
|
350
114
|
config?: Record<string, string | number | boolean>;
|
|
351
115
|
}): Promise<void>;
|
|
352
116
|
/**
|
|
353
|
-
* `lotics
|
|
354
|
-
* kinds, dispatched by the id form (mirrors `
|
|
355
|
-
* - 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
|
|
356
122
|
* `--keep-content`) archives its package-bound docs AND templates, listing each
|
|
357
123
|
* archived id.
|
|
358
124
|
* - anything else (an `app_id`) → an APP installation: archives its workflow
|
|
@@ -366,10 +132,12 @@ export declare function packageUninstall(client: LoticsClient, args: {
|
|
|
366
132
|
archive_tables: boolean;
|
|
367
133
|
}): Promise<void>;
|
|
368
134
|
/**
|
|
369
|
-
* `lotics package list-content` — list the selected workspace's
|
|
370
|
-
* content installations (
|
|
371
|
-
*
|
|
372
|
-
*
|
|
135
|
+
* `lotics package list-content` — list the selected workspace's STANDALONE
|
|
136
|
+
* content installations (an app-bundled corpus rides its app's
|
|
137
|
+
* `binding.knowledge` and shows on the Apps surface instead), each with its
|
|
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).
|
|
373
141
|
*/
|
|
374
142
|
export declare function packageListContent(client: LoticsClient): Promise<void>;
|
|
375
143
|
export declare function packageEject(client: LoticsClient, args: {
|
|
@@ -387,38 +155,59 @@ export declare function packageConfig(client: LoticsClient, args: {
|
|
|
387
155
|
sets: string[];
|
|
388
156
|
}): Promise<void>;
|
|
389
157
|
/**
|
|
390
|
-
* `lotics
|
|
391
|
-
*
|
|
158
|
+
* `lotics app unpublish <app_id|package_id> [--undo]` — take a published package
|
|
159
|
+
* off the shelf (or `--undo` restore it): new installs refuse it and it hides
|
|
160
|
+
* from other orgs, while existing installations keep working and may still
|
|
161
|
+
* upgrade. Given an app id (an installation of the package) it resolves the
|
|
162
|
+
* package from the app; a package id targets it directly. Owner-org admin-only.
|
|
392
163
|
*/
|
|
393
|
-
export declare function
|
|
394
|
-
|
|
164
|
+
export declare function appUnpublish(client: LoticsClient, args: {
|
|
165
|
+
id: string;
|
|
395
166
|
undo: boolean;
|
|
396
167
|
}): Promise<void>;
|
|
397
|
-
export declare function packageExtract(client: LoticsClient, args: {
|
|
398
|
-
app_id: string;
|
|
399
|
-
targetPath?: string;
|
|
400
|
-
}): Promise<void>;
|
|
401
168
|
/**
|
|
402
|
-
* `lotics
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
* (
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
169
|
+
* `lotics app publish [app_id|.] [--rename old=new ...] [-m <changelog>] [--yes]` —
|
|
170
|
+
* FIRST-RELEASE a bespoke app as a package (docs/packages.md § Promotion). Nothing
|
|
171
|
+
* starts as a package. Mirrors `app release`'s preview→apply UX: it first shows the
|
|
172
|
+
* dry-run preview (GET, no writes) — the package name, the auto-minted RENAMABLE
|
|
173
|
+
* aliases (the exact `--rename` keys, so v1's frozen aliases are inspected first,
|
|
174
|
+
* never a blind publish), and the extract findings — then APPLIES only with
|
|
175
|
+
* `--yes` (else exits 1 with the re-run hint). On apply the server extracts the
|
|
176
|
+
* contract, creates the registry package, publishes v1 from the DEPLOYED source +
|
|
177
|
+
* dist, and pins the origin as installation #1. `--rename old=new` fixes an
|
|
178
|
+
* auto-minted alias before v1 freezes it; an `error` finding blocks the apply. An
|
|
179
|
+
* already-linked app releases with `lotics app release` instead. The app id is the
|
|
180
|
+
* positional (`.`/omitted → resolved from the local app project manifest).
|
|
181
|
+
*/
|
|
182
|
+
export declare function appPublish(client: LoticsClient, args: {
|
|
183
|
+
app_id?: string;
|
|
184
|
+
renames: string[];
|
|
185
|
+
changelog?: string;
|
|
186
|
+
yes: boolean;
|
|
413
187
|
projectDir?: string;
|
|
414
188
|
}): Promise<void>;
|
|
415
189
|
/**
|
|
416
|
-
* `lotics
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
190
|
+
* `lotics app release [app_id|.] -m <changelog> [--yes]` — snapshot an
|
|
191
|
+
* adopted/installed origin app into its next registry version (docs/packages.md
|
|
192
|
+
* § Promotion). The origin is the permanent working copy; a release binding-aware-
|
|
193
|
+
* extracts it (stable aliases), repackages its DEPLOYED source + dist as the
|
|
194
|
+
* bundle, publishes the next version, and re-pins the origin. Prints the preview
|
|
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).
|
|
421
204
|
*/
|
|
205
|
+
export declare function appRelease(client: LoticsClient, args: {
|
|
206
|
+
app_id?: string;
|
|
207
|
+
changelog: string;
|
|
208
|
+
yes: boolean;
|
|
209
|
+
projectDir?: string;
|
|
210
|
+
}): Promise<void>;
|
|
422
211
|
/**
|
|
423
212
|
* `lotics package yank <package_id> <version> [--undo]` — mark a published
|
|
424
213
|
* version uninstallable (or restore it). New installs/upgrades/adopts refuse a
|
|
@@ -430,8 +219,3 @@ export declare function packageYank(client: LoticsClient, args: {
|
|
|
430
219
|
version: number;
|
|
431
220
|
undo: boolean;
|
|
432
221
|
}): Promise<void>;
|
|
433
|
-
export declare function packageFleetUpgrade(client: LoticsClient, args: {
|
|
434
|
-
package_id: string;
|
|
435
|
-
version?: number;
|
|
436
|
-
}): Promise<void>;
|
|
437
|
-
export {};
|