@sleep2agi/commhub-server 0.9.0-preview.7 → 0.9.0-preview.71
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 +130 -10
- package/bin/commhub.ts +10 -2
- package/package.json +5 -5
- package/src/ack-create-request-transport.test.ts +159 -0
- package/src/ack-create-request.test.ts +331 -0
- package/src/admin-delete-network-http.test.ts +177 -0
- package/src/admin-networks-http.test.ts +88 -0
- package/src/agent-access.ts +461 -0
- package/src/agent-acl-groups-http.test.ts +247 -0
- package/src/agent-acl-http.test.ts +510 -0
- package/src/agent-acl-slice3-http.test.ts +267 -0
- package/src/agent-groups-perf.test.ts +167 -0
- package/src/alias-filter.test.ts +72 -0
- package/src/alias-filter.ts +32 -0
- package/src/api-host-supervisors-can-create-nodes.test.ts +350 -0
- package/src/api-host-supervisors-fallback.test.ts +271 -0
- package/src/api-nodes-shape.test.ts +26 -10
- package/src/auth-sessions-http.test.ts +250 -0
- package/src/auth-validate.test.ts +5 -1
- package/src/auth.ts +423 -29
- package/src/avatar-validate.test.ts +163 -0
- package/src/avatar-validate.ts +103 -0
- package/src/blocked-exit-on-reply.test.ts +122 -0
- package/src/boot-side-effect.test.ts +124 -0
- package/src/config-apply-sec1.test.ts +107 -0
- package/src/config-apply-validate.test.ts +92 -0
- package/src/config-apply-validate.ts +81 -3
- package/src/create-node-blocked-gate.test.ts +356 -0
- package/src/create-node-tool-schema.test.ts +39 -0
- package/src/create-node-validate.test.ts +89 -1
- package/src/create-node-validate.ts +89 -7
- package/src/create-node-workdir.test.ts +255 -0
- package/src/create-node.ts +51 -1
- package/src/dashboard-slash-routing-http.test.ts +107 -0
- package/src/db-adapter-guard.test.ts +85 -0
- package/src/db-adapter-translate.test.ts +112 -0
- package/src/db-adapter.ts +246 -83
- package/src/db-timestamp.test.ts +38 -0
- package/src/db-timestamp.ts +15 -0
- package/src/db.ts +799 -33
- package/src/delivered-without-push.test.ts +140 -0
- package/src/desktop-message-seam.test.ts +150 -0
- package/src/desktop-message.test.ts +368 -0
- package/src/ext-token-shared.test.ts +60 -0
- package/src/ext-validation-regression.test.ts +131 -0
- package/src/external-schedule-edits-http.test.ts +321 -0
- package/src/external-schedule-edits-timestamps.test.ts +64 -0
- package/src/external-schedule-edits.ts +327 -0
- package/src/file-download-authz-dev-open.test.ts +135 -0
- package/src/file-download-authz.test.ts +404 -0
- package/src/file-download-date-bucket.test.ts +436 -0
- package/src/file-network-scope-dev-open.test.ts +97 -0
- package/src/file-network-scope.test.ts +732 -0
- package/src/health-redaction.test.ts +642 -0
- package/src/http-gzip.test.ts +73 -0
- package/src/http-gzip.ts +60 -0
- package/src/hub-timestamp.test.ts +38 -0
- package/src/hub-timestamp.ts +27 -0
- package/src/human-dm.ts +149 -0
- package/src/inbox-count-sse.test.ts +310 -0
- package/src/inbox-count.ts +29 -0
- package/src/index.ts +15 -2331
- package/src/lifecycle-guard.ts +50 -0
- package/src/mcp-write-network-resolution.test.ts +429 -0
- package/src/messages-ack-by-agent-http.test.ts +142 -0
- package/src/network-name-http.test.ts +75 -0
- package/src/network-scope.ts +224 -0
- package/src/node-attrs-validate.ts +88 -0
- package/src/node-attrs.test.ts +217 -0
- package/src/node-create-request-status-http.test.ts +92 -0
- package/src/node-files-transport.test.ts +344 -0
- package/src/node-id-alias.test.ts +188 -0
- package/src/node-lifecycle-controllable.test.ts +64 -0
- package/src/node-lifecycle-controllable.ts +51 -0
- package/src/node-logs-transport.test.ts +263 -0
- package/src/node-request-retention.test.ts +281 -0
- package/src/node-request-retention.ts +120 -0
- package/src/node-skills-transport.test.ts +209 -0
- package/src/node-token-privilege-http.test.ts +149 -0
- package/src/observer-avatar-http.test.ts +429 -0
- package/src/observer-push.test.ts +252 -0
- package/src/package-version-consistency.test.ts +25 -0
- package/src/peer-reply-atomic.test.ts +455 -0
- package/src/peer-reply-capability.test.ts +70 -0
- package/src/pg-worker.ts +87 -0
- package/src/push.ts +204 -7
- package/src/redact-tokens.test.ts +65 -0
- package/src/redact-tokens.ts +40 -0
- package/src/rename.ts +7 -2
- package/src/reply-target-derivation.test.ts +96 -0
- package/src/report-status-host-schema.test.ts +211 -0
- package/src/report-status-resume-id-handover.test.ts +150 -0
- package/src/require-explicit-test-db.ts +9 -0
- package/src/requirement-tags.ts +16 -0
- package/src/requirements-etag-http.test.ts +91 -0
- package/src/requirements-http.test.ts +708 -0
- package/src/requirements-mcp.test.ts +142 -0
- package/src/requirements-migrate.ts +83 -0
- package/src/requirements-priority-lowest.test.ts +114 -0
- package/src/requirements-start-date.test.ts +125 -0
- package/src/requirements-upgrade-e2e.test.ts +126 -0
- package/src/requirements-upgrade-migration.test.ts +85 -0
- package/src/requirements.ts +899 -0
- package/src/resolve-port.test.ts +57 -0
- package/src/resolve-port.ts +44 -0
- package/src/response-charset.test.ts +130 -0
- package/src/rest-explicit-columns-http.test.ts +216 -0
- package/src/rest-identity.test.ts +129 -0
- package/src/rest-identity.ts +100 -0
- package/src/rest-projections.ts +68 -0
- package/src/rest-write-network-resolution.test.ts +133 -0
- package/src/restricted-files.ts +73 -0
- package/src/retention.ts +10 -1
- package/src/rules-file-duplicate-alias.test.ts +234 -0
- package/src/rules-file-session-target.test.ts +207 -0
- package/src/rules-file-transport.test.ts +237 -0
- package/src/runtime-label.test.ts +22 -0
- package/src/runtime-label.ts +21 -0
- package/src/scheduled-doorbell-nodeless-session.test.ts +130 -0
- package/src/scheduled-run-terminal.test.ts +268 -0
- package/src/scheduled-skip-blocking-task.test.ts +120 -0
- package/src/scheduled-tasks-http.test.ts +625 -0
- package/src/scheduled-tasks.ts +597 -0
- package/src/send-dedup-request-id.test.ts +229 -0
- package/src/send-reply-agent-warning.test.ts +202 -0
- package/src/send-reply-alias-optional.test.ts +131 -0
- package/src/send-reply-attachments.test.ts +458 -0
- package/src/send_dedup.test.ts +54 -0
- package/src/send_dedup.ts +52 -6
- package/src/serve-error.test.ts +38 -0
- package/src/serve-error.ts +27 -0
- package/src/server.ts +4385 -0
- package/src/shared/external-schedule-contract.ts +60 -0
- package/src/side-thread-command-transport.test.ts +302 -0
- package/src/side-thread-command-transport.ts +318 -0
- package/src/side-thread-http-integration.test.ts +233 -0
- package/src/side-thread-http.ts +504 -0
- package/src/side-thread-production.test.ts +72 -0
- package/src/side-thread-production.ts +118 -0
- package/src/side-thread.test.ts +1067 -0
- package/src/side-thread.ts +2495 -0
- package/src/skillhub-http.test.ts +92 -0
- package/src/start-node.test.ts +109 -0
- package/src/status-alias-filter-http.test.ts +106 -0
- package/src/stop-delete-node.test.ts +1164 -0
- package/src/task-auth-origin-http.test.ts +91 -0
- package/src/task-auth-origin.test.ts +24 -0
- package/src/task-auth-origin.ts +7 -0
- package/src/task-consumption.test.ts +482 -0
- package/src/task-diagnostic-http.test.ts +149 -0
- package/src/task-diagnostic.test.ts +115 -0
- package/src/task-diagnostic.ts +118 -0
- package/src/task-idempotency-mcp.test.ts +142 -0
- package/src/task-idempotency.test.ts +60 -0
- package/src/task-idempotency.ts +75 -0
- package/src/task-lifecycle-watcher.test.ts +204 -0
- package/src/task-lifecycle-watcher.ts +49 -0
- package/src/task-network-resolution-http.test.ts +141 -0
- package/src/tasks-pagination-http.test.ts +141 -0
- package/src/tools-list-json-schema.test.ts +66 -0
- package/src/tools.ts +3446 -257
- package/src/update-provider.test.ts +65 -0
- package/src/upload-early-reject-guard.test.ts +155 -0
- package/src/uploads-http.test.ts +97 -15
- package/src/uploads.test.ts +66 -0
- package/src/uploads.ts +130 -5
- package/src/user-inbox-by-agent-http.test.ts +161 -0
- package/src/user-inbox-netid-notnull.test.ts +122 -0
- package/src/user-inbox-read-http.test.ts +223 -0
- package/src/user-inbox-schema.test.ts +54 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// 负责人 / 负责 Agent 拆分的启动迁移:旧库里 owner 是节点的卡,节点挪到 agent_owner、owner 置空。
|
|
2
|
+
// 用 #2065 时代的表结构(没有 agent_owner_json 列)先建库、塞行,再 import db.ts + requirements.ts(真实启动路径)。
|
|
3
|
+
import { afterAll, expect, test } from "bun:test";
|
|
4
|
+
import { Database } from "bun:sqlite";
|
|
5
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const dir = mkdtempSync(join(tmpdir(), "anet-req-agent-owner-"));
|
|
10
|
+
const file = join(dir, "hub.db");
|
|
11
|
+
process.env.COMMHUB_DB = file;
|
|
12
|
+
|
|
13
|
+
const legacy = new Database(file);
|
|
14
|
+
legacy.exec(`CREATE TABLE requirements (
|
|
15
|
+
requirement_id TEXT PRIMARY KEY, network_id TEXT NOT NULL, title TEXT NOT NULL,
|
|
16
|
+
column_name TEXT NOT NULL DEFAULT 'pool', priority TEXT NOT NULL DEFAULT 'normal', due_on TEXT, assignee TEXT,
|
|
17
|
+
client_id TEXT, issues_json TEXT, created_by TEXT,
|
|
18
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
19
|
+
owner_json TEXT, participants_json TEXT NOT NULL DEFAULT '[]')`);
|
|
20
|
+
const rows: [string, string | null, string][] = [
|
|
21
|
+
["r_node_owner", JSON.stringify({ kind: "node", id: "node_x" }), JSON.stringify([{ kind: "user", id: "u1" }])],
|
|
22
|
+
["r_user_owner", JSON.stringify({ kind: "user", id: "u1" }), "[]"],
|
|
23
|
+
["r_no_owner", null, "[]"],
|
|
24
|
+
["r_bad_json", "{not json", "[]"],
|
|
25
|
+
["r_node_no_id", JSON.stringify({ kind: "node" }), "[]"],
|
|
26
|
+
["r_node_owner_2", JSON.stringify({ kind: "node", id: "node_y" }), "[]"],
|
|
27
|
+
];
|
|
28
|
+
for (const [id, owner, participants] of rows) {
|
|
29
|
+
legacy.run("INSERT INTO requirements (requirement_id, network_id, title, due_on, assignee, owner_json, participants_json) VALUES (?1, 'net', ?2, '2026-10-01', 'legacy', ?3, ?4)", [id, `卡 ${id}`, owner, participants]);
|
|
30
|
+
}
|
|
31
|
+
legacy.close();
|
|
32
|
+
|
|
33
|
+
afterAll(() => { try { rmSync(dir, { recursive: true, force: true }); } catch {} });
|
|
34
|
+
|
|
35
|
+
const snapshot = (db: any) => db.all("SELECT requirement_id, network_id, title, due_on, assignee, participants_json, owner_json, agent_owner_json, project_id FROM requirements ORDER BY requirement_id") as any[];
|
|
36
|
+
|
|
37
|
+
test("startup migration moves node owners to agent_owner, keeps every row, and is idempotent", async () => {
|
|
38
|
+
const { db } = await import("./db.js");
|
|
39
|
+
await import("./requirements.js"); // 真实启动路径:server.ts 载入 requirements.ts 时迁移
|
|
40
|
+
const { migrateRequirementAgentOwners } = await import("./requirements-migrate.js");
|
|
41
|
+
const after = snapshot(db);
|
|
42
|
+
expect(after.length).toBe(rows.length);
|
|
43
|
+
const by = Object.fromEntries(after.map(r => [r.requirement_id, r]));
|
|
44
|
+
expect(by.r_node_owner.owner_json).toBeNull();
|
|
45
|
+
expect(JSON.parse(by.r_node_owner.agent_owner_json)).toEqual({ kind: "node", id: "node_x" });
|
|
46
|
+
expect(by.r_node_owner.participants_json).toBe(JSON.stringify([{ kind: "user", id: "u1" }]));
|
|
47
|
+
expect(JSON.parse(by.r_node_owner_2.agent_owner_json)).toEqual({ kind: "node", id: "node_y" });
|
|
48
|
+
expect(JSON.parse(by.r_user_owner.owner_json)).toEqual({ kind: "user", id: "u1" });
|
|
49
|
+
expect(by.r_user_owner.agent_owner_json).toBeNull();
|
|
50
|
+
expect(by.r_no_owner.owner_json).toBeNull();
|
|
51
|
+
// 读不懂的旧值原样留着,不猜、不删
|
|
52
|
+
expect(by.r_bad_json.owner_json).toBe("{not json");
|
|
53
|
+
expect(by.r_node_no_id.owner_json).toBe(JSON.stringify({ kind: "node" }));
|
|
54
|
+
for (const r of after) {
|
|
55
|
+
expect(r.title).toBe(`卡 ${r.requirement_id}`);
|
|
56
|
+
expect(r.network_id).toBe("net");
|
|
57
|
+
expect(r.due_on).toBe("2026-10-01");
|
|
58
|
+
expect(r.assignee).toBe("legacy");
|
|
59
|
+
}
|
|
60
|
+
// 加列只加不改:旧行的描述 / 子任务是空
|
|
61
|
+
const cols = (db.all("PRAGMA table_info(requirements)") as { name: string }[]).map(c => c.name);
|
|
62
|
+
expect(cols.includes("description") && cols.includes("checklist_json") && cols.includes("agent_owner_json")).toBe(true);
|
|
63
|
+
const extra = db.all("SELECT description, checklist_json FROM requirements") as any[];
|
|
64
|
+
expect(extra.every(r => r.description === null && r.checklist_json === null)).toBe(true);
|
|
65
|
+
// 项目表:建了、是空的(不预置),重复执行不报错;卡片的 project_id 列只加不改
|
|
66
|
+
expect(cols.includes("project_id")).toBe(true);
|
|
67
|
+
// PR B:外部引用 / 归档 / 谁做的 —— 只加不改;旧行 archived = 0、其余 NULL;external_ref 的部分唯一索引建了
|
|
68
|
+
for (const c of ["external_ref", "external_url", "archived", "created_by_json", "updated_by_json", "parent_id"]) expect(cols.includes(c)).toBe(true);
|
|
69
|
+
expect((db.all("SELECT parent_id FROM requirements WHERE parent_id IS NOT NULL") as any[]).length).toBe(0);
|
|
70
|
+
expect((db.all("PRAGMA index_list(requirements)") as { name: string }[]).some(i => i.name === "idx_requirements_parent")).toBe(true);
|
|
71
|
+
expect((db.all("SELECT archived, external_ref FROM requirements") as any[]).every(r => r.archived === 0 && r.external_ref === null)).toBe(true);
|
|
72
|
+
const idx = (db.all("PRAGMA index_list(requirements)") as { name: string; unique: number }[]).find(i => i.name === "idx_requirements_external_ref");
|
|
73
|
+
expect(idx?.unique).toBe(1);
|
|
74
|
+
const { ensureRequirementIndexes } = await import("./requirements-migrate.js");
|
|
75
|
+
ensureRequirementIndexes(db);
|
|
76
|
+
expect((db.all("SELECT project_id FROM requirements WHERE project_id IS NOT NULL") as any[]).length).toBe(0);
|
|
77
|
+
expect((db.get("SELECT COUNT(*) AS n FROM requirement_projects") as any).n).toBe(0);
|
|
78
|
+
const { ensureRequirementProjects } = await import("./requirements-migrate.js");
|
|
79
|
+
ensureRequirementProjects(db);
|
|
80
|
+
ensureRequirementProjects(db);
|
|
81
|
+
expect((db.get("SELECT COUNT(*) AS n FROM requirement_projects") as any).n).toBe(0);
|
|
82
|
+
// 再跑一次(= 下次启动):什么都不动
|
|
83
|
+
expect(migrateRequirementAgentOwners(db).moved).toBe(0);
|
|
84
|
+
expect(snapshot(db)).toEqual(after);
|
|
85
|
+
});
|