@gitset-dev/cli 2.4.3 → 2.5.1
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/README.md +17 -9
- package/index.js +3 -1
- package/lib/cli-commit.js +43 -2
- package/lib/knowledge/ci.js +99 -45
- package/package.json +1 -1
- package/src/commands/knowledge.js +107 -18
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ gitset knowledge init # scaffold optional .gitset-knowledge.json (include/
|
|
|
101
101
|
gitset knowledge scan # zero AI calls — discovers files, prints the plan + exact cost estimate
|
|
102
102
|
gitset knowledge generate # shows the estimate again, asks to confirm, then writes the knowledge base
|
|
103
103
|
gitset knowledge update # incremental — only changed modules (and their direct importers) are re-summarized
|
|
104
|
-
gitset knowledge automate # writes a GitHub Actions workflow that
|
|
104
|
+
gitset knowledge automate # writes a GitHub Actions workflow that keeps it fresh in CI (direct commits, or PRs with --sync pr)
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
It's a six-stage local pipeline (Discover → Map → Summarize → Plan → Write →
|
|
@@ -113,14 +113,22 @@ generated link, command, and script before anything is written to disk.
|
|
|
113
113
|
Secrets are redacted locally before any file content is sent, and prose
|
|
114
114
|
docs / test file bodies are listed structurally but never sent at all.
|
|
115
115
|
|
|
116
|
-
`gitset knowledge automate`
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
`gitset knowledge automate` applies updates in one of two ways, and you
|
|
117
|
+
never touch a GitHub settings page for either:
|
|
118
|
+
|
|
119
|
+
- **Direct commit (the default).** CI commits refreshed docs straight to
|
|
120
|
+
your default branch using only the built-in Actions token — works on
|
|
121
|
+
every repository and organization, zero extra permissions or tokens,
|
|
122
|
+
and it can't re-trigger itself.
|
|
123
|
+
- **Review pull request (`--sync pr`).** Each update arrives as a PR on
|
|
124
|
+
the `gitset/knowledge-update` branch. Its one prerequisite is set up
|
|
125
|
+
for you: the CLI first tries enabling the repo's Actions PR permission
|
|
126
|
+
via the API; if your organization blocks that, it offers to store a
|
|
127
|
+
token from your existing `gh` login as the `GITSET_PR_TOKEN` secret —
|
|
128
|
+
explained in plain language before asking, reversible anytime by
|
|
129
|
+
deleting the secret. If neither works out, updates still commit and
|
|
130
|
+
push their branch safely; only the PR step fails, and the workflow run
|
|
131
|
+
shows that failure clearly rather than hide it.
|
|
124
132
|
|
|
125
133
|
## Templates
|
|
126
134
|
|
package/index.js
CHANGED
|
@@ -132,9 +132,11 @@ before anything reaches your AI provider.
|
|
|
132
132
|
generate full run (always shows the estimate and asks first)
|
|
133
133
|
update incremental: re-summarizes only changed modules
|
|
134
134
|
automate write a GitHub Actions workflow that runs update in CI
|
|
135
|
-
|
|
135
|
+
(commits directly by default; --sync pr for review PRs,
|
|
136
|
+
with the required access set up for you — always asks first)
|
|
136
137
|
--since <ref> update selector via git diff instead of content hashes
|
|
137
138
|
--mode <m> automate trigger: push | releases | weekly
|
|
139
|
+
--sync <s> automate apply style: commit (default) | pr
|
|
138
140
|
--provider <p> override the default provider for this run
|
|
139
141
|
--model <m> override the model
|
|
140
142
|
--yes skip confirmations (CI)`,
|
package/lib/cli-commit.js
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* `gitset commit` — local, BYOAI commit-message generation with iterative
|
|
5
5
|
* refinement. No backend, key never leaves the machine.
|
|
6
6
|
*
|
|
7
|
+
* If nothing is staged but the working tree has changes, an interactive
|
|
8
|
+
* session is offered a one-time prompt to stage everything (`git add -A`)
|
|
9
|
+
* and continue; a non-interactive session (CI, `--yes`, `--json`, `--print`,
|
|
10
|
+
* or no TTY) fails immediately instead of hanging on the prompt.
|
|
11
|
+
*
|
|
7
12
|
* Flags:
|
|
8
13
|
* --provider <name> override default provider for this run
|
|
9
14
|
* --model <name> override model
|
|
@@ -65,8 +70,44 @@ async function runCommitCommand(argv) {
|
|
|
65
70
|
return 1;
|
|
66
71
|
}
|
|
67
72
|
if (!changes.diff.trim()) {
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
if (nonInteractive) {
|
|
74
|
+
errln('Nothing staged. Stage changes with `git add` (or pass --all).');
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let status = '';
|
|
79
|
+
try {
|
|
80
|
+
status = execFileSync('git', ['status', '--porcelain'], { encoding: 'utf8' }).trim();
|
|
81
|
+
} catch {
|
|
82
|
+
// getStagedChanges() already confirmed this is a git repo; treat as no changes.
|
|
83
|
+
}
|
|
84
|
+
if (!status) {
|
|
85
|
+
errln('Nothing to commit — the working tree is clean.');
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
out(theme.warn('No staged changes detected.'));
|
|
90
|
+
const stage = (await ask('Stage all changes and continue? [y/N] ')).toLowerCase();
|
|
91
|
+
if (stage !== 'y' && stage !== 'yes') {
|
|
92
|
+
out('Aborted. Nothing staged.');
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
execFileSync('git', ['add', '-A'], { stdio: 'ignore' });
|
|
97
|
+
} catch {
|
|
98
|
+
errln('`git add -A` failed — is this a git repository?');
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
changes = getStagedChanges();
|
|
103
|
+
} catch (e) {
|
|
104
|
+
errln(e.message);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
if (!changes.diff.trim()) {
|
|
108
|
+
errln('Still nothing staged after `git add -A` — nothing to commit.');
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
70
111
|
}
|
|
71
112
|
|
|
72
113
|
const style = getFlag(argv, '--style') || 'conventional';
|
package/lib/knowledge/ci.js
CHANGED
|
@@ -8,6 +8,11 @@ const MODES = {
|
|
|
8
8
|
weekly: 'weekly (Mondays 06:00 UTC)',
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
const SYNC_MODES = {
|
|
12
|
+
commit: 'commit updates directly to the default branch (zero setup, works everywhere)',
|
|
13
|
+
pr: 'open a review pull request for each update',
|
|
14
|
+
};
|
|
15
|
+
|
|
11
16
|
function buildTrigger(mode, defaultBranch) {
|
|
12
17
|
if (mode === 'push') {
|
|
13
18
|
return [
|
|
@@ -41,9 +46,97 @@ function buildTrigger(mode, defaultBranch) {
|
|
|
41
46
|
throw new Error(`Unknown automation mode "${mode}". One of: ${Object.keys(MODES).join(', ')}`);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
function
|
|
49
|
+
function commitModeLines(defaultBranch) {
|
|
50
|
+
return {
|
|
51
|
+
header: [
|
|
52
|
+
'#',
|
|
53
|
+
`# Updates are committed directly to ${defaultBranch} using the built-in`,
|
|
54
|
+
'# Actions token — no extra permissions, tokens, or settings needed.',
|
|
55
|
+
"# It cannot re-trigger itself: GitHub never runs workflows for pushes",
|
|
56
|
+
'# made with the built-in token, and the path filters ignore these',
|
|
57
|
+
'# files anyway.',
|
|
58
|
+
],
|
|
59
|
+
permissions: [
|
|
60
|
+
'permissions:',
|
|
61
|
+
' contents: write',
|
|
62
|
+
],
|
|
63
|
+
checkoutWith: [
|
|
64
|
+
' with:',
|
|
65
|
+
` ref: ${defaultBranch}`,
|
|
66
|
+
],
|
|
67
|
+
finalStep: [
|
|
68
|
+
' - name: Commit the updated knowledge base',
|
|
69
|
+
' run: |',
|
|
70
|
+
' if git diff --quiet -- docs/gitset-knowledge AGENTS.md; then',
|
|
71
|
+
' echo "Knowledge base already up to date."',
|
|
72
|
+
' exit 0',
|
|
73
|
+
' fi',
|
|
74
|
+
' git config user.name "github-actions[bot]"',
|
|
75
|
+
' git config user.email "41898282+github-actions[bot]@users.noreply.github.com"',
|
|
76
|
+
' git add docs/gitset-knowledge AGENTS.md',
|
|
77
|
+
' git commit -m "docs: refresh knowledge base"',
|
|
78
|
+
` git push origin ${defaultBranch} || (git pull --rebase origin ${defaultBranch} && git push origin ${defaultBranch})`,
|
|
79
|
+
` echo "Knowledge base refreshed directly on ${defaultBranch}."`,
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function prModeLines() {
|
|
85
|
+
return {
|
|
86
|
+
header: [
|
|
87
|
+
'#',
|
|
88
|
+
'# PR mode needs ONE of the following (gitset knowledge automate sets',
|
|
89
|
+
'# this up for you):',
|
|
90
|
+
'# a. "Allow GitHub Actions to create and approve pull requests"',
|
|
91
|
+
'# enabled under Settings > Actions > General, OR',
|
|
92
|
+
'# b. a repository secret GITSET_PR_TOKEN holding a GitHub token',
|
|
93
|
+
'# that can open pull requests (used automatically when present;',
|
|
94
|
+
'# not subject to organization-level Actions restrictions).',
|
|
95
|
+
'# Without either, the update still commits and pushes its branch',
|
|
96
|
+
'# safely — only opening the review PR fails, and this job reports',
|
|
97
|
+
'# that as a failure so it is never silently missed.',
|
|
98
|
+
],
|
|
99
|
+
permissions: [
|
|
100
|
+
'permissions:',
|
|
101
|
+
' contents: write',
|
|
102
|
+
' pull-requests: write',
|
|
103
|
+
],
|
|
104
|
+
checkoutWith: [],
|
|
105
|
+
finalStep: [
|
|
106
|
+
' - name: Open a PR when the knowledge base changed',
|
|
107
|
+
' env:',
|
|
108
|
+
' GH_TOKEN: ${{ secrets.GITSET_PR_TOKEN || github.token }}',
|
|
109
|
+
' run: |',
|
|
110
|
+
' if git diff --quiet -- docs/gitset-knowledge AGENTS.md; then',
|
|
111
|
+
' echo "Knowledge base already up to date."',
|
|
112
|
+
' exit 0',
|
|
113
|
+
' fi',
|
|
114
|
+
' git config user.name "github-actions[bot]"',
|
|
115
|
+
' git config user.email "41898282+github-actions[bot]@users.noreply.github.com"',
|
|
116
|
+
' git switch -c gitset/knowledge-update',
|
|
117
|
+
' git add docs/gitset-knowledge AGENTS.md',
|
|
118
|
+
' git commit -m "docs: refresh knowledge base"',
|
|
119
|
+
' git push -f origin gitset/knowledge-update',
|
|
120
|
+
' echo "Committed and pushed gitset/knowledge-update — this work is now safe on GitHub regardless of the next step."',
|
|
121
|
+
' if PR_OUTPUT=$(gh pr create --title "docs: refresh knowledge base" --body "Automated incremental update by [Gitset](https://gitset.dev) Knowledge Mapper. Only changed modules were re-analyzed; review like any other docs change." 2>&1); then',
|
|
122
|
+
' echo "$PR_OUTPUT"',
|
|
123
|
+
' elif echo "$PR_OUTPUT" | grep -qi "already exists"; then',
|
|
124
|
+
' echo "A pull request for gitset/knowledge-update already exists — nothing further to do."',
|
|
125
|
+
' echo "$PR_OUTPUT"',
|
|
126
|
+
' else',
|
|
127
|
+
' echo "$PR_OUTPUT"',
|
|
128
|
+
' echo "::error::Could not open the pull request automatically (the branch and commit ARE safely pushed — no work was lost). Run \'gitset knowledge automate\' again and pick PR mode to set this up automatically, or add a repository secret GITSET_PR_TOKEN with a GitHub token that can open PRs, or open it yourself: https://github.com/${{ github.repository }}/pull/new/gitset/knowledge-update"',
|
|
129
|
+
' exit 1',
|
|
130
|
+
' fi',
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function buildKnowledgeWorkflow({ mode, syncMode = 'commit', provider, envKey, model, defaultBranch = 'main' }) {
|
|
45
136
|
if (!provider || !envKey) throw new Error('provider and envKey are required');
|
|
137
|
+
if (!SYNC_MODES[syncMode]) throw new Error(`Unknown sync mode "${syncMode}". One of: ${Object.keys(SYNC_MODES).join(', ')}`);
|
|
46
138
|
const updateCmd = `gitset knowledge update --yes --provider ${provider}${model ? ` --model ${model}` : ''}`;
|
|
139
|
+
const sync = syncMode === 'commit' ? commitModeLines(defaultBranch) : prModeLines();
|
|
47
140
|
|
|
48
141
|
return [
|
|
49
142
|
'name: Gitset Knowledge Mapper',
|
|
@@ -53,26 +146,9 @@ function buildKnowledgeWorkflow({ mode, provider, envKey, model, defaultBranch =
|
|
|
53
146
|
'# provider — never to Gitset. Runs whose mapped source files are',
|
|
54
147
|
'# unchanged exit without any AI call (content-hash diff), so harmless',
|
|
55
148
|
'# triggers cost nothing beyond a few CI seconds.',
|
|
56
|
-
|
|
57
|
-
'# Also requires "Allow GitHub Actions to create and approve pull',
|
|
58
|
-
'# requests" to be enabled: Settings > Actions > General > Workflow',
|
|
59
|
-
'# permissions. Without it, the update still commits and pushes',
|
|
60
|
-
'# safely, but opening the review PR fails and this job reports it',
|
|
61
|
-
'# as a failure so it is never silently missed.',
|
|
62
|
-
'#',
|
|
63
|
-
'# If your organization enforces that setting off and it cannot be',
|
|
64
|
-
'# changed (the checkbox is greyed out even at the org level), add an',
|
|
65
|
-
'# optional repository secret GITSET_PR_TOKEN — a personal access',
|
|
66
|
-
'# token (classic: repo scope; fine-grained: Pull requests write) —',
|
|
67
|
-
'# and this workflow uses it instead of the default token, which is',
|
|
68
|
-
"# the standard workaround: an organization's PR-creation restriction",
|
|
69
|
-
'# applies to the auto-generated Actions token, not to a real PAT.',
|
|
70
|
-
'# No workflow changes needed after adding it — the next run picks it',
|
|
71
|
-
'# up automatically.',
|
|
149
|
+
...sync.header,
|
|
72
150
|
...buildTrigger(mode, defaultBranch),
|
|
73
|
-
|
|
74
|
-
' contents: write',
|
|
75
|
-
' pull-requests: write',
|
|
151
|
+
...sync.permissions,
|
|
76
152
|
'concurrency:',
|
|
77
153
|
' group: gitset-knowledge',
|
|
78
154
|
' cancel-in-progress: false',
|
|
@@ -81,6 +157,7 @@ function buildKnowledgeWorkflow({ mode, provider, envKey, model, defaultBranch =
|
|
|
81
157
|
' runs-on: ubuntu-latest',
|
|
82
158
|
' steps:',
|
|
83
159
|
' - uses: actions/checkout@v4',
|
|
160
|
+
...sync.checkoutWith,
|
|
84
161
|
' - uses: actions/setup-node@v4',
|
|
85
162
|
' with:',
|
|
86
163
|
" node-version: '20'",
|
|
@@ -89,31 +166,7 @@ function buildKnowledgeWorkflow({ mode, provider, envKey, model, defaultBranch =
|
|
|
89
166
|
' env:',
|
|
90
167
|
` ${envKey}: \${{ secrets.${envKey} }}`,
|
|
91
168
|
` run: ${updateCmd}`,
|
|
92
|
-
|
|
93
|
-
' env:',
|
|
94
|
-
' GH_TOKEN: ${{ secrets.GITSET_PR_TOKEN || github.token }}',
|
|
95
|
-
' run: |',
|
|
96
|
-
' if git diff --quiet -- docs/gitset-knowledge AGENTS.md; then',
|
|
97
|
-
' echo "Knowledge base already up to date."',
|
|
98
|
-
' exit 0',
|
|
99
|
-
' fi',
|
|
100
|
-
' git config user.name "github-actions[bot]"',
|
|
101
|
-
' git config user.email "41898282+github-actions[bot]@users.noreply.github.com"',
|
|
102
|
-
' git switch -c gitset/knowledge-update',
|
|
103
|
-
' git add docs/gitset-knowledge AGENTS.md',
|
|
104
|
-
' git commit -m "docs: refresh knowledge base"',
|
|
105
|
-
' git push -f origin gitset/knowledge-update',
|
|
106
|
-
' echo "Committed and pushed gitset/knowledge-update — this work is now safe on GitHub regardless of the next step."',
|
|
107
|
-
' if PR_OUTPUT=$(gh pr create --title "docs: refresh knowledge base" --body "Automated incremental update by [Gitset](https://gitset.dev) Knowledge Mapper. Only changed modules were re-analyzed; review like any other docs change." 2>&1); then',
|
|
108
|
-
' echo "$PR_OUTPUT"',
|
|
109
|
-
' elif echo "$PR_OUTPUT" | grep -qi "already exists"; then',
|
|
110
|
-
' echo "A pull request for gitset/knowledge-update already exists — nothing further to do."',
|
|
111
|
-
' echo "$PR_OUTPUT"',
|
|
112
|
-
' else',
|
|
113
|
-
' echo "$PR_OUTPUT"',
|
|
114
|
-
' echo "::error::Could not open the pull request automatically (the branch and commit ARE safely pushed — no work was lost). Try, in order: (1) enable \'Allow GitHub Actions to create and approve pull requests\' under Settings > Actions > General > Workflow permissions; (2) if that checkbox is greyed out, your organization enforces it off — add a repository secret named GITSET_PR_TOKEN with a personal access token (repo scope) and re-run, no workflow change needed; (3) open the PR yourself: https://github.com/${{ github.repository }}/pull/new/gitset/knowledge-update"',
|
|
115
|
-
' exit 1',
|
|
116
|
-
' fi',
|
|
169
|
+
...sync.finalStep,
|
|
117
170
|
'',
|
|
118
171
|
].join('\n');
|
|
119
172
|
}
|
|
@@ -121,5 +174,6 @@ function buildKnowledgeWorkflow({ mode, provider, envKey, model, defaultBranch =
|
|
|
121
174
|
module.exports = {
|
|
122
175
|
WORKFLOW_PATH,
|
|
123
176
|
MODES,
|
|
177
|
+
SYNC_MODES,
|
|
124
178
|
buildKnowledgeWorkflow,
|
|
125
179
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitset-dev/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "Gitset CLI — drafts commits, PRs, issues, READMEs and release notes with your own AI key. Fully local: your code and keys never touch a Gitset server. Draft. Refine. Ship.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -521,11 +521,65 @@ async function ensurePrPermission(repo, argv) {
|
|
|
521
521
|
return 'enabled';
|
|
522
522
|
} catch {
|
|
523
523
|
log('Could not change it automatically — you may not have admin access on this repo, or an organization policy locks this setting (if it appears greyed out in the GitHub UI at both the repo and org level, that\'s a hard enforcement you cannot toggle either way).', 'yellow');
|
|
524
|
-
log('Workaround: add a repository secret named GITSET_PR_TOKEN with a personal access token (repo scope). It is not subject to the organization\'s Actions PR-creation restriction, and the workflow picks it up automatically — no need to re-run automate.', 'dim');
|
|
525
524
|
return 'failed';
|
|
526
525
|
}
|
|
527
526
|
}
|
|
528
527
|
|
|
528
|
+
async function provisionPrToken(repo, argv) {
|
|
529
|
+
if (!repo.includes('/')) return 'unavailable';
|
|
530
|
+
|
|
531
|
+
const existing = (() => {
|
|
532
|
+
try {
|
|
533
|
+
const out = execFileSync('gh', ['secret', 'list', '--repo', repo], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
534
|
+
return out.includes('GITSET_PR_TOKEN');
|
|
535
|
+
} catch {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
})();
|
|
539
|
+
if (existing) {
|
|
540
|
+
log('The GITSET_PR_TOKEN secret already exists in this repository — PR mode is ready.', 'green');
|
|
541
|
+
return 'already-provisioned';
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
log('\nNo problem — this can be fixed right now, automatically:', 'cyan');
|
|
545
|
+
log(' Your repository (or its organization) blocks the built-in CI token from opening pull requests.', 'reset');
|
|
546
|
+
log(' The fix: store a token from YOUR current GitHub login (the same one the gh CLI already uses) as an encrypted secret named GITSET_PR_TOKEN in this repository.', 'reset');
|
|
547
|
+
log(' · You don\'t create anything manually — no settings pages, no token forms.', 'dim');
|
|
548
|
+
log(' · The token is stored encrypted by GitHub, in this repository only.', 'dim');
|
|
549
|
+
log(' · CI will open pull requests as you, which your organization does allow.', 'dim');
|
|
550
|
+
log(' · Undo anytime: delete the GITSET_PR_TOKEN secret and CI falls back to the built-in token.', 'dim');
|
|
551
|
+
|
|
552
|
+
const proceed = await confirmOrAbort('\nStore it now?', argv);
|
|
553
|
+
if (!proceed) return 'declined';
|
|
554
|
+
|
|
555
|
+
let token = '';
|
|
556
|
+
try {
|
|
557
|
+
token = execFileSync('gh', ['auth', 'token'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
558
|
+
} catch { }
|
|
559
|
+
if (!token) {
|
|
560
|
+
log('Could not read a token from your gh login. Run "gh auth login" first, then re-run: gitset knowledge automate', 'red');
|
|
561
|
+
return 'failed';
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
execFileSync('gh', ['secret', 'set', 'GITSET_PR_TOKEN', '--repo', repo], { input: token, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
566
|
+
} catch {
|
|
567
|
+
log('Could not store the secret (you may not have admin access on this repository).', 'red');
|
|
568
|
+
return 'failed';
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
try {
|
|
572
|
+
const out = execFileSync('gh', ['secret', 'list', '--repo', repo], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
573
|
+
if (!out.includes('GITSET_PR_TOKEN')) throw new Error('not visible');
|
|
574
|
+
} catch {
|
|
575
|
+
log('The secret was sent but could not be verified — check https://github.com/' + repo + '/settings/secrets/actions', 'yellow');
|
|
576
|
+
return 'unverified';
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
log('Done — GITSET_PR_TOKEN is stored. CI can now open pull requests, starting with the very next run.', 'green');
|
|
580
|
+
return 'provisioned';
|
|
581
|
+
}
|
|
582
|
+
|
|
529
583
|
async function runAutomate(rootDir, argv) {
|
|
530
584
|
let cfg;
|
|
531
585
|
try {
|
|
@@ -566,8 +620,44 @@ async function runAutomate(rootDir, argv) {
|
|
|
566
620
|
return 1;
|
|
567
621
|
}
|
|
568
622
|
|
|
623
|
+
const repo = repoLabel(rootDir);
|
|
624
|
+
|
|
625
|
+
let syncMode = flag(argv, '--sync');
|
|
626
|
+
if (!syncMode) {
|
|
627
|
+
if (!process.stdin.isTTY || argv.includes('--yes') || argv.includes('-y')) {
|
|
628
|
+
syncMode = 'commit';
|
|
629
|
+
} else {
|
|
630
|
+
syncMode = await selectOption('How should CI apply each update?', [
|
|
631
|
+
{ label: `Commit directly to ${defaultBranch} (recommended — zero setup, works on every repo and org)`, value: 'commit' },
|
|
632
|
+
{ label: 'Open a review pull request for each update (one extra one-time step — automated for you)', value: 'pr' },
|
|
633
|
+
{ label: 'Cancel', value: 'cancel' },
|
|
634
|
+
]);
|
|
635
|
+
if (syncMode === 'cancel') {
|
|
636
|
+
log('Nothing written.', 'yellow');
|
|
637
|
+
return 0;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
if (!km.SYNC_MODES[syncMode]) {
|
|
642
|
+
log(`Unknown sync mode "${syncMode}". One of: ${Object.keys(km.SYNC_MODES).join(', ')}`, 'red');
|
|
643
|
+
return 1;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
let prReady = null;
|
|
647
|
+
if (syncMode === 'pr') {
|
|
648
|
+
const prPermission = await ensurePrPermission(repo, argv);
|
|
649
|
+
if (prPermission === 'enabled' || prPermission === 'already-enabled') {
|
|
650
|
+
prReady = 'permission';
|
|
651
|
+
} else {
|
|
652
|
+
const patStatus = await provisionPrToken(repo, argv);
|
|
653
|
+
if (patStatus === 'provisioned' || patStatus === 'already-provisioned') prReady = 'token';
|
|
654
|
+
else if (patStatus === 'unverified') prReady = 'token-unverified';
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
569
658
|
const yaml = km.buildKnowledgeWorkflow({
|
|
570
659
|
mode,
|
|
660
|
+
syncMode,
|
|
571
661
|
provider: cfg.provider,
|
|
572
662
|
envKey,
|
|
573
663
|
model: cfg.model || null,
|
|
@@ -591,9 +681,6 @@ async function runAutomate(rootDir, argv) {
|
|
|
591
681
|
fs.writeFileSync(target, yaml);
|
|
592
682
|
log(`\nWrote ${km.WORKFLOW_PATH}.`, 'green');
|
|
593
683
|
|
|
594
|
-
const repo = repoLabel(rootDir);
|
|
595
|
-
const prPermission = await ensurePrPermission(repo, argv);
|
|
596
|
-
|
|
597
684
|
log('\nNext steps:', 'cyan');
|
|
598
685
|
log(` 1. Add the repository secret ${envKey} with your ${cfg.provider} API key:`, 'reset');
|
|
599
686
|
if (repo.includes('/')) {
|
|
@@ -601,23 +688,24 @@ async function runAutomate(rootDir, argv) {
|
|
|
601
688
|
} else {
|
|
602
689
|
log(' GitHub repo > Settings > Secrets and variables > Actions', 'dim');
|
|
603
690
|
}
|
|
604
|
-
|
|
605
|
-
|
|
691
|
+
log(' 2. Make sure the knowledge base itself is committed (gitset knowledge generate, then commit docs/gitset-knowledge/ and AGENTS.md).', 'reset');
|
|
692
|
+
log(' 3. Commit and push the workflow file.', 'reset');
|
|
693
|
+
|
|
694
|
+
if (syncMode === 'commit') {
|
|
695
|
+
log(`\nThat's it — CI will commit refreshed docs straight to ${defaultBranch} whenever mapped source changes. No permissions to touch, no tokens to create, and runs with no mapped changes make zero AI calls.`, 'dim');
|
|
696
|
+
log('Prefer reviewing each update as a pull request instead? Re-run: gitset knowledge automate --sync pr', 'dim');
|
|
606
697
|
} else {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
698
|
+
if (prReady === 'permission') {
|
|
699
|
+
log('\nPR mode is ready: GitHub Actions is allowed to open pull requests in this repository.', 'dim');
|
|
700
|
+
} else if (prReady === 'token') {
|
|
701
|
+
log('\nPR mode is ready: CI will open pull requests using the GITSET_PR_TOKEN secret that was just stored.', 'dim');
|
|
702
|
+
} else if (prReady === 'token-unverified') {
|
|
703
|
+
log(`\nPR mode should be ready, but the stored secret could not be verified — double-check https://github.com/${repo}/settings/secrets/actions`, 'yellow');
|
|
610
704
|
} else {
|
|
611
|
-
log('
|
|
612
|
-
}
|
|
613
|
-
log(' Without this, the update still runs and commits safely — only opening the review PR fails, and the workflow run will show that failure clearly rather than hide it.', 'dim');
|
|
614
|
-
if (prPermission === 'failed') {
|
|
615
|
-
log(' If that checkbox is greyed out even at the organization level, it is enforced off and cannot be toggled: add a repository secret named GITSET_PR_TOKEN with a personal access token (repo scope) instead — the workflow uses it automatically, no changes needed.', 'dim');
|
|
705
|
+
log('\nPR mode is NOT ready yet: CI cannot open pull requests in this repository until one of the fixes above is applied. Updates will still commit and push their branch safely — only the PR step will fail, visibly. Re-run "gitset knowledge automate" anytime to finish the setup, or switch to zero-setup direct commits with: gitset knowledge automate --sync commit', 'yellow');
|
|
616
706
|
}
|
|
707
|
+
log('When mapped source changes land, CI opens a PR on branch gitset/knowledge-update — you review it like any docs change. Runs with no mapped changes make zero AI calls.', 'dim');
|
|
617
708
|
}
|
|
618
|
-
log(' 3. Make sure the knowledge base itself is committed (gitset knowledge generate, then commit docs/gitset-knowledge/ and AGENTS.md).', 'reset');
|
|
619
|
-
log(' 4. Commit and push the workflow file.', 'reset');
|
|
620
|
-
log('\nWhen mapped source changes land, CI opens a PR on branch gitset/knowledge-update — you review it like any docs change. Runs with no mapped changes make zero AI calls.', 'dim');
|
|
621
709
|
return 0;
|
|
622
710
|
}
|
|
623
711
|
|
|
@@ -648,7 +736,8 @@ async function runKnowledgeCommand(argv = []) {
|
|
|
648
736
|
log(' generate build docs/gitset-knowledge/ from source code (asks before spending)', 'dim');
|
|
649
737
|
log(' update incremental refresh: only changed modules are re-summarized', 'dim');
|
|
650
738
|
log(' automate write a CI workflow that keeps it fresh (always asks first)', 'dim');
|
|
651
|
-
log(' flags --provider <p> --model <m> --yes --since <ref> (update)
|
|
739
|
+
log(' flags --provider <p> --model <m> --yes --since <ref> (update)', 'dim');
|
|
740
|
+
log(' --mode <push|releases|weekly> --sync <commit|pr> (automate)', 'dim');
|
|
652
741
|
return verb ? 1 : 0;
|
|
653
742
|
}
|
|
654
743
|
}
|