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,351 @@
1
+ // Zoom through Nango (zoom-discovery-connector-v0, local worker mode).
2
+ //
3
+ // Nango is the credential broker only (gong-discovery-connector-v0 D-003,
4
+ // carried by this packet's D-001): productfoo asks Nango for the company's Zoom
5
+ // credential and then talks to Zoom's REST API directly, so transcript bytes
6
+ // never transit Nango. Everything here is content-free on every surface productfoo
7
+ // owns: credentials are held in process memory for one command, the Nango
8
+ // connection id is never printed (an opaque `connection_ref` stands in for
9
+ // it), and errors carry a typed code plus a bounded message that never embeds
10
+ // a provider response or a tokenized download URL.
11
+ //
12
+ // Zoom API shapes below are beliefs owned by the packet's feasibility task
13
+ // (T-001) and pinned by fixtures in test/discoveryZoomRuntime.test.ts; the
14
+ // live dogfood run (T-010) is what promotes them from belief to verified.
15
+ import { createHash } from "node:crypto";
16
+ import { refuseSourceWrite } from "./sourceIngress.js";
17
+ export class ZoomRuntimeError extends Error {
18
+ code;
19
+ constructor(code, message) {
20
+ super(message);
21
+ this.code = code;
22
+ this.name = "ZoomRuntimeError";
23
+ }
24
+ }
25
+ // Versioned policy fields (Granola packet R-005, carried by D-001): hard
26
+ // ceilings the worker enforces and reports, so a later change is explicit
27
+ // rather than silent.
28
+ export const ZOOM_POLICY = {
29
+ policy_version: "zoom-local-worker-0.1",
30
+ max_response_bytes: 8 * 1024 * 1024,
31
+ max_transcript_bytes: 4 * 1024 * 1024,
32
+ fetch_timeout_ms: 90_000,
33
+ max_model_input_tokens: 100_000,
34
+ max_list_pages: 5,
35
+ max_page_size: 300,
36
+ min_request_interval_ms: 350,
37
+ };
38
+ // The recording read grant that also covers cloud-recording downloads
39
+ // (belief owned by T-001; the feasibility report pins the exact scope string).
40
+ const ZOOM_RECORDING_SCOPES = ["recording:read", "recording:read:admin"];
41
+ const DEFAULT_NANGO_HOST = "https://api.nango.dev";
42
+ const DEFAULT_ZOOM_BASE = "https://api.zoom.us";
43
+ const DEFAULT_ZOOM_TOKEN_BASE = "https://zoom.us";
44
+ function nangoConfigured(env) {
45
+ return Boolean(env.NANGO_SECRET_KEY?.trim() && env.FOO_ZOOM_NANGO_CONNECTION?.trim());
46
+ }
47
+ function directConfigured(env) {
48
+ return Boolean(env.FOO_ZOOM_ACCOUNT_ID?.trim() && env.FOO_ZOOM_CLIENT_ID?.trim() && env.FOO_ZOOM_CLIENT_SECRET?.trim());
49
+ }
50
+ export function zoomConnectionConfigured(env) {
51
+ return nangoConfigured(env) || directConfigured(env);
52
+ }
53
+ export function zoomCredentialBroker(env) {
54
+ if (nangoConfigured(env))
55
+ return "nango";
56
+ if (directConfigured(env))
57
+ return "direct";
58
+ return null;
59
+ }
60
+ function opaqueConnectionRef(integration, connectionId) {
61
+ return `zoom:${createHash("sha256").update(`${integration}\n${connectionId}`).digest("hex").slice(0, 16)}`;
62
+ }
63
+ async function fetchWithTimeout(fetchImpl, url, init, timeoutMs) {
64
+ const controller = new AbortController();
65
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
66
+ try {
67
+ return await fetchImpl(url, { ...init, signal: controller.signal });
68
+ }
69
+ catch (error) {
70
+ if (controller.signal.aborted)
71
+ throw new ZoomRuntimeError("provider_timeout", "the provider did not answer within the fetch ceiling");
72
+ throw new ZoomRuntimeError("network", `network failure reaching ${new URL(url).hostname}`);
73
+ }
74
+ finally {
75
+ clearTimeout(timer);
76
+ }
77
+ }
78
+ // Reads a response body while counting toward the byte ceiling, so an
79
+ // oversized transcript is dropped before it is ever materialized in full.
80
+ async function readBounded(response, maxBytes) {
81
+ const declared = Number(response.headers.get("content-length") ?? "0");
82
+ if (Number.isFinite(declared) && declared > maxBytes)
83
+ throw new ZoomRuntimeError("transcript_too_large", "the provider response exceeds the byte ceiling");
84
+ if (!response.body) {
85
+ const buffer = await response.arrayBuffer();
86
+ if (buffer.byteLength > maxBytes)
87
+ throw new ZoomRuntimeError("transcript_too_large", "the provider response exceeds the byte ceiling");
88
+ return new TextDecoder().decode(buffer);
89
+ }
90
+ const reader = response.body.getReader();
91
+ const chunks = [];
92
+ let total = 0;
93
+ for (;;) {
94
+ const { done, value } = await reader.read();
95
+ if (done)
96
+ break;
97
+ total += value.byteLength;
98
+ if (total > maxBytes) {
99
+ await reader.cancel().catch(() => undefined);
100
+ chunks.length = 0;
101
+ throw new ZoomRuntimeError("transcript_too_large", "the provider response exceeds the byte ceiling");
102
+ }
103
+ chunks.push(value);
104
+ }
105
+ return new TextDecoder().decode(Buffer.concat(chunks));
106
+ }
107
+ function parseJson(text, label) {
108
+ try {
109
+ const parsed = JSON.parse(text);
110
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
111
+ throw new Error("not an object");
112
+ return parsed;
113
+ }
114
+ catch {
115
+ throw new ZoomRuntimeError("provider_failure", `${label} returned a response productfoo could not read`);
116
+ }
117
+ }
118
+ function recordingScopeFromScopes(scopes) {
119
+ if (scopes.length === 0)
120
+ return "unknown";
121
+ return scopes.some((scope) => ZOOM_RECORDING_SCOPES.includes(scope)) ? "granted" : "missing";
122
+ }
123
+ /**
124
+ * Resolve the company's Zoom credential. Nango is the primary broker: it holds
125
+ * the credential, refreshes it, and is where an administrator revokes it. When
126
+ * Nango is not configured, an administrator-issued server-to-server OAuth app
127
+ * (FOO_ZOOM_ACCOUNT_ID / FOO_ZOOM_CLIENT_ID / FOO_ZOOM_CLIENT_SECRET) is
128
+ * accepted as the direct fallback — the same company grant, minus the central
129
+ * refresh and revoke story. Either way productfoo receives it for one command and
130
+ * never persists or prints it.
131
+ */
132
+ export async function resolveZoomConnection(input) {
133
+ const broker = zoomCredentialBroker(input.env);
134
+ if (broker === null) {
135
+ throw new ZoomRuntimeError("not_connected", "Zoom is not connected: set NANGO_SECRET_KEY and FOO_ZOOM_NANGO_CONNECTION for the company connection through Nango, or FOO_ZOOM_ACCOUNT_ID, FOO_ZOOM_CLIENT_ID, and FOO_ZOOM_CLIENT_SECRET for a direct administrator-issued server-to-server app");
136
+ }
137
+ if (broker === "direct") {
138
+ const accountId = input.env.FOO_ZOOM_ACCOUNT_ID.trim();
139
+ const clientId = input.env.FOO_ZOOM_CLIENT_ID.trim();
140
+ const clientSecret = input.env.FOO_ZOOM_CLIENT_SECRET.trim();
141
+ // Documented server-to-server token exchange — an auth operation, not a
142
+ // source read; it happens once per command against zoom.us. The response
143
+ // token lives in process memory for the command and is never logged.
144
+ const response = await fetchWithTimeout(input.fetchImpl, `${DEFAULT_ZOOM_TOKEN_BASE}/oauth/token`, {
145
+ method: "POST",
146
+ headers: { authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`, "content-type": "application/x-www-form-urlencoded" },
147
+ body: new URLSearchParams({ grant_type: "account_credentials", account_id: accountId }).toString(),
148
+ }, ZOOM_POLICY.fetch_timeout_ms);
149
+ if (response.status === 400 || response.status === 401 || response.status === 403)
150
+ throw new ZoomRuntimeError("auth_expired", "Zoom refused the server-to-server credential; check the account id, client id, and secret");
151
+ if (!response.ok)
152
+ throw new ZoomRuntimeError("provider_failure", `Zoom answered ${response.status} while exchanging the server-to-server credential`);
153
+ const body = parseJson(await readBounded(response, 64 * 1024), "Zoom");
154
+ const token = String(body.access_token ?? "");
155
+ if (!token)
156
+ throw new ZoomRuntimeError("auth_expired", "Zoom returned no access token for the server-to-server credential");
157
+ return { connection_ref: `zoom:direct:${createHash("sha256").update(clientId).digest("hex").slice(0, 16)}`, broker: "direct", credential: { type: "oauth2", access_token: token }, credential_type: "oauth2", transcript_scope: "granted" };
158
+ }
159
+ const secret = input.env.NANGO_SECRET_KEY.trim();
160
+ const connectionId = input.env.FOO_ZOOM_NANGO_CONNECTION.trim();
161
+ const integration = input.env.FOO_ZOOM_NANGO_INTEGRATION?.trim() || "zoom";
162
+ const host = (input.env.NANGO_HOST?.trim() || DEFAULT_NANGO_HOST).replace(/\/+$/, "");
163
+ const url = `${host}/connection/${encodeURIComponent(connectionId)}?provider_config_key=${encodeURIComponent(integration)}`;
164
+ const response = await fetchWithTimeout(input.fetchImpl, url, { method: "GET", headers: { authorization: `Bearer ${secret}`, accept: "application/json" } }, ZOOM_POLICY.fetch_timeout_ms);
165
+ if (response.status === 401 || response.status === 403)
166
+ throw new ZoomRuntimeError("not_connected", "Nango refused the secret key; reconnect Zoom");
167
+ if (response.status === 404)
168
+ throw new ZoomRuntimeError("not_connected", "Nango has no Zoom connection with that reference; connect Zoom first");
169
+ if (!response.ok)
170
+ throw new ZoomRuntimeError("provider_failure", `Nango answered ${response.status} while resolving the connection`);
171
+ const body = parseJson(await readBounded(response, 256 * 1024), "Nango");
172
+ const credentials = (body.credentials ?? {});
173
+ const type = String(credentials.type ?? "").toUpperCase();
174
+ const ref = opaqueConnectionRef(integration, connectionId);
175
+ if (type === "OAUTH2") {
176
+ const token = String(credentials.access_token ?? "");
177
+ if (!token)
178
+ throw new ZoomRuntimeError("auth_expired", "the Nango connection carries no usable Zoom access token; refresh or reconnect");
179
+ const raw = (credentials.raw ?? {});
180
+ const scopeValue = typeof raw.scope === "string" ? raw.scope : typeof credentials.scope === "string" ? credentials.scope : "";
181
+ const scopes = scopeValue.split(/[\s,]+/).filter(Boolean);
182
+ return { connection_ref: ref, broker: "nango", credential: { type: "oauth2", access_token: token }, credential_type: "oauth2", transcript_scope: recordingScopeFromScopes(scopes) };
183
+ }
184
+ throw new ZoomRuntimeError("not_connected", "the Nango connection uses a credential type productfoo does not support for Zoom");
185
+ }
186
+ /**
187
+ * Minimal read-only Zoom REST client. Only documented read operations are
188
+ * reachable; any other method or path routes through the single write-refusal
189
+ * choke point (R-009) so the refusal is testable rather than scattered.
190
+ */
191
+ export class ZoomClient {
192
+ credential;
193
+ options;
194
+ requests = { list: 0, transcript: 0 };
195
+ lastRequestAt = 0;
196
+ baseUrl;
197
+ sleep;
198
+ now;
199
+ fetchTimeoutMs;
200
+ constructor(credential, options) {
201
+ this.credential = credential;
202
+ this.options = options;
203
+ this.baseUrl = (options.baseUrl ?? DEFAULT_ZOOM_BASE).replace(/\/+$/, "");
204
+ this.sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
205
+ this.now = options.now ?? (() => Date.now());
206
+ this.fetchTimeoutMs = options.fetchTimeoutMs ?? ZOOM_POLICY.fetch_timeout_ms;
207
+ }
208
+ authorization() {
209
+ return `Bearer ${this.credential.access_token}`;
210
+ }
211
+ async request(pathname, maxBytes) {
212
+ if (!pathname.startsWith("/"))
213
+ refuseSourceWrite(`zoom ${pathname}`);
214
+ const wait = this.lastRequestAt + ZOOM_POLICY.min_request_interval_ms - this.now();
215
+ if (wait > 0)
216
+ await this.sleep(wait);
217
+ this.lastRequestAt = this.now();
218
+ const response = await fetchWithTimeout(this.options.fetchImpl, `${this.baseUrl}${pathname}`, { method: "GET", headers: { authorization: this.authorization(), accept: "application/json" } }, this.fetchTimeoutMs);
219
+ if (response.status === 401)
220
+ throw new ZoomRuntimeError("auth_expired", "Zoom rejected the credential; refresh or reconnect");
221
+ if (response.status === 403)
222
+ throw new ZoomRuntimeError("access_denied", "Zoom denied this read; the credential lacks the required permission");
223
+ if (response.status === 429)
224
+ throw new ZoomRuntimeError("budget_exhausted", "Zoom rate limit reached; no retry was attempted");
225
+ if (response.status === 404)
226
+ throw new ZoomRuntimeError("provider_failure", "Zoom reported the requested record does not exist");
227
+ if (!response.ok)
228
+ throw new ZoomRuntimeError("provider_failure", `Zoom answered ${response.status}`);
229
+ return parseJson(await readBounded(response, maxBytes), "Zoom");
230
+ }
231
+ /**
232
+ * Bounded metadata listing: one time window, a page ceiling, no content. A
233
+ * recording's participant records carry no affiliation field — the mapping
234
+ * passes through only what is observed and leaves the rest undefined.
235
+ */
236
+ async listSessions(userId, window) {
237
+ const recordings = [];
238
+ let nextPageToken;
239
+ let pages = 0;
240
+ for (;;) {
241
+ if (pages >= ZOOM_POLICY.max_list_pages)
242
+ return { recordings, pages, truncated: true };
243
+ const params = new URLSearchParams({ from: window.from, to: window.to, page_size: String(ZOOM_POLICY.max_page_size) });
244
+ if (nextPageToken)
245
+ params.set("next_page_token", nextPageToken);
246
+ this.requests.list += 1;
247
+ const body = await this.request(`/users/${encodeURIComponent(userId)}/recordings?${params.toString()}`, 4 * 1024 * 1024);
248
+ pages += 1;
249
+ for (const entry of Array.isArray(body.recordings) ? body.recordings : []) {
250
+ // Entries without the contract's required identity fields cannot be
251
+ // normalized and are skipped, exactly as Gong's listing skips calls
252
+ // without an id.
253
+ if (!entry || typeof entry.uuid !== "string" || typeof entry.topic !== "string" || typeof entry.start_time !== "string")
254
+ continue;
255
+ const files = (Array.isArray(entry.recording_files) ? entry.recording_files : []).map((file) => ({
256
+ file_type: typeof file.file_type === "string" ? file.file_type : undefined,
257
+ download_url: typeof file.download_url === "string" ? file.download_url : undefined,
258
+ play_url: typeof file.play_url === "string" ? file.play_url : undefined,
259
+ status: typeof file.status === "string" ? file.status : undefined,
260
+ }));
261
+ // A transcript file counts as available only when it is actually
262
+ // downloadable — the observed state of THIS recording, never assumed
263
+ // from the topic or the account (R-005).
264
+ const transcriptFile = files.find((file) => file.file_type === "TRANSCRIPTION" && file.download_url && file.status === "completed");
265
+ const participants = (Array.isArray(entry.participants) ? entry.participants : [])
266
+ .map((participant) => ({
267
+ display_name: typeof participant.display_name === "string" ? participant.display_name : undefined,
268
+ email: typeof participant.email === "string" ? participant.email : undefined,
269
+ }))
270
+ .filter((participant) => participant.display_name || participant.email);
271
+ recordings.push({
272
+ meeting_uuid: entry.uuid,
273
+ topic: entry.topic,
274
+ start_time: entry.start_time,
275
+ end_time: typeof entry.end_time === "string" ? entry.end_time : undefined,
276
+ state: typeof entry.state === "string" ? entry.state : undefined,
277
+ host_display_name: typeof entry.host_display_name === "string" ? entry.host_display_name : undefined,
278
+ participants,
279
+ // Omitted, never cleaned: a tokenized or non-canonical page URL is
280
+ // dropped here and the adapter additionally refuses non-canonical
281
+ // forms as defense in depth (R-006).
282
+ url: this.canonicalPageUrl(typeof entry.play_url === "string" ? entry.play_url : undefined),
283
+ transcript_available: Boolean(transcriptFile),
284
+ recording_files: files,
285
+ });
286
+ }
287
+ nextPageToken = typeof body.next_page_token === "string" && body.next_page_token ? body.next_page_token : undefined;
288
+ if (!nextPageToken)
289
+ return { recordings, pages, truncated: false };
290
+ }
291
+ }
292
+ // Accepts only the canonical recording page form the sanitizer in
293
+ // src/discoverySources.ts accepts (one account subdomain, /recording/<id>,
294
+ // no query, no fragment); anything else — including tokenized share links —
295
+ // is omitted, never cleaned (R-006).
296
+ canonicalPageUrl(url) {
297
+ if (!url)
298
+ return undefined;
299
+ try {
300
+ const parsed = new URL(url);
301
+ if (parsed.protocol !== "https:" || parsed.search || parsed.hash)
302
+ return undefined;
303
+ const host = parsed.hostname.toLowerCase();
304
+ const suffix = ".zoom.us";
305
+ if (!host.endsWith(suffix))
306
+ return undefined;
307
+ const label = host.slice(0, -suffix.length);
308
+ if (!label || !/^[a-z0-9-]+$/.test(label))
309
+ return undefined;
310
+ if (!/^\/recording\/[A-Za-z0-9_-]{16,128}$/.test(parsed.pathname))
311
+ return undefined;
312
+ return `https://${host}${parsed.pathname}`;
313
+ }
314
+ catch {
315
+ return undefined;
316
+ }
317
+ }
318
+ /**
319
+ * Exactly one transcript download (R-007): the observed, downloadable
320
+ * transcript file of one recording. The URL is the one the listing observed
321
+ * for that recording; a tokenized link may be used in transit (Zoom's own
322
+ * access mechanism) and is never logged, persisted, or echoed — error
323
+ * messages carry the hostname only.
324
+ */
325
+ async transcript(downloadUrl) {
326
+ let hostname = "";
327
+ try {
328
+ const parsed = new URL(downloadUrl);
329
+ hostname = parsed.hostname;
330
+ if (parsed.protocol !== "https:" || !(parsed.hostname === "zoom.us" || parsed.hostname.endsWith(".zoom.us"))) {
331
+ throw new Error("not a zoom host");
332
+ }
333
+ }
334
+ catch {
335
+ throw new ZoomRuntimeError("provider_failure", "a single well-formed Zoom transcript download URL is required");
336
+ }
337
+ this.requests.transcript += 1;
338
+ const response = await fetchWithTimeout(this.options.fetchImpl, downloadUrl, { method: "GET", headers: { authorization: this.authorization(), accept: "text/vtt, text/plain, */*" } }, this.fetchTimeoutMs);
339
+ if (response.status === 401)
340
+ throw new ZoomRuntimeError("auth_expired", `Zoom rejected the credential for the transcript download from ${hostname}`);
341
+ if (response.status === 403)
342
+ throw new ZoomRuntimeError("access_denied", `Zoom denied the transcript download from ${hostname}`);
343
+ if (response.status === 429)
344
+ throw new ZoomRuntimeError("budget_exhausted", "Zoom rate limit reached; no retry was attempted");
345
+ if (response.status === 404)
346
+ throw new ZoomRuntimeError("provider_failure", `Zoom reported the transcript on ${hostname} does not exist`);
347
+ if (!response.ok)
348
+ throw new ZoomRuntimeError("provider_failure", `Zoom answered ${response.status} for the transcript download`);
349
+ return { vtt: await readBounded(response, ZOOM_POLICY.max_transcript_bytes) };
350
+ }
351
+ }
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ This changelog covers the public productfoo distribution. Pre-public development
4
+ records are not part of the public release history.
5
+
6
+ ## 1.0.1 — October 17, 2026
7
+
8
+ Patch release from the fresh public repository. Includes updated README setup
9
+ guidance and section order, plus current installation documentation. CLI commands,
10
+ library exports, bundled skills, packet formats, and runtime requirements are
11
+ unchanged from 1.0.0.
12
+
13
+ ## 1.0.0 — October 17, 2026
14
+
15
+ The initial release candidate includes the local CLI, bundled product-management
16
+ skills, spec workflows, research and discovery helpers, validation, reconciliation,
17
+ and scanning tools under Apache-2.0. The terminal command is `foo`.
18
+
19
+ The experimental sales-development subsystem (`foo sdr`) and its PostgreSQL
20
+ dependency were removed before release. Core spec, research, discovery, skill,
21
+ and reporting workflows need no database server.
22
+
23
+ The local workflows require no productfoo account or hosted service. Optional
24
+ model and connector workflows may use external services and incur charges.
25
+
26
+ productfoo is a personal open-source project with best-effort maintenance and
27
+ support. Agent behavior depends on the selected model, runtime, and permissions;
28
+ checks cannot guarantee correctness or safety. Read
29
+ [project status and responsible use](https://github.com/rwo572/productfoo#project-status-and-responsible-use)
30
+ before getting started.
31
+
32
+ Each published release is verified against its exact source and package bytes.
@@ -0,0 +1,36 @@
1
+ # Third-party notices
2
+
3
+ This file lists productfoo's direct runtime dependencies and their licenses.
4
+ It is generated from the package's declared dependencies by
5
+ `scripts/gen-third-party-notices.mjs` — do not edit it by hand. To
6
+ regenerate after adding or upgrading a runtime dependency, run:
7
+
8
+ ```bash
9
+ node scripts/gen-third-party-notices.mjs
10
+ ```
11
+
12
+ Scope note: runtime dependencies may be bundled into the build or installed
13
+ alongside the package by npm. Development and build-time tooling is not
14
+ distributed with the package and is not listed here. productfoo itself is
15
+ licensed under the [Apache License 2.0](https://github.com/rwo572/productfoo/blob/main/LICENSE).
16
+
17
+ ## yaml 2.9.0
18
+
19
+ - License: ISC
20
+ - Homepage: https://eemeli.org/yaml/
21
+
22
+ ```text
23
+ Copyright Eemeli Aro <eemeli@gmail.com>
24
+
25
+ Permission to use, copy, modify, and/or distribute this software for any purpose
26
+ with or without fee is hereby granted, provided that the above copyright notice
27
+ and this permission notice appear in all copies.
28
+
29
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
30
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
31
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
32
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
34
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
35
+ THIS SOFTWARE.
36
+ ```
package/package.json CHANGED
@@ -1,6 +1,73 @@
1
1
  {
2
2
  "name": "productfoo",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.1",
4
+ "description": "Product-management workflows, specs, and verification for coding agents.",
5
+ "keywords": [
6
+ "cli",
7
+ "product-management",
8
+ "specifications",
9
+ "coding-agents",
10
+ "ai-agents"
11
+ ],
12
+ "license": "Apache-2.0",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/rwo572/productfoo.git"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/rwo572/productfoo/issues"
19
+ },
20
+ "homepage": "https://github.com/rwo572/productfoo#readme",
21
+ "type": "module",
22
+ "bin": {
23
+ "foo": "bin/foo.mjs"
24
+ },
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist-public/src/index.d.ts",
28
+ "default": "./dist-public/src/index.js"
29
+ },
30
+ "./cli": {
31
+ "types": "./dist-public/src/cli.d.ts",
32
+ "default": "./dist-public/src/cli.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "foo": {
37
+ "brandUrl": "https://github.com/rwo572/productfoo"
38
+ },
39
+ "files": [
40
+ "bin",
41
+ "docs/CHANGELOG.md",
42
+ "commands",
43
+ "dist-public/src",
44
+ "config/pricing.yaml",
45
+ "config/routing-policy.yaml",
46
+ "schemas",
47
+ "skills",
48
+ "skills-lock.json",
49
+ "docs/THIRD_PARTY_NOTICES.md"
50
+ ],
51
+ "engines": {
52
+ "node": ">=18"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc && node scripts/bundle-vendor.mjs",
56
+ "build:public": "node scripts/build-public.mjs",
57
+ "verify:public": "npm run build && npm run check:generated && npm run build:public && node scripts/verify-public-package.mjs && node scripts/verify-public-git-manifest.mjs && node scripts/smoke-public-package.mjs",
58
+ "prepack": "npm run build:public",
59
+ "prepublishOnly": "npm run build:public",
60
+ "test": "rm -rf dist && npm run build && find dist -name '*.test.js' -print0 | xargs -0 env NODE_ENV=test node --test",
61
+ "test:packetindex": "npm run build && env NODE_ENV=test node --test dist/test/packetIndexGolden.test.js dist/test/packetIndex.test.js",
62
+ "generate": "npm run build && node scripts/build-swarm-skills.mjs && node scripts/skill-tree-anchor.mjs && node scripts/build-anthropic-plugin.mjs && node scripts/gen-cli-reference.mjs && node scripts/gen-third-party-notices.mjs && node scripts/gen-cheatsheet.mjs",
63
+ "check:generated": "node scripts/build-swarm-skills.mjs --verify && node scripts/skill-tree-anchor.mjs --check && node scripts/build-anthropic-plugin.mjs --check && node scripts/gen-cli-reference.mjs --check && node scripts/gen-third-party-notices.mjs --check && node scripts/gen-cheatsheet.mjs --check"
64
+ },
65
+ "dependencies": {
66
+ "yaml": "^2.8.1"
67
+ },
68
+ "devDependencies": {
69
+ "@types/node": "^26.3.0",
70
+ "esbuild": "^0.28.2",
71
+ "typescript": "^7.0.2"
72
+ }
73
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://foo.example/schemas/bug-capsule-receipt.schema.json",
4
+ "title": "DeliveryReceipt 0.1",
5
+ "type": "object",
6
+ "required": ["schema_version", "receipt_id", "capsule_id", "payload_digest", "accepted_at", "destination", "status", "error"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "schema_version": { "const": "0.1" },
10
+ "receipt_id": { "$ref": "#/$defs/uuidV7" },
11
+ "capsule_id": { "$ref": "#/$defs/uuidV7" },
12
+ "payload_digest": {
13
+ "type": "string",
14
+ "maxLength": 4096,
15
+ "pattern": "^sha256:[0-9a-f]{64}$"
16
+ },
17
+ "accepted_at": { "$ref": "#/$defs/rfc3339Utc" },
18
+ "destination": { "$ref": "#/$defs/string" },
19
+ "status": { "enum": ["accepted", "rejected", "retryable"] },
20
+ "error": { "type": ["null", "object"] }
21
+ },
22
+ "allOf": [
23
+ {
24
+ "if": { "properties": { "status": { "const": "accepted" } }, "required": ["status"] },
25
+ "then": { "properties": { "error": { "const": null } } },
26
+ "else": { "properties": { "error": { "$ref": "#/$defs/error" } } }
27
+ }
28
+ ],
29
+ "$defs": {
30
+ "string": { "type": "string", "maxLength": 4096 },
31
+ "uuidV7": {
32
+ "type": "string",
33
+ "maxLength": 4096,
34
+ "format": "uuid",
35
+ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
36
+ },
37
+ "rfc3339Utc": {
38
+ "type": "string",
39
+ "maxLength": 4096,
40
+ "format": "date-time",
41
+ "pattern": "^(?:\\d{4})-(?:\\d{2})-(?:\\d{2})T(?:\\d{2}):(?:\\d{2}):(?:\\d{2})(?:\\.\\d+)?Z$"
42
+ },
43
+ "error": {
44
+ "type": "object",
45
+ "required": ["code", "message"],
46
+ "additionalProperties": false,
47
+ "properties": {
48
+ "code": { "$ref": "#/$defs/string" },
49
+ "message": { "$ref": "#/$defs/string" },
50
+ "retry_after": { "$ref": "#/$defs/rfc3339Utc" }
51
+ }
52
+ }
53
+ }
54
+ }