@dendelion/paper-camp 0.2.1 → 0.4.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/README.md +16 -7
- package/dist/app/assets/main-6nYButky.js +232 -0
- package/dist/app/assets/main-6nYButky.js.map +1 -0
- package/dist/app/assets/main-DUnpdvQF.css +1 -0
- package/dist/app/index.html +2 -2
- package/dist/chunks/serializer.B8u-L8BI.js +5249 -0
- package/dist/chunks/serializer.B8u-L8BI.js.map +1 -0
- package/dist/cli/index.js +2150 -932
- package/dist/cli/index.js.map +1 -1
- package/dist/core/frontmatter-schemas.d.ts +11 -0
- package/dist/core/frontmatter-schemas.d.ts.map +1 -0
- package/dist/core/frontmatter.test.d.ts +2 -0
- package/dist/core/frontmatter.test.d.ts.map +1 -0
- package/dist/core/idea-status.d.ts +7 -0
- package/dist/core/idea-status.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +48 -29
- package/dist/core/parser.d.ts +24 -3
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/readers.d.ts +27 -0
- package/dist/core/readers.d.ts.map +1 -0
- package/dist/core/readers.test.d.ts +2 -0
- package/dist/core/readers.test.d.ts.map +1 -0
- package/dist/core/scaffold.d.ts +4 -2
- package/dist/core/scaffold.d.ts.map +1 -1
- package/dist/core/schemas.d.ts +75 -12
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/core/serializer.d.ts +52 -2
- package/dist/core/serializer.d.ts.map +1 -1
- package/dist/types/index.d.ts +24 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +32 -10
- package/dist/types/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/app/assets/main-B61tEYvn.css +0 -1
- package/dist/app/assets/main-tAEncq68.js +0 -272
- package/dist/app/assets/main-tAEncq68.js.map +0 -1
- package/dist/chunks/serializer.D1Ts_p8h.js +0 -462
- package/dist/chunks/serializer.D1Ts_p8h.js.map +0 -1
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
import { mkdir as E, writeFile as m, access as O, readFile as j } from "node:fs/promises";
|
|
2
|
-
import { join as h, dirname as T } from "node:path";
|
|
3
|
-
import { z as a } from "zod";
|
|
4
|
-
import { AGENT_IDS as p } from "../types/index.js";
|
|
5
|
-
const G = /^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/;
|
|
6
|
-
function z(t) {
|
|
7
|
-
return t.length >= 2 && (t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'")) ? t.slice(1, -1) : t;
|
|
8
|
-
}
|
|
9
|
-
function S(t) {
|
|
10
|
-
return t === "" || /[\s#"]/.test(t) ? `"${t.replace(/"/g, '\\"')}"` : t;
|
|
11
|
-
}
|
|
12
|
-
function v(t) {
|
|
13
|
-
const e = t.trim();
|
|
14
|
-
if (!e || e.startsWith("#")) return null;
|
|
15
|
-
const n = e.match(G);
|
|
16
|
-
return n ? { key: n[1], value: z(n[2]) } : null;
|
|
17
|
-
}
|
|
18
|
-
function ht(t) {
|
|
19
|
-
const e = [];
|
|
20
|
-
for (const n of t.split(`
|
|
21
|
-
`)) {
|
|
22
|
-
const o = v(n);
|
|
23
|
-
o && e.push(o);
|
|
24
|
-
}
|
|
25
|
-
return e;
|
|
26
|
-
}
|
|
27
|
-
function pt(t, e) {
|
|
28
|
-
const n = new Map(e.map((i) => [i.key, i.value])), o = t.length > 0 ? t.split(`
|
|
29
|
-
`) : [], s = [];
|
|
30
|
-
for (const i of o) {
|
|
31
|
-
const r = v(i);
|
|
32
|
-
if (!r) {
|
|
33
|
-
s.push(i);
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
n.has(r.key) && (s.push(`${r.key}=${S(n.get(r.key) ?? "")}`), n.delete(r.key));
|
|
37
|
-
}
|
|
38
|
-
for (const [i, r] of n)
|
|
39
|
-
s.push(`${i}=${S(r)}`);
|
|
40
|
-
for (; s.length > 0 && s[s.length - 1] === ""; ) s.pop();
|
|
41
|
-
return s.length > 0 ? `${s.join(`
|
|
42
|
-
`)}
|
|
43
|
-
` : "";
|
|
44
|
-
}
|
|
45
|
-
const y = a.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date"), H = a.object({
|
|
46
|
-
status: a.enum(["idea", "planned", "in-progress", "review", "done", "dropped"]),
|
|
47
|
-
kind: a.enum(["feat", "fix", "chore", "docs", "refactor"]).optional(),
|
|
48
|
-
id: a.string().optional(),
|
|
49
|
-
idea: a.string().optional(),
|
|
50
|
-
agent: a.enum(p).optional(),
|
|
51
|
-
created: y,
|
|
52
|
-
updated: y.optional(),
|
|
53
|
-
tags: a.string().optional()
|
|
54
|
-
}), F = a.object({
|
|
55
|
-
date: y,
|
|
56
|
-
status: a.enum(["decided", "superseded"]),
|
|
57
|
-
"superseded-by": a.string().optional()
|
|
58
|
-
}), q = a.object({
|
|
59
|
-
status: a.enum(["open", "resolved"]),
|
|
60
|
-
raised: y,
|
|
61
|
-
"resolved-by": a.string().optional(),
|
|
62
|
-
blocks: a.string().optional()
|
|
63
|
-
}), U = a.object({
|
|
64
|
-
version: a.string(),
|
|
65
|
-
projectName: a.string(),
|
|
66
|
-
initializedAt: a.string(),
|
|
67
|
-
nextId: a.object({
|
|
68
|
-
feat: a.number(),
|
|
69
|
-
fix: a.number(),
|
|
70
|
-
chore: a.number(),
|
|
71
|
-
docs: a.number(),
|
|
72
|
-
refactor: a.number()
|
|
73
|
-
}).optional(),
|
|
74
|
-
defaultAgent: a.enum(p).optional(),
|
|
75
|
-
defaultAgents: a.object({
|
|
76
|
-
phase: a.enum(p),
|
|
77
|
-
planDraft: a.enum(p),
|
|
78
|
-
ideaExtend: a.enum(p)
|
|
79
|
-
}).optional()
|
|
80
|
-
}), x = /^##\s+(.+?)\s*$/, W = /^\*\*([A-Za-z][A-Za-z-]*):\*\*\s*(.*)$/, Y = /^###\s+Phases\s*$/i, M = /^###\s+Log\s*$/i, Z = /^###\s+Clarifications\s*$/i, _ = /^#{2,3}\s+/, I = /^[-*]\s+\[([ xX])\]\s+(.*)$/, J = /^\[review\]\s+(.*)$/, K = /^-\s+(\d{4}-\d{2}-\d{2}):\s*(.*)$/;
|
|
81
|
-
function R(t, e, n) {
|
|
82
|
-
const o = t.split(`
|
|
83
|
-
`), s = o.findIndex((c) => e.test(c));
|
|
84
|
-
if (s === -1) return { body: t, entries: [] };
|
|
85
|
-
let i = o.length;
|
|
86
|
-
for (let c = s + 1; c < o.length; c++)
|
|
87
|
-
if (_.test(o[c])) {
|
|
88
|
-
i = c;
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
const r = n(o, s + 1, i);
|
|
92
|
-
return { body: [...o.slice(0, s), ...o.slice(i)].join(`
|
|
93
|
-
`).trim(), entries: r };
|
|
94
|
-
}
|
|
95
|
-
function Q(t, e, n) {
|
|
96
|
-
const o = [];
|
|
97
|
-
let s = e;
|
|
98
|
-
for (; s < n; ) {
|
|
99
|
-
const i = t[s].match(I);
|
|
100
|
-
if (i) {
|
|
101
|
-
const r = i[1].toLowerCase() === "x", l = i[2].trim(), c = l.match(J), d = c ? c[1].trim() : l, g = c ? "review" : void 0, f = [];
|
|
102
|
-
for (s++; s < n; ) {
|
|
103
|
-
const u = t[s];
|
|
104
|
-
if (u.trim() === "" || I.test(u) || _.test(u)) break;
|
|
105
|
-
if (/^\s/.test(u))
|
|
106
|
-
f.push(u.trimStart()), s++;
|
|
107
|
-
else
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
o.push({
|
|
111
|
-
done: r,
|
|
112
|
-
text: d,
|
|
113
|
-
description: f.length > 0 ? f.join(`
|
|
114
|
-
`) : void 0,
|
|
115
|
-
source: g
|
|
116
|
-
});
|
|
117
|
-
} else
|
|
118
|
-
s++;
|
|
119
|
-
}
|
|
120
|
-
return o;
|
|
121
|
-
}
|
|
122
|
-
function X(t) {
|
|
123
|
-
const e = R(t, Y, Q);
|
|
124
|
-
return { body: e.body, phases: e.entries };
|
|
125
|
-
}
|
|
126
|
-
function V(t, e, n) {
|
|
127
|
-
const o = [];
|
|
128
|
-
for (let s = e; s < n; s++) {
|
|
129
|
-
const i = t[s].match(K);
|
|
130
|
-
i && o.push({ date: i[1], text: i[2].trim() });
|
|
131
|
-
}
|
|
132
|
-
return o;
|
|
133
|
-
}
|
|
134
|
-
function P(t, e) {
|
|
135
|
-
return R(t, e, V);
|
|
136
|
-
}
|
|
137
|
-
function tt(t) {
|
|
138
|
-
const { body: e, entries: n } = P(t, M);
|
|
139
|
-
return { body: e, log: n };
|
|
140
|
-
}
|
|
141
|
-
function et(t) {
|
|
142
|
-
const { body: e, entries: n } = P(t, Z);
|
|
143
|
-
return { body: e, clarifications: n };
|
|
144
|
-
}
|
|
145
|
-
function w(t) {
|
|
146
|
-
const e = t.split(`
|
|
147
|
-
`), n = [];
|
|
148
|
-
for (let s = 0; s < e.length; s++)
|
|
149
|
-
x.test(e[s]) && n.push(s);
|
|
150
|
-
const o = [];
|
|
151
|
-
for (let s = 0; s < n.length; s++) {
|
|
152
|
-
const i = n[s], r = s + 1 < n.length ? n[s + 1] : e.length, l = e[i].match(x)[1], c = e.slice(i + 1, r);
|
|
153
|
-
let d = 0;
|
|
154
|
-
for (; d < c.length && c[d].trim() === ""; ) d++;
|
|
155
|
-
const g = {};
|
|
156
|
-
for (; d < c.length; ) {
|
|
157
|
-
const b = c[d].match(W);
|
|
158
|
-
if (!b) break;
|
|
159
|
-
g[b[1].toLowerCase()] = b[2].trim(), d++;
|
|
160
|
-
}
|
|
161
|
-
for (; d < c.length && c[d].trim() === ""; ) d++;
|
|
162
|
-
const f = c.slice(d).join(`
|
|
163
|
-
`).trim();
|
|
164
|
-
let { body: u, phases: D } = X(f);
|
|
165
|
-
const { body: N, log: B } = tt(u);
|
|
166
|
-
u = N;
|
|
167
|
-
const { body: C, clarifications: L } = et(u);
|
|
168
|
-
u = C, o.push({ title: l, fields: g, body: u, phases: D, log: B, clarifications: L });
|
|
169
|
-
}
|
|
170
|
-
return o;
|
|
171
|
-
}
|
|
172
|
-
function mt(t) {
|
|
173
|
-
const e = [], n = [];
|
|
174
|
-
for (const o of w(t)) {
|
|
175
|
-
const s = H.safeParse(o.fields);
|
|
176
|
-
if (!s.success) {
|
|
177
|
-
n.push({
|
|
178
|
-
title: o.title,
|
|
179
|
-
message: s.error.issues.map((r) => r.message).join("; ")
|
|
180
|
-
});
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
const i = s.data;
|
|
184
|
-
e.push({
|
|
185
|
-
title: o.title,
|
|
186
|
-
status: i.status,
|
|
187
|
-
kind: i.kind,
|
|
188
|
-
id: i.id,
|
|
189
|
-
idea: i.idea,
|
|
190
|
-
agent: i.agent,
|
|
191
|
-
created: i.created,
|
|
192
|
-
updated: i.updated,
|
|
193
|
-
tags: i.tags ? i.tags.split(",").map((r) => r.trim()).filter(Boolean) : [],
|
|
194
|
-
body: o.body,
|
|
195
|
-
phases: o.phases,
|
|
196
|
-
log: o.log,
|
|
197
|
-
clarifications: o.clarifications
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
return { entries: e, warnings: n };
|
|
201
|
-
}
|
|
202
|
-
function gt(t) {
|
|
203
|
-
const e = [], n = [];
|
|
204
|
-
for (const o of w(t)) {
|
|
205
|
-
const s = F.safeParse(o.fields);
|
|
206
|
-
if (!s.success) {
|
|
207
|
-
n.push({
|
|
208
|
-
title: o.title,
|
|
209
|
-
message: s.error.issues.map((r) => r.message).join("; ")
|
|
210
|
-
});
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
const i = s.data;
|
|
214
|
-
e.push({
|
|
215
|
-
title: o.title,
|
|
216
|
-
date: i.date,
|
|
217
|
-
status: i.status,
|
|
218
|
-
supersededBy: i["superseded-by"],
|
|
219
|
-
body: o.body
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
return { entries: e, warnings: n };
|
|
223
|
-
}
|
|
224
|
-
function yt(t) {
|
|
225
|
-
const e = [], n = [];
|
|
226
|
-
for (const o of w(t)) {
|
|
227
|
-
const s = q.safeParse(o.fields);
|
|
228
|
-
if (!s.success) {
|
|
229
|
-
n.push({
|
|
230
|
-
title: o.title,
|
|
231
|
-
message: s.error.issues.map((r) => r.message).join("; ")
|
|
232
|
-
});
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
const i = s.data;
|
|
236
|
-
e.push({
|
|
237
|
-
title: o.title,
|
|
238
|
-
status: i.status,
|
|
239
|
-
raised: i.raised,
|
|
240
|
-
resolvedBy: i["resolved-by"],
|
|
241
|
-
blocks: i.blocks,
|
|
242
|
-
body: o.body
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
return { entries: e, warnings: n };
|
|
246
|
-
}
|
|
247
|
-
const st = /^(IDEA-\d+):\s*/, nt = /\n---+\n/;
|
|
248
|
-
function bt(t) {
|
|
249
|
-
return t.split(nt).filter(Boolean).map((n) => {
|
|
250
|
-
var c;
|
|
251
|
-
const o = n.match(/^#{1,3}\s+(.+)/m), s = o ? o[1].trim() : ((c = n.trim().split(`
|
|
252
|
-
`)[0]) == null ? void 0 : c.trim()) ?? "Untitled", i = s.match(st), r = (i == null ? void 0 : i[1]) ?? null, l = r ? s.slice(i[0].length) : s;
|
|
253
|
-
return { id: r, title: l, body: n.trim() };
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
function $t(t, e) {
|
|
257
|
-
return t.map((n) => {
|
|
258
|
-
if (!n.id)
|
|
259
|
-
return { ...n, status: "planned" };
|
|
260
|
-
const o = e.filter((i) => i.idea === n.id);
|
|
261
|
-
if (o.length === 0)
|
|
262
|
-
return { ...n, status: "planned" };
|
|
263
|
-
const s = o.every((i) => i.status === "done" || i.status === "dropped");
|
|
264
|
-
return { ...n, status: s ? "done" : "planned" };
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
function Et(t, e, n) {
|
|
268
|
-
const o = new Set(t.map((i) => i.title)), s = [];
|
|
269
|
-
for (const i of t)
|
|
270
|
-
i.supersededBy && !o.has(i.supersededBy) && s.push({
|
|
271
|
-
kind: "dangling-superseded-by",
|
|
272
|
-
section: "decisions",
|
|
273
|
-
title: i.title,
|
|
274
|
-
message: `Superseded-by "${i.supersededBy}" doesn't match any decision`
|
|
275
|
-
});
|
|
276
|
-
for (const i of e)
|
|
277
|
-
if (i.resolvedBy && !o.has(i.resolvedBy) && s.push({
|
|
278
|
-
kind: "dangling-resolved-by",
|
|
279
|
-
section: "open-questions",
|
|
280
|
-
title: i.title,
|
|
281
|
-
message: `Resolved-by "${i.resolvedBy}" doesn't match any decision`
|
|
282
|
-
}), i.status === "open" && i.blocks) {
|
|
283
|
-
const r = n.find((l) => l.id === i.blocks);
|
|
284
|
-
r && (r.status === "in-progress" || r.status === "review") && s.push({
|
|
285
|
-
kind: "blocked-plan-active",
|
|
286
|
-
section: "open-questions",
|
|
287
|
-
title: i.title,
|
|
288
|
-
planId: r.id,
|
|
289
|
-
message: `Still open but blocks "${r.title}" (${r.id}), already ${r.status}`
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
return s;
|
|
293
|
-
}
|
|
294
|
-
const k = /^##\s+(\d{4}-\d{2}-\d{2})\s*$/, it = /^[-*]\s+(.*)$/;
|
|
295
|
-
function wt(t) {
|
|
296
|
-
const e = t.split(`
|
|
297
|
-
`), n = [];
|
|
298
|
-
for (let s = 0; s < e.length; s++)
|
|
299
|
-
k.test(e[s]) && n.push(s);
|
|
300
|
-
const o = [];
|
|
301
|
-
for (let s = 0; s < n.length; s++) {
|
|
302
|
-
const i = n[s], r = s + 1 < n.length ? n[s + 1] : e.length, l = e[i].match(k)[1], c = e.slice(i + 1, r).map((d) => d.match(it)).filter((d) => d !== null).map((d) => d[1].trim());
|
|
303
|
-
o.push({ date: l, items: c });
|
|
304
|
-
}
|
|
305
|
-
return o;
|
|
306
|
-
}
|
|
307
|
-
const ot = "0.1.0";
|
|
308
|
-
class rt extends Error {
|
|
309
|
-
constructor(e) {
|
|
310
|
-
super(`Paper Camp is already initialized in ${e} (.paper-camp/config.json exists).`);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
async function $(t) {
|
|
314
|
-
try {
|
|
315
|
-
return await O(t), !0;
|
|
316
|
-
} catch {
|
|
317
|
-
return !1;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const at = ["plans.md", "progress.md", "decisions.md", "open-questions.md"];
|
|
321
|
-
async function St(t, e) {
|
|
322
|
-
const n = h(t, ".paper-camp"), o = h(n, "config.json"), s = h(t, "papercamp");
|
|
323
|
-
if (await $(o))
|
|
324
|
-
throw new rt(t);
|
|
325
|
-
const i = {
|
|
326
|
-
version: ot,
|
|
327
|
-
projectName: e.projectName,
|
|
328
|
-
initializedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
329
|
-
nextId: { feat: 1, fix: 1, chore: 1, docs: 1, refactor: 1 }
|
|
330
|
-
};
|
|
331
|
-
U.parse(i), await E(n, { recursive: !0 }), await m(o, `${JSON.stringify(i, null, 2)}
|
|
332
|
-
`, "utf-8"), await E(s, { recursive: !0 });
|
|
333
|
-
const r = h(s, "ideas.md");
|
|
334
|
-
if (!await $(r)) {
|
|
335
|
-
const l = e.intent ? `# ${e.projectName}
|
|
336
|
-
|
|
337
|
-
${e.intent}
|
|
338
|
-
` : `# ${e.projectName}
|
|
339
|
-
|
|
340
|
-
What are you building, and why?
|
|
341
|
-
`;
|
|
342
|
-
await m(r, l, "utf-8");
|
|
343
|
-
}
|
|
344
|
-
for (const l of at) {
|
|
345
|
-
const c = h(s, l);
|
|
346
|
-
await $(c) || await m(c, "", "utf-8");
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
function xt() {
|
|
350
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
351
|
-
}
|
|
352
|
-
let A = Promise.resolve();
|
|
353
|
-
async function It(t, e) {
|
|
354
|
-
const n = A.then(async () => {
|
|
355
|
-
let o = null;
|
|
356
|
-
try {
|
|
357
|
-
o = JSON.parse(await j(t, "utf-8"));
|
|
358
|
-
} catch {
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
if (!(o != null && o.nextId)) return;
|
|
362
|
-
const s = o.nextId[e] ?? 1, i = `${e.toUpperCase()}-${s}`;
|
|
363
|
-
return o.nextId[e] = s + 1, await m(t, `${JSON.stringify(o, null, 2)}
|
|
364
|
-
`), i;
|
|
365
|
-
});
|
|
366
|
-
return A = n.catch(() => {
|
|
367
|
-
}), n;
|
|
368
|
-
}
|
|
369
|
-
function ct(t) {
|
|
370
|
-
const e = [`## ${t.title}`, "", `**Status:** ${t.status}`];
|
|
371
|
-
if (t.kind && e.push(`**Kind:** ${t.kind}`), t.id && e.push(`**Id:** ${t.id}`), t.idea && e.push(`**Idea:** ${t.idea}`), t.agent && e.push(`**Agent:** ${t.agent}`), e.push(`**Created:** ${t.created}`), t.updated && e.push(`**Updated:** ${t.updated}`), t.tags && t.tags.length > 0 && e.push(`**Tags:** ${t.tags.join(", ")}`), e.push(""), t.body && e.push(t.body, ""), t.clarifications && t.clarifications.length > 0) {
|
|
372
|
-
e.push("### Clarifications");
|
|
373
|
-
for (const n of t.clarifications)
|
|
374
|
-
e.push(`- ${n.date}: ${n.text}`);
|
|
375
|
-
e.push("");
|
|
376
|
-
}
|
|
377
|
-
if (t.phases && t.phases.length > 0) {
|
|
378
|
-
e.push("### Phases");
|
|
379
|
-
for (const n of t.phases) {
|
|
380
|
-
const o = n.source === "review" ? `[review] ${n.text}` : n.text;
|
|
381
|
-
if (e.push(`- [${n.done ? "x" : " "}] ${o}`), n.description)
|
|
382
|
-
for (const s of n.description.split(`
|
|
383
|
-
`))
|
|
384
|
-
e.push(` ${s}`);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
if (t.log && t.log.length > 0) {
|
|
388
|
-
e.push("", "### Log");
|
|
389
|
-
for (const n of t.log)
|
|
390
|
-
e.push(`- ${n.date}: ${n.text}`);
|
|
391
|
-
}
|
|
392
|
-
return e.join(`
|
|
393
|
-
`).trimEnd();
|
|
394
|
-
}
|
|
395
|
-
function kt(t) {
|
|
396
|
-
const e = [`## ${t.title}`, "", `**Date:** ${t.date}`, `**Status:** ${t.status}`];
|
|
397
|
-
return t.supersededBy && e.push(`**Superseded-by:** ${t.supersededBy}`), e.push(""), t.body && e.push(t.body), e.join(`
|
|
398
|
-
`).trimEnd();
|
|
399
|
-
}
|
|
400
|
-
function At(t) {
|
|
401
|
-
const e = [
|
|
402
|
-
`## ${t.title}`,
|
|
403
|
-
"",
|
|
404
|
-
`**Status:** ${t.status}`,
|
|
405
|
-
`**Raised:** ${t.raised}`
|
|
406
|
-
];
|
|
407
|
-
return t.resolvedBy && e.push(`**Resolved-by:** ${t.resolvedBy}`), t.blocks && e.push(`**Blocks:** ${t.blocks}`), e.push(""), t.body && e.push(t.body), e.join(`
|
|
408
|
-
`).trimEnd();
|
|
409
|
-
}
|
|
410
|
-
function jt(t, e) {
|
|
411
|
-
return [`## ${t}`, ...e.map((n) => `- ${n}`)].join(`
|
|
412
|
-
`);
|
|
413
|
-
}
|
|
414
|
-
function vt(t) {
|
|
415
|
-
return t.length === 0 ? "" : `${t.map((e) => ct(e)).join(`
|
|
416
|
-
|
|
417
|
-
`)}
|
|
418
|
-
`;
|
|
419
|
-
}
|
|
420
|
-
async function _t(t, e) {
|
|
421
|
-
await E(T(t), { recursive: !0 });
|
|
422
|
-
let n = "";
|
|
423
|
-
try {
|
|
424
|
-
n = await j(t, "utf-8");
|
|
425
|
-
} catch (i) {
|
|
426
|
-
if (i.code !== "ENOENT") throw i;
|
|
427
|
-
}
|
|
428
|
-
const o = n.trimEnd(), s = o.length > 0 ? `${o}
|
|
429
|
-
|
|
430
|
-
${e}
|
|
431
|
-
` : `${e}
|
|
432
|
-
`;
|
|
433
|
-
await m(t, s, "utf-8");
|
|
434
|
-
}
|
|
435
|
-
export {
|
|
436
|
-
rt as A,
|
|
437
|
-
ot as P,
|
|
438
|
-
_t as a,
|
|
439
|
-
pt as b,
|
|
440
|
-
It as c,
|
|
441
|
-
F as d,
|
|
442
|
-
$t as e,
|
|
443
|
-
Et as f,
|
|
444
|
-
kt as g,
|
|
445
|
-
At as h,
|
|
446
|
-
ct as i,
|
|
447
|
-
vt as j,
|
|
448
|
-
jt as k,
|
|
449
|
-
St as l,
|
|
450
|
-
gt as m,
|
|
451
|
-
ht as n,
|
|
452
|
-
q as o,
|
|
453
|
-
U as p,
|
|
454
|
-
bt as q,
|
|
455
|
-
yt as r,
|
|
456
|
-
mt as s,
|
|
457
|
-
wt as t,
|
|
458
|
-
w as u,
|
|
459
|
-
H as v,
|
|
460
|
-
xt as w
|
|
461
|
-
};
|
|
462
|
-
//# sourceMappingURL=serializer.D1Ts_p8h.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.D1Ts_p8h.js","sources":["../../src/core/env.ts","../../src/core/schemas.ts","../../src/core/parser.ts","../../src/core/scaffold.ts","../../src/core/serializer.ts"],"sourcesContent":["import type { EnvEntry } from '../types/index';\n\nconst ENTRY_RE = /^([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*)$/;\n\nfunction unquote(value: string): string {\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction quoteIfNeeded(value: string): string {\n if (value === '' || /[\\s#\"]/.test(value)) return `\"${value.replace(/\"/g, '\\\\\"')}\"`;\n return value;\n}\n\nfunction matchEntry(line: string): { key: string; value: string } | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) return null;\n const match = trimmed.match(ENTRY_RE);\n return match ? { key: match[1], value: unquote(match[2]) } : null;\n}\n\n/** Parses `KEY=value` lines, skipping comments and blank lines. */\nexport function parseEnv(content: string): EnvEntry[] {\n const entries: EnvEntry[] = [];\n for (const line of content.split('\\n')) {\n const match = matchEntry(line);\n if (match) entries.push(match);\n }\n return entries;\n}\n\n/**\n * Replaces matched-key lines in place, drops keys no longer present, and appends\n * new keys at the end — preserving comments and the ordering of every untouched line.\n */\nexport function applyEnvEntries(content: string, entries: EnvEntry[]): string {\n const desired = new Map(entries.map((e) => [e.key, e.value]));\n const lines = content.length > 0 ? content.split('\\n') : [];\n const result: string[] = [];\n\n for (const line of lines) {\n const match = matchEntry(line);\n if (!match) {\n result.push(line);\n continue;\n }\n if (!desired.has(match.key)) continue; // key removed\n result.push(`${match.key}=${quoteIfNeeded(desired.get(match.key) ?? '')}`);\n desired.delete(match.key);\n }\n\n for (const [key, value] of desired) {\n result.push(`${key}=${quoteIfNeeded(value)}`);\n }\n\n while (result.length > 0 && result[result.length - 1] === '') result.pop();\n\n return result.length > 0 ? `${result.join('\\n')}\\n` : '';\n}\n","import { z } from 'zod';\nimport { AGENT_IDS } from '../types/index';\n\nconst dateString = z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'expected a YYYY-MM-DD date');\n\nexport const planFieldsSchema = z.object({\n status: z.enum(['idea', 'planned', 'in-progress', 'review', 'done', 'dropped']),\n kind: z.enum(['feat', 'fix', 'chore', 'docs', 'refactor']).optional(),\n id: z.string().optional(),\n idea: z.string().optional(),\n agent: z.enum(AGENT_IDS).optional(),\n created: dateString,\n updated: dateString.optional(),\n tags: z.string().optional(),\n});\n\nexport const decisionFieldsSchema = z.object({\n date: dateString,\n status: z.enum(['decided', 'superseded']),\n 'superseded-by': z.string().optional(),\n});\n\nexport const openQuestionFieldsSchema = z.object({\n status: z.enum(['open', 'resolved']),\n raised: dateString,\n 'resolved-by': z.string().optional(),\n blocks: z.string().optional(),\n});\n\nexport const paperCampConfigSchema = z.object({\n version: z.string(),\n projectName: z.string(),\n initializedAt: z.string(),\n nextId: z\n .object({\n feat: z.number(),\n fix: z.number(),\n chore: z.number(),\n docs: z.number(),\n refactor: z.number(),\n })\n .optional(),\n defaultAgent: z.enum(AGENT_IDS).optional(),\n defaultAgents: z\n .object({\n phase: z.enum(AGENT_IDS),\n planDraft: z.enum(AGENT_IDS),\n ideaExtend: z.enum(AGENT_IDS),\n })\n .optional(),\n});\n\nexport type PlanFields = z.infer<typeof planFieldsSchema>;\nexport type DecisionFields = z.infer<typeof decisionFieldsSchema>;\nexport type OpenQuestionFields = z.infer<typeof openQuestionFieldsSchema>;\n","import type {\n ConsistencyIssue,\n DecisionEntry,\n IdeaEntry,\n IdeaStatus,\n OpenQuestionEntry,\n ParseResult,\n PhaseItem,\n PlanEntry,\n ProgressEntry,\n RawEntry,\n} from '../types/index';\nimport { decisionFieldsSchema, openQuestionFieldsSchema, planFieldsSchema } from './schemas';\n\nconst HEADING_RE = /^##\\s+(.+?)\\s*$/;\nconst FIELD_RE = /^\\*\\*([A-Za-z][A-Za-z-]*):\\*\\*\\s*(.*)$/;\nconst PHASES_HEADING_RE = /^###\\s+Phases\\s*$/i;\nconst LOG_HEADING_RE = /^###\\s+Log\\s*$/i;\nconst CLARIFICATIONS_HEADING_RE = /^###\\s+Clarifications\\s*$/i;\nconst SUB_HEADING_RE = /^#{2,3}\\s+/;\nconst CHECKBOX_RE = /^[-*]\\s+\\[([ xX])\\]\\s+(.*)$/;\nconst PHASE_SOURCE_RE = /^\\[review\\]\\s+(.*)$/;\nconst LOG_ENTRY_RE = /^-\\s+(\\d{4}-\\d{2}-\\d{2}):\\s*(.*)$/;\n\nfunction extractSection<T>(\n body: string,\n headingRe: RegExp,\n parseFn: (lines: string[], start: number, end: number) => T[],\n): { body: string; entries: T[] } {\n const lines = body.split('\\n');\n const sectionStart = lines.findIndex((line) => headingRe.test(line));\n if (sectionStart === -1) return { body, entries: [] };\n\n let sectionEnd = lines.length;\n for (let i = sectionStart + 1; i < lines.length; i++) {\n if (SUB_HEADING_RE.test(lines[i])) {\n sectionEnd = i;\n break;\n }\n }\n\n const entries = parseFn(lines, sectionStart + 1, sectionEnd);\n const remaining = [...lines.slice(0, sectionStart), ...lines.slice(sectionEnd)].join('\\n').trim();\n return { body: remaining, entries };\n}\n\nfunction parsePhaseEntries(lines: string[], start: number, end: number): PhaseItem[] {\n const phases: PhaseItem[] = [];\n let i = start;\n while (i < end) {\n const match = lines[i].match(CHECKBOX_RE);\n if (match) {\n const done = match[1].toLowerCase() === 'x';\n const rawText = match[2].trim();\n const sourceMatch = rawText.match(PHASE_SOURCE_RE);\n const text = sourceMatch ? sourceMatch[1].trim() : rawText;\n const source = sourceMatch ? ('review' as const) : undefined;\n const descriptionLines: string[] = [];\n i++;\n while (i < end) {\n const next = lines[i];\n if (next.trim() === '') break;\n if (CHECKBOX_RE.test(next) || SUB_HEADING_RE.test(next)) break;\n if (/^\\s/.test(next)) {\n descriptionLines.push(next.trimStart());\n i++;\n } else {\n break;\n }\n }\n phases.push({\n done,\n text,\n description: descriptionLines.length > 0 ? descriptionLines.join('\\n') : undefined,\n source,\n });\n } else {\n i++;\n }\n }\n return phases;\n}\n\nfunction extractPhases(body: string): { body: string; phases: PhaseItem[] } {\n const result = extractSection(body, PHASES_HEADING_RE, parsePhaseEntries);\n return { body: result.body, phases: result.entries };\n}\n\nfunction parseDatedListEntries(\n lines: string[],\n start: number,\n end: number,\n): import('../types/index').LogEntry[] {\n const entries: import('../types/index').LogEntry[] = [];\n for (let i = start; i < end; i++) {\n const match = lines[i].match(LOG_ENTRY_RE);\n if (match) {\n entries.push({ date: match[1], text: match[2].trim() });\n }\n }\n return entries;\n}\n\nfunction extractDatedList(\n body: string,\n headingRe: RegExp,\n): { body: string; entries: import('../types/index').LogEntry[] } {\n return extractSection(body, headingRe, parseDatedListEntries);\n}\n\nfunction extractLog(body: string): { body: string; log: import('../types/index').LogEntry[] } {\n const { body: remaining, entries } = extractDatedList(body, LOG_HEADING_RE);\n return { body: remaining, log: entries };\n}\n\nfunction extractClarifications(body: string): {\n body: string;\n clarifications: import('../types/index').LogEntry[];\n} {\n const { body: remaining, entries } = extractDatedList(body, CLARIFICATIONS_HEADING_RE);\n return { body: remaining, clarifications: entries };\n}\n\nexport function parseRawEntries(markdown: string): RawEntry[] {\n const lines = markdown.split('\\n');\n const headingIndices: number[] = [];\n for (let i = 0; i < lines.length; i++) {\n if (HEADING_RE.test(lines[i])) {\n headingIndices.push(i);\n }\n }\n\n const entries: RawEntry[] = [];\n for (let h = 0; h < headingIndices.length; h++) {\n const start = headingIndices[h];\n const end = h + 1 < headingIndices.length ? headingIndices[h + 1] : lines.length;\n const title = lines[start].match(HEADING_RE)![1];\n const block = lines.slice(start + 1, end);\n\n let cursor = 0;\n while (cursor < block.length && block[cursor].trim() === '') cursor++;\n\n const fields: Record<string, string> = {};\n while (cursor < block.length) {\n const match = block[cursor].match(FIELD_RE);\n if (!match) break;\n fields[match[1].toLowerCase()] = match[2].trim();\n cursor++;\n }\n\n while (cursor < block.length && block[cursor].trim() === '') cursor++;\n\n const rawBody = block.slice(cursor).join('\\n').trim();\n let { body, phases } = extractPhases(rawBody);\n const { body: bodyAfterLog, log } = extractLog(body);\n body = bodyAfterLog;\n const { body: bodyAfterClarifications, clarifications } = extractClarifications(body);\n body = bodyAfterClarifications;\n\n entries.push({ title, fields, body, phases, log, clarifications });\n }\n\n return entries;\n}\n\nexport function parsePlans(markdown: string): ParseResult<PlanEntry> {\n const entries: PlanEntry[] = [];\n const warnings: ParseResult<PlanEntry>['warnings'] = [];\n\n for (const raw of parseRawEntries(markdown)) {\n const result = planFieldsSchema.safeParse(raw.fields);\n if (!result.success) {\n warnings.push({\n title: raw.title,\n message: result.error.issues.map((i) => i.message).join('; '),\n });\n continue;\n }\n const fields = result.data;\n entries.push({\n title: raw.title,\n status: fields.status,\n kind: fields.kind,\n id: fields.id,\n idea: fields.idea,\n agent: fields.agent,\n created: fields.created,\n updated: fields.updated,\n tags: fields.tags\n ? fields.tags\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean)\n : [],\n body: raw.body,\n phases: raw.phases,\n log: raw.log,\n clarifications: raw.clarifications,\n });\n }\n\n return { entries, warnings };\n}\n\nexport function parseDecisions(markdown: string): ParseResult<DecisionEntry> {\n const entries: DecisionEntry[] = [];\n const warnings: ParseResult<DecisionEntry>['warnings'] = [];\n\n for (const raw of parseRawEntries(markdown)) {\n const result = decisionFieldsSchema.safeParse(raw.fields);\n if (!result.success) {\n warnings.push({\n title: raw.title,\n message: result.error.issues.map((i) => i.message).join('; '),\n });\n continue;\n }\n const fields = result.data;\n entries.push({\n title: raw.title,\n date: fields.date,\n status: fields.status,\n supersededBy: fields['superseded-by'],\n body: raw.body,\n });\n }\n\n return { entries, warnings };\n}\n\nexport function parseOpenQuestions(markdown: string): ParseResult<OpenQuestionEntry> {\n const entries: OpenQuestionEntry[] = [];\n const warnings: ParseResult<OpenQuestionEntry>['warnings'] = [];\n\n for (const raw of parseRawEntries(markdown)) {\n const result = openQuestionFieldsSchema.safeParse(raw.fields);\n if (!result.success) {\n warnings.push({\n title: raw.title,\n message: result.error.issues.map((i) => i.message).join('; '),\n });\n continue;\n }\n const fields = result.data;\n entries.push({\n title: raw.title,\n status: fields.status,\n raised: fields.raised,\n resolvedBy: fields['resolved-by'],\n blocks: fields.blocks,\n body: raw.body,\n });\n }\n\n return { entries, warnings };\n}\n\nconst IDEA_ID_RE = /^(IDEA-\\d+):\\s*/;\n\nconst IDEA_SEPARATOR_RE = /\\n---+\\n/;\n\n/** ideas.md is split into sections by `---` separators. Each section has an optional\n * `### IDEA-N:` heading prefix followed by a short title, and a prose body. */\nexport function parseIdeas(markdown: string): IdeaEntry[] {\n const sections = markdown.split(IDEA_SEPARATOR_RE).filter(Boolean);\n return sections.map((section) => {\n const headingMatch = section.match(/^#{1,3}\\s+(.+)/m);\n const rawTitle = headingMatch\n ? headingMatch[1].trim()\n : (section.trim().split('\\n')[0]?.trim() ?? 'Untitled');\n const idMatch = rawTitle.match(IDEA_ID_RE);\n const id = idMatch?.[1] ?? null;\n const title = id ? rawTitle.slice(idMatch![0].length) : rawTitle;\n return { id, title, body: section.trim() };\n });\n}\n\nexport function deriveIdeaStatuses(ideas: IdeaEntry[], plans: PlanEntry[]): IdeaEntry[] {\n return ideas.map((idea) => {\n if (!idea.id) {\n return { ...idea, status: 'planned' };\n }\n const linkedPlans = plans.filter((p) => p.idea === idea.id);\n if (linkedPlans.length === 0) {\n return { ...idea, status: 'planned' };\n }\n const allDone = linkedPlans.every((p) => p.status === 'done' || p.status === 'dropped');\n return { ...idea, status: allDone ? 'done' : 'planned' };\n });\n}\n\n/** Read-only cross-reference checks over already-parsed decisions/open-questions/plans —\n * dangling `resolved-by`/`superseded-by` titles, and open questions blocking an\n * already-active plan. */\nexport function findConsistencyIssues(\n decisions: DecisionEntry[],\n openQuestions: OpenQuestionEntry[],\n plans: PlanEntry[],\n): ConsistencyIssue[] {\n const decisionTitles = new Set(decisions.map((d) => d.title));\n const issues: ConsistencyIssue[] = [];\n\n for (const decision of decisions) {\n if (decision.supersededBy && !decisionTitles.has(decision.supersededBy)) {\n issues.push({\n kind: 'dangling-superseded-by',\n section: 'decisions',\n title: decision.title,\n message: `Superseded-by \"${decision.supersededBy}\" doesn't match any decision`,\n });\n }\n }\n\n for (const question of openQuestions) {\n if (question.resolvedBy && !decisionTitles.has(question.resolvedBy)) {\n issues.push({\n kind: 'dangling-resolved-by',\n section: 'open-questions',\n title: question.title,\n message: `Resolved-by \"${question.resolvedBy}\" doesn't match any decision`,\n });\n }\n if (question.status === 'open' && question.blocks) {\n const blockedPlan = plans.find((p) => p.id === question.blocks);\n if (\n blockedPlan &&\n (blockedPlan.status === 'in-progress' || blockedPlan.status === 'review')\n ) {\n issues.push({\n kind: 'blocked-plan-active',\n section: 'open-questions',\n title: question.title,\n planId: blockedPlan.id,\n message: `Still open but blocks \"${blockedPlan.title}\" (${blockedPlan.id}), already ${blockedPlan.status}`,\n });\n }\n }\n }\n\n return issues;\n}\n\nconst PROGRESS_HEADING_RE = /^##\\s+(\\d{4}-\\d{2}-\\d{2})\\s*$/;\nconst BULLET_RE = /^[-*]\\s+(.*)$/;\n\n/** progress.md is an append-only date log, not a record-based file — no fields, no validation. */\nexport function parseProgress(markdown: string): ProgressEntry[] {\n const lines = markdown.split('\\n');\n const headingIndices: number[] = [];\n for (let i = 0; i < lines.length; i++) {\n if (PROGRESS_HEADING_RE.test(lines[i])) {\n headingIndices.push(i);\n }\n }\n\n const entries: ProgressEntry[] = [];\n for (let h = 0; h < headingIndices.length; h++) {\n const start = headingIndices[h];\n const end = h + 1 < headingIndices.length ? headingIndices[h + 1] : lines.length;\n const date = lines[start].match(PROGRESS_HEADING_RE)![1];\n const items = lines\n .slice(start + 1, end)\n .map((line) => line.match(BULLET_RE))\n .filter((m): m is RegExpMatchArray => m !== null)\n .map((m) => m[1].trim());\n\n entries.push({ date, items });\n }\n\n return entries;\n}\n","import { access, mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { PaperCampConfig } from '../types/index';\nimport { paperCampConfigSchema } from './schemas';\n\nexport const PAPER_CAMP_VERSION = '0.1.0';\n\nexport class AlreadyInitializedError extends Error {\n constructor(targetDir: string) {\n super(`Paper Camp is already initialized in ${targetDir} (.paper-camp/config.json exists).`);\n }\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nconst SKELETON_FILES = ['plans.md', 'progress.md', 'decisions.md', 'open-questions.md'];\n\nexport interface InitOptions {\n projectName: string;\n intent?: string;\n}\n\n/**\n * Scaffolds .paper-camp/config.json and papercamp/*.md. Never overwrites existing\n * files — a project's memory is never something `init` should clobber.\n */\nexport async function initProject(targetDir: string, options: InitOptions): Promise<void> {\n const configDir = join(targetDir, '.paper-camp');\n const configPath = join(configDir, 'config.json');\n const campDir = join(targetDir, 'papercamp');\n\n if (await exists(configPath)) {\n throw new AlreadyInitializedError(targetDir);\n }\n\n const config: PaperCampConfig = {\n version: PAPER_CAMP_VERSION,\n projectName: options.projectName,\n initializedAt: new Date().toISOString(),\n nextId: { feat: 1, fix: 1, chore: 1, docs: 1, refactor: 1 },\n };\n paperCampConfigSchema.parse(config);\n\n await mkdir(configDir, { recursive: true });\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, 'utf-8');\n\n await mkdir(campDir, { recursive: true });\n\n const ideasPath = join(campDir, 'ideas.md');\n if (!(await exists(ideasPath))) {\n const ideasBody = options.intent\n ? `# ${options.projectName}\\n\\n${options.intent}\\n`\n : `# ${options.projectName}\\n\\nWhat are you building, and why?\\n`;\n await writeFile(ideasPath, ideasBody, 'utf-8');\n }\n\n for (const name of SKELETON_FILES) {\n const filePath = join(campDir, name);\n if (!(await exists(filePath))) {\n await writeFile(filePath, '', 'utf-8');\n }\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { LogEntry, PhaseItem } from '../types/index';\n\nexport function todayDateString(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nlet idAssignmentChain: Promise<unknown> = Promise.resolve();\n\n/**\n * Mints the next `<KIND>-<N>` plan ID from the persistent counter in `.paper-camp/config.json`,\n * incrementing and writing it back. Calls are chained through a module-level promise so two\n * near-simultaneous calls within this process never read the same counter value and mint a\n * duplicate ID — this does not protect against a concurrent call from a separate process (e.g.\n * the CLI racing the dev server), which is an accepted gap for a local single-user tool.\n * Returns undefined if the config file is missing or has no `nextId` counters yet.\n */\nexport async function assignPlanId(configPath: string, kind: string): Promise<string | undefined> {\n const run = idAssignmentChain.then(async () => {\n let config: { nextId?: Record<string, number> } | null = null;\n try {\n config = JSON.parse(await readFile(configPath, 'utf-8')) as {\n nextId?: Record<string, number>;\n };\n } catch {\n return undefined;\n }\n if (!config?.nextId) return undefined;\n const next = config.nextId[kind] ?? 1;\n const id = `${kind.toUpperCase()}-${next}`;\n config.nextId[kind] = next + 1;\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n return id;\n });\n idAssignmentChain = run.catch(() => undefined);\n return run;\n}\n\ninterface NewPlanInput {\n title: string;\n status: string;\n kind?: string;\n id?: string;\n idea?: string;\n agent?: string;\n created: string;\n updated?: string;\n tags?: string[];\n body?: string;\n phases?: PhaseItem[];\n log?: LogEntry[];\n clarifications?: LogEntry[];\n}\n\nexport function formatPlanEntry(input: NewPlanInput): string {\n const lines = [`## ${input.title}`, '', `**Status:** ${input.status}`];\n if (input.kind) lines.push(`**Kind:** ${input.kind}`);\n if (input.id) lines.push(`**Id:** ${input.id}`);\n if (input.idea) lines.push(`**Idea:** ${input.idea}`);\n if (input.agent) lines.push(`**Agent:** ${input.agent}`);\n lines.push(`**Created:** ${input.created}`);\n if (input.updated) lines.push(`**Updated:** ${input.updated}`);\n if (input.tags && input.tags.length > 0) lines.push(`**Tags:** ${input.tags.join(', ')}`);\n lines.push('');\n if (input.body) lines.push(input.body, '');\n if (input.clarifications && input.clarifications.length > 0) {\n lines.push('### Clarifications');\n for (const entry of input.clarifications) {\n lines.push(`- ${entry.date}: ${entry.text}`);\n }\n lines.push('');\n }\n if (input.phases && input.phases.length > 0) {\n lines.push('### Phases');\n for (const phase of input.phases) {\n const text = phase.source === 'review' ? `[review] ${phase.text}` : phase.text;\n lines.push(`- [${phase.done ? 'x' : ' '}] ${text}`);\n if (phase.description) {\n for (const paragraphLine of phase.description.split('\\n')) {\n lines.push(` ${paragraphLine}`);\n }\n }\n }\n }\n if (input.log && input.log.length > 0) {\n lines.push('', '### Log');\n for (const entry of input.log) {\n lines.push(`- ${entry.date}: ${entry.text}`);\n }\n }\n return lines.join('\\n').trimEnd();\n}\n\ninterface NewDecisionInput {\n title: string;\n date: string;\n status: string;\n supersededBy?: string;\n body?: string;\n}\n\nexport function formatDecisionEntry(input: NewDecisionInput): string {\n const lines = [`## ${input.title}`, '', `**Date:** ${input.date}`, `**Status:** ${input.status}`];\n if (input.supersededBy) lines.push(`**Superseded-by:** ${input.supersededBy}`);\n lines.push('');\n if (input.body) lines.push(input.body);\n return lines.join('\\n').trimEnd();\n}\n\ninterface NewOpenQuestionInput {\n title: string;\n raised: string;\n status: string;\n resolvedBy?: string;\n blocks?: string;\n body?: string;\n}\n\nexport function formatOpenQuestionEntry(input: NewOpenQuestionInput): string {\n const lines = [\n `## ${input.title}`,\n '',\n `**Status:** ${input.status}`,\n `**Raised:** ${input.raised}`,\n ];\n if (input.resolvedBy) lines.push(`**Resolved-by:** ${input.resolvedBy}`);\n if (input.blocks) lines.push(`**Blocks:** ${input.blocks}`);\n lines.push('');\n if (input.body) lines.push(input.body);\n return lines.join('\\n').trimEnd();\n}\n\nexport function formatProgressEntry(date: string, items: string[]): string {\n return [`## ${date}`, ...items.map((item) => `- ${item}`)].join('\\n');\n}\n\n/** Serializes an array of plan entries back to a plans.md file. */\nexport function formatPlans(entries: NewPlanInput[]): string {\n if (entries.length === 0) return '';\n return `${entries.map((entry) => formatPlanEntry(entry)).join('\\n\\n')}\\n`;\n}\n\n/** Appends a pre-formatted block to a papercamp file, separated by a single blank line. */\nexport async function appendBlock(filePath: string, block: string): Promise<void> {\n await mkdir(dirname(filePath), { recursive: true });\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n\n const trimmed = existing.trimEnd();\n const next = trimmed.length > 0 ? `${trimmed}\\n\\n${block}\\n` : `${block}\\n`;\n await writeFile(filePath, next, 'utf-8');\n}\n"],"names":["ENTRY_RE","unquote","value","quoteIfNeeded","matchEntry","line","trimmed","match","parseEnv","content","entries","applyEnvEntries","desired","e","lines","result","key","dateString","z","planFieldsSchema","AGENT_IDS","decisionFieldsSchema","openQuestionFieldsSchema","paperCampConfigSchema","HEADING_RE","FIELD_RE","PHASES_HEADING_RE","LOG_HEADING_RE","CLARIFICATIONS_HEADING_RE","SUB_HEADING_RE","CHECKBOX_RE","PHASE_SOURCE_RE","LOG_ENTRY_RE","extractSection","body","headingRe","parseFn","sectionStart","sectionEnd","i","parsePhaseEntries","start","end","phases","done","rawText","sourceMatch","text","source","descriptionLines","next","extractPhases","parseDatedListEntries","extractDatedList","extractLog","remaining","extractClarifications","parseRawEntries","markdown","headingIndices","h","title","block","cursor","fields","rawBody","bodyAfterLog","log","bodyAfterClarifications","clarifications","parsePlans","warnings","raw","t","parseDecisions","parseOpenQuestions","IDEA_ID_RE","IDEA_SEPARATOR_RE","parseIdeas","section","headingMatch","rawTitle","_a","idMatch","id","deriveIdeaStatuses","ideas","plans","idea","linkedPlans","p","allDone","findConsistencyIssues","decisions","openQuestions","decisionTitles","d","issues","decision","question","blockedPlan","PROGRESS_HEADING_RE","BULLET_RE","parseProgress","date","items","m","PAPER_CAMP_VERSION","AlreadyInitializedError","targetDir","exists","path","access","SKELETON_FILES","initProject","options","configDir","join","configPath","campDir","config","mkdir","writeFile","ideasPath","ideasBody","name","filePath","todayDateString","idAssignmentChain","assignPlanId","kind","run","readFile","formatPlanEntry","input","entry","phase","paragraphLine","formatDecisionEntry","formatOpenQuestionEntry","formatProgressEntry","item","formatPlans","appendBlock","dirname","existing","error"],"mappings":"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"}
|