@poa-box/agent 0.1.0

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.
Files changed (139) hide show
  1. package/.env.agent.template +20 -0
  2. package/README.md +46 -0
  3. package/brain/Config/agent-config.json +14 -0
  4. package/brain/Config/brain-allowlist.json +20 -0
  5. package/brain/Identity/goals.template.md +23 -0
  6. package/brain/Identity/how-i-think.md +406 -0
  7. package/brain/Identity/who-i-am.template.md +34 -0
  8. package/brain/Knowledge/BOOTSTRAP.md +66 -0
  9. package/brain/Knowledge/audit-corpus-index.json +406 -0
  10. package/brain/Knowledge/discussions.json +245 -0
  11. package/brain/Knowledge/pop.brain.brainstorms.generated.md +48 -0
  12. package/brain/Knowledge/pop.brain.brainstorms.genesis.bin +0 -0
  13. package/brain/Knowledge/pop.brain.heuristics.snapshot.bin +0 -0
  14. package/brain/Knowledge/pop.brain.projects.generated.md +16 -0
  15. package/brain/Knowledge/pop.brain.projects.genesis.bin +0 -0
  16. package/brain/Knowledge/pop.brain.retros.generated.md +91 -0
  17. package/brain/Knowledge/pop.brain.retros.genesis.bin +0 -0
  18. package/brain/Knowledge/pop.brain.shared.generated.md +3811 -0
  19. package/brain/Knowledge/pop.brain.shared.genesis.bin +0 -0
  20. package/brain/Knowledge/projects.md +181 -0
  21. package/brain/Knowledge/risk-framework.md +90 -0
  22. package/brain/Knowledge/shared.md +416 -0
  23. package/brain/Knowledge/sprint-priorities.md +439 -0
  24. package/brain/Memory/.gitkeep +0 -0
  25. package/dist/commands/agent/daily-digest.d.ts +24 -0
  26. package/dist/commands/agent/daily-digest.js +336 -0
  27. package/dist/commands/agent/delegate.d.ts +12 -0
  28. package/dist/commands/agent/delegate.js +91 -0
  29. package/dist/commands/agent/deploy-to-org.d.ts +20 -0
  30. package/dist/commands/agent/deploy-to-org.js +154 -0
  31. package/dist/commands/agent/index.d.ts +2 -0
  32. package/dist/commands/agent/index.js +27 -0
  33. package/dist/commands/agent/init.d.ts +19 -0
  34. package/dist/commands/agent/init.js +303 -0
  35. package/dist/commands/agent/onboard.d.ts +22 -0
  36. package/dist/commands/agent/onboard.js +192 -0
  37. package/dist/commands/agent/paymaster-status.d.ts +14 -0
  38. package/dist/commands/agent/paymaster-status.js +130 -0
  39. package/dist/commands/agent/register.d.ts +21 -0
  40. package/dist/commands/agent/register.js +116 -0
  41. package/dist/commands/agent/setup-sponsorship.d.ts +22 -0
  42. package/dist/commands/agent/setup-sponsorship.js +154 -0
  43. package/dist/commands/agent/status.d.ts +12 -0
  44. package/dist/commands/agent/status.js +171 -0
  45. package/dist/commands/agent/triage.d.ts +12 -0
  46. package/dist/commands/agent/triage.js +503 -0
  47. package/dist/commands/brain/advance-stage.d.ts +42 -0
  48. package/dist/commands/brain/advance-stage.js +206 -0
  49. package/dist/commands/brain/allowlist.d.ts +30 -0
  50. package/dist/commands/brain/allowlist.js +274 -0
  51. package/dist/commands/brain/append-lesson.d.ts +55 -0
  52. package/dist/commands/brain/append-lesson.js +245 -0
  53. package/dist/commands/brain/brainstorm.d.ts +154 -0
  54. package/dist/commands/brain/brainstorm.js +573 -0
  55. package/dist/commands/brain/daemon.d.ts +31 -0
  56. package/dist/commands/brain/daemon.js +348 -0
  57. package/dist/commands/brain/doctor.d.ts +27 -0
  58. package/dist/commands/brain/doctor.js +497 -0
  59. package/dist/commands/brain/edit-lesson.d.ts +51 -0
  60. package/dist/commands/brain/edit-lesson.js +248 -0
  61. package/dist/commands/brain/import-snapshot.d.ts +68 -0
  62. package/dist/commands/brain/import-snapshot.js +177 -0
  63. package/dist/commands/brain/index.d.ts +2 -0
  64. package/dist/commands/brain/index.js +67 -0
  65. package/dist/commands/brain/list.d.ts +21 -0
  66. package/dist/commands/brain/list.js +83 -0
  67. package/dist/commands/brain/migrate-projects.d.ts +44 -0
  68. package/dist/commands/brain/migrate-projects.js +209 -0
  69. package/dist/commands/brain/migrate.d.ts +74 -0
  70. package/dist/commands/brain/migrate.js +306 -0
  71. package/dist/commands/brain/new-project.d.ts +53 -0
  72. package/dist/commands/brain/new-project.js +226 -0
  73. package/dist/commands/brain/read.d.ts +24 -0
  74. package/dist/commands/brain/read.js +81 -0
  75. package/dist/commands/brain/remove-lesson.d.ts +47 -0
  76. package/dist/commands/brain/remove-lesson.js +206 -0
  77. package/dist/commands/brain/remove-project.d.ts +36 -0
  78. package/dist/commands/brain/remove-project.js +177 -0
  79. package/dist/commands/brain/retro-file-tasks.d.ts +84 -0
  80. package/dist/commands/brain/retro-file-tasks.js +372 -0
  81. package/dist/commands/brain/retro-list.d.ts +28 -0
  82. package/dist/commands/brain/retro-list.js +125 -0
  83. package/dist/commands/brain/retro-mark-change.d.ts +58 -0
  84. package/dist/commands/brain/retro-mark-change.js +176 -0
  85. package/dist/commands/brain/retro-remove.d.ts +36 -0
  86. package/dist/commands/brain/retro-remove.js +142 -0
  87. package/dist/commands/brain/retro-respond.d.ts +56 -0
  88. package/dist/commands/brain/retro-respond.js +250 -0
  89. package/dist/commands/brain/retro-show.d.ts +23 -0
  90. package/dist/commands/brain/retro-show.js +100 -0
  91. package/dist/commands/brain/retro-start.d.ts +55 -0
  92. package/dist/commands/brain/retro-start.js +311 -0
  93. package/dist/commands/brain/search.d.ts +48 -0
  94. package/dist/commands/brain/search.js +190 -0
  95. package/dist/commands/brain/snapshot.d.ts +32 -0
  96. package/dist/commands/brain/snapshot.js +243 -0
  97. package/dist/commands/brain/status.d.ts +15 -0
  98. package/dist/commands/brain/status.js +166 -0
  99. package/dist/commands/brain/subscribe.d.ts +28 -0
  100. package/dist/commands/brain/subscribe.js +90 -0
  101. package/dist/commands/brain/tag.d.ts +46 -0
  102. package/dist/commands/brain/tag.js +192 -0
  103. package/dist/index.d.ts +17 -0
  104. package/dist/index.js +22 -0
  105. package/dist/lib/brain-daemon.d.ts +126 -0
  106. package/dist/lib/brain-daemon.js +811 -0
  107. package/dist/lib/brain-membership.d.ts +58 -0
  108. package/dist/lib/brain-membership.js +115 -0
  109. package/dist/lib/brain-migrate-projects.d.ts +43 -0
  110. package/dist/lib/brain-migrate-projects.js +247 -0
  111. package/dist/lib/brain-migrate.d.ts +77 -0
  112. package/dist/lib/brain-migrate.js +328 -0
  113. package/dist/lib/brain-ops.d.ts +271 -0
  114. package/dist/lib/brain-ops.js +571 -0
  115. package/dist/lib/brain-paths.d.ts +15 -0
  116. package/dist/lib/brain-paths.js +33 -0
  117. package/dist/lib/brain-projections.d.ts +216 -0
  118. package/dist/lib/brain-projections.js +829 -0
  119. package/dist/lib/brain-schemas.d.ts +36 -0
  120. package/dist/lib/brain-schemas.js +316 -0
  121. package/dist/lib/brain-signing.d.ts +103 -0
  122. package/dist/lib/brain-signing.js +256 -0
  123. package/dist/lib/brain.d.ts +198 -0
  124. package/dist/lib/brain.js +1057 -0
  125. package/dist/pop-agent.d.ts +1 -0
  126. package/dist/pop-agent.js +18 -0
  127. package/docs/agent.md +126 -0
  128. package/docs/agents/brain-anti-entropy.md +127 -0
  129. package/docs/agents/brain-cross-device-onboarding.md +210 -0
  130. package/docs/agents/brain-cross-machine-smoke.md +241 -0
  131. package/docs/agents/brain-layer-setup.md +725 -0
  132. package/docs/agents/offboarding-protocol.md +188 -0
  133. package/docs/agents/onboarding-protocol.md +243 -0
  134. package/docs/agents/running-an-agent.md +200 -0
  135. package/docs/brain.md +560 -0
  136. package/package.json +61 -0
  137. package/scripts/apply.sh +140 -0
  138. package/scripts/onboard.sh +205 -0
  139. package/scripts/setup-agent.ts +272 -0
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ /**
3
+ * pop brain daemon — process control for the persistent brain daemon
4
+ * (HB#322 architecture: go-ds-crdt-shaped rebroadcast + keepalive loop,
5
+ * see src/lib/brain-daemon.ts for the full design rationale).
6
+ *
7
+ * Subcommands:
8
+ * start spawn a detached daemon child
9
+ * stop signal a running daemon to shut down gracefully
10
+ * status print daemon stats (peer count, topics, uptime, rebroadcast
11
+ * counts) via IPC
12
+ * logs tail the daemon log file
13
+ * __run internal — the actual daemon entrypoint. Never call directly
14
+ * from the shell; start uses this.
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.daemonHandler = void 0;
51
+ const child_process_1 = require("child_process");
52
+ const fs_1 = require("fs");
53
+ const brain_daemon_1 = require("../../lib/brain-daemon");
54
+ const brain_1 = require("../../lib/brain");
55
+ const output = __importStar(require("@poa-box/cli/lib/output"));
56
+ async function handleStart() {
57
+ const existing = (0, brain_daemon_1.getRunningDaemonPid)();
58
+ if (existing !== null) {
59
+ if (output.isJsonMode()) {
60
+ output.json({
61
+ status: 'already-running',
62
+ pid: existing,
63
+ pidPath: (0, brain_daemon_1.getDaemonPidPath)(),
64
+ });
65
+ }
66
+ else {
67
+ console.log(`Brain daemon already running with PID ${existing}`);
68
+ console.log(` pid file: ${(0, brain_daemon_1.getDaemonPidPath)()}`);
69
+ console.log(` socket: ${(0, brain_daemon_1.getDaemonSockPath)()}`);
70
+ console.log(` log: ${(0, brain_daemon_1.getDaemonLogPath)()}`);
71
+ }
72
+ return;
73
+ }
74
+ // Determine the path to our own CLI entrypoint so the detached child
75
+ // can run the __run subcommand. We use process.argv[1] when it points
76
+ // at dist/index.js, else fall back to the canonical path.
77
+ const selfScript = process.argv[1];
78
+ const child = (0, child_process_1.spawn)(process.execPath, // node itself
79
+ [selfScript, 'brain', 'daemon', '__run'], {
80
+ detached: true,
81
+ stdio: 'ignore',
82
+ // Forward critical env so the child has the same wallet / brain home.
83
+ env: process.env,
84
+ });
85
+ child.unref();
86
+ // Poll the PID file for up to 5s to confirm the daemon actually came up.
87
+ // Without this the user gets "started" for a process that crashed at init.
88
+ const pidPath = (0, brain_daemon_1.getDaemonPidPath)();
89
+ const startedAt = Date.now();
90
+ let pid = null;
91
+ while (Date.now() - startedAt < 5000) {
92
+ if ((0, fs_1.existsSync)(pidPath)) {
93
+ try {
94
+ pid = parseInt((0, fs_1.readFileSync)(pidPath, 'utf8').trim(), 10);
95
+ if (Number.isFinite(pid) && pid > 0)
96
+ break;
97
+ }
98
+ catch { }
99
+ }
100
+ await new Promise(r => setTimeout(r, 100));
101
+ }
102
+ if (!pid) {
103
+ if (output.isJsonMode()) {
104
+ output.json({
105
+ status: 'error',
106
+ reason: 'daemon did not write PID file within 5s — check log',
107
+ logPath: (0, brain_daemon_1.getDaemonLogPath)(),
108
+ });
109
+ }
110
+ else {
111
+ console.error(`Brain daemon failed to start within 5s.`);
112
+ console.error(`Check the log: ${(0, brain_daemon_1.getDaemonLogPath)()}`);
113
+ }
114
+ process.exitCode = 1;
115
+ return;
116
+ }
117
+ if (output.isJsonMode()) {
118
+ output.json({
119
+ status: 'started',
120
+ pid,
121
+ pidPath,
122
+ sockPath: (0, brain_daemon_1.getDaemonSockPath)(),
123
+ logPath: (0, brain_daemon_1.getDaemonLogPath)(),
124
+ rebroadcastIntervalMs: brain_daemon_1.REBROADCAST_INTERVAL_MS,
125
+ keepaliveIntervalMs: brain_daemon_1.KEEPALIVE_INTERVAL_MS,
126
+ });
127
+ }
128
+ else {
129
+ console.log(`Brain daemon started`);
130
+ console.log(` PID: ${pid}`);
131
+ console.log(` brain home: ${(0, brain_1.getBrainHome)()}`);
132
+ console.log(` pid file: ${pidPath}`);
133
+ console.log(` socket: ${(0, brain_daemon_1.getDaemonSockPath)()}`);
134
+ console.log(` log: ${(0, brain_daemon_1.getDaemonLogPath)()}`);
135
+ console.log(` rebroadcast: ${brain_daemon_1.REBROADCAST_INTERVAL_MS / 1000}s`);
136
+ console.log(` keepalive: ${brain_daemon_1.KEEPALIVE_INTERVAL_MS / 1000}s`);
137
+ console.log(``);
138
+ console.log(`Verify with: pop brain daemon status`);
139
+ }
140
+ }
141
+ async function handleStop() {
142
+ const pid = (0, brain_daemon_1.getRunningDaemonPid)();
143
+ if (pid === null) {
144
+ if (output.isJsonMode()) {
145
+ output.json({ status: 'not-running' });
146
+ }
147
+ else {
148
+ console.log('Brain daemon is not running.');
149
+ }
150
+ return;
151
+ }
152
+ try {
153
+ process.kill(pid, 'SIGTERM');
154
+ }
155
+ catch (err) {
156
+ if (output.isJsonMode()) {
157
+ output.json({ status: 'error', reason: err.message, pid });
158
+ }
159
+ else {
160
+ console.error(`Failed to signal PID ${pid}: ${err.message}`);
161
+ }
162
+ process.exitCode = 1;
163
+ return;
164
+ }
165
+ // Wait up to 10s for the PID file to disappear (daemon's own cleanup).
166
+ const started = Date.now();
167
+ while (Date.now() - started < 10_000) {
168
+ if ((0, brain_daemon_1.getRunningDaemonPid)() === null)
169
+ break;
170
+ await new Promise(r => setTimeout(r, 100));
171
+ }
172
+ const stillRunning = (0, brain_daemon_1.getRunningDaemonPid)();
173
+ if (stillRunning !== null) {
174
+ if (output.isJsonMode()) {
175
+ output.json({
176
+ status: 'error',
177
+ reason: `daemon still running after SIGTERM + 10s — may need SIGKILL`,
178
+ pid: stillRunning,
179
+ });
180
+ }
181
+ else {
182
+ console.error(`Daemon still running after SIGTERM + 10s (PID ${stillRunning}).`);
183
+ console.error(`Force-kill with: kill -9 ${stillRunning}`);
184
+ }
185
+ process.exitCode = 1;
186
+ return;
187
+ }
188
+ if (output.isJsonMode()) {
189
+ output.json({ status: 'stopped', pid });
190
+ }
191
+ else {
192
+ console.log(`Brain daemon stopped (was PID ${pid}).`);
193
+ }
194
+ }
195
+ async function handleStatus() {
196
+ const pid = (0, brain_daemon_1.getRunningDaemonPid)();
197
+ if (pid === null) {
198
+ if (output.isJsonMode()) {
199
+ output.json({ status: 'not-running' });
200
+ }
201
+ else {
202
+ console.log('Brain daemon is not running.');
203
+ console.log('Start it with: pop brain daemon start');
204
+ }
205
+ return;
206
+ }
207
+ let ipcResult;
208
+ try {
209
+ ipcResult = await (0, brain_daemon_1.sendIpcRequest)('status', {}, 3000);
210
+ }
211
+ catch (err) {
212
+ if (output.isJsonMode()) {
213
+ output.json({
214
+ status: 'ipc-error',
215
+ pid,
216
+ reason: err.message,
217
+ });
218
+ }
219
+ else {
220
+ console.error(`Daemon PID ${pid} is alive but IPC failed: ${err.message}`);
221
+ console.error(`Check log: ${(0, brain_daemon_1.getDaemonLogPath)()}`);
222
+ }
223
+ process.exitCode = 1;
224
+ return;
225
+ }
226
+ if (output.isJsonMode()) {
227
+ output.json({
228
+ status: 'running',
229
+ pid,
230
+ ...ipcResult,
231
+ });
232
+ return;
233
+ }
234
+ const lastRebroadcast = ipcResult.lastRebroadcastAt
235
+ ? new Date(ipcResult.lastRebroadcastAt).toISOString()
236
+ : 'never';
237
+ const lastKeepalive = ipcResult.lastKeepaliveAt
238
+ ? new Date(ipcResult.lastKeepaliveAt).toISOString()
239
+ : 'never';
240
+ console.log(`Brain daemon running`);
241
+ console.log(` PID: ${pid}`);
242
+ console.log(` peer ID: ${ipcResult.peerId}`);
243
+ console.log(` uptime: ${ipcResult.uptime}s`);
244
+ console.log(` connections: ${ipcResult.connections}`);
245
+ console.log(` known peers: ${ipcResult.knownPeerCount}`);
246
+ console.log(` subscribed topics: ${ipcResult.topics?.length ?? 0}`);
247
+ if (ipcResult.topics?.length) {
248
+ for (const t of ipcResult.topics) {
249
+ console.log(` - ${t}`);
250
+ }
251
+ }
252
+ console.log(` subscribed docs: ${ipcResult.subscribedDocs?.length ?? 0}`);
253
+ if (ipcResult.subscribedDocs?.length) {
254
+ for (const d of ipcResult.subscribedDocs) {
255
+ console.log(` - ${d}`);
256
+ }
257
+ }
258
+ console.log(` rebroadcast count: ${ipcResult.rebroadcastCount}`);
259
+ console.log(` last rebroadcast: ${lastRebroadcast}`);
260
+ console.log(` keepalive count: ${ipcResult.keepaliveCount}`);
261
+ console.log(` last keepalive: ${lastKeepalive}`);
262
+ console.log(` incoming announces: ${ipcResult.incomingAnnouncements}`);
263
+ console.log(` incoming merges: ${ipcResult.incomingMerges}`);
264
+ console.log(` incoming rejects: ${ipcResult.incomingRejects || 0}`);
265
+ console.log(` brain home: ${ipcResult.brainHome}`);
266
+ console.log(` log: ${ipcResult.logPath}`);
267
+ }
268
+ async function handleLogs(tail, follow) {
269
+ const logPath = (0, brain_daemon_1.getDaemonLogPath)();
270
+ if (!(0, fs_1.existsSync)(logPath)) {
271
+ console.error(`No daemon log at ${logPath}`);
272
+ process.exitCode = 1;
273
+ return;
274
+ }
275
+ // Minimal implementation: print last N lines. --follow uses tail -F.
276
+ if (follow) {
277
+ const { spawn: spawnFollow } = await Promise.resolve().then(() => __importStar(require('child_process')));
278
+ const proc = spawnFollow('tail', ['-F', '-n', String(tail), logPath], {
279
+ stdio: 'inherit',
280
+ });
281
+ await new Promise(r => proc.on('close', r));
282
+ return;
283
+ }
284
+ const content = (0, fs_1.readFileSync)(logPath, 'utf8');
285
+ const lines = content.split('\n');
286
+ const slice = lines.slice(Math.max(0, lines.length - tail - 1));
287
+ console.log(slice.join('\n'));
288
+ }
289
+ async function handleRun() {
290
+ // This is the child process entrypoint. It blocks forever.
291
+ try {
292
+ await (0, brain_daemon_1.runDaemon)();
293
+ }
294
+ catch (err) {
295
+ // Write the error to the log file if we can; the parent process
296
+ // watches the PID file to detect failures.
297
+ const logPath = (0, brain_daemon_1.getDaemonLogPath)();
298
+ try {
299
+ const { appendFileSync } = await Promise.resolve().then(() => __importStar(require('fs')));
300
+ appendFileSync(logPath, `${new Date().toISOString()} FATAL ${err.stack ?? err.message}\n`);
301
+ }
302
+ catch { }
303
+ process.exit(1);
304
+ }
305
+ }
306
+ exports.daemonHandler = {
307
+ builder: (yargs) => yargs
308
+ .positional('action', {
309
+ describe: 'Daemon action',
310
+ type: 'string',
311
+ choices: ['start', 'stop', 'status', 'logs', '__run'],
312
+ })
313
+ .option('follow', {
314
+ alias: 'f',
315
+ describe: 'Follow the log file (logs subcommand only)',
316
+ type: 'boolean',
317
+ default: false,
318
+ })
319
+ .option('tail', {
320
+ alias: 'n',
321
+ describe: 'Number of log lines to print (logs subcommand only)',
322
+ type: 'number',
323
+ default: 50,
324
+ }),
325
+ handler: async (argv) => {
326
+ const action = argv.action;
327
+ switch (action) {
328
+ case 'start':
329
+ await handleStart();
330
+ return;
331
+ case 'stop':
332
+ await handleStop();
333
+ return;
334
+ case 'status':
335
+ await handleStatus();
336
+ return;
337
+ case 'logs':
338
+ await handleLogs(argv.tail ?? 50, argv.follow ?? false);
339
+ return;
340
+ case '__run':
341
+ await handleRun();
342
+ return;
343
+ default:
344
+ output.error(`Unknown daemon action: ${action}`);
345
+ process.exitCode = 1;
346
+ }
347
+ },
348
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * pop brain doctor — single-command health check for brain layer setup.
3
+ *
4
+ * Answers "is my brain setup healthy?" in one invocation. Complements
5
+ * `docs/agents/brain-layer-setup.md` (setup doc tells you HOW; doctor tells
6
+ * you IF the setup is actually working).
7
+ *
8
+ * Output shape:
9
+ * ✓ check name — pass
10
+ * ⚠ check name — warn (not fatal, but worth knowing)
11
+ * ✗ check name — fail (exit 1)
12
+ *
13
+ * Exit codes:
14
+ * 0 — all pass or pass+warn (warnings don't fail the run)
15
+ * 1 — any ✗ fail
16
+ *
17
+ * --json returns { checks: [{name, status, detail, elapsed?}], summary }
18
+ *
19
+ * Design: every check is self-contained and independent. A failure in
20
+ * one check does NOT stop later checks from running — the operator
21
+ * wants the full picture, not the first stumble.
22
+ */
23
+ import type { Argv, ArgumentsCamelCase } from 'yargs';
24
+ export declare const doctorHandler: {
25
+ builder: (yargs: Argv) => Argv<{}>;
26
+ handler: (_argv: ArgumentsCamelCase<{}>) => Promise<void>;
27
+ };