@anionex/dsh-tool-search 0.1.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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/README.zh.md +160 -0
- package/cordis.patch.yml +3 -0
- package/docs/benchmark-results.json +51 -0
- package/lib/bm25.js +83 -0
- package/lib/bm25.js.map +1 -0
- package/lib/catalog.js +53 -0
- package/lib/catalog.js.map +1 -0
- package/lib/client.js +388 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/lib/runtime.js +286 -0
- package/lib/runtime.js.map +1 -0
- package/lib/settings.js +50 -0
- package/lib/settings.js.map +1 -0
- package/lib/shared.js +40 -0
- package/lib/shared.js.map +1 -0
- package/lib/types/bm25.d.ts +20 -0
- package/lib/types/bm25.d.ts.map +1 -0
- package/lib/types/catalog.d.ts +26 -0
- package/lib/types/catalog.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +65 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/index.d.ts +14 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/runtime.d.ts +37 -0
- package/lib/types/runtime.d.ts.map +1 -0
- package/lib/types/settings.d.ts +16 -0
- package/lib/types/settings.d.ts.map +1 -0
- package/lib/types/shared.d.ts +31 -0
- package/lib/types/shared.d.ts.map +1 -0
- package/lib/types/web.d.ts +5 -0
- package/lib/types/web.d.ts.map +1 -0
- package/lib/web.js +28 -0
- package/lib/web.js.map +1 -0
- package/package.json +149 -0
- package/pnpm-workspace.yaml +11 -0
- package/scripts/benchmark.mjs +124 -0
- package/scripts/profile-e2e.mjs +366 -0
- package/scripts/validate.mjs +170 -0
- package/src/bm25.ts +104 -0
- package/src/catalog.ts +72 -0
- package/src/client/index.tsx +344 -0
- package/src/index.ts +32 -0
- package/src/runtime.ts +326 -0
- package/src/settings.ts +63 -0
- package/src/shared.ts +63 -0
- package/src/web.ts +34 -0
- package/src/wink-porter2-stemmer.d.ts +3 -0
- package/tests/bm25.spec.ts +75 -0
- package/tests/catalog.spec.ts +63 -0
- package/tests/client.spec.tsx +39 -0
- package/tests/execution-regression.spec.ts +200 -0
- package/tests/runtime.spec.ts +271 -0
- package/tests/settings.spec.ts +33 -0
- package/tsconfig.client.json +31 -0
- package/tsconfig.json +30 -0
- package/tsconfig.test.json +23 -0
- package/tsdown.config.mjs +37 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({ id: "@anionex/dsh-tool-search", factory: (require) => {
|
|
2
|
+
var module = { exports: {} }; var exports = module.exports;
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
|
|
7
|
+
//#region src/shared.ts
|
|
8
|
+
/** Values shared by the Host runtime and Web settings client. */
|
|
9
|
+
const TOOL_SEARCH_NAME = "tool_search";
|
|
10
|
+
const TOOL_SEARCH_SETTINGS_NAMESPACE = "tool-search";
|
|
11
|
+
const TOOL_SEARCH_CATALOG_ROUTE = "/_dsh/tool-search/catalog";
|
|
12
|
+
const DEFAULT_RESULT_LIMIT = 5;
|
|
13
|
+
/**
|
|
14
|
+
* Stable bootstrap surface for current DSH releases. Unknown future first-party
|
|
15
|
+
* names are deferred until this list or the user allowlist is updated because
|
|
16
|
+
* ToolDefinition does not expose package provenance.
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_CORE_TOOLS = Object.freeze([
|
|
19
|
+
"apply_patch",
|
|
20
|
+
"ask_user_question",
|
|
21
|
+
"bash",
|
|
22
|
+
"create_goal",
|
|
23
|
+
"dsh_im_return_file",
|
|
24
|
+
"exit_plan_mode",
|
|
25
|
+
"get_goal",
|
|
26
|
+
"interrupt_agent",
|
|
27
|
+
"job_kill",
|
|
28
|
+
"job_list",
|
|
29
|
+
"job_output",
|
|
30
|
+
"list_agents",
|
|
31
|
+
"ralph",
|
|
32
|
+
"report",
|
|
33
|
+
"send_message",
|
|
34
|
+
"skill",
|
|
35
|
+
"subagent",
|
|
36
|
+
"subagent_fork",
|
|
37
|
+
"todo_write",
|
|
38
|
+
"update_goal",
|
|
39
|
+
"workflow"
|
|
40
|
+
]);
|
|
41
|
+
const DEFAULT_SETTINGS = Object.freeze({
|
|
42
|
+
defaultLimit: 5,
|
|
43
|
+
alwaysVisible: [],
|
|
44
|
+
neverSearch: []
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/client/index.tsx
|
|
49
|
+
/** DSH Web settings surface for deferred tool policy. */
|
|
50
|
+
const en = {
|
|
51
|
+
nav: "Tool Search",
|
|
52
|
+
topK: "Default results",
|
|
53
|
+
alwaysVisible: "Always visible",
|
|
54
|
+
neverSearch: "Never searchable",
|
|
55
|
+
catalog: "Tool catalog",
|
|
56
|
+
filter: "Filter tools",
|
|
57
|
+
refresh: "Refresh",
|
|
58
|
+
tool: "Tool",
|
|
59
|
+
policy: "Policy",
|
|
60
|
+
selected: "Live agents",
|
|
61
|
+
defaultPolicy: "Default",
|
|
62
|
+
alwaysPolicy: "Always",
|
|
63
|
+
blockedPolicy: "Blocked",
|
|
64
|
+
loading: "Loading...",
|
|
65
|
+
empty: "No matching tools",
|
|
66
|
+
saved: "Saved",
|
|
67
|
+
onePerLine: "One exact tool name per line"
|
|
68
|
+
};
|
|
69
|
+
const zh = {
|
|
70
|
+
nav: "工具搜索",
|
|
71
|
+
topK: "默认结果数",
|
|
72
|
+
alwaysVisible: "常驻白名单",
|
|
73
|
+
neverSearch: "搜索黑名单",
|
|
74
|
+
catalog: "工具目录",
|
|
75
|
+
filter: "筛选工具",
|
|
76
|
+
refresh: "刷新",
|
|
77
|
+
tool: "工具",
|
|
78
|
+
policy: "策略",
|
|
79
|
+
selected: "活跃 Agent",
|
|
80
|
+
defaultPolicy: "默认",
|
|
81
|
+
alwaysPolicy: "常驻",
|
|
82
|
+
blockedPolicy: "禁用",
|
|
83
|
+
loading: "加载中...",
|
|
84
|
+
empty: "没有匹配工具",
|
|
85
|
+
saved: "已保存",
|
|
86
|
+
onePerLine: "每行一个精确工具名"
|
|
87
|
+
};
|
|
88
|
+
const EMPTY_SETTINGS = {
|
|
89
|
+
status: "unavailable",
|
|
90
|
+
value: void 0,
|
|
91
|
+
writable: false
|
|
92
|
+
};
|
|
93
|
+
const styles = `
|
|
94
|
+
.dts-settings{container-type:inline-size;display:flex;flex-direction:column;gap:20px;width:100%;min-width:0;color:var(--dsw-alias-label-primary)}
|
|
95
|
+
.dts-toolbar{display:grid;grid-template-columns:minmax(160px,220px) minmax(220px,1fr) auto;align-items:end;gap:12px}
|
|
96
|
+
.dts-field{display:flex;flex-direction:column;gap:6px;min-width:0}
|
|
97
|
+
.dts-field>span,.dts-section-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
98
|
+
.dts-input,.dts-textarea,.dts-select{box-sizing:border-box;width:100%;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit}
|
|
99
|
+
.dts-input,.dts-select{height:34px;padding:0 9px}.dts-textarea{min-height:104px;padding:8px 9px;resize:vertical;line-height:20px}
|
|
100
|
+
.dts-input:focus,.dts-textarea:focus,.dts-select:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
|
|
101
|
+
.dts-lists{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
|
|
102
|
+
.dts-hint{font-size:11px;color:var(--dsw-alias-label-tertiary)}
|
|
103
|
+
.dts-button{height:34px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer}
|
|
104
|
+
.dts-button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dts-button:disabled{opacity:.5;cursor:not-allowed}
|
|
105
|
+
.dts-status{min-height:18px;font-size:12px;color:var(--dsw-alias-label-secondary)}.dts-status[data-error=true]{color:var(--dsw-alias-state-error-primary)}
|
|
106
|
+
.dts-table-wrap{min-width:0;overflow:auto;border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2)}
|
|
107
|
+
.dts-table{width:100%;min-width:620px;border-collapse:collapse;table-layout:fixed}
|
|
108
|
+
.dts-table th,.dts-table td{box-sizing:border-box;padding:9px 10px;border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;vertical-align:middle;font-size:12px}
|
|
109
|
+
.dts-table th{position:sticky;top:0;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font-weight:600}
|
|
110
|
+
.dts-table tr:last-child td{border-bottom:0}.dts-tool{width:52%}.dts-tool code{display:block;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;white-space:nowrap;color:var(--dsw-alias-label-primary)}
|
|
111
|
+
.dts-description{display:block;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary)}
|
|
112
|
+
.dts-policy{width:26%}.dts-selected{width:22%;color:var(--dsw-alias-label-secondary)}
|
|
113
|
+
@container(max-width:620px){.dts-toolbar{grid-template-columns:1fr auto}.dts-toolbar .dts-limit{grid-column:1/-1}.dts-lists{grid-template-columns:1fr}.dts-table{min-width:0}.dts-table thead{display:none}.dts-table tr{display:grid;grid-template-columns:minmax(0,1fr) 132px;padding:8px 10px;border-bottom:1px solid var(--dsw-alias-border-l1)}.dts-table td{padding:4px 0;border:0}.dts-table .dts-tool,.dts-table .dts-policy{width:auto}.dts-table .dts-selected{grid-column:1/-1;width:auto;font-size:11px}.dts-table .dts-selected::before{content:attr(data-label) ": ";color:var(--dsw-alias-label-tertiary);font-weight:600}}
|
|
114
|
+
`;
|
|
115
|
+
function namesFromText(value) {
|
|
116
|
+
return [...new Set(value.split(/\r?\n/u).map((name) => name.trim()).filter(Boolean))].sort();
|
|
117
|
+
}
|
|
118
|
+
function overrideFor(name, settings) {
|
|
119
|
+
if (settings.neverSearch.includes(name)) return "blocked";
|
|
120
|
+
if (settings.alwaysVisible.includes(name)) return "always";
|
|
121
|
+
return "default";
|
|
122
|
+
}
|
|
123
|
+
function decodeCatalog(value) {
|
|
124
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Invalid catalog response");
|
|
125
|
+
const record = value;
|
|
126
|
+
if (record["schemaVersion"] !== 1 || !Array.isArray(record["tools"]) || typeof record["generation"] !== "number") throw new Error("Invalid catalog response");
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
function ToolSearchSettingsSection({ scope, t }) {
|
|
130
|
+
const snapshot = (0, react.useSyncExternalStore)((0, react.useCallback)((notify) => scope?.subscribe(notify) ?? (() => {}), [scope]), (0, react.useCallback)(() => scope?.getSnapshot() ?? EMPTY_SETTINGS, [scope]));
|
|
131
|
+
const [catalog, setCatalog] = (0, react.useState)();
|
|
132
|
+
const [filter, setFilter] = (0, react.useState)("");
|
|
133
|
+
const [alwaysText, setAlwaysText] = (0, react.useState)("");
|
|
134
|
+
const [blockedText, setBlockedText] = (0, react.useState)("");
|
|
135
|
+
const [limitText, setLimitText] = (0, react.useState)(String(5));
|
|
136
|
+
const [status, setStatus] = (0, react.useState)();
|
|
137
|
+
const translate = t ?? ((key) => en[key]);
|
|
138
|
+
const settings = snapshot.value;
|
|
139
|
+
const refresh = (0, react.useCallback)(async () => {
|
|
140
|
+
try {
|
|
141
|
+
const response = await fetch(TOOL_SEARCH_CATALOG_ROUTE, { cache: "no-store" });
|
|
142
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
143
|
+
setCatalog(decodeCatalog(await response.json()));
|
|
144
|
+
setStatus(void 0);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
setStatus({
|
|
147
|
+
text: error instanceof Error ? error.message : String(error),
|
|
148
|
+
error: true
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}, []);
|
|
152
|
+
(0, react.useEffect)(() => {
|
|
153
|
+
refresh();
|
|
154
|
+
}, [refresh]);
|
|
155
|
+
(0, react.useEffect)(() => {
|
|
156
|
+
if (settings === void 0) return;
|
|
157
|
+
setAlwaysText(settings.alwaysVisible.join("\n"));
|
|
158
|
+
setBlockedText(settings.neverSearch.join("\n"));
|
|
159
|
+
setLimitText(String(settings.defaultLimit));
|
|
160
|
+
}, [settings]);
|
|
161
|
+
const commit = (0, react.useCallback)((field, value) => {
|
|
162
|
+
if (scope === void 0 || !snapshot.writable) return;
|
|
163
|
+
setStatus(void 0);
|
|
164
|
+
scope.set(field, value).then(() => {
|
|
165
|
+
setStatus({
|
|
166
|
+
text: translate("saved"),
|
|
167
|
+
error: false
|
|
168
|
+
});
|
|
169
|
+
refresh();
|
|
170
|
+
}, (error) => {
|
|
171
|
+
setStatus({
|
|
172
|
+
text: error instanceof Error ? error.message : String(error),
|
|
173
|
+
error: true
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}, [
|
|
177
|
+
refresh,
|
|
178
|
+
scope,
|
|
179
|
+
snapshot.writable,
|
|
180
|
+
translate
|
|
181
|
+
]);
|
|
182
|
+
const visibleTools = (0, react.useMemo)(() => {
|
|
183
|
+
const query = filter.trim().toLowerCase();
|
|
184
|
+
if (query.length === 0) return catalog?.tools ?? [];
|
|
185
|
+
return (catalog?.tools ?? []).filter((tool) => tool.name.toLowerCase().includes(query) || tool.description.toLowerCase().includes(query));
|
|
186
|
+
}, [catalog, filter]);
|
|
187
|
+
const changePolicy = (name, next) => {
|
|
188
|
+
if (settings === void 0 || name === "tool_search") return;
|
|
189
|
+
const always = new Set(settings.alwaysVisible);
|
|
190
|
+
const blocked = new Set(settings.neverSearch);
|
|
191
|
+
always.delete(name);
|
|
192
|
+
blocked.delete(name);
|
|
193
|
+
if (next === "always") always.add(name);
|
|
194
|
+
if (next === "blocked") blocked.add(name);
|
|
195
|
+
commit("alwaysVisible", [...always].sort());
|
|
196
|
+
commit("neverSearch", [...blocked].sort());
|
|
197
|
+
};
|
|
198
|
+
const core = new Set(DEFAULT_CORE_TOOLS);
|
|
199
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
200
|
+
className: "dts-settings",
|
|
201
|
+
children: [
|
|
202
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
203
|
+
className: "dts-toolbar",
|
|
204
|
+
children: [
|
|
205
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
206
|
+
className: "dts-field dts-limit",
|
|
207
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: translate("topK") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
208
|
+
className: "dts-input",
|
|
209
|
+
type: "number",
|
|
210
|
+
min: 1,
|
|
211
|
+
max: 20,
|
|
212
|
+
value: limitText,
|
|
213
|
+
disabled: !snapshot.writable,
|
|
214
|
+
onChange: (event) => setLimitText(event.target.value),
|
|
215
|
+
onBlur: () => {
|
|
216
|
+
const value = Number.parseInt(limitText, 10);
|
|
217
|
+
if (Number.isSafeInteger(value) && value >= 1 && value <= 20) commit("defaultLimit", value);
|
|
218
|
+
else setLimitText(String(settings?.defaultLimit ?? 5));
|
|
219
|
+
}
|
|
220
|
+
})]
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
223
|
+
className: "dts-field",
|
|
224
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: translate("filter") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
225
|
+
className: "dts-input",
|
|
226
|
+
type: "search",
|
|
227
|
+
value: filter,
|
|
228
|
+
onChange: (event) => setFilter(event.target.value)
|
|
229
|
+
})]
|
|
230
|
+
}),
|
|
231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
232
|
+
className: "dts-button",
|
|
233
|
+
type: "button",
|
|
234
|
+
onClick: () => {
|
|
235
|
+
refresh();
|
|
236
|
+
},
|
|
237
|
+
children: translate("refresh")
|
|
238
|
+
})
|
|
239
|
+
]
|
|
240
|
+
}),
|
|
241
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
242
|
+
className: "dts-lists",
|
|
243
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
244
|
+
className: "dts-field",
|
|
245
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: translate("alwaysVisible") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
246
|
+
className: "dts-textarea",
|
|
247
|
+
value: alwaysText,
|
|
248
|
+
disabled: !snapshot.writable,
|
|
249
|
+
placeholder: translate("onePerLine"),
|
|
250
|
+
onChange: (event) => setAlwaysText(event.target.value),
|
|
251
|
+
onBlur: () => commit("alwaysVisible", namesFromText(alwaysText))
|
|
252
|
+
})]
|
|
253
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
254
|
+
className: "dts-field",
|
|
255
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: translate("neverSearch") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
256
|
+
className: "dts-textarea",
|
|
257
|
+
value: blockedText,
|
|
258
|
+
disabled: !snapshot.writable,
|
|
259
|
+
placeholder: translate("onePerLine"),
|
|
260
|
+
onChange: (event) => setBlockedText(event.target.value),
|
|
261
|
+
onBlur: () => commit("neverSearch", namesFromText(blockedText).filter((name) => name !== TOOL_SEARCH_NAME))
|
|
262
|
+
})]
|
|
263
|
+
})]
|
|
264
|
+
}),
|
|
265
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
266
|
+
className: "dts-field",
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
269
|
+
className: "dts-section-title",
|
|
270
|
+
children: translate("catalog")
|
|
271
|
+
}),
|
|
272
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
273
|
+
className: "dts-table-wrap",
|
|
274
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
275
|
+
className: "dts-table",
|
|
276
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
277
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
278
|
+
className: "dts-tool",
|
|
279
|
+
children: translate("tool")
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
282
|
+
className: "dts-policy",
|
|
283
|
+
children: translate("policy")
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
286
|
+
className: "dts-selected",
|
|
287
|
+
children: translate("selected")
|
|
288
|
+
})
|
|
289
|
+
] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tbody", { children: [visibleTools.map((tool) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
290
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
|
|
291
|
+
className: "dts-tool",
|
|
292
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
293
|
+
title: tool.name,
|
|
294
|
+
children: tool.name
|
|
295
|
+
}), tool.description.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
296
|
+
className: "dts-description",
|
|
297
|
+
title: tool.description,
|
|
298
|
+
children: tool.description
|
|
299
|
+
}) : null]
|
|
300
|
+
}),
|
|
301
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
302
|
+
className: "dts-policy",
|
|
303
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
304
|
+
className: "dts-select",
|
|
305
|
+
"aria-label": `${translate("policy")}: ${tool.name}`,
|
|
306
|
+
value: tool.name === "tool_search" ? "always" : overrideFor(tool.name, settings ?? {
|
|
307
|
+
defaultLimit: 5,
|
|
308
|
+
alwaysVisible: [],
|
|
309
|
+
neverSearch: []
|
|
310
|
+
}),
|
|
311
|
+
disabled: !snapshot.writable || tool.name === "tool_search",
|
|
312
|
+
onChange: (event) => changePolicy(tool.name, event.target.value),
|
|
313
|
+
children: [
|
|
314
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
315
|
+
value: "default",
|
|
316
|
+
children: core.has(tool.name) ? `${translate("defaultPolicy")} (${translate("alwaysPolicy")})` : translate("defaultPolicy")
|
|
317
|
+
}),
|
|
318
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
319
|
+
value: "always",
|
|
320
|
+
children: translate("alwaysPolicy")
|
|
321
|
+
}),
|
|
322
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
323
|
+
value: "blocked",
|
|
324
|
+
children: translate("blockedPolicy")
|
|
325
|
+
})
|
|
326
|
+
]
|
|
327
|
+
})
|
|
328
|
+
}),
|
|
329
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
330
|
+
className: "dts-selected",
|
|
331
|
+
"data-label": translate("selected"),
|
|
332
|
+
"aria-label": `${translate("selected")}: ${tool.selectedBy.length}`,
|
|
333
|
+
children: tool.selectedBy.length
|
|
334
|
+
})
|
|
335
|
+
] }, tool.name)), catalog !== void 0 && visibleTools.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
336
|
+
colSpan: 3,
|
|
337
|
+
children: translate("empty")
|
|
338
|
+
}) }) : null] })]
|
|
339
|
+
})
|
|
340
|
+
}),
|
|
341
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
342
|
+
className: "dts-status",
|
|
343
|
+
"data-error": status?.error || void 0,
|
|
344
|
+
children: status?.text ?? (catalog === void 0 ? translate("loading") : "")
|
|
345
|
+
})
|
|
346
|
+
]
|
|
347
|
+
})
|
|
348
|
+
]
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
const inject = [
|
|
352
|
+
"slots",
|
|
353
|
+
"locale",
|
|
354
|
+
"settingsScope"
|
|
355
|
+
];
|
|
356
|
+
function apply(ctx) {
|
|
357
|
+
ctx.effect(() => {
|
|
358
|
+
if (document.querySelector("style[data-plugin-css=\"@anionex/dsh-tool-search\"]") !== null) return () => {};
|
|
359
|
+
const tag = document.createElement("style");
|
|
360
|
+
tag.dataset.pluginCss = "@anionex/dsh-tool-search";
|
|
361
|
+
tag.textContent = styles;
|
|
362
|
+
document.head.append(tag);
|
|
363
|
+
return () => tag.remove();
|
|
364
|
+
}, "dsh-tool-search: styles");
|
|
365
|
+
ctx.effect(() => ctx.locale.register("settings.toolSearch", {
|
|
366
|
+
en,
|
|
367
|
+
zh
|
|
368
|
+
}), "dsh-tool-search: locale");
|
|
369
|
+
const t = ctx.locale.bind("settings.toolSearch");
|
|
370
|
+
const scope = ctx.settingsScope.bind({ namespace: TOOL_SEARCH_SETTINGS_NAMESPACE });
|
|
371
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
372
|
+
name: "settings.section",
|
|
373
|
+
id: "tool-search",
|
|
374
|
+
order: 34,
|
|
375
|
+
label: () => t("nav"),
|
|
376
|
+
inject: () => ({
|
|
377
|
+
scope,
|
|
378
|
+
t
|
|
379
|
+
})
|
|
380
|
+
}, ToolSearchSettingsSection));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
//#endregion
|
|
384
|
+
exports.ToolSearchSettingsSection = ToolSearchSettingsSection;
|
|
385
|
+
exports.apply = apply;
|
|
386
|
+
exports.inject = inject;
|
|
387
|
+
return module.exports; } });
|
|
388
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["useSyncExternalStore","useCallback","useState","useMemo"],"sources":["../src/shared.ts","../src/client/index.tsx"],"sourcesContent":["/** Values shared by the Host runtime and Web settings client. */\n\nexport const TOOL_SEARCH_NAME = 'tool_search'\nexport const TOOL_SEARCH_SETTINGS_NAMESPACE = 'tool-search'\nexport const TOOL_SEARCH_CATALOG_ROUTE = '/_dsh/tool-search/catalog'\nexport const DEFAULT_RESULT_LIMIT = 5\nexport const MAX_RESULT_LIMIT = 20\n\n/**\n * Stable bootstrap surface for current DSH releases. Unknown future first-party\n * names are deferred until this list or the user allowlist is updated because\n * ToolDefinition does not expose package provenance.\n */\nexport const DEFAULT_CORE_TOOLS = Object.freeze([\n 'apply_patch',\n 'ask_user_question',\n 'bash',\n 'create_goal',\n 'dsh_im_return_file',\n 'exit_plan_mode',\n 'get_goal',\n 'interrupt_agent',\n 'job_kill',\n 'job_list',\n 'job_output',\n 'list_agents',\n 'ralph',\n 'report',\n 'send_message',\n 'skill',\n 'subagent',\n 'subagent_fork',\n 'todo_write',\n 'update_goal',\n 'workflow',\n] as const)\n\nexport interface ToolSearchSettings {\n defaultLimit: number\n alwaysVisible: string[]\n neverSearch: string[]\n}\n\nexport const DEFAULT_SETTINGS: Readonly<ToolSearchSettings> = Object.freeze({\n defaultLimit: DEFAULT_RESULT_LIMIT,\n alwaysVisible: [],\n neverSearch: [],\n})\n\nexport type ToolPolicy = 'always' | 'deferred' | 'blocked'\n\nexport interface CatalogToolSummary {\n name: string\n description: string\n policy: ToolPolicy\n selectedBy: string[]\n}\n\nexport interface CatalogSnapshot {\n schemaVersion: 1\n generation: number\n tools: CatalogToolSummary[]\n}\n","/** DSH Web settings surface for deferred tool policy. */\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from 'react'\nimport {\n DEFAULT_CORE_TOOLS,\n DEFAULT_RESULT_LIMIT,\n MAX_RESULT_LIMIT,\n TOOL_SEARCH_CATALOG_ROUTE,\n TOOL_SEARCH_NAME,\n TOOL_SEARCH_SETTINGS_NAMESPACE,\n type CatalogSnapshot,\n type ToolPolicy,\n type ToolSearchSettings,\n} from '../shared.ts'\n\ninterface SettingsScopeSnapshot<T> {\n status: 'loading' | 'ready' | 'unavailable'\n value: T | undefined\n writable: boolean\n}\n\ninterface SettingsScope<T> {\n getSnapshot(): SettingsScopeSnapshot<T>\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise<void>\n}\n\ntype Disposer = () => void\n\ninterface ClientContext {\n effect(setup: () => Disposer | void, label: string): void\n locale: {\n register(namespace: string, catalogs: Record<string, Record<string, string>>): Disposer\n bind(namespace: string): (key: string) => string\n }\n settingsScope: {\n bind<T>(options: { namespace: string }): SettingsScope<T>\n }\n slots: {\n inject(name: string, callback: () => Disposer): Disposer\n register<P>(\n options: {\n name: string\n id: string\n order: number\n label: () => string\n inject: () => P\n },\n component: (props: P) => ReactNode,\n ): Disposer\n }\n}\n\ntype Translate = (key: keyof typeof en) => string\n\nconst en = {\n nav: 'Tool Search',\n topK: 'Default results',\n alwaysVisible: 'Always visible',\n neverSearch: 'Never searchable',\n catalog: 'Tool catalog',\n filter: 'Filter tools',\n refresh: 'Refresh',\n tool: 'Tool',\n policy: 'Policy',\n selected: 'Live agents',\n defaultPolicy: 'Default',\n alwaysPolicy: 'Always',\n blockedPolicy: 'Blocked',\n loading: 'Loading...',\n empty: 'No matching tools',\n saved: 'Saved',\n onePerLine: 'One exact tool name per line',\n}\n\nconst zh: typeof en = {\n nav: '工具搜索',\n topK: '默认结果数',\n alwaysVisible: '常驻白名单',\n neverSearch: '搜索黑名单',\n catalog: '工具目录',\n filter: '筛选工具',\n refresh: '刷新',\n tool: '工具',\n policy: '策略',\n selected: '活跃 Agent',\n defaultPolicy: '默认',\n alwaysPolicy: '常驻',\n blockedPolicy: '禁用',\n loading: '加载中...',\n empty: '没有匹配工具',\n saved: '已保存',\n onePerLine: '每行一个精确工具名',\n}\n\nconst EMPTY_SETTINGS: SettingsScopeSnapshot<ToolSearchSettings> = {\n status: 'unavailable',\n value: undefined,\n writable: false,\n}\n\nconst styles = `\n.dts-settings{container-type:inline-size;display:flex;flex-direction:column;gap:20px;width:100%;min-width:0;color:var(--dsw-alias-label-primary)}\n.dts-toolbar{display:grid;grid-template-columns:minmax(160px,220px) minmax(220px,1fr) auto;align-items:end;gap:12px}\n.dts-field{display:flex;flex-direction:column;gap:6px;min-width:0}\n.dts-field>span,.dts-section-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dts-input,.dts-textarea,.dts-select{box-sizing:border-box;width:100%;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit}\n.dts-input,.dts-select{height:34px;padding:0 9px}.dts-textarea{min-height:104px;padding:8px 9px;resize:vertical;line-height:20px}\n.dts-input:focus,.dts-textarea:focus,.dts-select:focus{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.dts-lists{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}\n.dts-hint{font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dts-button{height:34px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer}\n.dts-button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dts-button:disabled{opacity:.5;cursor:not-allowed}\n.dts-status{min-height:18px;font-size:12px;color:var(--dsw-alias-label-secondary)}.dts-status[data-error=true]{color:var(--dsw-alias-state-error-primary)}\n.dts-table-wrap{min-width:0;overflow:auto;border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2)}\n.dts-table{width:100%;min-width:620px;border-collapse:collapse;table-layout:fixed}\n.dts-table th,.dts-table td{box-sizing:border-box;padding:9px 10px;border-bottom:1px solid var(--dsw-alias-border-l1);text-align:left;vertical-align:middle;font-size:12px}\n.dts-table th{position:sticky;top:0;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font-weight:600}\n.dts-table tr:last-child td{border-bottom:0}.dts-tool{width:52%}.dts-tool code{display:block;overflow:hidden;text-overflow:ellipsis;overflow-wrap:anywhere;white-space:nowrap;color:var(--dsw-alias-label-primary)}\n.dts-description{display:block;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary)}\n.dts-policy{width:26%}.dts-selected{width:22%;color:var(--dsw-alias-label-secondary)}\n@container(max-width:620px){.dts-toolbar{grid-template-columns:1fr auto}.dts-toolbar .dts-limit{grid-column:1/-1}.dts-lists{grid-template-columns:1fr}.dts-table{min-width:0}.dts-table thead{display:none}.dts-table tr{display:grid;grid-template-columns:minmax(0,1fr) 132px;padding:8px 10px;border-bottom:1px solid var(--dsw-alias-border-l1)}.dts-table td{padding:4px 0;border:0}.dts-table .dts-tool,.dts-table .dts-policy{width:auto}.dts-table .dts-selected{grid-column:1/-1;width:auto;font-size:11px}.dts-table .dts-selected::before{content:attr(data-label) \": \";color:var(--dsw-alias-label-tertiary);font-weight:600}}\n`\n\nfunction namesFromText(value: string): string[] {\n return [...new Set(value.split(/\\r?\\n/u).map(name => name.trim()).filter(Boolean))].sort()\n}\n\nfunction overrideFor(name: string, settings: ToolSearchSettings): ToolPolicy | 'default' {\n if (settings.neverSearch.includes(name)) return 'blocked'\n if (settings.alwaysVisible.includes(name)) return 'always'\n return 'default'\n}\n\nfunction decodeCatalog(value: unknown): CatalogSnapshot {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('Invalid catalog response')\n const record = value as Record<string, unknown>\n if (record['schemaVersion'] !== 1 || !Array.isArray(record['tools']) || typeof record['generation'] !== 'number') {\n throw new Error('Invalid catalog response')\n }\n return value as CatalogSnapshot\n}\n\ntype SettingsProps = {\n scope?: SettingsScope<ToolSearchSettings>\n t?: Translate\n}\n\nexport function ToolSearchSettingsSection({ scope, t }: SettingsProps): ReactNode {\n const snapshot = useSyncExternalStore(\n useCallback((notify: () => void) => scope?.subscribe(notify) ?? (() => {}), [scope]),\n useCallback(() => scope?.getSnapshot() ?? EMPTY_SETTINGS, [scope]),\n )\n const [catalog, setCatalog] = useState<CatalogSnapshot>()\n const [filter, setFilter] = useState('')\n const [alwaysText, setAlwaysText] = useState('')\n const [blockedText, setBlockedText] = useState('')\n const [limitText, setLimitText] = useState(String(DEFAULT_RESULT_LIMIT))\n const [status, setStatus] = useState<{ text: string; error: boolean }>()\n const translate = t ?? ((key: keyof typeof en) => en[key])\n const settings = snapshot.value\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await fetch(TOOL_SEARCH_CATALOG_ROUTE, { cache: 'no-store' })\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n setCatalog(decodeCatalog(await response.json()))\n setStatus(undefined)\n } catch (error) {\n setStatus({ text: error instanceof Error ? error.message : String(error), error: true })\n }\n }, [])\n\n useEffect(() => { void refresh() }, [refresh])\n useEffect(() => {\n if (settings === undefined) return\n setAlwaysText(settings.alwaysVisible.join('\\n'))\n setBlockedText(settings.neverSearch.join('\\n'))\n setLimitText(String(settings.defaultLimit))\n }, [settings])\n\n const commit = useCallback((field: keyof ToolSearchSettings, value: unknown): void => {\n if (scope === undefined || !snapshot.writable) return\n setStatus(undefined)\n void scope.set(field, value).then(() => {\n setStatus({ text: translate('saved'), error: false })\n void refresh()\n }, error => {\n setStatus({ text: error instanceof Error ? error.message : String(error), error: true })\n })\n }, [refresh, scope, snapshot.writable, translate])\n\n const visibleTools = useMemo(() => {\n const query = filter.trim().toLowerCase()\n if (query.length === 0) return catalog?.tools ?? []\n return (catalog?.tools ?? []).filter(tool =>\n tool.name.toLowerCase().includes(query) || tool.description.toLowerCase().includes(query),\n )\n }, [catalog, filter])\n\n const changePolicy = (name: string, next: ToolPolicy | 'default'): void => {\n if (settings === undefined || name === TOOL_SEARCH_NAME) return\n const always = new Set(settings.alwaysVisible)\n const blocked = new Set(settings.neverSearch)\n always.delete(name)\n blocked.delete(name)\n if (next === 'always') always.add(name)\n if (next === 'blocked') blocked.add(name)\n commit('alwaysVisible', [...always].sort())\n commit('neverSearch', [...blocked].sort())\n }\n\n const core = new Set<string>(DEFAULT_CORE_TOOLS)\n return <div className=\"dts-settings\">\n <div className=\"dts-toolbar\">\n <label className=\"dts-field dts-limit\">\n <span>{translate('topK')}</span>\n <input\n className=\"dts-input\"\n type=\"number\"\n min={1}\n max={MAX_RESULT_LIMIT}\n value={limitText}\n disabled={!snapshot.writable}\n onChange={event => setLimitText(event.target.value)}\n onBlur={() => {\n const value = Number.parseInt(limitText, 10)\n if (Number.isSafeInteger(value) && value >= 1 && value <= MAX_RESULT_LIMIT) commit('defaultLimit', value)\n else setLimitText(String(settings?.defaultLimit ?? DEFAULT_RESULT_LIMIT))\n }}\n />\n </label>\n <label className=\"dts-field\">\n <span>{translate('filter')}</span>\n <input className=\"dts-input\" type=\"search\" value={filter} onChange={event => setFilter(event.target.value)} />\n </label>\n <button className=\"dts-button\" type=\"button\" onClick={() => { void refresh() }}>{translate('refresh')}</button>\n </div>\n\n <div className=\"dts-lists\">\n <label className=\"dts-field\">\n <span>{translate('alwaysVisible')}</span>\n <textarea\n className=\"dts-textarea\"\n value={alwaysText}\n disabled={!snapshot.writable}\n placeholder={translate('onePerLine')}\n onChange={event => setAlwaysText(event.target.value)}\n onBlur={() => commit('alwaysVisible', namesFromText(alwaysText))}\n />\n </label>\n <label className=\"dts-field\">\n <span>{translate('neverSearch')}</span>\n <textarea\n className=\"dts-textarea\"\n value={blockedText}\n disabled={!snapshot.writable}\n placeholder={translate('onePerLine')}\n onChange={event => setBlockedText(event.target.value)}\n onBlur={() => commit('neverSearch', namesFromText(blockedText).filter(name => name !== TOOL_SEARCH_NAME))}\n />\n </label>\n </div>\n\n <section className=\"dts-field\">\n <div className=\"dts-section-title\">{translate('catalog')}</div>\n <div className=\"dts-table-wrap\">\n <table className=\"dts-table\">\n <thead><tr>\n <th className=\"dts-tool\">{translate('tool')}</th>\n <th className=\"dts-policy\">{translate('policy')}</th>\n <th className=\"dts-selected\">{translate('selected')}</th>\n </tr></thead>\n <tbody>\n {visibleTools.map(tool => <tr key={tool.name}>\n <td className=\"dts-tool\">\n <code title={tool.name}>{tool.name}</code>\n {tool.description.length > 0 ? <span className=\"dts-description\" title={tool.description}>{tool.description}</span> : null}\n </td>\n <td className=\"dts-policy\">\n <select\n className=\"dts-select\"\n aria-label={`${translate('policy')}: ${tool.name}`}\n value={tool.name === TOOL_SEARCH_NAME ? 'always' : overrideFor(tool.name, settings ?? {\n defaultLimit: DEFAULT_RESULT_LIMIT,\n alwaysVisible: [],\n neverSearch: [],\n })}\n disabled={!snapshot.writable || tool.name === TOOL_SEARCH_NAME}\n onChange={event => changePolicy(tool.name, event.target.value as ToolPolicy | 'default')}\n >\n <option value=\"default\">{core.has(tool.name) ? `${translate('defaultPolicy')} (${translate('alwaysPolicy')})` : translate('defaultPolicy')}</option>\n <option value=\"always\">{translate('alwaysPolicy')}</option>\n <option value=\"blocked\">{translate('blockedPolicy')}</option>\n </select>\n </td>\n <td\n className=\"dts-selected\"\n data-label={translate('selected')}\n aria-label={`${translate('selected')}: ${tool.selectedBy.length}`}\n >{tool.selectedBy.length}</td>\n </tr>)}\n {catalog !== undefined && visibleTools.length === 0\n ? <tr><td colSpan={3}>{translate('empty')}</td></tr>\n : null}\n </tbody>\n </table>\n </div>\n <div className=\"dts-status\" data-error={status?.error || undefined}>\n {status?.text ?? (catalog === undefined ? translate('loading') : '')}\n </div>\n </section>\n </div>\n}\n\nexport const inject = ['slots', 'locale', 'settingsScope']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n if (document.querySelector('style[data-plugin-css=\"@anionex/dsh-tool-search\"]') !== null) return () => {}\n const tag = document.createElement('style')\n tag.dataset.pluginCss = '@anionex/dsh-tool-search'\n tag.textContent = styles\n document.head.append(tag)\n return () => tag.remove()\n }, 'dsh-tool-search: styles')\n ctx.effect(() => ctx.locale.register('settings.toolSearch', { en, zh }), 'dsh-tool-search: locale')\n const t = ctx.locale.bind('settings.toolSearch') as Translate\n const scope = ctx.settingsScope.bind<ToolSearchSettings>({ namespace: TOOL_SEARCH_SETTINGS_NAMESPACE })\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'tool-search',\n order: 34,\n label: () => t('nav'),\n inject: () => ({ scope, t }),\n }, ToolSearchSettingsSection))\n}\n"],"mappings":"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"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** DSH bundle entry for Codex-style deferred tool loading. */
|
|
2
|
+
import { ToolSearchRuntime } from "./runtime.js";
|
|
3
|
+
import { Config, TOOL_SEARCH_SETTINGS_NS } from "./settings.js";
|
|
4
|
+
import { installCatalogRoute } from "./web.js";
|
|
5
|
+
export const name = '@anionex/dsh-tool-search';
|
|
6
|
+
export const inject = ['agents', 'tools', 'systemPrompt', 'settings'];
|
|
7
|
+
export { Config };
|
|
8
|
+
export function apply(ctx, config) {
|
|
9
|
+
const settings = ctx.settings.register(TOOL_SEARCH_SETTINGS_NS, Config, {
|
|
10
|
+
base: config,
|
|
11
|
+
applies: 'live',
|
|
12
|
+
});
|
|
13
|
+
const runtime = new ToolSearchRuntime(ctx, settings.get());
|
|
14
|
+
ctx.tools.register(runtime.definition);
|
|
15
|
+
ctx.effect(() => runtime.install(), 'dsh-tool-search: agent visibility');
|
|
16
|
+
ctx.effect(() => settings.watch(next => { runtime.updateSettings(next); }), 'dsh-tool-search: settings');
|
|
17
|
+
installCatalogRoute(ctx, runtime);
|
|
18
|
+
}
|
|
19
|
+
export { Bm25Index, tokenize } from "./bm25.js";
|
|
20
|
+
export { appendSchemaSearchText, buildCatalog, toolSearchText } from "./catalog.js";
|
|
21
|
+
export { ToolSearchRuntime } from "./runtime.js";
|
|
22
|
+
export { normalizeSettings, ToolPolicyResolver } from "./settings.js";
|
|
23
|
+
export * from "./shared.js";
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAM9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAE9C,MAAM,CAAC,MAAM,IAAI,GAAG,0BAA0B,CAAA;AAC9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,CAAC,CAAA;AACrE,OAAO,EAAE,MAAM,EAAE,CAAA;AAEjB,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAA0B;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,EAAE;QACtE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAA;IAC1D,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,mCAAmC,CAAC,CAAA;IACxE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAAA;IACvG,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AACnC,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACrE,cAAc,aAAa,CAAA"}
|