@hawkeyexl/manni 2.0.1 → 2.2.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 +1 -1
- package/dist/{chunk-MV2T7XAW.js → chunk-2Q5JUEIO.js} +380 -62
- package/dist/chunk-2Q5JUEIO.js.map +1 -0
- package/dist/{chunk-PDNSN5UJ.js → chunk-5O4FIGDJ.js} +4952 -758
- package/dist/chunk-5O4FIGDJ.js.map +1 -0
- package/dist/{chunk-QLVNSAHR.js → chunk-6JWX6JM2.js} +160 -550
- package/dist/chunk-6JWX6JM2.js.map +1 -0
- package/dist/cli.js +10 -18
- package/dist/cli.js.map +1 -1
- package/dist/docmeta.js +4 -3
- package/dist/docmeta.js.map +1 -1
- package/dist/index.d.ts +965 -565
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-MV2T7XAW.js.map +0 -1
- package/dist/chunk-PDNSN5UJ.js.map +0 -1
- package/dist/chunk-QLVNSAHR.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,13 +8,20 @@ import {
|
|
|
8
8
|
DocmetaError,
|
|
9
9
|
FILL_FORMATS,
|
|
10
10
|
FILL_FORMAT_LIST,
|
|
11
|
+
LOCATION_EXTERNAL_SCHEMA,
|
|
12
|
+
LOCATION_PAGE_SCHEMA,
|
|
11
13
|
OMITTED_WHEN_CLEAN,
|
|
12
14
|
QUERY_FORMATS,
|
|
13
15
|
QUERY_FORMAT_LIST,
|
|
14
16
|
REPORT_FORMATS,
|
|
15
17
|
REPORT_FORMAT_LIST,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
STDIN_LABEL,
|
|
19
|
+
Validator,
|
|
20
|
+
applyRelocation,
|
|
21
|
+
collectSchemaPins,
|
|
22
|
+
deriveFailed,
|
|
23
|
+
fail,
|
|
24
|
+
formatList,
|
|
18
25
|
getSchemasInfo,
|
|
19
26
|
isCommonFormat,
|
|
20
27
|
isDeriveFormat,
|
|
@@ -24,74 +31,37 @@ import {
|
|
|
24
31
|
isQueryFindingsFormat,
|
|
25
32
|
isQueryFormat,
|
|
26
33
|
isReportFormat,
|
|
34
|
+
keyHome,
|
|
27
35
|
notice,
|
|
36
|
+
offerPrompt,
|
|
28
37
|
package_default,
|
|
29
38
|
palette,
|
|
39
|
+
planRelocation,
|
|
30
40
|
programName,
|
|
41
|
+
relocateFailed,
|
|
42
|
+
relocationContext,
|
|
31
43
|
render,
|
|
32
44
|
renderDerive,
|
|
33
45
|
renderFill,
|
|
34
46
|
renderGet,
|
|
35
47
|
renderQuery,
|
|
36
48
|
renderQueryCsv,
|
|
49
|
+
resolveRunConfig,
|
|
37
50
|
rowsToFindings,
|
|
38
51
|
runDerive,
|
|
39
52
|
runFill,
|
|
40
53
|
runGet,
|
|
41
54
|
runInferSchema,
|
|
42
55
|
runQuery,
|
|
56
|
+
runRelocate,
|
|
43
57
|
runValidate,
|
|
44
58
|
runVendorSchema,
|
|
45
|
-
|
|
59
|
+
schemaLoadOptions,
|
|
46
60
|
shouldColor,
|
|
47
61
|
supportedExtensions,
|
|
48
62
|
terminalConfirm,
|
|
49
63
|
toJsonText
|
|
50
|
-
} from "./chunk-
|
|
51
|
-
|
|
52
|
-
// src/shared/run.ts
|
|
53
|
-
import { realpathSync } from "node:fs";
|
|
54
|
-
import { fileURLToPath } from "node:url";
|
|
55
|
-
import { CommanderError } from "commander";
|
|
56
|
-
function fail(err) {
|
|
57
|
-
const msg = err instanceof ToolError ? err.message : `Unexpected error: ${errorMessage(err)}`;
|
|
58
|
-
process.stderr.write(`${programName()}: ${msg}
|
|
59
|
-
`);
|
|
60
|
-
process.exit(2);
|
|
61
|
-
}
|
|
62
|
-
var STDIN_LINES_MARKER = "\0";
|
|
63
|
-
var STDIN_WITH_LINES = /^-(:[1-9][0-9]*(?:-[1-9][0-9]*)?)$/;
|
|
64
|
-
function normalizeStdinArgv(argv) {
|
|
65
|
-
return argv.map((arg) => {
|
|
66
|
-
const lines = STDIN_WITH_LINES.exec(arg)?.[1];
|
|
67
|
-
return lines === void 0 ? arg : `${STDIN_LINES_MARKER}${lines}`;
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
async function runProgram(program, argv = process.argv) {
|
|
71
|
-
setProgramName(program.name());
|
|
72
|
-
try {
|
|
73
|
-
await program.parseAsync(normalizeStdinArgv(argv));
|
|
74
|
-
} catch (err) {
|
|
75
|
-
if (err instanceof CommanderError) {
|
|
76
|
-
process.exitCode = err.exitCode === 0 ? 0 : 2;
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
throw err;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function isMainModule(moduleUrl) {
|
|
83
|
-
const entry = process.argv[1];
|
|
84
|
-
if (!entry) return false;
|
|
85
|
-
try {
|
|
86
|
-
return realpathSync(entry) === fileURLToPath(moduleUrl);
|
|
87
|
-
} catch {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function runIfMain(moduleUrl, build) {
|
|
92
|
-
if (!isMainModule(moduleUrl)) return;
|
|
93
|
-
runProgram(build()).catch(fail);
|
|
94
|
-
}
|
|
64
|
+
} from "./chunk-5O4FIGDJ.js";
|
|
95
65
|
|
|
96
66
|
// src/meta/cli.ts
|
|
97
67
|
import { existsSync } from "node:fs";
|
|
@@ -128,6 +98,238 @@ function reportConfig(toStdout, cwd) {
|
|
|
128
98
|
};
|
|
129
99
|
}
|
|
130
100
|
|
|
101
|
+
// src/meta/reporters/relocate.ts
|
|
102
|
+
var RELOCATE_FORMATS = ["pretty", "json"];
|
|
103
|
+
var RELOCATE_FORMAT_LIST = formatList(RELOCATE_FORMATS);
|
|
104
|
+
function isRelocateFormat(value) {
|
|
105
|
+
return RELOCATE_FORMATS.includes(value);
|
|
106
|
+
}
|
|
107
|
+
function renderRelocate(result, format, opts = {}) {
|
|
108
|
+
switch (format) {
|
|
109
|
+
case "json":
|
|
110
|
+
return JSON.stringify(relocateJson(result), null, 2);
|
|
111
|
+
case "pretty":
|
|
112
|
+
return renderRelocatePretty(result, opts);
|
|
113
|
+
default: {
|
|
114
|
+
const unreachable = format;
|
|
115
|
+
throw new DocmetaError(
|
|
116
|
+
`relocate --format must be pretty or json; got ${JSON.stringify(unreachable)}.`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function relocateJson(result) {
|
|
122
|
+
return {
|
|
123
|
+
dryRun: result.dryRun,
|
|
124
|
+
config: {
|
|
125
|
+
file: result.config.file,
|
|
126
|
+
created: result.config.created,
|
|
127
|
+
collectionsCreated: result.config.collectionsCreated,
|
|
128
|
+
pathsAdded: result.config.pathsAdded
|
|
129
|
+
},
|
|
130
|
+
manifests: result.manifests.map((m) => ({
|
|
131
|
+
file: m.file,
|
|
132
|
+
collection: m.collection,
|
|
133
|
+
created: m.created,
|
|
134
|
+
keysAdded: m.keysAdded,
|
|
135
|
+
keysRemoved: m.keysRemoved,
|
|
136
|
+
undeclared: m.undeclared
|
|
137
|
+
})),
|
|
138
|
+
files: result.files.map((f) => ({
|
|
139
|
+
file: f.file,
|
|
140
|
+
moved: f.moved,
|
|
141
|
+
stayed: f.stayed.map((s) => ({ key: s.key, reason: s.reason }))
|
|
142
|
+
})),
|
|
143
|
+
summary: result.summary
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
var plural = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
147
|
+
var list = (xs) => xs.join(", ");
|
|
148
|
+
function renderRelocatePretty(result, opts = {}) {
|
|
149
|
+
const c = palette(opts.color ?? false);
|
|
150
|
+
const dry = result.dryRun;
|
|
151
|
+
const lines = [];
|
|
152
|
+
if (result.config.created && result.config.file !== null) {
|
|
153
|
+
lines.push(dry ? `Would create ${result.config.file}.` : `Created ${result.config.file}.`);
|
|
154
|
+
}
|
|
155
|
+
const pathsOf = (collection) => result.config.pathsAdded.filter((p) => p.collection === collection).map((p) => p.path);
|
|
156
|
+
const said = /* @__PURE__ */ new Set();
|
|
157
|
+
for (const created of result.config.collectionsCreated) {
|
|
158
|
+
said.add(created.name);
|
|
159
|
+
const made = result.manifests.filter((m) => m.collection === created.name && m.created);
|
|
160
|
+
const head = `${dry ? "Would create" : "Created"} collection ${created.name} (paths: ${list(created.paths)})`;
|
|
161
|
+
if (made.length === 0) {
|
|
162
|
+
lines.push(`${head}.`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const owns = list(made.flatMap((m) => m.keys));
|
|
166
|
+
lines.push(`${head} and ${list(made.map((m) => m.file))}; it ${dry ? "would own" : "owns"} ${owns}.`);
|
|
167
|
+
}
|
|
168
|
+
for (const m of result.manifests) {
|
|
169
|
+
if (said.has(m.collection) && m.created) continue;
|
|
170
|
+
const added = said.has(m.collection) ? [] : pathsOf(m.collection);
|
|
171
|
+
if (added.length > 0) said.add(m.collection);
|
|
172
|
+
const keys = list(m.keys);
|
|
173
|
+
if (m.created) {
|
|
174
|
+
if (added.length > 0) {
|
|
175
|
+
lines.push(
|
|
176
|
+
dry ? `Would add ${list(added)} to collection ${m.collection}'s paths and create ${m.file}; it would own ${keys}.` : `Added ${list(added)} to collection ${m.collection}'s paths and created ${m.file}; it owns ${keys}.`
|
|
177
|
+
);
|
|
178
|
+
} else {
|
|
179
|
+
lines.push(
|
|
180
|
+
dry ? `Would create ${m.file}; collections[${m.collection}].externalMetadata[${m.index}] would own ${keys}.` : `Created ${m.file}; collections[${m.collection}].externalMetadata[${m.index}] owns ${keys}.`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const beyond = m.beyond > 0 ? `, ${m.beyond} beyond the paths you named` : "";
|
|
186
|
+
const pronoun = (n) => n === 1 ? "it" : "them";
|
|
187
|
+
if (m.keysRemoved.length > 0) {
|
|
188
|
+
const what = `${list(m.keysRemoved)} from ${m.file}'s keys`;
|
|
189
|
+
const it = pronoun(m.keysRemoved.length);
|
|
190
|
+
const where = `into every page in collection ${m.collection}${beyond}`;
|
|
191
|
+
lines.push(dry ? `Would remove ${what}, moving ${it} ${where}.` : `Removing ${what} moves ${it} ${where}.`);
|
|
192
|
+
}
|
|
193
|
+
if (added.length > 0) {
|
|
194
|
+
lines.push(
|
|
195
|
+
dry ? `Would add ${list(added)} to collection ${m.collection}'s paths; ${m.file} would own ${keys}.` : `Added ${list(added)} to collection ${m.collection}'s paths; ${m.file} now owns ${keys}.`
|
|
196
|
+
);
|
|
197
|
+
} else if (m.keysAdded.length > 0) {
|
|
198
|
+
const what = `${list(m.keysAdded)} to ${m.file}'s keys`;
|
|
199
|
+
const it = pronoun(m.keysAdded.length);
|
|
200
|
+
const where = `out of every page in collection ${m.collection}${beyond}`;
|
|
201
|
+
lines.push(dry ? `Would add ${what}, moving ${it} ${where}.` : `Adding ${what} moves ${it} ${where}.`);
|
|
202
|
+
}
|
|
203
|
+
if (m.undeclared) {
|
|
204
|
+
lines.push(
|
|
205
|
+
dry ? `${m.file} would no longer own any keys and would no longer be declared; delete it when you are ready.` : `${m.file} no longer owns any keys and is no longer declared; delete it when you are ready.`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
for (const p of result.config.pathsAdded) {
|
|
210
|
+
if (said.has(p.collection)) continue;
|
|
211
|
+
said.add(p.collection);
|
|
212
|
+
lines.push(`${dry ? "Would add" : "Added"} ${list(pathsOf(p.collection))} to collection ${p.collection}'s paths.`);
|
|
213
|
+
}
|
|
214
|
+
const width = Math.max(
|
|
215
|
+
7,
|
|
216
|
+
...result.files.flatMap((f) => [...f.moved, ...f.stayed].map((v) => v.key.length))
|
|
217
|
+
);
|
|
218
|
+
const shown = result.files.filter((f) => !f.beyond || f.stayed.length > 0);
|
|
219
|
+
for (const f of shown) {
|
|
220
|
+
lines.push(f.file);
|
|
221
|
+
for (const mv of f.moved) {
|
|
222
|
+
const name = c.cyan(mv.key.padEnd(width));
|
|
223
|
+
if (mv.to === "page") {
|
|
224
|
+
lines.push(` ${name} \u2190 ${mv.from}`);
|
|
225
|
+
} else {
|
|
226
|
+
lines.push(` ${name} \u2192 ${mv.manifest}${mv.line !== void 0 ? `:${mv.line}` : ""}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
for (const st of f.stayed) {
|
|
230
|
+
lines.push(` ${c.cyan(st.key.padEnd(width))} ${c.yellow(`stays: ${st.detail ?? st.reason}`)}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const hidden = result.files.length - shown.length;
|
|
234
|
+
if (hidden > 0) lines.push(`\u2026 (${plural(hidden, "more file")})`);
|
|
235
|
+
const s = result.summary;
|
|
236
|
+
if (s.files === 0) {
|
|
237
|
+
lines.push("0 files, nothing to move");
|
|
238
|
+
return lines.join("\n");
|
|
239
|
+
}
|
|
240
|
+
const moves = result.files.flatMap((f) => f.moved);
|
|
241
|
+
const toPage = moves.filter((m) => m.to === "page").length;
|
|
242
|
+
const toManifest = moves.flatMap((m) => m.to === "manifest" ? [m.manifest] : []);
|
|
243
|
+
const manifests = plural(new Set(toManifest).size, "manifest");
|
|
244
|
+
let footer = `${plural(s.files, "file")}, ${plural(s.moved, "value")} ${dry ? "would move" : "moved"}`;
|
|
245
|
+
if (toPage > 0 && toManifest.length > 0) {
|
|
246
|
+
footer += `: ${toPage} into pages, ${toManifest.length} into ${manifests}`;
|
|
247
|
+
} else if (toManifest.length > 0) {
|
|
248
|
+
footer += ` to ${manifests}`;
|
|
249
|
+
} else if (toPage > 0) {
|
|
250
|
+
footer += " into pages";
|
|
251
|
+
}
|
|
252
|
+
if (s.stayed > 0) footer += `, ${s.stayed} stayed`;
|
|
253
|
+
lines.push(s.stayed > 0 ? c.yellow(footer) : footer);
|
|
254
|
+
return lines.join("\n");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// src/meta/commands/validate-offer.ts
|
|
258
|
+
async function offerRelocation(opts) {
|
|
259
|
+
const { confirm, output } = opts;
|
|
260
|
+
if (confirm === void 0 || opts.noConfig === true) return [];
|
|
261
|
+
const findings = opts.results.flatMap(
|
|
262
|
+
(r) => r.file === STDIN_LABEL ? [] : r.errors.filter((e) => e.schema === LOCATION_EXTERNAL_SCHEMA || e.schema === LOCATION_PAGE_SCHEMA).flatMap((e) => e.subject === void 0 ? [] : [{ file: r.file, key: e.subject, schema: e.schema }])
|
|
263
|
+
);
|
|
264
|
+
if (findings.length === 0) return [];
|
|
265
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
266
|
+
const run = await resolveRunConfig({
|
|
267
|
+
cwd,
|
|
268
|
+
...opts.configPath !== void 0 ? { configPath: opts.configPath } : {},
|
|
269
|
+
inputs: opts.inputs,
|
|
270
|
+
...opts.collections !== void 0 ? { collections: opts.collections } : {}
|
|
271
|
+
});
|
|
272
|
+
const validator = new Validator(
|
|
273
|
+
schemaLoadOptions({
|
|
274
|
+
root: run.configDir ?? cwd,
|
|
275
|
+
fileBase: cwd,
|
|
276
|
+
ttlHours: run.config?.schemaCache?.ttlHours,
|
|
277
|
+
offline: opts.offline ?? run.config?.offline,
|
|
278
|
+
pins: collectSchemaPins(run.config)
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
const ctx = relocationContext(run, {
|
|
282
|
+
cwd,
|
|
283
|
+
targets: run.fromCollections ? [] : opts.inputs,
|
|
284
|
+
validator,
|
|
285
|
+
...opts.cliSchemas !== void 0 && opts.cliSchemas.length > 0 ? { cliSchemas: opts.cliSchemas } : {},
|
|
286
|
+
...opts.as !== void 0 ? { as: opts.as } : {},
|
|
287
|
+
...opts.respectGitignore !== void 0 ? { respectGitignore: opts.respectGitignore } : {},
|
|
288
|
+
...opts.env !== void 0 ? { env: opts.env } : {}
|
|
289
|
+
});
|
|
290
|
+
const groups = /* @__PURE__ */ new Map();
|
|
291
|
+
for (const f of findings) {
|
|
292
|
+
const home = await keyHome(ctx, f.file, {}, f.key);
|
|
293
|
+
let collection;
|
|
294
|
+
if (f.schema === LOCATION_PAGE_SCHEMA) {
|
|
295
|
+
if (home.kind === "manifest") collection = home.collection;
|
|
296
|
+
} else if (home.kind === "unowned" && home.home.kind === "collection") {
|
|
297
|
+
collection = home.home.collection;
|
|
298
|
+
}
|
|
299
|
+
if (collection === void 0) continue;
|
|
300
|
+
const group = groups.get(collection) ?? { files: /* @__PURE__ */ new Set(), keys: /* @__PURE__ */ new Set() };
|
|
301
|
+
group.files.add(f.file);
|
|
302
|
+
group.keys.add(f.key);
|
|
303
|
+
groups.set(collection, group);
|
|
304
|
+
}
|
|
305
|
+
const applied = [];
|
|
306
|
+
const say = (message) => {
|
|
307
|
+
output.write(`${programName()}: ${message}
|
|
308
|
+
`);
|
|
309
|
+
};
|
|
310
|
+
for (const [collection, group] of groups) {
|
|
311
|
+
let plan;
|
|
312
|
+
try {
|
|
313
|
+
plan = await planRelocation(ctx, { files: [...group.files], fields: [...group.keys] });
|
|
314
|
+
} catch (err) {
|
|
315
|
+
if (!(err instanceof DocmetaError)) throw err;
|
|
316
|
+
say(err.message);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (plan.writes.length === 0) continue;
|
|
320
|
+
const offer = plan.offers.find((o) => o.collection === collection);
|
|
321
|
+
if (offer === void 0) continue;
|
|
322
|
+
const { notice: notice2, question } = offerPrompt(offer, "validate");
|
|
323
|
+
say(notice2);
|
|
324
|
+
if (!await confirm(question)) continue;
|
|
325
|
+
const result = await applyRelocation(ctx, plan);
|
|
326
|
+
output.write(`${renderRelocatePretty(result, { color: opts.color ?? false })}
|
|
327
|
+
`);
|
|
328
|
+
applied.push(result);
|
|
329
|
+
}
|
|
330
|
+
return applied;
|
|
331
|
+
}
|
|
332
|
+
|
|
131
333
|
// src/meta/reporters/infer.ts
|
|
132
334
|
var OUTLIERS_SHOWN = 5;
|
|
133
335
|
var ENUM_SHOWN = 3;
|
|
@@ -542,6 +744,22 @@ function buildProgram() {
|
|
|
542
744
|
`);
|
|
543
745
|
}
|
|
544
746
|
process.exitCode = summary.failed > 0 ? 1 : 0;
|
|
747
|
+
await offerRelocation({
|
|
748
|
+
results,
|
|
749
|
+
inputs: paths,
|
|
750
|
+
cliSchemas: options.schema,
|
|
751
|
+
as: options.as,
|
|
752
|
+
collections: options.collection,
|
|
753
|
+
...configOption(options.config),
|
|
754
|
+
respectGitignore: explicitFalse(options.gitignore),
|
|
755
|
+
offline: options.offline ? true : void 0,
|
|
756
|
+
confirm: paths.includes(STDIN) ? void 0 : terminalConfirm(),
|
|
757
|
+
output: process.stderr,
|
|
758
|
+
color: shouldColor({
|
|
759
|
+
noColor: (command.parent ?? command).opts().color === false,
|
|
760
|
+
isTTY: process.stderr.isTTY
|
|
761
|
+
})
|
|
762
|
+
});
|
|
545
763
|
} catch (err) {
|
|
546
764
|
fail(err);
|
|
547
765
|
}
|
|
@@ -762,7 +980,17 @@ function buildProgram() {
|
|
|
762
980
|
onNotice: notice,
|
|
763
981
|
// A write to a column marked x-manni-encrypt with no key asks
|
|
764
982
|
// for one on a terminal, and refuses off one (proposal 0045).
|
|
765
|
-
|
|
983
|
+
// The same Confirm asks P1 (proposal 0047).
|
|
984
|
+
confirm: terminalConfirm(),
|
|
985
|
+
// An accepted P1 offer prints relocate's report: on stdout
|
|
986
|
+
// beside a pretty report, on stderr when stdout must parse.
|
|
987
|
+
onRelocated: (result) => {
|
|
988
|
+
const text = renderRelocate(result, "pretty", {
|
|
989
|
+
color: format === "pretty" && resolveColor(command.parent ?? command)
|
|
990
|
+
});
|
|
991
|
+
(format === "pretty" ? process.stdout : process.stderr).write(`${text}
|
|
992
|
+
`);
|
|
993
|
+
}
|
|
766
994
|
});
|
|
767
995
|
if (run.db && sql === "") {
|
|
768
996
|
process.stdout.write(
|
|
@@ -926,8 +1154,18 @@ function buildProgram() {
|
|
|
926
1154
|
includeContent: usingStdin,
|
|
927
1155
|
// A field marked x-manni-encrypt with no key asks for one on a
|
|
928
1156
|
// terminal, and refuses off one (proposal 0045). Reading the page
|
|
929
|
-
// from stdin leaves no terminal to ask on.
|
|
930
|
-
|
|
1157
|
+
// from stdin leaves no terminal to ask on. The same Confirm asks
|
|
1158
|
+
// P1 (proposal 0047).
|
|
1159
|
+
confirm: usingStdin ? void 0 : terminalConfirm(),
|
|
1160
|
+
// An accepted P1 offer prints relocate's report: on stdout beside a
|
|
1161
|
+
// pretty report, on stderr when stdout must parse.
|
|
1162
|
+
onRelocated: (result) => {
|
|
1163
|
+
const text = renderRelocate(result, "pretty", {
|
|
1164
|
+
color: format === "pretty" && resolveColor(command.parent ?? command)
|
|
1165
|
+
});
|
|
1166
|
+
(format === "pretty" ? process.stdout : process.stderr).write(`${text}
|
|
1167
|
+
`);
|
|
1168
|
+
}
|
|
931
1169
|
});
|
|
932
1170
|
const color = resolveColor(command.parent ?? command);
|
|
933
1171
|
const report = renderFill(format, run, {
|
|
@@ -950,9 +1188,15 @@ function buildProgram() {
|
|
|
950
1188
|
});
|
|
951
1189
|
program.command("derive").description(
|
|
952
1190
|
"Stamp the managed stewardship fields from git history, CODEOWNERS and GitHub or GitLab reviews"
|
|
953
|
-
).argument(
|
|
1191
|
+
).argument(
|
|
1192
|
+
"[paths...]",
|
|
1193
|
+
"files, directories, or globs to stamp; <path>:L1-L2 names lines for --generated-by"
|
|
1194
|
+
).option(
|
|
954
1195
|
"--fields <list>",
|
|
955
1196
|
"comma-separated managed fields to stamp; config derive.fields otherwise"
|
|
1197
|
+
).option(
|
|
1198
|
+
"--generated-by <name>",
|
|
1199
|
+
"attribute uncommitted body lines, or a <path>:L1-L2 range, to this machine in provenance; MANNI_GENERATED_BY otherwise"
|
|
956
1200
|
).option(
|
|
957
1201
|
"--sources <list>",
|
|
958
1202
|
"comma-separated sources to consult: git, codeowners, github, gitlab, command (default all)"
|
|
@@ -978,7 +1222,9 @@ function buildProgram() {
|
|
|
978
1222
|
" manni meta derive --dry-run docs/install.md # what would change, nothing written",
|
|
979
1223
|
" manni meta derive --check -f github # CI: a stale stamp is an annotation, exit 1",
|
|
980
1224
|
" manni meta derive --fields reviewed-by,last-reviewed",
|
|
981
|
-
" manni meta derive --sources git,codeowners # no gh on this machine"
|
|
1225
|
+
" manni meta derive --sources git,codeowners # no gh on this machine",
|
|
1226
|
+
" MANNI_GENERATED_BY=claude-fable-5 manni meta derive --fields provenance",
|
|
1227
|
+
" manni meta derive docs/limits.md:12-31 --generated-by claude-fable-5"
|
|
982
1228
|
].join("\n")
|
|
983
1229
|
).action(async (paths, options, command) => {
|
|
984
1230
|
try {
|
|
@@ -998,6 +1244,7 @@ function buildProgram() {
|
|
|
998
1244
|
inputs: paths,
|
|
999
1245
|
fields: options.fields ? splitList(options.fields) : void 0,
|
|
1000
1246
|
sources: options.sources ? splitList(options.sources) : void 0,
|
|
1247
|
+
...options.generatedBy !== void 0 ? { generatedBy: options.generatedBy } : {},
|
|
1001
1248
|
dryRun: Boolean(options.dryRun),
|
|
1002
1249
|
check: Boolean(options.check),
|
|
1003
1250
|
cache: options.cache,
|
|
@@ -1011,8 +1258,18 @@ function buildProgram() {
|
|
|
1011
1258
|
respectGitignore: explicitFalse(options.gitignore),
|
|
1012
1259
|
onNotice: notice,
|
|
1013
1260
|
// A field its schema marks x-manni-encrypt (proposal 0045) with no
|
|
1014
|
-
// key yet: asked on a terminal, refused off one.
|
|
1015
|
-
|
|
1261
|
+
// key yet: asked on a terminal, refused off one. The same Confirm
|
|
1262
|
+
// asks P1 (proposal 0047).
|
|
1263
|
+
confirm: terminalConfirm(),
|
|
1264
|
+
// An accepted P1 offer prints relocate's report: on stdout beside a
|
|
1265
|
+
// pretty report, on stderr when stdout must parse.
|
|
1266
|
+
onRelocated: (result) => {
|
|
1267
|
+
const text2 = renderRelocate(result, "pretty", {
|
|
1268
|
+
color: format === "pretty" && resolveColor(command.parent ?? command)
|
|
1269
|
+
});
|
|
1270
|
+
(format === "pretty" ? process.stdout : process.stderr).write(`${text2}
|
|
1271
|
+
`);
|
|
1272
|
+
}
|
|
1016
1273
|
});
|
|
1017
1274
|
const text = renderDerive(run, format, {
|
|
1018
1275
|
color: resolveColor(command.parent ?? command),
|
|
@@ -1023,9 +1280,73 @@ function buildProgram() {
|
|
|
1023
1280
|
process.stdout.write(`${text}
|
|
1024
1281
|
`);
|
|
1025
1282
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1283
|
+
process.exitCode = deriveFailed(run) ? 1 : 0;
|
|
1284
|
+
} catch (err) {
|
|
1285
|
+
fail(err);
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
program.command("relocate").description(
|
|
1289
|
+
"Move each value to where its schema's x-manni-location and the config's manifests say it belongs"
|
|
1290
|
+
).argument(
|
|
1291
|
+
"[paths...]",
|
|
1292
|
+
"files, directories, or globs to relocate (stdin is refused)"
|
|
1293
|
+
).option(
|
|
1294
|
+
"--fields <list>",
|
|
1295
|
+
"comma-separated fields to move; each must be marked x-manni-location or manifest-owned"
|
|
1296
|
+
).option(
|
|
1297
|
+
"--collection <name>",
|
|
1298
|
+
"configured collection to run over; repeatable",
|
|
1299
|
+
collect,
|
|
1300
|
+
[]
|
|
1301
|
+
).option(
|
|
1302
|
+
"-s, --schema <ref>",
|
|
1303
|
+
"schema to judge preferences against; repeatable; overrides $schema/config",
|
|
1304
|
+
collect,
|
|
1305
|
+
[]
|
|
1306
|
+
).option("--dry-run", "report what would move and be created, and write nothing").option(
|
|
1307
|
+
"-f, --format <format>",
|
|
1308
|
+
`output: ${RELOCATE_FORMATS.join(" | ")}`,
|
|
1309
|
+
"pretty"
|
|
1310
|
+
).option("--ext <list>", "comma-separated extensions for directory walks").option("--exclude <glob>", "glob to exclude; repeatable", collect, []).option("--as <format>", "force an input format (e.g. markdown, mdx)").option("-c, --config <path>", "path to a manni config file").option("--no-config", "ignore any discovered config file (refused: relocate writes the config)").option("--allow-empty", "treat zero matched files as success").option("--no-gitignore", "relocate files .gitignore covers").addHelpText(
|
|
1311
|
+
"after",
|
|
1312
|
+
[
|
|
1313
|
+
"",
|
|
1314
|
+
"Examples:",
|
|
1315
|
+
" manni meta relocate # every collection, as config declares it",
|
|
1316
|
+
" manni meta relocate --dry-run # what would move and be created",
|
|
1317
|
+
" manni meta relocate docs/install.md --fields owner",
|
|
1318
|
+
" manni meta relocate docs/ guides/intro.md # no collections yet: creates collection default",
|
|
1319
|
+
" manni meta relocate -f json --dry-run # the scripting form"
|
|
1320
|
+
].join("\n")
|
|
1321
|
+
).action(async (paths, options, command) => {
|
|
1322
|
+
try {
|
|
1323
|
+
const format = options.format;
|
|
1324
|
+
if (!isRelocateFormat(format)) {
|
|
1325
|
+
throw new DocmetaError(
|
|
1326
|
+
`relocate --format must be pretty or json; got "${format}".`
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
const result = await runRelocate({
|
|
1330
|
+
inputs: paths,
|
|
1331
|
+
fields: options.fields ? splitList(options.fields) : void 0,
|
|
1332
|
+
collections: options.collection,
|
|
1333
|
+
cliSchemas: options.schema,
|
|
1334
|
+
dryRun: Boolean(options.dryRun),
|
|
1335
|
+
exts: options.ext ? splitList(options.ext) : void 0,
|
|
1336
|
+
exclude: options.exclude,
|
|
1337
|
+
as: options.as,
|
|
1338
|
+
...configOption(options.config),
|
|
1339
|
+
onConfigLoaded: reportConfig(format === "pretty", process.cwd()),
|
|
1340
|
+
allowEmpty: options.allowEmpty ? true : void 0,
|
|
1341
|
+
respectGitignore: explicitFalse(options.gitignore),
|
|
1342
|
+
onNotice: notice
|
|
1343
|
+
});
|
|
1344
|
+
const text = renderRelocate(result, format, {
|
|
1345
|
+
color: resolveColor(command.parent ?? command)
|
|
1346
|
+
});
|
|
1347
|
+
process.stdout.write(`${text}
|
|
1348
|
+
`);
|
|
1349
|
+
process.exitCode = relocateFailed(result) ? 1 : 0;
|
|
1029
1350
|
} catch (err) {
|
|
1030
1351
|
fail(err);
|
|
1031
1352
|
}
|
|
@@ -1195,9 +1516,6 @@ function buildProgram() {
|
|
|
1195
1516
|
}
|
|
1196
1517
|
|
|
1197
1518
|
export {
|
|
1198
|
-
fail,
|
|
1199
|
-
STDIN_LINES_MARKER,
|
|
1200
|
-
runIfMain,
|
|
1201
1519
|
collect,
|
|
1202
1520
|
splitList,
|
|
1203
1521
|
readStdin,
|
|
@@ -1206,4 +1524,4 @@ export {
|
|
|
1206
1524
|
reportConfig,
|
|
1207
1525
|
buildProgram
|
|
1208
1526
|
};
|
|
1209
|
-
//# sourceMappingURL=chunk-
|
|
1527
|
+
//# sourceMappingURL=chunk-2Q5JUEIO.js.map
|