@spikedpunch/align-cli 0.1.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/LICENSE +21 -0
- package/README.md +42 -0
- package/dist/align-dir.d.ts +55 -0
- package/dist/align-dir.d.ts.map +1 -0
- package/dist/align-dir.js +184 -0
- package/dist/align-dir.js.map +1 -0
- package/dist/commands/agent.d.ts +14 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +142 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/baseline.d.ts +4 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +57 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/build-report.d.ts +4 -0
- package/dist/commands/build-report.d.ts.map +1 -0
- package/dist/commands/build-report.js +122 -0
- package/dist/commands/build-report.js.map +1 -0
- package/dist/commands/build.d.ts +73 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +289 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/check.d.ts +31 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +203 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +173 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explain.d.ts +3 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +54 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/export-ir.d.ts +21 -0
- package/dist/commands/export-ir.d.ts.map +1 -0
- package/dist/commands/export-ir.js +33 -0
- package/dist/commands/export-ir.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +93 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/skill.d.ts +20 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +23 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/telemetry.d.ts +52 -0
- package/dist/commands/telemetry.d.ts.map +1 -0
- package/dist/commands/telemetry.js +238 -0
- package/dist/commands/telemetry.js.map +1 -0
- package/dist/composition-root.d.ts +14 -0
- package/dist/composition-root.d.ts.map +1 -0
- package/dist/composition-root.js +18 -0
- package/dist/composition-root.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +39 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/init/claude-md.d.ts +6 -0
- package/dist/init/claude-md.d.ts.map +1 -0
- package/dist/init/claude-md.js +42 -0
- package/dist/init/claude-md.js.map +1 -0
- package/dist/init/config-comment.d.ts +7 -0
- package/dist/init/config-comment.d.ts.map +1 -0
- package/dist/init/config-comment.js +44 -0
- package/dist/init/config-comment.js.map +1 -0
- package/dist/init/detect-components.d.ts +16 -0
- package/dist/init/detect-components.d.ts.map +1 -0
- package/dist/init/detect-components.js +121 -0
- package/dist/init/detect-components.js.map +1 -0
- package/dist/init/gitignore.d.ts +8 -0
- package/dist/init/gitignore.d.ts.map +1 -0
- package/dist/init/gitignore.js +27 -0
- package/dist/init/gitignore.js.map +1 -0
- package/dist/init/render-config.d.ts +18 -0
- package/dist/init/render-config.d.ts.map +1 -0
- package/dist/init/render-config.js +57 -0
- package/dist/init/render-config.js.map +1 -0
- package/dist/init/suggest-layers.d.ts +16 -0
- package/dist/init/suggest-layers.d.ts.map +1 -0
- package/dist/init/suggest-layers.js +65 -0
- package/dist/init/suggest-layers.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +182 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/program.d.ts +11 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +199 -0
- package/dist/program.js.map +1 -0
- package/dist/skill/bullet-grammar.d.ts +2 -0
- package/dist/skill/bullet-grammar.d.ts.map +1 -0
- package/dist/skill/bullet-grammar.js +12 -0
- package/dist/skill/bullet-grammar.js.map +1 -0
- package/dist/skill/cli-inventory.d.ts +16 -0
- package/dist/skill/cli-inventory.d.ts.map +1 -0
- package/dist/skill/cli-inventory.js +17 -0
- package/dist/skill/cli-inventory.js.map +1 -0
- package/dist/skill/condensed.d.ts +2 -0
- package/dist/skill/condensed.d.ts.map +1 -0
- package/dist/skill/condensed.js +24 -0
- package/dist/skill/condensed.js.map +1 -0
- package/dist/skill/dsl-verbs.d.ts +2 -0
- package/dist/skill/dsl-verbs.d.ts.map +1 -0
- package/dist/skill/dsl-verbs.js +10 -0
- package/dist/skill/dsl-verbs.js.map +1 -0
- package/dist/skill/fix-loop-protocol.d.ts +18 -0
- package/dist/skill/fix-loop-protocol.d.ts.map +1 -0
- package/dist/skill/fix-loop-protocol.js +38 -0
- package/dist/skill/fix-loop-protocol.js.map +1 -0
- package/dist/skill/gates.d.ts +2 -0
- package/dist/skill/gates.d.ts.map +1 -0
- package/dist/skill/gates.js +20 -0
- package/dist/skill/gates.js.map +1 -0
- package/dist/skill/install.d.ts +25 -0
- package/dist/skill/install.d.ts.map +1 -0
- package/dist/skill/install.js +49 -0
- package/dist/skill/install.js.map +1 -0
- package/dist/skill/render.d.ts +15 -0
- package/dist/skill/render.d.ts.map +1 -0
- package/dist/skill/render.js +35 -0
- package/dist/skill/render.js.map +1 -0
- package/dist/skill/rule-kinds.d.ts +12 -0
- package/dist/skill/rule-kinds.d.ts.map +1 -0
- package/dist/skill/rule-kinds.js +47 -0
- package/dist/skill/rule-kinds.js.map +1 -0
- package/dist/skill/static-sections.d.ts +5 -0
- package/dist/skill/static-sections.d.ts.map +1 -0
- package/dist/skill/static-sections.js +74 -0
- package/dist/skill/static-sections.js.map +1 -0
- package/dist/skill/version-stamp.d.ts +22 -0
- package/dist/skill/version-stamp.d.ts.map +1 -0
- package/dist/skill/version-stamp.js +29 -0
- package/dist/skill/version-stamp.js.map +1 -0
- package/dist/telemetry/check-event.d.ts +7 -0
- package/dist/telemetry/check-event.d.ts.map +1 -0
- package/dist/telemetry/check-event.js +29 -0
- package/dist/telemetry/check-event.js.map +1 -0
- package/dist/telemetry/index.d.ts +8 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +8 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/process-context.d.ts +9 -0
- package/dist/telemetry/process-context.d.ts.map +1 -0
- package/dist/telemetry/process-context.js +10 -0
- package/dist/telemetry/process-context.js.map +1 -0
- package/dist/telemetry/recorder.d.ts +43 -0
- package/dist/telemetry/recorder.d.ts.map +1 -0
- package/dist/telemetry/recorder.js +61 -0
- package/dist/telemetry/recorder.js.map +1 -0
- package/dist/telemetry/resolve.d.ts +19 -0
- package/dist/telemetry/resolve.d.ts.map +1 -0
- package/dist/telemetry/resolve.js +18 -0
- package/dist/telemetry/resolve.js.map +1 -0
- package/dist/telemetry/ruleset-hash.d.ts +10 -0
- package/dist/telemetry/ruleset-hash.d.ts.map +1 -0
- package/dist/telemetry/ruleset-hash.js +12 -0
- package/dist/telemetry/ruleset-hash.js.map +1 -0
- package/dist/telemetry/session.d.ts +6 -0
- package/dist/telemetry/session.d.ts.map +1 -0
- package/dist/telemetry/session.js +9 -0
- package/dist/telemetry/session.js.map +1 -0
- package/dist/telemetry/violations.d.ts +10 -0
- package/dist/telemetry/violations.d.ts.map +1 -0
- package/dist/telemetry/violations.js +36 -0
- package/dist/telemetry/violations.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const FIX_LOOP_PROTOCOL = [
|
|
2
|
+
{
|
|
3
|
+
summary: 'check → fix → re-check until green.',
|
|
4
|
+
detail: 'Run `align check` / `align_check` after every structural change. Fix what it reports, then re-check — ' +
|
|
5
|
+
'never assume a fix worked without a fresh verdict. Every check is a full fresh scan (ADR 005): there is ' +
|
|
6
|
+
'no stale cache to distrust, so trust every verdict as current.',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
summary: 'RED IS BLOCKING.',
|
|
10
|
+
detail: 'A red `align check` / `align_check` means the change is not done. Do not consider a structural change ' +
|
|
11
|
+
'complete, hand control back, or move on to the next task while red.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
summary: 'Never edit align.config.ts or .align/** to force green.',
|
|
15
|
+
detail: 'Removing, weakening, or suppressing a rule in align.config.ts, or hand-editing anything under .align/ ' +
|
|
16
|
+
'(baseline.json, generated-rules.json, rules.lock.json, cache), is not a fix — it hides the finding ' +
|
|
17
|
+
'instead of resolving it. Fix the code the rule is pointing at.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
summary: 'Baseline acceptance is a HUMAN decision.',
|
|
21
|
+
detail: '`align baseline accept` / `align_baseline_accept` (gated off by default, ADR 006) tolerates a violation ' +
|
|
22
|
+
'as existing debt — it does not fix it. An agent under pressure to reach green must not self-serve this; ' +
|
|
23
|
+
'propose it to the human instead of calling it unprompted.',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
summary: 'Explain on demand, not by default.',
|
|
27
|
+
detail: 'Use `align explain <ruleId>` / `align_explain_rule` to understand WHY a rule fired — its kind, ' +
|
|
28
|
+
'`.because()` rationale, and constrained components (plus a Mermaid diagram for cycle/dependency ' +
|
|
29
|
+
'violations) — before proposing a fix, not as a first-pass survey of the whole ruleset.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
summary: 'Payloads are structured-fields-only — render prose yourself if you need it.',
|
|
33
|
+
detail: 'Machine payloads (`align_check`, `align_violations`, `align check --json`) carry structured fields only ' +
|
|
34
|
+
'(file, line, specifier, snippet, fixHint) — no redundant prose `message` field (ADR 007, measured 3.6x ' +
|
|
35
|
+
'token reduction). Passing gates report counts only, never per-item text.',
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
//# sourceMappingURL=fix-loop-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-loop-protocol.js","sourceRoot":"","sources":["../../src/skill/fix-loop-protocol.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD;QACE,OAAO,EAAE,qCAAqC;QAC9C,MAAM,EACJ,wGAAwG;YACxG,0GAA0G;YAC1G,gEAAgE;KACnE;IACD;QACE,OAAO,EAAE,kBAAkB;QAC3B,MAAM,EACJ,wGAAwG;YACxG,qEAAqE;KACxE;IACD;QACE,OAAO,EAAE,yDAAyD;QAClE,MAAM,EACJ,wGAAwG;YACxG,qGAAqG;YACrG,gEAAgE;KACnE;IACD;QACE,OAAO,EAAE,0CAA0C;QACnD,MAAM,EACJ,0GAA0G;YAC1G,0GAA0G;YAC1G,2DAA2D;KAC9D;IACD;QACE,OAAO,EAAE,oCAAoC;QAC7C,MAAM,EACJ,iGAAiG;YACjG,kGAAkG;YAClG,wFAAwF;KAC3F;IACD;QACE,OAAO,EAAE,6EAA6E;QACtF,MAAM,EACJ,0GAA0G;YAC1G,yGAAyG;YACzG,0EAA0E;KAC7E;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/skill/gates.ts"],"names":[],"mappings":"AAaA,wBAAgB,kBAAkB,IAAI,MAAM,CAO3C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate-list reference for `align skill` — reads `@spikedpunch/align-core`'s `GATE_KINDS` (derived from
|
|
3
|
+
* `CATEGORIES`, `types/violation.ts`), the same array `GateResult['gate']` is typed from.
|
|
4
|
+
* Implementation status (which gates actually execute today vs. are reserved for the Stage 5
|
|
5
|
+
* tool-wrapping growth path) is current-state prose, not itself schema-derived — there is no
|
|
6
|
+
* runtime "is this gate wired up" flag in v1 — so it is hand-maintained here and covered by
|
|
7
|
+
* `test/skill-completeness.test.ts` only insofar as every GATE_KINDS entry must be *named*
|
|
8
|
+
* somewhere in the rendered section (not that its status prose is correct).
|
|
9
|
+
*/
|
|
10
|
+
import { GATE_KINDS } from '@spikedpunch/align-core';
|
|
11
|
+
const IMPLEMENTED = new Set(['parse', 'architecture', 'security']);
|
|
12
|
+
export function renderGatesSection() {
|
|
13
|
+
const order = 'Priority order (ADR 007, fixed even though not every gate is wired up yet): architecture > security > types > lint > format.';
|
|
14
|
+
const rows = GATE_KINDS.map((gate) => {
|
|
15
|
+
const status = IMPLEMENTED.has(gate) ? 'implemented (v1)' : 'reserved — Stage 5 tool-wrapping growth path, not yet wired up';
|
|
16
|
+
return `- \`${gate}\` — ${status}`;
|
|
17
|
+
});
|
|
18
|
+
return [order, '', ...rows].join('\n');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/skill/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;AAExF,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,8HAA8H,CAAC;IAC7I,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gEAAgE,CAAC;QAC7H,OAAO,OAAO,IAAI,QAAQ,MAAM,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Writes `.claude/skills/align/SKILL.md` into the target repo (Stage 5, IMPLEMENTATION_PLAN.md).
|
|
4
|
+
*
|
|
5
|
+
* Deliberately simpler than `init/claude-md.ts`'s preserve-content-around-the-block discipline:
|
|
6
|
+
* CLAUDE.md is a human-owned file align appends one section to, so re-running `init` must not
|
|
7
|
+
* clobber the surrounding human content. `.claude/skills/align/SKILL.md`, by contrast, is entirely
|
|
8
|
+
* align-generated (nothing else is expected to live in it, the same way nothing hand-written lives
|
|
9
|
+
* in `.align/generated-rules.json`) — every `--install` run fully regenerates it. The
|
|
10
|
+
* `<!-- align:start/end -->` markers are kept anyway for the same visual/debuggability reason
|
|
11
|
+
* every other generated-block file in this repo uses them, and so a future human addition after
|
|
12
|
+
* the block (unlikely, but not impossible) has a documented boundary to sit outside of.
|
|
13
|
+
*
|
|
14
|
+
* Always installs the full (`'all'`) guide regardless of the CLI invocation's `--topic` filter —
|
|
15
|
+
* `--topic` only scopes the stdout preview for a single call; the installed artifact is meant to
|
|
16
|
+
* be complete since it isn't re-run per interaction.
|
|
17
|
+
*
|
|
18
|
+
* The written block is stamped with the installing binary's `ALIGN_VERSION` (`version-stamp.ts`):
|
|
19
|
+
* a human-visible line plus a machine-parseable marker comment, both near the top of the block.
|
|
20
|
+
* Because the whole file is fully regenerated on every `--install` run (see above), re-running
|
|
21
|
+
* naturally updates the stamp in place — there is no separate "patch the existing stamp" step, and
|
|
22
|
+
* no risk of the block or the stamp duplicating.
|
|
23
|
+
*/
|
|
24
|
+
export declare function writeSkillFile(rootDir: string, program: Command): string;
|
|
25
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/skill/install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CASxE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { ALIGN_VERSION } from '../telemetry/index.js';
|
|
4
|
+
import { renderSkillMarkdown } from './render.js';
|
|
5
|
+
import { renderVersionStamp } from './version-stamp.js';
|
|
6
|
+
const START_MARKER = '<!-- align:start -->';
|
|
7
|
+
const END_MARKER = '<!-- align:end -->';
|
|
8
|
+
const FRONTMATTER = `---
|
|
9
|
+
name: align
|
|
10
|
+
description: >-
|
|
11
|
+
Guidance for authoring align architecture-conformance rules (DSL verbs, rule kinds, doc-authoring
|
|
12
|
+
bullet grammar) and for driving the align check-fix-recheck loop until green. Use when the user
|
|
13
|
+
asks to run align, fix an align/align_check violation, author an align.config.ts rule, understand
|
|
14
|
+
an architecture-conformance or dependency-direction failure, or asks what align rule kinds or DSL
|
|
15
|
+
verbs are available. Trigger phrases: "align check", "align violation", "architecture violation",
|
|
16
|
+
"align rule", "fix align", "align.config.ts", "dependency direction", "import cycle", "align skill".
|
|
17
|
+
---`;
|
|
18
|
+
/**
|
|
19
|
+
* Writes `.claude/skills/align/SKILL.md` into the target repo (Stage 5, IMPLEMENTATION_PLAN.md).
|
|
20
|
+
*
|
|
21
|
+
* Deliberately simpler than `init/claude-md.ts`'s preserve-content-around-the-block discipline:
|
|
22
|
+
* CLAUDE.md is a human-owned file align appends one section to, so re-running `init` must not
|
|
23
|
+
* clobber the surrounding human content. `.claude/skills/align/SKILL.md`, by contrast, is entirely
|
|
24
|
+
* align-generated (nothing else is expected to live in it, the same way nothing hand-written lives
|
|
25
|
+
* in `.align/generated-rules.json`) — every `--install` run fully regenerates it. The
|
|
26
|
+
* `<!-- align:start/end -->` markers are kept anyway for the same visual/debuggability reason
|
|
27
|
+
* every other generated-block file in this repo uses them, and so a future human addition after
|
|
28
|
+
* the block (unlikely, but not impossible) has a documented boundary to sit outside of.
|
|
29
|
+
*
|
|
30
|
+
* Always installs the full (`'all'`) guide regardless of the CLI invocation's `--topic` filter —
|
|
31
|
+
* `--topic` only scopes the stdout preview for a single call; the installed artifact is meant to
|
|
32
|
+
* be complete since it isn't re-run per interaction.
|
|
33
|
+
*
|
|
34
|
+
* The written block is stamped with the installing binary's `ALIGN_VERSION` (`version-stamp.ts`):
|
|
35
|
+
* a human-visible line plus a machine-parseable marker comment, both near the top of the block.
|
|
36
|
+
* Because the whole file is fully regenerated on every `--install` run (see above), re-running
|
|
37
|
+
* naturally updates the stamp in place — there is no separate "patch the existing stamp" step, and
|
|
38
|
+
* no risk of the block or the stamp duplicating.
|
|
39
|
+
*/
|
|
40
|
+
export function writeSkillFile(rootDir, program) {
|
|
41
|
+
const dir = path.join(rootDir, '.claude', 'skills', 'align');
|
|
42
|
+
const filePath = path.join(dir, 'SKILL.md');
|
|
43
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
44
|
+
const body = renderSkillMarkdown('all', program);
|
|
45
|
+
const content = `${FRONTMATTER}\n\n${START_MARKER}\n${renderVersionStamp(ALIGN_VERSION)}\n\n${body}\n${END_MARKER}\n`;
|
|
46
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
47
|
+
return filePath;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/skill/install.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAC5C,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC,MAAM,WAAW,GAAG;;;;;;;;;IAShB,CAAC;AAEL;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,OAAgB;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC5C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,GAAG,WAAW,OAAO,YAAY,KAAK,kBAAkB,CAAC,aAAa,CAAC,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC;IACtH,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composes the full `align skill` markdown from the generated sections (rule kinds, DSL verbs,
|
|
3
|
+
* bullet grammar, gates, CLI inventory — all read live from the installed binary, never
|
|
4
|
+
* hand-written prose lists, Stage 5 IMPLEMENTATION_PLAN.md) and the static prose sections
|
|
5
|
+
* (fix-loop protocol, doc-authoring guidance, baseline consent doctrine, MCP payload/tool
|
|
6
|
+
* reference).
|
|
7
|
+
*/
|
|
8
|
+
import type { Command } from 'commander';
|
|
9
|
+
export type SkillTopic = 'authoring' | 'fixing' | 'all';
|
|
10
|
+
/** `program` is the already-built `commander` `Command` tree (`buildProgram()`, `../program.js`)
|
|
11
|
+
* — passed in rather than imported here to avoid a cycle back to `program.ts`, which registers
|
|
12
|
+
* the `skill` command that reaches this module (`cli-inventory.ts`'s doc comment has the full
|
|
13
|
+
* rationale). */
|
|
14
|
+
export declare function renderSkillMarkdown(topic: SkillTopic, program: Command): string;
|
|
15
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/skill/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;AAMxD;;;iBAGiB;AACjB,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAuC/E"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { renderRuleKindsSection } from './rule-kinds.js';
|
|
2
|
+
import { renderDslVerbsSection } from './dsl-verbs.js';
|
|
3
|
+
import { renderBulletGrammarSection } from './bullet-grammar.js';
|
|
4
|
+
import { renderGatesSection } from './gates.js';
|
|
5
|
+
import { renderCliInventorySection } from './cli-inventory.js';
|
|
6
|
+
import { renderFixLoopProtocolSection, renderDocAuthoringSection, renderBaselineConsentSection, renderMcpPayloadReferenceSection } from './static-sections.js';
|
|
7
|
+
function section(heading, body) {
|
|
8
|
+
return `## ${heading}\n\n${body}`;
|
|
9
|
+
}
|
|
10
|
+
/** `program` is the already-built `commander` `Command` tree (`buildProgram()`, `../program.js`)
|
|
11
|
+
* — passed in rather than imported here to avoid a cycle back to `program.ts`, which registers
|
|
12
|
+
* the `skill` command that reaches this module (`cli-inventory.ts`'s doc comment has the full
|
|
13
|
+
* rationale). */
|
|
14
|
+
export function renderSkillMarkdown(topic, program) {
|
|
15
|
+
const parts = [
|
|
16
|
+
'# align — LLM skill guide',
|
|
17
|
+
'',
|
|
18
|
+
'align is an architecture-conformance verification oracle: a fluent TS DSL compiles to a portable JSON IR,',
|
|
19
|
+
'a language plugin evaluates it against the real dependency graph on every call (always a fresh scan — no',
|
|
20
|
+
'stale cache to distrust), and violations surface through the CLI and an MCP server. This guide is',
|
|
21
|
+
'generated by `align skill` from the installed binary\'s own live registries — the rule-kind list, DSL verb',
|
|
22
|
+
'table, bullet grammar, gate list, and CLI command inventory below can never drift from what this specific',
|
|
23
|
+
'install actually supports.',
|
|
24
|
+
];
|
|
25
|
+
if (topic === 'authoring' || topic === 'all') {
|
|
26
|
+
parts.push('', section('Rule kinds', 'Every rule kind the installed IR schema supports (walked live off `ruleIRSchema`):\n\n' + renderRuleKindsSection()), '', section('DSL verbs', 'The authoring surface (`defineProject`\'s `c.*` factories), introspected off the live builder objects:\n\n' + renderDslVerbsSection()), '', section('Tier-2 bullet grammar (doc authoring)', 'Sentence forms `- **Rule**: ...` bullets in an architecture doc parse into deterministically, zero LLM:\n\n' +
|
|
27
|
+
renderBulletGrammarSection()), '', section('Doc authoring: the precision ladder', renderDocAuthoringSection()));
|
|
28
|
+
}
|
|
29
|
+
if (topic === 'fixing' || topic === 'all') {
|
|
30
|
+
parts.push('', section('Fix-loop protocol', renderFixLoopProtocolSection()), '', section('Baseline consent doctrine', renderBaselineConsentSection()), '', section('MCP payload & tool reference', renderMcpPayloadReferenceSection()));
|
|
31
|
+
}
|
|
32
|
+
parts.push('', section('Gates', renderGatesSection()), '', section('CLI commands', renderCliInventorySection(program)));
|
|
33
|
+
return parts.join('\n');
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/skill/render.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AAI/J,SAAS,OAAO,CAAC,OAAe,EAAE,IAAY;IAC5C,OAAO,MAAM,OAAO,OAAO,IAAI,EAAE,CAAC;AACpC,CAAC;AAED;;;iBAGiB;AACjB,MAAM,UAAU,mBAAmB,CAAC,KAAiB,EAAE,OAAgB;IACrE,MAAM,KAAK,GAAa;QACtB,2BAA2B;QAC3B,EAAE;QACF,2GAA2G;QAC3G,0GAA0G;QAC1G,mGAAmG;QACnG,4GAA4G;QAC5G,2GAA2G;QAC3G,4BAA4B;KAC7B,CAAC;IAEF,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CACR,EAAE,EACF,OAAO,CACL,YAAY,EACZ,wFAAwF,GAAG,sBAAsB,EAAE,CACpH,EACD,EAAE,EACF,OAAO,CAAC,WAAW,EAAE,4GAA4G,GAAG,qBAAqB,EAAE,CAAC,EAC5J,EAAE,EACF,OAAO,CACL,uCAAuC,EACvC,6GAA6G;YAC3G,0BAA0B,EAAE,CAC/B,EACD,EAAE,EACF,OAAO,CAAC,qCAAqC,EAAE,yBAAyB,EAAE,CAAC,CAC5E,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,mBAAmB,EAAE,4BAA4B,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,2BAA2B,EAAE,4BAA4B,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,8BAA8B,EAAE,gCAAgC,EAAE,CAAC,CAAC,CAAC;IAC1O,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,cAAc,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAExH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Walks the live `ruleIRSchema` discriminated union and returns its member `kind` literals in
|
|
2
|
+
* declaration order — the "generated from the live schema/IR registry" source of truth. */
|
|
3
|
+
export declare function getRuleKinds(): readonly string[];
|
|
4
|
+
export interface RuleKindEntry {
|
|
5
|
+
readonly kind: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
}
|
|
8
|
+
/** Fails fast if a live kind has no description — the mechanism that keeps this file from
|
|
9
|
+
* silently drifting behind a new rule kind. */
|
|
10
|
+
export declare function describeRuleKinds(): readonly RuleKindEntry[];
|
|
11
|
+
export declare function renderRuleKindsSection(): string;
|
|
12
|
+
//# sourceMappingURL=rule-kinds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-kinds.d.ts","sourceRoot":"","sources":["../../src/skill/rule-kinds.ts"],"names":[],"mappings":"AAYA;2FAC2F;AAC3F,wBAAgB,YAAY,IAAI,SAAS,MAAM,EAAE,CAGhD;AAeD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;+CAC+C;AAC/C,wBAAgB,iBAAiB,IAAI,SAAS,aAAa,EAAE,CAa5D;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAG/C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule-kind reference (Stage 5, IMPLEMENTATION_PLAN.md "Elevated first items"): the *list* of
|
|
3
|
+
* kinds is walked live off `ruleIRSchema` (`@spikedpunch/align-core`'s zod discriminated union) — never
|
|
4
|
+
* hand-typed — so a new rule kind added to the IR shows up here automatically and a forgotten
|
|
5
|
+
* description fails fast (`describeRuleKinds`), the same discipline `dsl/verb-manifest.ts`
|
|
6
|
+
* applies to the DSL verb surface. `test/skill-completeness.test.ts` additionally asserts every
|
|
7
|
+
* live kind's text actually appears in the rendered skill markdown — the "adding a rule kind
|
|
8
|
+
* without skill coverage must fail CI" requirement.
|
|
9
|
+
*/
|
|
10
|
+
import { ruleIRSchema } from '@spikedpunch/align-core';
|
|
11
|
+
/** Walks the live `ruleIRSchema` discriminated union and returns its member `kind` literals in
|
|
12
|
+
* declaration order — the "generated from the live schema/IR registry" source of truth. */
|
|
13
|
+
export function getRuleKinds() {
|
|
14
|
+
const union = ruleIRSchema;
|
|
15
|
+
return union.options.map((option) => option.shape.kind.value);
|
|
16
|
+
}
|
|
17
|
+
// Hand-written one-liners, keyed by the live kind string above — RULE_KIND_DESCRIPTIONS is
|
|
18
|
+
// prose, but its *coverage* is enforced: `describeRuleKinds` throws for any live kind missing an
|
|
19
|
+
// entry here, and the skill-completeness test throws for any entry whose kind no longer exists.
|
|
20
|
+
const RULE_KIND_DESCRIPTIONS = {
|
|
21
|
+
'arch.no-dependency': 'One component must not import from another. Authored via `arch.layer(x).cannotDependOn(y)` or `arch.component(x).isIsolated()`.',
|
|
22
|
+
'arch.no-cycles': 'No import cycle within a scope (component or the whole repo). Authored via `arch.noCycles(scope?, { includeTypeOnly? })`. Violations carry per-edge chain detail, not just file names.',
|
|
23
|
+
'arch.layers': 'A component may depend only on an explicit allowlist of other components. Authored via `arch.layer(x).canOnlyDependOn(...)`.',
|
|
24
|
+
'arch.metric': 'A component-scoped numeric limit — today only `metric: "loc"` (max lines per file) is promoted; fan-in/fan-out/instability remain reserved pending evidence. Authored via `arch.component(x).maxLinesPerFile(max)`.',
|
|
25
|
+
'custom.host': "An escape hatch referencing a `HostPredicate` your `align.config.ts` registers by name in its `hostRules` export (`Record<string, HostPredicate>`). REGISTRATION IS REQUIRED: `custom.host('foo')` in the ruleset with no `hostRules.foo` predicate hard-errors the gate at check time (it never silently reports green) — register the predicate, fix the name, or remove the rule. Authored via `custom.host(hostRuleName)`.",
|
|
26
|
+
'security.manifest.source-hygiene': 'Flags any dependency specifier resolving to a git/http(s)/file/link source instead of the registry or `workspace:`. Authored via `security.manifest.sourceHygiene()`. Repo-wide — no component scoping.',
|
|
27
|
+
'security.manifest.new-dependency': 'Fingerprints every current runtime/dev dependency at baseline time; a genuinely new dependency added afterward shows red until accepted. Authored via `security.manifest.newDependencyGate()`. Repo-wide — no component scoping.',
|
|
28
|
+
};
|
|
29
|
+
/** Fails fast if a live kind has no description — the mechanism that keeps this file from
|
|
30
|
+
* silently drifting behind a new rule kind. */
|
|
31
|
+
export function describeRuleKinds() {
|
|
32
|
+
const kinds = getRuleKinds();
|
|
33
|
+
return kinds.map((kind) => {
|
|
34
|
+
const description = RULE_KIND_DESCRIPTIONS[kind];
|
|
35
|
+
if (description === undefined) {
|
|
36
|
+
throw new Error(`skill/rule-kinds.ts: live rule kind '${kind}' (from ruleIRSchema) has no entry in ` +
|
|
37
|
+
`RULE_KIND_DESCRIPTIONS. Add one so \`align skill\` cannot silently omit a rule kind the ` +
|
|
38
|
+
`installed binary actually supports.`);
|
|
39
|
+
}
|
|
40
|
+
return { kind, description };
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function renderRuleKindsSection() {
|
|
44
|
+
const lines = describeRuleKinds().map((entry) => `- \`${entry.kind}\` — ${entry.description}`);
|
|
45
|
+
return lines.join('\n');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=rule-kinds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-kinds.js","sourceRoot":"","sources":["../../src/skill/rule-kinds.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD;2FAC2F;AAC3F,MAAM,UAAU,YAAY;IAC1B,MAAM,KAAK,GAAG,YAA8F,CAAC;IAC7G,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,2FAA2F;AAC3F,iGAAiG;AACjG,gGAAgG;AAChG,MAAM,sBAAsB,GAA2B;IACrD,oBAAoB,EAAE,iIAAiI;IACvJ,gBAAgB,EAAE,wLAAwL;IAC1M,aAAa,EAAE,8HAA8H;IAC7I,aAAa,EAAE,qNAAqN;IACpO,aAAa,EAAE,gaAAga;IAC/a,kCAAkC,EAAE,yMAAyM;IAC7O,kCAAkC,EAAE,kOAAkO;CACvQ,CAAC;AAOF;+CAC+C;AAC/C,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,WAAW,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,wCAAwC;gBAClF,0FAA0F;gBAC1F,qCAAqC,CACxC,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function renderFixLoopProtocolSection(): string;
|
|
2
|
+
export declare function renderDocAuthoringSection(): string;
|
|
3
|
+
export declare function renderBaselineConsentSection(): string;
|
|
4
|
+
export declare function renderMcpPayloadReferenceSection(): string;
|
|
5
|
+
//# sourceMappingURL=static-sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-sections.d.ts","sourceRoot":"","sources":["../../src/skill/static-sections.ts"],"names":[],"mappings":"AASA,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAyBlD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAgBrD;AAED,wBAAgB,gCAAgC,IAAI,MAAM,CAkBzD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-written, stable prose sections for `align skill` (Stage 5, IMPLEMENTATION_PLAN.md
|
|
3
|
+
* "Elevated first items" — the plan explicitly separates these from the generated-from-schema
|
|
4
|
+
* sections in rule-kinds.ts/dsl-verbs.ts/bullet-grammar.ts/gates.ts/cli-inventory.ts). These
|
|
5
|
+
* describe protocol and doctrine, not the live rule/verb/gate surface, so there is nothing to
|
|
6
|
+
* introspect — they're reviewed like any other doc, not tested for schema completeness.
|
|
7
|
+
*/
|
|
8
|
+
import { FIX_LOOP_PROTOCOL } from './fix-loop-protocol.js';
|
|
9
|
+
export function renderFixLoopProtocolSection() {
|
|
10
|
+
return FIX_LOOP_PROTOCOL.map((p) => `- **${p.summary}** ${p.detail}`).join('\n');
|
|
11
|
+
}
|
|
12
|
+
export function renderDocAuthoringSection() {
|
|
13
|
+
return [
|
|
14
|
+
'A markdown architecture/best-practices doc is a buildable intent source (`align build`, ADR 011) — it',
|
|
15
|
+
"compiles to rules the way `package.json` resolves to a lockfile. `align build` (dry-run by default) and",
|
|
16
|
+
"the MCP `align_propose_rules` tool both compile a doc through the same **precision ladder**, most-trusted",
|
|
17
|
+
'form first — always author at the highest tier your intent allows:',
|
|
18
|
+
'',
|
|
19
|
+
'1. **Fenced ` ```align ` blocks compile verbatim, zero LLM.** Block content is a JSON `RuleFragment` — the',
|
|
20
|
+
" structural fields of one rule kind, minus `id`/`provenance` (both are always assigned by the build",
|
|
21
|
+
' pipeline). Highest trust, most precise, most work to author by hand.',
|
|
22
|
+
'2. **Structured `- **Rule**: ...` bullets parse deterministically** — see the generated bullet-grammar',
|
|
23
|
+
' section above for the exact sentence forms. An LLM only grounds fuzzy component-name selectors against',
|
|
24
|
+
' the components registry; it never invents rule structure.',
|
|
25
|
+
'3. **Free prose goes through two-pass clarification** (`align_propose_rules`, ADR 011): pass 1',
|
|
26
|
+
' (Discovery) — read the doc, output a short list of *concerns*, no IR yet, human confirms or skips each.',
|
|
27
|
+
' Pass 2 (Refinement) — IR is generated only for confirmed concerns, each selector grounded against',
|
|
28
|
+
' component names (never raw paths), with a dry-run impact report before anything is written. This is the',
|
|
29
|
+
' least-trusted, most-scaffolded path — never skip straight to writing rules from prose without the',
|
|
30
|
+
" human confirmation gate in between; that's the overwhelm failure mode this mode exists to prevent.",
|
|
31
|
+
'',
|
|
32
|
+
'Nothing writes without an explicit `--apply` (CLI) or `apply: true` (MCP) — the default is always a',
|
|
33
|
+
'dry-run diff + impact delta ("adds N new violations / masks M baselined"). A rule-level diff is minimized',
|
|
34
|
+
"(IR-identical rules keep their ids verbatim), so a prose typo fix re-proposing a section yields an empty",
|
|
35
|
+
'diff, not id churn.',
|
|
36
|
+
].join('\n');
|
|
37
|
+
}
|
|
38
|
+
export function renderBaselineConsentSection() {
|
|
39
|
+
return [
|
|
40
|
+
'The baseline tolerates existing debt so a new rule (or align\'s first run) on a mature repo does not',
|
|
41
|
+
'demand a wall of red on day one. Consent is explicit, never silent (ADR 006):',
|
|
42
|
+
'',
|
|
43
|
+
'- `align init` seeds the baseline from the first full check. **Interactive**: prints a loud summary and',
|
|
44
|
+
' asks. **Non-interactive/CI**: requires an explicit `--accept-existing` flag — silence is never consent,',
|
|
45
|
+
' and without the flag `align init` exits red.',
|
|
46
|
+
'- `align baseline accept [--rule <ruleId>]` accepts current violations (optionally scoped to one rule) —',
|
|
47
|
+
' a human-invoked CLI command.',
|
|
48
|
+
'- **MCP never self-serves baseline acceptance by default**: `align_baseline_accept` is gated behind',
|
|
49
|
+
' `allowBaselineFromMcp`, default `false`. An agent cannot grant itself amnesty from a rule it is failing.',
|
|
50
|
+
' If a violation looks like it should be baselined as pre-existing debt rather than fixed, say so to the',
|
|
51
|
+
" human and let them run the acceptance — don't call an acceptance tool unprompted under pressure to turn",
|
|
52
|
+
' a red verdict green.',
|
|
53
|
+
].join('\n');
|
|
54
|
+
}
|
|
55
|
+
export function renderMcpPayloadReferenceSection() {
|
|
56
|
+
return [
|
|
57
|
+
'`align mcp` (stdio) exposes:',
|
|
58
|
+
'',
|
|
59
|
+
'- **`align_check`** — fresh full scan, green/red/error verdict + per-gate counts. No arguments.',
|
|
60
|
+
'- **`align_violations`** — current violations in priority order (architecture > security > types > lint >',
|
|
61
|
+
' format), structured fields only, paginated (`cursor`).',
|
|
62
|
+
'- **`align_explain_rule`** — one rule\'s kind, `.because()` rationale, constrained components with example',
|
|
63
|
+
' files, and a Mermaid diagram for cycle/dependency violations. Pull-on-demand only — never inlined into',
|
|
64
|
+
' `align_check`/`align_violations` payloads.',
|
|
65
|
+
'- **`align_propose_rules`** — two-pass doc-to-rules compilation (see the doc-authoring section above).',
|
|
66
|
+
'',
|
|
67
|
+
'Payload discipline applies to every tool above (ADR 007): passing gates are counts, never per-item text;',
|
|
68
|
+
'no `message` prose field duplicating structured fields (`fromFile`/`toFile`/`specifier`/`line`/`snippet`',
|
|
69
|
+
'already exist structurally — render prose yourself if you need it); results are priority-sorted before',
|
|
70
|
+
'pagination/truncation; caps and pagination are mandatory, not optional. A red `align_check` response for a',
|
|
71
|
+
'handful of violations costs roughly 1K tokens, not tens of thousands.',
|
|
72
|
+
].join('\n');
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=static-sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-sections.js","sourceRoot":"","sources":["../../src/skill/static-sections.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,UAAU,4BAA4B;IAC1C,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,uGAAuG;QACvG,yGAAyG;QACzG,2GAA2G;QAC3G,oEAAoE;QACpE,EAAE;QACF,4GAA4G;QAC5G,uGAAuG;QACvG,yEAAyE;QACzE,wGAAwG;QACxG,2GAA2G;QAC3G,8DAA8D;QAC9D,gGAAgG;QAChG,4GAA4G;QAC5G,sGAAsG;QACtG,4GAA4G;QAC5G,sGAAsG;QACtG,uGAAuG;QACvG,EAAE;QACF,qGAAqG;QACrG,2GAA2G;QAC3G,0GAA0G;QAC1G,qBAAqB;KACtB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,sGAAsG;QACtG,+EAA+E;QAC/E,EAAE;QACF,yGAAyG;QACzG,2GAA2G;QAC3G,gDAAgD;QAChD,0GAA0G;QAC1G,gCAAgC;QAChC,qGAAqG;QACrG,4GAA4G;QAC5G,0GAA0G;QAC1G,2GAA2G;QAC3G,wBAAwB;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,gCAAgC;IAC9C,OAAO;QACL,8BAA8B;QAC9B,EAAE;QACF,iGAAiG;QACjG,2GAA2G;QAC3G,0DAA0D;QAC1D,4GAA4G;QAC5G,0GAA0G;QAC1G,8CAA8C;QAC9C,wGAAwG;QACxG,EAAE;QACF,0GAA0G;QAC1G,0GAA0G;QAC1G,wGAAwG;QACxG,4GAA4G;QAC5G,uEAAuE;KACxE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The version stamp embedded in every `align skill --install`-written SKILL.md (`install.ts`): a
|
|
3
|
+
* human-visible line plus a machine-parseable HTML-comment marker carrying the align version that
|
|
4
|
+
* generated the snapshot.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists: `align skill` (no `--install`) generates its guide live from the running
|
|
7
|
+
* binary's own registries on every call, so it can never drift. `--install`, by contrast, writes a
|
|
8
|
+
* point-in-time snapshot — a SKILL.md installed before some feature shipped (e.g. tier-2
|
|
9
|
+
* `.because()` support) silently won't mention it, with nothing telling the human or agent the
|
|
10
|
+
* snapshot is behind. The stamp makes that staleness detectable: `doctor.ts`'s `stale-skill`
|
|
11
|
+
* advisory reads the marker back out of an installed file and compares it against the running
|
|
12
|
+
* binary's `ALIGN_VERSION`. Defined here (not inline in `install.ts` or `doctor.ts`) so the
|
|
13
|
+
* marker's exact format has exactly one source of truth shared between the writer and the reader.
|
|
14
|
+
*/
|
|
15
|
+
/** Rendered into the installed body, near the top of the `<!-- align:start -->` block — never as
|
|
16
|
+
* frontmatter, so it can't collide with the `name`/`description` keys a skill loader requires. */
|
|
17
|
+
export declare function renderVersionStamp(version: string): string;
|
|
18
|
+
/** Extracts the stamped version from an installed SKILL.md's content, or `undefined` if the file
|
|
19
|
+
* predates version stamping (no marker present) — the "missing marker" case `doctor.ts` treats as
|
|
20
|
+
* stale on its own, distinct from a present-but-outdated version. */
|
|
21
|
+
export declare function parseSkillVersionMarker(content: string): string | undefined;
|
|
22
|
+
//# sourceMappingURL=version-stamp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-stamp.d.ts","sourceRoot":"","sources":["../../src/skill/version-stamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;kGACkG;AAClG,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED;;qEAEqE;AACrE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The version stamp embedded in every `align skill --install`-written SKILL.md (`install.ts`): a
|
|
3
|
+
* human-visible line plus a machine-parseable HTML-comment marker carrying the align version that
|
|
4
|
+
* generated the snapshot.
|
|
5
|
+
*
|
|
6
|
+
* Why this exists: `align skill` (no `--install`) generates its guide live from the running
|
|
7
|
+
* binary's own registries on every call, so it can never drift. `--install`, by contrast, writes a
|
|
8
|
+
* point-in-time snapshot — a SKILL.md installed before some feature shipped (e.g. tier-2
|
|
9
|
+
* `.because()` support) silently won't mention it, with nothing telling the human or agent the
|
|
10
|
+
* snapshot is behind. The stamp makes that staleness detectable: `doctor.ts`'s `stale-skill`
|
|
11
|
+
* advisory reads the marker back out of an installed file and compares it against the running
|
|
12
|
+
* binary's `ALIGN_VERSION`. Defined here (not inline in `install.ts` or `doctor.ts`) so the
|
|
13
|
+
* marker's exact format has exactly one source of truth shared between the writer and the reader.
|
|
14
|
+
*/
|
|
15
|
+
const VERSION_MARKER_PREFIX = 'align-skill-version';
|
|
16
|
+
/** Rendered into the installed body, near the top of the `<!-- align:start -->` block — never as
|
|
17
|
+
* frontmatter, so it can't collide with the `name`/`description` keys a skill loader requires. */
|
|
18
|
+
export function renderVersionStamp(version) {
|
|
19
|
+
return (`> Generated by \`align skill\` v${version}. Re-run \`align skill --install\` after upgrading align to refresh this snapshot.\n` +
|
|
20
|
+
`<!-- ${VERSION_MARKER_PREFIX}: ${version} -->`);
|
|
21
|
+
}
|
|
22
|
+
/** Extracts the stamped version from an installed SKILL.md's content, or `undefined` if the file
|
|
23
|
+
* predates version stamping (no marker present) — the "missing marker" case `doctor.ts` treats as
|
|
24
|
+
* stale on its own, distinct from a present-but-outdated version. */
|
|
25
|
+
export function parseSkillVersionMarker(content) {
|
|
26
|
+
const match = new RegExp(`<!--\\s*${VERSION_MARKER_PREFIX}:\\s*(\\S+)\\s*-->`).exec(content);
|
|
27
|
+
return match?.[1];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=version-stamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-stamp.js","sourceRoot":"","sources":["../../src/skill/version-stamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AAEpD;kGACkG;AAClG,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,CACL,mCAAmC,OAAO,sFAAsF;QAChI,QAAQ,qBAAqB,KAAK,OAAO,MAAM,CAChD,CAAC;AACJ,CAAC;AAED;;qEAEqE;AACrE,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,qBAAqB,oBAAoB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7F,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CheckEvent, CheckRun, CheckScope } from '@spikedpunch/align-core';
|
|
2
|
+
/** Maps a `CheckRun` (the same value `align check` already prints/emits as `--json`) to the
|
|
3
|
+
* `check` telemetry event — real latency DISTRIBUTION across many invocations, not one cold
|
|
4
|
+
* number (IMPLEMENTATION_PLAN.md's telemetry spec). `scope` is always `'all'` in v1 (ADR 005:
|
|
5
|
+
* `align check` only ever does a full fresh scan) — see `CheckScope`'s doc comment. */
|
|
6
|
+
export declare function buildCheckEvent(run: CheckRun, wallMs: number, scope?: CheckScope): CheckEvent;
|
|
7
|
+
//# sourceMappingURL=check-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-event.d.ts","sourceRoot":"","sources":["../../src/telemetry/check-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAe,MAAM,yBAAyB,CAAC;AAQ5G;;;uFAGuF;AACvF,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,UAAkB,GAAG,UAAU,CAiBpG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function countAdvisoriesByKind(advisories) {
|
|
2
|
+
const counts = new Map();
|
|
3
|
+
for (const a of advisories)
|
|
4
|
+
counts.set(a.kind, (counts.get(a.kind) ?? 0) + 1);
|
|
5
|
+
return [...counts.entries()].map(([kind, count]) => ({ kind, count }));
|
|
6
|
+
}
|
|
7
|
+
/** Maps a `CheckRun` (the same value `align check` already prints/emits as `--json`) to the
|
|
8
|
+
* `check` telemetry event — real latency DISTRIBUTION across many invocations, not one cold
|
|
9
|
+
* number (IMPLEMENTATION_PLAN.md's telemetry spec). `scope` is always `'all'` in v1 (ADR 005:
|
|
10
|
+
* `align check` only ever does a full fresh scan) — see `CheckScope`'s doc comment. */
|
|
11
|
+
export function buildCheckEvent(run, wallMs, scope = 'all') {
|
|
12
|
+
const gates = run.gates.map((g) => ({
|
|
13
|
+
gate: g.gate,
|
|
14
|
+
status: g.status,
|
|
15
|
+
newCount: g.violations.length,
|
|
16
|
+
baselinedCount: g.baselinedCount,
|
|
17
|
+
passCount: g.passCount ?? 0,
|
|
18
|
+
}));
|
|
19
|
+
return {
|
|
20
|
+
kind: 'check',
|
|
21
|
+
verdict: run.verdict,
|
|
22
|
+
gates,
|
|
23
|
+
wallMs,
|
|
24
|
+
scope,
|
|
25
|
+
ungroundedComponentCount: run.ungroundedComponents.length,
|
|
26
|
+
advisoryCounts: countAdvisoriesByKind(run.advisories),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=check-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-event.js","sourceRoot":"","sources":["../../src/telemetry/check-event.ts"],"names":[],"mappings":"AAEA,SAAS,qBAAqB,CAAC,UAAkC;IAC/D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC;AAED;;;uFAGuF;AACvF,MAAM,UAAU,eAAe,CAAC,GAAa,EAAE,MAAc,EAAE,QAAoB,KAAK;IACtF,MAAM,KAAK,GAAkB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM;QAC7B,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC;KAC5B,CAAC,CAAC,CAAC;IACJ,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK;QACL,MAAM;QACN,KAAK;QACL,wBAAwB,EAAE,GAAG,CAAC,oBAAoB,CAAC,MAAM;QACzD,cAAc,EAAE,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC;KACtD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './resolve.js';
|
|
2
|
+
export * from './session.js';
|
|
3
|
+
export * from './process-context.js';
|
|
4
|
+
export * from './recorder.js';
|
|
5
|
+
export * from './ruleset-hash.js';
|
|
6
|
+
export * from './violations.js';
|
|
7
|
+
export * from './check-event.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './resolve.js';
|
|
2
|
+
export * from './session.js';
|
|
3
|
+
export * from './process-context.js';
|
|
4
|
+
export * from './recorder.js';
|
|
5
|
+
export * from './ruleset-hash.js';
|
|
6
|
+
export * from './violations.js';
|
|
7
|
+
export * from './check-event.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/telemetry/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Single source of truth for the CLI's own version — `program.ts`'s `.version(...)` call imports
|
|
2
|
+
* this too, so there is exactly one place to bump on a release, not two literals that can drift. */
|
|
3
|
+
export declare const ALIGN_VERSION = "0.1.0";
|
|
4
|
+
/** Computed once, at module load — ESM caches a module instance per process, so every command
|
|
5
|
+
* within one `align` invocation that imports this sees the identical id (IMPLEMENTATION_PLAN.md:
|
|
6
|
+
* "sessionId injected, CLI generates one per process"). Never regenerated mid-process, never read
|
|
7
|
+
* from anywhere network-facing (`node:crypto`'s local `randomUUID`, `session.ts`). */
|
|
8
|
+
export declare const TELEMETRY_SESSION_ID: string;
|
|
9
|
+
//# sourceMappingURL=process-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-context.d.ts","sourceRoot":"","sources":["../../src/telemetry/process-context.ts"],"names":[],"mappings":"AAEA;oGACoG;AACpG,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC;;;sFAGsF;AACtF,eAAO,MAAM,oBAAoB,QAAsB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { generateSessionId } from './session.js';
|
|
2
|
+
/** Single source of truth for the CLI's own version — `program.ts`'s `.version(...)` call imports
|
|
3
|
+
* this too, so there is exactly one place to bump on a release, not two literals that can drift. */
|
|
4
|
+
export const ALIGN_VERSION = '0.1.0';
|
|
5
|
+
/** Computed once, at module load — ESM caches a module instance per process, so every command
|
|
6
|
+
* within one `align` invocation that imports this sees the identical id (IMPLEMENTATION_PLAN.md:
|
|
7
|
+
* "sessionId injected, CLI generates one per process"). Never regenerated mid-process, never read
|
|
8
|
+
* from anywhere network-facing (`node:crypto`'s local `randomUUID`, `session.ts`). */
|
|
9
|
+
export const TELEMETRY_SESSION_ID = generateSessionId();
|
|
10
|
+
//# sourceMappingURL=process-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-context.js","sourceRoot":"","sources":["../../src/telemetry/process-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD;oGACoG;AACpG,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC;AAErC;;;sFAGsF;AACtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type TelemetryEvent } from '@spikedpunch/align-core';
|
|
2
|
+
export interface TelemetryRecorderOptions {
|
|
3
|
+
readonly rootDir: string;
|
|
4
|
+
readonly enabled: boolean;
|
|
5
|
+
readonly sessionId: string;
|
|
6
|
+
readonly alignVersion: string;
|
|
7
|
+
readonly command: string;
|
|
8
|
+
/** Injected, never `Date.now()` called ad hoc — every envelope from one recorder shares the
|
|
9
|
+
* same clock function (real deployments: `Date.now`; tests: a fixed/stepped fake). */
|
|
10
|
+
readonly now: () => number;
|
|
11
|
+
/** Test/override hook — mirrors `align check --ir <path>`'s override pattern. Defaults to
|
|
12
|
+
* `.align/telemetry.jsonl` (`align-dir.ts`). */
|
|
13
|
+
readonly jsonlPathOverride?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The ONE wrapper that builds the envelope and writes it (IMPLEMENTATION_PLAN.md's telemetry spec:
|
|
17
|
+
* "prefer ONE wrapper... over scattering emit calls"). Every command that emits telemetry
|
|
18
|
+
* constructs exactly one of these (via `program.ts`'s `buildTelemetryRecorder`) and calls
|
|
19
|
+
* `.record()` with its own domain event — no command touches `appendTelemetryLine` or builds an
|
|
20
|
+
* envelope itself.
|
|
21
|
+
*/
|
|
22
|
+
export declare class TelemetryRecorder {
|
|
23
|
+
private readonly options;
|
|
24
|
+
constructor(options: TelemetryRecorderOptions);
|
|
25
|
+
get enabled(): boolean;
|
|
26
|
+
record(event: TelemetryEvent, opts?: {
|
|
27
|
+
readonly rulesetIrHash?: string;
|
|
28
|
+
}): void;
|
|
29
|
+
}
|
|
30
|
+
/** OFF-by-default (IMPLEMENTATION_PLAN.md): a recorder constructed with `enabled: false` never
|
|
31
|
+
* calls `appendTelemetryLine` — `.record()` is a no-op, so `.align/telemetry.jsonl` is never even
|
|
32
|
+
* created, let alone written to. */
|
|
33
|
+
export declare function createDisabledTelemetryRecorder(rootDir: string, command: string): TelemetryRecorder;
|
|
34
|
+
/**
|
|
35
|
+
* The composition-root factory every command calls (`program.ts` is the "central wiring point" —
|
|
36
|
+
* it resolves the pre-config half of the precedence via CLI flags/`ALIGN_TELEMETRY`, then each
|
|
37
|
+
* command finishes the resolution once it has loaded `align.config.ts`'s own `telemetry` export
|
|
38
|
+
* and calls this). `sessionId`/`alignVersion` always come from the shared process-wide constants
|
|
39
|
+
* (`process-context.ts`) — never re-derived per call — so every event in one `align` invocation,
|
|
40
|
+
* across however many commands ran, shares the same session id.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createTelemetryRecorder(rootDir: string, command: string, preConfig: boolean | undefined, configTelemetry: boolean | undefined, jsonlPathOverride?: string): TelemetryRecorder;
|
|
43
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/telemetry/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAKjH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;0FACsF;IACtF,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B;oDACgD;IAChD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,wBAAwB;IAE9D,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;CAapF;AAED;;oCAEoC;AACpC,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEnG;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,eAAe,EAAE,OAAO,GAAG,SAAS,EACpC,iBAAiB,CAAC,EAAE,MAAM,GACzB,iBAAiB,CAWnB"}
|