@wirecat/cli-base 0.44.4 → 0.45.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 +2 -1
- package/config/wirecat/biome.base.json +39 -2
- package/config/wirecat/manifest.json +6 -9
- package/config/wirecat/no-deep-wirecat-import.grit +15 -0
- package/dist/commands/document.d.ts +1 -1
- package/dist/commands/document.d.ts.map +1 -1
- package/dist/commands/document.js +1 -1
- package/dist/commands/document.js.map +1 -1
- package/dist/commands/index.d.ts +2 -121
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -105
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/page.d.ts +1 -1
- package/dist/commands/page.d.ts.map +1 -1
- package/dist/commands/registry.d.ts +122 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +106 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/standards/fields.d.ts +10 -0
- package/dist/standards/fields.d.ts.map +1 -0
- package/dist/standards/fields.js +17 -0
- package/dist/standards/fields.js.map +1 -0
- package/dist/standards/index.d.ts +1 -5
- package/dist/standards/index.d.ts.map +1 -1
- package/dist/standards/index.js +1 -5
- package/dist/standards/index.js.map +1 -1
- package/dist/standards/output.d.ts +0 -8
- package/dist/standards/output.d.ts.map +1 -1
- package/dist/standards/output.js +1 -15
- package/dist/standards/output.js.map +1 -1
- package/dist/standards/tables.d.ts +6 -0
- package/dist/standards/tables.d.ts.map +1 -0
- package/dist/standards/tables.js +6 -0
- package/dist/standards/tables.js.map +1 -0
- package/docs/standards/architecture.md +3 -4
- package/docs/standards/ci.md +48 -19
- package/docs/standards/docs.md +4 -7
- package/docs/standards/new-cli.md +3 -0
- package/docs/standards/releases.md +5 -6
- package/docs/standards/security.md +1 -1
- package/docs/standards/testing.md +9 -12
- package/docs/standards/toolchain.md +13 -12
- package/package.json +5 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describeQuery } from "../query/registry.js";
|
|
2
|
+
const labels = new WeakMap();
|
|
3
|
+
/** Attaches what the tree cannot say. Repeated calls merge; the command is returned for chaining. */
|
|
4
|
+
export const annotate = (command, meta) => {
|
|
5
|
+
labels.set(command, { ...labels.get(command), ...meta });
|
|
6
|
+
return command;
|
|
7
|
+
};
|
|
8
|
+
export const metaOf = (command) => labels.get(command) ?? {};
|
|
9
|
+
const optionLabels = new WeakMap();
|
|
10
|
+
/** `annotate` for an option. Repeated calls merge; the option is returned for `addOption`. */
|
|
11
|
+
export const annotateOption = (option, meta) => {
|
|
12
|
+
optionLabels.set(option, { ...optionLabels.get(option), ...meta });
|
|
13
|
+
return option;
|
|
14
|
+
};
|
|
15
|
+
export const optionMetaOf = (option) => optionLabels.get(option) ?? {};
|
|
16
|
+
export const describeProgram = (root) => visible(root).map((child) => describe(child, root.name(), [], { offMcp: false, noOffline: false }));
|
|
17
|
+
export const describeOptions = (command) => command.options.filter((option) => !option.hidden).map(describeOption);
|
|
18
|
+
export const flatten = (commands) => commands.flatMap((command) => [command, ...flatten(command.commands)]);
|
|
19
|
+
const snake = (name) => name.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`).replaceAll("-", "_");
|
|
20
|
+
/**
|
|
21
|
+
* What a next step may name, by command path (`messages list`): its effects, and the arguments and options it takes
|
|
22
|
+
* in snake_case. Hand it to `stepOf` and `errorObjectOf` as `targets`.
|
|
23
|
+
*/
|
|
24
|
+
export const stepTargets = (root) => {
|
|
25
|
+
const found = new Map();
|
|
26
|
+
// From the long flag, so `--no-input` is `no_input`: the name a step's args render back into the same flag.
|
|
27
|
+
const optionName = (option) => snake((option.long ?? option.attributeName()).replace(/^--/, ""));
|
|
28
|
+
const visit = (command, parents, above) => {
|
|
29
|
+
const path = [...parents, command.name()];
|
|
30
|
+
const options = [...above, ...command.options];
|
|
31
|
+
const { effects } = metaOf(command);
|
|
32
|
+
found.set(path.join(" "), {
|
|
33
|
+
...(effects ? { effects } : {}),
|
|
34
|
+
names: [...command.registeredArguments.map((argument) => snake(argument.name())), ...options.map(optionName)],
|
|
35
|
+
});
|
|
36
|
+
for (const child of command.commands)
|
|
37
|
+
visit(child, path, options);
|
|
38
|
+
};
|
|
39
|
+
for (const child of root.commands)
|
|
40
|
+
visit(child, [], root.options);
|
|
41
|
+
return (command) => found.get(command);
|
|
42
|
+
};
|
|
43
|
+
const describe = (command, cli, parents, above) => {
|
|
44
|
+
const path = [...parents, command.name()];
|
|
45
|
+
const args = command.registeredArguments.map(describeArgument);
|
|
46
|
+
const options = describeOptions(command);
|
|
47
|
+
const { origin = "handwritten", query, mcp, offline, ...meta } = metaOf(command);
|
|
48
|
+
const here = { offMcp: above.offMcp || mcp === false, noOffline: above.noOffline || offline === false };
|
|
49
|
+
const usage = [
|
|
50
|
+
cli,
|
|
51
|
+
...path,
|
|
52
|
+
...args.map((argument) => (argument.required ? `<${argument.name}>` : `[${argument.name}]`)),
|
|
53
|
+
options.length > 0 ? "[options]" : "",
|
|
54
|
+
]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join(" ");
|
|
57
|
+
return {
|
|
58
|
+
path,
|
|
59
|
+
name: command.name(),
|
|
60
|
+
...(command.summary() ? { summary: command.summary() } : {}),
|
|
61
|
+
description: command.description(),
|
|
62
|
+
usage,
|
|
63
|
+
origin,
|
|
64
|
+
...meta,
|
|
65
|
+
...(here.offMcp ? { mcp: false } : {}),
|
|
66
|
+
...(here.noOffline ? { offline: false } : {}),
|
|
67
|
+
...(query ? { query: describeQuery(query) } : {}),
|
|
68
|
+
...(visible(command).length > 0 && hasAction(command) ? { runnable: true } : {}),
|
|
69
|
+
arguments: args,
|
|
70
|
+
options,
|
|
71
|
+
commands: visible(command).map((child) => describe(child, cli, path, here)),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
// Commander has no public getter for the action either; without one, a group prints its help.
|
|
75
|
+
const hasAction = (command) => Boolean(command._actionHandler);
|
|
76
|
+
// `addCommand(command, { hidden: true })` sets only this; Commander has no public getter for it.
|
|
77
|
+
const visible = (command) => command.commands.filter((child) => !child._hidden);
|
|
78
|
+
const describeArgument = (argument) => ({
|
|
79
|
+
name: argument.name(),
|
|
80
|
+
required: argument.required,
|
|
81
|
+
variadic: argument.variadic,
|
|
82
|
+
description: argument.description,
|
|
83
|
+
...(argument.argChoices ? { choices: argument.argChoices } : {}),
|
|
84
|
+
...(argument.defaultValue === undefined ? {} : { default: argument.defaultValue }),
|
|
85
|
+
});
|
|
86
|
+
// Commander keys `implies` by attribute name (`dryRun`); the document names the flag, as everywhere else.
|
|
87
|
+
const impliesOf = (implied) => Object.fromEntries(Object.entries(implied).map(([name, value]) => [
|
|
88
|
+
`--${name.replace(/[A-Z]/g, (l) => `-${l.toLowerCase()}`)}`,
|
|
89
|
+
value,
|
|
90
|
+
]));
|
|
91
|
+
const describeOption = (option) => {
|
|
92
|
+
const { conflictsWith = [], implied } = option;
|
|
93
|
+
return {
|
|
94
|
+
flags: option.flags,
|
|
95
|
+
description: option.description,
|
|
96
|
+
takes_value: option.required || option.optional,
|
|
97
|
+
mandatory: option.mandatory,
|
|
98
|
+
...(option.argChoices ? { choices: option.argChoices } : {}),
|
|
99
|
+
...(option.defaultValue === undefined ? {} : { default: option.defaultValue }),
|
|
100
|
+
...(option.envVar ? { env: option.envVar } : {}),
|
|
101
|
+
...(conflictsWith.length > 0 ? { conflicts: conflictsWith } : {}),
|
|
102
|
+
...(implied ? { implies: impliesOf(implied) } : {}),
|
|
103
|
+
...(optionMetaOf(option).mcp === false ? { mcp: false } : {}),
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
declare const fieldRuleSchema: v.StrictObjectSchema<{
|
|
3
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
4
|
+
readonly rule: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
5
|
+
}, undefined>;
|
|
6
|
+
export type FieldRule = v.InferOutput<typeof fieldRuleSchema>;
|
|
7
|
+
export declare const defineFieldRules: (input: unknown) => FieldRule[];
|
|
8
|
+
export declare const FIELD_RULES: FieldRule[];
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/standards/fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAG5B,QAAA,MAAM,eAAe;;;aAA2C,CAAA;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,SAAS,EAGxD,CAAA;AAEH,eAAO,MAAM,WAAW,EAAE,SAAS,EAWjC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { duplicates, parseRegistry, text, word } from "./registry.js";
|
|
3
|
+
const fieldRuleSchema = v.strictObject({ id: word, rule: text });
|
|
4
|
+
export const defineFieldRules = (input) => parseRegistry("output field rules", v.array(fieldRuleSchema), input, (rules) => duplicates(rules.map((rule) => rule.id)).map((id) => `"${id}" is listed twice`));
|
|
5
|
+
export const FIELD_RULES = defineFieldRules([
|
|
6
|
+
{ id: "envelope", rule: "every JSON answer is one object: a list `{items, page, …}`, one thing `{item, …}`" },
|
|
7
|
+
{ id: "time", rule: "a time is an ISO 8601 string with a zone, never epoch milliseconds" },
|
|
8
|
+
{ id: "duration", rule: "a length of time is a number of milliseconds in a key ending in `_ms`" },
|
|
9
|
+
{ id: "ref", rule: "a stored thing is named by `ref`; a message's `ref` value is its locator" },
|
|
10
|
+
{ id: "snake-case", rule: "keys are snake_case words, no abbreviations a reader has to decode" },
|
|
11
|
+
{ id: "one-meaning", rule: "a key has one meaning and one type in every answer of every CLI" },
|
|
12
|
+
{
|
|
13
|
+
id: "absent-null",
|
|
14
|
+
rule: "absent: not asked for or not known; `null`: known to have no value; `[]`: known to be empty, never `null`; `0`: measured, never a stand-in for unknown",
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/standards/fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAErE,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AAGhE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAAe,EAAE,CAC9D,aAAa,CAAC,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAC7E,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAChF,CAAA;AAEH,MAAM,CAAC,MAAM,WAAW,GAAgB,gBAAgB,CAAC;IACvD,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,mFAAmF,EAAE;IAC7G,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,oEAAoE,EAAE;IAC1F,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,uEAAuE,EAAE;IACjG,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,0EAA0E,EAAE;IAC/F,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,oEAAoE,EAAE;IAChG,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,iEAAiE,EAAE;IAC9F;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,wJAAwJ;KAC/J;CACF,CAAC,CAAA"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
export { AUDIT_BLOCKS, AUDIT_RULES, type AuditRule, defineAuditRules, defineParityGroups, defineRequiredRoots, PARITY_GROUPS, type ParityGroup, REQUIRED_ROOTS, type RequiredRoot, } from "./audit.js";
|
|
2
1
|
export { EFFECT_LEVELS, type EffectLevel, type Effects, effectsSchema, writes } from "./effects.js";
|
|
3
2
|
export { BASE_REASONS, COMMON_DETAILS, CRASH_CODE, CRASH_REASON, defineReasons, type ErrorObject, type ErrorReason, errorObjectSchema, } from "./errors.js";
|
|
4
|
-
export { defineIdentifiers, IDENTIFIERS, type Identifier } from "./identifiers.js";
|
|
5
|
-
export { baselineProblems, baselineSchema, defineLintRules, LINT_RULES, LINT_SEVERITIES, type LintRule, type LintSeverity, OVERRIDE_BUDGET, OVERRIDE_RULE_REVIEW, type Override, overridesProblems, overridesSchema, rulesForReview, } from "./lint.js";
|
|
6
3
|
export { defineLogEvents, isContentKey, LOG_ATTRIBUTE_KEYS, LOG_EVENTS, LOG_SEVERITIES, type LogEvent, type LogRecord, type LogSeverity, logAttributesJsonSchema, logEventProblems, logRecordSchema, traceIdOf, } from "./log.js";
|
|
7
|
-
export {
|
|
4
|
+
export { type Issue, type ItemEnvelope, isoTime, issueSchema, itemEnvelopeSchema, jsonlEndSchema, jsonlItemSchema, jsonlOf, type ListEnvelope, listEnvelopeSchema, MAX_NEXT_STEPS, type Meta, type Missing, metaSchema, missingSchema, type NextStep, nextStepSchema, type Page, pageSchema, reference, } from "./output.js";
|
|
8
5
|
export { fill, jsonSchemaOf, RegistryError } from "./registry.js";
|
|
9
6
|
export { defineSteps, SAME_COMMAND, STEPS, type StepDefinition, type StepInput, type StepTarget, stepOf, } from "./steps.js";
|
|
10
|
-
export { defineVocabulary, FLAG_ROLES, FLAG_TYPES, type FlagRole, type FlagType, VOCABULARY, type Vocabulary, type VocabularyFlag, type VocabularyNoun, type VocabularyVerb, vocabularySchema, } from "./vocabulary.js";
|
|
11
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EACL,YAAY,EACZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,OAAO,EACP,KAAK,YAAY,EACjB,kBAAkB,EAClB,cAAc,EACd,KAAK,IAAI,EACT,KAAK,OAAO,EACZ,UAAU,EACV,aAAa,EACb,KAAK,QAAQ,EACb,cAAc,EACd,KAAK,IAAI,EACT,UAAU,EACV,SAAS,GACV,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,KAAK,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,MAAM,GACP,MAAM,YAAY,CAAA"}
|
package/dist/standards/index.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
export { AUDIT_BLOCKS, AUDIT_RULES, defineAuditRules, defineParityGroups, defineRequiredRoots, PARITY_GROUPS, REQUIRED_ROOTS, } from "./audit.js";
|
|
2
1
|
export { EFFECT_LEVELS, effectsSchema, writes } from "./effects.js";
|
|
3
2
|
export { BASE_REASONS, COMMON_DETAILS, CRASH_CODE, CRASH_REASON, defineReasons, errorObjectSchema, } from "./errors.js";
|
|
4
|
-
export { defineIdentifiers, IDENTIFIERS } from "./identifiers.js";
|
|
5
|
-
export { baselineProblems, baselineSchema, defineLintRules, LINT_RULES, LINT_SEVERITIES, OVERRIDE_BUDGET, OVERRIDE_RULE_REVIEW, overridesProblems, overridesSchema, rulesForReview, } from "./lint.js";
|
|
6
3
|
export { defineLogEvents, isContentKey, LOG_ATTRIBUTE_KEYS, LOG_EVENTS, LOG_SEVERITIES, logAttributesJsonSchema, logEventProblems, logRecordSchema, traceIdOf, } from "./log.js";
|
|
7
|
-
export {
|
|
4
|
+
export { isoTime, issueSchema, itemEnvelopeSchema, jsonlEndSchema, jsonlItemSchema, jsonlOf, listEnvelopeSchema, MAX_NEXT_STEPS, metaSchema, missingSchema, nextStepSchema, pageSchema, reference, } from "./output.js";
|
|
8
5
|
export { fill, jsonSchemaOf, RegistryError } from "./registry.js";
|
|
9
6
|
export { defineSteps, SAME_COMMAND, STEPS, stepOf, } from "./steps.js";
|
|
10
|
-
export { defineVocabulary, FLAG_ROLES, FLAG_TYPES, VOCABULARY, vocabularySchema, } from "./vocabulary.js";
|
|
11
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkC,aAAa,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EACL,YAAY,EACZ,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EAGb,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,cAAc,EAId,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,MAAM,UAAU,CAAA;AACjB,OAAO,EAGL,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,OAAO,EAEP,kBAAkB,EAClB,cAAc,EAGd,UAAU,EACV,aAAa,EAEb,cAAc,EAEd,UAAU,EACV,SAAS,GACV,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,KAAK,EAIL,MAAM,GACP,MAAM,YAAY,CAAA"}
|
|
@@ -192,13 +192,6 @@ export interface ItemEnvelope<T> {
|
|
|
192
192
|
missing?: Missing[];
|
|
193
193
|
meta: Meta;
|
|
194
194
|
}
|
|
195
|
-
declare const fieldRuleSchema: v.StrictObjectSchema<{
|
|
196
|
-
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
197
|
-
readonly rule: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
198
|
-
}, undefined>;
|
|
199
|
-
export type FieldRule = v.InferOutput<typeof fieldRuleSchema>;
|
|
200
|
-
export declare const defineFieldRules: (input: unknown) => FieldRule[];
|
|
201
|
-
export declare const FIELD_RULES: FieldRule[];
|
|
202
195
|
/** `--jsonl`: one item per line, then one end line, so a reader tells a finished stream from a cut one. */
|
|
203
196
|
export declare const jsonlItemSchema: <T extends v.GenericSchema>(item: T) => v.StrictObjectSchema<{
|
|
204
197
|
readonly type: v.LiteralSchema<"item", undefined>;
|
|
@@ -227,5 +220,4 @@ export declare const jsonlEndSchema: v.StrictObjectSchema<{
|
|
|
227
220
|
}, undefined>;
|
|
228
221
|
/** A list answer as JSON lines, the end line last. */
|
|
229
222
|
export declare const jsonlOf: <T>({ items, page, meta }: ListEnvelope<T>) => string;
|
|
230
|
-
export {};
|
|
231
223
|
//# sourceMappingURL=output.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAI5B,gFAAgF;AAChF,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B,eAAO,MAAM,OAAO,sHAAqE,CAAA;AAEzF,2GAA2G;AAC3G,eAAO,MAAM,SAAS,gHAA+E,CAAA;AAErG,eAAO,MAAM,cAAc;;;IAIvB,qGAAqG;;;;IAIrG,4FAA4F;;;;;;;0BAU9F,CAAA;AAEF,eAAO,MAAM,aAAa;;;IAGxB,uEAAuE;;aAEvE,CAAA;AAIF,4FAA4F;AAC5F,eAAO,MAAM,UAAU;;;;;;;;;;0BAQrB,CAAA;AAEF,kFAAkF;AAClF,eAAO,MAAM,WAAW;;;IAGtB,uEAAuE;;aAEvE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;QARrB,uEAAuE;;;;aAevE,CAAA;AAIF,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;;;;;;;;;;;;;QA3DjE,qGAAqG;;;;QAIrG,4FAA4F;;;;;;;;;;;;;;;;;;;;;;;;;QAe9F,uEAAuE;;;;;;;;;;;YAqBvE,uEAAuE;;;;;aA0BrE,CAAA;AAEJ,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;;QApEjE,qGAAqG;;;;QAIrG,4FAA4F;;;;;;;;;;;;;;;;;;;;;;;;;QAe9F,uEAAuE;;;;;;;;;;;YAqBvE,uEAAuE;;;;;aAkCrE,CAAA;AAEJ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,aAAa,CAAC,CAAA;AACzD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,WAAW,CAAC,CAAA;AACrD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AACD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AAED,
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAI5B,gFAAgF;AAChF,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B,eAAO,MAAM,OAAO,sHAAqE,CAAA;AAEzF,2GAA2G;AAC3G,eAAO,MAAM,SAAS,gHAA+E,CAAA;AAErG,eAAO,MAAM,cAAc;;;IAIvB,qGAAqG;;;;IAIrG,4FAA4F;;;;;;;0BAU9F,CAAA;AAEF,eAAO,MAAM,aAAa;;;IAGxB,uEAAuE;;aAEvE,CAAA;AAIF,4FAA4F;AAC5F,eAAO,MAAM,UAAU;;;;;;;;;;0BAQrB,CAAA;AAEF,kFAAkF;AAClF,eAAO,MAAM,WAAW;;;IAGtB,uEAAuE;;aAEvE,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;QARrB,uEAAuE;;;;aAevE,CAAA;AAIF,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;;;;;;;;;;;;;QA3DjE,qGAAqG;;;;QAIrG,4FAA4F;;;;;;;;;;;;;;;;;;;;;;;;;QAe9F,uEAAuE;;;;;;;;;;;YAqBvE,uEAAuE;;;;;aA0BrE,CAAA;AAEJ,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;;QApEjE,qGAAqG;;;;QAIrG,4FAA4F;;;;;;;;;;;;;;;;;;;;;;;;;QAe9F,uEAAuE;;;;;;;;;;;YAqBvE,uEAAuE;;;;;aAkCrE,CAAA;AAEJ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,aAAa,CAAC,CAAA;AACzD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,WAAW,CAAC,CAAA;AACrD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AACD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AAED,2GAA2G;AAC3G,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;aACT,CAAA;AAEzD,eAAO,MAAM,cAAc;;;;;;QA3DzB,uEAAuE;;;;;;;;;;;;;;aAgEvE,CAAA;AAEF,sDAAsD;AACtD,eAAO,MAAM,OAAO,GAAI,CAAC,yBAAyB,YAAY,CAAC,CAAC,CAAC,KAAG,MAItD,CAAA"}
|
package/dist/standards/output.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
import { errorCodes } from "../errors.js";
|
|
3
|
-
import { dottedId,
|
|
3
|
+
import { dottedId, text } from "./registry.js";
|
|
4
4
|
/** At most two next steps per answer: the one to take, then one alternative. */
|
|
5
5
|
export const MAX_NEXT_STEPS = 2;
|
|
6
6
|
export const isoTime = v.pipe(v.string(), v.isoTimestamp("an ISO 8601 time with a zone"));
|
|
@@ -75,20 +75,6 @@ export const itemEnvelopeSchema = (item) => v.strictObject({
|
|
|
75
75
|
missing: v.optional(v.array(missingSchema)),
|
|
76
76
|
meta: metaSchema,
|
|
77
77
|
});
|
|
78
|
-
const fieldRuleSchema = v.strictObject({ id: word, rule: text });
|
|
79
|
-
export const defineFieldRules = (input) => parseRegistry("output field rules", v.array(fieldRuleSchema), input, (rules) => duplicates(rules.map((rule) => rule.id)).map((id) => `"${id}" is listed twice`));
|
|
80
|
-
export const FIELD_RULES = defineFieldRules([
|
|
81
|
-
{ id: "envelope", rule: "every JSON answer is one object: a list `{items, page, …}`, one thing `{item, …}`" },
|
|
82
|
-
{ id: "time", rule: "a time is an ISO 8601 string with a zone, never epoch milliseconds" },
|
|
83
|
-
{ id: "duration", rule: "a length of time is a number of milliseconds in a key ending in `_ms`" },
|
|
84
|
-
{ id: "ref", rule: "a stored thing is named by `ref`; a message's `ref` value is its locator" },
|
|
85
|
-
{ id: "snake-case", rule: "keys are snake_case words, no abbreviations a reader has to decode" },
|
|
86
|
-
{ id: "one-meaning", rule: "a key has one meaning and one type in every answer of every CLI" },
|
|
87
|
-
{
|
|
88
|
-
id: "absent-null",
|
|
89
|
-
rule: "absent: not asked for or not known; `null`: known to have no value; `[]`: known to be empty, never `null`; `0`: measured, never a stand-in for unknown",
|
|
90
|
-
},
|
|
91
|
-
]);
|
|
92
78
|
/** `--jsonl`: one item per line, then one end line, so a reader tells a finished stream from a cut one. */
|
|
93
79
|
export const jsonlItemSchema = (item) => v.strictObject({ type: v.literal("item"), data: item });
|
|
94
80
|
export const jsonlEndSchema = v.strictObject({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AUDIT_BLOCKS, AUDIT_RULES, type AuditRule, defineAuditRules, defineParityGroups, defineRequiredRoots, PARITY_GROUPS, type ParityGroup, REQUIRED_ROOTS, type RequiredRoot, } from "./audit.js";
|
|
2
|
+
export { defineFieldRules, FIELD_RULES, type FieldRule } from "./fields.js";
|
|
3
|
+
export { defineIdentifiers, IDENTIFIERS, type Identifier } from "./identifiers.js";
|
|
4
|
+
export { baselineProblems, baselineSchema, defineLintRules, LINT_RULES, LINT_SEVERITIES, type LintRule, type LintSeverity, OVERRIDE_BUDGET, OVERRIDE_RULE_REVIEW, type Override, overridesProblems, overridesSchema, rulesForReview, } from "./lint.js";
|
|
5
|
+
export { defineVocabulary, FLAG_ROLES, FLAG_TYPES, type FlagRole, type FlagType, VOCABULARY, type Vocabulary, type VocabularyFlag, type VocabularyNoun, type VocabularyVerb, vocabularySchema, } from "./vocabulary.js";
|
|
6
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/standards/tables.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,SAAS,EACd,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,eAAe,EACf,oBAAoB,EACpB,KAAK,QAAQ,EACb,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,UAAU,EACV,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,gBAAgB,GACjB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AUDIT_BLOCKS, AUDIT_RULES, defineAuditRules, defineParityGroups, defineRequiredRoots, PARITY_GROUPS, REQUIRED_ROOTS, } from "./audit.js";
|
|
2
|
+
export { defineFieldRules, FIELD_RULES } from "./fields.js";
|
|
3
|
+
export { defineIdentifiers, IDENTIFIERS } from "./identifiers.js";
|
|
4
|
+
export { baselineProblems, baselineSchema, defineLintRules, LINT_RULES, LINT_SEVERITIES, OVERRIDE_BUDGET, OVERRIDE_RULE_REVIEW, overridesProblems, overridesSchema, rulesForReview, } from "./lint.js";
|
|
5
|
+
export { defineVocabulary, FLAG_ROLES, FLAG_TYPES, VOCABULARY, vocabularySchema, } from "./vocabulary.js";
|
|
6
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/standards/tables.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EAEX,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EAEb,cAAc,GAEf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAA;AAClF,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EAGf,eAAe,EACf,oBAAoB,EAEpB,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EAGV,UAAU,EAKV,gBAAgB,GACjB,MAAM,iBAAiB,CAAA"}
|
|
@@ -110,14 +110,13 @@ at start-up and the `serve` relay are in [Lifecycle](lifecycle.md); the store's
|
|
|
110
110
|
### WC-ARCH-8 · Cross a module boundary only through the module's entry point
|
|
111
111
|
|
|
112
112
|
- **Why:** a deep import ties the caller to another module's internals.
|
|
113
|
-
- **Enforced by:** `
|
|
114
|
-
`drive-cli: biome noRestrictedImports` · `zoom-cli: biome noRestrictedImports`.
|
|
113
|
+
- **Enforced by:** `pnpm lint` · `<app>: biome no-deep-wirecat-import` · `cli-core: biome noRestrictedImports`.
|
|
115
114
|
- **Example:** in cli-core, `src/tasks/` and `src/meetings/` are entered only through their `index.ts`, `cli/`, `mcp/`
|
|
116
|
-
and `testing/` entries; its `biome.json` refuses the rest.
|
|
115
|
+
and `testing/` entries; its `biome.json` refuses the rest. Every repository refuses `@wirecat/<package>/src/…` and `/dist/…` outside tests. A
|
|
117
116
|
package's own entry points are its `exports`
|
|
118
117
|
([WC-LAY-5](layout.md#wc-lay-5--add-an-entry-point-as-an-exports-entry-built-from-srcindexts)).
|
|
119
118
|
- **Exceptions:** a test inside a module may import what it tests; a test outside the module uses the entry point.
|
|
120
|
-
- **Applies to:** all CLIs.
|
|
119
|
+
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0.
|
|
121
120
|
**Rulings:** none.
|
|
122
121
|
|
|
123
122
|
### WC-ARCH-9 · Pass the narrow port or callback a use case needs, not a whole store or container
|
package/docs/standards/ci.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Scope
|
|
4
4
|
|
|
5
|
-
What runs where: the local hooks, the checks on every pull request
|
|
6
|
-
merge to `main`, and the monthly runs.
|
|
5
|
+
What runs where: the local hooks, the fast checks and the Linux validation on every pull request, full validation
|
|
6
|
+
on each merge to `main`, and the monthly runs.
|
|
7
7
|
|
|
8
8
|
Rule ids on this page are `WC-CI-<n>`. How to read a rule, how ids work and which rule wins are in the
|
|
9
9
|
[index](README.md). What each tool checks is on the [Toolchain page](toolchain.md); the release workflow is on the
|
|
@@ -48,7 +48,7 @@ cli-testing, cli-docs, plus community itself.
|
|
|
48
48
|
|
|
49
49
|
### WC-CI-4 · Keep `ci:quick` to early bug checks that finish within two minutes
|
|
50
50
|
|
|
51
|
-
- **Why:** it is the
|
|
51
|
+
- **Why:** it is the first build-level answer on a pull request, so it must stay fast enough that nobody wants it gone.
|
|
52
52
|
- **Enforced by:** `standards.yml:standards` · `pnpm ci:quick`.
|
|
53
53
|
- **Example:** what each repository runs today:
|
|
54
54
|
- tg, max, memo and wa: `pnpm typecheck && pnpm build && pnpm lint:commands`;
|
|
@@ -57,20 +57,45 @@ cli-testing, cli-docs, plus community itself.
|
|
|
57
57
|
- cli-core: `pnpm typecheck` and its command lint test;
|
|
58
58
|
- cli-docs: its unit tests, without the one that needs generated pages;
|
|
59
59
|
- community: its script tests.
|
|
60
|
-
- **Exceptions:** never put live-account suites, agent suites
|
|
60
|
+
- **Exceptions:** never put live-account suites, agent suites or platform jobs here. Full tests and coverage run in
|
|
61
|
+
the pull request validation job ([WC-CI-5](#wc-ci-5--run-the-full-linux-validation-on-every-pull-request-and-keep-platform-suites-out)),
|
|
62
|
+
not in `ci:quick`.
|
|
61
63
|
- **Applies to:** the ten repositories. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
62
64
|
|
|
63
|
-
### WC-CI-5 ·
|
|
64
|
-
|
|
65
|
-
- **Why:** pull request
|
|
66
|
-
|
|
67
|
-
- **Enforced by:**
|
|
68
|
-
- **Example:**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
### WC-CI-5 · Run the full Linux validation on every pull request, and keep platform suites out
|
|
66
|
+
|
|
67
|
+
- **Why:** a pull request that lowers coverage or breaks a contract must fail before it merges; once on `main` it
|
|
68
|
+
blocks every other branch and the next release. It costs about two and a half minutes per pull request.
|
|
69
|
+
- **Enforced by:** `pr.yml:validation`.
|
|
70
|
+
- **Example:** `pr.yml` runs on `pull_request` and calls the repository's own `ci.yml`, the same full validation as
|
|
71
|
+
`main` (WC-CI-7): lint, typecheck, `test:coverage` with the coverage floor, build, the contracts, the test matrix,
|
|
72
|
+
`docs:check` and parity, the Bun job and the secret scan. It passes `skip-platforms: true` where `ci.yml` has that
|
|
73
|
+
input, and a new commit cancels the run it replaces:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
on:
|
|
77
|
+
pull_request:
|
|
78
|
+
concurrency:
|
|
79
|
+
group: pr-validation-${{ github.event.pull_request.number }}
|
|
80
|
+
cancel-in-progress: true
|
|
81
|
+
permissions:
|
|
82
|
+
contents: read
|
|
83
|
+
jobs:
|
|
84
|
+
validation:
|
|
85
|
+
uses: ./.github/workflows/ci.yml
|
|
86
|
+
with:
|
|
87
|
+
skip-platforms: true
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
It runs beside the standards job (WC-CI-3), which stays the fast first answer.
|
|
91
|
+
- **Exceptions:** Windows, macOS and install checks stay out of pull requests and run in full validation at release,
|
|
92
|
+
monthly or on request. A path-scoped job that tests one platform-specific file may run on pull requests, such as
|
|
93
|
+
cli-base `macos.yml` for the path code. cli-docs and community run `security-pr.yml`, a new-commit secret scan;
|
|
94
|
+
cli-docs validates its site before each deployment instead, and community has no build. Third-party security apps
|
|
95
|
+
may post their own checks.
|
|
96
|
+
- **Applies to:** the CLIs, cli-base, cli-core and cli-testing. cli-base has `pr.yml`; wa adds it in its
|
|
97
|
+
`ci/pr-validation` branch; tg, max, memo, drive, zoom, cli-core and cli-testing do not have it yet. **Since:**
|
|
98
|
+
cli-base 0.41.0 (pull request validation since cli-base 0.44.6). **Rulings:** none.
|
|
74
99
|
|
|
75
100
|
### WC-CI-6 · Run the changelog guard on every pull request
|
|
76
101
|
|
|
@@ -84,7 +109,8 @@ cli-testing, cli-docs, plus community itself.
|
|
|
84
109
|
|
|
85
110
|
### WC-CI-7 · Run full validation once on each merge to `main`, on Linux, without publishing
|
|
86
111
|
|
|
87
|
-
- **Why:**
|
|
112
|
+
- **Why:** two pull requests that each pass on their own can still break each other once both are merged; `main`
|
|
113
|
+
catches that merge skew the same hour, not at the next release.
|
|
88
114
|
- **Enforced by:** `main.yml:validation` · `node-ci.yml:check` · `node-ci.yml:bun` · `node-ci.yml:secrets`.
|
|
89
115
|
- **Example:** `main.yml` calls the repository's own `ci.yml`, which calls cli-base `node-ci.yml`. That runs
|
|
90
116
|
`pnpm lint`, `pnpm typecheck`, `pnpm test:coverage`, `pnpm build`, then the project's `checks` lines (for max:
|
|
@@ -125,9 +151,12 @@ cli-testing, cli-docs, plus community itself.
|
|
|
125
151
|
changes.
|
|
126
152
|
- **Enforced by:** `release.yml:checks` · `monthly.yml:security`.
|
|
127
153
|
- **Example:** cli-base `release-checks.yml` runs the production dependency audit, the workflow scan (`zizmor`),
|
|
128
|
-
CodeQL and a full-history gitleaks scan. A release depends on it. A pull request runs
|
|
129
|
-
|
|
130
|
-
- **Exceptions:**
|
|
154
|
+
CodeQL and a full-history gitleaks scan. A release depends on it. A pull request runs the new-commit gitleaks scan
|
|
155
|
+
in the standards job.
|
|
156
|
+
- **Exceptions:** the full-history gitleaks scan in `node-ci.yml` also runs on pull requests, through the validation
|
|
157
|
+
job ([WC-CI-5](#wc-ci-5--run-the-full-linux-validation-on-every-pull-request-and-keep-platform-suites-out)); it
|
|
158
|
+
takes seconds. The dependency audit, `zizmor` and CodeQL stay out. Do not add a heavy scanner to an editor hook, a
|
|
159
|
+
stop hook or an ordinary pull request job.
|
|
131
160
|
- **Applies to:** the ten repositories. **Since:** cli-base 0.41.0. **Rulings:** sc:9.
|
|
132
161
|
|
|
133
162
|
### WC-CI-11 · Moved to [WC-SECR-20](security.md#wc-secr-20--pin-each-third-party-action-to-a-commit-and-give-each-workflow-read-only-defaults)
|
package/docs/standards/docs.md
CHANGED
|
@@ -43,11 +43,9 @@ Rule ids on this page are `WC-DOC-<n>`. How to read a rule, how ids work and whi
|
|
|
43
43
|
### WC-DOC-4 · A generated page is never edited by hand
|
|
44
44
|
|
|
45
45
|
- **Why:** the next generation overwrites a hand edit, and the page then disagrees with the program until it does.
|
|
46
|
-
- **Enforced by:** `
|
|
47
|
-
`zoom-cli: pnpm generate:check` · `tg-cli: ci.yml:ci` · `max-cli: ci.yml:ci` · `whatsapp-cli: ci.yml:ci`.
|
|
46
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm generate:check` · `whatsapp-cli: ci.yml:ci`.
|
|
48
47
|
- **Example:** `docs/commands.md` comes from the program. Change the command's help text, then run `pnpm generate`.
|
|
49
|
-
- **Exceptions:** none.
|
|
50
|
-
and then `git diff --exit-code` in full validation.
|
|
48
|
+
- **Exceptions:** none. wa runs the generator and then `git diff --exit-code` in full validation.
|
|
51
49
|
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
52
50
|
|
|
53
51
|
### WC-DOC-5 · Every relative link and anchor resolves
|
|
@@ -62,12 +60,11 @@ Rule ids on this page are `WC-DOC-<n>`. How to read a rule, how ids work and whi
|
|
|
62
60
|
### WC-DOC-6 · The `docs/` folder matches `docs/meta.json` and has the shared page set
|
|
63
61
|
|
|
64
62
|
- **Why:** every tool has the same pages at the same addresses, so a reader who knows one tool knows them all.
|
|
65
|
-
- **Enforced by:** `
|
|
63
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm docs:check` · `whatsapp-cli: pnpm docs:check`.
|
|
66
64
|
- **Example:** `docs/meta.json` lists every page once, in sidebar order. The folder has `index`, `installation`,
|
|
67
65
|
`usage`, `commands`, `configuration`, `troubleshooting` and `security`. Each page has exactly one `#` heading.
|
|
68
66
|
- **Exceptions:** `changelog` in `meta.json` comes from the root `CHANGELOG.md`. `cli-dev docs-check --pages` checks
|
|
69
|
-
this.
|
|
70
|
-
yet.
|
|
67
|
+
this. tg and drive run the same check in their own `scripts/docs-check.ts`.
|
|
71
68
|
- **Applies to:** every CLI in the docs portal. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
72
69
|
|
|
73
70
|
### WC-DOC-7 · `README.md` is the full introduction to the tool
|
|
@@ -30,6 +30,9 @@ whatsapp-cli is the worked example: it has every file below. Compare with it whe
|
|
|
30
30
|
workflow. Commit the result with the lockfile. Proved by: `pnpm standards:check`, run by `standards.yml`.
|
|
31
31
|
3. **Copy community's `monthly.yml` template** into `.github/workflows/`, and set its cron to a day no other
|
|
32
32
|
repository uses. Proved by: the workflow appears in the Actions tab. See [CI](ci.md).
|
|
33
|
+
4. **Add `pr.yml`**, the pull request validation that calls `ci.yml` with platform suites skipped, as shown in
|
|
34
|
+
[WC-CI-5](ci.md#wc-ci-5--run-the-full-linux-validation-on-every-pull-request-and-keep-platform-suites-out).
|
|
35
|
+
Proved by: the `validation` check on the first pull request.
|
|
33
36
|
|
|
34
37
|
## Toolchain
|
|
35
38
|
|
|
@@ -72,11 +72,10 @@ on the [CI](ci.md) page.
|
|
|
72
72
|
### WC-REL-6 · `package.json` holds the version, and the program reads a synced copy
|
|
73
73
|
|
|
74
74
|
- **Why:** a bundled command has no `package.json` to read, so `--version` reads a source file that must not drift.
|
|
75
|
-
- **Enforced by:** `
|
|
75
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm version:check` · `whatsapp-cli: pnpm version:check`.
|
|
76
76
|
- **Example:** edit only `package.json`, then run `pnpm version:sync` to update `src/version.ts`. `pnpm version:check`
|
|
77
77
|
fails when the two disagree.
|
|
78
|
-
- **Exceptions:** a shared library that prints no version has no `src/version.ts`.
|
|
79
|
-
`version:check`; memo, drive and zoom do not.
|
|
78
|
+
- **Exceptions:** a shared library that prints no version has no `src/version.ts`.
|
|
80
79
|
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
81
80
|
|
|
82
81
|
### WC-REL-7 · Versions are `x.y.z`; before 1.0.0 the changelog, not the number, marks a breaking change
|
|
@@ -174,11 +173,11 @@ on the [CI](ci.md) page.
|
|
|
174
173
|
### WC-REL-16 · The package ships only the files it names
|
|
175
174
|
|
|
176
175
|
- **Why:** a stray file in the package can leak local data and grows every install.
|
|
177
|
-
- **Enforced by:** `
|
|
176
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm package:check` · `whatsapp-cli: pnpm release:check`.
|
|
178
177
|
- **Example:** `package.json` `files` lists what ships. The CLI's `pnpm release:check` runs `packContents` from
|
|
179
178
|
`@wirecat/cli-base/release` and fails on any other path in `npm pack --dry-run`.
|
|
180
|
-
- **Exceptions:** none.
|
|
181
|
-
|
|
179
|
+
- **Exceptions:** none. Each CLI's `package:check` runs `packContents`; tg and max as
|
|
180
|
+
`release-check.ts --package-only`.
|
|
182
181
|
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
183
182
|
|
|
184
183
|
## Sources
|
|
@@ -193,7 +193,7 @@ critical goes to the owner for review first.
|
|
|
193
193
|
### WC-SECR-16 · Keep the secret scanners on, and run each one with `--redact`
|
|
194
194
|
|
|
195
195
|
- gitleaks, in the pre-commit hook on staged changes, in the pull request job on the new commits, and on the whole
|
|
196
|
-
history in full validation, at release and every month.
|
|
196
|
+
history in full validation (on pull requests and on `main`), at release and every month.
|
|
197
197
|
- Biome's `noSecrets` rule, from the shared preset, off in tests only
|
|
198
198
|
([WC-TOOL-10](toolchain.md#wc-tool-10--keep-the-secret-lint-on-and-suppress-a-finding-only-with-its-reason)).
|
|
199
199
|
- At release and every month: a dependency audit, zizmor for workflows and CodeQL.
|
|
@@ -151,7 +151,7 @@ and which run after merge is in [CI](ci.md).
|
|
|
151
151
|
### WC-TEST-11 · Keep a coverage floor, and raise it; never lower it
|
|
152
152
|
|
|
153
153
|
- **Why:** a floor stops coverage from falling one pull request at a time.
|
|
154
|
-
- **Enforced by:** `pnpm test:coverage` · `node-ci.yml:check`.
|
|
154
|
+
- **Enforced by:** `pnpm test:coverage` · `node-ci.yml:check` · `pr.yml:validation`.
|
|
155
155
|
- **Example:** `vitest.config.ts` holds thresholds for lines, statements, functions and branches over `src/`, a little
|
|
156
156
|
under what the suite reaches, and `perFile: { lines: 50 }`. A change that falls below gets a test, not a lower
|
|
157
157
|
number. Each excluded file has its reason written beside it.
|
|
@@ -163,37 +163,34 @@ and which run after merge is in [CI](ci.md).
|
|
|
163
163
|
### WC-TEST-12 · Every command and option has a test, or a written reason
|
|
164
164
|
|
|
165
165
|
- **Why:** a flag that no test passes can break without anyone noticing.
|
|
166
|
-
- **Enforced by:** `
|
|
167
|
-
`zoom-cli: pnpm test:matrix:check`.
|
|
166
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm test:matrix:check`.
|
|
168
167
|
- **Example:** under vitest, `run()` appends each parsed command path and option name (never a value) to
|
|
169
168
|
`coverage/argv.jsonl`. `pnpm test:matrix` turns that into `docs/dev/test-matrix.md` and fails on a command or
|
|
170
169
|
option with neither a test nor a reason. A reason names the live scenario that covers it. A test that calls a
|
|
171
170
|
function directly does not count.
|
|
172
171
|
- **Exceptions:** none.
|
|
173
|
-
- **Applies to:** all CLIs.
|
|
174
|
-
0.41.0. **Rulings:** NEED-359.
|
|
172
|
+
- **Applies to:** all CLIs. memo's check fails only on a stale page, not yet on an option with no test.
|
|
173
|
+
**Since:** cli-base 0.41.0. **Rulings:** NEED-359.
|
|
175
174
|
|
|
176
175
|
### WC-TEST-13 · Keep offline contracts for help, discovery, errors and the MCP tool list
|
|
177
176
|
|
|
178
177
|
- **Why:** agents depend on `commands --json` and the MCP tool list; a change to them must be seen and reviewed.
|
|
179
|
-
- **Enforced by:** `
|
|
180
|
-
`whatsapp-cli: pnpm contracts:check` · `drive-cli: pnpm contracts:check` · `zoom-cli: pnpm contracts:check`.
|
|
178
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm contracts:check` · `whatsapp-cli: pnpm contracts:check`.
|
|
181
179
|
- **Example:** `pnpm contracts:check` runs `cli-contract contracts/plan.json` against the built CLI. It checks the
|
|
182
180
|
help snapshot, that discovery is one JSON value on stdout with empty stderr, that a bad option gives the documented
|
|
183
181
|
exit code and one JSON error on stderr, and the MCP tool names, schemas and annotations. A change is accepted with
|
|
184
182
|
`pnpm exec cli-contract contracts/plan.json --update` and a reviewed diff.
|
|
185
|
-
- **Exceptions:**
|
|
186
|
-
- **Applies to:** all CLIs.
|
|
183
|
+
- **Exceptions:** none. The contracts run in full validation, on every pull request and on `main` (WC-CI-5, WC-CI-7).
|
|
184
|
+
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
187
185
|
|
|
188
186
|
### WC-TEST-14 · Check the upgrade from the previous published version
|
|
189
187
|
|
|
190
188
|
- **Why:** a release that cannot read what the previous one wrote loses the owner's data.
|
|
191
|
-
- **Enforced by:** `
|
|
192
|
-
`drive-cli: pnpm contracts:upgrade` · `zoom-cli: pnpm contracts:upgrade`.
|
|
189
|
+
- **Enforced by:** `node-ci.yml:check` · `<app>: pnpm contracts:upgrade`.
|
|
193
190
|
- **Example:** `pnpm contracts:upgrade` runs the previous published package and this build on the same synthetic
|
|
194
191
|
state and checks that the data survives. Each store migration also has its own upgrade test (WC-STORE-9).
|
|
195
192
|
- **Exceptions:** a CLI with no local state.
|
|
196
|
-
- **Applies to:** all CLIs with local state.
|
|
193
|
+
- **Applies to:** all CLIs with local state. wa has no upgrade contract yet. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
197
194
|
|
|
198
195
|
### WC-TEST-15 · A refactor keeps `commands --json` and the MCP tool list as they were
|
|
199
196
|
|