@hasna/todos 0.9.31 → 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 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,
@@ -2256,6 +2263,8 @@ function ensureSchema(db) {
2256
2263
  ensureColumn("agents", "reports_to", "TEXT");
2257
2264
  ensureColumn("agents", "title", "TEXT");
2258
2265
  ensureColumn("agents", "level", "TEXT");
2266
+ ensureColumn("agents", "org_id", "TEXT");
2267
+ ensureColumn("projects", "org_id", "TEXT");
2259
2268
  ensureColumn("plans", "task_list_id", "TEXT");
2260
2269
  ensureColumn("plans", "agent_id", "TEXT");
2261
2270
  ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
@@ -2553,6 +2562,19 @@ var init_database = __esm(() => {
2553
2562
  ALTER TABLE agents ADD COLUMN title TEXT;
2554
2563
  ALTER TABLE agents ADD COLUMN level TEXT;
2555
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);
2556
2578
  `
2557
2579
  ];
2558
2580
  });
@@ -3397,8 +3419,8 @@ function registerAgent(input, db) {
3397
3419
  }
3398
3420
  const id = shortUuid();
3399
3421
  const timestamp = now();
3400
- d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, metadata, created_at, last_seen_at)
3401
- 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
3402
3424
  id,
3403
3425
  input.name,
3404
3426
  input.description || null,
@@ -3407,6 +3429,7 @@ function registerAgent(input, db) {
3407
3429
  input.level || null,
3408
3430
  JSON.stringify(input.permissions || ["*"]),
3409
3431
  input.reports_to || null,
3432
+ input.org_id || null,
3410
3433
  JSON.stringify(input.metadata || {}),
3411
3434
  timestamp,
3412
3435
  timestamp
@@ -3466,6 +3489,10 @@ function updateAgent(id, input, db) {
3466
3489
  sets.push("reports_to = ?");
3467
3490
  params.push(input.reports_to);
3468
3491
  }
3492
+ if (input.org_id !== undefined) {
3493
+ sets.push("org_id = ?");
3494
+ params.push(input.org_id);
3495
+ }
3469
3496
  if (input.metadata !== undefined) {
3470
3497
  sets.push("metadata = ?");
3471
3498
  params.push(JSON.stringify(input.metadata));
@@ -9390,6 +9417,71 @@ In Progress:`);
9390
9417
  });
9391
9418
  });
9392
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
+
9393
9485
  // src/server/serve.ts
9394
9486
  var exports_serve = {};
9395
9487
  __export(exports_serve, {
@@ -9746,6 +9838,36 @@ Dashboard not found at: ${dashboardDir}`);
9746
9838
  return json({ error: e instanceof Error ? e.message : "Failed to claim" }, 500, port);
9747
9839
  }
9748
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
+ }
9749
9871
  if (path === "/api/org" && method === "GET") {
9750
9872
  const { getOrgChart: getOrgChart2 } = await Promise.resolve().then(() => (init_agents(), exports_agents));
9751
9873
  return json(getOrgChart2(), 200, port);
package/dist/index.js CHANGED
@@ -270,6 +270,19 @@ var MIGRATIONS = [
270
270
  ALTER TABLE agents ADD COLUMN title TEXT;
271
271
  ALTER TABLE agents ADD COLUMN level TEXT;
272
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);
273
286
  `
274
287
  ];
275
288
  var _db = null;
@@ -326,6 +339,13 @@ function ensureSchema(db) {
326
339
  db.exec(sql);
327
340
  } catch {}
328
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
+ )`);
329
349
  ensureTable("agents", `
330
350
  CREATE TABLE agents (
331
351
  id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
@@ -394,6 +414,8 @@ function ensureSchema(db) {
394
414
  ensureColumn("agents", "reports_to", "TEXT");
395
415
  ensureColumn("agents", "title", "TEXT");
396
416
  ensureColumn("agents", "level", "TEXT");
417
+ ensureColumn("agents", "org_id", "TEXT");
418
+ ensureColumn("projects", "org_id", "TEXT");
397
419
  ensureColumn("plans", "task_list_id", "TEXT");
398
420
  ensureColumn("plans", "agent_id", "TEXT");
399
421
  ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
@@ -1397,8 +1419,8 @@ function registerAgent(input, db) {
1397
1419
  }
1398
1420
  const id = shortUuid();
1399
1421
  const timestamp = now();
1400
- d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, metadata, created_at, last_seen_at)
1401
- 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
1402
1424
  id,
1403
1425
  input.name,
1404
1426
  input.description || null,
@@ -1407,6 +1429,7 @@ function registerAgent(input, db) {
1407
1429
  input.level || null,
1408
1430
  JSON.stringify(input.permissions || ["*"]),
1409
1431
  input.reports_to || null,
1432
+ input.org_id || null,
1410
1433
  JSON.stringify(input.metadata || {}),
1411
1434
  timestamp,
1412
1435
  timestamp
@@ -1466,6 +1489,10 @@ function updateAgent(id, input, db) {
1466
1489
  sets.push("reports_to = ?");
1467
1490
  params.push(input.reports_to);
1468
1491
  }
1492
+ if (input.org_id !== undefined) {
1493
+ sets.push("org_id = ?");
1494
+ params.push(input.org_id);
1495
+ }
1469
1496
  if (input.metadata !== undefined) {
1470
1497
  sets.push("metadata = ?");
1471
1498
  params.push(JSON.stringify(input.metadata));
@@ -1713,6 +1740,58 @@ function taskFromTemplate(templateId, overrides = {}, db) {
1713
1740
  ...overrides
1714
1741
  };
1715
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
+ }
1716
1795
  // src/lib/search.ts
1717
1796
  function rowToTask2(row) {
1718
1797
  return {
@@ -2266,6 +2345,7 @@ export {
2266
2345
  updateSessionActivity,
2267
2346
  updateProject,
2268
2347
  updatePlan,
2348
+ updateOrg,
2269
2349
  updateAgentActivity,
2270
2350
  updateAgent,
2271
2351
  unlockTask,
@@ -2291,6 +2371,7 @@ export {
2291
2371
  listSessions,
2292
2372
  listProjects,
2293
2373
  listPlans,
2374
+ listOrgs,
2294
2375
  listComments,
2295
2376
  listAgents,
2296
2377
  getWebhook,
@@ -2308,6 +2389,8 @@ export {
2308
2389
  getProject,
2309
2390
  getPlan,
2310
2391
  getOrgChart,
2392
+ getOrgByName,
2393
+ getOrg,
2311
2394
  getDirectReports,
2312
2395
  getDatabase,
2313
2396
  getCompletionGuardConfig,
@@ -2325,6 +2408,7 @@ export {
2325
2408
  deleteSession,
2326
2409
  deleteProject,
2327
2410
  deletePlan,
2411
+ deleteOrg,
2328
2412
  deleteComment,
2329
2413
  deleteAgent,
2330
2414
  defaultSyncAgents,
@@ -2335,6 +2419,7 @@ export {
2335
2419
  createSession,
2336
2420
  createProject,
2337
2421
  createPlan,
2422
+ createOrg,
2338
2423
  completeTask,
2339
2424
  closeDatabase,
2340
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,
@@ -190,6 +197,8 @@ function ensureSchema(db) {
190
197
  ensureColumn("agents", "reports_to", "TEXT");
191
198
  ensureColumn("agents", "title", "TEXT");
192
199
  ensureColumn("agents", "level", "TEXT");
200
+ ensureColumn("agents", "org_id", "TEXT");
201
+ ensureColumn("projects", "org_id", "TEXT");
193
202
  ensureColumn("plans", "task_list_id", "TEXT");
194
203
  ensureColumn("plans", "agent_id", "TEXT");
195
204
  ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
@@ -487,6 +496,19 @@ var init_database = __esm(() => {
487
496
  ALTER TABLE agents ADD COLUMN title TEXT;
488
497
  ALTER TABLE agents ADD COLUMN level TEXT;
489
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);
490
512
  `
491
513
  ];
492
514
  });
@@ -550,8 +572,8 @@ function registerAgent(input, db) {
550
572
  }
551
573
  const id = shortUuid();
552
574
  const timestamp = now();
553
- d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, metadata, created_at, last_seen_at)
554
- 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
555
577
  id,
556
578
  input.name,
557
579
  input.description || null,
@@ -560,6 +582,7 @@ function registerAgent(input, db) {
560
582
  input.level || null,
561
583
  JSON.stringify(input.permissions || ["*"]),
562
584
  input.reports_to || null,
585
+ input.org_id || null,
563
586
  JSON.stringify(input.metadata || {}),
564
587
  timestamp,
565
588
  timestamp
@@ -619,6 +642,10 @@ function updateAgent(id, input, db) {
619
642
  sets.push("reports_to = ?");
620
643
  params.push(input.reports_to);
621
644
  }
645
+ if (input.org_id !== undefined) {
646
+ sets.push("org_id = ?");
647
+ params.push(input.org_id);
648
+ }
622
649
  if (input.metadata !== undefined) {
623
650
  sets.push("metadata = ?");
624
651
  params.push(JSON.stringify(input.metadata));
@@ -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,
@@ -252,6 +259,8 @@ function ensureSchema(db) {
252
259
  ensureColumn("agents", "reports_to", "TEXT");
253
260
  ensureColumn("agents", "title", "TEXT");
254
261
  ensureColumn("agents", "level", "TEXT");
262
+ ensureColumn("agents", "org_id", "TEXT");
263
+ ensureColumn("projects", "org_id", "TEXT");
255
264
  ensureColumn("plans", "task_list_id", "TEXT");
256
265
  ensureColumn("plans", "agent_id", "TEXT");
257
266
  ensureIndex("CREATE INDEX IF NOT EXISTS idx_tasks_plan ON tasks(plan_id)");
@@ -535,6 +544,19 @@ var init_database = __esm(() => {
535
544
  ALTER TABLE agents ADD COLUMN title TEXT;
536
545
  ALTER TABLE agents ADD COLUMN level TEXT;
537
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);
538
560
  `
539
561
  ];
540
562
  });
@@ -714,8 +736,8 @@ function registerAgent(input, db) {
714
736
  }
715
737
  const id = shortUuid();
716
738
  const timestamp = now();
717
- d.run(`INSERT INTO agents (id, name, description, role, title, level, permissions, reports_to, metadata, created_at, last_seen_at)
718
- 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
719
741
  id,
720
742
  input.name,
721
743
  input.description || null,
@@ -724,6 +746,7 @@ function registerAgent(input, db) {
724
746
  input.level || null,
725
747
  JSON.stringify(input.permissions || ["*"]),
726
748
  input.reports_to || null,
749
+ input.org_id || null,
727
750
  JSON.stringify(input.metadata || {}),
728
751
  timestamp,
729
752
  timestamp
@@ -783,6 +806,10 @@ function updateAgent(id, input, db) {
783
806
  sets.push("reports_to = ?");
784
807
  params.push(input.reports_to);
785
808
  }
809
+ if (input.org_id !== undefined) {
810
+ sets.push("org_id = ?");
811
+ params.push(input.org_id);
812
+ }
786
813
  if (input.metadata !== undefined) {
787
814
  sets.push("metadata = ?");
788
815
  params.push(JSON.stringify(input.metadata));
@@ -818,6 +845,71 @@ var init_agents = __esm(() => {
818
845
  init_database();
819
846
  });
820
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
+
821
913
  // src/db/webhooks.ts
822
914
  var exports_webhooks = {};
823
915
  __export(exports_webhooks, {
@@ -1796,6 +1888,36 @@ Dashboard not found at: ${dashboardDir}`);
1796
1888
  return json({ error: e instanceof Error ? e.message : "Failed to claim" }, 500, port);
1797
1889
  }
1798
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
+ }
1799
1921
  if (path === "/api/org" && method === "GET") {
1800
1922
  const { getOrgChart: getOrgChart2 } = await Promise.resolve().then(() => (init_agents(), exports_agents));
1801
1923
  return json(getOrgChart2(), 200, port);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.31",
3
+ "version": "0.9.32",
4
4
  "description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",