@workflow-cannon/workspace-kit 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/dist/adapters/index.d.ts +1 -0
  4. package/dist/adapters/index.js +1 -0
  5. package/dist/cli.js +60 -2
  6. package/dist/contracts/index.d.ts +1 -0
  7. package/dist/contracts/index.js +1 -0
  8. package/dist/contracts/module-contract.d.ts +62 -0
  9. package/dist/contracts/module-contract.js +1 -0
  10. package/dist/core/index.d.ts +3 -0
  11. package/dist/core/index.js +2 -0
  12. package/dist/core/module-command-router.d.ts +27 -0
  13. package/dist/core/module-command-router.js +84 -0
  14. package/dist/core/module-registry.d.ts +24 -0
  15. package/dist/core/module-registry.js +183 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.js +3 -0
  18. package/dist/modules/approvals/index.d.ts +2 -0
  19. package/dist/modules/approvals/index.js +30 -0
  20. package/dist/modules/documentation/index.d.ts +3 -0
  21. package/dist/modules/documentation/index.js +98 -0
  22. package/dist/modules/documentation/runtime.d.ts +12 -0
  23. package/dist/modules/documentation/runtime.js +368 -0
  24. package/dist/modules/documentation/types.d.ts +46 -0
  25. package/dist/modules/documentation/types.js +1 -0
  26. package/dist/modules/improvement/index.d.ts +2 -0
  27. package/dist/modules/improvement/index.js +30 -0
  28. package/dist/modules/index.d.ts +7 -0
  29. package/dist/modules/index.js +5 -0
  30. package/dist/modules/planning/index.d.ts +2 -0
  31. package/dist/modules/planning/index.js +30 -0
  32. package/dist/modules/task-engine/generator.d.ts +2 -0
  33. package/dist/modules/task-engine/generator.js +101 -0
  34. package/dist/modules/task-engine/importer.d.ts +8 -0
  35. package/dist/modules/task-engine/importer.js +157 -0
  36. package/dist/modules/task-engine/index.d.ts +9 -0
  37. package/dist/modules/task-engine/index.js +253 -0
  38. package/dist/modules/task-engine/service.d.ts +21 -0
  39. package/dist/modules/task-engine/service.js +105 -0
  40. package/dist/modules/task-engine/store.d.ts +16 -0
  41. package/dist/modules/task-engine/store.js +88 -0
  42. package/dist/modules/task-engine/suggestions.d.ts +2 -0
  43. package/dist/modules/task-engine/suggestions.js +51 -0
  44. package/dist/modules/task-engine/transitions.d.ts +23 -0
  45. package/dist/modules/task-engine/transitions.js +109 -0
  46. package/dist/modules/task-engine/types.d.ts +82 -0
  47. package/dist/modules/task-engine/types.js +1 -0
  48. package/dist/ops/index.d.ts +1 -0
  49. package/dist/ops/index.js +1 -0
  50. package/package.json +4 -2
@@ -0,0 +1,30 @@
1
+ export const approvalsModule = {
2
+ registration: {
3
+ id: "approvals",
4
+ version: "0.1.0",
5
+ contractVersion: "1",
6
+ capabilities: ["approvals"],
7
+ dependsOn: ["task-engine"],
8
+ enabledByDefault: true,
9
+ config: {
10
+ path: "src/modules/approvals/config.md",
11
+ format: "md",
12
+ description: "Approvals module policy and queue configuration contract."
13
+ },
14
+ state: {
15
+ path: "src/modules/approvals/state.md",
16
+ format: "md",
17
+ description: "Approvals module decision and queue state contract."
18
+ },
19
+ instructions: {
20
+ directory: "src/modules/approvals/instructions",
21
+ entries: [
22
+ {
23
+ name: "review-item",
24
+ file: "review-item.md",
25
+ description: "Review and record an approval decision."
26
+ }
27
+ ]
28
+ }
29
+ }
30
+ };
@@ -0,0 +1,3 @@
1
+ import type { WorkflowModule } from "../../contracts/module-contract.js";
2
+ export type { DocumentationBatchResult, DocumentationConflict, DocumentationGenerateOptions, DocumentationGenerateResult, DocumentationGenerationEvidence, DocumentationValidationIssue } from "./types.js";
3
+ export declare const documentationModule: WorkflowModule;
@@ -0,0 +1,98 @@
1
+ import { generateDocument, generateAllDocuments } from "./runtime.js";
2
+ function parseOptions(raw) {
3
+ return {
4
+ dryRun: typeof raw.dryRun === "boolean" ? raw.dryRun : undefined,
5
+ overwrite: typeof raw.overwrite === "boolean" ? raw.overwrite : undefined,
6
+ overwriteAi: typeof raw.overwriteAi === "boolean" ? raw.overwriteAi : undefined,
7
+ overwriteHuman: typeof raw.overwriteHuman === "boolean" ? raw.overwriteHuman : undefined,
8
+ strict: typeof raw.strict === "boolean" ? raw.strict : undefined,
9
+ maxValidationAttempts: typeof raw.maxValidationAttempts === "number" ? raw.maxValidationAttempts : undefined,
10
+ allowWithoutTemplate: typeof raw.allowWithoutTemplate === "boolean" ? raw.allowWithoutTemplate : undefined,
11
+ };
12
+ }
13
+ export const documentationModule = {
14
+ registration: {
15
+ id: "documentation",
16
+ version: "0.2.0",
17
+ contractVersion: "1",
18
+ capabilities: ["documentation"],
19
+ dependsOn: [],
20
+ enabledByDefault: true,
21
+ config: {
22
+ path: "src/modules/documentation/config.md",
23
+ format: "md",
24
+ description: "Documentation module configuration contract."
25
+ },
26
+ state: {
27
+ path: "src/modules/documentation/state.md",
28
+ format: "md",
29
+ description: "Documentation module generation/runtime state contract."
30
+ },
31
+ instructions: {
32
+ directory: "src/modules/documentation/instructions",
33
+ entries: [
34
+ {
35
+ name: "document-project",
36
+ file: "document-project.md",
37
+ description: "Generate all project docs from templates to .ai and docs/maintainers surfaces."
38
+ },
39
+ {
40
+ name: "generate-document",
41
+ file: "generate-document.md",
42
+ description: "Generate a single document by type for .ai and docs/maintainers surfaces."
43
+ }
44
+ ]
45
+ }
46
+ },
47
+ async onCommand(command, ctx) {
48
+ const args = command.args ?? {};
49
+ const rawOptions = typeof args.options === "object" && args.options !== null
50
+ ? args.options
51
+ : {};
52
+ const options = parseOptions(rawOptions);
53
+ if (command.name === "document-project") {
54
+ const batchResult = await generateAllDocuments({ options }, ctx);
55
+ return {
56
+ ok: batchResult.ok,
57
+ code: batchResult.ok ? "documented-project" : "documentation-batch-failed",
58
+ message: batchResult.ok
59
+ ? `Generated ${batchResult.summary.succeeded} documents (${batchResult.summary.skipped} skipped)`
60
+ : `Batch failed: ${batchResult.summary.failed} of ${batchResult.summary.total} documents failed`,
61
+ data: {
62
+ summary: batchResult.summary,
63
+ results: batchResult.results.map((r) => ({
64
+ documentType: r.evidence.documentType,
65
+ ok: r.ok,
66
+ aiOutputPath: r.aiOutputPath,
67
+ humanOutputPath: r.humanOutputPath,
68
+ filesWritten: r.evidence.filesWritten,
69
+ filesSkipped: r.evidence.filesSkipped,
70
+ }))
71
+ }
72
+ };
73
+ }
74
+ if (command.name === "generate-document") {
75
+ const result = await generateDocument({
76
+ documentType: typeof args.documentType === "string" ? args.documentType : undefined,
77
+ options
78
+ }, ctx);
79
+ return {
80
+ ok: result.ok,
81
+ code: result.ok ? "generated-document" : "generation-failed",
82
+ message: result.ok
83
+ ? `Generated document '${args.documentType ?? "unknown"}'`
84
+ : `Failed to generate document '${args.documentType ?? "unknown"}'`,
85
+ data: {
86
+ aiOutputPath: result.aiOutputPath,
87
+ humanOutputPath: result.humanOutputPath,
88
+ evidence: result.evidence
89
+ }
90
+ };
91
+ }
92
+ return {
93
+ ok: false,
94
+ code: "unsupported-command",
95
+ message: `Documentation module does not support command '${command.name}'`
96
+ };
97
+ }
98
+ };
@@ -0,0 +1,12 @@
1
+ import type { DocumentationBatchResult, DocumentationGenerateOptions, DocumentationGenerateResult } from "./types.js";
2
+ import type { ModuleLifecycleContext } from "../../contracts/module-contract.js";
3
+ type GenerateDocumentArgs = {
4
+ documentType?: string;
5
+ options?: DocumentationGenerateOptions;
6
+ };
7
+ export declare function generateDocument(args: GenerateDocumentArgs, ctx: ModuleLifecycleContext): Promise<DocumentationGenerateResult>;
8
+ type GenerateAllDocumentsArgs = {
9
+ options?: DocumentationGenerateOptions;
10
+ };
11
+ export declare function generateAllDocuments(args: GenerateAllDocumentsArgs, ctx: ModuleLifecycleContext): Promise<DocumentationBatchResult>;
12
+ export {};
@@ -0,0 +1,368 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { resolve, sep } from "node:path";
4
+ import { readdir } from "node:fs/promises";
5
+ function isPathWithinRoot(path, root) {
6
+ return path === root || path.startsWith(`${root}${sep}`);
7
+ }
8
+ function parseDefaultValue(fileContent, key, fallback) {
9
+ const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10
+ const regex = new RegExp(`\\\`${escaped}\\\`[^\\n]*default:\\s*\\\`([^\\\`]+)\\\``);
11
+ const match = fileContent.match(regex);
12
+ return match?.[1] ?? fallback;
13
+ }
14
+ async function loadRuntimeConfig(workspacePath) {
15
+ const configPath = resolve(workspacePath, "src/modules/documentation/config.md");
16
+ const configContent = await readFile(configPath, "utf8");
17
+ const aiRoot = parseDefaultValue(configContent, "sources.aiRoot", "/.ai");
18
+ const humanRoot = parseDefaultValue(configContent, "sources.humanRoot", "docs/maintainers");
19
+ const templatesRoot = parseDefaultValue(configContent, "sources.templatesRoot", "src/modules/documentation/templates");
20
+ const instructionsRoot = parseDefaultValue(configContent, "sources.instructionsRoot", "src/modules/documentation/instructions");
21
+ const schemasRoot = parseDefaultValue(configContent, "sources.schemasRoot", "src/modules/documentation/schemas");
22
+ const maxValidationAttemptsRaw = parseDefaultValue(configContent, "generation.maxValidationAttempts", "3");
23
+ const maxValidationAttempts = Number.parseInt(maxValidationAttemptsRaw, 10);
24
+ return {
25
+ aiRoot,
26
+ humanRoot,
27
+ templatesRoot,
28
+ instructionsRoot,
29
+ schemasRoot,
30
+ maxValidationAttempts: Number.isFinite(maxValidationAttempts) ? maxValidationAttempts : 3
31
+ };
32
+ }
33
+ function validateAiSchema(aiOutput) {
34
+ const issues = [];
35
+ const lines = aiOutput.split("\n").filter((line) => line.trim().length > 0);
36
+ if (!lines[0]?.startsWith("meta|v=")) {
37
+ issues.push({
38
+ check: "schema",
39
+ message: "AI output must start with a meta record",
40
+ resolved: false
41
+ });
42
+ }
43
+ return issues;
44
+ }
45
+ function autoResolveAiSchema(aiOutput) {
46
+ if (aiOutput.startsWith("meta|v=")) {
47
+ return aiOutput;
48
+ }
49
+ return `meta|v=1|doc=rules|truth=canonical|st=draft\n\n${aiOutput}`;
50
+ }
51
+ function renderTemplate(templateContent) {
52
+ const output = templateContent.replace(/\{\{\{([\s\S]*?)\}\}\}/g, (_match, instructionText) => {
53
+ const normalized = instructionText.trim().split("\n")[0] ?? "template instructions";
54
+ return `Generated content based on instruction: ${normalized}`;
55
+ });
56
+ return {
57
+ output,
58
+ unresolvedBlocks: output.includes("{{{")
59
+ };
60
+ }
61
+ function validateSectionCoverage(templateContent, output) {
62
+ const issues = [];
63
+ const sectionRegex = /^##\s+(.+)$/gm;
64
+ const expectedSections = [...templateContent.matchAll(sectionRegex)].map((match) => match[1]);
65
+ for (const section of expectedSections) {
66
+ if (!output.includes(`## ${section}`)) {
67
+ issues.push({
68
+ check: "section-coverage",
69
+ message: `Missing required section: ${section}`,
70
+ resolved: false
71
+ });
72
+ }
73
+ }
74
+ return issues;
75
+ }
76
+ function detectConflicts(aiOutput, humanOutput) {
77
+ const conflicts = [];
78
+ const combined = `${aiOutput}\n${humanOutput}`;
79
+ if (combined.includes("CONFLICT:")) {
80
+ conflicts.push({
81
+ source: "generated-output",
82
+ reason: "Generated output flagged a conflict marker",
83
+ severity: "stop"
84
+ });
85
+ }
86
+ return conflicts;
87
+ }
88
+ export async function generateDocument(args, ctx) {
89
+ const documentType = args.documentType;
90
+ if (!documentType) {
91
+ return {
92
+ ok: false,
93
+ evidence: {
94
+ documentType: "unknown",
95
+ filesRead: [],
96
+ filesWritten: [],
97
+ filesSkipped: [],
98
+ validationIssues: [
99
+ {
100
+ check: "template-resolution",
101
+ message: "Missing required argument 'documentType'",
102
+ resolved: false
103
+ }
104
+ ],
105
+ conflicts: [],
106
+ attemptsUsed: 0,
107
+ timestamp: new Date().toISOString()
108
+ }
109
+ };
110
+ }
111
+ const options = args.options ?? {};
112
+ const config = await loadRuntimeConfig(ctx.workspacePath);
113
+ const filesRead = [];
114
+ const filesWritten = [];
115
+ const filesSkipped = [];
116
+ const validationIssues = [];
117
+ const conflicts = [];
118
+ const aiRoot = resolve(ctx.workspacePath, config.aiRoot.replace(/^\//, ""));
119
+ const humanRoot = resolve(ctx.workspacePath, config.humanRoot.replace(/^\//, ""));
120
+ const templatePath = resolve(ctx.workspacePath, config.templatesRoot, documentType);
121
+ const aiOutputPath = resolve(aiRoot, documentType);
122
+ const humanOutputPath = resolve(humanRoot, documentType);
123
+ if (!isPathWithinRoot(aiOutputPath, aiRoot) || !isPathWithinRoot(humanOutputPath, humanRoot)) {
124
+ return {
125
+ ok: false,
126
+ evidence: {
127
+ documentType,
128
+ filesRead,
129
+ filesWritten,
130
+ filesSkipped,
131
+ validationIssues: [
132
+ {
133
+ check: "write-boundary",
134
+ message: "Resolved output path escapes configured output roots",
135
+ resolved: false
136
+ }
137
+ ],
138
+ conflicts,
139
+ attemptsUsed: 0,
140
+ timestamp: new Date().toISOString()
141
+ }
142
+ };
143
+ }
144
+ let templateContent = "";
145
+ let templateFound = existsSync(templatePath);
146
+ if (templateFound) {
147
+ templateContent = await readFile(templatePath, "utf8");
148
+ filesRead.push(templatePath);
149
+ }
150
+ else {
151
+ validationIssues.push({
152
+ check: "template-resolution",
153
+ message: `Template not found for '${documentType}'`,
154
+ resolved: Boolean(options.allowWithoutTemplate)
155
+ });
156
+ if (!options.allowWithoutTemplate) {
157
+ return {
158
+ ok: false,
159
+ evidence: {
160
+ documentType,
161
+ filesRead,
162
+ filesWritten,
163
+ filesSkipped,
164
+ validationIssues,
165
+ conflicts,
166
+ attemptsUsed: 0,
167
+ timestamp: new Date().toISOString()
168
+ }
169
+ };
170
+ }
171
+ }
172
+ const schemaPath = resolve(ctx.workspacePath, config.schemasRoot, "documentation-schema.md");
173
+ if (existsSync(schemaPath)) {
174
+ filesRead.push(schemaPath);
175
+ await readFile(schemaPath, "utf8");
176
+ }
177
+ let aiOutput = `meta|v=1|doc=rules|truth=canonical|st=draft\nproject|name=workflow-cannon|type=generated_doc|scope=${documentType}`;
178
+ let attemptsUsed = 0;
179
+ const maxAttempts = options.maxValidationAttempts ?? config.maxValidationAttempts;
180
+ while (attemptsUsed < maxAttempts) {
181
+ attemptsUsed += 1;
182
+ const schemaIssues = validateAiSchema(aiOutput);
183
+ if (schemaIssues.length === 0) {
184
+ break;
185
+ }
186
+ validationIssues.push(...schemaIssues);
187
+ aiOutput = autoResolveAiSchema(aiOutput);
188
+ }
189
+ const aiFinalIssues = validateAiSchema(aiOutput);
190
+ if (aiFinalIssues.length > 0) {
191
+ validationIssues.push(...aiFinalIssues);
192
+ return {
193
+ ok: false,
194
+ evidence: {
195
+ documentType,
196
+ filesRead,
197
+ filesWritten,
198
+ filesSkipped,
199
+ validationIssues,
200
+ conflicts,
201
+ attemptsUsed,
202
+ timestamp: new Date().toISOString()
203
+ }
204
+ };
205
+ }
206
+ let humanOutput = `# ${documentType}\n\nGenerated without template.`;
207
+ if (templateFound) {
208
+ const rendered = renderTemplate(templateContent);
209
+ humanOutput = rendered.output;
210
+ if (rendered.unresolvedBlocks) {
211
+ validationIssues.push({
212
+ check: "section-coverage",
213
+ message: "Template output still contains unresolved {{{ }}} blocks",
214
+ resolved: false
215
+ });
216
+ }
217
+ validationIssues.push(...validateSectionCoverage(templateContent, humanOutput));
218
+ }
219
+ conflicts.push(...detectConflicts(aiOutput, humanOutput));
220
+ if (conflicts.some((conflict) => conflict.severity === "stop")) {
221
+ return {
222
+ ok: false,
223
+ evidence: {
224
+ documentType,
225
+ filesRead,
226
+ filesWritten,
227
+ filesSkipped,
228
+ validationIssues,
229
+ conflicts,
230
+ attemptsUsed,
231
+ timestamp: new Date().toISOString()
232
+ }
233
+ };
234
+ }
235
+ const hasUnresolvedValidation = validationIssues.some((issue) => !issue.resolved);
236
+ if (options.strict !== false && hasUnresolvedValidation) {
237
+ return {
238
+ ok: false,
239
+ evidence: {
240
+ documentType,
241
+ filesRead,
242
+ filesWritten,
243
+ filesSkipped,
244
+ validationIssues,
245
+ conflicts,
246
+ attemptsUsed,
247
+ timestamp: new Date().toISOString()
248
+ }
249
+ };
250
+ }
251
+ if (!options.dryRun) {
252
+ const canOverwriteAi = options.overwriteAi ?? options.overwrite ?? true;
253
+ const canOverwriteHuman = options.overwriteHuman ?? options.overwrite ?? true;
254
+ const aiExists = existsSync(aiOutputPath);
255
+ const humanExists = existsSync(humanOutputPath);
256
+ if ((!canOverwriteAi && aiExists) && (!canOverwriteHuman && humanExists)) {
257
+ return {
258
+ ok: false,
259
+ evidence: {
260
+ documentType,
261
+ filesRead,
262
+ filesWritten,
263
+ filesSkipped: [aiOutputPath, humanOutputPath],
264
+ validationIssues: [
265
+ ...validationIssues,
266
+ {
267
+ check: "write-boundary",
268
+ message: "Output exists and overwrite=false",
269
+ resolved: false
270
+ }
271
+ ],
272
+ conflicts,
273
+ attemptsUsed,
274
+ timestamp: new Date().toISOString()
275
+ }
276
+ };
277
+ }
278
+ await mkdir(aiRoot, { recursive: true });
279
+ await mkdir(humanRoot, { recursive: true });
280
+ if (canOverwriteAi || !aiExists) {
281
+ await writeFile(aiOutputPath, `${aiOutput}\n`, "utf8");
282
+ filesWritten.push(aiOutputPath);
283
+ }
284
+ else {
285
+ filesSkipped.push(aiOutputPath);
286
+ }
287
+ if (canOverwriteHuman || !humanExists) {
288
+ await writeFile(humanOutputPath, `${humanOutput}\n`, "utf8");
289
+ filesWritten.push(humanOutputPath);
290
+ }
291
+ else {
292
+ filesSkipped.push(humanOutputPath);
293
+ }
294
+ }
295
+ return {
296
+ ok: true,
297
+ aiOutputPath,
298
+ humanOutputPath,
299
+ evidence: {
300
+ documentType,
301
+ filesRead,
302
+ filesWritten,
303
+ filesSkipped,
304
+ validationIssues,
305
+ conflicts,
306
+ attemptsUsed,
307
+ timestamp: new Date().toISOString()
308
+ }
309
+ };
310
+ }
311
+ export async function generateAllDocuments(args, ctx) {
312
+ const config = await loadRuntimeConfig(ctx.workspacePath);
313
+ const templatesDir = resolve(ctx.workspacePath, config.templatesRoot);
314
+ let templateFiles = [];
315
+ try {
316
+ const entries = await readdir(templatesDir);
317
+ templateFiles = entries.filter((f) => f.endsWith(".md")).sort();
318
+ }
319
+ catch {
320
+ return {
321
+ ok: false,
322
+ results: [],
323
+ summary: {
324
+ total: 0,
325
+ succeeded: 0,
326
+ failed: 1,
327
+ skipped: 0,
328
+ timestamp: new Date().toISOString()
329
+ }
330
+ };
331
+ }
332
+ const results = [];
333
+ let succeeded = 0;
334
+ let failed = 0;
335
+ let skipped = 0;
336
+ const batchOptions = {
337
+ ...args.options,
338
+ overwriteAi: args.options?.overwriteAi ?? false,
339
+ overwriteHuman: args.options?.overwriteHuman ?? true,
340
+ strict: args.options?.strict ?? false,
341
+ };
342
+ for (const templateFile of templateFiles) {
343
+ const result = await generateDocument({ documentType: templateFile, options: batchOptions }, ctx);
344
+ results.push(result);
345
+ if (result.ok) {
346
+ if (result.evidence.filesWritten.length > 0) {
347
+ succeeded++;
348
+ }
349
+ else {
350
+ skipped++;
351
+ }
352
+ }
353
+ else {
354
+ failed++;
355
+ }
356
+ }
357
+ return {
358
+ ok: failed === 0,
359
+ results,
360
+ summary: {
361
+ total: templateFiles.length,
362
+ succeeded,
363
+ failed,
364
+ skipped,
365
+ timestamp: new Date().toISOString()
366
+ }
367
+ };
368
+ }
@@ -0,0 +1,46 @@
1
+ export type DocumentationGenerateOptions = {
2
+ dryRun?: boolean;
3
+ overwrite?: boolean;
4
+ overwriteAi?: boolean;
5
+ overwriteHuman?: boolean;
6
+ strict?: boolean;
7
+ maxValidationAttempts?: number;
8
+ allowWithoutTemplate?: boolean;
9
+ };
10
+ export type DocumentationConflict = {
11
+ source: string;
12
+ reason: string;
13
+ severity: "warn" | "stop";
14
+ };
15
+ export type DocumentationValidationIssue = {
16
+ check: "schema" | "section-coverage" | "template-resolution" | "write-boundary" | "conflict";
17
+ message: string;
18
+ resolved: boolean;
19
+ };
20
+ export type DocumentationGenerationEvidence = {
21
+ documentType: string;
22
+ filesRead: string[];
23
+ filesWritten: string[];
24
+ filesSkipped: string[];
25
+ validationIssues: DocumentationValidationIssue[];
26
+ conflicts: DocumentationConflict[];
27
+ attemptsUsed: number;
28
+ timestamp: string;
29
+ };
30
+ export type DocumentationGenerateResult = {
31
+ ok: boolean;
32
+ aiOutputPath?: string;
33
+ humanOutputPath?: string;
34
+ evidence: DocumentationGenerationEvidence;
35
+ };
36
+ export type DocumentationBatchResult = {
37
+ ok: boolean;
38
+ results: DocumentationGenerateResult[];
39
+ summary: {
40
+ total: number;
41
+ succeeded: number;
42
+ failed: number;
43
+ skipped: number;
44
+ timestamp: string;
45
+ };
46
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { WorkflowModule } from "../../contracts/module-contract.js";
2
+ export declare const improvementModule: WorkflowModule;
@@ -0,0 +1,30 @@
1
+ export const improvementModule = {
2
+ registration: {
3
+ id: "improvement",
4
+ version: "0.1.0",
5
+ contractVersion: "1",
6
+ capabilities: ["improvement"],
7
+ dependsOn: ["task-engine", "planning"],
8
+ enabledByDefault: true,
9
+ config: {
10
+ path: "src/modules/improvement/config.md",
11
+ format: "md",
12
+ description: "Improvement module configuration contract."
13
+ },
14
+ state: {
15
+ path: "src/modules/improvement/state.md",
16
+ format: "md",
17
+ description: "Improvement module recommendation state contract."
18
+ },
19
+ instructions: {
20
+ directory: "src/modules/improvement/instructions",
21
+ entries: [
22
+ {
23
+ name: "generate-recommendations",
24
+ file: "generate-recommendations.md",
25
+ description: "Produce evidence-backed workflow recommendations."
26
+ }
27
+ ]
28
+ }
29
+ }
30
+ };
@@ -0,0 +1,7 @@
1
+ export { approvalsModule } from "./approvals/index.js";
2
+ export { documentationModule } from "./documentation/index.js";
3
+ export type { DocumentationConflict, DocumentationGenerateOptions, DocumentationGenerateResult, DocumentationGenerationEvidence, DocumentationValidationIssue } from "./documentation/types.js";
4
+ export { improvementModule } from "./improvement/index.js";
5
+ export { planningModule } from "./planning/index.js";
6
+ export { taskEngineModule, TaskStore, TransitionService, TaskEngineError, TransitionValidator, isTransitionAllowed, getTransitionAction, resolveTargetState, getAllowedTransitionsFrom, stateValidityGuard, dependencyCheckGuard, generateTasksMd, importTasksFromMarkdown, getNextActions } from "./task-engine/index.js";
7
+ export type { TaskEntity, TaskStatus, TaskPriority, TaskStoreDocument, TransitionEvidence, TransitionGuard, TransitionContext, GuardResult, TaskEngineErrorCode, TaskAdapter, TaskAdapterCapability, NextActionSuggestion, BlockingAnalysisEntry } from "./task-engine/index.js";
@@ -0,0 +1,5 @@
1
+ export { approvalsModule } from "./approvals/index.js";
2
+ export { documentationModule } from "./documentation/index.js";
3
+ export { improvementModule } from "./improvement/index.js";
4
+ export { planningModule } from "./planning/index.js";
5
+ export { taskEngineModule, TaskStore, TransitionService, TaskEngineError, TransitionValidator, isTransitionAllowed, getTransitionAction, resolveTargetState, getAllowedTransitionsFrom, stateValidityGuard, dependencyCheckGuard, generateTasksMd, importTasksFromMarkdown, getNextActions } from "./task-engine/index.js";
@@ -0,0 +1,2 @@
1
+ import type { WorkflowModule } from "../../contracts/module-contract.js";
2
+ export declare const planningModule: WorkflowModule;
@@ -0,0 +1,30 @@
1
+ export const planningModule = {
2
+ registration: {
3
+ id: "planning",
4
+ version: "0.1.0",
5
+ contractVersion: "1",
6
+ capabilities: ["planning"],
7
+ dependsOn: ["task-engine"],
8
+ enabledByDefault: true,
9
+ config: {
10
+ path: "src/modules/planning/config.md",
11
+ format: "md",
12
+ description: "Planning module configuration contract."
13
+ },
14
+ state: {
15
+ path: "src/modules/planning/state.md",
16
+ format: "md",
17
+ description: "Planning module runtime state contract."
18
+ },
19
+ instructions: {
20
+ directory: "src/modules/planning/instructions",
21
+ entries: [
22
+ {
23
+ name: "build-plan",
24
+ file: "build-plan.md",
25
+ description: "Generate a dependency-aware execution plan."
26
+ }
27
+ ]
28
+ }
29
+ }
30
+ };
@@ -0,0 +1,2 @@
1
+ import type { TaskEntity } from "./types.js";
2
+ export declare function generateTasksMd(tasks: TaskEntity[]): string;