forgedock 1.0.1 → 1.0.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 +19 -2
- package/bin/forgedock.mjs +286 -10
- package/commands/analytics.md +129 -52
- package/commands/audit-agents.md +29 -5
- package/commands/audit.md +55 -17
- package/commands/autopilot.md +11 -6
- package/commands/cleanup.md +44 -24
- package/commands/deploy-info.md +7 -3
- package/commands/forge-stats.md +13 -4
- package/commands/forgedock-init.md +534 -0
- package/commands/geo-audit.md +114 -26
- package/commands/incident-response.md +4 -1
- package/commands/issue.md +26 -25
- package/commands/milestone.md +80 -59
- package/commands/orchestrate.md +38 -21
- package/commands/pipeline-health.md +26 -15
- package/commands/qa-sweep.md +68 -5
- package/commands/quality-gate.md +18 -0
- package/commands/review-pr-agents.md +58 -90
- package/commands/review-pr.md +58 -16
- package/commands/rollback.md +8 -5
- package/commands/security-audit.md +68 -12
- package/commands/sync-ecosystem.md +196 -156
- package/commands/work-on/build/architect.md +2 -2
- package/commands/work-on/build/context.md +2 -2
- package/commands/work-on/build/implement.md +3 -3
- package/commands/work-on/build/validate.md +3 -3
- package/commands/work-on/build.md +6 -6
- package/commands/work-on/close.md +59 -30
- package/commands/work-on/decompose.md +6 -6
- package/commands/work-on/investigate.md +16 -20
- package/commands/work-on/review.md +4 -4
- package/commands/work-on-monolithic.md +15 -16
- package/commands/work-on.md +45 -33
- package/docs/CODEX.md +1 -1
- package/docs/CONFIG.md +398 -0
- package/docs/WORKFLOW.md +115 -72
- package/package.json +1 -1
- package/scripts/verify-host-headers.sh +14 -9
- package/scripts/verify-route-registration.sh +10 -10
- package/commands/failure-recon.md +0 -375
package/commands/review-pr.md
CHANGED
|
@@ -4,7 +4,7 @@ argument-hint: [PR number, URL, "open", or "staging" for feature→main review]
|
|
|
4
4
|
allowed-tools: Task, Bash, Read, Grep, Glob, WebFetch, Skill
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# PR Review — Orchestrator
|
|
8
8
|
|
|
9
9
|
**Input**: $ARGUMENTS
|
|
10
10
|
|
|
@@ -20,8 +20,10 @@ This is the **orchestrator**. It routes to the right review mode, runs automated
|
|
|
20
20
|
|
|
21
21
|
| File | What | How to invoke |
|
|
22
22
|
|------|------|---------------|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
23
|
+
| `$FORGE_HOME/commands/review-pr-agents.md` | Agent prompt templates (9 agents + protocols) | `Read` tool during Phase 3C |
|
|
24
|
+
| `$FORGE_HOME/commands/review-pr-staging.md` | Full staging→main review pipeline | `Skill("review-pr-staging", ...)` during Phase 0 |
|
|
25
|
+
|
|
26
|
+
`$FORGE_HOME` defaults to `~/.claude` (the directory where `npx forgedock` symlinks commands). Override by setting `FORGE_HOME` in your environment.
|
|
25
27
|
|
|
26
28
|
**Invocation flow:**
|
|
27
29
|
```
|
|
@@ -38,7 +40,7 @@ This is the **orchestrator**. It routes to the right review mode, runs automated
|
|
|
38
40
|
If `$ARGUMENTS` contains `--auto-merge`, this review was invoked from `/work-on` and must merge the PR after approval. Parse:
|
|
39
41
|
|
|
40
42
|
```
|
|
41
|
-
Example: "3126 --auto-merge --issue 3124 --base staging --gh-flag -R
|
|
43
|
+
Example: "3126 --auto-merge --issue 3124 --base staging --gh-flag -R $GH_REPO --worktree /path/to/worktree"
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
Extract: `PR_NUMBER`, `AUTO_MERGE=true`, `MERGE_ISSUE`, `MERGE_BASE`, `MERGE_GH_FLAG`, `MERGE_WORKTREE` (optional — the absolute path to the git worktree to clean up after merge)
|
|
@@ -292,12 +294,12 @@ Map each changed file to its activation requirements:
|
|
|
292
294
|
| `web/src/app/**/*-client.tsx`, `web/src/components/**/*.tsx`, `web/src/lib/*.ts` (Client-side code with `fetch()`/`useSWR()`) | Client requests go through Next.js proxy (`/api/...`), never directly to FastAPI (`/api/v1/...`) | Grep changed `.tsx`/`.ts` files (excluding `route.ts` proxy handlers) for `fetch("/api/v1/` or `` `/api/v1/ `` in template literals or `useSWR.*"/api/v1/`. Any match is a **CONFIRMED BLOCKING** integration bug — direct calls bypass session auth (admin proxy JWT, session-to-bearer conversion) and fail locally (no nginx). |
|
|
293
295
|
| `.github/workflows/*.yml` (Workflow with test/build jobs) | Sibling workflows with same-named jobs stay in sync | For each job name in the changed workflow, check if the same job name exists in sibling workflows (`ci.yml` ↔ `deploy-production.yml` ↔ `hotfix-deploy.yml`). Compare env vars, PYTHONPATH, working-directory, and run commands for meaningful drift. |
|
|
294
296
|
| `docker-compose*.yml` changes to `postgres` or `redis` service (`command:`, `image:`, `volumes:`, `environment:`) | Stateful container will NOT be recreated during deploy, OR restart is safe | **Auto-escalate to HIGH risk.** Changing `command:` args, `image:` tag, or `volumes:` forces container recreation on `docker-compose up`. For stateful services (postgres, redis), verify: (1) `stop_grace_period` is set and sufficient (≥30s for PG); (2) `full_page_writes = on` in PG config (protects against partial page writes on crash); (3) `fsync = on` (ensures write durability); (4) No long-running transactions will be interrupted. If container recreation is unavoidable, recommend scheduling during a maintenance window — NOT as a side effect of a routine deploy. **This check prevents the class of incident documented in issue #146**: a PG `command:` arg change triggered container restart under active load, corrupting btree indexes. |
|
|
295
|
-
| `docker-compose*.yml` changes `entrypoint:` or `command:` to reference a script (`.sh` file) | Env vars used inside the entrypoint script are available inside the container at runtime | **Run `verify-env-vars.sh`** which detects shell `${VAR}` references in entrypoint scripts and cross-checks against the service's `environment:` section. Docker Compose `${VAR}` in YAML `command:` is parsed at Compose load time (host-side) — the var doesn't need to be in the container. But `${VAR}` inside an entrypoint `.sh` script runs at container runtime — it MUST be injected via `environment:` or `env_file:`. **This check prevents the class of incident
|
|
297
|
+
| `docker-compose*.yml` changes `entrypoint:` or `command:` to reference a script (`.sh` file) | Env vars used inside the entrypoint script are available inside the container at runtime | **Run `verify-env-vars.sh`** which detects shell `${VAR}` references in entrypoint scripts and cross-checks against the service's `environment:` section. Docker Compose `${VAR}` in YAML `command:` is parsed at Compose load time (host-side) — the var doesn't need to be in the container. But `${VAR}` inside an entrypoint `.sh` script runs at container runtime — it MUST be injected via `environment:` or `env_file:`. **This check prevents the class of incident where a service migrates from `command:` args (Compose interpolation) to an entrypoint script (container runtime) without adding the env var to `environment:`, causing a restart loop on deploy.** <!-- Added: forge#185 --> |
|
|
296
298
|
| **ANY staging→main PR** (regardless of files changed) | `ci.yml` and `deploy-production.yml` test jobs are in sync | **ALWAYS runs for staging→main PRs.** Pre-existing drift is invisible until deploy. Deep-diff shared jobs (test-api, test-web): compare PYTHONPATH values, dependency install steps, and step names. A missing PYTHONPATH or install step in deploy is CONFIRMED BLOCKING — CI passes but deploy fails (PR #11356 incident). |
|
|
297
299
|
|
|
298
300
|
### Step 2.5B: Run Verification
|
|
299
301
|
|
|
300
|
-
For each changed file, execute the relevant checks using the standalone verification scripts in
|
|
302
|
+
For each changed file, execute the relevant checks using the standalone verification scripts in `$FORGE_HOME/scripts/`. These scripts can also be run independently outside the review context (e.g., from `/quality-gate` or `/work-on` builder steps).
|
|
301
303
|
|
|
302
304
|
```bash
|
|
303
305
|
CHANGED_FILES=$(gh pr diff $ARGUMENTS --name-only)
|
|
@@ -315,19 +317,29 @@ gh pr diff $ARGUMENTS > "$DIFF_TMP"
|
|
|
315
317
|
|
|
316
318
|
# 1. Route/router/middleware/shared-module/component registration
|
|
317
319
|
echo "=== Running: verify-route-registration.sh ==="
|
|
318
|
-
|
|
320
|
+
$FORGE_HOME/scripts/verify-route-registration.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
|
|
319
321
|
|
|
320
322
|
# 2. Environment variable wiring (checks .env.example, docker-compose, env_validation, SOPS mapping)
|
|
321
323
|
echo "=== Running: verify-env-vars.sh ==="
|
|
322
|
-
|
|
324
|
+
$FORGE_HOME/scripts/verify-env-vars.sh "$DIFF_TMP" "$REPO_ROOT" || true
|
|
323
325
|
|
|
324
326
|
# 3. Host headers in shell scripts + client-side proxy bypass check
|
|
327
|
+
# Read project-specific internal service patterns from forge.yaml (if present)
|
|
328
|
+
FORGE_INTERNAL_PATTERNS=""
|
|
329
|
+
if [ -f "$REPO_ROOT/forge.yaml" ]; then
|
|
330
|
+
FORGE_INTERNAL_PATTERNS=$(grep -A 999 'internal_service_patterns:' "$REPO_ROOT/forge.yaml" \
|
|
331
|
+
| grep -E '^\s*-\s+' \
|
|
332
|
+
| sed 's/^\s*-\s*//' \
|
|
333
|
+
| tr -d '"'"'" \
|
|
334
|
+
| paste -sd '|' -)
|
|
335
|
+
fi
|
|
336
|
+
export FORGE_INTERNAL_PATTERNS
|
|
325
337
|
echo "=== Running: verify-host-headers.sh ==="
|
|
326
|
-
|
|
338
|
+
$FORGE_HOME/scripts/verify-host-headers.sh "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
|
|
327
339
|
|
|
328
340
|
# 4. SOPS deploy chain (ENV_MAPPING consistency, deploy path drift, hotfix sync)
|
|
329
341
|
echo "=== Running: verify-sops-chain.sh ==="
|
|
330
|
-
|
|
342
|
+
$FORGE_HOME/scripts/verify-sops-chain.sh "$DIFF_TMP" "$CHANGED_FILES_TMP" "$REPO_ROOT" || true
|
|
331
343
|
|
|
332
344
|
# Cleanup temp files
|
|
333
345
|
rm -f "$CHANGED_FILES_TMP" "$DIFF_TMP"
|
|
@@ -488,14 +500,37 @@ echo "$FILES" | grep -cE "^sdk/|openapi.*\.json$|openapi-versions/" && echo " S
|
|
|
488
500
|
|
|
489
501
|
**>>> INVOCATION: Read the agent catalog file:**
|
|
490
502
|
```
|
|
491
|
-
Read the file: /
|
|
503
|
+
Read the file: $FORGE_HOME/commands/review-pr-agents.md
|
|
492
504
|
```
|
|
493
505
|
|
|
506
|
+
(`$FORGE_HOME` defaults to `~/.claude`)
|
|
507
|
+
|
|
508
|
+
**>>> LOAD CONFIG: Read forge.yaml for project context:**
|
|
509
|
+
```bash
|
|
510
|
+
# Read review config from forge.yaml (if present in project root)
|
|
511
|
+
FORGE_YAML="${REPO_ROOT}/forge.yaml"
|
|
512
|
+
PROJECT_NAME=$(yq '.project.name' "$FORGE_YAML" 2>/dev/null || echo "this project")
|
|
513
|
+
PROJECT_CONTEXT=$(yq '.review.context' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
514
|
+
TECH_STACK=$(yq '.review.tech_stack' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
515
|
+
# Domain-specific context (keyed by agent name)
|
|
516
|
+
DOMAIN_CONTEXT_AUTH=$(yq '.review.domains.auth' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
517
|
+
DOMAIN_CONTEXT_BILLING=$(yq '.review.domains.billing' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
518
|
+
DOMAIN_CONTEXT_INFRA=$(yq '.review.domains.infra' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
519
|
+
DOMAIN_CONTEXT_DATABASE=$(yq '.review.domains.database' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
520
|
+
DOMAIN_CONTEXT_FRONTEND=$(yq '.review.domains.frontend' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
521
|
+
DOMAIN_CONTEXT_SECURITY=$(yq '.review.domains.security' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
522
|
+
DOMAIN_CONTEXT_API=$(yq '.review.domains.api' "$FORGE_YAML" 2>/dev/null || echo "")
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
If `forge.yaml` is absent or a field is empty/null, agents fall back to generic checks (no project-specific context injected — agents still function correctly, just without project conventions).
|
|
526
|
+
|
|
494
527
|
This file contains the Evidence-Based Review Protocol, Structured Findings Protocol, and all 9 agent prompt templates. For each selected agent:
|
|
495
528
|
1. Extract its template from the catalog
|
|
496
529
|
2. Substitute: `[PR_NUMBER]`, `[REVIEW_SHA]`, `[REVIEW_SHA_SHORT]`, `[TITLE]`, relevant files list
|
|
497
|
-
3.
|
|
498
|
-
4.
|
|
530
|
+
3. Substitute: `[PROJECT_NAME]` → `$PROJECT_NAME`, `[PROJECT_CONTEXT]` → `$PROJECT_CONTEXT`, `[TECH_STACK]` → `$TECH_STACK`
|
|
531
|
+
4. Substitute per-agent domain context: `[DOMAIN_CONTEXT]` → the agent's matching key from `forge.yaml → review.domains` (e.g., `$DOMAIN_CONTEXT_AUTH` for the auth agent, `$DOMAIN_CONTEXT_BILLING` for the billing agent)
|
|
532
|
+
5. If Phase 2.5 found broken assumptions, append them to the agent's prompt as "Pre-found integration issues to verify"
|
|
533
|
+
6. Launch via `Task` tool with the resolved model (default `"sonnet"`, fallback `"opus"` if rate-limited)
|
|
499
534
|
|
|
500
535
|
**CRITICAL**: Launch ALL selected agents in a SINGLE message using multiple Task tool calls. Each agent posts findings directly to the PR via `gh pr comment`.
|
|
501
536
|
|
|
@@ -711,10 +746,17 @@ Labels: `review-finding` + `needs-validation` + priority (`P1` CONFIRMED, `P2` L
|
|
|
711
746
|
**Add to project board:**
|
|
712
747
|
```bash
|
|
713
748
|
for FINDING_NUM in {numbers}; do
|
|
714
|
-
|
|
749
|
+
# GH_REPO and board IDs are read from forge.yaml → project_board section
|
|
750
|
+
# OWNER = forge.yaml → project_board.owner (or project.owner)
|
|
751
|
+
# PROJECT_NUMBER = forge.yaml → project_board.project_number
|
|
752
|
+
# PROJECT_ID = forge.yaml → project_board.project_id
|
|
753
|
+
# STATUS_FIELD_ID = forge.yaml → project_board.field_ids.status
|
|
754
|
+
# LANE_FIELD_ID = forge.yaml → project_board.field_ids.lane
|
|
755
|
+
# REVIEW_FINDING_OPTION_ID = forge.yaml → project_board.option_ids.status.in_review
|
|
756
|
+
ITEM_ID=$(gh project item-add ${PROJECT_NUMBER} --owner ${OWNER} --url "https://github.com/${GH_REPO}/issues/${FINDING_NUM}" --format json --jq '.id' 2>/dev/null)
|
|
715
757
|
[ -n "$ITEM_ID" ] && {
|
|
716
|
-
gh project item-edit --project-id
|
|
717
|
-
gh project item-edit --project-id
|
|
758
|
+
[ -n "$STATUS_FIELD_ID" ] && gh project item-edit --project-id ${PROJECT_ID} --id "$ITEM_ID" --field-id ${STATUS_FIELD_ID} --single-select-option-id ${REVIEW_FINDING_OPTION_ID} 2>/dev/null || true
|
|
759
|
+
[ -n "$LANE_FIELD_ID" ] && gh project item-edit --project-id ${PROJECT_ID} --id "$ITEM_ID" --field-id ${LANE_FIELD_ID} --single-select-option-id ${LANE_OPTION_ID} 2>/dev/null || true
|
|
718
760
|
}
|
|
719
761
|
done
|
|
720
762
|
```
|
package/commands/rollback.md
CHANGED
|
@@ -7,6 +7,9 @@ argument-hint: [PR number to revert, or "last" for most recent deploy]
|
|
|
7
7
|
|
|
8
8
|
**Input**: $ARGUMENTS
|
|
9
9
|
|
|
10
|
+
**Config variables used by this command** (set in `forge.yaml`):
|
|
11
|
+
- `{REPO_PATH}` ← `paths.root` — project repository root
|
|
12
|
+
|
|
10
13
|
You are the pipeline's emergency rollback system. When a shipped feature or fix causes production issues, this command creates a revert PR and fast-tracks it through the pipeline.
|
|
11
14
|
|
|
12
15
|
**Agent model policy**: Default `model: "sonnet"`. If Sonnet is rate-limited, fall back to `model: "opus"`. User can override with `--model <name>`.
|
|
@@ -75,11 +78,11 @@ Which approach? (Reply or press enter for option 1)
|
|
|
75
78
|
### Step 2A: Create a revert branch
|
|
76
79
|
|
|
77
80
|
```bash
|
|
78
|
-
cd
|
|
81
|
+
cd {REPO_PATH}
|
|
79
82
|
git fetch origin main
|
|
80
|
-
git worktree add ../
|
|
83
|
+
git worktree add ../revert-pr-{PR_NUMBER} -b revert/pr-{PR_NUMBER} origin/main
|
|
81
84
|
|
|
82
|
-
cd ../
|
|
85
|
+
cd ../revert-pr-{PR_NUMBER}
|
|
83
86
|
```
|
|
84
87
|
|
|
85
88
|
### Step 2B: Execute the revert
|
|
@@ -230,8 +233,8 @@ BODY_EOF
|
|
|
230
233
|
### Step 4C: Clean up worktree
|
|
231
234
|
|
|
232
235
|
```bash
|
|
233
|
-
cd
|
|
234
|
-
git worktree remove ../
|
|
236
|
+
cd {REPO_PATH}
|
|
237
|
+
git worktree remove ../revert-pr-{PR_NUMBER}
|
|
235
238
|
git branch -D revert/pr-{PR_NUMBER} 2>/dev/null || true
|
|
236
239
|
```
|
|
237
240
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Periodic security posture audit — runs a scripted 4-phase checklist against repo files (not diffs), creates GitHub issues for confirmed findings
|
|
3
|
-
argument-hint: [--repo
|
|
3
|
+
argument-hint: [--repo <prefix>] [--phase 1|2|3|4|all] [--dry-run]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /security-audit — Periodic Security Posture Audit
|
|
@@ -21,22 +21,70 @@ This is NOT a PR review — it does not approve or block. It creates issues for
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
+
## Config Preamble
|
|
25
|
+
|
|
26
|
+
Before executing any phase, read `forge.yaml` to resolve project references:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
|
|
30
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
31
|
+
GH_OWNER=$(yq '.project.owner' "$CONFIG_FILE")
|
|
32
|
+
GH_REPO_NAME=$(yq '.project.repo' "$CONFIG_FILE")
|
|
33
|
+
GH_REPO="${GH_OWNER}/${GH_REPO_NAME}"
|
|
34
|
+
GH_FLAG="-R $GH_REPO"
|
|
35
|
+
REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
|
|
36
|
+
# FORGE_REPO: the self-pipeline repo where security audit summary comments are posted.
|
|
37
|
+
# Set project.forge_repo in forge.yaml if your pipeline repo differs from GH_REPO.
|
|
38
|
+
FORGE_REPO=$(yq '.project.forge_repo // ""' "$CONFIG_FILE")
|
|
39
|
+
[ -z "$FORGE_REPO" ] && FORGE_REPO="$GH_REPO"
|
|
40
|
+
# BILLING_ENABLED: controls whether Phase 4 (Financial Integrity) runs.
|
|
41
|
+
# Set billing.enabled: true in forge.yaml if your project uses Stripe billing.
|
|
42
|
+
BILLING_ENABLED=$(yq '.billing.enabled // "false"' "$CONFIG_FILE")
|
|
43
|
+
else
|
|
44
|
+
echo "WARNING: forge.yaml not found — commands will use placeholder values"
|
|
45
|
+
echo "Run: cp forge.yaml.example forge.yaml and fill in your project details"
|
|
46
|
+
GH_REPO="your-org/your-repo"
|
|
47
|
+
GH_FLAG="-R $GH_REPO"
|
|
48
|
+
REPO_PATH="./"
|
|
49
|
+
FORGE_REPO="$GH_REPO"
|
|
50
|
+
BILLING_ENABLED="false"
|
|
51
|
+
fi
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
24
56
|
## Multi-Repo Support
|
|
25
57
|
|
|
26
|
-
|
|
27
|
-
|---------------|-------------|---------|-----------|
|
|
28
|
-
| `--repo alterlab` or default | AlterLab | `RapierCraft/AlterLab` | `/home/user/projects/alterlab` |
|
|
29
|
-
| `--repo mcp` | MCP Server | `RapierCraft/alterlab-mcp-server` | `/home/user/projects/alterlab-mcp-server` |
|
|
30
|
-
| `--repo n8n` | n8n Node | `RapierCraft/n8n-nodes-alterlab` | `/home/user/projects/n8n-nodes-alterlab` |
|
|
58
|
+
If your project spans multiple repositories, define them in the `repos.satellites` section of `forge.yaml`. The `--repo <prefix>` argument selects a satellite by its `prefix` field.
|
|
31
59
|
|
|
32
60
|
Parse `$ARGUMENTS` for:
|
|
33
|
-
- **`--repo <
|
|
61
|
+
- **`--repo <prefix>`**: target repo prefix (default: primary repo from `project.owner/project.repo`)
|
|
34
62
|
- **`--phase <N|all>`**: run only a specific phase, or all (default: `all`)
|
|
35
63
|
- **`--dry-run`**: print findings but do NOT create GitHub issues
|
|
36
64
|
|
|
37
|
-
Set context variables from
|
|
65
|
+
Set context variables from config:
|
|
66
|
+
|
|
38
67
|
```bash
|
|
39
|
-
|
|
68
|
+
REPO_PREFIX=$(echo "$ARGUMENTS" | grep -oP '(?<=--repo )\S+' || true)
|
|
69
|
+
|
|
70
|
+
if [ -n "$REPO_PREFIX" ]; then
|
|
71
|
+
# Look up satellite repo by prefix in forge.yaml
|
|
72
|
+
SATELLITE_REPO=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .repo" "$CONFIG_FILE" 2>/dev/null)
|
|
73
|
+
if [ -n "$SATELLITE_REPO" ] && [ "$SATELLITE_REPO" != "null" ]; then
|
|
74
|
+
GH_REPO="$SATELLITE_REPO"
|
|
75
|
+
GH_FLAG="-R $GH_REPO"
|
|
76
|
+
REPO_PATH=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .local_path" "$CONFIG_FILE" 2>/dev/null || echo "$REPO_PATH")
|
|
77
|
+
# Also read billing flag for satellite if set
|
|
78
|
+
BILLING_ENABLED=$(yq ".repos.satellites[] | select(.prefix == \"$REPO_PREFIX\") | .billing_enabled // \"false\"" "$CONFIG_FILE" 2>/dev/null || echo "false")
|
|
79
|
+
else
|
|
80
|
+
echo "WARNING: --repo prefix '$REPO_PREFIX' not found in forge.yaml repos.satellites — using default repo"
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# If REPO_PATH is not found locally, clone from GitHub
|
|
85
|
+
if [ ! -d "$REPO_PATH" ]; then
|
|
86
|
+
gh repo clone {GH_REPO} {REPO_PATH} -- --depth=1 2>/dev/null || true
|
|
87
|
+
fi
|
|
40
88
|
```
|
|
41
89
|
|
|
42
90
|
---
|
|
@@ -353,9 +401,17 @@ grep -rn '||\s*["'"'"'][a-zA-Z0-9]\{4,\}["'"'"']\|default.*password\|default.*se
|
|
|
353
401
|
|
|
354
402
|
---
|
|
355
403
|
|
|
356
|
-
## Phase 4: Financial Integrity
|
|
404
|
+
## Phase 4: Financial Integrity
|
|
357
405
|
|
|
358
|
-
*Skip this phase
|
|
406
|
+
*Skip this phase if `billing.enabled` is not set to `true` in `forge.yaml`. These checks require Stripe webhook integration and a billing architecture in your project.*
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
if [ "$BILLING_ENABLED" != "true" ]; then
|
|
410
|
+
echo "Phase 4 skipped — billing.enabled is not true in forge.yaml"
|
|
411
|
+
echo "To enable: add 'billing:\n enabled: true' to forge.yaml"
|
|
412
|
+
# Skip to Phase 5
|
|
413
|
+
fi
|
|
414
|
+
```
|
|
359
415
|
|
|
360
416
|
### 4A: Stripe Webhook Handler Coverage
|
|
361
417
|
|
|
@@ -491,7 +547,7 @@ ISSUE_EOF
|
|
|
491
547
|
If this command was invoked from within a `/work-on` context or with an issue reference:
|
|
492
548
|
|
|
493
549
|
```bash
|
|
494
|
-
gh issue comment "{CALLER_ISSUE}" -R
|
|
550
|
+
gh issue comment "{CALLER_ISSUE}" -R {FORGE_REPO} --body "$(cat <<'COMMENT_EOF'
|
|
495
551
|
<!-- FORGE:SECURITY_AUDIT -->
|
|
496
552
|
## Security Audit Complete
|
|
497
553
|
|