@claudetools/tools 0.1.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.
- package/README.md +86 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +61 -0
- package/dist/handlers/tool-handlers.d.ts +2 -0
- package/dist/handlers/tool-handlers.js +1108 -0
- package/dist/helpers/api-client.d.ts +50 -0
- package/dist/helpers/api-client.js +60 -0
- package/dist/helpers/config-manager.d.ts +68 -0
- package/dist/helpers/config-manager.js +306 -0
- package/dist/helpers/config.d.ts +55 -0
- package/dist/helpers/config.js +174 -0
- package/dist/helpers/dependencies.d.ts +30 -0
- package/dist/helpers/dependencies.js +87 -0
- package/dist/helpers/formatter.d.ts +2 -0
- package/dist/helpers/formatter.js +24 -0
- package/dist/helpers/patterns.d.ts +15 -0
- package/dist/helpers/patterns.js +118 -0
- package/dist/helpers/project-registration.d.ts +27 -0
- package/dist/helpers/project-registration.js +338 -0
- package/dist/helpers/tasks.d.ts +152 -0
- package/dist/helpers/tasks.js +274 -0
- package/dist/helpers/workers.d.ts +18 -0
- package/dist/helpers/workers.js +146 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +75 -0
- package/dist/logger.d.ts +32 -0
- package/dist/logger.js +401 -0
- package/dist/prompts.d.ts +2 -0
- package/dist/prompts.js +64 -0
- package/dist/resources.d.ts +2 -0
- package/dist/resources.js +79 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +206 -0
- package/dist/tools.d.ts +2 -0
- package/dist/tools.js +748 -0
- package/package.json +58 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Auto Project Registration System
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Automatically registers projects with the ClaudeTools API when used in
|
|
5
|
+
// unregistered directories. Caches project bindings locally for fast lookups.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
import { mcpLogger } from '../logger.js';
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as os from 'os';
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
import { API_BASE_URL, PROJECTS_FILE, CLAUDETOOLS_DIR } from './config.js';
|
|
13
|
+
import { getConfig } from './config-manager.js';
|
|
14
|
+
// -----------------------------------------------------------------------------
|
|
15
|
+
// System Registration
|
|
16
|
+
// -----------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Get unique system identifier (hostname)
|
|
19
|
+
*/
|
|
20
|
+
function getSystemInfo() {
|
|
21
|
+
return {
|
|
22
|
+
hostname: os.hostname(),
|
|
23
|
+
platform: os.platform(),
|
|
24
|
+
username: os.userInfo().username,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get or register this machine as a system
|
|
29
|
+
* Returns system_id for binding projects
|
|
30
|
+
*/
|
|
31
|
+
async function ensureSystemRegistered() {
|
|
32
|
+
const cache = loadProjectsCache();
|
|
33
|
+
// Check if we already have a system_id cached
|
|
34
|
+
if (cache.system_id) {
|
|
35
|
+
mcpLogger.debug('REGISTRATION', `Using cached system ID: ${cache.system_id}`);
|
|
36
|
+
return cache.system_id;
|
|
37
|
+
}
|
|
38
|
+
// Register this system
|
|
39
|
+
const systemInfo = getSystemInfo();
|
|
40
|
+
mcpLogger.info('REGISTRATION', `Registering new system: ${systemInfo.hostname}`);
|
|
41
|
+
try {
|
|
42
|
+
const config = getConfig();
|
|
43
|
+
const apiKey = config.apiKey || process.env.MEMORY_API_KEY || process.env.CLAUDETOOLS_API_KEY;
|
|
44
|
+
if (!apiKey) {
|
|
45
|
+
throw new Error('No API key found. Set CLAUDETOOLS_API_KEY or MEMORY_API_KEY in environment, ' +
|
|
46
|
+
'or configure via ~/.claudetools/config.json');
|
|
47
|
+
}
|
|
48
|
+
const response = await fetch(`${API_BASE_URL}/api/v1/systems/register`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: {
|
|
51
|
+
'Content-Type': 'application/json',
|
|
52
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify({
|
|
55
|
+
hostname: systemInfo.hostname,
|
|
56
|
+
platform: systemInfo.platform,
|
|
57
|
+
username: systemInfo.username,
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const error = await response.text();
|
|
62
|
+
throw new Error(`System registration failed: ${response.status} ${error}`);
|
|
63
|
+
}
|
|
64
|
+
const result = await response.json();
|
|
65
|
+
const systemId = result.data?.system_id || result.system_id;
|
|
66
|
+
if (!systemId) {
|
|
67
|
+
throw new Error('System registration did not return a system_id');
|
|
68
|
+
}
|
|
69
|
+
mcpLogger.info('REGISTRATION', `System registered successfully: ${systemId}`);
|
|
70
|
+
// Cache the system_id
|
|
71
|
+
cache.system_id = systemId;
|
|
72
|
+
saveProjectsCache(cache);
|
|
73
|
+
return systemId;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
mcpLogger.error('REGISTRATION', `System registration failed: ${error}`);
|
|
77
|
+
throw new Error(`Failed to register system: ${error}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// -----------------------------------------------------------------------------
|
|
81
|
+
// Git Detection
|
|
82
|
+
// -----------------------------------------------------------------------------
|
|
83
|
+
/**
|
|
84
|
+
* Try to detect git remote for a directory
|
|
85
|
+
*/
|
|
86
|
+
function detectGitRemote(localPath) {
|
|
87
|
+
try {
|
|
88
|
+
const gitRemote = execSync('git config --get remote.origin.url', {
|
|
89
|
+
cwd: localPath,
|
|
90
|
+
encoding: 'utf-8',
|
|
91
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
92
|
+
}).trim();
|
|
93
|
+
return gitRemote || undefined;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Not a git repo or no remote configured
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// -----------------------------------------------------------------------------
|
|
101
|
+
// Project Registration
|
|
102
|
+
// -----------------------------------------------------------------------------
|
|
103
|
+
/**
|
|
104
|
+
* Register a new project via API
|
|
105
|
+
*/
|
|
106
|
+
async function registerProject(localPath) {
|
|
107
|
+
const systemId = await ensureSystemRegistered();
|
|
108
|
+
const projectName = path.basename(localPath);
|
|
109
|
+
const gitRemote = detectGitRemote(localPath);
|
|
110
|
+
mcpLogger.info('REGISTRATION', `Registering new project: ${projectName} at ${localPath}`);
|
|
111
|
+
try {
|
|
112
|
+
const config = getConfig();
|
|
113
|
+
const apiKey = config.apiKey || process.env.MEMORY_API_KEY || process.env.CLAUDETOOLS_API_KEY;
|
|
114
|
+
if (!apiKey) {
|
|
115
|
+
throw new Error('No API key found. Set CLAUDETOOLS_API_KEY or MEMORY_API_KEY in environment, ' +
|
|
116
|
+
'or configure via ~/.claudetools/config.json');
|
|
117
|
+
}
|
|
118
|
+
// Step 1: Create project
|
|
119
|
+
const projectResponse = await fetch(`${API_BASE_URL}/api/v1/projects`, {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: {
|
|
122
|
+
'Content-Type': 'application/json',
|
|
123
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
124
|
+
},
|
|
125
|
+
body: JSON.stringify({
|
|
126
|
+
name: projectName,
|
|
127
|
+
description: `Auto-registered project from ${localPath}`,
|
|
128
|
+
git_remote: gitRemote,
|
|
129
|
+
}),
|
|
130
|
+
});
|
|
131
|
+
if (!projectResponse.ok) {
|
|
132
|
+
const error = await projectResponse.text();
|
|
133
|
+
throw new Error(`Project creation failed: ${projectResponse.status} ${error}`);
|
|
134
|
+
}
|
|
135
|
+
const projectResult = await projectResponse.json();
|
|
136
|
+
const projectId = projectResult.data?.project_id || projectResult.project_id;
|
|
137
|
+
const orgId = projectResult.data?.org_id || projectResult.org_id || 'default';
|
|
138
|
+
if (!projectId) {
|
|
139
|
+
throw new Error('Project creation did not return a project_id');
|
|
140
|
+
}
|
|
141
|
+
mcpLogger.info('REGISTRATION', `Project created: ${projectId}`);
|
|
142
|
+
// Step 2: Create binding (link project to local path on this system)
|
|
143
|
+
const bindingResponse = await fetch(`${API_BASE_URL}/api/v1/systems/${systemId}/bindings`, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: {
|
|
146
|
+
'Content-Type': 'application/json',
|
|
147
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
project_id: projectId,
|
|
151
|
+
local_path: localPath,
|
|
152
|
+
git_remote: gitRemote,
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
if (!bindingResponse.ok) {
|
|
156
|
+
const error = await bindingResponse.text();
|
|
157
|
+
throw new Error(`Binding creation failed: ${bindingResponse.status} ${error}`);
|
|
158
|
+
}
|
|
159
|
+
const bindingResult = await bindingResponse.json();
|
|
160
|
+
const bindingId = bindingResult.data?.binding_id || bindingResult.binding_id;
|
|
161
|
+
if (!bindingId) {
|
|
162
|
+
throw new Error('Binding creation did not return a binding_id');
|
|
163
|
+
}
|
|
164
|
+
mcpLogger.info('REGISTRATION', `Binding created: ${bindingId}`);
|
|
165
|
+
const binding = {
|
|
166
|
+
binding_id: bindingId,
|
|
167
|
+
project_id: projectId,
|
|
168
|
+
system_id: systemId,
|
|
169
|
+
local_path: localPath,
|
|
170
|
+
git_remote: gitRemote,
|
|
171
|
+
project_name: projectName,
|
|
172
|
+
org_id: orgId,
|
|
173
|
+
cached_at: new Date().toISOString(),
|
|
174
|
+
};
|
|
175
|
+
// Update local cache
|
|
176
|
+
updateProjectsCache(binding);
|
|
177
|
+
mcpLogger.info('REGISTRATION', `Successfully registered project: ${projectName} → ${projectId}`);
|
|
178
|
+
// Also cache the system_id at top level for future use
|
|
179
|
+
const cache = loadProjectsCache();
|
|
180
|
+
if (!cache.system_id) {
|
|
181
|
+
cache.system_id = systemId;
|
|
182
|
+
saveProjectsCache(cache);
|
|
183
|
+
}
|
|
184
|
+
return binding;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
mcpLogger.error('REGISTRATION', `Project registration failed: ${error}`);
|
|
188
|
+
throw new Error(`Failed to register project: ${error}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// -----------------------------------------------------------------------------
|
|
192
|
+
// Cache Management
|
|
193
|
+
// -----------------------------------------------------------------------------
|
|
194
|
+
/**
|
|
195
|
+
* Load projects cache from disk
|
|
196
|
+
*/
|
|
197
|
+
function loadProjectsCache() {
|
|
198
|
+
try {
|
|
199
|
+
// Ensure directory exists
|
|
200
|
+
if (!fs.existsSync(CLAUDETOOLS_DIR)) {
|
|
201
|
+
fs.mkdirSync(CLAUDETOOLS_DIR, { recursive: true });
|
|
202
|
+
}
|
|
203
|
+
if (fs.existsSync(PROJECTS_FILE)) {
|
|
204
|
+
const content = fs.readFileSync(PROJECTS_FILE, 'utf-8');
|
|
205
|
+
const cache = JSON.parse(content);
|
|
206
|
+
// Ensure bindings array exists
|
|
207
|
+
if (!cache.bindings) {
|
|
208
|
+
cache.bindings = [];
|
|
209
|
+
}
|
|
210
|
+
return cache;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
mcpLogger.error('REGISTRATION', `Error loading projects cache: ${error}`);
|
|
215
|
+
}
|
|
216
|
+
// Return empty cache
|
|
217
|
+
return {
|
|
218
|
+
bindings: [],
|
|
219
|
+
last_sync: new Date().toISOString(),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Save projects cache to disk
|
|
224
|
+
*/
|
|
225
|
+
function saveProjectsCache(cache) {
|
|
226
|
+
try {
|
|
227
|
+
// Ensure directory exists
|
|
228
|
+
if (!fs.existsSync(CLAUDETOOLS_DIR)) {
|
|
229
|
+
fs.mkdirSync(CLAUDETOOLS_DIR, { recursive: true });
|
|
230
|
+
}
|
|
231
|
+
cache.last_sync = new Date().toISOString();
|
|
232
|
+
const content = JSON.stringify(cache, null, 2);
|
|
233
|
+
fs.writeFileSync(PROJECTS_FILE, content, 'utf-8');
|
|
234
|
+
mcpLogger.debug('REGISTRATION', `Projects cache saved to ${PROJECTS_FILE}`);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
mcpLogger.error('REGISTRATION', `Error saving projects cache: ${error}`);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Update local cache with new binding
|
|
243
|
+
*/
|
|
244
|
+
function updateProjectsCache(binding) {
|
|
245
|
+
const cache = loadProjectsCache();
|
|
246
|
+
// Remove any existing binding for this path
|
|
247
|
+
cache.bindings = cache.bindings.filter(b => b.local_path !== binding.local_path);
|
|
248
|
+
// Add new binding
|
|
249
|
+
cache.bindings.push(binding);
|
|
250
|
+
saveProjectsCache(cache);
|
|
251
|
+
}
|
|
252
|
+
// -----------------------------------------------------------------------------
|
|
253
|
+
// Main Entry Point
|
|
254
|
+
// -----------------------------------------------------------------------------
|
|
255
|
+
/**
|
|
256
|
+
* Get or register project for a local path
|
|
257
|
+
* This is the main function called by config.ts
|
|
258
|
+
*
|
|
259
|
+
* Returns the project_id (UUID) for the given path
|
|
260
|
+
*/
|
|
261
|
+
export async function getOrRegisterProject(localPath) {
|
|
262
|
+
const config = getConfig();
|
|
263
|
+
// Check if auto-registration is disabled
|
|
264
|
+
if (!config.autoRegister) {
|
|
265
|
+
throw new Error(`No project binding found for ${localPath} and auto-registration is disabled. ` +
|
|
266
|
+
'Enable auto-registration in ~/.claudetools/config.json or manually register this project.');
|
|
267
|
+
}
|
|
268
|
+
mcpLogger.debug('REGISTRATION', `Looking up project for: ${localPath}`);
|
|
269
|
+
// Load cache and check for existing binding
|
|
270
|
+
const cache = loadProjectsCache();
|
|
271
|
+
// Try exact match first
|
|
272
|
+
const exactMatch = cache.bindings.find(b => b.local_path === localPath);
|
|
273
|
+
if (exactMatch) {
|
|
274
|
+
mcpLogger.debug('REGISTRATION', `Found exact match: ${exactMatch.project_id}`);
|
|
275
|
+
return exactMatch.project_id;
|
|
276
|
+
}
|
|
277
|
+
// Try prefix match (for subdirectories)
|
|
278
|
+
const prefixMatches = cache.bindings
|
|
279
|
+
.filter(b => localPath.startsWith(b.local_path + '/') || localPath === b.local_path)
|
|
280
|
+
.sort((a, b) => b.local_path.length - a.local_path.length);
|
|
281
|
+
if (prefixMatches.length > 0) {
|
|
282
|
+
mcpLogger.debug('REGISTRATION', `Found prefix match: ${prefixMatches[0].project_id}`);
|
|
283
|
+
return prefixMatches[0].project_id;
|
|
284
|
+
}
|
|
285
|
+
// No match found - register new project
|
|
286
|
+
mcpLogger.info('REGISTRATION', `No binding found for ${localPath}, registering...`);
|
|
287
|
+
try {
|
|
288
|
+
const binding = await registerProject(localPath);
|
|
289
|
+
return binding.project_id;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
mcpLogger.error('REGISTRATION', `Auto-registration failed: ${error}`);
|
|
293
|
+
throw new Error(`Failed to auto-register project for ${localPath}: ${error}\n\n` +
|
|
294
|
+
'Please check:\n' +
|
|
295
|
+
'1. API key is configured (CLAUDETOOLS_API_KEY or MEMORY_API_KEY)\n' +
|
|
296
|
+
'2. API URL is correct in ~/.claudetools/config.json\n' +
|
|
297
|
+
'3. Network connectivity to ClaudeTools API\n\n' +
|
|
298
|
+
'You can disable auto-registration by setting autoRegister: false in config.');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Sync projects from API (for future use)
|
|
303
|
+
* This would fetch all bindings from the API and update local cache
|
|
304
|
+
*/
|
|
305
|
+
export async function syncProjectsFromAPI() {
|
|
306
|
+
const systemId = await ensureSystemRegistered();
|
|
307
|
+
mcpLogger.info('REGISTRATION', 'Syncing projects from API...');
|
|
308
|
+
try {
|
|
309
|
+
const config = getConfig();
|
|
310
|
+
const apiKey = config.apiKey || process.env.MEMORY_API_KEY || process.env.CLAUDETOOLS_API_KEY;
|
|
311
|
+
if (!apiKey) {
|
|
312
|
+
throw new Error('No API key found for sync operation');
|
|
313
|
+
}
|
|
314
|
+
const response = await fetch(`${API_BASE_URL}/api/v1/systems/${systemId}/bindings`, {
|
|
315
|
+
method: 'GET',
|
|
316
|
+
headers: {
|
|
317
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
if (!response.ok) {
|
|
321
|
+
throw new Error(`Failed to fetch bindings: ${response.status}`);
|
|
322
|
+
}
|
|
323
|
+
const result = await response.json();
|
|
324
|
+
const bindings = result.data?.bindings || result.bindings || [];
|
|
325
|
+
// Update cache
|
|
326
|
+
const cache = loadProjectsCache();
|
|
327
|
+
cache.bindings = bindings.map((b) => ({
|
|
328
|
+
...b,
|
|
329
|
+
cached_at: new Date().toISOString(),
|
|
330
|
+
}));
|
|
331
|
+
saveProjectsCache(cache);
|
|
332
|
+
mcpLogger.info('REGISTRATION', `Synced ${bindings.length} project bindings from API`);
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
mcpLogger.error('REGISTRATION', `Sync failed: ${error}`);
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { ExpertWorker } from './workers.js';
|
|
2
|
+
export interface Task {
|
|
3
|
+
id: string;
|
|
4
|
+
type: 'epic' | 'task' | 'subtask';
|
|
5
|
+
parent_id: string | null;
|
|
6
|
+
user_id: string;
|
|
7
|
+
project_id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description: string;
|
|
10
|
+
acceptance_criteria: string | string[];
|
|
11
|
+
status: string;
|
|
12
|
+
priority: string;
|
|
13
|
+
blocked_by: string | string[];
|
|
14
|
+
agent_type: string | null;
|
|
15
|
+
domain: string | null;
|
|
16
|
+
assigned_to: string | null;
|
|
17
|
+
locked_at: string | null;
|
|
18
|
+
lock_expires_at: string | null;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
completed_at: string | null;
|
|
22
|
+
estimated_effort: string | null;
|
|
23
|
+
tags: string | string[];
|
|
24
|
+
metadata: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
export interface TaskContext {
|
|
27
|
+
id: string;
|
|
28
|
+
task_id: string;
|
|
29
|
+
context_type: string;
|
|
30
|
+
content: string;
|
|
31
|
+
source: string | null;
|
|
32
|
+
added_by: string;
|
|
33
|
+
created_at: string;
|
|
34
|
+
}
|
|
35
|
+
export interface DispatchableTask {
|
|
36
|
+
task: Task;
|
|
37
|
+
worker: ExpertWorker;
|
|
38
|
+
context: TaskContext[];
|
|
39
|
+
parentContext?: Task;
|
|
40
|
+
dependencies?: Task[];
|
|
41
|
+
}
|
|
42
|
+
export declare function parseJsonArray(value: string | string[] | null | undefined): string[];
|
|
43
|
+
export declare function createTask(userId: string, projectId: string, taskData: {
|
|
44
|
+
type: 'epic' | 'task' | 'subtask';
|
|
45
|
+
title: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
parent_id?: string;
|
|
48
|
+
priority?: string;
|
|
49
|
+
acceptance_criteria?: string[];
|
|
50
|
+
blocked_by?: string[];
|
|
51
|
+
estimated_effort?: string;
|
|
52
|
+
tags?: string[];
|
|
53
|
+
agent_type?: string;
|
|
54
|
+
domain?: string;
|
|
55
|
+
}): Promise<{
|
|
56
|
+
success: boolean;
|
|
57
|
+
data: Task;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function listTasks(userId: string, projectId: string, filters?: {
|
|
60
|
+
type?: string;
|
|
61
|
+
status?: string;
|
|
62
|
+
parent_id?: string;
|
|
63
|
+
assigned_to?: string;
|
|
64
|
+
limit?: number;
|
|
65
|
+
offset?: number;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
success: boolean;
|
|
68
|
+
data: Task[];
|
|
69
|
+
meta: {
|
|
70
|
+
limit: number;
|
|
71
|
+
offset: number;
|
|
72
|
+
count: number;
|
|
73
|
+
};
|
|
74
|
+
}>;
|
|
75
|
+
export declare function getTask(userId: string, projectId: string, taskId: string, full?: boolean): Promise<{
|
|
76
|
+
success: boolean;
|
|
77
|
+
data: Task | {
|
|
78
|
+
task: Task;
|
|
79
|
+
context: TaskContext[];
|
|
80
|
+
subtasks: Task[];
|
|
81
|
+
parent?: Task;
|
|
82
|
+
};
|
|
83
|
+
}>;
|
|
84
|
+
export declare function claimTask(userId: string, projectId: string, taskId: string, agentId: string, lockDurationMinutes?: number): Promise<{
|
|
85
|
+
success: boolean;
|
|
86
|
+
data: {
|
|
87
|
+
claimed: boolean;
|
|
88
|
+
lock_expires_at: string;
|
|
89
|
+
task: Task;
|
|
90
|
+
context: TaskContext[];
|
|
91
|
+
};
|
|
92
|
+
}>;
|
|
93
|
+
export declare function releaseTask(userId: string, projectId: string, taskId: string, agentId: string, newStatus?: string, workLog?: string): Promise<{
|
|
94
|
+
success: boolean;
|
|
95
|
+
data: {
|
|
96
|
+
released: boolean;
|
|
97
|
+
task: Task;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
export declare function updateTaskStatus(userId: string, projectId: string, taskId: string, status: string, agentId?: string): Promise<{
|
|
101
|
+
success: boolean;
|
|
102
|
+
data: Task;
|
|
103
|
+
}>;
|
|
104
|
+
export declare function addTaskContext(userId: string, projectId: string, taskId: string, contextType: string, content: string, addedBy: string, source?: string): Promise<{
|
|
105
|
+
success: boolean;
|
|
106
|
+
data: TaskContext;
|
|
107
|
+
}>;
|
|
108
|
+
export declare function getTaskSummary(userId: string, projectId: string): Promise<{
|
|
109
|
+
success: boolean;
|
|
110
|
+
data: {
|
|
111
|
+
by_status: Record<string, number>;
|
|
112
|
+
by_type: Record<string, number>;
|
|
113
|
+
active_agents: number;
|
|
114
|
+
recent_events: {
|
|
115
|
+
id: string;
|
|
116
|
+
task_id: string;
|
|
117
|
+
event_type: string;
|
|
118
|
+
task_title: string;
|
|
119
|
+
created_at: string;
|
|
120
|
+
}[];
|
|
121
|
+
};
|
|
122
|
+
}>;
|
|
123
|
+
export declare function heartbeatTask(userId: string, projectId: string, taskId: string, agentId: string, extendMinutes?: number): Promise<{
|
|
124
|
+
success: boolean;
|
|
125
|
+
data: {
|
|
126
|
+
extended: boolean;
|
|
127
|
+
new_expires_at: string;
|
|
128
|
+
};
|
|
129
|
+
}>;
|
|
130
|
+
/**
|
|
131
|
+
* Get all tasks ready for parallel dispatch
|
|
132
|
+
* - Filters for 'ready' status
|
|
133
|
+
* - Excludes already claimed tasks
|
|
134
|
+
* - Resolves dependencies (only returns unblocked tasks)
|
|
135
|
+
* - Matches each to appropriate expert worker
|
|
136
|
+
*/
|
|
137
|
+
export declare function getDispatchableTasks(userId: string, projectId: string, epicId?: string, maxParallel?: number): Promise<DispatchableTask[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Get full execution context for a worker agent
|
|
140
|
+
*/
|
|
141
|
+
export declare function getExecutionContext(userId: string, projectId: string, taskId: string): Promise<{
|
|
142
|
+
task: Task;
|
|
143
|
+
worker: ExpertWorker;
|
|
144
|
+
systemPrompt: string;
|
|
145
|
+
context: TaskContext[];
|
|
146
|
+
parentTask?: Task;
|
|
147
|
+
siblingTasks?: Task[];
|
|
148
|
+
}>;
|
|
149
|
+
/**
|
|
150
|
+
* Find newly unblocked tasks after a completion
|
|
151
|
+
*/
|
|
152
|
+
export declare function resolveTaskDependencies(userId: string, projectId: string, completedTaskId: string, epicId?: string): Promise<Task[]>;
|