@produck/agent-toolkit 0.8.0 → 0.8.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.
@@ -6,6 +6,7 @@ Behavior:
6
6
  - Applies organization-required root shared scripts:
7
7
  - scripts.produck:baseline = npm exec --package=@produck/agent-toolkit@latest -- agent-toolkit enforce-node-baseline --cwd .
8
8
  - scripts.produck:commit:check = npm run produck:format && npm run produck:lint
9
+ - scripts.prepare = husky
9
10
  - Applies organization-required root shared managed devDependencies:
10
11
  - devDependencies.husky = <fixed-version-from-baseline>
11
12
  - devDependencies.lerna = <fixed-version-from-baseline>
@@ -27,6 +27,8 @@ const REQUIRED_BASELINE_SCRIPT_VALUE =
27
27
  'npm exec --package=@produck/agent-toolkit@latest -- agent-toolkit enforce-node-baseline --cwd .';
28
28
  const REQUIRED_COMMIT_CHECK_SCRIPT_KEY = 'produck:commit:check';
29
29
  const REQUIRED_COMMIT_CHECK_SCRIPT_VALUE = 'npm run produck:format && npm run produck:lint';
30
+ const REQUIRED_PREPARE_SCRIPT_KEY = 'prepare';
31
+ const REQUIRED_PREPARE_SCRIPT_VALUE = 'husky';
30
32
 
31
33
  const GITATTRIBUTES_SOURCE_CANDIDATE_PATHS = [
32
34
  path.resolve(REPO_ROOT, '.gitattributes'),
@@ -187,6 +189,10 @@ function buildScriptState(pkg) {
187
189
  typeof scripts[REQUIRED_COMMIT_CHECK_SCRIPT_KEY] === 'string'
188
190
  ? scripts[REQUIRED_COMMIT_CHECK_SCRIPT_KEY]
189
191
  : null,
192
+ previousPrepare:
193
+ typeof scripts[REQUIRED_PREPARE_SCRIPT_KEY] === 'string'
194
+ ? scripts[REQUIRED_PREPARE_SCRIPT_KEY]
195
+ : null,
190
196
  };
191
197
  }
192
198
 
@@ -247,6 +253,7 @@ export function runSyncGit(options) {
247
253
  const scriptValidation = validateRequiredExactEntries(scriptState.scripts, {
248
254
  [REQUIRED_BASELINE_SCRIPT_KEY]: REQUIRED_BASELINE_SCRIPT_VALUE,
249
255
  [REQUIRED_COMMIT_CHECK_SCRIPT_KEY]: REQUIRED_COMMIT_CHECK_SCRIPT_VALUE,
256
+ [REQUIRED_PREPARE_SCRIPT_KEY]: REQUIRED_PREPARE_SCRIPT_VALUE,
250
257
  });
251
258
  const dependencyValidation = validateRequiredExactEntries(
252
259
  dependencyState.devDependencies,
@@ -257,6 +264,7 @@ export function runSyncGit(options) {
257
264
  const matchesRequiredCommitCheck = !(
258
265
  REQUIRED_COMMIT_CHECK_SCRIPT_KEY in scriptValidation.mismatches
259
266
  );
267
+ const matchesRequiredPrepare = !(REQUIRED_PREPARE_SCRIPT_KEY in scriptValidation.mismatches);
260
268
  const matchesRequiredManagedDevDependencies = dependencyValidation.ok;
261
269
 
262
270
  const gitAttributesPath = path.resolve(cwd, GITATTRIBUTES_FILE);
@@ -317,6 +325,7 @@ export function runSyncGit(options) {
317
325
  mismatches.length > 0 ||
318
326
  !matchesRequiredBaseline ||
319
327
  !matchesRequiredCommitCheck ||
328
+ !matchesRequiredPrepare ||
320
329
  !matchesRequiredManagedDevDependencies;
321
330
 
322
331
  if (mode === 'sync' && requiresUpdate) {
@@ -337,6 +346,7 @@ export function runSyncGit(options) {
337
346
 
338
347
  scriptState.scripts[REQUIRED_BASELINE_SCRIPT_KEY] = REQUIRED_BASELINE_SCRIPT_VALUE;
339
348
  scriptState.scripts[REQUIRED_COMMIT_CHECK_SCRIPT_KEY] = REQUIRED_COMMIT_CHECK_SCRIPT_VALUE;
349
+ scriptState.scripts[REQUIRED_PREPARE_SCRIPT_KEY] = REQUIRED_PREPARE_SCRIPT_VALUE;
340
350
  pkg.scripts = scriptState.scripts;
341
351
 
342
352
  for (const [name, version] of Object.entries(requiredDevDependencies)) {
@@ -364,6 +374,8 @@ export function runSyncGit(options) {
364
374
  baselineScriptValue: REQUIRED_BASELINE_SCRIPT_VALUE,
365
375
  commitCheckScriptKey: REQUIRED_COMMIT_CHECK_SCRIPT_KEY,
366
376
  commitCheckScriptValue: REQUIRED_COMMIT_CHECK_SCRIPT_VALUE,
377
+ prepareScriptKey: REQUIRED_PREPARE_SCRIPT_KEY,
378
+ prepareScriptValue: REQUIRED_PREPARE_SCRIPT_VALUE,
367
379
  preCommitHookPath: path.relative(cwd, preCommitHookPath),
368
380
  commitMsgHookPath: path.relative(cwd, commitMsgHookPath),
369
381
  managedDevDependencies: requiredDevDependencies,
@@ -380,6 +392,7 @@ export function runSyncGit(options) {
380
392
  matchesRequiredCommitMsgHookBefore: matchesRequiredCommitMsgHook,
381
393
  matchesRequiredBaselineBefore: matchesRequiredBaseline,
382
394
  matchesRequiredCommitCheckBefore: matchesRequiredCommitCheck,
395
+ matchesRequiredPrepareBefore: matchesRequiredPrepare,
383
396
  matchesRequiredManagedDevDependenciesBefore: matchesRequiredManagedDevDependencies,
384
397
  mismatchesBefore: mismatches,
385
398
  fileExistsAfter: requiresUpdate && mode === 'sync' ? true : fileExists,
@@ -400,6 +413,8 @@ export function runSyncGit(options) {
400
413
  requiresUpdate && mode === 'sync' ? true : matchesRequiredBaseline,
401
414
  matchesRequiredCommitCheckAfter:
402
415
  requiresUpdate && mode === 'sync' ? true : matchesRequiredCommitCheck,
416
+ matchesRequiredPrepareAfter:
417
+ requiresUpdate && mode === 'sync' ? true : matchesRequiredPrepare,
403
418
  matchesRequiredManagedDevDependenciesAfter:
404
419
  requiresUpdate && mode === 'sync' ? true : matchesRequiredManagedDevDependencies,
405
420
  mismatchesAfter: requiresUpdate && mode === 'sync' ? [] : mismatches,
@@ -1,6 +1,5 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { spawnSync } from 'node:child_process';
4
3
  import { fileURLToPath } from 'node:url';
5
4
 
6
5
  import { getSingle, hasFlag } from '../shared/args.mjs';
@@ -9,7 +8,12 @@ import { printTextResource } from '../shared/text-resource.mjs';
9
8
  const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
10
9
  const HELP_FILE = path.resolve(COMMAND_DIR, 'help.txt');
11
10
  const PACKAGE_ROOT = path.resolve(COMMAND_DIR, '../../..');
12
- const TOOLKIT_PACKAGE_JSON = path.resolve(PACKAGE_ROOT, 'package.json');
11
+ const REPO_ROOT = path.resolve(PACKAGE_ROOT, '../..');
12
+ const TOOLING_BASELINE_CANDIDATE_PATHS = [
13
+ path.resolve(REPO_ROOT, '.github/distribution/produck/tooling-version-baseline.json'),
14
+ path.resolve(PACKAGE_ROOT, 'publish-assets/instructions/produck/tooling-version-baseline.json'),
15
+ ];
16
+ const ESLINT_RULES_PACKAGE_NAME = '@produck/eslint-rules';
13
17
  const ESLINT_CONFIG_FILE = 'eslint.config.mjs';
14
18
 
15
19
  const REQUIRED_LINT_SCRIPT_KEY = 'produck:lint';
@@ -51,21 +55,41 @@ function readFileIfExists(filePath) {
51
55
  }
52
56
 
53
57
  function getRequiredEslintRulesDevDependency() {
54
- const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
55
- const latestResult = spawnSync(npmCommand, ['view', '@produck/eslint-rules', 'version'], {
56
- encoding: 'utf8',
58
+ // Prefer the in-tree source of truth: when sync-lint runs from inside the
59
+ // monorepo, the eslint-rules package.json is the authoritative version. When
60
+ // sync-lint runs as an installed dependency, fall back to the publish-assets
61
+ // tooling baseline (which build-publish-assets injects at prepack time from
62
+ // the same package.json).
63
+ const inTreeEslintRulesPkgPath = path.resolve(REPO_ROOT, 'packages/eslint-rules/package.json');
64
+ if (fs.existsSync(inTreeEslintRulesPkgPath)) {
65
+ const eslintRulesPkg = parseJsonFile(inTreeEslintRulesPkgPath, 'eslint-rules package.json');
66
+ const version = typeof eslintRulesPkg.version === 'string' ? eslintRulesPkg.version.trim() : '';
67
+ if (version) {
68
+ return version;
69
+ }
70
+ }
71
+
72
+ const toolingBaselinePath = TOOLING_BASELINE_CANDIDATE_PATHS.find((candidatePath) => {
73
+ return fs.existsSync(candidatePath);
57
74
  });
58
75
 
59
- const latestVersion = String(latestResult.stdout || '').trim();
60
- if (latestResult.status === 0 && latestVersion) {
61
- return latestVersion;
76
+ if (!toolingBaselinePath) {
77
+ console.error('Cannot resolve @produck/eslint-rules version. Looked at:');
78
+ console.error(`- ${inTreeEslintRulesPkgPath}`);
79
+ for (const candidatePath of TOOLING_BASELINE_CANDIDATE_PATHS) {
80
+ console.error(`- ${candidatePath}`);
81
+ }
82
+ process.exit(2);
62
83
  }
63
84
 
64
- const pkg = parseJsonFile(TOOLKIT_PACKAGE_JSON, 'Toolkit package.json');
65
- const version = typeof pkg.version === 'string' ? pkg.version.trim() : '';
85
+ const baseline = parseJsonFile(toolingBaselinePath, 'Tooling baseline file');
86
+ const entry = baseline?.tools?.[ESLINT_RULES_PACKAGE_NAME];
87
+ const version = typeof entry?.version === 'string' ? entry.version.trim() : '';
66
88
 
67
89
  if (!version) {
68
- console.error(`Toolkit package version is missing: ${TOOLKIT_PACKAGE_JSON}`);
90
+ console.error(
91
+ `Tooling baseline tools["${ESLINT_RULES_PACKAGE_NAME}"].version must be a non-empty string: ${toolingBaselinePath}`,
92
+ );
69
93
  process.exit(2);
70
94
  }
71
95
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produck/agent-toolkit",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Central CLI toolkit for organization AI execution workflows",
5
5
  "type": "module",
6
6
  "repository": {
@@ -30,5 +30,5 @@
30
30
  "devDependencies": {
31
31
  "c8": "11.0.0"
32
32
  },
33
- "gitHead": "a9e160249f664b28fa5971246e61d9e641c16586"
33
+ "gitHead": "d33ff4a5b28440659dc830bd8f94d3b8b04eb796"
34
34
  }