@soulcraft/sdk 1.6.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/client/create-client-sdk.d.ts +16 -2
  2. package/dist/client/create-client-sdk.d.ts.map +1 -1
  3. package/dist/client/create-client-sdk.js +2 -7
  4. package/dist/client/create-client-sdk.js.map +1 -1
  5. package/dist/client/index.d.ts +48 -37
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +61 -42
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/namespace-proxy.d.ts +108 -0
  10. package/dist/client/namespace-proxy.d.ts.map +1 -0
  11. package/dist/client/namespace-proxy.js +151 -0
  12. package/dist/client/namespace-proxy.js.map +1 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/modules/app-context/index.d.ts +214 -0
  17. package/dist/modules/app-context/index.d.ts.map +1 -0
  18. package/dist/modules/app-context/index.js +569 -0
  19. package/dist/modules/app-context/index.js.map +1 -0
  20. package/dist/modules/auth/products.d.ts +208 -0
  21. package/dist/modules/auth/products.d.ts.map +1 -0
  22. package/dist/modules/auth/products.js +165 -0
  23. package/dist/modules/auth/products.js.map +1 -0
  24. package/dist/namespaces.d.ts +2942 -0
  25. package/dist/namespaces.d.ts.map +1 -0
  26. package/dist/namespaces.js +37 -0
  27. package/dist/namespaces.js.map +1 -0
  28. package/dist/rpc.d.ts +156 -0
  29. package/dist/rpc.d.ts.map +1 -0
  30. package/dist/rpc.js +26 -0
  31. package/dist/rpc.js.map +1 -0
  32. package/dist/server/create-sdk.d.ts.map +1 -1
  33. package/dist/server/create-sdk.js +3 -13
  34. package/dist/server/create-sdk.js.map +1 -1
  35. package/dist/server/handlers/annotations.d.ts +52 -0
  36. package/dist/server/handlers/annotations.d.ts.map +1 -0
  37. package/dist/server/handlers/annotations.js +204 -0
  38. package/dist/server/handlers/annotations.js.map +1 -0
  39. package/dist/server/handlers/auth.d.ts +53 -0
  40. package/dist/server/handlers/auth.d.ts.map +1 -0
  41. package/dist/server/handlers/auth.js +66 -0
  42. package/dist/server/handlers/auth.js.map +1 -0
  43. package/dist/server/handlers/certification.d.ts +32 -0
  44. package/dist/server/handlers/certification.d.ts.map +1 -0
  45. package/dist/server/handlers/certification.js +253 -0
  46. package/dist/server/handlers/certification.js.map +1 -0
  47. package/dist/server/handlers/chat/conversations.d.ts +91 -0
  48. package/dist/server/handlers/chat/conversations.d.ts.map +1 -0
  49. package/dist/server/handlers/chat/conversations.js +314 -0
  50. package/dist/server/handlers/chat/conversations.js.map +1 -0
  51. package/dist/server/handlers/chat/delegator.d.ts +144 -0
  52. package/dist/server/handlers/chat/delegator.d.ts.map +1 -0
  53. package/dist/server/handlers/chat/delegator.js +431 -0
  54. package/dist/server/handlers/chat/delegator.js.map +1 -0
  55. package/dist/server/handlers/chat/engine.d.ts +81 -0
  56. package/dist/server/handlers/chat/engine.d.ts.map +1 -0
  57. package/dist/server/handlers/chat/engine.js +442 -0
  58. package/dist/server/handlers/chat/engine.js.map +1 -0
  59. package/dist/server/handlers/chat/executor.d.ts +65 -0
  60. package/dist/server/handlers/chat/executor.d.ts.map +1 -0
  61. package/dist/server/handlers/chat/executor.js +375 -0
  62. package/dist/server/handlers/chat/executor.js.map +1 -0
  63. package/dist/server/handlers/chat/index.d.ts +62 -0
  64. package/dist/server/handlers/chat/index.d.ts.map +1 -0
  65. package/dist/server/handlers/chat/index.js +182 -0
  66. package/dist/server/handlers/chat/index.js.map +1 -0
  67. package/dist/server/handlers/chat/memory.d.ts +91 -0
  68. package/dist/server/handlers/chat/memory.d.ts.map +1 -0
  69. package/dist/server/handlers/chat/memory.js +293 -0
  70. package/dist/server/handlers/chat/memory.js.map +1 -0
  71. package/dist/server/handlers/chat/models.d.ts +180 -0
  72. package/dist/server/handlers/chat/models.d.ts.map +1 -0
  73. package/dist/server/handlers/chat/models.js +304 -0
  74. package/dist/server/handlers/chat/models.js.map +1 -0
  75. package/dist/server/handlers/chat/planner.d.ts +116 -0
  76. package/dist/server/handlers/chat/planner.d.ts.map +1 -0
  77. package/dist/server/handlers/chat/planner.js +344 -0
  78. package/dist/server/handlers/chat/planner.js.map +1 -0
  79. package/dist/server/handlers/chat/types.d.ts +500 -0
  80. package/dist/server/handlers/chat/types.d.ts.map +1 -0
  81. package/dist/server/handlers/chat/types.js +11 -0
  82. package/dist/server/handlers/chat/types.js.map +1 -0
  83. package/dist/server/handlers/collections.d.ts +67 -0
  84. package/dist/server/handlers/collections.d.ts.map +1 -0
  85. package/dist/server/handlers/collections.js +484 -0
  86. package/dist/server/handlers/collections.js.map +1 -0
  87. package/dist/server/handlers/commerce.d.ts +106 -0
  88. package/dist/server/handlers/commerce.d.ts.map +1 -0
  89. package/dist/server/handlers/commerce.js +62 -0
  90. package/dist/server/handlers/commerce.js.map +1 -0
  91. package/dist/server/handlers/config.d.ts +112 -0
  92. package/dist/server/handlers/config.d.ts.map +1 -0
  93. package/dist/server/handlers/config.js +122 -0
  94. package/dist/server/handlers/config.js.map +1 -0
  95. package/dist/server/handlers/export.d.ts +72 -0
  96. package/dist/server/handlers/export.d.ts.map +1 -0
  97. package/dist/server/handlers/export.js +175 -0
  98. package/dist/server/handlers/export.js.map +1 -0
  99. package/dist/server/handlers/formats.d.ts +77 -0
  100. package/dist/server/handlers/formats.d.ts.map +1 -0
  101. package/dist/server/handlers/formats.js +65 -0
  102. package/dist/server/handlers/formats.js.map +1 -0
  103. package/dist/server/handlers/graph.d.ts +31 -0
  104. package/dist/server/handlers/graph.d.ts.map +1 -0
  105. package/dist/server/handlers/graph.js +490 -0
  106. package/dist/server/handlers/graph.js.map +1 -0
  107. package/dist/server/handlers/import.d.ts +96 -0
  108. package/dist/server/handlers/import.d.ts.map +1 -0
  109. package/dist/server/handlers/import.js +108 -0
  110. package/dist/server/handlers/import.js.map +1 -0
  111. package/dist/server/handlers/index.d.ts +68 -0
  112. package/dist/server/handlers/index.d.ts.map +1 -0
  113. package/dist/server/handlers/index.js +71 -0
  114. package/dist/server/handlers/index.js.map +1 -0
  115. package/dist/server/handlers/media.d.ts +76 -0
  116. package/dist/server/handlers/media.d.ts.map +1 -0
  117. package/dist/server/handlers/media.js +53 -0
  118. package/dist/server/handlers/media.js.map +1 -0
  119. package/dist/server/handlers/project.d.ts +45 -0
  120. package/dist/server/handlers/project.d.ts.map +1 -0
  121. package/dist/server/handlers/project.js +181 -0
  122. package/dist/server/handlers/project.js.map +1 -0
  123. package/dist/server/handlers/publish.d.ts +102 -0
  124. package/dist/server/handlers/publish.d.ts.map +1 -0
  125. package/dist/server/handlers/publish.js +130 -0
  126. package/dist/server/handlers/publish.js.map +1 -0
  127. package/dist/server/handlers/pulse.d.ts +39 -0
  128. package/dist/server/handlers/pulse.d.ts.map +1 -0
  129. package/dist/server/handlers/pulse.js +78 -0
  130. package/dist/server/handlers/pulse.js.map +1 -0
  131. package/dist/server/handlers/realtime.d.ts +55 -0
  132. package/dist/server/handlers/realtime.d.ts.map +1 -0
  133. package/dist/server/handlers/realtime.js +49 -0
  134. package/dist/server/handlers/realtime.js.map +1 -0
  135. package/dist/server/handlers/search.d.ts +21 -0
  136. package/dist/server/handlers/search.d.ts.map +1 -0
  137. package/dist/server/handlers/search.js +237 -0
  138. package/dist/server/handlers/search.js.map +1 -0
  139. package/dist/server/handlers/session.d.ts +47 -0
  140. package/dist/server/handlers/session.d.ts.map +1 -0
  141. package/dist/server/handlers/session.js +286 -0
  142. package/dist/server/handlers/session.js.map +1 -0
  143. package/dist/server/handlers/settings.d.ts +97 -0
  144. package/dist/server/handlers/settings.d.ts.map +1 -0
  145. package/dist/server/handlers/settings.js +131 -0
  146. package/dist/server/handlers/settings.js.map +1 -0
  147. package/dist/server/handlers/workspace.d.ts +78 -0
  148. package/dist/server/handlers/workspace.d.ts.map +1 -0
  149. package/dist/server/handlers/workspace.js +270 -0
  150. package/dist/server/handlers/workspace.js.map +1 -0
  151. package/dist/server/hono-router.d.ts +66 -0
  152. package/dist/server/hono-router.d.ts.map +1 -0
  153. package/dist/server/hono-router.js +203 -0
  154. package/dist/server/hono-router.js.map +1 -0
  155. package/dist/server/index.d.ts +29 -19
  156. package/dist/server/index.d.ts.map +1 -1
  157. package/dist/server/index.js +33 -19
  158. package/dist/server/index.js.map +1 -1
  159. package/dist/server/namespace-router.d.ts +204 -0
  160. package/dist/server/namespace-router.d.ts.map +1 -0
  161. package/dist/server/namespace-router.js +262 -0
  162. package/dist/server/namespace-router.js.map +1 -0
  163. package/dist/transports/http-namespace.d.ts +210 -0
  164. package/dist/transports/http-namespace.d.ts.map +1 -0
  165. package/dist/transports/http-namespace.js +514 -0
  166. package/dist/transports/http-namespace.js.map +1 -0
  167. package/dist/transports/workshop.d.ts +173 -0
  168. package/dist/transports/workshop.d.ts.map +1 -0
  169. package/dist/transports/workshop.js +307 -0
  170. package/dist/transports/workshop.js.map +1 -0
  171. package/dist/types.d.ts +65 -67
  172. package/dist/types.d.ts.map +1 -1
  173. package/dist/types.js +7 -3
  174. package/dist/types.js.map +1 -1
  175. package/docs/ADR-004-product-registry.md +108 -0
  176. package/package.json +1 -1
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module server/handlers/settings
3
+ * @description Settings namespace handler — BYOK API key management, AI usage
4
+ * stats, and workspace storage usage.
5
+ *
6
+ * Absorbs Workshop `routes/settings.ts`. The handler delegates to injected
7
+ * service interfaces for API key storage, billing, and storage tracking, so
8
+ * products can plug in their own implementations.
9
+ *
10
+ * Methods:
11
+ * - `saveApiKey` — Save a BYOK API key (encrypted at rest)
12
+ * - `getApiKey` — Get redacted API key info
13
+ * - `deleteApiKey` — Delete a saved API key
14
+ * - `getUsageStats` — Get AI usage statistics for the billing period
15
+ * - `getStorageUsage` — Get storage consumption breakdown
16
+ */
17
+ import type { NamespaceProvider } from '../namespace-router.js';
18
+ /**
19
+ * API key storage interface.
20
+ *
21
+ * Products implement this to manage BYOK API key persistence. Workshop uses
22
+ * encrypted filesystem storage; Venue might use a secrets manager.
23
+ */
24
+ export interface ApiKeyService {
25
+ /** Save an API key (encrypted at rest). */
26
+ saveKey(userId: string, provider: string, apiKey: string): Promise<{
27
+ success: boolean;
28
+ error?: string;
29
+ }>;
30
+ /**
31
+ * Get an API key for the given user and provider.
32
+ *
33
+ * @returns The key info, including whether it's a personal key or environment fallback.
34
+ */
35
+ getKey(userId: string, workspaceId: string, provider: string): Promise<{
36
+ success: boolean;
37
+ apiKey?: string;
38
+ source?: 'workspace' | 'global' | 'environment' | 'none';
39
+ }>;
40
+ /** Delete an API key. */
41
+ deleteKey(userId: string, provider: string): Promise<{
42
+ success: boolean;
43
+ error?: string;
44
+ }>;
45
+ /** Validate an API key format before saving. */
46
+ isValidKey(apiKey: string): boolean;
47
+ }
48
+ /**
49
+ * Billing service subset needed by the settings handler.
50
+ */
51
+ export interface SettingsBillingService {
52
+ /** Get AI usage status for the billing period. */
53
+ getUsageStatus(billingId: string, hasPersonalKey: boolean): Promise<Record<string, unknown>>;
54
+ /** Get the user's subscription for plan-based storage limits. */
55
+ getSubscription(billingId: string): Promise<{
56
+ plan?: string;
57
+ } | null>;
58
+ }
59
+ /**
60
+ * Storage tracking service for instant storage usage queries.
61
+ */
62
+ export interface StorageTracker {
63
+ /** Get cached storage usage in bytes. */
64
+ getUsage(storageId: string, workspaceId: string): Promise<number>;
65
+ /** Whether the tracker has initialized for this user+workspace. */
66
+ isInitialized(storageId: string, workspaceId: string): boolean;
67
+ /** Force a one-time initialization (first load). */
68
+ forceInit(storageId: string, workspaceId: string): Promise<number>;
69
+ }
70
+ /**
71
+ * Storage limit resolver — maps plan ID to maximum bytes allowed.
72
+ */
73
+ export interface StorageLimitResolver {
74
+ /** Get the storage limit in bytes for the given plan. */
75
+ getLimit(planId: string): Promise<number>;
76
+ }
77
+ /**
78
+ * Options for {@link createSettingsHandler}.
79
+ */
80
+ export interface SettingsHandlerOptions {
81
+ /** API key storage service. */
82
+ apiKeyService: ApiKeyService;
83
+ /** Billing service for usage and subscription queries. */
84
+ billing: SettingsBillingService;
85
+ /** Storage tracking service for instant usage queries. */
86
+ storageTracker: StorageTracker;
87
+ /** Storage limit resolver for plan-based limits. */
88
+ storageLimitResolver: StorageLimitResolver;
89
+ }
90
+ /**
91
+ * Creates the `settings` namespace handler.
92
+ *
93
+ * @param options - Settings handler dependencies.
94
+ * @returns A {@link NamespaceProvider} implementing {@link SettingsNamespace}.
95
+ */
96
+ export declare function createSettingsHandler(options: SettingsHandlerOptions): NamespaceProvider;
97
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,wBAAwB,CAAA;AAO/E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAExG;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QACrE,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAA;KACzD,CAAC,CAAA;IAEF,yBAAyB;IACzB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAE1F,gDAAgD;IAChD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,kDAAkD;IAClD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC5F,iEAAiE;IACjE,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACjE,mEAAmE;IACnE,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAA;IAC9D,oDAAoD;IACpD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACnE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC1C;AAMD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,aAAa,EAAE,aAAa,CAAA;IAC5B,0DAA0D;IAC1D,OAAO,EAAE,sBAAsB,CAAA;IAC/B,0DAA0D;IAC1D,cAAc,EAAE,cAAc,CAAA;IAC9B,oDAAoD;IACpD,oBAAoB,EAAE,oBAAoB,CAAA;CAC3C;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,iBAAiB,CA6IxF"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @module server/handlers/settings
3
+ * @description Settings namespace handler — BYOK API key management, AI usage
4
+ * stats, and workspace storage usage.
5
+ *
6
+ * Absorbs Workshop `routes/settings.ts`. The handler delegates to injected
7
+ * service interfaces for API key storage, billing, and storage tracking, so
8
+ * products can plug in their own implementations.
9
+ *
10
+ * Methods:
11
+ * - `saveApiKey` — Save a BYOK API key (encrypted at rest)
12
+ * - `getApiKey` — Get redacted API key info
13
+ * - `deleteApiKey` — Delete a saved API key
14
+ * - `getUsageStats` — Get AI usage statistics for the billing period
15
+ * - `getStorageUsage` — Get storage consumption breakdown
16
+ */
17
+ // ─────────────────────────────────────────────────────────────────────────────
18
+ // Handler factory
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ /**
21
+ * Creates the `settings` namespace handler.
22
+ *
23
+ * @param options - Settings handler dependencies.
24
+ * @returns A {@link NamespaceProvider} implementing {@link SettingsNamespace}.
25
+ */
26
+ export function createSettingsHandler(options) {
27
+ const { apiKeyService, billing, storageTracker, storageLimitResolver } = options;
28
+ return {
29
+ /**
30
+ * Save a BYOK API key, encrypted at rest.
31
+ *
32
+ * @param keyOptions - Provider name and raw key string.
33
+ * @param ctx - Handler context with authenticated user.
34
+ */
35
+ async saveApiKey(keyOptions, ctx) {
36
+ const { provider, key } = keyOptions;
37
+ if (!apiKeyService.isValidKey(key)) {
38
+ throw new Error('Invalid API key format');
39
+ }
40
+ const result = await apiKeyService.saveKey(ctx.user.emailHash, provider, key);
41
+ if (!result.success) {
42
+ throw new Error(result.error || 'Failed to save API key');
43
+ }
44
+ },
45
+ /**
46
+ * Get redacted API key information.
47
+ *
48
+ * @param provider - AI provider name (e.g. `'anthropic'`).
49
+ * @param ctx - Handler context with authenticated user.
50
+ * @returns Redacted key info or `null` if no key is saved.
51
+ */
52
+ async getApiKey(provider, ctx) {
53
+ const result = await apiKeyService.getKey(ctx.user.emailHash, ctx.workspaceId, provider);
54
+ // Only consider personal keys (workspace or global), not environment fallbacks
55
+ const isPersonalKey = result.source === 'workspace' || result.source === 'global';
56
+ if (!result.success || !result.apiKey || !isPersonalKey) {
57
+ return null;
58
+ }
59
+ return {
60
+ provider,
61
+ lastFour: result.apiKey.slice(-4),
62
+ createdAt: new Date().toISOString(), // Key service doesn't track creation date
63
+ };
64
+ },
65
+ /**
66
+ * Delete a saved API key.
67
+ *
68
+ * @param provider - AI provider whose key to delete.
69
+ * @param ctx - Handler context with authenticated user.
70
+ */
71
+ async deleteApiKey(provider, ctx) {
72
+ const result = await apiKeyService.deleteKey(ctx.user.emailHash, provider);
73
+ if (!result.success) {
74
+ throw new Error(result.error || 'Failed to delete API key');
75
+ }
76
+ },
77
+ /**
78
+ * Get AI usage statistics for the current billing period.
79
+ *
80
+ * @param ctx - Handler context with authenticated user.
81
+ * @returns Message count, token totals, and period identifier.
82
+ */
83
+ async getUsageStats(ctx) {
84
+ const billingId = ctx.user.email;
85
+ // Check if user has a personal key
86
+ const keyResult = await apiKeyService.getKey(ctx.user.emailHash, ctx.workspaceId, 'anthropic');
87
+ const hasPersonalKey = keyResult.success && keyResult.source === 'global';
88
+ const usageStatus = await billing.getUsageStatus(billingId, hasPersonalKey);
89
+ return {
90
+ messages: usageStatus.messages ?? 0,
91
+ tokens: {
92
+ input: usageStatus.tokensIn ?? usageStatus.inputTokens ?? 0,
93
+ output: usageStatus.tokensOut ?? usageStatus.outputTokens ?? 0,
94
+ },
95
+ period: usageStatus.period ?? new Date().toISOString().slice(0, 7),
96
+ };
97
+ },
98
+ /**
99
+ * Get storage consumption breakdown for the current workspace.
100
+ *
101
+ * Uses incremental storage tracking for instant response. On first access,
102
+ * forces a one-time initialization to ensure accurate data.
103
+ *
104
+ * @param ctx - Handler context with authenticated user and workspace.
105
+ * @returns Storage usage across entities, files, and indices.
106
+ */
107
+ async getStorageUsage(ctx) {
108
+ const storageId = ctx.user.emailHash;
109
+ const billingId = ctx.user.email;
110
+ // Get plan-based storage limit
111
+ const subscription = await billing.getSubscription(billingId);
112
+ const planId = subscription?.plan || 'free';
113
+ const limitBytes = await storageLimitResolver.getLimit(planId);
114
+ // Get current usage (instant from incremental tracker)
115
+ let usedBytes = await storageTracker.getUsage(storageId, ctx.workspaceId);
116
+ // Force init on first access for accuracy
117
+ if (!storageTracker.isInitialized(storageId, ctx.workspaceId)) {
118
+ usedBytes = await storageTracker.forceInit(storageId, ctx.workspaceId);
119
+ }
120
+ // The SDK contract returns a breakdown; we estimate the split from total.
121
+ // Products can override with more granular tracking if needed.
122
+ return {
123
+ totalBytes: usedBytes,
124
+ entityBytes: Math.round(usedBytes * 0.3), // Approximate: ~30% entities
125
+ fileBytes: Math.round(usedBytes * 0.6), // Approximate: ~60% files
126
+ indexBytes: Math.round(usedBytes * 0.1), // Approximate: ~10% indices
127
+ };
128
+ },
129
+ };
130
+ }
131
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/server/handlers/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @module server/handlers/workspace
3
+ * @description Workspace namespace handler — workspace CRUD, backup/restore,
4
+ * Venue connection, health checks, and workspace settings.
5
+ *
6
+ * Absorbs Workshop `routes/workspace.ts` (backup/restore, SSE events, whoami)
7
+ * and `routes/workspaces.ts` (CRUD, validation, connect-venue, available-venues).
8
+ *
9
+ * The handler delegates to an injected `WorkspaceManager` interface for workspace
10
+ * registry operations, so products can plug in their own storage backends.
11
+ *
12
+ * Methods:
13
+ * - `list` — List all workspaces for the current user
14
+ * - `get` — Get a specific workspace by ID
15
+ * - `create` — Create a new workspace (optionally from a kit)
16
+ * - `update` — Update workspace metadata
17
+ * - `delete` — Delete a workspace permanently
18
+ * - `getStatus` — Get workspace health and initialization status
19
+ * - `backup` — Create a downloadable backup archive
20
+ * - `restore` — Restore from a backup archive
21
+ * - `connectVenue` — Connect workspace to a Venue site
22
+ * - `getSettings` — Get workspace-level settings
23
+ * - `updateSettings` — Update workspace settings (merge)
24
+ * - `healthCheck` — Brainy round-trip health check
25
+ */
26
+ import type { NamespaceProvider } from '../namespace-router.js';
27
+ import type { WorkspaceInfo } from '../../namespaces.js';
28
+ /**
29
+ * Workspace registry manager — provides workspace CRUD without Hono coupling.
30
+ *
31
+ * Products implement this interface to connect to their workspace storage.
32
+ * Workshop uses a JSON file registry on the filesystem; Venue might use a
33
+ * database-backed registry.
34
+ */
35
+ export interface WorkspaceManager {
36
+ /** List all workspaces for the given user. */
37
+ listWorkspaces(userId: string): Promise<WorkspaceInfo[]>;
38
+ /** Get a workspace by ID. Returns `null` if not found. */
39
+ getWorkspace(userId: string, workspaceId: string): Promise<WorkspaceInfo | null>;
40
+ /** Create a new workspace. */
41
+ createWorkspace(userId: string, options: {
42
+ name: string;
43
+ kitId?: string;
44
+ description?: string;
45
+ color?: string;
46
+ icon?: string;
47
+ }): Promise<WorkspaceInfo>;
48
+ /** Update workspace metadata. */
49
+ updateWorkspace(userId: string, workspaceId: string, updates: {
50
+ name?: string;
51
+ }): Promise<WorkspaceInfo>;
52
+ /** Delete a workspace. */
53
+ deleteWorkspace(userId: string, workspaceId: string): Promise<void>;
54
+ /**
55
+ * Connect workspace to a Venue site.
56
+ *
57
+ * @param userId - User's email hash.
58
+ * @param venueUrl - Venue base URL.
59
+ * @param locationId - Venue location ID.
60
+ * @returns Connection metadata for the remote workspace.
61
+ */
62
+ connectVenue?(userId: string, venueUrl: string, locationId: string): Promise<WorkspaceInfo>;
63
+ }
64
+ /**
65
+ * Options for {@link createWorkspaceHandler}.
66
+ */
67
+ export interface WorkspaceHandlerOptions {
68
+ /** Workspace registry manager. */
69
+ workspaceManager: WorkspaceManager;
70
+ }
71
+ /**
72
+ * Creates the `workspace` namespace handler.
73
+ *
74
+ * @param options - Workspace handler dependencies.
75
+ * @returns A {@link NamespaceProvider} implementing {@link WorkspaceNamespace}.
76
+ */
77
+ export declare function createWorkspaceHandler(options: WorkspaceHandlerOptions): NamespaceProvider;
78
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,wBAAwB,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAA;AAMzE;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IAExD,0DAA0D;IAC1D,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;IAEhF,8BAA8B;IAC9B,eAAe,CACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7F,OAAO,CAAC,aAAa,CAAC,CAAA;IAEzB,iCAAiC;IACjC,eAAe,CACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,aAAa,CAAC,CAAA;IAEzB,0BAA0B;IAC1B,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnE;;;;;;;OAOG;IACH,YAAY,CAAC,CACX,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAMD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,iBAAiB,CAkR1F"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * @module server/handlers/workspace
3
+ * @description Workspace namespace handler — workspace CRUD, backup/restore,
4
+ * Venue connection, health checks, and workspace settings.
5
+ *
6
+ * Absorbs Workshop `routes/workspace.ts` (backup/restore, SSE events, whoami)
7
+ * and `routes/workspaces.ts` (CRUD, validation, connect-venue, available-venues).
8
+ *
9
+ * The handler delegates to an injected `WorkspaceManager` interface for workspace
10
+ * registry operations, so products can plug in their own storage backends.
11
+ *
12
+ * Methods:
13
+ * - `list` — List all workspaces for the current user
14
+ * - `get` — Get a specific workspace by ID
15
+ * - `create` — Create a new workspace (optionally from a kit)
16
+ * - `update` — Update workspace metadata
17
+ * - `delete` — Delete a workspace permanently
18
+ * - `getStatus` — Get workspace health and initialization status
19
+ * - `backup` — Create a downloadable backup archive
20
+ * - `restore` — Restore from a backup archive
21
+ * - `connectVenue` — Connect workspace to a Venue site
22
+ * - `getSettings` — Get workspace-level settings
23
+ * - `updateSettings` — Update workspace settings (merge)
24
+ * - `healthCheck` — Brainy round-trip health check
25
+ */
26
+ // ─────────────────────────────────────────────────────────────────────────────
27
+ // Handler factory
28
+ // ─────────────────────────────────────────────────────────────────────────────
29
+ /**
30
+ * Creates the `workspace` namespace handler.
31
+ *
32
+ * @param options - Workspace handler dependencies.
33
+ * @returns A {@link NamespaceProvider} implementing {@link WorkspaceNamespace}.
34
+ */
35
+ export function createWorkspaceHandler(options) {
36
+ const { workspaceManager } = options;
37
+ return {
38
+ /**
39
+ * List all workspaces for the current user.
40
+ *
41
+ * @param ctx - Handler context with authenticated user.
42
+ * @returns Array of workspace metadata.
43
+ */
44
+ async list(ctx) {
45
+ return workspaceManager.listWorkspaces(ctx.user.emailHash);
46
+ },
47
+ /**
48
+ * Get a specific workspace by ID.
49
+ *
50
+ * @param workspaceId - The workspace's unique identifier.
51
+ * @param ctx - Handler context with authenticated user.
52
+ * @returns Workspace metadata or `null` if not found.
53
+ */
54
+ async get(workspaceId, ctx) {
55
+ return workspaceManager.getWorkspace(ctx.user.emailHash, workspaceId);
56
+ },
57
+ /**
58
+ * Create a new workspace, optionally from a kit template.
59
+ *
60
+ * @param createOptions - Workspace creation options.
61
+ * @param ctx - Handler context with authenticated user.
62
+ * @returns The newly created workspace metadata.
63
+ */
64
+ async create(createOptions, ctx) {
65
+ return workspaceManager.createWorkspace(ctx.user.emailHash, createOptions);
66
+ },
67
+ /**
68
+ * Update workspace metadata.
69
+ *
70
+ * @param workspaceId - Workspace to update.
71
+ * @param updates - Fields to update.
72
+ * @param ctx - Handler context with authenticated user.
73
+ * @returns The updated workspace metadata.
74
+ */
75
+ async update(workspaceId, updates, ctx) {
76
+ return workspaceManager.updateWorkspace(ctx.user.emailHash, workspaceId, updates);
77
+ },
78
+ /**
79
+ * Delete a workspace and all its data permanently.
80
+ *
81
+ * @param workspaceId - Workspace to delete.
82
+ * @param ctx - Handler context with authenticated user.
83
+ */
84
+ async delete(workspaceId, ctx) {
85
+ await workspaceManager.deleteWorkspace(ctx.user.emailHash, workspaceId);
86
+ },
87
+ /**
88
+ * Get the workspace's health and initialization status.
89
+ *
90
+ * Pings the Brainy instance with `indexStats()` to verify it's responsive.
91
+ *
92
+ * @param ctx - Handler context with Brainy instance.
93
+ * @returns Status and entity count.
94
+ */
95
+ async getStatus(ctx) {
96
+ try {
97
+ const stats = await ctx.brain.indexStats();
98
+ return {
99
+ status: 'ready',
100
+ workspaceId: ctx.workspaceId,
101
+ entityCount: stats.entities ?? 0,
102
+ };
103
+ }
104
+ catch (err) {
105
+ return {
106
+ status: 'error',
107
+ workspaceId: ctx.workspaceId,
108
+ error: err.message,
109
+ };
110
+ }
111
+ },
112
+ /**
113
+ * Create a downloadable backup of the entire workspace.
114
+ *
115
+ * Exports all VFS files and entities into a zip archive. The archive is
116
+ * returned as raw binary data (Uint8Array) that the transport layer
117
+ * converts to a download response.
118
+ *
119
+ * @param ctx - Handler context with Brainy instance.
120
+ * @returns Backup archive metadata with download URL placeholder.
121
+ */
122
+ async backup(ctx) {
123
+ const { brain } = ctx;
124
+ // Collect all VFS files
125
+ const vfsFiles = [];
126
+ try {
127
+ const allFiles = await brain.vfs.readdir('/', { recursive: true });
128
+ for (const file of allFiles) {
129
+ try {
130
+ const content = await brain.vfs.readFile(file.path);
131
+ if (content !== null && content !== undefined) {
132
+ vfsFiles.push({
133
+ path: file.path,
134
+ content: typeof content === 'string' ? content : JSON.stringify(content),
135
+ });
136
+ }
137
+ }
138
+ catch {
139
+ // Skip unreadable files
140
+ }
141
+ }
142
+ }
143
+ catch {
144
+ // Empty VFS
145
+ }
146
+ // Export all entities
147
+ let entities = [];
148
+ try {
149
+ entities = await brain.find({ limit: 50000, excludeVFS: true });
150
+ }
151
+ catch {
152
+ // No entities
153
+ }
154
+ // Build manifest
155
+ const manifest = {
156
+ version: 1,
157
+ format: 'workshop-backup',
158
+ createdAt: new Date().toISOString(),
159
+ workspaceId: ctx.workspaceId,
160
+ fileCount: vfsFiles.length,
161
+ entityCount: entities.length,
162
+ };
163
+ // Estimate size (actual zip would be smaller)
164
+ const estimatedSize = vfsFiles.reduce((sum, f) => sum + f.content.length, 0)
165
+ + JSON.stringify(entities).length
166
+ + JSON.stringify(manifest).length;
167
+ // The actual zip creation happens at the transport/route level since it
168
+ // requires streaming binary data. The handler provides the data; the
169
+ // Hono route adapter assembles the archive.
170
+ // For now, return a placeholder that the Hono adapter interprets.
171
+ return {
172
+ downloadUrl: `__backup__:${ctx.workspaceId}`,
173
+ size: estimatedSize,
174
+ };
175
+ },
176
+ /**
177
+ * Restore a workspace from a backup archive.
178
+ *
179
+ * Processes the backup zip, restoring VFS files and entities into the
180
+ * current Brainy instance.
181
+ *
182
+ * @param backupData - The backup archive as raw binary data.
183
+ * @param ctx - Handler context with Brainy instance.
184
+ * @returns Counts of restored items.
185
+ */
186
+ async restore(backupData, ctx) {
187
+ const { brain } = ctx;
188
+ // Restore requires zip processing — delegated to the transport/route layer
189
+ // for binary handling. The core logic is:
190
+ // 1. Parse manifest.json from zip
191
+ // 2. Restore vfs/ entries via brain.vfs.writeFile()
192
+ // 3. Restore data/entities.json via brain.add()
193
+ // This will be fully wired when the Hono adapter handles multipart uploads.
194
+ throw new Error('workspace.restore requires binary transport — use the Hono route adapter');
195
+ },
196
+ /**
197
+ * Connect the workspace to a Venue site.
198
+ *
199
+ * @param venueOptions - Venue handle and slug.
200
+ * @param ctx - Handler context with authenticated user.
201
+ */
202
+ async connectVenue(venueOptions, ctx) {
203
+ if (!workspaceManager.connectVenue) {
204
+ throw new Error('Venue connection is not configured for this product');
205
+ }
206
+ // Derive Venue URL from handle (products configure this)
207
+ const venueUrl = `https://${venueOptions.venueHandle}.soulcraft.com`;
208
+ await workspaceManager.connectVenue(ctx.user.emailHash, venueUrl, venueOptions.venueSlug);
209
+ },
210
+ /**
211
+ * Get workspace-level settings.
212
+ *
213
+ * Reads the `workshop.settings` extended attribute from the workspace root.
214
+ *
215
+ * @param ctx - Handler context with Brainy instance.
216
+ * @returns Key-value settings object.
217
+ */
218
+ async getSettings(ctx) {
219
+ try {
220
+ return (await ctx.brain.vfs.getxattr('/', 'workshop.settings')) || {};
221
+ }
222
+ catch {
223
+ return {};
224
+ }
225
+ },
226
+ /**
227
+ * Update workspace settings (merge).
228
+ *
229
+ * Merges the provided settings into the existing `workshop.settings` xattr.
230
+ *
231
+ * @param settings - Key-value pairs to merge.
232
+ * @param ctx - Handler context with Brainy instance.
233
+ */
234
+ async updateSettings(settings, ctx) {
235
+ let existing = {};
236
+ try {
237
+ existing = (await ctx.brain.vfs.getxattr('/', 'workshop.settings')) || {};
238
+ }
239
+ catch {
240
+ // No existing settings
241
+ }
242
+ await ctx.brain.vfs.setxattr('/', 'workshop.settings', { ...existing, ...settings });
243
+ },
244
+ /**
245
+ * Run a health check on the Brainy instance.
246
+ *
247
+ * Measures round-trip latency of an `indexStats()` call.
248
+ *
249
+ * @param ctx - Handler context with Brainy instance.
250
+ * @returns Health status and latency in milliseconds.
251
+ */
252
+ async healthCheck(ctx) {
253
+ const start = performance.now();
254
+ try {
255
+ await ctx.brain.indexStats();
256
+ return {
257
+ status: 'ok',
258
+ latencyMs: Math.round(performance.now() - start),
259
+ };
260
+ }
261
+ catch {
262
+ return {
263
+ status: 'error',
264
+ latencyMs: Math.round(performance.now() - start),
265
+ };
266
+ }
267
+ },
268
+ };
269
+ }
270
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/server/handlers/workspace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @module server/hono-router
3
+ * @description Hono integration factory for the Soulcraft SDK namespace router.
4
+ *
5
+ * Creates a Hono app with three routes:
6
+ *
7
+ * - `POST /api/rpc` — Unified namespace RPC endpoint. Accepts the
8
+ * {@link SoulcraftRPC} envelope and dispatches via the namespace router.
9
+ * Streaming responses are delivered as SSE (`text/event-stream`).
10
+ *
11
+ * - `POST /api/brainy/rpc` — Legacy backward-compatible endpoint. Injects
12
+ * `ns: 'brainy'` and forwards to the same namespace router.
13
+ *
14
+ * - `GET /api/events` — SSE subscription for real-time change events (TBD,
15
+ * route registered but handler deferred to Phase 1b).
16
+ *
17
+ * Products mount this router in their Hono app with `app.route('', sdkRouter)`.
18
+ *
19
+ * @example Workshop server-hono.ts
20
+ * ```typescript
21
+ * import { createSoulcraftRouter } from '@soulcraft/sdk/server'
22
+ *
23
+ * const sdkRouter = createSoulcraftRouter({
24
+ * resolveBrain: async (ctx) => getUserBrainy(ctx.user!.emailHash, ctx.workspaceId),
25
+ * authenticate: async (ctx) => verifySession(ctx.request),
26
+ * providers: {
27
+ * chat: chatHandler,
28
+ * graph: graphHandler,
29
+ * search: searchHandler,
30
+ * },
31
+ * })
32
+ *
33
+ * app.route('', sdkRouter)
34
+ * ```
35
+ */
36
+ import { Hono } from 'hono';
37
+ import type { NamespaceRouterConfig } from './namespace-router.js';
38
+ /**
39
+ * Configuration for {@link createSoulcraftRouter}.
40
+ *
41
+ * Same as {@link NamespaceRouterConfig} — passed through to the namespace router.
42
+ */
43
+ export type SoulcraftRouterConfig = NamespaceRouterConfig;
44
+ /**
45
+ * Creates a Hono app with the unified Soulcraft RPC routes.
46
+ *
47
+ * The returned Hono app should be mounted at the root of your product server
48
+ * (not under a prefix) since it defines its own `/api/rpc` and `/api/brainy/rpc`
49
+ * paths.
50
+ *
51
+ * @param config - Namespace router configuration.
52
+ * @returns A Hono app ready to be mounted with `app.route('', sdkRouter)`.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const sdkRouter = createSoulcraftRouter({
57
+ * resolveBrain: async (ctx) => pool.forUser(ctx.user!.emailHash, ctx.workspaceId),
58
+ * authenticate: async (ctx) => verifySession(ctx.request),
59
+ * providers: { chat: chatHandler },
60
+ * })
61
+ *
62
+ * app.route('', sdkRouter)
63
+ * ```
64
+ */
65
+ export declare function createSoulcraftRouter(config: SoulcraftRouterConfig): Hono;
66
+ //# sourceMappingURL=hono-router.d.ts.map