@flowstack-ui/agent-tools 0.1.0-bootstrap.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 (239) hide show
  1. package/.codex-plugin/plugin.json +37 -0
  2. package/CHANGELOG.md +21 -0
  3. package/LICENSE +21 -0
  4. package/README.md +125 -0
  5. package/docs/architecture.md +77 -0
  6. package/docs/releasing.md +26 -0
  7. package/docs/testing.md +32 -0
  8. package/package.json +63 -0
  9. package/public/index.json +2073 -0
  10. package/public/llms.txt +19 -0
  11. package/public/packages/atom/0.24.0/components/accordion.txt +131 -0
  12. package/public/packages/atom/0.24.0/components/alert-dialog.txt +112 -0
  13. package/public/packages/atom/0.24.0/components/app-bar.txt +96 -0
  14. package/public/packages/atom/0.24.0/components/aspect-ratio.txt +111 -0
  15. package/public/packages/atom/0.24.0/components/avatar.txt +119 -0
  16. package/public/packages/atom/0.24.0/components/badge.txt +123 -0
  17. package/public/packages/atom/0.24.0/components/bottom-navigation.txt +96 -0
  18. package/public/packages/atom/0.24.0/components/breadcrumb.txt +96 -0
  19. package/public/packages/atom/0.24.0/components/button.txt +98 -0
  20. package/public/packages/atom/0.24.0/components/carousel.txt +128 -0
  21. package/public/packages/atom/0.24.0/components/checkbox-group.txt +118 -0
  22. package/public/packages/atom/0.24.0/components/checkbox.txt +100 -0
  23. package/public/packages/atom/0.24.0/components/clipboard.txt +112 -0
  24. package/public/packages/atom/0.24.0/components/collapsible.txt +112 -0
  25. package/public/packages/atom/0.24.0/components/color-picker.txt +117 -0
  26. package/public/packages/atom/0.24.0/components/combobox.txt +126 -0
  27. package/public/packages/atom/0.24.0/components/context-menu.txt +114 -0
  28. package/public/packages/atom/0.24.0/components/data-grid.txt +136 -0
  29. package/public/packages/atom/0.24.0/components/dialog.txt +116 -0
  30. package/public/packages/atom/0.24.0/components/direction.txt +132 -0
  31. package/public/packages/atom/0.24.0/components/divider.txt +94 -0
  32. package/public/packages/atom/0.24.0/components/drag-drop.txt +141 -0
  33. package/public/packages/atom/0.24.0/components/drawer.txt +96 -0
  34. package/public/packages/atom/0.24.0/components/dropdown-menu.txt +112 -0
  35. package/public/packages/atom/0.24.0/components/feed.txt +132 -0
  36. package/public/packages/atom/0.24.0/components/field.txt +108 -0
  37. package/public/packages/atom/0.24.0/components/fieldset.txt +96 -0
  38. package/public/packages/atom/0.24.0/components/file-upload.txt +120 -0
  39. package/public/packages/atom/0.24.0/components/form.txt +98 -0
  40. package/public/packages/atom/0.24.0/components/hover-card.txt +114 -0
  41. package/public/packages/atom/0.24.0/components/image.txt +94 -0
  42. package/public/packages/atom/0.24.0/components/input.txt +96 -0
  43. package/public/packages/atom/0.24.0/components/label.txt +121 -0
  44. package/public/packages/atom/0.24.0/components/link.txt +100 -0
  45. package/public/packages/atom/0.24.0/components/list.txt +131 -0
  46. package/public/packages/atom/0.24.0/components/listbox.txt +120 -0
  47. package/public/packages/atom/0.24.0/components/menu.txt +126 -0
  48. package/public/packages/atom/0.24.0/components/menubar.txt +120 -0
  49. package/public/packages/atom/0.24.0/components/modal.txt +118 -0
  50. package/public/packages/atom/0.24.0/components/multi-select.txt +120 -0
  51. package/public/packages/atom/0.24.0/components/nav-list.txt +104 -0
  52. package/public/packages/atom/0.24.0/components/navigation-menu.txt +104 -0
  53. package/public/packages/atom/0.24.0/components/number-input.txt +124 -0
  54. package/public/packages/atom/0.24.0/components/otp-field.txt +122 -0
  55. package/public/packages/atom/0.24.0/components/pagination.txt +111 -0
  56. package/public/packages/atom/0.24.0/components/password-toggle-field.txt +116 -0
  57. package/public/packages/atom/0.24.0/components/popover.txt +122 -0
  58. package/public/packages/atom/0.24.0/components/pressable.txt +94 -0
  59. package/public/packages/atom/0.24.0/components/progress.txt +130 -0
  60. package/public/packages/atom/0.24.0/components/radio-group.txt +118 -0
  61. package/public/packages/atom/0.24.0/components/rating.txt +122 -0
  62. package/public/packages/atom/0.24.0/components/reorder.txt +141 -0
  63. package/public/packages/atom/0.24.0/components/scroll-area.txt +96 -0
  64. package/public/packages/atom/0.24.0/components/select.txt +126 -0
  65. package/public/packages/atom/0.24.0/components/sidebar.txt +96 -0
  66. package/public/packages/atom/0.24.0/components/skip-link.txt +96 -0
  67. package/public/packages/atom/0.24.0/components/slider.txt +124 -0
  68. package/public/packages/atom/0.24.0/components/swipeable-item.txt +118 -0
  69. package/public/packages/atom/0.24.0/components/switch.txt +116 -0
  70. package/public/packages/atom/0.24.0/components/table.txt +128 -0
  71. package/public/packages/atom/0.24.0/components/tabs.txt +96 -0
  72. package/public/packages/atom/0.24.0/components/textarea.txt +96 -0
  73. package/public/packages/atom/0.24.0/components/toast.txt +124 -0
  74. package/public/packages/atom/0.24.0/components/toggle-group.txt +118 -0
  75. package/public/packages/atom/0.24.0/components/toggle.txt +110 -0
  76. package/public/packages/atom/0.24.0/components/toolbar.txt +98 -0
  77. package/public/packages/atom/0.24.0/components/tooltip.txt +112 -0
  78. package/public/packages/atom/0.24.0/components/tree-grid.txt +138 -0
  79. package/public/packages/atom/0.24.0/components/tree.txt +138 -0
  80. package/public/packages/atom/0.24.0/components/visually-hidden.txt +119 -0
  81. package/public/packages/atom/0.24.0/docs/guides/agent-knowledge.txt +55 -0
  82. package/public/packages/atom/0.24.0/docs/guides/getting-started.txt +65 -0
  83. package/public/packages/atom/0.24.0/docs/guides/imports.txt +26 -0
  84. package/public/packages/atom/0.24.0/docs/guides/public-api.txt +100 -0
  85. package/public/packages/atom/0.24.0/guides/behavior-composition.txt +277 -0
  86. package/public/packages/atom/0.24.0/guides/layer-selection.txt +807 -0
  87. package/public/packages/atom/0.24.0/index.txt +89 -0
  88. package/public/packages/brick/0.1.11/components/accordion.txt +158 -0
  89. package/public/packages/brick/0.1.11/components/alert-dialog.txt +175 -0
  90. package/public/packages/brick/0.1.11/components/app-bar.txt +134 -0
  91. package/public/packages/brick/0.1.11/components/appearance.txt +143 -0
  92. package/public/packages/brick/0.1.11/components/aspect-ratio.txt +136 -0
  93. package/public/packages/brick/0.1.11/components/avatar.txt +152 -0
  94. package/public/packages/brick/0.1.11/components/badge.txt +139 -0
  95. package/public/packages/brick/0.1.11/components/bleed.txt +104 -0
  96. package/public/packages/brick/0.1.11/components/bottom-navigation.txt +106 -0
  97. package/public/packages/brick/0.1.11/components/breadcrumb.txt +96 -0
  98. package/public/packages/brick/0.1.11/components/button.txt +103 -0
  99. package/public/packages/brick/0.1.11/components/card.txt +132 -0
  100. package/public/packages/brick/0.1.11/components/carousel.txt +206 -0
  101. package/public/packages/brick/0.1.11/components/checkbox-group.txt +175 -0
  102. package/public/packages/brick/0.1.11/components/checkbox.txt +103 -0
  103. package/public/packages/brick/0.1.11/components/chip.txt +128 -0
  104. package/public/packages/brick/0.1.11/components/code-block.txt +134 -0
  105. package/public/packages/brick/0.1.11/components/code.txt +120 -0
  106. package/public/packages/brick/0.1.11/components/collapsible.txt +179 -0
  107. package/public/packages/brick/0.1.11/components/color-picker.txt +135 -0
  108. package/public/packages/brick/0.1.11/components/color-swatch.txt +98 -0
  109. package/public/packages/brick/0.1.11/components/combobox.txt +157 -0
  110. package/public/packages/brick/0.1.11/components/container.txt +112 -0
  111. package/public/packages/brick/0.1.11/components/context-menu.txt +174 -0
  112. package/public/packages/brick/0.1.11/components/data-grid.txt +199 -0
  113. package/public/packages/brick/0.1.11/components/data-list.txt +115 -0
  114. package/public/packages/brick/0.1.11/components/dialog.txt +176 -0
  115. package/public/packages/brick/0.1.11/components/divider.txt +104 -0
  116. package/public/packages/brick/0.1.11/components/drawer.txt +146 -0
  117. package/public/packages/brick/0.1.11/components/dropdown-menu.txt +179 -0
  118. package/public/packages/brick/0.1.11/components/feed.txt +143 -0
  119. package/public/packages/brick/0.1.11/components/field.txt +115 -0
  120. package/public/packages/brick/0.1.11/components/fieldset.txt +103 -0
  121. package/public/packages/brick/0.1.11/components/file-upload.txt +154 -0
  122. package/public/packages/brick/0.1.11/components/form.txt +108 -0
  123. package/public/packages/brick/0.1.11/components/frame.txt +132 -0
  124. package/public/packages/brick/0.1.11/components/grid.txt +141 -0
  125. package/public/packages/brick/0.1.11/components/group.txt +136 -0
  126. package/public/packages/brick/0.1.11/components/hide.txt +121 -0
  127. package/public/packages/brick/0.1.11/components/hover-card.txt +156 -0
  128. package/public/packages/brick/0.1.11/components/icon-button.txt +119 -0
  129. package/public/packages/brick/0.1.11/components/icon.txt +160 -0
  130. package/public/packages/brick/0.1.11/components/image.txt +163 -0
  131. package/public/packages/brick/0.1.11/components/input.txt +101 -0
  132. package/public/packages/brick/0.1.11/components/link-box.txt +161 -0
  133. package/public/packages/brick/0.1.11/components/link.txt +133 -0
  134. package/public/packages/brick/0.1.11/components/list.txt +139 -0
  135. package/public/packages/brick/0.1.11/components/menubar.txt +174 -0
  136. package/public/packages/brick/0.1.11/components/multi-select.txt +153 -0
  137. package/public/packages/brick/0.1.11/components/nav-list.txt +130 -0
  138. package/public/packages/brick/0.1.11/components/navigation-menu.txt +150 -0
  139. package/public/packages/brick/0.1.11/components/notification-badge.txt +148 -0
  140. package/public/packages/brick/0.1.11/components/number-input.txt +150 -0
  141. package/public/packages/brick/0.1.11/components/otp-field.txt +146 -0
  142. package/public/packages/brick/0.1.11/components/pagination.txt +124 -0
  143. package/public/packages/brick/0.1.11/components/password-toggle-field.txt +146 -0
  144. package/public/packages/brick/0.1.11/components/popover.txt +181 -0
  145. package/public/packages/brick/0.1.11/components/progress-circle.txt +142 -0
  146. package/public/packages/brick/0.1.11/components/progress.txt +150 -0
  147. package/public/packages/brick/0.1.11/components/radio-group.txt +152 -0
  148. package/public/packages/brick/0.1.11/components/rating.txt +151 -0
  149. package/public/packages/brick/0.1.11/components/reorderable-list.txt +130 -0
  150. package/public/packages/brick/0.1.11/components/scroll-area.txt +110 -0
  151. package/public/packages/brick/0.1.11/components/section.txt +118 -0
  152. package/public/packages/brick/0.1.11/components/segment-group.txt +116 -0
  153. package/public/packages/brick/0.1.11/components/select.txt +157 -0
  154. package/public/packages/brick/0.1.11/components/show.txt +121 -0
  155. package/public/packages/brick/0.1.11/components/sidebar.txt +126 -0
  156. package/public/packages/brick/0.1.11/components/skeleton.txt +127 -0
  157. package/public/packages/brick/0.1.11/components/skip-link.txt +102 -0
  158. package/public/packages/brick/0.1.11/components/slider.txt +147 -0
  159. package/public/packages/brick/0.1.11/components/stack.txt +155 -0
  160. package/public/packages/brick/0.1.11/components/status.txt +110 -0
  161. package/public/packages/brick/0.1.11/components/surface.txt +194 -0
  162. package/public/packages/brick/0.1.11/components/swipeable-item.txt +154 -0
  163. package/public/packages/brick/0.1.11/components/switch.txt +152 -0
  164. package/public/packages/brick/0.1.11/components/table.txt +183 -0
  165. package/public/packages/brick/0.1.11/components/tabs.txt +136 -0
  166. package/public/packages/brick/0.1.11/components/text.txt +148 -0
  167. package/public/packages/brick/0.1.11/components/textarea.txt +101 -0
  168. package/public/packages/brick/0.1.11/components/toast.txt +150 -0
  169. package/public/packages/brick/0.1.11/components/toggle-group.txt +149 -0
  170. package/public/packages/brick/0.1.11/components/toggle.txt +140 -0
  171. package/public/packages/brick/0.1.11/components/toolbar.txt +118 -0
  172. package/public/packages/brick/0.1.11/components/tooltip.txt +156 -0
  173. package/public/packages/brick/0.1.11/components/tree-grid.txt +160 -0
  174. package/public/packages/brick/0.1.11/components/tree.txt +156 -0
  175. package/public/packages/brick/0.1.11/components/visually-hidden.txt +123 -0
  176. package/public/packages/brick/0.1.11/components/z-stack.txt +143 -0
  177. package/public/packages/brick/0.1.11/docs/guides/agent-knowledge.txt +67 -0
  178. package/public/packages/brick/0.1.11/docs/guides/appearance-and-tokens.txt +179 -0
  179. package/public/packages/brick/0.1.11/docs/guides/browser-support.txt +25 -0
  180. package/public/packages/brick/0.1.11/docs/guides/control-sizing.txt +59 -0
  181. package/public/packages/brick/0.1.11/docs/guides/installation.txt +79 -0
  182. package/public/packages/brick/0.1.11/docs/guides/theme-contract.txt +90 -0
  183. package/public/packages/brick/0.1.11/guides/interface-composition.txt +665 -0
  184. package/public/packages/brick/0.1.11/guides/layer-selection.txt +1437 -0
  185. package/public/packages/brick/0.1.11/index.txt +110 -0
  186. package/public/packages/colors/0.1.1/docs/agent-knowledge.txt +63 -0
  187. package/public/packages/colors/0.1.1/docs/architecture.txt +74 -0
  188. package/public/packages/colors/0.1.1/docs/color-foundations.txt +128 -0
  189. package/public/packages/colors/0.1.1/docs/compatibility.txt +75 -0
  190. package/public/packages/colors/0.1.1/docs/dependency-qualification.txt +117 -0
  191. package/public/packages/colors/0.1.1/docs/installation.txt +48 -0
  192. package/public/packages/colors/0.1.1/docs/palette-generation.txt +151 -0
  193. package/public/packages/colors/0.1.1/docs/releasing.txt +34 -0
  194. package/public/packages/colors/0.1.1/docs/testing.txt +51 -0
  195. package/public/packages/colors/0.1.1/guides/colors-system.txt +282 -0
  196. package/public/packages/colors/0.1.1/index.txt +29 -0
  197. package/public/packages/colors/0.1.1/operations/color-conversion.txt +14 -0
  198. package/public/packages/colors/0.1.1/operations/color-inspection.txt +23 -0
  199. package/public/packages/colors/0.1.1/operations/color-measurement.txt +18 -0
  200. package/public/packages/colors/0.1.1/operations/color-provenance.txt +14 -0
  201. package/public/packages/colors/0.1.1/operations/named-palette-reference.txt +15 -0
  202. package/public/packages/colors/0.1.1/operations/palette-candidate.txt +37 -0
  203. package/public/packages/theme/0.1.1/docs/agent-knowledge.txt +44 -0
  204. package/public/packages/theme/0.1.1/docs/appearances-and-portals.txt +41 -0
  205. package/public/packages/theme/0.1.1/docs/architecture.txt +121 -0
  206. package/public/packages/theme/0.1.1/docs/authoring.txt +141 -0
  207. package/public/packages/theme/0.1.1/docs/colors-interchange.txt +82 -0
  208. package/public/packages/theme/0.1.1/docs/fonts.txt +40 -0
  209. package/public/packages/theme/0.1.1/docs/installation.txt +45 -0
  210. package/public/packages/theme/0.1.1/docs/migration.txt +40 -0
  211. package/public/packages/theme/0.1.1/docs/testing.txt +64 -0
  212. package/public/packages/theme/0.1.1/docs/troubleshooting.txt +53 -0
  213. package/public/packages/theme/0.1.1/guides/theme-system.txt +340 -0
  214. package/public/packages/theme/0.1.1/index.txt +31 -0
  215. package/public/packages/theme/0.1.1/operations/brick-contract-compatibility.txt +35 -0
  216. package/public/packages/theme/0.1.1/operations/colors-interchange.txt +35 -0
  217. package/public/packages/theme/0.1.1/operations/theme-artifacts.txt +19 -0
  218. package/public/packages/theme/0.1.1/operations/theme-cli.txt +10 -0
  219. package/public/packages/theme/0.1.1/operations/theme-compilation.txt +23 -0
  220. package/public/packages/theme/0.1.1/operations/theme-definition.txt +36 -0
  221. package/public/packages/theme/0.1.1/operations/theme-validation.txt +19 -0
  222. package/public/tasks/data.txt +39 -0
  223. package/public/tasks/forms.txt +65 -0
  224. package/public/tasks/layout.txt +37 -0
  225. package/public/tasks/navigation.txt +51 -0
  226. package/public/tasks/overlays.txt +39 -0
  227. package/public/tasks/theming.txt +37 -0
  228. package/skills/flowstack-ui-builder/SKILL.md +35 -0
  229. package/skills/flowstack-ui-builder/agents/openai.yaml +4 -0
  230. package/skills/flowstack-ui-builder/scripts/resolve-agent-knowledge.mjs +399 -0
  231. package/skills/flowstack-ui-compose/SKILL.md +32 -0
  232. package/skills/flowstack-ui-compose/agents/openai.yaml +4 -0
  233. package/skills/flowstack-ui-compose/scripts/resolve-agent-knowledge.mjs +399 -0
  234. package/skills/flowstack-ui-maintainer/SKILL.md +40 -0
  235. package/skills/flowstack-ui-maintainer/agents/openai.yaml +4 -0
  236. package/skills/flowstack-ui-maintainer/scripts/resolve-agent-knowledge.mjs +399 -0
  237. package/skills/flowstack-ui-review/SKILL.md +29 -0
  238. package/skills/flowstack-ui-review/agents/openai.yaml +4 -0
  239. package/skills/flowstack-ui-review/scripts/resolve-agent-knowledge.mjs +399 -0
@@ -0,0 +1,399 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createHash } from "node:crypto";
4
+ import { access, readFile, realpath, stat } from "node:fs/promises";
5
+ import { createRequire } from "node:module";
6
+ import { dirname, join, relative, resolve, sep } from "node:path";
7
+
8
+ const allowedFlags = new Set(["agent-tools", "archive-sha256", "id", "kind", "package", "project", "version"]);
9
+ const values = new Map();
10
+ for (let index = 2; index < process.argv.length; index += 1) {
11
+ const flag = process.argv[index];
12
+ if (!flag?.startsWith("--")) fail(`invalid argument: ${flag ?? "end of command"}`);
13
+ const key = flag.slice(2);
14
+ if (!allowedFlags.has(key)) fail(`unknown flag: ${flag}`);
15
+ if (values.has(key)) fail(`duplicate flag: ${flag}`);
16
+ const value = process.argv[index + 1];
17
+ if (!value || value.startsWith("--")) fail(`missing value for ${flag}`);
18
+ values.set(key, value);
19
+ index += 1;
20
+ }
21
+
22
+ const project = resolve(values.get("project") ?? process.cwd());
23
+ const packageName = values.get("package");
24
+ const requestedVersion = values.get("version");
25
+ const requestedArchiveSha256 = values.get("archive-sha256");
26
+ const kind = values.get("kind");
27
+ const id = values.get("id");
28
+ if (!packageName) fail("--package is required");
29
+ if (!["@flowstack-ui/atom", "@flowstack-ui/brick", "@flowstack-ui/colors", "@flowstack-ui/theme"].includes(packageName)) fail(`unsupported public Agent Tools package: ${packageName}`);
30
+ if (requestedVersion && !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u.test(requestedVersion)) fail("--version must be one exact package version");
31
+ if (requestedArchiveSha256 && !/^[a-f0-9]{64}$/u.test(requestedArchiveSha256)) fail("--archive-sha256 must be one lowercase SHA-256 digest");
32
+ if ((kind && !id) || (!kind && id)) fail("--kind and --id must be supplied together");
33
+ if (kind && !["guide", "component", "operation"].includes(kind)) fail(`unsupported owner kind: ${kind}`);
34
+
35
+ const projectRequire = createRequire(join(project, "package.json"));
36
+ let installedPackagePath;
37
+ let manifestPath;
38
+ try {
39
+ manifestPath = projectRequire.resolve(`${packageName}/agents/manifest.json`);
40
+ } catch {}
41
+ try {
42
+ installedPackagePath = projectRequire.resolve(`${packageName}/package.json`);
43
+ } catch {}
44
+ if (!installedPackagePath && manifestPath) installedPackagePath = await findPackageJson(manifestPath);
45
+ if (!installedPackagePath) {
46
+ try {
47
+ installedPackagePath = await findPackageJson(projectRequire.resolve(packageName));
48
+ } catch {}
49
+ }
50
+
51
+ let installedPackage = null;
52
+ if (installedPackagePath) {
53
+ installedPackage = await readJson(installedPackagePath);
54
+ if (installedPackage.name !== packageName) fail(`installed package identity does not match ${packageName}`);
55
+ if (!requestedArchiveSha256 && requestedVersion && requestedVersion !== installedPackage.version) {
56
+ fail(`installed ${packageName}@${installedPackage.version} does not match requested ${requestedVersion}`);
57
+ }
58
+ if (manifestPath && !requestedArchiveSha256) {
59
+ const result = await resolveInstalled(installedPackage, installedPackagePath, manifestPath);
60
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
61
+ process.exit(0);
62
+ }
63
+ }
64
+
65
+ if (!installedPackage && !requestedVersion) {
66
+ fail(`--version is required when ${packageName} is not exactly installed`);
67
+ }
68
+
69
+ const toolsIndexPath = await findAgentToolsIndex();
70
+ if (toolsIndexPath) {
71
+ const result = await resolveDelivery(toolsIndexPath, installedPackage);
72
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
73
+ process.exit(0);
74
+ }
75
+
76
+ const exactVersion = requestedVersion ?? installedPackage?.version;
77
+ fail(`AGENT_KNOWLEDGE_UNAVAILABLE: no exact installed Agent Knowledge or Agent Tools route for ${packageName}@${exactVersion}`);
78
+
79
+ async function resolveInstalled(packageJson, packageJsonPath, unresolvedManifestPath) {
80
+ const packageRoot = dirname(await realpath(packageJsonPath));
81
+ const manifestPath = await containedFile(packageRoot, unresolvedManifestPath, "installed manifest");
82
+ const manifest = await readJson(manifestPath);
83
+ if (manifest.schema !== "flowstack.agent-manifest.v1") fail(`unsupported Agent Knowledge manifest schema in ${manifestPath}`);
84
+ assertIdentity(manifest, packageJson.name, packageJson.version, "manifest");
85
+ if (typeof manifest.coverage !== "string" || !manifest.coverage) fail("manifest coverage link is missing");
86
+ const coveragePath = await existingArtifact(manifestPath, manifest.coverage, "coverage");
87
+ const coverage = await readJson(coveragePath);
88
+ if (coverage.schema !== "flowstack.agent-coverage.v1") fail(`unsupported Agent Knowledge coverage schema in ${coveragePath}`);
89
+ assertIdentity(coverage, packageJson.name, packageJson.version, "coverage");
90
+ validateInstalledClosure(manifest, coverage);
91
+
92
+ const packageGuides = [];
93
+ for (const entry of manifest.guides) packageGuides.push(await installedGuide(manifest, manifestPath, entry));
94
+
95
+ return {
96
+ schema: "flowstack.agent-skill-resolution.v1",
97
+ source: "installed-package",
98
+ sourceIdentity: { kind: "installed-package", packageJsonPath, archiveSha256: null },
99
+ package: packageJson.name,
100
+ version: packageJson.version,
101
+ manifestPath,
102
+ coveragePath,
103
+ packageGuides,
104
+ selected: kind ? await installedSelection(manifest, coverage, manifestPath, packageGuides) : null,
105
+ };
106
+ }
107
+
108
+ function validateInstalledClosure(manifest, coverage) {
109
+ const summary = coverage.summary;
110
+ if (!summary || typeof summary !== "object") fail("coverage summary is missing");
111
+ requireEqualCount(summary, "publicSurfaces", "classifiedPublicSurfaces");
112
+ for (const key of ["unclassified", "invalidExclusions", "unresolvedSelections"]) requireZero(summary, key);
113
+ for (const [key, value] of Object.entries(summary)) {
114
+ if (/^(?:unclassified|invalid|unresolved)/u.test(key) && value !== 0) fail(`coverage counter ${key} must be zero`);
115
+ }
116
+ if (!Array.isArray(coverage.failures) || coverage.failures.length !== 0) fail(`coverage is not closed for ${coverage.package}@${coverage.packageVersion}`);
117
+
118
+ const guides = exactEntries(manifest.guides, "manifest guides", { nonempty: true });
119
+ const coveredGuides = coveredEntries(coverage.guides, "coverage guides");
120
+ sameIds(guides, coveredGuides, "guide");
121
+ requireCount(summary, "packageGuides", guides.length);
122
+ for (const guide of guides) {
123
+ const covered = coveredGuides.find((entry) => entry.id === guide.id);
124
+ const json = covered.manifestPaths?.json ?? covered.json;
125
+ const markdown = covered.manifestPaths?.markdown ?? covered.markdown;
126
+ if (json !== guide.json || markdown !== guide.markdown) fail(`guide ${guide.id} manifest and coverage artifacts do not match`);
127
+ }
128
+
129
+ const components = exactEntries(manifest.components ?? [], "manifest components");
130
+ const coveredComponents = coveredEntries(coverage.components, "coverage components");
131
+ sameIds(components, coveredComponents, "component");
132
+ requireEqualCount(summary, "componentOwners", "guidedComponentOwners");
133
+ requireCount(summary, "componentOwners", components.length);
134
+ const operations = exactEntries(manifest.operations ?? [], "manifest operations");
135
+ const coveredOperations = coveredEntries(coverage.operations ?? [], "coverage operations");
136
+ sameIds(operations, coveredOperations, "operation");
137
+ const items = exactEntries(manifest.registryItems ?? [], "manifest registry items");
138
+ const coveredItems = coveredEntries(coverage.registryItems ?? [], "coverage registry items");
139
+ sameIds(items, coveredItems, "registry item");
140
+ const owners = coveredEntries(coverage.owners ?? [], "coverage owners");
141
+
142
+ const profile = coverage.profile?.kind ?? ((coverage.layer === "atom" || coverage.layer === "brick") ? "component-package" : null);
143
+ if (profile === "component-package") {
144
+ if (coverage.profile && coverage.profile.ownerUnit !== "component") fail("component-package ownerUnit must be component");
145
+ if (operations.length || items.length || owners.length) fail("component package has non-component owners");
146
+ return;
147
+ }
148
+
149
+ for (const key of ["invalidRegistryItems", "unresolvedDependencies"]) requireZero(summary, key);
150
+ requireEqualCount(summary, "ownerUnits", "guidedOwnerUnits");
151
+ requireCount(summary, "ownerUnits", owners.length);
152
+
153
+ if (profile === "operation-package") {
154
+ if (coverage.profile?.ownerUnit !== "operation") fail("operation-package ownerUnit must be operation");
155
+ if (operations.length === 0) fail("manifest operations must be a nonempty array");
156
+ if (items.length) fail("operation package has registry owners");
157
+ sameIds(operations, owners, "operation owner");
158
+ requireEqualCount(summary, "operationOwners", "guidedOperationOwners");
159
+ requireCount(summary, "operationOwners", operations.length);
160
+ requireCount(summary, "registryItems", 0);
161
+ requireCount(summary, "guidedRegistryItems", 0);
162
+ for (const operation of operations) {
163
+ if (!guides.some((guide) => guide.json === operation.guide)) fail(`operation ${operation.id} has an unresolved guide`);
164
+ }
165
+ return;
166
+ }
167
+
168
+ fail(`unsupported coverage profile: ${profile ?? "missing"}`);
169
+ }
170
+
171
+ async function installedGuide(manifest, manifestPath, entry) {
172
+ const jsonPath = await existingArtifact(manifestPath, entry.json, `guide ${entry.id} JSON`);
173
+ const markdownPath = await existingArtifact(manifestPath, entry.markdown, `guide ${entry.id} Markdown`);
174
+ const machine = await readJson(jsonPath);
175
+ assertMachineArtifact(machine, { schema: "flowstack.agent-guide.v1", id: entry.id, packageName: manifest.package, kind: "guide" });
176
+ return { id: entry.id, json: jsonPath, markdown: markdownPath };
177
+ }
178
+
179
+ async function installedSelection(manifest, coverage, manifestPath, packageGuides) {
180
+ const collection = kind === "guide" ? manifest.guides : kind === "component" ? manifest.components : kind === "operation" ? manifest.operations : manifest.registryItems;
181
+ const matches = (collection ?? []).filter((candidate) => candidate.id === id);
182
+ if (matches.length !== 1) fail(`AGENT_KNOWLEDGE_UNAVAILABLE: ${manifest.package}@${manifest.packageVersion} has no unique ${kind} ${id}`);
183
+ const entry = matches[0];
184
+ if (kind === "guide") {
185
+ const guide = packageGuides.find((candidate) => candidate.id === id);
186
+ return { package: manifest.package, kind, ...guide };
187
+ }
188
+ if (kind === "operation") {
189
+ const guideEntry = manifest.guides.find((candidate) => candidate.json === entry.guide);
190
+ if (!guideEntry) fail(`operation ${id} has an unresolved guide`);
191
+ const guide = packageGuides.find((candidate) => candidate.id === guideEntry.id);
192
+ return { package: manifest.package, kind, id, guideId: guide.id, json: guide.json, markdown: guide.markdown };
193
+ }
194
+ const jsonReference = entry.json ?? entry.agentJson;
195
+ const markdownReference = entry.markdown ?? entry.agentMarkdown;
196
+ const jsonPath = await existingArtifact(manifestPath, jsonReference, `${kind} ${id} JSON`);
197
+ const markdownPath = await existingArtifact(manifestPath, markdownReference, `${kind} ${id} Markdown`);
198
+ const machine = await readJson(jsonPath);
199
+ if (kind === "component") {
200
+ assertMachineArtifact(machine, { schema: "flowstack.agent-component.v1", id, packageName: manifest.package, kind });
201
+ } else if (machine.$schema !== "flowstack.block-agent.v1" || machine.id !== id) {
202
+ fail(`selected block artifact identity does not match ${manifest.package} ${id}`);
203
+ }
204
+ return { package: manifest.package, kind, id, json: jsonPath, markdown: markdownPath };
205
+ }
206
+
207
+ async function resolveDelivery(unresolvedIndexPath, installedPackage) {
208
+ const indexPath = await containedFile(dirname(unresolvedIndexPath), unresolvedIndexPath, "Agent Tools index");
209
+ const index = await readJson(indexPath);
210
+ if (index.schema !== "flowstack.agent-delivery-index.v1") fail(`unsupported Agent Tools index schema in ${indexPath}`);
211
+ const exactVersion = requestedVersion ?? installedPackage?.version;
212
+ if (!exactVersion) fail(`--version is required when ${packageName} is not exactly installed`);
213
+ const records = index.packages.filter((entry) => entry.name === packageName && entry.version === exactVersion);
214
+ if (records.length !== 1) fail(`AGENT_KNOWLEDGE_UNAVAILABLE: Agent Tools has no unique exact route for ${packageName}@${exactVersion}`);
215
+ const record = records[0];
216
+ validateDeliveryRecord(record);
217
+
218
+ const routes = index.routes.filter((route) => route.package === record.id && route.version === record.version);
219
+ const keys = new Set();
220
+ const paths = new Set();
221
+ for (const route of routes) {
222
+ const key = `${route.kind}:${route.id}`;
223
+ if (keys.has(key) || paths.has(route.path)) fail(`Agent Tools has duplicate routes for ${packageName}@${record.version}`);
224
+ keys.add(key);
225
+ paths.add(route.path);
226
+ }
227
+ const expectedCounts = { guide: record.counts.guides, component: record.counts.components, operation: record.counts.operations, package: 1 };
228
+ for (const [routeKind, count] of Object.entries(expectedCounts)) {
229
+ if (routes.filter((route) => route.kind === routeKind).length !== count) fail(`Agent Tools ${routeKind} route count does not match ${packageName}@${record.version}`);
230
+ }
231
+
232
+ const publicRoot = dirname(indexPath);
233
+ const packageRoute = routes.find((route) => route.kind === "package" && route.path === record.route);
234
+ if (!packageRoute) fail(`AGENT_KNOWLEDGE_UNAVAILABLE: Agent Tools package route is missing for ${packageName}@${record.version}`);
235
+ const guideRoutes = routes.filter((route) => route.kind === "guide");
236
+ if (guideRoutes.length === 0) fail(`Agent Tools has no mandatory package guides for ${packageName}@${record.version}`);
237
+ const packageGuides = [];
238
+ for (const route of guideRoutes) packageGuides.push(await deliveryArtifact(publicRoot, route, record));
239
+
240
+ let selected = null;
241
+ if (kind) {
242
+ const matches = routes.filter((candidate) => candidate.kind === kind && candidate.id === id);
243
+ if (matches.length !== 1) fail(`AGENT_KNOWLEDGE_UNAVAILABLE: Agent Tools has no unique ${kind} ${id} for ${packageName}@${record.version}`);
244
+ selected = await deliveryArtifact(publicRoot, matches[0], record);
245
+ }
246
+ return {
247
+ schema: "flowstack.agent-skill-resolution.v1",
248
+ source: "agent-tools-route",
249
+ sourceIdentity: { kind: "locked-archive", archiveSha256: record.archiveSha256 },
250
+ package: packageName,
251
+ version: record.version,
252
+ indexPath,
253
+ packageRoute: await deliveryArtifact(publicRoot, packageRoute, record, { identity: false }),
254
+ packageGuides,
255
+ selected,
256
+ };
257
+ }
258
+
259
+ function validateDeliveryRecord(record) {
260
+ if (!/^[a-f0-9]{64}$/u.test(record.archiveSha256 ?? "")) fail(`Agent Tools archive digest is invalid for ${packageName}@${record.version}`);
261
+ if (requestedArchiveSha256 && record.archiveSha256 !== requestedArchiveSha256) {
262
+ fail(`AGENT_KNOWLEDGE_UNAVAILABLE: archive digest does not match ${packageName}@${record.version}`);
263
+ }
264
+ const coverage = record.coverage;
265
+ if (!coverage || coverage.failures !== 0 || coverage.publicSurfaces !== coverage.classifiedPublicSurfaces) {
266
+ fail(`AGENT_KNOWLEDGE_UNAVAILABLE: Agent Tools coverage is not closed for ${packageName}@${record.version}`);
267
+ }
268
+ if (!record.counts || !Number.isInteger(record.counts.guides) || record.counts.guides <= 0) fail(`Agent Tools guide count is invalid for ${packageName}@${record.version}`);
269
+ for (const key of ["components", "operations"]) if (!Number.isInteger(record.counts[key]) || record.counts[key] < 0) fail(`Agent Tools ${key} count is invalid`);
270
+ const profile = record.profile;
271
+ if (profile?.kind === "component-package" && profile.ownerUnit === "component") {
272
+ if (record.counts.components <= 0 || record.counts.operations !== 0) fail("Agent Tools component profile counts are inconsistent");
273
+ } else if (profile?.kind === "operation-package" && profile.ownerUnit === "operation") {
274
+ if (record.counts.operations <= 0 || record.counts.components !== 0) fail("Agent Tools operation profile counts are inconsistent");
275
+ } else {
276
+ fail(`unsupported Agent Tools coverage profile for ${packageName}@${record.version}`);
277
+ }
278
+ }
279
+
280
+ async function deliveryArtifact(publicRoot, route, record, { identity = true } = {}) {
281
+ const lexicalPath = resolve(publicRoot, route.path.replace(/^\//u, ""));
282
+ const path = await containedFile(publicRoot, lexicalPath, `Agent Tools route ${route.path}`);
283
+ const content = await readFile(path);
284
+ const digest = createHash("sha256").update(content).digest("hex");
285
+ if (!Number.isInteger(route.bytes) || content.length !== route.bytes || !/^[a-f0-9]{64}$/u.test(route.sha256) || digest !== route.sha256) {
286
+ fail(`AGENT_KNOWLEDGE_UNAVAILABLE: Agent Tools route integrity failed for ${route.path}`);
287
+ }
288
+ if (identity) {
289
+ const text = content.toString("utf8");
290
+ if (!text.includes(`\nSource: ${record.name}@${record.version}\n`) || !text.includes(`\nKind: ${route.kind}\n`) || !text.includes(`\nID: ${route.id}\n`)) {
291
+ fail(`Agent Tools route identity does not match ${record.name} ${route.kind} ${route.id}`);
292
+ }
293
+ }
294
+ return { package: record.name, kind: route.kind, id: route.id, route: route.path, path };
295
+ }
296
+
297
+ async function findAgentToolsIndex() {
298
+ const supplied = values.get("agent-tools");
299
+ if (supplied) {
300
+ const target = resolve(supplied);
301
+ const info = await stat(target).catch(() => null);
302
+ if (!info) return null;
303
+ if (!info.isDirectory()) return target;
304
+ for (const candidate of [join(target, "public", "index.json"), join(target, "index.json")]) {
305
+ if (await access(candidate).then(() => true).catch(() => false)) return candidate;
306
+ }
307
+ return null;
308
+ }
309
+ try {
310
+ return projectRequire.resolve("@flowstack-ui/agent-tools/index.json");
311
+ } catch {
312
+ return null;
313
+ }
314
+ }
315
+
316
+ async function existingArtifact(manifestPath, artifact, label) {
317
+ if (typeof artifact !== "string" || !artifact) fail(`${label} path is missing`);
318
+ const base = dirname(manifestPath);
319
+ const path = resolve(base, artifact);
320
+ const relativePath = relative(base, path);
321
+ if (relativePath === ".." || relativePath.startsWith(`..${sep}`)) fail(`escaping manifest artifact: ${artifact}`);
322
+ return containedFile(base, path, label);
323
+ }
324
+
325
+ async function containedFile(root, path, label) {
326
+ const rootPath = await realpath(root);
327
+ const filePath = await realpath(path).catch(() => null);
328
+ if (!filePath) fail(`${label} is missing`);
329
+ const relativePath = relative(rootPath, filePath);
330
+ if (relativePath === ".." || relativePath.startsWith(`..${sep}`)) fail(`${label} escapes its authority root`);
331
+ const info = await stat(filePath);
332
+ if (!info.isFile()) fail(`${label} is not a file`);
333
+ return filePath;
334
+ }
335
+
336
+ function assertMachineArtifact(machine, expected) {
337
+ if (machine.schema !== expected.schema || machine.id !== expected.id || machine.package !== expected.packageName || machine.kind !== expected.kind) {
338
+ fail(`selected artifact identity does not match ${expected.packageName} ${expected.kind} ${expected.id}`);
339
+ }
340
+ }
341
+
342
+ function assertIdentity(value, name, version, label) {
343
+ if (value.package !== name || value.packageVersion !== version) fail(`${label} identity does not match installed ${name}@${version}`);
344
+ }
345
+
346
+ function exactEntries(entries, label, { nonempty = false } = {}) {
347
+ if (!Array.isArray(entries) || (nonempty && entries.length === 0)) fail(`${label} must be ${nonempty ? "a nonempty" : "an"} array`);
348
+ const ids = new Set();
349
+ for (const entry of entries) {
350
+ if (!entry || typeof entry.id !== "string" || !entry.id || ids.has(entry.id)) fail(`${label} has a missing or duplicate id`);
351
+ ids.add(entry.id);
352
+ }
353
+ return entries;
354
+ }
355
+
356
+ function coveredEntries(entries, label) {
357
+ const result = exactEntries(entries, label);
358
+ if (result.some((entry) => entry.status !== "covered")) fail(`${label} contains an uncovered owner`);
359
+ return result;
360
+ }
361
+
362
+ function sameIds(left, right, label) {
363
+ const leftIds = left.map(({ id }) => id).sort();
364
+ const rightIds = right.map(({ id }) => id).sort();
365
+ if (JSON.stringify(leftIds) !== JSON.stringify(rightIds)) fail(`${label} manifest and coverage ids do not match`);
366
+ }
367
+
368
+ function requireCount(summary, key, expected) {
369
+ if (!Number.isInteger(summary[key]) || summary[key] !== expected) fail(`coverage counter ${key} must equal ${expected}`);
370
+ }
371
+
372
+ function requireEqualCount(summary, left, right) {
373
+ if (!Number.isInteger(summary[left]) || !Number.isInteger(summary[right]) || summary[left] !== summary[right]) fail(`coverage counters ${left} and ${right} must match`);
374
+ }
375
+
376
+ function requireZero(summary, key) {
377
+ requireCount(summary, key, 0);
378
+ }
379
+
380
+ async function readJson(path) {
381
+ return JSON.parse(await readFile(path, "utf8"));
382
+ }
383
+
384
+ async function findPackageJson(start) {
385
+ let directory = dirname(start);
386
+ while (true) {
387
+ const candidate = join(directory, "package.json");
388
+ const json = await readJson(candidate).catch(() => null);
389
+ if (json?.name === packageName) return candidate;
390
+ const parent = dirname(directory);
391
+ if (parent === directory) return null;
392
+ directory = parent;
393
+ }
394
+ }
395
+
396
+ function fail(message) {
397
+ process.stderr.write(`${message}\n`);
398
+ process.exit(1);
399
+ }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: flowstack-ui-compose
3
+ description: Map a supplied Blueprint or explicit application plan through finished Brick components using exact-version guidance. Use after product and creative decisions exist; do not use to invent those decisions.
4
+ ---
5
+
6
+ # FLOWSTACK UI Compose
7
+
8
+ Turn an explicit plan into public implementation ownership without becoming a Blueprint or product-policy engine.
9
+
10
+ ## Require a plan
11
+
12
+ Start from a supplied Blueprint or an application plan that identifies the jobs, content/route intent, and relevant state or policy decisions. If those inputs are missing, ask for them or report the handoff gap. Do not invent product strategy, information architecture, business rules, persistence, analytics, art direction, private catalog ranking, or premium Blueprint content.
13
+
14
+ ## Resolve exact public guidance
15
+
16
+ Inspect the target dependencies and lockfile. Run `scripts/resolve-agent-knowledge.mjs` for Brick and every other selected public package or owner. Pass an exact `--version` whenever that package is not installed; ranges and implicit locked-version selection are rejected. Read the resolved manifest, zero-failure coverage, package guides, and selected artifacts. Use installed artifacts or an exact matching Agent Tools locked route only. Stop and report an unavailable version rather than substituting latest, current-main, or remembered guidance.
17
+
18
+ ## Map the composition
19
+
20
+ 1. Keep application-owned content, routes, business state, services, persistence, and analytics attached to the supplied plan.
21
+ 2. Resolve every interface job through Brick's layer-selection and composition guides, then read every selected Brick component guide.
22
+ 3. Use Atom directly only for an explicitly headless plan. A Brick guide may route to exact Atom behavior guidance, but finished application imports remain Brick-first.
23
+ 4. For custom colors, preserve the order Colors review -> Theme definition/compilation -> compatible Theme artifacts -> Brick. Load Brick CSS and Theme artifacts as documented.
24
+ 5. If the supplied plan includes an authorized paid Block already copied by the authenticated CLI, treat that code as application-owned and resolve its public Brick owners. Do not search for, infer, or reproduce paid registry metadata or source through Agent Tools.
25
+
26
+ Compose outside-in while preserving the supplied responsive and state handoffs. Use supported recipes, semantic tokens, public parts, and application-owned semantic HTML only where exact guides assign them.
27
+
28
+ ## Verify and hand off gaps
29
+
30
+ Validate copied Block provenance, component anatomy, accessibility/interaction, responsive containment, CSS and Theme loading, appearance modes, types, focused tests, browser behavior, and production build.
31
+
32
+ For every unresolved job, record package/version, plan job, components searched, missing capability, temporary fallback, proposed owner (`Brick`, `Atom`, `Colors`, `Theme`, `Block`, `Blueprint`, or `application`), and required evidence. Return policy or creative gaps to the plan owner without exposing or fabricating private rules.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "FLOWSTACK UI Compose"
3
+ short_description: "Compose plans through Brick"
4
+ default_prompt: "Use $flowstack-ui-compose to map this supplied plan through exact FLOWSTACK Brick guidance."