@ouro.bot/cli 0.1.0-alpha.282 → 0.1.0-alpha.283

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/changelog.json CHANGED
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.283",
6
+ "changes": [
7
+ "chore(housekeeping): clean up ~3600 leaked test secret dirs in `~/.agentsecrets/`. The auth CLI test suite was creating ephemeral agent secret dirs (auth-local-*, auth-store-*, auth-no-switch-*, etc.) without cleaning them up, accreting over weeks into thousands of orphaned entries. Also purged three non-test orphans (`testagent`, `model-reviews`, `config-model-facing-*`) that were leftovers from manual probe sessions. Only `slugger` and `ouroboros` — the two real agents on this machine — remain.",
8
+ "chore(housekeeping): remove orphan bundle stubs from `~/AgentBundles/` (default.ouro, thoughts-test-*, an empty `friends/` dir, and a .DS_Store). These were skeletal test leftovers with no real identity — the daemon was already filtering them out of `listEnabledBundleAgents`, so deletion is invisible to the runtime but stops confusing anyone inspecting the bundles directory.",
9
+ "chore(tests): replace the `outlookServer.stop` v8 ignore band-aid in `daemon.ts` with a proper test. `OuroDaemonOptions` gains an `outlookServerFactory` seam that lets tests inject an in-memory stub handle instead of binding port 6876 (which a running production daemon holds on dev machines, causing EADDRINUSE flakes). New `daemon-outlook-lifecycle.test.ts` covers the happy path (factory runs, stop is called), the error path (factory throws, daemon logs warn and keeps going, stop is a no-op), and the double-start guard. The default production factory path (`createDefaultOutlookServer` — wires the real `startOutlookHttpServer` with bundlesRoot + view builders) is v8-ignored because it only runs under real bind on port 6876; `startOutlookHttpServer` itself has full coverage in `outlook-http.test.ts`. Removed the redundant `if (!this.outlookServer)` wrapper in `startInner()` that was guarding against an unreachable retry scenario. `daemon.ts` now hits 100% statements / branches / functions / lines with zero port binding in the test suite.",
10
+ "chore(ci): tighten the wrapper publish-sync check timing. The version-bump check and wrapper-publish-sync check now run BEFORE the ~2+ minute coverage gate, not after. Previously, a contributor would wait for the full test suite to pass only to then see a 'version already published' error. Now the fast checks surface in under a minute, and coverage only runs once version/wrapper gates have cleared. Same checks, same logic — just reordered steps in `.github/workflows/coverage.yml`."
11
+ ]
12
+ },
4
13
  {
5
14
  "version": "0.1.0-alpha.282",
6
15
  "changes": [
@@ -353,6 +353,7 @@ class OuroDaemon {
353
353
  mode;
354
354
  server = null;
355
355
  outlookServer = null;
356
+ outlookServerFactory;
356
357
  constructor(options) {
357
358
  this.socketPath = options.socketPath;
358
359
  this.processManager = options.processManager;
@@ -362,7 +363,42 @@ class OuroDaemon {
362
363
  this.senseManager = options.senseManager ?? null;
363
364
  this.bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
364
365
  this.mode = options.mode ?? "production";
366
+ this.outlookServerFactory = options.outlookServerFactory ?? this.createDefaultOutlookServer.bind(this);
365
367
  }
368
+ /* v8 ignore start -- default outlook server wiring: production-only path, tests inject outlookServerFactory stub instead. startOutlookHttpServer itself has full coverage in outlook-http.test.ts @preserve */
369
+ createDefaultOutlookServer() {
370
+ return (0, outlook_http_1.startOutlookHttpServer)({
371
+ host: "127.0.0.1",
372
+ port: outlook_types_1.OUTLOOK_DEFAULT_PORT,
373
+ bundlesRoot: this.bundlesRoot,
374
+ readMachineState: () => (0, outlook_read_1.readOutlookMachineState)({ bundlesRoot: this.bundlesRoot }),
375
+ readMachineView: ({ machine }) => {
376
+ const overview = this.buildStatusPayload().overview;
377
+ return (0, outlook_view_1.buildOutlookMachineView)({
378
+ machine,
379
+ daemon: {
380
+ status: overview.daemon,
381
+ health: overview.health,
382
+ mode: overview.mode,
383
+ socketPath: overview.socketPath,
384
+ outlookUrl: overview.outlookUrl,
385
+ entryPath: overview.entryPath,
386
+ workerCount: overview.workerCount,
387
+ senseCount: overview.senseCount,
388
+ },
389
+ });
390
+ },
391
+ readAgentState: (agentName) => (0, outlook_read_1.readOutlookAgentState)(agentName, { bundlesRoot: this.bundlesRoot }),
392
+ readAgentView: (agentName) => {
393
+ const agent = (0, outlook_read_1.readOutlookAgentState)(agentName, { bundlesRoot: this.bundlesRoot });
394
+ return (0, outlook_view_1.buildOutlookAgentView)({
395
+ agent,
396
+ viewer: { kind: "human" },
397
+ });
398
+ },
399
+ });
400
+ }
401
+ /* v8 ignore stop */
366
402
  buildStatusPayload() {
367
403
  const snapshots = this.processManager.listAgentSnapshots();
368
404
  const workers = buildWorkerRows(snapshots);
@@ -513,51 +549,21 @@ class OuroDaemon {
513
549
  await this.scheduler.reconcile?.();
514
550
  await this.drainPendingBundleMessages();
515
551
  await this.drainPendingSenseMessages();
516
- /* v8 ignore start — Outlook server startup, tested via outlook-http.test.ts */
517
- if (!this.outlookServer) {
518
- try {
519
- this.outlookServer = await (0, outlook_http_1.startOutlookHttpServer)({
520
- host: "127.0.0.1",
521
- port: outlook_types_1.OUTLOOK_DEFAULT_PORT,
522
- bundlesRoot: this.bundlesRoot,
523
- readMachineState: () => (0, outlook_read_1.readOutlookMachineState)({ bundlesRoot: this.bundlesRoot }),
524
- readMachineView: ({ machine }) => {
525
- const overview = this.buildStatusPayload().overview;
526
- return (0, outlook_view_1.buildOutlookMachineView)({
527
- machine,
528
- daemon: {
529
- status: overview.daemon,
530
- health: overview.health,
531
- mode: overview.mode,
532
- socketPath: overview.socketPath,
533
- outlookUrl: overview.outlookUrl,
534
- entryPath: overview.entryPath,
535
- workerCount: overview.workerCount,
536
- senseCount: overview.senseCount,
537
- },
538
- });
539
- },
540
- readAgentState: (agentName) => (0, outlook_read_1.readOutlookAgentState)(agentName, { bundlesRoot: this.bundlesRoot }),
541
- readAgentView: (agentName) => {
542
- const agent = (0, outlook_read_1.readOutlookAgentState)(agentName, { bundlesRoot: this.bundlesRoot });
543
- return (0, outlook_view_1.buildOutlookAgentView)({
544
- agent,
545
- viewer: { kind: "human" },
546
- });
547
- },
548
- });
549
- }
550
- catch (error) {
551
- (0, runtime_1.emitNervesEvent)({
552
- level: "warn",
553
- component: "daemon",
554
- event: "daemon.outlook_start_failed",
555
- message: `Outlook server failed to start: ${String(error)}`,
556
- meta: { port: outlook_types_1.OUTLOOK_DEFAULT_PORT },
557
- });
558
- }
552
+ // startInner is only reachable when this.server is null (guarded in
553
+ // start()), and stop() nulls out this.outlookServer alongside this.server,
554
+ // so outlookServer is guaranteed unset here — no need for a guard.
555
+ try {
556
+ this.outlookServer = await this.outlookServerFactory();
557
+ }
558
+ catch (error) {
559
+ (0, runtime_1.emitNervesEvent)({
560
+ level: "warn",
561
+ component: "daemon",
562
+ event: "daemon.outlook_start_failed",
563
+ message: `Outlook server failed to start: ${String(error)}`,
564
+ meta: { port: outlook_types_1.OUTLOOK_DEFAULT_PORT },
565
+ });
559
566
  }
560
- /* v8 ignore stop */
561
567
  if (fs.existsSync(this.socketPath)) {
562
568
  fs.unlinkSync(this.socketPath);
563
569
  }
@@ -815,12 +821,10 @@ class OuroDaemon {
815
821
  this.server.close();
816
822
  this.server = null;
817
823
  }
818
- /* v8 ignore start -- outlookServer stop: only reachable when the outlook HTTP server successfully bound to port 6876 during start(). Coverage fluctuates locally because a running production daemon holds the port and tests get EADDRINUSE, leaving outlookServer null. In CI the port is free and this block runs. Not worth fighting port contention to cover two trivial lines. @preserve */
819
824
  if (this.outlookServer) {
820
825
  await this.outlookServer.stop();
821
826
  this.outlookServer = null;
822
827
  }
823
- /* v8 ignore stop */
824
828
  if (fs.existsSync(this.socketPath)) {
825
829
  fs.unlinkSync(this.socketPath);
826
830
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.282",
3
+ "version": "0.1.0-alpha.283",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",