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.
- package/config/constants.ts +3 -3
- package/config/orchestrator_tasks/prompts/orchestrator-prompt.md +73 -0
- package/config/roles/architect/prompt.md +9 -0
- package/config/roles/backend-developer/prompt.md +9 -0
- package/config/roles/content-strategist/prompt.md +10 -0
- package/config/roles/designer/prompt.md +9 -0
- package/config/roles/developer/prompt.md +9 -0
- package/config/roles/frontend-developer/prompt.md +9 -0
- package/config/roles/fullstack-dev/prompt.md +9 -0
- package/config/roles/generalist/prompt.md +9 -0
- package/config/roles/ops/prompt.md +9 -0
- package/config/roles/product-manager/prompt.md +9 -0
- package/config/roles/qa/prompt.md +9 -0
- package/config/roles/qa-engineer/prompt.md +9 -0
- package/config/roles/researcher/prompt.md +9 -0
- package/config/roles/sales/prompt.md +9 -0
- package/config/roles/support/prompt.md +9 -0
- package/config/roles/team-leader/prompt.md +11 -0
- package/config/roles/tpm/prompt.md +9 -0
- package/config/roles/ux-designer/prompt.md +9 -0
- package/config/skills/_common/lib.sh +31 -0
- package/config/skills/_common/lib.test.sh +164 -0
- package/config/skills/agent/core/block-task/execute.sh +3 -1
- package/config/skills/agent/core/pipe-to-sink/execute.sh +41 -0
- package/config/skills/agent/core/read-task/execute.sh +3 -1
- package/config/skills/agent/core/report-progress/execute.sh +3 -1
- package/config/skills/agent/screenshot-compare/SKILL.md +75 -0
- package/config/skills/agent/screenshot-compare/execute.sh +182 -0
- package/config/skills/agent/screenshot-compare/skill.json +10 -0
- package/config/skills/agent/xiaoyuzhoufm-transcript/SKILL.md +85 -0
- package/config/skills/agent/xiaoyuzhoufm-transcript/execute.sh +306 -0
- package/config/skills/agent/xiaoyuzhoufm-transcript/skill.json +10 -0
- package/config/skills/orchestrator/cancel-cron/SKILL.md +44 -0
- package/config/skills/orchestrator/create-cron/SKILL.md +58 -0
- package/config/skills/orchestrator/list-cron/SKILL.md +51 -0
- package/config/skills/orchestrator/update-cron/SKILL.md +52 -0
- package/dist/backend/backend/src/constants.d.ts +7 -4
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +6 -3
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +21 -2
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.js +167 -29
- package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.routes.js +7 -3
- package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/data/data.controller.d.ts +47 -0
- package/dist/backend/backend/src/controllers/data/data.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/data/data.controller.js +201 -0
- package/dist/backend/backend/src/controllers/data/data.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/data/data.routes.d.ts +18 -0
- package/dist/backend/backend/src/controllers/data/data.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/data/data.routes.js +44 -0
- package/dist/backend/backend/src/controllers/data/data.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts +3 -2
- package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js +5 -3
- package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/cron-task.controller.d.ts +4 -0
- package/dist/backend/backend/src/controllers/system/cron-task.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/cron-task.controller.js +20 -0
- package/dist/backend/backend/src/controllers/system/cron-task.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +18 -0
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts +32 -0
- package/dist/backend/backend/src/controllers/team/team-export.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team/team-export.controller.js +61 -0
- package/dist/backend/backend/src/controllers/team/team-export.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +7 -0
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +37 -7
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +4 -1
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +6 -2
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/idle-detection.service.js +17 -2
- package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +2 -2
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/agent/task-planning.service.d.ts +134 -0
- package/dist/backend/backend/src/services/agent/task-planning.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/task-planning.service.js +291 -0
- package/dist/backend/backend/src/services/agent/task-planning.service.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +11 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +47 -18
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts +14 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +47 -4
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +13 -9
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js +44 -12
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +176 -0
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js +441 -0
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -0
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts +162 -0
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js +350 -0
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts +8 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-initializer.js +27 -0
- package/dist/backend/backend/src/services/cloud/cloud-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +2 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/core/team-export.service.d.ts +103 -0
- package/dist/backend/backend/src/services/core/team-export.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/core/team-export.service.js +182 -0
- package/dist/backend/backend/src/services/core/team-export.service.js.map +1 -0
- package/dist/backend/backend/src/services/data/data-object-store.service.d.ts +160 -0
- package/dist/backend/backend/src/services/data/data-object-store.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/data/data-object-store.service.js +434 -0
- package/dist/backend/backend/src/services/data/data-object-store.service.js.map +1 -0
- package/dist/backend/backend/src/services/data/data-object.types.d.ts +190 -0
- package/dist/backend/backend/src/services/data/data-object.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/data/data-object.types.js +143 -0
- package/dist/backend/backend/src/services/data/data-object.types.js.map +1 -0
- package/dist/backend/backend/src/services/data/schema-registry.service.d.ts +108 -0
- package/dist/backend/backend/src/services/data/schema-registry.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/data/schema-registry.service.js +290 -0
- package/dist/backend/backend/src/services/data/schema-registry.service.js.map +1 -0
- package/dist/backend/backend/src/services/data/sink-registry.service.d.ts +87 -0
- package/dist/backend/backend/src/services/data/sink-registry.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/data/sink-registry.service.js +188 -0
- package/dist/backend/backend/src/services/data/sink-registry.service.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/message-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/message-router.service.js +7 -0
- package/dist/backend/backend/src/services/messaging/message-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +55 -2
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js +89 -5
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts +105 -14
- package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/cron-task.service.js +400 -123
- package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
- package/dist/backend/backend/src/types/cron-task.types.d.ts +1 -1
- package/dist/backend/backend/src/types/data-object.types.d.ts +117 -0
- package/dist/backend/backend/src/types/data-object.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/data-object.types.js +23 -0
- package/dist/backend/backend/src/types/data-object.types.js.map +1 -0
- package/dist/backend/backend/src/types/settings.types.js +1 -1
- package/dist/backend/config/constants.d.ts +3 -3
- package/dist/backend/config/constants.js +3 -3
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +7 -4
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +6 -3
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/types/settings.types.js +1 -1
- package/dist/cli/config/constants.d.ts +3 -3
- package/dist/cli/config/constants.js +3 -3
- package/dist/cli/config/constants.js.map +1 -1
- package/frontend/dist/assets/index-371b68d4.css +33 -0
- package/frontend/dist/assets/{index-9af2ea40.js → index-506f70da.js} +321 -321
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- 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"}
|