forge-workflow 0.1.0-beta.4 → 0.1.0-beta.6
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 +18 -7
- package/CHANGELOG.md +79 -1
- package/CLAUDE.md +0 -12
- package/CODING_STANDARDS.md +72 -0
- package/README.md +6 -2
- package/bin/forge-cmd.js +20 -0
- package/bin/forge.js +28 -375
- 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 +8 -5
- package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +4 -0
- package/docs/reference/INSIGHTS_RECAP.md +9 -20
- package/docs/reference/INSTALL.md +4 -0
- package/docs/reference/LEGACY_CLAIM_REPAIR.md +112 -0
- package/docs/reference/RELEASE.md +5 -3
- package/docs/reference/TOOLCHAIN.md +8 -0
- package/docs/reference/github-accounts.md +134 -0
- package/docs/reference/protected-state-surfaces.md +4 -4
- package/docs/reference/shepherd.md +114 -35
- package/lefthook.yml +12 -0
- package/lib/activation/ensure-forge-home.js +33 -15
- package/lib/adapters/pr-state-adapter.js +359 -144
- package/lib/audit-evidence.js +71 -110
- package/lib/base-remote.js +138 -0
- package/lib/beta5-compatibility-evidence.js +1093 -0
- package/lib/bun-lockfile-proof.js +413 -0
- package/lib/bun-workflow-pins.js +461 -0
- package/lib/capabilities/index.js +9 -0
- package/lib/capabilities/model.js +141 -0
- package/lib/capabilities/probes.js +347 -0
- package/lib/capped-jsonl-log.js +236 -0
- package/lib/codex-skills.js +2 -2
- package/lib/commands/_manifest.js +1 -0
- package/lib/commands/_registry.js +50 -20
- package/lib/commands/clean.js +252 -32
- package/lib/commands/dev.js +4 -33
- package/lib/commands/doctor.js +37 -6
- package/lib/commands/gate.js +197 -27
- package/lib/commands/github.js +215 -0
- package/lib/commands/hooks.js +276 -30
- package/lib/commands/insights.js +8 -3
- package/lib/commands/memory.js +66 -2
- package/lib/commands/merge.js +1265 -58
- package/lib/commands/plan.js +33 -2
- package/lib/commands/pr.js +3 -1
- package/lib/commands/preflight.js +21 -4
- package/lib/commands/prime.js +21 -8
- package/lib/commands/push.js +146 -54
- package/lib/commands/recall.js +127 -49
- package/lib/commands/recap.js +6 -1
- package/lib/commands/release.js +39 -3
- package/lib/commands/remember.js +28 -4
- package/lib/commands/serve.js +26 -9
- package/lib/commands/setup.js +323 -98
- package/lib/commands/shepherd.js +591 -73
- package/lib/commands/ship.js +36 -91
- package/lib/commands/skill.js +127 -11
- package/lib/commands/status.js +17 -1
- package/lib/commands/team.js +47 -8
- package/lib/commands/test.js +187 -38
- package/lib/commands/validate.js +65 -21
- package/lib/commands/worktree.js +359 -45
- package/lib/core/runtime-graph.js +1 -1
- package/lib/doc-assertions.js +297 -0
- package/lib/existing-tdd-gate.js +253 -0
- package/lib/fixtures/beta5-corpus/v1/README.md +9 -0
- package/lib/fixtures/beta5-corpus/v1/contract/command-contract.json +26 -0
- package/lib/fixtures/beta5-corpus/v1/contract/package-contract.json +13 -0
- package/lib/fixtures/beta5-corpus/v1/contract/workflow-stage-matrix.json +8 -0
- package/lib/fixtures/beta5-corpus/v1/manifest.json +25 -0
- package/lib/fixtures/beta5-corpus/v1/state/comments.jsonl +1 -0
- package/lib/fixtures/beta5-corpus/v1/state/config.yaml +6 -0
- package/lib/fixtures/beta5-corpus/v1/state/dependencies.jsonl +1 -0
- package/lib/fixtures/beta5-corpus/v1/state/issues.jsonl +2 -0
- package/lib/fixtures/beta5-corpus/v1/state/kernel.sql +20 -0
- package/lib/forge-context.js +1 -4
- package/lib/forge-issues.js +134 -32
- package/lib/gate-events.js +98 -10
- package/lib/git-defaults.js +56 -0
- package/lib/github-context.js +308 -0
- package/lib/global-flags.js +1 -0
- package/lib/harness-capability-matrix.js +3 -3
- package/lib/hook-renderer.js +122 -5
- package/lib/insights.js +96 -80
- package/lib/issue-render.js +19 -0
- package/lib/kernel/backing-issue.js +14 -2
- package/lib/kernel/broker.js +739 -31
- package/lib/kernel/claim-reconciler.js +238 -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/lease-enforcer.js +9 -4
- package/lib/kernel/legacy-claim-repair.js +442 -0
- package/lib/kernel/live-claim-projection.js +26 -0
- package/lib/kernel/migrations.js +118 -3
- package/lib/kernel/readiness-model.js +184 -12
- package/lib/kernel/schema.js +49 -1
- package/lib/kernel/sqlite-driver.js +3435 -172
- package/lib/kernel/taxonomy-validator.js +4 -1
- package/lib/kernel/windows-private-acl.js +239 -0
- package/lib/lefthook-wiring.js +21 -1
- package/lib/memory/hygiene.js +191 -0
- package/lib/memory/router.js +110 -28
- package/lib/memory/usage-evidence.js +4 -0
- package/lib/memory-digest.js +106 -15
- package/lib/memory-recall-events.js +145 -0
- package/lib/memory-recall.js +71 -10
- package/lib/merge-rules.js +143 -21
- package/lib/npm-publish-workflow.js +465 -0
- package/lib/orientation.js +68 -43
- package/lib/package-root.js +2 -0
- package/lib/plugin-catalog.js +14 -4
- package/lib/pr-bundle.js +5 -6
- package/lib/pr-monitor/auto-actions.js +169 -28
- package/lib/pr-monitor/differ.js +110 -4
- package/lib/pr-monitor/events.js +0 -0
- package/lib/pr-monitor/flow-monitor.js +1424 -0
- package/lib/pr-monitor/gather.js +251 -44
- package/lib/pr-monitor/journal.js +18 -39
- package/lib/pr-monitor/monitor.js +117 -10
- package/lib/pr-monitor/process-identity.js +117 -0
- package/lib/pr-monitor/reconcile-executor.js +1129 -470
- package/lib/pr-monitor/reconcile.js +0 -0
- package/lib/pr-monitor/render-summary.js +293 -0
- package/lib/pr-monitor/review-preflight.js +269 -0
- package/lib/pr-monitor/shepherd-lease.js +38 -20
- package/lib/pr-monitor/verdict.js +438 -0
- package/lib/pr-monitor/watch-lifecycle.js +145 -27
- package/lib/pr-monitor/watch-owner.js +1414 -0
- package/lib/pr-monitor/watch.js +129 -58
- package/lib/pr-pull.js +33 -14
- package/lib/pr-shepherd.js +51 -11
- package/lib/preflight/gates.js +65 -18
- package/lib/preflight/runner.js +5 -0
- package/lib/project-memory.js +178 -4
- package/lib/protected-state-authority.js +1100 -0
- package/lib/protected-state-surfaces.js +243 -45
- package/lib/release-readiness.js +53 -7
- package/lib/review-adapter.js +65 -0
- package/lib/shell-utils.js +1 -1
- package/lib/skills-sync.js +71 -35
- package/lib/smart-merge.js +28 -4
- package/lib/symlink-utils.js +74 -26
- package/lib/upgrade-safety.js +39 -0
- package/lib/using-forge.js +19 -6
- package/lib/validation/risk-manifest.js +339 -0
- package/lib/workflow/enforce-stage.js +44 -0
- package/lib/workflow/plan-authority.js +225 -0
- package/package.json +12 -9
- package/scripts/commitlint.js +13 -15
- package/scripts/doc-asserting-tests.js +158 -0
- package/scripts/generate-risk-manifest.js +91 -0
- package/scripts/github-context-bridge.sh +10 -0
- package/scripts/legacy-claim-repair.js +145 -0
- package/scripts/lib/behavioral-eval-runner.js +310 -0
- package/scripts/lib/behavioral-eval-runtime.js +457 -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 +773 -0
- package/scripts/protected-state-check.js +479 -31
- package/scripts/run-command-eval.js +29 -1
- package/scripts/sync-agent-skills.js +333 -34
- package/scripts/sync-d20-audit.js +172 -0
- package/scripts/test-full-suite.js +935 -37
- package/scripts/test-profile.js +13 -3
- package/scripts/test.js +271 -57
- package/skills/coverage.json +1 -0
- package/skills/review/SKILL.md +6 -11
- package/skills/review/evals/scorecard.json +4 -4
- package/skills/rollback/SKILL.md +4 -11
- package/skills/rollback/evals/scorecard.json +3 -3
- package/skills/setup/SKILL.md +18 -0
- package/skills/setup/evals/scorecard.json +3 -3
- package/skills/shepherd/SKILL.md +39 -16
- package/skills/shepherd/evals/scorecard.json +4 -4
- package/skills/ship/SKILL.md +4 -12
- package/skills/ship/evals/scorecard.json +3 -3
- package/skills/validate/SKILL.md +3 -0
- package/skills/validate/evals/scorecard.json +1 -1
- package/skills/worktree/SKILL.md +6 -1
- package/skills/worktree/evals/scorecard.json +2 -2
- package/lib/beads-setup.js +0 -538
- package/lib/beads-sync-scaffold.js +0 -189
- package/lib/pat-setup.js +0 -207
- package/lib/pr-monitor/render-sticky.js +0 -206
- package/lib/pr-monitor/upsert-sticky.js +0 -169
- 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/lib/beads-migrate-to-dolt.mjs +0 -503
package/bin/forge.js
CHANGED
|
@@ -80,10 +80,8 @@ const { firstPositionalIndex } = require('../lib/global-flags');
|
|
|
80
80
|
const contextMerge = require('../lib/context-merge');
|
|
81
81
|
const projectDiscovery = require('../lib/project-discovery');
|
|
82
82
|
|
|
83
|
-
// Load lib modules for symlink
|
|
83
|
+
// Load lib modules for symlink setup
|
|
84
84
|
const { createSymlinkOrCopy: libCreateSymlinkOrCopy } = require('../lib/symlink-utils');
|
|
85
|
-
const beadsSetupLib = require('../lib/beads-setup');
|
|
86
|
-
const { scaffoldBeadsSync } = require('../lib/beads-sync-scaffold');
|
|
87
85
|
|
|
88
86
|
// Load incremental setup modules
|
|
89
87
|
const { detectEnvironment } = require('../lib/detect-agent');
|
|
@@ -113,7 +111,6 @@ let FORCE_MODE = false;
|
|
|
113
111
|
let VERBOSE_MODE = false;
|
|
114
112
|
let NON_INTERACTIVE = false;
|
|
115
113
|
let SYMLINK_ONLY = false; // --symlink: fail instead of copy fallback
|
|
116
|
-
let SYNC_ENABLED = false; // --sync: scaffold Beads GitHub sync workflows
|
|
117
114
|
let actionLog = new SetupActionLog();
|
|
118
115
|
|
|
119
116
|
// Detected package manager
|
|
@@ -429,7 +426,7 @@ Use these default-template commands via \`/command-name\`:
|
|
|
429
426
|
- \`/validate\` - Type check, lint, security, tests (HARD-GATE)
|
|
430
427
|
- \`/ship\` - Push and create PR with design doc reference
|
|
431
428
|
- \`/review\` - Handle ALL PR issues (Actions, Greptile, SonarCloud)
|
|
432
|
-
- \`/verify\` - Post-merge health check (CI on main, close
|
|
429
|
+
- \`/verify\` - Post-merge health check (CI on main, close kernel issues)
|
|
433
430
|
|
|
434
431
|
Pre-merge gate (not a numbered stage): finish docs + confirm CI green + hand off the PR — embedded in the /ship and /review stages.
|
|
435
432
|
|
|
@@ -706,9 +703,7 @@ async function detectProjectStatus() {
|
|
|
706
703
|
agentsMdLines: 0,
|
|
707
704
|
claudeMdLines: 0,
|
|
708
705
|
// Project tools status
|
|
709
|
-
hasBeads: isBeadsInitialized(),
|
|
710
706
|
hasSkills: isSkillsInitialized(),
|
|
711
|
-
beadsInstallType: checkForBeads(),
|
|
712
707
|
skillsInstallType: checkForSkills(),
|
|
713
708
|
// Enhanced: Auto-detected project context
|
|
714
709
|
autoDetected: null
|
|
@@ -1701,6 +1696,13 @@ function ensureDirWithNote(dir, purpose) {
|
|
|
1701
1696
|
|
|
1702
1697
|
// Setup core documentation and directories
|
|
1703
1698
|
function setupCoreDocs() {
|
|
1699
|
+
// Review skills reference this root contract in every installed repository.
|
|
1700
|
+
// It is a consumer-owned extension point after creation, so setup never overwrites it.
|
|
1701
|
+
const codingStandardsDest = path.join(projectRoot, 'CODING_STANDARDS.md');
|
|
1702
|
+
if (!fs.existsSync(codingStandardsDest)) {
|
|
1703
|
+
copyFile(path.join(packageDir, 'CODING_STANDARDS.md'), 'CODING_STANDARDS.md');
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1704
1706
|
// docs/planning/ and docs/research/ are created lazily on first use
|
|
1705
1707
|
// by /plan Phase 1 and Phase 2 respectively, via ensureDirWithNote().
|
|
1706
1708
|
// TEMPLATE.md and PROGRESS.md are also deferred to first use.
|
|
@@ -2196,15 +2198,6 @@ function displaySetupSummary(selectedAgents) {
|
|
|
2196
2198
|
console.log('Project Tools Status:');
|
|
2197
2199
|
console.log('');
|
|
2198
2200
|
|
|
2199
|
-
// Beads status
|
|
2200
|
-
if (isBeadsInitialized()) {
|
|
2201
|
-
console.log(' ✓ Beads initialized - Track work: forge ready');
|
|
2202
|
-
} else if (checkForBeads()) {
|
|
2203
|
-
console.log(' ! Beads available - Run: bd init');
|
|
2204
|
-
} else {
|
|
2205
|
-
console.log(` - Beads not installed - Run: ${PKG_MANAGER} install -g @beads/bd && bd init`);
|
|
2206
|
-
}
|
|
2207
|
-
|
|
2208
2201
|
// Skills status
|
|
2209
2202
|
if (isSkillsInitialized()) {
|
|
2210
2203
|
console.log(' ✓ Skills initialized - Manage skills: skills list');
|
|
@@ -2351,7 +2344,7 @@ function parseFlags() {
|
|
|
2351
2344
|
verbose: false, // Show file-by-file detail in setup summary
|
|
2352
2345
|
dryRun: false, // Preview planned actions without writing files
|
|
2353
2346
|
symlink: false, // Create CLAUDE.md as symlink to AGENTS.md (--symlink)
|
|
2354
|
-
|
|
2347
|
+
skillsOnly: false, // Install skills without Git or harness hook enforcement
|
|
2355
2348
|
};
|
|
2356
2349
|
|
|
2357
2350
|
// Issue passthrough commands delegate all flags to bd.
|
|
@@ -2368,6 +2361,9 @@ function parseFlags() {
|
|
|
2368
2361
|
for (let i = 0; i < args.length;) {
|
|
2369
2362
|
const arg = args[i];
|
|
2370
2363
|
|
|
2364
|
+
// Everything after the explicit launcher delimiter belongs to the child.
|
|
2365
|
+
if (arg === '--' && args[0] === 'github' && args[firstPositionalIndex(args, 1)] === 'run') break;
|
|
2366
|
+
|
|
2371
2367
|
if (arg === '--quick' || arg === '-q') {
|
|
2372
2368
|
flags.quick = true;
|
|
2373
2369
|
i++;
|
|
@@ -2417,8 +2413,8 @@ function parseFlags() {
|
|
|
2417
2413
|
} else if (arg === '--symlink') {
|
|
2418
2414
|
flags.symlink = true;
|
|
2419
2415
|
i++;
|
|
2420
|
-
} else if (arg === '--
|
|
2421
|
-
flags.
|
|
2416
|
+
} else if (arg === '--skills-only' || arg === '--no-hooks') {
|
|
2417
|
+
flags.skillsOnly = true;
|
|
2422
2418
|
i++;
|
|
2423
2419
|
} else if (arg === '--interview') {
|
|
2424
2420
|
flags.interview = true;
|
|
@@ -2577,6 +2573,8 @@ function showHelp() {
|
|
|
2577
2573
|
console.log(' --type <type> Set workflow profile type manually');
|
|
2578
2574
|
console.log(' Options: critical, standard, simple, hotfix, docs, refactor');
|
|
2579
2575
|
console.log(' --dry-run Preview planned actions without writing any files');
|
|
2576
|
+
console.log(' --skills-only Install skills without Git hooks, Forge-native, or harness hooks');
|
|
2577
|
+
console.log(' Alias: --no-hooks');
|
|
2580
2578
|
console.log(' --interview Force context interview (gather project information)');
|
|
2581
2579
|
console.log(' --budget <mode> Budget mode for recommend (free, open-source, startup, professional, custom)');
|
|
2582
2580
|
console.log(' --yes, -y Non-interactive setup with sensible defaults');
|
|
@@ -2602,6 +2600,7 @@ function showHelp() {
|
|
|
2602
2600
|
console.log(' npx forge setup --yes # Non-interactive, defaults to claude');
|
|
2603
2601
|
console.log(' npx forge setup --yes --agents cursor # Non-interactive, specific agent');
|
|
2604
2602
|
console.log(' npx forge setup --all --skip-external # All agents, no services');
|
|
2603
|
+
console.log(' npx forge setup --agents claude --skills-only # Skills without hook enforcement');
|
|
2605
2604
|
console.log(' npx forge setup --merge=smart # Use intelligent merge for existing files');
|
|
2606
2605
|
console.log(' npx forge setup --type=critical # Set workflow profile manually');
|
|
2607
2606
|
console.log(' npx forge setup --interview # Force context interview');
|
|
@@ -2835,121 +2834,6 @@ function checkForLefthook() {
|
|
|
2835
2834
|
return status;
|
|
2836
2835
|
}
|
|
2837
2836
|
|
|
2838
|
-
// Check if Beads is installed (global, local, or bunx-capable)
|
|
2839
|
-
function checkForBeads() {
|
|
2840
|
-
// Try global install first
|
|
2841
|
-
try {
|
|
2842
|
-
secureExecFileSync('bd', ['version'], { stdio: 'ignore' });
|
|
2843
|
-
return 'global';
|
|
2844
|
-
} catch (err) {
|
|
2845
|
-
// Not global
|
|
2846
|
-
console.warn('Beads not found globally:', err.message);
|
|
2847
|
-
}
|
|
2848
|
-
|
|
2849
|
-
// Check if bunx can run it
|
|
2850
|
-
try {
|
|
2851
|
-
secureExecFileSync('bunx', ['@beads/bd', 'version'], { stdio: 'ignore' });
|
|
2852
|
-
return 'bunx';
|
|
2853
|
-
} catch (err) {
|
|
2854
|
-
// Not bunx-capable
|
|
2855
|
-
console.warn('Beads not available via bunx:', err.message);
|
|
2856
|
-
}
|
|
2857
|
-
|
|
2858
|
-
// Check local project installation
|
|
2859
|
-
const pkgPath = path.join(projectRoot, 'package.json');
|
|
2860
|
-
if (!fs.existsSync(pkgPath)) return null;
|
|
2861
|
-
|
|
2862
|
-
try {
|
|
2863
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
2864
|
-
const isInstalled = pkg.devDependencies?.['@beads/bd'] || pkg.dependencies?.['@beads/bd'];
|
|
2865
|
-
return isInstalled ? 'local' : null;
|
|
2866
|
-
} catch (err) {
|
|
2867
|
-
console.warn('Failed to check Beads in package.json:', err.message);
|
|
2868
|
-
return null;
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
// Check if Beads is initialized in project — delegates to lib/beads-setup
|
|
2872
|
-
function isBeadsInitialized() {
|
|
2873
|
-
return beadsSetupLib.isBeadsInitialized(projectRoot);
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
|
-
function migrateExistingBeadsLocalState() {
|
|
2877
|
-
if (!fs.existsSync(path.join(projectRoot, '.beads'))) {
|
|
2878
|
-
return;
|
|
2879
|
-
}
|
|
2880
|
-
|
|
2881
|
-
try {
|
|
2882
|
-
beadsSetupLib.ensureBeadsGitExclude(projectRoot);
|
|
2883
|
-
} catch (err) {
|
|
2884
|
-
console.warn(` Warning: failed to migrate Beads local state: ${err.message}`);
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
|
|
2888
|
-
// Initialize Beads in the project using the defensive safeBeadsInit wrapper
|
|
2889
|
-
// Handles config/gitignore writes, hook snapshot/restore, and JSONL pre-seeding
|
|
2890
|
-
function initializeBeads(installType) {
|
|
2891
|
-
console.log('Initializing Beads in project...');
|
|
2892
|
-
|
|
2893
|
-
// Build the execBdInit function based on installType
|
|
2894
|
-
const execBdInit = (root) => {
|
|
2895
|
-
// SECURITY: execFileSync with hardcoded commands
|
|
2896
|
-
if (installType === 'global') {
|
|
2897
|
-
secureExecFileSync('bd', ['init'], { stdio: 'inherit', cwd: root });
|
|
2898
|
-
} else if (installType === 'bunx') {
|
|
2899
|
-
secureExecFileSync('bunx', ['@beads/bd', 'init'], { stdio: 'inherit', cwd: root });
|
|
2900
|
-
} else if (installType === 'local') {
|
|
2901
|
-
secureExecFileSync('npx', ['bd', 'init'], { stdio: 'inherit', cwd: root });
|
|
2902
|
-
}
|
|
2903
|
-
};
|
|
2904
|
-
|
|
2905
|
-
// Derive prefix from package.json name or directory name
|
|
2906
|
-
let prefix;
|
|
2907
|
-
try {
|
|
2908
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
|
|
2909
|
-
prefix = pkg.name || path.basename(projectRoot);
|
|
2910
|
-
} catch (_e) {
|
|
2911
|
-
prefix = path.basename(projectRoot);
|
|
2912
|
-
}
|
|
2913
|
-
|
|
2914
|
-
try {
|
|
2915
|
-
const result = beadsSetupLib.safeBeadsInit(projectRoot, {
|
|
2916
|
-
prefix,
|
|
2917
|
-
execBdInit,
|
|
2918
|
-
restoreLefthook: (root) => {
|
|
2919
|
-
try {
|
|
2920
|
-
secureExecFileSync('lefthook', ['install'], { stdio: 'ignore', cwd: root });
|
|
2921
|
-
} catch (_e) {
|
|
2922
|
-
// lefthook may not be installed yet — non-fatal
|
|
2923
|
-
}
|
|
2924
|
-
}
|
|
2925
|
-
});
|
|
2926
|
-
|
|
2927
|
-
if (result.skipped) {
|
|
2928
|
-
console.log(' ✓ Beads already initialized');
|
|
2929
|
-
return true;
|
|
2930
|
-
}
|
|
2931
|
-
|
|
2932
|
-
if (!result.success) {
|
|
2933
|
-
for (const e of result.errors) {
|
|
2934
|
-
console.log(` ⚠ ${e}`);
|
|
2935
|
-
}
|
|
2936
|
-
console.log(' Run manually: bd init');
|
|
2937
|
-
return false;
|
|
2938
|
-
}
|
|
2939
|
-
|
|
2940
|
-
for (const w of result.warnings) {
|
|
2941
|
-
console.warn(` ⚠ ${w}`);
|
|
2942
|
-
}
|
|
2943
|
-
console.log(' ✓ Beads initialized');
|
|
2944
|
-
|
|
2945
|
-
return true;
|
|
2946
|
-
} catch (err) {
|
|
2947
|
-
console.log(' ⚠ Failed to initialize Beads:', err.message);
|
|
2948
|
-
console.log(' Run manually: bd init');
|
|
2949
|
-
return false;
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
|
|
2953
2837
|
// Check if Skills CLI is installed
|
|
2954
2838
|
function checkForSkills() {
|
|
2955
2839
|
// Try global install first
|
|
@@ -3006,60 +2890,6 @@ function initializeSkills(installType) {
|
|
|
3006
2890
|
}
|
|
3007
2891
|
}
|
|
3008
2892
|
|
|
3009
|
-
// Prompt for Beads setup - extracted to reduce cognitive complexity
|
|
3010
|
-
async function promptBeadsSetup(question) {
|
|
3011
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
3012
|
-
console.log('Beads Setup (Recommended)');
|
|
3013
|
-
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
3014
|
-
console.log('');
|
|
3015
|
-
|
|
3016
|
-
const beadsInitialized = isBeadsInitialized();
|
|
3017
|
-
const beadsStatus = checkForBeads();
|
|
3018
|
-
|
|
3019
|
-
if (beadsInitialized) {
|
|
3020
|
-
migrateExistingBeadsLocalState();
|
|
3021
|
-
console.log('✓ Beads is already initialized in this project');
|
|
3022
|
-
console.log('');
|
|
3023
|
-
return;
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
|
-
if (beadsStatus) {
|
|
3027
|
-
// Already installed, just need to initialize
|
|
3028
|
-
console.log(`ℹ Beads is installed (${beadsStatus}), but not initialized`);
|
|
3029
|
-
const initBeads = await question('Initialize Beads in this project? (y/n): ');
|
|
3030
|
-
|
|
3031
|
-
if (initBeads.toLowerCase() === 'y') {
|
|
3032
|
-
initializeBeads(beadsStatus);
|
|
3033
|
-
} else {
|
|
3034
|
-
console.log('Skipped Beads initialization. Run manually: bd init');
|
|
3035
|
-
}
|
|
3036
|
-
console.log('');
|
|
3037
|
-
return;
|
|
3038
|
-
}
|
|
3039
|
-
|
|
3040
|
-
// Not installed
|
|
3041
|
-
console.log('ℹ Beads is not installed');
|
|
3042
|
-
const installBeads = await question('Install Beads? (y/n): ');
|
|
3043
|
-
|
|
3044
|
-
if (installBeads.toLowerCase() !== 'y') {
|
|
3045
|
-
console.log('Skipped Beads installation');
|
|
3046
|
-
console.log('');
|
|
3047
|
-
return;
|
|
3048
|
-
}
|
|
3049
|
-
|
|
3050
|
-
console.log('');
|
|
3051
|
-
console.log('Choose installation method:');
|
|
3052
|
-
console.log(' 1. Global (recommended) - Available system-wide');
|
|
3053
|
-
console.log(' 2. Local - Project-specific devDependency');
|
|
3054
|
-
console.log(' 3. Bunx - Use via bunx (requires bun)');
|
|
3055
|
-
console.log('');
|
|
3056
|
-
const method = await question('Choose method (1-3): ');
|
|
3057
|
-
|
|
3058
|
-
console.log('');
|
|
3059
|
-
installBeadsWithMethod(method);
|
|
3060
|
-
console.log('');
|
|
3061
|
-
}
|
|
3062
|
-
|
|
3063
2893
|
// Helper: Install tool via bunx - extracted to reduce cognitive complexity
|
|
3064
2894
|
function installViaBunx(packageName, versionArgs, initFn, toolName) {
|
|
3065
2895
|
console.log('Testing bunx capability...');
|
|
@@ -3073,68 +2903,6 @@ function installViaBunx(packageName, versionArgs, initFn, toolName) {
|
|
|
3073
2903
|
}
|
|
3074
2904
|
}
|
|
3075
2905
|
|
|
3076
|
-
// Helper: Install Beads with chosen method - extracted to reduce cognitive complexity
|
|
3077
|
-
// SECURITY NOTE: Downloads and executes a remote PowerShell script.
|
|
3078
|
-
// The npm @beads/bd package is broken on Windows (GitHub Issue #1031, closed "not planned"),
|
|
3079
|
-
// so the official PowerShell installer is the only supported path.
|
|
3080
|
-
// Mitigations: HTTPS transport (prevents MITM), official beads repo, user-visible URL.
|
|
3081
|
-
// TODO: Pin to a versioned release tag once beads publishes tagged releases (e.g. v0.49.1).
|
|
3082
|
-
const BEADS_INSTALL_PS1_URL = 'https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1';
|
|
3083
|
-
|
|
3084
|
-
function installBeadsOnWindows() {
|
|
3085
|
-
console.log(' (Windows detected: using PowerShell installer)');
|
|
3086
|
-
console.log(` Downloading: ${BEADS_INSTALL_PS1_URL}`);
|
|
3087
|
-
secureExecFileSync('powershell.exe', [
|
|
3088
|
-
'-NoProfile', '-NonInteractive', '-Command',
|
|
3089
|
-
`irm ${BEADS_INSTALL_PS1_URL} | iex`
|
|
3090
|
-
], { stdio: 'inherit' });
|
|
3091
|
-
}
|
|
3092
|
-
|
|
3093
|
-
function installBeadsWithMethod(method) {
|
|
3094
|
-
try {
|
|
3095
|
-
// SECURITY: secureExecFileSync with hardcoded commands
|
|
3096
|
-
if (method === '1') {
|
|
3097
|
-
console.log('Installing Beads globally...');
|
|
3098
|
-
if (process.platform === 'win32') {
|
|
3099
|
-
installBeadsOnWindows();
|
|
3100
|
-
} else {
|
|
3101
|
-
const pkgManager = PKG_MANAGER === 'bun' ? 'bun' : 'npm';
|
|
3102
|
-
secureExecFileSync(pkgManager, ['install', '-g', '@beads/bd'], { stdio: 'inherit' });
|
|
3103
|
-
}
|
|
3104
|
-
console.log(' ✓ Beads installed globally');
|
|
3105
|
-
initializeBeads('global');
|
|
3106
|
-
} else if (method === '2') {
|
|
3107
|
-
console.log('Installing Beads locally...');
|
|
3108
|
-
// On Windows, npm postinstall for @beads/bd runs Expand-Archive which has EPERM file-locking
|
|
3109
|
-
// (GitHub Issue #1031, closed "not planned") — same root cause as global install.
|
|
3110
|
-
// Redirect Windows users to the global PowerShell installer instead.
|
|
3111
|
-
if (process.platform === 'win32') {
|
|
3112
|
-
console.log(' ⚠ Local install not supported on Windows (npm @beads/bd EPERM issue).');
|
|
3113
|
-
console.log(' Falling back to global PowerShell installer...');
|
|
3114
|
-
installBeadsOnWindows();
|
|
3115
|
-
} else {
|
|
3116
|
-
const pkgManager = PKG_MANAGER === 'bun' ? 'bun' : 'npm';
|
|
3117
|
-
secureExecFileSync(pkgManager, ['install', '-D', '@beads/bd'], { stdio: 'inherit', cwd: projectRoot });
|
|
3118
|
-
}
|
|
3119
|
-
console.log(' ✓ Beads installed');
|
|
3120
|
-
// On Windows the fallback was global (PowerShell installer), so init as 'global'
|
|
3121
|
-
initializeBeads(process.platform === 'win32' ? 'global' : 'local');
|
|
3122
|
-
} else if (method === '3') {
|
|
3123
|
-
installViaBunx('@beads/bd', ['version'], initializeBeads, 'Beads');
|
|
3124
|
-
} else {
|
|
3125
|
-
console.log('Invalid choice. Skipping Beads installation.');
|
|
3126
|
-
}
|
|
3127
|
-
} catch (err) {
|
|
3128
|
-
console.warn('Beads installation failed:', err.message);
|
|
3129
|
-
console.log(' ⚠ Failed to install Beads:', err.message);
|
|
3130
|
-
if (process.platform === 'win32') {
|
|
3131
|
-
console.log(` Run manually: irm ${BEADS_INSTALL_PS1_URL} | iex`);
|
|
3132
|
-
} else {
|
|
3133
|
-
console.log(` Run manually: ${PKG_MANAGER === 'bun' ? 'bun add -g' : 'npm install -g'} @beads/bd && bd init`);
|
|
3134
|
-
}
|
|
3135
|
-
}
|
|
3136
|
-
}
|
|
3137
|
-
|
|
3138
2906
|
// Helper: Get package-manager-specific install args for Skills
|
|
3139
2907
|
function getSkillsInstallArgs(scope) {
|
|
3140
2908
|
const globalFlag = scope === 'global' ? '-g' : '-D';
|
|
@@ -3223,68 +2991,23 @@ async function promptSkillsSetup(question) {
|
|
|
3223
2991
|
console.log('');
|
|
3224
2992
|
}
|
|
3225
2993
|
|
|
3226
|
-
// Interactive setup for
|
|
3227
|
-
async function setupProjectTools(
|
|
2994
|
+
// Interactive setup for Skills
|
|
2995
|
+
async function setupProjectTools(_rl, question) {
|
|
3228
2996
|
console.log('');
|
|
3229
2997
|
console.log('═══════════════════════════════════════════════════════════');
|
|
3230
2998
|
console.log(' STEP 2: Project Tools (Recommended)');
|
|
3231
2999
|
console.log('═══════════════════════════════════════════════════════════');
|
|
3232
3000
|
console.log('');
|
|
3233
|
-
console.log('Forge recommends
|
|
3234
|
-
console.log('');
|
|
3235
|
-
console.log('• Beads - Git-backed issue tracking');
|
|
3236
|
-
console.log(' Persists tasks across sessions, tracks dependencies.');
|
|
3237
|
-
console.log(' Command: forge ready, forge create, forge close');
|
|
3001
|
+
console.log('Forge recommends the following tool for enhanced workflows:');
|
|
3238
3002
|
console.log('');
|
|
3239
3003
|
console.log('• Skills - Universal SKILL.md management');
|
|
3240
3004
|
console.log(' Manage AI agent skills across all agents.');
|
|
3241
3005
|
console.log(' Command: skills create, skills list, skills sync');
|
|
3242
3006
|
console.log('');
|
|
3243
3007
|
|
|
3244
|
-
// Use helper functions to reduce complexity
|
|
3245
|
-
await promptBeadsSetup(question);
|
|
3246
3008
|
await promptSkillsSetup(question);
|
|
3247
3009
|
}
|
|
3248
3010
|
|
|
3249
|
-
// Auto-setup Beads in quick mode - extracted to reduce cognitive complexity
|
|
3250
|
-
function autoSetupBeadsInQuickMode() {
|
|
3251
|
-
const beadsStatus = checkForBeads();
|
|
3252
|
-
const beadsInitialized = isBeadsInitialized();
|
|
3253
|
-
|
|
3254
|
-
if (beadsInitialized) {
|
|
3255
|
-
migrateExistingBeadsLocalState();
|
|
3256
|
-
}
|
|
3257
|
-
|
|
3258
|
-
if (!beadsInitialized && beadsStatus) {
|
|
3259
|
-
console.log('📦 Initializing Beads...');
|
|
3260
|
-
initializeBeads(beadsStatus);
|
|
3261
|
-
console.log('');
|
|
3262
|
-
} else if (!beadsInitialized && !beadsStatus) {
|
|
3263
|
-
console.log('📦 Installing Beads globally...');
|
|
3264
|
-
try {
|
|
3265
|
-
// SECURITY: use PowerShell on Windows (npm @beads/bd is broken on Windows - Issue #1031)
|
|
3266
|
-
if (process.platform === 'win32') {
|
|
3267
|
-
installBeadsOnWindows();
|
|
3268
|
-
} else {
|
|
3269
|
-
const pkgManager = PKG_MANAGER === 'bun' ? 'bun' : 'npm';
|
|
3270
|
-
secureExecFileSync(pkgManager, ['install', '-g', '@beads/bd'], { stdio: 'inherit' });
|
|
3271
|
-
}
|
|
3272
|
-
console.log(' ✓ Beads installed globally');
|
|
3273
|
-
initializeBeads('global');
|
|
3274
|
-
} catch (err) {
|
|
3275
|
-
// Installation failed - provide manual instructions
|
|
3276
|
-
console.log(' ⚠ Could not install Beads automatically');
|
|
3277
|
-
console.log(` Error: ${err.message}`);
|
|
3278
|
-
if (process.platform === 'win32') {
|
|
3279
|
-
console.log(` Run manually: irm ${BEADS_INSTALL_PS1_URL} | iex`);
|
|
3280
|
-
} else {
|
|
3281
|
-
console.log(` Run manually: ${PKG_MANAGER === 'bun' ? 'bun add -g' : 'npm install -g'} @beads/bd && bd init`);
|
|
3282
|
-
}
|
|
3283
|
-
}
|
|
3284
|
-
console.log('');
|
|
3285
|
-
}
|
|
3286
|
-
}
|
|
3287
|
-
|
|
3288
3011
|
// Helper: Auto-install lefthook if not present - extracted to reduce cognitive complexity
|
|
3289
3012
|
function autoInstallLefthook() {
|
|
3290
3013
|
const status = checkForLefthook();
|
|
@@ -3340,26 +3063,9 @@ function autoInstallLefthook() {
|
|
|
3340
3063
|
}
|
|
3341
3064
|
|
|
3342
3065
|
// Helper: Verify a tool is callable after install - extracted to reduce cognitive complexity
|
|
3343
|
-
function verifyToolInstall(command, args, toolName) {
|
|
3344
|
-
try {
|
|
3345
|
-
secureExecFileSync(command, args, { stdio: 'ignore' });
|
|
3346
|
-
return true;
|
|
3347
|
-
} catch (_err) { // NOSONAR - S2486: Intentionally ignored; verification failure is handled by caller
|
|
3348
|
-
console.log(` ⚠ ${toolName} installed but not callable. Check your PATH.`);
|
|
3349
|
-
return false;
|
|
3350
|
-
}
|
|
3351
|
-
}
|
|
3352
3066
|
|
|
3353
3067
|
// Helper: Auto-setup tools (Skills) in quick mode - extracted to reduce cognitive complexity
|
|
3354
3068
|
function autoSetupToolsInQuickMode() {
|
|
3355
|
-
// Beads: auto-install or initialize
|
|
3356
|
-
autoSetupBeadsInQuickMode();
|
|
3357
|
-
|
|
3358
|
-
// Post-install verification for Beads
|
|
3359
|
-
if (isBeadsInitialized()) {
|
|
3360
|
-
verifyToolInstall('bd', ['version'], 'Beads');
|
|
3361
|
-
}
|
|
3362
|
-
|
|
3363
3069
|
// Skills: only initialize if already installed (recommended tool)
|
|
3364
3070
|
const skillsStatus = checkForSkills();
|
|
3365
3071
|
if (skillsStatus && !isSkillsInitialized()) {
|
|
@@ -3421,7 +3127,7 @@ async function quickSetup(selectedAgents, skipExternal) {
|
|
|
3421
3127
|
// Auto-install lefthook if missing
|
|
3422
3128
|
autoInstallLefthook();
|
|
3423
3129
|
|
|
3424
|
-
// Auto-setup project tools (
|
|
3130
|
+
// Auto-setup project tools (Skills)
|
|
3425
3131
|
autoSetupToolsInQuickMode();
|
|
3426
3132
|
|
|
3427
3133
|
// Setup Claude first if selected, then remaining agents
|
|
@@ -3440,11 +3146,6 @@ async function quickSetup(selectedAgents, skipExternal) {
|
|
|
3440
3146
|
// Configure external services with defaults (unless skipped)
|
|
3441
3147
|
configureDefaultExternalServices(skipExternal);
|
|
3442
3148
|
|
|
3443
|
-
// --sync flag: scaffold Beads GitHub sync workflows without prompting
|
|
3444
|
-
if (SYNC_ENABLED) {
|
|
3445
|
-
await handleSyncScaffold();
|
|
3446
|
-
}
|
|
3447
|
-
|
|
3448
3149
|
// Progressive setup summary
|
|
3449
3150
|
console.log('');
|
|
3450
3151
|
console.log(renderSetupSummary(actionLog, selectedAgents, VERBOSE_MODE));
|
|
@@ -3789,8 +3490,9 @@ function dryRunSetup(agents) {
|
|
|
3789
3490
|
}
|
|
3790
3491
|
}
|
|
3791
3492
|
|
|
3792
|
-
//
|
|
3493
|
+
// Root policy files
|
|
3793
3494
|
addFileAction('AGENTS.md', 'Copy workflow documentation');
|
|
3495
|
+
addFileAction('CODING_STANDARDS.md', 'Install Forge coding standards');
|
|
3794
3496
|
|
|
3795
3497
|
// Per-agent planned actions
|
|
3796
3498
|
for (const agentKey of agents) {
|
|
@@ -3862,8 +3564,6 @@ async function executeSetup(config) {
|
|
|
3862
3564
|
checkPrerequisites();
|
|
3863
3565
|
console.log('');
|
|
3864
3566
|
|
|
3865
|
-
migrateExistingBeadsLocalState();
|
|
3866
|
-
|
|
3867
3567
|
// Copy AGENTS.md (only if not exists — preserve user customizations; actionLog tracks it)
|
|
3868
3568
|
const agentsDest = path.join(projectRoot, 'AGENTS.md');
|
|
3869
3569
|
if (fs.existsSync(agentsDest)) {
|
|
@@ -3894,32 +3594,12 @@ async function executeSetup(config) {
|
|
|
3894
3594
|
// External services (unless skipped)
|
|
3895
3595
|
await handleExternalServices(skipExternal, agents);
|
|
3896
3596
|
|
|
3897
|
-
// --sync flag: scaffold Beads GitHub sync workflows without prompting
|
|
3898
|
-
if (SYNC_ENABLED) {
|
|
3899
|
-
await handleSyncScaffold();
|
|
3900
|
-
}
|
|
3901
|
-
|
|
3902
3597
|
// Progressive setup summary
|
|
3903
3598
|
console.log('');
|
|
3904
3599
|
console.log(renderSetupSummary(actionLog, agents, VERBOSE_MODE));
|
|
3905
3600
|
console.log('');
|
|
3906
3601
|
}
|
|
3907
3602
|
|
|
3908
|
-
// Helper: Scaffold Beads GitHub sync when --sync flag is provided
|
|
3909
|
-
async function handleSyncScaffold() {
|
|
3910
|
-
console.log('');
|
|
3911
|
-
console.log('Beads GitHub sync scaffolding is deprecated (--sync).');
|
|
3912
|
-
try {
|
|
3913
|
-
const result = scaffoldBeadsSync(projectRoot, packageDir);
|
|
3914
|
-
console.log(` ${result.message}`);
|
|
3915
|
-
for (const f of result.filesRemoved || []) {
|
|
3916
|
-
console.log(` Removed deprecated sync file: ${f}`);
|
|
3917
|
-
}
|
|
3918
|
-
} catch (err) {
|
|
3919
|
-
console.error(` Error scaffolding GitHub-Beads sync: ${err.message}`);
|
|
3920
|
-
}
|
|
3921
|
-
}
|
|
3922
|
-
|
|
3923
3603
|
// Helper: Handle setup command in non-quick mode
|
|
3924
3604
|
async function handleSetupCommand(selectedAgents, flags) {
|
|
3925
3605
|
// Allow callers (e.g. reinstall) to override projectRoot without process.chdir()
|
|
@@ -3938,7 +3618,6 @@ async function handleSetupCommand(selectedAgents, flags) {
|
|
|
3938
3618
|
}
|
|
3939
3619
|
|
|
3940
3620
|
async function runInteractiveSetupFallback(flags, interactiveSetup = interactiveSetupWithFlags) {
|
|
3941
|
-
migrateExistingBeadsLocalState();
|
|
3942
3621
|
return interactiveSetup(flags);
|
|
3943
3622
|
}
|
|
3944
3623
|
|
|
@@ -3989,7 +3668,6 @@ async function main() {
|
|
|
3989
3668
|
VERBOSE_MODE = flags.verbose;
|
|
3990
3669
|
NON_INTERACTIVE = flags.nonInteractive || flags.yes || isNonInteractive();
|
|
3991
3670
|
SYMLINK_ONLY = flags.symlink;
|
|
3992
|
-
SYNC_ENABLED = flags.sync;
|
|
3993
3671
|
actionLog = new SetupActionLog();
|
|
3994
3672
|
|
|
3995
3673
|
// The non-interactive agent-selection notice is DEBUG-ONLY (kernel issue
|
|
@@ -4159,11 +3837,10 @@ async function main() {
|
|
|
4159
3837
|
console.error(`Error running '${command}':`, err.message);
|
|
4160
3838
|
process.exit(1);
|
|
4161
3839
|
}
|
|
4162
|
-
// NOTE:
|
|
4163
|
-
//
|
|
4164
|
-
//
|
|
4165
|
-
//
|
|
4166
|
-
// its own firing-policy + containment design. Start the daemon via `forge shepherd daemon`.
|
|
3840
|
+
// NOTE: an autonomous-shepherd every-command dispatch-finally trigger is intentionally
|
|
3841
|
+
// NOT wired here. Automatic firing is deliberately limited to the approved seams:
|
|
3842
|
+
// supported session start, successful push, and successful non-dry-run ship. Ordinary
|
|
3843
|
+
// commands cannot spawn a session-outliving daemon or break test isolation.
|
|
4167
3844
|
return;
|
|
4168
3845
|
}
|
|
4169
3846
|
|
|
@@ -4216,12 +3893,6 @@ async function main() {
|
|
|
4216
3893
|
return;
|
|
4217
3894
|
}
|
|
4218
3895
|
|
|
4219
|
-
if (flags.sync && selectedAgents.length === 0) {
|
|
4220
|
-
migrateExistingBeadsLocalState();
|
|
4221
|
-
await handleSyncScaffold();
|
|
4222
|
-
return;
|
|
4223
|
-
}
|
|
4224
|
-
|
|
4225
3896
|
// Agents specified via flag or --yes default (non-quick mode)
|
|
4226
3897
|
if (selectedAgents.length > 0) {
|
|
4227
3898
|
await handleSetupCommand(selectedAgents, flags);
|
|
@@ -4621,20 +4292,6 @@ function checkGitWorkingDirectory() {
|
|
|
4621
4292
|
}
|
|
4622
4293
|
}
|
|
4623
4294
|
|
|
4624
|
-
// Helper: Update Beads issue after PR rollback
|
|
4625
|
-
function updateBeadsIssue(commitMessage) {
|
|
4626
|
-
const issueMatch = commitMessage.match(/#(\d+)/);
|
|
4627
|
-
if (!issueMatch) return;
|
|
4628
|
-
|
|
4629
|
-
try {
|
|
4630
|
-
const { execFileSync } = require('node:child_process');
|
|
4631
|
-
execFileSync('bd', ['update', issueMatch[1], '--status', 'reverted', '--comment', 'PR reverted'], { stdio: 'inherit' });
|
|
4632
|
-
console.log(` Updated Beads issue #${issueMatch[1]} to 'reverted'`);
|
|
4633
|
-
} catch {
|
|
4634
|
-
// Beads not installed - silently continue
|
|
4635
|
-
}
|
|
4636
|
-
}
|
|
4637
|
-
|
|
4638
4295
|
// Helper: Handle commit rollback
|
|
4639
4296
|
function handleCommitRollback(target, dryRun, execSync) {
|
|
4640
4297
|
if (dryRun) {
|
|
@@ -4656,10 +4313,6 @@ function handlePrRollback(target, dryRun, execSync) {
|
|
|
4656
4313
|
files.trim().split('\n').forEach(f => console.log(` - ${f}`));
|
|
4657
4314
|
} else {
|
|
4658
4315
|
execSync(`git revert -m 1 --no-edit ${target}`, { stdio: 'inherit' });
|
|
4659
|
-
|
|
4660
|
-
// Update Beads issue if linked
|
|
4661
|
-
const commitMsg = execSync(`git log -1 --format=%B ${target}`, { encoding: 'utf-8' });
|
|
4662
|
-
updateBeadsIssue(commitMsg);
|
|
4663
4316
|
}
|
|
4664
4317
|
}
|
|
4665
4318
|
|
package/docs/INDEX.md
CHANGED
|
@@ -49,7 +49,7 @@ This is the canonical map for Forge documentation. DeepWiki and other generated
|
|
|
49
49
|
- [Protected path manifest](reference/PROTECTED_PATH_MANIFEST.md) - protected path manifest schema, harness enforcement mapping, and evidence command.
|
|
50
50
|
- [Patch format](reference/patch-md-format.md) - `.forge/patch.md` conventions.
|
|
51
51
|
- [Upgrade safety](reference/upgrade-safety.md) - trust policy and rollback limits.
|
|
52
|
-
- [Insights and recap](reference/INSIGHTS_RECAP.md) - `forge insights` and `forge recap
|
|
52
|
+
- [Insights and recap](reference/INSIGHTS_RECAP.md) - `forge insights` and `forge recap <issue>` evidence sources, output, and limitations.
|
|
53
53
|
- [Examples](reference/EXAMPLES.md) - worked examples.
|
|
54
54
|
- [Test environment](reference/test-environment.md) - test harness notes.
|
|
55
55
|
- [Agent permissions](reference/agent-permissions.md) - agent permission model.
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
# Beads/GitHub Sync
|
|
1
|
+
# Beads/GitHub Sync (Retired)
|
|
2
2
|
|
|
3
|
-
Beads/GitHub workflow sync
|
|
4
|
-
|
|
5
|
-
## Current Behavior
|
|
6
|
-
|
|
7
|
-
- `.beads/` is local runtime/export state and is not committed.
|
|
8
|
-
- `forge setup --sync` is retained only as a compatibility cleanup path and removes old generated Beads/GitHub sync files from existing installs when they are present.
|
|
9
|
-
- Plain `forge setup` does not perform Beads/GitHub sync cleanup as a side effect.
|
|
10
|
-
- `forge sync` may still run local Beads/Dolt sync operations while Beads compatibility remains, but it is not GitHub issue lifecycle sync.
|
|
11
|
-
|
|
12
|
-
## Removed Generated Files
|
|
13
|
-
|
|
14
|
-
The `forge setup --sync` compatibility cleanup removes the old generated files:
|
|
15
|
-
|
|
16
|
-
```text
|
|
17
|
-
.github/workflows/github-to-beads.yml
|
|
18
|
-
.github/workflows/beads-to-github.yml
|
|
19
|
-
.github/beads-mapping.json
|
|
20
|
-
.github/beads-sync-config.json
|
|
21
|
-
.github/scripts/beads-sync/*.mjs
|
|
22
|
-
scripts/github-beads-sync.config.json
|
|
23
|
-
scripts/github-beads-sync/*.mjs
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Unrelated GitHub workflows are preserved.
|
|
27
|
-
|
|
28
|
-
## Replacement Direction
|
|
29
|
-
|
|
30
|
-
Future GitHub issue sync must use Forge Kernel/server authority. Local-only work is durable in local Kernel SQLite. Team or cross-machine issue state is serialized through server authority, then GitHub issues can be updated as a projection from that authority.
|
|
31
|
-
|
|
32
|
-
Do not commit live `.beads/` files, create metadata-only PRs, or bypass protected branches to update issue tracker state.
|
|
3
|
+
**Historical.** Beads/GitHub workflow sync was retired with **D45** — Beads is no longer a live Forge feature, so there is nothing left to keep in sync. Forge ships no `github-to-beads.yml` or `beads-to-github.yml` templates and never scaffolds new sync files. Bringing an existing Beads store into Forge is a one-time import, `forge migrate --from beads`; after that the Forge Kernel is the sole issue-state authority, and GitHub issue updates are a server-side projection from that authority (see [docs/work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md](../work/2026-04-28-skeleton-pivot/forge-kernel-authority-control-plane.md)). Installs that still carry old generated sync files are cleaned automatically: the `forge setup` compatibility cleanup removes the old generated files, with no flag required.
|