@ambitresearch/genie 1.3.1

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 (301) hide show
  1. package/README.md +15 -0
  2. package/dist/auth/bearer.d.ts +49 -0
  3. package/dist/auth/bearer.d.ts.map +1 -0
  4. package/dist/auth/bearer.js +159 -0
  5. package/dist/auth/bearer.js.map +1 -0
  6. package/dist/auth/oauth/authorize.d.ts +19 -0
  7. package/dist/auth/oauth/authorize.d.ts.map +1 -0
  8. package/dist/auth/oauth/authorize.js +111 -0
  9. package/dist/auth/oauth/authorize.js.map +1 -0
  10. package/dist/auth/oauth/config.d.ts +10 -0
  11. package/dist/auth/oauth/config.d.ts.map +1 -0
  12. package/dist/auth/oauth/config.js +16 -0
  13. package/dist/auth/oauth/config.js.map +1 -0
  14. package/dist/auth/oauth/dcr.d.ts +15 -0
  15. package/dist/auth/oauth/dcr.d.ts.map +1 -0
  16. package/dist/auth/oauth/dcr.js +38 -0
  17. package/dist/auth/oauth/dcr.js.map +1 -0
  18. package/dist/auth/oauth/jwt.d.ts +13 -0
  19. package/dist/auth/oauth/jwt.d.ts.map +1 -0
  20. package/dist/auth/oauth/jwt.js +46 -0
  21. package/dist/auth/oauth/jwt.js.map +1 -0
  22. package/dist/auth/oauth/metadata.d.ts +9 -0
  23. package/dist/auth/oauth/metadata.d.ts.map +1 -0
  24. package/dist/auth/oauth/metadata.js +19 -0
  25. package/dist/auth/oauth/metadata.js.map +1 -0
  26. package/dist/auth/oauth/router.d.ts +32 -0
  27. package/dist/auth/oauth/router.d.ts.map +1 -0
  28. package/dist/auth/oauth/router.js +159 -0
  29. package/dist/auth/oauth/router.js.map +1 -0
  30. package/dist/auth/oauth/store.d.ts +55 -0
  31. package/dist/auth/oauth/store.d.ts.map +1 -0
  32. package/dist/auth/oauth/store.js +63 -0
  33. package/dist/auth/oauth/store.js.map +1 -0
  34. package/dist/auth/oauth/token.d.ts +21 -0
  35. package/dist/auth/oauth/token.d.ts.map +1 -0
  36. package/dist/auth/oauth/token.js +77 -0
  37. package/dist/auth/oauth/token.js.map +1 -0
  38. package/dist/auth/oidc/group-policy.d.ts +43 -0
  39. package/dist/auth/oidc/group-policy.d.ts.map +1 -0
  40. package/dist/auth/oidc/group-policy.js +54 -0
  41. package/dist/auth/oidc/group-policy.js.map +1 -0
  42. package/dist/auth/oidc/verifier.d.ts +42 -0
  43. package/dist/auth/oidc/verifier.d.ts.map +1 -0
  44. package/dist/auth/oidc/verifier.js +145 -0
  45. package/dist/auth/oidc/verifier.js.map +1 -0
  46. package/dist/auth/token-cli.d.ts +9 -0
  47. package/dist/auth/token-cli.d.ts.map +1 -0
  48. package/dist/auth/token-cli.js +98 -0
  49. package/dist/auth/token-cli.js.map +1 -0
  50. package/dist/cli.d.ts +3 -0
  51. package/dist/cli.d.ts.map +1 -0
  52. package/dist/cli.js +149 -0
  53. package/dist/cli.js.map +1 -0
  54. package/dist/config/redact.d.ts +20 -0
  55. package/dist/config/redact.d.ts.map +1 -0
  56. package/dist/config/redact.js +77 -0
  57. package/dist/config/redact.js.map +1 -0
  58. package/dist/config/secrets.d.ts +100 -0
  59. package/dist/config/secrets.d.ts.map +1 -0
  60. package/dist/config/secrets.js +130 -0
  61. package/dist/config/secrets.js.map +1 -0
  62. package/dist/framework/html.d.ts +103 -0
  63. package/dist/framework/html.d.ts.map +1 -0
  64. package/dist/framework/html.js +271 -0
  65. package/dist/framework/html.js.map +1 -0
  66. package/dist/framework/interface.d.ts +130 -0
  67. package/dist/framework/interface.d.ts.map +1 -0
  68. package/dist/framework/interface.js +112 -0
  69. package/dist/framework/interface.js.map +1 -0
  70. package/dist/framework/react.d.ts +133 -0
  71. package/dist/framework/react.d.ts.map +1 -0
  72. package/dist/framework/react.js +243 -0
  73. package/dist/framework/react.js.map +1 -0
  74. package/dist/framework/vue.d.ts +99 -0
  75. package/dist/framework/vue.d.ts.map +1 -0
  76. package/dist/framework/vue.js +375 -0
  77. package/dist/framework/vue.js.map +1 -0
  78. package/dist/index.d.ts +3 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +3 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/llm/client.d.ts +81 -0
  83. package/dist/llm/client.d.ts.map +1 -0
  84. package/dist/llm/client.js +141 -0
  85. package/dist/llm/client.js.map +1 -0
  86. package/dist/llm/component-response.d.ts +111 -0
  87. package/dist/llm/component-response.d.ts.map +1 -0
  88. package/dist/llm/component-response.js +167 -0
  89. package/dist/llm/component-response.js.map +1 -0
  90. package/dist/llm/generated-files.d.ts +10 -0
  91. package/dist/llm/generated-files.d.ts.map +1 -0
  92. package/dist/llm/generated-files.js +26 -0
  93. package/dist/llm/generated-files.js.map +1 -0
  94. package/dist/llm/prompts/CHANGELOG.md +70 -0
  95. package/dist/llm/prompts/generate-component.system.md +99 -0
  96. package/dist/llm/prompts/refine-component.system.md +112 -0
  97. package/dist/llm/prompts.d.ts +66 -0
  98. package/dist/llm/prompts.d.ts.map +1 -0
  99. package/dist/llm/prompts.js +78 -0
  100. package/dist/llm/prompts.js.map +1 -0
  101. package/dist/llm/retry.d.ts +183 -0
  102. package/dist/llm/retry.d.ts.map +1 -0
  103. package/dist/llm/retry.js +475 -0
  104. package/dist/llm/retry.js.map +1 -0
  105. package/dist/llm/schema.d.ts +129 -0
  106. package/dist/llm/schema.d.ts.map +1 -0
  107. package/dist/llm/schema.js +147 -0
  108. package/dist/llm/schema.js.map +1 -0
  109. package/dist/llm/validate.d.ts +107 -0
  110. package/dist/llm/validate.d.ts.map +1 -0
  111. package/dist/llm/validate.js +174 -0
  112. package/dist/llm/validate.js.map +1 -0
  113. package/dist/manifest/compiler.d.ts +112 -0
  114. package/dist/manifest/compiler.d.ts.map +1 -0
  115. package/dist/manifest/compiler.js +306 -0
  116. package/dist/manifest/compiler.js.map +1 -0
  117. package/dist/manifest/ensure.d.ts +46 -0
  118. package/dist/manifest/ensure.d.ts.map +1 -0
  119. package/dist/manifest/ensure.js +49 -0
  120. package/dist/manifest/ensure.js.map +1 -0
  121. package/dist/manifest/index.d.ts +13 -0
  122. package/dist/manifest/index.d.ts.map +1 -0
  123. package/dist/manifest/index.js +13 -0
  124. package/dist/manifest/index.js.map +1 -0
  125. package/dist/middleware/plan-guard.d.ts +167 -0
  126. package/dist/middleware/plan-guard.d.ts.map +1 -0
  127. package/dist/middleware/plan-guard.js +190 -0
  128. package/dist/middleware/plan-guard.js.map +1 -0
  129. package/dist/plans/index.d.ts +71 -0
  130. package/dist/plans/index.d.ts.map +1 -0
  131. package/dist/plans/index.js +252 -0
  132. package/dist/plans/index.js.map +1 -0
  133. package/dist/schemas/component.schema.json +114 -0
  134. package/dist/server.d.ts +96 -0
  135. package/dist/server.d.ts.map +1 -0
  136. package/dist/server.js +258 -0
  137. package/dist/server.js.map +1 -0
  138. package/dist/store/empty-manifest.d.ts +58 -0
  139. package/dist/store/empty-manifest.d.ts.map +1 -0
  140. package/dist/store/empty-manifest.js +59 -0
  141. package/dist/store/empty-manifest.js.map +1 -0
  142. package/dist/store/git-host.d.ts +120 -0
  143. package/dist/store/git-host.d.ts.map +1 -0
  144. package/dist/store/git-host.js +796 -0
  145. package/dist/store/git-host.js.map +1 -0
  146. package/dist/store/index.d.ts +5 -0
  147. package/dist/store/index.d.ts.map +1 -0
  148. package/dist/store/index.js +4 -0
  149. package/dist/store/index.js.map +1 -0
  150. package/dist/store/interface.d.ts +322 -0
  151. package/dist/store/interface.d.ts.map +1 -0
  152. package/dist/store/interface.js +100 -0
  153. package/dist/store/interface.js.map +1 -0
  154. package/dist/store/kit-files.d.ts +88 -0
  155. package/dist/store/kit-files.d.ts.map +1 -0
  156. package/dist/store/kit-files.js +199 -0
  157. package/dist/store/kit-files.js.map +1 -0
  158. package/dist/store/local.d.ts +70 -0
  159. package/dist/store/local.d.ts.map +1 -0
  160. package/dist/store/local.js +651 -0
  161. package/dist/store/local.js.map +1 -0
  162. package/dist/store/manifest.d.ts +44 -0
  163. package/dist/store/manifest.d.ts.map +1 -0
  164. package/dist/store/manifest.js +116 -0
  165. package/dist/store/manifest.js.map +1 -0
  166. package/dist/store/viewer-assets.d.ts +20 -0
  167. package/dist/store/viewer-assets.d.ts.map +1 -0
  168. package/dist/store/viewer-assets.js +118 -0
  169. package/dist/store/viewer-assets.js.map +1 -0
  170. package/dist/sync/anchor.d.ts +125 -0
  171. package/dist/sync/anchor.d.ts.map +1 -0
  172. package/dist/sync/anchor.js +210 -0
  173. package/dist/sync/anchor.js.map +1 -0
  174. package/dist/sync/index.d.ts +15 -0
  175. package/dist/sync/index.d.ts.map +1 -0
  176. package/dist/sync/index.js +15 -0
  177. package/dist/sync/index.js.map +1 -0
  178. package/dist/sync/orchestrator.d.ts +160 -0
  179. package/dist/sync/orchestrator.d.ts.map +1 -0
  180. package/dist/sync/orchestrator.js +288 -0
  181. package/dist/sync/orchestrator.js.map +1 -0
  182. package/dist/tools/bind_kit.d.ts +29 -0
  183. package/dist/tools/bind_kit.d.ts.map +1 -0
  184. package/dist/tools/bind_kit.js +70 -0
  185. package/dist/tools/bind_kit.js.map +1 -0
  186. package/dist/tools/conjure.d.ts +141 -0
  187. package/dist/tools/conjure.d.ts.map +1 -0
  188. package/dist/tools/conjure.js +655 -0
  189. package/dist/tools/conjure.js.map +1 -0
  190. package/dist/tools/conjure_screen.d.ts +174 -0
  191. package/dist/tools/conjure_screen.d.ts.map +1 -0
  192. package/dist/tools/conjure_screen.js +458 -0
  193. package/dist/tools/conjure_screen.js.map +1 -0
  194. package/dist/tools/create_kit.d.ts +32 -0
  195. package/dist/tools/create_kit.d.ts.map +1 -0
  196. package/dist/tools/create_kit.js +131 -0
  197. package/dist/tools/create_kit.js.map +1 -0
  198. package/dist/tools/create_project.d.ts +267 -0
  199. package/dist/tools/create_project.d.ts.map +1 -0
  200. package/dist/tools/create_project.js +546 -0
  201. package/dist/tools/create_project.js.map +1 -0
  202. package/dist/tools/delete_files.d.ts +93 -0
  203. package/dist/tools/delete_files.d.ts.map +1 -0
  204. package/dist/tools/delete_files.js +276 -0
  205. package/dist/tools/delete_files.js.map +1 -0
  206. package/dist/tools/delete_project.d.ts +43 -0
  207. package/dist/tools/delete_project.d.ts.map +1 -0
  208. package/dist/tools/delete_project.js +118 -0
  209. package/dist/tools/delete_project.js.map +1 -0
  210. package/dist/tools/get_kit.d.ts +28 -0
  211. package/dist/tools/get_kit.d.ts.map +1 -0
  212. package/dist/tools/get_kit.js +95 -0
  213. package/dist/tools/get_kit.js.map +1 -0
  214. package/dist/tools/get_project.d.ts +37 -0
  215. package/dist/tools/get_project.d.ts.map +1 -0
  216. package/dist/tools/get_project.js +71 -0
  217. package/dist/tools/get_project.js.map +1 -0
  218. package/dist/tools/list_components.d.ts +42 -0
  219. package/dist/tools/list_components.d.ts.map +1 -0
  220. package/dist/tools/list_components.js +125 -0
  221. package/dist/tools/list_components.js.map +1 -0
  222. package/dist/tools/list_files.d.ts +32 -0
  223. package/dist/tools/list_files.d.ts.map +1 -0
  224. package/dist/tools/list_files.js +109 -0
  225. package/dist/tools/list_files.js.map +1 -0
  226. package/dist/tools/list_kits.d.ts +14 -0
  227. package/dist/tools/list_kits.d.ts.map +1 -0
  228. package/dist/tools/list_kits.js +41 -0
  229. package/dist/tools/list_kits.js.map +1 -0
  230. package/dist/tools/list_projects.d.ts +23 -0
  231. package/dist/tools/list_projects.d.ts.map +1 -0
  232. package/dist/tools/list_projects.js +66 -0
  233. package/dist/tools/list_projects.js.map +1 -0
  234. package/dist/tools/plan.d.ts +16 -0
  235. package/dist/tools/plan.d.ts.map +1 -0
  236. package/dist/tools/plan.js +146 -0
  237. package/dist/tools/plan.js.map +1 -0
  238. package/dist/tools/preview.d.ts +289 -0
  239. package/dist/tools/preview.d.ts.map +1 -0
  240. package/dist/tools/preview.js +672 -0
  241. package/dist/tools/preview.js.map +1 -0
  242. package/dist/tools/read_file.d.ts +40 -0
  243. package/dist/tools/read_file.d.ts.map +1 -0
  244. package/dist/tools/read_file.js +114 -0
  245. package/dist/tools/read_file.js.map +1 -0
  246. package/dist/tools/refine.d.ts +220 -0
  247. package/dist/tools/refine.d.ts.map +1 -0
  248. package/dist/tools/refine.js +501 -0
  249. package/dist/tools/refine.js.map +1 -0
  250. package/dist/tools/validate.d.ts +74 -0
  251. package/dist/tools/validate.d.ts.map +1 -0
  252. package/dist/tools/validate.js +224 -0
  253. package/dist/tools/validate.js.map +1 -0
  254. package/dist/tools/write_files.d.ts +158 -0
  255. package/dist/tools/write_files.d.ts.map +1 -0
  256. package/dist/tools/write_files.js +541 -0
  257. package/dist/tools/write_files.js.map +1 -0
  258. package/dist/transport.d.ts +77 -0
  259. package/dist/transport.d.ts.map +1 -0
  260. package/dist/transport.js +448 -0
  261. package/dist/transport.js.map +1 -0
  262. package/dist/ui/card-asset-broker.d.ts +42 -0
  263. package/dist/ui/card-asset-broker.d.ts.map +1 -0
  264. package/dist/ui/card-asset-broker.js +479 -0
  265. package/dist/ui/card-asset-broker.js.map +1 -0
  266. package/dist/ui/grid-resource.d.ts +252 -0
  267. package/dist/ui/grid-resource.d.ts.map +1 -0
  268. package/dist/ui/grid-resource.js +680 -0
  269. package/dist/ui/grid-resource.js.map +1 -0
  270. package/dist/ui/viewer-static/index.html +95 -0
  271. package/dist/ui/viewer-static/viewer.css +451 -0
  272. package/dist/ui/viewer-static/viewer.js +1405 -0
  273. package/dist/validate/full-scan.d.ts +87 -0
  274. package/dist/validate/full-scan.d.ts.map +1 -0
  275. package/dist/validate/full-scan.js +299 -0
  276. package/dist/validate/full-scan.js.map +1 -0
  277. package/dist/validate/index.d.ts +15 -0
  278. package/dist/validate/index.d.ts.map +1 -0
  279. package/dist/validate/index.js +18 -0
  280. package/dist/validate/index.js.map +1 -0
  281. package/dist/validate/marker.d.ts +89 -0
  282. package/dist/validate/marker.d.ts.map +1 -0
  283. package/dist/validate/marker.js +87 -0
  284. package/dist/validate/marker.js.map +1 -0
  285. package/dist/validate/phash.d.ts +135 -0
  286. package/dist/validate/phash.d.ts.map +1 -0
  287. package/dist/validate/phash.js +307 -0
  288. package/dist/validate/phash.js.map +1 -0
  289. package/dist/validate/render.d.ts +38 -0
  290. package/dist/validate/render.d.ts.map +1 -0
  291. package/dist/validate/render.js +155 -0
  292. package/dist/validate/render.js.map +1 -0
  293. package/dist/watch/index.d.ts +12 -0
  294. package/dist/watch/index.d.ts.map +1 -0
  295. package/dist/watch/index.js +12 -0
  296. package/dist/watch/index.js.map +1 -0
  297. package/dist/watch/watcher.d.ts +65 -0
  298. package/dist/watch/watcher.d.ts.map +1 -0
  299. package/dist/watch/watcher.js +238 -0
  300. package/dist/watch/watcher.js.map +1 -0
  301. package/package.json +70 -0
@@ -0,0 +1,71 @@
1
+ import { z } from "zod";
2
+ import { PROJECT_ID_PATTERN, ProjectStoreError, projectScreenShape, projectSummaryShape, } from "./create_project.js";
3
+ export const GET_PROJECT_TOOL_NAME = "mcp__genie__get_project";
4
+ /** Error code raised when `projectId` does not resolve to an existing project. */
5
+ export const ERR_PROJECT_NOT_FOUND = "ERR_PROJECT_NOT_FOUND";
6
+ const projectIdSchema = z
7
+ .string()
8
+ .regex(PROJECT_ID_PATTERN, "projectId must be a 3-64 character slug containing only lowercase letters, numbers, and hyphens.");
9
+ const getProjectArgsSchema = z
10
+ .object({
11
+ projectId: projectIdSchema,
12
+ })
13
+ .strict();
14
+ /** Raw shape (not a constructed ZodObject) — matches how every other tool in this
15
+ * repo declares `outputSchema` (see get_kit.ts, delete_project.ts, list_files.ts). */
16
+ const projectDetailShape = {
17
+ ...projectSummaryShape,
18
+ screens: z.array(z.object(projectScreenShape).strict()),
19
+ sourceBlueprintId: z.string().optional(),
20
+ };
21
+ const projectDetailSchema = z.object(projectDetailShape).strict();
22
+ /**
23
+ * Validate args and fetch project detail. Exported standalone (bypassing the MCP
24
+ * transport) so programmatic/direct callers get the same validation defense-in-depth
25
+ * as `list_files`' `listFiles()` and `get_kit`'s `getKit()`.
26
+ */
27
+ export async function getProject(store, args) {
28
+ const { projectId } = getProjectArgsSchema.parse(args);
29
+ const detail = await store.getProject(projectId);
30
+ return projectDetailSchema.parse(detail);
31
+ }
32
+ export function registerGetProjectTool(server, store) {
33
+ server.registerTool(GET_PROJECT_TOOL_NAME, {
34
+ title: "Get project",
35
+ description: "Return metadata for one genie workspace or blueprint project, including its " +
36
+ "kit bindings, recorded screens, and canEdit status. Blueprints use the same " +
37
+ 'shape as workspaces (kind: "blueprint") — there is no separate tool family. ' +
38
+ "Typically follows list_projects; check kitBindings here before bind_kit or conjure_screen.",
39
+ inputSchema: {
40
+ projectId: projectIdSchema,
41
+ },
42
+ outputSchema: projectDetailShape,
43
+ }, async (args) => {
44
+ try {
45
+ const result = await getProject(store, args);
46
+ return {
47
+ content: [{ type: "text", text: JSON.stringify(result) }],
48
+ structuredContent: result,
49
+ };
50
+ }
51
+ catch (error) {
52
+ if (error instanceof ProjectStoreError) {
53
+ return {
54
+ isError: true,
55
+ content: [
56
+ {
57
+ type: "text",
58
+ text: JSON.stringify({
59
+ code: error.code,
60
+ message: error.message,
61
+ ...(error.projectId ? { projectId: error.projectId } : {}),
62
+ }),
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ throw error;
68
+ }
69
+ });
70
+ }
71
+ //# sourceMappingURL=get_project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_project.js","sourceRoot":"","sources":["../../src/tools/get_project.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE/D,kFAAkF;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAgC,CAAC;AAEtE,MAAM,eAAe,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,KAAK,CACJ,kBAAkB,EAClB,kGAAkG,CACnG,CAAC;AAEJ,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,SAAS,EAAE,eAAe;CAC3B,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ;sFACsF;AACtF,MAAM,kBAAkB,GAAG;IACzB,GAAG,mBAAmB;IACtB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;IACvD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;AAWlE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAsB,EACtB,IAAa;IAEb,MAAM,EAAE,SAAS,EAAE,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,KAAsB;IAC9E,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,8EAA8E;YAC9E,8EAA8E;YAC9E,8EAA8E;YAC9E,4FAA4F;QAC9F,WAAW,EAAE;YACX,SAAS,EAAE,eAAe;SAC3B;QACD,YAAY,EAAE,kBAAkB;KACjC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClE,iBAAiB,EAAE,MAAM;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,IAAI,EAAE,KAAK,CAAC,IAAI;gCAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gCACtB,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC3D,CAAC;yBACH;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ComponentEntry, KitStore } from "../store/interface.js";
3
+ export declare const LIST_COMPONENTS_TOOL_NAME = "mcp__genie__list_components";
4
+ /**
5
+ * Shared pagination cap (AC7): the same 256-result ceiling `list_files` and
6
+ * `list_kits` honour. A page never exceeds this many entries; the rest are
7
+ * reachable by re-calling with the returned `_meta.nextCursor`.
8
+ */
9
+ export declare const MAX_COMPONENTS = 256;
10
+ export declare const LIST_COMPONENTS_DESCRIPTION: string;
11
+ export interface ListComponentsResult {
12
+ components: ComponentEntry[];
13
+ nextCursor?: string;
14
+ }
15
+ /** Keyset cursor payload — the sort key of the last entry on the prior page. */
16
+ interface CursorKey {
17
+ g: string;
18
+ n: string;
19
+ p: string;
20
+ }
21
+ /**
22
+ * Encode a keyset cursor from the last entry of a page. The cursor carries the
23
+ * (group, name, path) sort key — NOT a numeric offset — so it stays correct
24
+ * even if the manifest gains or loses entries between calls: the next page
25
+ * resumes at the first component strictly after this key in the AC6 total
26
+ * order, rather than at a byte offset that a mutation would shift.
27
+ */
28
+ export declare function encodeCursor(entry: ComponentEntry): string;
29
+ /** Decode + validate a keyset cursor. Throws on tampered / malformed input. */
30
+ export declare function decodeCursor(cursor: string): CursorKey;
31
+ /**
32
+ * Slice one ≤256-entry page out of a deterministically-sorted component list
33
+ * (AC7). `components` MUST already be sorted by {@link compareComponents} — the
34
+ * store guarantees this. Keyset semantics: with no cursor, return the first
35
+ * page; with a cursor, return the page beginning at the first entry strictly
36
+ * greater than the cursor key. `nextCursor` is set only when more entries
37
+ * remain past the returned page.
38
+ */
39
+ export declare function paginateComponents(components: ComponentEntry[], cursor?: string): ListComponentsResult;
40
+ export declare function registerListComponents(server: McpServer, store: KitStore): void;
41
+ export {};
42
+ //# sourceMappingURL=list_components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_components.d.ts","sourceRoot":"","sources":["../../src/tools/list_components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtE,eAAO,MAAM,yBAAyB,gCAAgC,CAAC;AAEvE;;;;GAIG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,eAAO,MAAM,2BAA2B,QAQ+D,CAAC;AAYxG,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,UAAU,SAAS;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAG1D;AAaD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAoBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,cAAc,EAAE,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,oBAAoB,CActB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CA4C/E"}
@@ -0,0 +1,125 @@
1
+ import { z } from "zod";
2
+ import { compareComponents } from "../store/manifest.js";
3
+ export const LIST_COMPONENTS_TOOL_NAME = "mcp__genie__list_components";
4
+ /**
5
+ * Shared pagination cap (AC7): the same 256-result ceiling `list_files` and
6
+ * `list_kits` honour. A page never exceeds this many entries; the rest are
7
+ * reachable by re-calling with the returned `_meta.nextCursor`.
8
+ */
9
+ export const MAX_COMPONENTS = 256;
10
+ export const LIST_COMPONENTS_DESCRIPTION = "List components within a kit, optionally filtered by group. Returns an array of component metadata " +
11
+ "(name, group, path, viewport, hash, lastModified) sorted by group ASC, then name ASC, then path ASC " +
12
+ "for deterministic ordering. When group is omitted, returns every component across all groups. Returns " +
13
+ "[] when the kit has no components or the group filter matches nothing. Results are capped at 256 per " +
14
+ "call; when more remain, an opaque cursor is returned in _meta.nextCursor — pass it back as `cursor` to " +
15
+ "fetch the next page. Reads the compiled manifest, so results reflect components as of the last " +
16
+ "compile. Calling mcp__genie__preview recompiles before it returns, regardless of whether the " +
17
+ "host renders ui:// inline or opens a browser — call preview first after recent writes or deletions.";
18
+ /** Zod shape for a single component entry — reused by `outputSchema`. */
19
+ const componentEntryShape = {
20
+ name: z.string(),
21
+ group: z.string(),
22
+ path: z.string(),
23
+ viewport: z.string(),
24
+ hash: z.string(),
25
+ lastModified: z.string(),
26
+ };
27
+ /**
28
+ * Encode a keyset cursor from the last entry of a page. The cursor carries the
29
+ * (group, name, path) sort key — NOT a numeric offset — so it stays correct
30
+ * even if the manifest gains or loses entries between calls: the next page
31
+ * resumes at the first component strictly after this key in the AC6 total
32
+ * order, rather than at a byte offset that a mutation would shift.
33
+ */
34
+ export function encodeCursor(entry) {
35
+ const key = { g: entry.group, n: entry.name, p: entry.path };
36
+ return Buffer.from(JSON.stringify(key), "utf-8").toString("base64url");
37
+ }
38
+ /**
39
+ * Truncated, safe preview of an untrusted cursor for error messages. Echoing
40
+ * the full caller-supplied string would let an oversized/opaque token bloat
41
+ * logs and responses (and reflect tokens back to callers); we cap it hard and
42
+ * mark elision with an ellipsis so the message stays diagnostic but bounded.
43
+ */
44
+ const CURSOR_PREVIEW_MAX = 16;
45
+ function cursorPreview(cursor) {
46
+ return cursor.length <= CURSOR_PREVIEW_MAX ? cursor : `${cursor.slice(0, CURSOR_PREVIEW_MAX)}…`;
47
+ }
48
+ /** Decode + validate a keyset cursor. Throws on tampered / malformed input. */
49
+ export function decodeCursor(cursor) {
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(Buffer.from(cursor, "base64url").toString("utf-8"));
53
+ }
54
+ catch {
55
+ throw new Error(`Invalid cursor: "${cursorPreview(cursor)}" is not a decodable list_components cursor.`);
56
+ }
57
+ if (typeof parsed !== "object" ||
58
+ parsed === null ||
59
+ typeof parsed.g !== "string" ||
60
+ typeof parsed.n !== "string" ||
61
+ typeof parsed.p !== "string") {
62
+ throw new Error(`Invalid cursor: "${cursorPreview(cursor)}" has the wrong shape.`);
63
+ }
64
+ const { g, n, p } = parsed;
65
+ return { g, n, p };
66
+ }
67
+ /**
68
+ * Slice one ≤256-entry page out of a deterministically-sorted component list
69
+ * (AC7). `components` MUST already be sorted by {@link compareComponents} — the
70
+ * store guarantees this. Keyset semantics: with no cursor, return the first
71
+ * page; with a cursor, return the page beginning at the first entry strictly
72
+ * greater than the cursor key. `nextCursor` is set only when more entries
73
+ * remain past the returned page.
74
+ */
75
+ export function paginateComponents(components, cursor) {
76
+ let start = 0;
77
+ if (cursor !== undefined) {
78
+ const key = decodeCursor(cursor);
79
+ const sortKey = { group: key.g, name: key.n, path: key.p };
80
+ const idx = components.findIndex((c) => compareComponents(c, sortKey) > 0);
81
+ start = idx === -1 ? components.length : idx;
82
+ }
83
+ const page = components.slice(start, start + MAX_COMPONENTS);
84
+ const hasMore = start + MAX_COMPONENTS < components.length;
85
+ const nextCursor = hasMore && page.length > 0 ? encodeCursor(page[page.length - 1]) : undefined;
86
+ return nextCursor === undefined ? { components: page } : { components: page, nextCursor };
87
+ }
88
+ export function registerListComponents(server, store) {
89
+ server.registerTool(LIST_COMPONENTS_TOOL_NAME, {
90
+ title: "List components",
91
+ description: LIST_COMPONENTS_DESCRIPTION,
92
+ inputSchema: z
93
+ .object({
94
+ kitId: z
95
+ .string()
96
+ .regex(/^[a-z0-9-]{3,64}$/)
97
+ .describe("The ID of the kit to list components from"),
98
+ group: z
99
+ .string()
100
+ .min(1)
101
+ .optional()
102
+ .describe("Optional group filter. When specified, returns only components in that group. Empty string rejected."),
103
+ cursor: z
104
+ .string()
105
+ .optional()
106
+ .describe("Opaque pagination cursor from a prior call's _meta.nextCursor. Fetches the next page of results."),
107
+ })
108
+ .strict(),
109
+ outputSchema: {
110
+ components: z.array(z.object(componentEntryShape).strict()),
111
+ },
112
+ }, async ({ kitId, group, cursor }) => {
113
+ const all = await store.listComponents({ kitId, group });
114
+ const { components, nextCursor } = paginateComponents(all, cursor);
115
+ return {
116
+ content: [{ type: "text", text: JSON.stringify(components) }],
117
+ structuredContent: { components },
118
+ // AC7 — surface the continuation cursor out-of-band in _meta (only when
119
+ // the result was truncated) so the `components` payload stays a clean,
120
+ // schema-validated array.
121
+ ...(nextCursor === undefined ? {} : { _meta: { nextCursor } }),
122
+ };
123
+ });
124
+ }
125
+ //# sourceMappingURL=list_components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_components.js","sourceRoot":"","sources":["../../src/tools/list_components.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import type { KitStore } from "../store/interface.js";
4
+ export declare const LIST_FILES_TOOL_NAME = "mcp__genie__list_files";
5
+ declare const listFilesArgsSchema: z.ZodObject<{
6
+ kitId: z.ZodString;
7
+ }, z.core.$strict>;
8
+ declare const fileEntrySchema: z.ZodObject<{
9
+ path: z.ZodString;
10
+ size: z.ZodNumber;
11
+ hash: z.ZodString;
12
+ lastModified: z.ZodString;
13
+ }, z.core.$strict>;
14
+ export type ListFilesArgs = z.infer<typeof listFilesArgsSchema>;
15
+ export type ListedFile = z.infer<typeof fileEntrySchema>;
16
+ export declare class ListFilesError extends Error {
17
+ readonly code: "ERR_KIT_NOT_FOUND" | "ERR_INVALID_KIT_ID" | "ERR_INVALID_ARGS";
18
+ constructor(code: "ERR_KIT_NOT_FOUND" | "ERR_INVALID_KIT_ID" | "ERR_INVALID_ARGS", message: string);
19
+ }
20
+ /**
21
+ * List a kit's files as rich entries (path + size + SRI hash + lastModified),
22
+ * through the injected `KitStore` (M1-14a-1a / DRO-540). The store owns the
23
+ * walk, SHA-256 SRI hashing, size/mtime, and the `.genieignore` + default-dir
24
+ * exclusion — so the SAME verb runs against `LocalFsKitStore` (disk) or
25
+ * `GitHostKitStore` (git host). This function owns only arg-shape validation,
26
+ * the kitId guard, and mapping the store's `NotFoundError` onto the tool's
27
+ * `ERR_KIT_NOT_FOUND`.
28
+ */
29
+ export declare function listFiles(store: KitStore, args: ListFilesArgs): Promise<ListedFile[]>;
30
+ export declare function registerListFilesTool(server: McpServer, store: KitStore): void;
31
+ export {};
32
+ //# sourceMappingURL=list_files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_files.d.ts","sourceRoot":"","sources":["../../src/tools/list_files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItD,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAE7D,QAAA,MAAM,mBAAmB;;kBAId,CAAC;AAEZ,QAAA,MAAM,eAAe;;;;;kBAOV,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAEzD,qBAAa,cAAe,SAAQ,KAAK;IAErC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,oBAAoB,GAAG,kBAAkB;gBAArE,IAAI,EAAE,mBAAmB,GAAG,oBAAoB,GAAG,kBAAkB,EAC9E,OAAO,EAAE,MAAM;CAKlB;AAgBD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA2B3F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAuC9E"}
@@ -0,0 +1,109 @@
1
+ import { z } from "zod";
2
+ import { NotFoundError } from "../store/interface.js";
3
+ import { isSafeKitId } from "../store/kit-files.js";
4
+ export const LIST_FILES_TOOL_NAME = "mcp__genie__list_files";
5
+ const listFilesArgsSchema = z
6
+ .object({
7
+ kitId: z.string().min(1),
8
+ })
9
+ .strict();
10
+ const fileEntrySchema = z
11
+ .object({
12
+ path: z.string(),
13
+ size: z.number().int().nonnegative(),
14
+ hash: z.string().startsWith("sha256-"),
15
+ lastModified: z.string(),
16
+ })
17
+ .strict();
18
+ export class ListFilesError extends Error {
19
+ code;
20
+ constructor(code, message) {
21
+ super(message);
22
+ this.code = code;
23
+ this.name = "ListFilesError";
24
+ }
25
+ }
26
+ /**
27
+ * Reject path-shaped kit ids up front (the store also guards, but this keeps the
28
+ * tool's `ERR_INVALID_KIT_ID` contract). Delegates to the shared `isSafeKitId`
29
+ * rule (`store/kit-files.ts`) — the SAME predicate `read_file` and both stores
30
+ * use — so the two tools' kitId defenses cannot silently drift (AC1). The rule
31
+ * rejects the empty string, `.`/`..`, and any `/`/`\\` separator; ids that
32
+ * merely embed dots (`my..kit`) stay a valid single-segment child.
33
+ */
34
+ function assertValidKitId(kitId) {
35
+ if (!isSafeKitId(kitId)) {
36
+ throw new ListFilesError("ERR_INVALID_KIT_ID", `Invalid kitId "${kitId}".`);
37
+ }
38
+ }
39
+ /**
40
+ * List a kit's files as rich entries (path + size + SRI hash + lastModified),
41
+ * through the injected `KitStore` (M1-14a-1a / DRO-540). The store owns the
42
+ * walk, SHA-256 SRI hashing, size/mtime, and the `.genieignore` + default-dir
43
+ * exclusion — so the SAME verb runs against `LocalFsKitStore` (disk) or
44
+ * `GitHostKitStore` (git host). This function owns only arg-shape validation,
45
+ * the kitId guard, and mapping the store's `NotFoundError` onto the tool's
46
+ * `ERR_KIT_NOT_FOUND`.
47
+ */
48
+ export async function listFiles(store, args) {
49
+ let parsed;
50
+ try {
51
+ parsed = listFilesArgsSchema.parse(args);
52
+ }
53
+ catch (error) {
54
+ if (error instanceof z.ZodError) {
55
+ const issue = error.issues[0];
56
+ throw new ListFilesError("ERR_INVALID_ARGS", issue?.message ?? "Invalid arguments: expected { kitId: string }.");
57
+ }
58
+ throw error;
59
+ }
60
+ assertValidKitId(parsed.kitId);
61
+ let entries;
62
+ try {
63
+ entries = await store.listFiles(parsed.kitId);
64
+ }
65
+ catch (error) {
66
+ if (error instanceof NotFoundError) {
67
+ throw new ListFilesError("ERR_KIT_NOT_FOUND", `Kit "${parsed.kitId}" not found.`);
68
+ }
69
+ throw error;
70
+ }
71
+ return z.array(fileEntrySchema).parse(entries);
72
+ }
73
+ export function registerListFilesTool(server, store) {
74
+ server.registerTool(LIST_FILES_TOOL_NAME, {
75
+ title: "List files",
76
+ description: "Return the UI kit file tree with kit-root-relative paths, byte sizes, SHA-256 SRI hashes, and modification times. " +
77
+ "Reads the raw on-disk tree (unlike list_components, which reads the compiled manifest) — " +
78
+ "reach for this before read_file, or to see exactly which paths a delete_files plan needs to cover.",
79
+ inputSchema: {
80
+ kitId: z.string().min(1),
81
+ },
82
+ outputSchema: {
83
+ files: z.array(fileEntrySchema),
84
+ },
85
+ }, async (args) => {
86
+ try {
87
+ const result = await listFiles(store, args);
88
+ return {
89
+ content: [{ type: "text", text: JSON.stringify(result) }],
90
+ structuredContent: { files: result },
91
+ };
92
+ }
93
+ catch (error) {
94
+ if (error instanceof ListFilesError) {
95
+ return {
96
+ isError: true,
97
+ content: [
98
+ {
99
+ type: "text",
100
+ text: JSON.stringify({ code: error.code, message: error.message }),
101
+ },
102
+ ],
103
+ };
104
+ }
105
+ throw error;
106
+ }
107
+ });
108
+ }
109
+ //# sourceMappingURL=list_files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_files.js","sourceRoot":"","sources":["../../src/tools/list_files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { KitStore } from "../store/interface.js";
3
+ export declare const LIST_KITS_TOOL_NAME = "mcp__genie__list_kits";
4
+ export declare const LIST_KITS_DESCRIPTION = "List the user's writable UI kits. Returns every genie-native kit visible to the current store as an array of { id, name, owner, updatedAt, canEdit }. Filters out records whose stored type is not GENIE_KIT; interop adapters map Anthropic project types separately. Reach for this as the discovery step before conjure, plan, or bind_kit \u2014 each needs a valid kitId from here (or from create_kit for a brand-new kit).";
5
+ export interface ListKitsEntry extends Record<string, unknown> {
6
+ id: string;
7
+ name: string;
8
+ owner: string;
9
+ updatedAt: string;
10
+ canEdit: boolean;
11
+ }
12
+ export declare function listWritableKits(store: KitStore): Promise<ListKitsEntry[]>;
13
+ export declare function registerListKits(server: McpServer, store: KitStore): void;
14
+ //# sourceMappingURL=list_kits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_kits.d.ts","sourceRoot":"","sources":["../../src/tools/list_kits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAW,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG/D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D,eAAO,MAAM,qBAAqB,saAC8X,CAAC;AAEja,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAiBD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAWhF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAmBzE"}
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { KIT_TYPE } from "../store/interface.js";
3
+ export const LIST_KITS_TOOL_NAME = "mcp__genie__list_kits";
4
+ export const LIST_KITS_DESCRIPTION = "List the user's writable UI kits. Returns every genie-native kit visible to the current store as an array of { id, name, owner, updatedAt, canEdit }. Filters out records whose stored type is not GENIE_KIT; interop adapters map Anthropic project types separately. Reach for this as the discovery step before conjure, plan, or bind_kit — each needs a valid kitId from here (or from create_kit for a brand-new kit).";
5
+ /** Zod shape for a single `list_kits` entry — reused by `outputSchema`. */
6
+ const listKitsEntryShape = {
7
+ id: z.string(),
8
+ name: z.string(),
9
+ owner: z.string(),
10
+ updatedAt: z.string(),
11
+ canEdit: z.boolean(),
12
+ };
13
+ export async function listWritableKits(store) {
14
+ const kits = (await store.listKits());
15
+ return kits
16
+ .filter((kit) => kit.type === KIT_TYPE)
17
+ .map((kit) => ({
18
+ id: kit.id,
19
+ name: kit.name,
20
+ owner: kit.owner ?? "local",
21
+ updatedAt: kit.updatedAt ?? kit.createdAt,
22
+ canEdit: kit.canEdit ?? true,
23
+ }));
24
+ }
25
+ export function registerListKits(server, store) {
26
+ server.registerTool(LIST_KITS_TOOL_NAME, {
27
+ title: "List kits",
28
+ description: LIST_KITS_DESCRIPTION,
29
+ inputSchema: z.object({}).strict(),
30
+ outputSchema: {
31
+ kits: z.array(z.object(listKitsEntryShape).strict()),
32
+ },
33
+ }, async () => {
34
+ const kits = await listWritableKits(store);
35
+ return {
36
+ content: [{ type: "text", text: JSON.stringify(kits) }],
37
+ structuredContent: { kits },
38
+ };
39
+ });
40
+ }
41
+ //# sourceMappingURL=list_kits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_kits.js","sourceRoot":"","sources":["../../src/tools/list_kits.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D,MAAM,CAAC,MAAM,qBAAqB,GAChC,8ZAA8Z,CAAC;AAUja,2EAA2E;AAC3E,MAAM,kBAAkB,GAAG;IACzB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACrB,CAAC;AAQF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAe;IACpD,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAsB,CAAC;IAC3D,OAAO,IAAI;SACR,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC;SACtC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACb,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,OAAO;QAC3B,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS;QACzC,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;KAC7B,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,KAAe;IACjE,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,qBAAqB;QAClC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QAClC,YAAY,EAAE;YACZ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;SACrD;KACF,EACD,KAAK,IAAI,EAAE;QACT,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,iBAAiB,EAAE,EAAE,IAAI,EAAE;SAC5B,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ProjectSummary } from "./create_project.js";
3
+ export declare const LIST_PROJECTS_TOOL_NAME = "mcp__genie__list_projects";
4
+ export interface ProjectListStore {
5
+ listProjects(): Promise<ProjectSummary[]>;
6
+ }
7
+ export interface ProjectListBackend extends ProjectListStore {
8
+ name: string;
9
+ }
10
+ export interface ProjectListWarning extends Record<string, unknown> {
11
+ code: "ERR_BACKEND_UNREACHABLE";
12
+ message: string;
13
+ backend: string;
14
+ }
15
+ export interface ListProjectsResult extends Record<string, unknown> {
16
+ projects: ProjectSummary[];
17
+ }
18
+ export declare class ProjectBackendUnreachableError extends Error {
19
+ readonly code: "ERR_BACKEND_UNREACHABLE";
20
+ constructor(code: "ERR_BACKEND_UNREACHABLE", message: string);
21
+ }
22
+ export declare function registerListProjectsTool(server: McpServer, localStore: ProjectListStore, additionalBackends?: ProjectListBackend[]): void;
23
+ //# sourceMappingURL=list_projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_projects.d.ts","sourceRoot":"","sources":["../../src/tools/list_projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,YAAY,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAID,qBAAa,8BAA+B,SAAQ,KAAK;IAErD,QAAQ,CAAC,IAAI,EAAE,yBAAyB;gBAA/B,IAAI,EAAE,yBAAyB,EACxC,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,gBAAgB,EAC5B,kBAAkB,GAAE,kBAAkB,EAAO,GAC5C,IAAI,CAkCN"}
@@ -0,0 +1,66 @@
1
+ import { z } from "zod";
2
+ import { projectSummaryShape } from "./create_project.js";
3
+ export const LIST_PROJECTS_TOOL_NAME = "mcp__genie__list_projects";
4
+ const listProjectsArgsSchema = z.object({}).strict();
5
+ export class ProjectBackendUnreachableError extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = "ProjectBackendUnreachableError";
11
+ }
12
+ }
13
+ export function registerListProjectsTool(server, localStore, additionalBackends = []) {
14
+ server.registerTool(LIST_PROJECTS_TOOL_NAME, {
15
+ title: "List projects",
16
+ description: "List genie workspace and blueprint projects visible to this server. " +
17
+ "Read-only and idempotent; returns local results even if an optional git-host backend is unreachable. " +
18
+ "Reach for this as the discovery step before get_project, bind_kit, or conjure_screen.",
19
+ inputSchema: listProjectsArgsSchema,
20
+ outputSchema: {
21
+ projects: z.array(z.object(projectSummaryShape).strict()),
22
+ },
23
+ }, async (args) => {
24
+ listProjectsArgsSchema.parse(args);
25
+ const projects = [...(await localStore.listProjects())];
26
+ const warnings = [];
27
+ for (const backend of additionalBackends) {
28
+ try {
29
+ projects.push(...(await backend.listProjects()));
30
+ }
31
+ catch (error) {
32
+ warnings.push(toBackendWarning(backend.name, error));
33
+ }
34
+ }
35
+ const result = { projects: sortProjects(projects) };
36
+ return {
37
+ content: [{ type: "text", text: JSON.stringify(result) }],
38
+ structuredContent: result,
39
+ ...(warnings.length > 0 ? { _meta: { warnings } } : {}),
40
+ };
41
+ });
42
+ }
43
+ function sortProjects(projects) {
44
+ return [...projects].sort((a, b) => compareText(a.kind, b.kind) || compareText(a.name, b.name) || compareText(a.id, b.id));
45
+ }
46
+ function compareText(a, b) {
47
+ const aNorm = a.normalize("NFC").toLowerCase();
48
+ const bNorm = b.normalize("NFC").toLowerCase();
49
+ return aNorm < bNorm ? -1 : aNorm > bNorm ? 1 : a < b ? -1 : a > b ? 1 : 0;
50
+ }
51
+ function toBackendWarning(backend, error) {
52
+ if (error instanceof ProjectBackendUnreachableError) {
53
+ return {
54
+ code: error.code,
55
+ message: error.message,
56
+ backend,
57
+ };
58
+ }
59
+ const message = error instanceof Error ? error.message : String(error);
60
+ return {
61
+ code: "ERR_BACKEND_UNREACHABLE",
62
+ message: `Project backend "${backend}" unreachable; showing local projects only. ${message}`,
63
+ backend,
64
+ };
65
+ }
66
+ //# sourceMappingURL=list_projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_projects.js","sourceRoot":"","sources":["../../src/tools/list_projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAG1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAoBnE,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAErD,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IAE5C;IADX,YACW,IAA+B,EACxC,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,SAAI,GAAJ,IAAI,CAA2B;QAIxC,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,UAA4B,EAC5B,qBAA2C,EAAE;IAE7C,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,sEAAsE;YACtE,uGAAuG;YACvG,uFAAuF;QACzF,WAAW,EAAE,sBAAsB;QACnC,YAAY,EAAE;YACZ,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,MAAM,EAAE,CAAC;SAC1D;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,MAAM,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAyB,EAAE,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;YACzC,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;YACnD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAuB,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,iBAAiB,EAAE,MAAM;YACzB,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxD,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,QAA0B;IAC9C,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CACvB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAChG,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,CAAS,EAAE,CAAS;IACvC,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe,EAAE,KAAc;IACvD,IAAI,KAAK,YAAY,8BAA8B,EAAE,CAAC;QACpD,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO;SACR,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,oBAAoB,OAAO,+CAA+C,OAAO,EAAE;QAC5F,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * MCP tool: plan (M1-07).
3
+ *
4
+ * The single user-visible permission grant that locks `writes`, `deletes`,
5
+ * and `localDir`. Returns a `planId` that downstream write/delete calls must
6
+ * present. Without a valid `planId`, those verbs are rejected.
7
+ *
8
+ * Input: { kitId: string, writes: string[], deletes?: string[], localDir?: string }
9
+ * Output: { planId: string }
10
+ */
11
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
+ /**
13
+ * Register the `mcp__genie__plan` tool on the given MCP server.
14
+ */
15
+ export declare function registerPlan(server: McpServer): void;
16
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4CzE;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuHpD"}