@cyanautomation/kaseki-agent 1.33.1 → 1.34.1
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/__test-utils/api-client-assertions.d.ts +2 -36
- package/dist/__test-utils/api-client-assertions.d.ts.map +1 -1
- package/dist/__test-utils/api-client-assertions.js +2 -97
- package/dist/__test-utils/api-client-assertions.js.map +1 -1
- package/dist/cli/bootstrappers/AgentsBootstrapper.d.ts +51 -0
- package/dist/cli/bootstrappers/AgentsBootstrapper.d.ts.map +1 -0
- package/dist/cli/bootstrappers/AgentsBootstrapper.js +130 -0
- package/dist/cli/bootstrappers/AgentsBootstrapper.js.map +1 -0
- package/dist/cli/commands/QuickstartCommand.d.ts +7 -11
- package/dist/cli/commands/QuickstartCommand.d.ts.map +1 -1
- package/dist/cli/commands/QuickstartCommand.js +44 -267
- package/dist/cli/commands/QuickstartCommand.js.map +1 -1
- package/dist/cli/launchers/ContainerLauncher.d.ts +38 -0
- package/dist/cli/launchers/ContainerLauncher.d.ts.map +1 -0
- package/dist/cli/launchers/ContainerLauncher.js +148 -0
- package/dist/cli/launchers/ContainerLauncher.js.map +1 -0
- package/dist/cli/resolvers/SecretResolver.d.ts +34 -0
- package/dist/cli/resolvers/SecretResolver.d.ts.map +1 -0
- package/dist/cli/resolvers/SecretResolver.js +90 -0
- package/dist/cli/resolvers/SecretResolver.js.map +1 -0
- package/dist/cli/validators/EnvironmentValidator.d.ts +37 -0
- package/dist/cli/validators/EnvironmentValidator.d.ts.map +1 -0
- package/dist/cli/validators/EnvironmentValidator.js +82 -0
- package/dist/cli/validators/EnvironmentValidator.js.map +1 -0
- package/dist/config/ConfigManager.js +1 -1
- package/dist/config/ConfigManager.js.map +1 -1
- package/dist/job-scheduler.d.ts.map +1 -1
- package/dist/job-scheduler.js +1 -0
- package/dist/job-scheduler.js.map +1 -1
- package/dist/kaseki-api-config.js +1 -1
- package/dist/kaseki-api-routes.d.ts.map +1 -1
- package/dist/kaseki-api-routes.js +37 -17
- package/dist/kaseki-api-routes.js.map +1 -1
- package/dist/secrets/SecretsManager.d.ts +1 -1
- package/dist/secrets/SecretsManager.d.ts.map +1 -1
- package/dist/secrets/SecretsManager.js +2 -3
- package/dist/secrets/SecretsManager.js.map +1 -1
- package/dist/secrets/host-secrets-reader.d.ts +1 -1
- package/dist/secrets/host-secrets-reader.js +2 -2
- package/dist/secrets/host-secrets-reader.js.map +1 -1
- package/package.json +10 -6
- package/scripts/docker-entrypoint.sh +2 -27
- package/scripts/startup-checks.sh +85 -39
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Extracted from
|
|
2
|
+
* Minimal OpenAPI test assertion helpers
|
|
3
|
+
* Extracted from patterns in openapi-spec-generator.test.ts
|
|
4
4
|
* Reduces boilerplate and improves test maintainability
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
@@ -8,42 +8,8 @@
|
|
|
8
8
|
* Replaces nested Object.entries().forEach() patterns with a single helper call
|
|
9
9
|
*/
|
|
10
10
|
export declare function forEachPathOperation(paths: Record<string, Record<string, unknown>>, callback: (pathName: string, method: string, operation: Record<string, unknown>) => void): void;
|
|
11
|
-
/**
|
|
12
|
-
* Assert that a specific endpoint has a given HTTP status code documented in responses
|
|
13
|
-
*/
|
|
14
|
-
export declare function assertStatusCode(spec: Record<string, unknown>, endpoint: string, method: string, statusCode: string | number): void;
|
|
15
|
-
/**
|
|
16
|
-
* Assert that a schema property has the expected constraints and types
|
|
17
|
-
*/
|
|
18
|
-
export declare function assertSchemaProperty(schema: Record<string, Record<string, unknown>>, propertyName: string, expectedType?: string, expectedFormat?: string): void;
|
|
19
|
-
/**
|
|
20
|
-
* Assert that an endpoint requires or doesn't require authentication
|
|
21
|
-
*/
|
|
22
|
-
export declare function assertAuthRequired(spec: Record<string, unknown>, endpoint: string, shouldBeProtected: boolean): void;
|
|
23
|
-
/**
|
|
24
|
-
* Assert that all operations in a path item have required fields
|
|
25
|
-
*/
|
|
26
|
-
export declare function assertPathItemOperationsComplete(pathItem: Record<string, Record<string, unknown>>, requiredFields: string[]): void;
|
|
27
|
-
/**
|
|
28
|
-
* Assert that a schema is properly structured with type and properties
|
|
29
|
-
*/
|
|
30
|
-
export declare function assertSchemaStructure(schema: Record<string, unknown>, expectedType?: string): void;
|
|
31
|
-
/**
|
|
32
|
-
* Assert that a field is in the required array of a schema
|
|
33
|
-
*/
|
|
34
|
-
export declare function assertFieldRequired(schema: Record<string, unknown>, fieldName: string): void;
|
|
35
11
|
/**
|
|
36
12
|
* Assert that all paths have at least one operation defined (GET, POST, etc.)
|
|
37
13
|
*/
|
|
38
14
|
export declare function assertAllPathsHaveOperations(paths: Record<string, Record<string, unknown>>): void;
|
|
39
|
-
/**
|
|
40
|
-
* Assert that an HTTP response has expected status code and content type
|
|
41
|
-
* Common pattern from kaseki-api-routes.test.ts
|
|
42
|
-
*/
|
|
43
|
-
export declare function assertResponseStatus(response: Record<string, any>, expectedStatus: number, expectedContentType?: string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Assert that a JSON response body contains expected keys
|
|
46
|
-
* Reduces nested expect chains for object property checks
|
|
47
|
-
*/
|
|
48
|
-
export declare function assertJsonResponse(response: Record<string, unknown>, expectedKeys: string[]): void;
|
|
49
15
|
//# sourceMappingURL=api-client-assertions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client-assertions.d.ts","sourceRoot":"","sources":["../../src/__test-utils/api-client-assertions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC9C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GACvF,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"api-client-assertions.d.ts","sourceRoot":"","sources":["../../src/__test-utils/api-client-assertions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC9C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GACvF,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAOjG"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Extracted from
|
|
2
|
+
* Minimal OpenAPI test assertion helpers
|
|
3
|
+
* Extracted from patterns in openapi-spec-generator.test.ts
|
|
4
4
|
* Reduces boilerplate and improves test maintainability
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
@@ -14,80 +14,6 @@ export function forEachPathOperation(paths, callback) {
|
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Assert that a specific endpoint has a given HTTP status code documented in responses
|
|
19
|
-
*/
|
|
20
|
-
export function assertStatusCode(spec, endpoint, method, statusCode) {
|
|
21
|
-
const paths = spec.paths;
|
|
22
|
-
const pathItem = paths?.[endpoint];
|
|
23
|
-
const operation = pathItem?.[method.toLowerCase()];
|
|
24
|
-
const responses = operation?.responses;
|
|
25
|
-
expect(responses).toBeDefined();
|
|
26
|
-
expect(responses?.[statusCode.toString()]).toBeDefined();
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Assert that a schema property has the expected constraints and types
|
|
30
|
-
*/
|
|
31
|
-
export function assertSchemaProperty(schema, propertyName, expectedType, expectedFormat) {
|
|
32
|
-
const properties = schema.properties;
|
|
33
|
-
const property = properties?.[propertyName];
|
|
34
|
-
expect(property).toBeDefined();
|
|
35
|
-
if (expectedType) {
|
|
36
|
-
expect(property?.type).toBe(expectedType);
|
|
37
|
-
}
|
|
38
|
-
if (expectedFormat) {
|
|
39
|
-
expect(property?.format).toBe(expectedFormat);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Assert that an endpoint requires or doesn't require authentication
|
|
44
|
-
*/
|
|
45
|
-
export function assertAuthRequired(spec, endpoint, shouldBeProtected) {
|
|
46
|
-
const paths = spec.paths;
|
|
47
|
-
const pathItem = paths?.[endpoint];
|
|
48
|
-
expect(pathItem).toBeDefined();
|
|
49
|
-
Object.entries(pathItem).forEach(([, operation]) => {
|
|
50
|
-
const op = operation;
|
|
51
|
-
const security = op.security;
|
|
52
|
-
if (shouldBeProtected) {
|
|
53
|
-
expect(security).toBeDefined();
|
|
54
|
-
expect(Array.isArray(security)).toBe(true);
|
|
55
|
-
expect(security?.length).toBeGreaterThan(0);
|
|
56
|
-
expect(security?.[0]?.BearerAuth).toBeDefined();
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// Public endpoint: security should be empty array or undefined
|
|
60
|
-
expect(security === undefined || (Array.isArray(security) && security.length === 0)).toBe(true);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Assert that all operations in a path item have required fields
|
|
66
|
-
*/
|
|
67
|
-
export function assertPathItemOperationsComplete(pathItem, requiredFields) {
|
|
68
|
-
Object.entries(pathItem).forEach(([, operation]) => {
|
|
69
|
-
requiredFields.forEach((field) => {
|
|
70
|
-
expect(operation[field]).toBeDefined();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Assert that a schema is properly structured with type and properties
|
|
76
|
-
*/
|
|
77
|
-
export function assertSchemaStructure(schema, expectedType = 'object') {
|
|
78
|
-
expect(schema.type).toBe(expectedType);
|
|
79
|
-
expect(schema.properties).toBeDefined();
|
|
80
|
-
expect(typeof schema.properties).toBe('object');
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Assert that a field is in the required array of a schema
|
|
84
|
-
*/
|
|
85
|
-
export function assertFieldRequired(schema, fieldName) {
|
|
86
|
-
const required = schema.required;
|
|
87
|
-
expect(required).toBeDefined();
|
|
88
|
-
expect(Array.isArray(required)).toBe(true);
|
|
89
|
-
expect(required).toContain(fieldName);
|
|
90
|
-
}
|
|
91
17
|
/**
|
|
92
18
|
* Assert that all paths have at least one operation defined (GET, POST, etc.)
|
|
93
19
|
*/
|
|
@@ -98,25 +24,4 @@ export function assertAllPathsHaveOperations(paths) {
|
|
|
98
24
|
expect(hasOperation).toBe(true);
|
|
99
25
|
});
|
|
100
26
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Assert that an HTTP response has expected status code and content type
|
|
103
|
-
* Common pattern from kaseki-api-routes.test.ts
|
|
104
|
-
*/
|
|
105
|
-
export function assertResponseStatus(response, expectedStatus, expectedContentType) {
|
|
106
|
-
expect(response.status).toBe(expectedStatus);
|
|
107
|
-
if (expectedContentType) {
|
|
108
|
-
const contentType = response.headers?.['content-type'] || response.get?.('content-type') || '';
|
|
109
|
-
expect(contentType).toContain(expectedContentType);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Assert that a JSON response body contains expected keys
|
|
114
|
-
* Reduces nested expect chains for object property checks
|
|
115
|
-
*/
|
|
116
|
-
export function assertJsonResponse(response, expectedKeys) {
|
|
117
|
-
const body = response.body ?? response.data ?? response;
|
|
118
|
-
expectedKeys.forEach((key) => {
|
|
119
|
-
expect(body).toHaveProperty(key);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
27
|
//# sourceMappingURL=api-client-assertions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client-assertions.js","sourceRoot":"","sources":["../../src/__test-utils/api-client-assertions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAA8C,EAC9C,QAAwF;IAExF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE;QACrD,MAAM,CAAC,OAAO,CAAC,QAAmC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE;YAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAoC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"api-client-assertions.js","sourceRoot":"","sources":["../../src/__test-utils/api-client-assertions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAA8C,EAC9C,QAAwF;IAExF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE;QACrD,MAAM,CAAC,OAAO,CAAC,QAAmC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE;YAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAoC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAA8C;IACzF,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAEjF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE;QAC7C,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC;QACtE,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentsBootstrapper - Creates and initializes the /agents directory structure
|
|
3
|
+
* Handles sudo fallback and sets proper permissions for container access
|
|
4
|
+
*/
|
|
5
|
+
import { ConfigManager } from '../../config/ConfigManager';
|
|
6
|
+
export interface BootstrapResult {
|
|
7
|
+
ok: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class AgentsBootstrapper {
|
|
12
|
+
private configManager;
|
|
13
|
+
constructor(configManager: ConfigManager);
|
|
14
|
+
/**
|
|
15
|
+
* Ensure /agents directory structure exists with proper permissions
|
|
16
|
+
*/
|
|
17
|
+
bootstrap(dryRun?: boolean): Promise<BootstrapResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Write configuration file to ~/.kaseki/config.json
|
|
20
|
+
*/
|
|
21
|
+
writeConfig(secrets: {
|
|
22
|
+
openrouterKeyFile?: {
|
|
23
|
+
filePath: string;
|
|
24
|
+
} | null;
|
|
25
|
+
githubAppIdFile?: {
|
|
26
|
+
filePath: string;
|
|
27
|
+
} | null;
|
|
28
|
+
githubAppClientIdFile?: {
|
|
29
|
+
filePath: string;
|
|
30
|
+
} | null;
|
|
31
|
+
githubAppPrivateKeyFile?: {
|
|
32
|
+
filePath: string;
|
|
33
|
+
} | null;
|
|
34
|
+
kasekiApiKeysFile?: {
|
|
35
|
+
filePath: string;
|
|
36
|
+
} | null;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Create directory, falling back to sudo if needed
|
|
40
|
+
*/
|
|
41
|
+
private createDirectoryWithSudoFallback;
|
|
42
|
+
/**
|
|
43
|
+
* Set ownership to CONTAINER_UID, falling back to sudo if needed
|
|
44
|
+
*/
|
|
45
|
+
private setOwnershipWithSudoFallback;
|
|
46
|
+
/**
|
|
47
|
+
* Set directory permissions, falling back to sudo if needed
|
|
48
|
+
*/
|
|
49
|
+
private setPermissionsWithSudoFallback;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=AgentsBootstrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentsBootstrapper.d.ts","sourceRoot":"","sources":["../../../src/cli/bootstrappers/AgentsBootstrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAQ3D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,kBAAkB;IAEjB,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEhD;;OAEG;IACG,SAAS,CAAC,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IA2ClE;;OAEG;IACG,WAAW,CACf,OAAO,EAAE;QACP,iBAAiB,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAChD,eAAe,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAC9C,qBAAqB,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACpD,uBAAuB,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACtD,iBAAiB,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;KACjD,GACA,OAAO,CAAC,IAAI,CAAC;IAuBhB;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAevC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAepC;;OAEG;IACH,OAAO,CAAC,8BAA8B;CAcvC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentsBootstrapper - Creates and initializes the /agents directory structure
|
|
3
|
+
* Handles sudo fallback and sets proper permissions for container access
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { spawnSync } from 'child_process';
|
|
10
|
+
import { createLogger } from '../../logger.js';
|
|
11
|
+
const logger = createLogger('agents-bootstrapper');
|
|
12
|
+
const AGENTS_SUBDIRS = ['kaseki-results', 'kaseki-runs', 'kaseki-cache'];
|
|
13
|
+
const CONTAINER_UID = 10000;
|
|
14
|
+
export class AgentsBootstrapper {
|
|
15
|
+
configManager;
|
|
16
|
+
// @ts-expect-error - configManager may be used in future extensions
|
|
17
|
+
constructor(configManager) {
|
|
18
|
+
this.configManager = configManager;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Ensure /agents directory structure exists with proper permissions
|
|
22
|
+
*/
|
|
23
|
+
async bootstrap(dryRun = false) {
|
|
24
|
+
// Check if already set up
|
|
25
|
+
const allReady = ['/agents', ...AGENTS_SUBDIRS.map((d) => `/agents/${d}`)].every((p) => existsSync(p));
|
|
26
|
+
if (allReady) {
|
|
27
|
+
logger.debug('/agents already initialized');
|
|
28
|
+
return { ok: true, message: '✓ /agents already set up' };
|
|
29
|
+
}
|
|
30
|
+
if (dryRun) {
|
|
31
|
+
logger.debug('[dry-run] would create /agents');
|
|
32
|
+
return { ok: true, message: '[dry-run] would create /agents with UID 10000 ownership' };
|
|
33
|
+
}
|
|
34
|
+
// Create directory structure
|
|
35
|
+
const dirsToCreate = ['/agents', ...AGENTS_SUBDIRS.map((d) => `/agents/${d}`)];
|
|
36
|
+
for (const dir of dirsToCreate) {
|
|
37
|
+
const result = this.createDirectoryWithSudoFallback(dir);
|
|
38
|
+
if (!result.ok) {
|
|
39
|
+
logger.error(`Failed to create ${dir}: ${result.error}`);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Set ownership to CONTAINER_UID
|
|
44
|
+
const ownershipResult = this.setOwnershipWithSudoFallback('/agents');
|
|
45
|
+
if (!ownershipResult.ok) {
|
|
46
|
+
logger.error(`Failed to set ownership: ${ownershipResult.error}`);
|
|
47
|
+
return ownershipResult;
|
|
48
|
+
}
|
|
49
|
+
// Set permissions
|
|
50
|
+
const permissionResult = this.setPermissionsWithSudoFallback('/agents');
|
|
51
|
+
if (!permissionResult.ok) {
|
|
52
|
+
logger.error(`Failed to set permissions: ${permissionResult.error}`);
|
|
53
|
+
return permissionResult;
|
|
54
|
+
}
|
|
55
|
+
logger.info('/agents bootstrap completed successfully');
|
|
56
|
+
return { ok: true, message: '✓ /agents created with UID 10000 ownership' };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Write configuration file to ~/.kaseki/config.json
|
|
60
|
+
*/
|
|
61
|
+
async writeConfig(secrets) {
|
|
62
|
+
const kasekiDir = path.join(os.homedir(), '.kaseki');
|
|
63
|
+
await fs.mkdir(kasekiDir, { recursive: true, mode: 0o700 });
|
|
64
|
+
const auth = {};
|
|
65
|
+
if (secrets.openrouterKeyFile)
|
|
66
|
+
auth.openrouter_api_key_file = secrets.openrouterKeyFile.filePath;
|
|
67
|
+
if (secrets.githubAppIdFile)
|
|
68
|
+
auth.github_app_id_file = secrets.githubAppIdFile.filePath;
|
|
69
|
+
if (secrets.githubAppClientIdFile)
|
|
70
|
+
auth.github_app_client_id_file = secrets.githubAppClientIdFile.filePath;
|
|
71
|
+
if (secrets.githubAppPrivateKeyFile)
|
|
72
|
+
auth.github_app_private_key_file = secrets.githubAppPrivateKeyFile.filePath;
|
|
73
|
+
const config = {
|
|
74
|
+
auth,
|
|
75
|
+
api: {
|
|
76
|
+
url: 'http://localhost:8080/api',
|
|
77
|
+
...(secrets.kasekiApiKeysFile ? { key_file: secrets.kasekiApiKeysFile.filePath } : {}),
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const configPath = path.join(kasekiDir, 'config.json');
|
|
81
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
82
|
+
logger.info(`Config written to ${configPath}`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create directory, falling back to sudo if needed
|
|
86
|
+
*/
|
|
87
|
+
createDirectoryWithSudoFallback(dir) {
|
|
88
|
+
const mkdirResult = spawnSync('mkdir', ['-p', dir], { stdio: 'pipe' });
|
|
89
|
+
if (mkdirResult.status === 0) {
|
|
90
|
+
return { ok: true };
|
|
91
|
+
}
|
|
92
|
+
// Try with sudo
|
|
93
|
+
const sudoResult = spawnSync('sudo', ['mkdir', '-p', dir], { stdio: 'inherit' });
|
|
94
|
+
if (sudoResult.status === 0) {
|
|
95
|
+
return { ok: true };
|
|
96
|
+
}
|
|
97
|
+
return { ok: false, error: `Failed to create directory: ${dir}` };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Set ownership to CONTAINER_UID, falling back to sudo if needed
|
|
101
|
+
*/
|
|
102
|
+
setOwnershipWithSudoFallback(dir) {
|
|
103
|
+
const chownResult = spawnSync('chown', ['-R', `${CONTAINER_UID}:${CONTAINER_UID}`, dir], { stdio: 'pipe' });
|
|
104
|
+
if (chownResult.status === 0) {
|
|
105
|
+
return { ok: true };
|
|
106
|
+
}
|
|
107
|
+
// Try with sudo
|
|
108
|
+
const sudoResult = spawnSync('sudo', ['chown', '-R', `${CONTAINER_UID}:${CONTAINER_UID}`, dir], { stdio: 'inherit' });
|
|
109
|
+
if (sudoResult.status === 0) {
|
|
110
|
+
return { ok: true };
|
|
111
|
+
}
|
|
112
|
+
return { ok: false, error: 'Failed to set ownership on /agents' };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set directory permissions, falling back to sudo if needed
|
|
116
|
+
*/
|
|
117
|
+
setPermissionsWithSudoFallback(dir) {
|
|
118
|
+
const chmodResult = spawnSync('chmod', ['755', dir], { stdio: 'pipe' });
|
|
119
|
+
if (chmodResult.status === 0) {
|
|
120
|
+
return { ok: true };
|
|
121
|
+
}
|
|
122
|
+
// Try with sudo
|
|
123
|
+
const sudoResult = spawnSync('sudo', ['chmod', '755', dir], { stdio: 'inherit' });
|
|
124
|
+
if (sudoResult.status === 0) {
|
|
125
|
+
return { ok: true };
|
|
126
|
+
}
|
|
127
|
+
return { ok: false, error: 'Failed to set permissions on /agents' };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=AgentsBootstrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentsBootstrapper.js","sourceRoot":"","sources":["../../../src/cli/bootstrappers/AgentsBootstrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,23 +6,19 @@
|
|
|
6
6
|
* 2. Discover secrets at well-known locations
|
|
7
7
|
* 3. Write ~/.kaseki/config.json
|
|
8
8
|
* 4. Bootstrap /agents (with sudo if needed)
|
|
9
|
-
* 5. Start kaseki-api via docker
|
|
9
|
+
* 5. Start kaseki-api via docker (or docker run fallback)
|
|
10
10
|
* 6. Wait for /ready body to confirm the API is truly ready
|
|
11
11
|
* 7. Smoke-test the authenticated /api/runs endpoint
|
|
12
12
|
*/
|
|
13
13
|
import { BaseCommand } from '../BaseCommand';
|
|
14
|
+
import { ConfigManager } from '../../config/ConfigManager';
|
|
14
15
|
export declare class QuickstartCommand extends BaseCommand {
|
|
16
|
+
private environmentValidator;
|
|
17
|
+
private secretResolver;
|
|
18
|
+
private agentsBootstrapper;
|
|
19
|
+
private containerLauncher;
|
|
20
|
+
constructor(configManager: ConfigManager);
|
|
15
21
|
execute(args: string[]): Promise<number>;
|
|
16
|
-
private detectEnvironment;
|
|
17
|
-
private printEnvSummary;
|
|
18
|
-
private discoverSecrets;
|
|
19
|
-
private printSecretsSummary;
|
|
20
|
-
private writeConfig;
|
|
21
|
-
private bootstrapAgentsDir;
|
|
22
|
-
private startContainer;
|
|
23
|
-
private readApiKey;
|
|
24
|
-
private waitForReady;
|
|
25
|
-
private smokeTest;
|
|
26
22
|
private printSuccess;
|
|
27
23
|
private printHelp;
|
|
28
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuickstartCommand.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/QuickstartCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"QuickstartCommand.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/QuickstartCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAS3D,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,iBAAiB,CAAoB;gBAEjC,aAAa,EAAE,aAAa;IAQlC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAuI9C,OAAO,CAAC,YAAY;IA2BpB,OAAO,CAAC,SAAS;CA4BlB"}
|