borgmcp-server 0.1.7 → 0.1.9

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 (70) hide show
  1. package/README.md +61 -46
  2. package/SECURITY.md +12 -1
  3. package/THIRD_PARTY_NOTICES.md +1 -1
  4. package/dist/bootstrap.d.ts +8 -1
  5. package/dist/bootstrap.js +39 -6
  6. package/dist/bootstrap.js.map +1 -1
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.js +176 -1
  9. package/dist/cli.js.map +1 -1
  10. package/dist/coordination-api.js +10 -1
  11. package/dist/coordination-api.js.map +1 -1
  12. package/dist/credentials.d.ts +5 -1
  13. package/dist/credentials.js +35 -3
  14. package/dist/credentials.js.map +1 -1
  15. package/dist/debug-log.d.ts +2 -2
  16. package/dist/debug-log.js +2 -2
  17. package/dist/debug-log.js.map +1 -1
  18. package/dist/https-server.d.ts +5 -1
  19. package/dist/https-server.js +93 -27
  20. package/dist/https-server.js.map +1 -1
  21. package/dist/index.d.ts +14 -1
  22. package/dist/index.js +8 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/main.js +1 -0
  25. package/dist/main.js.map +1 -1
  26. package/dist/managed-service.d.ts +20 -0
  27. package/dist/managed-service.js +80 -0
  28. package/dist/managed-service.js.map +1 -0
  29. package/dist/migrations.js +23 -0
  30. package/dist/migrations.js.map +1 -1
  31. package/dist/portable-credential-store.d.ts +16 -0
  32. package/dist/portable-credential-store.js +305 -0
  33. package/dist/portable-credential-store.js.map +1 -0
  34. package/dist/registry-artifact.d.ts +11 -0
  35. package/dist/registry-artifact.js +99 -0
  36. package/dist/registry-artifact.js.map +1 -0
  37. package/dist/runtime-identity.d.ts +19 -0
  38. package/dist/runtime-identity.js +61 -0
  39. package/dist/runtime-identity.js.map +1 -0
  40. package/dist/runtime-lifecycle.d.ts +56 -0
  41. package/dist/runtime-lifecycle.js +486 -0
  42. package/dist/runtime-lifecycle.js.map +1 -0
  43. package/dist/runtime-operator.d.ts +24 -0
  44. package/dist/runtime-operator.js +95 -0
  45. package/dist/runtime-operator.js.map +1 -0
  46. package/dist/service.d.ts +53 -5
  47. package/dist/service.js +326 -15
  48. package/dist/service.js.map +1 -1
  49. package/dist/store.d.ts +16 -7
  50. package/dist/store.js +93 -83
  51. package/dist/store.js.map +1 -1
  52. package/npm-shrinkwrap.json +6 -6
  53. package/package.json +2 -2
  54. package/src/bootstrap.ts +46 -5
  55. package/src/cli.ts +171 -1
  56. package/src/coordination-api.ts +12 -0
  57. package/src/credentials.ts +36 -5
  58. package/src/debug-log.ts +4 -3
  59. package/src/https-server.ts +124 -27
  60. package/src/index.ts +46 -1
  61. package/src/main.ts +1 -0
  62. package/src/managed-service.ts +107 -0
  63. package/src/migrations.ts +23 -0
  64. package/src/portable-credential-store.ts +306 -0
  65. package/src/registry-artifact.ts +111 -0
  66. package/src/runtime-identity.ts +82 -0
  67. package/src/runtime-lifecycle.ts +567 -0
  68. package/src/runtime-operator.ts +124 -0
  69. package/src/service.ts +401 -20
  70. package/src/store.ts +100 -83
@@ -0,0 +1,124 @@
1
+ import type { RegistryArtifactSource } from "./registry-artifact.js";
2
+ import {
3
+ RuntimeActivationError,
4
+ type RuntimeLifecycle,
5
+ type RuntimeRecoveryState,
6
+ type VerifiedRuntimeArtifact,
7
+ } from "./runtime-lifecycle.js";
8
+ import type { RuntimeBuildIdentity } from "./runtime-identity.js";
9
+
10
+ export interface RuntimeOperator {
11
+ readonly prepareLatest: (timeoutMs: number) => Promise<VerifiedRuntimeArtifact>;
12
+ readonly updateLatest: (timeoutMs: number) => Promise<RuntimeUpdateResult>;
13
+ }
14
+
15
+ export interface RuntimeUpdateResult {
16
+ readonly outcome: "prepared" | "updated";
17
+ readonly artifact: VerifiedRuntimeArtifact;
18
+ readonly runningIdentity: RuntimeBuildIdentity | null;
19
+ readonly dataIdentity: "preserved";
20
+ }
21
+
22
+ export class RuntimeUpdateFailure extends Error {
23
+ readonly code: "ARTIFACT_VERIFICATION_FAILED" | "ACTIVATION_FAILED";
24
+ readonly recovery: RuntimeRecoveryState | null;
25
+
26
+ constructor(
27
+ code: "ARTIFACT_VERIFICATION_FAILED" | "ACTIVATION_FAILED",
28
+ recovery: RuntimeRecoveryState | null = null,
29
+ ) {
30
+ super("Runtime update did not complete.");
31
+ this.name = "RuntimeUpdateFailure";
32
+ this.code = code;
33
+ this.recovery = recovery;
34
+ }
35
+ }
36
+
37
+ export function createRuntimeOperator(options: {
38
+ readonly runtimeRoot: string;
39
+ readonly artifacts: RegistryArtifactSource;
40
+ readonly lifecycle: RuntimeLifecycle;
41
+ readonly isRunning: () => Promise<boolean>;
42
+ }): RuntimeOperator {
43
+ const stageLatest = async (timeoutMs: number): Promise<VerifiedRuntimeArtifact> => {
44
+ validateTimeout(timeoutMs);
45
+ const controller = new AbortController();
46
+ let timer: NodeJS.Timeout | undefined;
47
+ let downloaded: Awaited<ReturnType<RegistryArtifactSource["latest"]>> | undefined;
48
+ const download = options.artifacts.latest(options.runtimeRoot, controller.signal);
49
+ try {
50
+ downloaded = await Promise.race([
51
+ download,
52
+ new Promise<never>((_resolve, reject) => {
53
+ timer = setTimeout(() => {
54
+ controller.abort();
55
+ reject(new Error("Runtime artifact download timed out."));
56
+ }, timeoutMs);
57
+ }),
58
+ ]);
59
+ return await options.lifecycle.stage({
60
+ runtimeRoot: options.runtimeRoot,
61
+ tarballPath: downloaded.tarballPath,
62
+ expectedIntegrity: downloaded.integrity,
63
+ expectedVersion: downloaded.version,
64
+ ...(downloaded.sourceSha === null ? {} : { sourceSha: downloaded.sourceSha }),
65
+ timeoutMs,
66
+ });
67
+ } finally {
68
+ if (timer !== undefined) clearTimeout(timer);
69
+ if (downloaded === undefined) {
70
+ void download.then((late) => late.cleanup()).catch(() => undefined);
71
+ }
72
+ await downloaded?.cleanup();
73
+ }
74
+ };
75
+ return {
76
+ async prepareLatest(timeoutMs): Promise<VerifiedRuntimeArtifact> {
77
+ const artifact = await stageLatest(timeoutMs);
78
+ return options.lifecycle.prepare({ runtimeRoot: options.runtimeRoot, artifact });
79
+ },
80
+ async updateLatest(timeoutMs): Promise<RuntimeUpdateResult> {
81
+ await options.isRunning();
82
+ let artifact: VerifiedRuntimeArtifact;
83
+ try {
84
+ artifact = await stageLatest(timeoutMs);
85
+ } catch {
86
+ throw new RuntimeUpdateFailure("ARTIFACT_VERIFICATION_FAILED");
87
+ }
88
+ if (!await options.isRunning()) {
89
+ await options.lifecycle.prepare({ runtimeRoot: options.runtimeRoot, artifact });
90
+ return Object.freeze({
91
+ outcome: "prepared",
92
+ artifact,
93
+ runningIdentity: null,
94
+ dataIdentity: "preserved",
95
+ });
96
+ }
97
+ let runningIdentity: RuntimeBuildIdentity;
98
+ try {
99
+ runningIdentity = await options.lifecycle.activate({
100
+ runtimeRoot: options.runtimeRoot,
101
+ artifact,
102
+ timeoutMs,
103
+ });
104
+ } catch (error) {
105
+ throw new RuntimeUpdateFailure(
106
+ "ACTIVATION_FAILED",
107
+ error instanceof RuntimeActivationError ? error.recovery : "failed",
108
+ );
109
+ }
110
+ return Object.freeze({
111
+ outcome: "updated",
112
+ artifact,
113
+ runningIdentity,
114
+ dataIdentity: "preserved",
115
+ });
116
+ },
117
+ };
118
+ }
119
+
120
+ function validateTimeout(value: number): void {
121
+ if (!Number.isSafeInteger(value) || value < 100 || value > 300_000) {
122
+ throw new Error("Runtime operator timeout is invalid.");
123
+ }
124
+ }