@aarwitz/tapp 0.17.0-rc.15 → 0.17.0-rc.16
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/.claude-plugin/plugin.json +2 -2
- package/package.json +1 -1
- package/scripts/ci-gate.sh +42 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tapp",
|
|
3
3
|
"description": "Give Claude hands and eyes on iOS, Android, and web apps, with exploration, replayable flows, evidence, and deterministic CI gates.",
|
|
4
|
-
"version": "0.17.0-rc.
|
|
4
|
+
"version": "0.17.0-rc.16",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Aaron Horowitz",
|
|
7
7
|
"url": "https://github.com/aarwitz"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"command": "npx",
|
|
25
25
|
"args": [
|
|
26
26
|
"-y",
|
|
27
|
-
"@aarwitz/tapp@0.17.0-rc.
|
|
27
|
+
"@aarwitz/tapp@0.17.0-rc.16",
|
|
28
28
|
"mcp"
|
|
29
29
|
],
|
|
30
30
|
"cwd": "${CLAUDE_PROJECT_DIR}"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aarwitz/tapp",
|
|
3
|
-
"version": "0.17.0-rc.
|
|
3
|
+
"version": "0.17.0-rc.16",
|
|
4
4
|
"mcpName": "io.github.aarwitz/tapp",
|
|
5
5
|
"description": "Agent-driven app testing for iOS, Android, and web—real screens, replayable flows, and deterministic CI gates.",
|
|
6
6
|
"license": "MIT",
|
package/scripts/ci-gate.sh
CHANGED
|
@@ -86,6 +86,48 @@ TAPP_PROJECT_ARTIFACTS=""
|
|
|
86
86
|
if [[ -n "$PROJECT_DIR" ]]; then
|
|
87
87
|
[[ -d "$PROJECT_DIR/.tapp" ]] && TAPP_PROJECT_ARTIFACTS="$PROJECT_DIR/.tapp"
|
|
88
88
|
fi
|
|
89
|
+
|
|
90
|
+
# A repository-connected gate must retain the stable application-model target identity in its
|
|
91
|
+
# report. Otherwise its first passing report cannot become a target-scoped baseline, even though
|
|
92
|
+
# Tapp already knows exactly which application it built and exercised. Explicit --target-key still
|
|
93
|
+
# wins (the composite Action supplies one); the CLI derives it only when the repository model makes
|
|
94
|
+
# the selection conclusive. Multi-target repositories remain strict and print the available ids.
|
|
95
|
+
if [[ -z "$TARGET_KEY" && -n "$TAPP_PROJECT_ARTIFACTS" && -f "$TAPP_PROJECT_ARTIFACTS/application-model.json" ]]; then
|
|
96
|
+
if ! TARGET_KEY="$(node - "$TAPP_PROJECT_ARTIFACTS/application-model.json" "$PLATFORM" "$WEB_TARGET" "$APP_ID" "$BUNDLE_ID" <<'NODE'
|
|
97
|
+
const fs = require("fs");
|
|
98
|
+
const [modelPath, platform, webTarget, appId, bundleId] = process.argv.slice(2);
|
|
99
|
+
let model;
|
|
100
|
+
try { model = JSON.parse(fs.readFileSync(modelPath, "utf8")); }
|
|
101
|
+
catch (error) { console.error(`❌ Could not read application model ${modelPath}: ${error.message}`); process.exit(2); }
|
|
102
|
+
if (model?.kind !== "tapp-application-model" || !Array.isArray(model.targets)) {
|
|
103
|
+
console.error("❌ Expected .tapp/application-model.json to contain a Tapp application model");
|
|
104
|
+
process.exit(2);
|
|
105
|
+
}
|
|
106
|
+
let candidates = model.targets.filter((target) => target.platform === platform);
|
|
107
|
+
const requested = platform === "web" ? webTarget : platform === "android" ? appId : bundleId;
|
|
108
|
+
if (requested) {
|
|
109
|
+
const normalized = requested.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
110
|
+
candidates = candidates.filter((target) => {
|
|
111
|
+
const identities = [target.id, target.name, target.sourcePath];
|
|
112
|
+
if (platform === "android") identities.push(target.runtime?.applicationId);
|
|
113
|
+
if (platform === "ios") identities.push(target.runtime?.bundleId);
|
|
114
|
+
return identities.some((value) => String(value || "").replaceAll("\\", "/") === normalized);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (candidates.length !== 1) {
|
|
118
|
+
const available = model.targets.filter((target) => target.platform === platform);
|
|
119
|
+
console.error(candidates.length
|
|
120
|
+
? `❌ Multiple ${platform} targets match. Pass --target-key explicitly: ${candidates.map((target) => target.id).join(", ")}`
|
|
121
|
+
: `❌ Could not resolve one ${platform} target from the application model.${available.length ? ` Available target ids: ${available.map((target) => target.id).join(", ")}` : ""}`);
|
|
122
|
+
process.exit(2);
|
|
123
|
+
}
|
|
124
|
+
process.stdout.write(String(candidates[0].id));
|
|
125
|
+
NODE
|
|
126
|
+
)"; then
|
|
127
|
+
exit 2
|
|
128
|
+
fi
|
|
129
|
+
echo "Target identity: $PLATFORM:$TARGET_KEY (from .tapp/application-model.json)"
|
|
130
|
+
fi
|
|
89
131
|
[[ -z "$FLOWS" && -n "$TAPP_PROJECT_ARTIFACTS" && -d "$TAPP_PROJECT_ARTIFACTS/flows" ]] && FLOWS="$TAPP_PROJECT_ARTIFACTS/flows/*.yml"
|
|
90
132
|
[[ "$PLATFORM" == "web" && -z "$SCENARIOS" && -n "$TAPP_PROJECT_ARTIFACTS" && -d "$TAPP_PROJECT_ARTIFACTS/scenarios" ]] && SCENARIOS="$TAPP_PROJECT_ARTIFACTS/scenarios/*.yml"
|
|
91
133
|
[[ -z "$CONTRACTS" && -n "$TAPP_PROJECT_ARTIFACTS" && -d "$TAPP_PROJECT_ARTIFACTS/contracts" ]] && CONTRACTS="$TAPP_PROJECT_ARTIFACTS/contracts/*.contract.ts"
|