@amalgm/apps 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/PURPOSE.md +98 -0
  2. package/README.md +61 -0
  3. package/dist/apps.d.ts +58 -0
  4. package/dist/apps.js +274 -0
  5. package/dist/apps.js.map +1 -0
  6. package/dist/bin/apps.d.ts +2 -0
  7. package/dist/bin/apps.js +6 -0
  8. package/dist/bin/apps.js.map +1 -0
  9. package/dist/bin/mcp.d.ts +2 -0
  10. package/dist/bin/mcp.js +15 -0
  11. package/dist/bin/mcp.js.map +1 -0
  12. package/dist/boundaries.d.ts +11 -0
  13. package/dist/boundaries.js +55 -0
  14. package/dist/boundaries.js.map +1 -0
  15. package/dist/changes.d.ts +14 -0
  16. package/dist/changes.js +23 -0
  17. package/dist/changes.js.map +1 -0
  18. package/dist/cli.d.ts +24 -0
  19. package/dist/cli.js +138 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/command.d.ts +3 -0
  22. package/dist/command.js +40 -0
  23. package/dist/command.js.map +1 -0
  24. package/dist/faults.d.ts +21 -0
  25. package/dist/faults.js +59 -0
  26. package/dist/faults.js.map +1 -0
  27. package/dist/generations.d.ts +28 -0
  28. package/dist/generations.js +83 -0
  29. package/dist/generations.js.map +1 -0
  30. package/dist/health.d.ts +35 -0
  31. package/dist/health.js +116 -0
  32. package/dist/health.js.map +1 -0
  33. package/dist/identity.d.ts +10 -0
  34. package/dist/identity.js +59 -0
  35. package/dist/identity.js.map +1 -0
  36. package/dist/index.d.ts +8 -0
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/lease.d.ts +30 -0
  40. package/dist/lease.js +82 -0
  41. package/dist/lease.js.map +1 -0
  42. package/dist/logs.d.ts +11 -0
  43. package/dist/logs.js +40 -0
  44. package/dist/logs.js.map +1 -0
  45. package/dist/manifest.d.ts +6 -0
  46. package/dist/manifest.js +105 -0
  47. package/dist/manifest.js.map +1 -0
  48. package/dist/mcp-server.d.ts +3 -0
  49. package/dist/mcp-server.js +65 -0
  50. package/dist/mcp-server.js.map +1 -0
  51. package/dist/mcp.d.ts +4 -0
  52. package/dist/mcp.js +171 -0
  53. package/dist/mcp.js.map +1 -0
  54. package/dist/operations.d.ts +10 -0
  55. package/dist/operations.js +31 -0
  56. package/dist/operations.js.map +1 -0
  57. package/dist/ownership.d.ts +11 -0
  58. package/dist/ownership.js +75 -0
  59. package/dist/ownership.js.map +1 -0
  60. package/dist/package.d.ts +20 -0
  61. package/dist/package.js +204 -0
  62. package/dist/package.js.map +1 -0
  63. package/dist/presentation.d.ts +9 -0
  64. package/dist/presentation.js +63 -0
  65. package/dist/presentation.js.map +1 -0
  66. package/dist/process.d.ts +10 -0
  67. package/dist/process.js +68 -0
  68. package/dist/process.js.map +1 -0
  69. package/dist/reconciler.d.ts +27 -0
  70. package/dist/reconciler.js +103 -0
  71. package/dist/reconciler.js.map +1 -0
  72. package/dist/releases.d.ts +26 -0
  73. package/dist/releases.js +108 -0
  74. package/dist/releases.js.map +1 -0
  75. package/dist/restarts.d.ts +40 -0
  76. package/dist/restarts.js +137 -0
  77. package/dist/restarts.js.map +1 -0
  78. package/dist/runtime.d.ts +19 -0
  79. package/dist/runtime.js +57 -0
  80. package/dist/runtime.js.map +1 -0
  81. package/dist/schema.d.ts +3 -0
  82. package/dist/schema.js +80 -0
  83. package/dist/schema.js.map +1 -0
  84. package/dist/source-import.d.ts +4 -0
  85. package/dist/source-import.js +77 -0
  86. package/dist/source-import.js.map +1 -0
  87. package/dist/store.d.ts +29 -0
  88. package/dist/store.js +221 -0
  89. package/dist/store.js.map +1 -0
  90. package/dist/supervisor.d.ts +29 -0
  91. package/dist/supervisor.js +279 -0
  92. package/dist/supervisor.js.map +1 -0
  93. package/dist/types.d.ts +264 -0
  94. package/dist/types.js +2 -0
  95. package/dist/types.js.map +1 -0
  96. package/docs/ENGINE_INTEGRATION.md +68 -0
  97. package/docs/SUPERVISION.md +73 -0
  98. package/package.json +59 -0
package/PURPOSE.md ADDED
@@ -0,0 +1,98 @@
1
+ # Amalgm Apps
2
+
3
+ ## Purpose
4
+
5
+ Amalgm Apps lets a user turn any runnable project into a locally owned,
6
+ versioned application that Amalgm can build, keep alive, and route. It serves
7
+ users who want deployment operations without surrendering their source,
8
+ runtime, or data to a remote hosting platform. When the system is healthy, an
9
+ app keeps one stable identity while every deployment names an immutable
10
+ release, failed deployments leave the last working release recoverable, and
11
+ rollback means activating known bytes rather than rebuilding history.
12
+
13
+ Amalgm Engine is the composition root for the complete Amalgm runtime. This
14
+ repository owns the Apps product and its supervisor. Engine may run that
15
+ product beside independently supervised Events, Realtime, and other products;
16
+ it supplies identity, transport, and UI composition but does not absorb their
17
+ domain supervisors or maintain a second app lifecycle implementation.
18
+
19
+ ## Primitives
20
+
21
+ - An **app** is a stable local identity with a user-controlled name, route,
22
+ port, and desired running state.
23
+ - A **release** is one immutable, content-addressed package and its completed
24
+ build output.
25
+ - A **deployment** is an immutable record that activates one release for one
26
+ app.
27
+ - A **process generation** is one supervised execution attempt for a
28
+ deployment.
29
+ - The **Apps supervisor** is the sole lifecycle authority for apps in one
30
+ Apps state directory.
31
+ - A **product-service supervisor** is an optional outer Engine concern that
32
+ observes whether the Apps product is available; it never supervises
33
+ individual apps.
34
+ - The **data directory** is stable writable storage for an app across
35
+ deployments; release and deployment files are not persistent data.
36
+
37
+ ## Axioms
38
+
39
+ 1. App identity, app ref, public URL, and port survive deploys, rollbacks, and
40
+ renames.
41
+ 2. A release is identified by its normalized manifest and selected source
42
+ bytes; an existing release is never rebuilt or mutated.
43
+ 3. A deployment activates exactly one release, and activation history is
44
+ append-only.
45
+ 4. Rollback creates a new deployment of an existing release; it never changes
46
+ or deletes history.
47
+ 5. Registration and deploy finish validation and build before stopping the
48
+ active process.
49
+ 6. Activation requires the new process to survive its startup grace period;
50
+ failure before that boundary restores the previous runnable deployment
51
+ whenever one exists.
52
+ 7. The app name belongs to the stable app. The manifest seeds it during
53
+ registration; only rename changes it afterward.
54
+ 8. Process state changes only through the supervisor, and route eligibility
55
+ is derived from desired state, process state, health, and DNS connection.
56
+ 9. App code receives a stable data directory explicitly; writes made inside a
57
+ deployment directory never become part of a release or a later deploy.
58
+ 10. The SDK owns behavior. CLI, MCP, HTTP, and Engine integrations only adapt
59
+ that public service.
60
+ 11. Apps stores tool identifiers as opaque references and never edits Toolbox,
61
+ Agents, or another product. Any workflow spanning products has an explicit
62
+ product owner and never lives in a Core adapter.
63
+ 12. The app-side health lease is optional, inert outside Amalgm, and can never
64
+ crash or keep the hosted app alive by itself.
65
+ 13. The Apps supervisor belongs to this product in standalone and composed
66
+ deployments; exactly one active Apps supervisor owns a state directory.
67
+ 14. Engine composes product supervisors side by side. It may supervise the
68
+ Apps product as one service, but it never reaches through that boundary to
69
+ start, stop, adopt, or restart an individual app process.
70
+ 15. Supervisor state is scoped to its fault domain: an app failure changes
71
+ Apps state, an Apps-service failure changes Apps availability, and neither
72
+ is represented as failure of an unrelated product.
73
+ 16. Every lifecycle mutation is serialized per app, and one operating-system
74
+ owner guards every writable state directory.
75
+ 17. Crash restart budgets are derived from durable process-generation history;
76
+ restarting the Apps service never resets an app's budget.
77
+ 18. A crash restart reuses the active deployment directory without copying,
78
+ rebuilding, or mutating it.
79
+ 19. Embedder callbacks, child events, and supervision timers are fault
80
+ boundaries: failures are reported, routes fail closed, and no callback can
81
+ escape into the owning daemon.
82
+ 20. TypeScript under `src/` is the product source of truth. JavaScript and
83
+ declarations under `dist/` are generated together and are never edited by
84
+ hand or maintained as a parallel contract.
85
+ 21. An awaited lifecycle mutation resolves only after its ordered embedder
86
+ change notifications settle; observer failures are reported and contained.
87
+
88
+ ## Predictable behavior
89
+
90
+ Equal source and manifest content produces the same release id, even when
91
+ deployed twice. Deploying changed content creates a new release and
92
+ deployment. Rolling back selects an earlier successful release and appends a
93
+ new deployment. Renaming changes only the app record. If validation or build
94
+ fails, the running deployment is untouched. If the new process cannot start,
95
+ the deployment is marked failed and the previous deployment is reactivated.
96
+ When composed into Engine, the same Apps supervisor makes those decisions.
97
+ Engine sees the Apps product as available, degraded, or unavailable and can
98
+ restart that product independently without becoming a second app supervisor.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @amalgm/apps
2
+
3
+ Register, deploy, roll back, rename, and supervise local-first applications.
4
+ The complete behavioral contract is in [PURPOSE.md](./PURPOSE.md).
5
+
6
+ An app can use any language or framework. Its only integration is a small
7
+ `amalgm.app.json` manifest describing how to build, start, and package it.
8
+
9
+ ```json
10
+ {
11
+ "schemaVersion": 1,
12
+ "name": "Accounts dashboard",
13
+ "buildCommand": "npm ci && npm run build",
14
+ "startCommand": "npm start",
15
+ "package": {
16
+ "include": ["package*.json", "src/**", "public/**"],
17
+ "exclude": ["**/*.test.js"]
18
+ }
19
+ }
20
+ ```
21
+
22
+ ```sh
23
+ amalgm-apps register ./accounts
24
+ amalgm-apps deploy <app-id>
25
+ amalgm-apps versions <app-id>
26
+ amalgm-apps rollback <app-id>
27
+ amalgm-apps rename <app-id> "Accounts"
28
+ ```
29
+
30
+ The SDK, CLI, and MCP tools call the same `Apps` service. Releases and
31
+ deployment history live under `~/.amalgm/users/<scope>/apps` by default
32
+ (the kernel's scoped layout; `AMALGM_APPS_DIR` and `AMALGM_DIR` still
33
+ override). Hosted apps receive
34
+ `AMALGM_APP_DATA_DIR`, a stable writable directory that survives deployments.
35
+
36
+ ```ts
37
+ import { Apps } from '@amalgm/apps';
38
+
39
+ const apps = new Apps();
40
+ const app = await apps.register({ cwd: './accounts' });
41
+ await apps.deploy(app.id);
42
+ await apps.rollback(app.id);
43
+ ```
44
+
45
+ The SDK, supervisor, CLI, MCP server, lease, and tests are authored in
46
+ TypeScript. `npm run build` emits the CommonJS runtime and declarations into
47
+ `dist/`; generated output is not a second source tree.
48
+
49
+ Engine supplies runtime identity, route publication, and state notifications
50
+ through constructor callbacks; it does not replace product behavior. The
51
+ ownership and generated-source boundary are described in
52
+ [docs/ENGINE_INTEGRATION.md](./docs/ENGINE_INTEGRATION.md). Supervisor
53
+ ownership and the shared composition pattern for Apps, Events, and Realtime
54
+ are defined in [docs/SUPERVISION.md](./docs/SUPERVISION.md).
55
+
56
+ ## Verify
57
+
58
+ ```sh
59
+ npm install
60
+ npm run verify
61
+ ```
package/dist/apps.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ import { Changes } from './changes.js';
2
+ import { defaultStateDir } from './identity.js';
3
+ import type { Faults } from './faults.js';
4
+ import type { Health } from './health.js';
5
+ import type { Operations } from './operations.js';
6
+ import type { Ownership } from './ownership.js';
7
+ import type { Releases } from './releases.js';
8
+ import type { Store } from './store.js';
9
+ import type { Supervisor } from './supervisor.js';
10
+ import type { AppRecord, AppsOptions, AppView, CloseOptions, Deployment, DeployInput, ExistingAppInput, PackageInspection, PackedPackage, ReadyOptions, RegisterInput, Release, RollbackInput } from './types.js';
11
+ declare class Apps {
12
+ readonly options: AppsOptions;
13
+ readonly stateDir: string;
14
+ readonly domain: string;
15
+ readonly portMin: number;
16
+ readonly portMax: number;
17
+ routeQueue: Promise<unknown>;
18
+ readonly changes: Changes;
19
+ readonly faults: Faults;
20
+ readonly health: Health;
21
+ readonly operations: Operations;
22
+ readonly ownership: Ownership;
23
+ readonly releases: Releases;
24
+ readonly store: Store;
25
+ readonly supervisor: Supervisor;
26
+ constructor(options?: AppsOptions);
27
+ environment(app: AppRecord): NodeJS.ProcessEnv;
28
+ changed(app: AppRecord | {
29
+ id: string;
30
+ deleted: true;
31
+ }): void;
32
+ publishRoutes(reason?: string): Promise<unknown>;
33
+ view(app: AppRecord | null): AppView | null;
34
+ get(appId: string): AppView | null;
35
+ list(): AppView[];
36
+ validate(cwd: string): PackageInspection;
37
+ pack(cwd: string): PackedPackage;
38
+ register(input: RegisterInput): Promise<AppView>;
39
+ importExisting(input: ExistingAppInput): Promise<AppView>;
40
+ deploy(appId: string, input?: DeployInput): Promise<AppView>;
41
+ rollback(appId: string, input?: RollbackInput): Promise<AppView>;
42
+ activate(app: AppRecord, release: Release, reason: string): Promise<AppRecord>;
43
+ rename(appId: string, name: string): Promise<AppView>;
44
+ versions(appId: string): Release[];
45
+ deployments(appId: string): Deployment[];
46
+ start(appId: string): Promise<AppView>;
47
+ stop(appId: string): Promise<AppView>;
48
+ connectDns(appId: string): Promise<AppView>;
49
+ disconnectDns(appId: string): Promise<AppView>;
50
+ ready(appId: string, options?: ReadyOptions): unknown;
51
+ heartbeat(appId: string): unknown;
52
+ routes(): import('./types.js').AppRoute[];
53
+ delete(appId: string): Promise<AppView>;
54
+ removeAppFiles(appId: string): void;
55
+ boot(): Promise<PromiseSettledResult<AppView | null>[]>;
56
+ close(options?: CloseOptions): Promise<void>;
57
+ }
58
+ export { Apps, defaultStateDir };
package/dist/apps.js ADDED
@@ -0,0 +1,274 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { errorMessage, invoke } from './boundaries.js';
5
+ import { Changes } from './changes.js';
6
+ import { allocatePort, allocateRef, assertAppRef, defaultStateDir } from './identity.js';
7
+ import { importExisting } from './source-import.js';
8
+ import { inspectPackage, packPackage } from './package.js';
9
+ import { appEnvironment, appView, eligibleRoutes, queueRoutes, } from './presentation.js';
10
+ import { createRuntime } from './runtime.js';
11
+ class Apps {
12
+ options;
13
+ stateDir;
14
+ domain;
15
+ portMin;
16
+ portMax;
17
+ routeQueue;
18
+ changes;
19
+ faults;
20
+ health;
21
+ operations;
22
+ ownership;
23
+ releases;
24
+ store;
25
+ supervisor;
26
+ constructor(options = {}) {
27
+ this.options = options;
28
+ this.stateDir = path.resolve(options.stateDir || defaultStateDir(options.env));
29
+ this.domain = options.domain || 'apps.amalgm.ai';
30
+ this.portMin = options.portMin || 9100;
31
+ this.portMax = options.portMax || 9199;
32
+ this.routeQueue = Promise.resolve();
33
+ this.changes = new Changes(options, () => this.publishRoutes('state-change'));
34
+ const runtime = createRuntime(this, options);
35
+ this.faults = runtime.faults;
36
+ this.health = runtime.health;
37
+ this.operations = runtime.operations;
38
+ this.ownership = runtime.ownership;
39
+ this.releases = runtime.releases;
40
+ this.store = runtime.store;
41
+ this.supervisor = runtime.supervisor;
42
+ }
43
+ environment(app) {
44
+ return invoke(() => appEnvironment(this.options, app), [], this.options.onError, `Environment callback failed for ${app.id}`);
45
+ }
46
+ changed(app) { this.changes.publish(app); }
47
+ publishRoutes(reason = 'manual') {
48
+ return queueRoutes(this, reason);
49
+ }
50
+ view(app) {
51
+ return appView(this, app);
52
+ }
53
+ get(appId) {
54
+ return this.view(this.store.getApp(appId));
55
+ }
56
+ list() {
57
+ return this.store.listApps().map((app) => this.view(app));
58
+ }
59
+ validate(cwd) {
60
+ return inspectPackage(cwd);
61
+ }
62
+ pack(cwd) {
63
+ return packPackage(cwd);
64
+ }
65
+ async register(input) {
66
+ if (typeof input.cwd !== 'string' || !input.cwd.trim())
67
+ throw new Error('cwd is required');
68
+ const cwd = path.resolve(input.cwd);
69
+ const inspected = inspectPackage(cwd);
70
+ const id = input.id || `app-${crypto.randomUUID()}`;
71
+ return this.operations.run(id, 'register', async () => {
72
+ const appRef = assertAppRef(allocateRef(this.store));
73
+ const now = new Date().toISOString();
74
+ let app = this.store.createApp({
75
+ id,
76
+ name: inspected.manifest.name,
77
+ description: inspected.manifest.description,
78
+ appRef,
79
+ publicUrl: `https://${appRef}.${this.domain}/`,
80
+ port: allocatePort(this.store, input.port, this.portMin, this.portMax),
81
+ sourceDir: cwd,
82
+ dataDir: path.join(this.stateDir, 'data', id),
83
+ desiredState: 'running',
84
+ status: 'registered',
85
+ dnsConnected: input.connectDns !== false && input.connect_dns !== false,
86
+ autostart: input.autostart !== false,
87
+ keepAlive: input.keepAlive !== false && input.keep_alive !== false,
88
+ createdAt: now,
89
+ updatedAt: now,
90
+ });
91
+ try {
92
+ const release = await this.releases.prepare(app, cwd);
93
+ app = await this.activate(app, release, 'register');
94
+ return this.view(app);
95
+ }
96
+ catch (error) {
97
+ this.store.deleteApp(id);
98
+ this.removeAppFiles(id);
99
+ throw new Error(`App registration failed: ${errorMessage(error)}`);
100
+ }
101
+ });
102
+ }
103
+ async importExisting(input) {
104
+ return this.operations.run(input?.id || 'source-import', 'import', () => importExisting(this, input));
105
+ }
106
+ async deploy(appId, input = {}) {
107
+ return this.operations.run(appId, 'deploy', async () => {
108
+ const app = this.store.getApp(appId);
109
+ if (!app)
110
+ throw new Error(`App not found: ${appId}`);
111
+ const cwd = path.resolve(input.cwd || app.sourceDir);
112
+ const release = await this.releases.prepare(app, cwd);
113
+ const deployed = await this.activate(app, release, 'deploy');
114
+ this.store.updateApp(appId, { sourceDir: cwd });
115
+ return this.get(deployed.id);
116
+ });
117
+ }
118
+ async rollback(appId, input = {}) {
119
+ return this.operations.run(appId, 'rollback', async () => {
120
+ const app = this.store.getApp(appId);
121
+ if (!app)
122
+ throw new Error(`App not found: ${appId}`);
123
+ let release;
124
+ if (input.releaseId || input.versionId) {
125
+ release = this.store.getRelease((input.releaseId || input.versionId));
126
+ if (!release || release.appId !== appId)
127
+ throw new Error('Release does not belong to this app');
128
+ }
129
+ else {
130
+ const previous = this.store.previousDeployment(appId, app.activeReleaseId);
131
+ release = previous ? this.store.getRelease(previous.releaseId) : null;
132
+ }
133
+ if (!release)
134
+ throw new Error('No earlier release is available');
135
+ if (release.id === app.activeReleaseId)
136
+ throw new Error('Release is already active');
137
+ return this.view(await this.activate(app, release, 'rollback'));
138
+ });
139
+ }
140
+ async activate(app, release, reason) {
141
+ const previous = app.activeDeploymentId
142
+ ? this.store.getDeployment(app.activeDeploymentId)
143
+ : null;
144
+ const deployment = await this.releases.createDeployment(app, release, reason);
145
+ if (previous)
146
+ await this.supervisor.stop(app.id, { preserveDesiredState: true });
147
+ this.health.forget(app.id);
148
+ this.store.activate(app.id, deployment.id);
149
+ try {
150
+ const activated = await this.supervisor.start(app.id);
151
+ if (previous)
152
+ this.releases.removeDeployment(previous);
153
+ return activated;
154
+ }
155
+ catch (error) {
156
+ this.store.failDeployment(deployment.id, errorMessage(error));
157
+ this.releases.removeDeployment(deployment);
158
+ if (previous) {
159
+ this.store.activate(app.id, previous.id);
160
+ try {
161
+ await this.supervisor.start(app.id);
162
+ }
163
+ catch (restoreError) {
164
+ this.store.updateApp(app.id, {
165
+ status: 'error',
166
+ error: `Activation failed: ${errorMessage(error)}; restore failed: ${errorMessage(restoreError)}`,
167
+ });
168
+ }
169
+ }
170
+ throw new Error(`Activation failed: ${errorMessage(error)}`);
171
+ }
172
+ }
173
+ async rename(appId, name) {
174
+ return this.operations.run(appId, 'rename', async () => {
175
+ const value = typeof name === 'string' ? name.trim() : '';
176
+ if (!value)
177
+ throw new Error('name must be a non-empty string');
178
+ if (!this.store.getApp(appId))
179
+ throw new Error(`App not found: ${appId}`);
180
+ const app = this.store.updateApp(appId, { name: value });
181
+ this.changed(app);
182
+ return this.view(app);
183
+ });
184
+ }
185
+ versions(appId) {
186
+ if (!this.store.getApp(appId))
187
+ throw new Error(`App not found: ${appId}`);
188
+ return this.store.listReleases(appId);
189
+ }
190
+ deployments(appId) {
191
+ if (!this.store.getApp(appId))
192
+ throw new Error(`App not found: ${appId}`);
193
+ return this.store.listDeployments(appId);
194
+ }
195
+ async start(appId) {
196
+ return this.operations.run(appId, 'start', async () => this.view(await this.supervisor.start(appId)));
197
+ }
198
+ async stop(appId) {
199
+ return this.operations.run(appId, 'stop', async () => {
200
+ this.health.forget(appId);
201
+ return this.view(await this.supervisor.stop(appId));
202
+ });
203
+ }
204
+ async connectDns(appId) {
205
+ return this.operations.run(appId, 'connect-dns', async () => {
206
+ if (!this.store.getApp(appId))
207
+ throw new Error(`App not found: ${appId}`);
208
+ const app = this.store.updateApp(appId, { dnsConnected: true });
209
+ this.changed(app);
210
+ return this.view(app);
211
+ });
212
+ }
213
+ async disconnectDns(appId) {
214
+ return this.operations.run(appId, 'disconnect-dns', async () => {
215
+ if (!this.store.getApp(appId))
216
+ throw new Error(`App not found: ${appId}`);
217
+ const app = this.store.updateApp(appId, { dnsConnected: false });
218
+ this.changed(app);
219
+ return this.view(app);
220
+ });
221
+ }
222
+ ready(appId, options) {
223
+ return this.health.ready(appId, options);
224
+ }
225
+ heartbeat(appId) {
226
+ return this.health.heartbeat(appId);
227
+ }
228
+ routes() {
229
+ return eligibleRoutes(this);
230
+ }
231
+ async delete(appId) {
232
+ return this.operations.run(appId, 'delete', async () => {
233
+ const app = this.store.getApp(appId);
234
+ if (!app)
235
+ throw new Error(`App not found: ${appId}`);
236
+ await this.supervisor.stop(appId);
237
+ this.health.forget(appId);
238
+ this.store.deleteApp(appId);
239
+ this.removeAppFiles(appId);
240
+ this.changed({ id: appId, deleted: true });
241
+ return this.view(app);
242
+ });
243
+ }
244
+ removeAppFiles(appId) {
245
+ for (const directory of ['data', 'deployments', 'releases']) {
246
+ fs.rmSync(path.join(this.stateDir, directory, appId), { recursive: true, force: true });
247
+ }
248
+ const log = this.supervisor.logPath(appId);
249
+ fs.rmSync(log, { force: true });
250
+ fs.rmSync(`${log}.1`, { force: true });
251
+ }
252
+ async boot() {
253
+ await this.ownership.acquire();
254
+ this.health.start();
255
+ const results = await this.supervisor.boot();
256
+ await this.changes.settle();
257
+ await this.publishRoutes('boot');
258
+ return results.map((result) => (result.status === 'fulfilled'
259
+ ? { ...result, value: this.view(result.value) }
260
+ : result));
261
+ }
262
+ async close(options = {}) {
263
+ this.health.close();
264
+ if (options.stopProcesses)
265
+ await this.supervisor.close();
266
+ else
267
+ this.supervisor.detach();
268
+ await this.changes.settle();
269
+ this.store.close();
270
+ await this.ownership.release();
271
+ }
272
+ }
273
+ export { Apps, defaultStateDir };
274
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../cli.js';
3
+ runCli(process.argv.slice(2)).then((code) => {
4
+ process.exitCode = code;
5
+ });
6
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/bin/apps.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IAC1C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { errorMessage } from '../boundaries.js';
3
+ import { createMcpServer } from '../mcp-server.js';
4
+ const server = createMcpServer();
5
+ server.start().catch((error) => {
6
+ console.error(errorMessage(error));
7
+ process.exitCode = 1;
8
+ });
9
+ async function shutdown() {
10
+ await server.apps.close();
11
+ process.exit();
12
+ }
13
+ process.once('SIGINT', shutdown);
14
+ process.once('SIGTERM', shutdown);
15
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/bin/mcp.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;AACjC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC7B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,QAAQ;IACrB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC1B,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC;AAED,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACjC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ type ErrorObserver = ((error: Error) => unknown) | undefined | null;
2
+ declare function errorMessage(error: unknown): string;
3
+ declare function errorCode(error: unknown): unknown;
4
+ declare function contextual(error: unknown, context: string): Error & {
5
+ code?: unknown;
6
+ };
7
+ declare function report(onError: ErrorObserver, error: unknown, context: string): void;
8
+ declare function observe<TArgs extends unknown[], TResult>(callback: ((...args: TArgs) => TResult) | undefined, args: TArgs, onError: ErrorObserver, context: string): Promise<TResult | undefined>;
9
+ declare function invoke<TArgs extends unknown[], TResult>(callback: (...args: TArgs) => TResult, args: TArgs, onError: ErrorObserver, context: string): TResult;
10
+ declare function invokeAsync<TArgs extends unknown[], TResult>(callback: (...args: TArgs) => TResult | Promise<TResult>, args: TArgs, onError: ErrorObserver, context: string): Promise<TResult>;
11
+ export { contextual, errorCode, errorMessage, invoke, invokeAsync, observe, report };
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+ function errorMessage(error) {
3
+ return error instanceof Error ? error.message : String(error);
4
+ }
5
+ function errorCode(error) {
6
+ return error && typeof error === 'object' && 'code' in error ? error.code : undefined;
7
+ }
8
+ function contextual(error, context) {
9
+ const cause = error instanceof Error ? error : new Error(String(error));
10
+ const wrapped = new Error(`${context}: ${cause.message}`, { cause });
11
+ wrapped.code = cause.code;
12
+ return wrapped;
13
+ }
14
+ function report(onError, error, context) {
15
+ if (typeof onError !== 'function')
16
+ return;
17
+ const failure = contextual(error, context);
18
+ try {
19
+ Promise.resolve(onError(failure)).catch(() => undefined);
20
+ }
21
+ catch {
22
+ // Error reporting is a terminal boundary and must never recurse.
23
+ }
24
+ }
25
+ async function observe(callback, args, onError, context) {
26
+ if (typeof callback !== 'function')
27
+ return undefined;
28
+ try {
29
+ return await callback(...args);
30
+ }
31
+ catch (error) {
32
+ report(onError, error, context);
33
+ return undefined;
34
+ }
35
+ }
36
+ function invoke(callback, args, onError, context) {
37
+ try {
38
+ return callback(...args);
39
+ }
40
+ catch (error) {
41
+ report(onError, error, context);
42
+ throw contextual(error, context);
43
+ }
44
+ }
45
+ async function invokeAsync(callback, args, onError, context) {
46
+ try {
47
+ return await callback(...args);
48
+ }
49
+ catch (error) {
50
+ report(onError, error, context);
51
+ throw contextual(error, context);
52
+ }
53
+ }
54
+ export { contextual, errorCode, errorMessage, invoke, invokeAsync, observe, report };
55
+ //# sourceMappingURL=boundaries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundaries.js","sourceRoot":"","sources":["../src/boundaries.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACxF,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,OAAe;IACjD,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,MAAM,OAAO,GAA+B,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjG,OAAO,CAAC,IAAI,GAAI,KAAoC,CAAC,IAAI,CAAC;IAC1D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,OAAsB,EAAE,KAAc,EAAE,OAAe;IACrE,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO;IAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,QAAmD,EACnD,IAAW,EACX,OAAsB,EACtB,OAAe;IAEf,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CACb,QAAqC,EACrC,IAAW,EACX,OAAsB,EACtB,OAAe;IAEf,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,QAAwD,EACxD,IAAW,EACX,OAAsB,EACtB,OAAe;IAEf,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { AppRecord, AppsOptions } from './types.js';
2
+ type AppChange = AppRecord | {
3
+ id: string;
4
+ deleted: true;
5
+ };
6
+ declare class Changes {
7
+ private readonly options;
8
+ private readonly publishRoutes;
9
+ private queue;
10
+ constructor(options: AppsOptions, publishRoutes: () => Promise<unknown>);
11
+ publish(change: AppChange): void;
12
+ settle(): Promise<void>;
13
+ }
14
+ export { Changes };