ctxr-cli 0.29.0 → 0.31.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 (117) hide show
  1. package/README.md +43 -0
  2. package/dist/commands/land.d.ts.map +1 -1
  3. package/dist/commands/land.js +3 -18
  4. package/dist/commands/land.js.map +1 -1
  5. package/dist/commands/serve.d.ts.map +1 -1
  6. package/dist/commands/serve.js +10 -2
  7. package/dist/commands/serve.js.map +1 -1
  8. package/dist/config/defaults.d.ts +2 -0
  9. package/dist/config/defaults.d.ts.map +1 -1
  10. package/dist/config/defaults.js +2 -0
  11. package/dist/config/defaults.js.map +1 -1
  12. package/dist/config/schema.d.ts +39 -0
  13. package/dist/config/schema.d.ts.map +1 -1
  14. package/dist/config/schema.js +57 -8
  15. package/dist/config/schema.js.map +1 -1
  16. package/dist/core/browse/approve.d.ts +3 -0
  17. package/dist/core/browse/approve.d.ts.map +1 -1
  18. package/dist/core/browse/approve.js.map +1 -1
  19. package/dist/core/browse/page-url.d.ts +15 -0
  20. package/dist/core/browse/page-url.d.ts.map +1 -1
  21. package/dist/core/browse/page-url.js +8 -1
  22. package/dist/core/browse/page-url.js.map +1 -1
  23. package/dist/core/forge/credentials.d.ts +12 -1
  24. package/dist/core/forge/credentials.d.ts.map +1 -1
  25. package/dist/core/forge/credentials.js +25 -1
  26. package/dist/core/forge/credentials.js.map +1 -1
  27. package/dist/core/forge/github.d.ts +9 -0
  28. package/dist/core/forge/github.d.ts.map +1 -1
  29. package/dist/core/forge/github.js +6 -0
  30. package/dist/core/forge/github.js.map +1 -1
  31. package/dist/core/mcp/drafts.d.ts +30 -0
  32. package/dist/core/mcp/drafts.d.ts.map +1 -0
  33. package/dist/core/mcp/drafts.js +52 -0
  34. package/dist/core/mcp/drafts.js.map +1 -0
  35. package/dist/core/mcp/http.d.ts +40 -0
  36. package/dist/core/mcp/http.d.ts.map +1 -0
  37. package/dist/core/mcp/http.js +90 -0
  38. package/dist/core/mcp/http.js.map +1 -0
  39. package/dist/core/mcp/jsonrpc.d.ts +73 -0
  40. package/dist/core/mcp/jsonrpc.d.ts.map +1 -0
  41. package/dist/core/mcp/jsonrpc.js +149 -0
  42. package/dist/core/mcp/jsonrpc.js.map +1 -0
  43. package/dist/core/mcp/members.d.ts +11 -0
  44. package/dist/core/mcp/members.d.ts.map +1 -0
  45. package/dist/core/mcp/members.js +21 -0
  46. package/dist/core/mcp/members.js.map +1 -0
  47. package/dist/core/mcp/oauth.d.ts +99 -0
  48. package/dist/core/mcp/oauth.d.ts.map +1 -0
  49. package/dist/core/mcp/oauth.js +454 -0
  50. package/dist/core/mcp/oauth.js.map +1 -0
  51. package/dist/core/mcp/pages.d.ts +3 -0
  52. package/dist/core/mcp/pages.d.ts.map +1 -0
  53. package/dist/core/mcp/pages.js +41 -0
  54. package/dist/core/mcp/pages.js.map +1 -0
  55. package/dist/core/mcp/ripgrep.d.ts +48 -0
  56. package/dist/core/mcp/ripgrep.d.ts.map +1 -0
  57. package/dist/core/mcp/ripgrep.js +98 -0
  58. package/dist/core/mcp/ripgrep.js.map +1 -0
  59. package/dist/core/mcp/rwlock.d.ts +16 -0
  60. package/dist/core/mcp/rwlock.d.ts.map +1 -0
  61. package/dist/core/mcp/rwlock.js +59 -0
  62. package/dist/core/mcp/rwlock.js.map +1 -0
  63. package/dist/core/mcp/sessions.d.ts +84 -0
  64. package/dist/core/mcp/sessions.d.ts.map +1 -0
  65. package/dist/core/mcp/sessions.js +154 -0
  66. package/dist/core/mcp/sessions.js.map +1 -0
  67. package/dist/core/mcp/surface.d.ts +42 -0
  68. package/dist/core/mcp/surface.d.ts.map +1 -0
  69. package/dist/core/mcp/surface.js +141 -0
  70. package/dist/core/mcp/surface.js.map +1 -0
  71. package/dist/core/mcp/sync.d.ts +91 -0
  72. package/dist/core/mcp/sync.d.ts.map +1 -0
  73. package/dist/core/mcp/sync.js +218 -0
  74. package/dist/core/mcp/sync.js.map +1 -0
  75. package/dist/core/mcp/tools/capture.d.ts +64 -0
  76. package/dist/core/mcp/tools/capture.d.ts.map +1 -0
  77. package/dist/core/mcp/tools/capture.js +182 -0
  78. package/dist/core/mcp/tools/capture.js.map +1 -0
  79. package/dist/core/mcp/tools/edit.d.ts +79 -0
  80. package/dist/core/mcp/tools/edit.d.ts.map +1 -0
  81. package/dist/core/mcp/tools/edit.js +212 -0
  82. package/dist/core/mcp/tools/edit.js.map +1 -0
  83. package/dist/core/mcp/tools/files.d.ts +163 -0
  84. package/dist/core/mcp/tools/files.d.ts.map +1 -0
  85. package/dist/core/mcp/tools/files.js +265 -0
  86. package/dist/core/mcp/tools/files.js.map +1 -0
  87. package/dist/core/mcp/tools/find.d.ts +82 -0
  88. package/dist/core/mcp/tools/find.d.ts.map +1 -0
  89. package/dist/core/mcp/tools/find.js +136 -0
  90. package/dist/core/mcp/tools/find.js.map +1 -0
  91. package/dist/core/mcp/tools/gather.d.ts +88 -0
  92. package/dist/core/mcp/tools/gather.d.ts.map +1 -0
  93. package/dist/core/mcp/tools/gather.js +123 -0
  94. package/dist/core/mcp/tools/gather.js.map +1 -0
  95. package/dist/core/mcp/tools/index.d.ts +21 -0
  96. package/dist/core/mcp/tools/index.d.ts.map +1 -0
  97. package/dist/core/mcp/tools/index.js +129 -0
  98. package/dist/core/mcp/tools/index.js.map +1 -0
  99. package/dist/core/skills.d.ts +18 -2
  100. package/dist/core/skills.d.ts.map +1 -1
  101. package/dist/core/skills.js +51 -5
  102. package/dist/core/skills.js.map +1 -1
  103. package/dist/version.d.ts +1 -1
  104. package/dist/version.js +1 -1
  105. package/package.json +1 -1
  106. package/templates/mcp/Edit.md +7 -0
  107. package/templates/mcp/Glob.md +5 -0
  108. package/templates/mcp/Grep.md +10 -0
  109. package/templates/mcp/Read.md +7 -0
  110. package/templates/mcp/Write.md +7 -0
  111. package/templates/mcp/capture.md +9 -0
  112. package/templates/mcp/consent.html +40 -0
  113. package/templates/mcp/find.md +9 -0
  114. package/templates/mcp/gather.md +5 -0
  115. package/templates/mcp/server-instructions.md +17 -0
  116. package/templates/skills/ctxr-circleback/sweep.mjs +229 -0
  117. package/templates/skills/ctxr-circleback.md +70 -0
@@ -0,0 +1,136 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { joinBaseUrl, noteRoute } from '../../browse/page-url.js';
4
+ import { catalogSectionsFor, sectionForNote } from '../../catalog/model.js';
5
+ import { isUnderAnyPrefix } from '../../fs/prefix.js';
6
+ import { listCaptures, listNotes } from '../../notes/list.js';
7
+ import { readCatalogGlosses } from '../../records.js';
8
+ import { ToolRefusal } from '../jsonrpc.js';
9
+ /**
10
+ * remote-access spec, *`find` stands in for a client's own content
11
+ * matching*; context-retrieval's bounded exception. Literal,
12
+ * case-insensitive substring matching over the notes the store's
13
+ * enumeration admits, in path order, with no score. Captures — inbox files
14
+ * on the default branch and on pending `capture/` branches — come back in
15
+ * `unfiled`, never among the notes (context-ingest's exception, design.md
16
+ * D6). With no text, the catalog as a map to pick selectors from.
17
+ */
18
+ export const MAX_LINES_PER_HIT = 3;
19
+ export const MAX_LINE_CHARS = 240;
20
+ export const DEFAULT_MAX_MATCHES = 25;
21
+ export const DEFAULT_MAX_MAP_NOTES = 500;
22
+ export const MAX_RESULTS = 1000;
23
+ const MAX_TEXT_CHARS = 200;
24
+ /**
25
+ * Plain on purpose: type, description and required only. Some clients (Gemini) accept a narrow subset of JSON
26
+ * Schema and drop a tool whose schema uses more; every limit is enforced by `parseFindArgs` instead.
27
+ */
28
+ export const FIND_INPUT_SCHEMA = {
29
+ type: 'object',
30
+ properties: {
31
+ text: { type: 'string', description: 'Literal text to look for, case-insensitive. Omit it to get the map of the store instead.' },
32
+ under: { type: 'string', description: 'Only look under this folder of the store, e.g. "projects/".' },
33
+ max: { type: 'integer', description: `How many notes to return (default ${DEFAULT_MAX_MATCHES} when matching, ${DEFAULT_MAX_MAP_NOTES} for the map).` },
34
+ },
35
+ };
36
+ export function parseFindArgs(args) {
37
+ const out = {};
38
+ if (args.text !== undefined && args.text !== null) {
39
+ if (typeof args.text !== 'string')
40
+ throw new ToolRefusal('mcp.invalid_arguments', '"text" must be a string.');
41
+ if (args.text.length > MAX_TEXT_CHARS)
42
+ throw new ToolRefusal('mcp.invalid_arguments', `"text" is at most ${MAX_TEXT_CHARS} characters.`);
43
+ if (args.text.trim().length > 0)
44
+ out.text = args.text.trim();
45
+ }
46
+ if (args.under !== undefined && args.under !== null) {
47
+ if (typeof args.under !== 'string')
48
+ throw new ToolRefusal('mcp.invalid_arguments', '"under" must be a string.');
49
+ const under = args.under.trim().replace(/^\.?\/+/, '');
50
+ if (under.length > 0)
51
+ out.under = under;
52
+ }
53
+ if (args.max !== undefined && args.max !== null) {
54
+ if (typeof args.max !== 'number' || !Number.isInteger(args.max) || args.max < 1 || args.max > MAX_RESULTS) {
55
+ throw new ToolRefusal('mcp.invalid_arguments', `"max" must be a whole number from 1 to ${MAX_RESULTS}.`);
56
+ }
57
+ out.max = args.max;
58
+ }
59
+ return out;
60
+ }
61
+ function matchLines(text, needle) {
62
+ const lines = [];
63
+ let count = 0;
64
+ const all = text.split(/\r?\n/);
65
+ for (let i = 0; i < all.length; i += 1) {
66
+ const line = all[i];
67
+ if (!line.toLowerCase().includes(needle))
68
+ continue;
69
+ count += 1;
70
+ if (lines.length < MAX_LINES_PER_HIT) {
71
+ lines.push({ line: i + 1, text: line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS - 1)}…` : line });
72
+ }
73
+ }
74
+ return { lines, count };
75
+ }
76
+ const byPath = (a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
77
+ /** `baseUrl` is `serve.base_url` from the configuration `serve` loaded: links point at the browsing surface it answers. */
78
+ export async function find(snapshot, args, baseUrl) {
79
+ const store = snapshot.store;
80
+ const linkFor = (notePath) => joinBaseUrl(baseUrl, noteRoute(notePath));
81
+ const glosses = await readCatalogGlosses(store);
82
+ const scope = (p) => args.under === undefined || isUnderAnyPrefix(p, [args.under]);
83
+ const notes = (await listNotes(store.root, store.config)).filter((n) => scope(n.path)).sort(byPath);
84
+ if (args.text === undefined) {
85
+ const max = args.max ?? DEFAULT_MAX_MAP_NOTES;
86
+ const sections = catalogSectionsFor(store.config);
87
+ const grouped = new Map(sections.map((s) => [s.id, []]));
88
+ let listed = 0;
89
+ for (const note of notes) {
90
+ if (listed >= max)
91
+ break;
92
+ grouped.get(sectionForNote(sections, note.path).id).push({ path: note.path, gloss: glosses.get(note.path) ?? '', url: linkFor(note.path) });
93
+ listed += 1;
94
+ }
95
+ return {
96
+ mode: 'map',
97
+ sections: [...grouped.entries()].filter(([, entries]) => entries.length > 0).map(([id, entries]) => ({ id, notes: entries })),
98
+ notes_omitted: notes.length - listed,
99
+ };
100
+ }
101
+ const needle = args.text.toLowerCase();
102
+ const max = args.max ?? DEFAULT_MAX_MATCHES;
103
+ // Raw file text, frontmatter included, so line numbers are the file's own — what grep would report.
104
+ const noteHits = [];
105
+ for (const note of notes) {
106
+ const { lines, count } = matchLines(await readFile(path.join(store.root, note.path), 'utf8'), needle);
107
+ if (count > 0)
108
+ noteHits.push({ path: note.path, gloss: glosses.get(note.path) ?? '', lines, matching_lines: count, url: linkFor(note.path) });
109
+ }
110
+ const inbox = store.config.ingest.inbox_path;
111
+ const unfiled = [];
112
+ for (const capture of (await listCaptures(store.root, store.config)).sort(byPath)) {
113
+ if (!isUnderAnyPrefix(capture.path, [inbox]) || !scope(capture.path))
114
+ continue;
115
+ const { lines, count } = matchLines(await readFile(path.join(store.root, capture.path), 'utf8'), needle);
116
+ if (count > 0)
117
+ unfiled.push({ path: capture.path, lines, matching_lines: count, pending_merge: false, branch: null });
118
+ }
119
+ const pending = [...snapshot.pending].sort((a, b) => byPath(a, b) || (a.branch < b.branch ? -1 : 1));
120
+ for (const capture of pending) {
121
+ if (!scope(capture.path))
122
+ continue;
123
+ const { lines, count } = matchLines(capture.text, needle);
124
+ if (count > 0)
125
+ unfiled.push({ path: capture.path, lines, matching_lines: count, pending_merge: true, branch: capture.branch });
126
+ }
127
+ return {
128
+ mode: 'match',
129
+ text: args.text,
130
+ notes: noteHits.slice(0, max),
131
+ notes_omitted: Math.max(0, noteHits.length - max),
132
+ unfiled: unfiled.slice(0, max),
133
+ unfiled_omitted: Math.max(0, unfiled.length - max),
134
+ };
135
+ }
136
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../../src/core/mcp/tools/find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { type GatherOutcome, type GatherResult } from '../../retrieval/pass.js';
2
+ import type { Snapshot } from '../sync.js';
3
+ /**
4
+ * remote-access spec, *`gather` returns the retrieval pass with the bodies a
5
+ * client cannot read itself* (design.md D8). The pass runs unchanged against
6
+ * the view's notes and the view's own graph, and still returns no body; this
7
+ * attaches them afterwards, to a prefix of the pass's order, within a byte
8
+ * budget — so the cap never reorders anything, exactly as the pass's own cap.
9
+ */
10
+ export declare const DEFAULT_GATHER_MAX_BYTES = 60000;
11
+ export interface GatherArgs {
12
+ seeds?: string[];
13
+ sections?: string[];
14
+ under?: string[];
15
+ entities?: string[];
16
+ hops?: number;
17
+ direction?: 'in' | 'out' | 'both';
18
+ type?: string;
19
+ max_notes?: number;
20
+ }
21
+ export interface GatheredNote extends GatherResult {
22
+ /** The note's text, frontmatter included; null once the byte budget is spent. */
23
+ body: string | null;
24
+ /** Set on the first note only, when it alone exceeded the budget and was cut to it. */
25
+ body_clipped?: true;
26
+ }
27
+ export interface GatherToolResult extends Omit<GatherOutcome, 'notes'> {
28
+ notes: GatheredNote[];
29
+ bodies: {
30
+ max_bytes: number;
31
+ returned: number;
32
+ omitted: number;
33
+ };
34
+ }
35
+ /** Plain on purpose (see FIND_INPUT_SCHEMA): `parseGatherArgs` enforces every limit. */
36
+ export declare const GATHER_INPUT_SCHEMA: {
37
+ readonly type: 'object';
38
+ readonly properties: {
39
+ readonly seeds: {
40
+ readonly type: 'array';
41
+ readonly items: {
42
+ readonly type: 'string';
43
+ };
44
+ readonly description: 'Note paths to start from, usually from find.';
45
+ };
46
+ readonly sections: {
47
+ readonly type: 'array';
48
+ readonly items: {
49
+ readonly type: 'string';
50
+ };
51
+ readonly description: 'Catalog section ids whose notes to start from (find with no text lists them).';
52
+ };
53
+ readonly under: {
54
+ readonly type: 'array';
55
+ readonly items: {
56
+ readonly type: 'string';
57
+ };
58
+ readonly description: 'Folders whose notes to start from, e.g. "projects/".';
59
+ };
60
+ readonly entities: {
61
+ readonly type: 'array';
62
+ readonly items: {
63
+ readonly type: 'string';
64
+ };
65
+ readonly description: 'Note paths whose backlinks to start from: every note linking to them.';
66
+ };
67
+ readonly hops: {
68
+ readonly type: 'integer';
69
+ readonly description: 'How many links to follow out from the starting notes (default 1; 0 returns only them).';
70
+ };
71
+ readonly direction: {
72
+ readonly type: 'string';
73
+ readonly enum: readonly ['in', 'out', 'both'];
74
+ readonly description: 'Follow links pointing out, in, or both (default both).';
75
+ };
76
+ readonly type: {
77
+ readonly type: 'string';
78
+ readonly description: 'Follow only links of this relation type.';
79
+ };
80
+ readonly max_notes: {
81
+ readonly type: 'integer';
82
+ readonly description: 'Cap on how many notes to return; the omitted count is reported.';
83
+ };
84
+ };
85
+ };
86
+ export declare function parseGatherArgs(args: Record<string, unknown>): GatherArgs;
87
+ export declare function gatherWithBodies(snapshot: Snapshot, args: GatherArgs, maxBytes?: number): Promise<GatherToolResult>;
88
+ //# sourceMappingURL=gather.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../../src/core/mcp/tools/gather.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEnG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AAEH,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,iFAAiF;IACjF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uFAAuF;IACvF,YAAY,CAAC,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;IACpE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB;aAC9B,IAAI,EAAE,QAAQ;aACd,UAAU;iBACR,KAAK;qBAAI,IAAI,EAAE,OAAO;qBAAE,KAAK;yBAAI,IAAI,EAAE,QAAQ;;qBAAI,WAAW,EAAE,8CAA8C;;iBAC9G,QAAQ;qBAAI,IAAI,EAAE,OAAO;qBAAE,KAAK;yBAAI,IAAI,EAAE,QAAQ;;qBAAI,WAAW,EAAE,+EAA+E;;iBAClJ,KAAK;qBAAI,IAAI,EAAE,OAAO;qBAAE,KAAK;yBAAI,IAAI,EAAE,QAAQ;;qBAAI,WAAW,EAAE,sDAAsD;;iBACtH,QAAQ;qBAAI,IAAI,EAAE,OAAO;qBAAE,KAAK;yBAAI,IAAI,EAAE,QAAQ;;qBAAI,WAAW,EAAE,uEAAuE;;iBAC1I,IAAI;qBAAI,IAAI,EAAE,SAAS;qBAAE,WAAW,EAAE,wFAAwF;;iBAC9H,SAAS;qBAAI,IAAI,EAAE,QAAQ;qBAAE,IAAI,YAAG,IAAI,EAAE,KAAK,EAAE,MAAM;qBAAG,WAAW,EAAE,wDAAwD;;iBAC/H,IAAI;qBAAI,IAAI,EAAE,QAAQ;qBAAE,WAAW,EAAE,0CAA0C;;iBAC/E,SAAS;qBAAI,IAAI,EAAE,SAAS;qBAAE,WAAW,EAAE,iEAAiE;;;CAEtG,CAAC;AAqBX,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAuBzE;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,SAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiD3I"}
@@ -0,0 +1,123 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isUnderAnyPrefix } from '../../fs/prefix.js';
4
+ import { readAdmittedGraph } from '../../graph/persist.js';
5
+ import { listNotes } from '../../notes/list.js';
6
+ import { gather as runPass } from '../../retrieval/pass.js';
7
+ import { ToolRefusal } from '../jsonrpc.js';
8
+ /**
9
+ * remote-access spec, *`gather` returns the retrieval pass with the bodies a
10
+ * client cannot read itself* (design.md D8). The pass runs unchanged against
11
+ * the view's notes and the view's own graph, and still returns no body; this
12
+ * attaches them afterwards, to a prefix of the pass's order, within a byte
13
+ * budget — so the cap never reorders anything, exactly as the pass's own cap.
14
+ */
15
+ export const DEFAULT_GATHER_MAX_BYTES = 60_000;
16
+ /** Plain on purpose (see FIND_INPUT_SCHEMA): `parseGatherArgs` enforces every limit. */
17
+ export const GATHER_INPUT_SCHEMA = {
18
+ type: 'object',
19
+ properties: {
20
+ seeds: { type: 'array', items: { type: 'string' }, description: 'Note paths to start from, usually from find.' },
21
+ sections: { type: 'array', items: { type: 'string' }, description: 'Catalog section ids whose notes to start from (find with no text lists them).' },
22
+ under: { type: 'array', items: { type: 'string' }, description: 'Folders whose notes to start from, e.g. "projects/".' },
23
+ entities: { type: 'array', items: { type: 'string' }, description: 'Note paths whose backlinks to start from: every note linking to them.' },
24
+ hops: { type: 'integer', description: 'How many links to follow out from the starting notes (default 1; 0 returns only them).' },
25
+ direction: { type: 'string', enum: ['in', 'out', 'both'], description: 'Follow links pointing out, in, or both (default both).' },
26
+ type: { type: 'string', description: 'Follow only links of this relation type.' },
27
+ max_notes: { type: 'integer', description: 'Cap on how many notes to return; the omitted count is reported.' },
28
+ },
29
+ };
30
+ function stringList(args, key) {
31
+ const value = args[key];
32
+ if (value === undefined || value === null)
33
+ return undefined;
34
+ const list = typeof value === 'string' ? [value] : value;
35
+ if (!Array.isArray(list) || !list.every((v) => typeof v === 'string' && v.trim().length > 0)) {
36
+ throw new ToolRefusal('mcp.invalid_arguments', `"${key}" must be a list of non-empty strings.`);
37
+ }
38
+ return list.map((v) => v.trim().replace(/^\.?\/+/, ''));
39
+ }
40
+ function wholeNumber(args, key, min, max) {
41
+ const value = args[key];
42
+ if (value === undefined || value === null)
43
+ return undefined;
44
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) {
45
+ throw new ToolRefusal('mcp.invalid_arguments', `"${key}" must be a whole number from ${min} to ${max}.`);
46
+ }
47
+ return value;
48
+ }
49
+ export function parseGatherArgs(args) {
50
+ const out = {
51
+ seeds: stringList(args, 'seeds'),
52
+ sections: stringList(args, 'sections'),
53
+ under: stringList(args, 'under'),
54
+ entities: stringList(args, 'entities'),
55
+ hops: wholeNumber(args, 'hops', 0, 5),
56
+ max_notes: wholeNumber(args, 'max_notes', 1, 500),
57
+ };
58
+ if (args.direction !== undefined && args.direction !== null) {
59
+ if (args.direction !== 'in' && args.direction !== 'out' && args.direction !== 'both') {
60
+ throw new ToolRefusal('mcp.invalid_arguments', '"direction" is one of in, out, both.');
61
+ }
62
+ out.direction = args.direction;
63
+ }
64
+ if (args.type !== undefined && args.type !== null) {
65
+ if (typeof args.type !== 'string')
66
+ throw new ToolRefusal('mcp.invalid_arguments', '"type" must be a string.');
67
+ out.type = args.type;
68
+ }
69
+ if ([out.seeds, out.sections, out.under, out.entities].every((l) => l === undefined || l.length === 0)) {
70
+ throw new ToolRefusal('mcp.invalid_arguments', 'Name at least one starting point: seeds, sections, under or entities. Use find first to get note paths.');
71
+ }
72
+ return out;
73
+ }
74
+ export async function gatherWithBodies(snapshot, args, maxBytes = DEFAULT_GATHER_MAX_BYTES) {
75
+ const store = snapshot.store;
76
+ const captureRoot = store.config.ingest.capture_root;
77
+ for (const seed of args.seeds ?? []) {
78
+ if (isUnderAnyPrefix(seed, [captureRoot])) {
79
+ throw new ToolRefusal('mcp.capture_not_filed', `"${seed}" is a capture that has not been filed into a note yet, so it cannot start a gather; read it with Read instead.`, { path: seed });
80
+ }
81
+ }
82
+ const notes = await listNotes(store.root, store.config);
83
+ const graph = await readAdmittedGraph(store);
84
+ const pass = await runPass(store, notes, graph, {
85
+ seeds: args.seeds,
86
+ sections: args.sections,
87
+ under: args.under,
88
+ entities: args.entities,
89
+ hops: args.hops,
90
+ direction: args.direction,
91
+ type: args.type,
92
+ maxNotes: args.max_notes,
93
+ });
94
+ let spent = 0;
95
+ let open = true;
96
+ let returned = 0;
97
+ const withBodies = [];
98
+ for (const [index, note] of pass.notes.entries()) {
99
+ if (!open) {
100
+ withBodies.push({ ...note, body: null });
101
+ continue;
102
+ }
103
+ const text = await readFile(path.join(store.root, note.path), 'utf8');
104
+ const bytes = Buffer.byteLength(text, 'utf8');
105
+ if (spent + bytes <= maxBytes) {
106
+ spent += bytes;
107
+ returned += 1;
108
+ withBodies.push({ ...note, body: text });
109
+ }
110
+ else if (index === 0) {
111
+ // A call never comes back with no text at all: the first note is cut to the budget and says so.
112
+ withBodies.push({ ...note, body: Buffer.from(text, 'utf8').subarray(0, maxBytes).toString('utf8'), body_clipped: true });
113
+ returned += 1;
114
+ open = false;
115
+ }
116
+ else {
117
+ withBodies.push({ ...note, body: null });
118
+ open = false;
119
+ }
120
+ }
121
+ return { ...pass, notes: withBodies, bodies: { max_bytes: maxBytes, returned, omitted: pass.notes.length - returned } };
122
+ }
123
+ //# sourceMappingURL=gather.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../../src/core/mcp/tools/gather.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ToolDefinition } from '../jsonrpc.js';
2
+ import type { Principal } from '../oauth.js';
3
+ import type { Mutex, WriteDeps } from '../sessions.js';
4
+ import type { McpView, SyncDeps } from '../sync.js';
5
+ /**
6
+ * The remote surface's tool set and the prose that describes it
7
+ * (templates/mcp/, shipped-prose-lives-in-templates). Built per request from
8
+ * the server's current state. Reads go through `view.read`, so each sees one
9
+ * commit and names it; writes go through the one mutex (design.md D9, D13).
10
+ */
11
+ export declare function serverInstructions(storeName: string): string;
12
+ export interface ToolContext {
13
+ view: McpView;
14
+ syncDeps: SyncDeps;
15
+ write: WriteDeps;
16
+ mutex: Mutex;
17
+ /** `serve.base_url` from the loaded configuration. */
18
+ baseUrl: string | undefined;
19
+ }
20
+ export declare function buildTools(ctx: ToolContext): ToolDefinition<Principal>[];
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/mcp/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAoBpD;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAWD,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,EAAE,CAuGxE"}
@@ -0,0 +1,129 @@
1
+ import { packagedTemplate } from '../../templates.js';
2
+ import { asToolRefusal, capture, CAPTURE_INPUT_SCHEMA, parseCaptureArgs } from './capture.js';
3
+ import { EDIT_INPUT_SCHEMA, editTool, parseEditArgs, parseWriteArgs, WRITE_INPUT_SCHEMA, writeTool } from './edit.js';
4
+ import { GLOB_INPUT_SCHEMA, globTool, GREP_INPUT_SCHEMA, grepTool, parseGlobArgs, parseGrepArgs, parseReadArgs, READ_INPUT_SCHEMA, readTool, renderGlob, renderGrep, renderRead, } from './files.js';
5
+ import { find, FIND_INPUT_SCHEMA, parseFindArgs } from './find.js';
6
+ import { GATHER_INPUT_SCHEMA, gatherWithBodies, parseGatherArgs } from './gather.js';
7
+ /**
8
+ * The remote surface's tool set and the prose that describes it
9
+ * (templates/mcp/, shipped-prose-lives-in-templates). Built per request from
10
+ * the server's current state. Reads go through `view.read`, so each sees one
11
+ * commit and names it; writes go through the one mutex (design.md D9, D13).
12
+ */
13
+ export function serverInstructions(storeName) {
14
+ return packagedTemplate('mcp', 'server-instructions').replaceAll('__STORE_NAME__', storeName);
15
+ }
16
+ /** Writes surface a WriteRefusal as a refusal the client model can read. */
17
+ async function writing(ctx, fn) {
18
+ try {
19
+ return await ctx.mutex.run(fn);
20
+ }
21
+ catch (err) {
22
+ throw asToolRefusal(err);
23
+ }
24
+ }
25
+ export function buildTools(ctx) {
26
+ const read = (fn) => ctx.view.read(ctx.syncDeps, fn);
27
+ return [
28
+ {
29
+ name: 'find',
30
+ title: 'Find in the store',
31
+ description: packagedTemplate('mcp', 'find'),
32
+ inputSchema: FIND_INPUT_SCHEMA,
33
+ scope: 'read',
34
+ readOnly: true,
35
+ run: (args) => {
36
+ const parsed = parseFindArgs(args);
37
+ return read((snapshot) => find(snapshot, parsed, ctx.baseUrl));
38
+ },
39
+ },
40
+ {
41
+ name: 'gather',
42
+ title: 'Gather related notes',
43
+ description: packagedTemplate('mcp', 'gather'),
44
+ inputSchema: GATHER_INPUT_SCHEMA,
45
+ scope: 'read',
46
+ readOnly: true,
47
+ run: (args) => {
48
+ const parsed = parseGatherArgs(args);
49
+ return read((snapshot) => gatherWithBodies(snapshot, parsed));
50
+ },
51
+ },
52
+ {
53
+ name: 'Read',
54
+ title: 'Read a file',
55
+ description: packagedTemplate('mcp', 'Read'),
56
+ inputSchema: READ_INPUT_SCHEMA,
57
+ scope: 'read',
58
+ readOnly: true,
59
+ render: renderRead,
60
+ run: (args, principal) => {
61
+ const parsed = parseReadArgs(args);
62
+ return read((snapshot) => readTool(snapshot, ctx.write, principal.email, parsed));
63
+ },
64
+ },
65
+ {
66
+ name: 'Grep',
67
+ title: 'Search file contents',
68
+ description: packagedTemplate('mcp', 'Grep'),
69
+ inputSchema: GREP_INPUT_SCHEMA,
70
+ scope: 'read',
71
+ readOnly: true,
72
+ render: renderGrep,
73
+ run: (args) => {
74
+ const parsed = parseGrepArgs(args);
75
+ return read((snapshot) => grepTool(snapshot, parsed));
76
+ },
77
+ },
78
+ {
79
+ name: 'Glob',
80
+ title: 'Find files by name',
81
+ description: packagedTemplate('mcp', 'Glob'),
82
+ inputSchema: GLOB_INPUT_SCHEMA,
83
+ scope: 'read',
84
+ readOnly: true,
85
+ render: renderGlob,
86
+ run: (args) => {
87
+ const parsed = parseGlobArgs(args);
88
+ return read((snapshot) => globTool(snapshot, parsed));
89
+ },
90
+ },
91
+ {
92
+ name: 'capture',
93
+ title: 'Capture into the store',
94
+ description: packagedTemplate('mcp', 'capture'),
95
+ inputSchema: CAPTURE_INPUT_SCHEMA,
96
+ scope: 'capture',
97
+ readOnly: false,
98
+ run: (args, principal) => {
99
+ const parsed = parseCaptureArgs(args);
100
+ return writing(ctx, () => capture({ view: ctx.view, syncDeps: ctx.syncDeps, write: ctx.write }, principal.email, parsed));
101
+ },
102
+ },
103
+ {
104
+ name: 'Edit',
105
+ title: 'Edit a note',
106
+ description: packagedTemplate('mcp', 'Edit'),
107
+ inputSchema: EDIT_INPUT_SCHEMA,
108
+ scope: 'edit',
109
+ readOnly: false,
110
+ run: (args, principal) => {
111
+ const parsed = parseEditArgs(args);
112
+ return writing(ctx, () => editTool({ view: ctx.view, syncDeps: ctx.syncDeps, write: ctx.write }, principal.email, parsed));
113
+ },
114
+ },
115
+ {
116
+ name: 'Write',
117
+ title: 'Create a note',
118
+ description: packagedTemplate('mcp', 'Write'),
119
+ inputSchema: WRITE_INPUT_SCHEMA,
120
+ scope: 'edit',
121
+ readOnly: false,
122
+ run: (args, principal) => {
123
+ const parsed = parseWriteArgs(args);
124
+ return writing(ctx, () => writeTool({ view: ctx.view, syncDeps: ctx.syncDeps, write: ctx.write }, principal.email, parsed));
125
+ },
126
+ },
127
+ ];
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/mcp/tools/index.ts"],"names":[],"mappings":"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"}
@@ -38,12 +38,28 @@ export interface SkillSeed {
38
38
  description: string;
39
39
  /** The markdown body below the H1, one entry per line, rendered against the store's config. */
40
40
  body: (config: StoreConfig) => string[];
41
- /** Packaged files beside SKILL.md, verbatim. Absent for a skill that is one file. */
42
- supportingFiles?: () => ReadonlyMap<string, string>;
41
+ /**
42
+ * Packaged files beside SKILL.md. Absent for a skill that is one file.
43
+ * circleback-sweep: given the store's config, so a skill whose runner cannot
44
+ * read `contexture.yaml` itself (it uses the Node standard library only, which
45
+ * parses no YAML) can ship the settings it needs as a rendered file.
46
+ */
47
+ supportingFiles?: (config: StoreConfig) => ReadonlyMap<string, string>;
48
+ /**
49
+ * circleback-sweep: present only on an opt-in skill, which is written when
50
+ * this returns true for the store's config. When it turns false, the skill
51
+ * is no longer shipped to that store and `ctxr update` removes its managed
52
+ * directory like any skill the package stopped shipping.
53
+ */
54
+ enabled?: (config: StoreConfig) => boolean;
43
55
  }
44
56
  export declare const MANAGED_SKILL_HEADER = "<!-- Owned by contexture \u2014 written by `ctxr init`, refreshed by `ctxr update`. Do not edit; add your own skills alongside. -->";
45
57
  export declare function terminatingLayers(config: StoreConfig): TaxonomyLayerConfig[];
46
58
  export declare function retiredLayers(config: StoreConfig): TaxonomyLayerConfig[];
59
+ /** Owned skills a store gets only by opting in; each carries `enabled`. */
60
+ export declare const OPTIONAL_SKILLS: readonly SkillSeed[];
61
+ /** Every owned skill this store is shipped: the full set plus the opt-in ones its config enables. */
62
+ export declare function activeSkillSeeds(config: StoreConfig): SkillSeed[];
47
63
  export declare const SKILLS: readonly SkillSeed[];
48
64
  /** The owned skills, rendered against one store's configuration — what `syncShippedSkills` writes. */
49
65
  export declare function renderSkills(config: StoreConfig): Skill[];
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAsCjF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,KAAK;IACpB,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,uGAAuG;IACvG,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,IAAI,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,EAAE,CAAC;IACxC,qFAAqF;IACrF,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrD;AAED,eAAO,MAAM,oBAAoB,wIACiG,CAAC;AAYnI,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,EAAE,CAE5E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,EAAE,CAExE;AA8QD,eAAO,MAAM,MAAM,EAAE,SAAS,SAAS,EAkBtC,CAAC;AAEF,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,EAAE,CAEzD;AAYD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAEnF;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAMxD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE5F;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmDtH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,SAAS,SAAS,EAAW,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiB/H;AAwBD;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6FAA6F;AAC7F,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;AAyDnE;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CA6EpJ"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}