@monoes/monomindcli 2.16.11 → 2.16.13
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/.claude/agents/core/coder.md +1 -1
- package/.claude/agents/engineering/engineering-devops-automator.md +1 -1
- package/.claude/agents/github/repo-architect.md +1 -1
- package/.claude/agents/testing/production-validator.md +1 -1
- package/.claude/agents/testing/testing-tool-evaluator.md +1 -1
- package/.claude/commands/github/pr-manager.md +1 -1
- package/.claude/helpers/pick-rank.cjs +34 -4
- package/.claude/skills/monolean-audit/SKILL.md +1 -1
- package/dist/src/commands/cleanup-data.d.ts +30 -0
- package/dist/src/commands/cleanup-data.d.ts.map +1 -0
- package/dist/src/commands/cleanup-data.js +138 -0
- package/dist/src/commands/cleanup-data.js.map +1 -0
- package/dist/src/commands/cleanup-origin.d.ts +24 -0
- package/dist/src/commands/cleanup-origin.d.ts.map +1 -0
- package/dist/src/commands/cleanup-origin.js +67 -0
- package/dist/src/commands/cleanup-origin.js.map +1 -0
- package/dist/src/commands/cleanup-scratch.d.ts +43 -0
- package/dist/src/commands/cleanup-scratch.d.ts.map +1 -0
- package/dist/src/commands/cleanup-scratch.js +125 -0
- package/dist/src/commands/cleanup-scratch.js.map +1 -0
- package/dist/src/commands/cleanup.d.ts +2 -39
- package/dist/src/commands/cleanup.d.ts.map +1 -1
- package/dist/src/commands/cleanup.js +9 -296
- package/dist/src/commands/cleanup.js.map +1 -1
- package/dist/src/commands/doctor-gitignore-checks.d.ts +10 -0
- package/dist/src/commands/doctor-gitignore-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-gitignore-checks.js +141 -0
- package/dist/src/commands/doctor-gitignore-checks.js.map +1 -0
- package/dist/src/commands/doctor-helpers-checks.d.ts +10 -0
- package/dist/src/commands/doctor-helpers-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-helpers-checks.js +292 -0
- package/dist/src/commands/doctor-helpers-checks.js.map +1 -0
- package/dist/src/commands/doctor-memory-checks.d.ts +47 -0
- package/dist/src/commands/doctor-memory-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-memory-checks.js +298 -0
- package/dist/src/commands/doctor-memory-checks.js.map +1 -0
- package/dist/src/commands/doctor-monograph-checks.d.ts +9 -0
- package/dist/src/commands/doctor-monograph-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-monograph-checks.js +331 -0
- package/dist/src/commands/doctor-monograph-checks.js.map +1 -0
- package/dist/src/commands/doctor-project-checks.d.ts +7 -66
- package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
- package/dist/src/commands/doctor-project-checks.js +10 -1331
- package/dist/src/commands/doctor-project-checks.js.map +1 -1
- package/dist/src/commands/doctor-routing-checks.d.ts +10 -0
- package/dist/src/commands/doctor-routing-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-routing-checks.js +194 -0
- package/dist/src/commands/doctor-routing-checks.js.map +1 -0
- package/dist/src/commands/doctor-worker-checks.d.ts +17 -0
- package/dist/src/commands/doctor-worker-checks.d.ts.map +1 -0
- package/dist/src/commands/doctor-worker-checks.js +122 -0
- package/dist/src/commands/doctor-worker-checks.js.map +1 -0
- package/dist/src/commands/hooks-routing-commands.js +1 -1
- package/dist/src/commands/hooks-routing-commands.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +6 -15
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/init/never-commit.d.ts +3 -3
- package/dist/src/init/types.d.ts +1 -1
- package/dist/src/init/types.js +1 -1
- package/dist/src/knowledge/document-store.js +1 -1
- package/dist/src/knowledge/document-store.js.map +1 -1
- package/dist/src/mcp-tools/hooks-edit-command.d.ts +10 -0
- package/dist/src/mcp-tools/hooks-edit-command.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-edit-command.js +247 -0
- package/dist/src/mcp-tools/hooks-edit-command.js.map +1 -0
- package/dist/src/mcp-tools/hooks-learning.d.ts +9 -0
- package/dist/src/mcp-tools/hooks-learning.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-learning.js +408 -0
- package/dist/src/mcp-tools/hooks-learning.js.map +1 -0
- package/dist/src/mcp-tools/hooks-metrics-list.d.ts +8 -0
- package/dist/src/mcp-tools/hooks-metrics-list.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-metrics-list.js +205 -0
- package/dist/src/mcp-tools/hooks-metrics-list.js.map +1 -0
- package/dist/src/mcp-tools/hooks-route.d.ts +12 -0
- package/dist/src/mcp-tools/hooks-route.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-route.js +251 -0
- package/dist/src/mcp-tools/hooks-route.js.map +1 -0
- package/dist/src/mcp-tools/hooks-routing.d.ts +6 -27
- package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-routing.js +6 -1727
- package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
- package/dist/src/mcp-tools/hooks-session.d.ts +9 -0
- package/dist/src/mcp-tools/hooks-session.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-session.js +243 -0
- package/dist/src/mcp-tools/hooks-session.js.map +1 -0
- package/dist/src/mcp-tools/hooks-task.d.ts +17 -0
- package/dist/src/mcp-tools/hooks-task.d.ts.map +1 -0
- package/dist/src/mcp-tools/hooks-task.js +427 -0
- package/dist/src/mcp-tools/hooks-task.js.map +1 -0
- package/dist/src/mcp-tools/hooks-tools.d.ts +2 -1
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +2 -1
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/mcp-tools/memory-tools.js +1 -1
- package/dist/src/mcp-tools/memory-tools.js.map +1 -1
- package/dist/src/memory/bm25-index.d.ts +2 -2
- package/dist/src/memory/bm25-index.js +2 -2
- package/dist/src/memory/embedding-operations.js +2 -2
- package/dist/src/memory/embedding-operations.js.map +1 -1
- package/dist/src/memory/entity-name-key.d.ts +1 -1
- package/dist/src/memory/entity-name-key.js +1 -1
- package/dist/src/memory/hnsw-operations.d.ts +1 -1
- package/dist/src/memory/hnsw-operations.js +1 -1
- package/dist/src/memory/memory-bridge-backend.d.ts +43 -0
- package/dist/src/memory/memory-bridge-backend.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-backend.js +363 -0
- package/dist/src/memory/memory-bridge-backend.js.map +1 -0
- package/dist/src/memory/memory-bridge-core.d.ts +42 -0
- package/dist/src/memory/memory-bridge-core.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-core.js +126 -0
- package/dist/src/memory/memory-bridge-core.js.map +1 -0
- package/dist/src/memory/memory-bridge-entries.d.ts +131 -0
- package/dist/src/memory/memory-bridge-entries.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-entries.js +227 -0
- package/dist/src/memory/memory-bridge-entries.js.map +1 -0
- package/dist/src/memory/memory-bridge-feedback.d.ts +60 -0
- package/dist/src/memory/memory-bridge-feedback.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-feedback.js +118 -0
- package/dist/src/memory/memory-bridge-feedback.js.map +1 -0
- package/dist/src/memory/memory-bridge-paths.d.ts +123 -0
- package/dist/src/memory/memory-bridge-paths.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-paths.js +335 -0
- package/dist/src/memory/memory-bridge-paths.js.map +1 -0
- package/dist/src/memory/memory-bridge-search.d.ts +48 -0
- package/dist/src/memory/memory-bridge-search.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-search.js +383 -0
- package/dist/src/memory/memory-bridge-search.js.map +1 -0
- package/dist/src/memory/memory-bridge-sessions.d.ts +38 -0
- package/dist/src/memory/memory-bridge-sessions.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-sessions.js +109 -0
- package/dist/src/memory/memory-bridge-sessions.js.map +1 -0
- package/dist/src/memory/memory-bridge-store.d.ts +58 -0
- package/dist/src/memory/memory-bridge-store.d.ts.map +1 -0
- package/dist/src/memory/memory-bridge-store.js +201 -0
- package/dist/src/memory/memory-bridge-store.js.map +1 -0
- package/dist/src/memory/memory-bridge.d.ts +10 -438
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +14 -1787
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/memory-kg-claims.d.ts +52 -0
- package/dist/src/memory/memory-kg-claims.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-claims.js +99 -0
- package/dist/src/memory/memory-kg-claims.js.map +1 -0
- package/dist/src/memory/memory-kg-index.d.ts +86 -0
- package/dist/src/memory/memory-kg-index.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-index.js +256 -0
- package/dist/src/memory/memory-kg-index.js.map +1 -0
- package/dist/src/memory/memory-kg-ingest.d.ts +44 -0
- package/dist/src/memory/memory-kg-ingest.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-ingest.js +361 -0
- package/dist/src/memory/memory-kg-ingest.js.map +1 -0
- package/dist/src/memory/memory-kg-model.d.ts +168 -0
- package/dist/src/memory/memory-kg-model.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-model.js +158 -0
- package/dist/src/memory/memory-kg-model.js.map +1 -0
- package/dist/src/memory/memory-kg-names.d.ts +64 -0
- package/dist/src/memory/memory-kg-names.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-names.js +187 -0
- package/dist/src/memory/memory-kg-names.js.map +1 -0
- package/dist/src/memory/memory-kg-promote.d.ts +79 -0
- package/dist/src/memory/memory-kg-promote.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-promote.js +248 -0
- package/dist/src/memory/memory-kg-promote.js.map +1 -0
- package/dist/src/memory/memory-kg-rebuild.d.ts +77 -0
- package/dist/src/memory/memory-kg-rebuild.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-rebuild.js +299 -0
- package/dist/src/memory/memory-kg-rebuild.js.map +1 -0
- package/dist/src/memory/memory-kg-rollback.d.ts +47 -0
- package/dist/src/memory/memory-kg-rollback.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-rollback.js +193 -0
- package/dist/src/memory/memory-kg-rollback.js.map +1 -0
- package/dist/src/memory/memory-kg-rules.d.ts +64 -0
- package/dist/src/memory/memory-kg-rules.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-rules.js +251 -0
- package/dist/src/memory/memory-kg-rules.js.map +1 -0
- package/dist/src/memory/memory-kg-scan.d.ts +118 -0
- package/dist/src/memory/memory-kg-scan.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-scan.js +209 -0
- package/dist/src/memory/memory-kg-scan.js.map +1 -0
- package/dist/src/memory/memory-kg-search.d.ts +80 -0
- package/dist/src/memory/memory-kg-search.d.ts.map +1 -0
- package/dist/src/memory/memory-kg-search.js +239 -0
- package/dist/src/memory/memory-kg-search.js.map +1 -0
- package/dist/src/memory/memory-kg.d.ts +19 -547
- package/dist/src/memory/memory-kg.d.ts.map +1 -1
- package/dist/src/memory/memory-kg.js +10 -2389
- package/dist/src/memory/memory-kg.js.map +1 -1
- package/dist/src/orgrt/sandbox-stubs.d.ts +4 -0
- package/dist/src/orgrt/sandbox-stubs.d.ts.map +1 -1
- package/dist/src/orgrt/sandbox-stubs.js +12 -2
- package/dist/src/orgrt/sandbox-stubs.js.map +1 -1
- package/dist/src/ui/org-hil.mjs +1 -1
- package/dist/src/ui/routes-org-agents.mjs +318 -0
- package/dist/src/ui/routes-org-approvals.mjs +133 -0
- package/dist/src/ui/routes-org-config.mjs +459 -0
- package/dist/src/ui/routes-org-control.mjs +300 -0
- package/dist/src/ui/routes-org-files.mjs +172 -0
- package/dist/src/ui/routes-org-helpers.mjs +84 -0
- package/dist/src/ui/routes-org-knowledge.mjs +262 -0
- package/dist/src/ui/routes-org-lifecycle.mjs +224 -0
- package/dist/src/ui/routes-org-live.mjs +278 -0
- package/dist/src/ui/routes-org-mastermind.mjs +346 -0
- package/dist/src/ui/routes-org-planning.mjs +398 -0
- package/dist/src/ui/routes-org-runs.mjs +430 -0
- package/dist/src/ui/routes-org-status.mjs +342 -0
- package/dist/src/ui/routes-org-workflows.mjs +212 -0
- package/dist/src/ui/routes-org.mjs +26 -3847
- package/dist/src/ui/server.mjs +1 -1
- package/dist/src/utils/native-error.d.ts +1 -1
- package/dist/src/utils/native-error.js +1 -1
- package/dist/src/utils/paths.d.ts +2 -1
- package/dist/src/utils/paths.d.ts.map +1 -1
- package/dist/src/utils/paths.js +2 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/org-skills/adversarial-reviewer/SKILL.md +1 -1
- package/org-skills/board-deck-builder/SKILL.md +1 -1
- package/org-skills/code-reviewer/SKILL.md +1 -1
- package/org-skills/debugging-wizard/SKILL.md +1 -1
- package/org-skills/scientific-thinking-literature-review/SKILL.md +1 -1
- package/org-skills/scientific-thinking-scholar-evaluation/SKILL.md +1 -1
- package/package.json +8 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: coder
|
|
3
3
|
description: Implementation specialist that writes, refactors, and optimizes production code with tests, SOLID design, robust error handling, and monograph-first navigation
|
|
4
|
-
when_to_use: Use when implementing a feature, fixing a bug,
|
|
4
|
+
when_to_use: Use when implementing a feature, fixing a bug, refactoring code to a clear spec, or applying review comments; not for architecture decisions or reviewing code
|
|
5
5
|
tags: [code, implementation, refactoring, tdd]
|
|
6
6
|
category: core
|
|
7
7
|
capability:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: DevOps Automator
|
|
3
3
|
description: Expert DevOps engineer specializing in infrastructure automation, CI/CD pipeline development, and cloud operations
|
|
4
|
-
when_to_use: Use when setting up CI/CD pipelines, infrastructure as code, containers, or
|
|
4
|
+
when_to_use: Use when setting up CI/CD pipelines, infrastructure as code, containers, or automated deploys of apps to the cloud; for GitHub Actions specifically use workflow-automation
|
|
5
5
|
tags: [devops, ci-cd, infrastructure, cloud, automation]
|
|
6
6
|
category: devops
|
|
7
7
|
color: "#f97316"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: repo-architect
|
|
3
3
|
description: Designs a repository's structure — directory layout, templates, and conventions — and recommends improvements for scalable project architecture
|
|
4
|
-
when_to_use: Use when
|
|
4
|
+
when_to_use: Use when laying out or restructuring a repository's directories, templates, and conventions; for rolling changes across many repos use monoswarm-multi-repo
|
|
5
5
|
tags: [github, repository, structure, templates, monorepo]
|
|
6
6
|
category: github
|
|
7
7
|
---
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: production-validator
|
|
3
3
|
description: Production validation specialist ensuring applications are fully implemented and deployment-ready
|
|
4
|
-
when_to_use: Use when verifying an app is fully implemented (no mocks or stubs) and works against real databases, APIs, and infrastructure
|
|
4
|
+
when_to_use: Use when verifying, before a release, that an app is fully implemented (no mocks or stubs) and works against real databases, APIs, and infrastructure; not for deploying it
|
|
5
5
|
tags: [production-readiness, validation, e2e, deployment]
|
|
6
6
|
category: testing
|
|
7
7
|
---
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Tool Evaluator
|
|
3
3
|
description: Technology assessment specialist who evaluates, tests, and recommends tools, software, and platforms for business use
|
|
4
|
-
when_to_use: Use when comparing
|
|
4
|
+
when_to_use: Use when comparing tools, SaaS products, libraries, or platforms, or picking the best of several, and a recommendation is needed
|
|
5
5
|
tags: [evaluation, tools, research, comparison]
|
|
6
6
|
category: specialized
|
|
7
7
|
color: "#14b8a6"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github:pr-manager
|
|
3
|
-
description:
|
|
3
|
+
description: Open, update and merge GitHub pull requests with monomind swarm coordination - multi-reviewer runs, testing, conflict resolution and merge strategies.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# GitHub PR Manager
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
* "pull request". A task that names what a "not for" clause rules out (more
|
|
42
42
|
* than half the words of one of its alternatives, at least one of them a word
|
|
43
43
|
* the item does not otherwise carry) keeps EXCLUDED_FACTOR of its score.
|
|
44
|
+
* A pointer clause "for X use Y" / "For X, see Y" is read the same way: X is
|
|
45
|
+
* work that belongs to Y, and neither X nor Y's name describes this item
|
|
46
|
+
* ("for Node code patterns use backend-patterns" must not match "Node").
|
|
44
47
|
*/
|
|
45
48
|
|
|
46
49
|
var K1 = 1.2;
|
|
@@ -252,6 +255,22 @@ function queryTerms(text) {
|
|
|
252
255
|
var DOC_CLAUSE_SPLIT = /[.;:!?()[\]{}<>|\n\r\u2013\u2014]+|\s-+\s/;
|
|
253
256
|
var DOC_NOT_FOR = /\b(?:not|never)\s+(?:intended\s+|meant\s+)?for\s+(.+)$|\b(?:do\s+not|don't|dont|never)\s+use\s+(?:it\s+|this\s+)?for\s+(.+)$/;
|
|
254
257
|
var DOC_ALTERNATIVES = /,|\s(?:or|and|nor)\s/;
|
|
258
|
+
// "for X use Y" / "for X, see Y": work that belongs to another entry.
|
|
259
|
+
var DOC_REDIRECT = /^\s*for\s+(.+?),?\s+(?:use|see)\s+\S/;
|
|
260
|
+
var DOC_REDIRECT_SPLIT = /,\s*(?:and\s+)?for\s+/;
|
|
261
|
+
|
|
262
|
+
/** The X of each "for X use Y" in a clause made only of such redirects
|
|
263
|
+
* ("for A use B, for C see D"), else null. */
|
|
264
|
+
function redirects(clause) {
|
|
265
|
+
var out = [];
|
|
266
|
+
var parts = clause.split(DOC_REDIRECT_SPLIT);
|
|
267
|
+
for (var i = 0; i < parts.length; i++) {
|
|
268
|
+
var r = DOC_REDIRECT.exec(i ? 'for ' + parts[i] : parts[i]);
|
|
269
|
+
if (!r) return null;
|
|
270
|
+
out.push(r[1]);
|
|
271
|
+
}
|
|
272
|
+
return out;
|
|
273
|
+
}
|
|
255
274
|
|
|
256
275
|
/** A description's own exclusions (see the file header): `kept` is the text
|
|
257
276
|
* without its "not for" clauses, `ruledOut` the word lists of each
|
|
@@ -266,13 +285,24 @@ function docExclusions(description) {
|
|
|
266
285
|
.replace(/\u2019/g, "'")
|
|
267
286
|
.split(DOC_CLAUSE_SPLIT)
|
|
268
287
|
.forEach(function (clause) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
kept.push(clause.slice(0, m.index));
|
|
272
|
-
(m[1] || m[2]).split(DOC_ALTERNATIVES).forEach(function (alt) {
|
|
288
|
+
function ruleOut(text) {
|
|
289
|
+
text.split(DOC_ALTERNATIVES).forEach(function (alt) {
|
|
273
290
|
var t = tokens(alt);
|
|
274
291
|
if (t.length) ruledOut.push(t);
|
|
275
292
|
});
|
|
293
|
+
}
|
|
294
|
+
var alts = redirects(clause);
|
|
295
|
+
if (alts) {
|
|
296
|
+
// The pointer's target is another entry's name: unindexed, but its
|
|
297
|
+
// words stay where this entry's own text (tags) carries them.
|
|
298
|
+
alts.forEach(ruleOut);
|
|
299
|
+
dropped.push(alts.join(' '));
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
var m = DOC_NOT_FOR.exec(clause);
|
|
303
|
+
if (m) {
|
|
304
|
+
kept.push(clause.slice(0, m.index));
|
|
305
|
+
ruleOut(m[1] || m[2]);
|
|
276
306
|
dropped.push(m[1] || m[2]);
|
|
277
307
|
return;
|
|
278
308
|
}
|
|
@@ -6,7 +6,7 @@ description: >
|
|
|
6
6
|
or replace with stdlib/native equivalents. Use when the user says "audit this
|
|
7
7
|
codebase", "audit for over-engineering", "what can I delete from this repo",
|
|
8
8
|
"find bloat", "monolean-audit", or "/monolean-audit". One-shot report, does
|
|
9
|
-
not apply fixes.
|
|
9
|
+
not apply fixes. Not for security or vulnerability audits.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
An over-engineering review, repo-wide. Scan the whole tree instead of a diff.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup — orphaned per-project data pruning (--data): ~/.monomind/projects
|
|
3
|
+
* dirs and ~/.monomind-projects.json registry entries whose project is gone.
|
|
4
|
+
* Extracted from cleanup.ts.
|
|
5
|
+
*/
|
|
6
|
+
import type { StaleScratchItem } from './cleanup-scratch.js';
|
|
7
|
+
/**
|
|
8
|
+
* Entries of the project registry (~/.monomind-projects.json, written by
|
|
9
|
+
* `init` for `init upgrade --all`) whose project was deleted, by the same rule
|
|
10
|
+
* as project-data dirs. Exported for tests; unreadable registry → none.
|
|
11
|
+
*/
|
|
12
|
+
export declare function findStaleRegistryEntries(registryPath: string): string[];
|
|
13
|
+
/** Rewrite the registry without `stale`, re-read first so a concurrent `init` registration survives. */
|
|
14
|
+
export declare function pruneRegistryEntries(registryPath: string, stale: string[]): number;
|
|
15
|
+
/**
|
|
16
|
+
* Find prunable entries under the per-project data base (default
|
|
17
|
+
* ~/.monomind/projects). Exported for tests — `baseDir`/`now` injectable.
|
|
18
|
+
*
|
|
19
|
+
* Classification per dir:
|
|
20
|
+
* - `origin.json` present and its recorded path still exists → keep the dir,
|
|
21
|
+
* but flag a leftover `lancedb/` subdir (dead since the SQLite engine swap).
|
|
22
|
+
* - `origin.json` present, recorded path provably deleted (not merely on an
|
|
23
|
+
* unmounted volume, see {@link isProvablyDeleted}) → orphaned → prune.
|
|
24
|
+
* - no `origin.json` (pre-2.3.1 dirs can't prove their origin) → prune only
|
|
25
|
+
* when untouched for {@link UNKNOWN_DIR_MAX_AGE_MS} — or immediately with
|
|
26
|
+
* `--aggressive`, which treats unprovable dirs as junk (safe: every live
|
|
27
|
+
* project rewrites origin.json on its next memory access).
|
|
28
|
+
*/
|
|
29
|
+
export declare function findOrphanedProjectData(baseDir: string, now: number, aggressive: boolean): StaleScratchItem[];
|
|
30
|
+
//# sourceMappingURL=cleanup-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-data.d.ts","sourceRoot":"","sources":["../../../src/commands/cleanup-data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAM7D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAUvE;AAED,wGAAwG;AACxG,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAUlF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,OAAO,GAClB,gBAAgB,EAAE,CA+EpB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup — orphaned per-project data pruning (--data): ~/.monomind/projects
|
|
3
|
+
* dirs and ~/.monomind-projects.json registry entries whose project is gone.
|
|
4
|
+
* Extracted from cleanup.ts.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, lstatSync, readdirSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { atomicWriteFile } from '../init/fs-helpers.js';
|
|
9
|
+
import { isProvablyDeleted } from './cleanup-origin.js';
|
|
10
|
+
/** Orphaned per-project data (--data): ~/.monomind/projects/<slug> dirs whose
|
|
11
|
+
* source project is gone, plus dead lancedb/ dirs left by the pre-2.3.1 engine. */
|
|
12
|
+
const UNKNOWN_DIR_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000;
|
|
13
|
+
/**
|
|
14
|
+
* Entries of the project registry (~/.monomind-projects.json, written by
|
|
15
|
+
* `init` for `init upgrade --all`) whose project was deleted, by the same rule
|
|
16
|
+
* as project-data dirs. Exported for tests; unreadable registry → none.
|
|
17
|
+
*/
|
|
18
|
+
export function findStaleRegistryEntries(registryPath) {
|
|
19
|
+
try {
|
|
20
|
+
const reg = JSON.parse(readFileSync(registryPath, 'utf-8'));
|
|
21
|
+
if (!Array.isArray(reg.projects))
|
|
22
|
+
return [];
|
|
23
|
+
return reg.projects.filter((p) => typeof p === 'string' && p.length > 0 && isProvablyDeleted(p));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Rewrite the registry without `stale`, re-read first so a concurrent `init` registration survives. */
|
|
30
|
+
export function pruneRegistryEntries(registryPath, stale) {
|
|
31
|
+
const reg = JSON.parse(readFileSync(registryPath, 'utf-8'));
|
|
32
|
+
const drop = new Set(stale);
|
|
33
|
+
const kept = reg.projects.filter((p) => !(typeof p === 'string' && drop.has(p)));
|
|
34
|
+
const removed = reg.projects.length - kept.length;
|
|
35
|
+
if (removed > 0) {
|
|
36
|
+
reg.projects = kept;
|
|
37
|
+
atomicWriteFile(registryPath, JSON.stringify(reg, null, 2), 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
return removed;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Find prunable entries under the per-project data base (default
|
|
43
|
+
* ~/.monomind/projects). Exported for tests — `baseDir`/`now` injectable.
|
|
44
|
+
*
|
|
45
|
+
* Classification per dir:
|
|
46
|
+
* - `origin.json` present and its recorded path still exists → keep the dir,
|
|
47
|
+
* but flag a leftover `lancedb/` subdir (dead since the SQLite engine swap).
|
|
48
|
+
* - `origin.json` present, recorded path provably deleted (not merely on an
|
|
49
|
+
* unmounted volume, see {@link isProvablyDeleted}) → orphaned → prune.
|
|
50
|
+
* - no `origin.json` (pre-2.3.1 dirs can't prove their origin) → prune only
|
|
51
|
+
* when untouched for {@link UNKNOWN_DIR_MAX_AGE_MS} — or immediately with
|
|
52
|
+
* `--aggressive`, which treats unprovable dirs as junk (safe: every live
|
|
53
|
+
* project rewrites origin.json on its next memory access).
|
|
54
|
+
*/
|
|
55
|
+
export function findOrphanedProjectData(baseDir, now, aggressive) {
|
|
56
|
+
const out = [];
|
|
57
|
+
if (!existsSync(baseDir))
|
|
58
|
+
return out;
|
|
59
|
+
for (const name of readdirSync(baseDir)) {
|
|
60
|
+
if (name.startsWith('.'))
|
|
61
|
+
continue;
|
|
62
|
+
const dir = join(baseDir, name);
|
|
63
|
+
try {
|
|
64
|
+
if (!lstatSync(dir).isDirectory())
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Staleness must consider the files writes actually touch: appends to
|
|
71
|
+
// lancedb/memory.db and origin.json refreshes do NOT bump the slug dir's
|
|
72
|
+
// own mtime, so an actively-used project would otherwise look 30d stale.
|
|
73
|
+
const mtimeOf = (p) => {
|
|
74
|
+
try {
|
|
75
|
+
return lstatSync(p).mtimeMs;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const mtime = Math.max(mtimeOf(dir), mtimeOf(join(dir, 'origin.json')), mtimeOf(join(dir, 'lancedb', 'memory.db')), mtimeOf(join(dir, 'memory.db')));
|
|
82
|
+
const originFile = join(dir, 'origin.json');
|
|
83
|
+
let originPath = null;
|
|
84
|
+
let hasOrigin = false;
|
|
85
|
+
try {
|
|
86
|
+
originPath = String(JSON.parse(readFileSync(originFile, 'utf-8')).path ?? '');
|
|
87
|
+
hasOrigin = originPath.length > 0;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
/* no/corrupt marker */
|
|
91
|
+
}
|
|
92
|
+
if (hasOrigin && originPath && existsSync(originPath)) {
|
|
93
|
+
// NOTE: the directory is *named* lancedb for historical reasons, but the
|
|
94
|
+
// current SQLite engine keeps its LIVE memory.db inside it. Only genuine
|
|
95
|
+
// LanceDB leftovers (*.lance datasets, no memory.db) are dead weight.
|
|
96
|
+
const lance = join(dir, 'lancedb');
|
|
97
|
+
if (existsSync(lance) && !existsSync(join(lance, 'memory.db'))) {
|
|
98
|
+
let hasLanceData = false;
|
|
99
|
+
try {
|
|
100
|
+
hasLanceData = readdirSync(lance).some((f) => f.endsWith('.lance') || f === '__manifest');
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* unreadable — leave it */
|
|
104
|
+
}
|
|
105
|
+
if (hasLanceData)
|
|
106
|
+
out.push({
|
|
107
|
+
path: lance,
|
|
108
|
+
description: `dead lancedb store (project: ${originPath})`,
|
|
109
|
+
size: 0,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (hasOrigin && originPath) {
|
|
115
|
+
// An unmounted volume / disconnected network share makes the whole
|
|
116
|
+
// subtree vanish temporarily, and that must never count as "project
|
|
117
|
+
// deleted" — see isProvablyDeleted.
|
|
118
|
+
if (isProvablyDeleted(originPath)) {
|
|
119
|
+
out.push({
|
|
120
|
+
path: dir,
|
|
121
|
+
description: `orphaned project data (origin gone: ${originPath})`,
|
|
122
|
+
size: 0,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else if (aggressive || now - mtime > UNKNOWN_DIR_MAX_AGE_MS) {
|
|
127
|
+
out.push({
|
|
128
|
+
path: dir,
|
|
129
|
+
description: aggressive
|
|
130
|
+
? 'unverifiable project data (no origin marker)'
|
|
131
|
+
: 'unverifiable project data (untouched >30d)',
|
|
132
|
+
size: 0,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=cleanup-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-data.js","sourceRoot":"","sources":["../../../src/commands/cleanup-data.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deleted-vs-unmounted rule for `cleanup --data` (#347): decides whether a
|
|
3
|
+
* recorded project path is gone because it was deleted, or only because the
|
|
4
|
+
* volume holding it is not attached right now.
|
|
5
|
+
*/
|
|
6
|
+
/** The two filesystem questions the rule asks; injectable for tests. */
|
|
7
|
+
export interface OriginFs {
|
|
8
|
+
exists(p: string): boolean;
|
|
9
|
+
/** st_dev of `p`; throws when it cannot be stat-ed. */
|
|
10
|
+
dev(p: string): number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* True when a recorded project path is gone because it was deleted, not
|
|
14
|
+
* because the volume holding it is unmounted. Walks up to the nearest existing
|
|
15
|
+
* ancestor: when that is the path's own parent (the old rule), a well-known
|
|
16
|
+
* local root (home, /tmp, /var/tmp, the OS temp dir — a tmpfs /tmp is a mount,
|
|
17
|
+
* but its children vanishing means deletion) or a directory on the same device
|
|
18
|
+
* as its own parent, the path was deleted — this covers a whole deleted test
|
|
19
|
+
* root. When it is a mount point (`/`, a network share's mount) or a
|
|
20
|
+
* removable-media directory, the missing piece may be a volume that is not
|
|
21
|
+
* attached right now, so the path is kept.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isProvablyDeleted(p: string, fs?: OriginFs, localRoots?: readonly string[]): boolean;
|
|
24
|
+
//# sourceMappingURL=cleanup-origin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-origin.d.ts","sourceRoot":"","sources":["../../../src/commands/cleanup-origin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,wEAAwE;AACxE,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,uDAAuD;IACvD,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,MAAM,EACT,EAAE,GAAE,QAAuB,EAC3B,UAAU,GAAE,SAAS,MAAM,EAAwB,GAClD,OAAO,CAUT"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deleted-vs-unmounted rule for `cleanup --data` (#347): decides whether a
|
|
3
|
+
* recorded project path is gone because it was deleted, or only because the
|
|
4
|
+
* volume holding it is not attached right now.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, realpathSync, statSync } from 'node:fs';
|
|
7
|
+
import { homedir, tmpdir } from 'node:os';
|
|
8
|
+
import { dirname, resolve } from 'node:path';
|
|
9
|
+
const nodeOriginFs = {
|
|
10
|
+
exists: existsSync,
|
|
11
|
+
dev: (p) => statSync(p).dev,
|
|
12
|
+
};
|
|
13
|
+
/** Where removable volumes appear; a missing path under one may just be unplugged. */
|
|
14
|
+
const MEDIA_ROOTS = ['/Volumes', '/media', '/mnt', '/run/media'];
|
|
15
|
+
/** Home, /tmp, /var/tmp and the OS temp dir, as given and with symlinks resolved. */
|
|
16
|
+
function defaultLocalRoots() {
|
|
17
|
+
const roots = new Set();
|
|
18
|
+
for (const r of [homedir(), '/tmp', '/var/tmp', tmpdir()]) {
|
|
19
|
+
roots.add(resolve(r));
|
|
20
|
+
try {
|
|
21
|
+
roots.add(realpathSync(r));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
/* missing root — nothing to add */
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return [...roots];
|
|
28
|
+
}
|
|
29
|
+
function isMountPoint(dir, fs) {
|
|
30
|
+
const parent = dirname(dir);
|
|
31
|
+
if (parent === dir)
|
|
32
|
+
return true; // filesystem root
|
|
33
|
+
try {
|
|
34
|
+
return fs.dev(dir) !== fs.dev(parent);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return true; // cannot tell — stay cautious
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* True when a recorded project path is gone because it was deleted, not
|
|
42
|
+
* because the volume holding it is unmounted. Walks up to the nearest existing
|
|
43
|
+
* ancestor: when that is the path's own parent (the old rule), a well-known
|
|
44
|
+
* local root (home, /tmp, /var/tmp, the OS temp dir — a tmpfs /tmp is a mount,
|
|
45
|
+
* but its children vanishing means deletion) or a directory on the same device
|
|
46
|
+
* as its own parent, the path was deleted — this covers a whole deleted test
|
|
47
|
+
* root. When it is a mount point (`/`, a network share's mount) or a
|
|
48
|
+
* removable-media directory, the missing piece may be a volume that is not
|
|
49
|
+
* attached right now, so the path is kept.
|
|
50
|
+
*/
|
|
51
|
+
export function isProvablyDeleted(p, fs = nodeOriginFs, localRoots = defaultLocalRoots()) {
|
|
52
|
+
const target = resolve(p);
|
|
53
|
+
if (fs.exists(target))
|
|
54
|
+
return false;
|
|
55
|
+
const parent = dirname(target);
|
|
56
|
+
let nearest = parent;
|
|
57
|
+
while (!fs.exists(nearest) && dirname(nearest) !== nearest)
|
|
58
|
+
nearest = dirname(nearest);
|
|
59
|
+
if (nearest === parent)
|
|
60
|
+
return true;
|
|
61
|
+
if (localRoots.includes(nearest))
|
|
62
|
+
return true;
|
|
63
|
+
if (MEDIA_ROOTS.includes(nearest) || MEDIA_ROOTS.includes(dirname(nearest)))
|
|
64
|
+
return false;
|
|
65
|
+
return !isMountPoint(nearest, fs);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=cleanup-origin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-origin.js","sourceRoot":"","sources":["../../../src/commands/cleanup-origin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAS7C,MAAM,YAAY,GAAa;IAC7B,MAAM,EAAE,UAAU;IAClB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG;CAC5B,CAAC;AAEF,sFAAsF;AACtF,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;AAEjE,qFAAqF;AACrF,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAC1D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,EAAY;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;IACnD,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,8BAA8B;IAC7C,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,CAAS,EACT,EAAE,GAAa,YAAY,EAC3B,UAAU,GAAsB,iBAAiB,EAAE;IAEnD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO;QAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvF,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1F,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup — scratch pruning (--scratch): stale taskdev handoff files and
|
|
3
|
+
* abandoned loop state, plus the shared remove/report and size helpers.
|
|
4
|
+
* Extracted from cleanup.ts.
|
|
5
|
+
*/
|
|
6
|
+
/** A single stale-scratch candidate returned by {@link findStaleScratch}. */
|
|
7
|
+
export interface StaleScratchItem {
|
|
8
|
+
path: string;
|
|
9
|
+
description: string;
|
|
10
|
+
size: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Find stale mastermind scratch under `.monomind/taskdev/` and `.monomind/loops/`.
|
|
14
|
+
* Exported for tests. Never returns `progress.md` (the taskdev recovery ledger),
|
|
15
|
+
* directories, or loop JSON it cannot parse — deleting the unclassifiable loses data.
|
|
16
|
+
*
|
|
17
|
+
* A loop JSON is only ever classified as abandoned when it has a real, positive,
|
|
18
|
+
* numeric `nextRunAt` timestamp that is more than a day in the past. Live producers
|
|
19
|
+
* write `nextRunAt: 0` (real /do loops) or `nextRunAt: null` (dashboard) — those,
|
|
20
|
+
* along with missing/non-numeric values, are never eligible for deletion regardless
|
|
21
|
+
* of `status`, since a crashed daemon can leave a stale `status: 'running'` behind.
|
|
22
|
+
*/
|
|
23
|
+
export declare function findStaleScratch(cwd: string, now: number): StaleScratchItem[];
|
|
24
|
+
/**
|
|
25
|
+
* Report (dry run) or delete a batch of file/dir items, printing the same
|
|
26
|
+
* `[would remove]` / `[removed]` / `[failed]` lines used across cleanup modes.
|
|
27
|
+
* Shared by the scratch branch; the main artifact loop keeps its own copy
|
|
28
|
+
* because of the `--keep-config` `.claude/settings.json` preservation special case.
|
|
29
|
+
*/
|
|
30
|
+
export declare function removeOrReport(cwd: string, items: {
|
|
31
|
+
path: string;
|
|
32
|
+
description: string;
|
|
33
|
+
size: number;
|
|
34
|
+
type: 'dir' | 'file';
|
|
35
|
+
}[], dryRun: boolean): {
|
|
36
|
+
removed: number;
|
|
37
|
+
removedSize: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Format bytes into a human-readable string
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatSize(bytes: number): string;
|
|
43
|
+
//# sourceMappingURL=cleanup-scratch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-scratch.d.ts","sourceRoot":"","sources":["../../../src/commands/cleanup-scratch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA6D7E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,EAAE,EAClF,MAAM,EAAE,OAAO,GACd;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAgC1C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup — scratch pruning (--scratch): stale taskdev handoff files and
|
|
3
|
+
* abandoned loop state, plus the shared remove/report and size helpers.
|
|
4
|
+
* Extracted from cleanup.ts.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, lstatSync, readdirSync, readFileSync, rmSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { output } from '../output.js';
|
|
9
|
+
/** Scratch pruning (--scratch): taskdev handoff files and loop state. */
|
|
10
|
+
// monolean: manual flag only — upgrade path: invoke from the `cache` background worker so crashed-run scratch is pruned without anyone remembering the flag
|
|
11
|
+
const SCRATCH_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; // taskdev scratch older than this is stale
|
|
12
|
+
const LOOP_STALE_GRACE_MS = 24 * 60 * 60 * 1000; // a live loop reschedules every <=1h; overdue by a day = abandoned
|
|
13
|
+
/**
|
|
14
|
+
* Find stale mastermind scratch under `.monomind/taskdev/` and `.monomind/loops/`.
|
|
15
|
+
* Exported for tests. Never returns `progress.md` (the taskdev recovery ledger),
|
|
16
|
+
* directories, or loop JSON it cannot parse — deleting the unclassifiable loses data.
|
|
17
|
+
*
|
|
18
|
+
* A loop JSON is only ever classified as abandoned when it has a real, positive,
|
|
19
|
+
* numeric `nextRunAt` timestamp that is more than a day in the past. Live producers
|
|
20
|
+
* write `nextRunAt: 0` (real /do loops) or `nextRunAt: null` (dashboard) — those,
|
|
21
|
+
* along with missing/non-numeric values, are never eligible for deletion regardless
|
|
22
|
+
* of `status`, since a crashed daemon can leave a stale `status: 'running'` behind.
|
|
23
|
+
*/
|
|
24
|
+
export function findStaleScratch(cwd, now) {
|
|
25
|
+
const out = [];
|
|
26
|
+
const taskdevDir = join(cwd, '.monomind', 'taskdev');
|
|
27
|
+
if (existsSync(taskdevDir)) {
|
|
28
|
+
for (const f of readdirSync(taskdevDir)) {
|
|
29
|
+
if (f === 'progress.md')
|
|
30
|
+
continue; // the ledger is the recovery map — never auto-prune
|
|
31
|
+
try {
|
|
32
|
+
const st = lstatSync(join(taskdevDir, f));
|
|
33
|
+
if (st.isFile() && now - st.mtimeMs > SCRATCH_MAX_AGE_MS) {
|
|
34
|
+
out.push({
|
|
35
|
+
path: join('.monomind', 'taskdev', f),
|
|
36
|
+
description: 'stale taskdev scratch',
|
|
37
|
+
size: st.size,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
/* raced away or unreadable — leave it */
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const loopsDir = join(cwd, '.monomind', 'loops');
|
|
47
|
+
if (existsSync(loopsDir)) {
|
|
48
|
+
const entries = readdirSync(loopsDir);
|
|
49
|
+
const jsonStems = new Set(entries.filter((f) => f.endsWith('.json')).map((f) => f.replace(/\.json$/, '')));
|
|
50
|
+
for (const f of entries) {
|
|
51
|
+
try {
|
|
52
|
+
const st = lstatSync(join(loopsDir, f));
|
|
53
|
+
if (!st.isFile())
|
|
54
|
+
continue;
|
|
55
|
+
if (f.endsWith('.json')) {
|
|
56
|
+
const parsed = JSON.parse(readFileSync(join(loopsDir, f), 'utf8'));
|
|
57
|
+
const { nextRunAt } = parsed;
|
|
58
|
+
const isStale = typeof nextRunAt === 'number' &&
|
|
59
|
+
Number.isFinite(nextRunAt) &&
|
|
60
|
+
nextRunAt > 0 &&
|
|
61
|
+
now - nextRunAt > LOOP_STALE_GRACE_MS;
|
|
62
|
+
if (isStale) {
|
|
63
|
+
out.push({
|
|
64
|
+
path: join('.monomind', 'loops', f),
|
|
65
|
+
description: 'abandoned loop state',
|
|
66
|
+
size: st.size,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (f.endsWith('.stop') && !jsonStems.has(f.replace(/\.stop$/, ''))) {
|
|
71
|
+
out.push({
|
|
72
|
+
path: join('.monomind', 'loops', f),
|
|
73
|
+
description: 'orphaned loop stopfile',
|
|
74
|
+
size: st.size,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* unparseable or unreadable — never delete what we cannot classify */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Report (dry run) or delete a batch of file/dir items, printing the same
|
|
87
|
+
* `[would remove]` / `[removed]` / `[failed]` lines used across cleanup modes.
|
|
88
|
+
* Shared by the scratch branch; the main artifact loop keeps its own copy
|
|
89
|
+
* because of the `--keep-config` `.claude/settings.json` preservation special case.
|
|
90
|
+
*/
|
|
91
|
+
export function removeOrReport(cwd, items, dryRun) {
|
|
92
|
+
let removed = 0;
|
|
93
|
+
let removedSize = 0;
|
|
94
|
+
for (const item of items) {
|
|
95
|
+
const sizeStr = formatSize(item.size);
|
|
96
|
+
const typeLabel = item.type === 'dir' ? 'dir ' : 'file';
|
|
97
|
+
if (dryRun) {
|
|
98
|
+
output.writeln(output.warning(` [would remove] ${typeLabel} ${item.path} (${sizeStr}) - ${item.description}`));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
try {
|
|
102
|
+
rmSync(join(cwd, item.path), { recursive: item.type === 'dir', force: true });
|
|
103
|
+
output.writeln(output.success(` [removed] ${typeLabel} ${item.path} (${sizeStr}) - ${item.description}`));
|
|
104
|
+
removed++;
|
|
105
|
+
removedSize += item.size;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
output.writeln(output.error(` [failed] ${typeLabel} ${item.path} - ${err instanceof Error ? err.message : String(err)}`));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { removed, removedSize };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Format bytes into a human-readable string
|
|
116
|
+
*/
|
|
117
|
+
export function formatSize(bytes) {
|
|
118
|
+
if (bytes === 0)
|
|
119
|
+
return '0 B';
|
|
120
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
121
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
|
|
122
|
+
const value = bytes / 1024 ** i;
|
|
123
|
+
return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=cleanup-scratch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-scratch.js","sourceRoot":"","sources":["../../../src/commands/cleanup-scratch.ts"],"names":[],"mappings":"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"}
|