codebyplan 1.13.60 → 1.13.61

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.
Files changed (3) hide show
  1. package/dist/ci.js +518 -0
  2. package/dist/cli.js +395 -355
  3. package/package.json +12 -2
package/dist/cli.js CHANGED
@@ -48,7 +48,7 @@ var VERSION, PACKAGE_NAME;
48
48
  var init_version = __esm({
49
49
  "src/lib/version.ts"() {
50
50
  "use strict";
51
- VERSION = "1.13.60";
51
+ VERSION = "1.13.61";
52
52
  PACKAGE_NAME = "codebyplan";
53
53
  }
54
54
  });
@@ -122,8 +122,8 @@ async function readLocalConfig(projectPath, onMigrationNotice) {
122
122
  }
123
123
  async function writeLocalConfig(projectPath, config) {
124
124
  const content = { device_id: config.device_id };
125
- const path22 = localConfigPath(projectPath);
126
- const dirPath = dirname(path22);
125
+ const path23 = localConfigPath(projectPath);
126
+ const dirPath = dirname(path23);
127
127
  let phase = "stat config directory";
128
128
  try {
129
129
  try {
@@ -143,7 +143,7 @@ async function writeLocalConfig(projectPath, config) {
143
143
  phase = "create config directory";
144
144
  await mkdir(dirPath, { recursive: true });
145
145
  phase = "write local config";
146
- await writeFile(path22, JSON.stringify(content, null, 2) + "\n", "utf-8");
146
+ await writeFile(path23, JSON.stringify(content, null, 2) + "\n", "utf-8");
147
147
  } catch (err) {
148
148
  const code = err.code;
149
149
  if (code === "LEGACY_FILE_BLOCKS_DIR") {
@@ -672,8 +672,8 @@ var init_gitignore_block = __esm({
672
672
  // src/lib/worktree.ts
673
673
  import { mkdir as mkdir3, writeFile as writeFile4, readFile as readFile6 } from "node:fs/promises";
674
674
  import { join as join6 } from "node:path";
675
- function defaultExists(path22) {
676
- return readFile6(path22, "utf-8").then(() => true).catch(() => false);
675
+ function defaultExists(path23) {
676
+ return readFile6(path23, "utf-8").then(() => true).catch(() => false);
677
677
  }
678
678
  async function writeRepoJson(codebyplanDir, selectedRepo, deps) {
679
679
  const repoJson = {
@@ -794,9 +794,9 @@ var init_worktree = __esm({
794
794
  init_local_config();
795
795
  init_gitignore_block();
796
796
  defaultFsDeps = {
797
- mkdir: (path22, opts) => mkdir3(path22, opts).then(() => void 0),
798
- writeFile: (path22, data, encoding) => writeFile4(path22, data, encoding),
799
- readFile: (path22, encoding) => readFile6(path22, encoding),
797
+ mkdir: (path23, opts) => mkdir3(path23, opts).then(() => void 0),
798
+ writeFile: (path23, data, encoding) => writeFile4(path23, data, encoding),
799
+ readFile: (path23, encoding) => readFile6(path23, encoding),
800
800
  exists: defaultExists
801
801
  };
802
802
  }
@@ -864,12 +864,12 @@ async function readFallback(filename) {
864
864
  }
865
865
  }
866
866
  async function writeFallback(filename, data) {
867
- const path22 = fallbackFile(filename);
868
- await mkdir4(dirname2(path22), { recursive: true });
869
- await writeFile5(path22, JSON.stringify(data, null, 2) + "\n", "utf-8");
867
+ const path23 = fallbackFile(filename);
868
+ await mkdir4(dirname2(path23), { recursive: true });
869
+ await writeFile5(path23, JSON.stringify(data, null, 2) + "\n", "utf-8");
870
870
  if (platform() !== "win32") {
871
871
  try {
872
- await chmod(path22, 384);
872
+ await chmod(path23, 384);
873
873
  } catch {
874
874
  }
875
875
  }
@@ -1183,8 +1183,8 @@ async function validateConnectivity() {
1183
1183
  );
1184
1184
  }
1185
1185
  }
1186
- function buildUrl(path22, params) {
1187
- const url = new URL(`${baseUrl()}/api${path22}`);
1186
+ function buildUrl(path23, params) {
1187
+ const url = new URL(`${baseUrl()}/api${path23}`);
1188
1188
  if (params) {
1189
1189
  for (const [key, value] of Object.entries(params)) {
1190
1190
  if (value !== void 0) {
@@ -1201,10 +1201,10 @@ function isRetryable(err) {
1201
1201
  return false;
1202
1202
  }
1203
1203
  function delay(ms) {
1204
- return new Promise((resolve16) => setTimeout(resolve16, ms));
1204
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
1205
1205
  }
1206
- async function request(method, path22, options) {
1207
- const url = buildUrl(path22, options?.params);
1206
+ async function request(method, path23, options) {
1207
+ const url = buildUrl(path23, options?.params);
1208
1208
  const auth = await getAuthHeaders();
1209
1209
  let lastError;
1210
1210
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
@@ -1224,7 +1224,7 @@ async function request(method, path22, options) {
1224
1224
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
1225
1225
  });
1226
1226
  if (!res.ok) {
1227
- let message = `API ${method} ${path22} failed with status ${res.status}`;
1227
+ let message = `API ${method} ${path23} failed with status ${res.status}`;
1228
1228
  let code;
1229
1229
  try {
1230
1230
  const body = await res.json();
@@ -1258,20 +1258,20 @@ async function request(method, path22, options) {
1258
1258
  }
1259
1259
  throw lastError;
1260
1260
  }
1261
- async function apiGet(path22, params) {
1262
- return request("GET", path22, { params });
1261
+ async function apiGet(path23, params) {
1262
+ return request("GET", path23, { params });
1263
1263
  }
1264
- async function apiPost(path22, body) {
1265
- return request("POST", path22, { body });
1264
+ async function apiPost(path23, body) {
1265
+ return request("POST", path23, { body });
1266
1266
  }
1267
- async function apiPut(path22, body) {
1268
- return request("PUT", path22, { body });
1267
+ async function apiPut(path23, body) {
1268
+ return request("PUT", path23, { body });
1269
1269
  }
1270
- async function apiPatch(path22, body) {
1271
- return request("PATCH", path22, { body });
1270
+ async function apiPatch(path23, body) {
1271
+ return request("PATCH", path23, { body });
1272
1272
  }
1273
- async function apiDelete(path22, params) {
1274
- await request("DELETE", path22, { params });
1273
+ async function apiDelete(path23, params) {
1274
+ await request("DELETE", path23, { params });
1275
1275
  }
1276
1276
  async function callMcpTool(toolName, params) {
1277
1277
  const url = mcpEndpoint();
@@ -1565,7 +1565,7 @@ var init_device_flow = __esm({
1565
1565
  this.name = "OAuthInvalidClientError";
1566
1566
  }
1567
1567
  };
1568
- defaultSleep = (ms) => new Promise((resolve16) => setTimeout(resolve16, ms));
1568
+ defaultSleep = (ms) => new Promise((resolve17) => setTimeout(resolve17, ms));
1569
1569
  }
1570
1570
  });
1571
1571
 
@@ -2323,7 +2323,7 @@ async function defaultPromptRemoveIgnore(displayLine, opts) {
2323
2323
  });
2324
2324
  try {
2325
2325
  while (true) {
2326
- const answer = await new Promise((resolve16) => {
2326
+ const answer = await new Promise((resolve17) => {
2327
2327
  rl.question(
2328
2328
  `The following gitignore rule matches .claude/settings.json:
2329
2329
  ${displayLine}
@@ -2331,7 +2331,7 @@ Remove this line?
2331
2331
  [r] remove [k] keep
2332
2332
  > `,
2333
2333
  (input) => {
2334
- resolve16(input.trim().toLowerCase());
2334
+ resolve17(input.trim().toLowerCase());
2335
2335
  }
2336
2336
  );
2337
2337
  });
@@ -3693,9 +3693,9 @@ import { createInterface } from "node:readline/promises";
3693
3693
  function getConfigPath(scope) {
3694
3694
  return scope === "user" ? join15(homedir4(), ".claude.json") : join15(process.cwd(), ".mcp.json");
3695
3695
  }
3696
- async function readConfig(path22) {
3696
+ async function readConfig(path23) {
3697
3697
  try {
3698
- const raw = await readFile12(path22, "utf-8");
3698
+ const raw = await readFile12(path23, "utf-8");
3699
3699
  const parsed = JSON.parse(raw);
3700
3700
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
3701
3701
  return parsed;
@@ -4126,9 +4126,9 @@ import { join as join16 } from "node:path";
4126
4126
  function configPaths() {
4127
4127
  return [join16(homedir5(), ".claude.json"), join16(process.cwd(), ".mcp.json")];
4128
4128
  }
4129
- async function readConfig2(path22) {
4129
+ async function readConfig2(path23) {
4130
4130
  try {
4131
- const raw = await readFile13(path22, "utf-8");
4131
+ const raw = await readFile13(path23, "utf-8");
4132
4132
  const parsed = JSON.parse(raw);
4133
4133
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
4134
4134
  return parsed;
@@ -4142,7 +4142,7 @@ function entryHasLegacyApiKey(entry) {
4142
4142
  if (!entry || !entry.headers) return false;
4143
4143
  return "x-api-key" in entry.headers;
4144
4144
  }
4145
- async function rewriteConfig(path22, config, newUrl) {
4145
+ async function rewriteConfig(path23, config, newUrl) {
4146
4146
  const servers = config.mcpServers;
4147
4147
  if (!servers) return false;
4148
4148
  const entry = servers.codebyplan;
@@ -4150,7 +4150,7 @@ async function rewriteConfig(path22, config, newUrl) {
4150
4150
  if (!entryHasLegacyApiKey(entry) && entry.url === newUrl && entry.type === "http")
4151
4151
  return false;
4152
4152
  servers.codebyplan = { type: "http", url: newUrl };
4153
- await writeFile10(path22, JSON.stringify(config, null, 2) + "\n", "utf-8");
4153
+ await writeFile10(path23, JSON.stringify(config, null, 2) + "\n", "utf-8");
4154
4154
  return true;
4155
4155
  }
4156
4156
  async function runUpgradeAuth() {
@@ -4158,12 +4158,12 @@ async function runUpgradeAuth() {
4158
4158
  await runLogin();
4159
4159
  const newUrl = mcpEndpoint();
4160
4160
  let migrated = 0;
4161
- for (const path22 of configPaths()) {
4162
- const config = await readConfig2(path22);
4161
+ for (const path23 of configPaths()) {
4162
+ const config = await readConfig2(path23);
4163
4163
  if (!config) continue;
4164
- const changed = await rewriteConfig(path22, config, newUrl);
4164
+ const changed = await rewriteConfig(path23, config, newUrl);
4165
4165
  if (changed) {
4166
- console.log(` Updated ${path22}`);
4166
+ console.log(` Updated ${path23}`);
4167
4167
  migrated++;
4168
4168
  }
4169
4169
  }
@@ -5750,11 +5750,11 @@ function __metadata(metadataKey, metadataValue) {
5750
5750
  }
5751
5751
  function __awaiter(thisArg, _arguments, P, generator) {
5752
5752
  function adopt(value) {
5753
- return value instanceof P ? value : new P(function(resolve16) {
5754
- resolve16(value);
5753
+ return value instanceof P ? value : new P(function(resolve17) {
5754
+ resolve17(value);
5755
5755
  });
5756
5756
  }
5757
- return new (P || (P = Promise))(function(resolve16, reject) {
5757
+ return new (P || (P = Promise))(function(resolve17, reject) {
5758
5758
  function fulfilled(value) {
5759
5759
  try {
5760
5760
  step(generator.next(value));
@@ -5770,7 +5770,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
5770
5770
  }
5771
5771
  }
5772
5772
  function step(result) {
5773
- result.done ? resolve16(result.value) : adopt(result.value).then(fulfilled, rejected);
5773
+ result.done ? resolve17(result.value) : adopt(result.value).then(fulfilled, rejected);
5774
5774
  }
5775
5775
  step((generator = generator.apply(thisArg, _arguments || [])).next());
5776
5776
  });
@@ -5961,14 +5961,14 @@ function __asyncValues(o) {
5961
5961
  }, i);
5962
5962
  function verb(n) {
5963
5963
  i[n] = o[n] && function(v) {
5964
- return new Promise(function(resolve16, reject) {
5965
- v = o[n](v), settle(resolve16, reject, v.done, v.value);
5964
+ return new Promise(function(resolve17, reject) {
5965
+ v = o[n](v), settle(resolve17, reject, v.done, v.value);
5966
5966
  });
5967
5967
  };
5968
5968
  }
5969
- function settle(resolve16, reject, d, v) {
5969
+ function settle(resolve17, reject, d, v) {
5970
5970
  Promise.resolve(v).then(function(v2) {
5971
- resolve16({ value: v2, done: d });
5971
+ resolve17({ value: v2, done: d });
5972
5972
  }, reject);
5973
5973
  }
5974
5974
  }
@@ -6060,13 +6060,13 @@ function __disposeResources(env) {
6060
6060
  }
6061
6061
  return next();
6062
6062
  }
6063
- function __rewriteRelativeImportExtension(path22, preserveJsx) {
6064
- if (typeof path22 === "string" && /^\.\.?\//.test(path22)) {
6065
- return path22.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
6063
+ function __rewriteRelativeImportExtension(path23, preserveJsx) {
6064
+ if (typeof path23 === "string" && /^\.\.?\//.test(path23)) {
6065
+ return path23.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
6066
6066
  return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
6067
6067
  });
6068
6068
  }
6069
- return path22;
6069
+ return path23;
6070
6070
  }
6071
6071
  var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
6072
6072
  var init_tslib_es6 = __esm({
@@ -6541,18 +6541,18 @@ var require_main = __commonJS({
6541
6541
 
6542
6542
  // ../../node_modules/.pnpm/@supabase+postgrest-js@2.106.0/node_modules/@supabase/postgrest-js/dist/index.mjs
6543
6543
  function sleep(ms, signal) {
6544
- return new Promise((resolve16) => {
6544
+ return new Promise((resolve17) => {
6545
6545
  if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
6546
- resolve16();
6546
+ resolve17();
6547
6547
  return;
6548
6548
  }
6549
6549
  const id = setTimeout(() => {
6550
6550
  signal === null || signal === void 0 || signal.removeEventListener("abort", onAbort);
6551
- resolve16();
6551
+ resolve17();
6552
6552
  }, ms);
6553
6553
  function onAbort() {
6554
6554
  clearTimeout(id);
6555
- resolve16();
6555
+ resolve17();
6556
6556
  }
6557
6557
  signal === null || signal === void 0 || signal.addEventListener("abort", onAbort);
6558
6558
  });
@@ -14589,15 +14589,15 @@ var require_RealtimeChannel = __commonJS({
14589
14589
  }
14590
14590
  }
14591
14591
  } else {
14592
- return new Promise((resolve16) => {
14592
+ return new Promise((resolve17) => {
14593
14593
  var _a2, _b2, _c;
14594
14594
  const push = this.channelAdapter.push(args.type, args, opts.timeout || this.timeout);
14595
14595
  if (args.type === "broadcast" && !((_c = (_b2 = (_a2 = this.params) === null || _a2 === void 0 ? void 0 : _a2.config) === null || _b2 === void 0 ? void 0 : _b2.broadcast) === null || _c === void 0 ? void 0 : _c.ack)) {
14596
- resolve16("ok");
14596
+ resolve17("ok");
14597
14597
  }
14598
- push.receive("ok", () => resolve16("ok"));
14599
- push.receive("error", () => resolve16("error"));
14600
- push.receive("timeout", () => resolve16("timed out"));
14598
+ push.receive("ok", () => resolve17("ok"));
14599
+ push.receive("error", () => resolve17("error"));
14600
+ push.receive("timeout", () => resolve17("timed out"));
14601
14601
  });
14602
14602
  }
14603
14603
  }
@@ -14622,8 +14622,8 @@ var require_RealtimeChannel = __commonJS({
14622
14622
  * @category Realtime
14623
14623
  */
14624
14624
  async unsubscribe(timeout = this.timeout) {
14625
- return new Promise((resolve16) => {
14626
- this.channelAdapter.unsubscribe(timeout).receive("ok", () => resolve16("ok")).receive("timeout", () => resolve16("timed out")).receive("error", () => resolve16("error"));
14625
+ return new Promise((resolve17) => {
14626
+ this.channelAdapter.unsubscribe(timeout).receive("ok", () => resolve17("ok")).receive("timeout", () => resolve17("timed out")).receive("error", () => resolve17("error"));
14627
14627
  });
14628
14628
  }
14629
14629
  /**
@@ -14827,11 +14827,11 @@ var require_socketAdapter = __commonJS({
14827
14827
  this.socket.connect();
14828
14828
  }
14829
14829
  disconnect(callback, code, reason, timeout = 1e4) {
14830
- return new Promise((resolve16) => {
14831
- setTimeout(() => resolve16("timeout"), timeout);
14830
+ return new Promise((resolve17) => {
14831
+ setTimeout(() => resolve17("timeout"), timeout);
14832
14832
  this.socket.disconnect(() => {
14833
14833
  callback();
14834
- resolve16("ok");
14834
+ resolve17("ok");
14835
14835
  }, code, reason);
14836
14836
  });
14837
14837
  }
@@ -15588,8 +15588,8 @@ var require_main2 = __commonJS({
15588
15588
  });
15589
15589
 
15590
15590
  // ../../node_modules/.pnpm/iceberg-js@0.8.1/node_modules/iceberg-js/dist/index.mjs
15591
- function buildUrl2(baseUrl3, path22, query) {
15592
- const url = new URL(path22, baseUrl3);
15591
+ function buildUrl2(baseUrl3, path23, query) {
15592
+ const url = new URL(path23, baseUrl3);
15593
15593
  if (query) {
15594
15594
  for (const [key, value] of Object.entries(query)) {
15595
15595
  if (value !== void 0) {
@@ -15619,12 +15619,12 @@ function createFetchClient(options) {
15619
15619
  return {
15620
15620
  async request({
15621
15621
  method,
15622
- path: path22,
15622
+ path: path23,
15623
15623
  query,
15624
15624
  body,
15625
15625
  headers
15626
15626
  }) {
15627
- const url = buildUrl2(options.baseUrl, path22, query);
15627
+ const url = buildUrl2(options.baseUrl, path23, query);
15628
15628
  const authHeaders = await buildAuthHeaders(options.auth);
15629
15629
  const res = await fetchFn(url, {
15630
15630
  method,
@@ -16193,7 +16193,7 @@ function normalizeHeaders(headers) {
16193
16193
  return result;
16194
16194
  }
16195
16195
  async function _handleRequest(fetcher, method, url, options, parameters, body, namespace) {
16196
- return new Promise((resolve16, reject) => {
16196
+ return new Promise((resolve17, reject) => {
16197
16197
  fetcher(url, _getRequestParams(method, options, parameters, body)).then((result) => {
16198
16198
  if (!result.ok) throw result;
16199
16199
  if (options === null || options === void 0 ? void 0 : options.noResolveJson) return result;
@@ -16203,7 +16203,7 @@ async function _handleRequest(fetcher, method, url, options, parameters, body, n
16203
16203
  if (!contentType || !contentType.includes("application/json")) return {};
16204
16204
  }
16205
16205
  return result.json();
16206
- }).then((data) => resolve16(data)).catch((error) => handleError(error, reject, options, namespace));
16206
+ }).then((data) => resolve17(data)).catch((error) => handleError(error, reject, options, namespace));
16207
16207
  });
16208
16208
  }
16209
16209
  function createFetchApi(namespace = "storage") {
@@ -16522,7 +16522,7 @@ var init_dist3 = __esm({
16522
16522
  * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
16523
16523
  * @param fileBody The body of the file to be stored in the bucket.
16524
16524
  */
16525
- async uploadOrUpdate(method, path22, fileBody, fileOptions) {
16525
+ async uploadOrUpdate(method, path23, fileBody, fileOptions) {
16526
16526
  var _this = this;
16527
16527
  return _this.handleOperation(async () => {
16528
16528
  let body;
@@ -16546,7 +16546,7 @@ var init_dist3 = __esm({
16546
16546
  if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
16547
16547
  }
16548
16548
  if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
16549
- const cleanPath = _this._removeEmptyFolders(path22);
16549
+ const cleanPath = _this._removeEmptyFolders(path23);
16550
16550
  const _path = _this._getFinalPath(cleanPath);
16551
16551
  const data = await (method == "PUT" ? put : post)(_this.fetch, `${_this.url}/object/${_path}`, body, _objectSpread22({ headers }, (options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}));
16552
16552
  return {
@@ -16608,8 +16608,8 @@ var init_dist3 = __esm({
16608
16608
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16609
16609
  * - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below.
16610
16610
  */
16611
- async upload(path22, fileBody, fileOptions) {
16612
- return this.uploadOrUpdate("POST", path22, fileBody, fileOptions);
16611
+ async upload(path23, fileBody, fileOptions) {
16612
+ return this.uploadOrUpdate("POST", path23, fileBody, fileOptions);
16613
16613
  }
16614
16614
  /**
16615
16615
  * Upload a file with a token generated from `createSignedUploadUrl`.
@@ -16649,9 +16649,9 @@ var init_dist3 = __esm({
16649
16649
  * - `objects` table permissions: none
16650
16650
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16651
16651
  */
16652
- async uploadToSignedUrl(path22, token, fileBody, fileOptions) {
16652
+ async uploadToSignedUrl(path23, token, fileBody, fileOptions) {
16653
16653
  var _this3 = this;
16654
- const cleanPath = _this3._removeEmptyFolders(path22);
16654
+ const cleanPath = _this3._removeEmptyFolders(path23);
16655
16655
  const _path = _this3._getFinalPath(cleanPath);
16656
16656
  const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
16657
16657
  url.searchParams.set("token", token);
@@ -16720,10 +16720,10 @@ var init_dist3 = __esm({
16720
16720
  * - `objects` table permissions: `insert`
16721
16721
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16722
16722
  */
16723
- async createSignedUploadUrl(path22, options) {
16723
+ async createSignedUploadUrl(path23, options) {
16724
16724
  var _this4 = this;
16725
16725
  return _this4.handleOperation(async () => {
16726
- let _path = _this4._getFinalPath(path22);
16726
+ let _path = _this4._getFinalPath(path23);
16727
16727
  const headers = _objectSpread22({}, _this4.headers);
16728
16728
  if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
16729
16729
  const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
@@ -16732,7 +16732,7 @@ var init_dist3 = __esm({
16732
16732
  if (!token) throw new StorageError("No token returned by API");
16733
16733
  return {
16734
16734
  signedUrl: url.toString(),
16735
- path: path22,
16735
+ path: path23,
16736
16736
  token
16737
16737
  };
16738
16738
  });
@@ -16792,8 +16792,8 @@ var init_dist3 = __esm({
16792
16792
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16793
16793
  * - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below.
16794
16794
  */
16795
- async update(path22, fileBody, fileOptions) {
16796
- return this.uploadOrUpdate("PUT", path22, fileBody, fileOptions);
16795
+ async update(path23, fileBody, fileOptions) {
16796
+ return this.uploadOrUpdate("PUT", path23, fileBody, fileOptions);
16797
16797
  }
16798
16798
  /**
16799
16799
  * Moves an existing file to a new path in the same bucket.
@@ -16944,10 +16944,10 @@ var init_dist3 = __esm({
16944
16944
  * - `objects` table permissions: `select`
16945
16945
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16946
16946
  */
16947
- async createSignedUrl(path22, expiresIn, options) {
16947
+ async createSignedUrl(path23, expiresIn, options) {
16948
16948
  var _this8 = this;
16949
16949
  return _this8.handleOperation(async () => {
16950
- let _path = _this8._getFinalPath(path22);
16950
+ let _path = _this8._getFinalPath(path23);
16951
16951
  const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
16952
16952
  let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
16953
16953
  const query = new URLSearchParams();
@@ -17083,13 +17083,13 @@ var init_dist3 = __esm({
17083
17083
  * - `objects` table permissions: `select`
17084
17084
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
17085
17085
  */
17086
- download(path22, options, parameters) {
17086
+ download(path23, options, parameters) {
17087
17087
  const renderPath = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0 ? "render/image/authenticated" : "object";
17088
17088
  const query = new URLSearchParams();
17089
17089
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
17090
17090
  if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
17091
17091
  const queryString = query.toString();
17092
- const _path = this._getFinalPath(path22);
17092
+ const _path = this._getFinalPath(path23);
17093
17093
  const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
17094
17094
  headers: this.headers,
17095
17095
  noResolveJson: true
@@ -17120,9 +17120,9 @@ var init_dist3 = __esm({
17120
17120
  * }
17121
17121
  * ```
17122
17122
  */
17123
- async info(path22) {
17123
+ async info(path23) {
17124
17124
  var _this10 = this;
17125
- const _path = _this10._getFinalPath(path22);
17125
+ const _path = _this10._getFinalPath(path23);
17126
17126
  return _this10.handleOperation(async () => {
17127
17127
  return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
17128
17128
  });
@@ -17143,9 +17143,9 @@ var init_dist3 = __esm({
17143
17143
  * .exists('folder/avatar1.png')
17144
17144
  * ```
17145
17145
  */
17146
- async exists(path22) {
17146
+ async exists(path23) {
17147
17147
  var _this11 = this;
17148
- const _path = _this11._getFinalPath(path22);
17148
+ const _path = _this11._getFinalPath(path23);
17149
17149
  try {
17150
17150
  await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
17151
17151
  return {
@@ -17224,8 +17224,8 @@ var init_dist3 = __esm({
17224
17224
  * - `objects` table permissions: none
17225
17225
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
17226
17226
  */
17227
- getPublicUrl(path22, options) {
17228
- const _path = this._getFinalPath(path22);
17227
+ getPublicUrl(path23, options) {
17228
+ const _path = this._getFinalPath(path23);
17229
17229
  const query = new URLSearchParams();
17230
17230
  if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
17231
17231
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
@@ -17364,10 +17364,10 @@ var init_dist3 = __esm({
17364
17364
  * - `objects` table permissions: `select`
17365
17365
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
17366
17366
  */
17367
- async list(path22, options, parameters) {
17367
+ async list(path23, options, parameters) {
17368
17368
  var _this13 = this;
17369
17369
  return _this13.handleOperation(async () => {
17370
- const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path22 || "" });
17370
+ const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path23 || "" });
17371
17371
  return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
17372
17372
  });
17373
17373
  }
@@ -17432,11 +17432,11 @@ var init_dist3 = __esm({
17432
17432
  if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
17433
17433
  return btoa(data);
17434
17434
  }
17435
- _getFinalPath(path22) {
17436
- return `${this.bucketId}/${path22.replace(/^\/+/, "")}`;
17435
+ _getFinalPath(path23) {
17436
+ return `${this.bucketId}/${path23.replace(/^\/+/, "")}`;
17437
17437
  }
17438
- _removeEmptyFolders(path22) {
17439
- return path22.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
17438
+ _removeEmptyFolders(path23) {
17439
+ return path23.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
17440
17440
  }
17441
17441
  /** Modifies the `query`, appending values the from `transform` */
17442
17442
  applyTransformOptsToQuery(query, transform) {
@@ -26814,11 +26814,11 @@ __export(dist_exports, {
26814
26814
  });
26815
26815
  function __awaiter2(thisArg, _arguments, P, generator) {
26816
26816
  function adopt(value) {
26817
- return value instanceof P ? value : new P(function(resolve16) {
26818
- resolve16(value);
26817
+ return value instanceof P ? value : new P(function(resolve17) {
26818
+ resolve17(value);
26819
26819
  });
26820
26820
  }
26821
- return new (P || (P = Promise))(function(resolve16, reject) {
26821
+ return new (P || (P = Promise))(function(resolve17, reject) {
26822
26822
  function fulfilled(value) {
26823
26823
  try {
26824
26824
  step(generator.next(value));
@@ -26834,7 +26834,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
26834
26834
  }
26835
26835
  }
26836
26836
  function step(result) {
26837
- result.done ? resolve16(result.value) : adopt(result.value).then(fulfilled, rejected);
26837
+ result.done ? resolve17(result.value) : adopt(result.value).then(fulfilled, rejected);
26838
26838
  }
26839
26839
  step((generator = generator.apply(thisArg, _arguments || [])).next());
26840
26840
  });
@@ -27569,8 +27569,8 @@ var init_watch_daemon = __esm({
27569
27569
  );
27570
27570
  }
27571
27571
  this.startSafetyPoll(repoRoot, repoId, worktreeId);
27572
- await new Promise((resolve16) => {
27573
- this.stopResolve = resolve16;
27572
+ await new Promise((resolve17) => {
27573
+ this.stopResolve = resolve17;
27574
27574
  });
27575
27575
  }
27576
27576
  /**
@@ -27841,7 +27841,7 @@ var init_watch_daemon = __esm({
27841
27841
  }
27842
27842
  /** Sleep for `ms` milliseconds — uses setTimeout so fake timers work in tests. */
27843
27843
  sleep(ms) {
27844
- return new Promise((resolve16) => setTimeout(resolve16, ms));
27844
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
27845
27845
  }
27846
27846
  };
27847
27847
  }
@@ -28158,8 +28158,8 @@ var init_watch = __esm({
28158
28158
  function isConflict(err) {
28159
28159
  return err instanceof BackendError && err.status === 409;
28160
28160
  }
28161
- async function backendRequest(method, path22, body) {
28162
- const url = `${getBackendBase()}${path22}`;
28161
+ async function backendRequest(method, path23, body) {
28162
+ const url = `${getBackendBase()}${path23}`;
28163
28163
  const auth = await getAuthHeaders();
28164
28164
  const res = await fetch(url, {
28165
28165
  method,
@@ -28171,7 +28171,7 @@ async function backendRequest(method, path22, body) {
28171
28171
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
28172
28172
  });
28173
28173
  if (!res.ok) {
28174
- let message = `Backend ${method} ${path22} failed with status ${res.status}`;
28174
+ let message = `Backend ${method} ${path23} failed with status ${res.status}`;
28175
28175
  try {
28176
28176
  const errBody = await res.json();
28177
28177
  const msg = typeof errBody.message === "string" ? errBody.message : typeof errBody.error === "string" ? errBody.error : void 0;
@@ -28185,11 +28185,11 @@ async function backendRequest(method, path22, body) {
28185
28185
  }
28186
28186
  return res.json();
28187
28187
  }
28188
- async function apiBackendPost(path22, body) {
28189
- return backendRequest("POST", path22, body);
28188
+ async function apiBackendPost(path23, body) {
28189
+ return backendRequest("POST", path23, body);
28190
28190
  }
28191
- async function apiBackendPatch(path22, body) {
28192
- return backendRequest("PATCH", path22, body);
28191
+ async function apiBackendPatch(path23, body) {
28192
+ return backendRequest("PATCH", path23, body);
28193
28193
  }
28194
28194
  var REQUEST_TIMEOUT_MS2, BackendError;
28195
28195
  var init_state_client = __esm({
@@ -28465,8 +28465,8 @@ ${taskRows}
28465
28465
  for (const task of data.tasks) {
28466
28466
  if (Array.isArray(task.files_changed)) {
28467
28467
  for (const f of task.files_changed) {
28468
- const path22 = typeof f === "string" ? f : f?.path;
28469
- if (path22) allFiles.add(path22);
28468
+ const path23 = typeof f === "string" ? f : f?.path;
28469
+ if (path23) allFiles.add(path23);
28470
28470
  }
28471
28471
  }
28472
28472
  }
@@ -29388,7 +29388,7 @@ function setRetryDelayMs(ms) {
29388
29388
  RETRY_DELAY_MS = ms;
29389
29389
  }
29390
29390
  function sleep2(ms) {
29391
- return new Promise((resolve16) => setTimeout(resolve16, ms));
29391
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
29392
29392
  }
29393
29393
  function isTransientMcpError(err) {
29394
29394
  if (!(err instanceof McpError)) return false;
@@ -30528,7 +30528,7 @@ function generateMonotonicTimestamp(opts = {}) {
30528
30528
  }
30529
30529
  async function pollGhPreviewCheck(opts = {}) {
30530
30530
  const run = opts.run ?? defaultRun;
30531
- const sleep3 = opts.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
30531
+ const sleep3 = opts.sleep ?? ((ms) => new Promise((resolve17) => setTimeout(resolve17, ms)));
30532
30532
  const maxPolls = opts.maxPolls ?? 20;
30533
30533
  const intervalMs = opts.intervalMs ?? 15e3;
30534
30534
  if (!opts.prNumber) {
@@ -33273,12 +33273,60 @@ var init_atomic_write = __esm({
33273
33273
  }
33274
33274
  });
33275
33275
 
33276
+ // src/lib/repo-reader.ts
33277
+ import * as fsPromises from "node:fs/promises";
33278
+ import * as path10 from "node:path";
33279
+ var LocalFsReader;
33280
+ var init_repo_reader = __esm({
33281
+ "src/lib/repo-reader.ts"() {
33282
+ "use strict";
33283
+ LocalFsReader = class {
33284
+ constructor(rootDir) {
33285
+ this.rootDir = rootDir;
33286
+ }
33287
+ rootDir;
33288
+ resolve(p) {
33289
+ return path10.isAbsolute(p) ? p : path10.resolve(this.rootDir, p);
33290
+ }
33291
+ async list(dir) {
33292
+ const abs = this.resolve(dir);
33293
+ try {
33294
+ const entries = await fsPromises.readdir(abs, { withFileTypes: true });
33295
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
33296
+ } catch {
33297
+ return [];
33298
+ }
33299
+ }
33300
+ async read(filePath) {
33301
+ const abs = this.resolve(filePath);
33302
+ try {
33303
+ return await fsPromises.readFile(abs, "utf-8");
33304
+ } catch (err) {
33305
+ throw new Error(
33306
+ `repo-reader: could not read '${abs}': ${err instanceof Error ? err.message : String(err)}`
33307
+ );
33308
+ }
33309
+ }
33310
+ async exists(filePath) {
33311
+ const abs = this.resolve(filePath);
33312
+ try {
33313
+ await fsPromises.access(abs);
33314
+ return true;
33315
+ } catch {
33316
+ return false;
33317
+ }
33318
+ }
33319
+ };
33320
+ }
33321
+ });
33322
+
33276
33323
  // src/lib/ci-init.ts
33277
33324
  import * as fs8 from "node:fs";
33278
- import * as path10 from "node:path";
33279
- function tryReadJson(filePath) {
33325
+ import * as path11 from "node:path";
33326
+ async function tryReadJson(reader, filePath) {
33280
33327
  try {
33281
- return JSON.parse(fs8.readFileSync(filePath, "utf-8"));
33328
+ const raw = await reader.read(filePath);
33329
+ return JSON.parse(raw);
33282
33330
  } catch {
33283
33331
  return null;
33284
33332
  }
@@ -33294,30 +33342,24 @@ function hasDevDep(pkg, name) {
33294
33342
  const devDeps = pkg["devDependencies"];
33295
33343
  return Boolean(devDeps?.[name]);
33296
33344
  }
33297
- function detectPlatforms(projectDir) {
33345
+ async function detectPlatforms(reader) {
33298
33346
  const detected = /* @__PURE__ */ new Set();
33299
- const dirsToScan = [projectDir];
33300
- const appsDir = path10.join(projectDir, "apps");
33301
- if (fs8.existsSync(appsDir)) {
33302
- try {
33303
- const appsEntries = fs8.readdirSync(appsDir, { withFileTypes: true });
33304
- for (const entry of appsEntries) {
33305
- if (entry.isDirectory()) {
33306
- dirsToScan.push(path10.join(appsDir, entry.name));
33307
- }
33308
- }
33309
- } catch {
33310
- }
33347
+ const dirsToScan = [""];
33348
+ const appsChildren = await reader.list("apps");
33349
+ for (const name of appsChildren) {
33350
+ dirsToScan.push(`apps/${name}`);
33311
33351
  }
33312
33352
  for (const dir of dirsToScan) {
33313
- const pkg = tryReadJson(path10.join(dir, "package.json"));
33314
- if (fs8.existsSync(path10.join(dir, "next.config.ts")) || fs8.existsSync(path10.join(dir, "next.config.js")) || fs8.existsSync(path10.join(dir, "next.config.mjs"))) {
33353
+ const pkgPath = dir ? `${dir}/package.json` : "package.json";
33354
+ const pkg = await tryReadJson(reader, pkgPath);
33355
+ const nextBase = dir ? `${dir}/` : "";
33356
+ if (await reader.exists(`${nextBase}next.config.ts`) || await reader.exists(`${nextBase}next.config.js`) || await reader.exists(`${nextBase}next.config.mjs`)) {
33315
33357
  detected.add("next_js");
33316
33358
  }
33317
33359
  if (hasDep(pkg, "@nestjs/core")) {
33318
33360
  detected.add("nestjs");
33319
33361
  }
33320
- if (fs8.existsSync(path10.join(dir, "tauri.conf.json")) || fs8.existsSync(path10.join(dir, "src-tauri"))) {
33362
+ if (await reader.exists(`${nextBase}tauri.conf.json`) || await reader.exists(`${nextBase}src-tauri`)) {
33321
33363
  detected.add("tauri");
33322
33364
  }
33323
33365
  if (hasDevDep(pkg, "@types/vscode")) {
@@ -33328,15 +33370,9 @@ function detectPlatforms(projectDir) {
33328
33370
  detected.add("expo");
33329
33371
  }
33330
33372
  }
33331
- const packagesDir = path10.join(projectDir, "packages");
33332
- if (fs8.existsSync(packagesDir)) {
33333
- try {
33334
- const pkgEntries = fs8.readdirSync(packagesDir, { withFileTypes: true });
33335
- if (pkgEntries.some((e) => e.isDirectory())) {
33336
- detected.add("package");
33337
- }
33338
- } catch {
33339
- }
33373
+ const packagesChildren = await reader.list("packages");
33374
+ if (packagesChildren.length > 0) {
33375
+ detected.add("package");
33340
33376
  }
33341
33377
  if (detected.size === 0) {
33342
33378
  detected.add("package");
@@ -33364,12 +33400,12 @@ function buildDefaultCiConfig(platforms) {
33364
33400
  return config;
33365
33401
  }
33366
33402
  async function runCiInit(opts) {
33367
- await Promise.resolve();
33368
- const projectDir = path10.resolve(opts?.projectDir ?? process.cwd());
33403
+ const projectDir = path11.resolve(opts?.projectDir ?? process.cwd());
33369
33404
  const dryRun = opts?.dryRun ?? false;
33370
33405
  const force = opts?.force ?? false;
33371
- const ciPath = path10.join(projectDir, ".codebyplan", "ci.json");
33372
- const platforms = detectPlatforms(projectDir);
33406
+ const ciPath = path11.join(projectDir, ".codebyplan", "ci.json");
33407
+ const reader = opts?.reader ?? new LocalFsReader(projectDir);
33408
+ const platforms = await detectPlatforms(reader);
33373
33409
  if (dryRun) {
33374
33410
  return { status: "dry_run", path: ciPath, platforms };
33375
33411
  }
@@ -33413,7 +33449,7 @@ async function runCiInit(opts) {
33413
33449
  platforms: newPlatforms.length > 0 ? newPlatforms : platforms
33414
33450
  };
33415
33451
  }
33416
- const codebyplanDir = path10.join(projectDir, ".codebyplan");
33452
+ const codebyplanDir = path11.join(projectDir, ".codebyplan");
33417
33453
  fs8.mkdirSync(codebyplanDir, { recursive: true });
33418
33454
  writeJsonAtomic(ciPath, newConfig);
33419
33455
  return { status: "written", path: ciPath, platforms };
@@ -33423,6 +33459,7 @@ var init_ci_init = __esm({
33423
33459
  "src/lib/ci-init.ts"() {
33424
33460
  "use strict";
33425
33461
  init_atomic_write();
33462
+ init_repo_reader();
33426
33463
  PLATFORM_COMMAND_MAP = {
33427
33464
  next_js: {
33428
33465
  unit_test: {
@@ -33622,7 +33659,7 @@ var init_ci_init = __esm({
33622
33659
 
33623
33660
  // src/lib/scaffold-ci-workflow.ts
33624
33661
  import * as fs9 from "node:fs";
33625
- import * as path11 from "node:path";
33662
+ import * as path12 from "node:path";
33626
33663
  function substituteTokens(template, tokens) {
33627
33664
  let result = template;
33628
33665
  for (const [token, value] of Object.entries(tokens)) {
@@ -33630,10 +33667,9 @@ function substituteTokens(template, tokens) {
33630
33667
  }
33631
33668
  return result;
33632
33669
  }
33633
- function detectPnpmVersionFromPackageJson(projectDir) {
33670
+ async function detectPnpmVersionFromPackageJson(reader) {
33634
33671
  try {
33635
- const pkgPath = path11.join(projectDir, "package.json");
33636
- const raw = fs9.readFileSync(pkgPath, "utf-8");
33672
+ const raw = await reader.read("package.json");
33637
33673
  const pkg = JSON.parse(raw);
33638
33674
  const pm = pkg.packageManager;
33639
33675
  if (typeof pm === "string" && pm.startsWith("pnpm@")) {
@@ -33647,39 +33683,42 @@ function detectPnpmVersionFromPackageJson(projectDir) {
33647
33683
  return "10";
33648
33684
  }
33649
33685
  }
33650
- function detectStrictEnforcedFromCiJson(projectDir) {
33686
+ async function detectStrictEnforcedFromCiJson(reader) {
33651
33687
  try {
33652
- const ciJsonPath = path11.join(projectDir, ".codebyplan", "ci.json");
33653
- const raw = fs9.readFileSync(ciJsonPath, "utf-8");
33688
+ const raw = await reader.read(".codebyplan/ci.json");
33654
33689
  const parsed = JSON.parse(raw);
33655
33690
  return parsed.workflow?.strict_check_enforced === true;
33656
33691
  } catch {
33657
33692
  return false;
33658
33693
  }
33659
33694
  }
33660
- async function runScaffoldCiWorkflow(opts) {
33661
- await Promise.resolve();
33662
- const dryRun = opts?.dryRun ?? false;
33663
- const force = opts?.force ?? false;
33664
- const projectDir = path11.resolve(opts?.projectDir ?? process.cwd());
33665
- const pnpmVersion = opts?.pnpmVersion ?? detectPnpmVersionFromPackageJson(projectDir);
33695
+ async function renderCiWorkflowContent(opts) {
33696
+ const projectDir = path12.resolve(opts?.projectDir ?? process.cwd());
33697
+ const reader = opts?.reader ?? new LocalFsReader(projectDir);
33698
+ const pnpmVersion = opts?.pnpmVersion ?? await detectPnpmVersionFromPackageJson(reader);
33666
33699
  const nodeVersion = opts?.nodeVersion ?? "22";
33667
- const strictEnforced = opts?.strictEnforced ?? detectStrictEnforcedFromCiJson(projectDir);
33700
+ const strictEnforced = opts?.strictEnforced ?? await detectStrictEnforcedFromCiJson(reader);
33668
33701
  const templatesDir = opts?.templatesDir ?? resolveTemplatesDir();
33669
- const templatePath = path11.join(templatesDir, "github-workflows", "ci.yml");
33702
+ const templatePath = path12.join(templatesDir, "github-workflows", "ci.yml");
33670
33703
  if (!fs9.existsSync(templatePath)) {
33671
33704
  throw new Error(
33672
33705
  `scaffold-ci-workflow: template not found at ${templatePath}`
33673
33706
  );
33674
33707
  }
33675
33708
  const rawTemplate = fs9.readFileSync(templatePath, "utf-8");
33676
- const renderedContent = substituteTokens(rawTemplate, {
33709
+ return substituteTokens(rawTemplate, {
33677
33710
  PNPM_VERSION: pnpmVersion,
33678
33711
  NODE_VERSION: nodeVersion,
33679
33712
  STRICT_NAME_SUFFIX: strictEnforced ? "" : " (report-only)",
33680
33713
  STRICT_CONTINUE_ON_ERROR_LINE: strictEnforced ? "" : "\n continue-on-error: true"
33681
33714
  });
33682
- const targetPath = path11.join(projectDir, ".github", "workflows", "ci.yml");
33715
+ }
33716
+ async function runScaffoldCiWorkflow(opts) {
33717
+ const dryRun = opts?.dryRun ?? false;
33718
+ const force = opts?.force ?? false;
33719
+ const projectDir = path12.resolve(opts?.projectDir ?? process.cwd());
33720
+ const renderedContent = await renderCiWorkflowContent(opts);
33721
+ const targetPath = path12.join(projectDir, ".github", "workflows", "ci.yml");
33683
33722
  if (dryRun) {
33684
33723
  return { status: "dry_run", path: targetPath };
33685
33724
  }
@@ -33698,7 +33737,7 @@ async function runScaffoldCiWorkflow(opts) {
33698
33737
  );
33699
33738
  }
33700
33739
  }
33701
- const targetDir = path11.dirname(targetPath);
33740
+ const targetDir = path12.dirname(targetPath);
33702
33741
  fs9.mkdirSync(targetDir, { recursive: true });
33703
33742
  const tmpPath = targetPath + ".tmp";
33704
33743
  try {
@@ -33716,16 +33755,17 @@ async function runScaffoldCiWorkflow(opts) {
33716
33755
  var init_scaffold_ci_workflow = __esm({
33717
33756
  "src/lib/scaffold-ci-workflow.ts"() {
33718
33757
  "use strict";
33719
- init_install();
33758
+ init_templates_dir();
33759
+ init_repo_reader();
33720
33760
  }
33721
33761
  });
33722
33762
 
33723
33763
  // src/lib/gh-required-checks.ts
33724
33764
  import * as fs10 from "node:fs";
33725
- import * as path12 from "node:path";
33765
+ import * as path13 from "node:path";
33726
33766
  import { execSync as execSync6 } from "node:child_process";
33727
33767
  function readCiJson(projectDir) {
33728
- const ciPath = path12.join(projectDir, ".codebyplan", "ci.json");
33768
+ const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33729
33769
  if (!fs10.existsSync(ciPath)) {
33730
33770
  return {
33731
33771
  platforms: {},
@@ -33744,15 +33784,15 @@ function readCiJson(projectDir) {
33744
33784
  }
33745
33785
  }
33746
33786
  function writeCiJsonAtomic(projectDir, config) {
33747
- const ciPath = path12.join(projectDir, ".codebyplan", "ci.json");
33787
+ const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33748
33788
  writeJsonAtomic(ciPath, config);
33749
33789
  }
33750
33790
  function enforceRequiredCheck(opts) {
33751
- const projectDir = path12.resolve(opts?.projectDir ?? process.cwd());
33791
+ const projectDir = path13.resolve(opts?.projectDir ?? process.cwd());
33752
33792
  const branch = opts?.branch ?? "main";
33753
33793
  const checkName = opts?.checkName ?? "Lint + typecheck + test + build";
33754
33794
  const dryRun = opts?.dryRun ?? false;
33755
- const ciPath = path12.join(projectDir, ".codebyplan", "ci.json");
33795
+ const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33756
33796
  const config = readCiJson(projectDir);
33757
33797
  if (config.workflow?.required_check_enforced === true) {
33758
33798
  return { status: "already_enforced", path: ciPath };
@@ -34159,9 +34199,9 @@ var init_ci = __esm({
34159
34199
 
34160
34200
  // src/lib/cd-init.ts
34161
34201
  import * as fs11 from "node:fs";
34162
- import * as path13 from "node:path";
34202
+ import * as path14 from "node:path";
34163
34203
  function detectSurfaces(projectDir) {
34164
- const shipmentPath = path13.join(projectDir, ".codebyplan", "shipment.json");
34204
+ const shipmentPath = path14.join(projectDir, ".codebyplan", "shipment.json");
34165
34205
  let shipment;
34166
34206
  try {
34167
34207
  shipment = JSON.parse(fs11.readFileSync(shipmentPath, "utf-8"));
@@ -34214,10 +34254,10 @@ function buildDefaultCdConfig(rawSurfaceKeys) {
34214
34254
  }
34215
34255
  async function runCdInit(opts) {
34216
34256
  await Promise.resolve();
34217
- const projectDir = path13.resolve(opts?.projectDir ?? process.cwd());
34257
+ const projectDir = path14.resolve(opts?.projectDir ?? process.cwd());
34218
34258
  const dryRun = opts?.dryRun ?? false;
34219
34259
  const force = opts?.force ?? false;
34220
- const cdPath = path13.join(projectDir, ".codebyplan", "cd.json");
34260
+ const cdPath = path14.join(projectDir, ".codebyplan", "cd.json");
34221
34261
  const rawSurfaceKeys = detectSurfaces(projectDir);
34222
34262
  const seen = /* @__PURE__ */ new Set();
34223
34263
  const surfaces = [];
@@ -34258,7 +34298,7 @@ async function runCdInit(opts) {
34258
34298
  surfaces: newSurfaces
34259
34299
  };
34260
34300
  }
34261
- const codebyplanDir = path13.join(projectDir, ".codebyplan");
34301
+ const codebyplanDir = path14.join(projectDir, ".codebyplan");
34262
34302
  fs11.mkdirSync(codebyplanDir, { recursive: true });
34263
34303
  writeJsonAtomic(cdPath, newConfig);
34264
34304
  return { status: "written", path: cdPath, surfaces };
@@ -34348,14 +34388,14 @@ var init_cd_init = __esm({
34348
34388
 
34349
34389
  // src/lib/scaffold-cd-workflow.ts
34350
34390
  import * as fs12 from "node:fs";
34351
- import * as path14 from "node:path";
34391
+ import * as path15 from "node:path";
34352
34392
  async function scaffoldOneWorkflow(templateName, targetName, opts) {
34353
34393
  await Promise.resolve();
34354
34394
  const dryRun = opts.dryRun ?? false;
34355
34395
  const force = opts.force ?? false;
34356
- const projectDir = path14.resolve(opts.projectDir ?? process.cwd());
34396
+ const projectDir = path15.resolve(opts.projectDir ?? process.cwd());
34357
34397
  const templatesDir = opts.templatesDir ?? resolveTemplatesDir();
34358
- const templatePath = path14.join(
34398
+ const templatePath = path15.join(
34359
34399
  templatesDir,
34360
34400
  "github-workflows",
34361
34401
  templateName
@@ -34366,7 +34406,7 @@ async function scaffoldOneWorkflow(templateName, targetName, opts) {
34366
34406
  );
34367
34407
  }
34368
34408
  const templateContent = fs12.readFileSync(templatePath, "utf-8");
34369
- const targetPath = path14.join(projectDir, ".github", "workflows", targetName);
34409
+ const targetPath = path15.join(projectDir, ".github", "workflows", targetName);
34370
34410
  if (dryRun) {
34371
34411
  return { status: "dry_run", path: targetPath };
34372
34412
  }
@@ -34385,7 +34425,7 @@ async function scaffoldOneWorkflow(templateName, targetName, opts) {
34385
34425
  );
34386
34426
  }
34387
34427
  }
34388
- const targetDir = path14.dirname(targetPath);
34428
+ const targetDir = path15.dirname(targetPath);
34389
34429
  fs12.mkdirSync(targetDir, { recursive: true });
34390
34430
  const tmpPath = targetPath + ".tmp";
34391
34431
  try {
@@ -35218,8 +35258,8 @@ var upload_e2e_images_exports = {};
35218
35258
  __export(upload_e2e_images_exports, {
35219
35259
  runUploadE2eImagesCommand: () => runUploadE2eImagesCommand
35220
35260
  });
35221
- import { readFile as readFile20 } from "node:fs/promises";
35222
- import { join as join36, basename as basename2, resolve as resolve10 } from "node:path";
35261
+ import { readFile as readFile21 } from "node:fs/promises";
35262
+ import { join as join36, basename as basename2, resolve as resolve11 } from "node:path";
35223
35263
  import { execSync as execSync8 } from "node:child_process";
35224
35264
  function baseUrl2() {
35225
35265
  return (process.env.CODEBYPLAN_API_URL ?? "https://www.codebyplan.com").replace(/\/$/, "");
@@ -35253,7 +35293,7 @@ function parseArgs(args) {
35253
35293
  }
35254
35294
  async function readE2eConfig(projectPath) {
35255
35295
  try {
35256
- const raw = await readFile20(
35296
+ const raw = await readFile21(
35257
35297
  join36(projectPath, ".codebyplan", "e2e.json"),
35258
35298
  "utf-8"
35259
35299
  );
@@ -35334,7 +35374,7 @@ async function runUploadE2eImagesCommand(args) {
35334
35374
  process.exit(1);
35335
35375
  }
35336
35376
  const checkpointId = parsed.checkpointId;
35337
- const projectPath = resolve10(process.cwd());
35377
+ const projectPath = resolve11(process.cwd());
35338
35378
  let repoId = parsed.repoId;
35339
35379
  if (!repoId) {
35340
35380
  const found = await findCodebyplanConfig(projectPath);
@@ -35392,7 +35432,7 @@ async function runUploadE2eImagesCommand(args) {
35392
35432
  for (const png of allPngs) {
35393
35433
  let bytes;
35394
35434
  try {
35395
- bytes = await readFile20(png.absolutePath);
35435
+ bytes = await readFile21(png.absolutePath);
35396
35436
  } catch {
35397
35437
  process.stderr.write(
35398
35438
  `upload-e2e-images: could not read file: ${png.absolutePath}
@@ -35469,8 +35509,8 @@ __export(arch_map_exports, {
35469
35509
  runArchMapCommand: () => runArchMapCommand,
35470
35510
  updateFrontmatterFields: () => updateFrontmatterFields
35471
35511
  });
35472
- import { readFile as readFile21, writeFile as writeFile17 } from "node:fs/promises";
35473
- import { existsSync as existsSync11, readdirSync as readdirSync4 } from "node:fs";
35512
+ import { readFile as readFile22, writeFile as writeFile17 } from "node:fs/promises";
35513
+ import { existsSync as existsSync11, readdirSync as readdirSync3 } from "node:fs";
35474
35514
  import { join as join37 } from "node:path";
35475
35515
  import { spawnSync as spawnSync12 } from "node:child_process";
35476
35516
  function normalizeModulePath(modulePath) {
@@ -35498,7 +35538,7 @@ async function resolveCodebyplanDir(startDir) {
35498
35538
  async function readArchitectureConfig(codebyplanDir) {
35499
35539
  const filePath = join37(codebyplanDir, "architecture.json");
35500
35540
  try {
35501
- const raw = await readFile21(filePath, "utf-8");
35541
+ const raw = await readFile22(filePath, "utf-8");
35502
35542
  const parsed = JSON.parse(raw);
35503
35543
  if (typeof parsed !== "object" || parsed === null || !Array.isArray(parsed.modules)) {
35504
35544
  return { version: 1, modules: [] };
@@ -35531,7 +35571,7 @@ async function discoverModulePaths(projectRoot) {
35531
35571
  const workspacePath = join37(projectRoot, "pnpm-workspace.yaml");
35532
35572
  let patterns = [];
35533
35573
  try {
35534
- const raw = await readFile21(workspacePath, "utf-8");
35574
+ const raw = await readFile22(workspacePath, "utf-8");
35535
35575
  const lines = raw.split("\n");
35536
35576
  let inPackages = false;
35537
35577
  for (const line of lines) {
@@ -35558,7 +35598,7 @@ async function discoverModulePaths(projectRoot) {
35558
35598
  const absDir = join37(projectRoot, dir);
35559
35599
  try {
35560
35600
  if (existsSync11(absDir)) {
35561
- const entries = readdirSync4(absDir, { withFileTypes: true });
35601
+ const entries = readdirSync3(absDir, { withFileTypes: true });
35562
35602
  for (const entry of entries) {
35563
35603
  if (entry.isDirectory()) {
35564
35604
  paths.push(`${dir}/${entry.name}`);
@@ -35765,7 +35805,7 @@ async function runStamp(modulePath, sha, depthArg, projectRoot) {
35765
35805
  const mapAbsPath = join37(repoRoot, stampedEntry.map_file);
35766
35806
  let mapContent = null;
35767
35807
  try {
35768
- mapContent = await readFile21(mapAbsPath, "utf-8");
35808
+ mapContent = await readFile22(mapAbsPath, "utf-8");
35769
35809
  } catch {
35770
35810
  console.warn(
35771
35811
  " Warning: map file " + stampedEntry.map_file + " not found \u2014 stamped manifest only"
@@ -35967,7 +36007,7 @@ var init_worktree_port_resolver = __esm({
35967
36007
  });
35968
36008
 
35969
36009
  // src/lib/migrate-local-config.ts
35970
- import { mkdir as mkdir9, readFile as readFile22, unlink as unlink5, writeFile as writeFile18 } from "node:fs/promises";
36010
+ import { mkdir as mkdir9, readFile as readFile23, unlink as unlink5, writeFile as writeFile18 } from "node:fs/promises";
35971
36011
  import { join as join38 } from "node:path";
35972
36012
  function legacySharedPath(projectPath) {
35973
36013
  return join38(projectPath, ".codebyplan.json");
@@ -36018,7 +36058,7 @@ async function runLocalMigration(projectPath) {
36018
36058
  }
36019
36059
  let legacyRaw;
36020
36060
  try {
36021
- legacyRaw = await readFile22(legacySharedPath(projectPath), "utf-8");
36061
+ legacyRaw = await readFile23(legacySharedPath(projectPath), "utf-8");
36022
36062
  } catch {
36023
36063
  return {
36024
36064
  migrated: true,
@@ -36045,7 +36085,7 @@ async function runLocalMigration(projectPath) {
36045
36085
  let deviceId;
36046
36086
  let deviceWrittenByHelper = false;
36047
36087
  try {
36048
- const localRaw = await readFile22(legacyLocalPath(projectPath), "utf-8");
36088
+ const localRaw = await readFile23(legacyLocalPath(projectPath), "utf-8");
36049
36089
  const localParsed = JSON.parse(localRaw);
36050
36090
  if (typeof localParsed.device_id === "string") {
36051
36091
  deviceId = localParsed.device_id;
@@ -36145,7 +36185,7 @@ async function runLocalMigration(projectPath) {
36145
36185
  }
36146
36186
  const gitignorePath = join38(projectPath, ".gitignore");
36147
36187
  try {
36148
- const gitignoreContent = await readFile22(gitignorePath, "utf-8");
36188
+ const gitignoreContent = await readFile23(gitignorePath, "utf-8");
36149
36189
  const legacyLine = ".codebyplan.local.json";
36150
36190
  const newLine = ".codebyplan/device.local.json";
36151
36191
  const hasLegacy = gitignoreContent.split("\n").some((l) => l.trimEnd() === legacyLine);
@@ -36206,7 +36246,7 @@ __export(config_exports, {
36206
36246
  runConfig: () => runConfig,
36207
36247
  runConfigMigrate: () => runConfigMigrate
36208
36248
  });
36209
- import { mkdir as mkdir10, readFile as readFile23, writeFile as writeFile19 } from "node:fs/promises";
36249
+ import { mkdir as mkdir10, readFile as readFile24, writeFile as writeFile19 } from "node:fs/promises";
36210
36250
  import { join as join39 } from "node:path";
36211
36251
  async function runConfig() {
36212
36252
  const flags = parseFlags(3);
@@ -36337,7 +36377,7 @@ async function syncConfigToFile(repoId, projectPath, dryRun) {
36337
36377
  const newJson = JSON.stringify(payload, null, 2) + "\n";
36338
36378
  let currentJson = "";
36339
36379
  try {
36340
- currentJson = await readFile23(filePath, "utf-8");
36380
+ currentJson = await readFile24(filePath, "utf-8");
36341
36381
  } catch {
36342
36382
  }
36343
36383
  if (createOnly && currentJson !== "") continue;
@@ -36352,7 +36392,7 @@ async function syncConfigToFile(repoId, projectPath, dryRun) {
36352
36392
  }
36353
36393
  async function readRepoConfig(projectPath) {
36354
36394
  try {
36355
- const raw = await readFile23(
36395
+ const raw = await readFile24(
36356
36396
  join39(projectPath, ".codebyplan", "repo.json"),
36357
36397
  "utf-8"
36358
36398
  );
@@ -36363,7 +36403,7 @@ async function readRepoConfig(projectPath) {
36363
36403
  }
36364
36404
  async function readServerConfig(projectPath) {
36365
36405
  try {
36366
- const raw = await readFile23(
36406
+ const raw = await readFile24(
36367
36407
  join39(projectPath, ".codebyplan", "server.json"),
36368
36408
  "utf-8"
36369
36409
  );
@@ -36374,7 +36414,7 @@ async function readServerConfig(projectPath) {
36374
36414
  }
36375
36415
  async function readGitConfig2(projectPath) {
36376
36416
  try {
36377
- const raw = await readFile23(
36417
+ const raw = await readFile24(
36378
36418
  join39(projectPath, ".codebyplan", "git.json"),
36379
36419
  "utf-8"
36380
36420
  );
@@ -36385,7 +36425,7 @@ async function readGitConfig2(projectPath) {
36385
36425
  }
36386
36426
  async function readShipmentConfig2(projectPath) {
36387
36427
  try {
36388
- const raw = await readFile23(
36428
+ const raw = await readFile24(
36389
36429
  join39(projectPath, ".codebyplan", "shipment.json"),
36390
36430
  "utf-8"
36391
36431
  );
@@ -36396,7 +36436,7 @@ async function readShipmentConfig2(projectPath) {
36396
36436
  }
36397
36437
  async function readVendorConfig(projectPath) {
36398
36438
  try {
36399
- const raw = await readFile23(
36439
+ const raw = await readFile24(
36400
36440
  join39(projectPath, ".codebyplan", "vendor.json"),
36401
36441
  "utf-8"
36402
36442
  );
@@ -36407,7 +36447,7 @@ async function readVendorConfig(projectPath) {
36407
36447
  }
36408
36448
  async function readE2eConfig2(projectPath) {
36409
36449
  try {
36410
- const raw = await readFile23(
36450
+ const raw = await readFile24(
36411
36451
  join39(projectPath, ".codebyplan", "e2e.json"),
36412
36452
  "utf-8"
36413
36453
  );
@@ -36418,7 +36458,7 @@ async function readE2eConfig2(projectPath) {
36418
36458
  }
36419
36459
  async function readServerLocalConfig(projectPath) {
36420
36460
  try {
36421
- const raw = await readFile23(
36461
+ const raw = await readFile24(
36422
36462
  join39(projectPath, ".codebyplan", "server.local.json"),
36423
36463
  "utf-8"
36424
36464
  );
@@ -36491,11 +36531,11 @@ var init_config = __esm({
36491
36531
  });
36492
36532
 
36493
36533
  // src/lib/server-detect.ts
36494
- import { readFile as readFile24, readdir as readdir5, access as access6 } from "node:fs/promises";
36534
+ import { readFile as readFile25, readdir as readdir6, access as access7 } from "node:fs/promises";
36495
36535
  import { join as join40 } from "node:path";
36496
36536
  async function fileExists4(filePath) {
36497
36537
  try {
36498
- await access6(filePath);
36538
+ await access7(filePath);
36499
36539
  return true;
36500
36540
  } catch {
36501
36541
  return false;
@@ -36541,7 +36581,7 @@ async function isMonorepo(dir) {
36541
36581
  async function detectServers(projectPath) {
36542
36582
  let pkg;
36543
36583
  try {
36544
- const raw = await readFile24(join40(projectPath, "package.json"), "utf-8");
36584
+ const raw = await readFile25(join40(projectPath, "package.json"), "utf-8");
36545
36585
  pkg = JSON.parse(raw);
36546
36586
  } catch {
36547
36587
  return {
@@ -36559,13 +36599,13 @@ async function detectServers(projectPath) {
36559
36599
  if (mono) {
36560
36600
  const appsDir = join40(projectPath, "apps");
36561
36601
  try {
36562
- const entries = await readdir5(appsDir, { withFileTypes: true });
36602
+ const entries = await readdir6(appsDir, { withFileTypes: true });
36563
36603
  const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
36564
36604
  for (const entry of sorted) {
36565
36605
  if (!entry.isDirectory()) continue;
36566
36606
  const appPkgPath = join40(appsDir, entry.name, "package.json");
36567
36607
  try {
36568
- const appRaw = await readFile24(appPkgPath, "utf-8");
36608
+ const appRaw = await readFile25(appPkgPath, "utf-8");
36569
36609
  const appPkg = JSON.parse(appRaw);
36570
36610
  const appName = entry.name;
36571
36611
  const framework = detectFramework(appPkg);
@@ -36608,14 +36648,14 @@ var init_server_detect = __esm({
36608
36648
  });
36609
36649
 
36610
36650
  // src/lib/port-verify.ts
36611
- import { readFile as readFile25 } from "node:fs/promises";
36651
+ import { readFile as readFile26 } from "node:fs/promises";
36612
36652
  async function verifyPorts(projectPath, portAllocations) {
36613
36653
  const mismatches = [];
36614
36654
  const allocatedPorts = new Set(portAllocations.map((a) => a.port));
36615
36655
  const packageJsonPaths = await findPackageJsonFiles(projectPath, projectPath);
36616
36656
  for (const pkgPath of packageJsonPaths) {
36617
36657
  try {
36618
- const raw = await readFile25(pkgPath, "utf-8");
36658
+ const raw = await readFile26(pkgPath, "utf-8");
36619
36659
  const pkg = JSON.parse(raw);
36620
36660
  const scriptPort = detectPortFromScripts(pkg);
36621
36661
  if (scriptPort !== null && !allocatedPorts.has(scriptPort)) {
@@ -36678,7 +36718,7 @@ async function findUnallocatedApps(projectPath, portAllocations) {
36678
36718
  }
36679
36719
  let pkg;
36680
36720
  try {
36681
- const raw = await readFile25(`${app.absPath}/package.json`, "utf-8");
36721
+ const raw = await readFile26(`${app.absPath}/package.json`, "utf-8");
36682
36722
  pkg = JSON.parse(raw);
36683
36723
  } catch {
36684
36724
  continue;
@@ -36728,7 +36768,7 @@ __export(ports_exports, {
36728
36768
  parseEnvFile: () => parseEnvFile,
36729
36769
  runPorts: () => runPorts
36730
36770
  });
36731
- import { mkdir as mkdir11, readFile as readFile26, writeFile as writeFile20 } from "node:fs/promises";
36771
+ import { mkdir as mkdir11, readFile as readFile27, writeFile as writeFile20 } from "node:fs/promises";
36732
36772
  import { join as join41 } from "node:path";
36733
36773
  function printDetectionResult(result, projectPath) {
36734
36774
  console.log(`
@@ -36890,7 +36930,7 @@ async function writeServerLocalConfig(repoId, projectPath, dryRun) {
36890
36930
  const newJson = JSON.stringify(payload, null, 2) + "\n";
36891
36931
  let currentJson = "";
36892
36932
  try {
36893
- currentJson = await readFile26(filePath, "utf-8");
36933
+ currentJson = await readFile27(filePath, "utf-8");
36894
36934
  } catch {
36895
36935
  }
36896
36936
  if (currentJson === newJson) {
@@ -36912,7 +36952,7 @@ async function provisionE2eEnv(projectPath, dryRun) {
36912
36952
  const sourcePath = join41(projectPath, relSource);
36913
36953
  let sourceRaw;
36914
36954
  try {
36915
- sourceRaw = await readFile26(sourcePath, "utf-8");
36955
+ sourceRaw = await readFile27(sourcePath, "utf-8");
36916
36956
  } catch {
36917
36957
  console.warn(
36918
36958
  ` Skipped .codebyplan/e2e.env \u2014 source ${relSource} not found.`
@@ -36946,7 +36986,7 @@ async function provisionE2eEnv(projectPath, dryRun) {
36946
36986
  const newContent = lines.join("\n") + "\n";
36947
36987
  let currentContent = "";
36948
36988
  try {
36949
- currentContent = await readFile26(filePath, "utf-8");
36989
+ currentContent = await readFile27(filePath, "utf-8");
36950
36990
  } catch {
36951
36991
  }
36952
36992
  if (currentContent === newContent) {
@@ -37226,8 +37266,8 @@ __export(docs_exports, {
37226
37266
  stripRangePrefix: () => stripRangePrefix
37227
37267
  });
37228
37268
  import { existsSync as existsSync13 } from "node:fs";
37229
- import { mkdir as mkdir12, readFile as readFile27, readdir as readdir6, rm as rm2, writeFile as writeFile21 } from "node:fs/promises";
37230
- import { dirname as dirname14, isAbsolute as isAbsolute2, join as join42, relative as relative7, sep as sep2 } from "node:path";
37269
+ import { mkdir as mkdir12, readFile as readFile28, readdir as readdir7, rm as rm2, writeFile as writeFile21 } from "node:fs/promises";
37270
+ import { dirname as dirname14, isAbsolute as isAbsolute3, join as join42, relative as relative7, sep as sep2 } from "node:path";
37231
37271
  function selectDependencies(deps) {
37232
37272
  const byName = /* @__PURE__ */ new Map();
37233
37273
  for (const dep of deps) {
@@ -37285,7 +37325,7 @@ async function resolveExactVersion(projectPath, dep) {
37285
37325
  if (sourceDir !== projectPath) candidateDirs.push(sourceDir);
37286
37326
  for (const base of candidateDirs) {
37287
37327
  try {
37288
- const raw = await readFile27(
37328
+ const raw = await readFile28(
37289
37329
  join42(base, "node_modules", dep.name, "package.json"),
37290
37330
  "utf-8"
37291
37331
  );
@@ -37300,7 +37340,7 @@ async function resolveExactVersion(projectPath, dep) {
37300
37340
  }
37301
37341
  async function readVendorDocsPath(projectPath) {
37302
37342
  try {
37303
- const raw = await readFile27(
37343
+ const raw = await readFile28(
37304
37344
  join42(projectPath, ".codebyplan", "vendor.json"),
37305
37345
  "utf-8"
37306
37346
  );
@@ -37314,7 +37354,7 @@ async function readVendorDocsPath(projectPath) {
37314
37354
  }
37315
37355
  async function resolveDocsDir(projectPath, flags) {
37316
37356
  const configured = flags["dir"] ?? await readVendorDocsPath(projectPath) ?? DEFAULT_DOCS_DIR;
37317
- const absDir = isAbsolute2(configured) ? configured : join42(projectPath, configured);
37357
+ const absDir = isAbsolute3(configured) ? configured : join42(projectPath, configured);
37318
37358
  const rel = relative7(projectPath, absDir);
37319
37359
  const relDir = rel === "" || rel.startsWith("..") ? null : rel.split(sep2).join("/");
37320
37360
  return { absDir, relDir };
@@ -37323,7 +37363,7 @@ async function readDocsLock(absDir) {
37323
37363
  const empty = { generated_at: "", libraries: {} };
37324
37364
  let raw;
37325
37365
  try {
37326
- raw = await readFile27(join42(absDir, LOCK_FILE), "utf-8");
37366
+ raw = await readFile28(join42(absDir, LOCK_FILE), "utf-8");
37327
37367
  } catch {
37328
37368
  return empty;
37329
37369
  }
@@ -37422,7 +37462,7 @@ async function ensureDocsGitignoreEntry(projectPath, relDir, dryRun) {
37422
37462
  const gitignorePath = join42(projectPath, ".gitignore");
37423
37463
  let existing = "";
37424
37464
  try {
37425
- existing = await readFile27(gitignorePath, "utf-8");
37465
+ existing = await readFile28(gitignorePath, "utf-8");
37426
37466
  } catch {
37427
37467
  }
37428
37468
  const lines = existing.split(/\r?\n/).map((l) => l.trim());
@@ -37548,7 +37588,7 @@ async function syncOneLibrary(dep, ctx) {
37548
37588
  let removedVersionDirs = 0;
37549
37589
  let libEntries = [];
37550
37590
  try {
37551
- libEntries = await readdir6(libPath, { withFileTypes: true });
37591
+ libEntries = await readdir7(libPath, { withFileTypes: true });
37552
37592
  } catch {
37553
37593
  }
37554
37594
  for (const entry of libEntries) {
@@ -37678,7 +37718,7 @@ async function runDocsSync() {
37678
37718
  async function countFilesRecursively(dirPath) {
37679
37719
  let entries;
37680
37720
  try {
37681
- entries = await readdir6(dirPath, { withFileTypes: true });
37721
+ entries = await readdir7(dirPath, { withFileTypes: true });
37682
37722
  } catch {
37683
37723
  return 0;
37684
37724
  }
@@ -37702,7 +37742,7 @@ async function runDocsStatus() {
37702
37742
  `);
37703
37743
  let raw;
37704
37744
  try {
37705
- raw = await readFile27(join42(absDir, LOCK_FILE), "utf-8");
37745
+ raw = await readFile28(join42(absDir, LOCK_FILE), "utf-8");
37706
37746
  } catch {
37707
37747
  console.log(
37708
37748
  ` No ${LOCK_FILE} found \u2014 run \`codebyplan docs sync\` first.
@@ -38470,7 +38510,7 @@ var init_check2 = __esm({
38470
38510
 
38471
38511
  // src/lib/claude-plan.ts
38472
38512
  import * as fs13 from "node:fs";
38473
- import * as path15 from "node:path";
38513
+ import * as path16 from "node:path";
38474
38514
  function buildDriftPlan(projectDir, templatesDir, manifest) {
38475
38515
  const packaged = walkTemplates(templatesDir);
38476
38516
  const packagedBySrc = new Map(packaged.map((f) => [f.src, f]));
@@ -38484,8 +38524,8 @@ function buildDriftPlan(projectDir, templatesDir, manifest) {
38484
38524
  };
38485
38525
  for (const pkg of packaged) {
38486
38526
  const inManifest = manifestBySrc.get(pkg.src);
38487
- const absDest = path15.join(projectDir, ".claude", pkg.dest);
38488
- const absSrc = path15.join(templatesDir, pkg.src);
38527
+ const absDest = path16.join(projectDir, ".claude", pkg.dest);
38528
+ const absSrc = path16.join(templatesDir, pkg.src);
38489
38529
  if (!inManifest) {
38490
38530
  plan.newOptIn.push({
38491
38531
  packaged: { src: pkg.src, dest: pkg.dest, hash: pkg.hash },
@@ -38534,7 +38574,7 @@ __export(status_exports, {
38534
38574
  runStatus: () => runStatus2
38535
38575
  });
38536
38576
  import * as fs14 from "node:fs";
38537
- import * as path16 from "node:path";
38577
+ import * as path17 from "node:path";
38538
38578
  import { execSync as execSync9 } from "node:child_process";
38539
38579
  function makeFailSafe(checked_at) {
38540
38580
  return {
@@ -38643,12 +38683,12 @@ async function runStatus2(argv) {
38643
38683
  const latest = fetchLatestVersion();
38644
38684
  const newer = latest !== null && compareSemver(latest, installed) > 0;
38645
38685
  let settings_drift = false;
38646
- const settingsPath = path16.join(projectDir, ".claude", "settings.json");
38647
- const baseSettingsPath = path16.join(
38686
+ const settingsPath = path17.join(projectDir, ".claude", "settings.json");
38687
+ const baseSettingsPath = path17.join(
38648
38688
  templatesDir,
38649
38689
  "settings.project.base.json"
38650
38690
  );
38651
- const hooksJsonPath = path16.join(templatesDir, "hooks", "hooks.json");
38691
+ const hooksJsonPath = path17.join(templatesDir, "hooks", "hooks.json");
38652
38692
  if (fs14.existsSync(settingsPath)) {
38653
38693
  try {
38654
38694
  const settingsRaw = fs14.readFileSync(settingsPath, "utf8");
@@ -38718,10 +38758,10 @@ function emitResult(result, writeCache, quiet, projectDir) {
38718
38758
  const json = JSON.stringify(result, null, 2);
38719
38759
  if (writeCache) {
38720
38760
  try {
38721
- const cacheDir = path16.join(projectDir, ".codebyplan");
38761
+ const cacheDir = path17.join(projectDir, ".codebyplan");
38722
38762
  fs14.mkdirSync(cacheDir, { recursive: true });
38723
38763
  fs14.writeFileSync(
38724
- path16.join(cacheDir, "claude-status.local.json"),
38764
+ path17.join(cacheDir, "claude-status.local.json"),
38725
38765
  json + "\n",
38726
38766
  "utf8"
38727
38767
  );
@@ -38765,11 +38805,11 @@ async function ask(q, opts) {
38765
38805
  try {
38766
38806
  while (true) {
38767
38807
  const choices = q.choices.map((c) => `[${c.key}] ${c.label}`).join(" ");
38768
- const answer = await new Promise((resolve16) => {
38808
+ const answer = await new Promise((resolve17) => {
38769
38809
  rl.question(`${q.message}
38770
38810
  ${choices}
38771
38811
  > `, (input) => {
38772
- resolve16(input.trim().toLowerCase());
38812
+ resolve17(input.trim().toLowerCase());
38773
38813
  });
38774
38814
  });
38775
38815
  const match = q.choices.find(
@@ -38865,7 +38905,7 @@ __export(update_exports, {
38865
38905
  });
38866
38906
  import * as fs15 from "node:fs";
38867
38907
  import * as os3 from "node:os";
38868
- import * as path17 from "node:path";
38908
+ import * as path18 from "node:path";
38869
38909
  async function runUpdate(opts, deps = {}) {
38870
38910
  await Promise.resolve();
38871
38911
  const scope = opts.scope ?? "project";
@@ -38901,9 +38941,9 @@ async function runUpdate(opts, deps = {}) {
38901
38941
  finalManifestEntries.push(e);
38902
38942
  }
38903
38943
  for (const { packaged, absSrc } of plan.overwriteSafe) {
38904
- const absDest = path17.join(projectDir, ".claude", packaged.dest);
38944
+ const absDest = path18.join(projectDir, ".claude", packaged.dest);
38905
38945
  if (!opts.dryRun) {
38906
- fs15.mkdirSync(path17.dirname(absDest), { recursive: true });
38946
+ fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38907
38947
  fs15.copyFileSync(absSrc, absDest);
38908
38948
  if (opts.verbose) console.log(`updated ${packaged.dest}`);
38909
38949
  } else if (opts.verbose) {
@@ -38916,7 +38956,7 @@ async function runUpdate(opts, deps = {}) {
38916
38956
  absSrc,
38917
38957
  onDiskContent
38918
38958
  } of plan.overwriteHandEdited) {
38919
- const absDest = path17.join(projectDir, ".claude", packaged.dest);
38959
+ const absDest = path18.join(projectDir, ".claude", packaged.dest);
38920
38960
  const newContent = fs15.readFileSync(absSrc);
38921
38961
  const showDiff = () => {
38922
38962
  console.log(
@@ -38929,7 +38969,7 @@ async function runUpdate(opts, deps = {}) {
38929
38969
  const answer = await promptOverwrite(packaged.dest, opts, showDiff);
38930
38970
  if (answer === "overwrite") {
38931
38971
  if (!opts.dryRun) {
38932
- fs15.mkdirSync(path17.dirname(absDest), { recursive: true });
38972
+ fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38933
38973
  fs15.copyFileSync(absSrc, absDest);
38934
38974
  }
38935
38975
  finalManifestEntries.push(packaged);
@@ -38945,9 +38985,9 @@ async function runUpdate(opts, deps = {}) {
38945
38985
  for (const { packaged, absSrc } of plan.newOptIn) {
38946
38986
  const answer = await promptOptIn(packaged.dest, opts);
38947
38987
  if (answer === "opt-in") {
38948
- const absDest = path17.join(projectDir, ".claude", packaged.dest);
38988
+ const absDest = path18.join(projectDir, ".claude", packaged.dest);
38949
38989
  if (!opts.dryRun) {
38950
- fs15.mkdirSync(path17.dirname(absDest), { recursive: true });
38990
+ fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38951
38991
  fs15.copyFileSync(absSrc, absDest);
38952
38992
  }
38953
38993
  finalManifestEntries.push(packaged);
@@ -38959,25 +38999,25 @@ async function runUpdate(opts, deps = {}) {
38959
38999
  for (const e of plan.removedFromPackage) {
38960
39000
  const answer = await promptRemove(e.dest, opts);
38961
39001
  if (answer === "remove") {
38962
- const absDest = path17.join(projectDir, ".claude", e.dest);
39002
+ const absDest = path18.join(projectDir, ".claude", e.dest);
38963
39003
  if (!opts.dryRun && fs15.existsSync(absDest)) {
38964
39004
  fs15.rmSync(absDest);
38965
- const claudeDir = path17.join(projectDir, ".claude");
38966
- let cur = path17.dirname(absDest);
38967
- while (cur !== claudeDir && cur !== path17.dirname(cur)) {
38968
- if (path17.dirname(cur) === claudeDir) break;
39005
+ const claudeDir = path18.join(projectDir, ".claude");
39006
+ let cur = path18.dirname(absDest);
39007
+ while (cur !== claudeDir && cur !== path18.dirname(cur)) {
39008
+ if (path18.dirname(cur) === claudeDir) break;
38969
39009
  try {
38970
39010
  fs15.rmdirSync(cur);
38971
39011
  if (opts.verbose)
38972
39012
  console.log(
38973
- `pruned empty dir ${path17.relative(claudeDir, cur)}`
39013
+ `pruned empty dir ${path18.relative(claudeDir, cur)}`
38974
39014
  );
38975
- cur = path17.dirname(cur);
39015
+ cur = path18.dirname(cur);
38976
39016
  } catch (err) {
38977
39017
  const code = err.code;
38978
39018
  if (code !== "ENOTEMPTY" && code !== "ENOENT") {
38979
39019
  console.warn(
38980
- `codebyplan claude: could not prune empty dir ${path17.relative(claudeDir, cur)}: ${err.message}`
39020
+ `codebyplan claude: could not prune empty dir ${path18.relative(claudeDir, cur)}: ${err.message}`
38981
39021
  );
38982
39022
  }
38983
39023
  break;
@@ -38989,12 +39029,12 @@ async function runUpdate(opts, deps = {}) {
38989
39029
  if (opts.verbose) console.log(`kept (untracked) ${e.dest}`);
38990
39030
  }
38991
39031
  }
38992
- const hooksJsonPath = path17.join(templatesDir, "hooks", "hooks.json");
38993
- const baseSettingsPath = path17.join(
39032
+ const hooksJsonPath = path18.join(templatesDir, "hooks", "hooks.json");
39033
+ const baseSettingsPath = path18.join(
38994
39034
  templatesDir,
38995
39035
  "settings.project.base.json"
38996
39036
  );
38997
- const settingsPath = path17.join(projectDir, ".claude", "settings.json");
39037
+ const settingsPath = path18.join(projectDir, ".claude", "settings.json");
38998
39038
  const existingSettings = fs15.existsSync(settingsPath) ? JSON.parse(fs15.readFileSync(settingsPath, "utf8")) : {};
38999
39039
  if (fs15.existsSync(baseSettingsPath)) {
39000
39040
  const base = JSON.parse(
@@ -39021,7 +39061,7 @@ async function runUpdate(opts, deps = {}) {
39021
39061
  deps.detectHealDeps
39022
39062
  );
39023
39063
  if (!opts.dryRun) {
39024
- fs15.mkdirSync(path17.dirname(settingsPath), { recursive: true });
39064
+ fs15.mkdirSync(path18.dirname(settingsPath), { recursive: true });
39025
39065
  fs15.writeFileSync(
39026
39066
  settingsPath,
39027
39067
  JSON.stringify(existingSettings, null, 2) + "\n",
@@ -39037,7 +39077,7 @@ async function runUpdate(opts, deps = {}) {
39037
39077
  );
39038
39078
  if (opts.verbose && gitignoreAction !== "unchanged") {
39039
39079
  console.log(
39040
- `${opts.dryRun ? "[dry-run] would " : ""}${gitignoreAction} managed .gitignore block in ${path17.relative(projectDir, path17.join(projectDir, ".gitignore"))}`
39080
+ `${opts.dryRun ? "[dry-run] would " : ""}${gitignoreAction} managed .gitignore block in ${path18.relative(projectDir, path18.join(projectDir, ".gitignore"))}`
39041
39081
  );
39042
39082
  }
39043
39083
  if (!opts.dryRun) {
@@ -39077,9 +39117,9 @@ function runUpdateUser(opts, deps) {
39077
39117
  return;
39078
39118
  }
39079
39119
  try {
39080
- const userDir = deps.userDir ?? path17.join(os3.homedir(), ".claude");
39081
- const settingsPath = path17.join(userDir, "settings.json");
39082
- const userBaseSettingsPath = path17.join(
39120
+ const userDir = deps.userDir ?? path18.join(os3.homedir(), ".claude");
39121
+ const settingsPath = path18.join(userDir, "settings.json");
39122
+ const userBaseSettingsPath = path18.join(
39083
39123
  templatesDir,
39084
39124
  "settings.user.base.json"
39085
39125
  );
@@ -39151,7 +39191,7 @@ __export(uninstall_exports, {
39151
39191
  });
39152
39192
  import * as fs16 from "node:fs";
39153
39193
  import * as os4 from "node:os";
39154
- import * as path18 from "node:path";
39194
+ import * as path19 from "node:path";
39155
39195
  async function runUninstall(opts, deps = {}) {
39156
39196
  await Promise.resolve();
39157
39197
  const scope = opts.scope ?? "project";
@@ -39180,7 +39220,7 @@ async function runUninstall(opts, deps = {}) {
39180
39220
  let removed = 0;
39181
39221
  let warnings = 0;
39182
39222
  for (const entry of manifest.files) {
39183
- const abs = path18.join(projectDir, ".claude", entry.dest);
39223
+ const abs = path19.join(projectDir, ".claude", entry.dest);
39184
39224
  if (!fs16.existsSync(abs)) {
39185
39225
  console.warn(
39186
39226
  `codebyplan claude uninstall: ${entry.dest} already absent (skipping).`
@@ -39204,12 +39244,12 @@ async function runUninstall(opts, deps = {}) {
39204
39244
  if (!opts.dryRun) {
39205
39245
  pruneEmptyManagedDirs(projectDir);
39206
39246
  }
39207
- const settingsPath = path18.join(projectDir, ".claude", "settings.json");
39247
+ const settingsPath = path19.join(projectDir, ".claude", "settings.json");
39208
39248
  if (fs16.existsSync(settingsPath)) {
39209
39249
  const settings = JSON.parse(
39210
39250
  fs16.readFileSync(settingsPath, "utf8")
39211
39251
  );
39212
- const baseSettingsPath = templatesDir ? path18.join(templatesDir, "settings.project.base.json") : null;
39252
+ const baseSettingsPath = templatesDir ? path19.join(templatesDir, "settings.project.base.json") : null;
39213
39253
  if (baseSettingsPath && fs16.existsSync(baseSettingsPath)) {
39214
39254
  const base = JSON.parse(
39215
39255
  fs16.readFileSync(baseSettingsPath, "utf8")
@@ -39267,7 +39307,7 @@ function runUninstallUser(opts, deps) {
39267
39307
  }
39268
39308
  }
39269
39309
  try {
39270
- const userDir = deps.userDir ?? path18.join(os4.homedir(), ".claude");
39310
+ const userDir = deps.userDir ?? path19.join(os4.homedir(), ".claude");
39271
39311
  const existingManifest = readManifestForScope("user", userDir);
39272
39312
  if (!existingManifest) {
39273
39313
  console.error(
@@ -39276,12 +39316,12 @@ function runUninstallUser(opts, deps) {
39276
39316
  process.exitCode = 1;
39277
39317
  return;
39278
39318
  }
39279
- const settingsPath = path18.join(userDir, "settings.json");
39319
+ const settingsPath = path19.join(userDir, "settings.json");
39280
39320
  if (fs16.existsSync(settingsPath)) {
39281
39321
  const settings = JSON.parse(
39282
39322
  fs16.readFileSync(settingsPath, "utf8")
39283
39323
  );
39284
- const userBaseSettingsPath = templatesDir != null ? path18.join(templatesDir, "settings.user.base.json") : null;
39324
+ const userBaseSettingsPath = templatesDir != null ? path19.join(templatesDir, "settings.user.base.json") : null;
39285
39325
  if (userBaseSettingsPath && fs16.existsSync(userBaseSettingsPath)) {
39286
39326
  const userBase = JSON.parse(
39287
39327
  fs16.readFileSync(userBaseSettingsPath, "utf8")
@@ -39322,7 +39362,7 @@ function runUninstallUser(opts, deps) {
39322
39362
  function pruneEmptyManagedDirs(projectDir) {
39323
39363
  const managedRoots = ["skills", "agents", "hooks", "rules"];
39324
39364
  for (const root of managedRoots) {
39325
- const abs = path18.join(projectDir, ".claude", root);
39365
+ const abs = path19.join(projectDir, ".claude", root);
39326
39366
  if (!fs16.existsSync(abs)) continue;
39327
39367
  pruneLeafFirst(abs);
39328
39368
  }
@@ -39333,7 +39373,7 @@ function pruneLeafFirst(dir) {
39333
39373
  if (!stat3.isDirectory()) return;
39334
39374
  for (const entry of fs16.readdirSync(dir, { withFileTypes: true })) {
39335
39375
  if (entry.isDirectory()) {
39336
- pruneLeafFirst(path18.join(dir, entry.name));
39376
+ pruneLeafFirst(path19.join(dir, entry.name));
39337
39377
  }
39338
39378
  }
39339
39379
  const remaining = fs16.readdirSync(dir);
@@ -39354,7 +39394,7 @@ var init_uninstall = __esm({
39354
39394
 
39355
39395
  // src/lib/verify-parity.ts
39356
39396
  import * as fs17 from "node:fs";
39357
- import * as path19 from "node:path";
39397
+ import * as path20 from "node:path";
39358
39398
  function isValidScope(s) {
39359
39399
  return s === "org-shared" || s === "project-shared" || REPO_ONLY_RE.test(s);
39360
39400
  }
@@ -39371,25 +39411,25 @@ function checkSiblingParity(opts) {
39371
39411
  expectedOneSided = DEFAULT_EXPECTED_ONE_SIDED,
39372
39412
  ignoredSubtrees
39373
39413
  } = opts;
39374
- const defaultIgnored = [path19.join(claudeDir, "hooks", "__test-fixtures__")];
39414
+ const defaultIgnored = [path20.join(claudeDir, "hooks", "__test-fixtures__")];
39375
39415
  const ignored = ignoredSubtrees ?? defaultIgnored;
39376
39416
  const violations = [];
39377
39417
  const claudeSideRels = /* @__PURE__ */ new Set();
39378
39418
  for (const scanDir of SCAN_DIRS) {
39379
- const baseDir = path19.join(claudeDir, scanDir);
39419
+ const baseDir = path20.join(claudeDir, scanDir);
39380
39420
  if (!fs17.existsSync(baseDir)) continue;
39381
39421
  const entries = readdirRecursive(baseDir);
39382
39422
  for (const entry of entries) {
39383
- const absPath = path19.join(baseDir, entry);
39423
+ const absPath = path20.join(baseDir, entry);
39384
39424
  if (!fs17.lstatSync(absPath).isFile()) continue;
39385
39425
  if (ignored.some(
39386
- (ig) => absPath.startsWith(ig + path19.sep) || absPath === ig
39426
+ (ig) => absPath.startsWith(ig + path20.sep) || absPath === ig
39387
39427
  )) {
39388
39428
  continue;
39389
39429
  }
39390
- const relPath = path19.join(scanDir, entry).split(path19.sep).join("/");
39430
+ const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39391
39431
  claudeSideRels.add(relPath);
39392
- const templatePath = path19.join(templatesDir, relPath);
39432
+ const templatePath = path20.join(templatesDir, relPath);
39393
39433
  if (!fs17.existsSync(templatePath)) {
39394
39434
  if (!expectedOneSided.has(relPath) && !isScaffoldFile(entry)) {
39395
39435
  violations.push({ type: "missing-twin", path: relPath });
@@ -39404,14 +39444,14 @@ function checkSiblingParity(opts) {
39404
39444
  }
39405
39445
  }
39406
39446
  for (const scanDir of SCAN_DIRS) {
39407
- const tplBase = path19.join(templatesDir, scanDir);
39447
+ const tplBase = path20.join(templatesDir, scanDir);
39408
39448
  if (!fs17.existsSync(tplBase)) continue;
39409
39449
  const entries = readdirRecursive(tplBase);
39410
39450
  for (const entry of entries) {
39411
- const absPath = path19.join(tplBase, entry);
39451
+ const absPath = path20.join(tplBase, entry);
39412
39452
  if (!fs17.lstatSync(absPath).isFile()) continue;
39413
39453
  if (isScaffoldFile(entry)) continue;
39414
- const relPath = path19.join(scanDir, entry).split(path19.sep).join("/");
39454
+ const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39415
39455
  if (!claudeSideRels.has(relPath) && !expectedOneSided.has(relPath)) {
39416
39456
  violations.push({ type: "extra-twin", path: relPath });
39417
39457
  }
@@ -39447,18 +39487,18 @@ function checkScopeMarkers(opts) {
39447
39487
  const twinDetectionActive = templatesDir != null && fs17.existsSync(templatesDir);
39448
39488
  const violations = [];
39449
39489
  for (const scanDir of scanDirs) {
39450
- const baseDir = path19.join(claudeDir, scanDir);
39490
+ const baseDir = path20.join(claudeDir, scanDir);
39451
39491
  if (!fs17.existsSync(baseDir)) continue;
39452
39492
  const entries = readdirRecursive(baseDir);
39453
39493
  for (const entry of entries) {
39454
- const absPath = path19.join(baseDir, entry);
39494
+ const absPath = path20.join(baseDir, entry);
39455
39495
  if (!fs17.lstatSync(absPath).isFile()) continue;
39456
39496
  if (!isStructuralEntry(scanDir, entry)) continue;
39457
- const ext = path19.extname(entry).toLowerCase();
39497
+ const ext = path20.extname(entry).toLowerCase();
39458
39498
  const isMd = ext === ".md";
39459
39499
  const isSh = ext === ".sh";
39460
39500
  if (!isMd && !isSh) continue;
39461
- const relPath = path19.join(scanDir, entry).split(path19.sep).join("/");
39501
+ const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39462
39502
  if (allowlist.has(relPath)) continue;
39463
39503
  let content;
39464
39504
  try {
@@ -39472,7 +39512,7 @@ function checkScopeMarkers(opts) {
39472
39512
  continue;
39473
39513
  }
39474
39514
  const scopeValue = isMd ? extractFrontmatterScope(content) : extractShScope(content);
39475
- const managed = twinDetectionActive && fs17.existsSync(path19.join(templatesDir, relPath));
39515
+ const managed = twinDetectionActive && fs17.existsSync(path20.join(templatesDir, relPath));
39476
39516
  if (managed) {
39477
39517
  if (scopeValue === null) {
39478
39518
  } else if (scopeValue === "org-shared") {
@@ -39526,7 +39566,7 @@ function readdirRecursive(dir, rel = "", visited = /* @__PURE__ */ new Set()) {
39526
39566
  visited.add(realDir);
39527
39567
  const results = [];
39528
39568
  for (const name of fs17.readdirSync(dir)) {
39529
- const full = path19.join(dir, name);
39569
+ const full = path20.join(dir, name);
39530
39570
  const relName = rel ? `${rel}/${name}` : name;
39531
39571
  if (fs17.lstatSync(full).isDirectory()) {
39532
39572
  results.push(...readdirRecursive(full, relName, visited));
@@ -39599,12 +39639,12 @@ __export(verify_parity_exports, {
39599
39639
  verifyParity: () => verifyParity
39600
39640
  });
39601
39641
  import * as fs18 from "node:fs";
39602
- import * as path20 from "node:path";
39642
+ import * as path21 from "node:path";
39603
39643
  function verifyParity(args, deps = {}) {
39604
39644
  const warnOnly = args.includes("--warn-only");
39605
39645
  const jsonMode = args.includes("--json");
39606
39646
  const projectDir = deps.cwd ?? process.cwd();
39607
- const claudeDir = path20.join(projectDir, ".claude");
39647
+ const claudeDir = path21.join(projectDir, ".claude");
39608
39648
  if (!fs18.existsSync(claudeDir)) {
39609
39649
  const msg = "codebyplan claude verify-parity: .claude/ not found in cwd \u2014 run from the project root.\n";
39610
39650
  process.stderr.write(msg);
@@ -40111,11 +40151,11 @@ var generate_exports = {};
40111
40151
  __export(generate_exports, {
40112
40152
  runGenerate: () => runGenerate
40113
40153
  });
40114
- import { readFile as readFile28, mkdir as mkdir13, writeFile as writeFile22 } from "node:fs/promises";
40115
- import { join as join51, resolve as resolve11 } from "node:path";
40154
+ import { readFile as readFile29, mkdir as mkdir13, writeFile as writeFile22 } from "node:fs/promises";
40155
+ import { join as join51, resolve as resolve12 } from "node:path";
40116
40156
  async function readJsonFile4(filePath) {
40117
40157
  try {
40118
- const raw = await readFile28(filePath, "utf-8");
40158
+ const raw = await readFile29(filePath, "utf-8");
40119
40159
  return JSON.parse(raw);
40120
40160
  } catch {
40121
40161
  return null;
@@ -40123,7 +40163,7 @@ async function readJsonFile4(filePath) {
40123
40163
  }
40124
40164
  async function readPkgName(absPath) {
40125
40165
  try {
40126
- const raw = await readFile28(join51(absPath, "package.json"), "utf-8");
40166
+ const raw = await readFile29(join51(absPath, "package.json"), "utf-8");
40127
40167
  const pkg = JSON.parse(raw);
40128
40168
  return typeof pkg.name === "string" ? pkg.name : null;
40129
40169
  } catch {
@@ -40134,10 +40174,10 @@ async function runGenerate(opts) {
40134
40174
  const projectDir = opts.projectDir ?? opts["project-dir"] ?? process.cwd();
40135
40175
  const dryRun = opts.dryRun ?? opts["dryRun"] ?? false;
40136
40176
  const check = opts.check ?? opts["check"] ?? false;
40137
- const rootDir = resolve11(projectDir);
40177
+ const rootDir = resolve12(projectDir);
40138
40178
  let packageManager;
40139
40179
  try {
40140
- const raw = await readFile28(join51(rootDir, "package.json"), "utf-8");
40180
+ const raw = await readFile29(join51(rootDir, "package.json"), "utf-8");
40141
40181
  const pkg = JSON.parse(raw);
40142
40182
  if (typeof pkg.packageManager === "string") {
40143
40183
  packageManager = pkg.packageManager;
@@ -40241,7 +40281,7 @@ async function runGenerate(opts) {
40241
40281
  const agentsMdPath2 = join51(rootDir, "AGENTS.md");
40242
40282
  let existingAgents = null;
40243
40283
  try {
40244
- existingAgents = await readFile28(agentsMdPath2, "utf-8");
40284
+ existingAgents = await readFile29(agentsMdPath2, "utf-8");
40245
40285
  } catch {
40246
40286
  existingAgents = null;
40247
40287
  }
@@ -40286,7 +40326,7 @@ async function runGenerate(opts) {
40286
40326
  const agentsMdPath = join51(rootDir, "AGENTS.md");
40287
40327
  let existingAgentsContent = null;
40288
40328
  try {
40289
- existingAgentsContent = await readFile28(agentsMdPath, "utf-8");
40329
+ existingAgentsContent = await readFile29(agentsMdPath, "utf-8");
40290
40330
  } catch {
40291
40331
  existingAgentsContent = null;
40292
40332
  }
@@ -40314,11 +40354,11 @@ __export(readme_exports, {
40314
40354
  runReadme: () => runReadme,
40315
40355
  runReadmeCommand: () => runReadmeCommand
40316
40356
  });
40317
- import { readFile as readFile29, writeFile as writeFile23 } from "node:fs/promises";
40318
- import { join as join52, resolve as resolve12, relative as relative9 } from "node:path";
40357
+ import { readFile as readFile30, writeFile as writeFile23 } from "node:fs/promises";
40358
+ import { join as join52, resolve as resolve13, relative as relative9 } from "node:path";
40319
40359
  async function readJsonFile5(filePath) {
40320
40360
  try {
40321
- const raw = await readFile29(filePath, "utf-8");
40361
+ const raw = await readFile30(filePath, "utf-8");
40322
40362
  return JSON.parse(raw);
40323
40363
  } catch {
40324
40364
  return null;
@@ -40411,7 +40451,7 @@ async function runReadme(opts) {
40411
40451
  const dryRun = opts.dryRun ?? opts["dryRun"] ?? false;
40412
40452
  const check = opts.check ?? opts["check"] ?? false;
40413
40453
  const init = opts.init ?? opts["init"] ?? false;
40414
- const rootDir = resolve12(projectDir);
40454
+ const rootDir = resolve13(projectDir);
40415
40455
  const rootPkgJson = await readJsonFile5(
40416
40456
  join52(rootDir, "package.json")
40417
40457
  );
@@ -40426,7 +40466,7 @@ async function runReadme(opts) {
40426
40466
  const relPath = unit.isRoot ? "README.md" : join52(relative9(rootDir, unit.absPath), "README.md");
40427
40467
  let existingContent = null;
40428
40468
  try {
40429
- existingContent = await readFile29(readmePath, "utf-8");
40469
+ existingContent = await readFile30(readmePath, "utf-8");
40430
40470
  } catch {
40431
40471
  existingContent = null;
40432
40472
  }
@@ -40606,18 +40646,18 @@ __export(migrate_memory_exports, {
40606
40646
  runMigrateMemory: () => runMigrateMemory
40607
40647
  });
40608
40648
  import {
40609
- readFile as readFile30,
40649
+ readFile as readFile31,
40610
40650
  writeFile as writeFile24,
40611
40651
  mkdir as mkdir14,
40612
40652
  unlink as unlink6,
40613
40653
  rmdir,
40614
- readdir as readdir7
40654
+ readdir as readdir8
40615
40655
  } from "node:fs/promises";
40616
40656
  import { existsSync as existsSync21 } from "node:fs";
40617
- import { join as join53, resolve as resolve13, dirname as dirname16, sep as sep4 } from "node:path";
40657
+ import { join as join53, resolve as resolve14, dirname as dirname16, sep as sep4 } from "node:path";
40618
40658
  import { homedir as homedir8 } from "node:os";
40619
40659
  function encodeProjectPath(absPath) {
40620
- return resolve13(absPath).replace(/[/\\]/g, "-");
40660
+ return resolve14(absPath).replace(/[/\\]/g, "-");
40621
40661
  }
40622
40662
  function resolveAutoMemoryDir(opts) {
40623
40663
  if (opts.autoMemoryDir) {
@@ -40684,7 +40724,7 @@ function parseFrontmatter(content) {
40684
40724
  async function inventoryFiles(dir) {
40685
40725
  let filenames;
40686
40726
  try {
40687
- const entries = await readdir7(dir);
40727
+ const entries = await readdir8(dir);
40688
40728
  filenames = entries.filter((f) => f.endsWith(".md") && f !== "MEMORY.md").sort();
40689
40729
  } catch {
40690
40730
  return [];
@@ -40694,7 +40734,7 @@ async function inventoryFiles(dir) {
40694
40734
  const sourcePath = join53(dir, filename);
40695
40735
  let raw;
40696
40736
  try {
40697
- raw = await readFile30(sourcePath, "utf-8");
40737
+ raw = await readFile31(sourcePath, "utf-8");
40698
40738
  } catch (err) {
40699
40739
  const msg = err instanceof Error ? err.message : String(err);
40700
40740
  results.push({
@@ -40774,15 +40814,15 @@ function buildPlan(entries, opts) {
40774
40814
  return plan;
40775
40815
  }
40776
40816
  async function applyPlan(plan, opts) {
40777
- const projectDir = resolve13(opts.projectDir);
40817
+ const projectDir = resolve14(opts.projectDir);
40778
40818
  const dryRun = opts.dryRun ?? false;
40779
40819
  for (const entry of plan.entries) {
40780
40820
  if (entry.suggested_action !== "keep") continue;
40781
40821
  if (!entry.suggested_target?.startsWith("nested:")) continue;
40782
40822
  const relPath = entry.suggested_target.slice("nested:".length);
40783
- const targetDir = resolve13(join53(projectDir, relPath));
40823
+ const targetDir = resolve14(join53(projectDir, relPath));
40784
40824
  const targetFile = join53(targetDir, "CLAUDE.md");
40785
- if (!targetDir.startsWith(resolve13(projectDir) + sep4)) {
40825
+ if (!targetDir.startsWith(resolve14(projectDir) + sep4)) {
40786
40826
  process.stderr.write(
40787
40827
  `migrate-memory: skipping unsafe suggested_target "${entry.suggested_target}" \u2014 resolves outside projectDir
40788
40828
  `
@@ -40800,8 +40840,8 @@ ${anchor}
40800
40840
  if (dryRun) {
40801
40841
  process.stdout.write(`[dry-run] Would create/append: ${targetFile}
40802
40842
  `);
40803
- if (resolve13(entry.source_path).startsWith(
40804
- resolve13(plan.auto_memory_dir) + sep4
40843
+ if (resolve14(entry.source_path).startsWith(
40844
+ resolve14(plan.auto_memory_dir) + sep4
40805
40845
  )) {
40806
40846
  process.stdout.write(
40807
40847
  `[dry-run] Would delete migrated keep source: ${entry.source_path}
@@ -40813,13 +40853,13 @@ ${anchor}
40813
40853
  await mkdir14(targetDir, { recursive: true });
40814
40854
  let existing = "";
40815
40855
  try {
40816
- existing = await readFile30(targetFile, "utf-8");
40856
+ existing = await readFile31(targetFile, "utf-8");
40817
40857
  } catch {
40818
40858
  }
40819
40859
  if (!existing.includes(anchor)) {
40820
40860
  await writeFile24(targetFile, existing + appendContent, "utf-8");
40821
40861
  }
40822
- if (resolve13(entry.source_path).startsWith(resolve13(plan.auto_memory_dir) + sep4)) {
40862
+ if (resolve14(entry.source_path).startsWith(resolve14(plan.auto_memory_dir) + sep4)) {
40823
40863
  try {
40824
40864
  await unlink6(entry.source_path);
40825
40865
  } catch {
@@ -40840,7 +40880,7 @@ ${anchor}
40840
40880
  } else {
40841
40881
  let claudeMdContent = "";
40842
40882
  try {
40843
- claudeMdContent = await readFile30(rootClaudeMd, "utf-8");
40883
+ claudeMdContent = await readFile31(rootClaudeMd, "utf-8");
40844
40884
  } catch {
40845
40885
  await mkdir14(dirname16(rootClaudeMd), { recursive: true });
40846
40886
  }
@@ -40856,8 +40896,8 @@ ${IMPORT_LINE}
40856
40896
  }
40857
40897
  for (const entry of plan.entries) {
40858
40898
  if (entry.suggested_action !== "drop") continue;
40859
- if (!resolve13(entry.source_path).startsWith(
40860
- resolve13(plan.auto_memory_dir) + sep4
40899
+ if (!resolve14(entry.source_path).startsWith(
40900
+ resolve14(plan.auto_memory_dir) + sep4
40861
40901
  )) {
40862
40902
  process.stderr.write(
40863
40903
  `migrate-memory: skipping delete of "${entry.source_path}" \u2014 resolves outside auto_memory_dir
@@ -40881,7 +40921,7 @@ ${IMPORT_LINE}
40881
40921
  process.stdout.write(`[dry-run] Would delete MEMORY.md: ${memoryMd}
40882
40922
  `);
40883
40923
  } else {
40884
- if (resolve13(plan.auto_memory_dir).startsWith(safeRmdirBase + sep4)) {
40924
+ if (resolve14(plan.auto_memory_dir).startsWith(safeRmdirBase + sep4)) {
40885
40925
  try {
40886
40926
  await unlink6(memoryMd);
40887
40927
  } catch {
@@ -40899,14 +40939,14 @@ ${IMPORT_LINE}
40899
40939
  `
40900
40940
  );
40901
40941
  } else {
40902
- if (!resolve13(plan.auto_memory_dir).startsWith(safeRmdirBase + sep4)) {
40942
+ if (!resolve14(plan.auto_memory_dir).startsWith(safeRmdirBase + sep4)) {
40903
40943
  process.stderr.write(
40904
40944
  `migrate-memory: skipping rmdir of "${plan.auto_memory_dir}" \u2014 not under ~/.claude/projects
40905
40945
  `
40906
40946
  );
40907
40947
  } else {
40908
40948
  try {
40909
- const remaining = await readdir7(plan.auto_memory_dir);
40949
+ const remaining = await readdir8(plan.auto_memory_dir);
40910
40950
  if (remaining.length === 0) {
40911
40951
  await rmdir(plan.auto_memory_dir);
40912
40952
  }
@@ -40929,7 +40969,7 @@ async function runMigrateMemory(opts) {
40929
40969
  if (applyFile) {
40930
40970
  let planJson;
40931
40971
  try {
40932
- planJson = await readFile30(resolve13(applyFile), "utf-8");
40972
+ planJson = await readFile31(resolve14(applyFile), "utf-8");
40933
40973
  } catch (err) {
40934
40974
  const msg = err instanceof Error ? err.message : String(err);
40935
40975
  process.stderr.write(
@@ -40999,7 +41039,7 @@ var init_migrate_memory = __esm({
40999
41039
  });
41000
41040
 
41001
41041
  // src/lib/claude-mode-audit.ts
41002
- import { readdirSync as readdirSync7, readFileSync as readFileSync19, existsSync as existsSync22 } from "node:fs";
41042
+ import { readdirSync as readdirSync6, readFileSync as readFileSync19, existsSync as existsSync22 } from "node:fs";
41003
41043
  import { join as join54, basename as basename3 } from "node:path";
41004
41044
  function parseFrontmatter2(content) {
41005
41045
  const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
@@ -41079,14 +41119,14 @@ function auditMode(templatesDir) {
41079
41119
  const entries = [];
41080
41120
  const agentsDir = join54(templatesDir, "agents");
41081
41121
  if (existsSync22(agentsDir)) {
41082
- const agentFiles = readdirSync7(agentsDir).filter((f) => f.endsWith(".md")).sort();
41122
+ const agentFiles = readdirSync6(agentsDir).filter((f) => f.endsWith(".md")).sort();
41083
41123
  for (const f of agentFiles) {
41084
41124
  entries.push(auditAgent(join54(agentsDir, f)));
41085
41125
  }
41086
41126
  }
41087
41127
  const skillsDir = join54(templatesDir, "skills");
41088
41128
  if (existsSync22(skillsDir)) {
41089
- const skillDirs = readdirSync7(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
41129
+ const skillDirs = readdirSync6(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
41090
41130
  for (const dir of skillDirs) {
41091
41131
  if (existsSync22(join54(skillsDir, dir, "PROVENANCE.md"))) continue;
41092
41132
  const skillMd = join54(skillsDir, dir, "SKILL.md");
@@ -41348,7 +41388,7 @@ __export(new_migration_exports, {
41348
41388
  newMigration: () => newMigration
41349
41389
  });
41350
41390
  import * as fs19 from "node:fs";
41351
- import * as path21 from "node:path";
41391
+ import * as path22 from "node:path";
41352
41392
  function slugify(name) {
41353
41393
  return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").replace(/_+/g, "_");
41354
41394
  }
@@ -41369,9 +41409,9 @@ function newMigration(args, deps = {}) {
41369
41409
  }
41370
41410
  const slug = slugify(rawName);
41371
41411
  const stamp = genTimestamp({ cwd });
41372
- const migrationsDir = path21.join(cwd, "supabase", "migrations");
41412
+ const migrationsDir = path22.join(cwd, "supabase", "migrations");
41373
41413
  const filename = `${stamp}_${slug}.sql`;
41374
- const filePath = path21.join(migrationsDir, filename);
41414
+ const filePath = path22.join(migrationsDir, filename);
41375
41415
  mkdirSync12(migrationsDir, { recursive: true });
41376
41416
  writeFileSync13(filePath, "");
41377
41417
  process.stdout.write(JSON.stringify({ path: filePath }) + "\n");
@@ -41417,7 +41457,7 @@ function defaultGetPrNumber(cwd, run) {
41417
41457
  async function previewCheck(args, deps = {}) {
41418
41458
  const cwd = deps.cwd ?? process.cwd();
41419
41459
  const run = deps.run ?? defaultRun4;
41420
- const sleep3 = deps.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
41460
+ const sleep3 = deps.sleep ?? ((ms) => new Promise((resolve17) => setTimeout(resolve17, ms)));
41421
41461
  const getPrNumber = deps.getPrNumber ?? defaultGetPrNumber;
41422
41462
  const poll = deps.pollCheck ?? pollGhPreviewCheck;
41423
41463
  let mode = "pre_merge";
@@ -41737,13 +41777,13 @@ function validateWaves(waves) {
41737
41777
  pathOwners.set(file, owners);
41738
41778
  }
41739
41779
  }
41740
- for (const [path22, owners] of pathOwners) {
41780
+ for (const [path23, owners] of pathOwners) {
41741
41781
  if (owners.length > 1) {
41742
41782
  violations.push({
41743
41783
  invariant: "I",
41744
41784
  code: "DUPLICATE_FILE",
41745
- message: `File "${path22}" appears in multiple waves: ${owners.join(", ")}.`,
41746
- detail: { path: path22, waves: owners }
41785
+ message: `File "${path23}" appears in multiple waves: ${owners.join(", ")}.`,
41786
+ detail: { path: path23, waves: owners }
41747
41787
  });
41748
41788
  }
41749
41789
  }
@@ -41837,14 +41877,14 @@ var validate_waves_exports = {};
41837
41877
  __export(validate_waves_exports, {
41838
41878
  runValidateWavesCommand: () => runValidateWavesCommand
41839
41879
  });
41840
- import { readFile as readFile31 } from "node:fs/promises";
41880
+ import { readFile as readFile32 } from "node:fs/promises";
41841
41881
  async function readStdin() {
41842
- return new Promise((resolve16, reject) => {
41882
+ return new Promise((resolve17, reject) => {
41843
41883
  const chunks = [];
41844
41884
  process.stdin.on("data", (chunk) => chunks.push(chunk));
41845
41885
  process.stdin.on(
41846
41886
  "end",
41847
- () => resolve16(Buffer.concat(chunks).toString("utf-8"))
41887
+ () => resolve17(Buffer.concat(chunks).toString("utf-8"))
41848
41888
  );
41849
41889
  process.stdin.on("error", reject);
41850
41890
  });
@@ -41856,7 +41896,7 @@ async function runValidateWavesCommand(args) {
41856
41896
  let raw;
41857
41897
  if (filePath) {
41858
41898
  try {
41859
- raw = await readFile31(filePath, "utf-8");
41899
+ raw = await readFile32(filePath, "utf-8");
41860
41900
  } catch (err) {
41861
41901
  const msg = err instanceof Error ? err.message : String(err);
41862
41902
  process.stderr.write(
@@ -41951,7 +41991,7 @@ var init_path = __esm({
41951
41991
 
41952
41992
  // src/cli/worktree/add.ts
41953
41993
  import { join as join57, basename as basename5 } from "node:path";
41954
- import { mkdir as mkdir15, readFile as readFile32, writeFile as writeFile25 } from "node:fs/promises";
41994
+ import { mkdir as mkdir15, readFile as readFile33, writeFile as writeFile25 } from "node:fs/promises";
41955
41995
  import { spawnSync as spawnSync18 } from "node:child_process";
41956
41996
  async function defaultGetRepoId(cwd) {
41957
41997
  const found = await findCodebyplanConfig(cwd);
@@ -41994,7 +42034,7 @@ function defaultGitRun(args, cwd) {
41994
42034
  };
41995
42035
  }
41996
42036
  async function copyClaudeSettings(srcCwd, destPath, deps = {}) {
41997
- const readFileFn = deps.readFileFn ?? ((p) => readFile32(p, "utf-8"));
42037
+ const readFileFn = deps.readFileFn ?? ((p) => readFile33(p, "utf-8"));
41998
42038
  const writeFileFn = deps.writeFileFn ?? ((p, content) => writeFile25(p, content, "utf-8"));
41999
42039
  const existsFn = deps.existsFn ?? ((p) => import("node:fs/promises").then(
42000
42040
  (fsp) => fsp.access(p).then(() => true).catch(() => false)
@@ -42019,13 +42059,13 @@ async function defaultCopyConfigStubs(srcCwd, destPath) {
42019
42059
  const topLevelStubs = [".mcp.json", ".env.local"];
42020
42060
  for (const stub of topLevelStubs) {
42021
42061
  try {
42022
- const content = await readFile32(join57(srcCwd, stub), "utf-8");
42062
+ const content = await readFile33(join57(srcCwd, stub), "utf-8");
42023
42063
  await writeFile25(join57(destPath, stub), content, "utf-8");
42024
42064
  } catch {
42025
42065
  }
42026
42066
  }
42027
42067
  try {
42028
- const content = await readFile32(
42068
+ const content = await readFile33(
42029
42069
  join57(srcCwd, ".codebyplan", "repo.json"),
42030
42070
  "utf-8"
42031
42071
  );
@@ -42038,11 +42078,11 @@ async function defaultCopyConfigStubs(srcCwd, destPath) {
42038
42078
  }
42039
42079
  await copyClaudeSettings(srcCwd, destPath);
42040
42080
  }
42041
- async function defaultRegisterWorktree(repoId, name, path22) {
42081
+ async function defaultRegisterWorktree(repoId, name, path23) {
42042
42082
  const res = await apiPost("/worktrees", {
42043
42083
  repo_id: repoId,
42044
42084
  name,
42045
- path: path22,
42085
+ path: path23,
42046
42086
  status: "active"
42047
42087
  });
42048
42088
  return { worktree_id: res.data.id };
@@ -42076,7 +42116,7 @@ async function runWorktreeAdd(args, deps = {}) {
42076
42116
  const getRepoId = deps.getRepoId ?? defaultGetRepoId;
42077
42117
  const lookupBranch = deps.lookupBranch ?? defaultLookupBranch;
42078
42118
  const gitRun = deps.gitRun ?? defaultGitRun;
42079
- const sleep3 = deps.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
42119
+ const sleep3 = deps.sleep ?? ((ms) => new Promise((resolve17) => setTimeout(resolve17, ms)));
42080
42120
  const copyConfigStubs = deps.copyConfigStubs ?? defaultCopyConfigStubs;
42081
42121
  const registerWorktree = deps.registerWorktree ?? defaultRegisterWorktree;
42082
42122
  try {
@@ -42207,11 +42247,11 @@ async function defaultGetRepoIdentity(cwd) {
42207
42247
  project_id: typeof contents?.["project_id"] === "string" ? contents["project_id"] : void 0
42208
42248
  };
42209
42249
  }
42210
- async function defaultRegisterWorktree2(repoId, name, path22) {
42250
+ async function defaultRegisterWorktree2(repoId, name, path23) {
42211
42251
  const res = await apiPost("/worktrees", {
42212
42252
  repo_id: repoId,
42213
42253
  name,
42214
- path: path22,
42254
+ path: path23,
42215
42255
  status: "active"
42216
42256
  });
42217
42257
  return { worktree_id: res.data.id };
@@ -42762,15 +42802,15 @@ var init_e2e = __esm({
42762
42802
  });
42763
42803
 
42764
42804
  // src/cli/e2e/verify-round.ts
42765
- import { readFile as readFile33 } from "node:fs/promises";
42766
- import { resolve as resolve14 } from "node:path";
42805
+ import { readFile as readFile34 } from "node:fs/promises";
42806
+ import { resolve as resolve15 } from "node:path";
42767
42807
  async function defaultFetchRounds(taskId) {
42768
42808
  return mcpCall("get_rounds", { task_id: taskId });
42769
42809
  }
42770
42810
  async function defaultReadE2eConfig(cwd) {
42771
42811
  try {
42772
- const p = resolve14(cwd, ".codebyplan", "e2e.json");
42773
- const raw = await readFile33(p, "utf-8");
42812
+ const p = resolve15(cwd, ".codebyplan", "e2e.json");
42813
+ const raw = await readFile34(p, "utf-8");
42774
42814
  return JSON.parse(raw);
42775
42815
  } catch {
42776
42816
  return null;
@@ -43184,11 +43224,11 @@ var init_doctor = __esm({
43184
43224
  // src/index.ts
43185
43225
  init_version();
43186
43226
  import { readFileSync as readFileSync20 } from "node:fs";
43187
- import { resolve as resolve15 } from "node:path";
43227
+ import { resolve as resolve16 } from "node:path";
43188
43228
  void (async () => {
43189
43229
  if (!process.env.CODEBYPLAN_API_KEY) {
43190
43230
  try {
43191
- const envPath = resolve15(process.cwd(), ".env.local");
43231
+ const envPath = resolve16(process.cwd(), ".env.local");
43192
43232
  const content = readFileSync20(envPath, "utf-8");
43193
43233
  for (const line of content.split("\n")) {
43194
43234
  const trimmed = line.trim();