@agentplaneorg/core 0.1.8 → 0.1.9

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.
@@ -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;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"}
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
- if (!subject.includes(opts.taskId) && (suffix.length === 0 || !subject.includes(suffix))) {
25
- errors.push("commit subject must include task id or suffix");
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 (isGenericSubject(subject, opts.genericTokens)) {
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
  }
@@ -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;AAiDxD,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;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,CAgBzB"}
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;AAgDxD,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;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,CAqBzB"}
@@ -4,6 +4,7 @@ import { resolveProject } from "../project/project-root.js";
4
4
  const execFileAsync = promisify(execFile);
5
5
  const DEFAULT_BASE_BRANCH = "main";
6
6
  const GIT_CONFIG_BASE_BRANCH_KEY = "agentplane.baseBranch";
7
+ const LEGACY_DEFAULT_BASE_BRANCH = "master";
7
8
  async function gitConfigGet(cwd, key) {
8
9
  try {
9
10
  const { stdout } = await execFileAsync("git", ["config", "--local", "--get", key], { cwd });
@@ -32,22 +33,19 @@ async function gitConfigUnset(cwd, key) {
32
33
  throw err;
33
34
  }
34
35
  }
35
- async function gitCurrentBranch(cwd) {
36
+ async function gitLocalBranchExists(cwd, branch) {
36
37
  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
38
+ await execFileAsync("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], {
39
+ cwd,
40
+ });
41
+ return true;
44
42
  }
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");
43
+ catch (err) {
44
+ const code = err?.code;
45
+ if (code === 1)
46
+ return false;
47
+ throw err;
49
48
  }
50
- return trimmed;
51
49
  }
52
50
  export async function getPinnedBaseBranch(opts) {
53
51
  const resolved = await resolveProject({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null });
@@ -84,7 +82,12 @@ export async function resolveBaseBranch(opts) {
84
82
  cwd: opts.cwd,
85
83
  rootOverride: opts.rootOverride ?? null,
86
84
  });
87
- return await gitCurrentBranch(resolved.gitRoot);
85
+ if (await gitLocalBranchExists(resolved.gitRoot, DEFAULT_BASE_BRANCH))
86
+ return DEFAULT_BASE_BRANCH;
87
+ if (await gitLocalBranchExists(resolved.gitRoot, LEGACY_DEFAULT_BASE_BRANCH))
88
+ return LEGACY_DEFAULT_BASE_BRANCH;
89
+ // No safe default: require pinning to avoid silently treating feature branches as base.
90
+ return null;
88
91
  }
89
92
  return null;
90
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/git/git-utils.ts"],"names":[],"mappings":"AAeA,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,CAcpB"}
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"}
@@ -2,30 +2,27 @@ 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 gitLines(cwd, args) {
6
- const { stdout } = await execFileAsync("git", args, { cwd });
7
- return stdout
8
- .split("\n")
9
- .map((line) => line.trim())
10
- .filter((line) => line.length > 0);
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 gitLines(resolved.gitRoot, ["diff", "--name-only", "--cached"]);
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 lines = await gitLines(resolved.gitRoot, ["status", "--porcelain"]);
19
- const files = [];
20
- for (const line of lines) {
21
- const status = line.slice(0, 2);
22
- const filePart = line.slice(3).trim();
23
- if (!filePart)
24
- continue;
25
- const name = filePart.includes("->") ? filePart.split("->").at(-1)?.trim() : filePart;
26
- if ((status === "??" || status[1] !== " ") && name) {
27
- files.push(name);
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));
31
28
  }
@@ -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;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"}
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,CAoClF;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.map((v) => {
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" ? ["author", "body"] : null;
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} - {}`];
@@ -137,6 +150,7 @@ export function renderTaskFrontmatter(frontmatter) {
137
150
  "verification",
138
151
  "commit",
139
152
  "comments",
153
+ "events",
140
154
  "doc_version",
141
155
  "doc_updated_at",
142
156
  "doc_updated_by",
@@ -147,7 +161,10 @@ export function renderTaskFrontmatter(frontmatter) {
147
161
  const ordered = orderedKeys(frontmatter, preferredKeyOrder);
148
162
  const lines = [];
149
163
  for (const k of ordered) {
150
- lines.push(...renderValueLines(k, frontmatter[k], ""));
164
+ const value = frontmatter[k];
165
+ if (value === undefined)
166
+ continue;
167
+ lines.push(...renderValueLines(k, value, ""));
151
168
  }
152
169
  return `---\n${lines.join("\n")}\n---\n`;
153
170
  }
@@ -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":"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"}
1
+ {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/tasks/task-store.ts"],"names":[],"mappings":"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"}
@@ -158,6 +158,7 @@ export async function createTask(opts) {
158
158
  note: null,
159
159
  },
160
160
  comments: [],
161
+ events: [],
161
162
  doc_version: 2,
162
163
  doc_updated_at: nowIso(),
163
164
  doc_updated_by: opts.owner,
@@ -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,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
+ {"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
- return {
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentplaneorg/core",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Core utilities and models for the Agent Plane CLI.",
5
5
  "keywords": [
6
6
  "agentplane",