@codyswann/lisa 1.9.3 → 1.9.4

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.
Files changed (34) hide show
  1. package/README.md +59 -2
  2. package/all/copy-overwrite/CLAUDE.md +2 -3
  3. package/cdk/copy-overwrite/eslint.slow.config.ts +5 -0
  4. package/cdk/copy-overwrite/knip.json +0 -1
  5. package/cdk/tagged-merge/bin/infrastructure.js +16 -0
  6. package/cdk/tagged-merge/package.json +37 -0
  7. package/dist/core/config.d.ts +1 -1
  8. package/dist/core/config.d.ts.map +1 -1
  9. package/dist/core/config.js +1 -0
  10. package/dist/core/config.js.map +1 -1
  11. package/dist/core/lisa.d.ts.map +1 -1
  12. package/dist/core/lisa.js +2 -1
  13. package/dist/core/lisa.js.map +1 -1
  14. package/dist/strategies/index.d.ts +1 -0
  15. package/dist/strategies/index.d.ts.map +1 -1
  16. package/dist/strategies/index.js +3 -0
  17. package/dist/strategies/index.js.map +1 -1
  18. package/dist/strategies/tagged-merge-types.d.ts +30 -0
  19. package/dist/strategies/tagged-merge-types.d.ts.map +1 -0
  20. package/dist/strategies/tagged-merge-types.js +7 -0
  21. package/dist/strategies/tagged-merge-types.js.map +1 -0
  22. package/dist/strategies/tagged-merge.d.ts +206 -0
  23. package/dist/strategies/tagged-merge.d.ts.map +1 -0
  24. package/dist/strategies/tagged-merge.js +421 -0
  25. package/dist/strategies/tagged-merge.js.map +1 -0
  26. package/expo/copy-overwrite/eslint.slow.config.ts +5 -0
  27. package/expo/copy-overwrite/knip.json +0 -1
  28. package/expo/{merge → tagged-merge}/package.json +28 -28
  29. package/nestjs/{merge → tagged-merge}/package.json +28 -24
  30. package/package.json +1 -8
  31. package/typescript/copy-overwrite/eslint.slow.config.ts +6 -0
  32. package/typescript/copy-overwrite/knip.json +0 -1
  33. package/typescript/{merge → tagged-merge}/package.json +23 -21
  34. package/cdk/merge/package.json +0 -36
@@ -0,0 +1,206 @@
1
+ import type { FileOperationResult } from "../core/config.js";
2
+ import type { ICopyStrategy, StrategyContext } from "./strategy.interface.js";
3
+ /**
4
+ * Implements tagged merge strategy for JSON files with comment-based section control
5
+ * @remarks
6
+ * Supports three tag behaviors:
7
+ * - `//lisa-force-*`: Lisa replaces entire section, project changes ignored (for governance)
8
+ * - `//lisa-defaults-*`: Lisa provides values, project can override (for sensible defaults)
9
+ * - `//lisa-merge-*`: For arrays - combine Lisa's + project's items deduplicated (for shared lists)
10
+ *
11
+ * Tag format: `//lisa-<behavior>-<category>` with matching `//end-lisa-<behavior>-<category>`
12
+ *
13
+ * Order preservation: JSON key ordering is maintained throughout the merge process,
14
+ * ensuring deterministic output and minimal diff noise when configs change.
15
+ */
16
+ export declare class TaggedMergeStrategy implements ICopyStrategy {
17
+ readonly name: "tagged-merge";
18
+ /**
19
+ * Regex pattern for parsing opening tags
20
+ * @remarks Captures behavior (force|defaults|merge) and category name for routing to appropriate merge logic
21
+ */
22
+ private readonly tagPattern;
23
+ /**
24
+ * Apply tagged merge strategy to a JSON file
25
+ * @param sourcePath - Absolute path to Lisa template JSON file with tags
26
+ * @param destPath - Absolute path to project JSON file to merge into
27
+ * @param relativePath - Project-relative path for manifest recording and logging
28
+ * @param context - Strategy context with config, manifest recording, and backup functions
29
+ * @returns Operation result indicating copied, skipped, or merged action
30
+ * @throws JsonMergeError if source or destination JSON cannot be parsed
31
+ * @remarks
32
+ * When destination doesn't exist, copies source directly. When destination exists,
33
+ * performs tagged merge preserving project customizations outside tagged sections.
34
+ */
35
+ apply(sourcePath: string, destPath: string, relativePath: string, context: StrategyContext): Promise<FileOperationResult>;
36
+ /**
37
+ * Merge source and destination JSON using tagged sections
38
+ * @param source - Lisa template JSON containing tag markers and governed content
39
+ * @param dest - Project JSON with potential customizations to preserve
40
+ * @returns Merged JSON with tagged sections applied according to their behavior types
41
+ * @remarks
42
+ * Processing order: 1) Process all tagged sections from source applying their behaviors,
43
+ * 2) Add unprocessed content from destination (preserves project customizations),
44
+ * 3) Add any remaining unprocessed tags from source. This ensures governance while
45
+ * preserving project-specific additions outside tagged regions.
46
+ */
47
+ private mergeWithTags;
48
+ /**
49
+ * Preserve project customizations by adding untagged destination content to result
50
+ * @param result - Result object being built
51
+ * @param dest - Project JSON containing potential customizations
52
+ * @param processed - Keys already processed via tagged sections (to avoid duplicates)
53
+ * @param processedTags - Tag keys already processed (to avoid duplicates)
54
+ * @remarks
55
+ * This is the key step that preserves project freedom: any content outside tagged
56
+ * regions is copied from the project's file unchanged, allowing custom scripts,
57
+ * dependencies, or configs that Lisa doesn't govern.
58
+ */
59
+ private addUnprocessedContent;
60
+ /**
61
+ * Add any remaining tag keys from source that weren't part of complete tag pairs
62
+ * @param result - Result object being built
63
+ * @param source - Lisa template JSON
64
+ * @param processedTags - Tag keys already processed as part of complete sections
65
+ * @param processed - Content keys already processed
66
+ * @remarks
67
+ * Handles edge case of orphaned tags (e.g., opening tag without closing tag)
68
+ * by preserving them in output rather than silently dropping them.
69
+ */
70
+ private addUnprocessedTags;
71
+ /**
72
+ * Process a single tagged section, routing to appropriate behavior handler
73
+ * @param key - Opening tag key (e.g., `//lisa-force-scripts`)
74
+ * @param source - Lisa template JSON
75
+ * @param dest - Project JSON
76
+ * @param sourceTags - Map of all parsed tag sections from source
77
+ * @param result - Result object being built
78
+ * @param processed - Set tracking processed content keys
79
+ * @param processedTags - Set tracking processed tag keys
80
+ * @remarks
81
+ * Routes to applyForceSection, applyDefaultsSection, or applyMergeSection
82
+ * based on the behavior extracted from the tag. All keys within the section
83
+ * (including opening/closing tags) are marked as processed to prevent
84
+ * duplicate handling in subsequent steps.
85
+ */
86
+ private processTaggedSection;
87
+ /**
88
+ * Parse JSON object to extract all tagged sections with their boundaries
89
+ * @param obj - JSON object to parse for tag markers
90
+ * @returns Map of opening tag keys to section info (behavior, category, content keys, close key)
91
+ * @remarks
92
+ * Relies on JSON key ordering being preserved (standard in modern JS engines).
93
+ * Skips sections without matching closing tags to handle malformed input gracefully.
94
+ */
95
+ private parseTaggedSections;
96
+ /**
97
+ * Apply force behavior: Lisa's section replaces project's entirely
98
+ * @param result - Result object being built
99
+ * @param source - Lisa template containing the authoritative values
100
+ * @param section - Section info with content keys to copy
101
+ * @remarks
102
+ * Use force for governance-critical configs that projects must not override,
103
+ * such as CI/CD scripts, required linting commands, or mandatory dev dependencies.
104
+ * Project changes within force-tagged sections are discarded during merge.
105
+ */
106
+ private applyForceSection;
107
+ /**
108
+ * Apply defaults behavior: project's values take precedence if they exist
109
+ * @param result - Result object being built
110
+ * @param source - Lisa template with default values
111
+ * @param dest - Project JSON with potential overrides
112
+ * @param section - Section info from source
113
+ * @param category - Tag category name for looking up destination section
114
+ * @remarks
115
+ * Use defaults for sensible starting values that projects may legitimately need
116
+ * to customize, such as engine versions or optional configurations. If project
117
+ * has the same tagged section, its content is used; otherwise Lisa's defaults apply.
118
+ */
119
+ private applyDefaultsSection;
120
+ /**
121
+ * Add defaults section content, preferring project's version if it has content
122
+ * @param result - Result object being built
123
+ * @param source - Lisa template with fallback values
124
+ * @param dest - Project JSON with potential overrides
125
+ * @param section - Section info from source
126
+ * @param category - Tag category name
127
+ */
128
+ private addDefaultsContent;
129
+ /**
130
+ * Locate and extract the matching tagged section from destination JSON
131
+ * @param dest - Project JSON to search for matching tags
132
+ * @param section - Source section info containing behavior type
133
+ * @param category - Tag category name to match
134
+ * @returns Extracted section info if found, undefined if project lacks the section
135
+ */
136
+ private findAndExtractDestinationSection;
137
+ /**
138
+ * Copy content keys from source template to result
139
+ * @param result - Result object being built
140
+ * @param source - Lisa template containing values to copy
141
+ * @param contentKeys - Keys to copy from source
142
+ */
143
+ private addSourceContent;
144
+ /**
145
+ * Apply merge behavior: combine arrays from source and dest without duplicates
146
+ * @param result - Result object being built
147
+ * @param source - Lisa template with base array items
148
+ * @param dest - Project JSON with additional array items
149
+ * @param section - Section info with content keys
150
+ * @param category - Tag category name
151
+ * @remarks
152
+ * Use merge for shared lists where both Lisa and projects contribute items,
153
+ * such as trustedDependencies. Lisa's items come first, then project's unique
154
+ * additions. Deduplication uses JSON.stringify for value equality comparison.
155
+ */
156
+ private applyMergeSection;
157
+ /**
158
+ * Combine two arrays, removing duplicates while preserving order
159
+ * @param sourceArray - Lisa template array (items added first)
160
+ * @param destArray - Project array (unique items added after)
161
+ * @returns Combined array with source items first, then project's unique additions
162
+ * @remarks
163
+ * Uses JSON.stringify for value equality, so objects/arrays with same content
164
+ * are considered duplicates. This allows deduplicating complex items like
165
+ * package names with version specifiers.
166
+ */
167
+ private deduplicateArrays;
168
+ /**
169
+ * Test if a key is an opening tag (matches `//lisa-<behavior>-<category>` format)
170
+ * @param key - JSON key to test
171
+ * @returns True if key matches the opening tag pattern
172
+ */
173
+ private isOpeningTag;
174
+ /**
175
+ * Test if a key is any tag-like comment key (starts with `//`)
176
+ * @param key - JSON key to test
177
+ * @returns True if key is a JSON comment (convention used for documentation/tags)
178
+ */
179
+ private isTagKey;
180
+ /**
181
+ * Find opening tag key for a given behavior and category in an object
182
+ * @param obj - Object to search for the tag
183
+ * @param behavior - Tag behavior type (force, defaults, merge)
184
+ * @param category - Tag category name
185
+ * @returns Tag key string if found, undefined if object lacks this tag
186
+ */
187
+ private findSectionStart;
188
+ /**
189
+ * Extract section boundaries and content keys between opening and closing tags
190
+ * @param obj - Object containing the tagged section
191
+ * @param startKey - Opening tag key that marks section start
192
+ * @param behavior - Tag behavior type (for constructing close key)
193
+ * @param category - Tag category name (for constructing close key)
194
+ * @returns Complete section info including content keys between tags
195
+ */
196
+ private extractSectionContent;
197
+ /**
198
+ * Extract keys between opening and closing tag indices
199
+ * @param startIndex - Index of opening tag in keys array
200
+ * @param closeIndex - Index of closing tag in keys array
201
+ * @param keys - Ordered array of all keys in the object
202
+ * @returns Array of content keys between the tags, empty if indices invalid
203
+ */
204
+ private extractContentKeysFromRange;
205
+ }
206
+ //# sourceMappingURL=tagged-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tagged-merge.d.ts","sourceRoot":"","sources":["../../src/strategies/tagged-merge.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM9E;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IACvD,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IAExC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAEvE;;;;;;;;;;;OAWG;IACG,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,mBAAmB,CAAC;IAmD/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,aAAa;IA4BrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;IAsC5B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;;;;;OAMG;IACH,OAAO,CAAC,gCAAgC;IAqBxC;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAIhB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;CAUpC"}
@@ -0,0 +1,421 @@
1
+ /**
2
+ * @file tagged-merge.ts
3
+ * @description Copy strategy for JSON files using comment-based tags for section-level control
4
+ * @module strategies
5
+ * @remarks
6
+ * This strategy solves a limitation of the regular merge strategy: the inability to
7
+ * force certain values while allowing project overrides in other sections of the same file.
8
+ * By using comment tags as section markers, Lisa can govern critical configs (CI/CD scripts,
9
+ * required dependencies) while projects retain freedom to customize other areas.
10
+ */
11
+ /* eslint-disable max-lines -- Large complex strategy with many helper methods */
12
+ import * as fse from "fs-extra";
13
+ import { copyFile } from "node:fs/promises";
14
+ import { ensureParentDir } from "../utils/file-operations.js";
15
+ import { readJson, writeJson } from "../utils/json-utils.js";
16
+ import { JsonMergeError } from "../errors/index.js";
17
+ /**
18
+ * Implements tagged merge strategy for JSON files with comment-based section control
19
+ * @remarks
20
+ * Supports three tag behaviors:
21
+ * - `//lisa-force-*`: Lisa replaces entire section, project changes ignored (for governance)
22
+ * - `//lisa-defaults-*`: Lisa provides values, project can override (for sensible defaults)
23
+ * - `//lisa-merge-*`: For arrays - combine Lisa's + project's items deduplicated (for shared lists)
24
+ *
25
+ * Tag format: `//lisa-<behavior>-<category>` with matching `//end-lisa-<behavior>-<category>`
26
+ *
27
+ * Order preservation: JSON key ordering is maintained throughout the merge process,
28
+ * ensuring deterministic output and minimal diff noise when configs change.
29
+ */
30
+ export class TaggedMergeStrategy {
31
+ name = "tagged-merge";
32
+ /**
33
+ * Regex pattern for parsing opening tags
34
+ * @remarks Captures behavior (force|defaults|merge) and category name for routing to appropriate merge logic
35
+ */
36
+ tagPattern = /^\/\/lisa-(force|defaults|merge)-(.+)$/;
37
+ /**
38
+ * Apply tagged merge strategy to a JSON file
39
+ * @param sourcePath - Absolute path to Lisa template JSON file with tags
40
+ * @param destPath - Absolute path to project JSON file to merge into
41
+ * @param relativePath - Project-relative path for manifest recording and logging
42
+ * @param context - Strategy context with config, manifest recording, and backup functions
43
+ * @returns Operation result indicating copied, skipped, or merged action
44
+ * @throws JsonMergeError if source or destination JSON cannot be parsed
45
+ * @remarks
46
+ * When destination doesn't exist, copies source directly. When destination exists,
47
+ * performs tagged merge preserving project customizations outside tagged sections.
48
+ */
49
+ async apply(sourcePath, destPath, relativePath, context) {
50
+ const { config, recordFile, backupFile } = context;
51
+ const destExists = await fse.pathExists(destPath);
52
+ if (!destExists) {
53
+ if (!config.dryRun) {
54
+ await ensureParentDir(destPath);
55
+ await copyFile(sourcePath, destPath);
56
+ recordFile(relativePath, this.name);
57
+ }
58
+ return { relativePath, strategy: this.name, action: "copied" };
59
+ }
60
+ const sourceJson = await readJson(sourcePath).catch(() => {
61
+ throw new JsonMergeError(relativePath, `Failed to parse source: ${sourcePath}`);
62
+ });
63
+ const destJson = await readJson(destPath).catch(() => {
64
+ throw new JsonMergeError(relativePath, `Failed to parse destination: ${destPath}`);
65
+ });
66
+ const merged = this.mergeWithTags(sourceJson, destJson);
67
+ const normalizedDest = JSON.stringify(destJson, null, 2);
68
+ const normalizedMerged = JSON.stringify(merged, null, 2);
69
+ if (normalizedDest === normalizedMerged) {
70
+ if (!config.dryRun) {
71
+ recordFile(relativePath, this.name);
72
+ }
73
+ return { relativePath, strategy: this.name, action: "skipped" };
74
+ }
75
+ if (!config.dryRun) {
76
+ await backupFile(destPath);
77
+ await writeJson(destPath, merged);
78
+ recordFile(relativePath, this.name);
79
+ }
80
+ return { relativePath, strategy: this.name, action: "merged" };
81
+ }
82
+ /**
83
+ * Merge source and destination JSON using tagged sections
84
+ * @param source - Lisa template JSON containing tag markers and governed content
85
+ * @param dest - Project JSON with potential customizations to preserve
86
+ * @returns Merged JSON with tagged sections applied according to their behavior types
87
+ * @remarks
88
+ * Processing order: 1) Process all tagged sections from source applying their behaviors,
89
+ * 2) Add unprocessed content from destination (preserves project customizations),
90
+ * 3) Add any remaining unprocessed tags from source. This ensures governance while
91
+ * preserving project-specific additions outside tagged regions.
92
+ */
93
+ mergeWithTags(source, dest) {
94
+ const sourceTags = this.parseTaggedSections(source);
95
+ const result = {};
96
+ const processed = new Set();
97
+ const processedTags = new Set();
98
+ for (const key in source) {
99
+ if (this.isOpeningTag(key)) {
100
+ this.processTaggedSection(key, source, dest, sourceTags, result, processed, processedTags);
101
+ }
102
+ }
103
+ this.addUnprocessedContent(result, dest, processed, processedTags);
104
+ this.addUnprocessedTags(result, source, processedTags, processed);
105
+ return result;
106
+ }
107
+ /**
108
+ * Preserve project customizations by adding untagged destination content to result
109
+ * @param result - Result object being built
110
+ * @param dest - Project JSON containing potential customizations
111
+ * @param processed - Keys already processed via tagged sections (to avoid duplicates)
112
+ * @param processedTags - Tag keys already processed (to avoid duplicates)
113
+ * @remarks
114
+ * This is the key step that preserves project freedom: any content outside tagged
115
+ * regions is copied from the project's file unchanged, allowing custom scripts,
116
+ * dependencies, or configs that Lisa doesn't govern.
117
+ */
118
+ addUnprocessedContent(result, dest, processed, processedTags) {
119
+ for (const key in dest) {
120
+ if (!processed.has(key) &&
121
+ !processedTags.has(key) &&
122
+ !this.isTagKey(key)) {
123
+ result[key] = dest[key];
124
+ }
125
+ }
126
+ }
127
+ /**
128
+ * Add any remaining tag keys from source that weren't part of complete tag pairs
129
+ * @param result - Result object being built
130
+ * @param source - Lisa template JSON
131
+ * @param processedTags - Tag keys already processed as part of complete sections
132
+ * @param processed - Content keys already processed
133
+ * @remarks
134
+ * Handles edge case of orphaned tags (e.g., opening tag without closing tag)
135
+ * by preserving them in output rather than silently dropping them.
136
+ */
137
+ addUnprocessedTags(result, source, processedTags, processed) {
138
+ for (const key in source) {
139
+ if (this.isTagKey(key) &&
140
+ !processedTags.has(key) &&
141
+ !processed.has(key)) {
142
+ result[key] = source[key];
143
+ }
144
+ }
145
+ }
146
+ /**
147
+ * Process a single tagged section, routing to appropriate behavior handler
148
+ * @param key - Opening tag key (e.g., `//lisa-force-scripts`)
149
+ * @param source - Lisa template JSON
150
+ * @param dest - Project JSON
151
+ * @param sourceTags - Map of all parsed tag sections from source
152
+ * @param result - Result object being built
153
+ * @param processed - Set tracking processed content keys
154
+ * @param processedTags - Set tracking processed tag keys
155
+ * @remarks
156
+ * Routes to applyForceSection, applyDefaultsSection, or applyMergeSection
157
+ * based on the behavior extracted from the tag. All keys within the section
158
+ * (including opening/closing tags) are marked as processed to prevent
159
+ * duplicate handling in subsequent steps.
160
+ */
161
+ processTaggedSection(key, source, dest, sourceTags, result, processed, processedTags) {
162
+ const tagMatch = this.tagPattern.exec(key);
163
+ if (!tagMatch || !tagMatch[2])
164
+ return;
165
+ const behavior = tagMatch[1];
166
+ const category = tagMatch[2];
167
+ const section = sourceTags.get(key);
168
+ if (!section)
169
+ return;
170
+ processedTags.add(key);
171
+ processedTags.add(section.closeKey);
172
+ for (const contentKey of section.contentKeys) {
173
+ processedTags.add(contentKey);
174
+ }
175
+ if (behavior === "force") {
176
+ this.applyForceSection(result, source, section);
177
+ }
178
+ else if (behavior === "defaults") {
179
+ this.applyDefaultsSection(result, source, dest, section, category);
180
+ }
181
+ else if (behavior === "merge") {
182
+ this.applyMergeSection(result, source, dest, section, category);
183
+ }
184
+ for (const contentKey of section.contentKeys) {
185
+ processed.add(contentKey);
186
+ }
187
+ processed.add(key);
188
+ processed.add(section.closeKey);
189
+ }
190
+ /**
191
+ * Parse JSON object to extract all tagged sections with their boundaries
192
+ * @param obj - JSON object to parse for tag markers
193
+ * @returns Map of opening tag keys to section info (behavior, category, content keys, close key)
194
+ * @remarks
195
+ * Relies on JSON key ordering being preserved (standard in modern JS engines).
196
+ * Skips sections without matching closing tags to handle malformed input gracefully.
197
+ */
198
+ parseTaggedSections(obj) {
199
+ const sections = new Map();
200
+ const keys = Object.keys(obj);
201
+ keys.forEach((key, i) => {
202
+ if (!this.isOpeningTag(key))
203
+ return;
204
+ const match = this.tagPattern.exec(key);
205
+ if (!match || !match[2])
206
+ return;
207
+ const behavior = match[1];
208
+ const category = match[2];
209
+ const closeKey = `//end-lisa-${behavior}-${category}`;
210
+ const closeIndex = keys.indexOf(closeKey);
211
+ if (closeIndex === -1)
212
+ return;
213
+ const contentKeys = keys.slice(i + 1, closeIndex);
214
+ sections.set(key, { behavior, category, contentKeys, closeKey });
215
+ });
216
+ return sections;
217
+ }
218
+ /**
219
+ * Apply force behavior: Lisa's section replaces project's entirely
220
+ * @param result - Result object being built
221
+ * @param source - Lisa template containing the authoritative values
222
+ * @param section - Section info with content keys to copy
223
+ * @remarks
224
+ * Use force for governance-critical configs that projects must not override,
225
+ * such as CI/CD scripts, required linting commands, or mandatory dev dependencies.
226
+ * Project changes within force-tagged sections are discarded during merge.
227
+ */
228
+ applyForceSection(result, source, section) {
229
+ const openKey = `//lisa-${section.behavior}-${section.category}`;
230
+ result[openKey] = source[openKey];
231
+ for (const key of section.contentKeys) {
232
+ result[key] = source[key];
233
+ }
234
+ result[section.closeKey] = source[section.closeKey];
235
+ }
236
+ /**
237
+ * Apply defaults behavior: project's values take precedence if they exist
238
+ * @param result - Result object being built
239
+ * @param source - Lisa template with default values
240
+ * @param dest - Project JSON with potential overrides
241
+ * @param section - Section info from source
242
+ * @param category - Tag category name for looking up destination section
243
+ * @remarks
244
+ * Use defaults for sensible starting values that projects may legitimately need
245
+ * to customize, such as engine versions or optional configurations. If project
246
+ * has the same tagged section, its content is used; otherwise Lisa's defaults apply.
247
+ */
248
+ applyDefaultsSection(result, source, dest, section, category) {
249
+ const openKey = `//lisa-${section.behavior}-${category}`;
250
+ result[openKey] = source[openKey];
251
+ this.addDefaultsContent(result, source, dest, section, category);
252
+ result[section.closeKey] = source[section.closeKey];
253
+ }
254
+ /**
255
+ * Add defaults section content, preferring project's version if it has content
256
+ * @param result - Result object being built
257
+ * @param source - Lisa template with fallback values
258
+ * @param dest - Project JSON with potential overrides
259
+ * @param section - Section info from source
260
+ * @param category - Tag category name
261
+ */
262
+ addDefaultsContent(result, source, dest, section, category) {
263
+ const destSection = this.findAndExtractDestinationSection(dest, section, category);
264
+ if (destSection && destSection.contentKeys.length > 0) {
265
+ for (const key of destSection.contentKeys) {
266
+ if (key in dest) {
267
+ result[key] = dest[key];
268
+ }
269
+ }
270
+ }
271
+ else {
272
+ this.addSourceContent(result, source, section.contentKeys);
273
+ }
274
+ }
275
+ /**
276
+ * Locate and extract the matching tagged section from destination JSON
277
+ * @param dest - Project JSON to search for matching tags
278
+ * @param section - Source section info containing behavior type
279
+ * @param category - Tag category name to match
280
+ * @returns Extracted section info if found, undefined if project lacks the section
281
+ */
282
+ findAndExtractDestinationSection(dest, section, category) {
283
+ const destSectionStart = this.findSectionStart(dest, section.behavior, category);
284
+ return destSectionStart
285
+ ? this.extractSectionContent(dest, destSectionStart, section.behavior, category)
286
+ : undefined;
287
+ }
288
+ /**
289
+ * Copy content keys from source template to result
290
+ * @param result - Result object being built
291
+ * @param source - Lisa template containing values to copy
292
+ * @param contentKeys - Keys to copy from source
293
+ */
294
+ addSourceContent(result, source, contentKeys) {
295
+ for (const key of contentKeys) {
296
+ result[key] = source[key];
297
+ }
298
+ }
299
+ /**
300
+ * Apply merge behavior: combine arrays from source and dest without duplicates
301
+ * @param result - Result object being built
302
+ * @param source - Lisa template with base array items
303
+ * @param dest - Project JSON with additional array items
304
+ * @param section - Section info with content keys
305
+ * @param category - Tag category name
306
+ * @remarks
307
+ * Use merge for shared lists where both Lisa and projects contribute items,
308
+ * such as trustedDependencies. Lisa's items come first, then project's unique
309
+ * additions. Deduplication uses JSON.stringify for value equality comparison.
310
+ */
311
+ applyMergeSection(result, source, dest, section, category) {
312
+ const openKey = `//lisa-${section.behavior}-${category}`;
313
+ result[openKey] = source[openKey];
314
+ for (const key of section.contentKeys) {
315
+ const sourceValue = source[key];
316
+ const destValue = dest[key];
317
+ if (Array.isArray(sourceValue) && Array.isArray(destValue)) {
318
+ result[key] = this.deduplicateArrays(sourceValue, destValue);
319
+ }
320
+ else if (sourceValue !== undefined) {
321
+ result[key] = sourceValue;
322
+ }
323
+ else if (destValue !== undefined) {
324
+ result[key] = destValue;
325
+ }
326
+ }
327
+ result[section.closeKey] = source[section.closeKey];
328
+ }
329
+ /**
330
+ * Combine two arrays, removing duplicates while preserving order
331
+ * @param sourceArray - Lisa template array (items added first)
332
+ * @param destArray - Project array (unique items added after)
333
+ * @returns Combined array with source items first, then project's unique additions
334
+ * @remarks
335
+ * Uses JSON.stringify for value equality, so objects/arrays with same content
336
+ * are considered duplicates. This allows deduplicating complex items like
337
+ * package names with version specifiers.
338
+ */
339
+ deduplicateArrays(sourceArray, destArray) {
340
+ const seen = new Set();
341
+ const result = [];
342
+ for (const item of sourceArray) {
343
+ const key = JSON.stringify(item);
344
+ if (!seen.has(key)) {
345
+ seen.add(key);
346
+ result.push(item);
347
+ }
348
+ }
349
+ for (const item of destArray) {
350
+ const key = JSON.stringify(item);
351
+ if (!seen.has(key)) {
352
+ seen.add(key);
353
+ result.push(item);
354
+ }
355
+ }
356
+ return result;
357
+ }
358
+ /**
359
+ * Test if a key is an opening tag (matches `//lisa-<behavior>-<category>` format)
360
+ * @param key - JSON key to test
361
+ * @returns True if key matches the opening tag pattern
362
+ */
363
+ isOpeningTag(key) {
364
+ return this.tagPattern.test(key);
365
+ }
366
+ /**
367
+ * Test if a key is any tag-like comment key (starts with `//`)
368
+ * @param key - JSON key to test
369
+ * @returns True if key is a JSON comment (convention used for documentation/tags)
370
+ */
371
+ isTagKey(key) {
372
+ return key.startsWith("//");
373
+ }
374
+ /**
375
+ * Find opening tag key for a given behavior and category in an object
376
+ * @param obj - Object to search for the tag
377
+ * @param behavior - Tag behavior type (force, defaults, merge)
378
+ * @param category - Tag category name
379
+ * @returns Tag key string if found, undefined if object lacks this tag
380
+ */
381
+ findSectionStart(obj, behavior, category) {
382
+ const tagKey = `//lisa-${behavior}-${category}`;
383
+ return tagKey in obj ? tagKey : undefined;
384
+ }
385
+ /**
386
+ * Extract section boundaries and content keys between opening and closing tags
387
+ * @param obj - Object containing the tagged section
388
+ * @param startKey - Opening tag key that marks section start
389
+ * @param behavior - Tag behavior type (for constructing close key)
390
+ * @param category - Tag category name (for constructing close key)
391
+ * @returns Complete section info including content keys between tags
392
+ */
393
+ extractSectionContent(obj, startKey, behavior, category) {
394
+ const closeKey = `//end-lisa-${behavior}-${category}`;
395
+ const keys = Object.keys(obj);
396
+ const startIndex = keys.indexOf(startKey);
397
+ const closeIndex = keys.indexOf(closeKey);
398
+ const contentKeys = this.extractContentKeysFromRange(startIndex, closeIndex, keys);
399
+ return {
400
+ behavior,
401
+ category,
402
+ contentKeys,
403
+ closeKey,
404
+ };
405
+ }
406
+ /**
407
+ * Extract keys between opening and closing tag indices
408
+ * @param startIndex - Index of opening tag in keys array
409
+ * @param closeIndex - Index of closing tag in keys array
410
+ * @param keys - Ordered array of all keys in the object
411
+ * @returns Array of content keys between the tags, empty if indices invalid
412
+ */
413
+ extractContentKeysFromRange(startIndex, closeIndex, keys) {
414
+ if (startIndex === -1 || closeIndex === -1 || startIndex >= closeIndex) {
415
+ return [];
416
+ }
417
+ return keys.slice(startIndex + 1, closeIndex);
418
+ }
419
+ }
420
+ /* eslint-enable max-lines -- End of TaggedMergeStrategy */
421
+ //# sourceMappingURL=tagged-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tagged-merge.js","sourceRoot":"","sources":["../../src/strategies/tagged-merge.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,11 @@ export default [
55
55
  // TypeScript/TSX files - slow import and React rules only
56
56
  {
57
57
  files: ["**/*.ts", "**/*.tsx"],
58
+ linterOptions: {
59
+ // Ignore inline eslint-disable comments since they reference rules
60
+ // from the main config that aren't loaded in this minimal config
61
+ noInlineConfig: true,
62
+ },
58
63
  languageOptions: {
59
64
  parser: tseslint.parser,
60
65
  parserOptions: {
@@ -78,7 +78,6 @@
78
78
  "@types/lodash.merge",
79
79
  "babel-plugin-istanbul",
80
80
  "baseline-browser-mapping",
81
- "commitizen",
82
81
  "date-fns-tz",
83
82
  "eslint-config-expo",
84
83
  "eslint-config-prettier",