jiva-core 0.2.2 → 0.3.1

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 (156) hide show
  1. package/.dockerignore +53 -0
  2. package/.gcloudignore +49 -0
  3. package/CONTRIBUTING.md +92 -0
  4. package/Dockerfile +63 -0
  5. package/LICENSE +21 -0
  6. package/README.md +248 -102
  7. package/cloud-run-deploy.yaml +135 -0
  8. package/cloud-run.yaml +135 -0
  9. package/cloud-run.yaml.template +143 -0
  10. package/deploy.sh +107 -0
  11. package/dist/core/agent-spawner.d.ts +89 -0
  12. package/dist/core/agent-spawner.d.ts.map +1 -0
  13. package/dist/core/agent-spawner.js +195 -0
  14. package/dist/core/agent-spawner.js.map +1 -0
  15. package/dist/core/client-agent.d.ts +82 -0
  16. package/dist/core/client-agent.d.ts.map +1 -0
  17. package/dist/core/client-agent.js +406 -0
  18. package/dist/core/client-agent.js.map +1 -0
  19. package/dist/core/config.d.ts +59 -10
  20. package/dist/core/config.d.ts.map +1 -1
  21. package/dist/core/config.js +19 -2
  22. package/dist/core/config.js.map +1 -1
  23. package/dist/core/conversation-manager.d.ts +10 -18
  24. package/dist/core/conversation-manager.d.ts.map +1 -1
  25. package/dist/core/conversation-manager.js +28 -60
  26. package/dist/core/conversation-manager.js.map +1 -1
  27. package/dist/core/dual-agent.d.ts +24 -3
  28. package/dist/core/dual-agent.d.ts.map +1 -1
  29. package/dist/core/dual-agent.js +112 -19
  30. package/dist/core/dual-agent.js.map +1 -1
  31. package/dist/core/manager-agent.d.ts +3 -1
  32. package/dist/core/manager-agent.d.ts.map +1 -1
  33. package/dist/core/manager-agent.js +66 -14
  34. package/dist/core/manager-agent.js.map +1 -1
  35. package/dist/core/worker-agent.d.ts +15 -1
  36. package/dist/core/worker-agent.d.ts.map +1 -1
  37. package/dist/core/worker-agent.js +244 -11
  38. package/dist/core/worker-agent.js.map +1 -1
  39. package/dist/core/workspace.d.ts +5 -0
  40. package/dist/core/workspace.d.ts.map +1 -1
  41. package/dist/core/workspace.js +47 -7
  42. package/dist/core/workspace.js.map +1 -1
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +4 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/interfaces/cli/index.js +376 -44
  48. package/dist/interfaces/cli/index.js.map +1 -1
  49. package/dist/interfaces/cli/repl.d.ts.map +1 -1
  50. package/dist/interfaces/cli/repl.js +6 -0
  51. package/dist/interfaces/cli/repl.js.map +1 -1
  52. package/dist/interfaces/http/index.d.ts +22 -0
  53. package/dist/interfaces/http/index.d.ts.map +1 -0
  54. package/dist/interfaces/http/index.js +135 -0
  55. package/dist/interfaces/http/index.js.map +1 -0
  56. package/dist/interfaces/http/middleware/auth.d.ts +32 -0
  57. package/dist/interfaces/http/middleware/auth.d.ts.map +1 -0
  58. package/dist/interfaces/http/middleware/auth.js +176 -0
  59. package/dist/interfaces/http/middleware/auth.js.map +1 -0
  60. package/dist/interfaces/http/routes/chat.d.ts +7 -0
  61. package/dist/interfaces/http/routes/chat.d.ts.map +1 -0
  62. package/dist/interfaces/http/routes/chat.js +144 -0
  63. package/dist/interfaces/http/routes/chat.js.map +1 -0
  64. package/dist/interfaces/http/routes/health.d.ts +6 -0
  65. package/dist/interfaces/http/routes/health.d.ts.map +1 -0
  66. package/dist/interfaces/http/routes/health.js +25 -0
  67. package/dist/interfaces/http/routes/health.js.map +1 -0
  68. package/dist/interfaces/http/routes/session.d.ts +7 -0
  69. package/dist/interfaces/http/routes/session.d.ts.map +1 -0
  70. package/dist/interfaces/http/routes/session.js +114 -0
  71. package/dist/interfaces/http/routes/session.js.map +1 -0
  72. package/dist/interfaces/http/session-manager.d.ts +76 -0
  73. package/dist/interfaces/http/session-manager.d.ts.map +1 -0
  74. package/dist/interfaces/http/session-manager.js +339 -0
  75. package/dist/interfaces/http/session-manager.js.map +1 -0
  76. package/dist/interfaces/http/websocket-handler.d.ts +18 -0
  77. package/dist/interfaces/http/websocket-handler.d.ts.map +1 -0
  78. package/dist/interfaces/http/websocket-handler.js +146 -0
  79. package/dist/interfaces/http/websocket-handler.js.map +1 -0
  80. package/dist/mcp/client.d.ts +11 -2
  81. package/dist/mcp/client.d.ts.map +1 -1
  82. package/dist/mcp/client.js +44 -19
  83. package/dist/mcp/client.js.map +1 -1
  84. package/dist/mcp/server-manager.d.ts +1 -1
  85. package/dist/mcp/server-manager.d.ts.map +1 -1
  86. package/dist/mcp/server-manager.js +12 -2
  87. package/dist/mcp/server-manager.js.map +1 -1
  88. package/dist/personas/index.d.ts +13 -0
  89. package/dist/personas/index.d.ts.map +1 -0
  90. package/dist/personas/index.js +13 -0
  91. package/dist/personas/index.js.map +1 -0
  92. package/dist/personas/persona-loader.d.ts +30 -0
  93. package/dist/personas/persona-loader.d.ts.map +1 -0
  94. package/dist/personas/persona-loader.js +246 -0
  95. package/dist/personas/persona-loader.js.map +1 -0
  96. package/dist/personas/persona-manager.d.ts +82 -0
  97. package/dist/personas/persona-manager.d.ts.map +1 -0
  98. package/dist/personas/persona-manager.js +211 -0
  99. package/dist/personas/persona-manager.js.map +1 -0
  100. package/dist/personas/skill-loader.d.ts +35 -0
  101. package/dist/personas/skill-loader.d.ts.map +1 -0
  102. package/dist/personas/skill-loader.js +144 -0
  103. package/dist/personas/skill-loader.js.map +1 -0
  104. package/dist/personas/skill-packager.d.ts +25 -0
  105. package/dist/personas/skill-packager.d.ts.map +1 -0
  106. package/dist/personas/skill-packager.js +233 -0
  107. package/dist/personas/skill-packager.js.map +1 -0
  108. package/dist/personas/types.d.ts +134 -0
  109. package/dist/personas/types.d.ts.map +1 -0
  110. package/dist/personas/types.js +7 -0
  111. package/dist/personas/types.js.map +1 -0
  112. package/dist/personas/validator.d.ts +22 -0
  113. package/dist/personas/validator.d.ts.map +1 -0
  114. package/dist/personas/validator.js +144 -0
  115. package/dist/personas/validator.js.map +1 -0
  116. package/dist/storage/factory.d.ts +51 -0
  117. package/dist/storage/factory.d.ts.map +1 -0
  118. package/dist/storage/factory.js +154 -0
  119. package/dist/storage/factory.js.map +1 -0
  120. package/dist/storage/gcp-bucket-provider.d.ts +59 -0
  121. package/dist/storage/gcp-bucket-provider.d.ts.map +1 -0
  122. package/dist/storage/gcp-bucket-provider.js +275 -0
  123. package/dist/storage/gcp-bucket-provider.js.map +1 -0
  124. package/dist/storage/index.d.ts +33 -0
  125. package/dist/storage/index.d.ts.map +1 -0
  126. package/dist/storage/index.js +37 -0
  127. package/dist/storage/index.js.map +1 -0
  128. package/dist/storage/local-provider.d.ts +36 -0
  129. package/dist/storage/local-provider.d.ts.map +1 -0
  130. package/dist/storage/local-provider.js +219 -0
  131. package/dist/storage/local-provider.js.map +1 -0
  132. package/dist/storage/provider.d.ts +137 -0
  133. package/dist/storage/provider.d.ts.map +1 -0
  134. package/dist/storage/provider.js +136 -0
  135. package/dist/storage/provider.js.map +1 -0
  136. package/dist/storage/types.d.ts +78 -0
  137. package/dist/storage/types.d.ts.map +1 -0
  138. package/dist/storage/types.js +14 -0
  139. package/dist/storage/types.js.map +1 -0
  140. package/dist/utils/orchestration-logger.d.ts +36 -0
  141. package/dist/utils/orchestration-logger.d.ts.map +1 -0
  142. package/dist/utils/orchestration-logger.js +224 -0
  143. package/dist/utils/orchestration-logger.js.map +1 -0
  144. package/jiva-new-demo.gif +0 -0
  145. package/package.json +30 -2
  146. package/.fluen/cache/state.json +0 -7
  147. package/actions/action_registry.py +0 -75
  148. package/actions/python_coder.py +0 -470
  149. package/api/main.py +0 -269
  150. package/downloaded_image.avif +0 -0
  151. package/downloads/snipping_tool.avif +0 -0
  152. package/image.avif +0 -0
  153. package/ms_image.avif +0 -0
  154. package/screenshot.png +0 -0
  155. package/snipping_tool.avif +0 -0
  156. package/tmp_image.avif +0 -0
@@ -0,0 +1,275 @@
1
+ /**
2
+ * GCPBucketProvider - Google Cloud Storage based persistence
3
+ *
4
+ * Path structure:
5
+ * {bucket}/
6
+ * {tenantId}/
7
+ * config.json
8
+ * conversations/
9
+ * {conversationId}.json
10
+ * sessions/
11
+ * {sessionId}/
12
+ * state.json
13
+ * logs/
14
+ * {sessionId}.log
15
+ * directives/
16
+ * {workspaceHash}.md
17
+ *
18
+ * IMPORTANT: In cloud mode, setContext() MUST be called with tenantId/sessionId
19
+ * from the authenticated request (JWT) before any operations.
20
+ */
21
+ import { StorageProvider } from './provider.js';
22
+ import { createHash } from 'crypto';
23
+ export class GCPBucketProvider extends StorageProvider {
24
+ bucket = null;
25
+ bucketName;
26
+ configCache = new Map(); // Per-tenant config cache
27
+ constructor(infraConfig) {
28
+ super(infraConfig);
29
+ if (!infraConfig.gcpBucketName) {
30
+ throw new Error('GCP bucket name is required (gcpBucketName or JIVA_GCP_BUCKET env var)');
31
+ }
32
+ this.bucketName = infraConfig.gcpBucketName;
33
+ // No default context - MUST be set via setContext() in cloud mode
34
+ }
35
+ async initialize() {
36
+ // Dynamic import to avoid requiring the package when not used
37
+ let Storage;
38
+ try {
39
+ // @ts-ignore - dynamic import of optional dependency
40
+ const gcs = await import('@google-cloud/storage');
41
+ Storage = gcs.Storage;
42
+ }
43
+ catch (error) {
44
+ throw new Error('GCP Storage requires @google-cloud/storage package. Install with: npm install @google-cloud/storage');
45
+ }
46
+ // Initialize storage client
47
+ const storageOptions = {};
48
+ if (this.infraConfig.gcpProjectId) {
49
+ storageOptions.projectId = this.infraConfig.gcpProjectId;
50
+ }
51
+ if (this.infraConfig.gcpKeyFilePath) {
52
+ storageOptions.keyFilename = this.infraConfig.gcpKeyFilePath;
53
+ }
54
+ // Otherwise uses Application Default Credentials (ADC)
55
+ const storage = new Storage(storageOptions);
56
+ this.bucket = storage.bucket(this.bucketName);
57
+ // Verify bucket access
58
+ try {
59
+ await this.bucket.exists();
60
+ }
61
+ catch (error) {
62
+ throw new Error(`Cannot access GCP bucket '${this.bucketName}': ${error}`);
63
+ }
64
+ this.initialized = true;
65
+ }
66
+ // ─────────────────────────────────────────────────────────────
67
+ // Helper Methods
68
+ // ─────────────────────────────────────────────────────────────
69
+ async readJson(path) {
70
+ if (!this.bucket)
71
+ throw new Error('Provider not initialized');
72
+ try {
73
+ const file = this.bucket.file(path);
74
+ const [exists] = await file.exists();
75
+ if (!exists)
76
+ return null;
77
+ const [content] = await file.download();
78
+ return JSON.parse(content.toString('utf-8'));
79
+ }
80
+ catch (error) {
81
+ return null;
82
+ }
83
+ }
84
+ async writeJson(path, data) {
85
+ if (!this.bucket)
86
+ throw new Error('Provider not initialized');
87
+ const file = this.bucket.file(path);
88
+ await file.save(JSON.stringify(data, null, 2), {
89
+ contentType: 'application/json',
90
+ });
91
+ }
92
+ async writeText(path, content) {
93
+ if (!this.bucket)
94
+ throw new Error('Provider not initialized');
95
+ const file = this.bucket.file(path);
96
+ await file.save(content, {
97
+ contentType: 'text/plain',
98
+ });
99
+ }
100
+ async readText(path) {
101
+ if (!this.bucket)
102
+ throw new Error('Provider not initialized');
103
+ try {
104
+ const file = this.bucket.file(path);
105
+ const [exists] = await file.exists();
106
+ if (!exists)
107
+ return null;
108
+ const [content] = await file.download();
109
+ return content.toString('utf-8');
110
+ }
111
+ catch (error) {
112
+ return null;
113
+ }
114
+ }
115
+ async deleteFile(path) {
116
+ if (!this.bucket)
117
+ throw new Error('Provider not initialized');
118
+ try {
119
+ await this.bucket.file(path).delete();
120
+ }
121
+ catch (error) {
122
+ // Ignore if doesn't exist
123
+ }
124
+ }
125
+ async listFiles(prefix) {
126
+ if (!this.bucket)
127
+ throw new Error('Provider not initialized');
128
+ const [files] = await this.bucket.getFiles({ prefix });
129
+ return files.map((f) => f.name);
130
+ }
131
+ hashWorkspacePath(workspacePath) {
132
+ return createHash('sha256').update(workspacePath).digest('hex').substring(0, 16);
133
+ }
134
+ // ─────────────────────────────────────────────────────────────
135
+ // Configuration (per-tenant, cached)
136
+ // ─────────────────────────────────────────────────────────────
137
+ async loadConfigCache() {
138
+ const ctx = this.requireContext();
139
+ // Check memory cache first
140
+ if (this.configCache.has(ctx.tenantId)) {
141
+ return this.configCache.get(ctx.tenantId);
142
+ }
143
+ // Load from storage
144
+ const configPath = this.getConfigPath();
145
+ const config = (await this.readJson(configPath)) || {};
146
+ this.configCache.set(ctx.tenantId, config);
147
+ return config;
148
+ }
149
+ async getConfig(key) {
150
+ const config = await this.loadConfigCache();
151
+ return config[key];
152
+ }
153
+ async setConfig(key, value) {
154
+ const config = await this.loadConfigCache();
155
+ config[key] = value;
156
+ const ctx = this.requireContext();
157
+ this.configCache.set(ctx.tenantId, config);
158
+ await this.writeJson(this.getConfigPath(), config);
159
+ }
160
+ async getAllConfig() {
161
+ return { ...(await this.loadConfigCache()) };
162
+ }
163
+ // ─────────────────────────────────────────────────────────────
164
+ // Conversations
165
+ // ─────────────────────────────────────────────────────────────
166
+ getConversationObjectPath(id) {
167
+ return `${this.getConversationsPath()}${id}.json`;
168
+ }
169
+ async saveConversation(conversation) {
170
+ const objectPath = this.getConversationObjectPath(conversation.metadata.id);
171
+ await this.writeJson(objectPath, conversation);
172
+ return conversation.metadata.id;
173
+ }
174
+ async loadConversation(id) {
175
+ const objectPath = this.getConversationObjectPath(id);
176
+ return await this.readJson(objectPath);
177
+ }
178
+ async listConversations() {
179
+ const prefix = this.getConversationsPath();
180
+ const files = await this.listFiles(prefix);
181
+ const conversations = [];
182
+ for (const file of files) {
183
+ if (file.endsWith('.json')) {
184
+ const conv = await this.readJson(file);
185
+ if (conv) {
186
+ conversations.push(conv.metadata);
187
+ }
188
+ }
189
+ }
190
+ return conversations.sort((a, b) => new Date(b.updated).getTime() - new Date(a.updated).getTime());
191
+ }
192
+ async deleteConversation(id) {
193
+ const objectPath = this.getConversationObjectPath(id);
194
+ await this.deleteFile(objectPath);
195
+ }
196
+ // ─────────────────────────────────────────────────────────────
197
+ // Directive
198
+ // ─────────────────────────────────────────────────────────────
199
+ async loadDirective(workspacePath) {
200
+ const hash = this.hashWorkspacePath(workspacePath);
201
+ const objectPath = `${this.getTenantPath()}directives/${hash}.md`;
202
+ const content = await this.readText(objectPath);
203
+ return content || undefined;
204
+ }
205
+ async saveDirective(workspacePath, content) {
206
+ const hash = this.hashWorkspacePath(workspacePath);
207
+ const objectPath = `${this.getTenantPath()}directives/${hash}.md`;
208
+ await this.writeText(objectPath, content);
209
+ }
210
+ // ─────────────────────────────────────────────────────────────
211
+ // Logging
212
+ // ─────────────────────────────────────────────────────────────
213
+ async flushLogs() {
214
+ if (this.logBuffer.length === 0)
215
+ return;
216
+ const logPath = `${this.getLogsPath()}orchestration.log`;
217
+ const logContent = this.logBuffer
218
+ .map(entry => `[${entry.timestamp}] [${entry.level.toUpperCase()}] ${entry.event}${entry.data ? ' ' + JSON.stringify(entry.data) : ''}`)
219
+ .join('\n') + '\n';
220
+ // Append to existing log or create new
221
+ const existingContent = await this.readText(logPath);
222
+ const newContent = existingContent ? existingContent + logContent : logContent;
223
+ await this.writeText(logPath, newContent);
224
+ this.clearLogBuffer();
225
+ }
226
+ // ─────────────────────────────────────────────────────────────
227
+ // State Snapshots
228
+ // ─────────────────────────────────────────────────────────────
229
+ async exportState() {
230
+ const ctx = this.requireContext();
231
+ const conversation = await this.loadConversation(ctx.sessionId);
232
+ return {
233
+ version: '1.0.0',
234
+ tenantId: ctx.tenantId,
235
+ sessionId: ctx.sessionId,
236
+ exportedAt: new Date().toISOString(),
237
+ config: await this.getAllConfig(),
238
+ conversation,
239
+ directive: undefined,
240
+ logBuffer: this.getLogBuffer(),
241
+ };
242
+ }
243
+ async importState(state) {
244
+ // Set context from imported state
245
+ this.setContext({
246
+ tenantId: state.tenantId,
247
+ sessionId: state.sessionId,
248
+ });
249
+ // Import config
250
+ const ctx = this.requireContext();
251
+ this.configCache.set(ctx.tenantId, state.config);
252
+ await this.writeJson(this.getConfigPath(), state.config);
253
+ // Import conversation if present
254
+ if (state.conversation) {
255
+ await this.saveConversation(state.conversation);
256
+ }
257
+ // Import log buffer
258
+ this.logBuffer = [...state.logBuffer];
259
+ }
260
+ /**
261
+ * Save complete state snapshot for cloud function handoff
262
+ */
263
+ async saveStateSnapshot(state) {
264
+ const snapshotPath = `${this.getSessionPath()}state.json`;
265
+ await this.writeJson(snapshotPath, state);
266
+ }
267
+ /**
268
+ * Load state snapshot for cloud function restoration
269
+ */
270
+ async loadStateSnapshot() {
271
+ const snapshotPath = `${this.getSessionPath()}state.json`;
272
+ return await this.readJson(snapshotPath);
273
+ }
274
+ }
275
+ //# sourceMappingURL=gcp-bucket-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcp-bucket-provider.js","sourceRoot":"","sources":["../../src/storage/gcp-bucket-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Storage Module - Exports for the storage abstraction layer
3
+ *
4
+ * This module provides a unified interface for state persistence
5
+ * across different deployment modes:
6
+ *
7
+ * - CLI/Desktop: Uses LocalStorageProvider with filesystem (default)
8
+ * - Cloud Functions: Uses GCPBucketProvider (or other cloud providers)
9
+ *
10
+ * USAGE PATTERNS:
11
+ *
12
+ * 1. CLI Mode (backward compatible):
13
+ * const provider = await createLocalProvider();
14
+ * // Ready to use immediately with default context
15
+ *
16
+ * 2. Cloud Mode (with authenticated context):
17
+ * const provider = await createStorageProviderWithContext(
18
+ * { tenantId: jwt.sub, sessionId: req.sessionId },
19
+ * { gcpBucketName: 'my-bucket' }
20
+ * );
21
+ * // Ready to use with user's context
22
+ *
23
+ * 3. Cloud Mode (manual context):
24
+ * const provider = await createGCPProvider('my-bucket');
25
+ * provider.setContext({ tenantId, sessionId }); // From JWT
26
+ * // Now ready to use
27
+ */
28
+ export { StorageContext, ConversationMetadata, SavedConversation, LogEntry, JivaState, StorageInfraConfig, StorageProviderType, } from './types.js';
29
+ export { StorageProvider } from './provider.js';
30
+ export { LocalStorageProvider } from './local-provider.js';
31
+ export { GCPBucketProvider } from './gcp-bucket-provider.js';
32
+ export { createStorageProvider, createStorageProviderWithContext, createLocalProvider, createGCPProvider, } from './factory.js';
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EACL,qBAAqB,EACrB,gCAAgC,EAChC,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Storage Module - Exports for the storage abstraction layer
3
+ *
4
+ * This module provides a unified interface for state persistence
5
+ * across different deployment modes:
6
+ *
7
+ * - CLI/Desktop: Uses LocalStorageProvider with filesystem (default)
8
+ * - Cloud Functions: Uses GCPBucketProvider (or other cloud providers)
9
+ *
10
+ * USAGE PATTERNS:
11
+ *
12
+ * 1. CLI Mode (backward compatible):
13
+ * const provider = await createLocalProvider();
14
+ * // Ready to use immediately with default context
15
+ *
16
+ * 2. Cloud Mode (with authenticated context):
17
+ * const provider = await createStorageProviderWithContext(
18
+ * { tenantId: jwt.sub, sessionId: req.sessionId },
19
+ * { gcpBucketName: 'my-bucket' }
20
+ * );
21
+ * // Ready to use with user's context
22
+ *
23
+ * 3. Cloud Mode (manual context):
24
+ * const provider = await createGCPProvider('my-bucket');
25
+ * provider.setContext({ tenantId, sessionId }); // From JWT
26
+ * // Now ready to use
27
+ */
28
+ // Types
29
+ export { StorageProviderType, } from './types.js';
30
+ // Base class
31
+ export { StorageProvider } from './provider.js';
32
+ // Implementations
33
+ export { LocalStorageProvider } from './local-provider.js';
34
+ export { GCPBucketProvider } from './gcp-bucket-provider.js';
35
+ // Factory
36
+ export { createStorageProvider, createStorageProviderWithContext, createLocalProvider, createGCPProvider, } from './factory.js';
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,QAAQ;AACR,OAAO,EAOL,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,aAAa;AACb,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,kBAAkB;AAClB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,UAAU;AACV,OAAO,EACL,qBAAqB,EACrB,gCAAgC,EAChC,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * LocalStorageProvider - Filesystem-based storage for CLI/Desktop
3
+ *
4
+ * Maintains backward compatibility with existing ~/.jiva structure
5
+ *
6
+ * In CLI mode, uses default tenant/session for backward compatibility
7
+ * Context can be overridden via setContext() if needed
8
+ */
9
+ import { StorageProvider } from './provider.js';
10
+ import { StorageInfraConfig, SavedConversation, ConversationMetadata, JivaState } from './types.js';
11
+ export declare class LocalStorageProvider extends StorageProvider {
12
+ private basePath;
13
+ private configCache;
14
+ constructor(infraConfig?: StorageInfraConfig);
15
+ initialize(): Promise<void>;
16
+ /**
17
+ * Update session ID (useful for CLI when starting new conversation)
18
+ */
19
+ setSessionId(sessionId: string): void;
20
+ private loadConfigCache;
21
+ private saveConfigCache;
22
+ getConfig<T>(key: string): Promise<T | undefined>;
23
+ setConfig<T>(key: string, value: T): Promise<void>;
24
+ getAllConfig(): Promise<Record<string, any>>;
25
+ private getConversationFilePath;
26
+ saveConversation(conversation: SavedConversation): Promise<string>;
27
+ loadConversation(id: string): Promise<SavedConversation | null>;
28
+ listConversations(): Promise<ConversationMetadata[]>;
29
+ deleteConversation(id: string): Promise<void>;
30
+ loadDirective(workspacePath: string): Promise<string | undefined>;
31
+ saveDirective(workspacePath: string, content: string): Promise<void>;
32
+ flushLogs(): Promise<void>;
33
+ exportState(): Promise<JivaState>;
34
+ importState(state: JivaState): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=local-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-provider.d.ts","sourceRoot":"","sources":["../../src/storage/local-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACV,MAAM,YAAY,CAAC;AAMpB,qBAAa,oBAAqB,SAAQ,eAAe;IACvD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAA2B;gBAElC,WAAW,GAAE,kBAAuB;IAY1C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;YAYvB,eAAe;YAYf,eAAe;IAKvB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIjD,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAQlD,OAAO,CAAC,uBAAuB;IAIzB,gBAAgB,CAAC,YAAY,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAMlE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAU/D,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA+BpD,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7C,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAqBjE,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB1B,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC;IAgBjC,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBnD"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * LocalStorageProvider - Filesystem-based storage for CLI/Desktop
3
+ *
4
+ * Maintains backward compatibility with existing ~/.jiva structure
5
+ *
6
+ * In CLI mode, uses default tenant/session for backward compatibility
7
+ * Context can be overridden via setContext() if needed
8
+ */
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ import { existsSync, mkdirSync } from 'fs';
12
+ import { homedir } from 'os';
13
+ import { StorageProvider } from './provider.js';
14
+ // Default context for CLI mode (backward compatibility)
15
+ const CLI_DEFAULT_TENANT = 'local';
16
+ const CLI_DEFAULT_SESSION = 'cli-session';
17
+ export class LocalStorageProvider extends StorageProvider {
18
+ basePath;
19
+ configCache = {};
20
+ constructor(infraConfig = {}) {
21
+ super(infraConfig);
22
+ this.basePath = infraConfig.basePath || path.join(homedir(), '.jiva');
23
+ // Set default context for CLI mode (backward compatibility)
24
+ // Cloud mode should call setContext() to override this
25
+ this.context = {
26
+ tenantId: CLI_DEFAULT_TENANT,
27
+ sessionId: CLI_DEFAULT_SESSION,
28
+ };
29
+ }
30
+ async initialize() {
31
+ // Ensure base directories exist
32
+ const dirs = [
33
+ this.basePath,
34
+ path.join(this.basePath, 'conversations'),
35
+ path.join(this.basePath, 'logs'),
36
+ ];
37
+ for (const dir of dirs) {
38
+ if (!existsSync(dir)) {
39
+ mkdirSync(dir, { recursive: true });
40
+ }
41
+ }
42
+ // Load config into cache
43
+ await this.loadConfigCache();
44
+ this.initialized = true;
45
+ }
46
+ /**
47
+ * Update session ID (useful for CLI when starting new conversation)
48
+ */
49
+ setSessionId(sessionId) {
50
+ if (!this.context) {
51
+ this.context = { tenantId: CLI_DEFAULT_TENANT, sessionId };
52
+ }
53
+ else {
54
+ this.context.sessionId = sessionId;
55
+ }
56
+ }
57
+ // ─────────────────────────────────────────────────────────────
58
+ // Configuration
59
+ // ─────────────────────────────────────────────────────────────
60
+ async loadConfigCache() {
61
+ const configPath = path.join(this.basePath, 'config.json');
62
+ try {
63
+ if (existsSync(configPath)) {
64
+ const content = await fs.readFile(configPath, 'utf-8');
65
+ this.configCache = JSON.parse(content);
66
+ }
67
+ }
68
+ catch (error) {
69
+ this.configCache = {};
70
+ }
71
+ }
72
+ async saveConfigCache() {
73
+ const configPath = path.join(this.basePath, 'config.json');
74
+ await fs.writeFile(configPath, JSON.stringify(this.configCache, null, 2));
75
+ }
76
+ async getConfig(key) {
77
+ return this.configCache[key];
78
+ }
79
+ async setConfig(key, value) {
80
+ this.configCache[key] = value;
81
+ await this.saveConfigCache();
82
+ }
83
+ async getAllConfig() {
84
+ return { ...this.configCache };
85
+ }
86
+ // ─────────────────────────────────────────────────────────────
87
+ // Conversations
88
+ // ─────────────────────────────────────────────────────────────
89
+ getConversationFilePath(id) {
90
+ return path.join(this.basePath, 'conversations', `${id}.json`);
91
+ }
92
+ async saveConversation(conversation) {
93
+ const filePath = this.getConversationFilePath(conversation.metadata.id);
94
+ await fs.writeFile(filePath, JSON.stringify(conversation, null, 2));
95
+ return conversation.metadata.id;
96
+ }
97
+ async loadConversation(id) {
98
+ const filePath = this.getConversationFilePath(id);
99
+ try {
100
+ const content = await fs.readFile(filePath, 'utf-8');
101
+ return JSON.parse(content);
102
+ }
103
+ catch (error) {
104
+ return null;
105
+ }
106
+ }
107
+ async listConversations() {
108
+ const conversationsDir = path.join(this.basePath, 'conversations');
109
+ try {
110
+ const files = await fs.readdir(conversationsDir);
111
+ const conversations = [];
112
+ for (const file of files) {
113
+ if (file.endsWith('.json')) {
114
+ try {
115
+ const content = await fs.readFile(path.join(conversationsDir, file), 'utf-8');
116
+ const conv = JSON.parse(content);
117
+ conversations.push(conv.metadata);
118
+ }
119
+ catch (error) {
120
+ // Skip invalid files
121
+ }
122
+ }
123
+ }
124
+ // Sort by updated date, newest first
125
+ return conversations.sort((a, b) => new Date(b.updated).getTime() - new Date(a.updated).getTime());
126
+ }
127
+ catch (error) {
128
+ return [];
129
+ }
130
+ }
131
+ async deleteConversation(id) {
132
+ const filePath = this.getConversationFilePath(id);
133
+ try {
134
+ await fs.unlink(filePath);
135
+ }
136
+ catch (error) {
137
+ // Ignore if file doesn't exist
138
+ }
139
+ }
140
+ // ─────────────────────────────────────────────────────────────
141
+ // Directive
142
+ // ─────────────────────────────────────────────────────────────
143
+ async loadDirective(workspacePath) {
144
+ // Try multiple locations (matching existing workspace.ts logic)
145
+ const candidates = [
146
+ path.join(workspacePath, 'jiva-directive.md'),
147
+ path.join(workspacePath, 'directive.md'),
148
+ path.join(workspacePath, '.jiva', 'directive.md'),
149
+ ];
150
+ for (const candidate of candidates) {
151
+ try {
152
+ if (existsSync(candidate)) {
153
+ return await fs.readFile(candidate, 'utf-8');
154
+ }
155
+ }
156
+ catch (error) {
157
+ // Continue to next candidate
158
+ }
159
+ }
160
+ return undefined;
161
+ }
162
+ async saveDirective(workspacePath, content) {
163
+ const directivePath = path.join(workspacePath, 'jiva-directive.md');
164
+ await fs.writeFile(directivePath, content);
165
+ }
166
+ // ─────────────────────────────────────────────────────────────
167
+ // Logging
168
+ // ─────────────────────────────────────────────────────────────
169
+ async flushLogs() {
170
+ if (this.logBuffer.length === 0)
171
+ return;
172
+ const ctx = this.requireContext();
173
+ const logsDir = path.join(this.basePath, 'logs');
174
+ if (!existsSync(logsDir)) {
175
+ mkdirSync(logsDir, { recursive: true });
176
+ }
177
+ const logFile = path.join(logsDir, `${ctx.sessionId}.log`);
178
+ const logContent = this.logBuffer
179
+ .map(entry => `[${entry.timestamp}] [${entry.level.toUpperCase()}] ${entry.event}${entry.data ? ' ' + JSON.stringify(entry.data) : ''}`)
180
+ .join('\n') + '\n';
181
+ await fs.appendFile(logFile, logContent);
182
+ this.clearLogBuffer();
183
+ }
184
+ // ─────────────────────────────────────────────────────────────
185
+ // State Snapshots
186
+ // ─────────────────────────────────────────────────────────────
187
+ async exportState() {
188
+ const ctx = this.requireContext();
189
+ const conversation = await this.loadConversation(ctx.sessionId);
190
+ return {
191
+ version: '1.0.0',
192
+ tenantId: ctx.tenantId,
193
+ sessionId: ctx.sessionId,
194
+ exportedAt: new Date().toISOString(),
195
+ config: await this.getAllConfig(),
196
+ conversation,
197
+ directive: undefined, // Loaded separately per workspace
198
+ logBuffer: this.getLogBuffer(),
199
+ };
200
+ }
201
+ async importState(state) {
202
+ // Set context from imported state
203
+ this.setContext({
204
+ tenantId: state.tenantId,
205
+ sessionId: state.sessionId,
206
+ });
207
+ // Import config
208
+ for (const [key, value] of Object.entries(state.config)) {
209
+ await this.setConfig(key, value);
210
+ }
211
+ // Import conversation if present
212
+ if (state.conversation) {
213
+ await this.saveConversation(state.conversation);
214
+ }
215
+ // Import log buffer
216
+ this.logBuffer = [...state.logBuffer];
217
+ }
218
+ }
219
+ //# sourceMappingURL=local-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-provider.js","sourceRoot":"","sources":["../../src/storage/local-provider.ts"],"names":[],"mappings":"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"}