@agentplaneorg/core 0.1.7 → 0.1.8
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/config/config.d.ts.map +1 -1
- package/dist/config/config.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/tasks/task-readme-io.d.ts +7 -0
- package/dist/tasks/task-readme-io.d.ts.map +1 -0
- package/dist/tasks/task-readme-io.js +14 -0
- package/dist/tasks/task-readme.d.ts.map +1 -1
- package/dist/tasks/task-readme.js +62 -38
- package/dist/tasks/task-store.d.ts +12 -0
- package/dist/tasks/task-store.d.ts.map +1 -1
- package/dist/tasks/task-store.js +40 -18
- package/package.json +1 -1
- package/schemas/config.schema.json +6 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAWA,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,MAAM,CAAC,EAAE;QACP,SAAS,EAAE;YACT,YAAY,EAAE,OAAO,CAAC;YACtB,eAAe,EAAE,OAAO,CAAC;YACzB,cAAc,EAAE,OAAO,CAAC;SACzB,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,CAEhD;AAkED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAa7D;AAID,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,CA8B7E;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,CAS3B"}
|
package/dist/config/config.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { mkdir, readFile
|
|
2
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import AjvModule from "ajv";
|
|
6
6
|
import AjvFormatsModule from "ajv-formats";
|
|
7
|
+
import { atomicWriteFile } from "../fs/atomic-write.js";
|
|
7
8
|
export function defaultConfig() {
|
|
8
9
|
return structuredClone(DEFAULT_CONFIG);
|
|
9
10
|
}
|
|
@@ -148,6 +149,6 @@ export async function saveConfig(agentplaneDir, raw) {
|
|
|
148
149
|
await mkdir(agentplaneDir, { recursive: true });
|
|
149
150
|
const filePath = path.join(agentplaneDir, "config.json");
|
|
150
151
|
const text = `${JSON.stringify(sanitized.sanitized, null, 2)}\n`;
|
|
151
|
-
await
|
|
152
|
+
await atomicWriteFile(filePath, text, "utf8");
|
|
152
153
|
return validated;
|
|
153
154
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const CORE_VERSION = "0.0.0";
|
|
|
2
2
|
export { findGitRoot, resolveProject, type ResolvedProject, type ResolveProjectOptions, } from "./project/project-root.js";
|
|
3
3
|
export { defaultConfig, loadConfig, saveConfig, setByDottedKey, validateConfig, type AgentplaneConfig, type LoadedConfig, type StatusCommitPolicy, type WorkflowMode, } from "./config/config.js";
|
|
4
4
|
export { parseTaskReadme, renderTaskFrontmatter, renderTaskReadme, type ParsedTaskReadme, } from "./tasks/task-readme.js";
|
|
5
|
+
export { readTaskReadme, updateTaskReadmeAtomic } from "./tasks/task-readme-io.js";
|
|
5
6
|
export { docChanged, ensureDocSections, extractTaskDoc, mergeTaskDoc, normalizeDocSectionName, normalizeTaskDoc, parseDocSections, setMarkdownSection, splitCombinedHeadingLines, } from "./tasks/task-doc.js";
|
|
6
7
|
export { atomicWriteFile } from "./fs/atomic-write.js";
|
|
7
8
|
export { generateTaskId, timestampIdPrefix, TASK_ID_ALPHABET } from "./tasks/task-id.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,OAAO,EACL,WAAW,EACX,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,aAAa,EACb,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzF,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,OAAO,EACL,WAAW,EACX,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,aAAa,EACb,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnF,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzF,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export const CORE_VERSION = "0.0.0";
|
|
|
2
2
|
export { findGitRoot, resolveProject, } from "./project/project-root.js";
|
|
3
3
|
export { defaultConfig, loadConfig, saveConfig, setByDottedKey, validateConfig, } from "./config/config.js";
|
|
4
4
|
export { parseTaskReadme, renderTaskFrontmatter, renderTaskReadme, } from "./tasks/task-readme.js";
|
|
5
|
+
export { readTaskReadme, updateTaskReadmeAtomic } from "./tasks/task-readme-io.js";
|
|
5
6
|
export { docChanged, ensureDocSections, extractTaskDoc, mergeTaskDoc, normalizeDocSectionName, normalizeTaskDoc, parseDocSections, setMarkdownSection, splitCombinedHeadingLines, } from "./tasks/task-doc.js";
|
|
6
7
|
export { atomicWriteFile } from "./fs/atomic-write.js";
|
|
7
8
|
export { generateTaskId, timestampIdPrefix, TASK_ID_ALPHABET } from "./tasks/task-id.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ParsedTaskReadme } from "./task-readme.js";
|
|
2
|
+
export declare function readTaskReadme(readmePath: string): Promise<ParsedTaskReadme>;
|
|
3
|
+
export declare function updateTaskReadmeAtomic(readmePath: string, updater: (parsed: ParsedTaskReadme) => {
|
|
4
|
+
frontmatter: Record<string, unknown>;
|
|
5
|
+
body: string;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=task-readme-io.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-readme-io.d.ts","sourceRoot":"","sources":["../../src/tasks/task-readme-io.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqC,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE5F,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGlF;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK;IAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5F,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { atomicWriteFile } from "../fs/atomic-write.js";
|
|
3
|
+
import { parseTaskReadme, renderTaskReadme } from "./task-readme.js";
|
|
4
|
+
export async function readTaskReadme(readmePath) {
|
|
5
|
+
const text = await readFile(readmePath, "utf8");
|
|
6
|
+
return parseTaskReadme(text);
|
|
7
|
+
}
|
|
8
|
+
export async function updateTaskReadmeAtomic(readmePath, updater) {
|
|
9
|
+
const text = await readFile(readmePath, "utf8");
|
|
10
|
+
const parsed = parseTaskReadme(text);
|
|
11
|
+
const next = updater(parsed);
|
|
12
|
+
const rendered = renderTaskReadme(next.frontmatter, next.body);
|
|
13
|
+
await atomicWriteFile(readmePath, rendered.endsWith("\n") ? rendered : `${rendered}\n`);
|
|
14
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-readme.d.ts","sourceRoot":"","sources":["../../src/tasks/task-readme.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-readme.d.ts","sourceRoot":"","sources":["../../src/tasks/task-readme.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAqBF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAYlE;AAkFD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAiClF;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|
|
@@ -2,6 +2,18 @@ import { parse as parseYaml } from "yaml";
|
|
|
2
2
|
function isRecord(value) {
|
|
3
3
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
4
4
|
}
|
|
5
|
+
function orderedKeys(value, preferredKeyOrder) {
|
|
6
|
+
const keys = Object.keys(value);
|
|
7
|
+
const ordered = [];
|
|
8
|
+
if (preferredKeyOrder) {
|
|
9
|
+
for (const k of preferredKeyOrder)
|
|
10
|
+
if (k in value)
|
|
11
|
+
ordered.push(k);
|
|
12
|
+
}
|
|
13
|
+
const remaining = keys.filter((k) => !ordered.includes(k)).toSorted((a, b) => a.localeCompare(b));
|
|
14
|
+
ordered.push(...remaining);
|
|
15
|
+
return ordered;
|
|
16
|
+
}
|
|
5
17
|
function stripLeadingFrontmatterBlocks(body) {
|
|
6
18
|
let next = body.replaceAll("\r\n", "\n");
|
|
7
19
|
while (true) {
|
|
@@ -44,58 +56,69 @@ function renderScalar(value) {
|
|
|
44
56
|
return value ? "true" : "false";
|
|
45
57
|
throw new TypeError(`Unsupported scalar type: ${typeof value}`);
|
|
46
58
|
}
|
|
47
|
-
function renderInlineMap(value, preferredKeyOrder) {
|
|
48
|
-
const keys = Object.keys(value);
|
|
49
|
-
const ordered = [];
|
|
50
|
-
if (preferredKeyOrder) {
|
|
51
|
-
for (const k of preferredKeyOrder)
|
|
52
|
-
if (k in value)
|
|
53
|
-
ordered.push(k);
|
|
54
|
-
}
|
|
55
|
-
const remaining = keys.filter((k) => !ordered.includes(k)).toSorted((a, b) => a.localeCompare(b));
|
|
56
|
-
ordered.push(...remaining);
|
|
57
|
-
const parts = ordered.map((k) => {
|
|
58
|
-
const v = value[k];
|
|
59
|
-
if (Array.isArray(v))
|
|
60
|
-
return `${k}: ${renderFlowSeq(v)}`;
|
|
61
|
-
if (isRecord(v))
|
|
62
|
-
return `${k}: ${renderInlineMap(v, null)}`;
|
|
63
|
-
return `${k}: ${renderScalar(v)}`;
|
|
64
|
-
});
|
|
65
|
-
return `{ ${parts.join(", ")} }`;
|
|
66
|
-
}
|
|
67
59
|
function renderFlowSeq(value) {
|
|
68
60
|
const parts = value.map((v) => {
|
|
69
61
|
if (Array.isArray(v))
|
|
70
62
|
return renderFlowSeq(v);
|
|
71
63
|
if (isRecord(v))
|
|
72
|
-
return
|
|
64
|
+
return `{ ${orderedKeys(v, null)
|
|
65
|
+
.map((k) => `${k}: ${renderScalar(v[k])}`)
|
|
66
|
+
.join(", ")} }`;
|
|
73
67
|
return renderScalar(v);
|
|
74
68
|
});
|
|
75
69
|
return `[${parts.join(", ")}]`;
|
|
76
70
|
}
|
|
77
|
-
function
|
|
71
|
+
function renderMapLines(value, indent, preferredKeyOrder) {
|
|
72
|
+
const keys = orderedKeys(value, preferredKeyOrder);
|
|
73
|
+
const lines = [];
|
|
74
|
+
for (const k of keys) {
|
|
75
|
+
const v = value[k];
|
|
76
|
+
lines.push(...renderValueLines(k, v, indent));
|
|
77
|
+
}
|
|
78
|
+
return lines;
|
|
79
|
+
}
|
|
80
|
+
function isStringArray(value) {
|
|
81
|
+
return value.every((v) => typeof v === "string");
|
|
82
|
+
}
|
|
83
|
+
function renderValueLines(key, value, indent) {
|
|
78
84
|
if (Array.isArray(value)) {
|
|
79
85
|
if (value.length === 0)
|
|
80
|
-
return [`${key}: []`];
|
|
86
|
+
return [`${indent}${key}: []`];
|
|
87
|
+
if (isStringArray(value)) {
|
|
88
|
+
return [`${indent}${key}:`, ...value.map((item) => `${indent} - ${renderScalar(item)}`)];
|
|
89
|
+
}
|
|
81
90
|
const allObjects = value.every((v) => isRecord(v));
|
|
82
91
|
if (!allObjects)
|
|
83
|
-
return [`${key}: ${renderFlowSeq(value)}`];
|
|
92
|
+
return [`${indent}${key}: ${renderFlowSeq(value)}`];
|
|
84
93
|
return [
|
|
85
|
-
`${key}:`,
|
|
86
|
-
...value.
|
|
94
|
+
`${indent}${key}:`,
|
|
95
|
+
...value.flatMap((item) => {
|
|
87
96
|
if (!isRecord(item))
|
|
88
97
|
throw new TypeError("Expected an object item in YAML sequence");
|
|
89
98
|
const preferred = key === "comments" ? ["author", "body"] : null;
|
|
90
|
-
|
|
99
|
+
const itemLines = renderMapLines(item, `${indent} `, preferred);
|
|
100
|
+
if (itemLines.length === 0)
|
|
101
|
+
return [`${indent} - {}`];
|
|
102
|
+
return [`${indent} -`, ...itemLines];
|
|
91
103
|
}),
|
|
92
104
|
];
|
|
93
105
|
}
|
|
94
106
|
if (isRecord(value)) {
|
|
95
|
-
const preferred = key === "
|
|
96
|
-
|
|
107
|
+
const preferred = key === "origin"
|
|
108
|
+
? ["system", "issue_id", "url"]
|
|
109
|
+
: key === "plan_approval"
|
|
110
|
+
? ["state", "updated_at", "updated_by", "note"]
|
|
111
|
+
: key === "verification"
|
|
112
|
+
? ["state", "updated_at", "updated_by", "note"]
|
|
113
|
+
: key === "commit"
|
|
114
|
+
? ["hash", "message"]
|
|
115
|
+
: null;
|
|
116
|
+
const inner = renderMapLines(value, `${indent} `, preferred);
|
|
117
|
+
if (inner.length === 0)
|
|
118
|
+
return [`${indent}${key}: {}`];
|
|
119
|
+
return [`${indent}${key}:`, ...inner];
|
|
97
120
|
}
|
|
98
|
-
return [`${key}: ${renderScalar(value)}`];
|
|
121
|
+
return [`${indent}${key}: ${renderScalar(value)}`];
|
|
99
122
|
}
|
|
100
123
|
export function renderTaskFrontmatter(frontmatter) {
|
|
101
124
|
const preferredKeyOrder = [
|
|
@@ -104,26 +127,27 @@ export function renderTaskFrontmatter(frontmatter) {
|
|
|
104
127
|
"status",
|
|
105
128
|
"priority",
|
|
106
129
|
"owner",
|
|
130
|
+
"created_at",
|
|
131
|
+
"created_by",
|
|
132
|
+
"origin",
|
|
107
133
|
"depends_on",
|
|
108
134
|
"tags",
|
|
109
135
|
"verify",
|
|
136
|
+
"plan_approval",
|
|
137
|
+
"verification",
|
|
110
138
|
"commit",
|
|
111
139
|
"comments",
|
|
112
140
|
"doc_version",
|
|
113
141
|
"doc_updated_at",
|
|
114
142
|
"doc_updated_by",
|
|
115
143
|
"description",
|
|
144
|
+
"id_source",
|
|
145
|
+
"dirty",
|
|
116
146
|
];
|
|
117
|
-
const
|
|
118
|
-
const ordered = [];
|
|
119
|
-
for (const k of preferredKeyOrder)
|
|
120
|
-
if (k in frontmatter)
|
|
121
|
-
ordered.push(k);
|
|
122
|
-
const remaining = keys.filter((k) => !ordered.includes(k)).toSorted((a, b) => a.localeCompare(b));
|
|
123
|
-
ordered.push(...remaining);
|
|
147
|
+
const ordered = orderedKeys(frontmatter, preferredKeyOrder);
|
|
124
148
|
const lines = [];
|
|
125
149
|
for (const k of ordered) {
|
|
126
|
-
lines.push(...
|
|
150
|
+
lines.push(...renderValueLines(k, frontmatter[k], ""));
|
|
127
151
|
}
|
|
128
152
|
return `---\n${lines.join("\n")}\n---\n`;
|
|
129
153
|
}
|
|
@@ -10,6 +10,18 @@ export type TaskFrontmatter = {
|
|
|
10
10
|
depends_on: string[];
|
|
11
11
|
tags: string[];
|
|
12
12
|
verify: string[];
|
|
13
|
+
plan_approval?: {
|
|
14
|
+
state: "pending" | "approved" | "rejected";
|
|
15
|
+
updated_at: string | null;
|
|
16
|
+
updated_by: string | null;
|
|
17
|
+
note: string | null;
|
|
18
|
+
};
|
|
19
|
+
verification?: {
|
|
20
|
+
state: "pending" | "ok" | "needs_rework";
|
|
21
|
+
updated_at: string | null;
|
|
22
|
+
updated_by: string | null;
|
|
23
|
+
note: string | null;
|
|
24
|
+
};
|
|
13
25
|
comments: {
|
|
14
26
|
author: string;
|
|
15
27
|
body: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/tasks/task-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/tasks/task-store.ts"],"names":[],"mappings":"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"}
|
package/dist/tasks/task-store.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { mkdir, readdir, readFile
|
|
1
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { loadConfig } from "../config/config.js";
|
|
4
|
+
import { atomicWriteFile } from "../fs/atomic-write.js";
|
|
4
5
|
import { resolveProject } from "../project/project-root.js";
|
|
5
6
|
import { parseTaskReadme, renderTaskReadme } from "./task-readme.js";
|
|
7
|
+
import { updateTaskReadmeAtomic } from "./task-readme-io.js";
|
|
6
8
|
import { ensureDocSections, setMarkdownSection } from "./task-doc.js";
|
|
7
9
|
import { generateTaskId } from "./task-id.js";
|
|
8
10
|
function nowIso() {
|
|
@@ -55,15 +57,25 @@ function defaultTaskBody() {
|
|
|
55
57
|
"## Scope",
|
|
56
58
|
"",
|
|
57
59
|
"",
|
|
58
|
-
"##
|
|
60
|
+
"## Plan",
|
|
59
61
|
"",
|
|
60
62
|
"",
|
|
61
|
-
"##
|
|
63
|
+
"## Risks",
|
|
62
64
|
"",
|
|
63
65
|
"",
|
|
64
66
|
"## Verification",
|
|
65
67
|
"",
|
|
66
68
|
"",
|
|
69
|
+
"### Plan",
|
|
70
|
+
"",
|
|
71
|
+
"",
|
|
72
|
+
"### Results",
|
|
73
|
+
"",
|
|
74
|
+
"",
|
|
75
|
+
"<!-- BEGIN VERIFICATION RESULTS -->",
|
|
76
|
+
"<!-- END VERIFICATION RESULTS -->",
|
|
77
|
+
"",
|
|
78
|
+
"",
|
|
67
79
|
"## Rollback Plan",
|
|
68
80
|
"",
|
|
69
81
|
].join("\n");
|
|
@@ -133,6 +145,18 @@ export async function createTask(opts) {
|
|
|
133
145
|
depends_on: opts.dependsOn,
|
|
134
146
|
tags: opts.tags,
|
|
135
147
|
verify: opts.verify,
|
|
148
|
+
plan_approval: {
|
|
149
|
+
state: "pending",
|
|
150
|
+
updated_at: null,
|
|
151
|
+
updated_by: null,
|
|
152
|
+
note: null,
|
|
153
|
+
},
|
|
154
|
+
verification: {
|
|
155
|
+
state: "pending",
|
|
156
|
+
updated_at: null,
|
|
157
|
+
updated_by: null,
|
|
158
|
+
note: null,
|
|
159
|
+
},
|
|
136
160
|
comments: [],
|
|
137
161
|
doc_version: 2,
|
|
138
162
|
doc_updated_at: nowIso(),
|
|
@@ -141,8 +165,7 @@ export async function createTask(opts) {
|
|
|
141
165
|
};
|
|
142
166
|
const body = defaultTaskBody();
|
|
143
167
|
const text = renderTaskReadme(frontmatter, body);
|
|
144
|
-
await
|
|
145
|
-
await writeFile(readmePath, text, "utf8");
|
|
168
|
+
await atomicWriteFile(readmePath, text, "utf8");
|
|
146
169
|
return { id, readmePath };
|
|
147
170
|
}
|
|
148
171
|
export async function setTaskDocSection(opts) {
|
|
@@ -154,19 +177,18 @@ export async function setTaskDocSection(opts) {
|
|
|
154
177
|
}
|
|
155
178
|
const tasksDir = path.join(resolved.gitRoot, loaded.config.paths.workflow_dir);
|
|
156
179
|
const readmePath = taskReadmePath(tasksDir, opts.taskId);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
await writeFile(readmePath, nextText, "utf8");
|
|
180
|
+
await updateTaskReadmeAtomic(readmePath, (parsed) => {
|
|
181
|
+
const updatedBy = resolveDocUpdatedBy(parsed.frontmatter, opts.updatedBy);
|
|
182
|
+
const nextFrontmatter = {
|
|
183
|
+
...parsed.frontmatter,
|
|
184
|
+
doc_version: 2,
|
|
185
|
+
doc_updated_at: nowIso(),
|
|
186
|
+
doc_updated_by: updatedBy,
|
|
187
|
+
};
|
|
188
|
+
const baseDoc = ensureDocSections(parsed.body, loaded.config.tasks.doc.required_sections);
|
|
189
|
+
const nextBody = ensureDocSections(setMarkdownSection(baseDoc, opts.section, opts.text), loaded.config.tasks.doc.required_sections);
|
|
190
|
+
return { frontmatter: nextFrontmatter, body: nextBody };
|
|
191
|
+
});
|
|
170
192
|
return { readmePath };
|
|
171
193
|
}
|
|
172
194
|
export async function readTask(opts) {
|
package/package.json
CHANGED
|
@@ -111,6 +111,7 @@
|
|
|
111
111
|
"Summary",
|
|
112
112
|
"Context",
|
|
113
113
|
"Scope",
|
|
114
|
+
"Plan",
|
|
114
115
|
"Risks",
|
|
115
116
|
"Verify Steps",
|
|
116
117
|
"Verification",
|
|
@@ -120,8 +121,8 @@
|
|
|
120
121
|
"required_sections": [
|
|
121
122
|
"Summary",
|
|
122
123
|
"Scope",
|
|
124
|
+
"Plan",
|
|
123
125
|
"Risks",
|
|
124
|
-
"Verify Steps",
|
|
125
126
|
"Verification",
|
|
126
127
|
"Rollback Plan"
|
|
127
128
|
]
|
|
@@ -162,6 +163,7 @@
|
|
|
162
163
|
"Summary",
|
|
163
164
|
"Context",
|
|
164
165
|
"Scope",
|
|
166
|
+
"Plan",
|
|
165
167
|
"Risks",
|
|
166
168
|
"Verify Steps",
|
|
167
169
|
"Verification",
|
|
@@ -171,8 +173,8 @@
|
|
|
171
173
|
"required_sections": [
|
|
172
174
|
"Summary",
|
|
173
175
|
"Scope",
|
|
176
|
+
"Plan",
|
|
174
177
|
"Risks",
|
|
175
|
-
"Verify Steps",
|
|
176
178
|
"Verification",
|
|
177
179
|
"Rollback Plan"
|
|
178
180
|
]
|
|
@@ -185,6 +187,7 @@
|
|
|
185
187
|
"Summary",
|
|
186
188
|
"Context",
|
|
187
189
|
"Scope",
|
|
190
|
+
"Plan",
|
|
188
191
|
"Risks",
|
|
189
192
|
"Verify Steps",
|
|
190
193
|
"Verification",
|
|
@@ -195,14 +198,7 @@
|
|
|
195
198
|
"required_sections": {
|
|
196
199
|
"type": "array",
|
|
197
200
|
"items": { "type": "string", "minLength": 1 },
|
|
198
|
-
"default": [
|
|
199
|
-
"Summary",
|
|
200
|
-
"Scope",
|
|
201
|
-
"Risks",
|
|
202
|
-
"Verify Steps",
|
|
203
|
-
"Verification",
|
|
204
|
-
"Rollback Plan"
|
|
205
|
-
]
|
|
201
|
+
"default": ["Summary", "Scope", "Plan", "Risks", "Verification", "Rollback Plan"]
|
|
206
202
|
}
|
|
207
203
|
}
|
|
208
204
|
},
|