@warpgogol/forge 4.0.0 → 4.1.2

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.
Files changed (46) hide show
  1. package/AGENTS.md +18 -3
  2. package/bin/cli.ts +15 -8
  3. package/os/adr/adr.module.ts +24 -23
  4. package/os/adr/index.ts +1 -1
  5. package/os/audit/audit.module.ts +13 -8
  6. package/os/audit/index.ts +1 -1
  7. package/os/compass/compass.module.ts +22 -19
  8. package/os/core/core.module.ts +842 -864
  9. package/os/core/handlers/package-health.ts +20 -0
  10. package/os/core/index.ts +1 -1
  11. package/os/exploration/exploration.module.ts +19 -16
  12. package/os/exploration/index.ts +2 -2
  13. package/os/mission/index.ts +1 -1
  14. package/os/mission/mission.module.ts +13 -8
  15. package/os/naming/index.ts +1 -1
  16. package/os/naming/naming-convention.ts +1 -0
  17. package/os/naming/naming.module.ts +13 -7
  18. package/os/notes/index.ts +2 -2
  19. package/os/notes/notes.module.ts +20 -17
  20. package/os/plan/index.ts +1 -1
  21. package/os/plan/plan.module.ts +13 -8
  22. package/os/plugin/plugin.module.ts +10 -8
  23. package/os/program/program.module.ts +22 -20
  24. package/os/rfc/handlers/implement-stamp.ts +17 -1
  25. package/os/rfc/index.ts +1 -1
  26. package/os/rfc/rfc-0000-template.md +3 -2
  27. package/os/rfc/rfc.module.ts +54 -84
  28. package/os/rfc/types.ts +1 -0
  29. package/os/session/handlers/metrics-aggregate.ts +208 -0
  30. package/os/session/handlers/metrics-rfc.ts +339 -0
  31. package/os/session/handlers/metrics-session.ts +209 -0
  32. package/os/session/handlers/save.ts +19 -0
  33. package/os/session/index.ts +16 -1
  34. package/os/session/session.module.ts +133 -107
  35. package/os/session/types.ts +99 -0
  36. package/os/spec/spec.module.ts +28 -29
  37. package/os/werkstatt/werkstatt.module.ts +12 -9
  38. package/os/workflow/index.ts +1 -1
  39. package/os/workflow/workflow.module.ts +18 -12
  40. package/package.json +3 -1
  41. package/src/forge-module.ts +24 -10
  42. package/src/index.ts +12 -12
  43. package/src/onboarding/scaffold.ts +6 -4
  44. package/src/tests/metrics-rfc-1053.test.ts +355 -0
  45. package/src/types/werkstatt-engine-shims.d.ts +126 -48
  46. package/src/types/werkstatt-shared-shims.d.ts +6 -0
@@ -7,123 +7,149 @@
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
9
  <item>RFC-0537: initial forgeSessionModule registering session.save, session.archive, session.validate, session.list commands.</item>
10
+ <item>RFC-1053: register metrics.aggregate command for skill effectiveness metrics aggregation.</item>
10
11
  </CHANGE_SUMMARY>
11
12
  */
12
13
 
13
14
  import type { ForgeModule } from "../../src/forge-module.ts";
14
15
 
15
- export const forgeSessionModule: ForgeModule = {
16
- name: "forge-session",
17
- version: "0.1.0",
18
- runtime: "autonomous",
19
- async register(registry) {
20
- const { runSessionSave } = await import("./handlers/save.ts");
21
- const { runSessionArchive } = await import("./handlers/archive.ts");
22
- const { runSessionValidate } = await import("./handlers/validate.ts");
23
- const { runSessionList } = await import("./handlers/list.ts");
24
-
25
- registry.registerCommand({
26
- name: "session.save",
27
- description:
28
- "Convert raw ATIF files from docs/sessions/.raw/ to structured markdown " +
29
- "in docs/sessions/ with auto-extracted metadata. Idempotent — same raw " +
30
- "file always produces the same output filename. Deletes raw file after " +
31
- "conversion unless --keep-raw. Use --raw-file to process a specific file.",
32
- scope: "workspace",
33
- mutatesState: true,
34
- writes: ["docs/sessions/*.md"],
35
- reads: ["docs/sessions/.raw/*"],
36
- cacheable: false,
37
- flags: {
38
- "raw-file": {
39
- kind: "string",
40
- description: "Process a specific raw file instead of scanning .raw/.",
41
- },
42
- "keep-raw": {
43
- kind: "boolean",
44
- description: "Do not delete raw file after conversion.",
45
- },
46
- "dry-run": {
47
- kind: "boolean",
48
- description: "Preview without writing files.",
16
+ export async function createForgeSessionModule(): Promise<ForgeModule> {
17
+ const { runSessionSave } = await import("./handlers/save.ts");
18
+ const { runSessionArchive } = await import("./handlers/archive.ts");
19
+ const { runSessionValidate } = await import("./handlers/validate.ts");
20
+ const { runSessionList } = await import("./handlers/list.ts");
21
+ const { runMetricsAggregate } = await import("./handlers/metrics-aggregate.ts");
22
+ return {
23
+ name: "forge-session",
24
+ version: "0.1.0",
25
+ runtime: "autonomous",
26
+ declarations: [],
27
+ commands: [
28
+ {
29
+ name: "session.save",
30
+ description:
31
+ "Convert raw ATIF files from docs/sessions/.raw/ to structured markdown " +
32
+ "in docs/sessions/ with auto-extracted metadata. Idempotent same raw " +
33
+ "file always produces the same output filename. Deletes raw file after " +
34
+ "conversion unless --keep-raw. Use --raw-file to process a specific file.",
35
+ scope: "workspace",
36
+ mutatesState: true,
37
+ writes: ["docs/sessions/*.md"],
38
+ reads: ["docs/sessions/.raw/*"],
39
+ cacheable: false,
40
+ flags: {
41
+ "raw-file": {
42
+ kind: "string",
43
+ description: "Process a specific raw file instead of scanning .raw/.",
44
+ },
45
+ "keep-raw": {
46
+ kind: "boolean",
47
+ description: "Do not delete raw file after conversion.",
48
+ },
49
+ "dry-run": {
50
+ kind: "boolean",
51
+ description: "Preview without writing files.",
52
+ },
49
53
  },
54
+ execute: runSessionSave,
50
55
  },
51
- execute: runSessionSave,
52
- });
53
-
54
- registry.registerCommand({
55
- name: "session.archive",
56
- description:
57
- "Move session files older than --max-age-days (default 7) from " +
58
- "docs/sessions/ to docs/sessions/archive/. Bidirectional: files in " +
59
- "archive/ younger than threshold are moved back to docs/sessions/. " +
60
- "Use --dry-run to preview. Age is computed from frontmatter date, " +
61
- "not filesystem mtime. Prefer the docs.archive umbrella command " +
62
- "unless you need to archive only sessions.",
63
- scope: "workspace",
64
- mutatesState: true,
65
- writes: ["docs/sessions/*.md", "docs/sessions/archive/**"],
66
- reads: ["docs/sessions/**/*.md"],
67
- cacheable: false,
68
- flags: {
69
- "max-age-days": {
70
- kind: "string",
71
- description: "Age threshold in days (default 7).",
72
- },
73
- "dry-run": {
74
- kind: "boolean",
75
- description: "Preview what would be moved without touching the filesystem.",
56
+ {
57
+ name: "session.archive",
58
+ description:
59
+ "Move session files older than --max-age-days (default 7) from " +
60
+ "docs/sessions/ to docs/sessions/archive/. Bidirectional: files in " +
61
+ "archive/ younger than threshold are moved back to docs/sessions/. " +
62
+ "Use --dry-run to preview. Age is computed from frontmatter date, " +
63
+ "not filesystem mtime. Prefer the docs.archive umbrella command " +
64
+ "unless you need to archive only sessions.",
65
+ scope: "workspace",
66
+ mutatesState: true,
67
+ writes: ["docs/sessions/*.md", "docs/sessions/archive/**"],
68
+ reads: ["docs/sessions/**/*.md"],
69
+ cacheable: false,
70
+ flags: {
71
+ "max-age-days": {
72
+ kind: "string",
73
+ description: "Age threshold in days (default 7).",
74
+ },
75
+ "dry-run": {
76
+ kind: "boolean",
77
+ description: "Preview what would be moved without touching the filesystem.",
78
+ },
76
79
  },
80
+ execute: runSessionArchive,
77
81
  },
78
- execute: runSessionArchive,
79
- });
80
-
81
- registry.registerCommand({
82
- name: "session.validate",
83
- contract: "session",
84
- rules: [],
85
- description:
86
- "Validate session frontmatter schema (SES-01), id-filename match (SES-02), " +
87
- "RFC-id existence (SES-03), raw file hygiene (SES-04), and non-markdown " +
88
- "file detection (SES-05). Pass --id to validate a single file, " +
89
- "or run without arguments for all. On-demand only — not integrated into " +
90
- "build.check.",
91
- scope: "workspace",
92
- flags: {
93
- id: { kind: "string", description: "Target a single session by id." },
94
- },
95
- reads: ["docs/sessions/**/*.md", "docs/rfcs/**/*.md"],
96
- execute: runSessionValidate,
97
- });
98
-
99
- registry.registerCommand({
100
- name: "session.list",
101
- description:
102
- "List all sessions. Filter with --date-from, --date-to, --rfc, --type flags. " +
103
- "Use --json for machine-readable output. Parses frontmatter on the fly. " +
104
- "Includes archived sessions (marked with archived: true).",
105
- scope: "workspace",
106
- flags: {
107
- "date-from": {
108
- kind: "string",
109
- description: "Filter sessions from this date (YYYY-MM-DD, inclusive).",
110
- },
111
- "date-to": {
112
- kind: "string",
113
- description: "Filter sessions up to this date (YYYY-MM-DD, inclusive).",
82
+ {
83
+ name: "session.validate",
84
+ contract: "session",
85
+ rules: [],
86
+ description:
87
+ "Validate session frontmatter schema (SES-01), id-filename match (SES-02), " +
88
+ "RFC-id existence (SES-03), raw file hygiene (SES-04), and non-markdown " +
89
+ "file detection (SES-05). Pass --id to validate a single file, " +
90
+ "or run without arguments for all. On-demand only not integrated into " +
91
+ "build.check.",
92
+ scope: "workspace",
93
+ flags: {
94
+ id: { kind: "string", description: "Target a single session by id." },
114
95
  },
115
- rfc: {
116
- kind: "string",
117
- description: "Filter by related RFC id (e.g. RFC-0537).",
96
+ reads: ["docs/sessions/**/*.md", "docs/rfcs/**/*.md"],
97
+ execute: runSessionValidate,
98
+ },
99
+ {
100
+ name: "session.list",
101
+ description:
102
+ "List all sessions. Filter with --date-from, --date-to, --rfc, --type flags. " +
103
+ "Use --json for machine-readable output. Parses frontmatter on the fly. " +
104
+ "Includes archived sessions (marked with archived: true).",
105
+ scope: "workspace",
106
+ flags: {
107
+ "date-from": {
108
+ kind: "string",
109
+ description: "Filter sessions from this date (YYYY-MM-DD, inclusive).",
110
+ },
111
+ "date-to": {
112
+ kind: "string",
113
+ description: "Filter sessions up to this date (YYYY-MM-DD, inclusive).",
114
+ },
115
+ rfc: {
116
+ kind: "string",
117
+ description: "Filter by related RFC id (e.g. RFC-0537).",
118
+ },
119
+ type: {
120
+ kind: "string",
121
+ description:
122
+ "Filter by session type (mission, grilling, implementation, review, fix, freeform).",
123
+ },
118
124
  },
119
- type: {
120
- kind: "string",
121
- description:
122
- "Filter by session type (mission, grilling, implementation, review, fix, freeform).",
125
+ reads: ["docs/sessions/**/*.md"],
126
+ execute: runSessionList,
127
+ },
128
+ {
129
+ name: "metrics.aggregate",
130
+ description:
131
+ "Query and aggregate skill effectiveness metrics from docs/metrics/ files. " +
132
+ "Returns per-skill statistics (invocations, avgFindings, avgFixIterations, avgDurationMs). " +
133
+ "Use --skill to filter by skill name, --since/--until for date range.",
134
+ scope: "workspace",
135
+ flags: {
136
+ skill: {
137
+ kind: "string",
138
+ description: "Filter by skill name (e.g. fo-review).",
139
+ },
140
+ since: {
141
+ kind: "string",
142
+ description: "Only include metrics generated since this date (YYYY-MM-DD).",
143
+ },
144
+ until: {
145
+ kind: "string",
146
+ description: "Only include metrics generated until this date (YYYY-MM-DD).",
147
+ },
123
148
  },
149
+ reads: ["docs/metrics/**/*.yaml"],
150
+ execute: runMetricsAggregate,
124
151
  },
125
- reads: ["docs/sessions/**/*.md"],
126
- execute: runSessionList,
127
- });
128
- },
129
- };
152
+ ],
153
+ pipelines: [],
154
+ };
155
+ }
@@ -12,12 +12,14 @@ validation rule identifiers.
12
12
  <CHANGE_SUMMARY>
13
13
  <item>RFC-0537: initial session domain types, constants, and SES rule identifiers.</item>
14
14
  <item>RFC-0884: add checkpoint interfaces, extend SessionFrontmatter with optional checkpoint fields, add SES-06 rule.</item>
15
+ <item>RFC-1053: add metrics type interfaces (RfcMetrics, SessionMetrics, MetricsAggregateResult) and METRICS_DIR constant.</item>
15
16
  </CHANGE_SUMMARY>
16
17
  */
17
18
 
18
19
  export const SESSION_DIR = "docs/sessions";
19
20
  export const SESSION_RAW_SUBDIR = ".raw";
20
21
  export const SESSION_ARCHIVE_SUBDIR = "archive";
22
+ export const METRICS_DIR = "docs/metrics";
21
23
  export const SESSION_ID_PATTERN = /^\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-[0-9a-f]{6}$/;
22
24
  export const SESSION_FILE_PATTERN = /^\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-[0-9a-f]{6}\.md$/;
23
25
 
@@ -133,6 +135,7 @@ export interface SessionSaveResult {
133
135
  files: string[];
134
136
  commands: string[];
135
137
  };
138
+ metricsPath?: string;
136
139
  dryRun: boolean;
137
140
  }
138
141
 
@@ -201,3 +204,99 @@ export interface SessionListResult {
201
204
  sessions: SessionListEntry[];
202
205
  count: number;
203
206
  }
207
+
208
+ // ── RFC-1053: Skill effectiveness metrics ──
209
+
210
+ export interface RfcPipelineStep {
211
+ step: string;
212
+ skill: string | null;
213
+ commitSha: string | null;
214
+ timestamp: string | null;
215
+ }
216
+
217
+ export interface ReviewMetrics {
218
+ findingsCount: number;
219
+ findingsByAxis: Record<string, number>;
220
+ verdict: string | null;
221
+ }
222
+
223
+ export interface FixMetrics {
224
+ fixesApplied: number;
225
+ commitSha: string | null;
226
+ iterations: number;
227
+ }
228
+
229
+ export interface VerificationMetrics {
230
+ probesTotal: number;
231
+ probesPassed: number;
232
+ evidencePath: string | null;
233
+ }
234
+
235
+ export interface ResultMetrics {
236
+ acceptanceCriteriaTotal: number;
237
+ acceptanceCriteriaMet: number;
238
+ }
239
+
240
+ export interface RfcTimings {
241
+ firstCommitAt: string | null;
242
+ lastCommitAt: string | null;
243
+ totalDurationMs: number | null;
244
+ }
245
+
246
+ export interface RfcMetrics {
247
+ rfcId: string;
248
+ generatedAt: string;
249
+ pipeline: RfcPipelineStep[];
250
+ review: ReviewMetrics | null;
251
+ fix: FixMetrics | null;
252
+ verification: VerificationMetrics | null;
253
+ result: ResultMetrics;
254
+ timings: RfcTimings;
255
+ }
256
+
257
+ export interface SessionDocumentRef {
258
+ rfcId: string;
259
+ status: string;
260
+ metricsFile: string | null;
261
+ }
262
+
263
+ export interface SessionSkillInvocation {
264
+ skill: string;
265
+ approximateDurationMs: number | null;
266
+ }
267
+
268
+ export interface InsightSummary {
269
+ total: number;
270
+ byCategory: Record<string, number>;
271
+ }
272
+
273
+ export interface SessionMetrics {
274
+ sessionId: string;
275
+ generatedAt: string;
276
+ date: string;
277
+ durationMs: number;
278
+ approximateDurations: true;
279
+ documents: SessionDocumentRef[];
280
+ skills: SessionSkillInvocation[];
281
+ insights: InsightSummary | null;
282
+ commits: string[];
283
+ }
284
+
285
+ export interface SkillAggregate {
286
+ skill: string;
287
+ invocations: number;
288
+ avgFindings: number | null;
289
+ avgFixIterations: number | null;
290
+ avgDurationMs: number | null;
291
+ }
292
+
293
+ export interface MetricsAggregateResult {
294
+ command: "metrics.aggregate";
295
+ status: "ok";
296
+ skill: string | "all";
297
+ since: string | null;
298
+ until: string | null;
299
+ perSkill: SkillAggregate[];
300
+ totalRfcs: number;
301
+ totalSessions: number;
302
+ }
@@ -14,20 +14,21 @@
14
14
 
15
15
  import type { ForgeModule } from "../../src/forge-module.ts";
16
16
 
17
- export const forgeSpecModule: ForgeModule = {
18
- name: "forge-spec",
19
- version: "0.2.0",
20
- runtime: "autonomous",
21
- async register(registry) {
22
- const { runSpecValidate } = await import("./spec-validate.ts");
17
+ export async function createForgeSpecModule(): Promise<ForgeModule> {
18
+ const { runSpecValidate } = await import("./spec-validate.ts");
23
19
  const { runSpecStatus } = await import("./spec-status.ts");
24
20
  const { runSpecMaterialize } = await import("./spec-materialize.ts");
25
21
  const { runSpecLiveMerge } = await import("./live-spec-merge.ts");
26
22
  const { runSpecLiveList } = await import("./live-spec-list.ts");
27
23
  const { runSpecLiveShow } = await import("./live-spec-show.ts");
28
24
  const { runSpecLiveValidate } = await import("./live-spec-validate.ts");
29
-
30
- registry.registerCommand({
25
+ return {
26
+ name: "forge-spec",
27
+ version: "0.2.0",
28
+ runtime: "autonomous",
29
+ declarations: [],
30
+ commands: [
31
+ {
31
32
  name: "spec.validate",
32
33
  contract: "spec",
33
34
  rules: [],
@@ -45,9 +46,8 @@ export const forgeSpecModule: ForgeModule = {
45
46
  },
46
47
  reads: ["docs/specs/**/*"],
47
48
  execute: runSpecValidate,
48
- });
49
-
50
- registry.registerCommand({
49
+ },
50
+ {
51
51
  name: "spec.status",
52
52
  description:
53
53
  "Show roadmap progress for vendored specs. " +
@@ -61,9 +61,8 @@ export const forgeSpecModule: ForgeModule = {
61
61
  },
62
62
  reads: ["docs/specs/**/*", "docs/rfcs/**/*.md"],
63
63
  execute: runSpecStatus,
64
- });
65
-
66
- registry.registerCommand({
64
+ },
65
+ {
67
66
  name: "spec.materialize",
68
67
  description:
69
68
  "Scaffold RFC files for the next N front nodes of a spec roadmap. " +
@@ -78,9 +77,8 @@ export const forgeSpecModule: ForgeModule = {
78
77
  nodes: { kind: "string", description: "Comma-separated explicit node ids to materialize." },
79
78
  },
80
79
  execute: runSpecMaterialize,
81
- });
82
-
83
- registry.registerCommand({
80
+ },
81
+ {
84
82
  name: "spec.live.merge",
85
83
  description:
86
84
  "Merge deltas from an implemented RFC's ## Design section into a living feature spec " +
@@ -98,9 +96,8 @@ export const forgeSpecModule: ForgeModule = {
98
96
  "dry-run": { kind: "boolean", description: "Preview deltas without writing files." },
99
97
  },
100
98
  execute: runSpecLiveMerge,
101
- });
102
-
103
- registry.registerCommand({
99
+ },
100
+ {
104
101
  name: "spec.live.list",
105
102
  description:
106
103
  "List all living feature specs in docs/specs/live/. " +
@@ -108,9 +105,8 @@ export const forgeSpecModule: ForgeModule = {
108
105
  scope: "workspace",
109
106
  reads: ["docs/specs/live/*.md"],
110
107
  execute: runSpecLiveList,
111
- });
112
-
113
- registry.registerCommand({
108
+ },
109
+ {
114
110
  name: "spec.live.show",
115
111
  description:
116
112
  "Show a single living feature spec by domain. " +
@@ -121,9 +117,8 @@ export const forgeSpecModule: ForgeModule = {
121
117
  domain: { kind: "string", required: true, description: "Domain name (filename without .md)." },
122
118
  },
123
119
  execute: runSpecLiveShow,
124
- });
125
-
126
- registry.registerCommand({
120
+ },
121
+ {
127
122
  name: "spec.live.validate",
128
123
  contract: "spec",
129
124
  rules: [],
@@ -135,6 +130,10 @@ export const forgeSpecModule: ForgeModule = {
135
130
  scope: "workspace",
136
131
  reads: ["docs/specs/live/*.md", "docs/rfcs/**/*.md"],
137
132
  execute: runSpecLiveValidate,
138
- });
139
- },
140
- };
133
+ }
134
+ ],
135
+ pipelines: [
136
+
137
+ ]};
138
+ }
139
+ ;
@@ -20,8 +20,9 @@ export const forgeWerkstattModule: ForgeModule = {
20
20
  name: "forge-werkstatt",
21
21
  version: "0.1.0",
22
22
  runtime: "werkstatt-adapter",
23
- async register(registry) {
24
- registry.registerCommand({
23
+ declarations: [],
24
+ commands: [
25
+ {
25
26
  name: "werkstatt.lock.status",
26
27
  description: "Report all Werkstatt locks, their age, owner, and staleness (RFC-0362).",
27
28
  scope: "workspace",
@@ -29,8 +30,8 @@ export const forgeWerkstattModule: ForgeModule = {
29
30
  flags: {},
30
31
  reads: [".werkstatt/locks/**"],
31
32
  execute: runWerkstattLockStatus,
32
- });
33
- registry.registerCommand({
33
+ },
34
+ {
34
35
  name: "werkstatt.lock.recover",
35
36
  description:
36
37
  "Classify and clean stale locks and staging artifacts (RFC-0362). Flags: --scope, --purge.",
@@ -48,8 +49,8 @@ export const forgeWerkstattModule: ForgeModule = {
48
49
  reads: [".werkstatt/locks/**"],
49
50
  cacheable: false,
50
51
  execute: runWerkstattLockRecover,
51
- });
52
- registry.registerCommand({
52
+ },
53
+ {
53
54
  name: "werkstatt.operation.validate",
54
55
  contract: "werkstatt",
55
56
  rules: [],
@@ -60,6 +61,8 @@ export const forgeWerkstattModule: ForgeModule = {
60
61
  flags: {},
61
62
  reads: ["packages/os/site-kernel-handoff/src/**/*.ts"],
62
63
  execute: runWerkstattOperationValidate,
63
- });
64
- },
65
- };
64
+ }
65
+ ],
66
+ pipelines: [
67
+
68
+ ]};
@@ -14,7 +14,7 @@
14
14
  </CHANGE_SUMMARY>
15
15
  */
16
16
 
17
- export { forgeWorkflowModule } from "./workflow.module.ts";
17
+ export { createForgeWorkflowModule } from "./workflow.module.ts";
18
18
  export { runWorkflowLint, runWorkflowList, runWorkflowAmendList } from "./handlers.ts";
19
19
  export type {
20
20
  WorkflowPhase,
@@ -13,14 +13,16 @@
13
13
 
14
14
  import type { ForgeModule } from "../../src/forge-module.ts";
15
15
 
16
- export const forgeWorkflowModule: ForgeModule = {
16
+ export async function createForgeWorkflowModule(): Promise<ForgeModule> {
17
+ const { runWorkflowLint, runWorkflowList, runWorkflowAmendList } =
18
+ await import("./handlers.ts");
19
+ return {
17
20
  name: "workflow",
18
21
  version: "0.1.0",
19
22
  runtime: "autonomous",
20
- async register(registry) {
21
- const { runWorkflowLint, runWorkflowList, runWorkflowAmendList } =
22
- await import("./handlers.ts");
23
- registry.registerCommand({
23
+ declarations: [],
24
+ commands: [
25
+ {
24
26
  name: "workflow.lint",
25
27
  contract: "workflow",
26
28
  rules: [],
@@ -32,8 +34,8 @@ export const forgeWorkflowModule: ForgeModule = {
32
34
  supportsAllSites: true,
33
35
  reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"],
34
36
  execute: runWorkflowLint,
35
- });
36
- registry.registerCommand({
37
+ },
38
+ {
37
39
  name: "workflow.list",
38
40
  description:
39
41
  "List .agents/workflows entries with phase, IO summary, and next workflow (RFC-0075).",
@@ -42,8 +44,8 @@ export const forgeWorkflowModule: ForgeModule = {
42
44
  supportsAllSites: true,
43
45
  reads: [".agents/workflows/**/*.md", ".windsurf/workflows/**/*.md"],
44
46
  execute: runWorkflowList,
45
- });
46
- registry.registerCommand({
47
+ },
48
+ {
47
49
  name: "workflow-amend.list",
48
50
  description:
49
51
  "List .agents/workflows-amend entries with phase, IO summary, and next workflow (RFC-0136).",
@@ -52,6 +54,10 @@ export const forgeWorkflowModule: ForgeModule = {
52
54
  supportsAllSites: true,
53
55
  reads: [".agents/workflows-amend/**/*.md"],
54
56
  execute: runWorkflowAmendList,
55
- });
56
- },
57
- };
57
+ }
58
+ ],
59
+ pipelines: [
60
+
61
+ ]};
62
+ }
63
+ ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warpgogol/forge",
3
- "version": "4.0.0",
3
+ "version": "4.1.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -164,6 +164,7 @@
164
164
  "lint": "pnpm exec eslint \"src/**/*.ts\" \"os/**/*.ts\"",
165
165
  "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
166
166
  "test": "vitest run --passWithNoTests",
167
+ "test:coverage": "vitest run --coverage --passWithNoTests",
167
168
  "test:watch": "vitest",
168
169
  "test:tarball:node24": "node test-fixtures/node24-consumer/smoke.mjs"
169
170
  },
@@ -182,6 +183,7 @@
182
183
  "fast-check": "^4.9.0",
183
184
  "typescript": "^6.0.3",
184
185
  "typescript-eslint": "8.68.0",
186
+ "@vitest/coverage-v8": "^4.1.11",
185
187
  "vitest": "^4.1.11"
186
188
  },
187
189
  "engines": {