@agentplaneorg/core 0.1.8 → 0.2.0
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 -1
- package/dist/commit/commit-policy.js +40 -3
- package/dist/config/config.d.ts +4 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/git/base-branch.d.ts.map +1 -1
- package/dist/git/base-branch.js +3 -26
- package/dist/git/git-utils.d.ts +4 -0
- package/dist/git/git-utils.d.ts.map +1 -1
- package/dist/git/git-utils.js +23 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tasks/task-readme.d.ts.map +1 -1
- package/dist/tasks/task-readme.js +23 -3
- package/dist/tasks/task-store.d.ts +11 -0
- package/dist/tasks/task-store.d.ts.map +1 -1
- package/dist/tasks/task-store.js +1 -0
- package/dist/tasks/tasks-export.d.ts +10 -0
- package/dist/tasks/tasks-export.d.ts.map +1 -1
- package/dist/tasks/tasks-export.js +22 -1
- package/dist/tasks/tasks-lint.d.ts +1 -1
- package/dist/tasks/tasks-lint.d.ts.map +1 -1
- package/dist/tasks/tasks-lint.js +1 -9
- package/package.json +1 -1
- package/schemas/config.schema.json +15 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-policy.d.ts","sourceRoot":"","sources":["../../src/commit/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;
|
|
1
|
+
{"version":3,"file":"commit-policy.d.ts","sourceRoot":"","sources":["../../src/commit/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;AA4BD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,kBAAkB,CAgCrB"}
|
|
@@ -15,17 +15,54 @@ export function isGenericSubject(subject, genericTokens) {
|
|
|
15
15
|
const tokenSet = new Set(genericTokens.map((t) => t.toLowerCase()));
|
|
16
16
|
return words.length <= 3 && words.every((w) => tokenSet.has(w));
|
|
17
17
|
}
|
|
18
|
+
function parseSubjectTemplate(subject) {
|
|
19
|
+
const trimmed = subject.trim();
|
|
20
|
+
if (!trimmed)
|
|
21
|
+
return null;
|
|
22
|
+
const match = /^(\S+)\s+(\S+)\s+(.+)$/.exec(trimmed);
|
|
23
|
+
if (!match)
|
|
24
|
+
return null;
|
|
25
|
+
const emoji = match[1] ?? "";
|
|
26
|
+
const suffix = match[2] ?? "";
|
|
27
|
+
const rest = (match[3] ?? "").trim();
|
|
28
|
+
if (!emoji || !suffix || !rest)
|
|
29
|
+
return null;
|
|
30
|
+
const scopeMatch = /^([a-z][a-z0-9_-]*):\s+(.+)$/.exec(rest);
|
|
31
|
+
if (!scopeMatch)
|
|
32
|
+
return null;
|
|
33
|
+
const scope = scopeMatch[1] ?? "";
|
|
34
|
+
const summary = (scopeMatch[2] ?? "").trim();
|
|
35
|
+
if (!scope || !summary)
|
|
36
|
+
return null;
|
|
37
|
+
return { emoji, suffix, scope, summary };
|
|
38
|
+
}
|
|
18
39
|
export function validateCommitSubject(opts) {
|
|
19
40
|
const errors = [];
|
|
20
41
|
const subject = opts.subject.trim();
|
|
21
42
|
if (!subject)
|
|
22
43
|
errors.push("commit subject must be non-empty");
|
|
23
44
|
const suffix = extractTaskSuffix(opts.taskId);
|
|
24
|
-
|
|
25
|
-
|
|
45
|
+
const template = parseSubjectTemplate(subject);
|
|
46
|
+
if (!template) {
|
|
47
|
+
errors.push("commit subject must match: <emoji> <suffix> <scope>: <summary>");
|
|
48
|
+
return { ok: false, errors };
|
|
49
|
+
}
|
|
50
|
+
if (!suffix) {
|
|
51
|
+
errors.push("task id has no suffix");
|
|
26
52
|
}
|
|
27
|
-
if (
|
|
53
|
+
else if (template.suffix.toLowerCase() !== suffix.toLowerCase()) {
|
|
54
|
+
errors.push("commit subject must include task suffix as the second token");
|
|
55
|
+
}
|
|
56
|
+
const normalizedSummary = stripPunctuation(template.summary).toLowerCase().trim();
|
|
57
|
+
if (!normalizedSummary) {
|
|
28
58
|
errors.push("commit subject is too generic");
|
|
59
|
+
return { ok: errors.length === 0, errors };
|
|
29
60
|
}
|
|
61
|
+
const words = normalizedSummary.split(/\s+/).filter(Boolean);
|
|
62
|
+
const tokenSet = new Set(opts.genericTokens.map((t) => t.toLowerCase()));
|
|
63
|
+
const nonGenericCount = words.filter((w) => !tokenSet.has(w)).length;
|
|
64
|
+
// Require at least two words in the summary and at least one non-generic token.
|
|
65
|
+
if (words.length < 2 || nonGenericCount < 1)
|
|
66
|
+
errors.push("commit subject is too generic");
|
|
30
67
|
return { ok: errors.length === 0, errors };
|
|
31
68
|
}
|
package/dist/config/config.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export type AgentplaneConfig = {
|
|
|
32
32
|
id_suffix_length_default: number;
|
|
33
33
|
verify: {
|
|
34
34
|
required_tags: string[];
|
|
35
|
+
require_steps_for_tags?: string[];
|
|
36
|
+
spike_tag: string;
|
|
37
|
+
enforce_on_plan_approve: boolean;
|
|
38
|
+
enforce_on_start_when_no_plan: boolean;
|
|
35
39
|
};
|
|
36
40
|
doc: {
|
|
37
41
|
sections: string[];
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-branch.d.ts","sourceRoot":"","sources":["../../src/git/base-branch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"base-branch.d.ts","sourceRoot":"","sources":["../../src/git/base-branch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAiCxD,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,CAIlB;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;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASzB"}
|
package/dist/git/base-branch.js
CHANGED
|
@@ -2,7 +2,6 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
import { resolveProject } from "../project/project-root.js";
|
|
4
4
|
const execFileAsync = promisify(execFile);
|
|
5
|
-
const DEFAULT_BASE_BRANCH = "main";
|
|
6
5
|
const GIT_CONFIG_BASE_BRANCH_KEY = "agentplane.baseBranch";
|
|
7
6
|
async function gitConfigGet(cwd, key) {
|
|
8
7
|
try {
|
|
@@ -32,30 +31,15 @@ async function gitConfigUnset(cwd, key) {
|
|
|
32
31
|
throw err;
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
|
-
async function gitCurrentBranch(cwd) {
|
|
36
|
-
try {
|
|
37
|
-
const { stdout } = await execFileAsync("git", ["symbolic-ref", "--short", "HEAD"], { cwd });
|
|
38
|
-
const trimmed = stdout.trim();
|
|
39
|
-
if (trimmed)
|
|
40
|
-
return trimmed;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
// fall through
|
|
44
|
-
}
|
|
45
|
-
const { stdout } = await execFileAsync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd });
|
|
46
|
-
const trimmed = stdout.trim();
|
|
47
|
-
if (!trimmed || trimmed === "HEAD") {
|
|
48
|
-
throw new Error("Failed to resolve current branch");
|
|
49
|
-
}
|
|
50
|
-
return trimmed;
|
|
51
|
-
}
|
|
52
34
|
export async function getPinnedBaseBranch(opts) {
|
|
53
35
|
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
54
36
|
return await gitConfigGet(resolved.gitRoot, GIT_CONFIG_BASE_BRANCH_KEY);
|
|
55
37
|
}
|
|
56
38
|
export async function getBaseBranch(opts) {
|
|
57
39
|
const pinned = await getPinnedBaseBranch(opts);
|
|
58
|
-
|
|
40
|
+
if (pinned)
|
|
41
|
+
return pinned;
|
|
42
|
+
throw new Error("base branch is not pinned");
|
|
59
43
|
}
|
|
60
44
|
export async function setPinnedBaseBranch(opts) {
|
|
61
45
|
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
@@ -79,12 +63,5 @@ export async function resolveBaseBranch(opts) {
|
|
|
79
63
|
});
|
|
80
64
|
if (pinned)
|
|
81
65
|
return pinned;
|
|
82
|
-
if (opts.mode === "branch_pr") {
|
|
83
|
-
const resolved = await resolveProject({
|
|
84
|
-
cwd: opts.cwd,
|
|
85
|
-
rootOverride: opts.rootOverride ?? null,
|
|
86
|
-
});
|
|
87
|
-
return await gitCurrentBranch(resolved.gitRoot);
|
|
88
|
-
}
|
|
89
66
|
return null;
|
|
90
67
|
}
|
package/dist/git/git-utils.d.ts
CHANGED
|
@@ -6,4 +6,8 @@ export declare function getUnstagedFiles(opts: {
|
|
|
6
6
|
cwd: string;
|
|
7
7
|
rootOverride?: string | null;
|
|
8
8
|
}): Promise<string[]>;
|
|
9
|
+
export declare function getUnstagedTrackedFiles(opts: {
|
|
10
|
+
cwd: string;
|
|
11
|
+
rootOverride?: string | null;
|
|
12
|
+
}): Promise<string[]>;
|
|
9
13
|
//# sourceMappingURL=git-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/git/git-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/git/git-utils.ts"],"names":[],"mappings":"AAoBA,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOpB;AAID,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpB"}
|
package/dist/git/git-utils.js
CHANGED
|
@@ -2,30 +2,33 @@ import { execFile } from "node:child_process";
|
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
import { resolveProject } from "../project/project-root.js";
|
|
4
4
|
const execFileAsync = promisify(execFile);
|
|
5
|
-
async function
|
|
6
|
-
const { stdout } = await execFileAsync("git", args, {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
async function gitNullSeparatedPaths(cwd, args) {
|
|
6
|
+
const { stdout } = await execFileAsync("git", args, {
|
|
7
|
+
cwd,
|
|
8
|
+
encoding: "buffer",
|
|
9
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
10
|
+
});
|
|
11
|
+
const text = Buffer.isBuffer(stdout) ? stdout.toString("utf8") : String(stdout);
|
|
12
|
+
return text
|
|
13
|
+
.split("\0")
|
|
14
|
+
.map((entry) => entry.trim())
|
|
15
|
+
.filter((entry) => entry.length > 0);
|
|
11
16
|
}
|
|
12
17
|
export async function getStagedFiles(opts) {
|
|
13
18
|
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
14
|
-
return await
|
|
19
|
+
return await gitNullSeparatedPaths(resolved.gitRoot, ["diff", "--name-only", "--cached", "-z"]);
|
|
15
20
|
}
|
|
16
21
|
export async function getUnstagedFiles(opts) {
|
|
17
22
|
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return files;
|
|
23
|
+
const [unstaged, untracked] = await Promise.all([
|
|
24
|
+
gitNullSeparatedPaths(resolved.gitRoot, ["diff", "--name-only", "-z"]),
|
|
25
|
+
gitNullSeparatedPaths(resolved.gitRoot, ["ls-files", "--others", "--exclude-standard", "-z"]),
|
|
26
|
+
]);
|
|
27
|
+
return [...new Set([...unstaged, ...untracked])].toSorted((a, b) => a.localeCompare(b));
|
|
28
|
+
}
|
|
29
|
+
// Tracked-only dirty check (ignores untracked files). This matches the repo policy
|
|
30
|
+
// definition of "clean" used by guardrails: `git status --short --untracked-files=no`.
|
|
31
|
+
export async function getUnstagedTrackedFiles(opts) {
|
|
32
|
+
const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
|
|
33
|
+
return await gitNullSeparatedPaths(resolved.gitRoot, ["diff", "--name-only", "-z"]);
|
|
31
34
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { buildTasksExportSnapshot, canonicalTasksPayload, canonicalizeJson, comp
|
|
|
11
11
|
export { lintTasksFile, lintTasksSnapshot, readTasksExport, type TasksLintResult, } from "./tasks/tasks-lint.js";
|
|
12
12
|
export { clearPinnedBaseBranch, getBaseBranch, getPinnedBaseBranch, resolveBaseBranch, setPinnedBaseBranch, } from "./git/base-branch.js";
|
|
13
13
|
export { extractTaskSuffix, isGenericSubject, validateCommitSubject, type CommitPolicyResult, } from "./commit/commit-policy.js";
|
|
14
|
-
export { getStagedFiles, getUnstagedFiles } from "./git/git-utils.js";
|
|
14
|
+
export { getStagedFiles, getUnstagedFiles, getUnstagedTrackedFiles } from "./git/git-utils.js";
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
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,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"}
|
|
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,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,4 +11,4 @@ export { buildTasksExportSnapshot, canonicalTasksPayload, canonicalizeJson, comp
|
|
|
11
11
|
export { lintTasksFile, lintTasksSnapshot, readTasksExport, } from "./tasks/tasks-lint.js";
|
|
12
12
|
export { clearPinnedBaseBranch, getBaseBranch, getPinnedBaseBranch, resolveBaseBranch, setPinnedBaseBranch, } from "./git/base-branch.js";
|
|
13
13
|
export { extractTaskSuffix, isGenericSubject, validateCommitSubject, } from "./commit/commit-policy.js";
|
|
14
|
-
export { getStagedFiles, getUnstagedFiles } from "./git/git-utils.js";
|
|
14
|
+
export { getStagedFiles, getUnstagedFiles, getUnstagedTrackedFiles } from "./git/git-utils.js";
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AA6FD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAuClF;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|
|
@@ -46,6 +46,8 @@ export function parseTaskReadme(markdown) {
|
|
|
46
46
|
return { frontmatter: parsed, body };
|
|
47
47
|
}
|
|
48
48
|
function renderScalar(value) {
|
|
49
|
+
if (value === undefined)
|
|
50
|
+
return "null";
|
|
49
51
|
if (value === null)
|
|
50
52
|
return "null";
|
|
51
53
|
if (typeof value === "string")
|
|
@@ -57,11 +59,14 @@ function renderScalar(value) {
|
|
|
57
59
|
throw new TypeError(`Unsupported scalar type: ${typeof value}`);
|
|
58
60
|
}
|
|
59
61
|
function renderFlowSeq(value) {
|
|
60
|
-
const parts = value
|
|
62
|
+
const parts = value
|
|
63
|
+
.filter((v) => v !== undefined)
|
|
64
|
+
.map((v) => {
|
|
61
65
|
if (Array.isArray(v))
|
|
62
66
|
return renderFlowSeq(v);
|
|
63
67
|
if (isRecord(v))
|
|
64
68
|
return `{ ${orderedKeys(v, null)
|
|
69
|
+
.filter((k) => v[k] !== undefined)
|
|
65
70
|
.map((k) => `${k}: ${renderScalar(v[k])}`)
|
|
66
71
|
.join(", ")} }`;
|
|
67
72
|
return renderScalar(v);
|
|
@@ -73,6 +78,8 @@ function renderMapLines(value, indent, preferredKeyOrder) {
|
|
|
73
78
|
const lines = [];
|
|
74
79
|
for (const k of keys) {
|
|
75
80
|
const v = value[k];
|
|
81
|
+
if (v === undefined)
|
|
82
|
+
continue;
|
|
76
83
|
lines.push(...renderValueLines(k, v, indent));
|
|
77
84
|
}
|
|
78
85
|
return lines;
|
|
@@ -81,6 +88,8 @@ function isStringArray(value) {
|
|
|
81
88
|
return value.every((v) => typeof v === "string");
|
|
82
89
|
}
|
|
83
90
|
function renderValueLines(key, value, indent) {
|
|
91
|
+
if (value === undefined)
|
|
92
|
+
return [];
|
|
84
93
|
if (Array.isArray(value)) {
|
|
85
94
|
if (value.length === 0)
|
|
86
95
|
return [`${indent}${key}: []`];
|
|
@@ -95,7 +104,11 @@ function renderValueLines(key, value, indent) {
|
|
|
95
104
|
...value.flatMap((item) => {
|
|
96
105
|
if (!isRecord(item))
|
|
97
106
|
throw new TypeError("Expected an object item in YAML sequence");
|
|
98
|
-
const preferred = key === "comments"
|
|
107
|
+
const preferred = key === "comments"
|
|
108
|
+
? ["author", "body"]
|
|
109
|
+
: key === "events"
|
|
110
|
+
? ["type", "at", "author", "from", "to", "state", "note", "body"]
|
|
111
|
+
: null;
|
|
99
112
|
const itemLines = renderMapLines(item, `${indent} `, preferred);
|
|
100
113
|
if (itemLines.length === 0)
|
|
101
114
|
return [`${indent} - {}`];
|
|
@@ -124,6 +137,9 @@ export function renderTaskFrontmatter(frontmatter) {
|
|
|
124
137
|
const preferredKeyOrder = [
|
|
125
138
|
"id",
|
|
126
139
|
"title",
|
|
140
|
+
"result_summary",
|
|
141
|
+
"risk_level",
|
|
142
|
+
"breaking",
|
|
127
143
|
"status",
|
|
128
144
|
"priority",
|
|
129
145
|
"owner",
|
|
@@ -137,6 +153,7 @@ export function renderTaskFrontmatter(frontmatter) {
|
|
|
137
153
|
"verification",
|
|
138
154
|
"commit",
|
|
139
155
|
"comments",
|
|
156
|
+
"events",
|
|
140
157
|
"doc_version",
|
|
141
158
|
"doc_updated_at",
|
|
142
159
|
"doc_updated_by",
|
|
@@ -147,7 +164,10 @@ export function renderTaskFrontmatter(frontmatter) {
|
|
|
147
164
|
const ordered = orderedKeys(frontmatter, preferredKeyOrder);
|
|
148
165
|
const lines = [];
|
|
149
166
|
for (const k of ordered) {
|
|
150
|
-
|
|
167
|
+
const value = frontmatter[k];
|
|
168
|
+
if (value === undefined)
|
|
169
|
+
continue;
|
|
170
|
+
lines.push(...renderValueLines(k, value, ""));
|
|
151
171
|
}
|
|
152
172
|
return `---\n${lines.join("\n")}\n---\n`;
|
|
153
173
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { generateTaskId } from "./task-id.js";
|
|
2
2
|
export type TaskStatus = "TODO" | "DOING" | "DONE" | "BLOCKED";
|
|
3
3
|
export type TaskPriority = "low" | "normal" | "med" | "high";
|
|
4
|
+
export type TaskEvent = {
|
|
5
|
+
type: "status" | "comment" | "verify";
|
|
6
|
+
at: string;
|
|
7
|
+
author: string;
|
|
8
|
+
from?: string;
|
|
9
|
+
to?: string;
|
|
10
|
+
state?: string;
|
|
11
|
+
note?: string;
|
|
12
|
+
body?: string;
|
|
13
|
+
};
|
|
4
14
|
export type TaskFrontmatter = {
|
|
5
15
|
id: string;
|
|
6
16
|
title: string;
|
|
@@ -26,6 +36,7 @@ export type TaskFrontmatter = {
|
|
|
26
36
|
author: string;
|
|
27
37
|
body: string;
|
|
28
38
|
}[];
|
|
39
|
+
events?: TaskEvent[];
|
|
29
40
|
doc_version: 2;
|
|
30
41
|
doc_updated_at: string;
|
|
31
42
|
doc_updated_by: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/tasks/task-store.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAC/D,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7D,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE;QACd,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;QAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,cAAc,CAAC;QACzC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;KACrB,CAAC;IACF,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,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,eAAe,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAUF,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAgBtF;AAWD,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CASD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvE;AA4ED,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,cAAc,CAAC;CACrC,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
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
|
@@ -22,6 +22,16 @@ export type TasksExportTask = {
|
|
|
22
22
|
author: string;
|
|
23
23
|
body: string;
|
|
24
24
|
}[];
|
|
25
|
+
events?: {
|
|
26
|
+
type: string;
|
|
27
|
+
at: string;
|
|
28
|
+
author: string;
|
|
29
|
+
from?: string;
|
|
30
|
+
to?: string;
|
|
31
|
+
state?: string;
|
|
32
|
+
note?: string;
|
|
33
|
+
body?: string;
|
|
34
|
+
}[];
|
|
25
35
|
doc_version: 2;
|
|
26
36
|
doc_updated_at: string;
|
|
27
37
|
doc_updated_by: string;
|
|
@@ -1 +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,
|
|
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,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IACJ,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,CAyG/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"}
|
|
@@ -55,7 +55,24 @@ export async function buildTasksExportSnapshot(opts) {
|
|
|
55
55
|
.filter((c) => typeof c.author === "string" && typeof c.body === "string")
|
|
56
56
|
.map((c) => ({ author: c.author, body: c.body }))
|
|
57
57
|
: [];
|
|
58
|
-
|
|
58
|
+
const events = Array.isArray(fm.events)
|
|
59
|
+
? fm.events
|
|
60
|
+
.filter((event) => isRecord(event))
|
|
61
|
+
.filter((event) => typeof event.type === "string" &&
|
|
62
|
+
typeof event.at === "string" &&
|
|
63
|
+
typeof event.author === "string")
|
|
64
|
+
.map((event) => ({
|
|
65
|
+
type: event.type,
|
|
66
|
+
at: event.at,
|
|
67
|
+
author: event.author,
|
|
68
|
+
from: typeof event.from === "string" ? event.from : undefined,
|
|
69
|
+
to: typeof event.to === "string" ? event.to : undefined,
|
|
70
|
+
state: typeof event.state === "string" ? event.state : undefined,
|
|
71
|
+
note: typeof event.note === "string" ? event.note : undefined,
|
|
72
|
+
body: typeof event.body === "string" ? event.body : undefined,
|
|
73
|
+
}))
|
|
74
|
+
: [];
|
|
75
|
+
const base = {
|
|
59
76
|
id: typeof fm.id === "string" ? fm.id : t.id,
|
|
60
77
|
title: typeof fm.title === "string" ? fm.title : "",
|
|
61
78
|
status: typeof fm.status === "string" ? fm.status : "",
|
|
@@ -73,6 +90,10 @@ export async function buildTasksExportSnapshot(opts) {
|
|
|
73
90
|
dirty: false,
|
|
74
91
|
id_source: "generated",
|
|
75
92
|
};
|
|
93
|
+
if (events.length > 0) {
|
|
94
|
+
return { ...base, events };
|
|
95
|
+
}
|
|
96
|
+
return base;
|
|
76
97
|
});
|
|
77
98
|
const sorted = exportTasks.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
78
99
|
const checksum = computeTasksChecksum(sorted);
|
|
@@ -3,7 +3,7 @@ import { type TasksExportSnapshot } from "./tasks-export.js";
|
|
|
3
3
|
export type TasksLintResult = {
|
|
4
4
|
errors: string[];
|
|
5
5
|
};
|
|
6
|
-
export declare function lintTasksSnapshot(snapshot: TasksExportSnapshot,
|
|
6
|
+
export declare function lintTasksSnapshot(snapshot: TasksExportSnapshot, _config: AgentplaneConfig): TasksLintResult;
|
|
7
7
|
export declare function readTasksExport(opts: {
|
|
8
8
|
cwd: string;
|
|
9
9
|
rootOverride?: string | null;
|
|
@@ -1 +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,
|
|
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,OAAO,EAAE,gBAAgB,GACxB,eAAe,CAmGjB;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"}
|
package/dist/tasks/tasks-lint.js
CHANGED
|
@@ -48,7 +48,7 @@ function hasCycle(dependsOn) {
|
|
|
48
48
|
}
|
|
49
49
|
return null;
|
|
50
50
|
}
|
|
51
|
-
export function lintTasksSnapshot(snapshot,
|
|
51
|
+
export function lintTasksSnapshot(snapshot, _config) {
|
|
52
52
|
const errors = [];
|
|
53
53
|
if (!isRecord(snapshot) || !Array.isArray(snapshot.tasks) || !isRecord(snapshot.meta)) {
|
|
54
54
|
return { errors: ["tasks.json must have { tasks: [], meta: {} }"] };
|
|
@@ -127,14 +127,6 @@ export function lintTasksSnapshot(snapshot, config) {
|
|
|
127
127
|
typeof t.commit.message !== "string")) {
|
|
128
128
|
errors.push(`${id}: DONE tasks must have commit {hash,message}`);
|
|
129
129
|
}
|
|
130
|
-
const requiredTags = new Set(config.tasks.verify.required_tags);
|
|
131
|
-
const tagList = Array.isArray(t.tags) ? t.tags : [];
|
|
132
|
-
const needsVerify = tagList.some((tag) => requiredTags.has(tag));
|
|
133
|
-
if (needsVerify) {
|
|
134
|
-
const verifyList = Array.isArray(t.verify) ? t.verify : [];
|
|
135
|
-
if (verifyList.length === 0)
|
|
136
|
-
errors.push(`${id}: verify is required for tags: ${[...requiredTags].join(", ")}`);
|
|
137
|
-
}
|
|
138
130
|
}
|
|
139
131
|
// Depends-on must reference known tasks (only after tasks parsed).
|
|
140
132
|
for (const [id, t] of byId.entries()) {
|
package/package.json
CHANGED
|
@@ -144,14 +144,27 @@
|
|
|
144
144
|
"type": "object",
|
|
145
145
|
"additionalProperties": true,
|
|
146
146
|
"required": ["required_tags"],
|
|
147
|
-
"default": {
|
|
147
|
+
"default": {
|
|
148
|
+
"required_tags": ["code", "backend", "frontend"],
|
|
149
|
+
"spike_tag": "spike",
|
|
150
|
+
"enforce_on_plan_approve": true,
|
|
151
|
+
"enforce_on_start_when_no_plan": true
|
|
152
|
+
},
|
|
148
153
|
"properties": {
|
|
149
154
|
"required_tags": {
|
|
150
155
|
"type": "array",
|
|
151
156
|
"items": { "type": "string", "minLength": 1 },
|
|
152
157
|
"uniqueItems": true,
|
|
153
158
|
"default": ["code", "backend", "frontend"]
|
|
154
|
-
}
|
|
159
|
+
},
|
|
160
|
+
"require_steps_for_tags": {
|
|
161
|
+
"type": "array",
|
|
162
|
+
"items": { "type": "string", "minLength": 1 },
|
|
163
|
+
"uniqueItems": true
|
|
164
|
+
},
|
|
165
|
+
"spike_tag": { "type": "string", "minLength": 1, "default": "spike" },
|
|
166
|
+
"enforce_on_plan_approve": { "type": "boolean", "default": true },
|
|
167
|
+
"enforce_on_start_when_no_plan": { "type": "boolean", "default": true }
|
|
155
168
|
}
|
|
156
169
|
},
|
|
157
170
|
"doc": {
|