@misterhuydo/sentinel 1.3.1 → 1.3.2
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/.cairn/session.json +2 -2
- package/lib/add.js +46 -1
- package/lib/generate.js +10 -1
- package/package.json +1 -1
package/.cairn/session.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"message": "Auto-checkpoint at 2026-03-23T17:
|
|
3
|
-
"checkpoint_at": "2026-03-23T17:
|
|
2
|
+
"message": "Auto-checkpoint at 2026-03-23T17:56:42.485Z",
|
|
3
|
+
"checkpoint_at": "2026-03-23T17:56:42.486Z",
|
|
4
4
|
"active_files": [],
|
|
5
5
|
"notes": [],
|
|
6
6
|
"mtime_snapshot": {}
|
package/lib/add.js
CHANGED
|
@@ -364,6 +364,51 @@ async function addFromGit(gitUrl, workspace) {
|
|
|
364
364
|
warn('AUTO_PUBLISH=true: fixes push directly to main. Ensure CI blocks bad pushes.');
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
// ── GitHub token ───────────────────────────────────────────────────────────
|
|
368
|
+
// AUTO_PUBLISH=false → required (open PRs via API)
|
|
369
|
+
// AUTO_PUBLISH=true → optional (CI/CD triggers only)
|
|
370
|
+
const workspaceProps = path.join(workspace, 'sentinel.properties');
|
|
371
|
+
const existingToken = fs.existsSync(workspaceProps)
|
|
372
|
+
? (fs.readFileSync(workspaceProps, 'utf8').match(/^GITHUB_TOKEN\s*=\s*(.+)$/m) || [])[1]?.trim()
|
|
373
|
+
: '';
|
|
374
|
+
|
|
375
|
+
if (!autoPublish) {
|
|
376
|
+
// PR mode — token is required
|
|
377
|
+
console.log('');
|
|
378
|
+
console.log(chalk.bold(' GitHub Personal Access Token (classic) — required for opening PRs'));
|
|
379
|
+
console.log(chalk.cyan(' github.com/settings/tokens/new → Tokens (classic)'));
|
|
380
|
+
console.log(chalk.cyan(' Note: "Expiration → No expiration" Scope: ✓ repo'));
|
|
381
|
+
console.log('');
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const { githubToken } = await prompts({
|
|
385
|
+
type: (!autoPublish || !existingToken) ? 'password' : null,
|
|
386
|
+
name: 'githubToken',
|
|
387
|
+
message: existingToken
|
|
388
|
+
? 'GitHub token (press Enter to keep current)'
|
|
389
|
+
: autoPublish
|
|
390
|
+
? 'GitHub token (classic, repo scope) — optional, press Enter to skip'
|
|
391
|
+
: 'GitHub token (classic, repo scope)',
|
|
392
|
+
validate: v => {
|
|
393
|
+
if (!autoPublish && !v && !existingToken) return 'Token is required for PR mode';
|
|
394
|
+
if (v && !v.startsWith('ghp_') && !v.startsWith('github_pat_')) return 'Should start with ghp_ or github_pat_';
|
|
395
|
+
return true;
|
|
396
|
+
},
|
|
397
|
+
}, { onCancel: () => process.exit(0) });
|
|
398
|
+
|
|
399
|
+
const effectiveToken = githubToken || existingToken || '';
|
|
400
|
+
if (effectiveToken && fs.existsSync(workspaceProps)) {
|
|
401
|
+
let props = fs.readFileSync(workspaceProps, 'utf8');
|
|
402
|
+
if (/^#?\s*GITHUB_TOKEN\s*=/m.test(props))
|
|
403
|
+
props = props.replace(/^#?\s*GITHUB_TOKEN\s*=.*/m, `GITHUB_TOKEN=${effectiveToken}`);
|
|
404
|
+
else
|
|
405
|
+
props = props.trimEnd() + `\nGITHUB_TOKEN=${effectiveToken}\n`;
|
|
406
|
+
fs.writeFileSync(workspaceProps, props);
|
|
407
|
+
ok('GITHUB_TOKEN saved to workspace sentinel.properties');
|
|
408
|
+
} else if (effectiveToken) {
|
|
409
|
+
info('GITHUB_TOKEN will be written when project files are created');
|
|
410
|
+
}
|
|
411
|
+
|
|
367
412
|
// ── Preview + confirm ──────────────────────────────────────────────────────
|
|
368
413
|
const projectDir = path.join(workspace, name);
|
|
369
414
|
|
|
@@ -426,7 +471,7 @@ async function addFromGit(gitUrl, workspace) {
|
|
|
426
471
|
});
|
|
427
472
|
const example = path.join(repoDir, '_example.properties');
|
|
428
473
|
if (fs.existsSync(example)) fs.removeSync(example);
|
|
429
|
-
generateWorkspaceScripts(workspace);
|
|
474
|
+
generateWorkspaceScripts(workspace, {}, {}, {}, effectiveToken);
|
|
430
475
|
ok(`Project "${name}" created at ${projectDir}`);
|
|
431
476
|
printNextSteps(projectDir, autoPublish);
|
|
432
477
|
}
|
package/lib/generate.js
CHANGED
|
@@ -96,7 +96,7 @@ rm -f "$PID_FILE"
|
|
|
96
96
|
|
|
97
97
|
// ── Workspace-level startAll / stopAll ────────────────────────────────────────
|
|
98
98
|
|
|
99
|
-
function generateWorkspaceScripts(workspace, smtpConfig = {}, slackConfig = {}, authConfig = {}) {
|
|
99
|
+
function generateWorkspaceScripts(workspace, smtpConfig = {}, slackConfig = {}, authConfig = {}, githubToken = '') {
|
|
100
100
|
// Write shared sentinel.properties once (never overwrite existing)
|
|
101
101
|
const workspaceProps = path.join(workspace, 'sentinel.properties');
|
|
102
102
|
if (!fs.existsSync(workspaceProps)) {
|
|
@@ -126,6 +126,15 @@ function generateWorkspaceScripts(workspace, smtpConfig = {}, slackConfig = {},
|
|
|
126
126
|
}
|
|
127
127
|
fs.writeFileSync(workspaceProps, props);
|
|
128
128
|
}
|
|
129
|
+
// Always upsert GitHub token so re-runs persist it
|
|
130
|
+
if (githubToken) {
|
|
131
|
+
let props = fs.readFileSync(workspaceProps, 'utf8');
|
|
132
|
+
if (/^#?\s*GITHUB_TOKEN=/m.test(props))
|
|
133
|
+
props = props.replace(/^#?\s*GITHUB_TOKEN=.*/mg, 'GITHUB_TOKEN=' + githubToken);
|
|
134
|
+
else
|
|
135
|
+
props = props.trimEnd() + '\nGITHUB_TOKEN=' + githubToken + '\n';
|
|
136
|
+
fs.writeFileSync(workspaceProps, props);
|
|
137
|
+
}
|
|
129
138
|
// Always upsert Slack tokens so re-runs persist them
|
|
130
139
|
if (slackConfig.botToken || slackConfig.appToken) {
|
|
131
140
|
let props = fs.readFileSync(workspaceProps, 'utf8');
|