forgedock 1.1.2 → 1.1.4
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/bin/engine/phases.mjs +8 -6
- package/bin/forgedock.mjs +90 -4
- package/bin/journey.mjs +70 -1
- package/bin/runner.mjs +3 -2
- package/commands/autopilot.md +510 -425
- package/commands/deploy-pr.md +485 -0
- package/commands/fix-ci.md +577 -0
- package/commands/recover-orphans.md +576 -0
- package/docs/CI.md +14 -0
- package/docs/eval/README.md +7 -4
- package/docs/site/command-reference.md +49 -0
- package/package.json +1 -1
- package/packages/protocol/src/parse.js +27 -2
|
@@ -278,6 +278,40 @@ Shows what will deploy next — diff between staging and main with issue/PR summ
|
|
|
278
278
|
|
|
279
279
|
---
|
|
280
280
|
|
|
281
|
+
### `/deploy-pr`
|
|
282
|
+
|
|
283
|
+
**PR ship orchestrator.**
|
|
284
|
+
|
|
285
|
+
Ships a branch to its deploy target — detects or creates the PR, runs CI fixing via `/fix-ci`, runs the review gate via `/review-pr`, merges after both pass, and returns a structured result. Designed to be invoked by `/autopilot` as part of the autonomous deploy loop.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
/deploy-pr staging # Ship staging → main
|
|
289
|
+
/deploy-pr milestone/my-feature # Ship milestone → staging
|
|
290
|
+
/deploy-pr feat/my-branch --target staging # Ship any branch → staging
|
|
291
|
+
/deploy-pr staging --dry-run # Simulate without merging
|
|
292
|
+
/deploy-pr staging --issue 1234 # Reference parent issue in PR body
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Branch routing**: `staging` → `main` (Deploy), `milestone/*` → `staging` (Ship), other → `staging` (Merge). Never force-merges. Returns `{ pr, source, target, status, ci_fixes, review_findings }`.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### `/fix-ci`
|
|
300
|
+
|
|
301
|
+
**Automated CI failure resolution loop.**
|
|
302
|
+
|
|
303
|
+
Diagnoses CI failures on a PR, applies targeted fixes, pushes new commits, and loops until green or max attempts reached. Invoked automatically by `/deploy-pr` as the CI gate step; can also be run directly.
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
/fix-ci 123 # Fix CI on PR #123
|
|
307
|
+
/fix-ci 123 --max-attempts 5 # Allow up to 5 fix iterations
|
|
308
|
+
/fix-ci 123 --repo owner/repo # Explicit repo
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Returns `{ pr, status, attempts, fixes_applied }`.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
281
315
|
#### `/rollback`
|
|
282
316
|
|
|
283
317
|
**Revert PR creator.**
|
|
@@ -370,6 +404,21 @@ Cleans up stale labels, missing workflow state, project board gaps, dangling wor
|
|
|
370
404
|
|
|
371
405
|
---
|
|
372
406
|
|
|
407
|
+
### `/recover-orphans`
|
|
408
|
+
|
|
409
|
+
**Pipeline orphan recovery.**
|
|
410
|
+
|
|
411
|
+
Scans for issues stuck in intermediate workflow states (building, investigating, in-review) where the agent died mid-pipeline. Diagnoses each orphan's actual GitHub state and applies the appropriate recovery action — re-entering the pipeline via `/work-on` or `/review-pr`.
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
/recover-orphans # Scan and recover all orphans
|
|
415
|
+
/recover-orphans --dry-run # Show orphans without recovering
|
|
416
|
+
/recover-orphans --since 24 # Only orphans stalled > 24 hours
|
|
417
|
+
/recover-orphans --issue 42 # Recover a specific issue
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
373
422
|
#### `/pipeline-health`
|
|
374
423
|
|
|
375
424
|
**Pipeline performance analyzer.**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forgedock",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Autonomous dev pipeline for Claude Code. GitHub as institutional memory — every issue, PR, and annotation survives context resets and makes the next agent smarter.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"forgedock": "bin/forgedock.mjs"
|
|
@@ -98,6 +98,31 @@ function escapeRegExp(str) {
|
|
|
98
98
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Reverse the HTML entity escapes applied by emit()'s sanitizeFieldValue().
|
|
103
|
+
*
|
|
104
|
+
* emit() escapes three HTML comment delimiter sequences to protect GitHub's
|
|
105
|
+
* renderer from comment injection:
|
|
106
|
+
* 1. `<!--` → `<!--` (forge#1638)
|
|
107
|
+
* 2. `--!>` → `--!>` (forge#1594)
|
|
108
|
+
* 3. `-->` → `-->` (forge#1594)
|
|
109
|
+
*
|
|
110
|
+
* parse() must apply the inverse so that round-tripping through emit → parse
|
|
111
|
+
* is lossless. Unescape order: `--!>` before `-->` (most-specific first)
|
|
112
|
+
* to avoid the `!` being left dangling by an overly-greedy `-->` pass.
|
|
113
|
+
* The `<!--` unescape is independent and can run in any relative order.
|
|
114
|
+
* (forge#1662)
|
|
115
|
+
*
|
|
116
|
+
* @param {string} raw
|
|
117
|
+
* @returns {string}
|
|
118
|
+
*/
|
|
119
|
+
function unescapeFieldValue(raw) {
|
|
120
|
+
return raw
|
|
121
|
+
.replace(/--!>/g, '--!>')
|
|
122
|
+
.replace(/-->/g, '-->')
|
|
123
|
+
.replace(/<!--/g, '<!--');
|
|
124
|
+
}
|
|
125
|
+
|
|
101
126
|
/**
|
|
102
127
|
* Extract **Key**: value fields from an annotation body.
|
|
103
128
|
*
|
|
@@ -109,7 +134,7 @@ function extractFields(body) {
|
|
|
109
134
|
for (const line of body.split('\n')) {
|
|
110
135
|
const m = line.trim().match(BOLD_FIELD_RE);
|
|
111
136
|
if (m) {
|
|
112
|
-
fields[m[1].trim()] = m[2].trim();
|
|
137
|
+
fields[unescapeFieldValue(m[1].trim())] = unescapeFieldValue(m[2].trim());
|
|
113
138
|
}
|
|
114
139
|
}
|
|
115
140
|
return fields;
|
|
@@ -169,7 +194,7 @@ export function parse(commentBody) {
|
|
|
169
194
|
continue;
|
|
170
195
|
}
|
|
171
196
|
|
|
172
|
-
const inlineValue = rawInlineValue;
|
|
197
|
+
const inlineValue = rawInlineValue !== null ? unescapeFieldValue(rawInlineValue) : null;
|
|
173
198
|
const typeDef = typeDefForTag;
|
|
174
199
|
const isControl = typeDef?.controlMarker === true;
|
|
175
200
|
const isReserved = RESERVED_TYPE_NAMES.has(type);
|