@bleedingdev/modern-js-create 3.2.0-ultramodern.118 → 3.2.0-ultramodern.119

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.
@@ -504,7 +504,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
504
504
  'mf:types': "node ./scripts/assert-mf-types.mjs",
505
505
  'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
506
506
  'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
507
- postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs",
507
+ postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs",
508
508
  check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check'
509
509
  },
510
510
  engines: {
@@ -4592,7 +4592,7 @@ assert(rootPackage.scripts?.['cloudflare:deploy'] === expectedCloudflareDeploySc
4592
4592
  assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
4593
4593
  assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mjs', 'Root must expose skills:install');
4594
4594
  assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mjs --check', 'Root must expose skills:check');
4595
- assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4595
+ assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4596
4596
  const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mjs');
4597
4597
  assert(agentReferenceRepoSetup.includes("['commit', '--no-verify', '-m', message]"), 'Agent reference repo installer commits must skip hooks during postinstall');
4598
4598
  assert(agentReferenceRepoSetup.includes("commitInstallerChanges('Initialize UltraModern workspace')"), 'Initial agent reference repo commit must use the installer commit helper');
@@ -455,7 +455,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
455
455
  'mf:types': "node ./scripts/assert-mf-types.mjs",
456
456
  'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
457
457
  'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
458
- postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs",
458
+ postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs",
459
459
  check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check'
460
460
  },
461
461
  engines: {
@@ -4543,7 +4543,7 @@ assert(rootPackage.scripts?.['cloudflare:deploy'] === expectedCloudflareDeploySc
4543
4543
  assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
4544
4544
  assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mjs', 'Root must expose skills:install');
4545
4545
  assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mjs --check', 'Root must expose skills:check');
4546
- assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4546
+ assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4547
4547
  const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mjs');
4548
4548
  assert(agentReferenceRepoSetup.includes("['commit', '--no-verify', '-m', message]"), 'Agent reference repo installer commits must skip hooks during postinstall');
4549
4549
  assert(agentReferenceRepoSetup.includes("commitInstallerChanges('Initialize UltraModern workspace')"), 'Initial agent reference repo commit must use the installer commit helper');
@@ -456,7 +456,7 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
456
456
  'mf:types': "node ./scripts/assert-mf-types.mjs",
457
457
  'contract:check': "node ./scripts/validate-ultramodern-workspace.mjs",
458
458
  'i18n:boundaries': "node ./scripts/check-ultramodern-i18n-boundaries.mjs",
459
- postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs",
459
+ postinstall: "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs",
460
460
  check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm i18n:boundaries && pnpm contract:check'
461
461
  },
462
462
  engines: {
@@ -4544,7 +4544,7 @@ assert(rootPackage.scripts?.['cloudflare:deploy'] === expectedCloudflareDeploySc
4544
4544
  assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
4545
4545
  assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mjs', 'Root must expose skills:install');
4546
4546
  assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mjs --check', 'Root must expose skills:check');
4547
- assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4547
+ assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall && node ./scripts/setup-agent-reference-repos.mjs", 'Root postinstall must format, bootstrap agent skills, initialize git/hooks, and install reference repositories');
4548
4548
  const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mjs');
4549
4549
  assert(agentReferenceRepoSetup.includes("['commit', '--no-verify', '-m', message]"), 'Agent reference repo installer commits must skip hooks during postinstall');
4550
4550
  assert(agentReferenceRepoSetup.includes("commitInstallerChanges('Initialize UltraModern workspace')"), 'Initial agent reference repo commit must use the installer commit helper');
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.118",
24
+ "version": "3.2.0-ultramodern.119",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/esm-node/index.js",
27
27
  "bin": {
@@ -51,7 +51,7 @@
51
51
  "bin"
52
52
  ],
53
53
  "dependencies": {
54
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.118"
54
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.119"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@rslib/core": "0.21.5",
@@ -72,6 +72,6 @@
72
72
  "test": "rm -rf dist && rslib build -c rslibconfig.mts && rstest --passWithNoTests"
73
73
  },
74
74
  "ultramodern": {
75
- "frameworkVersion": "3.2.0-ultramodern.118"
75
+ "frameworkVersion": "3.2.0-ultramodern.119"
76
76
  }
77
77
  }
@@ -15,7 +15,7 @@ instructions, not optional reading.
15
15
  - `pnpm check` is a local convenience aggregate for the primitive gates.
16
16
  - Generated CI runs primitive gates as separate matrix jobs instead of calling `pnpm check`.
17
17
  - Generated Codex stop hooks and subagent-stop hooks run `pnpm format && pnpm lint:fix && pnpm check`.
18
- - `postinstall` formats the generated tree, initializes Git when needed, installs agent skills and reference repos, then installs `lefthook`. Generated `lefthook.yml` runs separate format and lint-fix commands on pre-commit; pre-push runs read-only primitive gates in parallel.
18
+ - `postinstall` formats the generated tree, initializes Git when needed, prepares agent skills and reference repos, then installs `lefthook`. Generated `lefthook.yml` runs separate format and lint-fix commands on pre-commit; pre-push runs read-only primitive gates in parallel.
19
19
 
20
20
  ## Localized Routes
21
21
 
@@ -41,7 +41,7 @@ Use these skills when the task touches the matching subsystem:
41
41
  - `rstest-best-practices`: Rstest configuration, test writing, mocking, snapshots, coverage, and CI test behavior.
42
42
  - `mf`: Module Federation docs, Modern.js integration, DTS/type checks, shared dependency checks, runtime errors, and observability troubleshooting.
43
43
 
44
- The public `module-federation/agent-skills` repository is installed during `pnpm install` and `pnpm skills:install`. `pnpm skills:check` fails when the required public `mf` skill is missing.
44
+ The public `module-federation/agent-skills` repository is installed during `pnpm install` and `pnpm skills:install`. Postinstall mode skips unavailable clone sources instead of blocking dependency installation; `pnpm skills:install` remains strict for required public skills. Use `ULTRAMODERN_SKIP_AGENT_SKILLS=1` when an install must avoid external skill repositories completely. `pnpm skills:check` fails when the required public `mf` skill is missing unless that skip flag is set.
45
45
 
46
46
  ## Private Skills
47
47
 
@@ -52,6 +52,12 @@ subtrees. Disable this setup with
52
52
  `ULTRAMODERN_SKIP_AGENT_REPOS=1 pnpm install`, or rerun it
53
53
  explicitly with `pnpm agents:refs:install`.
54
54
 
55
+ Agent skills are prepared during `pnpm install` as a developer convenience.
56
+ External skill repository failures do not block postinstall; strict installation
57
+ is available with `pnpm skills:install`. Use
58
+ `ULTRAMODERN_SKIP_AGENT_SKILLS=1` for a dependency install that avoids external
59
+ skill repositories completely.
60
+
55
61
  The topology and ownership metadata are generated under `topology/`. The
56
62
  workspace also ships `.github/workflows/ultramodern-workspace-gates.yml` and
57
63
  `.github/renovate.json` with read-only workflow permissions, commit-pinned
@@ -7,6 +7,16 @@ const root = process.cwd();
7
7
  const lockPath = path.join(root, '.agents/skills-lock.json');
8
8
  const checkOnly = process.argv.includes('--check');
9
9
  const force = process.argv.includes('--force');
10
+ const postinstall = process.argv.includes('--postinstall');
11
+ const truthy = value => /^(1|true|yes|on)$/i.test(String(value ?? ''));
12
+ const falsy = value => /^(0|false|no|off)$/i.test(String(value ?? ''));
13
+ const skipRequested =
14
+ truthy(process.env.ULTRAMODERN_SKIP_AGENT_SKILLS) ||
15
+ falsy(process.env.ULTRAMODERN_AGENT_SKILLS);
16
+ const cloneTimeoutMs = Number.parseInt(
17
+ process.env.ULTRAMODERN_AGENT_SKILLS_CLONE_TIMEOUT_MS ?? '60000',
18
+ 10,
19
+ );
10
20
 
11
21
  const readJson = filePath => JSON.parse(fs.readFileSync(filePath, 'utf-8'));
12
22
 
@@ -15,6 +25,7 @@ const run = (command, args, options = {}) =>
15
25
  cwd: options.cwd ?? root,
16
26
  encoding: 'utf-8',
17
27
  stdio: options.stdio ?? ['ignore', 'pipe', 'pipe'],
28
+ timeout: options.timeout,
18
29
  });
19
30
 
20
31
  const commandExists = command => {
@@ -106,12 +117,14 @@ const removeTree = dir =>
106
117
 
107
118
  const cloneSource = (source, targetDir) => {
108
119
  if (source.commit) {
109
- run('git', ['init', targetDir]);
120
+ run('git', ['init', targetDir], { timeout: 30000 });
110
121
  run('git', ['remote', 'add', 'origin', source.repository], {
111
122
  cwd: targetDir,
123
+ timeout: 30000,
112
124
  });
113
125
  run('git', ['fetch', '--depth', '1', '--quiet', 'origin', source.commit], {
114
126
  cwd: targetDir,
127
+ timeout: cloneTimeoutMs,
115
128
  });
116
129
  run(
117
130
  'git',
@@ -123,32 +136,24 @@ const cloneSource = (source, targetDir) => {
123
136
  '--quiet',
124
137
  'FETCH_HEAD',
125
138
  ],
126
- { cwd: targetDir },
139
+ { cwd: targetDir, timeout: 30000 },
127
140
  );
128
141
  return;
129
142
  }
130
143
 
131
144
  const repo = source.repository.replace(/^https:\/\/github.com\//u, '');
132
145
  try {
133
- run('gh', [
134
- 'repo',
135
- 'clone',
136
- repo,
137
- targetDir,
138
- '--',
139
- '--depth',
140
- '1',
141
- '--quiet',
142
- ]);
146
+ run(
147
+ 'gh',
148
+ ['repo', 'clone', repo, targetDir, '--', '--depth', '1', '--quiet'],
149
+ { timeout: cloneTimeoutMs },
150
+ );
143
151
  } catch {
144
- run('git', [
145
- 'clone',
146
- '--depth',
147
- '1',
148
- '--quiet',
149
- source.repository,
150
- targetDir,
151
- ]);
152
+ run(
153
+ 'git',
154
+ ['clone', '--depth', '1', '--quiet', source.repository, targetDir],
155
+ { timeout: cloneTimeoutMs },
156
+ );
152
157
  }
153
158
  };
154
159
 
@@ -186,6 +191,17 @@ const requiredSkills = [
186
191
  skills.findIndex(candidate => candidate.name === skill.name) === index,
187
192
  );
188
193
 
194
+ if (skipRequested) {
195
+ const reason = 'agent skills bootstrap skipped by environment';
196
+ if (checkOnly) {
197
+ console.log(reason);
198
+ process.exit(0);
199
+ }
200
+ console.log(reason);
201
+ installLefthook();
202
+ process.exit(0);
203
+ }
204
+
189
205
  if (checkOnly) {
190
206
  const missingRequired = requiredSkills
191
207
  .map(skill => skill.name)
@@ -230,10 +246,8 @@ for (const source of [...requiredCloneSources, ...optionalCloneSources]) {
230
246
  try {
231
247
  cloneSource(source, tempDir);
232
248
  } catch (error) {
233
- if (source.install === 'clone-if-authorized') {
234
- console.warn(
235
- `Skipping ${source.repository}; current developer may not have access.`,
236
- );
249
+ if (source.install === 'clone-if-authorized' || postinstall) {
250
+ console.warn(`Skipping ${source.repository}; ${error.message}`);
237
251
  continue;
238
252
  }
239
253
  throw error;