tarsk 0.5.65 → 0.5.67

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.
Files changed (135) hide show
  1. package/dist/bundled-skills/skill-creator/eval-viewer/generate_review.js +41 -40
  2. package/dist/bundled-skills/skill-creator/scripts/aggregate_benchmark.js +106 -98
  3. package/dist/bundled-skills/skill-creator/scripts/generate_report.js +78 -67
  4. package/dist/bundled-skills/skill-creator/scripts/improve_description.js +119 -72
  5. package/dist/bundled-skills/skill-creator/scripts/run_eval.js +76 -54
  6. package/dist/bundled-skills/skill-creator/scripts/run_loop.js +221 -142
  7. package/dist/index.js +51645 -47173
  8. package/dist/public/assets/{account-view-Dp0PfqVq.js → account-view-BlK6g38q.js} +1 -1
  9. package/dist/public/assets/{alert-dialog-Ge-FFGao.js → alert-dialog-B6An1LDY.js} +1 -1
  10. package/dist/public/assets/{async-error-boundary-B0tQed36.js → async-error-boundary-Rf-s2_Ez.js} +1 -1
  11. package/dist/public/assets/browser-tab-BJxPUVJi.js +12 -0
  12. package/dist/public/assets/{card-xQfAy2Rx.js → card-BDQUHsPD.js} +1 -1
  13. package/dist/public/assets/chat-dock-context-DyKjqpND.js +1 -0
  14. package/dist/public/assets/commit-dialog-CYb1kJCq.js +1 -0
  15. package/dist/public/assets/commit-error-dialog-DvxaNRcH.js +1 -0
  16. package/dist/public/assets/commit-method-fields-Dijc502F.js +1 -0
  17. package/dist/public/assets/context-menu-C51M1WGZ.js +1 -0
  18. package/dist/public/assets/conversation-history-view-w_6Jd3d-.js +1 -0
  19. package/dist/public/assets/create-project-dialog-CSVkngnF.js +6 -0
  20. package/dist/public/assets/create-repo-dialog-CcFA8pXz.js +1 -0
  21. package/dist/public/assets/{delete-confirm-dialog-Dy0dOtPe.js → delete-confirm-dialog-uTSX_x-i.js} +1 -1
  22. package/dist/public/assets/diff-view-XN5G5F6E.js +4 -0
  23. package/dist/public/assets/dist-IeRYu0zQ.js +142 -0
  24. package/dist/public/assets/{explorer-tab-context-8bs_tiCO.js → explorer-tab-context-BdjTEbFh.js} +1 -1
  25. package/dist/public/assets/explorer-tab-view-A2ICDFPB.js +2 -0
  26. package/dist/public/assets/explorer-tree-B04Ba59E.js +1 -0
  27. package/dist/public/assets/explorer-view-CofaKFiu.js +75 -0
  28. package/dist/public/assets/git-history-dialog-V3kaff2G.js +1 -0
  29. package/dist/public/assets/index-B0xy4BkI.js +3360 -0
  30. package/dist/public/assets/index-Cndc50ux.css +1 -0
  31. package/dist/public/assets/interactive-BrHVRHmQ.js +21 -0
  32. package/dist/public/assets/{main-tab-context-DHeKIUsf.js → main-tab-context-zQSuRQQG.js} +1 -1
  33. package/dist/public/assets/mcp-server-card-DOsP-SQ8.js +1 -0
  34. package/dist/public/assets/merged-pr-dialog-BerRzLlh.js +1 -0
  35. package/dist/public/assets/model-list-controls-Dw98tMn7.js +1 -0
  36. package/dist/public/assets/{monaco-setup-x3evbdq3.js → monaco-setup-C87kBr4u.js} +1 -1
  37. package/dist/public/assets/onboarding-DVc9-yKJ.js +46 -0
  38. package/dist/public/assets/project-env-vars-view-BQwUd7y6.js +1 -0
  39. package/dist/public/assets/project-model-aliases-view-CobSp09z.js +1 -0
  40. package/dist/public/assets/project-settings-view-CPTd5lEi.js +1 -0
  41. package/dist/public/assets/{project-tools-view-C44y08lY.js → project-tools-view-DShQghoz.js} +1 -1
  42. package/dist/public/assets/providers-list-view-Da9VMcuP.js +1 -0
  43. package/dist/public/assets/pull-request-dialog-BAarT9EM.js +1 -0
  44. package/dist/public/assets/pull-with-changes-dialog-BcF25mjQ.js +1 -0
  45. package/dist/public/assets/push-before-pr-dialog-BF0NzV2u.js +1 -0
  46. package/dist/public/assets/react-vendor-B7jFrulV.js +22 -0
  47. package/dist/public/assets/settings-general-view-DT4nElcL.js +1 -0
  48. package/dist/public/assets/settings-instructions-view-Bsr8wRMf.js +1 -0
  49. package/dist/public/assets/settings-list-B9wyVzKw.js +1 -0
  50. package/dist/public/assets/settings-logs-view-CyaGqUKH.js +5 -0
  51. package/dist/public/assets/settings-mcp-servers-view-BTUWHB5K.js +5 -0
  52. package/dist/public/assets/settings-models-view-DFwkVdt3.js +1 -0
  53. package/dist/public/assets/settings-rules-view-BhA9tjVh.js +8 -0
  54. package/dist/public/assets/settings-skills-view-BFoO9oZk.js +3 -0
  55. package/dist/public/assets/{settings-slack-view-OFUhhjTj.js → settings-slack-view-D4mrQ9C9.js} +1 -1
  56. package/dist/public/assets/settings-slash-commands-view-BLKPDUVG.js +1 -0
  57. package/dist/public/assets/settings-statistics-view-fa6iBiP8.js +1 -0
  58. package/dist/public/assets/settings-storage-view-LaiAi5gv.js +1 -0
  59. package/dist/public/assets/settings-subagents-view-BjMz2Ri_.js +2 -0
  60. package/dist/public/assets/settings-system-prompt-view-DNh1yqZh.js +1 -0
  61. package/dist/public/assets/settings-view-BoC66Wji.js +2 -0
  62. package/dist/public/assets/skeleton-CJSNEi3C.js +1 -0
  63. package/dist/public/assets/store-B_cK-gsT.js +8 -0
  64. package/dist/public/assets/{table-CYWF-RhQ.js → table-Cb2C1rQy.js} +1 -1
  65. package/dist/public/assets/tasks-view-B049aXpC.js +2 -0
  66. package/dist/public/assets/{terminal-panel-BxUHr-tZ.js → terminal-panel-Pv5xqCpm.js} +3 -3
  67. package/dist/public/assets/thread-tool-blocks-D9HUkPHB.js +1 -0
  68. package/dist/public/assets/{ui-components-DjoQfi8k.js → ui-components-DJLsrr5e.js} +1 -1
  69. package/dist/public/assets/{use-active-dock-panel-instance-BE69kVdb.js → use-active-dock-panel-instance-BlRDPUlZ.js} +1 -1
  70. package/dist/public/assets/{use-deferred-search-DXrcdbyC.js → use-deferred-search-0sV7mSzX.js} +1 -1
  71. package/dist/public/assets/use-installed-ai-files-DmLnugpj.js +1 -0
  72. package/dist/public/assets/{use-settings-page-loading-BC_wP7pl.js → use-settings-page-loading-BU2CDnfE.js} +1 -1
  73. package/dist/public/assets/{use-suspense-resource-rX-GqyWi.js → use-suspense-resource-CExc4Svq.js} +1 -1
  74. package/dist/public/assets/{use-toast-BFQ85Ly5.js → use-toast-hxHsVv6a.js} +1 -1
  75. package/dist/public/assets/{utils-Rlf65JHq.js → utils-SsF94Pkg.js} +1 -1
  76. package/dist/public/assets/{web-Q-tJsXNN.js → web-BidDZaMC.js} +1 -1
  77. package/dist/public/assets/{web-D8z4Nni0.js → web-C_HuLxHj.js} +1 -1
  78. package/dist/public/assets/{web-CxBqU2BU.js → web-DHUv7oQP.js} +1 -1
  79. package/dist/public/assets/{web-DTwF_7w-.js → web-JMCxQg4N.js} +1 -1
  80. package/dist/public/browser-preview-rpc.js +465 -7
  81. package/dist/public/index.html +14 -16
  82. package/dist/recommended-models.txt +5 -5
  83. package/package.json +1 -14
  84. package/dist/public/assets/api-BsPadLpi.js +0 -1
  85. package/dist/public/assets/browser-tab-hcbTzpVn.js +0 -8
  86. package/dist/public/assets/chat-dock-context-yQDhSXnw.js +0 -1
  87. package/dist/public/assets/commit-dialog-DK-NP7EN.js +0 -1
  88. package/dist/public/assets/commit-method-fields-DG3NtLE2.js +0 -1
  89. package/dist/public/assets/context-menu-M5y1Qb8G.js +0 -1
  90. package/dist/public/assets/conversation-history-view-YGPt-fC9.js +0 -1
  91. package/dist/public/assets/create-project-dialog-DW4oGrl2.js +0 -6
  92. package/dist/public/assets/create-repo-dialog-BFBOFZ2W.js +0 -1
  93. package/dist/public/assets/diff-view-Cy5PjlG_.js +0 -4
  94. package/dist/public/assets/dist-oojFghRi.js +0 -134
  95. package/dist/public/assets/explorer-tab-view-D6t9Ce05.js +0 -2
  96. package/dist/public/assets/explorer-tree-BCs2U0De.js +0 -1
  97. package/dist/public/assets/explorer-view-CxN4GRyn.js +0 -75
  98. package/dist/public/assets/git-history-dialog-fm9qhkgI.js +0 -1
  99. package/dist/public/assets/git-ops-button-DO1ng45p.js +0 -2
  100. package/dist/public/assets/index-B7qJtiRL.js +0 -3307
  101. package/dist/public/assets/index-GYexJ6QO.css +0 -1
  102. package/dist/public/assets/interactive-WtOIgeV4.js +0 -21
  103. package/dist/public/assets/local-tool-blocks-DlqmJ7__.js +0 -1
  104. package/dist/public/assets/mcp-server-card-V4Ddsgv3.js +0 -1
  105. package/dist/public/assets/merged-pr-dialog-Bi5pJzTO.js +0 -1
  106. package/dist/public/assets/model-list-controls-oiBE9X9_.js +0 -1
  107. package/dist/public/assets/onboarding-dbhmRuxw.js +0 -46
  108. package/dist/public/assets/project-env-vars-view-OVck-YEy.js +0 -1
  109. package/dist/public/assets/project-model-aliases-view-Cu-n2j94.js +0 -1
  110. package/dist/public/assets/project-settings-view-DKkLgg3C.js +0 -1
  111. package/dist/public/assets/providers-list-view-BEXiqKg8.js +0 -1
  112. package/dist/public/assets/pull-request-dialog-BOl1VloY.js +0 -1
  113. package/dist/public/assets/pull-with-changes-dialog-CJKvLUaf.js +0 -1
  114. package/dist/public/assets/push-before-pr-dialog-BZLScOoO.js +0 -1
  115. package/dist/public/assets/react-vendor-wGLyNWf9.js +0 -22
  116. package/dist/public/assets/settings-general-view-LnCQ2zkv.js +0 -1
  117. package/dist/public/assets/settings-instructions-view-B7lADJZh.js +0 -1
  118. package/dist/public/assets/settings-list-C5MACtux.js +0 -1
  119. package/dist/public/assets/settings-logs-view-YWMyQqu5.js +0 -5
  120. package/dist/public/assets/settings-mcp-servers-view-CN7JO2UD.js +0 -5
  121. package/dist/public/assets/settings-models-view-CswWfeDN.js +0 -1
  122. package/dist/public/assets/settings-rules-view-__5f33ot.js +0 -8
  123. package/dist/public/assets/settings-skills-view-Dvfrl9kz.js +0 -3
  124. package/dist/public/assets/settings-slash-commands-view-B1pO-Yie.js +0 -1
  125. package/dist/public/assets/settings-statistics-view-Bp624KXI.js +0 -1
  126. package/dist/public/assets/settings-storage-view-CHpGieRu.js +0 -1
  127. package/dist/public/assets/settings-subagents-view-CFggo62r.js +0 -2
  128. package/dist/public/assets/settings-system-prompt-view-BWD6RrX8.js +0 -1
  129. package/dist/public/assets/settings-view-ZgVxZhur.js +0 -2
  130. package/dist/public/assets/skeleton-B_xdlo2b.js +0 -1
  131. package/dist/public/assets/slug-utils-C5rnmMMP.js +0 -1
  132. package/dist/public/assets/store-CSyJjyNs.js +0 -7
  133. package/dist/public/assets/tasks-view-4yyCDYbV.js +0 -2
  134. package/dist/public/assets/thread-tool-blocks-BfowiaTH.js +0 -1
  135. package/dist/public/assets/use-installed-ai-files-CZIOFhcX.js +0 -1
@@ -32,28 +32,82 @@ function callTarsk(prompt, model, timeoutMs = 300000) {
32
32
  return result.stdout;
33
33
  }
34
34
 
35
- function improveDescription(
35
+ function parseDescription(text) {
36
+ const match = text.match(/<new_description>([\s\S]*?)<\/new_description>/);
37
+ return match
38
+ ? match[1].trim().replace(/^["']|["']$/g, "")
39
+ : text.trim().replace(/^["']|["']$/g, "");
40
+ }
41
+
42
+ function computeScoresSummary(evalResults, testResults) {
43
+ const trainScore = `${evalResults.summary.passed}/${evalResults.summary.total}`;
44
+ if (testResults) {
45
+ return `Train: ${trainScore}, Test: ${testResults.summary.passed}/${testResults.summary.total}`;
46
+ }
47
+ return `Train: ${trainScore}`;
48
+ }
49
+
50
+ function buildFailuresText(evalResults) {
51
+ const failedTriggers = evalResults.results.filter((r) => r.should_trigger && !r.pass);
52
+ const falseTriggers = evalResults.results.filter((r) => !r.should_trigger && !r.pass);
53
+
54
+ let text = "";
55
+ if (failedTriggers.length) {
56
+ text += "FAILED TO TRIGGER (should have triggered but didn't):\n";
57
+ for (const r of failedTriggers) {
58
+ text += ` - "${r.query}" (triggered ${r.triggers}/${r.runs} times)\n`;
59
+ }
60
+ text += "\n";
61
+ }
62
+
63
+ if (falseTriggers.length) {
64
+ text += "FALSE TRIGGERS (triggered but shouldn't have):\n";
65
+ for (const r of falseTriggers) {
66
+ text += ` - "${r.query}" (triggered ${r.triggers}/${r.runs} times)\n`;
67
+ }
68
+ text += "\n";
69
+ }
70
+
71
+ return text;
72
+ }
73
+
74
+ function buildHistoryText(history) {
75
+ if (!history.length) {
76
+ return "";
77
+ }
78
+
79
+ let text = "PREVIOUS ATTEMPTS (do NOT repeat these — try something structurally different):\n\n";
80
+ for (const h of history) {
81
+ const trainS = `${h.train_passed ?? h.passed ?? 0}/${h.train_total ?? h.total ?? 0}`;
82
+ const testS = h.test_passed != null ? `${h.test_passed}/${h.test_total ?? "?"}` : null;
83
+ const scoreStr = `train=${trainS}` + (testS ? `, test=${testS}` : "");
84
+ text += `<attempt ${scoreStr}>\n`;
85
+ text += `Description: "${h.description}"\n`;
86
+ if (h.results) {
87
+ text += "Train results:\n";
88
+ for (const r of h.results) {
89
+ const status = r.pass ? "PASS" : "FAIL";
90
+ text += ` [${status}] "${r.query.slice(0, 80)}" (triggered ${r.triggers}/${r.runs})\n`;
91
+ }
92
+ }
93
+ if (h.note) {
94
+ text += `Note: ${h.note}\n`;
95
+ }
96
+ text += "</attempt>\n\n";
97
+ }
98
+
99
+ return text;
100
+ }
101
+
102
+ function buildImprovePrompt(
36
103
  skillName,
37
104
  skillContent,
38
105
  currentDescription,
39
106
  evalResults,
40
107
  history,
41
- model,
42
- testResults = null,
43
- logDir = null,
44
- iteration = null,
108
+ testResults,
45
109
  ) {
46
- const failedTriggers = evalResults.results.filter((r) => r.should_trigger && !r.pass);
47
- const falseTriggers = evalResults.results.filter((r) => !r.should_trigger && !r.pass);
48
-
49
- const trainScore = `${evalResults.summary.passed}/${evalResults.summary.total}`;
50
- let scoresSummary;
51
- if (testResults) {
52
- const testScore = `${testResults.summary.passed}/${testResults.summary.total}`;
53
- scoresSummary = `Train: ${trainScore}, Test: ${testScore}`;
54
- } else {
55
- scoresSummary = `Train: ${trainScore}`;
56
- }
110
+ const scoresSummary = computeScoresSummary(evalResults, testResults);
57
111
 
58
112
  let prompt = `You are optimizing a skill description for a Tarsk Code skill called "${skillName}". A "skill" is sort of like a prompt, but with progressive disclosure -- there's a title and description that Tarsk sees when deciding whether to use the skill, and then if it does use the skill, it reads the .md file which has lots more details and potentially links to other resources in the skill folder like helper files and scripts and additional documentation or examples.
59
113
 
@@ -68,43 +122,8 @@ Current scores (${scoresSummary}):
68
122
  <scores_summary>
69
123
  `;
70
124
 
71
- if (failedTriggers.length) {
72
- prompt += "FAILED TO TRIGGER (should have triggered but didn't):\n";
73
- for (const r of failedTriggers) {
74
- prompt += ` - "${r.query}" (triggered ${r.triggers}/${r.runs} times)\n`;
75
- }
76
- prompt += "\n";
77
- }
78
-
79
- if (falseTriggers.length) {
80
- prompt += "FALSE TRIGGERS (triggered but shouldn't have):\n";
81
- for (const r of falseTriggers) {
82
- prompt += ` - "${r.query}" (triggered ${r.triggers}/${r.runs} times)\n`;
83
- }
84
- prompt += "\n";
85
- }
86
-
87
- if (history.length) {
88
- prompt += "PREVIOUS ATTEMPTS (do NOT repeat these — try something structurally different):\n\n";
89
- for (const h of history) {
90
- const trainS = `${h.train_passed ?? h.passed ?? 0}/${h.train_total ?? h.total ?? 0}`;
91
- const testS = h.test_passed != null ? `${h.test_passed}/${h.test_total ?? "?"}` : null;
92
- const scoreStr = `train=${trainS}` + (testS ? `, test=${testS}` : "");
93
- prompt += `<attempt ${scoreStr}>\n`;
94
- prompt += `Description: "${h.description}"\n`;
95
- if (h.results) {
96
- prompt += "Train results:\n";
97
- for (const r of h.results) {
98
- const status = r.pass ? "PASS" : "FAIL";
99
- prompt += ` [${status}] "${r.query.slice(0, 80)}" (triggered ${r.triggers}/${r.runs})\n`;
100
- }
101
- }
102
- if (h.note) {
103
- prompt += `Note: ${h.note}\n`;
104
- }
105
- prompt += "</attempt>\n\n";
106
- }
107
- }
125
+ prompt += buildFailuresText(evalResults);
126
+ prompt += buildHistoryText(history);
108
127
 
109
128
  prompt += `</scores_summary>
110
129
 
@@ -130,11 +149,49 @@ I'd encourage you to be creative and mix up the style in different iterations si
130
149
 
131
150
  Please respond with only the new description text in <new_description> tags, nothing else.`;
132
151
 
152
+ return prompt;
153
+ }
154
+
155
+ function shortenDescription(prompt, description, model) {
156
+ const shortenPrompt =
157
+ `${prompt}\n\n` +
158
+ `---\n\n` +
159
+ `A previous attempt produced this description, which at ` +
160
+ `${description.length} characters is over the 1024-character hard limit:\n\n` +
161
+ `"${description}"\n\n` +
162
+ `Rewrite it to be under 1024 characters while keeping the most ` +
163
+ `important trigger words and intent coverage. Respond with only ` +
164
+ `the new description in <new_description> tags.`;
165
+ const shortenText = callTarsk(shortenPrompt, model);
166
+ return {
167
+ shortenPrompt,
168
+ shortenText,
169
+ shortened: parseDescription(shortenText),
170
+ };
171
+ }
172
+
173
+ function improveDescription(
174
+ skillName,
175
+ skillContent,
176
+ currentDescription,
177
+ evalResults,
178
+ history,
179
+ model,
180
+ testResults = null,
181
+ logDir = null,
182
+ iteration = null,
183
+ ) {
184
+ const prompt = buildImprovePrompt(
185
+ skillName,
186
+ skillContent,
187
+ currentDescription,
188
+ evalResults,
189
+ history,
190
+ testResults,
191
+ );
192
+
133
193
  let text = callTarsk(prompt, model);
134
- let match = text.match(/<new_description>([\s\S]*?)<\/new_description>/);
135
- let description = match
136
- ? match[1].trim().replace(/^["']|["']$/g, "")
137
- : text.trim().replace(/^["']|["']$/g, "");
194
+ let description = parseDescription(text);
138
195
 
139
196
  const transcript = {
140
197
  iteration,
@@ -146,21 +203,11 @@ Please respond with only the new description text in <new_description> tags, not
146
203
  };
147
204
 
148
205
  if (description.length > 1024) {
149
- const shortenPrompt =
150
- `${prompt}\n\n` +
151
- `---\n\n` +
152
- `A previous attempt produced this description, which at ` +
153
- `${description.length} characters is over the 1024-character hard limit:\n\n` +
154
- `"${description}"\n\n` +
155
- `Rewrite it to be under 1024 characters while keeping the most ` +
156
- `important trigger words and intent coverage. Respond with only ` +
157
- `the new description in <new_description> tags.`;
158
- const shortenText = callTarsk(shortenPrompt, model);
159
- match = shortenText.match(/<new_description>([\s\S]*?)<\/new_description>/);
160
- const shortened = match
161
- ? match[1].trim().replace(/^["']|["']$/g, "")
162
- : shortenText.trim().replace(/^["']|["']$/g, "");
163
-
206
+ const { shortenPrompt, shortenText, shortened } = shortenDescription(
207
+ prompt,
208
+ description,
209
+ model,
210
+ );
164
211
  transcript.rewrite_prompt = shortenPrompt;
165
212
  transcript.rewrite_response = shortenText;
166
213
  transcript.rewrite_description = shortened;
@@ -29,6 +29,72 @@ function buildEnv() {
29
29
  return env;
30
30
  }
31
31
 
32
+ function handleStreamEventType(se, seType, state) {
33
+ if (seType === "content_block_start") {
34
+ const cb = se.content_block ?? {};
35
+ if (cb.type === "tool_use") {
36
+ const toolName = cb.name ?? "";
37
+ if (toolName === "Skill" || toolName === "Read") {
38
+ state.pendingToolName = toolName;
39
+ state.accumulatedJson = "";
40
+ } else {
41
+ state.finish(false);
42
+ return true;
43
+ }
44
+ }
45
+ } else if (seType === "content_block_delta" && state.pendingToolName) {
46
+ const delta = se.delta ?? {};
47
+ if (delta.type === "input_json_delta") {
48
+ state.accumulatedJson += delta.partial_json ?? "";
49
+ if (state.accumulatedJson.includes(state.cleanName)) {
50
+ state.finish(true);
51
+ return true;
52
+ }
53
+ }
54
+ } else if (seType === "content_block_stop" || seType === "message_stop") {
55
+ if (state.pendingToolName) {
56
+ state.finish(state.accumulatedJson.includes(state.cleanName));
57
+ return true;
58
+ }
59
+ if (seType === "message_stop") {
60
+ state.finish(false);
61
+ return true;
62
+ }
63
+ }
64
+ return false;
65
+ }
66
+
67
+ function handleAssistantEvent(message, state) {
68
+ for (const contentItem of message.content ?? []) {
69
+ if (contentItem.type !== "tool_use") continue;
70
+ const toolName = contentItem.name ?? "";
71
+ const toolInput = contentItem.input ?? {};
72
+ if (toolName === "Skill" && (toolInput.skill ?? "").includes(state.cleanName)) {
73
+ state.triggered = true;
74
+ } else if (toolName === "Read" && (toolInput.file_path ?? "").includes(state.cleanName)) {
75
+ state.triggered = true;
76
+ }
77
+ state.finish(state.triggered);
78
+ return true;
79
+ }
80
+ return false;
81
+ }
82
+
83
+ function handleStreamEvent(event, state) {
84
+ if (event.type === "stream_event") {
85
+ const se = event.event ?? {};
86
+ return handleStreamEventType(se, se.type ?? "", state);
87
+ }
88
+ if (event.type === "assistant") {
89
+ return handleAssistantEvent(event.message ?? {}, state);
90
+ }
91
+ if (event.type === "result") {
92
+ state.finish(state.triggered);
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+
32
98
  function runSingleQuery(query, skillName, skillDescription, timeoutSec, projectRoot, model = null) {
33
99
  return new Promise((resolve) => {
34
100
  const uniqueId = crypto.randomBytes(4).toString("hex").slice(0, 8);
@@ -79,6 +145,14 @@ function runSingleQuery(query, skillName, skillDescription, timeoutSec, projectR
79
145
  let accumulatedJson = "";
80
146
  let finished = false;
81
147
 
148
+ const state = {
149
+ cleanName,
150
+ pendingToolName,
151
+ accumulatedJson,
152
+ triggered,
153
+ finish,
154
+ };
155
+
82
156
  function finish(value) {
83
157
  if (finished) return;
84
158
  finished = true;
@@ -108,59 +182,7 @@ function runSingleQuery(query, skillName, skillDescription, timeoutSec, projectR
108
182
  continue;
109
183
  }
110
184
 
111
- if (event.type === "stream_event") {
112
- const se = event.event ?? {};
113
- const seType = se.type ?? "";
114
-
115
- if (seType === "content_block_start") {
116
- const cb = se.content_block ?? {};
117
- if (cb.type === "tool_use") {
118
- const toolName = cb.name ?? "";
119
- if (toolName === "Skill" || toolName === "Read") {
120
- pendingToolName = toolName;
121
- accumulatedJson = "";
122
- } else {
123
- finish(false);
124
- return;
125
- }
126
- }
127
- } else if (seType === "content_block_delta" && pendingToolName) {
128
- const delta = se.delta ?? {};
129
- if (delta.type === "input_json_delta") {
130
- accumulatedJson += delta.partial_json ?? "";
131
- if (accumulatedJson.includes(cleanName)) {
132
- finish(true);
133
- return;
134
- }
135
- }
136
- } else if (seType === "content_block_stop" || seType === "message_stop") {
137
- if (pendingToolName) {
138
- finish(accumulatedJson.includes(cleanName));
139
- return;
140
- }
141
- if (seType === "message_stop") {
142
- finish(false);
143
- return;
144
- }
145
- }
146
- } else if (event.type === "assistant") {
147
- const message = event.message ?? {};
148
- for (const contentItem of message.content ?? []) {
149
- if (contentItem.type !== "tool_use") continue;
150
- const toolName = contentItem.name ?? "";
151
- const toolInput = contentItem.input ?? {};
152
- if (toolName === "Skill" && (toolInput.skill ?? "").includes(cleanName)) {
153
- triggered = true;
154
- } else if (toolName === "Read" && (toolInput.file_path ?? "").includes(cleanName)) {
155
- triggered = true;
156
- }
157
- finish(triggered);
158
- return;
159
- }
160
- } else if (event.type === "result") {
161
- finish(triggered);
162
- return;
163
- }
185
+ if (handleStreamEvent(event, state)) return;
164
186
  }
165
187
  });
166
188
 
@@ -342,4 +364,4 @@ if (require.main === module) {
342
364
  });
343
365
  }
344
366
 
345
- module.exports = { findProjectRoot, runEval, runSingleQuery };
367
+ module.exports = { findProjectRoot, runEval };