forge-workflow 0.1.0-beta.3 → 0.1.0-beta.5
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/AGENTS.md +14 -7
- package/CHANGELOG.md +43 -1
- package/README.md +6 -2
- package/bin/forge-cmd.js +21 -1
- package/bin/forge.js +16 -369
- package/docs/INDEX.md +1 -1
- package/docs/guides/BEADS_GITHUB_SYNC.md +2 -31
- package/docs/guides/MIGRATION.md +4 -4
- package/docs/guides/SETUP.md +16 -16
- package/docs/reference/COMMANDS.md +9 -4
- package/docs/reference/INSIGHTS_RECAP.md +9 -20
- package/docs/reference/RELEASE.md +5 -3
- package/docs/reference/TOOLCHAIN.md +8 -0
- package/docs/reference/protected-state-surfaces.md +4 -4
- package/docs/reference/shepherd.md +117 -17
- package/lefthook.yml +12 -0
- package/lib/activation/ensure-forge-home.js +33 -15
- package/lib/adapters/greptile-review-adapter.js +1 -1
- package/lib/adapters/pr-state-adapter.js +397 -100
- package/lib/agents-config.js +5 -0
- package/lib/audit-evidence.js +71 -110
- package/lib/capped-jsonl-log.js +236 -0
- package/lib/commands/_issue.js +31 -46
- package/lib/commands/_manifest.js +1 -1
- package/lib/commands/_registry.js +2 -2
- package/lib/commands/_resolve-command-opts.js +36 -29
- package/lib/commands/claim.js +2 -4
- package/lib/commands/clean.js +196 -32
- package/lib/commands/dev.js +4 -33
- package/lib/commands/hooks.js +358 -13
- package/lib/commands/insights.js +8 -3
- package/lib/commands/merge.js +600 -40
- package/lib/commands/plan.js +23 -115
- package/lib/commands/pr.js +1 -1
- package/lib/commands/preflight.js +11 -2
- package/lib/commands/prime.js +23 -3
- package/lib/commands/push.js +41 -51
- package/lib/commands/recall.js +60 -16
- package/lib/commands/recap.js +6 -1
- package/lib/commands/release.js +18 -4
- package/lib/commands/serve.js +5 -2
- package/lib/commands/setup.js +191 -95
- package/lib/commands/shepherd.js +49 -4
- package/lib/commands/ship.js +22 -23
- package/lib/commands/skill.js +383 -0
- package/lib/commands/status.js +54 -33
- package/lib/commands/test.js +56 -34
- package/lib/commands/worktree.js +247 -43
- package/lib/core/runtime-graph.js +89 -15
- package/lib/doc-assertions.js +297 -0
- package/lib/existing-tdd-gate.js +253 -0
- package/lib/forge-context.js +1 -4
- package/lib/forge-issues.js +64 -491
- package/lib/git-defaults.js +56 -0
- package/lib/harness-capability-matrix.js +5 -5
- package/lib/hook-renderer.js +147 -16
- package/lib/insights.js +96 -80
- package/lib/issue-backend.js +42 -3
- package/lib/kernel/backing-issue.js +14 -2
- package/lib/kernel/broker.js +44 -0
- package/lib/kernel/cli-broker-factory.js +12 -1
- package/lib/kernel/close-on-merge.js +154 -0
- package/lib/kernel/fs-class.js +42 -25
- package/lib/kernel/migrations.js +30 -2
- package/lib/kernel/schema.js +35 -0
- package/lib/kernel/sqlite-driver.js +292 -18
- package/lib/lefthook-wiring.js +21 -1
- package/lib/memory/router.js +16 -1
- package/lib/memory-digest.js +47 -15
- package/lib/memory-recall-events.js +145 -0
- package/lib/memory-recall.js +212 -0
- package/lib/merge-rules.js +8 -4
- package/lib/npm-publish-workflow.js +272 -0
- package/lib/orientation.js +371 -49
- package/lib/plugin-catalog.js +14 -4
- package/lib/pr-bundle.js +9 -6
- package/lib/pr-monitor/journal.js +18 -2
- package/lib/pr-monitor/reconcile-executor.js +842 -0
- package/lib/pr-monitor/reconcile-tick.js +138 -0
- package/lib/pr-monitor/reconcile.js +0 -0
- package/lib/pr-monitor/render-summary.js +196 -0
- package/lib/pr-monitor/shepherd-lease.js +252 -0
- package/lib/pr-monitor/watch-lifecycle.js +14 -2
- package/lib/pr-pull.js +98 -24
- package/lib/pr-shepherd.js +34 -8
- package/lib/preflight/gates.js +65 -18
- package/lib/preflight/runner.js +5 -0
- package/lib/project-memory.js +40 -0
- package/lib/protected-state-authority.js +305 -0
- package/lib/protected-state-surfaces.js +64 -44
- package/lib/release-readiness.js +51 -4
- package/lib/rules-sync.js +4 -0
- package/lib/runtime-health.js +15 -46
- package/lib/shell-utils.js +1 -1
- package/lib/skill-eval.js +750 -0
- package/lib/skills-sync.js +6 -3
- package/lib/smart-merge.js +28 -4
- package/lib/status/identity.js +46 -0
- package/lib/status/presenter.js +0 -35
- package/lib/status/snapshot.js +11 -16
- package/lib/symlink-utils.js +74 -26
- package/lib/upgrade-safety.js +47 -9
- package/lib/using-forge.js +328 -0
- package/lib/workflow/enforce-stage.js +5 -5
- package/lib/workflow/state-manager.js +23 -23
- package/package.json +6 -7
- package/rules/using-forge.md +24 -0
- package/scripts/doc-asserting-tests.js +158 -0
- package/scripts/forge-team/index.sh +0 -5
- package/scripts/forge-team/tests/dispatcher.test.sh +1 -1
- package/scripts/forge-team/tests/workflow-integration.test.sh +0 -1
- package/scripts/lib/behavioral-eval-runner.js +310 -0
- package/scripts/lib/behavioral-eval-runtime.js +456 -0
- package/scripts/lib/eval-evidence.js +328 -0
- package/scripts/lib/eval-runner.js +81 -41
- package/scripts/lib/immutable-eval-corpus.js +309 -0
- package/scripts/lib/promotion-evidence-loader.js +94 -0
- package/scripts/lib/promotion-scorecard.js +314 -0
- package/scripts/npm-release-receipt.js +134 -0
- package/scripts/process-tree.js +761 -0
- package/scripts/protected-state-check.js +47 -22
- package/scripts/run-command-eval.js +29 -1
- package/scripts/sync-d20-audit.js +172 -0
- package/scripts/test-full-suite.js +249 -37
- package/scripts/test.js +184 -44
- package/skills/claim-safety/SKILL.md +4 -0
- package/skills/claim-safety/evals/scorecard.json +41 -0
- package/skills/coverage.json +83 -0
- package/skills/dev/SKILL.md +4 -0
- package/skills/dev/evals/scorecard.json +41 -0
- package/skills/gates/SKILL.md +80 -0
- package/skills/gates/evals/evals.json +38 -0
- package/skills/gates/evals/scorecard.json +41 -0
- package/skills/hermes-forge/SKILL.md +1 -0
- package/skills/hermes-forge/evals/scorecard.json +41 -0
- package/skills/issue-basics/SKILL.md +1 -0
- package/skills/issue-basics/evals/scorecard.json +41 -0
- package/skills/kernel/SKILL.md +38 -0
- package/skills/kernel/evals/scorecard.json +41 -0
- package/skills/memory/SKILL.md +16 -1
- package/skills/memory/evals/scorecard.json +41 -0
- package/skills/parallel-deep-research/SKILL.md +1 -0
- package/skills/parallel-deep-research/evals/scorecard.json +41 -0
- package/skills/plan/SKILL.md +6 -0
- package/skills/plan/evals/scorecard.json +41 -0
- package/skills/portability/SKILL.md +47 -0
- package/skills/portability/evals/evals.json +34 -0
- package/skills/portability/evals/scorecard.json +41 -0
- package/skills/research/SKILL.md +1 -0
- package/skills/research/evals/scorecard.json +41 -0
- package/skills/review/SKILL.md +10 -11
- package/skills/review/evals/scorecard.json +41 -0
- package/skills/rollback/SKILL.md +5 -11
- package/skills/rollback/evals/scorecard.json +41 -0
- package/skills/setup/SKILL.md +91 -0
- package/skills/setup/evals/evals.json +42 -0
- package/skills/setup/evals/scorecard.json +41 -0
- package/skills/shepherd/SKILL.md +84 -38
- package/skills/shepherd/evals/evals.json +21 -9
- package/skills/shepherd/evals/scorecard.json +41 -0
- package/skills/ship/SKILL.md +10 -12
- package/skills/ship/evals/scorecard.json +41 -0
- package/skills/smith/SKILL.md +8 -0
- package/skills/smith/evals/scorecard.json +41 -0
- package/skills/sonarcloud/SKILL.md +1 -0
- package/skills/sonarcloud/evals/scorecard.json +41 -0
- package/skills/sonarcloud-analysis/SKILL.md +1 -0
- package/skills/sonarcloud-analysis/evals/scorecard.json +41 -0
- package/skills/status/SKILL.md +3 -0
- package/skills/status/evals/scorecard.json +41 -0
- package/skills/triage-ready/SKILL.md +2 -0
- package/skills/triage-ready/evals/scorecard.json +41 -0
- package/skills/using-forge/SKILL.md +104 -0
- package/skills/using-forge/evals/scorecard.json +41 -0
- package/skills/validate/SKILL.md +4 -0
- package/skills/validate/evals/scorecard.json +41 -0
- package/skills/verify/SKILL.md +4 -0
- package/skills/verify/evals/scorecard.json +41 -0
- package/skills/worktree/SKILL.md +92 -0
- package/skills/worktree/evals/evals.json +38 -0
- package/skills/worktree/evals/scorecard.json +41 -0
- package/lib/adapters/beads-issue-adapter.js +0 -127
- package/lib/beads-nudge.js +0 -91
- package/lib/beads-setup.js +0 -538
- package/lib/beads-sync-scaffold.js +0 -189
- package/lib/commands/board.js +0 -64
- package/lib/pat-setup.js +0 -207
- package/lib/pr-monitor/render-sticky.js +0 -192
- package/lib/pr-monitor/upsert-sticky.js +0 -169
- package/lib/status/beads-snapshot.js +0 -145
- package/scripts/beads-context.sh +0 -577
- package/scripts/beads-migrate-to-dolt.sh +0 -7
- package/scripts/beads-upgrade-smoke.sh +0 -284
- package/scripts/forge-team/lib/dashboard.sh +0 -316
- package/scripts/forge-team/tests/dashboard.test.sh +0 -155
- package/scripts/lib/beads-migrate-to-dolt.mjs +0 -503
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "worktree",
|
|
3
|
+
"fixtures": "present",
|
|
4
|
+
"static": {
|
|
5
|
+
"token_cost": {
|
|
6
|
+
"desc_chars": 1013,
|
|
7
|
+
"body_lines": 75,
|
|
8
|
+
"score": 43
|
|
9
|
+
},
|
|
10
|
+
"caps": {
|
|
11
|
+
"desc_within": true,
|
|
12
|
+
"body_within": true,
|
|
13
|
+
"score": 100
|
|
14
|
+
},
|
|
15
|
+
"description_quality": {
|
|
16
|
+
"has_trigger_cues": true,
|
|
17
|
+
"has_disambiguation_cues": true,
|
|
18
|
+
"adequate_length": true,
|
|
19
|
+
"score": 100
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"router_reachability": {
|
|
23
|
+
"has_curated_rule": true,
|
|
24
|
+
"router_exempt": false,
|
|
25
|
+
"fixtures": "present",
|
|
26
|
+
"fixtures_total": 6,
|
|
27
|
+
"fixtures_best_hit": 6,
|
|
28
|
+
"reachable": true,
|
|
29
|
+
"keyword_alignment": 1
|
|
30
|
+
},
|
|
31
|
+
"behavioral": {
|
|
32
|
+
"trigger_recall": null,
|
|
33
|
+
"trigger_precision": null,
|
|
34
|
+
"disambiguation": null,
|
|
35
|
+
"chain_correctness": null,
|
|
36
|
+
"outcome_quality": null,
|
|
37
|
+
"variance": null,
|
|
38
|
+
"note": "behavioral — W5 (LLM judge): semantic recall/precision/chain/outcome/variance, not deterministic"
|
|
39
|
+
},
|
|
40
|
+
"composite": 83
|
|
41
|
+
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {
|
|
4
|
-
IssueAdapter,
|
|
5
|
-
decideIssueAuthority,
|
|
6
|
-
normalizeIssueStatus,
|
|
7
|
-
} = require('../issue-adapter.js');
|
|
8
|
-
|
|
9
|
-
class BeadsIssueAdapter extends IssueAdapter {
|
|
10
|
-
constructor(options = {}) {
|
|
11
|
-
super({
|
|
12
|
-
id: options.id || 'beads',
|
|
13
|
-
kind: 'issue',
|
|
14
|
-
name: options.name || 'Beads Issue Adapter',
|
|
15
|
-
version: options.version || '0.1.0',
|
|
16
|
-
});
|
|
17
|
-
this.runBeadsOperation = options.runBeadsOperation;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
run(operation, args = [], context = {}) {
|
|
21
|
-
if (typeof this.runBeadsOperation !== 'function') {
|
|
22
|
-
throw new TypeError('runBeadsOperation is not configured on this adapter');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return this.runBeadsOperation(operation, args, context, context.deps || {});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
list(args = [], context = {}) {
|
|
29
|
-
return this.run('list', args, context);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
ready(args = [], context = {}) {
|
|
33
|
-
return this.run('ready', args, context);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
read(args = [], context = {}) {
|
|
37
|
-
return this.run('show', args, context);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
show(args = [], context = {}) {
|
|
41
|
-
return this.read(args, context);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
create(args = [], context = {}) {
|
|
45
|
-
return this.run('create', args, context);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
search(args = [], context = {}) {
|
|
49
|
-
return this.run('search', args, context);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
stats(args = [], context = {}) {
|
|
53
|
-
return this.run('stats', args, context);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
update(args = [], context = {}) {
|
|
57
|
-
return this.run('update', args, context);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
close(args = [], context = {}) {
|
|
61
|
-
return this.run('close', args, context);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
comment(args = [], context = {}) {
|
|
65
|
-
return this.run('comment', args, context);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
depAdd(args = [], context = {}) {
|
|
69
|
-
return this.run('dep.add', args, context);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
depRemove(args = [], context = {}) {
|
|
73
|
-
return this.run('dep.remove', args, context);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// De-bead parity: claim/release and the KAP-7/KAP-12 derived reads now route
|
|
77
|
-
// through the backend abstraction (the translations moved out of _issue.js). The
|
|
78
|
-
// beads layer maps claim -> `update <id> --claim`; release has no bd equivalent
|
|
79
|
-
// and returns the Kernel-only contract error (handled in runBeadsOperation).
|
|
80
|
-
claim(args = [], context = {}) {
|
|
81
|
-
return this.run('claim', args, context);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
release(args = [], context = {}) {
|
|
85
|
-
return this.run('release', args, context);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
blocked(args = [], context = {}) {
|
|
89
|
-
return this.run('blocked', args, context);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
stale(args = [], context = {}) {
|
|
93
|
-
return this.run('stale', args, context);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
orphans(args = [], context = {}) {
|
|
97
|
-
return this.run('orphans', args, context);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
lint(args = [], context = {}) {
|
|
101
|
-
return this.run('lint', args, context);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Lease ownership is Kernel-only; the beads layer returns the Kernel-only contract
|
|
105
|
-
// error (handled in runBeadsOperation), matching the release passthrough.
|
|
106
|
-
owns(args = [], context = {}) {
|
|
107
|
-
return this.run('owns', args, context);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Active-lease listing is Kernel-only (kernel_claims); the beads layer returns the
|
|
111
|
-
// Kernel-only contract error (handled in runBeadsOperation), matching owns/release.
|
|
112
|
-
claims(args = [], context = {}) {
|
|
113
|
-
return this.run('claims', args, context);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
mapStatus(status, context = {}) {
|
|
117
|
-
return normalizeIssueStatus(status, context);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
decideAuthority(change = {}, context = {}) {
|
|
121
|
-
return decideIssueAuthority(change, context);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
module.exports = {
|
|
126
|
-
BeadsIssueAdapter,
|
|
127
|
-
};
|
package/lib/beads-nudge.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { resolveIssueBackend } = require('./issue-backend');
|
|
4
|
-
const { detectBeadsJsonlSource } = require('./beads-detect');
|
|
5
|
-
|
|
6
|
-
// Unmigrated legacy-store nudge (kernel issue a5399f3d — upgrade-safety
|
|
7
|
-
// 0.0.10 -> current).
|
|
8
|
-
//
|
|
9
|
-
// The 0.0.10 -> current upgrade flipped the DEFAULT issue backend to the Kernel,
|
|
10
|
-
// but the legacy -> kernel migration fires ONLY from `forge setup`/`init`, never
|
|
11
|
-
// lazily on the issue path. So a user who runs `bun update` then `forge list` /
|
|
12
|
-
// `forge ready` reads an EMPTY kernel and their 0.0.10 issues APPEAR GONE — the
|
|
13
|
-
// data is safe on disk, just invisible, with no hint. This helper closes that
|
|
14
|
-
// footgun: when the resolved backend is the (default) Kernel, a read comes back
|
|
15
|
-
// empty, AND a legacy jsonl store still exists, it prints a one-time guided hint.
|
|
16
|
-
//
|
|
17
|
-
// It lives in this NEUTRAL module (not lib/commands/_issue.js) on purpose: the
|
|
18
|
-
// message text names the retired backend + its `.beads` store, and _issue.js is a
|
|
19
|
-
// D20 release-readiness hot-path surface that must stay free of those tokens (the
|
|
20
|
-
// bd-call-site audit + kernel-backed checks scan it). Keeping the strings here
|
|
21
|
-
// lets the hot path call a token-free helper.
|
|
22
|
-
//
|
|
23
|
-
// Best-effort and non-blocking: it NEVER throws and never alters the read result.
|
|
24
|
-
// Fires at most once per project root per process to avoid spam.
|
|
25
|
-
const NUDGE_READS = new Set(['list', 'ready']);
|
|
26
|
-
const warnedRoots = new Set();
|
|
27
|
-
|
|
28
|
-
// A kernel read looks empty when its contract data carries no issues. Handles the
|
|
29
|
-
// issue.list/issue.ready shape ({ issues, count }) plus a bare array / null, and
|
|
30
|
-
// is deliberately conservative: anything it cannot confirm as empty is treated as
|
|
31
|
-
// NON-empty so a user with real kernel issues is never nagged.
|
|
32
|
-
function kernelReadLooksEmpty(result) {
|
|
33
|
-
if (!result || typeof result !== 'object' || result.ok !== true) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const data = result.data;
|
|
37
|
-
if (data === null || data === undefined) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
if (Array.isArray(data)) {
|
|
41
|
-
return data.length === 0;
|
|
42
|
-
}
|
|
43
|
-
if (Array.isArray(data.issues)) {
|
|
44
|
-
return data.issues.length === 0;
|
|
45
|
-
}
|
|
46
|
-
if (Array.isArray(data.items)) {
|
|
47
|
-
return data.items.length === 0;
|
|
48
|
-
}
|
|
49
|
-
if (typeof data.count === 'number') {
|
|
50
|
-
return data.count === 0;
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function maybeWarnUnmigratedBeads(subcommand, result, projectRoot, rawOpts = {}) {
|
|
56
|
-
try {
|
|
57
|
-
if (!NUDGE_READS.has(subcommand) || !projectRoot) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (warnedRoots.has(projectRoot)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const env = rawOpts.env || process.env;
|
|
64
|
-
// Resolve the EFFECTIVE backend (default kernel). An explicit opt-in to the
|
|
65
|
-
// retired backend means the user chose it deliberately — nothing to nudge.
|
|
66
|
-
const backend = resolveIssueBackend({ deps: rawOpts, env, projectRoot, warn: () => {} });
|
|
67
|
-
if (backend !== 'kernel' || !kernelReadLooksEmpty(result)) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
if (!detectBeadsJsonlSource(projectRoot)) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
warnedRoots.add(projectRoot);
|
|
74
|
-
console.error(
|
|
75
|
-
'\n[forge] Legacy issue data detected (.beads/*.jsonl) but the Kernel issue store is empty.\n'
|
|
76
|
-
+ 'Forge now defaults to the Kernel backend (breaking change since 0.0.10). Your legacy\n'
|
|
77
|
-
+ 'issues are safe on disk but will not appear until migrated. To migrate:\n'
|
|
78
|
-
+ ' forge migrate --from beads # import your legacy issues into the Kernel\n'
|
|
79
|
-
+ ' forge setup # (re)wire hooks + provision the Kernel store\n'
|
|
80
|
-
+ 'Prefer to stay on the legacy backend? Set `issueBackend: beads` in .forge/config.yaml '
|
|
81
|
-
+ '(or FORGE_ISSUE_BACKEND=beads).\n',
|
|
82
|
-
);
|
|
83
|
-
} catch (_err) { // NOSONAR S2486 — line-scoped; must sit on the catch line
|
|
84
|
-
/* the nudge is a best-effort hint; it must never break a read */
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
module.exports = {
|
|
89
|
-
maybeWarnUnmigratedBeads,
|
|
90
|
-
kernelReadLooksEmpty,
|
|
91
|
-
};
|