@inventarch/cli 0.0.0-stage → 1.0.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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +19 -2
- package/SPEC.md +30 -0
- package/assets/base/71f0665cb1ffc3f3964fc7710528451f635d664bdf4b8c95005ee97c21db5928.ia.tgz +0 -0
- package/assets/base.json +6 -0
- package/assets/host/43a1f8c471141b1f2f46cef4411a9a61c00da1c1aa19d277189ae2423282bfd6.tgz +0 -0
- package/assets/host.json +6 -0
- package/assets/vocabulary.json +3268 -0
- package/dist/args.d.ts +62 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +117 -0
- package/dist/args.js.map +1 -0
- package/dist/briefing.d.ts +76 -0
- package/dist/briefing.d.ts.map +1 -0
- package/dist/briefing.js +105 -0
- package/dist/briefing.js.map +1 -0
- package/dist/channel.d.ts +22 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +74 -0
- package/dist/channel.js.map +1 -0
- package/dist/claude-cli.d.ts +35 -0
- package/dist/claude-cli.d.ts.map +1 -0
- package/dist/claude-cli.js +101 -0
- package/dist/claude-cli.js.map +1 -0
- package/dist/commands.d.ts +39 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +436 -0
- package/dist/commands.js.map +1 -0
- package/dist/compile.d.ts +39 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +136 -0
- package/dist/compile.js.map +1 -0
- package/dist/consumer.d.ts +137 -0
- package/dist/consumer.d.ts.map +1 -0
- package/dist/consumer.js +366 -0
- package/dist/consumer.js.map +1 -0
- package/dist/decline.d.ts +7 -0
- package/dist/decline.d.ts.map +1 -0
- package/dist/decline.js +78 -0
- package/dist/decline.js.map +1 -0
- package/dist/distribute.d.ts +163 -0
- package/dist/distribute.d.ts.map +1 -0
- package/dist/distribute.js +664 -0
- package/dist/distribute.js.map +1 -0
- package/dist/doctor-user.d.ts +45 -0
- package/dist/doctor-user.d.ts.map +1 -0
- package/dist/doctor-user.js +193 -0
- package/dist/doctor-user.js.map +1 -0
- package/dist/doctor.d.ts +57 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +754 -0
- package/dist/doctor.js.map +1 -0
- package/dist/format.d.ts +25 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +168 -0
- package/dist/format.js.map +1 -0
- package/dist/home-remedy.d.ts +10 -0
- package/dist/home-remedy.d.ts.map +1 -0
- package/dist/home-remedy.js +26 -0
- package/dist/home-remedy.js.map +1 -0
- package/dist/host-projection.d.ts +11 -0
- package/dist/host-projection.d.ts.map +1 -0
- package/dist/host-projection.js +73 -0
- package/dist/host-projection.js.map +1 -0
- package/dist/host.d.ts +162 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +599 -0
- package/dist/host.js.map +1 -0
- package/dist/init.d.ts +217 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +840 -0
- package/dist/init.js.map +1 -0
- package/dist/inspect.d.ts +32 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +226 -0
- package/dist/inspect.js.map +1 -0
- package/dist/main.d.ts +24 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +215 -0
- package/dist/main.js.map +1 -0
- package/dist/operation-help.d.ts +14 -0
- package/dist/operation-help.d.ts.map +1 -0
- package/dist/operation-help.js +75 -0
- package/dist/operation-help.js.map +1 -0
- package/dist/pack.d.ts +17 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +121 -0
- package/dist/pack.js.map +1 -0
- package/dist/render.d.ts +165 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +277 -0
- package/dist/render.js.map +1 -0
- package/dist/session.d.ts +13 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +25 -0
- package/dist/session.js.map +1 -0
- package/dist/user-host.d.ts +59 -0
- package/dist/user-host.d.ts.map +1 -0
- package/dist/user-host.js +228 -0
- package/dist/user-host.js.map +1 -0
- package/dist/validate.d.ts +53 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +220 -0
- package/dist/validate.js.map +1 -0
- package/dist/vocabulary.d.ts +55 -0
- package/dist/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary.js +179 -0
- package/dist/vocabulary.js.map +1 -0
- package/package.json +153 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProtocolOperation } from '@inventarch/runtime';
|
|
2
|
+
/** spec-0012 CLI-05: asks for the operation's description as JSON rather than as help text. */
|
|
3
|
+
export declare const SCHEMA_TOKEN = "--schema";
|
|
4
|
+
export declare const describeOperation: (name: string) => ProtocolOperation | undefined;
|
|
5
|
+
/** CLI-05: one JSON line, the same object the MCP door's input schema is derived from. */
|
|
6
|
+
export declare const renderOperationSchema: (operation: ProtocolOperation) => string;
|
|
7
|
+
type Schema = Readonly<Record<string, unknown>>;
|
|
8
|
+
/** A JSON Schema fragment spelled for a reader: `string`, `array of string`, `integer 0-8`, `one of a | b`, `{a, b}`. */
|
|
9
|
+
export declare function typeText(schema: Schema): string;
|
|
10
|
+
/** C03: the route's exit for a documented refusal, derived rather than stored (spec-0012 ERR-02). */
|
|
11
|
+
export declare const refusalExit: (code: string) => number;
|
|
12
|
+
export declare function renderOperationHelp(operation: ProtocolOperation): string;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=operation-help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-help.d.ts","sourceRoot":"","sources":["../src/operation-help.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAK7D,+FAA+F;AAC/F,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,iBAAiB,GAAG,SACK,CAAC;AAC3E,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,GAAI,WAAW,iBAAiB,KAAG,MACO,CAAC;AAC7E,KAAK,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAChD,yHAAyH;AACzH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAe/C;AACD,qGAAqG;AACrG,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,MAAyD,CAAC;AACrG,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAwDxE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ia <operation> --help` (docs/specs/command-discoverability/README.md CLI-01..02): one operation's help, rendered
|
|
3
|
+
* from the machine protocol table that the MCP door and the reference page also read, so the three cannot drift. The
|
|
4
|
+
* machine route stays uncoloured whatever the environment asks for (SPEC.md C10), so the capabilities are fixed here.
|
|
5
|
+
*/
|
|
6
|
+
import { MACHINE_PROTOCOL } from '@inventarch/runtime';
|
|
7
|
+
import { atom, document, entry, fieldRows, MAX_WIDTH, sectionLabel, words } from './render.js';
|
|
8
|
+
const PLAIN = { color: false, ascii: true, width: MAX_WIDTH };
|
|
9
|
+
/** spec-0012 CLI-05: asks for the operation's description as JSON rather than as help text. */
|
|
10
|
+
export const SCHEMA_TOKEN = '--schema';
|
|
11
|
+
export const describeOperation = (name) => MACHINE_PROTOCOL.operations.find((operation) => operation.name === name);
|
|
12
|
+
/** CLI-05: one JSON line, the same object the MCP door's input schema is derived from. */
|
|
13
|
+
export const renderOperationSchema = (operation) => JSON.stringify({ version: MACHINE_PROTOCOL.version, ...operation }) + '\n';
|
|
14
|
+
/** A JSON Schema fragment spelled for a reader: `string`, `array of string`, `integer 0-8`, `one of a | b`, `{a, b}`. */
|
|
15
|
+
export function typeText(schema) {
|
|
16
|
+
if (Array.isArray(schema['enum']))
|
|
17
|
+
return `one of ${schema['enum'].join(' | ')}`;
|
|
18
|
+
if (schema['const'] !== undefined)
|
|
19
|
+
return JSON.stringify(schema['const']);
|
|
20
|
+
for (const key of ['anyOf', 'oneOf'])
|
|
21
|
+
if (Array.isArray(schema[key]))
|
|
22
|
+
return schema[key].map(typeText).join(' or ');
|
|
23
|
+
if (schema['type'] === 'array')
|
|
24
|
+
return `array of ${typeText((schema['items'] ?? {}))}`;
|
|
25
|
+
if (schema['type'] === 'integer')
|
|
26
|
+
return schema['maximum'] === undefined
|
|
27
|
+
? 'integer'
|
|
28
|
+
: `integer ${String(schema['minimum'] ?? 0)}-${String(schema['maximum'])}`;
|
|
29
|
+
if (schema['type'] === 'object') {
|
|
30
|
+
const keys = Object.keys((schema['properties'] ?? {}));
|
|
31
|
+
return keys.length === 0 ? 'object' : `{${keys.join(', ')}}`;
|
|
32
|
+
}
|
|
33
|
+
return String(schema['type'] ?? 'value');
|
|
34
|
+
}
|
|
35
|
+
/** C03: the route's exit for a documented refusal, derived rather than stored (spec-0012 ERR-02). */
|
|
36
|
+
export const refusalExit = (code) => (code === 'IA-RUNTIME-REQUEST-INVALID' ? 2 : 1);
|
|
37
|
+
export function renderOperationHelp(operation) {
|
|
38
|
+
const params = operation.params;
|
|
39
|
+
const required = new Set(params.required ?? []);
|
|
40
|
+
const rows = Object.entries(params.properties ?? {}).map(([name, schema]) => ({
|
|
41
|
+
label: name,
|
|
42
|
+
value: words(`${required.has(name) ? 'Required. ' : ''}${typeText(schema)}.${typeof schema['description'] === 'string' ? ` ${schema['description']}` : ''}`),
|
|
43
|
+
}));
|
|
44
|
+
return document([
|
|
45
|
+
entry([[atom(`ia ${operation.name}`, null, 0), ...words(operation.summary, null, 2)]], { depth: 0 }, PLAIN),
|
|
46
|
+
[
|
|
47
|
+
sectionLabel('Usage', PLAIN),
|
|
48
|
+
...entry([[atom(`ia ${operation.name} [--root <workspace>] [--params <JSON|->]`, null, 0)]], { depth: 1 }, PLAIN),
|
|
49
|
+
...entry([[atom(`ia ${operation.name} ${SCHEMA_TOKEN}`, null, 0)]], { depth: 1 }, PLAIN),
|
|
50
|
+
],
|
|
51
|
+
entry([words(operation.description)], { depth: 0 }, PLAIN),
|
|
52
|
+
[
|
|
53
|
+
sectionLabel('Parameters (the --params JSON object)', PLAIN),
|
|
54
|
+
...(rows.length === 0
|
|
55
|
+
? entry([words('None; pass {} or omit --params.')], { depth: 1 }, PLAIN)
|
|
56
|
+
: fieldRows(rows, { depth: 1 }, PLAIN)),
|
|
57
|
+
],
|
|
58
|
+
[sectionLabel('Result', PLAIN), ...entry([words(operation.result)], { depth: 1 }, PLAIN)],
|
|
59
|
+
[
|
|
60
|
+
sectionLabel('Refusals', PLAIN),
|
|
61
|
+
...fieldRows(operation.refusals.map((refusal) => ({
|
|
62
|
+
label: refusal.code,
|
|
63
|
+
value: words(`Exit ${refusalExit(refusal.code)}. ${refusal.when} ${refusal.next}`),
|
|
64
|
+
})), { depth: 1 }, PLAIN),
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
sectionLabel('Example', PLAIN),
|
|
68
|
+
...entry([[atom(`ia ${operation.name} --root <workspace> --params '${JSON.stringify(operation.example)}'`, null, 0)]], { depth: 1 }, PLAIN),
|
|
69
|
+
],
|
|
70
|
+
entry([
|
|
71
|
+
words(`Machine protocol v${MACHINE_PROTOCOL.version}: JSON in, one JSON line out, no color. ${operation.mcp === null ? 'The MCP door does not serve it.' : `MCP tool: ${operation.mcp}.`}`),
|
|
72
|
+
], { depth: 0 }, PLAIN),
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=operation-help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-help.js","sourceRoot":"","sources":["../src/operation-help.ts"],"names":[],"mappings":"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"}
|
package/dist/pack.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { PackedArchive } from '@inventarch/distribution/services';
|
|
2
|
+
import type { Context, Result } from './consumer.js';
|
|
3
|
+
import type { Capabilities } from './render.js';
|
|
4
|
+
export declare const DEFAULT_OUT = ".ia/work/dist";
|
|
5
|
+
/** §2.7: the rendered form lists the first 20 members and names the rest rather than printing them. */
|
|
6
|
+
export declare const LISTED_MEMBERS = 20;
|
|
7
|
+
export interface PackView {
|
|
8
|
+
readonly root: string;
|
|
9
|
+
readonly out: string;
|
|
10
|
+
readonly packed: PackedArchive;
|
|
11
|
+
}
|
|
12
|
+
export declare const expandedBytes: (packed: PackedArchive) => number;
|
|
13
|
+
export declare function packEnvelope(view: PackView): unknown;
|
|
14
|
+
export declare function renderPack(view: PackView, caps: Capabilities): string;
|
|
15
|
+
export declare function collectPack(root: string, cwd: string, descriptorPath: string, out: string | undefined, force: boolean): PackView;
|
|
16
|
+
export declare function runPack(context: Context): Result;
|
|
17
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAC3C,uGAAuG;AACvG,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,MACgB,CAAC;AAEvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CA4DrE;AAYD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,OAAO,GACb,QAAQ,CA0BV;AAkBD,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAQhD"}
|
package/dist/pack.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ia pack`: docs/specs/consumer-cli-contract/README.md §2.7.
|
|
3
|
+
*
|
|
4
|
+
* The consumer form renames the native `--source-root` to the common `--root` and defaults the output directory
|
|
5
|
+
* the native form requires. The packer itself is unchanged, including its recheck that the descriptor did not
|
|
6
|
+
* change while the archive was being built, which is the only reason `IA-DIST-SOURCE-CHANGED` can appear here.
|
|
7
|
+
*
|
|
8
|
+
* The digests are the integrity output: they are what a consumer checks an acquired artifact against. The archive
|
|
9
|
+
* name is its own digest, so re-packing unchanged sources on the same zlib build targets a path that already exists — refused by
|
|
10
|
+
* default with a next action naming --force, exactly as §2.4 refuses a compiled artifact.
|
|
11
|
+
*/
|
|
12
|
+
import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
|
|
13
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
14
|
+
import { DISTRIBUTION_LIMITS } from '@inventarch/db/distribution';
|
|
15
|
+
import { packToDirectory, readWorkspaceFile, replace } from '@inventarch/distribution/services';
|
|
16
|
+
import { Refusal, requireRoot } from './consumer.js';
|
|
17
|
+
import { codeOf } from './session.js';
|
|
18
|
+
import { atom, document, entry, fieldRows, headerLine, sectionLabel, truncateDigest, words } from './render.js';
|
|
19
|
+
export const DEFAULT_OUT = '.ia/work/dist';
|
|
20
|
+
/** §2.7: the rendered form lists the first 20 members and names the rest rather than printing them. */
|
|
21
|
+
export const LISTED_MEMBERS = 20;
|
|
22
|
+
export const expandedBytes = (packed) => packed.manifest.files.reduce((total, file) => total + file.bytes, 0);
|
|
23
|
+
export function packEnvelope(view) {
|
|
24
|
+
return { version: 1, ...view.packed };
|
|
25
|
+
}
|
|
26
|
+
export function renderPack(view, caps) {
|
|
27
|
+
const { packed } = view, members = packed.manifest.files.map((file) => file.path);
|
|
28
|
+
return document([
|
|
29
|
+
headerLine('Pack', `${packed.manifest.id} ${packed.manifest.version}`, [{ text: view.out, column: 50 }], caps),
|
|
30
|
+
entry([
|
|
31
|
+
words(`${members.length} ${members.length === 1 ? 'file' : 'files'}, ${expandedBytes(packed)} bytes expanded.`),
|
|
32
|
+
], { depth: 1, symbol: 'success' }, caps),
|
|
33
|
+
[
|
|
34
|
+
sectionLabel('Integrity', caps),
|
|
35
|
+
...fieldRows([
|
|
36
|
+
{ label: 'Archive', value: [atom(`sha256 ${truncateDigest(packed.archive, caps.ascii)}`, null, 0)] },
|
|
37
|
+
{
|
|
38
|
+
label: 'Manifest',
|
|
39
|
+
value: [atom(`sha256 ${truncateDigest(packed.manifestDigest, caps.ascii)}`, null, 0)],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
label: 'Source',
|
|
43
|
+
value: [atom(`sha256 ${truncateDigest(packed.sourceFingerprint, caps.ascii)}`, null, 0)],
|
|
44
|
+
},
|
|
45
|
+
// The file name carries the archive digest whole: §6.4 never truncates a digest inside an identifier.
|
|
46
|
+
{ label: 'File', value: [atom(packed.path, 'cyan', 0)] },
|
|
47
|
+
], { depth: 1 }, caps),
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
sectionLabel('Members', caps),
|
|
51
|
+
...members
|
|
52
|
+
.slice(0, LISTED_MEMBERS)
|
|
53
|
+
.flatMap((path) => entry([[atom(path, 'cyan', 0)]], { depth: 1, symbol: 'info' }, caps)),
|
|
54
|
+
...(members.length > LISTED_MEMBERS
|
|
55
|
+
? entry([words(`${caps.ascii ? '...' : '…'} and ${members.length - LISTED_MEMBERS} more`, 'dim')], { depth: 1 }, caps)
|
|
56
|
+
: []),
|
|
57
|
+
],
|
|
58
|
+
entry([
|
|
59
|
+
words('Verify an acquired copy against the archive digest above before installing it: the file name is that digest.'),
|
|
60
|
+
], { depth: 0, symbol: 'step' }, caps),
|
|
61
|
+
], { leadingBlank: true });
|
|
62
|
+
}
|
|
63
|
+
/** §2.7: the default directory is created by this command; a supplied one that is absent is a refusal. */
|
|
64
|
+
const destination = (root, cwd, supplied) => {
|
|
65
|
+
if (supplied === undefined) {
|
|
66
|
+
const path = resolve(root, DEFAULT_OUT);
|
|
67
|
+
mkdirSync(path, { recursive: true });
|
|
68
|
+
return path;
|
|
69
|
+
}
|
|
70
|
+
return isAbsolute(supplied) ? resolve(supplied) : resolve(cwd, supplied);
|
|
71
|
+
};
|
|
72
|
+
export function collectPack(root, cwd, descriptorPath, out, force) {
|
|
73
|
+
// outputRoot is a thunk: a pack that refuses never selects or creates a destination for an archive that does
|
|
74
|
+
// not exist. With --force the archive lands in a private directory first, because the packer's own publish
|
|
75
|
+
// step refuses an existing entry and carries no bytes back for a second attempt.
|
|
76
|
+
let selected;
|
|
77
|
+
const select = () => {
|
|
78
|
+
selected ??= destination(root, cwd, out);
|
|
79
|
+
return selected;
|
|
80
|
+
};
|
|
81
|
+
if (!force) {
|
|
82
|
+
const packed = attempt(() => packToDirectory({ sourceRoot: root, descriptorPath, outputRoot: select }));
|
|
83
|
+
return { root, out: select(), packed };
|
|
84
|
+
}
|
|
85
|
+
let staging;
|
|
86
|
+
const stage = () => {
|
|
87
|
+
staging = mkdtempSync(resolve(select(), '.pack-'));
|
|
88
|
+
return staging;
|
|
89
|
+
};
|
|
90
|
+
try {
|
|
91
|
+
const packed = attempt(() => packToDirectory({ sourceRoot: root, descriptorPath, outputRoot: stage }));
|
|
92
|
+
const content = readWorkspaceFile({ root: staging, path: packed.path, limit: DISTRIBUTION_LIMITS.compressed });
|
|
93
|
+
replace(select(), packed.path, content);
|
|
94
|
+
return { root, out: select(), packed };
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
if (staging !== undefined)
|
|
98
|
+
rmSync(staging, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** The existing-archive refusal is the service's own code; only the next action naming --force is the CLI's. */
|
|
102
|
+
function attempt(run) {
|
|
103
|
+
try {
|
|
104
|
+
return run();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (codeOf(error, '') !== 'IA-DIST-LOCAL-MODIFICATION')
|
|
108
|
+
throw error;
|
|
109
|
+
throw new Refusal('IA-DIST-LOCAL-MODIFICATION', 'An archive with this content digest is already in the output directory', 3, null, 'Pass --force to overwrite it, or pack into another --out directory.');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function runPack(context) {
|
|
113
|
+
const { args, caps, json } = context;
|
|
114
|
+
const root = requireRoot(context);
|
|
115
|
+
const view = collectPack(root, context.host.cwd, args.value('descriptor'), args.value('out'), args.flag('force'));
|
|
116
|
+
// §2.7: packing has no "ran correctly, bad result" state, so this verb never returns 1.
|
|
117
|
+
return json
|
|
118
|
+
? { exitCode: 0, stdout: JSON.stringify(packEnvelope(view)) + '\n', stderr: '' }
|
|
119
|
+
: { exitCode: 0, stdout: renderPack(view, caps), stderr: '' };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=pack.js.map
|
package/dist/pack.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../src/pack.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal presentation primitives for the consumer CLI: docs/specs/consumer-cli-contract/README.md §6.
|
|
3
|
+
* Everything here is pure. The environment is a parameter, so no function reads process.env, process.stdout or a clock.
|
|
4
|
+
*/
|
|
5
|
+
export type Role = 'bold' | 'dim' | 'red' | 'yellow' | 'green' | 'cyan';
|
|
6
|
+
export type SymbolName = 'success' | 'error' | 'warning' | 'unknown' | 'info' | 'step' | 'added' | 'removed' | 'updated';
|
|
7
|
+
export type Depth = 0 | 1 | 2;
|
|
8
|
+
export interface Terminal {
|
|
9
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
10
|
+
readonly isTTY: boolean;
|
|
11
|
+
/** undefined whenever stdout is not a TTY; measured on Windows for pipes, file redirection and a real console. */
|
|
12
|
+
readonly columns?: number | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface RenderFlags {
|
|
15
|
+
readonly color?: boolean | undefined;
|
|
16
|
+
readonly ascii?: boolean | undefined;
|
|
17
|
+
readonly json?: boolean | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface Capabilities {
|
|
20
|
+
readonly color: boolean;
|
|
21
|
+
readonly ascii: boolean;
|
|
22
|
+
readonly width: number;
|
|
23
|
+
}
|
|
24
|
+
/** §6.4: 80 is the ceiling; below 40 a label/value block drops its value column; below 60 header pairs split. */
|
|
25
|
+
export declare const MAX_WIDTH = 80;
|
|
26
|
+
export declare const NARROW_WIDTH = 40;
|
|
27
|
+
export declare const HEADER_WIDTH = 60;
|
|
28
|
+
/** §6.4: a bare digest field shows 12 hex characters and an explicit ellipsis. */
|
|
29
|
+
export declare const DIGEST_CHARACTERS = 12;
|
|
30
|
+
/** §6.7 colour precedence and §6.3's ASCII rule, resolved from an explicit environment rather than from the process. */
|
|
31
|
+
export declare function resolveCapabilities(terminal: Terminal, flags?: RenderFlags): Capabilities;
|
|
32
|
+
/** §6.1: a styled run is reset at its end and never left open across a newline, so each line is styled on its own. */
|
|
33
|
+
export declare function style(text: string, role: Role | null | undefined, color: boolean): string;
|
|
34
|
+
export interface StatusSymbol {
|
|
35
|
+
readonly text: string;
|
|
36
|
+
readonly width: number;
|
|
37
|
+
readonly role: Role | null;
|
|
38
|
+
}
|
|
39
|
+
/** Every symbol is one UTF-16 unit per display column, so length is the declared §6.3 width; no emoji is admitted. */
|
|
40
|
+
export declare function statusSymbol(name: SymbolName, ascii: boolean): StatusSymbol;
|
|
41
|
+
/** A wrap unit. `gap` is the spacing that precedes it when it stays on the current line; a line start drops the gap. */
|
|
42
|
+
export interface Token {
|
|
43
|
+
readonly text: string;
|
|
44
|
+
readonly gap: number;
|
|
45
|
+
readonly role: Role | null;
|
|
46
|
+
}
|
|
47
|
+
/** One unbreakable run: an identity, path, package id, digest, URL or a command that must stay copy-pasteable. */
|
|
48
|
+
export declare const atom: (text: string, role?: Role | null, gap?: number) => Token;
|
|
49
|
+
/** Prose, split at word boundaries; runs of spaces inside the text are preserved as wider gaps. */
|
|
50
|
+
export declare function words(text: string, role?: Role | null, gap?: number): readonly Token[];
|
|
51
|
+
/**
|
|
52
|
+
* §6.4: words wrap at the effective width; a token is never split, so an over-wide identifier overruns its line whole.
|
|
53
|
+
* `firstColumn` differs from `column` only where a value starts past its label and then hangs back at rule 3's column.
|
|
54
|
+
*/
|
|
55
|
+
export declare function wrapTokens(tokens: readonly Token[], column: number, caps: Capabilities, firstColumn?: number): readonly string[];
|
|
56
|
+
export interface Placement {
|
|
57
|
+
readonly depth?: Depth | undefined;
|
|
58
|
+
/** An explicit symbol column, used for an action nested at its parent's content column. Overrides `depth`. */
|
|
59
|
+
readonly column?: number | undefined;
|
|
60
|
+
}
|
|
61
|
+
export interface EntryOptions extends Placement {
|
|
62
|
+
readonly symbol?: SymbolName | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* §6.4 rule 2: the width of the widest symbol in this block, so every row of a block shares one content column.
|
|
65
|
+
* It never reaches a nested action, whose column is rule 3's `parent + width(its own symbol) + 2`.
|
|
66
|
+
*/
|
|
67
|
+
readonly symbolWidth?: number | undefined;
|
|
68
|
+
}
|
|
69
|
+
/** §6.4 rule 1. */
|
|
70
|
+
export declare const indentOf: (depth: Depth) => number;
|
|
71
|
+
/** The widest symbol of a block, which rule 2 measures the whole block's content column from. */
|
|
72
|
+
export declare const blockSymbolWidth: (names: readonly (SymbolName | undefined)[], ascii: boolean) => number;
|
|
73
|
+
/** §6.4 rule 2: `2·d + width + 2`, where width is the block's widest symbol and never less than this row's own. */
|
|
74
|
+
export declare const contentColumn: (base: number, symbol: StatusSymbol | null, symbolWidth?: number) => number;
|
|
75
|
+
export declare const entryColumn: (options: EntryOptions, ascii: boolean) => number;
|
|
76
|
+
/**
|
|
77
|
+
* One entry: block indent, the status symbol, two spaces, then its facts. §6.4 rule 3 hangs every continuation —
|
|
78
|
+
* a wrapped line or a further fact — at the entry's content column.
|
|
79
|
+
*/
|
|
80
|
+
export declare function entry(facts: readonly (readonly Token[])[], options: EntryOptions, caps: Capabilities): readonly string[];
|
|
81
|
+
export interface Field {
|
|
82
|
+
readonly label: string;
|
|
83
|
+
readonly value: readonly Token[];
|
|
84
|
+
readonly symbol?: SymbolName | undefined;
|
|
85
|
+
/** A next action nested under this row, at the row's content column, per rule 3. */
|
|
86
|
+
readonly action?: readonly Token[] | null | undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* §6.4 rule 4: one value column per block at `max(len(label)) + 2`, never shared across a blank line, over the one
|
|
90
|
+
* content column rule 2 gives the block. A value that wraps hangs at the entry's content column, which is rule 3 and
|
|
91
|
+
* not the value column. Below 40 columns, or when the padding would leave no room for a value, the block drops the
|
|
92
|
+
* value column and each field renders as `label value`.
|
|
93
|
+
*/
|
|
94
|
+
export declare function fieldRows(fields: readonly Field[], options: Placement, caps: Capabilities): readonly string[];
|
|
95
|
+
export interface HeaderItem {
|
|
96
|
+
readonly text: string;
|
|
97
|
+
/** The column this item starts at; §6.4 rule 5 only fixes the minimum gap of four spaces. */
|
|
98
|
+
readonly column?: number | undefined;
|
|
99
|
+
}
|
|
100
|
+
/** §6.4 rule 5: bold label, two spaces, value; further pairs share the line until the width drops below 60. */
|
|
101
|
+
export declare function headerLine(label: string, value: string, trailing: readonly HeaderItem[], caps: Capabilities): readonly string[];
|
|
102
|
+
export declare const sectionLabel: (text: string, caps: Capabilities) => string;
|
|
103
|
+
export interface DocumentOptions {
|
|
104
|
+
/** §7's report blocks open with one blank line; the standalone error blocks do not. */
|
|
105
|
+
readonly leadingBlank?: boolean | undefined;
|
|
106
|
+
}
|
|
107
|
+
/** §6.4 rule 6: exactly one blank line between blocks, never two, and no trailing blank before the process exits. */
|
|
108
|
+
export declare function document(blocks: readonly (readonly string[])[], options?: DocumentOptions): string;
|
|
109
|
+
/**
|
|
110
|
+
* One argument of a printed command, quoted only when a space or a quote would split or end it, so an invocation
|
|
111
|
+
* rebuilt from parsed arguments is the one a reader can paste back.
|
|
112
|
+
*/
|
|
113
|
+
export declare const quote: (value: string) => string;
|
|
114
|
+
/** §6.4: a command is unbreakable prose. The caller chooses the `\` break so every line stays runnable. */
|
|
115
|
+
export declare function commandFacts(lead: string, command: string, tail: string, column: number, caps: Capabilities): readonly (readonly Token[])[];
|
|
116
|
+
/**
|
|
117
|
+
* §6.4: only a bare digest field is truncated. A value carrying a path, URL or any other separator is returned whole,
|
|
118
|
+
* because truncating a digest inside an identifier destroys the identifier.
|
|
119
|
+
*/
|
|
120
|
+
export declare const truncateDigest: (value: string, ascii: boolean) => string;
|
|
121
|
+
export interface MessageContext {
|
|
122
|
+
readonly code?: string | undefined;
|
|
123
|
+
readonly location?: string | null | undefined;
|
|
124
|
+
readonly identity?: string | null | undefined;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* §6.5: strip what the block already shows. Findings embed `path:line: identity: `; RuntimeError and DbError embed
|
|
128
|
+
* `code: `; DistributionError embeds nothing. Without this, two of the three families print their code twice.
|
|
129
|
+
*/
|
|
130
|
+
export declare function stripMessage(message: string, context: MessageContext): string;
|
|
131
|
+
export interface ErrorElements {
|
|
132
|
+
/** A path, `path:line`, package id or workspace root. Null or empty renders as `(whole workspace)` — never `:1`. */
|
|
133
|
+
readonly location: string | null;
|
|
134
|
+
/** The originating check name, printed beside a location the finding does not have. */
|
|
135
|
+
readonly check?: string | null | undefined;
|
|
136
|
+
readonly identity?: string | null | undefined;
|
|
137
|
+
readonly code: string;
|
|
138
|
+
readonly message: string;
|
|
139
|
+
/** One imperative next action. Omitted on every member of a group but the one that carries the shared action. */
|
|
140
|
+
readonly next?: readonly Token[] | null | undefined;
|
|
141
|
+
/** A warning finding carries the same four elements under the warning symbol; the default is an error. */
|
|
142
|
+
readonly severity?: 'error' | 'warning' | undefined;
|
|
143
|
+
/** The block's widest symbol, when this finding shares a block with wider ones. */
|
|
144
|
+
readonly symbolWidth?: number | undefined;
|
|
145
|
+
}
|
|
146
|
+
/** §6.5: location, identity, cause, next action, in that order, with nothing interleaved. */
|
|
147
|
+
export declare function errorBlock(error: ErrorElements, options: Placement, caps: Capabilities): readonly string[];
|
|
148
|
+
export interface ProgressSink {
|
|
149
|
+
readonly write: (text: string) => void;
|
|
150
|
+
readonly isTTY: boolean;
|
|
151
|
+
}
|
|
152
|
+
export interface Progress {
|
|
153
|
+
readonly phase: (text: string) => void;
|
|
154
|
+
readonly clear: () => void;
|
|
155
|
+
readonly done: (text: string) => void;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* §6.6: progress lives on the sink the caller supplies, which is stderr — never structured stdout. It is rewritten in
|
|
159
|
+
* place only on a TTY, degrades to one appended line per phase otherwise, is erased before the result is written, and
|
|
160
|
+
* never carries the completion: `done` always emits a terminal state line as text.
|
|
161
|
+
*/
|
|
162
|
+
export declare function createProgress(sink: ProgressSink, options: {
|
|
163
|
+
readonly enabled: boolean;
|
|
164
|
+
}): Progress;
|
|
165
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|