@geraldmaron/construct 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -10
- package/bin/construct +286 -220
- package/bin/construct-postinstall.mjs +0 -21
- package/commands/work/optimize-prompts.md +1 -1
- package/examples/distribution/sources/adr.md +2 -2
- package/examples/seed-observations/decisions.md +1 -1
- package/lib/artifact-loop-core.mjs +412 -0
- package/lib/artifact-manifest.mjs +6 -0
- package/lib/artifact-release-gate.mjs +115 -49
- package/lib/audit-rules.mjs +2 -4
- package/lib/audit-skills.mjs +32 -20
- package/lib/audit-specialists.mjs +44 -26
- package/lib/auto-docs.mjs +6 -5
- package/lib/brand-prose.mjs +3 -3
- package/lib/brand-tokens.mjs +2 -2
- package/lib/certification/artifact-fixtures.mjs +4 -1
- package/lib/certification/demo-parity.mjs +6 -32
- package/lib/certification/real-llm-scenarios.mjs +58 -13
- package/lib/certification/role-cards.mjs +7 -6
- package/lib/certification/role-overlays.mjs +4 -4
- package/lib/certification/runner.mjs +9 -2
- package/lib/certification/skill-inventory.mjs +34 -22
- package/lib/certification/skill-scenarios.mjs +21 -8
- package/lib/certification/specialist-contracts.mjs +4 -3
- package/lib/certification/specialist-scenarios.mjs +7 -6
- package/lib/certification/status.mjs +5 -4
- package/lib/cli-commands.mjs +56 -57
- package/lib/comment-lint.mjs +1 -5
- package/lib/completions.mjs +20 -2
- package/lib/config/legacy-config-migration.mjs +125 -0
- package/lib/config/schema.mjs +5 -5
- package/lib/config/source-targets.mjs +80 -0
- package/lib/contracts/validate.mjs +119 -51
- package/lib/decisions/golden.mjs +3 -2
- package/lib/decisions/registry.mjs +11 -6
- package/lib/demo-project.mjs +188 -0
- package/lib/demo-recording.mjs +9 -34
- package/lib/demo-script.mjs +2 -2
- package/lib/demo-surface.mjs +13 -131
- package/lib/demo-tour-renderer.mjs +92 -0
- package/lib/demo.mjs +69 -54
- package/lib/diagram-export.mjs +63 -14
- package/lib/doctor/source-checkout.mjs +3 -4
- package/lib/doctor/watchers/consistency.mjs +90 -22
- package/lib/doctor/watchers/credential-parity.mjs +97 -0
- package/lib/doctor/watchers/mcp-protocol.mjs +1 -1
- package/lib/doctor/watchers/service-health.mjs +4 -32
- package/lib/document-export.mjs +73 -9
- package/lib/document-extract.mjs +10 -198
- package/lib/embed/artifact.mjs +2 -3
- package/lib/embed/cli.mjs +1 -1
- package/lib/embed/config.mjs +1 -2
- package/lib/embed/customer-profiles.mjs +1 -1
- package/lib/embed/daemon.mjs +5 -6
- package/lib/embed/demand-fetch.mjs +114 -2
- package/lib/embed/docs-lifecycle.mjs +9 -5
- package/lib/embed/intake-metrics.mjs +2 -2
- package/lib/embed/notifications.mjs +2 -3
- package/lib/embed/recommendation-store.mjs +25 -22
- package/lib/embed/role-framing.mjs +4 -9
- package/lib/embedded-contract/capability.mjs +4 -2
- package/lib/embedded-contract/contract-version.mjs +1 -1
- package/lib/env-config.mjs +2 -2
- package/lib/flavors/loader.mjs +21 -19
- package/lib/graph/build-from-registry.mjs +31 -7
- package/lib/graph/staleness.mjs +1 -1
- package/lib/headhunt.mjs +82 -35
- package/lib/hooks/agent-tracker.mjs +2 -2
- package/lib/hooks/config-protection.mjs +1 -1
- package/lib/hooks/registry-sync.mjs +3 -3
- package/lib/host-capabilities.mjs +5 -5
- package/lib/improvement/controller.mjs +2 -2
- package/lib/init-unified.mjs +19 -21
- package/lib/intake/classify.mjs +26 -0
- package/lib/intake/daemon.mjs +2 -3
- package/lib/intake/prepare.mjs +10 -3
- package/lib/intake/session-prelude.mjs +1 -1
- package/lib/intake/tables/creative.mjs +9 -9
- package/lib/intake/tables/operations.mjs +4 -4
- package/lib/intake/tables/research.mjs +2 -2
- package/lib/integrations/intake-integrations.mjs +9 -10
- package/lib/knowledge/research-store.mjs +2 -2
- package/lib/mcp/server.mjs +104 -61
- package/lib/mcp/tool-budget.mjs +1 -46
- package/lib/mcp/tool-recovery.mjs +44 -0
- package/lib/mcp/tools/artifact-author.mjs +36 -0
- package/lib/mcp/tools/find-tool.mjs +86 -0
- package/lib/mcp/tools/orchestration-run.mjs +107 -69
- package/lib/mcp/tools/project.mjs +4 -3
- package/lib/mcp/tools/{profile.mjs → scope.mjs} +54 -52
- package/lib/mcp/tools/skills.mjs +39 -22
- package/lib/mcp/tools/telemetry.mjs +2 -1
- package/lib/mcp/tools/workflow.mjs +1 -1
- package/lib/mcp-platform-config.mjs +7 -5
- package/lib/migrations/index.mjs +4 -2
- package/lib/migrations/v2-unified-registry.mjs +35 -0
- package/lib/model-router.mjs +203 -36
- package/lib/models/catalog.mjs +25 -9
- package/lib/models/execution-capability-profile.mjs +3 -3
- package/lib/models/execution-policy.mjs +7 -6
- package/lib/models/provider-poll.mjs +18 -4
- package/lib/opencode-config.mjs +56 -1
- package/lib/opencode-runtime-plugin.mjs +13 -10
- package/lib/oracle/artifact-gate.mjs +14 -4
- package/lib/oracle/cli.mjs +2 -0
- package/lib/oracle/dispatch.mjs +18 -1
- package/lib/oracle/execute.mjs +39 -7
- package/lib/oracle/index.mjs +1 -1
- package/lib/oracle/org-graph.mjs +10 -5
- package/lib/oracle/policy.mjs +6 -0
- package/lib/oracle/read-model.mjs +103 -6
- package/lib/oracle/reconcile.mjs +31 -4
- package/lib/oracle/remediation-dispatch.mjs +53 -0
- package/lib/oracle/routing.mjs +5 -0
- package/lib/oracle/synthesize.mjs +80 -3
- package/lib/orchestration/routing-tables.mjs +44 -10
- package/lib/orchestration/runtime.mjs +2 -0
- package/lib/orchestration/worker.mjs +1 -1
- package/lib/orchestration-policy.mjs +351 -62
- package/lib/overrides/resolver.mjs +1 -12
- package/lib/parity.mjs +37 -11
- package/lib/policy/engine.mjs +80 -15
- package/lib/prompt-composer.js +51 -15
- package/lib/prompt-metadata.mjs +3 -2
- package/lib/providers/connection-probe.mjs +58 -0
- package/lib/providers/copilot-auth.mjs +1 -1
- package/lib/providers/credential-bootstrap.mjs +1 -1
- package/lib/providers/op-run.mjs +3 -4
- package/lib/providers/secret-resolver.mjs +31 -0
- package/lib/publish-tooling.mjs +3 -11
- package/lib/publish.mjs +12 -29
- package/lib/reconcile/mcp-entry-reconcile.mjs +14 -9
- package/lib/reflect.mjs +2 -2
- package/lib/registry/agent-manifest.mjs +190 -0
- package/lib/registry/assemble.mjs +133 -0
- package/lib/registry/catalog.mjs +171 -0
- package/lib/registry/cli.mjs +590 -6
- package/lib/registry/consolidation.mjs +5 -4
- package/lib/registry/docs-sync.mjs +67 -0
- package/lib/registry/loader.mjs +147 -0
- package/lib/registry/org-io.mjs +76 -0
- package/lib/registry/retired-paths.mjs +71 -0
- package/lib/registry/surface-map.mjs +5 -7
- package/lib/registry/validator.mjs +438 -0
- package/lib/research-execution-policy.mjs +173 -0
- package/lib/roles/catalog.mjs +4 -9
- package/lib/roles/fence.mjs +107 -1
- package/lib/roles/flavor-bindings.mjs +68 -0
- package/lib/roles/gateway.mjs +140 -29
- package/lib/roles/manifest.mjs +22 -13
- package/lib/roles/router.mjs +1 -1
- package/lib/runtime-env.mjs +1 -1
- package/lib/scopes/enrich.mjs +67 -0
- package/lib/scopes/hooks.mjs +12 -0
- package/lib/{profiles → scopes}/lifecycle.mjs +70 -70
- package/lib/scopes/loader.mjs +104 -0
- package/lib/scopes/rebrand.mjs +32 -0
- package/lib/scopes/research-profile.mjs +16 -0
- package/lib/scopes/teams.mjs +98 -0
- package/lib/service-manager.mjs +1 -117
- package/lib/setup-prompts.mjs +1 -1
- package/lib/setup.mjs +17 -28
- package/lib/skills/composition-graph.mjs +98 -0
- package/lib/skills/router.mjs +80 -0
- package/lib/specialist-contracts.mjs +17 -18
- package/lib/specialists/postconditions.mjs +2 -2
- package/lib/specialists/prompt-schema.mjs +6 -5
- package/lib/specialists/roster.mjs +7 -12
- package/lib/specialists/schema.mjs +9 -6
- package/lib/status.mjs +25 -90
- package/lib/storage/file-lock.mjs +6 -3
- package/lib/telemetry/skill-calls.mjs +1 -1
- package/lib/templates/doc-presentation.mjs +63 -0
- package/lib/templates/visual-requirements.mjs +35 -2
- package/lib/term-format.mjs +107 -2
- package/lib/test-env-setup.mjs +21 -0
- package/lib/ui/components.mjs +42 -0
- package/lib/ui/glyphs.mjs +58 -0
- package/lib/ui/links.mjs +115 -0
- package/lib/ui/theme.mjs +108 -0
- package/lib/uninstall/uninstall.mjs +2 -1
- package/lib/validator.mjs +45 -8
- package/lib/validators/skill-effectiveness.mjs +174 -0
- package/lib/validators/skills.mjs +1 -1
- package/package.json +12 -7
- package/personas/construct.md +12 -3
- package/platforms/claude/CLAUDE.md +1 -1
- package/rules/common/beads-hygiene.md +52 -0
- package/rules/common/neurodivergent-output.md +4 -7
- package/rules/common/research.md +2 -0
- package/scripts/sync-specialists.mjs +260 -49
- package/skills/ai/prompt-optimizer.md +3 -3
- package/skills/brand/output-vibe.md +48 -0
- package/skills/docs/adr-workflow.md +3 -0
- package/skills/docs/backlog-proposal-workflow.md +3 -0
- package/skills/docs/codebase-research-workflow.md +5 -2
- package/skills/docs/customer-profile-workflow.md +3 -0
- package/skills/docs/document-ingest-workflow.md +3 -0
- package/skills/docs/evidence-ingest-workflow.md +4 -1
- package/skills/docs/init-project.md +1 -1
- package/skills/docs/prd-workflow.md +1 -1
- package/skills/docs/prfaq-workflow.md +3 -0
- package/skills/docs/product-intelligence-workflow.md +4 -1
- package/skills/docs/product-signal-workflow.md +3 -0
- package/skills/docs/research-workflow.md +13 -6
- package/skills/docs/runbook-workflow.md +3 -0
- package/skills/docs/strategy-workflow.md +3 -0
- package/skills/docs/user-research-workflow.md +6 -3
- package/skills/operating/orchestration-reference.md +1 -1
- package/skills/roles/{engineer.ai.md → ai-engineer.md} +2 -2
- package/skills/roles/architect.ai-systems.md +1 -1
- package/skills/roles/architect.data.md +1 -1
- package/skills/roles/architect.enterprise.md +1 -1
- package/skills/roles/architect.integration.md +1 -1
- package/skills/roles/architect.md +1 -1
- package/skills/roles/architect.platform.md +1 -1
- package/skills/roles/{product-manager.business-strategy.md → business-strategist.md} +3 -3
- package/skills/roles/data-analyst.experiment.md +1 -1
- package/skills/roles/data-analyst.md +1 -1
- package/skills/roles/data-analyst.product-intelligence.md +1 -1
- package/skills/roles/data-analyst.product.md +1 -1
- package/skills/roles/data-analyst.telemetry.md +1 -1
- package/skills/roles/{engineer.data.md → data-engineer.md} +2 -2
- package/skills/roles/data-engineer.pipeline.md +2 -2
- package/skills/roles/data-engineer.vector-retrieval.md +2 -2
- package/skills/roles/data-engineer.warehouse.md +2 -2
- package/skills/roles/debugger.md +1 -1
- package/skills/roles/designer.accessibility.md +1 -1
- package/skills/roles/designer.md +1 -1
- package/skills/roles/{reviewer.devil-advocate.md → devil-advocate.md} +2 -2
- package/skills/roles/{operator.docs.md → docs-keeper.md} +3 -3
- package/skills/roles/engineer.md +3 -7
- package/skills/roles/{reviewer.evaluator.md → evaluator.md} +2 -2
- package/skills/roles/{researcher.explorer.md → explorer.md} +2 -2
- package/skills/roles/{operator.md → operations.md} +2 -5
- package/skills/roles/orchestrator.md +1 -1
- package/skills/roles/{engineer.platform.md → platform-engineer.md} +2 -2
- package/skills/roles/product-manager.ai-product.md +1 -1
- package/skills/roles/product-manager.enterprise.md +1 -1
- package/skills/roles/product-manager.growth.md +1 -2
- package/skills/roles/product-manager.md +1 -2
- package/skills/roles/product-manager.platform.md +1 -1
- package/skills/roles/product-manager.product.md +1 -1
- package/skills/roles/qa.ai-eval.md +1 -1
- package/skills/roles/qa.api-contract.md +1 -1
- package/skills/roles/qa.data-pipeline.md +1 -1
- package/skills/roles/qa.md +1 -1
- package/skills/roles/qa.web-ui.md +1 -1
- package/skills/roles/{operator.release.md → release-manager.md} +3 -3
- package/skills/roles/researcher.md +1 -1
- package/skills/roles/reviewer.md +1 -1
- package/skills/roles/security.ai.md +1 -1
- package/skills/roles/security.appsec.md +1 -1
- package/skills/roles/security.cloud.md +1 -1
- package/skills/roles/security.legal-compliance.md +1 -1
- package/skills/roles/security.md +1 -1
- package/skills/roles/security.privacy.md +1 -1
- package/skills/roles/security.supply-chain.md +1 -1
- package/skills/roles/{operator.sre.md → sre.md} +3 -3
- package/skills/roles/{qa.test-automation.md → test-automation.md} +2 -2
- package/skills/roles/{reviewer.trace.md → trace-reviewer.md} +2 -2
- package/skills/roles/{researcher.ux.md → ux-researcher.md} +2 -2
- package/skills/routing.json +18 -0
- package/skills/routing.md +1 -1
- package/specialists/artifact-manifest.json +2 -1
- package/specialists/audit-enrichments.json +14 -14
- package/specialists/org/contracts/accessibility-to-qa.json +37 -0
- package/specialists/org/contracts/any-to-business-strategist.json +57 -0
- package/specialists/org/contracts/any-to-debugger.json +38 -0
- package/specialists/org/contracts/any-to-designer.json +33 -0
- package/specialists/org/contracts/any-to-docs-keeper.json +34 -0
- package/specialists/org/contracts/any-to-explorer.json +39 -0
- package/specialists/org/contracts/any-to-sre-incident.json +33 -0
- package/specialists/org/contracts/any-to-trace-reviewer.json +32 -0
- package/specialists/org/contracts/architect-to-ai-engineer.json +32 -0
- package/specialists/org/contracts/architect-to-data-engineer.json +52 -0
- package/specialists/org/contracts/architect-to-devil-advocate.json +38 -0
- package/specialists/org/contracts/architect-to-engineer.json +34 -0
- package/specialists/org/contracts/architect-to-evaluator.json +59 -0
- package/specialists/org/contracts/architect-to-legal-compliance.json +55 -0
- package/specialists/org/contracts/architect-to-operations.json +45 -0
- package/specialists/org/contracts/architect-to-platform-engineer.json +42 -0
- package/specialists/org/contracts/business-strategist-to-product-manager.json +39 -0
- package/specialists/org/contracts/construct-to-orchestrator.json +36 -0
- package/specialists/org/contracts/construct-to-rd-lead.json +53 -0
- package/specialists/org/contracts/data-analyst-to-product-manager.json +43 -0
- package/specialists/org/contracts/data-engineer-to-platform-engineer.json +36 -0
- package/specialists/org/contracts/designer-to-accessibility.json +36 -0
- package/specialists/org/contracts/engineer-to-qa.json +34 -0
- package/specialists/org/contracts/engineer-to-reviewer.json +52 -0
- package/specialists/org/contracts/explorer-to-engineer.json +38 -0
- package/specialists/org/contracts/legal-compliance-to-release-manager.json +43 -0
- package/specialists/org/contracts/platform-engineer-to-engineer.json +31 -0
- package/specialists/org/contracts/product-manager-to-architect.json +71 -0
- package/specialists/org/contracts/product-manager-to-data-analyst.json +49 -0
- package/specialists/org/contracts/product-manager-to-ux-researcher.json +51 -0
- package/specialists/org/contracts/qa-to-release-manager.json +42 -0
- package/specialists/org/contracts/qa-to-test-automation.json +42 -0
- package/specialists/org/contracts/rd-lead-to-architect.json +38 -0
- package/specialists/org/contracts/researcher-to-architect.json +40 -0
- package/specialists/org/contracts/researcher-to-product-manager.json +57 -0
- package/specialists/org/contracts/reviewer-to-security.json +41 -0
- package/specialists/org/contracts/sre-to-release-manager.json +36 -0
- package/specialists/org/contracts/test-automation-to-engineer.json +34 -0
- package/specialists/org/contracts/trace-reviewer-to-sre.json +41 -0
- package/specialists/org/contracts/user-to-construct.json +30 -0
- package/specialists/org/groups/engineering-group.json +43 -0
- package/specialists/org/groups/governance-group.json +38 -0
- package/specialists/org/groups/operations-group.json +41 -0
- package/specialists/org/groups/product-group.json +46 -0
- package/specialists/org/groups/quality-group.json +42 -0
- package/specialists/org/groups/strategy-group.json +41 -0
- package/specialists/org/policies/action-approval.json +13 -0
- package/specialists/org/policies/agents-routing.json +13 -0
- package/specialists/org/policies/architecture.json +20 -0
- package/specialists/org/policies/bash-safety.json +13 -0
- package/specialists/org/policies/beads-hygiene.json +13 -0
- package/specialists/org/policies/bootstrap-state.json +13 -0
- package/specialists/org/policies/code-review.json +13 -0
- package/specialists/org/policies/coding-style.json +13 -0
- package/specialists/org/policies/comments.json +13 -0
- package/specialists/org/policies/commit-approval.json +13 -0
- package/specialists/org/policies/contract-preconditions.json +13 -0
- package/specialists/org/policies/deployment.json +20 -0
- package/specialists/org/policies/description.json +14 -0
- package/specialists/org/policies/design-approval.json +19 -0
- package/specialists/org/policies/doc-ownership.json +13 -0
- package/specialists/org/policies/file-path-fence.json +13 -0
- package/specialists/org/policies/framing.json +13 -0
- package/specialists/org/policies/git-workflow.json +13 -0
- package/specialists/org/policies/incident-response.json +15 -0
- package/specialists/org/policies/intake-triage.json +15 -0
- package/specialists/org/policies/neurodivergent-output.json +13 -0
- package/specialists/org/policies/no-fabrication.json +13 -0
- package/specialists/org/policies/patterns.json +13 -0
- package/specialists/org/policies/quality-gate-approval.json +17 -0
- package/specialists/org/policies/release-gates.json +13 -0
- package/specialists/org/policies/research-evidence.json +13 -0
- package/specialists/org/policies/review-before-change.json +13 -0
- package/specialists/org/policies/rollback.json +15 -0
- package/specialists/org/policies/scope-change.json +20 -0
- package/specialists/org/policies/secret-scan.json +13 -0
- package/specialists/org/policies/security-approval.json +17 -0
- package/specialists/org/policies/security.json +13 -0
- package/specialists/org/policies/session-efficiency.json +13 -0
- package/specialists/org/policies/skill-routing.json +13 -0
- package/specialists/org/policies/strategic-prioritization.json +17 -0
- package/specialists/org/policies/testing.json +13 -0
- package/specialists/org/policies/tool-invisibility.json +14 -0
- package/specialists/org/scopes/creative.json +54 -0
- package/specialists/org/scopes/operations.json +51 -0
- package/specialists/org/scopes/research.json +60 -0
- package/specialists/org/scopes/rnd.json +81 -0
- package/specialists/org/specialists/cx-accessibility.json +69 -0
- package/specialists/org/specialists/cx-ai-engineer.json +75 -0
- package/specialists/org/specialists/cx-architect.json +89 -0
- package/specialists/org/specialists/cx-business-strategist.json +72 -0
- package/specialists/org/specialists/cx-data-analyst.json +68 -0
- package/specialists/org/specialists/cx-data-engineer.json +71 -0
- package/specialists/org/specialists/cx-debugger.json +75 -0
- package/specialists/org/specialists/cx-designer.json +85 -0
- package/specialists/org/specialists/cx-devil-advocate.json +71 -0
- package/specialists/org/specialists/cx-docs-keeper.json +82 -0
- package/specialists/org/specialists/cx-engineer.json +106 -0
- package/specialists/org/specialists/cx-evaluator.json +69 -0
- package/specialists/org/specialists/cx-explorer.json +69 -0
- package/specialists/org/specialists/cx-legal-compliance.json +74 -0
- package/specialists/org/specialists/cx-operations.json +72 -0
- package/specialists/org/specialists/cx-oracle.json +46 -0
- package/specialists/org/specialists/cx-orchestrator.json +81 -0
- package/specialists/org/specialists/cx-platform-engineer.json +80 -0
- package/specialists/org/specialists/cx-product-manager.json +102 -0
- package/specialists/org/specialists/cx-qa.json +79 -0
- package/specialists/org/specialists/cx-rd-lead.json +73 -0
- package/specialists/org/specialists/cx-release-manager.json +77 -0
- package/specialists/org/specialists/cx-researcher.json +82 -0
- package/specialists/org/specialists/cx-reviewer.json +71 -0
- package/specialists/org/specialists/cx-security.json +91 -0
- package/specialists/org/specialists/cx-sre.json +94 -0
- package/specialists/org/specialists/cx-test-automation.json +69 -0
- package/specialists/org/specialists/cx-trace-reviewer.json +69 -0
- package/specialists/org/specialists/cx-ux-researcher.json +68 -0
- package/specialists/org/teams/accessibility-team.json +39 -0
- package/specialists/org/teams/design-team.json +40 -0
- package/specialists/org/teams/engineering-team.json +50 -0
- package/specialists/org/teams/governance-team.json +41 -0
- package/specialists/org/teams/operations-team.json +46 -0
- package/specialists/org/teams/product-management-team.json +45 -0
- package/specialists/org/teams/quality-team.json +49 -0
- package/specialists/org/teams/research-team.json +39 -0
- package/specialists/org/teams/strategy-team.json +48 -0
- package/specialists/org/teams/ux-research-team.json +39 -0
- package/specialists/prompts/_shared/validation-contract.md +1 -1
- package/specialists/prompts/_team-template.md +10 -0
- package/specialists/prompts/cx-accessibility.md +1 -0
- package/specialists/prompts/cx-ai-engineer.md +1 -1
- package/specialists/prompts/cx-business-strategist.md +1 -1
- package/specialists/prompts/cx-data-engineer.md +1 -1
- package/specialists/prompts/cx-designer.md +1 -0
- package/specialists/prompts/cx-devil-advocate.md +1 -1
- package/specialists/prompts/cx-docs-keeper.md +1 -1
- package/specialists/prompts/cx-evaluator.md +1 -1
- package/specialists/prompts/cx-explorer.md +1 -1
- package/specialists/prompts/cx-operations.md +1 -1
- package/specialists/prompts/cx-oracle.md +7 -3
- package/specialists/prompts/cx-orchestrator.md +17 -1
- package/specialists/prompts/cx-platform-engineer.md +1 -1
- package/specialists/prompts/cx-product-manager.md +2 -0
- package/specialists/prompts/cx-release-manager.md +1 -1
- package/specialists/prompts/cx-researcher.md +7 -4
- package/specialists/prompts/cx-sre.md +1 -1
- package/specialists/prompts/cx-test-automation.md +2 -2
- package/specialists/prompts/cx-trace-reviewer.md +3 -3
- package/specialists/prompts/cx-ux-researcher.md +2 -1
- package/templates/demos/scripts/architecture-review-adr.json +30 -0
- package/templates/demos/scripts/capability-contract.json +25 -0
- package/templates/demos/scripts/intake-triage.json +25 -0
- package/templates/demos/scripts/profile-doctor-health.json +25 -0
- package/templates/demos/tapes/agentic-platforms-prd.tape +2 -2
- package/templates/demos/tapes/architecture-review-adr.tape +44 -0
- package/templates/demos/tapes/capability-contract.tape +39 -0
- package/templates/demos/tapes/intake-triage.tape +39 -0
- package/templates/demos/tapes/profile-doctor-health.tape +39 -0
- package/templates/distribution/construct-brand.typ +23 -18
- package/templates/distribution/construct-decision.typ +1 -1
- package/templates/distribution/construct-pdf.typ +1 -1
- package/templates/distribution/construct-prd.typ +1 -1
- package/templates/distribution/construct-research.typ +1 -1
- package/templates/distribution/mermaid-puppeteer.json +8 -0
- package/templates/docs/persona-artifact.md +1 -1
- package/templates/docs/prd.md +6 -0
- package/lib/boundary.mjs +0 -127
- package/lib/certification/dashboard-api.mjs +0 -71
- package/lib/chat/cli.mjs +0 -333
- package/lib/chat/command-suggest.mjs +0 -161
- package/lib/chat/commands.mjs +0 -215
- package/lib/chat/config.mjs +0 -142
- package/lib/chat/context-compactor.mjs +0 -250
- package/lib/chat/context-continuation.mjs +0 -253
- package/lib/chat/continuation-source.mjs +0 -58
- package/lib/chat/demo-guide.mjs +0 -61
- package/lib/chat/design-tokens.mjs +0 -91
- package/lib/chat/desktop-binary.mjs +0 -81
- package/lib/chat/desktop-build.mjs +0 -130
- package/lib/chat/desktop-launcher.mjs +0 -133
- package/lib/chat/evidence.mjs +0 -145
- package/lib/chat/export.mjs +0 -74
- package/lib/chat/harness/driver.mjs +0 -91
- package/lib/chat/list-picker.mjs +0 -112
- package/lib/chat/model-picker.mjs +0 -356
- package/lib/chat/openrouter-fallback.mjs +0 -151
- package/lib/chat/permission-prompt.mjs +0 -33
- package/lib/chat/picker-catalog.mjs +0 -45
- package/lib/chat/policy-telemetry.mjs +0 -34
- package/lib/chat/present.mjs +0 -246
- package/lib/chat/session-context.mjs +0 -39
- package/lib/chat/session-persist.mjs +0 -73
- package/lib/chat/session-restore.mjs +0 -71
- package/lib/chat/session-settings.mjs +0 -53
- package/lib/chat/system-prompt.mjs +0 -52
- package/lib/chat/transparency.mjs +0 -93
- package/lib/chat/tui/color-scheme.mjs +0 -42
- package/lib/chat/tui/markdown.mjs +0 -123
- package/lib/chat/tui/presentation.mjs +0 -100
- package/lib/chat/tui/render.mjs +0 -500
- package/lib/chat/tui/turn-block.mjs +0 -284
- package/lib/chat/tui/turn-present.mjs +0 -18
- package/lib/chat/tui/turn-state.mjs +0 -88
- package/lib/chat/tui/usage.mjs +0 -122
- package/lib/chat/web-commands.mjs +0 -146
- package/lib/chat/web-launcher.mjs +0 -63
- package/lib/chat/web-picker-keys.mjs +0 -46
- package/lib/chat/web-session.mjs +0 -159
- package/lib/config/alias.mjs +0 -57
- package/lib/dashboard-demo.mjs +0 -71
- package/lib/dashboard-static.mjs +0 -175
- package/lib/install/desktop-binary-download.mjs +0 -88
- package/lib/profiles/loader.mjs +0 -123
- package/lib/profiles/rebrand.mjs +0 -46
- package/lib/server/auth.mjs +0 -169
- package/lib/server/chat-loop.mjs +0 -622
- package/lib/server/chat.mjs +0 -336
- package/lib/server/cors.mjs +0 -77
- package/lib/server/csrf.mjs +0 -103
- package/lib/server/demo-preview.mjs +0 -63
- package/lib/server/index.mjs +0 -2641
- package/lib/server/insights.mjs +0 -780
- package/lib/server/langfuse-login.mjs +0 -58
- package/lib/server/rate-limit.mjs +0 -93
- package/lib/server/telemetry-login.mjs +0 -100
- package/lib/server/webhook.mjs +0 -512
- package/specialists/contracts.json +0 -1032
- package/specialists/contracts.schema.json +0 -83
- package/specialists/policy-inventory.json +0 -188
- package/specialists/registry.json +0 -1412
- package/specialists/role-manifests.json +0 -217
- package/specialists/teams.json +0 -94
|
@@ -55,13 +55,17 @@
|
|
|
55
55
|
#let construct-font-display = ("Space Grotesk",)
|
|
56
56
|
#let construct-font-mono = ("JetBrains Mono",)
|
|
57
57
|
|
|
58
|
+
#let horizontalrule = block(width: 100%, above: 0.85em, below: 0.95em)[
|
|
59
|
+
#line(length: 100%, stroke: 0.6pt + hairline-strong)
|
|
60
|
+
]
|
|
61
|
+
|
|
58
62
|
// Type scale. One modular ramp shared by every document type so sizing never
|
|
59
63
|
// drifts between a PRD, a research brief, and a decision record.
|
|
60
64
|
|
|
61
65
|
#let fs-micro = 8pt
|
|
62
66
|
#let fs-small = 8.5pt
|
|
63
67
|
#let fs-meta = 9pt
|
|
64
|
-
#let fs-body =
|
|
68
|
+
#let fs-body = 10.4pt
|
|
65
69
|
#let fs-h4 = 8.5pt
|
|
66
70
|
#let fs-h3 = 11pt
|
|
67
71
|
#let fs-h2 = 13pt
|
|
@@ -76,8 +80,8 @@
|
|
|
76
80
|
#let wt-semibold = 600
|
|
77
81
|
#let wt-bold = 700
|
|
78
82
|
|
|
79
|
-
#let construct-figure-max-width =
|
|
80
|
-
#let construct-figure-max-height =
|
|
83
|
+
#let construct-figure-max-width = 92%
|
|
84
|
+
#let construct-figure-max-height = 3.4in
|
|
81
85
|
|
|
82
86
|
// A document-type word maps to a compact badge so the masthead reads as a
|
|
83
87
|
// labelled artifact rather than a bare title.
|
|
@@ -290,20 +294,18 @@
|
|
|
290
294
|
|
|
291
295
|
#let construct-theme(body) = {
|
|
292
296
|
set text(font: construct-font-sans, size: fs-body, fill: ink-body, lang: "en", tracking: 0.002em)
|
|
293
|
-
set par(justify: false, leading: 0.
|
|
297
|
+
set par(justify: false, leading: 0.9em, spacing: 1.24em)
|
|
294
298
|
set heading(numbering: none, outlined: true)
|
|
295
299
|
|
|
296
300
|
show strong: set text(font: construct-font-sans, weight: wt-semibold, fill: ink)
|
|
297
301
|
show emph: set text(style: "italic")
|
|
298
302
|
|
|
299
|
-
// Lists
|
|
300
|
-
//
|
|
301
|
-
//
|
|
303
|
+
// Lists need looser vertical rhythm than body prose, but ordered lists must
|
|
304
|
+
// preserve Typst's native counter context or every item will render as `1.`.
|
|
305
|
+
// Spacing belongs on the list container, not on a wrapped enum.item block.
|
|
302
306
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
set list(marker: (text(fill: ink)[•], text(fill: ink-muted)[‣], text(fill: ink-faint)[–]), indent: 2pt, body-indent: 8pt, spacing: 0.9em)
|
|
306
|
-
set enum(indent: 2pt, body-indent: 8pt, spacing: 0.9em)
|
|
307
|
+
set list(marker: (text(fill: ink)[•], text(fill: ink-muted)[‣], text(fill: ink-faint)[–]), indent: 2pt, body-indent: 9pt, spacing: 1.02em)
|
|
308
|
+
set enum(numbering: "1.", indent: 2pt, body-indent: 9pt, spacing: 1.02em)
|
|
307
309
|
|
|
308
310
|
// Links carry ink with a hairline underline so citations stay legible without
|
|
309
311
|
// introducing color.
|
|
@@ -322,7 +324,7 @@
|
|
|
322
324
|
text(font: construct-font-display, size: fs-h1, weight: wt-semibold, fill: ink, tracking: -0.015em)[#it.body]
|
|
323
325
|
v(0.22em)
|
|
324
326
|
line(length: 100%, stroke: 0.5pt + hairline)
|
|
325
|
-
v(0.
|
|
327
|
+
v(0.7em, weak: true)
|
|
326
328
|
})
|
|
327
329
|
}
|
|
328
330
|
show heading.where(level: 2): it => {
|
|
@@ -331,14 +333,14 @@
|
|
|
331
333
|
text(font: construct-font-display, size: fs-h2, weight: wt-semibold, fill: ink, tracking: -0.01em)[#it.body]
|
|
332
334
|
v(0.4em)
|
|
333
335
|
line(length: 26pt, stroke: 1.5pt + ink)
|
|
334
|
-
v(0.
|
|
336
|
+
v(0.78em, weak: true)
|
|
335
337
|
})
|
|
336
338
|
}
|
|
337
339
|
show heading.where(level: 3): it => {
|
|
338
340
|
v(1.15em, weak: true)
|
|
339
341
|
block(sticky: true, {
|
|
340
342
|
text(font: construct-font-sans, size: fs-h3, weight: wt-semibold, fill: ink-strong)[#it.body]
|
|
341
|
-
v(0.
|
|
343
|
+
v(0.48em, weak: true)
|
|
342
344
|
})
|
|
343
345
|
}
|
|
344
346
|
show heading.where(level: 4): it => {
|
|
@@ -414,10 +416,13 @@
|
|
|
414
416
|
radius: 4pt,
|
|
415
417
|
)[
|
|
416
418
|
#align(center)[
|
|
417
|
-
#
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
419
|
+
#show image: img => image(
|
|
420
|
+
img,
|
|
421
|
+
width: construct-figure-max-width,
|
|
422
|
+
height: construct-figure-max-height,
|
|
423
|
+
fit: "contain",
|
|
424
|
+
)
|
|
425
|
+
#it.body
|
|
421
426
|
]
|
|
422
427
|
]
|
|
423
428
|
if it.caption != none {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# <Role display name>
|
|
2
2
|
|
|
3
|
-
> Anchor doc for the <role-id> persona. Methodology: `docs/guides/concepts/persona-research.md`. This file is generated by `construct
|
|
3
|
+
> Anchor doc for the <role-id> persona. Methodology: `docs/guides/concepts/persona-research.md`. This file is generated by `construct scope create` and is part of the discover + frame phases. The persona is not promotable until every section below is filled from evidence, not opinion.
|
|
4
4
|
|
|
5
5
|
## Goals
|
|
6
6
|
|
package/templates/docs/prd.md
CHANGED
|
@@ -20,6 +20,8 @@ not the whole document. Keep em dashes rare; prefer commas, periods, or parenthe
|
|
|
20
20
|
-->
|
|
21
21
|
|
|
22
22
|
## Summary
|
|
23
|
+
This PRD defines {title} for {primary user or customer segment}. It explains the current friction, the measurable outcome this work should unlock, and the smallest shippable path to prove the change works. Replace this paragraph with evidence-backed product context before review.
|
|
24
|
+
|
|
23
25
|
<!--
|
|
24
26
|
One paragraph (3-5 sentences) that a busy reader can use as the whole PRD.
|
|
25
27
|
What the change is, who it's for, why now, and what changes when it ships.
|
|
@@ -27,6 +29,8 @@ No solutions in this section that aren't decided. No ticket IDs. No team names.
|
|
|
27
29
|
-->
|
|
28
30
|
|
|
29
31
|
## Background
|
|
32
|
+
Today, {current workflow or system} creates avoidable friction for {affected users}. The evidence that matters for this PRD should include observed behavior, quantitative signals, or qualitative research, and the links below should let reviewers verify the claim without relying on memory.
|
|
33
|
+
|
|
30
34
|
<!--
|
|
31
35
|
Context the reader needs to evaluate this PRD without asking around.
|
|
32
36
|
Include relevant prior work (linked PRDs, ADRs, RFCs), observed signals, and
|
|
@@ -38,6 +42,8 @@ Avoid roadmap-speak ("this is a Q3 priority"); state what is happening to users.
|
|
|
38
42
|
-->
|
|
39
43
|
|
|
40
44
|
## Problem
|
|
45
|
+
{Affected users} cannot reliably achieve {desired outcome} because {constraint or failure mode}. The problem is important now because the current workaround is costly, error-prone, or blocks adoption for a clearly named segment.
|
|
46
|
+
|
|
41
47
|
<!--
|
|
42
48
|
The specific user or business outcome that is currently blocked. One or two
|
|
43
49
|
paragraphs. State the pain, not the solution.
|
package/lib/boundary.mjs
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/boundary.mjs — Authenticated parent/child boundary registration.
|
|
3
|
-
*
|
|
4
|
-
* Verifies a parent Construct instance is reachable, validates an HMAC
|
|
5
|
-
* signature over `childInstanceId|nonce` when a shared secret is configured,
|
|
6
|
-
* and persists the binding to boundary.json in the XDG config dir (mode 0600). A
|
|
7
|
-
* different parent rotates the registration only when explicitly allowed via
|
|
8
|
-
* CONSTRUCT_BOUNDARY_ALLOW_OVERRIDE=1; prior configs are archived alongside
|
|
9
|
-
* the active one. Exposed as a standalone module so the dashboard endpoint
|
|
10
|
-
* and the functional tests share the same logic.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
|
-
import { join } from 'node:path';
|
|
15
|
-
import { homedir } from 'node:os';
|
|
16
|
-
import { createHmac, timingSafeEqual, randomBytes } from 'node:crypto';
|
|
17
|
-
import { request as httpRequest } from 'node:http';
|
|
18
|
-
import { request as httpsRequest } from 'node:https';
|
|
19
|
-
import { configDir } from './config/xdg.mjs';
|
|
20
|
-
|
|
21
|
-
export const BOUNDARY_VERSION = '1.0';
|
|
22
|
-
|
|
23
|
-
function boundaryDir(home = homedir()) {
|
|
24
|
-
return configDir(home);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function boundaryConfigPath(home = homedir()) {
|
|
28
|
-
return join(boundaryDir(home), 'boundary.json');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function registerBoundary({
|
|
32
|
-
parentInstance,
|
|
33
|
-
parentUrl,
|
|
34
|
-
childInstanceId,
|
|
35
|
-
nonce,
|
|
36
|
-
signature,
|
|
37
|
-
sharedSecret = null,
|
|
38
|
-
home = homedir(),
|
|
39
|
-
allowOverride = process.env.CONSTRUCT_BOUNDARY_ALLOW_OVERRIDE === '1',
|
|
40
|
-
probe = probeParent,
|
|
41
|
-
}) {
|
|
42
|
-
if (!parentInstance || !parentUrl) {
|
|
43
|
-
return { ok: false, status: 400, error: 'parentInstance and parentUrl are required' };
|
|
44
|
-
}
|
|
45
|
-
if (!childInstanceId) {
|
|
46
|
-
return { ok: false, status: 400, error: 'childInstanceId is required' };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (sharedSecret) {
|
|
50
|
-
if (!nonce || !signature) {
|
|
51
|
-
return { ok: false, status: 401, error: 'nonce and signature are required when a shared secret is configured' };
|
|
52
|
-
}
|
|
53
|
-
const expected = createHmac('sha256', sharedSecret).update(`${childInstanceId}|${nonce}`).digest('hex');
|
|
54
|
-
const a = Buffer.from(expected, 'hex');
|
|
55
|
-
let b;
|
|
56
|
-
try { b = Buffer.from(String(signature), 'hex'); } catch { return { ok: false, status: 401, error: 'invalid signature encoding' }; }
|
|
57
|
-
if (a.length !== b.length || !timingSafeEqual(a, b)) {
|
|
58
|
-
return { ok: false, status: 401, error: 'signature mismatch' };
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const reachable = await probe(parentUrl);
|
|
63
|
-
if (!reachable.ok) {
|
|
64
|
-
return { ok: false, status: 502, error: `parent unreachable: ${reachable.error}` };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const dir = boundaryDir(home);
|
|
68
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
69
|
-
const cfgPath = boundaryConfigPath(home);
|
|
70
|
-
|
|
71
|
-
let prior = null;
|
|
72
|
-
if (existsSync(cfgPath)) {
|
|
73
|
-
try { prior = JSON.parse(readFileSync(cfgPath, 'utf8')); } catch { prior = null; }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (prior && prior.parentInstance && prior.parentInstance !== parentInstance) {
|
|
77
|
-
if (!allowOverride) {
|
|
78
|
-
return {
|
|
79
|
-
ok: false,
|
|
80
|
-
status: 409,
|
|
81
|
-
error: `child already bound to parent '${prior.parentInstance}'; set CONSTRUCT_BOUNDARY_ALLOW_OVERRIDE=1 to rotate`,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
const archivePath = join(dir, `boundary.${Date.now()}.json`);
|
|
85
|
-
try { writeFileSync(archivePath, JSON.stringify(prior, null, 2)); } catch { /* archive is best effort */ }
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const config = {
|
|
89
|
-
parentInstance,
|
|
90
|
-
parentUrl,
|
|
91
|
-
childInstanceId,
|
|
92
|
-
registeredAt: new Date().toISOString(),
|
|
93
|
-
rotatedFrom: prior?.parentInstance || null,
|
|
94
|
-
nonce: nonce || randomBytes(16).toString('hex'),
|
|
95
|
-
boundaryVersion: BOUNDARY_VERSION,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
writeFileSync(cfgPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
99
|
-
return { ok: true, config, path: cfgPath };
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function probeParent(parentUrl) {
|
|
103
|
-
return new Promise((resolve) => {
|
|
104
|
-
let parsed;
|
|
105
|
-
try { parsed = new URL(parentUrl); } catch { return resolve({ ok: false, error: 'invalid URL' }); }
|
|
106
|
-
if (!/^https?:$/.test(parsed.protocol)) return resolve({ ok: false, error: 'unsupported protocol' });
|
|
107
|
-
const fn = parsed.protocol === 'https:' ? httpsRequest : httpRequest;
|
|
108
|
-
const req = fn({
|
|
109
|
-
method: 'HEAD',
|
|
110
|
-
protocol: parsed.protocol,
|
|
111
|
-
hostname: parsed.hostname,
|
|
112
|
-
port: parsed.port,
|
|
113
|
-
path: parsed.pathname || '/',
|
|
114
|
-
timeout: 3000,
|
|
115
|
-
}, (response) => {
|
|
116
|
-
resolve({ ok: response.statusCode < 500 });
|
|
117
|
-
response.resume();
|
|
118
|
-
});
|
|
119
|
-
req.on('timeout', () => { req.destroy(); resolve({ ok: false, error: 'timeout' }); });
|
|
120
|
-
req.on('error', (err) => resolve({ ok: false, error: err.message }));
|
|
121
|
-
req.end();
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export function signBoundaryRequest({ childInstanceId, nonce, sharedSecret }) {
|
|
126
|
-
return createHmac('sha256', sharedSecret).update(`${childInstanceId}|${nonce}`).digest('hex');
|
|
127
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/certification/dashboard-api.mjs — dashboard-safe certification status payload.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors construct certify status for GET /api/certification/status without secrets.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import fs from 'node:fs';
|
|
8
|
-
import path from 'node:path';
|
|
9
|
-
|
|
10
|
-
import { buildCertificationStatus } from './status.mjs';
|
|
11
|
-
import { loadCertificationStatus } from './stale-impact.mjs';
|
|
12
|
-
import { certificationRunDir, certificationRunsRoot, listCertificationRunIds, readCertificationRun } from './store.mjs';
|
|
13
|
-
|
|
14
|
-
function findConstructRoot(startPath = process.cwd()) {
|
|
15
|
-
let current = path.resolve(startPath);
|
|
16
|
-
while (true) {
|
|
17
|
-
if (fs.existsSync(path.join(current, 'package.json'))) return current;
|
|
18
|
-
const parent = path.dirname(current);
|
|
19
|
-
if (parent === current) return path.resolve(startPath);
|
|
20
|
-
current = parent;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function buildStaleRows({ rootDir }) {
|
|
25
|
-
const { status } = loadCertificationStatus({ rootDir });
|
|
26
|
-
if (!status?.capabilities) return [];
|
|
27
|
-
return Object.entries(status.capabilities)
|
|
28
|
-
.filter(([, entry]) => entry.status === 'stale')
|
|
29
|
-
.map(([capabilityId, entry]) => ({
|
|
30
|
-
capabilityId,
|
|
31
|
-
staleSince: entry.staleSince ?? null,
|
|
32
|
-
staleReason: entry.staleReason ?? null,
|
|
33
|
-
stalePaths: entry.stalePaths ?? [],
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function buildCertificationDashboard({ rootDir = process.cwd() } = {}) {
|
|
38
|
-
const root = findConstructRoot(rootDir);
|
|
39
|
-
const report = buildCertificationStatus({ rootDir: root });
|
|
40
|
-
const runs = [];
|
|
41
|
-
for (const runId of listCertificationRunIds({ rootDir: root }).slice(-20)) {
|
|
42
|
-
try {
|
|
43
|
-
const { run } = readCertificationRun(runId, { rootDir: root });
|
|
44
|
-
const dir = certificationRunDir(runId, root);
|
|
45
|
-
runs.push({
|
|
46
|
-
id: run.id,
|
|
47
|
-
scenarioId: run.scenarioId,
|
|
48
|
-
capabilityId: run.capabilityId,
|
|
49
|
-
status: run.verdict?.status ?? 'unknown',
|
|
50
|
-
createdAt: run.createdAt,
|
|
51
|
-
artifactPath: path.relative(root, path.join(dir, 'run.json')),
|
|
52
|
-
});
|
|
53
|
-
} catch { /* skip corrupt */ }
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
generatedAt: report.generatedAt,
|
|
57
|
-
capabilities: report.capabilities,
|
|
58
|
-
specialists: report.specialists,
|
|
59
|
-
skills: report.skills,
|
|
60
|
-
artifactTypes: report.artifactTypes,
|
|
61
|
-
documentCategories: report.documentCategories,
|
|
62
|
-
demos: report.demos,
|
|
63
|
-
stale: buildStaleRows({ rootDir: root }),
|
|
64
|
-
runs,
|
|
65
|
-
runsDir: path.relative(root, certificationRunsRoot(root)),
|
|
66
|
-
artifactLinks: {
|
|
67
|
-
runsRoot: '.cx/certification/runs',
|
|
68
|
-
recentRunIds: runs.map((r) => r.id),
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
}
|