@okfit/cli 0.6.12 → 0.8.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 +77 -3
- package/commands/context.js +0 -2
- package/commands/graph.js +0 -2
- package/commands/init.js +56 -23
- package/commands/lint.js +4 -5
- package/commands/query.js +172 -0
- package/commands/root.js +8 -4
- package/commands/stale.js +0 -2
- package/commands/sync.js +0 -2
- package/commands/validate.js +4 -5
- package/commands/verify-picker.js +75 -0
- package/commands/verify.js +48 -11
- package/errors.js +13 -2
- package/index.d.ts +61 -7
- package/index.js +2 -1
- package/internal/initWizard.js +121 -0
- package/internal/versionFormatter.js +1 -1
- package/main.js +4 -4
- package/package.json +20 -17
- package/render/human.js +2 -13
- package/render/query.js +58 -0
- package/render/verify.js +10 -6
- package/version.js +1 -1
- package/internal/exit.js +0 -14
package/render/human.js
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
import { sort } from "@okfit/engine";
|
|
2
2
|
|
|
3
3
|
//#region src/render/human.ts
|
|
4
|
-
/** The ANSI escape character, built from its code point so the source never carries a raw control byte. */
|
|
5
|
-
const ESC = String.fromCharCode(27);
|
|
6
|
-
/** ANSI SGR codes for the severity word only (K-19); reset after, never applied elsewhere. */
|
|
7
|
-
const SEVERITY_COLOR = {
|
|
8
|
-
error: `${ESC}[31m`,
|
|
9
|
-
warning: `${ESC}[33m`,
|
|
10
|
-
info: `${ESC}[36m`
|
|
11
|
-
};
|
|
12
|
-
const RESET = `${ESC}[0m`;
|
|
13
|
-
const colorize = (severity, color) => color ? `${SEVERITY_COLOR[severity]}${severity}${RESET}` : severity;
|
|
14
4
|
/**
|
|
15
5
|
* K-16. With a range:
|
|
16
6
|
* `<file>:<range.line + 1>:<range.character + 1> <severity> <code> <message>`.
|
|
17
7
|
* Without one: `<file> <severity> <code> <message>`. `file: ""` renders as
|
|
18
8
|
* the literal `(bundle)`. Core's range is zero-based (D-32,
|
|
19
9
|
* `CORE/Diagnostic.ts:49-57`); the `+ 1`s here are the only place it becomes
|
|
20
|
-
* one-based. Colour, when `
|
|
10
|
+
* one-based. Colour, when a `paint` is given, wraps ONLY the severity word
|
|
21
11
|
* (K-19) — never the code, the path, or the message.
|
|
22
12
|
*
|
|
23
13
|
* @public
|
|
24
14
|
*/
|
|
25
15
|
const line = (diagnostic, options) => {
|
|
26
|
-
const color = options?.color ?? false;
|
|
27
16
|
const file = diagnostic.file === "" ? "(bundle)" : diagnostic.file;
|
|
28
|
-
const severity =
|
|
17
|
+
const severity = options?.paint === void 0 ? diagnostic.severity : options.paint(diagnostic.severity, diagnostic.severity);
|
|
29
18
|
return `${diagnostic.range === void 0 ? file : `${file}:${diagnostic.range.line + 1}:${diagnostic.range.character + 1}`} ${severity} ${diagnostic.code} ${diagnostic.message}`;
|
|
30
19
|
};
|
|
31
20
|
/**
|
package/render/query.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { Timestamp } from "@okfit/core";
|
|
3
|
+
|
|
4
|
+
//#region src/render/query.ts
|
|
5
|
+
/**
|
|
6
|
+
* One line per concept: `<id> <status> <type> <title>`. `items` arrive
|
|
7
|
+
* already sorted by id (`ConceptQuery.list`), so this never re-sorts.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
const humanQueryList = (items) => items.map((item) => `${item.id} ${item.status} ${item.type} ${item.title}`);
|
|
12
|
+
/**
|
|
13
|
+
* `<N> concepts in <root>` (`1 concept` for one) — the one-line stderr summary.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
const queryListSummary = (total, root) => `${total} ${total === 1 ? "concept" : "concepts"} in ${root}`;
|
|
18
|
+
/**
|
|
19
|
+
* The bare id, then `key: value` lines, one `verified:` line per attestation,
|
|
20
|
+
* then the outgoing links.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
const humanQueryGet = (input) => {
|
|
25
|
+
const { summary } = input;
|
|
26
|
+
return [
|
|
27
|
+
summary.id,
|
|
28
|
+
`type: ${summary.type}`,
|
|
29
|
+
`title: ${summary.title}`,
|
|
30
|
+
`status: ${summary.status}`,
|
|
31
|
+
`tags: ${summary.tags.length === 0 ? "(none)" : summary.tags.join(", ")}`,
|
|
32
|
+
`path: ${summary.path}`,
|
|
33
|
+
...input.verified.map((entry) => `verified: ${entry.by} at ${Schema.encodeSync(Timestamp)(entry.at)}`),
|
|
34
|
+
"links:",
|
|
35
|
+
...input.links.length === 0 ? [" (none)"] : input.links.map((link) => {
|
|
36
|
+
const detail = [
|
|
37
|
+
link.kind,
|
|
38
|
+
link.source,
|
|
39
|
+
...link.field === void 0 ? [] : [link.field]
|
|
40
|
+
].join(", ");
|
|
41
|
+
return ` -> ${link.to} (${detail})`;
|
|
42
|
+
})
|
|
43
|
+
];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* `outgoing:` then `incoming:`, each a list of `->`/`<-` lines or `(none)`.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
const humanQueryNeighbors = (input) => [
|
|
51
|
+
"outgoing:",
|
|
52
|
+
...input.outgoing.length === 0 ? [" (none)"] : input.outgoing.map((n) => ` -> ${n.id} (${n.kind})`),
|
|
53
|
+
"incoming:",
|
|
54
|
+
...input.incoming.length === 0 ? [" (none)"] : input.incoming.map((n) => ` <- ${n.id} (${n.kind})`)
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
export { humanQueryGet, humanQueryList, humanQueryNeighbors, queryListSummary };
|
package/render/verify.js
CHANGED
|
@@ -19,11 +19,15 @@ const indentFragment = (fragment) => {
|
|
|
19
19
|
*
|
|
20
20
|
* @public
|
|
21
21
|
*/
|
|
22
|
-
const humanVerify = (input) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const humanVerify = (input) => {
|
|
23
|
+
const statusSuffix = input.status === null ? "" : input.status.from === input.status.to ? `; status already ${input.status.to}` : `; status ${input.status.from ?? "(absent)"} -> ${input.status.to}`;
|
|
24
|
+
return [
|
|
25
|
+
...input.priorAt.map((at) => `already verified by ${input.by} at ${at}; appending`),
|
|
26
|
+
input.dryRun ? `would verify ${input.id} by ${input.by} at ${input.at}${statusSuffix} (dry run, nothing written)` : `verified ${input.id} by ${input.by} at ${input.at}${statusSuffix}`,
|
|
27
|
+
...input.dryRun ? ["would write:", ...indentFragment(input.fragment)] : [],
|
|
28
|
+
...input.dryRun && input.statusFragment !== null ? ["would set status:", ...indentFragment(input.statusFragment)] : []
|
|
29
|
+
];
|
|
30
|
+
};
|
|
27
31
|
/**
|
|
28
32
|
* V-11-at-batch-scale (#138): one line per skipped candidate, then one line
|
|
29
33
|
* (or, under `--dry-run`, three) per verified concept, then a trailing tally.
|
|
@@ -31,7 +35,7 @@ const humanVerify = (input) => [
|
|
|
31
35
|
* @public
|
|
32
36
|
*/
|
|
33
37
|
const humanVerifyBatch = (input) => [
|
|
34
|
-
...input.skipped.map((entry) => entry.reason === "
|
|
38
|
+
...input.skipped.map((entry) => entry.reason === "already-verified" ? `skipped ${entry.id}: already verified by ${input.by}` : `skipped ${entry.id}: ${entry.reason}`),
|
|
35
39
|
...input.verified.flatMap((entry) => input.dryRun ? [
|
|
36
40
|
`would verify ${entry.id} by ${input.by} at ${input.at}`,
|
|
37
41
|
"would write:",
|
package/version.js
CHANGED
package/internal/exit.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
//#region src/internal/exit.ts
|
|
2
|
-
/**
|
|
3
|
-
* K-7: exits `1` and `2` are a SUCCESSFUL run that found diagnostics, never
|
|
4
|
-
* an Effect failure. The handler writes the code here and returns `void`.
|
|
5
|
-
* The only writer of `process.exitCode` in this package.
|
|
6
|
-
*
|
|
7
|
-
* @public
|
|
8
|
-
*/
|
|
9
|
-
const setExitCode = (code) => {
|
|
10
|
-
process.exitCode = code;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
//#endregion
|
|
14
|
-
export { setExitCode };
|