@misterhuydo/sentinel 1.4.76 → 1.4.78

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/.hint-lock CHANGED
@@ -1 +1 @@
1
- 2026-03-26T18:52:08.498Z
1
+ 2026-03-27T01:29:06.939Z
@@ -1,6 +1,6 @@
1
1
  {
2
- "message": "Auto-checkpoint at 2026-03-26T19:12:24.024Z",
3
- "checkpoint_at": "2026-03-26T19:12:24.038Z",
2
+ "message": "Auto-checkpoint at 2026-03-27T01:47:36.091Z",
3
+ "checkpoint_at": "2026-03-27T01:47:36.092Z",
4
4
  "active_files": [],
5
5
  "notes": [],
6
6
  "mtime_snapshot": {}
@@ -1,8 +1,8 @@
1
1
  {
2
- "J:\\Projects\\Sentinel\\cli\\lib\\upgrade.js": {
3
- "tempPath": "J:\\Projects\\Sentinel\\cli\\lib\\.cairn\\views\\fb78ac_upgrade.js",
2
+ "J:\\Projects\\Sentinel\\cli\\lib\\init.js": {
3
+ "tempPath": "J:\\Projects\\Sentinel\\cli\\lib\\.cairn\\views\\2a85cc_init.js",
4
4
  "state": "edit-ready",
5
- "minifiedAt": 1774409075884.3267,
5
+ "minifiedAt": 1774439246927.6174,
6
6
  "readCount": 1
7
7
  }
8
8
  }
@@ -88,19 +88,25 @@ module.exports = async function init() {
88
88
  message: 'Set up Slack Bot (Sentinel Boss — conversational AI interface)?',
89
89
  initial: !!(existing.SLACK_BOT_TOKEN),
90
90
  },
91
+ ], { onCancel: () => process.exit(0) });
92
+ if (answers.setupSlack && !existing.SLACK_BOT_TOKEN) {
93
+ printSlackSetupGuide();
94
+ }
95
+ const tokenAnswers = await prompts([
91
96
  {
92
- type: prev => prev ? 'password' : null,
97
+ type: answers.setupSlack ? 'password' : null,
93
98
  name: 'slackBotToken',
94
99
  message: existing.SLACK_BOT_TOKEN ? 'Slack Bot Token (press Enter to keep current)' : 'Slack Bot Token (xoxb-...)',
95
100
  validate: v => !v || v.startsWith('xoxb-') ? true : 'Should start with xoxb-',
96
101
  },
97
102
  {
98
- type: (_, { setupSlack }) => setupSlack ? 'password' : null,
103
+ type: answers.setupSlack ? 'password' : null,
99
104
  name: 'slackAppToken',
100
105
  message: existing.SLACK_APP_TOKEN ? 'Slack App-Level Token (press Enter to keep current)' : 'Slack App-Level Token (xapp-...)',
101
106
  validate: v => !v || v.startsWith('xapp-') ? true : 'Should start with xapp-',
102
107
  },
103
108
  ], { onCancel: () => process.exit(0) });
109
+ Object.assign(answers, tokenAnswers);
104
110
  const { workspace, authMode, anthropicKey, example, systemd, smtpUser, smtpPassword, smtpHost, setupSlack, slackBotToken, slackAppToken } = answers;
105
111
  const effectiveAnthropicKey = anthropicKey || existing.ANTHROPIC_API_KEY || '';
106
112
  const effectiveSmtpPassword = smtpPassword || existing.SMTP_PASSWORD || '';
@@ -169,7 +175,8 @@ module.exports = async function init() {
169
175
  ok('Tokens will be written to workspace sentinel.properties');
170
176
  info('Sentinel Boss starts automatically when the project starts');
171
177
  } else if (setupSlack) {
172
- warn('Slack tokens not provided — add them to config/sentinel.properties later');
178
+ warn('Slack tokens not provided — add them to sentinel.properties later');
179
+ info('Re-run sentinel init after creating the app to fill in the tokens');
173
180
  }
174
181
  step('Creating workspace…');
175
182
  fs.ensureDirSync(workspace);
@@ -341,6 +348,89 @@ function ensureNpmUserPrefix() {
341
348
  warn(`Could not check npm prefix: ${e.message}`);
342
349
  }
343
350
  }
351
+ function buildSlackManifest() {
352
+ return {
353
+ display_information: {
354
+ name: 'Sentinel',
355
+ description: 'Autonomous DevOps Agent — monitors logs, fixes bugs, manages deployments',
356
+ background_color: '#1a1a2e',
357
+ },
358
+ features: {
359
+ bot_user: {
360
+ display_name: 'Sentinel',
361
+ always_online: true,
362
+ },
363
+ },
364
+ oauth_config: {
365
+ scopes: {
366
+ bot: [
367
+ 'app_mentions:read',
368
+ 'channels:history',
369
+ 'channels:read',
370
+ 'chat:write',
371
+ 'chat:write.customize',
372
+ 'chat:write.public',
373
+ 'files:read',
374
+ 'files:write',
375
+ 'groups:history',
376
+ 'groups:read',
377
+ 'im:history',
378
+ 'im:read',
379
+ 'im:write',
380
+ 'mpim:history',
381
+ 'mpim:read',
382
+ 'reactions:write',
383
+ 'users:read',
384
+ 'users:read.email',
385
+ 'usergroups:read',
386
+ ],
387
+ },
388
+ },
389
+ settings: {
390
+ event_subscriptions: {
391
+ bot_events: [
392
+ 'app_mention',
393
+ 'message.channels',
394
+ 'message.groups',
395
+ 'message.im',
396
+ 'message.mpim',
397
+ ],
398
+ },
399
+ interactivity: { is_enabled: false },
400
+ org_deploy_enabled: false,
401
+ socket_mode_enabled: true,
402
+ token_rotation_enabled: false,
403
+ },
404
+ };
405
+ }
406
+ function printSlackSetupGuide() {
407
+ const manifest = buildSlackManifest();
408
+ const manifestJson = JSON.stringify(manifest);
409
+ const encoded = encodeURIComponent(manifestJson);
410
+ const createUrl = `https://api.slack.com/apps?new_app=1&manifest_json=${encoded}`;
411
+ step('Setting up Slack Bot (Sentinel Boss)…');
412
+ console.log(`
413
+ ${chalk.bold('One-click Slack app setup:')}
414
+ ${chalk.cyan(createUrl)}
415
+ ${chalk.bold('Steps after clicking the link:')}
416
+ ${chalk.white('1.')} Slack opens with all permissions pre-filled → click ${chalk.green('"Create App"')}
417
+ ${chalk.white('2.')} Click ${chalk.green('"Install to Workspace"')} → Allow
418
+ ${chalk.white('3.')} Copy ${chalk.yellow('Bot Token')} (OAuth & Permissions → Bot User OAuth Token → xoxb-...)
419
+ ${chalk.white('4.')} Go to ${chalk.cyan('Settings → Basic Information → App-Level Tokens')}
420
+ → ${chalk.green('"Generate Token and Scopes"')} name it anything, add scope: ${chalk.yellow('connections:write')}
421
+ → Copy ${chalk.yellow('App-Level Token')} (xapp-...)
422
+ ${chalk.white('5.')} Paste both tokens below ↓
423
+ `);
424
+ try {
425
+ const { execSync: _exec } = require('child_process');
426
+ const opener = process.platform === 'darwin' ? 'open'
427
+ : process.platform === 'win32' ? 'start'
428
+ : 'xdg-open';
429
+ _exec(`${opener} "${createUrl}"`, { stdio: 'ignore' });
430
+ console.log(chalk.green(' ✔') + ' Opened in your browser\n');
431
+ } catch (_) {
432
+ }
433
+ }
344
434
  function setupSystemd(workspace) {
345
435
  const user = os.userInfo().username;
346
436
  const svc = `/etc/systemd/system/sentinel.service`;
package/lib/init.js CHANGED
@@ -97,7 +97,7 @@ module.exports = async function init() {
97
97
  ], { onCancel: () => process.exit(0) });
98
98
 
99
99
  // ── Slack app creation helper (shown before token prompts) ───────────────────
100
- if (answers.setupSlack && !existing.SLACK_BOT_TOKEN) {
100
+ if (answers.setupSlack) {
101
101
  printSlackSetupGuide();
102
102
  }
103
103
 
package/lib/upgrade.js CHANGED
@@ -67,7 +67,7 @@ module.exports = async function upgrade() {
67
67
  const { version: installed } = require(path.join(npmRootEarly, '@misterhuydo', 'sentinel', 'package.json'));
68
68
  if (installed !== current) {
69
69
  ok(`Upgraded: ${current} → ${installed} — re-running with new version...`);
70
- const newBin = path.join(path.dirname(npmRootEarly), 'bin', 'sentinel');
70
+ const newBin = path.join(npmRootEarly, '..', '..', 'bin', 'sentinel');
71
71
  const r = spawnSync(newBin, ['upgrade'], { stdio: 'inherit' });
72
72
  process.exit(r.status || 0);
73
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/sentinel",
3
- "version": "1.4.76",
3
+ "version": "1.4.78",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"