codebyplan 1.13.64 → 1.13.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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.64";
51
+ VERSION = "1.13.65";
52
52
  PACKAGE_NAME = "codebyplan";
53
53
  }
54
54
  });
@@ -303,6 +303,7 @@ var init_gitignore_block = __esm({
303
303
  ".codebyplan/state/",
304
304
  ".codebyplan/clear/",
305
305
  ".codebyplan/todo/",
306
+ "!.codebyplan/handoff/",
306
307
  ".codebyplan/claude-status.local.json",
307
308
  ".codebyplan.local.json"
308
309
  ];
@@ -314,8 +315,8 @@ var init_gitignore_block = __esm({
314
315
  // src/lib/worktree.ts
315
316
  import { mkdir as mkdir2, writeFile as writeFile3, readFile as readFile3 } from "node:fs/promises";
316
317
  import { join as join3 } from "node:path";
317
- function defaultExists(path23) {
318
- return readFile3(path23, "utf-8").then(() => true).catch(() => false);
318
+ function defaultExists(path25) {
319
+ return readFile3(path25, "utf-8").then(() => true).catch(() => false);
319
320
  }
320
321
  async function writeRepoJson(codebyplanDir, selectedRepo, deps) {
321
322
  const repoJson = {
@@ -432,9 +433,9 @@ var init_worktree = __esm({
432
433
  init_statusline_config();
433
434
  init_gitignore_block();
434
435
  defaultFsDeps = {
435
- mkdir: (path23, opts) => mkdir2(path23, opts).then(() => void 0),
436
- writeFile: (path23, data, encoding) => writeFile3(path23, data, encoding),
437
- readFile: (path23, encoding) => readFile3(path23, encoding),
436
+ mkdir: (path25, opts) => mkdir2(path25, opts).then(() => void 0),
437
+ writeFile: (path25, data, encoding) => writeFile3(path25, data, encoding),
438
+ readFile: (path25, encoding) => readFile3(path25, encoding),
438
439
  exists: defaultExists
439
440
  };
440
441
  }
@@ -502,12 +503,12 @@ async function readFallback(filename) {
502
503
  }
503
504
  }
504
505
  async function writeFallback(filename, data) {
505
- const path23 = fallbackFile(filename);
506
- await mkdir3(dirname(path23), { recursive: true });
507
- await writeFile4(path23, JSON.stringify(data, null, 2) + "\n", "utf-8");
506
+ const path25 = fallbackFile(filename);
507
+ await mkdir3(dirname(path25), { recursive: true });
508
+ await writeFile4(path25, JSON.stringify(data, null, 2) + "\n", "utf-8");
508
509
  if (platform() !== "win32") {
509
510
  try {
510
- await chmod(path23, 384);
511
+ await chmod(path25, 384);
511
512
  } catch {
512
513
  }
513
514
  }
@@ -3140,9 +3141,9 @@ import { createInterface } from "node:readline/promises";
3140
3141
  function getConfigPath(scope) {
3141
3142
  return scope === "user" ? join12(homedir4(), ".claude.json") : join12(process.cwd(), ".mcp.json");
3142
3143
  }
3143
- async function readConfig(path23) {
3144
+ async function readConfig(path25) {
3144
3145
  try {
3145
- const raw = await readFile9(path23, "utf-8");
3146
+ const raw = await readFile9(path25, "utf-8");
3146
3147
  const parsed = JSON.parse(raw);
3147
3148
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
3148
3149
  return parsed;
@@ -3551,9 +3552,9 @@ import { join as join13 } from "node:path";
3551
3552
  function configPaths() {
3552
3553
  return [join13(homedir5(), ".claude.json"), join13(process.cwd(), ".mcp.json")];
3553
3554
  }
3554
- async function readConfig2(path23) {
3555
+ async function readConfig2(path25) {
3555
3556
  try {
3556
- const raw = await readFile10(path23, "utf-8");
3557
+ const raw = await readFile10(path25, "utf-8");
3557
3558
  const parsed = JSON.parse(raw);
3558
3559
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
3559
3560
  return parsed;
@@ -3567,7 +3568,7 @@ function entryHasLegacyApiKey(entry) {
3567
3568
  if (!entry || !entry.headers) return false;
3568
3569
  return "x-api-key" in entry.headers;
3569
3570
  }
3570
- async function rewriteConfig(path23, config, newUrl) {
3571
+ async function rewriteConfig(path25, config, newUrl) {
3571
3572
  const servers = config.mcpServers;
3572
3573
  if (!servers) return false;
3573
3574
  const entry = servers.codebyplan;
@@ -3575,7 +3576,7 @@ async function rewriteConfig(path23, config, newUrl) {
3575
3576
  if (!entryHasLegacyApiKey(entry) && entry.url === newUrl && entry.type === "http")
3576
3577
  return false;
3577
3578
  servers.codebyplan = { type: "http", url: newUrl };
3578
- await writeFile8(path23, JSON.stringify(config, null, 2) + "\n", "utf-8");
3579
+ await writeFile8(path25, JSON.stringify(config, null, 2) + "\n", "utf-8");
3579
3580
  return true;
3580
3581
  }
3581
3582
  async function runUpgradeAuth() {
@@ -3583,12 +3584,12 @@ async function runUpgradeAuth() {
3583
3584
  await runLogin();
3584
3585
  const newUrl = mcpEndpoint();
3585
3586
  let migrated = 0;
3586
- for (const path23 of configPaths()) {
3587
- const config = await readConfig2(path23);
3587
+ for (const path25 of configPaths()) {
3588
+ const config = await readConfig2(path25);
3588
3589
  if (!config) continue;
3589
- const changed = await rewriteConfig(path23, config, newUrl);
3590
+ const changed = await rewriteConfig(path25, config, newUrl);
3590
3591
  if (changed) {
3591
- console.log(` Updated ${path23}`);
3592
+ console.log(` Updated ${path25}`);
3592
3593
  migrated++;
3593
3594
  }
3594
3595
  }
@@ -3731,8 +3732,8 @@ async function validateConnectivity() {
3731
3732
  );
3732
3733
  }
3733
3734
  }
3734
- function buildUrl(path23, params) {
3735
- const url = new URL(`${baseUrl()}/api${path23}`);
3735
+ function buildUrl(path25, params) {
3736
+ const url = new URL(`${baseUrl()}/api${path25}`);
3736
3737
  if (params) {
3737
3738
  for (const [key, value] of Object.entries(params)) {
3738
3739
  if (value !== void 0) {
@@ -3751,8 +3752,8 @@ function isRetryable(err) {
3751
3752
  function delay(ms) {
3752
3753
  return new Promise((resolve17) => setTimeout(resolve17, ms));
3753
3754
  }
3754
- async function request(method, path23, options) {
3755
- const url = buildUrl(path23, options?.params);
3755
+ async function request(method, path25, options) {
3756
+ const url = buildUrl(path25, options?.params);
3756
3757
  const auth = await getAuthHeaders();
3757
3758
  let lastError;
3758
3759
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
@@ -3772,7 +3773,7 @@ async function request(method, path23, options) {
3772
3773
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
3773
3774
  });
3774
3775
  if (!res.ok) {
3775
- let message = `API ${method} ${path23} failed with status ${res.status}`;
3776
+ let message = `API ${method} ${path25} failed with status ${res.status}`;
3776
3777
  let code;
3777
3778
  try {
3778
3779
  const body = await res.json();
@@ -3806,20 +3807,20 @@ async function request(method, path23, options) {
3806
3807
  }
3807
3808
  throw lastError;
3808
3809
  }
3809
- async function apiGet(path23, params) {
3810
- return request("GET", path23, { params });
3810
+ async function apiGet(path25, params) {
3811
+ return request("GET", path25, { params });
3811
3812
  }
3812
- async function apiPost(path23, body) {
3813
- return request("POST", path23, { body });
3813
+ async function apiPost(path25, body) {
3814
+ return request("POST", path25, { body });
3814
3815
  }
3815
- async function apiPut(path23, body) {
3816
- return request("PUT", path23, { body });
3816
+ async function apiPut(path25, body) {
3817
+ return request("PUT", path25, { body });
3817
3818
  }
3818
- async function apiPatch(path23, body) {
3819
- return request("PATCH", path23, { body });
3819
+ async function apiPatch(path25, body) {
3820
+ return request("PATCH", path25, { body });
3820
3821
  }
3821
- async function apiDelete(path23, params) {
3822
- await request("DELETE", path23, { params });
3822
+ async function apiDelete(path25, params) {
3823
+ await request("DELETE", path25, { params });
3823
3824
  }
3824
3825
  async function callMcpTool(toolName, params) {
3825
3826
  const url = mcpEndpoint();
@@ -5680,13 +5681,13 @@ function __disposeResources(env) {
5680
5681
  }
5681
5682
  return next();
5682
5683
  }
5683
- function __rewriteRelativeImportExtension(path23, preserveJsx) {
5684
- if (typeof path23 === "string" && /^\.\.?\//.test(path23)) {
5685
- return path23.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
5684
+ function __rewriteRelativeImportExtension(path25, preserveJsx) {
5685
+ if (typeof path25 === "string" && /^\.\.?\//.test(path25)) {
5686
+ return path25.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
5686
5687
  return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
5687
5688
  });
5688
5689
  }
5689
- return path23;
5690
+ return path25;
5690
5691
  }
5691
5692
  var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
5692
5693
  var init_tslib_es6 = __esm({
@@ -14324,8 +14325,8 @@ var require_RealtimeChannel = __commonJS({
14324
14325
  }
14325
14326
  /** @internal */
14326
14327
  _notThisChannelEvent(event, ref) {
14327
- const { close, error, leave, join: join57 } = constants_1.CHANNEL_EVENTS;
14328
- const events = [close, error, leave, join57];
14328
+ const { close, error, leave, join: join60 } = constants_1.CHANNEL_EVENTS;
14329
+ const events = [close, error, leave, join60];
14329
14330
  return ref && events.includes(event) && ref !== this.joinPush.ref;
14330
14331
  }
14331
14332
  /** @internal */
@@ -15208,8 +15209,8 @@ var require_main2 = __commonJS({
15208
15209
  });
15209
15210
 
15210
15211
  // ../../node_modules/.pnpm/iceberg-js@0.8.1/node_modules/iceberg-js/dist/index.mjs
15211
- function buildUrl2(baseUrl3, path23, query) {
15212
- const url = new URL(path23, baseUrl3);
15212
+ function buildUrl2(baseUrl3, path25, query) {
15213
+ const url = new URL(path25, baseUrl3);
15213
15214
  if (query) {
15214
15215
  for (const [key, value] of Object.entries(query)) {
15215
15216
  if (value !== void 0) {
@@ -15239,12 +15240,12 @@ function createFetchClient(options) {
15239
15240
  return {
15240
15241
  async request({
15241
15242
  method,
15242
- path: path23,
15243
+ path: path25,
15243
15244
  query,
15244
15245
  body,
15245
15246
  headers
15246
15247
  }) {
15247
- const url = buildUrl2(options.baseUrl, path23, query);
15248
+ const url = buildUrl2(options.baseUrl, path25, query);
15248
15249
  const authHeaders = await buildAuthHeaders(options.auth);
15249
15250
  const res = await fetchFn(url, {
15250
15251
  method,
@@ -16142,7 +16143,7 @@ var init_dist3 = __esm({
16142
16143
  * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload.
16143
16144
  * @param fileBody The body of the file to be stored in the bucket.
16144
16145
  */
16145
- async uploadOrUpdate(method, path23, fileBody, fileOptions) {
16146
+ async uploadOrUpdate(method, path25, fileBody, fileOptions) {
16146
16147
  var _this = this;
16147
16148
  return _this.handleOperation(async () => {
16148
16149
  let body;
@@ -16166,7 +16167,7 @@ var init_dist3 = __esm({
16166
16167
  if ((typeof ReadableStream !== "undefined" && body instanceof ReadableStream || body && typeof body === "object" && "pipe" in body && typeof body.pipe === "function") && !options.duplex) options.duplex = "half";
16167
16168
  }
16168
16169
  if (fileOptions === null || fileOptions === void 0 ? void 0 : fileOptions.headers) for (const [key, value] of Object.entries(fileOptions.headers)) headers = setHeader(headers, key, value);
16169
- const cleanPath = _this._removeEmptyFolders(path23);
16170
+ const cleanPath = _this._removeEmptyFolders(path25);
16170
16171
  const _path = _this._getFinalPath(cleanPath);
16171
16172
  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 } : {}));
16172
16173
  return {
@@ -16228,8 +16229,8 @@ var init_dist3 = __esm({
16228
16229
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16229
16230
  * - 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.
16230
16231
  */
16231
- async upload(path23, fileBody, fileOptions) {
16232
- return this.uploadOrUpdate("POST", path23, fileBody, fileOptions);
16232
+ async upload(path25, fileBody, fileOptions) {
16233
+ return this.uploadOrUpdate("POST", path25, fileBody, fileOptions);
16233
16234
  }
16234
16235
  /**
16235
16236
  * Upload a file with a token generated from `createSignedUploadUrl`.
@@ -16269,9 +16270,9 @@ var init_dist3 = __esm({
16269
16270
  * - `objects` table permissions: none
16270
16271
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16271
16272
  */
16272
- async uploadToSignedUrl(path23, token, fileBody, fileOptions) {
16273
+ async uploadToSignedUrl(path25, token, fileBody, fileOptions) {
16273
16274
  var _this3 = this;
16274
- const cleanPath = _this3._removeEmptyFolders(path23);
16275
+ const cleanPath = _this3._removeEmptyFolders(path25);
16275
16276
  const _path = _this3._getFinalPath(cleanPath);
16276
16277
  const url = new URL(_this3.url + `/object/upload/sign/${_path}`);
16277
16278
  url.searchParams.set("token", token);
@@ -16340,10 +16341,10 @@ var init_dist3 = __esm({
16340
16341
  * - `objects` table permissions: `insert`
16341
16342
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16342
16343
  */
16343
- async createSignedUploadUrl(path23, options) {
16344
+ async createSignedUploadUrl(path25, options) {
16344
16345
  var _this4 = this;
16345
16346
  return _this4.handleOperation(async () => {
16346
- let _path = _this4._getFinalPath(path23);
16347
+ let _path = _this4._getFinalPath(path25);
16347
16348
  const headers = _objectSpread22({}, _this4.headers);
16348
16349
  if (options === null || options === void 0 ? void 0 : options.upsert) headers["x-upsert"] = "true";
16349
16350
  const data = await post(_this4.fetch, `${_this4.url}/object/upload/sign/${_path}`, {}, { headers });
@@ -16352,7 +16353,7 @@ var init_dist3 = __esm({
16352
16353
  if (!token) throw new StorageError("No token returned by API");
16353
16354
  return {
16354
16355
  signedUrl: url.toString(),
16355
- path: path23,
16356
+ path: path25,
16356
16357
  token
16357
16358
  };
16358
16359
  });
@@ -16412,8 +16413,8 @@ var init_dist3 = __esm({
16412
16413
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16413
16414
  * - 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.
16414
16415
  */
16415
- async update(path23, fileBody, fileOptions) {
16416
- return this.uploadOrUpdate("PUT", path23, fileBody, fileOptions);
16416
+ async update(path25, fileBody, fileOptions) {
16417
+ return this.uploadOrUpdate("PUT", path25, fileBody, fileOptions);
16417
16418
  }
16418
16419
  /**
16419
16420
  * Moves an existing file to a new path in the same bucket.
@@ -16564,10 +16565,10 @@ var init_dist3 = __esm({
16564
16565
  * - `objects` table permissions: `select`
16565
16566
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16566
16567
  */
16567
- async createSignedUrl(path23, expiresIn, options) {
16568
+ async createSignedUrl(path25, expiresIn, options) {
16568
16569
  var _this8 = this;
16569
16570
  return _this8.handleOperation(async () => {
16570
- let _path = _this8._getFinalPath(path23);
16571
+ let _path = _this8._getFinalPath(path25);
16571
16572
  const hasTransform = typeof (options === null || options === void 0 ? void 0 : options.transform) === "object" && options.transform !== null && Object.keys(options.transform).length > 0;
16572
16573
  let data = await post(_this8.fetch, `${_this8.url}/object/sign/${_path}`, _objectSpread22({ expiresIn }, hasTransform ? { transform: options.transform } : {}), { headers: _this8.headers });
16573
16574
  const query = new URLSearchParams();
@@ -16703,13 +16704,13 @@ var init_dist3 = __esm({
16703
16704
  * - `objects` table permissions: `select`
16704
16705
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16705
16706
  */
16706
- download(path23, options, parameters) {
16707
+ download(path25, options, parameters) {
16707
16708
  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";
16708
16709
  const query = new URLSearchParams();
16709
16710
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
16710
16711
  if ((options === null || options === void 0 ? void 0 : options.cacheNonce) != null) query.set("cacheNonce", String(options.cacheNonce));
16711
16712
  const queryString = query.toString();
16712
- const _path = this._getFinalPath(path23);
16713
+ const _path = this._getFinalPath(path25);
16713
16714
  const downloadFn = () => get(this.fetch, `${this.url}/${renderPath}/${_path}${queryString ? `?${queryString}` : ""}`, {
16714
16715
  headers: this.headers,
16715
16716
  noResolveJson: true
@@ -16740,9 +16741,9 @@ var init_dist3 = __esm({
16740
16741
  * }
16741
16742
  * ```
16742
16743
  */
16743
- async info(path23) {
16744
+ async info(path25) {
16744
16745
  var _this10 = this;
16745
- const _path = _this10._getFinalPath(path23);
16746
+ const _path = _this10._getFinalPath(path25);
16746
16747
  return _this10.handleOperation(async () => {
16747
16748
  return recursiveToCamel(await get(_this10.fetch, `${_this10.url}/object/info/${_path}`, { headers: _this10.headers }));
16748
16749
  });
@@ -16763,9 +16764,9 @@ var init_dist3 = __esm({
16763
16764
  * .exists('folder/avatar1.png')
16764
16765
  * ```
16765
16766
  */
16766
- async exists(path23) {
16767
+ async exists(path25) {
16767
16768
  var _this11 = this;
16768
- const _path = _this11._getFinalPath(path23);
16769
+ const _path = _this11._getFinalPath(path25);
16769
16770
  try {
16770
16771
  await head(_this11.fetch, `${_this11.url}/object/${_path}`, { headers: _this11.headers });
16771
16772
  return {
@@ -16844,8 +16845,8 @@ var init_dist3 = __esm({
16844
16845
  * - `objects` table permissions: none
16845
16846
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16846
16847
  */
16847
- getPublicUrl(path23, options) {
16848
- const _path = this._getFinalPath(path23);
16848
+ getPublicUrl(path25, options) {
16849
+ const _path = this._getFinalPath(path25);
16849
16850
  const query = new URLSearchParams();
16850
16851
  if (options === null || options === void 0 ? void 0 : options.download) query.set("download", options.download === true ? "" : options.download);
16851
16852
  if (options === null || options === void 0 ? void 0 : options.transform) this.applyTransformOptsToQuery(query, options.transform);
@@ -16984,10 +16985,10 @@ var init_dist3 = __esm({
16984
16985
  * - `objects` table permissions: `select`
16985
16986
  * - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works
16986
16987
  */
16987
- async list(path23, options, parameters) {
16988
+ async list(path25, options, parameters) {
16988
16989
  var _this13 = this;
16989
16990
  return _this13.handleOperation(async () => {
16990
- const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path23 || "" });
16991
+ const body = _objectSpread22(_objectSpread22(_objectSpread22({}, DEFAULT_SEARCH_OPTIONS), options), {}, { prefix: path25 || "" });
16991
16992
  return await post(_this13.fetch, `${_this13.url}/object/list/${_this13.bucketId}`, body, { headers: _this13.headers }, parameters);
16992
16993
  });
16993
16994
  }
@@ -17052,11 +17053,11 @@ var init_dist3 = __esm({
17052
17053
  if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
17053
17054
  return btoa(data);
17054
17055
  }
17055
- _getFinalPath(path23) {
17056
- return `${this.bucketId}/${path23.replace(/^\/+/, "")}`;
17056
+ _getFinalPath(path25) {
17057
+ return `${this.bucketId}/${path25.replace(/^\/+/, "")}`;
17057
17058
  }
17058
- _removeEmptyFolders(path23) {
17059
- return path23.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
17059
+ _removeEmptyFolders(path25) {
17060
+ return path25.replace(/^\/|\/$/g, "").replace(/\/+/g, "/");
17060
17061
  }
17061
17062
  /** Modifies the `query`, appending values the from `transform` */
17062
17063
  applyTransformOptsToQuery(query, transform) {
@@ -27774,8 +27775,8 @@ var init_watch = __esm({
27774
27775
  function isConflict(err) {
27775
27776
  return err instanceof BackendError && err.status === 409;
27776
27777
  }
27777
- async function backendRequest(method, path23, body) {
27778
- const url = `${getBackendBase()}${path23}`;
27778
+ async function backendRequest(method, path25, body) {
27779
+ const url = `${getBackendBase()}${path25}`;
27779
27780
  const auth = await getAuthHeaders();
27780
27781
  const res = await fetch(url, {
27781
27782
  method,
@@ -27787,7 +27788,7 @@ async function backendRequest(method, path23, body) {
27787
27788
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
27788
27789
  });
27789
27790
  if (!res.ok) {
27790
- let message = `Backend ${method} ${path23} failed with status ${res.status}`;
27791
+ let message = `Backend ${method} ${path25} failed with status ${res.status}`;
27791
27792
  try {
27792
27793
  const errBody = await res.json();
27793
27794
  const msg = typeof errBody.message === "string" ? errBody.message : typeof errBody.error === "string" ? errBody.error : void 0;
@@ -27801,11 +27802,11 @@ async function backendRequest(method, path23, body) {
27801
27802
  }
27802
27803
  return res.json();
27803
27804
  }
27804
- async function apiBackendPost(path23, body) {
27805
- return backendRequest("POST", path23, body);
27805
+ async function apiBackendPost(path25, body) {
27806
+ return backendRequest("POST", path25, body);
27806
27807
  }
27807
- async function apiBackendPatch(path23, body) {
27808
- return backendRequest("PATCH", path23, body);
27808
+ async function apiBackendPatch(path25, body) {
27809
+ return backendRequest("PATCH", path25, body);
27809
27810
  }
27810
27811
  var REQUEST_TIMEOUT_MS2, BackendError;
27811
27812
  var init_state_client = __esm({
@@ -28081,8 +28082,8 @@ ${taskRows}
28081
28082
  for (const task of data.tasks) {
28082
28083
  if (Array.isArray(task.files_changed)) {
28083
28084
  for (const f of task.files_changed) {
28084
- const path23 = typeof f === "string" ? f : f?.path;
28085
- if (path23) allFiles.add(path23);
28085
+ const path25 = typeof f === "string" ? f : f?.path;
28086
+ if (path25) allFiles.add(path25);
28086
28087
  }
28087
28088
  }
28088
28089
  }
@@ -30690,7 +30691,7 @@ __export(start_exports, {
30690
30691
  runSessionStartCli: () => runSessionStartCli
30691
30692
  });
30692
30693
  import { spawnSync as spawnSync8 } from "node:child_process";
30693
- import { dirname as dirname7 } from "node:path";
30694
+ import { dirname as dirname7, join as join24 } from "node:path";
30694
30695
  async function updateCursorHashLocal(repoRoot, entityId, row) {
30695
30696
  const cursor = await readCursor(repoRoot);
30696
30697
  if (!cursor) return;
@@ -30738,7 +30739,7 @@ async function defaultUpdateStateActivate(repoId, repoRoot) {
30738
30739
  );
30739
30740
  }
30740
30741
  }
30741
- function buildCreateLogBody(repoId, now = /* @__PURE__ */ new Date()) {
30742
+ function buildCreateLogBody(repoId, now = /* @__PURE__ */ new Date(), claudeSessionId) {
30742
30743
  const session_date = now.toISOString().slice(0, 10);
30743
30744
  const jan1 = Date.UTC(now.getUTCFullYear(), 0, 1);
30744
30745
  const day_number = Math.floor((now.getTime() - jan1) / 864e5) + 1;
@@ -30747,11 +30748,28 @@ function buildCreateLogBody(repoId, now = /* @__PURE__ */ new Date()) {
30747
30748
  session_date,
30748
30749
  day_number,
30749
30750
  started_at: now.toISOString(),
30750
- summary: ""
30751
+ ...claudeSessionId != null ? { claude_session_id: claudeSessionId } : {}
30751
30752
  };
30752
30753
  }
30753
30754
  async function defaultCreateLog(repoId, repoRoot) {
30754
- const body = buildCreateLogBody(repoId);
30755
+ let claudeSessionId = null;
30756
+ try {
30757
+ const sessionIdFile = join24(
30758
+ repoRoot,
30759
+ ".codebyplan",
30760
+ "state",
30761
+ "session",
30762
+ "session-id.json"
30763
+ );
30764
+ const raw = await readEntityFile(
30765
+ sessionIdFile
30766
+ );
30767
+ if (raw?.claude_session_id && typeof raw.claude_session_id === "string") {
30768
+ claudeSessionId = raw.claude_session_id;
30769
+ }
30770
+ } catch {
30771
+ }
30772
+ const body = buildCreateLogBody(repoId, /* @__PURE__ */ new Date(), claudeSessionId);
30755
30773
  try {
30756
30774
  const created = await apiBackendPost(new URL(backendSessionLogsEndpoint()).pathname, body);
30757
30775
  const sessionLog = created.session_log ?? created;
@@ -31356,9 +31374,464 @@ var init_session2 = __esm({
31356
31374
  }
31357
31375
  });
31358
31376
 
31377
+ // src/lib/handoff-file.ts
31378
+ import * as path9 from "node:path";
31379
+ function handoffPath(projectDir, level, opts = {}) {
31380
+ const base = path9.join(projectDir, ".codebyplan", "handoff");
31381
+ switch (level) {
31382
+ case "repo":
31383
+ return path9.join(base, "repo.md");
31384
+ case "checkpoint": {
31385
+ if (opts.checkpoint == null) {
31386
+ throw new Error(
31387
+ 'handoffPath: opts.checkpoint is required for level "checkpoint"'
31388
+ );
31389
+ }
31390
+ const n = String(opts.checkpoint).padStart(3, "0");
31391
+ return path9.join(base, "checkpoint", `${n}.md`);
31392
+ }
31393
+ case "task": {
31394
+ if (opts.checkpoint == null) {
31395
+ throw new Error(
31396
+ 'handoffPath: opts.checkpoint is required for level "task"'
31397
+ );
31398
+ }
31399
+ if (opts.task == null) {
31400
+ throw new Error('handoffPath: opts.task is required for level "task"');
31401
+ }
31402
+ const n = String(opts.checkpoint).padStart(3, "0");
31403
+ return path9.join(base, "task", `${n}-${opts.task}.md`);
31404
+ }
31405
+ case "standalone": {
31406
+ if (opts.number == null) {
31407
+ throw new Error(
31408
+ 'handoffPath: opts.number is required for level "standalone"'
31409
+ );
31410
+ }
31411
+ return path9.join(base, "standalone", `${opts.number}.md`);
31412
+ }
31413
+ }
31414
+ }
31415
+ function isHandoffEmpty(content) {
31416
+ if (content == null) return true;
31417
+ return content.trim() === "";
31418
+ }
31419
+ function readHandoffSection(fileContent, sectionLabel) {
31420
+ const heading = `## ${sectionLabel}`;
31421
+ const lines = fileContent.split("\n");
31422
+ const startIdx = lines.findIndex((l) => l.trim() === heading);
31423
+ if (startIdx === -1) return null;
31424
+ const bodyLines = [];
31425
+ for (let i = startIdx + 1; i < lines.length; i++) {
31426
+ const line = lines[i];
31427
+ if (line.startsWith("## ")) break;
31428
+ bodyLines.push(line);
31429
+ }
31430
+ let start = 0;
31431
+ while (start < bodyLines.length && (bodyLines[start] ?? "").trim() === "") {
31432
+ start++;
31433
+ }
31434
+ let end = bodyLines.length - 1;
31435
+ while (end >= start && (bodyLines[end] ?? "").trim() === "") {
31436
+ end--;
31437
+ }
31438
+ const body = bodyLines.slice(start, end + 1).join("\n");
31439
+ return body.trim() === "" ? null : body;
31440
+ }
31441
+ function replaceHandoffSection(fileContent, sectionLabel, body) {
31442
+ if (isHandoffEmpty(body)) {
31443
+ return removeHandoffSection(fileContent, sectionLabel);
31444
+ }
31445
+ const heading = `## ${sectionLabel}`;
31446
+ const lines = fileContent.split("\n");
31447
+ const startIdx = lines.findIndex((l) => l.trim() === heading);
31448
+ const newSection = [heading, "", body.trim(), ""].join("\n");
31449
+ if (startIdx === -1) {
31450
+ const trimmed = fileContent.trimEnd();
31451
+ const separator = trimmed.length > 0 ? "\n\n" : "";
31452
+ return trimmed + separator + newSection;
31453
+ }
31454
+ let endIdx = lines.length;
31455
+ for (let i = startIdx + 1; i < lines.length; i++) {
31456
+ if ((lines[i] ?? "").startsWith("## ")) {
31457
+ endIdx = i;
31458
+ break;
31459
+ }
31460
+ }
31461
+ const before = lines.slice(0, startIdx).join("\n");
31462
+ const after = lines.slice(endIdx).join("\n");
31463
+ const parts = [];
31464
+ if (before.trimEnd().length > 0) parts.push(before.trimEnd());
31465
+ parts.push(newSection.trimEnd());
31466
+ if (after.trimStart().length > 0) parts.push(after.trimStart());
31467
+ return parts.join("\n\n") + "\n";
31468
+ }
31469
+ function removeHandoffSection(fileContent, sectionLabel) {
31470
+ const heading = `## ${sectionLabel}`;
31471
+ const lines = fileContent.split("\n");
31472
+ const startIdx = lines.findIndex((l) => l.trim() === heading);
31473
+ if (startIdx === -1) return fileContent;
31474
+ let endIdx = lines.length;
31475
+ for (let i = startIdx + 1; i < lines.length; i++) {
31476
+ if ((lines[i] ?? "").startsWith("## ")) {
31477
+ endIdx = i;
31478
+ break;
31479
+ }
31480
+ }
31481
+ const before = lines.slice(0, startIdx);
31482
+ const after = lines.slice(endIdx);
31483
+ while (before.length > 0 && (before[before.length - 1] ?? "").trim() === "") {
31484
+ before.pop();
31485
+ }
31486
+ while (after.length > 0 && (after[0] ?? "").trim() === "") {
31487
+ after.shift();
31488
+ }
31489
+ if (before.length === 0 && after.length === 0) return "";
31490
+ const parts = [];
31491
+ if (before.length > 0) parts.push(before.join("\n"));
31492
+ if (after.length > 0) parts.push(after.join("\n"));
31493
+ return parts.join("\n\n") + (fileContent.endsWith("\n") ? "\n" : "");
31494
+ }
31495
+ var HANDOFF_LEVELS;
31496
+ var init_handoff_file = __esm({
31497
+ "src/lib/handoff-file.ts"() {
31498
+ "use strict";
31499
+ HANDOFF_LEVELS = [
31500
+ "repo",
31501
+ "checkpoint",
31502
+ "task",
31503
+ "standalone"
31504
+ ];
31505
+ }
31506
+ });
31507
+
31508
+ // src/cli/handoff.ts
31509
+ var handoff_exports = {};
31510
+ __export(handoff_exports, {
31511
+ runHandoffCommand: () => runHandoffCommand
31512
+ });
31513
+ import { readFile as readFile15, writeFile as writeFile12, mkdir as mkdir7, unlink as unlink5, readdir as readdir4 } from "node:fs/promises";
31514
+ import * as path10 from "node:path";
31515
+ async function resolveWorktreeLabel(repoRoot) {
31516
+ let branch = "";
31517
+ try {
31518
+ branch = getCurrentBranch(repoRoot);
31519
+ } catch {
31520
+ }
31521
+ if (branch) {
31522
+ try {
31523
+ const worktreesPath = path10.join(
31524
+ repoRoot,
31525
+ ".codebyplan",
31526
+ "state",
31527
+ "worktrees.json"
31528
+ );
31529
+ const raw = await readFile15(worktreesPath, "utf-8");
31530
+ const parsed = JSON.parse(raw);
31531
+ const entries = Array.isArray(parsed) ? parsed : parsed.data ?? [];
31532
+ const match = entries.find((e) => e.branch === branch);
31533
+ if (match?.name) return match.name;
31534
+ } catch {
31535
+ }
31536
+ return branch.replace(/\//g, "-");
31537
+ }
31538
+ return "default";
31539
+ }
31540
+ async function readHandoffFile(filePath) {
31541
+ try {
31542
+ return await readFile15(filePath, "utf-8");
31543
+ } catch {
31544
+ return null;
31545
+ }
31546
+ }
31547
+ async function writeHandoffFile(filePath, content) {
31548
+ await mkdir7(path10.dirname(filePath), { recursive: true });
31549
+ await writeFile12(filePath, content, "utf-8");
31550
+ }
31551
+ async function deleteHandoffFile(filePath) {
31552
+ try {
31553
+ await unlink5(filePath);
31554
+ } catch {
31555
+ }
31556
+ }
31557
+ function parseLevel(flags) {
31558
+ const raw = flags["level"];
31559
+ if (!raw) {
31560
+ process.stderr.write("handoff: --level <level> is required\n");
31561
+ process.exit(1);
31562
+ }
31563
+ if (!HANDOFF_LEVELS.includes(raw)) {
31564
+ process.stderr.write(
31565
+ `handoff: unknown level "${raw}". Valid levels: ${HANDOFF_LEVELS.join(", ")}
31566
+ `
31567
+ );
31568
+ process.exit(1);
31569
+ }
31570
+ return raw;
31571
+ }
31572
+ function parsePathOpts(flags) {
31573
+ const opts = {};
31574
+ if (flags["number"] !== void 0) opts.number = Number(flags["number"]);
31575
+ if (flags["task"] !== void 0) opts.task = Number(flags["task"]);
31576
+ if (flags["checkpoint"] !== void 0)
31577
+ opts.checkpoint = Number(flags["checkpoint"]);
31578
+ if (opts.checkpoint == null && flags["number"] !== void 0) {
31579
+ opts.checkpoint = Number(flags["number"]);
31580
+ }
31581
+ return opts;
31582
+ }
31583
+ async function resolveRepoRoot5() {
31584
+ const found = await findCodebyplanConfig(process.cwd());
31585
+ if (!found) {
31586
+ process.stderr.write(
31587
+ "handoff: no .codebyplan/repo.json found. Run `codebyplan setup`.\n"
31588
+ );
31589
+ process.exit(1);
31590
+ }
31591
+ return deriveRepoRoot(found.path);
31592
+ }
31593
+ async function runHandoffRead(args) {
31594
+ const { flags } = parseFlagsFromArgs(args);
31595
+ const level = parseLevel(flags);
31596
+ const repoRoot = await resolveRepoRoot5();
31597
+ let filePath;
31598
+ try {
31599
+ filePath = handoffPath(repoRoot, level, parsePathOpts(flags));
31600
+ } catch (err) {
31601
+ process.stderr.write(
31602
+ `handoff read: ${err instanceof Error ? err.message : String(err)}
31603
+ `
31604
+ );
31605
+ process.exit(1);
31606
+ }
31607
+ const content = await readHandoffFile(filePath);
31608
+ if (content === null || isHandoffEmpty(content)) {
31609
+ process.exit(0);
31610
+ }
31611
+ if (level === "repo") {
31612
+ const label = await resolveWorktreeLabel(repoRoot);
31613
+ const section = readHandoffSection(content, label);
31614
+ if (section !== null) {
31615
+ process.stdout.write(section + "\n");
31616
+ }
31617
+ } else {
31618
+ process.stdout.write(content);
31619
+ }
31620
+ process.exit(0);
31621
+ }
31622
+ async function runHandoffWrite(args) {
31623
+ const { flags } = parseFlagsFromArgs(args);
31624
+ const level = parseLevel(flags);
31625
+ const newContent = flags["content"];
31626
+ if (newContent === void 0) {
31627
+ process.stderr.write("handoff write: --content <text> is required\n");
31628
+ process.exit(1);
31629
+ }
31630
+ const repoRoot = await resolveRepoRoot5();
31631
+ let filePath;
31632
+ try {
31633
+ filePath = handoffPath(repoRoot, level, parsePathOpts(flags));
31634
+ } catch (err) {
31635
+ process.stderr.write(
31636
+ `handoff write: ${err instanceof Error ? err.message : String(err)}
31637
+ `
31638
+ );
31639
+ process.exit(1);
31640
+ }
31641
+ if (level === "repo") {
31642
+ const label = await resolveWorktreeLabel(repoRoot);
31643
+ const existing = await readHandoffFile(filePath) ?? "";
31644
+ const updated = replaceHandoffSection(existing, label, newContent);
31645
+ if (isHandoffEmpty(updated)) {
31646
+ await deleteHandoffFile(filePath);
31647
+ } else {
31648
+ await writeHandoffFile(filePath, updated);
31649
+ }
31650
+ } else {
31651
+ if (isHandoffEmpty(newContent)) {
31652
+ await deleteHandoffFile(filePath);
31653
+ } else {
31654
+ await writeHandoffFile(filePath, newContent);
31655
+ }
31656
+ }
31657
+ process.exit(0);
31658
+ }
31659
+ async function runHandoffAppend(args) {
31660
+ const { flags } = parseFlagsFromArgs(args);
31661
+ const level = parseLevel(flags);
31662
+ const appendContent = flags["content"];
31663
+ if (appendContent === void 0) {
31664
+ process.stderr.write("handoff append: --content <text> is required\n");
31665
+ process.exit(1);
31666
+ }
31667
+ const repoRoot = await resolveRepoRoot5();
31668
+ let filePath;
31669
+ try {
31670
+ filePath = handoffPath(repoRoot, level, parsePathOpts(flags));
31671
+ } catch (err) {
31672
+ process.stderr.write(
31673
+ `handoff append: ${err instanceof Error ? err.message : String(err)}
31674
+ `
31675
+ );
31676
+ process.exit(1);
31677
+ }
31678
+ const existing = await readHandoffFile(filePath) ?? "";
31679
+ if (level === "repo") {
31680
+ const label = await resolveWorktreeLabel(repoRoot);
31681
+ const currentSection = readHandoffSection(existing, label) ?? "";
31682
+ const combined = isHandoffEmpty(currentSection) ? appendContent : currentSection + "\n" + appendContent;
31683
+ const updated = replaceHandoffSection(existing, label, combined);
31684
+ if (isHandoffEmpty(updated)) {
31685
+ await deleteHandoffFile(filePath);
31686
+ } else {
31687
+ await writeHandoffFile(filePath, updated);
31688
+ }
31689
+ } else {
31690
+ const combined = isHandoffEmpty(existing) ? appendContent : existing.trimEnd() + "\n" + appendContent;
31691
+ if (isHandoffEmpty(combined)) {
31692
+ await deleteHandoffFile(filePath);
31693
+ } else {
31694
+ await writeHandoffFile(filePath, combined);
31695
+ }
31696
+ }
31697
+ process.exit(0);
31698
+ }
31699
+ async function runHandoffClear(args) {
31700
+ const { flags } = parseFlagsFromArgs(args);
31701
+ const level = parseLevel(flags);
31702
+ const repoRoot = await resolveRepoRoot5();
31703
+ let filePath;
31704
+ try {
31705
+ filePath = handoffPath(repoRoot, level, parsePathOpts(flags));
31706
+ } catch (err) {
31707
+ process.stderr.write(
31708
+ `handoff clear: ${err instanceof Error ? err.message : String(err)}
31709
+ `
31710
+ );
31711
+ process.exit(1);
31712
+ }
31713
+ if (level === "repo") {
31714
+ const label = await resolveWorktreeLabel(repoRoot);
31715
+ const existing = await readHandoffFile(filePath) ?? "";
31716
+ const updated = removeHandoffSection(existing, label);
31717
+ if (isHandoffEmpty(updated)) {
31718
+ await deleteHandoffFile(filePath);
31719
+ } else {
31720
+ await writeHandoffFile(filePath, updated);
31721
+ }
31722
+ } else {
31723
+ await deleteHandoffFile(filePath);
31724
+ }
31725
+ process.exit(0);
31726
+ }
31727
+ async function scanHandoffDir(baseDir, level, subDir) {
31728
+ const dir = path10.join(baseDir, subDir);
31729
+ const entries = [];
31730
+ let files;
31731
+ try {
31732
+ files = await readdir4(dir);
31733
+ } catch {
31734
+ return entries;
31735
+ }
31736
+ for (const file of files.filter((f) => f.endsWith(".md"))) {
31737
+ const filePath = path10.join(dir, file);
31738
+ const content = await readHandoffFile(filePath);
31739
+ if (!isHandoffEmpty(content)) {
31740
+ entries.push({
31741
+ level,
31742
+ identifier: path10.basename(file, ".md"),
31743
+ path: filePath
31744
+ });
31745
+ }
31746
+ }
31747
+ return entries;
31748
+ }
31749
+ async function runHandoffStatus(args) {
31750
+ const { booleans } = parseFlagsFromArgs(args);
31751
+ const jsonMode = booleans.has("json");
31752
+ const repoRoot = await resolveRepoRoot5();
31753
+ const baseDir = path10.join(repoRoot, ".codebyplan", "handoff");
31754
+ const nonEmpty = [];
31755
+ const repoFile = path10.join(baseDir, "repo.md");
31756
+ const repoContent = await readHandoffFile(repoFile);
31757
+ if (!isHandoffEmpty(repoContent)) {
31758
+ nonEmpty.push({ level: "repo", identifier: "repo", path: repoFile });
31759
+ }
31760
+ nonEmpty.push(...await scanHandoffDir(baseDir, "checkpoint", "checkpoint"));
31761
+ nonEmpty.push(...await scanHandoffDir(baseDir, "task", "task"));
31762
+ nonEmpty.push(...await scanHandoffDir(baseDir, "standalone", "standalone"));
31763
+ const output = { nonEmpty, empty: [] };
31764
+ if (jsonMode) {
31765
+ process.stdout.write(JSON.stringify(output, null, 2) + "\n");
31766
+ } else {
31767
+ if (nonEmpty.length === 0) {
31768
+ process.stdout.write("No handoff content found.\n");
31769
+ } else {
31770
+ process.stdout.write("Handoffs with content:\n");
31771
+ for (const entry of nonEmpty) {
31772
+ process.stdout.write(
31773
+ ` [${entry.level}] ${entry.identifier} ${entry.path}
31774
+ `
31775
+ );
31776
+ }
31777
+ }
31778
+ }
31779
+ process.exit(0);
31780
+ }
31781
+ async function runHandoffCommand(args) {
31782
+ const subcommand = args[0];
31783
+ if (subcommand === "read") {
31784
+ await runHandoffRead(args.slice(1));
31785
+ return;
31786
+ }
31787
+ if (subcommand === "write") {
31788
+ await runHandoffWrite(args.slice(1));
31789
+ return;
31790
+ }
31791
+ if (subcommand === "append") {
31792
+ await runHandoffAppend(args.slice(1));
31793
+ return;
31794
+ }
31795
+ if (subcommand === "clear") {
31796
+ await runHandoffClear(args.slice(1));
31797
+ return;
31798
+ }
31799
+ if (subcommand === "status") {
31800
+ await runHandoffStatus(args.slice(1));
31801
+ return;
31802
+ }
31803
+ if (subcommand === "help" || subcommand === "--help" || subcommand === "-h") {
31804
+ printHandoffHelp();
31805
+ process.exit(0);
31806
+ }
31807
+ if (subcommand) {
31808
+ process.stderr.write(
31809
+ `Unknown handoff subcommand: ${subcommand}
31810
+ Run 'codebyplan handoff help' for usage.
31811
+ `
31812
+ );
31813
+ } else {
31814
+ printHandoffHelp();
31815
+ }
31816
+ process.exit(1);
31817
+ }
31818
+ function printHandoffHelp() {
31819
+ process.stdout.write(
31820
+ "\n codebyplan handoff <subcommand>\n\n Manage per-level handoff notes in .codebyplan/handoff/\n\n Levels:\n repo Per-worktree section in .codebyplan/handoff/repo.md\n checkpoint .codebyplan/handoff/checkpoint/<NNN>.md\n task .codebyplan/handoff/task/<NNN>-<T>.md\n standalone .codebyplan/handoff/standalone/<N>.md\n\n Subcommands:\n read --level <l> [--number N] [--task T]\n Print current handoff content (empty output if absent)\n write --level <l> [--number N] [--task T] --content <text>\n Replace handoff content; deletes file when content is empty\n append --level <l> [--number N] [--task T] --content <text>\n Append to existing handoff (creates if absent)\n clear --level <l> [--number N] [--task T]\n Delete handoff file (idempotent; repo level removes section)\n status [--json]\n List all levels with non-empty handoff content\n\n Level flags:\n --number N Standalone task number (level=standalone)\n or checkpoint number (level=checkpoint)\n --checkpoint N Checkpoint number (level=checkpoint or task)\n --task T Task number within checkpoint (level=task)\n\n"
31821
+ );
31822
+ }
31823
+ var init_handoff = __esm({
31824
+ "src/cli/handoff.ts"() {
31825
+ "use strict";
31826
+ init_flags();
31827
+ init_git_utils();
31828
+ init_handoff_file();
31829
+ }
31830
+ });
31831
+
31359
31832
  // src/lib/migrate-branch-model.ts
31360
- import { readFile as readFile15, writeFile as writeFile12 } from "node:fs/promises";
31361
- import { join as join24 } from "node:path";
31833
+ import { readFile as readFile16, writeFile as writeFile13 } from "node:fs/promises";
31834
+ import { join as join27 } from "node:path";
31362
31835
  import { execSync as execSync3 } from "node:child_process";
31363
31836
  function assertValidBranchName(branch) {
31364
31837
  if (!/^[a-zA-Z0-9/_.-]+$/.test(branch)) {
@@ -31368,7 +31841,7 @@ function assertValidBranchName(branch) {
31368
31841
  }
31369
31842
  }
31370
31843
  async function readJsonFile3(filePath) {
31371
- const raw = await readFile15(filePath, "utf-8");
31844
+ const raw = await readFile16(filePath, "utf-8");
31372
31845
  const parsed = JSON.parse(raw);
31373
31846
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
31374
31847
  throw new Error(`${filePath} does not contain a JSON object`);
@@ -31437,12 +31910,12 @@ async function runBranchMigration(opts) {
31437
31910
  if (found) {
31438
31911
  if (found.path.endsWith("/repo.json")) {
31439
31912
  const dir = found.path.slice(0, found.path.lastIndexOf("/"));
31440
- configPath = join24(dir, "git.json");
31913
+ configPath = join27(dir, "git.json");
31441
31914
  } else {
31442
31915
  configPath = found.path;
31443
31916
  }
31444
31917
  } else {
31445
- configPath = join24(cwd, ".codebyplan", "git.json");
31918
+ configPath = join27(cwd, ".codebyplan", "git.json");
31446
31919
  }
31447
31920
  let fileRaw;
31448
31921
  let fileParsed;
@@ -31516,7 +31989,7 @@ async function runBranchMigration(opts) {
31516
31989
  const updatedParsed = { ...fileParsed, branch_config: after };
31517
31990
  const newJson = JSON.stringify(updatedParsed, null, 2) + "\n";
31518
31991
  if (newJson !== fileRaw) {
31519
- await writeFile12(configPath, newJson, "utf-8");
31992
+ await writeFile13(configPath, newJson, "utf-8");
31520
31993
  }
31521
31994
  }
31522
31995
  return {
@@ -31788,8 +32261,8 @@ var init_branch = __esm({
31788
32261
  });
31789
32262
 
31790
32263
  // src/lib/bump.ts
31791
- import { readFile as readFile16, writeFile as writeFile13, access as access5, readdir as readdir4 } from "node:fs/promises";
31792
- import { join as join25, relative as relative5, resolve as resolve3 } from "node:path";
32264
+ import { readFile as readFile17, writeFile as writeFile14, access as access5, readdir as readdir5 } from "node:fs/promises";
32265
+ import { join as join28, relative as relative5, resolve as resolve3 } from "node:path";
31793
32266
  import { spawnSync as spawnSync10 } from "node:child_process";
31794
32267
  function parsePnpmWorkspaceGlobs(raw) {
31795
32268
  const lines = raw.split("\n");
@@ -31819,18 +32292,18 @@ async function expandGlob(cwd, glob) {
31819
32292
  if (parts.length !== 2 || parts[1] !== "*") {
31820
32293
  return [];
31821
32294
  }
31822
- const parentDir = join25(cwd, parts[0]);
32295
+ const parentDir = join28(cwd, parts[0]);
31823
32296
  let dirs;
31824
32297
  try {
31825
- const entries = await readdir4(parentDir, { withFileTypes: true });
31826
- dirs = entries.filter((e) => e.isDirectory()).map((e) => join25(parentDir, e.name));
32298
+ const entries = await readdir5(parentDir, { withFileTypes: true });
32299
+ dirs = entries.filter((e) => e.isDirectory()).map((e) => join28(parentDir, e.name));
31827
32300
  } catch {
31828
32301
  return [];
31829
32302
  }
31830
32303
  const results = [];
31831
32304
  for (const dir of dirs) {
31832
32305
  try {
31833
- await access5(join25(dir, "package.json"));
32306
+ await access5(join28(dir, "package.json"));
31834
32307
  results.push(dir);
31835
32308
  } catch {
31836
32309
  }
@@ -31841,7 +32314,7 @@ async function buildPackageMap(cwd) {
31841
32314
  const map = /* @__PURE__ */ new Map();
31842
32315
  let globs = [];
31843
32316
  try {
31844
- const raw = await readFile16(join25(cwd, "pnpm-workspace.yaml"), "utf-8");
32317
+ const raw = await readFile17(join28(cwd, "pnpm-workspace.yaml"), "utf-8");
31845
32318
  globs = parsePnpmWorkspaceGlobs(raw);
31846
32319
  } catch {
31847
32320
  }
@@ -31849,7 +32322,7 @@ async function buildPackageMap(cwd) {
31849
32322
  const dirs = await expandGlob(cwd, glob);
31850
32323
  for (const dir of dirs) {
31851
32324
  try {
31852
- const pkgRaw = await readFile16(join25(dir, "package.json"), "utf-8");
32325
+ const pkgRaw = await readFile17(join28(dir, "package.json"), "utf-8");
31853
32326
  const pkg = JSON.parse(pkgRaw);
31854
32327
  const name = pkg.name ?? relative5(cwd, dir);
31855
32328
  map.set(dir, { name, dir });
@@ -31968,7 +32441,7 @@ function injectVersion(raw, nextVersion, filePath) {
31968
32441
  async function prependChangelog(changelogPath, packageName, nextVersion, now, dryRun) {
31969
32442
  let existing;
31970
32443
  try {
31971
- existing = await readFile16(changelogPath, "utf-8");
32444
+ existing = await readFile17(changelogPath, "utf-8");
31972
32445
  } catch {
31973
32446
  return false;
31974
32447
  }
@@ -31981,7 +32454,7 @@ async function prependChangelog(changelogPath, packageName, nextVersion, now, dr
31981
32454
  `;
31982
32455
  const updated = entry + existing;
31983
32456
  if (!dryRun) {
31984
- await writeFile13(changelogPath, updated, "utf-8");
32457
+ await writeFile14(changelogPath, updated, "utf-8");
31985
32458
  }
31986
32459
  return true;
31987
32460
  }
@@ -32008,7 +32481,7 @@ async function runBump(opts) {
32008
32481
  const changedFiles = (diffResult.stdout ?? "").trim().split("\n").filter(Boolean).map((f) => resolve3(cwd, f));
32009
32482
  const packageMap = await buildPackageMap(cwd);
32010
32483
  const packageDirs = Array.from(packageMap.keys());
32011
- const rootPkgPath = join25(cwd, "package.json");
32484
+ const rootPkgPath = join28(cwd, "package.json");
32012
32485
  const changedPackageDirs = /* @__PURE__ */ new Set();
32013
32486
  for (const absFile of changedFiles) {
32014
32487
  const owner = findOwningPackage(absFile, packageDirs);
@@ -32019,19 +32492,19 @@ async function runBump(opts) {
32019
32492
  const entries = [];
32020
32493
  for (const pkgDir of changedPackageDirs) {
32021
32494
  const pkgInfo = packageMap.get(pkgDir);
32022
- const pkgJsonPath = join25(pkgDir, "package.json");
32495
+ const pkgJsonPath = join28(pkgDir, "package.json");
32023
32496
  if (pkgJsonPath === rootPkgPath) continue;
32024
32497
  const versionFileCandidates = [
32025
32498
  { abs: pkgJsonPath, rel: relative5(cwd, pkgJsonPath).replace(/\\/g, "/") }
32026
32499
  ];
32027
- const tauriConfPath = join25(pkgDir, "src-tauri", "tauri.conf.json");
32500
+ const tauriConfPath = join28(pkgDir, "src-tauri", "tauri.conf.json");
32028
32501
  const tauriRelPath = relative5(cwd, tauriConfPath).replace(/\\/g, "/");
32029
32502
  try {
32030
32503
  await access5(tauriConfPath);
32031
32504
  versionFileCandidates.push({ abs: tauriConfPath, rel: tauriRelPath });
32032
32505
  } catch {
32033
32506
  }
32034
- const appJsonPath = join25(pkgDir, "app.json");
32507
+ const appJsonPath = join28(pkgDir, "app.json");
32035
32508
  const appJsonRelPath = relative5(cwd, appJsonPath).replace(/\\/g, "/");
32036
32509
  try {
32037
32510
  await access5(appJsonPath);
@@ -32040,7 +32513,7 @@ async function runBump(opts) {
32040
32513
  }
32041
32514
  let currentPkgJsonRaw;
32042
32515
  try {
32043
- currentPkgJsonRaw = await readFile16(pkgJsonPath, "utf-8");
32516
+ currentPkgJsonRaw = await readFile17(pkgJsonPath, "utf-8");
32044
32517
  } catch (err) {
32045
32518
  console.warn(
32046
32519
  `runBump: could not read ${pkgJsonPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -32085,7 +32558,7 @@ async function runBump(opts) {
32085
32558
  for (const { abs, rel } of versionFileCandidates) {
32086
32559
  let raw;
32087
32560
  try {
32088
- raw = await readFile16(abs, "utf-8");
32561
+ raw = await readFile17(abs, "utf-8");
32089
32562
  } catch {
32090
32563
  continue;
32091
32564
  }
@@ -32099,11 +32572,11 @@ async function runBump(opts) {
32099
32572
  }
32100
32573
  const updated = injectVersion(raw, nextVersion, abs);
32101
32574
  if (!dryRun) {
32102
- await writeFile13(abs, updated, "utf-8");
32575
+ await writeFile14(abs, updated, "utf-8");
32103
32576
  }
32104
32577
  updatedVersionFiles.push(rel);
32105
32578
  }
32106
- const changelogPath = join25(pkgDir, "CHANGELOG.md");
32579
+ const changelogPath = join28(pkgDir, "CHANGELOG.md");
32107
32580
  const changelogUpdated = await prependChangelog(
32108
32581
  changelogPath,
32109
32582
  pkgInfo.name,
@@ -32646,14 +33119,14 @@ var init_ship2 = __esm({
32646
33119
 
32647
33120
  // src/lib/scaffold-publish-workflow.ts
32648
33121
  import * as fs6 from "node:fs";
32649
- import * as path9 from "node:path";
33122
+ import * as path11 from "node:path";
32650
33123
  async function runScaffoldPublishWorkflow(opts) {
32651
33124
  await Promise.resolve();
32652
33125
  const dryRun = opts?.dryRun ?? false;
32653
33126
  const force = opts?.force ?? false;
32654
- const projectDir = path9.resolve(opts?.projectDir ?? process.cwd());
33127
+ const projectDir = path11.resolve(opts?.projectDir ?? process.cwd());
32655
33128
  const templatesDir = opts?.templatesDir ?? resolveTemplatesDir();
32656
- const templatePath = path9.join(
33129
+ const templatePath = path11.join(
32657
33130
  templatesDir,
32658
33131
  "github-workflows",
32659
33132
  "publish.yml"
@@ -32664,7 +33137,7 @@ async function runScaffoldPublishWorkflow(opts) {
32664
33137
  );
32665
33138
  }
32666
33139
  const templateContent = fs6.readFileSync(templatePath, "utf-8");
32667
- const targetPath = path9.join(
33140
+ const targetPath = path11.join(
32668
33141
  projectDir,
32669
33142
  ".github",
32670
33143
  "workflows",
@@ -32688,7 +33161,7 @@ async function runScaffoldPublishWorkflow(opts) {
32688
33161
  );
32689
33162
  }
32690
33163
  }
32691
- const targetDir = path9.dirname(targetPath);
33164
+ const targetDir = path11.dirname(targetPath);
32692
33165
  fs6.mkdirSync(targetDir, { recursive: true });
32693
33166
  fs6.writeFileSync(targetPath, templateContent, "utf-8");
32694
33167
  return { status: "written", path: targetPath };
@@ -32785,7 +33258,7 @@ var init_atomic_write = __esm({
32785
33258
 
32786
33259
  // src/lib/repo-reader.ts
32787
33260
  import * as fsPromises from "node:fs/promises";
32788
- import * as path10 from "node:path";
33261
+ import * as path12 from "node:path";
32789
33262
  var LocalFsReader;
32790
33263
  var init_repo_reader = __esm({
32791
33264
  "src/lib/repo-reader.ts"() {
@@ -32796,7 +33269,7 @@ var init_repo_reader = __esm({
32796
33269
  }
32797
33270
  rootDir;
32798
33271
  resolve(p) {
32799
- return path10.isAbsolute(p) ? p : path10.resolve(this.rootDir, p);
33272
+ return path12.isAbsolute(p) ? p : path12.resolve(this.rootDir, p);
32800
33273
  }
32801
33274
  async list(dir) {
32802
33275
  const abs = this.resolve(dir);
@@ -32832,7 +33305,7 @@ var init_repo_reader = __esm({
32832
33305
 
32833
33306
  // src/lib/ci-init.ts
32834
33307
  import * as fs8 from "node:fs";
32835
- import * as path11 from "node:path";
33308
+ import * as path13 from "node:path";
32836
33309
  async function tryReadJson(reader, filePath) {
32837
33310
  try {
32838
33311
  const raw = await reader.read(filePath);
@@ -32910,10 +33383,10 @@ function buildDefaultCiConfig(platforms) {
32910
33383
  return config;
32911
33384
  }
32912
33385
  async function runCiInit(opts) {
32913
- const projectDir = path11.resolve(opts?.projectDir ?? process.cwd());
33386
+ const projectDir = path13.resolve(opts?.projectDir ?? process.cwd());
32914
33387
  const dryRun = opts?.dryRun ?? false;
32915
33388
  const force = opts?.force ?? false;
32916
- const ciPath = path11.join(projectDir, ".codebyplan", "ci.json");
33389
+ const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
32917
33390
  const reader = opts?.reader ?? new LocalFsReader(projectDir);
32918
33391
  const platforms = await detectPlatforms(reader);
32919
33392
  if (dryRun) {
@@ -32959,7 +33432,7 @@ async function runCiInit(opts) {
32959
33432
  platforms: newPlatforms.length > 0 ? newPlatforms : platforms
32960
33433
  };
32961
33434
  }
32962
- const codebyplanDir = path11.join(projectDir, ".codebyplan");
33435
+ const codebyplanDir = path13.join(projectDir, ".codebyplan");
32963
33436
  fs8.mkdirSync(codebyplanDir, { recursive: true });
32964
33437
  writeJsonAtomic(ciPath, newConfig);
32965
33438
  return { status: "written", path: ciPath, platforms };
@@ -33169,7 +33642,7 @@ var init_ci_init = __esm({
33169
33642
 
33170
33643
  // src/lib/scaffold-ci-workflow.ts
33171
33644
  import * as fs9 from "node:fs";
33172
- import * as path12 from "node:path";
33645
+ import * as path14 from "node:path";
33173
33646
  function substituteTokens(template, tokens) {
33174
33647
  let result = template;
33175
33648
  for (const [token, value] of Object.entries(tokens)) {
@@ -33203,13 +33676,13 @@ async function detectStrictEnforcedFromCiJson(reader) {
33203
33676
  }
33204
33677
  }
33205
33678
  async function renderCiWorkflowContent(opts) {
33206
- const projectDir = path12.resolve(opts?.projectDir ?? process.cwd());
33679
+ const projectDir = path14.resolve(opts?.projectDir ?? process.cwd());
33207
33680
  const reader = opts?.reader ?? new LocalFsReader(projectDir);
33208
33681
  const pnpmVersion = opts?.pnpmVersion ?? await detectPnpmVersionFromPackageJson(reader);
33209
33682
  const nodeVersion = opts?.nodeVersion ?? "22";
33210
33683
  const strictEnforced = opts?.strictEnforced ?? await detectStrictEnforcedFromCiJson(reader);
33211
33684
  const templatesDir = opts?.templatesDir ?? resolveTemplatesDir();
33212
- const templatePath = path12.join(templatesDir, "github-workflows", "ci.yml");
33685
+ const templatePath = path14.join(templatesDir, "github-workflows", "ci.yml");
33213
33686
  if (!fs9.existsSync(templatePath)) {
33214
33687
  throw new Error(
33215
33688
  `scaffold-ci-workflow: template not found at ${templatePath}`
@@ -33226,9 +33699,9 @@ async function renderCiWorkflowContent(opts) {
33226
33699
  async function runScaffoldCiWorkflow(opts) {
33227
33700
  const dryRun = opts?.dryRun ?? false;
33228
33701
  const force = opts?.force ?? false;
33229
- const projectDir = path12.resolve(opts?.projectDir ?? process.cwd());
33702
+ const projectDir = path14.resolve(opts?.projectDir ?? process.cwd());
33230
33703
  const renderedContent = await renderCiWorkflowContent(opts);
33231
- const targetPath = path12.join(projectDir, ".github", "workflows", "ci.yml");
33704
+ const targetPath = path14.join(projectDir, ".github", "workflows", "ci.yml");
33232
33705
  if (dryRun) {
33233
33706
  return { status: "dry_run", path: targetPath };
33234
33707
  }
@@ -33247,7 +33720,7 @@ async function runScaffoldCiWorkflow(opts) {
33247
33720
  );
33248
33721
  }
33249
33722
  }
33250
- const targetDir = path12.dirname(targetPath);
33723
+ const targetDir = path14.dirname(targetPath);
33251
33724
  fs9.mkdirSync(targetDir, { recursive: true });
33252
33725
  const tmpPath = targetPath + ".tmp";
33253
33726
  try {
@@ -33272,10 +33745,10 @@ var init_scaffold_ci_workflow = __esm({
33272
33745
 
33273
33746
  // src/lib/gh-required-checks.ts
33274
33747
  import * as fs10 from "node:fs";
33275
- import * as path13 from "node:path";
33748
+ import * as path15 from "node:path";
33276
33749
  import { execSync as execSync5 } from "node:child_process";
33277
33750
  function readCiJson(projectDir) {
33278
- const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33751
+ const ciPath = path15.join(projectDir, ".codebyplan", "ci.json");
33279
33752
  if (!fs10.existsSync(ciPath)) {
33280
33753
  return {
33281
33754
  platforms: {},
@@ -33294,15 +33767,15 @@ function readCiJson(projectDir) {
33294
33767
  }
33295
33768
  }
33296
33769
  function writeCiJsonAtomic(projectDir, config) {
33297
- const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33770
+ const ciPath = path15.join(projectDir, ".codebyplan", "ci.json");
33298
33771
  writeJsonAtomic(ciPath, config);
33299
33772
  }
33300
33773
  function enforceRequiredCheck(opts) {
33301
- const projectDir = path13.resolve(opts?.projectDir ?? process.cwd());
33774
+ const projectDir = path15.resolve(opts?.projectDir ?? process.cwd());
33302
33775
  const branch = opts?.branch ?? "main";
33303
33776
  const checkName = opts?.checkName ?? "Lint + typecheck + test + build";
33304
33777
  const dryRun = opts?.dryRun ?? false;
33305
- const ciPath = path13.join(projectDir, ".codebyplan", "ci.json");
33778
+ const ciPath = path15.join(projectDir, ".codebyplan", "ci.json");
33306
33779
  const config = readCiJson(projectDir);
33307
33780
  if (config.workflow?.required_check_enforced === true) {
33308
33781
  return { status: "already_enforced", path: ciPath };
@@ -33709,9 +34182,9 @@ var init_ci = __esm({
33709
34182
 
33710
34183
  // src/lib/cd-init.ts
33711
34184
  import * as fs11 from "node:fs";
33712
- import * as path14 from "node:path";
34185
+ import * as path16 from "node:path";
33713
34186
  function detectSurfaces(projectDir) {
33714
- const shipmentPath = path14.join(projectDir, ".codebyplan", "shipment.json");
34187
+ const shipmentPath = path16.join(projectDir, ".codebyplan", "shipment.json");
33715
34188
  let shipment;
33716
34189
  try {
33717
34190
  shipment = JSON.parse(fs11.readFileSync(shipmentPath, "utf-8"));
@@ -33764,10 +34237,10 @@ function buildDefaultCdConfig(rawSurfaceKeys) {
33764
34237
  }
33765
34238
  async function runCdInit(opts) {
33766
34239
  await Promise.resolve();
33767
- const projectDir = path14.resolve(opts?.projectDir ?? process.cwd());
34240
+ const projectDir = path16.resolve(opts?.projectDir ?? process.cwd());
33768
34241
  const dryRun = opts?.dryRun ?? false;
33769
34242
  const force = opts?.force ?? false;
33770
- const cdPath = path14.join(projectDir, ".codebyplan", "cd.json");
34243
+ const cdPath = path16.join(projectDir, ".codebyplan", "cd.json");
33771
34244
  const rawSurfaceKeys = detectSurfaces(projectDir);
33772
34245
  const seen = /* @__PURE__ */ new Set();
33773
34246
  const surfaces = [];
@@ -33808,7 +34281,7 @@ async function runCdInit(opts) {
33808
34281
  surfaces: newSurfaces
33809
34282
  };
33810
34283
  }
33811
- const codebyplanDir = path14.join(projectDir, ".codebyplan");
34284
+ const codebyplanDir = path16.join(projectDir, ".codebyplan");
33812
34285
  fs11.mkdirSync(codebyplanDir, { recursive: true });
33813
34286
  writeJsonAtomic(cdPath, newConfig);
33814
34287
  return { status: "written", path: cdPath, surfaces };
@@ -33898,14 +34371,14 @@ var init_cd_init = __esm({
33898
34371
 
33899
34372
  // src/lib/scaffold-cd-workflow.ts
33900
34373
  import * as fs12 from "node:fs";
33901
- import * as path15 from "node:path";
34374
+ import * as path17 from "node:path";
33902
34375
  async function scaffoldOneWorkflow(templateName, targetName, opts) {
33903
34376
  await Promise.resolve();
33904
34377
  const dryRun = opts.dryRun ?? false;
33905
34378
  const force = opts.force ?? false;
33906
- const projectDir = path15.resolve(opts.projectDir ?? process.cwd());
34379
+ const projectDir = path17.resolve(opts.projectDir ?? process.cwd());
33907
34380
  const templatesDir = opts.templatesDir ?? resolveTemplatesDir();
33908
- const templatePath = path15.join(
34381
+ const templatePath = path17.join(
33909
34382
  templatesDir,
33910
34383
  "github-workflows",
33911
34384
  templateName
@@ -33916,7 +34389,7 @@ async function scaffoldOneWorkflow(templateName, targetName, opts) {
33916
34389
  );
33917
34390
  }
33918
34391
  const templateContent = fs12.readFileSync(templatePath, "utf-8");
33919
- const targetPath = path15.join(projectDir, ".github", "workflows", targetName);
34392
+ const targetPath = path17.join(projectDir, ".github", "workflows", targetName);
33920
34393
  if (dryRun) {
33921
34394
  return { status: "dry_run", path: targetPath };
33922
34395
  }
@@ -33935,7 +34408,7 @@ async function scaffoldOneWorkflow(templateName, targetName, opts) {
33935
34408
  );
33936
34409
  }
33937
34410
  }
33938
- const targetDir = path15.dirname(targetPath);
34411
+ const targetDir = path17.dirname(targetPath);
33939
34412
  fs12.mkdirSync(targetDir, { recursive: true });
33940
34413
  const tmpPath = targetPath + ".tmp";
33941
34414
  try {
@@ -34461,7 +34934,7 @@ __export(version_status_exports, {
34461
34934
  });
34462
34935
  import { execFileSync, execSync as execSync6 } from "node:child_process";
34463
34936
  import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
34464
- import { dirname as dirname11, join as join32 } from "node:path";
34937
+ import { dirname as dirname12, join as join35 } from "node:path";
34465
34938
  function fetchLatestVersion() {
34466
34939
  try {
34467
34940
  return execFileSync("npm", ["view", "codebyplan", "version"], {
@@ -34485,11 +34958,11 @@ function detectPackageManager2(gitRoot) {
34485
34958
  let dir = process.cwd();
34486
34959
  const stopAt = gitRoot ?? null;
34487
34960
  while (true) {
34488
- if (existsSync10(join32(dir, "pnpm-lock.yaml"))) return "pnpm";
34489
- if (existsSync10(join32(dir, "yarn.lock"))) return "yarn";
34490
- if (existsSync10(join32(dir, "package-lock.json"))) return "npm";
34961
+ if (existsSync10(join35(dir, "pnpm-lock.yaml"))) return "pnpm";
34962
+ if (existsSync10(join35(dir, "yarn.lock"))) return "yarn";
34963
+ if (existsSync10(join35(dir, "package-lock.json"))) return "npm";
34491
34964
  if (stopAt !== null && dir === stopAt) break;
34492
- const parent = dirname11(dir);
34965
+ const parent = dirname12(dir);
34493
34966
  if (parent === dir) break;
34494
34967
  dir = parent;
34495
34968
  }
@@ -34507,7 +34980,7 @@ function buildInstallCommand2(pm) {
34507
34980
  }
34508
34981
  async function resolveGuard(gitRoot, currentBranch) {
34509
34982
  if (gitRoot !== null) {
34510
- const canonicalPkgPath = join32(
34983
+ const canonicalPkgPath = join35(
34511
34984
  gitRoot,
34512
34985
  "packages",
34513
34986
  "codebyplan-package",
@@ -34531,10 +35004,10 @@ async function resolveGuard(gitRoot, currentBranch) {
34531
35004
  let gitJsonPath;
34532
35005
  if (found.path.endsWith("/repo.json")) {
34533
35006
  const dir = found.path.slice(0, found.path.lastIndexOf("/"));
34534
- gitJsonPath = join32(dir, "git.json");
35007
+ gitJsonPath = join35(dir, "git.json");
34535
35008
  } else {
34536
35009
  const legacyDir = found.path.slice(0, found.path.lastIndexOf("/"));
34537
- gitJsonPath = join32(legacyDir, ".codebyplan", "git.json");
35010
+ gitJsonPath = join35(legacyDir, ".codebyplan", "git.json");
34538
35011
  }
34539
35012
  const raw = readFileSync11(gitJsonPath, "utf-8");
34540
35013
  const parsed = JSON.parse(raw);
@@ -34618,8 +35091,8 @@ var upload_e2e_images_exports = {};
34618
35091
  __export(upload_e2e_images_exports, {
34619
35092
  runUploadE2eImagesCommand: () => runUploadE2eImagesCommand
34620
35093
  });
34621
- import { readFile as readFile18 } from "node:fs/promises";
34622
- import { join as join33, basename as basename2, resolve as resolve11 } from "node:path";
35094
+ import { readFile as readFile19 } from "node:fs/promises";
35095
+ import { join as join36, basename as basename3, resolve as resolve11 } from "node:path";
34623
35096
  import { execSync as execSync7 } from "node:child_process";
34624
35097
  function baseUrl2() {
34625
35098
  return (process.env.CODEBYPLAN_API_URL ?? "https://www.codebyplan.com").replace(/\/$/, "");
@@ -34653,8 +35126,8 @@ function parseArgs(args) {
34653
35126
  }
34654
35127
  async function readE2eConfig(projectPath) {
34655
35128
  try {
34656
- const raw = await readFile18(
34657
- join33(projectPath, ".codebyplan", "e2e.json"),
35129
+ const raw = await readFile19(
35130
+ join36(projectPath, ".codebyplan", "e2e.json"),
34658
35131
  "utf-8"
34659
35132
  );
34660
35133
  return JSON.parse(raw);
@@ -34695,8 +35168,8 @@ function collectPngsFromGitDiff(projectPath, frameworkName, frameworkConfig, bas
34695
35168
  continue;
34696
35169
  const isNew = status === "A";
34697
35170
  results.push({
34698
- absolutePath: join33(projectPath, filePath),
34699
- filename: basename2(filePath),
35171
+ absolutePath: join36(projectPath, filePath),
35172
+ filename: basename3(filePath),
34700
35173
  framework: frameworkName,
34701
35174
  is_new: isNew
34702
35175
  });
@@ -34711,11 +35184,11 @@ function deriveTestName(absolutePath) {
34711
35184
  return seg.replace(".spec.ts-snapshots", "");
34712
35185
  }
34713
35186
  }
34714
- return basename2(absolutePath, ".png");
35187
+ return basename3(absolutePath, ".png");
34715
35188
  }
34716
35189
  function buildManifestItem(png) {
34717
35190
  const testName = deriveTestName(png.absolutePath);
34718
- const pageOrScreen = basename2(png.absolutePath, ".png");
35191
+ const pageOrScreen = basename3(png.absolutePath, ".png");
34719
35192
  return {
34720
35193
  filename: png.filename,
34721
35194
  test_name: testName,
@@ -34792,7 +35265,7 @@ async function runUploadE2eImagesCommand(args) {
34792
35265
  for (const png of allPngs) {
34793
35266
  let bytes;
34794
35267
  try {
34795
- bytes = await readFile18(png.absolutePath);
35268
+ bytes = await readFile19(png.absolutePath);
34796
35269
  } catch {
34797
35270
  process.stderr.write(
34798
35271
  `upload-e2e-images: could not read file: ${png.absolutePath}
@@ -34869,9 +35342,9 @@ __export(arch_map_exports, {
34869
35342
  runArchMapCommand: () => runArchMapCommand,
34870
35343
  updateFrontmatterFields: () => updateFrontmatterFields
34871
35344
  });
34872
- import { readFile as readFile19, writeFile as writeFile14 } from "node:fs/promises";
35345
+ import { readFile as readFile20, writeFile as writeFile15 } from "node:fs/promises";
34873
35346
  import { existsSync as existsSync11, readdirSync as readdirSync3 } from "node:fs";
34874
- import { join as join34 } from "node:path";
35347
+ import { join as join37 } from "node:path";
34875
35348
  import { spawnSync as spawnSync12 } from "node:child_process";
34876
35349
  function normalizeModulePath(modulePath) {
34877
35350
  return modulePath.replace(/\/+$/, "");
@@ -34896,9 +35369,9 @@ async function resolveCodebyplanDir(startDir) {
34896
35369
  }
34897
35370
  }
34898
35371
  async function readArchitectureConfig(codebyplanDir) {
34899
- const filePath = join34(codebyplanDir, "architecture.json");
35372
+ const filePath = join37(codebyplanDir, "architecture.json");
34900
35373
  try {
34901
- const raw = await readFile19(filePath, "utf-8");
35374
+ const raw = await readFile20(filePath, "utf-8");
34902
35375
  const parsed = JSON.parse(raw);
34903
35376
  if (typeof parsed !== "object" || parsed === null || !Array.isArray(parsed.modules)) {
34904
35377
  return { version: 1, modules: [] };
@@ -34909,8 +35382,8 @@ async function readArchitectureConfig(codebyplanDir) {
34909
35382
  }
34910
35383
  }
34911
35384
  async function writeArchitectureConfig(codebyplanDir, config) {
34912
- const filePath = join34(codebyplanDir, "architecture.json");
34913
- await writeFile14(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
35385
+ const filePath = join37(codebyplanDir, "architecture.json");
35386
+ await writeFile15(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
34914
35387
  }
34915
35388
  function resolveGitSha(modulePath, cwd) {
34916
35389
  try {
@@ -34928,10 +35401,10 @@ function resolveGitSha(modulePath, cwd) {
34928
35401
  }
34929
35402
  async function discoverModulePaths(projectRoot) {
34930
35403
  const paths = [];
34931
- const workspacePath = join34(projectRoot, "pnpm-workspace.yaml");
35404
+ const workspacePath = join37(projectRoot, "pnpm-workspace.yaml");
34932
35405
  let patterns = [];
34933
35406
  try {
34934
- const raw = await readFile19(workspacePath, "utf-8");
35407
+ const raw = await readFile20(workspacePath, "utf-8");
34935
35408
  const lines = raw.split("\n");
34936
35409
  let inPackages = false;
34937
35410
  for (const line of lines) {
@@ -34955,7 +35428,7 @@ async function discoverModulePaths(projectRoot) {
34955
35428
  for (const pattern of patterns) {
34956
35429
  if (pattern.endsWith("/*")) {
34957
35430
  const dir = pattern.slice(0, -2);
34958
- const absDir = join34(projectRoot, dir);
35431
+ const absDir = join37(projectRoot, dir);
34959
35432
  try {
34960
35433
  if (existsSync11(absDir)) {
34961
35434
  const entries = readdirSync3(absDir, { withFileTypes: true });
@@ -34968,7 +35441,7 @@ async function discoverModulePaths(projectRoot) {
34968
35441
  } catch {
34969
35442
  }
34970
35443
  } else if (!pattern.includes("*")) {
34971
- const absPath = join34(projectRoot, pattern);
35444
+ const absPath = join37(projectRoot, pattern);
34972
35445
  if (existsSync11(absPath)) {
34973
35446
  paths.push(pattern);
34974
35447
  }
@@ -34976,7 +35449,7 @@ async function discoverModulePaths(projectRoot) {
34976
35449
  }
34977
35450
  const crossCutting = ["supabase", ".github", "scripts"];
34978
35451
  for (const dir of crossCutting) {
34979
- const absPath = join34(projectRoot, dir);
35452
+ const absPath = join37(projectRoot, dir);
34980
35453
  try {
34981
35454
  if (existsSync11(absPath)) {
34982
35455
  paths.push(dir);
@@ -35162,10 +35635,10 @@ async function runStamp(modulePath, sha, depthArg, projectRoot) {
35162
35635
  }
35163
35636
  await writeArchitectureConfig(codebyplanDir, config);
35164
35637
  const stampedEntry = existingIndex >= 0 ? config.modules[existingIndex] : config.modules[config.modules.length - 1];
35165
- const mapAbsPath = join34(repoRoot, stampedEntry.map_file);
35638
+ const mapAbsPath = join37(repoRoot, stampedEntry.map_file);
35166
35639
  let mapContent = null;
35167
35640
  try {
35168
- mapContent = await readFile19(mapAbsPath, "utf-8");
35641
+ mapContent = await readFile20(mapAbsPath, "utf-8");
35169
35642
  } catch {
35170
35643
  console.warn(
35171
35644
  " Warning: map file " + stampedEntry.map_file + " not found \u2014 stamped manifest only"
@@ -35187,7 +35660,7 @@ async function runStamp(modulePath, sha, depthArg, projectRoot) {
35187
35660
  );
35188
35661
  } else {
35189
35662
  try {
35190
- await writeFile14(mapAbsPath, updated, "utf-8");
35663
+ await writeFile15(mapAbsPath, updated, "utf-8");
35191
35664
  } catch (writeErr) {
35192
35665
  console.warn(
35193
35666
  " Warning: could not write map file " + stampedEntry.map_file + " \u2014 " + (writeErr instanceof Error ? writeErr.message : String(writeErr)) + " \u2014 stamped manifest only"
@@ -35340,19 +35813,19 @@ var init_branch_port_resolver = __esm({
35340
35813
  });
35341
35814
 
35342
35815
  // src/lib/migrate-local-config.ts
35343
- import { mkdir as mkdir7, readFile as readFile20, unlink as unlink5, writeFile as writeFile15 } from "node:fs/promises";
35344
- import { join as join35 } from "node:path";
35816
+ import { mkdir as mkdir8, readFile as readFile21, unlink as unlink6, writeFile as writeFile16 } from "node:fs/promises";
35817
+ import { join as join38 } from "node:path";
35345
35818
  function legacySharedPath(projectPath) {
35346
- return join35(projectPath, ".codebyplan.json");
35819
+ return join38(projectPath, ".codebyplan.json");
35347
35820
  }
35348
35821
  function legacyLocalPath(projectPath) {
35349
- return join35(projectPath, ".codebyplan.local.json");
35822
+ return join38(projectPath, ".codebyplan.local.json");
35350
35823
  }
35351
35824
  function newDirPath(projectPath) {
35352
- return join35(projectPath, ".codebyplan");
35825
+ return join38(projectPath, ".codebyplan");
35353
35826
  }
35354
35827
  function sentinelPath(projectPath) {
35355
- return join35(projectPath, ".codebyplan", "repo.json");
35828
+ return join38(projectPath, ".codebyplan", "repo.json");
35356
35829
  }
35357
35830
  async function statSafe(p) {
35358
35831
  const { stat: stat2 } = await import("node:fs/promises");
@@ -35391,7 +35864,7 @@ async function runLocalMigration(projectPath) {
35391
35864
  }
35392
35865
  let legacyRaw;
35393
35866
  try {
35394
- legacyRaw = await readFile20(legacySharedPath(projectPath), "utf-8");
35867
+ legacyRaw = await readFile21(legacySharedPath(projectPath), "utf-8");
35395
35868
  } catch {
35396
35869
  return {
35397
35870
  migrated: true,
@@ -35416,7 +35889,7 @@ async function runLocalMigration(projectPath) {
35416
35889
  }
35417
35890
  const cfg = parsed;
35418
35891
  try {
35419
- await mkdir7(newDirPath(projectPath), { recursive: true });
35892
+ await mkdir8(newDirPath(projectPath), { recursive: true });
35420
35893
  } catch (err) {
35421
35894
  const code = err.code;
35422
35895
  if (code === "ENOTDIR" || code === "EEXIST") {
@@ -35431,8 +35904,8 @@ async function runLocalMigration(projectPath) {
35431
35904
  if ("repo_id" in cfg) repoJson.repo_id = cfg.repo_id;
35432
35905
  if ("organization_id" in cfg) repoJson.organization_id = cfg.organization_id;
35433
35906
  if ("project_id" in cfg) repoJson.project_id = cfg.project_id;
35434
- await writeFile15(
35435
- join35(projectPath, ".codebyplan", "repo.json"),
35907
+ await writeFile16(
35908
+ join38(projectPath, ".codebyplan", "repo.json"),
35436
35909
  JSON.stringify(repoJson, null, 2) + "\n",
35437
35910
  "utf-8"
35438
35911
  );
@@ -35444,8 +35917,8 @@ async function runLocalMigration(projectPath) {
35444
35917
  serverJson.auto_push_enabled = cfg.auto_push_enabled;
35445
35918
  if ("port_allocations" in cfg)
35446
35919
  serverJson.port_allocations = cfg.port_allocations;
35447
- await writeFile15(
35448
- join35(projectPath, ".codebyplan", "server.json"),
35920
+ await writeFile16(
35921
+ join38(projectPath, ".codebyplan", "server.json"),
35449
35922
  JSON.stringify(serverJson, null, 2) + "\n",
35450
35923
  "utf-8"
35451
35924
  );
@@ -35453,37 +35926,37 @@ async function runLocalMigration(projectPath) {
35453
35926
  const gitJson = {};
35454
35927
  if ("git_branch" in cfg) gitJson.git_branch = cfg.git_branch;
35455
35928
  if ("branch_config" in cfg) gitJson.branch_config = cfg.branch_config;
35456
- await writeFile15(
35457
- join35(projectPath, ".codebyplan", "git.json"),
35929
+ await writeFile16(
35930
+ join38(projectPath, ".codebyplan", "git.json"),
35458
35931
  JSON.stringify(gitJson, null, 2) + "\n",
35459
35932
  "utf-8"
35460
35933
  );
35461
35934
  filesChanged.push(".codebyplan/git.json");
35462
35935
  const shipmentJson = {};
35463
35936
  if ("shipment" in cfg) shipmentJson.shipment = cfg.shipment;
35464
- await writeFile15(
35465
- join35(projectPath, ".codebyplan", "shipment.json"),
35937
+ await writeFile16(
35938
+ join38(projectPath, ".codebyplan", "shipment.json"),
35466
35939
  JSON.stringify(shipmentJson, null, 2) + "\n",
35467
35940
  "utf-8"
35468
35941
  );
35469
35942
  filesChanged.push(".codebyplan/shipment.json");
35470
35943
  const vendorJson = {};
35471
- await writeFile15(
35472
- join35(projectPath, ".codebyplan", "vendor.json"),
35944
+ await writeFile16(
35945
+ join38(projectPath, ".codebyplan", "vendor.json"),
35473
35946
  JSON.stringify(vendorJson, null, 2) + "\n",
35474
35947
  "utf-8"
35475
35948
  );
35476
35949
  filesChanged.push(".codebyplan/vendor.json");
35477
35950
  const e2eJson = {};
35478
- await writeFile15(
35479
- join35(projectPath, ".codebyplan", "e2e.json"),
35951
+ await writeFile16(
35952
+ join38(projectPath, ".codebyplan", "e2e.json"),
35480
35953
  JSON.stringify(e2eJson, null, 2) + "\n",
35481
35954
  "utf-8"
35482
35955
  );
35483
35956
  filesChanged.push(".codebyplan/e2e.json");
35484
35957
  const eslintJson = {};
35485
- await writeFile15(
35486
- join35(projectPath, ".codebyplan", "eslint.json"),
35958
+ await writeFile16(
35959
+ join38(projectPath, ".codebyplan", "eslint.json"),
35487
35960
  JSON.stringify(eslintJson, null, 2) + "\n",
35488
35961
  "utf-8"
35489
35962
  );
@@ -35494,9 +35967,9 @@ async function runLocalMigration(projectPath) {
35494
35967
  "Migration write incomplete: .codebyplan/repo.json was not persisted. Re-run migration to retry from a clean state."
35495
35968
  );
35496
35969
  }
35497
- const gitignorePath = join35(projectPath, ".gitignore");
35970
+ const gitignorePath = join38(projectPath, ".gitignore");
35498
35971
  try {
35499
- const gitignoreContent = await readFile20(gitignorePath, "utf-8");
35972
+ const gitignoreContent = await readFile21(gitignorePath, "utf-8");
35500
35973
  const legacyLine = ".codebyplan.local.json";
35501
35974
  const newLine = ".codebyplan/device.local.json";
35502
35975
  const hasLegacy = gitignoreContent.split("\n").some((l) => l.trimEnd() === legacyLine);
@@ -35515,18 +35988,18 @@ async function runLocalMigration(projectPath) {
35515
35988
  updated = gitignoreContent;
35516
35989
  }
35517
35990
  if (updated !== gitignoreContent) {
35518
- await writeFile15(gitignorePath, updated, "utf-8");
35991
+ await writeFile16(gitignorePath, updated, "utf-8");
35519
35992
  filesChanged.push(".gitignore");
35520
35993
  }
35521
35994
  } catch {
35522
35995
  }
35523
35996
  try {
35524
- await unlink5(legacySharedPath(projectPath));
35997
+ await unlink6(legacySharedPath(projectPath));
35525
35998
  filesChanged.push(".codebyplan.json (deleted)");
35526
35999
  } catch {
35527
36000
  }
35528
36001
  try {
35529
- await unlink5(legacyLocalPath(projectPath));
36002
+ await unlink6(legacyLocalPath(projectPath));
35530
36003
  filesChanged.push(".codebyplan.local.json (deleted)");
35531
36004
  } catch {
35532
36005
  }
@@ -35556,8 +36029,8 @@ __export(config_exports, {
35556
36029
  runConfig: () => runConfig,
35557
36030
  runConfigMigrate: () => runConfigMigrate
35558
36031
  });
35559
- import { mkdir as mkdir8, readFile as readFile21, writeFile as writeFile16 } from "node:fs/promises";
35560
- import { join as join36 } from "node:path";
36032
+ import { mkdir as mkdir9, readFile as readFile22, writeFile as writeFile17 } from "node:fs/promises";
36033
+ import { join as join39 } from "node:path";
35561
36034
  async function runConfig() {
35562
36035
  const flags = parseFlags(3);
35563
36036
  const dryRun = hasFlag("dry-run", 3);
@@ -35590,7 +36063,7 @@ async function runConfig() {
35590
36063
  console.log("\n Config complete.\n");
35591
36064
  }
35592
36065
  async function syncConfigToFile(repoId, projectPath, dryRun) {
35593
- const codebyplanDir = join36(projectPath, ".codebyplan");
36066
+ const codebyplanDir = join39(projectPath, ".codebyplan");
35594
36067
  const {
35595
36068
  currentBranch,
35596
36069
  portAllocations,
@@ -35666,7 +36139,7 @@ async function syncConfigToFile(repoId, projectPath, dryRun) {
35666
36139
  console.log(" Config would be updated (dry-run).");
35667
36140
  return;
35668
36141
  }
35669
- await mkdir8(codebyplanDir, { recursive: true });
36142
+ await mkdir9(codebyplanDir, { recursive: true });
35670
36143
  const files = [
35671
36144
  { name: "repo.json", payload: repoPayload },
35672
36145
  { name: "server.json", payload: serverPayload },
@@ -35683,16 +36156,16 @@ async function syncConfigToFile(repoId, projectPath, dryRun) {
35683
36156
  ];
35684
36157
  let anyUpdated = false;
35685
36158
  for (const { name, payload, createOnly } of files) {
35686
- const filePath = join36(codebyplanDir, name);
36159
+ const filePath = join39(codebyplanDir, name);
35687
36160
  const newJson = JSON.stringify(payload, null, 2) + "\n";
35688
36161
  let currentJson = "";
35689
36162
  try {
35690
- currentJson = await readFile21(filePath, "utf-8");
36163
+ currentJson = await readFile22(filePath, "utf-8");
35691
36164
  } catch {
35692
36165
  }
35693
36166
  if (createOnly && currentJson !== "") continue;
35694
36167
  if (currentJson === newJson) continue;
35695
- await writeFile16(filePath, newJson, "utf-8");
36168
+ await writeFile17(filePath, newJson, "utf-8");
35696
36169
  console.log(` Updated .codebyplan/${name}`);
35697
36170
  anyUpdated = true;
35698
36171
  }
@@ -35702,8 +36175,8 @@ async function syncConfigToFile(repoId, projectPath, dryRun) {
35702
36175
  }
35703
36176
  async function readRepoConfig(projectPath) {
35704
36177
  try {
35705
- const raw = await readFile21(
35706
- join36(projectPath, ".codebyplan", "repo.json"),
36178
+ const raw = await readFile22(
36179
+ join39(projectPath, ".codebyplan", "repo.json"),
35707
36180
  "utf-8"
35708
36181
  );
35709
36182
  return JSON.parse(raw);
@@ -35713,8 +36186,8 @@ async function readRepoConfig(projectPath) {
35713
36186
  }
35714
36187
  async function readServerConfig(projectPath) {
35715
36188
  try {
35716
- const raw = await readFile21(
35717
- join36(projectPath, ".codebyplan", "server.json"),
36189
+ const raw = await readFile22(
36190
+ join39(projectPath, ".codebyplan", "server.json"),
35718
36191
  "utf-8"
35719
36192
  );
35720
36193
  return JSON.parse(raw);
@@ -35724,8 +36197,8 @@ async function readServerConfig(projectPath) {
35724
36197
  }
35725
36198
  async function readGitConfig2(projectPath) {
35726
36199
  try {
35727
- const raw = await readFile21(
35728
- join36(projectPath, ".codebyplan", "git.json"),
36200
+ const raw = await readFile22(
36201
+ join39(projectPath, ".codebyplan", "git.json"),
35729
36202
  "utf-8"
35730
36203
  );
35731
36204
  return JSON.parse(raw);
@@ -35735,8 +36208,8 @@ async function readGitConfig2(projectPath) {
35735
36208
  }
35736
36209
  async function readShipmentConfig2(projectPath) {
35737
36210
  try {
35738
- const raw = await readFile21(
35739
- join36(projectPath, ".codebyplan", "shipment.json"),
36211
+ const raw = await readFile22(
36212
+ join39(projectPath, ".codebyplan", "shipment.json"),
35740
36213
  "utf-8"
35741
36214
  );
35742
36215
  return JSON.parse(raw);
@@ -35746,8 +36219,8 @@ async function readShipmentConfig2(projectPath) {
35746
36219
  }
35747
36220
  async function readVendorConfig(projectPath) {
35748
36221
  try {
35749
- const raw = await readFile21(
35750
- join36(projectPath, ".codebyplan", "vendor.json"),
36222
+ const raw = await readFile22(
36223
+ join39(projectPath, ".codebyplan", "vendor.json"),
35751
36224
  "utf-8"
35752
36225
  );
35753
36226
  return JSON.parse(raw);
@@ -35757,8 +36230,8 @@ async function readVendorConfig(projectPath) {
35757
36230
  }
35758
36231
  async function readE2eConfig2(projectPath) {
35759
36232
  try {
35760
- const raw = await readFile21(
35761
- join36(projectPath, ".codebyplan", "e2e.json"),
36233
+ const raw = await readFile22(
36234
+ join39(projectPath, ".codebyplan", "e2e.json"),
35762
36235
  "utf-8"
35763
36236
  );
35764
36237
  return JSON.parse(raw);
@@ -35768,8 +36241,8 @@ async function readE2eConfig2(projectPath) {
35768
36241
  }
35769
36242
  async function readServerLocalConfig(projectPath) {
35770
36243
  try {
35771
- const raw = await readFile21(
35772
- join36(projectPath, ".codebyplan", "server.local.json"),
36244
+ const raw = await readFile22(
36245
+ join39(projectPath, ".codebyplan", "server.local.json"),
35773
36246
  "utf-8"
35774
36247
  );
35775
36248
  return JSON.parse(raw);
@@ -35841,8 +36314,8 @@ var init_config = __esm({
35841
36314
  });
35842
36315
 
35843
36316
  // src/lib/server-detect.ts
35844
- import { readFile as readFile22, readdir as readdir6, access as access7 } from "node:fs/promises";
35845
- import { join as join37 } from "node:path";
36317
+ import { readFile as readFile23, readdir as readdir7, access as access7 } from "node:fs/promises";
36318
+ import { join as join40 } from "node:path";
35846
36319
  async function fileExists4(filePath) {
35847
36320
  try {
35848
36321
  await access7(filePath);
@@ -35853,8 +36326,8 @@ async function fileExists4(filePath) {
35853
36326
  }
35854
36327
  function detectPackageManager3(dir) {
35855
36328
  return (async () => {
35856
- if (await fileExists4(join37(dir, "pnpm-lock.yaml"))) return "pnpm";
35857
- if (await fileExists4(join37(dir, "yarn.lock"))) return "yarn";
36329
+ if (await fileExists4(join40(dir, "pnpm-lock.yaml"))) return "pnpm";
36330
+ if (await fileExists4(join40(dir, "yarn.lock"))) return "yarn";
35858
36331
  return "npm";
35859
36332
  })();
35860
36333
  }
@@ -35886,12 +36359,12 @@ function detectPortFromScripts(pkg) {
35886
36359
  return null;
35887
36360
  }
35888
36361
  async function isMonorepo(dir) {
35889
- return await fileExists4(join37(dir, "turbo.json")) || await fileExists4(join37(dir, "pnpm-workspace.yaml"));
36362
+ return await fileExists4(join40(dir, "turbo.json")) || await fileExists4(join40(dir, "pnpm-workspace.yaml"));
35890
36363
  }
35891
36364
  async function detectServers(projectPath) {
35892
36365
  let pkg;
35893
36366
  try {
35894
- const raw = await readFile22(join37(projectPath, "package.json"), "utf-8");
36367
+ const raw = await readFile23(join40(projectPath, "package.json"), "utf-8");
35895
36368
  pkg = JSON.parse(raw);
35896
36369
  } catch {
35897
36370
  return {
@@ -35907,15 +36380,15 @@ async function detectServers(projectPath) {
35907
36380
  const mono = await isMonorepo(projectPath);
35908
36381
  const servers = [];
35909
36382
  if (mono) {
35910
- const appsDir = join37(projectPath, "apps");
36383
+ const appsDir = join40(projectPath, "apps");
35911
36384
  try {
35912
- const entries = await readdir6(appsDir, { withFileTypes: true });
36385
+ const entries = await readdir7(appsDir, { withFileTypes: true });
35913
36386
  const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
35914
36387
  for (const entry of sorted) {
35915
36388
  if (!entry.isDirectory()) continue;
35916
- const appPkgPath = join37(appsDir, entry.name, "package.json");
36389
+ const appPkgPath = join40(appsDir, entry.name, "package.json");
35917
36390
  try {
35918
- const appRaw = await readFile22(appPkgPath, "utf-8");
36391
+ const appRaw = await readFile23(appPkgPath, "utf-8");
35919
36392
  const appPkg = JSON.parse(appRaw);
35920
36393
  const appName = entry.name;
35921
36394
  const framework = detectFramework(appPkg);
@@ -35958,14 +36431,14 @@ var init_server_detect = __esm({
35958
36431
  });
35959
36432
 
35960
36433
  // src/lib/port-verify.ts
35961
- import { readFile as readFile23 } from "node:fs/promises";
36434
+ import { readFile as readFile24 } from "node:fs/promises";
35962
36435
  async function verifyPorts(projectPath, portAllocations) {
35963
36436
  const mismatches = [];
35964
36437
  const allocatedPorts = new Set(portAllocations.map((a) => a.port));
35965
36438
  const packageJsonPaths = await findPackageJsonFiles(projectPath, projectPath);
35966
36439
  for (const pkgPath of packageJsonPaths) {
35967
36440
  try {
35968
- const raw = await readFile23(pkgPath, "utf-8");
36441
+ const raw = await readFile24(pkgPath, "utf-8");
35969
36442
  const pkg = JSON.parse(raw);
35970
36443
  const scriptPort = detectPortFromScripts(pkg);
35971
36444
  if (scriptPort !== null && !allocatedPorts.has(scriptPort)) {
@@ -36028,7 +36501,7 @@ async function findUnallocatedApps(projectPath, portAllocations) {
36028
36501
  }
36029
36502
  let pkg;
36030
36503
  try {
36031
- const raw = await readFile23(`${app.absPath}/package.json`, "utf-8");
36504
+ const raw = await readFile24(`${app.absPath}/package.json`, "utf-8");
36032
36505
  pkg = JSON.parse(raw);
36033
36506
  } catch {
36034
36507
  continue;
@@ -36078,8 +36551,8 @@ __export(ports_exports, {
36078
36551
  parseEnvFile: () => parseEnvFile,
36079
36552
  runPorts: () => runPorts
36080
36553
  });
36081
- import { mkdir as mkdir9, readFile as readFile24, writeFile as writeFile17 } from "node:fs/promises";
36082
- import { join as join38 } from "node:path";
36554
+ import { mkdir as mkdir10, readFile as readFile25, writeFile as writeFile18 } from "node:fs/promises";
36555
+ import { join as join41 } from "node:path";
36083
36556
  function printDetectionResult(result, projectPath) {
36084
36557
  console.log(`
36085
36558
  CodeByPlan Ports - List`);
@@ -36236,12 +36709,12 @@ async function writeServerLocalConfig(repoId, projectPath, dryRun) {
36236
36709
  // which matches ServerLocalConfig.port_allocations — honest end-to-end.
36237
36710
  port_allocations: portAllocations
36238
36711
  };
36239
- const codebyplanDir = join38(projectPath, ".codebyplan");
36240
- const filePath = join38(codebyplanDir, "server.local.json");
36712
+ const codebyplanDir = join41(projectPath, ".codebyplan");
36713
+ const filePath = join41(codebyplanDir, "server.local.json");
36241
36714
  const newJson = JSON.stringify(payload, null, 2) + "\n";
36242
36715
  let currentJson = "";
36243
36716
  try {
36244
- currentJson = await readFile24(filePath, "utf-8");
36717
+ currentJson = await readFile25(filePath, "utf-8");
36245
36718
  } catch {
36246
36719
  }
36247
36720
  if (currentJson === newJson) {
@@ -36252,18 +36725,18 @@ async function writeServerLocalConfig(repoId, projectPath, dryRun) {
36252
36725
  console.log(" Would update .codebyplan/server.local.json (dry-run).");
36253
36726
  return;
36254
36727
  }
36255
- await mkdir9(codebyplanDir, { recursive: true });
36256
- await writeFile17(filePath, newJson, "utf-8");
36728
+ await mkdir10(codebyplanDir, { recursive: true });
36729
+ await writeFile18(filePath, newJson, "utf-8");
36257
36730
  console.log(
36258
36731
  ` Updated .codebyplan/server.local.json (branch '${currentBranch}', ${portAllocations.length} allocation${portAllocations.length === 1 ? "" : "s"}).`
36259
36732
  );
36260
36733
  }
36261
36734
  async function provisionE2eEnv(projectPath, dryRun) {
36262
- const relSource = join38("apps", "web", ".env.local");
36263
- const sourcePath = join38(projectPath, relSource);
36735
+ const relSource = join41("apps", "web", ".env.local");
36736
+ const sourcePath = join41(projectPath, relSource);
36264
36737
  let sourceRaw;
36265
36738
  try {
36266
- sourceRaw = await readFile24(sourcePath, "utf-8");
36739
+ sourceRaw = await readFile25(sourcePath, "utf-8");
36267
36740
  } catch {
36268
36741
  console.warn(
36269
36742
  ` Skipped .codebyplan/e2e.env \u2014 source ${relSource} not found.`
@@ -36292,12 +36765,12 @@ async function provisionE2eEnv(projectPath, dryRun) {
36292
36765
  );
36293
36766
  return;
36294
36767
  }
36295
- const codebyplanDir = join38(projectPath, ".codebyplan");
36296
- const filePath = join38(codebyplanDir, "e2e.env");
36768
+ const codebyplanDir = join41(projectPath, ".codebyplan");
36769
+ const filePath = join41(codebyplanDir, "e2e.env");
36297
36770
  const newContent = lines.join("\n") + "\n";
36298
36771
  let currentContent = "";
36299
36772
  try {
36300
- currentContent = await readFile24(filePath, "utf-8");
36773
+ currentContent = await readFile25(filePath, "utf-8");
36301
36774
  } catch {
36302
36775
  }
36303
36776
  if (currentContent === newContent) {
@@ -36308,8 +36781,8 @@ async function provisionE2eEnv(projectPath, dryRun) {
36308
36781
  console.log(" Would provision .codebyplan/e2e.env (dry-run).");
36309
36782
  return;
36310
36783
  }
36311
- await mkdir9(codebyplanDir, { recursive: true });
36312
- await writeFile17(filePath, newContent, "utf-8");
36784
+ await mkdir10(codebyplanDir, { recursive: true });
36785
+ await writeFile18(filePath, newContent, "utf-8");
36313
36786
  console.log(
36314
36787
  ` Provisioned .codebyplan/e2e.env (${lines.length} var${lines.length === 1 ? "" : "s"}).`
36315
36788
  );
@@ -36517,8 +36990,8 @@ __export(docs_exports, {
36517
36990
  stripRangePrefix: () => stripRangePrefix
36518
36991
  });
36519
36992
  import { existsSync as existsSync12 } from "node:fs";
36520
- import { mkdir as mkdir10, readFile as readFile25, readdir as readdir7, rm as rm2, writeFile as writeFile18 } from "node:fs/promises";
36521
- import { dirname as dirname12, isAbsolute as isAbsolute3, join as join39, relative as relative7, sep as sep2 } from "node:path";
36993
+ import { mkdir as mkdir11, readFile as readFile26, readdir as readdir8, rm as rm2, writeFile as writeFile19 } from "node:fs/promises";
36994
+ import { dirname as dirname13, isAbsolute as isAbsolute3, join as join42, relative as relative7, sep as sep2 } from "node:path";
36522
36995
  function selectDependencies(deps) {
36523
36996
  const byName = /* @__PURE__ */ new Map();
36524
36997
  for (const dep of deps) {
@@ -36572,12 +37045,12 @@ async function mapWithConcurrency(items, limit, fn) {
36572
37045
  }
36573
37046
  async function resolveExactVersion(projectPath, dep) {
36574
37047
  const candidateDirs = [projectPath];
36575
- const sourceDir = join39(projectPath, dirname12(dep.sourcePath));
37048
+ const sourceDir = join42(projectPath, dirname13(dep.sourcePath));
36576
37049
  if (sourceDir !== projectPath) candidateDirs.push(sourceDir);
36577
37050
  for (const base of candidateDirs) {
36578
37051
  try {
36579
- const raw = await readFile25(
36580
- join39(base, "node_modules", dep.name, "package.json"),
37052
+ const raw = await readFile26(
37053
+ join42(base, "node_modules", dep.name, "package.json"),
36581
37054
  "utf-8"
36582
37055
  );
36583
37056
  const pkg = JSON.parse(raw);
@@ -36591,8 +37064,8 @@ async function resolveExactVersion(projectPath, dep) {
36591
37064
  }
36592
37065
  async function readVendorDocsPath(projectPath) {
36593
37066
  try {
36594
- const raw = await readFile25(
36595
- join39(projectPath, ".codebyplan", "vendor.json"),
37067
+ const raw = await readFile26(
37068
+ join42(projectPath, ".codebyplan", "vendor.json"),
36596
37069
  "utf-8"
36597
37070
  );
36598
37071
  const parsed = JSON.parse(raw);
@@ -36605,7 +37078,7 @@ async function readVendorDocsPath(projectPath) {
36605
37078
  }
36606
37079
  async function resolveDocsDir(projectPath, flags) {
36607
37080
  const configured = flags["dir"] ?? await readVendorDocsPath(projectPath) ?? DEFAULT_DOCS_DIR;
36608
- const absDir = isAbsolute3(configured) ? configured : join39(projectPath, configured);
37081
+ const absDir = isAbsolute3(configured) ? configured : join42(projectPath, configured);
36609
37082
  const rel = relative7(projectPath, absDir);
36610
37083
  const relDir = rel === "" || rel.startsWith("..") ? null : rel.split(sep2).join("/");
36611
37084
  return { absDir, relDir };
@@ -36614,7 +37087,7 @@ async function readDocsLock(absDir) {
36614
37087
  const empty = { generated_at: "", libraries: {} };
36615
37088
  let raw;
36616
37089
  try {
36617
- raw = await readFile25(join39(absDir, LOCK_FILE), "utf-8");
37090
+ raw = await readFile26(join42(absDir, LOCK_FILE), "utf-8");
36618
37091
  } catch {
36619
37092
  return empty;
36620
37093
  }
@@ -36710,10 +37183,10 @@ function buildTopIndex(outcomes) {
36710
37183
  }
36711
37184
  async function ensureDocsGitignoreEntry(projectPath, relDir, dryRun) {
36712
37185
  const entry = `/${relDir}/`;
36713
- const gitignorePath = join39(projectPath, ".gitignore");
37186
+ const gitignorePath = join42(projectPath, ".gitignore");
36714
37187
  let existing = "";
36715
37188
  try {
36716
- existing = await readFile25(gitignorePath, "utf-8");
37189
+ existing = await readFile26(gitignorePath, "utf-8");
36717
37190
  } catch {
36718
37191
  }
36719
37192
  const lines = existing.split(/\r?\n/).map((l) => l.trim());
@@ -36725,7 +37198,7 @@ async function ensureDocsGitignoreEntry(projectPath, relDir, dryRun) {
36725
37198
  content += `${GITIGNORE_COMMENT}
36726
37199
  ${entry}
36727
37200
  `;
36728
- await writeFile18(gitignorePath, content, "utf-8");
37201
+ await writeFile19(gitignorePath, content, "utf-8");
36729
37202
  }
36730
37203
  return "added";
36731
37204
  }
@@ -36733,7 +37206,7 @@ async function markUncovered(dep, exactVersion, ctx) {
36733
37206
  console.log(
36734
37207
  ` uncovered ${dep.name}@${exactVersion || "?"} \u2014 no docs in the library mirror`
36735
37208
  );
36736
- const libPath = join39(ctx.absDir, libDirName(dep.name));
37209
+ const libPath = join42(ctx.absDir, libDirName(dep.name));
36737
37210
  if (existsSync12(libPath)) {
36738
37211
  if (ctx.dryRun) {
36739
37212
  console.log(` would remove stale mirror dir ${libPath}`);
@@ -36786,14 +37259,14 @@ async function syncOneLibrary(dep, ctx) {
36786
37259
  }
36787
37260
  }
36788
37261
  const lockEntry = ctx.lock.libraries[dep.name];
36789
- const libPath = join39(ctx.absDir, libDirName(dep.name));
36790
- const versionPath = join39(libPath, manifest.resolved_version);
37262
+ const libPath = join42(ctx.absDir, libDirName(dep.name));
37263
+ const versionPath = join42(libPath, manifest.resolved_version);
36791
37264
  if (manifestMatchesLock(manifest, lockEntry)) {
36792
37265
  console.log(` unchanged ${dep.name}@${manifest.resolved_version}`);
36793
- if (!ctx.dryRun && !existsSync12(join39(libPath, "INDEX.md"))) {
36794
- await mkdir10(libPath, { recursive: true });
36795
- await writeFile18(
36796
- join39(libPath, "INDEX.md"),
37266
+ if (!ctx.dryRun && !existsSync12(join42(libPath, "INDEX.md"))) {
37267
+ await mkdir11(libPath, { recursive: true });
37268
+ await writeFile19(
37269
+ join42(libPath, "INDEX.md"),
36797
37270
  buildLibIndex(dep.name, manifest),
36798
37271
  "utf-8"
36799
37272
  );
@@ -36815,14 +37288,14 @@ async function syncOneLibrary(dep, ctx) {
36815
37288
  );
36816
37289
  continue;
36817
37290
  }
36818
- const target = join39(versionPath, rel);
37291
+ const target = join42(versionPath, rel);
36819
37292
  if (sameVersionLockFiles[file.path] === file.content_hash && existsSync12(target)) {
36820
37293
  continue;
36821
37294
  }
36822
37295
  written++;
36823
37296
  if (!ctx.dryRun) {
36824
- await mkdir10(dirname12(target), { recursive: true });
36825
- await writeFile18(target, file.content, "utf-8");
37297
+ await mkdir11(dirname13(target), { recursive: true });
37298
+ await writeFile19(target, file.content, "utf-8");
36826
37299
  }
36827
37300
  }
36828
37301
  let removedFiles = 0;
@@ -36833,13 +37306,13 @@ async function syncOneLibrary(dep, ctx) {
36833
37306
  const rel = sanitizeDocPath(lockedPath);
36834
37307
  if (rel === null) continue;
36835
37308
  removedFiles++;
36836
- if (!ctx.dryRun) await rm2(join39(versionPath, rel), { force: true });
37309
+ if (!ctx.dryRun) await rm2(join42(versionPath, rel), { force: true });
36837
37310
  }
36838
37311
  }
36839
37312
  let removedVersionDirs = 0;
36840
37313
  let libEntries = [];
36841
37314
  try {
36842
- libEntries = await readdir7(libPath, { withFileTypes: true });
37315
+ libEntries = await readdir8(libPath, { withFileTypes: true });
36843
37316
  } catch {
36844
37317
  }
36845
37318
  for (const entry of libEntries) {
@@ -36848,13 +37321,13 @@ async function syncOneLibrary(dep, ctx) {
36848
37321
  }
36849
37322
  removedVersionDirs++;
36850
37323
  if (!ctx.dryRun) {
36851
- await rm2(join39(libPath, entry.name), { recursive: true, force: true });
37324
+ await rm2(join42(libPath, entry.name), { recursive: true, force: true });
36852
37325
  }
36853
37326
  }
36854
37327
  if (!ctx.dryRun) {
36855
- await mkdir10(libPath, { recursive: true });
36856
- await writeFile18(
36857
- join39(libPath, "INDEX.md"),
37328
+ await mkdir11(libPath, { recursive: true });
37329
+ await writeFile19(
37330
+ join42(libPath, "INDEX.md"),
36858
37331
  buildLibIndex(dep.name, manifest),
36859
37332
  "utf-8"
36860
37333
  );
@@ -36907,8 +37380,8 @@ async function runDocsSync() {
36907
37380
  (dep) => syncOneLibrary(dep, ctx)
36908
37381
  );
36909
37382
  if (!dryRun) {
36910
- await mkdir10(absDir, { recursive: true });
36911
- await writeFile18(join39(absDir, "INDEX.md"), buildTopIndex(outcomes), "utf-8");
37383
+ await mkdir11(absDir, { recursive: true });
37384
+ await writeFile19(join42(absDir, "INDEX.md"), buildTopIndex(outcomes), "utf-8");
36912
37385
  const libraries = {};
36913
37386
  for (const o of outcomes) {
36914
37387
  if (o.kind === "synced" || o.kind === "unchanged") {
@@ -36933,8 +37406,8 @@ async function runDocsSync() {
36933
37406
  generated_at: (/* @__PURE__ */ new Date()).toISOString(),
36934
37407
  libraries: sortedLibraries
36935
37408
  };
36936
- await writeFile18(
36937
- join39(absDir, LOCK_FILE),
37409
+ await writeFile19(
37410
+ join42(absDir, LOCK_FILE),
36938
37411
  JSON.stringify(newLock, null, 2) + "\n",
36939
37412
  "utf-8"
36940
37413
  );
@@ -36969,14 +37442,14 @@ async function runDocsSync() {
36969
37442
  async function countFilesRecursively(dirPath) {
36970
37443
  let entries;
36971
37444
  try {
36972
- entries = await readdir7(dirPath, { withFileTypes: true });
37445
+ entries = await readdir8(dirPath, { withFileTypes: true });
36973
37446
  } catch {
36974
37447
  return 0;
36975
37448
  }
36976
37449
  let count = 0;
36977
37450
  for (const entry of entries) {
36978
37451
  if (entry.isDirectory()) {
36979
- count += await countFilesRecursively(join39(dirPath, entry.name));
37452
+ count += await countFilesRecursively(join42(dirPath, entry.name));
36980
37453
  } else if (entry.isFile()) {
36981
37454
  count++;
36982
37455
  }
@@ -36993,7 +37466,7 @@ async function runDocsStatus() {
36993
37466
  `);
36994
37467
  let raw;
36995
37468
  try {
36996
- raw = await readFile25(join39(absDir, LOCK_FILE), "utf-8");
37469
+ raw = await readFile26(join42(absDir, LOCK_FILE), "utf-8");
36997
37470
  } catch {
36998
37471
  console.log(
36999
37472
  ` No ${LOCK_FILE} found \u2014 run \`codebyplan docs sync\` first.
@@ -37022,7 +37495,7 @@ async function runDocsStatus() {
37022
37495
  let outOfSync = 0;
37023
37496
  for (const name of names) {
37024
37497
  const entry = lock.libraries[name];
37025
- const versionPath = join39(absDir, libDirName(name), entry.resolved_version);
37498
+ const versionPath = join42(absDir, libDirName(name), entry.resolved_version);
37026
37499
  const expected = Object.keys(entry.files).length;
37027
37500
  if (!existsSync12(versionPath)) {
37028
37501
  outOfSync++;
@@ -37110,7 +37583,7 @@ var init_docs = __esm({
37110
37583
 
37111
37584
  // src/lib/check-baseline.ts
37112
37585
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
37113
- import { join as join40 } from "node:path";
37586
+ import { join as join43 } from "node:path";
37114
37587
  function emptyBaseline() {
37115
37588
  return {
37116
37589
  lint: { known_failing: [] },
@@ -37120,7 +37593,7 @@ function emptyBaseline() {
37120
37593
  };
37121
37594
  }
37122
37595
  function loadBaseline(projectRoot) {
37123
- const filePath = join40(projectRoot, BASELINE_FILENAME);
37596
+ const filePath = join43(projectRoot, BASELINE_FILENAME);
37124
37597
  try {
37125
37598
  const raw = readFileSync12(filePath, "utf-8");
37126
37599
  const parsed = JSON.parse(raw);
@@ -37144,7 +37617,7 @@ function loadBaseline(projectRoot) {
37144
37617
  }
37145
37618
  }
37146
37619
  function saveBaseline(projectRoot, baseline) {
37147
- const filePath = join40(projectRoot, BASELINE_FILENAME);
37620
+ const filePath = join43(projectRoot, BASELINE_FILENAME);
37148
37621
  writeFileSync8(filePath, JSON.stringify(baseline, null, 2) + "\n", "utf-8");
37149
37622
  }
37150
37623
  function diffBaseline(check, currentFailingPackages, baseline) {
@@ -37194,7 +37667,7 @@ var init_check_baseline = __esm({
37194
37667
 
37195
37668
  // src/lib/check.ts
37196
37669
  import { readFileSync as readFileSync13, existsSync as existsSync13 } from "node:fs";
37197
- import { join as join41 } from "node:path";
37670
+ import { join as join44 } from "node:path";
37198
37671
  import { spawnSync as spawnSync13 } from "node:child_process";
37199
37672
  function hasSentinelValue(arrays) {
37200
37673
  const SENTINELS = /* @__PURE__ */ new Set([
@@ -37262,9 +37735,9 @@ function parseFailingPackagesFromSummary(summaryPath) {
37262
37735
  return Array.from(failing).sort();
37263
37736
  }
37264
37737
  function resolveTurboBin(projectRoot) {
37265
- const localBin = join41(projectRoot, "node_modules", ".bin", "turbo");
37738
+ const localBin = join44(projectRoot, "node_modules", ".bin", "turbo");
37266
37739
  if (existsSync13(localBin)) return localBin;
37267
- const workspaceRootBin = join41(
37740
+ const workspaceRootBin = join44(
37268
37741
  projectRoot,
37269
37742
  "..",
37270
37743
  "..",
@@ -37781,7 +38254,7 @@ var init_check2 = __esm({
37781
38254
 
37782
38255
  // src/lib/claude-plan.ts
37783
38256
  import * as fs13 from "node:fs";
37784
- import * as path16 from "node:path";
38257
+ import * as path18 from "node:path";
37785
38258
  function buildDriftPlan(projectDir, templatesDir, manifest) {
37786
38259
  const packaged = walkTemplates(templatesDir);
37787
38260
  const packagedBySrc = new Map(packaged.map((f) => [f.src, f]));
@@ -37795,8 +38268,8 @@ function buildDriftPlan(projectDir, templatesDir, manifest) {
37795
38268
  };
37796
38269
  for (const pkg of packaged) {
37797
38270
  const inManifest = manifestBySrc.get(pkg.src);
37798
- const absDest = path16.join(projectDir, ".claude", pkg.dest);
37799
- const absSrc = path16.join(templatesDir, pkg.src);
38271
+ const absDest = path18.join(projectDir, ".claude", pkg.dest);
38272
+ const absSrc = path18.join(templatesDir, pkg.src);
37800
38273
  if (!inManifest) {
37801
38274
  plan.newOptIn.push({
37802
38275
  packaged: { src: pkg.src, dest: pkg.dest, hash: pkg.hash },
@@ -37845,7 +38318,7 @@ __export(status_exports, {
37845
38318
  runStatus: () => runStatus2
37846
38319
  });
37847
38320
  import * as fs14 from "node:fs";
37848
- import * as path17 from "node:path";
38321
+ import * as path19 from "node:path";
37849
38322
  import { execSync as execSync8 } from "node:child_process";
37850
38323
  function makeFailSafe(checked_at) {
37851
38324
  return {
@@ -37954,12 +38427,12 @@ async function runStatus2(argv) {
37954
38427
  const latest = fetchLatestVersion();
37955
38428
  const newer = latest !== null && compareSemver(latest, installed) > 0;
37956
38429
  let settings_drift = false;
37957
- const settingsPath = path17.join(projectDir, ".claude", "settings.json");
37958
- const baseSettingsPath = path17.join(
38430
+ const settingsPath = path19.join(projectDir, ".claude", "settings.json");
38431
+ const baseSettingsPath = path19.join(
37959
38432
  templatesDir,
37960
38433
  "settings.project.base.json"
37961
38434
  );
37962
- const hooksJsonPath = path17.join(templatesDir, "hooks", "hooks.json");
38435
+ const hooksJsonPath = path19.join(templatesDir, "hooks", "hooks.json");
37963
38436
  if (fs14.existsSync(settingsPath)) {
37964
38437
  try {
37965
38438
  const settingsRaw = fs14.readFileSync(settingsPath, "utf8");
@@ -38029,10 +38502,10 @@ function emitResult(result, writeCache, quiet, projectDir) {
38029
38502
  const json = JSON.stringify(result, null, 2);
38030
38503
  if (writeCache) {
38031
38504
  try {
38032
- const cacheDir = path17.join(projectDir, ".codebyplan");
38505
+ const cacheDir = path19.join(projectDir, ".codebyplan");
38033
38506
  fs14.mkdirSync(cacheDir, { recursive: true });
38034
38507
  fs14.writeFileSync(
38035
- path17.join(cacheDir, "claude-status.local.json"),
38508
+ path19.join(cacheDir, "claude-status.local.json"),
38036
38509
  json + "\n",
38037
38510
  "utf8"
38038
38511
  );
@@ -38176,7 +38649,7 @@ __export(update_exports, {
38176
38649
  });
38177
38650
  import * as fs15 from "node:fs";
38178
38651
  import * as os3 from "node:os";
38179
- import * as path18 from "node:path";
38652
+ import * as path20 from "node:path";
38180
38653
  async function runUpdate(opts, deps = {}) {
38181
38654
  await Promise.resolve();
38182
38655
  const scope = opts.scope ?? "project";
@@ -38212,9 +38685,9 @@ async function runUpdate(opts, deps = {}) {
38212
38685
  finalManifestEntries.push(e);
38213
38686
  }
38214
38687
  for (const { packaged, absSrc } of plan.overwriteSafe) {
38215
- const absDest = path18.join(projectDir, ".claude", packaged.dest);
38688
+ const absDest = path20.join(projectDir, ".claude", packaged.dest);
38216
38689
  if (!opts.dryRun) {
38217
- fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38690
+ fs15.mkdirSync(path20.dirname(absDest), { recursive: true });
38218
38691
  fs15.copyFileSync(absSrc, absDest);
38219
38692
  if (opts.verbose) console.log(`updated ${packaged.dest}`);
38220
38693
  } else if (opts.verbose) {
@@ -38227,7 +38700,7 @@ async function runUpdate(opts, deps = {}) {
38227
38700
  absSrc,
38228
38701
  onDiskContent
38229
38702
  } of plan.overwriteHandEdited) {
38230
- const absDest = path18.join(projectDir, ".claude", packaged.dest);
38703
+ const absDest = path20.join(projectDir, ".claude", packaged.dest);
38231
38704
  const newContent = fs15.readFileSync(absSrc);
38232
38705
  const showDiff = () => {
38233
38706
  console.log(
@@ -38240,7 +38713,7 @@ async function runUpdate(opts, deps = {}) {
38240
38713
  const answer = await promptOverwrite(packaged.dest, opts, showDiff);
38241
38714
  if (answer === "overwrite") {
38242
38715
  if (!opts.dryRun) {
38243
- fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38716
+ fs15.mkdirSync(path20.dirname(absDest), { recursive: true });
38244
38717
  fs15.copyFileSync(absSrc, absDest);
38245
38718
  }
38246
38719
  finalManifestEntries.push(packaged);
@@ -38256,9 +38729,9 @@ async function runUpdate(opts, deps = {}) {
38256
38729
  for (const { packaged, absSrc } of plan.newOptIn) {
38257
38730
  const answer = await promptOptIn(packaged.dest, opts);
38258
38731
  if (answer === "opt-in") {
38259
- const absDest = path18.join(projectDir, ".claude", packaged.dest);
38732
+ const absDest = path20.join(projectDir, ".claude", packaged.dest);
38260
38733
  if (!opts.dryRun) {
38261
- fs15.mkdirSync(path18.dirname(absDest), { recursive: true });
38734
+ fs15.mkdirSync(path20.dirname(absDest), { recursive: true });
38262
38735
  fs15.copyFileSync(absSrc, absDest);
38263
38736
  }
38264
38737
  finalManifestEntries.push(packaged);
@@ -38270,25 +38743,25 @@ async function runUpdate(opts, deps = {}) {
38270
38743
  for (const e of plan.removedFromPackage) {
38271
38744
  const answer = await promptRemove(e.dest, opts);
38272
38745
  if (answer === "remove") {
38273
- const absDest = path18.join(projectDir, ".claude", e.dest);
38746
+ const absDest = path20.join(projectDir, ".claude", e.dest);
38274
38747
  if (!opts.dryRun && fs15.existsSync(absDest)) {
38275
38748
  fs15.rmSync(absDest);
38276
- const claudeDir = path18.join(projectDir, ".claude");
38277
- let cur = path18.dirname(absDest);
38278
- while (cur !== claudeDir && cur !== path18.dirname(cur)) {
38279
- if (path18.dirname(cur) === claudeDir) break;
38749
+ const claudeDir = path20.join(projectDir, ".claude");
38750
+ let cur = path20.dirname(absDest);
38751
+ while (cur !== claudeDir && cur !== path20.dirname(cur)) {
38752
+ if (path20.dirname(cur) === claudeDir) break;
38280
38753
  try {
38281
38754
  fs15.rmdirSync(cur);
38282
38755
  if (opts.verbose)
38283
38756
  console.log(
38284
- `pruned empty dir ${path18.relative(claudeDir, cur)}`
38757
+ `pruned empty dir ${path20.relative(claudeDir, cur)}`
38285
38758
  );
38286
- cur = path18.dirname(cur);
38759
+ cur = path20.dirname(cur);
38287
38760
  } catch (err) {
38288
38761
  const code = err.code;
38289
38762
  if (code !== "ENOTEMPTY" && code !== "ENOENT") {
38290
38763
  console.warn(
38291
- `codebyplan claude: could not prune empty dir ${path18.relative(claudeDir, cur)}: ${err.message}`
38764
+ `codebyplan claude: could not prune empty dir ${path20.relative(claudeDir, cur)}: ${err.message}`
38292
38765
  );
38293
38766
  }
38294
38767
  break;
@@ -38300,12 +38773,12 @@ async function runUpdate(opts, deps = {}) {
38300
38773
  if (opts.verbose) console.log(`kept (untracked) ${e.dest}`);
38301
38774
  }
38302
38775
  }
38303
- const hooksJsonPath = path18.join(templatesDir, "hooks", "hooks.json");
38304
- const baseSettingsPath = path18.join(
38776
+ const hooksJsonPath = path20.join(templatesDir, "hooks", "hooks.json");
38777
+ const baseSettingsPath = path20.join(
38305
38778
  templatesDir,
38306
38779
  "settings.project.base.json"
38307
38780
  );
38308
- const settingsPath = path18.join(projectDir, ".claude", "settings.json");
38781
+ const settingsPath = path20.join(projectDir, ".claude", "settings.json");
38309
38782
  const existingSettings = fs15.existsSync(settingsPath) ? JSON.parse(fs15.readFileSync(settingsPath, "utf8")) : {};
38310
38783
  if (fs15.existsSync(baseSettingsPath)) {
38311
38784
  const base = JSON.parse(
@@ -38332,7 +38805,7 @@ async function runUpdate(opts, deps = {}) {
38332
38805
  deps.detectHealDeps
38333
38806
  );
38334
38807
  if (!opts.dryRun) {
38335
- fs15.mkdirSync(path18.dirname(settingsPath), { recursive: true });
38808
+ fs15.mkdirSync(path20.dirname(settingsPath), { recursive: true });
38336
38809
  fs15.writeFileSync(
38337
38810
  settingsPath,
38338
38811
  JSON.stringify(existingSettings, null, 2) + "\n",
@@ -38348,7 +38821,7 @@ async function runUpdate(opts, deps = {}) {
38348
38821
  );
38349
38822
  if (opts.verbose && gitignoreAction !== "unchanged") {
38350
38823
  console.log(
38351
- `${opts.dryRun ? "[dry-run] would " : ""}${gitignoreAction} managed .gitignore block in ${path18.relative(projectDir, path18.join(projectDir, ".gitignore"))}`
38824
+ `${opts.dryRun ? "[dry-run] would " : ""}${gitignoreAction} managed .gitignore block in ${path20.relative(projectDir, path20.join(projectDir, ".gitignore"))}`
38352
38825
  );
38353
38826
  }
38354
38827
  if (!opts.dryRun) {
@@ -38388,9 +38861,9 @@ function runUpdateUser(opts, deps) {
38388
38861
  return;
38389
38862
  }
38390
38863
  try {
38391
- const userDir = deps.userDir ?? path18.join(os3.homedir(), ".claude");
38392
- const settingsPath = path18.join(userDir, "settings.json");
38393
- const userBaseSettingsPath = path18.join(
38864
+ const userDir = deps.userDir ?? path20.join(os3.homedir(), ".claude");
38865
+ const settingsPath = path20.join(userDir, "settings.json");
38866
+ const userBaseSettingsPath = path20.join(
38394
38867
  templatesDir,
38395
38868
  "settings.user.base.json"
38396
38869
  );
@@ -38462,7 +38935,7 @@ __export(uninstall_exports, {
38462
38935
  });
38463
38936
  import * as fs16 from "node:fs";
38464
38937
  import * as os4 from "node:os";
38465
- import * as path19 from "node:path";
38938
+ import * as path21 from "node:path";
38466
38939
  async function runUninstall(opts, deps = {}) {
38467
38940
  await Promise.resolve();
38468
38941
  const scope = opts.scope ?? "project";
@@ -38491,7 +38964,7 @@ async function runUninstall(opts, deps = {}) {
38491
38964
  let removed = 0;
38492
38965
  let warnings = 0;
38493
38966
  for (const entry of manifest.files) {
38494
- const abs = path19.join(projectDir, ".claude", entry.dest);
38967
+ const abs = path21.join(projectDir, ".claude", entry.dest);
38495
38968
  if (!fs16.existsSync(abs)) {
38496
38969
  console.warn(
38497
38970
  `codebyplan claude uninstall: ${entry.dest} already absent (skipping).`
@@ -38515,12 +38988,12 @@ async function runUninstall(opts, deps = {}) {
38515
38988
  if (!opts.dryRun) {
38516
38989
  pruneEmptyManagedDirs(projectDir);
38517
38990
  }
38518
- const settingsPath = path19.join(projectDir, ".claude", "settings.json");
38991
+ const settingsPath = path21.join(projectDir, ".claude", "settings.json");
38519
38992
  if (fs16.existsSync(settingsPath)) {
38520
38993
  const settings = JSON.parse(
38521
38994
  fs16.readFileSync(settingsPath, "utf8")
38522
38995
  );
38523
- const baseSettingsPath = templatesDir ? path19.join(templatesDir, "settings.project.base.json") : null;
38996
+ const baseSettingsPath = templatesDir ? path21.join(templatesDir, "settings.project.base.json") : null;
38524
38997
  if (baseSettingsPath && fs16.existsSync(baseSettingsPath)) {
38525
38998
  const base = JSON.parse(
38526
38999
  fs16.readFileSync(baseSettingsPath, "utf8")
@@ -38578,7 +39051,7 @@ function runUninstallUser(opts, deps) {
38578
39051
  }
38579
39052
  }
38580
39053
  try {
38581
- const userDir = deps.userDir ?? path19.join(os4.homedir(), ".claude");
39054
+ const userDir = deps.userDir ?? path21.join(os4.homedir(), ".claude");
38582
39055
  const existingManifest = readManifestForScope("user", userDir);
38583
39056
  if (!existingManifest) {
38584
39057
  console.error(
@@ -38587,12 +39060,12 @@ function runUninstallUser(opts, deps) {
38587
39060
  process.exitCode = 1;
38588
39061
  return;
38589
39062
  }
38590
- const settingsPath = path19.join(userDir, "settings.json");
39063
+ const settingsPath = path21.join(userDir, "settings.json");
38591
39064
  if (fs16.existsSync(settingsPath)) {
38592
39065
  const settings = JSON.parse(
38593
39066
  fs16.readFileSync(settingsPath, "utf8")
38594
39067
  );
38595
- const userBaseSettingsPath = templatesDir != null ? path19.join(templatesDir, "settings.user.base.json") : null;
39068
+ const userBaseSettingsPath = templatesDir != null ? path21.join(templatesDir, "settings.user.base.json") : null;
38596
39069
  if (userBaseSettingsPath && fs16.existsSync(userBaseSettingsPath)) {
38597
39070
  const userBase = JSON.parse(
38598
39071
  fs16.readFileSync(userBaseSettingsPath, "utf8")
@@ -38633,7 +39106,7 @@ function runUninstallUser(opts, deps) {
38633
39106
  function pruneEmptyManagedDirs(projectDir) {
38634
39107
  const managedRoots = ["skills", "agents", "hooks", "rules"];
38635
39108
  for (const root of managedRoots) {
38636
- const abs = path19.join(projectDir, ".claude", root);
39109
+ const abs = path21.join(projectDir, ".claude", root);
38637
39110
  if (!fs16.existsSync(abs)) continue;
38638
39111
  pruneLeafFirst(abs);
38639
39112
  }
@@ -38644,7 +39117,7 @@ function pruneLeafFirst(dir) {
38644
39117
  if (!stat2.isDirectory()) return;
38645
39118
  for (const entry of fs16.readdirSync(dir, { withFileTypes: true })) {
38646
39119
  if (entry.isDirectory()) {
38647
- pruneLeafFirst(path19.join(dir, entry.name));
39120
+ pruneLeafFirst(path21.join(dir, entry.name));
38648
39121
  }
38649
39122
  }
38650
39123
  const remaining = fs16.readdirSync(dir);
@@ -38665,7 +39138,7 @@ var init_uninstall = __esm({
38665
39138
 
38666
39139
  // src/lib/verify-parity.ts
38667
39140
  import * as fs17 from "node:fs";
38668
- import * as path20 from "node:path";
39141
+ import * as path22 from "node:path";
38669
39142
  function isValidScope(s) {
38670
39143
  return s === "org-shared" || s === "project-shared" || REPO_ONLY_RE.test(s);
38671
39144
  }
@@ -38682,25 +39155,25 @@ function checkSiblingParity(opts) {
38682
39155
  expectedOneSided = DEFAULT_EXPECTED_ONE_SIDED,
38683
39156
  ignoredSubtrees
38684
39157
  } = opts;
38685
- const defaultIgnored = [path20.join(claudeDir, "hooks", "__test-fixtures__")];
39158
+ const defaultIgnored = [path22.join(claudeDir, "hooks", "__test-fixtures__")];
38686
39159
  const ignored = ignoredSubtrees ?? defaultIgnored;
38687
39160
  const violations = [];
38688
39161
  const claudeSideRels = /* @__PURE__ */ new Set();
38689
39162
  for (const scanDir of SCAN_DIRS) {
38690
- const baseDir = path20.join(claudeDir, scanDir);
39163
+ const baseDir = path22.join(claudeDir, scanDir);
38691
39164
  if (!fs17.existsSync(baseDir)) continue;
38692
39165
  const entries = readdirRecursive(baseDir);
38693
39166
  for (const entry of entries) {
38694
- const absPath = path20.join(baseDir, entry);
39167
+ const absPath = path22.join(baseDir, entry);
38695
39168
  if (!fs17.lstatSync(absPath).isFile()) continue;
38696
39169
  if (ignored.some(
38697
- (ig) => absPath.startsWith(ig + path20.sep) || absPath === ig
39170
+ (ig) => absPath.startsWith(ig + path22.sep) || absPath === ig
38698
39171
  )) {
38699
39172
  continue;
38700
39173
  }
38701
- const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39174
+ const relPath = path22.join(scanDir, entry).split(path22.sep).join("/");
38702
39175
  claudeSideRels.add(relPath);
38703
- const templatePath = path20.join(templatesDir, relPath);
39176
+ const templatePath = path22.join(templatesDir, relPath);
38704
39177
  if (!fs17.existsSync(templatePath)) {
38705
39178
  if (!expectedOneSided.has(relPath) && !isScaffoldFile(entry)) {
38706
39179
  violations.push({ type: "missing-twin", path: relPath });
@@ -38715,14 +39188,14 @@ function checkSiblingParity(opts) {
38715
39188
  }
38716
39189
  }
38717
39190
  for (const scanDir of SCAN_DIRS) {
38718
- const tplBase = path20.join(templatesDir, scanDir);
39191
+ const tplBase = path22.join(templatesDir, scanDir);
38719
39192
  if (!fs17.existsSync(tplBase)) continue;
38720
39193
  const entries = readdirRecursive(tplBase);
38721
39194
  for (const entry of entries) {
38722
- const absPath = path20.join(tplBase, entry);
39195
+ const absPath = path22.join(tplBase, entry);
38723
39196
  if (!fs17.lstatSync(absPath).isFile()) continue;
38724
39197
  if (isScaffoldFile(entry)) continue;
38725
- const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39198
+ const relPath = path22.join(scanDir, entry).split(path22.sep).join("/");
38726
39199
  if (!claudeSideRels.has(relPath) && !expectedOneSided.has(relPath)) {
38727
39200
  violations.push({ type: "extra-twin", path: relPath });
38728
39201
  }
@@ -38758,18 +39231,18 @@ function checkScopeMarkers(opts) {
38758
39231
  const twinDetectionActive = templatesDir != null && fs17.existsSync(templatesDir);
38759
39232
  const violations = [];
38760
39233
  for (const scanDir of scanDirs) {
38761
- const baseDir = path20.join(claudeDir, scanDir);
39234
+ const baseDir = path22.join(claudeDir, scanDir);
38762
39235
  if (!fs17.existsSync(baseDir)) continue;
38763
39236
  const entries = readdirRecursive(baseDir);
38764
39237
  for (const entry of entries) {
38765
- const absPath = path20.join(baseDir, entry);
39238
+ const absPath = path22.join(baseDir, entry);
38766
39239
  if (!fs17.lstatSync(absPath).isFile()) continue;
38767
39240
  if (!isStructuralEntry(scanDir, entry)) continue;
38768
- const ext = path20.extname(entry).toLowerCase();
39241
+ const ext = path22.extname(entry).toLowerCase();
38769
39242
  const isMd = ext === ".md";
38770
39243
  const isSh = ext === ".sh";
38771
39244
  if (!isMd && !isSh) continue;
38772
- const relPath = path20.join(scanDir, entry).split(path20.sep).join("/");
39245
+ const relPath = path22.join(scanDir, entry).split(path22.sep).join("/");
38773
39246
  if (allowlist.has(relPath)) continue;
38774
39247
  let content;
38775
39248
  try {
@@ -38783,7 +39256,7 @@ function checkScopeMarkers(opts) {
38783
39256
  continue;
38784
39257
  }
38785
39258
  const scopeValue = isMd ? extractFrontmatterScope(content) : extractShScope(content);
38786
- const managed = twinDetectionActive && fs17.existsSync(path20.join(templatesDir, relPath));
39259
+ const managed = twinDetectionActive && fs17.existsSync(path22.join(templatesDir, relPath));
38787
39260
  if (managed) {
38788
39261
  if (scopeValue === null) {
38789
39262
  } else if (scopeValue === "org-shared") {
@@ -38837,7 +39310,7 @@ function readdirRecursive(dir, rel = "", visited = /* @__PURE__ */ new Set()) {
38837
39310
  visited.add(realDir);
38838
39311
  const results = [];
38839
39312
  for (const name of fs17.readdirSync(dir)) {
38840
- const full = path20.join(dir, name);
39313
+ const full = path22.join(dir, name);
38841
39314
  const relName = rel ? `${rel}/${name}` : name;
38842
39315
  if (fs17.lstatSync(full).isDirectory()) {
38843
39316
  results.push(...readdirRecursive(full, relName, visited));
@@ -38910,12 +39383,12 @@ __export(verify_parity_exports, {
38910
39383
  verifyParity: () => verifyParity
38911
39384
  });
38912
39385
  import * as fs18 from "node:fs";
38913
- import * as path21 from "node:path";
39386
+ import * as path23 from "node:path";
38914
39387
  function verifyParity(args, deps = {}) {
38915
39388
  const warnOnly = args.includes("--warn-only");
38916
39389
  const jsonMode = args.includes("--json");
38917
39390
  const projectDir = deps.cwd ?? process.cwd();
38918
- const claudeDir = path21.join(projectDir, ".claude");
39391
+ const claudeDir = path23.join(projectDir, ".claude");
38919
39392
  if (!fs18.existsSync(claudeDir)) {
38920
39393
  const msg = "codebyplan claude verify-parity: .claude/ not found in cwd \u2014 run from the project root.\n";
38921
39394
  process.stderr.write(msg);
@@ -39422,11 +39895,11 @@ var generate_exports = {};
39422
39895
  __export(generate_exports, {
39423
39896
  runGenerate: () => runGenerate
39424
39897
  });
39425
- import { readFile as readFile26, mkdir as mkdir11, writeFile as writeFile19 } from "node:fs/promises";
39426
- import { join as join48, resolve as resolve12 } from "node:path";
39898
+ import { readFile as readFile27, mkdir as mkdir12, writeFile as writeFile20 } from "node:fs/promises";
39899
+ import { join as join51, resolve as resolve12 } from "node:path";
39427
39900
  async function readJsonFile4(filePath) {
39428
39901
  try {
39429
- const raw = await readFile26(filePath, "utf-8");
39902
+ const raw = await readFile27(filePath, "utf-8");
39430
39903
  return JSON.parse(raw);
39431
39904
  } catch {
39432
39905
  return null;
@@ -39434,7 +39907,7 @@ async function readJsonFile4(filePath) {
39434
39907
  }
39435
39908
  async function readPkgName(absPath) {
39436
39909
  try {
39437
- const raw = await readFile26(join48(absPath, "package.json"), "utf-8");
39910
+ const raw = await readFile27(join51(absPath, "package.json"), "utf-8");
39438
39911
  const pkg = JSON.parse(raw);
39439
39912
  return typeof pkg.name === "string" ? pkg.name : null;
39440
39913
  } catch {
@@ -39448,7 +39921,7 @@ async function runGenerate(opts) {
39448
39921
  const rootDir = resolve12(projectDir);
39449
39922
  let packageManager;
39450
39923
  try {
39451
- const raw = await readFile26(join48(rootDir, "package.json"), "utf-8");
39924
+ const raw = await readFile27(join51(rootDir, "package.json"), "utf-8");
39452
39925
  const pkg = JSON.parse(raw);
39453
39926
  if (typeof pkg.packageManager === "string") {
39454
39927
  packageManager = pkg.packageManager;
@@ -39456,7 +39929,7 @@ async function runGenerate(opts) {
39456
39929
  } catch {
39457
39930
  }
39458
39931
  const serverJson = await readJsonFile4(
39459
- join48(rootDir, ".codebyplan", "server.json")
39932
+ join51(rootDir, ".codebyplan", "server.json")
39460
39933
  );
39461
39934
  const ports = [];
39462
39935
  for (const alloc of serverJson?.port_allocations ?? []) {
@@ -39469,7 +39942,7 @@ async function runGenerate(opts) {
39469
39942
  }
39470
39943
  }
39471
39944
  const gitJson = await readJsonFile4(
39472
- join48(rootDir, ".codebyplan", "git.json")
39945
+ join51(rootDir, ".codebyplan", "git.json")
39473
39946
  );
39474
39947
  const branchModel = gitJson?.branch_config?.production ? {
39475
39948
  production: gitJson.branch_config.production,
@@ -39478,7 +39951,7 @@ async function runGenerate(opts) {
39478
39951
  )
39479
39952
  } : void 0;
39480
39953
  const shipmentJson = await readJsonFile4(
39481
- join48(rootDir, ".codebyplan", "shipment.json")
39954
+ join51(rootDir, ".codebyplan", "shipment.json")
39482
39955
  );
39483
39956
  const shipmentSurfaces = [];
39484
39957
  const rawSurfaces = shipmentJson?.shipment?.surfaces ?? shipmentJson?.surfaces ?? {};
@@ -39549,10 +40022,10 @@ async function runGenerate(opts) {
39549
40022
  const structureMdContent = generateStructureMd(config);
39550
40023
  const agentsContent = generateAgentsMd(structureMdContent);
39551
40024
  if (check) {
39552
- const agentsMdPath2 = join48(rootDir, "AGENTS.md");
40025
+ const agentsMdPath2 = join51(rootDir, "AGENTS.md");
39553
40026
  let existingAgents = null;
39554
40027
  try {
39555
- existingAgents = await readFile26(agentsMdPath2, "utf-8");
40028
+ existingAgents = await readFile27(agentsMdPath2, "utf-8");
39556
40029
  } catch {
39557
40030
  existingAgents = null;
39558
40031
  }
@@ -39588,16 +40061,16 @@ async function runGenerate(opts) {
39588
40061
  process.stdout.write(agentsContent);
39589
40062
  return;
39590
40063
  }
39591
- const outputDir = join48(rootDir, ".claude", "generated");
39592
- await mkdir11(outputDir, { recursive: true });
39593
- const outputPath = join48(outputDir, "structure.md");
39594
- await writeFile19(outputPath, structureMdContent, "utf-8");
40064
+ const outputDir = join51(rootDir, ".claude", "generated");
40065
+ await mkdir12(outputDir, { recursive: true });
40066
+ const outputPath = join51(outputDir, "structure.md");
40067
+ await writeFile20(outputPath, structureMdContent, "utf-8");
39595
40068
  process.stdout.write(`Wrote: .claude/generated/structure.md
39596
40069
  `);
39597
- const agentsMdPath = join48(rootDir, "AGENTS.md");
40070
+ const agentsMdPath = join51(rootDir, "AGENTS.md");
39598
40071
  let existingAgentsContent = null;
39599
40072
  try {
39600
- existingAgentsContent = await readFile26(agentsMdPath, "utf-8");
40073
+ existingAgentsContent = await readFile27(agentsMdPath, "utf-8");
39601
40074
  } catch {
39602
40075
  existingAgentsContent = null;
39603
40076
  }
@@ -39605,7 +40078,7 @@ async function runGenerate(opts) {
39605
40078
  process.stdout.write(`Up to date: AGENTS.md
39606
40079
  `);
39607
40080
  } else {
39608
- await writeFile19(agentsMdPath, agentsContent, "utf-8");
40081
+ await writeFile20(agentsMdPath, agentsContent, "utf-8");
39609
40082
  process.stdout.write(`Wrote: AGENTS.md
39610
40083
  `);
39611
40084
  }
@@ -39625,11 +40098,11 @@ __export(readme_exports, {
39625
40098
  runReadme: () => runReadme,
39626
40099
  runReadmeCommand: () => runReadmeCommand
39627
40100
  });
39628
- import { readFile as readFile27, writeFile as writeFile20 } from "node:fs/promises";
39629
- import { join as join49, resolve as resolve13, relative as relative9 } from "node:path";
40101
+ import { readFile as readFile28, writeFile as writeFile21 } from "node:fs/promises";
40102
+ import { join as join52, resolve as resolve13, relative as relative9 } from "node:path";
39630
40103
  async function readJsonFile5(filePath) {
39631
40104
  try {
39632
- const raw = await readFile27(filePath, "utf-8");
40105
+ const raw = await readFile28(filePath, "utf-8");
39633
40106
  return JSON.parse(raw);
39634
40107
  } catch {
39635
40108
  return null;
@@ -39698,7 +40171,7 @@ async function discoverUnits(rootDir, rootPkgJson) {
39698
40171
  const discovered = await discoverMonorepoApps(rootDir);
39699
40172
  for (const app of discovered) {
39700
40173
  const pkgJson = await readJsonFile5(
39701
- join49(app.absPath, "package.json")
40174
+ join52(app.absPath, "package.json")
39702
40175
  );
39703
40176
  pkgJsonByPath.set(app.absPath, pkgJson);
39704
40177
  allPackages.push({
@@ -39724,7 +40197,7 @@ async function runReadme(opts) {
39724
40197
  const init = opts.init ?? opts["init"] ?? false;
39725
40198
  const rootDir = resolve13(projectDir);
39726
40199
  const rootPkgJson = await readJsonFile5(
39727
- join49(rootDir, "package.json")
40200
+ join52(rootDir, "package.json")
39728
40201
  );
39729
40202
  const { units, allPackages, pkgJsonByPath } = await discoverUnits(
39730
40203
  rootDir,
@@ -39733,11 +40206,11 @@ async function runReadme(opts) {
39733
40206
  const driftUnits = [];
39734
40207
  const missingUnits = [];
39735
40208
  for (const unit of units) {
39736
- const readmePath = join49(unit.absPath, "README.md");
39737
- const relPath = unit.isRoot ? "README.md" : join49(relative9(rootDir, unit.absPath), "README.md");
40209
+ const readmePath = join52(unit.absPath, "README.md");
40210
+ const relPath = unit.isRoot ? "README.md" : join52(relative9(rootDir, unit.absPath), "README.md");
39738
40211
  let existingContent = null;
39739
40212
  try {
39740
- existingContent = await readFile27(readmePath, "utf-8");
40213
+ existingContent = await readFile28(readmePath, "utf-8");
39741
40214
  } catch {
39742
40215
  existingContent = null;
39743
40216
  }
@@ -39772,7 +40245,7 @@ ${newContent}
39772
40245
  `
39773
40246
  );
39774
40247
  } else {
39775
- await writeFile20(readmePath, newContent, "utf-8");
40248
+ await writeFile21(readmePath, newContent, "utf-8");
39776
40249
  process.stdout.write(`Wrote (scaffold): ${relPath}
39777
40250
  `);
39778
40251
  }
@@ -39810,7 +40283,7 @@ ${newContent}
39810
40283
  `
39811
40284
  );
39812
40285
  } else {
39813
- await writeFile20(readmePath, newContent, "utf-8");
40286
+ await writeFile21(readmePath, newContent, "utf-8");
39814
40287
  process.stdout.write(`Wrote (refresh): ${relPath}
39815
40288
  `);
39816
40289
  }
@@ -39829,7 +40302,7 @@ ${newContent}
39829
40302
  `
39830
40303
  );
39831
40304
  } else {
39832
- await writeFile20(readmePath, newContent, "utf-8");
40305
+ await writeFile21(readmePath, newContent, "utf-8");
39833
40306
  process.stdout.write(`Wrote (init): ${relPath}
39834
40307
  `);
39835
40308
  }
@@ -39917,15 +40390,15 @@ __export(migrate_memory_exports, {
39917
40390
  runMigrateMemory: () => runMigrateMemory
39918
40391
  });
39919
40392
  import {
39920
- readFile as readFile28,
39921
- writeFile as writeFile21,
39922
- mkdir as mkdir12,
39923
- unlink as unlink6,
40393
+ readFile as readFile29,
40394
+ writeFile as writeFile22,
40395
+ mkdir as mkdir13,
40396
+ unlink as unlink7,
39924
40397
  rmdir,
39925
- readdir as readdir8
40398
+ readdir as readdir9
39926
40399
  } from "node:fs/promises";
39927
40400
  import { existsSync as existsSync20 } from "node:fs";
39928
- import { join as join50, resolve as resolve14, dirname as dirname14, sep as sep4 } from "node:path";
40401
+ import { join as join53, resolve as resolve14, dirname as dirname15, sep as sep4 } from "node:path";
39929
40402
  import { homedir as homedir8 } from "node:os";
39930
40403
  function encodeProjectPath(absPath) {
39931
40404
  return resolve14(absPath).replace(/[/\\]/g, "-");
@@ -39936,7 +40409,7 @@ function resolveAutoMemoryDir(opts) {
39936
40409
  }
39937
40410
  const projectDir = opts.projectDir ?? process.cwd();
39938
40411
  const encoded = encodeProjectPath(projectDir);
39939
- return join50(homedir8(), ".claude", "projects", encoded, "memory");
40412
+ return join53(homedir8(), ".claude", "projects", encoded, "memory");
39940
40413
  }
39941
40414
  function parseFrontmatter(content) {
39942
40415
  content = content.replace(/\r\n/g, "\n");
@@ -39995,17 +40468,17 @@ function parseFrontmatter(content) {
39995
40468
  async function inventoryFiles(dir) {
39996
40469
  let filenames;
39997
40470
  try {
39998
- const entries = await readdir8(dir);
40471
+ const entries = await readdir9(dir);
39999
40472
  filenames = entries.filter((f) => f.endsWith(".md") && f !== "MEMORY.md").sort();
40000
40473
  } catch {
40001
40474
  return [];
40002
40475
  }
40003
40476
  const results = [];
40004
40477
  for (const filename of filenames) {
40005
- const sourcePath = join50(dir, filename);
40478
+ const sourcePath = join53(dir, filename);
40006
40479
  let raw;
40007
40480
  try {
40008
- raw = await readFile28(sourcePath, "utf-8");
40481
+ raw = await readFile29(sourcePath, "utf-8");
40009
40482
  } catch (err) {
40010
40483
  const msg = err instanceof Error ? err.message : String(err);
40011
40484
  results.push({
@@ -40091,8 +40564,8 @@ async function applyPlan(plan, opts) {
40091
40564
  if (entry.suggested_action !== "keep") continue;
40092
40565
  if (!entry.suggested_target?.startsWith("nested:")) continue;
40093
40566
  const relPath = entry.suggested_target.slice("nested:".length);
40094
- const targetDir = resolve14(join50(projectDir, relPath));
40095
- const targetFile = join50(targetDir, "CLAUDE.md");
40567
+ const targetDir = resolve14(join53(projectDir, relPath));
40568
+ const targetFile = join53(targetDir, "CLAUDE.md");
40096
40569
  if (!targetDir.startsWith(resolve14(projectDir) + sep4)) {
40097
40570
  process.stderr.write(
40098
40571
  `migrate-memory: skipping unsafe suggested_target "${entry.suggested_target}" \u2014 resolves outside projectDir
@@ -40121,18 +40594,18 @@ ${anchor}
40121
40594
  }
40122
40595
  continue;
40123
40596
  }
40124
- await mkdir12(targetDir, { recursive: true });
40597
+ await mkdir13(targetDir, { recursive: true });
40125
40598
  let existing = "";
40126
40599
  try {
40127
- existing = await readFile28(targetFile, "utf-8");
40600
+ existing = await readFile29(targetFile, "utf-8");
40128
40601
  } catch {
40129
40602
  }
40130
40603
  if (!existing.includes(anchor)) {
40131
- await writeFile21(targetFile, existing + appendContent, "utf-8");
40604
+ await writeFile22(targetFile, existing + appendContent, "utf-8");
40132
40605
  }
40133
40606
  if (resolve14(entry.source_path).startsWith(resolve14(plan.auto_memory_dir) + sep4)) {
40134
40607
  try {
40135
- await unlink6(entry.source_path);
40608
+ await unlink7(entry.source_path);
40136
40609
  } catch {
40137
40610
  }
40138
40611
  } else {
@@ -40142,7 +40615,7 @@ ${anchor}
40142
40615
  );
40143
40616
  }
40144
40617
  }
40145
- const rootClaudeMd = join50(projectDir, ".claude", "CLAUDE.md");
40618
+ const rootClaudeMd = join53(projectDir, ".claude", "CLAUDE.md");
40146
40619
  if (dryRun) {
40147
40620
  process.stdout.write(
40148
40621
  `[dry-run] Would ensure ${rootClaudeMd} contains: ${IMPORT_LINE}
@@ -40151,12 +40624,12 @@ ${anchor}
40151
40624
  } else {
40152
40625
  let claudeMdContent = "";
40153
40626
  try {
40154
- claudeMdContent = await readFile28(rootClaudeMd, "utf-8");
40627
+ claudeMdContent = await readFile29(rootClaudeMd, "utf-8");
40155
40628
  } catch {
40156
- await mkdir12(dirname14(rootClaudeMd), { recursive: true });
40629
+ await mkdir13(dirname15(rootClaudeMd), { recursive: true });
40157
40630
  }
40158
40631
  if (!claudeMdContent.includes(IMPORT_LINE)) {
40159
- await writeFile21(
40632
+ await writeFile22(
40160
40633
  rootClaudeMd,
40161
40634
  claudeMdContent + `
40162
40635
  ${IMPORT_LINE}
@@ -40182,19 +40655,19 @@ ${IMPORT_LINE}
40182
40655
  continue;
40183
40656
  }
40184
40657
  try {
40185
- await unlink6(entry.source_path);
40658
+ await unlink7(entry.source_path);
40186
40659
  } catch {
40187
40660
  }
40188
40661
  }
40189
- const memoryMd = join50(plan.auto_memory_dir, "MEMORY.md");
40190
- const safeRmdirBase = join50(homedir8(), ".claude", "projects");
40662
+ const memoryMd = join53(plan.auto_memory_dir, "MEMORY.md");
40663
+ const safeRmdirBase = join53(homedir8(), ".claude", "projects");
40191
40664
  if (dryRun) {
40192
40665
  process.stdout.write(`[dry-run] Would delete MEMORY.md: ${memoryMd}
40193
40666
  `);
40194
40667
  } else {
40195
40668
  if (resolve14(plan.auto_memory_dir).startsWith(safeRmdirBase + sep4)) {
40196
40669
  try {
40197
- await unlink6(memoryMd);
40670
+ await unlink7(memoryMd);
40198
40671
  } catch {
40199
40672
  }
40200
40673
  } else {
@@ -40217,7 +40690,7 @@ ${IMPORT_LINE}
40217
40690
  );
40218
40691
  } else {
40219
40692
  try {
40220
- const remaining = await readdir8(plan.auto_memory_dir);
40693
+ const remaining = await readdir9(plan.auto_memory_dir);
40221
40694
  if (remaining.length === 0) {
40222
40695
  await rmdir(plan.auto_memory_dir);
40223
40696
  }
@@ -40240,7 +40713,7 @@ async function runMigrateMemory(opts) {
40240
40713
  if (applyFile) {
40241
40714
  let planJson;
40242
40715
  try {
40243
- planJson = await readFile28(resolve14(applyFile), "utf-8");
40716
+ planJson = await readFile29(resolve14(applyFile), "utf-8");
40244
40717
  } catch (err) {
40245
40718
  const msg = err instanceof Error ? err.message : String(err);
40246
40719
  process.stderr.write(
@@ -40311,7 +40784,7 @@ var init_migrate_memory = __esm({
40311
40784
 
40312
40785
  // src/lib/claude-mode-audit.ts
40313
40786
  import { readdirSync as readdirSync6, readFileSync as readFileSync19, existsSync as existsSync21 } from "node:fs";
40314
- import { join as join51, basename as basename3 } from "node:path";
40787
+ import { join as join54, basename as basename4 } from "node:path";
40315
40788
  function parseFrontmatter2(content) {
40316
40789
  const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
40317
40790
  if (!match) return {};
@@ -40331,7 +40804,7 @@ function parseFrontmatter2(content) {
40331
40804
  function auditAgent(filePath) {
40332
40805
  const content = readFileSync19(filePath, "utf-8");
40333
40806
  const fm = parseFrontmatter2(content);
40334
- const agentName = fm.name ?? basename3(filePath, ".md");
40807
+ const agentName = fm.name ?? basename4(filePath, ".md");
40335
40808
  const expected = AGENT_EXCEPTIONS[agentName] ?? AGENT_DEFAULT;
40336
40809
  const expectedStr = `model:${expected.model}/effort:${expected.effort}`;
40337
40810
  const model = fm.model ?? null;
@@ -40390,19 +40863,19 @@ function auditSkill(filePath) {
40390
40863
  }
40391
40864
  function auditMode(templatesDir) {
40392
40865
  const entries = [];
40393
- const agentsDir = join51(templatesDir, "agents");
40866
+ const agentsDir = join54(templatesDir, "agents");
40394
40867
  if (existsSync21(agentsDir)) {
40395
40868
  const agentFiles = readdirSync6(agentsDir).filter((f) => f.endsWith(".md")).sort();
40396
40869
  for (const f of agentFiles) {
40397
- entries.push(auditAgent(join51(agentsDir, f)));
40870
+ entries.push(auditAgent(join54(agentsDir, f)));
40398
40871
  }
40399
40872
  }
40400
- const skillsDir = join51(templatesDir, "skills");
40873
+ const skillsDir = join54(templatesDir, "skills");
40401
40874
  if (existsSync21(skillsDir)) {
40402
40875
  const skillDirs = readdirSync6(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
40403
40876
  for (const dir of skillDirs) {
40404
- if (existsSync21(join51(skillsDir, dir, "PROVENANCE.md"))) continue;
40405
- const skillMd = join51(skillsDir, dir, "SKILL.md");
40877
+ if (existsSync21(join54(skillsDir, dir, "PROVENANCE.md"))) continue;
40878
+ const skillMd = join54(skillsDir, dir, "SKILL.md");
40406
40879
  if (existsSync21(skillMd)) {
40407
40880
  entries.push(auditSkill(skillMd));
40408
40881
  }
@@ -40667,7 +41140,7 @@ __export(new_migration_exports, {
40667
41140
  newMigration: () => newMigration
40668
41141
  });
40669
41142
  import * as fs19 from "node:fs";
40670
- import * as path22 from "node:path";
41143
+ import * as path24 from "node:path";
40671
41144
  function slugify(name) {
40672
41145
  return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "").replace(/_+/g, "_");
40673
41146
  }
@@ -40688,9 +41161,9 @@ function newMigration(args, deps = {}) {
40688
41161
  }
40689
41162
  const slug = slugify(rawName);
40690
41163
  const stamp = genTimestamp({ cwd });
40691
- const migrationsDir = path22.join(cwd, "supabase", "migrations");
41164
+ const migrationsDir = path24.join(cwd, "supabase", "migrations");
40692
41165
  const filename = `${stamp}_${slug}.sql`;
40693
- const filePath = path22.join(migrationsDir, filename);
41166
+ const filePath = path24.join(migrationsDir, filename);
40694
41167
  mkdirSync12(migrationsDir, { recursive: true });
40695
41168
  writeFileSync13(filePath, "");
40696
41169
  process.stdout.write(JSON.stringify({ path: filePath }) + "\n");
@@ -41056,13 +41529,13 @@ function validateWaves(waves) {
41056
41529
  pathOwners.set(file, owners);
41057
41530
  }
41058
41531
  }
41059
- for (const [path23, owners] of pathOwners) {
41532
+ for (const [path25, owners] of pathOwners) {
41060
41533
  if (owners.length > 1) {
41061
41534
  violations.push({
41062
41535
  invariant: "I",
41063
41536
  code: "DUPLICATE_FILE",
41064
- message: `File "${path23}" appears in multiple waves: ${owners.join(", ")}.`,
41065
- detail: { path: path23, waves: owners }
41537
+ message: `File "${path25}" appears in multiple waves: ${owners.join(", ")}.`,
41538
+ detail: { path: path25, waves: owners }
41066
41539
  });
41067
41540
  }
41068
41541
  }
@@ -41156,7 +41629,7 @@ var validate_waves_exports = {};
41156
41629
  __export(validate_waves_exports, {
41157
41630
  runValidateWavesCommand: () => runValidateWavesCommand
41158
41631
  });
41159
- import { readFile as readFile29 } from "node:fs/promises";
41632
+ import { readFile as readFile30 } from "node:fs/promises";
41160
41633
  async function readStdin() {
41161
41634
  return new Promise((resolve17, reject) => {
41162
41635
  const chunks = [];
@@ -41175,7 +41648,7 @@ async function runValidateWavesCommand(args) {
41175
41648
  let raw;
41176
41649
  if (filePath) {
41177
41650
  try {
41178
- raw = await readFile29(filePath, "utf-8");
41651
+ raw = await readFile30(filePath, "utf-8");
41179
41652
  } catch (err) {
41180
41653
  const msg = err instanceof Error ? err.message : String(err);
41181
41654
  process.stderr.write(
@@ -41255,12 +41728,12 @@ var init_validate_waves2 = __esm({
41255
41728
  });
41256
41729
 
41257
41730
  // src/cli/worktree/path.ts
41258
- import { dirname as dirname15, basename as basename4, join as join53 } from "node:path";
41731
+ import { dirname as dirname16, basename as basename5, join as join56 } from "node:path";
41259
41732
  function computeWorktreePath(cwd, checkpointNumber) {
41260
- const parent = dirname15(cwd);
41261
- const base = basename4(cwd);
41733
+ const parent = dirname16(cwd);
41734
+ const base = basename5(cwd);
41262
41735
  const nnn = String(checkpointNumber).padStart(3, "0");
41263
- return join53(parent, `${base}-CHK-${nnn}`);
41736
+ return join56(parent, `${base}-CHK-${nnn}`);
41264
41737
  }
41265
41738
  var init_path = __esm({
41266
41739
  "src/cli/worktree/path.ts"() {
@@ -41269,8 +41742,8 @@ var init_path = __esm({
41269
41742
  });
41270
41743
 
41271
41744
  // src/cli/worktree/add.ts
41272
- import { join as join54 } from "node:path";
41273
- import { mkdir as mkdir13, readFile as readFile30, writeFile as writeFile22 } from "node:fs/promises";
41745
+ import { join as join57 } from "node:path";
41746
+ import { mkdir as mkdir14, readFile as readFile31, writeFile as writeFile23 } from "node:fs/promises";
41274
41747
  import { spawnSync as spawnSync18 } from "node:child_process";
41275
41748
  async function defaultGetRepoId(cwd) {
41276
41749
  const found = await findCodebyplanConfig(cwd);
@@ -41313,17 +41786,17 @@ function defaultGitRun(args, cwd) {
41313
41786
  };
41314
41787
  }
41315
41788
  async function copyClaudeSettings(srcCwd, destPath, deps = {}) {
41316
- const readFileFn = deps.readFileFn ?? ((p) => readFile30(p, "utf-8"));
41317
- const writeFileFn = deps.writeFileFn ?? ((p, content) => writeFile22(p, content, "utf-8"));
41789
+ const readFileFn = deps.readFileFn ?? ((p) => readFile31(p, "utf-8"));
41790
+ const writeFileFn = deps.writeFileFn ?? ((p, content) => writeFile23(p, content, "utf-8"));
41318
41791
  const existsFn = deps.existsFn ?? ((p) => import("node:fs/promises").then(
41319
41792
  (fsp) => fsp.access(p).then(() => true).catch(() => false)
41320
41793
  ));
41321
- const mkdirFn = deps.mkdirFn ?? ((p, opts) => mkdir13(p, opts));
41322
- await mkdirFn(join54(destPath, ".claude"), { recursive: true });
41794
+ const mkdirFn = deps.mkdirFn ?? ((p, opts) => mkdir14(p, opts));
41795
+ await mkdirFn(join57(destPath, ".claude"), { recursive: true });
41323
41796
  const claudeStubs = ["settings.json", "settings.local.json"];
41324
41797
  for (const stub of claudeStubs) {
41325
- const srcFile = join54(srcCwd, ".claude", stub);
41326
- const destFile = join54(destPath, ".claude", stub);
41798
+ const srcFile = join57(srcCwd, ".claude", stub);
41799
+ const destFile = join57(destPath, ".claude", stub);
41327
41800
  try {
41328
41801
  const destExists = await existsFn(destFile);
41329
41802
  if (destExists) continue;
@@ -41334,22 +41807,22 @@ async function copyClaudeSettings(srcCwd, destPath, deps = {}) {
41334
41807
  }
41335
41808
  }
41336
41809
  async function defaultCopyConfigStubs(srcCwd, destPath) {
41337
- await mkdir13(join54(destPath, ".codebyplan"), { recursive: true });
41810
+ await mkdir14(join57(destPath, ".codebyplan"), { recursive: true });
41338
41811
  const topLevelStubs = [".mcp.json", ".env.local"];
41339
41812
  for (const stub of topLevelStubs) {
41340
41813
  try {
41341
- const content = await readFile30(join54(srcCwd, stub), "utf-8");
41342
- await writeFile22(join54(destPath, stub), content, "utf-8");
41814
+ const content = await readFile31(join57(srcCwd, stub), "utf-8");
41815
+ await writeFile23(join57(destPath, stub), content, "utf-8");
41343
41816
  } catch {
41344
41817
  }
41345
41818
  }
41346
41819
  try {
41347
- const content = await readFile30(
41348
- join54(srcCwd, ".codebyplan", "repo.json"),
41820
+ const content = await readFile31(
41821
+ join57(srcCwd, ".codebyplan", "repo.json"),
41349
41822
  "utf-8"
41350
41823
  );
41351
- await writeFile22(
41352
- join54(destPath, ".codebyplan", "repo.json"),
41824
+ await writeFile23(
41825
+ join57(destPath, ".codebyplan", "repo.json"),
41353
41826
  content,
41354
41827
  "utf-8"
41355
41828
  );
@@ -41483,7 +41956,7 @@ var init_add = __esm({
41483
41956
  });
41484
41957
 
41485
41958
  // src/cli/worktree/create.ts
41486
- import { join as join55 } from "node:path";
41959
+ import { join as join58 } from "node:path";
41487
41960
  async function defaultGetRepoIdentity(cwd) {
41488
41961
  const found = await findCodebyplanConfig(cwd);
41489
41962
  const contents = found?.contents ?? null;
@@ -41528,7 +42001,7 @@ async function runWorktreeCreate(args, deps = {}) {
41528
42001
  );
41529
42002
  return 1;
41530
42003
  }
41531
- const worktreePath = explicitPath ?? join55(cwd, "..", name);
42004
+ const worktreePath = explicitPath ?? join58(cwd, "..", name);
41532
42005
  let filesWritten = false;
41533
42006
  try {
41534
42007
  await createWorktreeFiles(
@@ -41938,7 +42411,7 @@ var init_e2e = __esm({
41938
42411
  });
41939
42412
 
41940
42413
  // src/cli/e2e/verify-round.ts
41941
- import { readFile as readFile31 } from "node:fs/promises";
42414
+ import { readFile as readFile32 } from "node:fs/promises";
41942
42415
  import { resolve as resolve15 } from "node:path";
41943
42416
  async function defaultFetchRounds(taskId) {
41944
42417
  return mcpCall("get_rounds", { task_id: taskId });
@@ -41946,7 +42419,7 @@ async function defaultFetchRounds(taskId) {
41946
42419
  async function defaultReadE2eConfig(cwd) {
41947
42420
  try {
41948
42421
  const p = resolve15(cwd, ".codebyplan", "e2e.json");
41949
- const raw = await readFile31(p, "utf-8");
42422
+ const raw = await readFile32(p, "utf-8");
41950
42423
  return JSON.parse(raw);
41951
42424
  } catch {
41952
42425
  return null;
@@ -42113,7 +42586,7 @@ __export(doctor_exports, {
42113
42586
  runDoctor: () => runDoctor
42114
42587
  });
42115
42588
  import { existsSync as existsSync22 } from "node:fs";
42116
- import { join as join56 } from "node:path";
42589
+ import { join as join59 } from "node:path";
42117
42590
  import { execSync as execSync10 } from "node:child_process";
42118
42591
  async function checkAuth() {
42119
42592
  try {
@@ -42190,7 +42663,7 @@ function checkSettings() {
42190
42663
  detail: "codebyplan not installed (no .cbp.manifest.json)"
42191
42664
  };
42192
42665
  }
42193
- if (!existsSync22(join56(projectDir, ".claude", "settings.json"))) {
42666
+ if (!existsSync22(join59(projectDir, ".claude", "settings.json"))) {
42194
42667
  return {
42195
42668
  name: "settings",
42196
42669
  status: "warn",
@@ -42435,6 +42908,11 @@ void (async () => {
42435
42908
  await runRoundCommand2(rest);
42436
42909
  process.exit(0);
42437
42910
  }
42911
+ if (arg === "handoff") {
42912
+ const { runHandoffCommand: runHandoffCommand2 } = await Promise.resolve().then(() => (init_handoff(), handoff_exports));
42913
+ await runHandoffCommand2(process.argv.slice(3));
42914
+ process.exit(process.exitCode ?? 0);
42915
+ }
42438
42916
  if (arg === "branch") {
42439
42917
  const { runBranchCommand: runBranchCommand2 } = await Promise.resolve().then(() => (init_branch(), branch_exports));
42440
42918
  const rest = process.argv.slice(3);
@@ -42772,6 +43250,8 @@ void (async () => {
42772
43250
  codebyplan watch stop Stop the running daemon
42773
43251
  codebyplan watch status Show daemon status (--json for machine-readable)
42774
43252
  codebyplan watch run Run daemon in foreground (used internally by start)
43253
+ codebyplan handoff Manage per-level handoff notes in .codebyplan/handoff/
43254
+ (read/write/append/clear/status -- --level repo|checkpoint|task|standalone)
42775
43255
  codebyplan round sync-approvals Sync git diff and approvals with round/task state
42776
43256
  codebyplan standalone-task Standalone task writes via MCP (create/update/complete)
42777
43257
  (create --title; update --id; complete --id \u2014 no --checkpoint-id)