@a5c-ai/babysitter-sdk 0.0.168 → 0.0.170-staging.00aac85c
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/dist/cli/commands/configure.d.ts +124 -0
- package/dist/cli/commands/configure.d.ts.map +1 -0
- package/dist/cli/commands/configure.js +514 -0
- package/dist/cli/commands/health.d.ts +89 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +579 -0
- package/dist/cli/commands/hookLog.d.ts +15 -0
- package/dist/cli/commands/hookLog.d.ts.map +1 -0
- package/dist/cli/commands/hookLog.js +286 -0
- package/dist/cli/commands/hookRun.d.ts +20 -0
- package/dist/cli/commands/hookRun.d.ts.map +1 -0
- package/dist/cli/commands/hookRun.js +544 -0
- package/dist/cli/commands/runExecuteTasks.d.ts +42 -0
- package/dist/cli/commands/runExecuteTasks.d.ts.map +1 -0
- package/dist/cli/commands/runExecuteTasks.js +377 -0
- package/dist/cli/commands/runIterate.d.ts +5 -1
- package/dist/cli/commands/runIterate.d.ts.map +1 -1
- package/dist/cli/commands/runIterate.js +75 -6
- package/dist/cli/commands/session.d.ts +97 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +922 -0
- package/dist/cli/commands/skill.d.ts +87 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +869 -0
- package/dist/cli/completionProof.d.ts +4 -0
- package/dist/cli/completionProof.d.ts.map +1 -0
- package/dist/cli/{completionSecret.js → completionProof.js} +7 -7
- package/dist/cli/main.d.ts +14 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +649 -16
- package/dist/config/defaults.d.ts +165 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +281 -0
- package/dist/config/index.d.ts +25 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +35 -0
- package/dist/hooks/dispatcher.d.ts.map +1 -1
- package/dist/hooks/dispatcher.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/runtime/constants.d.ts +1 -1
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/createRun.d.ts.map +1 -1
- package/dist/runtime/createRun.js +7 -3
- package/dist/runtime/exceptions.d.ts +186 -3
- package/dist/runtime/exceptions.d.ts.map +1 -1
- package/dist/runtime/exceptions.js +416 -15
- package/dist/runtime/types.d.ts +1 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/session/index.d.ts +9 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +30 -0
- package/dist/session/parse.d.ts +45 -0
- package/dist/session/parse.d.ts.map +1 -0
- package/dist/session/parse.js +159 -0
- package/dist/session/types.d.ts +194 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +45 -0
- package/dist/session/write.d.ts +50 -0
- package/dist/session/write.d.ts.map +1 -0
- package/dist/session/write.js +196 -0
- package/dist/storage/createRunDir.d.ts.map +1 -1
- package/dist/storage/createRunDir.js +1 -0
- package/dist/storage/paths.d.ts +5 -1
- package/dist/storage/paths.d.ts.map +1 -1
- package/dist/storage/paths.js +6 -1
- package/dist/storage/types.d.ts +3 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/tasks/kinds/index.d.ts.map +1 -1
- package/dist/tasks/kinds/index.js +6 -1
- package/dist/testing/runHarness.d.ts.map +1 -1
- package/dist/testing/runHarness.js +5 -1
- package/package.json +1 -2
- package/dist/cli/completionSecret.d.ts +0 -4
- package/dist/cli/completionSecret.d.ts.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* health command - Verify SDK installation and environment health
|
|
3
|
+
*
|
|
4
|
+
* This command performs diagnostic checks to verify:
|
|
5
|
+
* - SDK CLI is properly installed and version is accessible
|
|
6
|
+
* - .a5c directory exists and is writable
|
|
7
|
+
* - Node.js version is compatible (>=18)
|
|
8
|
+
* - Package.json has babysitter-sdk dependency if in project context
|
|
9
|
+
* - Environment variables are set correctly
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Status of an individual health check
|
|
13
|
+
*/
|
|
14
|
+
export type CheckStatus = "pass" | "fail" | "warn";
|
|
15
|
+
/**
|
|
16
|
+
* Result of a single health check
|
|
17
|
+
*/
|
|
18
|
+
export interface HealthCheck {
|
|
19
|
+
/** Name of the check */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Human-readable description of what was checked */
|
|
22
|
+
description: string;
|
|
23
|
+
/** Status of the check */
|
|
24
|
+
status: CheckStatus;
|
|
25
|
+
/** Detailed message about the result */
|
|
26
|
+
message: string;
|
|
27
|
+
/** Suggested next steps if the check failed or warned */
|
|
28
|
+
nextSteps?: string[];
|
|
29
|
+
/** Additional diagnostic details */
|
|
30
|
+
details?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for running health checks
|
|
34
|
+
*/
|
|
35
|
+
export interface HealthCheckOptions {
|
|
36
|
+
/** Output in JSON format for machine consumption */
|
|
37
|
+
json?: boolean;
|
|
38
|
+
/** Include verbose diagnostic information */
|
|
39
|
+
verbose?: boolean;
|
|
40
|
+
/** Working directory to check (defaults to cwd) */
|
|
41
|
+
cwd?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Overall health check result
|
|
45
|
+
*/
|
|
46
|
+
export interface HealthCheckResult {
|
|
47
|
+
/** Overall health status */
|
|
48
|
+
status: "healthy" | "degraded" | "unhealthy";
|
|
49
|
+
/** Timestamp of the health check */
|
|
50
|
+
timestamp: string;
|
|
51
|
+
/** Individual check results */
|
|
52
|
+
checks: HealthCheck[];
|
|
53
|
+
/** Summary counts */
|
|
54
|
+
summary: {
|
|
55
|
+
total: number;
|
|
56
|
+
passed: number;
|
|
57
|
+
failed: number;
|
|
58
|
+
warnings: number;
|
|
59
|
+
};
|
|
60
|
+
/** Aggregated next steps from all failing checks */
|
|
61
|
+
nextSteps: string[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Runs all health checks and returns aggregated results
|
|
65
|
+
*
|
|
66
|
+
* @param options - Health check options
|
|
67
|
+
* @returns Complete health check result
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* // Run health checks with default options
|
|
72
|
+
* const result = await runHealthCheck({});
|
|
73
|
+
*
|
|
74
|
+
* // Run with verbose output
|
|
75
|
+
* const result = await runHealthCheck({ verbose: true });
|
|
76
|
+
*
|
|
77
|
+
* // Get JSON output
|
|
78
|
+
* const result = await runHealthCheck({ json: true });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function runHealthCheck(options: HealthCheckOptions): Promise<HealthCheckResult>;
|
|
82
|
+
/**
|
|
83
|
+
* CLI entry point for the health command
|
|
84
|
+
*
|
|
85
|
+
* @param options - Parsed CLI options
|
|
86
|
+
* @returns Exit code (0 for healthy, 1 for unhealthy)
|
|
87
|
+
*/
|
|
88
|
+
export declare function handleHealthCommand(options: HealthCheckOptions): Promise<number>;
|
|
89
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,qBAAqB;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,oDAAoD;IACpD,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAyaD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkD5F;AA2ED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBtF"}
|
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* health command - Verify SDK installation and environment health
|
|
4
|
+
*
|
|
5
|
+
* This command performs diagnostic checks to verify:
|
|
6
|
+
* - SDK CLI is properly installed and version is accessible
|
|
7
|
+
* - .a5c directory exists and is writable
|
|
8
|
+
* - Node.js version is compatible (>=18)
|
|
9
|
+
* - Package.json has babysitter-sdk dependency if in project context
|
|
10
|
+
* - Environment variables are set correctly
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.runHealthCheck = runHealthCheck;
|
|
47
|
+
exports.handleHealthCommand = handleHealthCommand;
|
|
48
|
+
const node_fs_1 = require("node:fs");
|
|
49
|
+
const path = __importStar(require("node:path"));
|
|
50
|
+
const defaults_1 = require("../../config/defaults");
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Color Utilities
|
|
53
|
+
// ============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* ANSI color codes for terminal output
|
|
56
|
+
*/
|
|
57
|
+
const COLORS = {
|
|
58
|
+
reset: "\x1b[0m",
|
|
59
|
+
green: "\x1b[32m",
|
|
60
|
+
red: "\x1b[31m",
|
|
61
|
+
yellow: "\x1b[33m",
|
|
62
|
+
cyan: "\x1b[36m",
|
|
63
|
+
dim: "\x1b[2m",
|
|
64
|
+
bold: "\x1b[1m",
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Check symbols with colors
|
|
68
|
+
*/
|
|
69
|
+
const SYMBOLS = {
|
|
70
|
+
pass: `${COLORS.green}\u2713${COLORS.reset}`,
|
|
71
|
+
fail: `${COLORS.red}\u2717${COLORS.reset}`,
|
|
72
|
+
warn: `${COLORS.yellow}\u26A0${COLORS.reset}`,
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Plain symbols without colors (for non-TTY output)
|
|
76
|
+
*/
|
|
77
|
+
const PLAIN_SYMBOLS = {
|
|
78
|
+
pass: "[PASS]",
|
|
79
|
+
fail: "[FAIL]",
|
|
80
|
+
warn: "[WARN]",
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Checks if stdout supports colors
|
|
84
|
+
*/
|
|
85
|
+
function supportsColors() {
|
|
86
|
+
if (process.env.NO_COLOR !== undefined) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (process.env.FORCE_COLOR !== undefined) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
if (process.stdout && typeof process.stdout.isTTY === "boolean") {
|
|
93
|
+
return process.stdout.isTTY;
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get the appropriate symbol for a check status
|
|
99
|
+
*/
|
|
100
|
+
function getSymbol(status, useColors) {
|
|
101
|
+
return useColors ? SYMBOLS[status] : PLAIN_SYMBOLS[status];
|
|
102
|
+
}
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// Version Utilities
|
|
105
|
+
// ============================================================================
|
|
106
|
+
/**
|
|
107
|
+
* Reads the CLI version from package.json
|
|
108
|
+
*/
|
|
109
|
+
async function readCliVersion() {
|
|
110
|
+
try {
|
|
111
|
+
const packagePath = path.join(__dirname, "..", "..", "..", "package.json");
|
|
112
|
+
const raw = await node_fs_1.promises.readFile(packagePath, "utf8");
|
|
113
|
+
const parsed = JSON.parse(raw);
|
|
114
|
+
return parsed.version ?? "unknown";
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return "unknown";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Parses a semver version string into components
|
|
122
|
+
*/
|
|
123
|
+
function parseVersion(version) {
|
|
124
|
+
const match = version.match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
125
|
+
if (!match)
|
|
126
|
+
return null;
|
|
127
|
+
return {
|
|
128
|
+
major: parseInt(match[1], 10),
|
|
129
|
+
minor: parseInt(match[2], 10),
|
|
130
|
+
patch: parseInt(match[3], 10),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// Individual Health Checks
|
|
135
|
+
// ============================================================================
|
|
136
|
+
/**
|
|
137
|
+
* Check: SDK CLI Version
|
|
138
|
+
* Verifies the SDK CLI is installed and version is accessible
|
|
139
|
+
*/
|
|
140
|
+
async function checkSdkVersion() {
|
|
141
|
+
const version = await readCliVersion();
|
|
142
|
+
if (version === "unknown") {
|
|
143
|
+
return {
|
|
144
|
+
name: "sdk-version",
|
|
145
|
+
description: "SDK CLI version is accessible",
|
|
146
|
+
status: "fail",
|
|
147
|
+
message: "Unable to read SDK version from package.json",
|
|
148
|
+
nextSteps: [
|
|
149
|
+
"Ensure @a5c-ai/babysitter-sdk is properly installed",
|
|
150
|
+
"Run: npm install @a5c-ai/babysitter-sdk",
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
name: "sdk-version",
|
|
156
|
+
description: "SDK CLI version is accessible",
|
|
157
|
+
status: "pass",
|
|
158
|
+
message: `SDK version ${version}`,
|
|
159
|
+
details: { version },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check: Node.js Version
|
|
164
|
+
* Verifies Node.js version is compatible (>=18)
|
|
165
|
+
*/
|
|
166
|
+
function checkNodeVersion() {
|
|
167
|
+
const nodeVersion = process.version;
|
|
168
|
+
const parsed = parseVersion(nodeVersion);
|
|
169
|
+
if (!parsed) {
|
|
170
|
+
return {
|
|
171
|
+
name: "node-version",
|
|
172
|
+
description: "Node.js version is compatible (>=18)",
|
|
173
|
+
status: "warn",
|
|
174
|
+
message: `Unable to parse Node.js version: ${nodeVersion}`,
|
|
175
|
+
nextSteps: ["Verify Node.js is properly installed"],
|
|
176
|
+
details: { version: nodeVersion },
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const minMajor = 18;
|
|
180
|
+
if (parsed.major < minMajor) {
|
|
181
|
+
return {
|
|
182
|
+
name: "node-version",
|
|
183
|
+
description: "Node.js version is compatible (>=18)",
|
|
184
|
+
status: "fail",
|
|
185
|
+
message: `Node.js ${nodeVersion} is below minimum required version (v${minMajor}.0.0)`,
|
|
186
|
+
nextSteps: [
|
|
187
|
+
`Upgrade Node.js to version ${minMajor} or higher`,
|
|
188
|
+
"Visit https://nodejs.org to download the latest LTS version",
|
|
189
|
+
"Consider using nvm or fnm for version management",
|
|
190
|
+
],
|
|
191
|
+
details: { version: nodeVersion, required: `>=${minMajor}.0.0` },
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
name: "node-version",
|
|
196
|
+
description: "Node.js version is compatible (>=18)",
|
|
197
|
+
status: "pass",
|
|
198
|
+
message: `Node.js ${nodeVersion}`,
|
|
199
|
+
details: { version: nodeVersion, major: parsed.major },
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check: .a5c Directory
|
|
204
|
+
* Verifies the .a5c directory exists and is writable
|
|
205
|
+
*/
|
|
206
|
+
async function checkA5cDirectory(cwd) {
|
|
207
|
+
const a5cDir = path.join(cwd, ".a5c");
|
|
208
|
+
const runsDir = path.join(a5cDir, "runs");
|
|
209
|
+
try {
|
|
210
|
+
const stats = await node_fs_1.promises.stat(a5cDir);
|
|
211
|
+
if (!stats.isDirectory()) {
|
|
212
|
+
return {
|
|
213
|
+
name: "a5c-directory",
|
|
214
|
+
description: ".a5c directory exists and is writable",
|
|
215
|
+
status: "fail",
|
|
216
|
+
message: `.a5c exists but is not a directory at ${a5cDir}`,
|
|
217
|
+
nextSteps: [
|
|
218
|
+
"Remove the .a5c file and let the SDK create the directory",
|
|
219
|
+
"Or run: rm .a5c && mkdir -p .a5c/runs",
|
|
220
|
+
],
|
|
221
|
+
details: { path: a5cDir, isDirectory: false },
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// Check if writable by attempting to write a test file
|
|
225
|
+
const testFile = path.join(a5cDir, ".health-check-test");
|
|
226
|
+
try {
|
|
227
|
+
await node_fs_1.promises.writeFile(testFile, "test", "utf8");
|
|
228
|
+
await node_fs_1.promises.unlink(testFile);
|
|
229
|
+
}
|
|
230
|
+
catch (writeError) {
|
|
231
|
+
return {
|
|
232
|
+
name: "a5c-directory",
|
|
233
|
+
description: ".a5c directory exists and is writable",
|
|
234
|
+
status: "fail",
|
|
235
|
+
message: `.a5c directory exists but is not writable at ${a5cDir}`,
|
|
236
|
+
nextSteps: [
|
|
237
|
+
"Check file permissions on the .a5c directory",
|
|
238
|
+
"Run: chmod 755 .a5c",
|
|
239
|
+
],
|
|
240
|
+
details: { path: a5cDir, writable: false },
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
// Check if runs subdirectory exists
|
|
244
|
+
let runsExists = false;
|
|
245
|
+
try {
|
|
246
|
+
const runsStats = await node_fs_1.promises.stat(runsDir);
|
|
247
|
+
runsExists = runsStats.isDirectory();
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// runs dir doesn't exist yet, that's okay
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
name: "a5c-directory",
|
|
254
|
+
description: ".a5c directory exists and is writable",
|
|
255
|
+
status: "pass",
|
|
256
|
+
message: `.a5c directory is ready at ${a5cDir}`,
|
|
257
|
+
details: { path: a5cDir, runsDir, runsExists, writable: true },
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
const err = error;
|
|
262
|
+
if (err.code === "ENOENT") {
|
|
263
|
+
return {
|
|
264
|
+
name: "a5c-directory",
|
|
265
|
+
description: ".a5c directory exists and is writable",
|
|
266
|
+
status: "warn",
|
|
267
|
+
message: `.a5c directory does not exist at ${a5cDir}`,
|
|
268
|
+
nextSteps: [
|
|
269
|
+
"The directory will be created automatically when running babysitter commands",
|
|
270
|
+
"Or create it manually: mkdir -p .a5c/runs",
|
|
271
|
+
],
|
|
272
|
+
details: { path: a5cDir, exists: false },
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
name: "a5c-directory",
|
|
277
|
+
description: ".a5c directory exists and is writable",
|
|
278
|
+
status: "fail",
|
|
279
|
+
message: `Error accessing .a5c directory: ${err.message}`,
|
|
280
|
+
nextSteps: ["Check file system permissions and disk space"],
|
|
281
|
+
details: { path: a5cDir, error: err.message },
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Check: Package.json Dependency
|
|
287
|
+
* Verifies babysitter-sdk is listed as a dependency in the project
|
|
288
|
+
*/
|
|
289
|
+
async function checkPackageDependency(cwd) {
|
|
290
|
+
const packagePath = path.join(cwd, "package.json");
|
|
291
|
+
try {
|
|
292
|
+
const raw = await node_fs_1.promises.readFile(packagePath, "utf8");
|
|
293
|
+
const pkg = JSON.parse(raw);
|
|
294
|
+
const depVersion = pkg.dependencies?.["@a5c-ai/babysitter-sdk"];
|
|
295
|
+
const devDepVersion = pkg.devDependencies?.["@a5c-ai/babysitter-sdk"];
|
|
296
|
+
const version = depVersion || devDepVersion;
|
|
297
|
+
const location = depVersion ? "dependencies" : devDepVersion ? "devDependencies" : null;
|
|
298
|
+
if (version) {
|
|
299
|
+
return {
|
|
300
|
+
name: "package-dependency",
|
|
301
|
+
description: "Project has babysitter-sdk dependency",
|
|
302
|
+
status: "pass",
|
|
303
|
+
message: `@a5c-ai/babysitter-sdk@${version} found in ${location}`,
|
|
304
|
+
details: { version, location, packagePath },
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
name: "package-dependency",
|
|
309
|
+
description: "Project has babysitter-sdk dependency",
|
|
310
|
+
status: "warn",
|
|
311
|
+
message: "@a5c-ai/babysitter-sdk not found in package.json",
|
|
312
|
+
nextSteps: [
|
|
313
|
+
"Add the dependency: npm install @a5c-ai/babysitter-sdk",
|
|
314
|
+
"Or if this is not a babysitter project, this warning can be ignored",
|
|
315
|
+
],
|
|
316
|
+
details: { packagePath, found: false },
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
const err = error;
|
|
321
|
+
if (err.code === "ENOENT") {
|
|
322
|
+
return {
|
|
323
|
+
name: "package-dependency",
|
|
324
|
+
description: "Project has babysitter-sdk dependency",
|
|
325
|
+
status: "warn",
|
|
326
|
+
message: "No package.json found in current directory",
|
|
327
|
+
nextSteps: [
|
|
328
|
+
"If this is a Node.js project, run: npm init -y",
|
|
329
|
+
"If not in a project directory, this warning can be ignored",
|
|
330
|
+
],
|
|
331
|
+
details: { packagePath, exists: false },
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
name: "package-dependency",
|
|
336
|
+
description: "Project has babysitter-sdk dependency",
|
|
337
|
+
status: "warn",
|
|
338
|
+
message: `Error reading package.json: ${err.message}`,
|
|
339
|
+
details: { packagePath, error: err.message },
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Check: Environment Variables
|
|
345
|
+
* Verifies babysitter-related environment variables are set correctly
|
|
346
|
+
*/
|
|
347
|
+
function checkEnvironmentVariables() {
|
|
348
|
+
const envChecks = [];
|
|
349
|
+
// Check BABYSITTER_RUNS_DIR
|
|
350
|
+
const runsDir = process.env[defaults_1.CONFIG_ENV_VARS.RUNS_DIR];
|
|
351
|
+
envChecks.push({
|
|
352
|
+
name: "BABYSITTER_RUNS_DIR",
|
|
353
|
+
key: defaults_1.CONFIG_ENV_VARS.RUNS_DIR,
|
|
354
|
+
value: runsDir,
|
|
355
|
+
required: false,
|
|
356
|
+
valid: true,
|
|
357
|
+
note: runsDir ? `Custom runs directory: ${runsDir}` : `Using default: ${defaults_1.DEFAULTS.runsDir}`,
|
|
358
|
+
});
|
|
359
|
+
// Check BABYSITTER_MAX_ITERATIONS
|
|
360
|
+
const maxIterations = process.env[defaults_1.CONFIG_ENV_VARS.MAX_ITERATIONS];
|
|
361
|
+
let maxIterValid = true;
|
|
362
|
+
if (maxIterations) {
|
|
363
|
+
const parsed = parseInt(maxIterations, 10);
|
|
364
|
+
maxIterValid = Number.isFinite(parsed) && parsed > 0;
|
|
365
|
+
}
|
|
366
|
+
envChecks.push({
|
|
367
|
+
name: "BABYSITTER_MAX_ITERATIONS",
|
|
368
|
+
key: defaults_1.CONFIG_ENV_VARS.MAX_ITERATIONS,
|
|
369
|
+
value: maxIterations,
|
|
370
|
+
required: false,
|
|
371
|
+
valid: maxIterValid,
|
|
372
|
+
note: maxIterations
|
|
373
|
+
? maxIterValid
|
|
374
|
+
? `Max iterations: ${maxIterations}`
|
|
375
|
+
: `Invalid value: ${maxIterations} (must be positive integer)`
|
|
376
|
+
: `Using default: ${defaults_1.DEFAULTS.maxIterations}`,
|
|
377
|
+
});
|
|
378
|
+
// Check BABYSITTER_LOG_LEVEL
|
|
379
|
+
const logLevel = process.env[defaults_1.CONFIG_ENV_VARS.LOG_LEVEL];
|
|
380
|
+
const validLogLevels = ["debug", "info", "warn", "error", "silent"];
|
|
381
|
+
const logLevelValid = !logLevel || validLogLevels.includes(logLevel.toLowerCase());
|
|
382
|
+
envChecks.push({
|
|
383
|
+
name: "BABYSITTER_LOG_LEVEL",
|
|
384
|
+
key: defaults_1.CONFIG_ENV_VARS.LOG_LEVEL,
|
|
385
|
+
value: logLevel,
|
|
386
|
+
required: false,
|
|
387
|
+
valid: logLevelValid,
|
|
388
|
+
note: logLevel
|
|
389
|
+
? logLevelValid
|
|
390
|
+
? `Log level: ${logLevel}`
|
|
391
|
+
: `Invalid value: ${logLevel} (must be one of: ${validLogLevels.join(", ")})`
|
|
392
|
+
: `Using default: ${defaults_1.DEFAULTS.logLevel}`,
|
|
393
|
+
});
|
|
394
|
+
// Check BABYSITTER_ALLOW_SECRET_LOGS
|
|
395
|
+
const allowSecrets = process.env[defaults_1.CONFIG_ENV_VARS.ALLOW_SECRET_LOGS];
|
|
396
|
+
envChecks.push({
|
|
397
|
+
name: "BABYSITTER_ALLOW_SECRET_LOGS",
|
|
398
|
+
key: defaults_1.CONFIG_ENV_VARS.ALLOW_SECRET_LOGS,
|
|
399
|
+
value: allowSecrets,
|
|
400
|
+
required: false,
|
|
401
|
+
valid: true,
|
|
402
|
+
note: allowSecrets
|
|
403
|
+
? `Secret logging: ${allowSecrets === "1" || allowSecrets.toLowerCase() === "true" ? "enabled" : "disabled"}`
|
|
404
|
+
: "Secret logging: disabled (default)",
|
|
405
|
+
});
|
|
406
|
+
const invalidVars = envChecks.filter((c) => !c.valid);
|
|
407
|
+
const setVars = envChecks.filter((c) => c.value !== undefined);
|
|
408
|
+
if (invalidVars.length > 0) {
|
|
409
|
+
return {
|
|
410
|
+
name: "environment-variables",
|
|
411
|
+
description: "Environment variables are configured correctly",
|
|
412
|
+
status: "fail",
|
|
413
|
+
message: `${invalidVars.length} environment variable(s) have invalid values`,
|
|
414
|
+
nextSteps: invalidVars.map((v) => `Fix ${v.name}: ${v.note}`),
|
|
415
|
+
details: { checks: envChecks, invalid: invalidVars.map((v) => v.name) },
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
return {
|
|
419
|
+
name: "environment-variables",
|
|
420
|
+
description: "Environment variables are configured correctly",
|
|
421
|
+
status: "pass",
|
|
422
|
+
message: setVars.length > 0
|
|
423
|
+
? `${setVars.length} environment variable(s) configured`
|
|
424
|
+
: "Using default configuration",
|
|
425
|
+
details: { checks: envChecks, customized: setVars.map((v) => v.name) },
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
// ============================================================================
|
|
429
|
+
// Main Health Check Runner
|
|
430
|
+
// ============================================================================
|
|
431
|
+
/**
|
|
432
|
+
* Runs all health checks and returns aggregated results
|
|
433
|
+
*
|
|
434
|
+
* @param options - Health check options
|
|
435
|
+
* @returns Complete health check result
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```ts
|
|
439
|
+
* // Run health checks with default options
|
|
440
|
+
* const result = await runHealthCheck({});
|
|
441
|
+
*
|
|
442
|
+
* // Run with verbose output
|
|
443
|
+
* const result = await runHealthCheck({ verbose: true });
|
|
444
|
+
*
|
|
445
|
+
* // Get JSON output
|
|
446
|
+
* const result = await runHealthCheck({ json: true });
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
async function runHealthCheck(options) {
|
|
450
|
+
const cwd = options.cwd ?? process.cwd();
|
|
451
|
+
const timestamp = new Date().toISOString();
|
|
452
|
+
// Run all checks
|
|
453
|
+
const checks = await Promise.all([
|
|
454
|
+
checkSdkVersion(),
|
|
455
|
+
checkNodeVersion(),
|
|
456
|
+
checkA5cDirectory(cwd),
|
|
457
|
+
checkPackageDependency(cwd),
|
|
458
|
+
checkEnvironmentVariables(),
|
|
459
|
+
]);
|
|
460
|
+
// Calculate summary
|
|
461
|
+
const summary = {
|
|
462
|
+
total: checks.length,
|
|
463
|
+
passed: checks.filter((c) => c.status === "pass").length,
|
|
464
|
+
failed: checks.filter((c) => c.status === "fail").length,
|
|
465
|
+
warnings: checks.filter((c) => c.status === "warn").length,
|
|
466
|
+
};
|
|
467
|
+
// Determine overall status
|
|
468
|
+
let status;
|
|
469
|
+
if (summary.failed > 0) {
|
|
470
|
+
status = "unhealthy";
|
|
471
|
+
}
|
|
472
|
+
else if (summary.warnings > 0) {
|
|
473
|
+
status = "degraded";
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
status = "healthy";
|
|
477
|
+
}
|
|
478
|
+
// Aggregate next steps from failing and warning checks
|
|
479
|
+
const nextSteps = checks
|
|
480
|
+
.filter((c) => c.status === "fail" || c.status === "warn")
|
|
481
|
+
.flatMap((c) => c.nextSteps ?? []);
|
|
482
|
+
const result = {
|
|
483
|
+
status,
|
|
484
|
+
timestamp,
|
|
485
|
+
checks,
|
|
486
|
+
summary,
|
|
487
|
+
nextSteps,
|
|
488
|
+
};
|
|
489
|
+
// Output results
|
|
490
|
+
if (!options.json) {
|
|
491
|
+
outputTextResult(result, options);
|
|
492
|
+
}
|
|
493
|
+
return result;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Outputs health check results in human-readable format
|
|
497
|
+
*/
|
|
498
|
+
function outputTextResult(result, options) {
|
|
499
|
+
const useColors = supportsColors();
|
|
500
|
+
const { verbose } = options;
|
|
501
|
+
// Header
|
|
502
|
+
console.log("");
|
|
503
|
+
const statusColor = result.status === "healthy"
|
|
504
|
+
? COLORS.green
|
|
505
|
+
: result.status === "degraded"
|
|
506
|
+
? COLORS.yellow
|
|
507
|
+
: COLORS.red;
|
|
508
|
+
const statusText = useColors
|
|
509
|
+
? `${statusColor}${COLORS.bold}${result.status.toUpperCase()}${COLORS.reset}`
|
|
510
|
+
: result.status.toUpperCase();
|
|
511
|
+
console.log(`Babysitter SDK Health Check: ${statusText}`);
|
|
512
|
+
console.log("");
|
|
513
|
+
// Individual checks
|
|
514
|
+
for (const check of result.checks) {
|
|
515
|
+
const symbol = getSymbol(check.status, useColors);
|
|
516
|
+
console.log(` ${symbol} ${check.description}`);
|
|
517
|
+
if (verbose || check.status !== "pass") {
|
|
518
|
+
const msgColor = check.status === "pass"
|
|
519
|
+
? COLORS.dim
|
|
520
|
+
: check.status === "warn"
|
|
521
|
+
? COLORS.yellow
|
|
522
|
+
: COLORS.red;
|
|
523
|
+
const message = useColors ? `${msgColor}${check.message}${COLORS.reset}` : check.message;
|
|
524
|
+
console.log(` ${message}`);
|
|
525
|
+
}
|
|
526
|
+
if (verbose && check.details) {
|
|
527
|
+
const detailsStr = JSON.stringify(check.details, null, 2)
|
|
528
|
+
.split("\n")
|
|
529
|
+
.map((line) => ` ${useColors ? COLORS.dim : ""}${line}${useColors ? COLORS.reset : ""}`)
|
|
530
|
+
.join("\n");
|
|
531
|
+
console.log(detailsStr);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
console.log("");
|
|
535
|
+
// Summary
|
|
536
|
+
const summaryLine = [
|
|
537
|
+
`${result.summary.passed} passed`,
|
|
538
|
+
result.summary.failed > 0 ? `${result.summary.failed} failed` : null,
|
|
539
|
+
result.summary.warnings > 0 ? `${result.summary.warnings} warnings` : null,
|
|
540
|
+
]
|
|
541
|
+
.filter(Boolean)
|
|
542
|
+
.join(", ");
|
|
543
|
+
console.log(`Summary: ${summaryLine}`);
|
|
544
|
+
// Next steps
|
|
545
|
+
if (result.nextSteps.length > 0) {
|
|
546
|
+
console.log("");
|
|
547
|
+
const nextStepsHeader = useColors
|
|
548
|
+
? `${COLORS.cyan}${COLORS.bold}Next Steps:${COLORS.reset}`
|
|
549
|
+
: "Next Steps:";
|
|
550
|
+
console.log(nextStepsHeader);
|
|
551
|
+
for (const step of result.nextSteps) {
|
|
552
|
+
console.log(` - ${step}`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
console.log("");
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* CLI entry point for the health command
|
|
559
|
+
*
|
|
560
|
+
* @param options - Parsed CLI options
|
|
561
|
+
* @returns Exit code (0 for healthy, 1 for unhealthy)
|
|
562
|
+
*/
|
|
563
|
+
async function handleHealthCommand(options) {
|
|
564
|
+
const result = await runHealthCheck(options);
|
|
565
|
+
if (options.json) {
|
|
566
|
+
console.log(JSON.stringify(result, null, 2));
|
|
567
|
+
}
|
|
568
|
+
// Return exit code based on status
|
|
569
|
+
switch (result.status) {
|
|
570
|
+
case "healthy":
|
|
571
|
+
return 0;
|
|
572
|
+
case "degraded":
|
|
573
|
+
return 0; // Warnings don't cause failure
|
|
574
|
+
case "unhealthy":
|
|
575
|
+
return 1;
|
|
576
|
+
default:
|
|
577
|
+
return 1;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hook:log CLI command.
|
|
3
|
+
*
|
|
4
|
+
* Reads a hook payload from stdin, extracts the relevant fields for the
|
|
5
|
+
* given hook type, formats a structured log line, and appends it to the
|
|
6
|
+
* specified log file. This consolidates the field-extraction logic that
|
|
7
|
+
* was previously duplicated across 13 logger.sh shell scripts.
|
|
8
|
+
*/
|
|
9
|
+
export interface HookLogCommandArgs {
|
|
10
|
+
hookType: string;
|
|
11
|
+
logFile: string;
|
|
12
|
+
json: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function handleHookLog(args: HookLogCommandArgs): Promise<number>;
|
|
15
|
+
//# sourceMappingURL=hookLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookLog.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/hookLog.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAoLD,wBAAsB,aAAa,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuG7E"}
|