@hasna/todos 0.9.30 → 0.9.32
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/dist/cli/index.js +144 -6
- package/dist/index.js +101 -2
- package/dist/mcp/index.js +46 -4
- package/dist/server/index.js +138 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2188,6 +2188,13 @@ function ensureSchema(db) {
|
|
|
2188
2188
|
db.exec(sql);
|
|
2189
2189
|
} catch {}
|
|
2190
2190
|
};
|
|
2191
|
+
ensureTable("orgs", `
|
|
2192
|
+
CREATE TABLE orgs (
|
|
2193
|
+
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
2194
|
+
metadata TEXT DEFAULT '{}',
|
|
2195
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
2196
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
2197
|
+
)`);
|
|
2191
2198
|
ensureTable("agents", `
|
|
2192
2199
|
CREATE TABLE agents (
|
|
2193
2200
|
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
@@ -2254,6 +2261,10 @@ function ensureSchema(db) {
|
|
|
2254
2261
|
ensureColumn("agents", "role", "TEXT DEFAULT 'agent'");
|
|
2255
2262
|
ensureColumn("agents", "permissions", `TEXT DEFAULT '["*"]'`);
|
|
2256
2263
|
ensureColumn("agents", "reports_to", "TEXT");
|
|
2264
|
+
ensureColumn("agents", "title", "TEXT");
|
|
2265
|
+
ensureColumn("agents", "level", "TEXT");
|
|
2266
|
+
ensureColumn("agents", "org_id", "TEXT");
|
|
2267
|
+
ensureColumn("projects", "org_id", "TEXT");
|
|
2257
2268
|
ensureColumn("plans", "task_list_id", "TEXT");
|
|
2258
2269
|
ensureColumn("plans", "agent_id", "TEXT");
|
|
2259
2270
|
ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
|
|
@@ -2548,7 +2559,22 @@ var init_database = __esm(() => {
|
|
|
2548
2559
|
`,
|
|
2549
2560
|
`
|
|
2550
2561
|
ALTER TABLE agents ADD COLUMN reports_to TEXT;
|
|
2562
|
+
ALTER TABLE agents ADD COLUMN title TEXT;
|
|
2563
|
+
ALTER TABLE agents ADD COLUMN level TEXT;
|
|
2551
2564
|
INSERT OR IGNORE INTO _migrations (id) VALUES (11);
|
|
2565
|
+
`,
|
|
2566
|
+
`
|
|
2567
|
+
CREATE TABLE IF NOT EXISTS orgs (
|
|
2568
|
+
id TEXT PRIMARY KEY,
|
|
2569
|
+
name TEXT NOT NULL UNIQUE,
|
|
2570
|
+
description TEXT,
|
|
2571
|
+
metadata TEXT DEFAULT '{}',
|
|
2572
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
2573
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
2574
|
+
);
|
|
2575
|
+
ALTER TABLE agents ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
2576
|
+
ALTER TABLE projects ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
2577
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (12);
|
|
2552
2578
|
`
|
|
2553
2579
|
];
|
|
2554
2580
|
});
|
|
@@ -3393,14 +3419,17 @@ function registerAgent(input, db) {
|
|
|
3393
3419
|
}
|
|
3394
3420
|
const id = shortUuid();
|
|
3395
3421
|
const timestamp = now();
|
|
3396
|
-
d.run(`INSERT INTO agents (id, name, description, role, permissions, reports_to, metadata, created_at, last_seen_at)
|
|
3397
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
3422
|
+
d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, org_id, metadata, created_at, last_seen_at)
|
|
3423
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
3398
3424
|
id,
|
|
3399
3425
|
input.name,
|
|
3400
3426
|
input.description || null,
|
|
3401
3427
|
input.role || "agent",
|
|
3428
|
+
input.title || null,
|
|
3429
|
+
input.level || null,
|
|
3402
3430
|
JSON.stringify(input.permissions || ["*"]),
|
|
3403
3431
|
input.reports_to || null,
|
|
3432
|
+
input.org_id || null,
|
|
3404
3433
|
JSON.stringify(input.metadata || {}),
|
|
3405
3434
|
timestamp,
|
|
3406
3435
|
timestamp
|
|
@@ -3448,10 +3477,22 @@ function updateAgent(id, input, db) {
|
|
|
3448
3477
|
sets.push("permissions = ?");
|
|
3449
3478
|
params.push(JSON.stringify(input.permissions));
|
|
3450
3479
|
}
|
|
3480
|
+
if (input.title !== undefined) {
|
|
3481
|
+
sets.push("title = ?");
|
|
3482
|
+
params.push(input.title);
|
|
3483
|
+
}
|
|
3484
|
+
if (input.level !== undefined) {
|
|
3485
|
+
sets.push("level = ?");
|
|
3486
|
+
params.push(input.level);
|
|
3487
|
+
}
|
|
3451
3488
|
if (input.reports_to !== undefined) {
|
|
3452
3489
|
sets.push("reports_to = ?");
|
|
3453
3490
|
params.push(input.reports_to);
|
|
3454
3491
|
}
|
|
3492
|
+
if (input.org_id !== undefined) {
|
|
3493
|
+
sets.push("org_id = ?");
|
|
3494
|
+
params.push(input.org_id);
|
|
3495
|
+
}
|
|
3455
3496
|
if (input.metadata !== undefined) {
|
|
3456
3497
|
sets.push("metadata = ?");
|
|
3457
3498
|
params.push(JSON.stringify(input.metadata));
|
|
@@ -9241,8 +9282,9 @@ In Progress:`);
|
|
|
9241
9282
|
let render = function(nodes, indent = 0) {
|
|
9242
9283
|
return nodes.map((n) => {
|
|
9243
9284
|
const prefix = " ".repeat(indent);
|
|
9244
|
-
const
|
|
9245
|
-
const
|
|
9285
|
+
const title = n.agent.title ? ` \u2014 ${n.agent.title}` : "";
|
|
9286
|
+
const level = n.agent.level ? ` (${n.agent.level})` : "";
|
|
9287
|
+
const line = `${prefix}${n.agent.name}${title}${level}`;
|
|
9246
9288
|
const children = n.reports.length > 0 ? `
|
|
9247
9289
|
` + render(n.reports, indent + 1) : "";
|
|
9248
9290
|
return line + children;
|
|
@@ -9375,6 +9417,71 @@ In Progress:`);
|
|
|
9375
9417
|
});
|
|
9376
9418
|
});
|
|
9377
9419
|
|
|
9420
|
+
// src/db/orgs.ts
|
|
9421
|
+
var exports_orgs = {};
|
|
9422
|
+
__export(exports_orgs, {
|
|
9423
|
+
updateOrg: () => updateOrg,
|
|
9424
|
+
listOrgs: () => listOrgs,
|
|
9425
|
+
getOrgByName: () => getOrgByName,
|
|
9426
|
+
getOrg: () => getOrg,
|
|
9427
|
+
deleteOrg: () => deleteOrg,
|
|
9428
|
+
createOrg: () => createOrg
|
|
9429
|
+
});
|
|
9430
|
+
function rowToOrg(row) {
|
|
9431
|
+
return { ...row, metadata: JSON.parse(row.metadata || "{}") };
|
|
9432
|
+
}
|
|
9433
|
+
function createOrg(input, db) {
|
|
9434
|
+
const d = db || getDatabase();
|
|
9435
|
+
const id = uuid();
|
|
9436
|
+
const timestamp = now();
|
|
9437
|
+
d.run(`INSERT INTO orgs (id, name, description, metadata, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`, [id, input.name, input.description || null, JSON.stringify(input.metadata || {}), timestamp, timestamp]);
|
|
9438
|
+
return getOrg(id, d);
|
|
9439
|
+
}
|
|
9440
|
+
function getOrg(id, db) {
|
|
9441
|
+
const d = db || getDatabase();
|
|
9442
|
+
const row = d.query("SELECT * FROM orgs WHERE id = ?").get(id);
|
|
9443
|
+
return row ? rowToOrg(row) : null;
|
|
9444
|
+
}
|
|
9445
|
+
function getOrgByName(name, db) {
|
|
9446
|
+
const d = db || getDatabase();
|
|
9447
|
+
const row = d.query("SELECT * FROM orgs WHERE name = ?").get(name);
|
|
9448
|
+
return row ? rowToOrg(row) : null;
|
|
9449
|
+
}
|
|
9450
|
+
function listOrgs(db) {
|
|
9451
|
+
const d = db || getDatabase();
|
|
9452
|
+
return d.query("SELECT * FROM orgs ORDER BY name").all().map(rowToOrg);
|
|
9453
|
+
}
|
|
9454
|
+
function updateOrg(id, input, db) {
|
|
9455
|
+
const d = db || getDatabase();
|
|
9456
|
+
const org = getOrg(id, d);
|
|
9457
|
+
if (!org)
|
|
9458
|
+
throw new Error(`Org not found: ${id}`);
|
|
9459
|
+
const sets = ["updated_at = ?"];
|
|
9460
|
+
const params = [now()];
|
|
9461
|
+
if (input.name !== undefined) {
|
|
9462
|
+
sets.push("name = ?");
|
|
9463
|
+
params.push(input.name);
|
|
9464
|
+
}
|
|
9465
|
+
if (input.description !== undefined) {
|
|
9466
|
+
sets.push("description = ?");
|
|
9467
|
+
params.push(input.description);
|
|
9468
|
+
}
|
|
9469
|
+
if (input.metadata !== undefined) {
|
|
9470
|
+
sets.push("metadata = ?");
|
|
9471
|
+
params.push(JSON.stringify(input.metadata));
|
|
9472
|
+
}
|
|
9473
|
+
params.push(id);
|
|
9474
|
+
d.run(`UPDATE orgs SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
9475
|
+
return getOrg(id, d);
|
|
9476
|
+
}
|
|
9477
|
+
function deleteOrg(id, db) {
|
|
9478
|
+
const d = db || getDatabase();
|
|
9479
|
+
return d.run("DELETE FROM orgs WHERE id = ?", [id]).changes > 0;
|
|
9480
|
+
}
|
|
9481
|
+
var init_orgs = __esm(() => {
|
|
9482
|
+
init_database();
|
|
9483
|
+
});
|
|
9484
|
+
|
|
9378
9485
|
// src/server/serve.ts
|
|
9379
9486
|
var exports_serve = {};
|
|
9380
9487
|
__export(exports_serve, {
|
|
@@ -9731,6 +9838,36 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9731
9838
|
return json({ error: e instanceof Error ? e.message : "Failed to claim" }, 500, port);
|
|
9732
9839
|
}
|
|
9733
9840
|
}
|
|
9841
|
+
if (path === "/api/orgs" && method === "GET") {
|
|
9842
|
+
const { listOrgs: listOrgs2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
9843
|
+
return json(listOrgs2(), 200, port);
|
|
9844
|
+
}
|
|
9845
|
+
if (path === "/api/orgs" && method === "POST") {
|
|
9846
|
+
try {
|
|
9847
|
+
const body = await req.json();
|
|
9848
|
+
if (!body.name)
|
|
9849
|
+
return json({ error: "Missing name" }, 400, port);
|
|
9850
|
+
const { createOrg: createOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
9851
|
+
return json(createOrg2(body), 201, port);
|
|
9852
|
+
} catch (e) {
|
|
9853
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
9854
|
+
}
|
|
9855
|
+
}
|
|
9856
|
+
const orgMatch = path.match(/^\/api\/orgs\/([^/]+)$/);
|
|
9857
|
+
if (orgMatch && method === "PATCH") {
|
|
9858
|
+
try {
|
|
9859
|
+
const body = await req.json();
|
|
9860
|
+
const { updateOrg: updateOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
9861
|
+
return json(updateOrg2(orgMatch[1], body), 200, port);
|
|
9862
|
+
} catch (e) {
|
|
9863
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
if (orgMatch && method === "DELETE") {
|
|
9867
|
+
const { deleteOrg: deleteOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
9868
|
+
const deleted = deleteOrg2(orgMatch[1]);
|
|
9869
|
+
return json(deleted ? { success: true } : { error: "Not found" }, deleted ? 200 : 404, port);
|
|
9870
|
+
}
|
|
9734
9871
|
if (path === "/api/org" && method === "GET") {
|
|
9735
9872
|
const { getOrgChart: getOrgChart2 } = await Promise.resolve().then(() => (init_agents(), exports_agents));
|
|
9736
9873
|
return json(getOrgChart2(), 200, port);
|
|
@@ -12318,8 +12455,9 @@ program2.command("org").description("Show agent org chart \u2014 who reports to
|
|
|
12318
12455
|
function render2(nodes, indent = 0) {
|
|
12319
12456
|
for (const n of nodes) {
|
|
12320
12457
|
const prefix = " ".repeat(indent);
|
|
12321
|
-
const
|
|
12322
|
-
|
|
12458
|
+
const title = n.agent.title ? chalk.cyan(` \u2014 ${n.agent.title}`) : "";
|
|
12459
|
+
const level = n.agent.level ? chalk.dim(` (${n.agent.level})`) : "";
|
|
12460
|
+
console.log(`${prefix}${indent > 0 ? "\u251C\u2500\u2500 " : ""}${chalk.bold(n.agent.name)}${title}${level}`);
|
|
12323
12461
|
render2(n.reports, indent + 1);
|
|
12324
12462
|
}
|
|
12325
12463
|
}
|
package/dist/index.js
CHANGED
|
@@ -267,7 +267,22 @@ var MIGRATIONS = [
|
|
|
267
267
|
`,
|
|
268
268
|
`
|
|
269
269
|
ALTER TABLE agents ADD COLUMN reports_to TEXT;
|
|
270
|
+
ALTER TABLE agents ADD COLUMN title TEXT;
|
|
271
|
+
ALTER TABLE agents ADD COLUMN level TEXT;
|
|
270
272
|
INSERT OR IGNORE INTO _migrations (id) VALUES (11);
|
|
273
|
+
`,
|
|
274
|
+
`
|
|
275
|
+
CREATE TABLE IF NOT EXISTS orgs (
|
|
276
|
+
id TEXT PRIMARY KEY,
|
|
277
|
+
name TEXT NOT NULL UNIQUE,
|
|
278
|
+
description TEXT,
|
|
279
|
+
metadata TEXT DEFAULT '{}',
|
|
280
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
281
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
282
|
+
);
|
|
283
|
+
ALTER TABLE agents ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
284
|
+
ALTER TABLE projects ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
285
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (12);
|
|
271
286
|
`
|
|
272
287
|
];
|
|
273
288
|
var _db = null;
|
|
@@ -324,6 +339,13 @@ function ensureSchema(db) {
|
|
|
324
339
|
db.exec(sql);
|
|
325
340
|
} catch {}
|
|
326
341
|
};
|
|
342
|
+
ensureTable("orgs", `
|
|
343
|
+
CREATE TABLE orgs (
|
|
344
|
+
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
345
|
+
metadata TEXT DEFAULT '{}',
|
|
346
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
347
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
348
|
+
)`);
|
|
327
349
|
ensureTable("agents", `
|
|
328
350
|
CREATE TABLE agents (
|
|
329
351
|
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
@@ -390,6 +412,10 @@ function ensureSchema(db) {
|
|
|
390
412
|
ensureColumn("agents", "role", "TEXT DEFAULT 'agent'");
|
|
391
413
|
ensureColumn("agents", "permissions", `TEXT DEFAULT '["*"]'`);
|
|
392
414
|
ensureColumn("agents", "reports_to", "TEXT");
|
|
415
|
+
ensureColumn("agents", "title", "TEXT");
|
|
416
|
+
ensureColumn("agents", "level", "TEXT");
|
|
417
|
+
ensureColumn("agents", "org_id", "TEXT");
|
|
418
|
+
ensureColumn("projects", "org_id", "TEXT");
|
|
393
419
|
ensureColumn("plans", "task_list_id", "TEXT");
|
|
394
420
|
ensureColumn("plans", "agent_id", "TEXT");
|
|
395
421
|
ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
|
|
@@ -1393,14 +1419,17 @@ function registerAgent(input, db) {
|
|
|
1393
1419
|
}
|
|
1394
1420
|
const id = shortUuid();
|
|
1395
1421
|
const timestamp = now();
|
|
1396
|
-
d.run(`INSERT INTO agents (id, name, description, role, permissions, reports_to, metadata, created_at, last_seen_at)
|
|
1397
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
1422
|
+
d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, org_id, metadata, created_at, last_seen_at)
|
|
1423
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
1398
1424
|
id,
|
|
1399
1425
|
input.name,
|
|
1400
1426
|
input.description || null,
|
|
1401
1427
|
input.role || "agent",
|
|
1428
|
+
input.title || null,
|
|
1429
|
+
input.level || null,
|
|
1402
1430
|
JSON.stringify(input.permissions || ["*"]),
|
|
1403
1431
|
input.reports_to || null,
|
|
1432
|
+
input.org_id || null,
|
|
1404
1433
|
JSON.stringify(input.metadata || {}),
|
|
1405
1434
|
timestamp,
|
|
1406
1435
|
timestamp
|
|
@@ -1448,10 +1477,22 @@ function updateAgent(id, input, db) {
|
|
|
1448
1477
|
sets.push("permissions = ?");
|
|
1449
1478
|
params.push(JSON.stringify(input.permissions));
|
|
1450
1479
|
}
|
|
1480
|
+
if (input.title !== undefined) {
|
|
1481
|
+
sets.push("title = ?");
|
|
1482
|
+
params.push(input.title);
|
|
1483
|
+
}
|
|
1484
|
+
if (input.level !== undefined) {
|
|
1485
|
+
sets.push("level = ?");
|
|
1486
|
+
params.push(input.level);
|
|
1487
|
+
}
|
|
1451
1488
|
if (input.reports_to !== undefined) {
|
|
1452
1489
|
sets.push("reports_to = ?");
|
|
1453
1490
|
params.push(input.reports_to);
|
|
1454
1491
|
}
|
|
1492
|
+
if (input.org_id !== undefined) {
|
|
1493
|
+
sets.push("org_id = ?");
|
|
1494
|
+
params.push(input.org_id);
|
|
1495
|
+
}
|
|
1455
1496
|
if (input.metadata !== undefined) {
|
|
1456
1497
|
sets.push("metadata = ?");
|
|
1457
1498
|
params.push(JSON.stringify(input.metadata));
|
|
@@ -1699,6 +1740,58 @@ function taskFromTemplate(templateId, overrides = {}, db) {
|
|
|
1699
1740
|
...overrides
|
|
1700
1741
|
};
|
|
1701
1742
|
}
|
|
1743
|
+
// src/db/orgs.ts
|
|
1744
|
+
function rowToOrg(row) {
|
|
1745
|
+
return { ...row, metadata: JSON.parse(row.metadata || "{}") };
|
|
1746
|
+
}
|
|
1747
|
+
function createOrg(input, db) {
|
|
1748
|
+
const d = db || getDatabase();
|
|
1749
|
+
const id = uuid();
|
|
1750
|
+
const timestamp = now();
|
|
1751
|
+
d.run(`INSERT INTO orgs (id, name, description, metadata, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`, [id, input.name, input.description || null, JSON.stringify(input.metadata || {}), timestamp, timestamp]);
|
|
1752
|
+
return getOrg(id, d);
|
|
1753
|
+
}
|
|
1754
|
+
function getOrg(id, db) {
|
|
1755
|
+
const d = db || getDatabase();
|
|
1756
|
+
const row = d.query("SELECT * FROM orgs WHERE id = ?").get(id);
|
|
1757
|
+
return row ? rowToOrg(row) : null;
|
|
1758
|
+
}
|
|
1759
|
+
function getOrgByName(name, db) {
|
|
1760
|
+
const d = db || getDatabase();
|
|
1761
|
+
const row = d.query("SELECT * FROM orgs WHERE name = ?").get(name);
|
|
1762
|
+
return row ? rowToOrg(row) : null;
|
|
1763
|
+
}
|
|
1764
|
+
function listOrgs(db) {
|
|
1765
|
+
const d = db || getDatabase();
|
|
1766
|
+
return d.query("SELECT * FROM orgs ORDER BY name").all().map(rowToOrg);
|
|
1767
|
+
}
|
|
1768
|
+
function updateOrg(id, input, db) {
|
|
1769
|
+
const d = db || getDatabase();
|
|
1770
|
+
const org = getOrg(id, d);
|
|
1771
|
+
if (!org)
|
|
1772
|
+
throw new Error(`Org not found: ${id}`);
|
|
1773
|
+
const sets = ["updated_at = ?"];
|
|
1774
|
+
const params = [now()];
|
|
1775
|
+
if (input.name !== undefined) {
|
|
1776
|
+
sets.push("name = ?");
|
|
1777
|
+
params.push(input.name);
|
|
1778
|
+
}
|
|
1779
|
+
if (input.description !== undefined) {
|
|
1780
|
+
sets.push("description = ?");
|
|
1781
|
+
params.push(input.description);
|
|
1782
|
+
}
|
|
1783
|
+
if (input.metadata !== undefined) {
|
|
1784
|
+
sets.push("metadata = ?");
|
|
1785
|
+
params.push(JSON.stringify(input.metadata));
|
|
1786
|
+
}
|
|
1787
|
+
params.push(id);
|
|
1788
|
+
d.run(`UPDATE orgs SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
1789
|
+
return getOrg(id, d);
|
|
1790
|
+
}
|
|
1791
|
+
function deleteOrg(id, db) {
|
|
1792
|
+
const d = db || getDatabase();
|
|
1793
|
+
return d.run("DELETE FROM orgs WHERE id = ?", [id]).changes > 0;
|
|
1794
|
+
}
|
|
1702
1795
|
// src/lib/search.ts
|
|
1703
1796
|
function rowToTask2(row) {
|
|
1704
1797
|
return {
|
|
@@ -2252,6 +2345,7 @@ export {
|
|
|
2252
2345
|
updateSessionActivity,
|
|
2253
2346
|
updateProject,
|
|
2254
2347
|
updatePlan,
|
|
2348
|
+
updateOrg,
|
|
2255
2349
|
updateAgentActivity,
|
|
2256
2350
|
updateAgent,
|
|
2257
2351
|
unlockTask,
|
|
@@ -2277,6 +2371,7 @@ export {
|
|
|
2277
2371
|
listSessions,
|
|
2278
2372
|
listProjects,
|
|
2279
2373
|
listPlans,
|
|
2374
|
+
listOrgs,
|
|
2280
2375
|
listComments,
|
|
2281
2376
|
listAgents,
|
|
2282
2377
|
getWebhook,
|
|
@@ -2294,6 +2389,8 @@ export {
|
|
|
2294
2389
|
getProject,
|
|
2295
2390
|
getPlan,
|
|
2296
2391
|
getOrgChart,
|
|
2392
|
+
getOrgByName,
|
|
2393
|
+
getOrg,
|
|
2297
2394
|
getDirectReports,
|
|
2298
2395
|
getDatabase,
|
|
2299
2396
|
getCompletionGuardConfig,
|
|
@@ -2311,6 +2408,7 @@ export {
|
|
|
2311
2408
|
deleteSession,
|
|
2312
2409
|
deleteProject,
|
|
2313
2410
|
deletePlan,
|
|
2411
|
+
deleteOrg,
|
|
2314
2412
|
deleteComment,
|
|
2315
2413
|
deleteAgent,
|
|
2316
2414
|
defaultSyncAgents,
|
|
@@ -2321,6 +2419,7 @@ export {
|
|
|
2321
2419
|
createSession,
|
|
2322
2420
|
createProject,
|
|
2323
2421
|
createPlan,
|
|
2422
|
+
createOrg,
|
|
2324
2423
|
completeTask,
|
|
2325
2424
|
closeDatabase,
|
|
2326
2425
|
checkCompletionGuard,
|
package/dist/mcp/index.js
CHANGED
|
@@ -122,6 +122,13 @@ function ensureSchema(db) {
|
|
|
122
122
|
db.exec(sql);
|
|
123
123
|
} catch {}
|
|
124
124
|
};
|
|
125
|
+
ensureTable("orgs", `
|
|
126
|
+
CREATE TABLE orgs (
|
|
127
|
+
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
128
|
+
metadata TEXT DEFAULT '{}',
|
|
129
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
130
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
131
|
+
)`);
|
|
125
132
|
ensureTable("agents", `
|
|
126
133
|
CREATE TABLE agents (
|
|
127
134
|
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
@@ -188,6 +195,10 @@ function ensureSchema(db) {
|
|
|
188
195
|
ensureColumn("agents", "role", "TEXT DEFAULT 'agent'");
|
|
189
196
|
ensureColumn("agents", "permissions", `TEXT DEFAULT '["*"]'`);
|
|
190
197
|
ensureColumn("agents", "reports_to", "TEXT");
|
|
198
|
+
ensureColumn("agents", "title", "TEXT");
|
|
199
|
+
ensureColumn("agents", "level", "TEXT");
|
|
200
|
+
ensureColumn("agents", "org_id", "TEXT");
|
|
201
|
+
ensureColumn("projects", "org_id", "TEXT");
|
|
191
202
|
ensureColumn("plans", "task_list_id", "TEXT");
|
|
192
203
|
ensureColumn("plans", "agent_id", "TEXT");
|
|
193
204
|
ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
|
|
@@ -482,7 +493,22 @@ var init_database = __esm(() => {
|
|
|
482
493
|
`,
|
|
483
494
|
`
|
|
484
495
|
ALTER TABLE agents ADD COLUMN reports_to TEXT;
|
|
496
|
+
ALTER TABLE agents ADD COLUMN title TEXT;
|
|
497
|
+
ALTER TABLE agents ADD COLUMN level TEXT;
|
|
485
498
|
INSERT OR IGNORE INTO _migrations (id) VALUES (11);
|
|
499
|
+
`,
|
|
500
|
+
`
|
|
501
|
+
CREATE TABLE IF NOT EXISTS orgs (
|
|
502
|
+
id TEXT PRIMARY KEY,
|
|
503
|
+
name TEXT NOT NULL UNIQUE,
|
|
504
|
+
description TEXT,
|
|
505
|
+
metadata TEXT DEFAULT '{}',
|
|
506
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
507
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
508
|
+
);
|
|
509
|
+
ALTER TABLE agents ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
510
|
+
ALTER TABLE projects ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
511
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (12);
|
|
486
512
|
`
|
|
487
513
|
];
|
|
488
514
|
});
|
|
@@ -546,14 +572,17 @@ function registerAgent(input, db) {
|
|
|
546
572
|
}
|
|
547
573
|
const id = shortUuid();
|
|
548
574
|
const timestamp = now();
|
|
549
|
-
d.run(`INSERT INTO agents (id, name, description, role, permissions, reports_to, metadata, created_at, last_seen_at)
|
|
550
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
575
|
+
d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, org_id, metadata, created_at, last_seen_at)
|
|
576
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
551
577
|
id,
|
|
552
578
|
input.name,
|
|
553
579
|
input.description || null,
|
|
554
580
|
input.role || "agent",
|
|
581
|
+
input.title || null,
|
|
582
|
+
input.level || null,
|
|
555
583
|
JSON.stringify(input.permissions || ["*"]),
|
|
556
584
|
input.reports_to || null,
|
|
585
|
+
input.org_id || null,
|
|
557
586
|
JSON.stringify(input.metadata || {}),
|
|
558
587
|
timestamp,
|
|
559
588
|
timestamp
|
|
@@ -601,10 +630,22 @@ function updateAgent(id, input, db) {
|
|
|
601
630
|
sets.push("permissions = ?");
|
|
602
631
|
params.push(JSON.stringify(input.permissions));
|
|
603
632
|
}
|
|
633
|
+
if (input.title !== undefined) {
|
|
634
|
+
sets.push("title = ?");
|
|
635
|
+
params.push(input.title);
|
|
636
|
+
}
|
|
637
|
+
if (input.level !== undefined) {
|
|
638
|
+
sets.push("level = ?");
|
|
639
|
+
params.push(input.level);
|
|
640
|
+
}
|
|
604
641
|
if (input.reports_to !== undefined) {
|
|
605
642
|
sets.push("reports_to = ?");
|
|
606
643
|
params.push(input.reports_to);
|
|
607
644
|
}
|
|
645
|
+
if (input.org_id !== undefined) {
|
|
646
|
+
sets.push("org_id = ?");
|
|
647
|
+
params.push(input.org_id);
|
|
648
|
+
}
|
|
608
649
|
if (input.metadata !== undefined) {
|
|
609
650
|
sets.push("metadata = ?");
|
|
610
651
|
params.push(JSON.stringify(input.metadata));
|
|
@@ -7061,8 +7102,9 @@ server.tool("get_org_chart", "Get agent org chart \u2014 who reports to who.", {
|
|
|
7061
7102
|
let render = function(nodes, indent = 0) {
|
|
7062
7103
|
return nodes.map((n) => {
|
|
7063
7104
|
const prefix = " ".repeat(indent);
|
|
7064
|
-
const
|
|
7065
|
-
const
|
|
7105
|
+
const title = n.agent.title ? ` \u2014 ${n.agent.title}` : "";
|
|
7106
|
+
const level = n.agent.level ? ` (${n.agent.level})` : "";
|
|
7107
|
+
const line = `${prefix}${n.agent.name}${title}${level}`;
|
|
7066
7108
|
const children = n.reports.length > 0 ? `
|
|
7067
7109
|
` + render(n.reports, indent + 1) : "";
|
|
7068
7110
|
return line + children;
|
package/dist/server/index.js
CHANGED
|
@@ -184,6 +184,13 @@ function ensureSchema(db) {
|
|
|
184
184
|
db.exec(sql);
|
|
185
185
|
} catch {}
|
|
186
186
|
};
|
|
187
|
+
ensureTable("orgs", `
|
|
188
|
+
CREATE TABLE orgs (
|
|
189
|
+
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
190
|
+
metadata TEXT DEFAULT '{}',
|
|
191
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
192
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
193
|
+
)`);
|
|
187
194
|
ensureTable("agents", `
|
|
188
195
|
CREATE TABLE agents (
|
|
189
196
|
id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
|
|
@@ -250,6 +257,10 @@ function ensureSchema(db) {
|
|
|
250
257
|
ensureColumn("agents", "role", "TEXT DEFAULT 'agent'");
|
|
251
258
|
ensureColumn("agents", "permissions", `TEXT DEFAULT '["*"]'`);
|
|
252
259
|
ensureColumn("agents", "reports_to", "TEXT");
|
|
260
|
+
ensureColumn("agents", "title", "TEXT");
|
|
261
|
+
ensureColumn("agents", "level", "TEXT");
|
|
262
|
+
ensureColumn("agents", "org_id", "TEXT");
|
|
263
|
+
ensureColumn("projects", "org_id", "TEXT");
|
|
253
264
|
ensureColumn("plans", "task_list_id", "TEXT");
|
|
254
265
|
ensureColumn("plans", "agent_id", "TEXT");
|
|
255
266
|
ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
|
|
@@ -530,7 +541,22 @@ var init_database = __esm(() => {
|
|
|
530
541
|
`,
|
|
531
542
|
`
|
|
532
543
|
ALTER TABLE agents ADD COLUMN reports_to TEXT;
|
|
544
|
+
ALTER TABLE agents ADD COLUMN title TEXT;
|
|
545
|
+
ALTER TABLE agents ADD COLUMN level TEXT;
|
|
533
546
|
INSERT OR IGNORE INTO _migrations (id) VALUES (11);
|
|
547
|
+
`,
|
|
548
|
+
`
|
|
549
|
+
CREATE TABLE IF NOT EXISTS orgs (
|
|
550
|
+
id TEXT PRIMARY KEY,
|
|
551
|
+
name TEXT NOT NULL UNIQUE,
|
|
552
|
+
description TEXT,
|
|
553
|
+
metadata TEXT DEFAULT '{}',
|
|
554
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
555
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
556
|
+
);
|
|
557
|
+
ALTER TABLE agents ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
558
|
+
ALTER TABLE projects ADD COLUMN org_id TEXT REFERENCES orgs(id) ON DELETE SET NULL;
|
|
559
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (12);
|
|
534
560
|
`
|
|
535
561
|
];
|
|
536
562
|
});
|
|
@@ -710,14 +736,17 @@ function registerAgent(input, db) {
|
|
|
710
736
|
}
|
|
711
737
|
const id = shortUuid();
|
|
712
738
|
const timestamp = now();
|
|
713
|
-
d.run(`INSERT INTO agents (id, name, description, role, permissions, reports_to, metadata, created_at, last_seen_at)
|
|
714
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
739
|
+
d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, org_id, metadata, created_at, last_seen_at)
|
|
740
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
715
741
|
id,
|
|
716
742
|
input.name,
|
|
717
743
|
input.description || null,
|
|
718
744
|
input.role || "agent",
|
|
745
|
+
input.title || null,
|
|
746
|
+
input.level || null,
|
|
719
747
|
JSON.stringify(input.permissions || ["*"]),
|
|
720
748
|
input.reports_to || null,
|
|
749
|
+
input.org_id || null,
|
|
721
750
|
JSON.stringify(input.metadata || {}),
|
|
722
751
|
timestamp,
|
|
723
752
|
timestamp
|
|
@@ -765,10 +794,22 @@ function updateAgent(id, input, db) {
|
|
|
765
794
|
sets.push("permissions = ?");
|
|
766
795
|
params.push(JSON.stringify(input.permissions));
|
|
767
796
|
}
|
|
797
|
+
if (input.title !== undefined) {
|
|
798
|
+
sets.push("title = ?");
|
|
799
|
+
params.push(input.title);
|
|
800
|
+
}
|
|
801
|
+
if (input.level !== undefined) {
|
|
802
|
+
sets.push("level = ?");
|
|
803
|
+
params.push(input.level);
|
|
804
|
+
}
|
|
768
805
|
if (input.reports_to !== undefined) {
|
|
769
806
|
sets.push("reports_to = ?");
|
|
770
807
|
params.push(input.reports_to);
|
|
771
808
|
}
|
|
809
|
+
if (input.org_id !== undefined) {
|
|
810
|
+
sets.push("org_id = ?");
|
|
811
|
+
params.push(input.org_id);
|
|
812
|
+
}
|
|
772
813
|
if (input.metadata !== undefined) {
|
|
773
814
|
sets.push("metadata = ?");
|
|
774
815
|
params.push(JSON.stringify(input.metadata));
|
|
@@ -804,6 +845,71 @@ var init_agents = __esm(() => {
|
|
|
804
845
|
init_database();
|
|
805
846
|
});
|
|
806
847
|
|
|
848
|
+
// src/db/orgs.ts
|
|
849
|
+
var exports_orgs = {};
|
|
850
|
+
__export(exports_orgs, {
|
|
851
|
+
updateOrg: () => updateOrg,
|
|
852
|
+
listOrgs: () => listOrgs,
|
|
853
|
+
getOrgByName: () => getOrgByName,
|
|
854
|
+
getOrg: () => getOrg,
|
|
855
|
+
deleteOrg: () => deleteOrg,
|
|
856
|
+
createOrg: () => createOrg
|
|
857
|
+
});
|
|
858
|
+
function rowToOrg(row) {
|
|
859
|
+
return { ...row, metadata: JSON.parse(row.metadata || "{}") };
|
|
860
|
+
}
|
|
861
|
+
function createOrg(input, db) {
|
|
862
|
+
const d = db || getDatabase();
|
|
863
|
+
const id = uuid();
|
|
864
|
+
const timestamp = now();
|
|
865
|
+
d.run(`INSERT INTO orgs (id, name, description, metadata, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`, [id, input.name, input.description || null, JSON.stringify(input.metadata || {}), timestamp, timestamp]);
|
|
866
|
+
return getOrg(id, d);
|
|
867
|
+
}
|
|
868
|
+
function getOrg(id, db) {
|
|
869
|
+
const d = db || getDatabase();
|
|
870
|
+
const row = d.query("SELECT * FROM orgs WHERE id = ?").get(id);
|
|
871
|
+
return row ? rowToOrg(row) : null;
|
|
872
|
+
}
|
|
873
|
+
function getOrgByName(name, db) {
|
|
874
|
+
const d = db || getDatabase();
|
|
875
|
+
const row = d.query("SELECT * FROM orgs WHERE name = ?").get(name);
|
|
876
|
+
return row ? rowToOrg(row) : null;
|
|
877
|
+
}
|
|
878
|
+
function listOrgs(db) {
|
|
879
|
+
const d = db || getDatabase();
|
|
880
|
+
return d.query("SELECT * FROM orgs ORDER BY name").all().map(rowToOrg);
|
|
881
|
+
}
|
|
882
|
+
function updateOrg(id, input, db) {
|
|
883
|
+
const d = db || getDatabase();
|
|
884
|
+
const org = getOrg(id, d);
|
|
885
|
+
if (!org)
|
|
886
|
+
throw new Error(`Org not found: ${id}`);
|
|
887
|
+
const sets = ["updated_at = ?"];
|
|
888
|
+
const params = [now()];
|
|
889
|
+
if (input.name !== undefined) {
|
|
890
|
+
sets.push("name = ?");
|
|
891
|
+
params.push(input.name);
|
|
892
|
+
}
|
|
893
|
+
if (input.description !== undefined) {
|
|
894
|
+
sets.push("description = ?");
|
|
895
|
+
params.push(input.description);
|
|
896
|
+
}
|
|
897
|
+
if (input.metadata !== undefined) {
|
|
898
|
+
sets.push("metadata = ?");
|
|
899
|
+
params.push(JSON.stringify(input.metadata));
|
|
900
|
+
}
|
|
901
|
+
params.push(id);
|
|
902
|
+
d.run(`UPDATE orgs SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
903
|
+
return getOrg(id, d);
|
|
904
|
+
}
|
|
905
|
+
function deleteOrg(id, db) {
|
|
906
|
+
const d = db || getDatabase();
|
|
907
|
+
return d.run("DELETE FROM orgs WHERE id = ?", [id]).changes > 0;
|
|
908
|
+
}
|
|
909
|
+
var init_orgs = __esm(() => {
|
|
910
|
+
init_database();
|
|
911
|
+
});
|
|
912
|
+
|
|
807
913
|
// src/db/webhooks.ts
|
|
808
914
|
var exports_webhooks = {};
|
|
809
915
|
__export(exports_webhooks, {
|
|
@@ -1782,6 +1888,36 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
1782
1888
|
return json({ error: e instanceof Error ? e.message : "Failed to claim" }, 500, port);
|
|
1783
1889
|
}
|
|
1784
1890
|
}
|
|
1891
|
+
if (path === "/api/orgs" && method === "GET") {
|
|
1892
|
+
const { listOrgs: listOrgs2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
1893
|
+
return json(listOrgs2(), 200, port);
|
|
1894
|
+
}
|
|
1895
|
+
if (path === "/api/orgs" && method === "POST") {
|
|
1896
|
+
try {
|
|
1897
|
+
const body = await req.json();
|
|
1898
|
+
if (!body.name)
|
|
1899
|
+
return json({ error: "Missing name" }, 400, port);
|
|
1900
|
+
const { createOrg: createOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
1901
|
+
return json(createOrg2(body), 201, port);
|
|
1902
|
+
} catch (e) {
|
|
1903
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
const orgMatch = path.match(/^\/api\/orgs\/([^/]+)$/);
|
|
1907
|
+
if (orgMatch && method === "PATCH") {
|
|
1908
|
+
try {
|
|
1909
|
+
const body = await req.json();
|
|
1910
|
+
const { updateOrg: updateOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
1911
|
+
return json(updateOrg2(orgMatch[1], body), 200, port);
|
|
1912
|
+
} catch (e) {
|
|
1913
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
if (orgMatch && method === "DELETE") {
|
|
1917
|
+
const { deleteOrg: deleteOrg2 } = await Promise.resolve().then(() => (init_orgs(), exports_orgs));
|
|
1918
|
+
const deleted = deleteOrg2(orgMatch[1]);
|
|
1919
|
+
return json(deleted ? { success: true } : { error: "Not found" }, deleted ? 200 : 404, port);
|
|
1920
|
+
}
|
|
1785
1921
|
if (path === "/api/org" && method === "GET") {
|
|
1786
1922
|
const { getOrgChart: getOrgChart2 } = await Promise.resolve().then(() => (init_agents(), exports_agents));
|
|
1787
1923
|
return json(getOrgChart2(), 200, port);
|