@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,263 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ """Backfill embeddings for semantic_facts rows where ``embedding_json IS NULL``.
5
+
6
+ The P1 auto-embed-on-write change (``upsert_fact(auto_embed=True)``)
7
+ only covers rows written AFTER the upgrade. Pre-upgrade rows — and rows
8
+ written while the embed backend was down — sit with ``embedding_json
9
+ NULL`` and skip the cosine rerank in ``hybrid.rerank_candidates``.
10
+
11
+ This module embeds those NULL rows in place. Idempotent: a second run
12
+ finds zero NULL rows and is a no-op. Resumable: batched commits mean a
13
+ killed process loses at most one batch.
14
+
15
+ Public API:
16
+ backfill_embeddings(...) → BackfillResult library entry point
17
+ main(argv=None) → int CLI: report + exit code
18
+
19
+ Stdlib-only. Defers ``embed_backend.embed`` import so the script remains
20
+ importable in environments without MLX/Ollama (it will just report zero
21
+ work done and the underlying error).
22
+ """
23
+ from __future__ import annotations
24
+
25
+ import argparse
26
+ import json
27
+ import sqlite3
28
+ import sys
29
+ from dataclasses import dataclass, field
30
+ from pathlib import Path
31
+ from typing import Any, Callable, Optional
32
+
33
+ HERE = Path(__file__).resolve().parent
34
+ SCRIPTS = HERE.parent
35
+ if str(SCRIPTS) not in sys.path:
36
+ sys.path.insert(0, str(SCRIPTS))
37
+
38
+ from semantic_index import ( # noqa: E402
39
+ _db_path,
40
+ _embed_text_for_fact,
41
+ connect,
42
+ )
43
+
44
+
45
+ @dataclass
46
+ class BackfillResult:
47
+ """Outcome of a backfill run. Reportable without re-querying."""
48
+
49
+ db_path: str = ""
50
+ scanned: int = 0
51
+ embedded: int = 0
52
+ skipped_empty_text: int = 0
53
+ failed: int = 0
54
+ backend_unavailable: bool = False
55
+ error: Optional[str] = None
56
+ sample_failures: list[str] = field(default_factory=list)
57
+
58
+ def to_dict(self) -> dict[str, Any]:
59
+ return {
60
+ "db_path": self.db_path,
61
+ "scanned": self.scanned,
62
+ "embedded": self.embedded,
63
+ "skipped_empty_text": self.skipped_empty_text,
64
+ "failed": self.failed,
65
+ "backend_unavailable": self.backend_unavailable,
66
+ "error": self.error,
67
+ "sample_failures": self.sample_failures[:5],
68
+ }
69
+
70
+
71
+ def _resolve_default_embed_fn() -> Optional[Callable[[str], list[float]]]:
72
+ """Resolve ``embed_backend.embed`` lazily. Returns None on import error.
73
+
74
+ Kept out of module-import so the backfill module is importable in
75
+ environments without optional MLX/Ollama dependencies — the CLI
76
+ surfaces backend-unavailable as a clean error, not a stack trace.
77
+ """
78
+ try:
79
+ from embed_backend import embed as _embed # type: ignore # noqa: PLC0415
80
+ except Exception: # noqa: BLE001
81
+ return None
82
+ return _embed
83
+
84
+
85
+ def _iter_null_rows(
86
+ conn: sqlite3.Connection,
87
+ batch_size: int,
88
+ after_rowid: int = 0,
89
+ ) -> list[tuple[int, str, str, str]]:
90
+ """Fetch up to ``batch_size`` rows with NULL embedding_json AND
91
+ ``rowid > after_rowid``.
92
+
93
+ The ``after_rowid`` cursor prevents the inner loop from re-fetching
94
+ a row that failed to embed (which would leave it NULL and re-pick it
95
+ on the next iteration — an infinite loop). The outer call passes 0
96
+ on first batch and advances to the highest rowid seen so far.
97
+ Successfully-embedded rows are no longer NULL, so they fall out of
98
+ the predicate naturally — no separate exclusion set needed.
99
+
100
+ Returns (rowid, subject, predicate, object) tuples — exactly the
101
+ fields ``_embed_text_for_fact`` consumes. Bounded by ``batch_size``
102
+ so memory and commit-window scale predictably with large DBs.
103
+ """
104
+ cur = conn.execute(
105
+ """
106
+ SELECT rowid, subject, predicate, object
107
+ FROM semantic_facts
108
+ WHERE embedding_json IS NULL AND rowid > ?
109
+ ORDER BY rowid ASC
110
+ LIMIT ?
111
+ """,
112
+ (after_rowid, batch_size),
113
+ )
114
+ return [
115
+ (int(r[0]), str(r[1] or ""), str(r[2] or ""), str(r[3] or ""))
116
+ for r in cur.fetchall()
117
+ ]
118
+
119
+
120
+ def backfill_embeddings(
121
+ *,
122
+ db_path: str | Path | None = None,
123
+ embed_fn: Optional[Callable[[str], list[float]]] = None,
124
+ batch_size: int = 50,
125
+ max_rows: Optional[int] = None,
126
+ ) -> BackfillResult:
127
+ """Embed every ``embedding_json IS NULL`` row in place.
128
+
129
+ Idempotency: rows with non-NULL ``embedding_json`` are never re-
130
+ embedded. Re-running on a fully-backfilled DB scans zero rows and
131
+ returns ``embedded=0`` — safe to schedule periodically.
132
+
133
+ Per-row failure isolation: when ``embed_fn`` raises on a single row,
134
+ that row stays NULL (counted in ``failed``) and the loop continues.
135
+ A row-level failure does not abort the whole backfill — the embed
136
+ backend may genuinely choke on one pathological text (e.g. all
137
+ whitespace) but be fine on every other row.
138
+
139
+ ``max_rows``: cap total rows processed in this call. Useful for
140
+ incremental backfills under a time budget; the next call resumes.
141
+ """
142
+ result = BackfillResult(db_path=str(_db_path(db_path)))
143
+ path = _db_path(db_path)
144
+ if not path.exists():
145
+ # Nothing to backfill — fresh installs hit this before the first
146
+ # write. Not an error; not a backend-unavailable state either.
147
+ return result
148
+
149
+ if embed_fn is None:
150
+ embed_fn = _resolve_default_embed_fn()
151
+ if embed_fn is None:
152
+ result.backend_unavailable = True
153
+ result.error = "embed_backend import failed"
154
+ return result
155
+
156
+ conn = connect(path)
157
+ try:
158
+ rows_left = max_rows
159
+ cursor_rowid = 0 # advances past every row we touch (success or fail)
160
+ while True:
161
+ if rows_left is not None and rows_left <= 0:
162
+ break
163
+ limit = batch_size
164
+ if rows_left is not None:
165
+ limit = min(batch_size, rows_left)
166
+ batch = _iter_null_rows(conn, limit, after_rowid=cursor_rowid)
167
+ if not batch:
168
+ break
169
+
170
+ for rowid, subject, predicate, obj in batch:
171
+ cursor_rowid = max(cursor_rowid, rowid)
172
+ result.scanned += 1
173
+ if rows_left is not None:
174
+ rows_left -= 1
175
+ text = _embed_text_for_fact(subject, predicate, obj)
176
+ if not text:
177
+ result.skipped_empty_text += 1
178
+ continue
179
+ try:
180
+ vec = embed_fn(text)
181
+ except Exception as e: # noqa: BLE001 - per-row isolation
182
+ result.failed += 1
183
+ if len(result.sample_failures) < 5:
184
+ result.sample_failures.append(
185
+ f"rowid={rowid}: {type(e).__name__}: {e}"
186
+ )
187
+ continue
188
+ if not isinstance(vec, list) or not vec:
189
+ result.failed += 1
190
+ if len(result.sample_failures) < 5:
191
+ result.sample_failures.append(
192
+ f"rowid={rowid}: embed returned {type(vec).__name__}"
193
+ )
194
+ continue
195
+ try:
196
+ payload = json.dumps(
197
+ [float(x) for x in vec], ensure_ascii=False, sort_keys=True
198
+ )
199
+ except (TypeError, ValueError) as e:
200
+ result.failed += 1
201
+ if len(result.sample_failures) < 5:
202
+ result.sample_failures.append(
203
+ f"rowid={rowid}: non-numeric vector: {e}"
204
+ )
205
+ continue
206
+ conn.execute(
207
+ "UPDATE semantic_facts SET embedding_json = ? WHERE rowid = ?",
208
+ (payload, rowid),
209
+ )
210
+ result.embedded += 1
211
+ conn.commit() # per-batch commit → resumable if killed
212
+ finally:
213
+ conn.close()
214
+ return result
215
+
216
+
217
+ def main(argv: Optional[list[str]] = None) -> int:
218
+ """CLI: report scanned/embedded/failed counts as JSON.
219
+
220
+ Exit codes:
221
+ 0 — completed successfully (including zero-work no-ops).
222
+ 2 — embed backend unavailable (MLX broken + Ollama unreachable).
223
+ Distinct from 0 so cron/health checks can alert on degraded
224
+ embedding capability without flagging clean idempotent runs.
225
+ """
226
+ parser = argparse.ArgumentParser(
227
+ description="Backfill NULL semantic_facts.embedding_json rows."
228
+ )
229
+ parser.add_argument("--db-path", default=None)
230
+ parser.add_argument("--batch-size", type=int, default=50)
231
+ parser.add_argument(
232
+ "--max-rows",
233
+ type=int,
234
+ default=None,
235
+ help="Cap rows processed this call (for time-bounded incremental runs).",
236
+ )
237
+ parser.add_argument("--json", action="store_true")
238
+ args = parser.parse_args(argv)
239
+
240
+ result = backfill_embeddings(
241
+ db_path=args.db_path,
242
+ batch_size=args.batch_size,
243
+ max_rows=args.max_rows,
244
+ )
245
+ if args.json:
246
+ print(json.dumps(result.to_dict(), indent=2))
247
+ else:
248
+ print(
249
+ f"backfill: scanned={result.scanned} embedded={result.embedded} "
250
+ f"failed={result.failed} skipped_empty={result.skipped_empty_text} "
251
+ f"db={result.db_path}"
252
+ )
253
+ if result.backend_unavailable:
254
+ print(f" backend unavailable: {result.error}", file=sys.stderr)
255
+ for sample in result.sample_failures:
256
+ print(f" failure: {sample}", file=sys.stderr)
257
+ if result.backend_unavailable:
258
+ return 2
259
+ return 0
260
+
261
+
262
+ if __name__ == "__main__":
263
+ sys.exit(main())
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ """Hybrid keyword+embedding rerank for the SQLite semantic index.
5
+
6
+ Lifts the documented MemTier ceiling: default recall stops being pure
7
+ keyword (`scripts/semantic_index/__init__.py::query_facts` legacy path)
8
+ and gains an embedding-rerank stage that surfaces synonyms / paraphrases
9
+ the keyword scorer misses.
10
+
11
+ Pipeline (default):
12
+ 1. Keyword candidate generation (legacy SQLite scorer, overfetched).
13
+ 2. Embed the query via ``embed_backend.embed`` (MLX default, Ollama
14
+ fallback, daemon-aware).
15
+ 3. For each candidate that has a persisted embedding (``embedding_json``
16
+ column), compute cosine similarity to the query vector.
17
+ 4. Final score = ``keyword_score + cosine_sim``. Rows without a
18
+ persisted embedding keep their keyword-only score.
19
+
20
+ Graceful fallback (NEVER raises):
21
+ - Embed backend down (MLX broken + Ollama unreachable + daemon off):
22
+ return the pure-keyword ranking.
23
+ - No candidate has a persisted embedding: return the pure-keyword
24
+ ranking. Embedding backfill is opportunistic at write time
25
+ (``upsert_fact(embedding=...)``).
26
+
27
+ Reuse: the embedding store IS the existing ``embedding_json`` column on
28
+ ``semantic_facts`` — already populated when callers pass ``embedding=``
29
+ to ``upsert_fact``. No new table; no schema migration beyond the
30
+ pre-existing ``CREATE TABLE IF NOT EXISTS`` in ``init()``.
31
+
32
+ Stdlib-only. Math is plain Python (no numpy).
33
+ """
34
+ from __future__ import annotations
35
+
36
+ import json
37
+ import math
38
+ import sqlite3
39
+ from typing import Any, Callable, Optional, Sequence
40
+
41
+
42
+ def _cosine(a: Sequence[float], b: Sequence[float]) -> float:
43
+ """Cosine similarity between two equal-length float vectors.
44
+
45
+ Returns 0.0 when either vector is zero-length or zero-norm. Tolerates
46
+ short reads (caller may pass an embedding from a different model
47
+ version with a shorter dimension) by truncating to the shorter length.
48
+ """
49
+ n = min(len(a), len(b))
50
+ if n == 0:
51
+ return 0.0
52
+ dot = 0.0
53
+ na = 0.0
54
+ nb = 0.0
55
+ for i in range(n):
56
+ x = float(a[i])
57
+ y = float(b[i])
58
+ dot += x * y
59
+ na += x * x
60
+ nb += y * y
61
+ if na == 0.0 or nb == 0.0:
62
+ return 0.0
63
+ return dot / (math.sqrt(na) * math.sqrt(nb))
64
+
65
+
66
+ def _parse_embedding(raw: Any) -> Optional[list[float]]:
67
+ """Parse the embedding_json column value into a Python list of floats.
68
+
69
+ Returns None when the column is NULL, empty, or unparseable. Defensive
70
+ by design: a corrupt embedding row must not crash recall.
71
+ """
72
+ if raw is None:
73
+ return None
74
+ if isinstance(raw, list):
75
+ try:
76
+ return [float(x) for x in raw]
77
+ except (TypeError, ValueError):
78
+ return None
79
+ if isinstance(raw, (bytes, bytearray)):
80
+ try:
81
+ raw = raw.decode("utf-8")
82
+ except UnicodeDecodeError:
83
+ return None
84
+ if not isinstance(raw, str) or not raw.strip():
85
+ return None
86
+ try:
87
+ parsed = json.loads(raw)
88
+ except (json.JSONDecodeError, ValueError):
89
+ return None
90
+ if not isinstance(parsed, list):
91
+ return None
92
+ try:
93
+ return [float(x) for x in parsed]
94
+ except (TypeError, ValueError):
95
+ return None
96
+
97
+
98
+ def _safe_embed_query(
99
+ query: str,
100
+ embed_fn: Optional[Callable[[str], list[float]]],
101
+ ) -> Optional[list[float]]:
102
+ """Embed the query with the supplied backend. Returns None on failure.
103
+
104
+ ``embed_fn`` is injectable so tests can supply a deterministic backend
105
+ without monkey-patching the module-level ``embed_backend.embed``. When
106
+ None, falls through to ``embed_backend.embed`` lazily — the import is
107
+ deferred so missing optional deps don't fail at module import time.
108
+ """
109
+ if not query or not query.strip():
110
+ return None
111
+ if embed_fn is None:
112
+ try:
113
+ from embed_backend import embed as _embed # type: ignore # noqa: PLC0415
114
+ except Exception: # noqa: BLE001 graceful: backend not importable.
115
+ return None
116
+ embed_fn = _embed
117
+ try:
118
+ vec = embed_fn(query)
119
+ except Exception: # noqa: BLE001 graceful: backend raised at call time.
120
+ return None
121
+ if not isinstance(vec, list) or not vec:
122
+ return None
123
+ return vec
124
+
125
+
126
+ def rerank_candidates(
127
+ candidates: list[tuple[float, sqlite3.Row]],
128
+ query_embedding: list[float],
129
+ ) -> list[tuple[float, sqlite3.Row]]:
130
+ """Add cosine boost to candidate scores.
131
+
132
+ Returns a new list sorted by (boosted_score DESC). Candidates without a
133
+ parseable embedding keep their original keyword score (no cosine
134
+ boost), so they don't lose ground to no-embedding rows in the pure
135
+ keyword case.
136
+
137
+ Score formula: ``final = keyword_score + cosine(query, candidate)``.
138
+ Additive rather than weighted-mix because (a) the keyword score is a
139
+ small integer (token match count) and the cosine is in [-1,1] — the
140
+ addition naturally lets a strong cosine match (≈0.7+) rescue a
141
+ candidate that only matched on 1 keyword token; (b) anything with the
142
+ same keyword score now ranks by semantic similarity. No weighted
143
+ tuning needed; we never trade keyword precision away.
144
+ """
145
+ boosted: list[tuple[float, sqlite3.Row]] = []
146
+ for keyword_score, row in candidates:
147
+ emb = _parse_embedding(row["embedding_json"] if "embedding_json" in row.keys() else None)
148
+ if emb is None:
149
+ boosted.append((float(keyword_score), row))
150
+ continue
151
+ sim = _cosine(query_embedding, emb)
152
+ boosted.append((float(keyword_score) + sim, row))
153
+ boosted.sort(key=lambda item: item[0], reverse=True)
154
+ return boosted
155
+
156
+
157
+ def has_any_embedding(candidates: list[tuple[float, sqlite3.Row]]) -> bool:
158
+ """Cheap probe: does any candidate row carry a parseable embedding?
159
+
160
+ Per-row guard: a candidate without the column is skipped via ``continue``,
161
+ not short-circuited with ``return False``. Heterogeneous candidate sets
162
+ (e.g. a mid-migration mix of with/without-embedding rows, or a unioned
163
+ cursor from a future multi-source path) must still surface "yes" when
164
+ ANY row carries a vector. The earlier ``return False`` on the first
165
+ column-less row hid valid embedding rows downstream and turned hybrid
166
+ silently into keyword for the whole query — the exact dormancy this
167
+ rerank was meant to lift.
168
+ """
169
+ for _, row in candidates:
170
+ if "embedding_json" not in row.keys():
171
+ continue
172
+ if _parse_embedding(row["embedding_json"]) is not None:
173
+ return True
174
+ return False