@procedures/mark 0.0.0-stage → 0.1.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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +799 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/args.d.ts +77 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +351 -0
- package/dist/args.js.map +1 -0
- package/dist/ask.d.ts +48 -0
- package/dist/ask.d.ts.map +1 -0
- package/dist/ask.js +91 -0
- package/dist/ask.js.map +1 -0
- package/dist/bin.d.ts +9 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +10 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +61 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +530 -0
- package/dist/cli.js.map +1 -0
- package/dist/client-mode.d.ts +21 -0
- package/dist/client-mode.d.ts.map +1 -0
- package/dist/client-mode.js +75 -0
- package/dist/client-mode.js.map +1 -0
- package/dist/ecosystem.d.ts +66 -0
- package/dist/ecosystem.d.ts.map +1 -0
- package/dist/ecosystem.js +211 -0
- package/dist/ecosystem.js.map +1 -0
- package/dist/failure.d.ts +16 -0
- package/dist/failure.d.ts.map +1 -0
- package/dist/failure.js +47 -0
- package/dist/failure.js.map +1 -0
- package/dist/format.d.ts +30 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +125 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/lockfile.d.ts +26 -0
- package/dist/lockfile.d.ts.map +1 -0
- package/dist/lockfile.js +68 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/manifest-build.d.ts +7 -0
- package/dist/manifest-build.d.ts.map +1 -0
- package/dist/manifest-build.js +11 -0
- package/dist/manifest-build.js.map +1 -0
- package/dist/manifest.d.ts +57 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +140 -0
- package/dist/manifest.js.map +1 -0
- package/dist/manifest.json +20885 -0
- package/dist/parse.d.ts +143 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +509 -0
- package/dist/parse.js.map +1 -0
- package/dist/print.d.ts +42 -0
- package/dist/print.d.ts.map +1 -0
- package/dist/print.js +80 -0
- package/dist/print.js.map +1 -0
- package/dist/prompts.d.ts +58 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +124 -0
- package/dist/prompts.js.map +1 -0
- package/dist/repl.d.ts +34 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +101 -0
- package/dist/repl.js.map +1 -0
- package/dist/server-mode.d.ts +37 -0
- package/dist/server-mode.d.ts.map +1 -0
- package/dist/server-mode.js +167 -0
- package/dist/server-mode.js.map +1 -0
- package/package.json +97 -3
- package/src/args.ts +440 -0
- package/src/ask.ts +119 -0
- package/src/bin.ts +11 -0
- package/src/cli.ts +596 -0
- package/src/client-mode.ts +90 -0
- package/src/ecosystem.ts +258 -0
- package/src/failure.ts +47 -0
- package/src/format.ts +177 -0
- package/src/index.ts +31 -0
- package/src/lockfile.ts +85 -0
- package/src/manifest-build.ts +12 -0
- package/src/manifest.ts +162 -0
- package/src/parse.ts +670 -0
- package/src/print.ts +108 -0
- package/src/prompts.ts +181 -0
- package/src/repl.ts +121 -0
- package/src/server-mode.ts +205 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace-based Procedure Discovery
|
|
3
|
+
*
|
|
4
|
+
* Dynamically discovers and loads procedures from the packages of the
|
|
5
|
+
* monorepo this CLI lives in. This enables the CLI to automatically find
|
|
6
|
+
* all available procedures without hardcoding imports.
|
|
7
|
+
*
|
|
8
|
+
* Discovery flow:
|
|
9
|
+
* 1. Walk up from this module to the folder that holds pnpm-workspace.yaml
|
|
10
|
+
* 2. For each packages/* folder, read its package.json
|
|
11
|
+
* 3. If it has client.procedures, dynamically import it
|
|
12
|
+
* 4. Procedures auto-register via PROCEDURE_REGISTRY
|
|
13
|
+
*/
|
|
14
|
+
import { type ProcedureRegistry } from "@procedures/client";
|
|
15
|
+
interface DiscoveredPackage {
|
|
16
|
+
name: string;
|
|
17
|
+
path: string;
|
|
18
|
+
proceduresPath: string;
|
|
19
|
+
/** The file of the side-effect-free `./module` entry, when the package has one (roadmap 3.1) */
|
|
20
|
+
modulePath?: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Find the workspace root: the nearest folder above this module that holds pnpm-workspace.yaml
|
|
24
|
+
*/
|
|
25
|
+
export declare function findWorkspaceRoot(): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Discover workspace packages that declare client.procedures
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverFromEcosystem(root?: string | null): DiscoveredPackage[];
|
|
30
|
+
/**
|
|
31
|
+
* This function registers the core procedures of `@procedures/client` that its import does not
|
|
32
|
+
* register: the math, string, array, object, comparison, type and meta procedures (`client.add`
|
|
33
|
+
* and the others). The import registers only the control-flow procedures. (Docs review DOC-6:
|
|
34
|
+
* before, `mark client add` was an unknown command.) A procedure that is registered already stays.
|
|
35
|
+
*/
|
|
36
|
+
export declare function registerCoreProcedures(): number;
|
|
37
|
+
/**
|
|
38
|
+
* Dynamically load procedures from discovered packages.
|
|
39
|
+
*
|
|
40
|
+
* A package that fails to load gives one warning line on stderr, also without `verbose`: before,
|
|
41
|
+
* its commands were missing with no message (deep dive CLI-18). A package that is not built yet
|
|
42
|
+
* (no procedures file) is reported only with `verbose`. `warn: false` turns the warnings off (the
|
|
43
|
+
* build of mark writes the manifest while other packages can still be in their build).
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadEcosystemProcedures(verbose?: boolean, warn?: boolean): Promise<string[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get list of ecosystem packages that have procedures
|
|
48
|
+
*/
|
|
49
|
+
export declare function listEcosystemProcedurePackages(): Array<{
|
|
50
|
+
name: string;
|
|
51
|
+
path: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** The registry of `mark` and the names of the packages that it holds. */
|
|
54
|
+
export interface EcosystemRegistry {
|
|
55
|
+
registry: ProcedureRegistry;
|
|
56
|
+
loaded: string[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The registry of `mark` (roadmap 3.1): a registry of its own, built from the module of each
|
|
60
|
+
* workspace package that declares `client.procedures`, with all the core procedures. The global
|
|
61
|
+
* registry does not change for a package with a module entry. A package that fails to load gives
|
|
62
|
+
* one warning line on stderr, as with `loadEcosystemProcedures()`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function loadEcosystemRegistry(verbose?: boolean, warn?: boolean): Promise<EcosystemRegistry>;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=ecosystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecosystem.d.ts","sourceRoot":"","sources":["../src/ecosystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EASL,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAc5B,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AA6BD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAYjD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,MAAM,GAAG,IAA0B,GAAG,iBAAiB,EAAE,CA4BpG;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAS/C;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,UAAQ,EAAE,IAAI,UAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAuC7F;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAKtF;AAKD,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAsBD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,UAAQ,EAAE,IAAI,UAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoBpG"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace-based Procedure Discovery
|
|
3
|
+
*
|
|
4
|
+
* Dynamically discovers and loads procedures from the packages of the
|
|
5
|
+
* monorepo this CLI lives in. This enables the CLI to automatically find
|
|
6
|
+
* all available procedures without hardcoding imports.
|
|
7
|
+
*
|
|
8
|
+
* Discovery flow:
|
|
9
|
+
* 1. Walk up from this module to the folder that holds pnpm-workspace.yaml
|
|
10
|
+
* 2. For each packages/* folder, read its package.json
|
|
11
|
+
* 3. If it has client.procedures, dynamically import it
|
|
12
|
+
* 4. Procedures auto-register via PROCEDURE_REGISTRY
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from "node:fs";
|
|
15
|
+
import * as path from "node:path";
|
|
16
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
17
|
+
import { PROCEDURE_REGISTRY, allCoreProcedures, createRegistry, defineModule, pathToKey, registerModules, } from "@procedures/client";
|
|
18
|
+
/** The file of the `./module` export of a package, relative to the package folder. */
|
|
19
|
+
function moduleEntryOf(packageJson) {
|
|
20
|
+
const entry = packageJson.exports?.["./module"];
|
|
21
|
+
if (typeof entry === "string")
|
|
22
|
+
return entry;
|
|
23
|
+
if (entry && typeof entry === "object") {
|
|
24
|
+
const target = entry.import ?? entry.default;
|
|
25
|
+
return typeof target === "string" ? target : undefined;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// Discovery
|
|
31
|
+
// =============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Read and parse JSON file
|
|
34
|
+
*/
|
|
35
|
+
function readJson(filePath) {
|
|
36
|
+
try {
|
|
37
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
38
|
+
return JSON.parse(content);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Find the workspace root: the nearest folder above this module that holds pnpm-workspace.yaml
|
|
46
|
+
*/
|
|
47
|
+
export function findWorkspaceRoot() {
|
|
48
|
+
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
49
|
+
for (;;) {
|
|
50
|
+
if (fs.existsSync(path.join(dir, "pnpm-workspace.yaml"))) {
|
|
51
|
+
return dir;
|
|
52
|
+
}
|
|
53
|
+
const parent = path.dirname(dir);
|
|
54
|
+
if (parent === dir) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
dir = parent;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Discover workspace packages that declare client.procedures
|
|
62
|
+
*/
|
|
63
|
+
export function discoverFromEcosystem(root = findWorkspaceRoot()) {
|
|
64
|
+
const discovered = [];
|
|
65
|
+
if (!root) {
|
|
66
|
+
// Not running from inside the monorepo, nothing to discover
|
|
67
|
+
return discovered;
|
|
68
|
+
}
|
|
69
|
+
const packagesDir = path.join(root, "packages");
|
|
70
|
+
const entries = fs.readdirSync(packagesDir, { withFileTypes: true });
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (!entry.isDirectory()) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const packageDir = path.join(packagesDir, entry.name);
|
|
76
|
+
const packageJson = readJson(path.join(packageDir, "package.json"));
|
|
77
|
+
if (packageJson?.client?.procedures) {
|
|
78
|
+
discovered.push({
|
|
79
|
+
name: packageJson.name,
|
|
80
|
+
path: packageDir,
|
|
81
|
+
proceduresPath: packageJson.client.procedures,
|
|
82
|
+
modulePath: moduleEntryOf(packageJson),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return discovered;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* This function registers the core procedures of `@procedures/client` that its import does not
|
|
90
|
+
* register: the math, string, array, object, comparison, type and meta procedures (`client.add`
|
|
91
|
+
* and the others). The import registers only the control-flow procedures. (Docs review DOC-6:
|
|
92
|
+
* before, `mark client add` was an unknown command.) A procedure that is registered already stays.
|
|
93
|
+
*/
|
|
94
|
+
export function registerCoreProcedures() {
|
|
95
|
+
let added = 0;
|
|
96
|
+
for (const procedure of allCoreProcedures) {
|
|
97
|
+
if (!PROCEDURE_REGISTRY.has(procedure.path)) {
|
|
98
|
+
PROCEDURE_REGISTRY.register(procedure);
|
|
99
|
+
added++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return added;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Dynamically load procedures from discovered packages.
|
|
106
|
+
*
|
|
107
|
+
* A package that fails to load gives one warning line on stderr, also without `verbose`: before,
|
|
108
|
+
* its commands were missing with no message (deep dive CLI-18). A package that is not built yet
|
|
109
|
+
* (no procedures file) is reported only with `verbose`. `warn: false` turns the warnings off (the
|
|
110
|
+
* build of mark writes the manifest while other packages can still be in their build).
|
|
111
|
+
*/
|
|
112
|
+
export async function loadEcosystemProcedures(verbose = false, warn = true) {
|
|
113
|
+
registerCoreProcedures();
|
|
114
|
+
const discovered = discoverFromEcosystem();
|
|
115
|
+
const loaded = [];
|
|
116
|
+
for (const pkg of discovered) {
|
|
117
|
+
// Build the full path to the procedures file
|
|
118
|
+
const proceduresFullPath = path.join(pkg.path, pkg.proceduresPath);
|
|
119
|
+
// Check if file exists
|
|
120
|
+
if (!fs.existsSync(proceduresFullPath)) {
|
|
121
|
+
if (verbose) {
|
|
122
|
+
console.warn(`Procedures file not found (build the package): ${proceduresFullPath}`);
|
|
123
|
+
}
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
// Dynamic import - the module will self-register procedures. pathToFileURL escapes
|
|
128
|
+
// "#", "%" and spaces in the path (before, a string join broke such paths).
|
|
129
|
+
await import(pathToFileURL(proceduresFullPath).href);
|
|
130
|
+
loaded.push(pkg.name);
|
|
131
|
+
if (verbose) {
|
|
132
|
+
console.log(`Loaded procedures from: ${pkg.name}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
const message = error instanceof Error ? error.message.split("\n")[0] : String(error);
|
|
137
|
+
if (warn) {
|
|
138
|
+
console.warn(`mark: the procedures of ${pkg.name} did not load: ${message}`);
|
|
139
|
+
}
|
|
140
|
+
if (verbose && error instanceof Error && error.stack) {
|
|
141
|
+
console.warn(error.stack);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return loaded;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get list of ecosystem packages that have procedures
|
|
149
|
+
*/
|
|
150
|
+
export function listEcosystemProcedurePackages() {
|
|
151
|
+
return discoverFromEcosystem().map((pkg) => ({
|
|
152
|
+
name: pkg.name,
|
|
153
|
+
path: pkg.path,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
/** The core procedures that `mark` serves: all of them, also the ones that the core import does not register. */
|
|
157
|
+
const allCoreModule = defineModule("@procedures/client (all core procedures)", allCoreProcedures);
|
|
158
|
+
/**
|
|
159
|
+
* The module of a package: its `./module` entry (it registers nothing), or else the procedures
|
|
160
|
+
* that importing its procedures file adds to the global registry (a package of the old kind).
|
|
161
|
+
*/
|
|
162
|
+
async function moduleOfPackage(pkg) {
|
|
163
|
+
if (pkg.modulePath) {
|
|
164
|
+
const file = path.join(pkg.path, pkg.modulePath);
|
|
165
|
+
if (fs.existsSync(file)) {
|
|
166
|
+
const exports = (await import(pathToFileURL(file).href));
|
|
167
|
+
if (exports.default && Array.isArray(exports.default.procedures))
|
|
168
|
+
return exports.default;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const proceduresFile = path.join(pkg.path, pkg.proceduresPath);
|
|
172
|
+
if (!fs.existsSync(proceduresFile))
|
|
173
|
+
return undefined;
|
|
174
|
+
const before = new Set(PROCEDURE_REGISTRY.getAll().map((procedure) => pathToKey(procedure.path)));
|
|
175
|
+
await import(pathToFileURL(proceduresFile).href);
|
|
176
|
+
const added = PROCEDURE_REGISTRY.getAll().filter((procedure) => !before.has(pathToKey(procedure.path)));
|
|
177
|
+
return { name: pkg.name, procedures: added };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The registry of `mark` (roadmap 3.1): a registry of its own, built from the module of each
|
|
181
|
+
* workspace package that declares `client.procedures`, with all the core procedures. The global
|
|
182
|
+
* registry does not change for a package with a module entry. A package that fails to load gives
|
|
183
|
+
* one warning line on stderr, as with `loadEcosystemProcedures()`.
|
|
184
|
+
*/
|
|
185
|
+
export async function loadEcosystemRegistry(verbose = false, warn = true) {
|
|
186
|
+
const registry = createRegistry(allCoreModule);
|
|
187
|
+
const loaded = [];
|
|
188
|
+
for (const pkg of discoverFromEcosystem()) {
|
|
189
|
+
try {
|
|
190
|
+
const module = await moduleOfPackage(pkg);
|
|
191
|
+
if (!module) {
|
|
192
|
+
if (verbose)
|
|
193
|
+
console.warn(`Procedures file not found (build the package): ${path.join(pkg.path, pkg.proceduresPath)}`);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
registerModules(registry, [module]);
|
|
197
|
+
loaded.push(pkg.name);
|
|
198
|
+
if (verbose)
|
|
199
|
+
console.log(`Loaded procedures from: ${pkg.name}`);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
const message = error instanceof Error ? error.message.split("\n")[0] : String(error);
|
|
203
|
+
if (warn)
|
|
204
|
+
console.warn(`mark: the procedures of ${pkg.name} did not load: ${message}`);
|
|
205
|
+
if (verbose && error instanceof Error && error.stack)
|
|
206
|
+
console.warn(error.stack);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { registry, loaded };
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=ecosystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecosystem.js","sourceRoot":"","sources":["../src/ecosystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure-level failure
|
|
3
|
+
*
|
|
4
|
+
* A procedure reports a failure in one of three ways, and `mark` exits with code 1 for each:
|
|
5
|
+
*
|
|
6
|
+
* 1. It throws an error. This is the usual way.
|
|
7
|
+
* 2. It returns an object with `success: false`. Use this when the result has more to show,
|
|
8
|
+
* for example the list of problems of `lib audit`.
|
|
9
|
+
* 3. It returns an object with a numeric `exitCode` that is not 0. Use this for a procedure that
|
|
10
|
+
* runs an external command (`vitest run`, `shell run`), so the caller sees the command's result.
|
|
11
|
+
*
|
|
12
|
+
* For a streaming procedure, each item is examined: one failed item makes the command fail.
|
|
13
|
+
*/
|
|
14
|
+
/** A short description of the failure that a result reports, or undefined when it reports none */
|
|
15
|
+
export declare function failureOf(result: unknown): string | undefined;
|
|
16
|
+
//# sourceMappingURL=failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../src/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAa7D"}
|
package/dist/failure.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure-level failure
|
|
3
|
+
*
|
|
4
|
+
* A procedure reports a failure in one of three ways, and `mark` exits with code 1 for each:
|
|
5
|
+
*
|
|
6
|
+
* 1. It throws an error. This is the usual way.
|
|
7
|
+
* 2. It returns an object with `success: false`. Use this when the result has more to show,
|
|
8
|
+
* for example the list of problems of `lib audit`.
|
|
9
|
+
* 3. It returns an object with a numeric `exitCode` that is not 0. Use this for a procedure that
|
|
10
|
+
* runs an external command (`vitest run`, `shell run`), so the caller sees the command's result.
|
|
11
|
+
*
|
|
12
|
+
* For a streaming procedure, each item is examined: one failed item makes the command fail.
|
|
13
|
+
*/
|
|
14
|
+
/** A short description of the failure that a result reports, or undefined when it reports none */
|
|
15
|
+
export function failureOf(result) {
|
|
16
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const record = result;
|
|
20
|
+
const exitCode = record["exitCode"];
|
|
21
|
+
if (typeof exitCode === "number" && exitCode !== 0) {
|
|
22
|
+
return `exit code ${exitCode}`;
|
|
23
|
+
}
|
|
24
|
+
if (record["success"] === false) {
|
|
25
|
+
return firstText(record["error"]) ?? firstText(record["errors"]) ?? firstText(record["message"]) ?? "success: false";
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/** The first text of a value: a string, the message of an error object, or the first of a list */
|
|
30
|
+
function firstText(value) {
|
|
31
|
+
if (typeof value === "string" && value.length > 0) {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
for (const item of value) {
|
|
36
|
+
const text = firstText(item);
|
|
37
|
+
if (text)
|
|
38
|
+
return text;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
if (value && typeof value === "object" && typeof value.message === "string") {
|
|
43
|
+
return value.message;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=failure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.js","sourceRoot":"","sources":["../src/failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,kGAAkG;AAClG,MAAM,UAAU,SAAS,CAAC,MAAe;IACvC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,aAAa,QAAQ,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;QAChC,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,gBAAgB,CAAC;IACvH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,kGAAkG;AAClG,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC;QACxB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAQ,KAA+B,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvG,OAAQ,KAA6B,CAAC,OAAO,CAAC;IAChD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Formatting
|
|
3
|
+
*
|
|
4
|
+
* Formats procedure results for CLI output based on metadata hints.
|
|
5
|
+
*/
|
|
6
|
+
export type OutputFormat = "text" | "json" | "table" | "streaming";
|
|
7
|
+
/**
|
|
8
|
+
* Print interface (used by formatOutput)
|
|
9
|
+
*/
|
|
10
|
+
export interface Print {
|
|
11
|
+
info: (message: string) => void;
|
|
12
|
+
error: (message: string) => void;
|
|
13
|
+
success: (message: string) => void;
|
|
14
|
+
warning: (message: string) => void;
|
|
15
|
+
table: (data: string[][], options?: {
|
|
16
|
+
format?: string;
|
|
17
|
+
}) => void;
|
|
18
|
+
spin: (message: string) => Spinner;
|
|
19
|
+
}
|
|
20
|
+
export interface Spinner {
|
|
21
|
+
stop: () => void;
|
|
22
|
+
succeed: (message?: string) => void;
|
|
23
|
+
fail: (message?: string) => void;
|
|
24
|
+
text: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Format and print the result based on output format hint
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatOutput(print: Print, result: unknown, format?: OutputFormat): void;
|
|
30
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,EACf,MAAM,GAAE,YAAqB,GAC5B,IAAI,CAoBN"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Formatting
|
|
3
|
+
*
|
|
4
|
+
* Formats procedure results for CLI output based on metadata hints.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Format and print the result based on output format hint
|
|
8
|
+
*/
|
|
9
|
+
export function formatOutput(print, result, format = "text") {
|
|
10
|
+
if (result === undefined || result === null) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
switch (format) {
|
|
14
|
+
case "json":
|
|
15
|
+
print.info(JSON.stringify(result, null, 2));
|
|
16
|
+
break;
|
|
17
|
+
case "table":
|
|
18
|
+
formatTable(print, result);
|
|
19
|
+
break;
|
|
20
|
+
case "text":
|
|
21
|
+
case "streaming":
|
|
22
|
+
default:
|
|
23
|
+
formatText(print, result);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format as text - handles common result shapes
|
|
29
|
+
*/
|
|
30
|
+
function formatText(print, result) {
|
|
31
|
+
// String output
|
|
32
|
+
if (typeof result === "string") {
|
|
33
|
+
print.info(result);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Result with output field (common pattern)
|
|
37
|
+
if (isObjectWithOutput(result)) {
|
|
38
|
+
print.info(result.output);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Result with message field
|
|
42
|
+
if (isObjectWithMessage(result)) {
|
|
43
|
+
if (result.success === false) {
|
|
44
|
+
print.error(result.message);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
print.success(result.message);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Result with error field
|
|
52
|
+
if (isObjectWithError(result)) {
|
|
53
|
+
print.error(result.error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// Array of items
|
|
57
|
+
if (Array.isArray(result)) {
|
|
58
|
+
for (const item of result) {
|
|
59
|
+
formatText(print, item);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Fallback to JSON
|
|
64
|
+
print.info(JSON.stringify(result, null, 2));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Format as table - handles arrays of objects
|
|
68
|
+
*/
|
|
69
|
+
function formatTable(print, result) {
|
|
70
|
+
// Result with rows/headers
|
|
71
|
+
if (isTableResult(result)) {
|
|
72
|
+
const headers = result.headers ?? Object.keys(result.rows[0] ?? {});
|
|
73
|
+
const data = [headers];
|
|
74
|
+
for (const row of result.rows) {
|
|
75
|
+
if (Array.isArray(row)) {
|
|
76
|
+
data.push(row.map(String));
|
|
77
|
+
}
|
|
78
|
+
else if (typeof row === "object" && row !== null) {
|
|
79
|
+
data.push(headers.map((h) => String(row[h] ?? "")));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
print.table(data);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Plain array of objects
|
|
86
|
+
if (Array.isArray(result) && result.length > 0 && typeof result[0] === "object") {
|
|
87
|
+
const headers = Object.keys(result[0]);
|
|
88
|
+
const data = [headers];
|
|
89
|
+
for (const row of result) {
|
|
90
|
+
if (typeof row === "object" && row !== null) {
|
|
91
|
+
data.push(headers.map((h) => String(row[h] ?? "")));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
print.table(data);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Fallback to text
|
|
98
|
+
formatText(print, result);
|
|
99
|
+
}
|
|
100
|
+
// Type guards
|
|
101
|
+
function isObjectWithOutput(val) {
|
|
102
|
+
return (typeof val === "object" &&
|
|
103
|
+
val !== null &&
|
|
104
|
+
"output" in val &&
|
|
105
|
+
typeof val.output === "string");
|
|
106
|
+
}
|
|
107
|
+
function isObjectWithMessage(val) {
|
|
108
|
+
return (typeof val === "object" &&
|
|
109
|
+
val !== null &&
|
|
110
|
+
"message" in val &&
|
|
111
|
+
typeof val.message === "string");
|
|
112
|
+
}
|
|
113
|
+
function isObjectWithError(val) {
|
|
114
|
+
return (typeof val === "object" &&
|
|
115
|
+
val !== null &&
|
|
116
|
+
"error" in val &&
|
|
117
|
+
typeof val.error === "string");
|
|
118
|
+
}
|
|
119
|
+
function isTableResult(val) {
|
|
120
|
+
return (typeof val === "object" &&
|
|
121
|
+
val !== null &&
|
|
122
|
+
"rows" in val &&
|
|
123
|
+
Array.isArray(val.rows));
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark CLI
|
|
3
|
+
*
|
|
4
|
+
* A generic CLI that reflects registered procedures from client packages.
|
|
5
|
+
* Importing this module runs nothing: the `mark` bin (`dist/bin.js`) runs the CLI.
|
|
6
|
+
*/
|
|
7
|
+
export { run, main, executeArgs, initCli, type CliContext } from "./cli.js";
|
|
8
|
+
export { parseCommandLine, parseLeadingGlobals, type ParsedCommandLine, type Globals } from "./args.js";
|
|
9
|
+
export { failureOf } from "./failure.js";
|
|
10
|
+
export { parseFromSchema, generateHelp, extractSchemaFields, convertValue, type CLIMeta, type FieldType, type SchemaFieldInfo, } from "./parse.js";
|
|
11
|
+
export { formatOutput, type OutputFormat } from "./format.js";
|
|
12
|
+
export { readLockfile, writeLockfile, removeLockfile, isServerAlive, getLockfilePath, getLockfileDir, getLogPath, rotateLogFile, type LockfileData, } from "./lockfile.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACxG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,EACV,aAAa,EACb,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mark CLI
|
|
3
|
+
*
|
|
4
|
+
* A generic CLI that reflects registered procedures from client packages.
|
|
5
|
+
* Importing this module runs nothing: the `mark` bin (`dist/bin.js`) runs the CLI.
|
|
6
|
+
*/
|
|
7
|
+
export { run, main, executeArgs, initCli } from "./cli.js";
|
|
8
|
+
export { parseCommandLine, parseLeadingGlobals } from "./args.js";
|
|
9
|
+
export { failureOf } from "./failure.js";
|
|
10
|
+
export { parseFromSchema, generateHelp, extractSchemaFields, convertValue, } from "./parse.js";
|
|
11
|
+
export { formatOutput } from "./format.js";
|
|
12
|
+
export { readLockfile, writeLockfile, removeLockfile, isServerAlive, getLockfilePath, getLockfileDir, getLogPath, rotateLogFile, } from "./lockfile.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAwC,MAAM,WAAW,CAAC;AACxG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,YAAY,GAIb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAC9D,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,EACV,aAAa,GAEd,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lockfiles of the CLI server: `mark` uses the shared module of `client-server`, so `mark` and the
|
|
3
|
+
* `server.*` procedures read and write the same files the same way (deep dive CLI-4). This module
|
|
4
|
+
* adds what only `mark` needs: the log file and the build id.
|
|
5
|
+
*/
|
|
6
|
+
import { checkServer, findServer, readAllLockfiles, readLockfileForPort, removeLockfileForPort, type LockfileData } from "@procedures/peer/lockfile";
|
|
7
|
+
export type { LockfileData };
|
|
8
|
+
export { checkServer, findServer, readAllLockfiles, readLockfileForPort, removeLockfileForPort };
|
|
9
|
+
/**
|
|
10
|
+
* The build of this `mark`: its file and the time of its last build. A warm server runs only the
|
|
11
|
+
* commands of the same build (deep dive CLI-14): after `pnpm build`, or from another checkout,
|
|
12
|
+
* the CLI runs the command itself.
|
|
13
|
+
*/
|
|
14
|
+
export declare function currentBuild(): string;
|
|
15
|
+
export declare function writeLockfile(data: LockfileData): Promise<void>;
|
|
16
|
+
/** The first lockfile whose server answers as its peer (any folder, any build). */
|
|
17
|
+
export declare function readLockfile(): Promise<LockfileData | null>;
|
|
18
|
+
/** True when the lockfile's server answers as its peer. A dead server's lockfile is removed. */
|
|
19
|
+
export declare function isServerAlive(lockfile: LockfileData): Promise<boolean>;
|
|
20
|
+
/** This function removes the lockfile of the default port (3000). */
|
|
21
|
+
export declare function removeLockfile(): Promise<void>;
|
|
22
|
+
export declare function getLockfileDir(): string;
|
|
23
|
+
export declare function getLockfilePath(): string;
|
|
24
|
+
export declare function getLogPath(): string;
|
|
25
|
+
export declare function rotateLogFile(): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=lockfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACL,WAAW,EACX,UAAU,EAGV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EAErB,KAAK,YAAY,EAClB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,YAAY,EAAE,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAC;AAKjG;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAOrC;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;AAED,mFAAmF;AACnF,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAKjE;AAED,gGAAgG;AAChG,wBAAsB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5E;AAED,qEAAqE;AACrE,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAOnD"}
|