@divizend/scratch-core 1.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 (61) hide show
  1. package/basic/demo.ts +11 -0
  2. package/basic/index.ts +490 -0
  3. package/core/Auth.ts +63 -0
  4. package/core/Currency.ts +16 -0
  5. package/core/Env.ts +186 -0
  6. package/core/Fragment.ts +43 -0
  7. package/core/FragmentServingMode.ts +37 -0
  8. package/core/JsonSchemaValidator.ts +173 -0
  9. package/core/ProjectRoot.ts +76 -0
  10. package/core/Scratch.ts +44 -0
  11. package/core/URI.ts +203 -0
  12. package/core/Universe.ts +406 -0
  13. package/core/index.ts +27 -0
  14. package/gsuite/core/GSuite.ts +237 -0
  15. package/gsuite/core/GSuiteAdmin.ts +81 -0
  16. package/gsuite/core/GSuiteOrgConfig.ts +47 -0
  17. package/gsuite/core/GSuiteUser.ts +115 -0
  18. package/gsuite/core/index.ts +21 -0
  19. package/gsuite/documents/Document.ts +173 -0
  20. package/gsuite/documents/Documents.ts +52 -0
  21. package/gsuite/documents/index.ts +19 -0
  22. package/gsuite/drive/Drive.ts +118 -0
  23. package/gsuite/drive/DriveFile.ts +147 -0
  24. package/gsuite/drive/index.ts +19 -0
  25. package/gsuite/gmail/Gmail.ts +430 -0
  26. package/gsuite/gmail/GmailLabel.ts +55 -0
  27. package/gsuite/gmail/GmailMessage.ts +428 -0
  28. package/gsuite/gmail/GmailMessagePart.ts +298 -0
  29. package/gsuite/gmail/GmailThread.ts +97 -0
  30. package/gsuite/gmail/index.ts +5 -0
  31. package/gsuite/gmail/utils.ts +184 -0
  32. package/gsuite/index.ts +28 -0
  33. package/gsuite/spreadsheets/CellValue.ts +71 -0
  34. package/gsuite/spreadsheets/Sheet.ts +128 -0
  35. package/gsuite/spreadsheets/SheetValues.ts +12 -0
  36. package/gsuite/spreadsheets/Spreadsheet.ts +76 -0
  37. package/gsuite/spreadsheets/Spreadsheets.ts +52 -0
  38. package/gsuite/spreadsheets/index.ts +25 -0
  39. package/gsuite/spreadsheets/utils.ts +52 -0
  40. package/gsuite/utils.ts +104 -0
  41. package/http-server/HttpServer.ts +110 -0
  42. package/http-server/NativeHttpServer.ts +1084 -0
  43. package/http-server/index.ts +3 -0
  44. package/http-server/middlewares/01-cors.ts +33 -0
  45. package/http-server/middlewares/02-static.ts +67 -0
  46. package/http-server/middlewares/03-request-logger.ts +159 -0
  47. package/http-server/middlewares/04-body-parser.ts +54 -0
  48. package/http-server/middlewares/05-no-cache.ts +23 -0
  49. package/http-server/middlewares/06-response-handler.ts +39 -0
  50. package/http-server/middlewares/handler-wrapper.ts +250 -0
  51. package/http-server/middlewares/index.ts +37 -0
  52. package/http-server/middlewares/types.ts +27 -0
  53. package/index.ts +24 -0
  54. package/package.json +37 -0
  55. package/queue/EmailQueue.ts +228 -0
  56. package/queue/RateLimiter.ts +54 -0
  57. package/queue/index.ts +2 -0
  58. package/resend/Resend.ts +190 -0
  59. package/resend/index.ts +11 -0
  60. package/s2/S2.ts +335 -0
  61. package/s2/index.ts +11 -0
package/core/URI.ts ADDED
@@ -0,0 +1,203 @@
1
+ /**
2
+ * URI System - Unified Resource Identification
3
+ *
4
+ * The URI system provides a standardized way to identify and reference
5
+ * resources within the AI Executive system. It supports multiple protocols
6
+ * and resource types, with Gmail integration as the primary use case.
7
+ *
8
+ * URI Format: protocol://domain/resource-type/id[/sub-resource]
9
+ * Examples:
10
+ * - gmail://user@domain.com/message/messageId
11
+ * - gmail://user@domain.com/message/messageId/part/partId
12
+ *
13
+ * @module URI
14
+ * @version 1.0.0
15
+ * @author Divizend GmbH
16
+ */
17
+
18
+ /**
19
+ * Supported URI protocols for resource identification
20
+ */
21
+ export enum URIProtocol {
22
+ /** Gmail and Google Workspace resources */
23
+ Gmail = "gmail",
24
+ }
25
+
26
+ /**
27
+ * Types of resources that can be identified by URIs
28
+ */
29
+ export enum URIType {
30
+ /** Individual Gmail message */
31
+ GmailMessage = "GmailMessage",
32
+ /** Specific part of a Gmail message (attachment, body part) */
33
+ GmailMessagePart = "GmailMessagePart",
34
+ }
35
+
36
+ /**
37
+ * Base URI class for resource identification and parsing
38
+ *
39
+ * Provides a unified interface for accessing URI components and
40
+ * validating URI structure across different protocols and resource types.
41
+ */
42
+ export class URI {
43
+ /**
44
+ * Creates a new URI instance
45
+ *
46
+ * @param uri - The complete URI string
47
+ * @param props - Parsed URI properties and components
48
+ */
49
+ constructor(
50
+ public readonly uri: string,
51
+ public readonly props: { [key: string]: string }
52
+ ) {}
53
+
54
+ /**
55
+ * Parses a URI string and creates a URI instance
56
+ *
57
+ * This factory method validates the URI format and extracts
58
+ * relevant components based on the protocol and resource type.
59
+ *
60
+ * @param uri - The URI string to parse
61
+ * @returns URI instance with parsed properties
62
+ * @throws Error if the URI format is invalid or unsupported
63
+ */
64
+ static fromString(uri: string): URI {
65
+ const props: { [key: string]: string } = {};
66
+
67
+ if (uri.startsWith("gmail://")) {
68
+ const parts = uri.split("/");
69
+ if (parts.length === 5 && parts[3] === "message") {
70
+ // gmail://email/message/messageId
71
+ props["protocol"] = URIProtocol.Gmail;
72
+ props["type"] = URIType.GmailMessage;
73
+ props["email"] = parts[2]!;
74
+ props["messageId"] = parts[4]!;
75
+ } else if (
76
+ parts.length === 7 &&
77
+ parts[3] === "message" &&
78
+ parts[5] === "part"
79
+ ) {
80
+ // gmail://email/message/messageId/part/partId
81
+ props["protocol"] = URIProtocol.Gmail;
82
+ props["type"] = URIType.GmailMessagePart;
83
+ props["email"] = parts[2]!;
84
+ props["messageId"] = parts[4]!;
85
+ props["partId"] = parts[6]!;
86
+ } else {
87
+ throw new Error(`Invalid Gmail URI format: ${uri}`);
88
+ }
89
+ } else {
90
+ throw new Error("Invalid URI");
91
+ }
92
+
93
+ return new URI(uri, props);
94
+ }
95
+
96
+ /**
97
+ * Retrieves a URI property by key
98
+ *
99
+ * @param key - The property key to retrieve
100
+ * @returns The property value
101
+ * @throws Error if the key is not found
102
+ */
103
+ get(key: string) {
104
+ if (!this.props[key]) {
105
+ throw new Error(`Key ${key} not found in URI ${this.uri}`);
106
+ }
107
+
108
+ return this.props[key];
109
+ }
110
+
111
+ /** The protocol used by this URI (e.g., "gmail") */
112
+ get protocol() {
113
+ return this.get("protocol");
114
+ }
115
+
116
+ /** The type of resource this URI identifies */
117
+ get type() {
118
+ return this.get("type");
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Specialized URI class for Gmail message resources
124
+ *
125
+ * Provides type-safe access to Gmail message-specific URI components
126
+ * and validates that the URI represents a Gmail message.
127
+ */
128
+ export class GmailMessageURI extends URI {
129
+ /**
130
+ * Creates a GmailMessageURI from a URI string
131
+ *
132
+ * @param uri - The URI string to parse
133
+ * @returns GmailMessageURI instance
134
+ * @throws Error if the URI is not a valid Gmail message URI
135
+ */
136
+ static override fromString(uri: string): GmailMessageURI {
137
+ return GmailMessageURI.fromURI(super.fromString(uri));
138
+ }
139
+
140
+ /**
141
+ * Creates a GmailMessageURI from an existing URI instance
142
+ *
143
+ * @param uri - The URI instance to convert
144
+ * @returns GmailMessageURI instance
145
+ * @throws Error if the URI is not a Gmail message URI
146
+ */
147
+ static fromURI(uri: URI) {
148
+ if (uri.type !== URIType.GmailMessage) {
149
+ throw new Error(`Not a Gmail URI: ${uri.uri}`);
150
+ }
151
+
152
+ return new GmailMessageURI(uri.uri, uri.props);
153
+ }
154
+
155
+ /** The email address associated with this Gmail message */
156
+ get email() {
157
+ return this.get("email");
158
+ }
159
+
160
+ /** The unique identifier for this Gmail message */
161
+ get messageId() {
162
+ return this.get("messageId");
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Specialized URI class for Gmail message part resources
168
+ *
169
+ * Extends GmailMessageURI to provide access to message part-specific
170
+ * components like partId for attachments and body parts.
171
+ */
172
+ export class GmailMessagePartURI extends GmailMessageURI {
173
+ /**
174
+ * Creates a GmailMessagePartURI from a URI string
175
+ *
176
+ * @param uri - The URI string to parse
177
+ * @returns GmailMessagePartURI instance
178
+ * @throws Error if the URI is not a valid Gmail message part URI
179
+ */
180
+ static override fromString(uri: string): GmailMessagePartURI {
181
+ return GmailMessagePartURI.fromURI(super.fromString(uri));
182
+ }
183
+
184
+ /**
185
+ * Creates a GmailMessagePartURI from an existing URI instance
186
+ *
187
+ * @param uri - The URI instance to convert
188
+ * @returns GmailMessagePartURI instance
189
+ * @throws Error if the URI is not a Gmail message part URI
190
+ */
191
+ static override fromURI(uri: URI) {
192
+ if (uri.type !== URIType.GmailMessagePart) {
193
+ throw new Error(`Not a Gmail message part URI: ${uri.uri}`);
194
+ }
195
+
196
+ return new GmailMessagePartURI(uri.uri, uri.props);
197
+ }
198
+
199
+ /** The unique identifier for this message part */
200
+ get partId() {
201
+ return this.get("partId");
202
+ }
203
+ }
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Universe - Central System Orchestrator
3
+ *
4
+ * Please put ALL other APIs in here.
5
+ *
6
+ * @class Universe
7
+ * @version 1.0.0
8
+ * @author Divizend GmbH
9
+ */
10
+
11
+ import {
12
+ Fragment,
13
+ GSuite,
14
+ GmailMessage,
15
+ GmailMessagePart,
16
+ URI,
17
+ URIType,
18
+ EmailQueue,
19
+ EmailProfile,
20
+ QueuedEmail,
21
+ Resend,
22
+ JsonSchemaValidator,
23
+ S2,
24
+ } from "..";
25
+ import { Auth } from "./Auth";
26
+ import { HttpServer } from "../http-server";
27
+ import { NativeHttpServer } from "../http-server/NativeHttpServer";
28
+ import { ScratchContext, ScratchBlock } from "./Scratch";
29
+ import { resolve, join, dirname } from "node:path";
30
+ import { fileURLToPath } from "node:url";
31
+ import { envOrDefault } from "./Env";
32
+
33
+ /**
34
+ * Enumeration of available Universe modules
35
+ */
36
+ export enum UniverseModule {
37
+ /** GSuite integration for Gmail and Google Workspace services */
38
+ GSuite = "gsuite",
39
+ /** Resend email service integration */
40
+ Resend = "resend",
41
+ /** Email queue for managing and sending emails */
42
+ EmailQueue = "emailQueue",
43
+ /** S2 streamstore for durable stream storage */
44
+ S2 = "s2",
45
+ /** Endpoints for Scratch block definitions */
46
+ Endpoints = "endpoints",
47
+ /** Authentication module */
48
+ Auth = "auth",
49
+ }
50
+
51
+ export class Universe {
52
+ /** GSuite integration for Gmail and Google Workspace services */
53
+ public gsuite!: GSuite;
54
+ /** Email queue for managing and sending emails */
55
+ public emailQueue!: EmailQueue;
56
+ /** Resend email service integration */
57
+ public resend?: Resend;
58
+ /** S2 streamstore for durable stream storage */
59
+ public s2!: S2;
60
+ /** JSON Schema validator for request validation */
61
+ public jsonSchemaValidator: JsonSchemaValidator = new JsonSchemaValidator();
62
+ /** Authentication module (enabled by default) */
63
+ public auth: Auth = new Auth();
64
+ /** HTTP server for handling requests */
65
+ public httpServer!: HttpServer;
66
+
67
+ /**
68
+ * Constructs and initializes a new Universe instance
69
+ *
70
+ * This factory method creates a Universe and initializes all its subsystems
71
+ * in parallel for optimal performance. The method ensures proper dependency
72
+ * injection and initialization order.
73
+ *
74
+ * @returns Promise<Universe> - Fully initialized Universe instance
75
+ * @throws Error if any subsystem fails to initialize
76
+ */
77
+ static async construct({
78
+ gsuite: initGSuite = true,
79
+ endpointsDirectory,
80
+ }: {
81
+ gsuite?: boolean;
82
+ endpointsDirectory?: string;
83
+ } = {}): Promise<Universe> {
84
+ const universe = new Universe();
85
+
86
+ // Initialize all subsystems in parallel for optimal performance
87
+ const [gsuite] = await Promise.all([
88
+ initGSuite ? GSuite.construct(universe) : Promise.resolve(undefined),
89
+ ]);
90
+
91
+ universe.gsuite = gsuite!;
92
+
93
+ // Initialize Resend (fetches domains once during construction)
94
+ try {
95
+ universe.resend = await Resend.construct();
96
+ } catch (error) {
97
+ // Resend not configured - this is optional, so we continue without it
98
+ console.warn(
99
+ "Resend not initialized:",
100
+ error instanceof Error ? error.message : String(error)
101
+ );
102
+ }
103
+
104
+ // Initialize S2 streamstore (required)
105
+ try {
106
+ universe.s2 = S2.construct();
107
+ } catch (error) {
108
+ throw new Error(
109
+ `S2 streamstore is required but failed to initialize: ${
110
+ error instanceof Error ? error.message : String(error)
111
+ }`
112
+ );
113
+ }
114
+
115
+ // Initialize email queue with profiles
116
+ const profiles: EmailProfile[] = [];
117
+
118
+ // Resend profile
119
+ if (universe.resend) {
120
+ // Fetch domains once during profile creation
121
+ const resendDomains = universe.resend.getDomains();
122
+ profiles.push({
123
+ domains: resendDomains, // Use cached domains
124
+ getDomains: () => {
125
+ // Return cached domains synchronously
126
+ return universe.resend!.getDomains();
127
+ },
128
+ sendHandler: async (email: QueuedEmail) => {
129
+ const response = await universe.resend!.sendEmail({
130
+ from: email.from,
131
+ to: email.to,
132
+ subject: email.subject,
133
+ html: `<p>${email.content}</p>`,
134
+ });
135
+
136
+ if (!response.ok) {
137
+ throw new Error(
138
+ `Failed to send email via Resend: ${response.text}`
139
+ );
140
+ }
141
+ },
142
+ });
143
+ }
144
+
145
+ // GSuite profile
146
+ if (universe.gsuite) {
147
+ profiles.push({
148
+ domains: [], // Will be populated dynamically
149
+ getDomains: () => {
150
+ try {
151
+ const orgConfigs = (universe.gsuite as any).orgConfigs;
152
+ if (!orgConfigs || Object.keys(orgConfigs).length === 0) {
153
+ return [];
154
+ }
155
+
156
+ const domains: string[] = [];
157
+ for (const orgConfig of Object.values(orgConfigs) as any[]) {
158
+ for (const domain of orgConfig.domains) {
159
+ if (domain.domainName) {
160
+ domains.push(domain.domainName);
161
+ }
162
+ }
163
+ }
164
+ return domains;
165
+ } catch (error) {
166
+ console.warn("Failed to fetch GSuite domains:", error);
167
+ return [];
168
+ }
169
+ },
170
+ sendHandler: async (email: QueuedEmail) => {
171
+ if (!universe.gsuite) {
172
+ throw new Error("Google Workspace not connected");
173
+ }
174
+
175
+ // Use the "from" email as the GSuite user
176
+ const gsuiteUser = universe.gsuite.user(email.from);
177
+ const gmail = gsuiteUser.gmail();
178
+ await gmail.send({
179
+ to: email.to,
180
+ subject: email.subject,
181
+ body: email.content,
182
+ });
183
+ },
184
+ });
185
+ }
186
+
187
+ universe.emailQueue = new EmailQueue(profiles);
188
+
189
+ // Initialize HTTP server
190
+ universe.httpServer = new NativeHttpServer(universe);
191
+
192
+ // Get project root for static files
193
+ const { getProjectRoot } = await import("./ProjectRoot");
194
+ const projectRoot = await getProjectRoot();
195
+
196
+ // Register static files
197
+ universe.httpServer.registerStaticFiles(projectRoot);
198
+
199
+ // Load and register endpoints (if directory is provided)
200
+ if (endpointsDirectory) {
201
+ const endpointsDir = resolve(endpointsDirectory);
202
+ await universe.httpServer.loadEndpointsFromDirectory(endpointsDir);
203
+ }
204
+
205
+ // Log all registered endpoints (if endpoints were loaded)
206
+ if (endpointsDirectory) {
207
+ const endpointInfos = await universe.httpServer.getRegisteredEndpoints();
208
+ console.log("\n📋 Registered Scratch Endpoints:");
209
+ console.log("=".repeat(50));
210
+ endpointInfos.forEach((info) => {
211
+ console.log(
212
+ ` ${info.method.padEnd(4)} ${info.endpoint.padEnd(30)} ${
213
+ info.blockType
214
+ }${info.auth}`
215
+ );
216
+ });
217
+ console.log("=".repeat(50));
218
+ console.log(`Total: ${endpointInfos.length} endpoints\n`);
219
+ }
220
+
221
+ // Start the server (skip if running in Bun, as Bun handles server lifecycle)
222
+ if (typeof Bun === "undefined") {
223
+ const port = parseInt(envOrDefault(undefined, "PORT", "3000"), 10);
224
+ await universe.httpServer.start(port);
225
+ }
226
+
227
+ return universe;
228
+ }
229
+
230
+ /**
231
+ * Retrieves a fragment by its URI identifier
232
+ *
233
+ * This method serves as the central entry point for accessing any content
234
+ * in the system. It parses the URI, determines the content type, and
235
+ * delegates to the appropriate fragment factory method.
236
+ *
237
+ * Supported URI types:
238
+ * - GmailMessage: Individual email messages
239
+ * - GmailMessagePart: Email attachments and body parts
240
+ *
241
+ * @param uri - String URI identifying the fragment to retrieve
242
+ * @returns Promise<Fragment> - The requested fragment instance
243
+ * @throws Error if the URI type is unknown or fragment creation fails
244
+ */
245
+ /**
246
+ * Check if a specific module is available in this Universe instance
247
+ * @param module - The module to check
248
+ * @returns true if the module is available, false otherwise
249
+ */
250
+ hasModule(module: UniverseModule): boolean {
251
+ switch (module) {
252
+ case UniverseModule.GSuite:
253
+ return !!this.gsuite;
254
+ case UniverseModule.Resend:
255
+ return !!this.resend;
256
+ case UniverseModule.EmailQueue:
257
+ return !!this.emailQueue;
258
+ case UniverseModule.S2:
259
+ return !!this.s2;
260
+ case UniverseModule.Auth:
261
+ return !!this.auth;
262
+ default:
263
+ return false;
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Call an endpoint by name with the given arguments
269
+ * Maps arguments to parameter names based on the endpoint's schema
270
+ * @param context - The Scratch context to use for the call
271
+ * @param endpointName - The name (opcode) of the endpoint to call
272
+ * @param ...args - Arguments to pass to the endpoint (will be mapped to parameter names)
273
+ * @returns Promise<any> - The result from the endpoint handler
274
+ */
275
+ async call(
276
+ context: ScratchContext,
277
+ endpointName: string,
278
+ ...args: any[]
279
+ ): Promise<any> {
280
+ const handler = await this.httpServer.getHandler(endpointName);
281
+ if (!handler) {
282
+ throw new Error(`Endpoint handler not found: ${endpointName}`);
283
+ }
284
+
285
+ // Find endpoint definition to get schema for argument mapping
286
+ let endpointBlock: ScratchBlock | null = null;
287
+ for (const e of this.httpServer.getAllEndpoints()) {
288
+ const block = await e.block({});
289
+ if (block.opcode === endpointName) {
290
+ endpointBlock = block;
291
+ break;
292
+ }
293
+ }
294
+
295
+ // Map arguments to parameter names
296
+ const paramNames = endpointBlock?.schema
297
+ ? Object.keys(endpointBlock.schema)
298
+ : [];
299
+ const callInputs =
300
+ args.length > 0
301
+ ? Object.fromEntries(
302
+ args.map((arg, i) => [paramNames[i] || `param${i}`, arg])
303
+ )
304
+ : {};
305
+
306
+ // Call the handler
307
+ const callContext = { ...context, universe: this };
308
+ return await handler(callContext, {}, callInputs, context.authHeader);
309
+ }
310
+
311
+ /**
312
+ * Check if all specified modules are available
313
+ * @param modules - Array of modules to check
314
+ * @returns true if all modules are available, false otherwise
315
+ */
316
+ hasModules(modules: UniverseModule[]): boolean {
317
+ return modules.every((module) => this.hasModule(module));
318
+ }
319
+
320
+ async getFragment(uri: string): Promise<Fragment> {
321
+ const parsedUri = URI.fromString(uri);
322
+
323
+ switch (parsedUri.type) {
324
+ case URIType.GmailMessage: {
325
+ return GmailMessage.fromURI(this, parsedUri);
326
+ }
327
+ case URIType.GmailMessagePart: {
328
+ return GmailMessagePart.fromURI(this, parsedUri);
329
+ }
330
+ default: {
331
+ throw new Error(`Unknown URI type: ${parsedUri.type}`);
332
+ }
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Checks the health of all services in the Universe
338
+ * Aggregates health status from all configured services
339
+ *
340
+ * @returns Promise<{ status: string; services: { [key: string]: any } }>
341
+ */
342
+ async getHealth(): Promise<{
343
+ status: string;
344
+ services: { [key: string]: any };
345
+ }> {
346
+ const health: any = {
347
+ status: "ok",
348
+ services: {},
349
+ };
350
+
351
+ // Check GSuite
352
+ if (this.gsuite) {
353
+ health.services.gsuite = await this.gsuite.getHealth();
354
+ }
355
+
356
+ // Check Resend
357
+ if (this.resend) {
358
+ health.services.resend = this.resend.getHealth();
359
+ } else {
360
+ health.services.resend = {
361
+ status: "warning",
362
+ message: "RESEND_API_KEY not configured",
363
+ connected: false,
364
+ };
365
+ }
366
+
367
+ // Check S2
368
+ if (this.s2) {
369
+ health.services.s2 = await this.s2.getHealth();
370
+ }
371
+
372
+ // Determine overall status
373
+ const hasErrors = Object.values(health.services).some(
374
+ (service: any) => service.status === "error"
375
+ );
376
+ if (hasErrors) {
377
+ health.status = "error";
378
+ } else {
379
+ const hasWarnings = Object.values(health.services).some(
380
+ (service: any) => service.status === "warning"
381
+ );
382
+ if (hasWarnings) {
383
+ health.status = "warning";
384
+ }
385
+ }
386
+
387
+ return health;
388
+ }
389
+ }
390
+
391
+ // Global singleton instance
392
+ let universeInstance: Universe | null = null;
393
+
394
+ /**
395
+ * Get the global Universe singleton instance
396
+ */
397
+ export function getUniverse(): Universe | null {
398
+ return universeInstance;
399
+ }
400
+
401
+ /**
402
+ * Set the global Universe singleton instance
403
+ */
404
+ export function setUniverse(universe: Universe | null): void {
405
+ universeInstance = universe;
406
+ }
package/core/index.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Core Module - Foundation Components
3
+ *
4
+ * This module contains the fundamental building blocks of the AI Executive system:
5
+ * - Universe: Central orchestration and configuration management
6
+ * - Fragment: Abstract interface for all content types (emails, documents, etc.)
7
+ * - URI: Unified resource identification and parsing system
8
+ * - Currency: Financial data handling and conversion utilities
9
+ *
10
+ * These core components provide the foundation for all higher-level functionality
11
+ * including Gmail integration, workflow automation, and AI processing.
12
+ *
13
+ * @module Core
14
+ * @version 1.0.0
15
+ * @author Divizend GmbH
16
+ */
17
+
18
+ export * from "./Universe";
19
+ export * from "./Scratch";
20
+ export * from "./Auth";
21
+ export * from "./Fragment";
22
+ export * from "./FragmentServingMode";
23
+ export * from "./URI";
24
+ export * from "./Currency";
25
+ export * from "./JsonSchemaValidator";
26
+ export * from "./Env";
27
+ export * from "./ProjectRoot";