@xopcai/xopc 0.0.91 → 0.0.92

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 (134) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/agents-uwPn7ZW9.js +222 -0
  4. package/dist/gateway/static/root/assets/{apps-page-CIC8bmvZ.js → apps-page-CWKdhSPU.js} +1 -1
  5. package/dist/gateway/static/root/assets/channels-settings-hEhW7Mbk.js +1 -0
  6. package/dist/gateway/static/root/assets/{channels-status-swr-CYWL5DLD.js → channels-status-swr-XzddfJW2.js} +1 -1
  7. package/dist/gateway/static/root/assets/{cron-api-TVqLlGAC.js → cron-api--I8LJ44S.js} +1 -1
  8. package/dist/gateway/static/root/assets/cron-page-B0kvgZGR.js +1 -0
  9. package/dist/gateway/static/root/assets/{dist-CUV1uY5f.js → dist-CYgHMQO0.js} +1 -1
  10. package/dist/gateway/static/root/assets/{extension-debug-page-mTLHRDp1.js → extension-debug-page-6cRP0nA9.js} +1 -1
  11. package/dist/gateway/static/root/assets/{extension-page-iI8BI7WK.js → extension-page-DpwIkspI.js} +1 -1
  12. package/dist/gateway/static/root/assets/{extension-settings-page-ByXcdubM.js → extension-settings-page-DYbnQUxH.js} +1 -1
  13. package/dist/gateway/static/root/assets/{fetch-BWtQq_Ys.js → fetch-DTN0w7rV.js} +1 -1
  14. package/dist/gateway/static/root/assets/{field-primitives-BsZ-4VT5.js → field-primitives-CslW6HwD.js} +1 -1
  15. package/dist/gateway/static/root/assets/heartbeat-config-api-2UiKevxG.js +1 -0
  16. package/dist/gateway/static/root/assets/index-BUKUv7QW.css +1 -0
  17. package/dist/gateway/static/root/assets/{index-CKkR-v9U.js → index-DnevRVa6.js} +82 -82
  18. package/dist/gateway/static/root/assets/logs-page-sOP4TXJ4.js +1 -0
  19. package/dist/gateway/static/root/assets/{note-detail-page-DJ2Mb4x7.js → note-detail-page-DvW2qg4i.js} +3 -3
  20. package/dist/gateway/static/root/assets/{note-time-JLBPSLzK.js → note-time-BEiibLJv.js} +1 -1
  21. package/dist/gateway/static/root/assets/{notes-page-BE-75qz9.js → notes-page-BFQaquHU.js} +1 -1
  22. package/dist/gateway/static/root/assets/sessions-page-CptjDKAX.js +1 -0
  23. package/dist/gateway/static/root/assets/settings-advanced-gate-BctKqHcf.js +2 -0
  24. package/dist/gateway/static/root/assets/{settings-form-section-DSYCknxM.js → settings-form-section-QJh5ruel.js} +1 -1
  25. package/dist/gateway/static/root/assets/settings-page-V3p-hISB.js +2 -0
  26. package/dist/gateway/static/root/assets/{share-preview-page-awRqs4hV.js → share-preview-page-DBsvvbmD.js} +1 -1
  27. package/dist/gateway/static/root/assets/skills-page-q2zPUJAR.js +2 -0
  28. package/dist/gateway/static/root/assets/{theme-store-BC-42BoZ.js → theme-store-ht5iswWS.js} +1 -1
  29. package/dist/gateway/static/root/assets/{url-CY1RQKTU.js → url-CWWpfkq1.js} +2 -2
  30. package/dist/gateway/static/root/assets/{utils-DX3TQuap.js → utils-DhPv9xoB.js} +1 -1
  31. package/dist/gateway/static/root/assets/voice-api-key-field-DLSKUipa.js +1 -0
  32. package/dist/gateway/static/root/assets/{workflow-page.utils-ClC37yEp.js → workflow-page.utils-CJqnPWkW.js} +1 -1
  33. package/dist/gateway/static/root/assets/workflows-page-DRRQ1A0l.js +27 -0
  34. package/dist/gateway/static/root/index.html +5 -5
  35. package/dist/package.js +1 -1
  36. package/dist/src/agent/mcp/bundle-mcp-config.d.ts +2 -9
  37. package/dist/src/agent/mcp/bundle-mcp-config.js +10 -34
  38. package/dist/src/agent/mcp/bundle-mcp-config.js.map +1 -1
  39. package/dist/src/agent/mcp/bundle-mcp-policy.js +2 -2
  40. package/dist/src/agent/mcp/bundle-mcp-policy.js.map +1 -1
  41. package/dist/src/agent/mcp/bundle-mcp-runtime.js +4 -4
  42. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  43. package/dist/src/agent/mcp/index.js +2 -2
  44. package/dist/src/cli/command-catalog.js +0 -4
  45. package/dist/src/cli/command-catalog.js.map +1 -1
  46. package/dist/src/cli/command-loaders.js +1 -2
  47. package/dist/src/cli/command-loaders.js.map +1 -1
  48. package/dist/src/cli/command-manifest.js +0 -4
  49. package/dist/src/cli/command-manifest.js.map +1 -1
  50. package/dist/src/config/index.d.ts +0 -1
  51. package/dist/src/config/index.js +1 -2
  52. package/dist/src/config/index.js.map +1 -1
  53. package/dist/src/config/schema.d.ts +36 -6
  54. package/dist/src/config/schema.js +13 -11
  55. package/dist/src/config/schema.js.map +1 -1
  56. package/dist/src/connectors/builtin-catalog.d.ts +2 -0
  57. package/dist/src/connectors/builtin-catalog.js +152 -0
  58. package/dist/src/connectors/builtin-catalog.js.map +1 -0
  59. package/dist/src/connectors/catalog.d.ts +5 -0
  60. package/dist/src/connectors/catalog.js +13 -0
  61. package/dist/src/connectors/catalog.js.map +1 -0
  62. package/dist/src/connectors/health.d.ts +3 -0
  63. package/dist/src/connectors/health.js +61 -0
  64. package/dist/src/connectors/health.js.map +1 -0
  65. package/dist/src/connectors/install.d.ts +5 -0
  66. package/dist/src/connectors/install.js +46 -0
  67. package/dist/src/connectors/install.js.map +1 -0
  68. package/dist/src/connectors/instances.d.ts +4 -0
  69. package/dist/src/connectors/instances.js +43 -0
  70. package/dist/src/connectors/instances.js.map +1 -0
  71. package/dist/src/connectors/materialize.d.ts +9 -0
  72. package/dist/src/connectors/materialize.js +76 -0
  73. package/dist/src/connectors/materialize.js.map +1 -0
  74. package/dist/src/connectors/oauth.d.ts +22 -0
  75. package/dist/src/connectors/oauth.js +99 -0
  76. package/dist/src/connectors/oauth.js.map +1 -0
  77. package/dist/src/connectors/providers.d.ts +9 -0
  78. package/dist/src/connectors/providers.js +20 -0
  79. package/dist/src/connectors/providers.js.map +1 -0
  80. package/dist/src/connectors/secret-store.d.ts +7 -0
  81. package/dist/src/connectors/secret-store.js +47 -0
  82. package/dist/src/connectors/secret-store.js.map +1 -0
  83. package/dist/src/connectors/types.d.ts +102 -0
  84. package/dist/src/connectors/types.js +1 -0
  85. package/dist/src/connectors/usage.d.ts +6 -0
  86. package/dist/src/connectors/usage.js +63 -0
  87. package/dist/src/connectors/usage.js.map +1 -0
  88. package/dist/src/gateway/heartbeat/service.js +1 -1
  89. package/dist/src/gateway/hono/routes/connectors.d.ts +3 -0
  90. package/dist/src/gateway/hono/routes/connectors.js +177 -0
  91. package/dist/src/gateway/hono/routes/connectors.js.map +1 -0
  92. package/dist/src/gateway/hono/routes/home.d.ts +12 -0
  93. package/dist/src/gateway/hono/routes/home.js +50 -0
  94. package/dist/src/gateway/hono/routes/home.js.map +1 -0
  95. package/dist/src/gateway/hono/routes/lazy-bundles.js +12 -4
  96. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  97. package/dist/src/gateway/hono/routes/notes.js +31 -0
  98. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  99. package/dist/src/heartbeat/index.js +1 -1
  100. package/dist/src/mcp/channel-bridge.js +1 -1
  101. package/dist/src/mcp/channel-bridge.js.map +1 -1
  102. package/dist/src/notes/index.d.ts +1 -1
  103. package/dist/src/notes/service.d.ts +11 -0
  104. package/dist/src/notes/service.js +42 -0
  105. package/dist/src/notes/service.js.map +1 -1
  106. package/dist/src/notes/store.d.ts +1 -0
  107. package/dist/src/notes/store.js +29 -4
  108. package/dist/src/notes/store.js.map +1 -1
  109. package/dist/src/notes/types.d.ts +39 -2
  110. package/dist/src/session/store.d.ts +2 -0
  111. package/dist/src/session/store.js +21 -1
  112. package/dist/src/session/store.js.map +1 -1
  113. package/package.json +1 -1
  114. package/dist/gateway/static/root/assets/agents-bVWUlrlD.js +0 -222
  115. package/dist/gateway/static/root/assets/channels-settings-C8G8RAAP.js +0 -1
  116. package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +0 -2
  117. package/dist/gateway/static/root/assets/cron-page-BtcFYlvv.js +0 -1
  118. package/dist/gateway/static/root/assets/heartbeat-config-api-WjTsRLCU.js +0 -1
  119. package/dist/gateway/static/root/assets/index-VlELBY99.css +0 -1
  120. package/dist/gateway/static/root/assets/logs-page-ClnIpxfd.js +0 -1
  121. package/dist/gateway/static/root/assets/sessions-page-bJJkWtTl.js +0 -1
  122. package/dist/gateway/static/root/assets/settings-page-WcMXLq2U.js +0 -3
  123. package/dist/gateway/static/root/assets/skills-page-Lu-i1JG7.js +0 -2
  124. package/dist/gateway/static/root/assets/voice-api-key-field-B5uKlDqA.js +0 -1
  125. package/dist/gateway/static/root/assets/workflows-page-C7VhIXtR.js +0 -27
  126. package/dist/src/cli/commands/mcp.d.ts +0 -4
  127. package/dist/src/cli/commands/mcp.js +0 -85
  128. package/dist/src/cli/commands/mcp.js.map +0 -1
  129. package/dist/src/config/mcp-config.d.ts +0 -34
  130. package/dist/src/config/mcp-config.js +0 -116
  131. package/dist/src/config/mcp-config.js.map +0 -1
  132. package/dist/src/gateway/hono/routes/mcp.d.ts +0 -3
  133. package/dist/src/gateway/hono/routes/mcp.js +0 -99
  134. package/dist/src/gateway/hono/routes/mcp.js.map +0 -1
@@ -0,0 +1,102 @@
1
+ export type ConnectorKind = 'mcp' | 'cli' | 'http' | 'channel' | 'browser' | 'extension' | 'builtin';
2
+ export type ConnectorCategory = 'code' | 'docs' | 'browser' | 'data' | 'automation' | 'custom';
3
+ export type ConnectorCapability = 'tools' | 'resources' | 'prompts' | 'context' | 'channel' | 'events' | 'ui' | 'memory_source' | 'workflows' | 'auth.apiKey' | 'auth.oauth' | 'runtime.mcp.stdio' | 'runtime.mcp.sse' | 'runtime.mcp.streamableHttp';
4
+ export type ConnectorAuthMode = 'none' | 'apiKey' | 'oauth';
5
+ export type ConnectorSecretReference = {
6
+ xopcSecretRef: {
7
+ provider: string;
8
+ fieldKey: string;
9
+ };
10
+ };
11
+ export type ConnectorSecretField = {
12
+ key: string;
13
+ label: string;
14
+ description?: string;
15
+ required: boolean;
16
+ };
17
+ export type ConnectorConfigField = {
18
+ key: string;
19
+ label: string;
20
+ type: 'string' | 'number' | 'boolean' | 'json' | 'path';
21
+ required?: boolean;
22
+ placeholder?: string;
23
+ defaultValue?: unknown;
24
+ description?: string;
25
+ };
26
+ export type ConnectorRuntimeDefinition = {
27
+ type: 'mcp';
28
+ serverId: string;
29
+ serverTemplate: Record<string, unknown>;
30
+ };
31
+ export type ConnectorDefinition = {
32
+ id: string;
33
+ version: string;
34
+ displayName: string;
35
+ description: string;
36
+ category: ConnectorCategory;
37
+ kind: ConnectorKind;
38
+ source: 'builtin' | 'extension' | 'custom' | 'registry';
39
+ capabilities: ConnectorCapability[];
40
+ tags?: string[];
41
+ auth: {
42
+ mode: ConnectorAuthMode;
43
+ };
44
+ setup: {
45
+ secrets?: ConnectorSecretField[];
46
+ config?: ConnectorConfigField[];
47
+ };
48
+ runtime: ConnectorRuntimeDefinition;
49
+ };
50
+ export type ConnectorInstallInput = {
51
+ secrets?: Record<string, unknown>;
52
+ config?: Record<string, unknown>;
53
+ };
54
+ export type ConnectorUsageRecord = {
55
+ lastHealthCheckAt?: string;
56
+ lastHealthStatus?: ConnectorHealthStatus;
57
+ lastToolCount?: number;
58
+ };
59
+ export type ConnectorAuditRecord = {
60
+ at: string;
61
+ action: 'installed' | 'removed' | 'health_check';
62
+ status?: ConnectorHealthStatus;
63
+ ok?: boolean;
64
+ toolCount?: number;
65
+ };
66
+ export type ConnectorInstance = {
67
+ instanceId: string;
68
+ connectorId: string;
69
+ displayName: string;
70
+ enabled: boolean;
71
+ status: 'installed' | 'not_configured' | 'failed' | 'disabled';
72
+ secretStatus: Record<string, boolean>;
73
+ materialized: {
74
+ type: 'mcp';
75
+ serverId: string;
76
+ };
77
+ usage: ConnectorUsageRecord;
78
+ audit: ConnectorAuditRecord[];
79
+ };
80
+ export type ConnectorHealthStatus = 'ok' | 'server_not_found' | 'missing_secret' | 'startup_failed' | 'tools_list_failed' | 'timeout' | 'network_failed' | 'unknown_error';
81
+ export type ConnectorHealthResult = {
82
+ serverId: string;
83
+ ok: boolean;
84
+ status: ConnectorHealthStatus;
85
+ toolCount: number;
86
+ tools: Array<{
87
+ name: string;
88
+ shortName?: string;
89
+ description?: string;
90
+ }>;
91
+ error?: string;
92
+ action?: string;
93
+ };
94
+ export type ConnectorDetail = {
95
+ definition: ConnectorDefinition;
96
+ instances: ConnectorInstance[];
97
+ };
98
+ export type ManagedConnectorMarker = {
99
+ managed: true;
100
+ connectorId: string;
101
+ version: string;
102
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { Config } from '../config/schema.js';
2
+ import type { ConnectorAuditRecord, ConnectorHealthResult, ConnectorUsageRecord } from './types.js';
3
+ export declare function getConnectorUsageFromMarker(marker: unknown): ConnectorUsageRecord;
4
+ export declare function getConnectorAuditFromMarker(marker: unknown): ConnectorAuditRecord[];
5
+ export declare function appendConnectorAuditRecord(config: Config, instanceId: string, record: Omit<ConnectorAuditRecord, 'at'>): void;
6
+ export declare function recordConnectorHealthUsage(config: Config, instanceId: string, result: ConnectorHealthResult): void;
@@ -0,0 +1,63 @@
1
+ import { isManagedConnectorServer } from "./materialize.js";
2
+ //#region src/connectors/usage.ts
3
+ const MAX_AUDIT_RECORDS = 50;
4
+ function getManagedConnectorMarker(config, instanceId) {
5
+ const server = config.mcp?.servers?.[instanceId];
6
+ if (!isManagedConnectorServer(server)) return;
7
+ return server.xopcConnector;
8
+ }
9
+ function getConnectorUsageFromMarker(marker) {
10
+ if (!marker || typeof marker !== "object" || Array.isArray(marker)) return {};
11
+ const usage = marker.usage;
12
+ if (!usage || typeof usage !== "object" || Array.isArray(usage)) return {};
13
+ const record = usage;
14
+ return {
15
+ lastHealthCheckAt: typeof record.lastHealthCheckAt === "string" ? record.lastHealthCheckAt : void 0,
16
+ lastHealthStatus: typeof record.lastHealthStatus === "string" ? record.lastHealthStatus : void 0,
17
+ lastToolCount: typeof record.lastToolCount === "number" ? record.lastToolCount : void 0
18
+ };
19
+ }
20
+ function getConnectorAuditFromMarker(marker) {
21
+ if (!marker || typeof marker !== "object" || Array.isArray(marker)) return [];
22
+ const audit = marker.audit;
23
+ if (!Array.isArray(audit)) return [];
24
+ return audit.flatMap((entry) => {
25
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
26
+ const record = entry;
27
+ if (typeof record.at !== "string" || typeof record.action !== "string") return [];
28
+ return [{
29
+ at: record.at,
30
+ action: record.action,
31
+ status: typeof record.status === "string" ? record.status : void 0,
32
+ ok: typeof record.ok === "boolean" ? record.ok : void 0,
33
+ toolCount: typeof record.toolCount === "number" ? record.toolCount : void 0
34
+ }];
35
+ });
36
+ }
37
+ function appendConnectorAuditRecord(config, instanceId, record) {
38
+ const marker = getManagedConnectorMarker(config, instanceId);
39
+ if (!marker) return;
40
+ marker.audit = [...(Array.isArray(marker.audit) ? marker.audit : []).slice(-MAX_AUDIT_RECORDS + 1), {
41
+ ...record,
42
+ at: (/* @__PURE__ */ new Date()).toISOString()
43
+ }];
44
+ }
45
+ function recordConnectorHealthUsage(config, instanceId, result) {
46
+ const marker = getManagedConnectorMarker(config, instanceId);
47
+ if (!marker) return;
48
+ marker.usage = {
49
+ lastHealthCheckAt: (/* @__PURE__ */ new Date()).toISOString(),
50
+ lastHealthStatus: result.status,
51
+ lastToolCount: result.toolCount
52
+ };
53
+ appendConnectorAuditRecord(config, instanceId, {
54
+ action: "health_check",
55
+ status: result.status,
56
+ ok: result.ok,
57
+ toolCount: result.toolCount
58
+ });
59
+ }
60
+ //#endregion
61
+ export { appendConnectorAuditRecord, getConnectorAuditFromMarker, getConnectorUsageFromMarker, recordConnectorHealthUsage };
62
+
63
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","names":[],"sources":["../../../src/connectors/usage.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { isManagedConnectorServer } from './materialize.js';\nimport type { ConnectorAuditRecord, ConnectorHealthResult, ConnectorUsageRecord } from './types.js';\n\nconst MAX_AUDIT_RECORDS = 50;\n\nfunction getManagedConnectorMarker(config: Config, instanceId: string): Record<string, unknown> | undefined {\n const server = config.mcp?.servers?.[instanceId];\n if (!isManagedConnectorServer(server)) {\n return undefined;\n }\n return server.xopcConnector as Record<string, unknown>;\n}\n\nexport function getConnectorUsageFromMarker(marker: unknown): ConnectorUsageRecord {\n if (!marker || typeof marker !== 'object' || Array.isArray(marker)) {\n return {};\n }\n const usage = (marker as Record<string, unknown>).usage;\n if (!usage || typeof usage !== 'object' || Array.isArray(usage)) {\n return {};\n }\n const record = usage as Record<string, unknown>;\n return {\n lastHealthCheckAt: typeof record.lastHealthCheckAt === 'string' ? record.lastHealthCheckAt : undefined,\n lastHealthStatus: typeof record.lastHealthStatus === 'string' ? record.lastHealthStatus as ConnectorUsageRecord['lastHealthStatus'] : undefined,\n lastToolCount: typeof record.lastToolCount === 'number' ? record.lastToolCount : undefined,\n };\n}\n\nexport function getConnectorAuditFromMarker(marker: unknown): ConnectorAuditRecord[] {\n if (!marker || typeof marker !== 'object' || Array.isArray(marker)) {\n return [];\n }\n const audit = (marker as Record<string, unknown>).audit;\n if (!Array.isArray(audit)) {\n return [];\n }\n return audit.flatMap((entry) => {\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {\n return [];\n }\n const record = entry as Record<string, unknown>;\n if (typeof record.at !== 'string' || typeof record.action !== 'string') {\n return [];\n }\n return [{\n at: record.at,\n action: record.action as ConnectorAuditRecord['action'],\n status: typeof record.status === 'string' ? record.status as ConnectorAuditRecord['status'] : undefined,\n ok: typeof record.ok === 'boolean' ? record.ok : undefined,\n toolCount: typeof record.toolCount === 'number' ? record.toolCount : undefined,\n }];\n });\n}\n\nexport function appendConnectorAuditRecord(\n config: Config,\n instanceId: string,\n record: Omit<ConnectorAuditRecord, 'at'>,\n): void {\n const marker = getManagedConnectorMarker(config, instanceId);\n if (!marker) {\n return;\n }\n const existing = Array.isArray(marker.audit) ? marker.audit : [];\n marker.audit = [\n ...existing.slice(-MAX_AUDIT_RECORDS + 1),\n { ...record, at: new Date().toISOString() },\n ];\n}\n\nexport function recordConnectorHealthUsage(\n config: Config,\n instanceId: string,\n result: ConnectorHealthResult,\n): void {\n const marker = getManagedConnectorMarker(config, instanceId);\n if (!marker) {\n return;\n }\n marker.usage = {\n lastHealthCheckAt: new Date().toISOString(),\n lastHealthStatus: result.status,\n lastToolCount: result.toolCount,\n } satisfies ConnectorUsageRecord;\n appendConnectorAuditRecord(config, instanceId, {\n action: 'health_check',\n status: result.status,\n ok: result.ok,\n toolCount: result.toolCount,\n });\n}\n"],"mappings":";;AAIA,MAAM,oBAAoB;AAE1B,SAAS,0BAA0B,QAAgB,YAAyD;CAC1G,MAAM,SAAS,OAAO,KAAK,UAAU;AACrC,KAAI,CAAC,yBAAyB,OAAO,CACnC;AAEF,QAAO,OAAO;;AAGhB,SAAgB,4BAA4B,QAAuC;AACjF,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,QAAO,EAAE;CAEX,MAAM,QAAS,OAAmC;AAClD,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO,EAAE;CAEX,MAAM,SAAS;AACf,QAAO;EACL,mBAAmB,OAAO,OAAO,sBAAsB,WAAW,OAAO,oBAAoB,KAAA;EAC7F,kBAAkB,OAAO,OAAO,qBAAqB,WAAW,OAAO,mBAA+D,KAAA;EACtI,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,KAAA;EAClF;;AAGH,SAAgB,4BAA4B,QAAyC;AACnF,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,QAAO,EAAE;CAEX,MAAM,QAAS,OAAmC;AAClD,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,QAAO,EAAE;AAEX,QAAO,MAAM,SAAS,UAAU;AAC9B,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO,EAAE;EAEX,MAAM,SAAS;AACf,MAAI,OAAO,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,SAC5D,QAAO,EAAE;AAEX,SAAO,CAAC;GACN,IAAI,OAAO;GACX,QAAQ,OAAO;GACf,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAA2C,KAAA;GAC9F,IAAI,OAAO,OAAO,OAAO,YAAY,OAAO,KAAK,KAAA;GACjD,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY,KAAA;GACtE,CAAC;GACF;;AAGJ,SAAgB,2BACd,QACA,YACA,QACM;CACN,MAAM,SAAS,0BAA0B,QAAQ,WAAW;AAC5D,KAAI,CAAC,OACH;AAGF,QAAO,QAAQ,CACb,IAFe,MAAM,QAAQ,OAAO,MAAM,GAAG,OAAO,QAAQ,EAAE,EAElD,MAAM,CAAC,oBAAoB,EAAE,EACzC;EAAE,GAAG;EAAQ,qBAAI,IAAI,MAAM,EAAC,aAAa;EAAE,CAC5C;;AAGH,SAAgB,2BACd,QACA,YACA,QACM;CACN,MAAM,SAAS,0BAA0B,QAAQ,WAAW;AAC5D,KAAI,CAAC,OACH;AAEF,QAAO,QAAQ;EACb,oCAAmB,IAAI,MAAM,EAAC,aAAa;EAC3C,kBAAkB,OAAO;EACzB,eAAe,OAAO;EACvB;AACD,4BAA2B,QAAQ,YAAY;EAC7C,QAAQ;EACR,QAAQ,OAAO;EACf,IAAI,OAAO;EACX,WAAW,OAAO;EACnB,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
4
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
4
5
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
5
6
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
6
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
7
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
8
8
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
9
9
  import { readFile } from "fs/promises";
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerConnectorRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,177 @@
1
+ import { listConnectorProviders } from "../../../connectors/providers.js";
2
+ import { getConnectorDefinition, listConnectorCatalog } from "../../../connectors/catalog.js";
3
+ import { recordConnectorHealthUsage } from "../../../connectors/usage.js";
4
+ import { getConnectorInstance, listConnectorInstances } from "../../../connectors/instances.js";
5
+ import { testConnectorInstance } from "../../../connectors/health.js";
6
+ import { completeConnectorOAuth, startConnectorOAuth } from "../../../connectors/oauth.js";
7
+ import { installConnector, uninstallConnector } from "../../../connectors/install.js";
8
+ //#region src/gateway/hono/routes/connectors.ts
9
+ function errorMessage(error) {
10
+ return error instanceof Error ? error.message : String(error);
11
+ }
12
+ function registerConnectorRoutes(authenticated, deps) {
13
+ const { service, strictRateLimitMiddleware } = deps;
14
+ authenticated.get("/api/connectors/catalog", (c) => {
15
+ return c.json({
16
+ ok: true,
17
+ payload: {
18
+ connectors: listConnectorCatalog(),
19
+ providers: listConnectorProviders().map((provider) => ({
20
+ id: provider.id,
21
+ displayName: provider.displayName
22
+ }))
23
+ }
24
+ });
25
+ });
26
+ authenticated.get("/api/connectors/installed", (c) => {
27
+ const config = service.currentConfig;
28
+ return c.json({
29
+ ok: true,
30
+ payload: { instances: listConnectorInstances(config) }
31
+ });
32
+ });
33
+ authenticated.get("/api/connectors/:id", (c) => {
34
+ const connectorId = c.req.param("id");
35
+ const connector = getConnectorDefinition(connectorId);
36
+ if (!connector) return c.json({
37
+ ok: false,
38
+ error: `Unknown connector: ${connectorId}`
39
+ }, 404);
40
+ const config = service.currentConfig;
41
+ const instances = listConnectorInstances(config).filter((instance) => instance.connectorId === connectorId);
42
+ return c.json({
43
+ ok: true,
44
+ payload: {
45
+ connector,
46
+ instances
47
+ }
48
+ });
49
+ });
50
+ authenticated.post("/api/connectors/approvals/respond", async (c) => {
51
+ const body = await c.req.json().catch(() => ({}));
52
+ return c.json({
53
+ ok: true,
54
+ payload: {
55
+ acknowledged: true,
56
+ body
57
+ }
58
+ });
59
+ });
60
+ authenticated.post("/api/connectors/:id/oauth/start", strictRateLimitMiddleware, async (c) => {
61
+ const connectorId = c.req.param("id");
62
+ const connector = getConnectorDefinition(connectorId);
63
+ if (!connector) return c.json({
64
+ ok: false,
65
+ error: `Unknown connector: ${connectorId}`
66
+ }, 404);
67
+ try {
68
+ const oauth = await startConnectorOAuth(connector);
69
+ return c.json({
70
+ ok: true,
71
+ payload: { oauth }
72
+ });
73
+ } catch (error) {
74
+ return c.json({
75
+ ok: false,
76
+ error: errorMessage(error)
77
+ }, 400);
78
+ }
79
+ });
80
+ authenticated.post("/api/connectors/:id/oauth/complete", strictRateLimitMiddleware, async (c) => {
81
+ const connectorId = c.req.param("id");
82
+ const connector = getConnectorDefinition(connectorId);
83
+ if (!connector) return c.json({
84
+ ok: false,
85
+ error: `Unknown connector: ${connectorId}`
86
+ }, 404);
87
+ const body = await c.req.json().catch(() => ({}));
88
+ const deviceCode = body && typeof body === "object" && !Array.isArray(body) && typeof body.deviceCode === "string" ? body.deviceCode : "";
89
+ try {
90
+ const oauth = await completeConnectorOAuth(connector, { deviceCode });
91
+ return c.json({
92
+ ok: true,
93
+ payload: { oauth }
94
+ });
95
+ } catch (error) {
96
+ return c.json({
97
+ ok: false,
98
+ error: errorMessage(error)
99
+ }, 400);
100
+ }
101
+ });
102
+ authenticated.post("/api/connectors/:id/install", strictRateLimitMiddleware, async (c) => {
103
+ const connectorId = c.req.param("id");
104
+ const body = await c.req.json().catch(() => ({}));
105
+ const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
106
+ const config = service.currentConfig;
107
+ try {
108
+ const instance = await installConnector(config, connectorId, input);
109
+ const saved = await service.saveConfig(config);
110
+ if (!saved.saved) return c.json({
111
+ ok: false,
112
+ error: saved.error
113
+ }, 500);
114
+ return c.json({
115
+ ok: true,
116
+ payload: { instance }
117
+ });
118
+ } catch (error) {
119
+ return c.json({
120
+ ok: false,
121
+ error: errorMessage(error)
122
+ }, 400);
123
+ }
124
+ });
125
+ authenticated.post("/api/connectors/:id/test", async (c) => {
126
+ const instanceId = c.req.param("id");
127
+ const config = service.currentConfig;
128
+ const instance = getConnectorInstance(config, instanceId);
129
+ if (!instance) return c.json({
130
+ ok: false,
131
+ error: `Connector instance not found: ${instanceId}`
132
+ }, 404);
133
+ try {
134
+ const result = await testConnectorInstance(config, instance.materialized.serverId);
135
+ recordConnectorHealthUsage(config, instance.instanceId, result);
136
+ const saved = await service.saveConfig(config);
137
+ if (!saved.saved) return c.json({
138
+ ok: false,
139
+ error: saved.error
140
+ }, 500);
141
+ return c.json({
142
+ ok: true,
143
+ payload: result
144
+ });
145
+ } catch (error) {
146
+ return c.json({
147
+ ok: false,
148
+ error: errorMessage(error)
149
+ }, 500);
150
+ }
151
+ });
152
+ authenticated.delete("/api/connectors/:id", strictRateLimitMiddleware, async (c) => {
153
+ const instanceId = c.req.param("id");
154
+ const config = service.currentConfig;
155
+ try {
156
+ const instance = uninstallConnector(config, instanceId);
157
+ const saved = await service.saveConfig(config);
158
+ if (!saved.saved) return c.json({
159
+ ok: false,
160
+ error: saved.error
161
+ }, 500);
162
+ return c.json({
163
+ ok: true,
164
+ payload: { instance }
165
+ });
166
+ } catch (error) {
167
+ return c.json({
168
+ ok: false,
169
+ error: errorMessage(error)
170
+ }, 400);
171
+ }
172
+ });
173
+ }
174
+ //#endregion
175
+ export { registerConnectorRoutes };
176
+
177
+ //# sourceMappingURL=connectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectors.js","names":[],"sources":["../../../../../src/gateway/hono/routes/connectors.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { Config } from '../../../config/schema.js';\nimport { getConnectorDefinition, listConnectorCatalog, listConnectorProviders } from '../../../connectors/catalog.js';\nimport { testConnectorInstance } from '../../../connectors/health.js';\nimport { installConnector, uninstallConnector } from '../../../connectors/install.js';\nimport { getConnectorInstance, listConnectorInstances } from '../../../connectors/instances.js';\nimport { startConnectorOAuth, completeConnectorOAuth } from '../../../connectors/oauth.js';\nimport { recordConnectorHealthUsage } from '../../../connectors/usage.js';\nimport type { ConnectorInstallInput } from '../../../connectors/types.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function registerConnectorRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/connectors/catalog', (c) => {\n return c.json({\n ok: true,\n payload: {\n connectors: listConnectorCatalog(),\n providers: listConnectorProviders().map((provider) => ({\n id: provider.id,\n displayName: provider.displayName,\n })),\n },\n });\n });\n\n authenticated.get('/api/connectors/installed', (c) => {\n const config = service.currentConfig as Config;\n return c.json({ ok: true, payload: { instances: listConnectorInstances(config) } });\n });\n\n authenticated.get('/api/connectors/:id', (c) => {\n const connectorId = c.req.param('id');\n const connector = getConnectorDefinition(connectorId);\n if (!connector) {\n return c.json({ ok: false, error: `Unknown connector: ${connectorId}` }, 404);\n }\n const config = service.currentConfig as Config;\n const instances = listConnectorInstances(config).filter((instance) => instance.connectorId === connectorId);\n return c.json({ ok: true, payload: { connector, instances } });\n });\n\n authenticated.post('/api/connectors/approvals/respond', async (c) => {\n const body = await c.req.json().catch(() => ({}));\n return c.json({ ok: true, payload: { acknowledged: true, body } });\n });\n\n authenticated.post('/api/connectors/:id/oauth/start', strictRateLimitMiddleware, async (c) => {\n const connectorId = c.req.param('id');\n const connector = getConnectorDefinition(connectorId);\n if (!connector) {\n return c.json({ ok: false, error: `Unknown connector: ${connectorId}` }, 404);\n }\n try {\n const oauth = await startConnectorOAuth(connector);\n return c.json({ ok: true, payload: { oauth } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n\n authenticated.post('/api/connectors/:id/oauth/complete', strictRateLimitMiddleware, async (c) => {\n const connectorId = c.req.param('id');\n const connector = getConnectorDefinition(connectorId);\n if (!connector) {\n return c.json({ ok: false, error: `Unknown connector: ${connectorId}` }, 404);\n }\n const body = await c.req.json().catch(() => ({}));\n const deviceCode = body && typeof body === 'object' && !Array.isArray(body) && typeof body.deviceCode === 'string'\n ? body.deviceCode\n : '';\n try {\n const oauth = await completeConnectorOAuth(connector, { deviceCode });\n return c.json({ ok: true, payload: { oauth } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n\n authenticated.post('/api/connectors/:id/install', strictRateLimitMiddleware, async (c) => {\n const connectorId = c.req.param('id');\n const body = await c.req.json().catch(() => ({}));\n const input: ConnectorInstallInput = body && typeof body === 'object' && !Array.isArray(body) ? body : {};\n const config = service.currentConfig as Config;\n try {\n const instance = await installConnector(config, connectorId, input);\n const saved = await service.saveConfig(config);\n if (!saved.saved) {\n return c.json({ ok: false, error: saved.error }, 500);\n }\n return c.json({ ok: true, payload: { instance } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n\n authenticated.post('/api/connectors/:id/test', async (c) => {\n const instanceId = c.req.param('id');\n const config = service.currentConfig as Config;\n const instance = getConnectorInstance(config, instanceId);\n if (!instance) {\n return c.json({ ok: false, error: `Connector instance not found: ${instanceId}` }, 404);\n }\n try {\n const result = await testConnectorInstance(config, instance.materialized.serverId);\n recordConnectorHealthUsage(config, instance.instanceId, result);\n const saved = await service.saveConfig(config);\n if (!saved.saved) {\n return c.json({ ok: false, error: saved.error }, 500);\n }\n return c.json({ ok: true, payload: result });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 500);\n }\n });\n\n authenticated.delete('/api/connectors/:id', strictRateLimitMiddleware, async (c) => {\n const instanceId = c.req.param('id');\n const config = service.currentConfig as Config;\n try {\n const instance = uninstallConnector(config, instanceId);\n const saved = await service.saveConfig(config);\n if (!saved.saved) {\n return c.json({ ok: false, error: saved.error }, 500);\n }\n return c.json({ ok: true, payload: { instance } });\n } catch (error) {\n return c.json({ ok: false, error: errorMessage(error) }, 400);\n }\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ /**
4
+ * GET /api/home — Aggregated home screen data for the mobile app.
5
+ *
6
+ * Returns:
7
+ * - recentlyOpened: notes sorted by lastOpenedAt (continue rail)
8
+ * - inboxCount: number of notes with status === 'inbox'
9
+ * - pendingTasks: task notes where done === false
10
+ * - recentSessions: last 5 active AI sessions (threads)
11
+ */
12
+ export declare function registerHomeRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,50 @@
1
+ //#region src/gateway/hono/routes/home.ts
2
+ /**
3
+ * GET /api/home — Aggregated home screen data for the mobile app.
4
+ *
5
+ * Returns:
6
+ * - recentlyOpened: notes sorted by lastOpenedAt (continue rail)
7
+ * - inboxCount: number of notes with status === 'inbox'
8
+ * - pendingTasks: task notes where done === false
9
+ * - recentSessions: last 5 active AI sessions (threads)
10
+ */
11
+ function registerHomeRoutes(authenticated, deps) {
12
+ const { service } = deps;
13
+ authenticated.get("/api/home", async (c) => {
14
+ const notes = service.notesServiceInstance;
15
+ const sessions = service.sessions;
16
+ const [recentlyOpened, inbox, pendingTasks, recentSessions] = await Promise.all([
17
+ notes.listNotes({
18
+ sortBy: "lastOpenedAt",
19
+ sortOrder: "desc",
20
+ limit: 10
21
+ }),
22
+ notes.listNotes({
23
+ status: "inbox",
24
+ limit: 0
25
+ }),
26
+ notes.listNotes({
27
+ pendingTasksOnly: true,
28
+ sortBy: "createdAt",
29
+ sortOrder: "desc",
30
+ limit: 10
31
+ }),
32
+ sessions.listSessions({
33
+ sortBy: "updatedAt",
34
+ sortOrder: "desc",
35
+ limit: 5
36
+ })
37
+ ]);
38
+ return c.json({
39
+ recentlyOpened: recentlyOpened.items.filter((n) => n.lastOpenedAt),
40
+ inboxCount: inbox.total,
41
+ pendingTasks: pendingTasks.items,
42
+ pendingTaskCount: pendingTasks.total,
43
+ recentSessions: recentSessions.items
44
+ });
45
+ });
46
+ }
47
+ //#endregion
48
+ export { registerHomeRoutes };
49
+
50
+ //# sourceMappingURL=home.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home.js","names":[],"sources":["../../../../../src/gateway/hono/routes/home.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\n/**\n * GET /api/home — Aggregated home screen data for the mobile app.\n *\n * Returns:\n * - recentlyOpened: notes sorted by lastOpenedAt (continue rail)\n * - inboxCount: number of notes with status === 'inbox'\n * - pendingTasks: task notes where done === false\n * - recentSessions: last 5 active AI sessions (threads)\n */\nexport function registerHomeRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/home', async (c) => {\n const notes = service.notesServiceInstance;\n const sessions = service.sessions;\n\n const [recentlyOpened, inbox, pendingTasks, recentSessions] = await Promise.all([\n notes.listNotes({ sortBy: 'lastOpenedAt', sortOrder: 'desc', limit: 10 }),\n notes.listNotes({ status: 'inbox', limit: 0 }),\n notes.listNotes({ pendingTasksOnly: true, sortBy: 'createdAt', sortOrder: 'desc', limit: 10 }),\n sessions.listSessions({ sortBy: 'updatedAt', sortOrder: 'desc', limit: 5 }),\n ]);\n\n return c.json({\n recentlyOpened: recentlyOpened.items.filter((n) => n.lastOpenedAt),\n inboxCount: inbox.total,\n pendingTasks: pendingTasks.items,\n pendingTaskCount: pendingTasks.total,\n recentSessions: recentSessions.items,\n });\n });\n}\n"],"mappings":";;;;;;;;;;AAaA,SAAgB,mBAAmB,eAAqB,MAAoC;CAC1F,MAAM,EAAE,YAAY;AAEpB,eAAc,IAAI,aAAa,OAAO,MAAM;EAC1C,MAAM,QAAQ,QAAQ;EACtB,MAAM,WAAW,QAAQ;EAEzB,MAAM,CAAC,gBAAgB,OAAO,cAAc,kBAAkB,MAAM,QAAQ,IAAI;GAC9E,MAAM,UAAU;IAAE,QAAQ;IAAgB,WAAW;IAAQ,OAAO;IAAI,CAAC;GACzE,MAAM,UAAU;IAAE,QAAQ;IAAS,OAAO;IAAG,CAAC;GAC9C,MAAM,UAAU;IAAE,kBAAkB;IAAM,QAAQ;IAAa,WAAW;IAAQ,OAAO;IAAI,CAAC;GAC9F,SAAS,aAAa;IAAE,QAAQ;IAAa,WAAW;IAAQ,OAAO;IAAG,CAAC;GAC5E,CAAC;AAEF,SAAO,EAAE,KAAK;GACZ,gBAAgB,eAAe,MAAM,QAAQ,MAAM,EAAE,aAAa;GAClE,YAAY,MAAM;GAClB,cAAc,aAAa;GAC3B,kBAAkB,aAAa;GAC/B,gBAAgB,eAAe;GAChC,CAAC;GACF"}
@@ -134,6 +134,14 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
134
134
  return { register: registerNotesRoutes };
135
135
  }
136
136
  },
137
+ {
138
+ id: "home",
139
+ match: (path) => startsWithAny(path, ["/api/home"]),
140
+ load: async () => {
141
+ const { registerHomeRoutes } = await import("./home.js");
142
+ return { register: registerHomeRoutes };
143
+ }
144
+ },
137
145
  {
138
146
  id: "workflows",
139
147
  match: (path) => startsWithAny(path, ["/api/workflows"]),
@@ -207,11 +215,11 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
207
215
  }
208
216
  },
209
217
  {
210
- id: "mcp",
211
- match: (path) => startsWithAny(path, ["/api/mcp"]),
218
+ id: "connectors",
219
+ match: (path) => startsWithAny(path, ["/api/connectors"]),
212
220
  load: async () => {
213
- const { registerMcpRoutes } = await import("./mcp.js");
214
- return { register: registerMcpRoutes };
221
+ const { registerConnectorRoutes } = await import("./connectors.js");
222
+ return { register: registerConnectorRoutes };
215
223
  }
216
224
  }
217
225
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-bundles.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-bundles.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport type AuthenticatedLazyRouteBundle = {\n id: string;\n match: (path: string) => boolean;\n load: () => Promise<{ register: (authenticated: Hono, deps: AuthenticatedRouteDeps) => void }>;\n};\n\nexport type AppLazyRouteBundle = {\n id: string;\n prefixes: readonly string[];\n match: (path: string) => boolean;\n load: () => Promise<{\n registerOnApp: (app: Hono, service: GatewayService) => void;\n }>;\n};\n\nfunction startsWithAny(path: string, prefixes: readonly string[]): boolean {\n return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));\n}\n\nexport const AUTHENTICATED_LAZY_ROUTE_BUNDLES: readonly AuthenticatedLazyRouteBundle[] = [\n {\n id: 'workspace',\n match: (path) => startsWithAny(path, ['/api/workspace']),\n load: async () => {\n const { registerWorkspaceRoutes } = await import('./workspace.js');\n return { register: registerWorkspaceRoutes };\n },\n },\n {\n id: 'host-fs',\n match: (path) => startsWithAny(path, ['/api/host/fs']),\n load: async () => {\n const { registerHostFsRoutes } = await import('./host-fs.js');\n return { register: registerHostFsRoutes };\n },\n },\n {\n id: 'channels',\n match: (path) => startsWithAny(path, ['/api/channels']),\n load: async () => {\n const { registerChannelRoutes } = await import('./channels.js');\n return { register: registerChannelRoutes };\n },\n },\n {\n id: 'browser-install',\n match: (path) =>\n path === '/api/browser/playwright/install/stream' ||\n path === '/api/browser/cloakbrowser/install/stream',\n load: async () => {\n const { registerBrowserInstallRoutes } = await import('./browser-install.js');\n return { register: registerBrowserInstallRoutes };\n },\n },\n {\n id: 'browser',\n // `browser-install` above already matched the SSE install streams; this\n // catches the remaining /api/browser/* handlers (extension, cdp,\n // cloakbrowser doctor/launch/install, playwright doctor/install, cloud).\n match: (path) => startsWithAny(path, ['/api/browser']),\n load: async () => {\n const { registerBrowserRoutes } = await import('./browser.js');\n return { register: registerBrowserRoutes };\n },\n },\n {\n id: 'config',\n match: (path) =>\n startsWithAny(path, ['/api/config', '/api/heartbeat/trigger']),\n load: async () => {\n const { registerConfigRoutes } = await import('./config.js');\n return { register: registerConfigRoutes };\n },\n },\n {\n id: 'doctor',\n match: (path) => startsWithAny(path, ['/api/doctor']),\n load: async () => {\n const { registerDoctorRoutes } = await import('./doctor.js');\n return { register: registerDoctorRoutes };\n },\n },\n {\n id: 'dreaming',\n match: (path) => startsWithAny(path, ['/api/dreaming']),\n load: async () => {\n const { registerDreamingRoutes } = await import('./dreaming.js');\n return { register: registerDreamingRoutes };\n },\n },\n {\n id: 'agents',\n match: (path) => startsWithAny(path, ['/api/agents', '/api/voice/models']),\n load: async () => {\n const { registerAgentsRoutes } = await import('./agents.js');\n return { register: registerAgentsRoutes };\n },\n },\n {\n id: 'auth-registry-extensions',\n match: (path) =>\n startsWithAny(path, [\n '/api/auth',\n '/api/registry',\n '/api/extensions',\n '/api/context',\n '/api/marketplace',\n ]),\n load: async () => {\n const { registerAuthRegistryExtensionsRoutes } = await import('./auth-registry-extensions.js');\n return { register: registerAuthRegistryExtensionsRoutes };\n },\n },\n {\n id: 'models',\n match: (path) =>\n startsWithAny(path, ['/api/models', '/api/models-json', '/api/providers', '/api/image']),\n load: async () => {\n const { registerModelsRoutes } = await import('./models.js');\n return { register: registerModelsRoutes };\n },\n },\n {\n id: 'commands-skills',\n match: (path) => startsWithAny(path, ['/api/commands', '/api/skills']),\n load: async () => {\n const { registerCommandsSkillsRoutes } = await import('./commands-skills.js');\n return { register: registerCommandsSkillsRoutes };\n },\n },\n {\n id: 'cron',\n match: (path) => startsWithAny(path, ['/api/cron']),\n load: async () => {\n const { registerCronRoutes } = await import('./cron.js');\n return { register: registerCronRoutes };\n },\n },\n {\n id: 'goals',\n match: (path) => startsWithAny(path, ['/api/goals']),\n load: async () => {\n const { registerGoalsRoutes } = await import('./goals.js');\n return { register: registerGoalsRoutes };\n },\n },\n {\n id: 'notes',\n match: (path) => startsWithAny(path, ['/api/notes']),\n load: async () => {\n const { registerNotesRoutes } = await import('./notes.js');\n return { register: registerNotesRoutes };\n },\n },\n {\n id: 'workflows',\n match: (path) => startsWithAny(path, ['/api/workflows']),\n load: async () => {\n const { registerWorkflowRoutes } = await import('./workflows.js');\n return { register: registerWorkflowRoutes };\n },\n },\n {\n id: 'logs',\n match: (path) => startsWithAny(path, ['/api/logs']),\n load: async () => {\n const { registerLogsRoutes } = await import('./logs.js');\n return { register: registerLogsRoutes };\n },\n },\n {\n id: 'shares',\n match: (path) => startsWithAny(path, ['/api/shares']),\n load: async () => {\n const { registerShareRoutes } = await import('./shares.js');\n return { register: registerShareRoutes };\n },\n },\n {\n id: 'site-shares',\n match: (path) => startsWithAny(path, ['/api/site-shares']),\n load: async () => {\n const { registerSiteShareRoutes } = await import('./site-shares.js');\n return { register: registerSiteShareRoutes };\n },\n },\n {\n id: 'tunnel',\n match: (path) => startsWithAny(path, ['/api/tunnel']),\n load: async () => {\n const { registerTunnelRoutes } = await import('./tunnel.js');\n return { register: registerTunnelRoutes };\n },\n },\n {\n id: 'exposure',\n match: (path) => startsWithAny(path, ['/api/exposure']),\n load: async () => {\n const { registerExposureRoutes } = await import('./exposure.js');\n return { register: registerExposureRoutes };\n },\n },\n {\n id: 'extension-gateway',\n match: (path) => startsWithAny(path, ['/api/gateway']),\n load: async () => {\n const { registerExtensionGatewayRoutes } = await import('./extension-gateway.js');\n return { register: registerExtensionGatewayRoutes };\n },\n },\n {\n id: 'update',\n match: (path) => startsWithAny(path, ['/api/update']),\n load: async () => {\n const { registerUpdateRoutes } = await import('./update.js');\n return { register: registerUpdateRoutes };\n },\n },\n {\n id: 'voice',\n match: (path) => startsWithAny(path, ['/api/voice']) && path !== '/api/voice/models',\n load: async () => {\n const { registerVoiceRoutes } = await import('./voice.js');\n return { register: registerVoiceRoutes };\n },\n },\n {\n id: 'mcp',\n match: (path) => startsWithAny(path, ['/api/mcp']),\n load: async () => {\n const { registerMcpRoutes } = await import('./mcp.js');\n return { register: registerMcpRoutes };\n },\n },\n];\n\nexport const APP_LAZY_ROUTE_BUNDLES: readonly AppLazyRouteBundle[] = [\n {\n id: 'shares-public',\n prefixes: ['/s'],\n match: (path) => startsWithAny(path, ['/s']),\n load: async () => {\n const { registerSharePublicRoutes } = await import('./shares.js');\n return { registerOnApp: registerSharePublicRoutes };\n },\n },\n {\n id: 'tunnel-public',\n prefixes: [\n '/api/tunnel/pair/ping',\n '/api/tunnel/pair/validate-url',\n '/api/tunnel/exchange-token',\n ],\n match: (path) =>\n path === '/api/tunnel/exchange-token' ||\n path === '/api/tunnel/pair/ping' ||\n path === '/api/tunnel/pair/validate-url',\n load: async () => {\n const { registerTunnelPublicRoutes } = await import('./tunnel.js');\n return { registerOnApp: registerTunnelPublicRoutes };\n },\n },\n];\n\nexport function findAuthenticatedLazyRouteBundle(path: string): AuthenticatedLazyRouteBundle | undefined {\n return AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((bundle) => bundle.match(path));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"lazy-bundles.js","names":[],"sources":["../../../../../src/gateway/hono/routes/lazy-bundles.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport type AuthenticatedLazyRouteBundle = {\n id: string;\n match: (path: string) => boolean;\n load: () => Promise<{ register: (authenticated: Hono, deps: AuthenticatedRouteDeps) => void }>;\n};\n\nexport type AppLazyRouteBundle = {\n id: string;\n prefixes: readonly string[];\n match: (path: string) => boolean;\n load: () => Promise<{\n registerOnApp: (app: Hono, service: GatewayService) => void;\n }>;\n};\n\nfunction startsWithAny(path: string, prefixes: readonly string[]): boolean {\n return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));\n}\n\nexport const AUTHENTICATED_LAZY_ROUTE_BUNDLES: readonly AuthenticatedLazyRouteBundle[] = [\n {\n id: 'workspace',\n match: (path) => startsWithAny(path, ['/api/workspace']),\n load: async () => {\n const { registerWorkspaceRoutes } = await import('./workspace.js');\n return { register: registerWorkspaceRoutes };\n },\n },\n {\n id: 'host-fs',\n match: (path) => startsWithAny(path, ['/api/host/fs']),\n load: async () => {\n const { registerHostFsRoutes } = await import('./host-fs.js');\n return { register: registerHostFsRoutes };\n },\n },\n {\n id: 'channels',\n match: (path) => startsWithAny(path, ['/api/channels']),\n load: async () => {\n const { registerChannelRoutes } = await import('./channels.js');\n return { register: registerChannelRoutes };\n },\n },\n {\n id: 'browser-install',\n match: (path) =>\n path === '/api/browser/playwright/install/stream' ||\n path === '/api/browser/cloakbrowser/install/stream',\n load: async () => {\n const { registerBrowserInstallRoutes } = await import('./browser-install.js');\n return { register: registerBrowserInstallRoutes };\n },\n },\n {\n id: 'browser',\n // `browser-install` above already matched the SSE install streams; this\n // catches the remaining /api/browser/* handlers (extension, cdp,\n // cloakbrowser doctor/launch/install, playwright doctor/install, cloud).\n match: (path) => startsWithAny(path, ['/api/browser']),\n load: async () => {\n const { registerBrowserRoutes } = await import('./browser.js');\n return { register: registerBrowserRoutes };\n },\n },\n {\n id: 'config',\n match: (path) =>\n startsWithAny(path, ['/api/config', '/api/heartbeat/trigger']),\n load: async () => {\n const { registerConfigRoutes } = await import('./config.js');\n return { register: registerConfigRoutes };\n },\n },\n {\n id: 'doctor',\n match: (path) => startsWithAny(path, ['/api/doctor']),\n load: async () => {\n const { registerDoctorRoutes } = await import('./doctor.js');\n return { register: registerDoctorRoutes };\n },\n },\n {\n id: 'dreaming',\n match: (path) => startsWithAny(path, ['/api/dreaming']),\n load: async () => {\n const { registerDreamingRoutes } = await import('./dreaming.js');\n return { register: registerDreamingRoutes };\n },\n },\n {\n id: 'agents',\n match: (path) => startsWithAny(path, ['/api/agents', '/api/voice/models']),\n load: async () => {\n const { registerAgentsRoutes } = await import('./agents.js');\n return { register: registerAgentsRoutes };\n },\n },\n {\n id: 'auth-registry-extensions',\n match: (path) =>\n startsWithAny(path, [\n '/api/auth',\n '/api/registry',\n '/api/extensions',\n '/api/context',\n '/api/marketplace',\n ]),\n load: async () => {\n const { registerAuthRegistryExtensionsRoutes } = await import('./auth-registry-extensions.js');\n return { register: registerAuthRegistryExtensionsRoutes };\n },\n },\n {\n id: 'models',\n match: (path) =>\n startsWithAny(path, ['/api/models', '/api/models-json', '/api/providers', '/api/image']),\n load: async () => {\n const { registerModelsRoutes } = await import('./models.js');\n return { register: registerModelsRoutes };\n },\n },\n {\n id: 'commands-skills',\n match: (path) => startsWithAny(path, ['/api/commands', '/api/skills']),\n load: async () => {\n const { registerCommandsSkillsRoutes } = await import('./commands-skills.js');\n return { register: registerCommandsSkillsRoutes };\n },\n },\n {\n id: 'cron',\n match: (path) => startsWithAny(path, ['/api/cron']),\n load: async () => {\n const { registerCronRoutes } = await import('./cron.js');\n return { register: registerCronRoutes };\n },\n },\n {\n id: 'goals',\n match: (path) => startsWithAny(path, ['/api/goals']),\n load: async () => {\n const { registerGoalsRoutes } = await import('./goals.js');\n return { register: registerGoalsRoutes };\n },\n },\n {\n id: 'notes',\n match: (path) => startsWithAny(path, ['/api/notes']),\n load: async () => {\n const { registerNotesRoutes } = await import('./notes.js');\n return { register: registerNotesRoutes };\n },\n },\n {\n id: 'home',\n match: (path) => startsWithAny(path, ['/api/home']),\n load: async () => {\n const { registerHomeRoutes } = await import('./home.js');\n return { register: registerHomeRoutes };\n },\n },\n {\n id: 'workflows',\n match: (path) => startsWithAny(path, ['/api/workflows']),\n load: async () => {\n const { registerWorkflowRoutes } = await import('./workflows.js');\n return { register: registerWorkflowRoutes };\n },\n },\n {\n id: 'logs',\n match: (path) => startsWithAny(path, ['/api/logs']),\n load: async () => {\n const { registerLogsRoutes } = await import('./logs.js');\n return { register: registerLogsRoutes };\n },\n },\n {\n id: 'shares',\n match: (path) => startsWithAny(path, ['/api/shares']),\n load: async () => {\n const { registerShareRoutes } = await import('./shares.js');\n return { register: registerShareRoutes };\n },\n },\n {\n id: 'site-shares',\n match: (path) => startsWithAny(path, ['/api/site-shares']),\n load: async () => {\n const { registerSiteShareRoutes } = await import('./site-shares.js');\n return { register: registerSiteShareRoutes };\n },\n },\n {\n id: 'tunnel',\n match: (path) => startsWithAny(path, ['/api/tunnel']),\n load: async () => {\n const { registerTunnelRoutes } = await import('./tunnel.js');\n return { register: registerTunnelRoutes };\n },\n },\n {\n id: 'exposure',\n match: (path) => startsWithAny(path, ['/api/exposure']),\n load: async () => {\n const { registerExposureRoutes } = await import('./exposure.js');\n return { register: registerExposureRoutes };\n },\n },\n {\n id: 'extension-gateway',\n match: (path) => startsWithAny(path, ['/api/gateway']),\n load: async () => {\n const { registerExtensionGatewayRoutes } = await import('./extension-gateway.js');\n return { register: registerExtensionGatewayRoutes };\n },\n },\n {\n id: 'update',\n match: (path) => startsWithAny(path, ['/api/update']),\n load: async () => {\n const { registerUpdateRoutes } = await import('./update.js');\n return { register: registerUpdateRoutes };\n },\n },\n {\n id: 'voice',\n match: (path) => startsWithAny(path, ['/api/voice']) && path !== '/api/voice/models',\n load: async () => {\n const { registerVoiceRoutes } = await import('./voice.js');\n return { register: registerVoiceRoutes };\n },\n },\n {\n id: 'connectors',\n match: (path) => startsWithAny(path, ['/api/connectors']),\n load: async () => {\n const { registerConnectorRoutes } = await import('./connectors.js');\n return { register: registerConnectorRoutes };\n },\n },\n];\n\nexport const APP_LAZY_ROUTE_BUNDLES: readonly AppLazyRouteBundle[] = [\n {\n id: 'shares-public',\n prefixes: ['/s'],\n match: (path) => startsWithAny(path, ['/s']),\n load: async () => {\n const { registerSharePublicRoutes } = await import('./shares.js');\n return { registerOnApp: registerSharePublicRoutes };\n },\n },\n {\n id: 'tunnel-public',\n prefixes: [\n '/api/tunnel/pair/ping',\n '/api/tunnel/pair/validate-url',\n '/api/tunnel/exchange-token',\n ],\n match: (path) =>\n path === '/api/tunnel/exchange-token' ||\n path === '/api/tunnel/pair/ping' ||\n path === '/api/tunnel/pair/validate-url',\n load: async () => {\n const { registerTunnelPublicRoutes } = await import('./tunnel.js');\n return { registerOnApp: registerTunnelPublicRoutes };\n },\n },\n];\n\nexport function findAuthenticatedLazyRouteBundle(path: string): AuthenticatedLazyRouteBundle | undefined {\n return AUTHENTICATED_LAZY_ROUTE_BUNDLES.find((bundle) => bundle.match(path));\n}\n"],"mappings":"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"}
@@ -267,6 +267,37 @@ function registerNotesRoutes(authenticated, deps) {
267
267
  await s.pipe(readable);
268
268
  });
269
269
  });
270
+ authenticated.post("/api/notes/task", async (c) => {
271
+ const body = await c.req.json().catch(() => ({}));
272
+ const title = typeof body.title === "string" ? body.title.trim() : "";
273
+ if (!title) return c.json({ error: "Missing required field: title" }, 400);
274
+ const source = parseCaptureSource(body);
275
+ const note = await service.notesServiceInstance.createTask(title, source, {
276
+ dueAt: typeof body.dueAt === "number" ? body.dueAt : void 0,
277
+ priority: body.priority === "high" || body.priority === "medium" || body.priority === "low" ? body.priority : void 0,
278
+ sourceSessionKey: typeof body.sourceSessionKey === "string" ? body.sourceSessionKey : void 0,
279
+ sourceNoteId: typeof body.sourceNoteId === "string" ? body.sourceNoteId : void 0,
280
+ groupId: typeof body.groupId === "string" ? body.groupId : void 0
281
+ });
282
+ return c.json({ note }, 201);
283
+ });
284
+ authenticated.post("/api/notes/:id/toggle-done", async (c) => {
285
+ const note = await service.notesServiceInstance.toggleTaskDone(c.req.param("id"));
286
+ if (!note) return c.json({ error: "Not found or not a task" }, 404);
287
+ return c.json({ note });
288
+ });
289
+ authenticated.post("/api/notes/:id/open", async (c) => {
290
+ const note = await service.notesServiceInstance.recordOpen(c.req.param("id"));
291
+ if (!note) return c.json({ error: "Not found" }, 404);
292
+ return c.json({ note });
293
+ });
294
+ authenticated.post("/api/notes/:id/move", async (c) => {
295
+ const body = await c.req.json().catch(() => ({}));
296
+ const groupId = typeof body.groupId === "string" ? body.groupId : null;
297
+ const note = await service.notesServiceInstance.moveToGroup(c.req.param("id"), groupId);
298
+ if (!note) return c.json({ error: "Not found" }, 404);
299
+ return c.json({ note });
300
+ });
270
301
  }
271
302
  //#endregion
272
303
  export { registerNotesRoutes };