wake-bridge 0.9.0-preview.8

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 (115) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +222 -0
  3. package/dist/src/adapters/botlingknows.d.ts +42 -0
  4. package/dist/src/adapters/botlingknows.js +141 -0
  5. package/dist/src/adapters/botlingknows.js.map +1 -0
  6. package/dist/src/adapters/group-chat.d.ts +43 -0
  7. package/dist/src/adapters/group-chat.js +120 -0
  8. package/dist/src/adapters/group-chat.js.map +1 -0
  9. package/dist/src/cli.d.ts +2 -0
  10. package/dist/src/cli.js +637 -0
  11. package/dist/src/cli.js.map +1 -0
  12. package/dist/src/connector-catalog.d.ts +17 -0
  13. package/dist/src/connector-catalog.js +43 -0
  14. package/dist/src/connector-catalog.js.map +1 -0
  15. package/dist/src/connectors/botlingknows-mcp.d.ts +15 -0
  16. package/dist/src/connectors/botlingknows-mcp.js +130 -0
  17. package/dist/src/connectors/botlingknows-mcp.js.map +1 -0
  18. package/dist/src/connectors/group-chat-http.d.ts +17 -0
  19. package/dist/src/connectors/group-chat-http.js +226 -0
  20. package/dist/src/connectors/group-chat-http.js.map +1 -0
  21. package/dist/src/connectors/mcp-http-client.d.ts +11 -0
  22. package/dist/src/connectors/mcp-http-client.js +108 -0
  23. package/dist/src/connectors/mcp-http-client.js.map +1 -0
  24. package/dist/src/core.d.ts +170 -0
  25. package/dist/src/core.js +1720 -0
  26. package/dist/src/core.js.map +1 -0
  27. package/dist/src/daemon.d.ts +31 -0
  28. package/dist/src/daemon.js +605 -0
  29. package/dist/src/daemon.js.map +1 -0
  30. package/dist/src/db.d.ts +31 -0
  31. package/dist/src/db.js +513 -0
  32. package/dist/src/db.js.map +1 -0
  33. package/dist/src/event-sdk.d.ts +43 -0
  34. package/dist/src/event-sdk.js +152 -0
  35. package/dist/src/event-sdk.js.map +1 -0
  36. package/dist/src/host-adapter-registry.d.ts +21 -0
  37. package/dist/src/host-adapter-registry.js +59 -0
  38. package/dist/src/host-adapter-registry.js.map +1 -0
  39. package/dist/src/index.d.ts +5 -0
  40. package/dist/src/index.js +6 -0
  41. package/dist/src/index.js.map +1 -0
  42. package/dist/src/instance-config.d.ts +46 -0
  43. package/dist/src/instance-config.js +176 -0
  44. package/dist/src/instance-config.js.map +1 -0
  45. package/dist/src/mcp.d.ts +51 -0
  46. package/dist/src/mcp.js +728 -0
  47. package/dist/src/mcp.js.map +1 -0
  48. package/dist/src/operator-control.d.ts +82 -0
  49. package/dist/src/operator-control.js +220 -0
  50. package/dist/src/operator-control.js.map +1 -0
  51. package/dist/src/out-of-process-host.d.ts +37 -0
  52. package/dist/src/out-of-process-host.js +196 -0
  53. package/dist/src/out-of-process-host.js.map +1 -0
  54. package/dist/src/policy-control.d.ts +3 -0
  55. package/dist/src/policy-control.js +120 -0
  56. package/dist/src/policy-control.js.map +1 -0
  57. package/dist/src/release-lifecycle.d.ts +98 -0
  58. package/dist/src/release-lifecycle.js +378 -0
  59. package/dist/src/release-lifecycle.js.map +1 -0
  60. package/dist/src/sdk-error.d.ts +6 -0
  61. package/dist/src/sdk-error.js +12 -0
  62. package/dist/src/sdk-error.js.map +1 -0
  63. package/dist/src/source-adapter.d.ts +32 -0
  64. package/dist/src/source-adapter.js +164 -0
  65. package/dist/src/source-adapter.js.map +1 -0
  66. package/dist/src/source-connector.d.ts +50 -0
  67. package/dist/src/source-connector.js +358 -0
  68. package/dist/src/source-connector.js.map +1 -0
  69. package/dist/src/source-control-client.d.ts +38 -0
  70. package/dist/src/source-control-client.js +61 -0
  71. package/dist/src/source-control-client.js.map +1 -0
  72. package/dist/src/source-ingress.d.ts +16 -0
  73. package/dist/src/source-ingress.js +47 -0
  74. package/dist/src/source-ingress.js.map +1 -0
  75. package/dist/src/source-sdk.d.ts +6 -0
  76. package/dist/src/source-sdk.js +53 -0
  77. package/dist/src/source-sdk.js.map +1 -0
  78. package/dist/src/transport-sdk.d.ts +102 -0
  79. package/dist/src/transport-sdk.js +222 -0
  80. package/dist/src/transport-sdk.js.map +1 -0
  81. package/dist/src/transport.d.ts +23 -0
  82. package/dist/src/transport.js +71 -0
  83. package/dist/src/transport.js.map +1 -0
  84. package/dist/src/types.d.ts +522 -0
  85. package/dist/src/types.js +2 -0
  86. package/dist/src/types.js.map +1 -0
  87. package/dist/src/util.d.ts +26 -0
  88. package/dist/src/util.js +136 -0
  89. package/dist/src/util.js.map +1 -0
  90. package/dist/src/version.d.ts +1 -0
  91. package/dist/src/version.js +2 -0
  92. package/dist/src/version.js.map +1 -0
  93. package/docs/adapters/botlingknows.md +40 -0
  94. package/docs/adapters/gmail-planned.md +16 -0
  95. package/docs/adapters/group-chat.md +126 -0
  96. package/docs/operations/connector-catalog.md +40 -0
  97. package/docs/operations/operator-control.md +83 -0
  98. package/docs/operations/out-of-process-host-adapter.md +150 -0
  99. package/docs/operations/policies.md +106 -0
  100. package/docs/operations/public-sdk.md +87 -0
  101. package/docs/operations/release-lifecycle.md +154 -0
  102. package/docs/operations/source-connectors.md +163 -0
  103. package/docs/operations/source-ingress.md +108 -0
  104. package/docs/operations/templates/botlingknows-connector.env.example +5 -0
  105. package/docs/operations/templates/sources.json.example +15 -0
  106. package/docs/quickstart.md +143 -0
  107. package/docs/releases/0.9.0-preview.8.md +44 -0
  108. package/docs/verification.md +19 -0
  109. package/examples/policies/botlingknows-conservative.json +44 -0
  110. package/examples/reference-host-adapter/README.md +41 -0
  111. package/examples/reference-host-adapter/adapter.mjs +173 -0
  112. package/examples/reference-host-adapter/host-adapters.json.example +26 -0
  113. package/package.json +94 -0
  114. package/schemas/event-v1.schema.json +26 -0
  115. package/schemas/policy-v1.schema.json +66 -0
@@ -0,0 +1,43 @@
1
+ import type { JsonValue, WakeEventInput } from "./types.js";
2
+ export declare const EVENT_CONTRACT_VERSION: 1;
3
+ export declare const SUPPORTED_EVENT_CONTRACT_VERSIONS: readonly [1];
4
+ /** Validate and normalize the stable v1 producer payload. */
5
+ export declare function validateWakeEventInput(raw: WakeEventInput, now?: Date): WakeEventInput & {
6
+ schema_version: 1;
7
+ occurred_at: string;
8
+ };
9
+ export interface SourcePushClientOptions {
10
+ base_url: string;
11
+ source: string;
12
+ token: string;
13
+ fetch?: typeof fetch;
14
+ timeout_ms?: number;
15
+ }
16
+ export interface SourcePushReceipt {
17
+ event: {
18
+ id: string;
19
+ source: string;
20
+ type: string;
21
+ dedupe_key: string;
22
+ schema_version: number;
23
+ occurred_at: string;
24
+ received_at: string;
25
+ };
26
+ duplicate: boolean;
27
+ suppressed: boolean;
28
+ claim?: {
29
+ id: string;
30
+ };
31
+ [key: string]: JsonValue | object | undefined;
32
+ }
33
+ /** Narrow client for the credential-bound generic push ingress. */
34
+ export declare class SourcePushClient {
35
+ private readonly options;
36
+ private readonly origin;
37
+ private readonly fetchImpl;
38
+ private readonly timeoutMs;
39
+ constructor(options: SourcePushClientOptions);
40
+ emit(input: WakeEventInput): Promise<SourcePushReceipt>;
41
+ }
42
+ export type { JsonPrimitive, JsonValue, PriorityHint, ResourceRef, WakeEventInput } from "./types.js";
43
+ export { WakeBridgeSdkError } from "./sdk-error.js";
@@ -0,0 +1,152 @@
1
+ import { WakeBridgeSdkError } from "./sdk-error.js";
2
+ export const EVENT_CONTRACT_VERSION = 1;
3
+ export const SUPPORTED_EVENT_CONTRACT_VERSIONS = [EVENT_CONTRACT_VERSION];
4
+ const ABSOLUTE_RFC3339 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/u;
5
+ const FORBIDDEN_INPUT_KEYS = new Set([
6
+ "owner_id", "instance_id", "policy", "policy_id", "endpoint", "endpoint_id",
7
+ "wake_prompt", "wakePrompt", "system_instruction", "systemInstruction", "instructions", "prompt",
8
+ ]);
9
+ function validateNoPrompt(value, path = "input") {
10
+ if (!value || typeof value !== "object")
11
+ return;
12
+ if (Array.isArray(value)) {
13
+ value.forEach((item, index) => validateNoPrompt(item, `${path}[${index}]`));
14
+ return;
15
+ }
16
+ for (const [key, child] of Object.entries(value)) {
17
+ if (FORBIDDEN_INPUT_KEYS.has(key)) {
18
+ throw new WakeBridgeSdkError(`${path}.${key} is not accepted by event ingress`, "forbidden_field", 400);
19
+ }
20
+ validateNoPrompt(child, `${path}.${key}`);
21
+ }
22
+ }
23
+ function validateResource(resource) {
24
+ if (!resource || typeof resource !== "object" || typeof resource.uri !== "string") {
25
+ throw new WakeBridgeSdkError("resource.uri is required", "invalid_resource", 400);
26
+ }
27
+ if (resource.uri.length === 0 || resource.uri.length > 2048 || !/^[A-Za-z][A-Za-z0-9+.-]*:/u.test(resource.uri)) {
28
+ throw new WakeBridgeSdkError("resource.uri must be a bounded absolute URI", "invalid_resource", 400);
29
+ }
30
+ if (JSON.stringify(resource).length > 4096) {
31
+ throw new WakeBridgeSdkError("resource is too large", "oversized_event", 413);
32
+ }
33
+ }
34
+ function absoluteTimestamp(value, field) {
35
+ if (typeof value !== "string" || !ABSOLUTE_RFC3339.test(value)) {
36
+ throw new WakeBridgeSdkError(`${field} must be an absolute RFC3339 timestamp with Z or numeric offset`, "invalid_timestamp", 400);
37
+ }
38
+ const date = new Date(value);
39
+ if (Number.isNaN(date.getTime())) {
40
+ throw new WakeBridgeSdkError(`${field} is invalid`, "invalid_timestamp", 400);
41
+ }
42
+ return date.toISOString();
43
+ }
44
+ /** Validate and normalize the stable v1 producer payload. */
45
+ export function validateWakeEventInput(raw, now = new Date()) {
46
+ if (!raw || typeof raw.type !== "string" || !raw.type || raw.type.length > 200) {
47
+ throw new WakeBridgeSdkError("event type is required", "invalid_event", 400);
48
+ }
49
+ if (raw.schema_version != null && raw.schema_version !== EVENT_CONTRACT_VERSION) {
50
+ throw new WakeBridgeSdkError(`unsupported event schema_version: ${String(raw.schema_version)}`, "unsupported_schema", 400);
51
+ }
52
+ if (!raw.dedupe_key || typeof raw.dedupe_key !== "string" || raw.dedupe_key.length > 500) {
53
+ throw new WakeBridgeSdkError("dedupe_key is required and bounded", "invalid_event", 400);
54
+ }
55
+ validateNoPrompt(raw);
56
+ validateResource(raw.resource);
57
+ const metadata = raw.metadata ?? {};
58
+ if (!metadata || typeof metadata !== "object" || Array.isArray(metadata) || JSON.stringify(metadata).length > 8192) {
59
+ throw new WakeBridgeSdkError("metadata must be a bounded object", "oversized_event", 413);
60
+ }
61
+ if (raw.payload_preview != null && (typeof raw.payload_preview !== "string" || raw.payload_preview.length > 500)) {
62
+ throw new WakeBridgeSdkError("payload_preview is limited to 500 characters", "oversized_event", 413);
63
+ }
64
+ if (Number.isNaN(now.getTime())) {
65
+ throw new WakeBridgeSdkError("event clock is invalid", "invalid_event_clock", 500);
66
+ }
67
+ return {
68
+ schema_version: EVENT_CONTRACT_VERSION,
69
+ type: raw.type,
70
+ occurred_at: raw.occurred_at ? absoluteTimestamp(raw.occurred_at, "occurred_at") : now.toISOString(),
71
+ dedupe_key: raw.dedupe_key,
72
+ coalesce_key: raw.coalesce_key ?? null,
73
+ priority_hint: raw.priority_hint ?? null,
74
+ attention_channel_hint: raw.attention_channel_hint ?? null,
75
+ actor_ref: raw.actor_ref ?? null,
76
+ resource: raw.resource,
77
+ metadata,
78
+ payload_preview: raw.payload_preview ?? null,
79
+ idempotency_key: raw.idempotency_key ?? null,
80
+ };
81
+ }
82
+ const SOURCE_ID = /^[A-Za-z0-9_.:-]{1,128}$/u;
83
+ function localOrigin(raw) {
84
+ let url;
85
+ try {
86
+ url = new URL(raw);
87
+ }
88
+ catch {
89
+ throw new WakeBridgeSdkError("source push base_url is invalid", "invalid_source_push_config", 400);
90
+ }
91
+ if (url.protocol !== "http:" || !["127.0.0.1", "[::1]", "localhost"].includes(url.hostname)
92
+ || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
93
+ throw new WakeBridgeSdkError("source push base_url must be a credential-free loopback HTTP origin", "invalid_source_push_config", 400);
94
+ }
95
+ return url;
96
+ }
97
+ /** Narrow client for the credential-bound generic push ingress. */
98
+ export class SourcePushClient {
99
+ options;
100
+ origin;
101
+ fetchImpl;
102
+ timeoutMs;
103
+ constructor(options) {
104
+ this.options = options;
105
+ this.origin = localOrigin(options.base_url);
106
+ if (!SOURCE_ID.test(options.source)) {
107
+ throw new WakeBridgeSdkError("source push source is invalid", "invalid_source_push_config", 400);
108
+ }
109
+ if (typeof options.token !== "string" || options.token.length < 32) {
110
+ throw new WakeBridgeSdkError("source push token must contain at least 32 characters", "invalid_source_push_config", 400);
111
+ }
112
+ this.fetchImpl = options.fetch ?? fetch;
113
+ this.timeoutMs = options.timeout_ms ?? 15_000;
114
+ if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 300_000) {
115
+ throw new WakeBridgeSdkError("source push timeout_ms is invalid", "invalid_source_push_config", 400);
116
+ }
117
+ }
118
+ async emit(input) {
119
+ const event = validateWakeEventInput(input);
120
+ let response;
121
+ try {
122
+ response = await this.fetchImpl(new URL(`v1/ingress/${encodeURIComponent(this.options.source)}/events`, this.origin), {
123
+ method: "POST",
124
+ headers: { authorization: `Bearer ${this.options.token}`, "content-type": "application/json", accept: "application/json" },
125
+ body: JSON.stringify(event),
126
+ redirect: "error",
127
+ signal: AbortSignal.timeout(this.timeoutMs),
128
+ });
129
+ }
130
+ catch (error) {
131
+ throw new WakeBridgeSdkError(`source push is unavailable: ${String(error)}`, "source_push_unavailable", 503);
132
+ }
133
+ let body;
134
+ try {
135
+ body = await response.json();
136
+ }
137
+ catch {
138
+ body = null;
139
+ }
140
+ if (!response.ok) {
141
+ const remote = body && typeof body === "object" ? body : {};
142
+ throw new WakeBridgeSdkError(typeof remote.error === "string" ? remote.error : `source push returned HTTP ${response.status}`, typeof remote.code === "string" ? remote.code : "source_push_rejected", response.status);
143
+ }
144
+ const receipt = body;
145
+ if (!receipt?.event || receipt.event.source !== this.options.source || receipt.event.schema_version !== EVENT_CONTRACT_VERSION) {
146
+ throw new WakeBridgeSdkError("source push returned an invalid receipt", "invalid_source_push_receipt", 502);
147
+ }
148
+ return receipt;
149
+ }
150
+ }
151
+ export { WakeBridgeSdkError } from "./sdk-error.js";
152
+ //# sourceMappingURL=event-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-sdk.js","sourceRoot":"","sources":["../../src/event-sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type WakeBridge } from "./core.js";
2
+ import { type HostAdapter, type HostAdapterLifecycleContext, type HostAdapterManifest } from "./transport-sdk.js";
3
+ export interface HostBootstrapCredential {
4
+ id: string;
5
+ token: string;
6
+ adapter_kind: string;
7
+ host_kind: string;
8
+ attention_channels: string[];
9
+ }
10
+ /** Core-owned orchestration. This class is intentionally not a package export. */
11
+ export declare class HostAdapterRegistry {
12
+ private readonly adapters;
13
+ private started;
14
+ private bridge;
15
+ constructor(adapters?: HostAdapter[]);
16
+ register(adapter: HostAdapter): void;
17
+ list(): HostAdapterManifest[];
18
+ get(kind: string): HostAdapter | null;
19
+ start(bridge: WakeBridge, context: HostAdapterLifecycleContext): Promise<void>;
20
+ stop(): Promise<void>;
21
+ }
@@ -0,0 +1,59 @@
1
+ import { BridgeError } from "./core.js";
2
+ import { validateHostAdapterManifest, } from "./transport-sdk.js";
3
+ /** Core-owned orchestration. This class is intentionally not a package export. */
4
+ export class HostAdapterRegistry {
5
+ adapters = new Map();
6
+ started = [];
7
+ bridge = null;
8
+ constructor(adapters = []) {
9
+ for (const adapter of adapters)
10
+ this.register(adapter);
11
+ }
12
+ register(adapter) {
13
+ validateHostAdapterManifest(adapter.manifest);
14
+ if (adapter.kind !== adapter.manifest.adapter_kind) {
15
+ throw new BridgeError("adapter kind does not match manifest", "invalid_host_adapter", 400);
16
+ }
17
+ if (this.adapters.has(adapter.kind)) {
18
+ throw new BridgeError(`duplicate host adapter: ${adapter.kind}`, "duplicate_host_adapter", 409);
19
+ }
20
+ this.adapters.set(adapter.kind, adapter);
21
+ }
22
+ list() {
23
+ return [...this.adapters.values()].map((adapter) => adapter.manifest);
24
+ }
25
+ get(kind) {
26
+ return this.adapters.get(kind) ?? null;
27
+ }
28
+ async start(bridge, context) {
29
+ this.bridge = bridge;
30
+ for (const adapter of this.adapters.values()) {
31
+ const existing = bridge.transports.get(adapter.kind);
32
+ if (existing && existing !== adapter) {
33
+ throw new BridgeError(`transport kind already registered: ${adapter.kind}`, "duplicate_host_adapter", 409);
34
+ }
35
+ bridge.registerTransport(adapter);
36
+ this.started.push(adapter);
37
+ await adapter.start?.(context);
38
+ }
39
+ }
40
+ async stop() {
41
+ let firstError;
42
+ for (const adapter of [...this.started].reverse()) {
43
+ try {
44
+ await adapter.stop?.();
45
+ }
46
+ catch (error) {
47
+ firstError ??= error;
48
+ }
49
+ finally {
50
+ this.bridge?.unregisterTransport(adapter.kind, adapter);
51
+ }
52
+ }
53
+ this.started = [];
54
+ this.bridge = null;
55
+ if (firstError)
56
+ throw firstError;
57
+ }
58
+ }
59
+ //# sourceMappingURL=host-adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-adapter-registry.js","sourceRoot":"","sources":["../../src/host-adapter-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./version.js";
2
+ export * from "./event-sdk.js";
3
+ export * from "./source-sdk.js";
4
+ export * from "./transport-sdk.js";
5
+ export * from "./connector-catalog.js";
@@ -0,0 +1,6 @@
1
+ export * from "./version.js";
2
+ export * from "./event-sdk.js";
3
+ export * from "./source-sdk.js";
4
+ export * from "./transport-sdk.js";
5
+ export * from "./connector-catalog.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { BridgeConfig } from "./types.js";
2
+ export interface WakeBridgeInstanceConfigFile {
3
+ version: 1;
4
+ instance_id: string;
5
+ owner_id: string;
6
+ db_path: string;
7
+ timezone: string;
8
+ admin_token: string;
9
+ }
10
+ export interface InitializeInstanceOptions {
11
+ data_dir: string;
12
+ instance_id: string;
13
+ owner_id: string;
14
+ timezone?: string;
15
+ db_path?: string;
16
+ config_path?: string;
17
+ }
18
+ export declare function loadInstanceConfig(path: string): WakeBridgeInstanceConfigFile;
19
+ export declare function initializeInstance(options: InitializeInstanceOptions): {
20
+ config: WakeBridgeInstanceConfigFile;
21
+ config_path: string;
22
+ data_dir: string;
23
+ };
24
+ export declare function instanceConfigSecurity(path: string | undefined): {
25
+ configured: boolean;
26
+ path: string | null;
27
+ private_permissions: boolean | null;
28
+ database_exists: boolean | null;
29
+ database_private_permissions: boolean | null;
30
+ data_directory_private_permissions: boolean | null;
31
+ ready: boolean;
32
+ error: string | null;
33
+ };
34
+ export declare function instanceDataSecurity(dbPath: string): {
35
+ path: string;
36
+ exists: boolean;
37
+ private_permissions: boolean | null;
38
+ directory_private_permissions: boolean | null;
39
+ ready: boolean;
40
+ error: string | null;
41
+ };
42
+ export declare function bridgeConfigFromFile(path: string): BridgeConfig;
43
+ export declare function rotateOwnerCredential(path: string): {
44
+ config_path: string;
45
+ rotated: true;
46
+ };
@@ -0,0 +1,176 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync, } from "node:fs";
3
+ import { basename, dirname, isAbsolute, relative, resolve, sep } from "node:path";
4
+ import { WakeBridge, BridgeError } from "./core.js";
5
+ const INSTANCE_ID = /^[A-Za-z0-9_.:-]{1,128}$/u;
6
+ function assertPrivateMode(path, kind) {
7
+ if (process.platform === "win32")
8
+ return;
9
+ const mode = statSync(path).mode & 0o777;
10
+ if ((mode & 0o077) !== 0) {
11
+ throw new BridgeError(`${kind} must not be accessible by group or other users: ${path}`, "insecure_file_permissions", 400);
12
+ }
13
+ }
14
+ function assertWithin(dataDir, path, kind) {
15
+ const relation = relative(dataDir, path);
16
+ if (relation === "" || relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
17
+ throw new BridgeError(`${kind} must be a file inside data_dir`, "invalid_instance_config", 400);
18
+ }
19
+ }
20
+ export function loadInstanceConfig(path) {
21
+ let parsed;
22
+ try {
23
+ assertPrivateMode(path, "instance config");
24
+ parsed = JSON.parse(readFileSync(path, "utf8"));
25
+ }
26
+ catch (error) {
27
+ if (error instanceof BridgeError)
28
+ throw error;
29
+ throw new BridgeError(`instance config is unreadable: ${String(error)}`, "invalid_instance_config", 400);
30
+ }
31
+ const config = parsed;
32
+ if (config?.version !== 1 || !INSTANCE_ID.test(config.instance_id ?? "") || !INSTANCE_ID.test(config.owner_id ?? "")
33
+ || typeof config.db_path !== "string" || !isAbsolute(config.db_path)
34
+ || typeof config.timezone !== "string" || !config.timezone
35
+ || typeof config.admin_token !== "string" || config.admin_token.length < 32) {
36
+ throw new BridgeError("instance config is invalid", "invalid_instance_config", 400);
37
+ }
38
+ try {
39
+ new Intl.DateTimeFormat("en-US", { timeZone: config.timezone }).format(new Date());
40
+ }
41
+ catch {
42
+ throw new BridgeError("instance config timezone is invalid", "invalid_instance_config", 400);
43
+ }
44
+ return config;
45
+ }
46
+ export function initializeInstance(options) {
47
+ if (!INSTANCE_ID.test(options.instance_id) || !INSTANCE_ID.test(options.owner_id)) {
48
+ throw new BridgeError("explicit valid instance_id and owner_id are required", "invalid_instance_config", 400);
49
+ }
50
+ const dataDir = resolve(options.data_dir);
51
+ const configPath = resolve(options.config_path ?? resolve(dataDir, "wakebridge.config.json"));
52
+ const dbPath = resolve(options.db_path ?? resolve(dataDir, "wake-bridge.sqlite"));
53
+ assertWithin(dataDir, configPath, "config_path");
54
+ assertWithin(dataDir, dbPath, "db_path");
55
+ if (existsSync(configPath)) {
56
+ throw new BridgeError(`instance config already exists: ${configPath}`, "instance_already_initialized", 409);
57
+ }
58
+ if (existsSync(dbPath)) {
59
+ throw new BridgeError(`instance database already exists without a matching config: ${dbPath}`, "instance_database_exists", 409);
60
+ }
61
+ try {
62
+ new Intl.DateTimeFormat("en-US", { timeZone: options.timezone ?? "UTC" }).format(new Date());
63
+ }
64
+ catch {
65
+ throw new BridgeError("timezone must be a valid IANA timezone", "invalid_instance_config", 400);
66
+ }
67
+ if (!existsSync(dataDir))
68
+ mkdirSync(dataDir, { recursive: true, mode: 0o700 });
69
+ if (!statSync(dataDir).isDirectory())
70
+ throw new BridgeError("data_dir must be a directory", "invalid_instance_config", 400);
71
+ assertPrivateMode(dataDir, "data_dir");
72
+ mkdirSync(dirname(dbPath), { recursive: true, mode: 0o700 });
73
+ mkdirSync(dirname(configPath), { recursive: true, mode: 0o700 });
74
+ const config = {
75
+ version: 1,
76
+ instance_id: options.instance_id,
77
+ owner_id: options.owner_id,
78
+ db_path: dbPath,
79
+ timezone: options.timezone ?? "UTC",
80
+ admin_token: randomBytes(32).toString("base64url"),
81
+ };
82
+ const bridge = new WakeBridge(config, { recoverDispatchLeases: false });
83
+ bridge.close();
84
+ chmodSync(dbPath, 0o600);
85
+ for (const suffix of ["-wal", "-shm"]) {
86
+ if (existsSync(`${dbPath}${suffix}`))
87
+ chmodSync(`${dbPath}${suffix}`, 0o600);
88
+ }
89
+ writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, { encoding: "utf8", mode: 0o600, flag: "wx" });
90
+ chmodSync(configPath, 0o600);
91
+ return { config, config_path: configPath, data_dir: dataDir };
92
+ }
93
+ export function instanceConfigSecurity(path) {
94
+ if (!path)
95
+ return {
96
+ configured: false,
97
+ path: null,
98
+ private_permissions: null,
99
+ database_exists: null,
100
+ database_private_permissions: null,
101
+ data_directory_private_permissions: null,
102
+ ready: true,
103
+ error: null,
104
+ };
105
+ try {
106
+ assertPrivateMode(path, "instance config");
107
+ const config = loadInstanceConfig(path);
108
+ if (!existsSync(config.db_path))
109
+ throw new BridgeError(`instance database does not exist: ${config.db_path}`, "invalid_instance_config", 400);
110
+ assertPrivateMode(config.db_path, "instance database");
111
+ assertPrivateMode(dirname(config.db_path), "instance data directory");
112
+ return {
113
+ configured: true,
114
+ path: resolve(path),
115
+ private_permissions: true,
116
+ database_exists: true,
117
+ database_private_permissions: true,
118
+ data_directory_private_permissions: true,
119
+ ready: true,
120
+ error: null,
121
+ };
122
+ }
123
+ catch (error) {
124
+ return {
125
+ configured: true,
126
+ path: resolve(path),
127
+ private_permissions: false,
128
+ database_exists: null,
129
+ database_private_permissions: null,
130
+ data_directory_private_permissions: null,
131
+ ready: false,
132
+ error: error instanceof Error ? error.message : String(error),
133
+ };
134
+ }
135
+ }
136
+ export function instanceDataSecurity(dbPath) {
137
+ const path = resolve(dbPath);
138
+ try {
139
+ if (!existsSync(path))
140
+ throw new BridgeError(`instance database does not exist: ${path}`, "invalid_instance_config", 400);
141
+ assertPrivateMode(path, "instance database");
142
+ assertPrivateMode(dirname(path), "instance data directory");
143
+ return { path, exists: true, private_permissions: true, directory_private_permissions: true, ready: true, error: null };
144
+ }
145
+ catch (error) {
146
+ return {
147
+ path,
148
+ exists: existsSync(path),
149
+ private_permissions: null,
150
+ directory_private_permissions: null,
151
+ ready: false,
152
+ error: error instanceof Error ? error.message : String(error),
153
+ };
154
+ }
155
+ }
156
+ export function bridgeConfigFromFile(path) {
157
+ const config = loadInstanceConfig(path);
158
+ return {
159
+ instance_id: config.instance_id,
160
+ owner_id: config.owner_id,
161
+ db_path: config.db_path,
162
+ timezone: config.timezone,
163
+ admin_token: config.admin_token,
164
+ };
165
+ }
166
+ export function rotateOwnerCredential(path) {
167
+ const configPath = resolve(path);
168
+ const config = loadInstanceConfig(configPath);
169
+ const next = { ...config, admin_token: randomBytes(32).toString("base64url") };
170
+ const temporary = resolve(dirname(configPath), `.${basename(configPath)}.${randomBytes(8).toString("hex")}.tmp`);
171
+ writeFileSync(temporary, `${JSON.stringify(next, null, 2)}\n`, { encoding: "utf8", mode: 0o600, flag: "wx" });
172
+ chmodSync(temporary, 0o600);
173
+ renameSync(temporary, configPath);
174
+ return { config_path: configPath, rotated: true };
175
+ }
176
+ //# sourceMappingURL=instance-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-config.js","sourceRoot":"","sources":["../../src/instance-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { WakeBridge } from "./core.js";
2
+ import type { BridgeConfig, JsonValue } from "./types.js";
3
+ import type { AgentSourceControl } from "./source-control-client.js";
4
+ /** MCP protocol version understood by this local stdio server. */
5
+ export declare const MCP_PROTOCOL_VERSION = "2025-06-18";
6
+ export declare const MCP_SERVER_NAME = "wake-bridge";
7
+ export declare const MCP_SERVER_VERSION = "0.9.0-preview.8";
8
+ type RpcId = string | number | null;
9
+ type JsonObject = Record<string, unknown>;
10
+ type StdioInput = NodeJS.ReadableStream;
11
+ type StdioOutput = NodeJS.WritableStream;
12
+ export interface McpRequest {
13
+ jsonrpc: "2.0";
14
+ id?: RpcId;
15
+ method: string;
16
+ params?: JsonObject;
17
+ }
18
+ export interface McpResponse {
19
+ jsonrpc: "2.0";
20
+ id: RpcId;
21
+ result?: JsonObject;
22
+ error?: {
23
+ code: number;
24
+ message: string;
25
+ data?: JsonValue;
26
+ };
27
+ }
28
+ export interface McpServerOptions {
29
+ bridge: WakeBridge;
30
+ source_control?: AgentSourceControl;
31
+ }
32
+ /**
33
+ * In-process MCP implementation. It deliberately has no wait/warm tool: a
34
+ * stdio invocation must finish so normal turns can settle and cold transport
35
+ * remains the lifecycle baseline.
36
+ */
37
+ export declare class WakeBridgeMcpServer {
38
+ readonly bridge: WakeBridge;
39
+ private readonly sourceControl?;
40
+ constructor(options: McpServerOptions | WakeBridge);
41
+ handleRequest(request: unknown): Promise<McpResponse | null>;
42
+ callTool(name: string, args: JsonObject): Promise<JsonObject>;
43
+ private sources;
44
+ private errorValue;
45
+ }
46
+ export declare function createMcpServer(options: McpServerOptions | WakeBridge): WakeBridgeMcpServer;
47
+ /** Run newline-delimited JSON-RPC over stdin/stdout, with no stdout logging. */
48
+ export declare function runMcpStdio(server: WakeBridgeMcpServer, input?: StdioInput, output?: StdioOutput): Promise<void>;
49
+ /** Construct a bridge and serve it until stdin closes. Used by the CLI. */
50
+ export declare function runMcp(config: BridgeConfig): Promise<void>;
51
+ export default WakeBridgeMcpServer;