@git.zone/cli 2.9.1 → 2.10.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.
Files changed (32) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/mod_format/formatters/copy.formatter.d.ts +6 -3
  3. package/dist_ts/mod_format/formatters/copy.formatter.js +90 -6
  4. package/dist_ts/mod_format/formatters/gitignore.formatter.d.ts +6 -3
  5. package/dist_ts/mod_format/formatters/gitignore.formatter.js +101 -6
  6. package/dist_ts/mod_format/formatters/license.formatter.d.ts +7 -3
  7. package/dist_ts/mod_format/formatters/license.formatter.js +48 -6
  8. package/dist_ts/mod_format/formatters/npmextra.formatter.d.ts +6 -3
  9. package/dist_ts/mod_format/formatters/npmextra.formatter.js +130 -6
  10. package/dist_ts/mod_format/formatters/packagejson.formatter.d.ts +6 -3
  11. package/dist_ts/mod_format/formatters/packagejson.formatter.js +162 -6
  12. package/dist_ts/mod_format/formatters/prettier.formatter.d.ts +5 -1
  13. package/dist_ts/mod_format/formatters/prettier.formatter.js +46 -1
  14. package/dist_ts/mod_format/formatters/readme.formatter.js +35 -9
  15. package/dist_ts/mod_format/formatters/templates.formatter.d.ts +7 -3
  16. package/dist_ts/mod_format/formatters/templates.formatter.js +135 -6
  17. package/dist_ts/mod_format/formatters/tsconfig.formatter.d.ts +6 -3
  18. package/dist_ts/mod_format/formatters/tsconfig.formatter.js +61 -6
  19. package/package.json +31 -21
  20. package/ts/00_commitinfo_data.ts +1 -1
  21. package/ts/mod_format/formatters/copy.formatter.ts +114 -5
  22. package/ts/mod_format/formatters/gitignore.formatter.ts +108 -5
  23. package/ts/mod_format/formatters/license.formatter.ts +59 -5
  24. package/ts/mod_format/formatters/npmextra.formatter.ts +162 -5
  25. package/ts/mod_format/formatters/packagejson.formatter.ts +201 -5
  26. package/ts/mod_format/formatters/prettier.formatter.ts +50 -1
  27. package/ts/mod_format/formatters/readme.formatter.ts +39 -8
  28. package/ts/mod_format/formatters/templates.formatter.ts +152 -5
  29. package/ts/mod_format/formatters/tsconfig.formatter.ts +70 -5
  30. package/dist_ts/mod_format/formatters/legacy.formatter.d.ts +0 -11
  31. package/dist_ts/mod_format/formatters/legacy.formatter.js +0 -31
  32. package/ts/mod_format/formatters/legacy.formatter.ts +0 -43
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@git.zone/cli",
3
3
  "private": false,
4
- "version": "2.9.1",
4
+ "version": "2.10.0",
5
5
  "description": "A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.",
6
6
  "main": "dist_ts/index.ts",
7
7
  "typings": "dist_ts/index.d.ts",
@@ -10,6 +10,24 @@
10
10
  "gitzone": "./cli.js",
11
11
  "gzone": "./cli.js"
12
12
  },
13
+ "scripts": {
14
+ "test": "(npm run clean && npm run prepareTest && npm run testCli && npm run testFormat && npm run testCommit && npm run testDeprecate && npm run testVersion && npm run testReadme && npm run testUpdate && npm run testTemplateNpm && npm run testTemplateLit) && rm -rf test",
15
+ "build": "tsbuild tsfolders",
16
+ "clean": "(rm -rf test/)",
17
+ "prepareTest": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
18
+ "testBuild": "npm run build && rm -r dist/",
19
+ "testCli": "(cd test && node ../cli.ts.js)",
20
+ "testCommit": "(cd test && node ../cli.ts.js commit)",
21
+ "testDeprecate": "(cd test && node ../cli.ts.js deprecate)",
22
+ "testOpen": "(cd test && node ../cli.ts.js open ci)",
23
+ "testReadme": "(cd test && node ../cli.ts.js readme)",
24
+ "testFormat": "(cd test && node ../cli.ts.js format)",
25
+ "testTemplateNpm": "(rm -rf test/testtemplate_npm/ && mkdir test/testtemplate_npm && cd test/testtemplate_npm && node ../../cli.ts.js template npm)",
26
+ "testTemplateLit": "(rm -rf test/testtemplate_lit/ && mkdir test/testtemplate_lit && cd test/testtemplate_lit && node ../../cli.ts.js template lit)",
27
+ "testUpdate": "(cd test && node ../cli.ts.js update)",
28
+ "testVersion": "(cd test && node ../cli.ts.js -v)",
29
+ "buildDocs": "tsdoc"
30
+ },
13
31
  "repository": {
14
32
  "type": "git",
15
33
  "url": "https://gitlab.com/gitzone/private/gitzone.git"
@@ -49,7 +67,7 @@
49
67
  "@types/node": "^25.0.2"
50
68
  },
51
69
  "dependencies": {
52
- "@git.zone/tsdoc": "^1.11.2",
70
+ "@git.zone/tsdoc": "^1.11.3",
53
71
  "@git.zone/tspublish": "^1.10.3",
54
72
  "@push.rocks/commitinfo": "^1.0.12",
55
73
  "@push.rocks/early": "^4.0.4",
@@ -95,22 +113,14 @@
95
113
  "browserslist": [
96
114
  "last 1 chrome versions"
97
115
  ],
98
- "scripts": {
99
- "test": "(npm run clean && npm run prepareTest && npm run testCli && npm run testFormat && npm run testCommit && npm run testDeprecate && npm run testVersion && npm run testReadme && npm run testUpdate && npm run testTemplateNpm && npm run testTemplateLit) && rm -rf test",
100
- "build": "tsbuild tsfolders",
101
- "clean": "(rm -rf test/)",
102
- "prepareTest": "(git clone https://gitlab.com/sandboxzone/sandbox-npmts.git test/)",
103
- "testBuild": "npm run build && rm -r dist/",
104
- "testCli": "(cd test && node ../cli.ts.js)",
105
- "testCommit": "(cd test && node ../cli.ts.js commit)",
106
- "testDeprecate": "(cd test && node ../cli.ts.js deprecate)",
107
- "testOpen": "(cd test && node ../cli.ts.js open ci)",
108
- "testReadme": "(cd test && node ../cli.ts.js readme)",
109
- "testFormat": "(cd test && node ../cli.ts.js format)",
110
- "testTemplateNpm": "(rm -rf test/testtemplate_npm/ && mkdir test/testtemplate_npm && cd test/testtemplate_npm && node ../../cli.ts.js template npm)",
111
- "testTemplateLit": "(rm -rf test/testtemplate_lit/ && mkdir test/testtemplate_lit && cd test/testtemplate_lit && node ../../cli.ts.js template lit)",
112
- "testUpdate": "(cd test && node ../cli.ts.js update)",
113
- "testVersion": "(cd test && node ../cli.ts.js -v)",
114
- "buildDocs": "tsdoc"
115
- }
116
- }
116
+ "pnpm": {
117
+ "overrides": {},
118
+ "onlyBuiltDependencies": [
119
+ "esbuild",
120
+ "mongodb-memory-server",
121
+ "puppeteer",
122
+ "sharp"
123
+ ]
124
+ },
125
+ "packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6"
126
+ }
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/cli',
6
- version: '2.9.0',
6
+ version: '2.10.0',
7
7
  description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.'
8
8
  }
@@ -1,8 +1,117 @@
1
- import { LegacyFormatter } from './legacy.formatter.js';
2
- import * as formatCopy from '../format.copy.js';
1
+ import { BaseFormatter } from '../classes.baseformatter.js';
2
+ import type { IPlannedChange } from '../interfaces.format.js';
3
+ import * as plugins from '../mod.plugins.js';
4
+ import { logger, logVerbose } from '../../gitzone.logging.js';
3
5
 
4
- export class CopyFormatter extends LegacyFormatter {
5
- constructor(context: any, project: any) {
6
- super(context, project, 'copy', formatCopy);
6
+ interface ICopyPattern {
7
+ from: string;
8
+ to: string;
9
+ preservePath?: boolean;
10
+ }
11
+
12
+ export class CopyFormatter extends BaseFormatter {
13
+ get name(): string {
14
+ return 'copy';
15
+ }
16
+
17
+ async analyze(): Promise<IPlannedChange[]> {
18
+ const changes: IPlannedChange[] = [];
19
+
20
+ // Get copy configuration from npmextra.json
21
+ const npmextraConfig = new plugins.npmextra.Npmextra();
22
+ const copyConfig = npmextraConfig.dataFor<{ patterns: ICopyPattern[] }>(
23
+ 'gitzone.format.copy',
24
+ { patterns: [] },
25
+ );
26
+
27
+ if (!copyConfig.patterns || copyConfig.patterns.length === 0) {
28
+ logVerbose('No copy patterns configured in npmextra.json');
29
+ return changes;
30
+ }
31
+
32
+ for (const pattern of copyConfig.patterns) {
33
+ if (!pattern.from || !pattern.to) {
34
+ logVerbose('Invalid copy pattern - missing "from" or "to" field');
35
+ continue;
36
+ }
37
+
38
+ try {
39
+ // Handle glob patterns
40
+ const entries = await plugins.smartfs
41
+ .directory('.')
42
+ .recursive()
43
+ .filter(pattern.from)
44
+ .list();
45
+ const files = entries.map((entry) => entry.path);
46
+
47
+ for (const file of files) {
48
+ const sourcePath = file;
49
+ let destPath = pattern.to;
50
+
51
+ // If destination is a directory, preserve filename
52
+ if (pattern.to.endsWith('/')) {
53
+ const filename = plugins.path.basename(file);
54
+ destPath = plugins.path.join(pattern.to, filename);
55
+ }
56
+
57
+ // Handle template variables in destination path
58
+ if (pattern.preservePath) {
59
+ const relativePath = plugins.path.relative(
60
+ plugins.path.dirname(pattern.from.replace(/\*/g, '')),
61
+ file,
62
+ );
63
+ destPath = plugins.path.join(pattern.to, relativePath);
64
+ }
65
+
66
+ // Read source content
67
+ const content = (await plugins.smartfs
68
+ .file(sourcePath)
69
+ .encoding('utf8')
70
+ .read()) as string;
71
+
72
+ // Check if destination exists and has same content
73
+ let needsCopy = true;
74
+ const destExists = await plugins.smartfs.file(destPath).exists();
75
+ if (destExists) {
76
+ const existingContent = (await plugins.smartfs
77
+ .file(destPath)
78
+ .encoding('utf8')
79
+ .read()) as string;
80
+ if (existingContent === content) {
81
+ needsCopy = false;
82
+ }
83
+ }
84
+
85
+ if (needsCopy) {
86
+ changes.push({
87
+ type: destExists ? 'modify' : 'create',
88
+ path: destPath,
89
+ module: this.name,
90
+ description: `Copy from ${sourcePath}`,
91
+ content: content,
92
+ });
93
+ }
94
+ }
95
+ } catch (error) {
96
+ logVerbose(`Failed to process pattern ${pattern.from}: ${error.message}`);
97
+ }
98
+ }
99
+
100
+ return changes;
101
+ }
102
+
103
+ async applyChange(change: IPlannedChange): Promise<void> {
104
+ if (!change.content) return;
105
+
106
+ // Ensure destination directory exists
107
+ const destDir = plugins.path.dirname(change.path);
108
+ await plugins.smartfs.directory(destDir).recursive().create();
109
+
110
+ if (change.type === 'create') {
111
+ await this.createFile(change.path, change.content);
112
+ } else {
113
+ await this.modifyFile(change.path, change.content);
114
+ }
115
+ logger.log('info', `Copied to ${change.path}`);
7
116
  }
8
117
  }
@@ -1,8 +1,111 @@
1
- import { LegacyFormatter } from './legacy.formatter.js';
2
- import * as formatGitignore from '../format.gitignore.js';
1
+ import { BaseFormatter } from '../classes.baseformatter.js';
2
+ import type { IPlannedChange } from '../interfaces.format.js';
3
+ import * as plugins from '../mod.plugins.js';
4
+ import { logger } from '../../gitzone.logging.js';
3
5
 
4
- export class GitignoreFormatter extends LegacyFormatter {
5
- constructor(context: any, project: any) {
6
- super(context, project, 'gitignore', formatGitignore);
6
+ // Standard gitignore template content (without front-matter)
7
+ const GITIGNORE_TEMPLATE = `.nogit/
8
+
9
+ # artifacts
10
+ coverage/
11
+ public/
12
+
13
+ # installs
14
+ node_modules/
15
+
16
+ # caches
17
+ .yarn/
18
+ .cache/
19
+ .rpt2_cache
20
+
21
+ # builds
22
+ dist/
23
+ dist_*/
24
+
25
+ # AI
26
+ .claude/
27
+ .serena/
28
+
29
+ #------# custom`;
30
+
31
+ export class GitignoreFormatter extends BaseFormatter {
32
+ get name(): string {
33
+ return 'gitignore';
34
+ }
35
+
36
+ async analyze(): Promise<IPlannedChange[]> {
37
+ const changes: IPlannedChange[] = [];
38
+ const gitignorePath = '.gitignore';
39
+
40
+ // Check if file exists and extract custom content
41
+ let customContent = '';
42
+ const exists = await plugins.smartfs.file(gitignorePath).exists();
43
+
44
+ if (exists) {
45
+ const existingContent = (await plugins.smartfs
46
+ .file(gitignorePath)
47
+ .encoding('utf8')
48
+ .read()) as string;
49
+
50
+ // Extract custom section content
51
+ const customMarkers = ['#------# custom', '# custom'];
52
+ for (const marker of customMarkers) {
53
+ const splitResult = existingContent.split(marker);
54
+ if (splitResult.length > 1) {
55
+ customContent = splitResult[1].trim();
56
+ break;
57
+ }
58
+ }
59
+ }
60
+
61
+ // Compute new content
62
+ let newContent = GITIGNORE_TEMPLATE;
63
+ if (customContent) {
64
+ newContent = GITIGNORE_TEMPLATE + '\n' + customContent + '\n';
65
+ } else {
66
+ newContent = GITIGNORE_TEMPLATE + '\n';
67
+ }
68
+
69
+ // Read current content to compare
70
+ let currentContent = '';
71
+ if (exists) {
72
+ currentContent = (await plugins.smartfs
73
+ .file(gitignorePath)
74
+ .encoding('utf8')
75
+ .read()) as string;
76
+ }
77
+
78
+ // Determine change type
79
+ if (!exists) {
80
+ changes.push({
81
+ type: 'create',
82
+ path: gitignorePath,
83
+ module: this.name,
84
+ description: 'Create .gitignore',
85
+ content: newContent,
86
+ });
87
+ } else if (newContent !== currentContent) {
88
+ changes.push({
89
+ type: 'modify',
90
+ path: gitignorePath,
91
+ module: this.name,
92
+ description: 'Update .gitignore (preserving custom section)',
93
+ content: newContent,
94
+ });
95
+ }
96
+
97
+ return changes;
98
+ }
99
+
100
+ async applyChange(change: IPlannedChange): Promise<void> {
101
+ if (!change.content) return;
102
+
103
+ if (change.type === 'create') {
104
+ await this.createFile(change.path, change.content);
105
+ logger.log('info', 'Created .gitignore');
106
+ } else if (change.type === 'modify') {
107
+ await this.modifyFile(change.path, change.content);
108
+ logger.log('info', 'Updated .gitignore (preserved custom section)');
109
+ }
7
110
  }
8
111
  }
@@ -1,8 +1,62 @@
1
- import { LegacyFormatter } from './legacy.formatter.js';
2
- import * as formatLicense from '../format.license.js';
1
+ import { BaseFormatter } from '../classes.baseformatter.js';
2
+ import type { IPlannedChange } from '../interfaces.format.js';
3
+ import * as plugins from '../mod.plugins.js';
4
+ import * as paths from '../../paths.js';
5
+ import { logger } from '../../gitzone.logging.js';
3
6
 
4
- export class LicenseFormatter extends LegacyFormatter {
5
- constructor(context: any, project: any) {
6
- super(context, project, 'license', formatLicense);
7
+ const INCOMPATIBLE_LICENSES: string[] = ['AGPL', 'GPL', 'SSPL'];
8
+
9
+ export class LicenseFormatter extends BaseFormatter {
10
+ get name(): string {
11
+ return 'license';
12
+ }
13
+
14
+ async analyze(): Promise<IPlannedChange[]> {
15
+ // License formatter only checks for incompatible licenses
16
+ // It does not modify any files, so return empty array
17
+ // The actual check happens in execute() for reporting purposes
18
+ return [];
19
+ }
20
+
21
+ async execute(changes: IPlannedChange[]): Promise<void> {
22
+ const startTime = this.stats.moduleStartTime(this.name);
23
+ this.stats.startModule(this.name);
24
+
25
+ try {
26
+ // Check if node_modules exists
27
+ const nodeModulesPath = plugins.path.join(paths.cwd, 'node_modules');
28
+ const nodeModulesExists = await plugins.smartfs
29
+ .directory(nodeModulesPath)
30
+ .exists();
31
+
32
+ if (!nodeModulesExists) {
33
+ logger.log('warn', 'No node_modules found. Skipping license check');
34
+ return;
35
+ }
36
+
37
+ // Run license check
38
+ const licenseChecker = await plugins.smartlegal.createLicenseChecker();
39
+ const licenseCheckResult = await licenseChecker.excludeLicenseWithinPath(
40
+ paths.cwd,
41
+ INCOMPATIBLE_LICENSES,
42
+ );
43
+
44
+ if (licenseCheckResult.failingModules.length === 0) {
45
+ logger.log('info', 'License check passed - no incompatible licenses found');
46
+ } else {
47
+ logger.log('error', 'License check failed - incompatible licenses found:');
48
+ for (const failedModule of licenseCheckResult.failingModules) {
49
+ console.log(
50
+ ` ${failedModule.name} has license ${failedModule.license}`,
51
+ );
52
+ }
53
+ }
54
+ } finally {
55
+ this.stats.endModule(this.name, startTime);
56
+ }
57
+ }
58
+
59
+ async applyChange(change: IPlannedChange): Promise<void> {
60
+ // No file changes for license formatter
7
61
  }
8
62
  }
@@ -1,8 +1,165 @@
1
- import { LegacyFormatter } from './legacy.formatter.js';
2
- import * as formatNpmextra from '../format.npmextra.js';
1
+ import { BaseFormatter } from '../classes.baseformatter.js';
2
+ import type { IPlannedChange } from '../interfaces.format.js';
3
+ import * as plugins from '../mod.plugins.js';
4
+ import { logger, logVerbose } from '../../gitzone.logging.js';
3
5
 
4
- export class NpmextraFormatter extends LegacyFormatter {
5
- constructor(context: any, project: any) {
6
- super(context, project, 'npmextra', formatNpmextra);
6
+ /**
7
+ * Migrates npmextra.json from old namespace keys to new package-scoped keys
8
+ */
9
+ const migrateNamespaceKeys = (npmextraJson: any): boolean => {
10
+ let migrated = false;
11
+ const migrations = [
12
+ { oldKey: 'gitzone', newKey: '@git.zone/cli' },
13
+ { oldKey: 'tsdoc', newKey: '@git.zone/tsdoc' },
14
+ { oldKey: 'npmdocker', newKey: '@git.zone/tsdocker' },
15
+ { oldKey: 'npmci', newKey: '@ship.zone/szci' },
16
+ { oldKey: 'szci', newKey: '@ship.zone/szci' },
17
+ ];
18
+ for (const { oldKey, newKey } of migrations) {
19
+ if (npmextraJson[oldKey] && !npmextraJson[newKey]) {
20
+ npmextraJson[newKey] = npmextraJson[oldKey];
21
+ delete npmextraJson[oldKey];
22
+ migrated = true;
23
+ }
24
+ }
25
+ return migrated;
26
+ };
27
+
28
+ /**
29
+ * Migrates npmAccessLevel from @ship.zone/szci to @git.zone/cli.release.accessLevel
30
+ */
31
+ const migrateAccessLevel = (npmextraJson: any): boolean => {
32
+ const szciConfig = npmextraJson['@ship.zone/szci'];
33
+
34
+ if (!szciConfig?.npmAccessLevel) {
35
+ return false;
36
+ }
37
+
38
+ const gitzoneConfig = npmextraJson['@git.zone/cli'] || {};
39
+ if (gitzoneConfig?.release?.accessLevel) {
40
+ delete szciConfig.npmAccessLevel;
41
+ return true;
42
+ }
43
+
44
+ if (!npmextraJson['@git.zone/cli']) {
45
+ npmextraJson['@git.zone/cli'] = {};
46
+ }
47
+ if (!npmextraJson['@git.zone/cli'].release) {
48
+ npmextraJson['@git.zone/cli'].release = {};
49
+ }
50
+
51
+ npmextraJson['@git.zone/cli'].release.accessLevel = szciConfig.npmAccessLevel;
52
+ delete szciConfig.npmAccessLevel;
53
+
54
+ return true;
55
+ };
56
+
57
+ export class NpmextraFormatter extends BaseFormatter {
58
+ get name(): string {
59
+ return 'npmextra';
60
+ }
61
+
62
+ async analyze(): Promise<IPlannedChange[]> {
63
+ const changes: IPlannedChange[] = [];
64
+ const npmextraPath = 'npmextra.json';
65
+
66
+ // Check if file exists
67
+ const exists = await plugins.smartfs.file(npmextraPath).exists();
68
+ if (!exists) {
69
+ logVerbose('npmextra.json does not exist, skipping');
70
+ return changes;
71
+ }
72
+
73
+ // Read current content
74
+ const currentContent = (await plugins.smartfs
75
+ .file(npmextraPath)
76
+ .encoding('utf8')
77
+ .read()) as string;
78
+
79
+ // Parse and compute new content
80
+ const npmextraJson = JSON.parse(currentContent);
81
+
82
+ // Apply migrations (these are automatic, non-interactive)
83
+ migrateNamespaceKeys(npmextraJson);
84
+ migrateAccessLevel(npmextraJson);
85
+
86
+ // Ensure namespaces exist
87
+ if (!npmextraJson['@git.zone/cli']) {
88
+ npmextraJson['@git.zone/cli'] = {};
89
+ }
90
+ if (!npmextraJson['@ship.zone/szci']) {
91
+ npmextraJson['@ship.zone/szci'] = {};
92
+ }
93
+
94
+ const newContent = JSON.stringify(npmextraJson, null, 2);
95
+
96
+ // Only add change if content differs
97
+ if (newContent !== currentContent) {
98
+ changes.push({
99
+ type: 'modify',
100
+ path: npmextraPath,
101
+ module: this.name,
102
+ description: 'Migrate and format npmextra.json',
103
+ content: newContent,
104
+ });
105
+ }
106
+
107
+ return changes;
108
+ }
109
+
110
+ async applyChange(change: IPlannedChange): Promise<void> {
111
+ if (change.type !== 'modify' || !change.content) return;
112
+
113
+ // Parse the content to check for missing required fields
114
+ const npmextraJson = JSON.parse(change.content);
115
+
116
+ // Check for missing required module information
117
+ const expectedRepoInformation: string[] = [
118
+ 'projectType',
119
+ 'module.githost',
120
+ 'module.gitscope',
121
+ 'module.gitrepo',
122
+ 'module.description',
123
+ 'module.npmPackagename',
124
+ 'module.license',
125
+ ];
126
+
127
+ const interactInstance = new plugins.smartinteract.SmartInteract();
128
+ for (const expectedRepoInformationItem of expectedRepoInformation) {
129
+ if (
130
+ !plugins.smartobject.smartGet(
131
+ npmextraJson['@git.zone/cli'],
132
+ expectedRepoInformationItem,
133
+ )
134
+ ) {
135
+ interactInstance.addQuestions([
136
+ {
137
+ message: `What is the value of ${expectedRepoInformationItem}`,
138
+ name: expectedRepoInformationItem,
139
+ type: 'input',
140
+ default: 'undefined variable',
141
+ },
142
+ ]);
143
+ }
144
+ }
145
+
146
+ const answerbucket = await interactInstance.runQueue();
147
+ for (const expectedRepoInformationItem of expectedRepoInformation) {
148
+ const cliProvidedValue = answerbucket.getAnswerFor(
149
+ expectedRepoInformationItem,
150
+ );
151
+ if (cliProvidedValue) {
152
+ plugins.smartobject.smartAdd(
153
+ npmextraJson['@git.zone/cli'],
154
+ expectedRepoInformationItem,
155
+ cliProvidedValue,
156
+ );
157
+ }
158
+ }
159
+
160
+ // Write the final content
161
+ const finalContent = JSON.stringify(npmextraJson, null, 2);
162
+ await this.modifyFile(change.path, finalContent);
163
+ logger.log('info', 'Updated npmextra.json');
7
164
  }
8
165
  }