@warpgogol/forge 2.8.0 → 2.8.1
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.md +1 -1
- package/README.md +23 -13
- package/README.uk.md +19 -12
- package/os/adr/adr.module.ts +158 -0
- package/os/adr/frontmatter-io.ts +80 -0
- package/os/adr/handlers/archive.ts +244 -0
- package/os/adr/handlers/implement-stamp.ts +331 -0
- package/os/adr/handlers/list-create.ts +207 -0
- package/os/adr/handlers/validate.test.ts +232 -0
- package/os/adr/handlers/validate.ts +429 -0
- package/os/adr/index.ts +33 -0
- package/os/adr/types.ts +141 -0
- package/os/audit/audit.module.ts +48 -0
- package/os/audit/frontmatter-io.ts +84 -0
- package/os/audit/handlers/archive.ts +239 -0
- package/os/audit/index.ts +23 -0
- package/os/audit/types.ts +29 -0
- package/os/compass/compass.module.ts +186 -0
- package/os/compass/handlers/compass-audit-handler.ts +382 -0
- package/os/compass/handlers/compass-change-summary-handler.ts +272 -0
- package/os/compass/handlers/compass-inventory-handler.ts +294 -0
- package/os/compass/handlers/compass-inventory.ts +521 -0
- package/os/compass/handlers/git-revision.ts +137 -0
- package/os/compass/handlers/resolve-scan-root-workpiece.test.ts +65 -0
- package/os/compass/handlers/resolve-scan-root.ts +79 -0
- package/os/compass/index.ts +33 -0
- package/os/core/core.module.ts +948 -0
- package/os/core/handlers/assets-check.ts +122 -0
- package/os/core/handlers/assets-helpers.ts +174 -0
- package/os/core/handlers/assets-list.ts +99 -0
- package/os/core/handlers/build.ts +155 -0
- package/os/core/handlers/determinism-check.ts +354 -0
- package/os/core/handlers/dev.ts +127 -0
- package/os/core/handlers/invariant-engine.test.ts +681 -0
- package/os/core/handlers/knowledge-compact.ts +248 -0
- package/os/core/handlers/lifecycle-handlers.test.ts +524 -0
- package/os/core/handlers/note-frontmatter-validate.test.ts +93 -0
- package/os/core/handlers/note-link-validate.test.ts +117 -0
- package/os/core/handlers/note-orphan-detect.test.ts +94 -0
- package/os/core/handlers/package-health.test.ts +226 -0
- package/os/core/handlers/package-health.ts +231 -0
- package/os/core/handlers/pinned-check.ts +200 -0
- package/os/core/handlers/pinned-init.ts +333 -0
- package/os/core/handlers/pinned-types.ts +50 -0
- package/os/core/handlers/pinned-validate.ts +301 -0
- package/os/core/handlers/profile-resolve.ts +92 -0
- package/os/core/handlers/release-prepare.ts +294 -0
- package/os/core/handlers/release-publish.ts +211 -0
- package/os/core/handlers/validate.ts +262 -0
- package/os/core/handlers/workspace-deps.ts +55 -0
- package/os/core/index.ts +13 -0
- package/os/exploration/exploration.module.ts +90 -0
- package/os/exploration/frontmatter-io.ts +77 -0
- package/os/exploration/handlers/archive.ts +159 -0
- package/os/exploration/handlers/list.ts +77 -0
- package/os/exploration/handlers/show.ts +107 -0
- package/os/exploration/index.ts +25 -0
- package/os/exploration/types.ts +65 -0
- package/os/mission/handlers/archive.test.ts +391 -0
- package/os/mission/handlers/archive.ts +453 -0
- package/os/mission/index.ts +1 -0
- package/os/mission/mission.module.ts +48 -0
- package/os/mission/types.ts +41 -0
- package/os/naming/index.ts +14 -0
- package/os/naming/naming-convention.test.ts +163 -0
- package/os/naming/naming-convention.ts +378 -0
- package/os/naming/naming.module.ts +36 -0
- package/os/notes/index.ts +10 -0
- package/os/notes/notes.module.ts +109 -0
- package/os/plan/frontmatter-io.ts +82 -0
- package/os/plan/handlers/archive.ts +238 -0
- package/os/plan/index.ts +23 -0
- package/os/plan/plan.module.ts +48 -0
- package/os/plan/types.ts +29 -0
- package/os/program/discovery.ts +294 -0
- package/os/program/handlers/complete.ts +419 -0
- package/os/program/handlers/lease.ts +433 -0
- package/os/program/handlers/seal.ts +332 -0
- package/os/program/handlers/validate.ts +213 -0
- package/os/program/lease.ts +156 -0
- package/os/program/program.module.ts +212 -0
- package/os/program/schemas.ts +218 -0
- package/os/program/state.ts +264 -0
- package/os/rfc/acceptance.ts +344 -0
- package/os/rfc/decision-log.ts +310 -0
- package/os/rfc/dna-trace.ts +280 -0
- package/os/rfc/frontmatter-io.test.ts +132 -0
- package/os/rfc/frontmatter-io.ts +130 -0
- package/os/rfc/handlers/archive.ts +300 -0
- package/os/rfc/handlers/check.ts +238 -0
- package/os/rfc/handlers/implement-stamp.ts +515 -0
- package/os/rfc/handlers/index-graph.ts +237 -0
- package/os/rfc/handlers/lifecycle.test.ts +127 -0
- package/os/rfc/handlers/lifecycle.ts +249 -0
- package/os/rfc/handlers/list-create.ts +296 -0
- package/os/rfc/handlers/pipeline-status.ts +173 -0
- package/os/rfc/handlers/shared.ts +121 -0
- package/os/rfc/handlers/supersede-propose.ts +241 -0
- package/os/rfc/handlers/validate-rules.test.ts +891 -0
- package/os/rfc/handlers/validate-rules.ts +984 -0
- package/os/rfc/handlers/validate.ts +166 -0
- package/os/rfc/handlers.ts +19 -0
- package/os/rfc/index.ts +97 -0
- package/os/rfc/rfc.module.ts +416 -0
- package/os/rfc/types.ts +596 -0
- package/os/rfc/verification-evidence.ts +244 -0
- package/os/session/atif-parser.ts +166 -0
- package/os/session/frontmatter-io.ts +163 -0
- package/os/session/handlers/archive.ts +288 -0
- package/os/session/handlers/list.ts +174 -0
- package/os/session/handlers/save.ts +348 -0
- package/os/session/handlers/validate.ts +250 -0
- package/os/session/index.ts +50 -0
- package/os/session/session.module.ts +126 -0
- package/os/session/types.ts +203 -0
- package/os/spec/live-spec-list-show-validate.test.ts +257 -0
- package/os/spec/live-spec-list.ts +78 -0
- package/os/spec/live-spec-merge.test.ts +261 -0
- package/os/spec/live-spec-merge.ts +413 -0
- package/os/spec/live-spec-show.ts +117 -0
- package/os/spec/live-spec-types.ts +93 -0
- package/os/spec/live-spec-validate.ts +170 -0
- package/os/spec/spec-materialize.ts +390 -0
- package/os/spec/spec-schema.ts +174 -0
- package/os/spec/spec-status.ts +284 -0
- package/os/spec/spec-validate.ts +513 -0
- package/os/spec/spec.module.ts +135 -0
- package/os/werkstatt/handlers/lock.ts +168 -0
- package/os/werkstatt/handlers/schema.ts +47 -0
- package/os/werkstatt/handlers/werkstatt-lock-recover.ts +175 -0
- package/os/werkstatt/handlers/werkstatt-lock-status.ts +73 -0
- package/os/werkstatt/handlers/werkstatt-operation-validate.ts +104 -0
- package/os/werkstatt/index.ts +39 -0
- package/os/werkstatt/werkstatt.module.ts +62 -0
- package/os/workflow/handlers.ts +304 -0
- package/os/workflow/index.ts +28 -0
- package/os/workflow/types.ts +99 -0
- package/os/workflow/workflow.module.ts +54 -0
- package/package.json +3 -3
- package/profiles/godot-csharp.yaml +4 -4
- package/profiles/knowledge-typescript-turborepo.yaml +110 -0
- package/profiles/phaser-turborepo.yaml +5 -5
- package/skills/_shared/fo-session-summary.md +132 -16
- package/skills/fo/fo-add-tests/pbt-guide.md +13 -13
- package/skills/fo/fo-doc-audit/SKILL.md +6 -6
- package/skills/fo/fo-handoff/SKILL.md +5 -0
- package/skills/fo/fo-idea/SKILL.md +1 -1
- package/skills/fo/fo-review/SKILL.md +1 -1
- package/skills/fo/fo-session-retro/SKILL.md +8 -0
- package/skills/fo/fo-session-save/SKILL.md +8 -0
- package/src/cli-output.ts +59 -0
- package/src/config/forge-config.ts +524 -0
- package/src/forge-module.ts +39 -0
- package/src/index.ts +172 -0
- package/src/knowledge/budgets.ts +202 -0
- package/src/knowledge/compact.ts +405 -0
- package/src/knowledge/index.ts +53 -0
- package/src/knowledge/parse.ts +227 -0
- package/src/knowledge/promote.ts +156 -0
- package/src/knowledge/schema.ts +112 -0
- package/src/knowledge/serialize.ts +72 -0
- package/src/migration-adapters/git-utils.ts +71 -0
- package/src/migration-adapters/ignored-files.ts +221 -0
- package/src/migration-adapters/index.ts +21 -0
- package/src/migration-adapters/node-typescript-pnpm/index.ts +189 -0
- package/src/migration-adapters/phaser-pnpm/index.ts +189 -0
- package/src/migration-adapters/registry.ts +61 -0
- package/src/migration-adapters/types.ts +68 -0
- package/src/onboarding/agents-generate.ts +443 -0
- package/src/onboarding/create.ts +427 -0
- package/src/onboarding/doctor.ts +1297 -0
- package/src/onboarding/init.ts +337 -0
- package/src/onboarding/invariant-engine.ts +448 -0
- package/src/onboarding/memory-scaffold.ts +189 -0
- package/src/onboarding/nested-agents-generate.ts +93 -0
- package/src/onboarding/nested-agents-templates.ts +233 -0
- package/src/onboarding/profile-validate.ts +139 -0
- package/src/onboarding/scaffold-project.ts +299 -0
- package/src/onboarding/scaffold.ts +143 -0
- package/src/onboarding/upgrade.ts +558 -0
- package/src/onboarding/workspace-discovery.ts +167 -0
- package/src/profiles/profile-schema.ts +350 -0
- package/src/profiles/stack-profile.ts +188 -0
- package/src/profiles/terminology-utils.ts +36 -0
- package/src/registry.ts +185 -0
- package/src/skill-schema.ts +37 -0
- package/src/tests/acceptance-criteria.test.ts +99 -0
- package/src/tests/adr-implement-stamp.test.ts +368 -0
- package/src/tests/agents-generate-domain.test.ts +317 -0
- package/src/tests/agents-generate.test.ts +458 -0
- package/src/tests/bindings-schema.test.ts +314 -0
- package/src/tests/budgets.test.ts +213 -0
- package/src/tests/cli-output.test.ts +196 -0
- package/src/tests/compact.test.ts +796 -0
- package/src/tests/create.test.ts +289 -0
- package/src/tests/doctor-autonomy.test.ts +98 -0
- package/src/tests/doctor-bindings.test.ts +286 -0
- package/src/tests/doctor-domain.test.ts +113 -0
- package/src/tests/exploration-handlers.test.ts +256 -0
- package/src/tests/fixtures/agents-generate-business-before.txt +288 -0
- package/src/tests/forge-config.test.ts +420 -0
- package/src/tests/fs-atomic.test.ts +96 -0
- package/src/tests/fs.test.ts +103 -0
- package/src/tests/generated-marker.test.ts +161 -0
- package/src/tests/hash.test.ts +37 -0
- package/src/tests/implement-stamp.test.ts +505 -0
- package/src/tests/init-bindings.test.ts +183 -0
- package/src/tests/knowledge-parse.test.ts +307 -0
- package/src/tests/knowledge-pbt.test.ts +164 -0
- package/src/tests/memory-scaffold.test.ts +192 -0
- package/src/tests/migration-adapters.test.ts +480 -0
- package/src/tests/package-files.test.ts +51 -0
- package/src/tests/pinned-check.test.ts +194 -0
- package/src/tests/pinned-init.test.ts +126 -0
- package/src/tests/profile-schema.test.ts +194 -0
- package/src/tests/profile-validate.test.ts +120 -0
- package/src/tests/program-lease.test.ts +245 -0
- package/src/tests/program-paths-extended.test.ts +117 -0
- package/src/tests/program-paths.test.ts +98 -0
- package/src/tests/program-property.test.ts +139 -0
- package/src/tests/program-schemas.test.ts +445 -0
- package/src/tests/program-spec-node.test.ts +250 -0
- package/src/tests/promote.test.ts +481 -0
- package/src/tests/registry.test.ts +73 -0
- package/src/tests/scaffold-project.test.ts +150 -0
- package/src/tests/session-handlers.test.ts +503 -0
- package/src/tests/session-pbt.test.ts +190 -0
- package/src/tests/skill-schema.test.ts +146 -0
- package/src/tests/skill-validate-knowledge.test.ts +26 -0
- package/src/tests/skill-validate.test.ts +254 -0
- package/src/tests/stack-profile.test.ts +217 -0
- package/src/tests/string-utils.test.ts +42 -0
- package/src/tests/upgrade.test.ts +428 -0
- package/src/tests/werkstatt-lock.test.ts +343 -0
- package/src/tests/workspace-discovery-domain.test.ts +112 -0
- package/src/tests/workspace-discovery.test.ts +135 -0
- package/src/types.ts +221 -0
- package/src/utils/fs-atomic.ts +93 -0
- package/src/utils/fs-idempotent.ts +41 -0
- package/src/utils/fs-trash-sync.ts +37 -0
- package/src/utils/fs-trash.ts +24 -0
- package/src/utils/fs.ts +74 -0
- package/src/utils/generated-marker.ts +166 -0
- package/src/utils/hash.ts +19 -0
- package/src/utils/index.ts +29 -0
- package/src/utils/string-utils.ts +19 -0
- package/src/validators/note-frontmatter-validate.ts +142 -0
- package/src/validators/note-link-validate.ts +145 -0
- package/src/validators/note-orphan-detect.ts +146 -0
- package/src/validators/port-validate.ts +97 -0
- package/src/validators/skill-validate.ts +831 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>Command handler for forge.skill.knowledge.compact — wraps pure compaction functions in the kernel command contract (RFC-0662).</purpose>
|
|
4
|
+
<non-goals>
|
|
5
|
+
<item>Do not implement planning logic — that lives in src/knowledge/compact.ts.</item>
|
|
6
|
+
<item>Do not import from @warpgogol/* — os/core may use dynamic imports but this handler stays forge-internal.</item>
|
|
7
|
+
</non-goals>
|
|
8
|
+
</MODULE_CONTRACT>
|
|
9
|
+
<CHANGE_SUMMARY>
|
|
10
|
+
<item>RFC-0662: initial knowledge compaction command handler.</item>
|
|
11
|
+
</CHANGE_SUMMARY>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import type {
|
|
17
|
+
ForgeCommandInput,
|
|
18
|
+
ForgeCommandResult,
|
|
19
|
+
ForgeRuntimeContext,
|
|
20
|
+
} from "../../../src/types.ts";
|
|
21
|
+
import { FORGE_SKILLS, discoverPackSkills } from "../../../src/registry.ts";
|
|
22
|
+
import { loadForgeConfig } from "../../../src/config/forge-config.ts";
|
|
23
|
+
import { resolveForgeRoot } from "../../../src/config/forge-config.ts";
|
|
24
|
+
import {
|
|
25
|
+
planCompaction,
|
|
26
|
+
executeCompaction,
|
|
27
|
+
resolveRetentionDays,
|
|
28
|
+
resolveStaleDays,
|
|
29
|
+
type CompactReport,
|
|
30
|
+
} from "../../../src/knowledge/compact.ts";
|
|
31
|
+
import { parseKnowledgeFile } from "../../../src/knowledge/parse.ts";
|
|
32
|
+
import type { ParsedKnowledgeFile } from "../../../src/knowledge/schema.ts";
|
|
33
|
+
|
|
34
|
+
interface SkillKnowledgeFiles {
|
|
35
|
+
skill: string;
|
|
36
|
+
files: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function discoverSkillKnowledgeFiles(
|
|
40
|
+
workspaceRoot: string,
|
|
41
|
+
skillName: string | undefined,
|
|
42
|
+
all: boolean,
|
|
43
|
+
): SkillKnowledgeFiles[] {
|
|
44
|
+
const result: SkillKnowledgeFiles[] = [];
|
|
45
|
+
const config = loadForgeConfig(workspaceRoot);
|
|
46
|
+
|
|
47
|
+
// Resolve forge root
|
|
48
|
+
let forgeRoot: string;
|
|
49
|
+
try {
|
|
50
|
+
forgeRoot = resolveForgeRoot(workspaceRoot);
|
|
51
|
+
} catch {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Collect forge skills. skill.path is relative to forgeRoot and already
|
|
56
|
+
// includes the "skills/" prefix (see init.ts / skill-validate.ts).
|
|
57
|
+
for (const skill of FORGE_SKILLS) {
|
|
58
|
+
if (skillName && skill.name !== skillName) continue;
|
|
59
|
+
if (!skill.knowledge || skill.knowledge.length === 0) continue;
|
|
60
|
+
|
|
61
|
+
const skillDir = path.dirname(path.join(forgeRoot, skill.path));
|
|
62
|
+
const files = skill.knowledge
|
|
63
|
+
.map((f) => path.join(skillDir, f))
|
|
64
|
+
.filter((f) => {
|
|
65
|
+
try {
|
|
66
|
+
return fs.existsSync(f);
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (files.length > 0) {
|
|
73
|
+
result.push({ skill: skill.name, files });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Collect pack skills if --all or if --skill matches a pack skill
|
|
78
|
+
if (all || (skillName && !result.some((r) => r.skill === skillName))) {
|
|
79
|
+
const packSkills = discoverPackSkills(workspaceRoot, config);
|
|
80
|
+
for (const skill of packSkills) {
|
|
81
|
+
if (skillName && skill.name !== skillName) continue;
|
|
82
|
+
if (!skill.knowledge || skill.knowledge.length === 0) continue;
|
|
83
|
+
|
|
84
|
+
const packDir = path.resolve(workspaceRoot, skill.dir);
|
|
85
|
+
const skillDir = path.dirname(path.join(packDir, skill.path));
|
|
86
|
+
const files = skill.knowledge
|
|
87
|
+
.map((f) => path.join(skillDir, f))
|
|
88
|
+
.filter((f) => {
|
|
89
|
+
try {
|
|
90
|
+
return fs.existsSync(f);
|
|
91
|
+
} catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (files.length > 0) {
|
|
97
|
+
result.push({ skill: skill.name, files });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function runKnowledgeCompact(
|
|
106
|
+
input: ForgeCommandInput,
|
|
107
|
+
context: ForgeRuntimeContext,
|
|
108
|
+
): Promise<ForgeCommandResult<CompactReport>> {
|
|
109
|
+
const { flags } = input;
|
|
110
|
+
const skillName = typeof flags["skill"] === "string" ? flags["skill"] : undefined;
|
|
111
|
+
// --all is consumed by the site-kernel CLI (consumeCommonFlags) before the
|
|
112
|
+
// command runs, so the command-level switch is --all-skills.
|
|
113
|
+
const all = flags["all-skills"] === true;
|
|
114
|
+
const dryRun = context.dryRun || flags["dry-run"] === true;
|
|
115
|
+
const json = flags["json"] === true;
|
|
116
|
+
|
|
117
|
+
// Validate exactly one of --skill / --all
|
|
118
|
+
if (!skillName && !all) {
|
|
119
|
+
return {
|
|
120
|
+
data: {
|
|
121
|
+
command: "forge.skill.knowledge.compact",
|
|
122
|
+
status: "fail",
|
|
123
|
+
dryRun,
|
|
124
|
+
files: [],
|
|
125
|
+
totals: { archived: 0, markedStale: 0, legacyFiles: 0 },
|
|
126
|
+
errors: ["Exactly one of --skill <name> or --all-skills is required."],
|
|
127
|
+
},
|
|
128
|
+
exitCode: 1,
|
|
129
|
+
summary: "Error: --skill or --all-skills is required.",
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (skillName && all) {
|
|
134
|
+
return {
|
|
135
|
+
data: {
|
|
136
|
+
command: "forge.skill.knowledge.compact",
|
|
137
|
+
status: "fail",
|
|
138
|
+
dryRun,
|
|
139
|
+
files: [],
|
|
140
|
+
totals: { archived: 0, markedStale: 0, legacyFiles: 0 },
|
|
141
|
+
errors: ["--skill and --all-skills are mutually exclusive."],
|
|
142
|
+
},
|
|
143
|
+
exitCode: 1,
|
|
144
|
+
summary: "Error: --skill and --all-skills are mutually exclusive.",
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Resolve retention and stale days
|
|
149
|
+
const flagRetention =
|
|
150
|
+
typeof flags["retention-days"] === "string" ? Number(flags["retention-days"]) : undefined;
|
|
151
|
+
const flagStale =
|
|
152
|
+
typeof flags["stale-days"] === "string" ? Number(flags["stale-days"]) : undefined;
|
|
153
|
+
|
|
154
|
+
const retentionDays =
|
|
155
|
+
flagRetention !== undefined && flagRetention > 0 && Number.isInteger(flagRetention)
|
|
156
|
+
? flagRetention
|
|
157
|
+
: resolveRetentionDays(context.workspaceRoot);
|
|
158
|
+
const staleDays =
|
|
159
|
+
flagStale !== undefined && flagStale > 0 && Number.isInteger(flagStale)
|
|
160
|
+
? flagStale
|
|
161
|
+
: resolveStaleDays(context.workspaceRoot);
|
|
162
|
+
|
|
163
|
+
// Discover target skills and their knowledge files
|
|
164
|
+
const skillFiles = discoverSkillKnowledgeFiles(context.workspaceRoot, skillName, all);
|
|
165
|
+
|
|
166
|
+
if (skillFiles.length === 0) {
|
|
167
|
+
const summary = skillName
|
|
168
|
+
? `Skill "${skillName}" has no knowledge files to compact.`
|
|
169
|
+
: "No skills with knowledge files found.";
|
|
170
|
+
return {
|
|
171
|
+
data: {
|
|
172
|
+
command: "forge.skill.knowledge.compact",
|
|
173
|
+
status: "pass",
|
|
174
|
+
dryRun,
|
|
175
|
+
files: [],
|
|
176
|
+
totals: { archived: 0, markedStale: 0, legacyFiles: 0 },
|
|
177
|
+
},
|
|
178
|
+
exitCode: 0,
|
|
179
|
+
summary,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Parse all knowledge files
|
|
184
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
185
|
+
const allParsed: ParsedKnowledgeFile[] = [];
|
|
186
|
+
const fileToSkill = new Map<string, string>();
|
|
187
|
+
|
|
188
|
+
for (const { skill, files } of skillFiles) {
|
|
189
|
+
for (const file of files) {
|
|
190
|
+
const parsed = parseKnowledgeFile(file);
|
|
191
|
+
allParsed.push(parsed);
|
|
192
|
+
fileToSkill.set(file, skill);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Plan compaction
|
|
197
|
+
const plans = planCompaction(allParsed, { retentionDays, staleDays, today });
|
|
198
|
+
|
|
199
|
+
// Execute compaction
|
|
200
|
+
const report = executeCompaction(plans, dryRun);
|
|
201
|
+
|
|
202
|
+
// Group by skill for output
|
|
203
|
+
const skillsOutput = skillFiles.map(({ skill, files }) => {
|
|
204
|
+
const skillFileResults = report.files.filter((r) => files.includes(r.file));
|
|
205
|
+
return {
|
|
206
|
+
skill,
|
|
207
|
+
files: skillFileResults.map((r) => ({
|
|
208
|
+
file: path.basename(r.file),
|
|
209
|
+
actions: r.actions,
|
|
210
|
+
legacySectionCount: r.legacySectionCount,
|
|
211
|
+
})),
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const groupedReport = {
|
|
216
|
+
...report,
|
|
217
|
+
skills: skillsOutput,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const exitCode = report.status === "pass" ? 0 : 1;
|
|
221
|
+
const summary = dryRun
|
|
222
|
+
? `[dry-run] forge.skill.knowledge.compact: ${report.totals.archived} would archive, ${report.totals.markedStale} would mark stale, ${report.totals.legacyFiles} legacy file(s)`
|
|
223
|
+
: `forge.skill.knowledge.compact: ${report.totals.archived} archived, ${report.totals.markedStale} marked stale, ${report.totals.legacyFiles} legacy file(s)`;
|
|
224
|
+
|
|
225
|
+
if (context.outputFormat === "pretty" && !json) {
|
|
226
|
+
context.logger.section("Knowledge Compaction");
|
|
227
|
+
for (const skill of skillsOutput) {
|
|
228
|
+
context.logger.info(`Skill: ${skill.skill}`);
|
|
229
|
+
for (const file of skill.files) {
|
|
230
|
+
context.logger.info(
|
|
231
|
+
` ${file.file}: ${file.actions.length} action(s), ${file.legacySectionCount} legacy section(s)`,
|
|
232
|
+
);
|
|
233
|
+
for (const action of file.actions) {
|
|
234
|
+
context.logger.info(` ${action.kind}: ${action.entryId} — ${action.reason}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
context.logger.info(
|
|
239
|
+
`Totals: ${report.totals.archived} archived, ${report.totals.markedStale} marked stale, ${report.totals.legacyFiles} legacy file(s)`,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
data: groupedReport,
|
|
245
|
+
exitCode,
|
|
246
|
+
summary,
|
|
247
|
+
};
|
|
248
|
+
}
|