dsh-locator 0.13.0 → 0.14.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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.0 — 2026-11-14
4
+
5
+ * **Capability adapter (Wave 3, part 1)**: new tools `capability_search(intent, kinds?, riskMax?, ...)` and `capability_preflight(capability, argsJson?)` index the **live** DSH registries — tool definitions (including `mcp__<server>__<tool>` entries) and the skill catalog — and add intent matching, inferred risk (read/write/exec plus approval/sandbox hints), argument-schema validation and side-effect reporting. It reads `ctx.tools.definitions()` / `ctx.skills.list()`; it does not duplicate discovery and has no embedding dependency.
6
+ * Snapshot cache (60 s) and graceful degradation: a missing skill service or registry produces warnings instead of breaking the tool.
7
+ * `171 tests`; six engine binaries rebuilt at 0.14.0.
8
+ * Deferred and explicitly documented: refs persistence plus URL/spill/attachment refs and the panel ref chip (Wave 2), the panel capability view (Wave 3 UI), and tenant/enterprise packaging (blocked on a real dsh-ee instance and credentials).
9
+
3
10
  ## 0.13.0 — 2026-11-14
4
11
 
5
12
  * **Authorization fix**: `locator_find` no longer lets `sessionId`, `scope: "all"` or `pathPrefix` bypass the caller's identity. An explicit session id is allowed only for the caller session or sessions whose immutable `cwd` equals the caller cwd (the same rule as DSH's session-query tools); `pathPrefix` must resolve inside the configured roots; `scope: "all"` still searches every indexed file but keeps session documents inside the caller's authorized set unless the new `allowCrossWorkspaceSessions: true` is configured.
package/README-es.md CHANGED
@@ -403,6 +403,11 @@ DeepSeek Harness
403
403
 
404
404
  El motor es un único proceso Go y respeta las variables estándar `GOMEMLIMIT` y `GOGC` (o `memoryLimitMB` en la configuración). Un índice de 1,2–1,5 M de entradas alcanza varios cientos de MB de RSS con el GC por defecto; usa `GOMEMLIMIT=600MiB` (límite blando, el runtime cambia CPU por memoria) o `GOGC=50` cuando el host vaya justo de RAM. Ninguno cambia el formato de la instantánea. En la instalación en vivo usada para las cifras anteriores, el proceso anfitrión de DSH (incluida la caché de páginas de la base de contenido) rondaba los 700 MB de RSS con el índice construido, y la latencia del host en reposo se mantenía en p50 2 ms.
405
405
 
406
+ ## Notas de actualización 0.14.0
407
+
408
+ - **Adaptador de capacidades**: `capability_search` (encontrar "quién puede hacer esto" desde una intención) y `capability_preflight` (visibilidad, validación del esquema de argumentos, aprobación/sandbox y efectos secundarios) leen el registro de herramientas en vivo (incluidas acciones MCP) y el catálogo de skills. Sin descubrimiento duplicado ni embeddings; refresco cada 60 s.
409
+ - Primera parte de Wave 3; la vista de capacidades en el panel, el empaquetado multi-tenant/empresa y los refs persistentes de Wave 2 quedan para versiones posteriores.
410
+
406
411
  ## Notas de actualización 0.13.0
407
412
 
408
413
  - **Corrección de autorización**: `locator_find` ya no permite que `sessionId`, `scope:"all"` o `pathPrefix` eludan la identidad del llamador. Un id de sesión explícito solo se acepta para la sesión del llamador o sesiones cuyo `cwd` inmutable coincide (misma regla que las herramientas session-query de DSH); `pathPrefix` debe resolver dentro de los roots configurados; `scope:"all"` sigue buscando todos los archivos pero limita las sesiones al conjunto autorizado salvo `allowCrossWorkspaceSessions: true`.
package/README-hi.md CHANGED
@@ -404,6 +404,11 @@ DeepSeek Harness
404
404
 
405
405
  इंजन एक Go प्रोसेस है और मानक `GOMEMLIMIT` और `GOGC` (या कॉन्फ़िग में `memoryLimitMB`) मानता है। 1.2–1.5 M एंट्री का इंडेक्स डिफ़ॉल्ट GC के साथ कई सौ MB RSS तक जाता है; होस्ट पर RAM कम हो तो `GOMEMLIMIT=600MiB` (सॉफ़्ट सीमा, रनटाइम CPU देकर मेमोरी बचाता है) या `GOGC=50` रखें। इनसे स्नैपशॉट फ़ॉर्मेट नहीं बदलता। ऊपर के आँकड़ों वाले लाइव सेटअप में DSH होस्ट प्रोसेस (कंटेंट डेटाबेस पेज कैश सहित) इंडेक्स बने रहने पर लगभग 700 MB RSS पर था, और खाली बैठे होस्ट की देरी p50 2ms रही।
406
406
 
407
+ ## 0.14.0 अपग्रेड नोट्स
408
+
409
+ - **क्षमता अनुकूलक (capability adapter)**: `capability_search` (स्वाभाविक भाषा में "यह कौन कर सकता है" खोजें) और `capability_preflight` (दृश्यता, argument schema जाँच, approval/sandbox आवश्यकताएँ, side effects) होस्ट के live tool registry (MCP actions सहित) और skill catalog से पढ़ते हैं। कोई दोहरा discovery या embedding नहीं; snapshot हर 60 s में ताज़ा।
410
+ - यह Wave 3 का पहला भाग है; panel capability view, tenant/enterprise packaging और Wave 2 के refs persistence/URL·spill·attachment refs आगे के संस्करणों में।
411
+
407
412
  ## 0.13.0 अपग्रेड नोट्स
408
413
 
409
414
  - **अधिकार सुधार**: `locator_find` अब `sessionId`, `scope:"all"` या `pathPrefix` को कॉलर की पहचान बायपास करने नहीं देता। स्पष्ट session id केवल कॉलर सत्र या जिनका अपरिवर्तनीय `cwd` कॉलर के बराबर है (DSH session-query नियम) के लिए मान्य है; `pathPrefix` कॉन्फ़िगर किए roots के अंदर होना चाहिए; `scope:"all"` सभी फ़ाइलें खोजता है पर सत्र पंक्तियाँ कॉलर के अधिकृत सेट तक सीमित रहती हैं जब तक `allowCrossWorkspaceSessions: true` न हो।
package/README-pt.md CHANGED
@@ -404,6 +404,11 @@ DeepSeek Harness
404
404
 
405
405
  O motor é um único processo Go e respeita as variáveis padrão `GOMEMLIMIT` e `GOGC` (ou `memoryLimitMB` na configuração). Um índice de 1,2–1,5 M de entradas chega a várias centenas de MB de RSS com o GC padrão; use `GOMEMLIMIT=600MiB` (limite suave, o runtime troca CPU por memória) ou `GOGC=50` quando o host estiver apertado de RAM. Nenhum altera o formato do snapshot. Na instalação ao vivo usada para os números acima, o processo anfitrião do DSH (incluindo o cache de páginas do banco de conteúdo) ficava por volta de 700 MB de RSS com o índice construído, e a latência do host ocioso permanecia em p50 2 ms.
406
406
 
407
+ ## Notas de atualização 0.14.0
408
+
409
+ - **Adaptador de capacidades**: `capability_search` (encontrar "quem pode fazer isso" a partir de uma intenção) e `capability_preflight` (visibilidade, validação de schema dos argumentos, aprovação/sandbox e efeitos colaterais) leem o registro de ferramentas ao vivo (incluindo ações MCP) e o catálogo de skills. Sem descoberta duplicada e sem embeddings; atualização a cada 60 s.
410
+ - Primeira parte da Wave 3; a visão de capacidades no painel, o empacotamento multi-tenant/empresa e os refs persistentes da Wave 2 ficam para versões futuras.
411
+
407
412
  ## Notas de atualização 0.13.0
408
413
 
409
414
  - **Correção de autorização**: `locator_find` não deixa mais `sessionId`, `scope:"all"` ou `pathPrefix` contornarem a identidade do chamador. Um id de sessão explícito só é aceito para a sessão do chamador ou sessões cujo `cwd` imutável coincide (mesma regra das ferramentas session-query do DSH); `pathPrefix` deve resolver dentro dos roots configurados; `scope:"all"` continua buscando todos os arquivos mas limita as sessões ao conjunto autorizado, salvo `allowCrossWorkspaceSessions: true`.
package/README.en.md CHANGED
@@ -404,6 +404,11 @@ DeepSeek Harness
404
404
 
405
405
  The engine is a single Go process and honours the standard `GOMEMLIMIT` and `GOGC` environment variables (or `memoryLimitMB` in the config). A 1.2–1.5 M-entry index peaks around several hundred MB of RSS with the default GC; set `GOMEMLIMIT=600MiB` (soft limit, the runtime trades CPU for memory) or `GOGC=50` when the host is tight on RAM. Neither changes the snapshot format. In the live setup used for the numbers above, the DSH host process (including the content database page cache) sat around 700 MB RSS with the content index built, and idle host latency stayed at p50 2 ms.
406
406
 
407
+ ## 0.14.0 upgrade notes
408
+
409
+ - **Capability adapter**: `capability_search` (find "who can do this" from a natural-language intent) and `capability_preflight` (visibility, argument-schema validation, approval/sandbox requirements and side effects) read the host's live tool registry (including MCP actions) and skill catalog. No duplicate discovery and no embedding model; snapshots refresh every 60 s.
410
+ - This is part 1 of Wave 3. The panel capability view, tenancy/enterprise packaging (needs a real dsh-ee instance and credentials) and the Wave 2 refs persistence/URL·spill·attachment refs remain future work.
411
+
407
412
  ## 0.13.0 upgrade notes
408
413
 
409
414
  - **Authorization fix**: `locator_find` no longer lets `sessionId`, `scope: "all"` or `pathPrefix` bypass the caller identity. An explicit session id is allowed only for the caller session or sessions whose immutable `cwd` equals the caller cwd (same rule as DSH's session-query tools); `pathPrefix` must resolve inside the configured roots; `scope: "all"` still searches every indexed file but keeps session bodies inside the caller's authorized set unless `allowCrossWorkspaceSessions: true` is configured.
package/README.md CHANGED
@@ -366,6 +366,11 @@ Go 引擎在 `engine/` 下,测试用 `cd engine && go test ./...`。macOS 的
366
366
  - 当前会话范围只覆盖已落定索引的会话消息(活跃会话约 2 分钟延迟);实时查找用 `Ctrl+F`。会话内查找条只覆盖已加载窗口,更早历史需手动加载。
367
367
  - 会话内高亮依赖 CSS Custom Highlight API;不支持它的旧浏览器会退化为整行描边。
368
368
 
369
+ ## 0.14.0 更新
370
+
371
+ - **能力索引适配器**:新增 `capability_search`(自然语言找“谁能做这件事”)与 `capability_preflight`(能力是否可见、参数是否符合 schema、需要什么审批/沙箱、有哪些副作用);数据来自宿主已有的 tool registry(含 MCP 工具)与 skill catalog,不重复发现、不用 embedding,60s 自动刷新。
372
+ - 本版是 Wave 3 的第一部分;面板能力页、租户/企业包,以及 Wave 2 的 refs 持久化/URL·spill·attachment ref 留待后续版本(企业包需 dsh-ee 实例与凭据)。
373
+
369
374
  ## 0.13.0 更新
370
375
 
371
376
  - **授权修复**:`locator_find` 的 `sessionId`/`scope:"all"`/`pathPrefix` 不再绕过调用方身份——显式会话 id 只允许「当前会话」或「header.cwd 与调用方相同的会话」(与 DSH session-query 工具一致);`pathPrefix` 必须落在已配置 root 内;`scope:"all"` 仍可搜全部文件,但会话正文默认限调用方授权集合(`allowCrossWorkspaceSessions: true` 可显式放开)。
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Capability index: which tool/skill/MCP action can do a job, what it costs and
3
+ * what it may touch. This is a thin adapter over the DSH registries the host
4
+ * already keeps (tool definitions, skill catalog): it does not re-implement
5
+ * discovery, it adds intent matching, risk labels and a preflight check.
6
+ * @module dsh-locator/capabilities
7
+ */
8
+ import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
9
+ /** One capability card. */
10
+ export interface CapabilityCard {
11
+ id: string;
12
+ kind: 'tool' | 'mcp' | 'skill';
13
+ name: string;
14
+ summary: string;
15
+ input?: Record<string, unknown>;
16
+ tags: string[];
17
+ risk: {
18
+ level: 'read' | 'write' | 'exec';
19
+ actions: string[];
20
+ basis: 'schema' | 'name';
21
+ };
22
+ permission: {
23
+ approval: 'none' | 'ask';
24
+ sandbox: 'none' | 'write' | 'any';
25
+ };
26
+ state: 'available' | 'unknown';
27
+ source: 'tools' | 'skills';
28
+ }
29
+ /** One snapshot of the live capability surface. */
30
+ export interface CapabilitySnapshot {
31
+ builtAt: number;
32
+ cards: CapabilityCard[];
33
+ warnings: string[];
34
+ }
35
+ /** Minimal shape of the host services this module reads. */
36
+ export interface CapabilitySources {
37
+ tools?: {
38
+ definitions?: (scope?: unknown, toolSet?: unknown) => readonly unknown[];
39
+ get?: (name: string, scope?: unknown) => unknown;
40
+ } | undefined;
41
+ skills?: {
42
+ list?: (options?: Record<string, unknown>) => Promise<readonly unknown[]>;
43
+ } | undefined;
44
+ }
45
+ /** Tokenize one intent/name for the lexical scorer (letters, digits, CJK). */
46
+ export declare function tokenize(text: string): string[];
47
+ /** Infer risk/permission from a tool name, description and parameter schema. */
48
+ export declare function inferRisk(name: string, description: string, parameters?: Record<string, unknown>): CapabilityCard['risk'] & {
49
+ permission: CapabilityCard['permission'];
50
+ };
51
+ /** Build one capability snapshot from the live host services. */
52
+ export declare function buildCapabilitySnapshot(sources: CapabilitySources, scope?: unknown): Promise<CapabilitySnapshot>;
53
+ /** Card projection returned by tools: drop the full input schema payload. */
54
+ export declare function publicCard(card: CapabilityCard): Omit<CapabilityCard, 'input'>;
55
+ /** One ranked capability hit. */
56
+ export interface CapabilityHit {
57
+ card: CapabilityCard;
58
+ score: number;
59
+ why: string[];
60
+ }
61
+ /**
62
+ * Rank capability cards against an intent and optional filters.
63
+ * @param cards - snapshot cards.
64
+ * @param intent - what the caller wants to do.
65
+ * @param options - kind/risk filters and pagination.
66
+ * @returns ranked hits and the total before paging.
67
+ */
68
+ export declare function searchCapabilities(cards: readonly CapabilityCard[], intent: string, options?: {
69
+ kinds?: readonly CapabilityCard['kind'][];
70
+ riskMax?: 'read' | 'write' | 'exec';
71
+ limit?: number;
72
+ offset?: number;
73
+ availableOnly?: boolean;
74
+ }): {
75
+ hits: CapabilityHit[];
76
+ total: number;
77
+ };
78
+ /** One preflight result. */
79
+ export interface PreflightResult {
80
+ ok: boolean;
81
+ card?: CapabilityCard;
82
+ admitted: boolean;
83
+ schema?: {
84
+ valid: boolean;
85
+ violations: string[];
86
+ };
87
+ requires: {
88
+ approval: 'none' | 'ask';
89
+ sandbox: 'none' | 'write' | 'any';
90
+ };
91
+ sideEffects: string[];
92
+ next: {
93
+ callable: boolean;
94
+ suggestion?: string;
95
+ };
96
+ error?: string;
97
+ warnings: string[];
98
+ }
99
+ /**
100
+ * Check whether one capability can be called with the given arguments right
101
+ * now: existence/visibility, argument schema, predicted approval/sandbox and
102
+ * side effects. It never executes the target.
103
+ */
104
+ export declare function preflightCapability(snapshot: CapabilitySnapshot, target: string, args?: Record<string, unknown>, sources?: CapabilitySources, scope?: unknown): PreflightResult;
105
+ /** Build `capability_search` and `capability_preflight` bound to the host registries. */
106
+ export declare function makeCapabilityTools(sources: CapabilitySources): readonly [import("@deepseek-ai/dsh-tools").ToolDefinition, import("@deepseek-ai/dsh-tools").ToolDefinition];
107
+ /** ToolRunContext re-export keeps the module self-describing for tests. */
108
+ export type { ToolRunContext };
109
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Capability index: which tool/skill/MCP action can do a job, what it costs and
3
+ * what it may touch. This is a thin adapter over the DSH registries the host
4
+ * already keeps (tool definitions, skill catalog): it does not re-implement
5
+ * discovery, it adds intent matching, risk labels and a preflight check.
6
+ * @module dsh-locator/capabilities
7
+ */
8
+ import { defineTool, validateJsonSchemaValue } from '@deepseek-ai/dsh-tools';
9
+ const WRITE_WORDS = ['write', 'edit', 'delete', 'remove', 'move', 'rename', 'mkdir', 'install', 'uninstall', 'publish', 'patch', 'apply'];
10
+ const EXEC_WORDS = ['bash', 'shell', 'execute', 'terminal', 'run_code', 'spawn', 'command'];
11
+ const ALIASES = {
12
+ 文件: ['file', 'files', 'path'], 搜索: ['search', 'find', 'grep'], 写: ['write', 'edit'], 删除: ['delete', 'remove'],
13
+ 运行: ['run', 'exec', 'bash'], 命令: ['command', 'shell'], 网页: ['web', 'http', 'url'], 截图: ['screenshot', 'screen'],
14
+ 测试: ['test'], 安装: ['install'], 插件: ['plugin'], 技能: ['skill'], 工具: ['tool'],
15
+ };
16
+ /** Tokenize one intent/name for the lexical scorer (letters, digits, CJK). */
17
+ export function tokenize(text) {
18
+ const lowered = text.toLowerCase();
19
+ const ascii = lowered.match(/[a-z0-9_]{2,}/g) ?? [];
20
+ const cjk = lowered.match(/[\u4e00-\u9fff]{2}/g) ?? [];
21
+ const expanded = [...ascii, ...cjk];
22
+ for (const [key, values] of Object.entries(ALIASES)) {
23
+ if (lowered.includes(key))
24
+ expanded.push(...values);
25
+ }
26
+ return [...new Set(expanded)];
27
+ }
28
+ /** Infer risk/permission from a tool name, description and parameter schema. */
29
+ export function inferRisk(name, description, parameters) {
30
+ const haystack = `${name} ${description}`.toLowerCase();
31
+ const properties = parameters !== undefined && typeof parameters === 'object' && parameters !== null && typeof parameters.properties === 'object'
32
+ ? Object.keys(parameters.properties)
33
+ : [];
34
+ const actions = [];
35
+ let level = 'read';
36
+ if (EXEC_WORDS.some(word => haystack.includes(word)) || properties.includes('command') || properties.includes('cmd')) {
37
+ level = 'exec';
38
+ actions.push('may execute a process');
39
+ }
40
+ if (WRITE_WORDS.some(word => haystack.includes(word)) || properties.includes('content') || properties.includes('sandbox_permissions')) {
41
+ if (level !== 'exec')
42
+ level = 'write';
43
+ actions.push('may modify state');
44
+ }
45
+ if (properties.includes('sandbox_permissions'))
46
+ actions.push('can request escalated sandbox permissions');
47
+ return {
48
+ level,
49
+ actions: [...new Set(actions)],
50
+ basis: properties.length > 0 ? 'schema' : 'name',
51
+ permission: { approval: level === 'read' ? 'none' : 'ask', sandbox: level === 'read' ? 'none' : level === 'exec' ? 'any' : 'write' },
52
+ };
53
+ }
54
+ /** Convert one DSH ToolDefinition into a capability card. */
55
+ function toolCard(definition) {
56
+ if (typeof definition !== 'object' || definition === null)
57
+ return undefined;
58
+ const record = definition;
59
+ if (typeof record.name !== 'string' || record.name === '')
60
+ return undefined;
61
+ const name = record.name;
62
+ const description = typeof record.description === 'string' ? record.description : '';
63
+ const parameters = typeof record.parameters === 'object' && record.parameters !== null ? record.parameters : undefined;
64
+ const risk = inferRisk(name, description, parameters);
65
+ const mcpParts = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(name);
66
+ const kind = mcpParts !== null ? 'mcp' : 'tool';
67
+ const display = mcpParts !== null ? `${mcpParts[1]}/${mcpParts[2]}` : name;
68
+ return {
69
+ id: kind === 'mcp' ? `mcp:${display}` : `tool:${name}`,
70
+ kind,
71
+ name: display,
72
+ summary: description.split('\n')[0]?.slice(0, 240) ?? '',
73
+ ...(parameters === undefined ? {} : { input: parameters }),
74
+ tags: tokenize(`${name} ${description}`).slice(0, 12),
75
+ risk: { level: risk.level, actions: risk.actions, basis: risk.basis },
76
+ permission: risk.permission,
77
+ state: 'available',
78
+ source: 'tools',
79
+ };
80
+ }
81
+ /** Convert one SkillSummary into a capability card. */
82
+ function skillCard(skill) {
83
+ if (typeof skill !== 'object' || skill === null)
84
+ return undefined;
85
+ const record = skill;
86
+ if (typeof record.name !== 'string' || record.name === '')
87
+ return undefined;
88
+ const summary = `${typeof record.description === 'string' ? record.description : ''}${typeof record.whenToUse === 'string' ? ` · ${record.whenToUse}` : ''}`.trim();
89
+ const invocation = typeof record.invocation === 'object' && record.invocation !== null ? record.invocation : undefined;
90
+ return {
91
+ id: `skill:${record.name}`,
92
+ kind: 'skill',
93
+ name: record.name,
94
+ summary: summary.slice(0, 240),
95
+ tags: tokenize(`${record.name} ${summary}`).slice(0, 12),
96
+ risk: { level: 'read', actions: ['loads instructions, no direct side effects'], basis: 'name' },
97
+ permission: { approval: 'none', sandbox: 'none' },
98
+ state: invocation?.modelInvocable === false ? 'unknown' : 'available',
99
+ source: 'skills',
100
+ };
101
+ }
102
+ /** Build one capability snapshot from the live host services. */
103
+ export async function buildCapabilitySnapshot(sources, scope) {
104
+ const warnings = [];
105
+ const cards = [];
106
+ try {
107
+ const definitions = sources.tools?.definitions?.(scope) ?? [];
108
+ for (const definition of definitions) {
109
+ const card = toolCard(definition);
110
+ if (card !== undefined)
111
+ cards.push(card);
112
+ }
113
+ }
114
+ catch (error) {
115
+ warnings.push(`tool-catalog-unavailable: ${error instanceof Error ? error.message : String(error)}`);
116
+ }
117
+ if (sources.skills?.list !== undefined) {
118
+ try {
119
+ const skills = await sources.skills.list(scope === undefined ? {} : { scope });
120
+ for (const skill of skills) {
121
+ const card = skillCard(skill);
122
+ if (card !== undefined)
123
+ cards.push(card);
124
+ }
125
+ }
126
+ catch (error) {
127
+ warnings.push(`skill-catalog-unavailable: ${error instanceof Error ? error.message : String(error)}`);
128
+ }
129
+ }
130
+ else {
131
+ warnings.push('skill-service-unavailable');
132
+ }
133
+ cards.sort((left, right) => left.id.localeCompare(right.id));
134
+ return { builtAt: Date.now(), cards, warnings };
135
+ }
136
+ /** Card projection returned by tools: drop the full input schema payload. */
137
+ export function publicCard(card) {
138
+ const { input: _input, ...rest } = card;
139
+ return rest;
140
+ }
141
+ /**
142
+ * Rank capability cards against an intent and optional filters.
143
+ * @param cards - snapshot cards.
144
+ * @param intent - what the caller wants to do.
145
+ * @param options - kind/risk filters and pagination.
146
+ * @returns ranked hits and the total before paging.
147
+ */
148
+ export function searchCapabilities(cards, intent, options = {}) {
149
+ const terms = tokenize(intent);
150
+ const limit = Math.max(1, Math.min(50, options.limit ?? 10));
151
+ const offset = Math.max(0, options.offset ?? 0);
152
+ const matches = cards.filter(card => {
153
+ if (options.kinds !== undefined && options.kinds.length > 0 && !options.kinds.includes(card.kind))
154
+ return false;
155
+ if (options.availableOnly === true && card.state !== 'available')
156
+ return false;
157
+ if (options.riskMax !== undefined) {
158
+ const order = { read: 0, write: 1, exec: 2 };
159
+ if (order[card.risk.level] > order[options.riskMax])
160
+ return false;
161
+ }
162
+ return true;
163
+ });
164
+ const scored = [];
165
+ for (const card of matches) {
166
+ const haystack = tokenize(`${card.name} ${card.summary} ${card.tags.join(' ')}`);
167
+ const why = [];
168
+ let score = 0;
169
+ for (const term of terms) {
170
+ if (card.name.toLowerCase().includes(term)) {
171
+ score += 6;
172
+ why.push(`name:${term}`);
173
+ continue;
174
+ }
175
+ if (haystack.includes(term)) {
176
+ score += 2;
177
+ why.push(`text:${term}`);
178
+ }
179
+ }
180
+ if (terms.length === 0) {
181
+ score = 1;
182
+ why.push('intent-empty: lists capabilities');
183
+ }
184
+ if (score > 0)
185
+ scored.push({ card, score, why: why.slice(0, 6) });
186
+ }
187
+ scored.sort((left, right) => right.score - left.score || left.card.id.localeCompare(right.card.id));
188
+ return { hits: scored.slice(offset, offset + limit), total: scored.length };
189
+ }
190
+ /**
191
+ * Check whether one capability can be called with the given arguments right
192
+ * now: existence/visibility, argument schema, predicted approval/sandbox and
193
+ * side effects. It never executes the target.
194
+ */
195
+ export function preflightCapability(snapshot, target, args, sources, scope) {
196
+ const normalized = target.trim();
197
+ const card = snapshot.cards.find(entry => entry.id === normalized || entry.name === normalized || entry.id === `tool:${normalized}` || entry.id === `mcp:${normalized}` || entry.id === `skill:${normalized}`);
198
+ if (card === undefined) {
199
+ return { ok: false, admitted: false, requires: { approval: 'none', sandbox: 'none' }, sideEffects: [], next: { callable: false }, error: 'capability-not-found', warnings: [] };
200
+ }
201
+ const warnings = [...snapshot.warnings];
202
+ let visible = true;
203
+ if (card.kind !== 'skill' && sources?.tools?.get !== undefined) {
204
+ try {
205
+ visible = sources.tools.get(card.kind === 'mcp' ? card.name.replace('/', '__') : card.name, scope) !== undefined;
206
+ }
207
+ catch {
208
+ visible = true;
209
+ }
210
+ }
211
+ let schema;
212
+ if (args !== undefined && card.input !== undefined) {
213
+ try {
214
+ const violations = validateJsonSchemaValue(card.input, args);
215
+ schema = { valid: violations.length === 0, violations };
216
+ }
217
+ catch (error) {
218
+ schema = { valid: false, violations: [error instanceof Error ? error.message : String(error)] };
219
+ }
220
+ }
221
+ const callable = visible && (schema?.valid ?? true);
222
+ const suggestion = callable
223
+ ? undefined
224
+ : !visible
225
+ ? 'capability is registered but not visible in this agent scope'
226
+ : schema?.valid === false
227
+ ? 'fix the arguments against the declared schema'
228
+ : 'capability is not callable from this scope';
229
+ return {
230
+ ok: true,
231
+ card: publicCard(card),
232
+ admitted: callable,
233
+ ...(schema === undefined ? {} : { schema }),
234
+ requires: card.permission,
235
+ sideEffects: card.risk.actions,
236
+ next: { callable, ...(suggestion === undefined ? {} : { suggestion }) },
237
+ warnings,
238
+ };
239
+ }
240
+ const CARD_SCHEMA = {
241
+ type: 'object',
242
+ additionalProperties: false,
243
+ properties: {
244
+ id: { type: 'string' }, kind: { type: 'string', enum: ['tool', 'mcp', 'skill'] },
245
+ name: { type: 'string' }, summary: { type: 'string' },
246
+ tags: { type: 'array', items: { type: 'string' } },
247
+ risk: { type: 'object', additionalProperties: false, properties: { level: { type: 'string' }, actions: { type: 'array', items: { type: 'string' } }, basis: { type: 'string' } } },
248
+ permission: { type: 'object', additionalProperties: false, properties: { approval: { type: 'string' }, sandbox: { type: 'string' } } },
249
+ state: { type: 'string' }, source: { type: 'string' },
250
+ },
251
+ };
252
+ /** Build `capability_search` and `capability_preflight` bound to the host registries. */
253
+ export function makeCapabilityTools(sources) {
254
+ let cached;
255
+ const snapshotFor = async (scope) => {
256
+ if (cached === undefined || Date.now() - cached.builtAt > 60_000)
257
+ cached = await buildCapabilitySnapshot(sources, scope);
258
+ return cached;
259
+ };
260
+ const searchTool = defineTool({
261
+ name: 'capability_search',
262
+ description: [
263
+ 'Find the tool, MCP action or skill that can do a job (dsh-locator capability adapter).',
264
+ '',
265
+ 'Use it when the caller knows the goal but not which capability performs it: pass the intent in natural language and filter by kind/risk. Every hit carries risk and permission hints plus the card id usable with `capability_preflight`.',
266
+ '',
267
+ 'This is not a file search: it indexes the live DSH capability registry (tool definitions and the skill catalog), not file names or bodies.',
268
+ ].join('\n'),
269
+ parameters: {
270
+ intent: { type: 'string', required: true, description: 'What should be done, in natural language (English or Chinese).' },
271
+ kinds: { type: 'array', items: { type: 'string', enum: ['tool', 'mcp', 'skill'] }, description: 'Restrict to these capability kinds.' },
272
+ riskMax: { type: 'string', enum: ['read', 'write', 'exec'], description: 'Only return capabilities at or below this risk level.' },
273
+ availableOnly: { type: 'boolean', description: 'Only return cards that are currently visible/available.' },
274
+ limit: { type: 'integer', description: 'Maximum hits (default 10, at most 50).' },
275
+ offset: { type: 'integer', description: 'Skip this many ranked hits.' },
276
+ },
277
+ output: {
278
+ schema: {
279
+ type: 'object',
280
+ additionalProperties: false,
281
+ properties: {
282
+ ok: { type: 'boolean', required: true },
283
+ intent: { type: 'string' }, total: { type: 'integer' }, returned: { type: 'integer' },
284
+ hits: { type: 'array', items: { type: 'object', additionalProperties: false, properties: { card: CARD_SCHEMA, score: { type: 'number' }, why: { type: 'array', items: { type: 'string' } } } } },
285
+ warnings: { type: 'array', items: { type: 'string' } }, error: { type: 'string' },
286
+ },
287
+ },
288
+ render: (_args, value) => {
289
+ const v = value;
290
+ if (!v.ok)
291
+ return [{ type: 'text', text: `capability_search failed: ${v.error ?? 'unknown error'}` }];
292
+ const lines = [`capability_search ${JSON.stringify(v.intent ?? '')}: ${String(v.total ?? 0)} match(es)`];
293
+ for (const hit of v.hits ?? []) {
294
+ lines.push(`- ${hit.card.id} [${hit.card.kind}] risk=${hit.card.risk.level} approval=${hit.card.permission.approval} — ${hit.card.summary}`);
295
+ }
296
+ if ((v.warnings ?? []).length > 0)
297
+ lines.push(`warnings: ${[...new Set(v.warnings ?? [])].join(', ')}`);
298
+ return [{ type: 'text', text: lines.join('\n') }];
299
+ },
300
+ },
301
+ async execute(args, exec) {
302
+ const snapshot = await snapshotFor(exec?.agent);
303
+ const kinds = Array.isArray(args.kinds) ? args.kinds.filter((kind) => kind === 'tool' || kind === 'mcp' || kind === 'skill') : undefined;
304
+ const riskMax = args.riskMax === 'read' || args.riskMax === 'write' || args.riskMax === 'exec' ? args.riskMax : undefined;
305
+ const result = searchCapabilities(snapshot.cards, args.intent, { ...(kinds === undefined ? {} : { kinds }), ...(riskMax === undefined ? {} : { riskMax }), limit: Math.max(1, Math.min(50, args.limit ?? 10)), offset: Math.max(0, args.offset ?? 0), availableOnly: args.availableOnly === true });
306
+ const hits = result.hits.map(hit => ({ ...hit, card: publicCard(hit.card) }));
307
+ return { ok: true, intent: args.intent, total: result.total, returned: hits.length, hits, warnings: snapshot.warnings };
308
+ },
309
+ });
310
+ const preflightTool = defineTool({
311
+ name: 'capability_preflight',
312
+ description: [
313
+ 'Check one capability before calling it (dsh-locator capability adapter): whether it exists and is visible, whether the arguments match its declared schema, and which approval/sandbox/side effects it implies.',
314
+ '',
315
+ 'It never executes the target. Use it when a plan depends on a tool/MCP action/skill and the caller needs to know the cost or permission risk first.',
316
+ ].join('\n'),
317
+ parameters: {
318
+ capability: { type: 'string', required: true, description: 'Card id (`tool:<name>`, `mcp:<server>/<action>`, `skill:<name>`) or plain name from capability_search.' },
319
+ argsJson: { type: 'string', description: 'Candidate arguments as a JSON object string to validate against the declared schema.' },
320
+ },
321
+ output: {
322
+ schema: {
323
+ type: 'object',
324
+ additionalProperties: false,
325
+ properties: {
326
+ ok: { type: 'boolean', required: true },
327
+ card: CARD_SCHEMA,
328
+ admitted: { type: 'boolean' },
329
+ schema: { type: 'object', additionalProperties: false, properties: { valid: { type: 'boolean' }, violations: { type: 'array', items: { type: 'string' } } } },
330
+ requires: { type: 'object', additionalProperties: false, properties: { approval: { type: 'string' }, sandbox: { type: 'string' } } },
331
+ sideEffects: { type: 'array', items: { type: 'string' } },
332
+ next: { type: 'object', additionalProperties: false, properties: { callable: { type: 'boolean' }, suggestion: { type: 'string' } } },
333
+ error: { type: 'string' }, warnings: { type: 'array', items: { type: 'string' } },
334
+ },
335
+ },
336
+ render: (_args, value) => {
337
+ const v = value;
338
+ if (!v.ok)
339
+ return [{ type: 'text', text: `capability_preflight failed: ${v.error ?? 'unknown error'}` }];
340
+ const lines = [
341
+ `capability_preflight ${v.card?.id ?? ''}: callable=${String(v.next?.callable ?? v.admitted ?? false)}`,
342
+ ` risk: ${v.card?.risk.level ?? '?'} · approval=${v.requires?.approval ?? '?'} · sandbox=${v.requires?.sandbox ?? '?'}`,
343
+ ` schema: ${v.schema === undefined ? 'not checked (no args/schema)' : v.schema.valid ? 'valid' : `invalid (${v.schema.violations.join('; ')})`}`,
344
+ ];
345
+ if ((v.sideEffects ?? []).length > 0)
346
+ lines.push(` side effects: ${(v.sideEffects ?? []).join('; ')}`);
347
+ if (v.next?.suggestion !== undefined)
348
+ lines.push(` suggestion: ${v.next.suggestion}`);
349
+ return [{ type: 'text', text: lines.join('\n') }];
350
+ },
351
+ },
352
+ async execute(args, exec) {
353
+ const snapshot = await snapshotFor(exec?.agent);
354
+ let candidate;
355
+ if (typeof args.argsJson === 'string' && args.argsJson.trim() !== '') {
356
+ try {
357
+ const parsed = JSON.parse(args.argsJson);
358
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
359
+ return { ok: false, admitted: false, requires: { approval: 'none', sandbox: 'none' }, sideEffects: [], next: { callable: false }, error: 'invalid-args-json', warnings: [] };
360
+ }
361
+ candidate = parsed;
362
+ }
363
+ catch {
364
+ return { ok: false, admitted: false, requires: { approval: 'none', sandbox: 'none' }, sideEffects: [], next: { callable: false }, error: 'invalid-args-json', warnings: [] };
365
+ }
366
+ }
367
+ return preflightCapability(snapshot, args.capability, candidate, sources, exec?.agent);
368
+ },
369
+ });
370
+ return [searchTool, preflightTool];
371
+ }
372
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,IAAI,YAAY,EAAiB,MAAM,aAAa,CAAA;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAWzC,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,CAAA;AAEjC,0BAA0B;AAC1B,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,2DAA2D;AAC3D,eAAO,MAAM,MAAM,UAAY,CAAA;AAoC/B;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA4GxD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,IAAI,YAAY,EAAiB,MAAM,aAAa,CAAA;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAYzC,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,CAAA;AAEjC,0BAA0B;AAC1B,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,2DAA2D;AAC3D,eAAO,MAAM,MAAM,UAAY,CAAA;AAoC/B;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAoHxD"}
package/lib/index.js CHANGED
@@ -11,6 +11,7 @@ import { makeReindexTool } from "./reindex.js";
11
11
  import { registerHttp } from "./http.js";
12
12
  import { resolveBinary, resolveRoots, resolveStateDir } from "./paths.js";
13
13
  import { LocatorRuntime } from "./runtime.js";
14
+ import { makeCapabilityTools } from "./capabilities.js";
14
15
  import { makeCiteTool, makeResolveTool } from "./ref-tools.js";
15
16
  import { makeRebuildTool, makeSearchTool, makeStatusTool } from "./tools.js";
16
17
  export { ConfigSchema as Config };
@@ -160,6 +161,15 @@ export function apply(ctx, config) {
160
161
  ctx.tools.register(makeExportTool(rt));
161
162
  ctx.tools.register(makeResolveTool(rt, content));
162
163
  ctx.tools.register(makeCiteTool());
164
+ // Capability adapter: read the host's tool registry and skill catalog instead
165
+ // of duplicating discovery. Optional services stay optional.
166
+ const skillsService = ctx.get?.('skills');
167
+ const capabilitySources = {
168
+ tools: ctx.tools,
169
+ ...(skillsService === undefined ? {} : { skills: skillsService }),
170
+ };
171
+ for (const tool of makeCapabilityTools(capabilitySources))
172
+ ctx.tools.register(tool);
163
173
  if (content !== undefined) {
164
174
  ctx.tools.register(makeFindTool(content, ensureContent, roots, config.allowCrossWorkspaceSessions));
165
175
  ctx.tools.register(makeReindexTool(content, ensureContent));
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5E,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,CAAA;AAEjC,0BAA0B;AAC1B,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAA;AAEjC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;AAQ/B;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,GAAG,GAAI,GAAwE,CAAC,GAAG,CAAA;IACzF,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,OAAO,SAAS,CAAA;IAC/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAA0B,CAAA;QACpE,OAAO,KAAK,IAAI,SAAS,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,SAAS,UAAU,CAAC,MAAe;IACjC,IAAI,OAAO,MAAM,KAAK,UAAU;QAAE,OAAO,MAAoB,CAAA;IAC7D,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAQ,MAAgC,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACrH,OAAO,GAAG,EAAE,GAAI,MAAkC,CAAC,OAAO,EAAE,CAAA,CAAC,CAAC,CAAA;IAChE,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAAc;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAM;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;IACxC,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IACnE,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY;QACjC,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,EAAE;YACnB,QAAQ;YACR,WAAW,EAAE,MAAM,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS;YACzF,QAAQ,EAAE,MAAM,CAAC,eAAe;YAChC,eAAe,EAAE,MAAM,CAAC,sBAAsB;YAC9C,oBAAoB,EAAE,MAAM,CAAC,2BAA2B;YACxD,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,MAAM,CAAC,mBAAmB;YACxC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,aAAa;YAClD,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,QAAQ;YACxC,gBAAgB,EAAE,MAAM,CAAC,qBAAqB;YAC9C,kBAAkB,EAAE,MAAM,CAAC,uBAAuB;YAClD,WAAW,EAAE,MAAM,CAAC,kBAAkB;SACvC,CAAC;QACJ,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAChC,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,IAAI,aAAuC,CAAA;IAE3C,MAAM,UAAU,GAAG,GAAS,EAAE;QAC5B,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,gBAAgB,IAAI,CAAC,IAAI,aAAa,KAAK,SAAS;YAAE,OAAM;QAChG,MAAM,IAAI,GAAG,GAAS,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAA,CAAC,CAAC,CAAA;QACjD,IAAI,OAAO,KAAK,EAAE,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;YACxE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAAC,aAAa,GAAG,MAAM,CAAC;gBAAC,OAAM;YAAC,CAAC;QAC9D,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;QACzD,aAAa,GAAG,GAAG,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAA;IACjD,CAAC,CAAA;IAED;;;;OAIG;IACH,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,OAAO,KAAK,SAAS,IAAI,cAAc;YAAE,OAAM;QACnD,cAAc,GAAG,IAAI,CAAA;QACrB,2EAA2E;QAC3E,0EAA0E;QAC1E,OAAO,CAAC,WAAW,EAAE,CAAA;QACrB,KAAK,YAAY,EAAE,CAAA;IACrB,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;QAC7C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,SAAS,EAAE,CAAA;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,EAAE,CAAA;gBACtC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ;oBAAE,MAAK;gBACnD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;YAC1D,CAAC;YACD,OAAQ,CAAC,IAAI,EAAE,CAAA;YACf,UAAU,EAAE,CAAA;YACZ,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAQ,CAAC,YAAY,EAAE,CAAA;YACvB,MAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjG,CAAC;IACH,CAAC,CAAA;IAED,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;QACd,2EAA2E;QAC3E,MAAM,KAAK,GAAG,GAAS,EAAE;YACvB,EAAE,CAAC,KAAK,EAAE,CAAA;YACV,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,QAAQ,GAAG,CAAC,CAAA;YACnE,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK;gBAAE,aAAa,EAAE,CAAA;QAC5E,CAAC,CAAA;QACD,IAAI,WAAqC,CAAA;QACzC,IAAI,OAAO,KAAK,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC;YACzC,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;QACtD,CAAC;QACD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;YACtC,WAAW,GAAG,GAAG,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAA;QAC9C,CAAC;QACD,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,EAAE,CAAA;YACf,aAAa,EAAE,EAAE,CAAA;YACjB,aAAa,GAAG,SAAS,CAAA;YACzB,OAAO,EAAE,KAAK,EAAE,CAAA;YAChB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAA;QAChB,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;IACtC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/C,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAA;IACvC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;IACtC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IAChD,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAA;IAClC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAA;QACnG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAA;IAC7D,CAAC;IAED,wEAAwE;IACxE,uCAAuC;IACvC,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,kBAAkB,EAAE,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAA;AACtG,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-locator",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Whole-disk, millisecond file search for DeepSeek Harness without Everything: a self-built cross-platform index, an Everything-style query language, agent tools and a Web search panel (Ctrl+Shift+F). Windows, macOS and Linux.",
5
5
  "author": "PerryLink contributors",
6
6
  "repository": {
@@ -0,0 +1,405 @@
1
+ /**
2
+ * Capability index: which tool/skill/MCP action can do a job, what it costs and
3
+ * what it may touch. This is a thin adapter over the DSH registries the host
4
+ * already keeps (tool definitions, skill catalog): it does not re-implement
5
+ * discovery, it adds intent matching, risk labels and a preflight check.
6
+ * @module dsh-locator/capabilities
7
+ */
8
+
9
+ import { defineTool, validateJsonSchemaValue } from '@deepseek-ai/dsh-tools'
10
+ import type { ToolRunContext } from '@deepseek-ai/dsh-tools'
11
+
12
+ /** One capability card. */
13
+ export interface CapabilityCard {
14
+ id: string
15
+ kind: 'tool' | 'mcp' | 'skill'
16
+ name: string
17
+ summary: string
18
+ input?: Record<string, unknown>
19
+ tags: string[]
20
+ risk: { level: 'read' | 'write' | 'exec'; actions: string[]; basis: 'schema' | 'name' }
21
+ permission: { approval: 'none' | 'ask'; sandbox: 'none' | 'write' | 'any' }
22
+ state: 'available' | 'unknown'
23
+ source: 'tools' | 'skills'
24
+ }
25
+
26
+ /** One snapshot of the live capability surface. */
27
+ export interface CapabilitySnapshot {
28
+ builtAt: number
29
+ cards: CapabilityCard[]
30
+ warnings: string[]
31
+ }
32
+
33
+ /** Minimal shape of the host services this module reads. */
34
+ export interface CapabilitySources {
35
+ tools?: {
36
+ definitions?: (scope?: unknown, toolSet?: unknown) => readonly unknown[]
37
+ get?: (name: string, scope?: unknown) => unknown
38
+ } | undefined
39
+ skills?: { list?: (options?: Record<string, unknown>) => Promise<readonly unknown[]> } | undefined
40
+ }
41
+
42
+ const WRITE_WORDS = ['write', 'edit', 'delete', 'remove', 'move', 'rename', 'mkdir', 'install', 'uninstall', 'publish', 'patch', 'apply']
43
+ const EXEC_WORDS = ['bash', 'shell', 'execute', 'terminal', 'run_code', 'spawn', 'command']
44
+ const ALIASES: Record<string, string[]> = {
45
+ 文件: ['file', 'files', 'path'], 搜索: ['search', 'find', 'grep'], 写: ['write', 'edit'], 删除: ['delete', 'remove'],
46
+ 运行: ['run', 'exec', 'bash'], 命令: ['command', 'shell'], 网页: ['web', 'http', 'url'], 截图: ['screenshot', 'screen'],
47
+ 测试: ['test'], 安装: ['install'], 插件: ['plugin'], 技能: ['skill'], 工具: ['tool'],
48
+ }
49
+
50
+ /** Tokenize one intent/name for the lexical scorer (letters, digits, CJK). */
51
+ export function tokenize(text: string): string[] {
52
+ const lowered = text.toLowerCase()
53
+ const ascii = lowered.match(/[a-z0-9_]{2,}/g) ?? []
54
+ const cjk = lowered.match(/[\u4e00-\u9fff]{2}/g) ?? []
55
+ const expanded = [...ascii, ...cjk]
56
+ for (const [key, values] of Object.entries(ALIASES)) {
57
+ if (lowered.includes(key)) expanded.push(...values)
58
+ }
59
+ return [...new Set(expanded)]
60
+ }
61
+
62
+ /** Infer risk/permission from a tool name, description and parameter schema. */
63
+ export function inferRisk(name: string, description: string, parameters?: Record<string, unknown>): CapabilityCard['risk'] & { permission: CapabilityCard['permission'] } {
64
+ const haystack = `${name} ${description}`.toLowerCase()
65
+ const properties = parameters !== undefined && typeof parameters === 'object' && parameters !== null && typeof (parameters as { properties?: unknown }).properties === 'object'
66
+ ? Object.keys((parameters as { properties: Record<string, unknown> }).properties)
67
+ : []
68
+ const actions: string[] = []
69
+ let level: 'read' | 'write' | 'exec' = 'read'
70
+ if (EXEC_WORDS.some(word => haystack.includes(word)) || properties.includes('command') || properties.includes('cmd')) { level = 'exec'; actions.push('may execute a process') }
71
+ if (WRITE_WORDS.some(word => haystack.includes(word)) || properties.includes('content') || properties.includes('sandbox_permissions')) {
72
+ if (level !== 'exec') level = 'write'
73
+ actions.push('may modify state')
74
+ }
75
+ if (properties.includes('sandbox_permissions')) actions.push('can request escalated sandbox permissions')
76
+ return {
77
+ level,
78
+ actions: [...new Set(actions)],
79
+ basis: properties.length > 0 ? 'schema' : 'name',
80
+ permission: { approval: level === 'read' ? 'none' : 'ask', sandbox: level === 'read' ? 'none' : level === 'exec' ? 'any' : 'write' },
81
+ }
82
+ }
83
+
84
+ /** Convert one DSH ToolDefinition into a capability card. */
85
+ function toolCard(definition: unknown): CapabilityCard | undefined {
86
+ if (typeof definition !== 'object' || definition === null) return undefined
87
+ const record = definition as { name?: unknown; description?: unknown; parameters?: unknown; output?: unknown }
88
+ if (typeof record.name !== 'string' || record.name === '') return undefined
89
+ const name = record.name
90
+ const description = typeof record.description === 'string' ? record.description : ''
91
+ const parameters = typeof record.parameters === 'object' && record.parameters !== null ? record.parameters as Record<string, unknown> : undefined
92
+ const risk = inferRisk(name, description, parameters)
93
+ const mcpParts = /^mcp__([^_]+(?:_[^_]+)*)__(.+)$/.exec(name)
94
+ const kind: CapabilityCard['kind'] = mcpParts !== null ? 'mcp' : 'tool'
95
+ const display = mcpParts !== null ? `${mcpParts[1]}/${mcpParts[2]}` : name
96
+ return {
97
+ id: kind === 'mcp' ? `mcp:${display}` : `tool:${name}`,
98
+ kind,
99
+ name: display,
100
+ summary: description.split('\n')[0]?.slice(0, 240) ?? '',
101
+ ...(parameters === undefined ? {} : { input: parameters }),
102
+ tags: tokenize(`${name} ${description}`).slice(0, 12),
103
+ risk: { level: risk.level, actions: risk.actions, basis: risk.basis },
104
+ permission: risk.permission,
105
+ state: 'available',
106
+ source: 'tools',
107
+ }
108
+ }
109
+
110
+ /** Convert one SkillSummary into a capability card. */
111
+ function skillCard(skill: unknown): CapabilityCard | undefined {
112
+ if (typeof skill !== 'object' || skill === null) return undefined
113
+ const record = skill as { name?: unknown; description?: unknown; whenToUse?: unknown; source?: unknown; invocation?: unknown }
114
+ if (typeof record.name !== 'string' || record.name === '') return undefined
115
+ const summary = `${typeof record.description === 'string' ? record.description : ''}${typeof record.whenToUse === 'string' ? ` · ${record.whenToUse}` : ''}`.trim()
116
+ const invocation = typeof record.invocation === 'object' && record.invocation !== null ? record.invocation as { modelInvocable?: unknown } : undefined
117
+ return {
118
+ id: `skill:${record.name}`,
119
+ kind: 'skill',
120
+ name: record.name,
121
+ summary: summary.slice(0, 240),
122
+ tags: tokenize(`${record.name} ${summary}`).slice(0, 12),
123
+ risk: { level: 'read', actions: ['loads instructions, no direct side effects'], basis: 'name' },
124
+ permission: { approval: 'none', sandbox: 'none' },
125
+ state: invocation?.modelInvocable === false ? 'unknown' : 'available',
126
+ source: 'skills',
127
+ }
128
+ }
129
+
130
+ /** Build one capability snapshot from the live host services. */
131
+ export async function buildCapabilitySnapshot(sources: CapabilitySources, scope?: unknown): Promise<CapabilitySnapshot> {
132
+ const warnings: string[] = []
133
+ const cards: CapabilityCard[] = []
134
+ try {
135
+ const definitions = sources.tools?.definitions?.(scope) ?? []
136
+ for (const definition of definitions) {
137
+ const card = toolCard(definition)
138
+ if (card !== undefined) cards.push(card)
139
+ }
140
+ } catch (error) {
141
+ warnings.push(`tool-catalog-unavailable: ${error instanceof Error ? error.message : String(error)}`)
142
+ }
143
+ if (sources.skills?.list !== undefined) {
144
+ try {
145
+ const skills = await sources.skills.list(scope === undefined ? {} : { scope })
146
+ for (const skill of skills) {
147
+ const card = skillCard(skill)
148
+ if (card !== undefined) cards.push(card)
149
+ }
150
+ } catch (error) {
151
+ warnings.push(`skill-catalog-unavailable: ${error instanceof Error ? error.message : String(error)}`)
152
+ }
153
+ } else {
154
+ warnings.push('skill-service-unavailable')
155
+ }
156
+ cards.sort((left, right) => left.id.localeCompare(right.id))
157
+ return { builtAt: Date.now(), cards, warnings }
158
+ }
159
+
160
+ /** Card projection returned by tools: drop the full input schema payload. */
161
+ export function publicCard(card: CapabilityCard): Omit<CapabilityCard, 'input'> {
162
+ const { input: _input, ...rest } = card
163
+ return rest
164
+ }
165
+
166
+ /** One ranked capability hit. */
167
+ export interface CapabilityHit {
168
+ card: CapabilityCard
169
+ score: number
170
+ why: string[]
171
+ }
172
+
173
+ /**
174
+ * Rank capability cards against an intent and optional filters.
175
+ * @param cards - snapshot cards.
176
+ * @param intent - what the caller wants to do.
177
+ * @param options - kind/risk filters and pagination.
178
+ * @returns ranked hits and the total before paging.
179
+ */
180
+ export function searchCapabilities(
181
+ cards: readonly CapabilityCard[],
182
+ intent: string,
183
+ options: { kinds?: readonly CapabilityCard['kind'][]; riskMax?: 'read' | 'write' | 'exec'; limit?: number; offset?: number; availableOnly?: boolean } = {},
184
+ ): { hits: CapabilityHit[]; total: number } {
185
+ const terms = tokenize(intent)
186
+ const limit = Math.max(1, Math.min(50, options.limit ?? 10))
187
+ const offset = Math.max(0, options.offset ?? 0)
188
+ const matches = cards.filter(card => {
189
+ if (options.kinds !== undefined && options.kinds.length > 0 && !options.kinds.includes(card.kind)) return false
190
+ if (options.availableOnly === true && card.state !== 'available') return false
191
+ if (options.riskMax !== undefined) {
192
+ const order = { read: 0, write: 1, exec: 2 } as const
193
+ if (order[card.risk.level] > order[options.riskMax]) return false
194
+ }
195
+ return true
196
+ })
197
+ const scored: CapabilityHit[] = []
198
+ for (const card of matches) {
199
+ const haystack = tokenize(`${card.name} ${card.summary} ${card.tags.join(' ')}`)
200
+ const why: string[] = []
201
+ let score = 0
202
+ for (const term of terms) {
203
+ if (card.name.toLowerCase().includes(term)) { score += 6; why.push(`name:${term}`); continue }
204
+ if (haystack.includes(term)) { score += 2; why.push(`text:${term}`) }
205
+ }
206
+ if (terms.length === 0) { score = 1; why.push('intent-empty: lists capabilities') }
207
+ if (score > 0) scored.push({ card, score, why: why.slice(0, 6) })
208
+ }
209
+ scored.sort((left, right) => right.score - left.score || left.card.id.localeCompare(right.card.id))
210
+ return { hits: scored.slice(offset, offset + limit), total: scored.length }
211
+ }
212
+
213
+ /** One preflight result. */
214
+ export interface PreflightResult {
215
+ ok: boolean
216
+ card?: CapabilityCard
217
+ admitted: boolean
218
+ schema?: { valid: boolean; violations: string[] }
219
+ requires: { approval: 'none' | 'ask'; sandbox: 'none' | 'write' | 'any' }
220
+ sideEffects: string[]
221
+ next: { callable: boolean; suggestion?: string }
222
+ error?: string
223
+ warnings: string[]
224
+ }
225
+
226
+ /**
227
+ * Check whether one capability can be called with the given arguments right
228
+ * now: existence/visibility, argument schema, predicted approval/sandbox and
229
+ * side effects. It never executes the target.
230
+ */
231
+ export function preflightCapability(
232
+ snapshot: CapabilitySnapshot,
233
+ target: string,
234
+ args?: Record<string, unknown>,
235
+ sources?: CapabilitySources,
236
+ scope?: unknown,
237
+ ): PreflightResult {
238
+ const normalized = target.trim()
239
+ const card = snapshot.cards.find(entry => entry.id === normalized || entry.name === normalized || entry.id === `tool:${normalized}` || entry.id === `mcp:${normalized}` || entry.id === `skill:${normalized}`)
240
+ if (card === undefined) {
241
+ return { ok: false, admitted: false, requires: { approval: 'none', sandbox: 'none' }, sideEffects: [], next: { callable: false }, error: 'capability-not-found', warnings: [] }
242
+ }
243
+ const warnings = [...snapshot.warnings]
244
+ let visible = true
245
+ if (card.kind !== 'skill' && sources?.tools?.get !== undefined) {
246
+ try { visible = sources.tools.get(card.kind === 'mcp' ? card.name.replace('/', '__') : card.name, scope) !== undefined } catch { visible = true }
247
+ }
248
+ let schema: { valid: boolean; violations: string[] } | undefined
249
+ if (args !== undefined && card.input !== undefined) {
250
+ try {
251
+ const violations = validateJsonSchemaValue(card.input as unknown as Parameters<typeof validateJsonSchemaValue>[0], args)
252
+ schema = { valid: violations.length === 0, violations }
253
+ } catch (error) {
254
+ schema = { valid: false, violations: [error instanceof Error ? error.message : String(error)] }
255
+ }
256
+ }
257
+ const callable = visible && (schema?.valid ?? true)
258
+ const suggestion = callable
259
+ ? undefined
260
+ : !visible
261
+ ? 'capability is registered but not visible in this agent scope'
262
+ : schema?.valid === false
263
+ ? 'fix the arguments against the declared schema'
264
+ : 'capability is not callable from this scope'
265
+ return {
266
+ ok: true,
267
+ card: publicCard(card),
268
+ admitted: callable,
269
+ ...(schema === undefined ? {} : { schema }),
270
+ requires: card.permission,
271
+ sideEffects: card.risk.actions,
272
+ next: { callable, ...(suggestion === undefined ? {} : { suggestion }) },
273
+ warnings,
274
+ }
275
+ }
276
+
277
+ const CARD_SCHEMA = {
278
+ type: 'object',
279
+ additionalProperties: false,
280
+ properties: {
281
+ id: { type: 'string' }, kind: { type: 'string', enum: ['tool', 'mcp', 'skill'] },
282
+ name: { type: 'string' }, summary: { type: 'string' },
283
+ tags: { type: 'array', items: { type: 'string' } },
284
+ risk: { type: 'object', additionalProperties: false, properties: { level: { type: 'string' }, actions: { type: 'array', items: { type: 'string' } }, basis: { type: 'string' } } },
285
+ permission: { type: 'object', additionalProperties: false, properties: { approval: { type: 'string' }, sandbox: { type: 'string' } } },
286
+ state: { type: 'string' }, source: { type: 'string' },
287
+ },
288
+ } as const
289
+
290
+ /** Build `capability_search` and `capability_preflight` bound to the host registries. */
291
+ export function makeCapabilityTools(sources: CapabilitySources) {
292
+ let cached: CapabilitySnapshot | undefined
293
+ const snapshotFor = async (scope?: unknown): Promise<CapabilitySnapshot> => {
294
+ if (cached === undefined || Date.now() - cached.builtAt > 60_000) cached = await buildCapabilitySnapshot(sources, scope)
295
+ return cached
296
+ }
297
+ const searchTool = defineTool({
298
+ name: 'capability_search',
299
+ description: [
300
+ 'Find the tool, MCP action or skill that can do a job (dsh-locator capability adapter).',
301
+ '',
302
+ 'Use it when the caller knows the goal but not which capability performs it: pass the intent in natural language and filter by kind/risk. Every hit carries risk and permission hints plus the card id usable with `capability_preflight`.',
303
+ '',
304
+ 'This is not a file search: it indexes the live DSH capability registry (tool definitions and the skill catalog), not file names or bodies.',
305
+ ].join('\n'),
306
+ parameters: {
307
+ intent: { type: 'string', required: true, description: 'What should be done, in natural language (English or Chinese).' },
308
+ kinds: { type: 'array', items: { type: 'string', enum: ['tool', 'mcp', 'skill'] }, description: 'Restrict to these capability kinds.' },
309
+ riskMax: { type: 'string', enum: ['read', 'write', 'exec'], description: 'Only return capabilities at or below this risk level.' },
310
+ availableOnly: { type: 'boolean', description: 'Only return cards that are currently visible/available.' },
311
+ limit: { type: 'integer', description: 'Maximum hits (default 10, at most 50).' },
312
+ offset: { type: 'integer', description: 'Skip this many ranked hits.' },
313
+ },
314
+ output: {
315
+ schema: {
316
+ type: 'object',
317
+ additionalProperties: false,
318
+ properties: {
319
+ ok: { type: 'boolean', required: true },
320
+ intent: { type: 'string' }, total: { type: 'integer' }, returned: { type: 'integer' },
321
+ hits: { type: 'array', items: { type: 'object', additionalProperties: false, properties: { card: CARD_SCHEMA, score: { type: 'number' }, why: { type: 'array', items: { type: 'string' } } } } },
322
+ warnings: { type: 'array', items: { type: 'string' } }, error: { type: 'string' },
323
+ },
324
+ },
325
+ render: (_args, value) => {
326
+ const v = value as { ok: boolean; intent?: string; total?: number; hits?: Array<{ card: CapabilityCard; why: string[] }>; warnings?: string[]; error?: string }
327
+ if (!v.ok) return [{ type: 'text', text: `capability_search failed: ${v.error ?? 'unknown error'}` }]
328
+ const lines = [`capability_search ${JSON.stringify(v.intent ?? '')}: ${String(v.total ?? 0)} match(es)`]
329
+ for (const hit of v.hits ?? []) {
330
+ lines.push(`- ${hit.card.id} [${hit.card.kind}] risk=${hit.card.risk.level} approval=${hit.card.permission.approval} — ${hit.card.summary}`)
331
+ }
332
+ if ((v.warnings ?? []).length > 0) lines.push(`warnings: ${[...new Set(v.warnings ?? [])].join(', ')}`)
333
+ return [{ type: 'text', text: lines.join('\n') }]
334
+ },
335
+ },
336
+ async execute(args, exec) {
337
+ const snapshot = await snapshotFor(exec?.agent)
338
+ const kinds = Array.isArray(args.kinds) ? args.kinds.filter((kind): kind is CapabilityCard['kind'] => kind === 'tool' || kind === 'mcp' || kind === 'skill') : undefined
339
+ const riskMax = args.riskMax === 'read' || args.riskMax === 'write' || args.riskMax === 'exec' ? args.riskMax : undefined
340
+ const result = searchCapabilities(snapshot.cards, args.intent, { ...(kinds === undefined ? {} : { kinds }), ...(riskMax === undefined ? {} : { riskMax }), limit: Math.max(1, Math.min(50, args.limit ?? 10)), offset: Math.max(0, args.offset ?? 0), availableOnly: args.availableOnly === true })
341
+ const hits = result.hits.map(hit => ({ ...hit, card: publicCard(hit.card) }))
342
+ return { ok: true as const, intent: args.intent, total: result.total, returned: hits.length, hits, warnings: snapshot.warnings }
343
+ },
344
+ })
345
+ const preflightTool = defineTool({
346
+ name: 'capability_preflight',
347
+ description: [
348
+ 'Check one capability before calling it (dsh-locator capability adapter): whether it exists and is visible, whether the arguments match its declared schema, and which approval/sandbox/side effects it implies.',
349
+ '',
350
+ 'It never executes the target. Use it when a plan depends on a tool/MCP action/skill and the caller needs to know the cost or permission risk first.',
351
+ ].join('\n'),
352
+ parameters: {
353
+ capability: { type: 'string', required: true, description: 'Card id (`tool:<name>`, `mcp:<server>/<action>`, `skill:<name>`) or plain name from capability_search.' },
354
+ argsJson: { type: 'string', description: 'Candidate arguments as a JSON object string to validate against the declared schema.' },
355
+ },
356
+ output: {
357
+ schema: {
358
+ type: 'object',
359
+ additionalProperties: false,
360
+ properties: {
361
+ ok: { type: 'boolean', required: true },
362
+ card: CARD_SCHEMA,
363
+ admitted: { type: 'boolean' },
364
+ schema: { type: 'object', additionalProperties: false, properties: { valid: { type: 'boolean' }, violations: { type: 'array', items: { type: 'string' } } } },
365
+ requires: { type: 'object', additionalProperties: false, properties: { approval: { type: 'string' }, sandbox: { type: 'string' } } },
366
+ sideEffects: { type: 'array', items: { type: 'string' } },
367
+ next: { type: 'object', additionalProperties: false, properties: { callable: { type: 'boolean' }, suggestion: { type: 'string' } } },
368
+ error: { type: 'string' }, warnings: { type: 'array', items: { type: 'string' } },
369
+ },
370
+ },
371
+ render: (_args, value) => {
372
+ const v = value as { ok: boolean; card?: CapabilityCard; admitted?: boolean; schema?: { valid: boolean; violations: string[] }; requires?: { approval: string; sandbox: string }; sideEffects?: string[]; next?: { callable: boolean; suggestion?: string }; error?: string; warnings?: string[] }
373
+ if (!v.ok) return [{ type: 'text', text: `capability_preflight failed: ${v.error ?? 'unknown error'}` }]
374
+ const lines = [
375
+ `capability_preflight ${v.card?.id ?? ''}: callable=${String(v.next?.callable ?? v.admitted ?? false)}`,
376
+ ` risk: ${v.card?.risk.level ?? '?'} · approval=${v.requires?.approval ?? '?'} · sandbox=${v.requires?.sandbox ?? '?'}`,
377
+ ` schema: ${v.schema === undefined ? 'not checked (no args/schema)' : v.schema.valid ? 'valid' : `invalid (${v.schema.violations.join('; ')})`}`,
378
+ ]
379
+ if ((v.sideEffects ?? []).length > 0) lines.push(` side effects: ${(v.sideEffects ?? []).join('; ')}`)
380
+ if (v.next?.suggestion !== undefined) lines.push(` suggestion: ${v.next.suggestion}`)
381
+ return [{ type: 'text', text: lines.join('\n') }]
382
+ },
383
+ },
384
+ async execute(args, exec) {
385
+ const snapshot = await snapshotFor(exec?.agent)
386
+ let candidate: Record<string, unknown> | undefined
387
+ if (typeof args.argsJson === 'string' && args.argsJson.trim() !== '') {
388
+ try {
389
+ const parsed: unknown = JSON.parse(args.argsJson)
390
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
391
+ return { ok: false as const, admitted: false, requires: { approval: 'none' as const, sandbox: 'none' as const }, sideEffects: [], next: { callable: false }, error: 'invalid-args-json', warnings: [] }
392
+ }
393
+ candidate = parsed as Record<string, unknown>
394
+ } catch {
395
+ return { ok: false as const, admitted: false, requires: { approval: 'none' as const, sandbox: 'none' as const }, sideEffects: [], next: { callable: false }, error: 'invalid-args-json', warnings: [] }
396
+ }
397
+ }
398
+ return preflightCapability(snapshot, args.capability, candidate, sources, exec?.agent)
399
+ },
400
+ })
401
+ return [searchTool, preflightTool] as const
402
+ }
403
+
404
+ /** ToolRunContext re-export keeps the module self-describing for tests. */
405
+ export type { ToolRunContext }
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ import { makeReindexTool } from './reindex.ts'
14
14
  import { registerHttp } from './http.ts'
15
15
  import { resolveBinary, resolveRoots, resolveStateDir } from './paths.ts'
16
16
  import { LocatorRuntime } from './runtime.ts'
17
+ import { makeCapabilityTools, type CapabilitySources } from './capabilities.ts'
17
18
  import { makeCiteTool, makeResolveTool } from './ref-tools.ts'
18
19
  import { makeRebuildTool, makeSearchTool, makeStatusTool } from './tools.ts'
19
20
 
@@ -168,6 +169,14 @@ export function apply(ctx: Context, config: Config): void {
168
169
  ctx.tools.register(makeExportTool(rt))
169
170
  ctx.tools.register(makeResolveTool(rt, content))
170
171
  ctx.tools.register(makeCiteTool())
172
+ // Capability adapter: read the host's tool registry and skill catalog instead
173
+ // of duplicating discovery. Optional services stay optional.
174
+ const skillsService = (ctx as unknown as { get?: (name: string) => unknown }).get?.('skills')
175
+ const capabilitySources: CapabilitySources = {
176
+ tools: ctx.tools as unknown as CapabilitySources['tools'],
177
+ ...(skillsService === undefined ? {} : { skills: skillsService as CapabilitySources['skills'] }),
178
+ }
179
+ for (const tool of makeCapabilityTools(capabilitySources)) ctx.tools.register(tool)
171
180
  if (content !== undefined) {
172
181
  ctx.tools.register(makeFindTool(content, ensureContent, roots, config.allowCrossWorkspaceSessions))
173
182
  ctx.tools.register(makeReindexTool(content, ensureContent))