@misterhuydo/sentinel 1.3.3 → 1.3.5

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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "message": "Auto-checkpoint at 2026-03-23T18:08:05.159Z",
3
- "checkpoint_at": "2026-03-23T18:08:05.160Z",
2
+ "message": "Auto-checkpoint at 2026-03-23T18:27:21.579Z",
3
+ "checkpoint_at": "2026-03-23T18:27:21.580Z",
4
4
  "active_files": [],
5
5
  "notes": [],
6
6
  "mtime_snapshot": {}
package/lib/add.js CHANGED
@@ -179,11 +179,29 @@ function printDeployKeyInstructions(orgRepo, keyFile) {
179
179
  function gitEnv(extra = {}) {
180
180
  const PATH = [
181
181
  process.env.PATH || '',
182
- '/usr/bin', '/usr/local/bin', '/bin', '/usr/sbin',
182
+ '/usr/bin', '/usr/local/bin', '/bin', '/usr/sbin', '/usr/local/sbin',
183
183
  ].filter(Boolean).join(':');
184
184
  return { ...process.env, PATH, GIT_TERMINAL_PROMPT: '0', ...extra };
185
185
  }
186
186
 
187
+ function findBin(name) {
188
+ const candidates = [
189
+ `/usr/bin/${name}`, `/usr/local/bin/${name}`, `/bin/${name}`,
190
+ ];
191
+ for (const p of candidates) {
192
+ if (fs.existsSync(p)) return p;
193
+ }
194
+ // fall back to letting the shell resolve it
195
+ const r = spawnSync('which', [name], { encoding: 'utf8', env: gitEnv() });
196
+ return (r.stdout || '').trim() || name;
197
+ }
198
+
199
+ let _gitBin;
200
+ function gitBin() {
201
+ if (!_gitBin) _gitBin = findBin('git');
202
+ return _gitBin;
203
+ }
204
+
187
205
  // ── repo discovery helpers ────────────────────────────────────────────────────
188
206
 
189
207
  function gitUrlToOrgRepo(gitUrl) {
@@ -198,7 +216,7 @@ function toHttpsUrl(gitUrl) {
198
216
  }
199
217
 
200
218
  function isPublicRepo(gitUrl) {
201
- const r = spawnSync('git', ['ls-remote', '--heads', toHttpsUrl(gitUrl)], {
219
+ const r = spawnSync(gitBin(), ['ls-remote', '--heads', toHttpsUrl(gitUrl)], {
202
220
  encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'],
203
221
  env: gitEnv(),
204
222
  });
@@ -209,7 +227,7 @@ function validateAccess(repoUrl, keyFile) {
209
227
  const extra = keyFile
210
228
  ? { GIT_SSH_COMMAND: `ssh -i ${keyFile} -o StrictHostKeyChecking=no -o BatchMode=yes` }
211
229
  : {};
212
- const r = spawnSync('git', ['ls-remote', '--heads', repoUrl], {
230
+ const r = spawnSync(gitBin(), ['ls-remote', '--heads', repoUrl], {
213
231
  encoding: 'utf8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'],
214
232
  env: gitEnv(extra),
215
233
  });
@@ -269,7 +287,7 @@ async function addFromGit(gitUrl, workspace) {
269
287
  step(`[2/3] Scanning repo-configs in ${repoSlug}…`);
270
288
 
271
289
  if (!fs.existsSync(localPath)) {
272
- spawnSync('git', ['clone', '--depth', '1', gitUrl, localPath], {
290
+ spawnSync(gitBin(), ['clone', '--depth', '1', gitUrl, localPath], {
273
291
  stdio: 'inherit',
274
292
  env: gitEnv({ GIT_SSH_COMMAND: `ssh -i ${keyFile} -o StrictHostKeyChecking=no -o BatchMode=yes` }),
275
293
  });
@@ -466,6 +484,7 @@ async function addFromGit(gitUrl, workspace) {
466
484
  }
467
485
  ok(`Project "${name}" ready at ${localPath}`);
468
486
  printNextSteps(localPath, autoPublish);
487
+ await offerToStart(localPath);
469
488
  } else {
470
489
  // No existing repo-configs — scaffold fresh project
471
490
  fs.ensureDirSync(projectDir);
@@ -485,6 +504,7 @@ async function addFromGit(gitUrl, workspace) {
485
504
  generateWorkspaceScripts(workspace, {}, {}, {}, effectiveToken);
486
505
  ok(`Project "${name}" created at ${projectDir}`);
487
506
  printNextSteps(projectDir, autoPublish);
507
+ await offerToStart(projectDir);
488
508
  }
489
509
  }
490
510
 
@@ -632,21 +652,36 @@ async function addFromUrl(url, workspace) {
632
652
  // ── printNextSteps ────────────────────────────────────────────────────────────
633
653
 
634
654
  function printNextSteps(projectDir, autoPublish) {
655
+ const logFile = path.join(projectDir, 'logs', 'sentinel.log');
635
656
  const mode = autoPublish === true
636
- ? chalk.yellow(' ⚠ Fixes push directly to main — ensure CI blocks bad pushes')
657
+ ? chalk.yellow('\n ⚠ Fixes push directly to main — ensure CI blocks bad pushes')
637
658
  : autoPublish === false
638
- ? chalk.cyan(' → Sentinel will open a GitHub PR for each fix — review and merge at github.com')
659
+ ? chalk.cyan('\n → Sentinel opens a GitHub PR for each fix — review and merge at github.com')
639
660
  : '';
640
661
  console.log(`
641
- Next steps:
642
- 1. Edit config/log-configs/ to add your log sources
643
- ${chalk.cyan(`${projectDir}/config/`)}
644
- 2. Start Sentinel:
645
- ${chalk.cyan(`${projectDir}/start.sh`)}
646
- ${mode ? ' ' + mode : ''}
662
+ Config: ${chalk.cyan(path.join(projectDir, 'config', ''))}
663
+ Start: ${chalk.cyan(path.join(projectDir, 'start.sh'))}${mode}
664
+ Logs: ${chalk.cyan(logFile)}
665
+ ${chalk.gray(`tail -f ${logFile}`)}
647
666
  `);
648
667
  }
649
668
 
669
+ async function offerToStart(projectDir) {
670
+ const startSh = path.join(projectDir, 'start.sh');
671
+ if (!fs.existsSync(startSh)) return;
672
+ const { startNow } = await prompts({
673
+ type: 'confirm', name: 'startNow',
674
+ message: 'Start Sentinel now?', initial: true,
675
+ }, { onCancel: () => {} });
676
+ if (!startNow) return;
677
+ const { status } = spawnSync('bash', [startSh], { stdio: 'inherit', env: gitEnv() });
678
+ if (status === 0) {
679
+ const logFile = path.join(projectDir, 'logs', 'sentinel.log');
680
+ ok('Sentinel started');
681
+ info(`Logs: tail -f ${logFile}`);
682
+ }
683
+ }
684
+
650
685
  // ── entry point ───────────────────────────────────────────────────────────────
651
686
 
652
687
  module.exports = async function add(arg) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/sentinel",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"