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.
- package/LICENSE +201 -0
- package/README.md +338 -2
- package/bin/foo +3 -0
- package/bin/foo.mjs +42 -0
- package/commands/bug.md +31 -0
- package/commands/discovery.md +28 -0
- package/commands/ideate.md +27 -0
- package/commands/init.md +28 -0
- package/commands/pitch.md +27 -0
- package/commands/preview.md +25 -0
- package/commands/research.md +31 -0
- package/commands/roast.md +27 -0
- package/commands/spec.md +30 -0
- package/config/pricing.yaml +198 -0
- package/config/routing-policy.yaml +171 -0
- package/dist-public/src/activeModel.d.ts +83 -0
- package/dist-public/src/activeModel.js +331 -0
- package/dist-public/src/agentAdapters.d.ts +122 -0
- package/dist-public/src/agentAdapters.js +178 -0
- package/dist-public/src/agentState.d.ts +43 -0
- package/dist-public/src/agentState.js +177 -0
- package/dist-public/src/bugCapsule.d.ts +94 -0
- package/dist-public/src/bugCapsule.js +227 -0
- package/dist-public/src/bugCapture.d.ts +26 -0
- package/dist-public/src/bugCapture.js +251 -0
- package/dist-public/src/bugOwnerLog.d.ts +93 -0
- package/dist-public/src/bugOwnerLog.js +304 -0
- package/dist-public/src/bugReportStore.d.ts +48 -0
- package/dist-public/src/bugReportStore.js +860 -0
- package/dist-public/src/bugSpecContext.d.ts +7 -0
- package/dist-public/src/bugSpecContext.js +129 -0
- package/dist-public/src/channelFreshness.d.ts +25 -0
- package/dist-public/src/channelFreshness.js +194 -0
- package/dist-public/src/cli.d.ts +30 -0
- package/dist-public/src/cli.js +1667 -0
- package/dist-public/src/cliArgs.d.ts +7 -0
- package/dist-public/src/cliArgs.js +44 -0
- package/dist-public/src/codeCatalog.d.ts +41 -0
- package/dist-public/src/codeCatalog.js +197 -0
- package/dist-public/src/commandContract.d.ts +84 -0
- package/dist-public/src/commandContract.js +390 -0
- package/dist-public/src/commandUsage.d.ts +3 -0
- package/dist-public/src/commandUsage.js +30 -0
- package/dist-public/src/commands/agent.d.ts +60 -0
- package/dist-public/src/commands/agent.js +1353 -0
- package/dist-public/src/commands/asp.d.ts +8 -0
- package/dist-public/src/commands/asp.js +669 -0
- package/dist-public/src/commands/evalCmd.d.ts +4 -0
- package/dist-public/src/commands/evalCmd.js +405 -0
- package/dist-public/src/commands/login.d.ts +25 -0
- package/dist-public/src/commands/login.js +94 -0
- package/dist-public/src/commands/loop.d.ts +16 -0
- package/dist-public/src/commands/loop.js +619 -0
- package/dist-public/src/commands/reconcile.d.ts +41 -0
- package/dist-public/src/commands/reconcile.js +292 -0
- package/dist-public/src/commands/runtime.d.ts +1 -0
- package/dist-public/src/commands/runtime.js +36 -0
- package/dist-public/src/commands/scanRedact.d.ts +8 -0
- package/dist-public/src/commands/scanRedact.js +266 -0
- package/dist-public/src/commands/setup.d.ts +28 -0
- package/dist-public/src/commands/setup.js +398 -0
- package/dist-public/src/commands/shared.d.ts +17 -0
- package/dist-public/src/commands/shared.js +147 -0
- package/dist-public/src/commands/source.d.ts +1 -0
- package/dist-public/src/commands/source.js +134 -0
- package/dist-public/src/commands/specCmd.d.ts +24 -0
- package/dist-public/src/commands/specCmd.js +794 -0
- package/dist-public/src/commands/update.d.ts +61 -0
- package/dist-public/src/commands/update.js +244 -0
- package/dist-public/src/comprehensionSignal.d.ts +20 -0
- package/dist-public/src/comprehensionSignal.js +166 -0
- package/dist-public/src/conductor/diversity.d.ts +48 -0
- package/dist-public/src/conductor/diversity.js +423 -0
- package/dist-public/src/conductor/engine.d.ts +7 -0
- package/dist-public/src/conductor/engine.js +295 -0
- package/dist-public/src/conductor/families/ideate.d.ts +2 -0
- package/dist-public/src/conductor/families/ideate.js +255 -0
- package/dist-public/src/conductor/families/interview.d.ts +2 -0
- package/dist-public/src/conductor/families/interview.js +39 -0
- package/dist-public/src/conductor/families/specSwarm.d.ts +2 -0
- package/dist-public/src/conductor/families/specSwarm.js +146 -0
- package/dist-public/src/conductor/familyDelivery.d.ts +6 -0
- package/dist-public/src/conductor/familyDelivery.js +37 -0
- package/dist-public/src/conductor/familyPackArtifact.d.ts +4 -0
- package/dist-public/src/conductor/familyPackArtifact.js +260 -0
- package/dist-public/src/conductor/ideateDecision.d.ts +6 -0
- package/dist-public/src/conductor/ideateDecision.js +237 -0
- package/dist-public/src/conductor/pack.d.ts +26 -0
- package/dist-public/src/conductor/pack.js +75 -0
- package/dist-public/src/conductor/types.d.ts +111 -0
- package/dist-public/src/conductor/types.js +7 -0
- package/dist-public/src/configPath.d.ts +2 -0
- package/dist-public/src/configPath.js +7 -0
- package/dist-public/src/discoveryArtifacts.d.ts +54 -0
- package/dist-public/src/discoveryArtifacts.js +467 -0
- package/dist-public/src/discoveryCommand.d.ts +127 -0
- package/dist-public/src/discoveryCommand.js +2148 -0
- package/dist-public/src/discoveryConnections.d.ts +339 -0
- package/dist-public/src/discoveryConnections.js +613 -0
- package/dist-public/src/discoveryDocs.d.ts +129 -0
- package/dist-public/src/discoveryDocs.js +577 -0
- package/dist-public/src/discoveryEvidence.d.ts +59 -0
- package/dist-public/src/discoveryEvidence.js +198 -0
- package/dist-public/src/discoveryFireflies.d.ts +25 -0
- package/dist-public/src/discoveryFireflies.js +551 -0
- package/dist-public/src/discoveryGmail.d.ts +12 -0
- package/dist-public/src/discoveryGmail.js +466 -0
- package/dist-public/src/discoveryGong.d.ts +12 -0
- package/dist-public/src/discoveryGong.js +491 -0
- package/dist-public/src/discoveryLearningRouting.d.ts +90 -0
- package/dist-public/src/discoveryLearningRouting.js +405 -0
- package/dist-public/src/discoveryMatching.d.ts +26 -0
- package/dist-public/src/discoveryMatching.js +73 -0
- package/dist-public/src/discoveryOutlook.d.ts +12 -0
- package/dist-public/src/discoveryOutlook.js +492 -0
- package/dist-public/src/discoveryProcess.d.ts +221 -0
- package/dist-public/src/discoveryProcess.js +703 -0
- package/dist-public/src/discoveryProof.d.ts +143 -0
- package/dist-public/src/discoveryProof.js +529 -0
- package/dist-public/src/discoveryProviders.d.ts +152 -0
- package/dist-public/src/discoveryProviders.js +756 -0
- package/dist-public/src/discoveryReadiness.d.ts +219 -0
- package/dist-public/src/discoveryReadiness.js +672 -0
- package/dist-public/src/discoveryReconcile.d.ts +57 -0
- package/dist-public/src/discoveryReconcile.js +424 -0
- package/dist-public/src/discoverySlack.d.ts +12 -0
- package/dist-public/src/discoverySlack.js +452 -0
- package/dist-public/src/discoverySources.d.ts +56 -0
- package/dist-public/src/discoverySources.js +322 -0
- package/dist-public/src/discoverySync.d.ts +52 -0
- package/dist-public/src/discoverySync.js +151 -0
- package/dist-public/src/discoverySynthesis.d.ts +57 -0
- package/dist-public/src/discoverySynthesis.js +215 -0
- package/dist-public/src/discoveryTeams.d.ts +12 -0
- package/dist-public/src/discoveryTeams.js +516 -0
- package/dist-public/src/discoveryZoom.d.ts +12 -0
- package/dist-public/src/discoveryZoom.js +523 -0
- package/dist-public/src/elicitationSurface.d.ts +13 -0
- package/dist-public/src/elicitationSurface.js +77 -0
- package/dist-public/src/errorReport.d.ts +99 -0
- package/dist-public/src/errorReport.js +443 -0
- package/dist-public/src/errorTaxonomy.d.ts +84 -0
- package/dist-public/src/errorTaxonomy.js +189 -0
- package/dist-public/src/evalCalibration.d.ts +82 -0
- package/dist-public/src/evalCalibration.js +169 -0
- package/dist-public/src/evalChecks.d.ts +21 -0
- package/dist-public/src/evalChecks.js +295 -0
- package/dist-public/src/evalCompile.d.ts +56 -0
- package/dist-public/src/evalCompile.js +58 -0
- package/dist-public/src/evalImprove.d.ts +60 -0
- package/dist-public/src/evalImprove.js +175 -0
- package/dist-public/src/evalJudge.d.ts +47 -0
- package/dist-public/src/evalJudge.js +143 -0
- package/dist-public/src/evalLabels.d.ts +100 -0
- package/dist-public/src/evalLabels.js +287 -0
- package/dist-public/src/evalRecord.d.ts +68 -0
- package/dist-public/src/evalRecord.js +165 -0
- package/dist-public/src/evalRoast.d.ts +88 -0
- package/dist-public/src/evalRoast.js +249 -0
- package/dist-public/src/evidenceIntake.d.ts +66 -0
- package/dist-public/src/evidenceIntake.js +356 -0
- package/dist-public/src/feedback.d.ts +78 -0
- package/dist-public/src/feedback.js +294 -0
- package/dist-public/src/firefliesClient.d.ts +106 -0
- package/dist-public/src/firefliesClient.js +258 -0
- package/dist-public/src/firstMoveTensions.d.ts +10 -0
- package/dist-public/src/firstMoveTensions.js +93 -0
- package/dist-public/src/gitRun.d.ts +21 -0
- package/dist-public/src/gitRun.js +50 -0
- package/dist-public/src/githubReconcile.d.ts +94 -0
- package/dist-public/src/githubReconcile.js +205 -0
- package/dist-public/src/gmailNango.d.ts +131 -0
- package/dist-public/src/gmailNango.js +329 -0
- package/dist-public/src/gongNango.d.ts +118 -0
- package/dist-public/src/gongNango.js +308 -0
- package/dist-public/src/grammarGate.d.ts +13 -0
- package/dist-public/src/grammarGate.js +72 -0
- package/dist-public/src/harnessGates.d.ts +65 -0
- package/dist-public/src/harnessGates.js +168 -0
- package/dist-public/src/humanSurfaceEval.d.ts +19 -0
- package/dist-public/src/humanSurfaceEval.js +156 -0
- package/dist-public/src/ideate.d.ts +43 -0
- package/dist-public/src/ideate.js +255 -0
- package/dist-public/src/ideateContext.d.ts +11 -0
- package/dist-public/src/ideateContext.js +83 -0
- package/dist-public/src/index.d.ts +2 -0
- package/dist-public/src/index.js +4 -0
- package/dist-public/src/initCommand.d.ts +25 -0
- package/dist-public/src/initCommand.js +558 -0
- package/dist-public/src/interviewGate.d.ts +25 -0
- package/dist-public/src/interviewGate.js +126 -0
- package/dist-public/src/jsonFile.d.ts +2 -0
- package/dist-public/src/jsonFile.js +22 -0
- package/dist-public/src/loopBudget.d.ts +182 -0
- package/dist-public/src/loopBudget.js +494 -0
- package/dist-public/src/loopContracts.d.ts +35 -0
- package/dist-public/src/loopContracts.js +364 -0
- package/dist-public/src/machineState.d.ts +1 -0
- package/dist-public/src/machineState.js +9 -0
- package/dist-public/src/notionNango.d.ts +93 -0
- package/dist-public/src/notionNango.js +279 -0
- package/dist-public/src/orchestrationResult.d.ts +11 -0
- package/dist-public/src/orchestrationResult.js +73 -0
- package/dist-public/src/outlookNango.d.ts +124 -0
- package/dist-public/src/outlookNango.js +327 -0
- package/dist-public/src/packetCorrections.d.ts +40 -0
- package/dist-public/src/packetCorrections.js +172 -0
- package/dist-public/src/packetGlossary.d.ts +6 -0
- package/dist-public/src/packetGlossary.js +42 -0
- package/dist-public/src/packetIndex.d.ts +54 -0
- package/dist-public/src/packetIndex.js +744 -0
- package/dist-public/src/packetIndexEntry.d.ts +3 -0
- package/dist-public/src/packetIndexEntry.js +128 -0
- package/dist-public/src/packetIndexServe.d.ts +13 -0
- package/dist-public/src/packetIndexServe.js +113 -0
- package/dist-public/src/packetIndexWorker.d.ts +7 -0
- package/dist-public/src/packetIndexWorker.js +45 -0
- package/dist-public/src/packetLifecycle.d.ts +30 -0
- package/dist-public/src/packetLifecycle.js +127 -0
- package/dist-public/src/packetReconcile.d.ts +73 -0
- package/dist-public/src/packetReconcile.js +386 -0
- package/dist-public/src/packetStatus.d.ts +125 -0
- package/dist-public/src/packetStatus.js +770 -0
- package/dist-public/src/packetValidation.d.ts +17 -0
- package/dist-public/src/packetValidation.js +333 -0
- package/dist-public/src/packetVerify.d.ts +73 -0
- package/dist-public/src/packetVerify.js +303 -0
- package/dist-public/src/packetWrite.d.ts +52 -0
- package/dist-public/src/packetWrite.js +448 -0
- package/dist-public/src/pitch.d.ts +38 -0
- package/dist-public/src/pitch.js +154 -0
- package/dist-public/src/processMemo.d.ts +8 -0
- package/dist-public/src/processMemo.js +23 -0
- package/dist-public/src/productDetect.d.ts +30 -0
- package/dist-public/src/productDetect.js +376 -0
- package/dist-public/src/profile.d.ts +62 -0
- package/dist-public/src/profile.js +334 -0
- package/dist-public/src/questionModel.d.ts +46 -0
- package/dist-public/src/questionModel.js +74 -0
- package/dist-public/src/questionText.d.ts +7 -0
- package/dist-public/src/questionText.js +38 -0
- package/dist-public/src/redactConfig.d.ts +2 -0
- package/dist-public/src/redactConfig.js +11 -0
- package/dist-public/src/redactEngine.d.ts +59 -0
- package/dist-public/src/redactEngine.js +509 -0
- package/dist-public/src/redactGate.d.ts +63 -0
- package/dist-public/src/redactGate.js +209 -0
- package/dist-public/src/repoRead.d.ts +29 -0
- package/dist-public/src/repoRead.js +160 -0
- package/dist-public/src/research.d.ts +242 -0
- package/dist-public/src/research.js +1314 -0
- package/dist-public/src/researchCompletion.d.ts +34 -0
- package/dist-public/src/researchCompletion.js +123 -0
- package/dist-public/src/researchExecution.d.ts +47 -0
- package/dist-public/src/researchExecution.js +309 -0
- package/dist-public/src/researchFormat.d.ts +21 -0
- package/dist-public/src/researchFormat.js +77 -0
- package/dist-public/src/researchGate.d.ts +86 -0
- package/dist-public/src/researchGate.js +1036 -0
- package/dist-public/src/researchReceipt.d.ts +76 -0
- package/dist-public/src/researchReceipt.js +148 -0
- package/dist-public/src/researchRender.d.ts +2 -0
- package/dist-public/src/researchRender.js +267 -0
- package/dist-public/src/researchSigningKey.d.ts +19 -0
- package/dist-public/src/researchSigningKey.js +95 -0
- package/dist-public/src/riskClassify.d.ts +42 -0
- package/dist-public/src/riskClassify.js +149 -0
- package/dist-public/src/routines.d.ts +42 -0
- package/dist-public/src/routines.js +269 -0
- package/dist-public/src/routingPolicy.d.ts +172 -0
- package/dist-public/src/routingPolicy.js +646 -0
- package/dist-public/src/secretInput.d.ts +8 -0
- package/dist-public/src/secretInput.js +89 -0
- package/dist-public/src/selfCheck.d.ts +7 -0
- package/dist-public/src/selfCheck.js +473 -0
- package/dist-public/src/selfCheckCache.d.ts +29 -0
- package/dist-public/src/selfCheckCache.js +147 -0
- package/dist-public/src/severityClass.d.ts +15 -0
- package/dist-public/src/severityClass.js +22 -0
- package/dist-public/src/skillClientPolicy.d.ts +8 -0
- package/dist-public/src/skillClientPolicy.js +16 -0
- package/dist-public/src/skillLocal.d.ts +98 -0
- package/dist-public/src/skillLocal.js +463 -0
- package/dist-public/src/skillTreeDigest.d.ts +9 -0
- package/dist-public/src/skillTreeDigest.js +64 -0
- package/dist-public/src/slackNango.d.ts +62 -0
- package/dist-public/src/slackNango.js +208 -0
- package/dist-public/src/social/arxiv.d.ts +19 -0
- package/dist-public/src/social/arxiv.js +96 -0
- package/dist-public/src/social/github.d.ts +2 -0
- package/dist-public/src/social/github.js +78 -0
- package/dist-public/src/social/hackernews.d.ts +2 -0
- package/dist-public/src/social/hackernews.js +67 -0
- package/dist-public/src/social/index.d.ts +10 -0
- package/dist-public/src/social/index.js +79 -0
- package/dist-public/src/social/reddit.d.ts +2 -0
- package/dist-public/src/social/reddit.js +125 -0
- package/dist-public/src/social/types.d.ts +73 -0
- package/dist-public/src/social/types.js +61 -0
- package/dist-public/src/social/xml.d.ts +10 -0
- package/dist-public/src/social/xml.js +49 -0
- package/dist-public/src/social/youtube.d.ts +7 -0
- package/dist-public/src/social/youtube.js +217 -0
- package/dist-public/src/sourceIngress.d.ts +488 -0
- package/dist-public/src/sourceIngress.js +1651 -0
- package/dist-public/src/specAfter.d.ts +187 -0
- package/dist-public/src/specAfter.js +814 -0
- package/dist-public/src/specBudget.d.ts +124 -0
- package/dist-public/src/specBudget.js +424 -0
- package/dist-public/src/specDecisionSignals.d.ts +38 -0
- package/dist-public/src/specDecisionSignals.js +121 -0
- package/dist-public/src/specLinkedCommits.d.ts +7 -0
- package/dist-public/src/specLinkedCommits.js +107 -0
- package/dist-public/src/specSections.d.ts +105 -0
- package/dist-public/src/specSections.js +718 -0
- package/dist-public/src/statusGlyphs.d.ts +18 -0
- package/dist-public/src/statusGlyphs.js +75 -0
- package/dist-public/src/swarmCommand.d.ts +10 -0
- package/dist-public/src/swarmCommand.js +96 -0
- package/dist-public/src/teamsNango.d.ts +114 -0
- package/dist-public/src/teamsNango.js +301 -0
- package/dist-public/src/tokenStore.d.ts +10 -0
- package/dist-public/src/tokenStore.js +77 -0
- package/dist-public/src/trustEnvelope.d.ts +78 -0
- package/dist-public/src/trustEnvelope.js +392 -0
- package/dist-public/src/untrustedText.d.ts +6 -0
- package/dist-public/src/untrustedText.js +20 -0
- package/dist-public/src/updateNotice.d.ts +41 -0
- package/dist-public/src/updateNotice.js +290 -0
- package/dist-public/src/vendorYaml.d.ts +1 -0
- package/dist-public/src/vendorYaml.js +7374 -0
- package/dist-public/src/workflowRunActuals.d.ts +67 -0
- package/dist-public/src/workflowRunActuals.js +184 -0
- package/dist-public/src/zendeskDiscovery.d.ts +12 -0
- package/dist-public/src/zendeskDiscovery.js +513 -0
- package/dist-public/src/zendeskNango.d.ts +131 -0
- package/dist-public/src/zendeskNango.js +344 -0
- package/dist-public/src/zoomNango.d.ts +106 -0
- package/dist-public/src/zoomNango.js +351 -0
- package/docs/CHANGELOG.md +32 -0
- package/docs/THIRD_PARTY_NOTICES.md +36 -0
- package/package.json +71 -4
- package/schemas/bug-capsule-receipt.schema.json +54 -0
- package/schemas/bug-capsule.schema.json +189 -0
- package/schemas/discovery-evidence-envelope.schema.json +79 -0
- package/schemas/discovery-processing-receipt.schema.json +71 -0
- package/schemas/discovery-service-contract.schema.json +189 -0
- package/skills/AGENTS.md +32 -0
- package/skills/README.md +287 -0
- package/skills/bug/SKILL.md +49 -0
- package/skills/build-preview-spec/SKILL.md +103 -0
- package/skills/capture-external-artifact/SKILL.md +23 -0
- package/skills/capture-external-artifact/agents/openai.yaml +4 -0
- package/skills/capture-external-artifact/references/extractor-libraries.md +27 -0
- package/skills/check-spec-health/SKILL.md +45 -0
- package/skills/check-spec-health/agents/openai.yaml +4 -0
- package/skills/competitive-positioning/SKILL.md +86 -0
- package/skills/competitive-positioning/agents/openai.yaml +4 -0
- package/skills/cpo-lens/SKILL.md +398 -0
- package/skills/cpo-lens/agents/openai.yaml +4 -0
- package/skills/create-prd/SKILL.md +26 -0
- package/skills/create-prd/agents/openai.yaml +4 -0
- package/skills/customer-discovery/SKILL.md +192 -0
- package/skills/design-system/SKILL.md +49 -0
- package/skills/design-system/agents/openai.yaml +4 -0
- package/skills/discussion-guide/SKILL.md +75 -0
- package/skills/discussion-guide/agents/openai.yaml +4 -0
- package/skills/firecrawl-research-papers/SKILL.md +96 -0
- package/skills/firecrawl-research-papers/agents/openai.yaml +4 -0
- package/skills/foo-roast/SKILL.md +325 -0
- package/skills/generate-gtm-brief/SKILL.md +41 -0
- package/skills/generate-gtm-brief/agents/openai.yaml +4 -0
- package/skills/generate-gtm-brief/references/gtm-brief-template.md +56 -0
- package/skills/gong-quotes/SKILL.md +43 -0
- package/skills/gong-quotes/agents/openai.yaml +4 -0
- package/skills/grill-me/SKILL.md +27 -0
- package/skills/grill-me/agents/openai.yaml +4 -0
- package/skills/ideate/SKILL.md +180 -0
- package/skills/ideate/references/family-packs.md +5 -0
- package/skills/initiative-tracker/SKILL.md +23 -0
- package/skills/initiative-tracker/agents/openai.yaml +4 -0
- package/skills/interop-review/SKILL.md +25 -0
- package/skills/interop-review/agents/openai.yaml +4 -0
- package/skills/interview-me/SKILL.md +404 -0
- package/skills/interview-me/agents/openai.yaml +4 -0
- package/skills/loop-library-audit/SKILL.md +123 -0
- package/skills/pitch/SKILL.md +110 -0
- package/skills/pitch/references/opportunity-assessment.md +136 -0
- package/skills/pitch/references/prfaq-template.md +54 -0
- package/skills/pmm-release-briefing/SKILL.md +27 -0
- package/skills/pmm-release-briefing/agents/openai.yaml +4 -0
- package/skills/pmm-release-briefing/references/variant-generalized.md +16 -0
- package/skills/positioning-messaging/SKILL.md +70 -0
- package/skills/positioning-messaging/agents/openai.yaml +4 -0
- package/skills/positioning-messaging/references/guest-insights.md +1400 -0
- package/skills/preview-swarm/SKILL.md +418 -0
- package/skills/preview-swarm/agents/openai.yaml +4 -0
- package/skills/preview-swarm/references/html-effectiveness-build-previews.md +168 -0
- package/skills/product-copywriting/SKILL.md +127 -0
- package/skills/product-copywriting/agents/openai.yaml +4 -0
- package/skills/product-copywriting/references/foo-voice.md +26 -0
- package/skills/product-shape-interview/SKILL.md +219 -0
- package/skills/product-shape-interview/agents/openai.yaml +4 -0
- package/skills/ready-for-release/SKILL.md +39 -0
- package/skills/ready-for-release/agents/openai.yaml +4 -0
- package/skills/redact-transcripts/SKILL.md +23 -0
- package/skills/redact-transcripts/agents/openai.yaml +4 -0
- package/skills/research-brief/SKILL.md +48 -0
- package/skills/research-brief/agents/openai.yaml +4 -0
- package/skills/research-refresh/SKILL.md +63 -0
- package/skills/research-refresh/references/worked-cases.md +44 -0
- package/skills/review-loop/SKILL.md +200 -0
- package/skills/review-spec/SKILL.md +32 -0
- package/skills/review-spec/agents/openai.yaml +4 -0
- package/skills/rfc-from-research/SKILL.md +42 -0
- package/skills/rfc-from-research/agents/openai.yaml +4 -0
- package/skills/rfc-from-research/references/rfc-pattern.md +69 -0
- package/skills/skill-registry.yaml +810 -0
- package/skills/spec-cleanup/SKILL.md +103 -0
- package/skills/spec-cleanup/agents/openai.yaml +4 -0
- package/skills/spec-swarm/SKILL.md +87 -0
- package/skills/spec-swarm/agents/openai.yaml +4 -0
- package/skills/spec-swarm/template/SKILL.template.md +94 -0
- package/skills/spec-swarm/template/personas/accessibility-inclusion.md +40 -0
- package/skills/spec-swarm/template/personas/ai-technical-pm.md +69 -0
- package/skills/spec-swarm/template/personas/analytics-engineering.md +39 -0
- package/skills/spec-swarm/template/personas/applied-ai-eval.md +64 -0
- package/skills/spec-swarm/template/personas/business-gm-pm.md +67 -0
- package/skills/spec-swarm/template/personas/consumer-craft-pm.md +68 -0
- package/skills/spec-swarm/template/personas/content-design.md +40 -0
- package/skills/spec-swarm/template/personas/cpo.md +42 -0
- package/skills/spec-swarm/template/personas/data-science.md +42 -0
- package/skills/spec-swarm/template/personas/developer-experience.md +65 -0
- package/skills/spec-swarm/template/personas/dx-product.md +70 -0
- package/skills/spec-swarm/template/personas/field.md +43 -0
- package/skills/spec-swarm/template/personas/finance-cfo.md +40 -0
- package/skills/spec-swarm/template/personas/growth-pm.md +67 -0
- package/skills/spec-swarm/template/personas/platform-pm.md +67 -0
- package/skills/spec-swarm/template/personas/pmm.md +43 -0
- package/skills/spec-swarm/template/personas/principal-product-designer.md +42 -0
- package/skills/spec-swarm/template/personas/product-ops-program.md +41 -0
- package/skills/spec-swarm/template/personas/qa-release.md +41 -0
- package/skills/spec-swarm/template/personas/responsible-ai-safety.md +64 -0
- package/skills/spec-swarm/template/personas/security-privacy-legal.md +40 -0
- package/skills/spec-swarm/template/personas/strategy-competitive.md +41 -0
- package/skills/spec-swarm/template/personas/technical-architect.md +42 -0
- package/skills/spec-swarm/template/personas/technical-lead.md +43 -0
- package/skills/spec-swarm/template/personas/user-research.md +41 -0
- package/skills/spec-swarm-accessibility-inclusion/SKILL.md +95 -0
- package/skills/spec-swarm-accessibility-inclusion/agents/openai.yaml +4 -0
- package/skills/spec-swarm-ai-technical-pm/SKILL.md +124 -0
- package/skills/spec-swarm-analytics-engineering/SKILL.md +94 -0
- package/skills/spec-swarm-analytics-engineering/agents/openai.yaml +4 -0
- package/skills/spec-swarm-applied-ai-eval/SKILL.md +120 -0
- package/skills/spec-swarm-business-gm-pm/SKILL.md +122 -0
- package/skills/spec-swarm-consumer-craft-pm/SKILL.md +122 -0
- package/skills/spec-swarm-content-design/SKILL.md +95 -0
- package/skills/spec-swarm-content-design/agents/openai.yaml +4 -0
- package/skills/spec-swarm-cpo/SKILL.md +94 -0
- package/skills/spec-swarm-cpo/agents/openai.yaml +4 -0
- package/skills/spec-swarm-data-science/SKILL.md +95 -0
- package/skills/spec-swarm-data-science/agents/openai.yaml +4 -0
- package/skills/spec-swarm-developer-experience/SKILL.md +121 -0
- package/skills/spec-swarm-dx-product/SKILL.md +126 -0
- package/skills/spec-swarm-field/SKILL.md +96 -0
- package/skills/spec-swarm-field/agents/openai.yaml +4 -0
- package/skills/spec-swarm-finance-cfo/SKILL.md +95 -0
- package/skills/spec-swarm-finance-cfo/agents/openai.yaml +4 -0
- package/skills/spec-swarm-growth-pm/SKILL.md +122 -0
- package/skills/spec-swarm-platform-pm/SKILL.md +122 -0
- package/skills/spec-swarm-pmm/SKILL.md +96 -0
- package/skills/spec-swarm-pmm/agents/openai.yaml +4 -0
- package/skills/spec-swarm-principal-product-designer/SKILL.md +95 -0
- package/skills/spec-swarm-principal-product-designer/agents/openai.yaml +4 -0
- package/skills/spec-swarm-product-ops-program/SKILL.md +96 -0
- package/skills/spec-swarm-product-ops-program/agents/openai.yaml +4 -0
- package/skills/spec-swarm-qa-release/SKILL.md +96 -0
- package/skills/spec-swarm-qa-release/agents/openai.yaml +4 -0
- package/skills/spec-swarm-responsible-ai-safety/SKILL.md +120 -0
- package/skills/spec-swarm-security-privacy-legal/SKILL.md +95 -0
- package/skills/spec-swarm-security-privacy-legal/agents/openai.yaml +4 -0
- package/skills/spec-swarm-strategy-competitive/SKILL.md +96 -0
- package/skills/spec-swarm-strategy-competitive/agents/openai.yaml +4 -0
- package/skills/spec-swarm-technical-architect/SKILL.md +95 -0
- package/skills/spec-swarm-technical-architect/agents/openai.yaml +4 -0
- package/skills/spec-swarm-technical-lead/SKILL.md +96 -0
- package/skills/spec-swarm-technical-lead/agents/openai.yaml +4 -0
- package/skills/spec-swarm-user-research/SKILL.md +95 -0
- package/skills/spec-swarm-user-research/agents/openai.yaml +4 -0
- package/skills/strategy-check/SKILL.md +170 -0
- package/skills/strategy-check/agents/openai.yaml +4 -0
- package/skills/study-digest/SKILL.md +41 -0
- package/skills/synthetic-customer/SKILL.md +68 -0
- package/skills/update-cli-spec/SKILL.md +69 -0
- package/skills/update-cli-spec/agents/openai.yaml +4 -0
- package/skills/voc-researcher/SKILL.md +45 -0
- package/skills/voc-researcher/agents/openai.yaml +4 -0
- package/skills-lock.json +35 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// This registry is intentionally narrow. It catches productfoo's filing system and
|
|
2
|
+
// process chrome, not ordinary product words. In particular, words such as
|
|
3
|
+
// "agent", "task", "spec", and "drift" are valid user language on their own.
|
|
4
|
+
// Token boundaries apply the same false-positive lesson as the research gate:
|
|
5
|
+
// a substring is not evidence that the risky phrase is present.
|
|
6
|
+
const RULES = [
|
|
7
|
+
{
|
|
8
|
+
id: "HS-001",
|
|
9
|
+
pattern: /(?<![\w-])(?:OQ-?\d{1,4}|(?:T|R|C|D)-\d{1,4})(?![\w-])/gi,
|
|
10
|
+
rewrite: "Remove the internal identifier and ask or state the thing directly.",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "HS-002",
|
|
14
|
+
pattern: /(?<![\w-])(?:spec_id|done_when|next_action|decision_findings|tasks\.yaml|events\.jsonl)(?![\w-])|\bState:\s*needs-decision\b|\b(?:packet handoff|packet grammar|spec packet|loop contract)\b/gi,
|
|
15
|
+
rewrite: "Describe the state or next step in ordinary words instead of exposing the storage format.",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "HS-004",
|
|
19
|
+
pattern: /\b(?:judgment ledger|Shape Brief|product bet|source and approval boundaries|MVP scope|validation bar|human judgment|human is the decider|read-only view of the (?:agent|assistant)|(?:Foo|productfoo) has taken over your default behavior)\b|\b(?:Capability|Skill adapter):/gi,
|
|
20
|
+
rewrite: "Replace productfoo's filing or process label with what it means for this person.",
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const PROCESS_LABELS = new Set([
|
|
24
|
+
"what the assistant sees",
|
|
25
|
+
"what the agent sees",
|
|
26
|
+
"thinks",
|
|
27
|
+
"based on",
|
|
28
|
+
"would do",
|
|
29
|
+
"needs you",
|
|
30
|
+
"updates",
|
|
31
|
+
"this direction",
|
|
32
|
+
]);
|
|
33
|
+
const PROCESS_LABEL_REWRITE = "Remove the process label and state the useful fact, question, or action directly.";
|
|
34
|
+
function normalizedProcessLabel(line) {
|
|
35
|
+
let label = line.trim();
|
|
36
|
+
label = label.replace(/^#{1,6}\s+/, "").replace(/:\s*$/, "").trim();
|
|
37
|
+
// Markdown decoration does not make productfoo's process chrome user language.
|
|
38
|
+
// Peel matching emphasis pairs, including nested pairs, before comparison.
|
|
39
|
+
let changed = true;
|
|
40
|
+
while (changed) {
|
|
41
|
+
changed = false;
|
|
42
|
+
for (const marker of ["**", "__", "*", "_"]) {
|
|
43
|
+
if (label.length > marker.length * 2 && label.startsWith(marker) && label.endsWith(marker)) {
|
|
44
|
+
label = label.slice(marker.length, -marker.length).trim();
|
|
45
|
+
changed = true;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// productfoo renders the state name as uppercase DRIFT. Lowercase/title-case
|
|
51
|
+
// "drift" remains ordinary product language and must not be blocked.
|
|
52
|
+
return label === "DRIFT" || PROCESS_LABELS.has(label.toLocaleLowerCase("en-US")) ? label : undefined;
|
|
53
|
+
}
|
|
54
|
+
function blankInlineCode(line) {
|
|
55
|
+
const output = [...line];
|
|
56
|
+
let index = 0;
|
|
57
|
+
while (index < line.length) {
|
|
58
|
+
if (line[index] !== "`") {
|
|
59
|
+
index += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
let runEnd = index;
|
|
63
|
+
while (line[runEnd] === "`")
|
|
64
|
+
runEnd += 1;
|
|
65
|
+
const delimiter = line.slice(index, runEnd);
|
|
66
|
+
const close = line.indexOf(delimiter, runEnd);
|
|
67
|
+
if (close === -1) {
|
|
68
|
+
index = runEnd;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
output.fill(" ", index, close + delimiter.length);
|
|
72
|
+
index = close + delimiter.length;
|
|
73
|
+
}
|
|
74
|
+
return output.join("");
|
|
75
|
+
}
|
|
76
|
+
function proseLines(text) {
|
|
77
|
+
const output = [];
|
|
78
|
+
let fence;
|
|
79
|
+
for (const [index, raw] of text.split(/\r?\n/).entries()) {
|
|
80
|
+
const trimmed = raw.trim();
|
|
81
|
+
const fenceRun = trimmed.match(/^(`{3,}|~{3,})/)?.[1];
|
|
82
|
+
if (!fence && fenceRun) {
|
|
83
|
+
fence = { marker: fenceRun[0], length: fenceRun.length };
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (fence) {
|
|
87
|
+
const closesFence = fenceRun !== undefined &&
|
|
88
|
+
fenceRun[0] === fence.marker &&
|
|
89
|
+
fenceRun.length >= fence.length &&
|
|
90
|
+
trimmed.slice(fenceRun.length).trim() === "";
|
|
91
|
+
if (closesFence)
|
|
92
|
+
fence = undefined;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
output.push({ line: index + 1, text: blankInlineCode(raw) });
|
|
96
|
+
}
|
|
97
|
+
return output;
|
|
98
|
+
}
|
|
99
|
+
export function evaluateHumanSurface(text) {
|
|
100
|
+
if (!text.trim())
|
|
101
|
+
return { ok: false, findings: [], error: "empty-input" };
|
|
102
|
+
const findings = [];
|
|
103
|
+
for (const candidate of proseLines(text)) {
|
|
104
|
+
const processLabel = normalizedProcessLabel(candidate.text);
|
|
105
|
+
if (processLabel) {
|
|
106
|
+
findings.push({
|
|
107
|
+
rule: "HS-003",
|
|
108
|
+
line: candidate.line,
|
|
109
|
+
phrase: processLabel,
|
|
110
|
+
rewrite: PROCESS_LABEL_REWRITE,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
for (const rule of RULES) {
|
|
114
|
+
// RegExp instances with the global flag retain lastIndex. matchAll on a
|
|
115
|
+
// fresh clone keeps every line independent and finds multiple leaks on
|
|
116
|
+
// one line without mutating the shared registry.
|
|
117
|
+
const matches = candidate.text.matchAll(new RegExp(rule.pattern.source, rule.pattern.flags));
|
|
118
|
+
for (const match of matches) {
|
|
119
|
+
const phrase = match[0].trim();
|
|
120
|
+
if (!phrase)
|
|
121
|
+
continue;
|
|
122
|
+
findings.push({ rule: rule.id, line: candidate.line, phrase, rewrite: rule.rewrite });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { ok: findings.length === 0, findings };
|
|
127
|
+
}
|
|
128
|
+
export function renderHumanSurfaceEval(result) {
|
|
129
|
+
if (result.error === "empty-input")
|
|
130
|
+
return "No user-facing copy was provided. Pass the draft on stdin and try again.\n";
|
|
131
|
+
if (result.ok)
|
|
132
|
+
return "User-facing copy is clear.\n";
|
|
133
|
+
return [
|
|
134
|
+
`User-facing copy needs a rewrite (${result.findings.length} finding${result.findings.length === 1 ? "" : "s"}).`,
|
|
135
|
+
...result.findings.map((finding) => `- Line ${finding.line}: replace "${finding.phrase}". ${finding.rewrite}`),
|
|
136
|
+
"Rewrite the draft and run this check again before showing it to the user.",
|
|
137
|
+
"",
|
|
138
|
+
].join("\n");
|
|
139
|
+
}
|
|
140
|
+
export class HumanSurfaceLeakError extends Error {
|
|
141
|
+
result;
|
|
142
|
+
constructor(result) {
|
|
143
|
+
// This error can cross the CLI boundary. Keep its message safe for the
|
|
144
|
+
// person at the terminal; detailed findings stay on the typed result for
|
|
145
|
+
// tests and the explicit agent-only stdin evaluator.
|
|
146
|
+
super("productfoo could not prepare clear user-facing copy. Nothing was shown; update productfoo and try again.");
|
|
147
|
+
this.name = "HumanSurfaceLeakError";
|
|
148
|
+
this.result = result;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export function guardHumanSurface(text) {
|
|
152
|
+
const result = evaluateHumanSurface(text);
|
|
153
|
+
if (!result.ok)
|
|
154
|
+
throw new HumanSurfaceLeakError(result);
|
|
155
|
+
return text;
|
|
156
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FamilyPack } from "./conductor/pack.js";
|
|
2
|
+
import type { Depth, GateResult } from "./conductor/types.js";
|
|
3
|
+
export type IdeateDepth = Depth;
|
|
4
|
+
export interface IdeateTier {
|
|
5
|
+
depth: IdeateDepth;
|
|
6
|
+
reframes: number;
|
|
7
|
+
ideators: number;
|
|
8
|
+
stress_on: number;
|
|
9
|
+
judges: number;
|
|
10
|
+
extra_dissent_round: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const MAX_IDEATORS = 8;
|
|
13
|
+
export declare const BUILD_ON_ROUNDS = 1;
|
|
14
|
+
export interface IdeatorCell {
|
|
15
|
+
ideator: string;
|
|
16
|
+
frame: string;
|
|
17
|
+
lens: string;
|
|
18
|
+
seed: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function tierFromPack(pack: FamilyPack): IdeateTier;
|
|
21
|
+
export declare function cellMatrixFromPack(pack: FamilyPack): IdeatorCell[];
|
|
22
|
+
export interface IdeatePlan {
|
|
23
|
+
schema_version: "0.1";
|
|
24
|
+
idea: string;
|
|
25
|
+
depth: IdeateDepth;
|
|
26
|
+
tier: IdeateTier;
|
|
27
|
+
cells: IdeatorCell[];
|
|
28
|
+
phases: string[];
|
|
29
|
+
record_path: string;
|
|
30
|
+
verification: string;
|
|
31
|
+
handoff: string;
|
|
32
|
+
decider: "human";
|
|
33
|
+
}
|
|
34
|
+
export declare function planFromPack(pack: FamilyPack, idea: string, at: string): IdeatePlan;
|
|
35
|
+
export declare function scaffoldFromPack(pack: FamilyPack, root: string, idea: string, at: string): string;
|
|
36
|
+
export type IdeateCheckFinding = GateResult["findings"][number];
|
|
37
|
+
export type IdeateCheckResult = GateResult;
|
|
38
|
+
export declare function checkRecordWithPack(pack: FamilyPack, recordText: string): IdeateCheckResult;
|
|
39
|
+
export declare function writeMeasuredMeter(recordText: string, meterText: string): string;
|
|
40
|
+
export declare function runIdeateCommand(root: string, args: string[]): Promise<{
|
|
41
|
+
output: string;
|
|
42
|
+
exitCode: number;
|
|
43
|
+
}>;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
// ideate-command-v0 → methodology-compiler-v0 (T-003) → methodology-as-data
|
|
2
|
+
// (T-004): `foo ideate` is an adapter over the conductor. The family's
|
|
3
|
+
// orchestration lives as DATA and is resolved from the verified local package.
|
|
4
|
+
// A missing family is unavailable while remote delivery is rebuilt. This module
|
|
5
|
+
// imports NO family: it drives the engine from a resolved FamilyPack. The CLI
|
|
6
|
+
// still never generates ideas and never picks a winner (D6).
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { buildCells, checkRecord, slugify } from "./conductor/engine.js";
|
|
10
|
+
import { resolveFamilyPack } from "./conductor/familyDelivery.js";
|
|
11
|
+
import { computeDiversity, clustererLine, meterLine, parseIdeaObjects, readDeclaredMeter, DIVERSITY_METER_LINE, } from "./conductor/diversity.js";
|
|
12
|
+
import { contractFromPack, recordFromPack } from "./conductor/pack.js";
|
|
13
|
+
import { markFailure } from "./errorTaxonomy.js";
|
|
14
|
+
import { checkFalsification, decisionResult } from "./conductor/ideateDecision.js";
|
|
15
|
+
import { renderOrchestrationResult } from "./orchestrationResult.js";
|
|
16
|
+
import { findIdeateContext } from "./ideateContext.js";
|
|
17
|
+
export const MAX_IDEATORS = 8;
|
|
18
|
+
export const BUILD_ON_ROUNDS = 1;
|
|
19
|
+
// The engine functions only read a couple of fields off a FamilyDefinition;
|
|
20
|
+
// a pack carries them, so these shims let the generic engine run from pack data.
|
|
21
|
+
function cellsShim(pack) {
|
|
22
|
+
return { cells: pack.cells };
|
|
23
|
+
}
|
|
24
|
+
function gatesShim(pack) {
|
|
25
|
+
return { gates: pack.gates, depths: pack.depths };
|
|
26
|
+
}
|
|
27
|
+
export function tierFromPack(pack) {
|
|
28
|
+
const t = pack.depths[pack.depth];
|
|
29
|
+
return {
|
|
30
|
+
depth: pack.depth,
|
|
31
|
+
reframes: Number(t.reframes),
|
|
32
|
+
ideators: Number(t.ideators),
|
|
33
|
+
stress_on: Number(t.stress_on),
|
|
34
|
+
judges: Number(t.judges),
|
|
35
|
+
extra_dissent_round: Boolean(t.extra_dissent_round),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function cellMatrixFromPack(pack) {
|
|
39
|
+
return buildCells(cellsShim(pack), pack.depths[pack.depth]).map((c) => ({
|
|
40
|
+
ideator: c.role,
|
|
41
|
+
frame: String(c.attrs.frame),
|
|
42
|
+
lens: String(c.attrs.lens),
|
|
43
|
+
seed: Number(c.attrs.seed),
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
function recordPathFromPack(pack, idea, at) {
|
|
47
|
+
if (!pack.recordDir)
|
|
48
|
+
throw new Error(`${pack.family} has no record dir`);
|
|
49
|
+
return path.posix.join(pack.recordDir, `${at.slice(0, 10)}-${slugify(idea)}.md`);
|
|
50
|
+
}
|
|
51
|
+
export function planFromPack(pack, idea, at) {
|
|
52
|
+
const recordPath = recordPathFromPack(pack, idea, at);
|
|
53
|
+
return {
|
|
54
|
+
schema_version: "0.1",
|
|
55
|
+
idea,
|
|
56
|
+
depth: pack.depth,
|
|
57
|
+
tier: tierFromPack(pack),
|
|
58
|
+
cells: cellMatrixFromPack(pack),
|
|
59
|
+
phases: [...pack.phases],
|
|
60
|
+
record_path: recordPath,
|
|
61
|
+
verification: `foo ideate check ${recordPath}`,
|
|
62
|
+
handoff: pack.handoff,
|
|
63
|
+
decider: "human",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Scaffold a record from a pack: substitute the real idea + timestamp into the
|
|
67
|
+
// pack's pre-rendered frontmatter/body and write it to the real record path.
|
|
68
|
+
export function scaffoldFromPack(pack, root, idea, at) {
|
|
69
|
+
const rendered = recordFromPack(pack, idea, at);
|
|
70
|
+
if (!rendered)
|
|
71
|
+
throw new Error(`${pack.family} has no record template`);
|
|
72
|
+
const recordPath = recordPathFromPack(pack, idea, at);
|
|
73
|
+
const full = path.resolve(root, recordPath);
|
|
74
|
+
if (existsSync(full))
|
|
75
|
+
throw new Error(`${pack.family} record already exists: ${recordPath}`);
|
|
76
|
+
mkdirSync(path.dirname(full), { recursive: true });
|
|
77
|
+
writeFileSync(full, [...rendered.frontmatter, ...rendered.body].join("\n"));
|
|
78
|
+
return full;
|
|
79
|
+
}
|
|
80
|
+
export function checkRecordWithPack(pack, recordText) {
|
|
81
|
+
return checkRecord(gatesShim(pack), recordText);
|
|
82
|
+
}
|
|
83
|
+
// --- Diversity (ideate-cost-v1 T-003) -----------------------------------------
|
|
84
|
+
// Rewrite the record's meter with the computed one and mark it measured. The
|
|
85
|
+
// CLI computing this number is the whole point: the orchestrator never reads 70
|
|
86
|
+
// ideas to count near-dupes, so the count stops being a judgment call. `exhausted`
|
|
87
|
+
// is NOT computed — whether the idea space is spent is a run's honest call, so
|
|
88
|
+
// whatever the record already declared survives the rewrite.
|
|
89
|
+
// The clusterer that produced the number is stamped alongside it, so a later
|
|
90
|
+
// reader (and the provenance gate) can tell a current number from one an older,
|
|
91
|
+
// weaker clusterer produced — the meter is only as trustworthy as the code that
|
|
92
|
+
// computed it, and that used to be invisible.
|
|
93
|
+
export function writeMeasuredMeter(recordText, meterText) {
|
|
94
|
+
const withMeter = recordText.replace(DIVERSITY_METER_LINE, meterText);
|
|
95
|
+
const withMethod = /^diversity_method:/m.test(withMeter)
|
|
96
|
+
? withMeter.replace(/^diversity_method:.*$/m, "diversity_method: measured")
|
|
97
|
+
: withMeter.replace(meterText, `${meterText}\ndiversity_method: measured`);
|
|
98
|
+
return /^diversity_clusterer:/m.test(withMethod)
|
|
99
|
+
? withMethod.replace(/^diversity_clusterer:.*$/m, clustererLine())
|
|
100
|
+
: withMethod.replace("diversity_method: measured", `diversity_method: measured\n${clustererLine()}`);
|
|
101
|
+
}
|
|
102
|
+
// --- CLI ----------------------------------------------------------------------
|
|
103
|
+
const LEAN = (process.env.FOO_LEAN_CONTRACT ?? "").trim() === "1";
|
|
104
|
+
export async function runIdeateCommand(root, args) {
|
|
105
|
+
const json = args.includes("--json");
|
|
106
|
+
if (args[0] === "context") {
|
|
107
|
+
const idea = args.slice(1).filter((arg) => arg !== "--json").join(" ").trim();
|
|
108
|
+
if (!idea)
|
|
109
|
+
return { output: 'usage: foo ideate context "<idea>" [--json]\n', exitCode: 1 };
|
|
110
|
+
const context = findIdeateContext(root, idea);
|
|
111
|
+
return { output: json ? `${JSON.stringify(context, null, 2)}\n` : [
|
|
112
|
+
"Prior work to read before generating ideas",
|
|
113
|
+
...context.candidates.map((c, i) => `${i + 1}. ${c.title} — ${c.path}`),
|
|
114
|
+
...(context.candidates.length ? [] : ["No keyword matches found. Inspect related names and user-supplied references before declaring a gap."]),
|
|
115
|
+
context.limitations, "",
|
|
116
|
+
].join("\n"), exitCode: 0 };
|
|
117
|
+
}
|
|
118
|
+
if (args[0] === "check" || args[0] === "result") {
|
|
119
|
+
const target = args[1];
|
|
120
|
+
if (!target) {
|
|
121
|
+
markFailure({ errorClass: "usage_error", errorCode: "E_IDEATE_IDEA_MISSING", message: "ideate check: no record given" });
|
|
122
|
+
return { output: `usage: foo ideate ${args[0]} <record.md> [--json]${args[0] === "check" ? " [--before-build-on]" : ""}\n`, exitCode: 1 };
|
|
123
|
+
}
|
|
124
|
+
const full = path.resolve(root, target);
|
|
125
|
+
if (!existsSync(full)) {
|
|
126
|
+
markFailure({ errorClass: "not_found", errorCode: "E_SPEC_NOT_FOUND", message: `ideate record not found: ${target}` });
|
|
127
|
+
return { output: `ideate record not found: ${target}\n`, exitCode: 1 };
|
|
128
|
+
}
|
|
129
|
+
// gates are depth-independent; any depth's pack carries the same gate set.
|
|
130
|
+
const pack = await resolveFamilyPack("ideate", "standard", LEAN);
|
|
131
|
+
const record = readFileSync(full, "utf8");
|
|
132
|
+
const early = args[0] === "check" && args.includes("--before-build-on");
|
|
133
|
+
const errors = early ? checkFalsification(record) : [];
|
|
134
|
+
const result = early
|
|
135
|
+
? { ok: !errors.length, findings: [{ check: "early-falsification", ok: !errors.length, detail: errors.length ? errors.join("; ") : "claim coverage verified; unknowns remain hypotheses, not facts" }] }
|
|
136
|
+
: checkRecordWithPack(pack, record);
|
|
137
|
+
if (args[0] === "result" && result.ok) {
|
|
138
|
+
try {
|
|
139
|
+
const value = decisionResult(record);
|
|
140
|
+
return { output: json ? `${JSON.stringify(value, null, 2)}\n` : renderOrchestrationResult(value), exitCode: 0 };
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const detail = error.message;
|
|
144
|
+
return { output: json ? `${JSON.stringify({ ok: false, detail })}\n` : `Cannot render decision: ${detail}\n`, exitCode: 1 };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (json)
|
|
148
|
+
return { output: `${JSON.stringify({ schema_version: "0.1", ...result }, null, 2)}\n`, exitCode: result.ok ? 0 : 1 };
|
|
149
|
+
const lines = [`ideate check — ${target}`];
|
|
150
|
+
for (const f of result.findings)
|
|
151
|
+
lines.push(` ${f.ok ? "ok " : "FAIL"} ${f.check}: ${f.detail}`);
|
|
152
|
+
lines.push(result.ok ? (early ? "Early check passes. Continue only with surviving ideas; disclose unknowns and recheck added claims." : "Record verifies: shortlist is contract-complete.") : "Record does not verify — fix the FAIL lines; do not hand off an unverified shortlist.");
|
|
153
|
+
return { output: `${lines.join("\n")}\n`, exitCode: result.ok ? 0 : 1 };
|
|
154
|
+
}
|
|
155
|
+
if (args[0] === "read") {
|
|
156
|
+
// #700: the pool is stored as machine JSON so the meter can compute from
|
|
157
|
+
// it — but a human reads ideas, not objects. This renders the stored pool
|
|
158
|
+
// grouped by computed cluster, claims first, so the record's substance is
|
|
159
|
+
// readable without parsing anything.
|
|
160
|
+
const target = args[1];
|
|
161
|
+
if (!target) {
|
|
162
|
+
markFailure({ errorClass: "usage_error", errorCode: "E_IDEATE_IDEA_MISSING", message: "ideate read: no record given" });
|
|
163
|
+
return { output: "usage: foo ideate read <record.md>\n", exitCode: 1 };
|
|
164
|
+
}
|
|
165
|
+
const full = path.resolve(root, target);
|
|
166
|
+
if (!existsSync(full)) {
|
|
167
|
+
markFailure({ errorClass: "not_found", errorCode: "E_SPEC_NOT_FOUND", message: `ideate record not found: ${target}` });
|
|
168
|
+
return { output: `ideate record not found: ${target}\n`, exitCode: 1 };
|
|
169
|
+
}
|
|
170
|
+
const parsed = parseIdeaObjects(readFileSync(full, "utf8"));
|
|
171
|
+
if (!parsed.present || parsed.ideas.length === 0) {
|
|
172
|
+
return { output: "Nothing to read — the record stores no ideas yet.\n", exitCode: 1 };
|
|
173
|
+
}
|
|
174
|
+
const byId = new Map(parsed.ideas.map((i) => [i.id, i]));
|
|
175
|
+
const computed = computeDiversity(parsed.ideas);
|
|
176
|
+
const lines = [];
|
|
177
|
+
computed.clusters.forEach((ids, index) => {
|
|
178
|
+
lines.push(`### C${index + 1}${ids.length > 1 ? ` — ${ids.length} ideas, merged as one move` : ""}`);
|
|
179
|
+
for (const id of ids) {
|
|
180
|
+
const idea = byId.get(id);
|
|
181
|
+
if (!idea)
|
|
182
|
+
continue;
|
|
183
|
+
lines.push("");
|
|
184
|
+
lines.push(`**${idea.claim}** — ${id} · ${idea.frame} × ${idea.lens}`);
|
|
185
|
+
if (idea.reasoning.trim())
|
|
186
|
+
lines.push(`- move: ${idea.reasoning}`);
|
|
187
|
+
lines.push(`- how: ${idea.mechanism}`);
|
|
188
|
+
lines.push(`- novelty: ${idea.novelty}`);
|
|
189
|
+
lines.push(`- bet: ${idea.assumption}`);
|
|
190
|
+
}
|
|
191
|
+
lines.push("");
|
|
192
|
+
});
|
|
193
|
+
return { output: `${lines.join("\n")}\n`, exitCode: 0 };
|
|
194
|
+
}
|
|
195
|
+
if (args[0] === "diversity") {
|
|
196
|
+
const target = args[1];
|
|
197
|
+
if (!target || target.startsWith("--")) {
|
|
198
|
+
markFailure({ errorClass: "usage_error", errorCode: "E_IDEATE_IDEA_MISSING", message: "ideate diversity: no record given" });
|
|
199
|
+
return { output: "usage: foo ideate diversity <record.md> [--write] [--json]\n", exitCode: 1 };
|
|
200
|
+
}
|
|
201
|
+
const full = path.resolve(root, target);
|
|
202
|
+
if (!existsSync(full)) {
|
|
203
|
+
markFailure({ errorClass: "not_found", errorCode: "E_SPEC_NOT_FOUND", message: `ideate record not found: ${target}` });
|
|
204
|
+
return { output: `ideate record not found: ${target}\n`, exitCode: 1 };
|
|
205
|
+
}
|
|
206
|
+
const text = readFileSync(full, "utf8");
|
|
207
|
+
const parsed = parseIdeaObjects(text);
|
|
208
|
+
if (!parsed.present || parsed.errors.length || parsed.ideas.length === 0) {
|
|
209
|
+
const why = !parsed.present
|
|
210
|
+
? "no ideas block in the record — the pools have not stored their objects yet"
|
|
211
|
+
: parsed.errors.length
|
|
212
|
+
? `stored ideas do not validate: ${parsed.errors.join("; ")}`
|
|
213
|
+
: "the ideas block is empty — nothing to cluster";
|
|
214
|
+
// A refusal by design, not a crash: the record cannot show its work, so
|
|
215
|
+
// foo declines to hand back a number it would be inventing.
|
|
216
|
+
markFailure({ errorClass: "gate_block", errorCode: "E_GATE_BLOCKED", message: `ideate diversity: ${why}` });
|
|
217
|
+
if (json)
|
|
218
|
+
return { output: `${JSON.stringify({ schema_version: "0.1", ok: false, detail: why }, null, 2)}\n`, exitCode: 1 };
|
|
219
|
+
return { output: `Cannot measure diversity — ${why}.\nUntil the ideas are stored, the meter is a guess: say diversity_method: estimated.\n`, exitCode: 1 };
|
|
220
|
+
}
|
|
221
|
+
const computed = computeDiversity(parsed.ideas, readDeclaredMeter(text)?.exhausted ?? false);
|
|
222
|
+
const line = meterLine(computed);
|
|
223
|
+
if (args.includes("--write"))
|
|
224
|
+
writeFileSync(full, writeMeasuredMeter(text, line));
|
|
225
|
+
if (json)
|
|
226
|
+
return { output: `${JSON.stringify({ schema_version: "0.1", ok: true, ...computed }, null, 2)}\n`, exitCode: 0 };
|
|
227
|
+
const lines = [
|
|
228
|
+
`ideate diversity — ${target}`,
|
|
229
|
+
` ${line}`,
|
|
230
|
+
` ${computed.raw} idea(s) merged into ${computed.distinct_clusters} distinct cluster(s); ${computed.near_dupes_merged} near-dupe(s) merged.`,
|
|
231
|
+
args.includes("--write")
|
|
232
|
+
? "Written into the record as diversity_method: measured."
|
|
233
|
+
: "Not written. Re-run with --write to put this line in the record and mark it measured.",
|
|
234
|
+
];
|
|
235
|
+
return { output: `${lines.join("\n")}\n`, exitCode: 0 };
|
|
236
|
+
}
|
|
237
|
+
const depthIdx = args.indexOf("--depth");
|
|
238
|
+
const depth = (depthIdx === -1 ? "standard" : args[depthIdx + 1]);
|
|
239
|
+
if (!["fast", "standard", "deep"].includes(depth)) {
|
|
240
|
+
markFailure({ errorClass: "usage_error", errorCode: "E_BAD_FLAG", message: "ideate: --depth must be fast, standard, or deep" });
|
|
241
|
+
return { output: "--depth must be fast, standard, or deep\n", exitCode: 1 };
|
|
242
|
+
}
|
|
243
|
+
const idea = args.filter((a, i) => !a.startsWith("--") && (depthIdx === -1 || i !== depthIdx + 1)).join(" ").trim();
|
|
244
|
+
if (!idea) {
|
|
245
|
+
markFailure({ errorClass: "usage_error", errorCode: "E_IDEATE_IDEA_MISSING", message: "ideate: no idea given" });
|
|
246
|
+
return { output: 'usage: foo ideate "<raw idea>" [--depth fast|standard|deep] [--json]\n', exitCode: 1 };
|
|
247
|
+
}
|
|
248
|
+
const pack = await resolveFamilyPack("ideate", depth, LEAN);
|
|
249
|
+
const at = new Date().toISOString();
|
|
250
|
+
scaffoldFromPack(pack, root, idea, at);
|
|
251
|
+
if (json)
|
|
252
|
+
return { output: `${JSON.stringify(planFromPack(pack, idea, at), null, 2)}\n`, exitCode: 0 };
|
|
253
|
+
// The contract array ends with "", so join already carries the trailing newline.
|
|
254
|
+
return { output: contractFromPack(pack, idea, at).join("\n"), exitCode: 0 };
|
|
255
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
// Read-only, bounded discovery of existing public project artifacts. The agent
|
|
4
|
+
// must read and assess candidates; keyword matches are neither evidence nor a
|
|
5
|
+
// claim that all relevant work was found. Never walk caches/private raw stores.
|
|
6
|
+
const HOMES = ["ideas", "research", "specs", "docs/brainstorms"];
|
|
7
|
+
const SKIP = new Set(["quarantine", "incoming", "raw", "transcripts", "node_modules"]);
|
|
8
|
+
const STOP = new Set("a an and are as at be better by can do for from help how i improve improving in is it make my of on or our should that the this to we what with would".split(" "));
|
|
9
|
+
const words = (value) => [...new Set((value.toLowerCase().match(/[a-z0-9]+/g) ?? []).filter((w) => w.length > 2 && !STOP.has(w)))];
|
|
10
|
+
export function findIdeateContext(root, idea) {
|
|
11
|
+
const terms = words(idea);
|
|
12
|
+
const candidates = [];
|
|
13
|
+
const frequency = new Map();
|
|
14
|
+
let scanned = 0;
|
|
15
|
+
let visited = 0;
|
|
16
|
+
let truncated = false;
|
|
17
|
+
function walk(relative, depth) {
|
|
18
|
+
if (depth > 3 || visited >= 1500) {
|
|
19
|
+
truncated = true;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const full = path.join(root, relative);
|
|
23
|
+
try {
|
|
24
|
+
let component = root;
|
|
25
|
+
for (const part of relative.split("/")) {
|
|
26
|
+
component = path.join(component, part);
|
|
27
|
+
if (lstatSync(component).isSymbolicLink())
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!lstatSync(full).isDirectory() || lstatSync(full).isSymbolicLink())
|
|
31
|
+
return;
|
|
32
|
+
for (const entry of readdirSync(full, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
33
|
+
if (visited++ >= 1500) {
|
|
34
|
+
truncated = true;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
if (entry.name.startsWith(".") || SKIP.has(entry.name) || entry.isSymbolicLink())
|
|
38
|
+
continue;
|
|
39
|
+
const rel = path.posix.join(relative, entry.name);
|
|
40
|
+
if (entry.isDirectory()) {
|
|
41
|
+
walk(rel, depth + 1);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (!entry.isFile() || !entry.name.endsWith(".md") || entry.name === "AGENTS.md")
|
|
45
|
+
continue;
|
|
46
|
+
scanned++;
|
|
47
|
+
const file = path.join(root, rel);
|
|
48
|
+
if (lstatSync(file).size > 128 * 1024) {
|
|
49
|
+
truncated = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const body = readFileSync(file, "utf8");
|
|
53
|
+
if (relative === "ideas" && /^recommendation:\s*null\s*$/m.test(body))
|
|
54
|
+
continue;
|
|
55
|
+
const title = body.match(/^#\s+(.+)$/m)?.[1] ?? entry.name;
|
|
56
|
+
const filename = new Set(words(rel));
|
|
57
|
+
const heading = new Set(words(title));
|
|
58
|
+
const content = new Set(words(body));
|
|
59
|
+
const matched = terms.filter((term) => filename.has(term) || content.has(term));
|
|
60
|
+
if (!matched.length)
|
|
61
|
+
continue;
|
|
62
|
+
for (const term of matched)
|
|
63
|
+
frequency.set(term, (frequency.get(term) ?? 0) + 1);
|
|
64
|
+
const weights = matched.map((term) => (filename.has(term) ? 6 : 0) + (heading.has(term) ? 4 : 0) + (content.has(term) ? 1 : 0));
|
|
65
|
+
candidates.push({ path: rel, title: title.slice(0, 180), matched_terms: matched, weights, score: 0 });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch { /* Missing/unreadable homes are reported through discovery limits. */ }
|
|
69
|
+
}
|
|
70
|
+
for (const home of HOMES)
|
|
71
|
+
walk(home, 0);
|
|
72
|
+
for (const candidate of candidates) {
|
|
73
|
+
candidate.score = candidate.matched_terms.reduce((score, term, i) => score + candidate.weights[i] * Math.log(1 + scanned / (1 + (frequency.get(term) ?? 0))), 0);
|
|
74
|
+
}
|
|
75
|
+
candidates.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
|
|
76
|
+
return {
|
|
77
|
+
searched: HOMES,
|
|
78
|
+
candidates: candidates.slice(0, 10).map(({ score: _score, weights: _weights, ...candidate }) => candidate),
|
|
79
|
+
scanned,
|
|
80
|
+
truncated: truncated || candidates.length > 10,
|
|
81
|
+
limitations: "Local keyword discovery only; no match does not prove no prior work. Read candidates, follow their references, distinguish findings from hypotheses, and record gaps. No web or connected sources were queried.",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { main, type MainDeps } from "./cli.js";
|
|
2
|
+
export { askToSendReports, createReportRunContext, noteCapsuleFromThisRun, pendingReports, renderReportCommandResult, reportsDir, runReportCommand, writeErrorReport, type ErrorReport, type ReportCommandDeps, type ReportCommandResult, type ReportCommandRun, type ReportFinalizationDeps, type ReportInvocationMode, type ReportRunContext, } from "./errorReport.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Supported package entrypoint: CLI bootstrap and local diagnostic report API.
|
|
2
|
+
// The export map and docs/library-exports.md define the consumer contract.
|
|
3
|
+
export { main } from "./cli.js";
|
|
4
|
+
export { askToSendReports, createReportRunContext, noteCapsuleFromThisRun, pendingReports, renderReportCommandResult, reportsDir, runReportCommand, writeErrorReport, } from "./errorReport.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type SurveyIO } from "./profile.js";
|
|
2
|
+
export declare const FIRST_RUN_OPENER: readonly string[];
|
|
3
|
+
export declare const NO_REPO_STORY: readonly string[];
|
|
4
|
+
export declare function scaffoldPacket(root: string, title: string, evidence: string[], intent: string): string;
|
|
5
|
+
type InitOptions = {
|
|
6
|
+
json: boolean;
|
|
7
|
+
pick: number | null;
|
|
8
|
+
intent: string | null;
|
|
9
|
+
pm: boolean;
|
|
10
|
+
attachProof: string | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseInitArgs(args: string[]): InitOptions;
|
|
13
|
+
import { JARGON_TERMS } from "./productDetect.js";
|
|
14
|
+
export { JARGON_TERMS as PM_SURFACE_FORBIDDEN };
|
|
15
|
+
export declare function pmSurfaceLeaks(text: string): string[];
|
|
16
|
+
export declare function runInit(root: string, args: string[]): string;
|
|
17
|
+
export declare function initHandoffSteps(root: string): string[];
|
|
18
|
+
export declare function surveyApplies(root: string, args: string[], io: {
|
|
19
|
+
inputTTY: boolean;
|
|
20
|
+
outputTTY: boolean;
|
|
21
|
+
}): boolean;
|
|
22
|
+
export declare function runInitInteractive(root: string, args: string[], io?: SurveyIO & {
|
|
23
|
+
inputTTY?: boolean;
|
|
24
|
+
outputTTY?: boolean;
|
|
25
|
+
}): Promise<string>;
|