lalph 0.3.93 → 0.3.95

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
@@ -397,7 +397,7 @@ function flow(ab, bc, cd, de, ef, fg, gh, hi, ij) {
397
397
  /**
398
398
  * @since 4.0.0
399
399
  */
400
- function memoize(f) {
400
+ function memoize$1(f) {
401
401
  const cache = /* @__PURE__ */ new WeakMap();
402
402
  return (a) => {
403
403
  if (cache.has(a)) return cache.get(a);
@@ -18395,7 +18395,7 @@ const resolveDescription$1 = /* @__PURE__ */ resolveAt$1("description");
18395
18395
  /** @internal */
18396
18396
  const resolveBrands = /* @__PURE__ */ resolveAt$1("brands");
18397
18397
  /** @internal */
18398
- const getExpected = /* @__PURE__ */ memoize((ast) => {
18398
+ const getExpected = /* @__PURE__ */ memoize$1((ast) => {
18399
18399
  const identifier = resolveIdentifier$1(ast);
18400
18400
  if (typeof identifier === "string") return identifier;
18401
18401
  return ast.getExpected(getExpected);
@@ -23314,7 +23314,7 @@ function isMutable(ast) {
23314
23314
  *
23315
23315
  * @since 4.0.0
23316
23316
  */
23317
- const toType$1 = /* @__PURE__ */ memoize((ast) => {
23317
+ const toType$1 = /* @__PURE__ */ memoize$1((ast) => {
23318
23318
  if (ast.encoding) return toType$1(replaceEncoding(ast, void 0));
23319
23319
  const out = ast;
23320
23320
  return out.recur?.(toType$1) ?? out;
@@ -23344,7 +23344,7 @@ const toType$1 = /* @__PURE__ */ memoize((ast) => {
23344
23344
  *
23345
23345
  * @since 4.0.0
23346
23346
  */
23347
- const toEncoded$1 = /* @__PURE__ */ memoize((ast) => {
23347
+ const toEncoded$1 = /* @__PURE__ */ memoize$1((ast) => {
23348
23348
  return toType$1(flip(ast));
23349
23349
  });
23350
23350
  function flipEncoding(ast, encoding) {
@@ -23373,7 +23373,7 @@ function flipEncoding(ast, encoding) {
23373
23373
  *
23374
23374
  * @since 4.0.0
23375
23375
  */
23376
- const flip = /* @__PURE__ */ memoize((ast) => {
23376
+ const flip = /* @__PURE__ */ memoize$1((ast) => {
23377
23377
  if (ast.encoding) return flipEncoding(ast, ast.encoding);
23378
23378
  const out = ast;
23379
23379
  return out.flip?.(flip) ?? out.recur?.(flip) ?? out;
@@ -23390,7 +23390,7 @@ function getTemplateLiteralSource(ast, top) {
23390
23390
  return ast.encodedParts.map((part) => handleTemplateLiteralASTPartParens(part, getTemplateLiteralASTPartPattern(part), top)).join("");
23391
23391
  }
23392
23392
  /** @internal */
23393
- const getTemplateLiteralRegExp = /* @__PURE__ */ memoize((ast) => {
23393
+ const getTemplateLiteralRegExp = /* @__PURE__ */ memoize$1((ast) => {
23394
23394
  return new globalThis.RegExp(`^${getTemplateLiteralSource(ast, true)}$`);
23395
23395
  });
23396
23396
  function getTemplateLiteralASTPartPattern(part) {
@@ -23427,7 +23427,7 @@ function toCodec(f) {
23427
23427
  function out(ast) {
23428
23428
  return ast.encoding ? replaceEncoding(ast, updateLastLink(ast.encoding, out)) : f(ast);
23429
23429
  }
23430
- return memoize(out);
23430
+ return memoize$1(out);
23431
23431
  }
23432
23432
  const indexSignatureParameterFromString = /* @__PURE__ */ toCodec((ast) => {
23433
23433
  switch (ast._tag) {
@@ -34112,7 +34112,7 @@ const match$1 = /* @__PURE__ */ dual(2, (self, { onDefined, onUndefined }) => se
34112
34112
  /**
34113
34113
  * @since 4.0.0
34114
34114
  */
34115
- const recurDefaults = /* @__PURE__ */ memoize((ast) => {
34115
+ const recurDefaults = /* @__PURE__ */ memoize$1((ast) => {
34116
34116
  switch (ast._tag) {
34117
34117
  case "Declaration": {
34118
34118
  const getLink = ast.annotations?.[ClassTypeId];
@@ -34261,7 +34261,7 @@ function asOption(parser) {
34261
34261
  function asSync(parser) {
34262
34262
  return (input, options) => runSync(mapErrorEager(parser(input, options), (issue) => new Error(issue.toString(), { cause: issue })));
34263
34263
  }
34264
- const recur$1 = /* @__PURE__ */ memoize((ast) => {
34264
+ const recur$1 = /* @__PURE__ */ memoize$1((ast) => {
34265
34265
  let parser;
34266
34266
  if (!ast.context && !ast.encoding && !ast.checks) return (ou, options) => {
34267
34267
  parser ??= ast.getParser(recur$1);
@@ -61464,7 +61464,7 @@ var RouterImpl = class {
61464
61464
  if (staticPart) {
61465
61465
  staticPart = staticPart.split("::").join(":");
61466
61466
  staticPart = staticPart.split("%").join("%25");
61467
- regexps.push(escapeRegExp(staticPart));
61467
+ regexps.push(escapeRegExp$1(staticPart));
61468
61468
  }
61469
61469
  lastParamStartIndex = j + 1;
61470
61470
  if (isEndOfNode || pattern.charCodeAt(j) === 47 || j === pattern.length) {
@@ -61778,7 +61778,7 @@ function trimRegExpStartAndEnd(regexString) {
61778
61778
  if (regexString.charCodeAt(regexString.length - 2) === 36) regexString = regexString.slice(0, regexString.length - 2) + regexString.slice(regexString.length - 1);
61779
61779
  return regexString;
61780
61780
  }
61781
- function escapeRegExp(string) {
61781
+ function escapeRegExp$1(string) {
61782
61782
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
61783
61783
  }
61784
61784
  function decodeComponentChar(highCharCode, lowCharCode) {
@@ -178282,7 +178282,10 @@ var TokenManager$1 = class extends Service$1()("lalph/Linear/TokenManager", { ma
178282
178282
  })), {
178283
178283
  disableListenLog: true,
178284
178284
  disableLogger: true
178285
- }).pipe(provide$3(layer$15(createServer, { port: 34338 })), build, orDie$2);
178285
+ }).pipe(provide$3(layer$15(createServer, {
178286
+ port: 34338,
178287
+ disablePreemptiveShutdown: true
178288
+ })), build, orDie$2);
178286
178289
  const redirectUri = `http://localhost:34338/callback`;
178287
178290
  const verifier = crypto.randomUUID();
178288
178291
  const verifierSha256 = yield* promise(() => crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)));
@@ -181680,7 +181683,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
181680
181683
  });
181681
181684
  Ze.glob = Ze;
181682
181685
  //#endregion
181683
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ApplyPatch.js
181686
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ApplyPatch.js
181684
181687
  /**
181685
181688
  * @since 1.0.0
181686
181689
  */
@@ -196553,7 +196556,7 @@ var StreamableHTTPClientTransport = class {
196553
196556
  }
196554
196557
  };
196555
196558
  //#endregion
196556
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/McpClient.js
196559
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/McpClient.js
196557
196560
  /**
196558
196561
  * @since 1.0.0
196559
196562
  */
@@ -196598,7 +196601,7 @@ const layer$13 = effect$1(McpClient, gen(function* () {
196598
196601
  });
196599
196602
  }));
196600
196603
  //#endregion
196601
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ExaSearch.js
196604
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ExaSearch.js
196602
196605
  /**
196603
196606
  * @since 1.0.0
196604
196607
  */
@@ -211548,7 +211551,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin$1(((exports) => {
211548
211551
  exports.impl = impl;
211549
211552
  }));
211550
211553
  //#endregion
211551
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/WebToMarkdown.js
211554
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/WebToMarkdown.js
211552
211555
  /**
211553
211556
  * @since 1.0.0
211554
211557
  */
@@ -215166,7 +215169,7 @@ const mapProviderResults = (inputLength, results) => {
215166
215169
  return succeed$3(embeddings);
215167
215170
  };
215168
215171
  //#endregion
215169
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ChunkRepo.js
215172
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ChunkRepo.js
215170
215173
  /**
215171
215174
  * @since 1.0.0
215172
215175
  * @category Models
@@ -215297,7 +215300,7 @@ const layer$10 = effect$1(ChunkRepo, gen(function* () {
215297
215300
  });
215298
215301
  }));
215299
215302
  //#endregion
215300
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/CodeChunker.js
215303
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/CodeChunker.js
215301
215304
  /**
215302
215305
  * @since 1.0.0
215303
215306
  */
@@ -215920,7 +215923,7 @@ const run$1 = /* @__PURE__ */ make$25({});
215920
215923
  */
215921
215924
  const layer$7 = (options) => effectDiscard(run$1(options));
215922
215925
  //#endregion
215923
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/internal/sqlite-vector.js
215926
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/internal/sqlite-vector.js
215924
215927
  /**
215925
215928
  * Binary extension for each platform
215926
215929
  */
@@ -216037,7 +216040,7 @@ function getExtensionPath() {
216037
216040
  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`);
216038
216041
  }
216039
216042
  //#endregion
216040
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/Sqlite.js
216043
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/Sqlite.js
216041
216044
  /**
216042
216045
  * @since 1.0.0
216043
216046
  */
@@ -216065,7 +216068,7 @@ const SqliteLayer = (database) => layer$7({ loader: fromRecord({ "0001_create_ch
216065
216068
  yield* fs.makeDirectory(directory, { recursive: true });
216066
216069
  }))));
216067
216070
  //#endregion
216068
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/SemanticSearch.js
216071
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/SemanticSearch.js
216069
216072
  /**
216070
216073
  * @since 1.0.0
216071
216074
  */
@@ -216209,7 +216212,7 @@ const maybeRemoveFile = (path) => serviceOption(SemanticSearch).pipe(flatMap$4(m
216209
216212
  onSome: (service) => service.removeFile(path)
216210
216213
  })));
216211
216214
  //#endregion
216212
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/AgentTools.js
216215
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/AgentTools.js
216213
216216
  /**
216214
216217
  * @since 1.0.0
216215
216218
  */
@@ -216560,7 +216563,7 @@ const AgentToolHandlers = AgentToolHandlersNoDeps.pipe(provide$3([layer$12, laye
216560
216563
  AgentToolHandlersNoDeps.pipe(provide$3([mock(ExaSearch)({}), mock(WebToMarkdown)({})]));
216561
216564
  var ApplyPatchError = class extends TaggedClass$2("ApplyPatchError") {};
216562
216565
  //#endregion
216563
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/TypeBuilder.js
216566
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/TypeBuilder.js
216564
216567
  const resolveDocumentation = resolveAt("documentation");
216565
216568
  const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
216566
216569
  const Precedence = {
@@ -216833,7 +216836,7 @@ const render = (schema, options) => {
216833
216836
  return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
216834
216837
  };
216835
216838
  //#endregion
216836
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ToolkitRenderer.js
216839
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ToolkitRenderer.js
216837
216840
  /**
216838
216841
  * @since 1.0.0
216839
216842
  */
@@ -216842,7 +216845,7 @@ const render = (schema, options) => {
216842
216845
  * @category Services
216843
216846
  */
216844
216847
  var ToolkitRenderer = class ToolkitRenderer extends Service$1()("clanka/ToolkitRenderer") {
216845
- static layer = succeed$4(ToolkitRenderer, { render: memoize((tools) => {
216848
+ static layer = succeed$4(ToolkitRenderer, { render: memoize$1((tools) => {
216846
216849
  const output = empty$17();
216847
216850
  for (const [name, tool] of Object.entries(tools.tools)) {
216848
216851
  const paramName = resolveIdentifier(tool.parametersSchema.ast) ?? "options";
@@ -216855,7 +216858,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
216855
216858
  }) });
216856
216859
  };
216857
216860
  //#endregion
216858
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ScriptPreprocessing.js
216861
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ScriptPreprocessing.js
216859
216862
  const isIdentifierChar = (char) => char !== void 0 && /[A-Za-z0-9_$]/.test(char);
216860
216863
  const isIdentifierStartChar = (char) => char !== void 0 && /[A-Za-z_$]/.test(char);
216861
216864
  const hasIdentifierBoundary = (text, index, length) => !isIdentifierChar(text[index - 1]) && !isIdentifierChar(text[index + length]);
@@ -217040,6 +217043,80 @@ const findClosingParen = (text, openParen) => {
217040
217043
  }
217041
217044
  return -1;
217042
217045
  };
217046
+ const findClosingBrace = (text, openBrace) => {
217047
+ let depth = 1;
217048
+ let stringDelimiter;
217049
+ for (let i = openBrace + 1; i < text.length; i++) {
217050
+ const char = text[i];
217051
+ if (stringDelimiter !== void 0) {
217052
+ if (char === stringDelimiter && !isEscaped(text, i)) stringDelimiter = void 0;
217053
+ continue;
217054
+ }
217055
+ if (char === "\"" || char === "'" || char === "`") {
217056
+ stringDelimiter = char;
217057
+ continue;
217058
+ }
217059
+ if (char === "{") {
217060
+ depth++;
217061
+ continue;
217062
+ }
217063
+ if (char === "}") {
217064
+ depth--;
217065
+ if (depth === 0) return i;
217066
+ }
217067
+ }
217068
+ return -1;
217069
+ };
217070
+ const fixObjectLiteralTemplateValues = (text) => text.replace(/\\{2,}(?=`|\$\{)/g, "\\");
217071
+ const fixAssignedObjectTemplateValues = (script, variableName) => {
217072
+ let out = script;
217073
+ let cursor = 0;
217074
+ while (cursor < out.length) {
217075
+ const variableStart = findNextIdentifier(out, variableName, cursor);
217076
+ if (variableStart === -1) break;
217077
+ let assignmentStart = skipWhitespace(out, variableStart + variableName.length);
217078
+ if (out[assignmentStart] === ":") {
217079
+ assignmentStart = findTypeAnnotationAssignment(out, assignmentStart + 1);
217080
+ if (assignmentStart === -1) {
217081
+ cursor = variableStart + variableName.length;
217082
+ continue;
217083
+ }
217084
+ }
217085
+ if (out[assignmentStart] !== "=" || out[assignmentStart + 1] === "=" || out[assignmentStart + 1] === ">") {
217086
+ cursor = variableStart + variableName.length;
217087
+ continue;
217088
+ }
217089
+ const objectStart = skipWhitespace(out, assignmentStart + 1);
217090
+ if (out[objectStart] !== "{") {
217091
+ cursor = objectStart + 1;
217092
+ continue;
217093
+ }
217094
+ const objectEnd = findClosingBrace(out, objectStart);
217095
+ if (objectEnd === -1) {
217096
+ cursor = objectStart + 1;
217097
+ continue;
217098
+ }
217099
+ const original = out.slice(objectStart, objectEnd + 1);
217100
+ const escaped = fixObjectLiteralTemplateValues(original);
217101
+ if (escaped !== original) {
217102
+ out = `${out.slice(0, objectStart)}${escaped}${out.slice(objectEnd + 1)}`;
217103
+ cursor = objectEnd + (escaped.length - original.length) + 1;
217104
+ continue;
217105
+ }
217106
+ cursor = objectEnd + 1;
217107
+ }
217108
+ return out;
217109
+ };
217110
+ const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&");
217111
+ const collectObjectEntryMapSources = (script, valueIdentifier) => {
217112
+ const out = /* @__PURE__ */ new Set();
217113
+ const pattern = new RegExp(`Object\\.entries\\(\\s*([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\)\\s*\\.map\\(\\s*(?:async\\s*)?\\(\\s*\\[\\s*[A-Za-z_$][A-Za-z0-9_$]*\\s*,\\s*${escapeRegExp(valueIdentifier)}\\s*\\]\\s*\\)\\s*=>`, "g");
217114
+ for (const match of script.matchAll(pattern)) {
217115
+ const sourceIdentifier = match[1];
217116
+ if (sourceIdentifier !== void 0) out.add(sourceIdentifier);
217117
+ }
217118
+ return out;
217119
+ };
217043
217120
  const findCallTemplateEnd = (text, templateStart, openParen) => {
217044
217121
  const closeParen = findClosingParen(text, openParen);
217045
217122
  if (closeParen === -1) return -1;
@@ -217221,13 +217298,16 @@ const fixAssignedTemplatesForToolCalls = (script) => {
217221
217298
  for (const functionName of ["applyPatch", "taskComplete"]) for (const identifier of collectCallArgumentIdentifiers(script, functionName)) identifiers.add(identifier);
217222
217299
  for (const [functionName, propertyName] of callObjectPropertyTargets) for (const identifier of collectCallObjectPropertyIdentifiers(script, functionName, propertyName)) identifiers.add(identifier);
217223
217300
  if (script.includes("*** Begin Patch")) identifiers.add("patch");
217301
+ const objectTemplateIdentifiers = /* @__PURE__ */ new Set();
217302
+ for (const identifier of identifiers) for (const sourceIdentifier of collectObjectEntryMapSources(script, identifier)) objectTemplateIdentifiers.add(sourceIdentifier);
217224
217303
  let out = script;
217225
217304
  for (const identifier of identifiers) out = fixAssignedTemplate(out, identifier);
217305
+ for (const identifier of objectTemplateIdentifiers) out = fixAssignedObjectTemplateValues(out, identifier);
217226
217306
  return out;
217227
217307
  };
217228
217308
  const preprocessScript = (script) => fixAssignedTemplatesForToolCalls(["applyPatch", "taskComplete"].reduce((current, functionName) => fixCallTemplateArgument(current, functionName), fixTargetCallObjectPropertyTemplates(script)));
217229
217309
  //#endregion
217230
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/AgentExecutor.js
217310
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/AgentExecutor.js
217231
217311
  /**
217232
217312
  * @since 1.0.0
217233
217313
  */
@@ -217412,7 +217492,7 @@ var QueueWriteStream = class extends Writable {
217412
217492
  }
217413
217493
  };
217414
217494
  //#endregion
217415
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/ScriptExtraction.js
217495
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/ScriptExtraction.js
217416
217496
  const stripWrappingCodeFence = (script) => {
217417
217497
  const lines = script.split(/\r?\n/);
217418
217498
  if (lines.length < 2) return script;
@@ -218961,7 +219041,7 @@ const applySpanTransformer = (transformer, response, options) => {
218961
219041
  });
218962
219042
  };
218963
219043
  //#endregion
218964
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/Agent.js
219044
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/Agent.js
218965
219045
  /**
218966
219046
  * @since 1.0.0
218967
219047
  */
@@ -230345,7 +230425,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
230345
230425
  })));
230346
230426
  });
230347
230427
  //#endregion
230348
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/CodexAuth.js
230428
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/CodexAuth.js
230349
230429
  /**
230350
230430
  * @since 1.0.0
230351
230431
  */
@@ -230565,7 +230645,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
230565
230645
  static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
230566
230646
  };
230567
230647
  //#endregion
230568
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/Codex.js
230648
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/Codex.js
230569
230649
  /**
230570
230650
  * @since 1.0.0
230571
230651
  */
@@ -231877,7 +231957,7 @@ const getUsageDetailNumber = (details, field) => {
231877
231957
  return typeof value === "number" ? value : void 0;
231878
231958
  };
231879
231959
  //#endregion
231880
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/CopilotAuth.js
231960
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/CopilotAuth.js
231881
231961
  /**
231882
231962
  * @since 1.0.0
231883
231963
  */
@@ -232068,7 +232148,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
232068
232148
  static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
232069
232149
  };
232070
232150
  //#endregion
232071
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/Copilot.js
232151
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/Copilot.js
232072
232152
  /**
232073
232153
  * @since 1.0.0
232074
232154
  */
@@ -232488,7 +232568,7 @@ Object.defineProperties(createChalk.prototype, styles);
232488
232568
  const chalk = createChalk();
232489
232569
  createChalk({ level: stderrColor ? stderrColor.level : 0 });
232490
232570
  //#endregion
232491
- //#region node_modules/.pnpm/clanka@0.2.20_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_6b0046a993593c9ab506aa2cfcf3e05c/node_modules/clanka/dist/OutputFormatter.js
232571
+ //#region node_modules/.pnpm/clanka@0.2.21_@effect+ai-openai-compat@4.0.0-beta.36_effect@4.0.0-beta.36__@effect+ai-o_09288369fd42a7055df614a5b619d2f6/node_modules/clanka/dist/OutputFormatter.js
232492
232572
  /**
232493
232573
  * @since 1.0.0
232494
232574
  */
@@ -232821,19 +232901,34 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232821
232901
  const presets = yield* getPresetsWithMetadata("linear", PresetMetadata$1);
232822
232902
  const identifierMap = /* @__PURE__ */ new Map();
232823
232903
  const presetMap = /* @__PURE__ */ new Map();
232824
- const backlogState = state.states.find((s) => s.type === "backlog" && s.name.toLowerCase().includes("backlog")) || state.states.find((s) => s.type === "backlog");
232825
- const todoState = state.states.find((s) => s.type === "unstarted" && (s.name.toLowerCase().includes("todo") || s.name.toLowerCase().includes("unstarted"))) || state.states.find((s) => s.type === "unstarted");
232826
- const inProgressState = state.states.find((s) => s.type === "started" && (s.name.toLowerCase().includes("progress") || s.name.toLowerCase().includes("started"))) || state.states.find((s) => s.type === "started");
232827
- const inReviewState = state.states.find((s) => s.type === "started" && s.name.toLowerCase().includes("review")) || state.states.find((s) => s.type === "completed");
232828
- const doneState = state.states.find((s) => s.type === "completed");
232829
- const canceledState = state.states.find((state) => state.type === "canceled");
232830
- const linearStateToPrdState = (state) => {
232904
+ const findState = (teamId, type, names = [], fallbackType = type) => {
232905
+ const filtered = state.states.filter((s) => {
232906
+ if (names.length === 0) return s.type === type;
232907
+ const name = s.name.toLowerCase();
232908
+ return s.type === type && names.some((n) => name.includes(n));
232909
+ });
232910
+ const withTeamId = filtered.filter((s) => s.teamId === teamId);
232911
+ if (withTeamId.length > 0) return withTeamId[0];
232912
+ const withoutTeamId = filtered.filter((s) => s.teamId === void 0);
232913
+ if (withoutTeamId.length > 0) return withoutTeamId[0];
232914
+ return state.states.find((s) => s.type === fallbackType);
232915
+ };
232916
+ const statesForTeamId = memoize((teamId) => ({
232917
+ backlog: findState(teamId, "backlog", ["backlog"]),
232918
+ todo: findState(teamId, "unstarted", ["todo", "unstarted"]),
232919
+ inProgress: findState(teamId, "started", ["progress", "started"]),
232920
+ inReview: findState(teamId, "started", ["review"], "completed"),
232921
+ done: findState(teamId, "completed"),
232922
+ canceled: findState(teamId, "canceled")
232923
+ }));
232924
+ const linearStateToPrdState = (state, teamId) => {
232925
+ const states = statesForTeamId(teamId);
232831
232926
  switch (state.id) {
232832
- case backlogState.id: return "backlog";
232833
- case todoState.id: return "todo";
232834
- case inProgressState.id: return "in-progress";
232835
- case inReviewState.id: return "in-review";
232836
- case doneState.id: return "done";
232927
+ case states.backlog.id: return "backlog";
232928
+ case states.todo.id: return "todo";
232929
+ case states.inProgress.id: return "in-progress";
232930
+ case states.inReview.id: return "in-review";
232931
+ case states.done.id: return "done";
232837
232932
  default:
232838
232933
  if (state.type === "backlog") return "backlog";
232839
232934
  if (state.type === "unstarted") return "todo";
@@ -232842,16 +232937,17 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232842
232937
  return "backlog";
232843
232938
  }
232844
232939
  };
232845
- const prdStateToLinearStateId = (state) => {
232940
+ const prdStateToLinearStateId = (state, teamId) => {
232941
+ const states = statesForTeamId(teamId);
232846
232942
  switch (state) {
232847
- case "backlog": return backlogState.id;
232848
- case "todo": return todoState.id;
232849
- case "in-progress": return inProgressState.id;
232850
- case "in-review": return inReviewState.id;
232851
- case "done": return doneState.id;
232943
+ case "backlog": return states.backlog.id;
232944
+ case "todo": return states.todo.id;
232945
+ case "in-progress": return states.inProgress.id;
232946
+ case "in-review": return states.inReview.id;
232947
+ case "done": return states.done.id;
232852
232948
  }
232853
232949
  };
232854
- const issues = ({ labelId, projectId, autoMergeLabelId }) => linear.issues({
232950
+ const issues = ({ labelId, projectId, teamId, autoMergeLabelId }) => linear.issues({
232855
232951
  labelId,
232856
232952
  projectId
232857
232953
  }).pipe(mapError$2((cause) => new IssueSourceError({ cause })), map$9((issues) => {
@@ -232869,7 +232965,7 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232869
232965
  description: issue.description ?? "",
232870
232966
  priority: issue.priority,
232871
232967
  estimate: issue.estimate ?? null,
232872
- state: linearStateToPrdState(issue.state),
232968
+ state: linearStateToPrdState(issue.state, teamId),
232873
232969
  blockedBy: issue.blockedBy.map((r) => r.issue.identifier),
232874
232970
  autoMerge: autoMergeLabelId.pipe(map$16((labelId) => issue.labelIds.includes(labelId)), getOrElse$2(() => false))
232875
232971
  })));
@@ -232879,6 +232975,7 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232879
232975
  const settings = yield* get$7(projectSettings, projectId);
232880
232976
  return yield* issues({
232881
232977
  projectId: settings.project.id,
232978
+ teamId: settings.teamId,
232882
232979
  labelId: settings.labelId,
232883
232980
  autoMergeLabelId: settings.autoMergeLabelId
232884
232981
  });
@@ -232888,6 +232985,7 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232888
232985
  return (yield* issues({
232889
232986
  projectId: settings.project.id,
232890
232987
  labelId: settings.labelId,
232988
+ teamId: settings.teamId,
232891
232989
  autoMergeLabelId: settings.autoMergeLabelId
232892
232990
  })).find((issue) => issue.id === issueId) ?? null;
232893
232991
  }),
@@ -232902,7 +233000,7 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232902
233000
  description: issue.description,
232903
233001
  priority: issue.priority,
232904
233002
  estimate: issue.estimate,
232905
- stateId: prdStateToLinearStateId(issue.state)
233003
+ stateId: prdStateToLinearStateId(issue.state, teamId)
232906
233004
  }));
232907
233005
  const linearIssue = yield* linear.use(() => created.issue);
232908
233006
  identifierMap.set(linearIssue.identifier, linearIssue.id);
@@ -232925,13 +233023,13 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232925
233023
  };
232926
233024
  }, mapError$2((cause) => new IssueSourceError({ cause }))),
232927
233025
  updateIssue: fnUntraced(function* (options) {
232928
- const { autoMergeLabelId } = yield* get$7(projectSettings, options.projectId);
233026
+ const { autoMergeLabelId, teamId } = yield* get$7(projectSettings, options.projectId);
232929
233027
  const issueId = identifierMap.get(options.issueId);
232930
233028
  const linearIssue = yield* linear.issueById(issueId);
232931
233029
  const update = { labelIds: linearIssue.labelIds.slice() };
232932
233030
  if (options.title) update.title = options.title;
232933
233031
  if (options.description) update.description = options.description;
232934
- if (options.state) update.stateId = prdStateToLinearStateId(options.state);
233032
+ if (options.state) update.stateId = prdStateToLinearStateId(options.state, teamId);
232935
233033
  if (options.autoMerge !== void 0 && isSome(autoMergeLabelId)) {
232936
233034
  const hasLabel = update.labelIds.includes(autoMergeLabelId.value);
232937
233035
  if (options.autoMerge && !hasLabel) update.labelIds.push(autoMergeLabelId.value);
@@ -232954,9 +233052,11 @@ const LinearIssueSource = effect$1(IssueSource, gen(function* () {
232954
233052
  })).pipe(ignore$1), { concurrency: 5 });
232955
233053
  yield* forEach$4(toRemove, (relation) => linear.use((c) => c.deleteIssueRelation(relation.id)).pipe(ignore$1), { concurrency: 5 });
232956
233054
  }, mapError$2((cause) => new IssueSourceError({ cause }))),
232957
- cancelIssue: fnUntraced(function* (_project, issueId) {
233055
+ cancelIssue: fnUntraced(function* (projectId, issueId) {
233056
+ const { teamId } = yield* get$7(projectSettings, projectId);
233057
+ const states = statesForTeamId(teamId);
232958
233058
  const linearIssueId = identifierMap.get(issueId);
232959
- yield* linear.use((c) => c.updateIssue(linearIssueId, { stateId: canceledState.id }));
233059
+ yield* linear.use((c) => c.updateIssue(linearIssueId, { stateId: states.canceled.id }));
232960
233060
  }, mapError$2((cause) => new IssueSourceError({ cause }))),
232961
233061
  reset: gen(function* () {
232962
233062
  const projectId = yield* CurrentProjectId;
@@ -233220,11 +233320,22 @@ var LinearState = class extends Class$1()("lalph/LinearState", {
233220
233320
  states: Array$1(Struct$2({
233221
233321
  id: String$1,
233222
233322
  name: String$1,
233223
- type: String$1
233323
+ type: String$1,
233324
+ teamId: optional$3(String$1)
233224
233325
  })),
233225
233326
  viewer: Struct$2({ id: String$1 })
233226
233327
  })
233227
233328
  }) {};
233329
+ const memoize = (f) => {
233330
+ const cache = /* @__PURE__ */ new Map();
233331
+ return (a) => {
233332
+ const cached = cache.get(a);
233333
+ if (cached) return cached;
233334
+ const b = f(a);
233335
+ cache.set(a, b);
233336
+ return b;
233337
+ };
233338
+ };
233228
233339
  //#endregion
233229
233340
  //#region node_modules/.pnpm/universal-user-agent@7.0.3/node_modules/universal-user-agent/index.js
233230
233341
  function getUserAgent() {
@@ -241816,10 +241927,8 @@ const runProject = fnUntraced(function* (options) {
241816
241927
  const gitFlowLayer = resolveGitFlowLayer();
241817
241928
  const fiber = yield* checkForWork(options.project).pipe(andThen(resolveRunEffect(startedDeferred).pipe(provide$1(gitFlowLayer, { local: true }), withWorkerState(options.project.id))), catchTags$1({
241818
241929
  ChosenTaskNotFound(_error) {
241819
- if (executionMode._tag !== "ralph") {
241820
- ralphDone = true;
241821
- return void_$2;
241822
- }
241930
+ if (executionMode._tag !== "ralph") return void_$2;
241931
+ ralphDone = true;
241823
241932
  return log$1(`No more work to process for Ralph, ending after ${currentIteration + 1} iteration(s).`);
241824
241933
  },
241825
241934
  NoMoreWork(_error) {
@@ -242183,7 +242292,7 @@ const commandEdit = make$58("edit").pipe(withDescription("Open the selected proj
242183
242292
  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));
242184
242293
  //#endregion
242185
242294
  //#region package.json
242186
- var version = "0.3.93";
242295
+ var version = "0.3.95";
242187
242296
  //#endregion
242188
242297
  //#region src/commands/projects/ls.ts
242189
242298
  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.93",
4
+ "version": "0.3.95",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -39,13 +39,13 @@
39
39
  "@changesets/cli": "^2.30.0",
40
40
  "@effect/ai-openai": "4.0.0-beta.36",
41
41
  "@effect/ai-openai-compat": "4.0.0-beta.36",
42
- "@effect/language-service": "^0.80.0",
42
+ "@effect/language-service": "^0.81.0",
43
43
  "@effect/platform-node": "4.0.0-beta.36",
44
44
  "@linear/sdk": "^78.0.0",
45
45
  "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
46
46
  "@octokit/types": "^16.0.0",
47
- "@typescript/native-preview": "7.0.0-dev.20260319.1",
48
- "clanka": "^0.2.20",
47
+ "@typescript/native-preview": "7.0.0-dev.20260320.1",
48
+ "clanka": "^0.2.21",
49
49
  "concurrently": "^9.2.1",
50
50
  "effect": "4.0.0-beta.36",
51
51
  "husky": "^9.1.7",
@@ -106,7 +106,12 @@ export class TokenManager extends ServiceMap.Service<TokenManager>()(
106
106
  disableListenLog: true,
107
107
  disableLogger: true,
108
108
  }).pipe(
109
- Layer.provide(NodeHttpServer.layer(createServer, { port: 34338 })),
109
+ Layer.provide(
110
+ NodeHttpServer.layer(createServer, {
111
+ port: 34338,
112
+ disablePreemptiveShutdown: true,
113
+ }),
114
+ ),
110
115
  Layer.build,
111
116
  Effect.orDie,
112
117
  )
package/src/Linear.ts CHANGED
@@ -208,45 +208,48 @@ export const LinearIssueSource = Layer.effect(
208
208
  const identifierMap = new Map<string, string>()
209
209
  const presetMap = new Map<string, CliAgentPreset>()
210
210
 
211
- const backlogState =
212
- state.states.find(
213
- (s) => s.type === "backlog" && s.name.toLowerCase().includes("backlog"),
214
- ) || state.states.find((s) => s.type === "backlog")!
215
- const todoState =
216
- state.states.find(
217
- (s) =>
218
- s.type === "unstarted" &&
219
- (s.name.toLowerCase().includes("todo") ||
220
- s.name.toLowerCase().includes("unstarted")),
221
- ) || state.states.find((s) => s.type === "unstarted")!
222
- const inProgressState =
223
- state.states.find(
224
- (s) =>
225
- s.type === "started" &&
226
- (s.name.toLowerCase().includes("progress") ||
227
- s.name.toLowerCase().includes("started")),
228
- ) || state.states.find((s) => s.type === "started")!
229
- const inReviewState =
230
- state.states.find(
231
- (s) => s.type === "started" && s.name.toLowerCase().includes("review"),
232
- ) || state.states.find((s) => s.type === "completed")!
233
- const doneState = state.states.find((s) => s.type === "completed")!
234
-
235
- const canceledState = state.states.find(
236
- (state) => state.type === "canceled",
237
- )!
238
-
239
- const linearStateToPrdState = (state: State): PrdIssue["state"] => {
211
+ const findState = (
212
+ teamId: string,
213
+ type: string,
214
+ names: Array<string> = [],
215
+ fallbackType = type,
216
+ ) => {
217
+ const filtered = state.states.filter((s) => {
218
+ if (names.length === 0) return s.type === type
219
+ const name = s.name.toLowerCase()
220
+ return s.type === type && names.some((n) => name.includes(n))
221
+ })
222
+ const withTeamId = filtered.filter((s) => s.teamId === teamId)
223
+ if (withTeamId.length > 0) return withTeamId[0]!
224
+ const withoutTeamId = filtered.filter((s) => s.teamId === undefined)
225
+ if (withoutTeamId.length > 0) return withoutTeamId[0]!
226
+ return state.states.find((s) => s.type === fallbackType)!
227
+ }
228
+
229
+ const statesForTeamId = memoize((teamId: string) => ({
230
+ backlog: findState(teamId, "backlog", ["backlog"]),
231
+ todo: findState(teamId, "unstarted", ["todo", "unstarted"]),
232
+ inProgress: findState(teamId, "started", ["progress", "started"]),
233
+ inReview: findState(teamId, "started", ["review"], "completed"),
234
+ done: findState(teamId, "completed"),
235
+ canceled: findState(teamId, "canceled"),
236
+ }))
237
+
238
+ const linearStateToPrdState = (
239
+ state: State,
240
+ teamId: string,
241
+ ): PrdIssue["state"] => {
242
+ const states = statesForTeamId(teamId)
240
243
  switch (state.id) {
241
- case backlogState.id:
244
+ case states.backlog.id:
242
245
  return "backlog"
243
- case todoState.id:
246
+ case states.todo.id:
244
247
  return "todo"
245
- case inProgressState.id:
248
+ case states.inProgress.id:
246
249
  return "in-progress"
247
- case inReviewState.id:
250
+ case states.inReview.id:
248
251
  return "in-review"
249
- case doneState.id:
252
+ case states.done.id:
250
253
  return "done"
251
254
  default:
252
255
  if (state.type === "backlog") return "backlog"
@@ -256,28 +259,34 @@ export const LinearIssueSource = Layer.effect(
256
259
  return "backlog"
257
260
  }
258
261
  }
259
- const prdStateToLinearStateId = (state: PrdIssue["state"]): string => {
262
+ const prdStateToLinearStateId = (
263
+ state: PrdIssue["state"],
264
+ teamId: string,
265
+ ): string => {
266
+ const states = statesForTeamId(teamId)
260
267
  switch (state) {
261
268
  case "backlog":
262
- return backlogState.id
269
+ return states.backlog.id
263
270
  case "todo":
264
- return todoState.id
271
+ return states.todo.id
265
272
  case "in-progress":
266
- return inProgressState.id
273
+ return states.inProgress.id
267
274
  case "in-review":
268
- return inReviewState.id
275
+ return states.inReview.id
269
276
  case "done":
270
- return doneState.id
277
+ return states.done.id
271
278
  }
272
279
  }
273
280
 
274
281
  const issues = ({
275
282
  labelId,
276
283
  projectId,
284
+ teamId,
277
285
  autoMergeLabelId,
278
286
  }: {
279
287
  readonly labelId: Option.Option<string>
280
288
  readonly projectId: string
289
+ readonly teamId: string
281
290
  readonly autoMergeLabelId: Option.Option<string>
282
291
  }) =>
283
292
  linear.issues({ labelId, projectId }).pipe(
@@ -308,7 +317,7 @@ export const LinearIssueSource = Layer.effect(
308
317
  description: issue.description ?? "",
309
318
  priority: issue.priority,
310
319
  estimate: issue.estimate ?? null,
311
- state: linearStateToPrdState(issue.state),
320
+ state: linearStateToPrdState(issue.state, teamId),
312
321
  blockedBy: issue.blockedBy.map((r) => r.issue.identifier),
313
322
  autoMerge: autoMergeLabelId.pipe(
314
323
  Option.map((labelId) => issue.labelIds.includes(labelId)),
@@ -325,6 +334,7 @@ export const LinearIssueSource = Layer.effect(
325
334
  const settings = yield* Cache.get(projectSettings, projectId)
326
335
  return yield* issues({
327
336
  projectId: settings.project.id,
337
+ teamId: settings.teamId,
328
338
  labelId: settings.labelId,
329
339
  autoMergeLabelId: settings.autoMergeLabelId,
330
340
  })
@@ -334,6 +344,7 @@ export const LinearIssueSource = Layer.effect(
334
344
  const projectIssues = yield* issues({
335
345
  projectId: settings.project.id,
336
346
  labelId: settings.labelId,
347
+ teamId: settings.teamId,
337
348
  autoMergeLabelId: settings.autoMergeLabelId,
338
349
  })
339
350
  return projectIssues.find((issue) => issue.id === issueId) ?? null
@@ -355,7 +366,7 @@ export const LinearIssueSource = Layer.effect(
355
366
  description: issue.description,
356
367
  priority: issue.priority,
357
368
  estimate: issue.estimate,
358
- stateId: prdStateToLinearStateId(issue.state),
369
+ stateId: prdStateToLinearStateId(issue.state, teamId),
359
370
  }),
360
371
  )
361
372
  const linearIssue = yield* linear.use(() => created.issue!)
@@ -391,7 +402,7 @@ export const LinearIssueSource = Layer.effect(
391
402
  ),
392
403
  updateIssue: Effect.fnUntraced(
393
404
  function* (options) {
394
- const { autoMergeLabelId } = yield* Cache.get(
405
+ const { autoMergeLabelId, teamId } = yield* Cache.get(
395
406
  projectSettings,
396
407
  options.projectId,
397
408
  )
@@ -412,7 +423,7 @@ export const LinearIssueSource = Layer.effect(
412
423
  update.description = options.description
413
424
  }
414
425
  if (options.state) {
415
- update.stateId = prdStateToLinearStateId(options.state)
426
+ update.stateId = prdStateToLinearStateId(options.state, teamId)
416
427
  }
417
428
  if (
418
429
  options.autoMerge !== undefined &&
@@ -475,11 +486,13 @@ export const LinearIssueSource = Layer.effect(
475
486
  Effect.mapError((cause) => new IssueSourceError({ cause })),
476
487
  ),
477
488
  cancelIssue: Effect.fnUntraced(
478
- function* (_project, issueId) {
489
+ function* (projectId, issueId) {
490
+ const { teamId } = yield* Cache.get(projectSettings, projectId)
491
+ const states = statesForTeamId(teamId)
479
492
  const linearIssueId = identifierMap.get(issueId)!
480
493
  yield* linear.use((c) =>
481
494
  c.updateIssue(linearIssueId, {
482
- stateId: canceledState.id,
495
+ stateId: states.canceled.id,
483
496
  }),
484
497
  )
485
498
  },
@@ -878,6 +891,7 @@ class LinearState extends Persistable.Class<{
878
891
  id: Schema.String,
879
892
  name: Schema.String,
880
893
  type: Schema.String,
894
+ teamId: Schema.optional(Schema.String),
881
895
  }),
882
896
  ),
883
897
  viewer: Schema.Struct({
@@ -885,3 +899,14 @@ class LinearState extends Persistable.Class<{
885
899
  }),
886
900
  }),
887
901
  }) {}
902
+
903
+ const memoize = <A, B>(f: (a: A) => B): ((a: A) => B) => {
904
+ const cache = new Map<A, B>()
905
+ return (a: A) => {
906
+ const cached = cache.get(a)
907
+ if (cached) return cached
908
+ const b = f(a)
909
+ cache.set(a, b)
910
+ return b
911
+ }
912
+ }
@@ -661,9 +661,9 @@ const runProject = Effect.fnUntraced(
661
661
  Effect.catchTags({
662
662
  ChosenTaskNotFound(_error) {
663
663
  if (executionMode._tag !== "ralph") {
664
- ralphDone = true
665
664
  return Effect.void
666
665
  }
666
+ ralphDone = true
667
667
  return Effect.log(
668
668
  `No more work to process for Ralph, ending after ${currentIteration + 1} iteration(s).`,
669
669
  )