@graphmemory/server 1.1.0 → 1.3.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 (104) hide show
  1. package/LICENSE +84 -12
  2. package/README.md +66 -101
  3. package/dist/api/index.js +279 -169
  4. package/dist/api/rest/index.js +36 -16
  5. package/dist/api/rest/tools.js +8 -1
  6. package/dist/api/rest/websocket.js +22 -1
  7. package/dist/api/tools/code/search-code.js +12 -9
  8. package/dist/api/tools/code/search-files.js +1 -1
  9. package/dist/api/tools/docs/cross-references.js +3 -2
  10. package/dist/api/tools/docs/explain-symbol.js +2 -1
  11. package/dist/api/tools/docs/find-examples.js +2 -1
  12. package/dist/api/tools/docs/search-files.js +1 -1
  13. package/dist/api/tools/docs/search-snippets.js +1 -1
  14. package/dist/api/tools/docs/search.js +5 -4
  15. package/dist/api/tools/file-index/search-all-files.js +1 -1
  16. package/dist/api/tools/knowledge/add-attachment.js +14 -3
  17. package/dist/api/tools/knowledge/create-relation.js +2 -2
  18. package/dist/api/tools/knowledge/delete-relation.js +2 -2
  19. package/dist/api/tools/knowledge/find-linked-notes.js +1 -1
  20. package/dist/api/tools/knowledge/remove-attachment.js +5 -1
  21. package/dist/api/tools/knowledge/search-notes.js +5 -4
  22. package/dist/api/tools/skills/add-attachment.js +14 -3
  23. package/dist/api/tools/skills/recall-skills.js +1 -1
  24. package/dist/api/tools/skills/remove-attachment.js +5 -1
  25. package/dist/api/tools/skills/search-skills.js +6 -5
  26. package/dist/api/tools/tasks/add-attachment.js +14 -3
  27. package/dist/api/tools/tasks/create-task-link.js +1 -1
  28. package/dist/api/tools/tasks/delete-task-link.js +1 -1
  29. package/dist/api/tools/tasks/find-linked-tasks.js +1 -1
  30. package/dist/api/tools/tasks/remove-attachment.js +5 -1
  31. package/dist/api/tools/tasks/search-tasks.js +5 -4
  32. package/dist/cli/index.js +69 -311
  33. package/dist/cli/indexer.js +61 -29
  34. package/dist/graphs/code.js +70 -7
  35. package/dist/graphs/docs.js +15 -2
  36. package/dist/graphs/file-index.js +20 -6
  37. package/dist/graphs/file-lang.js +1 -1
  38. package/dist/graphs/knowledge.js +20 -3
  39. package/dist/graphs/manager-types.js +1 -1
  40. package/dist/graphs/skill.js +23 -4
  41. package/dist/graphs/task.js +23 -4
  42. package/dist/lib/embedding-codec.js +65 -0
  43. package/dist/lib/file-mirror.js +7 -7
  44. package/dist/lib/frontmatter.js +3 -2
  45. package/dist/lib/jwt.js +4 -4
  46. package/dist/lib/mirror-watcher.js +5 -4
  47. package/dist/lib/multi-config.js +60 -1
  48. package/dist/lib/parsers/code.js +158 -31
  49. package/dist/lib/parsers/codeblock.js +11 -6
  50. package/dist/lib/parsers/docs.js +59 -31
  51. package/dist/lib/parsers/languages/registry.js +10 -4
  52. package/dist/lib/parsers/languages/typescript.js +195 -48
  53. package/dist/lib/project-manager.js +14 -10
  54. package/dist/lib/search/bm25.js +18 -1
  55. package/dist/lib/search/code.js +12 -3
  56. package/dist/lib/watcher.js +17 -9
  57. package/dist/ui/assets/NoteForm-aZX9f6-3.js +1 -0
  58. package/dist/ui/assets/SkillForm-KYa3o92l.js +1 -0
  59. package/dist/ui/assets/TaskForm-Bl5nkybO.js +1 -0
  60. package/dist/ui/assets/_articleId_-DjbCByxM.js +1 -0
  61. package/dist/ui/assets/_docId_-hdCDjclV.js +1 -0
  62. package/dist/ui/assets/_filePath_-CpG836v4.js +1 -0
  63. package/dist/ui/assets/_noteId_-C1enaQd1.js +1 -0
  64. package/dist/ui/assets/_skillId_-hPoCet7J.js +1 -0
  65. package/dist/ui/assets/_taskId_-DSB3dLVz.js +1 -0
  66. package/dist/ui/assets/_toolName_-3SmCfxZy.js +2 -0
  67. package/dist/ui/assets/api-BMnBjMMf.js +1 -0
  68. package/dist/ui/assets/api-BlFF6gX-.js +1 -0
  69. package/dist/ui/assets/api-CrGJOcaN.js +1 -0
  70. package/dist/ui/assets/api-DuX-0a_X.js +1 -0
  71. package/dist/ui/assets/attachments-CEQ-2nMo.js +1 -0
  72. package/dist/ui/assets/client-Bq88u7gN.js +1 -0
  73. package/dist/ui/assets/docs-CrXsRcOG.js +1 -0
  74. package/dist/ui/assets/edit-BYiy1FZy.js +1 -0
  75. package/dist/ui/assets/edit-TUIIpUMF.js +1 -0
  76. package/dist/ui/assets/edit-hc-ZWz3y.js +1 -0
  77. package/dist/ui/assets/esm-BWiKNcBW.js +1 -0
  78. package/dist/ui/assets/files-0bPg6NH9.js +1 -0
  79. package/dist/ui/assets/graph-DXGud_wF.js +1 -0
  80. package/dist/ui/assets/help-CEMQqZUR.js +891 -0
  81. package/dist/ui/assets/help-DJ52_fxN.js +1 -0
  82. package/dist/ui/assets/index-BCZDAYZi.js +2 -0
  83. package/dist/ui/assets/index-D6zSNtzo.css +1 -0
  84. package/dist/ui/assets/knowledge-DeygeGGH.js +1 -0
  85. package/dist/ui/assets/new-CpD7hOBA.js +1 -0
  86. package/dist/ui/assets/new-DHTg3Dqq.js +1 -0
  87. package/dist/ui/assets/new-s8c0M75X.js +1 -0
  88. package/dist/ui/assets/prompts-BgOmdxgM.js +295 -0
  89. package/dist/ui/assets/rolldown-runtime-Dw2cE7zH.js +1 -0
  90. package/dist/ui/assets/search-EpJhdP2a.js +1 -0
  91. package/dist/ui/assets/skill-y9pizyqE.js +1 -0
  92. package/dist/ui/assets/skills-Cga9iUZN.js +1 -0
  93. package/dist/ui/assets/tasks-CobouTKV.js +1 -0
  94. package/dist/ui/assets/tools-JxKH5BDF.js +1 -0
  95. package/dist/ui/assets/vendor-graph-BWpSgpMe.js +321 -0
  96. package/dist/ui/assets/vendor-markdown-CT8ZVEPu.js +50 -0
  97. package/dist/ui/assets/vendor-md-editor-DmWafJvr.js +44 -0
  98. package/dist/ui/assets/{index-kKd4mVrh.css → vendor-md-editor-HrwGbQou.css} +1 -1
  99. package/dist/ui/assets/vendor-mui-BPj7d3Sw.js +139 -0
  100. package/dist/ui/assets/vendor-mui-icons-B196sG3f.js +1 -0
  101. package/dist/ui/assets/vendor-react-CHUjhoxh.js +11 -0
  102. package/dist/ui/index.html +11 -3
  103. package/package.json +2 -2
  104. package/dist/ui/assets/index-D6oxrVF7.js +0 -1759
@@ -13,11 +13,46 @@ function getDocComment(node) {
13
13
  }
14
14
  return '';
15
15
  }
16
- /** Build a signature: first line of the node text (truncated to 200 chars). */
17
- function buildSignature(node) {
18
- const text = node.text ?? '';
19
- const firstLine = text.split('\n')[0].trim();
20
- return firstLine.length > 200 ? firstLine.slice(0, 200) + '…' : firstLine;
16
+ /** Collapse whitespace and truncate. */
17
+ function truncate(text, maxLen = 300) {
18
+ const collapsed = text.replace(/\s+/g, ' ').trim();
19
+ return collapsed.length > maxLen ? collapsed.slice(0, maxLen) + '' : collapsed;
20
+ }
21
+ /**
22
+ * Build signature by taking everything before the body node.
23
+ * For code (ASCII-dominated), byte offset ≈ char offset.
24
+ * Falls back to first line if no body found.
25
+ */
26
+ function buildSignature(outerNode, innerNode) {
27
+ const bodyNode = innerNode.childForFieldName('body');
28
+ const text = outerNode.text ?? '';
29
+ if (!bodyNode) {
30
+ // No body (type alias, ambient declaration, etc.) — use full text
31
+ return truncate(text);
32
+ }
33
+ // Slice text from outer start up to body start
34
+ const headerBytes = bodyNode.startIndex - outerNode.startIndex;
35
+ if (headerBytes > 0) {
36
+ return truncate(text.slice(0, headerBytes));
37
+ }
38
+ return truncate(text.split('\n')[0]);
39
+ }
40
+ /**
41
+ * Build signature for variable declarations.
42
+ * If value is arrow/function, strip the function body.
43
+ */
44
+ function buildVariableSignature(outerNode, declarator) {
45
+ const value = declarator.childForFieldName('value');
46
+ if (value) {
47
+ const valueBody = value.childForFieldName('body');
48
+ if (valueBody) {
49
+ const fullText = outerNode.text ?? '';
50
+ const bodyOffset = valueBody.startIndex - outerNode.startIndex;
51
+ if (bodyOffset > 0)
52
+ return truncate(fullText.slice(0, bodyOffset));
53
+ }
54
+ }
55
+ return truncate(outerNode.text ?? '');
21
56
  }
22
57
  /** Build the full body text for a symbol. Includes JSDoc + node text. */
23
58
  function buildBody(node, docComment) {
@@ -26,14 +61,6 @@ function buildBody(node, docComment) {
26
61
  }
27
62
  return node.text ?? '';
28
63
  }
29
- /** Build a signature that includes the JSDoc first line if present. */
30
- function buildFullSignature(node, docComment) {
31
- if (docComment) {
32
- const firstDocLine = docComment.split('\n')[0].trim();
33
- return firstDocLine;
34
- }
35
- return buildSignature(node);
36
- }
37
64
  /** Check if a node is inside an export_statement. */
38
65
  function isExported(node) {
39
66
  const parent = node.parent;
@@ -53,76 +80,171 @@ function startLine(node) {
53
80
  function endLine(node) {
54
81
  return (node.endPosition?.row ?? 0) + 1;
55
82
  }
83
+ /**
84
+ * Extract the base type name from a type node, handling generic types.
85
+ * `Foo` → "Foo", `Foo<T>` (generic_type) → "Foo"
86
+ */
87
+ function extractTypeName(node) {
88
+ if (node.type === 'identifier' || node.type === 'type_identifier') {
89
+ return node.text;
90
+ }
91
+ if (node.type === 'generic_type') {
92
+ const name = node.childForFieldName('name') ?? node.namedChildren?.[0];
93
+ if (name && (name.type === 'identifier' || name.type === 'type_identifier')) {
94
+ return name.text;
95
+ }
96
+ }
97
+ return null;
98
+ }
56
99
  // ---------------------------------------------------------------------------
57
100
  // Symbol extraction
58
101
  // ---------------------------------------------------------------------------
59
- function extractClassSymbol(node) {
60
- const outer = getOuterNode(node);
61
- const doc = getDocComment(outer);
62
- const name = node.childForFieldName('name')?.text ?? '';
63
- const body = node.childForFieldName('body');
64
- // Extract methods
102
+ /** Extract class members: methods, fields, getters/setters. */
103
+ function extractClassMembers(body) {
65
104
  const children = [];
66
- if (body) {
67
- for (const member of body.namedChildren) {
68
- if (member.type === 'method_definition') {
105
+ if (!body)
106
+ return children;
107
+ for (const member of body.namedChildren) {
108
+ switch (member.type) {
109
+ case 'method_definition':
110
+ case 'abstract_method_definition':
111
+ case 'abstract_method_signature': {
69
112
  const methodName = member.childForFieldName('name')?.text ?? '';
70
113
  if (!methodName)
71
114
  continue;
72
115
  const methodDoc = getDocComment(member);
73
116
  children.push({
74
117
  name: methodName,
75
- kind: 'method',
76
- signature: buildSignature(member),
118
+ kind: methodName === 'constructor' ? 'constructor' : 'method',
119
+ signature: buildSignature(member, member),
77
120
  docComment: methodDoc,
78
121
  body: buildBody(member, methodDoc),
79
122
  startLine: startLine(member),
80
123
  endLine: endLine(member),
81
124
  isExported: false,
82
125
  });
126
+ break;
127
+ }
128
+ case 'public_field_definition':
129
+ case 'property_definition': {
130
+ const fieldName = member.childForFieldName('name')?.text ?? '';
131
+ if (!fieldName)
132
+ continue;
133
+ const fieldDoc = getDocComment(member);
134
+ children.push({
135
+ name: fieldName,
136
+ kind: 'variable',
137
+ signature: truncate(member.text ?? ''),
138
+ docComment: fieldDoc,
139
+ body: buildBody(member, fieldDoc),
140
+ startLine: startLine(member),
141
+ endLine: endLine(member),
142
+ isExported: false,
143
+ });
144
+ break;
83
145
  }
84
146
  }
85
147
  }
148
+ return children;
149
+ }
150
+ function extractClassSymbol(node) {
151
+ const outer = getOuterNode(node);
152
+ const doc = getDocComment(outer);
153
+ const name = node.childForFieldName('name')?.text ?? '';
154
+ const body = node.childForFieldName('body');
155
+ const children = extractClassMembers(body);
86
156
  return {
87
157
  name,
88
158
  kind: 'class',
89
- signature: buildFullSignature(outer, doc),
159
+ signature: buildSignature(outer, node),
90
160
  docComment: doc,
91
161
  body: buildBody(outer, doc),
92
162
  startLine: startLine(outer),
93
163
  endLine: endLine(outer),
94
164
  isExported: isExported(node),
95
- children,
165
+ children: children.length > 0 ? children : undefined,
96
166
  };
97
167
  }
168
+ /** Extract nested named function declarations from a function body (1 level deep). */
169
+ function extractNestedFunctions(body) {
170
+ const nested = [];
171
+ if (!body || body.type !== 'statement_block')
172
+ return nested;
173
+ for (const stmt of body.namedChildren) {
174
+ if (stmt.type === 'function_declaration') {
175
+ const childName = stmt.childForFieldName('name')?.text;
176
+ if (!childName)
177
+ continue;
178
+ const childDoc = getDocComment(stmt);
179
+ nested.push({
180
+ name: childName,
181
+ kind: 'function',
182
+ signature: buildSignature(stmt, stmt),
183
+ docComment: childDoc,
184
+ body: buildBody(stmt, childDoc),
185
+ startLine: startLine(stmt),
186
+ endLine: endLine(stmt),
187
+ isExported: false,
188
+ });
189
+ }
190
+ }
191
+ return nested;
192
+ }
98
193
  function extractFunctionSymbol(node) {
99
194
  const outer = getOuterNode(node);
100
195
  const doc = getDocComment(outer);
101
196
  const name = node.childForFieldName('name')?.text ?? '';
197
+ const body = node.childForFieldName('body');
198
+ const children = extractNestedFunctions(body);
102
199
  return {
103
200
  name,
104
201
  kind: 'function',
105
- signature: buildFullSignature(outer, doc),
202
+ signature: buildSignature(outer, node),
106
203
  docComment: doc,
107
204
  body: buildBody(outer, doc),
108
205
  startLine: startLine(outer),
109
206
  endLine: endLine(outer),
110
207
  isExported: isExported(node),
208
+ children: children.length > 0 ? children : undefined,
111
209
  };
112
210
  }
113
211
  function extractInterfaceSymbol(node) {
114
212
  const outer = getOuterNode(node);
115
213
  const doc = getDocComment(outer);
116
214
  const name = node.childForFieldName('name')?.text ?? '';
215
+ // Extract interface members
216
+ const children = [];
217
+ const body = node.childForFieldName('body');
218
+ if (body) {
219
+ for (const member of body.namedChildren) {
220
+ if (member.type === 'property_signature' || member.type === 'method_signature') {
221
+ const memberName = member.childForFieldName('name')?.text ?? '';
222
+ if (!memberName)
223
+ continue;
224
+ const memberDoc = getDocComment(member);
225
+ children.push({
226
+ name: memberName,
227
+ kind: member.type === 'method_signature' ? 'method' : 'variable',
228
+ signature: truncate(member.text ?? ''),
229
+ docComment: memberDoc,
230
+ body: buildBody(member, memberDoc),
231
+ startLine: startLine(member),
232
+ endLine: endLine(member),
233
+ isExported: false,
234
+ });
235
+ }
236
+ }
237
+ }
117
238
  return {
118
239
  name,
119
240
  kind: 'interface',
120
- signature: buildFullSignature(outer, doc),
241
+ signature: buildSignature(outer, node),
121
242
  docComment: doc,
122
243
  body: buildBody(outer, doc),
123
244
  startLine: startLine(outer),
124
245
  endLine: endLine(outer),
125
246
  isExported: isExported(node),
247
+ children: children.length > 0 ? children : undefined,
126
248
  };
127
249
  }
128
250
  function extractTypeAliasSymbol(node) {
@@ -132,7 +254,7 @@ function extractTypeAliasSymbol(node) {
132
254
  return {
133
255
  name,
134
256
  kind: 'type',
135
- signature: buildFullSignature(outer, doc),
257
+ signature: truncate(outer.text ?? ''),
136
258
  docComment: doc,
137
259
  body: buildBody(outer, doc),
138
260
  startLine: startLine(outer),
@@ -147,7 +269,7 @@ function extractEnumSymbol(node) {
147
269
  return {
148
270
  name,
149
271
  kind: 'enum',
150
- signature: buildFullSignature(outer, doc),
272
+ signature: buildSignature(outer, node),
151
273
  docComment: doc,
152
274
  body: buildBody(outer, doc),
153
275
  startLine: startLine(outer),
@@ -159,7 +281,6 @@ function extractVariableSymbols(node, exported) {
159
281
  const outer = exported ? node.parent : node;
160
282
  const doc = getDocComment(outer);
161
283
  const symbols = [];
162
- // Find all variable_declarator children
163
284
  for (const child of node.namedChildren) {
164
285
  if (child.type === 'variable_declarator') {
165
286
  const name = child.childForFieldName('name')?.text ?? '';
@@ -167,15 +288,24 @@ function extractVariableSymbols(node, exported) {
167
288
  continue;
168
289
  const value = child.childForFieldName('value');
169
290
  const isArrow = value?.type === 'arrow_function' || value?.type === 'function_expression';
291
+ // Extract nested named functions from arrow/function body
292
+ let children;
293
+ if (isArrow && value) {
294
+ const fnBody = value.childForFieldName('body');
295
+ const nested = extractNestedFunctions(fnBody);
296
+ if (nested.length > 0)
297
+ children = nested;
298
+ }
170
299
  symbols.push({
171
300
  name,
172
301
  kind: isArrow ? 'function' : 'variable',
173
- signature: buildFullSignature(outer, doc),
302
+ signature: buildVariableSignature(outer, child),
174
303
  docComment: doc,
175
304
  body: buildBody(outer, doc),
176
305
  startLine: startLine(outer),
177
306
  endLine: endLine(outer),
178
307
  isExported: exported,
308
+ children,
179
309
  });
180
310
  }
181
311
  }
@@ -186,13 +316,15 @@ function extractVariableSymbols(node, exported) {
186
316
  // ---------------------------------------------------------------------------
187
317
  function processTopLevel(node) {
188
318
  switch (node.type) {
189
- case 'function_declaration': {
319
+ case 'function_declaration':
320
+ case 'function_signature': {
190
321
  const name = node.childForFieldName('name')?.text;
191
322
  if (!name)
192
323
  return [];
193
324
  return [extractFunctionSymbol(node)];
194
325
  }
195
- case 'class_declaration': {
326
+ case 'class_declaration':
327
+ case 'abstract_class_declaration': {
196
328
  const name = node.childForFieldName('name')?.text;
197
329
  if (!name)
198
330
  return [];
@@ -222,6 +354,17 @@ function processTopLevel(node) {
222
354
  }
223
355
  return [];
224
356
  }
357
+ case 'ambient_declaration': {
358
+ // declare function/class/interface/etc — unwrap and process inner declaration
359
+ for (const child of node.namedChildren) {
360
+ if (child.type === 'comment')
361
+ continue;
362
+ const results = processTopLevel(child);
363
+ if (results.length > 0)
364
+ return results;
365
+ }
366
+ return [];
367
+ }
225
368
  default:
226
369
  return [];
227
370
  }
@@ -237,27 +380,27 @@ const typescriptMapper = {
237
380
  extractEdges(rootNode) {
238
381
  const edges = [];
239
382
  function findClasses(node) {
240
- if (node.type === 'class_declaration') {
383
+ if (node.type === 'class_declaration' || node.type === 'abstract_class_declaration') {
241
384
  const className = node.childForFieldName('name')?.text;
242
385
  if (!className)
243
386
  return;
244
- // Look for class_heritage
245
387
  for (const child of node.namedChildren) {
246
388
  if (child.type === 'class_heritage') {
247
389
  for (const clause of child.namedChildren) {
248
390
  if (clause.type === 'extends_clause') {
249
- // First named child is the base class
250
391
  for (const c of clause.namedChildren) {
251
- if (c.type === 'identifier' || c.type === 'type_identifier') {
252
- edges.push({ fromName: className, toName: c.text, kind: 'extends' });
253
- break;
392
+ const typeName = extractTypeName(c);
393
+ if (typeName) {
394
+ edges.push({ fromName: className, toName: typeName, kind: 'extends' });
395
+ break; // Only one base class
254
396
  }
255
397
  }
256
398
  }
257
399
  if (clause.type === 'implements_clause') {
258
400
  for (const c of clause.namedChildren) {
259
- if (c.type === 'type_identifier' || c.type === 'identifier') {
260
- edges.push({ fromName: className, toName: c.text, kind: 'implements' });
401
+ const typeName = extractTypeName(c);
402
+ if (typeName) {
403
+ edges.push({ fromName: className, toName: typeName, kind: 'implements' });
261
404
  }
262
405
  }
263
406
  }
@@ -275,14 +418,20 @@ const typescriptMapper = {
275
418
  extractImports(rootNode) {
276
419
  const imports = [];
277
420
  for (const child of rootNode.children) {
421
+ // import statements
278
422
  if (child.type === 'import_statement') {
279
423
  const source = child.childForFieldName('source');
280
424
  if (source) {
281
- // Remove quotes from string literal
282
425
  const specifier = source.text.replace(/^['"]|['"]$/g, '');
283
- if (specifier.startsWith('./') || specifier.startsWith('../')) {
284
- imports.push({ specifier });
285
- }
426
+ imports.push({ specifier });
427
+ }
428
+ }
429
+ // Re-exports: export { ... } from '...' and export * from '...'
430
+ if (child.type === 'export_statement') {
431
+ const source = child.childForFieldName('source');
432
+ if (source) {
433
+ const specifier = source.text.replace(/^['"]|['"]$/g, '');
434
+ imports.push({ specifier });
286
435
  }
287
436
  }
288
437
  }
@@ -297,10 +446,8 @@ function registerTypescript() {
297
446
  if (_registered)
298
447
  return;
299
448
  _registered = true;
300
- // TypeScript and TSX share the same mapper
301
449
  (0, registry_1.registerLanguage)('typescript', 'tree-sitter-typescript.wasm', typescriptMapper);
302
450
  (0, registry_1.registerLanguage)('tsx', 'tree-sitter-tsx.wasm', typescriptMapper);
303
- // JavaScript and JSX use the same mapper (TS is a superset)
304
451
  (0, registry_1.registerLanguage)('javascript', 'tree-sitter-javascript.wasm', typescriptMapper);
305
452
  (0, registry_1.registerLanguage)('jsx', 'tree-sitter-javascript.wasm', typescriptMapper);
306
453
  }
@@ -287,17 +287,21 @@ class ProjectManager extends events_1.EventEmitter {
287
287
  this.saveProject(instance);
288
288
  instance.dirty = false;
289
289
  // Scan and watch .notes/ and .tasks/ for reverse import (skip for workspace projects — handled by workspace)
290
+ // Skip mirror entirely if knowledge or tasks graph is readonly (mirror requires both)
290
291
  if (instance.mirrorTracker && !instance.workspaceId && instance.knowledgeManager && instance.taskManager) {
291
- const mirrorConfig = {
292
- projectDir: instance.config.projectDir,
293
- knowledgeManager: instance.knowledgeManager,
294
- taskManager: instance.taskManager,
295
- skillManager: instance.skillManager,
296
- mutationQueue: instance.mutationQueue,
297
- tracker: instance.mirrorTracker,
298
- };
299
- await (0, mirror_watcher_1.scanMirrorDirs)(mirrorConfig);
300
- instance.mirrorWatcher = (0, mirror_watcher_1.startMirrorWatcher)(mirrorConfig);
292
+ const gc = instance.config.graphConfigs;
293
+ if (!gc.knowledge.readonly && !gc.tasks.readonly) {
294
+ const mirrorConfig = {
295
+ projectDir: instance.config.projectDir,
296
+ knowledgeManager: instance.knowledgeManager,
297
+ taskManager: instance.taskManager,
298
+ skillManager: gc.skills.readonly ? undefined : instance.skillManager,
299
+ mutationQueue: instance.mutationQueue,
300
+ tracker: instance.mirrorTracker,
301
+ };
302
+ await (0, mirror_watcher_1.scanMirrorDirs)(mirrorConfig);
303
+ instance.mirrorWatcher = (0, mirror_watcher_1.startMirrorWatcher)(mirrorConfig);
304
+ }
301
305
  }
302
306
  this.emit('project:indexed', { projectId: id });
303
307
  process.stderr.write(`[project-manager] Project "${id}" indexed\n`);
@@ -15,6 +15,23 @@ exports.rrfFuse = rrfFuse;
15
15
  * "getUserById" → ["get", "user", "by", "id"]
16
16
  * "JWT tokens" → ["jwt", "tokens"]
17
17
  */
18
+ /**
19
+ * Minimal stop words for code/doc search.
20
+ * Only articles, conjunctions, prepositions, and pronouns — words that never
21
+ * carry meaning in code search. Excludes programming-significant words like
22
+ * `for`, `do`, `if`, `not`, `is`, `has`, `all`, `can`, `no`.
23
+ */
24
+ const STOP_WORDS = new Set([
25
+ 'a', 'an', 'the', // articles
26
+ 'and', 'or', 'but', 'nor', // conjunctions
27
+ 'of', 'with', 'by', 'from', 'as', 'at', 'on', 'in', 'to', 'into', 'onto', // prepositions
28
+ 'it', 'its', 'he', 'she', 'we', 'they', 'i', 'me', // pronouns
29
+ 'my', 'you', 'your', 'his', 'her', 'our', 'their', // possessives
30
+ 'this', 'that', 'these', 'those', // demonstratives
31
+ 'been', 'being', 'were', 'was', 'are', // be-forms (but not 'be', 'is')
32
+ 'would', 'could', 'should', 'shall', 'might', // modals (but not 'can', 'may', 'will', 'do')
33
+ 'than', 'such', 'very', 'just', 'also', 'about', // fillers
34
+ ]);
18
35
  function tokenize(text) {
19
36
  if (!text)
20
37
  return [];
@@ -24,7 +41,7 @@ function tokenize(text) {
24
41
  .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') // XMLParser → XML Parser
25
42
  .split(/[^a-zA-Z0-9]+/)
26
43
  .map(t => t.toLowerCase())
27
- .filter(t => t.length > 0);
44
+ .filter(t => t.length > 0 && !STOP_WORDS.has(t));
28
45
  return parts;
29
46
  }
30
47
  // ---------------------------------------------------------------------------
@@ -12,7 +12,7 @@ const bm25_1 = require("../../lib/search/bm25");
12
12
  * 4. De-duplicate, re-filter, sort, cap at `maxResults`.
13
13
  */
14
14
  function searchCode(graph, queryEmbedding, options = {}) {
15
- const { topK = 5, bfsDepth = 1, maxResults = 20, minScore = 0.5, bfsDecay = 0.8, queryText, bm25Index, searchMode = 'hybrid', rrfK = 60 } = options;
15
+ const { topK = 5, bfsDepth = 1, maxResults = 20, minScore = 0.3, bfsDecay = 0.8, includeBody = false, queryText, bm25Index, searchMode = 'hybrid', rrfK = 60 } = options;
16
16
  const useVector = searchMode !== 'keyword';
17
17
  const useBm25 = searchMode !== 'vector' && !!queryText && !!bm25Index;
18
18
  // --- 1. Score all nodes ---
@@ -74,8 +74,14 @@ function searchCode(graph, queryEmbedding, options = {}) {
74
74
  if (item.score * bfsDecay < minS)
75
75
  continue;
76
76
  const nextScore = item.score * bfsDecay;
77
+ // Follow all outgoing edges (contains, imports, extends, implements)
77
78
  graph.outNeighbors(item.id).forEach(n => queue.push({ id: n, depth: item.depth + 1, score: nextScore }));
78
- graph.inNeighbors(item.id).forEach(n => queue.push({ id: n, depth: item.depth + 1, score: nextScore }));
79
+ // Follow incoming edges, but NOT reverse imports (avoids noise from popular utility files)
80
+ graph.forEachInEdge(item.id, (_edge, attrs, source) => {
81
+ if (attrs.kind !== 'imports') {
82
+ queue.push({ id: source, depth: item.depth + 1, score: nextScore });
83
+ }
84
+ });
79
85
  }
80
86
  }
81
87
  for (const seed of seeds) {
@@ -86,7 +92,7 @@ function searchCode(graph, queryEmbedding, options = {}) {
86
92
  .filter(([, score]) => score >= minS)
87
93
  .map(([id, score]) => {
88
94
  const attrs = graph.getNodeAttributes(id);
89
- return {
95
+ const result = {
90
96
  id,
91
97
  fileId: attrs.fileId,
92
98
  kind: attrs.kind,
@@ -97,6 +103,9 @@ function searchCode(graph, queryEmbedding, options = {}) {
97
103
  endLine: attrs.endLine,
98
104
  score,
99
105
  };
106
+ if (includeBody)
107
+ result.body = attrs.body;
108
+ return result;
100
109
  })
101
110
  .sort((a, b) => b.score - a.score)
102
111
  .slice(0, maxResults);
@@ -3,12 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ALWAYS_IGNORED = void 0;
6
7
  exports.startWatcher = startWatcher;
7
8
  const chokidar_1 = __importDefault(require("chokidar"));
8
9
  const micromatch_1 = __importDefault(require("micromatch"));
9
10
  const path_1 = __importDefault(require("path"));
10
- /** Directories that are always excluded from watching (heavy, never useful). */
11
- const ALWAYS_IGNORED = ['.git', 'node_modules', '.next', '.nuxt', '.turbo', 'dist', 'build', '.graph-memory', '.notes', '.tasks', '.skills'];
11
+ /** Directory basenames that are always excluded from watching and scanning at any nesting level. */
12
+ exports.ALWAYS_IGNORED = new Set([
13
+ 'node_modules', '.git', '.hg', '.svn',
14
+ '.next', '.nuxt', '.turbo',
15
+ 'dist', 'build',
16
+ '.graph-memory', '.notes', '.tasks', '.skills',
17
+ ]);
12
18
  // chokidar 5: watch the directory directly — glob patterns don't fire 'add' for existing files
13
19
  function startWatcher(dir, handlers, pattern = '**/*.md', excludePatterns) {
14
20
  const matches = (filePath) => {
@@ -17,17 +23,19 @@ function startWatcher(dir, handlers, pattern = '**/*.md', excludePatterns) {
17
23
  return false;
18
24
  return micromatch_1.default.isMatch(rel, pattern);
19
25
  };
20
- // chokidar 5 `ignored` accepts a function — use micromatch for glob exclude patterns
21
- // plus always skip heavy directories (.git, node_modules, etc.)
22
- const alwaysIgnoredSet = new Set(ALWAYS_IGNORED.map(d => path_1.default.join(dir, d)));
23
26
  const ignored = (filePath) => {
24
- // Always ignore heavy directories by exact basename match
25
- if (alwaysIgnoredSet.has(filePath))
27
+ const basename = path_1.default.basename(filePath);
28
+ // Skip dotfiles and dotdirs (hidden) at any level — except the watched root itself
29
+ if (basename.startsWith('.') && filePath !== dir)
26
30
  return true;
27
- // User-defined exclude patterns (glob-based)
31
+ // Always-ignored directories by basename at any nesting level
32
+ if (exports.ALWAYS_IGNORED.has(basename))
33
+ return true;
34
+ // User-defined exclude patterns (glob-based) — only prune directories, not individual files.
35
+ // File-level filtering is handled by matches() + dispatchAdd per-graph excludes.
28
36
  if (excludePatterns && excludePatterns.length > 0) {
29
37
  const rel = path_1.default.relative(dir, filePath);
30
- if (micromatch_1.default.isMatch(rel, excludePatterns))
38
+ if (micromatch_1.default.isMatch(rel + '/x', excludePatterns))
31
39
  return true;
32
40
  }
33
41
  return false;
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{Y as r,nt as i,q as a,r as o}from"./vendor-mui-BPj7d3Sw.js";import{D as s,E as c,I as l,O as u,P as d,S as f}from"./index-BCZDAYZi.js";var p=e(n(),1),m=t();function h({note:e,onSubmit:t,onCancel:n,submitLabel:h=`Save`}){let[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(``),[b,x]=(0,p.useState)([]),[S,C]=(0,p.useState)(!1),[w,T]=(0,p.useState)(!1);(0,p.useEffect)(()=>{e&&(_(e.title),y(e.content),x(e.tags??[]))},[e]);let E=async()=>{if(!g.trim()){T(!0);return}C(!0);try{await t({title:g.trim(),content:v.trim(),tags:b})}finally{C(!1)}};return(0,m.jsxs)(r,{component:`form`,id:`note-form`,onSubmit:e=>{e.preventDefault(),E()},sx:{display:`flex`,flexDirection:`column`,gap:3},children:[(0,m.jsx)(l,{title:`Details`,children:(0,m.jsxs)(u,{children:[(0,m.jsxs)(s,{fullWidth:!0,children:[(0,m.jsx)(c,{required:!0,children:`Title`}),(0,m.jsx)(o,{autoFocus:!0,fullWidth:!0,value:g,onChange:e=>{_(e.target.value),T(!1)},error:w,helperText:w?`Title is required`:void 0})]}),(0,m.jsxs)(s,{fullWidth:!0,children:[(0,m.jsx)(c,{children:`Content`}),(0,m.jsx)(f,{value:v,onChange:y,height:300})]}),(0,m.jsx)(s,{fullWidth:!0,children:(0,m.jsx)(d,{tags:b,editable:!0,onAdd:e=>x(t=>t.includes(e)?t:[...t,e]),onRemove:e=>x(t=>t.filter(t=>t!==e))})})]})}),(0,m.jsxs)(r,{sx:{display:`flex`,gap:1,justifyContent:`flex-end`},children:[(0,m.jsx)(a,{onClick:n,children:`Cancel`}),(0,m.jsx)(a,{variant:`contained`,onClick:E,disabled:S||!g.trim(),children:S?(0,m.jsx)(i,{size:20}):h})]})]})}export{h as t};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{$ as r,Y as i,_ as a,nt as o,q as s,r as c,tt as l,v as u,y as d}from"./vendor-mui-BPj7d3Sw.js";import{K as f,i as p}from"./vendor-mui-icons-B196sG3f.js";import{D as m,E as h,I as g,O as _,P as v,S as y}from"./index-BCZDAYZi.js";var b=e(n(),1),x=t();function S({skill:e,onSubmit:t,onCancel:n,submitLabel:S=`Save`}){let[C,w]=(0,b.useState)(``),[T,E]=(0,b.useState)(``),[D,O]=(0,b.useState)([``]),[k,A]=(0,b.useState)([]),[j,M]=(0,b.useState)([]),[N,P]=(0,b.useState)([]),[F,I]=(0,b.useState)([]),[L,R]=(0,b.useState)(`user`),[z,B]=(0,b.useState)(1),[V,H]=(0,b.useState)(!1),[U,W]=(0,b.useState)(!1);(0,b.useEffect)(()=>{e&&(w(e.title),E(e.description),O(e.steps.length>0?e.steps:[``]),A(e.triggers??[]),M(e.inputHints??[]),P(e.filePatterns??[]),I(e.tags??[]),R(e.source),B(e.confidence))},[e]);let G=async()=>{if(!C.trim()){W(!0);return}H(!0);try{await t({title:C.trim(),description:T.trim(),steps:D.map(e=>e.trim()).filter(Boolean),triggers:k,inputHints:j,filePatterns:N,tags:F,source:L,confidence:z})}finally{H(!1)}},K=(e,t)=>{O(n=>n.map((n,r)=>r===e?t:n))},q=()=>{O(e=>[...e,``])},J=e=>{O(t=>t.filter((t,n)=>n!==e))};return(0,x.jsxs)(i,{component:`form`,id:`skill-form`,onSubmit:e=>{e.preventDefault(),G()},sx:{display:`flex`,flexDirection:`column`,gap:3},children:[(0,x.jsx)(g,{title:`Details`,children:(0,x.jsxs)(_,{children:[(0,x.jsxs)(m,{fullWidth:!0,children:[(0,x.jsx)(h,{required:!0,children:`Title`}),(0,x.jsx)(c,{autoFocus:!0,fullWidth:!0,value:C,onChange:e=>{w(e.target.value),W(!1)},error:U,helperText:U?`Title is required`:void 0})]}),(0,x.jsxs)(m,{fullWidth:!0,children:[(0,x.jsx)(h,{children:`Description`}),(0,x.jsx)(y,{value:T,onChange:E,height:200})]})]})}),(0,x.jsx)(g,{title:`Steps`,children:(0,x.jsxs)(i,{sx:{display:`flex`,flexDirection:`column`,gap:1},children:[D.map((e,t)=>(0,x.jsxs)(i,{sx:{display:`flex`,gap:1,alignItems:`center`},children:[(0,x.jsxs)(r,{variant:`body2`,sx:{minWidth:24,color:`text.secondary`},children:[t+1,`.`]}),(0,x.jsx)(c,{fullWidth:!0,size:`small`,value:e,onChange:e=>K(t,e.target.value),placeholder:`Step ${t+1}`}),D.length>1&&(0,x.jsx)(l,{size:`small`,onClick:()=>J(t),color:`error`,children:(0,x.jsx)(p,{fontSize:`small`})})]},t)),(0,x.jsx)(s,{size:`small`,startIcon:(0,x.jsx)(f,{}),onClick:q,sx:{alignSelf:`flex-start`},children:`Add Step`})]})}),(0,x.jsx)(g,{title:`Matching`,children:(0,x.jsxs)(_,{children:[(0,x.jsxs)(m,{fullWidth:!0,children:[(0,x.jsx)(h,{children:`Triggers`}),(0,x.jsx)(v,{tags:k,editable:!0,onAdd:e=>A(t=>t.includes(e)?t:[...t,e]),onRemove:e=>A(t=>t.filter(t=>t!==e))})]}),(0,x.jsxs)(m,{fullWidth:!0,children:[(0,x.jsx)(h,{children:`Input Hints`}),(0,x.jsx)(v,{tags:j,editable:!0,onAdd:e=>M(t=>t.includes(e)?t:[...t,e]),onRemove:e=>M(t=>t.filter(t=>t!==e))})]}),(0,x.jsxs)(m,{fullWidth:!0,children:[(0,x.jsx)(h,{children:`File Patterns`}),(0,x.jsx)(v,{tags:N,editable:!0,onAdd:e=>P(t=>t.includes(e)?t:[...t,e]),onRemove:e=>P(t=>t.filter(t=>t!==e))})]})]})}),(0,x.jsx)(g,{title:`Properties`,children:(0,x.jsxs)(_,{children:[(0,x.jsxs)(m,{children:[(0,x.jsx)(h,{children:`Source`}),(0,x.jsxs)(u,{fullWidth:!0,value:L,onChange:e=>R(e.target.value),children:[(0,x.jsx)(d,{value:`user`,children:`User`}),(0,x.jsx)(d,{value:`learned`,children:`Learned`})]})]}),(0,x.jsx)(m,{children:(0,x.jsxs)(i,{sx:{px:1},children:[(0,x.jsxs)(h,{children:[`Confidence: `,Math.round(z*100),`%`]}),(0,x.jsx)(a,{value:z,onChange:(e,t)=>B(t),min:0,max:1,step:.01,valueLabelDisplay:`auto`,valueLabelFormat:e=>`${Math.round(e*100)}%`})]})}),(0,x.jsx)(m,{fullWidth:!0,children:(0,x.jsx)(v,{tags:F,editable:!0,onAdd:e=>I(t=>t.includes(e)?t:[...t,e]),onRemove:e=>I(t=>t.filter(t=>t!==e))})})]})}),(0,x.jsxs)(i,{sx:{display:`flex`,gap:1,justifyContent:`flex-end`},children:[(0,x.jsx)(s,{onClick:n,children:`Cancel`}),(0,x.jsx)(s,{variant:`contained`,onClick:G,disabled:V||!C.trim(),children:V?(0,x.jsx)(o,{size:20}):S})]})]})}export{S as t};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{l as r}from"./vendor-react-CHUjhoxh.js";import{Y as i,nt as a,q as o,r as s,v as c,y as l}from"./vendor-mui-BPj7d3Sw.js";import{D as u,E as d,I as f,O as p,P as m,S as h,et as g,t as _}from"./index-BCZDAYZi.js";var v=e(n(),1),y=t();function b({task:e,onSubmit:t,onCancel:n,submitLabel:b=`Save`}){let{projectId:x}=r(),[S,C]=(0,v.useState)(``),[w,T]=(0,v.useState)(``),[E,D]=(0,v.useState)(`todo`),[O,k]=(0,v.useState)(`medium`),[A,j]=(0,v.useState)([]),[M,N]=(0,v.useState)(``),[P,F]=(0,v.useState)(``),[I,L]=(0,v.useState)(``),[R,z]=(0,v.useState)([]),[B,V]=(0,v.useState)(!1),[H,U]=(0,v.useState)(!1);(0,v.useEffect)(()=>{e&&(C(e.title),T(e.description),D(e.status),k(e.priority),j(e.tags??[]),N(e.dueDate?new Date(e.dueDate).toISOString().split(`T`)[0]:``),F(e.estimate==null?``:String(e.estimate)),L(e.assignee??``))},[e]),(0,v.useEffect)(()=>{x&&g(x).then(z).catch(()=>{})},[x]);let W=async()=>{if(!S.trim()){U(!0);return}V(!0);try{await t({title:S.trim(),description:w.trim(),status:E,priority:O,tags:A,dueDate:M?new Date(M).getTime():null,estimate:P?Number(P):null,assignee:I||null})}finally{V(!1)}};return(0,y.jsxs)(i,{component:`form`,id:`task-form`,onSubmit:e=>{e.preventDefault(),W()},sx:{display:`flex`,flexDirection:`column`,gap:3},children:[(0,y.jsx)(f,{title:`Details`,children:(0,y.jsxs)(p,{children:[(0,y.jsxs)(u,{fullWidth:!0,children:[(0,y.jsx)(d,{required:!0,children:`Title`}),(0,y.jsx)(s,{autoFocus:!0,fullWidth:!0,value:S,onChange:e=>{C(e.target.value),U(!1)},error:H,helperText:H?`Title is required`:void 0})]}),(0,y.jsxs)(u,{fullWidth:!0,children:[(0,y.jsx)(d,{children:`Description`}),(0,y.jsx)(h,{value:w,onChange:T,height:250})]})]})}),(0,y.jsx)(f,{title:`Properties`,children:(0,y.jsxs)(p,{children:[(0,y.jsxs)(u,{children:[(0,y.jsx)(d,{children:`Status`}),(0,y.jsx)(c,{fullWidth:!0,value:E,onChange:e=>D(e.target.value),children:_.map(e=>(0,y.jsx)(l,{value:e.status,children:e.label},e.status))})]}),(0,y.jsxs)(u,{children:[(0,y.jsx)(d,{children:`Priority`}),(0,y.jsxs)(c,{fullWidth:!0,value:O,onChange:e=>k(e.target.value),children:[(0,y.jsx)(l,{value:`critical`,children:`Critical`}),(0,y.jsx)(l,{value:`high`,children:`High`}),(0,y.jsx)(l,{value:`medium`,children:`Medium`}),(0,y.jsx)(l,{value:`low`,children:`Low`})]})]}),(0,y.jsxs)(u,{children:[(0,y.jsx)(d,{children:`Due Date`}),(0,y.jsx)(s,{fullWidth:!0,type:`date`,value:M,onChange:e=>N(e.target.value)})]}),(0,y.jsxs)(u,{children:[(0,y.jsx)(d,{children:`Estimate (hours)`}),(0,y.jsx)(s,{fullWidth:!0,type:`number`,value:P,onChange:e=>F(e.target.value),slotProps:{input:{inputProps:{min:0,step:.5}}}})]}),(0,y.jsxs)(u,{children:[(0,y.jsx)(d,{children:`Assignee`}),(0,y.jsxs)(c,{fullWidth:!0,value:I,onChange:e=>L(e.target.value),displayEmpty:!0,renderValue:e=>e?R.find(t=>t.id===e)?.name||e:`Unassigned`,children:[(0,y.jsx)(l,{value:``,children:`Unassigned`}),R.map(e=>(0,y.jsx)(l,{value:e.id,children:e.name||e.id},e.id))]})]}),(0,y.jsx)(u,{fullWidth:!0,children:(0,y.jsx)(m,{tags:A,editable:!0,onAdd:e=>j(t=>t.includes(e)?t:[...t,e]),onRemove:e=>j(t=>t.filter(t=>t!==e))})})]})}),(0,y.jsxs)(i,{sx:{display:`flex`,gap:1,justifyContent:`flex-end`},children:[(0,y.jsx)(o,{onClick:n,children:`Cancel`}),(0,y.jsx)(o,{variant:`contained`,onClick:W,disabled:B||!S.trim(),children:B?(0,y.jsx)(a,{size:20}):b})]})]})}export{b as t};
@@ -0,0 +1 @@
1
+ import{D as e}from"./vendor-markdown-CT8ZVEPu.js";import{c as t,l as n}from"./vendor-react-CHUjhoxh.js";import{$ as r,X as i,Y as a,ut as o}from"./vendor-mui-BPj7d3Sw.js";import"./vendor-md-editor-DmWafJvr.js";import{nt as s,tt as c}from"./vendor-mui-icons-B196sG3f.js";import{C as l,F as u,I as d,T as f,j as p}from"./index-BCZDAYZi.js";import{t as m}from"./help-CEMQqZUR.js";var h=e(),g={overview:`primary`,concept:`warning`,guide:`success`};function _(){let{projectId:e,articleId:_}=n(),v=t(),{palette:y}=o(),b=_?m(_):void 0;return b?(0,h.jsxs)(a,{children:[(0,h.jsx)(p,{breadcrumbs:[{label:`Help`,to:`/${e}/help`},{label:b.title}]}),(0,h.jsxs)(a,{sx:{display:`flex`,flexDirection:`column`,gap:2},children:[(0,h.jsxs)(a,{sx:{display:`flex`,alignItems:`center`,gap:1.5,mb:1},children:[(0,h.jsx)(u,{label:b.category===`overview`?`Overview`:b.category===`concept`?`Concept`:`Guide`,color:g[b.category]||`primary`}),(0,h.jsx)(r,{variant:`body2`,sx:{color:y.custom.textMuted},children:b.summary})]}),(0,h.jsx)(d,{title:`Article`,children:(0,h.jsx)(l,{children:b.content})}),b.relatedTools.length>0&&(0,h.jsx)(d,{title:`Related Tools`,children:(0,h.jsx)(a,{sx:{display:`flex`,flexWrap:`wrap`,gap:1},children:b.relatedTools.map(t=>(0,h.jsx)(i,{icon:(0,h.jsx)(s,{}),label:t,size:`small`,variant:`outlined`,clickable:!0,onClick:()=>v(`/${e}/tools/${t}`),sx:{fontFamily:`monospace`}},t))})})]})]}):(0,h.jsxs)(a,{children:[(0,h.jsx)(p,{breadcrumbs:[{label:`Help`,to:`/${e}/help`},{label:`Not Found`}]}),(0,h.jsx)(f,{icon:(0,h.jsx)(c,{}),title:`Article not found`})]})}export{_ as default};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{c as r,l as i}from"./vendor-react-CHUjhoxh.js";import{$ as a,D as o,E as s,O as c,S as l,Y as u,et as d,nt as f,ut as p}from"./vendor-mui-BPj7d3Sw.js";import"./vendor-md-editor-DmWafJvr.js";import{I as m,N as h,P as g,j as _,k as v}from"./index-BCZDAYZi.js";import{n as y,t as b}from"./api-BlFF6gX-.js";var x=e(n(),1),S=t();function C(){let{projectId:e,docId:t}=i(),n=r(),{palette:C}=p(),[w,T]=(0,x.useState)(null),[E,D]=(0,x.useState)([]),[O,k]=(0,x.useState)(!0),[A,j]=(0,x.useState)(null);if((0,x.useEffect)(()=>{if(!e||!t)return;k(!0);let n=decodeURIComponent(t);Promise.all([b(e,n),b(e,n).then(t=>y(e,t.fileId).catch(()=>[]))]).then(([e,t])=>{T(e),D(t),j(null)}).catch(e=>j(e instanceof Error?e.message:String(e))).finally(()=>k(!1))},[e,t]),O)return(0,S.jsx)(u,{sx:{display:`flex`,justifyContent:`center`,py:4},children:(0,S.jsx)(f,{})});if(A||!w)return(0,S.jsx)(d,{severity:`error`,children:A||`Doc node not found`});let M=decodeURIComponent(t);return(0,S.jsxs)(u,{children:[(0,S.jsx)(_,{breadcrumbs:[{label:`Docs`,to:`/${e}/docs`},{label:w.title||w.id}]}),(0,S.jsxs)(m,{title:`Details`,sx:{mb:3},children:[(0,S.jsx)(v,{label:`ID`,children:(0,S.jsxs)(u,{sx:{display:`flex`,alignItems:`center`,gap:.5},children:[(0,S.jsx)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:w.id}),(0,S.jsx)(h,{value:w.id})]})}),(0,S.jsx)(v,{label:`File`,children:(0,S.jsx)(c,{component:`button`,variant:`body2`,onClick:()=>n(`/${e}/docs`),children:w.fileId})}),(0,S.jsx)(v,{label:`Level`,children:(0,S.jsx)(a,{variant:`body2`,children:w.level})}),w.language&&(0,S.jsx)(v,{label:`Language`,children:(0,S.jsx)(a,{variant:`body2`,children:w.language})}),w.symbols&&w.symbols.length>0&&(0,S.jsx)(v,{label:`Symbols`,divider:!1,children:(0,S.jsx)(g,{tags:w.symbols})})]}),w.content&&(0,S.jsx)(m,{title:`Content`,sx:{mb:3},children:(0,S.jsx)(a,{variant:`body2`,sx:{whiteSpace:`pre-wrap`,fontFamily:w.language?`monospace`:`inherit`,fontSize:w.language?`0.85rem`:void 0},children:w.content})}),E.length>1&&(0,S.jsx)(m,{title:`In this file`,children:(0,S.jsx)(o,{dense:!0,disablePadding:!0,children:E.map(t=>(0,S.jsx)(s,{selected:t.id===M,onClick:()=>n(`/${e}/docs/${encodeURIComponent(t.id)}`),sx:{borderRadius:1,py:.25,...t.id===M&&{bgcolor:`${C.primary.main}14`}},children:(0,S.jsx)(l,{primary:(0,S.jsx)(a,{variant:`body2`,sx:{pl:(t.level-1)*2},fontWeight:t.id===M?700:400,children:t.title||t.id})})},t.id))})})]})}export{C as default};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{c as r,l as i}from"./vendor-react-CHUjhoxh.js";import{$ as a,O as o,Y as s,et as c,m as l,nt as u,ut as d}from"./vendor-mui-BPj7d3Sw.js";import"./vendor-md-editor-DmWafJvr.js";import{F as f,H as p,I as m,N as h,a as g,d as _,j as v,k as y,r as b}from"./index-BCZDAYZi.js";import{t as x}from"./api-BMnBjMMf.js";var S=e(n(),1),C=t();function w(e){return e==null?`—`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function T(){let{projectId:e,"*":t}=i(),n=r(),{palette:T}=d(),[E,D]=(0,S.useState)(null),[O,k]=(0,S.useState)([]),[A,j]=(0,S.useState)([]),[M,N]=(0,S.useState)(!0),[P,F]=(0,S.useState)(null);if((0,S.useEffect)(()=>{!e||!t||(N(!0),Promise.all([x(e,t),p(e,`files`,t).catch(()=>[]),_(e,`files`,t).catch(()=>[])]).then(([e,t,n])=>{D(e),k(t),j(n),F(null)}).catch(e=>F(e instanceof Error?e.message:String(e))).finally(()=>N(!1)))},[e,t]),M)return(0,C.jsx)(s,{sx:{display:`flex`,justifyContent:`center`,py:4},children:(0,C.jsx)(u,{})});if(P||!E)return(0,C.jsx)(c,{severity:`error`,children:P||`File not found`});let I=t.split(`/`).slice(0,-1).join(`/`)||`.`;return(0,C.jsxs)(s,{children:[(0,C.jsx)(v,{breadcrumbs:[{label:`Files`,to:`/${e}/files`},{label:E.fileName}]}),(0,C.jsxs)(m,{title:`Metadata`,sx:{mb:3},children:[(0,C.jsx)(y,{label:`Path`,children:(0,C.jsxs)(s,{sx:{display:`flex`,alignItems:`center`,gap:.5},children:[(0,C.jsx)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:E.filePath}),(0,C.jsx)(h,{value:E.filePath})]})}),(0,C.jsx)(y,{label:`Size`,children:(0,C.jsx)(a,{variant:`body2`,children:w(E.size)})}),E.language&&(0,C.jsx)(y,{label:`Language`,children:(0,C.jsx)(a,{variant:`body2`,children:E.language})}),E.mimeType&&(0,C.jsx)(y,{label:`MIME Type`,children:(0,C.jsx)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:E.mimeType})}),E.extension&&(0,C.jsx)(y,{label:`Extension`,children:(0,C.jsx)(a,{variant:`body2`,children:E.extension})}),(0,C.jsx)(y,{label:`Directory`,divider:!1,children:(0,C.jsx)(o,{component:`button`,variant:`body2`,onClick:()=>n(`/${e}/files?dir=${I}`),children:I})})]}),(0,C.jsx)(m,{title:`Linked Notes`,sx:{mb:3},children:O.length===0?(0,C.jsx)(a,{variant:`body2`,sx:{color:T.custom.textMuted},children:`No linked notes`}):(0,C.jsx)(l,{spacing:.5,children:O.map(t=>(0,C.jsxs)(s,{sx:{display:`flex`,alignItems:`center`,gap:1},children:[(0,C.jsx)(f,{label:t.kind,color:`neutral`,size:`small`}),(0,C.jsx)(o,{component:`button`,variant:`body2`,onClick:()=>n(`/${e}/knowledge/${t.noteId}`),children:t.title})]},t.noteId))})}),(0,C.jsx)(m,{title:`Linked Tasks`,children:A.length===0?(0,C.jsx)(a,{variant:`body2`,sx:{color:T.custom.textMuted},children:`No linked tasks`}):(0,C.jsx)(l,{spacing:.5,children:A.map(t=>(0,C.jsxs)(s,{sx:{display:`flex`,alignItems:`center`,gap:1},children:[(0,C.jsx)(f,{label:g(t.status),color:b[t.status]??`neutral`,size:`small`}),(0,C.jsx)(o,{component:`button`,variant:`body2`,onClick:()=>n(`/${e}/tasks/${t.taskId}`),children:t.title})]},t.taskId))})})]})}export{T as default};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{c as r,l as i}from"./vendor-react-CHUjhoxh.js";import{$ as a,Y as o,et as s,nt as c,q as l}from"./vendor-mui-BPj7d3Sw.js";import"./vendor-md-editor-DmWafJvr.js";import{M as u,W as d}from"./vendor-mui-icons-B196sG3f.js";import{B as f,C as p,I as m,K as h,M as g,N as _,P as v,Q as y,U as b,W as x,X as S,Z as C,j as w,k as T,q as E,w as D,z as O}from"./index-BCZDAYZi.js";import"./skill-y9pizyqE.js";import{n as k,t as A}from"./attachments-CEQ-2nMo.js";var j=e(n(),1),M=t();function N(){let{projectId:e,noteId:t}=i(),n=r(),N=C(`knowledge`),[P,F]=(0,j.useState)(null),[I,L]=(0,j.useState)([]),[R,z]=(0,j.useState)([]),[B,V]=(0,j.useState)(!0),[H,U]=(0,j.useState)(null),[W,G]=(0,j.useState)(!1),K=(0,j.useCallback)(async()=>{if(!(!e||!t))try{let[n,r,i]=await Promise.all([b(e,t),h(e,t),x(e,t)]);F(n),L(r),z(i),U(null)}catch(e){U(e instanceof Error?e.message:String(e))}finally{V(!1)}},[e,t]);return(0,j.useEffect)(()=>{K()},[K]),y(e??null,(0,j.useCallback)(e=>{e.type.startsWith(`note:`)&&K()},[K])),B?(0,M.jsx)(o,{sx:{display:`flex`,justifyContent:`center`,py:4},children:(0,M.jsx)(c,{})}):H||!P?(0,M.jsx)(s,{severity:`error`,children:H||`Note not found`}):(0,M.jsxs)(o,{children:[(0,M.jsx)(w,{breadcrumbs:[{label:`Knowledge`,to:`/${e}/knowledge`},{label:P.title}],actions:N?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(l,{variant:`contained`,color:`success`,startIcon:(0,M.jsx)(d,{}),onClick:()=>n(`/${e}/knowledge/${t}/edit`),children:`Edit`}),(0,M.jsx)(l,{color:`error`,startIcon:(0,M.jsx)(u,{}),onClick:()=>G(!0),children:`Delete`})]}):void 0}),(0,M.jsxs)(m,{title:`Details`,sx:{mb:3},children:[(0,M.jsx)(T,{label:`ID`,children:(0,M.jsxs)(o,{sx:{display:`flex`,alignItems:`center`,gap:.5},children:[(0,M.jsx)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:P.id}),(0,M.jsx)(_,{value:P.id})]})}),(0,M.jsx)(T,{label:`Version`,children:(0,M.jsxs)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:[`v`,P.version]})}),(0,M.jsx)(T,{label:`Tags`,children:P.tags.length>0?(0,M.jsx)(v,{tags:P.tags}):(0,M.jsx)(a,{variant:`body2`,color:`text.secondary`,children:`—`})}),P.createdBy&&(0,M.jsx)(T,{label:`Created by`,children:(0,M.jsx)(a,{variant:`body2`,children:P.createdBy})}),P.updatedBy&&P.updatedBy!==P.createdBy&&(0,M.jsx)(T,{label:`Updated by`,children:(0,M.jsx)(a,{variant:`body2`,children:P.updatedBy})}),(0,M.jsx)(T,{label:`Created`,children:(0,M.jsx)(g,{value:P.createdAt,showTime:!0,showRelative:!0})}),(0,M.jsx)(T,{label:`Updated`,divider:!P.content,children:(0,M.jsx)(g,{value:P.updatedAt,showTime:!0,showRelative:!0})}),P.content&&(0,M.jsx)(T,{label:`Content`,divider:!1,children:(0,M.jsx)(p,{children:P.content})})]}),(0,M.jsx)(m,{title:`Attachments`,sx:{mb:3},children:(0,M.jsx)(A,{attachments:R,getUrl:n=>E(e,t,n),onUpload:async n=>{await S(e,t,n),z(await x(e,t))},onDelete:async n=>{await f(e,t,n),z(await x(e,t))},readOnly:!N})}),(0,M.jsx)(m,{title:`Relations`,children:(0,M.jsx)(k,{projectId:e,entityId:t,entityType:`knowledge`,relations:I,onRefresh:K})}),(0,M.jsx)(D,{open:W,title:`Delete Note`,message:`Are you sure you want to delete "${P.title}"? This cannot be undone.`,confirmLabel:`Delete`,confirmColor:`error`,onConfirm:async()=>{!e||!t||(await O(e,t),n(`/${e}/knowledge`))},onCancel:()=>G(!1)})]})}export{N as default};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{D as t,O as n}from"./vendor-markdown-CT8ZVEPu.js";import{c as r,l as i}from"./vendor-react-CHUjhoxh.js";import{$ as a,X as o,Y as s,et as c,nt as l,q as u}from"./vendor-mui-BPj7d3Sw.js";import"./vendor-md-editor-DmWafJvr.js";import{M as d,W as f}from"./vendor-mui-icons-B196sG3f.js";import{C as p,F as m,I as h,N as g,P as _,Q as v,Z as y,j as b,k as x,w as S}from"./index-BCZDAYZi.js";import{_ as C,c as w,d as T,f as E,h as D,i as O,n as k,r as A,s as j,u as M}from"./skill-y9pizyqE.js";import{n as N,t as P}from"./attachments-CEQ-2nMo.js";var F=e(n(),1),I=t();function L(){let{projectId:e,skillId:t}=i(),n=r(),L=y(`skills`),[R,z]=(0,F.useState)(null),[B,V]=(0,F.useState)([]),[H,U]=(0,F.useState)([]),[W,G]=(0,F.useState)(!0),[K,q]=(0,F.useState)(null),[J,Y]=(0,F.useState)(!1),X=(0,F.useCallback)(async()=>{if(!(!e||!t))try{let[n,r,i]=await Promise.all([M(e,t),E(e,t),T(e,t)]);z(n),V(r),U(i),q(null)}catch(e){q(e instanceof Error?e.message:String(e))}finally{G(!1)}},[e,t]);return(0,F.useEffect)(()=>{X()},[X]),v(e??null,(0,F.useCallback)(e=>{e.type.startsWith(`skill:`)&&X()},[X])),W?(0,I.jsx)(s,{sx:{display:`flex`,justifyContent:`center`,py:4},children:(0,I.jsx)(l,{})}):K||!R?(0,I.jsx)(c,{severity:`error`,children:K||`Skill not found`}):(0,I.jsxs)(s,{children:[(0,I.jsx)(b,{breadcrumbs:[{label:`Skills`,to:`/${e}/skills`},{label:R.title}],actions:L?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(u,{variant:`contained`,color:`success`,startIcon:(0,I.jsx)(f,{}),onClick:()=>n(`/${e}/skills/${t}/edit`),children:`Edit`}),(0,I.jsx)(u,{color:`error`,startIcon:(0,I.jsx)(d,{}),onClick:()=>Y(!0),children:`Delete`})]}):void 0}),(0,I.jsxs)(h,{title:`Details`,sx:{mb:3},children:[(0,I.jsx)(x,{label:`ID`,children:(0,I.jsxs)(s,{sx:{display:`flex`,alignItems:`center`,gap:.5},children:[(0,I.jsx)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:R.id}),(0,I.jsx)(g,{value:R.id})]})}),(0,I.jsx)(x,{label:`Version`,children:(0,I.jsxs)(a,{variant:`body2`,sx:{fontFamily:`monospace`},children:[`v`,R.version]})}),(0,I.jsx)(x,{label:`Source`,children:(0,I.jsx)(m,{label:O(R.source),color:k[R.source]??`primary`})}),(0,I.jsx)(x,{label:`Confidence`,children:(0,I.jsx)(a,{variant:`body2`,children:A(R.confidence)})}),(0,I.jsx)(x,{label:`Usage Count`,children:(0,I.jsx)(a,{variant:`body2`,children:R.usageCount})}),R.lastUsedAt&&(0,I.jsx)(x,{label:`Last Used`,children:(0,I.jsx)(a,{variant:`body2`,children:new Date(R.lastUsedAt).toLocaleString()})}),R.createdBy&&(0,I.jsx)(x,{label:`Created by`,children:(0,I.jsx)(a,{variant:`body2`,children:R.createdBy})}),R.updatedBy&&R.updatedBy!==R.createdBy&&(0,I.jsx)(x,{label:`Updated by`,children:(0,I.jsx)(a,{variant:`body2`,children:R.updatedBy})}),(0,I.jsx)(x,{label:`Created`,children:(0,I.jsx)(a,{variant:`body2`,children:new Date(R.createdAt).toLocaleString()})}),(0,I.jsx)(x,{label:`Updated`,children:(0,I.jsx)(a,{variant:`body2`,children:new Date(R.updatedAt).toLocaleString()})}),(0,I.jsx)(x,{label:`Tags`,children:R.tags.length>0?(0,I.jsx)(_,{tags:R.tags}):(0,I.jsx)(a,{variant:`body2`,color:`text.secondary`,children:`—`})}),R.description&&(0,I.jsx)(x,{label:`Description`,divider:!1,children:(0,I.jsx)(p,{children:R.description})})]}),R.steps.length>0&&(0,I.jsx)(h,{title:`Steps`,sx:{mb:3},children:(0,I.jsx)(s,{component:`ol`,sx:{m:0,pl:2.5},children:R.steps.map((e,t)=>(0,I.jsx)(a,{component:`li`,variant:`body2`,sx:{mb:.5},children:e},t))})}),R.triggers.length>0&&(0,I.jsx)(h,{title:`Triggers`,sx:{mb:3},children:(0,I.jsx)(s,{sx:{display:`flex`,flexWrap:`wrap`,gap:.5},children:R.triggers.map((e,t)=>(0,I.jsx)(o,{label:e,size:`small`,variant:`outlined`},t))})}),R.inputHints.length>0&&(0,I.jsx)(h,{title:`Input Hints`,sx:{mb:3},children:(0,I.jsx)(s,{sx:{display:`flex`,flexWrap:`wrap`,gap:.5},children:R.inputHints.map((e,t)=>(0,I.jsx)(o,{label:e,size:`small`,variant:`outlined`},t))})}),R.filePatterns.length>0&&(0,I.jsx)(h,{title:`File Patterns`,sx:{mb:3},children:(0,I.jsx)(s,{sx:{display:`flex`,flexWrap:`wrap`,gap:.5},children:R.filePatterns.map((e,t)=>(0,I.jsx)(o,{label:e,size:`small`,variant:`outlined`,sx:{fontFamily:`monospace`}},t))})}),(0,I.jsx)(h,{title:`Attachments`,sx:{mb:3},children:(0,I.jsx)(P,{attachments:H,getUrl:n=>D(e,t,n),onUpload:async n=>{await C(e,t,n),U(await T(e,t))},onDelete:async n=>{await w(e,t,n),U(await T(e,t))},readOnly:!L})}),(0,I.jsx)(h,{title:`Relations`,children:(0,I.jsx)(N,{projectId:e,entityId:t,entityType:`skills`,relations:B,onRefresh:X})}),(0,I.jsx)(S,{open:J,title:`Delete Skill`,message:`Are you sure you want to delete "${R.title}"? This cannot be undone.`,confirmLabel:`Delete`,confirmColor:`error`,onConfirm:async()=>{!e||!t||(await j(e,t),n(`/${e}/skills`))},onCancel:()=>Y(!1)})]})}export{L as default};