coding-friend-cli 1.38.3 → 1.38.4
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.
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "./chunk-NREZK463.js";
|
|
15
15
|
|
|
16
16
|
// src/commands/clean.ts
|
|
17
|
-
import { existsSync, readdirSync, rmSync, statSync } from "fs";
|
|
17
|
+
import { existsSync, readFileSync, readdirSync, rmSync, statSync } from "fs";
|
|
18
18
|
import { join, relative } from "path";
|
|
19
19
|
import { confirm, input, select } from "@inquirer/prompts";
|
|
20
20
|
import chalk from "chalk";
|
|
@@ -55,6 +55,32 @@ function matchesRange(entryPath, name, range, cutoff, now) {
|
|
|
55
55
|
return cutoff !== null && date.getTime() < cutoff.getTime();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
var STATUS_RE = /^status:\s*([^\s#]+)/m;
|
|
59
|
+
function readPlanStatus(entryPath, isDirectory) {
|
|
60
|
+
let file;
|
|
61
|
+
if (isDirectory) {
|
|
62
|
+
file = join(entryPath, "README.md");
|
|
63
|
+
} else if (entryPath.endsWith(".md")) {
|
|
64
|
+
file = entryPath;
|
|
65
|
+
} else {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (!existsSync(file)) return null;
|
|
69
|
+
try {
|
|
70
|
+
const content = readFileSync(file, "utf8");
|
|
71
|
+
if (!content.startsWith("---")) return null;
|
|
72
|
+
const end = content.indexOf("\n---", 3);
|
|
73
|
+
if (end === -1) return null;
|
|
74
|
+
const frontmatter = content.slice(3, end);
|
|
75
|
+
const m = STATUS_RE.exec(frontmatter);
|
|
76
|
+
return m ? m[1].trim().toLowerCase() : null;
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function isDonePlan(entryPath, isDirectory) {
|
|
82
|
+
return readPlanStatus(entryPath, isDirectory) === "done";
|
|
83
|
+
}
|
|
58
84
|
function countFiles(dir) {
|
|
59
85
|
if (!existsSync(dir)) return 0;
|
|
60
86
|
let count = 0;
|
|
@@ -68,12 +94,13 @@ function countFiles(dir) {
|
|
|
68
94
|
}
|
|
69
95
|
return count;
|
|
70
96
|
}
|
|
71
|
-
function deleteMatchingEntries(dir, range, cutoff, now) {
|
|
97
|
+
function deleteMatchingEntries(dir, range, cutoff, now, extraFilter) {
|
|
72
98
|
if (!existsSync(dir)) return { deleted: 0, failed: 0 };
|
|
73
99
|
let deleted = 0;
|
|
74
100
|
let failed = 0;
|
|
75
101
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
76
102
|
const entryPath = join(dir, entry.name);
|
|
103
|
+
if (extraFilter && !extraFilter(entryPath, entry.isDirectory())) continue;
|
|
77
104
|
if (matchesRange(entryPath, entry.name, range, cutoff, now)) {
|
|
78
105
|
const filesBefore = entry.isDirectory() ? countFiles(entryPath) : 1;
|
|
79
106
|
try {
|
|
@@ -147,7 +174,15 @@ async function cleanCommand() {
|
|
|
147
174
|
console.log(`${chalk.yellow("\u2192")} ${chalk.bold(entry.key)} (${relPath})`);
|
|
148
175
|
const { range, cutoff } = await promptDateRange();
|
|
149
176
|
const isMemory = entry.key === "memory";
|
|
150
|
-
const
|
|
177
|
+
const isPlans = entry.key === "plans";
|
|
178
|
+
let message;
|
|
179
|
+
if (isMemory) {
|
|
180
|
+
message = `Delete matching contents of ${relPath}/? (includes SQLite databases \u2014 stop memory daemon first if running)`;
|
|
181
|
+
} else if (isPlans) {
|
|
182
|
+
message = `Delete matching plans in ${relPath}/? (only plans with frontmatter status: done are removed \u2014 in-progress/failed plans are kept)`;
|
|
183
|
+
} else {
|
|
184
|
+
message = `Delete matching contents of ${relPath}/?`;
|
|
185
|
+
}
|
|
151
186
|
const ok = await confirm({ message, default: false });
|
|
152
187
|
if (ok) {
|
|
153
188
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -155,7 +190,8 @@ async function cleanCommand() {
|
|
|
155
190
|
entry.path,
|
|
156
191
|
range,
|
|
157
192
|
cutoff,
|
|
158
|
-
now
|
|
193
|
+
now,
|
|
194
|
+
isPlans ? isDonePlan : void 0
|
|
159
195
|
);
|
|
160
196
|
summary.push({ key: entry.key, deleted });
|
|
161
197
|
const failNote = failed > 0 ? `, ${failed} failed` : "";
|
|
@@ -181,7 +217,9 @@ async function cleanCommand() {
|
|
|
181
217
|
export {
|
|
182
218
|
cleanCommand,
|
|
183
219
|
getEffectiveDate,
|
|
220
|
+
isDonePlan,
|
|
184
221
|
matchesRange,
|
|
185
222
|
olderThanDays,
|
|
186
|
-
parseDateFromName
|
|
223
|
+
parseDateFromName,
|
|
224
|
+
readPlanStatus
|
|
187
225
|
};
|
package/dist/index.js
CHANGED
|
@@ -132,7 +132,7 @@ program.command("status").description("Show comprehensive Coding Friend status")
|
|
|
132
132
|
await statusCommand();
|
|
133
133
|
});
|
|
134
134
|
program.command("clean").description("Clean files generated by Coding Friend in docs/").action(async () => {
|
|
135
|
-
const { cleanCommand } = await import("./clean-
|
|
135
|
+
const { cleanCommand } = await import("./clean-MSRZSOSO.js");
|
|
136
136
|
await cleanCommand();
|
|
137
137
|
});
|
|
138
138
|
var session = program.command("session").description("[beta] Save and load Claude Code sessions across machines");
|