@tacuchi/agent-workflow-cli 4.6.0 → 5.0.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 (65) hide show
  1. package/dist/application/dev-graduate-service.d.ts +33 -4
  2. package/dist/application/dev-graduate-service.d.ts.map +1 -1
  3. package/dist/application/dev-graduate-service.js +225 -41
  4. package/dist/application/dev-graduate-service.js.map +1 -1
  5. package/dist/application/dsn-reader-service.d.ts +10 -0
  6. package/dist/application/dsn-reader-service.d.ts.map +1 -0
  7. package/dist/application/dsn-reader-service.js +26 -0
  8. package/dist/application/dsn-reader-service.js.map +1 -0
  9. package/dist/application/graduation-check-service.d.ts +19 -0
  10. package/dist/application/graduation-check-service.d.ts.map +1 -0
  11. package/dist/application/graduation-check-service.js +145 -0
  12. package/dist/application/graduation-check-service.js.map +1 -0
  13. package/dist/application/hub-init-service.d.ts +47 -0
  14. package/dist/application/hub-init-service.d.ts.map +1 -0
  15. package/dist/application/hub-init-service.js +92 -0
  16. package/dist/application/hub-init-service.js.map +1 -0
  17. package/dist/application/mcp-doctor-service.d.ts +23 -0
  18. package/dist/application/mcp-doctor-service.d.ts.map +1 -0
  19. package/dist/application/mcp-doctor-service.js +123 -0
  20. package/dist/application/mcp-doctor-service.js.map +1 -0
  21. package/dist/application/mcp-host-reader.d.ts +13 -0
  22. package/dist/application/mcp-host-reader.d.ts.map +1 -0
  23. package/dist/application/mcp-host-reader.js +89 -0
  24. package/dist/application/mcp-host-reader.js.map +1 -0
  25. package/dist/application/mcp-host-writer.d.ts +13 -0
  26. package/dist/application/mcp-host-writer.d.ts.map +1 -0
  27. package/dist/application/mcp-host-writer.js +196 -0
  28. package/dist/application/mcp-host-writer.js.map +1 -0
  29. package/dist/application/mcp-setup-service.d.ts +31 -0
  30. package/dist/application/mcp-setup-service.d.ts.map +1 -0
  31. package/dist/application/mcp-setup-service.js +69 -0
  32. package/dist/application/mcp-setup-service.js.map +1 -0
  33. package/dist/application/paths-service.d.ts +22 -0
  34. package/dist/application/paths-service.d.ts.map +1 -1
  35. package/dist/application/paths-service.js +33 -1
  36. package/dist/application/paths-service.js.map +1 -1
  37. package/dist/application/visibility-doctor-service.d.ts +34 -0
  38. package/dist/application/visibility-doctor-service.d.ts.map +1 -0
  39. package/dist/application/visibility-doctor-service.js +192 -0
  40. package/dist/application/visibility-doctor-service.js.map +1 -0
  41. package/dist/cli/commands/graduation-check.d.ts +3 -0
  42. package/dist/cli/commands/graduation-check.d.ts.map +1 -0
  43. package/dist/cli/commands/graduation-check.js +11 -0
  44. package/dist/cli/commands/graduation-check.js.map +1 -0
  45. package/dist/cli/commands/hub-init.d.ts +3 -0
  46. package/dist/cli/commands/hub-init.d.ts.map +1 -0
  47. package/dist/cli/commands/hub-init.js +95 -0
  48. package/dist/cli/commands/hub-init.js.map +1 -0
  49. package/dist/cli/commands/mcp.d.ts.map +1 -1
  50. package/dist/cli/commands/mcp.js +159 -37
  51. package/dist/cli/commands/mcp.js.map +1 -1
  52. package/dist/cli/commands/visibility.d.ts +3 -0
  53. package/dist/cli/commands/visibility.d.ts.map +1 -0
  54. package/dist/cli/commands/visibility.js +42 -0
  55. package/dist/cli/commands/visibility.js.map +1 -0
  56. package/dist/cli/commands/wave4d-simple.d.ts.map +1 -1
  57. package/dist/cli/commands/wave4d-simple.js +9 -4
  58. package/dist/cli/commands/wave4d-simple.js.map +1 -1
  59. package/dist/cli/main.js +6 -0
  60. package/dist/cli/main.js.map +1 -1
  61. package/dist/domain/mcp-entry.d.ts +44 -0
  62. package/dist/domain/mcp-entry.d.ts.map +1 -0
  63. package/dist/domain/mcp-entry.js +13 -0
  64. package/dist/domain/mcp-entry.js.map +1 -0
  65. package/package.json +3 -2
@@ -1,11 +1,14 @@
1
1
  import type { EnvPort } from "../ports/env.js";
2
2
  import type { FileSystemPort } from "../ports/file-system.js";
3
- import type { PathsService } from "./paths-service.js";
3
+ import { PathsService } from "./paths-service.js";
4
+ declare const ALLOWED_KINDS: readonly ["decision", "manual", "script", "especificacion", "conclusion", "release"];
5
+ export type GraduateKind = (typeof ALLOWED_KINDS)[number];
4
6
  export interface GraduateInput {
5
7
  kind?: string;
6
8
  session?: string;
7
9
  decId?: string;
8
10
  slug?: string;
11
+ source?: string;
9
12
  }
10
13
  export interface GraduateDecisionOutput {
11
14
  kind: "decision";
@@ -16,8 +19,33 @@ export interface GraduateDecisionOutput {
16
19
  dec_id: string;
17
20
  slug: string;
18
21
  }
19
- export interface GraduatePlanOutput {
20
- kind: "plan";
22
+ export interface GraduateManualOutput {
23
+ kind: "manual";
24
+ session: string;
25
+ source: string;
26
+ target: string;
27
+ next_number: string;
28
+ slug: string;
29
+ }
30
+ export interface GraduateScriptOutput {
31
+ kind: "script";
32
+ session: string;
33
+ source: string;
34
+ target: string;
35
+ next_number: string;
36
+ slug: string;
37
+ files_copied: number;
38
+ }
39
+ export interface GraduateEspecificacionOutput {
40
+ kind: "especificacion";
41
+ session: string;
42
+ source: string;
43
+ target: string;
44
+ next_number: string;
45
+ slug: string;
46
+ }
47
+ export interface GraduateConclusionOutput {
48
+ kind: "conclusion";
21
49
  session: string;
22
50
  source: string;
23
51
  target: string;
@@ -27,7 +55,8 @@ export interface GraduatePlanOutput {
27
55
  export interface GraduateError {
28
56
  error: string;
29
57
  }
30
- export type GraduateOutput = GraduateDecisionOutput | GraduatePlanOutput;
58
+ export type GraduateOutput = GraduateDecisionOutput | GraduateManualOutput | GraduateScriptOutput | GraduateEspecificacionOutput | GraduateConclusionOutput;
31
59
  export type GraduateResult = GraduateOutput | GraduateError;
32
60
  export declare function runGraduate(fs: FileSystemPort, env: EnvPort, paths: PathsService, input: GraduateInput): Promise<GraduateResult>;
61
+ export {};
33
62
  //# sourceMappingURL=dev-graduate-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-graduate-service.d.ts","sourceRoot":"","sources":["../../src/application/dev-graduate-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;AACzE,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,aAAa,CAAC;AAE5D,wBAAsB,WAAW,CAC/B,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,CAAC,CA0BzB"}
1
+ {"version":3,"file":"dev-graduate-service.d.ts","sourceRoot":"","sources":["../../src/application/dev-graduate-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAwB,MAAM,oBAAoB,CAAC;AAOxE,QAAA,MAAM,aAAa,sFAOT,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GACtB,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,4BAA4B,GAC5B,wBAAwB,CAAC;AAC7B,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,aAAa,CAAC;AAE5D,wBAAsB,WAAW,CAC/B,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,CAAC,CAyCzB"}
@@ -1,8 +1,62 @@
1
- import { join } from "node:path";
1
+ import { basename, join } from "node:path";
2
+ import { PathsService, resolveWorkspaceRoot } from "./paths-service.js";
2
3
  import { resolveSession } from "./session-resolver.js";
4
+ // Kinds graduable per DEC-003 (session006). The `release` kind is only
5
+ // invocable through the `release` command — it is rejected here with a hint.
6
+ // `script` is also typically driven by `release`; if invoked directly we still
7
+ // support it but we keep the bundle layout consistent with the release output.
8
+ const ALLOWED_KINDS = [
9
+ "decision",
10
+ "manual",
11
+ "script",
12
+ "especificacion",
13
+ "conclusion",
14
+ "release",
15
+ ];
3
16
  export async function runGraduate(fs, env, paths, input) {
4
- if (input.kind !== "decision" && input.kind !== "plan") {
5
- return { error: "--kind debe ser 'decision' o 'plan'" };
17
+ const validation = validateInput(input);
18
+ if ("error" in validation)
19
+ return validation;
20
+ // DEC-002: walk up from cwd to find the workspace root, then re-anchor session
21
+ // resolution and graduation destination there. Lets the user invoke `graduate`
22
+ // from inside a fuente subdirectory of a hub workspace and still land in the
23
+ // hub's docs/.
24
+ const workspaceRoot = await resolveWorkspaceRoot(fs, env, paths);
25
+ const wsPaths = workspaceRoot === env.cwd()
26
+ ? paths
27
+ : new PathsService(paths.namespace, env.homeDir(), workspaceRoot);
28
+ const session = await resolveSession(fs, env, wsPaths, input.session, true);
29
+ if (!session)
30
+ return { error: `Sesión no encontrada: ${input.session}` };
31
+ const ctx = {
32
+ fs,
33
+ workspaceRoot,
34
+ sessionPath: session.path,
35
+ folder: session.folder,
36
+ slug: validation.slug,
37
+ };
38
+ switch (validation.kind) {
39
+ case "decision":
40
+ return graduateDecision(ctx, validation.decId);
41
+ case "manual":
42
+ return graduateManual(ctx, input.source);
43
+ case "script":
44
+ return graduateScript(ctx);
45
+ case "especificacion":
46
+ return graduateEspecificacion(ctx, input.source);
47
+ case "conclusion":
48
+ return graduateConclusion(ctx);
49
+ case "release":
50
+ return {
51
+ error: "El kind 'release' no se gradúa con `graduate`; usá el comando `release` (consolida sesiones en un paquete de paso a producción).",
52
+ };
53
+ }
54
+ }
55
+ function validateInput(input) {
56
+ if (input.kind === undefined || !isAllowedKind(input.kind)) {
57
+ return {
58
+ error: `--kind debe ser uno de: ${ALLOWED_KINDS.join(", ")}`,
59
+ };
6
60
  }
7
61
  if (!input.session || !input.slug) {
8
62
  return { error: "--session y --slug son obligatorios" };
@@ -10,64 +64,157 @@ export async function runGraduate(fs, env, paths, input) {
10
64
  if (input.kind === "decision" && !input.decId) {
11
65
  return { error: "--id (DEC-NNN) obligatorio para --kind decision" };
12
66
  }
13
- const session = await resolveSession(fs, env, paths, input.session, true);
14
- if (!session)
15
- return { error: `Sesión no encontrada: ${input.session}` };
16
- const sessionPath = session.path;
17
- if (input.kind === "decision") {
18
- return graduateDecision(fs, env.cwd(), sessionPath, session.folder, input.decId ?? "", input.slug);
67
+ if (input.kind === "release") {
68
+ return {
69
+ error: "El kind 'release' no se gradúa con `graduate`; usá el comando `release` (consolida sesiones en un paquete de paso a producción).",
70
+ };
19
71
  }
20
- return graduatePlan(fs, env.cwd(), sessionPath, session.folder, input.slug);
72
+ const validated = {
73
+ kind: input.kind,
74
+ slug: input.slug,
75
+ };
76
+ if (input.decId !== undefined)
77
+ validated.decId = input.decId;
78
+ return validated;
79
+ }
80
+ function isAllowedKind(value) {
81
+ return ALLOWED_KINDS.includes(value);
21
82
  }
22
- async function graduateDecision(fs, cwd, sessionPath, folder, decId, slug) {
23
- const decFile = join(sessionPath, "DECISIONES.md");
24
- if (!(await fs.exists(decFile))) {
83
+ // ─── decision ───────────────────────────────────────────────────────────────
84
+ async function graduateDecision(ctx, decId) {
85
+ if (!decId)
86
+ return { error: "--id (DEC-NNN) obligatorio para --kind decision" };
87
+ const decFile = join(ctx.sessionPath, "DECISIONES.md");
88
+ if (!(await ctx.fs.exists(decFile))) {
25
89
  return { error: "DECISIONES.md no existe en la sesión" };
26
90
  }
27
- const text = await fs.readText(decFile);
28
- // Mirror Python regex: (^##\s+{decId}[^\n]*\n)(.*?)(?=^##\s+|\Z) — JS no soporta \Z, line-by-line parser.
91
+ const text = await ctx.fs.readText(decFile);
29
92
  const block = extractDecisionBlock(text, decId);
30
93
  if (!block) {
31
94
  return { error: `Bloque ${decId} no encontrado en DECISIONES.md` };
32
95
  }
33
- const destDir = join(cwd, "docs", "decisiones");
34
- await fs.mkdirp(destDir);
35
- const nnn = await nextNumberInDir(fs, destDir);
36
- const destFile = join(destDir, `${nnn}-${slug}.md`);
37
- await fs.writeText(destFile, `${block.header}\n\n${block.body}\n`);
38
- const pointer = `${block.header}\n→ docs/decisiones/${nnn}-${slug}.md\n\n`;
96
+ const destDir = join(ctx.workspaceRoot, "docs", "decisiones");
97
+ await ctx.fs.mkdirp(destDir);
98
+ const nnn = await nextNumberInDir(ctx.fs, destDir);
99
+ const destFile = join(destDir, `${nnn}-${ctx.slug}.md`);
100
+ await ctx.fs.writeText(destFile, `${block.header}\n\n${block.body}\n`);
101
+ const pointer = `${block.header}\n→ docs/decisiones/${nnn}-${ctx.slug}.md\n\n`;
39
102
  const newText = text.slice(0, block.startIndex) + pointer + text.slice(block.endIndex);
40
- await fs.writeText(decFile, newText);
103
+ await ctx.fs.writeText(decFile, newText);
41
104
  return {
42
105
  kind: "decision",
43
- session: folder,
106
+ session: ctx.folder,
44
107
  source: decFile,
45
108
  target: destFile,
46
109
  next_number: nnn,
47
110
  dec_id: decId,
48
- slug,
111
+ slug: ctx.slug,
49
112
  };
50
113
  }
51
- async function graduatePlan(fs, cwd, sessionPath, folder, slug) {
52
- const tasksFile = join(sessionPath, "TASKS.md");
53
- if (!(await fs.exists(tasksFile))) {
54
- return { error: "TASKS.md no existe en la sesión" };
114
+ // ─── manual ─────────────────────────────────────────────────────────────────
115
+ async function graduateManual(ctx, sourceArg) {
116
+ const sourceRel = sourceArg && sourceArg.length > 0 ? sourceArg : "MANUAL.md";
117
+ const sourceFile = join(ctx.sessionPath, sourceRel);
118
+ if (!(await ctx.fs.exists(sourceFile))) {
119
+ return { error: `Fuente no existe: ${sourceRel} en la sesión` };
55
120
  }
56
- const content = await fs.readText(tasksFile);
57
- const destDir = join(cwd, "docs", "planes");
58
- await fs.mkdirp(destDir);
59
- const nnn = await nextNumberInDir(fs, destDir);
60
- const destFile = join(destDir, `${nnn}-${slug}.md`);
61
- await fs.writeText(destFile, content);
62
- const pointer = `# Tareas — ${folder}\n\n→ docs/planes/${nnn}-${slug}.md\n`;
63
- await fs.writeText(tasksFile, pointer);
121
+ const content = await ctx.fs.readText(sourceFile);
122
+ const destDir = join(ctx.workspaceRoot, "docs", "manuales");
123
+ await ctx.fs.mkdirp(destDir);
124
+ const nnn = await nextNumberInDir(ctx.fs, destDir);
125
+ const destFile = join(destDir, `${nnn}-${ctx.slug}.md`);
126
+ await ctx.fs.writeText(destFile, content);
64
127
  return {
65
- kind: "plan",
66
- session: folder,
67
- source: tasksFile,
128
+ kind: "manual",
129
+ session: ctx.folder,
130
+ source: sourceFile,
68
131
  target: destFile,
69
132
  next_number: nnn,
70
- slug,
133
+ slug: ctx.slug,
134
+ };
135
+ }
136
+ // ─── script ─────────────────────────────────────────────────────────────────
137
+ async function graduateScript(ctx) {
138
+ const sessionCode = parseSessionCode(ctx.folder);
139
+ if (!sessionCode) {
140
+ return { error: `No se pudo extraer el código de sesión de '${ctx.folder}'` };
141
+ }
142
+ const scriptsDir = join(ctx.sessionPath, "scripts");
143
+ const queriesDir = join(ctx.sessionPath, "queries");
144
+ const hasScripts = await ctx.fs.exists(scriptsDir);
145
+ const hasQueries = await ctx.fs.exists(queriesDir);
146
+ if (!hasScripts && !hasQueries) {
147
+ return {
148
+ error: "La sesión no contiene 'scripts/' ni 'queries/' — nada para graduar.",
149
+ };
150
+ }
151
+ const destRoot = join(ctx.workspaceRoot, "docs", "scripts");
152
+ await ctx.fs.mkdirp(destRoot);
153
+ const nnn = await nextNumberInDirsByPrefix(ctx.fs, destRoot);
154
+ const bundleName = `${nnn}-session${sessionCode}-${ctx.slug}`;
155
+ const destDir = join(destRoot, bundleName);
156
+ await ctx.fs.mkdirp(destDir);
157
+ let copied = 0;
158
+ if (hasScripts) {
159
+ copied += await copyTree(ctx.fs, scriptsDir, join(destDir, "scripts"));
160
+ }
161
+ if (hasQueries) {
162
+ copied += await copyTree(ctx.fs, queriesDir, join(destDir, "queries"));
163
+ }
164
+ return {
165
+ kind: "script",
166
+ session: ctx.folder,
167
+ source: hasScripts ? scriptsDir : queriesDir,
168
+ target: destDir,
169
+ next_number: nnn,
170
+ slug: ctx.slug,
171
+ files_copied: copied,
172
+ };
173
+ }
174
+ // ─── especificacion ─────────────────────────────────────────────────────────
175
+ async function graduateEspecificacion(ctx, sourceArg) {
176
+ const sourceRel = sourceArg && sourceArg.length > 0 ? sourceArg : "ENTREGA.md";
177
+ const sourceFile = join(ctx.sessionPath, sourceRel);
178
+ if (!(await ctx.fs.exists(sourceFile))) {
179
+ return { error: `Fuente no existe: ${sourceRel} en la sesión` };
180
+ }
181
+ const content = await ctx.fs.readText(sourceFile);
182
+ const destRoot = join(ctx.workspaceRoot, "docs", "especificaciones");
183
+ await ctx.fs.mkdirp(destRoot);
184
+ const nnn = await nextNumberInDirsByPrefix(ctx.fs, destRoot);
185
+ const destDir = join(destRoot, `${nnn}-${ctx.slug}`);
186
+ await ctx.fs.mkdirp(destDir);
187
+ const filename = basename(sourceRel);
188
+ const destFile = join(destDir, filename);
189
+ await ctx.fs.writeText(destFile, content);
190
+ return {
191
+ kind: "especificacion",
192
+ session: ctx.folder,
193
+ source: sourceFile,
194
+ target: destFile,
195
+ next_number: nnn,
196
+ slug: ctx.slug,
197
+ };
198
+ }
199
+ // ─── conclusion ─────────────────────────────────────────────────────────────
200
+ async function graduateConclusion(ctx) {
201
+ const sourceFile = join(ctx.sessionPath, "CONCLUSIONES.md");
202
+ if (!(await ctx.fs.exists(sourceFile))) {
203
+ return { error: "CONCLUSIONES.md no existe en la sesión" };
204
+ }
205
+ const content = await ctx.fs.readText(sourceFile);
206
+ const destDir = join(ctx.workspaceRoot, "docs", "conclusiones");
207
+ await ctx.fs.mkdirp(destDir);
208
+ const nnn = await nextNumberInDir(ctx.fs, destDir);
209
+ const destFile = join(destDir, `${nnn}-${ctx.slug}.md`);
210
+ await ctx.fs.writeText(destFile, content);
211
+ return {
212
+ kind: "conclusion",
213
+ session: ctx.folder,
214
+ source: sourceFile,
215
+ target: destFile,
216
+ next_number: nnn,
217
+ slug: ctx.slug,
71
218
  };
72
219
  }
73
220
  function extractDecisionBlock(text, decId) {
@@ -78,7 +225,6 @@ function extractDecisionBlock(text, decId) {
78
225
  const headerStart = m.index;
79
226
  const headerLine = m[0];
80
227
  const headerEnd = headerStart + headerLine.length;
81
- // Body: after header newline until next `## ` or EOF.
82
228
  const afterHeader = text.indexOf("\n", headerEnd);
83
229
  const bodyStart = afterHeader === -1 ? text.length : afterHeader + 1;
84
230
  let bodyEnd = text.length;
@@ -110,6 +256,44 @@ async function nextNumberInDir(fs, dir) {
110
256
  const max = numbers.length > 0 ? Math.max(...numbers) : 0;
111
257
  return String(max + 1).padStart(3, "0");
112
258
  }
259
+ async function nextNumberInDirsByPrefix(fs, dir) {
260
+ if (!(await fs.exists(dir)))
261
+ return "001";
262
+ const entries = await fs.list(dir);
263
+ const numbers = [];
264
+ for (const entry of entries) {
265
+ if (entry.type !== "dir")
266
+ continue;
267
+ const m = entry.name.match(/^(\d{3})-/);
268
+ if (m?.[1])
269
+ numbers.push(Number.parseInt(m[1], 10));
270
+ }
271
+ const max = numbers.length > 0 ? Math.max(...numbers) : 0;
272
+ return String(max + 1).padStart(3, "0");
273
+ }
274
+ async function copyTree(fs, srcDir, destDir) {
275
+ if (!(await fs.exists(srcDir)))
276
+ return 0;
277
+ await fs.mkdirp(destDir);
278
+ let count = 0;
279
+ const entries = await fs.list(srcDir);
280
+ for (const entry of entries) {
281
+ const target = join(destDir, entry.name);
282
+ if (entry.type === "dir") {
283
+ count += await copyTree(fs, entry.path, target);
284
+ }
285
+ else if (entry.type === "file") {
286
+ const content = await fs.readText(entry.path);
287
+ await fs.writeText(target, content);
288
+ count += 1;
289
+ }
290
+ }
291
+ return count;
292
+ }
293
+ function parseSessionCode(folder) {
294
+ const m = folder.match(/^session(\d{3})-/);
295
+ return m?.[1] ?? null;
296
+ }
113
297
  function escapeRegex(s) {
114
298
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
115
299
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dev-graduate-service.js","sourceRoot":"","sources":["../../src/application/dev-graduate-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev-graduate-service.js","sourceRoot":"","sources":["../../src/application/dev-graduate-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { McpInstance } from "../domain/mcp-entry.js";
2
+ import type { PathsService } from "./paths-service.js";
3
+ export interface DsnReadResult {
4
+ path: string;
5
+ exists: boolean;
6
+ values: Record<string, string>;
7
+ }
8
+ export declare function readBootstrapDsn(paths: PathsService): DsnReadResult;
9
+ export declare function dsnKeyForInstance(instance: McpInstance): string;
10
+ //# sourceMappingURL=dsn-reader-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsn-reader-service.d.ts","sourceRoot":"","sources":["../../src/application/dsn-reader-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAiBnE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,26 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ export function readBootstrapDsn(paths) {
3
+ const path = paths.userDsnFile();
4
+ if (!existsSync(path)) {
5
+ return { path, exists: false, values: {} };
6
+ }
7
+ const text = readFileSync(path, "utf-8");
8
+ const values = {};
9
+ for (const rawLine of text.split("\n")) {
10
+ const line = rawLine.trim();
11
+ if (line.length === 0 || line.startsWith("#"))
12
+ continue;
13
+ const eq = line.indexOf("=");
14
+ if (eq <= 0)
15
+ continue;
16
+ const key = line.slice(0, eq).trim();
17
+ const val = line.slice(eq + 1).trim();
18
+ if (key.length > 0)
19
+ values[key] = val;
20
+ }
21
+ return { path, exists: true, values };
22
+ }
23
+ export function dsnKeyForInstance(instance) {
24
+ return instance === "cert" ? "DB_CERT_DSN" : "DB_PROD_DSN";
25
+ }
26
+ //# sourceMappingURL=dsn-reader-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsn-reader-service.js","sourceRoot":"","sources":["../../src/application/dsn-reader-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAUnD,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7C,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACxD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,IAAI,CAAC;YAAE,SAAS;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACxC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAqB;IACrD,OAAO,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { EnvPort } from "../ports/env.js";
2
+ import type { FileSystemPort } from "../ports/file-system.js";
3
+ export interface GraduationCheckFinding {
4
+ level: "warn" | "ok";
5
+ fuente: string;
6
+ categoria: string;
7
+ file: string;
8
+ msg: string;
9
+ }
10
+ export interface GraduationCheckOutput {
11
+ status: "ok" | "warn" | "skipped";
12
+ hub_mode: boolean;
13
+ hub_path: string;
14
+ fuentes_count: number;
15
+ findings: GraduationCheckFinding[];
16
+ reason?: string;
17
+ }
18
+ export declare function runGraduationCheck(fs: FileSystemPort, env: EnvPort): Promise<GraduationCheckOutput>;
19
+ //# sourceMappingURL=graduation-check-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graduation-check-service.d.ts","sourceRoot":"","sources":["../../src/application/graduation-check-service.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAK9D,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,qBAAqB,CAAC,CAkDhC"}
@@ -0,0 +1,145 @@
1
+ // Graduation routing check — detecta artefactos graduados a fuentes (docs/manuales|rfcs|post-mortems|analisis)
2
+ // sin breadcrumb correspondiente en el hub. Aplica solo en hub mode.
3
+ //
4
+ // Lee CLAUDE.md del cwd (hub workspace), parsea bloque `## Fuentes` para
5
+ // obtener alias + path, y walkea docs/<categoria>/ en cada fuente. Por cada
6
+ // archivo NNN-<slug>.md encontrado en una fuente, busca breadcrumb correspondiente
7
+ // en `<hub>/docs/<categoria>/000-INDEX.md` (regex sobre el filename).
8
+ //
9
+ // Output: lista de findings con level (error/warn/ok) por categoría.
10
+ //
11
+ // Origen: session005-dev-fix-graduacion-docs-hub-fuente, Phase 3.
12
+ import { join } from "node:path";
13
+ const CATEGORIAS = ["manuales", "rfcs", "post-mortems", "analisis", "refactors"];
14
+ export async function runGraduationCheck(fs, env) {
15
+ const hubPath = env.cwd();
16
+ const claudeMd = await readClaudeMd(fs, hubPath);
17
+ if (!claudeMd) {
18
+ return {
19
+ status: "skipped",
20
+ hub_mode: false,
21
+ hub_path: hubPath,
22
+ fuentes_count: 0,
23
+ findings: [],
24
+ reason: "CLAUDE.md no encontrado en cwd",
25
+ };
26
+ }
27
+ if (!isHubMode(claudeMd)) {
28
+ return {
29
+ status: "skipped",
30
+ hub_mode: false,
31
+ hub_path: hubPath,
32
+ fuentes_count: 0,
33
+ findings: [],
34
+ reason: "workspace no está en Mode: hub",
35
+ };
36
+ }
37
+ const fuentes = parseFuentes(claudeMd);
38
+ if (fuentes.length === 0) {
39
+ return {
40
+ status: "skipped",
41
+ hub_mode: true,
42
+ hub_path: hubPath,
43
+ fuentes_count: 0,
44
+ findings: [],
45
+ reason: "no se encontraron fuentes en CLAUDE.md",
46
+ };
47
+ }
48
+ const findings = [];
49
+ for (const fuente of fuentes) {
50
+ for (const categoria of CATEGORIAS) {
51
+ const f = await checkFuenteCategoria(fs, hubPath, fuente, categoria);
52
+ findings.push(...f);
53
+ }
54
+ }
55
+ const status = findings.some((f) => f.level === "warn") ? "warn" : "ok";
56
+ return {
57
+ status,
58
+ hub_mode: true,
59
+ hub_path: hubPath,
60
+ fuentes_count: fuentes.length,
61
+ findings,
62
+ };
63
+ }
64
+ async function readClaudeMd(fs, hubPath) {
65
+ const claudePath = join(hubPath, "CLAUDE.md");
66
+ if (!(await fs.exists(claudePath))) {
67
+ const agentsPath = join(hubPath, "AGENTS.md");
68
+ if (!(await fs.exists(agentsPath)))
69
+ return null;
70
+ return fs.readText(agentsPath);
71
+ }
72
+ return fs.readText(claudePath);
73
+ }
74
+ function isHubMode(text) {
75
+ return /^\s*Mode:\s*hub\s*$/m.test(text);
76
+ }
77
+ function parseFuentes(text) {
78
+ const lines = text.split(/\r?\n/);
79
+ const out = [];
80
+ let inFuentes = false;
81
+ for (const line of lines) {
82
+ if (/^##\s+Fuentes\s*$/i.test(line)) {
83
+ inFuentes = true;
84
+ continue;
85
+ }
86
+ if (inFuentes && /^##\s+/.test(line))
87
+ break;
88
+ if (!inFuentes)
89
+ continue;
90
+ const m = line.match(/^\|\s*([\w-]+)\s*\|\s*([^\s|]+)\s*\|/);
91
+ if (m?.[1] && m[2] && m[1] !== "Alias" && !m[1].startsWith("---")) {
92
+ out.push({ alias: m[1], path: m[2] });
93
+ }
94
+ }
95
+ return out;
96
+ }
97
+ async function checkFuenteCategoria(fs, hubPath, fuente, categoria) {
98
+ const fuenteDir = join(fuente.path, "docs", categoria);
99
+ if (!(await fs.exists(fuenteDir)))
100
+ return [];
101
+ let entries;
102
+ try {
103
+ entries = await fs.list(fuenteDir);
104
+ }
105
+ catch {
106
+ return [];
107
+ }
108
+ const orphans = [];
109
+ for (const entry of entries) {
110
+ if (entry.type !== "file")
111
+ continue;
112
+ if (!/^\d{3}-.*\.md$/.test(entry.name))
113
+ continue;
114
+ if (entry.name === "000-INDEX.md")
115
+ continue;
116
+ orphans.push(entry.name);
117
+ }
118
+ if (orphans.length === 0)
119
+ return [];
120
+ const indexFile = join(hubPath, "docs", categoria, "000-INDEX.md");
121
+ const indexText = (await fs.exists(indexFile)) ? await fs.readText(indexFile) : "";
122
+ const findings = [];
123
+ for (const orphan of orphans) {
124
+ if (indexText.includes(orphan)) {
125
+ findings.push({
126
+ level: "ok",
127
+ fuente: fuente.alias,
128
+ categoria,
129
+ file: `${fuente.path}/docs/${categoria}/${orphan}`,
130
+ msg: "breadcrumb encontrado en hub",
131
+ });
132
+ }
133
+ else {
134
+ findings.push({
135
+ level: "warn",
136
+ fuente: fuente.alias,
137
+ categoria,
138
+ file: `${fuente.path}/docs/${categoria}/${orphan}`,
139
+ msg: `falta breadcrumb en <hub>/docs/${categoria}/000-INDEX.md (debe mencionar '${orphan}')`,
140
+ });
141
+ }
142
+ }
143
+ return findings;
144
+ }
145
+ //# sourceMappingURL=graduation-check-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graduation-check-service.js","sourceRoot":"","sources":["../../src/application/graduation-check-service.ts"],"names":[],"mappings":"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"}