taphound 0.2.0-dev.1 → 0.2.0-dev.12
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 +49 -149
- package/README.zh-CN.md +47 -147
- package/assets/skills/taphound-case-suite/SKILL.md +363 -0
- package/assets/skills/taphound-case-suite/schemas/base-flow-record.schema.json +22 -0
- package/assets/skills/taphound-case-suite/schemas/case-catalog.schema.json +26 -0
- package/assets/skills/taphound-case-suite/schemas/case-ledger.schema.json +158 -0
- package/assets/skills/taphound-case-suite/schemas/suite-input.schema.json +41 -0
- package/assets/skills/taphound-case-suite/schemas/transition.schema.json +61 -0
- package/assets/skills/taphound-case-suite/scripts/ledger.mjs +1207 -0
- package/assets/skills/taphound-case-suite/templates/base-flow-record.example.json +20 -0
- package/assets/skills/taphound-case-suite/templates/suite-input.example.json +27 -0
- package/assets/skills/taphound-case-suite/templates/transition.example.json +8 -0
- package/assets/skills/taphound-flash/SKILL.md +115 -0
- package/assets/skills/taphound-flash/scripts/flash.mjs +585 -0
- package/assets/skills/taphound-flash/templates/flash-plan.example.json +15 -0
- package/assets/skills/taphound-journey-brief-author/CONTEXT-GUIDE.md +471 -0
- package/assets/skills/taphound-journey-brief-author/SKILL.md +494 -0
- package/assets/skills/taphound-journey-brief-author/prompts/brief-author-role.md +96 -0
- package/assets/skills/taphound-journey-brief-author/prompts/brief-author-role.zh-CN.md +80 -0
- package/assets/skills/taphound-journey-brief-author/prompts/context-analyze-project.md +309 -0
- package/assets/skills/taphound-journey-brief-author/schemas/context-refresh-result.json +123 -0
- package/assets/skills/taphound-journey-brief-author/schemas/project-context-module.json +192 -0
- package/assets/skills/taphound-journey-brief-author/schemas/project-context.json +152 -0
- package/assets/skills/taphound-journey-brief-author/templates/project-context-module.example.json +58 -0
- package/assets/skills/taphound-journey-brief-author/templates/project-context.example.json +51 -0
- package/assets/skills/taphound-journey-brief-author/templates/taphound-journey-brief.template.md +63 -0
- package/assets/skills/taphound-journey-generator/SKILL.md +507 -0
- package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/prompts/check-completion.md +3 -0
- package/assets/skills/taphound-journey-generator/prompts/consume-journey-brief.md +52 -0
- package/assets/skills/taphound-journey-generator/prompts/generate-step.md +211 -0
- package/assets/skills/taphound-journey-generator/prompts/select-flow.md +91 -0
- package/assets/skills/taphound-journey-generator/references/bridge.md +35 -0
- package/assets/skills/taphound-journey-generator/references/mid-session.md +44 -0
- package/assets/skills/taphound-journey-generator/schemas/external-flow.json +37 -0
- package/assets/skills/taphound-journey-generator/schemas/flow.json +28 -0
- package/assets/skills/taphound-journey-generator/schemas/journey-source.json +25 -0
- package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/schemas/observe-output.json +13 -4
- package/assets/skills/{taphound-ai-journey → taphound-journey-generator}/schemas/proposed-step-envelope.json +127 -5
- package/assets/skills/taphound-journey-generator/scripts/envelope.mjs +578 -0
- package/assets/skills/taphound-journey-generator/templates/external-flow.example.json +22 -0
- package/assets/skills/taphound-journey-generator/templates/flow.example.json +22 -0
- package/assets/skills/taphound-journey-generator/templates/journey-source.example.json +17 -0
- package/assets/skills/taphound-journey-generator/templates/taphound-journey-brief.example.md +70 -0
- package/assets/skills/taphound-verify-change/SKILL.md +91 -0
- package/assets/skills/taphound-verify-change/references/accept.md +38 -0
- package/assets/skills/taphound-verify-change/references/preserve.md +357 -0
- package/assets/skills/taphound-verify-change/schemas/workflow-manifest.schema.json +295 -0
- package/assets/skills/taphound-verify-change/scripts/handoff.mjs +482 -0
- package/assets/skills/taphound-verify-change/scripts/ui-refactor.mjs +505 -0
- package/dist/adapters/adb/adb-adapter.d.ts +16 -2
- package/dist/adapters/adb/adb-adapter.js +199 -0
- package/dist/adapters/adb/system-uiautomator-snapshot-provider.d.ts +13 -0
- package/dist/adapters/adb/system-uiautomator-snapshot-provider.js +122 -0
- package/dist/adapters/adb/ui-automator-parser.d.ts +3 -0
- package/dist/adapters/adb/ui-automator-parser.js +160 -0
- package/dist/adapters/adb/window-topology-parser.d.ts +2 -0
- package/dist/adapters/adb/window-topology-parser.js +101 -0
- package/dist/adapters/android-cli/android-cli-adapter.d.ts +16 -8
- package/dist/adapters/android-cli/android-cli-adapter.js +137 -15
- package/dist/adapters/android-cli/android-cli-snapshot-provider.d.ts +9 -0
- package/dist/adapters/android-cli/android-cli-snapshot-provider.js +99 -0
- package/dist/adapters/android-cli/layout-parser.js +12 -8
- package/dist/adapters/appium/appium-doctor.d.ts +7 -0
- package/dist/adapters/appium/appium-doctor.js +128 -0
- package/dist/adapters/appium/appium-ui-snapshot-provider.d.ts +42 -0
- package/dist/adapters/appium/appium-ui-snapshot-provider.js +309 -0
- package/dist/adapters/camera/camera-probe-adapter.d.ts +18 -0
- package/dist/adapters/camera/camera-probe-adapter.js +286 -0
- package/dist/adapters/filesystem/artifact-store.js +40 -1
- package/dist/adapters/filesystem/context-document-writer.d.ts +15 -0
- package/dist/adapters/filesystem/context-document-writer.js +112 -0
- package/dist/adapters/filesystem/diagnostics-journal.d.ts +17 -0
- package/dist/adapters/filesystem/diagnostics-journal.js +130 -0
- package/dist/adapters/filesystem/external-flow-registry.d.ts +17 -0
- package/dist/adapters/filesystem/external-flow-registry.js +325 -0
- package/dist/adapters/filesystem/generation-session-store.d.ts +17 -11
- package/dist/adapters/filesystem/generation-session-store.js +281 -855
- package/dist/adapters/filesystem/generation-store/session-lock.d.ts +29 -0
- package/dist/adapters/filesystem/generation-store/session-lock.js +202 -0
- package/dist/adapters/filesystem/generation-store/session-transitions.d.ts +24 -0
- package/dist/adapters/filesystem/generation-store/session-transitions.js +340 -0
- package/dist/adapters/filesystem/generation-store/store-files.d.ts +50 -0
- package/dist/adapters/filesystem/generation-store/store-files.js +363 -0
- package/dist/adapters/filesystem/journey-composition-store.d.ts +23 -0
- package/dist/adapters/filesystem/journey-composition-store.js +151 -0
- package/dist/adapters/filesystem/knowledge-registry.d.ts +12 -0
- package/dist/adapters/filesystem/knowledge-registry.js +223 -0
- package/dist/adapters/filesystem/project-bound-file.js +3 -5
- package/dist/adapters/filesystem/project-file-inspector.d.ts +2 -0
- package/dist/adapters/filesystem/project-file-inspector.js +57 -28
- package/dist/adapters/filesystem/project-identity-inspector.d.ts +7 -0
- package/dist/adapters/filesystem/project-identity-inspector.js +215 -0
- package/dist/adapters/filesystem/project-inventory-inspector.d.ts +8 -0
- package/dist/adapters/filesystem/project-inventory-inspector.js +93 -0
- package/dist/adapters/filesystem/project-module-discoverer.d.ts +6 -0
- package/dist/adapters/filesystem/project-module-discoverer.js +158 -0
- package/dist/adapters/filesystem/skill-installer.d.ts +7 -2
- package/dist/adapters/filesystem/skill-installer.js +40 -11
- package/dist/adapters/filesystem/workspace-layout.d.ts +7 -0
- package/dist/adapters/filesystem/workspace-layout.js +57 -0
- package/dist/adapters/git/node-git-diff.d.ts +17 -0
- package/dist/adapters/git/node-git-diff.js +114 -0
- package/dist/adapters/process/node-detached-process-launcher.d.ts +6 -0
- package/dist/adapters/process/node-detached-process-launcher.js +96 -0
- package/dist/adapters/process/node-process-runner.js +11 -2
- package/dist/adapters/prompt/inquirer-align-prompt.d.ts +27 -0
- package/dist/adapters/prompt/inquirer-align-prompt.js +65 -0
- package/dist/adapters/prompt/inquirer-generation-prompt.js +3 -0
- package/dist/adapters/prompt/inquirer-recorder-prompt.d.ts +9 -1
- package/dist/adapters/prompt/inquirer-recorder-prompt.js +63 -0
- package/dist/adapters/runtime/adb-runtime-backend.d.ts +67 -0
- package/dist/adapters/runtime/adb-runtime-backend.js +206 -0
- package/dist/adapters/runtime/fake-runtime-backend.d.ts +87 -0
- package/dist/adapters/runtime/fake-runtime-backend.js +240 -0
- package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.d.ts +45 -0
- package/dist/adapters/runtime/mobile-mcp/mcp-tool-client.js +153 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.d.ts +23 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-errors.js +39 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.d.ts +20 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-responses.js +180 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.d.ts +78 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-runtime-backend.js +379 -0
- package/dist/adapters/runtime/mobile-mcp/mobile-mcp-tools.d.ts +46 -0
- package/dist/adapters/runtime/session-adb-view.d.ts +53 -0
- package/dist/adapters/runtime/session-adb-view.js +193 -0
- package/dist/adapters/runtime/session-backed-ports.d.ts +21 -0
- package/dist/adapters/runtime/session-backed-ports.js +43 -0
- package/dist/adapters/runtime/shared-session-runtime-backend.d.ts +12 -0
- package/dist/adapters/runtime/shared-session-runtime-backend.js +64 -0
- package/dist/adapters/ui/auto-ui-snapshot-provider.d.ts +8 -0
- package/dist/adapters/ui/auto-ui-snapshot-provider.js +48 -0
- package/dist/adapters/ui/device-layout-temp.d.ts +6 -0
- package/dist/adapters/ui/device-layout-temp.js +18 -0
- package/dist/adapters/ui/device-ui-environment.d.ts +13 -0
- package/dist/adapters/ui/device-ui-environment.js +81 -0
- package/dist/adapters/ui/layout-normalization.d.ts +9 -0
- package/dist/adapters/ui/layout-normalization.js +44 -0
- package/dist/adapters/ui/ui-snapshot-error.d.ts +11 -0
- package/dist/adapters/ui/ui-snapshot-error.js +12 -0
- package/dist/adapters/ui/ui-snapshot-support.d.ts +15 -0
- package/dist/adapters/ui/ui-snapshot-support.js +12 -0
- package/dist/application/align/align-service.d.ts +42 -0
- package/dist/application/align/align-service.js +106 -0
- package/dist/application/assertion/expectation-evaluator.d.ts +18 -5
- package/dist/application/assertion/expectation-evaluator.js +156 -18
- package/dist/application/assertion/guarded-expectation.d.ts +45 -0
- package/dist/application/assertion/guarded-expectation.js +74 -0
- package/dist/application/checkpoint/baseline-capturer.d.ts +26 -0
- package/dist/application/checkpoint/baseline-capturer.js +163 -0
- package/dist/application/checkpoint/baseline-error.d.ts +5 -0
- package/dist/application/checkpoint/baseline-error.js +8 -0
- package/dist/application/checkpoint/baseline-service.d.ts +31 -0
- package/dist/application/checkpoint/baseline-service.js +147 -0
- package/dist/application/checkpoint/checkpoint-evaluator.d.ts +35 -0
- package/dist/application/checkpoint/checkpoint-evaluator.js +415 -0
- package/dist/application/checkpoint/regression-comparator.d.ts +18 -0
- package/dist/application/checkpoint/regression-comparator.js +192 -0
- package/dist/application/collector/logcat-collector.d.ts +22 -1
- package/dist/application/collector/logcat-collector.js +103 -15
- package/dist/application/collector/logcat-event.d.ts +8 -0
- package/dist/application/collector/logcat-event.js +79 -0
- package/dist/application/collector/logcat-stop.d.ts +2 -0
- package/dist/application/collector/logcat-stop.js +11 -0
- package/dist/application/context/context-generator.d.ts +45 -0
- package/dist/application/context/context-generator.js +228 -0
- package/dist/application/context/context-loader.d.ts +40 -0
- package/dist/application/context/context-loader.js +223 -0
- package/dist/application/context/context-refresher.d.ts +59 -0
- package/dist/application/context/context-refresher.js +349 -0
- package/dist/application/context/context-rehasher.d.ts +36 -0
- package/dist/application/context/context-rehasher.js +110 -0
- package/dist/application/context/context-validator.d.ts +23 -1
- package/dist/application/context/context-validator.js +116 -9
- package/dist/application/context/evidence-hash.d.ts +1 -0
- package/dist/application/context/evidence-hash.js +125 -0
- package/dist/application/context/evidence-match.d.ts +9 -0
- package/dist/application/context/evidence-match.js +8 -0
- package/dist/application/context/shard-identity.d.ts +2 -0
- package/dist/application/context/shard-identity.js +7 -0
- package/dist/application/contract/contract-loader.d.ts +25 -0
- package/dist/application/contract/contract-loader.js +68 -0
- package/dist/application/contract/contract-review.d.ts +25 -0
- package/dist/application/contract/contract-review.js +51 -0
- package/dist/application/contract/contract-verifier.d.ts +53 -0
- package/dist/application/contract/contract-verifier.js +645 -0
- package/dist/application/devices/resolve-device-assignments.d.ts +21 -0
- package/dist/application/devices/resolve-device-assignments.js +60 -0
- package/dist/application/diagnosis/failure-classifier.d.ts +23 -0
- package/dist/application/diagnosis/failure-classifier.js +179 -0
- package/dist/application/diagnostics/diagnostics-exporter.d.ts +29 -0
- package/dist/application/diagnostics/diagnostics-exporter.js +283 -0
- package/dist/application/diagnostics/ui-capture-telemetry.d.ts +16 -0
- package/dist/application/diagnostics/ui-capture-telemetry.js +81 -0
- package/dist/application/doctor/doctor-service.d.ts +36 -3
- package/dist/application/doctor/doctor-service.js +255 -25
- package/dist/application/generation/generation-app-preparer.d.ts +20 -0
- package/dist/application/generation/generation-app-preparer.js +28 -0
- package/dist/application/generation/generation-config-service.d.ts +21 -0
- package/dist/application/generation/generation-config-service.js +53 -0
- package/dist/application/generation/generation-confirmation-service.d.ts +14 -3
- package/dist/application/generation/generation-confirmation-service.js +109 -24
- package/dist/application/generation/generation-context-snapshot.d.ts +6 -0
- package/dist/application/generation/generation-context-snapshot.js +29 -0
- package/dist/application/generation/generation-finalizer.d.ts +15 -9
- package/dist/application/generation/generation-finalizer.js +167 -70
- package/dist/application/generation/generation-publisher.js +12 -8
- package/dist/application/generation/generation-recovery-service.d.ts +35 -0
- package/dist/application/generation/generation-recovery-service.js +144 -0
- package/dist/application/generation/generation-reopen-service.d.ts +15 -0
- package/dist/application/generation/generation-reopen-service.js +37 -0
- package/dist/application/generation/generation-replace-service.d.ts +32 -0
- package/dist/application/generation/generation-replace-service.js +116 -0
- package/dist/application/generation/generation-starter.d.ts +44 -4
- package/dist/application/generation/generation-starter.js +175 -8
- package/dist/application/generation/generation-step-executor.d.ts +67 -5
- package/dist/application/generation/generation-step-executor.js +471 -108
- package/dist/application/generation/proposed-step-validator.js +96 -30
- package/dist/application/generation/replay-policy-loader.d.ts +16 -0
- package/dist/application/generation/replay-policy-loader.js +29 -0
- package/dist/application/generation/risk-evaluator.d.ts +4 -1
- package/dist/application/generation/risk-evaluator.js +118 -3
- package/dist/application/generation/runtime-observer.d.ts +39 -7
- package/dist/application/generation/runtime-observer.js +193 -24
- package/dist/application/impact/impact-resolver.d.ts +32 -0
- package/dist/application/impact/impact-resolver.js +160 -0
- package/dist/application/init/init-service.js +26 -13
- package/dist/application/interaction/action-executor.d.ts +3 -2
- package/dist/application/interaction/action-executor.js +11 -1
- package/dist/application/interaction/action-target.d.ts +17 -0
- package/dist/application/interaction/action-target.js +40 -0
- package/dist/application/interaction/external-step-runner.d.ts +153 -0
- package/dist/application/interaction/external-step-runner.js +332 -0
- package/dist/application/interaction/fallback-resolver.d.ts +6 -3
- package/dist/application/interaction/fallback-resolver.js +7 -5
- package/dist/application/interaction/scroll-to-executor.d.ts +17 -3
- package/dist/application/interaction/scroll-to-executor.js +118 -36
- package/dist/application/journey/external-flow-resolver.d.ts +25 -0
- package/dist/application/journey/external-flow-resolver.js +22 -0
- package/dist/application/journey/journey-check-service.d.ts +54 -0
- package/dist/application/journey/journey-check-service.js +207 -0
- package/dist/application/journey/journey-promoter.d.ts +26 -0
- package/dist/application/journey/journey-promoter.js +123 -0
- package/dist/application/journey/journey-resolver.d.ts +42 -0
- package/dist/application/journey/journey-resolver.js +239 -0
- package/dist/application/journey/journey-retirer.d.ts +25 -0
- package/dist/application/journey/journey-retirer.js +87 -0
- package/dist/application/knowledge/anchor-resolver.d.ts +36 -0
- package/dist/application/knowledge/anchor-resolver.js +110 -0
- package/dist/application/knowledge/knowledge-loader.d.ts +16 -0
- package/dist/application/knowledge/knowledge-loader.js +36 -0
- package/dist/application/locator/layout-failure-summary.d.ts +2 -0
- package/dist/application/locator/layout-failure-summary.js +67 -0
- package/dist/application/locator/layout-traversal.d.ts +11 -0
- package/dist/application/locator/layout-traversal.js +18 -0
- package/dist/application/locator/locator-resolver.d.ts +13 -1
- package/dist/application/locator/locator-resolver.js +182 -18
- package/dist/application/observe/observe-service.d.ts +20 -0
- package/dist/application/observe/observe-service.js +91 -0
- package/dist/application/project/project-describer.d.ts +14 -6
- package/dist/application/project/project-describer.js +38 -5
- package/dist/application/recognition/screen-detector.d.ts +28 -0
- package/dist/application/recognition/screen-detector.js +111 -0
- package/dist/application/recorder/locator-selector.js +151 -17
- package/dist/application/recorder/recorder-service.d.ts +16 -4
- package/dist/application/recorder/recorder-service.js +420 -128
- package/dist/application/report/report-writer.d.ts +5 -0
- package/dist/application/report/report-writer.js +17 -1
- package/dist/application/runtime/cold-launch.d.ts +28 -0
- package/dist/application/runtime/cold-launch.js +59 -0
- package/dist/application/runtime/step-runner.d.ts +49 -4
- package/dist/application/runtime/step-runner.js +721 -130
- package/dist/application/runtime/verify-runtime.d.ts +57 -7
- package/dist/application/runtime/verify-runtime.js +577 -175
- package/dist/application/ui/cached-ui-snapshot-provider.d.ts +45 -0
- package/dist/application/ui/cached-ui-snapshot-provider.js +111 -0
- package/dist/application/ui/observed-ui-snapshot-provider.d.ts +15 -0
- package/dist/application/ui/observed-ui-snapshot-provider.js +66 -0
- package/dist/application/ui/ui-snapshot-lifecycle.d.ts +2 -0
- package/dist/application/ui/ui-snapshot-lifecycle.js +8 -0
- package/dist/application/ui/ui-stability-probe.d.ts +9 -0
- package/dist/application/ui/ui-stability-probe.js +24 -0
- package/dist/application/wait/idle-advice.d.ts +6 -0
- package/dist/application/wait/idle-advice.js +27 -0
- package/dist/application/wait/idle-profiles.d.ts +15 -0
- package/dist/application/wait/idle-profiles.js +75 -0
- package/dist/application/wait/idle-waiter.d.ts +28 -4
- package/dist/application/wait/idle-waiter.js +201 -15
- package/dist/cli/commands/align.d.ts +3 -0
- package/dist/cli/commands/align.js +124 -0
- package/dist/cli/commands/baseline.d.ts +3 -0
- package/dist/cli/commands/baseline.js +130 -0
- package/dist/cli/commands/context.js +300 -27
- package/dist/cli/commands/contract.d.ts +3 -0
- package/dist/cli/commands/contract.js +120 -0
- package/dist/cli/commands/diagnose.d.ts +3 -0
- package/dist/cli/commands/diagnose.js +84 -0
- package/dist/cli/commands/doctor.js +16 -9
- package/dist/cli/commands/failure.d.ts +3 -0
- package/dist/cli/commands/failure.js +63 -0
- package/dist/cli/commands/generation/lifecycle-commands.d.ts +5 -0
- package/dist/cli/commands/generation/lifecycle-commands.js +211 -0
- package/dist/cli/commands/generation/session-commands.d.ts +11 -0
- package/dist/cli/commands/generation/session-commands.js +472 -0
- package/dist/cli/commands/generation/shared.d.ts +1414 -0
- package/dist/cli/commands/generation/shared.js +291 -0
- package/dist/cli/commands/generation/step-commands.d.ts +8 -0
- package/dist/cli/commands/generation/step-commands.js +315 -0
- package/dist/cli/commands/generation.js +10 -507
- package/dist/cli/commands/impact.d.ts +3 -0
- package/dist/cli/commands/impact.js +87 -0
- package/dist/cli/commands/init.js +13 -6
- package/dist/cli/commands/journey.d.ts +3 -0
- package/dist/cli/commands/journey.js +382 -0
- package/dist/cli/commands/knowledge.d.ts +3 -0
- package/dist/cli/commands/knowledge.js +93 -0
- package/dist/cli/commands/observe.d.ts +3 -0
- package/dist/cli/commands/observe.js +127 -0
- package/dist/cli/commands/project.js +2 -1
- package/dist/cli/commands/record.js +18 -5
- package/dist/cli/commands/verify.js +326 -64
- package/dist/cli/dependencies.d.ts +136 -1
- package/dist/cli/dependencies.js +504 -52
- package/dist/cli/diagnostics-recorder.d.ts +31 -0
- package/dist/cli/diagnostics-recorder.js +82 -0
- package/dist/cli/diff-verification.d.ts +41 -0
- package/dist/cli/diff-verification.js +192 -0
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.js +107 -2
- package/dist/cli/output.d.ts +5 -3
- package/dist/cli/output.js +12 -0
- package/dist/cli/program.js +21 -1
- package/dist/cli/project-root.d.ts +1 -0
- package/dist/cli/project-root.js +6 -0
- package/dist/cli/runtime-selection.d.ts +22 -0
- package/dist/cli/runtime-selection.js +92 -0
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.js +14 -0
- package/dist/cli/workspace-guard.d.ts +2 -0
- package/dist/cli/workspace-guard.js +3 -0
- package/dist/domain/binding-reference.d.ts +4 -0
- package/dist/domain/binding-reference.js +23 -0
- package/dist/domain/checkpoint.d.ts +404 -0
- package/dist/domain/checkpoint.js +297 -0
- package/dist/domain/config.d.ts +107 -1
- package/dist/domain/config.js +52 -6
- package/dist/domain/contract.d.ts +413 -0
- package/dist/domain/contract.js +196 -0
- package/dist/domain/diagnostics.d.ts +1396 -0
- package/dist/domain/diagnostics.js +193 -0
- package/dist/domain/external-flow.d.ts +493 -0
- package/dist/domain/external-flow.js +15 -0
- package/dist/domain/failure-classification.d.ts +176 -0
- package/dist/domain/failure-classification.js +169 -0
- package/dist/domain/failure.d.ts +2 -1
- package/dist/domain/failure.js +123 -0
- package/dist/domain/generation.d.ts +1671 -132
- package/dist/domain/generation.js +202 -13
- package/dist/domain/geometry.d.ts +13 -0
- package/dist/domain/geometry.js +16 -0
- package/dist/domain/impact.d.ts +71 -0
- package/dist/domain/impact.js +76 -0
- package/dist/domain/init.d.ts +12 -4
- package/dist/domain/init.js +24 -18
- package/dist/domain/journey-composition.d.ts +2285 -0
- package/dist/domain/journey-composition.js +85 -0
- package/dist/domain/journey-lifecycle.d.ts +10 -0
- package/dist/domain/journey-lifecycle.js +9 -0
- package/dist/domain/journey.d.ts +2419 -212
- package/dist/domain/journey.js +384 -14
- package/dist/domain/knowledge.d.ts +165 -0
- package/dist/domain/knowledge.js +188 -0
- package/dist/domain/layout.d.ts +34 -5
- package/dist/domain/layout.js +64 -6
- package/dist/domain/locator-evidence.d.ts +3 -0
- package/dist/domain/locator-evidence.js +36 -0
- package/dist/domain/logcat-event.d.ts +54 -0
- package/dist/domain/logcat-event.js +40 -0
- package/dist/domain/observation.d.ts +33 -0
- package/dist/domain/observation.js +18 -0
- package/dist/domain/project-context.d.ts +219 -1
- package/dist/domain/project-context.js +209 -6
- package/dist/domain/proposed-step.d.ts +340 -60
- package/dist/domain/proposed-step.js +23 -3
- package/dist/domain/report.d.ts +1455 -28
- package/dist/domain/report.js +211 -14
- package/dist/domain/runtime-snapshot.d.ts +58 -1
- package/dist/domain/runtime-snapshot.js +14 -3
- package/dist/domain/runtime.d.ts +50 -0
- package/dist/domain/runtime.js +36 -0
- package/dist/domain/system-app-profiles.d.ts +6 -0
- package/dist/domain/system-app-profiles.js +43 -0
- package/dist/domain/ui-backend.d.ts +28 -0
- package/dist/domain/ui-backend.js +33 -0
- package/dist/domain/ui-cache.d.ts +11 -0
- package/dist/domain/ui-cache.js +10 -0
- package/dist/domain/verify-receipt.d.ts +17 -0
- package/dist/domain/verify-receipt.js +17 -0
- package/dist/domain/window-hierarchy.d.ts +84 -0
- package/dist/domain/window-hierarchy.js +172 -0
- package/dist/domain/workflow-manifest.d.ts +77 -0
- package/dist/domain/workflow-manifest.js +136 -0
- package/dist/domain/workspace.d.ts +30 -0
- package/dist/domain/workspace.js +74 -0
- package/dist/ports/adb.d.ts +34 -1
- package/dist/ports/align-prompt.d.ts +11 -0
- package/dist/ports/align-prompt.js +6 -0
- package/dist/ports/anchor-resolver.d.ts +30 -0
- package/dist/ports/anchor-resolver.js +1 -0
- package/dist/ports/annotated-screen-resolver.d.ts +4 -0
- package/dist/ports/annotated-screen-resolver.js +1 -0
- package/dist/ports/camera-probe.d.ts +23 -0
- package/dist/ports/camera-probe.js +8 -0
- package/dist/ports/context-document-writer.d.ts +24 -0
- package/dist/ports/context-document-writer.js +1 -0
- package/dist/ports/detached-process-launcher.d.ts +12 -0
- package/dist/ports/detached-process-launcher.js +1 -0
- package/dist/ports/diagnostics.d.ts +15 -0
- package/dist/ports/diagnostics.js +1 -0
- package/dist/ports/external-flow-registry.d.ts +37 -0
- package/dist/ports/external-flow-registry.js +1 -0
- package/dist/ports/generation-prompt.d.ts +2 -1
- package/dist/ports/generation-session-store.d.ts +12 -2
- package/dist/ports/git-diff.d.ts +9 -0
- package/dist/ports/git-diff.js +1 -0
- package/dist/ports/journey-composition-store.d.ts +17 -0
- package/dist/ports/journey-composition-store.js +1 -0
- package/dist/ports/knowledge-registry.d.ts +20 -0
- package/dist/ports/knowledge-registry.js +1 -0
- package/dist/ports/process-runner.d.ts +7 -0
- package/dist/ports/project-file-inspector.d.ts +1 -0
- package/dist/ports/project-identity-inspector.d.ts +24 -0
- package/dist/ports/project-identity-inspector.js +1 -0
- package/dist/ports/project-inventory-inspector.d.ts +21 -0
- package/dist/ports/project-inventory-inspector.js +1 -0
- package/dist/ports/project-module-discoverer.d.ts +26 -0
- package/dist/ports/project-module-discoverer.js +1 -0
- package/dist/ports/recorder-prompt.d.ts +10 -1
- package/dist/ports/runtime-backend.d.ts +89 -0
- package/dist/ports/runtime-backend.js +13 -0
- package/dist/ports/runtime-capability.d.ts +12 -0
- package/dist/ports/runtime-capability.js +20 -0
- package/dist/ports/runtime-session-ports.d.ts +25 -0
- package/dist/ports/runtime-session-ports.js +1 -0
- package/dist/ports/screenshot.d.ts +11 -0
- package/dist/ports/screenshot.js +1 -0
- package/dist/ports/skill-installer.d.ts +2 -2
- package/dist/ports/ui-snapshot.d.ts +35 -0
- package/dist/ports/ui-snapshot.js +1 -0
- package/dist/ports/ui-stability.d.ts +19 -0
- package/dist/ports/ui-stability.js +1 -0
- package/dist/ports/workspace-layout.d.ts +4 -0
- package/dist/ports/workspace-layout.js +1 -0
- package/dist/shared/errors.d.ts +2 -0
- package/dist/shared/errors.js +22 -0
- package/dist/shared/paths.d.ts +2 -0
- package/dist/shared/paths.js +24 -0
- package/dist/shared/strings.d.ts +2 -0
- package/dist/shared/strings.js +16 -0
- package/package.json +7 -2
- package/assets/skills/taphound-ai-journey/GUIDE.md +0 -862
- package/assets/skills/taphound-ai-journey/SKILL.md +0 -377
- package/assets/skills/taphound-ai-journey/prompts/analyze-project.md +0 -526
- package/assets/skills/taphound-ai-journey/prompts/generate-step.md +0 -109
- package/assets/skills/taphound-ai-journey/schemas/project-context.json +0 -81
- package/assets/skills/taphound-ai-journey/templates/project-context.example.json +0 -49
- package/dist/ports/android-cli.d.ts +0 -21
- /package/dist/{ports/android-cli.js → adapters/runtime/mobile-mcp/mobile-mcp-tools.js} +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type CommandEvent, type DiagnosticsHostSchema } from "../domain/diagnostics.js";
|
|
3
|
+
import type { UiCaptureTelemetry } from "../application/diagnostics/ui-capture-telemetry.js";
|
|
4
|
+
import type { DiagnosticsJournal } from "../ports/diagnostics.js";
|
|
5
|
+
import type { z } from "zod";
|
|
6
|
+
export interface CliDiagnostics {
|
|
7
|
+
journal: DiagnosticsJournal;
|
|
8
|
+
telemetry: UiCaptureTelemetry;
|
|
9
|
+
}
|
|
10
|
+
export declare function diagnosticsEnabled(env: Record<string, string | undefined>): boolean;
|
|
11
|
+
export declare function diagnosticsHost(): z.infer<typeof DiagnosticsHostSchema>;
|
|
12
|
+
/** What the invoked command is, captured before its action runs. */
|
|
13
|
+
export interface InvokedCommand {
|
|
14
|
+
command: string;
|
|
15
|
+
flags: string[];
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function describeInvocation(action: Command, cwd: string): InvokedCommand;
|
|
19
|
+
/**
|
|
20
|
+
* Reads only the structured outcome of one machine-readable output: status,
|
|
21
|
+
* failure code, and run id. Messages and every other field are ignored.
|
|
22
|
+
*/
|
|
23
|
+
export declare function outcomeFromJsonOutput(stdout: string): Pick<CommandEvent, "status" | "failureCode" | "runId">;
|
|
24
|
+
export declare function commandEvent(input: {
|
|
25
|
+
invocation: InvokedCommand;
|
|
26
|
+
startedAt: Date;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
exitCode: number;
|
|
29
|
+
stdout: string | undefined;
|
|
30
|
+
telemetry: UiCaptureTelemetry;
|
|
31
|
+
}): CommandEvent;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { arch, platform, version as nodeVersion } from "node:process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { CommandEventSchema, DIAGNOSTICS_DISABLE_ENV_VAR } from "../domain/diagnostics.js";
|
|
4
|
+
import { FAILURE_CODES } from "../domain/failure.js";
|
|
5
|
+
import { readCliVersion } from "./version.js";
|
|
6
|
+
export function diagnosticsEnabled(env) {
|
|
7
|
+
const value = env[DIAGNOSTICS_DISABLE_ENV_VAR]?.trim().toLowerCase();
|
|
8
|
+
return !["0", "off", "false", "no"].includes(value ?? "");
|
|
9
|
+
}
|
|
10
|
+
export function diagnosticsHost() {
|
|
11
|
+
return {
|
|
12
|
+
platform,
|
|
13
|
+
arch,
|
|
14
|
+
node: nodeVersion.replace(/^v/, "")
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function describeInvocation(action, cwd) {
|
|
18
|
+
const names = [];
|
|
19
|
+
let command = action;
|
|
20
|
+
while (command.parent !== null) {
|
|
21
|
+
names.unshift(command.name());
|
|
22
|
+
command = command.parent;
|
|
23
|
+
}
|
|
24
|
+
const flags = action.options
|
|
25
|
+
.map((option) => option.attributeName())
|
|
26
|
+
.filter((name) => action.getOptionValueSource(name) === "cli");
|
|
27
|
+
const project = action.opts().project;
|
|
28
|
+
return {
|
|
29
|
+
command: names.join(" "),
|
|
30
|
+
flags,
|
|
31
|
+
projectRoot: typeof project === "string" ? resolve(cwd, project) : cwd
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function record(value) {
|
|
35
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
36
|
+
? value
|
|
37
|
+
: undefined;
|
|
38
|
+
}
|
|
39
|
+
function failureCode(value) {
|
|
40
|
+
return FAILURE_CODES.find((code) => code === value);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reads only the structured outcome of one machine-readable output: status,
|
|
44
|
+
* failure code, and run id. Messages and every other field are ignored.
|
|
45
|
+
*/
|
|
46
|
+
export function outcomeFromJsonOutput(stdout) {
|
|
47
|
+
let parsed;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(stdout.trim());
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
const output = record(parsed);
|
|
55
|
+
if (output === undefined)
|
|
56
|
+
return {};
|
|
57
|
+
const report = record(output.report);
|
|
58
|
+
const status = [output.status, output.verdict].find((value) => (typeof value === "string" && /^[a-zA-Z][a-zA-Z\d]{0,31}$/.test(value)));
|
|
59
|
+
const code = failureCode(record(output.failure)?.code)
|
|
60
|
+
?? failureCode(record(report?.primaryFailure)?.code);
|
|
61
|
+
const runId = [report?.runId, output.runId].find((value) => (typeof value === "string" && /^[\w.-]{1,128}$/.test(value)));
|
|
62
|
+
return {
|
|
63
|
+
...(typeof status === "string" ? { status } : {}),
|
|
64
|
+
...(code === undefined ? {} : { failureCode: code }),
|
|
65
|
+
...(typeof runId === "string" ? { runId } : {})
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function commandEvent(input) {
|
|
69
|
+
return CommandEventSchema.parse({
|
|
70
|
+
version: 1,
|
|
71
|
+
kind: "command",
|
|
72
|
+
at: input.startedAt.toISOString(),
|
|
73
|
+
taphoundVersion: readCliVersion(),
|
|
74
|
+
host: diagnosticsHost(),
|
|
75
|
+
command: input.invocation.command,
|
|
76
|
+
flags: input.invocation.flags,
|
|
77
|
+
durationMs: Math.max(0, Math.round(input.durationMs)),
|
|
78
|
+
exitCode: input.exitCode,
|
|
79
|
+
...(input.stdout === undefined ? {} : outcomeFromJsonOutput(input.stdout)),
|
|
80
|
+
ui: input.telemetry.summary()
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ImpactSet } from "../domain/impact.js";
|
|
2
|
+
import { CONFIG_PATH } from "../domain/workspace.js";
|
|
3
|
+
import { type FailureCode } from "../domain/failure.js";
|
|
4
|
+
import type { CliDependencies } from "./dependencies.js";
|
|
5
|
+
export interface DiffVerificationOptions {
|
|
6
|
+
project: string;
|
|
7
|
+
config: string;
|
|
8
|
+
base: string;
|
|
9
|
+
head?: string | undefined;
|
|
10
|
+
device?: string | undefined;
|
|
11
|
+
scope?: string | undefined;
|
|
12
|
+
json?: boolean | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface JourneyVerdict {
|
|
15
|
+
path: string;
|
|
16
|
+
name: string;
|
|
17
|
+
selection: "p0" | "p1" | "p2";
|
|
18
|
+
status: string;
|
|
19
|
+
exitCode: 0 | 1 | 2 | 3 | 4;
|
|
20
|
+
reportPath: string;
|
|
21
|
+
}
|
|
22
|
+
export interface DiffVerificationResult {
|
|
23
|
+
base: string;
|
|
24
|
+
head: string;
|
|
25
|
+
impact: ImpactSet;
|
|
26
|
+
results: JourneyVerdict[];
|
|
27
|
+
overall: "passed" | "failed" | "error";
|
|
28
|
+
exitCode: 0 | 1 | 2 | 3 | 4;
|
|
29
|
+
note?: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
declare function writeFailure(dependencies: CliDependencies, json: boolean, code: FailureCode, message: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Diff-driven verification: compute the ImpactSet for a Git change, select
|
|
34
|
+
* the affected Journeys by tier (p0/p1/p2), and verify each one on the
|
|
35
|
+
* connected device.
|
|
36
|
+
*
|
|
37
|
+
* This is the Agent-facing entry behind `verify --diff`; it never parses the app's internals — the Coding Agent
|
|
38
|
+
* only sees Journey names + verdicts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function runDiffVerification(dependencies: CliDependencies, options: DiffVerificationOptions): Promise<void>;
|
|
41
|
+
export { CONFIG_PATH, writeFailure };
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { TapHoundConfigSchema } from "../domain/config.js";
|
|
3
|
+
import { DEFAULT_DEVICE_ROLE, JourneySchema } from "../domain/journey.js";
|
|
4
|
+
import { assertArtifactDirectory, CONFIG_PATH } from "../domain/workspace.js";
|
|
5
|
+
import { exitCodeForFailure, failureCodeFromUnknown } from "../domain/failure.js";
|
|
6
|
+
import { errorMessage, failureOutput, writeJson, writeLine } from "./output.js";
|
|
7
|
+
import { prepareWorkspace } from "./workspace-guard.js";
|
|
8
|
+
function selectedScopes(scope) {
|
|
9
|
+
const normalized = scope ?? "p0,p1";
|
|
10
|
+
const tiers = [];
|
|
11
|
+
for (const token of normalized.split(",").map((value) => value.trim())) {
|
|
12
|
+
if (token === "p0" || token === "p1" || token === "p2") {
|
|
13
|
+
tiers.push(token);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return tiers;
|
|
17
|
+
}
|
|
18
|
+
function toolVersions(checks) {
|
|
19
|
+
return Object.fromEntries(checks.flatMap((check) => (check.version === undefined
|
|
20
|
+
|| !["node", "adb", "android"].includes(check.name)
|
|
21
|
+
? []
|
|
22
|
+
: [[check.name, check.version]])));
|
|
23
|
+
}
|
|
24
|
+
function writeFailure(dependencies, json, code, message) {
|
|
25
|
+
const exitCode = exitCodeForFailure(code);
|
|
26
|
+
const output = failureOutput(exitCode, code, message);
|
|
27
|
+
if (json) {
|
|
28
|
+
writeJson(dependencies.stdout, output);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
writeLine(dependencies.stderr, output.failure.message);
|
|
32
|
+
}
|
|
33
|
+
dependencies.setExitCode(exitCode);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Diff-driven verification: compute the ImpactSet for a Git change, select
|
|
37
|
+
* the affected Journeys by tier (p0/p1/p2), and verify each one on the
|
|
38
|
+
* connected device.
|
|
39
|
+
*
|
|
40
|
+
* This is the Agent-facing entry behind `verify --diff`; it never parses the app's internals — the Coding Agent
|
|
41
|
+
* only sees Journey names + verdicts.
|
|
42
|
+
*/
|
|
43
|
+
export async function runDiffVerification(dependencies, options) {
|
|
44
|
+
try {
|
|
45
|
+
if (dependencies.gitDiff === undefined
|
|
46
|
+
|| dependencies.impact === undefined) {
|
|
47
|
+
throw new Error("TapHound change verification is not configured");
|
|
48
|
+
}
|
|
49
|
+
const head = options.head ?? "HEAD";
|
|
50
|
+
const projectRoot = options.project;
|
|
51
|
+
const config = TapHoundConfigSchema.parse(await dependencies.readJson(resolve(projectRoot, options.config)));
|
|
52
|
+
assertArtifactDirectory(projectRoot, config.artifactsDir);
|
|
53
|
+
await prepareWorkspace(dependencies, projectRoot);
|
|
54
|
+
const changeSet = await dependencies.gitDiff.diff({
|
|
55
|
+
projectRoot,
|
|
56
|
+
base: options.base,
|
|
57
|
+
head
|
|
58
|
+
});
|
|
59
|
+
const impact = await dependencies.impact.resolve({
|
|
60
|
+
projectRoot,
|
|
61
|
+
packageName: config.run.packageName,
|
|
62
|
+
changeSet
|
|
63
|
+
});
|
|
64
|
+
const scopes = selectedScopes(options.scope);
|
|
65
|
+
const selected = scopes.flatMap((tier) => (impact.selectedJourneys[tier].map((entry) => ({
|
|
66
|
+
tier,
|
|
67
|
+
path: entry.id
|
|
68
|
+
}))));
|
|
69
|
+
const doctor = await dependencies.doctor.run({
|
|
70
|
+
packageName: config.run.packageName,
|
|
71
|
+
...(config.ui?.backend === undefined
|
|
72
|
+
? {}
|
|
73
|
+
: { requestedUiBackend: config.ui.backend }),
|
|
74
|
+
...(options.device === undefined
|
|
75
|
+
? {}
|
|
76
|
+
: { requestedDevice: options.device }),
|
|
77
|
+
...(dependencies.signal === undefined
|
|
78
|
+
? {}
|
|
79
|
+
: { signal: dependencies.signal })
|
|
80
|
+
});
|
|
81
|
+
if (doctor.status === "failed") {
|
|
82
|
+
const output = failureOutput(3, doctor.failureCode ?? "ENVIRONMENT_MISSING_TOOL", doctor.checks.find((check) => check.status === "failed")?.message
|
|
83
|
+
?? "TapHound environment preflight failed");
|
|
84
|
+
if (options.json === true) {
|
|
85
|
+
writeJson(dependencies.stdout, output);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
writeLine(dependencies.stderr, output.failure.message);
|
|
89
|
+
}
|
|
90
|
+
dependencies.setExitCode(3);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const deviceSerial = options.device ?? doctor.deviceSerial;
|
|
94
|
+
if (deviceSerial === undefined) {
|
|
95
|
+
throw new Error("Doctor did not select a device");
|
|
96
|
+
}
|
|
97
|
+
if (dependencies.journeyCompositionStore === undefined) {
|
|
98
|
+
throw new Error("TapHound change verification is not configured");
|
|
99
|
+
}
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const entry of selected) {
|
|
102
|
+
const bytes = await dependencies.journeyCompositionStore.read({
|
|
103
|
+
projectRoot,
|
|
104
|
+
relativePath: entry.path
|
|
105
|
+
});
|
|
106
|
+
const journey = JourneySchema.parse(JSON.parse(bytes.toString("utf8")));
|
|
107
|
+
if (journey.devices.length > 1) {
|
|
108
|
+
writeFailure(dependencies, options.json === true, "DEVICE_ROLE_UNMAPPED", `Journey ${journey.name} declares multiple devices; map each role with --device <role>=<serial>`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
writeLine(dependencies.stderr, `TapHound: verifying ${journey.name} (${entry.tier})`);
|
|
112
|
+
const result = await dependencies.verifier.verify({
|
|
113
|
+
config,
|
|
114
|
+
journey,
|
|
115
|
+
projectRoot,
|
|
116
|
+
devices: [{
|
|
117
|
+
role: journey.devices[0]?.role ?? DEFAULT_DEVICE_ROLE,
|
|
118
|
+
deviceSerial
|
|
119
|
+
}],
|
|
120
|
+
toolVersions: toolVersions(doctor.checks),
|
|
121
|
+
manualReplay: process.stdin.isTTY,
|
|
122
|
+
...(dependencies.signal === undefined
|
|
123
|
+
? {}
|
|
124
|
+
: { signal: dependencies.signal })
|
|
125
|
+
});
|
|
126
|
+
results.push({
|
|
127
|
+
path: entry.path,
|
|
128
|
+
name: journey.name,
|
|
129
|
+
selection: entry.tier,
|
|
130
|
+
status: result.status,
|
|
131
|
+
exitCode: result.exitCode,
|
|
132
|
+
reportPath: result.reportPath
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const failed = results.find((result) => result.status !== "passed");
|
|
136
|
+
let overall;
|
|
137
|
+
let note;
|
|
138
|
+
if (changeSet.files.length === 0) {
|
|
139
|
+
overall = "passed";
|
|
140
|
+
note = "No changes; nothing to verify";
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
overall = results.length === 0
|
|
144
|
+
? "error"
|
|
145
|
+
: failed === undefined
|
|
146
|
+
? "passed"
|
|
147
|
+
: "failed";
|
|
148
|
+
}
|
|
149
|
+
const exitCode = results.length === 0
|
|
150
|
+
? (changeSet.files.length === 0 ? 0 : 4)
|
|
151
|
+
: failed === undefined
|
|
152
|
+
? 0
|
|
153
|
+
: failed.exitCode;
|
|
154
|
+
const payload = {
|
|
155
|
+
base: options.base,
|
|
156
|
+
head,
|
|
157
|
+
impact,
|
|
158
|
+
results,
|
|
159
|
+
overall,
|
|
160
|
+
exitCode,
|
|
161
|
+
...(note === undefined ? {} : { note })
|
|
162
|
+
};
|
|
163
|
+
if (options.json === true) {
|
|
164
|
+
writeJson(dependencies.stdout, payload);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const lines = [
|
|
168
|
+
`TapHound verify (${options.base}...${head}):`,
|
|
169
|
+
...results.map((result) => (` ${result.selection.toUpperCase()} ${result.name}: ${result.status.toUpperCase()}`)),
|
|
170
|
+
`overall: ${overall.toUpperCase()}`
|
|
171
|
+
];
|
|
172
|
+
writeLine(dependencies.stdout, lines.join("\n"));
|
|
173
|
+
}
|
|
174
|
+
dependencies.setExitCode(exitCode);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
const code = failureCodeFromUnknown(error);
|
|
178
|
+
if (code !== undefined) {
|
|
179
|
+
writeFailure(dependencies, options.json === true, code, errorMessage(error));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const output = failureOutput(4, "INTERNAL_ERROR", errorMessage(error));
|
|
183
|
+
if (options.json === true) {
|
|
184
|
+
writeJson(dependencies.stdout, output);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
writeLine(dependencies.stderr, output.failure.message);
|
|
188
|
+
}
|
|
189
|
+
dependencies.setExitCode(4);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export { CONFIG_PATH, writeFailure };
|
package/dist/cli/main.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export interface TerminationSignalSource {
|
|
|
5
5
|
off: (event: "SIGINT" | "SIGTERM", listener: () => void) => unknown;
|
|
6
6
|
}
|
|
7
7
|
export declare function withTerminationSignal<T>(operation: (signal: AbortSignal) => Promise<T>, source?: TerminationSignalSource): Promise<T>;
|
|
8
|
-
export declare function runMain(argv: readonly string[],
|
|
8
|
+
export declare function runMain(argv: readonly string[], baseDependencies?: CliDependencies): Promise<void>;
|
package/dist/cli/main.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
3
4
|
import { resolve } from "node:path";
|
|
4
5
|
import { pathToFileURL } from "node:url";
|
|
5
6
|
import { CommanderError } from "commander";
|
|
6
7
|
import { createProductionDependencies } from "./dependencies.js";
|
|
8
|
+
import { RuntimeBackendConfigError, RuntimeBackendSelectionError, resolveRuntimeBackendChoiceFromInvocation } from "./runtime-selection.js";
|
|
9
|
+
import { commandEvent, describeInvocation } from "./diagnostics-recorder.js";
|
|
7
10
|
import { errorMessage, failureOutput, writeJson, writeLine } from "./output.js";
|
|
8
11
|
import { createProgram } from "./program.js";
|
|
9
12
|
export async function withTerminationSignal(operation, source = process) {
|
|
@@ -41,11 +44,64 @@ function overrideCommandExits(command) {
|
|
|
41
44
|
overrideCommandExits(child);
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Wraps the dependencies so the finished invocation can be journaled: the
|
|
49
|
+
* last exit code, and stdout only when the command promised one JSON value.
|
|
50
|
+
*/
|
|
51
|
+
function observeInvocation(dependencies, json) {
|
|
52
|
+
let exitCode = 0;
|
|
53
|
+
let stdout = "";
|
|
54
|
+
return {
|
|
55
|
+
dependencies: {
|
|
56
|
+
...dependencies,
|
|
57
|
+
stdout: {
|
|
58
|
+
write: (content) => {
|
|
59
|
+
if (json)
|
|
60
|
+
stdout += content;
|
|
61
|
+
dependencies.stdout.write(content);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
setExitCode: (code) => {
|
|
65
|
+
exitCode = code;
|
|
66
|
+
dependencies.setExitCode(code);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
exitCode: () => exitCode,
|
|
70
|
+
stdout: () => (json ? stdout : undefined)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function journalInvocation(dependencies, invocation, startedAt, observed) {
|
|
74
|
+
const diagnostics = dependencies.diagnostics;
|
|
75
|
+
if (diagnostics === undefined || invocation === undefined)
|
|
76
|
+
return;
|
|
77
|
+
try {
|
|
78
|
+
await diagnostics.journal.append(invocation.projectRoot, commandEvent({
|
|
79
|
+
invocation,
|
|
80
|
+
startedAt,
|
|
81
|
+
durationMs: Date.now() - startedAt.getTime(),
|
|
82
|
+
exitCode: observed.exitCode(),
|
|
83
|
+
stdout: observed.stdout(),
|
|
84
|
+
telemetry: diagnostics.telemetry
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// The journal is best-effort evidence; it never changes a command result.
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export async function runMain(argv, baseDependencies = createProductionDependencies()) {
|
|
45
92
|
const json = argv.includes("--json");
|
|
93
|
+
const startedAt = new Date();
|
|
94
|
+
const observed = observeInvocation(baseDependencies, json);
|
|
95
|
+
const dependencies = baseDependencies.diagnostics === undefined
|
|
96
|
+
? baseDependencies
|
|
97
|
+
: observed.dependencies;
|
|
98
|
+
let invocation;
|
|
46
99
|
try {
|
|
47
100
|
const program = createProgram(dependencies);
|
|
48
101
|
overrideCommandExits(program);
|
|
102
|
+
program.hook("preAction", (_program, action) => {
|
|
103
|
+
invocation = describeInvocation(action, dependencies.cwd());
|
|
104
|
+
});
|
|
49
105
|
await program.parseAsync([...argv]);
|
|
50
106
|
}
|
|
51
107
|
catch (error) {
|
|
@@ -65,9 +121,58 @@ export async function runMain(argv, dependencies = createProductionDependencies(
|
|
|
65
121
|
}
|
|
66
122
|
dependencies.setExitCode(exitCode);
|
|
67
123
|
}
|
|
124
|
+
finally {
|
|
125
|
+
await journalInvocation(dependencies, invocation, startedAt, observed);
|
|
126
|
+
}
|
|
68
127
|
}
|
|
69
128
|
const entryPath = process.argv[1];
|
|
70
129
|
if (entryPath !== undefined
|
|
71
130
|
&& import.meta.url === pathToFileURL(realpathSync(resolve(entryPath))).href) {
|
|
72
|
-
await withTerminationSignal((signal) =>
|
|
131
|
+
await withTerminationSignal(async (signal) => {
|
|
132
|
+
let dependencies;
|
|
133
|
+
try {
|
|
134
|
+
dependencies = createProductionDependencies(signal, {
|
|
135
|
+
runtimeBackendChoice: await resolveRuntimeBackendChoiceFromInvocation({
|
|
136
|
+
env: process.env,
|
|
137
|
+
argv: process.argv,
|
|
138
|
+
cwd: process.cwd(),
|
|
139
|
+
readConfigFile: (path) => readFile(path, "utf8")
|
|
140
|
+
})
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof RuntimeBackendSelectionError
|
|
145
|
+
|| error instanceof RuntimeBackendConfigError) {
|
|
146
|
+
const output = failureOutput(2, "CONFIG_INVALID", error.message);
|
|
147
|
+
if (process.argv.includes("--json")) {
|
|
148
|
+
writeJson({
|
|
149
|
+
write: (content) => {
|
|
150
|
+
process.stdout.write(content);
|
|
151
|
+
}
|
|
152
|
+
}, output);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
writeLine({
|
|
156
|
+
write: (content) => {
|
|
157
|
+
process.stderr.write(content);
|
|
158
|
+
}
|
|
159
|
+
}, output.failure.message);
|
|
160
|
+
}
|
|
161
|
+
process.exitCode = 2;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
await runMain(process.argv, dependencies);
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
try {
|
|
171
|
+
await dependencies.close?.();
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
process.stderr.write(`TapHound: failed to release the runtime backend: ${errorMessage(error)}\n`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
73
178
|
}
|
package/dist/cli/output.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { DoctorReport } from "../application/doctor/doctor-service.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ContextLoadError } from "../application/context/context-loader.js";
|
|
3
|
+
import type { FailureCode, TapHoundExitCode } from "../domain/failure.js";
|
|
3
4
|
import type { TextOutput } from "./dependencies.js";
|
|
4
5
|
export interface CliFailureOutput {
|
|
5
6
|
status: "error";
|
|
6
|
-
exitCode:
|
|
7
|
+
exitCode: TapHoundExitCode;
|
|
7
8
|
failure: {
|
|
8
9
|
code: FailureCode;
|
|
9
10
|
message: string;
|
|
@@ -11,6 +12,7 @@ export interface CliFailureOutput {
|
|
|
11
12
|
}
|
|
12
13
|
export declare function writeJson(output: TextOutput, value: unknown): void;
|
|
13
14
|
export declare function writeLine(output: TextOutput, value: string): void;
|
|
14
|
-
export declare function failureOutput(exitCode:
|
|
15
|
+
export declare function failureOutput(exitCode: TapHoundExitCode, code: FailureCode, message: string): CliFailureOutput;
|
|
15
16
|
export declare function doctorMessage(report: DoctorReport): string;
|
|
16
17
|
export declare function errorMessage(error: unknown): string;
|
|
18
|
+
export declare function contextLoadHint(error: ContextLoadError): string | undefined;
|
package/dist/cli/output.js
CHANGED
|
@@ -20,3 +20,15 @@ export function doctorMessage(report) {
|
|
|
20
20
|
export function errorMessage(error) {
|
|
21
21
|
return error instanceof Error ? error.message : String(error);
|
|
22
22
|
}
|
|
23
|
+
export function contextLoadHint(error) {
|
|
24
|
+
if (error.code !== "CONTEXT_INVALID"
|
|
25
|
+
|| (!error.message.includes("index does not exist")
|
|
26
|
+
&& !error.message.includes("shard does not exist"))) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return "Project Context is missing at the resolved path. Generate the "
|
|
30
|
+
+ "committed Context first with `taphound context generate`, or pass "
|
|
31
|
+
+ "--context with an explicit index path. For a registered local "
|
|
32
|
+
+ "target, run `taphound local sync <id>` before retrying. See "
|
|
33
|
+
+ "docs/agent-integration.md and docs/local-target.md.";
|
|
34
|
+
}
|
package/dist/cli/program.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { readCliVersion } from "./version.js";
|
|
2
3
|
import { createContextCommand } from "./commands/context.js";
|
|
3
4
|
import { createDoctorCommand } from "./commands/doctor.js";
|
|
4
5
|
import { createGenerationCommand } from "./commands/generation.js";
|
|
5
6
|
import { createInitCommand } from "./commands/init.js";
|
|
7
|
+
import { createJourneyCommand } from "./commands/journey.js";
|
|
8
|
+
import { createObserveCommand } from "./commands/observe.js";
|
|
6
9
|
import { createProjectCommand } from "./commands/project.js";
|
|
7
10
|
import { createRecordCommand } from "./commands/record.js";
|
|
8
11
|
import { createVerifyCommand } from "./commands/verify.js";
|
|
12
|
+
import { createContractCommand } from "./commands/contract.js";
|
|
13
|
+
import { createAlignCommand } from "./commands/align.js";
|
|
14
|
+
import { createImpactCommand } from "./commands/impact.js";
|
|
15
|
+
import { createKnowledgeCommand } from "./commands/knowledge.js";
|
|
16
|
+
import { createBaselineCommand } from "./commands/baseline.js";
|
|
17
|
+
import { createFailureCommand } from "./commands/failure.js";
|
|
18
|
+
import { createDiagnoseCommand } from "./commands/diagnose.js";
|
|
9
19
|
import { createProductionDependencies } from "./dependencies.js";
|
|
10
20
|
export function createProgram(dependencies = createProductionDependencies()) {
|
|
11
21
|
const configureOutput = (command) => {
|
|
@@ -25,6 +35,7 @@ export function createProgram(dependencies = createProductionDependencies()) {
|
|
|
25
35
|
return new Command()
|
|
26
36
|
.name("taphound")
|
|
27
37
|
.description("Deterministic app journey recording and verification")
|
|
38
|
+
.version(readCliVersion(), "-v, --version")
|
|
28
39
|
.configureOutput({
|
|
29
40
|
writeOut: (content) => {
|
|
30
41
|
dependencies.stdout.write(content);
|
|
@@ -36,8 +47,17 @@ export function createProgram(dependencies = createProductionDependencies()) {
|
|
|
36
47
|
.addCommand(configureOutput(createDoctorCommand(dependencies)))
|
|
37
48
|
.addCommand(configureOutput(createRecordCommand(dependencies)))
|
|
38
49
|
.addCommand(configureOutput(createVerifyCommand(dependencies)))
|
|
50
|
+
.addCommand(configureOutput(createContractCommand(dependencies)))
|
|
51
|
+
.addCommand(configureOutput(createObserveCommand(dependencies)))
|
|
39
52
|
.addCommand(configureOutput(createProjectCommand(dependencies)))
|
|
40
53
|
.addCommand(configureOutput(createContextCommand(dependencies)))
|
|
54
|
+
.addCommand(configureOutput(createJourneyCommand(dependencies)))
|
|
41
55
|
.addCommand(configureOutput(createGenerationCommand(dependencies)))
|
|
42
|
-
.addCommand(configureOutput(
|
|
56
|
+
.addCommand(configureOutput(createKnowledgeCommand(dependencies)))
|
|
57
|
+
.addCommand(configureOutput(createBaselineCommand(dependencies)))
|
|
58
|
+
.addCommand(configureOutput(createFailureCommand(dependencies)))
|
|
59
|
+
.addCommand(configureOutput(createInitCommand(dependencies)))
|
|
60
|
+
.addCommand(configureOutput(createAlignCommand(dependencies)))
|
|
61
|
+
.addCommand(configureOutput(createImpactCommand(dependencies)))
|
|
62
|
+
.addCommand(configureOutput(createDiagnoseCommand(dependencies)));
|
|
43
63
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function canonicalProjectRoot(cwd: string, projectRoot: string): Promise<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RuntimeBackendChoice } from "../domain/runtime.js";
|
|
2
|
+
export declare const RUNTIME_BACKEND_ENV_VAR = "TAPHOUND_RUNTIME_BACKEND";
|
|
3
|
+
export declare class RuntimeBackendSelectionError extends Error {
|
|
4
|
+
constructor(value: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class RuntimeBackendConfigError extends Error {
|
|
7
|
+
constructor(path: string, value: unknown);
|
|
8
|
+
}
|
|
9
|
+
export declare function readRuntimeBackendChoice(env: Record<string, string | undefined>): RuntimeBackendChoice;
|
|
10
|
+
export interface RuntimeBackendInvocation {
|
|
11
|
+
env: Record<string, string | undefined>;
|
|
12
|
+
argv: readonly string[];
|
|
13
|
+
cwd: string;
|
|
14
|
+
readConfigFile: (path: string) => Promise<string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolves the effective runtime backend choice for one CLI invocation.
|
|
18
|
+
* An explicit `TAPHOUND_RUNTIME_BACKEND` wins over the config file so CI and
|
|
19
|
+
* experiments can override committed project state; `auto` defers to the
|
|
20
|
+
* config's `runtime.backend`, which itself defaults to `auto`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveRuntimeBackendChoiceFromInvocation(invocation: RuntimeBackendInvocation): Promise<RuntimeBackendChoice>;
|