forge-orkes 0.62.0 → 0.64.0

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.
Files changed (56) hide show
  1. package/bin/create-forge.js +250 -99
  2. package/experimental/conventions/README.md +87 -0
  3. package/experimental/conventions/install.sh +179 -0
  4. package/experimental/conventions/source/rules/code-quality.md +17 -0
  5. package/experimental/conventions/source/rules/laravel-http.md +21 -0
  6. package/experimental/conventions/source/rules/laravel-jobs.md +19 -0
  7. package/experimental/conventions/source/rules/laravel-migrations.md +19 -0
  8. package/experimental/conventions/source/rules/laravel-services.md +21 -0
  9. package/experimental/conventions/source/rules/python.md +14 -0
  10. package/experimental/conventions/source/rules/testing.md +15 -0
  11. package/experimental/conventions/source/rules/vue-inertia.md +24 -0
  12. package/experimental/conventions/source/skills/laravel-conventions/SKILL.md +124 -0
  13. package/experimental/conventions/source/skills/python-conventions/SKILL.md +100 -0
  14. package/experimental/conventions/source/skills/testing-standards/SKILL.md +142 -0
  15. package/experimental/conventions/source/skills/vue-conventions/SKILL.md +92 -0
  16. package/experimental/conventions/uninstall.sh +97 -0
  17. package/experimental/m10/README.md +130 -0
  18. package/experimental/m10/install.sh +198 -0
  19. package/experimental/m10/source/hooks/forge-branch-guard.sh +61 -0
  20. package/experimental/m10/source/hooks/forge-claim-check-doctor.sh +77 -0
  21. package/experimental/m10/source/hooks/forge-claim-check.sh +113 -0
  22. package/experimental/m10/source/hooks/forge-session-id.sh +22 -0
  23. package/experimental/m10/source/mcp-server/README.md +74 -0
  24. package/experimental/m10/source/mcp-server/example.mcp.json +8 -0
  25. package/experimental/m10/source/mcp-server/index.js +460 -0
  26. package/experimental/m10/source/mcp-server/package.json +17 -0
  27. package/experimental/m10/source/skills/orchestrating/SKILL.md +223 -0
  28. package/experimental/m10/source/skills/orchestrating/bootstrap-checks.md +70 -0
  29. package/experimental/m10/uninstall.sh +69 -0
  30. package/package.json +3 -2
  31. package/template/.claude/hooks/forge-release-fold.sh +9 -1
  32. package/template/.claude/settings.json +1 -7
  33. package/template/.claude/skills/jarvis/SKILL.md +204 -0
  34. package/template/.claude/skills/upgrading/SKILL.md +105 -176
  35. package/template/.forge/FORGE.md +2 -2
  36. package/template/.forge/checks/forge-board-render.sh +11 -5
  37. package/template/.forge/checks/forge-jarvis-answer.sh +79 -0
  38. package/template/.forge/checks/forge-jarvis-awareness.sh +128 -0
  39. package/template/.forge/checks/forge-jarvis-bridge-clean.sh +130 -0
  40. package/template/.forge/checks/forge-jarvis-dispatch.sh +176 -0
  41. package/template/.forge/checks/forge-jarvis-instruments.sh +146 -0
  42. package/template/.forge/checks/forge-jarvis-notify-logonly.sh +40 -0
  43. package/template/.forge/checks/forge-jarvis-promote.sh +103 -0
  44. package/template/.forge/checks/forge-jarvis-prwatch.sh +92 -0
  45. package/template/.forge/checks/forge-jarvis-relay.sh +215 -0
  46. package/template/.forge/checks/forge-jarvis.sh +160 -0
  47. package/template/.forge/checks/tests/forge-jarvis-answer.test.sh +75 -0
  48. package/template/.forge/checks/tests/forge-jarvis-bridge-clean.test.sh +94 -0
  49. package/template/.forge/checks/tests/forge-jarvis-dispatch.test.sh +162 -0
  50. package/template/.forge/checks/tests/forge-jarvis-instruments.test.sh +64 -0
  51. package/template/.forge/checks/tests/forge-jarvis-promote.test.sh +102 -0
  52. package/template/.forge/checks/tests/forge-jarvis-prwatch.test.sh +66 -0
  53. package/template/.forge/checks/tests/forge-jarvis-relay.test.sh +135 -0
  54. package/template/.forge/checks/tests/forge-jarvis.test.sh +122 -0
  55. package/template/.forge/migrations/0.63.0-origin-first-upgrading.md +49 -0
  56. package/template/.forge/templates/project.yml +11 -0
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env sh
2
+ # Fixture-repo test suite for .forge/checks/forge-jarvis.sh --dry-run (m-37, Brief-R2 step 4 B2).
3
+ #
4
+ # Contract under test (handoff-step4-jarvis.md REV2 B2 + operator ruling 6 +
5
+ # runbook-B1-live-test-recon.md "After B1" bake-ins):
6
+ # --dry-run prints the fully resolved launch command and NEVER executes:
7
+ # caffeinate -s claude remote-control --name <sticky> --spawn worktree --capacity <N>
8
+ # Name: jarvis-<repo-basename> (from the git COMMON dir — stable across worktrees),
9
+ # + optional suffix from jarvis.name_suffix, overridden per machine by
10
+ # FORGE_JARVIS_NAME_SUFFIX (probe ii: the sticky name is the only discoverability
11
+ # anchor). Capacity: --capacity flag > jarvis.capacity > 4. NO token export ever
12
+ # (probe iv — asserted here as an env-name absence in the output). Refusals:
13
+ # jarvis.enabled: false, or not a git repo → non-zero exit, NO command on stdout.
14
+ #
15
+ # Builds throwaway git repos in a mktemp dir, offline by construction; only ever
16
+ # invokes --dry-run, so `claude`/`caffeinate` need not exist (dry-run is pure
17
+ # resolution — that determinism is itself part of the contract).
18
+ #
19
+ # Usage: ./.forge/checks/tests/forge-jarvis.test.sh
20
+ # RED-phase friendly: a missing/non-executable script fails every case, exits non-zero.
21
+ set -u
22
+
23
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
24
+ JARVIS="$SCRIPT_DIR/../forge-jarvis.sh"
25
+
26
+ [ -f "$JARVIS" ] || printf 'NOTE: %s missing — RED phase, every case should FAIL\n' "$JARVIS" >&2
27
+
28
+ ROOT="$(mktemp -d)"
29
+ trap 'rm -rf "$ROOT"' EXIT INT TERM
30
+ GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=/dev/null
31
+ export GIT_CONFIG_GLOBAL GIT_CONFIG_SYSTEM
32
+ unset FORGE_JARVIS_NAME_SUFFIX 2>/dev/null || true
33
+
34
+ PASSED=0; FAILED=0
35
+ ok() { PASSED=$((PASSED+1)); printf ' ok %s\n' "$1"; }
36
+ bad() { FAILED=$((FAILED+1)); printf ' FAIL %s\n %s\n' "$1" "$2"; }
37
+
38
+ # --- fixture repo (basename "proj" → expected sticky base jarvis-proj) -------
39
+ REPO="$ROOT/proj"
40
+ mkdir -p "$REPO/.forge"
41
+ git -C "$ROOT" init -q -b main "$REPO"
42
+
43
+ # 1. default derivation — no jarvis: block → full default command
44
+ out="$(cd "$REPO" && sh "$JARVIS" --dry-run 2>/dev/null)"; rc=$?
45
+ want="caffeinate -s claude remote-control --name jarvis-proj --spawn worktree --capacity 4"
46
+ if [ "$rc" = 0 ] && [ "$out" = "$want" ]; then
47
+ ok "default derivation: no config → jarvis-proj, capacity 4"
48
+ else
49
+ bad "default derivation" "rc=$rc out=$out"
50
+ fi
51
+
52
+ # 2. caffeinate -s present (operator ruling 6 — asserted on its own so a future
53
+ # edit dropping the wrap fails a NAMED case, not just the exact-match above)
54
+ case "$out" in
55
+ "caffeinate -s "*) ok "caffeinate -s wraps the resolved command (ruling 6 / probe iii)" ;;
56
+ *) bad "caffeinate -s wrap" "out=$out" ;;
57
+ esac
58
+
59
+ # 3. config override — jarvis: block with name_suffix + capacity
60
+ cat > "$REPO/.forge/project.yml" <<'EOF'
61
+ project:
62
+ name: "proj"
63
+ jarvis:
64
+ enabled: true
65
+ name_suffix: "alpha"
66
+ capacity: 2
67
+ EOF
68
+ out="$(cd "$REPO" && sh "$JARVIS" --dry-run 2>/dev/null)"; rc=$?
69
+ want="caffeinate -s claude remote-control --name jarvis-proj-alpha --spawn worktree --capacity 2"
70
+ if [ "$rc" = 0 ] && [ "$out" = "$want" ]; then
71
+ ok "config override: name_suffix + capacity from jarvis: block"
72
+ else
73
+ bad "config override" "rc=$rc out=$out"
74
+ fi
75
+
76
+ # 4. per-machine env seam — FORGE_JARVIS_NAME_SUFFIX beats jarvis.name_suffix
77
+ out="$(cd "$REPO" && FORGE_JARVIS_NAME_SUFFIX=work sh "$JARVIS" --dry-run 2>/dev/null)"; rc=$?
78
+ case "$out" in
79
+ *"--name jarvis-proj-work "*) ok "env FORGE_JARVIS_NAME_SUFFIX overrides config suffix (per-machine seam)" ;;
80
+ *) bad "env suffix override" "rc=$rc out=$out" ;;
81
+ esac
82
+
83
+ # 5. capacity flag override — --capacity beats jarvis.capacity
84
+ out="$(cd "$REPO" && sh "$JARVIS" --dry-run --capacity 7 2>/dev/null)"; rc=$?
85
+ case "$out" in
86
+ *"--capacity 7") ok "--capacity flag overrides config capacity" ;;
87
+ *) bad "capacity flag override" "rc=$rc out=$out" ;;
88
+ esac
89
+
90
+ # 6. no token export — the resolved command never carries an auth env assignment
91
+ # (probe iv: keychain authenticates; a token in the launch line would be the
92
+ # exact regression the B1 bake-in forbids)
93
+ case "$out" in
94
+ *CLAUDE_CODE_OAUTH_TOKEN*|*ANTHROPIC_API_KEY*) bad "no token in resolved command" "out=$out" ;;
95
+ *) ok "no token export in the resolved command (probe iv)" ;;
96
+ esac
97
+
98
+ # 7. NEG: enabled: false → clean refusal (non-zero, no command on stdout)
99
+ cat > "$REPO/.forge/project.yml" <<'EOF'
100
+ jarvis:
101
+ enabled: false
102
+ EOF
103
+ out="$(cd "$REPO" && sh "$JARVIS" --dry-run 2>/dev/null)"; rc=$?
104
+ if [ "$rc" != 0 ] && [ -z "$out" ]; then
105
+ ok "neg-control: jarvis.enabled false → refusal, no command emitted"
106
+ else
107
+ bad "neg-control enabled:false" "rc=$rc out=$out"
108
+ fi
109
+
110
+ # 8. NEG: not a git repo → clean refusal (RC --spawn worktree needs one)
111
+ NOREPO="$ROOT/norepo"
112
+ mkdir -p "$NOREPO"
113
+ out="$(cd "$NOREPO" && sh "$JARVIS" --dry-run 2>/dev/null)"; rc=$?
114
+ if [ "$rc" != 0 ] && [ -z "$out" ]; then
115
+ ok "neg-control: outside a git repo → refusal, no command emitted"
116
+ else
117
+ bad "neg-control non-repo" "rc=$rc out=$out"
118
+ fi
119
+
120
+ # --- summary -----------------------------------------------------------------
121
+ printf '\n%s: %d passed, %d failed\n' "$(basename "$0")" "$PASSED" "$FAILED"
122
+ [ "$FAILED" = 0 ]
@@ -0,0 +1,49 @@
1
+ # Migration Guide: Origin-First Upgrading (Forge 0.63.0)
2
+
3
+ Applies to projects whose installed `upgrading` skill predates 0.63.0. The default `/upgrading` path changed from "sync from a local Forge clone at `.forge/dev-source`" to "wrap the npm registry bin": `/upgrading` now runs `npx forge-orkes@latest upgrade --yes --json` as the one sync engine and layers the agent-only steps (migration prompts, experimental re-sync, Codex offer, worktree propagation) on the bin's JSON report. Local-clone sync survives only as explicit **Dev Mode** (`/upgrading dev`) — presence of `.forge/dev-source` never selects it (ADR-026).
4
+
5
+ ## Prerequisites
6
+
7
+ 1. Network access to the npm registry (the new default path runs `npx forge-orkes`).
8
+ 2. Nothing else — the migration IS the upgrade run; no files need hand-editing.
9
+
10
+ ## Detection
11
+
12
+ Prints `MIGRATE` when the installed upgrading skill is old-shape (it lacks the registry engine invocation the 0.63.0 skill always carries); silent + exit 0 otherwise.
13
+
14
+ ```bash
15
+ # Old-shape upgrading skill: exists but lacks the registry engine invocation.
16
+ S=.claude/skills/upgrading/SKILL.md
17
+ [ -f "$S" ] || exit 0 # skill not installed → nothing to do
18
+ if ! grep -q 'forge-orkes@latest upgrade --yes --json' "$S" 2>/dev/null; then
19
+ echo "MIGRATE — installed upgrading skill predates the origin-first default (registry engine); re-running the upgrade replaces it"
20
+ fi
21
+ ```
22
+
23
+ ## Migration steps
24
+
25
+ ### 1. Re-run the upgrade
26
+
27
+ The sync itself replaces the skill — that is the whole migration. Either route works:
28
+
29
+ - `npx forge-orkes@latest upgrade` (any machine, no clone needed), or
30
+ - `/upgrading` in a Claude Code session **on 0.63.0+ framework files** (the run that installs this guide already synced the new skill; this Detection then stops firing).
31
+
32
+ ### 2. Understand what changed in daily use
33
+
34
+ - **`/upgrading`** now upgrades from the npm registry. If `.forge/dev-source` exists you will see exactly one notice line — *"dev mode available — `/upgrading dev`"* — and the registry upgrade proceeds anyway.
35
+ - **`/upgrading X.Y.Z`** pins the engine to that release (`npx forge-orkes@X.Y.Z upgrade --yes --json`).
36
+ - **`/upgrading dev`** is the only way to sync from a local clone (framework development). Its flow — source resolution, downgrade guard, upstream desire-path harvest — is unchanged, just explicit.
37
+ - Experimental skills now re-sync from the release tarball itself (`experimental/` ships in the package since 0.63.0), so registry-only machines get staleness detection + consent-gated re-sync too (closes issue #5).
38
+
39
+ ### 3. Optional: drop `.forge/dev-source` on non-dev machines
40
+
41
+ On machines that never develop Forge itself, the file now only produces the notice line. Removing it is safe and silences the notice. Keep it on your framework-dev machine(s) for `/upgrading dev`.
42
+
43
+ ## Validation
44
+
45
+ ```bash
46
+ grep -q 'forge-orkes@latest upgrade --yes --json' .claude/skills/upgrading/SKILL.md \
47
+ && echo "upgrading skill is origin-first (0.63.0+)" \
48
+ || echo "still old-shape — re-run the upgrade"
49
+ ```
@@ -138,6 +138,17 @@ models:
138
138
  # backlog: true # lane is PROJECT-LOCAL config composing these; the framework carries none.
139
139
  # deferred: true # status / backlog (explicit-intake, M21) / deferred view.
140
140
 
141
+ # jarvis: # OPTIONAL front door (Brief-R2 step 4) — the repo's standing presence: a
142
+ # # named `claude remote-control` server whose pre-created session is Jarvis,
143
+ # # started by the operator via .forge/checks/forge-jarvis.sh. Unlike board:,
144
+ # # absence does NOT mean inert — the launcher is operator-invoked, never
145
+ # # ambient, and works with no block (defaults below). See docs/jarvis.md.
146
+ # enabled: true # explicit false = the launcher refuses (the door is switched off)
147
+ # name_suffix: "" # appended to the sticky name jarvis-<repo-basename>; on multi-machine
148
+ # # repos each machine overrides via env FORGE_JARVIS_NAME_SUFFIX so two
149
+ # # live presences never share one name
150
+ # capacity: 4 # RC server session capacity (--capacity), default 4
151
+
141
152
  risks: # What could go wrong?
142
153
  - risk: ""
143
154
  mitigation: ""