@specatlas/core 0.1.1 → 0.1.3

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/dist/index.d.ts CHANGED
@@ -215,6 +215,7 @@ interface Workspace {
215
215
  sddDir: string;
216
216
  specs: SpecRef[];
217
217
  changes: Change[];
218
+ archived?: Change[];
218
219
  diagnostics: Diagnostic[];
219
220
  }
220
221
 
@@ -1047,7 +1048,7 @@ interface ApprovalsIndex {
1047
1048
  }
1048
1049
  declare function loadApprovals(sddDir: string): Promise<ApprovalsIndex>;
1049
1050
  declare function loadSpecs(sddDir: string): Promise<SpecRef[]>;
1050
- declare function loadChange(root: string, slug: string): Promise<Change>;
1051
+ declare function loadChange(root: string, slug: string, relDir?: string): Promise<Change>;
1051
1052
  declare function listChangeSlugs(root: string, opts?: {
1052
1053
  includeArchived?: boolean;
1053
1054
  }): Promise<string[]>;
package/dist/index.js CHANGED
@@ -1255,8 +1255,8 @@ async function loadSpecs(sddDir) {
1255
1255
  }
1256
1256
  return out;
1257
1257
  }
1258
- async function loadChange(root, slug) {
1259
- const dir = path4.join(root, SDD_DIR, "changes", slug);
1258
+ async function loadChange(root, slug, relDir) {
1259
+ const dir = path4.join(root, SDD_DIR, "changes", relDir ?? slug);
1260
1260
  const diagnostics = [];
1261
1261
  const change = { slug, dir, diagnostics };
1262
1262
  const metaFile = path4.join(dir, "meta.yaml");
@@ -1318,7 +1318,14 @@ async function loadWorkspace(root) {
1318
1318
  changes.push(change);
1319
1319
  diagnostics.push(...change.diagnostics);
1320
1320
  }
1321
- return { workspace: { root, sddDir, specs, changes, diagnostics }, config };
1321
+ const archived = [];
1322
+ const archivedDir = path4.join(sddDir, "changes", "archive");
1323
+ if (await isDirectory(archivedDir)) {
1324
+ for (const entry of await listDirs(archivedDir)) {
1325
+ archived.push(await loadChange(root, entry.replace(/^\d{4}-\d{2}-/, ""), path4.join("archive", entry)));
1326
+ }
1327
+ }
1328
+ return { workspace: { root, sddDir, specs, changes, archived, diagnostics }, config };
1322
1329
  }
1323
1330
  async function ensureSddDirs(sddDir) {
1324
1331
  const created = [];
@@ -3073,7 +3080,7 @@ async function generatePresentation(opts) {
3073
3080
  language,
3074
3081
  labels,
3075
3082
  title: change.meta?.title ?? change.slug,
3076
- domain: change.meta?.domain ?? "\xE2\u20AC\u201D",
3083
+ domain: change.meta?.domain ?? "\u2014",
3077
3084
  lane: change.meta?.lane ?? config.lanes.default,
3078
3085
  project: config.project.name,
3079
3086
  version: change.delta.sectionsFound.length,
@@ -3100,7 +3107,7 @@ async function copyMockups(root, change, destDir) {
3100
3107
  for (const screen of manifest.screens) {
3101
3108
  const src = path12.join(dir, screen.file);
3102
3109
  if (!await exists(src)) {
3103
- diagnostics.push(diag("ATLAS-PRESENT-002", "warning", `El mockup ${screen.file} no existe y no se incluir\xC3\xA1`, { path: src }));
3110
+ diagnostics.push(diag("ATLAS-PRESENT-002", "warning", `El mockup ${screen.file} no existe y no se incluir\xE1`, { path: src }));
3104
3111
  continue;
3105
3112
  }
3106
3113
  await copyFile(src, path12.join(destDir, screen.file));
@@ -3151,15 +3158,15 @@ function labelsFor(language) {
3151
3158
  return {
3152
3159
  kicker: "Propuesta",
3153
3160
  summary: "Resumen de negocio",
3154
- criteria: "Criterios de aceptaci\xC3\xB3n",
3161
+ criteria: "Criterios de aceptaci\xF3n",
3155
3162
  requirements: "Requisitos y escenarios",
3156
3163
  mockups: "Mockups",
3157
- approve: "Aprobaci\xC3\xB3n",
3164
+ approve: "Aprobaci\xF3n",
3158
3165
  approveText: "Esta propuesta se aprueba firmando la spec (hash + autor). Cualquier cambio posterior invalida la firma.",
3159
3166
  command: "Comando",
3160
3167
  hash: "Hash",
3161
3168
  generated: "Generado",
3162
- noProposal: "La propuesta est\xC3\xA1 vac\xC3\xADa.",
3169
+ noProposal: "La propuesta est\xE1 vac\xEDa.",
3163
3170
  added: "agregado",
3164
3171
  modified: "modificado",
3165
3172
  scenario: "Escenario",
@@ -3214,13 +3221,13 @@ footer { color: var(--muted); font-size: 13px; text-align:center; }
3214
3221
  function page(input) {
3215
3222
  const l = input.labels;
3216
3223
  const reqHtml = input.requirements.map(({ req, kind }) => {
3217
- const rules = req.rules.map((r) => `<li><code>${esc(r.id)}</code> \xE2\u20AC\u201D ${inline(r.text)}</li>`).join("");
3224
+ const rules = req.rules.map((r) => `<li><code>${esc(r.id)}</code> \u2014 ${inline(r.text)}</li>`).join("");
3218
3225
  const scenarios = req.scenarios.map((s) => {
3219
3226
  const when = s.when.map((w) => `<div class="when">CUANDO ${inline(w)}</div>`).join("");
3220
3227
  const then = s.then.map((t) => `<div class="then">ENTONCES ${inline(t)}</div>`).join("");
3221
- return `<div class="scenario"><h4>${esc(s.id)} \xE2\u20AC\u201D ${esc(s.title)}</h4>${when}${then}</div>`;
3228
+ return `<div class="scenario"><h4>${esc(s.id)} \u2014 ${esc(s.title)}</h4>${when}${then}</div>`;
3222
3229
  }).join("");
3223
- return `<div class="req"><h3>${esc(req.id)} \xE2\u20AC\u201D ${esc(req.title)}<span class="badge">${kind === "added" ? l.added : l.modified}</span></h3><p>${inline(req.prose)}</p>${rules ? `<ul class="rules">${rules}</ul>` : ""}${scenarios}</div>`;
3230
+ return `<div class="req"><h3>${esc(req.id)} \u2014 ${esc(req.title)}<span class="badge">${kind === "added" ? l.added : l.modified}</span></h3><p>${inline(req.prose)}</p>${rules ? `<ul class="rules">${rules}</ul>` : ""}${scenarios}</div>`;
3224
3231
  }).join("");
3225
3232
  const criteriaRows = input.requirements.flatMap(({ req }) => req.scenarios).map((s) => {
3226
3233
  const status = input.evidence.get(s.id);
@@ -3229,7 +3236,7 @@ function page(input) {
3229
3236
  return `<tr><td><code>${esc(s.id)}</code></td><td>${esc(s.title)}</td><td><span class="pill ${cls}">${esc(label)}</span></td></tr>`;
3230
3237
  }).join("");
3231
3238
  const mockupHtml = input.mockups.length === 0 ? `<p><em>${l.noMockups}</em></p>` : `<div class="mockups">${input.mockups.map(
3232
- (m) => `<div class="mockup ${m.platform === "mobile" ? "phone" : ""}"><header>${esc(m.title)} \xE2\u20AC\u201D ${esc(m.file)}</header><iframe src="${esc(m.file)}" loading="lazy" title="${esc(m.title)}"></iframe></div>`
3239
+ (m) => `<div class="mockup ${m.platform === "mobile" ? "phone" : ""}"><header>${esc(m.title)} \u2014 ${esc(m.file)}</header><iframe src="${esc(m.file)}" loading="lazy" title="${esc(m.title)}"></iframe></div>`
3233
3240
  ).join("")}</div>`;
3234
3241
  const shotsHtml = input.screenshots.length === 0 ? "" : `<h3>${l.screenshots}</h3><div class="grid-shots">${input.screenshots.map((s) => `<img src="${esc(s)}" alt="${esc(s)}" loading="lazy">`).join("")}</div>`;
3235
3242
  return `<!doctype html>
@@ -3237,15 +3244,15 @@ function page(input) {
3237
3244
  <head>
3238
3245
  <meta charset="utf-8">
3239
3246
  <meta name="viewport" content="width=device-width, initial-scale=1">
3240
- <title>${esc(l.kicker)} \xE2\u20AC\u201D ${esc(input.title)}</title>
3247
+ <title>${esc(l.kicker)} \u2014 ${esc(input.title)}</title>
3241
3248
  <style>${CSS}</style>
3242
3249
  </head>
3243
3250
  <body>
3244
3251
  <div class="wrap">
3245
3252
  <header class="hero">
3246
- <p class="kicker">${esc(l.kicker)} \xC2\xB7 ${esc(input.domain)} \xC2\xB7 ${esc(input.lane)}</p>
3253
+ <p class="kicker">${esc(l.kicker)} \xB7 ${esc(input.domain)} \xB7 ${esc(input.lane)}</p>
3247
3254
  <h1>${esc(input.title)}</h1>
3248
- <p class="meta">${esc(input.project)} \xC2\xB7 ${esc(l.hash)} ${esc(shortHash(input.hash))} \xC2\xB7 ${esc(l.generated)} ${esc(input.generatedAt)}</p>
3255
+ <p class="meta">${esc(input.project)} \xB7 ${esc(l.hash)} ${esc(shortHash(input.hash))} \xB7 ${esc(l.generated)} ${esc(input.generatedAt)}</p>
3249
3256
  </header>
3250
3257
 
3251
3258
  <section>
@@ -3275,7 +3282,7 @@ function page(input) {
3275
3282
  <p>${esc(l.command)}: <code>${esc(input.approveHint)}</code></p>
3276
3283
  </section>
3277
3284
 
3278
- <footer>SpecAtlas \xC2\xB7 ${esc(input.project)} \xC2\xB7 ${esc(input.generatedAt)}</footer>
3285
+ <footer>SpecAtlas \xB7 ${esc(input.project)} \xB7 ${esc(input.generatedAt)}</footer>
3279
3286
  </div>
3280
3287
  </body>
3281
3288
  </html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@specatlas/core",
3
- "version": "0.1.1",
4
- "description": "Kernel determinista de SpecAtlas: parsing, validación, trazabilidad, olas y ciclo de vida",
3
+ "version": "0.1.3",
4
+ "description": "Kernel determinista de SpecAtlas: parsing, validación, trazabilidad, olas y ciclo de vida",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",