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.
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
11041
|
-
updatedAt: now
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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: ${(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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.
|
|
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.
|
|
43
|
+
"@specatlas/core": "0.1.12"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"typecheck": "tsc --noEmit",
|