@agentplaneorg/core 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commit/commit-policy.d.ts.map +1 -0
- package/dist/{config.d.ts → config/config.d.ts} +1 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +124 -0
- package/dist/fs/atomic-write.d.ts +2 -0
- package/dist/fs/atomic-write.d.ts.map +1 -0
- package/dist/fs/atomic-write.js +9 -0
- package/dist/git/base-branch.d.ts.map +1 -0
- package/dist/{base-branch.js → git/base-branch.js} +1 -1
- package/dist/git/git-utils.d.ts.map +1 -0
- package/dist/{git-utils.js → git/git-utils.js} +1 -1
- package/dist/index.d.ts +12 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -9
- package/dist/project/project-root.d.ts.map +1 -0
- package/dist/tasks/task-doc.d.ts +16 -0
- package/dist/tasks/task-doc.d.ts.map +1 -0
- package/dist/tasks/task-doc.js +326 -0
- package/dist/tasks/task-id.d.ts +9 -0
- package/dist/tasks/task-id.d.ts.map +1 -0
- package/dist/tasks/task-id.js +28 -0
- package/dist/tasks/task-readme.d.ts.map +1 -0
- package/dist/{task-store.d.ts → tasks/task-store.d.ts} +2 -0
- package/dist/tasks/task-store.d.ts.map +1 -0
- package/dist/tasks/task-store.js +212 -0
- package/dist/tasks/tasks-export.d.ts.map +1 -0
- package/dist/{tasks-export.js → tasks/tasks-export.js} +5 -4
- package/dist/{tasks-lint.d.ts → tasks/tasks-lint.d.ts} +1 -1
- package/dist/tasks/tasks-lint.d.ts.map +1 -0
- package/dist/{tasks-lint.js → tasks/tasks-lint.js} +2 -2
- package/package.json +4 -1
- package/schemas/config.schema.json +278 -0
- package/dist/base-branch.d.ts.map +0 -1
- package/dist/commit-policy.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -237
- package/dist/git-utils.d.ts.map +0 -1
- package/dist/project-root.d.ts.map +0 -1
- package/dist/task-readme.d.ts.map +0 -1
- package/dist/task-store.d.ts.map +0 -1
- package/dist/task-store.js +0 -359
- package/dist/tasks-export.d.ts.map +0 -1
- package/dist/tasks-lint.d.ts.map +0 -1
- /package/dist/{commit-policy.d.ts → commit/commit-policy.d.ts} +0 -0
- /package/dist/{commit-policy.js → commit/commit-policy.js} +0 -0
- /package/dist/{base-branch.d.ts → git/base-branch.d.ts} +0 -0
- /package/dist/{git-utils.d.ts → git/git-utils.d.ts} +0 -0
- /package/dist/{project-root.d.ts → project/project-root.d.ts} +0 -0
- /package/dist/{project-root.js → project/project-root.js} +0 -0
- /package/dist/{task-readme.d.ts → tasks/task-readme.d.ts} +0 -0
- /package/dist/{task-readme.js → tasks/task-readme.js} +0 -0
- /package/dist/{tasks-export.d.ts → tasks/tasks-export.d.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateTaskId } from "./task-id.js";
|
|
1
2
|
export type TaskStatus = "TODO" | "DOING" | "DONE" | "BLOCKED";
|
|
2
3
|
export type TaskPriority = "low" | "normal" | "med" | "high";
|
|
3
4
|
export type TaskFrontmatter = {
|
|
@@ -48,6 +49,7 @@ export declare function createTask(opts: {
|
|
|
48
49
|
tags: string[];
|
|
49
50
|
dependsOn: string[];
|
|
50
51
|
verify: string[];
|
|
52
|
+
idGenerator?: typeof generateTaskId;
|
|
51
53
|
}): Promise<{
|
|
52
54
|
id: string;
|
|
53
55
|
readmePath: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/tasks/task-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadConfig } from "../config/config.js";
|
|
4
|
+
import { resolveProject } from "../project/project-root.js";
|
|
5
|
+
import { parseTaskReadme, renderTaskReadme } from "./task-readme.js";
|
|
6
|
+
import { ensureDocSections, setMarkdownSection } from "./task-doc.js";
|
|
7
|
+
import { generateTaskId } from "./task-id.js";
|
|
8
|
+
function nowIso() {
|
|
9
|
+
return new Date().toISOString();
|
|
10
|
+
}
|
|
11
|
+
function isRecord(value) {
|
|
12
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
13
|
+
}
|
|
14
|
+
export function validateTaskDocMetadata(frontmatter) {
|
|
15
|
+
const errors = [];
|
|
16
|
+
if (frontmatter.doc_version !== 2)
|
|
17
|
+
errors.push("doc_version must be 2");
|
|
18
|
+
const updatedAt = frontmatter.doc_updated_at;
|
|
19
|
+
if (typeof updatedAt !== "string" || Number.isNaN(Date.parse(updatedAt))) {
|
|
20
|
+
errors.push("doc_updated_at must be an ISO timestamp");
|
|
21
|
+
}
|
|
22
|
+
const updatedBy = frontmatter.doc_updated_by;
|
|
23
|
+
if (typeof updatedBy !== "string" || updatedBy.trim().length === 0) {
|
|
24
|
+
errors.push("doc_updated_by must be a non-empty string");
|
|
25
|
+
}
|
|
26
|
+
return errors;
|
|
27
|
+
}
|
|
28
|
+
async function fileExists(filePath) {
|
|
29
|
+
try {
|
|
30
|
+
await readFile(filePath, "utf8");
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export async function getTasksDir(opts) {
|
|
38
|
+
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
39
|
+
const loaded = await loadConfig(resolved.agentplaneDir);
|
|
40
|
+
const tasksDir = path.join(resolved.gitRoot, loaded.config.paths.workflow_dir);
|
|
41
|
+
return {
|
|
42
|
+
gitRoot: resolved.gitRoot,
|
|
43
|
+
tasksDir,
|
|
44
|
+
idSuffixLengthDefault: loaded.config.tasks.id_suffix_length_default,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function taskReadmePath(tasksDir, taskId) {
|
|
48
|
+
return path.join(tasksDir, taskId, "README.md");
|
|
49
|
+
}
|
|
50
|
+
function defaultTaskBody() {
|
|
51
|
+
return [
|
|
52
|
+
"## Summary",
|
|
53
|
+
"",
|
|
54
|
+
"",
|
|
55
|
+
"## Scope",
|
|
56
|
+
"",
|
|
57
|
+
"",
|
|
58
|
+
"## Risks",
|
|
59
|
+
"",
|
|
60
|
+
"",
|
|
61
|
+
"## Verify Steps",
|
|
62
|
+
"",
|
|
63
|
+
"",
|
|
64
|
+
"## Verification",
|
|
65
|
+
"",
|
|
66
|
+
"",
|
|
67
|
+
"## Rollback Plan",
|
|
68
|
+
"",
|
|
69
|
+
].join("\n");
|
|
70
|
+
}
|
|
71
|
+
function getLastCommentAuthor(frontmatter) {
|
|
72
|
+
const comments = frontmatter.comments;
|
|
73
|
+
if (!Array.isArray(comments))
|
|
74
|
+
return null;
|
|
75
|
+
const entries = comments;
|
|
76
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
77
|
+
const entry = entries[i];
|
|
78
|
+
if (!isRecord(entry))
|
|
79
|
+
continue;
|
|
80
|
+
const author = entry.author;
|
|
81
|
+
if (typeof author === "string") {
|
|
82
|
+
const trimmed = author.trim();
|
|
83
|
+
if (trimmed)
|
|
84
|
+
return trimmed;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
function resolveDocUpdatedBy(frontmatter, updatedBy) {
|
|
90
|
+
if (updatedBy != null) {
|
|
91
|
+
const explicit = updatedBy.trim();
|
|
92
|
+
if (explicit.length === 0) {
|
|
93
|
+
throw new Error("doc_updated_by must be a non-empty string");
|
|
94
|
+
}
|
|
95
|
+
return explicit;
|
|
96
|
+
}
|
|
97
|
+
const lastAuthor = getLastCommentAuthor(frontmatter);
|
|
98
|
+
if (lastAuthor)
|
|
99
|
+
return lastAuthor;
|
|
100
|
+
const existing = frontmatter.doc_updated_by;
|
|
101
|
+
if (typeof existing === "string") {
|
|
102
|
+
const trimmed = existing.trim();
|
|
103
|
+
if (trimmed && trimmed.toLowerCase() !== "agentplane")
|
|
104
|
+
return trimmed;
|
|
105
|
+
}
|
|
106
|
+
const owner = frontmatter.owner;
|
|
107
|
+
if (typeof owner === "string") {
|
|
108
|
+
const trimmed = owner.trim();
|
|
109
|
+
if (trimmed)
|
|
110
|
+
return trimmed;
|
|
111
|
+
}
|
|
112
|
+
return "agentplane";
|
|
113
|
+
}
|
|
114
|
+
export async function createTask(opts) {
|
|
115
|
+
const { tasksDir, idSuffixLengthDefault } = await getTasksDir({
|
|
116
|
+
cwd: opts.cwd,
|
|
117
|
+
rootOverride: opts.rootOverride ?? null,
|
|
118
|
+
});
|
|
119
|
+
await mkdir(tasksDir, { recursive: true });
|
|
120
|
+
const suffixLength = idSuffixLengthDefault;
|
|
121
|
+
const id = await (opts.idGenerator ?? generateTaskId)({
|
|
122
|
+
length: suffixLength,
|
|
123
|
+
attempts: 20,
|
|
124
|
+
isAvailable: async (taskId) => !(await fileExists(taskReadmePath(tasksDir, taskId))),
|
|
125
|
+
});
|
|
126
|
+
const readmePath = taskReadmePath(tasksDir, id);
|
|
127
|
+
const frontmatter = {
|
|
128
|
+
id,
|
|
129
|
+
title: opts.title,
|
|
130
|
+
status: "TODO",
|
|
131
|
+
priority: opts.priority,
|
|
132
|
+
owner: opts.owner,
|
|
133
|
+
depends_on: opts.dependsOn,
|
|
134
|
+
tags: opts.tags,
|
|
135
|
+
verify: opts.verify,
|
|
136
|
+
comments: [],
|
|
137
|
+
doc_version: 2,
|
|
138
|
+
doc_updated_at: nowIso(),
|
|
139
|
+
doc_updated_by: opts.owner,
|
|
140
|
+
description: opts.description,
|
|
141
|
+
};
|
|
142
|
+
const body = defaultTaskBody();
|
|
143
|
+
const text = renderTaskReadme(frontmatter, body);
|
|
144
|
+
await mkdir(path.dirname(readmePath), { recursive: true });
|
|
145
|
+
await writeFile(readmePath, text, "utf8");
|
|
146
|
+
return { id, readmePath };
|
|
147
|
+
}
|
|
148
|
+
export async function setTaskDocSection(opts) {
|
|
149
|
+
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
150
|
+
const loaded = await loadConfig(resolved.agentplaneDir);
|
|
151
|
+
const allowed = loaded.config.tasks.doc.sections;
|
|
152
|
+
if (!allowed.includes(opts.section)) {
|
|
153
|
+
throw new Error(`Unknown doc section: ${opts.section}`);
|
|
154
|
+
}
|
|
155
|
+
const tasksDir = path.join(resolved.gitRoot, loaded.config.paths.workflow_dir);
|
|
156
|
+
const readmePath = taskReadmePath(tasksDir, opts.taskId);
|
|
157
|
+
const original = await readFile(readmePath, "utf8");
|
|
158
|
+
const parsed = parseTaskReadme(original);
|
|
159
|
+
const updatedBy = resolveDocUpdatedBy(parsed.frontmatter, opts.updatedBy);
|
|
160
|
+
const nextFrontmatter = {
|
|
161
|
+
...parsed.frontmatter,
|
|
162
|
+
doc_version: 2,
|
|
163
|
+
doc_updated_at: nowIso(),
|
|
164
|
+
doc_updated_by: updatedBy,
|
|
165
|
+
};
|
|
166
|
+
const baseDoc = ensureDocSections(parsed.body, loaded.config.tasks.doc.required_sections);
|
|
167
|
+
const nextBody = ensureDocSections(setMarkdownSection(baseDoc, opts.section, opts.text), loaded.config.tasks.doc.required_sections);
|
|
168
|
+
const nextText = renderTaskReadme(nextFrontmatter, nextBody);
|
|
169
|
+
await writeFile(readmePath, nextText, "utf8");
|
|
170
|
+
return { readmePath };
|
|
171
|
+
}
|
|
172
|
+
export async function readTask(opts) {
|
|
173
|
+
const { tasksDir } = await getTasksDir({
|
|
174
|
+
cwd: opts.cwd,
|
|
175
|
+
rootOverride: opts.rootOverride ?? null,
|
|
176
|
+
});
|
|
177
|
+
const readmePath = taskReadmePath(tasksDir, opts.taskId);
|
|
178
|
+
const text = await readFile(readmePath, "utf8");
|
|
179
|
+
const parsed = parseTaskReadme(text);
|
|
180
|
+
return {
|
|
181
|
+
id: opts.taskId,
|
|
182
|
+
frontmatter: parsed.frontmatter,
|
|
183
|
+
body: parsed.body,
|
|
184
|
+
readmePath,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
export async function listTasks(opts) {
|
|
188
|
+
const { tasksDir } = await getTasksDir({
|
|
189
|
+
cwd: opts.cwd,
|
|
190
|
+
rootOverride: opts.rootOverride ?? null,
|
|
191
|
+
});
|
|
192
|
+
const entries = await readdir(tasksDir, { withFileTypes: true }).catch(() => []);
|
|
193
|
+
const ids = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
194
|
+
const tasks = [];
|
|
195
|
+
for (const id of ids) {
|
|
196
|
+
const readmePath = taskReadmePath(tasksDir, id);
|
|
197
|
+
try {
|
|
198
|
+
const text = await readFile(readmePath, "utf8");
|
|
199
|
+
const parsed = parseTaskReadme(text);
|
|
200
|
+
tasks.push({
|
|
201
|
+
id,
|
|
202
|
+
frontmatter: parsed.frontmatter,
|
|
203
|
+
body: parsed.body,
|
|
204
|
+
readmePath,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Skip unreadable/broken tasks for now; lint will handle this later.
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return tasks.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
212
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-export.d.ts","sourceRoot":"","sources":["../../src/tasks/tasks-export.ts"],"names":[],"mappings":"AAaA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWxD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,QAAQ,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C,WAAW,EAAE,CAAC,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,IAAI,EAAE,eAAe,CAAC;CACvB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,CAEtE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,CAGrE;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqE/B;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAW3D"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { mkdir
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { loadConfig } from "
|
|
5
|
-
import {
|
|
4
|
+
import { loadConfig } from "../config/config.js";
|
|
5
|
+
import { atomicWriteFile } from "../fs/atomic-write.js";
|
|
6
|
+
import { resolveProject } from "../project/project-root.js";
|
|
6
7
|
import { listTasks } from "./task-store.js";
|
|
7
8
|
function isRecord(value) {
|
|
8
9
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -91,6 +92,6 @@ export async function writeTasksExport(opts) {
|
|
|
91
92
|
const outPath = path.join(resolved.gitRoot, loaded.config.paths.tasks_path);
|
|
92
93
|
const snapshot = await buildTasksExportSnapshot(opts);
|
|
93
94
|
await mkdir(path.dirname(outPath), { recursive: true });
|
|
94
|
-
await
|
|
95
|
+
await atomicWriteFile(outPath, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
95
96
|
return { path: outPath, snapshot };
|
|
96
97
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-lint.d.ts","sourceRoot":"","sources":["../../src/tasks/tasks-lint.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AA2DF,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,gBAAgB,GACvB,eAAe,CA4GjB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAOrF;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,eAAe,CAAC,CAG3B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { loadConfig } from "
|
|
4
|
-
import { resolveProject } from "
|
|
3
|
+
import { loadConfig } from "../config/config.js";
|
|
4
|
+
import { resolveProject } from "../project/project-root.js";
|
|
5
5
|
import { computeTasksChecksum, } from "./tasks-export.js";
|
|
6
6
|
function isRecord(value) {
|
|
7
7
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentplaneorg/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Core utilities and models for the Agent Plane CLI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentplane",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"types": "./dist/index.d.ts",
|
|
31
31
|
"files": [
|
|
32
32
|
"dist",
|
|
33
|
+
"schemas",
|
|
33
34
|
"README.md",
|
|
34
35
|
"LICENSE"
|
|
35
36
|
],
|
|
@@ -43,6 +44,8 @@
|
|
|
43
44
|
"prepack": "bun run clean && bun run build"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
47
|
+
"ajv": "^8.17.1",
|
|
48
|
+
"ajv-formats": "^3.0.1",
|
|
46
49
|
"yaml": "^2.8.2"
|
|
47
50
|
}
|
|
48
51
|
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://agentplane.dev/schemas/config.schema.json",
|
|
4
|
+
"title": "agentplane config.json (v1)",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": ["schema_version", "workflow_mode", "paths", "tasks", "commit", "tasks_backend"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "type": "integer", "const": 1, "default": 1 },
|
|
10
|
+
"workflow_mode": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": ["direct", "branch_pr"],
|
|
13
|
+
"default": "direct"
|
|
14
|
+
},
|
|
15
|
+
"status_commit_policy": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["off", "warn", "confirm"],
|
|
18
|
+
"default": "warn"
|
|
19
|
+
},
|
|
20
|
+
"finish_auto_status_commit": { "type": "boolean", "default": true },
|
|
21
|
+
"base_branch": { "type": "string", "minLength": 1, "default": "main" },
|
|
22
|
+
"agents": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": true,
|
|
25
|
+
"required": ["approvals"],
|
|
26
|
+
"default": {
|
|
27
|
+
"approvals": { "require_plan": true, "require_network": true, "require_verify": true }
|
|
28
|
+
},
|
|
29
|
+
"properties": {
|
|
30
|
+
"approvals": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": true,
|
|
33
|
+
"required": ["require_plan", "require_network", "require_verify"],
|
|
34
|
+
"default": { "require_plan": true, "require_network": true, "require_verify": true },
|
|
35
|
+
"properties": {
|
|
36
|
+
"require_plan": { "type": "boolean", "default": true },
|
|
37
|
+
"require_network": { "type": "boolean", "default": true },
|
|
38
|
+
"require_verify": { "type": "boolean", "default": true }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"recipes": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"additionalProperties": true,
|
|
46
|
+
"required": ["storage_default"],
|
|
47
|
+
"default": { "storage_default": "link" },
|
|
48
|
+
"properties": {
|
|
49
|
+
"storage_default": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": ["link", "copy", "global"],
|
|
52
|
+
"default": "link"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"paths": {
|
|
57
|
+
"type": "object",
|
|
58
|
+
"additionalProperties": true,
|
|
59
|
+
"required": ["agents_dir", "tasks_path", "workflow_dir", "worktrees_dir"],
|
|
60
|
+
"default": {
|
|
61
|
+
"agents_dir": ".agentplane/agents",
|
|
62
|
+
"tasks_path": ".agentplane/tasks.json",
|
|
63
|
+
"workflow_dir": ".agentplane/tasks",
|
|
64
|
+
"worktrees_dir": ".agentplane/worktrees"
|
|
65
|
+
},
|
|
66
|
+
"properties": {
|
|
67
|
+
"agents_dir": { "type": "string", "minLength": 1, "default": ".agentplane/agents" },
|
|
68
|
+
"tasks_path": { "type": "string", "minLength": 1, "default": ".agentplane/tasks.json" },
|
|
69
|
+
"workflow_dir": { "type": "string", "minLength": 1, "default": ".agentplane/tasks" },
|
|
70
|
+
"worktrees_dir": { "type": "string", "minLength": 1, "default": ".agentplane/worktrees" }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"branch": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": true,
|
|
76
|
+
"required": ["task_prefix"],
|
|
77
|
+
"default": { "task_prefix": "task" },
|
|
78
|
+
"properties": {
|
|
79
|
+
"task_prefix": { "type": "string", "minLength": 1, "default": "task" }
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"framework": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"additionalProperties": true,
|
|
85
|
+
"required": ["source", "last_update"],
|
|
86
|
+
"default": {
|
|
87
|
+
"source": "https://github.com/basilisk-labs/agent-plane",
|
|
88
|
+
"last_update": null
|
|
89
|
+
},
|
|
90
|
+
"properties": {
|
|
91
|
+
"source": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"minLength": 1,
|
|
94
|
+
"default": "https://github.com/basilisk-labs/agent-plane"
|
|
95
|
+
},
|
|
96
|
+
"last_update": {
|
|
97
|
+
"type": ["string", "null"],
|
|
98
|
+
"format": "date-time",
|
|
99
|
+
"default": null
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"tasks": {
|
|
104
|
+
"type": "object",
|
|
105
|
+
"additionalProperties": true,
|
|
106
|
+
"required": ["id_suffix_length_default", "verify", "doc", "comments"],
|
|
107
|
+
"default": {
|
|
108
|
+
"id_suffix_length_default": 6,
|
|
109
|
+
"verify": { "required_tags": ["code", "backend", "frontend"] },
|
|
110
|
+
"doc": {
|
|
111
|
+
"sections": [
|
|
112
|
+
"Summary",
|
|
113
|
+
"Context",
|
|
114
|
+
"Scope",
|
|
115
|
+
"Risks",
|
|
116
|
+
"Verify Steps",
|
|
117
|
+
"Verification",
|
|
118
|
+
"Rollback Plan",
|
|
119
|
+
"Notes"
|
|
120
|
+
],
|
|
121
|
+
"required_sections": [
|
|
122
|
+
"Summary",
|
|
123
|
+
"Scope",
|
|
124
|
+
"Risks",
|
|
125
|
+
"Verify Steps",
|
|
126
|
+
"Verification",
|
|
127
|
+
"Rollback Plan"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
"comments": {
|
|
131
|
+
"start": { "prefix": "Start:", "min_chars": 40 },
|
|
132
|
+
"blocked": { "prefix": "Blocked:", "min_chars": 40 },
|
|
133
|
+
"verified": { "prefix": "Verified:", "min_chars": 60 }
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"properties": {
|
|
137
|
+
"id_suffix_length_default": {
|
|
138
|
+
"type": "integer",
|
|
139
|
+
"minimum": 3,
|
|
140
|
+
"maximum": 16,
|
|
141
|
+
"default": 6
|
|
142
|
+
},
|
|
143
|
+
"verify": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"additionalProperties": true,
|
|
146
|
+
"required": ["required_tags"],
|
|
147
|
+
"default": { "required_tags": ["code", "backend", "frontend"] },
|
|
148
|
+
"properties": {
|
|
149
|
+
"required_tags": {
|
|
150
|
+
"type": "array",
|
|
151
|
+
"items": { "type": "string", "minLength": 1 },
|
|
152
|
+
"uniqueItems": true,
|
|
153
|
+
"default": ["code", "backend", "frontend"]
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"doc": {
|
|
158
|
+
"type": "object",
|
|
159
|
+
"additionalProperties": true,
|
|
160
|
+
"required": ["sections", "required_sections"],
|
|
161
|
+
"default": {
|
|
162
|
+
"sections": [
|
|
163
|
+
"Summary",
|
|
164
|
+
"Context",
|
|
165
|
+
"Scope",
|
|
166
|
+
"Risks",
|
|
167
|
+
"Verify Steps",
|
|
168
|
+
"Verification",
|
|
169
|
+
"Rollback Plan",
|
|
170
|
+
"Notes"
|
|
171
|
+
],
|
|
172
|
+
"required_sections": [
|
|
173
|
+
"Summary",
|
|
174
|
+
"Scope",
|
|
175
|
+
"Risks",
|
|
176
|
+
"Verify Steps",
|
|
177
|
+
"Verification",
|
|
178
|
+
"Rollback Plan"
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"properties": {
|
|
182
|
+
"sections": {
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": { "type": "string", "minLength": 1 },
|
|
185
|
+
"default": [
|
|
186
|
+
"Summary",
|
|
187
|
+
"Context",
|
|
188
|
+
"Scope",
|
|
189
|
+
"Risks",
|
|
190
|
+
"Verify Steps",
|
|
191
|
+
"Verification",
|
|
192
|
+
"Rollback Plan",
|
|
193
|
+
"Notes"
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
"required_sections": {
|
|
197
|
+
"type": "array",
|
|
198
|
+
"items": { "type": "string", "minLength": 1 },
|
|
199
|
+
"default": [
|
|
200
|
+
"Summary",
|
|
201
|
+
"Scope",
|
|
202
|
+
"Risks",
|
|
203
|
+
"Verify Steps",
|
|
204
|
+
"Verification",
|
|
205
|
+
"Rollback Plan"
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"comments": {
|
|
211
|
+
"type": "object",
|
|
212
|
+
"additionalProperties": true,
|
|
213
|
+
"required": ["start", "blocked", "verified"],
|
|
214
|
+
"default": {
|
|
215
|
+
"start": { "prefix": "Start:", "min_chars": 40 },
|
|
216
|
+
"blocked": { "prefix": "Blocked:", "min_chars": 40 },
|
|
217
|
+
"verified": { "prefix": "Verified:", "min_chars": 60 }
|
|
218
|
+
},
|
|
219
|
+
"properties": {
|
|
220
|
+
"start": {
|
|
221
|
+
"$ref": "#/$defs/comment_policy",
|
|
222
|
+
"default": { "prefix": "Start:", "min_chars": 40 }
|
|
223
|
+
},
|
|
224
|
+
"blocked": {
|
|
225
|
+
"$ref": "#/$defs/comment_policy",
|
|
226
|
+
"default": { "prefix": "Blocked:", "min_chars": 40 }
|
|
227
|
+
},
|
|
228
|
+
"verified": {
|
|
229
|
+
"$ref": "#/$defs/comment_policy",
|
|
230
|
+
"default": { "prefix": "Verified:", "min_chars": 60 }
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"commit": {
|
|
237
|
+
"type": "object",
|
|
238
|
+
"additionalProperties": true,
|
|
239
|
+
"required": ["generic_tokens"],
|
|
240
|
+
"default": {
|
|
241
|
+
"generic_tokens": ["start", "status", "mark", "done", "wip", "update", "tasks", "task"]
|
|
242
|
+
},
|
|
243
|
+
"properties": {
|
|
244
|
+
"generic_tokens": {
|
|
245
|
+
"type": "array",
|
|
246
|
+
"items": { "type": "string", "minLength": 1 },
|
|
247
|
+
"uniqueItems": true,
|
|
248
|
+
"default": ["start", "status", "mark", "done", "wip", "update", "tasks", "task"]
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"tasks_backend": {
|
|
253
|
+
"type": "object",
|
|
254
|
+
"additionalProperties": true,
|
|
255
|
+
"required": ["config_path"],
|
|
256
|
+
"default": { "config_path": ".agentplane/backends/local/backend.json" },
|
|
257
|
+
"properties": {
|
|
258
|
+
"config_path": {
|
|
259
|
+
"type": "string",
|
|
260
|
+
"minLength": 1,
|
|
261
|
+
"default": ".agentplane/backends/local/backend.json"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"closure_commit_requires_approval": { "type": "boolean", "default": false }
|
|
266
|
+
},
|
|
267
|
+
"$defs": {
|
|
268
|
+
"comment_policy": {
|
|
269
|
+
"type": "object",
|
|
270
|
+
"additionalProperties": true,
|
|
271
|
+
"required": ["prefix", "min_chars"],
|
|
272
|
+
"properties": {
|
|
273
|
+
"prefix": { "type": "string", "minLength": 1 },
|
|
274
|
+
"min_chars": { "type": "integer", "minimum": 0 }
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-branch.d.ts","sourceRoot":"","sources":["../src/base-branch.ts"],"names":[],"mappings":"AA0BA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commit-policy.d.ts","sourceRoot":"","sources":["../src/commit-policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAMF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAOlF;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,kBAAkB,CAerB"}
|
package/dist/config.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAClD,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,CAAC,CAAC;IAClB,aAAa,EAAE,YAAY,CAAC;IAC5B,oBAAoB,EAAE,kBAAkB,CAAC;IACzC,yBAAyB,EAAE,OAAO,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,SAAS,EAAE;YACT,YAAY,EAAE,OAAO,CAAC;YACtB,eAAe,EAAE,OAAO,CAAC;SAC1B,CAAC;KACH,CAAC;IACF,OAAO,CAAC,EAAE;QACR,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;KAC7C,CAAC;IACF,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1D,KAAK,EAAE;QACL,wBAAwB,EAAE,MAAM,CAAC;QACjC,MAAM,EAAE;YAAE,aAAa,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACpC,GAAG,EAAE;YAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACzD,QAAQ,EAAE;YACR,KAAK,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CAAC;YAC7C,OAAO,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CAAC;YAC/C,QAAQ,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,MAAM,CAAA;aAAE,CAAC;SACjD,CAAC;KACH,CAAC;IACF,MAAM,EAAE;QAAE,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrC,aAAa,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,gCAAgC,EAAE,OAAO,CAAC;CAC3C,CAAC;AAEF,wBAAgB,aAAa,IAAI,gBAAgB,CAmDhD;AAMD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAiG7D;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B,CAAC;AAQF,wBAAsB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAyB7E;AAkBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,IAAI,CAgBN;AAED,wBAAsB,UAAU,CAC9B,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAO3B"}
|