@pennyfarthing/core 11.0.0 → 11.1.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/README.md +81 -23
- package/package.json +1 -1
- package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.d.ts +20 -0
- package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.js +278 -0
- package/packages/core/dist/cli/utils/010-detect-remove-old-packages.test.js.map +1 -0
- package/packages/core/dist/cli/utils/constants.d.ts +8 -2
- package/packages/core/dist/cli/utils/constants.d.ts.map +1 -1
- package/packages/core/dist/cli/utils/constants.js +4 -1
- package/packages/core/dist/cli/utils/constants.js.map +1 -1
- package/packages/core/dist/cli/utils/constants.test.d.ts +10 -0
- package/packages/core/dist/cli/utils/constants.test.d.ts.map +1 -0
- package/packages/core/dist/cli/utils/constants.test.js +38 -0
- package/packages/core/dist/cli/utils/constants.test.js.map +1 -0
- package/packages/core/dist/consultation/consultation-protocol.d.ts +139 -0
- package/packages/core/dist/consultation/consultation-protocol.d.ts.map +1 -0
- package/packages/core/dist/consultation/consultation-protocol.js +178 -0
- package/packages/core/dist/consultation/consultation-protocol.js.map +1 -0
- package/packages/core/dist/consultation/consultation-protocol.test.d.ts +20 -0
- package/packages/core/dist/consultation/consultation-protocol.test.d.ts.map +1 -0
- package/packages/core/dist/consultation/consultation-protocol.test.js +474 -0
- package/packages/core/dist/consultation/consultation-protocol.test.js.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.d.ts +75 -0
- package/packages/core/dist/consultation/dialogue-manager.d.ts.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.js +334 -0
- package/packages/core/dist/consultation/dialogue-manager.js.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.test.d.ts +19 -0
- package/packages/core/dist/consultation/dialogue-manager.test.d.ts.map +1 -0
- package/packages/core/dist/consultation/dialogue-manager.test.js +444 -0
- package/packages/core/dist/consultation/dialogue-manager.test.js.map +1 -0
- package/packages/core/dist/public/js/react/react.js +3 -3
- package/packages/core/dist/scripts/theme-detail.test.d.ts +10 -0
- package/packages/core/dist/scripts/theme-detail.test.js +199 -0
- package/packages/core/dist/server/api/git.d.ts +13 -1
- package/packages/core/dist/server/api/git.d.ts.map +1 -1
- package/packages/core/dist/server/api/git.js +53 -34
- package/packages/core/dist/server/api/git.js.map +1 -1
- package/packages/core/dist/server/api/health-score.d.ts.map +1 -1
- package/packages/core/dist/server/api/health-score.js +25 -1
- package/packages/core/dist/server/api/health-score.js.map +1 -1
- package/packages/core/dist/server/api/settings.d.ts.map +1 -1
- package/packages/core/dist/server/api/settings.js +63 -1
- package/packages/core/dist/server/api/settings.js.map +1 -1
- package/packages/core/dist/server/api/theme-agents.d.ts.map +1 -1
- package/packages/core/dist/server/api/theme-agents.js +61 -0
- package/packages/core/dist/server/api/theme-agents.js.map +1 -1
- package/packages/core/dist/server/server.d.ts.map +1 -1
- package/packages/core/dist/server/server.js +17 -12
- package/packages/core/dist/server/server.js.map +1 -1
- package/packages/core/dist/shared/skill-search.test.js +2 -2
- package/packages/core/dist/workflow/gate-file-validation.d.ts +49 -0
- package/packages/core/dist/workflow/gate-file-validation.d.ts.map +1 -0
- package/packages/core/dist/workflow/gate-file-validation.js +157 -0
- package/packages/core/dist/workflow/gate-file-validation.js.map +1 -0
- package/packages/core/dist/workflow/gate-file-validation.test.d.ts +19 -0
- package/packages/core/dist/workflow/gate-file-validation.test.d.ts.map +1 -0
- package/packages/core/dist/workflow/gate-file-validation.test.js +536 -0
- package/packages/core/dist/workflow/gate-file-validation.test.js.map +1 -0
- package/packages/core/dist/workflow/gate-schema-validation.test.d.ts +14 -0
- package/packages/core/dist/workflow/gate-schema-validation.test.d.ts.map +1 -0
- package/packages/core/dist/workflow/gate-schema-validation.test.js +339 -0
- package/packages/core/dist/workflow/gate-schema-validation.test.js.map +1 -0
- package/packages/core/dist/workflow/handoff.js +2 -2
- package/packages/core/dist/workflow/handoff.js.map +1 -1
- package/packages/core/dist/workflow/handoff.test.js +16 -0
- package/packages/core/dist/workflow/handoff.test.js.map +1 -1
- package/packages/core/dist/workflow/workflow-schema.d.ts +4 -2
- package/packages/core/dist/workflow/workflow-schema.d.ts.map +1 -1
- package/packages/core/dist/workflow/workflow-schema.js +43 -8
- package/packages/core/dist/workflow/workflow-schema.js.map +1 -1
- package/pennyfarthing-dist/agents/README.md +6 -14
- package/pennyfarthing-dist/agents/architect.md +43 -29
- package/pennyfarthing-dist/agents/ba.md +30 -29
- package/pennyfarthing-dist/agents/dev.md +32 -43
- package/pennyfarthing-dist/agents/devops.md +57 -21
- package/pennyfarthing-dist/agents/orchestrator.md +3 -10
- package/pennyfarthing-dist/agents/pm.md +45 -31
- package/pennyfarthing-dist/agents/reviewer.md +20 -66
- package/pennyfarthing-dist/agents/sm-setup.md +2 -2
- package/pennyfarthing-dist/agents/sm.md +8 -30
- package/pennyfarthing-dist/agents/tea.md +25 -41
- package/pennyfarthing-dist/agents/tech-writer.md +33 -90
- package/pennyfarthing-dist/agents/ux-designer.md +39 -39
- package/pennyfarthing-dist/commands/benchmark-control.md +8 -64
- package/pennyfarthing-dist/commands/benchmark.md +8 -480
- package/pennyfarthing-dist/commands/job-fair.md +8 -97
- package/pennyfarthing-dist/commands/pf-benchmark-control.md +70 -0
- package/pennyfarthing-dist/commands/pf-benchmark.md +486 -0
- package/pennyfarthing-dist/commands/pf-chore.md +4 -4
- package/pennyfarthing-dist/commands/pf-ci.md +40 -0
- package/pennyfarthing-dist/commands/pf-close-epic.md +9 -27
- package/pennyfarthing-dist/commands/pf-continue-session.md +9 -213
- package/pennyfarthing-dist/commands/pf-create-branches-from-story.md +11 -353
- package/pennyfarthing-dist/commands/pf-docs.md +28 -0
- package/pennyfarthing-dist/commands/pf-epic.md +67 -0
- package/pennyfarthing-dist/commands/pf-git-cleanup.md +11 -52
- package/pennyfarthing-dist/commands/pf-git.md +75 -0
- package/pennyfarthing-dist/commands/pf-help.md +110 -128
- package/pennyfarthing-dist/commands/pf-job-fair.md +102 -0
- package/pennyfarthing-dist/commands/pf-new-work.md +9 -18
- package/pennyfarthing-dist/commands/pf-parallel-work.md +6 -66
- package/pennyfarthing-dist/commands/pf-release.md +11 -76
- package/pennyfarthing-dist/commands/pf-repo-status.md +11 -44
- package/pennyfarthing-dist/commands/pf-run-ci.md +8 -111
- package/pennyfarthing-dist/commands/pf-session.md +51 -0
- package/pennyfarthing-dist/commands/pf-solo.md +447 -0
- package/pennyfarthing-dist/commands/pf-sprint-planning.md +8 -104
- package/pennyfarthing-dist/commands/pf-standalone.md +1 -1
- package/pennyfarthing-dist/commands/pf-start-epic.md +9 -163
- package/pennyfarthing-dist/commands/pf-sync-epic-to-jira.md +8 -179
- package/pennyfarthing-dist/commands/pf-sync-work-with-sprint.md +8 -368
- package/pennyfarthing-dist/commands/pf-update-domain-docs.md +8 -78
- package/pennyfarthing-dist/commands/solo.md +8 -442
- package/pennyfarthing-dist/guides/agent-behavior.md +13 -13
- package/pennyfarthing-dist/guides/agent-coordination.md +7 -7
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +6 -5
- package/pennyfarthing-dist/guides/bikerack.md +128 -0
- package/pennyfarthing-dist/guides/brownfield-tools.md +133 -0
- package/pennyfarthing-dist/guides/command-tag-taxonomy.md +2 -2
- package/pennyfarthing-dist/guides/gate-schema.md +227 -0
- package/pennyfarthing-dist/guides/gates.md +120 -0
- package/pennyfarthing-dist/guides/handoff-cli.md +116 -0
- package/pennyfarthing-dist/guides/hooks.md +86 -4
- package/pennyfarthing-dist/guides/output-styles.md +65 -0
- package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +5 -5
- package/pennyfarthing-dist/guides/patterns/tdd-flow-pattern.md +4 -4
- package/pennyfarthing-dist/guides/prompt-patterns.md +5 -5
- package/pennyfarthing-dist/guides/reflector.md +4 -4
- package/pennyfarthing-dist/guides/session-artifacts.md +1 -1
- package/pennyfarthing-dist/guides/skill-schema.md +1 -1
- package/pennyfarthing-dist/guides/tandem-protocol.md +13 -1
- package/pennyfarthing-dist/guides/worktree-mode.md +3 -3
- package/pennyfarthing-dist/guides/xml-tags.md +5 -4
- package/pennyfarthing-dist/personas/themes/hogans-heroes.yaml +11 -22
- package/pennyfarthing-dist/personas/themes/stephen-king.yaml +13 -24
- package/pennyfarthing-dist/scripts/core/dialogue-manager.sh +322 -0
- package/pennyfarthing-dist/scripts/core/phase-check-start.sh +1 -1
- package/pennyfarthing-dist/scripts/hooks/otel-auto-config.sh +19 -14
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.py +191 -57
- package/pennyfarthing-dist/scripts/portraits/generate-portraits.sh +26 -10
- package/pennyfarthing-dist/skills/pf-changelog/SKILL.md +4 -4
- package/pennyfarthing-dist/skills/pf-sprint/skill.md +1 -1
- package/pennyfarthing-dist/skills/skill-registry.schema.json +4 -0
- package/pennyfarthing-dist/skills/skill-registry.yaml +5 -0
- package/pennyfarthing-dist/workflows/2party-tdd.yaml +11 -0
- package/pennyfarthing-dist/workflows/agent-docs.yaml +2 -0
- package/pennyfarthing-dist/workflows/bdd-tandem.yaml +4 -0
- package/pennyfarthing-dist/workflows/bdd.yaml +4 -0
- package/pennyfarthing-dist/workflows/git-cleanup/steps/step-05-complete.md +1 -1
- package/pennyfarthing-dist/workflows/tdd-tandem.yaml +3 -0
- package/pennyfarthing-dist/workflows/tdd.yaml +3 -0
- package/pennyfarthing-dist/workflows/trivial.yaml +2 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/bellmode_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/context.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/hooks.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_bidirectional_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_epic_creation.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira_sync_story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/patch_mode.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/pretooluse_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/schema_validation_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/session_start_hook.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bc/__pycache__/focus.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/background_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/base_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/changed_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/debug_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/diffs_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/git_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/launcher.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/sprint_panel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/tui.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/__pycache__/ws_client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/bikerack/cli.py +10 -11
- package/pennyfarthing_scripts/bikerack/debug_panel.py +218 -0
- package/pennyfarthing_scripts/bikerack/diffs_panel.py +203 -27
- package/pennyfarthing_scripts/brownfield/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/brownfield/__pycache__/discover.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/cli.py +114 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/codemarkers/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/config.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/output.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/common/__pycache__/themes.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/complexity/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/deadcode/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/dependencies/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/epic/__init__.py +0 -0
- package/pennyfarthing_scripts/epic/cli.py +64 -0
- package/pennyfarthing_scripts/gate/__init__.py +1 -0
- package/pennyfarthing_scripts/gate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/__pycache__/validate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/gate/cli.py +56 -0
- package/pennyfarthing_scripts/gate/validate.py +266 -0
- package/pennyfarthing_scripts/git/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/create_branches.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git/__pycache__/status_all.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/git_group/__init__.py +0 -0
- package/pennyfarthing_scripts/git_group/cli.py +100 -0
- package/pennyfarthing_scripts/handoff/__init__.py +1 -0
- package/pennyfarthing_scripts/handoff/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/complete_phase.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/gate_file.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/gate_runner.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/marker.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/__pycache__/resolve_gate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/handoff/cli.py +120 -0
- package/pennyfarthing_scripts/handoff/complete_phase.py +155 -0
- package/pennyfarthing_scripts/handoff/gate_file.py +105 -0
- package/pennyfarthing_scripts/handoff/gate_runner.py +152 -0
- package/pennyfarthing_scripts/handoff/marker.py +109 -0
- package/pennyfarthing_scripts/handoff/resolve_gate.py +152 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/healthscore/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/analyze.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/formatters.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/hotspots/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/bidirectional.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/claim.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/client.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/operations.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/reconcile.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/story.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/sync.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/launch/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/skill.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/step.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/validate.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/preflight/__pycache__/finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/persona.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/session.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/tiers.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/version_sentinel.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/workflow.py +39 -0
- package/pennyfarthing_scripts/session/__init__.py +0 -0
- package/pennyfarthing_scripts/session/cli.py +87 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/archive_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/epic_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/import_epic.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/loader.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/status.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_add.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_finish.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/story_update.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validate_cmd.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/validator.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/work.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/__pycache__/yaml_io.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/sprint/story_finish.py +14 -0
- package/pennyfarthing_scripts/story/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/create.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/size.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/story/__pycache__/template.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_108_2_remove_handoff_fallback.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_archive_epic.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bc.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_bikerack.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_brownfield.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_modules.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_cli_normalization.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_codemarkers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_common.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_epic_shard_validation.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_gate_file_resolution.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_gate_runner.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_git_utils.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_handoff_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_handoff_e2e.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_healthscore.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_jira_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_package_structure.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_patch_mode.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_prime.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_resolve_gate_file_field.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_sprint_validator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_add.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_package.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_story_update.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tiers.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_token_counting.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_topology_loader.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_focus.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_tui_panel_persistence.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_validate_cmd.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_version_sentinel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_check.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_yaml_io.cpython-314-pytest-9.0.2.pyc +0 -0
- package/pennyfarthing_scripts/tests/test_108_1_gate_migration.py +540 -0
- package/pennyfarthing_scripts/tests/test_108_2_remove_handoff_fallback.py +339 -0
- package/pennyfarthing_scripts/tests/test_confidence_sm_evaluation.py +253 -0
- package/pennyfarthing_scripts/tests/test_confidence_sm_gate.py +315 -0
- package/pennyfarthing_scripts/tests/test_gate_file_resolution.py +341 -0
- package/pennyfarthing_scripts/tests/test_gate_runner.py +620 -0
- package/pennyfarthing_scripts/tests/test_handoff_cli.py +929 -0
- package/pennyfarthing_scripts/tests/test_handoff_e2e.py +454 -0
- package/pennyfarthing_scripts/tests/test_resolve_gate_file_field.py +464 -0
- package/pennyfarthing_scripts/theme/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/theme/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/agent.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/schema.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/skill_command.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/__pycache__/workflow.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/validate/adapters/skill_command.py +200 -0
- package/pennyfarthing_scripts/validate/adapters/workflow.py +64 -0
- package/pennyfarthing_scripts/validate/cli.py +15 -4
- package/packages/core/dist/scripts/benchmark-integration.d.ts +0 -182
- package/packages/core/dist/scripts/benchmark-integration.d.ts.map +0 -1
- package/packages/core/dist/scripts/benchmark-integration.js +0 -691
- package/packages/core/dist/scripts/benchmark-integration.js.map +0 -1
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts +0 -150
- package/packages/core/dist/scripts/job-fair-aggregator.d.ts.map +0 -1
- package/packages/core/dist/scripts/job-fair-aggregator.js +0 -547
- package/packages/core/dist/scripts/job-fair-aggregator.js.map +0 -1
- package/pennyfarthing-dist/agents/handoff.md +0 -250
- package/pennyfarthing-dist/agents/sm-handoff.md +0 -152
- package/pennyfarthing-dist/scripts/core/handoff-marker.sh +0 -112
- package/pennyfarthing-dist/scripts/hooks/__pycache__/question_reflector_check.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/jira.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/sprint.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/__pycache__/workflow.cpython-311.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/compat.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/mappings.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/jira/__pycache__/models.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/migration/__pycache__/cli.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/prime/__pycache__/__main__.cpython-314.pyc +0 -0
- package/pennyfarthing_scripts/tests/__pycache__/test_workflow_cli.cpython-314-pytest-9.0.2.pyc +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Story 86-2: Consultation Protocol Implementation
|
|
3
|
+
*
|
|
4
|
+
* RED state tests for the tandem consultation protocol.
|
|
5
|
+
* Consultation is an active request/response mechanism where a leader agent
|
|
6
|
+
* spawns a partner agent with a focused question and receives a structured recommendation.
|
|
7
|
+
*
|
|
8
|
+
* ACs covered:
|
|
9
|
+
* AC1: Consultation request format (context, question, options, code)
|
|
10
|
+
* AC2: Consultation response format (recommendation, rationale, watch-out-for, confidence)
|
|
11
|
+
* AC3: Leader spawns partner via Task tool with model: sonnet
|
|
12
|
+
* AC4: Partner prompt includes: agent definition, persona, consultation request
|
|
13
|
+
* AC5: Response parsed and available to leader for continued work
|
|
14
|
+
* AC6: Graceful degradation: partner failure → leader continues solo
|
|
15
|
+
* AC7: Token budget enforced via prompt instruction
|
|
16
|
+
*
|
|
17
|
+
* Run with: npm test
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it } from 'node:test';
|
|
20
|
+
import assert from 'node:assert';
|
|
21
|
+
import { formatConsultationRequest, parseConsultationResponse, validateConsultationRequest, validateConsultationResponse, buildPartnerPrompt, buildConsultationSpawnParams, executeConsultation, } from './consultation-protocol.js';
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Test Fixtures
|
|
24
|
+
// =============================================================================
|
|
25
|
+
const VALID_REQUEST = {
|
|
26
|
+
leader: 'dev',
|
|
27
|
+
leaderCharacter: 'Jack Torrance',
|
|
28
|
+
partner: 'architect',
|
|
29
|
+
context: 'Implementing consultation protocol for tandem agent communication',
|
|
30
|
+
question: 'Should we use markdown or JSON for the consultation request format?',
|
|
31
|
+
alternativesConsidered: [
|
|
32
|
+
'Structured markdown with bold field labels',
|
|
33
|
+
'JSON schema with typed fields',
|
|
34
|
+
'YAML document format',
|
|
35
|
+
],
|
|
36
|
+
relevantCode: 'See tandem-lifecycle.ts for existing backseat spawn pattern',
|
|
37
|
+
tokenBudget: 1000,
|
|
38
|
+
};
|
|
39
|
+
const VALID_RESPONSE_MARKDOWN = `**Recommendation:** Use structured markdown with bold field labels
|
|
40
|
+
**Rationale:** Markdown is human-readable, consistent with existing session files, and parseable with regex
|
|
41
|
+
**Watch-Out-For:** Markdown parsing is fragile — multiline values need careful handling, and bold markers inside code blocks could cause false matches
|
|
42
|
+
**Confidence:** high
|
|
43
|
+
**Token Count:** 85`;
|
|
44
|
+
const VALID_RESPONSE = {
|
|
45
|
+
recommendation: 'Use structured markdown with bold field labels',
|
|
46
|
+
rationale: 'Markdown is human-readable, consistent with existing session files, and parseable with regex',
|
|
47
|
+
watchOutFor: 'Markdown parsing is fragile — multiline values need careful handling, and bold markers inside code blocks could cause false matches',
|
|
48
|
+
confidence: 'high',
|
|
49
|
+
tokenCount: 85,
|
|
50
|
+
};
|
|
51
|
+
const MOCK_AGENT_DEF = '# Architect Agent\n<role>System design</role>';
|
|
52
|
+
const MOCK_PERSONA = '<persona agent="architect">Andy Dufresne</persona>';
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// AC1: Consultation request format defined
|
|
55
|
+
// =============================================================================
|
|
56
|
+
describe('86-2: Consultation Protocol', () => {
|
|
57
|
+
describe('AC1: Consultation request format', () => {
|
|
58
|
+
it('should format request with all required fields as markdown', () => {
|
|
59
|
+
const result = formatConsultationRequest(VALID_REQUEST);
|
|
60
|
+
assert.ok(result.includes('**Leader:**'), 'Must include Leader field');
|
|
61
|
+
assert.ok(result.includes('**Partner:**'), 'Must include Partner field');
|
|
62
|
+
assert.ok(result.includes('**Context:**'), 'Must include Context field');
|
|
63
|
+
assert.ok(result.includes('**Question:**'), 'Must include Question field');
|
|
64
|
+
assert.ok(result.includes('**Alternatives Considered:**'), 'Must include Alternatives field');
|
|
65
|
+
assert.ok(result.includes('**Relevant Code/Files:**'), 'Must include Relevant Code field');
|
|
66
|
+
assert.ok(result.includes('**Token Budget:**'), 'Must include Token Budget field');
|
|
67
|
+
});
|
|
68
|
+
it('should include leader character name in Leader field', () => {
|
|
69
|
+
const result = formatConsultationRequest(VALID_REQUEST);
|
|
70
|
+
assert.ok(result.includes('Jack Torrance'), 'Must include character name');
|
|
71
|
+
assert.ok(result.includes('dev'), 'Must include agent name');
|
|
72
|
+
});
|
|
73
|
+
it('should list all alternatives considered', () => {
|
|
74
|
+
const result = formatConsultationRequest(VALID_REQUEST);
|
|
75
|
+
for (const alt of VALID_REQUEST.alternativesConsidered) {
|
|
76
|
+
assert.ok(result.includes(alt), `Must include alternative: ${alt}`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
it('should include token budget as number', () => {
|
|
80
|
+
const result = formatConsultationRequest(VALID_REQUEST);
|
|
81
|
+
assert.ok(result.includes('1000'), 'Must include numeric token budget');
|
|
82
|
+
});
|
|
83
|
+
it('should validate request with all fields present', () => {
|
|
84
|
+
const result = validateConsultationRequest(VALID_REQUEST);
|
|
85
|
+
assert.strictEqual(result.valid, true, 'Valid request should pass validation');
|
|
86
|
+
assert.strictEqual(result.errors.length, 0, 'No errors for valid request');
|
|
87
|
+
});
|
|
88
|
+
it('should reject request with empty question', () => {
|
|
89
|
+
const invalid = {
|
|
90
|
+
...VALID_REQUEST,
|
|
91
|
+
question: '',
|
|
92
|
+
};
|
|
93
|
+
const result = validateConsultationRequest(invalid);
|
|
94
|
+
assert.strictEqual(result.valid, false, 'Empty question should fail');
|
|
95
|
+
assert.ok(result.errors.some(e => e.includes('question')), 'Error must mention question field');
|
|
96
|
+
});
|
|
97
|
+
it('should reject request with empty partner', () => {
|
|
98
|
+
const invalid = {
|
|
99
|
+
...VALID_REQUEST,
|
|
100
|
+
partner: '',
|
|
101
|
+
};
|
|
102
|
+
const result = validateConsultationRequest(invalid);
|
|
103
|
+
assert.strictEqual(result.valid, false, 'Empty partner should fail');
|
|
104
|
+
assert.ok(result.errors.some(e => e.includes('partner')), 'Error must mention partner field');
|
|
105
|
+
});
|
|
106
|
+
it('should reject request with zero token budget', () => {
|
|
107
|
+
const invalid = {
|
|
108
|
+
...VALID_REQUEST,
|
|
109
|
+
tokenBudget: 0,
|
|
110
|
+
};
|
|
111
|
+
const result = validateConsultationRequest(invalid);
|
|
112
|
+
assert.strictEqual(result.valid, false, 'Zero budget should fail');
|
|
113
|
+
assert.ok(result.errors.some(e => e.includes('tokenBudget')), 'Error must mention tokenBudget field');
|
|
114
|
+
});
|
|
115
|
+
it('should reject request with negative token budget', () => {
|
|
116
|
+
const invalid = {
|
|
117
|
+
...VALID_REQUEST,
|
|
118
|
+
tokenBudget: -100,
|
|
119
|
+
};
|
|
120
|
+
const result = validateConsultationRequest(invalid);
|
|
121
|
+
assert.strictEqual(result.valid, false, 'Negative budget should fail');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
// =============================================================================
|
|
125
|
+
// AC2: Consultation response format defined
|
|
126
|
+
// =============================================================================
|
|
127
|
+
describe('AC2: Consultation response format', () => {
|
|
128
|
+
it('should parse well-formed response markdown', () => {
|
|
129
|
+
const result = parseConsultationResponse(VALID_RESPONSE_MARKDOWN);
|
|
130
|
+
assert.ok(result, 'Should parse valid response');
|
|
131
|
+
assert.strictEqual(result.recommendation, VALID_RESPONSE.recommendation);
|
|
132
|
+
assert.strictEqual(result.rationale, VALID_RESPONSE.rationale);
|
|
133
|
+
assert.strictEqual(result.watchOutFor, VALID_RESPONSE.watchOutFor);
|
|
134
|
+
assert.strictEqual(result.confidence, VALID_RESPONSE.confidence);
|
|
135
|
+
assert.strictEqual(result.tokenCount, VALID_RESPONSE.tokenCount);
|
|
136
|
+
});
|
|
137
|
+
it('should return null for completely malformed response', () => {
|
|
138
|
+
const result = parseConsultationResponse('This is just plain text with no structure');
|
|
139
|
+
assert.strictEqual(result, null, 'Should return null for unparseable response');
|
|
140
|
+
});
|
|
141
|
+
it('should handle response with missing confidence gracefully', () => {
|
|
142
|
+
const partial = `**Recommendation:** Do X
|
|
143
|
+
**Rationale:** Because Y
|
|
144
|
+
**Watch-Out-For:** Edge case Z
|
|
145
|
+
**Token Count:** 50`;
|
|
146
|
+
const result = parseConsultationResponse(partial);
|
|
147
|
+
// Should still parse but with undefined/default confidence
|
|
148
|
+
assert.ok(result === null || result.confidence === undefined, 'Missing confidence should result in null or undefined confidence');
|
|
149
|
+
});
|
|
150
|
+
it('should handle response with missing token count', () => {
|
|
151
|
+
const noTokenCount = `**Recommendation:** Do X
|
|
152
|
+
**Rationale:** Because Y
|
|
153
|
+
**Watch-Out-For:** Edge case Z
|
|
154
|
+
**Confidence:** medium`;
|
|
155
|
+
const result = parseConsultationResponse(noTokenCount);
|
|
156
|
+
// Should still parse but tokenCount should be 0 or NaN
|
|
157
|
+
if (result) {
|
|
158
|
+
assert.ok(result.tokenCount === 0 || Number.isNaN(result.tokenCount), 'Missing token count should default to 0 or NaN');
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
it('should validate response with all fields present', () => {
|
|
162
|
+
const result = validateConsultationResponse(VALID_RESPONSE);
|
|
163
|
+
assert.strictEqual(result.valid, true, 'Valid response should pass');
|
|
164
|
+
assert.strictEqual(result.errors.length, 0);
|
|
165
|
+
});
|
|
166
|
+
it('should reject response with empty recommendation', () => {
|
|
167
|
+
const invalid = {
|
|
168
|
+
...VALID_RESPONSE,
|
|
169
|
+
recommendation: '',
|
|
170
|
+
};
|
|
171
|
+
const result = validateConsultationResponse(invalid);
|
|
172
|
+
assert.strictEqual(result.valid, false, 'Empty recommendation should fail');
|
|
173
|
+
assert.ok(result.errors.some(e => e.includes('recommendation')));
|
|
174
|
+
});
|
|
175
|
+
it('should reject response with invalid confidence level', () => {
|
|
176
|
+
const invalid = {
|
|
177
|
+
...VALID_RESPONSE,
|
|
178
|
+
confidence: 'very-high',
|
|
179
|
+
};
|
|
180
|
+
const result = validateConsultationResponse(invalid);
|
|
181
|
+
assert.strictEqual(result.valid, false, 'Invalid confidence should fail');
|
|
182
|
+
assert.ok(result.errors.some(e => e.includes('confidence')));
|
|
183
|
+
});
|
|
184
|
+
it('should parse response with extra whitespace and newlines', () => {
|
|
185
|
+
const messy = `
|
|
186
|
+
**Recommendation:** Use option A
|
|
187
|
+
**Rationale:** It is simpler
|
|
188
|
+
|
|
189
|
+
**Watch-Out-For:** Performance in edge cases
|
|
190
|
+
**Confidence:** low
|
|
191
|
+
**Token Count:** 42
|
|
192
|
+
`;
|
|
193
|
+
const result = parseConsultationResponse(messy);
|
|
194
|
+
assert.ok(result, 'Should handle whitespace gracefully');
|
|
195
|
+
assert.strictEqual(result.recommendation.trim(), 'Use option A');
|
|
196
|
+
assert.strictEqual(result.confidence, 'low');
|
|
197
|
+
assert.strictEqual(result.tokenCount, 42);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
// =============================================================================
|
|
201
|
+
// AC3: Leader spawns partner via Task tool with model: sonnet
|
|
202
|
+
// =============================================================================
|
|
203
|
+
describe('AC3: Spawn partner with sonnet model', () => {
|
|
204
|
+
it('should return model as sonnet (not haiku)', () => {
|
|
205
|
+
const params = buildConsultationSpawnParams(VALID_REQUEST);
|
|
206
|
+
assert.strictEqual(params.model, 'sonnet', 'Consultation uses sonnet per ADR-0012, not haiku (which is for backseat)');
|
|
207
|
+
});
|
|
208
|
+
it('should return correct partner name', () => {
|
|
209
|
+
const params = buildConsultationSpawnParams(VALID_REQUEST);
|
|
210
|
+
assert.strictEqual(params.partner, 'architect');
|
|
211
|
+
});
|
|
212
|
+
it('should use sonnet for different partner agents', () => {
|
|
213
|
+
const teaRequest = {
|
|
214
|
+
...VALID_REQUEST,
|
|
215
|
+
partner: 'tea',
|
|
216
|
+
};
|
|
217
|
+
const params = buildConsultationSpawnParams(teaRequest);
|
|
218
|
+
assert.strictEqual(params.model, 'sonnet', 'All consultation partners use sonnet regardless of agent type');
|
|
219
|
+
assert.strictEqual(params.partner, 'tea');
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
// =============================================================================
|
|
223
|
+
// AC4: Partner prompt includes agent definition, persona, request
|
|
224
|
+
// =============================================================================
|
|
225
|
+
describe('AC4: Partner prompt composition', () => {
|
|
226
|
+
it('should include agent definition in prompt', () => {
|
|
227
|
+
const params = {
|
|
228
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
229
|
+
personaBlock: MOCK_PERSONA,
|
|
230
|
+
formattedRequest: '**Question:** test?',
|
|
231
|
+
tokenBudget: 1000,
|
|
232
|
+
};
|
|
233
|
+
const prompt = buildPartnerPrompt(params);
|
|
234
|
+
assert.ok(prompt.includes(MOCK_AGENT_DEF), 'Prompt must include full agent definition');
|
|
235
|
+
});
|
|
236
|
+
it('should include persona block in prompt', () => {
|
|
237
|
+
const params = {
|
|
238
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
239
|
+
personaBlock: MOCK_PERSONA,
|
|
240
|
+
formattedRequest: '**Question:** test?',
|
|
241
|
+
tokenBudget: 1000,
|
|
242
|
+
};
|
|
243
|
+
const prompt = buildPartnerPrompt(params);
|
|
244
|
+
assert.ok(prompt.includes(MOCK_PERSONA), 'Prompt must include persona block');
|
|
245
|
+
});
|
|
246
|
+
it('should include formatted consultation request in prompt', () => {
|
|
247
|
+
const formattedRequest = '**Question:** Should we use X or Y?';
|
|
248
|
+
const params = {
|
|
249
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
250
|
+
personaBlock: MOCK_PERSONA,
|
|
251
|
+
formattedRequest,
|
|
252
|
+
tokenBudget: 1000,
|
|
253
|
+
};
|
|
254
|
+
const prompt = buildPartnerPrompt(params);
|
|
255
|
+
assert.ok(prompt.includes(formattedRequest), 'Prompt must include formatted request');
|
|
256
|
+
});
|
|
257
|
+
it('should include token budget instruction in prompt', () => {
|
|
258
|
+
const params = {
|
|
259
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
260
|
+
personaBlock: MOCK_PERSONA,
|
|
261
|
+
formattedRequest: '**Question:** test?',
|
|
262
|
+
tokenBudget: 500,
|
|
263
|
+
};
|
|
264
|
+
const prompt = buildPartnerPrompt(params);
|
|
265
|
+
assert.ok(prompt.includes('500'), 'Prompt must include token budget number');
|
|
266
|
+
assert.ok(prompt.toLowerCase().includes('token'), 'Prompt must reference tokens');
|
|
267
|
+
});
|
|
268
|
+
it('should include response format instructions in prompt', () => {
|
|
269
|
+
const params = {
|
|
270
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
271
|
+
personaBlock: MOCK_PERSONA,
|
|
272
|
+
formattedRequest: '**Question:** test?',
|
|
273
|
+
tokenBudget: 1000,
|
|
274
|
+
};
|
|
275
|
+
const prompt = buildPartnerPrompt(params);
|
|
276
|
+
assert.ok(prompt.includes('**Recommendation:**'), 'Prompt must instruct partner on response format');
|
|
277
|
+
assert.ok(prompt.includes('**Confidence:**'), 'Prompt must include confidence field in instructions');
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
// =============================================================================
|
|
281
|
+
// AC5: Response parsed and available to leader
|
|
282
|
+
// =============================================================================
|
|
283
|
+
describe('AC5: Full consultation execution with response', () => {
|
|
284
|
+
it('should execute consultation and return parsed response', async () => {
|
|
285
|
+
const adapter = {
|
|
286
|
+
spawn: async () => ({ responseText: VALID_RESPONSE_MARKDOWN }),
|
|
287
|
+
};
|
|
288
|
+
const result = await executeConsultation({
|
|
289
|
+
request: VALID_REQUEST,
|
|
290
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
291
|
+
personaBlock: MOCK_PERSONA,
|
|
292
|
+
adapter,
|
|
293
|
+
});
|
|
294
|
+
assert.strictEqual(result.success, true, 'Consultation should succeed');
|
|
295
|
+
assert.ok(result.data, 'Should have parsed data');
|
|
296
|
+
assert.strictEqual(result.data.response.recommendation, VALID_RESPONSE.recommendation);
|
|
297
|
+
assert.strictEqual(result.data.response.confidence, 'high');
|
|
298
|
+
});
|
|
299
|
+
it('should pass model: sonnet to adapter', async () => {
|
|
300
|
+
let spawnedModel = '';
|
|
301
|
+
const adapter = {
|
|
302
|
+
spawn: async (params) => {
|
|
303
|
+
spawnedModel = params.model;
|
|
304
|
+
return { responseText: VALID_RESPONSE_MARKDOWN };
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
await executeConsultation({
|
|
308
|
+
request: VALID_REQUEST,
|
|
309
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
310
|
+
personaBlock: MOCK_PERSONA,
|
|
311
|
+
adapter,
|
|
312
|
+
});
|
|
313
|
+
assert.strictEqual(spawnedModel, 'sonnet', 'Must spawn partner with sonnet model');
|
|
314
|
+
});
|
|
315
|
+
it('should pass complete prompt to adapter', async () => {
|
|
316
|
+
let receivedPrompt = '';
|
|
317
|
+
const adapter = {
|
|
318
|
+
spawn: async (params) => {
|
|
319
|
+
receivedPrompt = params.prompt;
|
|
320
|
+
return { responseText: VALID_RESPONSE_MARKDOWN };
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
await executeConsultation({
|
|
324
|
+
request: VALID_REQUEST,
|
|
325
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
326
|
+
personaBlock: MOCK_PERSONA,
|
|
327
|
+
adapter,
|
|
328
|
+
});
|
|
329
|
+
assert.ok(receivedPrompt.includes(MOCK_AGENT_DEF), 'Prompt must include agent def');
|
|
330
|
+
assert.ok(receivedPrompt.includes(MOCK_PERSONA), 'Prompt must include persona');
|
|
331
|
+
assert.ok(receivedPrompt.includes(VALID_REQUEST.question), 'Prompt must include question');
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
// =============================================================================
|
|
335
|
+
// AC6: Graceful degradation
|
|
336
|
+
// =============================================================================
|
|
337
|
+
describe('AC6: Graceful degradation on partner failure', () => {
|
|
338
|
+
it('should return degraded result when partner spawn fails', async () => {
|
|
339
|
+
const adapter = {
|
|
340
|
+
spawn: async () => { throw new Error('Connection refused'); },
|
|
341
|
+
};
|
|
342
|
+
const result = await executeConsultation({
|
|
343
|
+
request: VALID_REQUEST,
|
|
344
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
345
|
+
personaBlock: MOCK_PERSONA,
|
|
346
|
+
adapter,
|
|
347
|
+
});
|
|
348
|
+
assert.strictEqual(result.success, false, 'Should fail gracefully');
|
|
349
|
+
assert.strictEqual(result.degraded, true, 'Must flag as degraded');
|
|
350
|
+
assert.ok(result.error, 'Must include error message');
|
|
351
|
+
});
|
|
352
|
+
it('should not throw when partner spawn fails', async () => {
|
|
353
|
+
const adapter = {
|
|
354
|
+
spawn: async () => { throw new Error('Timeout'); },
|
|
355
|
+
};
|
|
356
|
+
await assert.doesNotReject(() => executeConsultation({
|
|
357
|
+
request: VALID_REQUEST,
|
|
358
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
359
|
+
personaBlock: MOCK_PERSONA,
|
|
360
|
+
adapter,
|
|
361
|
+
}), 'Must not throw — leader must continue working');
|
|
362
|
+
});
|
|
363
|
+
it('should return degraded result when response is unparseable', async () => {
|
|
364
|
+
const adapter = {
|
|
365
|
+
spawn: async () => ({ responseText: 'completely garbled nonsense' }),
|
|
366
|
+
};
|
|
367
|
+
const result = await executeConsultation({
|
|
368
|
+
request: VALID_REQUEST,
|
|
369
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
370
|
+
personaBlock: MOCK_PERSONA,
|
|
371
|
+
adapter,
|
|
372
|
+
});
|
|
373
|
+
assert.strictEqual(result.success, false, 'Unparseable response should fail');
|
|
374
|
+
assert.strictEqual(result.degraded, true, 'Must flag as degraded');
|
|
375
|
+
});
|
|
376
|
+
it('should include error context in degraded result', async () => {
|
|
377
|
+
const adapter = {
|
|
378
|
+
spawn: async () => { throw new Error('Model rate limited'); },
|
|
379
|
+
};
|
|
380
|
+
const result = await executeConsultation({
|
|
381
|
+
request: VALID_REQUEST,
|
|
382
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
383
|
+
personaBlock: MOCK_PERSONA,
|
|
384
|
+
adapter,
|
|
385
|
+
});
|
|
386
|
+
assert.ok(result.error?.includes('rate limited'), 'Error should preserve original failure message');
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
// =============================================================================
|
|
390
|
+
// AC7: Token budget enforced via prompt instruction
|
|
391
|
+
// =============================================================================
|
|
392
|
+
describe('AC7: Token budget enforcement', () => {
|
|
393
|
+
it('should flag response as over-budget when tokenCount exceeds budget', async () => {
|
|
394
|
+
const overBudgetResponse = `**Recommendation:** Do X
|
|
395
|
+
**Rationale:** Because Y
|
|
396
|
+
**Watch-Out-For:** Edge case Z
|
|
397
|
+
**Confidence:** high
|
|
398
|
+
**Token Count:** 2000`;
|
|
399
|
+
const adapter = {
|
|
400
|
+
spawn: async () => ({ responseText: overBudgetResponse }),
|
|
401
|
+
};
|
|
402
|
+
const requestWithSmallBudget = {
|
|
403
|
+
...VALID_REQUEST,
|
|
404
|
+
tokenBudget: 500,
|
|
405
|
+
};
|
|
406
|
+
const result = await executeConsultation({
|
|
407
|
+
request: requestWithSmallBudget,
|
|
408
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
409
|
+
personaBlock: MOCK_PERSONA,
|
|
410
|
+
adapter,
|
|
411
|
+
});
|
|
412
|
+
assert.strictEqual(result.success, true, 'Over-budget should still succeed');
|
|
413
|
+
assert.strictEqual(result.data.overBudget, true, 'Must flag over-budget response');
|
|
414
|
+
});
|
|
415
|
+
it('should not flag response as over-budget when within limit', async () => {
|
|
416
|
+
const adapter = {
|
|
417
|
+
spawn: async () => ({ responseText: VALID_RESPONSE_MARKDOWN }),
|
|
418
|
+
};
|
|
419
|
+
const result = await executeConsultation({
|
|
420
|
+
request: VALID_REQUEST, // budget is 1000, response is 85
|
|
421
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
422
|
+
personaBlock: MOCK_PERSONA,
|
|
423
|
+
adapter,
|
|
424
|
+
});
|
|
425
|
+
assert.strictEqual(result.success, true);
|
|
426
|
+
assert.strictEqual(result.data.overBudget, false, 'Within-budget response should not be flagged');
|
|
427
|
+
});
|
|
428
|
+
it('should include token budget in partner prompt as hard instruction', () => {
|
|
429
|
+
const params = {
|
|
430
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
431
|
+
personaBlock: MOCK_PERSONA,
|
|
432
|
+
formattedRequest: '**Question:** test?',
|
|
433
|
+
tokenBudget: 750,
|
|
434
|
+
};
|
|
435
|
+
const prompt = buildPartnerPrompt(params);
|
|
436
|
+
assert.ok(prompt.includes('750'), 'Must include specific budget number');
|
|
437
|
+
assert.ok(prompt.toLowerCase().includes('must not exceed') ||
|
|
438
|
+
prompt.toLowerCase().includes('do not exceed') ||
|
|
439
|
+
prompt.toLowerCase().includes('limit'), 'Must include enforcement language');
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
// =============================================================================
|
|
443
|
+
// Result format compliance (framework pattern)
|
|
444
|
+
// =============================================================================
|
|
445
|
+
describe('Result format compliance', () => {
|
|
446
|
+
it('should return {success, data?, error?} from executeConsultation on success', async () => {
|
|
447
|
+
const adapter = {
|
|
448
|
+
spawn: async () => ({ responseText: VALID_RESPONSE_MARKDOWN }),
|
|
449
|
+
};
|
|
450
|
+
const result = await executeConsultation({
|
|
451
|
+
request: VALID_REQUEST,
|
|
452
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
453
|
+
personaBlock: MOCK_PERSONA,
|
|
454
|
+
adapter,
|
|
455
|
+
});
|
|
456
|
+
assert.ok('success' in result, 'Must have success field');
|
|
457
|
+
assert.ok(typeof result.success === 'boolean', 'success must be boolean');
|
|
458
|
+
});
|
|
459
|
+
it('should return {success, data?, error?, degraded?} from executeConsultation on failure', async () => {
|
|
460
|
+
const adapter = {
|
|
461
|
+
spawn: async () => { throw new Error('fail'); },
|
|
462
|
+
};
|
|
463
|
+
const result = await executeConsultation({
|
|
464
|
+
request: VALID_REQUEST,
|
|
465
|
+
agentDefinition: MOCK_AGENT_DEF,
|
|
466
|
+
personaBlock: MOCK_PERSONA,
|
|
467
|
+
adapter,
|
|
468
|
+
});
|
|
469
|
+
assert.ok('success' in result, 'Must have success field');
|
|
470
|
+
assert.ok('degraded' in result, 'Must have degraded field on failure');
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
//# sourceMappingURL=consultation-protocol.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consultation-protocol.test.js","sourceRoot":"","sources":["../../src/consultation/consultation-protocol.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dialogue File Management for Story 86-3
|
|
3
|
+
*
|
|
4
|
+
* Persistence layer for tandem agent consultation exchanges.
|
|
5
|
+
* Creates, appends, and archives dialogue files following the format
|
|
6
|
+
* defined in ADR-0012 (lines 156-195).
|
|
7
|
+
*
|
|
8
|
+
* All functions are pure or use simple file I/O — no external dependencies.
|
|
9
|
+
*/
|
|
10
|
+
export type Outcome = 'applied' | 'deferred' | 'rejected';
|
|
11
|
+
export interface DialogueHeader {
|
|
12
|
+
storyId: string;
|
|
13
|
+
workflow: string;
|
|
14
|
+
leader: string;
|
|
15
|
+
leaderCharacter?: string;
|
|
16
|
+
partner: string;
|
|
17
|
+
partnerCharacter?: string;
|
|
18
|
+
startedAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DialogueExchange {
|
|
21
|
+
number: number;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
leader: string;
|
|
24
|
+
partner: string;
|
|
25
|
+
question: string;
|
|
26
|
+
recommendation: string;
|
|
27
|
+
confidence: string;
|
|
28
|
+
outcome?: Outcome;
|
|
29
|
+
outcomeNote?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface DialogueResult {
|
|
32
|
+
success: boolean;
|
|
33
|
+
data?: Record<string, unknown>;
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
interface ArchiveParams {
|
|
37
|
+
dialoguePath: string;
|
|
38
|
+
archiveDir: string;
|
|
39
|
+
jiraKey?: string;
|
|
40
|
+
storyId?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create initial dialogue file content with header and empty summary.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createDialogueContent(header: DialogueHeader): string;
|
|
46
|
+
/**
|
|
47
|
+
* Format a single exchange as markdown block.
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatExchange(exchange: DialogueExchange): string;
|
|
50
|
+
/**
|
|
51
|
+
* Parse exchanges from dialogue file content.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseDialogueExchanges(content: string): DialogueExchange[];
|
|
54
|
+
/**
|
|
55
|
+
* Generate summary markdown section from exchanges.
|
|
56
|
+
*/
|
|
57
|
+
export declare function generateSummary(exchanges: DialogueExchange[], startedAt: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* Append an exchange to a dialogue file. Creates the file if missing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function appendExchangeToFile(dialoguePath: string, exchange: DialogueExchange, header?: DialogueHeader): Promise<DialogueResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Update the outcome of a specific exchange in the dialogue file.
|
|
64
|
+
*/
|
|
65
|
+
export declare function updateOutcomeInFile(dialoguePath: string, exchangeNum: number, outcome: Outcome, note?: string): Promise<DialogueResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Regenerate the summary section in an existing dialogue file.
|
|
68
|
+
*/
|
|
69
|
+
export declare function refreshSummary(dialoguePath: string): Promise<DialogueResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Copy dialogue file to archive directory.
|
|
72
|
+
*/
|
|
73
|
+
export declare function archiveDialogue(params: ArchiveParams): Promise<DialogueResult>;
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=dialogue-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialogue-manager.d.ts","sourceRoot":"","sources":["../../src/consultation/dialogue-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiBD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAqBpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAoBjE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAuG1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA0BxF;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CA6BzB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,cAAc,CAAC,CAsCzB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA6BlF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAoBpF"}
|