wildcrane-runner 0.6.4 → 0.6.5
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/akb/dist/kanban.mjs +371 -616
- package/dist/akb/package.json +1 -1
- package/dist/launcher.mjs +2 -2
- package/dist/runner.mjs +336 -346
- package/package.json +1 -1
package/dist/runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// wildcrane-runner 0.6.
|
|
1
|
+
// wildcrane-runner 0.6.5 — built by runner/scripts/build.mjs. Do not edit.
|
|
2
2
|
import { createRequire as __ai4kanbanRequire } from 'node:module'
|
|
3
3
|
const require = __ai4kanbanRequire(import.meta.url)
|
|
4
4
|
var __create = Object.create;
|
|
@@ -4382,15 +4382,15 @@ var require_react_dom_server_legacy_node_production = __commonJS({
|
|
|
4382
4382
|
childState.suspenseyImages && (parentState.suspenseyImages = true);
|
|
4383
4383
|
}
|
|
4384
4384
|
function createRenderState(resumableState, generateStaticMarkup) {
|
|
4385
|
-
var
|
|
4385
|
+
var idPrefix = resumableState.idPrefix, bootstrapChunks = [], bootstrapScriptContent = resumableState.bootstrapScriptContent, bootstrapScripts = resumableState.bootstrapScripts, bootstrapModules = resumableState.bootstrapModules;
|
|
4386
4386
|
void 0 !== bootstrapScriptContent && (bootstrapChunks.push("<script"), pushCompletedShellIdAttribute(bootstrapChunks, resumableState), bootstrapChunks.push(
|
|
4387
4387
|
">",
|
|
4388
4388
|
("" + bootstrapScriptContent).replace(scriptRegex, scriptReplacer),
|
|
4389
4389
|
"</script>"
|
|
4390
4390
|
));
|
|
4391
|
-
bootstrapScriptContent =
|
|
4392
|
-
var JSCompiler_object_inline_segmentPrefix_1724 =
|
|
4393
|
-
|
|
4391
|
+
bootstrapScriptContent = idPrefix + "P:";
|
|
4392
|
+
var JSCompiler_object_inline_segmentPrefix_1724 = idPrefix + "S:";
|
|
4393
|
+
idPrefix += "B:";
|
|
4394
4394
|
var JSCompiler_object_inline_preconnects_1738 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_fontPreloads_1739 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_highImagePreloads_1740 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_styles_1741 = /* @__PURE__ */ new Map(), JSCompiler_object_inline_bootstrapScripts_1742 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_scripts_1743 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_bulkPreloads_1744 = /* @__PURE__ */ new Set(), JSCompiler_object_inline_preloads_1745 = {
|
|
4395
4395
|
images: /* @__PURE__ */ new Map(),
|
|
4396
4396
|
stylesheets: /* @__PURE__ */ new Map(),
|
|
@@ -4449,7 +4449,7 @@ var require_react_dom_server_legacy_node_production = __commonJS({
|
|
|
4449
4449
|
return {
|
|
4450
4450
|
placeholderPrefix: bootstrapScriptContent,
|
|
4451
4451
|
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1724,
|
|
4452
|
-
boundaryPrefix:
|
|
4452
|
+
boundaryPrefix: idPrefix,
|
|
4453
4453
|
startInlineScript: "<script",
|
|
4454
4454
|
startInlineStyle: "<style",
|
|
4455
4455
|
preamble: { htmlChunks: null, headChunks: null, bodyChunks: null },
|
|
@@ -7804,7 +7804,7 @@ var require_react_dom_server_node_production = __commonJS({
|
|
|
7804
7804
|
'<script nonce="' + escapeTextForBrowser(externalRuntimeConfig) + '"'
|
|
7805
7805
|
), nonceStyle = "string" === typeof nonce ? void 0 : nonce && nonce.style, inlineStyleWithNonce = void 0 === nonceStyle ? startInlineStyle : stringToPrecomputedChunk(
|
|
7806
7806
|
'<style nonce="' + escapeTextForBrowser(nonceStyle) + '"'
|
|
7807
|
-
),
|
|
7807
|
+
), idPrefix = resumableState.idPrefix, bootstrapChunks = [], bootstrapScriptContent = resumableState.bootstrapScriptContent, bootstrapScripts = resumableState.bootstrapScripts, bootstrapModules = resumableState.bootstrapModules;
|
|
7808
7808
|
void 0 !== bootstrapScriptContent && (bootstrapChunks.push(inlineScriptWithNonce), pushCompletedShellIdAttribute(bootstrapChunks, resumableState), bootstrapChunks.push(
|
|
7809
7809
|
endOfStartTag,
|
|
7810
7810
|
("" + bootstrapScriptContent).replace(scriptRegex, scriptReplacer),
|
|
@@ -7825,9 +7825,9 @@ var require_react_dom_server_node_production = __commonJS({
|
|
|
7825
7825
|
remainingCapacity: 2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)
|
|
7826
7826
|
} : null;
|
|
7827
7827
|
onHeaders = {
|
|
7828
|
-
placeholderPrefix: stringToPrecomputedChunk(
|
|
7829
|
-
segmentPrefix: stringToPrecomputedChunk(
|
|
7830
|
-
boundaryPrefix: stringToPrecomputedChunk(
|
|
7828
|
+
placeholderPrefix: stringToPrecomputedChunk(idPrefix + "P:"),
|
|
7829
|
+
segmentPrefix: stringToPrecomputedChunk(idPrefix + "S:"),
|
|
7830
|
+
boundaryPrefix: stringToPrecomputedChunk(idPrefix + "B:"),
|
|
7831
7831
|
startInlineScript: inlineScriptWithNonce,
|
|
7832
7832
|
startInlineStyle: inlineStyleWithNonce,
|
|
7833
7833
|
preamble: createPreambleState(),
|
|
@@ -7865,12 +7865,12 @@ var require_react_dom_server_node_production = __commonJS({
|
|
|
7865
7865
|
};
|
|
7866
7866
|
if (void 0 !== bootstrapScripts)
|
|
7867
7867
|
for (importMap = 0; importMap < bootstrapScripts.length; importMap++)
|
|
7868
|
-
|
|
7868
|
+
idPrefix = bootstrapScripts[importMap], nonceStyle = inlineScriptWithNonce = void 0, inlineStyleWithNonce = {
|
|
7869
7869
|
rel: "preload",
|
|
7870
7870
|
as: "script",
|
|
7871
7871
|
fetchPriority: "low",
|
|
7872
7872
|
nonce
|
|
7873
|
-
}, "string" === typeof
|
|
7873
|
+
}, "string" === typeof idPrefix ? inlineStyleWithNonce.href = maxHeadersLength = idPrefix : (inlineStyleWithNonce.href = maxHeadersLength = idPrefix.src, inlineStyleWithNonce.integrity = nonceStyle = "string" === typeof idPrefix.integrity ? idPrefix.integrity : void 0, inlineStyleWithNonce.crossOrigin = inlineScriptWithNonce = "string" === typeof idPrefix || null == idPrefix.crossOrigin ? void 0 : "use-credentials" === idPrefix.crossOrigin ? "use-credentials" : ""), idPrefix = resumableState, bootstrapScriptContent = maxHeadersLength, idPrefix.scriptResources[bootstrapScriptContent] = null, idPrefix.moduleScriptResources[bootstrapScriptContent] = null, idPrefix = [], pushLinkImpl(idPrefix, inlineStyleWithNonce), onHeaders.bootstrapScripts.add(idPrefix), bootstrapChunks.push(
|
|
7874
7874
|
startScriptSrc,
|
|
7875
7875
|
escapeTextForBrowser(maxHeadersLength),
|
|
7876
7876
|
attributeEnd
|
|
@@ -16247,16 +16247,16 @@ var require_react_dom_server_legacy_node_development = __commonJS({
|
|
|
16247
16247
|
childState.suspenseyImages && (parentState.suspenseyImages = true);
|
|
16248
16248
|
}
|
|
16249
16249
|
function createRenderState(resumableState, generateStaticMarkup) {
|
|
16250
|
-
var
|
|
16250
|
+
var idPrefix = resumableState.idPrefix, bootstrapChunks = [], bootstrapScriptContent = resumableState.bootstrapScriptContent, bootstrapScripts = resumableState.bootstrapScripts, bootstrapModules = resumableState.bootstrapModules;
|
|
16251
16251
|
void 0 !== bootstrapScriptContent && (bootstrapChunks.push("<script"), pushCompletedShellIdAttribute(bootstrapChunks, resumableState), bootstrapChunks.push(
|
|
16252
16252
|
endOfStartTag,
|
|
16253
16253
|
escapeEntireInlineScriptContent(bootstrapScriptContent),
|
|
16254
16254
|
endInlineScript
|
|
16255
16255
|
));
|
|
16256
|
-
|
|
16257
|
-
placeholderPrefix:
|
|
16258
|
-
segmentPrefix:
|
|
16259
|
-
boundaryPrefix:
|
|
16256
|
+
idPrefix = {
|
|
16257
|
+
placeholderPrefix: idPrefix + "P:",
|
|
16258
|
+
segmentPrefix: idPrefix + "S:",
|
|
16259
|
+
boundaryPrefix: idPrefix + "B:",
|
|
16260
16260
|
startInlineScript: "<script",
|
|
16261
16261
|
startInlineStyle: "<style",
|
|
16262
16262
|
preamble: { htmlChunks: null, headChunks: null, bodyChunks: null },
|
|
@@ -16301,7 +16301,7 @@ var require_react_dom_server_legacy_node_development = __commonJS({
|
|
|
16301
16301
|
nonce: void 0
|
|
16302
16302
|
};
|
|
16303
16303
|
"string" === typeof scriptConfig ? props.href = src = scriptConfig : (props.href = src = scriptConfig.src, props.integrity = integrity = "string" === typeof scriptConfig.integrity ? scriptConfig.integrity : void 0, props.crossOrigin = crossOrigin = "string" === typeof scriptConfig || null == scriptConfig.crossOrigin ? void 0 : "use-credentials" === scriptConfig.crossOrigin ? "use-credentials" : "");
|
|
16304
|
-
preloadBootstrapScriptOrModule(resumableState,
|
|
16304
|
+
preloadBootstrapScriptOrModule(resumableState, idPrefix, src, props);
|
|
16305
16305
|
bootstrapChunks.push(
|
|
16306
16306
|
'<script src="',
|
|
16307
16307
|
escapeTextForBrowser(src),
|
|
@@ -16328,7 +16328,7 @@ var require_react_dom_server_legacy_node_development = __commonJS({
|
|
|
16328
16328
|
nonce: void 0
|
|
16329
16329
|
}, "string" === typeof bootstrapScriptContent ? integrity.href = scriptConfig = bootstrapScriptContent : (integrity.href = scriptConfig = bootstrapScriptContent.src, integrity.integrity = crossOrigin = "string" === typeof bootstrapScriptContent.integrity ? bootstrapScriptContent.integrity : void 0, integrity.crossOrigin = src = "string" === typeof bootstrapScriptContent || null == bootstrapScriptContent.crossOrigin ? void 0 : "use-credentials" === bootstrapScriptContent.crossOrigin ? "use-credentials" : ""), preloadBootstrapScriptOrModule(
|
|
16330
16330
|
resumableState,
|
|
16331
|
-
|
|
16331
|
+
idPrefix,
|
|
16332
16332
|
scriptConfig,
|
|
16333
16333
|
integrity
|
|
16334
16334
|
), bootstrapChunks.push(
|
|
@@ -16345,31 +16345,31 @@ var require_react_dom_server_legacy_node_development = __commonJS({
|
|
|
16345
16345
|
attributeEnd
|
|
16346
16346
|
), pushCompletedShellIdAttribute(bootstrapChunks, resumableState), bootstrapChunks.push(' async=""></script>');
|
|
16347
16347
|
return {
|
|
16348
|
-
placeholderPrefix:
|
|
16349
|
-
segmentPrefix:
|
|
16350
|
-
boundaryPrefix:
|
|
16351
|
-
startInlineScript:
|
|
16352
|
-
startInlineStyle:
|
|
16353
|
-
preamble:
|
|
16354
|
-
externalRuntimeScript:
|
|
16355
|
-
bootstrapChunks:
|
|
16356
|
-
importMapChunks:
|
|
16357
|
-
onHeaders:
|
|
16358
|
-
headers:
|
|
16359
|
-
resets:
|
|
16360
|
-
charsetChunks:
|
|
16361
|
-
viewportChunks:
|
|
16362
|
-
hoistableChunks:
|
|
16363
|
-
preconnects:
|
|
16364
|
-
fontPreloads:
|
|
16365
|
-
highImagePreloads:
|
|
16366
|
-
styles:
|
|
16367
|
-
bootstrapScripts:
|
|
16368
|
-
scripts:
|
|
16369
|
-
bulkPreloads:
|
|
16370
|
-
preloads:
|
|
16371
|
-
nonce:
|
|
16372
|
-
stylesToHoist:
|
|
16348
|
+
placeholderPrefix: idPrefix.placeholderPrefix,
|
|
16349
|
+
segmentPrefix: idPrefix.segmentPrefix,
|
|
16350
|
+
boundaryPrefix: idPrefix.boundaryPrefix,
|
|
16351
|
+
startInlineScript: idPrefix.startInlineScript,
|
|
16352
|
+
startInlineStyle: idPrefix.startInlineStyle,
|
|
16353
|
+
preamble: idPrefix.preamble,
|
|
16354
|
+
externalRuntimeScript: idPrefix.externalRuntimeScript,
|
|
16355
|
+
bootstrapChunks: idPrefix.bootstrapChunks,
|
|
16356
|
+
importMapChunks: idPrefix.importMapChunks,
|
|
16357
|
+
onHeaders: idPrefix.onHeaders,
|
|
16358
|
+
headers: idPrefix.headers,
|
|
16359
|
+
resets: idPrefix.resets,
|
|
16360
|
+
charsetChunks: idPrefix.charsetChunks,
|
|
16361
|
+
viewportChunks: idPrefix.viewportChunks,
|
|
16362
|
+
hoistableChunks: idPrefix.hoistableChunks,
|
|
16363
|
+
preconnects: idPrefix.preconnects,
|
|
16364
|
+
fontPreloads: idPrefix.fontPreloads,
|
|
16365
|
+
highImagePreloads: idPrefix.highImagePreloads,
|
|
16366
|
+
styles: idPrefix.styles,
|
|
16367
|
+
bootstrapScripts: idPrefix.bootstrapScripts,
|
|
16368
|
+
scripts: idPrefix.scripts,
|
|
16369
|
+
bulkPreloads: idPrefix.bulkPreloads,
|
|
16370
|
+
preloads: idPrefix.preloads,
|
|
16371
|
+
nonce: idPrefix.nonce,
|
|
16372
|
+
stylesToHoist: idPrefix.stylesToHoist,
|
|
16373
16373
|
generateStaticMarkup
|
|
16374
16374
|
};
|
|
16375
16375
|
}
|
|
@@ -21749,7 +21749,7 @@ var require_react_dom_server_node_development = __commonJS({
|
|
|
21749
21749
|
'<script nonce="' + escapeTextForBrowser(externalRuntimeConfig) + '"'
|
|
21750
21750
|
), nonceStyle = "string" === typeof nonce ? void 0 : nonce && nonce.style, inlineStyleWithNonce = void 0 === nonceStyle ? startInlineStyle : stringToPrecomputedChunk(
|
|
21751
21751
|
'<style nonce="' + escapeTextForBrowser(nonceStyle) + '"'
|
|
21752
|
-
),
|
|
21752
|
+
), idPrefix = resumableState.idPrefix, bootstrapChunks = [], bootstrapScriptContent = resumableState.bootstrapScriptContent, bootstrapScripts = resumableState.bootstrapScripts, bootstrapModules = resumableState.bootstrapModules;
|
|
21753
21753
|
void 0 !== bootstrapScriptContent && (bootstrapChunks.push(inlineScriptWithNonce), pushCompletedShellIdAttribute(bootstrapChunks, resumableState), bootstrapChunks.push(
|
|
21754
21754
|
endOfStartTag,
|
|
21755
21755
|
escapeEntireInlineScriptContent(bootstrapScriptContent),
|
|
@@ -21774,9 +21774,9 @@ var require_react_dom_server_node_development = __commonJS({
|
|
|
21774
21774
|
remainingCapacity: 2 + ("number" === typeof maxHeadersLength ? maxHeadersLength : 2e3)
|
|
21775
21775
|
} : null;
|
|
21776
21776
|
onHeaders = {
|
|
21777
|
-
placeholderPrefix: stringToPrecomputedChunk(
|
|
21778
|
-
segmentPrefix: stringToPrecomputedChunk(
|
|
21779
|
-
boundaryPrefix: stringToPrecomputedChunk(
|
|
21777
|
+
placeholderPrefix: stringToPrecomputedChunk(idPrefix + "P:"),
|
|
21778
|
+
segmentPrefix: stringToPrecomputedChunk(idPrefix + "S:"),
|
|
21779
|
+
boundaryPrefix: stringToPrecomputedChunk(idPrefix + "B:"),
|
|
21780
21780
|
startInlineScript: inlineScriptWithNonce,
|
|
21781
21781
|
startInlineStyle: inlineStyleWithNonce,
|
|
21782
21782
|
preamble: createPreambleState(),
|
|
@@ -21814,16 +21814,16 @@ var require_react_dom_server_node_development = __commonJS({
|
|
|
21814
21814
|
};
|
|
21815
21815
|
if (void 0 !== bootstrapScripts)
|
|
21816
21816
|
for (importMap = 0; importMap < bootstrapScripts.length; importMap++)
|
|
21817
|
-
maxHeadersLength = bootstrapScripts[importMap], inlineStyleWithNonce = nonceStyle = void 0,
|
|
21817
|
+
maxHeadersLength = bootstrapScripts[importMap], inlineStyleWithNonce = nonceStyle = void 0, idPrefix = {
|
|
21818
21818
|
rel: "preload",
|
|
21819
21819
|
as: "script",
|
|
21820
21820
|
fetchPriority: "low",
|
|
21821
21821
|
nonce
|
|
21822
|
-
}, "string" === typeof maxHeadersLength ?
|
|
21822
|
+
}, "string" === typeof maxHeadersLength ? idPrefix.href = inlineScriptWithNonce = maxHeadersLength : (idPrefix.href = inlineScriptWithNonce = maxHeadersLength.src, idPrefix.integrity = inlineStyleWithNonce = "string" === typeof maxHeadersLength.integrity ? maxHeadersLength.integrity : void 0, idPrefix.crossOrigin = nonceStyle = "string" === typeof maxHeadersLength || null == maxHeadersLength.crossOrigin ? void 0 : "use-credentials" === maxHeadersLength.crossOrigin ? "use-credentials" : ""), preloadBootstrapScriptOrModule(
|
|
21823
21823
|
resumableState,
|
|
21824
21824
|
onHeaders,
|
|
21825
21825
|
inlineScriptWithNonce,
|
|
21826
|
-
|
|
21826
|
+
idPrefix
|
|
21827
21827
|
), bootstrapChunks.push(
|
|
21828
21828
|
startScriptSrc,
|
|
21829
21829
|
escapeTextForBrowser(inlineScriptWithNonce),
|
|
@@ -84355,7 +84355,7 @@ function alive(pid) {
|
|
|
84355
84355
|
return e2.code === "EPERM";
|
|
84356
84356
|
}
|
|
84357
84357
|
}
|
|
84358
|
-
var sleep = (
|
|
84358
|
+
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
84359
84359
|
|
|
84360
84360
|
// src/home.ts
|
|
84361
84361
|
import crypto from "node:crypto";
|
|
@@ -84453,9 +84453,9 @@ function status(line) {
|
|
|
84453
84453
|
}
|
|
84454
84454
|
|
|
84455
84455
|
// src/protocol.ts
|
|
84456
|
-
var VERSION = true ? "0.6.
|
|
84457
|
-
var AKB_VERSION = true ? "0.11.
|
|
84458
|
-
var AKB_CONTRACT = true ?
|
|
84456
|
+
var VERSION = true ? "0.6.5" : "0.0.0";
|
|
84457
|
+
var AKB_VERSION = true ? "0.11.4" : "0.0.0";
|
|
84458
|
+
var AKB_CONTRACT = true ? 2 : 0;
|
|
84459
84459
|
var EXIT_REFUSED = 10;
|
|
84460
84460
|
var EXIT_OUTDATED = 11;
|
|
84461
84461
|
|
|
@@ -85940,8 +85940,8 @@ function createTail(log) {
|
|
|
85940
85940
|
// ../cli/package.json
|
|
85941
85941
|
var package_default = {
|
|
85942
85942
|
name: "wildcrane",
|
|
85943
|
-
version: "0.11.
|
|
85944
|
-
akbContract:
|
|
85943
|
+
version: "0.11.4",
|
|
85944
|
+
akbContract: 2,
|
|
85945
85945
|
description: "WildCrane's `akb` command \u2014 scaffold the Markdown board under docs/kanban/, put an agent on a card, and carry the flows the agent works by.",
|
|
85946
85946
|
keywords: [
|
|
85947
85947
|
"kanban",
|
|
@@ -86936,6 +86936,7 @@ var REPO_ROOT = "";
|
|
|
86936
86936
|
var KANBAN = "";
|
|
86937
86937
|
var TODO = "";
|
|
86938
86938
|
var ARCHIVE = "";
|
|
86939
|
+
var REJECTIONS_TO_REVIEW = ".sync";
|
|
86939
86940
|
var ARCHIVE_MD = "";
|
|
86940
86941
|
var README = "";
|
|
86941
86942
|
var MODULES_MD = "";
|
|
@@ -88041,6 +88042,7 @@ var DEFAULT_HARNESS = HARNESSES[0];
|
|
|
88041
88042
|
checkHarnesses(HARNESSES);
|
|
88042
88043
|
|
|
88043
88044
|
// ../cli/src/lib/agent/env.ts
|
|
88045
|
+
var SCHEDULED_AGENTS_ENV = "AI4KANBAN_SCHEDULED_AGENTS";
|
|
88044
88046
|
var SESSION_VARS = {
|
|
88045
88047
|
"claude-code": "CLAUDE_CODE_SESSION_ID",
|
|
88046
88048
|
codex: "CODEX_THREAD_ID"
|
|
@@ -88253,7 +88255,7 @@ var secretsSet = () => Object.fromEntries(Object.entries(readAll()).map(([id, ke
|
|
|
88253
88255
|
var RUNTIMES = ["claude-code", "codex", "cursor", "opencode", "kimi", "dsh", "zcode", "grok"];
|
|
88254
88256
|
var PROTOCOL = 11;
|
|
88255
88257
|
var TIMEOUT_MS = 2e4;
|
|
88256
|
-
async function send(method, route, body, signedIn,
|
|
88258
|
+
async function send(method, route, body, signedIn, ms, type) {
|
|
88257
88259
|
const headers = { accept: "application/json" };
|
|
88258
88260
|
if (signedIn) {
|
|
88259
88261
|
const token = await accessToken();
|
|
@@ -88269,7 +88271,7 @@ async function send(method, route, body, signedIn, ms2, type) {
|
|
|
88269
88271
|
method,
|
|
88270
88272
|
headers,
|
|
88271
88273
|
body: body === void 0 ? void 0 : raw ? body : JSON.stringify(body),
|
|
88272
|
-
signal: AbortSignal.timeout(
|
|
88274
|
+
signal: AbortSignal.timeout(ms)
|
|
88273
88275
|
});
|
|
88274
88276
|
return { ok: true, value: response };
|
|
88275
88277
|
} catch (e2) {
|
|
@@ -88808,239 +88810,6 @@ function nextDue(lastRun, cadence) {
|
|
|
88808
88810
|
return new Date(last2.getFullYear(), last2.getMonth(), last2.getDate() + c2.n, hour, minute, 0, 0);
|
|
88809
88811
|
}
|
|
88810
88812
|
|
|
88811
|
-
// ../cli/src/lib/yaml.ts
|
|
88812
|
-
function yamlScalar(s) {
|
|
88813
|
-
const text3 = String(s);
|
|
88814
|
-
if (text3 === "") return '""';
|
|
88815
|
-
if (/^[-?:,[\]{}#&*!|>'"%@`]/.test(text3) || /:\s/.test(text3) || /[\n"]/.test(text3) || /^\s|\s$/.test(text3)) {
|
|
88816
|
-
return JSON.stringify(text3);
|
|
88817
|
-
}
|
|
88818
|
-
return text3;
|
|
88819
|
-
}
|
|
88820
|
-
function unquote(v2) {
|
|
88821
|
-
const text3 = String(v2).trim();
|
|
88822
|
-
if (text3.startsWith('"') && text3.endsWith('"')) {
|
|
88823
|
-
try {
|
|
88824
|
-
return JSON.parse(text3);
|
|
88825
|
-
} catch {
|
|
88826
|
-
return text3.slice(1, -1);
|
|
88827
|
-
}
|
|
88828
|
-
}
|
|
88829
|
-
if (text3.startsWith("'") && text3.endsWith("'")) return text3.slice(1, -1);
|
|
88830
|
-
return text3;
|
|
88831
|
-
}
|
|
88832
|
-
|
|
88833
|
-
// ../cli/src/lib/question-block.ts
|
|
88834
|
-
var MODES = ["single", "multi"];
|
|
88835
|
-
var withoutTag = (text3) => text3.replace(/^\[user\]\s+/, "");
|
|
88836
|
-
function normalizeQuestion(raw) {
|
|
88837
|
-
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
88838
|
-
const source = raw;
|
|
88839
|
-
const text3 = withoutTag(String(source.question ?? source.text ?? ""));
|
|
88840
|
-
const extra = {
|
|
88841
|
-
...typeof source.agent === "string" && source.agent.trim() ? { agent: source.agent.trim() } : {},
|
|
88842
|
-
...source.skipped === true || source.skipped === "true" ? { skipped: true } : {}
|
|
88843
|
-
};
|
|
88844
|
-
const options = (Array.isArray(source.options) ? source.options : []).map((o2) => String(o2).trim()).filter(Boolean);
|
|
88845
|
-
if (options.length === 0) return { text: text3, ...extra };
|
|
88846
|
-
const mode = MODES.includes(String(source.mode)) ? String(source.mode) : "single";
|
|
88847
|
-
const recommend = (Array.isArray(source.recommend) ? source.recommend : []).map(Number).filter((n) => Number.isInteger(n) && n >= 1 && n <= options.length);
|
|
88848
|
-
return { text: text3, mode, options, recommend: mode === "single" ? recommend.slice(0, 1) : recommend, ...extra };
|
|
88849
|
-
}
|
|
88850
|
-
return { text: withoutTag(String(raw)) };
|
|
88851
|
-
}
|
|
88852
|
-
function parseQuestionsBlock(lines) {
|
|
88853
|
-
const out = [];
|
|
88854
|
-
for (let i = 0; i < lines.length; i++) {
|
|
88855
|
-
const m = lines[i].match(/^\s*-\s+([\s\S]*)$/);
|
|
88856
|
-
if (!m) continue;
|
|
88857
|
-
const head2 = m[1];
|
|
88858
|
-
const opened = head2.match(/^question:\s*(.*)$/);
|
|
88859
|
-
if (!opened) {
|
|
88860
|
-
out.push(normalizeQuestion(unquote(head2)));
|
|
88861
|
-
continue;
|
|
88862
|
-
}
|
|
88863
|
-
const q3 = {
|
|
88864
|
-
question: unquote(opened[1]),
|
|
88865
|
-
options: [],
|
|
88866
|
-
recommend: []
|
|
88867
|
-
};
|
|
88868
|
-
while (i + 1 < lines.length && !/^\s*-\s/.test(lines[i + 1])) {
|
|
88869
|
-
const field = lines[i + 1].match(/^\s*([A-Za-z_]+):\s*(.*)$/);
|
|
88870
|
-
i++;
|
|
88871
|
-
if (!field) continue;
|
|
88872
|
-
const [, key, val] = field;
|
|
88873
|
-
if (key === "options") {
|
|
88874
|
-
while (i + 1 < lines.length && /^\s*-\s+/.test(lines[i + 1])) {
|
|
88875
|
-
q3.options.push(unquote(lines[i + 1].replace(/^\s*-\s+/, "")));
|
|
88876
|
-
i++;
|
|
88877
|
-
}
|
|
88878
|
-
} else if (key === "recommend") {
|
|
88879
|
-
q3.recommend = val.replace(/^\[|\]$/g, "").split(",").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n));
|
|
88880
|
-
} else if (key === "mode") {
|
|
88881
|
-
q3.mode = unquote(val);
|
|
88882
|
-
} else if (key === "agent") {
|
|
88883
|
-
q3.agent = unquote(val);
|
|
88884
|
-
} else if (key === "skipped") {
|
|
88885
|
-
q3.skipped = unquote(val) === "true";
|
|
88886
|
-
}
|
|
88887
|
-
}
|
|
88888
|
-
out.push(normalizeQuestion(q3));
|
|
88889
|
-
}
|
|
88890
|
-
return out;
|
|
88891
|
-
}
|
|
88892
|
-
|
|
88893
|
-
// ../cli/src/lib/view/rules.ts
|
|
88894
|
-
var openOf = (questions) => questions.filter((q3) => !q3.skipped);
|
|
88895
|
-
|
|
88896
|
-
// ../cli/src/lib/frontmatter.ts
|
|
88897
|
-
function parseFrontmatter(text3) {
|
|
88898
|
-
const lines = text3.split("\n");
|
|
88899
|
-
if (lines[0].trim() !== "---") return { meta: null, body: text3 };
|
|
88900
|
-
let i = 1;
|
|
88901
|
-
const fm = [];
|
|
88902
|
-
while (i < lines.length && lines[i].trim() !== "---") {
|
|
88903
|
-
fm.push(lines[i]);
|
|
88904
|
-
i++;
|
|
88905
|
-
}
|
|
88906
|
-
if (i >= lines.length) return { meta: null, body: text3 };
|
|
88907
|
-
const meta = {};
|
|
88908
|
-
for (let j2 = 0; j2 < fm.length; j2++) {
|
|
88909
|
-
const m = fm[j2].match(/^([A-Za-z_]+):\s*(.*)$/);
|
|
88910
|
-
if (!m) continue;
|
|
88911
|
-
const key = m[1];
|
|
88912
|
-
const val = m[2];
|
|
88913
|
-
if (key === "questions") {
|
|
88914
|
-
if (val === "") {
|
|
88915
|
-
const block = [];
|
|
88916
|
-
while (j2 + 1 < fm.length && /^\s/.test(fm[j2 + 1]) && fm[j2 + 1].trim() !== "") {
|
|
88917
|
-
block.push(fm[j2 + 1]);
|
|
88918
|
-
j2++;
|
|
88919
|
-
}
|
|
88920
|
-
meta.questions = parseQuestionsBlock(block);
|
|
88921
|
-
} else {
|
|
88922
|
-
meta.questions = val.trim() === "[]" ? [] : [normalizeQuestion(unquote(val))];
|
|
88923
|
-
}
|
|
88924
|
-
continue;
|
|
88925
|
-
}
|
|
88926
|
-
if (val === "") {
|
|
88927
|
-
const items = [];
|
|
88928
|
-
while (j2 + 1 < fm.length && /^\s*-\s+/.test(fm[j2 + 1])) {
|
|
88929
|
-
items.push(unquote(fm[j2 + 1].replace(/^\s*-\s+/, "")));
|
|
88930
|
-
j2++;
|
|
88931
|
-
}
|
|
88932
|
-
meta[key] = items;
|
|
88933
|
-
} else if (val.startsWith("[")) {
|
|
88934
|
-
const inner = val.slice(1, val.lastIndexOf("]"));
|
|
88935
|
-
meta[key] = inner.split(",").map((s) => s.trim()).filter(Boolean).map(unquote);
|
|
88936
|
-
} else {
|
|
88937
|
-
meta[key] = unquote(val);
|
|
88938
|
-
}
|
|
88939
|
-
}
|
|
88940
|
-
for (const k of ["blocked_by", "related"]) {
|
|
88941
|
-
const value = meta[k];
|
|
88942
|
-
if (Array.isArray(value)) {
|
|
88943
|
-
meta[k] = value.map((x2) => Number(String(x2).replace(/^#/, ""))).filter((n) => Number.isInteger(n));
|
|
88944
|
-
} else {
|
|
88945
|
-
meta[k] = [];
|
|
88946
|
-
}
|
|
88947
|
-
}
|
|
88948
|
-
if (!Array.isArray(meta.questions)) {
|
|
88949
|
-
meta.questions = meta.questions ? [normalizeQuestion(meta.questions)] : [];
|
|
88950
|
-
}
|
|
88951
|
-
meta.priority = typeof meta.priority === "string" ? meta.priority.trim() : "";
|
|
88952
|
-
if (!Array.isArray(meta.modules)) meta.modules = [];
|
|
88953
|
-
delete meta.channels;
|
|
88954
|
-
delete meta.decided;
|
|
88955
|
-
delete meta.verify;
|
|
88956
|
-
delete meta.release;
|
|
88957
|
-
delete meta.schedule;
|
|
88958
|
-
delete meta.roi;
|
|
88959
|
-
meta.workflow = typeof meta.workflow === "string" && meta.workflow.trim() ? meta.workflow.trim() : "";
|
|
88960
|
-
meta.triage = typeof meta.triage === "string" ? meta.triage.trim() : "";
|
|
88961
|
-
meta.source = (Array.isArray(meta.source) ? meta.source : typeof meta.source === "string" ? [meta.source] : []).map((ref) => String(ref).trim()).filter(Boolean);
|
|
88962
|
-
delete meta.phases;
|
|
88963
|
-
if (Array.isArray(meta.previews)) meta.previews = meta.previews.map((name) => String(name).trim()).filter(Boolean);
|
|
88964
|
-
else delete meta.previews;
|
|
88965
|
-
meta.stages = /^\d+$/.test(String(meta.stages ?? "").trim()) ? Number(meta.stages) : 0;
|
|
88966
|
-
meta.phase = /^\d+$/.test(String(meta.phase ?? "").trim()) ? Number(meta.phase) : 0;
|
|
88967
|
-
meta.preview_approved = meta.preview_approved === "true";
|
|
88968
|
-
meta.archived = typeof meta.archived === "string" && meta.archived.trim() ? meta.archived.trim() : "";
|
|
88969
|
-
meta.rejected = meta.rejected === "true";
|
|
88970
|
-
meta.rejected_reason = typeof meta.rejected_reason === "string" ? meta.rejected_reason : "";
|
|
88971
|
-
meta.rejected_at = typeof meta.rejected_at === "string" ? meta.rejected_at.trim() : "";
|
|
88972
|
-
meta.rejected_by = meta.rejected_by === "user" || meta.rejected_by === "agent" ? meta.rejected_by : "";
|
|
88973
|
-
return { meta, body: lines.slice(i + 1).join("\n") };
|
|
88974
|
-
}
|
|
88975
|
-
|
|
88976
|
-
// ../cli/src/lib/spec-agent-names.ts
|
|
88977
|
-
var LEGACY_SPEC_AGENT_NAMES = {
|
|
88978
|
-
"recommend-tech-stack": "tech-stack-advisor",
|
|
88979
|
-
"technology-selection": "tech-stack-advisor",
|
|
88980
|
-
"ui-design": "ui-designer",
|
|
88981
|
-
// Renamed in #945 and folded into the editor in #1057; its asset memory stays in
|
|
88982
|
-
// `memory/agents/video-assets/`.
|
|
88983
|
-
"video-assets": "hyperframes-editor",
|
|
88984
|
-
// Renamed in #1502: it reads chats, and writes memory as a result.
|
|
88985
|
-
"memory-reviewer": "chat-reviewer",
|
|
88986
|
-
// Folded into `copywriting` in #1582.
|
|
88987
|
-
"user-docs": "copywriting"
|
|
88988
|
-
};
|
|
88989
|
-
var canonicalSpecAgent = (name) => {
|
|
88990
|
-
const asked = name.trim();
|
|
88991
|
-
return LEGACY_SPEC_AGENT_NAMES[asked] ?? asked;
|
|
88992
|
-
};
|
|
88993
|
-
|
|
88994
|
-
// ../cli/src/lib/slug.ts
|
|
88995
|
-
function slugify(s) {
|
|
88996
|
-
const out = String(s).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60).replace(/-+$/g, "");
|
|
88997
|
-
return out || "task";
|
|
88998
|
-
}
|
|
88999
|
-
|
|
89000
|
-
// ../cli/src/lib/memory.ts
|
|
89001
|
-
var PLANNER_MEMORY_FILES = ["decisions.md", "rejected.md", "redesign.md"];
|
|
89002
|
-
var STARTERS = {
|
|
89003
|
-
"readme.md": `# Shipped
|
|
89004
|
-
|
|
89005
|
-
User-facing work that has shipped, one line each \u2014 a link to the published doc that
|
|
89006
|
-
covers it, or a plain-words note.
|
|
89007
|
-
|
|
89008
|
-
_(nothing recorded yet \u2014 the first finished task fills it in.)_
|
|
89009
|
-
`,
|
|
89010
|
-
"decisions.md": `# Decisions
|
|
89011
|
-
|
|
89012
|
-
Settled answers to cards' open questions, grouped by topic. Keep only **user-facing**
|
|
89013
|
-
calls that guide future planning \u2014 what a user can see, do, or would care about.
|
|
89014
|
-
Internal detail stays on the card.
|
|
89015
|
-
`,
|
|
89016
|
-
"redesign.md": `# Redesign
|
|
89017
|
-
|
|
89018
|
-
Design mistakes to avoid when writing a card, grouped by topic. One entry each: the
|
|
89019
|
-
mistake, then the design we actually want. Read before writing or reviewing a card.
|
|
89020
|
-
`,
|
|
89021
|
-
"rejected.md": `# Rejected
|
|
89022
|
-
|
|
89023
|
-
Ideas we turned down, grouped by topic. One line each: the idea, and why we said no. Read
|
|
89024
|
-
before proposing so you don't re-suggest them.
|
|
89025
|
-
`,
|
|
89026
|
-
// Only a header: `describe-project` writes the body, and runs while there is none (#1268).
|
|
89027
|
-
"project.md": `# Project
|
|
89028
|
-
|
|
89029
|
-
What the project is today, from its users' side. Rewritten whole by \`akb describe-project\`;
|
|
89030
|
-
edits here do not last.
|
|
89031
|
-
`
|
|
89032
|
-
};
|
|
89033
|
-
var RESERVED_MODULE_NAMES = PLANNER_MEMORY_FILES.map((name) => name.replace(/\.md$/, ""));
|
|
89034
|
-
var PRODUCT_STARTER = STARTERS["project.md"].replaceAll("Project", "Product").replaceAll("project", "product");
|
|
89035
|
-
var SEEDED_GOAL_PARAGRAPHS = new Set(
|
|
89036
|
-
[
|
|
89037
|
-
"# Goal",
|
|
89038
|
-
"Where this is headed, in the user's own words: the long-term goal, the horizon it aims at, and the roadmap of what comes next, roughly in order. Not this week's work \u2014 that's the cards on the board. The user owns this file; the agent seeds it but does not invent the goal.",
|
|
89039
|
-
"The direction, in the user's own words \u2014 where this is headed. One short statement. The user owns this file; the agent seeds it but does not invent the goal.",
|
|
89040
|
-
"_(not filled in yet \u2014 the user writes this.)_"
|
|
89041
|
-
].map((p2) => p2.replace(/\s+/g, " "))
|
|
89042
|
-
);
|
|
89043
|
-
|
|
89044
88813
|
// ../cli/src/lib/agent/due.ts
|
|
89045
88814
|
var AUTO_GAP = "6h";
|
|
89046
88815
|
var DAY = 864e5;
|
|
@@ -89065,22 +88834,32 @@ function scheduleDue(ask, now = Date.now()) {
|
|
|
89065
88834
|
}
|
|
89066
88835
|
const newest2 = ask.attempts.reduce((a3, r2) => a3 && a3.startedAt >= r2.startedAt ? a3 : r2, null);
|
|
89067
88836
|
const retrying = isAuto(ask.cadence) && newest2?.status === "error";
|
|
89068
|
-
const wait3 = next.getTime() > now ? retrying ? "retrying" : "tooSoon" : !ask.newWork() ? "nothingNew" :
|
|
88837
|
+
const wait3 = next.getTime() > now ? retrying ? "retrying" : "tooSoon" : !ask.newWork() ? "nothingNew" : null;
|
|
89069
88838
|
const reason = !wait3 || wait3 === "tooSoon" ? void 0 : wait3 === "nothingNew" ? ask.reads : wait3;
|
|
89070
88839
|
return { next, wait: wait3, ...reason ? { reason } : {} };
|
|
89071
88840
|
}
|
|
89072
88841
|
|
|
89073
88842
|
// src/agents.ts
|
|
89074
|
-
|
|
89075
|
-
|
|
88843
|
+
function nextHour(now = Date.now()) {
|
|
88844
|
+
const at2 = new Date(now);
|
|
88845
|
+
at2.setMinutes(60, 0, 0);
|
|
88846
|
+
return at2.getTime();
|
|
88847
|
+
}
|
|
88848
|
+
function hourOf(at2) {
|
|
88849
|
+
const hour = new Date(at2 ?? NaN);
|
|
88850
|
+
if (Number.isNaN(hour.getTime())) return 0;
|
|
88851
|
+
hour.setMinutes(hour.getMinutes() + 30, 0, 0);
|
|
88852
|
+
hour.setMinutes(0, 0, 0);
|
|
88853
|
+
return hour.getTime();
|
|
88854
|
+
}
|
|
89076
88855
|
function agentDue(agent, now = Date.now()) {
|
|
89077
88856
|
if (agent.attempts.some((a3) => a3.status === "running")) return false;
|
|
89078
88857
|
const due = scheduleDue({
|
|
89079
88858
|
cadence: agent.cadence,
|
|
89080
88859
|
fallback: agent.fallback,
|
|
89081
88860
|
reads: agent.reads,
|
|
89082
|
-
from: Math.max(
|
|
89083
|
-
attempts: agent.attempts.map((a3) => ({ startedAt:
|
|
88861
|
+
from: Math.max(hourOf(agent.lastSuccess), hourOf(agent.since)),
|
|
88862
|
+
attempts: agent.attempts.map((a3) => ({ startedAt: hourOf(a3.startedAt), status: a3.status })),
|
|
89084
88863
|
newWork: () => agent.newWork
|
|
89085
88864
|
}, now);
|
|
89086
88865
|
return !due.wait;
|
|
@@ -89137,7 +88916,7 @@ exec ${line} "$@"
|
|
|
89137
88916
|
}
|
|
89138
88917
|
function akbEnv(akb, board, task, line) {
|
|
89139
88918
|
const env2 = {};
|
|
89140
|
-
const dropped = ["AI4KANBAN_BOARD", "AI4KANBAN_TASK", LANGUAGE_LINE_ENV];
|
|
88919
|
+
const dropped = ["AI4KANBAN_BOARD", "AI4KANBAN_TASK", LANGUAGE_LINE_ENV, SCHEDULED_AGENTS_ENV];
|
|
89141
88920
|
for (const [k, v2] of Object.entries(process.env)) if (!k.startsWith("KANBAN_") && !dropped.includes(k)) env2[k] = v2;
|
|
89142
88921
|
const key = Object.keys(env2).find((k) => k.toUpperCase() === "PATH") ?? "PATH";
|
|
89143
88922
|
env2[key] = [shimDir(akb), env2[key]].filter(Boolean).join(path14.delimiter);
|
|
@@ -89158,7 +88937,7 @@ function runAkb(akb, args, opts) {
|
|
|
89158
88937
|
};
|
|
89159
88938
|
let child;
|
|
89160
88939
|
try {
|
|
89161
|
-
child = spawn3(akb.command, [...akb.args, ...args], { cwd: opts.cwd, env: akbEnv(akb, opts.board, opts.task, opts.line), stdio: ["ignore", "pipe", "pipe"] });
|
|
88940
|
+
child = spawn3(akb.command, [...akb.args, ...args], { cwd: opts.cwd, env: { ...akbEnv(akb, opts.board, opts.task, opts.line), ...opts.env }, stdio: ["ignore", "pipe", "pipe"] });
|
|
89162
88941
|
} catch (e2) {
|
|
89163
88942
|
return resolve2({ code: null, out: "", last: e2 instanceof Error ? e2.message : String(e2) });
|
|
89164
88943
|
}
|
|
@@ -89783,10 +89562,11 @@ function numberOfCard(path34) {
|
|
|
89783
89562
|
var cardSlug = (task) => task.toLowerCase().replace(/_/g, "-");
|
|
89784
89563
|
var assetsFile = (task) => `assets/${task}.json`;
|
|
89785
89564
|
var workflowFolder = (id) => id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
89565
|
+
var OWN_FOLDER = /^wf-(?!builtin-)[a-z0-9-]+$/;
|
|
89786
89566
|
var workflowName = (id) => id.startsWith("wf_builtin_") ? id.slice("wf_builtin_".length).replace(/_/g, "-") : workflowFolder(id);
|
|
89787
89567
|
var BUILDER = "wf_builtin_workflow_builder";
|
|
89788
89568
|
var draftFolder = (task) => cardSlug(task);
|
|
89789
|
-
var
|
|
89569
|
+
var unquote = (value) => value.trim().replace(/^(["'])(.*)\1$/, "$2");
|
|
89790
89570
|
function cardFront(body) {
|
|
89791
89571
|
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(body);
|
|
89792
89572
|
if (!match) return {};
|
|
@@ -89795,13 +89575,13 @@ function cardFront(body) {
|
|
|
89795
89575
|
const field = /^(title|status|phase|stages|previews):\s*(.*)$/.exec(line);
|
|
89796
89576
|
if (!field) continue;
|
|
89797
89577
|
const [, key, value = ""] = field;
|
|
89798
|
-
if (key === "title" && value.trim()) out.title =
|
|
89799
|
-
else if (key === "status" && value.trim()) out.status =
|
|
89578
|
+
if (key === "title" && value.trim()) out.title = unquote(value);
|
|
89579
|
+
else if (key === "status" && value.trim()) out.status = unquote(value);
|
|
89800
89580
|
else if (key === "phase" && Number.isInteger(Number(value)) && value.trim()) out.phase = Number(value);
|
|
89801
89581
|
else if (key === "stages" && Number.isInteger(Number(value)) && value.trim()) out.stages = Number(value);
|
|
89802
89582
|
else if (key === "previews") {
|
|
89803
89583
|
const flow = /^\[(.*)\]\s*$/.exec(value.trim());
|
|
89804
|
-
if (flow) out.previews = flow[1].split(",").map(
|
|
89584
|
+
if (flow) out.previews = flow[1].split(",").map(unquote).filter(Boolean);
|
|
89805
89585
|
}
|
|
89806
89586
|
}
|
|
89807
89587
|
return out;
|
|
@@ -90026,6 +89806,28 @@ function diff3Merge(a3, o2, b2, options) {
|
|
|
90026
89806
|
return results;
|
|
90027
89807
|
}
|
|
90028
89808
|
|
|
89809
|
+
// ../cli/src/lib/yaml.ts
|
|
89810
|
+
function yamlScalar(s) {
|
|
89811
|
+
const text3 = String(s);
|
|
89812
|
+
if (text3 === "") return '""';
|
|
89813
|
+
if (/^[-?:,[\]{}#&*!|>'"%@`]/.test(text3) || /:\s/.test(text3) || /[\n"]/.test(text3) || /^\s|\s$/.test(text3)) {
|
|
89814
|
+
return JSON.stringify(text3);
|
|
89815
|
+
}
|
|
89816
|
+
return text3;
|
|
89817
|
+
}
|
|
89818
|
+
function unquote2(v2) {
|
|
89819
|
+
const text3 = String(v2).trim();
|
|
89820
|
+
if (text3.startsWith('"') && text3.endsWith('"')) {
|
|
89821
|
+
try {
|
|
89822
|
+
return JSON.parse(text3);
|
|
89823
|
+
} catch {
|
|
89824
|
+
return text3.slice(1, -1);
|
|
89825
|
+
}
|
|
89826
|
+
}
|
|
89827
|
+
if (text3.startsWith("'") && text3.endsWith("'")) return text3.slice(1, -1);
|
|
89828
|
+
return text3;
|
|
89829
|
+
}
|
|
89830
|
+
|
|
90029
89831
|
// ../cloud/src/triage-files.ts
|
|
90030
89832
|
var ITEM = /^triage\/(?:(dismissed|archived)\/)?([^/]+)\.md$/;
|
|
90031
89833
|
function itemAt(path34) {
|
|
@@ -90615,8 +90417,8 @@ function readMap(lines, start, indent) {
|
|
|
90615
90417
|
}
|
|
90616
90418
|
function readScalar(value) {
|
|
90617
90419
|
const flow = value.match(/^\[(.*)\]$/);
|
|
90618
|
-
if (!flow) return
|
|
90619
|
-
return flow[1].split(",").map((item) =>
|
|
90420
|
+
if (!flow) return unquote2(value);
|
|
90421
|
+
return flow[1].split(",").map((item) => unquote2(item.trim())).filter(Boolean);
|
|
90620
90422
|
}
|
|
90621
90423
|
function readBlock(lines, start, parentIndent) {
|
|
90622
90424
|
if (start >= lines.length || lines[start].indent <= parentIndent) return ["", start];
|
|
@@ -90645,7 +90447,7 @@ function readList2(lines, start, indent) {
|
|
|
90645
90447
|
}
|
|
90646
90448
|
const item = {};
|
|
90647
90449
|
const inline = stripComment(match[2].trim());
|
|
90648
|
-
if (inline) item[match[1].trim()] =
|
|
90450
|
+
if (inline) item[match[1].trim()] = unquote2(inline);
|
|
90649
90451
|
else {
|
|
90650
90452
|
const [value, next2] = readBlock(lines, i, keyIndent);
|
|
90651
90453
|
item[match[1].trim()] = value;
|
|
@@ -91045,7 +90847,6 @@ async function pullWorkflow(ws, record, base) {
|
|
|
91045
90847
|
record.agents = {};
|
|
91046
90848
|
return { ok: true, value: void 0 };
|
|
91047
90849
|
}
|
|
91048
|
-
var OWN_FOLDER = /^wf-(?!builtin-)[a-z0-9-]+$/;
|
|
91049
90850
|
var agentsRecord = (ws) => path23.join(ws.board, ".sync", "agents.json");
|
|
91050
90851
|
function readPlaced(ws) {
|
|
91051
90852
|
try {
|
|
@@ -91501,7 +91302,7 @@ function keptFolders() {
|
|
|
91501
91302
|
}
|
|
91502
91303
|
return [.../* @__PURE__ */ new Set([...allowedProjects(), ...cached2])].flatMap((dir) => [keptBoard(dir)].filter((ws) => !!ws));
|
|
91503
91304
|
}
|
|
91504
|
-
function watchBoards(machineId2,
|
|
91305
|
+
function watchBoards(machineId2, ms, lookMs = LOOK_MS, pullMs = PULL_MS) {
|
|
91505
91306
|
const watched = /* @__PURE__ */ new Map();
|
|
91506
91307
|
const due = /* @__PURE__ */ new Map();
|
|
91507
91308
|
const afterJob = /* @__PURE__ */ new Set();
|
|
@@ -91525,7 +91326,7 @@ function watchBoards(machineId2, ms2, lookMs = LOOK_MS, pullMs = PULL_MS) {
|
|
|
91525
91326
|
const held4 = watched.get(ws.cwd);
|
|
91526
91327
|
if (closed || !p2 || !isBoardPath(p2) || !held4) return;
|
|
91527
91328
|
clearTimeout(held4.timer);
|
|
91528
|
-
held4.timer = setTimeout(() => void send3(ws),
|
|
91329
|
+
held4.timer = setTimeout(() => void send3(ws), ms);
|
|
91529
91330
|
});
|
|
91530
91331
|
} catch {
|
|
91531
91332
|
return false;
|
|
@@ -91658,6 +91459,149 @@ async function answerHint(machineId2, hint2) {
|
|
|
91658
91459
|
import fs25 from "node:fs";
|
|
91659
91460
|
import path28 from "node:path";
|
|
91660
91461
|
|
|
91462
|
+
// ../cli/src/lib/question-block.ts
|
|
91463
|
+
var MODES = ["single", "multi"];
|
|
91464
|
+
var withoutTag = (text3) => text3.replace(/^\[user\]\s+/, "");
|
|
91465
|
+
function normalizeQuestion(raw) {
|
|
91466
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
91467
|
+
const source = raw;
|
|
91468
|
+
const text3 = withoutTag(String(source.question ?? source.text ?? ""));
|
|
91469
|
+
const extra = {
|
|
91470
|
+
...typeof source.agent === "string" && source.agent.trim() ? { agent: source.agent.trim() } : {},
|
|
91471
|
+
...source.skipped === true || source.skipped === "true" ? { skipped: true } : {}
|
|
91472
|
+
};
|
|
91473
|
+
const options = (Array.isArray(source.options) ? source.options : []).map((o2) => String(o2).trim()).filter(Boolean);
|
|
91474
|
+
if (options.length === 0) return { text: text3, ...extra };
|
|
91475
|
+
const mode = MODES.includes(String(source.mode)) ? String(source.mode) : "single";
|
|
91476
|
+
const recommend = (Array.isArray(source.recommend) ? source.recommend : []).map(Number).filter((n) => Number.isInteger(n) && n >= 1 && n <= options.length);
|
|
91477
|
+
return { text: text3, mode, options, recommend: mode === "single" ? recommend.slice(0, 1) : recommend, ...extra };
|
|
91478
|
+
}
|
|
91479
|
+
return { text: withoutTag(String(raw)) };
|
|
91480
|
+
}
|
|
91481
|
+
function parseQuestionsBlock(lines) {
|
|
91482
|
+
const out = [];
|
|
91483
|
+
for (let i = 0; i < lines.length; i++) {
|
|
91484
|
+
const m = lines[i].match(/^\s*-\s+([\s\S]*)$/);
|
|
91485
|
+
if (!m) continue;
|
|
91486
|
+
const head2 = m[1];
|
|
91487
|
+
const opened = head2.match(/^question:\s*(.*)$/);
|
|
91488
|
+
if (!opened) {
|
|
91489
|
+
out.push(normalizeQuestion(unquote2(head2)));
|
|
91490
|
+
continue;
|
|
91491
|
+
}
|
|
91492
|
+
const q3 = {
|
|
91493
|
+
question: unquote2(opened[1]),
|
|
91494
|
+
options: [],
|
|
91495
|
+
recommend: []
|
|
91496
|
+
};
|
|
91497
|
+
while (i + 1 < lines.length && !/^\s*-\s/.test(lines[i + 1])) {
|
|
91498
|
+
const field = lines[i + 1].match(/^\s*([A-Za-z_]+):\s*(.*)$/);
|
|
91499
|
+
i++;
|
|
91500
|
+
if (!field) continue;
|
|
91501
|
+
const [, key, val] = field;
|
|
91502
|
+
if (key === "options") {
|
|
91503
|
+
while (i + 1 < lines.length && /^\s*-\s+/.test(lines[i + 1])) {
|
|
91504
|
+
q3.options.push(unquote2(lines[i + 1].replace(/^\s*-\s+/, "")));
|
|
91505
|
+
i++;
|
|
91506
|
+
}
|
|
91507
|
+
} else if (key === "recommend") {
|
|
91508
|
+
q3.recommend = val.replace(/^\[|\]$/g, "").split(",").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n));
|
|
91509
|
+
} else if (key === "mode") {
|
|
91510
|
+
q3.mode = unquote2(val);
|
|
91511
|
+
} else if (key === "agent") {
|
|
91512
|
+
q3.agent = unquote2(val);
|
|
91513
|
+
} else if (key === "skipped") {
|
|
91514
|
+
q3.skipped = unquote2(val) === "true";
|
|
91515
|
+
}
|
|
91516
|
+
}
|
|
91517
|
+
out.push(normalizeQuestion(q3));
|
|
91518
|
+
}
|
|
91519
|
+
return out;
|
|
91520
|
+
}
|
|
91521
|
+
|
|
91522
|
+
// ../cli/src/lib/view/rules.ts
|
|
91523
|
+
var openOf = (questions) => questions.filter((q3) => !q3.skipped);
|
|
91524
|
+
|
|
91525
|
+
// ../cli/src/lib/frontmatter.ts
|
|
91526
|
+
function parseFrontmatter(text3) {
|
|
91527
|
+
const lines = text3.split("\n");
|
|
91528
|
+
if (lines[0].trim() !== "---") return { meta: null, body: text3 };
|
|
91529
|
+
let i = 1;
|
|
91530
|
+
const fm = [];
|
|
91531
|
+
while (i < lines.length && lines[i].trim() !== "---") {
|
|
91532
|
+
fm.push(lines[i]);
|
|
91533
|
+
i++;
|
|
91534
|
+
}
|
|
91535
|
+
if (i >= lines.length) return { meta: null, body: text3 };
|
|
91536
|
+
const meta = {};
|
|
91537
|
+
for (let j2 = 0; j2 < fm.length; j2++) {
|
|
91538
|
+
const m = fm[j2].match(/^([A-Za-z_]+):\s*(.*)$/);
|
|
91539
|
+
if (!m) continue;
|
|
91540
|
+
const key = m[1];
|
|
91541
|
+
const val = m[2];
|
|
91542
|
+
if (key === "questions") {
|
|
91543
|
+
if (val === "") {
|
|
91544
|
+
const block = [];
|
|
91545
|
+
while (j2 + 1 < fm.length && /^\s/.test(fm[j2 + 1]) && fm[j2 + 1].trim() !== "") {
|
|
91546
|
+
block.push(fm[j2 + 1]);
|
|
91547
|
+
j2++;
|
|
91548
|
+
}
|
|
91549
|
+
meta.questions = parseQuestionsBlock(block);
|
|
91550
|
+
} else {
|
|
91551
|
+
meta.questions = val.trim() === "[]" ? [] : [normalizeQuestion(unquote2(val))];
|
|
91552
|
+
}
|
|
91553
|
+
continue;
|
|
91554
|
+
}
|
|
91555
|
+
if (val === "") {
|
|
91556
|
+
const items = [];
|
|
91557
|
+
while (j2 + 1 < fm.length && /^\s*-\s+/.test(fm[j2 + 1])) {
|
|
91558
|
+
items.push(unquote2(fm[j2 + 1].replace(/^\s*-\s+/, "")));
|
|
91559
|
+
j2++;
|
|
91560
|
+
}
|
|
91561
|
+
meta[key] = items;
|
|
91562
|
+
} else if (val.startsWith("[")) {
|
|
91563
|
+
const inner = val.slice(1, val.lastIndexOf("]"));
|
|
91564
|
+
meta[key] = inner.split(",").map((s) => s.trim()).filter(Boolean).map(unquote2);
|
|
91565
|
+
} else {
|
|
91566
|
+
meta[key] = unquote2(val);
|
|
91567
|
+
}
|
|
91568
|
+
}
|
|
91569
|
+
for (const k of ["blocked_by", "related"]) {
|
|
91570
|
+
const value = meta[k];
|
|
91571
|
+
if (Array.isArray(value)) {
|
|
91572
|
+
meta[k] = value.map((x2) => Number(String(x2).replace(/^#/, ""))).filter((n) => Number.isInteger(n));
|
|
91573
|
+
} else {
|
|
91574
|
+
meta[k] = [];
|
|
91575
|
+
}
|
|
91576
|
+
}
|
|
91577
|
+
if (!Array.isArray(meta.questions)) {
|
|
91578
|
+
meta.questions = meta.questions ? [normalizeQuestion(meta.questions)] : [];
|
|
91579
|
+
}
|
|
91580
|
+
meta.priority = typeof meta.priority === "string" ? meta.priority.trim() : "";
|
|
91581
|
+
if (!Array.isArray(meta.modules)) meta.modules = [];
|
|
91582
|
+
delete meta.channels;
|
|
91583
|
+
delete meta.decided;
|
|
91584
|
+
delete meta.verify;
|
|
91585
|
+
delete meta.release;
|
|
91586
|
+
delete meta.schedule;
|
|
91587
|
+
delete meta.roi;
|
|
91588
|
+
meta.workflow = typeof meta.workflow === "string" && meta.workflow.trim() ? meta.workflow.trim() : "";
|
|
91589
|
+
meta.triage = typeof meta.triage === "string" ? meta.triage.trim() : "";
|
|
91590
|
+
meta.source = (Array.isArray(meta.source) ? meta.source : typeof meta.source === "string" ? [meta.source] : []).map((ref) => String(ref).trim()).filter(Boolean);
|
|
91591
|
+
delete meta.phases;
|
|
91592
|
+
if (Array.isArray(meta.previews)) meta.previews = meta.previews.map((name) => String(name).trim()).filter(Boolean);
|
|
91593
|
+
else delete meta.previews;
|
|
91594
|
+
meta.stages = /^\d+$/.test(String(meta.stages ?? "").trim()) ? Number(meta.stages) : 0;
|
|
91595
|
+
meta.phase = /^\d+$/.test(String(meta.phase ?? "").trim()) ? Number(meta.phase) : 0;
|
|
91596
|
+
meta.preview_approved = meta.preview_approved === "true";
|
|
91597
|
+
meta.archived = typeof meta.archived === "string" && meta.archived.trim() ? meta.archived.trim() : "";
|
|
91598
|
+
meta.rejected = meta.rejected === "true";
|
|
91599
|
+
meta.rejected_reason = typeof meta.rejected_reason === "string" ? meta.rejected_reason : "";
|
|
91600
|
+
meta.rejected_at = typeof meta.rejected_at === "string" ? meta.rejected_at.trim() : "";
|
|
91601
|
+
meta.rejected_by = meta.rejected_by === "user" || meta.rejected_by === "agent" ? meta.rejected_by : "";
|
|
91602
|
+
return { meta, body: lines.slice(i + 1).join("\n") };
|
|
91603
|
+
}
|
|
91604
|
+
|
|
91661
91605
|
// src/triage.ts
|
|
91662
91606
|
import fs23 from "node:fs";
|
|
91663
91607
|
import path26 from "node:path";
|
|
@@ -91667,9 +91611,15 @@ import { createHash } from "node:crypto";
|
|
|
91667
91611
|
var DERIVED = "derived-";
|
|
91668
91612
|
var derivedSourceId = (seed) => `${DERIVED}${createHash("sha256").update(seed).digest("hex").slice(0, 16)}`;
|
|
91669
91613
|
|
|
91614
|
+
// ../cli/src/lib/slug.ts
|
|
91615
|
+
function slugify(s) {
|
|
91616
|
+
const out = String(s).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60).replace(/-+$/g, "");
|
|
91617
|
+
return out || "task";
|
|
91618
|
+
}
|
|
91619
|
+
|
|
91670
91620
|
// src/triage.ts
|
|
91671
91621
|
var triageDir = (board) => path26.join(board, "triage");
|
|
91672
|
-
var rejectedDir = (board) => path26.join(board, ".archive",
|
|
91622
|
+
var rejectedDir = (board) => path26.join(board, ".archive", REJECTIONS_TO_REVIEW);
|
|
91673
91623
|
var SCRATCH = ["dismissed", "archived"];
|
|
91674
91624
|
var stamp = (at2) => formatStamp(at2 ? new Date(at2) : /* @__PURE__ */ new Date());
|
|
91675
91625
|
function slugOf(title) {
|
|
@@ -91738,6 +91688,24 @@ function clearLaid(board) {
|
|
|
91738
91688
|
import fs24 from "node:fs";
|
|
91739
91689
|
import path27 from "node:path";
|
|
91740
91690
|
|
|
91691
|
+
// ../cli/src/lib/spec-agent-names.ts
|
|
91692
|
+
var LEGACY_SPEC_AGENT_NAMES = {
|
|
91693
|
+
"recommend-tech-stack": "tech-stack-advisor",
|
|
91694
|
+
"technology-selection": "tech-stack-advisor",
|
|
91695
|
+
"ui-design": "ui-designer",
|
|
91696
|
+
// Renamed in #945 and folded into the editor in #1057; its asset memory stays in
|
|
91697
|
+
// `memory/agents/video-assets/`.
|
|
91698
|
+
"video-assets": "hyperframes-editor",
|
|
91699
|
+
// Renamed in #1502: it reads chats, and writes memory as a result.
|
|
91700
|
+
"memory-reviewer": "chat-reviewer",
|
|
91701
|
+
// Folded into `copywriting` in #1582.
|
|
91702
|
+
"user-docs": "copywriting"
|
|
91703
|
+
};
|
|
91704
|
+
var canonicalSpecAgent = (name) => {
|
|
91705
|
+
const asked = name.trim();
|
|
91706
|
+
return LEGACY_SPEC_AGENT_NAMES[asked] ?? asked;
|
|
91707
|
+
};
|
|
91708
|
+
|
|
91741
91709
|
// ../cli/src/lib/agent/workflow-def.ts
|
|
91742
91710
|
var WORKFLOW_ID = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
91743
91711
|
var OLD_KEYS = ["stages", "delivers", "helpers", "every"];
|
|
@@ -92002,9 +91970,9 @@ function mcpArgs(runtime, servers, file2) {
|
|
|
92002
91970
|
]).join(" ");
|
|
92003
91971
|
}
|
|
92004
91972
|
var MCP_KEY = "mcpConfig";
|
|
92005
|
-
var wait = (
|
|
92006
|
-
async function stopRuns(akb, ws, id, since,
|
|
92007
|
-
const until = Date.now() +
|
|
91973
|
+
var wait = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
91974
|
+
async function stopRuns(akb, ws, id, since, ms) {
|
|
91975
|
+
const until = Date.now() + ms;
|
|
92008
91976
|
const call = (args) => runAkb(akb, [...args, "--board", ws.board], { cwd: ws.cwd, board: ws.board });
|
|
92009
91977
|
while (Date.now() < until) {
|
|
92010
91978
|
const runs = answerOf2(await call(["run", "list", "--card", String(id), "--all", "--json"]))?.runs;
|
|
@@ -92016,8 +91984,8 @@ async function stopRuns(akb, ws, id, since, ms2) {
|
|
|
92016
91984
|
}
|
|
92017
91985
|
var working = /* @__PURE__ */ new Map();
|
|
92018
91986
|
var workKey = (ws, id) => `${ws.board}#${id}`;
|
|
92019
|
-
async function stopLeftBehind(akb, ws, id,
|
|
92020
|
-
if (!working.has(workKey(ws, id))) await stopRuns(akb, ws, id, 0,
|
|
91987
|
+
async function stopLeftBehind(akb, ws, id, ms) {
|
|
91988
|
+
if (!working.has(workKey(ws, id))) await stopRuns(akb, ws, id, 0, ms);
|
|
92021
91989
|
}
|
|
92022
91990
|
function deliveryEnding(ws, id) {
|
|
92023
91991
|
if (!id) return null;
|
|
@@ -92094,11 +92062,11 @@ function logLines(show, event2) {
|
|
|
92094
92062
|
};
|
|
92095
92063
|
}
|
|
92096
92064
|
function boardAkb(job, ws, deps, io, task) {
|
|
92097
|
-
return async (args, show = false) => {
|
|
92065
|
+
return async (args, show = false, env2) => {
|
|
92098
92066
|
const at2 = args.includes("--") ? args.indexOf("--") : args.length;
|
|
92099
92067
|
const full = [...args.slice(0, at2), "--board", ws.board, ...args.slice(at2)];
|
|
92100
92068
|
const log = show ? logLines(io.show, io.event) : void 0;
|
|
92101
|
-
const ran = await runAkb(deps.akb, full, { cwd: ws.cwd, board: ws.board, task, line: job.languageLine ?? "", show: log?.push, track: io.track });
|
|
92069
|
+
const ran = await runAkb(deps.akb, full, { cwd: ws.cwd, board: ws.board, task, line: job.languageLine ?? "", env: env2, show: log?.push, track: io.track });
|
|
92102
92070
|
log?.end();
|
|
92103
92071
|
return ran;
|
|
92104
92072
|
};
|
|
@@ -92179,7 +92147,7 @@ async function reviewRejections(job, ws, deps, io) {
|
|
|
92179
92147
|
const akb = boardAkb(job, ws, deps, io);
|
|
92180
92148
|
return withBoard(ws, async (push2) => {
|
|
92181
92149
|
const laid = layOut(ws.board, read.value);
|
|
92182
|
-
const ran = await akb(["review-dismissals", "--
|
|
92150
|
+
const ran = await akb(["review-dismissals", "--follow", "--events", "--json"], true);
|
|
92183
92151
|
clearLaid(ws.board);
|
|
92184
92152
|
resetSorted(ws);
|
|
92185
92153
|
const runs = (answerOf2(await akb(["run", "list", "--all", "--json"]))?.runs ?? []).filter((r2) => (r2.startedAt ?? 0) >= since);
|
|
@@ -92196,6 +92164,15 @@ async function learnRejections(job, ws, deps, io) {
|
|
|
92196
92164
|
if (failure) console.error(`runner: rejections not learned: ${failure}`);
|
|
92197
92165
|
return runs;
|
|
92198
92166
|
}
|
|
92167
|
+
async function scheduledEnv(ws, deps) {
|
|
92168
|
+
const read = await deps.api.readAgents(deps.machineId, ws.project);
|
|
92169
|
+
if (!read.ok) {
|
|
92170
|
+
console.error(`runner: scheduled agents not read: ${read.error}`);
|
|
92171
|
+
return {};
|
|
92172
|
+
}
|
|
92173
|
+
const names2 = read.value.agents.filter((a3) => a3.workflow).map((a3) => a3.name);
|
|
92174
|
+
return { [SCHEDULED_AGENTS_ENV]: [...new Set(names2)].join(",") };
|
|
92175
|
+
}
|
|
92199
92176
|
async function runAgent(job, ws, deps, io) {
|
|
92200
92177
|
const since = Date.now();
|
|
92201
92178
|
const failed = await setUp(job, ws, deps, io);
|
|
@@ -92210,7 +92187,8 @@ async function runAgent(job, ws, deps, io) {
|
|
|
92210
92187
|
const args = workflow ? ["agent", "run", workflowName(workflow), name] : name === "reflect" ? ["reflect", "--cards", ...tasks.map((t2) => String(t2.number))] : [name];
|
|
92211
92188
|
const akb = boardAkb(job, ws, deps, io, ws.cloudTask ?? void 0);
|
|
92212
92189
|
await akb(["run", "list", "--all", "--json"]);
|
|
92213
|
-
const
|
|
92190
|
+
const env2 = name === "reflect" && !workflow ? await scheduledEnv(ws, deps) : void 0;
|
|
92191
|
+
const ran = await akb([...args, "--follow", "--events", "--json"], true, env2);
|
|
92214
92192
|
if (io.lost()) return { ok: false, reason: "" };
|
|
92215
92193
|
const answer = answerOf2(ran);
|
|
92216
92194
|
if (ran.code !== 0) return { ok: false, reason: firstLine(answer?.error?.message?.replace(/^run \S+ ended \w+: /, "")) ?? refusal2(ran) };
|
|
@@ -92360,7 +92338,7 @@ ${draftLine(ws)}
|
|
|
92360
92338
|
return { ok: true, report: { card: card2 } };
|
|
92361
92339
|
}
|
|
92362
92340
|
function carryArgs(verb) {
|
|
92363
|
-
if (!["refine", "resolve", "revise"].includes(verb)) return [];
|
|
92341
|
+
if (!["refine", "resolve", "revise", "implement"].includes(verb)) return [];
|
|
92364
92342
|
const transcript = writeTranscript(job, path28.join(ws.board, ".sync", `${ws.task}.discussion`));
|
|
92365
92343
|
return [
|
|
92366
92344
|
...job.resume ? ["--session", job.resume, ...job.fork ? ["--fork"] : []] : [],
|
|
@@ -92389,8 +92367,8 @@ function holdMachine(kind, onHeld, onWaiting) {
|
|
|
92389
92367
|
let waiting = null;
|
|
92390
92368
|
let timer = null;
|
|
92391
92369
|
const peers = /* @__PURE__ */ new Set();
|
|
92392
|
-
const later = (
|
|
92393
|
-
if (!closed) timer = setTimeout(attempt,
|
|
92370
|
+
const later = (ms) => {
|
|
92371
|
+
if (!closed) timer = setTimeout(attempt, ms);
|
|
92394
92372
|
};
|
|
92395
92373
|
const attempt = () => {
|
|
92396
92374
|
timer = null;
|
|
@@ -92708,6 +92686,7 @@ function streamOut(deps, id, lease) {
|
|
|
92708
92686
|
const stored = new Promise((resolve2) => ended2 = resolve2);
|
|
92709
92687
|
const children = /* @__PURE__ */ new Set();
|
|
92710
92688
|
const kill = (child) => {
|
|
92689
|
+
if (!child.pid) return;
|
|
92711
92690
|
child.kill("SIGTERM");
|
|
92712
92691
|
setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS).unref();
|
|
92713
92692
|
};
|
|
@@ -93073,10 +93052,11 @@ async function runAgentJob(job, deps, track, keep2) {
|
|
|
93073
93052
|
var quietLines = (plan2, chunk) => chunk.split("\n").filter((line) => line && !plan2.quiet(line)).map((line) => `${line}
|
|
93074
93053
|
`).join("");
|
|
93075
93054
|
var stop = (child) => {
|
|
93055
|
+
if (!child.pid) return;
|
|
93076
93056
|
child.kill("SIGTERM");
|
|
93077
93057
|
setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS).unref();
|
|
93078
93058
|
};
|
|
93079
|
-
var wait2 = (
|
|
93059
|
+
var wait2 = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
93080
93060
|
var held3 = (deps, lease) => Date.now() - lease.at < deps.leaseMs;
|
|
93081
93061
|
async function whileOffline(deps, id, lease, attempt) {
|
|
93082
93062
|
for (; ; ) {
|
|
@@ -93122,8 +93102,8 @@ async function runSecret(job, deps) {
|
|
|
93122
93102
|
await deps.api.finishJob(deps.machineId, job.id, "done", "");
|
|
93123
93103
|
}
|
|
93124
93104
|
async function runTest(job, deps) {
|
|
93125
|
-
const finish2 = async (outcome, reason,
|
|
93126
|
-
await deps.api.finishJob(deps.machineId, job.id, outcome, reason,
|
|
93105
|
+
const finish2 = async (outcome, reason, ms2) => {
|
|
93106
|
+
await deps.api.finishJob(deps.machineId, job.id, outcome, reason, ms2 === void 0 ? void 0 : { ms: ms2 });
|
|
93127
93107
|
};
|
|
93128
93108
|
const report2 = (await deps.runtimes()).find((r2) => r2.name === job.runtime);
|
|
93129
93109
|
if (!report2?.installed) return finish2("failed", "not_installed");
|
|
@@ -93145,10 +93125,10 @@ async function runTest(job, deps) {
|
|
|
93145
93125
|
]);
|
|
93146
93126
|
clearTimeout(timer);
|
|
93147
93127
|
stop(child);
|
|
93148
|
-
const
|
|
93149
|
-
if (end === "timeout") return finish2("failed", "timeout",
|
|
93150
|
-
if (end instanceof Error) return end.code === "ENOENT" ? finish2("failed", "not_installed") : finish2("failed", end.message.slice(0, 300),
|
|
93151
|
-
return end.ok ? finish2("done", "",
|
|
93128
|
+
const ms2 = Date.now() - startedAt;
|
|
93129
|
+
if (end === "timeout") return finish2("failed", "timeout", ms2);
|
|
93130
|
+
if (end instanceof Error) return end.code === "ENOENT" ? finish2("failed", "not_installed") : finish2("failed", end.message.slice(0, 300), ms2);
|
|
93131
|
+
return end.ok ? finish2("done", "", ms2) : finish2("failed", (end.error || "The connector stopped.").slice(0, 300), ms2);
|
|
93152
93132
|
}
|
|
93153
93133
|
const renderer = run2.renderer;
|
|
93154
93134
|
const ended2 = await new Promise((resolve2) => {
|
|
@@ -93182,13 +93162,13 @@ async function runTest(job, deps) {
|
|
|
93182
93162
|
resolve2({ code, said });
|
|
93183
93163
|
});
|
|
93184
93164
|
});
|
|
93185
|
-
const
|
|
93186
|
-
if (ended2.timedOut) return finish2("failed", "timeout",
|
|
93165
|
+
const ms = Date.now() - startedAt;
|
|
93166
|
+
if (ended2.timedOut) return finish2("failed", "timeout", ms);
|
|
93187
93167
|
if (ended2.error?.code === "ENOENT") return finish2("failed", "not_installed");
|
|
93188
93168
|
renderer.flush();
|
|
93189
93169
|
const failure = ended2.error?.message ?? renderer.failure?.() ?? (ended2.code === 0 ? void 0 : ended2.said.trim().split("\n").at(-1) || `Exited with code ${ended2.code}.`);
|
|
93190
|
-
if (failure) return finish2("failed", failure.slice(0, 300),
|
|
93191
|
-
return finish2("done", "",
|
|
93170
|
+
if (failure) return finish2("failed", failure.slice(0, 300), ms);
|
|
93171
|
+
return finish2("done", "", ms);
|
|
93192
93172
|
}
|
|
93193
93173
|
function report(job, run2, turn) {
|
|
93194
93174
|
const context = turn ? turn.context : run2.renderer?.context?.();
|
|
@@ -93279,9 +93259,10 @@ function keepPresence(machineId2, pingMs = PING_MS) {
|
|
|
93279
93259
|
}
|
|
93280
93260
|
|
|
93281
93261
|
// src/connect.ts
|
|
93282
|
-
var HEARTBEAT_MS2 =
|
|
93262
|
+
var HEARTBEAT_MS2 = 10 * 6e4;
|
|
93283
93263
|
var POLL_MS = 6e4;
|
|
93284
93264
|
var BACKOFF_MS3 = [1e3, 2e3, 5e3, 1e4, 3e4];
|
|
93265
|
+
var LOOK_LATE_MS = 6e4;
|
|
93285
93266
|
function startRunner(options) {
|
|
93286
93267
|
let registration = null;
|
|
93287
93268
|
let connected = false;
|
|
@@ -93313,10 +93294,10 @@ function startRunner(options) {
|
|
|
93313
93294
|
return found;
|
|
93314
93295
|
};
|
|
93315
93296
|
const idle2 = () => running.size ? t.running(running.size) : t.connected(registration.machineName);
|
|
93316
|
-
const schedule = (
|
|
93297
|
+
const schedule = (ms) => {
|
|
93317
93298
|
if (closed) return;
|
|
93318
93299
|
if (timer) clearTimeout(timer);
|
|
93319
|
-
timer = setTimeout(tick,
|
|
93300
|
+
timer = setTimeout(tick, ms);
|
|
93320
93301
|
};
|
|
93321
93302
|
let looking = false;
|
|
93322
93303
|
const agentsDue = async () => {
|
|
@@ -93330,8 +93311,18 @@ function startRunner(options) {
|
|
|
93330
93311
|
looking = false;
|
|
93331
93312
|
}
|
|
93332
93313
|
};
|
|
93333
|
-
|
|
93334
|
-
|
|
93314
|
+
let agentsTimer = null;
|
|
93315
|
+
const lookNext = () => {
|
|
93316
|
+
if (closed) return;
|
|
93317
|
+
const at2 = (options.nextLook ?? nextHour)(Date.now());
|
|
93318
|
+
agentsTimer = setTimeout(() => {
|
|
93319
|
+
const late = Date.now() - at2;
|
|
93320
|
+
if (late >= 0 && late < LOOK_LATE_MS) void agentsDue();
|
|
93321
|
+
lookNext();
|
|
93322
|
+
}, at2 - Date.now());
|
|
93323
|
+
agentsTimer.unref?.();
|
|
93324
|
+
};
|
|
93325
|
+
lookNext();
|
|
93335
93326
|
let sweeping = false;
|
|
93336
93327
|
let swept = false;
|
|
93337
93328
|
const sweep = async () => {
|
|
@@ -93391,7 +93382,6 @@ function startRunner(options) {
|
|
|
93391
93382
|
await readJobs();
|
|
93392
93383
|
if (!live?.joined()) boards?.pullAll();
|
|
93393
93384
|
void reviewDue();
|
|
93394
|
-
void agentsDue();
|
|
93395
93385
|
schedule(live?.joined() ? options.heartbeatMs ?? HEARTBEAT_MS2 : Math.min(options.pollMs ?? POLL_MS, options.heartbeatMs ?? HEARTBEAT_MS2));
|
|
93396
93386
|
};
|
|
93397
93387
|
const openLive = () => {
|
|
@@ -93487,7 +93477,7 @@ function startRunner(options) {
|
|
|
93487
93477
|
closed = true;
|
|
93488
93478
|
lock.release();
|
|
93489
93479
|
if (timer) clearTimeout(timer);
|
|
93490
|
-
|
|
93480
|
+
if (agentsTimer) clearTimeout(agentsTimer);
|
|
93491
93481
|
clearInterval(sweepTimer);
|
|
93492
93482
|
live?.close();
|
|
93493
93483
|
presence?.close();
|
|
@@ -93655,7 +93645,7 @@ async function runDesktop(tell2) {
|
|
|
93655
93645
|
const shown = /* @__PURE__ */ new Set();
|
|
93656
93646
|
let wake = () => {
|
|
93657
93647
|
};
|
|
93658
|
-
const
|
|
93648
|
+
const readInbox2 = () => {
|
|
93659
93649
|
if (inboxTimer) clearTimeout(inboxTimer);
|
|
93660
93650
|
inboxTimer = setTimeout(async () => {
|
|
93661
93651
|
const inbox = await readInbox();
|
|
@@ -93717,7 +93707,7 @@ async function runDesktop(tell2) {
|
|
|
93717
93707
|
void readFolders();
|
|
93718
93708
|
void readPlan2();
|
|
93719
93709
|
void readAlerts();
|
|
93720
|
-
|
|
93710
|
+
readInbox2();
|
|
93721
93711
|
};
|
|
93722
93712
|
const onConnected = () => {
|
|
93723
93713
|
tell2({ type: "connected" });
|
|
@@ -93755,11 +93745,11 @@ async function runDesktop(tell2) {
|
|
|
93755
93745
|
notify = command.on;
|
|
93756
93746
|
return runner?.renew();
|
|
93757
93747
|
case "refresh":
|
|
93758
|
-
|
|
93748
|
+
readInbox2();
|
|
93759
93749
|
return void readAlerts();
|
|
93760
93750
|
case "read":
|
|
93761
93751
|
await readAlert(command.alert);
|
|
93762
|
-
return
|
|
93752
|
+
return readInbox2();
|
|
93763
93753
|
case "addFolder": {
|
|
93764
93754
|
const project = command.project;
|
|
93765
93755
|
const why = refusal(command.path);
|
|
@@ -93829,11 +93819,11 @@ async function runDesktop(tell2) {
|
|
|
93829
93819
|
onDisconnected: () => emit({ type: "connection", state: "reconnecting" }),
|
|
93830
93820
|
onHint: (payload) => {
|
|
93831
93821
|
if (payload.alertId || !payload.taskId) void readAlerts();
|
|
93832
|
-
if (!payload.jobId)
|
|
93822
|
+
if (!payload.jobId) readInbox2();
|
|
93833
93823
|
}
|
|
93834
93824
|
});
|
|
93835
93825
|
poller = setInterval(() => {
|
|
93836
|
-
|
|
93826
|
+
readInbox2();
|
|
93837
93827
|
void readAlerts();
|
|
93838
93828
|
}, POLL_MS2);
|
|
93839
93829
|
void runner.stopped.then(wake);
|