@forgeax/engine-devkit 0.1.2 → 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) => {
@@ -4941,10 +4928,11 @@ async function findSdkContext() {
4941
4928
  );
4942
4929
  const defaultTemplate = manifest.templates.find((template2) => template2.default);
4943
4930
  if (defaultTemplate === void 0) throw new Error("sdk-default-template-missing");
4931
+ const store = resolve(cursor, "store", "pnpm");
4944
4932
  return {
4945
4933
  root: cursor,
4946
4934
  manifest,
4947
- store: resolve(cursor, "store", "pnpm"),
4935
+ ...await readable(store) ? { store } : {},
4948
4936
  templates,
4949
4937
  defaultTemplate: defaultTemplate.id
4950
4938
  };
@@ -4954,6 +4942,149 @@ async function findSdkContext() {
4954
4942
  cursor = parent;
4955
4943
  }
4956
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
+ }
4957
5088
  var PROJECT_SKILL_MOUNT_ROOTS = Object.freeze([
4958
5089
  ".codebuddy/skills",
4959
5090
  ".cursor/skills",
@@ -5245,7 +5376,7 @@ async function installProjectSkills(root2, provenance) {
5245
5376
  }
5246
5377
 
5247
5378
  // src/bootstrap-commands.ts
5248
- var execFileAsync = promisify(execFile);
5379
+ var execFileAsync2 = promisify(execFile);
5249
5380
  function isMissingPathError(cause) {
5250
5381
  return cause !== null && typeof cause === "object" && "code" in cause && cause.code === "ENOENT";
5251
5382
  }
@@ -5264,6 +5395,20 @@ async function canonicalProspectivePath(path) {
5264
5395
  }
5265
5396
  }
5266
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
+ }
5267
5412
  function containsOrEquals(parent, child) {
5268
5413
  const path = relative(parent, child);
5269
5414
  return path === "" || path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
@@ -5274,14 +5419,14 @@ function nodeSupported() {
5274
5419
  }
5275
5420
  function pnpmSupported(version) {
5276
5421
  const [major = 0, minor = 0] = version.split(".").map(Number);
5277
- return major === 10 && minor >= 33;
5422
+ return major === 11 && minor >= 7;
5278
5423
  }
5279
5424
  async function doctorCommand(options = {}) {
5280
5425
  const facts = await readProjectFacts(options.root);
5281
5426
  if (!facts.ok) return facts;
5282
5427
  let pnpm;
5283
5428
  try {
5284
- pnpm = (await execFileAsync("pnpm", ["--version"], { cwd: facts.value.root })).stdout.trim();
5429
+ pnpm = (await execFileAsync2("pnpm", ["--version"], { cwd: facts.value.root })).stdout.trim();
5285
5430
  } catch (cause) {
5286
5431
  return {
5287
5432
  ok: false,
@@ -5309,7 +5454,7 @@ async function doctorCommand(options = {}) {
5309
5454
  ok: false,
5310
5455
  error: {
5311
5456
  code: "pnpm-version-unsupported",
5312
- expected: "pnpm >=10.33.0 <11",
5457
+ expected: "pnpm >=11.7.0 <12",
5313
5458
  hint: "Enable the packageManager-declared pnpm version with Corepack and retry.",
5314
5459
  detail: { actual: pnpm }
5315
5460
  }
@@ -5348,12 +5493,20 @@ async function doctorCommand(options = {}) {
5348
5493
  };
5349
5494
  }
5350
5495
  async function initCommand(options = {}) {
5351
- const facts = await readProjectFacts(options.root);
5352
- if (!facts.ok) return facts;
5353
5496
  try {
5354
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;
5355
5504
  const plan = createInitPlan(facts.value, sdk?.manifest);
5356
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
+ }
5357
5510
  const applied = await applyInitPlan(facts.value, plan.value, options);
5358
5511
  if (!applied.ok || options.dryRun === true) return applied;
5359
5512
  if (sdk !== void 0) {
@@ -5363,19 +5516,31 @@ async function initCommand(options = {}) {
5363
5516
  resolve(template2, "pnpm-lock.yaml"),
5364
5517
  resolve(facts.value.root, "pnpm-lock.yaml")
5365
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
+ }
5366
5533
  await copySdkSkills(sdk, facts.value.root);
5367
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
+ );
5368
5539
  }
5369
5540
  if (options.install === false) return applied;
5370
- const installArgs = sdk === void 0 ? ["install", "--frozen-lockfile=false"] : [
5371
- "install",
5372
- "--offline",
5373
- "--frozen-lockfile",
5374
- "--side-effects-cache=false",
5375
- "--store-dir",
5376
- sdk.store
5377
- ];
5378
- 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, {
5379
5544
  cwd: facts.value.root,
5380
5545
  env: { ...process.env, CI: "true" },
5381
5546
  maxBuffer: 16 * 1024 * 1024
@@ -5453,12 +5618,15 @@ async function newCommand(options = {}) {
5453
5618
  value: { root: root2, template: templateId, sdkVersion: sdk.manifest.sdkVersion }
5454
5619
  };
5455
5620
  }
5621
+ const initialized = await requireSdkInitialization(sdk);
5622
+ if (!initialized.ok) return initialized;
5456
5623
  const parent = dirname(root2);
5457
5624
  await mkdir(parent, { recursive: true });
5458
5625
  let staging = await mkdtemp(
5459
5626
  resolve(parent, `.${basename(root2)}.forgeax-staging-`)
5460
5627
  );
5461
5628
  const committedNames = [];
5629
+ let committed = false;
5462
5630
  try {
5463
5631
  for (const name of await readdir(template2)) {
5464
5632
  await cp(resolve(template2, name), resolve(staging, name), {
@@ -5469,25 +5637,12 @@ async function newCommand(options = {}) {
5469
5637
  }
5470
5638
  await copySdkSkills(sdk, staging);
5471
5639
  await installProjectSkills(staging, sdk.manifest);
5472
- await execFileAsync(
5473
- "pnpm",
5474
- [
5475
- "install",
5476
- "--offline",
5477
- "--frozen-lockfile",
5478
- "--side-effects-cache=false",
5479
- "--store-dir",
5480
- sdk.store
5481
- ],
5482
- {
5483
- cwd: staging,
5484
- env: { ...process.env, CI: "true" },
5485
- maxBuffer: 16 * 1024 * 1024
5486
- }
5487
- );
5640
+ const store = sdk.store === void 0 ? void 0 : await canonicalProspectivePath(sdk.store);
5641
+ await configureSdkStore(staging, store);
5488
5642
  if (!targetExists) {
5489
5643
  await rename(staging, root2);
5490
5644
  staging = void 0;
5645
+ committedNames.push(...await readdir(root2));
5491
5646
  } else {
5492
5647
  for (const name of await readdir(staging)) {
5493
5648
  await rename(resolve(staging, name), resolve(root2, name));
@@ -5496,15 +5651,34 @@ async function newCommand(options = {}) {
5496
5651
  await rm(staging, { recursive: true, force: true });
5497
5652
  staging = void 0;
5498
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
+ });
5499
5660
  return {
5500
5661
  ok: true,
5501
5662
  value: { root: root2, template: templateId, sdkVersion: sdk.manifest.sdkVersion }
5502
5663
  };
5503
5664
  } catch (cause) {
5504
5665
  if (staging !== void 0) await rm(staging, { recursive: true, force: true });
5505
- await Promise.all(
5506
- committedNames.map((name) => rm(resolve(root2, name), { recursive: true, force: true }))
5507
- );
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
+ }
5508
5682
  return { ok: false, error: commandError(cause, "project-create-failed") };
5509
5683
  }
5510
5684
  } catch (cause) {