crewx 0.8.1 → 0.8.2-rc.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.
- package/README.md +268 -268
- package/bin/cli-commands.js +34 -0
- package/bin/crewx-lib.js +213 -108
- package/bin/crewx-ui.js +83 -83
- package/bin/crewx.js +219 -147
- package/bin/launcher-flags.js +29 -0
- package/bin/package.json +1 -1
- package/dist/assets/{MarketPage-Dwsg6K-B.js → MarketPage-njRHlSSN.js} +1 -1
- package/dist/assets/{PromptTab-DVKc7hJY.js → PromptTab-CNyClpEe.js} +1 -1
- package/dist/assets/{_baseUniq-wjlVo2E6.js → _baseUniq-CGNNUfN7.js} +1 -1
- package/dist/assets/{arc-BfPgRtzW.js → arc-BEN-1A69.js} +1 -1
- package/dist/assets/{architectureDiagram-Q4EWVU46-ewcueFAG.js → architectureDiagram-Q4EWVU46-fAPvGzXk.js} +1 -1
- package/dist/assets/{blockDiagram-DXYQGD6D-TxlbbvKn.js → blockDiagram-DXYQGD6D-BWrb7uua.js} +1 -1
- package/dist/assets/{c4Diagram-AHTNJAMY-C1lT_bl_.js → c4Diagram-AHTNJAMY-CbnLz81q.js} +1 -1
- package/dist/assets/channel-uEnl63Ym.js +1 -0
- package/dist/assets/chatgpt-logo-dark.svg +15 -15
- package/dist/assets/chatgpt-logo.svg +15 -15
- package/dist/assets/{chunk-4BX2VUAB-C41j2mCL.js → chunk-4BX2VUAB-BopMVv1Q.js} +1 -1
- package/dist/assets/{chunk-4TB4RGXK-HNNsUbz0.js → chunk-4TB4RGXK-Axjc-DMR.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-qtCgO0r2.js → chunk-55IACEB6-BVzu25a2.js} +1 -1
- package/dist/assets/{chunk-EDXVE4YY-BSnDYtsd.js → chunk-EDXVE4YY-Csh0IKkY.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-DyHRLQqX.js → chunk-FMBD7UC4-D3yW6Ykv.js} +1 -1
- package/dist/assets/{chunk-OYMX7WX6-CCjfi6WS.js → chunk-OYMX7WX6-CDzLbKmY.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-COLty8kd.js → chunk-QZHKN3VN-CqYP7txP.js} +1 -1
- package/dist/assets/{chunk-YZCP3GAM-CHUUnGeN.js → chunk-YZCP3GAM-CIz2ApJG.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-CU98S3yn.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-CU98S3yn.js +1 -0
- package/dist/assets/clone-D3Eqsbb8.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-CSip-V2g.js → cose-bilkent-S5V4N54A-DgVG9_nb.js} +1 -1
- package/dist/assets/{dagre-KV5264BT-DkdpnWhv.js → dagre-KV5264BT-DnNIMI1A.js} +1 -1
- package/dist/assets/{diagram-5BDNPKRD-PH4qc6PV.js → diagram-5BDNPKRD-asGr2q6a.js} +1 -1
- package/dist/assets/{diagram-G4DWMVQ6-Cg5xZcjx.js → diagram-G4DWMVQ6-hwyZkwNx.js} +1 -1
- package/dist/assets/{diagram-MMDJMWI5-soKmeTCW.js → diagram-MMDJMWI5-BJbIxezj.js} +1 -1
- package/dist/assets/{diagram-TYMM5635-Daq5Mihu.js → diagram-TYMM5635-JB2YJBVu.js} +1 -1
- package/dist/assets/{erDiagram-SMLLAGMA-kr2OtY0Y.js → erDiagram-SMLLAGMA-i1KkUgG6.js} +1 -1
- package/dist/assets/{flowDiagram-DWJPFMVM-DQZCb8gm.js → flowDiagram-DWJPFMVM-62cwXjLB.js} +1 -1
- package/dist/assets/{ganttDiagram-T4ZO3ILL-BHkn485T.js → ganttDiagram-T4ZO3ILL-BDhku_zz.js} +1 -1
- package/dist/assets/{gitGraphDiagram-UUTBAWPF-FaCyYFmC.js → gitGraphDiagram-UUTBAWPF-DkHe0Kwk.js} +1 -1
- package/dist/assets/{graph-BVJlrP6V.js → graph-BnMMHCuQ.js} +1 -1
- package/dist/assets/{infoDiagram-42DDH7IO-DJOWkKdM.js → infoDiagram-42DDH7IO-V7zg8GAV.js} +1 -1
- package/dist/assets/{ishikawaDiagram-UXIWVN3A-VfpvNaIf.js → ishikawaDiagram-UXIWVN3A-CTtEO2wl.js} +1 -1
- package/dist/assets/{journeyDiagram-VCZTEJTY-CPzsak-v.js → journeyDiagram-VCZTEJTY-NxQMTN2m.js} +1 -1
- package/dist/assets/{kanban-definition-6JOO6SKY-DFqLDBU0.js → kanban-definition-6JOO6SKY-BHBrmGg3.js} +1 -1
- package/dist/assets/{layout-CCSbNPHm.js → layout-DutU1eng.js} +1 -1
- package/dist/assets/{linear-C4T7PCKE.js → linear-Czvrvocq.js} +1 -1
- package/dist/assets/{main-CELBpK6r.js → main-D0PuDE6-.js} +230 -226
- package/dist/assets/{min-CGQNEYGh.js → min-CI38XtLs.js} +1 -1
- package/dist/assets/{mindmap-definition-QFDTVHPH-AuU1EqwS.js → mindmap-definition-QFDTVHPH-CbFeHoxp.js} +1 -1
- package/dist/assets/{pieDiagram-DEJITSTG-CopkCZwp.js → pieDiagram-DEJITSTG-MV4uB5yA.js} +1 -1
- package/dist/assets/{quadrantDiagram-34T5L4WZ-lMKrSv_t.js → quadrantDiagram-34T5L4WZ-D0a8e2mx.js} +1 -1
- package/dist/assets/{requirementDiagram-MS252O5E-dWUpHOFb.js → requirementDiagram-MS252O5E-CeTlv4na.js} +1 -1
- package/dist/assets/{sankeyDiagram-XADWPNL6-C8UQx9Bb.js → sankeyDiagram-XADWPNL6-D1E3xq9q.js} +1 -1
- package/dist/assets/{sequenceDiagram-FGHM5R23-CUVNIItJ.js → sequenceDiagram-FGHM5R23-BO1RXtYs.js} +1 -1
- package/dist/assets/{stateDiagram-FHFEXIEX-Ct0GamGl.js → stateDiagram-FHFEXIEX-AhFKkuPE.js} +1 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-gv2g1MYi.js +1 -0
- package/dist/assets/{timeline-definition-GMOUNBTQ-ul8Po7f7.js → timeline-definition-GMOUNBTQ-BMVxUhID.js} +1 -1
- package/dist/assets/{vennDiagram-DHZGUBPP-B4AOWQnP.js → vennDiagram-DHZGUBPP-YFiJZns6.js} +1 -1
- package/dist/assets/{wardley-RL74JXVD-Dr7Wp3AJ.js → wardley-RL74JXVD-JlCdJekg.js} +1 -1
- package/dist/assets/{wardleyDiagram-NUSXRM2D-Ck70faXX.js → wardleyDiagram-NUSXRM2D-BLn2PZq9.js} +1 -1
- package/dist/assets/{xychartDiagram-5P7HB3ND-Bsy5-cNt.js → xychartDiagram-5P7HB3ND-DNOUK9or.js} +1 -1
- package/dist/index.html +12 -12
- package/dist-electron/main.js +153 -116
- package/dist-electron/overlay.js +102 -65
- package/dist-electron/package.json +1 -0
- package/dist-electron/preload.js +8 -8
- package/dist-server/bootstrap/crewx-server.js +19 -10
- package/dist-server/repository/box.repository.js +20 -20
- package/dist-server/repository/project.repository.js +13 -13
- package/dist-server/repository/request-log.repository.js +10 -10
- package/dist-server/repository/task.repository.js +72 -72
- package/dist-server/repository/thread.repository.js +57 -57
- package/package.json +6 -6
- package/packages/cli/dist/bootstrap/crewx-cli.js +12 -0
- package/packages/cli/dist/commands/agent.js +23 -23
- package/packages/cli/dist/commands/init.js +19 -19
- package/packages/cli/dist/commands/parse-common-flags.d.ts +19 -3
- package/packages/cli/dist/commands/parse-common-flags.js +46 -6
- package/packages/cli/dist/commands/registry.d.ts +13 -0
- package/packages/cli/dist/commands/registry.js +29 -0
- package/packages/cli/dist/commands/task-db.js +7 -7
- package/packages/cli/dist/examples/deny-secrets-plugin.d.ts +22 -0
- package/packages/cli/dist/examples/deny-secrets-plugin.js +40 -0
- package/packages/cli/dist/main.js +134 -68
- package/packages/cli/dist/plugins/examples/echo-hook.d.ts +24 -0
- package/packages/cli/dist/plugins/examples/echo-hook.js +60 -0
- package/packages/cli/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
- package/packages/cli/dist/plugins/examples/verify-echo-hook.js +47 -0
- package/packages/cli/dist/plugins/sqlite-tracing.d.ts +11 -0
- package/packages/cli/dist/plugins/sqlite-tracing.js +19 -0
- package/packages/cli/dist/schema/tasks.d.ts +7 -0
- package/packages/cli/dist/schema/tasks.js +48 -0
- package/packages/cli/package.json +52 -52
- package/scripts/build-manual.mjs +266 -266
- package/scripts/emit-dist-server-package-json.mjs +7 -7
- package/scripts/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/scripts/postinstall.mjs +44 -44
- package/scripts/smoke-tarball.mjs +285 -285
- package/scripts/snapshot-msg-list.sh +52 -52
- package/server.js +167 -164
- package/dist/assets/channel-BP4PNMmz.js +0 -1
- package/dist/assets/classDiagram-6PBFFD2Q-Upr3UAcM.js +0 -1
- package/dist/assets/classDiagram-v2-HSJHXN6E-Upr3UAcM.js +0 -1
- package/dist/assets/clone-B8BP7ReZ.js +0 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-CFBLQDEx.js +0 -1
- package/dist-server/domain/task/dto/project-usage.dto.js +0 -38
- package/dist-server/domain/thread/dto/send-message.dto.js +0 -10
|
@@ -31,9 +31,9 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
|
|
|
31
31
|
}
|
|
32
32
|
// Backfill workspace_path for rows that still have it in the old repo_path column
|
|
33
33
|
try {
|
|
34
|
-
db.run(`
|
|
35
|
-
UPDATE workspaces SET workspace_path = repo_path
|
|
36
|
-
WHERE (workspace_path IS NULL OR workspace_path = '') AND repo_path IS NOT NULL AND repo_path != ''
|
|
34
|
+
db.run(`
|
|
35
|
+
UPDATE workspaces SET workspace_path = repo_path
|
|
36
|
+
WHERE (workspace_path IS NULL OR workspace_path = '') AND repo_path IS NOT NULL AND repo_path != ''
|
|
37
37
|
`);
|
|
38
38
|
}
|
|
39
39
|
catch {
|
|
@@ -86,13 +86,13 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
|
|
|
86
86
|
const db = this.openProjectDb();
|
|
87
87
|
try {
|
|
88
88
|
const countRow = db.get('SELECT COUNT(*) as count FROM threads WHERE workspace_id = ?', [id]);
|
|
89
|
-
const rows = db.all(`
|
|
90
|
-
SELECT t.*,
|
|
91
|
-
(SELECT agent_id FROM tasks tk WHERE tk.thread_id = t.id AND tk.agent_id IS NOT NULL ORDER BY tk.started_at ASC LIMIT 1) AS agent_id
|
|
92
|
-
FROM threads t
|
|
93
|
-
WHERE t.workspace_id = ?
|
|
94
|
-
ORDER BY t.updated_at DESC
|
|
95
|
-
LIMIT ? OFFSET ?
|
|
89
|
+
const rows = db.all(`
|
|
90
|
+
SELECT t.*,
|
|
91
|
+
(SELECT agent_id FROM tasks tk WHERE tk.thread_id = t.id AND tk.agent_id IS NOT NULL ORDER BY tk.started_at ASC LIMIT 1) AS agent_id
|
|
92
|
+
FROM threads t
|
|
93
|
+
WHERE t.workspace_id = ?
|
|
94
|
+
ORDER BY t.updated_at DESC
|
|
95
|
+
LIMIT ? OFFSET ?
|
|
96
96
|
`, [id, params.limit, params.offset]);
|
|
97
97
|
return { rows, total: countRow.count };
|
|
98
98
|
}
|
|
@@ -128,9 +128,9 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
|
|
|
128
128
|
const db = this.openProjectDb(false);
|
|
129
129
|
try {
|
|
130
130
|
const now = new Date().toISOString();
|
|
131
|
-
db.run(`
|
|
132
|
-
INSERT INTO workspaces (id, slug, name, workspace_path, is_active, created_at, updated_at)
|
|
133
|
-
VALUES (?, ?, ?, ?, 1, ?, ?)
|
|
131
|
+
db.run(`
|
|
132
|
+
INSERT INTO workspaces (id, slug, name, workspace_path, is_active, created_at, updated_at)
|
|
133
|
+
VALUES (?, ?, ?, ?, 1, ?, ?)
|
|
134
134
|
`, [id, slug, name, repoPath, now, now]);
|
|
135
135
|
return db.get('SELECT * FROM workspaces WHERE id = ?', [id]);
|
|
136
136
|
}
|
|
@@ -15,16 +15,16 @@ const common_1 = require("@nestjs/common");
|
|
|
15
15
|
const base_sqlite_repository_js_1 = require("./base-sqlite.repository.js");
|
|
16
16
|
let RequestLogRepository = class RequestLogRepository extends base_sqlite_repository_js_1.BaseSqliteRepository {
|
|
17
17
|
static { RequestLogRepository_1 = this; }
|
|
18
|
-
static INSERT_SQL = `
|
|
19
|
-
INSERT INTO request_logs (
|
|
20
|
-
id, path, method, status_code, duration_ms,
|
|
21
|
-
ip, request_headers, response_headers, request_body, response_body,
|
|
22
|
-
query, user_id, project_id, partition_key, timestamp, metadata
|
|
23
|
-
) VALUES (
|
|
24
|
-
?, ?, ?, ?, ?,
|
|
25
|
-
?, ?, ?, ?, ?,
|
|
26
|
-
?, ?, ?, ?, ?, ?
|
|
27
|
-
)
|
|
18
|
+
static INSERT_SQL = `
|
|
19
|
+
INSERT INTO request_logs (
|
|
20
|
+
id, path, method, status_code, duration_ms,
|
|
21
|
+
ip, request_headers, response_headers, request_body, response_body,
|
|
22
|
+
query, user_id, project_id, partition_key, timestamp, metadata
|
|
23
|
+
) VALUES (
|
|
24
|
+
?, ?, ?, ?, ?,
|
|
25
|
+
?, ?, ?, ?, ?,
|
|
26
|
+
?, ?, ?, ?, ?, ?
|
|
27
|
+
)
|
|
28
28
|
`;
|
|
29
29
|
logger = new common_1.Logger(RequestLogRepository_1.name);
|
|
30
30
|
db = null;
|
|
@@ -23,16 +23,16 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
23
23
|
const db = this.openReadonly(dbPath);
|
|
24
24
|
try {
|
|
25
25
|
// Primary lookup: by internal task UUID
|
|
26
|
-
let row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
|
|
27
|
-
error, caller_agent_id, parent_task_id, logs,
|
|
28
|
-
prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
|
|
26
|
+
let row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
|
|
27
|
+
error, caller_agent_id, parent_task_id, logs,
|
|
28
|
+
prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
|
|
29
29
|
FROM tasks WHERE id = ?${wsFilter}`, [taskId, ...wsParams]);
|
|
30
30
|
// Fallback: treat taskId as thread/conversation name
|
|
31
31
|
if (!row) {
|
|
32
|
-
row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
|
|
33
|
-
error, caller_agent_id, parent_task_id, logs,
|
|
34
|
-
prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
|
|
35
|
-
FROM tasks WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
|
|
32
|
+
row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
|
|
33
|
+
error, caller_agent_id, parent_task_id, logs,
|
|
34
|
+
prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
|
|
35
|
+
FROM tasks WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
|
|
36
36
|
ORDER BY started_at DESC LIMIT 1`, [taskId, `%--thread=${taskId}%`, ...wsParams]);
|
|
37
37
|
}
|
|
38
38
|
if (row)
|
|
@@ -51,7 +51,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
51
51
|
}
|
|
52
52
|
/** Get child tasks for a parent task. */
|
|
53
53
|
findChildTasks(db, parentTaskId) {
|
|
54
|
-
return db.all(`SELECT id, agent_id, status, started_at, completed_at, duration_ms, error, logs
|
|
54
|
+
return db.all(`SELECT id, agent_id, status, started_at, completed_at, duration_ms, error, logs
|
|
55
55
|
FROM tasks WHERE parent_task_id = ? ORDER BY started_at ASC`, [parentTaskId]);
|
|
56
56
|
}
|
|
57
57
|
/** Get workspace usage summary, optionally filtered by workspaceId. */
|
|
@@ -63,18 +63,18 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
63
63
|
try {
|
|
64
64
|
const whereClause = workspaceId ? `WHERE workspace_id = ?` : '';
|
|
65
65
|
const queryParams = workspaceId ? [workspaceId] : [];
|
|
66
|
-
return db.all(`
|
|
67
|
-
SELECT
|
|
68
|
-
COALESCE(workspace_id, 'unknown') AS workspace_id,
|
|
69
|
-
COALESCE(workspace_name, 'Unknown Workspace') AS workspace_name,
|
|
70
|
-
SUM(input_tokens) AS input_tokens,
|
|
71
|
-
SUM(output_tokens) AS output_tokens,
|
|
72
|
-
SUM(cost_usd) AS cost_usd,
|
|
73
|
-
COUNT(*) AS task_count
|
|
74
|
-
FROM tasks
|
|
75
|
-
${whereClause}
|
|
76
|
-
GROUP BY workspace_id, workspace_name
|
|
77
|
-
ORDER BY (SUM(input_tokens) + SUM(output_tokens)) DESC
|
|
66
|
+
return db.all(`
|
|
67
|
+
SELECT
|
|
68
|
+
COALESCE(workspace_id, 'unknown') AS workspace_id,
|
|
69
|
+
COALESCE(workspace_name, 'Unknown Workspace') AS workspace_name,
|
|
70
|
+
SUM(input_tokens) AS input_tokens,
|
|
71
|
+
SUM(output_tokens) AS output_tokens,
|
|
72
|
+
SUM(cost_usd) AS cost_usd,
|
|
73
|
+
COUNT(*) AS task_count
|
|
74
|
+
FROM tasks
|
|
75
|
+
${whereClause}
|
|
76
|
+
GROUP BY workspace_id, workspace_name
|
|
77
|
+
ORDER BY (SUM(input_tokens) + SUM(output_tokens)) DESC
|
|
78
78
|
`, queryParams);
|
|
79
79
|
}
|
|
80
80
|
catch (error) {
|
|
@@ -98,7 +98,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
98
98
|
continue;
|
|
99
99
|
const db = this.openReadonly(dbPath);
|
|
100
100
|
try {
|
|
101
|
-
const rows = db.all(`SELECT id, input_tokens, output_tokens, cost_usd
|
|
101
|
+
const rows = db.all(`SELECT id, input_tokens, output_tokens, cost_usd
|
|
102
102
|
FROM tasks WHERE thread_id = ? OR (thread_id IS NULL AND command LIKE ?)`, [threadId, `%--thread=${threadId}%`]);
|
|
103
103
|
for (const row of rows) {
|
|
104
104
|
if (seenIds.has(row.id))
|
|
@@ -134,9 +134,9 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
134
134
|
const baseParams = [threadId, `%--thread=${threadId}%`];
|
|
135
135
|
if (workspaceId)
|
|
136
136
|
baseParams.push(workspaceId);
|
|
137
|
-
const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
|
|
138
|
-
FROM tasks
|
|
139
|
-
WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
|
|
137
|
+
const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
|
|
138
|
+
FROM tasks
|
|
139
|
+
WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
|
|
140
140
|
ORDER BY started_at ASC`, baseParams);
|
|
141
141
|
for (const row of rows) {
|
|
142
142
|
if (!seenIds.has(row.id)) {
|
|
@@ -187,10 +187,10 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
187
187
|
const countRow = db.get(`SELECT COUNT(*) AS cnt FROM tasks ${whereClause}`, queryParams);
|
|
188
188
|
const total = countRow?.cnt ?? 0;
|
|
189
189
|
const sortDir = params.sortDir === 'ASC' ? 'ASC' : 'DESC';
|
|
190
|
-
const tasks = db.all(`SELECT id, agent_id, status, prompt, model, started_at, completed_at, duration_ms,
|
|
191
|
-
input_tokens, output_tokens, cost_usd, thread_id
|
|
192
|
-
FROM tasks ${whereClause}
|
|
193
|
-
ORDER BY started_at ${sortDir}
|
|
190
|
+
const tasks = db.all(`SELECT id, agent_id, status, prompt, model, started_at, completed_at, duration_ms,
|
|
191
|
+
input_tokens, output_tokens, cost_usd, thread_id
|
|
192
|
+
FROM tasks ${whereClause}
|
|
193
|
+
ORDER BY started_at ${sortDir}
|
|
194
194
|
LIMIT ? OFFSET ?`, [...queryParams, params.limit, params.offset]);
|
|
195
195
|
return { tasks, total };
|
|
196
196
|
}
|
|
@@ -215,34 +215,34 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
215
215
|
? (params.push(workspace), `AND t.workspace_name = ?`)
|
|
216
216
|
: '';
|
|
217
217
|
// Provider derived from coding_agent_command first word (no agents table)
|
|
218
|
-
return db.all(`
|
|
219
|
-
SELECT
|
|
220
|
-
t.agent_id,
|
|
221
|
-
t.workspace_id,
|
|
222
|
-
t.workspace_name,
|
|
223
|
-
COALESCE(
|
|
224
|
-
'cli/' || SUBSTR(t.coding_agent_command, 1,
|
|
225
|
-
CASE WHEN INSTR(t.coding_agent_command, ' ') > 0
|
|
226
|
-
THEN INSTR(t.coding_agent_command, ' ') - 1
|
|
227
|
-
ELSE LENGTH(t.coding_agent_command)
|
|
228
|
-
END
|
|
229
|
-
),
|
|
230
|
-
'unknown'
|
|
231
|
-
) AS provider,
|
|
232
|
-
COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
|
|
233
|
-
COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
|
|
234
|
-
COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0) AS total_tokens,
|
|
235
|
-
COALESCE(SUM(t.cost_usd), 0) AS total_cost,
|
|
236
|
-
COUNT(*) AS task_count,
|
|
237
|
-
COALESCE(SUM(t.duration_ms), 0) AS active_duration_ms,
|
|
238
|
-
MAX(t.completed_at) AS last_active_at
|
|
239
|
-
FROM tasks t
|
|
240
|
-
WHERE t.status IN ('completed', 'success')
|
|
241
|
-
AND t.started_at >= ?
|
|
242
|
-
AND t.started_at < ?
|
|
243
|
-
${workspaceCondition}
|
|
244
|
-
GROUP BY t.agent_id, t.workspace_id, t.workspace_name, provider
|
|
245
|
-
ORDER BY total_tokens DESC
|
|
218
|
+
return db.all(`
|
|
219
|
+
SELECT
|
|
220
|
+
t.agent_id,
|
|
221
|
+
t.workspace_id,
|
|
222
|
+
t.workspace_name,
|
|
223
|
+
COALESCE(
|
|
224
|
+
'cli/' || SUBSTR(t.coding_agent_command, 1,
|
|
225
|
+
CASE WHEN INSTR(t.coding_agent_command, ' ') > 0
|
|
226
|
+
THEN INSTR(t.coding_agent_command, ' ') - 1
|
|
227
|
+
ELSE LENGTH(t.coding_agent_command)
|
|
228
|
+
END
|
|
229
|
+
),
|
|
230
|
+
'unknown'
|
|
231
|
+
) AS provider,
|
|
232
|
+
COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
|
|
233
|
+
COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
|
|
234
|
+
COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0) AS total_tokens,
|
|
235
|
+
COALESCE(SUM(t.cost_usd), 0) AS total_cost,
|
|
236
|
+
COUNT(*) AS task_count,
|
|
237
|
+
COALESCE(SUM(t.duration_ms), 0) AS active_duration_ms,
|
|
238
|
+
MAX(t.completed_at) AS last_active_at
|
|
239
|
+
FROM tasks t
|
|
240
|
+
WHERE t.status IN ('completed', 'success')
|
|
241
|
+
AND t.started_at >= ?
|
|
242
|
+
AND t.started_at < ?
|
|
243
|
+
${workspaceCondition}
|
|
244
|
+
GROUP BY t.agent_id, t.workspace_id, t.workspace_name, provider
|
|
245
|
+
ORDER BY total_tokens DESC
|
|
246
246
|
`, params);
|
|
247
247
|
}
|
|
248
248
|
catch (error) {
|
|
@@ -263,18 +263,18 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
263
263
|
const workspaceCondition = workspace
|
|
264
264
|
? (params.push(workspace), `AND t.workspace_name = ?`)
|
|
265
265
|
: '';
|
|
266
|
-
return db.all(`
|
|
267
|
-
SELECT
|
|
268
|
-
t.started_at,
|
|
269
|
-
t.agent_id,
|
|
270
|
-
COALESCE(t.input_tokens, 0) AS input_tokens,
|
|
271
|
-
COALESCE(t.output_tokens, 0) AS output_tokens
|
|
272
|
-
FROM tasks t
|
|
273
|
-
WHERE t.status IN ('completed', 'success')
|
|
274
|
-
AND t.started_at >= ?
|
|
275
|
-
AND t.started_at < ?
|
|
276
|
-
${workspaceCondition}
|
|
277
|
-
ORDER BY t.started_at ASC
|
|
266
|
+
return db.all(`
|
|
267
|
+
SELECT
|
|
268
|
+
t.started_at,
|
|
269
|
+
t.agent_id,
|
|
270
|
+
COALESCE(t.input_tokens, 0) AS input_tokens,
|
|
271
|
+
COALESCE(t.output_tokens, 0) AS output_tokens
|
|
272
|
+
FROM tasks t
|
|
273
|
+
WHERE t.status IN ('completed', 'success')
|
|
274
|
+
AND t.started_at >= ?
|
|
275
|
+
AND t.started_at < ?
|
|
276
|
+
${workspaceCondition}
|
|
277
|
+
ORDER BY t.started_at ASC
|
|
278
278
|
`, params);
|
|
279
279
|
}
|
|
280
280
|
catch (error) {
|
|
@@ -315,7 +315,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
315
315
|
const params = workspaceId
|
|
316
316
|
? [error, now, taskId, workspaceId]
|
|
317
317
|
: [error, now, taskId];
|
|
318
|
-
db.run(`UPDATE tasks SET status = 'failed', error = ?, completed_at = ?
|
|
318
|
+
db.run(`UPDATE tasks SET status = 'failed', error = ?, completed_at = ?
|
|
319
319
|
WHERE id = ? AND status = 'running'${wsFilter}`, params);
|
|
320
320
|
const changes = db.get(`SELECT changes() AS cnt`);
|
|
321
321
|
return (changes?.cnt ?? 0) > 0;
|
|
@@ -336,9 +336,9 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
|
|
|
336
336
|
try {
|
|
337
337
|
const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
|
|
338
338
|
const params = workspaceId ? [`%${hint}%`, workspaceId] : [`%${hint}%`];
|
|
339
|
-
const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
|
|
340
|
-
FROM tasks
|
|
341
|
-
WHERE prompt LIKE ?${wsFilter}
|
|
339
|
+
const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
|
|
340
|
+
FROM tasks
|
|
341
|
+
WHERE prompt LIKE ?${wsFilter}
|
|
342
342
|
ORDER BY started_at ASC`, params);
|
|
343
343
|
for (const row of rows) {
|
|
344
344
|
if (!seenIds.has(row.id)) {
|
|
@@ -29,12 +29,12 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
29
29
|
? `WHERE (workspace_id = ? OR workspace_id IS NULL)`
|
|
30
30
|
: '';
|
|
31
31
|
const queryParams = workspaceId ? [workspaceId] : [];
|
|
32
|
-
const fetched = db.all(`
|
|
33
|
-
SELECT id, workspace_id, platform, title, first_message, last_message,
|
|
34
|
-
message_count, created_at, updated_at, metadata
|
|
35
|
-
FROM threads
|
|
36
|
-
${whereClause}
|
|
37
|
-
ORDER BY updated_at DESC
|
|
32
|
+
const fetched = db.all(`
|
|
33
|
+
SELECT id, workspace_id, platform, title, first_message, last_message,
|
|
34
|
+
message_count, created_at, updated_at, metadata
|
|
35
|
+
FROM threads
|
|
36
|
+
${whereClause}
|
|
37
|
+
ORDER BY updated_at DESC
|
|
38
38
|
`, queryParams);
|
|
39
39
|
for (const row of fetched) {
|
|
40
40
|
if (!seenIds.has(row.id)) {
|
|
@@ -66,10 +66,10 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
66
66
|
continue;
|
|
67
67
|
const wsFilter = workspaceId ? ` AND (workspace_id = ? OR workspace_id IS NULL)` : '';
|
|
68
68
|
const params = workspaceId ? [threadId, workspaceId] : [threadId];
|
|
69
|
-
const row = db.get(`
|
|
70
|
-
SELECT id, workspace_id, platform, title, first_message, last_message,
|
|
71
|
-
message_count, created_at, updated_at, metadata
|
|
72
|
-
FROM threads WHERE id = ?${wsFilter}
|
|
69
|
+
const row = db.get(`
|
|
70
|
+
SELECT id, workspace_id, platform, title, first_message, last_message,
|
|
71
|
+
message_count, created_at, updated_at, metadata
|
|
72
|
+
FROM threads WHERE id = ?${wsFilter}
|
|
73
73
|
`, params);
|
|
74
74
|
if (row)
|
|
75
75
|
return row;
|
|
@@ -129,22 +129,22 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
129
129
|
continue;
|
|
130
130
|
const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
|
|
131
131
|
const statsParams = workspaceId ? [threadId, workspaceId] : [threadId];
|
|
132
|
-
const stats = db.get(`
|
|
133
|
-
SELECT COUNT(*) as cnt,
|
|
134
|
-
COALESCE(SUM(input_tokens), 0) as total_input,
|
|
135
|
-
COALESCE(SUM(output_tokens), 0) as total_output,
|
|
136
|
-
COALESCE(SUM(cost_usd), 0) as total_cost
|
|
137
|
-
FROM tasks
|
|
138
|
-
WHERE thread_id = ? AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
132
|
+
const stats = db.get(`
|
|
133
|
+
SELECT COUNT(*) as cnt,
|
|
134
|
+
COALESCE(SUM(input_tokens), 0) as total_input,
|
|
135
|
+
COALESCE(SUM(output_tokens), 0) as total_output,
|
|
136
|
+
COALESCE(SUM(cost_usd), 0) as total_cost
|
|
137
|
+
FROM tasks
|
|
138
|
+
WHERE thread_id = ? AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
139
139
|
`, statsParams);
|
|
140
140
|
taskCount += stats.cnt;
|
|
141
141
|
inputTokens += stats.total_input;
|
|
142
142
|
outputTokens += stats.total_output;
|
|
143
143
|
costUsd += stats.total_cost;
|
|
144
|
-
const agentRows = db.all(`
|
|
145
|
-
SELECT DISTINCT agent_id FROM tasks
|
|
146
|
-
WHERE thread_id = ? AND agent_id IS NOT NULL AND agent_id != ''
|
|
147
|
-
AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
144
|
+
const agentRows = db.all(`
|
|
145
|
+
SELECT DISTINCT agent_id FROM tasks
|
|
146
|
+
WHERE thread_id = ? AND agent_id IS NOT NULL AND agent_id != ''
|
|
147
|
+
AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
148
148
|
`, statsParams);
|
|
149
149
|
for (const row of agentRows) {
|
|
150
150
|
agents.add(row.agent_id);
|
|
@@ -175,13 +175,13 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
175
175
|
continue;
|
|
176
176
|
const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
|
|
177
177
|
const taskParams = workspaceId ? [threadId, workspaceId] : [threadId];
|
|
178
|
-
const tasks = db.all(`
|
|
179
|
-
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
180
|
-
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
181
|
-
error, parent_task_id, caller_agent_id
|
|
182
|
-
FROM tasks
|
|
183
|
-
WHERE thread_id = ? AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
184
|
-
ORDER BY started_at ASC
|
|
178
|
+
const tasks = db.all(`
|
|
179
|
+
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
180
|
+
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
181
|
+
error, parent_task_id, caller_agent_id
|
|
182
|
+
FROM tasks
|
|
183
|
+
WHERE thread_id = ? AND (parent_task_id IS NULL OR parent_task_id = '')${wsFilter}
|
|
184
|
+
ORDER BY started_at ASC
|
|
185
185
|
`, taskParams);
|
|
186
186
|
for (const t of tasks) {
|
|
187
187
|
if (!seenIds.has(t.id)) {
|
|
@@ -215,12 +215,12 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
215
215
|
continue;
|
|
216
216
|
const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
|
|
217
217
|
const taskParams = workspaceId ? [threadId, workspaceId] : [threadId];
|
|
218
|
-
const tasks = db.all(`
|
|
219
|
-
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
220
|
-
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
221
|
-
error, parent_task_id, caller_agent_id
|
|
222
|
-
FROM tasks WHERE thread_id = ?${wsFilter}
|
|
223
|
-
ORDER BY started_at ASC
|
|
218
|
+
const tasks = db.all(`
|
|
219
|
+
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
220
|
+
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
221
|
+
error, parent_task_id, caller_agent_id
|
|
222
|
+
FROM tasks WHERE thread_id = ?${wsFilter}
|
|
223
|
+
ORDER BY started_at ASC
|
|
224
224
|
`, taskParams);
|
|
225
225
|
for (const t of tasks) {
|
|
226
226
|
if (!seenIds.has(t.id)) {
|
|
@@ -250,17 +250,17 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
250
250
|
try {
|
|
251
251
|
const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
|
|
252
252
|
const findParams = workspaceId ? [taskId, threadId, workspaceId] : [taskId, threadId];
|
|
253
|
-
const row = db.get(`
|
|
254
|
-
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
255
|
-
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
256
|
-
error, parent_task_id, caller_agent_id
|
|
257
|
-
FROM tasks WHERE id = ? AND thread_id = ?${wsFilter}
|
|
253
|
+
const row = db.get(`
|
|
254
|
+
SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
255
|
+
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
256
|
+
error, parent_task_id, caller_agent_id
|
|
257
|
+
FROM tasks WHERE id = ? AND thread_id = ?${wsFilter}
|
|
258
258
|
`, findParams);
|
|
259
259
|
if (!row)
|
|
260
260
|
continue;
|
|
261
|
-
const children = db.all(`SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
262
|
-
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
263
|
-
error, parent_task_id, caller_agent_id
|
|
261
|
+
const children = db.all(`SELECT id, agent_id, prompt, result, status, started_at, completed_at,
|
|
262
|
+
duration_ms, thread_id, logs, input_tokens, output_tokens, cost_usd,
|
|
263
|
+
error, parent_task_id, caller_agent_id
|
|
264
264
|
FROM tasks WHERE parent_task_id = ? ORDER BY started_at ASC`, [row.id]);
|
|
265
265
|
return { task: row, children };
|
|
266
266
|
}
|
|
@@ -287,13 +287,13 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
287
287
|
continue;
|
|
288
288
|
const db = this.openReadonly(dbPath);
|
|
289
289
|
try {
|
|
290
|
-
const rows = db.all(`
|
|
291
|
-
SELECT id, agent_id, status, started_at, completed_at,
|
|
292
|
-
duration_ms, thread_id, input_tokens, output_tokens, cost_usd, error
|
|
293
|
-
FROM tasks
|
|
294
|
-
WHERE thread_id IN (${placeholders})
|
|
295
|
-
AND (parent_task_id IS NULL OR parent_task_id = '')
|
|
296
|
-
ORDER BY started_at ASC
|
|
290
|
+
const rows = db.all(`
|
|
291
|
+
SELECT id, agent_id, status, started_at, completed_at,
|
|
292
|
+
duration_ms, thread_id, input_tokens, output_tokens, cost_usd, error
|
|
293
|
+
FROM tasks
|
|
294
|
+
WHERE thread_id IN (${placeholders})
|
|
295
|
+
AND (parent_task_id IS NULL OR parent_task_id = '')
|
|
296
|
+
ORDER BY started_at ASC
|
|
297
297
|
`, threadIds);
|
|
298
298
|
for (const row of rows) {
|
|
299
299
|
const tid = row.thread_id;
|
|
@@ -323,17 +323,17 @@ let ThreadRepository = class ThreadRepository extends base_sqlite_repository_js_
|
|
|
323
323
|
try {
|
|
324
324
|
const existing = db.get('SELECT id, message_count FROM threads WHERE id = ?', [threadId]);
|
|
325
325
|
if (existing) {
|
|
326
|
-
db.run(`
|
|
327
|
-
UPDATE threads
|
|
328
|
-
SET updated_at = datetime('now'), message_count = message_count + 1
|
|
329
|
-
WHERE id = ?
|
|
326
|
+
db.run(`
|
|
327
|
+
UPDATE threads
|
|
328
|
+
SET updated_at = datetime('now'), message_count = message_count + 1
|
|
329
|
+
WHERE id = ?
|
|
330
330
|
`, [threadId]);
|
|
331
331
|
}
|
|
332
332
|
else {
|
|
333
|
-
db.run(`
|
|
334
|
-
INSERT OR REPLACE INTO threads
|
|
335
|
-
(id, workspace_id, platform, title, first_message, message_count, created_at, updated_at)
|
|
336
|
-
VALUES (?, ?, 'cli', ?, ?, 1, datetime('now'), datetime('now'))
|
|
333
|
+
db.run(`
|
|
334
|
+
INSERT OR REPLACE INTO threads
|
|
335
|
+
(id, workspace_id, platform, title, first_message, message_count, created_at, updated_at)
|
|
336
|
+
VALUES (?, ?, 'cli', ?, ?, 1, datetime('now'), datetime('now'))
|
|
337
337
|
`, [threadId, opts.workspaceId ?? null, opts.title, opts.firstMessage]);
|
|
338
338
|
}
|
|
339
339
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crewx",
|
|
3
|
-
"version": "0.8.1",
|
|
3
|
+
"version": "0.8.2-rc.1",
|
|
4
4
|
"description": "CrewX — AI agent team dashboard with Electron UI and CLI (Web + Electron + Global CLI)",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -97,17 +97,17 @@
|
|
|
97
97
|
"yargs": "^17.7.0",
|
|
98
98
|
"zod": "^3.22.0",
|
|
99
99
|
"zustand": "^4.5.0",
|
|
100
|
+
"@crewx/cli": "0.8.2-rc.1",
|
|
100
101
|
"@crewx/cron": "0.1.7",
|
|
101
|
-
"@crewx/cli": "0.8.1",
|
|
102
102
|
"@crewx/doc": "0.1.7",
|
|
103
103
|
"@crewx/knowledge-core": "0.1.5",
|
|
104
104
|
"@crewx/memory": "0.1.9",
|
|
105
105
|
"@crewx/search": "0.1.8",
|
|
106
|
+
"@crewx/wbs": "0.1.8",
|
|
106
107
|
"@crewx/shared": "0.0.4",
|
|
107
108
|
"@crewx/workflow": "0.3.8",
|
|
108
|
-
"@crewx/
|
|
109
|
-
"@crewx/
|
|
110
|
-
"@crewx/skill": "0.1.7"
|
|
109
|
+
"@crewx/skill": "0.1.7",
|
|
110
|
+
"@crewx/sdk": "0.8.2-rc.1"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@nestjs/cli": "^11.0.16",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"typescript": "^5.3.3",
|
|
146
146
|
"vite": "^5.0.10",
|
|
147
147
|
"vite-plugin-electron": "^0.29.0",
|
|
148
|
-
"vitest": "^
|
|
148
|
+
"vitest": "^3.2.4"
|
|
149
149
|
},
|
|
150
150
|
"optionalDependencies": {
|
|
151
151
|
"electron": "^39.2.7"
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.createCliCrewx = createCliCrewx;
|
|
4
7
|
const fs_1 = require("fs");
|
|
5
8
|
const path_1 = require("path");
|
|
9
|
+
const os_1 = require("os");
|
|
10
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
6
11
|
const sdk_1 = require("@crewx/sdk");
|
|
7
12
|
const plugins_1 = require("@crewx/sdk/plugins");
|
|
8
13
|
const register_builtin_tools_1 = require("../register-builtin-tools");
|
|
9
14
|
const version_1 = require("../utils/version");
|
|
15
|
+
const tasks_1 = require("../schema/tasks");
|
|
10
16
|
/**
|
|
11
17
|
* Build a Crewx instance with CLI-standard plugins (FileLogger + SqliteTracing)
|
|
12
18
|
* and built-in tools registered. Use this from any CLI command that needs a
|
|
@@ -39,6 +45,12 @@ async function createCliCrewx(configPath = process.env.CREWX_CONFIG ?? 'crewx.ya
|
|
|
39
45
|
// No explicit config and file doesn't exist — built-in-only mode
|
|
40
46
|
yamlPath = undefined;
|
|
41
47
|
}
|
|
48
|
+
// Ensure ~/.crewx/crewx.db schema exists before SqliteTracingPlugin opens it.
|
|
49
|
+
const dbDir = (0, path_1.join)((0, os_1.homedir)(), '.crewx');
|
|
50
|
+
(0, fs_1.mkdirSync)(dbDir, { recursive: true });
|
|
51
|
+
const schemaDb = new better_sqlite3_1.default((0, path_1.join)(dbDir, 'crewx.db'));
|
|
52
|
+
(0, tasks_1.ensureTasksSchema)(schemaDb);
|
|
53
|
+
schemaDb.close();
|
|
42
54
|
// Pass ourselves back to the SDK: when this Crewx encounters a file:// remote
|
|
43
55
|
// agent, the SDK uses this factory to bootstrap the target Crewx instance
|
|
44
56
|
// with the same plugin set (FileLogger + SqliteTracing + built-in tools).
|
|
@@ -219,28 +219,28 @@ function loadAgentSkills() {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
function printAgentHelp() {
|
|
222
|
-
console.log(`
|
|
223
|
-
CrewX Agent Management
|
|
224
|
-
|
|
225
|
-
Usage:
|
|
226
|
-
crewx agent # List configured agents (default)
|
|
227
|
-
crewx agent ls # List configured agents
|
|
228
|
-
crewx agent list # Alias for ls
|
|
229
|
-
crewx agent prompt <id> # Inspect rendered agent prompt
|
|
230
|
-
|
|
231
|
-
Filter Options (for agent ls):
|
|
232
|
-
--role <value> Filter by agent role (comma-separated for multiple: PM,Dev)
|
|
233
|
-
--team <value> Filter by agent team (comma-separated for multiple)
|
|
234
|
-
--provider <value> Filter by provider (comma-separated, partial match: claude)
|
|
235
|
-
|
|
236
|
-
Examples:
|
|
237
|
-
crewx agent
|
|
238
|
-
crewx agent ls
|
|
239
|
-
crewx agent ls --role=PM
|
|
240
|
-
crewx agent ls --team="CrewX Core 개발팀"
|
|
241
|
-
crewx agent ls --provider=claude
|
|
242
|
-
crewx agent ls --role=PM --provider=claude
|
|
243
|
-
crewx agent ls --role=PM,general
|
|
244
|
-
CREWX_CONFIG=./crewx.yaml crewx agent list
|
|
222
|
+
console.log(`
|
|
223
|
+
CrewX Agent Management
|
|
224
|
+
|
|
225
|
+
Usage:
|
|
226
|
+
crewx agent # List configured agents (default)
|
|
227
|
+
crewx agent ls # List configured agents
|
|
228
|
+
crewx agent list # Alias for ls
|
|
229
|
+
crewx agent prompt <id> # Inspect rendered agent prompt
|
|
230
|
+
|
|
231
|
+
Filter Options (for agent ls):
|
|
232
|
+
--role <value> Filter by agent role (comma-separated for multiple: PM,Dev)
|
|
233
|
+
--team <value> Filter by agent team (comma-separated for multiple)
|
|
234
|
+
--provider <value> Filter by provider (comma-separated, partial match: claude)
|
|
235
|
+
|
|
236
|
+
Examples:
|
|
237
|
+
crewx agent
|
|
238
|
+
crewx agent ls
|
|
239
|
+
crewx agent ls --role=PM
|
|
240
|
+
crewx agent ls --team="CrewX Core 개발팀"
|
|
241
|
+
crewx agent ls --provider=claude
|
|
242
|
+
crewx agent ls --role=PM --provider=claude
|
|
243
|
+
crewx agent ls --role=PM,general
|
|
244
|
+
CREWX_CONFIG=./crewx.yaml crewx agent list
|
|
245
245
|
`.trim());
|
|
246
246
|
}
|
|
@@ -56,27 +56,27 @@ function escapeYamlBlock(text) {
|
|
|
56
56
|
}
|
|
57
57
|
function generateDefaultYaml(agents) {
|
|
58
58
|
const agentBlocks = agents
|
|
59
|
-
.map((a) => ` - id: "${a.id}"
|
|
60
|
-
name: "${a.name}"
|
|
61
|
-
role: "${a.role}"
|
|
62
|
-
team: "${a.team}"
|
|
63
|
-
provider: "${a.provider}"
|
|
64
|
-
default_model: "${a.default_model}"
|
|
65
|
-
working_directory: "${a.working_directory}"
|
|
66
|
-
description: "${a.description}"
|
|
67
|
-
system_prompt: |
|
|
59
|
+
.map((a) => ` - id: "${a.id}"
|
|
60
|
+
name: "${a.name}"
|
|
61
|
+
role: "${a.role}"
|
|
62
|
+
team: "${a.team}"
|
|
63
|
+
provider: "${a.provider}"
|
|
64
|
+
default_model: "${a.default_model}"
|
|
65
|
+
working_directory: "${a.working_directory}"
|
|
66
|
+
description: "${a.description}"
|
|
67
|
+
system_prompt: |
|
|
68
68
|
${escapeYamlBlock(a.system_prompt)}`)
|
|
69
69
|
.join('\n\n');
|
|
70
|
-
return `# CrewX Agents Configuration
|
|
71
|
-
# Generated by 'crewx init'
|
|
72
|
-
|
|
73
|
-
agents:
|
|
74
|
-
${agentBlocks}
|
|
75
|
-
|
|
76
|
-
# Usage examples:
|
|
77
|
-
# crewx query "@planner analyze this codebase"
|
|
78
|
-
# crewx execute "@developer implement the feature described above"
|
|
79
|
-
# crewx agent ls
|
|
70
|
+
return `# CrewX Agents Configuration
|
|
71
|
+
# Generated by 'crewx init'
|
|
72
|
+
|
|
73
|
+
agents:
|
|
74
|
+
${agentBlocks}
|
|
75
|
+
|
|
76
|
+
# Usage examples:
|
|
77
|
+
# crewx query "@planner analyze this codebase"
|
|
78
|
+
# crewx execute "@developer implement the feature described above"
|
|
79
|
+
# crewx agent ls
|
|
80
80
|
`;
|
|
81
81
|
}
|
|
82
82
|
/**
|