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
|
@@ -1,526 +0,0 @@
|
|
|
1
|
-
# Analyze Android Project for TapHound Context
|
|
2
|
-
|
|
3
|
-
You are generating or updating a TapHound Project Context JSON file for
|
|
4
|
-
an Android project. Read the project source code and produce a Context
|
|
5
|
-
that matches `schemas/project-context.json`.
|
|
6
|
-
|
|
7
|
-
There are two modes:
|
|
8
|
-
- **Full generation** (no existing Context, or `context status` returns
|
|
9
|
-
`"invalid"`): Follow all steps below from scratch.
|
|
10
|
-
- **Incremental update** (existing Context, `context status` returns
|
|
11
|
-
`"stale"`, structural counts match): Skip to the Incremental Update
|
|
12
|
-
section at the bottom. Only re-analyze changed files.
|
|
13
|
-
|
|
14
|
-
## Step 1: Discover Project Modules
|
|
15
|
-
|
|
16
|
-
Modern Android projects may have multiple modules. Activities, layouts, and
|
|
17
|
-
source files can live in any module, not just `app/`.
|
|
18
|
-
|
|
19
|
-
### 1a. Primary: `./gradlew projects`
|
|
20
|
-
|
|
21
|
-
Run the Gradle wrapper to get the authoritative module tree:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
cd <project-root>
|
|
25
|
-
./gradlew projects --console=plain
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
This resolves the full project structure including `projectDir` overrides,
|
|
29
|
-
`includeBuild` composite builds, and nested subprojects. The output looks
|
|
30
|
-
like:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
Root project 'taphound-demo'
|
|
34
|
-
+--- Project ':app'
|
|
35
|
-
+--- Project ':feature-search'
|
|
36
|
-
| \--- Project ':feature-search:sub-widget'
|
|
37
|
-
\--- Project ':lib-ui'
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
For each `Project ':<path>'` line:
|
|
41
|
-
- The Gradle path (`:app`, `:feature-search`) identifies the module.
|
|
42
|
-
- The directory is derived from the path: replace `:` with `/`, drop the
|
|
43
|
-
leading `/`. So `:feature-search` → `feature-search/`,
|
|
44
|
-
`:feature-search:sub-widget` → `feature-search/sub-widget/`.
|
|
45
|
-
- If the project uses `projectDir` overrides, the Gradle path may not
|
|
46
|
-
match the directory. In that case, check `settings.gradle(.kts)` for the
|
|
47
|
-
explicit `project(...).projectDir` mapping (see 1b).
|
|
48
|
-
|
|
49
|
-
> **Note**: `./gradlew projects` runs a configuration phase which can be
|
|
50
|
-
> slow on first run (downloading dependencies). Subsequent runs are fast
|
|
51
|
-
> due to Gradle daemon caching. If the wrapper is not executable
|
|
52
|
-
> (`./gradlew: Permission denied`), run `chmod +x gradlew` first. On
|
|
53
|
-
> Windows, use `gradlew.bat projects`.
|
|
54
|
-
|
|
55
|
-
### 1b. Fallback: parse `settings.gradle(.kts)`
|
|
56
|
-
|
|
57
|
-
If `./gradlew projects` is unavailable (no wrapper, no JDK, or timeout),
|
|
58
|
-
parse `settings.gradle` or `settings.gradle.kts` at the project root:
|
|
59
|
-
|
|
60
|
-
1. Extract all module names from `include` statements:
|
|
61
|
-
```
|
|
62
|
-
include ':app', ':feature-search', ':lib-ui'
|
|
63
|
-
```
|
|
64
|
-
2. For each included module, check for `projectDir` overrides:
|
|
65
|
-
```
|
|
66
|
-
project(':feature-search').projectDir = file('features/search')
|
|
67
|
-
```
|
|
68
|
-
If overridden, use the specified directory. Otherwise, derive the
|
|
69
|
-
directory from the path (drop `:`, replace remaining `:` with `/`).
|
|
70
|
-
3. **Watch for custom functions**: Some projects use helper functions
|
|
71
|
-
like `includeModule()` that dynamically include modules. If you see
|
|
72
|
-
function calls in `settings.gradle` that are not standard Gradle,
|
|
73
|
-
you MUST use the filesystem fallback below — parsing `include`
|
|
74
|
-
statements alone will miss modules.
|
|
75
|
-
4. **Filesystem fallback** (use when `settings.gradle` has custom
|
|
76
|
-
functions or `./gradlew projects` is unavailable):
|
|
77
|
-
```bash
|
|
78
|
-
find . -name "build.gradle" -o -name "build.gradle.kts" \
|
|
79
|
-
| grep -v '/build/' | sort
|
|
80
|
-
```
|
|
81
|
-
Each result is a module directory. This catches all modules
|
|
82
|
-
regardless of how they are included in `settings.gradle`.
|
|
83
|
-
5. If no `settings.gradle` exists, treat the project as single-module
|
|
84
|
-
with the root directory as the only module.
|
|
85
|
-
|
|
86
|
-
### 1c. Identify the app module
|
|
87
|
-
|
|
88
|
-
The app module (the one that produces the APK) is the one with
|
|
89
|
-
`applicationId` or `applicationIdSuffix` in its `build.gradle(.kts)`, or
|
|
90
|
-
a `<application>` tag in its `AndroidManifest.xml`. Library modules have
|
|
91
|
-
`com.android.library` plugin instead of `com.android.application`.
|
|
92
|
-
|
|
93
|
-
## Step 2: Determine packageName
|
|
94
|
-
|
|
95
|
-
Modern Android projects (AGP 7.0+) no longer set the `package` attribute
|
|
96
|
-
in `AndroidManifest.xml`. Determine the package name in this priority
|
|
97
|
-
order:
|
|
98
|
-
|
|
99
|
-
1. **`applicationId` in the app module's build file**:
|
|
100
|
-
Check both `build.gradle.kts` (Kotlin DSL) and `build.gradle` (Groovy
|
|
101
|
-
DSL). One of them will exist; projects do not use both in the same
|
|
102
|
-
module.
|
|
103
|
-
|
|
104
|
-
Kotlin DSL (`build.gradle.kts`) — uses `=`:
|
|
105
|
-
```kotlin
|
|
106
|
-
android {
|
|
107
|
-
defaultConfig {
|
|
108
|
-
applicationId = "dev.taphound.demo"
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Groovy DSL (`build.gradle`) — no `=`:
|
|
114
|
-
```groovy
|
|
115
|
-
android {
|
|
116
|
-
defaultConfig {
|
|
117
|
-
applicationId "dev.taphound.demo"
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
This is the authoritative package name. Use this if present.
|
|
123
|
-
|
|
124
|
-
2. **`package` attribute in `AndroidManifest.xml`** (legacy):
|
|
125
|
-
```xml
|
|
126
|
-
<manifest xmlns:android="..."
|
|
127
|
-
package="dev.taphound.demo">
|
|
128
|
-
```
|
|
129
|
-
Use this only if `applicationId` is not set in either build file.
|
|
130
|
-
|
|
131
|
-
3. **`namespace` in the build file** (fallback):
|
|
132
|
-
Same dual-syntax as above — Kotlin DSL uses `=`, Groovy does not.
|
|
133
|
-
|
|
134
|
-
Kotlin DSL:
|
|
135
|
-
```kotlin
|
|
136
|
-
android {
|
|
137
|
-
namespace = "dev.taphound.demo"
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Groovy DSL:
|
|
142
|
-
```groovy
|
|
143
|
-
android {
|
|
144
|
-
namespace "dev.taphound.demo"
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
`namespace` is used for R class generation and is NOT the same as
|
|
149
|
-
`applicationId` (they can differ, especially with build flavors or
|
|
150
|
-
suffixes). Use `namespace` only when neither `applicationId` nor
|
|
151
|
-
`package` is available.
|
|
152
|
-
|
|
153
|
-
> **Important**: If the project uses build flavors with different
|
|
154
|
-
> `applicationId` suffixes (e.g., `.debug`, `.staging`), use the base
|
|
155
|
-
> `applicationId` without the suffix. TapHound verifies against the
|
|
156
|
-
> installed package at runtime.
|
|
157
|
-
|
|
158
|
-
### 2a. Dynamic applicationId resolution
|
|
159
|
-
|
|
160
|
-
Some projects do not set `applicationId` to a string literal. Instead,
|
|
161
|
-
they reference a Gradle ext property or a function call:
|
|
162
|
-
|
|
163
|
-
```groovy
|
|
164
|
-
// app/build.gradle
|
|
165
|
-
applicationId gradle.ext.buildApplicationId
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
When you encounter a non-literal `applicationId`, trace the resolution
|
|
169
|
-
chain to find the actual string value:
|
|
170
|
-
|
|
171
|
-
1. Search for the variable definition in `gradle.properties`:
|
|
172
|
-
```bash
|
|
173
|
-
grep -rn "buildApplicationId" gradle.properties
|
|
174
|
-
# Example: buildApplicationId=com.whaleco.tchat
|
|
175
|
-
```
|
|
176
|
-
2. If not in `gradle.properties`, search all `.gradle` files under
|
|
177
|
-
`gradle/` for the assignment:
|
|
178
|
-
```bash
|
|
179
|
-
grep -rn "buildApplicationId" gradle/ --include="*.gradle"
|
|
180
|
-
```
|
|
181
|
-
3. If the variable is set via a function call (e.g.,
|
|
182
|
-
`gradle.ext.buildApplicationId = getApplicationId()`), find the
|
|
183
|
-
function definition and trace its return value.
|
|
184
|
-
4. **Include ALL files in the resolution chain** in `manifest.files`:
|
|
185
|
-
- `gradle.properties` (if it defines the value)
|
|
186
|
-
- Any `.gradle` file that contains the variable assignment or function
|
|
187
|
-
definition (e.g., `gradle/prebuild.gradle`)
|
|
188
|
-
- `app/build.gradle` (where `applicationId` is referenced)
|
|
189
|
-
|
|
190
|
-
These files are part of the package name provenance and must be
|
|
191
|
-
tracked for staleness detection.
|
|
192
|
-
|
|
193
|
-
## Step 3: Identify Launch Activity
|
|
194
|
-
|
|
195
|
-
1. Read the **app module's** `src/main/AndroidManifest.xml`.
|
|
196
|
-
2. Find the `<activity>` that contains an `<intent-filter>` with both:
|
|
197
|
-
- `<action android:name="android.intent.action.MAIN" />`
|
|
198
|
-
- `<category android:name="android.intent.category.LAUNCHER" />`
|
|
199
|
-
3. The `android:name` attribute gives the Activity class. If it starts
|
|
200
|
-
with `.` (e.g., `.MainActivity`), prepend the package name to get the
|
|
201
|
-
fully qualified class (e.g., `dev.taphound.demo.MainActivity`).
|
|
202
|
-
|
|
203
|
-
> **Multi-module note**: Library modules may declare their own Activities
|
|
204
|
-
> in their own manifests. These get merged into the final manifest at
|
|
205
|
-
> build time. The launch Activity is almost always in the `app` module's
|
|
206
|
-
> manifest. If not found there, check merged manifest output in
|
|
207
|
-
> `app/build/intermediates/merged_manifests/` (do not hash build
|
|
208
|
-
> artifacts — only use them for discovery).
|
|
209
|
-
|
|
210
|
-
## Step 4: Scan Source Files Across All Modules
|
|
211
|
-
|
|
212
|
-
For each module discovered in Step 1, scan `src/main/` (and
|
|
213
|
-
`src/<flavor>/main/` if flavors exist):
|
|
214
|
-
|
|
215
|
-
### 4a. Kotlin/Java source (`src/main/java/` or `src/main/kotlin/`)
|
|
216
|
-
|
|
217
|
-
- Find `setContentView(R.layout.*)` to map each Activity to its layout.
|
|
218
|
-
- Find `findViewById<T>(R.id.*)` or view binding references
|
|
219
|
-
(`binding.submitButton`) to identify interactive UI elements.
|
|
220
|
-
- Find `setOnClickListener`, `setOnCheckedChangeListener`,
|
|
221
|
-
`setOnTouchListener`, etc. to determine which elements are actionable.
|
|
222
|
-
- Find `Log.i(tag, message)`, `Log.d(tag, ...)`, `Log.w(tag, ...)`, etc.
|
|
223
|
-
to identify logcat tags and message patterns usable as expectations.
|
|
224
|
-
- Find `startActivity(Intent(this, TargetActivity::class.java))` or
|
|
225
|
-
navigation component calls to predict Activity transitions.
|
|
226
|
-
- Find `EditText`, `TextView`, `Button`, `RecyclerView`, `ScrollView`
|
|
227
|
-
usages to understand what actions each screen supports.
|
|
228
|
-
|
|
229
|
-
### 4b. Layout XML (`src/main/res/layout/`)
|
|
230
|
-
|
|
231
|
-
Extract UI element information from layout files:
|
|
232
|
-
|
|
233
|
-
- Extract `android:id="@+id/<name>"` — the `resourceId` for locators is
|
|
234
|
-
the bare name (e.g., `open_search`, not `id/open_search`).
|
|
235
|
-
- Extract `android:text` and `android:contentDescription` as fallback
|
|
236
|
-
locator identity fields.
|
|
237
|
-
- Note the widget type (Button, EditText, TextView, RecyclerView,
|
|
238
|
-
ScrollView, etc.) to understand what actions each element supports.
|
|
239
|
-
|
|
240
|
-
#### Handling Complex Layout Structures
|
|
241
|
-
|
|
242
|
-
Real Android layouts use several composition mechanisms. Handle each:
|
|
243
|
-
|
|
244
|
-
**`<include layout="@layout/foo" />`**:
|
|
245
|
-
- The included layout's views are merged into the parent at runtime.
|
|
246
|
-
- Recursively read the included layout file and collect its IDs as if
|
|
247
|
-
they were in the parent.
|
|
248
|
-
- An `<include>` may override the included root's `android:id` with its
|
|
249
|
-
own `android:id` attribute — note both the include ID and the included
|
|
250
|
-
layout's child IDs.
|
|
251
|
-
|
|
252
|
-
**`<merge>`**:
|
|
253
|
-
- `<merge>` has no ID itself. Its children are directly inlined into the
|
|
254
|
-
parent at inflation time.
|
|
255
|
-
- When you encounter `<merge>` as the root of an included layout, treat
|
|
256
|
-
its children as belonging to the including parent.
|
|
257
|
-
|
|
258
|
-
**`<layout>` (Data Binding)**:
|
|
259
|
-
- The `<layout>` tag wraps the actual root view. It may also contain
|
|
260
|
-
`<data>` elements (variable definitions).
|
|
261
|
-
- Look inside `<layout>` for the actual root view and its children.
|
|
262
|
-
Ignore the `<data>` section — it has no UI elements.
|
|
263
|
-
|
|
264
|
-
**`<ViewStub android:layout="@layout/foo" />`**:
|
|
265
|
-
- A `ViewStub` is lazily inflated. Its content is NOT in the initial
|
|
266
|
-
layout. The `android:inflatedId` attribute gives the ID of the
|
|
267
|
-
inflated root, and `android:layout` points to the layout resource.
|
|
268
|
-
- Note these elements but understand they may not be visible until
|
|
269
|
-
explicitly inflated at runtime.
|
|
270
|
-
|
|
271
|
-
**Duplicate IDs across layout files**:
|
|
272
|
-
- The same `@+id/submit` can appear in both `activity_main.xml` and
|
|
273
|
-
`activity_search.xml`. This is normal and NOT a conflict — each
|
|
274
|
-
layout is independent, and only one is active at a time.
|
|
275
|
-
- Do NOT try to deduplicate IDs across different layout files.
|
|
276
|
-
- At runtime, TapHound's `observe` command dumps the live layout, so
|
|
277
|
-
element resolution always happens against the currently displayed
|
|
278
|
-
screen, not against static XML.
|
|
279
|
-
- What matters for the Context is understanding which IDs exist and
|
|
280
|
-
what actions they support, so you can set `interactionPolicy`
|
|
281
|
-
correctly and so the step-generation prompt can make informed
|
|
282
|
-
decisions.
|
|
283
|
-
|
|
284
|
-
### 4c. Build files (Kotlin DSL or Groovy DSL)
|
|
285
|
-
|
|
286
|
-
Each module has either `build.gradle.kts` (Kotlin DSL) or `build.gradle`
|
|
287
|
-
(Groovy DSL), never both. Check which file exists before reading.
|
|
288
|
-
|
|
289
|
-
- Read the app module's build file for `applicationId` (Step 2) and
|
|
290
|
-
`namespace`. The syntax differs:
|
|
291
|
-
- Kotlin DSL: `applicationId = "..."`, `namespace = "..."`
|
|
292
|
-
- Groovy DSL: `applicationId "..."`, `namespace "..."`
|
|
293
|
-
- Check for `buildTypes` / `productFlavors` that might affect the
|
|
294
|
-
package name (suffixes like `.debug`). In Kotlin DSL these use `=`,
|
|
295
|
-
in Groovy they do not.
|
|
296
|
-
- Read `settings.gradle.kts` or `settings.gradle` (whichever exists) for
|
|
297
|
-
module includes if using the fallback method in Step 1.
|
|
298
|
-
- Note any `proguard` / `proguardFiles` rules that might strip logcat
|
|
299
|
-
tags (if Logcat calls are stripped in release builds, note this — it
|
|
300
|
-
affects expectation feasibility).
|
|
301
|
-
|
|
302
|
-
## Step 5: Verify Completeness
|
|
303
|
-
|
|
304
|
-
Before generating the Context JSON, verify that you have found ALL
|
|
305
|
-
relevant files. Incomplete coverage makes the Context useless for
|
|
306
|
-
staleness detection and leads to missing interaction policies.
|
|
307
|
-
|
|
308
|
-
### 5a. Activity completeness
|
|
309
|
-
|
|
310
|
-
Enumerate every `<activity>` declaration across ALL module manifests
|
|
311
|
-
(not just the `app` module). Use shell commands to ensure nothing is
|
|
312
|
-
missed:
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
# Find all manifest files (excluding build artifacts)
|
|
316
|
-
find . -name "AndroidManifest.xml" -not -path "*/build/*"
|
|
317
|
-
|
|
318
|
-
# Extract all activity names from all manifests
|
|
319
|
-
find . -name "AndroidManifest.xml" -not -path "*/build/*" \
|
|
320
|
-
-exec grep '<activity' {} + | sed 's/.*android:name="//' | sed 's/".*//'
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
For each Activity name found:
|
|
324
|
-
- If it starts with `.`, prepend the module's namespace to get the
|
|
325
|
-
fully qualified class name.
|
|
326
|
-
- Find the corresponding source file (`.kt` or `.java`) on disk.
|
|
327
|
-
- If the source file cannot be found (e.g., generated class, or class
|
|
328
|
-
from a third-party dependency), skip it but note it.
|
|
329
|
-
|
|
330
|
-
**You MUST include every Activity source file you find.** Missing
|
|
331
|
-
Activities means the Context cannot detect when those screens change,
|
|
332
|
-
and the AI agent will not know about their UI elements or Logcat tags.
|
|
333
|
-
|
|
334
|
-
### 5b. Layout completeness
|
|
335
|
-
|
|
336
|
-
For each Activity you found, identify its layout via
|
|
337
|
-
`setContentView(R.layout.<name>)` in the source. Then find the
|
|
338
|
-
corresponding layout XML:
|
|
339
|
-
|
|
340
|
-
```bash
|
|
341
|
-
# Find all layout XML files across all modules (excluding build artifacts)
|
|
342
|
-
find . -path "*/res/layout/*.xml" -not -path "*/build/*"
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
Include each layout file that is directly referenced by an Activity
|
|
346
|
-
you found. Also include layouts referenced via `<include>` from those
|
|
347
|
-
layouts (resolve transitively).
|
|
348
|
-
|
|
349
|
-
You may EXCLUDE:
|
|
350
|
-
- Layout files not referenced by any Activity (e.g., item layouts for
|
|
351
|
-
RecyclerView adapters, preference layouts) unless they contain
|
|
352
|
-
interactive elements the test Goal might touch.
|
|
353
|
-
- Debug-only or developer-tool layouts.
|
|
354
|
-
|
|
355
|
-
### 5c. Large project strategy
|
|
356
|
-
|
|
357
|
-
For projects with many modules (10+ Activities, 50+ layouts), use
|
|
358
|
-
systematic shell-based discovery rather than reading files one by one:
|
|
359
|
-
|
|
360
|
-
```bash
|
|
361
|
-
# Count activities per module
|
|
362
|
-
find . -name "AndroidManifest.xml" -not -path "*/build/*" \
|
|
363
|
-
-exec grep -c '<activity' {} +
|
|
364
|
-
|
|
365
|
-
# Count source files with Activity classes
|
|
366
|
-
find . \( -name "*.kt" -o -name "*.java" \) -not -path "*/build/*" \
|
|
367
|
-
-exec grep -l "extends.*Activity\|:.*Activity(" {} +
|
|
368
|
-
|
|
369
|
-
# Count layout files
|
|
370
|
-
find . -path "*/res/layout/*.xml" -not -path "*/build/*" | wc -l
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
If the project has hundreds of Activities/layouts, focus on:
|
|
374
|
-
- All Activities in the `app` module (these are the entry points).
|
|
375
|
-
- Activities in feature modules that a normal user flow can reach
|
|
376
|
-
(navigated to from app module Activities via `startActivity`).
|
|
377
|
-
- Exclude internal/debug Activities (database repair, process utilities,
|
|
378
|
-
install helpers) unless the Goal specifically targets them.
|
|
379
|
-
|
|
380
|
-
But DO NOT skip entire modules — if a feature module has Activities
|
|
381
|
-
reachable from the app's user flow, include them.
|
|
382
|
-
|
|
383
|
-
## Step 6: Compute SHA-256 Hashes
|
|
384
|
-
|
|
385
|
-
For every file you include in the Context manifest, compute its SHA-256
|
|
386
|
-
using this shell command (NEVER guess a hash):
|
|
387
|
-
|
|
388
|
-
```bash
|
|
389
|
-
node -e "const c=require('node:crypto');const f=require('node:fs');process.stdout.write(c.createHash('sha256').update(f.readFileSync('<relative-path>')).digest('hex'))"
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
The path must be relative to the Android project root (not the TapHound
|
|
393
|
-
repo root), use forward slashes, and must not start with `/` or contain
|
|
394
|
-
`..`.
|
|
395
|
-
|
|
396
|
-
## Step 6: Generate the Context JSON
|
|
397
|
-
|
|
398
|
-
Produce a JSON object with:
|
|
399
|
-
|
|
400
|
-
- `version`: `1`
|
|
401
|
-
- `packageName`: the `applicationId` from the app module's build file
|
|
402
|
-
(`build.gradle.kts` or `build.gradle`, per Step 2), or `package` from
|
|
403
|
-
manifest as fallback.
|
|
404
|
-
- `launchActivity`: fully qualified launch Activity class, per Step 3.
|
|
405
|
-
- `manifest.files`: list every source file you read that is relevant to
|
|
406
|
-
the UI structure. Include:
|
|
407
|
-
- All `AndroidManifest.xml` files (from app and library modules).
|
|
408
|
-
- All Kotlin/Java source files that define Activities, handle UI
|
|
409
|
-
interactions, or emit logcat tags used for expectations.
|
|
410
|
-
- All layout XML files that are referenced by Activities (directly via
|
|
411
|
-
`setContentView` or transitively via `<include>`).
|
|
412
|
-
- The app module's build file (`build.gradle.kts` or `build.gradle`,
|
|
413
|
-
whichever exists) for `applicationId`.
|
|
414
|
-
- `settings.gradle.kts` or `settings.gradle` (whichever exists) if
|
|
415
|
-
multi-module.
|
|
416
|
-
- Do NOT include build artifacts (`build/` directory), generated files,
|
|
417
|
-
Gradle wrapper scripts, resource values (strings.xml, colors.xml),
|
|
418
|
-
or themes unless they contain UI logic.
|
|
419
|
-
- Set `confidence` to `"sourceConfirmed"` for files you directly read.
|
|
420
|
-
- `interactionPolicy`:
|
|
421
|
-
- `allowedActions`: list ONLY actions the UI actually supports, derived
|
|
422
|
-
from source evidence. A Button supports `click`/`longClick`. An
|
|
423
|
-
EditText supports `inputText`. A scrollable container (ScrollView,
|
|
424
|
-
RecyclerView) supports `swipe`/`scrollTo`. System navigation supports
|
|
425
|
-
`back`. Any screen supports `wait`. Do NOT list all actions blindly
|
|
426
|
-
— if you found no `longClick` handlers in source, do not include
|
|
427
|
-
`longClick`.
|
|
428
|
-
- `confirmationRequiredActions`: **WARNING — this is per-action-TYPE,
|
|
429
|
-
not per-element.** Listing `click` here means EVERY click in the
|
|
430
|
-
entire app will require human TTY approval during generation, making
|
|
431
|
-
the process extremely tedious. Only list an action here if ALL
|
|
432
|
-
instances of that action in the app are potentially dangerous (e.g.,
|
|
433
|
-
an app where every click triggers a payment). In most apps, leave
|
|
434
|
-
this EMPTY — the Core risk evaluator handles per-step risk
|
|
435
|
-
assessment at runtime and will flag dangerous actions automatically.
|
|
436
|
-
- `forbiddenActions`: actions that are dangerous by default (payment,
|
|
437
|
-
account deletion, password changes, installing APKs, third-party app
|
|
438
|
-
navigation). If none apply, leave empty.
|
|
439
|
-
- No action may appear in both `allowedActions` and `forbiddenActions`.
|
|
440
|
-
- Every action in `confirmationRequiredActions` must also be in
|
|
441
|
-
`allowedActions`.
|
|
442
|
-
|
|
443
|
-
## Rules
|
|
444
|
-
|
|
445
|
-
- Never guess a SHA-256 hash. Always compute it with the shell command.
|
|
446
|
-
- Paths in `manifest.files` are relative to the Android project root,
|
|
447
|
-
use forward slashes, and must not start with `/` or contain `..`.
|
|
448
|
-
- The `packageName` in the Context must exactly match the Android
|
|
449
|
-
`applicationId` (or legacy `package` attribute). For dynamic
|
|
450
|
-
`applicationId` references, trace the full resolution chain and include
|
|
451
|
-
all files in that chain.
|
|
452
|
-
- The `launchActivity` must exactly match the class in the manifest.
|
|
453
|
-
- For multi-module projects, include files from all modules that
|
|
454
|
-
contribute to the UI — not just the `app` module. Use `./gradlew
|
|
455
|
-
projects` or the filesystem fallback to discover ALL modules.
|
|
456
|
-
- **Completeness is mandatory**: enumerate ALL `<activity>` entries from
|
|
457
|
-
ALL module manifests and include each Activity's source file. Missing
|
|
458
|
-
Activities means the Context cannot detect source changes and the AI
|
|
459
|
-
agent will not know about those screens.
|
|
460
|
-
- For layouts using `<include>`, `<merge>`, or `<layout>`, resolve
|
|
461
|
-
transitively to understand the full element set, but only hash the
|
|
462
|
-
actual XML files you read.
|
|
463
|
-
- Do not include build artifacts, generated code, or non-UI files in
|
|
464
|
-
`manifest.files`.
|
|
465
|
-
- `confirmationRequiredActions` is per-action-TYPE. Listing `click`
|
|
466
|
-
makes EVERY click require human approval. Leave empty unless ALL
|
|
467
|
-
instances of that action are dangerous.
|
|
468
|
-
- `allowedActions` must be derived from source evidence, not blanket
|
|
469
|
-
inclusion. If no source evidence supports an action, do not list it.
|
|
470
|
-
|
|
471
|
-
## Incremental Update Mode
|
|
472
|
-
|
|
473
|
-
When an existing Context is `stale` (file hashes changed) but the
|
|
474
|
-
structural counts match (same number of Activities and layouts on disk
|
|
475
|
-
as in the Context), you can do a targeted update instead of full
|
|
476
|
-
regeneration.
|
|
477
|
-
|
|
478
|
-
### Procedure
|
|
479
|
-
|
|
480
|
-
1. **Identify changed files**: Compare current file hashes with the
|
|
481
|
-
Context's `manifest.files` entries. The `context status` command
|
|
482
|
-
reports which files are stale.
|
|
483
|
-
|
|
484
|
-
2. **Re-hash changed files**: Recompute SHA-256 for each stale file:
|
|
485
|
-
```bash
|
|
486
|
-
node -e "const c=require('node:crypto');const f=require('node:fs');process.stdout.write(c.createHash('sha256').update(f.readFileSync('<relative-path>')).digest('hex'))"
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
3. **Re-analyze changed Activity source files**: For each stale `.kt` or
|
|
490
|
-
`.java` file, re-read it and check for:
|
|
491
|
-
- New `Log.i(tag, ...)` / `Log.d(tag, ...)` calls (new expect
|
|
492
|
-
candidates)
|
|
493
|
-
- New `setOnClickListener` / `setOnCheckedChangeListener` (new
|
|
494
|
-
actionable elements)
|
|
495
|
-
- New `startActivity(Intent(...))` (new navigation targets)
|
|
496
|
-
- Removed elements (locators/expectations that no longer apply)
|
|
497
|
-
Update `interactionPolicy.allowedActions` if new action types appeared.
|
|
498
|
-
|
|
499
|
-
4. **Re-analyze changed layout XML files**: For each stale layout, re-read
|
|
500
|
-
it and check for:
|
|
501
|
-
- New `android:id="@+id/<name>"` elements (new locator candidates)
|
|
502
|
-
- Removed elements
|
|
503
|
-
- Changed `android:text` or `android:contentDescription`
|
|
504
|
-
- New `<include>` / `<merge>` / `<ViewStub>` references
|
|
505
|
-
Resolve any new `<include>` references transitively.
|
|
506
|
-
|
|
507
|
-
5. **Update the Context JSON**: Replace the stale hashes with new ones.
|
|
508
|
-
Update `interactionPolicy` if needed. Do NOT change `packageName` or
|
|
509
|
-
`launchActivity` unless they actually changed.
|
|
510
|
-
|
|
511
|
-
6. **Validate**:
|
|
512
|
-
```bash
|
|
513
|
-
taphound context validate \
|
|
514
|
-
--project <project> \
|
|
515
|
-
--context .taphound/context/project-context.json \
|
|
516
|
-
--json
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### When NOT to use incremental update
|
|
520
|
-
|
|
521
|
-
Switch to full regeneration (Steps 1-7 above) if:
|
|
522
|
-
- The structural count check reveals new files on disk not in the Context.
|
|
523
|
-
- An Activity or layout was deleted (file in Context but not on disk).
|
|
524
|
-
- A new module was added (check `settings.gradle` or run `./gradlew
|
|
525
|
-
projects`).
|
|
526
|
-
- The `packageName` or `launchActivity` changed.
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Generate Next Proposed Step
|
|
2
|
-
|
|
3
|
-
You are generating the next proposed step in a TapHound journey. You have:
|
|
4
|
-
|
|
5
|
-
- **Goal**: the user's natural-language description of the test scenario.
|
|
6
|
-
- **Project Context**: the JSON you generated in Phase 1 (known UI elements,
|
|
7
|
-
locators, interaction policy).
|
|
8
|
-
- **Snapshot**: the current device state from `generation observe --json`,
|
|
9
|
-
including the `layout` array (all visible UI elements with their
|
|
10
|
-
properties) and the current `activity`.
|
|
11
|
-
- **Completed steps**: a list of steps that have already succeeded in this
|
|
12
|
-
session.
|
|
13
|
-
|
|
14
|
-
## Your Task
|
|
15
|
-
|
|
16
|
-
Determine the next single action that advances the Goal. Output one proposed
|
|
17
|
-
step JSON object (without the `binding` field — the caller adds binding from
|
|
18
|
-
the observe result).
|
|
19
|
-
|
|
20
|
-
## How to Decide
|
|
21
|
-
|
|
22
|
-
1. **Identify what remains**: Compare the Goal against completed steps. What
|
|
23
|
-
is the next logical action?
|
|
24
|
-
|
|
25
|
-
2. **Find the target element**: Look through `snapshot.layout` for an element
|
|
26
|
-
that matches the next intended action:
|
|
27
|
-
- Match by `resourceId` first (highest priority).
|
|
28
|
-
- If no `resourceId` match, match by `text`.
|
|
29
|
-
- If no `text` match, match by `contentDescription`.
|
|
30
|
-
- The element must be `enabled: true`.
|
|
31
|
-
- For `click`: prefer `clickable: true` elements.
|
|
32
|
-
- For `inputText`: the target should be `focusable: true` (an EditText).
|
|
33
|
-
Do not include a `locator` for `inputText` — the Core uses the focused
|
|
34
|
-
element.
|
|
35
|
-
- For `swipe`: the target should be `scrollable: true` with `bounds`.
|
|
36
|
-
- For `scrollTo`: specify both `locator` (target) and `container`
|
|
37
|
-
(scrollable parent).
|
|
38
|
-
|
|
39
|
-
3. **Determine activity.before**: This is `snapshot.activity` (the current
|
|
40
|
-
Activity class). The proposed step only includes `activity.before` —
|
|
41
|
-
never `activity.after`. The Core determines the after-Activity from
|
|
42
|
-
live device observation after executing the action.
|
|
43
|
-
|
|
44
|
-
4. **Add expect (optional)**: Only if there is a deterministic, verifiable
|
|
45
|
-
outcome:
|
|
46
|
-
- `element`: a specific element should appear after the action (e.g., a
|
|
47
|
-
search input field appears after clicking "open search").
|
|
48
|
-
- `logcat`: a specific log line should be emitted (e.g., the source code
|
|
49
|
-
shows `Log.i("SearchViewModel", "submitted query=" + query)` — use
|
|
50
|
-
`tag: "SearchViewModel"`, `pattern: "submitted query=..."`,
|
|
51
|
-
`match: "literal"`).
|
|
52
|
-
- `activity`: a specific Activity should be foregrounded.
|
|
53
|
-
- Do not add expectations you cannot verify from source code or Context.
|
|
54
|
-
- Do not invent log patterns that don't exist in the source.
|
|
55
|
-
|
|
56
|
-
## Output Format
|
|
57
|
-
|
|
58
|
-
A single JSON object matching one of the step types in
|
|
59
|
-
`schemas/proposed-step-envelope.json` `$defs/ProposedStep`, but **without**
|
|
60
|
-
the `binding` field. The caller wraps it with binding and snapshot.
|
|
61
|
-
|
|
62
|
-
Example (click):
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"action": "click",
|
|
66
|
-
"locator": { "resourceId": "open_search" },
|
|
67
|
-
"activity": {
|
|
68
|
-
"before": "dev.taphound.demo.MainActivity"
|
|
69
|
-
},
|
|
70
|
-
"expect": {
|
|
71
|
-
"type": "element",
|
|
72
|
-
"locator": { "resourceId": "search_input" },
|
|
73
|
-
"timeoutMs": 3000
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Example (inputText):
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"action": "inputText",
|
|
82
|
-
"text": "hello world",
|
|
83
|
-
"activity": {
|
|
84
|
-
"before": "dev.taphound.demo.SearchActivity"
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Rules
|
|
90
|
-
|
|
91
|
-
- Never use coordinates, visual guessing, or annotated-label fallback.
|
|
92
|
-
- The proposed step only includes `activity.before`, never `activity.after`.
|
|
93
|
-
The Core determines `after` from live device observation.
|
|
94
|
-
- Locator priority is fixed: `resourceId` > `text` > `contentDescription`.
|
|
95
|
-
Do not use multiple fields simultaneously unless that is the only way to
|
|
96
|
-
disambiguate.
|
|
97
|
-
- The `snapshot.layout` from `observe` is the live device layout — it is
|
|
98
|
-
the source of truth for element matching, not the static XML files from
|
|
99
|
-
Context generation. The same `resourceId` may appear in different layout
|
|
100
|
-
XML files, but only one layout is active at runtime. Match against what
|
|
101
|
-
`observe` returns.
|
|
102
|
-
- Activities from library/feature modules are valid navigation targets.
|
|
103
|
-
Use the fully qualified class name from the manifest or source.
|
|
104
|
-
- Do not include `binding` — the caller adds it from the observe result.
|
|
105
|
-
- Do not include `fallback` — proposals do not support fallback.
|
|
106
|
-
- If no actionable element matches the Goal, return:
|
|
107
|
-
`{"error": "no matching element", "reason": "..."}`
|
|
108
|
-
- If the Goal appears complete, return `{"complete": true}` instead of a
|
|
109
|
-
step.
|