lalph 0.3.89 → 0.3.90
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 +198 -128
- package/package.json +2 -2
- package/src/Agents/reviewer.ts +14 -3
- package/src/Agents/timeout.ts +30 -40
- package/src/Agents/worker.ts +12 -5
- package/src/commands/root.ts +119 -55
- package/src/domain/CurrentTask.ts +14 -0
package/dist/cli.mjs
CHANGED
|
@@ -181596,7 +181596,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
|
|
|
181596
181596
|
});
|
|
181597
181597
|
Ze.glob = Ze;
|
|
181598
181598
|
//#endregion
|
|
181599
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
181599
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ApplyPatch.js
|
|
181600
181600
|
/**
|
|
181601
181601
|
* @since 1.0.0
|
|
181602
181602
|
*/
|
|
@@ -196469,7 +196469,7 @@ var StreamableHTTPClientTransport = class {
|
|
|
196469
196469
|
}
|
|
196470
196470
|
};
|
|
196471
196471
|
//#endregion
|
|
196472
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
196472
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/McpClient.js
|
|
196473
196473
|
/**
|
|
196474
196474
|
* @since 1.0.0
|
|
196475
196475
|
*/
|
|
@@ -196514,7 +196514,7 @@ const layer$13 = effect$1(McpClient, gen(function* () {
|
|
|
196514
196514
|
});
|
|
196515
196515
|
}));
|
|
196516
196516
|
//#endregion
|
|
196517
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
196517
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ExaSearch.js
|
|
196518
196518
|
/**
|
|
196519
196519
|
* @since 1.0.0
|
|
196520
196520
|
*/
|
|
@@ -211464,7 +211464,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
|
211464
211464
|
exports.impl = impl;
|
|
211465
211465
|
}));
|
|
211466
211466
|
//#endregion
|
|
211467
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
211467
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/WebToMarkdown.js
|
|
211468
211468
|
/**
|
|
211469
211469
|
* @since 1.0.0
|
|
211470
211470
|
*/
|
|
@@ -215082,7 +215082,7 @@ const mapProviderResults = (inputLength, results) => {
|
|
|
215082
215082
|
return succeed$3(embeddings);
|
|
215083
215083
|
};
|
|
215084
215084
|
//#endregion
|
|
215085
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
215085
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ChunkRepo.js
|
|
215086
215086
|
/**
|
|
215087
215087
|
* @since 1.0.0
|
|
215088
215088
|
* @category Models
|
|
@@ -215213,7 +215213,7 @@ const layer$10 = effect$1(ChunkRepo, gen(function* () {
|
|
|
215213
215213
|
});
|
|
215214
215214
|
}));
|
|
215215
215215
|
//#endregion
|
|
215216
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
215216
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/CodeChunker.js
|
|
215217
215217
|
/**
|
|
215218
215218
|
* @since 1.0.0
|
|
215219
215219
|
*/
|
|
@@ -215806,7 +215806,7 @@ const run$1 = /* @__PURE__ */ make$25({});
|
|
|
215806
215806
|
*/
|
|
215807
215807
|
const layer$7 = (options) => effectDiscard(run$1(options));
|
|
215808
215808
|
//#endregion
|
|
215809
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
215809
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/internal/sqlite-vector.js
|
|
215810
215810
|
/**
|
|
215811
215811
|
* Binary extension for each platform
|
|
215812
215812
|
*/
|
|
@@ -215923,7 +215923,7 @@ function getExtensionPath() {
|
|
|
215923
215923
|
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`);
|
|
215924
215924
|
}
|
|
215925
215925
|
//#endregion
|
|
215926
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
215926
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/Sqlite.js
|
|
215927
215927
|
/**
|
|
215928
215928
|
* @since 1.0.0
|
|
215929
215929
|
*/
|
|
@@ -215951,7 +215951,7 @@ const SqliteLayer = (database) => layer$7({ loader: fromRecord({ "0001_create_ch
|
|
|
215951
215951
|
yield* fs.makeDirectory(directory, { recursive: true });
|
|
215952
215952
|
}))));
|
|
215953
215953
|
//#endregion
|
|
215954
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
215954
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/SemanticSearch.js
|
|
215955
215955
|
/**
|
|
215956
215956
|
* @since 1.0.0
|
|
215957
215957
|
*/
|
|
@@ -216093,7 +216093,7 @@ const maybeRemoveFile = (path) => serviceOption(SemanticSearch).pipe(flatMap$4(m
|
|
|
216093
216093
|
onSome: (service) => service.removeFile(path)
|
|
216094
216094
|
})));
|
|
216095
216095
|
//#endregion
|
|
216096
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
216096
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/AgentTools.js
|
|
216097
216097
|
/**
|
|
216098
216098
|
* @since 1.0.0
|
|
216099
216099
|
*/
|
|
@@ -216444,7 +216444,7 @@ const AgentToolHandlers = AgentToolHandlersNoDeps.pipe(provide$3([layer$12, laye
|
|
|
216444
216444
|
AgentToolHandlersNoDeps.pipe(provide$3([mock(ExaSearch)({}), mock(WebToMarkdown)({})]));
|
|
216445
216445
|
var ApplyPatchError = class extends TaggedClass$2("ApplyPatchError") {};
|
|
216446
216446
|
//#endregion
|
|
216447
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
216447
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/TypeBuilder.js
|
|
216448
216448
|
const resolveDocumentation = resolveAt("documentation");
|
|
216449
216449
|
const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
|
|
216450
216450
|
const Precedence = {
|
|
@@ -216717,7 +216717,7 @@ const render = (schema, options) => {
|
|
|
216717
216717
|
return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
|
|
216718
216718
|
};
|
|
216719
216719
|
//#endregion
|
|
216720
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
216720
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ToolkitRenderer.js
|
|
216721
216721
|
/**
|
|
216722
216722
|
* @since 1.0.0
|
|
216723
216723
|
*/
|
|
@@ -216739,7 +216739,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
|
|
|
216739
216739
|
}) });
|
|
216740
216740
|
};
|
|
216741
216741
|
//#endregion
|
|
216742
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
216742
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ScriptPreprocessing.js
|
|
216743
216743
|
const isIdentifierChar = (char) => char !== void 0 && /[A-Za-z0-9_$]/.test(char);
|
|
216744
216744
|
const isIdentifierStartChar = (char) => char !== void 0 && /[A-Za-z_$]/.test(char);
|
|
216745
216745
|
const hasIdentifierBoundary = (text, index, length) => !isIdentifierChar(text[index - 1]) && !isIdentifierChar(text[index + length]);
|
|
@@ -216785,11 +216785,16 @@ const needsTemplateEscaping = (text) => {
|
|
|
216785
216785
|
const normalizePatchEscapedQuotes = (text) => text.includes("*** Begin Patch") ? text.replace(/\\"([A-Za-z0-9_$.-]+)\\"/g, "\"$1\"") : text;
|
|
216786
216786
|
const escapeTemplateLiteralContent = (text) => {
|
|
216787
216787
|
const normalized = normalizePatchEscapedQuotes(text);
|
|
216788
|
+
const isPatchContent = normalized.includes("*** Begin Patch");
|
|
216788
216789
|
if (!needsTemplateEscaping(normalized)) return normalized;
|
|
216789
216790
|
let out = "";
|
|
216790
216791
|
for (let i = 0; i < normalized.length; i++) {
|
|
216791
216792
|
const char = normalized[i];
|
|
216792
216793
|
if (char === "\\") {
|
|
216794
|
+
if (!isPatchContent && (normalized[i + 1] === "`" || normalized[i + 1] === "$" && normalized[i + 2] === "{")) {
|
|
216795
|
+
out += "\\";
|
|
216796
|
+
continue;
|
|
216797
|
+
}
|
|
216793
216798
|
out += "\\\\";
|
|
216794
216799
|
continue;
|
|
216795
216800
|
}
|
|
@@ -216876,47 +216881,25 @@ const fixCallTemplateArgument = (script, functionName) => {
|
|
|
216876
216881
|
}
|
|
216877
216882
|
return out;
|
|
216878
216883
|
};
|
|
216879
|
-
const
|
|
216880
|
-
const out = /* @__PURE__ */ new Set();
|
|
216881
|
-
let cursor = 0;
|
|
216882
|
-
while (cursor < script.length) {
|
|
216883
|
-
const callStart = findNextIdentifier(script, functionName, cursor);
|
|
216884
|
-
if (callStart === -1) break;
|
|
216885
|
-
const openParen = skipWhitespace(script, callStart + functionName.length);
|
|
216886
|
-
if (script[openParen] !== "(") {
|
|
216887
|
-
cursor = callStart + functionName.length;
|
|
216888
|
-
continue;
|
|
216889
|
-
}
|
|
216890
|
-
const identifier = parseIdentifier(script, skipWhitespace(script, openParen + 1));
|
|
216891
|
-
if (identifier === void 0) {
|
|
216892
|
-
cursor = openParen + 1;
|
|
216893
|
-
continue;
|
|
216894
|
-
}
|
|
216895
|
-
const argumentEnd = skipWhitespace(script, identifier.end);
|
|
216896
|
-
if (script[argumentEnd] === ")" || script[argumentEnd] === ",") out.add(identifier.name);
|
|
216897
|
-
cursor = identifier.end;
|
|
216898
|
-
}
|
|
216899
|
-
return out;
|
|
216900
|
-
};
|
|
216901
|
-
const fixWriteFileContentTemplates = (script) => {
|
|
216884
|
+
const fixCallObjectPropertyTemplate = (script, functionName, propertyName) => {
|
|
216902
216885
|
let out = script;
|
|
216903
216886
|
let cursor = 0;
|
|
216904
216887
|
while (cursor < out.length) {
|
|
216905
|
-
const callStart = findNextIdentifier(out,
|
|
216888
|
+
const callStart = findNextIdentifier(out, functionName, cursor);
|
|
216906
216889
|
if (callStart === -1) break;
|
|
216907
|
-
const openParen = skipWhitespace(out, callStart +
|
|
216890
|
+
const openParen = skipWhitespace(out, callStart + functionName.length);
|
|
216908
216891
|
if (out[openParen] !== "(") {
|
|
216909
|
-
cursor = callStart +
|
|
216892
|
+
cursor = callStart + functionName.length;
|
|
216910
216893
|
continue;
|
|
216911
216894
|
}
|
|
216912
|
-
const
|
|
216913
|
-
if (
|
|
216895
|
+
const propertyKey = findNextIdentifier(out, propertyName, openParen + 1);
|
|
216896
|
+
if (propertyKey === -1) {
|
|
216914
216897
|
cursor = openParen + 1;
|
|
216915
216898
|
continue;
|
|
216916
216899
|
}
|
|
216917
|
-
const colon = skipWhitespace(out,
|
|
216900
|
+
const colon = skipWhitespace(out, propertyKey + propertyName.length);
|
|
216918
216901
|
if (out[colon] !== ":") {
|
|
216919
|
-
cursor =
|
|
216902
|
+
cursor = propertyKey + propertyName.length;
|
|
216920
216903
|
continue;
|
|
216921
216904
|
}
|
|
216922
216905
|
const templateStart = skipWhitespace(out, colon + 1);
|
|
@@ -216940,25 +216923,47 @@ const fixWriteFileContentTemplates = (script) => {
|
|
|
216940
216923
|
}
|
|
216941
216924
|
return out;
|
|
216942
216925
|
};
|
|
216943
|
-
const
|
|
216926
|
+
const collectCallArgumentIdentifiers = (script, functionName) => {
|
|
216944
216927
|
const out = /* @__PURE__ */ new Set();
|
|
216945
216928
|
let cursor = 0;
|
|
216946
216929
|
while (cursor < script.length) {
|
|
216947
|
-
const callStart = findNextIdentifier(script,
|
|
216930
|
+
const callStart = findNextIdentifier(script, functionName, cursor);
|
|
216948
216931
|
if (callStart === -1) break;
|
|
216949
|
-
const openParen = skipWhitespace(script, callStart +
|
|
216932
|
+
const openParen = skipWhitespace(script, callStart + functionName.length);
|
|
216950
216933
|
if (script[openParen] !== "(") {
|
|
216951
|
-
cursor = callStart +
|
|
216934
|
+
cursor = callStart + functionName.length;
|
|
216952
216935
|
continue;
|
|
216953
216936
|
}
|
|
216954
|
-
const
|
|
216955
|
-
if (
|
|
216937
|
+
const identifier = parseIdentifier(script, skipWhitespace(script, openParen + 1));
|
|
216938
|
+
if (identifier === void 0) {
|
|
216956
216939
|
cursor = openParen + 1;
|
|
216957
216940
|
continue;
|
|
216958
216941
|
}
|
|
216959
|
-
const
|
|
216960
|
-
if (script[
|
|
216961
|
-
|
|
216942
|
+
const argumentEnd = skipWhitespace(script, identifier.end);
|
|
216943
|
+
if (script[argumentEnd] === ")" || script[argumentEnd] === ",") out.add(identifier.name);
|
|
216944
|
+
cursor = identifier.end;
|
|
216945
|
+
}
|
|
216946
|
+
return out;
|
|
216947
|
+
};
|
|
216948
|
+
const collectCallObjectPropertyIdentifiers = (script, functionName, propertyName) => {
|
|
216949
|
+
const out = /* @__PURE__ */ new Set();
|
|
216950
|
+
let cursor = 0;
|
|
216951
|
+
while (cursor < script.length) {
|
|
216952
|
+
const callStart = findNextIdentifier(script, functionName, cursor);
|
|
216953
|
+
if (callStart === -1) break;
|
|
216954
|
+
const openParen = skipWhitespace(script, callStart + functionName.length);
|
|
216955
|
+
if (script[openParen] !== "(") {
|
|
216956
|
+
cursor = callStart + functionName.length;
|
|
216957
|
+
continue;
|
|
216958
|
+
}
|
|
216959
|
+
const propertyKey = findNextIdentifier(script, propertyName, openParen + 1);
|
|
216960
|
+
if (propertyKey === -1) {
|
|
216961
|
+
cursor = openParen + 1;
|
|
216962
|
+
continue;
|
|
216963
|
+
}
|
|
216964
|
+
const afterProperty = skipWhitespace(script, propertyKey + propertyName.length);
|
|
216965
|
+
if (script[afterProperty] === ":") {
|
|
216966
|
+
const valueStart = skipWhitespace(script, afterProperty + 1);
|
|
216962
216967
|
const identifier = parseIdentifier(script, valueStart);
|
|
216963
216968
|
if (identifier !== void 0) {
|
|
216964
216969
|
const valueEnd = skipWhitespace(script, identifier.end);
|
|
@@ -216967,15 +216972,17 @@ const collectWriteFileContentIdentifiers = (script) => {
|
|
|
216967
216972
|
cursor = valueStart + 1;
|
|
216968
216973
|
continue;
|
|
216969
216974
|
}
|
|
216970
|
-
if (script[
|
|
216971
|
-
out.add(
|
|
216972
|
-
cursor =
|
|
216975
|
+
if (script[afterProperty] === "}" || script[afterProperty] === ",") {
|
|
216976
|
+
out.add(propertyName);
|
|
216977
|
+
cursor = afterProperty + 1;
|
|
216973
216978
|
continue;
|
|
216974
216979
|
}
|
|
216975
|
-
cursor =
|
|
216980
|
+
cursor = afterProperty + 1;
|
|
216976
216981
|
}
|
|
216977
216982
|
return out;
|
|
216978
216983
|
};
|
|
216984
|
+
const callObjectPropertyTargets = [["writeFile", "content"], ["updateTask", "description"]];
|
|
216985
|
+
const fixTargetCallObjectPropertyTemplates = (script) => callObjectPropertyTargets.reduce((current, [functionName, propertyName]) => fixCallObjectPropertyTemplate(current, functionName, propertyName), script);
|
|
216979
216986
|
const fixAssignedTemplate = (script, variableName) => {
|
|
216980
216987
|
let out = script;
|
|
216981
216988
|
let cursor = 0;
|
|
@@ -217018,15 +217025,15 @@ const fixAssignedTemplate = (script, variableName) => {
|
|
|
217018
217025
|
const fixAssignedTemplatesForToolCalls = (script) => {
|
|
217019
217026
|
const identifiers = /* @__PURE__ */ new Set();
|
|
217020
217027
|
for (const functionName of ["applyPatch", "taskComplete"]) for (const identifier of collectCallArgumentIdentifiers(script, functionName)) identifiers.add(identifier);
|
|
217021
|
-
for (const identifier of
|
|
217028
|
+
for (const [functionName, propertyName] of callObjectPropertyTargets) for (const identifier of collectCallObjectPropertyIdentifiers(script, functionName, propertyName)) identifiers.add(identifier);
|
|
217022
217029
|
if (script.includes("*** Begin Patch")) identifiers.add("patch");
|
|
217023
217030
|
let out = script;
|
|
217024
217031
|
for (const identifier of identifiers) out = fixAssignedTemplate(out, identifier);
|
|
217025
217032
|
return out;
|
|
217026
217033
|
};
|
|
217027
|
-
const preprocessScript = (script) => fixAssignedTemplatesForToolCalls(["applyPatch", "taskComplete"].reduce((current, functionName) => fixCallTemplateArgument(current, functionName),
|
|
217034
|
+
const preprocessScript = (script) => fixAssignedTemplatesForToolCalls(["applyPatch", "taskComplete"].reduce((current, functionName) => fixCallTemplateArgument(current, functionName), fixTargetCallObjectPropertyTemplates(script)));
|
|
217028
217035
|
//#endregion
|
|
217029
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
217036
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/AgentExecutor.js
|
|
217030
217037
|
/**
|
|
217031
217038
|
* @since 1.0.0
|
|
217032
217039
|
*/
|
|
@@ -217211,7 +217218,7 @@ var QueueWriteStream = class extends Writable {
|
|
|
217211
217218
|
}
|
|
217212
217219
|
};
|
|
217213
217220
|
//#endregion
|
|
217214
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
217221
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/ScriptExtraction.js
|
|
217215
217222
|
const stripWrappingCodeFence = (script) => {
|
|
217216
217223
|
const lines = script.split(/\r?\n/);
|
|
217217
217224
|
if (lines.length < 2) return script;
|
|
@@ -218760,7 +218767,7 @@ const applySpanTransformer = (transformer, response, options) => {
|
|
|
218760
218767
|
});
|
|
218761
218768
|
};
|
|
218762
218769
|
//#endregion
|
|
218763
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
218770
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/Agent.js
|
|
218764
218771
|
/**
|
|
218765
218772
|
* @since 1.0.0
|
|
218766
218773
|
*/
|
|
@@ -230090,7 +230097,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
|
|
|
230090
230097
|
})));
|
|
230091
230098
|
});
|
|
230092
230099
|
//#endregion
|
|
230093
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
230100
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/CodexAuth.js
|
|
230094
230101
|
/**
|
|
230095
230102
|
* @since 1.0.0
|
|
230096
230103
|
*/
|
|
@@ -230310,7 +230317,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
|
|
|
230310
230317
|
static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
|
|
230311
230318
|
};
|
|
230312
230319
|
//#endregion
|
|
230313
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
230320
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/Codex.js
|
|
230314
230321
|
/**
|
|
230315
230322
|
* @since 1.0.0
|
|
230316
230323
|
*/
|
|
@@ -231622,7 +231629,7 @@ const getUsageDetailNumber = (details, field) => {
|
|
|
231622
231629
|
return typeof value === "number" ? value : void 0;
|
|
231623
231630
|
};
|
|
231624
231631
|
//#endregion
|
|
231625
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
231632
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/CopilotAuth.js
|
|
231626
231633
|
/**
|
|
231627
231634
|
* @since 1.0.0
|
|
231628
231635
|
*/
|
|
@@ -231813,7 +231820,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
|
|
|
231813
231820
|
static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
|
|
231814
231821
|
};
|
|
231815
231822
|
//#endregion
|
|
231816
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
231823
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/Copilot.js
|
|
231817
231824
|
/**
|
|
231818
231825
|
* @since 1.0.0
|
|
231819
231826
|
*/
|
|
@@ -232233,7 +232240,7 @@ Object.defineProperties(createChalk.prototype, styles);
|
|
|
232233
232240
|
const chalk = createChalk();
|
|
232234
232241
|
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
232235
232242
|
//#endregion
|
|
232236
|
-
//#region node_modules/.pnpm/clanka@0.2.
|
|
232243
|
+
//#region node_modules/.pnpm/clanka@0.2.18_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_500c9c5f2cf95b88472d3c06656714c8/node_modules/clanka/dist/OutputFormatter.js
|
|
232237
232244
|
/**
|
|
232238
232245
|
* @since 1.0.0
|
|
232239
232246
|
*/
|
|
@@ -240892,10 +240899,17 @@ const runClanka = fnUntraced(function* (options) {
|
|
|
240892
240899
|
tools: options.mode === "ralph" ? void 0 : options.mode === "choose" ? TaskChooseTools : TaskTools
|
|
240893
240900
|
}).pipe(merge$6(ClankaModels.get(options.model)))), provide$1([layerUndici, TaskToolsHandlers]));
|
|
240894
240901
|
//#endregion
|
|
240902
|
+
//#region src/domain/CurrentTask.ts
|
|
240903
|
+
const CurrentTask = taggedEnum();
|
|
240904
|
+
//#endregion
|
|
240895
240905
|
//#region src/Agents/worker.ts
|
|
240896
240906
|
const agentWorker = fnUntraced(function* (options) {
|
|
240897
240907
|
const pathService = yield* Path$1;
|
|
240898
240908
|
const worktree = yield* Worktree;
|
|
240909
|
+
const prdFilePath = CurrentTask.$match(options.currentTask, {
|
|
240910
|
+
task: () => pathService.join(".lalph", "prd.yml"),
|
|
240911
|
+
ralph: () => void 0
|
|
240912
|
+
});
|
|
240899
240913
|
if (!options.preset.cliAgent.command) {
|
|
240900
240914
|
yield* runClanka({
|
|
240901
240915
|
directory: worktree.directory,
|
|
@@ -240917,13 +240931,16 @@ ${research}`
|
|
|
240917
240931
|
stallTimeout: options.stallTimeout,
|
|
240918
240932
|
maxContext: options.maxContext,
|
|
240919
240933
|
steer: options.steer,
|
|
240920
|
-
mode: options.
|
|
240934
|
+
mode: CurrentTask.$match(options.currentTask, {
|
|
240935
|
+
task: () => "default",
|
|
240936
|
+
ralph: () => "ralph"
|
|
240937
|
+
})
|
|
240921
240938
|
});
|
|
240922
240939
|
return ExitCode(0);
|
|
240923
240940
|
}
|
|
240924
240941
|
return yield* pipe$1(options.preset.cliAgent.command({
|
|
240925
240942
|
prompt: options.prompt,
|
|
240926
|
-
prdFilePath
|
|
240943
|
+
prdFilePath,
|
|
240927
240944
|
extraArgs: options.preset.extraArgs
|
|
240928
240945
|
}), setCwd(worktree.directory), options.preset.withCommandPrefix).pipe(worktree.execWithStallTimeout({
|
|
240929
240946
|
cliAgent: options.preset.cliAgent,
|
|
@@ -241113,12 +241130,20 @@ const agentReviewer = fnUntraced(function* (options) {
|
|
|
241113
241130
|
const worktree = yield* Worktree;
|
|
241114
241131
|
const promptGen = yield* PromptGen;
|
|
241115
241132
|
const gitFlow = yield* GitFlow;
|
|
241133
|
+
const mode = CurrentTask.$match(options.currentTask, {
|
|
241134
|
+
task: () => "default",
|
|
241135
|
+
ralph: () => "ralph"
|
|
241136
|
+
});
|
|
241137
|
+
const system = CurrentTask.$match(options.currentTask, {
|
|
241138
|
+
task: () => promptGen.systemClanka(options),
|
|
241139
|
+
ralph: () => void 0
|
|
241140
|
+
});
|
|
241116
241141
|
const customInstructions = yield* pipe$1(fs.readFileString(pathService.join(worktree.directory, "LALPH_REVIEW.md")), option$1);
|
|
241117
241142
|
if (!options.preset.cliAgent.command) {
|
|
241118
241143
|
yield* runClanka({
|
|
241119
241144
|
directory: worktree.directory,
|
|
241120
241145
|
model: options.preset.extraArgs.join(" "),
|
|
241121
|
-
system
|
|
241146
|
+
system,
|
|
241122
241147
|
prompt: match$10(customInstructions, {
|
|
241123
241148
|
onNone: () => promptGen.promptReview({
|
|
241124
241149
|
prompt: options.instructions,
|
|
@@ -241131,7 +241156,7 @@ const agentReviewer = fnUntraced(function* (options) {
|
|
|
241131
241156
|
})
|
|
241132
241157
|
}),
|
|
241133
241158
|
stallTimeout: options.stallTimeout,
|
|
241134
|
-
mode
|
|
241159
|
+
mode
|
|
241135
241160
|
});
|
|
241136
241161
|
return ExitCode(0);
|
|
241137
241162
|
}
|
|
@@ -241160,32 +241185,48 @@ const agentTimeout = fnUntraced(function* (options) {
|
|
|
241160
241185
|
const pathService = yield* Path$1;
|
|
241161
241186
|
const worktree = yield* Worktree;
|
|
241162
241187
|
const promptGen = yield* PromptGen;
|
|
241188
|
+
const timeoutMode = CurrentTask.$match(options.currentTask, {
|
|
241189
|
+
task: ({ task }) => ({
|
|
241190
|
+
mode: "default",
|
|
241191
|
+
system: promptGen.systemClanka(options),
|
|
241192
|
+
clankaPrompt: promptGen.promptTimeoutClanka({
|
|
241193
|
+
taskId: task.id,
|
|
241194
|
+
specsDirectory: options.specsDirectory
|
|
241195
|
+
}),
|
|
241196
|
+
cliPrompt: promptGen.promptTimeout({
|
|
241197
|
+
taskId: task.id,
|
|
241198
|
+
specsDirectory: options.specsDirectory
|
|
241199
|
+
}),
|
|
241200
|
+
prdFilePath: pathService.join(".lalph", "prd.yml")
|
|
241201
|
+
}),
|
|
241202
|
+
ralph: ({ task, specFile }) => ({
|
|
241203
|
+
mode: "ralph",
|
|
241204
|
+
system: void 0,
|
|
241205
|
+
clankaPrompt: promptGen.promptTimeoutRalph({
|
|
241206
|
+
task,
|
|
241207
|
+
specFile
|
|
241208
|
+
}),
|
|
241209
|
+
cliPrompt: promptGen.promptTimeoutRalph({
|
|
241210
|
+
task,
|
|
241211
|
+
specFile
|
|
241212
|
+
}),
|
|
241213
|
+
prdFilePath: void 0
|
|
241214
|
+
})
|
|
241215
|
+
});
|
|
241163
241216
|
if (!options.preset.cliAgent.command) {
|
|
241164
241217
|
yield* runClanka({
|
|
241165
241218
|
directory: worktree.directory,
|
|
241166
241219
|
model: options.preset.extraArgs.join(" "),
|
|
241167
|
-
system:
|
|
241168
|
-
prompt:
|
|
241169
|
-
task: options.task.task,
|
|
241170
|
-
specFile: options.task.specFile
|
|
241171
|
-
}) : promptGen.promptTimeoutClanka({
|
|
241172
|
-
taskId: options.task.task.id,
|
|
241173
|
-
specsDirectory: options.specsDirectory
|
|
241174
|
-
}),
|
|
241220
|
+
system: timeoutMode.system,
|
|
241221
|
+
prompt: timeoutMode.clankaPrompt,
|
|
241175
241222
|
stallTimeout: options.stallTimeout,
|
|
241176
|
-
mode:
|
|
241223
|
+
mode: timeoutMode.mode
|
|
241177
241224
|
});
|
|
241178
241225
|
return ExitCode(0);
|
|
241179
241226
|
}
|
|
241180
241227
|
return yield* pipe$1(options.preset.cliAgent.command({
|
|
241181
|
-
prompt:
|
|
241182
|
-
|
|
241183
|
-
specFile: options.task.specFile
|
|
241184
|
-
}) : promptGen.promptTimeout({
|
|
241185
|
-
taskId: options.task.task.id,
|
|
241186
|
-
specsDirectory: options.specsDirectory
|
|
241187
|
-
}),
|
|
241188
|
-
prdFilePath: options.task._tag === "ralph" ? void 0 : pathService.join(".lalph", "prd.yml"),
|
|
241228
|
+
prompt: timeoutMode.cliPrompt,
|
|
241229
|
+
prdFilePath: timeoutMode.prdFilePath,
|
|
241189
241230
|
extraArgs: options.preset.extraArgs
|
|
241190
241231
|
}), setCwd(worktree.directory), options.preset.withCommandPrefix).pipe(worktree.execWithStallTimeout({
|
|
241191
241232
|
cliAgent: options.preset.cliAgent,
|
|
@@ -241330,7 +241371,7 @@ const run = fnUntraced(function* (options) {
|
|
|
241330
241371
|
prompt: instructions,
|
|
241331
241372
|
research: researchResult,
|
|
241332
241373
|
steer,
|
|
241333
|
-
|
|
241374
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd })
|
|
241334
241375
|
}).pipe(provideService$2(CurrentTaskRef, issueRef), catchStallInReview, withSpan$1("Main.agentWorker"))}`);
|
|
241335
241376
|
if (options.review) {
|
|
241336
241377
|
yield* source.updateIssue({
|
|
@@ -241344,7 +241385,7 @@ const run = fnUntraced(function* (options) {
|
|
|
241344
241385
|
stallTimeout: options.stallTimeout,
|
|
241345
241386
|
preset: taskPreset,
|
|
241346
241387
|
instructions,
|
|
241347
|
-
|
|
241388
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd })
|
|
241348
241389
|
}).pipe(catchStallInReview, withSpan$1("Main.agentReviewer"));
|
|
241349
241390
|
yield* source.updateIssue({
|
|
241350
241391
|
projectId,
|
|
@@ -241356,10 +241397,7 @@ const run = fnUntraced(function* (options) {
|
|
|
241356
241397
|
specsDirectory: options.specsDirectory,
|
|
241357
241398
|
stallTimeout: options.stallTimeout,
|
|
241358
241399
|
preset: taskPreset,
|
|
241359
|
-
task:
|
|
241360
|
-
_tag: "task",
|
|
241361
|
-
task: chosenTask.prd
|
|
241362
|
-
}
|
|
241400
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd })
|
|
241363
241401
|
})), raceFirst(watchTaskState({ issueId: taskId })), as$1(false), catchTag$1("TaskStateChanged", (error) => log$1(`Task ${error.issueId} moved to ${error.state}; cancelling run.`).pipe(as$1(true))))) return;
|
|
241364
241402
|
yield* gitFlow.postWork({
|
|
241365
241403
|
worktree,
|
|
@@ -241409,7 +241447,10 @@ const runRalph = fnUntraced(function* (options) {
|
|
|
241409
241447
|
prompt: instructions,
|
|
241410
241448
|
research: researchResult,
|
|
241411
241449
|
maxContext: options.maxContext,
|
|
241412
|
-
|
|
241450
|
+
currentTask: CurrentTask.ralph({
|
|
241451
|
+
task: chosenTask,
|
|
241452
|
+
specFile: options.specFile
|
|
241453
|
+
})
|
|
241413
241454
|
}).pipe(withSpan$1("Main.worker"))}`);
|
|
241414
241455
|
if (options.review) {
|
|
241415
241456
|
registry.update(currentWorker.state, (s) => s.transitionTo(WorkerStatus.Reviewing({ issueId: "ralph" })));
|
|
@@ -241418,18 +241459,20 @@ const runRalph = fnUntraced(function* (options) {
|
|
|
241418
241459
|
stallTimeout: options.stallTimeout,
|
|
241419
241460
|
preset,
|
|
241420
241461
|
instructions,
|
|
241421
|
-
|
|
241462
|
+
currentTask: CurrentTask.ralph({
|
|
241463
|
+
task: chosenTask,
|
|
241464
|
+
specFile: options.specFile
|
|
241465
|
+
})
|
|
241422
241466
|
}).pipe(withSpan$1("Main.review"));
|
|
241423
241467
|
}
|
|
241424
241468
|
}).pipe(timeout(options.runTimeout), tapErrorTag("TimeoutError", () => agentTimeout({
|
|
241425
241469
|
specsDirectory: "",
|
|
241426
241470
|
stallTimeout: options.stallTimeout,
|
|
241427
241471
|
preset,
|
|
241428
|
-
|
|
241429
|
-
_tag: "ralph",
|
|
241472
|
+
currentTask: CurrentTask.ralph({
|
|
241430
241473
|
task: chosenTask,
|
|
241431
241474
|
specFile: options.specFile
|
|
241432
|
-
}
|
|
241475
|
+
})
|
|
241433
241476
|
})));
|
|
241434
241477
|
yield* gitFlow.postWork({
|
|
241435
241478
|
worktree,
|
|
@@ -241437,35 +241480,41 @@ const runRalph = fnUntraced(function* (options) {
|
|
|
241437
241480
|
issueId: ""
|
|
241438
241481
|
});
|
|
241439
241482
|
}, scoped$1, provide$1(SemanticSearchLayer.pipe(provideMerge([Prd.layerNoop, Worktree.layer])), { local: true }));
|
|
241483
|
+
var RalphSpecMissing = class extends TaggedError("RalphSpecMissing") {
|
|
241484
|
+
message = `Project "${this.projectId}" is configured with gitFlow="ralph" but is missing "ralphSpec". Run 'lalph projects edit' and set "Path to Ralph spec file".`;
|
|
241485
|
+
};
|
|
241440
241486
|
const runProject = fnUntraced(function* (options) {
|
|
241441
241487
|
const isFinite = Number.isFinite(options.iterations);
|
|
241442
241488
|
const iterationsDisplay = isFinite ? options.iterations : "unlimited";
|
|
241443
241489
|
const semaphore = makeUnsafe$9(options.project.concurrency);
|
|
241444
241490
|
const fibers = yield* make$54();
|
|
241445
|
-
|
|
241446
|
-
|
|
241447
|
-
|
|
241448
|
-
|
|
241449
|
-
|
|
241450
|
-
|
|
241451
|
-
|
|
241452
|
-
|
|
241453
|
-
|
|
241454
|
-
|
|
241455
|
-
|
|
241456
|
-
|
|
241457
|
-
|
|
241458
|
-
|
|
241459
|
-
|
|
241460
|
-
|
|
241491
|
+
let executionMode;
|
|
241492
|
+
if (options.project.gitFlow === "ralph") {
|
|
241493
|
+
if (!options.project.ralphSpec) return yield* new RalphSpecMissing({ projectId: options.project.id });
|
|
241494
|
+
executionMode = {
|
|
241495
|
+
_tag: "ralph",
|
|
241496
|
+
specFile: options.project.ralphSpec
|
|
241497
|
+
};
|
|
241498
|
+
} else executionMode = {
|
|
241499
|
+
_tag: "standard",
|
|
241500
|
+
gitFlow: options.project.gitFlow
|
|
241501
|
+
};
|
|
241502
|
+
const resolveGitFlowLayer = () => {
|
|
241503
|
+
if (executionMode._tag === "ralph") return GitFlowRalph;
|
|
241504
|
+
if (executionMode.gitFlow === "commit") return GitFlowCommit;
|
|
241505
|
+
return GitFlowPR;
|
|
241506
|
+
};
|
|
241507
|
+
const resolveRunEffect = (startedDeferred) => {
|
|
241508
|
+
if (executionMode._tag === "ralph") return runRalph({
|
|
241461
241509
|
targetBranch: options.project.targetBranch,
|
|
241462
241510
|
stallTimeout: options.stallTimeout,
|
|
241463
241511
|
runTimeout: options.runTimeout,
|
|
241464
|
-
maxContext: options.maxContext,
|
|
241465
241512
|
review: options.project.reviewAgent,
|
|
241466
241513
|
research: options.project.researchAgent,
|
|
241467
|
-
specFile:
|
|
241468
|
-
|
|
241514
|
+
specFile: executionMode.specFile,
|
|
241515
|
+
maxContext: options.maxContext
|
|
241516
|
+
});
|
|
241517
|
+
return run({
|
|
241469
241518
|
startedDeferred,
|
|
241470
241519
|
targetBranch: options.project.targetBranch,
|
|
241471
241520
|
specsDirectory: options.specsDirectory,
|
|
@@ -241473,27 +241522,48 @@ const runProject = fnUntraced(function* (options) {
|
|
|
241473
241522
|
runTimeout: options.runTimeout,
|
|
241474
241523
|
review: options.project.reviewAgent,
|
|
241475
241524
|
research: options.project.researchAgent
|
|
241476
|
-
})
|
|
241525
|
+
});
|
|
241526
|
+
};
|
|
241527
|
+
const handleNoMoreWork = (currentIteration, setIterations) => {
|
|
241528
|
+
if (executionMode._tag === "ralph") return void_$2;
|
|
241529
|
+
if (isFinite) {
|
|
241530
|
+
setIterations(currentIteration);
|
|
241531
|
+
return log$1(`No more work to process, ending after ${currentIteration} iteration(s).`);
|
|
241532
|
+
}
|
|
241533
|
+
return andThen(size$3(fibers) <= 1 ? log$1("No more work to process, waiting 30 seconds...") : void_$2, sleep(seconds(30)));
|
|
241534
|
+
};
|
|
241535
|
+
yield* resetInProgress.pipe(withSpan$1("Main.resetInProgress"));
|
|
241536
|
+
yield* log$1(`Executing ${iterationsDisplay} iteration(s) with concurrency ${options.project.concurrency}`);
|
|
241537
|
+
let iterations = options.iterations;
|
|
241538
|
+
let iteration = 0;
|
|
241539
|
+
let quit = false;
|
|
241540
|
+
yield* mount(activeWorkerLoggingAtom);
|
|
241541
|
+
while (true) {
|
|
241542
|
+
yield* semaphore.take(1);
|
|
241543
|
+
if (quit || isFinite && iteration >= iterations) break;
|
|
241544
|
+
const currentIteration = iteration;
|
|
241545
|
+
const startedDeferred = yield* make$85();
|
|
241546
|
+
let ralphDone = false;
|
|
241547
|
+
const gitFlowLayer = resolveGitFlowLayer();
|
|
241548
|
+
const fiber = yield* checkForWork(options.project).pipe(andThen(resolveRunEffect(startedDeferred).pipe(provide$1(gitFlowLayer, { local: true }), withWorkerState(options.project.id))), catchTags$1({
|
|
241477
241549
|
ChosenTaskNotFound(_error) {
|
|
241478
|
-
if (
|
|
241550
|
+
if (executionMode._tag !== "ralph") {
|
|
241479
241551
|
ralphDone = true;
|
|
241480
|
-
return
|
|
241552
|
+
return void_$2;
|
|
241481
241553
|
}
|
|
241482
|
-
return
|
|
241554
|
+
return log$1(`No more work to process for Ralph, ending after ${currentIteration + 1} iteration(s).`);
|
|
241483
241555
|
},
|
|
241484
241556
|
NoMoreWork(_error) {
|
|
241485
|
-
|
|
241486
|
-
iterations =
|
|
241487
|
-
|
|
241488
|
-
}
|
|
241489
|
-
return andThen(size$3(fibers) <= 1 ? log$1("No more work to process, waiting 30 seconds...") : void_$2, sleep(seconds(30)));
|
|
241557
|
+
return handleNoMoreWork(currentIteration, (newIterations) => {
|
|
241558
|
+
iterations = newIterations;
|
|
241559
|
+
});
|
|
241490
241560
|
},
|
|
241491
241561
|
QuitError(_error) {
|
|
241492
241562
|
quit = true;
|
|
241493
241563
|
return void_$2;
|
|
241494
241564
|
}
|
|
241495
241565
|
}), catchCause$1((cause) => logWarning(cause).pipe(andThen(sleep(seconds(10))))), ensuring$2(semaphore.release(1)), ensuring$2(completeWith(startedDeferred, void_$2)), run$2(fibers));
|
|
241496
|
-
if (
|
|
241566
|
+
if (executionMode._tag === "ralph") {
|
|
241497
241567
|
yield* await_(fiber);
|
|
241498
241568
|
if (ralphDone) break;
|
|
241499
241569
|
} else yield* _await(startedDeferred);
|
|
@@ -241844,7 +241914,7 @@ const commandEdit = make$58("edit").pipe(withDescription("Open the selected proj
|
|
|
241844
241914
|
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));
|
|
241845
241915
|
//#endregion
|
|
241846
241916
|
//#region package.json
|
|
241847
|
-
var version = "0.3.
|
|
241917
|
+
var version = "0.3.90";
|
|
241848
241918
|
//#endregion
|
|
241849
241919
|
//#region src/commands/projects/ls.ts
|
|
241850
241920
|
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.
|
|
4
|
+
"version": "0.3.90",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
|
|
46
46
|
"@octokit/types": "^16.0.0",
|
|
47
47
|
"@typescript/native-preview": "7.0.0-dev.20260319.1",
|
|
48
|
-
"clanka": "^0.2.
|
|
48
|
+
"clanka": "^0.2.18",
|
|
49
49
|
"concurrently": "^9.2.1",
|
|
50
50
|
"effect": "https://pkg.pr.new/Effect-TS/effect-smol/effect@89c3e98",
|
|
51
51
|
"husky": "^9.1.7",
|
package/src/Agents/reviewer.ts
CHANGED
|
@@ -6,13 +6,14 @@ import { GitFlow } from "../GitFlow.ts"
|
|
|
6
6
|
import type { CliAgentPreset } from "../domain/CliAgentPreset.ts"
|
|
7
7
|
import { ExitCode } from "effect/unstable/process/ChildProcessSpawner"
|
|
8
8
|
import { runClanka } from "../Clanka.ts"
|
|
9
|
+
import { CurrentTask } from "../domain/CurrentTask.ts"
|
|
9
10
|
|
|
10
11
|
export const agentReviewer = Effect.fnUntraced(function* (options: {
|
|
11
12
|
readonly specsDirectory: string
|
|
12
13
|
readonly stallTimeout: Duration.Duration
|
|
13
14
|
readonly preset: CliAgentPreset
|
|
14
15
|
readonly instructions: string
|
|
15
|
-
readonly
|
|
16
|
+
readonly currentTask: CurrentTask
|
|
16
17
|
}) {
|
|
17
18
|
const fs = yield* FileSystem.FileSystem
|
|
18
19
|
const pathService = yield* Path.Path
|
|
@@ -20,6 +21,16 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
|
|
|
20
21
|
const promptGen = yield* PromptGen
|
|
21
22
|
const gitFlow = yield* GitFlow
|
|
22
23
|
|
|
24
|
+
const mode = CurrentTask.$match(options.currentTask, {
|
|
25
|
+
task: () => "default" as const,
|
|
26
|
+
ralph: () => "ralph" as const,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const system = CurrentTask.$match(options.currentTask, {
|
|
30
|
+
task: () => promptGen.systemClanka(options),
|
|
31
|
+
ralph: () => undefined,
|
|
32
|
+
})
|
|
33
|
+
|
|
23
34
|
const customInstructions = yield* pipe(
|
|
24
35
|
fs.readFileString(pathService.join(worktree.directory, "LALPH_REVIEW.md")),
|
|
25
36
|
Effect.option,
|
|
@@ -30,7 +41,7 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
|
|
|
30
41
|
yield* runClanka({
|
|
31
42
|
directory: worktree.directory,
|
|
32
43
|
model: options.preset.extraArgs.join(" "),
|
|
33
|
-
system
|
|
44
|
+
system,
|
|
34
45
|
prompt: Option.match(customInstructions, {
|
|
35
46
|
onNone: () =>
|
|
36
47
|
promptGen.promptReview({
|
|
@@ -45,7 +56,7 @@ export const agentReviewer = Effect.fnUntraced(function* (options: {
|
|
|
45
56
|
}),
|
|
46
57
|
}),
|
|
47
58
|
stallTimeout: options.stallTimeout,
|
|
48
|
-
mode
|
|
59
|
+
mode,
|
|
49
60
|
})
|
|
50
61
|
return ExitCode(0)
|
|
51
62
|
}
|
package/src/Agents/timeout.ts
CHANGED
|
@@ -2,71 +2,61 @@ import { Duration, Effect, Path, pipe } from "effect"
|
|
|
2
2
|
import { PromptGen } from "../PromptGen.ts"
|
|
3
3
|
import { ChildProcess } from "effect/unstable/process"
|
|
4
4
|
import { Worktree } from "../Worktree.ts"
|
|
5
|
-
import type { PrdIssue } from "../domain/PrdIssue.ts"
|
|
6
5
|
import type { CliAgentPreset } from "../domain/CliAgentPreset.ts"
|
|
7
6
|
import { ExitCode } from "effect/unstable/process/ChildProcessSpawner"
|
|
8
7
|
import { runClanka } from "../Clanka.ts"
|
|
8
|
+
import { CurrentTask } from "../domain/CurrentTask.ts"
|
|
9
9
|
|
|
10
10
|
export const agentTimeout = Effect.fnUntraced(function* (options: {
|
|
11
11
|
readonly specsDirectory: string
|
|
12
12
|
readonly stallTimeout: Duration.Duration
|
|
13
13
|
readonly preset: CliAgentPreset
|
|
14
|
-
readonly
|
|
15
|
-
| {
|
|
16
|
-
readonly _tag: "task"
|
|
17
|
-
readonly task: PrdIssue
|
|
18
|
-
}
|
|
19
|
-
| {
|
|
20
|
-
readonly _tag: "ralph"
|
|
21
|
-
readonly task: string
|
|
22
|
-
readonly specFile: string
|
|
23
|
-
}
|
|
14
|
+
readonly currentTask: CurrentTask
|
|
24
15
|
}) {
|
|
25
16
|
const pathService = yield* Path.Path
|
|
26
17
|
const worktree = yield* Worktree
|
|
27
18
|
const promptGen = yield* PromptGen
|
|
28
19
|
|
|
20
|
+
const timeoutMode = CurrentTask.$match(options.currentTask, {
|
|
21
|
+
task: ({ task }) => ({
|
|
22
|
+
mode: "default" as const,
|
|
23
|
+
system: promptGen.systemClanka(options),
|
|
24
|
+
clankaPrompt: promptGen.promptTimeoutClanka({
|
|
25
|
+
taskId: task.id!,
|
|
26
|
+
specsDirectory: options.specsDirectory,
|
|
27
|
+
}),
|
|
28
|
+
cliPrompt: promptGen.promptTimeout({
|
|
29
|
+
taskId: task.id!,
|
|
30
|
+
specsDirectory: options.specsDirectory,
|
|
31
|
+
}),
|
|
32
|
+
prdFilePath: pathService.join(".lalph", "prd.yml"),
|
|
33
|
+
}),
|
|
34
|
+
ralph: ({ task, specFile }) => ({
|
|
35
|
+
mode: "ralph" as const,
|
|
36
|
+
system: undefined,
|
|
37
|
+
clankaPrompt: promptGen.promptTimeoutRalph({ task, specFile }),
|
|
38
|
+
cliPrompt: promptGen.promptTimeoutRalph({ task, specFile }),
|
|
39
|
+
prdFilePath: undefined,
|
|
40
|
+
}),
|
|
41
|
+
})
|
|
42
|
+
|
|
29
43
|
// use clanka
|
|
30
44
|
if (!options.preset.cliAgent.command) {
|
|
31
45
|
yield* runClanka({
|
|
32
46
|
directory: worktree.directory,
|
|
33
47
|
model: options.preset.extraArgs.join(" "),
|
|
34
|
-
system:
|
|
35
|
-
|
|
36
|
-
? undefined
|
|
37
|
-
: promptGen.systemClanka(options),
|
|
38
|
-
prompt:
|
|
39
|
-
options.task._tag === "ralph"
|
|
40
|
-
? promptGen.promptTimeoutRalph({
|
|
41
|
-
task: options.task.task,
|
|
42
|
-
specFile: options.task.specFile,
|
|
43
|
-
})
|
|
44
|
-
: promptGen.promptTimeoutClanka({
|
|
45
|
-
taskId: options.task.task.id!,
|
|
46
|
-
specsDirectory: options.specsDirectory,
|
|
47
|
-
}),
|
|
48
|
+
system: timeoutMode.system,
|
|
49
|
+
prompt: timeoutMode.clankaPrompt,
|
|
48
50
|
stallTimeout: options.stallTimeout,
|
|
49
|
-
mode:
|
|
51
|
+
mode: timeoutMode.mode,
|
|
50
52
|
})
|
|
51
53
|
return ExitCode(0)
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
const timeoutCommand = pipe(
|
|
55
57
|
options.preset.cliAgent.command({
|
|
56
|
-
prompt:
|
|
57
|
-
|
|
58
|
-
? promptGen.promptTimeoutRalph({
|
|
59
|
-
task: options.task.task,
|
|
60
|
-
specFile: options.task.specFile,
|
|
61
|
-
})
|
|
62
|
-
: promptGen.promptTimeout({
|
|
63
|
-
taskId: options.task.task.id!,
|
|
64
|
-
specsDirectory: options.specsDirectory,
|
|
65
|
-
}),
|
|
66
|
-
prdFilePath:
|
|
67
|
-
options.task._tag === "ralph"
|
|
68
|
-
? undefined
|
|
69
|
-
: pathService.join(".lalph", "prd.yml"),
|
|
58
|
+
prompt: timeoutMode.cliPrompt,
|
|
59
|
+
prdFilePath: timeoutMode.prdFilePath,
|
|
70
60
|
extraArgs: options.preset.extraArgs,
|
|
71
61
|
}),
|
|
72
62
|
ChildProcess.setCwd(worktree.directory),
|
package/src/Agents/worker.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { CliAgentPreset } from "../domain/CliAgentPreset.ts"
|
|
|
5
5
|
import { runClanka } from "../Clanka.ts"
|
|
6
6
|
import { ExitCode } from "effect/unstable/process/ChildProcessSpawner"
|
|
7
7
|
import { Prompt } from "effect/unstable/ai"
|
|
8
|
+
import { CurrentTask } from "../domain/CurrentTask.ts"
|
|
8
9
|
|
|
9
10
|
export const agentWorker = Effect.fnUntraced(function* (options: {
|
|
10
11
|
readonly stallTimeout: Duration.Duration
|
|
@@ -14,11 +15,16 @@ export const agentWorker = Effect.fnUntraced(function* (options: {
|
|
|
14
15
|
readonly research: Option.Option<string>
|
|
15
16
|
readonly steer?: Stream.Stream<string>
|
|
16
17
|
readonly maxContext?: number | undefined
|
|
17
|
-
readonly
|
|
18
|
+
readonly currentTask: CurrentTask
|
|
18
19
|
}) {
|
|
19
20
|
const pathService = yield* Path.Path
|
|
20
21
|
const worktree = yield* Worktree
|
|
21
22
|
|
|
23
|
+
const prdFilePath = CurrentTask.$match(options.currentTask, {
|
|
24
|
+
task: () => pathService.join(".lalph", "prd.yml"),
|
|
25
|
+
ralph: () => undefined,
|
|
26
|
+
})
|
|
27
|
+
|
|
22
28
|
// use clanka
|
|
23
29
|
if (!options.preset.cliAgent.command) {
|
|
24
30
|
yield* runClanka({
|
|
@@ -45,7 +51,10 @@ ${research}`,
|
|
|
45
51
|
stallTimeout: options.stallTimeout,
|
|
46
52
|
maxContext: options.maxContext,
|
|
47
53
|
steer: options.steer,
|
|
48
|
-
mode: options.
|
|
54
|
+
mode: CurrentTask.$match(options.currentTask, {
|
|
55
|
+
task: () => "default" as const,
|
|
56
|
+
ralph: () => "ralph" as const,
|
|
57
|
+
}),
|
|
49
58
|
})
|
|
50
59
|
return ExitCode(0)
|
|
51
60
|
}
|
|
@@ -53,9 +62,7 @@ ${research}`,
|
|
|
53
62
|
const cliCommand = pipe(
|
|
54
63
|
options.preset.cliAgent.command({
|
|
55
64
|
prompt: options.prompt,
|
|
56
|
-
prdFilePath
|
|
57
|
-
? undefined
|
|
58
|
-
: pathService.join(".lalph", "prd.yml"),
|
|
65
|
+
prdFilePath,
|
|
59
66
|
extraArgs: options.preset.extraArgs,
|
|
60
67
|
}),
|
|
61
68
|
ChildProcess.setCwd(worktree.directory),
|
package/src/commands/root.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Config,
|
|
3
|
+
Data,
|
|
3
4
|
Deferred,
|
|
4
5
|
Duration,
|
|
5
6
|
Effect,
|
|
@@ -18,7 +19,6 @@ import {
|
|
|
18
19
|
Scope,
|
|
19
20
|
Semaphore,
|
|
20
21
|
Stream,
|
|
21
|
-
Unify,
|
|
22
22
|
} from "effect"
|
|
23
23
|
import { PromptGen } from "../PromptGen.ts"
|
|
24
24
|
import { Prd } from "../Prd.ts"
|
|
@@ -66,6 +66,7 @@ import type { OutputFormatter } from "clanka"
|
|
|
66
66
|
import { ClankaMuxerLayer, SemanticSearchLayer } from "../Clanka.ts"
|
|
67
67
|
import { agentResearcher } from "../Agents/researcher.ts"
|
|
68
68
|
import { agentChooserRalph } from "../Agents/chooserRalph.ts"
|
|
69
|
+
import { CurrentTask } from "../domain/CurrentTask.ts"
|
|
69
70
|
|
|
70
71
|
// Main iteration run logic
|
|
71
72
|
|
|
@@ -268,7 +269,7 @@ const run = Effect.fnUntraced(
|
|
|
268
269
|
prompt: instructions,
|
|
269
270
|
research: researchResult,
|
|
270
271
|
steer,
|
|
271
|
-
|
|
272
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd }),
|
|
272
273
|
}).pipe(
|
|
273
274
|
Effect.provideService(CurrentTaskRef, issueRef),
|
|
274
275
|
catchStallInReview,
|
|
@@ -295,7 +296,7 @@ const run = Effect.fnUntraced(
|
|
|
295
296
|
stallTimeout: options.stallTimeout,
|
|
296
297
|
preset: taskPreset,
|
|
297
298
|
instructions,
|
|
298
|
-
|
|
299
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd }),
|
|
299
300
|
}).pipe(catchStallInReview, Effect.withSpan("Main.agentReviewer"))
|
|
300
301
|
|
|
301
302
|
yield* source.updateIssue({
|
|
@@ -311,7 +312,7 @@ const run = Effect.fnUntraced(
|
|
|
311
312
|
specsDirectory: options.specsDirectory,
|
|
312
313
|
stallTimeout: options.stallTimeout,
|
|
313
314
|
preset: taskPreset,
|
|
314
|
-
|
|
315
|
+
currentTask: CurrentTask.task({ task: chosenTask.prd }),
|
|
315
316
|
}),
|
|
316
317
|
),
|
|
317
318
|
Effect.raceFirst(watchTaskState({ issueId: taskId })),
|
|
@@ -470,7 +471,10 @@ const runRalph = Effect.fnUntraced(
|
|
|
470
471
|
prompt: instructions,
|
|
471
472
|
research: researchResult,
|
|
472
473
|
maxContext: options.maxContext,
|
|
473
|
-
|
|
474
|
+
currentTask: CurrentTask.ralph({
|
|
475
|
+
task: chosenTask,
|
|
476
|
+
specFile: options.specFile,
|
|
477
|
+
}),
|
|
474
478
|
}).pipe(Effect.withSpan("Main.worker"))
|
|
475
479
|
yield* Effect.log(`Agent exited with code: ${exitCode}`)
|
|
476
480
|
|
|
@@ -487,7 +491,10 @@ const runRalph = Effect.fnUntraced(
|
|
|
487
491
|
stallTimeout: options.stallTimeout,
|
|
488
492
|
preset,
|
|
489
493
|
instructions,
|
|
490
|
-
|
|
494
|
+
currentTask: CurrentTask.ralph({
|
|
495
|
+
task: chosenTask,
|
|
496
|
+
specFile: options.specFile,
|
|
497
|
+
}),
|
|
491
498
|
}).pipe(Effect.withSpan("Main.review"))
|
|
492
499
|
}
|
|
493
500
|
}).pipe(
|
|
@@ -497,7 +504,10 @@ const runRalph = Effect.fnUntraced(
|
|
|
497
504
|
specsDirectory: "",
|
|
498
505
|
stallTimeout: options.stallTimeout,
|
|
499
506
|
preset,
|
|
500
|
-
|
|
507
|
+
currentTask: CurrentTask.ralph({
|
|
508
|
+
task: chosenTask,
|
|
509
|
+
specFile: options.specFile,
|
|
510
|
+
}),
|
|
501
511
|
}),
|
|
502
512
|
),
|
|
503
513
|
)
|
|
@@ -517,6 +527,22 @@ const runRalph = Effect.fnUntraced(
|
|
|
517
527
|
),
|
|
518
528
|
)
|
|
519
529
|
|
|
530
|
+
class RalphSpecMissing extends Data.TaggedError("RalphSpecMissing")<{
|
|
531
|
+
readonly projectId: Project["id"]
|
|
532
|
+
}> {
|
|
533
|
+
readonly message = `Project "${this.projectId}" is configured with gitFlow="ralph" but is missing "ralphSpec". Run 'lalph projects edit' and set "Path to Ralph spec file".`
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
type ProjectExecutionMode =
|
|
537
|
+
| {
|
|
538
|
+
readonly _tag: "standard"
|
|
539
|
+
readonly gitFlow: "pr" | "commit"
|
|
540
|
+
}
|
|
541
|
+
| {
|
|
542
|
+
readonly _tag: "ralph"
|
|
543
|
+
readonly specFile: string
|
|
544
|
+
}
|
|
545
|
+
|
|
520
546
|
const runProject = Effect.fnUntraced(
|
|
521
547
|
function* (options: {
|
|
522
548
|
readonly iterations: number
|
|
@@ -531,6 +557,79 @@ const runProject = Effect.fnUntraced(
|
|
|
531
557
|
const semaphore = Semaphore.makeUnsafe(options.project.concurrency)
|
|
532
558
|
const fibers = yield* FiberSet.make()
|
|
533
559
|
|
|
560
|
+
let executionMode: ProjectExecutionMode
|
|
561
|
+
if (options.project.gitFlow === "ralph") {
|
|
562
|
+
if (!options.project.ralphSpec) {
|
|
563
|
+
return yield* new RalphSpecMissing({
|
|
564
|
+
projectId: options.project.id,
|
|
565
|
+
})
|
|
566
|
+
}
|
|
567
|
+
executionMode = {
|
|
568
|
+
_tag: "ralph",
|
|
569
|
+
specFile: options.project.ralphSpec,
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
executionMode = {
|
|
573
|
+
_tag: "standard",
|
|
574
|
+
gitFlow: options.project.gitFlow,
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const resolveGitFlowLayer = () => {
|
|
579
|
+
if (executionMode._tag === "ralph") {
|
|
580
|
+
return GitFlowRalph
|
|
581
|
+
}
|
|
582
|
+
if (executionMode.gitFlow === "commit") {
|
|
583
|
+
return GitFlowCommit
|
|
584
|
+
}
|
|
585
|
+
return GitFlowPR
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const resolveRunEffect = (startedDeferred: Deferred.Deferred<void>) => {
|
|
589
|
+
if (executionMode._tag === "ralph") {
|
|
590
|
+
return runRalph({
|
|
591
|
+
targetBranch: options.project.targetBranch,
|
|
592
|
+
stallTimeout: options.stallTimeout,
|
|
593
|
+
runTimeout: options.runTimeout,
|
|
594
|
+
review: options.project.reviewAgent,
|
|
595
|
+
research: options.project.researchAgent,
|
|
596
|
+
specFile: executionMode.specFile,
|
|
597
|
+
maxContext: options.maxContext,
|
|
598
|
+
})
|
|
599
|
+
}
|
|
600
|
+
return run({
|
|
601
|
+
startedDeferred,
|
|
602
|
+
targetBranch: options.project.targetBranch,
|
|
603
|
+
specsDirectory: options.specsDirectory,
|
|
604
|
+
stallTimeout: options.stallTimeout,
|
|
605
|
+
runTimeout: options.runTimeout,
|
|
606
|
+
review: options.project.reviewAgent,
|
|
607
|
+
research: options.project.researchAgent,
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const handleNoMoreWork = (
|
|
612
|
+
currentIteration: number,
|
|
613
|
+
setIterations: (iterations: number) => void,
|
|
614
|
+
) => {
|
|
615
|
+
if (executionMode._tag === "ralph") {
|
|
616
|
+
return Effect.void
|
|
617
|
+
}
|
|
618
|
+
if (isFinite) {
|
|
619
|
+
// If we have a finite number of iterations, we exit when no more
|
|
620
|
+
// work is found
|
|
621
|
+
setIterations(currentIteration)
|
|
622
|
+
return Effect.log(
|
|
623
|
+
`No more work to process, ending after ${currentIteration} iteration(s).`,
|
|
624
|
+
)
|
|
625
|
+
}
|
|
626
|
+
const log =
|
|
627
|
+
Iterable.size(fibers) <= 1
|
|
628
|
+
? Effect.log("No more work to process, waiting 30 seconds...")
|
|
629
|
+
: Effect.void
|
|
630
|
+
return Effect.andThen(log, Effect.sleep(Duration.seconds(30)))
|
|
631
|
+
}
|
|
632
|
+
|
|
534
633
|
yield* resetInProgress.pipe(Effect.withSpan("Main.resetInProgress"))
|
|
535
634
|
|
|
536
635
|
yield* Effect.log(
|
|
@@ -554,65 +653,28 @@ const runProject = Effect.fnUntraced(
|
|
|
554
653
|
const startedDeferred = yield* Deferred.make<void>()
|
|
555
654
|
let ralphDone = false
|
|
556
655
|
|
|
557
|
-
const
|
|
558
|
-
const isRalph = gitFlow === "ralph"
|
|
559
|
-
const gitFlowLayer =
|
|
560
|
-
gitFlow === "commit"
|
|
561
|
-
? GitFlowCommit
|
|
562
|
-
: gitFlow === "ralph"
|
|
563
|
-
? GitFlowRalph
|
|
564
|
-
: GitFlowPR
|
|
656
|
+
const gitFlowLayer = resolveGitFlowLayer()
|
|
565
657
|
const fiber = yield* checkForWork(options.project).pipe(
|
|
566
658
|
Effect.andThen(
|
|
567
|
-
|
|
568
|
-
isRalph
|
|
569
|
-
? runRalph({
|
|
570
|
-
targetBranch: options.project.targetBranch,
|
|
571
|
-
stallTimeout: options.stallTimeout,
|
|
572
|
-
runTimeout: options.runTimeout,
|
|
573
|
-
maxContext: options.maxContext,
|
|
574
|
-
review: options.project.reviewAgent,
|
|
575
|
-
research: options.project.researchAgent,
|
|
576
|
-
specFile: options.project.ralphSpec!,
|
|
577
|
-
})
|
|
578
|
-
: run({
|
|
579
|
-
startedDeferred,
|
|
580
|
-
targetBranch: options.project.targetBranch,
|
|
581
|
-
specsDirectory: options.specsDirectory,
|
|
582
|
-
stallTimeout: options.stallTimeout,
|
|
583
|
-
runTimeout: options.runTimeout,
|
|
584
|
-
review: options.project.reviewAgent,
|
|
585
|
-
research: options.project.researchAgent,
|
|
586
|
-
}),
|
|
587
|
-
).pipe(
|
|
659
|
+
resolveRunEffect(startedDeferred).pipe(
|
|
588
660
|
Effect.provide(gitFlowLayer, { local: true }),
|
|
589
661
|
withWorkerState(options.project.id),
|
|
590
662
|
),
|
|
591
663
|
),
|
|
592
664
|
Effect.catchTags({
|
|
593
665
|
ChosenTaskNotFound(_error) {
|
|
594
|
-
if (
|
|
666
|
+
if (executionMode._tag !== "ralph") {
|
|
595
667
|
ralphDone = true
|
|
596
|
-
return Effect.
|
|
597
|
-
`No more work to process for Ralph, ending after ${currentIteration + 1} iteration(s).`,
|
|
598
|
-
)
|
|
668
|
+
return Effect.void
|
|
599
669
|
}
|
|
600
|
-
return Effect.
|
|
670
|
+
return Effect.log(
|
|
671
|
+
`No more work to process for Ralph, ending after ${currentIteration + 1} iteration(s).`,
|
|
672
|
+
)
|
|
601
673
|
},
|
|
602
674
|
NoMoreWork(_error) {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
iterations = currentIteration
|
|
607
|
-
return Effect.log(
|
|
608
|
-
`No more work to process, ending after ${currentIteration} iteration(s).`,
|
|
609
|
-
)
|
|
610
|
-
}
|
|
611
|
-
const log =
|
|
612
|
-
Iterable.size(fibers) <= 1
|
|
613
|
-
? Effect.log("No more work to process, waiting 30 seconds...")
|
|
614
|
-
: Effect.void
|
|
615
|
-
return Effect.andThen(log, Effect.sleep(Duration.seconds(30)))
|
|
675
|
+
return handleNoMoreWork(currentIteration, (newIterations) => {
|
|
676
|
+
iterations = newIterations
|
|
677
|
+
})
|
|
616
678
|
},
|
|
617
679
|
QuitError(_error) {
|
|
618
680
|
quit = true
|
|
@@ -628,12 +690,14 @@ const runProject = Effect.fnUntraced(
|
|
|
628
690
|
Effect.ensuring(Deferred.completeWith(startedDeferred, Effect.void)),
|
|
629
691
|
FiberSet.run(fibers),
|
|
630
692
|
)
|
|
631
|
-
|
|
693
|
+
|
|
694
|
+
if (executionMode._tag === "ralph") {
|
|
632
695
|
yield* Fiber.await(fiber)
|
|
633
696
|
if (ralphDone) break
|
|
634
697
|
} else {
|
|
635
698
|
yield* Deferred.await(startedDeferred)
|
|
636
699
|
}
|
|
700
|
+
|
|
637
701
|
iteration++
|
|
638
702
|
}
|
|
639
703
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Data } from "effect"
|
|
2
|
+
import type { PrdIssue } from "./PrdIssue.ts"
|
|
3
|
+
|
|
4
|
+
export type CurrentTask = Data.TaggedEnum<{
|
|
5
|
+
task: {
|
|
6
|
+
readonly task: PrdIssue
|
|
7
|
+
}
|
|
8
|
+
ralph: {
|
|
9
|
+
readonly task: string
|
|
10
|
+
readonly specFile: string
|
|
11
|
+
}
|
|
12
|
+
}>
|
|
13
|
+
|
|
14
|
+
export const CurrentTask = Data.taggedEnum<CurrentTask>()
|