forge-workflow 0.0.4 → 0.0.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/.claude/commands/dev.md +345 -340
- package/.claude/commands/plan.md +566 -521
- package/.claude/commands/premerge.md +186 -176
- package/.claude/commands/research.md +42 -42
- package/.claude/commands/review.md +448 -442
- package/.claude/commands/rollback.md +721 -721
- package/.claude/commands/ship.md +212 -164
- package/.claude/commands/sonarcloud.md +152 -152
- package/.claude/commands/status.md +90 -48
- package/.claude/commands/validate.md +288 -282
- package/.claude/commands/verify.md +269 -221
- package/.claude/rules/greptile-review-process.md +285 -285
- package/.claude/rules/workflow.md +121 -105
- package/.claude/scripts/greptile-resolve.sh +558 -526
- package/.claude/scripts/load-env.sh +32 -32
- package/.cline/workflows/dev.md +342 -337
- package/.cline/workflows/plan.md +563 -518
- package/.cline/workflows/premerge.md +183 -173
- package/.cline/workflows/research.md +39 -39
- package/.cline/workflows/review.md +445 -439
- package/.cline/workflows/rollback.md +718 -718
- package/.cline/workflows/ship.md +209 -161
- package/.cline/workflows/sonarcloud.md +146 -146
- package/.cline/workflows/status.md +87 -45
- package/.cline/workflows/validate.md +285 -279
- package/.cline/workflows/verify.md +266 -218
- package/.codex/config.toml +11 -11
- package/.codex/skills/dev/SKILL.md +345 -340
- package/.codex/skills/plan/SKILL.md +566 -521
- package/.codex/skills/premerge/SKILL.md +186 -176
- package/.codex/skills/research/SKILL.md +42 -42
- package/.codex/skills/review/SKILL.md +448 -442
- package/.codex/skills/rollback/SKILL.md +721 -721
- package/.codex/skills/ship/SKILL.md +212 -164
- package/.codex/skills/sonarcloud/SKILL.md +149 -149
- package/.codex/skills/status/SKILL.md +90 -48
- package/.codex/skills/validate/SKILL.md +288 -282
- package/.codex/skills/verify/SKILL.md +269 -221
- package/.cursor/commands/dev.md +342 -337
- package/.cursor/commands/plan.md +563 -518
- package/.cursor/commands/premerge.md +183 -173
- package/.cursor/commands/research.md +39 -39
- package/.cursor/commands/review.md +445 -439
- package/.cursor/commands/rollback.md +718 -718
- package/.cursor/commands/ship.md +209 -161
- package/.cursor/commands/sonarcloud.md +146 -146
- package/.cursor/commands/status.md +87 -45
- package/.cursor/commands/validate.md +285 -279
- package/.cursor/commands/verify.md +266 -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 +347 -342
- package/.github/prompts/plan.prompt.md +568 -523
- package/.github/prompts/premerge.prompt.md +188 -178
- package/.github/prompts/research.prompt.md +44 -44
- package/.github/prompts/review.prompt.md +450 -444
- package/.github/prompts/rollback.prompt.md +723 -723
- package/.github/prompts/ship.prompt.md +214 -166
- package/.github/prompts/sonarcloud.prompt.md +151 -151
- package/.github/prompts/status.prompt.md +92 -50
- package/.github/prompts/validate.prompt.md +290 -284
- package/.github/prompts/verify.prompt.md +271 -223
- package/.github/workflows/beads-to-github.yml +56 -0
- package/.github/workflows/github-to-beads.yml +97 -0
- package/.kilocode/workflows/dev.md +346 -341
- package/.kilocode/workflows/plan.md +567 -522
- package/.kilocode/workflows/premerge.md +187 -177
- package/.kilocode/workflows/research.md +43 -43
- package/.kilocode/workflows/review.md +449 -443
- package/.kilocode/workflows/rollback.md +722 -722
- package/.kilocode/workflows/ship.md +213 -165
- package/.kilocode/workflows/sonarcloud.md +150 -150
- package/.kilocode/workflows/status.md +91 -49
- package/.kilocode/workflows/validate.md +289 -283
- package/.kilocode/workflows/verify.md +270 -222
- package/.mcp.json.example +12 -12
- package/.opencode/commands/dev.md +345 -340
- package/.opencode/commands/plan.md +566 -521
- package/.opencode/commands/premerge.md +186 -176
- package/.opencode/commands/research.md +42 -42
- package/.opencode/commands/review.md +448 -442
- package/.opencode/commands/rollback.md +721 -721
- package/.opencode/commands/ship.md +212 -164
- package/.opencode/commands/sonarcloud.md +149 -149
- package/.opencode/commands/status.md +90 -48
- package/.opencode/commands/validate.md +288 -282
- package/.opencode/commands/verify.md +269 -221
- package/.roo/commands/dev.md +346 -341
- package/.roo/commands/plan.md +567 -522
- package/.roo/commands/premerge.md +187 -177
- package/.roo/commands/research.md +43 -43
- package/.roo/commands/review.md +449 -443
- package/.roo/commands/rollback.md +722 -722
- package/.roo/commands/ship.md +213 -165
- package/.roo/commands/sonarcloud.md +150 -150
- package/.roo/commands/status.md +91 -49
- package/.roo/commands/validate.md +289 -283
- package/.roo/commands/verify.md +270 -222
- package/AGENTS.md +272 -175
- package/CLAUDE.md +110 -100
- package/README.md +429 -416
- package/bin/forge-cmd.js +317 -313
- package/bin/forge-preflight.js +322 -309
- package/bin/forge.js +4765 -4303
- package/docs/AGENT_INSTALL_PROMPT.md +342 -342
- package/docs/BEADS_GITHUB_SYNC.md +251 -251
- package/docs/ENHANCED_ONBOARDING.md +612 -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 -631
- package/docs/TOOLCHAIN.md +653 -630
- package/docs/VALIDATION.md +363 -363
- package/install.sh +40 -1056
- package/lefthook.yml +50 -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/_registry.js +134 -0
- package/lib/commands/clean.js +181 -0
- package/lib/commands/dev.js +571 -513
- package/lib/commands/plan.js +692 -692
- package/lib/commands/push.js +196 -0
- package/lib/commands/recommend.js +119 -119
- package/lib/commands/ship.js +377 -377
- package/lib/commands/status.js +378 -378
- package/lib/commands/sync.js +55 -0
- package/lib/commands/team.js +37 -0
- package/lib/commands/test.js +207 -0
- package/lib/commands/validate.js +602 -602
- package/lib/commands/worktree.js +310 -0
- 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 -191
- package/lib/detect-worktree.js +47 -47
- package/lib/docs-command.js +51 -0
- package/lib/docs-copy.js +50 -0
- package/lib/file-hash.js +26 -26
- package/lib/freshness-token.js +148 -0
- package/lib/greptile-match.js +80 -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/reset.js +309 -0
- package/lib/setup-action-log.js +139 -139
- package/lib/setup-summary-renderer.js +106 -106
- package/lib/setup-utils.js +96 -0
- package/lib/setup.js +192 -192
- package/lib/smart-merge.js +64 -0
- package/lib/symlink-utils.js +81 -0
- package/lib/task-ownership.js +117 -0
- package/lib/workflow-profiles.js +197 -197
- package/package.json +131 -128
- package/scripts/beads-context.sh +426 -0
- package/scripts/beads-context.test.js +567 -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/check-forge-token.js +98 -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 +789 -0
- package/scripts/eval_win.py +249 -0
- package/scripts/file-index.sh +493 -0
- package/scripts/forge-team/index.sh +86 -0
- package/scripts/forge-team/lib/agent-prompt.sh +52 -0
- package/scripts/forge-team/lib/claim.sh +256 -0
- package/scripts/forge-team/lib/dashboard.sh +341 -0
- package/scripts/forge-team/lib/epic.sh +332 -0
- package/scripts/forge-team/lib/hooks.sh +253 -0
- package/scripts/forge-team/lib/identity.sh +235 -0
- package/scripts/forge-team/lib/sync-github.sh +317 -0
- package/scripts/forge-team/lib/verify.sh +284 -0
- package/scripts/forge-team/lib/workload.sh +296 -0
- package/scripts/forge-team/tests/agent-prompt.test.sh +72 -0
- package/scripts/forge-team/tests/claim.test.sh +179 -0
- package/scripts/forge-team/tests/dashboard.test.sh +170 -0
- package/scripts/forge-team/tests/dispatcher.test.sh +79 -0
- package/scripts/forge-team/tests/epic.test.sh +176 -0
- package/scripts/forge-team/tests/hooks.test.sh +239 -0
- package/scripts/forge-team/tests/identity.test.sh +176 -0
- package/scripts/forge-team/tests/integration.test.sh +371 -0
- package/scripts/forge-team/tests/sync-github.test.sh +209 -0
- package/scripts/forge-team/tests/verify.test.sh +314 -0
- package/scripts/forge-team/tests/workflow-integration.test.sh +43 -0
- package/scripts/forge-team/tests/workload.test.sh +209 -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 +268 -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/jsonl-lock.sh +48 -0
- package/scripts/lib/sanitize.sh +116 -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/pr-coordinator.sh +706 -0
- package/scripts/run-command-eval.js +236 -0
- package/scripts/smart-status.sh +809 -0
- package/scripts/sync-commands.js +571 -0
- package/scripts/sync-utils.sh +455 -0
- package/scripts/test-dashboard.js +123 -0
- package/scripts/test.js +46 -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/.cursor/hooks/state/continual-learning-index.json +0 -19
- package/.cursor/hooks/state/continual-learning.json +0 -8
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lefthook prerequisite check — verifies both package.json entry and binary existence.
|
|
3
|
+
* @module lib/lefthook-check
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Check whether lefthook is declared in package.json AND whether the binary
|
|
11
|
+
* is actually available in node_modules/.bin.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} projectRoot - Absolute path to the project root directory.
|
|
14
|
+
* @returns {{ installed: boolean, binaryAvailable: boolean, message: string }}
|
|
15
|
+
* - installed: true if lefthook appears in dependencies or devDependencies
|
|
16
|
+
* - binaryAvailable: true if the lefthook binary exists in node_modules/.bin
|
|
17
|
+
* - message: actionable guidance when something is missing, empty string when OK
|
|
18
|
+
*/
|
|
19
|
+
function checkLefthookStatus(projectRoot) {
|
|
20
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
21
|
+
|
|
22
|
+
// No package.json — nothing to report
|
|
23
|
+
if (!fs.existsSync(pkgPath)) {
|
|
24
|
+
return { installed: false, binaryAvailable: false, message: '' };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let pkg;
|
|
28
|
+
try {
|
|
29
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
30
|
+
} catch (_err) {
|
|
31
|
+
// Expected: package.json may contain invalid JSON — treat as absent
|
|
32
|
+
return { installed: false, binaryAvailable: false, message: '' };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const installed = Boolean(
|
|
36
|
+
pkg.devDependencies?.lefthook || pkg.dependencies?.lefthook
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (!installed) {
|
|
40
|
+
return {
|
|
41
|
+
installed: false,
|
|
42
|
+
binaryAvailable: false,
|
|
43
|
+
message: 'lefthook not found. Run: bun add -D lefthook && bun install',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Check for the binary in node_modules/.bin
|
|
48
|
+
const binDir = path.join(projectRoot, 'node_modules', '.bin');
|
|
49
|
+
const binaryAvailable =
|
|
50
|
+
fs.existsSync(path.join(binDir, 'lefthook')) ||
|
|
51
|
+
fs.existsSync(path.join(binDir, 'lefthook.cmd'));
|
|
52
|
+
|
|
53
|
+
if (!binaryAvailable) {
|
|
54
|
+
return {
|
|
55
|
+
installed: true,
|
|
56
|
+
binaryAvailable: false,
|
|
57
|
+
message:
|
|
58
|
+
'lefthook is in package.json but not installed. Run: bun install',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { installed: true, binaryAvailable: true, message: '' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { checkLefthookStatus };
|
package/lib/pat-setup.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guided PAT (Personal Access Token) setup for Beads GitHub sync.
|
|
3
|
+
*
|
|
4
|
+
* Walks the user through creating a fine-grained PAT and saving it
|
|
5
|
+
* as a repository secret via the `gh` CLI. Token values are never
|
|
6
|
+
* printed to stdout — they are piped to `gh secret set` via stdin.
|
|
7
|
+
*
|
|
8
|
+
* @module pat-setup
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const { execFileSync: defaultExecFileSync } = require('node:child_process');
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// checkGhAuth
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check whether the user is authenticated to GitHub via `gh auth status`.
|
|
19
|
+
*
|
|
20
|
+
* @param {object} [options={}]
|
|
21
|
+
* @param {Function} [options._exec] - DI override for execFileSync
|
|
22
|
+
* @returns {{ authenticated: boolean, user: string|null }}
|
|
23
|
+
*/
|
|
24
|
+
function checkGhAuth(options = {}) {
|
|
25
|
+
const exec = options._exec || defaultExecFileSync;
|
|
26
|
+
try {
|
|
27
|
+
const output = exec('gh', ['auth', 'status'], { encoding: 'utf8' });
|
|
28
|
+
const str = typeof output === 'string' ? output : output.toString('utf8');
|
|
29
|
+
const match = str.match(/account\s+(\S+)/);
|
|
30
|
+
return {
|
|
31
|
+
authenticated: true,
|
|
32
|
+
user: match ? match[1] : null
|
|
33
|
+
};
|
|
34
|
+
} catch (_err) {
|
|
35
|
+
// Expected: 'gh auth status' fails when user is not authenticated — report as unauthenticated
|
|
36
|
+
return { authenticated: false, user: null };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// validateToken
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Validate that a string looks like a GitHub PAT.
|
|
46
|
+
*
|
|
47
|
+
* Accepts tokens starting with `ghp_` or `github_pat_` followed by at
|
|
48
|
+
* least one additional character.
|
|
49
|
+
*
|
|
50
|
+
* @param {string|undefined} token
|
|
51
|
+
* @returns {{ valid: boolean, reason?: string }}
|
|
52
|
+
*/
|
|
53
|
+
function validateToken(token) {
|
|
54
|
+
if (!token || typeof token !== 'string' || token.trim() === '') {
|
|
55
|
+
return { valid: false, reason: 'Token is empty or not provided.' };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const trimmed = token.trim();
|
|
59
|
+
|
|
60
|
+
// Must start with a known prefix AND have content after the prefix
|
|
61
|
+
const ghpValid = trimmed.startsWith('ghp_') && trimmed.length > 'ghp_'.length;
|
|
62
|
+
const patValid = trimmed.startsWith('github_pat_') && trimmed.length > 'github_pat_'.length;
|
|
63
|
+
|
|
64
|
+
if (!ghpValid && !patValid) {
|
|
65
|
+
return {
|
|
66
|
+
valid: false,
|
|
67
|
+
reason: 'Token must start with "ghp_" or "github_pat_" followed by additional characters.'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { valid: true };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// saveSecret
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Save a token as a GitHub repository secret via `gh secret set`.
|
|
80
|
+
*
|
|
81
|
+
* The token is piped to stdin (via the `input` option of execFileSync)
|
|
82
|
+
* so that it never appears in process arguments or stdout.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} secretName - Name of the repository secret
|
|
85
|
+
* @param {string} token - The PAT value (piped via stdin, never logged)
|
|
86
|
+
* @param {object} [options={}]
|
|
87
|
+
* @param {Function} [options._exec] - DI override for execFileSync
|
|
88
|
+
* @returns {{ success: boolean, error: string|null }}
|
|
89
|
+
*/
|
|
90
|
+
function saveSecret(secretName, token, options = {}) {
|
|
91
|
+
const exec = options._exec || defaultExecFileSync;
|
|
92
|
+
try {
|
|
93
|
+
exec('gh', ['secret', 'set', secretName], {
|
|
94
|
+
input: token,
|
|
95
|
+
encoding: 'utf8'
|
|
96
|
+
});
|
|
97
|
+
return { success: true, error: null };
|
|
98
|
+
} catch (err) {
|
|
99
|
+
let msg;
|
|
100
|
+
if (err.stderr) {
|
|
101
|
+
msg = typeof err.stderr === 'string' ? err.stderr : err.stderr.toString('utf8');
|
|
102
|
+
} else {
|
|
103
|
+
msg = err.message;
|
|
104
|
+
}
|
|
105
|
+
return { success: false, error: msg };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// setupPAT
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Orchestrate the full PAT setup flow.
|
|
115
|
+
*
|
|
116
|
+
* In non-interactive mode the step is skipped entirely. When `gh` is not
|
|
117
|
+
* authenticated the user receives manual instructions. Otherwise the
|
|
118
|
+
* function prompts for a token, validates it, and saves it as the
|
|
119
|
+
* `BEADS_SYNC_TOKEN` repository secret.
|
|
120
|
+
*
|
|
121
|
+
* @param {string} _projectRoot - Absolute path to the project root
|
|
122
|
+
* @param {object} [options={}]
|
|
123
|
+
* @param {boolean} [options.interactive=true] - Whether prompts are allowed
|
|
124
|
+
* @param {Function} [options._exec] - DI override for execFileSync
|
|
125
|
+
* @param {Function} [options._prompt] - DI override for user input prompt
|
|
126
|
+
* @returns {{ success: boolean, method: string, error?: string, reminder?: string, instructions?: string }}
|
|
127
|
+
*/
|
|
128
|
+
function setupPAT(_projectRoot, options = {}) {
|
|
129
|
+
const { interactive = true, _prompt } = options;
|
|
130
|
+
|
|
131
|
+
// Non-interactive: skip entirely
|
|
132
|
+
if (!interactive) {
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
method: 'skipped',
|
|
136
|
+
reminder: 'Run "forge setup" interactively to configure the Beads sync PAT, or manually set the BEADS_SYNC_TOKEN repository secret.'
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check gh authentication
|
|
141
|
+
const auth = checkGhAuth(options);
|
|
142
|
+
|
|
143
|
+
if (!auth.authenticated) {
|
|
144
|
+
const instructions = [
|
|
145
|
+
'GitHub CLI is not authenticated. To set up the Beads sync token manually:',
|
|
146
|
+
'1. Go to https://github.com/settings/tokens?type=beta',
|
|
147
|
+
'2. Create a fine-grained PAT with "repo" scope',
|
|
148
|
+
'3. Run: gh secret set BEADS_SYNC_TOKEN',
|
|
149
|
+
' (or add it via your repo Settings > Secrets > Actions)'
|
|
150
|
+
].join('\n');
|
|
151
|
+
console.log(` ${instructions.replaceAll('\n', '\n ')}`);
|
|
152
|
+
return {
|
|
153
|
+
success: false,
|
|
154
|
+
method: 'manual',
|
|
155
|
+
instructions
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Prompt for token
|
|
160
|
+
if (!_prompt) {
|
|
161
|
+
console.log(' No prompt function provided — skipping PAT setup.');
|
|
162
|
+
console.log(' Run "gh secret set BEADS_SYNC_TOKEN" manually to configure.');
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
method: 'manual',
|
|
166
|
+
error: 'No prompt function available for interactive token input'
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const token = _prompt();
|
|
171
|
+
|
|
172
|
+
// Validate
|
|
173
|
+
const validation = validateToken(token);
|
|
174
|
+
if (!validation.valid) {
|
|
175
|
+
console.log(` Invalid token: ${validation.reason}`);
|
|
176
|
+
return {
|
|
177
|
+
success: false,
|
|
178
|
+
method: 'automated',
|
|
179
|
+
error: validation.reason
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Save the secret — token is piped via stdin, never logged
|
|
184
|
+
const saveResult = saveSecret('BEADS_SYNC_TOKEN', token, options);
|
|
185
|
+
|
|
186
|
+
if (!saveResult.success) {
|
|
187
|
+
console.log(` Failed to save secret: ${saveResult.error}`);
|
|
188
|
+
return {
|
|
189
|
+
success: false,
|
|
190
|
+
method: 'automated',
|
|
191
|
+
error: saveResult.error
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log(' PAT saved as BEADS_SYNC_TOKEN repository secret.');
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
method: 'automated'
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
module.exports = {
|
|
203
|
+
checkGhAuth,
|
|
204
|
+
validateToken,
|
|
205
|
+
saveSecret,
|
|
206
|
+
setupPAT
|
|
207
|
+
};
|