lalph 0.3.45 → 0.3.46

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
@@ -180191,7 +180191,7 @@ ${options.gitFlow.reviewInstructions}
180191
180191
  # Previous instructions (only for context, do not repeat)
180192
180192
 
180193
180193
  ${options.prompt}`;
180194
- const promptReviewCustom = (options) => `${options.prompt}
180194
+ const promptReviewCustom = (options) => options.removePrdNotes ? options.prompt : `${options.prompt}
180195
180195
 
180196
180196
  ${prdNotes(options)}`;
180197
180197
  const promptTimeout = (options) => `Your earlier attempt to complete the task with id \`${options.taskId}\` took too
@@ -187991,7 +187991,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
187991
187991
  });
187992
187992
  Ze.glob = Ze;
187993
187993
  //#endregion
187994
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/ApplyPatch.js
187994
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/ApplyPatch.js
187995
187995
  /**
187996
187996
  * @since 1.0.0
187997
187997
  */
@@ -188019,17 +188019,27 @@ const locate = (text) => {
188019
188019
  end
188020
188020
  };
188021
188021
  };
188022
+ const parseChunkHeader = (line) => {
188023
+ if (line === "@@") return;
188024
+ const unified = line.match(/^@@\s+-\d+(?:,\d+)?\s+\+\d+(?:,\d+)?\s+@@(?:\s?(.*))?$/);
188025
+ if (unified) {
188026
+ const ctx = unified[1]?.trim();
188027
+ return ctx === void 0 || ctx.length === 0 ? void 0 : ctx;
188028
+ }
188029
+ const ctx = line.slice(2).trim();
188030
+ return ctx.length === 0 ? void 0 : ctx;
188031
+ };
188022
188032
  const parseChunks = (lines, start, end = lines.length) => {
188023
188033
  const chunks = Array();
188024
188034
  let i = start;
188025
188035
  while (i < end) {
188026
188036
  const line = lines[i];
188027
- if (line.startsWith("***")) break;
188037
+ if (line.startsWith("***") || line.startsWith("diff --git ")) break;
188028
188038
  if (!line.startsWith("@@")) {
188029
188039
  i++;
188030
188040
  continue;
188031
188041
  }
188032
- const ctx = line.slice(2).trim();
188042
+ const ctx = parseChunkHeader(line);
188033
188043
  const old = Array();
188034
188044
  const next = Array();
188035
188045
  let eof = false;
@@ -188041,19 +188051,20 @@ const parseChunks = (lines, start, end = lines.length) => {
188041
188051
  i++;
188042
188052
  break;
188043
188053
  }
188044
- if (line.startsWith("@@") || line.startsWith("***")) break;
188054
+ if (line.startsWith("@@") || line.startsWith("***") || line.startsWith("diff --git ")) break;
188045
188055
  if (line.startsWith(" ")) {
188046
188056
  const text = line.slice(1);
188047
188057
  old.push(text);
188048
188058
  next.push(text);
188049
188059
  } else if (line.startsWith("-")) old.push(line.slice(1));
188050
188060
  else if (line.startsWith("+")) next.push(line.slice(1));
188061
+ else if (line === "\") {}
188051
188062
  i++;
188052
188063
  }
188053
188064
  chunks.push({
188054
188065
  old,
188055
188066
  next,
188056
- ...ctx.length > 0 ? { ctx } : {},
188067
+ ...ctx === void 0 ? {} : { ctx },
188057
188068
  ...eof ? { eof: true } : {}
188058
188069
  });
188059
188070
  }
@@ -188076,64 +188087,158 @@ const parseAdd = (lines, start, end) => {
188076
188087
  next: i
188077
188088
  };
188078
188089
  };
188079
- const parsePatch = (input) => {
188080
- const text = normalize(input);
188081
- if (text.length === 0) throw new Error("patchText is required");
188082
- if (text === `${BEGIN}\n${END}`) throw new Error("patch rejected: empty patch");
188083
- const { lines, begin, end } = locate(text);
188090
+ const normalizeDiffPath = (path) => {
188091
+ if (path === "/dev/null") return path;
188092
+ if (path.startsWith("a/") || path.startsWith("b/")) return path.slice(2);
188093
+ return path;
188094
+ };
188095
+ const parseHeaderPath = (line, prefix) => {
188096
+ const body = line.slice(prefix.length);
188097
+ const tabIndex = body.indexOf(" ");
188098
+ return normalizeDiffPath((tabIndex === -1 ? body : body.slice(0, tabIndex)).trim());
188099
+ };
188100
+ const parseDiffGitPaths = (line) => {
188101
+ const match = line.match(/^diff --git a\/(.+) b\/(.+)$/);
188102
+ if (!match) return;
188103
+ return [match[1], match[2]];
188104
+ };
188105
+ const hasDiffHeaders = (lines) => lines.some((line) => line.startsWith("diff --git ") || line.startsWith("--- ") || line.startsWith("rename from ") || line.startsWith("rename to "));
188106
+ const parseGitPatch = (text) => {
188107
+ const lines = text.split("\n");
188084
188108
  const out = Array();
188085
- let i = begin + 1;
188086
- while (i < end) {
188087
- while (i < end && lines[i].trim() === "") i++;
188088
- if (i === end) break;
188089
- const line = lines[i];
188090
- if (line.startsWith(ADD)) {
188091
- const path = line.slice(13).trim();
188092
- if (path.length === 0) fail("missing add file path");
188093
- const parsed = parseAdd(lines, i + 1, end);
188109
+ let i = 0;
188110
+ while (i < lines.length) {
188111
+ while (i < lines.length && lines[i].trim() === "") i++;
188112
+ if (i >= lines.length) break;
188113
+ let oldPath;
188114
+ let newPath;
188115
+ let renameFrom;
188116
+ let renameTo;
188117
+ if (lines[i].startsWith("diff --git ")) {
188118
+ const parsedPaths = parseDiffGitPaths(lines[i]);
188119
+ if (!parsedPaths) return fail(`invalid git diff header: ${lines[i]}`);
188120
+ const [parsedOldPath, parsedNewPath] = parsedPaths;
188121
+ oldPath = parsedOldPath;
188122
+ newPath = parsedNewPath;
188123
+ i++;
188124
+ }
188125
+ while (i < lines.length) {
188126
+ const line = lines[i];
188127
+ if (line.startsWith("diff --git ")) break;
188128
+ if (line.startsWith("rename from ")) {
188129
+ renameFrom = line.slice(12).trim();
188130
+ i++;
188131
+ continue;
188132
+ }
188133
+ if (line.startsWith("rename to ")) {
188134
+ renameTo = line.slice(10).trim();
188135
+ i++;
188136
+ continue;
188137
+ }
188138
+ if (line.startsWith("--- ")) {
188139
+ oldPath = parseHeaderPath(line, "--- ");
188140
+ i++;
188141
+ if (i >= lines.length || !lines[i].startsWith("+++ ")) fail("missing new file header");
188142
+ newPath = parseHeaderPath(lines[i], "+++ ");
188143
+ i++;
188144
+ break;
188145
+ }
188146
+ if (line.startsWith("@@")) break;
188147
+ i++;
188148
+ }
188149
+ const parsed = parseChunks(lines, i);
188150
+ i = parsed.next;
188151
+ const fromPath = normalizeDiffPath(renameFrom ?? oldPath ?? "/dev/null");
188152
+ const toPath = normalizeDiffPath(renameTo ?? newPath ?? fromPath);
188153
+ if (fromPath === "/dev/null") {
188154
+ if (toPath === "/dev/null") fail("invalid diff: both file paths are /dev/null");
188094
188155
  out.push({
188095
188156
  type: "add",
188096
- path,
188097
- content: parsed.content
188157
+ path: toPath,
188158
+ content: patchChunks(toPath, "", parsed.chunks)
188098
188159
  });
188099
- i = parsed.next;
188100
188160
  continue;
188101
188161
  }
188102
- if (line.startsWith(DELETE)) {
188103
- const path = line.slice(16).trim();
188104
- if (path.length === 0) fail("missing delete file path");
188162
+ if (toPath === "/dev/null") {
188105
188163
  out.push({
188106
188164
  type: "delete",
188107
- path
188165
+ path: fromPath
188108
188166
  });
188109
- i++;
188110
188167
  continue;
188111
188168
  }
188112
- if (line.startsWith(UPDATE)) {
188113
- const path = line.slice(16).trim();
188114
- if (path.length === 0) fail("missing update file path");
188115
- i++;
188116
- let movePath;
188117
- if (i < end && lines[i].startsWith(MOVE)) {
188118
- movePath = lines[i].slice(12).trim();
188119
- if (movePath.length === 0) fail("missing move file path");
188169
+ if (parsed.chunks.length === 0 && fromPath === toPath) fail(`no hunks found for ${fromPath}`);
188170
+ out.push({
188171
+ type: "update",
188172
+ path: fromPath,
188173
+ chunks: parsed.chunks,
188174
+ ...toPath === fromPath ? {} : { movePath: toPath }
188175
+ });
188176
+ }
188177
+ if (out.length === 0) fail("no hunks found");
188178
+ return out;
188179
+ };
188180
+ const parsePatch = (input) => {
188181
+ const text = normalize(input);
188182
+ if (text.length === 0) throw new Error("patchText is required");
188183
+ if (text === `${BEGIN}\n${END}`) throw new Error("patch rejected: empty patch");
188184
+ if (text.startsWith(BEGIN)) {
188185
+ const { lines, begin, end } = locate(text);
188186
+ const out = Array();
188187
+ let i = begin + 1;
188188
+ while (i < end) {
188189
+ while (i < end && lines[i].trim() === "") i++;
188190
+ if (i === end) break;
188191
+ const line = lines[i];
188192
+ if (line.startsWith(ADD)) {
188193
+ const path = line.slice(13).trim();
188194
+ if (path.length === 0) fail("missing add file path");
188195
+ const parsed = parseAdd(lines, i + 1, end);
188196
+ out.push({
188197
+ type: "add",
188198
+ path,
188199
+ content: parsed.content
188200
+ });
188201
+ i = parsed.next;
188202
+ continue;
188203
+ }
188204
+ if (line.startsWith(DELETE)) {
188205
+ const path = line.slice(16).trim();
188206
+ if (path.length === 0) fail("missing delete file path");
188207
+ out.push({
188208
+ type: "delete",
188209
+ path
188210
+ });
188120
188211
  i++;
188212
+ continue;
188121
188213
  }
188122
- const parsed = parseChunks(lines, i, end);
188123
- if (parsed.chunks.length === 0) fail("no hunks found");
188124
- out.push({
188125
- type: "update",
188126
- path,
188127
- chunks: parsed.chunks,
188128
- ...movePath === void 0 ? {} : { movePath }
188129
- });
188130
- i = parsed.next;
188131
- continue;
188214
+ if (line.startsWith(UPDATE)) {
188215
+ const path = line.slice(16).trim();
188216
+ if (path.length === 0) fail("missing update file path");
188217
+ i++;
188218
+ let movePath;
188219
+ if (i < end && lines[i].startsWith(MOVE)) {
188220
+ movePath = lines[i].slice(12).trim();
188221
+ if (movePath.length === 0) fail("missing move file path");
188222
+ i++;
188223
+ }
188224
+ const parsed = parseChunks(lines, i, end);
188225
+ if (parsed.chunks.length === 0) fail("no hunks found");
188226
+ out.push({
188227
+ type: "update",
188228
+ path,
188229
+ chunks: parsed.chunks,
188230
+ ...movePath === void 0 ? {} : { movePath }
188231
+ });
188232
+ i = parsed.next;
188233
+ continue;
188234
+ }
188235
+ fail(`unexpected line in wrapped patch: ${line}`);
188132
188236
  }
188133
- fail(`unexpected line in wrapped patch: ${line}`);
188237
+ if (out.length === 0) fail("no hunks found");
188238
+ return out;
188134
188239
  }
188135
- if (out.length === 0) fail("no hunks found");
188136
- return out;
188240
+ if (hasDiffHeaders(text.split("\n"))) return parseGitPatch(text);
188241
+ return fail("Invalid patch format: expected git/unified diff");
188137
188242
  };
188138
188243
  const normalizeUnicode = (line) => line.replace(/[\u2018\u2019\u201A\u201B]/g, "'").replace(/[\u201C\u201D\u201E\u201F]/g, "\"").replace(/[\u2010\u2011\u2012\u2013\u2014\u2015]/g, "-").replace(/\u2026/g, "...").replace(/\u00A0/g, " ");
188139
188244
  const match = (lines, part, from, same, eof) => {
@@ -188215,7 +188320,7 @@ const patchChunks = (file, input, chunks) => {
188215
188320
  return eol === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
188216
188321
  };
188217
188322
  //#endregion
188218
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/AgentTools.js
188323
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/AgentTools.js
188219
188324
  /**
188220
188325
  * @since 1.0.0
188221
188326
  */
@@ -188247,15 +188352,15 @@ const AgentTools = make$9(make$7("readFile", {
188247
188352
  }),
188248
188353
  success: NullOr(String$1),
188249
188354
  dependencies: [CurrentDirectory]
188250
- }), make$7("createFile", {
188251
- description: "Write content to a file, creating parent directories if needed.",
188355
+ }), make$7("writeFile", {
188356
+ description: "Write content to a file, creating parent directories if needed. PREFER USING applyPatch to update existing files.",
188252
188357
  parameters: Struct({
188253
188358
  path: String$1,
188254
188359
  content: String$1
188255
188360
  }),
188256
188361
  dependencies: [CurrentDirectory]
188257
188362
  }), make$7("applyPatch", {
188258
- description: "Apply a wrapped patch with Add/Delete/Update sections.",
188363
+ description: "Apply a git diff / unified diff patch across one or more files.",
188259
188364
  parameters: String$1.annotate({ identifier: "patch" }),
188260
188365
  success: String$1,
188261
188366
  dependencies: [CurrentDirectory]
@@ -188341,8 +188446,8 @@ const AgentToolHandlers = AgentTools.toLayer(gen(function* () {
188341
188446
  if (options.endLine) stream = take(stream, options.endLine - (options.startLine ?? 1) + 1);
188342
188447
  return yield* runCollect(stream).pipe(map$8(join$3("\n")), catchReason("PlatformError", "NotFound", () => succeed$3(null)), orDie$2);
188343
188448
  }),
188344
- createFile: fn("AgentTools.createFile")(function* (options) {
188345
- yield* logInfo(`Calling "createFile"`).pipe(annotateLogs({ path: options.path }));
188449
+ writeFile: fn("AgentTools.writeFile")(function* (options) {
188450
+ yield* logInfo(`Calling "writeFile"`).pipe(annotateLogs({ path: options.path }));
188346
188451
  const cwd = yield* CurrentDirectory;
188347
188452
  const path = pathService.resolve(cwd, options.path);
188348
188453
  if (yield* fs.exists(path)) return yield* die$2("File already exists");
@@ -188511,7 +188616,7 @@ const AgentToolHandlers = AgentTools.toLayer(gen(function* () {
188511
188616
  }));
188512
188617
  var ApplyPatchError = class extends TaggedClass$1("ApplyPatchError") {};
188513
188618
  //#endregion
188514
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/Executor.js
188619
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/Executor.js
188515
188620
  /**
188516
188621
  * @since 1.0.0
188517
188622
  */
@@ -188591,7 +188696,7 @@ var QueueWriteStream = class extends Writable {
188591
188696
  }
188592
188697
  };
188593
188698
  //#endregion
188594
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/TypeBuilder.js
188699
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/TypeBuilder.js
188595
188700
  const resolveDocumentation = resolveAt("documentation");
188596
188701
  const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
188597
188702
  const Precedence = {
@@ -188864,7 +188969,7 @@ const render = (schema, options) => {
188864
188969
  return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
188865
188970
  };
188866
188971
  //#endregion
188867
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/ToolkitRenderer.js
188972
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/ToolkitRenderer.js
188868
188973
  /**
188869
188974
  * @since 1.0.0
188870
188975
  */
@@ -188886,7 +188991,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
188886
188991
  }) });
188887
188992
  };
188888
188993
  //#endregion
188889
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/Agent.js
188994
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/Agent.js
188890
188995
  /**
188891
188996
  * @since 1.0.0
188892
188997
  */
@@ -189527,7 +189632,7 @@ var Retry = class Retry extends TaggedClass$1("Retry") {
189527
189632
  }
189528
189633
  };
189529
189634
  //#endregion
189530
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/Generated.js
189635
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/Generated.js
189531
189636
  /**
189532
189637
  * @since 1.0.0
189533
189638
  */ const AdminApiKey = /* @__PURE__ */ Struct({
@@ -195933,6 +196038,13 @@ const ResponseStreamEvent = /* @__PURE__ */ Union([
195933
196038
  ResponseInProgressEvent,
195934
196039
  ResponseFailedEvent,
195935
196040
  ResponseIncompleteEvent,
196041
+ /* @__PURE__ */ Struct({
196042
+ "type": Literal("keepalive").annotate({ "description": "The type of the keepalive event. Always `keepalive`." }),
196043
+ "sequence_number": Number$1.annotate({ "description": "The sequence number of this keepalive event." }).check(isInt())
196044
+ }).annotate({
196045
+ "title": "Keep alive",
196046
+ "description": "A keepalive event emitted during long-running response streams."
196047
+ }),
195936
196048
  ResponseOutputItemAddedEvent,
195937
196049
  ResponseOutputItemDoneEvent,
195938
196050
  ResponseReasoningSummaryPartAddedEvent,
@@ -197588,7 +197700,7 @@ const OpenAiClientError = (tag, cause, response) => new OpenAiClientErrorImpl({
197588
197700
  request: response.request
197589
197701
  });
197590
197702
  //#endregion
197591
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/internal/errors.js
197703
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/internal/errors.js
197592
197704
  /** @internal */
197593
197705
  const OpenAiErrorBody$1 = /* @__PURE__ */ Struct({ error: /* @__PURE__ */ Struct({
197594
197706
  message: String$1,
@@ -197801,7 +197913,7 @@ const mapStatusCodeToReason$1 = ({ status, headers, message, metadata, http }) =
197801
197913
  }
197802
197914
  };
197803
197915
  //#endregion
197804
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiConfig.js
197916
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiConfig.js
197805
197917
  /**
197806
197918
  * @since 1.0.0
197807
197919
  */
@@ -197816,7 +197928,7 @@ var OpenAiConfig$1 = class OpenAiConfig$1 extends Service$1()("@effect/ai-openai
197816
197928
  static getOrUndefined = /* @__PURE__ */ map$8(/* @__PURE__ */ services(), (context) => context.mapUnsafe.get(OpenAiConfig$1.key));
197817
197929
  };
197818
197930
  //#endregion
197819
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiClient.js
197931
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiClient.js
197820
197932
  /**
197821
197933
  * OpenAI Client module for interacting with OpenAI's API.
197822
197934
  *
@@ -197887,7 +197999,7 @@ const make$3 = /* @__PURE__ */ fnUntraced(function* (options) {
197887
197999
  */
197888
198000
  const layer$3 = (options) => effect$1(OpenAiClient$1, make$3(options));
197889
198001
  //#endregion
197890
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/internal/utilities.js
198002
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/internal/utilities.js
197891
198003
  const finishReasonMap$1 = {
197892
198004
  content_filter: "content-filter",
197893
198005
  function_call: "tool-calls",
@@ -197905,7 +198017,7 @@ const resolveFinishReason$1 = (finishReason, hasToolCalls) => {
197905
198017
  return reason;
197906
198018
  };
197907
198019
  //#endregion
197908
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiTelemetry.js
198020
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiTelemetry.js
197909
198021
  /**
197910
198022
  * OpenAI telemetry attributes for OpenTelemetry integration.
197911
198023
  *
@@ -197934,7 +198046,7 @@ const addGenAIAnnotations$1 = /* @__PURE__ */ dual(2, (span, options) => {
197934
198046
  }
197935
198047
  });
197936
198048
  //#endregion
197937
- //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiLanguageModel.js
198049
+ //#region node_modules/.pnpm/@effect+ai-openai@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai/dist/OpenAiLanguageModel.js
197938
198050
  /**
197939
198051
  * OpenAI Language Model implementation.
197940
198052
  *
@@ -199647,7 +199759,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
199647
199759
  })));
199648
199760
  });
199649
199761
  //#endregion
199650
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/CodexAuth.js
199762
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/CodexAuth.js
199651
199763
  /**
199652
199764
  * @since 1.0.0
199653
199765
  */
@@ -199867,7 +199979,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
199867
199979
  static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
199868
199980
  };
199869
199981
  //#endregion
199870
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/Codex.js
199982
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/Codex.js
199871
199983
  /**
199872
199984
  * @since 1.0.0
199873
199985
  */
@@ -199896,7 +200008,7 @@ const model$1 = (model, options) => make$6("openai", model, merge$5(layer$2({
199896
200008
  supportsNoTools: options?.supportsNoTools ?? true
199897
200009
  })).pipe(provide$3(layerClient$1)));
199898
200010
  //#endregion
199899
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/internal/errors.js
200011
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/internal/errors.js
199900
200012
  /** @internal */
199901
200013
  const OpenAiErrorBody = /* @__PURE__ */ Struct({ error: /* @__PURE__ */ Struct({
199902
200014
  message: String$1,
@@ -200104,7 +200216,7 @@ const mapStatusCodeToReason = ({ status, headers, message, metadata, http }) =>
200104
200216
  }
200105
200217
  };
200106
200218
  //#endregion
200107
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiConfig.js
200219
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiConfig.js
200108
200220
  /**
200109
200221
  * @since 1.0.0
200110
200222
  */
@@ -200119,7 +200231,7 @@ var OpenAiConfig = class OpenAiConfig extends Service$1()("@effect/ai-openai-com
200119
200231
  static getOrUndefined = /* @__PURE__ */ map$8(/* @__PURE__ */ services(), (context) => context.mapUnsafe.get(OpenAiConfig.key));
200120
200232
  };
200121
200233
  //#endregion
200122
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiClient.js
200234
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiClient.js
200123
200235
  /**
200124
200236
  * @since 1.0.0
200125
200237
  */
@@ -200188,27 +200300,34 @@ const CreateEmbeddingResponseSchema = /* @__PURE__ */ Struct({
200188
200300
  total_tokens: Number$1
200189
200301
  }))
200190
200302
  });
200191
- const ChatCompletionToolCall = /* @__PURE__ */ Struct({
200192
- id: /* @__PURE__ */ optionalKey(String$1),
200193
- index: /* @__PURE__ */ optionalKey(Number$1),
200194
- type: /* @__PURE__ */ optionalKey(String$1),
200195
- function: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Struct({
200196
- name: String$1,
200197
- arguments: /* @__PURE__ */ optionalKey(String$1)
200198
- }))
200199
- });
200200
200303
  const ChatCompletionChoice = /* @__PURE__ */ Struct({
200201
200304
  index: Number$1,
200202
200305
  finish_reason: /* @__PURE__ */ optionalKey(/* @__PURE__ */ NullOr(String$1)),
200203
200306
  message: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Struct({
200204
200307
  role: /* @__PURE__ */ optionalKey(String$1),
200205
200308
  content: /* @__PURE__ */ optionalKey(/* @__PURE__ */ NullOr(String$1)),
200206
- tool_calls: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Array$1(ChatCompletionToolCall))
200309
+ tool_calls: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Array$1(/* @__PURE__ */ Struct({
200310
+ id: /* @__PURE__ */ optionalKey(String$1),
200311
+ index: /* @__PURE__ */ optionalKey(Number$1),
200312
+ type: /* @__PURE__ */ optionalKey(String$1),
200313
+ function: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Struct({
200314
+ name: String$1,
200315
+ arguments: /* @__PURE__ */ optionalKey(String$1)
200316
+ }))
200317
+ })))
200207
200318
  })),
200208
200319
  delta: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Struct({
200209
200320
  role: /* @__PURE__ */ optionalKey(String$1),
200210
200321
  content: /* @__PURE__ */ optionalKey(/* @__PURE__ */ NullOr(String$1)),
200211
- tool_calls: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Array$1(ChatCompletionToolCall))
200322
+ tool_calls: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Array$1(/* @__PURE__ */ Struct({
200323
+ id: /* @__PURE__ */ optionalKey(String$1),
200324
+ index: /* @__PURE__ */ optionalKey(Number$1),
200325
+ type: /* @__PURE__ */ optionalKey(String$1),
200326
+ function: /* @__PURE__ */ optionalKey(/* @__PURE__ */ Struct({
200327
+ name: /* @__PURE__ */ optionalKey(String$1),
200328
+ arguments: /* @__PURE__ */ optionalKey(String$1)
200329
+ }))
200330
+ })))
200212
200331
  }))
200213
200332
  });
200214
200333
  const ChatCompletionUsage = /* @__PURE__ */ Struct({
@@ -200248,7 +200367,7 @@ const decodeChatCompletionSseData = (data) => {
200248
200367
  return isChatCompletionChunk(parsed) ? parsed : void 0;
200249
200368
  };
200250
200369
  //#endregion
200251
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/internal/utilities.js
200370
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/internal/utilities.js
200252
200371
  const finishReasonMap = {
200253
200372
  content_filter: "content-filter",
200254
200373
  function_call: "tool-calls",
@@ -200264,7 +200383,7 @@ const resolveFinishReason = (finishReason, hasToolCalls) => {
200264
200383
  return reason;
200265
200384
  };
200266
200385
  //#endregion
200267
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiTelemetry.js
200386
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiTelemetry.js
200268
200387
  /**
200269
200388
  * OpenAI telemetry attributes for OpenTelemetry integration.
200270
200389
  *
@@ -200293,7 +200412,7 @@ const addGenAIAnnotations = /* @__PURE__ */ dual(2, (span, options) => {
200293
200412
  }
200294
200413
  });
200295
200414
  //#endregion
200296
- //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiLanguageModel.js
200415
+ //#region node_modules/.pnpm/@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30/node_modules/@effect/ai-openai-compat/dist/OpenAiLanguageModel.js
200297
200416
  /**
200298
200417
  * OpenAI Language Model implementation.
200299
200418
  *
@@ -200751,11 +200870,11 @@ const makeStreamResponse = /* @__PURE__ */ fnUntraced(function* ({ stream, respo
200751
200870
  hasToolCalls = hasToolCalls || choice.delta.tool_calls.length > 0;
200752
200871
  choice.delta.tool_calls.forEach((deltaTool, indexInChunk) => {
200753
200872
  const toolIndex = deltaTool.index ?? indexInChunk;
200754
- const toolId = deltaTool.id ?? `${event.id}_tool_${toolIndex}`;
200873
+ const activeToolCall = activeToolCalls[toolIndex];
200874
+ const toolId = activeToolCall?.id ?? deltaTool.id ?? `${event.id}_tool_${toolIndex}`;
200755
200875
  const providerToolName = deltaTool.function?.name;
200756
- const toolName = toolNameMapper.getCustomName(providerToolName ?? "unknown_tool");
200876
+ const toolName = providerToolName !== void 0 ? toolNameMapper.getCustomName(providerToolName) : activeToolCall?.name ?? toolNameMapper.getCustomName("unknown_tool");
200757
200877
  const argumentsDelta = deltaTool.function?.arguments ?? "";
200758
- const activeToolCall = activeToolCalls[toolIndex];
200759
200878
  if (isUndefined(activeToolCall)) {
200760
200879
  activeToolCalls[toolIndex] = {
200761
200880
  id: toolId,
@@ -201175,7 +201294,7 @@ const getUsageDetailNumber = (details, field) => {
201175
201294
  return typeof value === "number" ? value : void 0;
201176
201295
  };
201177
201296
  //#endregion
201178
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/CopilotAuth.js
201297
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/CopilotAuth.js
201179
201298
  /**
201180
201299
  * @since 1.0.0
201181
201300
  */
@@ -201366,7 +201485,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
201366
201485
  static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
201367
201486
  };
201368
201487
  //#endregion
201369
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/Copilot.js
201488
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/Copilot.js
201370
201489
  /**
201371
201490
  * @since 1.0.0
201372
201491
  */
@@ -201789,7 +201908,7 @@ Object.defineProperties(createChalk.prototype, styles);
201789
201908
  const chalk = createChalk();
201790
201909
  createChalk({ level: stderrColor ? stderrColor.level : 0 });
201791
201910
  //#endregion
201792
- //#region node_modules/.pnpm/clanka@0.0.15_@effect+ai-openai-compat@4.0.0-beta.29_effect@4.0.0-beta.30__@effect+ai-o_cb421abed6b4689eec8c33622f2a024f/node_modules/clanka/dist/OutputFormatter.js
201911
+ //#region node_modules/.pnpm/clanka@0.0.16_@effect+ai-openai-compat@4.0.0-beta.30_effect@4.0.0-beta.30__@effect+ai-o_a5af971af29a90bb95c8868bd6eda6a9/node_modules/clanka/dist/OutputFormatter.js
201793
201912
  /**
201794
201913
  * @since 1.0.0
201795
201914
  */
@@ -201833,19 +201952,20 @@ const doneIcon = "";
201833
201952
  //#endregion
201834
201953
  //#region src/TaskTools.ts
201835
201954
  var ChosenTaskDeferred = class extends Reference("lalph/TaskTools/ChosenTaskDeferred", { defaultValue: makeUnsafe$13 }) {};
201955
+ const TaskList = Array$1(Struct({
201956
+ id: String$1.annotate({ documentation: "The unique identifier of the task." }),
201957
+ ...pick(PrdIssue.fields, [
201958
+ "title",
201959
+ "description",
201960
+ "state",
201961
+ "priority",
201962
+ "estimate",
201963
+ "blockedBy"
201964
+ ])
201965
+ }));
201836
201966
  var TaskTools = class extends make$9(make$7("listTasks", {
201837
201967
  description: "Returns the current list of tasks.",
201838
- success: Array$1(Struct({
201839
- id: String$1.annotate({ documentation: "The unique identifier of the task." }),
201840
- ...pick(PrdIssue.fields, [
201841
- "title",
201842
- "description",
201843
- "state",
201844
- "priority",
201845
- "estimate",
201846
- "blockedBy"
201847
- ])
201848
- })),
201968
+ success: TaskList,
201849
201969
  dependencies: [CurrentProjectId]
201850
201970
  }), make$7("createTask", {
201851
201971
  description: "Create a new task and return it's id.",
@@ -201869,6 +201989,10 @@ var TaskTools = class extends make$9(make$7("listTasks", {
201869
201989
  blockedBy: optional$2(PrdIssue.fields.blockedBy)
201870
201990
  }),
201871
201991
  dependencies: [CurrentProjectId]
201992
+ }), make$7("removeTask", {
201993
+ description: "Remove a task by it's id.",
201994
+ parameters: String$1.annotate({ identifier: "taskId" }),
201995
+ dependencies: [CurrentProjectId]
201872
201996
  })) {};
201873
201997
  var TaskToolsWithChoose = class extends merge(TaskTools, make$9(make$7("chooseTask", {
201874
201998
  description: "Choose the task to work on",
@@ -201876,6 +202000,10 @@ var TaskToolsWithChoose = class extends merge(TaskTools, make$9(make$7("chooseTa
201876
202000
  taskId: String$1,
201877
202001
  githubPrNumber: optional$2(Number$1)
201878
202002
  })
202003
+ }), make$7("listEligibleTasks", {
202004
+ description: "List tasks eligible for being chosen with chooseTask.",
202005
+ success: TaskList,
202006
+ dependencies: [CurrentProjectId]
201879
202007
  }))) {};
201880
202008
  const TaskToolsHandlers = TaskToolsWithChoose.toLayer(gen(function* () {
201881
202009
  const source = yield* IssueSource;
@@ -201893,6 +202021,19 @@ const TaskToolsHandlers = TaskToolsWithChoose.toLayer(gen(function* () {
201893
202021
  blockedBy: issue.blockedBy
201894
202022
  }));
201895
202023
  }, orDie$2),
202024
+ listEligibleTasks: fn("TaskTools.listEligibleTasks")(function* () {
202025
+ yield* log$1(`Calling "listEligibleTasks"`);
202026
+ const projectId = yield* CurrentProjectId;
202027
+ return (yield* source.issues(projectId)).filter((t) => t.blockedBy.length === 0 && t.state === "todo").map((issue) => ({
202028
+ id: issue.id ?? "",
202029
+ title: issue.title,
202030
+ description: issue.description,
202031
+ state: issue.state,
202032
+ priority: issue.priority,
202033
+ estimate: issue.estimate,
202034
+ blockedBy: issue.blockedBy
202035
+ }));
202036
+ }, orDie$2),
201896
202037
  chooseTask: fn("TaskTools.chooseTask")(function* (options) {
201897
202038
  yield* log$1(`Calling "chooseTask"`).pipe(annotateLogs(options));
201898
202039
  yield* succeed$5(yield* ChosenTaskDeferred, options);
@@ -201914,6 +202055,11 @@ const TaskToolsHandlers = TaskToolsWithChoose.toLayer(gen(function* () {
201914
202055
  issueId: options.taskId,
201915
202056
  ...options
201916
202057
  });
202058
+ }, orDie$2),
202059
+ removeTask: fn("TaskTools.removeTask")(function* (taskId) {
202060
+ yield* log$1(`Calling "removeTask"`).pipe(annotateLogs({ taskId }));
202061
+ const projectId = yield* CurrentProjectId;
202062
+ yield* source.cancelIssue(projectId, taskId);
201917
202063
  }, orDie$2)
201918
202064
  });
201919
202065
  }));
@@ -202168,7 +202314,8 @@ const agentReviewer = fnUntraced(function* (options) {
202168
202314
  }),
202169
202315
  onSome: (prompt) => promptGen.promptReviewCustom({
202170
202316
  prompt,
202171
- specsDirectory: options.specsDirectory
202317
+ specsDirectory: options.specsDirectory,
202318
+ removePrdNotes: true
202172
202319
  })
202173
202320
  }),
202174
202321
  stallTimeout: options.stallTimeout
@@ -202183,7 +202330,8 @@ const agentReviewer = fnUntraced(function* (options) {
202183
202330
  }),
202184
202331
  onSome: (prompt) => promptGen.promptReviewCustom({
202185
202332
  prompt,
202186
- specsDirectory: options.specsDirectory
202333
+ specsDirectory: options.specsDirectory,
202334
+ removePrdNotes: false
202187
202335
  })
202188
202336
  }),
202189
202337
  prdFilePath: pathService.join(".lalph", "prd.yml"),
@@ -202284,7 +202432,14 @@ const run = fnUntraced(function* (options) {
202284
202432
  }));
202285
202433
  if (yield* gen(function* () {
202286
202434
  registry.update(currentWorker.state, (s) => s.transitionTo(WorkerStatus.Working({ issueId: taskId })));
202287
- const instructions = (yield* PromptGen).prompt({
202435
+ const promptGen = yield* PromptGen;
202436
+ const instructions = taskPreset.cliAgent.command ? promptGen.prompt({
202437
+ specsDirectory: options.specsDirectory,
202438
+ targetBranch: getOrUndefined$1(options.targetBranch),
202439
+ task: chosenTask.prd,
202440
+ githubPrNumber: chosenTask.githubPrNumber ?? void 0,
202441
+ gitFlow
202442
+ }) : promptGen.promptClanka({
202288
202443
  specsDirectory: options.specsDirectory,
202289
202444
  targetBranch: getOrUndefined$1(options.targetBranch),
202290
202445
  task: chosenTask.prd,
@@ -202677,7 +202832,7 @@ const commandEdit = make$46("edit").pipe(withDescription("Open the selected proj
202677
202832
  const commandSource = make$46("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));
202678
202833
  //#endregion
202679
202834
  //#region package.json
202680
- var version = "0.3.45";
202835
+ var version = "0.3.46";
202681
202836
  //#endregion
202682
202837
  //#region src/commands/projects/ls.ts
202683
202838
  const commandProjectsLs = make$46("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.45",
4
+ "version": "0.3.46",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -22,13 +22,15 @@
22
22
  "devDependencies": {
23
23
  "@changesets/changelog-github": "^0.6.0",
24
24
  "@changesets/cli": "^2.30.0",
25
+ "@effect/ai-openai": "4.0.0-beta.30",
26
+ "@effect/ai-openai-compat": "4.0.0-beta.30",
25
27
  "@effect/language-service": "^0.79.0",
26
28
  "@effect/platform-node": "4.0.0-beta.30",
27
29
  "@linear/sdk": "^77.0.0",
28
30
  "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
29
31
  "@octokit/types": "^16.0.0",
30
32
  "@typescript/native-preview": "7.0.0-dev.20260310.1",
31
- "clanka": "^0.0.15",
33
+ "clanka": "^0.0.16",
32
34
  "concurrently": "^9.2.1",
33
35
  "effect": "4.0.0-beta.30",
34
36
  "husky": "^9.1.7",
@@ -40,6 +40,7 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
40
40
  promptGen.promptReviewCustom({
41
41
  prompt,
42
42
  specsDirectory: options.specsDirectory,
43
+ removePrdNotes: true,
43
44
  }),
44
45
  }),
45
46
  stallTimeout: options.stallTimeout,
@@ -59,6 +60,7 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
59
60
  promptGen.promptReviewCustom({
60
61
  prompt,
61
62
  specsDirectory: options.specsDirectory,
63
+ removePrdNotes: false,
62
64
  }),
63
65
  }),
64
66
  prdFilePath: pathService.join(".lalph", "prd.yml"),
package/src/PromptGen.ts CHANGED
@@ -285,7 +285,11 @@ ${options.prompt}`
285
285
  const promptReviewCustom = (options: {
286
286
  readonly prompt: string
287
287
  readonly specsDirectory: string
288
- }) => `${options.prompt}
288
+ readonly removePrdNotes: boolean
289
+ }) =>
290
+ options.removePrdNotes
291
+ ? options.prompt
292
+ : `${options.prompt}
289
293
 
290
294
  ${prdNotes(options)}`
291
295
 
package/src/TaskTools.ts CHANGED
@@ -14,24 +14,26 @@ export class ChosenTaskDeferred extends ServiceMap.Reference(
14
14
  },
15
15
  ) {}
16
16
 
17
+ const TaskList = Schema.Array(
18
+ Schema.Struct({
19
+ id: Schema.String.annotate({
20
+ documentation: "The unique identifier of the task.",
21
+ }),
22
+ ...Struct.pick(PrdIssue.fields, [
23
+ "title",
24
+ "description",
25
+ "state",
26
+ "priority",
27
+ "estimate",
28
+ "blockedBy",
29
+ ]),
30
+ }),
31
+ )
32
+
17
33
  export class TaskTools extends Toolkit.make(
18
34
  Tool.make("listTasks", {
19
35
  description: "Returns the current list of tasks.",
20
- success: Schema.Array(
21
- Schema.Struct({
22
- id: Schema.String.annotate({
23
- documentation: "The unique identifier of the task.",
24
- }),
25
- ...Struct.pick(PrdIssue.fields, [
26
- "title",
27
- "description",
28
- "state",
29
- "priority",
30
- "estimate",
31
- "blockedBy",
32
- ]),
33
- }),
34
- ),
36
+ success: TaskList,
35
37
  dependencies: [CurrentProjectId],
36
38
  }),
37
39
  Tool.make("createTask", {
@@ -58,13 +60,13 @@ export class TaskTools extends Toolkit.make(
58
60
  }),
59
61
  dependencies: [CurrentProjectId],
60
62
  }),
61
- // Tool.make("removeTask", {
62
- // description: "Remove a task by it's id.",
63
- // parameters: Schema.String.annotate({
64
- // identifier: "taskId",
65
- // }),
66
- // dependencies: [CurrentProjectId],
67
- // }),
63
+ Tool.make("removeTask", {
64
+ description: "Remove a task by it's id.",
65
+ parameters: Schema.String.annotate({
66
+ identifier: "taskId",
67
+ }),
68
+ dependencies: [CurrentProjectId],
69
+ }),
68
70
  ) {}
69
71
 
70
72
  export class TaskToolsWithChoose extends Toolkit.merge(
@@ -77,6 +79,11 @@ export class TaskToolsWithChoose extends Toolkit.merge(
77
79
  githubPrNumber: Schema.optional(Schema.Number),
78
80
  }),
79
81
  }),
82
+ Tool.make("listEligibleTasks", {
83
+ description: "List tasks eligible for being chosen with chooseTask.",
84
+ success: TaskList,
85
+ dependencies: [CurrentProjectId],
86
+ }),
80
87
  ),
81
88
  ) {}
82
89
 
@@ -99,6 +106,22 @@ export const TaskToolsHandlers = TaskToolsWithChoose.toLayer(
99
106
  blockedBy: issue.blockedBy,
100
107
  }))
101
108
  }, Effect.orDie),
109
+ listEligibleTasks: Effect.fn("TaskTools.listEligibleTasks")(function* () {
110
+ yield* Effect.log(`Calling "listEligibleTasks"`)
111
+ const projectId = yield* CurrentProjectId
112
+ const tasks = yield* source.issues(projectId)
113
+ return tasks
114
+ .filter((t) => t.blockedBy.length === 0 && t.state === "todo")
115
+ .map((issue) => ({
116
+ id: issue.id ?? "",
117
+ title: issue.title,
118
+ description: issue.description,
119
+ state: issue.state,
120
+ priority: issue.priority,
121
+ estimate: issue.estimate,
122
+ blockedBy: issue.blockedBy,
123
+ }))
124
+ }, Effect.orDie),
102
125
  chooseTask: Effect.fn("TaskTools.chooseTask")(function* (options) {
103
126
  yield* Effect.log(`Calling "chooseTask"`).pipe(
104
127
  Effect.annotateLogs(options),
@@ -130,13 +153,13 @@ export const TaskToolsHandlers = TaskToolsWithChoose.toLayer(
130
153
  ...options,
131
154
  })
132
155
  }, Effect.orDie),
133
- // removeTask: Effect.fn("TaskTools.removeTask")(function* (taskId) {
134
- // yield* Effect.log(`Calling "removeTask"`).pipe(
135
- // Effect.annotateLogs({ taskId }),
136
- // )
137
- // const projectId = yield* CurrentProjectId
138
- // yield* source.cancelIssue(projectId, taskId)
139
- // }, Effect.orDie),
156
+ removeTask: Effect.fn("TaskTools.removeTask")(function* (taskId) {
157
+ yield* Effect.log(`Calling "removeTask"`).pipe(
158
+ Effect.annotateLogs({ taskId }),
159
+ )
160
+ const projectId = yield* CurrentProjectId
161
+ yield* source.cancelIssue(projectId, taskId)
162
+ }, Effect.orDie),
140
163
  })
141
164
  }),
142
165
  )
@@ -201,13 +201,21 @@ const run = Effect.fnUntraced(
201
201
  )
202
202
 
203
203
  const promptGen = yield* PromptGen
204
- const instructions = promptGen.prompt({
205
- specsDirectory: options.specsDirectory,
206
- targetBranch: Option.getOrUndefined(options.targetBranch),
207
- task: chosenTask.prd,
208
- githubPrNumber: chosenTask.githubPrNumber ?? undefined,
209
- gitFlow,
210
- })
204
+ const instructions = taskPreset.cliAgent.command
205
+ ? promptGen.prompt({
206
+ specsDirectory: options.specsDirectory,
207
+ targetBranch: Option.getOrUndefined(options.targetBranch),
208
+ task: chosenTask.prd,
209
+ githubPrNumber: chosenTask.githubPrNumber ?? undefined,
210
+ gitFlow,
211
+ })
212
+ : promptGen.promptClanka({
213
+ specsDirectory: options.specsDirectory,
214
+ targetBranch: Option.getOrUndefined(options.targetBranch),
215
+ task: chosenTask.prd,
216
+ githubPrNumber: chosenTask.githubPrNumber ?? undefined,
217
+ gitFlow,
218
+ })
211
219
 
212
220
  const exitCode = yield* agentWorker({
213
221
  stallTimeout: options.stallTimeout,