ai-fob 1.10.1 → 1.11.2
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 +26 -1
- package/assets/agents/build-validator-agent.md +3 -2
- package/assets/commands/build-phase-V2.md +30 -25
- package/assets/commands/migrate-runtime-config.md +248 -0
- package/assets/commands/setup-project.md +101 -80
- package/assets/pi/agents/build-phase-build-validator.md +6 -6
- package/assets/pi/extensions/inter-agent-team/README.md +55 -2
- package/assets/pi/extensions/inter-agent-team/registry.ts +3 -1
- package/assets/pi/extensions/inter-agent-team/runtime/claude-code-adapter.ts +27 -0
- package/assets/pi/extensions/inter-agent-team/runtime/pty-session.ts +27 -0
- package/assets/pi/extensions/inter-agent-team/runtime/runtime-adapter.ts +17 -2
- package/assets/pi/extensions/inter-agent-team/schema.ts +3 -0
- package/assets/pi/extensions/inter-agent-team/tool.ts +6 -5
- package/assets/pi/extensions/inter-agent-team/types.ts +6 -1
- package/assets/pi/extensions/inter-agent-team/ui/teammate-overlay.ts +32 -5
- package/assets/pi/extensions/inter-agent-team/widget.ts +1 -1
- package/assets/pi/prompts/build-feature-interagent.md +394 -0
- package/assets/pi/prompts/build-phase.md +31 -24
- package/assets/pi/skills/testing-and-validation/SKILL.md +78 -83
- package/assets/skills/testing-and-validation/SKILL.md +76 -87
- package/bin/install.js +124 -2
- package/manifest.json +6 -4
- package/package.json +1 -1
- package/assets/pi/skills/testing-and-validation/auth.example.json +0 -47
- package/assets/skills/testing-and-validation/auth.example.json +0 -47
package/README.md
CHANGED
|
@@ -78,12 +78,37 @@ All Claude Code presets (coding + cc-assets). Does NOT include `pi-coding`, `pi-
|
|
|
78
78
|
Run `npx ai-fob@latest --preset coding` to upgrade.
|
|
79
79
|
|
|
80
80
|
- **Unmodified files** are updated to the latest version
|
|
81
|
-
- **Locally modified customizable files** (like `
|
|
81
|
+
- **Locally modified customizable files** (like `statusline.sh`) are preserved -- the new version is saved as `.ai-fob-new` for you to compare
|
|
82
82
|
- **Your custom assets** (agents, skills, commands you created) are never touched
|
|
83
83
|
- **settings.json** is deep-merged -- your existing settings are preserved, new keys are added
|
|
84
|
+
- **Per-project runtime configuration** lives in `runtime/` at the project root (not inside `.claude/` or `.pi/`) and is never overwritten by ai-fob. Populate `runtime/project.json` via `/setup-project`; copy `runtime/auth.example.json` to `runtime/auth.json` and fill local test credentials when needed (the latter is gitignored).
|
|
84
85
|
|
|
85
86
|
A `.ai-fob.json` file in your `.claude/` directory tracks what was installed and detects modifications.
|
|
86
87
|
|
|
88
|
+
## Upgrading from v1.10.x
|
|
89
|
+
|
|
90
|
+
v1.11 moves per-project credentials (`auth.json`) and adds a per-project `project.json` for scripts/URL/mobile config. Both live in a shared `runtime/` directory at the project root, replacing the v1.10 per-skill `.claude/skills/testing-and-validation/auth.json` (and Pi equivalent).
|
|
91
|
+
|
|
92
|
+
Two-step upgrade (the migration command ships *in* v1.11, so the package upgrade comes first):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# 1. Install v1.11 — this also installs the /migrate-runtime-config command.
|
|
96
|
+
# The upgrade overwrites your v1.10 SKILL.md files (the customizable
|
|
97
|
+
# carve-out is gone), which is intentional: per-project values now live
|
|
98
|
+
# in runtime/project.json instead.
|
|
99
|
+
npx ai-fob@latest --preset coding
|
|
100
|
+
|
|
101
|
+
# 2. In Claude Code, from your project root, run the one-shot migration:
|
|
102
|
+
/migrate-runtime-config
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The migration command:
|
|
106
|
+
- Atomically moves `.claude/skills/testing-and-validation/auth.json` (and Pi equivalent) to `runtime/auth.json`.
|
|
107
|
+
- Recovers your previous v1.10 SKILL.md tables to populate `runtime/project.json`. Because step 1 already overwrote the on-disk SKILL.md, the parser walks `git history` for the pre-upgrade version: it tries `git show HEAD:<path>` first, then walks back through the last 20 commits touching that file.
|
|
108
|
+
- Falls back to a template-only `runtime/project.json` (all values `null`) only when no git history is available or no commit of the v1.10 SKILL.md exists. In that case, populate `runtime/project.json` manually from your previous scripts.
|
|
109
|
+
- Deletes the orphan v1.10 files from both skill directories.
|
|
110
|
+
- Prints a verification summary showing which source it parsed from.
|
|
111
|
+
|
|
87
112
|
## License
|
|
88
113
|
|
|
89
114
|
MIT
|
|
@@ -38,7 +38,8 @@ For BLOCKED checks and aggregate-result derivation, follow the **Validation Taxo
|
|
|
38
38
|
- Record `criticality`, `executor`, `risk` from the taxonomy.
|
|
39
39
|
- Apply the **overall-result derivation** rules to compute the aggregate result: `pass | fail | blocked | pass-with-followups`.
|
|
40
40
|
- Apply the **self-consistency requirement**: if no terminal blockers exist, the overall result must be `pass-with-followups`, not `blocked`.
|
|
41
|
-
- For auth-required browser checks, follow the **
|
|
41
|
+
- For auth-required browser checks, follow the **Project Runtime Configuration** section of the same skill (look up `runtime/auth.json` at the project root; never mark auth BLOCKED if valid credentials are configured; never print raw secrets).
|
|
42
|
+
- For project-specific scripts, testing URL, and mobile devices, read from `runtime/project.json` at the project root.
|
|
42
43
|
|
|
43
44
|
The detailed check schema (Criticality/Executor/Risk columns, `[HL]` prefix semantics, fix-cycle interaction) is provided by the calling command's spawn prompt — this agent applies the taxonomy generically and lets the spawn prompt specify column layout.
|
|
44
45
|
|
|
@@ -48,7 +49,7 @@ The calling prompt provides a numbered list of checks to run. Execute every chec
|
|
|
48
49
|
|
|
49
50
|
1. Read the check name and description from the prompt
|
|
50
51
|
2. Determine the check type from the description and execute accordingly:
|
|
51
|
-
- **Shell command checks**: Run the command via Bash. Record exit code and output. PASS if exit code is 0 and output matches expectations; FAIL otherwise. Include the first 50 lines of output on failure. Use the exact scripts from
|
|
52
|
+
- **Shell command checks**: Run the command via Bash. Record exit code and output. PASS if exit code is 0 and output matches expectations; FAIL otherwise. Include the first 50 lines of output on failure. Use the exact scripts from `runtime/project.json` (read `scripts.*` paths) -- do not guess or improvise commands. If a configured script path does not exist, FAIL the check with "Script not found: {path}".
|
|
52
53
|
- **File verification checks**: Use Read/Grep/Glob to verify file existence, content patterns, and structural requirements. PASS if all conditions met; FAIL otherwise.
|
|
53
54
|
- **Browser verification checks**: Use the agent-browser skill workflow -- navigate (`agent-browser open <url>`), snapshot (`agent-browser snapshot -i`), interact, re-snapshot. Use `agent-browser screenshot` to capture visual state as evidence. Always check the browser console for JavaScript errors as part of browser checks. Compare actual page state against expected outcomes described in the check. Close the browser session when all browser checks are complete (`agent-browser close`).
|
|
54
55
|
3. Record specific findings (command output, file paths verified, screenshots taken, elements observed)
|
|
@@ -989,19 +989,27 @@ Store the total check count as `BUILD_CHECK_COUNT`. Store the count of HL criter
|
|
|
989
989
|
|
|
990
990
|
Determine if browser checks exist: scan the assembled check list for any check that mentions "browser", "agent-browser", "navigate", "page", "UI", or "localhost". Store as `HAS_BROWSER_CHECKS` (true/false).
|
|
991
991
|
|
|
992
|
-
If `HAS_BROWSER_CHECKS` is true: Read
|
|
993
|
-
- If `MOBILE_PRIMARY_DEVICE` is
|
|
992
|
+
If `HAS_BROWSER_CHECKS` is true: Read `runtime/project.json`. Extract `mobile.primaryDevice` and `mobile.secondaryDevice`. Store as `MOBILE_PRIMARY_DEVICE` and `MOBILE_SECONDARY_DEVICE`. Determine `HAS_MOBILE_CHECKS`:
|
|
993
|
+
- If `MOBILE_PRIMARY_DEVICE` is `null` (or missing): set `HAS_MOBILE_CHECKS = false`.
|
|
994
994
|
- Otherwise: set `HAS_MOBILE_CHECKS = true`.
|
|
995
995
|
|
|
996
996
|
If `HAS_BROWSER_CHECKS` is false: set `HAS_MOBILE_CHECKS = false`.
|
|
997
997
|
|
|
998
|
+
Also read from `runtime/project.json`:
|
|
999
|
+
- `testing.testingUrl` → store as `TESTING_URL` (used for browser checks and dev-server readiness probes).
|
|
1000
|
+
- `scripts.devAll` → store as `DEV_SERVER_SCRIPT` (used to start the dev server).
|
|
1001
|
+
|
|
1002
|
+
If `runtime/project.json` is missing, OR `testing.testingUrl` is null/missing, OR `scripts.devAll` is null/missing when `HAS_BROWSER_CHECKS` is true: warn "runtime/project.json is missing or incomplete. Browser checks will be marked BLOCKED with terminal severity." Set `HAS_BROWSER_CHECKS = false` and skip 5b (dev server cannot start without a configured script).
|
|
1003
|
+
|
|
1004
|
+
Derive `TESTING_URL_PORT` by parsing the port from `TESTING_URL` (default 3000 if no explicit port — e.g. `http://localhost` → 80, but localhost without port is treated as 3000 for back-compat unless an explicit port is present).
|
|
1005
|
+
|
|
998
1006
|
#### 5b. Start Dev Server (if needed)
|
|
999
1007
|
|
|
1000
1008
|
If `HAS_BROWSER_CHECKS` is true:
|
|
1001
1009
|
|
|
1002
|
-
1. Kill any existing process on
|
|
1003
|
-
2. Start the dev server via Bash with `run_in_background: true`:
|
|
1004
|
-
3. Wait for the server to be ready: poll `curl -s -o /dev/null -w "%{http_code}"
|
|
1010
|
+
1. Kill any existing process on `TESTING_URL_PORT`: run `lsof -ti:{TESTING_URL_PORT} | xargs kill -9 2>/dev/null` via Bash. Ignore errors (no process on port is fine).
|
|
1011
|
+
2. Start the dev server via Bash with `run_in_background: true`: `{DEV_SERVER_SCRIPT} > /tmp/dev-server.log 2>&1 &` (from `runtime/project.json` `scripts.devAll`). The trailing `&` is CRITICAL — it ensures the shell backgrounds the process so the Bash call returns immediately regardless of the `run_in_background` parameter.
|
|
1012
|
+
3. Wait for the server to be ready: poll `curl -s -o /dev/null -w "%{http_code}" {TESTING_URL}` via Bash every 3 seconds, up to 60 seconds. A response of 200 or 3xx means ready.
|
|
1005
1013
|
4. If no successful response within 60 seconds: warn "Dev server did not start within 60 seconds. Browser checks may fail." Proceed anyway -- the validator will FAIL browser checks if the server is unreachable.
|
|
1006
1014
|
5. Store `DEV_SERVER_STARTED = true`.
|
|
1007
1015
|
|
|
@@ -1031,26 +1039,25 @@ Read the build report(s) for context on what was built:
|
|
|
1031
1039
|
|
|
1032
1040
|
## Dev Server
|
|
1033
1041
|
{If DEV_SERVER_STARTED is true:
|
|
1034
|
-
"A dev server is already running at
|
|
1042
|
+
"A dev server is already running at {TESTING_URL} (from runtime/project.json `testing.testingUrl`). Use this URL for all browser-based checks. Do NOT start your own dev server."
|
|
1035
1043
|
If DEV_SERVER_STARTED is false:
|
|
1036
1044
|
"No dev server is running. There are no browser checks in this validation."}
|
|
1037
1045
|
|
|
1038
1046
|
## Test Credentials
|
|
1039
|
-
{Look up
|
|
1040
|
-
|
|
1041
|
-
Source resolution:
|
|
1042
|
-
PRIMARY: `.claude/skills/testing-and-validation/auth.json` if it exists. Read `browserAuth.enabled`, `browserAuth.loginUrl`, `browserAuth.postLoginUrl`, `browserAuth.users.primary.username`, `browserAuth.users.primary.password`.
|
|
1043
|
-
FALLBACK: the Test Credentials section of `.claude/skills/testing-and-validation/SKILL.md` (Login URL / Username / Password / Post-Login URL).
|
|
1047
|
+
{Look up `runtime/auth.json` (the gitignored, project-root credentials file). Read `browserAuth.enabled`, `browserAuth.loginUrl`, `browserAuth.postLoginUrl`, `browserAuth.users.primary.username`, `browserAuth.users.primary.password`.
|
|
1044
1048
|
|
|
1045
1049
|
Then branch:
|
|
1046
1050
|
|
|
1047
|
-
If
|
|
1051
|
+
If `runtime/auth.json` does NOT exist:
|
|
1052
|
+
"Test credentials are NOT available. Browser checks that require authentication MUST be marked as BLOCKED with severity classification per the Validation Taxonomy in the testing-and-validation skill. Use reason: 'runtime/auth.json not present — user must copy runtime/auth.example.json to runtime/auth.json and populate.' Mark severity as non-terminal if substitute evidence exists; mark terminal if the entire phase depends on authenticated browser flow."
|
|
1053
|
+
|
|
1054
|
+
Else if browserAuth.enabled is true AND primary username is set AND is NOT "REPLACE_WITH_TEST_USERNAME":
|
|
1048
1055
|
"Test credentials are configured. You MUST authenticate before running browser checks that require a logged-in session.
|
|
1049
1056
|
|
|
1050
|
-
- Login URL: {browserAuth.loginUrl
|
|
1057
|
+
- Login URL: {browserAuth.loginUrl}
|
|
1051
1058
|
- Username: [REDACTED — present]
|
|
1052
1059
|
- Password: [REDACTED — present]
|
|
1053
|
-
- Post-Login URL: {browserAuth.postLoginUrl
|
|
1060
|
+
- Post-Login URL: {browserAuth.postLoginUrl}
|
|
1054
1061
|
|
|
1055
1062
|
Authentication procedure (use the agent-browser skill workflow):
|
|
1056
1063
|
1. Open the Login URL: `agent-browser open {Login URL}`
|
|
@@ -1060,23 +1067,21 @@ Read the build report(s) for context on what was built:
|
|
|
1060
1067
|
5. Click the submit/login button
|
|
1061
1068
|
6. Wait for navigation to the Post-Login URL: `agent-browser wait --url \"**{Post-Login URL path}\"`
|
|
1062
1069
|
7. Take a snapshot to confirm successful login
|
|
1063
|
-
8. Save the authenticated browser state: `agent-browser state save browser-state.json` (NOTE: this is the agent-browser playwright state file; it is DISTINCT from the credentials file `auth.json`
|
|
1070
|
+
8. Save the authenticated browser state: `agent-browser state save browser-state.json` (NOTE: this is the agent-browser playwright state file; it is DISTINCT from the credentials file `runtime/auth.json`)
|
|
1064
1071
|
9. For subsequent browser checks, load the saved state: `agent-browser state load browser-state.json`
|
|
1065
1072
|
|
|
1066
1073
|
REDACTION REQUIREMENT: Never print raw usernames, passwords, API keys, webhook secrets, or full credential values in your report, evidence, or summary. Redact as `[REDACTED]` or report only presence/absence. Failure to redact must be treated as a critical reporting bug.
|
|
1067
1074
|
|
|
1068
1075
|
IMPORTANT: Because credentials are configured, you MUST NOT mark any browser check as BLOCKED due to authentication requirements. If authentication fails, mark the check as FAIL (not BLOCKED) and include the error details with credentials redacted."
|
|
1069
1076
|
|
|
1070
|
-
|
|
1077
|
+
Else if browserAuth.enabled is false:
|
|
1071
1078
|
"This project does not require authentication for browser tests. No login step is needed."
|
|
1072
1079
|
|
|
1073
|
-
|
|
1074
|
-
"Test credentials have NOT been
|
|
1080
|
+
Else (auth.json exists, browserAuth.enabled is true, but primary username is still the placeholder):
|
|
1081
|
+
"Test credentials have NOT been populated. runtime/auth.json exists with `browserAuth.enabled: true` but `users.primary.username` is still `REPLACE_WITH_TEST_USERNAME`. Browser checks that require authentication MUST be marked as BLOCKED with severity classification per the Validation Taxonomy. Use reason: 'runtime/auth.json present but credentials are placeholders — user must populate users.primary.username/password.' Mark severity as non-terminal if substitute evidence exists; mark terminal if the entire phase depends on authenticated browser flow."}
|
|
1075
1082
|
|
|
1076
1083
|
## Mobile Device Testing
|
|
1077
|
-
{
|
|
1078
|
-
|
|
1079
|
-
If HAS_MOBILE_CHECKS is true (Primary Device is NOT "NONE"):
|
|
1084
|
+
{If HAS_MOBILE_CHECKS is true (`mobile.primaryDevice` in runtime/project.json is NOT null):
|
|
1080
1085
|
"Mobile viewport testing is configured for this project. After completing each browser check at the default desktop viewport, you MUST repeat the visual/layout portions of that check at the mobile viewport.
|
|
1081
1086
|
|
|
1082
1087
|
Mobile testing procedure (use the agent-browser skill):
|
|
@@ -1086,13 +1091,13 @@ Read the build report(s) for context on what was built:
|
|
|
1086
1091
|
4. Take a snapshot to verify layout at mobile viewport: `agent-browser snapshot -i`
|
|
1087
1092
|
5. Take a screenshot for visual evidence: `agent-browser screenshot`
|
|
1088
1093
|
6. Verify the page renders correctly at the mobile viewport -- no overlapping elements, no horizontal scrolling, no truncated content, no inaccessible interactive elements
|
|
1089
|
-
7. Reset to desktop viewport when done: `agent-browser set viewport 1920 1080`{If MOBILE_SECONDARY_DEVICE is not
|
|
1094
|
+
7. Reset to desktop viewport when done: `agent-browser set viewport 1920 1080`{If MOBILE_SECONDARY_DEVICE is not null:
|
|
1090
1095
|
8. Repeat steps 2-7 with the secondary device: `agent-browser set device \"{MOBILE_SECONDARY_DEVICE}\"`}
|
|
1091
1096
|
|
|
1092
1097
|
For each browser check, report desktop and mobile results separately. If a check passes at desktop but fails at mobile, the overall check result is FAIL. Include the device name in the findings (e.g., 'FAIL at iPhone 12 Pro: navigation menu overlaps content')."
|
|
1093
1098
|
|
|
1094
1099
|
If HAS_MOBILE_CHECKS is false:
|
|
1095
|
-
"Mobile viewport testing is not configured (
|
|
1100
|
+
"Mobile viewport testing is not configured (`mobile.primaryDevice` is null in runtime/project.json). All browser checks run at the default desktop viewport only."}
|
|
1096
1101
|
|
|
1097
1102
|
## Validation Checks ({BUILD_CHECK_COUNT} -- run ALL of these)
|
|
1098
1103
|
|
|
@@ -1164,7 +1169,7 @@ Then branch on `result`:
|
|
|
1164
1169
|
- **If `result: pass-with-followups`**: Set `BUILD_VALIDATION_RESULT = "pass-with-followups"`. Extract the same fields. The build is accepted; non-terminal follow-ups will be surfaced in the phase completion report for human action. Proceed to 5f (Cleanup). Do NOT enter the fix loop — non-terminal blockers are operator/dashboard/external work, not code defects.
|
|
1165
1170
|
- **If `result: fail`**: Extract all five fields. Proceed to 5e (Fix and Re-validate).
|
|
1166
1171
|
- **If `result: blocked`**: Extract all five fields. This means at least one TERMINAL blocker exists. Auth-credentials recovery check (constrained):
|
|
1167
|
-
- Review each terminal BLOCKED check reason. If a BLOCKED check cites "authentication", "login", "credentials", or "authenticated session" AND `auth.json` is present with `browserAuth.enabled: true` AND `users.primary.username` is set
|
|
1172
|
+
- Review each terminal BLOCKED check reason. If a BLOCKED check cites "authentication", "login", "credentials", or "authenticated session" AND `runtime/auth.json` is present with `browserAuth.enabled: true` AND `users.primary.username` is set and is not `"REPLACE_WITH_TEST_USERNAME"` AND this is the FIRST cycle (BUILD_VALIDATION_CYCLE == 1) AND the check has no documented substitute evidence: re-spawn the validator ONCE without incrementing BUILD_VALIDATION_CYCLE. Log: "Validator marked auth-requiring check as BLOCKED despite configured credentials on first cycle. Re-running once without cycle increment."
|
|
1168
1173
|
- The no-increment recovery is allowed ONLY when ALL of the conditions above hold. On any subsequent cycle, on any non-auth-related blocker, or when credentials are unconfigured, increment the cycle normally and treat the result as terminal-blocked.
|
|
1169
1174
|
- If recovery does not apply, set `BUILD_VALIDATION_RESULT = "blocked"`. Do NOT enter the fix loop — genuinely BLOCKED checks cannot be fixed by a builder agent. Proceed to 5f (Cleanup). The terminal blocked checks will be surfaced in the phase completion report for human action.
|
|
1170
1175
|
|
|
@@ -1257,7 +1262,7 @@ If GIT_AVAILABLE == true:
|
|
|
1257
1262
|
##### 5e-iii. Dev server check
|
|
1258
1263
|
|
|
1259
1264
|
If DEV_SERVER_STARTED == true:
|
|
1260
|
-
1. Check if the dev server is still responding: run `curl -s -o /dev/null -w "%{http_code}"
|
|
1265
|
+
1. Check if the dev server is still responding: run `curl -s -o /dev/null -w "%{http_code}" {TESTING_URL}` via Bash.
|
|
1261
1266
|
2. If NOT responding (no 200/3xx): restart the dev server using the same approach as 5b (kill port, start background, poll). Update any process tracking.
|
|
1262
1267
|
3. If responding: no action needed. Hot reload should pick up code changes for most frameworks.
|
|
1263
1268
|
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: One-shot migration from the v1.10 skill-local auth.json layout to the v1.11 root-level runtime/ layout. Moves credentials, parses old SKILL.md tables into runtime/project.json, deletes orphan files.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Migrate Runtime Config (v1.10 → v1.11)
|
|
6
|
+
|
|
7
|
+
This command is for projects that were set up under ai-fob **v1.10.x**, which placed `auth.json` and `auth.example.json` inside each skill directory (`.claude/skills/testing-and-validation/` and `.pi/skills/testing-and-validation/`). v1.11.0 consolidates that configuration into a shared `runtime/` directory at the project root, plus a new `runtime/project.json` for scripts/testing/mobile.
|
|
8
|
+
|
|
9
|
+
Run this command ONCE **after** running `npx ai-fob@latest --preset coding` (the upgrade is what installs this command in the first place). The upgrade overwrites your v1.10 `SKILL.md` files before you can invoke the migration, so this command walks `git history` to recover the pre-upgrade SKILL.md and parse its tables. It is idempotent — running a second time detects the already-migrated state and exits cleanly.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
- You just upgraded to v1.11 (the new SKILL.md was installed) AND
|
|
14
|
+
- You have `.claude/skills/testing-and-validation/auth.json` or `.pi/skills/testing-and-validation/auth.json` on disk OR your git history contains a v1.10-shape SKILL.md, AND
|
|
15
|
+
- You do not yet have a `runtime/` directory at the project root.
|
|
16
|
+
|
|
17
|
+
If neither of the v1.10 files exist (e.g. fresh project), skip this command — run `/setup-project` for a fresh scaffold instead.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
### Step 0: Pre-flight
|
|
22
|
+
|
|
23
|
+
1. Determine `PROJECT_ROOT` (current working directory).
|
|
24
|
+
2. Check whether `runtime/` already exists at the project root.
|
|
25
|
+
- If `runtime/project.json` exists AND `runtime/auth.example.json` exists: print `Already migrated. runtime/ exists at <PROJECT_ROOT>/runtime/. Exiting.` and STOP.
|
|
26
|
+
- If `runtime/` exists but is partial (e.g. only `auth.json`): print a warning, list what's there, and ask the user whether to continue (which will fill in the missing template/.gitignore files but not overwrite existing files).
|
|
27
|
+
3. Check whether any v1.10 source exists:
|
|
28
|
+
- `CLAUDE_AUTH_JSON` = `.claude/skills/testing-and-validation/auth.json` (may or may not exist)
|
|
29
|
+
- `CLAUDE_AUTH_EXAMPLE` = `.claude/skills/testing-and-validation/auth.example.json`
|
|
30
|
+
- `CLAUDE_GITIGNORE` = `.claude/skills/testing-and-validation/.gitignore`
|
|
31
|
+
- `PI_AUTH_JSON` = `.pi/skills/testing-and-validation/auth.json`
|
|
32
|
+
- `PI_AUTH_EXAMPLE` = `.pi/skills/testing-and-validation/auth.example.json`
|
|
33
|
+
- `PI_GITIGNORE` = `.pi/skills/testing-and-validation/.gitignore`
|
|
34
|
+
- `CLAUDE_SKILL_MD` = `.claude/skills/testing-and-validation/SKILL.md`
|
|
35
|
+
- `PI_SKILL_MD` = `.pi/skills/testing-and-validation/SKILL.md`
|
|
36
|
+
4. If neither `CLAUDE_AUTH_JSON` nor `PI_AUTH_JSON` exists AND no v1.10-shaped SKILL.md tables are present, print: `No v1.10 runtime configuration detected. Nothing to migrate. Run /setup-project for a fresh scaffold.` and STOP.
|
|
37
|
+
5. Initialize a `MIGRATION_LOG` array — every action taken gets appended for the final report.
|
|
38
|
+
|
|
39
|
+
### Step 1: Create runtime/ with templates and .gitignore
|
|
40
|
+
|
|
41
|
+
1. Create the directory `runtime/` (if it does not already exist).
|
|
42
|
+
|
|
43
|
+
2. Write `runtime/auth.example.json` (only if it does not already exist) with this content verbatim:
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"$schemaComment": "Copy this file to runtime/auth.json and fill local/dev-only values. Never commit runtime/auth.json.",
|
|
47
|
+
"browserAuth": {
|
|
48
|
+
"enabled": false,
|
|
49
|
+
"loginUrl": "http://localhost:3000/login",
|
|
50
|
+
"postLoginUrl": "http://localhost:3000/dashboard",
|
|
51
|
+
"users": {
|
|
52
|
+
"primary": { "username": "REPLACE_WITH_TEST_USERNAME", "password": "REPLACE_WITH_TEST_PASSWORD" },
|
|
53
|
+
"secondary": { "username": "REPLACE_WITH_SECONDARY_TEST_USERNAME", "password": "REPLACE_WITH_SECONDARY_TEST_PASSWORD" }
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"providers": {
|
|
57
|
+
"clerk": { "enabled": false, "publishableKey": "", "secretKey": "", "webhookSecret": "", "dashboardUrl": "https://dashboard.clerk.com/", "allowReadOnlyApiAccess": false, "allowMutations": false },
|
|
58
|
+
"convex": { "enabled": false, "deploymentUrl": "", "deployKey": "", "dashboardUrl": "https://dashboard.convex.dev/", "allowReadOnlyApiAccess": false, "allowMutations": false }
|
|
59
|
+
},
|
|
60
|
+
"safety": {
|
|
61
|
+
"allowExternalAccountCreation": false,
|
|
62
|
+
"allowDestructiveProviderActions": false,
|
|
63
|
+
"allowSecretMutation": false,
|
|
64
|
+
"allowProductionLikeTargets": false
|
|
65
|
+
},
|
|
66
|
+
"notes": {
|
|
67
|
+
"redaction": "Agents must never print passwords, tokens, API keys, webhook secrets, or full credential values in reports/logs.",
|
|
68
|
+
"scope": "Use only local/dev/test credentials. Do not place production secrets here."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
3. Write `runtime/project.example.json` (only if it does not already exist) with this content verbatim:
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"$schemaComment": "Per-project scripts and testing configuration. Committed to git. Populate via /setup-project. Update manually as scripts evolve. null means 'not configured for this project'.",
|
|
77
|
+
"scripts": {
|
|
78
|
+
"devAll": "./scripts/dev.sh",
|
|
79
|
+
"devFrontend": "./scripts/dev-frontend.sh",
|
|
80
|
+
"devBackend": "./scripts/dev-backend.sh",
|
|
81
|
+
"lint": "./scripts/lint.sh",
|
|
82
|
+
"typecheck": "./scripts/typecheck.sh",
|
|
83
|
+
"format": "./scripts/format.sh",
|
|
84
|
+
"build": "./scripts/build.sh",
|
|
85
|
+
"dockerBuild": "./scripts/docker-build.sh",
|
|
86
|
+
"dockerRun": "./scripts/docker-run.sh",
|
|
87
|
+
"test": null,
|
|
88
|
+
"testE2E": null
|
|
89
|
+
},
|
|
90
|
+
"testing": {
|
|
91
|
+
"testingUrl": "http://localhost:3000",
|
|
92
|
+
"backendUrl": null,
|
|
93
|
+
"testRunner": null
|
|
94
|
+
},
|
|
95
|
+
"mobile": {
|
|
96
|
+
"primaryDevice": "iPhone 12 Pro",
|
|
97
|
+
"secondaryDevice": null
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
4. Write `runtime/.gitignore` (only if it does not already exist) with content verbatim:
|
|
103
|
+
```
|
|
104
|
+
# Local-only runtime credentials. Never commit.
|
|
105
|
+
auth.json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Log each file you created.
|
|
109
|
+
|
|
110
|
+
### Step 2: Migrate auth.json (the user's actual credentials)
|
|
111
|
+
|
|
112
|
+
1. If both `CLAUDE_AUTH_JSON` and `PI_AUTH_JSON` exist:
|
|
113
|
+
- Compare their contents with `diff`.
|
|
114
|
+
- If identical, prefer `CLAUDE_AUTH_JSON` as the source.
|
|
115
|
+
- If different, print a warning: `Conflict: .claude/.../auth.json and .pi/.../auth.json differ. Using Claude version; Pi version will be deleted. Review the diff below if you need to merge manually before continuing.` Print the diff. Ask the user whether to continue (yes/no).
|
|
116
|
+
2. Move whichever auth.json exists to `runtime/auth.json` using `mv`. Do NOT use `cp` then delete — atomic move preserves file permissions and avoids leaving a window where credentials are duplicated on disk.
|
|
117
|
+
3. If `runtime/auth.json` already exists (unlikely given Step 0), do not overwrite. Print a warning and leave both files in place for the user to reconcile.
|
|
118
|
+
|
|
119
|
+
Log the move.
|
|
120
|
+
|
|
121
|
+
### Step 3: Build runtime/project.json from the old SKILL.md tables
|
|
122
|
+
|
|
123
|
+
The pre-v1.11 SKILL.md carried three populated tables: Project Scripts, Testing Configuration, Mobile Test Devices. Parse them from whichever variant still has them.
|
|
124
|
+
|
|
125
|
+
1. Resolve the source SKILL.md to parse. Define the test "has v1.10 tables" as: file contents contain both the header line `## Project Scripts` AND the header line `## Mobile Test Devices`. The v1.11 SKILL.md contains NEITHER header, so this reliably distinguishes the two shapes.
|
|
126
|
+
|
|
127
|
+
Walk this priority chain, stop at the FIRST source that passes the "has v1.10 tables" test. Record which source won as `PARSE_SOURCE_LABEL`:
|
|
128
|
+
|
|
129
|
+
a. `CLAUDE_SKILL_MD` on disk (label: `.claude/skills/testing-and-validation/SKILL.md (on disk, pre-upgrade)`).
|
|
130
|
+
b. `PI_SKILL_MD` on disk (label: `.pi/skills/testing-and-validation/SKILL.md (on disk, pre-upgrade)`).
|
|
131
|
+
c. If `.git/` exists at the project root: `git show HEAD:.claude/skills/testing-and-validation/SKILL.md` (label: `git HEAD .claude/skills/testing-and-validation/SKILL.md`). Capture stderr — if the file did not exist at HEAD, this fails with non-zero exit, treat as "not found" and continue.
|
|
132
|
+
d. `git show HEAD:.pi/skills/testing-and-validation/SKILL.md` (label: `git HEAD .pi/skills/testing-and-validation/SKILL.md`).
|
|
133
|
+
e. Walk back through git history for the Claude variant: run `git log --format=%H -n 20 -- .claude/skills/testing-and-validation/SKILL.md`. For each commit hash from newest to oldest, run `git show <hash>:.claude/skills/testing-and-validation/SKILL.md` and apply the test. First hit wins (label: `git <short-hash> .claude/skills/testing-and-validation/SKILL.md`).
|
|
134
|
+
f. Same as (e) for the Pi variant.
|
|
135
|
+
g. None of the above produced a v1.10-shape source. Set `PARSE_SOURCE = null` and `PARSE_SOURCE_LABEL = "template-only (no v1.10 SKILL.md found in working tree or git history)"`. Skip to sub-step 7.
|
|
136
|
+
|
|
137
|
+
The 20-commit cap on history walking prevents runaway searches; a project that hasn't touched SKILL.md in 20 commits is fine with the template-only fallback.
|
|
138
|
+
|
|
139
|
+
2. Read the resolved source content (either from disk in cases a/b, or captured stdout from `git show` in cases c-f).
|
|
140
|
+
3. Look for the `## Project Scripts` section heading. If found, parse the markdown table rows. For each row, the script category is column 1, the command is column 2. Map:
|
|
141
|
+
- `Run All Dev Servers` → `scripts.devAll`
|
|
142
|
+
- `Run Frontend` → `scripts.devFrontend`
|
|
143
|
+
- `Run Backend` → `scripts.devBackend`
|
|
144
|
+
- `Lint` → `scripts.lint`
|
|
145
|
+
- `Type Check` → `scripts.typecheck`
|
|
146
|
+
- `Format` → `scripts.format`
|
|
147
|
+
- `Build` → `scripts.build`
|
|
148
|
+
- `Docker Build` → `scripts.dockerBuild`
|
|
149
|
+
- `Docker Run` → `scripts.dockerRun`
|
|
150
|
+
- Any row whose command is `"N/A"`, `"NONE"`, empty, or a backtick-wrapped equivalent → set to `null`.
|
|
151
|
+
4. Look for the `## Testing Configuration` section heading. Parse:
|
|
152
|
+
- `Testing URL` → `testing.testingUrl` (strip backticks)
|
|
153
|
+
- `Backend URL` → `testing.backendUrl`
|
|
154
|
+
- `Test Runner` → `testing.testRunner`
|
|
155
|
+
- `Test Command` → `scripts.test`
|
|
156
|
+
- `E2E Test Command` → `scripts.testE2E`
|
|
157
|
+
- Any value matching `Not configured` / `NONE` / empty → `null`.
|
|
158
|
+
5. Look for the `## Mobile Test Devices` section heading. Parse:
|
|
159
|
+
- `Primary Device` → `mobile.primaryDevice` (strip backticks)
|
|
160
|
+
- `Secondary Device` → `mobile.secondaryDevice`
|
|
161
|
+
- Any value matching `NONE` (case-insensitive) → `null`.
|
|
162
|
+
|
|
163
|
+
6. If parsing succeeded (at least the Project Scripts section was found and parsed): write the populated values to `runtime/project.json`, starting from the template in Step 1.3 and overwriting only the fields you successfully parsed.
|
|
164
|
+
|
|
165
|
+
7. If parsing FAILED OR `PARSE_SOURCE = null`: copy `runtime/project.example.json` to `runtime/project.json` unchanged. Log: `Could not recover v1.10 SKILL.md tables from any source (working tree, git HEAD, or last 20 commits touching SKILL.md). runtime/project.json written from template with all values null; populate manually from your project scripts. PARSE_SOURCE_LABEL: <label>.`
|
|
166
|
+
|
|
167
|
+
Log the source file used and which fields were populated.
|
|
168
|
+
|
|
169
|
+
### Step 4: Delete orphan v1.10 files from both skill directories
|
|
170
|
+
|
|
171
|
+
Delete (if they exist):
|
|
172
|
+
- `CLAUDE_AUTH_JSON` (if not already moved in Step 2)
|
|
173
|
+
- `CLAUDE_AUTH_EXAMPLE`
|
|
174
|
+
- `CLAUDE_GITIGNORE`
|
|
175
|
+
- `PI_AUTH_JSON` (if not already moved in Step 2 — i.e. when Claude's was the chosen source)
|
|
176
|
+
- `PI_AUTH_EXAMPLE`
|
|
177
|
+
- `PI_GITIGNORE`
|
|
178
|
+
|
|
179
|
+
Do NOT delete `CLAUDE_SKILL_MD` or `PI_SKILL_MD` — those are still in use, and the ai-fob upgrade will overwrite them with the v1.11 versions on next install.
|
|
180
|
+
|
|
181
|
+
Log each deletion.
|
|
182
|
+
|
|
183
|
+
### Step 5: Verify
|
|
184
|
+
|
|
185
|
+
Run these checks and include results in the report:
|
|
186
|
+
|
|
187
|
+
1. `test -f runtime/project.json` — must exist.
|
|
188
|
+
2. `test -f runtime/auth.example.json` — must exist.
|
|
189
|
+
3. `test -f runtime/project.example.json` — must exist.
|
|
190
|
+
4. `test -f runtime/.gitignore` — must exist; verify `auth.json` appears as a non-comment line.
|
|
191
|
+
5. `python3 -c "import json; json.load(open('runtime/project.json'))"` (or `node -e "JSON.parse(require('fs').readFileSync('runtime/project.json'))"`) — must parse.
|
|
192
|
+
6. If `.git` exists: `git check-ignore runtime/auth.json` — must return exit 0 (path would be ignored).
|
|
193
|
+
7. `test ! -e .claude/skills/testing-and-validation/auth.json` — old file should be gone.
|
|
194
|
+
8. `test ! -e .pi/skills/testing-and-validation/auth.json` — old file should be gone.
|
|
195
|
+
|
|
196
|
+
If any check fails, mark the migration `INCOMPLETE` and surface the failing check in the report.
|
|
197
|
+
|
|
198
|
+
### Step 6: Report
|
|
199
|
+
|
|
200
|
+
Present a summary to the user:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
RUNTIME CONFIG MIGRATION COMPLETE
|
|
204
|
+
|
|
205
|
+
Project Root: <PROJECT_ROOT>
|
|
206
|
+
Status: COMPLETE | INCOMPLETE
|
|
207
|
+
|
|
208
|
+
Created:
|
|
209
|
+
runtime/auth.example.json (template)
|
|
210
|
+
runtime/project.example.json (template)
|
|
211
|
+
runtime/.gitignore (auth.json ignored)
|
|
212
|
+
|
|
213
|
+
Moved:
|
|
214
|
+
<source path> → runtime/auth.json
|
|
215
|
+
|
|
216
|
+
Populated runtime/project.json from:
|
|
217
|
+
<PARSE_SOURCE_LABEL>
|
|
218
|
+
(resolution chain: working tree → git HEAD → git history walk → template-only fallback)
|
|
219
|
+
|
|
220
|
+
Fields populated: scripts (N), testing (M), mobile (K)
|
|
221
|
+
Fields left null: <list>
|
|
222
|
+
|
|
223
|
+
Deleted (orphan v1.10 files):
|
|
224
|
+
.claude/skills/testing-and-validation/auth.example.json
|
|
225
|
+
.claude/skills/testing-and-validation/.gitignore
|
|
226
|
+
.pi/skills/testing-and-validation/auth.example.json
|
|
227
|
+
.pi/skills/testing-and-validation/.gitignore
|
|
228
|
+
(and any auth.json copies that weren't the migration source)
|
|
229
|
+
|
|
230
|
+
Verification:
|
|
231
|
+
runtime/project.json valid JSON: YES | NO
|
|
232
|
+
runtime/auth.json gitignored: YES | NO | N/A (no git)
|
|
233
|
+
|
|
234
|
+
Next Steps:
|
|
235
|
+
1. Review runtime/project.json — verify every script path matches a real file under scripts/. Replace any null fields if you have a script for them.
|
|
236
|
+
2. (Optional) Verify runtime/auth.json contents are still correct.
|
|
237
|
+
3. Run `npx ai-fob@latest` to upgrade your skill/agent/command/prompt assets to v1.11. The old SKILL.md files will be overwritten (this is intentional — they no longer carry per-project values).
|
|
238
|
+
4. Commit runtime/project.json, runtime/auth.example.json, runtime/project.example.json, and runtime/.gitignore. Do NOT commit runtime/auth.json.
|
|
239
|
+
|
|
240
|
+
If anything in this report looks wrong, restore from your git history (the v1.10 files were tracked) and report the issue.
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Edge cases
|
|
244
|
+
|
|
245
|
+
- **No v1.10 auth.json on disk** (only the example file): still run Step 1 to scaffold templates, skip Step 2, run Step 3 if SKILL.md tables exist, Step 4 to delete the example/.gitignore.
|
|
246
|
+
- **User customized auth.example.json**: it gets deleted in Step 4. The user can recover from git history. We do not preserve example-file edits because they are not user data.
|
|
247
|
+
- **Already-modified SKILL.md**: if the user added their own custom sections, those are lost when ai-fob upgrades the skill in v1.11. We can't preserve them automatically. Recommend the user save a copy before upgrading.
|
|
248
|
+
- **Migration interrupted mid-run**: the operations are not transactional. If the command fails between Step 2 and Step 4, the user has a half-migrated state. Re-running the command should be safe — Step 0's idempotency check catches the `runtime/` exists case, and Step 4 deletions are skipped for already-deleted files.
|