strikethroo 3.12.0 → 3.13.0
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-web/assets/{arc-BVtIjHfG.js → arc-BgbdqiWZ.js} +1 -1
- package/dist-web/assets/{architectureDiagram-3BPJPVTR-6n6Kx_Nw.js → architectureDiagram-3BPJPVTR-C11ra1og.js} +1 -1
- package/dist-web/assets/{blockDiagram-GPEHLZMM-DVQrCUNW.js → blockDiagram-GPEHLZMM-sneTcKTc.js} +1 -1
- package/dist-web/assets/{c4Diagram-AAUBKEIU-BmsJKunV.js → c4Diagram-AAUBKEIU-rcZrBkXz.js} +1 -1
- package/dist-web/assets/channel-DhL4ovjN.js +1 -0
- package/dist-web/assets/{chunk-2J33WTMH-CLmshK_w.js → chunk-2J33WTMH-BMATkNbT.js} +1 -1
- package/dist-web/assets/{chunk-4BX2VUAB-DFWJI57N.js → chunk-4BX2VUAB-BSz2O6Ft.js} +1 -1
- package/dist-web/assets/{chunk-55IACEB6-Cw5bYv7_.js → chunk-55IACEB6-MumFzZkZ.js} +1 -1
- package/dist-web/assets/{chunk-727SXJPM-cGYMQHSz.js → chunk-727SXJPM-4dQkVcIM.js} +1 -1
- package/dist-web/assets/{chunk-AQP2D5EJ-CQjDykhJ.js → chunk-AQP2D5EJ-v5TVK_fa.js} +1 -1
- package/dist-web/assets/{chunk-FMBD7UC4-x3hzV0ms.js → chunk-FMBD7UC4-BArw-yD6.js} +1 -1
- package/dist-web/assets/{chunk-ND2GUHAM-B2mXRbNo.js → chunk-ND2GUHAM-jmMu7-6G.js} +1 -1
- package/dist-web/assets/{chunk-QZHKN3VN-CvnkhP9r.js → chunk-QZHKN3VN-CoFZRE9S.js} +1 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-DNoS6CPC.js +1 -0
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-DNoS6CPC.js +1 -0
- package/dist-web/assets/{cose-bilkent-S5V4N54A-BZpF-dzH.js → cose-bilkent-S5V4N54A-DfE6Yc6V.js} +1 -1
- package/dist-web/assets/{dagre-BM42HDAG-DFMuZyrG.js → dagre-BM42HDAG-GLQxrEea.js} +1 -1
- package/dist-web/assets/{diagram-2AECGRRQ-BvprRz2I.js → diagram-2AECGRRQ-CPF-j3jI.js} +1 -1
- package/dist-web/assets/{diagram-5GNKFQAL-DbHN8zOP.js → diagram-5GNKFQAL-DX8N0bhf.js} +1 -1
- package/dist-web/assets/{diagram-KO2AKTUF-2xhIBvDF.js → diagram-KO2AKTUF-D4wM_Xrg.js} +1 -1
- package/dist-web/assets/{diagram-LMA3HP47-BZSMb8wm.js → diagram-LMA3HP47-uVt4DExc.js} +1 -1
- package/dist-web/assets/{diagram-OG6HWLK6-DZxBiAwf.js → diagram-OG6HWLK6-DzfLImY-.js} +1 -1
- package/dist-web/assets/{erDiagram-TEJ5UH35-DOc66mWB.js → erDiagram-TEJ5UH35-BDOB8bJk.js} +1 -1
- package/dist-web/assets/{flowDiagram-I6XJVG4X-rEwEgwKf.js → flowDiagram-I6XJVG4X-DsofFC7H.js} +1 -1
- package/dist-web/assets/{ganttDiagram-6RSMTGT7-BAStzA-L.js → ganttDiagram-6RSMTGT7-DYCTEBUe.js} +1 -1
- package/dist-web/assets/{gitGraphDiagram-PVQCEYII-C0gTHRDa.js → gitGraphDiagram-PVQCEYII-B373xEyt.js} +1 -1
- package/dist-web/assets/{index-DBUy3IfQ.js → index-BrXKePvp.js} +1 -1
- package/dist-web/assets/{index-CNj2Qj_m.js → index-BxjDhqax.js} +1 -1
- package/dist-web/assets/{index-CGjoHidG.js → index-CvZkEGgs.js} +4 -4
- package/dist-web/assets/{infoDiagram-5YYISTIA-Dh2D2DOL.js → infoDiagram-5YYISTIA-BTdfbRG3.js} +1 -1
- package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-4Fb9ugBL.js → ishikawaDiagram-YF4QCWOH-By0jpBpG.js} +1 -1
- package/dist-web/assets/{journeyDiagram-JHISSGLW-BBjMcjNc.js → journeyDiagram-JHISSGLW-CN4ddpRF.js} +1 -1
- package/dist-web/assets/{kanban-definition-UN3LZRKU-eyj4aSf_.js → kanban-definition-UN3LZRKU-CSzp97xY.js} +1 -1
- package/dist-web/assets/{linear-KJUWAP7h.js → linear-Bo45a3LX.js} +1 -1
- package/dist-web/assets/{mermaid.core-B9tzk4XH.js → mermaid.core-fEMv_ThD.js} +4 -4
- package/dist-web/assets/{mindmap-definition-RKZ34NQL-pTCX9_8k.js → mindmap-definition-RKZ34NQL-lcelYnaU.js} +1 -1
- package/dist-web/assets/{pieDiagram-4H26LBE5-CV1GWPlT.js → pieDiagram-4H26LBE5-DqrHeOSK.js} +1 -1
- package/dist-web/assets/{quadrantDiagram-W4KKPZXB-C60DVKh9.js → quadrantDiagram-W4KKPZXB-lKQsolLl.js} +1 -1
- package/dist-web/assets/{requirementDiagram-4Y6WPE33-D5GCyDny.js → requirementDiagram-4Y6WPE33-D3GerVWN.js} +1 -1
- package/dist-web/assets/{sankeyDiagram-5OEKKPKP-L_jgOwN_.js → sankeyDiagram-5OEKKPKP-Dn0Rn4jy.js} +1 -1
- package/dist-web/assets/{sequenceDiagram-3UESZ5HK-ek4VA0bX.js → sequenceDiagram-3UESZ5HK-BMZb9HkP.js} +1 -1
- package/dist-web/assets/{stateDiagram-AJRCARHV-DaTz-gXI.js → stateDiagram-AJRCARHV-mHX_sHdp.js} +1 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BwuUXdDR.js +1 -0
- package/dist-web/assets/{timeline-definition-PNZ67QCA-BSZIQpRw.js → timeline-definition-PNZ67QCA-CrVF3pNw.js} +1 -1
- package/dist-web/assets/{vennDiagram-CIIHVFJN-0qDOzqt8.js → vennDiagram-CIIHVFJN-Dfw6e8s7.js} +1 -1
- package/dist-web/assets/{wardley-L42UT6IY-BOcRObI0.js → wardley-L42UT6IY-HlLGXiR6.js} +1 -1
- package/dist-web/assets/{wardleyDiagram-YWT4CUSO-KyyBf4a6.js → wardleyDiagram-YWT4CUSO-DPL-Ch-8.js} +1 -1
- package/dist-web/assets/{xychartDiagram-2RQKCTM6-SCVN95Cn.js → xychartDiagram-2RQKCTM6-Cd6IimVj.js} +1 -1
- package/dist-web/index.html +1 -1
- package/package.json +1 -1
- package/templates/harness/skills/st-full-workflow/scripts/route-task-execution.cjs +133 -26
- package/templates/harness/skills/st-generate-tasks/scripts/route-task-execution.cjs +133 -26
- package/templates/strikethroo/config/config.yaml +8 -6
- package/dist-web/assets/channel-C1JVeaAF.js +0 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-D1UIhNJl.js +0 -1
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-D1UIhNJl.js +0 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-CgQxtWKp.js +0 -1
|
@@ -3337,8 +3337,8 @@ var require_excerpt = __commonJS({
|
|
|
3337
3337
|
if (sep == null && (opts.excerpt === false || opts.excerpt == null)) {
|
|
3338
3338
|
return file;
|
|
3339
3339
|
}
|
|
3340
|
-
const
|
|
3341
|
-
const idx = file.content.indexOf(
|
|
3340
|
+
const delimiter2 = typeof opts.excerpt === "string" ? opts.excerpt : sep || opts.delimiters[0];
|
|
3341
|
+
const idx = file.content.indexOf(delimiter2);
|
|
3342
3342
|
if (idx !== -1) {
|
|
3343
3343
|
file.excerpt = file.content.slice(0, idx);
|
|
3344
3344
|
}
|
|
@@ -3402,7 +3402,7 @@ var require_parse = __commonJS({
|
|
|
3402
3402
|
var require_gray_matter = __commonJS({
|
|
3403
3403
|
"node_modules/gray-matter/index.js"(exports2, module2) {
|
|
3404
3404
|
"use strict";
|
|
3405
|
-
var
|
|
3405
|
+
var fs7 = require("fs");
|
|
3406
3406
|
var sections = require_section_matter();
|
|
3407
3407
|
var defaults = require_defaults();
|
|
3408
3408
|
var stringify = require_stringify();
|
|
@@ -3486,7 +3486,7 @@ var require_gray_matter = __commonJS({
|
|
|
3486
3486
|
return stringify(file, data, options2);
|
|
3487
3487
|
};
|
|
3488
3488
|
matter2.read = function(filepath, options2) {
|
|
3489
|
-
const str2 =
|
|
3489
|
+
const str2 = fs7.readFileSync(filepath, "utf8");
|
|
3490
3490
|
const file = matter2(str2, options2);
|
|
3491
3491
|
file.path = filepath;
|
|
3492
3492
|
return file;
|
|
@@ -3515,8 +3515,8 @@ var require_gray_matter = __commonJS({
|
|
|
3515
3515
|
});
|
|
3516
3516
|
|
|
3517
3517
|
// src/skill-scripts/route-task-execution.ts
|
|
3518
|
-
var
|
|
3519
|
-
var
|
|
3518
|
+
var fs6 = __toESM(require("fs"));
|
|
3519
|
+
var path6 = __toESM(require("path"));
|
|
3520
3520
|
|
|
3521
3521
|
// src/types.ts
|
|
3522
3522
|
var SUPPORTED_HARNESSES = [
|
|
@@ -3797,8 +3797,8 @@ var readTaskExecutionPolicy = (taskMarkdown, context) => {
|
|
|
3797
3797
|
};
|
|
3798
3798
|
|
|
3799
3799
|
// src/skill-scripts/shared/execution-routing.ts
|
|
3800
|
-
var
|
|
3801
|
-
var
|
|
3800
|
+
var fs5 = __toESM(require("fs"));
|
|
3801
|
+
var path5 = __toESM(require("path"));
|
|
3802
3802
|
var import_child_process = require("child_process");
|
|
3803
3803
|
|
|
3804
3804
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -6023,8 +6023,108 @@ var DEFAULT_DUMP_OPTIONS = {
|
|
|
6023
6023
|
}
|
|
6024
6024
|
};
|
|
6025
6025
|
|
|
6026
|
+
// src/skill-scripts/shared/external-dispatch.ts
|
|
6027
|
+
var fs4 = __toESM(require("fs"));
|
|
6028
|
+
var path4 = __toESM(require("path"));
|
|
6029
|
+
var taskPrompt = (request) => `Strikethroo external task dispatch \u2014 Plan ${request.planId}, Task ${request.taskId}.
|
|
6030
|
+
Workspace: ${request.workspace}
|
|
6031
|
+
Task file: ${request.taskFile}
|
|
6032
|
+
Before implementation, read and execute ${path4.join(
|
|
6033
|
+
request.workspace,
|
|
6034
|
+
".ai/strikethroo/config/hooks/PRE_TASK_EXECUTION.md"
|
|
6035
|
+
)}. Halt if that hook fails.
|
|
6036
|
+
|
|
6037
|
+
Read and implement this task. Preserve dependency validation, status transitions, evidence reporting, and error-hook handling. Report failures clearly.
|
|
6038
|
+
|
|
6039
|
+
${request.taskMarkdown}`;
|
|
6040
|
+
var command = (executable, argv, request) => ({
|
|
6041
|
+
executable,
|
|
6042
|
+
argv,
|
|
6043
|
+
cwd: request.workspace,
|
|
6044
|
+
stdin: taskPrompt(request)
|
|
6045
|
+
});
|
|
6046
|
+
var EXTERNAL_HARNESS_ADAPTERS = {
|
|
6047
|
+
claude: {
|
|
6048
|
+
executable: "claude",
|
|
6049
|
+
buildCommand: (request) => command(
|
|
6050
|
+
"claude",
|
|
6051
|
+
[
|
|
6052
|
+
"-p",
|
|
6053
|
+
"--model",
|
|
6054
|
+
request.model,
|
|
6055
|
+
...request.reasoningEffort === void 0 ? [] : ["--effort", request.reasoningEffort]
|
|
6056
|
+
],
|
|
6057
|
+
request
|
|
6058
|
+
),
|
|
6059
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6060
|
+
},
|
|
6061
|
+
codex: {
|
|
6062
|
+
executable: "codex",
|
|
6063
|
+
buildCommand: (request) => command(
|
|
6064
|
+
"codex",
|
|
6065
|
+
[
|
|
6066
|
+
"exec",
|
|
6067
|
+
"--model",
|
|
6068
|
+
request.model,
|
|
6069
|
+
...request.reasoningEffort === void 0 ? [] : ["--config", `model_reasoning_effort=${request.reasoningEffort}`],
|
|
6070
|
+
"-"
|
|
6071
|
+
],
|
|
6072
|
+
request
|
|
6073
|
+
),
|
|
6074
|
+
authenticationArgv: () => ["login", "status"]
|
|
6075
|
+
},
|
|
6076
|
+
cursor: {
|
|
6077
|
+
executable: "cursor-agent",
|
|
6078
|
+
buildCommand: (request) => command("cursor-agent", ["--print", "--model", request.model], request),
|
|
6079
|
+
authenticationArgv: () => ["status"]
|
|
6080
|
+
},
|
|
6081
|
+
gemini: {
|
|
6082
|
+
executable: "gemini",
|
|
6083
|
+
buildCommand: (request) => command("gemini", ["--prompt", "", "--model", request.model], request),
|
|
6084
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6085
|
+
},
|
|
6086
|
+
copilot: {
|
|
6087
|
+
executable: "copilot",
|
|
6088
|
+
buildCommand: (request) => command("copilot", ["-p", "", "--model", request.model], request),
|
|
6089
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6090
|
+
},
|
|
6091
|
+
opencode: {
|
|
6092
|
+
executable: "opencode",
|
|
6093
|
+
buildCommand: (request) => command(
|
|
6094
|
+
"opencode",
|
|
6095
|
+
[
|
|
6096
|
+
"run",
|
|
6097
|
+
"--model",
|
|
6098
|
+
request.model,
|
|
6099
|
+
...request.reasoningEffort === void 0 ? [] : ["--variant", request.reasoningEffort],
|
|
6100
|
+
"-"
|
|
6101
|
+
],
|
|
6102
|
+
request
|
|
6103
|
+
),
|
|
6104
|
+
authenticationArgv: () => ["auth", "list"]
|
|
6105
|
+
}
|
|
6106
|
+
};
|
|
6107
|
+
var adapterKeys = Object.keys(EXTERNAL_HARNESS_ADAPTERS).sort();
|
|
6108
|
+
var harnessKeys = [...SUPPORTED_HARNESSES].sort();
|
|
6109
|
+
if (adapterKeys.join("\0") !== harnessKeys.join("\0")) {
|
|
6110
|
+
throw new Error("External harness adapter registry does not cover SUPPORTED_HARNESSES exactly.");
|
|
6111
|
+
}
|
|
6112
|
+
var executableOnPath = (executable) => (process.env.PATH ?? "").split(path4.delimiter).some((directory) => {
|
|
6113
|
+
if (!directory) return false;
|
|
6114
|
+
const candidate = path4.join(directory, executable);
|
|
6115
|
+
try {
|
|
6116
|
+
return fs4.statSync(candidate).isFile();
|
|
6117
|
+
} catch {
|
|
6118
|
+
return false;
|
|
6119
|
+
}
|
|
6120
|
+
});
|
|
6121
|
+
var harnessExecutableAvailable = (harness) => {
|
|
6122
|
+
const adapter = EXTERNAL_HARNESS_ADAPTERS[harness];
|
|
6123
|
+
return adapter ? executableOnPath(adapter.executable) : false;
|
|
6124
|
+
};
|
|
6125
|
+
|
|
6026
6126
|
// src/skill-scripts/shared/execution-routing.ts
|
|
6027
|
-
var WORKSPACE_CONFIG_RELPATH =
|
|
6127
|
+
var WORKSPACE_CONFIG_RELPATH = path5.join("config", "config.yaml");
|
|
6028
6128
|
var EXECUTION_ROUTING_SECTION = "execution_routing";
|
|
6029
6129
|
var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6030
6130
|
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
@@ -6099,10 +6199,10 @@ var validateProfile = (name, raw, supportedHarnesses, errors) => {
|
|
|
6099
6199
|
return { name, description: raw.description.trim(), targets };
|
|
6100
6200
|
};
|
|
6101
6201
|
var loadRoutingConfig = (strikethrooRoot, supportedHarnesses) => {
|
|
6102
|
-
const configPath =
|
|
6202
|
+
const configPath = path5.join(strikethrooRoot, WORKSPACE_CONFIG_RELPATH);
|
|
6103
6203
|
let contents;
|
|
6104
6204
|
try {
|
|
6105
|
-
contents =
|
|
6205
|
+
contents = fs5.readFileSync(configPath, "utf8");
|
|
6106
6206
|
} catch {
|
|
6107
6207
|
return { kind: "no-config" };
|
|
6108
6208
|
}
|
|
@@ -6221,16 +6321,23 @@ var selectTargets = (config, assignments, options2) => {
|
|
|
6221
6321
|
return { id, profile: profileName, candidates: profile.targets };
|
|
6222
6322
|
});
|
|
6223
6323
|
if (!config.resolverScript) {
|
|
6324
|
+
const isHarnessAvailable = options2.harnessAvailable ?? harnessExecutableAvailable;
|
|
6325
|
+
const random = options2.random ?? Math.random;
|
|
6224
6326
|
const selections2 = /* @__PURE__ */ new Map();
|
|
6225
6327
|
for (const task of tasks) {
|
|
6226
|
-
const
|
|
6227
|
-
if (!
|
|
6228
|
-
|
|
6328
|
+
const fallback2 = task.candidates[0];
|
|
6329
|
+
if (!fallback2) throw new Error(`profile "${task.profile}" has no targets`);
|
|
6330
|
+
const available = task.candidates.filter(
|
|
6331
|
+
(candidate) => candidate.harness === void 0 || isHarnessAvailable(candidate.harness)
|
|
6332
|
+
);
|
|
6333
|
+
const pool = available.length > 0 ? available : [fallback2];
|
|
6334
|
+
const chosen = pool[Math.floor(random() * pool.length)] ?? fallback2;
|
|
6335
|
+
selections2.set(task.id, chosen);
|
|
6229
6336
|
}
|
|
6230
6337
|
return { kind: "selected", selections: selections2 };
|
|
6231
6338
|
}
|
|
6232
|
-
const scriptPath =
|
|
6233
|
-
if (!
|
|
6339
|
+
const scriptPath = path5.resolve(options2.projectRoot, config.resolverScript);
|
|
6340
|
+
if (!fs5.existsSync(scriptPath)) {
|
|
6234
6341
|
return {
|
|
6235
6342
|
kind: "resolver-failure",
|
|
6236
6343
|
detail: `custom resolver script not found: ${scriptPath}`
|
|
@@ -6344,10 +6451,10 @@ var usage = () => emit(
|
|
|
6344
6451
|
2
|
|
6345
6452
|
);
|
|
6346
6453
|
var readTaskDocuments = (planDir) => {
|
|
6347
|
-
const tasksDir =
|
|
6454
|
+
const tasksDir = path6.join(planDir, "tasks");
|
|
6348
6455
|
let entries;
|
|
6349
6456
|
try {
|
|
6350
|
-
entries =
|
|
6457
|
+
entries = fs6.readdirSync(tasksDir, { withFileTypes: true });
|
|
6351
6458
|
} catch {
|
|
6352
6459
|
return { kind: "invalid", errors: [`no tasks directory at ${tasksDir}.`] };
|
|
6353
6460
|
}
|
|
@@ -6357,8 +6464,8 @@ var readTaskDocuments = (planDir) => {
|
|
|
6357
6464
|
const taskFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => e.name).sort();
|
|
6358
6465
|
for (const name of taskFiles) {
|
|
6359
6466
|
const entry = { name };
|
|
6360
|
-
const file =
|
|
6361
|
-
const content =
|
|
6467
|
+
const file = path6.join(tasksDir, entry.name);
|
|
6468
|
+
const content = fs6.readFileSync(file, "utf8");
|
|
6362
6469
|
const id = extractPlanId(content, file);
|
|
6363
6470
|
if (id === null) {
|
|
6364
6471
|
errors.push(`task file ${entry.name} has no integer id in its frontmatter.`);
|
|
@@ -6431,7 +6538,7 @@ var main = () => {
|
|
|
6431
6538
|
}
|
|
6432
6539
|
let rawMap;
|
|
6433
6540
|
try {
|
|
6434
|
-
rawMap = JSON.parse(
|
|
6541
|
+
rawMap = JSON.parse(fs6.readFileSync(assignmentFile, "utf8"));
|
|
6435
6542
|
} catch (error) {
|
|
6436
6543
|
emit(
|
|
6437
6544
|
{
|
|
@@ -6453,7 +6560,7 @@ var main = () => {
|
|
|
6453
6560
|
emit({ kind: "invalid-assignments", errors: assignmentResult.errors }, 1);
|
|
6454
6561
|
return;
|
|
6455
6562
|
}
|
|
6456
|
-
const projectRoot =
|
|
6563
|
+
const projectRoot = path6.dirname(path6.dirname(resolved.strikethrooRoot));
|
|
6457
6564
|
const selection = selectTargets(config, assignmentResult.assignments, {
|
|
6458
6565
|
planId: resolved.planId,
|
|
6459
6566
|
projectRoot
|
|
@@ -6481,7 +6588,7 @@ var main = () => {
|
|
|
6481
6588
|
emit(
|
|
6482
6589
|
{
|
|
6483
6590
|
kind: "routing-failure",
|
|
6484
|
-
detail: `task ${task.id} (${
|
|
6591
|
+
detail: `task ${task.id} (${path6.basename(task.file)}): ${error instanceof Error ? error.message : String(error)}`
|
|
6485
6592
|
},
|
|
6486
6593
|
1
|
|
6487
6594
|
);
|
|
@@ -6503,11 +6610,11 @@ var main = () => {
|
|
|
6503
6610
|
const written = [];
|
|
6504
6611
|
try {
|
|
6505
6612
|
for (const { task, next } of staged) {
|
|
6506
|
-
|
|
6613
|
+
fs6.writeFileSync(task.file, next);
|
|
6507
6614
|
written.push(task);
|
|
6508
6615
|
}
|
|
6509
6616
|
for (const { task, execution } of staged) {
|
|
6510
|
-
const reread =
|
|
6617
|
+
const reread = fs6.readFileSync(task.file, "utf8");
|
|
6511
6618
|
const policy = readTaskExecutionPolicy(reread, policyContext);
|
|
6512
6619
|
if (!policyMatchesExecution(policy, execution)) {
|
|
6513
6620
|
throw new Error(`task ${task.id} failed post-write verification.`);
|
|
@@ -6516,7 +6623,7 @@ var main = () => {
|
|
|
6516
6623
|
} catch (error) {
|
|
6517
6624
|
for (const task of written) {
|
|
6518
6625
|
try {
|
|
6519
|
-
|
|
6626
|
+
fs6.writeFileSync(task.file, task.content);
|
|
6520
6627
|
} catch {
|
|
6521
6628
|
}
|
|
6522
6629
|
}
|
|
@@ -3337,8 +3337,8 @@ var require_excerpt = __commonJS({
|
|
|
3337
3337
|
if (sep == null && (opts.excerpt === false || opts.excerpt == null)) {
|
|
3338
3338
|
return file;
|
|
3339
3339
|
}
|
|
3340
|
-
const
|
|
3341
|
-
const idx = file.content.indexOf(
|
|
3340
|
+
const delimiter2 = typeof opts.excerpt === "string" ? opts.excerpt : sep || opts.delimiters[0];
|
|
3341
|
+
const idx = file.content.indexOf(delimiter2);
|
|
3342
3342
|
if (idx !== -1) {
|
|
3343
3343
|
file.excerpt = file.content.slice(0, idx);
|
|
3344
3344
|
}
|
|
@@ -3402,7 +3402,7 @@ var require_parse = __commonJS({
|
|
|
3402
3402
|
var require_gray_matter = __commonJS({
|
|
3403
3403
|
"node_modules/gray-matter/index.js"(exports2, module2) {
|
|
3404
3404
|
"use strict";
|
|
3405
|
-
var
|
|
3405
|
+
var fs7 = require("fs");
|
|
3406
3406
|
var sections = require_section_matter();
|
|
3407
3407
|
var defaults = require_defaults();
|
|
3408
3408
|
var stringify = require_stringify();
|
|
@@ -3486,7 +3486,7 @@ var require_gray_matter = __commonJS({
|
|
|
3486
3486
|
return stringify(file, data, options2);
|
|
3487
3487
|
};
|
|
3488
3488
|
matter2.read = function(filepath, options2) {
|
|
3489
|
-
const str2 =
|
|
3489
|
+
const str2 = fs7.readFileSync(filepath, "utf8");
|
|
3490
3490
|
const file = matter2(str2, options2);
|
|
3491
3491
|
file.path = filepath;
|
|
3492
3492
|
return file;
|
|
@@ -3515,8 +3515,8 @@ var require_gray_matter = __commonJS({
|
|
|
3515
3515
|
});
|
|
3516
3516
|
|
|
3517
3517
|
// src/skill-scripts/route-task-execution.ts
|
|
3518
|
-
var
|
|
3519
|
-
var
|
|
3518
|
+
var fs6 = __toESM(require("fs"));
|
|
3519
|
+
var path6 = __toESM(require("path"));
|
|
3520
3520
|
|
|
3521
3521
|
// src/types.ts
|
|
3522
3522
|
var SUPPORTED_HARNESSES = [
|
|
@@ -3797,8 +3797,8 @@ var readTaskExecutionPolicy = (taskMarkdown, context) => {
|
|
|
3797
3797
|
};
|
|
3798
3798
|
|
|
3799
3799
|
// src/skill-scripts/shared/execution-routing.ts
|
|
3800
|
-
var
|
|
3801
|
-
var
|
|
3800
|
+
var fs5 = __toESM(require("fs"));
|
|
3801
|
+
var path5 = __toESM(require("path"));
|
|
3802
3802
|
var import_child_process = require("child_process");
|
|
3803
3803
|
|
|
3804
3804
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
@@ -6023,8 +6023,108 @@ var DEFAULT_DUMP_OPTIONS = {
|
|
|
6023
6023
|
}
|
|
6024
6024
|
};
|
|
6025
6025
|
|
|
6026
|
+
// src/skill-scripts/shared/external-dispatch.ts
|
|
6027
|
+
var fs4 = __toESM(require("fs"));
|
|
6028
|
+
var path4 = __toESM(require("path"));
|
|
6029
|
+
var taskPrompt = (request) => `Strikethroo external task dispatch \u2014 Plan ${request.planId}, Task ${request.taskId}.
|
|
6030
|
+
Workspace: ${request.workspace}
|
|
6031
|
+
Task file: ${request.taskFile}
|
|
6032
|
+
Before implementation, read and execute ${path4.join(
|
|
6033
|
+
request.workspace,
|
|
6034
|
+
".ai/strikethroo/config/hooks/PRE_TASK_EXECUTION.md"
|
|
6035
|
+
)}. Halt if that hook fails.
|
|
6036
|
+
|
|
6037
|
+
Read and implement this task. Preserve dependency validation, status transitions, evidence reporting, and error-hook handling. Report failures clearly.
|
|
6038
|
+
|
|
6039
|
+
${request.taskMarkdown}`;
|
|
6040
|
+
var command = (executable, argv, request) => ({
|
|
6041
|
+
executable,
|
|
6042
|
+
argv,
|
|
6043
|
+
cwd: request.workspace,
|
|
6044
|
+
stdin: taskPrompt(request)
|
|
6045
|
+
});
|
|
6046
|
+
var EXTERNAL_HARNESS_ADAPTERS = {
|
|
6047
|
+
claude: {
|
|
6048
|
+
executable: "claude",
|
|
6049
|
+
buildCommand: (request) => command(
|
|
6050
|
+
"claude",
|
|
6051
|
+
[
|
|
6052
|
+
"-p",
|
|
6053
|
+
"--model",
|
|
6054
|
+
request.model,
|
|
6055
|
+
...request.reasoningEffort === void 0 ? [] : ["--effort", request.reasoningEffort]
|
|
6056
|
+
],
|
|
6057
|
+
request
|
|
6058
|
+
),
|
|
6059
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6060
|
+
},
|
|
6061
|
+
codex: {
|
|
6062
|
+
executable: "codex",
|
|
6063
|
+
buildCommand: (request) => command(
|
|
6064
|
+
"codex",
|
|
6065
|
+
[
|
|
6066
|
+
"exec",
|
|
6067
|
+
"--model",
|
|
6068
|
+
request.model,
|
|
6069
|
+
...request.reasoningEffort === void 0 ? [] : ["--config", `model_reasoning_effort=${request.reasoningEffort}`],
|
|
6070
|
+
"-"
|
|
6071
|
+
],
|
|
6072
|
+
request
|
|
6073
|
+
),
|
|
6074
|
+
authenticationArgv: () => ["login", "status"]
|
|
6075
|
+
},
|
|
6076
|
+
cursor: {
|
|
6077
|
+
executable: "cursor-agent",
|
|
6078
|
+
buildCommand: (request) => command("cursor-agent", ["--print", "--model", request.model], request),
|
|
6079
|
+
authenticationArgv: () => ["status"]
|
|
6080
|
+
},
|
|
6081
|
+
gemini: {
|
|
6082
|
+
executable: "gemini",
|
|
6083
|
+
buildCommand: (request) => command("gemini", ["--prompt", "", "--model", request.model], request),
|
|
6084
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6085
|
+
},
|
|
6086
|
+
copilot: {
|
|
6087
|
+
executable: "copilot",
|
|
6088
|
+
buildCommand: (request) => command("copilot", ["-p", "", "--model", request.model], request),
|
|
6089
|
+
authenticationArgv: () => ["auth", "status"]
|
|
6090
|
+
},
|
|
6091
|
+
opencode: {
|
|
6092
|
+
executable: "opencode",
|
|
6093
|
+
buildCommand: (request) => command(
|
|
6094
|
+
"opencode",
|
|
6095
|
+
[
|
|
6096
|
+
"run",
|
|
6097
|
+
"--model",
|
|
6098
|
+
request.model,
|
|
6099
|
+
...request.reasoningEffort === void 0 ? [] : ["--variant", request.reasoningEffort],
|
|
6100
|
+
"-"
|
|
6101
|
+
],
|
|
6102
|
+
request
|
|
6103
|
+
),
|
|
6104
|
+
authenticationArgv: () => ["auth", "list"]
|
|
6105
|
+
}
|
|
6106
|
+
};
|
|
6107
|
+
var adapterKeys = Object.keys(EXTERNAL_HARNESS_ADAPTERS).sort();
|
|
6108
|
+
var harnessKeys = [...SUPPORTED_HARNESSES].sort();
|
|
6109
|
+
if (adapterKeys.join("\0") !== harnessKeys.join("\0")) {
|
|
6110
|
+
throw new Error("External harness adapter registry does not cover SUPPORTED_HARNESSES exactly.");
|
|
6111
|
+
}
|
|
6112
|
+
var executableOnPath = (executable) => (process.env.PATH ?? "").split(path4.delimiter).some((directory) => {
|
|
6113
|
+
if (!directory) return false;
|
|
6114
|
+
const candidate = path4.join(directory, executable);
|
|
6115
|
+
try {
|
|
6116
|
+
return fs4.statSync(candidate).isFile();
|
|
6117
|
+
} catch {
|
|
6118
|
+
return false;
|
|
6119
|
+
}
|
|
6120
|
+
});
|
|
6121
|
+
var harnessExecutableAvailable = (harness) => {
|
|
6122
|
+
const adapter = EXTERNAL_HARNESS_ADAPTERS[harness];
|
|
6123
|
+
return adapter ? executableOnPath(adapter.executable) : false;
|
|
6124
|
+
};
|
|
6125
|
+
|
|
6026
6126
|
// src/skill-scripts/shared/execution-routing.ts
|
|
6027
|
-
var WORKSPACE_CONFIG_RELPATH =
|
|
6127
|
+
var WORKSPACE_CONFIG_RELPATH = path5.join("config", "config.yaml");
|
|
6028
6128
|
var EXECUTION_ROUTING_SECTION = "execution_routing";
|
|
6029
6129
|
var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6030
6130
|
var isNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0;
|
|
@@ -6099,10 +6199,10 @@ var validateProfile = (name, raw, supportedHarnesses, errors) => {
|
|
|
6099
6199
|
return { name, description: raw.description.trim(), targets };
|
|
6100
6200
|
};
|
|
6101
6201
|
var loadRoutingConfig = (strikethrooRoot, supportedHarnesses) => {
|
|
6102
|
-
const configPath =
|
|
6202
|
+
const configPath = path5.join(strikethrooRoot, WORKSPACE_CONFIG_RELPATH);
|
|
6103
6203
|
let contents;
|
|
6104
6204
|
try {
|
|
6105
|
-
contents =
|
|
6205
|
+
contents = fs5.readFileSync(configPath, "utf8");
|
|
6106
6206
|
} catch {
|
|
6107
6207
|
return { kind: "no-config" };
|
|
6108
6208
|
}
|
|
@@ -6221,16 +6321,23 @@ var selectTargets = (config, assignments, options2) => {
|
|
|
6221
6321
|
return { id, profile: profileName, candidates: profile.targets };
|
|
6222
6322
|
});
|
|
6223
6323
|
if (!config.resolverScript) {
|
|
6324
|
+
const isHarnessAvailable = options2.harnessAvailable ?? harnessExecutableAvailable;
|
|
6325
|
+
const random = options2.random ?? Math.random;
|
|
6224
6326
|
const selections2 = /* @__PURE__ */ new Map();
|
|
6225
6327
|
for (const task of tasks) {
|
|
6226
|
-
const
|
|
6227
|
-
if (!
|
|
6228
|
-
|
|
6328
|
+
const fallback2 = task.candidates[0];
|
|
6329
|
+
if (!fallback2) throw new Error(`profile "${task.profile}" has no targets`);
|
|
6330
|
+
const available = task.candidates.filter(
|
|
6331
|
+
(candidate) => candidate.harness === void 0 || isHarnessAvailable(candidate.harness)
|
|
6332
|
+
);
|
|
6333
|
+
const pool = available.length > 0 ? available : [fallback2];
|
|
6334
|
+
const chosen = pool[Math.floor(random() * pool.length)] ?? fallback2;
|
|
6335
|
+
selections2.set(task.id, chosen);
|
|
6229
6336
|
}
|
|
6230
6337
|
return { kind: "selected", selections: selections2 };
|
|
6231
6338
|
}
|
|
6232
|
-
const scriptPath =
|
|
6233
|
-
if (!
|
|
6339
|
+
const scriptPath = path5.resolve(options2.projectRoot, config.resolverScript);
|
|
6340
|
+
if (!fs5.existsSync(scriptPath)) {
|
|
6234
6341
|
return {
|
|
6235
6342
|
kind: "resolver-failure",
|
|
6236
6343
|
detail: `custom resolver script not found: ${scriptPath}`
|
|
@@ -6344,10 +6451,10 @@ var usage = () => emit(
|
|
|
6344
6451
|
2
|
|
6345
6452
|
);
|
|
6346
6453
|
var readTaskDocuments = (planDir) => {
|
|
6347
|
-
const tasksDir =
|
|
6454
|
+
const tasksDir = path6.join(planDir, "tasks");
|
|
6348
6455
|
let entries;
|
|
6349
6456
|
try {
|
|
6350
|
-
entries =
|
|
6457
|
+
entries = fs6.readdirSync(tasksDir, { withFileTypes: true });
|
|
6351
6458
|
} catch {
|
|
6352
6459
|
return { kind: "invalid", errors: [`no tasks directory at ${tasksDir}.`] };
|
|
6353
6460
|
}
|
|
@@ -6357,8 +6464,8 @@ var readTaskDocuments = (planDir) => {
|
|
|
6357
6464
|
const taskFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => e.name).sort();
|
|
6358
6465
|
for (const name of taskFiles) {
|
|
6359
6466
|
const entry = { name };
|
|
6360
|
-
const file =
|
|
6361
|
-
const content =
|
|
6467
|
+
const file = path6.join(tasksDir, entry.name);
|
|
6468
|
+
const content = fs6.readFileSync(file, "utf8");
|
|
6362
6469
|
const id = extractPlanId(content, file);
|
|
6363
6470
|
if (id === null) {
|
|
6364
6471
|
errors.push(`task file ${entry.name} has no integer id in its frontmatter.`);
|
|
@@ -6431,7 +6538,7 @@ var main = () => {
|
|
|
6431
6538
|
}
|
|
6432
6539
|
let rawMap;
|
|
6433
6540
|
try {
|
|
6434
|
-
rawMap = JSON.parse(
|
|
6541
|
+
rawMap = JSON.parse(fs6.readFileSync(assignmentFile, "utf8"));
|
|
6435
6542
|
} catch (error) {
|
|
6436
6543
|
emit(
|
|
6437
6544
|
{
|
|
@@ -6453,7 +6560,7 @@ var main = () => {
|
|
|
6453
6560
|
emit({ kind: "invalid-assignments", errors: assignmentResult.errors }, 1);
|
|
6454
6561
|
return;
|
|
6455
6562
|
}
|
|
6456
|
-
const projectRoot =
|
|
6563
|
+
const projectRoot = path6.dirname(path6.dirname(resolved.strikethrooRoot));
|
|
6457
6564
|
const selection = selectTargets(config, assignmentResult.assignments, {
|
|
6458
6565
|
planId: resolved.planId,
|
|
6459
6566
|
projectRoot
|
|
@@ -6481,7 +6588,7 @@ var main = () => {
|
|
|
6481
6588
|
emit(
|
|
6482
6589
|
{
|
|
6483
6590
|
kind: "routing-failure",
|
|
6484
|
-
detail: `task ${task.id} (${
|
|
6591
|
+
detail: `task ${task.id} (${path6.basename(task.file)}): ${error instanceof Error ? error.message : String(error)}`
|
|
6485
6592
|
},
|
|
6486
6593
|
1
|
|
6487
6594
|
);
|
|
@@ -6503,11 +6610,11 @@ var main = () => {
|
|
|
6503
6610
|
const written = [];
|
|
6504
6611
|
try {
|
|
6505
6612
|
for (const { task, next } of staged) {
|
|
6506
|
-
|
|
6613
|
+
fs6.writeFileSync(task.file, next);
|
|
6507
6614
|
written.push(task);
|
|
6508
6615
|
}
|
|
6509
6616
|
for (const { task, execution } of staged) {
|
|
6510
|
-
const reread =
|
|
6617
|
+
const reread = fs6.readFileSync(task.file, "utf8");
|
|
6511
6618
|
const policy = readTaskExecutionPolicy(reread, policyContext);
|
|
6512
6619
|
if (!policyMatchesExecution(policy, execution)) {
|
|
6513
6620
|
throw new Error(`task ${task.id} failed post-write verification.`);
|
|
@@ -6516,7 +6623,7 @@ var main = () => {
|
|
|
6516
6623
|
} catch (error) {
|
|
6517
6624
|
for (const task of written) {
|
|
6518
6625
|
try {
|
|
6519
|
-
|
|
6626
|
+
fs6.writeFileSync(task.file, task.content);
|
|
6520
6627
|
} catch {
|
|
6521
6628
|
}
|
|
6522
6629
|
}
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
# execution_routing — automatic task execution routing during task
|
|
11
11
|
# generation. Profiles are arbitrary, project-defined routing categories;
|
|
12
12
|
# each `description` tells the task-generation LLM when the profile
|
|
13
|
-
# applies, and `models` is
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# (
|
|
18
|
-
#
|
|
13
|
+
# applies, and `models` is a list of exact execution targets (`model`
|
|
14
|
+
# required; `harness` and `reasoning_effort` optional; values are copied
|
|
15
|
+
# verbatim — no aliases, defaults, or translation). By default one target
|
|
16
|
+
# is chosen at random from those whose harness is available on this machine
|
|
17
|
+
# (a target with no `harness` is native and always available); one optional
|
|
18
|
+
# global `resolver.script` (repository-relative) can override that choice.
|
|
19
|
+
# Routing is disabled while `profiles` is empty. See the customization
|
|
20
|
+
# guide for the full
|
|
19
21
|
# contract and an illustrative example:
|
|
20
22
|
# https://strikethroo.canpicasoft.com/customization.html
|
|
21
23
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-B9tzk4XH.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-cGYMQHSz.js";import{b as i}from"./mermaid.core-B9tzk4XH.js";import"./chunk-FMBD7UC4-x3hzV0ms.js";import"./chunk-ND2GUHAM-B2mXRbNo.js";import"./chunk-55IACEB6-Cw5bYv7_.js";import"./chunk-2J33WTMH-CLmshK_w.js";import"./index-CGjoHidG.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-cGYMQHSz.js";import{b as i}from"./mermaid.core-B9tzk4XH.js";import"./chunk-FMBD7UC4-x3hzV0ms.js";import"./chunk-ND2GUHAM-B2mXRbNo.js";import"./chunk-55IACEB6-Cw5bYv7_.js";import"./chunk-2J33WTMH-CLmshK_w.js";import"./index-CGjoHidG.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as e,a as r,s as a,S as s}from"./chunk-AQP2D5EJ-CQjDykhJ.js";import{b as i}from"./mermaid.core-B9tzk4XH.js";import"./chunk-55IACEB6-Cw5bYv7_.js";import"./chunk-2J33WTMH-CLmshK_w.js";import"./index-CGjoHidG.js";var u={parser:a,get db(){return new s(2)},renderer:r,styles:e,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{u as diagram};
|