@moretea-labs/forge 1.7.0 → 1.7.1

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 (175) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +13 -0
  3. package/CLAUDE.md +2 -0
  4. package/THIRD_PARTY_NOTICES.md +1 -1
  5. package/agents/openai.yaml +1 -1
  6. package/assets/partials-agents/02-operating-mode.partial.md +2 -0
  7. package/assets/plugin-registry.v1.json +3 -3
  8. package/assets/skill-version.json +2 -2
  9. package/assets/templates/helpers/check-architecture-sync.sh +17 -0
  10. package/assets/templates/helpers/inspect-project-state.ts +8 -6
  11. package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
  12. package/assets/templates/helpers/workflow-contract.ts +5 -1
  13. package/docs/architecture/CURRENT.md +12 -4
  14. package/docs/forge-plugin-management.md +1 -1
  15. package/docs/operations/controller-performance-and-502.md +19 -0
  16. package/docs/operations/homebrew.md +2 -2
  17. package/package.json +5 -2
  18. package/scripts/architecture-event.ts +2 -820
  19. package/scripts/architecture-queue.sh +2 -645
  20. package/scripts/archive-architecture-request.sh +2 -242
  21. package/scripts/archive-workflow.sh +1 -291
  22. package/scripts/benchmark-work-efficiency.ts +0 -0
  23. package/scripts/capability-config.ts +2 -392
  24. package/scripts/capability-resolver.ts +2 -503
  25. package/scripts/capture-plan.sh +1 -332
  26. package/scripts/check-agent-tooling.sh +2 -1531
  27. package/scripts/check-architecture-sync.sh +2 -302
  28. package/scripts/check-brain-manifest.sh +2 -253
  29. package/scripts/check-context-files.sh +2 -47
  30. package/scripts/check-deploy-sql-order.sh +2 -115
  31. package/scripts/check-runtime-architecture.mjs +243 -16
  32. package/scripts/check-skill-version.ts +3 -191
  33. package/scripts/check-source-duplication.mjs +61 -0
  34. package/scripts/check-stable-baseline.ts +0 -0
  35. package/scripts/check-task-sync.sh +2 -63
  36. package/scripts/check-task-workflow.sh +2 -1000
  37. package/scripts/codex-handoff-resume.sh +2 -267
  38. package/scripts/context-contract-sync.sh +2 -514
  39. package/scripts/contract-run.ts +2 -463
  40. package/scripts/contract-worktree.sh +1 -702
  41. package/scripts/ensure-task-workflow.sh +1 -1192
  42. package/scripts/inspect-project-state.ts +4 -279
  43. package/scripts/lib/project-init-lib.sh +7 -2
  44. package/scripts/lib/run-forge-helper.sh +19 -0
  45. package/scripts/lib/run-forge-helper.ts +26 -0
  46. package/scripts/migrate-project-template.sh +1 -33
  47. package/scripts/migrate-workflow-docs.ts +4 -412
  48. package/scripts/new-plan.sh +1 -180
  49. package/scripts/new-spec.sh +1 -47
  50. package/scripts/new-sprint.sh +1 -46
  51. package/scripts/plan-to-todo.sh +1 -771
  52. package/scripts/prepare-codex-handoff.sh +2 -201
  53. package/scripts/prepare-handoff.sh +1 -78
  54. package/scripts/refresh-current-status.sh +2 -467
  55. package/scripts/run-governed-gate.ts +3 -0
  56. package/scripts/select-agent-context-blocks.sh +2 -64
  57. package/scripts/ship-worktrees.sh +1 -531
  58. package/scripts/sprint-backlog.sh +1 -834
  59. package/scripts/stage-runtime-release.ts +2 -1
  60. package/scripts/summarize-failures.sh +2 -123
  61. package/scripts/switch-plan.sh +1 -150
  62. package/scripts/sync-brain-docs.sh +2 -379
  63. package/scripts/sync-generated-authority.mjs +175 -0
  64. package/scripts/verify-contract.sh +2 -593
  65. package/scripts/verify-sprint.sh +1 -500
  66. package/scripts/workflow-contract.ts +4 -201
  67. package/scripts/workstream-sync.sh +2 -261
  68. package/src/cli/agent-jobs/executor-health.ts +1 -1
  69. package/src/cli/commands/plugin.ts +12 -3
  70. package/src/cli/controller/check-runner.ts +7 -2
  71. package/src/cli/controller/context-pack.ts +46 -21
  72. package/src/cli/github/contracts.ts +16 -0
  73. package/src/cli/github/github.ts +2 -16
  74. package/src/cli/github/session.ts +2 -1
  75. package/src/cli/local-bridge/facade-api.ts +37 -47
  76. package/src/cli/local-bridge/server.ts +2 -2
  77. package/src/cli/mcp/legacy-tool-service.ts +10 -33
  78. package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
  79. package/src/cli/mcp/repository-tools.ts +85 -89
  80. package/src/cli/mcp/server.ts +57 -13
  81. package/src/cli/mcp/tool-contract.ts +14 -0
  82. package/src/cli/mcp/toolset.ts +2 -2
  83. package/src/cli/mcp/transports/http.ts +23 -0
  84. package/src/cli/repositories/command-classifier.ts +2 -2
  85. package/src/cli/repositories/command-executor.ts +24 -6
  86. package/src/cli/repositories/repository-snapshot.ts +5 -2
  87. package/src/cli/repositories/structured-git.ts +57 -3
  88. package/src/cli/repository/inspector.ts +11 -3
  89. package/src/runtime/context/generic-lsp-provider.ts +1 -1
  90. package/src/runtime/context/semantic-navigation-contract.ts +61 -0
  91. package/src/runtime/context/semantic-navigation.ts +9 -61
  92. package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +18 -25
  93. package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
  94. package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
  95. package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
  96. package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
  97. package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
  98. package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
  99. package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
  100. package/src/runtime/control-plane/execution/work-handle-store.ts +1 -1
  101. package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
  102. package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
  103. package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
  104. package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
  105. package/src/runtime/control-plane/execution/work-task-receipt.ts +4 -43
  106. package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +13 -3
  107. package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
  108. package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
  109. package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
  110. package/src/runtime/control-plane/facade/controller-round-relay.ts +164 -37
  111. package/src/runtime/control-plane/facade/controller-session-store.ts +183 -24
  112. package/src/runtime/control-plane/facade/goal-workloop-access.ts +15 -1
  113. package/src/runtime/control-plane/facade/goal-workloop.ts +329 -148
  114. package/src/runtime/control-plane/facade/index.ts +2 -0
  115. package/src/runtime/control-plane/facade/plan-contract-store.ts +90 -22
  116. package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
  117. package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
  118. package/src/runtime/control-plane/facade/types.ts +68 -5
  119. package/src/runtime/control-plane/facade/work-contract-store.ts +3 -209
  120. package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
  121. package/src/runtime/control-plane/global-scheduler/maintenance.ts +14 -7
  122. package/src/runtime/control-plane/global-scheduler/scheduler.ts +5 -1
  123. package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +13 -0
  124. package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +15 -6
  125. package/src/runtime/control-plane/launcher/launch-reservation-store.ts +54 -5
  126. package/src/runtime/control-plane/launcher/thin-launcher.ts +56 -7
  127. package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
  128. package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
  129. package/src/runtime/control-plane/routing/route-policy.ts +18 -6
  130. package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
  131. package/src/runtime/evidence/process-check-execution.ts +18 -0
  132. package/src/runtime/execution/jobs/child-reference.ts +6 -2
  133. package/src/runtime/execution/process-runtime/check-result.ts +53 -18
  134. package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
  135. package/src/runtime/execution/process-runtime/command-facade.ts +39 -17
  136. package/src/runtime/execution/process-runtime/lightweight-managed.ts +20 -3
  137. package/src/runtime/execution/process-runtime/persisted-check.ts +4 -1
  138. package/src/runtime/execution/process-runtime/runtime.ts +10 -0
  139. package/src/runtime/execution/process-runtime/types.ts +2 -12
  140. package/src/runtime/execution/work-activity.ts +21 -0
  141. package/src/runtime/execution/workers/executor.ts +18 -13
  142. package/src/runtime/gateway/mcp/execution-tools.ts +35 -2930
  143. package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
  144. package/src/runtime/gateway/mcp/router.ts +2 -2
  145. package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +21 -2
  146. package/src/runtime/gateway/mcp/runtime-tools.ts +805 -1009
  147. package/src/runtime/plugins/app-store-connect-adapter.ts +93 -28
  148. package/src/runtime/plugins/browser-adapter.ts +256 -1083
  149. package/src/runtime/plugins/browser-handoff-host.ts +2 -25
  150. package/src/runtime/plugins/browser-handoff.ts +18 -3
  151. package/src/runtime/plugins/browser-macos-bridge.ts +121 -16
  152. package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
  153. package/src/runtime/plugins/browser-native-session-service.ts +222 -0
  154. package/src/runtime/plugins/browser-runtime-contract.ts +2 -0
  155. package/src/runtime/plugins/browser-runtime.ts +10 -0
  156. package/src/runtime/plugins/browser-session-store.ts +121 -0
  157. package/src/runtime/plugins/browser-session-types.ts +98 -0
  158. package/src/runtime/plugins/desktop-operator-registration.ts +4 -4
  159. package/src/runtime/plugins/external-adapter.ts +92 -58
  160. package/src/runtime/plugins/macos-capability-broker.ts +0 -8
  161. package/src/runtime/plugins/store.ts +66 -9
  162. package/src/runtime/plugins/types.ts +3 -1
  163. package/src/runtime/recovery/maintenance-executor.ts +61 -25
  164. package/src/runtime/root/package-connector-service.ts +46 -4
  165. package/src/runtime/root/package-runtime-release.ts +1 -1
  166. package/src/runtime/root/package-runtime-service.ts +33 -2
  167. package/src/runtime/root/release-manifest.ts +137 -16
  168. package/src/runtime/root/release-materialize.ts +109 -35
  169. package/src/runtime/root/types.ts +10 -0
  170. package/src/runtime/standalone-recovery/core.ts +425 -194
  171. package/src/runtime/standalone-recovery/entry.ts +1 -1
  172. package/src/runtime/standalone-recovery/installer.ts +1 -1
  173. package/src/runtime/workflow/schedules/engine.ts +113 -87
  174. package/src/runtime/workflow/schedules/settlement.ts +26 -23
  175. package/src/runtime/workflow/schedules/store.ts +79 -10
@@ -1,469 +1,4 @@
1
1
  #!/bin/bash
2
2
  set -euo pipefail
3
-
4
- usage() {
5
- cat <<'USAGE_EOF'
6
- Usage: scripts/refresh-current-status.sh [--write] [--clear] [--reason <reason>] [--target <branch>]
7
-
8
- Refresh the tracked tasks/current.md read model from repo-local workflow
9
- artifacts. By default this prints a preview. Use --write to update the file.
10
- USAGE_EOF
11
- }
12
-
13
- write=0
14
- clear=0
15
- reason="manual"
16
- target_override=""
17
- current_status_file="tasks/current.md"
18
- stale_after="24h"
19
-
20
- while [[ $# -gt 0 ]]; do
21
- case "$1" in
22
- --write)
23
- write=1
24
- shift
25
- ;;
26
- --clear)
27
- clear=1
28
- shift
29
- ;;
30
- --reason)
31
- [[ -n "${2:-}" ]] || { echo "refresh-current-status: --reason requires a value" >&2; exit 2; }
32
- reason="$2"
33
- shift 2
34
- ;;
35
- --target)
36
- [[ -n "${2:-}" ]] || { echo "refresh-current-status: --target requires a value" >&2; exit 2; }
37
- target_override="$2"
38
- shift 2
39
- ;;
40
- --help|-h)
41
- usage
42
- exit 0
43
- ;;
44
- *)
45
- echo "refresh-current-status: unknown argument: $1" >&2
46
- usage >&2
47
- exit 2
48
- ;;
49
- esac
50
- done
51
-
52
- policy_file=".ai/harness/policy.json"
53
-
54
- json_get() {
55
- local path="$1"
56
- local default_value="${2:-}"
57
- local value
58
-
59
- if [[ -f "$policy_file" ]] && command -v jq >/dev/null 2>&1; then
60
- value="$(jq -r "$path // empty" "$policy_file" 2>/dev/null || true)"
61
- if [[ -n "$value" && "$value" != "null" ]]; then
62
- printf '%s' "$value"
63
- return 0
64
- fi
65
- fi
66
-
67
- printf '%s' "$default_value"
68
- }
69
-
70
- target_branch() {
71
- if [[ -n "$target_override" ]]; then
72
- printf '%s' "$target_override"
73
- return 0
74
- fi
75
-
76
- local target
77
- target="$(json_get '.worktree_strategy.merge_back.target' '')"
78
- if [[ -z "$target" ]]; then
79
- target="$(json_get '.worktree_strategy.base_branch' 'main')"
80
- fi
81
- printf '%s' "${target:-main}"
82
- }
83
-
84
- current_branch() {
85
- local branch
86
- branch="$(git branch --show-current 2>/dev/null || true)"
87
- printf '%s' "${branch:-detached}"
88
- }
89
-
90
- source_commit() {
91
- git rev-parse --short HEAD 2>/dev/null || printf '(none)'
92
- }
93
-
94
- timestamp_now() {
95
- date '+%Y-%m-%dT%H:%M:%S%z'
96
- }
97
-
98
- file_metadata_value() {
99
- local file="$1"
100
- local label="$2"
101
- [[ -f "$file" ]] || return 1
102
- awk -v label="$label" '
103
- $0 ~ "^> \\*\\*" label "\\*\\*:" {
104
- sub("^> \\*\\*" label "\\*\\*: *", "")
105
- gsub(/\r/, "")
106
- print
107
- exit
108
- }
109
- ' "$file" | xargs
110
- }
111
-
112
- read_plan_status() {
113
- local plan_file="$1"
114
- file_metadata_value "$plan_file" "Status" || true
115
- }
116
-
117
- normalize_plan_path() {
118
- local worktree="$1"
119
- local plan_path="$2"
120
- if [[ -z "$plan_path" ]]; then
121
- return 1
122
- fi
123
- if [[ "$plan_path" == /* ]]; then
124
- printf '%s' "$plan_path"
125
- else
126
- printf '%s/%s' "$worktree" "$plan_path"
127
- fi
128
- }
129
-
130
- append_unique_line() {
131
- local line="$1"
132
- [[ -n "$line" ]] || return 0
133
- if ! printf '%s\n' "$active_refs" | grep -Fxq -- "$line"; then
134
- active_refs="${active_refs}${line}"$'\n'
135
- fi
136
- }
137
-
138
- inspect_worktree_active_state() {
139
- local worktree="$1"
140
- local rel_worktree="$2"
141
- local marker plan_path plan_abs owner
142
-
143
- for marker in ".ai/harness/active-plan" ".claude/.active-plan"; do
144
- [[ -f "$worktree/$marker" ]] || continue
145
- plan_path="$(cat "$worktree/$marker" 2>/dev/null | xargs || true)"
146
- [[ -n "$plan_path" ]] || continue
147
- plan_abs="$(normalize_plan_path "$worktree" "$plan_path")"
148
- if [[ -f "$plan_abs" ]]; then
149
- append_unique_line "- ${rel_worktree}: ${plan_path}"
150
- else
151
- append_unique_line "- ${rel_worktree}: stale active-plan marker -> ${plan_path}"
152
- fi
153
- done
154
-
155
- if [[ -f "$worktree/.ai/harness/active-worktree" ]]; then
156
- owner="$(cat "$worktree/.ai/harness/active-worktree" 2>/dev/null | xargs || true)"
157
- if [[ -n "$owner" ]]; then
158
- append_unique_line "- ${rel_worktree}: active-worktree owner -> ${owner}"
159
- fi
160
- fi
161
- }
162
-
163
- collect_active_work_refs() {
164
- local root current_path worktree_path
165
- active_refs=""
166
- current_path="$(pwd -P 2>/dev/null || pwd)"
167
- inspect_worktree_active_state "$current_path" "."
168
-
169
- if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
170
- while IFS= read -r worktree_path; do
171
- [[ -n "$worktree_path" ]] || continue
172
- [[ "$worktree_path" == "$current_path" ]] && continue
173
- inspect_worktree_active_state "$worktree_path" "$worktree_path"
174
- done < <(git worktree list --porcelain 2>/dev/null | awk '$1 == "worktree" { sub(/^worktree /, ""); print }')
175
- fi
176
-
177
- printf '%s' "$active_refs"
178
- }
179
-
180
- read_current_active_plan() {
181
- local marker plan_path plan_abs current_path
182
- current_path="$(pwd -P 2>/dev/null || pwd)"
183
- for marker in ".ai/harness/active-plan" ".claude/.active-plan"; do
184
- [[ -f "$marker" ]] || continue
185
- plan_path="$(cat "$marker" 2>/dev/null | xargs || true)"
186
- [[ -n "$plan_path" ]] || continue
187
- plan_abs="$(normalize_plan_path "$current_path" "$plan_path")"
188
- if [[ -f "$plan_abs" ]]; then
189
- printf '%s' "$plan_path"
190
- return 0
191
- fi
192
- done
193
- return 1
194
- }
195
-
196
- next_plan_task() {
197
- local plan_file="$1"
198
- [[ -f "$plan_file" ]] || { printf '(none)'; return 0; }
199
- awk '
200
- BEGIN { in_section = 0 }
201
- /^## Task Breakdown[[:space:]]*$/ { in_section = 1; next }
202
- in_section && /^## / { exit }
203
- in_section && /^[[:space:]]*-[[:space:]]\[[[:space:]]\][[:space:]]+/ {
204
- line = $0
205
- sub(/^[[:space:]]*-[[:space:]]\[[[:space:]]\][[:space:]]+/, "", line)
206
- gsub(/\r/, "", line)
207
- print line
208
- found = 1
209
- exit
210
- }
211
- END { if (!found) print "(none)" }
212
- ' "$plan_file"
213
- }
214
-
215
- handoff_next_step() {
216
- local handoff_file
217
- handoff_file="$(json_get '.session.continuation_file' '.ai/harness/session/continuation.md')"
218
- [[ -f "$handoff_file" ]] || { printf '(none)'; return 0; }
219
- awk '
220
- /^## Exact Next Step[[:space:]]*$/ { in_section = 1; next }
221
- /^## / && in_section { exit }
222
- in_section && /^[[:space:]]*-[[:space:]]+/ {
223
- line = $0
224
- sub(/^[[:space:]]*-[[:space:]]+/, "", line)
225
- print line
226
- found = 1
227
- exit
228
- }
229
- END { if (!found) print "(none)" }
230
- ' "$handoff_file"
231
- }
232
-
233
- checks_summary() {
234
- local checks_file status source exit_code
235
- checks_file="$(json_get '.harness.checks_file' '.ai/harness/checks/latest.json')"
236
- [[ -s "$checks_file" ]] || { printf 'status=(none), source=(none), file=%s' "$checks_file"; return 0; }
237
-
238
- if command -v jq >/dev/null 2>&1; then
239
- status="$(jq -r '.status // "(none)"' "$checks_file" 2>/dev/null || printf '(unreadable)')"
240
- source="$(jq -r '.source // "(none)"' "$checks_file" 2>/dev/null || printf '(unreadable)')"
241
- exit_code="$(jq -r '.exit_code // "(none)"' "$checks_file" 2>/dev/null || printf '(unreadable)')"
242
- printf 'status=%s, source=%s, exit_code=%s, file=%s' "$status" "$source" "$exit_code" "$checks_file"
243
- return 0
244
- fi
245
-
246
- printf 'file=%s' "$checks_file"
247
- }
248
-
249
- workstream_summary() {
250
- local workstreams_dir file count status current_slice source_plan
251
- workstreams_dir="$(json_get '.tasks.workstreams_dir' 'tasks/workstreams')"
252
- [[ -d "$workstreams_dir" ]] || { printf -- '- (none)\n'; return 0; }
253
-
254
- count=0
255
- while IFS= read -r file; do
256
- [[ -n "$file" ]] || continue
257
- status="$(file_metadata_value "$file" "Status" || printf 'unknown')"
258
- current_slice="$(file_metadata_value "$file" "Current Slice" || printf 'unknown')"
259
- source_plan="$(file_metadata_value "$file" "Source Plan" || printf 'unknown')"
260
- printf -- '- `%s`: status=%s, current_slice=%s, source_plan=%s\n' "$file" "$status" "$current_slice" "$source_plan"
261
- count=$((count + 1))
262
- [[ "$count" -ge 8 ]] && break
263
- done < <(find "$workstreams_dir" -type f -name '*.md' 2>/dev/null | sort)
264
-
265
- [[ "$count" -gt 0 ]] || printf -- '- (none)\n'
266
- }
267
-
268
- sprint_backlog_progress() {
269
- local sprint_file="$1"
270
- awk -F '|' '
271
- /^## Backlog[[:space:]]*$/ { in_section = 1; next }
272
- in_section && /^## / { exit }
273
- !in_section { next }
274
- /^\|[[:space:]]*[0-9]+[[:space:]]*\|/ {
275
- total++
276
- cell = $3
277
- gsub(/^[[:space:]]+|[[:space:]]+$/, "", cell)
278
- if (cell ~ /^\[[xX]\]$/) done++
279
- }
280
- END { printf "%d/%d", done + 0, total + 0 }
281
- ' "$sprint_file"
282
- }
283
-
284
- sprint_next_task() {
285
- local sprint_file="$1"
286
- awk -F '|' '
287
- /^## Backlog[[:space:]]*$/ { in_section = 1; next }
288
- in_section && /^## / { exit }
289
- !in_section { next }
290
- /^\|[[:space:]]*[0-9]+[[:space:]]*\|/ {
291
- status = $3; task = $4
292
- gsub(/^[[:space:]]+|[[:space:]]+$/, "", status)
293
- gsub(/^[[:space:]]+|[[:space:]]+$/, "", task)
294
- if (status == "[ ]") { print task; found = 1; exit }
295
- }
296
- END { if (!found) print "(none)" }
297
- ' "$sprint_file"
298
- }
299
-
300
- sprint_summary() {
301
- local marker sprint_file status
302
- marker="$(json_get '.sprints.active_marker_file' '.ai/harness/sprint/active-sprint')"
303
- if [[ ! -f "$marker" ]]; then
304
- printf -- '- Sprint: (none)\n'
305
- return 0
306
- fi
307
-
308
- sprint_file="$(cat "$marker" 2>/dev/null | xargs || true)"
309
- if [[ -z "$sprint_file" || ! -f "$sprint_file" ]]; then
310
- printf -- '- Sprint: stale active-sprint marker -> %s\n' "${sprint_file:-(empty)}"
311
- return 0
312
- fi
313
-
314
- status="$(file_metadata_value "$sprint_file" "Status" || printf 'unknown')"
315
- printf -- '- Sprint: `%s`\n' "$sprint_file"
316
- printf -- '- Sprint Status: %s\n' "${status:-unknown}"
317
- printf -- '- Backlog: %s\n' "$(sprint_backlog_progress "$sprint_file")"
318
- printf -- '- Next Sprint Task: %s\n' "$(sprint_next_task "$sprint_file")"
319
- }
320
-
321
- git_status_summary() {
322
- if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
323
- printf 'not a git repository'
324
- return 0
325
- fi
326
-
327
- local count
328
- count="$(git_status_short_filtered | sed '/^[[:space:]]*$/d' | wc -l | tr -d ' ')"
329
- if [[ "${count:-0}" -eq 0 ]]; then
330
- printf 'clean'
331
- else
332
- printf '%s changed/untracked path(s)' "$count"
333
- fi
334
- }
335
-
336
- git_status_short_filtered() {
337
- git status --short 2>/dev/null | grep -Ev '^[? MARCUD!]{2}[[:space:]]+tasks/\.current\.md\.tmp\.[^[:space:]]+$' || true
338
- }
339
-
340
- git_status_files() {
341
- if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
342
- printf '(none)\n'
343
- return 0
344
- fi
345
- local files
346
- files="$(git_status_short_filtered | head -40)"
347
- if [[ -n "$files" ]]; then
348
- printf '%s\n' "$files"
349
- else
350
- printf '(none)\n'
351
- fi
352
- }
353
-
354
- render_status() {
355
- local now branch commit target active_work active_plan plan_status next_task status clear_note
356
- local checks git_summary handoff_next
357
- now="$(timestamp_now)"
358
- branch="$(current_branch)"
359
- commit="$(source_commit)"
360
- target="$(target_branch)"
361
- active_work="$(collect_active_work_refs)"
362
- active_plan="$(read_current_active_plan || true)"
363
- plan_status="(none)"
364
- next_task="(none)"
365
- if [[ -n "$active_plan" && -f "$active_plan" ]]; then
366
- plan_status="$(read_plan_status "$active_plan")"
367
- plan_status="${plan_status:-unknown}"
368
- next_task="$(next_plan_task "$active_plan")"
369
- elif [[ -n "$active_work" ]]; then
370
- next_task="inspect active worktree marker(s)"
371
- fi
372
-
373
- if [[ "$clear" -eq 1 && -n "$active_work" ]]; then
374
- status="ManualClearedWithActiveWork"
375
- clear_note="Manual clear requested, but active work markers still exist. Idle was not written."
376
- elif [[ -n "$active_work" ]]; then
377
- status="Active"
378
- clear_note="(none)"
379
- else
380
- status="Idle"
381
- clear_note="(none)"
382
- fi
383
-
384
- checks="$(checks_summary)"
385
- git_summary="$(git_status_summary)"
386
- handoff_next="$(handoff_next_step)"
387
-
388
- cat <<EOF_STATUS
389
- # Current Status Snapshot
390
-
391
- <!-- generated-by: forge refresh-current-status v1 -->
392
- <!-- updated_at: ${now} -->
393
- <!-- stale_after: ${stale_after} -->
394
-
395
- > **Status**: ${status}
396
- > **Updated At**: ${now}
397
- > **Source Branch**: ${branch}
398
- > **Source Commit**: ${commit}
399
- > **Target Branch**: ${target}
400
- > **Stale After**: ${stale_after}
401
- > **Reason**: ${reason}
402
- > **Derived From**: active-plan, active-sprint, workstreams, handoff, checks, git status
403
-
404
- This file is a tracked mainline snapshot derived from repo artifacts. It is not a live lock, not a kanban board, and not an implementation gate. If it is stale, read the source artifacts below.
405
-
406
- ## Current Focus
407
-
408
- - Status: ${status}
409
- - Active Plan: ${active_plan:-(none)}
410
- - Plan Status: ${plan_status}
411
- - Next Task: ${next_task}
412
- - Clear Note: ${clear_note}
413
-
414
- ## Mainline Snapshot Reading
415
-
416
- - Current worktree: \`tasks/current.md\`
417
- - Target branch snapshot: \`git show ${target}:tasks/current.md\`
418
- - Rule: non-target worktrees may read the target branch snapshot, but must verify against source artifacts before acting.
419
-
420
- ## Active Work
421
-
422
- ${active_work:-- (none)}
423
- ## Active Sprint
424
-
425
- $(sprint_summary)
426
- ## Workstreams
427
-
428
- $(workstream_summary)
429
- ## Handoff
430
-
431
- - Exact Next Step: ${handoff_next}
432
-
433
- ## Checks
434
-
435
- - ${checks}
436
-
437
- ## Git Status
438
-
439
- - Summary: ${git_summary}
440
-
441
- \`\`\`
442
- $(git_status_files)
443
- \`\`\`
444
-
445
- ## Source Artifacts
446
-
447
- - Plans: \`plans/plan-*.md\`
448
- - Active marker: \`.ai/harness/active-plan\`
449
- - Active worktree marker: \`.ai/harness/active-worktree\`
450
- - PRDs: \`plans/prds/*.prd.md\`
451
- - Sprints: \`$(json_get '.sprints.dir' 'plans/sprints')/*.sprint.md\`
452
- - Active sprint marker: \`.ai/harness/sprint/active-sprint\`
453
- - Workstreams: \`tasks/workstreams/**/*.md\`
454
- - Handoff: \`.ai/harness/session/continuation.md\`
455
- - Checks: \`.ai/harness/checks/latest.json\`
456
- EOF_STATUS
457
- }
458
-
459
- if [[ "$write" -eq 1 ]]; then
460
- mkdir -p "$(dirname "$current_status_file")"
461
- tmp_file="$(mktemp "$(dirname "$current_status_file")/.current.md.tmp.XXXXXX")"
462
- trap 'rm -f "$tmp_file"' EXIT
463
- render_status > "$tmp_file"
464
- mv "$tmp_file" "$current_status_file"
465
- trap - EXIT
466
- echo "[CurrentStatus] Wrote ${current_status_file}."
467
- else
468
- render_status
469
- fi
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ exec "$SCRIPT_DIR/lib/run-forge-helper.sh" "refresh-current-status.sh" "$@"
@@ -17,6 +17,9 @@ export function stepsFor(gate: Gate): Step[] {
17
17
  if (gate === 'task') return [
18
18
  { label: 'typecheck', command: 'bun', args: ['run', 'check:type'], timeoutMs: 10 * 60_000 },
19
19
  { label: 'static architecture', command: 'bun', args: ['run', 'check:runtime-architecture'], timeoutMs: 5 * 60_000 },
20
+ { label: 'generated authority', command: 'node', args: ['scripts/sync-generated-authority.mjs', '--check'], timeoutMs: 2 * 60_000 },
21
+ { label: 'source duplication', command: 'node', args: ['scripts/check-source-duplication.mjs'], timeoutMs: 2 * 60_000 },
22
+ { label: 'controller UI bundle', command: 'bun', args: ['run', 'check:controller-ui'], timeoutMs: 5 * 60_000 },
20
23
  { label: 'test manifest', command: 'bun', args: ['run', 'check:test-governance'], timeoutMs: 5 * 60_000 },
21
24
  { label: 'affected tests', command: 'bun', args: ['run', 'test'], timeoutMs: 30 * 60_000 },
22
25
  ];
@@ -1,66 +1,4 @@
1
1
  #!/bin/bash
2
2
  set -euo pipefail
3
-
4
- repo="${1:-.}"
5
- repo="$(cd "$repo" && pwd)"
6
- config_file="${FORGE_CONTEXT_BLOCKS_FILE:-$repo/.ai/context/agent-context-blocks.txt}"
7
- registry_file="$repo/.ai/context/capabilities.json"
8
-
9
- emit_lines() {
10
- sed -e 's/#.*$//' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | sed '/^$/d'
11
- }
12
-
13
- emit_existing_dirs() {
14
- while IFS= read -r rel_dir; do
15
- rel_dir="${rel_dir#./}"
16
- rel_dir="${rel_dir%/}"
17
- [[ -z "$rel_dir" || "$rel_dir" == "." ]] && continue
18
- case "$rel_dir" in
19
- /*|../*|*/../*|*\"*)
20
- continue
21
- ;;
22
- esac
23
- [[ -d "$repo/$rel_dir" ]] || continue
24
- printf '%s\n' "$rel_dir"
25
- done | sort -u
26
- }
27
-
28
- if [[ -f "$registry_file" ]]; then
29
- if command -v bun >/dev/null 2>&1 && [[ -f "$repo/scripts/capability-resolver.ts" ]]; then
30
- (cd "$repo" && bun scripts/capability-resolver.ts list --format prefixes 2>/dev/null || true) | emit_existing_dirs
31
- exit 0
32
- fi
33
-
34
- if command -v node >/dev/null 2>&1; then
35
- node - "$registry_file" <<'JS_EOF' | emit_existing_dirs
36
- const fs = require("fs");
37
- const registry = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
38
- for (const capability of registry.capabilities || []) {
39
- for (const prefix of capability.prefixes || []) {
40
- console.log(prefix);
41
- }
42
- }
43
- JS_EOF
44
- exit 0
45
- fi
46
- fi
47
-
48
- context_blocks="${FORGE_CONTEXT_BLOCKS:-}"
49
- if [[ -n "$context_blocks" ]]; then
50
- printf '%s\n' "$context_blocks" | tr ',:' '\n' | emit_lines | emit_existing_dirs
51
- exit 0
52
- fi
53
-
54
- if [[ -f "$config_file" ]]; then
55
- emit_lines < "$config_file" | emit_existing_dirs
56
- exit 0
57
- fi
58
-
59
- find "$repo" \
60
- \( -path "$repo/.git" -o -path "$repo/node_modules" -o -path "$repo/.ai" -o -path "$repo/.claude" -o -path "$repo/_ref" -o -path "$repo/_ops" -o -path "$repo/.worktrees" \) -prune -o \
61
- \( -type f \( -name 'CLAUDE.md' -o -name 'AGENTS.md' \) \) -print 2>/dev/null | while IFS= read -r context_file; do
62
- context_dir="$(dirname "$context_file")"
63
- rel_dir="${context_dir#$repo/}"
64
- [[ "$rel_dir" == "$context_dir" || "$rel_dir" == "." ]] && continue
65
- printf '%s\n' "$rel_dir"
66
- done | sort -u
3
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4
+ exec "$SCRIPT_DIR/lib/run-forge-helper.sh" "select-agent-context-blocks.sh" "$@"