specatlas 0.1.13 → 0.1.15

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  signApproval
4
- } from "./chunk-X4FIHYOJ.js";
4
+ } from "./chunk-HYN75DTZ.js";
5
5
  import "./chunk-DKFIPJ74.js";
6
6
  export {
7
7
  signApproval
package/dist/bin.js CHANGED
@@ -3,12 +3,16 @@ import {
3
3
  artifactHash,
4
4
  countBySeverity,
5
5
  diag,
6
+ localCompact,
7
+ localDate,
8
+ localMonth,
9
+ localStamp,
6
10
  parseApprovals,
7
11
  parseChangeMeta,
8
12
  sha256,
9
13
  shortHash,
10
14
  signApproval
11
- } from "./chunk-X4FIHYOJ.js";
15
+ } from "./chunk-HYN75DTZ.js";
12
16
  import {
13
17
  __commonJS,
14
18
  __toESM,
@@ -10837,7 +10841,7 @@ async function approveFromGithub(opts) {
10837
10841
  if (!by) {
10838
10842
  return { approved: false, label, issueNumber: number, diagnostics: [diag("ATLAS-GH-011", "error", "No se pudo determinar qui\xE9n aprueba (--by ni `gh api user`)")] };
10839
10843
  }
10840
- const { signApproval: signApproval2 } = await import("./approvals-4QHIT7F6-JAI5IHNX.js");
10844
+ const { signApproval: signApproval2 } = await import("./approvals-2PO6223I-54L7NGZ5.js");
10841
10845
  const signed = await signApproval2({
10842
10846
  root: opts.root,
10843
10847
  artifact: path5.posix.join("changes", opts.slug, "spec.md"),
@@ -10987,7 +10991,7 @@ ${exec.stderr}`);
10987
10991
  scenario,
10988
10992
  method,
10989
10993
  result,
10990
- date: (opts.now ?? /* @__PURE__ */ new Date()).toISOString(),
10994
+ date: localStamp(opts.now),
10991
10995
  by: opts.by.trim(),
10992
10996
  line: 0
10993
10997
  };
@@ -11024,7 +11028,7 @@ ${yaml2}
11024
11028
  return returned;
11025
11029
  }
11026
11030
  function generateRunId(now = /* @__PURE__ */ new Date()) {
11027
- const iso = now.toISOString().replace(/[-:T]/g, "").slice(0, 14);
11031
+ const iso = localCompact(now);
11028
11032
  return `${iso.slice(0, 8)}-${iso.slice(8, 14)}-${randomBytes(3).toString("hex")}`;
11029
11033
  }
11030
11034
  function runsDir(root) {
@@ -11037,8 +11041,8 @@ async function createRun(root, slug, phase, inputs, now = /* @__PURE__ */ new Da
11037
11041
  slug,
11038
11042
  phase,
11039
11043
  status: "active",
11040
- startedAt: now.toISOString(),
11041
- updatedAt: now.toISOString()
11044
+ startedAt: localStamp(now),
11045
+ updatedAt: localStamp(now)
11042
11046
  };
11043
11047
  if (inputs) state.inputs = inputs;
11044
11048
  const dir = path7.join(runsDir(root), runId);
@@ -11050,7 +11054,7 @@ async function createRun(root, slug, phase, inputs, now = /* @__PURE__ */ new Da
11050
11054
  return state;
11051
11055
  }
11052
11056
  async function appendRunEvent(root, runId, type, data, now = /* @__PURE__ */ new Date()) {
11053
- const event = { eventId: randomBytes(4).toString("hex"), at: now.toISOString(), type };
11057
+ const event = { eventId: randomBytes(4).toString("hex"), at: localStamp(now), type };
11054
11058
  if (data) event.data = data;
11055
11059
  const file = path7.join(runsDir(root), runId, "events.jsonl");
11056
11060
  const previous = await readTextIfExists(file) ?? "";
@@ -11064,7 +11068,7 @@ async function updateRunStatus(root, runId, status, now = /* @__PURE__ */ new Da
11064
11068
  if (raw === void 0) return;
11065
11069
  const state = JSON.parse(raw);
11066
11070
  state.status = status;
11067
- state.updatedAt = now.toISOString();
11071
+ state.updatedAt = localStamp(now);
11068
11072
  await writeText(file, `${JSON.stringify(state, null, 2)}
11069
11073
  `);
11070
11074
  }
@@ -11289,7 +11293,7 @@ async function writeMockupPlan(root, slug, plan, now = /* @__PURE__ */ new Date(
11289
11293
  if (await exists(file)) return file;
11290
11294
  const doc = {
11291
11295
  schema_version: 1,
11292
- generated_at: now.toISOString(),
11296
+ generated_at: localStamp(now),
11293
11297
  platform: plan.platform,
11294
11298
  screens: plan.screens.map((s) => ({ id: s.id, title: s.title, file: s.file, illustrates: s.illustrates, states: s.states, breakpoints: s.breakpoints }))
11295
11299
  };
@@ -11305,7 +11309,7 @@ async function writeMockupManifest(root, slug, plan, inputsHash, now = /* @__PUR
11305
11309
  level: "hifi",
11306
11310
  platform: plan.platform,
11307
11311
  inputs_hash: inputsHash,
11308
- generated_at: now.toISOString(),
11312
+ generated_at: localStamp(now),
11309
11313
  screens: plan.screens.map((s) => ({ id: s.id, title: s.title, file: s.file, illustrates: s.illustrates, states: s.states, breakpoints: s.breakpoints })),
11310
11314
  screenshots: []
11311
11315
  };
@@ -11747,7 +11751,7 @@ async function runAnalyze(opts) {
11747
11751
  if (packs) result.packs = packs;
11748
11752
  if (opts.write !== false) {
11749
11753
  const file = path10.join(change.dir, "analyze.md");
11750
- await writeText(file, renderAnalyze(change, result, (opts.now ?? /* @__PURE__ */ new Date()).toISOString()));
11754
+ await writeText(file, renderAnalyze(change, result, localStamp(opts.now)));
11751
11755
  result.path = file;
11752
11756
  }
11753
11757
  return result;
@@ -11886,7 +11890,7 @@ async function collectMetrics(root, now = /* @__PURE__ */ new Date()) {
11886
11890
  archived: archivedEntries.length
11887
11891
  };
11888
11892
  return {
11889
- generatedAt: now.toISOString(),
11893
+ generatedAt: localStamp(now),
11890
11894
  project: config.project.name,
11891
11895
  root: resolved,
11892
11896
  changes,
@@ -11941,7 +11945,7 @@ async function generatePresentation(opts) {
11941
11945
  project: config.project.name,
11942
11946
  version: change.delta.sectionsFound.length,
11943
11947
  hash,
11944
- generatedAt: now.toISOString(),
11948
+ generatedAt: localStamp(now),
11945
11949
  proposalHtml: proposalBody ? renderMarkdown2(proposalBody) : `<p><em>${labels.noProposal}</em></p>`,
11946
11950
  requirements: change.delta ? [...change.delta.added.map((r) => ({ req: r, kind: "added" })), ...change.delta.modified.map((r) => ({ req: r, kind: "modified" }))] : [],
11947
11951
  evidence: new Map((change.verify?.evidence ?? []).map((e) => [e.scenario, e.result])),
@@ -12320,7 +12324,7 @@ function baselineSpec(domain, files) {
12320
12324
  lines.push(`domain: ${domain}`);
12321
12325
  lines.push(`title: ${title}`);
12322
12326
  lines.push("version: 1");
12323
- lines.push(`updated: ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`);
12327
+ lines.push(`updated: ${localDate()}`);
12324
12328
  lines.push("---");
12325
12329
  lines.push("");
12326
12330
  lines.push(`# ${title}`);
@@ -12341,7 +12345,7 @@ function adoptReport(input) {
12341
12345
  lines.push(es ? "# Adopci\xF3n (brownfield)" : "# Adoption (brownfield)");
12342
12346
  lines.push("");
12343
12347
  lines.push(es ? `- Proyecto: ${input.config.project.name}` : `- Project: ${input.config.project.name}`);
12344
- lines.push(es ? `- Generado: ${input.now.toISOString()}` : `- Generated: ${input.now.toISOString()}`);
12348
+ lines.push(es ? `- Generado: ${localStamp(input.now)}` : `- Generated: ${localStamp(input.now)}`);
12345
12349
  lines.push(es ? `- Archivos de c\xF3digo inventariados: ${input.files} (de ${input.inventoried} archivos totales)` : `- Inventoried source files: ${input.files} (of ${input.inventoried} total files)`);
12346
12350
  if (input.detection) lines.push(es ? `- Stack detectado: ${input.detection.name} (${input.detection.score} puntos)` : `- Detected stack: ${input.detection.name} (${input.detection.score})`);
12347
12351
  lines.push("");
@@ -12393,7 +12397,7 @@ async function initWorkspace(opts) {
12393
12397
  created.push(path14.join(sddDir, "glossary.md"));
12394
12398
  const detected = await detectIfPossible(root, opts.profilesDir);
12395
12399
  if (detected) {
12396
- const yaml2 = detectionToYaml(detected, (opts.now ?? /* @__PURE__ */ new Date()).toISOString());
12400
+ const yaml2 = detectionToYaml(detected, localStamp(opts.now));
12397
12401
  await writeText(path14.join(sddDir, "profiles", "detected.yaml"), yaml2);
12398
12402
  created.push(path14.join(sddDir, "profiles", "detected.yaml"));
12399
12403
  if (detected.best) {
@@ -12469,7 +12473,7 @@ async function createChange(opts) {
12469
12473
  title,
12470
12474
  domain,
12471
12475
  lane,
12472
- created: (opts.now ?? /* @__PURE__ */ new Date()).toISOString().slice(0, 10)
12476
+ created: localDate(opts.now)
12473
12477
  };
12474
12478
  await ensureDir(dir);
12475
12479
  const templates = templatesFor(language);
@@ -12576,7 +12580,7 @@ async function archiveChange(opts) {
12576
12580
  return { slug: opts.slug, fold: emptyFold, diagnostics, dryRun: opts.dryRun ?? false };
12577
12581
  }
12578
12582
  const nowFix = opts.now ?? /* @__PURE__ */ new Date();
12579
- const targetFix = path16.join(root, ".sdd", "changes", "archive", `${nowFix.toISOString().slice(0, 7)}-${opts.slug}`);
12583
+ const targetFix = path16.join(root, ".sdd", "changes", "archive", `${localMonth(nowFix)}-${opts.slug}`);
12580
12584
  if (await exists(targetFix)) {
12581
12585
  diagnostics.push(diag("ATLAS-ARCH-002", "error", `Ya existe un cambio archivado en ${targetFix}`, { path: targetFix }));
12582
12586
  return { slug: opts.slug, fold: emptyFold, diagnostics, dryRun: opts.dryRun ?? false };
@@ -12617,7 +12621,7 @@ version: 0
12617
12621
  title: fm.data["title"] ?? change.meta.title ?? domain,
12618
12622
  owner: fm.data["owner"],
12619
12623
  version: version + 1,
12620
- updated: now.toISOString().slice(0, 10)
12624
+ updated: localDate(now)
12621
12625
  };
12622
12626
  for (const key of Object.keys(nextFm)) if (nextFm[key] === void 0) delete nextFm[key];
12623
12627
  const body = fold.content.replace(/^[\r\n]+/, "").trimEnd() + "\n";
@@ -12626,7 +12630,7 @@ ${Object.entries(nextFm).map(([k, v]) => `${k}: ${String(v)}`).join("\n")}
12626
12630
  ---
12627
12631
 
12628
12632
  ${body}`;
12629
- const month = now.toISOString().slice(0, 7);
12633
+ const month = localMonth(now);
12630
12634
  const archiveDir = path16.join(root, ".sdd", "changes", "archive");
12631
12635
  const target = path16.join(archiveDir, `${month}-${opts.slug}`);
12632
12636
  if (await exists(target)) {
@@ -5,12 +5,33 @@ import {
5
5
  writeText
6
6
  } from "./chunk-DKFIPJ74.js";
7
7
 
8
- // ../core/dist/chunk-LMJURGRU.js
8
+ // ../core/dist/chunk-WF6H5ITI.js
9
9
  import path from "path";
10
10
  import { stringify as stringifyYaml } from "yaml";
11
11
  import { createHash } from "crypto";
12
12
  import { parse as parseYaml } from "yaml";
13
13
  import { z } from "zod";
14
+ function pad(value, length = 2) {
15
+ return String(value).padStart(length, "0");
16
+ }
17
+ function localDate(date = /* @__PURE__ */ new Date()) {
18
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
19
+ }
20
+ function localMonth(date = /* @__PURE__ */ new Date()) {
21
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}`;
22
+ }
23
+ function localOffset(date = /* @__PURE__ */ new Date()) {
24
+ const offset = -date.getTimezoneOffset();
25
+ const sign = offset >= 0 ? "+" : "-";
26
+ const absolute = Math.abs(offset);
27
+ return `${sign}${pad(Math.floor(absolute / 60))}:${pad(absolute % 60)}`;
28
+ }
29
+ function localStamp(date = /* @__PURE__ */ new Date()) {
30
+ return `${localDate(date)} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())} ${localOffset(date)}`;
31
+ }
32
+ function localCompact(date = /* @__PURE__ */ new Date()) {
33
+ return `${localDate(date).replace(/-/g, "")}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
34
+ }
14
35
  function diag(code, severity, message, opts = {}) {
15
36
  const d = { code, severity, message };
16
37
  if (opts.path !== void 0) d.path = opts.path;
@@ -189,7 +210,7 @@ async function signApproval(opts) {
189
210
  artifact: rel,
190
211
  artifactHash: artifactHash(content),
191
212
  approvedBy: opts.by.trim(),
192
- approvedAt: now.toISOString(),
213
+ approvedAt: localStamp(now),
193
214
  channel: opts.channel ?? "cli"
194
215
  };
195
216
  if (opts.note) approval.note = opts.note;
@@ -216,6 +237,10 @@ async function signApproval(opts) {
216
237
  }
217
238
 
218
239
  export {
240
+ localDate,
241
+ localMonth,
242
+ localStamp,
243
+ localCompact,
219
244
  diag,
220
245
  countBySeverity,
221
246
  sha256,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specatlas",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "SpecAtlas: kernel determinista de Spec-Driven Development (CLI)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@specatlas/adapters": "0.1.1",
43
- "@specatlas/core": "0.1.10"
43
+ "@specatlas/core": "0.1.12"
44
44
  },
45
45
  "scripts": {
46
46
  "typecheck": "tsc --noEmit",