@misterhuydo/sentinel 1.0.21 → 1.0.22
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/generate.js +10 -1
- package/lib/init.js +11 -9
- package/package.json +1 -1
- package/templates/workspace-sentinel.properties +5 -0
package/.cairn/session.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"message": "Auto-checkpoint at 2026-03-21T19:
|
|
3
|
-
"checkpoint_at": "2026-03-21T19:
|
|
2
|
+
"message": "Auto-checkpoint at 2026-03-21T19:19:54.642Z",
|
|
3
|
+
"checkpoint_at": "2026-03-21T19:19:54.643Z",
|
|
4
4
|
"active_files": [],
|
|
5
5
|
"notes": [],
|
|
6
6
|
"mtime_snapshot": {}
|
package/lib/generate.js
CHANGED
|
@@ -92,7 +92,7 @@ rm -f "$PID_FILE"
|
|
|
92
92
|
|
|
93
93
|
// ── Workspace-level startAll / stopAll ────────────────────────────────────────
|
|
94
94
|
|
|
95
|
-
function generateWorkspaceScripts(workspace, smtpConfig = {}) {
|
|
95
|
+
function generateWorkspaceScripts(workspace, smtpConfig = {}, slackConfig = {}) {
|
|
96
96
|
// Write shared sentinel.properties once (never overwrite existing)
|
|
97
97
|
const workspaceProps = path.join(workspace, 'sentinel.properties');
|
|
98
98
|
if (!fs.existsSync(workspaceProps)) {
|
|
@@ -104,6 +104,15 @@ function generateWorkspaceScripts(workspace, smtpConfig = {}) {
|
|
|
104
104
|
if (smtpConfig.password) tpl = tpl.replace('SMTP_PASSWORD=<app-password>', 'SMTP_PASSWORD=' + smtpConfig.password);
|
|
105
105
|
fs.writeFileSync(workspaceProps, tpl);
|
|
106
106
|
}
|
|
107
|
+
// Always upsert Slack tokens so re-runs persist them
|
|
108
|
+
if (slackConfig.botToken || slackConfig.appToken) {
|
|
109
|
+
let props = fs.readFileSync(workspaceProps, 'utf8');
|
|
110
|
+
if (slackConfig.botToken)
|
|
111
|
+
props = props.replace(/^#?\s*SLACK_BOT_TOKEN=.*/m, 'SLACK_BOT_TOKEN=' + slackConfig.botToken);
|
|
112
|
+
if (slackConfig.appToken)
|
|
113
|
+
props = props.replace(/^#?\s*SLACK_APP_TOKEN=.*/m, 'SLACK_APP_TOKEN=' + slackConfig.appToken);
|
|
114
|
+
fs.writeFileSync(workspaceProps, props);
|
|
115
|
+
}
|
|
107
116
|
// startAll.sh
|
|
108
117
|
fs.writeFileSync(path.join(workspace, 'startAll.sh'), `#!/usr/bin/env bash
|
|
109
118
|
# Start all valid Sentinel project instances.
|
package/lib/init.js
CHANGED
|
@@ -84,14 +84,14 @@ module.exports = async function init() {
|
|
|
84
84
|
{
|
|
85
85
|
type: prev => prev ? 'password' : null,
|
|
86
86
|
name: 'slackBotToken',
|
|
87
|
-
message: 'Slack Bot Token (xoxb-...)',
|
|
88
|
-
validate: v => v.startsWith('xoxb-') ? true : 'Should start with xoxb-',
|
|
87
|
+
message: existing.SLACK_BOT_TOKEN ? 'Slack Bot Token (press Enter to keep current)' : 'Slack Bot Token (xoxb-...)',
|
|
88
|
+
validate: v => !v || v.startsWith('xoxb-') ? true : 'Should start with xoxb-',
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
|
-
type: (_, {
|
|
91
|
+
type: (_, { setupSlack }) => setupSlack ? 'password' : null,
|
|
92
92
|
name: 'slackAppToken',
|
|
93
|
-
message: 'Slack App-Level Token (xapp-...)',
|
|
94
|
-
validate: v => v.startsWith('xapp-') ? true : 'Should start with xapp-',
|
|
93
|
+
message: existing.SLACK_APP_TOKEN ? 'Slack App-Level Token (press Enter to keep current)' : 'Slack App-Level Token (xapp-...)',
|
|
94
|
+
validate: v => !v || v.startsWith('xapp-') ? true : 'Should start with xapp-',
|
|
95
95
|
},
|
|
96
96
|
], { onCancel: () => process.exit(0) });
|
|
97
97
|
|
|
@@ -149,9 +149,9 @@ module.exports = async function init() {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
// ── Slack Bot ────────────────────────────────────────────────────────────────
|
|
152
|
-
if (
|
|
152
|
+
if (effectiveSlackBotToken && effectiveSlackAppToken) {
|
|
153
153
|
step('Slack Bot (Sentinel Boss)…');
|
|
154
|
-
ok('Tokens will be written to
|
|
154
|
+
ok('Tokens will be written to workspace sentinel.properties');
|
|
155
155
|
info('Sentinel Boss starts automatically when the project starts');
|
|
156
156
|
} else if (setupSlack) {
|
|
157
157
|
warn('Slack tokens not provided — add them to config/sentinel.properties later');
|
|
@@ -166,7 +166,7 @@ module.exports = async function init() {
|
|
|
166
166
|
if (example) {
|
|
167
167
|
step('Creating example project…');
|
|
168
168
|
const exampleDir = path.join(workspace, 'my-project');
|
|
169
|
-
writeExampleProject(exampleDir, codeDir, pythonBin, anthropicKey || '', { botToken:
|
|
169
|
+
writeExampleProject(exampleDir, codeDir, pythonBin, anthropicKey || '', { botToken: effectiveSlackBotToken, appToken: effectiveSlackAppToken });
|
|
170
170
|
ok(`Example project: ${exampleDir}`);
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -174,7 +174,9 @@ module.exports = async function init() {
|
|
|
174
174
|
step('Generating scripts…');
|
|
175
175
|
// If user left password blank (pressed Enter to keep), fall back to existing
|
|
176
176
|
const effectiveSmtpPassword = smtpPassword || existing.SMTP_PASSWORD || '';
|
|
177
|
-
|
|
177
|
+
const effectiveSlackBotToken = slackBotToken || existing.SLACK_BOT_TOKEN || '';
|
|
178
|
+
const effectiveSlackAppToken = slackAppToken || existing.SLACK_APP_TOKEN || '';
|
|
179
|
+
generateWorkspaceScripts(workspace, { host: smtpHost, user: smtpUser, password: effectiveSmtpPassword }, { botToken: effectiveSlackBotToken, appToken: effectiveSlackAppToken });
|
|
178
180
|
ok(`${workspace}/startAll.sh`);
|
|
179
181
|
ok(`${workspace}/stopAll.sh`);
|
|
180
182
|
|
package/package.json
CHANGED
|
@@ -26,3 +26,8 @@ UPGRADE_CHECK_HOURS=6
|
|
|
26
26
|
|
|
27
27
|
# Config repo polling: if the project dir is a git repo, pull for config changes every N seconds
|
|
28
28
|
CONFIG_POLL_INTERVAL=60
|
|
29
|
+
|
|
30
|
+
# Slack Bot (Sentinel Boss) — shared across all projects
|
|
31
|
+
# SLACK_BOT_TOKEN=xoxb-...
|
|
32
|
+
# SLACK_APP_TOKEN=xapp-...
|
|
33
|
+
# SLACK_CHANNEL=devops-sentinel
|