@mmnto/cli 1.14.10 → 1.14.12
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/dist/commands/compile-export-archive-filter.test.d.ts +2 -0
- package/dist/commands/compile-export-archive-filter.test.d.ts.map +1 -0
- package/dist/commands/compile-export-archive-filter.test.js +119 -0
- package/dist/commands/compile-export-archive-filter.test.js.map +1 -0
- package/dist/commands/compile-prune.test.js +35 -18
- package/dist/commands/compile-prune.test.js.map +1 -1
- package/dist/commands/compile-verbose-trace.test.d.ts +2 -0
- package/dist/commands/compile-verbose-trace.test.d.ts.map +1 -0
- package/dist/commands/compile-verbose-trace.test.js +128 -0
- package/dist/commands/compile-verbose-trace.test.js.map +1 -0
- package/dist/commands/compile.d.ts +33 -8
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +148 -13
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/docs.test.js +1 -0
- package/dist/commands/docs.test.js.map +1 -1
- package/dist/commands/doctor.d.ts +44 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +147 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +342 -2
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/install.d.ts +82 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +440 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/install.test.d.ts +2 -0
- package/dist/commands/install.test.d.ts.map +1 -0
- package/dist/commands/install.test.js +196 -0
- package/dist/commands/install.test.js.map +1 -0
- package/dist/commands/pre-compact-hook.test.d.ts +10 -0
- package/dist/commands/pre-compact-hook.test.d.ts.map +1 -0
- package/dist/commands/pre-compact-hook.test.js +131 -0
- package/dist/commands/pre-compact-hook.test.js.map +1 -0
- package/dist/commands/run-compiled-rules.d.ts.map +1 -1
- package/dist/commands/run-compiled-rules.js +17 -2
- package/dist/commands/run-compiled-rules.js.map +1 -1
- package/dist/commands/run-compiled-rules.test.js +65 -0
- package/dist/commands/run-compiled-rules.test.js.map +1 -1
- package/dist/commands/shield-learn.test.js +1 -0
- package/dist/commands/shield-learn.test.js.map +1 -1
- package/dist/commands/shield.content-hash-parity.test.d.ts +2 -0
- package/dist/commands/shield.content-hash-parity.test.d.ts.map +1 -0
- package/dist/commands/shield.content-hash-parity.test.js +155 -0
- package/dist/commands/shield.content-hash-parity.test.js.map +1 -0
- package/dist/commands/shield.d.ts +8 -1
- package/dist/commands/shield.d.ts.map +1 -1
- package/dist/commands/shield.js +59 -9
- package/dist/commands/shield.js.map +1 -1
- package/dist/commands/sync.d.ts +7 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +39 -3
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/sync.test.js +131 -9
- package/dist/commands/sync.test.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/pilot.test.js +1 -0
- package/dist/utils/pilot.test.js.map +1 -1
- package/dist/utils.test.js +1 -0
- package/dist/utils.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `totem install pack/<name>` — pack install command (mmnto-ai/totem#1491).
|
|
3
|
+
*
|
|
4
|
+
* Executes the ADR-085 pack install flow:
|
|
5
|
+
* 1. Validate the target syntax (`pack/name` or `pack/@scope/name`).
|
|
6
|
+
* 2. Short-circuit if the pack is already in the `extends` array.
|
|
7
|
+
* 3. Fetch the pack via the repo's existing package manager (pm-detection
|
|
8
|
+
* mirrors `totem init`).
|
|
9
|
+
* 4. Validate the pack manifest structure before mutating any repo state
|
|
10
|
+
* outside `node_modules`. This ordering matters: if validation fails
|
|
11
|
+
* we have not yet touched `totem.config.ts` or the local rules file,
|
|
12
|
+
* so the user's repo stays in a clean state.
|
|
13
|
+
* 5. Update the `extends` array in `totem.config.ts`.
|
|
14
|
+
* 6. Merge pack rules into `.totem/compiled-rules.json` via the
|
|
15
|
+
* mmnto-ai/totem#1515 `mergeRules` primitive.
|
|
16
|
+
* 7. Merge `.totemignore` entries. Without `--yes` the command prints a
|
|
17
|
+
* diff preview and skips the merge with a reminder; with `--yes` it
|
|
18
|
+
* appends the missing entries.
|
|
19
|
+
*
|
|
20
|
+
* All errors thread the underlying cause through `TotemConfigError` so the
|
|
21
|
+
* central error handler can present the full chain.
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectPackageManager(fs: {
|
|
24
|
+
existsSync: (p: string) => boolean;
|
|
25
|
+
}, path: {
|
|
26
|
+
join: (...paths: string[]) => string;
|
|
27
|
+
}, cwd: string): 'pnpm' | 'yarn' | 'bun' | 'npm';
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the npm package name from a `pack/<name>` or `pack/@scope/<name>` target.
|
|
30
|
+
* Accepts raw npm names unchanged so callers that have already normalized
|
|
31
|
+
* do not double-strip the prefix.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolvePackName(target: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Gate on the `pack/<name>` or `pack/@scope/<name>` shape. Rejects leading
|
|
36
|
+
* hyphens in the name segment (a flag-injection hardening pair with the
|
|
37
|
+
* `--` delimiter on the install invocation below). Rejects targets longer
|
|
38
|
+
* than 214 chars per the npm package-name spec.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isValidTarget(target: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the actual filesystem subpath declared under a package's
|
|
43
|
+
* `exports['./compiled-rules.json']` entry. Accepts:
|
|
44
|
+
* - `"./compiled-rules.json"` (plain string)
|
|
45
|
+
* - `{ default: "./dist/compiled-rules.json" }` (single-condition object)
|
|
46
|
+
* - `{ import: "./dist/foo.json", require: "./dist/foo.json" }` (first
|
|
47
|
+
* string value wins; packs should not need multiple conditions for
|
|
48
|
+
* a JSON payload but we accept it without choking)
|
|
49
|
+
*
|
|
50
|
+
* Returns null when the export value cannot be resolved to a usable
|
|
51
|
+
* subpath, so the caller can produce a targeted error. Shield finding
|
|
52
|
+
* on PR mmnto-ai/totem#1516: hardcoding `compiled-rules.json` bypassed the exports
|
|
53
|
+
* contract and would mis-read packs that publish to a subdirectory.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveCompiledRulesExport(exportValue: unknown): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* Check whether the pack is already referenced inside the `extends` array.
|
|
58
|
+
* Scoped to the array contents so that a comment or unrelated property
|
|
59
|
+
* containing the same string does not short-circuit the install.
|
|
60
|
+
*
|
|
61
|
+
* Uses `stripComments` to locate the extends array range (so a
|
|
62
|
+
* commented-out `// extends: [...]` line or string-literal content is
|
|
63
|
+
* not mistaken for the active declaration), then searches the ORIGINAL
|
|
64
|
+
* content at those offsets for the pack name — the stripped version
|
|
65
|
+
* has scrubbed string contents and would miss real array entries.
|
|
66
|
+
*/
|
|
67
|
+
export declare function isInExtends(configContent: string, packName: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Build the `.totemignore` diff shown to the user when `--yes` is not
|
|
70
|
+
* provided. Returns only the lines that would be appended.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildTotemignoreDiff(packIgnoreContent: string, localIgnoreContent: string): string[];
|
|
73
|
+
export interface InstallOptions {
|
|
74
|
+
/**
|
|
75
|
+
* Skip the interactive diff preview for the `.totemignore` merge and
|
|
76
|
+
* append missing entries directly. Required in non-interactive contexts
|
|
77
|
+
* (CI) per the mmnto-ai/totem#1491 AC.
|
|
78
|
+
*/
|
|
79
|
+
yes?: boolean;
|
|
80
|
+
}
|
|
81
|
+
export declare function installCommand(target: string, options?: InstallOptions): Promise<void>;
|
|
82
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE;IAAE,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,EAC1C,IAAI,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE,EAC9C,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAQjC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AA4ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAc9E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAY5E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,iBAAiB,EAAE,MAAM,EACzB,kBAAkB,EAAE,MAAM,GACzB,MAAM,EAAE,CAWV;AAID,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAID,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+LhG"}
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `totem install pack/<name>` — pack install command (mmnto-ai/totem#1491).
|
|
3
|
+
*
|
|
4
|
+
* Executes the ADR-085 pack install flow:
|
|
5
|
+
* 1. Validate the target syntax (`pack/name` or `pack/@scope/name`).
|
|
6
|
+
* 2. Short-circuit if the pack is already in the `extends` array.
|
|
7
|
+
* 3. Fetch the pack via the repo's existing package manager (pm-detection
|
|
8
|
+
* mirrors `totem init`).
|
|
9
|
+
* 4. Validate the pack manifest structure before mutating any repo state
|
|
10
|
+
* outside `node_modules`. This ordering matters: if validation fails
|
|
11
|
+
* we have not yet touched `totem.config.ts` or the local rules file,
|
|
12
|
+
* so the user's repo stays in a clean state.
|
|
13
|
+
* 5. Update the `extends` array in `totem.config.ts`.
|
|
14
|
+
* 6. Merge pack rules into `.totem/compiled-rules.json` via the
|
|
15
|
+
* mmnto-ai/totem#1515 `mergeRules` primitive.
|
|
16
|
+
* 7. Merge `.totemignore` entries. Without `--yes` the command prints a
|
|
17
|
+
* diff preview and skips the merge with a reminder; with `--yes` it
|
|
18
|
+
* appends the missing entries.
|
|
19
|
+
*
|
|
20
|
+
* All errors thread the underlying cause through `TotemConfigError` so the
|
|
21
|
+
* central error handler can present the full chain.
|
|
22
|
+
*/
|
|
23
|
+
// ─── Pure helpers (exported for unit tests) ─────────
|
|
24
|
+
export function detectPackageManager(fs, path, cwd) {
|
|
25
|
+
if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml')))
|
|
26
|
+
return 'pnpm';
|
|
27
|
+
if (fs.existsSync(path.join(cwd, 'yarn.lock')))
|
|
28
|
+
return 'yarn';
|
|
29
|
+
// totem-context: bun lockfile names are intentional package-manager probes
|
|
30
|
+
if (fs.existsSync(path.join(cwd, 'bun.lockb')) || fs.existsSync(path.join(cwd, 'bun.lock'))) {
|
|
31
|
+
return 'bun';
|
|
32
|
+
}
|
|
33
|
+
return 'npm';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the npm package name from a `pack/<name>` or `pack/@scope/<name>` target.
|
|
37
|
+
* Accepts raw npm names unchanged so callers that have already normalized
|
|
38
|
+
* do not double-strip the prefix.
|
|
39
|
+
*/
|
|
40
|
+
export function resolvePackName(target) {
|
|
41
|
+
if (target.startsWith('pack/'))
|
|
42
|
+
return target.slice(5);
|
|
43
|
+
return target;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gate on the `pack/<name>` or `pack/@scope/<name>` shape. Rejects leading
|
|
47
|
+
* hyphens in the name segment (a flag-injection hardening pair with the
|
|
48
|
+
* `--` delimiter on the install invocation below). Rejects targets longer
|
|
49
|
+
* than 214 chars per the npm package-name spec.
|
|
50
|
+
*/
|
|
51
|
+
export function isValidTarget(target) {
|
|
52
|
+
if (target.length > 214)
|
|
53
|
+
return false;
|
|
54
|
+
return /^pack\/(@[a-z0-9][a-z0-9-]*\/)?[a-z0-9][a-z0-9-]*$/i.test(target);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Strip line comments, block comments, AND string literal contents from a
|
|
58
|
+
* JS/TS source string. Replaces scrubbed characters with spaces so
|
|
59
|
+
* character offsets are preserved for downstream regex matches.
|
|
60
|
+
*
|
|
61
|
+
* String-literal handling is required (GCA finding on PR mmnto-ai/totem#1516): a rule
|
|
62
|
+
* message or regex pattern in a string literal might contain `//`, `/*`,
|
|
63
|
+
* or the structural sequence `extends: [`. Without tracking string
|
|
64
|
+
* boundaries the matcher would either trip on a commented-out-looking
|
|
65
|
+
* prefix inside a string, or (worse) inject new syntax into the middle
|
|
66
|
+
* of a string when `addToExtends` rewrites by offset.
|
|
67
|
+
*/
|
|
68
|
+
function stripComments(source) {
|
|
69
|
+
let result = '';
|
|
70
|
+
let i = 0;
|
|
71
|
+
while (i < source.length) {
|
|
72
|
+
const ch = source[i];
|
|
73
|
+
const next = source[i + 1];
|
|
74
|
+
// Line comment: replace with spaces through the next newline.
|
|
75
|
+
if (ch === '/' && next === '/') {
|
|
76
|
+
while (i < source.length && source[i] !== '\n') {
|
|
77
|
+
result += ' ';
|
|
78
|
+
i++;
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Block comment: replace with spaces through the closing */.
|
|
83
|
+
if (ch === '/' && next === '*') {
|
|
84
|
+
result += ' ';
|
|
85
|
+
i += 2;
|
|
86
|
+
while (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) {
|
|
87
|
+
result += source[i] === '\n' ? '\n' : ' ';
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
if (i < source.length) {
|
|
91
|
+
result += ' ';
|
|
92
|
+
i += 2;
|
|
93
|
+
}
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// String literal: scrub contents while preserving newlines and the
|
|
97
|
+
// opening/closing quote characters (so the downstream regex cannot
|
|
98
|
+
// mistake them for structural syntax). Single-quote, double-quote,
|
|
99
|
+
// and backtick strings are all tracked. Escape sequences are
|
|
100
|
+
// handled by skipping the character after a backslash.
|
|
101
|
+
if (ch === "'" || ch === '"' || ch === '`') {
|
|
102
|
+
const quote = ch;
|
|
103
|
+
result += ch;
|
|
104
|
+
i++;
|
|
105
|
+
while (i < source.length && source[i] !== quote) {
|
|
106
|
+
if (source[i] === '\\' && i + 1 < source.length) {
|
|
107
|
+
result += ' ';
|
|
108
|
+
i += 2;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
result += source[i] === '\n' ? '\n' : ' ';
|
|
112
|
+
i++;
|
|
113
|
+
}
|
|
114
|
+
if (i < source.length) {
|
|
115
|
+
result += source[i];
|
|
116
|
+
i++;
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
result += ch;
|
|
121
|
+
i++;
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resolve the actual filesystem subpath declared under a package's
|
|
127
|
+
* `exports['./compiled-rules.json']` entry. Accepts:
|
|
128
|
+
* - `"./compiled-rules.json"` (plain string)
|
|
129
|
+
* - `{ default: "./dist/compiled-rules.json" }` (single-condition object)
|
|
130
|
+
* - `{ import: "./dist/foo.json", require: "./dist/foo.json" }` (first
|
|
131
|
+
* string value wins; packs should not need multiple conditions for
|
|
132
|
+
* a JSON payload but we accept it without choking)
|
|
133
|
+
*
|
|
134
|
+
* Returns null when the export value cannot be resolved to a usable
|
|
135
|
+
* subpath, so the caller can produce a targeted error. Shield finding
|
|
136
|
+
* on PR mmnto-ai/totem#1516: hardcoding `compiled-rules.json` bypassed the exports
|
|
137
|
+
* contract and would mis-read packs that publish to a subdirectory.
|
|
138
|
+
*/
|
|
139
|
+
export function resolveCompiledRulesExport(exportValue) {
|
|
140
|
+
if (typeof exportValue === 'string')
|
|
141
|
+
return exportValue;
|
|
142
|
+
// Order matters: the null guard trails the object-type check so short-
|
|
143
|
+
// circuit evaluation protects the property access below. The runtime
|
|
144
|
+
// behavior matches a leading truthy guard (object-type check returns
|
|
145
|
+
// true for null, then the trailing conjunction short-circuits).
|
|
146
|
+
if (typeof exportValue === 'object' && exportValue) {
|
|
147
|
+
const conditions = exportValue;
|
|
148
|
+
if (typeof conditions['default'] === 'string')
|
|
149
|
+
return conditions['default'];
|
|
150
|
+
for (const v of Object.values(conditions)) {
|
|
151
|
+
if (typeof v === 'string')
|
|
152
|
+
return v;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check whether the pack is already referenced inside the `extends` array.
|
|
159
|
+
* Scoped to the array contents so that a comment or unrelated property
|
|
160
|
+
* containing the same string does not short-circuit the install.
|
|
161
|
+
*
|
|
162
|
+
* Uses `stripComments` to locate the extends array range (so a
|
|
163
|
+
* commented-out `// extends: [...]` line or string-literal content is
|
|
164
|
+
* not mistaken for the active declaration), then searches the ORIGINAL
|
|
165
|
+
* content at those offsets for the pack name — the stripped version
|
|
166
|
+
* has scrubbed string contents and would miss real array entries.
|
|
167
|
+
*/
|
|
168
|
+
export function isInExtends(configContent, packName) {
|
|
169
|
+
const stripped = stripComments(configContent);
|
|
170
|
+
const match = stripped.match(/extends\s*:\s*\[([\s\S]*?)\]/);
|
|
171
|
+
if (!match || match.index === undefined)
|
|
172
|
+
return false;
|
|
173
|
+
const bodyStart = match.index + match[0].indexOf('[') + 1;
|
|
174
|
+
const bodyEnd = bodyStart + (match[1] ?? '').length;
|
|
175
|
+
const body = configContent.slice(bodyStart, bodyEnd);
|
|
176
|
+
return (body.includes(`'${packName}'`) ||
|
|
177
|
+
body.includes(`"${packName}"`) ||
|
|
178
|
+
body.includes(`\`${packName}\``));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Build the `.totemignore` diff shown to the user when `--yes` is not
|
|
182
|
+
* provided. Returns only the lines that would be appended.
|
|
183
|
+
*/
|
|
184
|
+
export function buildTotemignoreDiff(packIgnoreContent, localIgnoreContent) {
|
|
185
|
+
const localLines = new Set(localIgnoreContent
|
|
186
|
+
.split('\n')
|
|
187
|
+
.map((l) => l.trim())
|
|
188
|
+
.filter((l) => l.length > 0));
|
|
189
|
+
return packIgnoreContent
|
|
190
|
+
.split('\n')
|
|
191
|
+
.map((l) => l.trim())
|
|
192
|
+
.filter((l) => l.length > 0 && !localLines.has(l));
|
|
193
|
+
}
|
|
194
|
+
// ─── Command ────────────────────────────────────────
|
|
195
|
+
export async function installCommand(target, options = {}) {
|
|
196
|
+
const fs = await import('node:fs');
|
|
197
|
+
const path = await import('node:path');
|
|
198
|
+
const { safeExec, mergeRules, CompiledRulesFileSchema, saveCompiledRulesFile, TotemConfigError } = await import('@mmnto/totem');
|
|
199
|
+
const { log } = await import('../ui.js');
|
|
200
|
+
const { isGlobalConfigPath, resolveConfigPath } = await import('../utils.js');
|
|
201
|
+
const { resolveGitRoot } = await import('../git.js');
|
|
202
|
+
const TAG = 'Install';
|
|
203
|
+
const cwd = process.cwd();
|
|
204
|
+
const gitRoot = resolveGitRoot(cwd) || cwd;
|
|
205
|
+
const totemDir = path.join(gitRoot, '.totem');
|
|
206
|
+
// ── 1. Validate target syntax ─────────────────
|
|
207
|
+
if (!isValidTarget(target)) {
|
|
208
|
+
throw new TotemConfigError(`Invalid target: ${target}. Expected format: pack/<name> or pack/@scope/<name>`, 'Example: totem install pack/agent-security', 'CONFIG_INVALID');
|
|
209
|
+
}
|
|
210
|
+
const packName = resolvePackName(target);
|
|
211
|
+
// Config path is optional for install — the command can still merge
|
|
212
|
+
// rules and the ignore file when no config exists, leaving only an
|
|
213
|
+
// extends-array warning. resolveConfigPath throws CONFIG_MISSING when
|
|
214
|
+
// no config is found; catch that one code and proceed without one.
|
|
215
|
+
// Reject global-config resolution: totem install targets the current
|
|
216
|
+
// project, never the user's personal profile.
|
|
217
|
+
let configPath;
|
|
218
|
+
try {
|
|
219
|
+
const resolved = resolveConfigPath(gitRoot);
|
|
220
|
+
if (isGlobalConfigPath(resolved)) {
|
|
221
|
+
log.warn(TAG, `Skipping ${resolved}: totem install only modifies a project-local config.`);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
configPath = resolved;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
if (!(err instanceof TotemConfigError && err.code === 'CONFIG_MISSING')) {
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const configContent = configPath && fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf-8') : '';
|
|
233
|
+
// ── 2. Short-circuit if already installed ─────
|
|
234
|
+
if (configContent && isInExtends(configContent, packName)) {
|
|
235
|
+
log.dim(TAG, `Pack ${packName} is already in extends; nothing to do.`);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// ── 3. Fetch via package manager ──────────────
|
|
239
|
+
const pm = detectPackageManager(fs, path, gitRoot);
|
|
240
|
+
log.info(TAG, `Fetching ${packName} via ${pm}...`);
|
|
241
|
+
try {
|
|
242
|
+
// The `--` delimiter hardens against flag injection: a pack name
|
|
243
|
+
// starting with `-` would otherwise be parsed as a package-manager
|
|
244
|
+
// flag. `isValidTarget` already rejects leading hyphens; the
|
|
245
|
+
// delimiter is belt-and-suspenders.
|
|
246
|
+
const args = pm === 'npm' ? ['install', '-D', '--', packName] : ['add', '-D', '--', packName];
|
|
247
|
+
safeExec(pm, args, { cwd: gitRoot });
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
throw new TotemConfigError(`Failed to fetch pack ${packName} via ${pm}.`, 'Check the package name and your registry access.', 'CONFIG_INVALID', err);
|
|
251
|
+
}
|
|
252
|
+
// ── 4. Validate pack manifest BEFORE touching repo state ──
|
|
253
|
+
const packDir = path.join(gitRoot, 'node_modules', packName);
|
|
254
|
+
const packPkgPath = path.join(packDir, 'package.json');
|
|
255
|
+
if (!fs.existsSync(packPkgPath)) {
|
|
256
|
+
throw new TotemConfigError(`Pack ${packName} installed but package.json is missing at ${packPkgPath}.`, 'The installed package does not look like a Totem pack.', 'CONFIG_INVALID');
|
|
257
|
+
}
|
|
258
|
+
let packPkg;
|
|
259
|
+
try {
|
|
260
|
+
packPkg = JSON.parse(fs.readFileSync(packPkgPath, 'utf-8'));
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
throw new TotemConfigError(`Pack ${packName} has an unparseable package.json.`, 'The installed package is corrupt or was not written correctly.', 'CONFIG_INVALID', err);
|
|
264
|
+
}
|
|
265
|
+
if (!packPkg.exports || !packPkg.exports['./compiled-rules.json']) {
|
|
266
|
+
throw new TotemConfigError(`Package ${packName} is not a Totem pack (missing exports['./compiled-rules.json']).`, 'Totem packs declare their compiled rules file under the package exports map.', 'CONFIG_INVALID');
|
|
267
|
+
}
|
|
268
|
+
// Resolve the actual file path from the exports map. Packs that ship
|
|
269
|
+
// their build to a subdirectory (e.g. `./dist/compiled-rules.json`)
|
|
270
|
+
// must not be read from `packDir/compiled-rules.json`.
|
|
271
|
+
const exportValue = packPkg.exports['./compiled-rules.json'];
|
|
272
|
+
const exportSubpath = resolveCompiledRulesExport(exportValue);
|
|
273
|
+
if (!exportSubpath) {
|
|
274
|
+
throw new TotemConfigError(`Pack ${packName} exports['./compiled-rules.json'] is not a resolvable subpath.`, 'The export must be a string, or an object whose default/first string value is a path.', 'CONFIG_INVALID');
|
|
275
|
+
}
|
|
276
|
+
const packRulesPath = path.join(packDir, exportSubpath);
|
|
277
|
+
if (!fs.existsSync(packRulesPath)) {
|
|
278
|
+
throw new TotemConfigError(`Pack ${packName} declares a rules export at ${exportSubpath} but the file is missing (${packRulesPath}).`, 'The pack may have shipped an empty or broken build.', 'CONFIG_INVALID');
|
|
279
|
+
}
|
|
280
|
+
let packRulesFile;
|
|
281
|
+
try {
|
|
282
|
+
const raw = JSON.parse(fs.readFileSync(packRulesPath, 'utf-8'));
|
|
283
|
+
packRulesFile = CompiledRulesFileSchema.parse(raw);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
throw new TotemConfigError(`Pack ${packName} has a malformed compiled-rules.json.`, 'The file must match the CompiledRulesFile schema.', 'CONFIG_INVALID', err);
|
|
287
|
+
}
|
|
288
|
+
// ── 5. Update extends in totem.config.ts ──────
|
|
289
|
+
// Failure to update the config is a soft failure: log a warning with
|
|
290
|
+
// manual-edit guidance and continue with the rules/ignore merge.
|
|
291
|
+
// Throwing here would brick the install (Shield finding on PR mmnto-ai/totem#1516):
|
|
292
|
+
// the user adds the pack manually to extends, re-runs totem install,
|
|
293
|
+
// isInExtends short-circuits, and the rules/ignore merge is skipped
|
|
294
|
+
// forever. Proceeding with a warning keeps the install recoverable.
|
|
295
|
+
if (configPath && configContent) {
|
|
296
|
+
const updatedConfig = addToExtends(configContent, packName);
|
|
297
|
+
if (updatedConfig === null) {
|
|
298
|
+
log.warn(TAG, `Could not auto-update extends array in ${configPath}. Add ${JSON.stringify(packName)} to it manually; continuing with rules merge.`);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
fs.writeFileSync(configPath, updatedConfig, 'utf-8');
|
|
302
|
+
log.success(TAG, `Added ${packName} to extends in ${path.basename(configPath)}.`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
log.warn(TAG, `No totem.config.ts found. Add ${JSON.stringify(packName)} to your extends array manually.`);
|
|
307
|
+
}
|
|
308
|
+
// ── 6. Merge rules into .totem/compiled-rules.json ──
|
|
309
|
+
mergeLocalRules(fs, totemDir, path.join(totemDir, 'compiled-rules.json'), packRulesFile, {
|
|
310
|
+
mergeRules,
|
|
311
|
+
CompiledRulesFileSchema,
|
|
312
|
+
saveCompiledRulesFile,
|
|
313
|
+
TotemConfigError,
|
|
314
|
+
log,
|
|
315
|
+
tag: TAG,
|
|
316
|
+
packName,
|
|
317
|
+
});
|
|
318
|
+
// ── 7. Merge .totemignore entries ─────────────
|
|
319
|
+
const packIgnorePath = path.join(packDir, '.totemignore');
|
|
320
|
+
if (fs.existsSync(packIgnorePath)) {
|
|
321
|
+
mergeTotemIgnore(fs, path.join(gitRoot, '.totemignore'), fs.readFileSync(packIgnorePath, 'utf-8'), packName, options.yes === true, log, TAG);
|
|
322
|
+
}
|
|
323
|
+
log.success(TAG, `Installed ${packName}.`);
|
|
324
|
+
}
|
|
325
|
+
// ─── Internal helpers (not exported) ────────────────
|
|
326
|
+
/**
|
|
327
|
+
* Add `packName` to the `extends` array in a totem.config.ts file.
|
|
328
|
+
* Returns the updated content, or null if the config shape was not
|
|
329
|
+
* recognized. Uses replacer functions (never string back-references) so
|
|
330
|
+
* dynamic content cannot trigger `$&` / `$1` interpretation.
|
|
331
|
+
*
|
|
332
|
+
* Search uses `stripComments` so a commented-out `// extends: [...]` is
|
|
333
|
+
* not treated as the active declaration. The edit applies to the same
|
|
334
|
+
* offset in the original content because `stripComments` preserves
|
|
335
|
+
* character positions.
|
|
336
|
+
*/
|
|
337
|
+
function addToExtends(configContent, packName) {
|
|
338
|
+
const stripped = stripComments(configContent);
|
|
339
|
+
const extendsMatch = stripped.match(/extends\s*:\s*\[/);
|
|
340
|
+
if (extendsMatch && extendsMatch.index !== undefined) {
|
|
341
|
+
const start = extendsMatch.index;
|
|
342
|
+
const end = start + extendsMatch[0].length;
|
|
343
|
+
return (configContent.slice(0, start) +
|
|
344
|
+
`extends: [\n ${JSON.stringify(packName)},` +
|
|
345
|
+
configContent.slice(end));
|
|
346
|
+
}
|
|
347
|
+
const exportMatch = stripped.match(/export\s+default\s+\{/);
|
|
348
|
+
if (exportMatch && exportMatch.index !== undefined) {
|
|
349
|
+
const start = exportMatch.index;
|
|
350
|
+
const end = start + exportMatch[0].length;
|
|
351
|
+
return (configContent.slice(0, start) +
|
|
352
|
+
`export default {\n extends: [${JSON.stringify(packName)}],` +
|
|
353
|
+
configContent.slice(end));
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Merge pack rules into the local compiled-rules.json. Parses and validates
|
|
359
|
+
* the local file before mutating anything; on parse failure throws rather
|
|
360
|
+
* than silently overwriting. Mirrors the mmnto-ai/totem#1515 `mergeRules` contract.
|
|
361
|
+
*/
|
|
362
|
+
function mergeLocalRules(fs, totemDir, localRulesPath, packRulesFile, deps) {
|
|
363
|
+
const empty = { version: 1, rules: [], nonCompilable: [] };
|
|
364
|
+
let localRulesFile;
|
|
365
|
+
if (fs.existsSync(localRulesPath)) {
|
|
366
|
+
try {
|
|
367
|
+
const raw = JSON.parse(fs.readFileSync(localRulesPath, 'utf-8'));
|
|
368
|
+
localRulesFile = deps.CompiledRulesFileSchema.parse(raw);
|
|
369
|
+
}
|
|
370
|
+
catch (err) {
|
|
371
|
+
// Refuse to proceed: silently overwriting a broken local rules file
|
|
372
|
+
// would destroy the user's data. Abort so they can recover the file
|
|
373
|
+
// or regenerate it via `totem lesson compile`.
|
|
374
|
+
throw new deps.TotemConfigError(`Local ${localRulesPath} could not be parsed; refusing to merge pack rules.`, 'Fix the file manually or delete it and run `totem lesson compile` to regenerate.', 'CONFIG_INVALID', err);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
localRulesFile = empty;
|
|
379
|
+
if (!fs.existsSync(totemDir)) {
|
|
380
|
+
fs.mkdirSync(totemDir, { recursive: true });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const { rules: mergedRules, blocks } = deps.mergeRules(localRulesFile.rules, packRulesFile.rules);
|
|
384
|
+
// Surface ADR-089 immutable override blocks as warnings so the user
|
|
385
|
+
// knows their local severity/archive changes were ignored and why.
|
|
386
|
+
for (const block of blocks) {
|
|
387
|
+
deps.log.warn(deps.tag, `Immutable rule override blocked: "${block.lessonHeading}" (${block.lessonHash}) — ` +
|
|
388
|
+
`local ${block.attemptedChange} ignored; pack enforcement wins per ADR-089.`);
|
|
389
|
+
}
|
|
390
|
+
// Merge the pack's nonCompilable entries into the local set. These
|
|
391
|
+
// are conceptual/architectural lessons the pack shipped as metadata;
|
|
392
|
+
// dropping them on install would lose their reachability for
|
|
393
|
+
// `search_knowledge` and downstream reporting (GCA finding on mmnto-ai/totem#1516).
|
|
394
|
+
const localNonCompilable = localRulesFile.nonCompilable ?? [];
|
|
395
|
+
const packNonCompilable = packRulesFile.nonCompilable ?? [];
|
|
396
|
+
const seenHashes = new Set(localNonCompilable.map((e) => e.hash));
|
|
397
|
+
const mergedNonCompilable = [...localNonCompilable];
|
|
398
|
+
for (const entry of packNonCompilable) {
|
|
399
|
+
if (!seenHashes.has(entry.hash)) {
|
|
400
|
+
mergedNonCompilable.push(entry);
|
|
401
|
+
seenHashes.add(entry.hash);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const output = {
|
|
405
|
+
...localRulesFile,
|
|
406
|
+
rules: mergedRules,
|
|
407
|
+
nonCompilable: mergedNonCompilable,
|
|
408
|
+
};
|
|
409
|
+
deps.saveCompiledRulesFile(localRulesPath, output);
|
|
410
|
+
deps.log.success(deps.tag, `Merged ${packRulesFile.rules.length} rule(s) from ${deps.packName}; ` +
|
|
411
|
+
`local now has ${mergedRules.length} rule(s).`);
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Merge entries from the pack's `.totemignore` into the repo's own. Without
|
|
415
|
+
* `--yes` the function prints the proposed additions as a diff and skips
|
|
416
|
+
* the append so CI does not silently mutate repo state. With `--yes` the
|
|
417
|
+
* additions are appended with a header comment naming the pack.
|
|
418
|
+
*/
|
|
419
|
+
function mergeTotemIgnore(fs, localIgnorePath, packIgnoreContent, packName, autoApprove, log, tag) {
|
|
420
|
+
const localIgnoreContent = fs.existsSync(localIgnorePath)
|
|
421
|
+
? fs.readFileSync(localIgnorePath, 'utf-8')
|
|
422
|
+
: '';
|
|
423
|
+
const additions = buildTotemignoreDiff(packIgnoreContent, localIgnoreContent);
|
|
424
|
+
if (additions.length === 0) {
|
|
425
|
+
log.dim(tag, `.totemignore merge: no new entries from ${packName}.`);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (!autoApprove) {
|
|
429
|
+
log.info(tag, `.totemignore diff from ${packName} (${additions.length} new entries):`);
|
|
430
|
+
for (const line of additions) {
|
|
431
|
+
log.dim(tag, ` + ${line}`);
|
|
432
|
+
}
|
|
433
|
+
log.info(tag, `Re-run with --yes to apply, or copy the entries into .totemignore manually.`);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const separator = localIgnoreContent && !localIgnoreContent.endsWith('\n') ? '\n' : '';
|
|
437
|
+
fs.appendFileSync(localIgnorePath, `${separator}# Merged from ${packName}\n${additions.join('\n')}\n`);
|
|
438
|
+
log.success(tag, `.totemignore: appended ${additions.length} entries from ${packName}.`);
|
|
439
|
+
}
|
|
440
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.test.d.ts","sourceRoot":"","sources":["../../src/commands/install.test.ts"],"names":[],"mappings":""}
|