@difflab/pi 0.7.0-rc.202609271854.6af8600 → 0.7.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/agents/diffpi-planner.md +5 -5
- package/dist/cli.js +100 -53
- package/dist/extensions/index.js +86 -90
- package/dist/index.js +87 -90
- package/dist/plan/store.d.ts.map +1 -1
- package/dist/tools/index.js +86 -90
- package/package.json +1 -1
- package/skills/plan/SKILL.md +5 -5
- package/skills/plan/references/design-quality.md +29 -18
- package/skills/plan/references/workflows/new.md +5 -5
- package/skills/plan/references/workflows/update.md +5 -5
- package/templates/plan/PLAN.md +11 -17
- package/templates/plan/implementation.md +12 -28
- package/agents/diffpi-plan-reviewer.md +0 -27
package/dist/index.js
CHANGED
|
@@ -2635,8 +2635,8 @@ function parseJsonObject(content, path) {
|
|
|
2635
2635
|
}
|
|
2636
2636
|
// src/plan/store.ts
|
|
2637
2637
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
2638
|
-
import { mkdir as mkdir7, readdir as readdir2, readFile as
|
|
2639
|
-
import { basename as basename6, dirname as dirname8, join as
|
|
2638
|
+
import { mkdir as mkdir7, readdir as readdir2, readFile as readFile12, realpath as realpath4, rename as rename3, rm as rm2 } from "node:fs/promises";
|
|
2639
|
+
import { basename as basename6, dirname as dirname8, join as join16, resolve as resolve4, sep } from "node:path";
|
|
2640
2640
|
|
|
2641
2641
|
// src/extensions/fsx.ts
|
|
2642
2642
|
import { mkdir as mkdir6, rename as rename2, rm, writeFile as writeFile7 } from "node:fs/promises";
|
|
@@ -2687,6 +2687,42 @@ async function appendLogEntry(logPath, event) {
|
|
|
2687
2687
|
return entry;
|
|
2688
2688
|
}
|
|
2689
2689
|
|
|
2690
|
+
// src/templates.ts
|
|
2691
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
2692
|
+
import { homedir as homedir8 } from "node:os";
|
|
2693
|
+
import { join as join14, normalize } from "node:path";
|
|
2694
|
+
async function loadTemplate(name, options = {}) {
|
|
2695
|
+
const relative = templateRelativePath(name);
|
|
2696
|
+
const userPath = join14(options.homeDir ?? homedir8(), ".difflab", "diffpi", "templates", relative);
|
|
2697
|
+
const bundledPath = join14(options.bundledDir ?? resolveBundledTemplatesDir(), relative);
|
|
2698
|
+
const user = await readOptionalFile(userPath);
|
|
2699
|
+
if (user !== undefined)
|
|
2700
|
+
return { name, path: userPath, source: "user", content: user };
|
|
2701
|
+
const bundled = await readOptionalFile(bundledPath);
|
|
2702
|
+
if (bundled !== undefined)
|
|
2703
|
+
return { name, path: bundledPath, source: "bundled", content: bundled };
|
|
2704
|
+
throw new Error(`Template "${name}" was not found at ${userPath} or ${bundledPath}.`);
|
|
2705
|
+
}
|
|
2706
|
+
function renderTemplate(content, variables) {
|
|
2707
|
+
return content.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (match, key) => variables[key] ?? match);
|
|
2708
|
+
}
|
|
2709
|
+
function templateRelativePath(name) {
|
|
2710
|
+
const normalized = normalize(name.replaceAll("\\", "/")).replace(/^\.\//, "");
|
|
2711
|
+
if (!normalized || normalized.startsWith("../") || normalized.includes("/../") || normalized.startsWith("/")) {
|
|
2712
|
+
throw new Error(`Invalid template name: ${name}`);
|
|
2713
|
+
}
|
|
2714
|
+
return normalized.endsWith(".md") ? normalized : `${normalized}.md`;
|
|
2715
|
+
}
|
|
2716
|
+
async function readOptionalFile(path) {
|
|
2717
|
+
try {
|
|
2718
|
+
return await readFile11(path, "utf8");
|
|
2719
|
+
} catch (error) {
|
|
2720
|
+
if (error.code === "ENOENT")
|
|
2721
|
+
return;
|
|
2722
|
+
throw error;
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2690
2726
|
// src/plan/markdown.ts
|
|
2691
2727
|
var import_mdast_builder = __toESM(require_src(), 1);
|
|
2692
2728
|
|
|
@@ -4033,7 +4069,7 @@ var handle = {
|
|
|
4033
4069
|
};
|
|
4034
4070
|
|
|
4035
4071
|
// ../../node_modules/mdast-util-to-markdown/lib/join.js
|
|
4036
|
-
var
|
|
4072
|
+
var join15 = [joinDefaults];
|
|
4037
4073
|
function joinDefaults(left, right, parent, state) {
|
|
4038
4074
|
if (right.type === "code" && formatCodeAsIndented(right, state) && (left.type === "list" || left.type === right.type && formatCodeAsIndented(left, state))) {
|
|
4039
4075
|
return false;
|
|
@@ -6579,7 +6615,7 @@ function toMarkdown(tree, options) {
|
|
|
6579
6615
|
handle: undefined,
|
|
6580
6616
|
indentLines,
|
|
6581
6617
|
indexStack: [],
|
|
6582
|
-
join: [...
|
|
6618
|
+
join: [...join15],
|
|
6583
6619
|
options: {},
|
|
6584
6620
|
safe: safeBound,
|
|
6585
6621
|
stack: [],
|
|
@@ -7893,7 +7929,7 @@ async function resolvePlan(cwd, query, filters = {}, options = {}) {
|
|
|
7893
7929
|
continue;
|
|
7894
7930
|
if (normalizedQuery && entry.name !== normalizedQuery && stripDate(entry.name) !== normalizedQuery)
|
|
7895
7931
|
continue;
|
|
7896
|
-
const dir =
|
|
7932
|
+
const dir = join16(root, entry.name);
|
|
7897
7933
|
await assertContained(root, dir);
|
|
7898
7934
|
try {
|
|
7899
7935
|
const record = await readRecord(dir);
|
|
@@ -7928,30 +7964,26 @@ function createPlanStore(options = {}) {
|
|
|
7928
7964
|
async init(input) {
|
|
7929
7965
|
const root = await plansDir(input.cwd, options.homeDir);
|
|
7930
7966
|
const id = planRecordName(input.shortSlug, now());
|
|
7931
|
-
const dir =
|
|
7967
|
+
const dir = join16(root, id);
|
|
7932
7968
|
await createPlanDirectory(root, dir, id);
|
|
7933
7969
|
try {
|
|
7934
7970
|
const timestamp = now().toISOString();
|
|
7971
|
+
const template = await loadTemplate("plan/PLAN", {
|
|
7972
|
+
homeDir: options.homeDir,
|
|
7973
|
+
bundledDir: options.bundledTemplatesDir
|
|
7974
|
+
});
|
|
7935
7975
|
const title = input.title?.trim() || titleFromSlug(input.shortSlug);
|
|
7936
|
-
const
|
|
7937
|
-
schemaVersion: 1,
|
|
7976
|
+
const source = renderTemplate(template.content, {
|
|
7938
7977
|
id,
|
|
7939
|
-
revision: 0,
|
|
7940
|
-
title,
|
|
7941
7978
|
branch: input.branch,
|
|
7942
|
-
|
|
7943
|
-
...input.issueUrl?.trim() ? { issueUrl: input.issueUrl.trim() } : {},
|
|
7979
|
+
title,
|
|
7944
7980
|
intent: input.intent?.trim() || "<!-- Describe the intended outcome. -->",
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
updatedAt: timestamp
|
|
7952
|
-
};
|
|
7953
|
-
const source = renderPlanDocument(document);
|
|
7954
|
-
parsePlanDocument(source, join15(dir, "PLAN.md"));
|
|
7981
|
+
issue_id: input.issueId?.trim() || "",
|
|
7982
|
+
issue_url: input.issueUrl?.trim() || "",
|
|
7983
|
+
created_at: timestamp,
|
|
7984
|
+
updated_at: timestamp
|
|
7985
|
+
});
|
|
7986
|
+
const document = parsePlanDocument(source, join16(dir, "PLAN.md"));
|
|
7955
7987
|
const authoringRequest = input.request ?? { kind: "user", text: input.intent?.trim() || `Initialize phase-less plan ${title}.` };
|
|
7956
7988
|
await writeRevisionSnapshot(dir, document, source, authoringRequest, []);
|
|
7957
7989
|
await writeLatestView(dir, document, source, []);
|
|
@@ -7966,14 +7998,14 @@ function createPlanStore(options = {}) {
|
|
|
7966
7998
|
if (request.mode === "create") {
|
|
7967
7999
|
const root = await plansDir(cwd, options.homeDir);
|
|
7968
8000
|
const id = planRecordName(request.shortSlug, now());
|
|
7969
|
-
const dir =
|
|
8001
|
+
const dir = join16(root, id);
|
|
7970
8002
|
await createPlanDirectory(root, dir, id);
|
|
7971
8003
|
try {
|
|
7972
8004
|
const timestamp = now().toISOString();
|
|
7973
8005
|
const document = normalizeRevision(undefined, request, id, 0, timestamp);
|
|
7974
8006
|
assertCompleteRevision(document, request.briefs);
|
|
7975
8007
|
const source = renderPlanDocument(document);
|
|
7976
|
-
parsePlanDocument(source,
|
|
8008
|
+
parsePlanDocument(source, join16(dir, "PLAN.md"));
|
|
7977
8009
|
await writeRevisionSnapshot(dir, document, source, request.request, request.briefs);
|
|
7978
8010
|
await writeLatestView(dir, document, source, request.briefs);
|
|
7979
8011
|
return await readRecord(dir);
|
|
@@ -7983,7 +8015,7 @@ function createPlanStore(options = {}) {
|
|
|
7983
8015
|
}
|
|
7984
8016
|
}
|
|
7985
8017
|
const initial = await read(cwd, request.plan);
|
|
7986
|
-
return withDirectoryLock(
|
|
8018
|
+
return withDirectoryLock(join16(initial.dir, ".lock"), async () => {
|
|
7987
8019
|
const current = await readRecord(initial.dir);
|
|
7988
8020
|
if (current.document.revision !== request.expectedPlanRevision)
|
|
7989
8021
|
throw new Error(`Expected plan revision ${request.expectedPlanRevision}, found ${current.document.revision}.`);
|
|
@@ -7996,7 +8028,7 @@ function createPlanStore(options = {}) {
|
|
|
7996
8028
|
try {
|
|
7997
8029
|
await writeLatestView(current.dir, document, source, request.briefs);
|
|
7998
8030
|
} catch (error) {
|
|
7999
|
-
await rm2(
|
|
8031
|
+
await rm2(join16(current.dir, "revisions", String(revision)), { recursive: true, force: true });
|
|
8000
8032
|
throw error;
|
|
8001
8033
|
}
|
|
8002
8034
|
return await readRecord(current.dir);
|
|
@@ -8004,7 +8036,7 @@ function createPlanStore(options = {}) {
|
|
|
8004
8036
|
},
|
|
8005
8037
|
async mutate(cwd, query, operation, update) {
|
|
8006
8038
|
const initial = await read(cwd, query);
|
|
8007
|
-
return withDirectoryLock(
|
|
8039
|
+
return withDirectoryLock(join16(initial.dir, ".lock"), async () => {
|
|
8008
8040
|
const current = await readRecord(initial.dir);
|
|
8009
8041
|
const next = await update(structuredClone(current.document));
|
|
8010
8042
|
if (next.id !== current.id)
|
|
@@ -8027,16 +8059,16 @@ function createPlanStore(options = {}) {
|
|
|
8027
8059
|
};
|
|
8028
8060
|
}
|
|
8029
8061
|
async function readRecord(dir) {
|
|
8030
|
-
const planPath =
|
|
8031
|
-
const logPath =
|
|
8032
|
-
const source = await
|
|
8062
|
+
const planPath = join16(dir, "PLAN.md");
|
|
8063
|
+
const logPath = join16(dir, "logs.txt");
|
|
8064
|
+
const source = await readFile12(planPath, "utf8");
|
|
8033
8065
|
const document = parsePlanDocument(source, planPath);
|
|
8034
8066
|
return {
|
|
8035
8067
|
id: basename6(dir),
|
|
8036
8068
|
dir,
|
|
8037
8069
|
planPath,
|
|
8038
8070
|
logPath,
|
|
8039
|
-
implementationDir:
|
|
8071
|
+
implementationDir: join16(dir, "implementation"),
|
|
8040
8072
|
document,
|
|
8041
8073
|
source
|
|
8042
8074
|
};
|
|
@@ -8056,17 +8088,17 @@ async function writeRevisionSnapshot(planDir, document, source, request, briefs)
|
|
|
8056
8088
|
throw new Error("An exact non-empty authoring request is required.");
|
|
8057
8089
|
if (request.kind === "annotation" && !request.response?.trim())
|
|
8058
8090
|
throw new Error("Annotation requests require a non-empty response.");
|
|
8059
|
-
const revisionsDir =
|
|
8091
|
+
const revisionsDir = join16(planDir, "revisions");
|
|
8060
8092
|
await mkdir7(revisionsDir, { recursive: true });
|
|
8061
|
-
const target =
|
|
8093
|
+
const target = join16(revisionsDir, String(document.revision));
|
|
8062
8094
|
try {
|
|
8063
|
-
await
|
|
8095
|
+
await readFile12(join16(target, "metadata.json"), "utf8");
|
|
8064
8096
|
throw new Error(`Revision ${document.revision} already exists and is immutable.`);
|
|
8065
8097
|
} catch (error) {
|
|
8066
8098
|
if (error.code !== "ENOENT")
|
|
8067
8099
|
throw error;
|
|
8068
8100
|
}
|
|
8069
|
-
const staging =
|
|
8101
|
+
const staging = join16(revisionsDir, `.tmp-${document.revision}-${randomUUID2()}`);
|
|
8070
8102
|
await mkdir7(staging);
|
|
8071
8103
|
try {
|
|
8072
8104
|
const requestSource = request.kind === "annotation" ? `## Original annotation
|
|
@@ -8074,8 +8106,8 @@ ${request.text}
|
|
|
8074
8106
|
|
|
8075
8107
|
## LLM response
|
|
8076
8108
|
${request.response}` : request.text;
|
|
8077
|
-
await atomicWrite(
|
|
8078
|
-
await atomicWrite(
|
|
8109
|
+
await atomicWrite(join16(staging, "request.md"), requestSource);
|
|
8110
|
+
await atomicWrite(join16(staging, "metadata.json"), `${JSON.stringify({
|
|
8079
8111
|
schemaVersion: 1,
|
|
8080
8112
|
id: document.id,
|
|
8081
8113
|
revision: document.revision,
|
|
@@ -8085,7 +8117,7 @@ ${request.response}` : request.text;
|
|
|
8085
8117
|
createdAt: document.updatedAt
|
|
8086
8118
|
}, null, 2)}
|
|
8087
8119
|
`);
|
|
8088
|
-
await atomicWrite(
|
|
8120
|
+
await atomicWrite(join16(staging, "PLAN.md"), source);
|
|
8089
8121
|
await writeImplementationDirectory(staging, document, briefs);
|
|
8090
8122
|
await rename3(staging, target);
|
|
8091
8123
|
} catch (error) {
|
|
@@ -8094,10 +8126,10 @@ ${request.response}` : request.text;
|
|
|
8094
8126
|
}
|
|
8095
8127
|
}
|
|
8096
8128
|
async function writeLatestView(planDir, document, source, briefs) {
|
|
8097
|
-
const current =
|
|
8098
|
-
const stagingRoot =
|
|
8099
|
-
const stagedImplementation =
|
|
8100
|
-
const backup =
|
|
8129
|
+
const current = join16(planDir, "implementation");
|
|
8130
|
+
const stagingRoot = join16(planDir, `.latest-${randomUUID2()}`);
|
|
8131
|
+
const stagedImplementation = join16(stagingRoot, "implementation");
|
|
8132
|
+
const backup = join16(planDir, `.implementation-backup-${randomUUID2()}`);
|
|
8101
8133
|
await mkdir7(stagingRoot);
|
|
8102
8134
|
await writeImplementationDirectory(stagingRoot, document, briefs);
|
|
8103
8135
|
let backedUp = false;
|
|
@@ -8110,7 +8142,7 @@ async function writeLatestView(planDir, document, source, briefs) {
|
|
|
8110
8142
|
throw error;
|
|
8111
8143
|
}
|
|
8112
8144
|
await rename3(stagedImplementation, current);
|
|
8113
|
-
await atomicWrite(
|
|
8145
|
+
await atomicWrite(join16(planDir, "PLAN.md"), source);
|
|
8114
8146
|
if (backedUp)
|
|
8115
8147
|
await rm2(backup, { recursive: true, force: true });
|
|
8116
8148
|
} catch (error) {
|
|
@@ -8123,13 +8155,13 @@ async function writeLatestView(planDir, document, source, briefs) {
|
|
|
8123
8155
|
}
|
|
8124
8156
|
}
|
|
8125
8157
|
async function writeImplementationDirectory(baseDir, document, briefs) {
|
|
8126
|
-
const implementationDir =
|
|
8158
|
+
const implementationDir = join16(baseDir, "implementation");
|
|
8127
8159
|
await mkdir7(implementationDir, { recursive: true });
|
|
8128
8160
|
for (const [index, phase] of document.phases.entries()) {
|
|
8129
8161
|
const brief = briefs[index];
|
|
8130
8162
|
if (!brief)
|
|
8131
8163
|
throw new Error(`Missing implementation brief for phase ${phase.id}.`);
|
|
8132
|
-
await atomicWrite(
|
|
8164
|
+
await atomicWrite(join16(implementationDir, `phase-${index + 1}.md`), renderImplementationBrief(document.revision, index + 1, phase, brief));
|
|
8133
8165
|
}
|
|
8134
8166
|
}
|
|
8135
8167
|
function normalizeRevision(current, request, id, revision, updatedAt) {
|
|
@@ -8282,9 +8314,9 @@ function titleFromSlug(value) {
|
|
|
8282
8314
|
}
|
|
8283
8315
|
// src/setup.ts
|
|
8284
8316
|
import { parseFrontmatter as parseFrontmatter3 } from "@earendil-works/pi-coding-agent";
|
|
8285
|
-
import { readdir as readdir3, readFile as
|
|
8286
|
-
import { homedir as
|
|
8287
|
-
import { basename as basename7, join as
|
|
8317
|
+
import { readdir as readdir3, readFile as readFile13 } from "node:fs/promises";
|
|
8318
|
+
import { homedir as homedir9 } from "node:os";
|
|
8319
|
+
import { basename as basename7, join as join17 } from "node:path";
|
|
8288
8320
|
var MISE_DEPENDENCIES = [
|
|
8289
8321
|
{ name: "node", tool: "node", spec: "node@22", minimumVersion: "22.19.0" },
|
|
8290
8322
|
{ name: "zellij", tool: "zellij", spec: "zellij@latest", minimumVersion: undefined },
|
|
@@ -8322,8 +8354,8 @@ var FORGE_DEPENDENCIES = {
|
|
|
8322
8354
|
gitlab: { name: "glab", tool: "glab", spec: "glab@latest", minimumVersion: undefined }
|
|
8323
8355
|
};
|
|
8324
8356
|
async function ensureMise(options = {}) {
|
|
8325
|
-
const homeDir = options.homeDir ??
|
|
8326
|
-
const current = await mise.executableCheck() ?? await mise.executableCheck(
|
|
8357
|
+
const homeDir = options.homeDir ?? homedir9();
|
|
8358
|
+
const current = await mise.executableCheck() ?? await mise.executableCheck(join17(homeDir, ".local", "bin", "mise"));
|
|
8327
8359
|
if (current)
|
|
8328
8360
|
return { executable: current, action: createSetupAction("mise", "ready", current) };
|
|
8329
8361
|
reportProgress(options, "Installing mise");
|
|
@@ -8372,9 +8404,9 @@ async function ensureMiseDeps(miseExecutable, options = {}) {
|
|
|
8372
8404
|
async function ensurePiPlugins(options = {}) {
|
|
8373
8405
|
const actions = await ensurePiPackages(PI_PACKAGES, options);
|
|
8374
8406
|
const agentDir = options.agentDir ?? pi.agentDir(options.homeDir);
|
|
8375
|
-
const webSearch = await pi.configEnsure(
|
|
8407
|
+
const webSearch = await pi.configEnsure(join17(agentDir, "web-search.json"), (config) => ({ ...config, workflow: "auto-summary" }), options.dryRun);
|
|
8376
8408
|
actions.push(getConfigSetupAction("web search settings", webSearch));
|
|
8377
|
-
const lsp = await pi.configEnsure(
|
|
8409
|
+
const lsp = await pi.configEnsure(join17(agentDir, "pi-lsp.json"), (config) => ({
|
|
8378
8410
|
...config,
|
|
8379
8411
|
progressive: { ...getRecord(config.progressive), enabled: true, inject: "none" }
|
|
8380
8412
|
}), options.dryRun);
|
|
@@ -8389,7 +8421,7 @@ async function ensurePiAgents(options = {}) {
|
|
|
8389
8421
|
const actions = [];
|
|
8390
8422
|
for (const entry of entries) {
|
|
8391
8423
|
const id = basename7(entry.name, ".md").replace(/^diffpi-/, "");
|
|
8392
|
-
const source = await
|
|
8424
|
+
const source = await readFile13(join17(bundledAgentsDir, entry.name), "utf8");
|
|
8393
8425
|
const content = materializeAgentModels(source, id, userConfig.config, options.availableModels);
|
|
8394
8426
|
const result = await pi.agentEnsure(entry.name, content, agentDir, options.dryRun);
|
|
8395
8427
|
actions.push(getConfigSetupAction(`pi agent ${id}`, result));
|
|
@@ -8398,7 +8430,7 @@ async function ensurePiAgents(options = {}) {
|
|
|
8398
8430
|
}
|
|
8399
8431
|
async function ensurePiSkills(miseExecutable, options = {}) {
|
|
8400
8432
|
const agentDir = options.agentDir ?? pi.agentDir(options.homeDir);
|
|
8401
|
-
const sharedSkillsDir =
|
|
8433
|
+
const sharedSkillsDir = join17(options.homeDir ?? homedir9(), ".agents", "skills");
|
|
8402
8434
|
const actions = [];
|
|
8403
8435
|
for (const source of PI_SKILL_SOURCES) {
|
|
8404
8436
|
const missing = [];
|
|
@@ -8594,7 +8626,7 @@ function reportProgress(options, message) {
|
|
|
8594
8626
|
options.onProgress?.(message);
|
|
8595
8627
|
}
|
|
8596
8628
|
async function packageVersion2() {
|
|
8597
|
-
const source = await
|
|
8629
|
+
const source = await readFile13(join17(resolveBundledAgentsDir(), "..", "package.json"), "utf8");
|
|
8598
8630
|
let value;
|
|
8599
8631
|
try {
|
|
8600
8632
|
value = JSON.parse(source);
|
|
@@ -8608,41 +8640,6 @@ async function packageVersion2() {
|
|
|
8608
8640
|
function getRecord(value) {
|
|
8609
8641
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8610
8642
|
}
|
|
8611
|
-
// src/templates.ts
|
|
8612
|
-
import { readFile as readFile13 } from "node:fs/promises";
|
|
8613
|
-
import { homedir as homedir9 } from "node:os";
|
|
8614
|
-
import { join as join17, normalize } from "node:path";
|
|
8615
|
-
async function loadTemplate(name, options = {}) {
|
|
8616
|
-
const relative = templateRelativePath(name);
|
|
8617
|
-
const userPath = join17(options.homeDir ?? homedir9(), ".difflab", "diffpi", "templates", relative);
|
|
8618
|
-
const bundledPath = join17(options.bundledDir ?? resolveBundledTemplatesDir(), relative);
|
|
8619
|
-
const user = await readOptionalFile(userPath);
|
|
8620
|
-
if (user !== undefined)
|
|
8621
|
-
return { name, path: userPath, source: "user", content: user };
|
|
8622
|
-
const bundled = await readOptionalFile(bundledPath);
|
|
8623
|
-
if (bundled !== undefined)
|
|
8624
|
-
return { name, path: bundledPath, source: "bundled", content: bundled };
|
|
8625
|
-
throw new Error(`Template "${name}" was not found at ${userPath} or ${bundledPath}.`);
|
|
8626
|
-
}
|
|
8627
|
-
function renderTemplate(content, variables) {
|
|
8628
|
-
return content.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (match, key) => variables[key] ?? match);
|
|
8629
|
-
}
|
|
8630
|
-
function templateRelativePath(name) {
|
|
8631
|
-
const normalized = normalize(name.replaceAll("\\", "/")).replace(/^\.\//, "");
|
|
8632
|
-
if (!normalized || normalized.startsWith("../") || normalized.includes("/../") || normalized.startsWith("/")) {
|
|
8633
|
-
throw new Error(`Invalid template name: ${name}`);
|
|
8634
|
-
}
|
|
8635
|
-
return normalized.endsWith(".md") ? normalized : `${normalized}.md`;
|
|
8636
|
-
}
|
|
8637
|
-
async function readOptionalFile(path) {
|
|
8638
|
-
try {
|
|
8639
|
-
return await readFile13(path, "utf8");
|
|
8640
|
-
} catch (error) {
|
|
8641
|
-
if (error.code === "ENOENT")
|
|
8642
|
-
return;
|
|
8643
|
-
throw error;
|
|
8644
|
-
}
|
|
8645
|
-
}
|
|
8646
8643
|
export {
|
|
8647
8644
|
CONVENTIONAL_COMMIT,
|
|
8648
8645
|
GitHubVcsBackend,
|
package/dist/plan/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/plan/store.ts"],"names":[],"mappings":"AAKA,OAAO,EAAkB,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/plan/store.ts"],"names":[],"mappings":"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"}
|