@wirecat/cli-base 0.44.5 → 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/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
package/README.md
CHANGED
|
@@ -59,7 +59,8 @@ The package is split by **when** a piece runs, so a tool loads only what it call
|
|
|
59
59
|
|---|---|
|
|
60
60
|
| Every command | root: streams, renderer, errors and exit codes, keyring, credentials, paths, config, time, retry, logging, field selection, output buffer, deadlines |
|
|
61
61
|
| Only if the tool speaks HTTP | `/http` |
|
|
62
|
-
|
|
|
62
|
+
| Every command that answers | `/standards`: effects, errors, output envelopes, log record, next steps |
|
|
63
|
+
| Commands that describe the tool | `/commands`, `/completion`, `/query`, `/skill`, `/mcp`, `/update`, `/standards/tables` |
|
|
63
64
|
| Build time | `/codegen`, with a small `/codegen/runtime` for the generated schemas |
|
|
64
65
|
| Release time | `/release` |
|
|
65
66
|
| Tests | `/testing`: captured streams, memory and broken keyrings, a fake clock |
|
|
@@ -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
|
|
|
@@ -79,13 +79,15 @@ cli-testing, cli-docs, plus community itself.
|
|
|
79
79
|
|
|
80
80
|
- **Why:** users install the CLIs with either runtime, and a static import of one runtime's module fails to load on
|
|
81
81
|
the other.
|
|
82
|
-
- **Enforced by:** `pnpm smoke:bun` · `node-ci.yml:bun
|
|
82
|
+
- **Enforced by:** `pnpm smoke:bun` · `node-ci.yml:bun` · `node-ci.yml:platforms` (the unit suite on Windows and
|
|
83
|
+
macOS).
|
|
83
84
|
- **Example:** `"engines": { "node": ">=22" }` in `package.json`. Full validation runs on Node 24. `bun test` cannot
|
|
84
85
|
run the vitest suite, so `scripts/smoke.ts` runs the built exports with plain assertions, and the Bun job runs it
|
|
85
86
|
(`pnpm build && pnpm smoke:bun`). A new entry point gets a line there. Node 22 runs in the Windows install matrix of
|
|
86
87
|
tg, max and wa, in zoom's full validation and in cli-core's old-Node job.
|
|
87
88
|
- **Exceptions:** cli-docs and community publish no runtime package. memo, drive and cli-base do not run Node 22 in
|
|
88
|
-
any workflow yet.
|
|
89
|
+
any workflow yet. The unit suite runs on Windows and macOS for tg, max and drive (`platforms: true`); zoom and
|
|
90
|
+
memo still fail tests there, so theirs is off.
|
|
89
91
|
- **Applies to:** the CLIs, cli-core and cli-base. **Since:** cli-base 0.41.0. **Rulings:** NEED-11.
|
|
90
92
|
|
|
91
93
|
### WC-TOOL-7 · Let Biome format the code, and do not format by hand
|
|
@@ -152,22 +154,22 @@ cli-testing, cli-docs, plus community itself.
|
|
|
152
154
|
### WC-TOOL-13 · Cap every file at 1,000 lines with Biome
|
|
153
155
|
|
|
154
156
|
- **Why:** a file past 1,000 lines always holds more than one job; the cap stops it before review has to.
|
|
155
|
-
- **Enforced by:**
|
|
156
|
-
- **Example:** `biome.json` sets the style rule
|
|
157
|
-
off for
|
|
157
|
+
- **Enforced by:** `pnpm lint` · `standards.yml:standards` (the shared Biome base, like WC-TOOL-8).
|
|
158
|
+
- **Example:** the shared Biome base (community `standards/configs/biome.base.json`) sets the style rule
|
|
159
|
+
noExcessiveLinesPerFile to error with `"maxLines": 1000`, and turns it off for tests, `fixtures/` and `generated/`. Below the cap, the review signals at 300 and 500 lines are
|
|
158
160
|
in [WC-LAY-7](layout.md#wc-lay-7--treat-300-and-500-lines-as-review-signals).
|
|
159
161
|
- **Exceptions:** a file that is one cohesive unit may get its own override, listed by path in `biome.json` (tg
|
|
160
|
-
`src/telegram/adapter.ts`; four files in cli-core). A smaller cap is allowed: zoom uses 500. cli-
|
|
161
|
-
|
|
162
|
+
`src/telegram/adapter.ts`; four files in cli-core). A smaller cap is allowed: zoom uses 500. cli-docs turns it off for
|
|
163
|
+
stylesheets. Biome reads only JavaScript and TypeScript, so the cap does not cover
|
|
162
164
|
code in another language, such as wa's Go engine; the review signals of WC-LAY-7 still apply to it.
|
|
163
165
|
- **Applies to:** the ten repositories. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
164
166
|
|
|
165
167
|
### WC-TOOL-14 · Turn on the import cycle rule
|
|
166
168
|
|
|
167
169
|
- **Why:** a cycle makes load order decide which value a module sees, and the failure shows only at run time.
|
|
168
|
-
- **Enforced by:**
|
|
169
|
-
- **Example:**
|
|
170
|
-
- **Exceptions:**
|
|
170
|
+
- **Enforced by:** `pnpm lint` · `standards.yml:standards` (the shared Biome base, like WC-TOOL-8).
|
|
171
|
+
- **Example:** the shared Biome base sets the suspicious rule noImportCycles to error.
|
|
172
|
+
- **Exceptions:** none.
|
|
171
173
|
- **Applies to:** the ten repositories. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
172
174
|
|
|
173
175
|
### WC-TOOL-15 · Declare layer boundaries as restricted imports in `biome.json`
|
|
@@ -178,8 +180,7 @@ cli-testing, cli-docs, plus community itself.
|
|
|
178
180
|
folders that layer may not import, and a `message` that says why, such as "commands speak the domain model; only
|
|
179
181
|
`src/client.ts` may reach the protocol". Which layers exist and which way they depend is on the
|
|
180
182
|
[Architecture page](architecture.md).
|
|
181
|
-
- **Exceptions:** cli-base and cli-docs have no layer overrides.
|
|
182
|
-
the earlier ones today, so they catch nothing until it is fixed.
|
|
183
|
+
- **Exceptions:** cli-base and cli-docs have no layer overrides.
|
|
183
184
|
- **Applies to:** the CLIs, cli-core and cli-testing. **Since:** cli-base 0.41.0. **Rulings:** none.
|
|
184
185
|
|
|
185
186
|
### WC-TOOL-16 · Run the command lint on the built CLI, and let its baseline only shrink
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "The parts every command line tool needs: output modes, terminal rendering, error model, exit codes, credentials, clocks",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|
|
@@ -81,6 +81,10 @@
|
|
|
81
81
|
"types": "./dist/standards/index.d.ts",
|
|
82
82
|
"default": "./dist/standards/index.js"
|
|
83
83
|
},
|
|
84
|
+
"./standards/tables": {
|
|
85
|
+
"types": "./dist/standards/tables.d.ts",
|
|
86
|
+
"default": "./dist/standards/tables.js"
|
|
87
|
+
},
|
|
84
88
|
"./biome": "./config/biome.base.json",
|
|
85
89
|
"./tsconfig.base.json": "./config/tsconfig.base.json",
|
|
86
90
|
"./tsconfig.test.json": "./config/tsconfig.test.json",
|