crewly 1.5.11 → 1.5.13

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/config/constants.ts +3 -3
  2. package/config/orchestrator_tasks/prompts/orchestrator-prompt.md +73 -0
  3. package/config/roles/architect/prompt.md +9 -0
  4. package/config/roles/backend-developer/prompt.md +9 -0
  5. package/config/roles/content-strategist/prompt.md +10 -0
  6. package/config/roles/designer/prompt.md +9 -0
  7. package/config/roles/developer/prompt.md +9 -0
  8. package/config/roles/frontend-developer/prompt.md +9 -0
  9. package/config/roles/fullstack-dev/prompt.md +9 -0
  10. package/config/roles/generalist/prompt.md +9 -0
  11. package/config/roles/ops/prompt.md +9 -0
  12. package/config/roles/product-manager/prompt.md +9 -0
  13. package/config/roles/qa/prompt.md +9 -0
  14. package/config/roles/qa-engineer/prompt.md +9 -0
  15. package/config/roles/researcher/prompt.md +9 -0
  16. package/config/roles/sales/prompt.md +9 -0
  17. package/config/roles/support/prompt.md +9 -0
  18. package/config/roles/team-leader/prompt.md +11 -0
  19. package/config/roles/tpm/prompt.md +9 -0
  20. package/config/roles/ux-designer/prompt.md +9 -0
  21. package/config/skills/_common/lib.sh +31 -0
  22. package/config/skills/_common/lib.test.sh +164 -0
  23. package/config/skills/agent/core/block-task/execute.sh +3 -1
  24. package/config/skills/agent/core/pipe-to-sink/execute.sh +41 -0
  25. package/config/skills/agent/core/read-task/execute.sh +3 -1
  26. package/config/skills/agent/core/report-progress/execute.sh +3 -1
  27. package/config/skills/agent/screenshot-compare/SKILL.md +75 -0
  28. package/config/skills/agent/screenshot-compare/execute.sh +182 -0
  29. package/config/skills/agent/screenshot-compare/skill.json +10 -0
  30. package/config/skills/agent/xiaoyuzhoufm-transcript/SKILL.md +85 -0
  31. package/config/skills/agent/xiaoyuzhoufm-transcript/execute.sh +306 -0
  32. package/config/skills/agent/xiaoyuzhoufm-transcript/skill.json +10 -0
  33. package/config/skills/orchestrator/cancel-cron/SKILL.md +44 -0
  34. package/config/skills/orchestrator/create-cron/SKILL.md +58 -0
  35. package/config/skills/orchestrator/list-cron/SKILL.md +51 -0
  36. package/config/skills/orchestrator/update-cron/SKILL.md +52 -0
  37. package/dist/backend/backend/src/constants.d.ts +7 -4
  38. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  39. package/dist/backend/backend/src/constants.js +6 -3
  40. package/dist/backend/backend/src/constants.js.map +1 -1
  41. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +21 -2
  42. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  43. package/dist/backend/backend/src/controllers/browser/browser.controller.js +167 -29
  44. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  45. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts +1 -1
  46. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  47. package/dist/backend/backend/src/controllers/browser/browser.routes.js +7 -3
  48. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  49. package/dist/backend/backend/src/controllers/data/data.controller.d.ts +47 -0
  50. package/dist/backend/backend/src/controllers/data/data.controller.d.ts.map +1 -0
  51. package/dist/backend/backend/src/controllers/data/data.controller.js +201 -0
  52. package/dist/backend/backend/src/controllers/data/data.controller.js.map +1 -0
  53. package/dist/backend/backend/src/controllers/data/data.routes.d.ts +18 -0
  54. package/dist/backend/backend/src/controllers/data/data.routes.d.ts.map +1 -0
  55. package/dist/backend/backend/src/controllers/data/data.routes.js +44 -0
  56. package/dist/backend/backend/src/controllers/data/data.routes.js.map +1 -0
  57. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts +3 -2
  58. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts.map +1 -1
  59. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js +5 -3
  60. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js.map +1 -1
  61. package/dist/backend/backend/src/controllers/system/cron-task.controller.d.ts +4 -0
  62. package/dist/backend/backend/src/controllers/system/cron-task.controller.d.ts.map +1 -1
  63. package/dist/backend/backend/src/controllers/system/cron-task.controller.js +20 -0
  64. package/dist/backend/backend/src/controllers/system/cron-task.controller.js.map +1 -1
  65. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
  66. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +18 -0
  67. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
  68. package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts +32 -0
  69. package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts.map +1 -0
  70. package/dist/backend/backend/src/controllers/team/team-export.controller.js +61 -0
  71. package/dist/backend/backend/src/controllers/team/team-export.controller.js.map +1 -0
  72. package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
  73. package/dist/backend/backend/src/controllers/team/team.routes.js +7 -0
  74. package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
  75. package/dist/backend/backend/src/index.d.ts.map +1 -1
  76. package/dist/backend/backend/src/index.js +37 -7
  77. package/dist/backend/backend/src/index.js.map +1 -1
  78. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  79. package/dist/backend/backend/src/routes/api.routes.js +4 -1
  80. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  81. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  82. package/dist/backend/backend/src/services/agent/agent-registration.service.js +6 -2
  83. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  84. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/agent/idle-detection.service.js +17 -2
  86. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  87. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +1 -1
  88. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +2 -2
  89. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  90. package/dist/backend/backend/src/services/agent/task-planning.service.d.ts +134 -0
  91. package/dist/backend/backend/src/services/agent/task-planning.service.d.ts.map +1 -0
  92. package/dist/backend/backend/src/services/agent/task-planning.service.js +291 -0
  93. package/dist/backend/backend/src/services/agent/task-planning.service.js.map +1 -0
  94. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +11 -0
  95. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
  96. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +47 -18
  97. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  98. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts +14 -0
  99. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  100. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +47 -4
  101. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  102. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +13 -9
  103. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  104. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +44 -12
  105. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  106. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +176 -0
  107. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -0
  108. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +441 -0
  109. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -0
  110. package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts +162 -0
  111. package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts.map +1 -0
  112. package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js +350 -0
  113. package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js.map +1 -0
  114. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +8 -0
  115. package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
  116. package/dist/backend/backend/src/services/cloud/cloud-initializer.js +27 -0
  117. package/dist/backend/backend/src/services/cloud/cloud-initializer.js.map +1 -1
  118. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
  119. package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +2 -0
  121. package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
  122. package/dist/backend/backend/src/services/core/team-export.service.d.ts +103 -0
  123. package/dist/backend/backend/src/services/core/team-export.service.d.ts.map +1 -0
  124. package/dist/backend/backend/src/services/core/team-export.service.js +182 -0
  125. package/dist/backend/backend/src/services/core/team-export.service.js.map +1 -0
  126. package/dist/backend/backend/src/services/data/data-object-store.service.d.ts +160 -0
  127. package/dist/backend/backend/src/services/data/data-object-store.service.d.ts.map +1 -0
  128. package/dist/backend/backend/src/services/data/data-object-store.service.js +434 -0
  129. package/dist/backend/backend/src/services/data/data-object-store.service.js.map +1 -0
  130. package/dist/backend/backend/src/services/data/data-object.types.d.ts +190 -0
  131. package/dist/backend/backend/src/services/data/data-object.types.d.ts.map +1 -0
  132. package/dist/backend/backend/src/services/data/data-object.types.js +143 -0
  133. package/dist/backend/backend/src/services/data/data-object.types.js.map +1 -0
  134. package/dist/backend/backend/src/services/data/schema-registry.service.d.ts +108 -0
  135. package/dist/backend/backend/src/services/data/schema-registry.service.d.ts.map +1 -0
  136. package/dist/backend/backend/src/services/data/schema-registry.service.js +290 -0
  137. package/dist/backend/backend/src/services/data/schema-registry.service.js.map +1 -0
  138. package/dist/backend/backend/src/services/data/sink-registry.service.d.ts +87 -0
  139. package/dist/backend/backend/src/services/data/sink-registry.service.d.ts.map +1 -0
  140. package/dist/backend/backend/src/services/data/sink-registry.service.js +188 -0
  141. package/dist/backend/backend/src/services/data/sink-registry.service.js.map +1 -0
  142. package/dist/backend/backend/src/services/messaging/message-router.service.d.ts.map +1 -1
  143. package/dist/backend/backend/src/services/messaging/message-router.service.js +7 -0
  144. package/dist/backend/backend/src/services/messaging/message-router.service.js.map +1 -1
  145. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +55 -2
  146. package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
  147. package/dist/backend/backend/src/services/monitoring/token-usage.service.js +89 -5
  148. package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
  149. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +1 -1
  150. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
  151. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts +105 -14
  152. package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
  153. package/dist/backend/backend/src/services/workflow/cron-task.service.js +400 -123
  154. package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
  155. package/dist/backend/backend/src/types/cron-task.types.d.ts +1 -1
  156. package/dist/backend/backend/src/types/data-object.types.d.ts +117 -0
  157. package/dist/backend/backend/src/types/data-object.types.d.ts.map +1 -0
  158. package/dist/backend/backend/src/types/data-object.types.js +23 -0
  159. package/dist/backend/backend/src/types/data-object.types.js.map +1 -0
  160. package/dist/backend/backend/src/types/settings.types.js +1 -1
  161. package/dist/backend/config/constants.d.ts +3 -3
  162. package/dist/backend/config/constants.js +3 -3
  163. package/dist/backend/config/constants.js.map +1 -1
  164. package/dist/cli/backend/src/constants.d.ts +7 -4
  165. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  166. package/dist/cli/backend/src/constants.js +6 -3
  167. package/dist/cli/backend/src/constants.js.map +1 -1
  168. package/dist/cli/backend/src/types/settings.types.js +1 -1
  169. package/dist/cli/config/constants.d.ts +3 -3
  170. package/dist/cli/config/constants.js +3 -3
  171. package/dist/cli/config/constants.js.map +1 -1
  172. package/frontend/dist/assets/index-371b68d4.css +33 -0
  173. package/frontend/dist/assets/{index-9af2ea40.js → index-506f70da.js} +321 -321
  174. package/frontend/dist/index.html +2 -2
  175. package/package.json +1 -1
  176. package/frontend/dist/assets/index-b19b2478.css +0 -33
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Team Export/Import Service
3
+ *
4
+ * Bundles a team's config, prompts, norms, and cron tasks into a single
5
+ * exportable JSON document. Supports importing from that format to create
6
+ * a complete team with all associated data.
7
+ *
8
+ * Part of the team-scoped cron feature (Phase 3).
9
+ *
10
+ * @module services/core/team-export.service
11
+ */
12
+ import fs from 'fs/promises';
13
+ import { existsSync, mkdirSync } from 'fs';
14
+ import * as path from 'path';
15
+ import * as crypto from 'crypto';
16
+ // =============================================================================
17
+ // Service
18
+ // =============================================================================
19
+ /**
20
+ * Service for exporting and importing complete team bundles.
21
+ *
22
+ * Export collects: config.json + prompts/*.md + norms/*.md + cron-tasks.json
23
+ * Import creates: team directory + prompts + norms + cron tasks with new IDs
24
+ */
25
+ export class TeamExportService {
26
+ storageService;
27
+ /**
28
+ * Create a new TeamExportService.
29
+ *
30
+ * @param storageService - StorageService for team data access
31
+ */
32
+ constructor(storageService) {
33
+ this.storageService = storageService;
34
+ }
35
+ /**
36
+ * Export a team and all its associated data as a single JSON bundle.
37
+ *
38
+ * Collects:
39
+ * - Team config (config.json)
40
+ * - Member prompts (prompts/*.md)
41
+ * - Norms/SOPs (norms/*.md)
42
+ * - Cron tasks (cron-tasks.json)
43
+ *
44
+ * @param teamId - ID of the team to export
45
+ * @returns Complete team export bundle
46
+ * @throws Error if team not found
47
+ */
48
+ async exportTeam(teamId) {
49
+ const teams = await this.storageService.getTeams();
50
+ const team = teams.find((t) => t.id === teamId);
51
+ if (!team) {
52
+ throw new Error(`Team not found: ${teamId}`);
53
+ }
54
+ const teamDir = this.storageService.getTeamDir(teamId);
55
+ // Read prompts
56
+ const prompts = {};
57
+ const promptsDir = path.join(teamDir, 'prompts');
58
+ if (existsSync(promptsDir)) {
59
+ try {
60
+ const files = await fs.readdir(promptsDir);
61
+ for (const file of files) {
62
+ if (file.endsWith('.md')) {
63
+ const memberId = file.replace('.md', '');
64
+ prompts[memberId] = await fs.readFile(path.join(promptsDir, file), 'utf8');
65
+ }
66
+ }
67
+ }
68
+ catch {
69
+ // prompts dir doesn't exist or unreadable — skip
70
+ }
71
+ }
72
+ // Read norms
73
+ const norms = {};
74
+ const normsDir = path.join(teamDir, 'norms');
75
+ if (existsSync(normsDir)) {
76
+ try {
77
+ const files = await fs.readdir(normsDir);
78
+ for (const file of files) {
79
+ norms[file] = await fs.readFile(path.join(normsDir, file), 'utf8');
80
+ }
81
+ }
82
+ catch {
83
+ // norms dir doesn't exist or unreadable — skip
84
+ }
85
+ }
86
+ // Read cron tasks
87
+ const cronTasks = await this.readCronTasks(teamDir);
88
+ return {
89
+ version: '1.0',
90
+ exportedAt: new Date().toISOString(),
91
+ team,
92
+ prompts,
93
+ norms,
94
+ cronTasks,
95
+ };
96
+ }
97
+ /**
98
+ * Import a team from a complete export bundle.
99
+ *
100
+ * Creates:
101
+ * - Team via storageService.saveTeam()
102
+ * - Prompts written to teams/{teamId}/prompts/
103
+ * - Norms written to teams/{teamId}/norms/
104
+ * - Cron tasks with NEW IDs to teams/{teamId}/cron-tasks.json
105
+ *
106
+ * @param data - The team export bundle to import
107
+ * @returns Import result with counts
108
+ * @throws Error if import data is invalid
109
+ */
110
+ async importTeam(data) {
111
+ if (!data.version || !data.team) {
112
+ throw new Error('Invalid team export format: missing version or team data');
113
+ }
114
+ // Save the team config
115
+ const team = data.team;
116
+ await this.storageService.saveTeam(team);
117
+ const teamDir = this.storageService.getTeamDir(team.id);
118
+ // Write prompts
119
+ let promptsImported = 0;
120
+ if (data.prompts && Object.keys(data.prompts).length > 0) {
121
+ for (const [memberId, content] of Object.entries(data.prompts)) {
122
+ await this.storageService.saveMemberPrompt(team.id, memberId, content);
123
+ promptsImported++;
124
+ }
125
+ }
126
+ // Write norms
127
+ let normsImported = 0;
128
+ if (data.norms && Object.keys(data.norms).length > 0) {
129
+ const normsDir = path.join(teamDir, 'norms');
130
+ mkdirSync(normsDir, { recursive: true });
131
+ for (const [filename, content] of Object.entries(data.norms)) {
132
+ await fs.writeFile(path.join(normsDir, filename), content, 'utf8');
133
+ normsImported++;
134
+ }
135
+ }
136
+ // Write cron tasks with new IDs and remapped targetTeamId
137
+ let cronTasksImported = 0;
138
+ if (data.cronTasks && data.cronTasks.length > 0) {
139
+ const remapped = data.cronTasks.map((task) => ({
140
+ ...task,
141
+ id: generateCronId(),
142
+ targetTeamId: team.id,
143
+ }));
144
+ const cronStore = { tasks: remapped };
145
+ const cronPath = path.join(teamDir, 'cron-tasks.json');
146
+ await fs.writeFile(cronPath, JSON.stringify(cronStore, null, 2), 'utf8');
147
+ cronTasksImported = remapped.length;
148
+ }
149
+ return {
150
+ team,
151
+ promptsImported,
152
+ normsImported,
153
+ cronTasksImported,
154
+ };
155
+ }
156
+ /**
157
+ * Read cron tasks from a team directory.
158
+ *
159
+ * @param teamDir - Path to the team directory
160
+ * @returns Array of cron tasks, empty if file doesn't exist
161
+ */
162
+ async readCronTasks(teamDir) {
163
+ const cronPath = path.join(teamDir, 'cron-tasks.json');
164
+ try {
165
+ const raw = await fs.readFile(cronPath, 'utf8');
166
+ const store = JSON.parse(raw);
167
+ return store.tasks ?? [];
168
+ }
169
+ catch {
170
+ return [];
171
+ }
172
+ }
173
+ }
174
+ /**
175
+ * Generate a unique cron task ID.
176
+ *
177
+ * @returns ID in format "cron-xxxxxxxx"
178
+ */
179
+ export function generateCronId() {
180
+ return `cron-${crypto.randomUUID().slice(0, 8)}`;
181
+ }
182
+ //# sourceMappingURL=team-export.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-export.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/core/team-export.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * DataObjectStore — file-based CRUD service for the Unified DataObject Model.
3
+ *
4
+ * Persists DataObjects as individual JSON files organised by namespace:
5
+ * - scope=agent → `{projectPath}/.crewly/agents/{owner_id}/data/{id}.json`
6
+ * - scope=project → `{projectPath}/.crewly/data/{namespace}/{id}.json`
7
+ * - scope=global → `~/.crewly/data/{namespace}/{id}.json`
8
+ *
9
+ * @see specs/crewly-data-architecture-v2.md
10
+ */
11
+ import { DataObject, CreateDataObjectInput, DataObjectFilters } from './data-object.types.js';
12
+ /**
13
+ * File-based CRUD store for DataObjects.
14
+ *
15
+ * Uses a singleton pattern consistent with other Crewly services.
16
+ * Each DataObject is stored as a separate JSON file so that
17
+ * concurrent agents can write without lock contention.
18
+ */
19
+ export declare class DataObjectStore {
20
+ private static instance;
21
+ private static instanceProjectPath;
22
+ private projectPath;
23
+ private logger;
24
+ /**
25
+ * @param projectPath - Absolute path to the Crewly project root.
26
+ * Used to resolve scope-based storage directories.
27
+ */
28
+ constructor(projectPath: string);
29
+ /**
30
+ * Returns the singleton DataObjectStore instance.
31
+ *
32
+ * If `projectPath` differs from the current instance, a new one is created.
33
+ *
34
+ * @param projectPath - Absolute path to the Crewly project root
35
+ * @returns Singleton DataObjectStore
36
+ */
37
+ static getInstance(projectPath: string): DataObjectStore;
38
+ /**
39
+ * Clears the singleton (useful for tests).
40
+ */
41
+ static clearInstance(): void;
42
+ /**
43
+ * Creates a new DataObject, persists it to disk, and returns it.
44
+ *
45
+ * Generates a UUID, sets timestamps, and applies sensible defaults.
46
+ *
47
+ * @param input - Fields for the new DataObject
48
+ * @returns The persisted DataObject
49
+ */
50
+ create(input: CreateDataObjectInput): Promise<DataObject>;
51
+ /**
52
+ * Retrieves a DataObject by its ID.
53
+ *
54
+ * Scans all namespace directories because the caller may not know
55
+ * the namespace. For hot-path lookups, prefer `listByNamespace`.
56
+ *
57
+ * @param id - UUID of the DataObject
58
+ * @returns The DataObject, or null if not found
59
+ */
60
+ getById(id: string): Promise<DataObject | null>;
61
+ /**
62
+ * Lists DataObjects matching the supplied filters.
63
+ *
64
+ * @param filters - Optional field constraints
65
+ * @returns Array of matching DataObjects
66
+ */
67
+ list(filters?: DataObjectFilters): Promise<DataObject[]>;
68
+ /**
69
+ * Applies a partial update to an existing DataObject.
70
+ *
71
+ * Only the fields present in `patch` are overwritten; the rest
72
+ * are preserved. `metadata.updated_at` is always refreshed.
73
+ *
74
+ * @param id - UUID of the DataObject to update
75
+ * @param patch - Fields to overwrite
76
+ * @returns The updated DataObject
77
+ * @throws Error if the DataObject does not exist
78
+ */
79
+ update(id: string, patch: Partial<DataObject>): Promise<DataObject>;
80
+ /**
81
+ * Deletes a DataObject by ID.
82
+ *
83
+ * @param id - UUID of the DataObject to delete
84
+ * @returns true if the object existed and was deleted, false otherwise
85
+ */
86
+ delete(id: string): Promise<boolean>;
87
+ /**
88
+ * Lists all DataObjects within a given namespace.
89
+ *
90
+ * @param namespace - The namespace to scan, e.g. "marketing/steve-inputs"
91
+ * @returns Array of DataObjects in that namespace
92
+ */
93
+ listByNamespace(namespace: string): Promise<DataObject[]>;
94
+ /**
95
+ * Resolves the absolute file path for a DataObject based on its scope.
96
+ *
97
+ * @param obj - The DataObject (or partial with scope, namespace, owner_id, id)
98
+ * @returns Absolute path to the JSON file
99
+ */
100
+ private filePath;
101
+ /**
102
+ * Persists a DataObject to its resolved file path using atomic writes.
103
+ */
104
+ private persist;
105
+ /**
106
+ * Safely deletes a file, ignoring ENOENT errors.
107
+ */
108
+ private safeDelete;
109
+ /**
110
+ * Lists entries in a directory, returning empty array if it doesn't exist.
111
+ */
112
+ private safeReaddir;
113
+ /**
114
+ * Checks if a directory exists.
115
+ */
116
+ private dirExists;
117
+ /**
118
+ * Reads all DataObject JSON files from a single directory.
119
+ */
120
+ private readAllFromDir;
121
+ /**
122
+ * Recursively reads all DataObject JSON files from a directory tree
123
+ * up to a configurable depth. Handles both shallow (data/{ns}/)
124
+ * and deep (agents/{owner}/data/) hierarchies.
125
+ *
126
+ * @param dir - Root directory to scan
127
+ * @param maxDepth - Maximum directory depth to descend (default 3)
128
+ */
129
+ private readAllRecursive;
130
+ /**
131
+ * Reads all DataObjects from a base directory tree.
132
+ */
133
+ private readAllFromBase;
134
+ /**
135
+ * Searches for a specific ID within a base directory tree (recursive).
136
+ */
137
+ private findInBase;
138
+ /**
139
+ * Recursively searches for a DataObject by ID in a directory tree.
140
+ */
141
+ private findInDir;
142
+ /**
143
+ * Tries to read and parse a single DataObject JSON file.
144
+ * Returns null on any failure.
145
+ */
146
+ private tryReadFile;
147
+ /**
148
+ * Returns all possible base directories to scan.
149
+ */
150
+ private allBaseDirs;
151
+ /**
152
+ * Narrows base directories based on scope filter, if provided.
153
+ */
154
+ private baseDirsForFilters;
155
+ /**
156
+ * Tests whether a DataObject matches all non-undefined filter fields.
157
+ */
158
+ private matchesFilters;
159
+ }
160
+ //# sourceMappingURL=data-object-store.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-object-store.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/data/data-object-store.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgC;IACvD,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAuB;IAEzD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAkB;IAEhC;;;OAGG;gBACS,WAAW,EAAE,MAAM;IAU/B;;;;;;;OAOG;WACW,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe;IAY/D;;OAEG;WACW,aAAa,IAAI,IAAI;IASnC;;;;;;;OAOG;IACG,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;IA2B/D;;;;;;;;OAQG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAUrD;;;;;OAKG;IACG,IAAI,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAgBlE;;;;;;;;;;OAUG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IA6BzE;;;;;OAKG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAa1C;;;;;OAKG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAkC/D;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAoChB;;OAEG;YACW,OAAO;IAMrB;;OAEG;YACW,UAAU;IAQxB;;OAEG;YACW,WAAW;IAQzB;;OAEG;YACW,SAAS;IASvB;;OAEG;YACW,cAAc;IAuB5B;;;;;;;OAOG;YACW,gBAAgB;IAmB9B;;OAEG;YACW,eAAe;IAI7B;;OAEG;YACW,UAAU;IAIxB;;OAEG;YACW,SAAS;IAqBvB;;;OAGG;YACW,WAAW;IAUzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,cAAc;CAYvB"}