productfoo 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +338 -2
  3. package/bin/foo +3 -0
  4. package/bin/foo.mjs +42 -0
  5. package/commands/bug.md +31 -0
  6. package/commands/discovery.md +28 -0
  7. package/commands/ideate.md +27 -0
  8. package/commands/init.md +28 -0
  9. package/commands/pitch.md +27 -0
  10. package/commands/preview.md +25 -0
  11. package/commands/research.md +31 -0
  12. package/commands/roast.md +27 -0
  13. package/commands/spec.md +30 -0
  14. package/config/pricing.yaml +198 -0
  15. package/config/routing-policy.yaml +171 -0
  16. package/dist-public/src/activeModel.d.ts +83 -0
  17. package/dist-public/src/activeModel.js +331 -0
  18. package/dist-public/src/agentAdapters.d.ts +122 -0
  19. package/dist-public/src/agentAdapters.js +178 -0
  20. package/dist-public/src/agentState.d.ts +43 -0
  21. package/dist-public/src/agentState.js +177 -0
  22. package/dist-public/src/bugCapsule.d.ts +94 -0
  23. package/dist-public/src/bugCapsule.js +227 -0
  24. package/dist-public/src/bugCapture.d.ts +26 -0
  25. package/dist-public/src/bugCapture.js +251 -0
  26. package/dist-public/src/bugOwnerLog.d.ts +93 -0
  27. package/dist-public/src/bugOwnerLog.js +304 -0
  28. package/dist-public/src/bugReportStore.d.ts +48 -0
  29. package/dist-public/src/bugReportStore.js +860 -0
  30. package/dist-public/src/bugSpecContext.d.ts +7 -0
  31. package/dist-public/src/bugSpecContext.js +129 -0
  32. package/dist-public/src/channelFreshness.d.ts +25 -0
  33. package/dist-public/src/channelFreshness.js +194 -0
  34. package/dist-public/src/cli.d.ts +30 -0
  35. package/dist-public/src/cli.js +1667 -0
  36. package/dist-public/src/cliArgs.d.ts +7 -0
  37. package/dist-public/src/cliArgs.js +44 -0
  38. package/dist-public/src/codeCatalog.d.ts +41 -0
  39. package/dist-public/src/codeCatalog.js +197 -0
  40. package/dist-public/src/commandContract.d.ts +84 -0
  41. package/dist-public/src/commandContract.js +390 -0
  42. package/dist-public/src/commandUsage.d.ts +3 -0
  43. package/dist-public/src/commandUsage.js +30 -0
  44. package/dist-public/src/commands/agent.d.ts +60 -0
  45. package/dist-public/src/commands/agent.js +1353 -0
  46. package/dist-public/src/commands/asp.d.ts +8 -0
  47. package/dist-public/src/commands/asp.js +669 -0
  48. package/dist-public/src/commands/evalCmd.d.ts +4 -0
  49. package/dist-public/src/commands/evalCmd.js +405 -0
  50. package/dist-public/src/commands/login.d.ts +25 -0
  51. package/dist-public/src/commands/login.js +94 -0
  52. package/dist-public/src/commands/loop.d.ts +16 -0
  53. package/dist-public/src/commands/loop.js +619 -0
  54. package/dist-public/src/commands/reconcile.d.ts +41 -0
  55. package/dist-public/src/commands/reconcile.js +292 -0
  56. package/dist-public/src/commands/runtime.d.ts +1 -0
  57. package/dist-public/src/commands/runtime.js +36 -0
  58. package/dist-public/src/commands/scanRedact.d.ts +8 -0
  59. package/dist-public/src/commands/scanRedact.js +266 -0
  60. package/dist-public/src/commands/setup.d.ts +28 -0
  61. package/dist-public/src/commands/setup.js +398 -0
  62. package/dist-public/src/commands/shared.d.ts +17 -0
  63. package/dist-public/src/commands/shared.js +147 -0
  64. package/dist-public/src/commands/source.d.ts +1 -0
  65. package/dist-public/src/commands/source.js +134 -0
  66. package/dist-public/src/commands/specCmd.d.ts +24 -0
  67. package/dist-public/src/commands/specCmd.js +794 -0
  68. package/dist-public/src/commands/update.d.ts +61 -0
  69. package/dist-public/src/commands/update.js +244 -0
  70. package/dist-public/src/comprehensionSignal.d.ts +20 -0
  71. package/dist-public/src/comprehensionSignal.js +166 -0
  72. package/dist-public/src/conductor/diversity.d.ts +48 -0
  73. package/dist-public/src/conductor/diversity.js +423 -0
  74. package/dist-public/src/conductor/engine.d.ts +7 -0
  75. package/dist-public/src/conductor/engine.js +295 -0
  76. package/dist-public/src/conductor/families/ideate.d.ts +2 -0
  77. package/dist-public/src/conductor/families/ideate.js +255 -0
  78. package/dist-public/src/conductor/families/interview.d.ts +2 -0
  79. package/dist-public/src/conductor/families/interview.js +39 -0
  80. package/dist-public/src/conductor/families/specSwarm.d.ts +2 -0
  81. package/dist-public/src/conductor/families/specSwarm.js +146 -0
  82. package/dist-public/src/conductor/familyDelivery.d.ts +6 -0
  83. package/dist-public/src/conductor/familyDelivery.js +37 -0
  84. package/dist-public/src/conductor/familyPackArtifact.d.ts +4 -0
  85. package/dist-public/src/conductor/familyPackArtifact.js +260 -0
  86. package/dist-public/src/conductor/ideateDecision.d.ts +6 -0
  87. package/dist-public/src/conductor/ideateDecision.js +237 -0
  88. package/dist-public/src/conductor/pack.d.ts +26 -0
  89. package/dist-public/src/conductor/pack.js +75 -0
  90. package/dist-public/src/conductor/types.d.ts +111 -0
  91. package/dist-public/src/conductor/types.js +7 -0
  92. package/dist-public/src/configPath.d.ts +2 -0
  93. package/dist-public/src/configPath.js +7 -0
  94. package/dist-public/src/discoveryArtifacts.d.ts +54 -0
  95. package/dist-public/src/discoveryArtifacts.js +467 -0
  96. package/dist-public/src/discoveryCommand.d.ts +127 -0
  97. package/dist-public/src/discoveryCommand.js +2148 -0
  98. package/dist-public/src/discoveryConnections.d.ts +339 -0
  99. package/dist-public/src/discoveryConnections.js +613 -0
  100. package/dist-public/src/discoveryDocs.d.ts +129 -0
  101. package/dist-public/src/discoveryDocs.js +577 -0
  102. package/dist-public/src/discoveryEvidence.d.ts +59 -0
  103. package/dist-public/src/discoveryEvidence.js +198 -0
  104. package/dist-public/src/discoveryFireflies.d.ts +25 -0
  105. package/dist-public/src/discoveryFireflies.js +551 -0
  106. package/dist-public/src/discoveryGmail.d.ts +12 -0
  107. package/dist-public/src/discoveryGmail.js +466 -0
  108. package/dist-public/src/discoveryGong.d.ts +12 -0
  109. package/dist-public/src/discoveryGong.js +491 -0
  110. package/dist-public/src/discoveryLearningRouting.d.ts +90 -0
  111. package/dist-public/src/discoveryLearningRouting.js +405 -0
  112. package/dist-public/src/discoveryMatching.d.ts +26 -0
  113. package/dist-public/src/discoveryMatching.js +73 -0
  114. package/dist-public/src/discoveryOutlook.d.ts +12 -0
  115. package/dist-public/src/discoveryOutlook.js +492 -0
  116. package/dist-public/src/discoveryProcess.d.ts +221 -0
  117. package/dist-public/src/discoveryProcess.js +703 -0
  118. package/dist-public/src/discoveryProof.d.ts +143 -0
  119. package/dist-public/src/discoveryProof.js +529 -0
  120. package/dist-public/src/discoveryProviders.d.ts +152 -0
  121. package/dist-public/src/discoveryProviders.js +756 -0
  122. package/dist-public/src/discoveryReadiness.d.ts +219 -0
  123. package/dist-public/src/discoveryReadiness.js +672 -0
  124. package/dist-public/src/discoveryReconcile.d.ts +57 -0
  125. package/dist-public/src/discoveryReconcile.js +424 -0
  126. package/dist-public/src/discoverySlack.d.ts +12 -0
  127. package/dist-public/src/discoverySlack.js +452 -0
  128. package/dist-public/src/discoverySources.d.ts +56 -0
  129. package/dist-public/src/discoverySources.js +322 -0
  130. package/dist-public/src/discoverySync.d.ts +52 -0
  131. package/dist-public/src/discoverySync.js +151 -0
  132. package/dist-public/src/discoverySynthesis.d.ts +57 -0
  133. package/dist-public/src/discoverySynthesis.js +215 -0
  134. package/dist-public/src/discoveryTeams.d.ts +12 -0
  135. package/dist-public/src/discoveryTeams.js +516 -0
  136. package/dist-public/src/discoveryZoom.d.ts +12 -0
  137. package/dist-public/src/discoveryZoom.js +523 -0
  138. package/dist-public/src/elicitationSurface.d.ts +13 -0
  139. package/dist-public/src/elicitationSurface.js +77 -0
  140. package/dist-public/src/errorReport.d.ts +99 -0
  141. package/dist-public/src/errorReport.js +443 -0
  142. package/dist-public/src/errorTaxonomy.d.ts +84 -0
  143. package/dist-public/src/errorTaxonomy.js +189 -0
  144. package/dist-public/src/evalCalibration.d.ts +82 -0
  145. package/dist-public/src/evalCalibration.js +169 -0
  146. package/dist-public/src/evalChecks.d.ts +21 -0
  147. package/dist-public/src/evalChecks.js +295 -0
  148. package/dist-public/src/evalCompile.d.ts +56 -0
  149. package/dist-public/src/evalCompile.js +58 -0
  150. package/dist-public/src/evalImprove.d.ts +60 -0
  151. package/dist-public/src/evalImprove.js +175 -0
  152. package/dist-public/src/evalJudge.d.ts +47 -0
  153. package/dist-public/src/evalJudge.js +143 -0
  154. package/dist-public/src/evalLabels.d.ts +100 -0
  155. package/dist-public/src/evalLabels.js +287 -0
  156. package/dist-public/src/evalRecord.d.ts +68 -0
  157. package/dist-public/src/evalRecord.js +165 -0
  158. package/dist-public/src/evalRoast.d.ts +88 -0
  159. package/dist-public/src/evalRoast.js +249 -0
  160. package/dist-public/src/evidenceIntake.d.ts +66 -0
  161. package/dist-public/src/evidenceIntake.js +356 -0
  162. package/dist-public/src/feedback.d.ts +78 -0
  163. package/dist-public/src/feedback.js +294 -0
  164. package/dist-public/src/firefliesClient.d.ts +106 -0
  165. package/dist-public/src/firefliesClient.js +258 -0
  166. package/dist-public/src/firstMoveTensions.d.ts +10 -0
  167. package/dist-public/src/firstMoveTensions.js +93 -0
  168. package/dist-public/src/gitRun.d.ts +21 -0
  169. package/dist-public/src/gitRun.js +50 -0
  170. package/dist-public/src/githubReconcile.d.ts +94 -0
  171. package/dist-public/src/githubReconcile.js +205 -0
  172. package/dist-public/src/gmailNango.d.ts +131 -0
  173. package/dist-public/src/gmailNango.js +329 -0
  174. package/dist-public/src/gongNango.d.ts +118 -0
  175. package/dist-public/src/gongNango.js +308 -0
  176. package/dist-public/src/grammarGate.d.ts +13 -0
  177. package/dist-public/src/grammarGate.js +72 -0
  178. package/dist-public/src/harnessGates.d.ts +65 -0
  179. package/dist-public/src/harnessGates.js +168 -0
  180. package/dist-public/src/humanSurfaceEval.d.ts +19 -0
  181. package/dist-public/src/humanSurfaceEval.js +156 -0
  182. package/dist-public/src/ideate.d.ts +43 -0
  183. package/dist-public/src/ideate.js +255 -0
  184. package/dist-public/src/ideateContext.d.ts +11 -0
  185. package/dist-public/src/ideateContext.js +83 -0
  186. package/dist-public/src/index.d.ts +2 -0
  187. package/dist-public/src/index.js +4 -0
  188. package/dist-public/src/initCommand.d.ts +25 -0
  189. package/dist-public/src/initCommand.js +558 -0
  190. package/dist-public/src/interviewGate.d.ts +25 -0
  191. package/dist-public/src/interviewGate.js +126 -0
  192. package/dist-public/src/jsonFile.d.ts +2 -0
  193. package/dist-public/src/jsonFile.js +22 -0
  194. package/dist-public/src/loopBudget.d.ts +182 -0
  195. package/dist-public/src/loopBudget.js +494 -0
  196. package/dist-public/src/loopContracts.d.ts +35 -0
  197. package/dist-public/src/loopContracts.js +364 -0
  198. package/dist-public/src/machineState.d.ts +1 -0
  199. package/dist-public/src/machineState.js +9 -0
  200. package/dist-public/src/notionNango.d.ts +93 -0
  201. package/dist-public/src/notionNango.js +279 -0
  202. package/dist-public/src/orchestrationResult.d.ts +11 -0
  203. package/dist-public/src/orchestrationResult.js +73 -0
  204. package/dist-public/src/outlookNango.d.ts +124 -0
  205. package/dist-public/src/outlookNango.js +327 -0
  206. package/dist-public/src/packetCorrections.d.ts +40 -0
  207. package/dist-public/src/packetCorrections.js +172 -0
  208. package/dist-public/src/packetGlossary.d.ts +6 -0
  209. package/dist-public/src/packetGlossary.js +42 -0
  210. package/dist-public/src/packetIndex.d.ts +54 -0
  211. package/dist-public/src/packetIndex.js +744 -0
  212. package/dist-public/src/packetIndexEntry.d.ts +3 -0
  213. package/dist-public/src/packetIndexEntry.js +128 -0
  214. package/dist-public/src/packetIndexServe.d.ts +13 -0
  215. package/dist-public/src/packetIndexServe.js +113 -0
  216. package/dist-public/src/packetIndexWorker.d.ts +7 -0
  217. package/dist-public/src/packetIndexWorker.js +45 -0
  218. package/dist-public/src/packetLifecycle.d.ts +30 -0
  219. package/dist-public/src/packetLifecycle.js +127 -0
  220. package/dist-public/src/packetReconcile.d.ts +73 -0
  221. package/dist-public/src/packetReconcile.js +386 -0
  222. package/dist-public/src/packetStatus.d.ts +125 -0
  223. package/dist-public/src/packetStatus.js +770 -0
  224. package/dist-public/src/packetValidation.d.ts +17 -0
  225. package/dist-public/src/packetValidation.js +333 -0
  226. package/dist-public/src/packetVerify.d.ts +73 -0
  227. package/dist-public/src/packetVerify.js +303 -0
  228. package/dist-public/src/packetWrite.d.ts +52 -0
  229. package/dist-public/src/packetWrite.js +448 -0
  230. package/dist-public/src/pitch.d.ts +38 -0
  231. package/dist-public/src/pitch.js +154 -0
  232. package/dist-public/src/processMemo.d.ts +8 -0
  233. package/dist-public/src/processMemo.js +23 -0
  234. package/dist-public/src/productDetect.d.ts +30 -0
  235. package/dist-public/src/productDetect.js +376 -0
  236. package/dist-public/src/profile.d.ts +62 -0
  237. package/dist-public/src/profile.js +334 -0
  238. package/dist-public/src/questionModel.d.ts +46 -0
  239. package/dist-public/src/questionModel.js +74 -0
  240. package/dist-public/src/questionText.d.ts +7 -0
  241. package/dist-public/src/questionText.js +38 -0
  242. package/dist-public/src/redactConfig.d.ts +2 -0
  243. package/dist-public/src/redactConfig.js +11 -0
  244. package/dist-public/src/redactEngine.d.ts +59 -0
  245. package/dist-public/src/redactEngine.js +509 -0
  246. package/dist-public/src/redactGate.d.ts +63 -0
  247. package/dist-public/src/redactGate.js +209 -0
  248. package/dist-public/src/repoRead.d.ts +29 -0
  249. package/dist-public/src/repoRead.js +160 -0
  250. package/dist-public/src/research.d.ts +242 -0
  251. package/dist-public/src/research.js +1314 -0
  252. package/dist-public/src/researchCompletion.d.ts +34 -0
  253. package/dist-public/src/researchCompletion.js +123 -0
  254. package/dist-public/src/researchExecution.d.ts +47 -0
  255. package/dist-public/src/researchExecution.js +309 -0
  256. package/dist-public/src/researchFormat.d.ts +21 -0
  257. package/dist-public/src/researchFormat.js +77 -0
  258. package/dist-public/src/researchGate.d.ts +86 -0
  259. package/dist-public/src/researchGate.js +1036 -0
  260. package/dist-public/src/researchReceipt.d.ts +76 -0
  261. package/dist-public/src/researchReceipt.js +148 -0
  262. package/dist-public/src/researchRender.d.ts +2 -0
  263. package/dist-public/src/researchRender.js +267 -0
  264. package/dist-public/src/researchSigningKey.d.ts +19 -0
  265. package/dist-public/src/researchSigningKey.js +95 -0
  266. package/dist-public/src/riskClassify.d.ts +42 -0
  267. package/dist-public/src/riskClassify.js +149 -0
  268. package/dist-public/src/routines.d.ts +42 -0
  269. package/dist-public/src/routines.js +269 -0
  270. package/dist-public/src/routingPolicy.d.ts +172 -0
  271. package/dist-public/src/routingPolicy.js +646 -0
  272. package/dist-public/src/secretInput.d.ts +8 -0
  273. package/dist-public/src/secretInput.js +89 -0
  274. package/dist-public/src/selfCheck.d.ts +7 -0
  275. package/dist-public/src/selfCheck.js +473 -0
  276. package/dist-public/src/selfCheckCache.d.ts +29 -0
  277. package/dist-public/src/selfCheckCache.js +147 -0
  278. package/dist-public/src/severityClass.d.ts +15 -0
  279. package/dist-public/src/severityClass.js +22 -0
  280. package/dist-public/src/skillClientPolicy.d.ts +8 -0
  281. package/dist-public/src/skillClientPolicy.js +16 -0
  282. package/dist-public/src/skillLocal.d.ts +98 -0
  283. package/dist-public/src/skillLocal.js +463 -0
  284. package/dist-public/src/skillTreeDigest.d.ts +9 -0
  285. package/dist-public/src/skillTreeDigest.js +64 -0
  286. package/dist-public/src/slackNango.d.ts +62 -0
  287. package/dist-public/src/slackNango.js +208 -0
  288. package/dist-public/src/social/arxiv.d.ts +19 -0
  289. package/dist-public/src/social/arxiv.js +96 -0
  290. package/dist-public/src/social/github.d.ts +2 -0
  291. package/dist-public/src/social/github.js +78 -0
  292. package/dist-public/src/social/hackernews.d.ts +2 -0
  293. package/dist-public/src/social/hackernews.js +67 -0
  294. package/dist-public/src/social/index.d.ts +10 -0
  295. package/dist-public/src/social/index.js +79 -0
  296. package/dist-public/src/social/reddit.d.ts +2 -0
  297. package/dist-public/src/social/reddit.js +125 -0
  298. package/dist-public/src/social/types.d.ts +73 -0
  299. package/dist-public/src/social/types.js +61 -0
  300. package/dist-public/src/social/xml.d.ts +10 -0
  301. package/dist-public/src/social/xml.js +49 -0
  302. package/dist-public/src/social/youtube.d.ts +7 -0
  303. package/dist-public/src/social/youtube.js +217 -0
  304. package/dist-public/src/sourceIngress.d.ts +488 -0
  305. package/dist-public/src/sourceIngress.js +1651 -0
  306. package/dist-public/src/specAfter.d.ts +187 -0
  307. package/dist-public/src/specAfter.js +814 -0
  308. package/dist-public/src/specBudget.d.ts +124 -0
  309. package/dist-public/src/specBudget.js +424 -0
  310. package/dist-public/src/specDecisionSignals.d.ts +38 -0
  311. package/dist-public/src/specDecisionSignals.js +121 -0
  312. package/dist-public/src/specLinkedCommits.d.ts +7 -0
  313. package/dist-public/src/specLinkedCommits.js +107 -0
  314. package/dist-public/src/specSections.d.ts +105 -0
  315. package/dist-public/src/specSections.js +718 -0
  316. package/dist-public/src/statusGlyphs.d.ts +18 -0
  317. package/dist-public/src/statusGlyphs.js +75 -0
  318. package/dist-public/src/swarmCommand.d.ts +10 -0
  319. package/dist-public/src/swarmCommand.js +96 -0
  320. package/dist-public/src/teamsNango.d.ts +114 -0
  321. package/dist-public/src/teamsNango.js +301 -0
  322. package/dist-public/src/tokenStore.d.ts +10 -0
  323. package/dist-public/src/tokenStore.js +77 -0
  324. package/dist-public/src/trustEnvelope.d.ts +78 -0
  325. package/dist-public/src/trustEnvelope.js +392 -0
  326. package/dist-public/src/untrustedText.d.ts +6 -0
  327. package/dist-public/src/untrustedText.js +20 -0
  328. package/dist-public/src/updateNotice.d.ts +41 -0
  329. package/dist-public/src/updateNotice.js +290 -0
  330. package/dist-public/src/vendorYaml.d.ts +1 -0
  331. package/dist-public/src/vendorYaml.js +7374 -0
  332. package/dist-public/src/workflowRunActuals.d.ts +67 -0
  333. package/dist-public/src/workflowRunActuals.js +184 -0
  334. package/dist-public/src/zendeskDiscovery.d.ts +12 -0
  335. package/dist-public/src/zendeskDiscovery.js +513 -0
  336. package/dist-public/src/zendeskNango.d.ts +131 -0
  337. package/dist-public/src/zendeskNango.js +344 -0
  338. package/dist-public/src/zoomNango.d.ts +106 -0
  339. package/dist-public/src/zoomNango.js +351 -0
  340. package/docs/CHANGELOG.md +32 -0
  341. package/docs/THIRD_PARTY_NOTICES.md +36 -0
  342. package/package.json +71 -4
  343. package/schemas/bug-capsule-receipt.schema.json +54 -0
  344. package/schemas/bug-capsule.schema.json +189 -0
  345. package/schemas/discovery-evidence-envelope.schema.json +79 -0
  346. package/schemas/discovery-processing-receipt.schema.json +71 -0
  347. package/schemas/discovery-service-contract.schema.json +189 -0
  348. package/skills/AGENTS.md +32 -0
  349. package/skills/README.md +287 -0
  350. package/skills/bug/SKILL.md +49 -0
  351. package/skills/build-preview-spec/SKILL.md +103 -0
  352. package/skills/capture-external-artifact/SKILL.md +23 -0
  353. package/skills/capture-external-artifact/agents/openai.yaml +4 -0
  354. package/skills/capture-external-artifact/references/extractor-libraries.md +27 -0
  355. package/skills/check-spec-health/SKILL.md +45 -0
  356. package/skills/check-spec-health/agents/openai.yaml +4 -0
  357. package/skills/competitive-positioning/SKILL.md +86 -0
  358. package/skills/competitive-positioning/agents/openai.yaml +4 -0
  359. package/skills/cpo-lens/SKILL.md +398 -0
  360. package/skills/cpo-lens/agents/openai.yaml +4 -0
  361. package/skills/create-prd/SKILL.md +26 -0
  362. package/skills/create-prd/agents/openai.yaml +4 -0
  363. package/skills/customer-discovery/SKILL.md +192 -0
  364. package/skills/design-system/SKILL.md +49 -0
  365. package/skills/design-system/agents/openai.yaml +4 -0
  366. package/skills/discussion-guide/SKILL.md +75 -0
  367. package/skills/discussion-guide/agents/openai.yaml +4 -0
  368. package/skills/firecrawl-research-papers/SKILL.md +96 -0
  369. package/skills/firecrawl-research-papers/agents/openai.yaml +4 -0
  370. package/skills/foo-roast/SKILL.md +325 -0
  371. package/skills/generate-gtm-brief/SKILL.md +41 -0
  372. package/skills/generate-gtm-brief/agents/openai.yaml +4 -0
  373. package/skills/generate-gtm-brief/references/gtm-brief-template.md +56 -0
  374. package/skills/gong-quotes/SKILL.md +43 -0
  375. package/skills/gong-quotes/agents/openai.yaml +4 -0
  376. package/skills/grill-me/SKILL.md +27 -0
  377. package/skills/grill-me/agents/openai.yaml +4 -0
  378. package/skills/ideate/SKILL.md +180 -0
  379. package/skills/ideate/references/family-packs.md +5 -0
  380. package/skills/initiative-tracker/SKILL.md +23 -0
  381. package/skills/initiative-tracker/agents/openai.yaml +4 -0
  382. package/skills/interop-review/SKILL.md +25 -0
  383. package/skills/interop-review/agents/openai.yaml +4 -0
  384. package/skills/interview-me/SKILL.md +404 -0
  385. package/skills/interview-me/agents/openai.yaml +4 -0
  386. package/skills/loop-library-audit/SKILL.md +123 -0
  387. package/skills/pitch/SKILL.md +110 -0
  388. package/skills/pitch/references/opportunity-assessment.md +136 -0
  389. package/skills/pitch/references/prfaq-template.md +54 -0
  390. package/skills/pmm-release-briefing/SKILL.md +27 -0
  391. package/skills/pmm-release-briefing/agents/openai.yaml +4 -0
  392. package/skills/pmm-release-briefing/references/variant-generalized.md +16 -0
  393. package/skills/positioning-messaging/SKILL.md +70 -0
  394. package/skills/positioning-messaging/agents/openai.yaml +4 -0
  395. package/skills/positioning-messaging/references/guest-insights.md +1400 -0
  396. package/skills/preview-swarm/SKILL.md +418 -0
  397. package/skills/preview-swarm/agents/openai.yaml +4 -0
  398. package/skills/preview-swarm/references/html-effectiveness-build-previews.md +168 -0
  399. package/skills/product-copywriting/SKILL.md +127 -0
  400. package/skills/product-copywriting/agents/openai.yaml +4 -0
  401. package/skills/product-copywriting/references/foo-voice.md +26 -0
  402. package/skills/product-shape-interview/SKILL.md +219 -0
  403. package/skills/product-shape-interview/agents/openai.yaml +4 -0
  404. package/skills/ready-for-release/SKILL.md +39 -0
  405. package/skills/ready-for-release/agents/openai.yaml +4 -0
  406. package/skills/redact-transcripts/SKILL.md +23 -0
  407. package/skills/redact-transcripts/agents/openai.yaml +4 -0
  408. package/skills/research-brief/SKILL.md +48 -0
  409. package/skills/research-brief/agents/openai.yaml +4 -0
  410. package/skills/research-refresh/SKILL.md +63 -0
  411. package/skills/research-refresh/references/worked-cases.md +44 -0
  412. package/skills/review-loop/SKILL.md +200 -0
  413. package/skills/review-spec/SKILL.md +32 -0
  414. package/skills/review-spec/agents/openai.yaml +4 -0
  415. package/skills/rfc-from-research/SKILL.md +42 -0
  416. package/skills/rfc-from-research/agents/openai.yaml +4 -0
  417. package/skills/rfc-from-research/references/rfc-pattern.md +69 -0
  418. package/skills/skill-registry.yaml +810 -0
  419. package/skills/spec-cleanup/SKILL.md +103 -0
  420. package/skills/spec-cleanup/agents/openai.yaml +4 -0
  421. package/skills/spec-swarm/SKILL.md +87 -0
  422. package/skills/spec-swarm/agents/openai.yaml +4 -0
  423. package/skills/spec-swarm/template/SKILL.template.md +94 -0
  424. package/skills/spec-swarm/template/personas/accessibility-inclusion.md +40 -0
  425. package/skills/spec-swarm/template/personas/ai-technical-pm.md +69 -0
  426. package/skills/spec-swarm/template/personas/analytics-engineering.md +39 -0
  427. package/skills/spec-swarm/template/personas/applied-ai-eval.md +64 -0
  428. package/skills/spec-swarm/template/personas/business-gm-pm.md +67 -0
  429. package/skills/spec-swarm/template/personas/consumer-craft-pm.md +68 -0
  430. package/skills/spec-swarm/template/personas/content-design.md +40 -0
  431. package/skills/spec-swarm/template/personas/cpo.md +42 -0
  432. package/skills/spec-swarm/template/personas/data-science.md +42 -0
  433. package/skills/spec-swarm/template/personas/developer-experience.md +65 -0
  434. package/skills/spec-swarm/template/personas/dx-product.md +70 -0
  435. package/skills/spec-swarm/template/personas/field.md +43 -0
  436. package/skills/spec-swarm/template/personas/finance-cfo.md +40 -0
  437. package/skills/spec-swarm/template/personas/growth-pm.md +67 -0
  438. package/skills/spec-swarm/template/personas/platform-pm.md +67 -0
  439. package/skills/spec-swarm/template/personas/pmm.md +43 -0
  440. package/skills/spec-swarm/template/personas/principal-product-designer.md +42 -0
  441. package/skills/spec-swarm/template/personas/product-ops-program.md +41 -0
  442. package/skills/spec-swarm/template/personas/qa-release.md +41 -0
  443. package/skills/spec-swarm/template/personas/responsible-ai-safety.md +64 -0
  444. package/skills/spec-swarm/template/personas/security-privacy-legal.md +40 -0
  445. package/skills/spec-swarm/template/personas/strategy-competitive.md +41 -0
  446. package/skills/spec-swarm/template/personas/technical-architect.md +42 -0
  447. package/skills/spec-swarm/template/personas/technical-lead.md +43 -0
  448. package/skills/spec-swarm/template/personas/user-research.md +41 -0
  449. package/skills/spec-swarm-accessibility-inclusion/SKILL.md +95 -0
  450. package/skills/spec-swarm-accessibility-inclusion/agents/openai.yaml +4 -0
  451. package/skills/spec-swarm-ai-technical-pm/SKILL.md +124 -0
  452. package/skills/spec-swarm-analytics-engineering/SKILL.md +94 -0
  453. package/skills/spec-swarm-analytics-engineering/agents/openai.yaml +4 -0
  454. package/skills/spec-swarm-applied-ai-eval/SKILL.md +120 -0
  455. package/skills/spec-swarm-business-gm-pm/SKILL.md +122 -0
  456. package/skills/spec-swarm-consumer-craft-pm/SKILL.md +122 -0
  457. package/skills/spec-swarm-content-design/SKILL.md +95 -0
  458. package/skills/spec-swarm-content-design/agents/openai.yaml +4 -0
  459. package/skills/spec-swarm-cpo/SKILL.md +94 -0
  460. package/skills/spec-swarm-cpo/agents/openai.yaml +4 -0
  461. package/skills/spec-swarm-data-science/SKILL.md +95 -0
  462. package/skills/spec-swarm-data-science/agents/openai.yaml +4 -0
  463. package/skills/spec-swarm-developer-experience/SKILL.md +121 -0
  464. package/skills/spec-swarm-dx-product/SKILL.md +126 -0
  465. package/skills/spec-swarm-field/SKILL.md +96 -0
  466. package/skills/spec-swarm-field/agents/openai.yaml +4 -0
  467. package/skills/spec-swarm-finance-cfo/SKILL.md +95 -0
  468. package/skills/spec-swarm-finance-cfo/agents/openai.yaml +4 -0
  469. package/skills/spec-swarm-growth-pm/SKILL.md +122 -0
  470. package/skills/spec-swarm-platform-pm/SKILL.md +122 -0
  471. package/skills/spec-swarm-pmm/SKILL.md +96 -0
  472. package/skills/spec-swarm-pmm/agents/openai.yaml +4 -0
  473. package/skills/spec-swarm-principal-product-designer/SKILL.md +95 -0
  474. package/skills/spec-swarm-principal-product-designer/agents/openai.yaml +4 -0
  475. package/skills/spec-swarm-product-ops-program/SKILL.md +96 -0
  476. package/skills/spec-swarm-product-ops-program/agents/openai.yaml +4 -0
  477. package/skills/spec-swarm-qa-release/SKILL.md +96 -0
  478. package/skills/spec-swarm-qa-release/agents/openai.yaml +4 -0
  479. package/skills/spec-swarm-responsible-ai-safety/SKILL.md +120 -0
  480. package/skills/spec-swarm-security-privacy-legal/SKILL.md +95 -0
  481. package/skills/spec-swarm-security-privacy-legal/agents/openai.yaml +4 -0
  482. package/skills/spec-swarm-strategy-competitive/SKILL.md +96 -0
  483. package/skills/spec-swarm-strategy-competitive/agents/openai.yaml +4 -0
  484. package/skills/spec-swarm-technical-architect/SKILL.md +95 -0
  485. package/skills/spec-swarm-technical-architect/agents/openai.yaml +4 -0
  486. package/skills/spec-swarm-technical-lead/SKILL.md +96 -0
  487. package/skills/spec-swarm-technical-lead/agents/openai.yaml +4 -0
  488. package/skills/spec-swarm-user-research/SKILL.md +95 -0
  489. package/skills/spec-swarm-user-research/agents/openai.yaml +4 -0
  490. package/skills/strategy-check/SKILL.md +170 -0
  491. package/skills/strategy-check/agents/openai.yaml +4 -0
  492. package/skills/study-digest/SKILL.md +41 -0
  493. package/skills/synthetic-customer/SKILL.md +68 -0
  494. package/skills/update-cli-spec/SKILL.md +69 -0
  495. package/skills/update-cli-spec/agents/openai.yaml +4 -0
  496. package/skills/voc-researcher/SKILL.md +45 -0
  497. package/skills/voc-researcher/agents/openai.yaml +4 -0
  498. package/skills-lock.json +35 -0
@@ -0,0 +1,83 @@
1
+ export type ModelFamily = string;
2
+ export type ModelConfidence = "confirmed" | "assumed";
3
+ export declare const UNKNOWN_FAMILY = "unknown";
4
+ export declare const UNKNOWN_MODEL = "unknown";
5
+ /**
6
+ * Model families foo default-denies for autonomous work (glm-model-awareness-v0
7
+ * R-005): weaker self-correction makes them a degraded verifier of their own
8
+ * loop, and the inference-egress boundary is not yet in place.
9
+ *
10
+ * This is the ONE source of truth. It used to be an inline `family === "glm"`
11
+ * check in the loop command, which meant `foo estimate` — knowing nothing about
12
+ * it — would cheerfully recommend a cheaper GLM build that `foo loop estimate
13
+ * --agree` then refuses. Any surface that offers a model as an option must be
14
+ * able to ask this question.
15
+ */
16
+ export declare const AUTONOMY_DENIED_FAMILIES: ReadonlySet<string>;
17
+ export declare function autonomyDenied(family: string | undefined | null): boolean;
18
+ export declare const ANTHROPIC_BASE_DEFAULT = "https://api.anthropic.com";
19
+ export type ActiveModel = {
20
+ /** Friendly provider name: e.g. "anthropic" (native), "z.ai", "fireworks", or the host. */
21
+ provider: string;
22
+ /** Coarse model family (data-driven), used for pricing-key canonicalization and family signals. */
23
+ family: ModelFamily;
24
+ /** Resolved worker model id — the pricing/budget key for the acting model. */
25
+ worker: string;
26
+ /** Resolved verifier model id. */
27
+ verifier: string;
28
+ /** confirmed = explicit declaration or genuinely-native; assumed = inferred from a base URL. */
29
+ confidence: ModelConfidence;
30
+ /** Is the harness pointed off its native provider? */
31
+ routed: boolean;
32
+ /** Active API base for the harness's provider (drives count_tokens routing). */
33
+ baseUrl: string;
34
+ /** count_tokens endpoint derived from baseUrl — never a hardcoded provider literal. */
35
+ countTokensUrl: string;
36
+ /** Provenance of the resolution (which signal won). */
37
+ source: string;
38
+ /**
39
+ * Worded, human-readable findings: roster-data degradation and labeled
40
+ * "unknown model" honesty (R-003). Empty when everything resolved cleanly.
41
+ * Plain text only — the caller owns glyph gating.
42
+ */
43
+ findings: string[];
44
+ };
45
+ export type RosterEntry = {
46
+ id: string;
47
+ family: string;
48
+ roles: readonly string[];
49
+ modelMarkers: readonly string[];
50
+ hostMarkers: readonly string[];
51
+ provider: string | null;
52
+ /** Wire format for direct panel calls (multi-model-research-panel-v0 R-005): "anthropic" | "openai" | null. */
53
+ wire: string | null;
54
+ /**
55
+ * Routing tier this model serves (model-orchestrator-v0 R-001). Null when the
56
+ * roster does not place it — the routing policy then resolves it to the
57
+ * conservative tier with a worded finding rather than guessing (R-013).
58
+ */
59
+ routingTier?: string | null;
60
+ /** Optional per-model task-type override; empty means "whatever the tier says". */
61
+ routingTaskTypes?: readonly string[];
62
+ };
63
+ export type ModelRoster = {
64
+ /** Basename of the data file, e.g. "pricing.yaml". */
65
+ source: string;
66
+ /** False when the data file is missing/unreadable — resolution degrades, never blocks. */
67
+ available: boolean;
68
+ nativeProvider: string;
69
+ nativeFamily: string;
70
+ nativeBaseUrl: string;
71
+ nativeHosts: readonly string[];
72
+ multiModelHosts: readonly {
73
+ marker: string;
74
+ provider: string;
75
+ }[];
76
+ entries: readonly RosterEntry[];
77
+ /** Worded degradation findings carried into every resolution. */
78
+ findings: readonly string[];
79
+ };
80
+ export declare function loadModelRoster(root?: string): ModelRoster;
81
+ export declare function deriveCountTokensUrl(baseUrl: string): string;
82
+ export declare function resolveActiveModel(env?: NodeJS.ProcessEnv, roster?: ModelRoster): ActiveModel;
83
+ export declare function describeActiveModel(active: ActiveModel): string | null;
@@ -0,0 +1,331 @@
1
+ // The single authoritative active-model resolver (glm-model-awareness-v0 / T-001,
2
+ // R-001, D-003; data-driven since model-roster-data-v0 R-001).
3
+ //
4
+ // foo silently assumed Anthropic/Opus everywhere a model fact was needed: pricing,
5
+ // loop-budget estimation, and the count_tokens endpoint were all hardcoded to Claude
6
+ // models and api.anthropic.com. But a coding harness (Claude Code first) can be pointed
7
+ // at a different model via a compatible endpoint — concretely GLM served by z.ai
8
+ // (Anthropic-compatible) or Fireworks (OpenAI-compatible). Because of server-side model
9
+ // mapping the harness still reports "Claude", so the active model is invisible and foo
10
+ // emits a confident, Opus-priced, wrong number with no signal it is guessing.
11
+ //
12
+ // D-003 is the load-bearing rule: there is exactly ONE place that resolves the active
13
+ // provider/model, and every model-aware subsystem (pricing, budget key, count_tokens
14
+ // routing, provenance) reads only from it. No second source that can drift from the base
15
+ // URL the harness actually calls. This module is that source.
16
+ //
17
+ // model-roster-data-v0 R-001 moves the *constants* out: the worker/verifier roster,
18
+ // provider host markers, and detection hints live in the committed, dated pricing.yaml
19
+ // (loaded by loadModelRoster), so a model rename or a new provider is a data-only
20
+ // change. The resolver contract — one source, explicit precedence, honest confidence —
21
+ // is unchanged; this module holds zero model-name literals.
22
+ //
23
+ // Precedence (R-001): an explicit declaration wins; inference from the base URL is the
24
+ // fallback; native default (from the data file) is the default.
25
+ // 1. FOO_MODEL / FOO_ACTOR_MODEL (+ FOO_ACTOR_PROVIDER) -> confirmed
26
+ // 2. ANTHROPIC_BASE_URL / OPENAI_BASE_URL off a native host -> inferred, "assumed"
27
+ // 3. nothing routed -> native default, confirmed
28
+ //
29
+ // Confidence is honest by construction: only an explicit foo-level declaration (or the
30
+ // genuinely-native default) is "confirmed". Anything inferred from an endpoint override
31
+ // is "assumed" — because the harness's own model env may not match the provider's
32
+ // server-side mapping — and that drives the ⚠️ provenance tag (R-004 / T-004).
33
+ //
34
+ // Unknown-model honesty (model-roster-data-v0 R-003): a model id absent from the data
35
+ // file resolves as itself with a labeled "unknown model" finding and token-only
36
+ // handling downstream — never a silent fallback to another model's rates (the exact
37
+ // bug class this module was built to kill). A missing/unreadable data file degrades
38
+ // the same way: the resolver never blocks, it gets honest.
39
+ import { existsSync, readFileSync } from "node:fs";
40
+ import { configPath } from "./configPath.js";
41
+ import { parse as parseYaml } from "./vendorYaml.js";
42
+ export const UNKNOWN_FAMILY = "unknown";
43
+ export const UNKNOWN_MODEL = "unknown";
44
+ /**
45
+ * Model families foo default-denies for autonomous work (glm-model-awareness-v0
46
+ * R-005): weaker self-correction makes them a degraded verifier of their own
47
+ * loop, and the inference-egress boundary is not yet in place.
48
+ *
49
+ * This is the ONE source of truth. It used to be an inline `family === "glm"`
50
+ * check in the loop command, which meant `foo estimate` — knowing nothing about
51
+ * it — would cheerfully recommend a cheaper GLM build that `foo loop estimate
52
+ * --agree` then refuses. Any surface that offers a model as an option must be
53
+ * able to ask this question.
54
+ */
55
+ export const AUTONOMY_DENIED_FAMILIES = new Set(["glm"]);
56
+ export function autonomyDenied(family) {
57
+ return typeof family === "string" && AUTONOMY_DENIED_FAMILIES.has(family);
58
+ }
59
+ // Provider label (not a model name) and default base for the case where nothing is
60
+ // routed and the roster itself is unavailable — the harness's native endpoint.
61
+ const NATIVE_PROVIDER_FALLBACK = "anthropic";
62
+ export const ANTHROPIC_BASE_DEFAULT = "https://api.anthropic.com";
63
+ const ROSTER_SOURCE = "pricing.yaml";
64
+ function isObj(value) {
65
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
66
+ }
67
+ function strOf(value) {
68
+ return typeof value === "string" && value.length > 0 ? value : null;
69
+ }
70
+ function strArray(value) {
71
+ if (!Array.isArray(value))
72
+ return [];
73
+ return value.filter((item) => typeof item === "string" && item.length > 0);
74
+ }
75
+ function degradedRoster(finding) {
76
+ return {
77
+ source: ROSTER_SOURCE,
78
+ available: false,
79
+ nativeProvider: NATIVE_PROVIDER_FALLBACK,
80
+ nativeFamily: UNKNOWN_FAMILY,
81
+ nativeBaseUrl: ANTHROPIC_BASE_DEFAULT,
82
+ nativeHosts: [],
83
+ multiModelHosts: [],
84
+ entries: [],
85
+ findings: [finding],
86
+ };
87
+ }
88
+ // Load the model roster (identity, roles, detection) from the committed data file.
89
+ // Missing or unreadable data degrades to an honest "unknown" roster with a worded
90
+ // finding — it never throws, because model *resolution* must never block (D-006:
91
+ // detection is a signal, not a boundary).
92
+ export function loadModelRoster(root = process.cwd()) {
93
+ const file = configPath(root, ROSTER_SOURCE);
94
+ if (!existsSync(file)) {
95
+ return degradedRoster(`model roster unavailable: ${ROSTER_SOURCE} missing at repo root or in config/ — active model resolves as unknown; token-only handling`);
96
+ }
97
+ let doc;
98
+ try {
99
+ doc = parseYaml(readFileSync(file, "utf8"));
100
+ }
101
+ catch (error) {
102
+ return degradedRoster(`model roster unavailable: ${ROSTER_SOURCE} unreadable (${error instanceof Error ? error.message : String(error)}) — active model resolves as unknown; token-only handling`);
103
+ }
104
+ if (!isObj(doc))
105
+ return degradedRoster(`model roster unavailable: ${ROSTER_SOURCE} is not a mapping — active model resolves as unknown; token-only handling`);
106
+ const roster = isObj(doc.roster) ? doc.roster : {};
107
+ const providers = isObj(doc.providers) ? doc.providers : {};
108
+ const models = isObj(doc.models) ? doc.models : {};
109
+ const entries = Object.entries(models).map(([id, raw]) => {
110
+ const model = isObj(raw) ? raw : {};
111
+ const detect = isObj(model.detect) ? model.detect : {};
112
+ const routing = isObj(model.routing) ? model.routing : {};
113
+ return {
114
+ id,
115
+ family: strOf(model.family) ?? UNKNOWN_FAMILY,
116
+ roles: strArray(model.roles),
117
+ modelMarkers: strArray(detect.model_markers).map((m) => m.toLowerCase()),
118
+ hostMarkers: strArray(detect.host_markers).map((m) => m.toLowerCase()),
119
+ provider: strOf(detect.provider),
120
+ wire: strOf(model.wire),
121
+ routingTier: strOf(routing.tier),
122
+ routingTaskTypes: strArray(routing.task_types),
123
+ };
124
+ });
125
+ const multiModelHosts = (Array.isArray(providers.multi_model_hosts) ? providers.multi_model_hosts : [])
126
+ .filter(isObj)
127
+ .map((entry) => ({ marker: strOf(entry.marker) ?? "", provider: strOf(entry.provider) ?? "" }))
128
+ .filter((entry) => entry.marker.length > 0 && entry.provider.length > 0);
129
+ const findings = [];
130
+ if (entries.length === 0) {
131
+ findings.push(`model roster degraded: ${ROSTER_SOURCE} has no models — active model resolves as unknown; token-only handling`);
132
+ }
133
+ else if (!entries.some((entry) => entry.family !== UNKNOWN_FAMILY)) {
134
+ findings.push(`model roster degraded: ${ROSTER_SOURCE} models carry no roster fields (family/roles/detect) — detection limited`);
135
+ }
136
+ return {
137
+ source: ROSTER_SOURCE,
138
+ available: true,
139
+ nativeProvider: strOf(roster.native_provider) ?? NATIVE_PROVIDER_FALLBACK,
140
+ nativeFamily: strOf(roster.native_family) ?? UNKNOWN_FAMILY,
141
+ nativeBaseUrl: strOf(roster.native_base_url) ?? ANTHROPIC_BASE_DEFAULT,
142
+ nativeHosts: strArray(providers.native_hosts).map((h) => h.toLowerCase()),
143
+ multiModelHosts,
144
+ entries,
145
+ findings,
146
+ };
147
+ }
148
+ // --- Resolution helpers (all read only the roster data) ----------------------
149
+ function hostOf(url) {
150
+ const trimmed = url?.trim();
151
+ if (!trimmed)
152
+ return null;
153
+ try {
154
+ return new URL(trimmed).host.toLowerCase();
155
+ }
156
+ catch {
157
+ const match = trimmed.replace(/^https?:\/\//, "").replace(/^\/+/, "").match(/^([^/]+)/);
158
+ return match ? match[1].toLowerCase() : null;
159
+ }
160
+ }
161
+ function providerFromHost(roster, host) {
162
+ for (const entry of roster.entries) {
163
+ if (entry.hostMarkers.some((marker) => host.includes(marker)))
164
+ return entry.provider ?? entry.family;
165
+ }
166
+ for (const multi of roster.multiModelHosts) {
167
+ if (host.includes(multi.marker))
168
+ return multi.provider;
169
+ }
170
+ return host;
171
+ }
172
+ // Family detection: a model id/hint marker wins over a host marker (a multi-model
173
+ // host only means a family when the model id says so — that ordering is why e.g.
174
+ // Fireworks carries no host marker in the data file).
175
+ function detectFamily(roster, host, modelHint) {
176
+ const hint = modelHint?.toLowerCase() ?? null;
177
+ if (hint) {
178
+ for (const entry of roster.entries) {
179
+ if (entry.modelMarkers.some((marker) => hint.includes(marker)))
180
+ return entry.family;
181
+ }
182
+ }
183
+ if (host) {
184
+ for (const entry of roster.entries) {
185
+ if (entry.hostMarkers.some((marker) => host.includes(marker)))
186
+ return entry.family;
187
+ }
188
+ }
189
+ return UNKNOWN_FAMILY;
190
+ }
191
+ // The family's default worker/verifier mix, from per-model `roles` in the data file.
192
+ function familyRoster(roster, family) {
193
+ if (family === UNKNOWN_FAMILY)
194
+ return { worker: null, verifier: null };
195
+ const inFamily = roster.entries.filter((entry) => entry.family === family);
196
+ return {
197
+ worker: inFamily.find((entry) => entry.roles.includes("worker"))?.id ?? null,
198
+ verifier: inFamily.find((entry) => entry.roles.includes("verifier"))?.id ?? null,
199
+ };
200
+ }
201
+ // Friendly provider label for an unrouted family (e.g. a declared GLM model with no
202
+ // base-URL override reads its provider from the family's detection entry).
203
+ function familyProvider(roster, family) {
204
+ if (family === UNKNOWN_FAMILY)
205
+ return null;
206
+ return roster.entries.find((entry) => entry.family === family && entry.provider)?.provider ?? null;
207
+ }
208
+ function isKnownModel(roster, id) {
209
+ return roster.entries.some((entry) => entry.id === id);
210
+ }
211
+ // R-003 unknown-model honesty: label anything the data file cannot vouch for.
212
+ function modelFindings(roster, worker, verifier) {
213
+ const findings = [...roster.findings];
214
+ const flag = (id) => {
215
+ if (id === UNKNOWN_MODEL) {
216
+ findings.push("unknown model: the active model could not be resolved (no declaration, no roster match) — token-only handling, no default-model rates assumed");
217
+ }
218
+ else if (roster.available && !isKnownModel(roster, id)) {
219
+ findings.push(`unknown model: ${id} is not in ${roster.source} — token-only handling, no default-model rates assumed`);
220
+ }
221
+ };
222
+ flag(worker);
223
+ if (verifier !== worker)
224
+ flag(verifier);
225
+ return [...new Set(findings)];
226
+ }
227
+ // Derive the count_tokens endpoint from the active base URL (R-003). The Anthropic-shaped
228
+ // path (z.ai mirrors it under /api/anthropic) is `<base>/v1/messages/count_tokens`. This is
229
+ // the only place that endpoint is built, so it always follows the harness.
230
+ export function deriveCountTokensUrl(baseUrl) {
231
+ return `${baseUrl.replace(/\/+$/, "")}/v1/messages/count_tokens`;
232
+ }
233
+ // Resolve the active provider/model from the single source. Reads the environment and
234
+ // the committed roster data only; pure given (env, roster) and testable. Every
235
+ // model-aware subsystem calls this and nothing else.
236
+ export function resolveActiveModel(env = process.env, roster = loadModelRoster()) {
237
+ const declaredModel = env.FOO_MODEL?.trim() || env.FOO_ACTOR_MODEL?.trim() || null;
238
+ const declaredProvider = env.FOO_ACTOR_PROVIDER?.trim() || null;
239
+ const nativeHosts = new Set(roster.nativeHosts);
240
+ const anthropicHost = hostOf(env.ANTHROPIC_BASE_URL);
241
+ const openaiHost = hostOf(env.OPENAI_BASE_URL ?? env.OPENAI_API_BASE);
242
+ let routedHost = null;
243
+ let routedBase = null;
244
+ let routedSource = null;
245
+ if (anthropicHost && !nativeHosts.has(anthropicHost)) {
246
+ routedHost = anthropicHost;
247
+ routedBase = (env.ANTHROPIC_BASE_URL ?? "").trim();
248
+ routedSource = "ANTHROPIC_BASE_URL";
249
+ }
250
+ else if (openaiHost && !nativeHosts.has(openaiHost)) {
251
+ routedHost = openaiHost;
252
+ routedBase = (env.OPENAI_BASE_URL ?? env.OPENAI_API_BASE ?? "").trim();
253
+ routedSource = env.OPENAI_BASE_URL ? "OPENAI_BASE_URL" : "OPENAI_API_BASE";
254
+ }
255
+ const routed = Boolean(routedHost);
256
+ const harnessModelHint = env.ANTHROPIC_MODEL?.trim() || env.OPENAI_MODEL?.trim() || null;
257
+ // 1. Explicit declaration wins — confirmed. The declared id is honored as-is: an id
258
+ // the data file does not know gets an "unknown model" finding (R-003), never a
259
+ // silent canonicalization onto another model's pricing key.
260
+ if (declaredModel) {
261
+ const family = detectFamily(roster, routedHost, declaredModel);
262
+ const mix = familyRoster(roster, family);
263
+ const worker = declaredModel;
264
+ const verifier = isKnownModel(roster, declaredModel) ? mix.verifier ?? declaredModel : declaredModel;
265
+ const provider = declaredProvider ??
266
+ (routedHost ? providerFromHost(roster, routedHost) : familyProvider(roster, family) ?? roster.nativeProvider);
267
+ const baseUrl = routedBase || roster.nativeBaseUrl;
268
+ return {
269
+ provider,
270
+ family,
271
+ worker,
272
+ verifier,
273
+ confidence: "confirmed",
274
+ routed,
275
+ baseUrl,
276
+ countTokensUrl: deriveCountTokensUrl(baseUrl),
277
+ source: env.FOO_MODEL ? "FOO_MODEL" : "FOO_ACTOR_MODEL",
278
+ findings: modelFindings(roster, worker, verifier),
279
+ };
280
+ }
281
+ // 2. Inference from a base-URL override — assumed (the honest tag). A recognized
282
+ // family resolves to that family's roster mix (server-side mapping makes the raw
283
+ // hint unreliable, so the family pricing key is the honest resolution); an
284
+ // unrecognized one resolves to the hint or "unknown" with a finding.
285
+ if (routed && routedHost && routedBase) {
286
+ const family = detectFamily(roster, routedHost, harnessModelHint);
287
+ const mix = familyRoster(roster, family);
288
+ const worker = mix.worker ?? harnessModelHint ?? UNKNOWN_MODEL;
289
+ const verifier = mix.verifier ?? harnessModelHint ?? UNKNOWN_MODEL;
290
+ return {
291
+ provider: providerFromHost(roster, routedHost),
292
+ family,
293
+ worker,
294
+ verifier,
295
+ confidence: "assumed",
296
+ routed: true,
297
+ baseUrl: routedBase,
298
+ countTokensUrl: deriveCountTokensUrl(routedBase),
299
+ source: `${routedSource} (server-side model mapping may differ)`,
300
+ findings: modelFindings(roster, worker, verifier),
301
+ };
302
+ }
303
+ // 3. Native default — from the data file. Confirmed only when the roster actually
304
+ // vouches for the native mix; a degraded roster resolves honestly as unknown.
305
+ const family = roster.nativeFamily;
306
+ const mix = familyRoster(roster, family);
307
+ const worker = mix.worker ?? UNKNOWN_MODEL;
308
+ const verifier = mix.verifier ?? worker;
309
+ return {
310
+ provider: roster.nativeProvider,
311
+ family,
312
+ worker,
313
+ verifier,
314
+ confidence: worker === UNKNOWN_MODEL ? "assumed" : "confirmed",
315
+ routed: false,
316
+ baseUrl: roster.nativeBaseUrl,
317
+ countTokensUrl: deriveCountTokensUrl(roster.nativeBaseUrl),
318
+ source: "native default",
319
+ findings: modelFindings(roster, worker, verifier),
320
+ };
321
+ }
322
+ // One-line, human-only provenance description. Returns null when the active model is the
323
+ // genuinely-native default with nothing to flag (no signal worth showing). The caller owns
324
+ // glyph-gating (TTY-only, never into --json/contracts) — this returns plain text.
325
+ export function describeActiveModel(active) {
326
+ if (!active.routed && active.confidence === "confirmed" && active.findings.length === 0)
327
+ return null;
328
+ const tag = active.confidence === "assumed" ? "model: unconfirmed" : `model: ${active.worker}`;
329
+ const where = active.routed ? `routed to ${active.provider}` : `native ${active.provider}`;
330
+ return `${where} — ${tag} (${active.family}); pricing/token follow the active model`;
331
+ }
@@ -0,0 +1,122 @@
1
+ export type RuntimeId = "claude" | "codex" | "cursor" | "github-actions";
2
+ export type AdapterSupport = "supported" | "planned";
3
+ export type TriggerKind = "manual" | "schedule" | "event";
4
+ export interface AgentAdapter {
5
+ id: RuntimeId;
6
+ label: string;
7
+ /** supported = productfoo can emit a working binding today; planned = mapped, not yet emitted. */
8
+ support: AdapterSupport;
9
+ /** Runtime config home, where a committed binding would live. null when external (e.g. CI). */
10
+ config_dir: string | null;
11
+ /** Can this runtime run one routine pass non-interactively? Required for any unattended trigger. */
12
+ can_run_headless: boolean;
13
+ /** Trigger kinds this runtime can arm natively. */
14
+ trigger_mechanisms: TriggerKind[];
15
+ /**
16
+ * Headless invocation template for one pass. {prompt} is the routine's pass
17
+ * instruction; {packet} is the packet dir. null when the runtime cannot yet
18
+ * be driven headless. Templates are illustrative bindings, not a promise the
19
+ * binary exists on PATH — the emitted artifact is reviewed before it is armed.
20
+ */
21
+ invoke_template: string | null;
22
+ /** What we would need to fit this runtime fully (the honest gap). */
23
+ notes: string;
24
+ }
25
+ export type HarnessAdapterStatus = "ready" | "missing" | "drift" | "unsupported";
26
+ export type HarnessAdapterId = "codex" | "claude-code" | "cursor" | "opencode" | "grok";
27
+ export type HarnessCommandFormat = "markdown" | "toml";
28
+ export type HarnessCommandSupport = "supported" | "planned";
29
+ export interface HarnessCommandDirs {
30
+ global: string | null;
31
+ project: string | null;
32
+ }
33
+ export interface HarnessCommandAdapter {
34
+ id: HarnessAdapterId;
35
+ label: string;
36
+ /** The real per-scope command directories. Replaces the aspirational shared `.agents/commands`. */
37
+ commandsDir: HarnessCommandDirs;
38
+ /** Filename extension for emitted command files: ".md" | ".prompt.md" | ".toml". */
39
+ commandExtension: string;
40
+ /** Content format productfoo must emit. "markdown" ships today; "toml" is not yet emittable. */
41
+ commandFormat: HarnessCommandFormat;
42
+ /** Plugin skills use <id>/SKILL.md instead of flat command files. */
43
+ commandLayout?: "flat" | "skills";
44
+ /**
45
+ * Command-surface support (D-002): "supported" = directory AND format are
46
+ * verified and emittable; "planned" = mapped honestly but NOT installed
47
+ * (unverified dir or un-emittable format). `unsupportedReason` names the gap.
48
+ */
49
+ support: HarnessCommandSupport;
50
+ unsupportedReason?: string;
51
+ /**
52
+ * Flat (non-plugin) harnesses prefix productfoo's commands (e.g. `foo-spec`) so they
53
+ * group together and cannot collide with a user's own `/spec`. Plugin harnesses
54
+ * namespace instead and leave this unset.
55
+ */
56
+ commandPrefix?: string;
57
+ /**
58
+ * Setup/readiness path for the command surface. This is an adapter surface,
59
+ * not a productfoo core dependency; unknown harnesses can still call `foo` directly.
60
+ */
61
+ projectPath: string;
62
+ /**
63
+ * Namespaced command wrapper, when a harness supports a plugin-like command
64
+ * surface. Plain command adapters leave this unset and use the `commandPrefix`
65
+ * convention instead.
66
+ */
67
+ plugin?: {
68
+ dir: string;
69
+ name: string;
70
+ manifestRelPath: string;
71
+ };
72
+ /** Personal Codex marketplace entry required to install this plugin. */
73
+ marketplace?: {
74
+ manifestRelPath: string;
75
+ name: string;
76
+ };
77
+ /**
78
+ * Directory-derived namespace: the harness types commands as /<ns>:<id>
79
+ * because they live in a subdirectory named <ns> of its native commands dir
80
+ * (no plugin, no registration). Mutually exclusive with `plugin`.
81
+ */
82
+ commandNamespace?: string;
83
+ /**
84
+ * Namespace the HARNESS imposes in its own slash menu, independent of where
85
+ * the files sit. Unlike `commandNamespace`, this never affects a path.
86
+ * Retained for flat adapters that impose their own menu namespace.
87
+ */
88
+ invocationNamespace?: string;
89
+ /**
90
+ * Commands to exclude from this harness (e.g., "bug" for third-party bots).
91
+ * When set, setup skips these command IDs for this adapter only.
92
+ */
93
+ excludedCommands?: readonly string[];
94
+ /**
95
+ * Paths written by older productfoo adapter versions. Setup removes only productfoo-managed
96
+ * files/symlinks at these paths so harness-specific shims do not leak into
97
+ * the core contract.
98
+ */
99
+ legacyPaths: string[];
100
+ legacyCommandsDir?: string;
101
+ legacyCommandPrefix?: string;
102
+ /** A retired plugin install dir (manifest + commands) that setup migrates away from. */
103
+ legacyPluginDir?: string;
104
+ }
105
+ export type HarnessCommandTarget = {
106
+ supported: true;
107
+ dir: string;
108
+ extension: string;
109
+ format: HarnessCommandFormat;
110
+ prefix: string;
111
+ } | {
112
+ supported: false;
113
+ reason: string;
114
+ };
115
+ export declare function resolveHarnessCommandTarget(adapter: HarnessCommandAdapter, scope: "global" | "project"): HarnessCommandTarget;
116
+ export declare const AGENT_ADAPTERS: Record<RuntimeId, AgentAdapter>;
117
+ export declare const HARNESS_COMMAND_ADAPTERS: Record<HarnessAdapterId, HarnessCommandAdapter>;
118
+ export declare function getAdapter(id: string): AgentAdapter | undefined;
119
+ export declare function supportedRuntimes(): RuntimeId[];
120
+ export declare function knownRuntimes(): RuntimeId[];
121
+ export declare function knownHarnessCommandAdapters(): HarnessAdapterId[];
122
+ export declare function getHarnessCommandAdapter(id: string): HarnessCommandAdapter | undefined;