@lotics/cli 0.76.0 → 0.76.1
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 +31 -1
- package/dist/args.d.ts +15 -2
- package/dist/args.js +21 -0
- package/dist/cli.js +82 -31
- package/dist/client.d.ts +171 -30
- package/dist/client.js +77 -32
- package/dist/package_commands.d.ts +194 -32
- package/dist/package_commands.js +846 -93
- package/dist/package_commands.test.js +354 -5
- package/dist/src/cli.js +18856 -1538
- package/package.json +1 -1
|
@@ -1,20 +1,74 @@
|
|
|
1
1
|
import { LoticsClient, type PackageBinding, type ExtractFinding } from "./client.js";
|
|
2
|
+
import { type KnowledgeUpgradeEntry, type KnowledgeResolution, type ModificationResolution } from "@lotics/shared/schemas/packages";
|
|
2
3
|
/** One dev workspace's pinned installation of this package (manifest bookkeeping). */
|
|
3
4
|
interface PackageDevInstallation {
|
|
4
5
|
app_id: string;
|
|
5
6
|
version: number;
|
|
6
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* One package-managed knowledge doc's authoring metadata, from
|
|
10
|
+
* `package.json#lotics.package.knowledge` (alias → this). The content lives in a
|
|
11
|
+
* sibling `knowledge/<alias>.md` file; `build`/`publish` sha256 the file and fold
|
|
12
|
+
* both into the contract's `knowledge` namespace. Round-trips through the manifest
|
|
13
|
+
* so a manifest write (e.g. stamping the package id on first publish) never drops
|
|
14
|
+
* it — and it therefore ships in `source.tar.gz` for eject/extract.
|
|
15
|
+
*/
|
|
16
|
+
interface PackageKnowledgeManifestEntry {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string | null;
|
|
19
|
+
active_by_default: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** The 5 document-template kinds a package template may declare (== the contract's). */
|
|
22
|
+
export type PackageTemplateKind = "html" | "email" | "excel" | "word" | "pdf-form";
|
|
23
|
+
/**
|
|
24
|
+
* One package-managed document template's authoring metadata, from
|
|
25
|
+
* `package.json#lotics.package.templates` (alias → this). The template file lives
|
|
26
|
+
* at `templates/<file>`; `build`/`publish` fold it into the contract's
|
|
27
|
+
* `templates` namespace — an inline kind (html/email) reads the file as `content`,
|
|
28
|
+
* a file-backed kind (excel/word/pdf-form) records `bytes_ref: templates/<file>`
|
|
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
|
+
}
|
|
7
41
|
/**
|
|
8
42
|
* The `package.json#lotics.package` block of a package project. `id` is null
|
|
9
43
|
* until the first publish (which creates the registry package); `version` tracks
|
|
10
44
|
* the latest version this project has published; `dev` maps a dev workspace id to
|
|
11
45
|
* the installation it scaffold-syncs into.
|
|
12
46
|
*/
|
|
47
|
+
/** A package project's kind — mirrors the registry `packages.kind` (immutable after create). */
|
|
48
|
+
export type PackageKind = "app" | "content";
|
|
13
49
|
interface PackageManifest {
|
|
14
50
|
id: string | null;
|
|
15
51
|
name: string;
|
|
16
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;
|
|
17
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[];
|
|
18
72
|
dev: Record<string, PackageDevInstallation>;
|
|
19
73
|
}
|
|
20
74
|
interface PackageProjectFile {
|
|
@@ -58,6 +112,7 @@ export declare function parseAdoptBindingFile(raw: unknown, expectedAppId: strin
|
|
|
58
112
|
app_id: string;
|
|
59
113
|
workspace_id: string;
|
|
60
114
|
binding: PackageBinding;
|
|
115
|
+
knowledge_binding: Record<string, string>;
|
|
61
116
|
};
|
|
62
117
|
/**
|
|
63
118
|
* Render an extraction report grouped by severity (errors, then warnings, then
|
|
@@ -70,6 +125,48 @@ export declare function formatExtractReport(report: ExtractFinding[]): {
|
|
|
70
125
|
lines: string[];
|
|
71
126
|
hasError: boolean;
|
|
72
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* Fold a package project's knowledge corpus into its contract before publish:
|
|
130
|
+
* per `lotics.package.knowledge` alias, read `knowledge/<alias>.md`, sha256 the
|
|
131
|
+
* bytes, and emit the contract's `knowledge` namespace (alias → {name,
|
|
132
|
+
* description, content_ref, content_sha256, active_by_default}) +
|
|
133
|
+
* `knowledge_expects` (from `lotics.package.knowledge_expects`). This is the ONE
|
|
134
|
+
* place the sha is computed — it can't be hand-authored, which is why knowledge
|
|
135
|
+
* (unlike a template `bytes_ref`) is derived rather than written into
|
|
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>;
|
|
73
170
|
/**
|
|
74
171
|
* Copy the project's source tree into `sourceStage` with explicit TOP-LEVEL
|
|
75
172
|
* excludes, writing a sanitized `package.json` in place of the on-disk one.
|
|
@@ -82,15 +179,16 @@ export declare function stagePackageSource(projectDir: string, sourceStage: stri
|
|
|
82
179
|
/** The minimal, valid starting contract a `package new` scaffold ships. */
|
|
83
180
|
export declare function starterContract(name: string): Record<string, unknown>;
|
|
84
181
|
/**
|
|
85
|
-
* `lotics package new <name> [path]` — scaffold a package
|
|
86
|
-
* app starter (Vite+React+TS) for the code
|
|
87
|
-
* package manifest, and adds a starter
|
|
88
|
-
*
|
|
89
|
-
* `lotics package
|
|
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`.
|
|
90
187
|
*/
|
|
91
188
|
export declare function packageNew(args: {
|
|
92
189
|
name: string;
|
|
93
190
|
targetPath?: string;
|
|
191
|
+
kind?: PackageKind;
|
|
94
192
|
}): Promise<void>;
|
|
95
193
|
/**
|
|
96
194
|
* `lotics package build [path]` — build the publishable bundle and write it to
|
|
@@ -167,28 +265,113 @@ export declare function packageDoctor(client: LoticsClient, args: {
|
|
|
167
265
|
app_id?: string;
|
|
168
266
|
}): Promise<void>;
|
|
169
267
|
/**
|
|
170
|
-
* Preview-then-apply upgrade. Prints the additive plan +
|
|
171
|
-
* removals; refuses (exit 1, with
|
|
172
|
-
* binding drift
|
|
268
|
+
* Preview-then-apply an app-installation upgrade. Prints the additive plan +
|
|
269
|
+
* informational removals + any bundled-knowledge changes; refuses (exit 1, with
|
|
270
|
+
* the exact --resolve syntax) while any binding drift, modified core artifact, or
|
|
271
|
+
* consent-requiring bundled-knowledge doc lacks a resolution.
|
|
272
|
+
*
|
|
273
|
+
* `--resolve` is shared across the finding classes: a key naming a bundled
|
|
274
|
+
* knowledge doc routes to `knowledge_resolutions` (apply|keep|archive|recreate|
|
|
275
|
+
* unbind), everything else to core `resolutions`; `--bind-to` consents an
|
|
276
|
+
* added-knowledge-doc name collision; `--apply-all` accepts the package's version
|
|
277
|
+
* for every consent-requiring knowledge doc (overwriting local edits).
|
|
173
278
|
*/
|
|
174
279
|
export declare function packageUpgrade(client: LoticsClient, args: {
|
|
175
280
|
app_id: string;
|
|
176
281
|
version?: number;
|
|
177
|
-
|
|
282
|
+
resolve: string[];
|
|
283
|
+
bindTo: string[];
|
|
284
|
+
applyAll: boolean;
|
|
178
285
|
}): Promise<void>;
|
|
179
286
|
/**
|
|
180
287
|
* `lotics package show <package_id>` — registry metadata + version history
|
|
181
288
|
* (trust badge, retirement, per-version channel/yank/changelog). The read
|
|
182
|
-
* surface for "what is this package and what shipped when".
|
|
289
|
+
* surface for "what is this package and what shipped when". Kind-agnostic — a
|
|
290
|
+
* content package shows here the same way.
|
|
183
291
|
*/
|
|
184
292
|
export declare function packageShow(client: LoticsClient, args: {
|
|
185
293
|
package_id: string;
|
|
186
294
|
}): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Route an app-install upgrade's `--resolve` entries into the core-artifact
|
|
297
|
+
* bucket vs the bundled-knowledge bucket. `--resolve` is shared between the two
|
|
298
|
+
* finding classes, so each key is matched against the preview: a key that names a
|
|
299
|
+
* bundled knowledge doc resolves that doc (its value validated against the doc's
|
|
300
|
+
* change class here — the app path has no separate knowledge-only parser);
|
|
301
|
+
* anything else stays a core resolution (a `<namespace>.<alias>` drift, a
|
|
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.
|
|
317
|
+
*/
|
|
318
|
+
export declare function routeContentResolveFlags(resolve: string[], knowledgeAliases: ReadonlySet<string>, templateAliases: ReadonlySet<string>): {
|
|
319
|
+
knowledge: Record<string, KnowledgeResolution>;
|
|
320
|
+
templates: Record<string, ModificationResolution>;
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Preview-then-apply a STANDALONE content installation upgrade — knowledge docs
|
|
324
|
+
* AND document templates behind one review gate. Prints the per-alias plan;
|
|
325
|
+
* refuses (exit 1, with the exact `--resolve` syntax) while any consent-requiring
|
|
326
|
+
* entry lacks a resolution — a modified knowledge change/removal or drift, or a
|
|
327
|
+
* locally-edited changed template. `--apply-all` auto-resolves EVERY consent entry
|
|
328
|
+
* by accepting the package's version (knowledge changed→apply, removed→archive,
|
|
329
|
+
* drifted→recreate; template→revert) — an explicit bulk "take upstream" that
|
|
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).
|
|
333
|
+
*/
|
|
334
|
+
export declare function packageUpgradeKnowledge(client: LoticsClient, args: {
|
|
335
|
+
installation_id: string;
|
|
336
|
+
version?: number;
|
|
337
|
+
/** Raw `--resolve <alias>=<value>` flags, routed to knowledge/templates after the preview. */
|
|
338
|
+
resolve: string[];
|
|
339
|
+
bind_to: Record<string, string>;
|
|
340
|
+
applyAll: boolean;
|
|
341
|
+
}): Promise<void>;
|
|
342
|
+
/** Parse repeated `--bind-to alias=kdc_id` flags into an alias → doc-id consent map. */
|
|
343
|
+
export declare function parseBindToFlags(bindTo: string[]): Record<string, string>;
|
|
187
344
|
export declare function packageInstall(client: LoticsClient, args: {
|
|
188
345
|
package_id: string;
|
|
189
346
|
version?: number;
|
|
347
|
+
/** Content-kind only: adopt a same-named workspace doc on a knowledge collision. */
|
|
348
|
+
bind_to?: Record<string, string>;
|
|
349
|
+
/** App-kind only: per-knob config overrides applied over the contract defaults. */
|
|
190
350
|
config?: Record<string, string | number | boolean>;
|
|
191
351
|
}): Promise<void>;
|
|
352
|
+
/**
|
|
353
|
+
* `lotics package uninstall <app_id|pci_id>` — ONE command over both installation
|
|
354
|
+
* kinds, dispatched by the id form (mirrors `package upgrade`):
|
|
355
|
+
* - a `pci_` id → a STANDALONE CONTENT installation: deletes the row and (unless
|
|
356
|
+
* `--keep-content`) archives its package-bound docs AND templates, listing each
|
|
357
|
+
* archived id.
|
|
358
|
+
* - anything else (an `app_id`) → an APP installation: archives its workflow
|
|
359
|
+
* artifacts and — with `--archive-tables` — the scaffolded entity tables
|
|
360
|
+
* (provenance- + reference-gated server-side).
|
|
361
|
+
* A flag used on the wrong path is a loud error, never silently ignored.
|
|
362
|
+
*/
|
|
363
|
+
export declare function packageUninstall(client: LoticsClient, args: {
|
|
364
|
+
id: string;
|
|
365
|
+
keep_content: boolean;
|
|
366
|
+
archive_tables: boolean;
|
|
367
|
+
}): Promise<void>;
|
|
368
|
+
/**
|
|
369
|
+
* `lotics package list-content` — list the selected workspace's package-managed
|
|
370
|
+
* content installations (standalone `pci_` corpora + app-bundled ones), each
|
|
371
|
+
* with its registry status. The read surface that surfaces a standalone `pci_` id
|
|
372
|
+
* for `upgrade` / `uninstall` (install prints it once; nothing else did before).
|
|
373
|
+
*/
|
|
374
|
+
export declare function packageListContent(client: LoticsClient): Promise<void>;
|
|
192
375
|
export declare function packageEject(client: LoticsClient, args: {
|
|
193
376
|
app_id: string;
|
|
194
377
|
}): Promise<void>;
|
|
@@ -203,15 +386,6 @@ export declare function packageConfig(client: LoticsClient, args: {
|
|
|
203
386
|
app_id: string;
|
|
204
387
|
sets: string[];
|
|
205
388
|
}): Promise<void>;
|
|
206
|
-
/**
|
|
207
|
-
* `lotics package uninstall <app_id> [--archive-tables]` — remove a package
|
|
208
|
-
* installation. Prints what will be archived (workflow artifacts, plus the
|
|
209
|
-
* scaffolded tables when the flag is set), then uninstalls.
|
|
210
|
-
*/
|
|
211
|
-
export declare function packageUninstall(client: LoticsClient, args: {
|
|
212
|
-
app_id: string;
|
|
213
|
-
archive_tables: boolean;
|
|
214
|
-
}): Promise<void>;
|
|
215
389
|
/**
|
|
216
390
|
* `lotics package retire <package_id> [--undo]` — retire (or un-retire) a
|
|
217
391
|
* registry package. Owner-org admin-only.
|
|
@@ -220,25 +394,13 @@ export declare function packageRetire(client: LoticsClient, args: {
|
|
|
220
394
|
package_id: string;
|
|
221
395
|
undo: boolean;
|
|
222
396
|
}): Promise<void>;
|
|
223
|
-
/**
|
|
224
|
-
* `lotics package extract <app_id> [path]` — promote a bespoke app to a DRAFT
|
|
225
|
-
* package project (docs/app_packages.md § Promotion). Calls the extract read,
|
|
226
|
-
* prints the findings report grouped by severity, then ALWAYS emits the draft
|
|
227
|
-
* project (a broken contract is still the reviewable starting point): the app's
|
|
228
|
-
* current source archive (same mechanics as `lotics app pull`) with the app
|
|
229
|
-
* manifest swapped for an unpublished package manifest, `contract.json`, the
|
|
230
|
-
* file-backed templates staged at their `bytes_ref` paths, and
|
|
231
|
-
* `.lotics/adopt_binding.json` (the origin pin the `adopt` step reads back).
|
|
232
|
-
* Exits non-zero when any `error` finding exists — the draft is written, but
|
|
233
|
-
* publish re-validates and nothing should ship unreviewed.
|
|
234
|
-
*/
|
|
235
397
|
export declare function packageExtract(client: LoticsClient, args: {
|
|
236
398
|
app_id: string;
|
|
237
399
|
targetPath?: string;
|
|
238
400
|
}): Promise<void>;
|
|
239
401
|
/**
|
|
240
402
|
* `lotics package adopt <app_id> [path]` — bind the published package project
|
|
241
|
-
* onto the origin app (docs/
|
|
403
|
+
* onto the origin app (docs/packages.md § Promotion). Reads the project
|
|
242
404
|
* manifest (must be published — refuses otherwise), resolves the version
|
|
243
405
|
* (`--version N` else the manifest's), and reads `.lotics/adopt_binding.json`,
|
|
244
406
|
* REFUSING a pin recorded for a different app. On success the app becomes
|