@swarm-agent/sdk 0.1.47
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/APPLICATIONS.md +133 -0
- package/HEADLESS_UI.md +97 -0
- package/LICENSE +201 -0
- package/README.md +473 -0
- package/dist/app-results.d.ts +24 -0
- package/dist/app-results.js +167 -0
- package/dist/apps.d.ts +82 -0
- package/dist/apps.js +89 -0
- package/dist/auth.d.ts +45 -0
- package/dist/auth.js +89 -0
- package/dist/automations.d.ts +74 -0
- package/dist/automations.js +159 -0
- package/dist/client.d.ts +61 -0
- package/dist/client.js +103 -0
- package/dist/deliverables.d.ts +42 -0
- package/dist/deliverables.js +83 -0
- package/dist/deploy/dockerfile.d.ts +14 -0
- package/dist/deploy/dockerfile.js +14 -0
- package/dist/deploy/index.d.ts +67 -0
- package/dist/deploy/index.js +226 -0
- package/dist/deploy/manifest.d.ts +17 -0
- package/dist/deploy/manifest.js +220 -0
- package/dist/deploy/providers/gcp-cloud-run.d.ts +9 -0
- package/dist/deploy/providers/gcp-cloud-run.js +12 -0
- package/dist/deploy/providers/gcp-compute.d.ts +9 -0
- package/dist/deploy/providers/gcp-compute.js +12 -0
- package/dist/deploy/types.d.ts +211 -0
- package/dist/deploy/types.js +4 -0
- package/dist/deploy/worker-cloud-deployer.d.ts +33 -0
- package/dist/deploy/worker-cloud-deployer.js +14 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.js +68 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +20 -0
- package/dist/notifications.d.ts +28 -0
- package/dist/notifications.js +65 -0
- package/dist/projects.d.ts +147 -0
- package/dist/projects.js +513 -0
- package/dist/provider-auth.d.ts +160 -0
- package/dist/provider-auth.js +54 -0
- package/dist/realtime.d.ts +240 -0
- package/dist/realtime.js +312 -0
- package/dist/sessions.d.ts +60 -0
- package/dist/sessions.js +194 -0
- package/dist/settings.d.ts +85 -0
- package/dist/settings.js +26 -0
- package/dist/storage/adapters/memory.d.ts +13 -0
- package/dist/storage/adapters/memory.js +35 -0
- package/dist/storage/adapters/s3.d.ts +31 -0
- package/dist/storage/adapters/s3.js +171 -0
- package/dist/storage/client.d.ts +174 -0
- package/dist/storage/client.js +121 -0
- package/dist/storage/hub.d.ts +30 -0
- package/dist/storage/hub.js +372 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.js +6 -0
- package/dist/storage/runner.d.ts +48 -0
- package/dist/storage/runner.js +233 -0
- package/dist/storage/types.d.ts +198 -0
- package/dist/storage/types.js +1 -0
- package/dist/system.d.ts +14 -0
- package/dist/system.js +52 -0
- package/dist/transport.d.ts +17 -0
- package/dist/transport.js +243 -0
- package/dist/types.d.ts +1137 -0
- package/dist/types.js +1 -0
- package/dist/usage.d.ts +106 -0
- package/dist/usage.js +82 -0
- package/dist/workers.d.ts +146 -0
- package/dist/workers.js +822 -0
- package/dist/workspaces.d.ts +81 -0
- package/dist/workspaces.js +58 -0
- package/examples/headless-session.ts +85 -0
- package/package.json +56 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { SwarmAppsNamespace } from './apps.js';
|
|
2
|
+
import { SwarmSettingsNamespace } from './settings.js';
|
|
3
|
+
import { SwarmOnboardingNamespace } from './provider-auth.js';
|
|
4
|
+
import { SwarmRealtimeNamespace } from './realtime.js';
|
|
5
|
+
import { SwarmUsageNamespace } from './usage.js';
|
|
6
|
+
import { SwarmAuthNamespace } from './auth.js';
|
|
7
|
+
import { SwarmAutomationsNamespace } from './automations.js';
|
|
8
|
+
import { SwarmWorkersNamespace } from './workers.js';
|
|
9
|
+
import { SwarmDeliverablesNamespace } from './deliverables.js';
|
|
10
|
+
import { SwarmDeployNamespace } from './deploy/index.js';
|
|
11
|
+
import { SwarmNotificationsNamespace } from './notifications.js';
|
|
12
|
+
import { SwarmProjectsNamespace } from './projects.js';
|
|
13
|
+
import { SwarmSessionsNamespace } from './sessions.js';
|
|
14
|
+
import { SwarmSystemNamespace } from './system.js';
|
|
15
|
+
import { SwarmStorageNamespace } from './storage/index.js';
|
|
16
|
+
import { SwarmTransport } from './transport.js';
|
|
17
|
+
import { SwarmWorkspacesNamespace } from './workspaces.js';
|
|
18
|
+
export class SwarmClient {
|
|
19
|
+
config;
|
|
20
|
+
transport;
|
|
21
|
+
auth;
|
|
22
|
+
settings;
|
|
23
|
+
onboarding;
|
|
24
|
+
realtime;
|
|
25
|
+
/**
|
|
26
|
+
* Legacy automations namespace targeting /v3/automations/v2.
|
|
27
|
+
* Note: This is legacy automation API, not the canonical durable worker identity authority.
|
|
28
|
+
*/
|
|
29
|
+
automations;
|
|
30
|
+
/**
|
|
31
|
+
* Canonical durable worker namespace managing account-owned workers,
|
|
32
|
+
* revisions, attached automations, and portable import/export definitions over /v3/workers.
|
|
33
|
+
*/
|
|
34
|
+
workers;
|
|
35
|
+
usage;
|
|
36
|
+
deliverables;
|
|
37
|
+
/** Convenient alias for deliverables namespace: mailbox */
|
|
38
|
+
mailbox;
|
|
39
|
+
workspaces;
|
|
40
|
+
projects;
|
|
41
|
+
sessions;
|
|
42
|
+
apps;
|
|
43
|
+
system;
|
|
44
|
+
deploy;
|
|
45
|
+
notifications;
|
|
46
|
+
/** Convenient alias for notifications namespace: inbox */
|
|
47
|
+
inbox;
|
|
48
|
+
storage;
|
|
49
|
+
/** Convenient alias for cloud storage connections: cloud */
|
|
50
|
+
cloud;
|
|
51
|
+
constructor(config = {}) {
|
|
52
|
+
const env = typeof process !== 'undefined' && process?.env ? process.env : {};
|
|
53
|
+
const baseUrl = config.baseUrl ||
|
|
54
|
+
env.SWARM_API_URL ||
|
|
55
|
+
env.SWARM_DESKTOP_URL ||
|
|
56
|
+
'http://127.0.0.1:18080';
|
|
57
|
+
const socketPath = config.socketPath || env.SWARM_SOCKET_PATH;
|
|
58
|
+
const token = config.token || env.SWARM_AUTH_TOKEN || env.SWARM_DEPLOY_TOKEN;
|
|
59
|
+
const resolved = {
|
|
60
|
+
baseUrl: baseUrl.replace(/\/+$/, ''),
|
|
61
|
+
token,
|
|
62
|
+
socketPath,
|
|
63
|
+
defaultHeaders: config.defaultHeaders ?? {},
|
|
64
|
+
timeoutMs: config.timeoutMs ?? 30_000,
|
|
65
|
+
};
|
|
66
|
+
this.transport = new SwarmTransport(resolved);
|
|
67
|
+
this.config = this.transport.getConfig();
|
|
68
|
+
this.auth = new SwarmAuthNamespace(this.transport, (token) => {
|
|
69
|
+
this.config.token = token;
|
|
70
|
+
});
|
|
71
|
+
this.settings = new SwarmSettingsNamespace(this.transport);
|
|
72
|
+
this.onboarding = new SwarmOnboardingNamespace(this.transport);
|
|
73
|
+
this.realtime = new SwarmRealtimeNamespace(this.transport);
|
|
74
|
+
this.automations = new SwarmAutomationsNamespace(this.transport);
|
|
75
|
+
this.workers = new SwarmWorkersNamespace(this.transport);
|
|
76
|
+
this.usage = new SwarmUsageNamespace(this.transport);
|
|
77
|
+
this.deliverables = new SwarmDeliverablesNamespace(this.transport);
|
|
78
|
+
this.mailbox = this.deliverables;
|
|
79
|
+
this.workspaces = new SwarmWorkspacesNamespace(this.transport);
|
|
80
|
+
this.projects = new SwarmProjectsNamespace(this.transport);
|
|
81
|
+
this.sessions = new SwarmSessionsNamespace(this.transport);
|
|
82
|
+
this.apps = new SwarmAppsNamespace(this.transport);
|
|
83
|
+
this.system = new SwarmSystemNamespace(this.transport);
|
|
84
|
+
this.deploy = new SwarmDeployNamespace(this.transport);
|
|
85
|
+
this.notifications = new SwarmNotificationsNamespace(this.transport);
|
|
86
|
+
this.inbox = this.notifications;
|
|
87
|
+
this.storage = new SwarmStorageNamespace(this.transport);
|
|
88
|
+
this.cloud = this.storage;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Updates the bearer authentication token for all subsequent client requests.
|
|
92
|
+
*/
|
|
93
|
+
setToken(token) {
|
|
94
|
+
this.transport.setConfig({ token });
|
|
95
|
+
this.config.token = token;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Factory function to create a new SwarmClient instance.
|
|
100
|
+
*/
|
|
101
|
+
export function createSwarmClient(config) {
|
|
102
|
+
return new SwarmClient(config);
|
|
103
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SwarmTransport } from './transport.js';
|
|
2
|
+
import type { CreateDeliverableParams, DeliverableFilter, DeliverableRecord } from './types.js';
|
|
3
|
+
export declare class SwarmDeliverablesNamespace {
|
|
4
|
+
private readonly transport;
|
|
5
|
+
constructor(transport: SwarmTransport);
|
|
6
|
+
/**
|
|
7
|
+
* Submits a new deliverable (e.g. social post batch, alert, report, PR draft) to the Agent Mailbox.
|
|
8
|
+
*/
|
|
9
|
+
submit(params: CreateDeliverableParams): Promise<DeliverableRecord>;
|
|
10
|
+
/**
|
|
11
|
+
* Lists deliverables across the account, optionally filtered by status, worker, kind, or workspace.
|
|
12
|
+
*/
|
|
13
|
+
list(filter?: DeliverableFilter): Promise<DeliverableRecord[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Fetches a single deliverable by ID.
|
|
16
|
+
*/
|
|
17
|
+
get(id: string): Promise<DeliverableRecord>;
|
|
18
|
+
/**
|
|
19
|
+
* Approves a deliverable, triggering any linked publication action (e.g. publish to X, webhook).
|
|
20
|
+
*/
|
|
21
|
+
approve(id: string, params?: {
|
|
22
|
+
parameters?: Record<string, unknown>;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
deliverable: DeliverableRecord;
|
|
25
|
+
action_result?: Record<string, unknown>;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Dismisses a pending deliverable without executing its publication action.
|
|
29
|
+
*/
|
|
30
|
+
dismiss(id: string): Promise<DeliverableRecord>;
|
|
31
|
+
/**
|
|
32
|
+
* Requests changes on a deliverable, sending it back to the worker with feedback notes and optional tags.
|
|
33
|
+
*/
|
|
34
|
+
requestChanges(id: string, params: {
|
|
35
|
+
notes: string;
|
|
36
|
+
tags?: string[];
|
|
37
|
+
}): Promise<DeliverableRecord>;
|
|
38
|
+
/**
|
|
39
|
+
* Deletes a deliverable permanently from the mailbox.
|
|
40
|
+
*/
|
|
41
|
+
delete(id: string): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export class SwarmDeliverablesNamespace {
|
|
2
|
+
transport;
|
|
3
|
+
constructor(transport) {
|
|
4
|
+
this.transport = transport;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Submits a new deliverable (e.g. social post batch, alert, report, PR draft) to the Agent Mailbox.
|
|
8
|
+
*/
|
|
9
|
+
async submit(params) {
|
|
10
|
+
const res = await this.transport.request('/v3/deliverables', {
|
|
11
|
+
method: 'POST',
|
|
12
|
+
body: params,
|
|
13
|
+
});
|
|
14
|
+
return res.data.deliverable;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Lists deliverables across the account, optionally filtered by status, worker, kind, or workspace.
|
|
18
|
+
*/
|
|
19
|
+
async list(filter = {}) {
|
|
20
|
+
const q = new URLSearchParams();
|
|
21
|
+
if (filter.status)
|
|
22
|
+
q.set('status', filter.status);
|
|
23
|
+
if (filter.worker_id)
|
|
24
|
+
q.set('worker_id', filter.worker_id);
|
|
25
|
+
if (filter.kind)
|
|
26
|
+
q.set('kind', filter.kind);
|
|
27
|
+
if (filter.workspace_id)
|
|
28
|
+
q.set('workspace_id', filter.workspace_id);
|
|
29
|
+
if (typeof filter.limit === 'number')
|
|
30
|
+
q.set('limit', String(filter.limit));
|
|
31
|
+
const path = q.toString() ? `/v3/deliverables?${q.toString()}` : '/v3/deliverables';
|
|
32
|
+
const res = await this.transport.request(path, {
|
|
33
|
+
method: 'GET',
|
|
34
|
+
});
|
|
35
|
+
return res.data.deliverables || [];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Fetches a single deliverable by ID.
|
|
39
|
+
*/
|
|
40
|
+
async get(id) {
|
|
41
|
+
const res = await this.transport.request(`/v3/deliverables/${encodeURIComponent(id)}`, {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
});
|
|
44
|
+
return res.data.deliverable;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Approves a deliverable, triggering any linked publication action (e.g. publish to X, webhook).
|
|
48
|
+
*/
|
|
49
|
+
async approve(id, params = {}) {
|
|
50
|
+
const res = await this.transport.request(`/v3/deliverables/${encodeURIComponent(id)}/approve`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
body: params,
|
|
53
|
+
});
|
|
54
|
+
return res.data;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Dismisses a pending deliverable without executing its publication action.
|
|
58
|
+
*/
|
|
59
|
+
async dismiss(id) {
|
|
60
|
+
const res = await this.transport.request(`/v3/deliverables/${encodeURIComponent(id)}/dismiss`, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
});
|
|
63
|
+
return res.data.deliverable;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Requests changes on a deliverable, sending it back to the worker with feedback notes and optional tags.
|
|
67
|
+
*/
|
|
68
|
+
async requestChanges(id, params) {
|
|
69
|
+
const res = await this.transport.request(`/v3/deliverables/${encodeURIComponent(id)}/request_changes`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
body: params,
|
|
72
|
+
});
|
|
73
|
+
return res.data.deliverable;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Deletes a deliverable permanently from the mailbox.
|
|
77
|
+
*/
|
|
78
|
+
async delete(id) {
|
|
79
|
+
await this.transport.request(`/v3/deliverables/${encodeURIComponent(id)}`, {
|
|
80
|
+
method: 'DELETE',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BuildStrategy, SourceConfig } from './types.js';
|
|
2
|
+
export interface DockerfileOptions {
|
|
3
|
+
/** Required qualified release manifest image, never a mutable tag. */
|
|
4
|
+
runtimeImage?: string;
|
|
5
|
+
/** Legacy source-build options are rejected, not silently ignored. */
|
|
6
|
+
source?: SourceConfig;
|
|
7
|
+
port?: number;
|
|
8
|
+
strategy?: BuildStrategy;
|
|
9
|
+
goVersion?: string;
|
|
10
|
+
packagePath?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Consume the canonical CGO/glibc/FFF runtime; never rebuild the daemon here. */
|
|
13
|
+
export declare function generateOptimizedDockerfile(options?: DockerfileOptions): string;
|
|
14
|
+
export declare function generateDockerIgnore(): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SwarmValidationError } from '../errors.js';
|
|
2
|
+
/** Consume the canonical CGO/glibc/FFF runtime; never rebuild the daemon here. */
|
|
3
|
+
export function generateOptimizedDockerfile(options = {}) {
|
|
4
|
+
if (options.source || options.strategy || options.goVersion || options.packagePath || options.port !== undefined) {
|
|
5
|
+
throw new SwarmValidationError('Source builds and listener overrides are unsupported. Use the qualified runtimeImage and the private application recipe.');
|
|
6
|
+
}
|
|
7
|
+
if (!/^ghcr\.io\/swarm-agent\/swarm-headless@sha256:[a-f0-9]{64}$/.test(options.runtimeImage ?? '')) {
|
|
8
|
+
throw new SwarmValidationError('runtimeImage must be ghcr.io/swarm-agent/swarm-headless@sha256:<64 lowercase hex characters> from the qualified release manifest.');
|
|
9
|
+
}
|
|
10
|
+
return `# Canonical runtime; inherits non-root identity, private listeners and durable volumes.\nFROM ${options.runtimeImage}\n`;
|
|
11
|
+
}
|
|
12
|
+
export function generateDockerIgnore() {
|
|
13
|
+
return `.git\n.github\nnode_modules\n**/node_modules\n*.log\n*.tmp\n.env\n.env.*\n*.sock\ntmp\n.vscode\n.idea\n`;
|
|
14
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment namespace and multi-cloud providers for Swarm.
|
|
3
|
+
*/
|
|
4
|
+
import type { SwarmTransport } from '../transport.js';
|
|
5
|
+
import type { CloudDeployProvider, CloudTarget, CreateManifestOptions, DeployCommand, DeployExecutionResult, DeployPlan, ExecuteDeployOptions, SwarmDeployManifest, ValidationResult } from './types.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './manifest.js';
|
|
8
|
+
export * from './dockerfile.js';
|
|
9
|
+
export * from './providers/gcp-cloud-run.js';
|
|
10
|
+
export * from './providers/gcp-compute.js';
|
|
11
|
+
export * from './worker-cloud-deployer.js';
|
|
12
|
+
export declare class SwarmDeployNamespace {
|
|
13
|
+
protected readonly transport?: SwarmTransport | undefined;
|
|
14
|
+
private readonly providers;
|
|
15
|
+
constructor(transport?: SwarmTransport | undefined);
|
|
16
|
+
/**
|
|
17
|
+
* Registers a new cloud deployment provider (extensible for AWS, Azure, Fly.io, etc.).
|
|
18
|
+
*/
|
|
19
|
+
registerProvider(provider: CloudDeployProvider): void;
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves the deployment provider registered for a target platform.
|
|
22
|
+
*/
|
|
23
|
+
getProvider(target: CloudTarget): CloudDeployProvider;
|
|
24
|
+
/**
|
|
25
|
+
* Returns all currently registered cloud deployment providers.
|
|
26
|
+
*/
|
|
27
|
+
listProviders(): CloudDeployProvider[];
|
|
28
|
+
/**
|
|
29
|
+
* Creates a typed deployment manifest using proven best-practice presets.
|
|
30
|
+
*/
|
|
31
|
+
createManifest(options?: CreateManifestOptions): SwarmDeployManifest;
|
|
32
|
+
/**
|
|
33
|
+
* Parses, resolves environment variables, and validates a deployment manifest.
|
|
34
|
+
*/
|
|
35
|
+
loadManifest(input: string | Record<string, unknown>, envLookup?: Record<string, string>): SwarmDeployManifest;
|
|
36
|
+
/**
|
|
37
|
+
* Serializes a manifest to formatted JSON.
|
|
38
|
+
*/
|
|
39
|
+
serializeManifest(manifest: SwarmDeployManifest, indent?: number): string;
|
|
40
|
+
/**
|
|
41
|
+
* Validates a deployment manifest against its target provider rules.
|
|
42
|
+
*/
|
|
43
|
+
validate(manifest: SwarmDeployManifest): ValidationResult;
|
|
44
|
+
/**
|
|
45
|
+
* Generates a complete, structured deployment plan including artifacts, shell commands, and cost estimates.
|
|
46
|
+
*/
|
|
47
|
+
plan(input: SwarmDeployManifest | CreateManifestOptions | string | Record<string, unknown>): DeployPlan;
|
|
48
|
+
/**
|
|
49
|
+
* Generates all required deployment artifacts (Dockerfile, scripts, config files) as a key-value record.
|
|
50
|
+
*/
|
|
51
|
+
generateArtifacts(input: SwarmDeployManifest | CreateManifestOptions | string | Record<string, unknown>): Record<string, string>;
|
|
52
|
+
/**
|
|
53
|
+
* Generates sequential shell commands required to execute the build and deployment.
|
|
54
|
+
*/
|
|
55
|
+
generateCommands(input: SwarmDeployManifest | CreateManifestOptions | string | Record<string, unknown>): DeployCommand[];
|
|
56
|
+
/**
|
|
57
|
+
* Writes all generated deployment artifacts to a target directory on disk.
|
|
58
|
+
*/
|
|
59
|
+
writeArtifacts(targetDir: string, input: SwarmDeployManifest | CreateManifestOptions | string | Record<string, unknown> | DeployPlan): Promise<string[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Programmatically executes the deployment plan.
|
|
62
|
+
* In dryRun mode, validates prerequisites, writes artifacts, and simulates command execution.
|
|
63
|
+
* In live mode, executes sequential pipeline commands and verifies service reachability.
|
|
64
|
+
*/
|
|
65
|
+
execute(input: SwarmDeployManifest | CreateManifestOptions | string | Record<string, unknown> | DeployPlan, options?: ExecuteDeployOptions): Promise<DeployExecutionResult>;
|
|
66
|
+
private ensureManifest;
|
|
67
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment namespace and multi-cloud providers for Swarm.
|
|
3
|
+
*/
|
|
4
|
+
import { SwarmNotFoundError, SwarmValidationError } from '../errors.js';
|
|
5
|
+
import { createDeployManifest, loadDeployManifest, serializeDeployManifest } from './manifest.js';
|
|
6
|
+
import { GcpCloudRunProvider } from './providers/gcp-cloud-run.js';
|
|
7
|
+
import { GcpComputeEngineProvider } from './providers/gcp-compute.js';
|
|
8
|
+
export * from './types.js';
|
|
9
|
+
export * from './manifest.js';
|
|
10
|
+
export * from './dockerfile.js';
|
|
11
|
+
export * from './providers/gcp-cloud-run.js';
|
|
12
|
+
export * from './providers/gcp-compute.js';
|
|
13
|
+
export * from './worker-cloud-deployer.js';
|
|
14
|
+
export class SwarmDeployNamespace {
|
|
15
|
+
transport;
|
|
16
|
+
providers = new Map();
|
|
17
|
+
constructor(transport) {
|
|
18
|
+
this.transport = transport;
|
|
19
|
+
// Register default providers
|
|
20
|
+
this.registerProvider(new GcpCloudRunProvider());
|
|
21
|
+
this.registerProvider(new GcpComputeEngineProvider());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Registers a new cloud deployment provider (extensible for AWS, Azure, Fly.io, etc.).
|
|
25
|
+
*/
|
|
26
|
+
registerProvider(provider) {
|
|
27
|
+
this.providers.set(provider.target, provider);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the deployment provider registered for a target platform.
|
|
31
|
+
*/
|
|
32
|
+
getProvider(target) {
|
|
33
|
+
const provider = this.providers.get(target);
|
|
34
|
+
if (!provider) {
|
|
35
|
+
const available = Array.from(this.providers.keys()).join(', ');
|
|
36
|
+
throw new SwarmNotFoundError(`No deployment provider registered for target '${target}'. Available targets: ${available}`, { code: 'PROVIDER_NOT_FOUND' });
|
|
37
|
+
}
|
|
38
|
+
return provider;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns all currently registered cloud deployment providers.
|
|
42
|
+
*/
|
|
43
|
+
listProviders() {
|
|
44
|
+
return Array.from(this.providers.values());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a typed deployment manifest using proven best-practice presets.
|
|
48
|
+
*/
|
|
49
|
+
createManifest(options) {
|
|
50
|
+
return createDeployManifest(options);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parses, resolves environment variables, and validates a deployment manifest.
|
|
54
|
+
*/
|
|
55
|
+
loadManifest(input, envLookup) {
|
|
56
|
+
return loadDeployManifest(input, envLookup);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Serializes a manifest to formatted JSON.
|
|
60
|
+
*/
|
|
61
|
+
serializeManifest(manifest, indent = 2) {
|
|
62
|
+
return serializeDeployManifest(manifest, indent);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validates a deployment manifest against its target provider rules.
|
|
66
|
+
*/
|
|
67
|
+
validate(manifest) {
|
|
68
|
+
const provider = this.getProvider(manifest.target);
|
|
69
|
+
return provider.validate(manifest);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generates a complete, structured deployment plan including artifacts, shell commands, and cost estimates.
|
|
73
|
+
*/
|
|
74
|
+
plan(input) {
|
|
75
|
+
const manifest = this.ensureManifest(input);
|
|
76
|
+
const provider = this.getProvider(manifest.target);
|
|
77
|
+
return provider.plan(manifest);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Generates all required deployment artifacts (Dockerfile, scripts, config files) as a key-value record.
|
|
81
|
+
*/
|
|
82
|
+
generateArtifacts(input) {
|
|
83
|
+
const manifest = this.ensureManifest(input);
|
|
84
|
+
const provider = this.getProvider(manifest.target);
|
|
85
|
+
return provider.generateArtifacts(manifest);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Generates sequential shell commands required to execute the build and deployment.
|
|
89
|
+
*/
|
|
90
|
+
generateCommands(input) {
|
|
91
|
+
const manifest = this.ensureManifest(input);
|
|
92
|
+
const provider = this.getProvider(manifest.target);
|
|
93
|
+
return provider.generateCommands(manifest);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Writes all generated deployment artifacts to a target directory on disk.
|
|
97
|
+
*/
|
|
98
|
+
async writeArtifacts(targetDir, input) {
|
|
99
|
+
const plan = typeof input === 'object' && input !== null && 'artifacts' in input
|
|
100
|
+
? input
|
|
101
|
+
: this.plan(input);
|
|
102
|
+
const validation = this.validate(plan.manifest);
|
|
103
|
+
if (!validation.valid)
|
|
104
|
+
throw new SwarmValidationError(validation.errors.join('; '));
|
|
105
|
+
const modFs = 'node:fs';
|
|
106
|
+
const modPath = 'node:path';
|
|
107
|
+
const fs = await import(modFs);
|
|
108
|
+
const path = await import(modPath);
|
|
109
|
+
await fs.promises.mkdir(targetDir, { recursive: true });
|
|
110
|
+
const writtenFiles = [];
|
|
111
|
+
for (const [filename, content] of Object.entries(plan.artifacts)) {
|
|
112
|
+
const filePath = path.join(targetDir, filename);
|
|
113
|
+
await fs.promises.writeFile(filePath, content, 'utf8');
|
|
114
|
+
if (filename.endsWith('.sh')) {
|
|
115
|
+
await fs.promises.chmod(filePath, 0o755).catch(() => { });
|
|
116
|
+
}
|
|
117
|
+
writtenFiles.push(filePath);
|
|
118
|
+
}
|
|
119
|
+
return writtenFiles;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Programmatically executes the deployment plan.
|
|
123
|
+
* In dryRun mode, validates prerequisites, writes artifacts, and simulates command execution.
|
|
124
|
+
* In live mode, executes sequential pipeline commands and verifies service reachability.
|
|
125
|
+
*/
|
|
126
|
+
async execute(input, options = {}) {
|
|
127
|
+
const startTime = Date.now();
|
|
128
|
+
const plan = typeof input === 'object' && input !== null && 'artifacts' in input
|
|
129
|
+
? input
|
|
130
|
+
: this.plan(input);
|
|
131
|
+
const validation = this.validate(plan.manifest);
|
|
132
|
+
if (!validation.valid)
|
|
133
|
+
throw new SwarmValidationError(validation.errors.join('; '));
|
|
134
|
+
const modFs = 'node:fs';
|
|
135
|
+
const modPath = 'node:path';
|
|
136
|
+
const modOs = 'node:os';
|
|
137
|
+
const modCp = 'node:child_process';
|
|
138
|
+
const modUtil = 'node:util';
|
|
139
|
+
const fs = await import(modFs);
|
|
140
|
+
const path = await import(modPath);
|
|
141
|
+
const os = await import(modOs);
|
|
142
|
+
const { exec } = await import(modCp);
|
|
143
|
+
const { promisify } = await import(modUtil);
|
|
144
|
+
const execAsync = promisify(exec);
|
|
145
|
+
const targetDir = options.outputDir || (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'swarm-deploy-')));
|
|
146
|
+
await this.writeArtifacts(targetDir, plan);
|
|
147
|
+
const stepOutputs = {};
|
|
148
|
+
let serviceUrl;
|
|
149
|
+
let externalIp;
|
|
150
|
+
if (options.dryRun) {
|
|
151
|
+
for (const cmd of plan.commands) {
|
|
152
|
+
options.onLog?.(`[DRY RUN] [${cmd.phase}] ${cmd.title}: ${cmd.command}`, cmd.phase);
|
|
153
|
+
stepOutputs[cmd.title] = `(simulated: ${cmd.command})`;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
target: plan.target,
|
|
158
|
+
durationMs: Date.now() - startTime,
|
|
159
|
+
stepOutputs,
|
|
160
|
+
outputDir: targetDir,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
for (const cmd of plan.commands) {
|
|
165
|
+
// Skip cleanup step during initial deployment execution
|
|
166
|
+
if (cmd.phase === 'cleanup') {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
options.onLog?.(`[${cmd.phase}] ${cmd.title}...`, cmd.phase);
|
|
170
|
+
const procEnv = typeof process !== 'undefined' ? process.env : {};
|
|
171
|
+
const execEnv = {
|
|
172
|
+
...procEnv,
|
|
173
|
+
...(options.env || {}),
|
|
174
|
+
};
|
|
175
|
+
const { stdout, stderr } = await execAsync(cmd.command, {
|
|
176
|
+
cwd: targetDir,
|
|
177
|
+
env: execEnv,
|
|
178
|
+
timeout: 600_000,
|
|
179
|
+
});
|
|
180
|
+
const output = (stdout + (stderr ? `\n${stderr}` : '')).trim();
|
|
181
|
+
stepOutputs[cmd.title] = output;
|
|
182
|
+
options.onLog?.(output, cmd.phase);
|
|
183
|
+
// Extract Cloud Run URL or Compute NAT IP if present
|
|
184
|
+
const urlMatch = output.match(/https:\/\/[a-z0-9-]+\.[a-z0-9.-]+\.run\.app/i);
|
|
185
|
+
if (urlMatch) {
|
|
186
|
+
serviceUrl = urlMatch[0];
|
|
187
|
+
}
|
|
188
|
+
const ipMatch = output.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/);
|
|
189
|
+
if (ipMatch && plan.target === 'gcp-compute-engine' && cmd.phase === 'verify') {
|
|
190
|
+
externalIp = ipMatch[0];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
target: plan.target,
|
|
196
|
+
durationMs: Date.now() - startTime,
|
|
197
|
+
stepOutputs,
|
|
198
|
+
serviceUrl,
|
|
199
|
+
externalIp,
|
|
200
|
+
outputDir: targetDir,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
target: plan.target,
|
|
207
|
+
durationMs: Date.now() - startTime,
|
|
208
|
+
stepOutputs,
|
|
209
|
+
outputDir: targetDir,
|
|
210
|
+
error: err.message || String(err),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
ensureManifest(input) {
|
|
215
|
+
if (typeof input === 'string') {
|
|
216
|
+
return this.loadManifest(input);
|
|
217
|
+
}
|
|
218
|
+
if (typeof input === 'object' && input !== null) {
|
|
219
|
+
if ('version' in input && input.version === '1.0' && 'target' in input && 'source' in input) {
|
|
220
|
+
return input;
|
|
221
|
+
}
|
|
222
|
+
return this.createManifest(input);
|
|
223
|
+
}
|
|
224
|
+
return this.createManifest();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest parsing, creation, and resolution for Swarm deployments.
|
|
3
|
+
*/
|
|
4
|
+
import type { CreateManifestOptions, SwarmDeployManifest } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a well-formed SwarmDeployManifest using proven best-practice presets.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createDeployManifest(options?: CreateManifestOptions): SwarmDeployManifest;
|
|
9
|
+
/**
|
|
10
|
+
* Loads, validates, and resolves a SwarmDeployManifest from a JSON string or raw object.
|
|
11
|
+
* Automatically expands ${VAR_NAME} placeholders using environment variables or optional dictionary.
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadDeployManifest(input: string | Record<string, unknown>, envLookup?: Record<string, string>): SwarmDeployManifest;
|
|
14
|
+
/**
|
|
15
|
+
* Serializes a deployment manifest to formatted JSON.
|
|
16
|
+
*/
|
|
17
|
+
export declare function serializeDeployManifest(manifest: SwarmDeployManifest, indent?: number): string;
|