loreforge 0.1.0-alpha.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.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/dist/cli/args.js +287 -0
  4. package/dist/cli/args.js.map +1 -0
  5. package/dist/cli/detect.js +94 -0
  6. package/dist/cli/detect.js.map +1 -0
  7. package/dist/cli/home.js +36 -0
  8. package/dist/cli/home.js.map +1 -0
  9. package/dist/cli/init.js +309 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/cli/input.js +72 -0
  12. package/dist/cli/input.js.map +1 -0
  13. package/dist/cli/instructions.js +83 -0
  14. package/dist/cli/instructions.js.map +1 -0
  15. package/dist/cli/main.js +250 -0
  16. package/dist/cli/main.js.map +1 -0
  17. package/dist/cli/output.js +108 -0
  18. package/dist/cli/output.js.map +1 -0
  19. package/dist/context/render.js +297 -0
  20. package/dist/context/render.js.map +1 -0
  21. package/dist/core/contracts.js +49 -0
  22. package/dist/core/contracts.js.map +1 -0
  23. package/dist/core/dispatch.js +109 -0
  24. package/dist/core/dispatch.js.map +1 -0
  25. package/dist/core/errors.js +36 -0
  26. package/dist/core/errors.js.map +1 -0
  27. package/dist/core/index.js +40 -0
  28. package/dist/core/index.js.map +1 -0
  29. package/dist/core/operations/claims.js +91 -0
  30. package/dist/core/operations/claims.js.map +1 -0
  31. package/dist/core/operations/common.js +108 -0
  32. package/dist/core/operations/common.js.map +1 -0
  33. package/dist/core/operations/context.js +130 -0
  34. package/dist/core/operations/context.js.map +1 -0
  35. package/dist/core/operations/decisions.js +44 -0
  36. package/dist/core/operations/decisions.js.map +1 -0
  37. package/dist/core/operations/handoffs.js +147 -0
  38. package/dist/core/operations/handoffs.js.map +1 -0
  39. package/dist/core/operations/messages.js +117 -0
  40. package/dist/core/operations/messages.js.map +1 -0
  41. package/dist/core/operations/register.js +51 -0
  42. package/dist/core/operations/register.js.map +1 -0
  43. package/dist/core/operations/tasks.js +54 -0
  44. package/dist/core/operations/tasks.js.map +1 -0
  45. package/dist/core/schemas/common.js +81 -0
  46. package/dist/core/schemas/common.js.map +1 -0
  47. package/dist/core/schemas/context.js +10 -0
  48. package/dist/core/schemas/context.js.map +1 -0
  49. package/dist/core/schemas/decisions.js +11 -0
  50. package/dist/core/schemas/decisions.js.map +1 -0
  51. package/dist/core/schemas/handoffs.js +38 -0
  52. package/dist/core/schemas/handoffs.js.map +1 -0
  53. package/dist/core/schemas/questions.js +22 -0
  54. package/dist/core/schemas/questions.js.map +1 -0
  55. package/dist/core/schemas/registration.js +16 -0
  56. package/dist/core/schemas/registration.js.map +1 -0
  57. package/dist/core/schemas/request.js +103 -0
  58. package/dist/core/schemas/request.js.map +1 -0
  59. package/dist/core/schemas/tasks.js +35 -0
  60. package/dist/core/schemas/tasks.js.map +1 -0
  61. package/dist/evidence/git.js +119 -0
  62. package/dist/evidence/git.js.map +1 -0
  63. package/dist/integrations/index.js +32 -0
  64. package/dist/integrations/index.js.map +1 -0
  65. package/dist/storage/db.js +239 -0
  66. package/dist/storage/db.js.map +1 -0
  67. package/dist/storage/faults.js +12 -0
  68. package/dist/storage/faults.js.map +1 -0
  69. package/dist/storage/receipts.js +82 -0
  70. package/dist/storage/receipts.js.map +1 -0
  71. package/dist/storage/schema.js +119 -0
  72. package/dist/storage/schema.js.map +1 -0
  73. package/docs/integrations.md +71 -0
  74. package/docs/usage.md +405 -0
  75. package/package.json +54 -0
  76. package/templates/instructions.template.md +42 -0
  77. package/templates/session-rule.md +34 -0
@@ -0,0 +1,117 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { OpError } from "../errors.js";
3
+ import { requireAgent, requireProject, toIso, withMutation, } from "./common.js";
4
+ function toAnswer(row) {
5
+ return { id: row.id, actorId: row.actor_id, body: row.body, createdAt: toIso(row.created_at) };
6
+ }
7
+ export function toQuestion(row, answer) {
8
+ return {
9
+ id: row.id,
10
+ projectId: row.project_id,
11
+ taskId: row.task_id,
12
+ fromAgentId: row.from_agent_id,
13
+ toAgentId: row.to_agent_id,
14
+ body: row.body,
15
+ createdAt: toIso(row.created_at),
16
+ answer: answer === undefined ? null : toAnswer(answer),
17
+ };
18
+ }
19
+ function loadQuestion(db, projectId, questionId) {
20
+ const row = db.prepare("SELECT * FROM questions WHERE id = ? AND project_id = ?").get(questionId, projectId);
21
+ if (!row)
22
+ throw OpError.notFound("question not found");
23
+ return row;
24
+ }
25
+ function loadAnswer(db, questionId) {
26
+ return db.prepare("SELECT * FROM answers WHERE question_id = ?").get(questionId);
27
+ }
28
+ function insertEvent(db, projectId, recipientId, kind, questionId, taskId, body, nowMs) {
29
+ db.prepare("INSERT INTO inbox_events (project_id, recipient_id, kind, question_id, task_id, body, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)").run(projectId, recipientId, kind, questionId, taskId, body, nowMs);
30
+ }
31
+ export function askQuestion(db, now, request) {
32
+ return withMutation(db, now, request, (nowMs) => {
33
+ requireProject(db, request.projectId);
34
+ requireAgent(db, request.actorId);
35
+ const task = db.prepare("SELECT status FROM tasks WHERE id = ? AND project_id = ?").get(request.payload.taskId, request.projectId);
36
+ if (!task)
37
+ throw OpError.notFound("task not found");
38
+ if (task.status !== "open" && task.status !== "running" && task.status !== "blocked") {
39
+ throw OpError.conflict(`cannot ask questions on a ${task.status} task`);
40
+ }
41
+ requireAgent(db, request.payload.toAgentId);
42
+ const row = {
43
+ id: randomUUID(),
44
+ project_id: request.projectId,
45
+ task_id: request.payload.taskId,
46
+ from_agent_id: request.actorId,
47
+ to_agent_id: request.payload.toAgentId,
48
+ body: request.payload.body,
49
+ created_at: nowMs,
50
+ };
51
+ db.prepare("INSERT INTO questions (id, project_id, task_id, from_agent_id, to_agent_id, body, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)").run(row.id, row.project_id, row.task_id, row.from_agent_id, row.to_agent_id, row.body, row.created_at);
52
+ insertEvent(db, request.projectId, row.to_agent_id, "question", row.id, row.task_id, row.body, nowMs);
53
+ return { question: toQuestion(row, undefined) };
54
+ });
55
+ }
56
+ export function answerQuestion(db, now, request) {
57
+ return withMutation(db, now, request, (nowMs) => {
58
+ requireProject(db, request.projectId);
59
+ requireAgent(db, request.actorId);
60
+ const question = loadQuestion(db, request.projectId, request.payload.questionId);
61
+ if (question.to_agent_id !== request.actorId) {
62
+ throw OpError.conflict("only the addressed agent may answer this question");
63
+ }
64
+ if (loadAnswer(db, question.id) !== undefined) {
65
+ throw OpError.conflict("question already answered");
66
+ }
67
+ const answer = {
68
+ question_id: question.id,
69
+ id: randomUUID(),
70
+ actor_id: request.actorId,
71
+ body: request.payload.body,
72
+ created_at: nowMs,
73
+ };
74
+ try {
75
+ db.prepare("INSERT INTO answers (question_id, id, actor_id, body, created_at) VALUES (?, ?, ?, ?, ?)").run(answer.question_id, answer.id, answer.actor_id, answer.body, answer.created_at);
76
+ }
77
+ catch (error) {
78
+ // A concurrent answer won the race between our check and insert.
79
+ const message = error instanceof Error ? error.message : String(error);
80
+ if (/UNIQUE constraint failed: answers/.test(message)) {
81
+ throw OpError.conflict("question already answered");
82
+ }
83
+ throw error;
84
+ }
85
+ insertEvent(db, request.projectId, question.from_agent_id, "answer", question.id, question.task_id, answer.body, nowMs);
86
+ return { question: toQuestion(question, answer) };
87
+ });
88
+ }
89
+ function toEvent(row) {
90
+ return {
91
+ id: row.id,
92
+ projectId: row.project_id,
93
+ recipientId: row.recipient_id,
94
+ kind: row.kind,
95
+ questionId: row.question_id,
96
+ taskId: row.task_id,
97
+ body: row.body,
98
+ createdAt: toIso(row.created_at),
99
+ };
100
+ }
101
+ export function listInbox(db, request) {
102
+ requireProject(db, request.projectId);
103
+ requireAgent(db, request.actorId);
104
+ const after = request.payload.after;
105
+ const limit = request.payload.limit;
106
+ const rows = db
107
+ .prepare("SELECT * FROM inbox_events WHERE project_id = ? AND recipient_id = ? AND id > ? ORDER BY id ASC LIMIT ?")
108
+ .all(request.projectId, request.actorId, after, limit + 1);
109
+ const hasMore = rows.length > limit;
110
+ const page = hasMore ? rows.slice(0, limit) : rows;
111
+ return {
112
+ events: page.map(toEvent),
113
+ nextCursor: page.length > 0 ? page[page.length - 1].id : after,
114
+ hasMore,
115
+ };
116
+ }
117
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/core/operations/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAWzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,KAAK,EACL,YAAY,GACb,MAAM,aAAa,CAAC;AAwBrB,SAAS,QAAQ,CAAC,GAAc;IAC9B,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAgB,EAAE,MAA6B;IACxE,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,WAAW,EAAE,GAAG,CAAC,aAAa;QAC9B,SAAS,EAAE,GAAG,CAAC,WAAW;QAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;QAChC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,EAAgB,EAAE,SAAiB,EAAE,UAAkB;IAC3E,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC,GAAG,CACnF,UAAU,EACV,SAAS,CAC4B,CAAC;IACxC,IAAI,CAAC,GAAG;QAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACvD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,EAAgB,EAAE,UAAkB;IACtD,OAAO,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,CAAC,UAAU,CAElE,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAClB,EAAgB,EAChB,SAAiB,EACjB,WAAmB,EACnB,IAAY,EACZ,UAAkB,EAClB,MAAc,EACd,IAAY,EACZ,KAAa;IAEb,EAAE,CAAC,OAAO,CACR,gIAAgI,CACjI,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,EAAgB,EAChB,GAAiB,EACjB,OAA2B;IAE3B,OAAO,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9C,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC,GAAG,CACrF,OAAO,CAAC,OAAO,CAAC,MAAM,EACtB,OAAO,CAAC,SAAS,CACgB,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACpD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrF,MAAM,OAAO,CAAC,QAAQ,CAAC,6BAA6B,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;QAC1E,CAAC;QACD,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAgB;YACvB,EAAE,EAAE,UAAU,EAAE;YAChB,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM;YAC/B,aAAa,EAAE,OAAO,CAAC,OAAO;YAC9B,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS;YACtC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YAC1B,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,EAAE,CAAC,OAAO,CACR,4HAA4H,CAC7H,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACzG,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtG,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,EAAgB,EAChB,GAAiB,EACjB,OAA8B;IAE9B,OAAO,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9C,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACjF,IAAI,QAAQ,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7C,MAAM,OAAO,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,MAAM,GAAc;YACxB,WAAW,EAAE,QAAQ,CAAC,EAAE;YACxB,EAAE,EAAE,UAAU,EAAE;YAChB,QAAQ,EAAE,OAAO,CAAC,OAAO;YACzB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YAC1B,UAAU,EAAE,KAAK;SAClB,CAAC;QACF,IAAI,CAAC;YACH,EAAE,CAAC,OAAO,CAAC,0FAA0F,CAAC,CAAC,GAAG,CACxG,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,UAAU,CAClB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iEAAiE;YACjE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,mCAAmC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,MAAM,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxH,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC;AAaD,SAAS,OAAO,CAAC,GAAa;IAC5B,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,IAAI,EAAE,GAAG,CAAC,IAA0B;QACpC,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAgB,EAAE,OAAyB;IACnE,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IACpC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN,yGAAyG,CAC1G;SACA,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAA0B,CAAC;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;QACzB,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;QAC9D,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { OpError } from "../errors.js";
3
+ import { discoverProject } from "../../evidence/git.js";
4
+ import { readReceipt } from "../../storage/receipts.js";
5
+ import { toAgent, toProject, transactMutation, withMutation } from "./common.js";
6
+ export function registerProject(db, now, request) {
7
+ const early = readReceipt(db, request);
8
+ if (early !== undefined)
9
+ return early;
10
+ // Git discovery happens outside the transaction: it is an observation, and
11
+ // a retry must still succeed after the checkout moves or disappears.
12
+ const identity = discoverProject(request.payload.root);
13
+ return transactMutation(db, now, request, (nowMs) => {
14
+ const existing = db
15
+ .prepare("SELECT * FROM projects WHERE git_common_dir = ?")
16
+ .get(identity.gitCommonDir);
17
+ // An existing canonical identity returns the existing record and never
18
+ // renames it, regardless of the requested name.
19
+ const project = existing
20
+ ? toProject(existing)
21
+ : (() => {
22
+ const row = {
23
+ id: randomUUID(),
24
+ name: request.payload.name,
25
+ root: identity.root,
26
+ git_common_dir: identity.gitCommonDir,
27
+ created_at: nowMs,
28
+ };
29
+ db.prepare("INSERT INTO projects (id, name, root, git_common_dir, created_at) VALUES (?, ?, ?, ?, ?)").run(row.id, row.name, row.root, row.git_common_dir, row.created_at);
30
+ return toProject(row);
31
+ })();
32
+ return { project };
33
+ });
34
+ }
35
+ export function registerAgent(db, now, request) {
36
+ return withMutation(db, now, request, (nowMs) => {
37
+ const existing = db.prepare("SELECT * FROM agents WHERE id = ?").get(request.payload.id);
38
+ if (existing) {
39
+ // Same id and name replays the existing record; a different name for a
40
+ // taken id is CONFLICT, decided here rather than by the receipt layer.
41
+ if (existing.display_name !== request.payload.displayName) {
42
+ throw OpError.conflict("agent id is already registered with a different name");
43
+ }
44
+ return { agent: toAgent(existing) };
45
+ }
46
+ const row = { id: request.payload.id, display_name: request.payload.displayName, created_at: nowMs };
47
+ db.prepare("INSERT INTO agents (id, display_name, created_at) VALUES (?, ?, ?)").run(row.id, row.display_name, row.created_at);
48
+ return { agent: toAgent(row) };
49
+ });
50
+ }
51
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/core/operations/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { OpError } from "../errors.js";
3
+ import { requireAgent, requireProject, toTask, withMutation } from "./common.js";
4
+ export function createTask(db, now, request) {
5
+ return withMutation(db, now, request, (nowMs) => {
6
+ requireProject(db, request.projectId);
7
+ requireAgent(db, request.actorId);
8
+ // Every dependency must already exist in the same project. Existence is a
9
+ // runtime check, so wrong-project IDs are NOT_FOUND here, never leaked.
10
+ for (const dependsOn of request.payload.dependsOn) {
11
+ const row = db.prepare("SELECT project_id FROM tasks WHERE id = ?").get(dependsOn);
12
+ if (!row || row.project_id !== request.projectId) {
13
+ throw OpError.notFound("dependency not found");
14
+ }
15
+ }
16
+ const id = randomUUID();
17
+ db.prepare("INSERT INTO tasks (id, project_id, title, description, status, owner_id, claim_token, attempt, lease_until, created_at, updated_at) VALUES (?, ?, ?, ?, 'open', NULL, NULL, 0, NULL, ?, ?)").run(id, request.projectId, request.payload.title, request.payload.description, nowMs, nowMs);
18
+ const insertDep = db.prepare("INSERT INTO task_dependencies (task_id, depends_on_task_id) VALUES (?, ?)");
19
+ for (const dependsOn of request.payload.dependsOn) {
20
+ insertDep.run(id, dependsOn);
21
+ }
22
+ const row = db.prepare("SELECT * FROM tasks WHERE id = ?").get(id);
23
+ return { task: toTask(db, row) };
24
+ });
25
+ }
26
+ export function getTask(db, request) {
27
+ requireProject(db, request.projectId);
28
+ const row = db.prepare("SELECT * FROM tasks WHERE id = ? AND project_id = ?").get(request.payload.taskId, request.projectId);
29
+ if (!row)
30
+ throw OpError.notFound("task not found");
31
+ return { task: toTask(db, row) };
32
+ }
33
+ export function listTasks(db, request) {
34
+ requireProject(db, request.projectId);
35
+ const status = request.payload.status;
36
+ const limit = request.payload.limit;
37
+ const countRow = (status === undefined
38
+ ? db.prepare("SELECT COUNT(*) AS n FROM tasks WHERE project_id = ?").get(request.projectId)
39
+ : db
40
+ .prepare("SELECT COUNT(*) AS n FROM tasks WHERE project_id = ? AND status = ?")
41
+ .get(request.projectId, status));
42
+ const rows = (status === undefined
43
+ ? db
44
+ .prepare("SELECT * FROM tasks WHERE project_id = ? ORDER BY created_at DESC, id ASC LIMIT ?")
45
+ .all(request.projectId, limit)
46
+ : db
47
+ .prepare("SELECT * FROM tasks WHERE project_id = ? AND status = ? ORDER BY created_at DESC, id ASC LIMIT ?")
48
+ .all(request.projectId, status, limit));
49
+ return {
50
+ tasks: rows.map((row) => toTask(db, row)),
51
+ omittedCount: Math.max(0, countRow.n - rows.length),
52
+ };
53
+ }
54
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/core/operations/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ // Shared primitives for every domain schema. Input schemas are pure: they
3
+ // never touch the filesystem, environment, or SQLite.
4
+ export const SCHEMA_VERSION = 1;
5
+ // Character/count limits from CONTRACT.md (characters unless noted).
6
+ export const LIMITS = {
7
+ jsonBytes: 64 * 1024,
8
+ title: 200,
9
+ description: 4000,
10
+ summary: 2000,
11
+ body: 4000,
12
+ listString: 500,
13
+ arrayItems: 20,
14
+ requestId: 128,
15
+ projectName: 100,
16
+ displayName: 100,
17
+ relativePath: 400,
18
+ evidenceFiles: 100,
19
+ checks: 20,
20
+ checkCommand: 500,
21
+ checkSummary: 1000,
22
+ claimToken: 256,
23
+ };
24
+ const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
25
+ const AGENT_ID_RE = /^[a-z][a-z0-9_-]{0,63}$/;
26
+ const HEAD_RE = /^(?:[0-9a-fA-F]{40}|[0-9a-fA-F]{64})$/;
27
+ const NUL = String.fromCharCode(0);
28
+ function noNul(value) {
29
+ return !value.includes(NUL);
30
+ }
31
+ // Required free text: trimmed, nonempty, bounded, NUL-free. Length limits
32
+ // apply after trim; a value that trims to empty is rejected, never stored
33
+ // as empty. Output is the trimmed value.
34
+ export function requiredText(max) {
35
+ return z
36
+ .string()
37
+ .refine(noNul)
38
+ .transform((value) => value.trim())
39
+ .pipe(z.string().min(1).max(max));
40
+ }
41
+ // Generated entity IDs are UUIDs.
42
+ export const UuidSchema = z.string().regex(UUID_RE);
43
+ // Coordination labels such as `muse`, `flash`, `codex`, `human`.
44
+ export const AgentIdSchema = z.string().regex(AGENT_ID_RE);
45
+ // Caller-chosen retry key: nonempty, bounded, NUL-free. Callers reuse it
46
+ // only for an exact retry.
47
+ export const RequestIdSchema = z.string().min(1).max(LIMITS.requestId).refine(noNul);
48
+ // Core-issued claim token. Compared opaquely; never logged or echoed outside
49
+ // the intentional claim result.
50
+ export const ClaimTokenSchema = z.string().min(1).max(LIMITS.claimToken).refine(noNul);
51
+ // Full 40- or 64-hex commit ID observed by the agent.
52
+ export const HeadSchema = z.string().regex(HEAD_RE);
53
+ export const TaskStatusSchema = z.enum(["open", "running", "blocked", "completed", "cancelled"]);
54
+ // Absolute path (project roots, checkout roots): nonempty, NUL-free, rooted.
55
+ // No length normalization: resolvable aliases are canonicalized by the core
56
+ // against the filesystem, not by the schema.
57
+ export const AbsolutePathSchema = z.string().min(1).refine(noNul).refine((value) => value.startsWith("/"));
58
+ // Project-relative path using `/` separators. Rejects absolute paths, `..`
59
+ // segments, NUL bytes, and empties. Length applies after trim.
60
+ export const RelativePathSchema = z
61
+ .string()
62
+ .refine(noNul)
63
+ .transform((value) => value.trim())
64
+ .pipe(z
65
+ .string()
66
+ .min(1)
67
+ .max(LIMITS.relativePath)
68
+ .refine((value) => !value.startsWith("/"))
69
+ .refine((value) => !value.split("/").includes("..")));
70
+ // Array whose entries must be unique (used for IDs and paths).
71
+ export function uniqueArray(schema, max) {
72
+ return z
73
+ .array(schema)
74
+ .max(max)
75
+ .refine((values) => new Set(values).size === values.length);
76
+ }
77
+ // Read-list paging: default limit 20, range 1..100.
78
+ export const LimitSchema = z.number().int().min(1).max(100).default(20);
79
+ // Inbox cursor: monotonic event id, default 0 (everything).
80
+ export const AfterSchema = z.number().int().min(0).default(0);
81
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/core/schemas/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ import { UuidSchema } from "./common.js";
3
+ // context.get: {taskId,mode?} -> {snapshot}. Mode defaults to work; review
4
+ // mode omits implementation prose and Q&A by policy (selection is core's,
5
+ // rendering is the client's).
6
+ export const ContextGetPayloadSchema = z.strictObject({
7
+ taskId: UuidSchema,
8
+ mode: z.enum(["work", "review"]).default("work"),
9
+ });
10
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/core/schemas/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,2EAA2E;AAC3E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,YAAY,CAAC;IACpD,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACjD,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ import { LIMITS, RelativePathSchema, UuidSchema, requiredText, uniqueArray } from "./common.js";
3
+ // decision.record: {body,paths,supersedesId} -> {decision}. Empty paths
4
+ // means project-wide. supersedesId is a required key holding an active
5
+ // decision ID in the same project, or null. No destructive update/delete.
6
+ export const DecisionRecordPayloadSchema = z.strictObject({
7
+ body: requiredText(LIMITS.body),
8
+ paths: uniqueArray(RelativePathSchema, LIMITS.arrayItems),
9
+ supersedesId: UuidSchema.nullable(),
10
+ });
11
+ //# sourceMappingURL=decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../../src/core/schemas/decisions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhG,wEAAwE;AACxE,uEAAuE;AACvE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,YAAY,CAAC;IACxD,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;IAC/B,KAAK,EAAE,WAAW,CAAC,kBAAkB,EAAE,MAAM,CAAC,UAAU,CAAC;IACzD,YAAY,EAAE,UAAU,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ import { AbsolutePathSchema, ClaimTokenSchema, HeadSchema, LIMITS, RelativePathSchema, UuidSchema, requiredText, uniqueArray, } from "./common.js";
3
+ // Agent-reported evidence. The core never executes checks and never treats
4
+ // reported file assertions as verified; it only records them alongside its
5
+ // own read-only Git observation.
6
+ const EvidenceFileSchema = z.strictObject({
7
+ path: RelativePathSchema,
8
+ change: z.enum(["added", "modified", "deleted"]),
9
+ });
10
+ const EvidenceCheckSchema = z.strictObject({
11
+ command: requiredText(LIMITS.checkCommand),
12
+ outcome: z.enum(["passed", "failed", "not_run"]),
13
+ summary: requiredText(LIMITS.checkSummary),
14
+ });
15
+ export const EvidenceInputSchema = z.strictObject({
16
+ checkoutRoot: AbsolutePathSchema,
17
+ head: HeadSchema,
18
+ dirty: z.boolean(),
19
+ files: z
20
+ .array(EvidenceFileSchema)
21
+ .max(LIMITS.evidenceFiles)
22
+ .refine((files) => new Set(files.map((file) => file.path)).size === files.length),
23
+ checks: z.array(EvidenceCheckSchema).max(LIMITS.checks),
24
+ });
25
+ // handoff.submit -> {task,handoff}. blockingQuestionIds is required: empty
26
+ // for completed, nonempty for blocked. Question existence, project/task
27
+ // match, and unanswered state are runtime checks.
28
+ export const HandoffSubmitPayloadSchema = z.strictObject({
29
+ taskId: UuidSchema,
30
+ claimToken: ClaimTokenSchema,
31
+ outcome: z.enum(["completed", "blocked"]),
32
+ summary: requiredText(LIMITS.summary),
33
+ evidence: EvidenceInputSchema,
34
+ unresolved: z.array(requiredText(LIMITS.listString)).max(LIMITS.arrayItems),
35
+ nextSteps: z.array(requiredText(LIMITS.listString)).max(LIMITS.arrayItems),
36
+ blockingQuestionIds: uniqueArray(UuidSchema, LIMITS.arrayItems),
37
+ });
38
+ //# sourceMappingURL=handoffs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoffs.js","sourceRoot":"","sources":["../../../src/core/schemas/handoffs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,2EAA2E;AAC3E,iCAAiC;AACjC,MAAM,kBAAkB,GAAG,CAAC,CAAC,YAAY,CAAC;IACxC,IAAI,EAAE,kBAAkB;IACxB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IACzC,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAChD,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IAChD,YAAY,EAAE,kBAAkB;IAChC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,kBAAkB,CAAC;SACzB,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;SACzB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC;IACnF,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;CACxD,CAAC,CAAC;AAGH,2EAA2E;AAC3E,wEAAwE;AACxE,kDAAkD;AAClD,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,MAAM,EAAE,UAAU;IAClB,UAAU,EAAE,gBAAgB;IAC5B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACzC,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;IACrC,QAAQ,EAAE,mBAAmB;IAC7B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;IAC3E,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;IAC1E,mBAAmB,EAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAChE,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import { AfterSchema, AgentIdSchema, LIMITS, LimitSchema, UuidSchema, requiredText } from "./common.js";
3
+ // question.ask: {taskId,toAgentId,body} -> {question}. Allowed on
4
+ // open/running/blocked tasks only (runtime); terminal tasks reject.
5
+ export const QuestionAskPayloadSchema = z.strictObject({
6
+ taskId: UuidSchema,
7
+ toAgentId: AgentIdSchema,
8
+ body: requiredText(LIMITS.body),
9
+ });
10
+ // question.answer: {questionId,body} -> {question}. Only the addressed agent
11
+ // may answer; answers stay permitted after terminal task state (runtime).
12
+ export const QuestionAnswerPayloadSchema = z.strictObject({
13
+ questionId: UuidSchema,
14
+ body: requiredText(LIMITS.body),
15
+ });
16
+ // inbox.list: {after?,limit?} -> {events,nextCursor,hasMore}. Filters by
17
+ // project AND recipient AND event.id > after, ascending event.id.
18
+ export const InboxListPayloadSchema = z.strictObject({
19
+ after: AfterSchema,
20
+ limit: LimitSchema,
21
+ });
22
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.js","sourceRoot":"","sources":["../../../src/core/schemas/questions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExG,kEAAkE;AAClE,oEAAoE;AACpE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,YAAY,CAAC;IACrD,MAAM,EAAE,UAAU;IAClB,SAAS,EAAE,aAAa;IACxB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;CAChC,CAAC,CAAC;AAGH,6EAA6E;AAC7E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,YAAY,CAAC;IACxD,UAAU,EAAE,UAAU;IACtB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;CAChC,CAAC,CAAC;AAGH,yEAAyE;AACzE,kEAAkE;AAClE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,YAAY,CAAC;IACnD,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,WAAW;CACnB,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import { AbsolutePathSchema, AgentIdSchema, LIMITS, requiredText } from "./common.js";
3
+ // project.register: {root,name} -> {project}. projectId and actorId are
4
+ // forbidden on the envelope; requestId is required. An existing canonical
5
+ // identity returns the existing record and does not rename.
6
+ export const ProjectRegisterPayloadSchema = z.strictObject({
7
+ root: AbsolutePathSchema,
8
+ name: requiredText(LIMITS.projectName),
9
+ });
10
+ // agent.register: {id,displayName} -> {agent}. Same id/name returns the
11
+ // existing record; a different name for the same id is CONFLICT (runtime).
12
+ export const AgentRegisterPayloadSchema = z.strictObject({
13
+ id: AgentIdSchema,
14
+ displayName: requiredText(LIMITS.displayName),
15
+ });
16
+ //# sourceMappingURL=registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/core/schemas/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEtF,wEAAwE;AACxE,0EAA0E;AAC1E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC;CACvC,CAAC,CAAC;AAGH,wEAAwE;AACxE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,EAAE,EAAE,aAAa;IACjB,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC;CAC9C,CAAC,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { z } from "zod";
2
+ import { AgentIdSchema, RequestIdSchema, SCHEMA_VERSION, UuidSchema } from "./common.js";
3
+ import { AgentRegisterPayloadSchema, ProjectRegisterPayloadSchema } from "./registration.js";
4
+ import { TaskClaimPayloadSchema, TaskCreatePayloadSchema, TaskGetPayloadSchema, TaskIdOnlyPayloadSchema, TaskLeasePayloadSchema, TaskListPayloadSchema, } from "./tasks.js";
5
+ import { HandoffSubmitPayloadSchema } from "./handoffs.js";
6
+ import { InboxListPayloadSchema, QuestionAnswerPayloadSchema, QuestionAskPayloadSchema, } from "./questions.js";
7
+ import { DecisionRecordPayloadSchema } from "./decisions.js";
8
+ import { ContextGetPayloadSchema } from "./context.js";
9
+ // Request envelope rules from CONTRACT.md:
10
+ // - project.register / agent.register: requestId required; projectId and
11
+ // actorId forbidden.
12
+ // - reads other than inbox.list: projectId required; actorId and requestId
13
+ // forbidden.
14
+ // - inbox.list: projectId and actorId required; requestId forbidden.
15
+ // - every other mutation: projectId, actorId, and requestId required.
16
+ // Unknown keys are validation errors at every level, so each envelope is a
17
+ // strict object with exactly its allowed keys.
18
+ const versionField = z.literal(SCHEMA_VERSION);
19
+ function registerEnvelope(operation, payload) {
20
+ return z.strictObject({
21
+ schemaVersion: versionField,
22
+ operation: z.literal(operation),
23
+ requestId: RequestIdSchema,
24
+ payload,
25
+ });
26
+ }
27
+ function readEnvelope(operation, payload) {
28
+ return z.strictObject({
29
+ schemaVersion: versionField,
30
+ operation: z.literal(operation),
31
+ projectId: UuidSchema,
32
+ payload,
33
+ });
34
+ }
35
+ function mutationEnvelope(operation, payload) {
36
+ return z.strictObject({
37
+ schemaVersion: versionField,
38
+ operation: z.literal(operation),
39
+ projectId: UuidSchema,
40
+ actorId: AgentIdSchema,
41
+ requestId: RequestIdSchema,
42
+ payload,
43
+ });
44
+ }
45
+ const InboxListRequestSchema = z.strictObject({
46
+ schemaVersion: versionField,
47
+ operation: z.literal("inbox.list"),
48
+ projectId: UuidSchema,
49
+ actorId: AgentIdSchema,
50
+ payload: InboxListPayloadSchema,
51
+ });
52
+ export const RequestSchema = z.discriminatedUnion("operation", [
53
+ registerEnvelope("project.register", ProjectRegisterPayloadSchema),
54
+ registerEnvelope("agent.register", AgentRegisterPayloadSchema),
55
+ mutationEnvelope("task.create", TaskCreatePayloadSchema),
56
+ readEnvelope("task.get", TaskGetPayloadSchema),
57
+ readEnvelope("task.list", TaskListPayloadSchema),
58
+ mutationEnvelope("task.claim", TaskClaimPayloadSchema),
59
+ mutationEnvelope("task.renew", TaskLeasePayloadSchema),
60
+ mutationEnvelope("task.release", TaskLeasePayloadSchema),
61
+ mutationEnvelope("task.reopen", TaskIdOnlyPayloadSchema),
62
+ mutationEnvelope("task.cancel", TaskIdOnlyPayloadSchema),
63
+ mutationEnvelope("handoff.submit", HandoffSubmitPayloadSchema),
64
+ mutationEnvelope("question.ask", QuestionAskPayloadSchema),
65
+ mutationEnvelope("question.answer", QuestionAnswerPayloadSchema),
66
+ InboxListRequestSchema,
67
+ mutationEnvelope("decision.record", DecisionRecordPayloadSchema),
68
+ readEnvelope("context.get", ContextGetPayloadSchema),
69
+ ]);
70
+ // All sixteen operation names, in contract-table order.
71
+ export const OPERATIONS = [
72
+ "project.register",
73
+ "agent.register",
74
+ "task.create",
75
+ "task.get",
76
+ "task.list",
77
+ "task.claim",
78
+ "task.renew",
79
+ "task.release",
80
+ "task.reopen",
81
+ "task.cancel",
82
+ "handoff.submit",
83
+ "question.ask",
84
+ "question.answer",
85
+ "inbox.list",
86
+ "decision.record",
87
+ "context.get",
88
+ ];
89
+ // Parse an unknown value into a validated Request. Throws the Zod validation
90
+ // error on failure; the CLI maps it to VALIDATION without echoing values.
91
+ // Pure: never opens SQLite or the filesystem.
92
+ export function parseRequest(value) {
93
+ return RequestSchema.parse(value);
94
+ }
95
+ export function validationDetails(error) {
96
+ return {
97
+ issues: error.issues.map((issue) => ({
98
+ path: issue.path.map((part) => (typeof part === "number" ? part : String(part))),
99
+ code: issue.code,
100
+ })),
101
+ };
102
+ }
103
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../../src/core/schemas/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ import { ClaimTokenSchema, LIMITS, LimitSchema, TaskStatusSchema, UuidSchema, requiredText, uniqueArray, } from "./common.js";
3
+ // task.create: {title,description,dependsOn} -> {task}. All keys required;
4
+ // pass an empty array when there are no dependencies. Dependency IDs must
5
+ // already exist in the same project (checked at runtime, not by schema).
6
+ export const TaskCreatePayloadSchema = z.strictObject({
7
+ title: requiredText(LIMITS.title),
8
+ description: requiredText(LIMITS.description),
9
+ dependsOn: uniqueArray(UuidSchema, LIMITS.arrayItems),
10
+ });
11
+ // task.get: {taskId} -> {task}. Retrieves an omitted task as well.
12
+ export const TaskGetPayloadSchema = z.strictObject({
13
+ taskId: UuidSchema,
14
+ });
15
+ // task.list: {status?,limit?} -> {tasks,omittedCount}. Newest-created first
16
+ // with ID ascending tie-break (applied at runtime).
17
+ export const TaskListPayloadSchema = z.strictObject({
18
+ status: TaskStatusSchema.optional(),
19
+ limit: LimitSchema,
20
+ });
21
+ // task.claim: {taskId} -> {task,claimToken}.
22
+ export const TaskClaimPayloadSchema = z.strictObject({
23
+ taskId: UuidSchema,
24
+ });
25
+ // task.renew / task.release: {taskId,claimToken} -> {task}.
26
+ export const TaskLeasePayloadSchema = z.strictObject({
27
+ taskId: UuidSchema,
28
+ claimToken: ClaimTokenSchema,
29
+ });
30
+ // task.reopen / task.cancel: {taskId} -> {task}. Reopen is blocked-only;
31
+ // cancel accepts open/running/blocked (runtime transitions).
32
+ export const TaskIdOnlyPayloadSchema = z.strictObject({
33
+ taskId: UuidSchema,
34
+ });
35
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/core/schemas/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,0EAA0E;AAC1E,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,YAAY,CAAC;IACpD,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;IACjC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC;IAC7C,SAAS,EAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CACtD,CAAC,CAAC;AAGH,mEAAmE;AACnE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,YAAY,CAAC;IACjD,MAAM,EAAE,UAAU;CACnB,CAAC,CAAC;AAGH,4EAA4E;AAC5E,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,YAAY,CAAC;IAClD,MAAM,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACnC,KAAK,EAAE,WAAW;CACnB,CAAC,CAAC;AAGH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,YAAY,CAAC;IACnD,MAAM,EAAE,UAAU;CACnB,CAAC,CAAC;AAGH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,YAAY,CAAC;IACnD,MAAM,EAAE,UAAU;IAClB,UAAU,EAAE,gBAAgB;CAC7B,CAAC,CAAC;AAGH,yEAAyE;AACzE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,YAAY,CAAC;IACpD,MAAM,EAAE,UAAU;CACnB,CAAC,CAAC"}