@orchestrator-claude/cli 3.1.12 → 3.2.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.
- package/dist/api-client/OrchestratorAPIClient.d.ts +50 -1
- package/dist/api-client/OrchestratorAPIClient.d.ts.map +1 -1
- package/dist/api-client/OrchestratorAPIClient.js +73 -1
- package/dist/api-client/OrchestratorAPIClient.js.map +1 -1
- package/dist/api-client/types.d.ts +95 -2
- package/dist/api-client/types.d.ts.map +1 -1
- package/dist/commands/InitCommand.d.ts +22 -3
- package/dist/commands/InitCommand.d.ts.map +1 -1
- package/dist/commands/InitCommand.js +147 -13
- package/dist/commands/InitCommand.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/BootstrapService.d.ts +100 -0
- package/dist/services/BootstrapService.d.ts.map +1 -0
- package/dist/services/BootstrapService.js +231 -0
- package/dist/services/BootstrapService.js.map +1 -0
- package/dist/services/CleanupManager.d.ts +49 -0
- package/dist/services/CleanupManager.d.ts.map +1 -0
- package/dist/services/CleanupManager.js +87 -0
- package/dist/services/CleanupManager.js.map +1 -0
- package/dist/services/CredentialGenerator.d.ts +11 -0
- package/dist/services/CredentialGenerator.d.ts.map +1 -0
- package/dist/services/CredentialGenerator.js +25 -0
- package/dist/services/CredentialGenerator.js.map +1 -0
- package/dist/services/VerificationService.d.ts +103 -0
- package/dist/services/VerificationService.d.ts.map +1 -0
- package/dist/services/VerificationService.js +350 -0
- package/dist/services/VerificationService.js.map +1 -0
- package/dist/templates/base/claude/skills/release/SKILL.md +236 -0
- package/dist/templates/base/claude/skills/release/release.sh +460 -0
- package/dist/templates/base/docker-compose.yml.hbs +189 -8
- package/dist/templates/base/mcp.json.hbs +16 -9
- package/dist/templates/default/docker-compose.yml +190 -10
- package/package.json +1 -1
- package/templates/base/claude/skills/release/SKILL.md +236 -0
- package/templates/base/claude/skills/release/release.sh +460 -0
- package/templates/base/docker-compose.yml.hbs +189 -8
- package/templates/base/mcp.json.hbs +16 -9
- package/templates/default/docker-compose.yml +190 -10
- package/dist/templates/base/orchestrator-index.json.hbs +0 -37
- package/dist/templates/projects/api/files/index.ts.hbs +0 -30
- package/dist/templates/projects/api/files/server.ts.hbs +0 -63
- package/dist/templates/projects/api/files/tsconfig.json.hbs +0 -27
- package/dist/templates/projects/api/files/vitest.config.ts.hbs +0 -28
- package/dist/templates/projects/api/template.config.json +0 -238
- package/dist/templates/projects/api/template.config.ts +0 -149
- package/dist/templates/projects/cli/files/cli.ts.hbs +0 -50
- package/dist/templates/projects/cli/files/index.ts.hbs +0 -8
- package/dist/templates/projects/cli/files/tsconfig.json.hbs +0 -27
- package/dist/templates/projects/cli/files/vitest.config.ts.hbs +0 -28
- package/dist/templates/projects/cli/template.config.json +0 -213
- package/dist/templates/projects/cli/template.config.ts +0 -126
- package/dist/templates/projects/frontend/files/App.tsx.hbs +0 -31
- package/dist/templates/projects/frontend/files/index.html.hbs +0 -13
- package/dist/templates/projects/frontend/files/main.tsx.hbs +0 -22
- package/dist/templates/projects/frontend/files/tsconfig.json.hbs +0 -34
- package/dist/templates/projects/frontend/files/tsconfig.node.json.hbs +0 -10
- package/dist/templates/projects/frontend/files/vite.config.ts.hbs +0 -19
- package/dist/templates/projects/frontend/files/vitest.config.ts.hbs +0 -36
- package/dist/templates/projects/frontend/template.config.json +0 -241
- package/dist/templates/projects/frontend/template.config.ts +0 -153
- package/dist/templates/projects/minimal/files/claude-settings.json.hbs +0 -20
- package/dist/templates/projects/minimal/files/env.example.hbs +0 -17
- package/dist/templates/projects/minimal/files/gitignore.hbs +0 -41
- package/dist/templates/projects/minimal/files/index.ts.hbs +0 -13
- package/dist/templates/projects/minimal/files/tsconfig.json.hbs +0 -27
- package/dist/templates/projects/minimal/template.config.json +0 -185
- package/dist/templates/projects/minimal/template.config.ts +0 -88
- package/templates/base/orchestrator-index.json.hbs +0 -37
- package/templates/projects/api/files/index.ts.hbs +0 -30
- package/templates/projects/api/files/server.ts.hbs +0 -63
- package/templates/projects/api/files/tsconfig.json.hbs +0 -27
- package/templates/projects/api/files/vitest.config.ts.hbs +0 -28
- package/templates/projects/api/template.config.json +0 -238
- package/templates/projects/api/template.config.ts +0 -149
- package/templates/projects/cli/files/cli.ts.hbs +0 -50
- package/templates/projects/cli/files/index.ts.hbs +0 -8
- package/templates/projects/cli/files/tsconfig.json.hbs +0 -27
- package/templates/projects/cli/files/vitest.config.ts.hbs +0 -28
- package/templates/projects/cli/template.config.json +0 -213
- package/templates/projects/cli/template.config.ts +0 -126
- package/templates/projects/frontend/files/App.tsx.hbs +0 -31
- package/templates/projects/frontend/files/index.html.hbs +0 -13
- package/templates/projects/frontend/files/main.tsx.hbs +0 -22
- package/templates/projects/frontend/files/tsconfig.json.hbs +0 -34
- package/templates/projects/frontend/files/tsconfig.node.json.hbs +0 -10
- package/templates/projects/frontend/files/vite.config.ts.hbs +0 -19
- package/templates/projects/frontend/files/vitest.config.ts.hbs +0 -36
- package/templates/projects/frontend/template.config.json +0 -241
- package/templates/projects/frontend/template.config.ts +0 -153
- package/templates/projects/minimal/files/claude-settings.json.hbs +0 -20
- package/templates/projects/minimal/files/env.example.hbs +0 -17
- package/templates/projects/minimal/files/gitignore.hbs +0 -41
- package/templates/projects/minimal/files/index.ts.hbs +0 -13
- package/templates/projects/minimal/files/tsconfig.json.hbs +0 -27
- package/templates/projects/minimal/template.config.json +0 -185
- package/templates/projects/minimal/template.config.ts +0 -88
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CleanupManager.js","sourceRoot":"","sources":["../../src/services/CleanupManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAS9C,MAAM,OAAO,cAAc;IACR,KAAK,GAAG,IAAI,GAAG,EAAgC,CAAC;IACzD,WAAW,GAAG,KAAK,CAAC;IACpB,uBAAuB,GAAG,KAAK,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,KAAmB,EAAE,UAA0B,EAAE;QACpD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,iFAAiF;QACjF,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,QAAQ,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,CAAC;YAAC,MAAM,CAAC;gBACP,2CAA2C;gBAC3C,IAAI,CAAC;oBACH,QAAQ,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACpE,CAAC;gBAAC,MAAM,CAAC;oBACP,4DAA4D;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAE,CAAC;YAChD,IAAI,GAAG,CAAC,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP,qCAAqC;gBACvC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,qBAAqB;QACnB,IAAI,IAAI,CAAC,uBAAuB;YAAE,OAAO;QACzC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GeneratedCredentials } from '../api-client/types.js';
|
|
2
|
+
export declare class CredentialGenerator {
|
|
3
|
+
/**
|
|
4
|
+
* Generate secure credentials for a project.
|
|
5
|
+
*
|
|
6
|
+
* @param projectName - Project name used for email local domain
|
|
7
|
+
* @returns Generated credentials (email, password, jwtSecret)
|
|
8
|
+
*/
|
|
9
|
+
generate(projectName: string): GeneratedCredentials;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=CredentialGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CredentialGenerator.d.ts","sourceRoot":"","sources":["../../src/services/CredentialGenerator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,qBAAa,mBAAmB;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB;CAOpD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates cryptographically secure credentials for project bootstrap.
|
|
5
|
+
* Pure class with no side effects — uses only Node.js built-in crypto.
|
|
6
|
+
*
|
|
7
|
+
* @module services/CredentialGenerator
|
|
8
|
+
*/
|
|
9
|
+
import { randomBytes } from 'node:crypto';
|
|
10
|
+
export class CredentialGenerator {
|
|
11
|
+
/**
|
|
12
|
+
* Generate secure credentials for a project.
|
|
13
|
+
*
|
|
14
|
+
* @param projectName - Project name used for email local domain
|
|
15
|
+
* @returns Generated credentials (email, password, jwtSecret)
|
|
16
|
+
*/
|
|
17
|
+
generate(projectName) {
|
|
18
|
+
return {
|
|
19
|
+
email: `admin@${projectName}.local`,
|
|
20
|
+
password: randomBytes(24).toString('base64url'),
|
|
21
|
+
jwtSecret: randomBytes(32).toString('hex'),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=CredentialGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CredentialGenerator.js","sourceRoot":"","sources":["../../src/services/CredentialGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,OAAO,mBAAmB;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,WAAmB;QAC1B,OAAO;YACL,KAAK,EAAE,SAAS,WAAW,QAAQ;YACnC,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC/C,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;SAC3C,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { VerificationCheck, VerificationResult } from '../api-client/types.js';
|
|
2
|
+
import type { OrchestratorAPIClient } from '../api-client/OrchestratorAPIClient.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for the top-level verify() method.
|
|
5
|
+
*/
|
|
6
|
+
export interface VerifyOptions {
|
|
7
|
+
/** Absolute path to the project root (where .env and docker-compose.yml live). */
|
|
8
|
+
projectPath: string;
|
|
9
|
+
/** Admin email to use for the authentication check. */
|
|
10
|
+
email?: string;
|
|
11
|
+
/** Admin password to use for the authentication check. */
|
|
12
|
+
password?: string;
|
|
13
|
+
/** Project ID to verify registration (from bootstrap result). */
|
|
14
|
+
projectId?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Runs structured post-init verification checks against the orchestrator stack.
|
|
18
|
+
*
|
|
19
|
+
* Each individual check method is public so they can be called in isolation
|
|
20
|
+
* during testing or from custom tooling.
|
|
21
|
+
*/
|
|
22
|
+
export declare class VerificationService {
|
|
23
|
+
private readonly apiClient;
|
|
24
|
+
constructor(apiClient: OrchestratorAPIClient);
|
|
25
|
+
/**
|
|
26
|
+
* Verify that the Orchestrator API is reachable and reports a healthy status.
|
|
27
|
+
*
|
|
28
|
+
* @returns VerificationCheck with passed:true when API returns status === 'ok'
|
|
29
|
+
*/
|
|
30
|
+
checkApiHealth(): Promise<VerificationCheck>;
|
|
31
|
+
/**
|
|
32
|
+
* Verify that the provided credentials can authenticate successfully.
|
|
33
|
+
*
|
|
34
|
+
* Returns passed:false with a descriptive message when no credentials are given,
|
|
35
|
+
* so callers always receive a structured result rather than a thrown error.
|
|
36
|
+
*
|
|
37
|
+
* @param email - Admin email address
|
|
38
|
+
* @param password - Admin password
|
|
39
|
+
* @returns VerificationCheck with passed:true when login succeeds
|
|
40
|
+
*/
|
|
41
|
+
checkAuth(email?: string, password?: string): Promise<VerificationCheck>;
|
|
42
|
+
/**
|
|
43
|
+
* Verify that the .env file at the given project path contains all required
|
|
44
|
+
* critical environment variables with non-placeholder values.
|
|
45
|
+
*
|
|
46
|
+
* Parsing is done manually so no dotenv package is required at runtime.
|
|
47
|
+
*
|
|
48
|
+
* @param projectPath - Absolute path to the project root
|
|
49
|
+
* @returns VerificationCheck with passed:true when all CRITICAL_ENV_VARS are set
|
|
50
|
+
*/
|
|
51
|
+
checkEnvCompleteness(projectPath: string): Promise<VerificationCheck>;
|
|
52
|
+
/**
|
|
53
|
+
* Verify that Docker Compose services are running in the given project directory.
|
|
54
|
+
*
|
|
55
|
+
* Runs `docker compose ps` synchronously and counts lines that contain
|
|
56
|
+
* 'running' or 'up' (case-insensitive) to determine service health.
|
|
57
|
+
*
|
|
58
|
+
* @param projectPath - Absolute path to the directory containing docker-compose.yml
|
|
59
|
+
* @returns VerificationCheck with passed:true when at least one service is running
|
|
60
|
+
*/
|
|
61
|
+
checkDockerServices(projectPath: string): Promise<VerificationCheck>;
|
|
62
|
+
/**
|
|
63
|
+
* Verify that the registered project exists in the Orchestrator API.
|
|
64
|
+
*
|
|
65
|
+
* Returns passed:false gracefully when no projectId is provided or
|
|
66
|
+
* when the API returns 404.
|
|
67
|
+
*
|
|
68
|
+
* @param projectId - The project ID to look up (optional)
|
|
69
|
+
* @returns VerificationCheck with passed:true when project is found
|
|
70
|
+
*/
|
|
71
|
+
checkProjectExists(projectId?: string): Promise<VerificationCheck>;
|
|
72
|
+
/**
|
|
73
|
+
* Verify that the MCP tool chain is reachable by exercising the
|
|
74
|
+
* detectWorkflow endpoint (a lightweight MCP-backed operation).
|
|
75
|
+
*
|
|
76
|
+
* @returns VerificationCheck with passed:true when detectWorkflow succeeds
|
|
77
|
+
*/
|
|
78
|
+
checkMcpConnectivity(): Promise<VerificationCheck>;
|
|
79
|
+
/**
|
|
80
|
+
* Run all verification checks in parallel and aggregate the results.
|
|
81
|
+
*
|
|
82
|
+
* All four checks (API health, auth, env completeness, Docker services)
|
|
83
|
+
* are executed concurrently via Promise.all to minimise total wall-clock time.
|
|
84
|
+
*
|
|
85
|
+
* @param options - Verify options (projectPath, email, password)
|
|
86
|
+
* @returns Aggregated VerificationResult with allPassed flag and duration
|
|
87
|
+
*/
|
|
88
|
+
verify(options: VerifyOptions): Promise<VerificationResult>;
|
|
89
|
+
/**
|
|
90
|
+
* Parse a .env file string into a key-value Map.
|
|
91
|
+
*
|
|
92
|
+
* Rules:
|
|
93
|
+
* - Lines starting with '#' are comments and are ignored
|
|
94
|
+
* - Empty lines are ignored
|
|
95
|
+
* - Lines without '=' are ignored
|
|
96
|
+
* - Values are trimmed of surrounding whitespace
|
|
97
|
+
*
|
|
98
|
+
* @param content - Raw .env file content
|
|
99
|
+
* @returns Map from variable name to value
|
|
100
|
+
*/
|
|
101
|
+
private parseEnvFile;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=VerificationService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerificationService.d.ts","sourceRoot":"","sources":["../../src/services/VerificationService.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AA2BpF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;GAKG;AACH,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,qBAAqB;IAM7D;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAyBlD;;;;;;;;;OASG;IACG,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA8B9E;;;;;;;;OAQG;IACG,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAyD3E;;;;;;;;OAQG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAyC1E;;;;;;;;OAQG;IACG,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiCxE;;;;;OAKG;IACG,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAyBxD;;;;;;;;OAQG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuBjE;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,YAAY;CAiBrB"}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Service
|
|
3
|
+
*
|
|
4
|
+
* Runs post-init verification checks to confirm the orchestrator stack
|
|
5
|
+
* is fully operational: API health, authentication, environment completeness,
|
|
6
|
+
* and Docker service status.
|
|
7
|
+
*
|
|
8
|
+
* Design principles:
|
|
9
|
+
* - All check methods catch errors internally and return passed:false (never throw)
|
|
10
|
+
* - Checks are run in parallel via Promise.all for speed
|
|
11
|
+
* - No dotenv dependency: .env is parsed manually
|
|
12
|
+
*
|
|
13
|
+
* @module services/VerificationService
|
|
14
|
+
*/
|
|
15
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Constants
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Environment variables that must be present and non-empty in .env
|
|
23
|
+
* for the project to be considered fully configured.
|
|
24
|
+
*/
|
|
25
|
+
const CRITICAL_ENV_VARS = [
|
|
26
|
+
'ORCHESTRATOR_API_URL',
|
|
27
|
+
'ORCHESTRATOR_ADMIN_EMAIL',
|
|
28
|
+
'ORCHESTRATOR_ADMIN_PASSWORD',
|
|
29
|
+
'ORCHESTRATOR_PROJECT_ID',
|
|
30
|
+
'JWT_SECRET',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Regex to detect unresolved template placeholder tokens, e.g. {{SOME_VAR}}.
|
|
34
|
+
*/
|
|
35
|
+
const PLACEHOLDER_REGEX = /\{\{[^}]+\}\}/;
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// VerificationService
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
/**
|
|
40
|
+
* Runs structured post-init verification checks against the orchestrator stack.
|
|
41
|
+
*
|
|
42
|
+
* Each individual check method is public so they can be called in isolation
|
|
43
|
+
* during testing or from custom tooling.
|
|
44
|
+
*/
|
|
45
|
+
export class VerificationService {
|
|
46
|
+
apiClient;
|
|
47
|
+
constructor(apiClient) {
|
|
48
|
+
this.apiClient = apiClient;
|
|
49
|
+
}
|
|
50
|
+
// -------------------------------------------------------------------------
|
|
51
|
+
// checkApiHealth
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Verify that the Orchestrator API is reachable and reports a healthy status.
|
|
55
|
+
*
|
|
56
|
+
* @returns VerificationCheck with passed:true when API returns status === 'ok'
|
|
57
|
+
*/
|
|
58
|
+
async checkApiHealth() {
|
|
59
|
+
try {
|
|
60
|
+
const response = await this.apiClient.healthCheck();
|
|
61
|
+
const passed = response?.status === 'ok';
|
|
62
|
+
return {
|
|
63
|
+
name: 'API Health',
|
|
64
|
+
passed,
|
|
65
|
+
message: passed
|
|
66
|
+
? 'API is healthy'
|
|
67
|
+
: `API returned status: ${response?.status}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
72
|
+
return {
|
|
73
|
+
name: 'API Health',
|
|
74
|
+
passed: false,
|
|
75
|
+
message: `API health check failed: ${msg}`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// -------------------------------------------------------------------------
|
|
80
|
+
// checkAuth
|
|
81
|
+
// -------------------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Verify that the provided credentials can authenticate successfully.
|
|
84
|
+
*
|
|
85
|
+
* Returns passed:false with a descriptive message when no credentials are given,
|
|
86
|
+
* so callers always receive a structured result rather than a thrown error.
|
|
87
|
+
*
|
|
88
|
+
* @param email - Admin email address
|
|
89
|
+
* @param password - Admin password
|
|
90
|
+
* @returns VerificationCheck with passed:true when login succeeds
|
|
91
|
+
*/
|
|
92
|
+
async checkAuth(email, password) {
|
|
93
|
+
if (!email || !password) {
|
|
94
|
+
return {
|
|
95
|
+
name: 'Authentication',
|
|
96
|
+
passed: false,
|
|
97
|
+
message: 'No credentials provided for authentication check',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
await this.apiClient.login({ email, password });
|
|
102
|
+
return {
|
|
103
|
+
name: 'Authentication',
|
|
104
|
+
passed: true,
|
|
105
|
+
message: 'Authentication successful',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
110
|
+
return {
|
|
111
|
+
name: 'Authentication',
|
|
112
|
+
passed: false,
|
|
113
|
+
message: `Authentication failed: ${msg}`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// -------------------------------------------------------------------------
|
|
118
|
+
// checkEnvCompleteness
|
|
119
|
+
// -------------------------------------------------------------------------
|
|
120
|
+
/**
|
|
121
|
+
* Verify that the .env file at the given project path contains all required
|
|
122
|
+
* critical environment variables with non-placeholder values.
|
|
123
|
+
*
|
|
124
|
+
* Parsing is done manually so no dotenv package is required at runtime.
|
|
125
|
+
*
|
|
126
|
+
* @param projectPath - Absolute path to the project root
|
|
127
|
+
* @returns VerificationCheck with passed:true when all CRITICAL_ENV_VARS are set
|
|
128
|
+
*/
|
|
129
|
+
async checkEnvCompleteness(projectPath) {
|
|
130
|
+
const envPath = join(projectPath, '.env');
|
|
131
|
+
if (!existsSync(envPath)) {
|
|
132
|
+
return {
|
|
133
|
+
name: 'Environment Completeness',
|
|
134
|
+
passed: false,
|
|
135
|
+
message: `.env file not found at ${envPath}`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
140
|
+
const envVars = this.parseEnvFile(content);
|
|
141
|
+
// Check for missing or empty CRITICAL vars
|
|
142
|
+
const missing = CRITICAL_ENV_VARS.filter(v => !envVars.has(v) || !envVars.get(v));
|
|
143
|
+
if (missing.length > 0) {
|
|
144
|
+
return {
|
|
145
|
+
name: 'Environment Completeness',
|
|
146
|
+
passed: false,
|
|
147
|
+
message: `Required environment variables missing: ${missing.join(', ')}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Check for unresolved placeholder tokens
|
|
151
|
+
const withPlaceholders = CRITICAL_ENV_VARS.filter(v => {
|
|
152
|
+
const val = envVars.get(v) ?? '';
|
|
153
|
+
return PLACEHOLDER_REGEX.test(val);
|
|
154
|
+
});
|
|
155
|
+
if (withPlaceholders.length > 0) {
|
|
156
|
+
return {
|
|
157
|
+
name: 'Environment Completeness',
|
|
158
|
+
passed: false,
|
|
159
|
+
message: `Environment variables contain unresolved placeholder tokens: ${withPlaceholders.join(', ')}`,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
name: 'Environment Completeness',
|
|
164
|
+
passed: true,
|
|
165
|
+
message: 'All required environment variables are set',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
170
|
+
return {
|
|
171
|
+
name: 'Environment Completeness',
|
|
172
|
+
passed: false,
|
|
173
|
+
message: `Failed to read .env: ${msg}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// -------------------------------------------------------------------------
|
|
178
|
+
// checkDockerServices
|
|
179
|
+
// -------------------------------------------------------------------------
|
|
180
|
+
/**
|
|
181
|
+
* Verify that Docker Compose services are running in the given project directory.
|
|
182
|
+
*
|
|
183
|
+
* Runs `docker compose ps` synchronously and counts lines that contain
|
|
184
|
+
* 'running' or 'up' (case-insensitive) to determine service health.
|
|
185
|
+
*
|
|
186
|
+
* @param projectPath - Absolute path to the directory containing docker-compose.yml
|
|
187
|
+
* @returns VerificationCheck with passed:true when at least one service is running
|
|
188
|
+
*/
|
|
189
|
+
async checkDockerServices(projectPath) {
|
|
190
|
+
try {
|
|
191
|
+
const output = execSync('docker compose ps', {
|
|
192
|
+
cwd: projectPath,
|
|
193
|
+
stdio: 'pipe',
|
|
194
|
+
}).toString();
|
|
195
|
+
const lines = output.split('\n').filter(l => l.trim());
|
|
196
|
+
// First line is the header row — skip it
|
|
197
|
+
const serviceLines = lines.slice(1);
|
|
198
|
+
const runningServices = serviceLines.filter(l => l.toLowerCase().includes('running') || l.toLowerCase().includes('up'));
|
|
199
|
+
if (runningServices.length === 0) {
|
|
200
|
+
return {
|
|
201
|
+
name: 'Docker Services',
|
|
202
|
+
passed: false,
|
|
203
|
+
message: 'No running Docker services found',
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
name: 'Docker Services',
|
|
208
|
+
passed: true,
|
|
209
|
+
message: `${runningServices.length} Docker service(s) running`,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
214
|
+
return {
|
|
215
|
+
name: 'Docker Services',
|
|
216
|
+
passed: false,
|
|
217
|
+
message: `Docker check failed: ${msg}`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// -------------------------------------------------------------------------
|
|
222
|
+
// checkProjectExists
|
|
223
|
+
// -------------------------------------------------------------------------
|
|
224
|
+
/**
|
|
225
|
+
* Verify that the registered project exists in the Orchestrator API.
|
|
226
|
+
*
|
|
227
|
+
* Returns passed:false gracefully when no projectId is provided or
|
|
228
|
+
* when the API returns 404.
|
|
229
|
+
*
|
|
230
|
+
* @param projectId - The project ID to look up (optional)
|
|
231
|
+
* @returns VerificationCheck with passed:true when project is found
|
|
232
|
+
*/
|
|
233
|
+
async checkProjectExists(projectId) {
|
|
234
|
+
if (!projectId) {
|
|
235
|
+
return {
|
|
236
|
+
name: 'Project Registration',
|
|
237
|
+
passed: false,
|
|
238
|
+
message: 'No projectId provided for project existence check',
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const project = await this.apiClient.getProject(projectId);
|
|
243
|
+
const passed = !!project?.id;
|
|
244
|
+
return {
|
|
245
|
+
name: 'Project Registration',
|
|
246
|
+
passed,
|
|
247
|
+
message: passed
|
|
248
|
+
? `Project "${project.name}" is registered`
|
|
249
|
+
: 'Project not found in API',
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
254
|
+
return {
|
|
255
|
+
name: 'Project Registration',
|
|
256
|
+
passed: false,
|
|
257
|
+
message: `Project existence check failed: ${msg}`,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// -------------------------------------------------------------------------
|
|
262
|
+
// checkMcpConnectivity
|
|
263
|
+
// -------------------------------------------------------------------------
|
|
264
|
+
/**
|
|
265
|
+
* Verify that the MCP tool chain is reachable by exercising the
|
|
266
|
+
* detectWorkflow endpoint (a lightweight MCP-backed operation).
|
|
267
|
+
*
|
|
268
|
+
* @returns VerificationCheck with passed:true when detectWorkflow succeeds
|
|
269
|
+
*/
|
|
270
|
+
async checkMcpConnectivity() {
|
|
271
|
+
try {
|
|
272
|
+
const result = await this.apiClient.detectWorkflow('test connectivity');
|
|
273
|
+
const passed = !!result?.workflowType;
|
|
274
|
+
return {
|
|
275
|
+
name: 'MCP Connectivity',
|
|
276
|
+
passed,
|
|
277
|
+
message: passed
|
|
278
|
+
? 'MCP tool chain is reachable'
|
|
279
|
+
: 'MCP detectWorkflow returned empty response',
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
284
|
+
return {
|
|
285
|
+
name: 'MCP Connectivity',
|
|
286
|
+
passed: false,
|
|
287
|
+
message: `MCP connectivity check failed: ${msg}`,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// -------------------------------------------------------------------------
|
|
292
|
+
// verify
|
|
293
|
+
// -------------------------------------------------------------------------
|
|
294
|
+
/**
|
|
295
|
+
* Run all verification checks in parallel and aggregate the results.
|
|
296
|
+
*
|
|
297
|
+
* All four checks (API health, auth, env completeness, Docker services)
|
|
298
|
+
* are executed concurrently via Promise.all to minimise total wall-clock time.
|
|
299
|
+
*
|
|
300
|
+
* @param options - Verify options (projectPath, email, password)
|
|
301
|
+
* @returns Aggregated VerificationResult with allPassed flag and duration
|
|
302
|
+
*/
|
|
303
|
+
async verify(options) {
|
|
304
|
+
const start = Date.now();
|
|
305
|
+
const checks = await Promise.all([
|
|
306
|
+
this.checkApiHealth(),
|
|
307
|
+
this.checkAuth(options.email, options.password),
|
|
308
|
+
this.checkEnvCompleteness(options.projectPath),
|
|
309
|
+
this.checkDockerServices(options.projectPath),
|
|
310
|
+
this.checkProjectExists(options.projectId),
|
|
311
|
+
this.checkMcpConnectivity(),
|
|
312
|
+
]);
|
|
313
|
+
return {
|
|
314
|
+
allPassed: checks.every(c => c.passed),
|
|
315
|
+
checks,
|
|
316
|
+
duration: Date.now() - start,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// -------------------------------------------------------------------------
|
|
320
|
+
// Private helpers
|
|
321
|
+
// -------------------------------------------------------------------------
|
|
322
|
+
/**
|
|
323
|
+
* Parse a .env file string into a key-value Map.
|
|
324
|
+
*
|
|
325
|
+
* Rules:
|
|
326
|
+
* - Lines starting with '#' are comments and are ignored
|
|
327
|
+
* - Empty lines are ignored
|
|
328
|
+
* - Lines without '=' are ignored
|
|
329
|
+
* - Values are trimmed of surrounding whitespace
|
|
330
|
+
*
|
|
331
|
+
* @param content - Raw .env file content
|
|
332
|
+
* @returns Map from variable name to value
|
|
333
|
+
*/
|
|
334
|
+
parseEnvFile(content) {
|
|
335
|
+
const envVars = new Map();
|
|
336
|
+
for (const line of content.split('\n')) {
|
|
337
|
+
const trimmed = line.trim();
|
|
338
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
339
|
+
continue;
|
|
340
|
+
const eqIndex = trimmed.indexOf('=');
|
|
341
|
+
if (eqIndex === -1)
|
|
342
|
+
continue;
|
|
343
|
+
const key = trimmed.substring(0, eqIndex).trim();
|
|
344
|
+
const value = trimmed.substring(eqIndex + 1).trim();
|
|
345
|
+
envVars.set(key, value);
|
|
346
|
+
}
|
|
347
|
+
return envVars;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=VerificationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerificationService.js","sourceRoot":"","sources":["../../src/services/VerificationService.ts"],"names":[],"mappings":"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"}
|