@erclx/canon 5.34.0 → 5.36.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 +15 -17
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/REQUIREMENT.md +1 -1
- package/claude/skills/auto-ship/references/draft-mark.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +12 -12
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +2 -2
- package/claude/skills/canvas-board/references/design.md +53 -36
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -1
- package/claude/skills/codebase-layout/SKILL.md +2 -2
- package/claude/skills/create-rule/REQUIREMENT.md +6 -8
- package/claude/skills/create-rule/SKILL.md +8 -8
- package/claude/skills/create-rule/references/rule.md +11 -23
- package/claude/skills/create-skill/SKILL.md +2 -1
- package/claude/skills/create-skill/references/skill-paths.md +12 -15
- package/{standards/standard.md → claude/skills/create-skill/references/skill-reference.md} +50 -45
- package/claude/skills/create-skill/references/skill.md +9 -3
- package/claude/skills/design-taste/REQUIREMENT.md +6 -6
- package/claude/skills/design-taste/SKILL.md +2 -2
- package/claude/skills/design-taste/references/craft.md +1 -1
- package/claude/skills/design-taste/references/preflight.md +2 -2
- package/claude/skills/design-taste/references/tells.md +1 -1
- package/claude/skills/draft-and-pick/SKILL.md +1 -1
- package/claude/skills/draft-identity/SKILL.md +3 -2
- package/claude/skills/git-commit/references/versioning.md +13 -13
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/markdown-craft/references/markdown.md +3 -2
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/review-address/REQUIREMENT.md +1 -1
- package/claude/skills/review-address/SKILL.md +2 -2
- package/claude/skills/review-craft/references/ui.md +1 -1
- package/claude/skills/review-pr/SKILL.md +3 -3
- package/claude/skills/review-pr/references/post.md +1 -1
- package/claude/skills/review-ui/REQUIREMENT.md +1 -1
- package/claude/skills/review-ui/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +2 -2
- package/claude/skills/role-orchestrator/SKILL.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +3 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -8
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +10 -4
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +12 -15
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +6 -4
- package/claude/skills/role-orchestrator/scripts/poll.ts +50 -1
- package/claude/skills/role-reviewer/REQUIREMENT.md +17 -7
- package/claude/skills/role-reviewer/SKILL.md +17 -10
- package/claude/skills/role-worker/REQUIREMENT.md +1 -1
- package/claude/skills/role-worker/SKILL.md +6 -6
- package/claude/skills/session-compact/references/handoff-note.md +1 -1
- package/claude/skills/target-setup/SKILL.md +2 -2
- package/claude/skills/target-setup/references/detect.md +3 -3
- package/claude/skills/test-craft/SKILL.md +2 -2
- package/claude/skills/ux-audit/REQUIREMENT.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +2 -2
- package/claude/skills/ux-measure/REQUIREMENT.md +1 -1
- package/claude/skills/write-human/references/machine-tells.md +12 -0
- package/docs/agents/audits.md +1 -1
- package/docs/agents/commands.md +14 -13
- package/docs/agents/comments.md +1 -1
- package/docs/agents/counts.md +5 -6
- package/docs/agents/drift-surfaces.md +15 -19
- package/docs/agents/gov-detect.md +1 -1
- package/docs/agents/index.md +2 -3
- package/docs/agents/install-and-sync.md +10 -34
- package/docs/agents/markdown-audit.md +22 -12
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/output-shape.md +1 -1
- package/docs/agents/overview.md +2 -2
- package/docs/agents/records-stale.md +1 -1
- package/docs/agents/records-validate.md +11 -23
- package/docs/agents/records.md +1 -1
- package/docs/agents/routing.md +1 -1
- package/docs/agents/rule-citations.md +9 -17
- package/docs/agents/scripting.md +2 -20
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/tasks-validate.md +1 -1
- package/docs/agents/teach.md +1 -1
- package/docs/target/index.md +1 -0
- package/docs/target/migrations.md +4 -0
- package/docs/target/projects.md +10 -10
- package/docs/target/scenarios.md +5 -6
- package/docs/target/standards-moved.md +32 -0
- package/docs/target/sync.md +5 -5
- package/docs/workflow/ai-workflow.md +1 -1
- package/docs/workflow/operating-model.md +16 -18
- package/docs/workflow/skill-map.md +1 -1
- package/docs/workflow/visual-design-workflow.md +3 -3
- package/governance/detect.toml +32 -36
- package/governance/renames.toml +44 -1
- package/governance/rules/lib/{305-e2e-reliability.md → e2e-reliability.md} +1 -1
- package/governance/rules/lib/{306-test-scope.md → test-scope.md} +2 -2
- package/governance/rules/ui/{410-a11y.md → a11y.md} +1 -1
- package/governance/rules/ui/{440-surface-capture.md → surface-capture.md} +3 -3
- package/governance/stacks/base.toml +15 -8
- package/governance/stacks/go.toml +2 -0
- package/governance/stacks/node.toml +1 -1
- package/governance/stacks/php.toml +2 -0
- package/governance/stacks/python.toml +1 -1
- package/package.json +1 -4
- package/scripts/core/install-check.sh +4 -10
- package/src/audits/catalog.ts +0 -9
- package/src/capture/frame-values.ts +3 -6
- package/src/claude/routing.ts +1 -1
- package/src/claude/skills-reach.ts +4 -6
- package/src/cli/help-all.ts +96 -0
- package/src/cli/help.ts +29 -29
- package/src/cli.ts +8 -3
- package/src/commands/claude.ts +29 -0
- package/src/commands/design.ts +22 -1
- package/src/commands/gov.ts +29 -11
- package/src/commands/init.ts +10 -1
- package/src/commands/labels.ts +4 -44
- package/src/commands/markdown.ts +96 -3
- package/src/commands/migrate.ts +1 -1
- package/src/commands/records.ts +5 -21
- package/src/commands/sync.ts +11 -0
- package/src/commands/tooling.ts +10 -4
- package/src/counts/catalogs.ts +0 -6
- package/src/design/budget.ts +14 -10
- package/src/design/document.ts +5 -5
- package/src/design/parse.ts +21 -4
- package/src/design/render.ts +3 -3
- package/src/gate/boundaries.ts +2 -2
- package/src/gate/measures.ts +7 -29
- package/src/gate/sequencer.ts +51 -2
- package/src/gate/stages.ts +0 -18
- package/src/gov/citations.ts +16 -71
- package/src/gov/stacks.ts +3 -3
- package/src/inventory/subjects.ts +1 -1
- package/src/markdown/bans.ts +1 -1
- package/src/markdown/ceiling.ts +6 -1
- package/src/markdown/colons.ts +86 -0
- package/src/markdown/gate.ts +15 -0
- package/src/markdown/heading-case.ts +74 -0
- package/src/migrate/scratch-evidence.ts +2 -2
- package/src/records/validate.ts +6 -194
- package/src/sandbox/provision.ts +0 -5
- package/src/secrets/shipped.ts +1 -2
- package/src/serve/static.ts +1 -2
- package/src/shipped/references.ts +42 -93
- package/src/sync/check.ts +18 -14
- package/src/sync/copy.ts +4 -5
- package/src/tooling/inject.ts +6 -37
- package/src/tooling/read.ts +2 -3
- package/src/tooling/scan.ts +4 -17
- package/src/tooling/subfolder.ts +2 -66
- package/tooling/astro/manifest.toml +0 -1
- package/tooling/astro/reference.md +0 -8
- package/tooling/base/configs/scripts/verify.json +1 -1
- package/tooling/base/configs/scripts/verify.ts +22 -17
- package/tooling/base/manifest.toml +7 -7
- package/tooling/base/reference.md +19 -32
- package/tooling/base/seeds/.github/workflows/verify.yml +0 -9
- package/tooling/base/seeds/.lintstagedrc +2 -4
- package/tooling/base/seeds/canon/context/ci.md +4 -6
- package/tooling/base/seeds/canon/context/development.md +2 -2
- package/tooling/claude/reference.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +13 -1
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +1 -1
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +27 -2
- package/tooling/claude/seeds/CLAUDE.md +1 -1
- package/tooling/claude/seeds/canon/DESIGN.md +24 -37
- package/tooling/go/reference.md +1 -1
- package/tooling/php/reference.md +1 -1
- package/tooling/python/reference.md +2 -2
- package/tooling/shell/configs/.github/workflows/shell.yml +30 -0
- package/tooling/shell/manifest.toml +12 -0
- package/tooling/shell/reference.md +46 -0
- package/tooling/vite-react/manifest.toml +0 -1
- package/tooling/vite-react/reference.md +0 -8
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +3 -5
- package/tooling/web/configs/.github/workflows/verify.yml +0 -9
- package/tooling/web/manifest.toml +1 -2
- package/tooling/web/reference.md +4 -6
- package/docs/agents/standards-audit.md +0 -40
- package/governance/rules/tooling/765-spelling.md +0 -19
- package/governance/stacks/astro.toml +0 -2
- package/governance/stacks/nextjs.toml +0 -2
- package/governance/stacks/node-server.toml +0 -2
- package/governance/stacks/python-fastapi.toml +0 -2
- package/governance/stacks/react.toml +0 -2
- package/src/commands/standards.ts +0 -278
- package/src/labels/spelling.ts +0 -120
- package/src/standards/audit.ts +0 -146
- package/src/standards/list.ts +0 -33
- package/src/standards/read.ts +0 -177
- package/src/standards/scope.ts +0 -56
- package/standards/index.md +0 -10
- package/tooling/base/configs/.vscode/extensions.json +0 -9
- package/tooling/base/configs/.vscode/settings.json +0 -3
- package/tooling/base/configs/scripts/verify.sh +0 -2
- package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +0 -25
- package/tooling/base/seeds/cspell.json +0 -20
- package/tooling/go/seeds/.cspell/tech-stack.txt +0 -16
- package/tooling/nextjs/seeds/.cspell/tech-stack.txt +0 -3
- package/tooling/php/seeds/.cspell/tech-stack.txt +0 -5
- package/tooling/python/seeds/.cspell/tech-stack.txt +0 -18
- package/tooling/vite-react/seeds/.cspell/project-terms.txt +0 -1
- package/tooling/vite-react/seeds/.cspell/tech-stack.txt +0 -2
- package/tooling/web/configs/.vscode/extensions.json +0 -13
- package/tooling/web/configs/.vscode/settings.json +0 -10
- package/tooling/web/seeds/.cspell/tech-stack.txt +0 -21
- /package/governance/rules/canon/{606-git.md → git.md} +0 -0
- /package/governance/rules/canon/{611-indexes.md → indexes.md} +0 -0
- /package/governance/rules/canon/{604-scratch.md → scratch.md} +0 -0
- /package/governance/rules/canon/{602-tasks.md → task-scope.md} +0 -0
- /package/governance/rules/canon/{605-worktrees.md → worktrees.md} +0 -0
- /package/governance/rules/claude/{566-output.md → output.md} +0 -0
- /package/governance/rules/code/{000-code.md → routing.md} +0 -0
- /package/governance/rules/code/{010-testing.md → testing.md} +0 -0
- /package/governance/rules/framework/{210-astro.md → astro.md} +0 -0
- /package/governance/rules/framework/{220-fastapi.md → fastapi.md} +0 -0
- /package/governance/rules/framework/{230-nextjs.md → nextjs.md} +0 -0
- /package/governance/rules/framework/{200-react.md → react.md} +0 -0
- /package/governance/rules/framework/{260-shadcn.md → shadcn.md} +0 -0
- /package/governance/rules/framework/{250-tailwind.md → tailwind.md} +0 -0
- /package/governance/rules/lang/{130-go.md → go.md} +0 -0
- /package/governance/rules/lang/{140-php.md → php.md} +0 -0
- /package/governance/rules/lang/{110-python.md → python.md} +0 -0
- /package/governance/rules/lang/{100-typescript.md → typescript.md} +0 -0
- /package/governance/rules/lib/{370-database.md → database.md} +0 -0
- /package/governance/rules/lib/{340-pydantic.md → pydantic.md} +0 -0
- /package/governance/rules/lib/{360-security-server.md → security-server.md} +0 -0
- /package/governance/rules/lib/{350-security-web.md → security-web.md} +0 -0
- /package/governance/rules/lib/{320-tanstack-query.md → tanstack-query.md} +0 -0
- /package/governance/rules/lib/{335-testing-go.md → testing-go.md} +0 -0
- /package/governance/rules/lib/{336-testing-php.md → testing-php.md} +0 -0
- /package/governance/rules/lib/{330-testing-py.md → testing-py.md} +0 -0
- /package/governance/rules/lib/{300-testing-ts.md → testing-ts.md} +0 -0
- /package/governance/rules/lib/{310-zod.md → zod.md} +0 -0
- /package/governance/rules/tooling/{700-ci-workflow.md → ci-workflow.md} +0 -0
- /package/governance/rules/tooling/{790-code-comments.md → code-comments.md} +0 -0
- /package/governance/rules/tooling/{780-config-comments.md → config-comments.md} +0 -0
- /package/governance/rules/tooling/{775-dependencies.md → dependencies.md} +0 -0
- /package/governance/rules/ui/{480-canvas.md → canvas.md} +0 -0
- /package/governance/rules/ui/{400-ui.md → copy.md} +0 -0
- /package/governance/rules/ui/{460-design-taste.md → design-taste.md} +0 -0
- /package/governance/rules/ui/{420-forms.md → forms.md} +0 -0
- /package/governance/rules/ui/{465-interface-casing.md → interface-casing.md} +0 -0
- /package/governance/rules/ui/{450-link-behavior.md → link-behavior.md} +0 -0
- /package/governance/rules/ui/{470-motion.md → motion.md} +0 -0
- /package/governance/rules/ui/{430-ux-completeness.md → ux-completeness.md} +0 -0
- /package/tooling/{base → shell}/configs/.editorconfig +0 -0
- /package/tooling/{base → shell}/configs/.shellcheckrc +0 -0
|
@@ -6,10 +6,9 @@ import { SURFACE_ROOTS } from '@/roots/surface'
|
|
|
6
6
|
/**
|
|
7
7
|
* The authoring roots this repository owns and no install channel delivers.
|
|
8
8
|
*
|
|
9
|
-
* Every entry is a folder a target never holds under that spelling.
|
|
10
|
-
* install
|
|
11
|
-
*
|
|
12
|
-
* own source, docs, and catalogs.
|
|
9
|
+
* Every entry is a folder a target never holds under that spelling. Rules
|
|
10
|
+
* install under `.claude/rules/`, and the rest are this repository's own
|
|
11
|
+
* source, docs, and catalogs.
|
|
13
12
|
*
|
|
14
13
|
* `src/`, `scripts/`, and bare `docs/` are deliberately absent. A body naming
|
|
15
14
|
* one of those is describing the reader's own tree, so listing them would
|
|
@@ -28,7 +27,6 @@ const AUTHORING_ROOTS = [
|
|
|
28
27
|
'docs/agents/',
|
|
29
28
|
'governance/',
|
|
30
29
|
'internal/',
|
|
31
|
-
'standards/',
|
|
32
30
|
'tooling/',
|
|
33
31
|
'wiki/',
|
|
34
32
|
] as const
|
|
@@ -51,7 +49,7 @@ const TOKEN = /`([^`\s]+)`/g
|
|
|
51
49
|
*
|
|
52
50
|
* Requires an extension and a separator, and admits no `<`, `$`, or `*`. A
|
|
53
51
|
* body writes `canon/context/<domain>.md` to name a shape rather than a
|
|
54
|
-
* file, and `${CLAUDE_SKILL_DIR}
|
|
52
|
+
* file, and `${CLAUDE_SKILL_DIR}/../<skill>/references/<name>.md` to resolve
|
|
55
53
|
* against the plugin root, which is self-contained by construction.
|
|
56
54
|
*/
|
|
57
55
|
const CONCRETE = /^[.A-Za-z0-9_][A-Za-z0-9._/-]*\.[a-z]{1,4}$/
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
|
|
3
|
+
export type HelpRoute =
|
|
4
|
+
| { kind: 'parse' }
|
|
5
|
+
| { kind: 'top' }
|
|
6
|
+
| { kind: 'all'; command: Command }
|
|
7
|
+
| { kind: 'unknown'; name: string }
|
|
8
|
+
|
|
9
|
+
const HELP_FLAGS = new Set(['-h', '--help'])
|
|
10
|
+
|
|
11
|
+
// Commander exposes no getter for a disabled help option, and `canon sandbox`
|
|
12
|
+
// disables its own to forward `--help` to a bash script.
|
|
13
|
+
function hasHelpOption(command: Command): boolean {
|
|
14
|
+
return command.helpInformation().includes('--help')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// A group with its own action, or with a default subcommand such as
|
|
18
|
+
// `inventory run`, takes an operand that names no subcommand. Commander keeps
|
|
19
|
+
// both on private fields.
|
|
20
|
+
function takesOperand(command: Command): boolean {
|
|
21
|
+
const internals = command as unknown as {
|
|
22
|
+
_actionHandler: unknown
|
|
23
|
+
_defaultCommandName: unknown
|
|
24
|
+
}
|
|
25
|
+
return (
|
|
26
|
+
command.registeredArguments.length > 0 ||
|
|
27
|
+
internals._actionHandler !== null ||
|
|
28
|
+
internals._defaultCommandName !== null
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function visibleChildren(command: Command): Command[] {
|
|
33
|
+
return command
|
|
34
|
+
.createHelp()
|
|
35
|
+
.visibleCommands(command)
|
|
36
|
+
.filter((child) => command.commands.includes(child))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function leaves(command: Command): Command[] {
|
|
40
|
+
return visibleChildren(command).flatMap((child) =>
|
|
41
|
+
visibleChildren(child).length === 0 ? [child] : leaves(child),
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// `outputHelp` rather than `helpInformation`, since only the former emits the
|
|
46
|
+
// blocks `addHelpText` registers, which carry every verb's exit codes and
|
|
47
|
+
// examples.
|
|
48
|
+
function captureHelp(command: Command): string {
|
|
49
|
+
const config = command.configureOutput()
|
|
50
|
+
const { writeOut } = config
|
|
51
|
+
let text = ''
|
|
52
|
+
command.configureOutput({ writeOut: (chunk) => (text += chunk) })
|
|
53
|
+
try {
|
|
54
|
+
command.outputHelp()
|
|
55
|
+
} finally {
|
|
56
|
+
command.configureOutput({ writeOut })
|
|
57
|
+
}
|
|
58
|
+
return text.trimEnd()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Each block opens on its own `Usage:` line, so a blank line is the whole
|
|
62
|
+
// separator and a reader splits on the usage header.
|
|
63
|
+
export function renderAll(command: Command): string {
|
|
64
|
+
const blocks = [command, ...leaves(command)].map(captureHelp)
|
|
65
|
+
return `${blocks.join('\n\n')}\n`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Reads argv ahead of commander, which prints a group's help for an unknown
|
|
69
|
+
// subcommand because it answers `--help` before it resolves operands. Walking
|
|
70
|
+
// stops at the first option, so an option's value is never read as a name.
|
|
71
|
+
export function routeHelp(program: Command, args: string[]): HelpRoute {
|
|
72
|
+
if (!args.some((arg) => HELP_FLAGS.has(arg))) return { kind: 'parse' }
|
|
73
|
+
|
|
74
|
+
let command = program
|
|
75
|
+
let depth = 0
|
|
76
|
+
for (const arg of args) {
|
|
77
|
+
if (arg.startsWith('-')) break
|
|
78
|
+
const child = command.commands.find((c) => c.name() === arg)
|
|
79
|
+
if (child === undefined) {
|
|
80
|
+
const isGroupOnly =
|
|
81
|
+
command !== program &&
|
|
82
|
+
command.commands.length > 0 &&
|
|
83
|
+
!takesOperand(command) &&
|
|
84
|
+
arg !== 'help'
|
|
85
|
+
if (isGroupOnly) return { kind: 'unknown', name: arg }
|
|
86
|
+
break
|
|
87
|
+
}
|
|
88
|
+
command = child
|
|
89
|
+
depth += 1
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!args.includes('--all')) return { kind: 'parse' }
|
|
93
|
+
if (depth === 0) return { kind: 'top' }
|
|
94
|
+
if (!hasHelpOption(command)) return { kind: 'parse' }
|
|
95
|
+
return { kind: 'all', command }
|
|
96
|
+
}
|
package/src/cli/help.ts
CHANGED
|
@@ -20,62 +20,61 @@ export const COMMAND_GROUPS: { title: string; rows: CommandRow[] }[] = [
|
|
|
20
20
|
['sync [path]', 'Sync all installed domains in a project'],
|
|
21
21
|
['upgrade', 'Reinstall the CLI with the manager that installed it'],
|
|
22
22
|
['migrate [cmd]', 'Move a project off a retired name or layout'],
|
|
23
|
-
['targets [cmd]', 'Projects this toolkit installed into
|
|
23
|
+
['targets [cmd]', 'Projects this toolkit installed into'],
|
|
24
24
|
],
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
title: 'Domains',
|
|
28
28
|
rows: [
|
|
29
|
-
['gov [cmd]', 'Governance rules
|
|
30
|
-
['
|
|
31
|
-
['
|
|
32
|
-
['
|
|
33
|
-
['
|
|
34
|
-
['
|
|
35
|
-
['docs [cmd|topic]', 'Emit toolkit reference docs (list, <topic>)'],
|
|
29
|
+
['gov [cmd]', 'Governance rules'],
|
|
30
|
+
['tooling [cmd]', 'Tooling stacks'],
|
|
31
|
+
['claude [cmd]', 'Claude workflow'],
|
|
32
|
+
['wiki [cmd]', 'Wiki pages'],
|
|
33
|
+
['indexes [cmd]', 'Regenerate index.md files'],
|
|
34
|
+
['docs [cmd|topic]', 'Emit toolkit reference docs'],
|
|
36
35
|
],
|
|
37
36
|
},
|
|
38
37
|
{
|
|
39
38
|
title: 'Author and render',
|
|
40
39
|
rows: [
|
|
41
|
-
['design [cmd]', 'Design system
|
|
42
|
-
['slides [cmd]', 'Slide decks
|
|
40
|
+
['design [cmd]', 'Design system'],
|
|
41
|
+
['slides [cmd]', 'Slide decks'],
|
|
43
42
|
['capture [source]', 'Render HTML capture sources to PNG'],
|
|
44
43
|
['serve [dir]', 'Serve a directory on localhost, print the link'],
|
|
45
|
-
['demo [cmd]', 'Record a running app
|
|
44
|
+
['demo [cmd]', 'Record a running app'],
|
|
46
45
|
['inventory [subj]', 'Report one computed property across every route'],
|
|
47
46
|
['drive <url> <run>', 'Walk a page through interactions, measure each'],
|
|
48
47
|
['transcripts <url>', 'Fetch a YouTube transcript with frontmatter'],
|
|
49
|
-
['teach [cmd]', 'Learning workspaces
|
|
50
|
-
['canvas [cmd]', 'Local canvas of pages and frames
|
|
48
|
+
['teach [cmd]', 'Learning workspaces'],
|
|
49
|
+
['canvas [cmd]', 'Local canvas of pages and frames'],
|
|
51
50
|
],
|
|
52
51
|
},
|
|
53
52
|
{
|
|
54
53
|
title: 'Session and ship',
|
|
55
54
|
rows: [
|
|
56
55
|
['sandbox [cat:cmd]', 'Provision and run sandbox scenarios'],
|
|
57
|
-
['tasks [cmd]', 'Task board
|
|
58
|
-
['intake [cmd]', 'Intake folders under .canon/intake/
|
|
59
|
-
['records [cmd]', 'Session records
|
|
56
|
+
['tasks [cmd]', 'Task board'],
|
|
57
|
+
['intake [cmd]', 'Intake folders under .canon/intake/'],
|
|
58
|
+
['records [cmd]', 'Session records'],
|
|
60
59
|
['sessions [cmd]', 'Resolve live sessions to worktree and branch'],
|
|
61
60
|
['worktrees [cmd]', 'Reclaim worktrees whose branches merged'],
|
|
62
|
-
['hooks [cmd]', 'Run the steps a git hook drives
|
|
63
|
-
['pr [cmd]', 'Read a pull request
|
|
64
|
-
['upstream [cmd]', 'Read Claude Code releases
|
|
61
|
+
['hooks [cmd]', 'Run the steps a git hook drives'],
|
|
62
|
+
['pr [cmd]', 'Read a pull request'],
|
|
63
|
+
['upstream [cmd]', 'Read Claude Code releases'],
|
|
65
64
|
['feedback', 'File toolkit feedback as a GitHub issue'],
|
|
66
65
|
],
|
|
67
66
|
},
|
|
68
67
|
{
|
|
69
68
|
title: 'Repo reports',
|
|
70
69
|
rows: [
|
|
71
|
-
['audits [cmd]', 'Run every health check as one set
|
|
72
|
-
['gate [cmd]', 'Run the merge gate stage by stage
|
|
73
|
-
['secrets [cmd]', 'Scan the shipped tree for credentials
|
|
74
|
-
['deps [cmd]', 'Read the dependency set for advisories
|
|
75
|
-
['labels [cmd]', 'Read a changed set against the label map
|
|
76
|
-
['comments [cmd]', 'Measure comment density and trend
|
|
77
|
-
['context [cmd]', 'Report context folder health
|
|
78
|
-
['markdown [cmd]', 'Report markdown against the
|
|
70
|
+
['audits [cmd]', 'Run every health check as one set'],
|
|
71
|
+
['gate [cmd]', 'Run the merge gate stage by stage'],
|
|
72
|
+
['secrets [cmd]', 'Scan the shipped tree for credentials'],
|
|
73
|
+
['deps [cmd]', 'Read the dependency set for advisories'],
|
|
74
|
+
['labels [cmd]', 'Read a changed set against the label map'],
|
|
75
|
+
['comments [cmd]', 'Measure comment density and trend'],
|
|
76
|
+
['context [cmd]', 'Report context folder health'],
|
|
77
|
+
['markdown [cmd]', 'Report markdown against the shipped bans'],
|
|
79
78
|
['census [path]', 'Report file count, extensions, and line totals'],
|
|
80
79
|
],
|
|
81
80
|
},
|
|
@@ -91,10 +90,10 @@ const SANDBOX_ROWS: CommandRow[] = [
|
|
|
91
90
|
const EXAMPLES = [
|
|
92
91
|
'canon sync ../my-app',
|
|
93
92
|
'canon sandbox git:commit',
|
|
94
|
-
'canon gov install
|
|
93
|
+
'canon gov install node',
|
|
95
94
|
'canon gov sync ../my-app',
|
|
96
95
|
'canon gov restated --json',
|
|
97
|
-
'canon
|
|
96
|
+
'canon markdown audit docs/',
|
|
98
97
|
'canon init ../my-app',
|
|
99
98
|
'canon tooling sync base',
|
|
100
99
|
'canon claude init',
|
|
@@ -112,6 +111,7 @@ const EXAMPLES = [
|
|
|
112
111
|
'canon drive http://localhost:4173 run.json --json',
|
|
113
112
|
'pbpaste | canon feedback',
|
|
114
113
|
'canon transcripts https://youtu.be/VIDEO_ID',
|
|
114
|
+
'canon tasks --help --all',
|
|
115
115
|
'canon tasks archive --pull-request 673 --json',
|
|
116
116
|
'canon intake list toolkit-overview --unread --json',
|
|
117
117
|
'canon teach list --json',
|
package/src/cli.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { register as init } from '@/commands/init'
|
|
|
5
5
|
import { register as sandbox } from '@/commands/sandbox'
|
|
6
6
|
import { register as sync } from '@/commands/sync'
|
|
7
7
|
import { register as gov } from '@/commands/gov'
|
|
8
|
-
import { register as standards } from '@/commands/standards'
|
|
9
8
|
import { register as tooling } from '@/commands/tooling'
|
|
10
9
|
import { register as claude } from '@/commands/claude'
|
|
11
10
|
import { register as wiki } from '@/commands/wiki'
|
|
@@ -44,6 +43,7 @@ import { register as targets } from '@/commands/targets'
|
|
|
44
43
|
import { register as upgrade } from '@/commands/upgrade'
|
|
45
44
|
import { readInstalled, UNKNOWN_LABEL } from '@/version/installed'
|
|
46
45
|
import { renderHelp } from '@/cli/help'
|
|
46
|
+
import { renderAll, routeHelp } from '@/cli/help-all'
|
|
47
47
|
|
|
48
48
|
function showHelp(): void {
|
|
49
49
|
console.log(renderHelp(process.stdout))
|
|
@@ -66,7 +66,6 @@ init(program)
|
|
|
66
66
|
sandbox(program)
|
|
67
67
|
sync(program)
|
|
68
68
|
gov(program)
|
|
69
|
-
standards(program)
|
|
70
69
|
tooling(program)
|
|
71
70
|
claude(program)
|
|
72
71
|
wiki(program)
|
|
@@ -104,4 +103,10 @@ audits(program)
|
|
|
104
103
|
gate(program)
|
|
105
104
|
upgrade(program)
|
|
106
105
|
|
|
107
|
-
program.
|
|
106
|
+
const route = routeHelp(program, process.argv.slice(2))
|
|
107
|
+
if (route.kind === 'top') showHelp()
|
|
108
|
+
else if (route.kind === 'all') process.stdout.write(renderAll(route.command))
|
|
109
|
+
else if (route.kind === 'unknown') {
|
|
110
|
+
console.error(`error: unknown command '${route.name}'`)
|
|
111
|
+
process.exitCode = 1
|
|
112
|
+
} else program.parse()
|
package/src/commands/claude.ts
CHANGED
|
@@ -212,6 +212,20 @@ export function register(program: Command): void {
|
|
|
212
212
|
.description('Seed .claude/ workflow docs into a project')
|
|
213
213
|
.argument('[target]', 'Target directory', '.')
|
|
214
214
|
.helpOption('-h, --help', 'Show this help message')
|
|
215
|
+
.addHelpText(
|
|
216
|
+
'after',
|
|
217
|
+
[
|
|
218
|
+
'',
|
|
219
|
+
'Copies each workflow seed the target lacks, CLAUDE.md included, and',
|
|
220
|
+
'leaves one already present alone. Then adds the .gitignore entries',
|
|
221
|
+
'the claude manifest lists.',
|
|
222
|
+
'',
|
|
223
|
+
'Exit codes:',
|
|
224
|
+
' 0 initialized, already initialized, or the prompt was cancelled',
|
|
225
|
+
' 1 the target is missing or is the toolkit root',
|
|
226
|
+
'',
|
|
227
|
+
].join('\n'),
|
|
228
|
+
)
|
|
215
229
|
.action(async (target: string) => {
|
|
216
230
|
process.exitCode = await runInit(target)
|
|
217
231
|
})
|
|
@@ -221,6 +235,21 @@ export function register(program: Command): void {
|
|
|
221
235
|
.description('Reconcile .gitignore against the claude manifest')
|
|
222
236
|
.argument('[target]', 'Target directory', '.')
|
|
223
237
|
.helpOption('-h, --help', 'Show this help message')
|
|
238
|
+
.addHelpText(
|
|
239
|
+
'after',
|
|
240
|
+
[
|
|
241
|
+
'',
|
|
242
|
+
'Writes .gitignore alone: adds the entries the claude manifest lists',
|
|
243
|
+
'and drops ones under its headers that the manifest no longer lists.',
|
|
244
|
+
'A seeded file is reported, never rewritten, and a missing one points',
|
|
245
|
+
'at `canon claude init`.',
|
|
246
|
+
'',
|
|
247
|
+
'Exit codes:',
|
|
248
|
+
' 0 synced, already up to date, or the prompt was cancelled',
|
|
249
|
+
' 1 the target is missing or is the toolkit root',
|
|
250
|
+
'',
|
|
251
|
+
].join('\n'),
|
|
252
|
+
)
|
|
224
253
|
.action(async (target: string) => {
|
|
225
254
|
process.exitCode = await runSync(target)
|
|
226
255
|
})
|
package/src/commands/design.ts
CHANGED
|
@@ -161,7 +161,13 @@ export function register(program: Command): void {
|
|
|
161
161
|
`overrides a value by writing ${join(DESIGN_INSTALL_DIR, DESIGN_PROJECT_SUBDIR)}/`,
|
|
162
162
|
'itself, which sync never touches. Nothing arrives on a project that',
|
|
163
163
|
'has not run this, so a design value reaches a target on an install',
|
|
164
|
-
'rather than on the next sync.',
|
|
164
|
+
'rather than on the next sync. A base stylesheet already installed is',
|
|
165
|
+
'replaced.',
|
|
166
|
+
'',
|
|
167
|
+
'Exit codes:',
|
|
168
|
+
' 0 the stylesheet was installed',
|
|
169
|
+
' 1 the target is missing or is the toolkit root, or the toolkit',
|
|
170
|
+
' source is absent',
|
|
165
171
|
'',
|
|
166
172
|
].join('\n'),
|
|
167
173
|
)
|
|
@@ -176,6 +182,21 @@ export function register(program: Command): void {
|
|
|
176
182
|
)
|
|
177
183
|
.argument('[target]', 'Target directory', '.')
|
|
178
184
|
.helpOption('-h, --help', 'Show this help message')
|
|
185
|
+
.addHelpText(
|
|
186
|
+
'after',
|
|
187
|
+
[
|
|
188
|
+
'',
|
|
189
|
+
'Replaces the shipped design files under .claude/design/ with the',
|
|
190
|
+
'toolkit copy, edited or not, and leaves',
|
|
191
|
+
`${join(DESIGN_INSTALL_DIR, DESIGN_PROJECT_SUBDIR)}/ alone. It deletes nothing it finds no`,
|
|
192
|
+
'source for.',
|
|
193
|
+
'',
|
|
194
|
+
'Exit codes:',
|
|
195
|
+
' 0 synced, already up to date, or the prompt was cancelled',
|
|
196
|
+
' 1 the target is missing or is the toolkit root',
|
|
197
|
+
'',
|
|
198
|
+
].join('\n'),
|
|
199
|
+
)
|
|
179
200
|
.action(async (target: string) => {
|
|
180
201
|
process.exitCode = await runDomainSync(
|
|
181
202
|
createDesignAdapter(PROJECT_ROOT),
|
package/src/commands/gov.ts
CHANGED
|
@@ -143,7 +143,7 @@ export function register(program: Command): void {
|
|
|
143
143
|
gov
|
|
144
144
|
.command('install')
|
|
145
145
|
.description('Install a governance stack into .claude/rules/canon/')
|
|
146
|
-
.argument('[stack]', 'Stack name (e.g. base, node,
|
|
146
|
+
.argument('[stack]', 'Stack name (e.g. base, node, python)')
|
|
147
147
|
.argument('[target]', 'Target directory', '.')
|
|
148
148
|
.helpOption('-h, --help', 'Show this help message')
|
|
149
149
|
.option('--add <rules>', 'Comma-separated rules to layer on the stack')
|
|
@@ -152,15 +152,23 @@ export function register(program: Command): void {
|
|
|
152
152
|
[
|
|
153
153
|
'',
|
|
154
154
|
'Examples:',
|
|
155
|
-
' canon gov install
|
|
155
|
+
' canon gov install node',
|
|
156
156
|
' canon gov install node ../my-app',
|
|
157
|
-
' canon gov install
|
|
157
|
+
' canon gov install node --add astro,shadcn ../my-app',
|
|
158
158
|
' canon gov install --add tasks,plan ../my-app',
|
|
159
159
|
'',
|
|
160
160
|
'With --add and no stack, the named rules install alone. A first',
|
|
161
161
|
'positional naming a stack is read as the stack, so pass . or a path',
|
|
162
162
|
'carrying a slash to force a target that shares a stack name.',
|
|
163
163
|
'',
|
|
164
|
+
'Copies each rule into .claude/rules/canon/, replacing a copy already',
|
|
165
|
+
'there. Rules under .claude/rules/project/ are never read.',
|
|
166
|
+
'',
|
|
167
|
+
'Exit codes:',
|
|
168
|
+
' 0 installed, the stack held no rules, or the prompt was cancelled',
|
|
169
|
+
' 1 refused: no stack named headlessly, an unknown stack, no --add',
|
|
170
|
+
' rule resolved, or a missing target or the toolkit root',
|
|
171
|
+
'',
|
|
164
172
|
].join('\n'),
|
|
165
173
|
)
|
|
166
174
|
.action(
|
|
@@ -178,6 +186,21 @@ export function register(program: Command): void {
|
|
|
178
186
|
.description('Update rules already installed under .claude/rules/canon/')
|
|
179
187
|
.argument('[target]', 'Target directory', '.')
|
|
180
188
|
.helpOption('-h, --help', 'Show this help message')
|
|
189
|
+
.addHelpText(
|
|
190
|
+
'after',
|
|
191
|
+
[
|
|
192
|
+
'',
|
|
193
|
+
'Replaces an edited rule under .claude/rules/canon/ with the shipped',
|
|
194
|
+
'copy, deletes a rule the toolkit retired, and moves a renamed one.',
|
|
195
|
+
'It adds no new rule, which is `canon gov install`, and never touches',
|
|
196
|
+
'.claude/rules/project/.',
|
|
197
|
+
'',
|
|
198
|
+
'Exit codes:',
|
|
199
|
+
' 0 synced, already up to date, or the prompt was cancelled',
|
|
200
|
+
' 1 the target is missing or is the toolkit root',
|
|
201
|
+
'',
|
|
202
|
+
].join('\n'),
|
|
203
|
+
)
|
|
181
204
|
.action(async (target: string) => {
|
|
182
205
|
process.exitCode = await runDomainSync(
|
|
183
206
|
createGovAdapter(PROJECT_ROOT),
|
|
@@ -307,7 +330,7 @@ export function register(program: Command): void {
|
|
|
307
330
|
'members a closed catalog holds, then compares the stated figure',
|
|
308
331
|
'against what the tree actually counts.',
|
|
309
332
|
'',
|
|
310
|
-
'Catalogs read: skills, governance rules,
|
|
333
|
+
'Catalogs read: skills, governance rules, CLI commands,',
|
|
311
334
|
'and audit ids. Closed rather than derived, so widening the',
|
|
312
335
|
'set is a deliberate change rather than a side effect of a new list',
|
|
313
336
|
'command shipping elsewhere.',
|
|
@@ -440,21 +463,16 @@ export function register(program: Command): void {
|
|
|
440
463
|
'internal corpus ships nowhere, which makes the tree it governs the tree',
|
|
441
464
|
'present and the question answerable.',
|
|
442
465
|
'',
|
|
443
|
-
'
|
|
444
|
-
' standard canon standards <name> , against standards/ alone, which',
|
|
445
|
-
' is where the verb itself looks. internal/standards/ is not',
|
|
446
|
-
' tried, since a name resolving only there refuses for the',
|
|
447
|
-
' session that opens the citation.',
|
|
466
|
+
'Form read, with where it resolves:',
|
|
448
467
|
' path a backticked path carrying a directory segment and a file',
|
|
449
468
|
' extension, against the root',
|
|
450
|
-
" sibling a bare <nnn>-<slug>.md , against the citing rule's folder",
|
|
451
469
|
'',
|
|
452
470
|
'Not read, each a shape the corpus writes and none of them a citation:',
|
|
453
471
|
' a placeholder or glob segment, which describes a shape rather than',
|
|
454
472
|
' naming a file, such as canon/context/<domain>.md or app/**/route.ts',
|
|
455
473
|
' a bare filename naming a convention, such as route.ts or manifest.toml',
|
|
456
474
|
' a span carrying no file extension, which is a folder or a module',
|
|
457
|
-
' specifier, such as src/pages/ , next/font , or claude/
|
|
475
|
+
' specifier, such as src/pages/ , next/font , or claude/skills',
|
|
458
476
|
' a fenced block, which displays a path rather than pointing at one',
|
|
459
477
|
'',
|
|
460
478
|
'Exempt, reported by name rather than dropped:',
|
package/src/commands/init.ts
CHANGED
|
@@ -37,10 +37,19 @@ export function register(program: Command): void {
|
|
|
37
37
|
'',
|
|
38
38
|
'Passing any option skips the confirmation prompt.',
|
|
39
39
|
'',
|
|
40
|
+
'Runs `canon tooling sync base --write` first, which replaces every',
|
|
41
|
+
'base golden config the target holds, then `canon claude init`,',
|
|
42
|
+
'`canon gov install`, and `canon wiki init`. Refuses a target that is',
|
|
43
|
+
'not a directory or is the toolkit root.',
|
|
44
|
+
'',
|
|
45
|
+
'Exit codes:',
|
|
46
|
+
' 0 every domain installed, or the prompt was cancelled',
|
|
47
|
+
' 1 the target was refused, or a domain failed, named on stderr',
|
|
48
|
+
'',
|
|
40
49
|
'Examples:',
|
|
41
50
|
' canon init',
|
|
42
51
|
' canon init ../my-app',
|
|
43
|
-
' canon init --stack
|
|
52
|
+
' canon init --stack node --add astro,shadcn ../my-app',
|
|
44
53
|
' canon init --skip governance ../my-app',
|
|
45
54
|
'',
|
|
46
55
|
].join('\n'),
|
package/src/commands/labels.ts
CHANGED
|
@@ -10,7 +10,6 @@ import { checkTitleFormat, type TitleFormatIssue } from '@/labels/format'
|
|
|
10
10
|
import { MAP_REL } from '@/labels/map'
|
|
11
11
|
import { isReleasePullRequest, scanPhaseLabels } from '@/labels/phase'
|
|
12
12
|
import { checkSections } from '@/labels/sections'
|
|
13
|
-
import { scanTitleSpelling } from '@/labels/spelling'
|
|
14
13
|
import { BAN_SETS } from '@/markdown/bans'
|
|
15
14
|
import { bodyLines, scanBans } from '@/markdown/scan'
|
|
16
15
|
import { intro, logInfo, logStep, logWarn, outro, plural } from '@/cli/ui'
|
|
@@ -169,7 +168,7 @@ export function register(program: Command): void {
|
|
|
169
168
|
labels
|
|
170
169
|
.command('scan')
|
|
171
170
|
.description(
|
|
172
|
-
'Fail a pull request or a posted review whose title, body, or review comment carries a phase label, a board identifier, a session link
|
|
171
|
+
'Fail a pull request or a posted review whose title, body, or review comment carries a phase label, a board identifier, or a session link',
|
|
173
172
|
)
|
|
174
173
|
.helpOption('-h, --help', 'Show this help message')
|
|
175
174
|
.option(
|
|
@@ -188,7 +187,7 @@ export function register(program: Command): void {
|
|
|
188
187
|
'after',
|
|
189
188
|
[
|
|
190
189
|
'',
|
|
191
|
-
'Reads
|
|
190
|
+
'Reads the git-commit versioning reference for the two namespaces and sorts every',
|
|
192
191
|
'version-shaped token this pull request carries into the one the pull',
|
|
193
192
|
'request is allowed to hold. A release-please pull request, read off its',
|
|
194
193
|
'own fixed head branch and title, may carry semver references. Every',
|
|
@@ -212,13 +211,6 @@ export function register(program: Command): void {
|
|
|
212
211
|
'session and for no other reader, which no clone repairs, so it is read',
|
|
213
212
|
'on a release pull request too, where the board identifier is not.',
|
|
214
213
|
'',
|
|
215
|
-
"It also spell-checks the title alone against this repository's own",
|
|
216
|
-
'cspell config, since release-please copies the title into',
|
|
217
|
-
'CHANGELOG.md and nothing else spell-checks it first. The check shells',
|
|
218
|
-
"this repository's own resolved cspell binary and reports nothing when",
|
|
219
|
-
'a target project carries none, rather than reaching the network or',
|
|
220
|
-
'forcing a new dependency.',
|
|
221
|
-
'',
|
|
222
214
|
"It also grades the title alone against claude/skills/git-pr/references/pr.md's ## Title",
|
|
223
215
|
'section: the `<type>(<scope>)[!]: <subject>` structure, lowercase casing',
|
|
224
216
|
'for the type, the scope, and the first subject word, and a 72-',
|
|
@@ -234,11 +226,11 @@ export function register(program: Command): void {
|
|
|
234
226
|
'request or a review, outside a code span or a link.',
|
|
235
227
|
'',
|
|
236
228
|
'Exit codes:',
|
|
237
|
-
' 0 none of the
|
|
229
|
+
' 0 none of the six found',
|
|
238
230
|
' 1 refused, with the reason on stderr or in the JSON record',
|
|
239
231
|
' 2 the title or body carries a phase label, a board identifier, a',
|
|
240
232
|
' session link, a banned character, a heading outside the closed',
|
|
241
|
-
' list or a required one missing,
|
|
233
|
+
' list or a required one missing, or a title',
|
|
242
234
|
" breaking claude/skills/git-pr/references/pr.md's format, casing, or length",
|
|
243
235
|
'',
|
|
244
236
|
'Examples:',
|
|
@@ -532,7 +524,6 @@ async function runScan(opts: ScanOptions): Promise<number> {
|
|
|
532
524
|
}
|
|
533
525
|
|
|
534
526
|
const result = scanPhaseLabels(resolved)
|
|
535
|
-
const spelling = await scanTitleSpelling(resolved.title, process.cwd())
|
|
536
527
|
// A scan given no title, whatever produced that absence, has nothing to
|
|
537
528
|
// grade and would otherwise fail as `structure` for the wrong reason.
|
|
538
529
|
const titleFormat =
|
|
@@ -579,34 +570,6 @@ async function runScan(opts: ScanOptions): Promise<number> {
|
|
|
579
570
|
for (const link of result.sessionLinks) logWarn(link)
|
|
580
571
|
}
|
|
581
572
|
|
|
582
|
-
const spellingChecked = spelling.kind === 'checked'
|
|
583
|
-
const unspelledWords =
|
|
584
|
-
spelling.kind === 'checked' ? spelling.unknownWords : []
|
|
585
|
-
|
|
586
|
-
logStep(
|
|
587
|
-
spelling.kind === 'unavailable'
|
|
588
|
-
? 'Spelling unavailable'
|
|
589
|
-
: unspelledWords.length === 0
|
|
590
|
-
? 'Clean'
|
|
591
|
-
: 'Unspelled word found',
|
|
592
|
-
)
|
|
593
|
-
if (spelling.kind === 'unavailable' && spelling.reason === 'no-binary') {
|
|
594
|
-
logInfo(
|
|
595
|
-
`no node_modules/.bin/cspell resolved walking up from ${spelling.probedFrom}, so the title was not checked`,
|
|
596
|
-
)
|
|
597
|
-
} else if (spelling.kind === 'unavailable') {
|
|
598
|
-
logInfo(
|
|
599
|
-
`cspell did not exit clean or with issues found (${spelling.message}), so the title was not checked`,
|
|
600
|
-
)
|
|
601
|
-
} else if (unspelledWords.length === 0) {
|
|
602
|
-
logInfo('no word in the title is absent from every dictionary')
|
|
603
|
-
} else {
|
|
604
|
-
logWarn(
|
|
605
|
-
`${plural(unspelledWords.length, 'word')} in the title absent from every dictionary. Fix the spelling, or add jargon and project-specific terms to .cspell/project-terms.txt and dependency vocabulary to .cspell/tech-stack.txt.`,
|
|
606
|
-
)
|
|
607
|
-
for (const word of unspelledWords) logWarn(word)
|
|
608
|
-
}
|
|
609
|
-
|
|
610
573
|
const titleFormatIssues = titleFormat?.issues ?? []
|
|
611
574
|
|
|
612
575
|
// A review carries its own headings, a release-please body opens on a
|
|
@@ -707,8 +670,6 @@ async function runScan(opts: ScanOptions): Promise<number> {
|
|
|
707
670
|
semverTags: result.semverTags,
|
|
708
671
|
boardReferences: result.boardReferences,
|
|
709
672
|
sessionLinks: result.sessionLinks,
|
|
710
|
-
unspelledWords,
|
|
711
|
-
spellingChecked,
|
|
712
673
|
titleFormatIssues,
|
|
713
674
|
sections: { checked: sectionsChecked, ...sections },
|
|
714
675
|
bannedCharacters,
|
|
@@ -719,7 +680,6 @@ async function runScan(opts: ScanOptions): Promise<number> {
|
|
|
719
680
|
return result.phaseLabels.length === 0 &&
|
|
720
681
|
result.boardReferences.length === 0 &&
|
|
721
682
|
result.sessionLinks.length === 0 &&
|
|
722
|
-
unspelledWords.length === 0 &&
|
|
723
683
|
titleFormatIssues.length === 0 &&
|
|
724
684
|
sections.outside.length === 0 &&
|
|
725
685
|
sections.missing.length === 0 &&
|