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,7 @@
|
|
|
1
|
+
import type { BugCapsule } from "./bugCapsule.js";
|
|
2
|
+
export type BugSpecContext = NonNullable<NonNullable<BugCapsule["extensions"]["foo"]>["spec_context"]>;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve only the packet argument positions owned by packet-aware commands.
|
|
5
|
+
* Packet content is never consulted: tasks.yaml is the complete metadata source.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveBugSpecContext(root: string, domain: string, args: string[]): BugSpecContext | undefined;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { realpathSync, readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "./vendorYaml.js";
|
|
4
|
+
const MAX_STRING_LENGTH = 4_096;
|
|
5
|
+
const MAX_ARRAY_LENGTH = 100;
|
|
6
|
+
const SPEC_ID = /^[a-z][a-z0-9_]{0,127}$/;
|
|
7
|
+
const TASK_ID = /^T-\d{3}$/;
|
|
8
|
+
const REQUIREMENT_ID = /^R-\d{3}$/;
|
|
9
|
+
const PATH_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
10
|
+
const RFC_3339 = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))$/;
|
|
11
|
+
const PACKET_COMMANDS = {
|
|
12
|
+
asp: new Set(["validate", "migrate", "reconcile", "verify", "status", "event", "task", "verdict"]),
|
|
13
|
+
loop: new Set(["design", "check", "status", "estimate", "routine"]),
|
|
14
|
+
source: new Set(["discover", "approve", "revoke", "claim", "receipt"]),
|
|
15
|
+
};
|
|
16
|
+
function inside(parent, candidate) {
|
|
17
|
+
const relative = path.relative(parent, candidate);
|
|
18
|
+
return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
|
|
19
|
+
}
|
|
20
|
+
function object(value) {
|
|
21
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
22
|
+
? value
|
|
23
|
+
: undefined;
|
|
24
|
+
}
|
|
25
|
+
function bounded(value) {
|
|
26
|
+
return typeof value === "string" && value.length > 0 && value.length <= MAX_STRING_LENGTH ? value : undefined;
|
|
27
|
+
}
|
|
28
|
+
function packetArgument(domain, args) {
|
|
29
|
+
if (domain === "estimate")
|
|
30
|
+
return args[1];
|
|
31
|
+
const allowed = PACKET_COMMANDS[domain];
|
|
32
|
+
return allowed?.has(args[1] ?? "") ? args[2] : undefined;
|
|
33
|
+
}
|
|
34
|
+
function safePacketPath(value) {
|
|
35
|
+
if (path.isAbsolute(value) || value.includes("\\"))
|
|
36
|
+
return false;
|
|
37
|
+
const segments = value.split("/");
|
|
38
|
+
return segments.length >= 2 && segments[0] === "specs" && segments.every((segment) => PATH_SEGMENT.test(segment));
|
|
39
|
+
}
|
|
40
|
+
function rfc3339(value) {
|
|
41
|
+
const candidate = bounded(value);
|
|
42
|
+
if (!candidate)
|
|
43
|
+
return undefined;
|
|
44
|
+
const match = RFC_3339.exec(candidate);
|
|
45
|
+
if (!match)
|
|
46
|
+
return undefined;
|
|
47
|
+
const [, year, month, day, hour, minute, second, offsetHour, offsetMinute] = match;
|
|
48
|
+
if (Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59 ||
|
|
49
|
+
Number(offsetHour ?? 0) > 23 || Number(offsetMinute ?? 0) > 59)
|
|
50
|
+
return undefined;
|
|
51
|
+
const calendar = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
|
|
52
|
+
if (calendar.getUTCFullYear() !== Number(year) ||
|
|
53
|
+
calendar.getUTCMonth() + 1 !== Number(month) ||
|
|
54
|
+
calendar.getUTCDate() !== Number(day) ||
|
|
55
|
+
Number.isNaN(Date.parse(candidate)))
|
|
56
|
+
return undefined;
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve only the packet argument positions owned by packet-aware commands.
|
|
61
|
+
* Packet content is never consulted: tasks.yaml is the complete metadata source.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveBugSpecContext(root, domain, args) {
|
|
64
|
+
const packetArg = packetArgument(domain, args);
|
|
65
|
+
if (!packetArg || !safePacketPath(packetArg))
|
|
66
|
+
return undefined;
|
|
67
|
+
try {
|
|
68
|
+
const lexicalRoot = path.resolve(root);
|
|
69
|
+
const lexicalSpecs = path.join(lexicalRoot, "specs");
|
|
70
|
+
const lexicalPacket = path.resolve(lexicalRoot, packetArg);
|
|
71
|
+
if (!inside(lexicalSpecs, lexicalPacket) || lexicalPacket === lexicalSpecs)
|
|
72
|
+
return undefined;
|
|
73
|
+
const realRoot = realpathSync(lexicalRoot);
|
|
74
|
+
const realSpecs = realpathSync(lexicalSpecs);
|
|
75
|
+
const realPacket = realpathSync(lexicalPacket);
|
|
76
|
+
if (!inside(realRoot, realSpecs) || !inside(realSpecs, realPacket) || realPacket === realSpecs)
|
|
77
|
+
return undefined;
|
|
78
|
+
const tasksPath = path.join(realPacket, "tasks.yaml");
|
|
79
|
+
const realTasksPath = realpathSync(tasksPath);
|
|
80
|
+
if (!inside(realPacket, realTasksPath) || !inside(realSpecs, realTasksPath))
|
|
81
|
+
return undefined;
|
|
82
|
+
const document = object(parseYaml(readFileSync(realTasksPath, "utf8")));
|
|
83
|
+
if (!document)
|
|
84
|
+
return undefined;
|
|
85
|
+
const specId = bounded(document.spec_id);
|
|
86
|
+
if (!specId || !SPEC_ID.test(specId))
|
|
87
|
+
return undefined;
|
|
88
|
+
if (!specId || !Array.isArray(document.tasks) || document.tasks.length > MAX_ARRAY_LENGTH)
|
|
89
|
+
return undefined;
|
|
90
|
+
let requirementIds = [];
|
|
91
|
+
let taskIds = [];
|
|
92
|
+
if (domain === "asp" && args[1] === "task") {
|
|
93
|
+
const taskId = bounded(args[3]);
|
|
94
|
+
if (!taskId || !TASK_ID.test(taskId))
|
|
95
|
+
return undefined;
|
|
96
|
+
const matches = document.tasks
|
|
97
|
+
.map(object)
|
|
98
|
+
.filter((task) => task !== undefined && task.id === taskId);
|
|
99
|
+
if (matches.length !== 1)
|
|
100
|
+
return undefined;
|
|
101
|
+
const refs = matches[0].refs;
|
|
102
|
+
if (!Array.isArray(refs) || refs.length > MAX_ARRAY_LENGTH)
|
|
103
|
+
return undefined;
|
|
104
|
+
if (refs.some((ref) => typeof ref === "string" && ref.startsWith("R-") && !REQUIREMENT_ID.test(ref)))
|
|
105
|
+
return undefined;
|
|
106
|
+
requirementIds = refs.filter((ref) => typeof ref === "string" && REQUIREMENT_ID.test(ref));
|
|
107
|
+
if (requirementIds.some((ref) => ref.length > MAX_STRING_LENGTH))
|
|
108
|
+
return undefined;
|
|
109
|
+
taskIds = [taskId];
|
|
110
|
+
}
|
|
111
|
+
const packetPath = path.relative(realRoot, realPacket).split(path.sep).join("/");
|
|
112
|
+
if (!packetPath || packetPath.length > MAX_STRING_LENGTH || !safePacketPath(packetPath))
|
|
113
|
+
return undefined;
|
|
114
|
+
const revision = document.updated === undefined ? undefined : rfc3339(document.updated);
|
|
115
|
+
if (document.updated !== undefined && !revision)
|
|
116
|
+
return undefined;
|
|
117
|
+
return {
|
|
118
|
+
spec_id: specId,
|
|
119
|
+
packet_path: packetPath,
|
|
120
|
+
...(revision ? { revision } : {}),
|
|
121
|
+
requirement_ids: requirementIds,
|
|
122
|
+
task_ids: taskIds,
|
|
123
|
+
provenance: "reporter_observed",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const RETIRED_DIST_PACKAGE = "github:rwo572/foo-dist";
|
|
2
|
+
export declare function distributionPackageName(): string;
|
|
3
|
+
export declare function globalInstallCommand(): string;
|
|
4
|
+
export declare function channelInstallCommand(home?: string): string;
|
|
5
|
+
export type ChannelFreshnessState = "no-channel" | "unknown" | "current" | "behind";
|
|
6
|
+
export type ClientKind = "repo" | "channel" | "global";
|
|
7
|
+
export type ChannelFreshness = {
|
|
8
|
+
state: ChannelFreshnessState;
|
|
9
|
+
installed: string | null;
|
|
10
|
+
latest: string | null;
|
|
11
|
+
kind: ClientKind;
|
|
12
|
+
};
|
|
13
|
+
export declare function runningVersion(packageRoot?: string): string | null;
|
|
14
|
+
export declare function isSourceCheckout(packageRoot?: string): boolean;
|
|
15
|
+
export declare function runningClientKind(packageRoot?: string, home?: string): ClientKind;
|
|
16
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
17
|
+
export declare function channelFreshnessPlan(input: {
|
|
18
|
+
installed: string | null;
|
|
19
|
+
latest: string | null;
|
|
20
|
+
kind?: ClientKind;
|
|
21
|
+
}): ChannelFreshness;
|
|
22
|
+
export declare function fooHome(): string;
|
|
23
|
+
export declare function installedDistVersion(home?: string): string | null;
|
|
24
|
+
export declare function latestPublishedVersion(registryTimeoutMs?: number): string | null;
|
|
25
|
+
export declare function channelFreshness(packageRoot?: string, home?: string): ChannelFreshness;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Is the client you are running the newest one that was published?
|
|
2
|
+
//
|
|
3
|
+
// Nothing here self-updates: `npm install` pins whatever was published that day,
|
|
4
|
+
// and nothing ever revisits it. So a release can land and productfoo keeps serving the
|
|
5
|
+
// old client while cheerfully reporting a version number — which is exactly how
|
|
6
|
+
// the dist channel sat on 0.1.6 for a day after 0.1.10 shipped, with no surface
|
|
7
|
+
// anywhere saying so.
|
|
8
|
+
//
|
|
9
|
+
// The update notice (`updateNotice.ts`) covers this for testers who are working:
|
|
10
|
+
// the skill server stamps every response with the current version. But it can
|
|
11
|
+
// only speak to a client that CALLS the server, so it is silent for anyone
|
|
12
|
+
// resolving skills locally, and silent in any session that loads no skill. That
|
|
13
|
+
// leaves doctor — the one command whose whole job is "tell me if my setup is
|
|
14
|
+
// wrong" — as the only surface that can answer the question unprompted. So it
|
|
15
|
+
// answers it for every install, not just the channel one.
|
|
16
|
+
//
|
|
17
|
+
// This is an advisory doctor signal, never a block, and it is offline-safe:
|
|
18
|
+
// when the newest release cannot be read, doctor says it could not check rather
|
|
19
|
+
// than reporting a reassuring "current".
|
|
20
|
+
import { spawnSync } from "node:child_process";
|
|
21
|
+
import { existsSync } from "node:fs";
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
import { readJson } from "./jsonFile.js";
|
|
26
|
+
// ── The distribution-target contract ─────────────────────────────────────────
|
|
27
|
+
// productfoo's canonical distribution target is the npm package this artifact ships
|
|
28
|
+
// as. Every surface that names it — the update notice, doctor, the invite
|
|
29
|
+
// email, `foo update`'s argv — resolves it through the functions below instead
|
|
30
|
+
// of repeating a string. The published-package NAME is an open owner decision
|
|
31
|
+
// (spec D-006/D-007), so the contract keeps that decision in ONE place:
|
|
32
|
+
// settling it, or moving to a successor name, is a package.json edit plus this
|
|
33
|
+
// module — never a grep across the tree.
|
|
34
|
+
//
|
|
35
|
+
// The Git install (`github:rwo572/foo-dist`) is retired, not bridged (R-009):
|
|
36
|
+
// it was the private alpha channel, and the private repository it pointed at
|
|
37
|
+
// stops resolving. The only deliberate survivors are commented historical
|
|
38
|
+
// references, each saying why it survives.
|
|
39
|
+
// Historical name of the retired private dist channel. Recorded here (and only
|
|
40
|
+
// here) so the successor-seam comment below has a concrete referent; no install
|
|
41
|
+
// surface may print it again.
|
|
42
|
+
export const RETIRED_DIST_PACKAGE = "github:rwo572/foo-dist";
|
|
43
|
+
// The successor-package seam (spec D-006): a later scope move republishes under
|
|
44
|
+
// a new name and deprecates the old, and this contract is the one place the new
|
|
45
|
+
// name lands. FOO_DISTRIBUTION_PACKAGE exists for the transition window — an
|
|
46
|
+
// operator run whose package.json name and publish name differ — and for tests.
|
|
47
|
+
export function distributionPackageName() {
|
|
48
|
+
const forced = (process.env.FOO_DISTRIBUTION_PACKAGE ?? "").trim();
|
|
49
|
+
if (forced)
|
|
50
|
+
return forced;
|
|
51
|
+
try {
|
|
52
|
+
const name = readJson(path.join(PACKAGE_ROOT, "package.json")).name;
|
|
53
|
+
if (typeof name === "string" && name.length > 0)
|
|
54
|
+
return name;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Fall through to the shipped-name fallback below.
|
|
58
|
+
}
|
|
59
|
+
// The name this artifact ships today. One hardcoded name, inside the
|
|
60
|
+
// contract, so an unreadable package.json still yields a command a human can
|
|
61
|
+
// run — never a Git URL.
|
|
62
|
+
return "productfoo";
|
|
63
|
+
}
|
|
64
|
+
// The two install commands. One place, so the notice prints the same thing
|
|
65
|
+
// `foo update` execs and doctor points at. `--prefix` is absolute because argv
|
|
66
|
+
// is not a shell and nothing expands a tilde there.
|
|
67
|
+
export function globalInstallCommand() {
|
|
68
|
+
return `npm install -g ${distributionPackageName()}`;
|
|
69
|
+
}
|
|
70
|
+
export function channelInstallCommand(home = fooHome()) {
|
|
71
|
+
return `npm install --prefix ${path.join(home, "versions", "dist")} ${distributionPackageName()}`;
|
|
72
|
+
}
|
|
73
|
+
// This file compiles to dist/src/channelFreshness.js, so two levels up is productfoo's
|
|
74
|
+
// own package root — the client actually executing, whatever directory it was
|
|
75
|
+
// invoked from.
|
|
76
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
77
|
+
// Deliberately not `clientVersion()` from updateNotice: that module already
|
|
78
|
+
// imports compareVersions from here, and importing back would close a cycle.
|
|
79
|
+
// The semantics differ anyway — null means "cannot tell", which must never be
|
|
80
|
+
// compared against a real version.
|
|
81
|
+
export function runningVersion(packageRoot = PACKAGE_ROOT) {
|
|
82
|
+
try {
|
|
83
|
+
const version = readJson(path.join(packageRoot, "package.json")).version;
|
|
84
|
+
return typeof version === "string" && version.length > 0 ? version : null;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// A repo checkout carries productfoo's TypeScript source; no npm install does
|
|
91
|
+
// (package.json "files" ships the compiled dist-public/, never src/, and
|
|
92
|
+
// test/channelFreshness.test.ts pins that against open-source/npm-files.json).
|
|
93
|
+
// #892: this used to key on skills/, but the public package bundles skills/
|
|
94
|
+
// since #813, so every npm install read as a checkout and could never update.
|
|
95
|
+
export function isSourceCheckout(packageRoot = PACKAGE_ROOT) {
|
|
96
|
+
return existsSync(path.join(packageRoot, "src", "cli.ts"));
|
|
97
|
+
}
|
|
98
|
+
export function runningClientKind(packageRoot = PACKAGE_ROOT, home = fooHome()) {
|
|
99
|
+
if (isSourceCheckout(packageRoot))
|
|
100
|
+
return "repo";
|
|
101
|
+
return packageRoot.startsWith(path.join(home, "versions", "dist") + path.sep) ? "channel" : "global";
|
|
102
|
+
}
|
|
103
|
+
// Numeric, segment-by-segment. A string compare says "0.1.10" < "0.1.6", which
|
|
104
|
+
// would hide the very release this check exists to catch.
|
|
105
|
+
export function compareVersions(a, b) {
|
|
106
|
+
const parse = (value) => value.replace(/^v/, "").split(".").map((segment) => Number.parseInt(segment, 10) || 0);
|
|
107
|
+
const left = parse(a);
|
|
108
|
+
const right = parse(b);
|
|
109
|
+
for (let i = 0; i < Math.max(left.length, right.length); i += 1) {
|
|
110
|
+
const diff = (left[i] ?? 0) - (right[i] ?? 0);
|
|
111
|
+
if (diff !== 0)
|
|
112
|
+
return diff < 0 ? -1 : 1;
|
|
113
|
+
}
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
// Pure decision, so every state is unit-testable without a network or a $HOME.
|
|
117
|
+
export function channelFreshnessPlan(input) {
|
|
118
|
+
const { installed, latest } = input;
|
|
119
|
+
const kind = input.kind ?? "channel";
|
|
120
|
+
if (installed === null)
|
|
121
|
+
return { state: "no-channel", installed, latest, kind };
|
|
122
|
+
if (latest === null)
|
|
123
|
+
return { state: "unknown", installed, latest, kind };
|
|
124
|
+
return { state: compareVersions(installed, latest) < 0 ? "behind" : "current", installed, latest, kind };
|
|
125
|
+
}
|
|
126
|
+
export function fooHome() {
|
|
127
|
+
return process.env.FOO_HOME ?? path.join(homedir(), ".foo");
|
|
128
|
+
}
|
|
129
|
+
// What the `dist` channel actually has installed right now.
|
|
130
|
+
export function installedDistVersion(home = fooHome()) {
|
|
131
|
+
// #892: the channel copy lives under its published name, whatever that is.
|
|
132
|
+
const manifest = path.join(home, "versions", "dist", "node_modules", ...distributionPackageName().split("/"), "package.json");
|
|
133
|
+
if (!existsSync(manifest))
|
|
134
|
+
return null;
|
|
135
|
+
try {
|
|
136
|
+
const version = readJson(manifest).version;
|
|
137
|
+
return typeof version === "string" && version.length > 0 ? version : null;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Newest published release, read from the npm registry — the same source `npm
|
|
144
|
+
// install` resolves. The update notice rides the skill-server header (the
|
|
145
|
+
// server is the source of truth for a client that is running); this probe is
|
|
146
|
+
// the offline-safe backstop doctor uses, and it needs no credentials now that
|
|
147
|
+
// the target is a public package. Bounded and silent: any failure — offline, no
|
|
148
|
+
// npm on PATH, a slow registry — returns null, which doctor reports as "could
|
|
149
|
+
// not check", never a reassuring "current". Set FOO_SKIP_UPDATE_CHECK=1 to skip
|
|
150
|
+
// the probe entirely.
|
|
151
|
+
export function latestPublishedVersion(registryTimeoutMs = 5_000) {
|
|
152
|
+
if (process.env.FOO_SKIP_UPDATE_CHECK === "1")
|
|
153
|
+
return null;
|
|
154
|
+
// A test NEVER touches the registry — the same posture as telemetry, and for
|
|
155
|
+
// the same reason. The suite spawns `foo doctor` ~19 times and inherits the
|
|
156
|
+
// real HOME, so without this every one of them fired a network probe:
|
|
157
|
+
// ~0.5s each, network-dependent, and an intermittent failure whenever the
|
|
158
|
+
// network was slow enough to push a spawn toward the timeout.
|
|
159
|
+
if ((process.env.NODE_ENV ?? "").trim() === "test")
|
|
160
|
+
return null;
|
|
161
|
+
const res = spawnSync("npm", ["view", distributionPackageName(), "version", "--json"], {
|
|
162
|
+
encoding: "utf8",
|
|
163
|
+
timeout: registryTimeoutMs,
|
|
164
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
165
|
+
});
|
|
166
|
+
if (res.error || res.status !== 0 || typeof res.stdout !== "string")
|
|
167
|
+
return null;
|
|
168
|
+
// `npm view <pkg> version --json` prints a bare JSON string: "0.1.37".
|
|
169
|
+
try {
|
|
170
|
+
const version = JSON.parse(res.stdout);
|
|
171
|
+
if (typeof version !== "string")
|
|
172
|
+
return null;
|
|
173
|
+
const clean = version.trim().replace(/^v/, "");
|
|
174
|
+
return /^\d+(\.\d+)*$/.test(clean) ? clean : null;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Freshness of the client that is running right now — the one whose version the
|
|
181
|
+
// user would have to change.
|
|
182
|
+
//
|
|
183
|
+
// A repo run is the exception, and it is the case this check was originally
|
|
184
|
+
// built for: a dev checkout has no published build to be behind, but bare `foo`
|
|
185
|
+
// may still be serving a stale channel install while `bin/foo` runs new code.
|
|
186
|
+
// So a repo run reports the channel; an installed run reports itself.
|
|
187
|
+
export function channelFreshness(packageRoot = PACKAGE_ROOT, home = fooHome()) {
|
|
188
|
+
const kind = runningClientKind(packageRoot, home);
|
|
189
|
+
const installed = kind === "repo" ? installedDistVersion(home) : runningVersion(packageRoot);
|
|
190
|
+
// Don't go to the network at all when there is nothing that could be stale.
|
|
191
|
+
if (installed === null)
|
|
192
|
+
return channelFreshnessPlan({ installed: null, latest: null, kind });
|
|
193
|
+
return channelFreshnessPlan({ installed, latest: latestPublishedVersion(), kind });
|
|
194
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ReportFinalizationDeps, type ReportInvocationMode } from "./errorReport.js";
|
|
2
|
+
export type { PacketContext } from "./commands/asp.js";
|
|
3
|
+
/**
|
|
4
|
+
* #885: one command's usage, taken from the canonical full listing so the two
|
|
5
|
+
* can never drift. Null when the listing carries no line for the command
|
|
6
|
+
* (harness-only surfaces such as `interview`), so it falls through to normal
|
|
7
|
+
* dispatch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function domainHelp(domain: string): string | null;
|
|
10
|
+
export declare const CLI_DOMAINS: Set<string>;
|
|
11
|
+
export declare const CLI_SUBCOMMANDS: Record<string, readonly string[]>;
|
|
12
|
+
export declare function deriveCliCommand(args: string[]): {
|
|
13
|
+
domain: string;
|
|
14
|
+
command: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function firstRunNotice(_env?: NodeJS.ProcessEnv): string;
|
|
17
|
+
export declare function reportInvocationMode(args: string[], env?: NodeJS.ProcessEnv, terminal?: {
|
|
18
|
+
stdinIsTTY: boolean;
|
|
19
|
+
stdoutIsTTY: boolean;
|
|
20
|
+
stderrIsTTY: boolean;
|
|
21
|
+
}): ReportInvocationMode;
|
|
22
|
+
export type MainDeps = {
|
|
23
|
+
terminal?: {
|
|
24
|
+
stdinIsTTY: boolean;
|
|
25
|
+
stdoutIsTTY: boolean;
|
|
26
|
+
stderrIsTTY: boolean;
|
|
27
|
+
};
|
|
28
|
+
report?: ReportFinalizationDeps;
|
|
29
|
+
};
|
|
30
|
+
export declare function main(argv: string[], deps?: MainDeps): Promise<number>;
|