@tyroneross/build-loop 0.30.3

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 (389) hide show
  1. package/.agents/plugins/marketplace.json +10 -0
  2. package/.claude-plugin/marketplace.json +38 -0
  3. package/.claude-plugin/plugin.json +30 -0
  4. package/.codex-plugin/plugin.json +41 -0
  5. package/.cursor/rules/build-loop-surface.mdc +22 -0
  6. package/AGENTS.md +498 -0
  7. package/LICENSE +202 -0
  8. package/README.md +403 -0
  9. package/agents/alignment-checker.md +124 -0
  10. package/agents/api-assessor.md +136 -0
  11. package/agents/architecture-scout.md +185 -0
  12. package/agents/assessment-orchestrator.md +163 -0
  13. package/agents/build-orchestrator.md +198 -0
  14. package/agents/database-assessor.md +133 -0
  15. package/agents/design-contract-specialist.md +239 -0
  16. package/agents/fact-checker.md +69 -0
  17. package/agents/fix-critique.md +161 -0
  18. package/agents/frontend-assessor.md +136 -0
  19. package/agents/implementer.md +185 -0
  20. package/agents/independent-auditor.md +143 -0
  21. package/agents/mock-scanner.md +78 -0
  22. package/agents/optimize-runner.md +112 -0
  23. package/agents/overfitting-reviewer.md +96 -0
  24. package/agents/performance-assessor.md +159 -0
  25. package/agents/plan-critic.md +85 -0
  26. package/agents/promotion-reviewer.md +121 -0
  27. package/agents/recurring-pattern-detector.md +248 -0
  28. package/agents/retrospective-synthesizer.md +109 -0
  29. package/agents/root-cause-investigator.md +285 -0
  30. package/agents/scope-auditor.md +121 -0
  31. package/agents/security-reviewer.md +151 -0
  32. package/agents/self-improvement-architect.md +125 -0
  33. package/agents/synthesis-critic.md +99 -0
  34. package/agents/transcript-pattern-miner.md +165 -0
  35. package/agents/ui-validator.md +193 -0
  36. package/codex-skills/build-loop/SKILL.md +20 -0
  37. package/codex-skills/debug-loop/SKILL.md +18 -0
  38. package/codex-skills/handoff/SKILL.md +22 -0
  39. package/codex-skills/knowledge/SKILL.md +21 -0
  40. package/codex-skills/optimize/SKILL.md +18 -0
  41. package/codex-skills/research/SKILL.md +18 -0
  42. package/commands/agent-rally-point.md +301 -0
  43. package/commands/assess.md +41 -0
  44. package/commands/debug.md +20 -0
  45. package/commands/debugger-detail.md +34 -0
  46. package/commands/debugger-scan.md +15 -0
  47. package/commands/debugger-status.md +20 -0
  48. package/commands/debugger.md +32 -0
  49. package/commands/handoff.md +113 -0
  50. package/commands/knowledge-review.md +16 -0
  51. package/commands/optimize.md +31 -0
  52. package/commands/plan-verify.md +39 -0
  53. package/commands/promote-experiment.md +129 -0
  54. package/commands/research.md +22 -0
  55. package/commands/run.md +12 -0
  56. package/commands/self-review.md +51 -0
  57. package/commands/start-prd.md +57 -0
  58. package/commands/test.md +34 -0
  59. package/dist/src/assessment-orchestrator.d.ts +78 -0
  60. package/dist/src/assessment-orchestrator.d.ts.map +1 -0
  61. package/dist/src/assessment-orchestrator.js +304 -0
  62. package/dist/src/assessment-orchestrator.js.map +1 -0
  63. package/dist/src/audit-miner.d.ts +21 -0
  64. package/dist/src/audit-miner.d.ts.map +1 -0
  65. package/dist/src/audit-miner.js +421 -0
  66. package/dist/src/audit-miner.js.map +1 -0
  67. package/dist/src/batch-operations.d.ts +30 -0
  68. package/dist/src/batch-operations.d.ts.map +1 -0
  69. package/dist/src/batch-operations.js +339 -0
  70. package/dist/src/batch-operations.js.map +1 -0
  71. package/dist/src/config.d.ts +83 -0
  72. package/dist/src/config.d.ts.map +1 -0
  73. package/dist/src/config.js +176 -0
  74. package/dist/src/config.js.map +1 -0
  75. package/dist/src/context-engine.d.ts +45 -0
  76. package/dist/src/context-engine.d.ts.map +1 -0
  77. package/dist/src/context-engine.js +135 -0
  78. package/dist/src/context-engine.js.map +1 -0
  79. package/dist/src/debug-wrapper.d.ts +58 -0
  80. package/dist/src/debug-wrapper.d.ts.map +1 -0
  81. package/dist/src/debug-wrapper.js +285 -0
  82. package/dist/src/debug-wrapper.js.map +1 -0
  83. package/dist/src/index.d.ts +31 -0
  84. package/dist/src/index.d.ts.map +1 -0
  85. package/dist/src/index.js +149 -0
  86. package/dist/src/index.js.map +1 -0
  87. package/dist/src/interactive-verifier.d.ts +26 -0
  88. package/dist/src/interactive-verifier.d.ts.map +1 -0
  89. package/dist/src/interactive-verifier.js +435 -0
  90. package/dist/src/interactive-verifier.js.map +1 -0
  91. package/dist/src/lessons.d.ts +59 -0
  92. package/dist/src/lessons.d.ts.map +1 -0
  93. package/dist/src/lessons.js +172 -0
  94. package/dist/src/lessons.js.map +1 -0
  95. package/dist/src/log-reader.d.ts +39 -0
  96. package/dist/src/log-reader.d.ts.map +1 -0
  97. package/dist/src/log-reader.js +291 -0
  98. package/dist/src/log-reader.js.map +1 -0
  99. package/dist/src/logger.d.ts +59 -0
  100. package/dist/src/logger.d.ts.map +1 -0
  101. package/dist/src/logger.js +328 -0
  102. package/dist/src/logger.js.map +1 -0
  103. package/dist/src/parallel-retrieval.d.ts +52 -0
  104. package/dist/src/parallel-retrieval.d.ts.map +1 -0
  105. package/dist/src/parallel-retrieval.js +309 -0
  106. package/dist/src/parallel-retrieval.js.map +1 -0
  107. package/dist/src/pattern-extractor.d.ts +30 -0
  108. package/dist/src/pattern-extractor.d.ts.map +1 -0
  109. package/dist/src/pattern-extractor.js +386 -0
  110. package/dist/src/pattern-extractor.js.map +1 -0
  111. package/dist/src/result-aggregator.d.ts +44 -0
  112. package/dist/src/result-aggregator.d.ts.map +1 -0
  113. package/dist/src/result-aggregator.js +315 -0
  114. package/dist/src/result-aggregator.js.map +1 -0
  115. package/dist/src/retrieval.d.ts +139 -0
  116. package/dist/src/retrieval.d.ts.map +1 -0
  117. package/dist/src/retrieval.js +724 -0
  118. package/dist/src/retrieval.js.map +1 -0
  119. package/dist/src/setup/auto-setup.d.ts +15 -0
  120. package/dist/src/setup/auto-setup.d.ts.map +1 -0
  121. package/dist/src/setup/auto-setup.js +157 -0
  122. package/dist/src/setup/auto-setup.js.map +1 -0
  123. package/dist/src/setup/configure-hooks.d.ts +8 -0
  124. package/dist/src/setup/configure-hooks.d.ts.map +1 -0
  125. package/dist/src/setup/configure-hooks.js +16 -0
  126. package/dist/src/setup/configure-hooks.js.map +1 -0
  127. package/dist/src/setup/create-slash-commands.d.ts +8 -0
  128. package/dist/src/setup/create-slash-commands.d.ts.map +1 -0
  129. package/dist/src/setup/create-slash-commands.js +101 -0
  130. package/dist/src/setup/create-slash-commands.js.map +1 -0
  131. package/dist/src/setup/index.d.ts +8 -0
  132. package/dist/src/setup/index.d.ts.map +1 -0
  133. package/dist/src/setup/index.js +17 -0
  134. package/dist/src/setup/index.js.map +1 -0
  135. package/dist/src/setup/inject-claude-md.d.ts +10 -0
  136. package/dist/src/setup/inject-claude-md.d.ts.map +1 -0
  137. package/dist/src/setup/inject-claude-md.js +150 -0
  138. package/dist/src/setup/inject-claude-md.js.map +1 -0
  139. package/dist/src/setup/uninstall.d.ts +22 -0
  140. package/dist/src/setup/uninstall.d.ts.map +1 -0
  141. package/dist/src/setup/uninstall.js +235 -0
  142. package/dist/src/setup/uninstall.js.map +1 -0
  143. package/dist/src/storage.d.ts +192 -0
  144. package/dist/src/storage.d.ts.map +1 -0
  145. package/dist/src/storage.js +1037 -0
  146. package/dist/src/storage.js.map +1 -0
  147. package/dist/src/string-similarity.d.ts +8 -0
  148. package/dist/src/string-similarity.d.ts.map +1 -0
  149. package/dist/src/string-similarity.js +57 -0
  150. package/dist/src/string-similarity.js.map +1 -0
  151. package/dist/src/traces/adapters/browser.d.ts +69 -0
  152. package/dist/src/traces/adapters/browser.d.ts.map +1 -0
  153. package/dist/src/traces/adapters/browser.js +280 -0
  154. package/dist/src/traces/adapters/browser.js.map +1 -0
  155. package/dist/src/traces/adapters/index.d.ts +23 -0
  156. package/dist/src/traces/adapters/index.d.ts.map +1 -0
  157. package/dist/src/traces/adapters/index.js +67 -0
  158. package/dist/src/traces/adapters/index.js.map +1 -0
  159. package/dist/src/traces/adapters/langchain.d.ts +42 -0
  160. package/dist/src/traces/adapters/langchain.d.ts.map +1 -0
  161. package/dist/src/traces/adapters/langchain.js +151 -0
  162. package/dist/src/traces/adapters/langchain.js.map +1 -0
  163. package/dist/src/traces/adapters/opentelemetry.d.ts +46 -0
  164. package/dist/src/traces/adapters/opentelemetry.d.ts.map +1 -0
  165. package/dist/src/traces/adapters/opentelemetry.js +164 -0
  166. package/dist/src/traces/adapters/opentelemetry.js.map +1 -0
  167. package/dist/src/traces/adapters/sentry.d.ts +58 -0
  168. package/dist/src/traces/adapters/sentry.d.ts.map +1 -0
  169. package/dist/src/traces/adapters/sentry.js +212 -0
  170. package/dist/src/traces/adapters/sentry.js.map +1 -0
  171. package/dist/src/traces/index.d.ts +10 -0
  172. package/dist/src/traces/index.d.ts.map +1 -0
  173. package/dist/src/traces/index.js +45 -0
  174. package/dist/src/traces/index.js.map +1 -0
  175. package/dist/src/traces/storage.d.ts +78 -0
  176. package/dist/src/traces/storage.d.ts.map +1 -0
  177. package/dist/src/traces/storage.js +399 -0
  178. package/dist/src/traces/storage.js.map +1 -0
  179. package/dist/src/traces/summarizer.d.ts +83 -0
  180. package/dist/src/traces/summarizer.d.ts.map +1 -0
  181. package/dist/src/traces/summarizer.js +247 -0
  182. package/dist/src/traces/summarizer.js.map +1 -0
  183. package/dist/src/traces/types.d.ts +365 -0
  184. package/dist/src/traces/types.d.ts.map +1 -0
  185. package/dist/src/traces/types.js +14 -0
  186. package/dist/src/traces/types.js.map +1 -0
  187. package/dist/src/types.d.ts +495 -0
  188. package/dist/src/types.d.ts.map +1 -0
  189. package/dist/src/types.js +27 -0
  190. package/dist/src/types.js.map +1 -0
  191. package/docs/agent-surface-policy.md +45 -0
  192. package/docs/memory-setup.md +226 -0
  193. package/hooks/_arch_scan_bg.py +88 -0
  194. package/hooks/_plugin_drift_check_bg.py +85 -0
  195. package/hooks/_session_start_lib.sh +42 -0
  196. package/hooks/git/pre-push +141 -0
  197. package/hooks/hooks.json +126 -0
  198. package/hooks/post-commit +30 -0
  199. package/hooks/pre-commit +29 -0
  200. package/hooks/pre-edit-apppulse.sh +6 -0
  201. package/hooks/pre-edit-architecture.sh +106 -0
  202. package/hooks/pre-edit-rally-point.sh +92 -0
  203. package/hooks/session-start-apppulse.sh +6 -0
  204. package/hooks/session-start-architecture.sh +10 -0
  205. package/hooks/session-start-git-hooks.sh +12 -0
  206. package/hooks/session-start-plugin-drift.sh +27 -0
  207. package/hooks/session-start-rally-point.sh +44 -0
  208. package/hooks/session-start-retrieval.sh +24 -0
  209. package/hooks/session-start-worktree-gc.sh +105 -0
  210. package/hooks/test_apppulse_hooks.sh +6 -0
  211. package/hooks/test_rally_point_hooks.sh +388 -0
  212. package/hooks/test_sec008_hooks.sh +66 -0
  213. package/package.json +111 -0
  214. package/scripts/README.md +301 -0
  215. package/scripts/_db_url.py +61 -0
  216. package/scripts/_paths.py +445 -0
  217. package/scripts/blm.py +162 -0
  218. package/scripts/blm_api.py +263 -0
  219. package/scripts/check_cache_sync.py +490 -0
  220. package/scripts/embed_backend.py +475 -0
  221. package/scripts/install_memory.py +556 -0
  222. package/scripts/lessons_index/__init__.py +77 -0
  223. package/scripts/lessons_index/__main__.py +135 -0
  224. package/scripts/lessons_index/ingest.py +288 -0
  225. package/scripts/lessons_index/query.py +285 -0
  226. package/scripts/lessons_index/schema.py +114 -0
  227. package/scripts/memory_context/__init__.py +610 -0
  228. package/scripts/memory_graph/__init__.py +393 -0
  229. package/scripts/project_resolver.py +172 -0
  230. package/scripts/prune_codex_plugin_cache.py +23 -0
  231. package/scripts/prune_plugin_cache.py +359 -0
  232. package/scripts/semantic_index/__init__.py +482 -0
  233. package/scripts/semantic_index/_bench_hybrid.py +175 -0
  234. package/scripts/semantic_index/backfill.py +263 -0
  235. package/scripts/semantic_index/hybrid.py +174 -0
  236. package/scripts/semantic_index/test_backfill.py +292 -0
  237. package/scripts/semantic_index/test_hybrid.py +541 -0
  238. package/scripts/sync_navgator_lessons.py +666 -0
  239. package/scripts/sync_plugin_cache.py +388 -0
  240. package/skills/agent-rally-point/SKILL.md +165 -0
  241. package/skills/agent-rally-watcher/SKILL.md +83 -0
  242. package/skills/api-registry-bridge/SKILL.md +59 -0
  243. package/skills/architecture/dead/SKILL.md +56 -0
  244. package/skills/architecture/impact/SKILL.md +88 -0
  245. package/skills/architecture/review/SKILL.md +227 -0
  246. package/skills/architecture/rules/SKILL.md +72 -0
  247. package/skills/architecture/scan/SKILL.md +79 -0
  248. package/skills/architecture/trace/SKILL.md +65 -0
  249. package/skills/attribution-standard/SKILL.md +122 -0
  250. package/skills/authentication/SKILL.md +81 -0
  251. package/skills/authentication/references/better-auth-magic-link.md +135 -0
  252. package/skills/authentication/references/better-auth-setup.md +224 -0
  253. package/skills/authentication/references/google-calendar-sync.md +278 -0
  254. package/skills/authentication/references/google-cloud-console.md +159 -0
  255. package/skills/authentication/references/google-geocoding-directions.md +126 -0
  256. package/skills/authentication/references/google-lessons-example-web-app.md +177 -0
  257. package/skills/authentication/references/google-maps.md +162 -0
  258. package/skills/authentication/references/google-oauth-setup.md +343 -0
  259. package/skills/authentication/references/google-places.md +173 -0
  260. package/skills/authentication/references/lessons-example-web-app-better-auth.md +126 -0
  261. package/skills/authentication/references/resend-email.md +227 -0
  262. package/skills/authentication/references/resend-otp-magic-link.md +153 -0
  263. package/skills/authentication/references/supabase-auth.md +172 -0
  264. package/skills/auto-decision-capture/SKILL.md +419 -0
  265. package/skills/build-loop/SKILL.md +516 -0
  266. package/skills/build-loop/detect-plugins.mjs +82 -0
  267. package/skills/build-loop/eval-guide.md +65 -0
  268. package/skills/build-loop/fallbacks.md +549 -0
  269. package/skills/build-loop/phases/fact-check.md +42 -0
  270. package/skills/build-loop/phases/ui-validation.md +267 -0
  271. package/skills/build-loop/references/apple-native-planning.md +439 -0
  272. package/skills/build-loop/references/capability-routing.md +181 -0
  273. package/skills/build-loop/references/codex-subagents.md +98 -0
  274. package/skills/build-loop/references/coordination.md +161 -0
  275. package/skills/build-loop/references/correction-aware-capture.md +177 -0
  276. package/skills/build-loop/references/independent-auditor.md +72 -0
  277. package/skills/build-loop/references/intent-capability-pack.md +170 -0
  278. package/skills/build-loop/references/intent-exploration-prompts.md +96 -0
  279. package/skills/build-loop/references/leadership.md +72 -0
  280. package/skills/build-loop/references/memory.md +284 -0
  281. package/skills/build-loop/references/modular-systems-pack.md +96 -0
  282. package/skills/build-loop/references/output-style.md +129 -0
  283. package/skills/build-loop/references/pay-it-forward-arch.md +98 -0
  284. package/skills/build-loop/references/phase-1-assess.md +218 -0
  285. package/skills/build-loop/references/phase-2-plan.md +77 -0
  286. package/skills/build-loop/references/phase-3-execute.md +47 -0
  287. package/skills/build-loop/references/phase-4-review.md +310 -0
  288. package/skills/build-loop/references/phase-5-iterate.md +71 -0
  289. package/skills/build-loop/references/phase-6-learn.md +56 -0
  290. package/skills/build-loop/references/recent-design-structures.md +274 -0
  291. package/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
  292. package/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
  293. package/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
  294. package/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
  295. package/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
  296. package/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
  297. package/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
  298. package/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
  299. package/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
  300. package/skills/build-loop/references/self-recursive-dev.md +77 -0
  301. package/skills/build-loop/references/self-review.md +232 -0
  302. package/skills/build-loop/references/ui-io-contract.md +116 -0
  303. package/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
  304. package/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
  305. package/skills/build-loop/templates/backlog-item.md +35 -0
  306. package/skills/build-loop/templates/codex-worker-prompt.md +89 -0
  307. package/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
  308. package/skills/build-loop/templates/ux-fix-plan.md +40 -0
  309. package/skills/building-with-deepagents/SKILL.md +195 -0
  310. package/skills/building-with-deepagents/references/anti-patterns.md +141 -0
  311. package/skills/building-with-deepagents/references/api-quick-reference.md +184 -0
  312. package/skills/capabilities/SKILL.md +91 -0
  313. package/skills/debug-loop/SKILL.md +278 -0
  314. package/skills/debug-loop/references/convergence-rules.md +145 -0
  315. package/skills/debug-loop/references/swiftui-macos-clunky-ui-debugger.html +823 -0
  316. package/skills/debugging/assess/SKILL.md +111 -0
  317. package/skills/debugging/debug-loop/SKILL.md +231 -0
  318. package/skills/debugging/memory/SKILL.md +147 -0
  319. package/skills/debugging/store/SKILL.md +153 -0
  320. package/skills/debugging-memory/SKILL.md +440 -0
  321. package/skills/debugging-memory/examples/incident-example.json +67 -0
  322. package/skills/debugging-memory/references/incident-documentation.md +280 -0
  323. package/skills/debugging-memory/references/ios-notification-alarm-playbook.md +300 -0
  324. package/skills/debugging-memory/references/pattern-extraction.md +163 -0
  325. package/skills/debugging-memory/references/subagent-integration.md +312 -0
  326. package/skills/defenseclaw-bridge/SKILL.md +156 -0
  327. package/skills/defenseclaw-bridge/references/dc-config-mapping.md +162 -0
  328. package/skills/defenseclaw-bridge/references/output-format.md +108 -0
  329. package/skills/handoff/SKILL.md +94 -0
  330. package/skills/ibr-bridge/SKILL.md +68 -0
  331. package/skills/knowledge/SKILL.md +127 -0
  332. package/skills/knowledge/references/recall-integration.md +83 -0
  333. package/skills/knowledge/templates/madr-minimal.md +56 -0
  334. package/skills/knowledge-review/SKILL.md +112 -0
  335. package/skills/logging-tracer/SKILL.md +202 -0
  336. package/skills/logging-tracer/references/log-analysis.md +128 -0
  337. package/skills/logging-tracer/references/stack-templates.md +274 -0
  338. package/skills/logging-tracer-bridge/SKILL.md +70 -0
  339. package/skills/mcp-builder/SKILL.md +278 -0
  340. package/skills/mcp-builder/references/mcp-security.md +106 -0
  341. package/skills/model-tiering/SKILL.md +216 -0
  342. package/skills/native-ax-driver/SKILL.md +220 -0
  343. package/skills/native-ax-driver/scripts/layout_fill.py +222 -0
  344. package/skills/native-ax-driver/scripts/native_driver.py +495 -0
  345. package/skills/native-ax-driver/swift/bl-ax-driver/Package.swift +20 -0
  346. package/skills/native-ax-driver/swift/bl-ax-driver/Sources/main.swift +542 -0
  347. package/skills/optimize/SKILL.md +202 -0
  348. package/skills/optimize/profiles.md +61 -0
  349. package/skills/plan-verify/SKILL.md +115 -0
  350. package/skills/plan-verify/test-fixtures/example-app-v20-findings.json +27 -0
  351. package/skills/plan-verify/test-fixtures/example-app-v20.md +42 -0
  352. package/skills/plan-verify/test-fixtures/example-app-v22-findings.json +15 -0
  353. package/skills/plan-verify/test-fixtures/example-app-v22.md +1608 -0
  354. package/skills/plan-verify/test-fixtures/unrelated-good-plan-findings.json +15 -0
  355. package/skills/plan-verify/test-fixtures/unrelated-good-plan.md +55 -0
  356. package/skills/plugin-builder/SKILL.md +329 -0
  357. package/skills/plugin-builder/references/authoritative-sources.md +104 -0
  358. package/skills/plugin-builder/references/build-loop-phase-guidance.md +94 -0
  359. package/skills/plugin-builder/references/components-guide.md +221 -0
  360. package/skills/plugin-builder/references/distribution.md +317 -0
  361. package/skills/plugin-builder/references/dual-host-claude-codex.md +220 -0
  362. package/skills/plugin-builder/references/hooks-reference.md +210 -0
  363. package/skills/plugin-builder/references/manifest-schema.md +111 -0
  364. package/skills/plugin-builder/references/plugin-hygiene-lessons.md +307 -0
  365. package/skills/plugin-tests/SKILL.md +94 -0
  366. package/skills/prd-bridge/SKILL.md +135 -0
  367. package/skills/research/SKILL.md +80 -0
  368. package/skills/security-methodology/SKILL.md +105 -0
  369. package/skills/security-methodology/references/cross-source-matrix.md +77 -0
  370. package/skills/security-methodology/references/mitre-atlas-starter.md +83 -0
  371. package/skills/security-methodology/references/nist-600-1-mapping.md +119 -0
  372. package/skills/security-methodology/references/owasp-agentic-top-10.md +157 -0
  373. package/skills/security-methodology/references/owasp-llm-top-10.md +144 -0
  374. package/skills/security-methodology/references/owasp-web-top-10.md +65 -0
  375. package/skills/self-improve/SKILL.md +298 -0
  376. package/skills/spec-writing/SKILL.md +548 -0
  377. package/skills/spec-writing/scripts/check_checklist.py +478 -0
  378. package/skills/sync-skills/SKILL.md +132 -0
  379. package/skills/telemetry/SKILL.md +66 -0
  380. package/skills/ui-design/SKILL.md +75 -0
  381. package/skills/ui-design/references/design-patterns-multi.md +165 -0
  382. package/skills/ui-design/references/design-preferences-from-owned-apps.md +150 -0
  383. package/skills/ui-design/references/evidence-capture-policy.md +55 -0
  384. package/skills/ui-design/references/ui-guidance-sources.md +330 -0
  385. package/skills/ui-design/references/universal-design-principles.alt.md +182 -0
  386. package/skills/ui-design/references/universal-design-principles.md +419 -0
  387. package/templates/memory/MEMORY.md.template +55 -0
  388. package/templates/memory/constitution.md.template +64 -0
  389. package/templates/memory/manifest.json +47 -0
@@ -0,0 +1,542 @@
1
+ // SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Build-loop native AX driver
4
+ //
5
+ // Reads a running macOS app's accessibility tree and dispatches AX actions
6
+ // (AXPress, AXShowMenu, AXSetValue, AXFocus, AXIncrement, AXDecrement,
7
+ // AXConfirm, AXCancel, AXScrollToVisible) on individual elements.
8
+ //
9
+ // Provenance: ported from interface-built-right's ibr-ax-extract
10
+ // (src/native/swift/ibr-ax-extract/Sources/main.swift). Kept binary-compatible
11
+ // with that tool's output schema so existing parsers work unchanged. Build-loop
12
+ // vendors its own copy so this capability is built in, not bridged.
13
+ //
14
+ // All actions go through AXUIElement APIs. The driver does NOT post CGEvent
15
+ // mouse/keyboard events — the user's hardware cursor is never moved.
16
+
17
+ import AppKit
18
+ import Foundation
19
+
20
+ // MARK: - Element Model
21
+
22
+ struct AXExtractedElement: Codable {
23
+ let role: String
24
+ let subrole: String?
25
+ let title: String?
26
+ let description: String?
27
+ let identifier: String?
28
+ let value: String?
29
+ let enabled: Bool
30
+ let focused: Bool
31
+ let actions: [String]
32
+ let position: Position?
33
+ let size: Size?
34
+ let children: [AXExtractedElement]
35
+ let path: [Int] // Index path from app root: [0, 2, 1] = 1st child → 3rd child → 2nd child
36
+
37
+ struct Position: Codable {
38
+ let x: Double
39
+ let y: Double
40
+ }
41
+
42
+ struct Size: Codable {
43
+ let width: Double
44
+ let height: Double
45
+ }
46
+ }
47
+
48
+ /// Legacy output format for simulator scanning (backwards compatible)
49
+ struct LegacyElement: Codable {
50
+ let identifier: String
51
+ let label: String
52
+ let role: String
53
+ let traits: [String]
54
+ let frame: Frame
55
+ let isEnabled: Bool
56
+ let value: String?
57
+ let path: [Int]
58
+ let children: [LegacyElement]
59
+
60
+ struct Frame: Codable {
61
+ let x: Double
62
+ let y: Double
63
+ let width: Double
64
+ let height: Double
65
+ }
66
+ }
67
+
68
+ // MARK: - AX Attribute Helpers
69
+
70
+ func getStringAttribute(_ element: AXUIElement, _ attribute: String) -> String? {
71
+ var value: AnyObject?
72
+ let result = AXUIElementCopyAttributeValue(element, attribute as CFString, &value)
73
+ guard result == .success, let str = value as? String else { return nil }
74
+ return str
75
+ }
76
+
77
+ func getBoolAttribute(_ element: AXUIElement, _ attribute: String) -> Bool {
78
+ var value: AnyObject?
79
+ let result = AXUIElementCopyAttributeValue(element, attribute as CFString, &value)
80
+ guard result == .success else { return false }
81
+ if let num = value as? NSNumber { return num.boolValue }
82
+ return false
83
+ }
84
+
85
+ func getPosition(_ element: AXUIElement) -> AXExtractedElement.Position? {
86
+ var posValue: AnyObject?
87
+ let result = AXUIElementCopyAttributeValue(element, kAXPositionAttribute as CFString, &posValue)
88
+ guard result == .success, let val = posValue else { return nil }
89
+ var position = CGPoint.zero
90
+ AXValueGetValue(val as! AXValue, .cgPoint, &position)
91
+ return AXExtractedElement.Position(x: Double(position.x), y: Double(position.y))
92
+ }
93
+
94
+ func getSize(_ element: AXUIElement) -> AXExtractedElement.Size? {
95
+ var sizeValue: AnyObject?
96
+ let result = AXUIElementCopyAttributeValue(element, kAXSizeAttribute as CFString, &sizeValue)
97
+ guard result == .success, let val = sizeValue else { return nil }
98
+ var size = CGSize.zero
99
+ AXValueGetValue(val as! AXValue, .cgSize, &size)
100
+ return AXExtractedElement.Size(width: Double(size.width), height: Double(size.height))
101
+ }
102
+
103
+ func getActions(_ element: AXUIElement) -> [String] {
104
+ var actionsValue: CFArray?
105
+ let result = AXUIElementCopyActionNames(element, &actionsValue)
106
+ guard result == .success, let actions = actionsValue as? [String] else { return [] }
107
+ return actions
108
+ }
109
+
110
+ func getChildren(_ element: AXUIElement) -> [AXUIElement] {
111
+ var value: AnyObject?
112
+ let result = AXUIElementCopyAttributeValue(element, kAXChildrenAttribute as CFString, &value)
113
+ guard result == .success, let children = value as? [AXUIElement] else { return [] }
114
+ return children
115
+ }
116
+
117
+ func getFrame(_ element: AXUIElement) -> LegacyElement.Frame {
118
+ let pos = getPosition(element)
119
+ let sz = getSize(element)
120
+ return LegacyElement.Frame(
121
+ x: pos?.x ?? 0, y: pos?.y ?? 0,
122
+ width: sz?.width ?? 0, height: sz?.height ?? 0
123
+ )
124
+ }
125
+
126
+ // MARK: - AX Tree Walkers
127
+
128
+ /// Walk element tree — full AX attributes, tracking index path
129
+ func walkElementFull(_ element: AXUIElement, depth: Int = 0, maxDepth: Int = 15, currentPath: [Int] = []) -> AXExtractedElement? {
130
+ guard depth < maxDepth else { return nil }
131
+
132
+ let role = getStringAttribute(element, kAXRoleAttribute) ?? "AXUnknown"
133
+ let subrole = getStringAttribute(element, kAXSubroleAttribute)
134
+ let title = getStringAttribute(element, kAXTitleAttribute)
135
+ let descriptionAttr = getStringAttribute(element, kAXDescriptionAttribute)
136
+ let identifier = getStringAttribute(element, "AXIdentifier")
137
+ let value = getStringAttribute(element, kAXValueAttribute as String)
138
+ let enabled = getBoolAttribute(element, kAXEnabledAttribute)
139
+ let focused = getBoolAttribute(element, kAXFocusedAttribute)
140
+ let position = getPosition(element)
141
+ let size = getSize(element)
142
+ let actions = getActions(element)
143
+
144
+ if let sz = size, sz.width <= 0 && sz.height <= 0 && depth > 2 {
145
+ return nil
146
+ }
147
+
148
+ let axChildren = getChildren(element)
149
+ var childElements: [AXExtractedElement] = []
150
+ for (index, child) in axChildren.enumerated() {
151
+ let childPath = currentPath + [index]
152
+ if let childEl = walkElementFull(child, depth: depth + 1, maxDepth: maxDepth, currentPath: childPath) {
153
+ childElements.append(childEl)
154
+ }
155
+ }
156
+
157
+ return AXExtractedElement(
158
+ role: role,
159
+ subrole: subrole,
160
+ title: title,
161
+ description: descriptionAttr,
162
+ identifier: identifier,
163
+ value: value,
164
+ enabled: enabled,
165
+ focused: focused,
166
+ actions: actions,
167
+ position: position,
168
+ size: size,
169
+ children: childElements,
170
+ path: currentPath
171
+ )
172
+ }
173
+
174
+ /// Walk element tree — legacy format for simulator compatibility
175
+ func walkElementLegacy(_ element: AXUIElement, depth: Int = 0, maxDepth: Int = 15, currentPath: [Int] = []) -> LegacyElement? {
176
+ guard depth < maxDepth else { return nil }
177
+
178
+ let role = getStringAttribute(element, kAXRoleAttribute) ?? "AXUnknown"
179
+ let label = getStringAttribute(element, kAXTitleAttribute)
180
+ ?? getStringAttribute(element, kAXDescriptionAttribute)
181
+ ?? getStringAttribute(element, kAXValueAttribute as String)
182
+ ?? ""
183
+ let identifier = getStringAttribute(element, "AXIdentifier") ?? ""
184
+ let isEnabled = getBoolAttribute(element, kAXEnabledAttribute)
185
+ let value = getStringAttribute(element, kAXValueAttribute as String)
186
+ let frame = getFrame(element)
187
+
188
+ if frame.width <= 0 && frame.height <= 0 && depth > 2 {
189
+ return nil
190
+ }
191
+
192
+ let axChildren = getChildren(element)
193
+ var childElements: [LegacyElement] = []
194
+ for (index, child) in axChildren.enumerated() {
195
+ let childPath = currentPath + [index]
196
+ if let childEl = walkElementLegacy(child, depth: depth + 1, maxDepth: maxDepth, currentPath: childPath) {
197
+ childElements.append(childEl)
198
+ }
199
+ }
200
+
201
+ var traits: [String] = []
202
+ if role == "AXButton" { traits.append("button") }
203
+ if role == "AXLink" { traits.append("link") }
204
+ if role == "AXStaticText" { traits.append("staticText") }
205
+ if role == "AXImage" { traits.append("image") }
206
+ if !isEnabled { traits.append("disabled") }
207
+
208
+ return LegacyElement(
209
+ identifier: identifier,
210
+ label: label,
211
+ role: role,
212
+ traits: traits,
213
+ frame: frame,
214
+ isEnabled: isEnabled,
215
+ value: value,
216
+ path: currentPath,
217
+ children: childElements
218
+ )
219
+ }
220
+
221
+ // MARK: - App Finders
222
+
223
+ func findSimulatorApp() -> NSRunningApplication? {
224
+ let apps = NSWorkspace.shared.runningApplications
225
+ return apps.first { $0.bundleIdentifier == "com.apple.iphonesimulator" }
226
+ }
227
+
228
+ func findSimulatorWindow(app: NSRunningApplication, deviceName: String?) -> AXUIElement? {
229
+ let appElement = AXUIElementCreateApplication(app.processIdentifier)
230
+
231
+ var windowsValue: AnyObject?
232
+ let result = AXUIElementCopyAttributeValue(appElement, kAXWindowsAttribute as CFString, &windowsValue)
233
+ guard result == .success, let windows = windowsValue as? [AXUIElement] else { return nil }
234
+
235
+ if let deviceName = deviceName {
236
+ for window in windows {
237
+ let title = getStringAttribute(window, kAXTitleAttribute) ?? ""
238
+ if title.localizedCaseInsensitiveContains(deviceName) {
239
+ return window
240
+ }
241
+ }
242
+ }
243
+
244
+ return windows.first
245
+ }
246
+
247
+ /// Find a running app by name (case-insensitive substring match)
248
+ func findAppByName(_ name: String) -> NSRunningApplication? {
249
+ let apps = NSWorkspace.shared.runningApplications
250
+ let lowered = name.lowercased()
251
+ return apps.first { app in
252
+ let appName = app.localizedName?.lowercased() ?? ""
253
+ let bundleId = app.bundleIdentifier?.lowercased() ?? ""
254
+ return appName.contains(lowered) || bundleId.contains(lowered)
255
+ }
256
+ }
257
+
258
+ func findAppByPid(_ pid: pid_t) -> NSRunningApplication? {
259
+ return NSWorkspace.shared.runningApplications.first { $0.processIdentifier == pid }
260
+ }
261
+
262
+ /// Find the frontmost/main window for a given app
263
+ func findMainWindow(pid: pid_t) -> (window: AXUIElement, id: CGWindowID, title: String, size: CGSize)? {
264
+ let appElement = AXUIElementCreateApplication(pid)
265
+
266
+ var windowsValue: AnyObject?
267
+ let result = AXUIElementCopyAttributeValue(appElement, kAXWindowsAttribute as CFString, &windowsValue)
268
+ guard result == .success, let windows = windowsValue as? [AXUIElement], !windows.isEmpty else {
269
+ return nil
270
+ }
271
+
272
+ let window: AXUIElement
273
+ var mainWindow: AnyObject?
274
+ let mainResult = AXUIElementCopyAttributeValue(appElement, kAXMainWindowAttribute as CFString, &mainWindow)
275
+ if mainResult == .success, let mw = mainWindow {
276
+ window = (mw as! AXUIElement)
277
+ } else {
278
+ window = windows[0]
279
+ }
280
+
281
+ let title = getStringAttribute(window, kAXTitleAttribute) ?? "Untitled"
282
+ let sz = getSize(window) ?? AXExtractedElement.Size(width: 800, height: 600)
283
+
284
+ var windowId: CGWindowID = 0
285
+ let windowList = CGWindowListCopyWindowInfo([.optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID) as? [[String: Any]] ?? []
286
+ for info in windowList {
287
+ guard let ownerPid = info[kCGWindowOwnerPID as String] as? Int32,
288
+ let wid = info[kCGWindowNumber as String] as? CGWindowID,
289
+ ownerPid == pid else { continue }
290
+ let wName = info[kCGWindowName as String] as? String ?? ""
291
+ if wName == title || windowId == 0 {
292
+ windowId = wid
293
+ if wName == title { break }
294
+ }
295
+ }
296
+
297
+ return (window: window, id: windowId, title: title,
298
+ size: CGSize(width: sz.width, height: sz.height))
299
+ }
300
+
301
+ // MARK: - Action Execution
302
+
303
+ /// Traverse the AX tree by numeric index path from the app root
304
+ func navigateToElement(root: AXUIElement, path: [Int]) -> AXUIElement? {
305
+ var current = root
306
+ for index in path {
307
+ var childrenRef: CFTypeRef?
308
+ guard AXUIElementCopyAttributeValue(current, kAXChildrenAttribute as CFString, &childrenRef) == .success,
309
+ let children = childrenRef as? [AXUIElement],
310
+ index < children.count else { return nil }
311
+ current = children[index]
312
+ }
313
+ return current
314
+ }
315
+
316
+ /// Execute an accessibility action on the element at the given path
317
+ func performAction(pid: pid_t, deviceName: String?, elementPath: [Int], action: String, value: String?) -> (Bool, String?) {
318
+ let root: AXUIElement?
319
+ if let app = findAppByPid(pid),
320
+ app.bundleIdentifier == "com.apple.iphonesimulator",
321
+ let simulatorWindow = findSimulatorWindow(app: app, deviceName: deviceName) {
322
+ root = simulatorWindow
323
+ } else {
324
+ root = findMainWindow(pid: pid)?.window
325
+ }
326
+
327
+ guard let actionRoot = root else {
328
+ return (false, "No action root window found for pid \(pid)")
329
+ }
330
+
331
+ guard let element = navigateToElement(root: actionRoot, path: elementPath) else {
332
+ return (false, "Element not found at path")
333
+ }
334
+
335
+ switch action {
336
+ case "press":
337
+ let ok = AXUIElementPerformAction(element, kAXPressAction as CFString) == .success
338
+ return (ok, ok ? nil : "AXPress failed")
339
+ case "setValue":
340
+ guard let value = value else {
341
+ return (false, "setValue requires --value")
342
+ }
343
+ let ok = AXUIElementSetAttributeValue(element, kAXValueAttribute as CFString, value as CFTypeRef) == .success
344
+ return (ok, ok ? nil : "AXSetValue failed")
345
+ case "increment":
346
+ let ok = AXUIElementPerformAction(element, kAXIncrementAction as CFString) == .success
347
+ return (ok, ok ? nil : "AXIncrement failed")
348
+ case "decrement":
349
+ let ok = AXUIElementPerformAction(element, kAXDecrementAction as CFString) == .success
350
+ return (ok, ok ? nil : "AXDecrement failed")
351
+ case "showMenu":
352
+ let ok = AXUIElementPerformAction(element, kAXShowMenuAction as CFString) == .success
353
+ return (ok, ok ? nil : "AXShowMenu failed")
354
+ case "confirm":
355
+ let ok = AXUIElementPerformAction(element, kAXConfirmAction as CFString) == .success
356
+ return (ok, ok ? nil : "AXConfirm failed")
357
+ case "cancel":
358
+ let ok = AXUIElementPerformAction(element, kAXCancelAction as CFString) == .success
359
+ return (ok, ok ? nil : "AXCancel failed")
360
+ case "focus":
361
+ let ok = AXUIElementSetAttributeValue(element, kAXFocusedAttribute as CFString, true as CFTypeRef) == .success
362
+ return (ok, ok ? nil : "AXFocus failed")
363
+ case "scrollToVisible":
364
+ let ok = AXUIElementPerformAction(element, "AXScrollToVisible" as CFString) == .success
365
+ return (ok, ok ? nil : "AXScrollToVisible failed")
366
+ default:
367
+ return (false, "Unknown action: \(action)")
368
+ }
369
+ }
370
+
371
+ // MARK: - Main
372
+
373
+ let args = CommandLine.arguments
374
+
375
+ var deviceName: String? = nil
376
+ var targetPid: pid_t? = nil
377
+ var targetApp: String? = nil
378
+ var resolveApp: String? = nil
379
+ var outputMode: String = "auto"
380
+ var actionName: String? = nil
381
+ var elementPathStr: String? = nil
382
+ var actionValue: String? = nil
383
+
384
+ var i = 1
385
+ while i < args.count {
386
+ switch args[i] {
387
+ case "--device-name":
388
+ i += 1
389
+ if i < args.count { deviceName = args[i] }
390
+ case "--pid":
391
+ i += 1
392
+ if i < args.count { targetPid = pid_t(args[i]) }
393
+ case "--app":
394
+ i += 1
395
+ if i < args.count { targetApp = args[i] }
396
+ case "--resolve-app":
397
+ i += 1
398
+ if i < args.count { resolveApp = args[i] }
399
+ case "--format":
400
+ i += 1
401
+ if i < args.count { outputMode = args[i] }
402
+ case "--action":
403
+ i += 1
404
+ if i < args.count { actionName = args[i] }
405
+ case "--element-path":
406
+ i += 1
407
+ if i < args.count { elementPathStr = args[i] } // comma-separated: "0,2,1"
408
+ case "--value":
409
+ i += 1
410
+ if i < args.count { actionValue = args[i] }
411
+ default:
412
+ break
413
+ }
414
+ i += 1
415
+ }
416
+
417
+ // --- Mode: Resolve a running macOS app without AX permission ---
418
+ if let appName = resolveApp {
419
+ guard let app = findAppByName(appName) else {
420
+ fputs("Error: No running app found matching \"\(appName)\"\n", stderr)
421
+ exit(1)
422
+ }
423
+
424
+ let payload: [String: Any] = [
425
+ "pid": Int(app.processIdentifier),
426
+ "name": app.localizedName ?? "",
427
+ "bundleIdentifier": app.bundleIdentifier ?? ""
428
+ ]
429
+ if let data = try? JSONSerialization.data(withJSONObject: payload),
430
+ let str = String(data: data, encoding: .utf8) {
431
+ print(str)
432
+ exit(0)
433
+ }
434
+ fputs("Error: Failed to encode app resolution JSON\n", stderr)
435
+ exit(1)
436
+ }
437
+
438
+ // Check accessibility permission
439
+ let checkOpts = [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true] as CFDictionary
440
+ guard AXIsProcessTrustedWithOptions(checkOpts) else {
441
+ fputs("Error: Accessibility permission required. Grant access in System Settings > Privacy & Security > Accessibility\n", stderr)
442
+ exit(1)
443
+ }
444
+
445
+ let encoder = JSONEncoder()
446
+ encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
447
+
448
+ // --- Mode: Action execution (--action --pid --element-path) ---
449
+ if let actionName = actionName, let pathStr = elementPathStr {
450
+ guard let pid = targetPid else {
451
+ fputs("{\"error\":\"--pid is required for action mode\"}\n", stderr)
452
+ exit(1)
453
+ }
454
+ let path = pathStr.split(separator: ",").compactMap { Int($0) }
455
+ let (success, error) = performAction(pid: pid, deviceName: deviceName, elementPath: path, action: actionName, value: actionValue)
456
+ var result: [String: Any] = ["success": success, "action": actionName]
457
+ if let error = error {
458
+ result["error"] = error
459
+ }
460
+ if let data = try? JSONSerialization.data(withJSONObject: result),
461
+ let str = String(data: data, encoding: .utf8) {
462
+ print(str)
463
+ }
464
+ exit(success ? 0 : 1)
465
+ }
466
+
467
+ // --- Mode 1: macOS app scanning (--pid or --app) ---
468
+ if targetPid != nil || targetApp != nil {
469
+ let pid: pid_t
470
+ if let p = targetPid {
471
+ pid = p
472
+ } else if let appName = targetApp {
473
+ guard let app = findAppByName(appName) else {
474
+ fputs("Error: No running app found matching \"\(appName)\"\n", stderr)
475
+ fputs("Running apps:\n", stderr)
476
+ for app in NSWorkspace.shared.runningApplications where app.activationPolicy == .regular {
477
+ let name = app.localizedName ?? "Unknown"
478
+ let bundle = app.bundleIdentifier ?? "unknown"
479
+ fputs(" \(name) (\(bundle)) pid=\(app.processIdentifier)\n", stderr)
480
+ }
481
+ exit(1)
482
+ }
483
+ pid = app.processIdentifier
484
+ } else {
485
+ fputs("Error: No target specified\n", stderr)
486
+ exit(1)
487
+ }
488
+
489
+ guard let windowInfo = findMainWindow(pid: pid) else {
490
+ fputs("Error: No windows found for pid \(pid)\n", stderr)
491
+ exit(1)
492
+ }
493
+
494
+ let widthInt = Int(windowInfo.size.width)
495
+ let heightInt = Int(windowInfo.size.height)
496
+ print("WINDOW:\(windowInfo.id):\(widthInt)x\(heightInt):\(windowInfo.title)")
497
+
498
+ guard let rootElement = walkElementFull(windowInfo.window, currentPath: []) else {
499
+ fputs("Error: Failed to walk accessibility tree\n", stderr)
500
+ exit(1)
501
+ }
502
+
503
+ let output = rootElement.children
504
+ let data = try encoder.encode(output)
505
+ if let json = String(data: data, encoding: .utf8) {
506
+ print(json)
507
+ } else {
508
+ fputs("Error: Failed to encode JSON\n", stderr)
509
+ exit(1)
510
+ }
511
+
512
+ exit(0)
513
+ }
514
+
515
+ // --- Mode 2: Simulator scanning (--device-name or default) ---
516
+ guard let simApp = findSimulatorApp() else {
517
+ fputs("Error: Simulator.app is not running\n", stderr)
518
+ exit(1)
519
+ }
520
+
521
+ guard let window = findSimulatorWindow(app: simApp, deviceName: deviceName) else {
522
+ let msg = deviceName != nil
523
+ ? "Error: No simulator window found for device: \(deviceName!)"
524
+ : "Error: No simulator windows found"
525
+ fputs("\(msg)\n", stderr)
526
+ exit(1)
527
+ }
528
+
529
+ guard let rootElement = walkElementLegacy(window, currentPath: []) else {
530
+ fputs("Error: Failed to walk accessibility tree\n", stderr)
531
+ exit(1)
532
+ }
533
+
534
+ let output = rootElement.children
535
+ let data = try encoder.encode(output)
536
+
537
+ if let json = String(data: data, encoding: .utf8) {
538
+ print(json)
539
+ } else {
540
+ fputs("Error: Failed to encode JSON\n", stderr)
541
+ exit(1)
542
+ }