@wrongstack/tools 1.0.6 → 1.0.7
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/audit.js +4 -4
- package/dist/bash.js +2 -2
- package/dist/builtin.js +39 -39
- package/dist/{chunk-HKR56VNF.js → chunk-2IAEJRLT.js} +4 -3
- package/dist/{chunk-5UA4TNJJ.js → chunk-2NTHMZV3.js} +2 -2
- package/dist/{chunk-ZSW5KO5S.js → chunk-2W4XTULI.js} +2 -2
- package/dist/{chunk-JQ43NVFU.js → chunk-3LQJXJDM.js} +2 -2
- package/dist/{chunk-OVFQC6FU.js → chunk-4DK5WZGR.js} +341 -146
- package/dist/{chunk-47GYABZW.js → chunk-4SW6BXUR.js} +2 -2
- package/dist/{chunk-7EQ2LUXU.js → chunk-5MP76C72.js} +3 -3
- package/dist/{chunk-7PEZU5Y4.js → chunk-7E55DAFW.js} +8 -8
- package/dist/{chunk-YILT3CSO.js → chunk-A3LNNBYO.js} +14 -5
- package/dist/{chunk-D4HWMWGE.js → chunk-AH7J5HWL.js} +3 -3
- package/dist/{chunk-OZVGRDCM.js → chunk-B62LKMWQ.js} +3 -3
- package/dist/{chunk-WKXL5XHU.js → chunk-BVHKBBGA.js} +2 -2
- package/dist/{chunk-54SIRJ6D.js → chunk-C4DSQBTT.js} +3 -3
- package/dist/{chunk-2ZWQIVEW.js → chunk-CAF4L6KN.js} +2 -2
- package/dist/{chunk-4KI4HHID.js → chunk-CLJXKFVS.js} +2 -2
- package/dist/{chunk-MG7CUN6R.js → chunk-EGT5QLCB.js} +6 -3
- package/dist/{chunk-TL5T4A4E.js → chunk-GF4JHLCO.js} +3 -3
- package/dist/{chunk-ZETZHHV5.js → chunk-H2VB7GCR.js} +3 -3
- package/dist/{chunk-C64UUXTA.js → chunk-HCPSVK7J.js} +3 -3
- package/dist/{chunk-K7Y2IWEB.js → chunk-HIRVCXLP.js} +4 -4
- package/dist/{chunk-CYPYJIAF.js → chunk-JB5JLY7V.js} +4 -4
- package/dist/{chunk-IMIHTHF7.js → chunk-JKFIDWQG.js} +2 -2
- package/dist/{chunk-S6E2AM4U.js → chunk-KF7GMVNU.js} +3 -3
- package/dist/{chunk-IOOFLBVM.js → chunk-KMXPP32M.js} +3 -3
- package/dist/{chunk-6ZRP5IKQ.js → chunk-KPR53VKZ.js} +2 -2
- package/dist/{chunk-REWOZIA4.js → chunk-M2W36JT7.js} +2 -2
- package/dist/{chunk-BU6VUXWG.js → chunk-N3OTTQNC.js} +2 -2
- package/dist/{chunk-YJQQ5F5J.js → chunk-NL45OWEO.js} +3 -3
- package/dist/{chunk-NKOTOW6X.js → chunk-O6AGFJBO.js} +3 -3
- package/dist/{chunk-OBVXDVLE.js → chunk-QJARSK2G.js} +3 -3
- package/dist/{chunk-R36RWYXE.js → chunk-R3HIZVFS.js} +3 -3
- package/dist/{chunk-TGVQMKVH.js → chunk-S6CGSFLX.js} +3 -3
- package/dist/{chunk-JK5WXW4S.js → chunk-SEONDNLN.js} +2 -2
- package/dist/{chunk-6IEBD27U.js → chunk-SKRMUHTU.js} +2 -2
- package/dist/{chunk-DOHU3XHS.js → chunk-TU6UVATU.js} +3 -3
- package/dist/{chunk-G35NLPG5.js → chunk-WKLUOXR4.js} +3 -3
- package/dist/{chunk-FRIUJ534.js → chunk-YPSIG23D.js} +3 -3
- package/dist/{chunk-5BKQVP56.js → chunk-YZECCW3F.js} +34 -14
- package/dist/{chunk-3F7HQ3KS.js → chunk-YZQSUL5G.js} +2 -2
- package/dist/{chunk-2IC5FRD7.js → chunk-ZMCV3XOV.js} +2 -2
- package/dist/{chunk-WBAPU3AB.js → chunk-ZOUG3KKS.js} +2 -2
- package/dist/clarify.d.ts +26 -19
- package/dist/codebase-index/index.js +8 -8
- package/dist/codebase-index/parser-worker-script.js +3 -3
- package/dist/codebase-index/project-server.js +5 -5
- package/dist/codebase-index/worker.js +4 -4
- package/dist/diff.js +2 -2
- package/dist/e2e.js +2 -2
- package/dist/edit.js +8 -8
- package/dist/exec.js +2 -2
- package/dist/fetch.js +2 -2
- package/dist/format.js +4 -4
- package/dist/{generic-parser-WFMIRHBX.js → generic-parser-N2PLGBC2.js} +2 -2
- package/dist/git.js +2 -2
- package/dist/glob.js +2 -2
- package/dist/{go-parser-EMKTAAD3.js → go-parser-VDPRQEGM.js} +5 -5
- package/dist/grep.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +41 -41
- package/dist/install.js +4 -4
- package/dist/{json-parser-34DHYCPW.js → json-parser-IJD77VL4.js} +11 -17
- package/dist/json.js +2 -2
- package/dist/kanban.js +2 -2
- package/dist/languages/index.js +2 -2
- package/dist/{legacy-bridge-XM2GV665.js → legacy-bridge-4T4OTSQP.js} +4 -4
- package/dist/lint.js +4 -4
- package/dist/logs.js +2 -2
- package/dist/outdated.js +2 -2
- package/dist/pack.js +40 -40
- package/dist/{parser-dispatch-HZDZSIYH.js → parser-dispatch-4E2SDQUO.js} +4 -4
- package/dist/patch.js +8 -8
- package/dist/plan.js +4 -4
- package/dist/{py-parser-DDG53RXI.js → py-parser-MAW6DHFE.js} +3 -3
- package/dist/read.js +8 -8
- package/dist/replace.js +8 -8
- package/dist/session-kanban.d.ts +7 -0
- package/dist/session-kanban.js +3 -1
- package/dist/task.js +4 -4
- package/dist/test.js +4 -4
- package/dist/todo.js +3 -3
- package/dist/tool-tier.js +41 -41
- package/dist/tree.js +2 -2
- package/dist/typecheck.js +4 -4
- package/dist/write.js +8 -8
- package/dist/{yaml-parser-RGBXEZE4.js → yaml-parser-DFBC5FWH.js} +7 -6
- package/package.json +5 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
e2ePlanTool
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BVHKBBGA.js";
|
|
4
4
|
import {
|
|
5
5
|
codebaseAstReplaceTool,
|
|
6
6
|
codebaseContextTool,
|
|
@@ -15,31 +15,31 @@ import {
|
|
|
15
15
|
codebaseStatsTool,
|
|
16
16
|
codebaseTargetedTestTool,
|
|
17
17
|
deadCodeScanTool
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-JB5JLY7V.js";
|
|
19
19
|
import {
|
|
20
20
|
designTool
|
|
21
21
|
} from "./chunk-IXIS7RSG.js";
|
|
22
22
|
import {
|
|
23
23
|
planTool
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-O6AGFJBO.js";
|
|
25
25
|
import {
|
|
26
26
|
taskTool
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-B62LKMWQ.js";
|
|
28
28
|
import {
|
|
29
29
|
testTool
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-KF7GMVNU.js";
|
|
31
31
|
import {
|
|
32
32
|
installTool
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-H2VB7GCR.js";
|
|
34
34
|
import {
|
|
35
35
|
auditTool
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-HCPSVK7J.js";
|
|
37
37
|
import {
|
|
38
38
|
outdatedTool
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-NL45OWEO.js";
|
|
40
40
|
import {
|
|
41
41
|
logsTool
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-CAF4L6KN.js";
|
|
43
43
|
import {
|
|
44
44
|
toolSearchTool
|
|
45
45
|
} from "./chunk-YA2ZYCJY.js";
|
|
@@ -48,52 +48,52 @@ import {
|
|
|
48
48
|
} from "./chunk-B3MGJBFI.js";
|
|
49
49
|
import {
|
|
50
50
|
gitTool
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-ZMCV3XOV.js";
|
|
52
52
|
import {
|
|
53
53
|
patchTool
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-5MP76C72.js";
|
|
55
55
|
import {
|
|
56
56
|
jsonTool
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-EGT5QLCB.js";
|
|
58
58
|
import {
|
|
59
59
|
diffTool
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-N3OTTQNC.js";
|
|
61
61
|
import {
|
|
62
62
|
treeTool
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-YZQSUL5G.js";
|
|
64
64
|
import {
|
|
65
65
|
lintTool
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-R3HIZVFS.js";
|
|
67
67
|
import {
|
|
68
68
|
formatTool
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-QJARSK2G.js";
|
|
70
70
|
import {
|
|
71
71
|
typecheckTool
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-AH7J5HWL.js";
|
|
73
73
|
import {
|
|
74
74
|
languageInfoTool,
|
|
75
75
|
languagePackageTool,
|
|
76
76
|
languageTool
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-SEONDNLN.js";
|
|
78
78
|
import {
|
|
79
79
|
replaceTool
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-KMXPP32M.js";
|
|
81
81
|
import {
|
|
82
82
|
globTool
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-JKFIDWQG.js";
|
|
84
84
|
import {
|
|
85
85
|
grepTool
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-2W4XTULI.js";
|
|
87
87
|
import {
|
|
88
88
|
bashTool,
|
|
89
89
|
checkAndBlockKillCommand,
|
|
90
90
|
diagnoseBashism,
|
|
91
91
|
shellArgs
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-CLJXKFVS.js";
|
|
93
93
|
import {
|
|
94
94
|
detectDanger,
|
|
95
95
|
execTool
|
|
96
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-A3LNNBYO.js";
|
|
97
97
|
import {
|
|
98
98
|
buildChildEnv
|
|
99
99
|
} from "./chunk-BTSFTGIL.js";
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
} from "./chunk-HDYUBRMF.js";
|
|
108
108
|
import {
|
|
109
109
|
fetchTool
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-4SW6BXUR.js";
|
|
111
111
|
import {
|
|
112
112
|
searchTool
|
|
113
113
|
} from "./chunk-62OAECEQ.js";
|
|
@@ -116,22 +116,22 @@ import {
|
|
|
116
116
|
} from "./chunk-NBDZMMG2.js";
|
|
117
117
|
import {
|
|
118
118
|
todoTool
|
|
119
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-S6CGSFLX.js";
|
|
120
120
|
import {
|
|
121
121
|
kanbanTool
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-2NTHMZV3.js";
|
|
123
123
|
import {
|
|
124
124
|
browserTools
|
|
125
125
|
} from "./chunk-6XYFYLN7.js";
|
|
126
126
|
import {
|
|
127
127
|
readTool
|
|
128
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-HIRVCXLP.js";
|
|
129
129
|
import {
|
|
130
130
|
writeTool
|
|
131
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-GF4JHLCO.js";
|
|
132
132
|
import {
|
|
133
133
|
editTool
|
|
134
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-WKLUOXR4.js";
|
|
135
135
|
import {
|
|
136
136
|
resolvePowerShell
|
|
137
137
|
} from "./chunk-5U5ULQX2.js";
|
|
@@ -139,9 +139,10 @@ import {
|
|
|
139
139
|
normalizeCommandOutput,
|
|
140
140
|
safeResolveProjectPath,
|
|
141
141
|
safeResolveReal
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-2IAEJRLT.js";
|
|
143
143
|
|
|
144
144
|
// src/clarify.ts
|
|
145
|
+
import { randomUUID } from "node:crypto";
|
|
145
146
|
import { toErrorMessage } from "@wrongstack/core/utils";
|
|
146
147
|
var clarifyTool = {
|
|
147
148
|
name: "clarify",
|
|
@@ -149,62 +150,42 @@ var clarifyTool = {
|
|
|
149
150
|
icon: "meta",
|
|
150
151
|
permission: "auto",
|
|
151
152
|
mutating: false,
|
|
152
|
-
description: "
|
|
153
|
-
usageHint: '
|
|
153
|
+
description: "Pause and ask the user for required decisions in one structured, tabbed form. Supports single-select, multi-select, free text, option descriptions, write-ins, and explicitly recommended answers. Submit returns all answers to the model at once.",
|
|
154
|
+
usageHint: 'Prefer `tabs` with stable snake_case ids. Every decision should include a recommended answer and a short recommendationReason. Use `type: "text"` for free-form input. Bounds: 1-8 tabs, 1-12 questions per tab, and 2-8 labeled options per select question. Blank questions, empty tabs, and description-only options are invalid by design. `type` is canonical; legacy isMultiSelect flags may be used only when they do not conflict. Legacy `question`/`questions` inputs remain supported.',
|
|
154
155
|
inputSchema: {
|
|
155
156
|
type: "object",
|
|
156
157
|
properties: {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
},
|
|
161
|
-
context: {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
},
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
},
|
|
176
|
-
isMultiSelect: {
|
|
177
|
-
type: "boolean",
|
|
178
|
-
description: "Whether multiple options can be chosen simultaneously."
|
|
179
|
-
},
|
|
180
|
-
is_multi_select: {
|
|
181
|
-
type: "boolean",
|
|
182
|
-
description: "Snake-case alias for isMultiSelect."
|
|
183
|
-
},
|
|
184
|
-
allowCustomResponse: {
|
|
185
|
-
type: "boolean",
|
|
186
|
-
description: "Whether to allow the user to type a custom write-in response (default: true)."
|
|
187
|
-
},
|
|
188
|
-
questions: {
|
|
158
|
+
title: { type: "string", description: "Short form title." },
|
|
159
|
+
description: { type: "string", description: "Why these answers are needed." },
|
|
160
|
+
submitLabel: { type: "string", description: "Submit button label." },
|
|
161
|
+
question: { type: "string", minLength: 1 },
|
|
162
|
+
context: { type: "string" },
|
|
163
|
+
type: { type: "string", enum: ["single_select", "multi_select", "text"] },
|
|
164
|
+
options: optionArraySchema(),
|
|
165
|
+
recommendedOption: { type: "string" },
|
|
166
|
+
recommendedOptions: { type: "array", items: { type: "string" } },
|
|
167
|
+
recommendedText: { type: "string" },
|
|
168
|
+
recommendationReason: { type: "string" },
|
|
169
|
+
isMultiSelect: { type: "boolean" },
|
|
170
|
+
is_multi_select: { type: "boolean" },
|
|
171
|
+
allowCustomResponse: { type: "boolean" },
|
|
172
|
+
required: { type: "boolean" },
|
|
173
|
+
placeholder: { type: "string" },
|
|
174
|
+
questions: { type: "array", minItems: 1, items: questionSchema() },
|
|
175
|
+
tabs: {
|
|
189
176
|
type: "array",
|
|
190
|
-
|
|
177
|
+
minItems: 1,
|
|
178
|
+
maxItems: 8,
|
|
191
179
|
items: {
|
|
192
180
|
type: "object",
|
|
193
181
|
properties: {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
items: { type: "string" },
|
|
199
|
-
minItems: 2,
|
|
200
|
-
maxItems: 6
|
|
201
|
-
},
|
|
202
|
-
recommendedOption: { type: "string" },
|
|
203
|
-
isMultiSelect: { type: "boolean" },
|
|
204
|
-
is_multi_select: { type: "boolean" },
|
|
205
|
-
allowCustomResponse: { type: "boolean" }
|
|
182
|
+
id: { type: "string" },
|
|
183
|
+
label: { type: "string", minLength: 1 },
|
|
184
|
+
description: { type: "string" },
|
|
185
|
+
questions: { type: "array", minItems: 1, maxItems: 12, items: questionSchema() }
|
|
206
186
|
},
|
|
207
|
-
required: ["
|
|
187
|
+
required: ["label", "questions"],
|
|
188
|
+
additionalProperties: false
|
|
208
189
|
}
|
|
209
190
|
}
|
|
210
191
|
},
|
|
@@ -212,84 +193,298 @@ var clarifyTool = {
|
|
|
212
193
|
},
|
|
213
194
|
async execute(input, ctx, opts) {
|
|
214
195
|
try {
|
|
215
|
-
const signal = opts?.signal ?? ctx
|
|
216
|
-
signal
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
allowCustomResponse: input.allowCustomResponse
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
if (items.length === 0) {
|
|
231
|
-
throw new Error("clarify requires either `question` with `options`, or a `questions` array with at least 1 item.");
|
|
232
|
-
}
|
|
233
|
-
for (const item of items) {
|
|
234
|
-
if (!item.options || item.options.length < 2) {
|
|
235
|
-
throw new Error(`clarify question "${item.question}" requires at least 2 distinct options.`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
const hostAsk = ctx?.askUserChoices;
|
|
239
|
-
const answers = [];
|
|
240
|
-
let isAutoDecided = false;
|
|
241
|
-
for (const item of items) {
|
|
242
|
-
const multi = item.isMultiSelect ?? item.is_multi_select ?? false;
|
|
243
|
-
const options = item.options;
|
|
244
|
-
if (typeof hostAsk === "function") {
|
|
245
|
-
const res = await hostAsk(item.question, options, {
|
|
246
|
-
isMultiSelect: multi,
|
|
247
|
-
...item.context === void 0 ? {} : { context: item.context },
|
|
248
|
-
...item.recommendedOption === void 0 ? {} : { recommendedOption: item.recommendedOption },
|
|
249
|
-
allowCustomResponse: item.allowCustomResponse ?? true
|
|
250
|
-
});
|
|
251
|
-
const selected = Array.isArray(res?.selected) ? res.selected : [];
|
|
252
|
-
answers.push({
|
|
253
|
-
question: item.question,
|
|
254
|
-
selectedOptions: selected,
|
|
255
|
-
customResponse: res?.custom
|
|
256
|
-
});
|
|
257
|
-
} else {
|
|
258
|
-
isAutoDecided = true;
|
|
259
|
-
const rec = item.recommendedOption ?? options.find((opt) => /^\(?recommended\)?/i.test(opt)) ?? options[0] ?? "Default";
|
|
260
|
-
answers.push({
|
|
261
|
-
question: item.question,
|
|
262
|
-
selectedOptions: [rec],
|
|
263
|
-
customResponse: void 0
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
}
|
|
196
|
+
const signal = opts?.signal ?? ctx.signal;
|
|
197
|
+
signal.throwIfAborted();
|
|
198
|
+
const request = normalizeRequest(input);
|
|
199
|
+
let response;
|
|
200
|
+
if (typeof ctx.requestUserInput === "function")
|
|
201
|
+
response = await ctx.requestUserInput(request, signal);
|
|
202
|
+
else response = await legacyHostResponse(ctx, request);
|
|
203
|
+
const autoDecided = response === void 0;
|
|
204
|
+
const resolved = response ?? recommendedResponse(request);
|
|
205
|
+
if (resolved.status === "cancelled")
|
|
206
|
+
return skipped(request, "User cancelled the clarification form.");
|
|
207
|
+
const answers = materializeAnswers(request, resolved.answers);
|
|
267
208
|
const primary = answers[0];
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
209
|
+
const decisionSummary = `${autoDecided ? "Auto-selected recommended answers in non-interactive mode" : "User clarified"}: ${answers.map((answer) => {
|
|
210
|
+
if (answer.delegatedToModel)
|
|
211
|
+
return `"${answer.question}": model should decide (user delegated)`;
|
|
212
|
+
const values = [
|
|
213
|
+
...answer.selectedOptions,
|
|
214
|
+
...answer.customResponse ? [answer.customResponse] : []
|
|
215
|
+
];
|
|
216
|
+
return `"${answer.question}": ${values.join(", ") || "(blank)"}`;
|
|
217
|
+
}).join("; ")}`;
|
|
273
218
|
return {
|
|
274
|
-
status:
|
|
219
|
+
status: autoDecided ? "auto_decided" : "answered",
|
|
275
220
|
question: primary.question,
|
|
276
221
|
selectedOptions: primary.selectedOptions,
|
|
277
222
|
customResponse: primary.customResponse,
|
|
278
223
|
answers,
|
|
279
224
|
decisionSummary
|
|
280
225
|
};
|
|
281
|
-
} catch (
|
|
282
|
-
|
|
283
|
-
return {
|
|
284
|
-
status: "skipped",
|
|
285
|
-
question: fallbackQuestion,
|
|
286
|
-
selectedOptions: [],
|
|
287
|
-
decisionSummary: "",
|
|
288
|
-
error: toErrorMessage(err)
|
|
289
|
-
};
|
|
226
|
+
} catch (error) {
|
|
227
|
+
return skippedFromInput(input, toErrorMessage(error));
|
|
290
228
|
}
|
|
291
229
|
}
|
|
292
230
|
};
|
|
231
|
+
function optionArraySchema() {
|
|
232
|
+
return {
|
|
233
|
+
type: "array",
|
|
234
|
+
minItems: 2,
|
|
235
|
+
maxItems: 8,
|
|
236
|
+
items: {
|
|
237
|
+
oneOf: [
|
|
238
|
+
{ type: "string" },
|
|
239
|
+
{
|
|
240
|
+
type: "object",
|
|
241
|
+
properties: {
|
|
242
|
+
id: { type: "string" },
|
|
243
|
+
label: { type: "string", minLength: 1 },
|
|
244
|
+
description: { type: "string" }
|
|
245
|
+
},
|
|
246
|
+
required: ["label"],
|
|
247
|
+
additionalProperties: false
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function questionSchema() {
|
|
254
|
+
return {
|
|
255
|
+
type: "object",
|
|
256
|
+
properties: {
|
|
257
|
+
id: { type: "string" },
|
|
258
|
+
question: { type: "string", minLength: 1 },
|
|
259
|
+
context: { type: "string" },
|
|
260
|
+
type: { type: "string", enum: ["single_select", "multi_select", "text"] },
|
|
261
|
+
options: optionArraySchema(),
|
|
262
|
+
recommendedOption: { type: "string" },
|
|
263
|
+
recommendedOptions: { type: "array", items: { type: "string" } },
|
|
264
|
+
recommendedText: { type: "string" },
|
|
265
|
+
recommendationReason: { type: "string" },
|
|
266
|
+
isMultiSelect: { type: "boolean" },
|
|
267
|
+
is_multi_select: { type: "boolean" },
|
|
268
|
+
allowCustomResponse: { type: "boolean" },
|
|
269
|
+
required: { type: "boolean" },
|
|
270
|
+
placeholder: { type: "string" }
|
|
271
|
+
},
|
|
272
|
+
required: ["question"],
|
|
273
|
+
additionalProperties: false
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function slug(value, fallback) {
|
|
277
|
+
return value.toLocaleLowerCase("tr-TR").replace(/[ıİ]/g, "i").replace(/ğ/g, "g").replace(/ü/g, "u").replace(/ş/g, "s").replace(/ö/g, "o").replace(/ç/g, "c").normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || fallback;
|
|
278
|
+
}
|
|
279
|
+
function normalizeRequest(input) {
|
|
280
|
+
const sourceTabs = input.tabs !== void 0 ? input.tabs : [
|
|
281
|
+
{
|
|
282
|
+
label: "Questions",
|
|
283
|
+
questions: input.questions !== void 0 ? input.questions : [input]
|
|
284
|
+
}
|
|
285
|
+
];
|
|
286
|
+
if (sourceTabs.length === 0) throw new Error("clarify requires at least one tab.");
|
|
287
|
+
const seen = /* @__PURE__ */ new Set();
|
|
288
|
+
const tabs = sourceTabs.map((tab, tabIndex) => {
|
|
289
|
+
if (!tab.label?.trim()) throw new Error("Every clarify tab requires a non-empty `label`.");
|
|
290
|
+
if (!Array.isArray(tab.questions) || tab.questions.length === 0) {
|
|
291
|
+
throw new Error(`clarify tab "${tab.label}" requires at least one question.`);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
id: tab.id ?? slug(tab.label, `tab_${tabIndex + 1}`),
|
|
295
|
+
label: tab.label,
|
|
296
|
+
description: tab.description,
|
|
297
|
+
questions: tab.questions.map((question, questionIndex) => {
|
|
298
|
+
if (!question.question?.trim())
|
|
299
|
+
throw new Error("Every clarify question requires non-empty `question`.");
|
|
300
|
+
const id = question.id ?? slug(question.question, `question_${questionIndex + 1}`);
|
|
301
|
+
if (seen.has(id)) throw new Error(`Duplicate clarify question id: ${id}`);
|
|
302
|
+
seen.add(id);
|
|
303
|
+
const legacyMulti = resolveLegacyMultiSelect(question);
|
|
304
|
+
if (question.type !== void 0 && legacyMulti !== void 0 && (question.type === "text" || question.type === "multi_select" !== legacyMulti)) {
|
|
305
|
+
throw new Error(
|
|
306
|
+
`clarify question "${question.question}" has conflicting \`type\` and \`isMultiSelect\` values. Use \`type\` as the canonical field or remove the legacy flag.`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
const kind = question.type ?? (legacyMulti ? "multi_select" : "single_select");
|
|
310
|
+
const seenOptions = /* @__PURE__ */ new Set();
|
|
311
|
+
const options = (question.options ?? []).map((option, index) => {
|
|
312
|
+
const value = typeof option === "string" ? { label: option } : option;
|
|
313
|
+
if (!value?.label?.trim()) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
`clarify question "${question.question}" option ${index + 1} requires a non-empty \`label\`; \`description\` alone is not selectable.`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
const normalized = {
|
|
319
|
+
id: value.id ?? slug(value.label, `option_${index + 1}`),
|
|
320
|
+
label: value.label,
|
|
321
|
+
description: value.description
|
|
322
|
+
};
|
|
323
|
+
if (seenOptions.has(normalized.id)) {
|
|
324
|
+
throw new Error(
|
|
325
|
+
`clarify question "${question.question}" has duplicate option id: ${normalized.id}`
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
seenOptions.add(normalized.id);
|
|
329
|
+
return normalized;
|
|
330
|
+
});
|
|
331
|
+
if (kind !== "text" && options.length < 2)
|
|
332
|
+
throw new Error(`clarify question "${question.question}" requires at least 2 options.`);
|
|
333
|
+
const explicitRecommended = question.recommendedOptions ?? (question.recommendedOption ? [question.recommendedOption] : []);
|
|
334
|
+
const recommended = explicitRecommended.length > 0 ? explicitRecommended : options.filter((option) => /^\s*\(?recommended\)?\b/i.test(option.label)).slice(0, kind === "single_select" ? 1 : void 0).map((option) => option.id);
|
|
335
|
+
const recommendedOptionIds = recommended.map(
|
|
336
|
+
(value) => options.find((option) => option.id === value || option.label === value)?.id ?? value
|
|
337
|
+
);
|
|
338
|
+
const unknownRecommendation = recommendedOptionIds.find(
|
|
339
|
+
(recommendedId) => !options.some((option) => option.id === recommendedId)
|
|
340
|
+
);
|
|
341
|
+
if (unknownRecommendation) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`clarify question "${question.question}" recommends unknown option: ${unknownRecommendation}`
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
if (kind === "single_select" && recommendedOptionIds.length > 1)
|
|
347
|
+
throw new Error(
|
|
348
|
+
`Single-select question "${question.question}" can recommend only one option.`
|
|
349
|
+
);
|
|
350
|
+
if (kind === "single_select" && recommendedOptionIds.length > 0 && question.recommendedText?.trim()) {
|
|
351
|
+
throw new Error(
|
|
352
|
+
`Single-select question "${question.question}" cannot recommend both an option and a custom text answer.`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
return {
|
|
356
|
+
id,
|
|
357
|
+
prompt: question.question,
|
|
358
|
+
description: question.context,
|
|
359
|
+
kind,
|
|
360
|
+
required: question.required ?? true,
|
|
361
|
+
options: kind === "text" ? void 0 : options,
|
|
362
|
+
recommendedOptionIds,
|
|
363
|
+
recommendedText: question.recommendedText,
|
|
364
|
+
recommendationReason: question.recommendationReason,
|
|
365
|
+
allowCustomResponse: kind === "text" ? void 0 : question.allowCustomResponse ?? true,
|
|
366
|
+
placeholder: question.placeholder
|
|
367
|
+
};
|
|
368
|
+
})
|
|
369
|
+
};
|
|
370
|
+
});
|
|
371
|
+
return {
|
|
372
|
+
id: `clarify_${randomUUID()}`,
|
|
373
|
+
title: input.title?.trim() || "A few decisions are needed",
|
|
374
|
+
description: input.description,
|
|
375
|
+
submitLabel: input.submitLabel ?? "Submit answers",
|
|
376
|
+
tabs
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
function recommendedResponse(request) {
|
|
380
|
+
return {
|
|
381
|
+
requestId: request.id,
|
|
382
|
+
status: "submitted",
|
|
383
|
+
answers: request.tabs.flatMap(
|
|
384
|
+
(tab) => tab.questions.map((question) => ({
|
|
385
|
+
questionId: question.id,
|
|
386
|
+
selectedOptionIds: question.recommendedOptionIds?.length ? question.recommendedOptionIds : question.kind === "text" ? [] : question.options?.slice(0, 1).map((option) => option.id) ?? [],
|
|
387
|
+
text: question.recommendedText,
|
|
388
|
+
delegated: false,
|
|
389
|
+
usedRecommendation: Boolean(
|
|
390
|
+
question.recommendedOptionIds?.length || question.recommendedText
|
|
391
|
+
)
|
|
392
|
+
}))
|
|
393
|
+
)
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function materializeAnswers(request, answers) {
|
|
397
|
+
const byId = new Map(answers.map((answer) => [answer.questionId, answer]));
|
|
398
|
+
return request.tabs.flatMap(
|
|
399
|
+
(tab) => tab.questions.map((question) => {
|
|
400
|
+
const answer = byId.get(question.id) ?? {
|
|
401
|
+
questionId: question.id,
|
|
402
|
+
selectedOptionIds: [],
|
|
403
|
+
usedRecommendation: false
|
|
404
|
+
};
|
|
405
|
+
if (answer.delegated) {
|
|
406
|
+
return {
|
|
407
|
+
questionId: question.id,
|
|
408
|
+
question: question.prompt,
|
|
409
|
+
selectedOptions: [],
|
|
410
|
+
delegatedToModel: true,
|
|
411
|
+
usedRecommendation: false
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
questionId: question.id,
|
|
416
|
+
question: question.prompt,
|
|
417
|
+
selectedOptions: answer.selectedOptionIds.map(
|
|
418
|
+
(id) => question.options?.find((option) => option.id === id)?.label ?? id
|
|
419
|
+
),
|
|
420
|
+
customResponse: answer.text,
|
|
421
|
+
delegatedToModel: false,
|
|
422
|
+
usedRecommendation: matchesRecommendation(question, answer)
|
|
423
|
+
};
|
|
424
|
+
})
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
function resolveLegacyMultiSelect(question) {
|
|
428
|
+
if (question.isMultiSelect !== void 0 && question.is_multi_select !== void 0 && question.isMultiSelect !== question.is_multi_select) {
|
|
429
|
+
throw new Error(
|
|
430
|
+
`clarify question "${question.question}" has conflicting \`isMultiSelect\` and \`is_multi_select\` values.`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
return question.isMultiSelect ?? question.is_multi_select;
|
|
434
|
+
}
|
|
435
|
+
function matchesRecommendation(question, answer) {
|
|
436
|
+
if (answer.delegated) return false;
|
|
437
|
+
const recommendedOptions = question.recommendedOptionIds ?? [];
|
|
438
|
+
const recommendedText = question.recommendedText?.trim() ?? "";
|
|
439
|
+
if (recommendedOptions.length === 0 && recommendedText.length === 0) return false;
|
|
440
|
+
const selected = answer.selectedOptionIds;
|
|
441
|
+
return selected.length === recommendedOptions.length && selected.every((id) => recommendedOptions.includes(id)) && (answer.text?.trim() ?? "") === recommendedText;
|
|
442
|
+
}
|
|
443
|
+
async function legacyHostResponse(ctx, request) {
|
|
444
|
+
const ask = ctx.askUserChoices;
|
|
445
|
+
if (typeof ask !== "function") return void 0;
|
|
446
|
+
const answers = [];
|
|
447
|
+
for (const question of request.tabs.flatMap((tab) => tab.questions)) {
|
|
448
|
+
const result = await ask(
|
|
449
|
+
question.prompt,
|
|
450
|
+
question.options?.map((option) => option.label) ?? [],
|
|
451
|
+
{
|
|
452
|
+
isMultiSelect: question.kind === "multi_select",
|
|
453
|
+
context: question.description,
|
|
454
|
+
recommendedOption: question.recommendedOptionIds?.[0],
|
|
455
|
+
allowCustomResponse: question.allowCustomResponse
|
|
456
|
+
}
|
|
457
|
+
);
|
|
458
|
+
const ids = result.selected.map(
|
|
459
|
+
(value) => question.options?.find((option) => option.label === value || option.id === value)?.id ?? value
|
|
460
|
+
);
|
|
461
|
+
answers.push({
|
|
462
|
+
questionId: question.id,
|
|
463
|
+
selectedOptionIds: ids,
|
|
464
|
+
text: result.custom,
|
|
465
|
+
usedRecommendation: ids.length === (question.recommendedOptionIds?.length ?? 0) && ids.every((id) => question.recommendedOptionIds?.includes(id))
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
return { requestId: request.id, status: "submitted", answers };
|
|
469
|
+
}
|
|
470
|
+
function skipped(request, error) {
|
|
471
|
+
return {
|
|
472
|
+
status: "skipped",
|
|
473
|
+
question: request.tabs[0]?.questions[0]?.prompt ?? "",
|
|
474
|
+
selectedOptions: [],
|
|
475
|
+
decisionSummary: "",
|
|
476
|
+
error
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function skippedFromInput(input, error) {
|
|
480
|
+
return {
|
|
481
|
+
status: "skipped",
|
|
482
|
+
question: input.question ?? input.questions?.[0]?.question ?? input.tabs?.[0]?.questions[0]?.question ?? "",
|
|
483
|
+
selectedOptions: [],
|
|
484
|
+
decisionSummary: "",
|
|
485
|
+
error
|
|
486
|
+
};
|
|
487
|
+
}
|
|
293
488
|
|
|
294
489
|
// src/pwsh.ts
|
|
295
490
|
import { spawn } from "node:child_process";
|
|
@@ -1497,4 +1692,4 @@ export {
|
|
|
1497
1692
|
TIER3_TOOLS,
|
|
1498
1693
|
builtinTools
|
|
1499
1694
|
};
|
|
1500
|
-
//# sourceMappingURL=chunk-
|
|
1695
|
+
//# sourceMappingURL=chunk-4DK5WZGR.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-NBDZMMG2.js";
|
|
6
6
|
import {
|
|
7
7
|
truncateMiddle
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2IAEJRLT.js";
|
|
9
9
|
|
|
10
10
|
// src/fetch.ts
|
|
11
11
|
import { FetchError, ToolError, ToolValidationError } from "@wrongstack/core/types";
|
|
@@ -281,4 +281,4 @@ function prettyJson(s) {
|
|
|
281
281
|
export {
|
|
282
282
|
fetchTool
|
|
283
283
|
};
|
|
284
|
-
//# sourceMappingURL=chunk-
|
|
284
|
+
//# sourceMappingURL=chunk-4SW6BXUR.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
enqueueReindex
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TU6UVATU.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveRealInsideRoot,
|
|
6
6
|
safeResolveReal,
|
|
7
7
|
sha256hex
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2IAEJRLT.js";
|
|
9
9
|
|
|
10
10
|
// src/patch.ts
|
|
11
11
|
import { spawn } from "node:child_process";
|
|
@@ -395,4 +395,4 @@ function extractPatchedFiles(output) {
|
|
|
395
395
|
export {
|
|
396
396
|
patchTool
|
|
397
397
|
};
|
|
398
|
-
//# sourceMappingURL=chunk-
|
|
398
|
+
//# sourceMappingURL=chunk-5MP76C72.js.map
|