@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,61 @@
|
|
|
1
|
+
import { serializeTelemetryEvent, TELEMETRY_SCHEMA_VERSION } from '@spikedpunch/align-core';
|
|
2
|
+
import { appendTelemetryLine } from '../align-dir.js';
|
|
3
|
+
import { resolveTelemetryEnabled } from './resolve.js';
|
|
4
|
+
import { ALIGN_VERSION, TELEMETRY_SESSION_ID } from './process-context.js';
|
|
5
|
+
/**
|
|
6
|
+
* The ONE wrapper that builds the envelope and writes it (IMPLEMENTATION_PLAN.md's telemetry spec:
|
|
7
|
+
* "prefer ONE wrapper... over scattering emit calls"). Every command that emits telemetry
|
|
8
|
+
* constructs exactly one of these (via `program.ts`'s `buildTelemetryRecorder`) and calls
|
|
9
|
+
* `.record()` with its own domain event — no command touches `appendTelemetryLine` or builds an
|
|
10
|
+
* envelope itself.
|
|
11
|
+
*/
|
|
12
|
+
export class TelemetryRecorder {
|
|
13
|
+
options;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
get enabled() {
|
|
18
|
+
return this.options.enabled;
|
|
19
|
+
}
|
|
20
|
+
record(event, opts = {}) {
|
|
21
|
+
if (!this.options.enabled)
|
|
22
|
+
return;
|
|
23
|
+
const envelope = {
|
|
24
|
+
schemaVersion: TELEMETRY_SCHEMA_VERSION,
|
|
25
|
+
sessionId: this.options.sessionId,
|
|
26
|
+
alignVersion: this.options.alignVersion,
|
|
27
|
+
...(opts.rulesetIrHash !== undefined ? { rulesetIrHash: opts.rulesetIrHash } : {}),
|
|
28
|
+
ts: this.options.now(),
|
|
29
|
+
command: this.options.command,
|
|
30
|
+
event,
|
|
31
|
+
};
|
|
32
|
+
appendTelemetryLine(this.options.rootDir, serializeTelemetryEvent(envelope), this.options.jsonlPathOverride);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** OFF-by-default (IMPLEMENTATION_PLAN.md): a recorder constructed with `enabled: false` never
|
|
36
|
+
* calls `appendTelemetryLine` — `.record()` is a no-op, so `.align/telemetry.jsonl` is never even
|
|
37
|
+
* created, let alone written to. */
|
|
38
|
+
export function createDisabledTelemetryRecorder(rootDir, command) {
|
|
39
|
+
return new TelemetryRecorder({ rootDir, enabled: false, sessionId: '', alignVersion: '', command, now: Date.now });
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The composition-root factory every command calls (`program.ts` is the "central wiring point" —
|
|
43
|
+
* it resolves the pre-config half of the precedence via CLI flags/`ALIGN_TELEMETRY`, then each
|
|
44
|
+
* command finishes the resolution once it has loaded `align.config.ts`'s own `telemetry` export
|
|
45
|
+
* and calls this). `sessionId`/`alignVersion` always come from the shared process-wide constants
|
|
46
|
+
* (`process-context.ts`) — never re-derived per call — so every event in one `align` invocation,
|
|
47
|
+
* across however many commands ran, shares the same session id.
|
|
48
|
+
*/
|
|
49
|
+
export function createTelemetryRecorder(rootDir, command, preConfig, configTelemetry, jsonlPathOverride) {
|
|
50
|
+
const enabled = resolveTelemetryEnabled(preConfig, configTelemetry);
|
|
51
|
+
return new TelemetryRecorder({
|
|
52
|
+
rootDir,
|
|
53
|
+
enabled,
|
|
54
|
+
sessionId: TELEMETRY_SESSION_ID,
|
|
55
|
+
alignVersion: ALIGN_VERSION,
|
|
56
|
+
command,
|
|
57
|
+
now: Date.now,
|
|
58
|
+
...(jsonlPathOverride !== undefined ? { jsonlPathOverride } : {}),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/telemetry/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAuB,MAAM,yBAAyB,CAAC;AACjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAgB3E;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,OAAiC;QAAjC,YAAO,GAAP,OAAO,CAA0B;IAAG,CAAC;IAElE,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,KAAqB,EAAE,OAA4C,EAAE;QAC1E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,OAAO;QAClC,MAAM,QAAQ,GAAG;YACf,aAAa,EAAE,wBAAwB;YACvC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;YACvC,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;YACtB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,KAAK;SACN,CAAC;QACF,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,uBAAuB,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/G,CAAC;CACF;AAED;;oCAEoC;AACpC,MAAM,UAAU,+BAA+B,CAAC,OAAe,EAAE,OAAe;IAC9E,OAAO,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AACrH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,OAAe,EACf,SAA8B,EAC9B,eAAoC,EACpC,iBAA0B;IAE1B,MAAM,OAAO,GAAG,uBAAuB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACpE,OAAO,IAAI,iBAAiB,CAAC;QAC3B,OAAO;QACP,OAAO;QACP,SAAS,EAAE,oBAAoB;QAC/B,YAAY,EAAE,aAAa;QAC3B,OAAO;QACP,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ALIGN_TELEMETRY=1` (env) OR `telemetry: true` (align.config.ts) OR `--telemetry` (flag)
|
|
3
|
+
* enables telemetry; `--no-telemetry` overrides ALL of them. OFF by default
|
|
4
|
+
* (IMPLEMENTATION_PLAN.md's telemetry Design Reserve entry).
|
|
5
|
+
*
|
|
6
|
+
* Split into two steps because the flag/env precedence is decidable before `align.config.ts` is
|
|
7
|
+
* ever loaded (and `align check --untrusted` never loads it at all, ADR 014) while the config-file
|
|
8
|
+
* toggle only exists once a command has called `loadConfig`. `resolveTelemetryPreConfig` returns
|
|
9
|
+
* `undefined` exactly when the decision must defer to `config.telemetry`.
|
|
10
|
+
*/
|
|
11
|
+
export interface TelemetryCliFlags {
|
|
12
|
+
/** `--telemetry` / `--no-telemetry`, straight from commander's `opts.telemetry` — always passed
|
|
13
|
+
* explicitly (not `?:`) so a call site's `{ telemetry: opts.telemetry }` never trips
|
|
14
|
+
* `exactOptionalPropertyTypes` just because commander's own type is `boolean | undefined`. */
|
|
15
|
+
readonly telemetry: boolean | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveTelemetryPreConfig(flags: TelemetryCliFlags, env?: NodeJS.ProcessEnv): boolean | undefined;
|
|
18
|
+
export declare function resolveTelemetryEnabled(preConfig: boolean | undefined, configTelemetry: boolean | undefined): boolean;
|
|
19
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/telemetry/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC;;kGAE8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,GAAG,SAAS,CAQ7H;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,EAAE,eAAe,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAGrH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function resolveTelemetryPreConfig(flags, env = process.env) {
|
|
2
|
+
// Commander's negatable-option pairing (`--telemetry` / `--no-telemetry` sharing one `telemetry`
|
|
3
|
+
// property) already collapses "--no-telemetry was passed" down to `flags.telemetry === false` —
|
|
4
|
+
// that's the one case that must win over everything else, checked first.
|
|
5
|
+
if (flags.telemetry === false)
|
|
6
|
+
return false;
|
|
7
|
+
if (flags.telemetry === true)
|
|
8
|
+
return true;
|
|
9
|
+
if (env['ALIGN_TELEMETRY'] === '1')
|
|
10
|
+
return true;
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
export function resolveTelemetryEnabled(preConfig, configTelemetry) {
|
|
14
|
+
if (preConfig !== undefined)
|
|
15
|
+
return preConfig;
|
|
16
|
+
return configTelemetry === true;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/telemetry/resolve.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,yBAAyB,CAAC,KAAwB,EAAE,MAAyB,OAAO,CAAC,GAAG;IACtG,iGAAiG;IACjG,gGAAgG;IAChG,yEAAyE;IACzE,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,GAAG,CAAC,iBAAiB,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAA8B,EAAE,eAAoC;IAC1G,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9C,OAAO,eAAe,KAAK,IAAI,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RulesetIR } from '@spikedpunch/align-core';
|
|
2
|
+
/**
|
|
3
|
+
* `rulesetIrHash` (the envelope's cross-session-comparability refinement) — reuses the exact
|
|
4
|
+
* content-hash function `.align/rules.lock.json`'s divergence detection already computes with
|
|
5
|
+
* (`sha256Hex`, `packages/core/src/build/hash.ts`) rather than inventing a second hashing scheme.
|
|
6
|
+
* `RulesetIR` is always zod-parsed JSON with a fixed field order (ADR 002: no function-valued
|
|
7
|
+
* fields, portable), so `JSON.stringify` is deterministic for a given ruleset content.
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeRulesetIrHash(ruleset: RulesetIR): string;
|
|
10
|
+
//# sourceMappingURL=ruleset-hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleset-hash.d.ts","sourceRoot":"","sources":["../../src/telemetry/ruleset-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpE;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAE/D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { sha256Hex } from '@spikedpunch/align-core';
|
|
2
|
+
/**
|
|
3
|
+
* `rulesetIrHash` (the envelope's cross-session-comparability refinement) — reuses the exact
|
|
4
|
+
* content-hash function `.align/rules.lock.json`'s divergence detection already computes with
|
|
5
|
+
* (`sha256Hex`, `packages/core/src/build/hash.ts`) rather than inventing a second hashing scheme.
|
|
6
|
+
* `RulesetIR` is always zod-parsed JSON with a fixed field order (ADR 002: no function-valued
|
|
7
|
+
* fields, portable), so `JSON.stringify` is deterministic for a given ruleset content.
|
|
8
|
+
*/
|
|
9
|
+
export function computeRulesetIrHash(ruleset) {
|
|
10
|
+
return sha256Hex(JSON.stringify(ruleset));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ruleset-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleset-hash.js","sourceRoot":"","sources":["../../src/telemetry/ruleset-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAkB;IACrD,OAAO,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** One session id per CLI process (IMPLEMENTATION_PLAN.md's cross-session-comparability
|
|
2
|
+
* refinement) — generated once here and threaded through every event the process emits, never
|
|
3
|
+
* regenerated mid-process. `randomUUID` is a local, non-network primitive (Node's `node:crypto`),
|
|
4
|
+
* not a call to any external id service. */
|
|
5
|
+
export declare function generateSessionId(): string;
|
|
6
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/telemetry/session.ts"],"names":[],"mappings":"AAEA;;;4CAG4C;AAC5C,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/** One session id per CLI process (IMPLEMENTATION_PLAN.md's cross-session-comparability
|
|
3
|
+
* refinement) — generated once here and threaded through every event the process emits, never
|
|
4
|
+
* regenerated mid-process. `randomUUID` is a local, non-network primitive (Node's `node:crypto`),
|
|
5
|
+
* not a call to any external id service. */
|
|
6
|
+
export function generateSessionId() {
|
|
7
|
+
return randomUUID();
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/telemetry/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;4CAG4C;AAC5C,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type TelemetryEvent, type Violation } from '@spikedpunch/align-core';
|
|
2
|
+
/**
|
|
3
|
+
* `violation-appeared`/`violation-resolved` (IMPLEMENTATION_PLAN.md's telemetry spec): diffs the
|
|
4
|
+
* current check's non-baselined violation set against `.align/telemetry-state.json` (the previous
|
|
5
|
+
* check's set), then persists the new set for the next invocation. Only called when telemetry is
|
|
6
|
+
* enabled — a disabled run must never touch `telemetry-state.json` (OFF-by-default writes
|
|
7
|
+
* nothing), so gating happens at the call site (`commands/check.ts`), not here.
|
|
8
|
+
*/
|
|
9
|
+
export declare function computeAndPersistViolationTransitions(rootDir: string, violations: readonly Violation[]): readonly TelemetryEvent[];
|
|
10
|
+
//# sourceMappingURL=violations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"violations.d.ts","sourceRoot":"","sources":["../../src/telemetry/violations.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzH;;;;;;GAMG;AACH,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,cAAc,EAAE,CA0BlI"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { diffViolationState, telemetryStateEntryOf } from '@spikedpunch/align-core';
|
|
2
|
+
import { readTelemetryState, writeTelemetryState } from '../align-dir.js';
|
|
3
|
+
/**
|
|
4
|
+
* `violation-appeared`/`violation-resolved` (IMPLEMENTATION_PLAN.md's telemetry spec): diffs the
|
|
5
|
+
* current check's non-baselined violation set against `.align/telemetry-state.json` (the previous
|
|
6
|
+
* check's set), then persists the new set for the next invocation. Only called when telemetry is
|
|
7
|
+
* enabled — a disabled run must never touch `telemetry-state.json` (OFF-by-default writes
|
|
8
|
+
* nothing), so gating happens at the call site (`commands/check.ts`), not here.
|
|
9
|
+
*/
|
|
10
|
+
export function computeAndPersistViolationTransitions(rootDir, violations) {
|
|
11
|
+
const previous = readTelemetryState(rootDir).violations;
|
|
12
|
+
const current = violations.map((v) => telemetryStateEntryOf(v));
|
|
13
|
+
const diff = diffViolationState(previous, current);
|
|
14
|
+
writeTelemetryState(rootDir, { violations: current });
|
|
15
|
+
const events = [];
|
|
16
|
+
for (const e of diff.appeared) {
|
|
17
|
+
events.push({
|
|
18
|
+
kind: 'violation-appeared',
|
|
19
|
+
ruleId: e.ruleId,
|
|
20
|
+
file: e.file,
|
|
21
|
+
violationFingerprint: e.fingerprint,
|
|
22
|
+
...(e.component !== undefined ? { component: e.component } : {}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
for (const e of diff.resolved) {
|
|
26
|
+
events.push({
|
|
27
|
+
kind: 'violation-resolved',
|
|
28
|
+
ruleId: e.ruleId,
|
|
29
|
+
file: e.file,
|
|
30
|
+
violationFingerprint: e.fingerprint,
|
|
31
|
+
...(e.component !== undefined ? { component: e.component } : {}),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return events;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=violations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"violations.js","sourceRoot":"","sources":["../../src/telemetry/violations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAuC,MAAM,yBAAyB,CAAC;AACzH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE1E;;;;;;GAMG;AACH,MAAM,UAAU,qCAAqC,CAAC,OAAe,EAAE,UAAgC;IACrG,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IACxD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,mBAAmB,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,oBAAoB,EAAE,CAAC,CAAC,WAAW;YACnC,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,oBAAoB,EAAE,CAAC,CAAC,WAAW;YACnC,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spikedpunch/align-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "align CLI — an architecture-conformance verification oracle for LLM coding agents, with a built-in MCP server.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/SpikedPunchVictim/align",
|
|
9
|
+
"directory": "packages/cli"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"align",
|
|
13
|
+
"architecture",
|
|
14
|
+
"conformance",
|
|
15
|
+
"cli",
|
|
16
|
+
"mcp",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"dependency-graph",
|
|
19
|
+
"static-analysis"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"bin": {
|
|
23
|
+
"align": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=20"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.9.0",
|
|
42
|
+
"commander": "^12.1.0",
|
|
43
|
+
"zod": "^3.23.8",
|
|
44
|
+
"@spikedpunch/align-plugin-typescript": "0.1.0",
|
|
45
|
+
"@spikedpunch/align-core": "0.1.0",
|
|
46
|
+
"@spikedpunch/align-agent": "0.1.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"typescript": "^5.6.3",
|
|
50
|
+
"vitest": "^2.1.4",
|
|
51
|
+
"@types/node": "^22.9.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.json",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
57
|
+
}
|
|
58
|
+
}
|