lalph 0.3.71 → 0.3.73

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.mjs CHANGED
@@ -181199,7 +181199,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
181199
181199
  });
181200
181200
  Ze.glob = Ze;
181201
181201
  //#endregion
181202
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/ApplyPatch.js
181202
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/ApplyPatch.js
181203
181203
  /**
181204
181204
  * @since 1.0.0
181205
181205
  */
@@ -196072,7 +196072,7 @@ var StreamableHTTPClientTransport = class {
196072
196072
  }
196073
196073
  };
196074
196074
  //#endregion
196075
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/McpClient.js
196075
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/McpClient.js
196076
196076
  /**
196077
196077
  * @since 1.0.0
196078
196078
  */
@@ -196117,7 +196117,7 @@ const layer$13 = effect$1(McpClient, gen(function* () {
196117
196117
  });
196118
196118
  }));
196119
196119
  //#endregion
196120
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/ExaSearch.js
196120
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/ExaSearch.js
196121
196121
  /**
196122
196122
  * @since 1.0.0
196123
196123
  */
@@ -211067,7 +211067,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin$1(((exports) => {
211067
211067
  exports.impl = impl;
211068
211068
  }));
211069
211069
  //#endregion
211070
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/WebToMarkdown.js
211070
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/WebToMarkdown.js
211071
211071
  /**
211072
211072
  * @since 1.0.0
211073
211073
  */
@@ -214684,7 +214684,7 @@ const mapProviderResults = (inputLength, results) => {
214684
214684
  return succeed$3(embeddings);
214685
214685
  };
214686
214686
  //#endregion
214687
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/ChunkRepo.js
214687
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/ChunkRepo.js
214688
214688
  /**
214689
214689
  * @since 1.0.0
214690
214690
  * @category Models
@@ -214807,11 +214807,12 @@ const layer$10 = effect$1(ChunkRepo, gen(function* () {
214807
214807
  }),
214808
214808
  quantize: maybeQuantize,
214809
214809
  setSyncId: (chunkId, syncId) => sql`update chunks set syncId = ${syncId} where id = ${chunkId}`.pipe(mapError$2((reason) => new ChunkRepoError({ reason }))),
214810
+ deleteByPath: (path) => sql`delete from chunks where path = ${path}`.pipe(mapError$2((reason) => new ChunkRepoError({ reason }))),
214810
214811
  deleteForSyncId: (syncId) => sql`delete from chunks where syncId != ${syncId}`.pipe(mapError$2((reason) => new ChunkRepoError({ reason })))
214811
214812
  });
214812
214813
  }));
214813
214814
  //#endregion
214814
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/CodeChunker.js
214815
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/CodeChunker.js
214815
214816
  /**
214816
214817
  * @since 1.0.0
214817
214818
  */
@@ -214908,7 +214909,7 @@ const ignoredDirectories = new Set([
214908
214909
  "node_modules",
214909
214910
  "target"
214910
214911
  ]);
214911
- const normalizePath = (path) => path.replace(/\\/g, "/");
214912
+ const normalizePath$1 = (path) => path.replace(/\\/g, "/");
214912
214913
  const normalizeText = (content) => content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
214913
214914
  const hashContent = (content) => createHash("sha256").update(content).digest("hex");
214914
214915
  const meaningfulLinePattern = /[^\s\p{P}]/u;
@@ -214931,7 +214932,7 @@ const isProbablyMinified = (content) => {
214931
214932
  * @category Predicates
214932
214933
  */
214933
214934
  const isMeaningfulFile = (path) => {
214934
- const parts = normalizePath(path).toLowerCase().split("/");
214935
+ const parts = normalizePath$1(path).toLowerCase().split("/");
214935
214936
  const fileName = parts.at(-1);
214936
214937
  if (fileName === void 0 || fileName.length === 0) return false;
214937
214938
  if (parts.some((part) => ignoredDirectories.has(part))) return false;
@@ -214957,7 +214958,7 @@ const resolveChunkSettings = (options) => {
214957
214958
  */
214958
214959
  const chunkFileContent = (path, content, options) => {
214959
214960
  if (content.trim().length === 0 || isProbablyMinified(content)) return [];
214960
- const normalizedPath = normalizePath(path);
214961
+ const normalizedPath = normalizePath$1(path);
214961
214962
  const lines = normalizeText(content).split("\n");
214962
214963
  if (lines.at(-1) === "") lines.pop();
214963
214964
  if (lines.length === 0) return [];
@@ -215005,20 +215006,37 @@ const layer$9 = effect$1(CodeChunker, gen(function* () {
215005
215006
  ], {
215006
215007
  cwd: root,
215007
215008
  stdin: "ignore"
215008
- })), runCollect, map$9(fromIterable$5), map$9((entries) => entries.map((entry) => normalizePath(entry.trim())).filter((entry) => entry.length > 0 && isMeaningfulFile(entry)).sort((left, right) => left.localeCompare(right))), orDie$2);
215009
+ })), runCollect, map$9(fromIterable$5), map$9((entries) => entries.map((entry) => normalizePath$1(entry.trim())).filter((entry) => entry.length > 0 && isMeaningfulFile(entry)).sort((left, right) => left.localeCompare(right))), orDie$2);
215009
215010
  });
215011
+ const chunkFile = fn("CodeChunker.chunkFile")(function* (options) {
215012
+ const root = pathService.resolve(options.root);
215013
+ const absolutePath = pathService.resolve(root, options.path);
215014
+ const path = normalizePath$1(pathService.relative(root, absolutePath));
215015
+ if (path.length === 0 || path === ".." || path.startsWith("../") || !isMeaningfulFile(path)) return [];
215016
+ return yield* pipe$1(fs.readFileString(absolutePath), map$9((content) => chunkFileContent(path, content, options)), catch_$2(() => succeed$3([])));
215017
+ });
215018
+ const chunkFiles = (options) => fromArray(options.paths).pipe(flatMap$2((path) => pipe$1(chunkFile({
215019
+ root: options.root,
215020
+ path,
215021
+ chunkSize: options.chunkSize,
215022
+ chunkOverlap: options.chunkOverlap
215023
+ }), fromArrayEffect), { concurrency: 5 }));
215010
215024
  const chunkCodebase = fnUntraced(function* (options) {
215011
215025
  const root = pathService.resolve(options.root);
215012
- return fromArray(yield* listFiles({
215026
+ return chunkFiles({
215013
215027
  root,
215014
- ...options.maxFileSize === void 0 ? {} : { maxFileSize: options.maxFileSize }
215015
- })).pipe(flatMap$2((path) => {
215016
- const absolutePath = pathService.resolve(root, path);
215017
- return pipe$1(fs.readFileString(absolutePath), map$9((content) => chunkFileContent(path, content, options)), catch_$2(() => succeed$3([])), fromArrayEffect);
215018
- }, { concurrency: 5 }));
215028
+ paths: yield* listFiles({
215029
+ root,
215030
+ ...options.maxFileSize === void 0 ? {} : { maxFileSize: options.maxFileSize }
215031
+ }),
215032
+ chunkSize: options.chunkSize,
215033
+ chunkOverlap: options.chunkOverlap
215034
+ });
215019
215035
  }, unwrap);
215020
215036
  return CodeChunker.of({
215021
215037
  listFiles,
215038
+ chunkFile,
215039
+ chunkFiles,
215022
215040
  chunkCodebase
215023
215041
  });
215024
215042
  }));
@@ -215172,7 +215190,7 @@ const run$1 = /* @__PURE__ */ make$25({});
215172
215190
  */
215173
215191
  const layer$7 = (options) => effectDiscard(run$1(options));
215174
215192
  //#endregion
215175
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/internal/sqlite-vector.js
215193
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/internal/sqlite-vector.js
215176
215194
  /**
215177
215195
  * Binary extension for each platform
215178
215196
  */
@@ -215289,7 +215307,7 @@ function getExtensionPath() {
215289
215307
  throw new ExtensionNotFoundError(`SQLite Vector extension not found for platform: ${getCurrentPlatform()}\n\nThe platform-specific package "${getPlatformPackageName()}" is not installed.\nThis usually happens when:\n 1. Your platform is not supported\n 2. npm failed to install optional dependencies\n 3. You're installing with --no-optional flag\n\nTry running: npm install --force`);
215290
215308
  }
215291
215309
  //#endregion
215292
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/Sqlite.js
215310
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/Sqlite.js
215293
215311
  /**
215294
215312
  * @since 1.0.0
215295
215313
  */
@@ -215319,10 +215337,15 @@ const SqliteLayer = (database) => layer$7({ loader: fromRecord({ "0001_create_ch
215319
215337
  yield* fs.makeDirectory(directory, { recursive: true });
215320
215338
  }))));
215321
215339
  //#endregion
215322
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/SemanticSearch.js
215340
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/SemanticSearch.js
215323
215341
  /**
215324
215342
  * @since 1.0.0
215325
215343
  */
215344
+ const normalizePath = (path) => path.replace(/\\/g, "/");
215345
+ const chunkConfig = {
215346
+ chunkSize: 20,
215347
+ chunkOverlap: 5
215348
+ };
215326
215349
  /**
215327
215350
  * @since 1.0.0
215328
215351
  * @category Services
@@ -215336,44 +215359,60 @@ const layer$6 = (options) => effect$1(SemanticSearch, gen(function* () {
215336
215359
  const chunker = yield* CodeChunker;
215337
215360
  const repo = yield* ChunkRepo;
215338
215361
  const embeddings = yield* EmbeddingModel;
215362
+ const pathService = yield* Path$1;
215363
+ const root = pathService.resolve(options.directory);
215339
215364
  const resolver = embeddings.resolver.pipe(setDelay(options.embeddingBatchSize ?? millis(50)), batchN(options.embeddingBatchSize ?? 500));
215365
+ const concurrency = options.concurrency ?? 2e3;
215340
215366
  const indexHandle = yield* make$56();
215341
215367
  const console = yield* Console$1;
215342
- const runIndex = run$4(indexHandle, gen(function* () {
215343
- const syncId = SyncId.makeUnsafe(crypto.randomUUID());
215344
- yield* logInfo("Starting SemanticSearch index");
215345
- yield* pipe$1(chunker.chunkCodebase({
215346
- root: options.directory,
215347
- chunkSize: 20,
215348
- chunkOverlap: 5
215349
- }), tap(fnUntraced(function* (chunk) {
215368
+ const resolveIndexedPath = (path) => {
215369
+ const absolutePath = pathService.resolve(root, path);
215370
+ const relativePath = normalizePath(pathService.relative(root, absolutePath));
215371
+ if (relativePath.length === 0 || relativePath === ".." || relativePath.startsWith("../")) return none$4();
215372
+ return some$2(relativePath);
215373
+ };
215374
+ const processChunk = fnUntraced(function* (options) {
215375
+ if (options.checkExisting) {
215350
215376
  const id = yield* repo.exists({
215351
- path: chunk.path,
215352
- startLine: chunk.startLine,
215353
- hash: chunk.contentHash
215377
+ path: options.chunk.path,
215378
+ startLine: options.chunk.startLine,
215379
+ hash: options.chunk.contentHash
215354
215380
  });
215355
215381
  if (isSome(id)) {
215356
- yield* repo.setSyncId(id.value, syncId);
215382
+ yield* repo.setSyncId(id.value, options.syncId);
215357
215383
  return;
215358
215384
  }
215359
- const result = yield* request$2(new EmbeddingRequest({ input: `File: ${chunk.path}
215360
- Lines: ${chunk.startLine}-${chunk.endLine}
215385
+ }
215386
+ const result = yield* request$2(new EmbeddingRequest({ input: `File: ${options.chunk.path}
215387
+ Lines: ${options.chunk.startLine}-${options.chunk.endLine}
215361
215388
 
215362
- ${chunk.content}` }), resolver);
215363
- const vector = new Float32Array(result.vector);
215364
- yield* repo.insert(Chunk.insert.makeUnsafe({
215365
- path: chunk.path,
215366
- startLine: chunk.startLine,
215367
- endLine: chunk.endLine,
215368
- hash: chunk.contentHash,
215369
- content: chunk.content,
215370
- vector,
215371
- syncId
215372
- }));
215373
- }, ignore$1({
215374
- log: "Warn",
215375
- message: "Failed to process chunk for embedding"
215376
- }), (effect, chunk) => annotateLogs(effect, { chunk: `${chunk.path}/${chunk.startLine}` })), { concurrency: options.concurrency ?? 2e3 }), runDrain);
215389
+ ${options.chunk.content}` }), resolver);
215390
+ const vector = new Float32Array(result.vector);
215391
+ yield* repo.insert(Chunk.insert.makeUnsafe({
215392
+ path: options.chunk.path,
215393
+ startLine: options.chunk.startLine,
215394
+ endLine: options.chunk.endLine,
215395
+ hash: options.chunk.contentHash,
215396
+ content: options.chunk.content,
215397
+ vector,
215398
+ syncId: options.syncId
215399
+ }));
215400
+ }, ignore$1({
215401
+ log: "Warn",
215402
+ message: "Failed to process chunk for embedding"
215403
+ }), (effect, options) => annotateLogs(effect, { chunk: `${options.chunk.path}/${options.chunk.startLine}` }));
215404
+ const runIndex = run$4(indexHandle, gen(function* () {
215405
+ const syncId = SyncId.makeUnsafe(crypto.randomUUID());
215406
+ yield* logInfo("Starting SemanticSearch index");
215407
+ yield* pipe$1(chunker.chunkCodebase({
215408
+ root,
215409
+ ...chunkConfig
215410
+ }), tap((chunk) => processChunk({
215411
+ chunk,
215412
+ syncId,
215413
+ checkExisting: true
215414
+ }), { concurrency }), runDrain);
215415
+ yield* repo.deleteForSyncId(syncId);
215377
215416
  yield* logInfo("Finished SemanticSearch index");
215378
215417
  }).pipe(withSpan$1("SemanticSearch.index"), withLogSpan("SemanticSearch.index"), provideService$2(Console$1, console)), { onlyIfMissing: true });
215379
215418
  const initialIndex = yield* runIndex;
@@ -215388,19 +215427,50 @@ ${chunk.content}` }), resolver);
215388
215427
  limit: options.limit
215389
215428
  })).map((r) => r.format()).join("\n\n");
215390
215429
  }, orDie$2),
215391
- reindex: asVoid(runIndex)
215430
+ updateFile: fn("SemanticSearch.updateFile")(function* (path) {
215431
+ yield* join$2(initialIndex);
215432
+ const indexedPath = resolveIndexedPath(path);
215433
+ if (isNone(indexedPath)) return;
215434
+ yield* repo.deleteByPath(indexedPath.value);
215435
+ const chunks = yield* chunker.chunkFile({
215436
+ root,
215437
+ path: indexedPath.value,
215438
+ ...chunkConfig
215439
+ });
215440
+ if (chunks.length === 0) return;
215441
+ const syncId = SyncId.makeUnsafe(crypto.randomUUID());
215442
+ yield* pipe$1(fromArray(chunks), tap((chunk) => processChunk({
215443
+ chunk,
215444
+ syncId,
215445
+ checkExisting: false
215446
+ }), { concurrency }), runDrain);
215447
+ }, orDie$2),
215448
+ removeFile: fn("SemanticSearch.removeFile")(function* (path) {
215449
+ yield* join$2(initialIndex);
215450
+ const indexedPath = resolveIndexedPath(path);
215451
+ if (isNone(indexedPath)) return;
215452
+ yield* repo.deleteByPath(indexedPath.value);
215453
+ }, orDie$2)
215392
215454
  });
215393
215455
  })).pipe(provide$3([layer$9, layer$10.pipe(provide$3(SqliteLayer(options.database ?? ".clanka/search.sqlite")))]));
215394
215456
  /**
215395
215457
  * @since 1.0.0
215396
215458
  * @category Utils
215397
215459
  */
215398
- const maybeReindex = serviceOption(SemanticSearch).pipe(flatMap$4(match$10({
215460
+ const maybeUpdateFile = (path) => serviceOption(SemanticSearch).pipe(flatMap$4(match$10({
215461
+ onNone: () => void_$2,
215462
+ onSome: (service) => service.updateFile(path)
215463
+ })));
215464
+ /**
215465
+ * @since 1.0.0
215466
+ * @category Utils
215467
+ */
215468
+ const maybeRemoveFile = (path) => serviceOption(SemanticSearch).pipe(flatMap$4(match$10({
215399
215469
  onNone: () => void_$2,
215400
- onSome: (service) => service.reindex
215470
+ onSome: (service) => service.removeFile(path)
215401
215471
  })));
215402
215472
  //#endregion
215403
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/AgentTools.js
215473
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/AgentTools.js
215404
215474
  /**
215405
215475
  * @since 1.0.0
215406
215476
  */
@@ -215559,12 +215629,14 @@ const AgentToolHandlersNoDeps = AgentToolsWithSearch.toLayer(gen(function* () {
215559
215629
  const path = pathService.resolve(cwd, options.path);
215560
215630
  yield* fs.makeDirectory(pathService.dirname(path), { recursive: true });
215561
215631
  yield* fs.writeFileString(path, options.content);
215562
- yield* maybeReindex;
215632
+ yield* maybeUpdateFile(pathService.relative(cwd, path));
215563
215633
  }, orDie$2),
215564
215634
  removeFile: fn("AgentTools.removeFile")(function* (path) {
215565
215635
  yield* logInfo(`Calling "removeFile"`).pipe(annotateLogs({ path }));
215566
215636
  const cwd = yield* CurrentDirectory;
215567
- return yield* fs.remove(pathService.resolve(cwd, path), { force: true });
215637
+ const absolutePath = pathService.resolve(cwd, path);
215638
+ yield* fs.remove(absolutePath, { force: true });
215639
+ yield* maybeRemoveFile(pathService.relative(cwd, absolutePath));
215568
215640
  }, orDie$2),
215569
215641
  renameFile: fn("AgentTools.renameFile")(function* (options) {
215570
215642
  yield* logInfo(`Calling "renameFile"`).pipe(annotateLogs(options));
@@ -215572,7 +215644,9 @@ const AgentToolHandlersNoDeps = AgentToolsWithSearch.toLayer(gen(function* () {
215572
215644
  const from = pathService.resolve(cwd, options.from);
215573
215645
  const to = pathService.resolve(cwd, options.to);
215574
215646
  yield* fs.makeDirectory(pathService.dirname(to), { recursive: true });
215575
- return yield* fs.rename(from, to);
215647
+ yield* fs.rename(from, to);
215648
+ yield* maybeRemoveFile(pathService.relative(cwd, from));
215649
+ yield* maybeUpdateFile(pathService.relative(cwd, to));
215576
215650
  }, orDie$2),
215577
215651
  mkdir: fn("AgentTools.mkdir")(function* (path) {
215578
215652
  yield* logInfo(`Calling "mkdir"`).pipe(annotateLogs({ path }));
@@ -215659,7 +215733,7 @@ const AgentToolHandlersNoDeps = AgentToolsWithSearch.toLayer(gen(function* () {
215659
215733
  const state = /* @__PURE__ */ new Map();
215660
215734
  const steps = [];
215661
215735
  const out = [];
215662
- const rel = (path) => pathService.relative(cwd, path).replaceAll("\\", "/");
215736
+ const rel = (path) => pathService.relative(cwd, path);
215663
215737
  const load = fn("AgentTools.applyPatch.load")(function* (path, reason) {
215664
215738
  if (state.has(path)) {
215665
215739
  const input = state.get(path);
@@ -215724,17 +215798,20 @@ const AgentToolHandlersNoDeps = AgentToolsWithSearch.toLayer(gen(function* () {
215724
215798
  case "update":
215725
215799
  yield* fs.makeDirectory(pathService.dirname(step.path), { recursive: true });
215726
215800
  yield* fs.writeFileString(step.path, step.next);
215801
+ yield* maybeUpdateFile(rel(step.path));
215727
215802
  break;
215728
215803
  case "move":
215729
215804
  yield* fs.makeDirectory(pathService.dirname(step.movePath), { recursive: true });
215730
215805
  yield* fs.writeFileString(step.movePath, step.next);
215731
215806
  yield* fs.remove(step.path);
215807
+ yield* maybeRemoveFile(rel(step.path));
215808
+ yield* maybeUpdateFile(rel(step.movePath));
215732
215809
  break;
215733
215810
  case "delete":
215734
215811
  yield* fs.remove(step.path);
215812
+ yield* maybeRemoveFile(rel(step.path));
215735
215813
  break;
215736
215814
  }
215737
- yield* maybeReindex;
215738
215815
  return `Success. Updated the following files:\n${out.join("\n")}`;
215739
215816
  }, orDie$2),
215740
215817
  delegate: fn("AgentTools.delegate")(function* (prompt) {
@@ -215756,7 +215833,7 @@ const AgentToolHandlers = AgentToolHandlersNoDeps.pipe(provide$3([layer$12, laye
215756
215833
  AgentToolHandlersNoDeps.pipe(provide$3([mock(ExaSearch)({}), mock(WebToMarkdown)({})]));
215757
215834
  var ApplyPatchError = class extends TaggedClass$2("ApplyPatchError") {};
215758
215835
  //#endregion
215759
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/TypeBuilder.js
215836
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/TypeBuilder.js
215760
215837
  const resolveDocumentation = resolveAt("documentation");
215761
215838
  const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
215762
215839
  const Precedence = {
@@ -216029,7 +216106,7 @@ const render = (schema, options) => {
216029
216106
  return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
216030
216107
  };
216031
216108
  //#endregion
216032
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/ToolkitRenderer.js
216109
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/ToolkitRenderer.js
216033
216110
  /**
216034
216111
  * @since 1.0.0
216035
216112
  */
@@ -216051,7 +216128,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
216051
216128
  }) });
216052
216129
  };
216053
216130
  //#endregion
216054
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/AgentExecutor.js
216131
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/AgentExecutor.js
216055
216132
  /**
216056
216133
  * @since 1.0.0
216057
216134
  */
@@ -216220,7 +216297,7 @@ var QueueWriteStream = class extends Writable {
216220
216297
  }
216221
216298
  };
216222
216299
  //#endregion
216223
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/ScriptExtraction.js
216300
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/ScriptExtraction.js
216224
216301
  const stripWrappingCodeFence = (script) => {
216225
216302
  const lines = script.split(/\r?\n/);
216226
216303
  if (lines.length < 2) return script;
@@ -217753,7 +217830,7 @@ const applySpanTransformer = (transformer, response, options) => {
217753
217830
  });
217754
217831
  };
217755
217832
  //#endregion
217756
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/Agent.js
217833
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/Agent.js
217757
217834
  /**
217758
217835
  * @since 1.0.0
217759
217836
  */
@@ -229066,7 +229143,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
229066
229143
  })));
229067
229144
  });
229068
229145
  //#endregion
229069
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/CodexAuth.js
229146
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/CodexAuth.js
229070
229147
  /**
229071
229148
  * @since 1.0.0
229072
229149
  */
@@ -229286,7 +229363,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
229286
229363
  static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
229287
229364
  };
229288
229365
  //#endregion
229289
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/Codex.js
229366
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/Codex.js
229290
229367
  /**
229291
229368
  * @since 1.0.0
229292
229369
  */
@@ -230598,7 +230675,7 @@ const getUsageDetailNumber = (details, field) => {
230598
230675
  return typeof value === "number" ? value : void 0;
230599
230676
  };
230600
230677
  //#endregion
230601
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/CopilotAuth.js
230678
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/CopilotAuth.js
230602
230679
  /**
230603
230680
  * @since 1.0.0
230604
230681
  */
@@ -230789,7 +230866,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
230789
230866
  static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
230790
230867
  };
230791
230868
  //#endregion
230792
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/Copilot.js
230869
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/Copilot.js
230793
230870
  /**
230794
230871
  * @since 1.0.0
230795
230872
  */
@@ -231209,7 +231286,7 @@ Object.defineProperties(createChalk.prototype, styles);
231209
231286
  const chalk = createChalk();
231210
231287
  createChalk({ level: stderrColor ? stderrColor.level : 0 });
231211
231288
  //#endregion
231212
- //#region node_modules/.pnpm/clanka@0.1.22_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-o_7a4026aab05a714a14be1d2fa397b573/node_modules/clanka/dist/OutputFormatter.js
231289
+ //#region node_modules/.pnpm/clanka@0.2.0_@effect+ai-openai-compat@4.0.0-beta.34_effect@4.0.0-beta.34__@effect+ai-op_eb2d2d405b4b82a47d844a8a6523d5fc/node_modules/clanka/dist/OutputFormatter.js
231213
231290
  /**
231214
231291
  * @since 1.0.0
231215
231292
  */
@@ -239344,6 +239421,8 @@ var Worktree = class extends Service$1()("lalph/Worktree", { make: gen(function*
239344
239421
  };
239345
239422
  }
239346
239423
  const directory = yield* fs.makeTempDirectory();
239424
+ const shared = pathService.resolve(".lalph", "shared");
239425
+ const worktreeShared = pathService.join(directory, ".lalph", "shared");
239347
239426
  yield* addFinalizer(fnUntraced(function* () {
239348
239427
  yield* execIgnore(spawner, make$45`git worktree remove --force ${directory}`);
239349
239428
  }));
@@ -239352,8 +239431,16 @@ var Worktree = class extends Service$1()("lalph/Worktree", { make: gen(function*
239352
239431
  const execHelpers = yield* makeExecHelpers({ directory });
239353
239432
  yield* setupWorktree({
239354
239433
  directory,
239355
- exec: execHelpers.exec
239434
+ exec: execHelpers.exec,
239435
+ shared,
239436
+ worktreeShared
239356
239437
  });
239438
+ yield* addFinalizer(fnUntraced(function* () {
239439
+ yield* copySharedBack({
239440
+ shared,
239441
+ worktreeShared
239442
+ }).pipe(catchCause$1(logWarning));
239443
+ }));
239357
239444
  return {
239358
239445
  directory,
239359
239446
  inExisting,
@@ -239394,9 +239481,8 @@ const setupWorktree = fnUntraced(function* (options) {
239394
239481
  yield* options.exec`git push -u ${parsed.remote} ${parsed.branch}`;
239395
239482
  }
239396
239483
  }
239397
- const shared = pathService.resolve(".lalph", "shared");
239398
- yield* fs.makeDirectory(shared, { recursive: true });
239399
- yield* fs.symlink(shared, pathService.join(options.directory, ".lalph", "shared"));
239484
+ yield* fs.makeDirectory(options.shared, { recursive: true });
239485
+ yield* fs.copy(options.shared, options.worktreeShared, { overwrite: true });
239400
239486
  const cwdSetupPath = pathService.resolve("scripts", "worktree-setup.sh");
239401
239487
  const worktreeSetupPath = pathService.join(options.directory, "scripts", "worktree-setup.sh");
239402
239488
  yield* seedSetupScript(cwdSetupPath);
@@ -239408,6 +239494,17 @@ const setupWorktree = fnUntraced(function* (options) {
239408
239494
  stdout: "inherit"
239409
239495
  })`${setupPath}`.pipe(spawner.exitCode);
239410
239496
  });
239497
+ const copySharedBack = fnUntraced(function* (options) {
239498
+ const fs = yield* FileSystem;
239499
+ const pathService = yield* Path$1;
239500
+ if (!(yield* fs.exists(options.worktreeShared))) return;
239501
+ yield* fs.makeDirectory(pathService.dirname(options.shared), { recursive: true });
239502
+ yield* fs.remove(options.shared, {
239503
+ recursive: true,
239504
+ force: true
239505
+ });
239506
+ yield* fs.copy(options.worktreeShared, options.shared);
239507
+ });
239411
239508
  const getTargetBranch = gen(function* () {
239412
239509
  const project = yield* projectById(yield* CurrentProjectId);
239413
239510
  if (isNone(project)) return none$4();
@@ -239591,7 +239688,7 @@ var Prd = class extends Service$1()("lalph/Prd", { make: gen(function* () {
239591
239688
  if (currentYaml === nextYaml) return;
239592
239689
  yield* fs.writeFileString(prdFile, nextYaml);
239593
239690
  }, scoped$1, withSpan$1("Prd.updateSync"), run$4(updateSyncHandle, { onlyIfMissing: true }), syncSemaphore.withPermitsIfAvailable(1));
239594
- yield* fs.watch(lalphDir).pipe(debounce(50), runForEach((_) => clear(updateSyncHandle).pipe(andThen(ignore$1(sync$3)))), retry$3(forever$1), forkScoped);
239691
+ yield* fs.watch(lalphDir).pipe(filter$3((event) => event.path.endsWith("prd.yml")), debounce(50), runForEach((_) => clear(updateSyncHandle).pipe(andThen(ignore$1(sync$3)))), retry$3(forever$1), forkScoped);
239595
239692
  yield* toStreamResult(registry, currentIssuesAtom(projectId)).pipe(runForEach(updateSync), forkScoped);
239596
239693
  const findById = fnUntraced(function* (issueId) {
239597
239694
  return (yield* getCurrentIssues).find((i) => i.id === issueId) ?? null;
@@ -239932,7 +240029,7 @@ const agentChooser = fnUntraced(function* (options) {
239932
240029
  withChoose: true
239933
240030
  }).pipe(provideService$2(ChosenTaskDeferred, deferred), flatMap$4(() => fail$6(new ChosenTaskNotFound())), raceFirst(_await(deferred)));
239934
240031
  const prdTask = yield* prd.findById(result.taskId);
239935
- if (!prdTask) throw new ChosenTaskNotFound();
240032
+ if (!prdTask) return yield* new ChosenTaskNotFound();
239936
240033
  return {
239937
240034
  id: result.taskId,
239938
240035
  githubPrNumber: result.githubPrNumber ?? null,
@@ -240567,7 +240664,7 @@ const commandEdit = make$58("edit").pipe(withDescription("Open the selected proj
240567
240664
  const commandSource = make$58("source").pipe(withDescription("Select the issue source to use (e.g. GitHub Issues or Linear). This applies to all projects."), withHandler(() => selectIssueSource), provide(Settings.layer));
240568
240665
  //#endregion
240569
240666
  //#region package.json
240570
- var version = "0.3.71";
240667
+ var version = "0.3.73";
240571
240668
  //#endregion
240572
240669
  //#region src/commands/projects/ls.ts
240573
240670
  const commandProjectsLs = make$58("ls").pipe(withDescription("List configured projects and how they run (enabled state, concurrency, branch, git flow, review agent)."), withHandler(fnUntraced(function* () {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.3.71",
4
+ "version": "0.3.73",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -42,7 +42,7 @@
42
42
  "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
43
43
  "@octokit/types": "^16.0.0",
44
44
  "@typescript/native-preview": "7.0.0-dev.20260317.1",
45
- "clanka": "^0.1.22",
45
+ "clanka": "^0.2.0",
46
46
  "concurrently": "^9.2.1",
47
47
  "effect": "4.0.0-beta.34",
48
48
  "husky": "^9.1.7",
@@ -46,7 +46,7 @@ export const agentChooser = Effect.fnUntraced(function* (options: {
46
46
  Effect.raceFirst(Deferred.await(deferred)),
47
47
  )
48
48
  const prdTask = yield* prd.findById(result.taskId)
49
- if (!prdTask) throw new ChosenTaskNotFound()
49
+ if (!prdTask) return yield* new ChosenTaskNotFound()
50
50
  return {
51
51
  id: result.taskId,
52
52
  githubPrNumber: result.githubPrNumber ?? null,
package/src/Prd.ts CHANGED
@@ -231,6 +231,7 @@ export class Prd extends ServiceMap.Service<
231
231
  )
232
232
 
233
233
  yield* fs.watch(lalphDir).pipe(
234
+ Stream.filter((event) => event.path.endsWith("prd.yml")),
234
235
  Stream.debounce(50),
235
236
  Stream.runForEach((_) =>
236
237
  FiberHandle.clear(updateSyncHandle).pipe(
package/src/Worktree.ts CHANGED
@@ -40,6 +40,8 @@ export class Worktree extends ServiceMap.Service<Worktree>()("lalph/Worktree", {
40
40
  }
41
41
 
42
42
  const directory = yield* fs.makeTempDirectory()
43
+ const shared = pathService.resolve(".lalph", "shared")
44
+ const worktreeShared = pathService.join(directory, ".lalph", "shared")
43
45
 
44
46
  yield* Effect.addFinalizer(
45
47
  Effect.fnUntraced(function* () {
@@ -62,8 +64,19 @@ export class Worktree extends ServiceMap.Service<Worktree>()("lalph/Worktree", {
62
64
  yield* setupWorktree({
63
65
  directory,
64
66
  exec: execHelpers.exec,
67
+ shared,
68
+ worktreeShared,
65
69
  })
66
70
 
71
+ yield* Effect.addFinalizer(
72
+ Effect.fnUntraced(function* () {
73
+ yield* copySharedBack({
74
+ shared,
75
+ worktreeShared,
76
+ }).pipe(Effect.catchCause(Effect.logWarning))
77
+ }),
78
+ )
79
+
67
80
  return {
68
81
  directory,
69
82
  inExisting,
@@ -109,6 +122,8 @@ const seedSetupScript = Effect.fnUntraced(function* (setupPath: string) {
109
122
 
110
123
  const setupWorktree = Effect.fnUntraced(function* (options: {
111
124
  readonly directory: string
125
+ readonly shared: string
126
+ readonly worktreeShared: string
112
127
  readonly exec: (
113
128
  template: TemplateStringsArray,
114
129
  ...args: Array<string | number | boolean>
@@ -129,12 +144,10 @@ const setupWorktree = Effect.fnUntraced(function* (options: {
129
144
  }
130
145
  }
131
146
 
132
- const shared = pathService.resolve(".lalph", "shared")
133
- yield* fs.makeDirectory(shared, { recursive: true })
134
- yield* fs.symlink(
135
- shared,
136
- pathService.join(options.directory, ".lalph", "shared"),
137
- )
147
+ yield* fs.makeDirectory(options.shared, { recursive: true })
148
+ yield* fs.copy(options.shared, options.worktreeShared, {
149
+ overwrite: true,
150
+ })
138
151
 
139
152
  const cwdSetupPath = pathService.resolve("scripts", "worktree-setup.sh")
140
153
  const worktreeSetupPath = pathService.join(
@@ -158,6 +171,24 @@ const setupWorktree = Effect.fnUntraced(function* (options: {
158
171
  })`${setupPath}`.pipe(spawner.exitCode)
159
172
  })
160
173
 
174
+ const copySharedBack = Effect.fnUntraced(function* (options: {
175
+ readonly shared: string
176
+ readonly worktreeShared: string
177
+ }) {
178
+ const fs = yield* FileSystem.FileSystem
179
+ const pathService = yield* Path.Path
180
+
181
+ if (!(yield* fs.exists(options.worktreeShared))) {
182
+ return
183
+ }
184
+
185
+ yield* fs.makeDirectory(pathService.dirname(options.shared), {
186
+ recursive: true,
187
+ })
188
+ yield* fs.remove(options.shared, { recursive: true, force: true })
189
+ yield* fs.copy(options.worktreeShared, options.shared)
190
+ })
191
+
161
192
  const getTargetBranch = Effect.gen(function* () {
162
193
  const projectId = yield* CurrentProjectId
163
194
  const project = yield* projectById(projectId)