@spikedpunch/align-plugin-typescript 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 align contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @spikedpunch/align-plugin-typescript
2
+
3
+ The TypeScript/JavaScript language plugin for
4
+ [align](https://github.com/SpikedPunchVictim/align) — an architecture-conformance verification
5
+ oracle for humans and LLM coding agents.
6
+
7
+ Implements [`@spikedpunch/align-core`](https://www.npmjs.com/package/@spikedpunch/align-core)'s
8
+ `LanguagePlugin`/`Scanner` and `ManifestScanner` interfaces:
9
+
10
+ - a scan-and-discard dependency-graph builder over the TypeScript compiler API,
11
+ - nearest-`tsconfig` resolution,
12
+ - a pnpm-workspace-name resolver with **realpath** classification of inter-package edges (path
13
+ substring matching silently misclassifies workspace-symlinked edges as external), and
14
+ - the `package.json`/`pnpm-lock.yaml` manifest scanner behind align's security gate.
15
+
16
+ Depends on `typescript` and `yaml`. `@spikedpunch/align-core` never imports this package —
17
+ dependency direction is `core ← plugin`, enforced by align's own dogfooded rules.
18
+
19
+ Most users want the `align` CLI — see
20
+ [`@spikedpunch/align-cli`](https://www.npmjs.com/package/@spikedpunch/align-cli). Import this
21
+ package directly only to compose a custom align host.
22
+
23
+ ## License
24
+
25
+ MIT
@@ -0,0 +1,25 @@
1
+ export interface DeadAlias {
2
+ readonly tsconfig: string;
3
+ readonly alias: string;
4
+ readonly target: string;
5
+ }
6
+ /**
7
+ * tsconfig `paths` entries whose target doesn't resolve to anything on disk (spike finding:
8
+ * `@kluster/shared/*` -> a nonexistent directory — trusting tsconfig paths uncritically would
9
+ * have turned it into a phantom component per ADR 003). Walks every tsconfig.json in the repo
10
+ * (not just ones already visited by a check/scan), since a dead alias in an otherwise-unused
11
+ * tsconfig is exactly the kind of drift `align doctor` exists to surface.
12
+ */
13
+ export declare function findDeadAliases(rootDir: string, excludes?: readonly string[]): DeadAlias[];
14
+ export interface OrphanedPackage {
15
+ readonly dir: string;
16
+ readonly name: string;
17
+ }
18
+ /**
19
+ * Packages on disk (a directory with a `package.json`) that no `pnpm-workspace.yaml` glob covers
20
+ * (spike finding: kluster had 13 workspace-orphaned `@fold/*` packages). Returns `[]` when there's
21
+ * no `pnpm-workspace.yaml` at all — the "orphaned" concept only applies to declared pnpm
22
+ * workspaces, not every repo with a package.json.
23
+ */
24
+ export declare function findOrphanedPackages(rootDir: string, excludes?: readonly string[]): OrphanedPackage[];
25
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAqEA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,SAAS,EAAE,CAoC9F;AASD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,eAAe,EAAE,CAwBzG"}
package/dist/doctor.js ADDED
@@ -0,0 +1,149 @@
1
+ /**
2
+ * `align doctor` advisory scans (Stage 2) that need TS-specific filesystem knowledge — tsconfig
3
+ * `paths` parsing and workspace-package inventory — so they live in the TypeScript plugin
4
+ * alongside the scanner/resolver that already own that knowledge, rather than duplicating tsconfig
5
+ * parsing in the CLI. Both functions are read-only surveys: malformed input is skipped, never
6
+ * thrown, matching the scanner's "read-only survey posture" (ADR 003/004).
7
+ */
8
+ import * as fs from 'node:fs';
9
+ import * as path from 'node:path';
10
+ import ts from 'typescript';
11
+ import { loadWorkspacePackages } from './workspace.js';
12
+ const EXCLUDED_DIR_NAMES = new Set([
13
+ 'node_modules',
14
+ 'dist',
15
+ 'build',
16
+ '.build',
17
+ '.history',
18
+ '.git',
19
+ '.next',
20
+ '.turbo',
21
+ '.cache',
22
+ 'coverage',
23
+ 'out',
24
+ ]);
25
+ function toSlash(p) {
26
+ return p.split(path.sep).join('/');
27
+ }
28
+ /** Same exclude vocabulary as the scanner's `excludes` option (literal prefixes and simple
29
+ * `*`/`**` globs) — a repo's own align.config.ts excludes (e.g. read-only vendored trees, fixture
30
+ * directories with intentionally-broken configs) must apply here too, or `align doctor` reports
31
+ * noise the repo owner already told align to ignore. */
32
+ function isExcluded(relPath, excludes) {
33
+ if (relPath === '')
34
+ return false;
35
+ return excludes.some((pattern) => relPath === pattern || relPath.startsWith(`${pattern}/`) || globLikeMatch(pattern, relPath));
36
+ }
37
+ function globLikeMatch(pattern, filePath) {
38
+ if (!pattern.includes('*'))
39
+ return false;
40
+ const escaped = pattern
41
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
42
+ .replace(/\*\*/g, ' ')
43
+ .replace(/\*/g, '[^/]*')
44
+ .replace(/ /g, '.*');
45
+ return new RegExp(`^${escaped}$`).test(filePath);
46
+ }
47
+ function walkDirs(rootDir, excludes, visit) {
48
+ const inner = (absDir) => {
49
+ const relDir = toSlash(path.relative(rootDir, absDir));
50
+ if (isExcluded(relDir, excludes))
51
+ return;
52
+ visit(absDir);
53
+ let entries;
54
+ try {
55
+ entries = fs.readdirSync(absDir, { withFileTypes: true });
56
+ }
57
+ catch {
58
+ return;
59
+ }
60
+ for (const entry of entries) {
61
+ if (entry.isDirectory() && !EXCLUDED_DIR_NAMES.has(entry.name) && !entry.name.startsWith('.')) {
62
+ inner(path.join(absDir, entry.name));
63
+ }
64
+ }
65
+ };
66
+ inner(rootDir);
67
+ }
68
+ /**
69
+ * tsconfig `paths` entries whose target doesn't resolve to anything on disk (spike finding:
70
+ * `@kluster/shared/*` -> a nonexistent directory — trusting tsconfig paths uncritically would
71
+ * have turned it into a phantom component per ADR 003). Walks every tsconfig.json in the repo
72
+ * (not just ones already visited by a check/scan), since a dead alias in an otherwise-unused
73
+ * tsconfig is exactly the kind of drift `align doctor` exists to surface.
74
+ */
75
+ export function findDeadAliases(rootDir, excludes = []) {
76
+ const dead = [];
77
+ walkDirs(rootDir, excludes, (absDir) => {
78
+ const tsconfigPath = path.join(absDir, 'tsconfig.json');
79
+ if (!fs.existsSync(tsconfigPath))
80
+ return;
81
+ const read = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
82
+ if (read.config === undefined)
83
+ return;
84
+ // Same trap as TsconfigResolver: strip include/files before parseJsonConfigFileContent.
85
+ const config = read.config;
86
+ delete config['include'];
87
+ delete config['exclude'];
88
+ config['files'] = [];
89
+ let parsed;
90
+ try {
91
+ parsed = ts.parseJsonConfigFileContent(config, ts.sys, absDir);
92
+ }
93
+ catch {
94
+ return;
95
+ }
96
+ const paths = parsed.options.paths;
97
+ if (paths === undefined)
98
+ return;
99
+ const baseUrl = parsed.options.baseUrl ?? absDir;
100
+ for (const [alias, targets] of Object.entries(paths)) {
101
+ for (const target of targets) {
102
+ if (!targetExists(baseUrl, target)) {
103
+ dead.push({ tsconfig: toSlash(path.relative(rootDir, tsconfigPath)), alias, target });
104
+ }
105
+ }
106
+ }
107
+ });
108
+ return dead;
109
+ }
110
+ function targetExists(baseUrl, target) {
111
+ const withoutGlob = target.endsWith('*') ? target.slice(0, -1) : target;
112
+ const resolved = path.resolve(baseUrl, withoutGlob);
113
+ if (fs.existsSync(resolved))
114
+ return true;
115
+ return ['.ts', '.tsx', '.d.ts', '.js', '.mts', '.cts'].some((ext) => fs.existsSync(`${resolved}${ext}`));
116
+ }
117
+ /**
118
+ * Packages on disk (a directory with a `package.json`) that no `pnpm-workspace.yaml` glob covers
119
+ * (spike finding: kluster had 13 workspace-orphaned `@fold/*` packages). Returns `[]` when there's
120
+ * no `pnpm-workspace.yaml` at all — the "orphaned" concept only applies to declared pnpm
121
+ * workspaces, not every repo with a package.json.
122
+ */
123
+ export function findOrphanedPackages(rootDir, excludes = []) {
124
+ const covered = new Set(loadWorkspacePackages(rootDir).map((p) => p.dir));
125
+ if (!fs.existsSync(path.join(rootDir, 'pnpm-workspace.yaml')))
126
+ return [];
127
+ const orphaned = [];
128
+ walkDirs(rootDir, excludes, (absDir) => {
129
+ if (absDir === rootDir)
130
+ return; // the monorepo root manifest is not itself a workspace member
131
+ const pkgJsonPath = path.join(absDir, 'package.json');
132
+ if (!fs.existsSync(pkgJsonPath))
133
+ return;
134
+ const relDir = `${toSlash(path.relative(rootDir, absDir))}/`;
135
+ if (covered.has(relDir))
136
+ return;
137
+ try {
138
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
139
+ if (typeof pkg.name === 'string' && pkg.name.length > 0) {
140
+ orphaned.push({ dir: relDir, name: pkg.name });
141
+ }
142
+ }
143
+ catch {
144
+ // malformed package.json: skip this one, not the whole scan
145
+ }
146
+ });
147
+ return orphaned;
148
+ }
149
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Condensed symbol table extraction (Stage 4: FixProposal grounding): a pure, best-effort static
3
+ * syntactic pass over an already-parsed `ts.SourceFile` that lists a module's importable symbol
4
+ * names — the "default" sentinel for `export default`, and declared/re-exported names otherwise.
5
+ * Deliberately mirrors `scanFile`'s parse -> extract -> discard philosophy: no type-checking
6
+ * `ts.Program`, no cross-file resolution. `export * from './other'` barrels are the one case that
7
+ * would require resolving and scanning the target module to enumerate; that's out of scope here,
8
+ * so barrels are recognized (not crashed on) and simply contribute no symbols of their own.
9
+ */
10
+ import ts from 'typescript';
11
+ /** Extracts the set of names importable from this module. Only walks top-level statements —
12
+ * import/export declarations are only valid there in a module, so no need for a full recursive
13
+ * AST walk (unlike edge extraction, which must find nested dynamic `import()`/`require()` calls). */
14
+ export declare function extractExportedSymbols(sourceFile: ts.SourceFile): string[];
15
+ //# sourceMappingURL=exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAkB5B;;qGAEqG;AACrG,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,EAAE,CAwD1E"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Condensed symbol table extraction (Stage 4: FixProposal grounding): a pure, best-effort static
3
+ * syntactic pass over an already-parsed `ts.SourceFile` that lists a module's importable symbol
4
+ * names — the "default" sentinel for `export default`, and declared/re-exported names otherwise.
5
+ * Deliberately mirrors `scanFile`'s parse -> extract -> discard philosophy: no type-checking
6
+ * `ts.Program`, no cross-file resolution. `export * from './other'` barrels are the one case that
7
+ * would require resolving and scanning the target module to enumerate; that's out of scope here,
8
+ * so barrels are recognized (not crashed on) and simply contribute no symbols of their own.
9
+ */
10
+ import ts from 'typescript';
11
+ function hasModifier(node, kind) {
12
+ if (!ts.canHaveModifiers(node))
13
+ return false;
14
+ return ts.getModifiers(node)?.some((m) => m.kind === kind) ?? false;
15
+ }
16
+ /** Flattens a (possibly destructured) binding name into the identifiers it introduces, e.g.
17
+ * `export const { a, b: c } = obj;` yields `['a', 'c']`. */
18
+ function collectBindingNames(name) {
19
+ if (ts.isIdentifier(name))
20
+ return [name.text];
21
+ const names = [];
22
+ for (const element of name.elements) {
23
+ if (ts.isBindingElement(element))
24
+ names.push(...collectBindingNames(element.name));
25
+ }
26
+ return names;
27
+ }
28
+ /** Extracts the set of names importable from this module. Only walks top-level statements —
29
+ * import/export declarations are only valid there in a module, so no need for a full recursive
30
+ * AST walk (unlike edge extraction, which must find nested dynamic `import()`/`require()` calls). */
31
+ export function extractExportedSymbols(sourceFile) {
32
+ const symbols = new Set();
33
+ for (const statement of sourceFile.statements) {
34
+ if (ts.isExportAssignment(statement)) {
35
+ // `export default expr;` (isExportEquals: false) contributes the default sentinel.
36
+ // `export = expr;` (isExportEquals: true) is CommonJS-only export-assignment syntax with no
37
+ // ESM-style named/default symbol to ground fixes against — skipped.
38
+ if (!statement.isExportEquals)
39
+ symbols.add('default');
40
+ continue;
41
+ }
42
+ if (ts.isExportDeclaration(statement)) {
43
+ if (statement.exportClause === undefined) {
44
+ // `export * from './other'` — a barrel re-export. Enumerating its contents would require
45
+ // resolving and scanning the target module (cross-file), which this per-file pass
46
+ // deliberately doesn't do (see module doc comment). Not a crash, just no symbols added.
47
+ continue;
48
+ }
49
+ if (ts.isNamedExports(statement.exportClause)) {
50
+ // Covers both `export { foo, bar as baz }` and `export { foo } from './other'` — either
51
+ // way, `.name` is the externally-visible (importer-facing) identifier.
52
+ for (const specifier of statement.exportClause.elements)
53
+ symbols.add(specifier.name.text);
54
+ }
55
+ else if (ts.isNamespaceExport(statement.exportClause)) {
56
+ // `export * as ns from './other'` — unlike a bare `export *`, the namespace binding name
57
+ // itself is statically known without resolving the target.
58
+ symbols.add(statement.exportClause.name.text);
59
+ }
60
+ continue;
61
+ }
62
+ if (!hasModifier(statement, ts.SyntaxKind.ExportKeyword))
63
+ continue;
64
+ if (hasModifier(statement, ts.SyntaxKind.DefaultKeyword)) {
65
+ // `export default function foo() {}` / `export default class Foo {}` — importable only as
66
+ // "default"; the local name `foo`/`Foo` isn't a separate importable symbol.
67
+ symbols.add('default');
68
+ continue;
69
+ }
70
+ if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) {
71
+ if (statement.name !== undefined)
72
+ symbols.add(statement.name.text);
73
+ }
74
+ else if (ts.isInterfaceDeclaration(statement) ||
75
+ ts.isTypeAliasDeclaration(statement) ||
76
+ ts.isEnumDeclaration(statement)) {
77
+ symbols.add(statement.name.text);
78
+ }
79
+ else if (ts.isVariableStatement(statement)) {
80
+ for (const declaration of statement.declarationList.declarations) {
81
+ for (const name of collectBindingNames(declaration.name))
82
+ symbols.add(name);
83
+ }
84
+ }
85
+ }
86
+ return [...symbols];
87
+ }
88
+ //# sourceMappingURL=exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from './exports.js';
2
+ export * from './plugin.js';
3
+ export * from './scanner.js';
4
+ export * from './tsconfig-resolver.js';
5
+ export * from './workspace.js';
6
+ export * from './doctor.js';
7
+ export * from './manifest.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './exports.js';
2
+ export * from './plugin.js';
3
+ export * from './scanner.js';
4
+ export * from './tsconfig-resolver.js';
5
+ export * from './workspace.js';
6
+ export * from './doctor.js';
7
+ export * from './manifest.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type ManifestInventory, type ManifestScanner, type ManifestScanOptions } from '@spikedpunch/align-core';
2
+ /** Scans the manifest domain for one repo: the root `package.json` (always, even though it's
3
+ * never itself a `loadWorkspacePackages` entry — that function only enumerates
4
+ * `pnpm-workspace.yaml` glob members) plus every workspace member's `package.json`, each
5
+ * dependency's specifier resolved through `pnpm-lock.yaml`'s matching `importers:` entry when a
6
+ * lockfile is present (root importer key is `.`; member keys are their repo-relative dir with no
7
+ * trailing slash). */
8
+ export declare function scanManifests(rootDir: string, excludes?: readonly string[]): ManifestInventory;
9
+ /** `@spikedpunch/align-core`'s `ManifestScanner` injection seam, concretely implemented for the pnpm/Node
10
+ * ecosystem — wired in at the CLI composition root exactly like `TypeScriptPlugin`
11
+ * (`packages/cli/src/composition-root.ts`), never imported by `@spikedpunch/align-core` directly. */
12
+ export declare class NodeManifestScanner implements ManifestScanner {
13
+ scan(options: ManifestScanOptions): ManifestInventory;
14
+ }
15
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAYA,OAAO,EAIL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AA6FjC;;;;;sBAKsB;AACtB,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,iBAAiB,CAelG;AAED;;qGAEqG;AACrG,qBAAa,mBAAoB,YAAW,eAAe;IACzD,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,iBAAiB;CAGtD"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Manifest scan domain (ADR 013): the concrete pnpm/Node-ecosystem reader for `security.manifest.*`
3
+ * rules — root + workspace `package.json` files (workspace inventory via `workspace.ts`'s
4
+ * `loadWorkspacePackages`, reused rather than duplicated) plus `pnpm-lock.yaml`'s `importers:`
5
+ * section for lockfile-resolved specifiers (needed so a `catalog:`-managed dependency's real
6
+ * specifier is visible to `security.manifest.source-hygiene` — spike/MANIFEST_PROBE_REPORT.md Rule
7
+ * 1's documented reason for reading the lockfile at all, not just package.json). No network, no
8
+ * `node_modules` required — same read-only, pre-install posture as `workspace.ts` (ADR 004).
9
+ */
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ import { parse as parseYaml } from 'yaml';
13
+ import { toRepoRelativePath, } from '@spikedpunch/align-core';
14
+ import { loadWorkspacePackages } from './workspace.js';
15
+ const DEP_FIELDS = ['dependencies', 'devDependencies', 'optionalDependencies'];
16
+ function readJson(absPath) {
17
+ try {
18
+ return JSON.parse(fs.readFileSync(absPath, 'utf8'));
19
+ }
20
+ catch {
21
+ return undefined; // malformed/unreadable: skip this one file, not the whole scan
22
+ }
23
+ }
24
+ function readLockfile(rootDir) {
25
+ const lockPath = path.join(rootDir, 'pnpm-lock.yaml');
26
+ if (!fs.existsSync(lockPath))
27
+ return undefined;
28
+ try {
29
+ return parseYaml(fs.readFileSync(lockPath, 'utf8'));
30
+ }
31
+ catch {
32
+ return undefined; // malformed lockfile: read-only survey posture, don't crash the scan
33
+ }
34
+ }
35
+ function escapeRegExp(s) {
36
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
37
+ }
38
+ /** Best-effort raw-text line lookup for a dependency key — a deliberately boring heuristic (first
39
+ * `"<name>":` match in the file), not a JSON-position parser; documented v1 limitation, same
40
+ * posture as `workspace.ts`'s `resolveWorkspaceSpecifier` (CODING_BEST_PRACTICES.md §3). Good
41
+ * enough for `Violation.range`/`snippet` — a wrong line within the same file is a minor cosmetic
42
+ * miss, never a wrong fingerprint (fingerprints never use line numbers, ADR 006/013). */
43
+ function findDependencyLine(raw, depName) {
44
+ const re = new RegExp(`^\\s*"${escapeRegExp(depName)}"\\s*:`);
45
+ const lines = raw.split('\n');
46
+ for (let i = 0; i < lines.length; i += 1) {
47
+ if (re.test(lines[i] ?? ''))
48
+ return i + 1;
49
+ }
50
+ return undefined;
51
+ }
52
+ function isExcluded(relDir, excludes) {
53
+ if (relDir === '')
54
+ return false;
55
+ return excludes.some((pattern) => relDir === pattern || relDir.startsWith(`${pattern}/`));
56
+ }
57
+ function buildManifestRecord(rootDir, relDir, lockImporter) {
58
+ const pkgJsonPath = path.join(rootDir, relDir, 'package.json');
59
+ if (!fs.existsSync(pkgJsonPath))
60
+ return undefined;
61
+ let raw;
62
+ try {
63
+ raw = fs.readFileSync(pkgJsonPath, 'utf8');
64
+ }
65
+ catch {
66
+ return undefined;
67
+ }
68
+ const pkg = readJson(pkgJsonPath);
69
+ if (pkg === undefined)
70
+ return undefined;
71
+ const dependencies = [];
72
+ for (const field of DEP_FIELDS) {
73
+ const declared = pkg[field];
74
+ if (declared === undefined)
75
+ continue;
76
+ const lockGroup = lockImporter?.[field];
77
+ for (const [name, rawSpecifier] of Object.entries(declared)) {
78
+ const specifier = lockGroup?.[name]?.specifier ?? rawSpecifier;
79
+ const line = findDependencyLine(raw, name);
80
+ dependencies.push({ name, specifier, field, ...(line === undefined ? {} : { line }) });
81
+ }
82
+ }
83
+ const filePath = relDir === '' ? 'package.json' : `${relDir}/package.json`;
84
+ return { file: toRepoRelativePath(filePath), raw, dependencies };
85
+ }
86
+ /** Scans the manifest domain for one repo: the root `package.json` (always, even though it's
87
+ * never itself a `loadWorkspacePackages` entry — that function only enumerates
88
+ * `pnpm-workspace.yaml` glob members) plus every workspace member's `package.json`, each
89
+ * dependency's specifier resolved through `pnpm-lock.yaml`'s matching `importers:` entry when a
90
+ * lockfile is present (root importer key is `.`; member keys are their repo-relative dir with no
91
+ * trailing slash). */
92
+ export function scanManifests(rootDir, excludes = []) {
93
+ const lock = readLockfile(rootDir);
94
+ const manifests = [];
95
+ const rootRecord = buildManifestRecord(rootDir, '', lock?.importers?.['.']);
96
+ if (rootRecord !== undefined)
97
+ manifests.push(rootRecord);
98
+ for (const pkg of loadWorkspacePackages(rootDir)) {
99
+ const relDir = pkg.dir.endsWith('/') ? pkg.dir.slice(0, -1) : pkg.dir;
100
+ if (isExcluded(relDir, excludes))
101
+ continue;
102
+ const record = buildManifestRecord(rootDir, relDir, lock?.importers?.[relDir]);
103
+ if (record !== undefined)
104
+ manifests.push(record);
105
+ }
106
+ return { manifests, lockfilePresent: lock !== undefined };
107
+ }
108
+ /** `@spikedpunch/align-core`'s `ManifestScanner` injection seam, concretely implemented for the pnpm/Node
109
+ * ecosystem — wired in at the CLI composition root exactly like `TypeScriptPlugin`
110
+ * (`packages/cli/src/composition-root.ts`), never imported by `@spikedpunch/align-core` directly. */
111
+ export class NodeManifestScanner {
112
+ scan(options) {
113
+ return scanManifests(options.rootDir, options.excludes);
114
+ }
115
+ }
116
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { LanguagePlugin } from '@spikedpunch/align-core';
2
+ import { TypeScriptScanner } from './scanner.js';
3
+ export declare class TypeScriptPlugin implements LanguagePlugin {
4
+ readonly id = "typescript";
5
+ readonly fileMatch: string[];
6
+ readonly scanner: TypeScriptScanner;
7
+ }
8
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,qBAAa,gBAAiB,YAAW,cAAc;IACrD,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,QAAQ,CAAC,SAAS,WAAkD;IACpE,QAAQ,CAAC,OAAO,oBAA2B;CAC5C"}
package/dist/plugin.js ADDED
@@ -0,0 +1,7 @@
1
+ import { TypeScriptScanner } from './scanner.js';
2
+ export class TypeScriptPlugin {
3
+ id = 'typescript';
4
+ fileMatch = ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
5
+ scanner = new TypeScriptScanner();
6
+ }
7
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,OAAO,gBAAgB;IAClB,EAAE,GAAG,YAAY,CAAC;IAClB,SAAS,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3D,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;CAC5C"}
@@ -0,0 +1,6 @@
1
+ import { type ComponentName, type DependencyGraph, type ScanInput, type Scanner } from '@spikedpunch/align-core';
2
+ export declare const UNMAPPED_COMPONENT: ComponentName;
3
+ export declare class TypeScriptScanner implements Scanner {
4
+ scan(input: ScanInput): Promise<DependencyGraph>;
5
+ }
6
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAUA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,eAAe,EAOpB,KAAK,SAAS,EACd,KAAK,OAAO,EAEb,MAAM,yBAAyB,CAAC;AAQjC,eAAO,MAAM,kBAAkB,eAAkC,CAAC;AAgElE,qBAAa,iBAAkB,YAAW,OAAO;IACzC,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC;CA4DvD"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type WorkspacePackage } from './workspace.js';
2
+ export type ResolvedTarget = {
3
+ readonly kind: 'internal';
4
+ readonly absolutePath: string;
5
+ } | {
6
+ readonly kind: 'external';
7
+ readonly packageName: string;
8
+ readonly isBuiltin: boolean;
9
+ } | {
10
+ readonly kind: 'unresolved';
11
+ };
12
+ export declare class TsconfigResolver {
13
+ private readonly repoRoot;
14
+ private readonly workspacePackages;
15
+ private readonly tsconfigByDir;
16
+ private readonly optionsByTsconfig;
17
+ private readonly resolutionCache;
18
+ constructor(repoRoot: string, workspacePackages: readonly WorkspacePackage[]);
19
+ resolveSpecifier(specifier: string, containingFile: string): ResolvedTarget;
20
+ private resolveUncached;
21
+ private realpathOf;
22
+ private optionsForDir;
23
+ private parseTsconfig;
24
+ private findNearestTsconfig;
25
+ }
26
+ //# sourceMappingURL=tsconfig-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsconfig-resolver.d.ts","sourceRoot":"","sources":["../src/tsconfig-resolver.ts"],"names":[],"mappings":"AASA,OAAO,EAA6B,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIlF,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAI5D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC;AAEpC,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IANpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyC;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAC3E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;gBAGlD,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,SAAS,gBAAgB,EAAE;IAGjE,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,cAAc;IAe3E,OAAO,CAAC,eAAe;IA8BvB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,mBAAmB;CA2B5B"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsconfig-resolver.js","sourceRoot":"","sources":["../src/tsconfig-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface WorkspacePackage {
2
+ readonly name: string;
3
+ readonly dir: string;
4
+ }
5
+ export declare function loadWorkspacePackages(rootDir: string): WorkspacePackage[];
6
+ /** Given a bare import specifier and the workspace inventory, finds the owning package and its
7
+ * source-entry file (package-entry -> source mapping, ADR 004). Tries common TS monorepo entry
8
+ * conventions rather than a full package.json `exports` map resolver — a deliberately boring
9
+ * heuristic (CODING_BEST_PRACTICES.md §3), documented as a v1 limitation. */
10
+ export declare function resolveWorkspaceSpecifier(specifier: string, packages: readonly WorkspacePackage[], rootDir: string): string | undefined;
11
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAgCzE;AAgED;;;6EAG6E;AAC7E,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CA6BpB"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * pnpm-workspace.yaml package inventory (ADR 004): resolves workspace package names to their
3
+ * source directories without requiring `node_modules` to exist — the mechanism that makes
4
+ * `pnpm install` a non-prerequisite for seeing a repo's architecture. Doubles as the
5
+ * package-entry -> source mapping (cross-package imports would otherwise resolve to
6
+ * `dist/**\/*.d.ts`, which are not scanned nodes).
7
+ */
8
+ import * as fs from 'node:fs';
9
+ import * as path from 'node:path';
10
+ import { parse as parseYaml } from 'yaml';
11
+ export function loadWorkspacePackages(rootDir) {
12
+ const wsPath = path.join(rootDir, 'pnpm-workspace.yaml');
13
+ if (!fs.existsSync(wsPath))
14
+ return [];
15
+ let patterns;
16
+ try {
17
+ const doc = parseYaml(fs.readFileSync(wsPath, 'utf8'));
18
+ patterns = Array.isArray(doc?.packages) ? doc.packages.filter((p) => typeof p === 'string') : [];
19
+ }
20
+ catch {
21
+ return []; // malformed workspace file: read-only survey posture, don't crash the scan
22
+ }
23
+ const dirs = new Set();
24
+ for (const pattern of patterns) {
25
+ for (const dir of expandPattern(rootDir, pattern))
26
+ dirs.add(dir);
27
+ }
28
+ const packages = [];
29
+ for (const abs of dirs) {
30
+ const pkgJsonPath = path.join(abs, 'package.json');
31
+ if (!fs.existsSync(pkgJsonPath))
32
+ continue;
33
+ try {
34
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
35
+ if (typeof pkg.name === 'string' && pkg.name.length > 0) {
36
+ const rel = path.relative(rootDir, abs).split(path.sep).join('/');
37
+ packages.push({ name: pkg.name, dir: rel.endsWith('/') ? rel : `${rel}/` });
38
+ }
39
+ }
40
+ catch {
41
+ // malformed package.json: skip this one package, not the whole scan
42
+ }
43
+ }
44
+ return packages;
45
+ }
46
+ /** Expands one pnpm-workspace.yaml glob pattern to absolute directories that contain a
47
+ * package.json. Supports the pattern vocabulary pnpm-workspace.yaml actually uses: literal
48
+ * segments, a single trailing/interior `*` (one directory level), and a trailing `**` (recursive
49
+ * — any package.json anywhere under the prefix). */
50
+ function expandPattern(rootDir, pattern) {
51
+ const normalized = pattern.split('\\').join('/');
52
+ if (normalized.endsWith('/**') || normalized === '**') {
53
+ const prefix = normalized === '**' ? '' : normalized.slice(0, -'/**'.length);
54
+ const base = path.join(rootDir, prefix);
55
+ return collectPackageDirsRecursive(base);
56
+ }
57
+ const segments = normalized.split('/').filter((s) => s.length > 0);
58
+ let currentDirs = [rootDir];
59
+ for (const segment of segments) {
60
+ const next = [];
61
+ for (const dir of currentDirs) {
62
+ if (segment === '*') {
63
+ for (const entry of safeReaddir(dir)) {
64
+ if (entry.isDirectory())
65
+ next.push(path.join(dir, entry.name));
66
+ }
67
+ }
68
+ else {
69
+ const candidate = path.join(dir, segment);
70
+ if (isDirectory(candidate))
71
+ next.push(candidate);
72
+ }
73
+ }
74
+ currentDirs = next;
75
+ }
76
+ return currentDirs;
77
+ }
78
+ function collectPackageDirsRecursive(base) {
79
+ const results = [];
80
+ const visit = (dir) => {
81
+ if (!isDirectory(dir))
82
+ return;
83
+ if (fs.existsSync(path.join(dir, 'package.json')))
84
+ results.push(dir);
85
+ for (const entry of safeReaddir(dir)) {
86
+ if (entry.isDirectory() && entry.name !== 'node_modules' && !entry.name.startsWith('.')) {
87
+ visit(path.join(dir, entry.name));
88
+ }
89
+ }
90
+ };
91
+ visit(base);
92
+ return results;
93
+ }
94
+ function safeReaddir(dir) {
95
+ try {
96
+ return fs.readdirSync(dir, { withFileTypes: true });
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ }
102
+ function isDirectory(p) {
103
+ try {
104
+ return fs.statSync(p).isDirectory();
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ /** Given a bare import specifier and the workspace inventory, finds the owning package and its
111
+ * source-entry file (package-entry -> source mapping, ADR 004). Tries common TS monorepo entry
112
+ * conventions rather than a full package.json `exports` map resolver — a deliberately boring
113
+ * heuristic (CODING_BEST_PRACTICES.md §3), documented as a v1 limitation. */
114
+ export function resolveWorkspaceSpecifier(specifier, packages, rootDir) {
115
+ const match = packages.find((p) => specifier === p.name || specifier.startsWith(`${p.name}/`));
116
+ if (match === undefined)
117
+ return undefined;
118
+ const subpath = specifier === match.name ? '' : specifier.slice(match.name.length + 1);
119
+ const pkgAbsDir = path.join(rootDir, match.dir);
120
+ const candidates = subpath === ''
121
+ ? [
122
+ path.join(pkgAbsDir, 'src', 'index.ts'),
123
+ path.join(pkgAbsDir, 'src', 'index.tsx'),
124
+ path.join(pkgAbsDir, 'index.ts'),
125
+ path.join(pkgAbsDir, 'index.tsx'),
126
+ path.join(pkgAbsDir, 'src', 'index.js'),
127
+ path.join(pkgAbsDir, 'index.js'),
128
+ ]
129
+ : [
130
+ `${path.join(pkgAbsDir, subpath)}.ts`,
131
+ `${path.join(pkgAbsDir, subpath)}.tsx`,
132
+ path.join(pkgAbsDir, subpath, 'index.ts'),
133
+ `${path.join(pkgAbsDir, 'src', subpath)}.ts`,
134
+ path.join(pkgAbsDir, 'src', subpath, 'index.ts'),
135
+ `${path.join(pkgAbsDir, subpath)}.js`,
136
+ ];
137
+ for (const candidate of candidates) {
138
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile())
139
+ return candidate;
140
+ }
141
+ return undefined;
142
+ }
143
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@spikedpunch/align-plugin-typescript",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript/JavaScript dependency-graph plugin for align — ts-morph-based scanning and language adapters.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/SpikedPunchVictim/align",
9
+ "directory": "packages/plugin-typescript"
10
+ },
11
+ "keywords": [
12
+ "align",
13
+ "architecture",
14
+ "conformance",
15
+ "typescript",
16
+ "javascript",
17
+ "ts-morph",
18
+ "dependency-graph",
19
+ "plugin"
20
+ ],
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "engines": {
35
+ "node": ">=20"
36
+ },
37
+ "dependencies": {
38
+ "typescript": "^5.6.3",
39
+ "yaml": "^2.6.0",
40
+ "@spikedpunch/align-core": "0.1.0"
41
+ },
42
+ "devDependencies": {
43
+ "vitest": "^2.1.4"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc -p tsconfig.json",
47
+ "test": "vitest run",
48
+ "typecheck": "tsc -p tsconfig.json --noEmit"
49
+ }
50
+ }