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.
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/cli/args.js +287 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/detect.js +94 -0
- package/dist/cli/detect.js.map +1 -0
- package/dist/cli/home.js +36 -0
- package/dist/cli/home.js.map +1 -0
- package/dist/cli/init.js +309 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/input.js +72 -0
- package/dist/cli/input.js.map +1 -0
- package/dist/cli/instructions.js +83 -0
- package/dist/cli/instructions.js.map +1 -0
- package/dist/cli/main.js +250 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +108 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/context/render.js +297 -0
- package/dist/context/render.js.map +1 -0
- package/dist/core/contracts.js +49 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/dispatch.js +109 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/core/errors.js +36 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.js +40 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/operations/claims.js +91 -0
- package/dist/core/operations/claims.js.map +1 -0
- package/dist/core/operations/common.js +108 -0
- package/dist/core/operations/common.js.map +1 -0
- package/dist/core/operations/context.js +130 -0
- package/dist/core/operations/context.js.map +1 -0
- package/dist/core/operations/decisions.js +44 -0
- package/dist/core/operations/decisions.js.map +1 -0
- package/dist/core/operations/handoffs.js +147 -0
- package/dist/core/operations/handoffs.js.map +1 -0
- package/dist/core/operations/messages.js +117 -0
- package/dist/core/operations/messages.js.map +1 -0
- package/dist/core/operations/register.js +51 -0
- package/dist/core/operations/register.js.map +1 -0
- package/dist/core/operations/tasks.js +54 -0
- package/dist/core/operations/tasks.js.map +1 -0
- package/dist/core/schemas/common.js +81 -0
- package/dist/core/schemas/common.js.map +1 -0
- package/dist/core/schemas/context.js +10 -0
- package/dist/core/schemas/context.js.map +1 -0
- package/dist/core/schemas/decisions.js +11 -0
- package/dist/core/schemas/decisions.js.map +1 -0
- package/dist/core/schemas/handoffs.js +38 -0
- package/dist/core/schemas/handoffs.js.map +1 -0
- package/dist/core/schemas/questions.js +22 -0
- package/dist/core/schemas/questions.js.map +1 -0
- package/dist/core/schemas/registration.js +16 -0
- package/dist/core/schemas/registration.js.map +1 -0
- package/dist/core/schemas/request.js +103 -0
- package/dist/core/schemas/request.js.map +1 -0
- package/dist/core/schemas/tasks.js +35 -0
- package/dist/core/schemas/tasks.js.map +1 -0
- package/dist/evidence/git.js +119 -0
- package/dist/evidence/git.js.map +1 -0
- package/dist/integrations/index.js +32 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/storage/db.js +239 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/faults.js +12 -0
- package/dist/storage/faults.js.map +1 -0
- package/dist/storage/receipts.js +82 -0
- package/dist/storage/receipts.js.map +1 -0
- package/dist/storage/schema.js +119 -0
- package/dist/storage/schema.js.map +1 -0
- package/docs/integrations.md +71 -0
- package/docs/usage.md +405 -0
- package/package.json +54 -0
- package/templates/instructions.template.md +42 -0
- 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":"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"}
|
|
@@ -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":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,0EAA0E;AAC1E,sDAAsD;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAU,CAAC;AAEzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,SAAS,EAAE,EAAE,GAAG,IAAI;IACpB,KAAK,EAAE,GAAG;IACV,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,EAAE;IACd,SAAS,EAAE,GAAG;IACd,WAAW,EAAE,GAAG;IAChB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,EAAE;IACV,YAAY,EAAE,GAAG;IACjB,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,GAAG;CACP,CAAC;AAEX,MAAM,OAAO,GAAG,+EAA+E,CAAC;AAChG,MAAM,WAAW,GAAG,yBAAyB,CAAC;AAC9C,MAAM,OAAO,GAAG,uCAAuC,CAAC;AAExD,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,0EAA0E;AAC1E,0EAA0E;AAC1E,yCAAyC;AACzC,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,CAAC;SACL,MAAM,EAAE;SACR,MAAM,CAAC,KAAK,CAAC;SACb,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,kCAAkC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAEpD,iEAAiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAE3D,yEAAyE;AACzE,2BAA2B;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAErF,6EAA6E;AAC7E,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEvF,sDAAsD;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAEpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AAEjG,6EAA6E;AAC7E,4EAA4E;AAC5E,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAE3G,2EAA2E;AAC3E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,MAAM,CAAC,KAAK,CAAC;KACb,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;KAClC,IAAI,CACH,CAAC;KACE,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;KACxB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;KACzC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CACvD,CAAC;AAEJ,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAI,MAAoB,EAAE,GAAW;IAC9D,OAAO,CAAC;SACL,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,GAAG,CAAC;SACR,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;AAChE,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAExE,4DAA4D;AAC5D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -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"}
|