dsh-locator 0.8.2 → 0.10.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README-es.md +30 -5
  3. package/README-hi.md +31 -5
  4. package/README-pt.md +31 -5
  5. package/README.en.md +31 -5
  6. package/README.md +31 -5
  7. package/bin/darwin-arm64/indexd +0 -0
  8. package/bin/darwin-x64/indexd +0 -0
  9. package/bin/linux-arm64/indexd +0 -0
  10. package/bin/linux-x64/indexd +0 -0
  11. package/bin/win32-arm64/indexd.exe +0 -0
  12. package/bin/win32-x64/indexd.exe +0 -0
  13. package/client.js +1198 -117
  14. package/lib/combined.d.ts +20 -3
  15. package/lib/combined.d.ts.map +1 -1
  16. package/lib/combined.js +85 -15
  17. package/lib/combined.js.map +1 -1
  18. package/lib/content-search-worker.d.ts +8 -3
  19. package/lib/content-search-worker.d.ts.map +1 -1
  20. package/lib/content-search-worker.js +54 -27
  21. package/lib/content-search-worker.js.map +1 -1
  22. package/lib/content-search.d.ts +127 -7
  23. package/lib/content-search.d.ts.map +1 -1
  24. package/lib/content-search.js +571 -36
  25. package/lib/content-search.js.map +1 -1
  26. package/lib/content.d.ts +83 -5
  27. package/lib/content.d.ts.map +1 -1
  28. package/lib/content.js +351 -87
  29. package/lib/content.js.map +1 -1
  30. package/lib/export.d.ts +61 -0
  31. package/lib/export.d.ts.map +1 -1
  32. package/lib/export.js +217 -52
  33. package/lib/export.js.map +1 -1
  34. package/lib/find.d.ts.map +1 -1
  35. package/lib/find.js +73 -16
  36. package/lib/find.js.map +1 -1
  37. package/lib/http.d.ts +38 -2
  38. package/lib/http.d.ts.map +1 -1
  39. package/lib/http.js +279 -82
  40. package/lib/http.js.map +1 -1
  41. package/lib/reveal.d.ts +69 -3
  42. package/lib/reveal.d.ts.map +1 -1
  43. package/lib/reveal.js +140 -11
  44. package/lib/reveal.js.map +1 -1
  45. package/lib/tools.d.ts +30 -0
  46. package/lib/tools.d.ts.map +1 -1
  47. package/lib/tools.js +65 -3
  48. package/lib/tools.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/combined.ts +107 -17
  51. package/src/content-search-worker.ts +52 -24
  52. package/src/content-search.ts +710 -36
  53. package/src/content.ts +349 -73
  54. package/src/export.ts +240 -50
  55. package/src/find.ts +83 -16
  56. package/src/http.ts +271 -83
  57. package/src/reveal.ts +148 -10
  58. package/src/tools.ts +83 -6
package/lib/find.js CHANGED
@@ -14,9 +14,24 @@ const HIT = {
14
14
  sessionId: { type: 'string' },
15
15
  messageId: { type: 'string' },
16
16
  nodeKey: { type: 'string' },
17
+ line: { type: 'integer', description: '1-based line of the first match in the stored body (file hits).' },
17
18
  score: { type: 'number' },
18
19
  },
19
20
  };
21
+ const STATE = {
22
+ type: 'object',
23
+ additionalProperties: false,
24
+ properties: {
25
+ building: { type: 'boolean' },
26
+ files: { type: 'integer' },
27
+ sessions: { type: 'integer' },
28
+ messages: { type: 'integer' },
29
+ truncated: { type: 'boolean' },
30
+ updatedAt: { type: 'integer' },
31
+ error: { type: 'string' },
32
+ warnings: { type: 'array', items: { type: 'string' }, description: 'Non-fatal build problems, e.g. an unreadable session log.' },
33
+ },
34
+ };
20
35
  /** Build the locator_find tool. */
21
36
  export function makeFindTool(content, ensure) {
22
37
  return defineTool({
@@ -26,11 +41,19 @@ export function makeFindTool(content, ensure) {
26
41
  '',
27
42
  'Use it when the user remembers a phrase, a sentence, a decision or a code snippet rather than a file name. `locator_search` searches names and paths; this searches bodies and returns snippets plus `sessionId`/`messageId` for session hits, so the result can be opened at its source.',
28
43
  '',
29
- 'Content is built asynchronously after start: results may be partial while `state.building` is true. Text files are capped by `contentMaxFileBytes`; session logs are decompressed from `$DSH_HOME/sessions`.',
44
+ 'Content is substring search over an FTS5 trigram index: every term must be at least 3 characters (shorter queries are rejected with `content-query-too-short` instead of scanning the whole corpus). Text files are capped by `contentMaxFileBytes`; session logs are decompressed from `$DSH_HOME/sessions`.',
30
45
  ].join('\n'),
31
46
  parameters: {
32
47
  query: { type: 'string', required: true, description: 'Words or a phrase to find in file/session content.' },
33
48
  limit: { type: 'integer', description: 'Maximum hits (default 30, at most 100).' },
49
+ matchMode: { type: 'string', enum: ['normal', 'extended'], description: 'normal: whitespace-separated substring terms. extended: one literal phrase with Notepad++ escapes (\\n, \\r, \\t, \\0, \\xNN, \\\\).' },
50
+ caseSensitive: { type: 'boolean', description: 'Match letter case exactly.' },
51
+ wholeWord: { type: 'boolean', description: 'Only match whole words ([A-Za-z0-9_] boundaries; CJK counts as non-word).' },
52
+ sessionId: { type: 'string', description: 'Only search messages of one DSH session id (defaults to the caller session in workspace scope).' },
53
+ scope: { type: 'string', enum: ['workspace', 'all'], description: 'workspace (default) restricts file hits to the caller workspace/cwd and session hits to the caller session; all searches every indexed file and session (explicit cross-workspace access).' },
54
+ count: { type: 'string', enum: ['exact', 'bounded', 'none'], description: 'How much counting work to spend; bounded stops at countLimit.' },
55
+ countLimit: { type: 'integer', description: 'Counting cap for bounded counts (default 1000, at most 5000).' },
56
+ pathPrefix: { type: 'string', description: 'Only return file hits whose path starts with this directory (session hits are unaffected).' },
34
57
  },
35
58
  output: {
36
59
  schema: {
@@ -40,42 +63,76 @@ export function makeFindTool(content, ensure) {
40
63
  ok: { type: 'boolean', required: true },
41
64
  query: { type: 'string' },
42
65
  hits: { type: 'array', items: HIT },
43
- state: {
66
+ count: {
44
67
  type: 'object',
45
68
  additionalProperties: false,
46
69
  properties: {
47
- building: { type: 'boolean' },
48
- files: { type: 'integer' },
49
- sessions: { type: 'integer' },
50
- messages: { type: 'integer' },
51
- truncated: { type: 'boolean' },
52
- updatedAt: { type: 'integer' },
53
- error: { type: 'string' },
70
+ value: { type: 'integer' },
71
+ kind: { type: 'string', enum: ['exact', 'bounded', 'unknown'] },
72
+ limit: { type: 'integer' },
54
73
  },
55
74
  },
75
+ warnings: { type: 'array', items: { type: 'string' } },
76
+ state: STATE,
56
77
  error: { type: 'string' },
57
78
  },
58
79
  },
59
80
  render: (_args, value) => {
60
81
  const v = value;
61
- if (!v.ok)
62
- return [{ type: 'text', text: `locator_find failed: ${v.error ?? 'unknown'}` }];
63
- const lines = (v.hits ?? []).map((hit, index) => `${String(index + 1)}. [${hit.kind}] ${hit.title ?? ''} — ${hit.snippet ?? ''}\n ${hit.path ?? ''}`);
82
+ if (!v.ok) {
83
+ const detail = v.warnings !== undefined && v.warnings.length > 0 ? ` (${[...new Set(v.warnings)].join(', ')})` : '';
84
+ return [{ type: 'text', text: `locator_find failed: ${v.error ?? 'unknown'}${detail}` }];
85
+ }
86
+ const lines = (v.hits ?? []).map((hit, index) => {
87
+ const ref = hit.kind === 'session' && (hit.sessionId !== undefined || hit.messageId !== undefined)
88
+ ? `\n session ${String(hit.sessionId ?? '')}${hit.messageId === undefined ? '' : ` message ${String(hit.messageId)}`}`
89
+ : '';
90
+ return `${String(index + 1)}. [${hit.kind}] ${hit.title ?? ''} — ${hit.snippet ?? ''}\n ${hit.path ?? ''}${typeof hit.line === 'number' ? ` (line ${String(hit.line)})` : ''}${ref}`;
91
+ });
92
+ const count = v.count === undefined
93
+ ? ''
94
+ : v.count.kind === 'bounded'
95
+ ? `, count ≥ ${String(v.count.value)}`
96
+ : v.count.kind === 'exact'
97
+ ? `, count ${String(v.count.value)}`
98
+ : '';
99
+ const warnings = [...new Set([...(v.warnings ?? []), ...(v.state?.warnings ?? [])])];
64
100
  const notes = [
65
101
  v.state?.building ? ' (index still building)' : '',
66
102
  v.state?.truncated === true ? ' (content budget reached: raise contentMaxTotalBytes or trim contentExcludes; later files are not searchable)' : '',
103
+ warnings.length > 0 ? ` (warnings: ${warnings.join(', ')})` : '',
67
104
  ].join('');
68
- return [{ type: 'text', text: `${String(v.hits?.length ?? 0)} content hit(s)${notes}\n${lines.join('\n')}` }];
105
+ return [{ type: 'text', text: `${String(v.hits?.length ?? 0)} content hit(s)${count}${notes}\n${lines.join('\n')}` }];
69
106
  },
70
107
  },
71
- async execute(args) {
108
+ async execute(args, exec) {
72
109
  ensure?.();
73
110
  const query = args.query.trim();
74
111
  if (query === '')
75
112
  return { ok: false, error: 'query is empty' };
76
113
  const limit = Math.max(1, Math.min(100, args.limit ?? 30));
77
- const hits = await content.search(query, limit);
78
- return { ok: true, query, hits, state: content.status() };
114
+ const scope = args.scope === 'all' ? 'all' : 'workspace';
115
+ const callerSessionId = scope === 'workspace' ? exec?.agent?.session?.id : undefined;
116
+ const callerCwd = scope === 'workspace' ? exec?.agent?.session?.header?.cwd : undefined;
117
+ const options = {
118
+ ...(args.matchMode === undefined ? {} : { matchMode: args.matchMode }),
119
+ ...(args.caseSensitive === undefined ? {} : { caseSensitive: args.caseSensitive }),
120
+ ...(args.wholeWord === undefined ? {} : { wholeWord: args.wholeWord }),
121
+ ...(args.sessionId !== undefined && args.sessionId !== ''
122
+ ? { sessionId: args.sessionId }
123
+ : callerSessionId === undefined ? {} : { sessionId: String(callerSessionId) }),
124
+ ...(args.count === undefined ? {} : { count: args.count }),
125
+ ...(args.countLimit === undefined ? {} : { countLimit: args.countLimit }),
126
+ ...(args.pathPrefix !== undefined && args.pathPrefix !== ''
127
+ ? { pathPrefix: args.pathPrefix }
128
+ : callerCwd === undefined ? {} : { pathPrefix: callerCwd }),
129
+ };
130
+ const result = await content.search(query, limit, options);
131
+ const state = content.status();
132
+ if (result.error !== undefined) {
133
+ return { ok: false, query, error: result.error, warnings: result.warnings, hits: [], state };
134
+ }
135
+ return { ok: true, query, hits: result.hits, count: result.count, warnings: result.warnings, state };
79
136
  },
80
137
  });
81
138
  }
package/lib/find.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"find.js","sourceRoot":"","sources":["../src/find.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../src/find.ts"],"names":[],"mappings":"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"}
package/lib/http.d.ts CHANGED
@@ -2,18 +2,54 @@
2
2
  * Optional HTTP surface for the Web GUI panel.
3
3
  *
4
4
  * The panel is a browser overlay (client.js) and cannot call the stdio engine
5
- * directly, so the host exposes two exact routes on the Web server:
5
+ * directly, so the host exposes exact routes on the Web server:
6
6
  *
7
7
  * POST /dsh-locator/search { query, limit, offset, sort, desc, ... }
8
8
  * POST /dsh-locator/status {}
9
9
  *
10
+ * Security is fail-closed. The routes only exist when the host's `connection`
11
+ * service — the browser authentication + Host/Origin trust fence — is
12
+ * available, so a profile without it mounts no locator HTTP surface at all.
13
+ * Every request then asks that service for a rejection first; if the service
14
+ * disappeared or its check fails, the route answers 503 instead of allowing
15
+ * the call. On top of that fence each request must be a `POST` with an
16
+ * `application/json` content type (415 otherwise), the body is capped at
17
+ * 64 KiB, and a cross-site `Origin`/`Sec-Fetch-Site` marker is refused locally
18
+ * as defense in depth.
19
+ *
10
20
  * Registration is optional: headless and TUI profiles have no `webServer`
11
21
  * service, and the plugin still works there through its tools.
12
22
  * @module dsh-locator/http
13
23
  */
14
24
  import type { Context } from '@deepseek-ai/cordis';
25
+ import type { IncomingHttpHeaders } from 'node:http';
15
26
  import type { LocatorRuntime } from './runtime.ts';
16
27
  import type { ContentIndex } from './content.ts';
17
- /** Mount the panel's routes when this profile runs a Web server. */
28
+ /**
29
+ * Mount the panel's routes when this profile runs a Web server **and** the
30
+ * host connection trust fence. Without `connection` no route is registered:
31
+ * an unauthenticated locator HTTP surface is never exposed.
32
+ * @param ctx - plugin context.
33
+ * @param rt - locator runtime backing the name search.
34
+ * @param content - content index, when enabled.
35
+ * @param ensure - lazy content boot hook.
36
+ */
18
37
  export declare function registerHttp(ctx: Context, rt: LocatorRuntime, content?: ContentIndex, ensure?: () => void): void;
38
+ /**
39
+ * The exact JSON media type required by every locator route. A charset or any
40
+ * other parameter is tolerated (`application/json; charset=utf-8`), any other
41
+ * essence (including `text/plain` and a missing header) is not.
42
+ * @param value - the raw `content-type` header value.
43
+ */
44
+ export declare function isJsonContentType(value: string | string[] | undefined): boolean;
45
+ /**
46
+ * The local same-origin fence, defense in depth behind the host connection
47
+ * check. A `Sec-Fetch-Site: cross-site` marker is refused; when a browser
48
+ * attaches an `Origin`, it must name this listener's own authority. Requests
49
+ * without browser markers (CLI clients) pass: they are already gated by
50
+ * authentication.
51
+ * @param headers - request headers.
52
+ * @returns 403 when the request is provably cross-site, else undefined.
53
+ */
54
+ export declare function originRejection(headers: IncomingHttpHeaders): 403 | undefined;
19
55
  //# sourceMappingURL=http.d.ts.map
package/lib/http.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAgChD,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAwDhH"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAmC,MAAM,WAAW,CAAA;AACrF,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AA+ChD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAoChH;AA6GD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAK/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,GAAG,GAAG,SAAS,CAuB7E"}