@tacuchi/agent-workflow-cli 12.3.0 → 12.5.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.
- package/dist/application/humanize-es.d.ts +18 -0
- package/dist/application/humanize-es.d.ts.map +1 -0
- package/dist/application/humanize-es.js +71 -0
- package/dist/application/humanize-es.js.map +1 -0
- package/dist/application/session-close-service.d.ts.map +1 -1
- package/dist/application/session-close-service.js +4 -1
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.d.ts +2 -0
- package/dist/application/session-create-service.d.ts.map +1 -1
- package/dist/application/session-create-service.js +26 -3
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/status-service.d.ts +74 -0
- package/dist/application/status-service.d.ts.map +1 -0
- package/dist/application/status-service.js +336 -0
- package/dist/application/status-service.js.map +1 -0
- package/dist/application/templates/session.d.ts +4 -2
- package/dist/application/templates/session.d.ts.map +1 -1
- package/dist/application/templates/session.js +15 -11
- package/dist/application/templates/session.js.map +1 -1
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +10 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/help-groups.js +1 -1
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/main.js +2 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/tui/data/workflow-content.d.ts.map +1 -1
- package/dist/cli/tui/data/workflow-content.js +2 -1
- package/dist/cli/tui/data/workflow-content.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/README.md +2 -2
- package/skills/w/SKILL.md +6 -5
- package/skills/w/artifacts/README.md +8 -7
- package/skills/w/artifacts/artifacts-core/BACKLOG.md +5 -8
- package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +14 -13
- package/skills/w/artifacts/artifacts-core/SESSION.md +10 -11
- package/skills/w/artifacts/artifacts-core/TASKS.md +4 -4
- package/skills/w/artifacts/artifacts-dev/DECISION.md +3 -3
- package/skills/w/artifacts/artifacts-dev/TECHNICAL-NOTE.md +14 -14
- package/skills/w/artifacts/artifacts-research/ANALYSIS-FILE.md +14 -27
- package/skills/w/artifacts/artifacts-research/CONCLUSIONS.md +10 -13
- package/skills/w/commands/README.md +9 -6
- package/skills/w/commands/export-diagrams.md +2 -6
- package/skills/w/commands/export-manuals.md +2 -6
- package/skills/w/commands/export-reports.md +2 -6
- package/skills/w/commands/export-scripts.md +2 -6
- package/skills/w/commands/plan-exec.md +11 -10
- package/skills/w/commands/plan-new.md +15 -12
- package/skills/w/commands/quick.md +7 -6
- package/skills/w/commands/spec-new.md +18 -7
- package/skills/w/commands/spec-refine.md +14 -11
- package/skills/w/commands/status.md +50 -0
- package/skills/w/loops/README.md +12 -11
- package/skills/w/loops/plan-exec-loop/SKILL.md +54 -52
- package/skills/w/loops/plan-new-loop/SKILL.md +28 -24
- package/skills/w/loops/quick-loop/SKILL.md +20 -19
- package/skills/w/loops/spec-refine-loop/SKILL.md +85 -63
- package/skills/w/roles/README.md +1 -1
- package/skills/w/roles/research/SKILL.md +21 -81
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spanish relative-date humanizer (es-PE). Pure, no I/O, no clock — `now` is
|
|
3
|
+
* injected so callers (and tests) stay deterministic. Mirrors the `options.now`
|
|
4
|
+
* precedent in `lock-service` / `checkpoint-service`.
|
|
5
|
+
*
|
|
6
|
+
* Produces friendly, direct strings: "recién", "hace 5 minutos", "hoy en la
|
|
7
|
+
* mañana", "ayer en la tarde", "hace 3 días", "la semana pasada", "hace 2
|
|
8
|
+
* semanas", "hace un mes", "hace 4 meses", "hace un año", "hace 2 años".
|
|
9
|
+
*
|
|
10
|
+
* Day/week deltas are computed over LOCAL calendar dates (not raw 24h spans) so
|
|
11
|
+
* "ayer" is a calendar concept; month/year deltas use calendar arithmetic.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Humanize `then` relative to `now` in Spanish. Future / clock-skew (`then`
|
|
15
|
+
* ahead of `now`) clamps to "recién" — never emits a future phrase.
|
|
16
|
+
*/
|
|
17
|
+
export declare function humanizeRelativeEs(then: Date, now: Date): string;
|
|
18
|
+
//# sourceMappingURL=humanize-es.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"humanize-es.d.ts","sourceRoot":"","sources":["../../src/application/humanize-es.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8BH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAuBhE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spanish relative-date humanizer (es-PE). Pure, no I/O, no clock — `now` is
|
|
3
|
+
* injected so callers (and tests) stay deterministic. Mirrors the `options.now`
|
|
4
|
+
* precedent in `lock-service` / `checkpoint-service`.
|
|
5
|
+
*
|
|
6
|
+
* Produces friendly, direct strings: "recién", "hace 5 minutos", "hoy en la
|
|
7
|
+
* mañana", "ayer en la tarde", "hace 3 días", "la semana pasada", "hace 2
|
|
8
|
+
* semanas", "hace un mes", "hace 4 meses", "hace un año", "hace 2 años".
|
|
9
|
+
*
|
|
10
|
+
* Day/week deltas are computed over LOCAL calendar dates (not raw 24h spans) so
|
|
11
|
+
* "ayer" is a calendar concept; month/year deltas use calendar arithmetic.
|
|
12
|
+
*/
|
|
13
|
+
const MS_PER_MINUTE = 60_000;
|
|
14
|
+
/** Time-of-day band of `d`'s local clock. */
|
|
15
|
+
function franja(d) {
|
|
16
|
+
const h = d.getHours();
|
|
17
|
+
if (h < 12)
|
|
18
|
+
return "mañana";
|
|
19
|
+
if (h < 19)
|
|
20
|
+
return "tarde";
|
|
21
|
+
return "noche";
|
|
22
|
+
}
|
|
23
|
+
/** Local midnight of `d`. */
|
|
24
|
+
function startOfDay(d) {
|
|
25
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
26
|
+
}
|
|
27
|
+
/** Whole-day difference between the local calendar dates of `then` and `now`. */
|
|
28
|
+
function calendarDayDiff(then, now) {
|
|
29
|
+
const ms = startOfDay(now).getTime() - startOfDay(then).getTime();
|
|
30
|
+
return Math.round(ms / 86_400_000);
|
|
31
|
+
}
|
|
32
|
+
/** Calendar-month difference (>= 0), accounting for day-of-month. */
|
|
33
|
+
function calendarMonthDiff(then, now) {
|
|
34
|
+
let m = (now.getFullYear() - then.getFullYear()) * 12 + (now.getMonth() - then.getMonth());
|
|
35
|
+
if (now.getDate() < then.getDate())
|
|
36
|
+
m -= 1;
|
|
37
|
+
return Math.max(0, m);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Humanize `then` relative to `now` in Spanish. Future / clock-skew (`then`
|
|
41
|
+
* ahead of `now`) clamps to "recién" — never emits a future phrase.
|
|
42
|
+
*/
|
|
43
|
+
export function humanizeRelativeEs(then, now) {
|
|
44
|
+
const ms = now.getTime() - then.getTime();
|
|
45
|
+
// Just now / future skew.
|
|
46
|
+
if (ms < MS_PER_MINUTE)
|
|
47
|
+
return "recién";
|
|
48
|
+
// Minutes within the hour.
|
|
49
|
+
const minutes = Math.floor(ms / MS_PER_MINUTE);
|
|
50
|
+
if (minutes < 60)
|
|
51
|
+
return minutes === 1 ? "hace un minuto" : `hace ${minutes} minutos`;
|
|
52
|
+
const days = calendarDayDiff(then, now);
|
|
53
|
+
if (days === 0)
|
|
54
|
+
return `hoy en la ${franja(then)}`;
|
|
55
|
+
if (days === 1)
|
|
56
|
+
return `ayer en la ${franja(then)}`;
|
|
57
|
+
if (days <= 6)
|
|
58
|
+
return `hace ${days} días`;
|
|
59
|
+
if (days <= 13)
|
|
60
|
+
return "la semana pasada";
|
|
61
|
+
if (days <= 27)
|
|
62
|
+
return `hace ${Math.floor(days / 7)} semanas`;
|
|
63
|
+
const months = calendarMonthDiff(then, now);
|
|
64
|
+
if (months <= 1)
|
|
65
|
+
return "hace un mes";
|
|
66
|
+
if (months <= 11)
|
|
67
|
+
return `hace ${months} meses`;
|
|
68
|
+
const years = Math.floor(months / 12);
|
|
69
|
+
return years === 1 ? "hace un año" : `hace ${years} años`;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=humanize-es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"humanize-es.js","sourceRoot":"","sources":["../../src/application/humanize-es.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-close-service.d.ts","sourceRoot":"","sources":["../../src/application/session-close-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;AAIvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,sBAAsB,GAAG,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"session-close-service.d.ts","sourceRoot":"","sources":["../../src/application/session-close-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;AAIvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,sBAAsB,GAAG,iBAAiB,CAAC,CA8BrD"}
|
|
@@ -8,10 +8,13 @@ export async function runSessionClose(fs, env, paths, input) {
|
|
|
8
8
|
if (!session)
|
|
9
9
|
return { error: `Sesión no encontrada: ${input.code}` };
|
|
10
10
|
// Persist the durable artifacts in the session folder (they survive close).
|
|
11
|
+
// CHECKPOINT is a resume safety net (no-op when the loop already wrote one).
|
|
12
|
+
// BACKLOG is NOT fabricated here: the owning loop writes a real BACKLOG.md
|
|
13
|
+
// only when there is deferred/followup content, so close no longer creates
|
|
14
|
+
// an empty boilerplate file. `backlog_path` still reports the canonical path.
|
|
11
15
|
const checkpointPath = canonicalArtifactPath(session.path, "checkpoint");
|
|
12
16
|
const backlogPath = canonicalArtifactPath(session.path, "backlog");
|
|
13
17
|
await ensureFile(fs, checkpointPath, "# CHECKPOINT\n");
|
|
14
|
-
await ensureFile(fs, backlogPath, "# BACKLOG\n");
|
|
15
18
|
// Mark the session closed via the folder-local sentinel file.
|
|
16
19
|
// Sessions are internal/light: closing no longer touches the project block.
|
|
17
20
|
await fs.writeText(join(session.path, CLOSED_MARKER), "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-close-service.js","sourceRoot":"","sources":["../../src/application/session-close-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAyBtE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAkB,EAClB,GAAY,EACZ,KAAmB,EACnB,KAAwB;IAExB,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;IAEtE,4EAA4E;IAC5E,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACnE,MAAM,UAAU,CAAC,EAAE,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"session-close-service.js","sourceRoot":"","sources":["../../src/application/session-close-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAyBtE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAkB,EAClB,GAAY,EACZ,KAAmB,EACnB,KAAwB;IAExB,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;IAEtE,4EAA4E;IAC5E,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,8EAA8E;IAC9E,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACnE,MAAM,UAAU,CAAC,EAAE,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAEvD,8DAA8D;IAC9D,4EAA4E;IAC5E,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAuB;QACvC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE;QACtC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,IAAI;QACZ,eAAe,EAAE,cAAc;QAC/B,YAAY,EAAE,WAAW;KAC1B,CAAC;IACF,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,YAAY,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,EAAkB,EAAE,IAAY,EAAE,cAAsB;IAChF,IAAI,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO;IAClC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -12,6 +12,8 @@ export interface SessionCreateInput {
|
|
|
12
12
|
export interface SessionCreateRecordOutput {
|
|
13
13
|
type: SessionType;
|
|
14
14
|
name: string;
|
|
15
|
+
/** Global sequential number assigned by the CLI (zero-padded, e.g. "003"). */
|
|
16
|
+
number: string;
|
|
15
17
|
folder: string;
|
|
16
18
|
path: string;
|
|
17
19
|
session_path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-create-service.d.ts","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,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;AAMvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,yBAAyB,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"session-create-service.d.ts","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,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;AAMvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,yBAAyB,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,CAgCvD"}
|
|
@@ -22,6 +22,7 @@ export async function runSessionCreate(fs, _env, paths, input) {
|
|
|
22
22
|
const record = {
|
|
23
23
|
type,
|
|
24
24
|
name,
|
|
25
|
+
number: folderInfo.number,
|
|
25
26
|
folder: folderInfo.folder,
|
|
26
27
|
path: sessionPath,
|
|
27
28
|
session_path: sessionFilePath,
|
|
@@ -55,13 +56,35 @@ function validateInput(input) {
|
|
|
55
56
|
async function prepareSessionFolder(fs, paths, name) {
|
|
56
57
|
const sessionsDir = paths.cwdSessionsDir();
|
|
57
58
|
await fs.mkdirp(sessionsDir);
|
|
58
|
-
//
|
|
59
|
-
|
|
59
|
+
// The CLI owns the session number: a single global, sequential counter across
|
|
60
|
+
// ALL sessions in `.workflow/sessions/` (any type), so numbering never resets
|
|
61
|
+
// per type nor collides. Callers pass only the descriptor via `--name`; the
|
|
62
|
+
// `NNN-` prefix is assigned here. A descriptor that already carries a leading
|
|
63
|
+
// `NNN-` is normalized away first so the prefix can't double up.
|
|
64
|
+
const descriptor = name.replace(/^\d{3}-/, "");
|
|
65
|
+
const number = await nextSessionNumber(fs, sessionsDir);
|
|
66
|
+
const folder = `${number}-${descriptor}`;
|
|
60
67
|
const sessionPath = join(sessionsDir, folder);
|
|
61
68
|
if (await fs.exists(sessionPath)) {
|
|
62
69
|
return { error: `Ya existe ${sessionPath}` };
|
|
63
70
|
}
|
|
64
71
|
await fs.mkdirp(sessionPath);
|
|
65
|
-
return { folder, sessionPath, sessionsDir };
|
|
72
|
+
return { folder, number, sessionPath, sessionsDir };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Next global session number: scan `.workflow/sessions/` for any entry whose name
|
|
76
|
+
* starts with a 3-digit code and return max+1, zero-padded. Type-agnostic — one
|
|
77
|
+
* sequence for every session regardless of kind. Legacy `sessionNNN-…` folders
|
|
78
|
+
* (no leading digit) don't match and are ignored, so the new sequence starts fresh.
|
|
79
|
+
*/
|
|
80
|
+
async function nextSessionNumber(fs, sessionsDir) {
|
|
81
|
+
const entries = await fs.list(sessionsDir);
|
|
82
|
+
let max = 0;
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const m = entry.name.match(/^(\d{3})/);
|
|
85
|
+
if (m?.[1])
|
|
86
|
+
max = Math.max(max, Number.parseInt(m[1], 10));
|
|
87
|
+
}
|
|
88
|
+
return String(max + 1).padStart(3, "0");
|
|
66
89
|
}
|
|
67
90
|
//# sourceMappingURL=session-create-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-create-service.js","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"session-create-service.js","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { EnvPort } from "../ports/env.js";
|
|
2
|
+
import type { FileSystemPort } from "../ports/file-system.js";
|
|
3
|
+
import type { PathsService } from "./paths-service.js";
|
|
4
|
+
export interface StatusWorkspace {
|
|
5
|
+
name: string;
|
|
6
|
+
path: string;
|
|
7
|
+
/** `.<ns>/` present in the workspace root. */
|
|
8
|
+
initialized: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface StatusSpec {
|
|
11
|
+
file: string;
|
|
12
|
+
number: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
/** has `## Refinement decisions` AND `## Q&A traceability` */
|
|
15
|
+
refined: boolean;
|
|
16
|
+
open_questions: number;
|
|
17
|
+
date: string;
|
|
18
|
+
relative: string;
|
|
19
|
+
}
|
|
20
|
+
export interface StatusPlan {
|
|
21
|
+
file: string;
|
|
22
|
+
number: string;
|
|
23
|
+
slug: string;
|
|
24
|
+
tasks_total: number;
|
|
25
|
+
tasks_done: number;
|
|
26
|
+
progress_pct: number;
|
|
27
|
+
date: string;
|
|
28
|
+
relative: string;
|
|
29
|
+
}
|
|
30
|
+
export interface StatusSession {
|
|
31
|
+
code: string | null;
|
|
32
|
+
folder: string;
|
|
33
|
+
type: string | null;
|
|
34
|
+
summary: string;
|
|
35
|
+
date: string;
|
|
36
|
+
relative: string;
|
|
37
|
+
}
|
|
38
|
+
export type DiscardedKind = "deferred" | "excluded";
|
|
39
|
+
export interface StatusDiscarded {
|
|
40
|
+
source: string;
|
|
41
|
+
source_path: string;
|
|
42
|
+
kind: DiscardedKind;
|
|
43
|
+
text: string;
|
|
44
|
+
date: string;
|
|
45
|
+
relative: string;
|
|
46
|
+
}
|
|
47
|
+
export interface StatusOutput {
|
|
48
|
+
workspace: StatusWorkspace;
|
|
49
|
+
specs: StatusSpec[];
|
|
50
|
+
plans: StatusPlan[];
|
|
51
|
+
sessions: {
|
|
52
|
+
active: StatusSession[];
|
|
53
|
+
closed: StatusSession[];
|
|
54
|
+
};
|
|
55
|
+
discarded: StatusDiscarded[];
|
|
56
|
+
counts: {
|
|
57
|
+
specs: number;
|
|
58
|
+
specs_refined: number;
|
|
59
|
+
plans: number;
|
|
60
|
+
sessions_active: number;
|
|
61
|
+
sessions_closed: number;
|
|
62
|
+
discarded: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export interface StatusInput {
|
|
66
|
+
now?: Date;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Read-only whole-workspace status aggregator. Never throws on a reachable cwd:
|
|
70
|
+
* an uninitialized workspace returns `initialized:false` with empty collections;
|
|
71
|
+
* a single unreadable file is skipped rather than tanking the command.
|
|
72
|
+
*/
|
|
73
|
+
export declare function runStatusCommand(fs: FileSystemPort, env: EnvPort, paths: PathsService, input?: StatusInput): Promise<StatusOutput>;
|
|
74
|
+
//# sourceMappingURL=status-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-service.d.ts","sourceRoot":"","sources":["../../src/application/status-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAK9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,MAAM,EAAE,aAAa,EAAE,CAAC;QACxB,MAAM,EAAE,aAAa,EAAE,CAAC;KACzB,CAAC;IACF,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,GAAE,WAAgB,GACtB,OAAO,CAAC,YAAY,CAAC,CAyBvB"}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { basename, join } from "node:path";
|
|
2
|
+
import { humanizeRelativeEs } from "./humanize-es.js";
|
|
3
|
+
import { firstNonEmptyLine } from "./markdown.js";
|
|
4
|
+
import { parseProjectBlock } from "./parsers/project-block.js";
|
|
5
|
+
import { parseTasks } from "./parsers/tasks.js";
|
|
6
|
+
import { findArtifact } from "./session-artifacts.js";
|
|
7
|
+
import { SessionsService } from "./sessions-service.js";
|
|
8
|
+
/**
|
|
9
|
+
* Read-only whole-workspace status aggregator. Never throws on a reachable cwd:
|
|
10
|
+
* an uninitialized workspace returns `initialized:false` with empty collections;
|
|
11
|
+
* a single unreadable file is skipped rather than tanking the command.
|
|
12
|
+
*/
|
|
13
|
+
export async function runStatusCommand(fs, env, paths, input = {}) {
|
|
14
|
+
const now = input.now ?? new Date();
|
|
15
|
+
const cwd = paths.workspaceDir();
|
|
16
|
+
const workspace = await readWorkspace(fs, paths, cwd);
|
|
17
|
+
const specs = await readSpecs(fs, cwd, now);
|
|
18
|
+
const plans = await readPlans(fs, cwd, now);
|
|
19
|
+
const { active, closed, folders } = await readSessions(fs, env, paths, now);
|
|
20
|
+
const discarded = await readDiscarded(fs, folders, cwd, now);
|
|
21
|
+
return {
|
|
22
|
+
workspace,
|
|
23
|
+
specs,
|
|
24
|
+
plans,
|
|
25
|
+
sessions: { active, closed },
|
|
26
|
+
discarded,
|
|
27
|
+
counts: {
|
|
28
|
+
specs: specs.length,
|
|
29
|
+
specs_refined: specs.filter((s) => s.refined).length,
|
|
30
|
+
plans: plans.length,
|
|
31
|
+
sessions_active: active.length,
|
|
32
|
+
sessions_closed: closed.length,
|
|
33
|
+
discarded: discarded.length,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// ── workspace ──────────────────────────────────────────────────────────────
|
|
38
|
+
async function readWorkspace(fs, paths, cwd) {
|
|
39
|
+
let name = basename(cwd);
|
|
40
|
+
for (const file of [join(cwd, "CLAUDE.md"), join(cwd, "AGENTS.md")]) {
|
|
41
|
+
try {
|
|
42
|
+
if (!(await fs.exists(file)))
|
|
43
|
+
continue;
|
|
44
|
+
const block = parseProjectBlock(await fs.readText(file), paths.blockMarkers());
|
|
45
|
+
if (block?.proyecto) {
|
|
46
|
+
name = block.proyecto;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// ignore; fall back to basename
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const initialized = await safeExists(fs, paths.cwdRoot());
|
|
55
|
+
return { name, path: cwd, initialized };
|
|
56
|
+
}
|
|
57
|
+
// ── specs ──────────────────────────────────────────────────────────────────
|
|
58
|
+
const SPEC_RE = /^(\d{3})-spec(?:-(.+))?\.md$/i;
|
|
59
|
+
async function readSpecs(fs, cwd, now) {
|
|
60
|
+
const dir = join(cwd, "docs", "specs");
|
|
61
|
+
const files = await listMarkdown(fs, dir, SPEC_RE);
|
|
62
|
+
const deduped = dedupeRefined(files);
|
|
63
|
+
const out = [];
|
|
64
|
+
for (const f of deduped) {
|
|
65
|
+
try {
|
|
66
|
+
const text = await fs.readText(f.path);
|
|
67
|
+
const refined = parseMdSectionLoose(text, "Refinement decisions") !== undefined &&
|
|
68
|
+
parseMdSectionLoose(text, "Q&A traceability") !== undefined;
|
|
69
|
+
const ts = await resolveTimestamp(fs, f.path, undefined, now);
|
|
70
|
+
out.push({
|
|
71
|
+
file: relFromCwd(f.path, cwd),
|
|
72
|
+
number: f.number,
|
|
73
|
+
slug: f.slug,
|
|
74
|
+
refined,
|
|
75
|
+
open_questions: countOpenQuestions(text),
|
|
76
|
+
date: ts.date,
|
|
77
|
+
relative: ts.relative,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// skip unreadable spec
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return sortByNumber(out);
|
|
85
|
+
}
|
|
86
|
+
// ── plans ────────────────────────────────────────────────────────────────────
|
|
87
|
+
const PLAN_RE = /^(\d{3})-plan(?:-(.+))?\.md$/i;
|
|
88
|
+
async function readPlans(fs, cwd, now) {
|
|
89
|
+
const dir = join(cwd, "docs", "plans");
|
|
90
|
+
const files = await listMarkdown(fs, dir, PLAN_RE);
|
|
91
|
+
const out = [];
|
|
92
|
+
for (const f of files) {
|
|
93
|
+
try {
|
|
94
|
+
const text = await fs.readText(f.path);
|
|
95
|
+
const t = parseTasks(text);
|
|
96
|
+
const ts = await resolveTimestamp(fs, f.path, undefined, now);
|
|
97
|
+
out.push({
|
|
98
|
+
file: relFromCwd(f.path, cwd),
|
|
99
|
+
number: f.number,
|
|
100
|
+
slug: f.slug,
|
|
101
|
+
tasks_total: t.total,
|
|
102
|
+
tasks_done: t.closed,
|
|
103
|
+
progress_pct: t.progress_pct,
|
|
104
|
+
date: ts.date,
|
|
105
|
+
relative: ts.relative,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// skip unreadable plan
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return sortByNumber(out);
|
|
113
|
+
}
|
|
114
|
+
async function readSessions(fs, env, paths, now) {
|
|
115
|
+
const active = [];
|
|
116
|
+
const closed = [];
|
|
117
|
+
const folders = [];
|
|
118
|
+
let list;
|
|
119
|
+
try {
|
|
120
|
+
list = await new SessionsService(fs, env, paths).list({ state: "all", verbose: true });
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return { active, closed, folders };
|
|
124
|
+
}
|
|
125
|
+
for (const s of list.sessions) {
|
|
126
|
+
folders.push({ code: s.code, folder: s.folder, path: s.path });
|
|
127
|
+
const primary = (await findArtifact(s.path, "session", fs)) ?? s.path;
|
|
128
|
+
const ts = await resolveTimestamp(fs, primary, s.date, now);
|
|
129
|
+
const entry = {
|
|
130
|
+
code: s.code,
|
|
131
|
+
folder: s.folder,
|
|
132
|
+
type: s.type ?? null,
|
|
133
|
+
summary: s.summary ?? s.folder,
|
|
134
|
+
date: ts.date,
|
|
135
|
+
relative: ts.relative,
|
|
136
|
+
};
|
|
137
|
+
(s.state === "closed" ? closed : active).push(entry);
|
|
138
|
+
}
|
|
139
|
+
return { active, closed, folders };
|
|
140
|
+
}
|
|
141
|
+
// ── discarded ──────────────────────────────────────────────────────────────────
|
|
142
|
+
async function readDiscarded(fs, folders, cwd, now) {
|
|
143
|
+
const out = [];
|
|
144
|
+
for (const f of folders) {
|
|
145
|
+
await collectDiscarded(fs, f, "backlog", "Deferred", "deferred", cwd, now, out);
|
|
146
|
+
await collectDiscarded(fs, f, "checkpoint", "Excluded", "excluded", cwd, now, out);
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
async function collectDiscarded(fs, ref, artifact, heading, kind, cwd, now, out) {
|
|
151
|
+
try {
|
|
152
|
+
const path = await findArtifact(ref.path, artifact, fs);
|
|
153
|
+
if (!path)
|
|
154
|
+
return;
|
|
155
|
+
const items = listItems(parseMdSectionLoose(await fs.readText(path), heading));
|
|
156
|
+
if (items.length === 0)
|
|
157
|
+
return;
|
|
158
|
+
const ts = await resolveTimestamp(fs, path, undefined, now);
|
|
159
|
+
for (const text of items) {
|
|
160
|
+
out.push({
|
|
161
|
+
source: ref.code ?? ref.folder,
|
|
162
|
+
source_path: relFromCwd(ref.path, cwd),
|
|
163
|
+
kind,
|
|
164
|
+
text,
|
|
165
|
+
date: ts.date,
|
|
166
|
+
relative: ts.relative,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// skip unreadable artifact
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function listMarkdown(fs, dir, re) {
|
|
175
|
+
if (!(await safeExists(fs, dir)))
|
|
176
|
+
return [];
|
|
177
|
+
let entries;
|
|
178
|
+
try {
|
|
179
|
+
entries = await fs.list(dir);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
const out = [];
|
|
185
|
+
for (const e of entries) {
|
|
186
|
+
if (e.type !== "file")
|
|
187
|
+
continue;
|
|
188
|
+
const m = re.exec(e.name);
|
|
189
|
+
if (!m?.[1])
|
|
190
|
+
continue;
|
|
191
|
+
out.push({ path: e.path, number: m[1], slug: m[2] ?? "" });
|
|
192
|
+
}
|
|
193
|
+
return out;
|
|
194
|
+
}
|
|
195
|
+
/** Drop legacy `NNN-spec-refined.md` when another file shares its number. */
|
|
196
|
+
function dedupeRefined(files) {
|
|
197
|
+
const byNumber = new Map();
|
|
198
|
+
for (const f of files) {
|
|
199
|
+
const group = byNumber.get(f.number) ?? [];
|
|
200
|
+
group.push(f);
|
|
201
|
+
byNumber.set(f.number, group);
|
|
202
|
+
}
|
|
203
|
+
const out = [];
|
|
204
|
+
for (const group of byNumber.values()) {
|
|
205
|
+
const isRefined = (f) => /(^|-)refined$/i.test(f.slug);
|
|
206
|
+
const nonRefined = group.filter((f) => !isRefined(f));
|
|
207
|
+
const chosen = nonRefined.length > 0 ? nonRefined : group;
|
|
208
|
+
chosen.sort((a, b) => a.path.localeCompare(b.path));
|
|
209
|
+
const first = chosen[0];
|
|
210
|
+
if (first)
|
|
211
|
+
out.push(first);
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
function sortByNumber(items) {
|
|
216
|
+
return items.sort((a, b) => a.number.localeCompare(b.number) || a.file.localeCompare(b.file));
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Best-available timestamp for `relative`/`date`: full-precision fs mtime if the
|
|
220
|
+
* path stats, else a date-only fallback projected to local noon, else `now`.
|
|
221
|
+
*/
|
|
222
|
+
async function resolveTimestamp(fs, path, fallbackDateOnly, now) {
|
|
223
|
+
let mtime = null;
|
|
224
|
+
try {
|
|
225
|
+
mtime = (await fs.stat(path)).mtime;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
mtime = null;
|
|
229
|
+
}
|
|
230
|
+
const when = mtime ?? dateOnlyToNoon(fallbackDateOnly) ?? now;
|
|
231
|
+
return {
|
|
232
|
+
date: formatDateOnly(when),
|
|
233
|
+
relative: humanizeRelativeEs(when, now),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function dateOnlyToNoon(dateStr) {
|
|
237
|
+
if (!dateStr)
|
|
238
|
+
return null;
|
|
239
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(dateStr);
|
|
240
|
+
if (!m)
|
|
241
|
+
return null;
|
|
242
|
+
return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]), 12, 0, 0);
|
|
243
|
+
}
|
|
244
|
+
function formatDateOnly(date) {
|
|
245
|
+
const year = date.getFullYear();
|
|
246
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
247
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
248
|
+
return `${year}-${month}-${day}`;
|
|
249
|
+
}
|
|
250
|
+
async function safeExists(fs, path) {
|
|
251
|
+
try {
|
|
252
|
+
return await fs.exists(path);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function relFromCwd(path, cwd) {
|
|
259
|
+
const prefix = cwd.endsWith("/") ? cwd : `${cwd}/`;
|
|
260
|
+
return path.startsWith(prefix) ? path.slice(prefix.length) : path;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Like `parseMdSection` but tolerant of the template heading annotations
|
|
264
|
+
* (`## Excluded (list):`, `## Deferred (text):`) — matches a heading whose name
|
|
265
|
+
* starts with `heading`, ignoring a trailing `(...)` / `:`. Kept local so
|
|
266
|
+
* `markdown.ts` stays stable; needed for legacy artifacts that still carry the
|
|
267
|
+
* suffix.
|
|
268
|
+
*/
|
|
269
|
+
function parseMdSectionLoose(text, heading) {
|
|
270
|
+
const target = heading.trim().toLowerCase();
|
|
271
|
+
const lines = text.split("\n");
|
|
272
|
+
const headingRe = /^(#{1,6})\s+(.+?)\s*$/;
|
|
273
|
+
let captureFrom = null;
|
|
274
|
+
let captureLevel = 0;
|
|
275
|
+
for (let i = 0; i < lines.length; i++) {
|
|
276
|
+
const line = lines[i];
|
|
277
|
+
if (line === undefined)
|
|
278
|
+
continue;
|
|
279
|
+
const match = line.match(headingRe);
|
|
280
|
+
if (!match?.[1] || !match[2])
|
|
281
|
+
continue;
|
|
282
|
+
const level = match[1].length;
|
|
283
|
+
const name = normalizeHeading(match[2]);
|
|
284
|
+
if (captureFrom === null) {
|
|
285
|
+
if (name === target) {
|
|
286
|
+
captureFrom = i + 1;
|
|
287
|
+
captureLevel = level;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else if (level <= captureLevel) {
|
|
291
|
+
return lines.slice(captureFrom, i).join("\n").trim();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (captureFrom !== null)
|
|
295
|
+
return lines.slice(captureFrom).join("\n").trim();
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
function normalizeHeading(raw) {
|
|
299
|
+
return raw
|
|
300
|
+
.trim()
|
|
301
|
+
.toLowerCase()
|
|
302
|
+
.replace(/\s*\([^)]*\)\s*:?\s*$/, "")
|
|
303
|
+
.replace(/:\s*$/, "")
|
|
304
|
+
.trim();
|
|
305
|
+
}
|
|
306
|
+
/** List-item lines of a section, dropping the `List of …` template placeholder. */
|
|
307
|
+
function listItems(section) {
|
|
308
|
+
if (!section)
|
|
309
|
+
return [];
|
|
310
|
+
const out = [];
|
|
311
|
+
for (const raw of section.split("\n")) {
|
|
312
|
+
const m = /^\s*[-*]\s+(.+?)\s*$/.exec(raw);
|
|
313
|
+
if (!m?.[1])
|
|
314
|
+
continue;
|
|
315
|
+
const text = m[1].trim();
|
|
316
|
+
if (text.length === 0)
|
|
317
|
+
continue;
|
|
318
|
+
if (/^list of\b/i.test(text))
|
|
319
|
+
continue; // template placeholder
|
|
320
|
+
out.push(text);
|
|
321
|
+
}
|
|
322
|
+
return out;
|
|
323
|
+
}
|
|
324
|
+
function countOpenQuestions(text) {
|
|
325
|
+
const sec = parseMdSectionLoose(text, "Open questions");
|
|
326
|
+
if (!sec)
|
|
327
|
+
return 0;
|
|
328
|
+
const first = (firstNonEmptyLine(sec) ?? "").toLowerCase();
|
|
329
|
+
if (first.length === 0)
|
|
330
|
+
return 0;
|
|
331
|
+
if (/^[-*]?\s*(none|ninguna|ninguno|n\/a|—|-)\.?$/.test(first))
|
|
332
|
+
return 0;
|
|
333
|
+
const bullets = sec.split("\n").filter((l) => /^\s*[-*]\s+\S/.test(l)).length;
|
|
334
|
+
return bullets > 0 ? bullets : 1;
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=status-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-service.js","sourceRoot":"","sources":["../../src/application/status-service.ts"],"names":[],"mappings":"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"}
|