@produck/agent-toolkit 0.9.0 → 0.9.2
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/bin/command/sync-coverage/index.mjs +7 -2
- package/bin/command/sync-git/help.txt +1 -1
- package/bin/command/sync-git/index.mjs +15 -4
- package/bin/command/sync-install/index.mjs +1 -1
- package/bin/command/sync-lint/eslint.config.template.mjs +3 -16
- package/bin/command/sync-lint/index.mjs +80 -40
- package/bin/command/sync-publish/index.mjs +9 -4
- package/package.json +3 -3
- package/publish-assets/eslint.config.template.mjs +3 -16
- package/publish-assets/instructions/produck/tooling-version-baseline.json +1 -1
|
@@ -21,8 +21,13 @@ const TOOLING_BASELINE_CANDIDATE_PATHS = [
|
|
|
21
21
|
];
|
|
22
22
|
const GLOB_TOKEN_PATTERN = /[*?{}[\]]/;
|
|
23
23
|
const REQUIRED_ROOT_COVERAGE_SCRIPT_KEY = 'produck:coverage';
|
|
24
|
-
const REQUIRED_ROOT_COVERAGE_SCRIPT_VALUE =
|
|
25
|
-
'c8
|
|
24
|
+
const REQUIRED_ROOT_COVERAGE_SCRIPT_VALUE = [
|
|
25
|
+
'c8',
|
|
26
|
+
'--config .c8rc.json',
|
|
27
|
+
'npm run test',
|
|
28
|
+
'--workspaces',
|
|
29
|
+
'--if-present',
|
|
30
|
+
].join(' ');
|
|
26
31
|
const REQUIRED_COVERAGE_SCRIPT_KEY = 'produck:coverage';
|
|
27
32
|
const REQUIRED_TEST_SCRIPT_KEY = 'test';
|
|
28
33
|
const DEFAULT_TEST_SCRIPT_VALUE =
|
|
@@ -4,7 +4,7 @@ Usage:
|
|
|
4
4
|
|
|
5
5
|
Behavior:
|
|
6
6
|
- Applies organization-required root shared scripts:
|
|
7
|
-
- scripts.produck:baseline = npm exec --package=@produck/agent-toolkit@latest -- agent-toolkit enforce-node-baseline --cwd .
|
|
7
|
+
- scripts.produck:baseline = npm exec --package=@produck/agent-toolkit@latest -- agent-toolkit enforce-node-baseline --cwd . && npm run produck:install
|
|
8
8
|
- scripts.produck:commit:check = npm run produck:format && npm run produck:lint
|
|
9
9
|
- scripts.prepare = husky
|
|
10
10
|
- Applies organization-required root shared managed devDependencies:
|
|
@@ -29,11 +29,22 @@ const HUSKY_DIR = '.husky';
|
|
|
29
29
|
const PRE_COMMIT_HOOK_FILE = 'pre-commit';
|
|
30
30
|
const COMMIT_MSG_HOOK_FILE = 'commit-msg';
|
|
31
31
|
const REQUIRED_BASELINE_SCRIPT_KEY = 'produck:baseline';
|
|
32
|
-
const REQUIRED_BASELINE_SCRIPT_VALUE =
|
|
33
|
-
|
|
32
|
+
const REQUIRED_BASELINE_SCRIPT_VALUE = [
|
|
33
|
+
[
|
|
34
|
+
'npm exec',
|
|
35
|
+
'--package=@produck/agent-toolkit@latest',
|
|
36
|
+
'--',
|
|
37
|
+
'agent-toolkit',
|
|
38
|
+
'enforce-node-baseline',
|
|
39
|
+
'--cwd .',
|
|
40
|
+
].join(' '),
|
|
41
|
+
'npm run produck:install',
|
|
42
|
+
].join(' && ');
|
|
34
43
|
const REQUIRED_COMMIT_CHECK_SCRIPT_KEY = 'produck:commit:check';
|
|
35
|
-
const REQUIRED_COMMIT_CHECK_SCRIPT_VALUE =
|
|
36
|
-
'npm run produck:format
|
|
44
|
+
const REQUIRED_COMMIT_CHECK_SCRIPT_VALUE = [
|
|
45
|
+
'npm run produck:format',
|
|
46
|
+
'npm run produck:lint',
|
|
47
|
+
].join(' && ');
|
|
37
48
|
const REQUIRED_PREPARE_SCRIPT_KEY = 'prepare';
|
|
38
49
|
const REQUIRED_PREPARE_SCRIPT_VALUE = 'husky';
|
|
39
50
|
|
|
@@ -9,7 +9,7 @@ const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
|
9
9
|
const HELP_FILE = path.resolve(COMMAND_DIR, 'help.txt');
|
|
10
10
|
const LEGACY_INSTALL_SCRIPT_KEY = 'deps:install';
|
|
11
11
|
const REQUIRED_INSTALL_SCRIPT_KEY = 'produck:install';
|
|
12
|
-
const REQUIRED_INSTALL_SCRIPT_VALUE = 'npm -v
|
|
12
|
+
const REQUIRED_INSTALL_SCRIPT_VALUE = ['npm -v', 'npm install'].join(' && ');
|
|
13
13
|
|
|
14
14
|
export function printSyncInstallHelp() {
|
|
15
15
|
printTextResource(HELP_FILE);
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import js from '@eslint/js';
|
|
2
2
|
import globals from 'globals';
|
|
3
3
|
import tseslint from 'typescript-eslint';
|
|
4
|
-
import json from '@eslint/json';
|
|
5
|
-
import markdown from '@eslint/markdown';
|
|
6
4
|
import { defineConfig } from 'eslint/config';
|
|
7
5
|
import * as ProduckRule from '@produck/eslint-rules';
|
|
8
6
|
|
|
@@ -14,19 +12,8 @@ export default defineConfig([
|
|
|
14
12
|
languageOptions: { globals: { ...globals.browser, ...globals.node } },
|
|
15
13
|
},
|
|
16
14
|
tseslint.configs.recommended,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
plugins: { json },
|
|
21
|
-
language: 'json/json',
|
|
22
|
-
extends: ['json/recommended'],
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
files: ['**/*.md'],
|
|
26
|
-
plugins: { markdown },
|
|
27
|
-
language: 'markdown/gfm',
|
|
28
|
-
extends: ['markdown/recommended'],
|
|
29
|
-
},
|
|
30
|
-
ProduckRule.config,
|
|
15
|
+
ProduckRule.config.ecma,
|
|
16
|
+
ProduckRule.config.json,
|
|
17
|
+
ProduckRule.config.markdown,
|
|
31
18
|
ProduckRule.excludeGitIgnore(import.meta.url),
|
|
32
19
|
]);
|
|
@@ -21,6 +21,12 @@ const TOOLING_BASELINE_CANDIDATE_PATHS = [
|
|
|
21
21
|
];
|
|
22
22
|
const ESLINT_RULES_PACKAGE_NAME = '@produck/eslint-rules';
|
|
23
23
|
const ESLINT_CONFIG_FILE = 'eslint.config.mjs';
|
|
24
|
+
const REQUIRED_ESLINT_ENTRIES = [
|
|
25
|
+
'ProduckRule.config.ecma',
|
|
26
|
+
'ProduckRule.config.json',
|
|
27
|
+
'ProduckRule.config.markdown',
|
|
28
|
+
'ProduckRule.excludeGitIgnore(import.meta.url)',
|
|
29
|
+
];
|
|
24
30
|
|
|
25
31
|
const REQUIRED_LINT_SCRIPT_KEY = 'produck:lint';
|
|
26
32
|
const REQUIRED_LINT_SCRIPT_VALUE = 'eslint --fix . --max-warnings=0';
|
|
@@ -54,16 +60,27 @@ function readFileIfExists(filePath) {
|
|
|
54
60
|
return fs.readFileSync(filePath, 'utf8');
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
const ESLINT_TOOLING_PACKAGE_NAMES = [
|
|
64
|
+
'eslint',
|
|
65
|
+
'@eslint/js',
|
|
66
|
+
'@eslint/json',
|
|
67
|
+
'@eslint/markdown',
|
|
68
|
+
'@eslint/config-helpers',
|
|
69
|
+
'typescript-eslint',
|
|
70
|
+
'globals',
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
function getRequiredEslintDevDependencies() {
|
|
74
|
+
// Prefer the in-tree source of truth for @produck/eslint-rules: when
|
|
75
|
+
// sync-lint runs inside the monorepo, eslint-rules/package.json is
|
|
76
|
+
// authoritative. When running as an installed dependency, fall back to the
|
|
77
|
+
// publish-assets tooling baseline.
|
|
63
78
|
const inTreeEslintRulesPkgPath = path.resolve(
|
|
64
79
|
REPO_ROOT,
|
|
65
80
|
'packages/eslint-rules/package.json',
|
|
66
81
|
);
|
|
82
|
+
|
|
83
|
+
let eslintRulesVersion = '';
|
|
67
84
|
if (fs.existsSync(inTreeEslintRulesPkgPath)) {
|
|
68
85
|
const eslintRulesPkg = parseJsonFile(
|
|
69
86
|
inTreeEslintRulesPkgPath,
|
|
@@ -71,13 +88,13 @@ function getRequiredEslintRulesDevDependency() {
|
|
|
71
88
|
);
|
|
72
89
|
// The '' fallback is for when the in-tree package.json has a non-string
|
|
73
90
|
// version field, which never occurs for this package.
|
|
74
|
-
const
|
|
91
|
+
const v =
|
|
75
92
|
typeof eslintRulesPkg.version === 'string'
|
|
76
93
|
? eslintRulesPkg.version.trim()
|
|
77
94
|
: /* c8 ignore next */
|
|
78
95
|
'';
|
|
79
|
-
if (
|
|
80
|
-
|
|
96
|
+
if (v) {
|
|
97
|
+
eslintRulesVersion = v;
|
|
81
98
|
}
|
|
82
99
|
}
|
|
83
100
|
|
|
@@ -87,9 +104,9 @@ function getRequiredEslintRulesDevDependency() {
|
|
|
87
104
|
},
|
|
88
105
|
);
|
|
89
106
|
|
|
107
|
+
/* c8 ignore next 7 */
|
|
90
108
|
if (!toolingBaselinePath) {
|
|
91
|
-
console.error('Cannot resolve
|
|
92
|
-
console.error(`- ${inTreeEslintRulesPkgPath}`);
|
|
109
|
+
console.error('Cannot resolve ESLint tooling versions. Looked at:');
|
|
93
110
|
for (const candidatePath of TOOLING_BASELINE_CANDIDATE_PATHS) {
|
|
94
111
|
console.error(`- ${candidatePath}`);
|
|
95
112
|
}
|
|
@@ -97,21 +114,40 @@ function getRequiredEslintRulesDevDependency() {
|
|
|
97
114
|
}
|
|
98
115
|
|
|
99
116
|
const baseline = parseJsonFile(toolingBaselinePath, 'Tooling baseline file');
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
|
|
118
|
+
/* c8 ignore next 12 */
|
|
119
|
+
if (!eslintRulesVersion) {
|
|
120
|
+
const entry = baseline?.tools?.[ESLINT_RULES_PACKAGE_NAME];
|
|
121
|
+
const v = typeof entry?.version === 'string' ? entry.version.trim() : '';
|
|
122
|
+
if (!v) {
|
|
123
|
+
console.error(
|
|
124
|
+
`Tooling baseline tools["${ESLINT_RULES_PACKAGE_NAME}"].version must be a non-empty string: ${toolingBaselinePath}`,
|
|
125
|
+
);
|
|
126
|
+
process.exit(2);
|
|
127
|
+
}
|
|
128
|
+
eslintRulesVersion = v;
|
|
112
129
|
}
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
const deps = { [ESLINT_RULES_PACKAGE_NAME]: eslintRulesVersion };
|
|
132
|
+
|
|
133
|
+
for (const name of ESLINT_TOOLING_PACKAGE_NAMES) {
|
|
134
|
+
const entry = baseline?.tools?.[name];
|
|
135
|
+
const v =
|
|
136
|
+
typeof entry?.version === 'string'
|
|
137
|
+
? entry.version.trim()
|
|
138
|
+
: /* c8 ignore next */
|
|
139
|
+
'';
|
|
140
|
+
/* c8 ignore next 6 */
|
|
141
|
+
if (!v) {
|
|
142
|
+
console.error(
|
|
143
|
+
`Tooling baseline tools["${name}"].version must be a non-empty string: ${toolingBaselinePath}`,
|
|
144
|
+
);
|
|
145
|
+
process.exit(2);
|
|
146
|
+
}
|
|
147
|
+
deps[name] = v;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return deps;
|
|
115
151
|
}
|
|
116
152
|
|
|
117
153
|
function patchEslintConfig(existing) {
|
|
@@ -139,7 +175,7 @@ function patchEslintConfig(existing) {
|
|
|
139
175
|
}
|
|
140
176
|
|
|
141
177
|
output =
|
|
142
|
-
`${output.slice(0, exportEnd)} ProduckRule.config,\n ProduckRule.excludeGitIgnore(import.meta.url),\n` +
|
|
178
|
+
`${output.slice(0, exportEnd)} ProduckRule.config.ecma,\n ProduckRule.config.json,\n ProduckRule.config.markdown,\n ProduckRule.excludeGitIgnore(import.meta.url),\n` +
|
|
143
179
|
output.slice(exportEnd);
|
|
144
180
|
|
|
145
181
|
if (!output.endsWith('\n')) {
|
|
@@ -186,19 +222,15 @@ export function runSyncLint(options) {
|
|
|
186
222
|
typeof scripts[REQUIRED_LINT_SCRIPT_KEY] === 'string'
|
|
187
223
|
? scripts[REQUIRED_LINT_SCRIPT_KEY]
|
|
188
224
|
: null;
|
|
189
|
-
const
|
|
190
|
-
typeof devDependencies['@produck/eslint-rules'] === 'string'
|
|
191
|
-
? devDependencies['@produck/eslint-rules']
|
|
192
|
-
: null;
|
|
193
|
-
|
|
194
|
-
const requiredEslintRulesDependency = getRequiredEslintRulesDevDependency();
|
|
225
|
+
const requiredEslintDevDeps = getRequiredEslintDevDependencies();
|
|
195
226
|
|
|
196
227
|
const eslintConfigPath = path.resolve(cwd, ESLINT_CONFIG_FILE);
|
|
197
228
|
const previousEslintConfig = readFileIfExists(eslintConfigPath);
|
|
198
229
|
|
|
199
230
|
const matchesRequiredLint = previousLint === REQUIRED_LINT_SCRIPT_VALUE;
|
|
200
|
-
const
|
|
201
|
-
|
|
231
|
+
const matchesRequiredEslintDeps = Object.entries(requiredEslintDevDeps).every(
|
|
232
|
+
([name, version]) => devDependencies[name] === version,
|
|
233
|
+
);
|
|
202
234
|
|
|
203
235
|
let eslintConfigAction = 'unchanged';
|
|
204
236
|
let matchesRequiredEslintConfig = false;
|
|
@@ -209,8 +241,14 @@ export function runSyncLint(options) {
|
|
|
209
241
|
nextEslintConfigText = REQUIRED_ESLINT_CONFIG;
|
|
210
242
|
} else if (previousEslintConfig === REQUIRED_ESLINT_CONFIG) {
|
|
211
243
|
matchesRequiredEslintConfig = true;
|
|
212
|
-
} else if (
|
|
244
|
+
} else if (
|
|
245
|
+
previousEslintConfig.includes(ESLINT_RULES_PACKAGE_NAME) &&
|
|
246
|
+
REQUIRED_ESLINT_ENTRIES.every((e) => previousEslintConfig.includes(e))
|
|
247
|
+
) {
|
|
213
248
|
matchesRequiredEslintConfig = true;
|
|
249
|
+
} else if (previousEslintConfig.includes(ESLINT_RULES_PACKAGE_NAME)) {
|
|
250
|
+
eslintConfigAction = 'replaced';
|
|
251
|
+
nextEslintConfigText = REQUIRED_ESLINT_CONFIG;
|
|
214
252
|
} else {
|
|
215
253
|
const patched = patchEslintConfig(previousEslintConfig);
|
|
216
254
|
if (patched.ok) {
|
|
@@ -223,7 +261,7 @@ export function runSyncLint(options) {
|
|
|
223
261
|
|
|
224
262
|
const requiresUpdate =
|
|
225
263
|
!matchesRequiredLint ||
|
|
226
|
-
!
|
|
264
|
+
!matchesRequiredEslintDeps ||
|
|
227
265
|
!matchesRequiredEslintConfig;
|
|
228
266
|
const hasUnpatchableEslintConfig = eslintConfigAction === 'unpatchable';
|
|
229
267
|
|
|
@@ -231,7 +269,9 @@ export function runSyncLint(options) {
|
|
|
231
269
|
scripts[REQUIRED_LINT_SCRIPT_KEY] = REQUIRED_LINT_SCRIPT_VALUE;
|
|
232
270
|
pkg.scripts = scripts;
|
|
233
271
|
|
|
234
|
-
|
|
272
|
+
for (const [name, version] of Object.entries(requiredEslintDevDeps)) {
|
|
273
|
+
devDependencies[name] = version;
|
|
274
|
+
}
|
|
235
275
|
pkg.devDependencies = devDependencies;
|
|
236
276
|
|
|
237
277
|
fs.writeFileSync(
|
|
@@ -257,22 +297,22 @@ export function runSyncLint(options) {
|
|
|
257
297
|
required: {
|
|
258
298
|
lintScriptKey: REQUIRED_LINT_SCRIPT_KEY,
|
|
259
299
|
lintScriptValue: REQUIRED_LINT_SCRIPT_VALUE,
|
|
260
|
-
|
|
300
|
+
eslintDevDependencies: requiredEslintDevDeps,
|
|
261
301
|
eslintConfigPath: path.relative(cwd, eslintConfigPath),
|
|
262
302
|
eslintConfigAction,
|
|
263
303
|
},
|
|
264
304
|
status: {
|
|
265
305
|
matchesRequiredLintBefore: matchesRequiredLint,
|
|
266
|
-
|
|
306
|
+
matchesRequiredEslintDepsBefore: matchesRequiredEslintDeps,
|
|
267
307
|
matchesRequiredEslintConfigBefore: matchesRequiredEslintConfig,
|
|
268
308
|
matchesRequiredLintAfter:
|
|
269
309
|
requiresUpdate && mode === 'sync' && !hasUnpatchableEslintConfig
|
|
270
310
|
? true
|
|
271
311
|
: matchesRequiredLint,
|
|
272
|
-
|
|
312
|
+
matchesRequiredEslintDepsAfter:
|
|
273
313
|
requiresUpdate && mode === 'sync' && !hasUnpatchableEslintConfig
|
|
274
314
|
? true
|
|
275
|
-
:
|
|
315
|
+
: matchesRequiredEslintDeps,
|
|
276
316
|
matchesRequiredEslintConfigAfter:
|
|
277
317
|
requiresUpdate && mode === 'sync' && !hasUnpatchableEslintConfig
|
|
278
318
|
? true
|
|
@@ -16,11 +16,16 @@ const LERNA_TEMPLATE_CANDIDATE_PATHS = [
|
|
|
16
16
|
];
|
|
17
17
|
|
|
18
18
|
const REQUIRED_PUBLISH_CHECK_SCRIPT_KEY = 'produck:publish:check';
|
|
19
|
-
const REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE =
|
|
20
|
-
'npm run produck:install
|
|
19
|
+
const REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE = [
|
|
20
|
+
'npm run produck:install',
|
|
21
|
+
'npm run produck:coverage',
|
|
22
|
+
'npm run produck:commit:check',
|
|
23
|
+
].join(' && ');
|
|
21
24
|
const REQUIRED_PUBLISH_SCRIPT_KEY = 'produck:publish';
|
|
22
|
-
const REQUIRED_PUBLISH_SCRIPT_VALUE =
|
|
23
|
-
'npm run produck:publish:check
|
|
25
|
+
const REQUIRED_PUBLISH_SCRIPT_VALUE = [
|
|
26
|
+
'npm run produck:publish:check',
|
|
27
|
+
'npm run publish --',
|
|
28
|
+
].join(' && ');
|
|
24
29
|
const REQUIRED_LERNA_VERSION_COMMIT_HOOKS = false;
|
|
25
30
|
|
|
26
31
|
export function printSyncPublishHelp() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produck/agent-toolkit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Central CLI toolkit for organization AI execution workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@produck/eslint-rules": "^0.
|
|
32
|
+
"@produck/eslint-rules": "^0.4.0",
|
|
33
33
|
"c8": "11.0.0"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "aa9500630476fb423720f0b0056096e0e87e4c21"
|
|
36
36
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import js from '@eslint/js';
|
|
2
2
|
import globals from 'globals';
|
|
3
3
|
import tseslint from 'typescript-eslint';
|
|
4
|
-
import json from '@eslint/json';
|
|
5
|
-
import markdown from '@eslint/markdown';
|
|
6
4
|
import { defineConfig } from 'eslint/config';
|
|
7
5
|
import * as ProduckRule from '@produck/eslint-rules';
|
|
8
6
|
|
|
@@ -14,19 +12,8 @@ export default defineConfig([
|
|
|
14
12
|
languageOptions: { globals: { ...globals.browser, ...globals.node } },
|
|
15
13
|
},
|
|
16
14
|
tseslint.configs.recommended,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
plugins: { json },
|
|
21
|
-
language: 'json/json',
|
|
22
|
-
extends: ['json/recommended'],
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
files: ['**/*.md'],
|
|
26
|
-
plugins: { markdown },
|
|
27
|
-
language: 'markdown/gfm',
|
|
28
|
-
extends: ['markdown/recommended'],
|
|
29
|
-
},
|
|
30
|
-
ProduckRule.config,
|
|
15
|
+
ProduckRule.config.ecma,
|
|
16
|
+
ProduckRule.config.json,
|
|
17
|
+
ProduckRule.config.markdown,
|
|
31
18
|
ProduckRule.excludeGitIgnore(import.meta.url),
|
|
32
19
|
]);
|