forge-workflow 0.0.3 → 0.0.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/.claude/commands/dev.md +340 -314
- package/.claude/commands/plan.md +521 -478
- package/.claude/commands/premerge.md +176 -179
- package/.claude/commands/research.md +42 -42
- package/.claude/commands/review.md +442 -442
- package/.claude/commands/rollback.md +721 -721
- package/.claude/commands/ship.md +164 -134
- package/.claude/commands/sonarcloud.md +152 -152
- package/.claude/commands/status.md +48 -77
- package/.claude/commands/validate.md +282 -237
- package/.claude/commands/verify.md +221 -221
- package/.claude/rules/greptile-review-process.md +285 -285
- package/.claude/rules/workflow.md +105 -105
- package/.claude/scripts/greptile-resolve.sh +526 -526
- package/.claude/scripts/load-env.sh +32 -32
- package/.cline/workflows/dev.md +337 -311
- package/.cline/workflows/plan.md +518 -475
- package/.cline/workflows/premerge.md +173 -176
- package/.cline/workflows/research.md +39 -39
- package/.cline/workflows/review.md +439 -439
- package/.cline/workflows/rollback.md +718 -718
- package/.cline/workflows/ship.md +161 -131
- package/.cline/workflows/sonarcloud.md +146 -146
- package/.cline/workflows/status.md +45 -74
- package/.cline/workflows/validate.md +279 -234
- package/.cline/workflows/verify.md +218 -218
- package/.codex/config.toml +11 -11
- package/.codex/skills/dev/SKILL.md +340 -314
- package/.codex/skills/plan/SKILL.md +521 -478
- package/.codex/skills/premerge/SKILL.md +176 -179
- package/.codex/skills/research/SKILL.md +42 -42
- package/.codex/skills/review/SKILL.md +442 -442
- package/.codex/skills/rollback/SKILL.md +721 -721
- package/.codex/skills/ship/SKILL.md +164 -134
- package/.codex/skills/sonarcloud/SKILL.md +149 -149
- package/.codex/skills/status/SKILL.md +48 -77
- package/.codex/skills/validate/SKILL.md +282 -237
- package/.codex/skills/verify/SKILL.md +221 -221
- package/.cursor/commands/dev.md +337 -311
- package/.cursor/commands/plan.md +518 -475
- package/.cursor/commands/premerge.md +173 -176
- package/.cursor/commands/research.md +39 -39
- package/.cursor/commands/review.md +439 -439
- package/.cursor/commands/rollback.md +718 -718
- package/.cursor/commands/ship.md +161 -131
- package/.cursor/commands/sonarcloud.md +146 -146
- package/.cursor/commands/status.md +45 -74
- package/.cursor/commands/validate.md +279 -234
- package/.cursor/commands/verify.md +218 -218
- package/.cursor/rules/permissions-guidance.mdc +37 -37
- package/.forge/hooks/check-tdd.js +240 -240
- package/.github/PLUGIN_TEMPLATE.json +32 -32
- package/.github/prompts/dev.prompt.md +342 -316
- package/.github/prompts/plan.prompt.md +523 -480
- package/.github/prompts/premerge.prompt.md +178 -181
- package/.github/prompts/research.prompt.md +44 -44
- package/.github/prompts/review.prompt.md +444 -444
- package/.github/prompts/rollback.prompt.md +723 -723
- package/.github/prompts/ship.prompt.md +166 -136
- package/.github/prompts/sonarcloud.prompt.md +151 -151
- package/.github/prompts/status.prompt.md +50 -79
- package/.github/prompts/validate.prompt.md +284 -239
- package/.github/prompts/verify.prompt.md +223 -223
- package/.github/workflows/beads-to-github.yml +56 -0
- package/.github/workflows/github-to-beads.yml +97 -0
- package/.kilocode/workflows/dev.md +341 -315
- package/.kilocode/workflows/plan.md +522 -479
- package/.kilocode/workflows/premerge.md +177 -180
- package/.kilocode/workflows/research.md +43 -43
- package/.kilocode/workflows/review.md +443 -443
- package/.kilocode/workflows/rollback.md +722 -722
- package/.kilocode/workflows/ship.md +165 -135
- package/.kilocode/workflows/sonarcloud.md +150 -150
- package/.kilocode/workflows/status.md +49 -78
- package/.kilocode/workflows/validate.md +283 -238
- package/.kilocode/workflows/verify.md +222 -222
- package/.mcp.json.example +12 -12
- package/.opencode/commands/dev.md +340 -314
- package/.opencode/commands/plan.md +521 -478
- package/.opencode/commands/premerge.md +176 -179
- package/.opencode/commands/research.md +42 -42
- package/.opencode/commands/review.md +442 -442
- package/.opencode/commands/rollback.md +721 -721
- package/.opencode/commands/ship.md +164 -134
- package/.opencode/commands/sonarcloud.md +149 -149
- package/.opencode/commands/status.md +48 -77
- package/.opencode/commands/validate.md +282 -237
- package/.opencode/commands/verify.md +221 -221
- package/.roo/commands/dev.md +341 -315
- package/.roo/commands/plan.md +522 -479
- package/.roo/commands/premerge.md +177 -180
- package/.roo/commands/research.md +43 -43
- package/.roo/commands/review.md +443 -443
- package/.roo/commands/rollback.md +722 -722
- package/.roo/commands/ship.md +165 -135
- package/.roo/commands/sonarcloud.md +150 -150
- package/.roo/commands/status.md +49 -78
- package/.roo/commands/validate.md +283 -238
- package/.roo/commands/verify.md +222 -222
- package/AGENTS.md +175 -169
- package/CLAUDE.md +100 -99
- package/LICENSE +21 -21
- package/README.md +429 -414
- package/bin/forge-cmd.js +313 -313
- package/bin/{forge-validate.js → forge-preflight.js} +309 -303
- package/bin/forge.js +4596 -4232
- package/docs/AGENT_INSTALL_PROMPT.md +342 -342
- package/docs/BEADS_GITHUB_SYNC.md +251 -0
- package/docs/ENHANCED_ONBOARDING.md +602 -602
- package/docs/EXAMPLES.md +482 -482
- package/docs/GREPTILE_SETUP.md +400 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +106 -106
- package/docs/ROADMAP.md +359 -359
- package/docs/SETUP.md +663 -632
- package/docs/TOOLCHAIN.md +630 -630
- package/docs/VALIDATION.md +363 -363
- package/install.sh +40 -1058
- package/lefthook.yml +39 -39
- package/lib/agents/README.md +198 -198
- package/lib/agents/claude.plugin.json +28 -28
- package/lib/agents/cline.plugin.json +22 -22
- package/lib/agents/codex.plugin.json +19 -19
- package/lib/agents/copilot.plugin.json +24 -24
- package/lib/agents/cursor.plugin.json +25 -25
- package/lib/agents/kilocode.plugin.json +22 -22
- package/lib/agents/opencode.plugin.json +20 -20
- package/lib/agents/roo.plugin.json +23 -23
- package/lib/agents-config.js +2112 -2112
- package/lib/beads-health-check.js +143 -0
- package/lib/beads-setup.js +341 -0
- package/lib/beads-sync-scaffold.js +260 -0
- package/lib/commands/dev.js +513 -513
- package/lib/commands/plan.js +692 -692
- package/lib/commands/recommend.js +119 -119
- package/lib/commands/ship.js +377 -377
- package/lib/commands/status.js +378 -378
- package/lib/commands/validate.js +602 -602
- package/lib/context-merge.js +359 -359
- package/lib/dep-guard/analyzer.js +294 -294
- package/lib/dep-guard/behavior-detector.js +98 -98
- package/lib/dep-guard/contract-detector.js +162 -162
- package/lib/dep-guard/import-detector.js +498 -498
- package/lib/dep-guard/path-utils.js +13 -13
- package/lib/dep-guard/rubric.js +120 -120
- package/lib/dep-guard/task-parser.js +318 -318
- package/lib/detect-agent.js +191 -0
- package/lib/detect-worktree.js +47 -0
- package/lib/file-hash.js +26 -0
- package/lib/husky-migration.js +450 -0
- package/lib/lefthook-check.js +65 -0
- package/lib/pat-setup.js +207 -0
- package/lib/plugin-catalog.js +350 -350
- package/lib/plugin-manager.js +166 -166
- package/lib/plugin-recommender.js +141 -141
- package/lib/project-discovery.js +491 -491
- package/lib/setup-action-log.js +139 -0
- package/lib/setup-summary-renderer.js +106 -0
- package/lib/setup-utils.js +96 -0
- package/lib/setup.js +192 -118
- package/lib/smart-merge.js +64 -0
- package/lib/symlink-utils.js +81 -0
- package/lib/workflow-profiles.js +197 -197
- package/package.json +131 -129
- package/scripts/beads-context.sh +291 -0
- package/scripts/beads-context.test.js +563 -0
- package/scripts/behavioral-judge.sh +378 -0
- package/scripts/benchmark.js +85 -0
- package/scripts/branch-protection.js +183 -0
- package/scripts/check-agents.js +172 -0
- package/scripts/commitlint.js +42 -0
- package/scripts/conflict-detect.sh +323 -0
- package/scripts/dep-guard-analyze.js +71 -0
- package/scripts/dep-guard.sh +811 -0
- package/scripts/eval_win.py +249 -0
- package/scripts/file-index.sh +399 -0
- package/scripts/github-beads-sync/comment.mjs +64 -0
- package/scripts/github-beads-sync/config.mjs +148 -0
- package/scripts/github-beads-sync/github-api.mjs +131 -0
- package/scripts/github-beads-sync/index.mjs +332 -0
- package/scripts/github-beads-sync/label-mapper.mjs +54 -0
- package/scripts/github-beads-sync/mapping.mjs +78 -0
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +31 -0
- package/scripts/github-beads-sync/reverse-sync.mjs +138 -0
- package/scripts/github-beads-sync/run-bd.mjs +159 -0
- package/scripts/github-beads-sync/sanitize.mjs +121 -0
- package/scripts/github-beads-sync.config.json +26 -0
- package/scripts/improve-command.js +375 -0
- package/scripts/lib/eval-runner.js +229 -0
- package/scripts/lib/eval-schema.js +135 -0
- package/scripts/lib/eval-storage.js +78 -0
- package/scripts/lib/grading.js +203 -0
- package/scripts/lib/transcript-parser.js +63 -0
- package/scripts/lint.js +47 -0
- package/scripts/migrate-to-bun-test.js +412 -0
- package/scripts/run-command-eval.js +236 -0
- package/scripts/smart-status.sh +782 -0
- package/scripts/sync-commands.js +571 -0
- package/scripts/sync-utils.sh +460 -0
- package/scripts/test-dashboard.js +123 -0
- package/scripts/test.js +44 -0
- package/scripts/validate.sh +94 -0
- package/skills/parallel-deep-research/SKILL.md +108 -108
- package/skills/parallel-deep-research/evals/README.md +27 -27
- package/skills/parallel-deep-research/evals/evals.json +62 -62
- package/skills/sonarcloud-analysis/SKILL.md +171 -171
- package/skills/sonarcloud-analysis/evals/README.md +27 -27
- package/skills/sonarcloud-analysis/evals/evals.json +50 -50
- package/skills/sonarcloud-analysis/references/api-reference.md +466 -466
- package/docs/WORKFLOW.md +0 -400
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { execFileSync } = require('node:child_process');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Detect the default branch of the repository.
|
|
9
|
+
*
|
|
10
|
+
* Strategy (in order):
|
|
11
|
+
* 1. `git symbolic-ref refs/remotes/origin/HEAD` -> parse branch name
|
|
12
|
+
* 2. `git remote show origin` -> parse "HEAD branch:" line
|
|
13
|
+
* 3. Fall back to `'main'`
|
|
14
|
+
*
|
|
15
|
+
* @param {string} projectRoot - Absolute path to the project root.
|
|
16
|
+
* @param {object} [options] - Options object.
|
|
17
|
+
* @param {Function} [options._exec] - Injected execFileSync for testing.
|
|
18
|
+
* @returns {string} The default branch name.
|
|
19
|
+
*/
|
|
20
|
+
function detectDefaultBranch(projectRoot, options = {}) {
|
|
21
|
+
const exec = options._exec || execFileSync;
|
|
22
|
+
|
|
23
|
+
// Strategy 1: symbolic-ref
|
|
24
|
+
try {
|
|
25
|
+
const out = exec('git', ['symbolic-ref', 'refs/remotes/origin/HEAD'], {
|
|
26
|
+
cwd: projectRoot,
|
|
27
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
28
|
+
});
|
|
29
|
+
const ref = out.toString().trim();
|
|
30
|
+
// refs/remotes/origin/main -> main
|
|
31
|
+
const parts = ref.split('/');
|
|
32
|
+
if (parts.length > 0) {
|
|
33
|
+
return parts[parts.length - 1];
|
|
34
|
+
}
|
|
35
|
+
} catch (_e) {
|
|
36
|
+
// Expected: symbolic-ref fails when origin/HEAD is not set — fall through to strategy 2
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Strategy 2: remote show origin
|
|
40
|
+
try {
|
|
41
|
+
const out = exec('git', ['remote', 'show', 'origin'], {
|
|
42
|
+
cwd: projectRoot,
|
|
43
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
|
+
});
|
|
45
|
+
const text = out.toString();
|
|
46
|
+
const match = text.match(/HEAD branch:\s*(.+)/);
|
|
47
|
+
if (match) {
|
|
48
|
+
return match[1].trim();
|
|
49
|
+
}
|
|
50
|
+
} catch (_e) {
|
|
51
|
+
// Expected: 'git remote show origin' fails when no remote is configured — fall through to fallback
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Strategy 3: fallback
|
|
55
|
+
return 'main';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Detect the installed Beads version.
|
|
60
|
+
*
|
|
61
|
+
* Strategy (in order):
|
|
62
|
+
* 1. `bd --version` -> parse version string (e.g. "beads version 0.52.0" -> "0.52.0")
|
|
63
|
+
* 2. Fall back to known-good default `'0.49.1'`
|
|
64
|
+
*
|
|
65
|
+
* @param {object} [options] - Options object.
|
|
66
|
+
* @param {Function} [options._exec] - Injected execFileSync for testing.
|
|
67
|
+
* @returns {string} The Beads version string.
|
|
68
|
+
*/
|
|
69
|
+
function detectBeadsVersion(options = {}) {
|
|
70
|
+
const exec = options._exec || execFileSync;
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const out = exec('bd', ['--version'], {
|
|
74
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
75
|
+
});
|
|
76
|
+
const text = out.toString().trim();
|
|
77
|
+
// "beads version 0.52.0" -> "0.52.0"
|
|
78
|
+
const match = text.match(/(\d{1,4}\.\d{1,4}\.\d{1,4})/);
|
|
79
|
+
if (match) {
|
|
80
|
+
return match[1];
|
|
81
|
+
}
|
|
82
|
+
} catch (_e) {
|
|
83
|
+
// Expected: 'bd --version' fails when bd CLI is not installed — fall through to default version
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return '0.49.1';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Template workflow YAML files by replacing the default branch and Beads version.
|
|
91
|
+
*
|
|
92
|
+
* Templates only forge-created workflow files by replacing the default branch
|
|
93
|
+
* and Beads version. Skips user-owned workflows to avoid overwriting legitimate
|
|
94
|
+
* branch targets.
|
|
95
|
+
*
|
|
96
|
+
* @param {string} workflowDir - Absolute path to the directory containing YAML files.
|
|
97
|
+
* @param {string} branch - The default branch name to substitute.
|
|
98
|
+
* @param {string} beadsVersion - The Beads version to substitute.
|
|
99
|
+
* @param {string[]} [createdFiles=[]] - List of file paths created by scaffoldBeadsSync. Only these are templated.
|
|
100
|
+
*/
|
|
101
|
+
function templateWorkflows(workflowDir, branch, beadsVersion, createdFiles = []) {
|
|
102
|
+
if (!fs.existsSync(workflowDir)) return;
|
|
103
|
+
|
|
104
|
+
const targetNames = new Set(createdFiles.map(f => path.basename(f)));
|
|
105
|
+
|
|
106
|
+
const entries = fs.readdirSync(workflowDir);
|
|
107
|
+
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
// Only template forge-created files; skip user-owned workflows
|
|
110
|
+
if (targetNames.size > 0 && !targetNames.has(entry)) continue;
|
|
111
|
+
|
|
112
|
+
const ext = path.extname(entry).toLowerCase();
|
|
113
|
+
if (ext !== '.yml' && ext !== '.yaml') {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const filePath = path.join(workflowDir, entry);
|
|
118
|
+
const stat = fs.statSync(filePath);
|
|
119
|
+
if (!stat.isFile()) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const original = fs.readFileSync(filePath, 'utf8');
|
|
124
|
+
let content = original;
|
|
125
|
+
content = content.replaceAll(
|
|
126
|
+
/branches:\s*\[master\]/g,
|
|
127
|
+
`branches: [${branch}]`
|
|
128
|
+
);
|
|
129
|
+
content = content.replaceAll(
|
|
130
|
+
/BD_VERSION="0\.49\.1"/g,
|
|
131
|
+
`BD_VERSION="${beadsVersion}"`
|
|
132
|
+
);
|
|
133
|
+
// Only write if content actually changed
|
|
134
|
+
if (content !== original) {
|
|
135
|
+
fs.writeFileSync(filePath, content);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @typedef {Object} ScaffoldResult
|
|
142
|
+
* @property {string[]} filesCreated - Relative paths of files written (new or overwritten)
|
|
143
|
+
* @property {string[]} filesSkipped - Relative paths of files that already existed and were preserved
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Copy a single file from src to dest, creating parent directories as needed.
|
|
148
|
+
*
|
|
149
|
+
* @param {string} src - Absolute source path
|
|
150
|
+
* @param {string} dest - Absolute destination path
|
|
151
|
+
* @returns {void}
|
|
152
|
+
*/
|
|
153
|
+
function copyFileWithDirs(src, dest) {
|
|
154
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
155
|
+
fs.copyFileSync(src, dest);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Scaffold Beads sync workflows and scripts to the user's project.
|
|
160
|
+
*
|
|
161
|
+
* Copies workflow templates, sync modules, config, and mapping stub into
|
|
162
|
+
* the project's `.github/` tree from the forge package source.
|
|
163
|
+
*
|
|
164
|
+
* @param {string} projectRoot - Absolute path to the user's project root
|
|
165
|
+
* @param {string} packageDir - Absolute path to the forge package install location
|
|
166
|
+
* @param {Object} [_options={}] - Reserved for future options
|
|
167
|
+
* @returns {ScaffoldResult}
|
|
168
|
+
*/
|
|
169
|
+
function scaffoldBeadsSync(projectRoot, packageDir, _options = {}) {
|
|
170
|
+
/** @type {string[]} */
|
|
171
|
+
const filesCreated = [];
|
|
172
|
+
/** @type {string[]} */
|
|
173
|
+
const filesSkipped = [];
|
|
174
|
+
|
|
175
|
+
const githubDir = path.join(projectRoot, '.github');
|
|
176
|
+
|
|
177
|
+
// --- Step a: Copy workflow templates ---
|
|
178
|
+
const workflowNames = ['github-to-beads.yml', 'beads-to-github.yml'];
|
|
179
|
+
const srcWorkflowsDir = path.join(packageDir, '.github', 'workflows');
|
|
180
|
+
|
|
181
|
+
for (const name of workflowNames) {
|
|
182
|
+
const src = path.join(srcWorkflowsDir, name);
|
|
183
|
+
const relPath = `.github/workflows/${name}`;
|
|
184
|
+
const dest = path.join(projectRoot, '.github', 'workflows', name);
|
|
185
|
+
|
|
186
|
+
if (!fs.existsSync(src)) continue;
|
|
187
|
+
if (fs.existsSync(dest)) {
|
|
188
|
+
filesSkipped.push(relPath);
|
|
189
|
+
} else {
|
|
190
|
+
copyFileWithDirs(src, dest);
|
|
191
|
+
filesCreated.push(relPath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// --- Step b: Copy sync modules ---
|
|
196
|
+
const srcSyncDir = path.join(packageDir, 'scripts', 'github-beads-sync');
|
|
197
|
+
const destSyncDir = path.join(githubDir, 'scripts', 'beads-sync');
|
|
198
|
+
|
|
199
|
+
if (fs.existsSync(srcSyncDir)) {
|
|
200
|
+
const entries = fs.readdirSync(srcSyncDir);
|
|
201
|
+
for (const entry of entries) {
|
|
202
|
+
const srcFile = path.join(srcSyncDir, entry);
|
|
203
|
+
const stat = fs.statSync(srcFile);
|
|
204
|
+
if (stat.isFile()) {
|
|
205
|
+
const relPath = `.github/scripts/beads-sync/${entry}`;
|
|
206
|
+
const dest = path.join(destSyncDir, entry);
|
|
207
|
+
if (fs.existsSync(dest)) {
|
|
208
|
+
filesSkipped.push(relPath);
|
|
209
|
+
} else {
|
|
210
|
+
copyFileWithDirs(srcFile, dest);
|
|
211
|
+
filesCreated.push(relPath);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// --- Step c: Create beads-sync-config.json ---
|
|
218
|
+
const configRelPath = '.github/beads-sync-config.json';
|
|
219
|
+
const configDest = path.join(githubDir, 'beads-sync-config.json');
|
|
220
|
+
const srcConfig = path.join(packageDir, 'scripts', 'github-beads-sync.config.json');
|
|
221
|
+
|
|
222
|
+
if (fs.existsSync(configDest)) {
|
|
223
|
+
filesSkipped.push(configRelPath);
|
|
224
|
+
} else if (fs.existsSync(srcConfig)) {
|
|
225
|
+
copyFileWithDirs(srcConfig, configDest);
|
|
226
|
+
filesCreated.push(configRelPath);
|
|
227
|
+
} else {
|
|
228
|
+
// Create a sensible default config
|
|
229
|
+
const defaultConfig = {
|
|
230
|
+
defaultType: 'task',
|
|
231
|
+
defaultPriority: 2,
|
|
232
|
+
mapAssignee: true,
|
|
233
|
+
publicRepoGate: 'none'
|
|
234
|
+
};
|
|
235
|
+
fs.mkdirSync(path.dirname(configDest), { recursive: true });
|
|
236
|
+
fs.writeFileSync(configDest, JSON.stringify(defaultConfig, null, 2) + '\n');
|
|
237
|
+
filesCreated.push(configRelPath);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// --- Step d: Create beads-mapping.json if not exists ---
|
|
241
|
+
const mappingRelPath = '.github/beads-mapping.json';
|
|
242
|
+
const mappingDest = path.join(githubDir, 'beads-mapping.json');
|
|
243
|
+
|
|
244
|
+
if (fs.existsSync(mappingDest)) {
|
|
245
|
+
filesSkipped.push(mappingRelPath);
|
|
246
|
+
} else {
|
|
247
|
+
fs.mkdirSync(path.dirname(mappingDest), { recursive: true });
|
|
248
|
+
fs.writeFileSync(mappingDest, '{}');
|
|
249
|
+
filesCreated.push(mappingRelPath);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return { filesCreated, filesSkipped };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = {
|
|
256
|
+
detectDefaultBranch,
|
|
257
|
+
detectBeadsVersion,
|
|
258
|
+
templateWorkflows,
|
|
259
|
+
scaffoldBeadsSync,
|
|
260
|
+
};
|