obsidian-plugin-config 1.5.12 → 1.6.1

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 (43) hide show
  1. package/.vscode/tasks.json +5 -69
  2. package/DONE.md +60 -0
  3. package/FINAL_SUMMARY.md +163 -0
  4. package/README.md +70 -35
  5. package/bin/obsidian-inject.js +1 -1
  6. package/docs/APPLIED_MODIFS.md +104 -0
  7. package/docs/INTERACTIVE_INJECTION.md +137 -0
  8. package/docs/LLM-GUIDE.md +60 -50
  9. package/docs/TECHNICAL_NOTES.md +43 -0
  10. package/docs/implementation_plan.md +127 -0
  11. package/docs/modifs.md +434 -0
  12. package/package.json +3 -29
  13. package/scripts/acp.ts +7 -11
  14. package/scripts/build-npm.ts +78 -75
  15. package/scripts/help.ts +45 -107
  16. package/scripts/inject-core.ts +74 -36
  17. package/scripts/inject-options.ts +139 -0
  18. package/scripts/inject-path.ts +18 -4
  19. package/scripts/inject-prompt.ts +2 -1
  20. package/scripts/update-version-config.ts +2 -5
  21. package/templates/.gitattributes +4 -0
  22. package/templates/.github/workflows/release.yml +1 -1
  23. package/templates/.prettierignore +6 -0
  24. package/templates/.vscode/extensions.json +8 -0
  25. package/templates/.vscode/settings.json +0 -1
  26. package/templates/package.json +3 -2
  27. package/templates/scripts/esbuild.config.ts +16 -21
  28. package/tsconfig.json +2 -8
  29. package/.injection-info.json +0 -5
  30. package/docs/EXPORTS-EXPLAINED.md +0 -164
  31. package/manifest.json +0 -11
  32. package/scripts/esbuild.config.ts +0 -268
  33. package/scripts/sync-template-deps.ts +0 -59
  34. package/scripts/update-exports.js +0 -82
  35. package/src/index.ts +0 -6
  36. package/src/main.ts +0 -117
  37. package/src/modals/GenericConfirmModal.ts +0 -79
  38. package/src/modals/index.ts +0 -7
  39. package/src/tools/index.ts +0 -9
  40. package/src/utils/NoticeHelper.ts +0 -85
  41. package/src/utils/SettingsHelper.ts +0 -170
  42. package/src/utils/index.ts +0 -3
  43. package/versions.json +0 -64
@@ -201,82 +201,102 @@ main();
201
201
  console.log(` āœ… Generated ${binPath}`);
202
202
  }
203
203
 
204
+ /**
205
+ * Check NPM authentication and prompt login if needed
206
+ */
207
+ async function ensureNpmAuth(): Promise<void> {
208
+ console.log(`šŸ” Checking NPM authentication...`);
209
+
210
+ try {
211
+ const whoami = execSync('npm whoami --registry https://registry.npmjs.org/', {
212
+ stdio: 'pipe',
213
+ encoding: 'utf8'
214
+ }).trim();
215
+ console.log(` āœ… Logged in as: ${whoami}\n`);
216
+ } catch {
217
+ console.log(` āš ļø Not logged in to NPM\n`);
218
+ console.log(`šŸ”‘ Please login to NPM to publish the package`);
219
+ console.log(` Opening browser for authentication...\n`);
220
+
221
+ try {
222
+ execSync('npm login --auth-type=web --registry https://registry.npmjs.org/', {
223
+ stdio: 'inherit'
224
+ });
225
+ console.log(`\n āœ… Successfully logged in to NPM\n`);
226
+ } catch {
227
+ console.error(`\n āŒ NPM login failed`);
228
+ console.error(` Please run 'npm login' manually and try again`);
229
+ throw new Error('NPM authentication required');
230
+ }
231
+ }
232
+ }
233
+
204
234
  /**
205
235
  * Complete NPM workflow - Version, Commit, Push, Publish
206
236
  */
207
237
  async function buildAndPublishNpm(): Promise<void> {
208
- console.log(`šŸš€ Obsidian Plugin Config - Complete NPM Workflow`);
209
- console.log(`Full automation: version → exports → bin → commit → publish\n`);
238
+ console.log(`šŸš€ Obsidian Plugin Config - NPM Publish Workflow`);
239
+ console.log(`Automation: version → bin → verify → commit → publish\n`);
210
240
 
211
241
  try {
212
- // Step 0: Check NPM login
213
- // console.log(`šŸ” Checking NPM authentication...`);
214
- // try {
215
- // const whoami = execSync('npm whoami --registry https://registry.npmjs.org/', {
216
- // stdio: 'pipe',
217
- // encoding: 'utf8'
218
- // }).trim();
219
- // console.log(` āœ… Logged in as: ${whoami}\n`);
220
- // } catch {
221
- // console.error(` āŒ Not logged in to NPM. Run: npm login`);
222
- // process.exit(1);
223
- // }
242
+ // Step 0: Check NPM authentication
243
+ await ensureNpmAuth();
224
244
 
225
245
  // Step 1: Update version
226
- console.log(`šŸ“‹ Step 1/7: Updating version...`);
246
+ console.log(`šŸ“‹ Step 1/5: Updating version...`);
227
247
  execSync('tsx scripts/update-version-config.ts', { stdio: 'inherit' });
228
248
 
229
- // Step 2: Update exports
230
- console.log(`\nšŸ“¦ Step 2/7: Updating exports...`);
231
- execSync('yarn update-exports', { stdio: 'inherit' });
232
-
233
- // Step 3: Generate bin file
234
- console.log(`\nšŸ”§ Step 3/7: Generating bin/obsidian-inject.js...`);
249
+ // Step 2: Generate bin file
250
+ console.log(`\nšŸ”§ Step 2/5: Generating bin/obsidian-inject.js...`);
235
251
  await generateBinFile();
236
252
 
237
- // Step 4: Verify package and sync versions.json
238
- console.log(`\nšŸ“‹ Step 4/7: Verifying package...`);
253
+ // Step 3: Verify package
254
+ console.log(`\nšŸ“‹ Step 3/5: Verifying package...`);
239
255
  verifyPackage();
240
256
 
241
- // Step 5: Commit and push
242
- console.log(`\nšŸ“¤ Step 5/7: Committing and pushing changes...`);
257
+ // Step 4: Commit and push
258
+ console.log(`\nšŸ“¤ Step 4/5: Committing and pushing changes...`);
243
259
  try {
244
- execSync('echo "Publish NPM package" | tsx scripts/acp.ts -b', {
245
- stdio: 'inherit'
246
- });
247
- } catch {
248
- console.log(` ā„¹ļø No additional changes to commit`);
260
+ // Add all changes
261
+ execSync('git add -A', { stdio: 'pipe' });
262
+
263
+ // Check if there are changes to commit
264
+ const status = execSync('git status --porcelain', { encoding: 'utf8' });
265
+ if (status.trim()) {
266
+ const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
267
+ execSync(`git commit -m "Publish NPM package v${packageJson.version}"`, {
268
+ stdio: 'pipe'
269
+ });
270
+
271
+ // Get current branch and push
272
+ const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
273
+ encoding: 'utf8'
274
+ }).trim();
275
+ execSync(`git push origin ${currentBranch}`, { stdio: 'inherit' });
276
+ console.log(` āœ… Changes committed and pushed`);
277
+ } else {
278
+ console.log(` ā„¹ļø No changes to commit`);
279
+ }
280
+ } catch (error) {
281
+ console.error(` āŒ Commit/push failed: ${error instanceof Error ? error.message : String(error)}`);
282
+ throw error;
249
283
  }
250
284
 
251
- // Step 6: Publish to NPM
252
- console.log(`\nšŸ“¤ Step 6/7: Publishing to NPM...`);
285
+ // Step 5: Publish to NPM
286
+ console.log(`\nšŸ“¤ Step 5/5: Publishing to NPM...`);
253
287
  execSync('npm publish --registry https://registry.npmjs.org/', {
254
288
  stdio: 'inherit'
255
289
  });
256
290
 
257
- // Step 7: Update global CLI (auto if --auto-update, else ask)
258
- console.log(`\nšŸŒ Step 7/7: Update global CLI?`);
259
- const autoUpdate = process.argv.includes('--auto-update');
260
- let doUpdate = autoUpdate;
261
- if (!autoUpdate) {
262
- const { askConfirmation, createReadlineInterface } =
263
- await import('./utils.js');
264
- const rl = createReadlineInterface();
265
- doUpdate = await askConfirmation(
266
- `Install obsidian-plugin-config@latest globally?`,
267
- rl
268
- );
269
- rl.close();
270
- }
271
- if (doUpdate) {
272
- console.log(` ā³ Waiting 15s for NPM registry propagation...`);
273
- await new Promise((resolve) => setTimeout(resolve, 15000));
274
- execSync(
275
- 'npm install -g obsidian-plugin-config@latest --force --engine-strict=false',
276
- { stdio: 'inherit' }
277
- );
278
- console.log(` āœ… Global CLI updated`);
279
- }
291
+ // Optional: Update global CLI automatically
292
+ console.log(`\nšŸŒ Updating global CLI...`);
293
+ console.log(` ā³ Waiting 15s for NPM registry propagation...`);
294
+ await new Promise((resolve) => setTimeout(resolve, 15000));
295
+ execSync(
296
+ 'npm install -g obsidian-plugin-config@latest --force --engine-strict=false',
297
+ { stdio: 'inherit' }
298
+ );
299
+ console.log(` āœ… Global CLI updated`);
280
300
 
281
301
  console.log(`\nšŸŽ‰ Complete workflow successful!`);
282
302
  console.log(` Test: cd any-plugin && obsidian-inject`);
@@ -296,8 +316,8 @@ function verifyPackage(): void {
296
316
  const requiredScripts = [
297
317
  'scripts/inject-path.ts',
298
318
  'scripts/inject-prompt.ts',
319
+ 'scripts/inject-core.ts',
299
320
  'scripts/utils.ts',
300
- 'scripts/esbuild.config.ts',
301
321
  'scripts/acp.ts',
302
322
  'scripts/update-version-config.ts',
303
323
  'scripts/help.ts'
@@ -334,26 +354,9 @@ function verifyPackage(): void {
334
354
  }
335
355
  console.log(` āœ… Bin file ready`);
336
356
 
337
- // Sync versions.json
338
- const versionsPath = 'versions.json';
339
- let versions: Record<string, string> = {};
340
-
341
- if (fs.existsSync(versionsPath)) {
342
- versions = JSON.parse(fs.readFileSync(versionsPath, 'utf8'));
343
- }
344
-
345
- if (!versions[packageJson.version]) {
346
- const manifest = JSON.parse(fs.readFileSync('manifest.json', 'utf8'));
347
- versions[packageJson.version] = manifest.minAppVersion;
348
- fs.writeFileSync(versionsPath, JSON.stringify(versions, null, ' '), 'utf8');
349
- console.log(` āœ… Added version ${packageJson.version} to versions.json`);
350
- } else {
351
- console.log(` āœ… Version ${packageJson.version} in versions.json`);
352
- }
353
-
354
357
  // Quick build test
355
- execSync('yarn build', { stdio: 'pipe' });
356
- console.log(` āœ… Build test passed`);
358
+ execSync('tsc --noEmit', { stdio: 'pipe' });
359
+ console.log(` āœ… TypeScript check passed`);
357
360
  }
358
361
 
359
362
  // Run the script
package/scripts/help.ts CHANGED
@@ -2,150 +2,88 @@
2
2
 
3
3
  console.log(`
4
4
  šŸŽÆ Obsidian Plugin Config - Quick Help
5
- Injection system for autonomous Obsidian plugins
5
+ Global CLI injection tool for Obsidian plugins
6
6
 
7
7
  ═══════════════════════════════════════════════════════════════════
8
8
 
9
- šŸ“‹ PLUGIN CONFIG COMMANDS
9
+ šŸ“‹ DEVELOPMENT COMMANDS
10
10
 
11
- INSTALLATION & SETUP:
12
- yarn i, install # Install dependencies
13
- yarn update-exports, ue # Update package.json exports
14
-
15
- GIT & VERSION MANAGEMENT:
11
+ GIT & VERSION:
16
12
  yarn acp # Add, commit, push
17
- yarn bacp # Build + add, commit, push
18
- yarn v, update-version # Update version (package.json + versions.json)
13
+ yarn v, update-version # Update version
19
14
 
20
- BUILD & TESTING:
21
- yarn build # TypeScript check (no build needed)
22
- yarn dev # Start development mode (watch)
23
- yarn real # Build for production to real vault
15
+ LINTING:
24
16
  yarn lint, lint:fix # ESLint verification/correction
25
17
 
26
- INJECTION (Development phase):
27
- yarn inject-prompt <path> # Interactive injection (recommended)
28
- yarn inject-path <path> --yes # Direct injection with auto-confirm
18
+ INJECTION (local testing):
19
+ yarn inject-prompt # Interactive injection
20
+ yarn inject-path <path> # Direct injection
29
21
  yarn inject <path> --sass # Injection with SASS support
30
22
  yarn check-plugin <path> # Verification only (dry-run)
31
23
 
32
- NPM PUBLISHING (all-in-one - no acp needed before):
33
- yarn npm-publish # Full workflow (7 steps):
34
- # 0. NPM auth check
24
+ NPM PUBLISHING:
25
+ yarn npm-publish # Full workflow (5 steps):
35
26
  # 1. version bump
36
- # 2. update exports
37
- # 3. generate bin
38
- # 4. verify package
39
- # 5. commit + push
40
- # 6. publish to NPM
41
- # 7. offer global CLI update
42
- yarn build-npm # Alias for npm-publish
43
-
44
- UPGRADE:
45
- yarn upgrade-all # yarn upgrade + sync template deps
27
+ # 2. generate bin
28
+ # 3. verify package
29
+ # 4. commit + push
30
+ # 5. publish to NPM
46
31
 
47
32
  HELP:
48
- yarn help, h # This help
49
-
50
- ═══════════════════════════════════════════════════════════════════
51
-
52
- šŸ“¦ EXPORTS SYSTEM
53
-
54
- The package exposes a single entry point:
55
- obsidian-plugin-config # Main entry — re-exports all modules
56
-
57
- Src modules (auto-exported via src/index.ts):
58
- modals, tools, utils
59
-
60
- After adding a new module to src/, run:
61
- yarn update-exports # Regenerates src/index.ts
33
+ yarn h # This help
62
34
 
63
35
  ═══════════════════════════════════════════════════════════════════
64
36
 
65
37
  šŸ—ļø ARCHITECTURE
66
38
 
67
- TWO DISTINCT ROLES:
68
- Root (src/, scripts/) # Local plugin + NPM snippet exports
69
- templates/ # Source of truth for injection
39
+ PURE INJECTION TOOL:
40
+ templates/ # Files to inject into target plugins
41
+ scripts/inject-*.ts # Injection logic
42
+ bin/obsidian-inject.js # Global CLI entry point
70
43
 
71
44
  templates/ → what gets injected:
72
45
  templates/package.json # Base deps/scripts for target plugins
73
46
  templates/package-sass.json # Extra deps when --sass is used
74
- templates/tsconfig.json # TypeScript config for target plugins
75
- templates/scripts/* # Scripts copied to <target>/scripts/
76
- templates/eslint.config.mts # ESLint config for target plugins
47
+ templates/tsconfig.json # TypeScript config
48
+ templates/scripts/* # Scripts copied to target
49
+ templates/eslint.config.mts # ESLint config
50
+ templates/.github/workflows/* # GitHub Actions
77
51
 
78
52
  inject-core.ts — shared injection logic:
79
- updatePackageJson() # Reads templates/package.json (not hardcoded)
80
- injectScripts() # Copies templates/ files to target
81
- performInjection() # Main orchestration function
53
+ updatePackageJson() # Merges template package.json
54
+ injectScripts() # Copies template files to target
55
+ performInjection() # Main orchestration
82
56
 
83
57
  inject-path.ts — CLI entry point:
84
58
  Parses --yes, --dry-run, --sass flags
85
59
 
86
- inject-prompt.ts — interactive entry point:
87
- Prompts for target path interactively
60
+ inject-prompt.ts — interactive entry:
61
+ Prompts for target path
88
62
 
89
63
  ═══════════════════════════════════════════════════════════════════
90
64
 
91
- šŸ”§ DEVELOPMENT WORKFLOWS
65
+ šŸ”§ WORKFLOWS
92
66
 
93
- Plugin Config Development:
94
- 1. yarn i # Install dependencies
95
- 2. yarn update-exports # Update exports
96
- 3. yarn dev # Test as plugin (optional)
97
- 4. yarn lint:fix # Fix code issues
98
- 5. yarn v # Update version + commit + push
99
- 6. yarn npm-publish # Publish to NPM
67
+ Development:
68
+ 1. Make changes to templates/ or scripts/
69
+ 2. yarn lint:fix # Fix code issues
70
+ 3. yarn npm-publish # Version, commit, publish
100
71
 
101
- Injection Usage:
102
- Usage (from plugin directory or by path):
103
- obsidian-inject # Inject in current dir
104
- obsidian-inject ../my-plugin # Inject by path
105
- obsidian-inject ../my-plugin --sass # With SASS
72
+ Global CLI Usage:
73
+ obsidian-inject # Inject in current dir
74
+ obsidian-inject ../my-plugin # Inject by path
75
+ obsidian-inject ../my-plugin --sass # With SASS
76
+ obsidian-inject --help # Show help
106
77
 
107
- Or with local yarn commands:
108
- yarn inject-prompt # Interactive
109
- yarn inject-path ../my-plugin # Direct injection
110
- yarn check-plugin ../my-plugin # Dry-run only
78
+ Local Testing:
79
+ yarn inject-prompt # Interactive
80
+ yarn inject-path ../my-plugin # Direct
81
+ yarn check-plugin ../my-plugin # Dry-run
111
82
 
112
83
  SASS Support (--sass flag):
113
- What gets added to the target plugin:
114
- āœ… esbuild-sass-plugin dependency
115
- āœ… Automatic .scss file detection (src/styles.scss priority)
116
- āœ… CSS cleanup after compilation
117
-
118
- The standard esbuild.config.ts handles SASS via dynamic import —
119
- no separate template needed.
120
-
121
- ═══════════════════════════════════════════════════════════════════
122
-
123
- šŸš€ COMPLETE WORKFLOWS
124
-
125
- STANDARD DEVELOPMENT WORKFLOW:
126
- 1. yarn i # Install dependencies
127
- 2. Make changes to src/ or templates/
128
- 3. yarn lint:fix # Fix any linting issues
129
- 4. yarn npm-publish # Does EVERYTHING:
130
- # → Ask for version bump type
131
- # → Update exports
132
- # → Generate bin file
133
- # → Verify package
134
- # → Commit + push to GitHub
135
- # → Publish to NPM
136
-
137
- Note: yarn acp is only needed for intermediate commits
138
- (not required before npm-publish).
139
-
140
- AFTER NPM PUBLISH - Update global CLI:
141
- npm install -g obsidian-plugin-config@latest --force
142
- obsidian-inject # Test in current plugin dir
143
- obsidian-inject ../test-plugin --sass
144
-
145
- TESTING AS PLUGIN (Optional):
146
- 1. Configure .env with TEST_VAULT and REAL_VAULT paths
147
- 2. yarn dev # Watch mode for development
148
- 3. yarn real # Install to real vault
84
+ āœ… esbuild-sass-plugin dependency
85
+ āœ… Automatic .scss detection (src/styles.scss priority)
86
+ āœ… CSS cleanup after compilation
149
87
 
150
88
  ═══════════════════════════════════════════════════════════════════
151
89
 
@@ -5,6 +5,7 @@ import path from 'path';
5
5
  import { execSync } from 'child_process';
6
6
  import { fileURLToPath } from 'url';
7
7
  import { isValidPath, gitExec } from './utils.js';
8
+ import type { InjectionOptions } from './inject-options.js';
8
9
 
9
10
  export interface InjectionPlan {
10
11
  targetPath: string;
@@ -272,7 +273,10 @@ export async function cleanOldLintFiles(targetPath: string): Promise<void> {
272
273
  /**
273
274
  * Inject scripts and config files
274
275
  */
275
- export async function injectScripts(targetPath: string): Promise<void> {
276
+ export async function injectScripts(
277
+ targetPath: string,
278
+ options: InjectionOptions
279
+ ): Promise<void> {
276
280
  const scriptsPath = path.join(targetPath, 'scripts');
277
281
 
278
282
  if (!(await isValidPath(scriptsPath))) {
@@ -320,22 +324,41 @@ export async function injectScripts(targetPath: string): Promise<void> {
320
324
 
321
325
  console.log(`\nšŸ“„ Copying scripts from local files...`);
322
326
 
323
- for (const scriptFile of scriptFiles) {
324
- try {
325
- const content = copyFromLocal(scriptFile);
326
- const fileName = path.basename(scriptFile);
327
- const targetFile = path.join(scriptsPath, fileName);
328
- fs.writeFileSync(targetFile, content, 'utf8');
329
- console.log(` āœ… ${fileName}`);
330
- } catch (error) {
331
- console.error(` āŒ Failed to inject ${scriptFile}: ${error}`);
327
+ if (options.scripts) {
328
+ for (const scriptFile of scriptFiles) {
329
+ try {
330
+ const content = copyFromLocal(scriptFile);
331
+ const fileName = path.basename(scriptFile);
332
+ const targetFile = path.join(scriptsPath, fileName);
333
+ fs.writeFileSync(targetFile, content, 'utf8');
334
+ console.log(` āœ… ${fileName}`);
335
+ } catch (error) {
336
+ console.error(` āŒ Failed to inject ${scriptFile}: ${error}`);
337
+ }
332
338
  }
339
+ } else {
340
+ console.log(` ā­ļø Skipped (user choice)`);
333
341
  }
334
342
 
335
343
  console.log(`\nšŸ“„ Copying config files...`);
336
344
 
337
345
  // Copy root config files
338
346
  for (const [src, destName] of Object.entries(configFileMap)) {
347
+ // Check if this file should be injected based on options
348
+ const shouldInject =
349
+ (destName === 'tsconfig.json' && options.tsconfig) ||
350
+ (destName === 'eslint.config.mts' && options.eslint) ||
351
+ (destName === '.prettierrc' && options.prettier) ||
352
+ (destName === '.editorconfig' && options.editorconfig) ||
353
+ (destName === '.gitignore' && options.gitignore) ||
354
+ (destName === '.env' && options.env) ||
355
+ (destName === '.npmrc'); // Always inject .npmrc
356
+
357
+ if (!shouldInject) {
358
+ console.log(` ā­ļø Skipped ${destName} (user choice)`);
359
+ continue;
360
+ }
361
+
339
362
  try {
340
363
  const targetFile = path.join(targetPath, destName);
341
364
  const templateContent = copyFromLocal(src);
@@ -375,39 +398,47 @@ export async function injectScripts(targetPath: string): Promise<void> {
375
398
  }
376
399
 
377
400
  // Copy .vscode config files
378
- for (const [src, destName] of Object.entries(configVscodeMap)) {
379
- try {
380
- const content = copyFromLocal(src);
381
- const targetFile = path.join(targetPath, destName);
382
- const targetDir = path.dirname(targetFile);
383
- if (!(await isValidPath(targetDir))) {
384
- fs.mkdirSync(targetDir, { recursive: true });
401
+ if (options.vscode) {
402
+ for (const [src, destName] of Object.entries(configVscodeMap)) {
403
+ try {
404
+ const content = copyFromLocal(src);
405
+ const targetFile = path.join(targetPath, destName);
406
+ const targetDir = path.dirname(targetFile);
407
+ if (!(await isValidPath(targetDir))) {
408
+ fs.mkdirSync(targetDir, { recursive: true });
409
+ }
410
+ fs.writeFileSync(targetFile, content, 'utf8');
411
+ console.log(` āœ… ${destName}`);
412
+ } catch (error) {
413
+ console.error(` āŒ Failed to inject ${destName}: ${error}`);
385
414
  }
386
- fs.writeFileSync(targetFile, content, 'utf8');
387
- console.log(` āœ… ${destName}`);
388
- } catch (error) {
389
- console.error(` āŒ Failed to inject ${destName}: ${error}`);
390
415
  }
416
+ } else {
417
+ console.log(` ā­ļø Skipped .vscode/ (user choice)`);
391
418
  }
392
419
 
393
420
  console.log(`\nšŸ“„ Copying GitHub workflows from local files...`);
394
421
 
395
- for (const workflowFile of workflowFiles) {
396
- try {
397
- const content = copyFromLocal(workflowFile);
398
- const relativePath = workflowFile.replace('templates/', '');
399
- const targetFile = path.join(targetPath, relativePath);
400
- const targetDir = path.dirname(targetFile);
422
+ if (options.github) {
423
+ for (const workflowFile of workflowFiles) {
424
+ try {
425
+ const content = copyFromLocal(workflowFile);
426
+ const relativePath = workflowFile.replace('templates/', '');
427
+ const targetFile = path.join(targetPath, relativePath);
428
+ const targetDir = path.dirname(targetFile);
401
429
 
402
- if (!(await isValidPath(targetDir))) {
403
- fs.mkdirSync(targetDir, { recursive: true });
404
- }
430
+ if (!(await isValidPath(targetDir))) {
431
+ fs.mkdirSync(targetDir, { recursive: true });
432
+ }
405
433
 
406
- fs.writeFileSync(targetFile, content, 'utf8');
407
- console.log(` āœ… ${relativePath}`);
408
- } catch (error) {
409
- console.error(` āŒ Failed to inject ${workflowFile}: ${error}`);
434
+ fs.writeFileSync(targetFile, content, 'utf8');
435
+ console.log(` āœ… ${relativePath}`);
436
+ } catch (error) {
437
+ console.error(` āŒ Failed to inject ${workflowFile}: ${error}`);
438
+ }
410
439
  }
440
+ } else {
441
+ console.log(` ā­ļø Skipped (user choice)`);
411
442
  }
412
443
  }
413
444
 
@@ -416,6 +447,7 @@ export async function injectScripts(targetPath: string): Promise<void> {
416
447
  */
417
448
  export async function updatePackageJson(
418
449
  targetPath: string,
450
+ options: InjectionOptions,
419
451
  useSass: boolean = false
420
452
  ): Promise<void> {
421
453
  const packageJsonPath = path.join(targetPath, 'package.json');
@@ -425,6 +457,11 @@ export async function updatePackageJson(
425
457
  return;
426
458
  }
427
459
 
460
+ if (!options.packageJson) {
461
+ console.log(`ā­ļø Skipped package.json update (user choice)`);
462
+ return;
463
+ }
464
+
428
465
  try {
429
466
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
430
467
 
@@ -704,6 +741,7 @@ export async function runYarnInstall(targetPath: string): Promise<void> {
704
741
  */
705
742
  export async function performInjection(
706
743
  targetPath: string,
744
+ options: InjectionOptions,
707
745
  useSass: boolean = false
708
746
  ): Promise<void> {
709
747
  console.log(`\nšŸš€ Starting injection process...`);
@@ -711,10 +749,10 @@ export async function performInjection(
711
749
  try {
712
750
  await cleanNpmArtifactsIfNeeded(targetPath);
713
751
  await ensureTsxInstalled(targetPath);
714
- await injectScripts(targetPath);
752
+ await injectScripts(targetPath, options);
715
753
 
716
754
  console.log(`\nšŸ“¦ Updating package.json...`);
717
- await updatePackageJson(targetPath, useSass);
755
+ await updatePackageJson(targetPath, options, useSass);
718
756
 
719
757
  await analyzeCentralizedImports(targetPath);
720
758