@lotics/cli 0.86.1 → 0.87.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 +0 -78
- package/dist/args.d.ts +0 -39
- package/dist/args.js +2 -83
- package/dist/args.test.js +0 -49
- package/dist/cli.js +1 -283
- package/dist/cli_dispatch.test.js +43 -109
- package/dist/client.d.ts +34 -13
- package/dist/client.js +18 -12
- package/dist/src/cli.js +1620 -19314
- package/package.json +1 -1
- package/dist/package_commands.d.ts +0 -221
- package/dist/package_commands.js +0 -1007
- package/dist/package_commands.test.d.ts +0 -1
- package/dist/package_commands.test.js +0 -309
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Dispatch smoke test over the BUILT CLI artifact
|
|
3
|
-
* the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* positional conventions (top-level verbs read the id from `subcommand`; the
|
|
9
|
-
* `package` family from `toolArgs`), and nothing else tests it: `package yank`
|
|
10
|
-
* shipped dispatched inside the WORKSPACE family and surfaced only on the first
|
|
11
|
-
* live invocation.
|
|
2
|
+
* Dispatch smoke test over the BUILT public CLI artifact, focused on the
|
|
3
|
+
* build-vs-operate split: the packages distribution surface moved WHOLESALE to
|
|
4
|
+
* the private operator CLI (`packages/opctl`), and the public CLI keeps ZERO
|
|
5
|
+
* knowledge of it — every removed verb must fall through to the plain
|
|
6
|
+
* unknown-command refusal (no redirect, no hint), while the build surface
|
|
7
|
+
* (app/workspace/run/upload) keeps routing.
|
|
12
8
|
*
|
|
13
9
|
* The fake API key satisfies `requireClient` (client construction is offline);
|
|
14
|
-
* every asserted path exits before any network call.
|
|
15
|
-
* temp cwd so path-defaulting subcommands fail on the missing project file —
|
|
16
|
-
* which equally proves their dispatch reached the right handler.
|
|
10
|
+
* every asserted path exits before any network call.
|
|
17
11
|
*/
|
|
18
12
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
19
13
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
@@ -30,9 +24,6 @@ function runCli(args) {
|
|
|
30
24
|
env: {
|
|
31
25
|
...process.env,
|
|
32
26
|
LOTICS_API_KEY: "ltk_dispatch_smoke_fake_key_never_used_on_wire",
|
|
33
|
-
// A pinned (fake) workspace skips the pre-dispatch auto-resolution,
|
|
34
|
-
// which would otherwise hit the network (`listWorkspaces`) before any
|
|
35
|
-
// usage gate. Nothing below ever reaches the wire.
|
|
36
27
|
LOTICS_WORKSPACE: "wsp_dispatch_smoke_fake",
|
|
37
28
|
LOTICS_ORG: "",
|
|
38
29
|
},
|
|
@@ -42,114 +33,57 @@ function runCli(args) {
|
|
|
42
33
|
return { status: result.status, stderr: result.stderr ?? "" };
|
|
43
34
|
}
|
|
44
35
|
beforeAll(() => {
|
|
45
|
-
// Bundle the real artifact from src (esbuild only —
|
|
46
|
-
//
|
|
36
|
+
// Bundle the real artifact from src (esbuild only — vitest's transform is
|
|
37
|
+
// already type-agnostic). ~1s.
|
|
47
38
|
execFileSync(process.execPath, ["scripts/build_cli.mjs"], { cwd: packageRoot });
|
|
48
39
|
}, 120_000);
|
|
49
|
-
describe("
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// Folded into the upgrade grammar — the removed verb must redirect loudly.
|
|
58
|
-
["rebind-role", /folded into the upgrade grammar[\s\S]*--resolve roles\./],
|
|
59
|
-
];
|
|
60
|
-
for (const [sub, usage] of usageCases) {
|
|
61
|
-
it(`routes "package ${sub}" to its handler (usage on missing args)`, () => {
|
|
62
|
-
const { status, stderr } = runCli(["package", sub]);
|
|
63
|
-
expect(stderr).toMatch(usage);
|
|
64
|
-
expect(stderr).not.toMatch(/Unknown package subcommand/);
|
|
40
|
+
describe("removed packages surface — unknown commands, zero knowledge", () => {
|
|
41
|
+
// The whole distribution surface lives in opctl now. The public CLI treats
|
|
42
|
+
// the old verbs as any other unknown command — no "moved to opctl" hint.
|
|
43
|
+
for (const verb of ["install", "uninstall", "upgrade", "package"]) {
|
|
44
|
+
it(`rejects "${verb}" as an unknown command`, () => {
|
|
45
|
+
const { status, stderr } = runCli([verb, "apg_x"]);
|
|
46
|
+
expect(stderr).toMatch(new RegExp(`Unknown command: ${verb}`));
|
|
47
|
+
expect(stderr).not.toMatch(/opctl/);
|
|
65
48
|
expect(status).toBe(1);
|
|
66
49
|
});
|
|
67
50
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
["uninstall", /moved to the top level.*lotics uninstall/],
|
|
74
|
-
["upgrade", /moved to the top level.*lotics upgrade/],
|
|
75
|
-
["fleet-upgrade", /moved to the top level.*lotics upgrade <package_id>/],
|
|
76
|
-
];
|
|
77
|
-
for (const [sub, redirect] of movedForms) {
|
|
78
|
-
it(`rejects the moved "package ${sub}" form with a top-level redirect`, () => {
|
|
79
|
-
const { status, stderr } = runCli(["package", sub]);
|
|
80
|
-
expect(stderr).toMatch(redirect);
|
|
51
|
+
for (const sub of ["publish", "release", "unpublish"]) {
|
|
52
|
+
it(`rejects "app ${sub}" as an unknown app subcommand`, () => {
|
|
53
|
+
const { status, stderr } = runCli(["app", sub]);
|
|
54
|
+
expect(stderr).toMatch(/Unknown app subcommand/);
|
|
55
|
+
expect(stderr).not.toMatch(/opctl/);
|
|
81
56
|
expect(status).toBe(1);
|
|
82
57
|
});
|
|
83
58
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
it(`rejects the removed "package ${sub}" subcommand`, () => {
|
|
90
|
-
const { status, stderr } = runCli(["package", sub]);
|
|
91
|
-
expect(stderr).toMatch(/Unknown package subcommand/);
|
|
92
|
-
expect(status).toBe(1);
|
|
59
|
+
it("keeps --help free of package verbs", () => {
|
|
60
|
+
const result = spawnSync(process.execPath, [cliBin, "--help"], {
|
|
61
|
+
cwd: emptyCwd,
|
|
62
|
+
encoding: "utf-8",
|
|
63
|
+
timeout: 30_000,
|
|
93
64
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
expect(
|
|
98
|
-
expect(
|
|
65
|
+
const help = `${result.stdout}\n${result.stderr}`;
|
|
66
|
+
expect(help).not.toMatch(/opctl/);
|
|
67
|
+
expect(help).not.toMatch(/lotics install/);
|
|
68
|
+
expect(help).not.toMatch(/lotics package/);
|
|
69
|
+
expect(help).not.toMatch(/app publish/);
|
|
99
70
|
});
|
|
100
71
|
});
|
|
101
|
-
describe("
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const usageCases = [
|
|
106
|
-
["install", /Usage: lotics install <package_id>/],
|
|
107
|
-
["uninstall", /Usage: lotics uninstall <app_id\|package_id>/],
|
|
108
|
-
["upgrade", /Usage: lotics upgrade <app_id \| package_id>/],
|
|
109
|
-
];
|
|
110
|
-
for (const [verb, usage] of usageCases) {
|
|
111
|
-
it(`routes top-level "${verb}" to its handler (usage on missing id)`, () => {
|
|
112
|
-
const { status, stderr } = runCli([verb]);
|
|
113
|
-
expect(stderr).toMatch(usage);
|
|
114
|
-
expect(stderr).not.toMatch(/Unknown command/);
|
|
115
|
-
expect(status).toBe(1);
|
|
116
|
-
});
|
|
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
|
-
}
|
|
131
|
-
});
|
|
132
|
-
describe("lotics app author-verb dispatch", () => {
|
|
133
|
-
// `app publish` (no id, empty cwd) must fail on the missing local app
|
|
134
|
-
// manifest — its handler's message, proving routing without any network.
|
|
135
|
-
it('routes "app publish" to its handler (no app id in empty cwd)', () => {
|
|
136
|
-
const { status, stderr } = runCli(["app", "publish"]);
|
|
137
|
-
expect(stderr).toMatch(/No app id/);
|
|
138
|
-
expect(stderr).not.toMatch(/Unknown app subcommand/);
|
|
72
|
+
describe("build surface keeps routing", () => {
|
|
73
|
+
it('routes "app deploy" to its handler (usage on missing -m)', () => {
|
|
74
|
+
const { status, stderr } = runCli(["app", "deploy"]);
|
|
75
|
+
expect(stderr).toMatch(/Usage: lotics app deploy/);
|
|
139
76
|
expect(status).toBe(1);
|
|
140
77
|
});
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
expect(stderr).toMatch(/
|
|
145
|
-
expect(stderr).not.toMatch(/Unknown app subcommand/);
|
|
78
|
+
it('routes "download" to its usage gate', () => {
|
|
79
|
+
const { status, stderr } = runCli(["download"]);
|
|
80
|
+
expect(stderr).toMatch(/Usage:/);
|
|
81
|
+
expect(stderr).toMatch(/lotics download <file_id>/);
|
|
146
82
|
expect(status).toBe(1);
|
|
147
83
|
});
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
expect(stderr).toMatch(/Usage: lotics app unpublish/);
|
|
152
|
-
expect(stderr).not.toMatch(/Unknown app subcommand/);
|
|
84
|
+
it('routes "run" to its usage gate', () => {
|
|
85
|
+
const { status, stderr } = runCli(["run"]);
|
|
86
|
+
expect(stderr).toMatch(/Usage: lotics run <tool>/);
|
|
153
87
|
expect(status).toBe(1);
|
|
154
88
|
});
|
|
155
89
|
});
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { KnowledgeUpgradeEntry, ModifiedArtifact, PackageContentBinding, UpgradeResolutions } from "@lotics/shared/schemas/packages";
|
|
1
|
+
import type { ContractConfigEntry, KnowledgeUpgradeEntry, ModifiedArtifact, PackageContentBinding, UpgradeResolutions } from "@lotics/shared/schemas/packages";
|
|
2
2
|
/**
|
|
3
3
|
* The error message for a non-ok response. A genuine JSON error (a 4xx carrying
|
|
4
4
|
* a `message`) surfaces verbatim; a non-JSON body (a gateway HTML page), any
|
|
@@ -246,7 +246,7 @@ export declare class LoticsClient {
|
|
|
246
246
|
/**
|
|
247
247
|
* Uninstall a standalone content package — delete the installation row. By
|
|
248
248
|
* default the package-bound docs are ARCHIVED; `keep_content` retains them as
|
|
249
|
-
* ordinary workspace docs. Admin-only. Backs `
|
|
249
|
+
* ordinary workspace docs. Admin-only. Backs `opctl uninstall`.
|
|
250
250
|
*/
|
|
251
251
|
uninstallContentPackage(installation_id: string, opts?: {
|
|
252
252
|
keep_content?: boolean;
|
|
@@ -300,7 +300,7 @@ export declare class LoticsClient {
|
|
|
300
300
|
} | null;
|
|
301
301
|
}>>;
|
|
302
302
|
/**
|
|
303
|
-
* Uninstall a package installation (backs `
|
|
303
|
+
* Uninstall a package installation (backs `opctl uninstall`). Does
|
|
304
304
|
* everything DELETE does plus archives the installation's lifecycle
|
|
305
305
|
* artifacts; with `archive_tables` it also archives the scaffolded entity
|
|
306
306
|
* tables — refused server-side unless this installation created them
|
|
@@ -314,7 +314,7 @@ export declare class LoticsClient {
|
|
|
314
314
|
archived_table_ids: string[];
|
|
315
315
|
}>;
|
|
316
316
|
/**
|
|
317
|
-
* Partial-merge a package installation's config (backs `
|
|
317
|
+
* Partial-merge a package installation's config (backs `opctl package config
|
|
318
318
|
* --set`). Only the provided keys change; validated against the installed
|
|
319
319
|
* contract. Returns the full effective config. Admin-only.
|
|
320
320
|
*/
|
|
@@ -355,13 +355,13 @@ export declare class LoticsClient {
|
|
|
355
355
|
* org to the target version (latest when omitted) in one call. Hands-off
|
|
356
356
|
* applies only where the preview is clean; installations with breaking/
|
|
357
357
|
* drift/modified-core findings are skipped and reported for the normal
|
|
358
|
-
* per-installation consent flow. Backs `
|
|
358
|
+
* per-installation consent flow. Backs `opctl upgrade <package_id>` (fleet).
|
|
359
359
|
* Admin-only; org-scoped (no workspace header needed).
|
|
360
360
|
*/
|
|
361
361
|
/**
|
|
362
362
|
* Yank / unyank a published package version — refuses NEW installs/upgrades/
|
|
363
363
|
* adopts targeting it; pinned installations keep running. Owner-org
|
|
364
|
-
* admin-only. Backs `
|
|
364
|
+
* admin-only. Backs `opctl package yank`.
|
|
365
365
|
*/
|
|
366
366
|
yankPackageVersion(package_id: string, version: number, yanked: boolean): Promise<{
|
|
367
367
|
package_id: string;
|
|
@@ -385,6 +385,7 @@ export declare class LoticsClient {
|
|
|
385
385
|
breaking: number;
|
|
386
386
|
drift: number;
|
|
387
387
|
modified: number;
|
|
388
|
+
knowledge: number;
|
|
388
389
|
};
|
|
389
390
|
message?: string;
|
|
390
391
|
}>;
|
|
@@ -406,7 +407,7 @@ export declare class LoticsClient {
|
|
|
406
407
|
created_at: string;
|
|
407
408
|
updated_at: string;
|
|
408
409
|
}>;
|
|
409
|
-
/** Version history newest-first (no contract payloads) — backs `
|
|
410
|
+
/** Version history newest-first (no contract payloads) — backs `opctl package show`. Admin-only. */
|
|
410
411
|
listPackageVersions(package_id: string): Promise<{
|
|
411
412
|
versions: Array<{
|
|
412
413
|
version: number;
|
|
@@ -504,7 +505,7 @@ export declare class LoticsClient {
|
|
|
504
505
|
/**
|
|
505
506
|
* Health check for a package installation — version pin vs. registry latest,
|
|
506
507
|
* binding drift, and locally modified core artifacts. Read-only; backs
|
|
507
|
-
* `
|
|
508
|
+
* `opctl package doctor`. Admin-only.
|
|
508
509
|
*/
|
|
509
510
|
getPackageHealth(app_id: string): Promise<{
|
|
510
511
|
app_id: string;
|
|
@@ -540,7 +541,7 @@ export declare class LoticsClient {
|
|
|
540
541
|
missing_expected_docs: string[];
|
|
541
542
|
}>;
|
|
542
543
|
/**
|
|
543
|
-
* Preview a release — the dry run behind `
|
|
544
|
+
* Preview a release — the dry run behind `opctl app release`. Runs the
|
|
544
545
|
* binding-aware extract of the origin (aliases stable through the app's current
|
|
545
546
|
* binding) and reports the next version number, the new + changed aliases, the
|
|
546
547
|
* bundled-knowledge delta, and any extract findings (an `error` blocks the
|
|
@@ -555,6 +556,8 @@ export declare class LoticsClient {
|
|
|
555
556
|
alias: string;
|
|
556
557
|
doc_id: string;
|
|
557
558
|
}>;
|
|
559
|
+
/** Config knob declarations re-declaring the config (from the manifest). */
|
|
560
|
+
config?: ContractConfigEntry[];
|
|
558
561
|
}): Promise<{
|
|
559
562
|
package_id: string;
|
|
560
563
|
version: number;
|
|
@@ -566,6 +569,12 @@ export declare class LoticsClient {
|
|
|
566
569
|
removed: string[];
|
|
567
570
|
changed: string[];
|
|
568
571
|
};
|
|
572
|
+
/** Absent from a pre-declaration server (deploy skew) — treat as empty delta. */
|
|
573
|
+
config?: {
|
|
574
|
+
added: string[];
|
|
575
|
+
removed: string[];
|
|
576
|
+
changed: string[];
|
|
577
|
+
};
|
|
569
578
|
findings: ExtractFinding[];
|
|
570
579
|
}>;
|
|
571
580
|
/**
|
|
@@ -576,7 +585,7 @@ export declare class LoticsClient {
|
|
|
576
585
|
* bundled-knowledge set (added/dropped/re-snapshotted docs; omitted preserves
|
|
577
586
|
* the current corpus). Error findings from extract surface as a 409; a
|
|
578
587
|
* missing/archived declared doc is a 400, a foreign-package doc a 409. Admin,
|
|
579
|
-
* owning-org only. Backs `
|
|
588
|
+
* owning-org only. Backs `opctl app release --yes`.
|
|
580
589
|
*/
|
|
581
590
|
releasePackage(app_id: string, body: {
|
|
582
591
|
changelog: string;
|
|
@@ -585,6 +594,8 @@ export declare class LoticsClient {
|
|
|
585
594
|
alias: string;
|
|
586
595
|
doc_id: string;
|
|
587
596
|
}>;
|
|
597
|
+
/** Config knob declarations re-declaring the config (from the manifest). */
|
|
598
|
+
config?: ContractConfigEntry[];
|
|
588
599
|
}): Promise<{
|
|
589
600
|
package_id: string;
|
|
590
601
|
version: number;
|
|
@@ -596,9 +607,15 @@ export declare class LoticsClient {
|
|
|
596
607
|
removed: string[];
|
|
597
608
|
changed: string[];
|
|
598
609
|
};
|
|
610
|
+
/** Absent from a pre-declaration server (deploy skew) — treat as empty delta. */
|
|
611
|
+
config?: {
|
|
612
|
+
added: string[];
|
|
613
|
+
removed: string[];
|
|
614
|
+
changed: string[];
|
|
615
|
+
};
|
|
599
616
|
}>;
|
|
600
617
|
/**
|
|
601
|
-
* Dry-run preview of a first-release — the `GET` behind `
|
|
618
|
+
* Dry-run preview of a first-release — the `GET` behind `opctl app publish`
|
|
602
619
|
* (no `--yes`), the publish-side analogue of `previewPackageRelease`. The
|
|
603
620
|
* server runs the same fresh-alias extract + `src/` scan the apply runs
|
|
604
621
|
* (through any `renames`) and returns the package name it would mint, the
|
|
@@ -615,6 +632,8 @@ export declare class LoticsClient {
|
|
|
615
632
|
alias: string;
|
|
616
633
|
doc_id: string;
|
|
617
634
|
}>;
|
|
635
|
+
/** Config knob declarations v1 would freeze (from the manifest's `lotics.config`). */
|
|
636
|
+
config?: ContractConfigEntry[];
|
|
618
637
|
}): Promise<{
|
|
619
638
|
app_id: string;
|
|
620
639
|
package_name: string;
|
|
@@ -630,13 +649,13 @@ export declare class LoticsClient {
|
|
|
630
649
|
}>;
|
|
631
650
|
/**
|
|
632
651
|
* First-release apply — mint a package from a BESPOKE app and publish v1 in one
|
|
633
|
-
* call (the `POST` behind `
|
|
652
|
+
* call (the `POST` behind `opctl app publish --yes`). The server extracts an
|
|
634
653
|
* alias-keyed contract from the app (fresh aliases; `renames` fixes them before
|
|
635
654
|
* v1 freezes), creates the registry package (name/description from the app),
|
|
636
655
|
* publishes v1 from the app's deployed source + dist, and pins the origin as
|
|
637
656
|
* installation #1. Error findings from extract surface as a 409. An
|
|
638
657
|
* already-linked app must use `releasePackage` instead. Admin-only. Backs
|
|
639
|
-
* `
|
|
658
|
+
* `opctl app publish <app_id>`.
|
|
640
659
|
*/
|
|
641
660
|
publishAppAsPackage(app_id: string, body: {
|
|
642
661
|
renames?: Array<{
|
|
@@ -649,6 +668,8 @@ export declare class LoticsClient {
|
|
|
649
668
|
alias: string;
|
|
650
669
|
doc_id: string;
|
|
651
670
|
}>;
|
|
671
|
+
/** Config knob declarations v1 freezes (from the manifest's `lotics.config`). */
|
|
672
|
+
config?: ContractConfigEntry[];
|
|
652
673
|
}): Promise<{
|
|
653
674
|
package_id: string;
|
|
654
675
|
version: number;
|
package/dist/client.js
CHANGED
|
@@ -209,7 +209,7 @@ export class LoticsClient {
|
|
|
209
209
|
/**
|
|
210
210
|
* Uninstall a standalone content package — delete the installation row. By
|
|
211
211
|
* default the package-bound docs are ARCHIVED; `keep_content` retains them as
|
|
212
|
-
* ordinary workspace docs. Admin-only. Backs `
|
|
212
|
+
* ordinary workspace docs. Admin-only. Backs `opctl uninstall`.
|
|
213
213
|
*/
|
|
214
214
|
async uninstallContentPackage(installation_id, opts = {}) {
|
|
215
215
|
const qs = opts.keep_content ? "?keep_content=true" : "";
|
|
@@ -244,7 +244,7 @@ export class LoticsClient {
|
|
|
244
244
|
return this.request("GET", `/v1/workspaces/${encodeURIComponent(workspace_id)}/content-installations`);
|
|
245
245
|
}
|
|
246
246
|
/**
|
|
247
|
-
* Uninstall a package installation (backs `
|
|
247
|
+
* Uninstall a package installation (backs `opctl uninstall`). Does
|
|
248
248
|
* everything DELETE does plus archives the installation's lifecycle
|
|
249
249
|
* artifacts; with `archive_tables` it also archives the scaffolded entity
|
|
250
250
|
* tables — refused server-side unless this installation created them
|
|
@@ -254,7 +254,7 @@ export class LoticsClient {
|
|
|
254
254
|
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/uninstall`, body);
|
|
255
255
|
}
|
|
256
256
|
/**
|
|
257
|
-
* Partial-merge a package installation's config (backs `
|
|
257
|
+
* Partial-merge a package installation's config (backs `opctl package config
|
|
258
258
|
* --set`). Only the provided keys change; validated against the installed
|
|
259
259
|
* contract. Returns the full effective config. Admin-only.
|
|
260
260
|
*/
|
|
@@ -286,13 +286,13 @@ export class LoticsClient {
|
|
|
286
286
|
* org to the target version (latest when omitted) in one call. Hands-off
|
|
287
287
|
* applies only where the preview is clean; installations with breaking/
|
|
288
288
|
* drift/modified-core findings are skipped and reported for the normal
|
|
289
|
-
* per-installation consent flow. Backs `
|
|
289
|
+
* per-installation consent flow. Backs `opctl upgrade <package_id>` (fleet).
|
|
290
290
|
* Admin-only; org-scoped (no workspace header needed).
|
|
291
291
|
*/
|
|
292
292
|
/**
|
|
293
293
|
* Yank / unyank a published package version — refuses NEW installs/upgrades/
|
|
294
294
|
* adopts targeting it; pinned installations keep running. Owner-org
|
|
295
|
-
* admin-only. Backs `
|
|
295
|
+
* admin-only. Backs `opctl package yank`.
|
|
296
296
|
*/
|
|
297
297
|
async yankPackageVersion(package_id, version, yanked) {
|
|
298
298
|
return this.request("POST", `/v1/packages/${encodeURIComponent(package_id)}/versions/${version}/yank`, { yanked });
|
|
@@ -311,7 +311,7 @@ export class LoticsClient {
|
|
|
311
311
|
async getPackage(package_id) {
|
|
312
312
|
return this.request("GET", `/v1/packages/${encodeURIComponent(package_id)}`);
|
|
313
313
|
}
|
|
314
|
-
/** Version history newest-first (no contract payloads) — backs `
|
|
314
|
+
/** Version history newest-first (no contract payloads) — backs `opctl package show`. Admin-only. */
|
|
315
315
|
async listPackageVersions(package_id) {
|
|
316
316
|
return this.request("GET", `/v1/packages/${encodeURIComponent(package_id)}/versions`);
|
|
317
317
|
}
|
|
@@ -345,13 +345,13 @@ export class LoticsClient {
|
|
|
345
345
|
/**
|
|
346
346
|
* Health check for a package installation — version pin vs. registry latest,
|
|
347
347
|
* binding drift, and locally modified core artifacts. Read-only; backs
|
|
348
|
-
* `
|
|
348
|
+
* `opctl package doctor`. Admin-only.
|
|
349
349
|
*/
|
|
350
350
|
async getPackageHealth(app_id) {
|
|
351
351
|
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/package-health`);
|
|
352
352
|
}
|
|
353
353
|
/**
|
|
354
|
-
* Preview a release — the dry run behind `
|
|
354
|
+
* Preview a release — the dry run behind `opctl app release`. Runs the
|
|
355
355
|
* binding-aware extract of the origin (aliases stable through the app's current
|
|
356
356
|
* binding) and reports the next version number, the new + changed aliases, the
|
|
357
357
|
* bundled-knowledge delta, and any extract findings (an `error` blocks the
|
|
@@ -365,6 +365,9 @@ export class LoticsClient {
|
|
|
365
365
|
if (opts.knowledge !== undefined && opts.knowledge.length > 0) {
|
|
366
366
|
params.set("knowledge", JSON.stringify(opts.knowledge));
|
|
367
367
|
}
|
|
368
|
+
if (opts.config !== undefined) {
|
|
369
|
+
params.set("config", JSON.stringify(opts.config));
|
|
370
|
+
}
|
|
368
371
|
const query = params.toString();
|
|
369
372
|
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/package-release${query ? `?${query}` : ""}`);
|
|
370
373
|
}
|
|
@@ -376,13 +379,13 @@ export class LoticsClient {
|
|
|
376
379
|
* bundled-knowledge set (added/dropped/re-snapshotted docs; omitted preserves
|
|
377
380
|
* the current corpus). Error findings from extract surface as a 409; a
|
|
378
381
|
* missing/archived declared doc is a 400, a foreign-package doc a 409. Admin,
|
|
379
|
-
* owning-org only. Backs `
|
|
382
|
+
* owning-org only. Backs `opctl app release --yes`.
|
|
380
383
|
*/
|
|
381
384
|
async releasePackage(app_id, body) {
|
|
382
385
|
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/package-release`, body);
|
|
383
386
|
}
|
|
384
387
|
/**
|
|
385
|
-
* Dry-run preview of a first-release — the `GET` behind `
|
|
388
|
+
* Dry-run preview of a first-release — the `GET` behind `opctl app publish`
|
|
386
389
|
* (no `--yes`), the publish-side analogue of `previewPackageRelease`. The
|
|
387
390
|
* server runs the same fresh-alias extract + `src/` scan the apply runs
|
|
388
391
|
* (through any `renames`) and returns the package name it would mint, the
|
|
@@ -394,6 +397,9 @@ export class LoticsClient {
|
|
|
394
397
|
if (opts.knowledge !== undefined && opts.knowledge.length > 0) {
|
|
395
398
|
params.set("knowledge", JSON.stringify(opts.knowledge));
|
|
396
399
|
}
|
|
400
|
+
if (opts.config !== undefined && opts.config.length > 0) {
|
|
401
|
+
params.set("config", JSON.stringify(opts.config));
|
|
402
|
+
}
|
|
397
403
|
if (opts.renames !== undefined && opts.renames.length > 0) {
|
|
398
404
|
params.set("renames", JSON.stringify(opts.renames));
|
|
399
405
|
}
|
|
@@ -402,13 +408,13 @@ export class LoticsClient {
|
|
|
402
408
|
}
|
|
403
409
|
/**
|
|
404
410
|
* First-release apply — mint a package from a BESPOKE app and publish v1 in one
|
|
405
|
-
* call (the `POST` behind `
|
|
411
|
+
* call (the `POST` behind `opctl app publish --yes`). The server extracts an
|
|
406
412
|
* alias-keyed contract from the app (fresh aliases; `renames` fixes them before
|
|
407
413
|
* v1 freezes), creates the registry package (name/description from the app),
|
|
408
414
|
* publishes v1 from the app's deployed source + dist, and pins the origin as
|
|
409
415
|
* installation #1. Error findings from extract surface as a 409. An
|
|
410
416
|
* already-linked app must use `releasePackage` instead. Admin-only. Backs
|
|
411
|
-
* `
|
|
417
|
+
* `opctl app publish <app_id>`.
|
|
412
418
|
*/
|
|
413
419
|
async publishAppAsPackage(app_id, body) {
|
|
414
420
|
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/package-publish`, body);
|