@forgeax/engine-devkit 0.1.3 → 0.1.4

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/dist/init.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { CommandResult, InitOptions, ProjectFacts } from './types.js';
3
3
  export interface InitPlan {
4
4
  readonly root: string;
5
5
  readonly version: string;
6
+ readonly pnpmVersion?: string;
6
7
  readonly archiveBacked: boolean;
7
8
  readonly dependencyChanges: readonly {
8
9
  readonly section: string;
@@ -15,6 +16,6 @@ export interface InitPlan {
15
16
  readonly to: string;
16
17
  }[];
17
18
  }
18
- export declare function createInitPlan(facts: ProjectFacts, sdk?: Pick<SdkManifest, 'sdkVersion' | 'packages'>): CommandResult<InitPlan>;
19
+ export declare function createInitPlan(facts: ProjectFacts, sdk?: Pick<SdkManifest, 'sdkVersion' | 'packages' | 'requirements'>): CommandResult<InitPlan>;
19
20
  export declare function applyInitPlan(facts: ProjectFacts, plan: InitPlan, options: InitOptions): Promise<CommandResult<InitPlan>>;
20
21
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoB3E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,SAAS;QACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,QAAQ,CAAC,aAAa,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnF;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC,GACjD,aAAa,CAAC,QAAQ,CAAC,CAkHzB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CA2ClC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoB3E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,iBAAiB,EAAE,SAAS;QACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,QAAQ,CAAC,aAAa,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnF;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,UAAU,GAAG,cAAc,CAAC,GAClE,aAAa,CAAC,QAAQ,CAAC,CAmHzB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAyBlC"}
@@ -0,0 +1,25 @@
1
+ import type { SdkContext } from './sdk.js';
2
+ import type { CommandResult } from './types.js';
3
+ declare const SDK_INIT_SCHEMA_VERSION: "1.0.0";
4
+ export interface SdkInitState {
5
+ readonly schemaVersion: typeof SDK_INIT_SCHEMA_VERSION;
6
+ readonly sdkVersion: string;
7
+ readonly engineCommit: string;
8
+ readonly pnpm: string;
9
+ readonly node: string;
10
+ readonly platform: NodeJS.Platform;
11
+ readonly arch: string;
12
+ }
13
+ export interface SdkInitReport extends SdkInitState {
14
+ readonly root: string;
15
+ readonly store: 'offline' | 'registry';
16
+ }
17
+ export declare function sdkProjectInstallArgs(store: string | undefined): string[];
18
+ export declare function readSdkInitState(sdk: SdkContext): Promise<SdkInitState | undefined>;
19
+ export declare function requireSdkInitialization(sdk: SdkContext): Promise<CommandResult<SdkInitState>>;
20
+ export declare function sdkInitCommand(sdk: SdkContext, options?: {
21
+ readonly dryRun?: boolean;
22
+ readonly install?: boolean;
23
+ }): Promise<CommandResult<SdkInitReport>>;
24
+ export {};
25
+ //# sourceMappingURL=sdk-bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-bootstrap.d.ts","sourceRoot":"","sources":["../src/sdk-bootstrap.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,QAAA,MAAM,uBAAuB,EAAG,OAAgB,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,uBAAuB,CAAC;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;CACxC;AAeD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAWzE;AAkDD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAOzF;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAkBtC;AAsBD,wBAAsB,cAAc,CAClC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACtE,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAiDvC"}
package/dist/sdk-cli.mjs CHANGED
@@ -4,6 +4,7 @@ import { pathToFileURL, fileURLToPath } from 'url';
4
4
  import { execFile } from 'child_process';
5
5
  import { readdir, mkdir, mkdtemp, cp, rename, rm, copyFile, readFile, realpath, writeFile, symlink, access, lstat, readlink, rmdir } from 'fs/promises';
6
6
  import { promisify } from 'util';
7
+ import { tmpdir } from 'os';
7
8
 
8
9
  var __defProp = Object.defineProperty;
9
10
  var __export = (target, all) => {
@@ -126,6 +127,7 @@ function createInitPlan(facts, sdk) {
126
127
  value: {
127
128
  root: facts.root,
128
129
  version: sdk?.sdkVersion ?? devkitVersion,
130
+ ...sdk === void 0 ? {} : { pnpmVersion: sdk.requirements.pnpm },
129
131
  archiveBacked: sdk !== void 0,
130
132
  dependencyChanges,
131
133
  scriptChanges
@@ -146,23 +148,8 @@ async function applyInitPlan(facts, plan, options) {
146
148
  for (const change of plan.scriptChanges) scripts[change.name] = change.to;
147
149
  manifest.scripts = scripts;
148
150
  if (plan.archiveBacked) {
149
- manifest.packageManager = "pnpm@10.33.2";
150
- const pnpmValue = manifest.pnpm;
151
- const pnpm = pnpmValue !== null && typeof pnpmValue === "object" ? pnpmValue : {};
152
- manifest.pnpm = {
153
- ...pnpm,
154
- onlyBuiltDependencies: [
155
- "@forgeax/engine-codec",
156
- "@forgeax/engine-fbx",
157
- "@forgeax/engine-wgpu-wasm",
158
- "esbuild"
159
- ],
160
- supportedArchitectures: {
161
- os: ["darwin", "linux", "win32"],
162
- cpu: ["x64", "arm64"],
163
- libc: ["glibc", "musl"]
164
- }
165
- };
151
+ if (plan.pnpmVersion === void 0) throw new Error("sdk-pnpm-version-missing");
152
+ manifest.packageManager = `pnpm@${plan.pnpmVersion}`;
166
153
  }
167
154
  await writeFile(resolve(facts.root, "package.json"), `${JSON.stringify(manifest, null, 2)}
168
155
  `);
@@ -4684,7 +4671,7 @@ var coerce = {
4684
4671
  };
4685
4672
  var NEVER = INVALID;
4686
4673
 
4687
- // ../engine-project/dist/index.mjs
4674
+ // ../project/dist/index.mjs
4688
4675
  var GuidString = external_exports.string().refine(
4689
4676
  (val) => AssetGuid.parse(val).ok,
4690
4677
  (val) => {
@@ -4955,6 +4942,149 @@ async function findSdkContext() {
4955
4942
  cursor = parent;
4956
4943
  }
4957
4944
  }
4945
+ var execFileAsync = promisify(execFile);
4946
+ var SDK_INIT_PATH = [".forgeax", "sdk-init.json"];
4947
+ var SDK_INIT_SCHEMA_VERSION = "1.0.0";
4948
+ function sdkInitPath(sdk) {
4949
+ return resolve(sdk.root, ...SDK_INIT_PATH);
4950
+ }
4951
+ function commandFailure(code, expected, hint, detail = {}) {
4952
+ return { ok: false, error: { code, expected, hint, detail } };
4953
+ }
4954
+ function sdkProjectInstallArgs(store) {
4955
+ const common = [
4956
+ "install",
4957
+ "--frozen-lockfile",
4958
+ "--ignore-scripts",
4959
+ "--side-effects-cache=true",
4960
+ "--child-concurrency=1"
4961
+ ];
4962
+ return store === void 0 ? common : [...common, "--offline", "--trust-lockfile", "--store-dir", store];
4963
+ }
4964
+ function sdkBootstrapInstallArgs(store) {
4965
+ const common = [
4966
+ "install",
4967
+ "--frozen-lockfile",
4968
+ "--child-concurrency=1",
4969
+ "--side-effects-cache=true"
4970
+ ];
4971
+ return store === void 0 ? common : [...common, "--offline", "--trust-lockfile", "--store-dir", store];
4972
+ }
4973
+ function supportedPnpm(version) {
4974
+ const [major = 0, minor = 0] = version.split(".").map(Number);
4975
+ return major === 11 && minor >= 7;
4976
+ }
4977
+ async function currentPnpm() {
4978
+ try {
4979
+ const result = await execFileAsync("pnpm", ["--version"], { maxBuffer: 1024 * 1024 });
4980
+ const version = result.stdout.trim();
4981
+ if (version.length === 0) throw new Error("pnpm returned an empty version");
4982
+ return { ok: true, value: version };
4983
+ } catch (cause) {
4984
+ return commandFailure(
4985
+ "pnpm-unavailable",
4986
+ "pnpm 11.7.0 or newer in the pnpm 11 line to be available on PATH",
4987
+ "Install or activate pnpm 11, then rerun forgeax init from the SDK root.",
4988
+ { reason: cause instanceof Error ? cause.message : String(cause) }
4989
+ );
4990
+ }
4991
+ }
4992
+ function matchesState(sdk, state) {
4993
+ if (state === null || typeof state !== "object" || Array.isArray(state)) return false;
4994
+ const value = state;
4995
+ return value.schemaVersion === SDK_INIT_SCHEMA_VERSION && value.sdkVersion === sdk.manifest.sdkVersion && value.engineCommit === sdk.manifest.engineCommit && typeof value.pnpm === "string" && supportedPnpm(value.pnpm) && value.node === process.versions.node && value.platform === process.platform && value.arch === process.arch;
4996
+ }
4997
+ async function readSdkInitState(sdk) {
4998
+ try {
4999
+ const value = JSON.parse(await readFile(sdkInitPath(sdk), "utf8"));
5000
+ return matchesState(sdk, value) ? value : void 0;
5001
+ } catch {
5002
+ return void 0;
5003
+ }
5004
+ }
5005
+ async function requireSdkInitialization(sdk) {
5006
+ const state = await readSdkInitState(sdk);
5007
+ if (state === void 0) {
5008
+ return commandFailure(
5009
+ "sdk-not-initialized",
5010
+ "the downloaded SDK to be initialized for this Node/pnpm/platform tuple",
5011
+ "Run ./bin/forgeax init from the SDK root once, then run forgeax new outside the SDK.",
5012
+ {
5013
+ sdkRoot: sdk.root,
5014
+ sdkVersion: sdk.manifest.sdkVersion,
5015
+ pnpm: sdk.manifest.requirements.pnpm,
5016
+ node: process.versions.node,
5017
+ platform: process.platform,
5018
+ arch: process.arch
5019
+ }
5020
+ );
5021
+ }
5022
+ return { ok: true, value: state };
5023
+ }
5024
+ async function copyBootstrapInputs(sdk, root2) {
5025
+ const template2 = sdk.templates.get(sdk.defaultTemplate);
5026
+ if (template2 === void 0) throw new Error("sdk-default-template-missing");
5027
+ for (const name of ["package.json", "pnpm-lock.yaml", "pnpm-workspace.yaml"]) {
5028
+ await cp(resolve(template2, name), resolve(root2, name));
5029
+ }
5030
+ try {
5031
+ await cp(resolve(template2, ".npmrc"), resolve(root2, ".npmrc"));
5032
+ } catch (cause) {
5033
+ if (cause === null || typeof cause !== "object" || !("code" in cause) || cause.code !== "ENOENT") {
5034
+ throw cause;
5035
+ }
5036
+ }
5037
+ }
5038
+ async function sdkInitCommand(sdk, options = {}) {
5039
+ const pnpmResult = await currentPnpm();
5040
+ if (!pnpmResult.ok) return pnpmResult;
5041
+ if (!supportedPnpm(pnpmResult.value)) {
5042
+ return commandFailure(
5043
+ "pnpm-version-unsupported",
5044
+ "pnpm >=11.7.0 <12",
5045
+ "Activate pnpm 11.7.0 or newer in the pnpm 11 line, then rerun forgeax init.",
5046
+ { actual: pnpmResult.value, expected: sdk.manifest.requirements.pnpm }
5047
+ );
5048
+ }
5049
+ const state = {
5050
+ schemaVersion: SDK_INIT_SCHEMA_VERSION,
5051
+ sdkVersion: sdk.manifest.sdkVersion,
5052
+ engineCommit: sdk.manifest.engineCommit,
5053
+ pnpm: pnpmResult.value,
5054
+ node: process.versions.node,
5055
+ platform: process.platform,
5056
+ arch: process.arch
5057
+ };
5058
+ const report = {
5059
+ ...state,
5060
+ root: sdk.root,
5061
+ store: sdk.store === void 0 ? "registry" : "offline"
5062
+ };
5063
+ if (options.dryRun === true || options.install === false) return { ok: true, value: report };
5064
+ let staging;
5065
+ try {
5066
+ staging = await mkdtemp(resolve(tmpdir(), "forgeax-sdk-init-"));
5067
+ await copyBootstrapInputs(sdk, staging);
5068
+ await execFileAsync("pnpm", sdkBootstrapInstallArgs(sdk.store), {
5069
+ cwd: staging,
5070
+ env: { ...process.env, CI: "true" },
5071
+ maxBuffer: 16 * 1024 * 1024
5072
+ });
5073
+ await mkdir(resolve(sdk.root, ".forgeax"), { recursive: true });
5074
+ await writeFile(sdkInitPath(sdk), `${JSON.stringify(state, null, 2)}
5075
+ `);
5076
+ return { ok: true, value: report };
5077
+ } catch (cause) {
5078
+ return commandFailure(
5079
+ "sdk-init-failed",
5080
+ "the SDK dependency closure to install and build native packages successfully",
5081
+ "Inspect the pnpm output, repair Node/pnpm or platform permissions, then rerun forgeax init from the SDK root.",
5082
+ { reason: cause instanceof Error ? cause.message : String(cause), sdkRoot: sdk.root }
5083
+ );
5084
+ } finally {
5085
+ if (staging !== void 0) await rm(staging, { recursive: true, force: true });
5086
+ }
5087
+ }
4958
5088
  var PROJECT_SKILL_MOUNT_ROOTS = Object.freeze([
4959
5089
  ".codebuddy/skills",
4960
5090
  ".cursor/skills",
@@ -5246,7 +5376,7 @@ async function installProjectSkills(root2, provenance) {
5246
5376
  }
5247
5377
 
5248
5378
  // src/bootstrap-commands.ts
5249
- var execFileAsync = promisify(execFile);
5379
+ var execFileAsync2 = promisify(execFile);
5250
5380
  function isMissingPathError(cause) {
5251
5381
  return cause !== null && typeof cause === "object" && "code" in cause && cause.code === "ENOENT";
5252
5382
  }
@@ -5265,6 +5395,20 @@ async function canonicalProspectivePath(path) {
5265
5395
  }
5266
5396
  }
5267
5397
  }
5398
+ async function configureSdkStore(root2, store) {
5399
+ if (store === void 0) return;
5400
+ const path = resolve(root2, ".npmrc");
5401
+ let content = "";
5402
+ try {
5403
+ content = await readFile(path, "utf8");
5404
+ } catch (cause) {
5405
+ if (!isMissingPathError(cause)) throw cause;
5406
+ }
5407
+ const lines = content.split(/\r?\n/).filter((line) => line.trim().length > 0 && !/^\s*store-dir\s*=/.test(line));
5408
+ lines.push(`store-dir=${store}`);
5409
+ await writeFile(path, `${lines.join("\n")}
5410
+ `);
5411
+ }
5268
5412
  function containsOrEquals(parent, child) {
5269
5413
  const path = relative(parent, child);
5270
5414
  return path === "" || path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
@@ -5275,25 +5419,14 @@ function nodeSupported() {
5275
5419
  }
5276
5420
  function pnpmSupported(version) {
5277
5421
  const [major = 0, minor = 0] = version.split(".").map(Number);
5278
- return major === 10 && minor >= 33;
5279
- }
5280
- function sdkInstallArgs(store) {
5281
- if (store === void 0) return ["install", "--frozen-lockfile"];
5282
- return [
5283
- "install",
5284
- "--offline",
5285
- "--frozen-lockfile",
5286
- "--side-effects-cache=false",
5287
- "--store-dir",
5288
- store
5289
- ];
5422
+ return major === 11 && minor >= 7;
5290
5423
  }
5291
5424
  async function doctorCommand(options = {}) {
5292
5425
  const facts = await readProjectFacts(options.root);
5293
5426
  if (!facts.ok) return facts;
5294
5427
  let pnpm;
5295
5428
  try {
5296
- pnpm = (await execFileAsync("pnpm", ["--version"], { cwd: facts.value.root })).stdout.trim();
5429
+ pnpm = (await execFileAsync2("pnpm", ["--version"], { cwd: facts.value.root })).stdout.trim();
5297
5430
  } catch (cause) {
5298
5431
  return {
5299
5432
  ok: false,
@@ -5321,7 +5454,7 @@ async function doctorCommand(options = {}) {
5321
5454
  ok: false,
5322
5455
  error: {
5323
5456
  code: "pnpm-version-unsupported",
5324
- expected: "pnpm >=10.33.0 <11",
5457
+ expected: "pnpm >=11.7.0 <12",
5325
5458
  hint: "Enable the packageManager-declared pnpm version with Corepack and retry.",
5326
5459
  detail: { actual: pnpm }
5327
5460
  }
@@ -5360,12 +5493,20 @@ async function doctorCommand(options = {}) {
5360
5493
  };
5361
5494
  }
5362
5495
  async function initCommand(options = {}) {
5363
- const facts = await readProjectFacts(options.root);
5364
- if (!facts.ok) return facts;
5365
5496
  try {
5366
5497
  const sdk = await findSdkContext();
5498
+ const root2 = await canonicalProspectivePath(options.root ?? process.cwd());
5499
+ if (sdk !== void 0 && root2 === await canonicalProspectivePath(sdk.root)) {
5500
+ return sdkInitCommand(sdk, options);
5501
+ }
5502
+ const facts = await readProjectFacts(root2);
5503
+ if (!facts.ok) return facts;
5367
5504
  const plan = createInitPlan(facts.value, sdk?.manifest);
5368
5505
  if (!plan.ok) return plan;
5506
+ if (sdk !== void 0 && options.dryRun !== true) {
5507
+ const initialized = await requireSdkInitialization(sdk);
5508
+ if (!initialized.ok) return initialized;
5509
+ }
5369
5510
  const applied = await applyInitPlan(facts.value, plan.value, options);
5370
5511
  if (!applied.ok || options.dryRun === true) return applied;
5371
5512
  if (sdk !== void 0) {
@@ -5375,12 +5516,31 @@ async function initCommand(options = {}) {
5375
5516
  resolve(template2, "pnpm-lock.yaml"),
5376
5517
  resolve(facts.value.root, "pnpm-lock.yaml")
5377
5518
  );
5519
+ await copyFile(
5520
+ resolve(template2, "pnpm-workspace.yaml"),
5521
+ resolve(facts.value.root, "pnpm-workspace.yaml")
5522
+ );
5523
+ try {
5524
+ await readFile(resolve(facts.value.root, ".npmrc"), "utf8");
5525
+ } catch (cause) {
5526
+ if (!isMissingPathError(cause)) throw cause;
5527
+ try {
5528
+ await copyFile(resolve(template2, ".npmrc"), resolve(facts.value.root, ".npmrc"));
5529
+ } catch (templateCause) {
5530
+ if (!isMissingPathError(templateCause)) throw templateCause;
5531
+ }
5532
+ }
5378
5533
  await copySdkSkills(sdk, facts.value.root);
5379
5534
  await installProjectSkills(facts.value.root, sdk.manifest);
5535
+ await configureSdkStore(
5536
+ facts.value.root,
5537
+ sdk.store === void 0 ? void 0 : await canonicalProspectivePath(sdk.store)
5538
+ );
5380
5539
  }
5381
5540
  if (options.install === false) return applied;
5382
- const installArgs = sdk === void 0 ? ["install", "--frozen-lockfile=false"] : sdkInstallArgs(sdk.store);
5383
- await execFileAsync("pnpm", installArgs, {
5541
+ const store = sdk === void 0 || sdk.store === void 0 ? void 0 : await canonicalProspectivePath(sdk.store);
5542
+ const installArgs = sdk === void 0 ? ["install", "--frozen-lockfile=false"] : sdkProjectInstallArgs(store);
5543
+ await execFileAsync2("pnpm", installArgs, {
5384
5544
  cwd: facts.value.root,
5385
5545
  env: { ...process.env, CI: "true" },
5386
5546
  maxBuffer: 16 * 1024 * 1024
@@ -5458,12 +5618,15 @@ async function newCommand(options = {}) {
5458
5618
  value: { root: root2, template: templateId, sdkVersion: sdk.manifest.sdkVersion }
5459
5619
  };
5460
5620
  }
5621
+ const initialized = await requireSdkInitialization(sdk);
5622
+ if (!initialized.ok) return initialized;
5461
5623
  const parent = dirname(root2);
5462
5624
  await mkdir(parent, { recursive: true });
5463
5625
  let staging = await mkdtemp(
5464
5626
  resolve(parent, `.${basename(root2)}.forgeax-staging-`)
5465
5627
  );
5466
5628
  const committedNames = [];
5629
+ let committed = false;
5467
5630
  try {
5468
5631
  for (const name of await readdir(template2)) {
5469
5632
  await cp(resolve(template2, name), resolve(staging, name), {
@@ -5474,14 +5637,12 @@ async function newCommand(options = {}) {
5474
5637
  }
5475
5638
  await copySdkSkills(sdk, staging);
5476
5639
  await installProjectSkills(staging, sdk.manifest);
5477
- await execFileAsync("pnpm", sdkInstallArgs(sdk.store), {
5478
- cwd: staging,
5479
- env: { ...process.env, CI: "true" },
5480
- maxBuffer: 16 * 1024 * 1024
5481
- });
5640
+ const store = sdk.store === void 0 ? void 0 : await canonicalProspectivePath(sdk.store);
5641
+ await configureSdkStore(staging, store);
5482
5642
  if (!targetExists) {
5483
5643
  await rename(staging, root2);
5484
5644
  staging = void 0;
5645
+ committedNames.push(...await readdir(root2));
5485
5646
  } else {
5486
5647
  for (const name of await readdir(staging)) {
5487
5648
  await rename(resolve(staging, name), resolve(root2, name));
@@ -5490,15 +5651,34 @@ async function newCommand(options = {}) {
5490
5651
  await rm(staging, { recursive: true, force: true });
5491
5652
  staging = void 0;
5492
5653
  }
5654
+ committed = true;
5655
+ await execFileAsync2("pnpm", sdkProjectInstallArgs(store), {
5656
+ cwd: root2,
5657
+ env: { ...process.env, CI: "true" },
5658
+ maxBuffer: 16 * 1024 * 1024
5659
+ });
5493
5660
  return {
5494
5661
  ok: true,
5495
5662
  value: { root: root2, template: templateId, sdkVersion: sdk.manifest.sdkVersion }
5496
5663
  };
5497
5664
  } catch (cause) {
5498
5665
  if (staging !== void 0) await rm(staging, { recursive: true, force: true });
5499
- await Promise.all(
5500
- committedNames.map((name) => rm(resolve(root2, name), { recursive: true, force: true }))
5501
- );
5666
+ if (committed) {
5667
+ if (!targetExists) {
5668
+ await rm(root2, { recursive: true, force: true });
5669
+ return { ok: false, error: commandError(cause, "project-create-failed") };
5670
+ }
5671
+ const cleanupNames = /* @__PURE__ */ new Set([...committedNames, "node_modules"]);
5672
+ await Promise.all(
5673
+ [...cleanupNames].map(
5674
+ (name) => rm(resolve(root2, name), { recursive: true, force: true })
5675
+ )
5676
+ );
5677
+ } else {
5678
+ await Promise.all(
5679
+ committedNames.map((name) => rm(resolve(root2, name), { recursive: true, force: true }))
5680
+ );
5681
+ }
5502
5682
  return { ok: false, error: commandError(cause, "project-create-failed") };
5503
5683
  }
5504
5684
  } catch (cause) {