pi-smart-router 0.1.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 (310) hide show
  1. package/.pi/extensions/smart-router/command-formatters.ts +167 -0
  2. package/.pi/extensions/smart-router/commands.ts +242 -0
  3. package/.pi/extensions/smart-router/dataset-export.ts +142 -0
  4. package/.pi/extensions/smart-router/delegate-stream.ts +105 -0
  5. package/.pi/extensions/smart-router/delegation-runtime.ts +355 -0
  6. package/.pi/extensions/smart-router/extension-setup.ts +115 -0
  7. package/.pi/extensions/smart-router/fleet-bootstrap.ts +244 -0
  8. package/.pi/extensions/smart-router/index.ts +115 -0
  9. package/.pi/extensions/smart-router/package.json +3 -0
  10. package/.pi/extensions/smart-router/pi-model-scope.ts +55 -0
  11. package/.pi/extensions/smart-router/pricing-lifecycle.ts +43 -0
  12. package/.pi/extensions/smart-router/route-and-delegate.ts +562 -0
  13. package/.pi/extensions/smart-router/routing-context.ts +171 -0
  14. package/.pi/extensions/smart-router/routing-outcomes.ts +44 -0
  15. package/.pi/extensions/smart-router/session-lifecycle.ts +140 -0
  16. package/.pi/extensions/smart-router/stream-delegation.ts +75 -0
  17. package/.pi/extensions/smart-router/types.ts +90 -0
  18. package/.pi/extensions/smart-router/utils.ts +58 -0
  19. package/README.md +593 -0
  20. package/bin/pi-smart-router.mjs +79 -0
  21. package/config/.gitkeep +0 -0
  22. package/config/hydra-projection-weights.json.example +1169 -0
  23. package/config/models.yaml.example +58 -0
  24. package/config/p-success-weights.json.example +19 -0
  25. package/config/routing-calibration.json.example +1605 -0
  26. package/config/routing-centroids.json.example +1570 -0
  27. package/config/routing-clusters.yaml.example +41 -0
  28. package/data/contrib/example.json +25 -0
  29. package/dist/api/explain/router-explain.d.ts +47 -0
  30. package/dist/api/explain/router-explain.d.ts.map +1 -0
  31. package/dist/api/explain/router-explain.js +101 -0
  32. package/dist/api/explain/router-explain.js.map +1 -0
  33. package/dist/api/middleware/pi-router-middleware.d.ts +86 -0
  34. package/dist/api/middleware/pi-router-middleware.d.ts.map +1 -0
  35. package/dist/api/middleware/pi-router-middleware.js +83 -0
  36. package/dist/api/middleware/pi-router-middleware.js.map +1 -0
  37. package/dist/cli/smart-router-cli.d.ts +85 -0
  38. package/dist/cli/smart-router-cli.d.ts.map +1 -0
  39. package/dist/cli/smart-router-cli.js +293 -0
  40. package/dist/cli/smart-router-cli.js.map +1 -0
  41. package/dist/config/defaults.d.ts +7 -0
  42. package/dist/config/defaults.d.ts.map +1 -0
  43. package/dist/config/defaults.js +33 -0
  44. package/dist/config/defaults.js.map +1 -0
  45. package/dist/config/models-loader.d.ts +22 -0
  46. package/dist/config/models-loader.d.ts.map +1 -0
  47. package/dist/config/models-loader.js +51 -0
  48. package/dist/config/models-loader.js.map +1 -0
  49. package/dist/config/pi-model-mapper.d.ts +40 -0
  50. package/dist/config/pi-model-mapper.d.ts.map +1 -0
  51. package/dist/config/pi-model-mapper.js +216 -0
  52. package/dist/config/pi-model-mapper.js.map +1 -0
  53. package/dist/config/routing-clusters-loader.d.ts +35 -0
  54. package/dist/config/routing-clusters-loader.d.ts.map +1 -0
  55. package/dist/config/routing-clusters-loader.js +100 -0
  56. package/dist/config/routing-clusters-loader.js.map +1 -0
  57. package/dist/domain/delegation/delegation-context.d.ts +23 -0
  58. package/dist/domain/delegation/delegation-context.d.ts.map +1 -0
  59. package/dist/domain/delegation/delegation-context.js +73 -0
  60. package/dist/domain/delegation/delegation-context.js.map +1 -0
  61. package/dist/domain/delegation/execution-ledger.d.ts +19 -0
  62. package/dist/domain/delegation/execution-ledger.d.ts.map +1 -0
  63. package/dist/domain/delegation/execution-ledger.js +23 -0
  64. package/dist/domain/delegation/execution-ledger.js.map +1 -0
  65. package/dist/domain/delegation/output-headroom.d.ts +39 -0
  66. package/dist/domain/delegation/output-headroom.d.ts.map +1 -0
  67. package/dist/domain/delegation/output-headroom.js +78 -0
  68. package/dist/domain/delegation/output-headroom.js.map +1 -0
  69. package/dist/domain/matching/cluster-matcher.d.ts +69 -0
  70. package/dist/domain/matching/cluster-matcher.d.ts.map +1 -0
  71. package/dist/domain/matching/cluster-matcher.js +294 -0
  72. package/dist/domain/matching/cluster-matcher.js.map +1 -0
  73. package/dist/domain/matching/embedding-provider.d.ts +21 -0
  74. package/dist/domain/matching/embedding-provider.d.ts.map +1 -0
  75. package/dist/domain/matching/embedding-provider.js +42 -0
  76. package/dist/domain/matching/embedding-provider.js.map +1 -0
  77. package/dist/domain/matching/hydra-input.d.ts +18 -0
  78. package/dist/domain/matching/hydra-input.d.ts.map +1 -0
  79. package/dist/domain/matching/hydra-input.js +40 -0
  80. package/dist/domain/matching/hydra-input.js.map +1 -0
  81. package/dist/domain/matching/hydra-matcher.d.ts +103 -0
  82. package/dist/domain/matching/hydra-matcher.d.ts.map +1 -0
  83. package/dist/domain/matching/hydra-matcher.js +275 -0
  84. package/dist/domain/matching/hydra-matcher.js.map +1 -0
  85. package/dist/domain/pinning/cache-economics.d.ts +53 -0
  86. package/dist/domain/pinning/cache-economics.d.ts.map +1 -0
  87. package/dist/domain/pinning/cache-economics.js +72 -0
  88. package/dist/domain/pinning/cache-economics.js.map +1 -0
  89. package/dist/domain/pinning/loop-escalation.d.ts +41 -0
  90. package/dist/domain/pinning/loop-escalation.d.ts.map +1 -0
  91. package/dist/domain/pinning/loop-escalation.js +137 -0
  92. package/dist/domain/pinning/loop-escalation.js.map +1 -0
  93. package/dist/domain/pinning/session-pinner.d.ts +81 -0
  94. package/dist/domain/pinning/session-pinner.d.ts.map +1 -0
  95. package/dist/domain/pinning/session-pinner.js +237 -0
  96. package/dist/domain/pinning/session-pinner.js.map +1 -0
  97. package/dist/domain/pinning/sub-route-policy.d.ts +41 -0
  98. package/dist/domain/pinning/sub-route-policy.d.ts.map +1 -0
  99. package/dist/domain/pinning/sub-route-policy.js +72 -0
  100. package/dist/domain/pinning/sub-route-policy.js.map +1 -0
  101. package/dist/domain/pipeline/router-pipeline.d.ts +180 -0
  102. package/dist/domain/pipeline/router-pipeline.d.ts.map +1 -0
  103. package/dist/domain/pipeline/router-pipeline.js +807 -0
  104. package/dist/domain/pipeline/router-pipeline.js.map +1 -0
  105. package/dist/domain/pipeline/safe-default.d.ts +25 -0
  106. package/dist/domain/pipeline/safe-default.d.ts.map +1 -0
  107. package/dist/domain/pipeline/safe-default.js +41 -0
  108. package/dist/domain/pipeline/safe-default.js.map +1 -0
  109. package/dist/domain/refactor-guardrails.d.ts +48 -0
  110. package/dist/domain/refactor-guardrails.d.ts.map +1 -0
  111. package/dist/domain/refactor-guardrails.js +129 -0
  112. package/dist/domain/refactor-guardrails.js.map +1 -0
  113. package/dist/domain/routing/context-fit.d.ts +53 -0
  114. package/dist/domain/routing/context-fit.d.ts.map +1 -0
  115. package/dist/domain/routing/context-fit.js +142 -0
  116. package/dist/domain/routing/context-fit.js.map +1 -0
  117. package/dist/domain/routing/expected-cost.d.ts +63 -0
  118. package/dist/domain/routing/expected-cost.d.ts.map +1 -0
  119. package/dist/domain/routing/expected-cost.js +177 -0
  120. package/dist/domain/routing/expected-cost.js.map +1 -0
  121. package/dist/domain/routing/p-success-classifier.d.ts +130 -0
  122. package/dist/domain/routing/p-success-classifier.d.ts.map +1 -0
  123. package/dist/domain/routing/p-success-classifier.js +350 -0
  124. package/dist/domain/routing/p-success-classifier.js.map +1 -0
  125. package/dist/domain/routing/tier-features.d.ts +70 -0
  126. package/dist/domain/routing/tier-features.d.ts.map +1 -0
  127. package/dist/domain/routing/tier-features.js +174 -0
  128. package/dist/domain/routing/tier-features.js.map +1 -0
  129. package/dist/domain/routing/tool-history-guard.d.ts +32 -0
  130. package/dist/domain/routing/tool-history-guard.d.ts.map +1 -0
  131. package/dist/domain/routing/tool-history-guard.js +110 -0
  132. package/dist/domain/routing/tool-history-guard.js.map +1 -0
  133. package/dist/domain/scoring/multi-objective.d.ts +48 -0
  134. package/dist/domain/scoring/multi-objective.d.ts.map +1 -0
  135. package/dist/domain/scoring/multi-objective.js +116 -0
  136. package/dist/domain/scoring/multi-objective.js.map +1 -0
  137. package/dist/domain/triage/triage-engine.d.ts +43 -0
  138. package/dist/domain/triage/triage-engine.d.ts.map +1 -0
  139. package/dist/domain/triage/triage-engine.js +317 -0
  140. package/dist/domain/triage/triage-engine.js.map +1 -0
  141. package/dist/domain/triage/turn-envelope.d.ts +17 -0
  142. package/dist/domain/triage/turn-envelope.d.ts.map +1 -0
  143. package/dist/domain/triage/turn-envelope.js +81 -0
  144. package/dist/domain/triage/turn-envelope.js.map +1 -0
  145. package/dist/domain/types/entities.d.ts +303 -0
  146. package/dist/domain/types/entities.d.ts.map +1 -0
  147. package/dist/domain/types/entities.js +6 -0
  148. package/dist/domain/types/entities.js.map +1 -0
  149. package/dist/domain/types/index.d.ts +4 -0
  150. package/dist/domain/types/index.d.ts.map +1 -0
  151. package/dist/domain/types/index.js +2 -0
  152. package/dist/domain/types/index.js.map +1 -0
  153. package/dist/domain/types/schemas.d.ts +346 -0
  154. package/dist/domain/types/schemas.d.ts.map +1 -0
  155. package/dist/domain/types/schemas.js +241 -0
  156. package/dist/domain/types/schemas.js.map +1 -0
  157. package/dist/domain/types/store-port.d.ts +44 -0
  158. package/dist/domain/types/store-port.d.ts.map +1 -0
  159. package/dist/domain/types/store-port.js +6 -0
  160. package/dist/domain/types/store-port.js.map +1 -0
  161. package/dist/index.d.ts +39 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +36 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/infra/gemini-provider.d.ts +28 -0
  166. package/dist/infra/gemini-provider.d.ts.map +1 -0
  167. package/dist/infra/gemini-provider.js +112 -0
  168. package/dist/infra/gemini-provider.js.map +1 -0
  169. package/dist/infra/telemetry.d.ts +51 -0
  170. package/dist/infra/telemetry.d.ts.map +1 -0
  171. package/dist/infra/telemetry.js +100 -0
  172. package/dist/infra/telemetry.js.map +1 -0
  173. package/dist/infrastructure/delegation/provider-error.d.ts +44 -0
  174. package/dist/infrastructure/delegation/provider-error.d.ts.map +1 -0
  175. package/dist/infrastructure/delegation/provider-error.js +179 -0
  176. package/dist/infrastructure/delegation/provider-error.js.map +1 -0
  177. package/dist/infrastructure/gateway/circuit-breaker.d.ts +68 -0
  178. package/dist/infrastructure/gateway/circuit-breaker.d.ts.map +1 -0
  179. package/dist/infrastructure/gateway/circuit-breaker.js +150 -0
  180. package/dist/infrastructure/gateway/circuit-breaker.js.map +1 -0
  181. package/dist/infrastructure/gateway/gateway-dispatch.d.ts +138 -0
  182. package/dist/infrastructure/gateway/gateway-dispatch.d.ts.map +1 -0
  183. package/dist/infrastructure/gateway/gateway-dispatch.js +308 -0
  184. package/dist/infrastructure/gateway/gateway-dispatch.js.map +1 -0
  185. package/dist/infrastructure/hardware/hardware-probe.d.ts +32 -0
  186. package/dist/infrastructure/hardware/hardware-probe.d.ts.map +1 -0
  187. package/dist/infrastructure/hardware/hardware-probe.js +199 -0
  188. package/dist/infrastructure/hardware/hardware-probe.js.map +1 -0
  189. package/dist/infrastructure/local/local-zero-tier.d.ts +47 -0
  190. package/dist/infrastructure/local/local-zero-tier.d.ts.map +1 -0
  191. package/dist/infrastructure/local/local-zero-tier.js +92 -0
  192. package/dist/infrastructure/local/local-zero-tier.js.map +1 -0
  193. package/dist/infrastructure/persistence/memory-store.d.ts +31 -0
  194. package/dist/infrastructure/persistence/memory-store.d.ts.map +1 -0
  195. package/dist/infrastructure/persistence/memory-store.js +87 -0
  196. package/dist/infrastructure/persistence/memory-store.js.map +1 -0
  197. package/dist/infrastructure/persistence/sqlite-store.d.ts +81 -0
  198. package/dist/infrastructure/persistence/sqlite-store.d.ts.map +1 -0
  199. package/dist/infrastructure/persistence/sqlite-store.js +658 -0
  200. package/dist/infrastructure/persistence/sqlite-store.js.map +1 -0
  201. package/dist/infrastructure/pricing/litellm-fetch.d.ts +46 -0
  202. package/dist/infrastructure/pricing/litellm-fetch.d.ts.map +1 -0
  203. package/dist/infrastructure/pricing/litellm-fetch.js +145 -0
  204. package/dist/infrastructure/pricing/litellm-fetch.js.map +1 -0
  205. package/dist/infrastructure/pricing/price-broker.d.ts +56 -0
  206. package/dist/infrastructure/pricing/price-broker.d.ts.map +1 -0
  207. package/dist/infrastructure/pricing/price-broker.js +133 -0
  208. package/dist/infrastructure/pricing/price-broker.js.map +1 -0
  209. package/dist/infrastructure/pricing/pricing-monitor.d.ts +27 -0
  210. package/dist/infrastructure/pricing/pricing-monitor.d.ts.map +1 -0
  211. package/dist/infrastructure/pricing/pricing-monitor.js +46 -0
  212. package/dist/infrastructure/pricing/pricing-monitor.js.map +1 -0
  213. package/dist/infrastructure/telemetry/dataset-limits.d.ts +13 -0
  214. package/dist/infrastructure/telemetry/dataset-limits.d.ts.map +1 -0
  215. package/dist/infrastructure/telemetry/dataset-limits.js +28 -0
  216. package/dist/infrastructure/telemetry/dataset-limits.js.map +1 -0
  217. package/dist/infrastructure/telemetry/dataset-recorder.d.ts +48 -0
  218. package/dist/infrastructure/telemetry/dataset-recorder.d.ts.map +1 -0
  219. package/dist/infrastructure/telemetry/dataset-recorder.js +154 -0
  220. package/dist/infrastructure/telemetry/dataset-recorder.js.map +1 -0
  221. package/dist/infrastructure/telemetry/outcome-limits.d.ts +12 -0
  222. package/dist/infrastructure/telemetry/outcome-limits.d.ts.map +1 -0
  223. package/dist/infrastructure/telemetry/outcome-limits.js +28 -0
  224. package/dist/infrastructure/telemetry/outcome-limits.js.map +1 -0
  225. package/dist/infrastructure/telemetry/outcome-recorder.d.ts +29 -0
  226. package/dist/infrastructure/telemetry/outcome-recorder.d.ts.map +1 -0
  227. package/dist/infrastructure/telemetry/outcome-recorder.js +49 -0
  228. package/dist/infrastructure/telemetry/outcome-recorder.js.map +1 -0
  229. package/dist/infrastructure/telemetry/routing-telemetry.d.ts +115 -0
  230. package/dist/infrastructure/telemetry/routing-telemetry.d.ts.map +1 -0
  231. package/dist/infrastructure/telemetry/routing-telemetry.js +529 -0
  232. package/dist/infrastructure/telemetry/routing-telemetry.js.map +1 -0
  233. package/dist/infrastructure/telemetry/telemetry-limits.d.ts +16 -0
  234. package/dist/infrastructure/telemetry/telemetry-limits.d.ts.map +1 -0
  235. package/dist/infrastructure/telemetry/telemetry-limits.js +35 -0
  236. package/dist/infrastructure/telemetry/telemetry-limits.js.map +1 -0
  237. package/package.json +110 -0
  238. package/skills/router-backlog-orchestrator/SKILL.md +183 -0
  239. package/skills/router-backlog-orchestrator/references/github-router-issue-template.md +78 -0
  240. package/skills/router-backlog-orchestrator/references/packet-from-issue.md +99 -0
  241. package/skills/router-backlog-orchestrator/references/prioritization-rubric.md +65 -0
  242. package/skills/router-backlog-orchestrator/scripts/collect-backlog.sh +44 -0
  243. package/specs/001-build-smart-router/contracts/telemetry-contrib.schema.json +151 -0
  244. package/src/api/explain/.gitkeep +0 -0
  245. package/src/api/explain/router-explain.ts +146 -0
  246. package/src/api/middleware/.gitkeep +0 -0
  247. package/src/api/middleware/pi-router-middleware.ts +169 -0
  248. package/src/cli/smart-router-cli.ts +436 -0
  249. package/src/config/.gitkeep +0 -0
  250. package/src/config/defaults.ts +35 -0
  251. package/src/config/models-loader.ts +68 -0
  252. package/src/config/pi-model-mapper.ts +285 -0
  253. package/src/config/routing-clusters-loader.ts +148 -0
  254. package/src/domain/delegation/delegation-context.ts +111 -0
  255. package/src/domain/delegation/execution-ledger.ts +34 -0
  256. package/src/domain/delegation/output-headroom.ts +131 -0
  257. package/src/domain/matching/.gitkeep +0 -0
  258. package/src/domain/matching/cluster-matcher.ts +474 -0
  259. package/src/domain/matching/embedding-provider.ts +79 -0
  260. package/src/domain/matching/hydra-input.ts +53 -0
  261. package/src/domain/matching/hydra-matcher.ts +454 -0
  262. package/src/domain/pinning/.gitkeep +0 -0
  263. package/src/domain/pinning/cache-economics.ts +128 -0
  264. package/src/domain/pinning/loop-escalation.ts +181 -0
  265. package/src/domain/pinning/session-pinner.ts +388 -0
  266. package/src/domain/pinning/sub-route-policy.ts +119 -0
  267. package/src/domain/pipeline/.gitkeep +0 -0
  268. package/src/domain/pipeline/router-pipeline.ts +1139 -0
  269. package/src/domain/pipeline/safe-default.ts +70 -0
  270. package/src/domain/refactor-guardrails.ts +202 -0
  271. package/src/domain/routing/context-fit.ts +221 -0
  272. package/src/domain/routing/expected-cost.ts +320 -0
  273. package/src/domain/routing/p-success-classifier.ts +511 -0
  274. package/src/domain/routing/tier-features.ts +290 -0
  275. package/src/domain/routing/tool-history-guard.ts +159 -0
  276. package/src/domain/scoring/.gitkeep +0 -0
  277. package/src/domain/scoring/multi-objective.ts +175 -0
  278. package/src/domain/triage/.gitkeep +0 -0
  279. package/src/domain/triage/triage-engine.ts +373 -0
  280. package/src/domain/triage/turn-envelope.ts +104 -0
  281. package/src/domain/types/.gitkeep +0 -0
  282. package/src/domain/types/entities.ts +384 -0
  283. package/src/domain/types/index.ts +41 -0
  284. package/src/domain/types/schemas.ts +289 -0
  285. package/src/domain/types/store-port.ts +59 -0
  286. package/src/index.ts +103 -0
  287. package/src/infra/gemini-provider.ts +142 -0
  288. package/src/infra/telemetry.ts +169 -0
  289. package/src/infrastructure/delegation/provider-error.ts +251 -0
  290. package/src/infrastructure/gateway/.gitkeep +0 -0
  291. package/src/infrastructure/gateway/circuit-breaker.ts +196 -0
  292. package/src/infrastructure/gateway/gateway-dispatch.ts +444 -0
  293. package/src/infrastructure/hardware/.gitkeep +0 -0
  294. package/src/infrastructure/hardware/hardware-probe.ts +276 -0
  295. package/src/infrastructure/local/.gitkeep +0 -0
  296. package/src/infrastructure/local/local-zero-tier.ts +151 -0
  297. package/src/infrastructure/persistence/.gitkeep +0 -0
  298. package/src/infrastructure/persistence/memory-store.ts +122 -0
  299. package/src/infrastructure/persistence/sqlite-store.ts +900 -0
  300. package/src/infrastructure/pricing/.gitkeep +0 -0
  301. package/src/infrastructure/pricing/litellm-fetch.ts +215 -0
  302. package/src/infrastructure/pricing/price-broker.ts +183 -0
  303. package/src/infrastructure/pricing/pricing-monitor.ts +65 -0
  304. package/src/infrastructure/telemetry/.gitkeep +0 -0
  305. package/src/infrastructure/telemetry/dataset-limits.ts +39 -0
  306. package/src/infrastructure/telemetry/dataset-recorder.ts +215 -0
  307. package/src/infrastructure/telemetry/outcome-limits.ts +42 -0
  308. package/src/infrastructure/telemetry/outcome-recorder.ts +118 -0
  309. package/src/infrastructure/telemetry/routing-telemetry.ts +824 -0
  310. package/src/infrastructure/telemetry/telemetry-limits.ts +50 -0
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "pi-smart-router",
3
+ "version": "0.1.0",
4
+ "description": "Auto-model router middleware for the pi.dev coding agent",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "pi-package",
9
+ "pi-extension",
10
+ "pi",
11
+ "smart-router",
12
+ "routing",
13
+ "ai",
14
+ "agent"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/beettlle/pi-smart-router.git"
19
+ },
20
+ "homepage": "https://github.com/beettlle/pi-smart-router#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/beettlle/pi-smart-router/issues"
23
+ },
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "bin": {
28
+ "pi-smart-router": "./bin/pi-smart-router.mjs"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js"
34
+ }
35
+ },
36
+ "main": "./dist/index.js",
37
+ "types": "./dist/index.d.ts",
38
+ "files": [
39
+ "dist",
40
+ "src",
41
+ "bin",
42
+ ".pi/extensions/smart-router",
43
+ "!.pi/extensions/smart-router/node_modules",
44
+ "!.pi/extensions/smart-router/node_modules/**",
45
+ "!.pi/extensions/smart-router/package-lock.json",
46
+ "config",
47
+ "skills",
48
+ "specs/001-build-smart-router/contracts/telemetry-contrib.schema.json",
49
+ "data/contrib/example.json"
50
+ ],
51
+ "scripts": {
52
+ "build": "tsc --project tsconfig.build.json",
53
+ "prepublishOnly": "npm run release:check",
54
+ "release:check": "npm run verify:ci",
55
+ "typecheck": "tsc --noEmit",
56
+ "test": "vitest run",
57
+ "coverage:check": "vitest run --coverage",
58
+ "lint": "eslint . --ext .ts && node --input-type=module -e \"import { readFileSync } from 'node:fs'; import { parse } from 'yaml'; const doc = parse(readFileSync('config/models.yaml.example', 'utf8')); if (!Array.isArray(doc.models) || doc.models.length < 3) throw new Error('models.yaml.example must list at least one model per tier'); const tiers = new Set(doc.models.map((m) => m.tier)); for (const tier of ['zero-tier', 'economical-cloud', 'frontier-cloud']) { if (!tiers.has(tier)) throw new Error('missing tier: ' + tier); } console.log('models.yaml.example: valid');\"",
59
+ "routing:bootstrap-centroids": "node --experimental-strip-types scripts/bootstrap-routing-centroids.ts",
60
+ "routing:calibration-aggregate": "node --experimental-strip-types scripts/calibration-aggregate.ts",
61
+ "routing:train-calibration": "node --experimental-strip-types scripts/train-routing-calibration.ts",
62
+ "routing:verify-calibration": "npm run build && node --experimental-strip-types scripts/verify-routing-calibration.ts",
63
+ "routing:test-projection": "npm run build && node --experimental-strip-types scripts/test-hydra-projection.ts",
64
+ "verify:ci": "npm run build && npm run typecheck && npm run lint && npm test && npm run coverage:check"
65
+ },
66
+ "peerDependencies": {
67
+ "@earendil-works/pi-ai": "*",
68
+ "@earendil-works/pi-coding-agent": "*"
69
+ },
70
+ "peerDependenciesMeta": {
71
+ "@earendil-works/pi-ai": {
72
+ "optional": true
73
+ },
74
+ "@earendil-works/pi-coding-agent": {
75
+ "optional": true
76
+ }
77
+ },
78
+ "devDependencies": {
79
+ "@earendil-works/pi-coding-agent": "^0.80.3",
80
+ "@types/better-sqlite3": "^7.6.13",
81
+ "@types/node": "^22.15.21",
82
+ "@typescript-eslint/eslint-plugin": "^8.62.1",
83
+ "@typescript-eslint/parser": "^8.62.1",
84
+ "ajv": "^8.20.0",
85
+ "ajv-formats": "^3.0.1",
86
+ "eslint": "^8.57.1",
87
+ "typescript": "^5.8.3",
88
+ "@vitest/coverage-v8": "^3.2.3",
89
+ "vitest": "^3.2.3",
90
+ "yaml": "^2.9.0"
91
+ },
92
+ "dependencies": {
93
+ "@earendil-works/pi-ai": "^0.80.3",
94
+ "@huggingface/transformers": "^4.2.0",
95
+ "better-sqlite3": "^12.11.1",
96
+ "zod": "^4.4.3"
97
+ },
98
+ "allowScripts": {
99
+ "better-sqlite3@12.11.1": true
100
+ },
101
+ "pi": {
102
+ "extensions": [
103
+ ".pi/extensions/smart-router/index.ts"
104
+ ],
105
+ "skills": [
106
+ "./skills"
107
+ ],
108
+ "minPiVersion": "0.80.0"
109
+ }
110
+ }
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: router-backlog-orchestrator
3
+ description: Plans and executes the next pi-smart-router development cycle from GitHub issues and spine backlog. Prioritizes documentation first, then bugs, then features at one feature per 3-5 bugs. Creates SP-* task packets, runs spine batch with monitoring, and files issues on beettlle/pi-spine or beettlle/pi-smart-router as appropriate.
4
+ disable-model-invocation: true
5
+ compatibility: Requires gh CLI, spine CLI, git, Node >= 20. Run from repo root on main.
6
+ ---
7
+
8
+ # Router Backlog Orchestrator
9
+
10
+ Orchestrates **backlog triage → spine packet authoring → batch execution → issue filing** for [pi-smart-router](https://github.com/beettlle/pi-smart-router).
11
+
12
+ Invoke explicitly: `/skill:router-backlog-orchestrator`
13
+
14
+ **Compose with:**
15
+ - pi-spine `create-spine-tasks` skill — packet structure and size rules
16
+ - [`skills/spine-autonomous-operator/SKILL.md`](../spine-autonomous-operator/SKILL.md) — preflight, wave loop, recovery, pi-spine issue filing
17
+ - [`.cursor/rules/spine-task-authoring.mdc`](../../.cursor/rules/spine-task-authoring.mdc) — PROMPT/STATUS contracts
18
+ - [`.cursor/rules/spine-operator-cursor.mdc`](../../.cursor/rules/spine-operator-cursor.mdc) — spine CLI reference
19
+
20
+ ## Success criteria
21
+
22
+ 1. Backlog plan approved by operator before batch start
23
+ 2. Documentation issues processed before bugs; feature ratio **1 per 3–5 bugs**
24
+ 3. New `SP-*` packets validate (`spine tasks validate pending`)
25
+ 4. Queued scope lands on `main` via gate + integrate
26
+ 5. Linked GitHub issues commented/closed when tasks complete
27
+ 6. Engine faults filed at [pi-spine issues](https://github.com/beettlle/pi-spine/issues); product defects at [pi-smart-router issues](https://github.com/beettlle/pi-smart-router/issues)
28
+
29
+ ## Hard rules
30
+
31
+ - **Never** hand-edit `.spine/batch-state.json` or `.spine/runtime/**`
32
+ - **Never** start a batch without operator approval of the backlog plan table
33
+ - **Never** claim batch/test success without CLI output
34
+ - **Never** create XL tasks; split epics into S/M packets
35
+ - **Always** run docs bucket completely before bug/feature ratio units
36
+ - **Always** link packets to GitHub issues in `## Source`
37
+
38
+ ## Phase 0 — Baseline
39
+
40
+ ```bash
41
+ cd <repo-root>
42
+ gh auth status
43
+ spine --version && spine doctor
44
+ git status && git branch --show-current # must be main
45
+ ```
46
+
47
+ Stop if not on `main` or `gh`/`spine` unavailable.
48
+
49
+ Optional snapshot:
50
+
51
+ ```bash
52
+ skills/router-backlog-orchestrator/scripts/collect-backlog.sh
53
+ ```
54
+
55
+ ## Phase 1 — Collect backlog
56
+
57
+ **GitHub:**
58
+
59
+ ```bash
60
+ gh issue list --repo beettlle/pi-smart-router --state open --limit 100 \
61
+ --json number,title,labels,body,url,createdAt
62
+ ```
63
+
64
+ **Local spine:**
65
+
66
+ ```bash
67
+ spine plan pending
68
+ spine plan all
69
+ ```
70
+
71
+ Scan for orphan packets (PROMPT without `.DONE`). Read [`spine-tasks/CONTEXT.md`](../../spine-tasks/CONTEXT.md) for `Next Task ID`.
72
+
73
+ Write optional authoring snapshot: `spine-tasks/_authoring/backlog-snapshot-YYYYMMDD.md`.
74
+
75
+ ## Phase 2 — Classify and dedupe
76
+
77
+ Use [references/prioritization-rubric.md](references/prioritization-rubric.md).
78
+
79
+ | Bucket | Signals |
80
+ |--------|---------|
81
+ | documentation | label `documentation`, or README/docs/quickstart/operator guide |
82
+ | bug | label `bug`, fix/wiring/regression/P0 audit |
83
+ | feature | label `enhancement`, new capability |
84
+ | epic | title `[Epic]` or multiple deliverables → **split** before authoring |
85
+
86
+ Dedup:
87
+ - Search `spine-tasks/**/PROMPT.md` for `GitHub: beettlle/pi-smart-router#NNN`
88
+ - Skip issues already linked to `.DONE` tasks unless amendment needed
89
+ - Prefer GitHub issue over duplicate orphan PROMPT
90
+
91
+ ## Phase 3 — Prioritize
92
+
93
+ **Order:**
94
+ 1. All **documentation** issues
95
+ 2. **Bugs** — user-facing / CI blockers first, then wiring/refactors; decompose epics
96
+ 3. **Features** — one per ratio unit after every **3–5 bugs**
97
+
98
+ **Default batch scope per invocation:**
99
+ - All open doc tasks first
100
+ - Then **one ratio unit**: 3–5 bugs + 1 feature
101
+ - Repeat until operator stops or backlog empty
102
+
103
+ ## Phase 4 — Operator approval
104
+
105
+ Present a **Backlog Plan** table before any writes:
106
+
107
+ | Order | Issue | Bucket | Proposed SP-ID | Size | Notes |
108
+ |-------|-------|--------|----------------|------|-------|
109
+
110
+ Include ratio summary (e.g. "4 bugs + 1 feature this cycle"). **Stop** until operator approves.
111
+
112
+ ## Phase 5 — Author spine packets
113
+
114
+ Follow [references/packet-from-issue.md](references/packet-from-issue.md) and `create-spine-tasks`:
115
+
116
+ 1. Allocate IDs from `Next Task ID` in `spine-tasks/CONTEXT.md`
117
+ 2. Create `spine-tasks/SP-0xx-slug/PROMPT.md` + `STATUS.md`
118
+ 3. Add `## Source` with GitHub link and bucket
119
+ 4. Update `spine-tasks/dependencies.json` (serialize hot files: `.pi/extensions/smart-router/index.ts`, `src/domain/pipeline/router-pipeline.ts`)
120
+ 5. Validate:
121
+
122
+ ```bash
123
+ spine tasks validate pending
124
+ spine tasks analyze pending
125
+ spine plan pending
126
+ ```
127
+
128
+ 6. Commit on `main`:
129
+
130
+ ```bash
131
+ git add spine-tasks/
132
+ git commit -m "chore(spine): queue SP-0xx+ from backlog orchestrator"
133
+ ```
134
+
135
+ ## Phase 6 — Execute spine batch
136
+
137
+ Hand off to [`skills/spine-autonomous-operator/SKILL.md`](../spine-autonomous-operator/SKILL.md) **Phase 2 onward**:
138
+
139
+ - `spine preflight` (green required)
140
+ - Wave loop: `spine batch start pending --wave N --attached`
141
+ - Monitor: `spine status --diagnose`, `spine wait`
142
+ - Land: `spine gate approve` → `spine integrate` → `npm install` → `npm run verify:ci` → `spine batch complete`
143
+
144
+ Do not advance waves until current wave is integrated on `main`.
145
+
146
+ ## Phase 7 — Issue filing
147
+
148
+ | Situation | Repo | Action |
149
+ |-----------|------|--------|
150
+ | Repeatable spine fault after `suggestedCommand` | beettlle/pi-spine | `spine issue draft --create` or template in spine-autonomous-operator |
151
+ | Product bug / regression found during work | beettlle/pi-smart-router | [references/github-router-issue-template.md](references/github-router-issue-template.md) |
152
+ | Task lands (.DONE + integrate) | beettlle/pi-smart-router | Comment summary + **close** linked issue if acceptance met |
153
+
154
+ Search existing issues before creating duplicates.
155
+
156
+ ## Phase 8 — Final report
157
+
158
+ 1. Backlog plan executed (issue → SP mapping)
159
+ 2. Ratio achieved (bugs vs features)
160
+ 3. GitHub issues opened/closed/commented (URLs)
161
+ 4. Spine recovery actions
162
+ 5. Verification: `spine plan pending`, `spine preflight`, `npm run verify:ci` — **block success on any failure**
163
+ 6. Remaining backlog preview for next invocation
164
+
165
+ **Final report verification template** — list each CI step pass/fail:
166
+
167
+ | Step | Command | Result |
168
+ |------|---------|--------|
169
+ | Build | `npm run build` | pass / fail |
170
+ | Typecheck | `npm run typecheck` | pass / fail |
171
+ | Lint | `npm run lint` | pass / fail |
172
+ | Test | `npm test` | pass / fail |
173
+ | Coverage | `npm run coverage:check` | pass / fail |
174
+
175
+ Do not claim orchestrator success unless `npm run verify:ci` exits 0 and the table is included in the report.
176
+
177
+ ## Short prompt (resume)
178
+
179
+ ```text
180
+ Run router-backlog-orchestrator: collect GitHub + spine backlog → classify →
181
+ prioritize (docs first, 3-5 bugs + 1 feature) → show plan → author SP packets →
182
+ spine preflight → batch waves → file issues → final report.
183
+ ```
@@ -0,0 +1,78 @@
1
+ # pi-smart-router GitHub issue template
2
+
3
+ File product bugs and gaps at https://github.com/beettlle/pi-smart-router/issues
4
+
5
+ Search existing issues before creating.
6
+
7
+ ## Title format
8
+
9
+ ```text
10
+ [bug] Short description
11
+ [docs] Short description
12
+ [enhancement] Short description
13
+ ```
14
+
15
+ ## Body template
16
+
17
+ ```markdown
18
+ ## Summary
19
+
20
+ One paragraph describing the problem or gap.
21
+
22
+ ## Environment
23
+
24
+ - pi-smart-router: `<git rev-parse --short HEAD>`
25
+ - pi: `pi --version`
26
+ - Node: `node --version`
27
+ - Provider/model (if routing): e.g. smart-router/auto → gemini-flash
28
+
29
+ ## Steps to reproduce
30
+
31
+ 1. ...
32
+ 2. ...
33
+
34
+ ## Expected
35
+
36
+ ...
37
+
38
+ ## Actual
39
+
40
+ ...
41
+
42
+ ## Spine task (if any)
43
+
44
+ - SP-0xx-slug (link or path)
45
+ - Batch ID: `.spine/runtime/...` (if applicable)
46
+
47
+ ## Verification
48
+
49
+ Commands that demonstrate fix or repro:
50
+
51
+ ```bash
52
+ npm run typecheck && npm test
53
+ ```
54
+
55
+ ## Labels
56
+
57
+ - `bug` | `documentation` | `enhancement`
58
+ ```
59
+
60
+ ## Create via gh
61
+
62
+ ```bash
63
+ gh issue create --repo beettlle/pi-smart-router \
64
+ --title "[bug] ..." \
65
+ --label bug \
66
+ --body-file /tmp/issue-body.md
67
+ ```
68
+
69
+ ## Close linked issue after SP task lands
70
+
71
+ ```bash
72
+ gh issue comment 13 --repo beettlle/pi-smart-router \
73
+ --body "Fixed in SP-047, integrated on main. Verification: npm run typecheck && npm test."
74
+
75
+ gh issue close 13 --repo beettlle/pi-smart-router --reason completed
76
+ ```
77
+
78
+ Only close when acceptance criteria from the issue are met and verification output is attached or referenced.
@@ -0,0 +1,99 @@
1
+ # Spine packet from GitHub issue
2
+
3
+ Map GitHub issue fields → `spine-tasks/SP-0xx-slug/PROMPT.md`.
4
+
5
+ ## PROMPT skeleton
6
+
7
+ ```markdown
8
+ # Task: SP-0xx — Short Slug
9
+
10
+ **Created:** YYYY-MM-DD
11
+ **Size:** S|M
12
+
13
+ ## Review Level: 1
14
+
15
+ **Assessment:** One-line scope from issue title.
16
+ **Score:** N/8
17
+
18
+ ## Source
19
+
20
+ - GitHub: beettlle/pi-smart-router#NNN
21
+ - Bucket: documentation|bug|feature
22
+
23
+ ## Mission
24
+
25
+ (Paste or distill issue body — acceptance criteria as prose.)
26
+
27
+ ## Dependencies
28
+
29
+ - SP-0yy # prior task if hot-file or logical order
30
+
31
+ ## Context to Read First
32
+
33
+ - (paths from issue + codebase search)
34
+
35
+ ## File Scope
36
+
37
+ | Scope | Paths |
38
+ |-------|-------|
39
+ | Must change | `path/to/file.ts` |
40
+ | Must NOT change | `src/domain/**` |
41
+
42
+ ## Contract
43
+
44
+ | Field | Value |
45
+ |-------|-------|
46
+ | testCommand | `npm run verify:ci` |
47
+ | fileScopeMustChange | `path/to/primary/file.ts` |
48
+ | fileScopeMustNotChange | `src/domain/**` |
49
+ | completionCriteria | (from issue acceptance criteria) |
50
+
51
+ ## Steps
52
+
53
+ ### Step 1: ...
54
+
55
+ - [ ] ...
56
+
57
+ ### Step 2: Testing and verification
58
+
59
+ - [ ] Run `npm run verify:ci`
60
+ - [ ] (issue-specific checks)
61
+
62
+ ## Completion Criteria
63
+
64
+ - [ ] (bullet list mirroring issue)
65
+ ```
66
+
67
+ ## Field mapping
68
+
69
+ | GitHub | PROMPT section |
70
+ |--------|----------------|
71
+ | `title` | `# Task: SP-0xx —` suffix; Review Level assessment |
72
+ | `body` | Mission, Steps, Completion Criteria |
73
+ | `labels` | Source bucket; hints for File Scope |
74
+ | `number` | `## Source` link |
75
+
76
+ ## STATUS.md
77
+
78
+ Use template from `.cursor/rules/taskplane/status-template.md`. Initialize all checkboxes unchecked.
79
+
80
+ ## dependencies.json
81
+
82
+ Add edge `"SP-0xx": ["SP-0yy"]` matching PROMPT `## Dependencies`.
83
+
84
+ ## CONTEXT.md
85
+
86
+ After creating packets:
87
+ - Bump `Next Task ID`
88
+ - Add phase table row(s) for new tasks
89
+ - Update `Last Updated` date
90
+
91
+ ## Validation
92
+
93
+ ```bash
94
+ spine tasks validate pending
95
+ spine tasks analyze pending
96
+ spine plan pending
97
+ ```
98
+
99
+ Fix contract paths: no trailing `/`, no parenthetical path comments.
@@ -0,0 +1,65 @@
1
+ # Backlog prioritization rubric
2
+
3
+ Use when classifying and ordering work in `router-backlog-orchestrator`.
4
+
5
+ ## Buckets
6
+
7
+ ### documentation
8
+
9
+ - GitHub label: `documentation`
10
+ - Title/body mentions: README, quickstart, operator guide, env vars, install, dogfooding
11
+ - **Always first** in every orchestrator run — process all open doc issues before bugs
12
+
13
+ ### bug
14
+
15
+ - GitHub label: `bug`
16
+ - Keywords: fix, wiring, regression, P0, audit gap, fails, error, crash, missing
17
+ - Secondary sort (after docs):
18
+ 1. User-facing / session-breaking (routing failures, failover, auth)
19
+ 2. CI / verification blockers (lint, typecheck, missing build script)
20
+ 3. Correctness / spec drift (pipeline order, ghost layers, swallowed errors)
21
+ 4. Internal refactors that unblock other bugs
22
+
23
+ ### feature
24
+
25
+ - GitHub label: `enhancement` (without `documentation` primary intent)
26
+ - New commands, dataset recording, platform support, build tooling enhancements
27
+
28
+ ### epic
29
+
30
+ - Title contains `[Epic]` or body lists multiple independent deliverables
31
+ - **Never** one SP packet — split into S/M tasks with explicit dependencies
32
+ - Example: privacy dataset epic → schema → store → opt-in → export (serial chain)
33
+
34
+ ## Feature-to-bug ratio
35
+
36
+ After documentation bucket is empty for this cycle:
37
+
38
+ - Queue **3 to 5 bugs**, then **exactly 1 feature**
39
+ - One **ratio unit** per orchestrator invocation (default)
40
+ - If fewer than 3 bugs remain, queue remaining bugs + 1 feature (or 0 features if none left)
41
+
42
+ ## Dedup rules
43
+
44
+ 1. If `PROMPT.md` contains `GitHub: beettlle/pi-smart-router#N` and task has `.DONE`, skip unless issue reopened
45
+ 2. If open issue matches pending SP without `.DONE`, do not duplicate — finish existing packet
46
+ 3. If orphan PROMPT conflicts with GitHub issue, prefer GitHub as source; amend or retire orphan
47
+
48
+ ## Hot-file serialization
49
+
50
+ These paths must not appear in parallel same-wave `fileScopeMustChange`:
51
+
52
+ - `.pi/extensions/smart-router/index.ts`
53
+ - `src/domain/pipeline/router-pipeline.ts`
54
+ - `src/api/middleware/pi-router-middleware.ts`
55
+
56
+ Chain dependencies in `dependencies.json` when multiple tasks touch the same file.
57
+
58
+ ## Size limits
59
+
60
+ | Size | Target | Action |
61
+ |------|--------|--------|
62
+ | S | <2h, ≤4 impl steps | Preferred |
63
+ | M | 2–4h | OK if scope disjoint |
64
+ | L | 4–8h | Split |
65
+ | XL | >8h | Must split |
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # Collect open GitHub issues and local spine backlog snapshot.
3
+ # Usage: from repo root: skills/router-backlog-orchestrator/scripts/collect-backlog.sh
4
+
5
+ set -euo pipefail
6
+
7
+ REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
8
+ cd "$REPO_ROOT"
9
+
10
+ echo "=== pi-smart-router backlog snapshot ==="
11
+ echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
12
+ echo "Repo: $REPO_ROOT"
13
+ echo "Branch: $(git branch --show-current 2>/dev/null || echo unknown)"
14
+ echo ""
15
+
16
+ echo "=== GitHub open issues (beettlle/pi-smart-router) ==="
17
+ if command -v gh >/dev/null 2>&1; then
18
+ gh issue list --repo beettlle/pi-smart-router --state open --limit 100 \
19
+ --json number,title,labels,url,createdAt \
20
+ 2>/dev/null || echo "(gh failed — check auth)"
21
+ else
22
+ echo "(gh not installed)"
23
+ fi
24
+ echo ""
25
+
26
+ echo "=== Spine plan pending ==="
27
+ if command -v spine >/dev/null 2>&1; then
28
+ spine plan pending 2>/dev/null || true
29
+ else
30
+ echo "(spine not installed)"
31
+ fi
32
+ echo ""
33
+
34
+ echo "=== Orphan PROMPT packets (no .DONE) ==="
35
+ find spine-tasks -name PROMPT.md 2>/dev/null | while read -r prompt; do
36
+ dir="$(dirname "$prompt")"
37
+ if [[ ! -f "$dir/.DONE" ]]; then
38
+ echo "$dir"
39
+ fi
40
+ done
41
+
42
+ echo ""
43
+ echo "=== Next Task ID (from CONTEXT.md) ==="
44
+ grep -E '^\*\*Next Task ID:\*\*' spine-tasks/CONTEXT.md 2>/dev/null || echo "(CONTEXT.md not found)"