@agentuity/cli 0.0.101 → 0.0.103

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 (210) hide show
  1. package/AGENTS.md +19 -188
  2. package/bin/cli.ts +21 -14
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +41 -12
  5. package/dist/cli.js.map +1 -1
  6. package/dist/cmd/ai/index.d.ts.map +1 -1
  7. package/dist/cmd/ai/index.js +6 -1
  8. package/dist/cmd/ai/index.js.map +1 -1
  9. package/dist/cmd/ai/prompt/agent.d.ts +7 -0
  10. package/dist/cmd/ai/prompt/agent.d.ts.map +1 -1
  11. package/dist/cmd/ai/prompt/agent.js +12 -323
  12. package/dist/cmd/ai/prompt/agent.js.map +1 -1
  13. package/dist/cmd/ai/prompt/api.d.ts +7 -0
  14. package/dist/cmd/ai/prompt/api.d.ts.map +1 -1
  15. package/dist/cmd/ai/prompt/api.js +12 -260
  16. package/dist/cmd/ai/prompt/api.js.map +1 -1
  17. package/dist/cmd/ai/prompt/version.d.ts +35 -0
  18. package/dist/cmd/ai/prompt/version.d.ts.map +1 -0
  19. package/dist/cmd/ai/prompt/version.js +55 -0
  20. package/dist/cmd/ai/prompt/version.js.map +1 -0
  21. package/dist/cmd/ai/prompt/web.d.ts +7 -0
  22. package/dist/cmd/ai/prompt/web.d.ts.map +1 -1
  23. package/dist/cmd/ai/prompt/web.js +12 -283
  24. package/dist/cmd/ai/prompt/web.js.map +1 -1
  25. package/dist/cmd/ai/skills/generate.d.ts +3 -0
  26. package/dist/cmd/ai/skills/generate.d.ts.map +1 -0
  27. package/dist/cmd/ai/skills/generate.js +65 -0
  28. package/dist/cmd/ai/skills/generate.js.map +1 -0
  29. package/dist/cmd/ai/skills/generator.d.ts +4 -0
  30. package/dist/cmd/ai/skills/generator.d.ts.map +1 -0
  31. package/dist/cmd/ai/skills/generator.js +402 -0
  32. package/dist/cmd/ai/skills/generator.js.map +1 -0
  33. package/dist/cmd/ai/skills/index.d.ts +4 -0
  34. package/dist/cmd/ai/skills/index.d.ts.map +1 -0
  35. package/dist/cmd/ai/skills/index.js +21 -0
  36. package/dist/cmd/ai/skills/index.js.map +1 -0
  37. package/dist/cmd/auth/signup.d.ts.map +1 -1
  38. package/dist/cmd/auth/signup.js +1 -0
  39. package/dist/cmd/auth/signup.js.map +1 -1
  40. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  41. package/dist/cmd/build/entry-generator.js +40 -5
  42. package/dist/cmd/build/entry-generator.js.map +1 -1
  43. package/dist/cmd/build/vite/bun-dev-server.d.ts +7 -1
  44. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
  45. package/dist/cmd/build/vite/bun-dev-server.js +30 -26
  46. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
  47. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  48. package/dist/cmd/build/vite/metadata-generator.js +58 -7
  49. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  50. package/dist/cmd/build/vite/prompt-generator.d.ts +23 -0
  51. package/dist/cmd/build/vite/prompt-generator.d.ts.map +1 -0
  52. package/dist/cmd/build/vite/prompt-generator.js +123 -0
  53. package/dist/cmd/build/vite/prompt-generator.js.map +1 -0
  54. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  55. package/dist/cmd/build/vite/registry-generator.js +28 -11
  56. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  57. package/dist/cmd/build/vite/server-bundler.d.ts +4 -0
  58. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
  59. package/dist/cmd/build/vite/server-bundler.js +45 -16
  60. package/dist/cmd/build/vite/server-bundler.js.map +1 -1
  61. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
  62. package/dist/cmd/build/vite/vite-asset-server-config.js +4 -0
  63. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
  64. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  65. package/dist/cmd/build/vite/vite-builder.js +99 -87
  66. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  67. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  68. package/dist/cmd/cloud/deploy.js +80 -27
  69. package/dist/cmd/cloud/deploy.js.map +1 -1
  70. package/dist/cmd/cloud/keyvalue/create-namespace.d.ts.map +1 -1
  71. package/dist/cmd/cloud/keyvalue/create-namespace.js +3 -1
  72. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
  73. package/dist/cmd/cloud/keyvalue/delete-namespace.d.ts.map +1 -1
  74. package/dist/cmd/cloud/keyvalue/delete-namespace.js +3 -1
  75. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
  76. package/dist/cmd/cloud/keyvalue/delete.d.ts.map +1 -1
  77. package/dist/cmd/cloud/keyvalue/delete.js +3 -1
  78. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
  79. package/dist/cmd/cloud/keyvalue/set.d.ts.map +1 -1
  80. package/dist/cmd/cloud/keyvalue/set.js +4 -2
  81. package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
  82. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  83. package/dist/cmd/cloud/stream/get.js +2 -13
  84. package/dist/cmd/cloud/stream/get.js.map +1 -1
  85. package/dist/cmd/cloud/vector/delete-namespace.d.ts +3 -0
  86. package/dist/cmd/cloud/vector/delete-namespace.d.ts.map +1 -0
  87. package/dist/cmd/cloud/vector/delete-namespace.js +77 -0
  88. package/dist/cmd/cloud/vector/delete-namespace.js.map +1 -0
  89. package/dist/cmd/cloud/vector/index.d.ts.map +1 -1
  90. package/dist/cmd/cloud/vector/index.js +21 -4
  91. package/dist/cmd/cloud/vector/index.js.map +1 -1
  92. package/dist/cmd/cloud/vector/list-namespaces.d.ts +3 -0
  93. package/dist/cmd/cloud/vector/list-namespaces.d.ts.map +1 -0
  94. package/dist/cmd/cloud/vector/list-namespaces.js +42 -0
  95. package/dist/cmd/cloud/vector/list-namespaces.js.map +1 -0
  96. package/dist/cmd/cloud/vector/stats.d.ts +3 -0
  97. package/dist/cmd/cloud/vector/stats.d.ts.map +1 -0
  98. package/dist/cmd/cloud/vector/stats.js +142 -0
  99. package/dist/cmd/cloud/vector/stats.js.map +1 -0
  100. package/dist/cmd/cloud/vector/upsert.d.ts +3 -0
  101. package/dist/cmd/cloud/vector/upsert.d.ts.map +1 -0
  102. package/dist/cmd/cloud/vector/upsert.js +192 -0
  103. package/dist/cmd/cloud/vector/upsert.js.map +1 -0
  104. package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
  105. package/dist/cmd/dev/file-watcher.js +90 -31
  106. package/dist/cmd/dev/file-watcher.js.map +1 -1
  107. package/dist/cmd/dev/index.d.ts.map +1 -1
  108. package/dist/cmd/dev/index.js +244 -64
  109. package/dist/cmd/dev/index.js.map +1 -1
  110. package/dist/cmd/dev/skills.d.ts +10 -0
  111. package/dist/cmd/dev/skills.d.ts.map +1 -0
  112. package/dist/cmd/dev/skills.js +57 -0
  113. package/dist/cmd/dev/skills.js.map +1 -0
  114. package/dist/cmd/dev/sync.js +7 -7
  115. package/dist/cmd/dev/sync.js.map +1 -1
  116. package/dist/cmd/index.d.ts.map +1 -1
  117. package/dist/cmd/index.js +1 -0
  118. package/dist/cmd/index.js.map +1 -1
  119. package/dist/cmd/project/create.d.ts.map +1 -1
  120. package/dist/cmd/project/create.js +3 -0
  121. package/dist/cmd/project/create.js.map +1 -1
  122. package/dist/cmd/project/template-flow.d.ts +1 -0
  123. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  124. package/dist/cmd/project/template-flow.js +30 -5
  125. package/dist/cmd/project/template-flow.js.map +1 -1
  126. package/dist/cmd/setup/index.d.ts.map +1 -1
  127. package/dist/cmd/setup/index.js +1 -0
  128. package/dist/cmd/setup/index.js.map +1 -1
  129. package/dist/cmd/upgrade/index.d.ts +15 -0
  130. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  131. package/dist/cmd/upgrade/index.js +59 -4
  132. package/dist/cmd/upgrade/index.js.map +1 -1
  133. package/dist/domain.d.ts +45 -0
  134. package/dist/domain.d.ts.map +1 -0
  135. package/dist/domain.js +200 -0
  136. package/dist/domain.js.map +1 -0
  137. package/dist/schema-generator.d.ts +2 -0
  138. package/dist/schema-generator.d.ts.map +1 -1
  139. package/dist/schema-generator.js +18 -0
  140. package/dist/schema-generator.js.map +1 -1
  141. package/dist/steps.d.ts +1 -1
  142. package/dist/steps.d.ts.map +1 -1
  143. package/dist/steps.js +16 -5
  144. package/dist/steps.js.map +1 -1
  145. package/dist/tui/prompt.d.ts +1 -2
  146. package/dist/tui/prompt.d.ts.map +1 -1
  147. package/dist/tui/prompt.js +8 -4
  148. package/dist/tui/prompt.js.map +1 -1
  149. package/dist/tui.d.ts +16 -0
  150. package/dist/tui.d.ts.map +1 -1
  151. package/dist/tui.js +23 -2
  152. package/dist/tui.js.map +1 -1
  153. package/dist/types.d.ts +9 -2
  154. package/dist/types.d.ts.map +1 -1
  155. package/dist/types.js +3 -3
  156. package/dist/types.js.map +1 -1
  157. package/package.json +4 -4
  158. package/src/cli.ts +47 -12
  159. package/src/cmd/ai/index.ts +6 -1
  160. package/src/cmd/ai/prompt/agent.md +306 -0
  161. package/src/cmd/ai/prompt/agent.ts +12 -322
  162. package/src/cmd/ai/prompt/api.md +360 -0
  163. package/src/cmd/ai/prompt/api.ts +13 -260
  164. package/src/cmd/ai/prompt/version.ts +61 -0
  165. package/src/cmd/ai/prompt/web.md +509 -0
  166. package/src/cmd/ai/prompt/web.ts +12 -282
  167. package/src/cmd/ai/skills/generate.ts +75 -0
  168. package/src/cmd/ai/skills/generator.ts +519 -0
  169. package/src/cmd/ai/skills/index.ts +23 -0
  170. package/src/cmd/auth/signup.ts +1 -0
  171. package/src/cmd/build/entry-generator.ts +43 -7
  172. package/src/cmd/build/vite/bun-dev-server.ts +31 -28
  173. package/src/cmd/build/vite/metadata-generator.ts +73 -7
  174. package/src/cmd/build/vite/prompt-generator.ts +169 -0
  175. package/src/cmd/build/vite/registry-generator.ts +33 -10
  176. package/src/cmd/build/vite/server-bundler.ts +53 -22
  177. package/src/cmd/build/vite/vite-asset-server-config.ts +5 -0
  178. package/src/cmd/build/vite/vite-builder.ts +107 -87
  179. package/src/cmd/cloud/deploy.ts +103 -31
  180. package/src/cmd/cloud/keyvalue/create-namespace.ts +3 -1
  181. package/src/cmd/cloud/keyvalue/delete-namespace.ts +3 -1
  182. package/src/cmd/cloud/keyvalue/delete.ts +3 -1
  183. package/src/cmd/cloud/keyvalue/set.ts +4 -2
  184. package/src/cmd/cloud/stream/get.ts +2 -9
  185. package/src/cmd/cloud/vector/delete-namespace.ts +89 -0
  186. package/src/cmd/cloud/vector/index.ts +21 -4
  187. package/src/cmd/cloud/vector/list-namespaces.ts +46 -0
  188. package/src/cmd/cloud/vector/stats.ts +160 -0
  189. package/src/cmd/cloud/vector/upsert.ts +216 -0
  190. package/src/cmd/dev/file-watcher.ts +101 -32
  191. package/src/cmd/dev/index.ts +343 -115
  192. package/src/cmd/dev/skills.ts +82 -0
  193. package/src/cmd/dev/sync.ts +7 -7
  194. package/src/cmd/index.ts +1 -0
  195. package/src/cmd/project/create.ts +3 -0
  196. package/src/cmd/project/template-flow.ts +37 -5
  197. package/src/cmd/setup/index.ts +1 -0
  198. package/src/cmd/upgrade/index.ts +68 -4
  199. package/src/domain.ts +273 -0
  200. package/src/schema-generator.ts +23 -0
  201. package/src/steps.ts +16 -5
  202. package/src/tui/prompt.ts +11 -5
  203. package/src/tui.ts +21 -2
  204. package/src/types/md.d.ts +8 -0
  205. package/src/types.ts +12 -3
  206. package/dist/cmd/cloud/domain.d.ts +0 -17
  207. package/dist/cmd/cloud/domain.d.ts.map +0 -1
  208. package/dist/cmd/cloud/domain.js +0 -79
  209. package/dist/cmd/cloud/domain.js.map +0 -1
  210. package/src/cmd/cloud/domain.ts +0 -100
@@ -1,21 +1,38 @@
1
1
  import { createCommand } from '../../../types';
2
2
  import { deleteSubcommand } from './delete';
3
+ import { deleteNamespaceSubcommand } from './delete-namespace';
3
4
  import { getSubcommand } from './get';
5
+ import { listNamespacesSubcommand } from './list-namespaces';
4
6
  import { searchSubcommand } from './search';
7
+ import { statsSubcommand } from './stats';
8
+ import { upsertSubcommand } from './upsert';
5
9
  import { getCommand } from '../../../command-prefix';
6
10
  export const vectorCommand = createCommand({
7
11
  name: 'vector',
8
12
  aliases: ['vec'],
9
13
  description: 'Manage vector storage for your projects',
10
- tags: ['requires-auth', 'destructive', 'deletes-resource', 'slow'],
14
+ tags: ['requires-auth', 'slow'],
11
15
  examples: [
12
16
  {
13
- command: getCommand('cloud vector search "query text"'),
17
+ command: getCommand('cloud vector search products "query text"'),
14
18
  description: 'Search vector storage',
15
19
  },
16
- { command: getCommand('cloud vec get <id>'), description: 'Get vector by ID' },
20
+ {
21
+ command: getCommand('cloud vec upsert products doc1 --document "text"'),
22
+ description: 'Upsert a vector',
23
+ },
24
+ { command: getCommand('cloud vec get products doc1'), description: 'Get vector by key' },
25
+ { command: getCommand('cloud vec stats'), description: 'Show namespace statistics' },
26
+ ],
27
+ subcommands: [
28
+ upsertSubcommand,
29
+ searchSubcommand,
30
+ getSubcommand,
31
+ deleteSubcommand,
32
+ statsSubcommand,
33
+ listNamespacesSubcommand,
34
+ deleteNamespaceSubcommand,
17
35
  ],
18
- subcommands: [searchSubcommand, getSubcommand, deleteSubcommand],
19
36
  requires: { auth: true, project: true },
20
37
  });
21
38
  export default vectorCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,WAAW,EAAE,yCAAyC;IACtD,IAAI,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,CAAC;IAClE,QAAQ,EAAE;QACT;YACC,OAAO,EAAE,UAAU,CAAC,kCAAkC,CAAC;YACvD,WAAW,EAAE,uBAAuB;SACpC;QACD,EAAE,OAAO,EAAE,UAAU,CAAC,oBAAoB,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE;KAC9E;IACD,WAAW,EAAE,CAAC,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,CAAC;IAChE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;CACvC,CAAC,CAAC;AAEH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,WAAW,EAAE,yCAAyC;IACtD,IAAI,EAAE,CAAC,eAAe,EAAE,MAAM,CAAC;IAC/B,QAAQ,EAAE;QACT;YACC,OAAO,EAAE,UAAU,CAAC,2CAA2C,CAAC;YAChE,WAAW,EAAE,uBAAuB;SACpC;QACD;YACC,OAAO,EAAE,UAAU,CAAC,kDAAkD,CAAC;YACvE,WAAW,EAAE,iBAAiB;SAC9B;QACD,EAAE,OAAO,EAAE,UAAU,CAAC,6BAA6B,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE;QACxF,EAAE,OAAO,EAAE,UAAU,CAAC,iBAAiB,CAAC,EAAE,WAAW,EAAE,2BAA2B,EAAE;KACpF;IACD,WAAW,EAAE;QACZ,gBAAgB;QAChB,gBAAgB;QAChB,aAAa;QACb,gBAAgB;QAChB,eAAe;QACf,wBAAwB;QACxB,yBAAyB;KACzB;IACD,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;CACvC,CAAC,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const listNamespacesSubcommand: import("../../..").CommandDefinition;
2
+ export default listNamespacesSubcommand;
3
+ //# sourceMappingURL=list-namespaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-namespaces.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/list-namespaces.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,wBAAwB,sCAmCnC,CAAC;AAEH,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createStorageAdapter } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+ const NamespaceListResponseSchema = z.array(z.string().describe('Namespace name'));
7
+ export const listNamespacesSubcommand = createCommand({
8
+ name: 'list-namespaces',
9
+ aliases: ['namespaces', 'ns'],
10
+ description: 'List all vector namespaces',
11
+ tags: ['read-only', 'fast', 'requires-auth'],
12
+ requires: { auth: true, project: true },
13
+ examples: [
14
+ { command: getCommand('vector list-namespaces'), description: 'List all namespaces' },
15
+ { command: getCommand('vector namespaces'), description: 'List namespaces (using alias)' },
16
+ { command: getCommand('vector ns'), description: 'List namespaces (short alias)' },
17
+ ],
18
+ schema: {
19
+ response: NamespaceListResponseSchema,
20
+ },
21
+ webUrl: '/services/vector',
22
+ idempotent: true,
23
+ async handler(ctx) {
24
+ const { options } = ctx;
25
+ const storage = await createStorageAdapter(ctx);
26
+ const namespaces = await storage.getNamespaces();
27
+ if (!options.json) {
28
+ if (namespaces.length === 0) {
29
+ tui.info('No vector namespaces found');
30
+ }
31
+ else {
32
+ tui.info(`Found ${namespaces.length} namespace(s):`);
33
+ for (const name of namespaces) {
34
+ tui.arrow(name);
35
+ }
36
+ }
37
+ }
38
+ return namespaces;
39
+ },
40
+ });
41
+ export default listNamespacesSubcommand;
42
+ //# sourceMappingURL=list-namespaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-namespaces.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/list-namespaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAEnF,MAAM,CAAC,MAAM,wBAAwB,GAAG,aAAa,CAAC;IACrD,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC;IAC7B,WAAW,EAAE,4BAA4B;IACzC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC;IAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;IACvC,QAAQ,EAAE;QACT,EAAE,OAAO,EAAE,UAAU,CAAC,wBAAwB,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE;QACrF,EAAE,OAAO,EAAE,UAAU,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE;QAC1F,EAAE,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE;KAClF;IACD,MAAM,EAAE;QACP,QAAQ,EAAE,2BAA2B;KACrC;IACD,MAAM,EAAE,kBAAkB;IAC1B,UAAU,EAAE,IAAI;IAEhB,KAAK,CAAC,OAAO,CAAC,GAAG;QAChB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;QACxB,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;QAEjD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACP,GAAG,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,gBAAgB,CAAC,CAAC;gBACrD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC/B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjB,CAAC;YACF,CAAC;QACF,CAAC;QAED,OAAO,UAAU,CAAC;IACnB,CAAC;CACD,CAAC,CAAC;AAEH,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const statsSubcommand: import("../../..").CommandDefinition;
2
+ export default statsSubcommand;
3
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/stats.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,eAAe,sCA8H1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -0,0 +1,142 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createStorageAdapter } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+ const VectorItemStatsSchema = z.object({
7
+ embedding: z.array(z.number()).optional().describe('The embedding vector'),
8
+ document: z.string().optional().describe('Original document text'),
9
+ size: z.number().describe('Size in bytes'),
10
+ metadata: z.record(z.string(), z.unknown()).optional().describe('Metadata'),
11
+ firstUsed: z.number().describe('First access timestamp (ms)'),
12
+ lastUsed: z.number().describe('Last access timestamp (ms)'),
13
+ count: z.number().optional().describe('Access count (only available in cloud storage)'),
14
+ });
15
+ const VectorNamespaceStatsSchema = z.object({
16
+ sum: z.number().describe('Total size in bytes'),
17
+ count: z.number().describe('Number of vectors'),
18
+ createdAt: z.number().optional().describe('Creation timestamp (ms)'),
19
+ lastUsed: z.number().optional().describe('Last used timestamp (ms)'),
20
+ });
21
+ const VectorStatsResponseSchema = z.union([
22
+ VectorNamespaceStatsSchema.extend({
23
+ namespace: z.string().describe('Namespace name'),
24
+ sampledResults: z.record(z.string(), VectorItemStatsSchema).optional(),
25
+ }),
26
+ z.record(z.string(), VectorNamespaceStatsSchema),
27
+ ]);
28
+ export const statsSubcommand = createCommand({
29
+ name: 'stats',
30
+ description: 'Get statistics for vector storage',
31
+ tags: ['read-only', 'fast', 'requires-auth'],
32
+ requires: { auth: true, project: true },
33
+ idempotent: true,
34
+ examples: [
35
+ { command: getCommand('vector stats'), description: 'Show stats for all namespaces' },
36
+ {
37
+ command: getCommand('vector stats products'),
38
+ description: 'Show detailed stats for products namespace',
39
+ },
40
+ { command: getCommand('vector stats embeddings'), description: 'Show stats for embeddings' },
41
+ ],
42
+ schema: {
43
+ args: z.object({
44
+ name: z.string().optional().describe('the vector namespace (optional)'),
45
+ }),
46
+ response: VectorStatsResponseSchema,
47
+ },
48
+ webUrl: (ctx) => ctx.args.name ? `/services/vector/${encodeURIComponent(ctx.args.name)}` : '/services/vector',
49
+ async handler(ctx) {
50
+ const { args, options } = ctx;
51
+ const storage = await createStorageAdapter(ctx);
52
+ if (args.name) {
53
+ const stats = await storage.getStats(args.name);
54
+ if (!options.json) {
55
+ if (stats.count === 0 && stats.sum === 0) {
56
+ tui.info(`Namespace ${tui.bold(args.name)} is empty or does not exist`);
57
+ }
58
+ else {
59
+ tui.info(`Statistics for ${tui.bold(args.name)}:`);
60
+ tui.info(` Vectors: ${stats.count}`);
61
+ const sizeDisplay = stats.sum < 1024 * 1024
62
+ ? `${stats.sum.toLocaleString()} bytes`
63
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
64
+ tui.info(` Total size: ${sizeDisplay}`);
65
+ if (stats.createdAt) {
66
+ tui.info(` Created: ${new Date(stats.createdAt).toLocaleString()}`);
67
+ }
68
+ if (stats.lastUsed) {
69
+ tui.info(` Last used: ${new Date(stats.lastUsed).toLocaleString()}`);
70
+ }
71
+ if (stats.sampledResults && Object.keys(stats.sampledResults).length > 0) {
72
+ tui.info('');
73
+ tui.info(` Sample vectors (${Object.keys(stats.sampledResults).length}):`);
74
+ const tableData = Object.entries(stats.sampledResults).map(([key, item]) => {
75
+ const docPreview = item.document
76
+ ? item.document.length > 30
77
+ ? item.document.substring(0, 27) + '...'
78
+ : item.document
79
+ : '-';
80
+ return {
81
+ Key: key,
82
+ Size: `${item.size} bytes`,
83
+ Accesses: item.count ?? '-',
84
+ 'Last Used': new Date(item.lastUsed).toLocaleDateString(),
85
+ Document: docPreview,
86
+ };
87
+ });
88
+ tui.table(tableData, [
89
+ { name: 'Key', alignment: 'left' },
90
+ { name: 'Size', alignment: 'right' },
91
+ { name: 'Accesses', alignment: 'right' },
92
+ { name: 'Last Used', alignment: 'left' },
93
+ { name: 'Document', alignment: 'left' },
94
+ ]);
95
+ }
96
+ }
97
+ }
98
+ return {
99
+ namespace: args.name,
100
+ ...stats,
101
+ };
102
+ }
103
+ else {
104
+ const allStats = await storage.getAllStats();
105
+ const entries = Object.entries(allStats);
106
+ if (!options.json) {
107
+ if (entries.length === 0) {
108
+ tui.info('No vector namespaces found');
109
+ }
110
+ else {
111
+ tui.info(`Found ${entries.length} ${tui.plural(entries.length, 'namespace', 'namespaces')}:`);
112
+ const tableData = entries.map(([name, stats]) => {
113
+ const sizeDisplay = stats.sum < 1024 * 1024
114
+ ? `${stats.sum.toLocaleString()} bytes`
115
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
116
+ return {
117
+ Namespace: name,
118
+ Vectors: stats.count,
119
+ Size: sizeDisplay,
120
+ Created: stats.createdAt
121
+ ? new Date(stats.createdAt).toLocaleDateString()
122
+ : '-',
123
+ 'Last Used': stats.lastUsed
124
+ ? new Date(stats.lastUsed).toLocaleDateString()
125
+ : '-',
126
+ };
127
+ });
128
+ tui.table(tableData, [
129
+ { name: 'Namespace', alignment: 'left' },
130
+ { name: 'Vectors', alignment: 'right' },
131
+ { name: 'Size', alignment: 'right' },
132
+ { name: 'Created', alignment: 'left' },
133
+ { name: 'Last Used', alignment: 'left' },
134
+ ]);
135
+ }
136
+ }
137
+ return allStats;
138
+ }
139
+ },
140
+ });
141
+ export default statsSubcommand;
142
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const upsertSubcommand: import("../../..").CommandDefinition;
2
+ export default upsertSubcommand;
3
+ //# sourceMappingURL=upsert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/upsert.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,gBAAgB,sCA+L3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,192 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createStorageAdapter } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+ const VectorUpsertResponseSchema = z.object({
7
+ success: z.boolean().describe('Whether the operation succeeded'),
8
+ namespace: z.string().describe('Namespace name'),
9
+ count: z.number().describe('Number of vectors upserted'),
10
+ results: z
11
+ .array(z.object({
12
+ key: z.string().describe('Vector key'),
13
+ id: z.string().describe('Vector ID'),
14
+ }))
15
+ .describe('Upsert results with key-to-id mappings'),
16
+ durationMs: z.number().describe('Operation duration in milliseconds'),
17
+ });
18
+ export const upsertSubcommand = createCommand({
19
+ name: 'upsert',
20
+ aliases: ['put', 'add'],
21
+ description: 'Add or update vectors in the vector storage',
22
+ tags: ['mutating', 'updates-resource', 'slow', 'requires-auth'],
23
+ idempotent: true,
24
+ requires: { auth: true, project: true },
25
+ examples: [
26
+ {
27
+ command: getCommand('vector upsert products doc1 --document "Comfortable office chair"'),
28
+ description: 'Upsert a single vector with document text',
29
+ },
30
+ {
31
+ command: getCommand('vector upsert products doc1 --document "Chair" --metadata \'{"category":"furniture"}\''),
32
+ description: 'Upsert with metadata',
33
+ },
34
+ {
35
+ command: getCommand('vector upsert embeddings vec1 --embeddings "[0.1, 0.2, 0.3]"'),
36
+ description: 'Upsert with pre-computed embeddings',
37
+ },
38
+ {
39
+ command: getCommand('vector upsert products --file vectors.json'),
40
+ description: 'Bulk upsert from JSON file',
41
+ },
42
+ {
43
+ command: `cat vectors.json | ${getCommand('vector upsert products -')}`,
44
+ description: 'Bulk upsert from stdin',
45
+ },
46
+ ],
47
+ schema: {
48
+ args: z.object({
49
+ namespace: z.string().min(1).describe('the vector storage namespace'),
50
+ key: z
51
+ .string()
52
+ .optional()
53
+ .describe('the key for single vector upsert (not used with --file or stdin)'),
54
+ }),
55
+ options: z.object({
56
+ document: z.string().optional().describe('document text to embed'),
57
+ embeddings: z.string().optional().describe('pre-computed embeddings as JSON array'),
58
+ metadata: z.string().optional().describe('metadata as JSON object'),
59
+ file: z
60
+ .string()
61
+ .optional()
62
+ .describe('path to JSON file containing vectors, or "-" for stdin'),
63
+ }),
64
+ response: VectorUpsertResponseSchema,
65
+ },
66
+ webUrl: (ctx) => `/services/vector/${encodeURIComponent(ctx.args.namespace)}`,
67
+ async handler(ctx) {
68
+ const { args, opts, options, logger } = ctx;
69
+ const storage = await createStorageAdapter(ctx);
70
+ let documents = [];
71
+ // Check if reading from file or stdin
72
+ const fileArg = opts.file || (args.key === '-' ? '-' : undefined);
73
+ if (fileArg) {
74
+ let content;
75
+ if (fileArg === '-') {
76
+ // Read from stdin
77
+ const chunks = [];
78
+ const reader = Bun.stdin.stream().getReader();
79
+ while (true) {
80
+ const { done, value } = await reader.read();
81
+ if (done)
82
+ break;
83
+ chunks.push(value);
84
+ }
85
+ const decoder = new TextDecoder();
86
+ content = chunks.map((chunk) => decoder.decode(chunk, { stream: true })).join('');
87
+ }
88
+ else {
89
+ // Read from file
90
+ const file = Bun.file(fileArg);
91
+ if (!(await file.exists())) {
92
+ tui.fatal(`File not found: ${fileArg}`);
93
+ }
94
+ content = await file.text();
95
+ }
96
+ try {
97
+ const parsed = JSON.parse(content.trim());
98
+ if (Array.isArray(parsed)) {
99
+ documents = parsed;
100
+ }
101
+ else {
102
+ documents = [parsed];
103
+ }
104
+ }
105
+ catch {
106
+ tui.fatal('Invalid JSON in input file/stdin');
107
+ }
108
+ // Validate documents
109
+ for (const doc of documents) {
110
+ if (!doc.key || typeof doc.key !== 'string') {
111
+ tui.fatal('Each document must have a non-empty "key" property');
112
+ }
113
+ if (!doc.document && !('embeddings' in doc)) {
114
+ tui.fatal(`Document with key "${doc.key}" must have either "document" or "embeddings" property`);
115
+ }
116
+ }
117
+ }
118
+ else {
119
+ // Single vector upsert via command line arguments
120
+ if (!args.key) {
121
+ tui.fatal('Key is required for single vector upsert. Use --file for bulk upsert.');
122
+ }
123
+ if (!opts.document && !opts.embeddings) {
124
+ tui.fatal('Either --document or --embeddings is required');
125
+ }
126
+ if (opts.document && opts.embeddings) {
127
+ tui.fatal('Cannot use both --document and --embeddings');
128
+ }
129
+ let metadata;
130
+ if (opts.metadata) {
131
+ try {
132
+ metadata = JSON.parse(opts.metadata);
133
+ }
134
+ catch {
135
+ tui.fatal('Invalid JSON in --metadata');
136
+ }
137
+ }
138
+ if (opts.document) {
139
+ documents = [
140
+ {
141
+ key: args.key,
142
+ document: opts.document,
143
+ metadata,
144
+ },
145
+ ];
146
+ }
147
+ else if (opts.embeddings) {
148
+ let embeddings;
149
+ try {
150
+ embeddings = JSON.parse(opts.embeddings);
151
+ if (!Array.isArray(embeddings) || !embeddings.every((n) => typeof n === 'number')) {
152
+ throw new Error('Not an array of numbers');
153
+ }
154
+ }
155
+ catch {
156
+ tui.fatal('Invalid embeddings: must be a JSON array of numbers');
157
+ }
158
+ documents = [
159
+ {
160
+ key: args.key,
161
+ embeddings,
162
+ metadata,
163
+ },
164
+ ];
165
+ }
166
+ }
167
+ if (documents.length === 0) {
168
+ tui.fatal('No documents to upsert');
169
+ }
170
+ const started = Date.now();
171
+ logger.debug(`Upserting ${documents.length} vector(s) to ${args.namespace}`);
172
+ const results = await storage.upsert(args.namespace, ...documents);
173
+ const durationMs = Date.now() - started;
174
+ if (!options.json) {
175
+ tui.success(`Upserted ${results.length} vector(s) to ${tui.bold(args.namespace)} (${durationMs}ms)`);
176
+ if (results.length <= 10) {
177
+ for (const result of results) {
178
+ tui.arrow(`${result.key} → ${result.id}`);
179
+ }
180
+ }
181
+ }
182
+ return {
183
+ success: true,
184
+ namespace: args.namespace,
185
+ count: results.length,
186
+ results,
187
+ durationMs,
188
+ };
189
+ },
190
+ });
191
+ export default upsertSubcommand;
192
+ //# sourceMappingURL=upsert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert.js","sourceRoot":"","sources":["../../../../src/cmd/cloud/vector/upsert.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../../src/cmd/dev/file-watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAgPjF"}
1
+ {"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../../src/cmd/dev/file-watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAqTjF"}
@@ -4,8 +4,8 @@
4
4
  * Watches source files and triggers server restart on changes.
5
5
  * Handles both backend (API, agents, lib) and generates restart signals.
6
6
  */
7
- import { watch, statSync, readdirSync } from 'node:fs';
8
- import { resolve } from 'node:path';
7
+ import { watch, statSync, readdirSync, lstatSync } from 'node:fs';
8
+ import { resolve, relative } from 'node:path';
9
9
  import { createAgentTemplates, createAPITemplates } from './templates';
10
10
  /**
11
11
  * Create a file watcher manager for hot reload
@@ -15,12 +15,28 @@ export function createFileWatcher(options) {
15
15
  const watchers = [];
16
16
  let paused = false;
17
17
  let buildCooldownTimer = null;
18
- // Watch the entire root directory recursively
19
- // This is simpler and more reliable than watching individual paths
20
- const watchDirs = [rootDir];
21
- // Directories to ignore
18
+ // Directories to ignore - these are NEVER traversed into
19
+ // This prevents EMFILE errors from symlink cycles in node_modules
20
+ const ignoreDirs = new Set([
21
+ '.agentuity',
22
+ '.agents',
23
+ '.claude',
24
+ '.code',
25
+ '.opencode',
26
+ 'node_modules',
27
+ '.git',
28
+ 'dist',
29
+ 'build',
30
+ '.next',
31
+ '.turbo',
32
+ ]);
33
+ // Paths to ignore for file change events (but may still be traversed)
22
34
  const ignorePaths = [
23
35
  '.agentuity',
36
+ '.agents',
37
+ '.claude',
38
+ '.code',
39
+ '.opencode',
24
40
  'node_modules',
25
41
  '.git',
26
42
  'dist',
@@ -125,43 +141,86 @@ export function createFileWatcher(options) {
125
141
  logger.debug('File changed (%s): %s', eventType, changedFile || watchDir);
126
142
  onRestart();
127
143
  }
144
+ /**
145
+ * Recursively collect all directories to watch, skipping ignored directories.
146
+ * This prevents EMFILE errors from symlink cycles in node_modules.
147
+ */
148
+ function collectWatchDirs(dir, visited = new Set()) {
149
+ const dirs = [dir];
150
+ try {
151
+ // Use lstat to check for symlinks - get the real path to detect cycles
152
+ const stat = lstatSync(dir);
153
+ // Skip symlinks to prevent following circular symlinks
154
+ if (stat.isSymbolicLink()) {
155
+ logger.trace('Skipping symlink: %s', dir);
156
+ return [];
157
+ }
158
+ // Track visited inodes to detect cycles
159
+ const key = `${stat.dev}:${stat.ino}`;
160
+ if (visited.has(key)) {
161
+ logger.trace('Skipping already visited directory (cycle detected): %s', dir);
162
+ return [];
163
+ }
164
+ visited.add(key);
165
+ const entries = readdirSync(dir, { withFileTypes: true });
166
+ for (const entry of entries) {
167
+ if (!entry.isDirectory())
168
+ continue;
169
+ const name = entry.name;
170
+ // Skip ignored directories entirely - this is the key fix
171
+ if (ignoreDirs.has(name)) {
172
+ logger.trace('Skipping ignored directory: %s', resolve(dir, name));
173
+ continue;
174
+ }
175
+ // Skip hidden directories (except specific ones like .env folders)
176
+ if (name.startsWith('.')) {
177
+ logger.trace('Skipping hidden directory: %s', resolve(dir, name));
178
+ continue;
179
+ }
180
+ const fullPath = resolve(dir, name);
181
+ dirs.push(...collectWatchDirs(fullPath, visited));
182
+ }
183
+ }
184
+ catch (error) {
185
+ logger.trace('Error reading directory %s: %s', dir, error);
186
+ }
187
+ return dirs;
188
+ }
128
189
  /**
129
190
  * Start watching files
130
191
  */
131
192
  function start() {
132
193
  logger.debug('Starting file watchers for hot reload...');
133
- // Watch root directory (already absolute path)
134
- for (const watchPath of watchDirs) {
194
+ // Collect all directories to watch, excluding node_modules and other ignored dirs
195
+ const allDirs = collectWatchDirs(rootDir);
196
+ // Add additional paths
197
+ if (additionalPaths && additionalPaths.length > 0) {
198
+ for (const additionalPath of additionalPaths) {
199
+ const fullPath = resolve(rootDir, additionalPath);
200
+ allDirs.push(...collectWatchDirs(fullPath));
201
+ }
202
+ }
203
+ // De-duplicate directories
204
+ const uniqueDirs = [...new Set(allDirs)];
205
+ logger.debug('Collected %d directories to watch', uniqueDirs.length);
206
+ // Watch each directory non-recursively
207
+ for (const watchPath of uniqueDirs) {
135
208
  try {
136
- logger.trace('Setting up watcher for: %s', watchPath);
137
- const watcher = watch(watchPath, { recursive: true }, (eventType, changedFile) => {
138
- handleFileChange(eventType, changedFile, watchPath);
209
+ // Use non-recursive watch to avoid traversing into node_modules
210
+ const watcher = watch(watchPath, { recursive: false }, (eventType, changedFile) => {
211
+ // Construct relative path from rootDir for consistent handling
212
+ const relPath = changedFile
213
+ ? relative(rootDir, resolve(watchPath, changedFile))
214
+ : relative(rootDir, watchPath);
215
+ handleFileChange(eventType, relPath || changedFile, rootDir);
139
216
  });
140
217
  watchers.push(watcher);
141
- logger.trace('Watcher started for: %s', watchPath);
142
218
  }
143
219
  catch (error) {
144
- logger.warn('Failed to start watcher for %s: %s', watchPath, error);
145
- }
146
- }
147
- // Watch additional paths if provided
148
- if (additionalPaths && additionalPaths.length > 0) {
149
- for (const additionalPath of additionalPaths) {
150
- const fullPath = resolve(rootDir, additionalPath);
151
- try {
152
- logger.trace('Setting up watcher for additional path: %s', fullPath);
153
- const watcher = watch(fullPath, { recursive: true }, (eventType, changedFile) => {
154
- handleFileChange(eventType, changedFile, fullPath);
155
- });
156
- watchers.push(watcher);
157
- logger.trace('Watcher started for additional path: %s', fullPath);
158
- }
159
- catch (error) {
160
- logger.warn('Failed to start watcher for %s: %s', fullPath, error);
161
- }
220
+ logger.trace('Failed to start watcher for %s: %s', watchPath, error);
162
221
  }
163
222
  }
164
- logger.debug('File watchers started (%d paths)', watchers.length);
223
+ logger.debug('File watchers started (%d directories)', watchers.length);
165
224
  }
166
225
  /**
167
226
  * Stop all watchers