@xenos1996/usa 2.4.0 → 2.6.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/README.md +2 -2
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +2 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/providers.d.ts +56 -0
- package/dist/agent/providers.d.ts.map +1 -0
- package/dist/agent/providers.js +334 -0
- package/dist/agent/providers.js.map +1 -0
- package/dist/agent/types.d.ts +103 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +19 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +115 -2
- package/dist/cli.js.map +1 -1
- package/dist/engine/categories.d.ts +45 -0
- package/dist/engine/categories.d.ts.map +1 -0
- package/dist/engine/categories.js +148 -0
- package/dist/engine/categories.js.map +1 -0
- package/dist/engine/test-evidence.d.ts +84 -0
- package/dist/engine/test-evidence.d.ts.map +1 -0
- package/dist/engine/test-evidence.js +154 -0
- package/dist/engine/test-evidence.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/live/runner.d.ts +34 -0
- package/dist/live/runner.d.ts.map +1 -0
- package/dist/live/runner.js +220 -0
- package/dist/live/runner.js.map +1 -0
- package/dist/live/session.d.ts +25 -0
- package/dist/live/session.d.ts.map +1 -0
- package/dist/live/session.js +100 -0
- package/dist/live/session.js.map +1 -0
- package/dist/live/types.d.ts +31 -0
- package/dist/live/types.d.ts.map +1 -0
- package/dist/live/types.js +9 -0
- package/dist/live/types.js.map +1 -0
- package/package.json +1 -1
- package/rules/categories.yaml +124 -0
- package/rules/core/testing-assurance.yaml +240 -0
- package/rules/index.yaml +1 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic test-evidence analyzers (testing-assurance evidence slice).
|
|
3
|
+
*
|
|
4
|
+
* DOCTRINE (ADR-0032): these are pure deterministic heuristics that count
|
|
5
|
+
* observable signals in file paths and file contents. Interpretation stays
|
|
6
|
+
* agent-side. Nothing here asserts quality, coverage semantics, or assurance —
|
|
7
|
+
* a count of patterns is presence evidence only, never a verdict.
|
|
8
|
+
*
|
|
9
|
+
* The module performs no I/O: callers supply paths, contents, inventories,
|
|
10
|
+
* and timestamps explicitly. It changes no scores and wires into no report.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Default pattern table (documented contract):
|
|
14
|
+
*
|
|
15
|
+
* - unit: `__tests__`, `*.unit.*`, `*.spec.*`, `test_*`
|
|
16
|
+
* - integration: `*integration*`, `*contract*`, `*pact*`
|
|
17
|
+
* - system: `*system*`, `*acceptance*`
|
|
18
|
+
* - e2e: `*e2e*`, `*end-to-end*`, `*.e2e.*`
|
|
19
|
+
* - else: `unknown`
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_PATTERNS = {
|
|
22
|
+
unit: ['__tests__', '*.unit.*', '*.spec.*', 'test_*'],
|
|
23
|
+
integration: ['*integration*', '*contract*', '*pact*'],
|
|
24
|
+
system: ['*system*', '*acceptance*'],
|
|
25
|
+
e2e: ['*e2e*', '*end-to-end*', '*.e2e.*'],
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Match precedence, narrowest scope first. A path matching several levels
|
|
29
|
+
* (e.g. `e2e/login.spec.ts`) is classified by the earliest level here.
|
|
30
|
+
* This is an arbitrary tie-break, documented so it cannot surprise.
|
|
31
|
+
*/
|
|
32
|
+
const LEVEL_PRECEDENCE = [
|
|
33
|
+
'e2e',
|
|
34
|
+
'system',
|
|
35
|
+
'integration',
|
|
36
|
+
'unit',
|
|
37
|
+
];
|
|
38
|
+
/** Escape a literal so it can be embedded in a RegExp source. */
|
|
39
|
+
function escapeRegExp(literal) {
|
|
40
|
+
return literal.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
|
|
41
|
+
}
|
|
42
|
+
/** Convert a `*`-glob to an unanchored, case-insensitive RegExp (substring match). */
|
|
43
|
+
function globToRegExp(glob) {
|
|
44
|
+
return new RegExp(glob.split('*').map(escapeRegExp).join('.*'), 'i');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Classify a test file path into a level. Returns `unknown` when no
|
|
48
|
+
* pattern matches. Counts as a naming signal only — it says nothing about
|
|
49
|
+
* what the file actually exercises.
|
|
50
|
+
*/
|
|
51
|
+
export function classifyTestFile(filePath, patterns) {
|
|
52
|
+
const table = {
|
|
53
|
+
...DEFAULT_PATTERNS,
|
|
54
|
+
...patterns,
|
|
55
|
+
};
|
|
56
|
+
for (const level of LEVEL_PRECEDENCE) {
|
|
57
|
+
if (table[level].some((glob) => globToRegExp(glob).test(filePath))) {
|
|
58
|
+
return level;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return 'unknown';
|
|
62
|
+
}
|
|
63
|
+
/** Count files per level. The result always carries all five keys. */
|
|
64
|
+
export function inventoryTests(files, patterns) {
|
|
65
|
+
const inventory = {
|
|
66
|
+
unit: 0,
|
|
67
|
+
integration: 0,
|
|
68
|
+
system: 0,
|
|
69
|
+
e2e: 0,
|
|
70
|
+
unknown: 0,
|
|
71
|
+
};
|
|
72
|
+
for (const file of files) {
|
|
73
|
+
inventory[classifyTestFile(file, patterns)] += 1;
|
|
74
|
+
}
|
|
75
|
+
return inventory;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Signal patterns (documented contract — each counts literal occurrences):
|
|
79
|
+
*
|
|
80
|
+
* - failureAssertions: `toThrow|assert\.throws|rejects|assert\.rejects`
|
|
81
|
+
* - mockUsages: `jest\.mock|vi\.mock|sinon|mockReturnValue|mockResolvedValue|Mock`
|
|
82
|
+
* - focusedMarkers: `describe\.only|it\.only|test\.only|fit\(|fdescribe\(`
|
|
83
|
+
* - skippedMarkers: `describe\.skip|it\.skip|test\.skip|xit\(|xdescribe\(`
|
|
84
|
+
*
|
|
85
|
+
* A high mock count does not prove over-mocking; a focused marker is an
|
|
86
|
+
* isolation signal, not a failure. Interpretation stays agent-side.
|
|
87
|
+
*/
|
|
88
|
+
const SIGNAL_PATTERNS = {
|
|
89
|
+
failureAssertions: /toThrow|assert\.throws|rejects|assert\.rejects/g,
|
|
90
|
+
mockUsages: /jest\.mock|vi\.mock|sinon|mockReturnValue|mockResolvedValue|Mock/g,
|
|
91
|
+
focusedMarkers: /describe\.only|it\.only|test\.only|fit\(|fdescribe\(/g,
|
|
92
|
+
skippedMarkers: /describe\.skip|it\.skip|test\.skip|xit\(|xdescribe\(/g,
|
|
93
|
+
};
|
|
94
|
+
/** Count global regex matches (0 when there are none). */
|
|
95
|
+
function countMatches(content, pattern) {
|
|
96
|
+
const matches = content.match(pattern);
|
|
97
|
+
return matches === null ? 0 : matches.length;
|
|
98
|
+
}
|
|
99
|
+
/** Count assertion/marker signals in file content. Pure string scan. */
|
|
100
|
+
export function assertionSignals(content) {
|
|
101
|
+
return {
|
|
102
|
+
failureAssertions: countMatches(content, SIGNAL_PATTERNS.failureAssertions),
|
|
103
|
+
mockUsages: countMatches(content, SIGNAL_PATTERNS.mockUsages),
|
|
104
|
+
focusedMarkers: countMatches(content, SIGNAL_PATTERNS.focusedMarkers),
|
|
105
|
+
skippedMarkers: countMatches(content, SIGNAL_PATTERNS.skippedMarkers),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Share of the inventory held by system+e2e above which the shape is
|
|
110
|
+
* labelled `top-heavy`. Strictly greater-than: exactly 30% is not top-heavy.
|
|
111
|
+
*/
|
|
112
|
+
export const TOP_HEAVY_SHARE = 0.3;
|
|
113
|
+
/**
|
|
114
|
+
* Label the shape of a level inventory. THE PYRAMID IS A HEURISTIC, NOT A
|
|
115
|
+
* LAW: these labels describe count proportions only and assert nothing about
|
|
116
|
+
* whether the suite is adequate, fast, or trustworthy.
|
|
117
|
+
*
|
|
118
|
+
* Documented rules: all counts zero → `untested`; system+e2e share strictly
|
|
119
|
+
* above TOP_HEAVY_SHARE → `top-heavy`; no integration tests while unit tests
|
|
120
|
+
* exist → `no-middle`; otherwise → `balanced` (no flag). `unknown` files
|
|
121
|
+
* count toward the total but toward no level. Rule order is part of the
|
|
122
|
+
* contract: `untested` beats `top-heavy` beats `no-middle` beats `balanced`.
|
|
123
|
+
*/
|
|
124
|
+
export function pyramidAssessment(inventory) {
|
|
125
|
+
const total = inventory.unit + inventory.integration + inventory.system + inventory.e2e + inventory.unknown;
|
|
126
|
+
if (total === 0) {
|
|
127
|
+
return { shape: 'untested', flag: 'untested' };
|
|
128
|
+
}
|
|
129
|
+
if ((inventory.e2e + inventory.system) / total > TOP_HEAVY_SHARE) {
|
|
130
|
+
return { shape: 'top-heavy', flag: 'top-heavy' };
|
|
131
|
+
}
|
|
132
|
+
if (inventory.integration === 0 && inventory.unit > 0) {
|
|
133
|
+
return { shape: 'no-middle', flag: 'no-middle' };
|
|
134
|
+
}
|
|
135
|
+
return { shape: 'balanced' };
|
|
136
|
+
}
|
|
137
|
+
/** Milliseconds in a day; the unit of `ageDays`. */
|
|
138
|
+
export const MS_PER_DAY = 86_400_000;
|
|
139
|
+
/**
|
|
140
|
+
* Compare an evidence-artifact timestamp against HEAD time, purely on the
|
|
141
|
+
* explicit arguments (no clock reads). `ageDays` is fractional and may be
|
|
142
|
+
* negative. `stale` is true when the artifact predates HEAD. Non-finite
|
|
143
|
+
* inputs are a time paradox and fail closed: `stale` true, `ageDays` NaN.
|
|
144
|
+
* Staleness is a timestamp ordering only — it says nothing about whether
|
|
145
|
+
* the artifact's claims still hold.
|
|
146
|
+
*/
|
|
147
|
+
export function freshnessCheck(artifactMtimeMs, headTimeMs) {
|
|
148
|
+
if (!Number.isFinite(artifactMtimeMs) || !Number.isFinite(headTimeMs)) {
|
|
149
|
+
return { stale: true, ageDays: NaN };
|
|
150
|
+
}
|
|
151
|
+
const ageDays = (artifactMtimeMs - headTimeMs) / MS_PER_DAY;
|
|
152
|
+
return { stale: ageDays < 0, ageDays };
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=test-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-evidence.js","sourceRoot":"","sources":["../../src/engine/test-evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoD;IAC/E,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC;IACrD,WAAW,EAAE,CAAC,eAAe,EAAE,YAAY,EAAE,QAAQ,CAAC;IACtD,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,GAAG,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,CAAC;CAC1C,CAAC;AAEF;;;;GAIG;AACH,MAAM,gBAAgB,GAAyC;IAC7D,KAAK;IACL,QAAQ;IACR,aAAa;IACb,MAAM;CACP,CAAC;AAEF,iEAAiE;AACjE,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,sFAAsF;AACtF,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,QAAwB;IACzE,MAAM,KAAK,GAAoD;QAC7D,GAAG,gBAAgB;QACnB,GAAG,QAAQ;KACZ,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACnE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAC5B,KAAe,EACf,QAAwB;IAExB,MAAM,SAAS,GAA8B;QAC3C,IAAI,EAAE,CAAC;QACP,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,OAAO,EAAE,CAAC;KACX,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAUD;;;;;;;;;;GAUG;AACH,MAAM,eAAe,GAA2C;IAC9D,iBAAiB,EAAE,iDAAiD;IACpE,UAAU,EAAE,mEAAmE;IAC/E,cAAc,EAAE,uDAAuD;IACvE,cAAc,EAAE,uDAAuD;CACxE,CAAC;AAEF,0DAA0D;AAC1D,SAAS,YAAY,CAAC,OAAe,EAAE,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;AAC/C,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO;QACL,iBAAiB,EAAE,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,iBAAiB,CAAC;QAC3E,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC;QAC7D,cAAc,EAAE,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,cAAc,CAAC;QACrE,cAAc,EAAE,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,cAAc,CAAC;KACtE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AAOnC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAoC;IACpE,MAAM,KAAK,GACT,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC;IAChG,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,eAAe,EAAE,CAAC;QACjE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,SAAS,CAAC,WAAW,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;AAOrC;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,eAAuB,EAAE,UAAkB;IACxE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACvC,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;IAC5D,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,13 @@ export { buildSuppressionIndex, applySuppressions, unusedSuppressions, describeS
|
|
|
14
14
|
export { automatabilityOf, ruleAutomatability, parseCatalogue, validateCatalogue, validateAutomatability, } from './engine/automatability.js';
|
|
15
15
|
export { buildReviewIndex, attachReviews, resolveActiveReviews, unusedReviews, describeReview, reviewAgeDays, reviewOverdueDays, isReviewStale, type ReviewIndex, type ReviewEntry, } from './engine/review.js';
|
|
16
16
|
export { loadCatalogues, catalogueOf, catalogueCoverage, type Catalogue, type CatalogueCoverage, } from './engine/catalogues.js';
|
|
17
|
+
export { loadCategories, categoryCoverage, type CategoryDef, type CategoryCoverage, type CategoryId, } from './engine/categories.js';
|
|
18
|
+
export { complete, listModels, loadProviderConfig, PROVIDER_PRESETS } from './agent/providers.js';
|
|
19
|
+
export type { ChatMessage, ChatRequest, ChatResult, ProviderPreset, ProviderOverrides, ResolvedConfig, ModelInfo, } from './agent/types.js';
|
|
20
|
+
export { initialSession, advance, renderTranscript } from './live/session.js';
|
|
21
|
+
export { runLiveSession, DETERMINISTIC_SKIP_PREFIX, type LiveSessionOptions, } from './live/runner.js';
|
|
22
|
+
export type { SessionState, SessionPhase, TranscriptEntry, TranscriptKind } from './live/types.js';
|
|
23
|
+
export { classifyTestFile, inventoryTests, assertionSignals, pyramidAssessment, freshnessCheck, DEFAULT_PATTERNS, TOP_HEAVY_SHARE, MS_PER_DAY, type TestLevel, type LevelPatterns, type AssertionSignals, type PyramidAssessment, type FreshnessResult, } from './engine/test-evidence.js';
|
|
17
24
|
export { renderMarkdown, parseTrailer, trailer } from './report/markdown.js';
|
|
18
25
|
export { renderJson, toJsonReport, JSON_SCHEMA, type JsonReport, type JsonFinding, } from './report/json.js';
|
|
19
26
|
export { renderSarif, toSarif, SARIF_VERSION, type SarifLog } from './report/sarif.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,11 @@ export { buildSuppressionIndex, applySuppressions, unusedSuppressions, describeS
|
|
|
14
14
|
export { automatabilityOf, ruleAutomatability, parseCatalogue, validateCatalogue, validateAutomatability, } from './engine/automatability.js';
|
|
15
15
|
export { buildReviewIndex, attachReviews, resolveActiveReviews, unusedReviews, describeReview, reviewAgeDays, reviewOverdueDays, isReviewStale, } from './engine/review.js';
|
|
16
16
|
export { loadCatalogues, catalogueOf, catalogueCoverage, } from './engine/catalogues.js';
|
|
17
|
+
export { loadCategories, categoryCoverage, } from './engine/categories.js';
|
|
18
|
+
export { complete, listModels, loadProviderConfig, PROVIDER_PRESETS } from './agent/providers.js';
|
|
19
|
+
export { initialSession, advance, renderTranscript } from './live/session.js';
|
|
20
|
+
export { runLiveSession, DETERMINISTIC_SKIP_PREFIX, } from './live/runner.js';
|
|
21
|
+
export { classifyTestFile, inventoryTests, assertionSignals, pyramidAssessment, freshnessCheck, DEFAULT_PATTERNS, TOP_HEAVY_SHARE, MS_PER_DAY, } from './engine/test-evidence.js';
|
|
17
22
|
export { renderMarkdown, parseTrailer, trailer } from './report/markdown.js';
|
|
18
23
|
export { renderJson, toJsonReport, JSON_SCHEMA, } from './report/json.js';
|
|
19
24
|
export { renderSarif, toSarif, SARIF_VERSION } from './report/sarif.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,GAIb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,aAAa,GAGd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,WAAW,EACX,iBAAiB,GAGlB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,GAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAiB,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtE,2EAA2E;AAC3E,2BAA2B;AAC3B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session runner — drives the deterministic phases with optional LLM
|
|
3
|
+
* turns behind an injectable `ChatFn`.
|
|
4
|
+
*
|
|
5
|
+
* Doctrine: the engine verifies, the model only proposes. Without a
|
|
6
|
+
* configured provider (`chat` undefined) every model turn prints a loud skip
|
|
7
|
+
* line and the session continues deterministically — conversation is lost,
|
|
8
|
+
* correctness never is. A throwing `chat` degrades the same way (loud line,
|
|
9
|
+
* deterministic continuation), never a crash.
|
|
10
|
+
*
|
|
11
|
+
* Read-only seam: foundation builders and `runAudit` are imported, never
|
|
12
|
+
* modified. Types for the LLM call come from `src/agent` only.
|
|
13
|
+
*/
|
|
14
|
+
import type { ChatRequest } from '../agent/types.js';
|
|
15
|
+
import type { AskFn, ChatFn, PrintFn } from './types.js';
|
|
16
|
+
export type { AskFn, ChatFn, PrintFn } from './types.js';
|
|
17
|
+
export type { ChatRequest };
|
|
18
|
+
/** Loud marker printed whenever a model turn is skipped (deterministic-only). */
|
|
19
|
+
export declare const DETERMINISTIC_SKIP_PREFIX = "LLM skipped (deterministic-only mode)";
|
|
20
|
+
export interface LiveSessionOptions {
|
|
21
|
+
dir: string;
|
|
22
|
+
ask: AskFn;
|
|
23
|
+
print: PrintFn;
|
|
24
|
+
chat?: ChatFn;
|
|
25
|
+
transcriptPath?: string;
|
|
26
|
+
provider?: string;
|
|
27
|
+
model?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Runs foundation → audit → triage → report → done.
|
|
31
|
+
* Exit codes mirror the CLI gate convention: 0 done, 2 broken input.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runLiveSession(opts: LiveSessionOptions): Promise<number>;
|
|
34
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/live/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAiC,MAAM,YAAY,CAAC;AAExF,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,iFAAiF;AACjF,eAAO,MAAM,yBAAyB,0CAA0C,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,KAAK,CAAC;IACX,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB9E"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session runner — drives the deterministic phases with optional LLM
|
|
3
|
+
* turns behind an injectable `ChatFn`.
|
|
4
|
+
*
|
|
5
|
+
* Doctrine: the engine verifies, the model only proposes. Without a
|
|
6
|
+
* configured provider (`chat` undefined) every model turn prints a loud skip
|
|
7
|
+
* line and the session continues deterministically — conversation is lost,
|
|
8
|
+
* correctness never is. A throwing `chat` degrades the same way (loud line,
|
|
9
|
+
* deterministic continuation), never a crash.
|
|
10
|
+
*
|
|
11
|
+
* Read-only seam: foundation builders and `runAudit` are imported, never
|
|
12
|
+
* modified. Types for the LLM call come from `src/agent` only.
|
|
13
|
+
*/
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { runAudit } from '../engine/audit.js';
|
|
17
|
+
import { renderMarkdown } from '../report/markdown.js';
|
|
18
|
+
import { INTERVIEW_QUESTIONS, applyInterviewAnswer, formatQuestionPrompt, } from '../foundation/interview.js';
|
|
19
|
+
import { defaultFoundation } from '../foundation/types.js';
|
|
20
|
+
import { sanitizeIntent } from '../foundation/loader.js';
|
|
21
|
+
import { advance, initialSession, renderTranscript } from './session.js';
|
|
22
|
+
/** Loud marker printed whenever a model turn is skipped (deterministic-only). */
|
|
23
|
+
export const DETERMINISTIC_SKIP_PREFIX = 'LLM skipped (deterministic-only mode)';
|
|
24
|
+
const SYSTEM_PROMPT = 'You are the USA live audit assistant. Propose, never decide.';
|
|
25
|
+
/** Triage walks at most this many UNKNOWN findings; the rest stay queued. */
|
|
26
|
+
const TRIAGE_CAP = 50;
|
|
27
|
+
/**
|
|
28
|
+
* Runs foundation → audit → triage → report → done.
|
|
29
|
+
* Exit codes mirror the CLI gate convention: 0 done, 2 broken input.
|
|
30
|
+
*/
|
|
31
|
+
export async function runLiveSession(opts) {
|
|
32
|
+
const dir = path.resolve(opts.dir);
|
|
33
|
+
if (!isUsableDir(dir)) {
|
|
34
|
+
opts.print(`live: target not found or not a directory: ${opts.dir}`);
|
|
35
|
+
return 2;
|
|
36
|
+
}
|
|
37
|
+
const ctx = { state: initialSession() };
|
|
38
|
+
let code = 0;
|
|
39
|
+
try {
|
|
40
|
+
await runFoundationStep(opts, ctx);
|
|
41
|
+
await runAuditStep(opts, ctx);
|
|
42
|
+
await runTriageStep(opts, ctx);
|
|
43
|
+
await runReportStep(opts, ctx);
|
|
44
|
+
ctx.state = advance(ctx.state, 'done');
|
|
45
|
+
opts.print('Live session complete.');
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
opts.print(`live: ${err.message}`);
|
|
49
|
+
code = 2;
|
|
50
|
+
}
|
|
51
|
+
if (opts.transcriptPath)
|
|
52
|
+
code = writeTranscript(opts, ctx, code);
|
|
53
|
+
return code;
|
|
54
|
+
}
|
|
55
|
+
function isUsableDir(dir) {
|
|
56
|
+
try {
|
|
57
|
+
return fs.statSync(dir).isDirectory();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Transcript is the artifact: always written at the end when requested. */
|
|
64
|
+
function writeTranscript(opts, ctx, code) {
|
|
65
|
+
try {
|
|
66
|
+
const file = path.resolve(opts.transcriptPath);
|
|
67
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
68
|
+
fs.writeFileSync(file, renderTranscript(ctx.state), 'utf8');
|
|
69
|
+
opts.print(`Transcript written to ${opts.transcriptPath}.`);
|
|
70
|
+
return code;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
opts.print(`live: cannot write transcript: ${err.message}`);
|
|
74
|
+
return 2;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function appendTool(ctx, text) {
|
|
78
|
+
const entry = { phase: ctx.state.phase, kind: 'tool', text };
|
|
79
|
+
ctx.state = { ...ctx.state, transcript: [...ctx.state.transcript, entry] };
|
|
80
|
+
}
|
|
81
|
+
/* --------------------------------------------------------------- model -- */
|
|
82
|
+
async function modelTurn(opts, ctx, tag, user) {
|
|
83
|
+
if (!opts.chat) {
|
|
84
|
+
const line = `${DETERMINISTIC_SKIP_PREFIX}: no provider configured — ` +
|
|
85
|
+
`continuing without model input (${tag}).`;
|
|
86
|
+
opts.print(line);
|
|
87
|
+
appendTool(ctx, line);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const req = {
|
|
91
|
+
provider: opts.provider ?? 'usa-live',
|
|
92
|
+
model: opts.model ?? 'usa-live',
|
|
93
|
+
messages: [
|
|
94
|
+
{ role: 'system', content: SYSTEM_PROMPT },
|
|
95
|
+
{ role: 'user', content: user },
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
try {
|
|
99
|
+
const res = await opts.chat(req);
|
|
100
|
+
opts.print(res.text);
|
|
101
|
+
const entry = { phase: ctx.state.phase, kind: 'model', text: res.text };
|
|
102
|
+
ctx.state = { ...ctx.state, transcript: [...ctx.state.transcript, entry] };
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const line = `LLM unavailable (${err.message}) — continuing deterministically (${tag}).`;
|
|
106
|
+
opts.print(line);
|
|
107
|
+
appendTool(ctx, line);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/* ---------------------------------------------------------- foundation -- */
|
|
111
|
+
async function runFoundationStep(opts, ctx) {
|
|
112
|
+
ctx.state = advance(ctx.state, 'foundation');
|
|
113
|
+
opts.print('Foundation: capturing project intent (empty answers keep defaults).');
|
|
114
|
+
let config = defaultFoundation(path.basename(path.resolve(opts.dir)) || 'project');
|
|
115
|
+
for (const question of INTERVIEW_QUESTIONS) {
|
|
116
|
+
const raw = await opts.ask(formatQuestionPrompt(question, config));
|
|
117
|
+
if (raw === null) {
|
|
118
|
+
opts.print('(EOF — keeping defaults for the remaining questions.)');
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
config = await applyWithRetries(opts, question, config, raw);
|
|
122
|
+
}
|
|
123
|
+
const facts = intentFacts(config);
|
|
124
|
+
ctx.state = { ...ctx.state, facts: [...ctx.state.facts, ...facts] };
|
|
125
|
+
const summary = `Foundation captured: ${facts.length > 0 ? facts.join(', ') : '(no usable intents)'}.`;
|
|
126
|
+
opts.print(summary);
|
|
127
|
+
appendTool(ctx, summary);
|
|
128
|
+
await modelTurn(opts, ctx, 'foundation', `[foundation] facts: ${facts.join(', ') || '(none)'}.`);
|
|
129
|
+
}
|
|
130
|
+
/** Intent entries that sanitize become `intent:<value>` facts; the rest assert nothing. */
|
|
131
|
+
function intentFacts(config) {
|
|
132
|
+
const facts = [];
|
|
133
|
+
for (const intent of config.project.intents) {
|
|
134
|
+
const flag = sanitizeIntent(intent);
|
|
135
|
+
if (flag !== undefined)
|
|
136
|
+
facts.push(flag);
|
|
137
|
+
}
|
|
138
|
+
return facts;
|
|
139
|
+
}
|
|
140
|
+
/** Invalid answers re-prompt (bounded); then the default stands, loudly. */
|
|
141
|
+
async function applyWithRetries(opts, question, config, firstRaw) {
|
|
142
|
+
let raw = firstRaw;
|
|
143
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
144
|
+
try {
|
|
145
|
+
return applyInterviewAnswer(config, question.id, raw);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
opts.print(err.message);
|
|
149
|
+
}
|
|
150
|
+
const retry = await opts.ask(formatQuestionPrompt(question, config));
|
|
151
|
+
if (retry === null)
|
|
152
|
+
return config;
|
|
153
|
+
raw = retry;
|
|
154
|
+
}
|
|
155
|
+
opts.print(`Keeping the default for ${question.id} after repeated invalid answers.`);
|
|
156
|
+
return config;
|
|
157
|
+
}
|
|
158
|
+
/* --------------------------------------------------------------- audit -- */
|
|
159
|
+
async function runAuditStep(opts, ctx) {
|
|
160
|
+
ctx.state = advance(ctx.state, 'audit');
|
|
161
|
+
const { report, warnings, profile } = runAudit({ target: path.resolve(opts.dir) });
|
|
162
|
+
for (const warning of warnings)
|
|
163
|
+
opts.print(`warning: ${warning}`);
|
|
164
|
+
ctx.report = report;
|
|
165
|
+
ctx.profile = profile;
|
|
166
|
+
const summary = auditSummary(report);
|
|
167
|
+
opts.print(summary);
|
|
168
|
+
appendTool(ctx, summary);
|
|
169
|
+
await modelTurn(opts, ctx, 'audit', `[audit] ${summary}`);
|
|
170
|
+
}
|
|
171
|
+
function auditSummary(report) {
|
|
172
|
+
const unknown = report.score.counts.UNKNOWN ?? 0;
|
|
173
|
+
return (`Audit: ${report.score.overall}/100 — ${report.findings.length} finding(s), ` +
|
|
174
|
+
`${unknown} to review (${report.score.automationCoverage}% verified automatically).`);
|
|
175
|
+
}
|
|
176
|
+
/* -------------------------------------------------------------- triage -- */
|
|
177
|
+
async function runTriageStep(opts, ctx) {
|
|
178
|
+
ctx.state = advance(ctx.state, 'next');
|
|
179
|
+
const report = ctx.report;
|
|
180
|
+
const unknowns = report.findings.filter((f) => f.status === 'UNKNOWN');
|
|
181
|
+
const capped = unknowns.slice(0, TRIAGE_CAP);
|
|
182
|
+
let recorded = 0;
|
|
183
|
+
for (const finding of capped) {
|
|
184
|
+
const raw = await opts.ask(`Evidence for ${finding.ruleId} (${finding.title}) — file:line or empty to skip: `);
|
|
185
|
+
const answer = (raw ?? '').trim();
|
|
186
|
+
if (answer === '')
|
|
187
|
+
continue;
|
|
188
|
+
recorded++;
|
|
189
|
+
const entry = {
|
|
190
|
+
phase: ctx.state.phase,
|
|
191
|
+
kind: 'decision',
|
|
192
|
+
text: `${finding.ruleId}: ${answer}`,
|
|
193
|
+
};
|
|
194
|
+
ctx.state = {
|
|
195
|
+
...ctx.state,
|
|
196
|
+
transcript: [...ctx.state.transcript, entry],
|
|
197
|
+
facts: [...ctx.state.facts, `${finding.ruleId}@${answer}`],
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (unknowns.length > capped.length) {
|
|
201
|
+
appendTool(ctx, `${unknowns.length - capped.length} finding(s) left queued (triage cap ${TRIAGE_CAP}).`);
|
|
202
|
+
}
|
|
203
|
+
const summary = `Triage: ${recorded} evidence note(s) recorded over ${capped.length} finding(s) walked.`;
|
|
204
|
+
opts.print(summary);
|
|
205
|
+
appendTool(ctx, summary);
|
|
206
|
+
await modelTurn(opts, ctx, 'triage', `[triage] recorded ${recorded} evidence note(s).`);
|
|
207
|
+
}
|
|
208
|
+
/* -------------------------------------------------------------- report -- */
|
|
209
|
+
async function runReportStep(opts, ctx) {
|
|
210
|
+
ctx.state = advance(ctx.state, 'next');
|
|
211
|
+
const report = ctx.report;
|
|
212
|
+
const profile = ctx.profile;
|
|
213
|
+
const markdown = renderMarkdown(report, profile);
|
|
214
|
+
const summary = `Report rendered (${markdown.length} chars): ` +
|
|
215
|
+
`${report.score.overall}/100, ${report.findings.length} finding(s).`;
|
|
216
|
+
opts.print(summary);
|
|
217
|
+
appendTool(ctx, summary);
|
|
218
|
+
await modelTurn(opts, ctx, 'report', `[report] score ${report.score.overall}/100.`);
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/live/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAyB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMzE,iFAAiF;AACjF,MAAM,CAAC,MAAM,yBAAyB,GAAG,uCAAuC,CAAC;AAkBjF,MAAM,aAAa,GAAG,8DAA8D,CAAC;AAErF,6EAA6E;AAC7E,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwB;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAgB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,CAAC;IACrD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC;QACH,MAAM,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9B,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,SAAU,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,cAAc;QAAE,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,eAAe,CAAC,IAAwB,EAAE,GAAgB,EAAE,IAAY;IAC/E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAwB,CAAC,CAAC;QACzD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,IAAI,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAAgB,EAAE,IAAY;IAChD,MAAM,KAAK,GAAoB,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC9E,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,8EAA8E;AAE9E,KAAK,UAAU,SAAS,CACtB,IAAwB,EACxB,GAAgB,EAChB,GAAW,EACX,IAAY;IAEZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,GACR,GAAG,yBAAyB,6BAA6B;YACzD,mCAAmC,GAAG,IAAI,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAgB;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,UAAU;QACrC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,UAAU;QAC/B,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;YAC1C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;SAChC;KACF,CAAC;IACF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,KAAK,GAAoB,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACzF,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;IAC7E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,oBAAqB,GAAa,CAAC,OAAO,qCAAqC,GAAG,IAAI,CAAC;QACpG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,8EAA8E;AAE9E,KAAK,UAAU,iBAAiB,CAAC,IAAwB,EAAE,GAAgB;IACzE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;IAClF,IAAI,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC;IACnF,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACpE,MAAM;QACR,CAAC;QACD,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpE,MAAM,OAAO,GAAG,wBAAwB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,qBAAqB,GAAG,CAAC;IACvG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,uBAAuB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;AACnG,CAAC;AAED,2FAA2F;AAC3F,SAAS,WAAW,CAAC,MAAwB;IAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4EAA4E;AAC5E,KAAK,UAAU,gBAAgB,CAC7B,IAAwB,EACxB,QAA2B,EAC3B,MAAwB,EACxB,QAAgB;IAEhB,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,OAAO,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACrE,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAClC,GAAG,GAAG,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,2BAA2B,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;IACrF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAE9E,KAAK,UAAU,YAAY,CAAC,IAAwB,EAAE,GAAgB;IACpE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnF,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,IAAI,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IAClE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACpB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,OAAO,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,YAAY,CAAC,MAAmB;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;IACjD,OAAO,CACL,UAAU,MAAM,CAAC,KAAK,CAAC,OAAO,UAAU,MAAM,CAAC,QAAQ,CAAC,MAAM,eAAe;QAC7E,GAAG,OAAO,eAAe,MAAM,CAAC,KAAK,CAAC,kBAAkB,4BAA4B,CACrF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,KAAK,UAAU,aAAa,CAAC,IAAwB,EAAE,GAAgB;IACrE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAqB,CAAC;IACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC7C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CACxB,gBAAgB,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,KAAK,kCAAkC,CACnF,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,MAAM,KAAK,EAAE;YAAE,SAAS;QAC5B,QAAQ,EAAE,CAAC;QACX,MAAM,KAAK,GAAoB;YAC7B,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK;YACtB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;SACrC,CAAC;QACF,GAAG,CAAC,KAAK,GAAG;YACV,GAAG,GAAG,CAAC,KAAK;YACZ,UAAU,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC;YAC5C,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;SAC3D,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,UAAU,CACR,GAAG,EACH,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,uCAAuC,UAAU,IAAI,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,QAAQ,mCAAmC,MAAM,CAAC,MAAM,qBAAqB,CAAC;IACzG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,qBAAqB,QAAQ,oBAAoB,CAAC,CAAC;AAC1F,CAAC;AAED,8EAA8E;AAE9E,KAAK,UAAU,aAAa,CAAC,IAAwB,EAAE,GAAgB;IACrE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAqB,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,OAA0B,CAAC;IAC/C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,OAAO,GACX,oBAAoB,QAAQ,CAAC,MAAM,WAAW;QAC9C,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,CAAC,QAAQ,CAAC,MAAM,cAAc,CAAC;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,kBAAkB,MAAM,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session state machine — pure reducer plus deterministic rendering.
|
|
3
|
+
*
|
|
4
|
+
* The reducer never throws on user text: unknown input keeps the phase and
|
|
5
|
+
* appends a help line. Phase movement happens only on explicit commands
|
|
6
|
+
* (`foundation`, `audit`, `next`, `done`). Rendering carries no timestamps.
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionState } from './types.js';
|
|
9
|
+
/** Commands the reducer understands (matched case-insensitively, trimmed). */
|
|
10
|
+
export declare const LIVE_COMMANDS: readonly ["foundation", "audit", "next", "done"];
|
|
11
|
+
export declare const LIVE_HELP: string;
|
|
12
|
+
/** Fresh session: idle, silent, no facts. */
|
|
13
|
+
export declare function initialSession(): SessionState;
|
|
14
|
+
/**
|
|
15
|
+
* Advances the session on one line of user input. Pure: returns a new state,
|
|
16
|
+
* never mutates, never throws — even non-string input degrades to a help
|
|
17
|
+
* line in the current phase.
|
|
18
|
+
*/
|
|
19
|
+
export declare function advance(state: SessionState, input: unknown): SessionState;
|
|
20
|
+
/**
|
|
21
|
+
* Renders the transcript as Markdown. Deterministic: phase names, kinds, and
|
|
22
|
+
* texts only — no timestamps, no dates, no durations.
|
|
23
|
+
*/
|
|
24
|
+
export declare function renderTranscript(state: SessionState): string;
|
|
25
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/live/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAgB,YAAY,EAAmB,MAAM,YAAY,CAAC;AAE9E,8EAA8E;AAC9E,eAAO,MAAM,aAAa,kDAAmD,CAAC;AAW9E,eAAO,MAAM,SAAS,QAE2C,CAAC;AAElE,6CAA6C;AAC7C,wBAAgB,cAAc,IAAI,YAAY,CAE7C;AAkBD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,YAAY,CA6BzE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAiB5D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session state machine — pure reducer plus deterministic rendering.
|
|
3
|
+
*
|
|
4
|
+
* The reducer never throws on user text: unknown input keeps the phase and
|
|
5
|
+
* appends a help line. Phase movement happens only on explicit commands
|
|
6
|
+
* (`foundation`, `audit`, `next`, `done`). Rendering carries no timestamps.
|
|
7
|
+
*/
|
|
8
|
+
/** Commands the reducer understands (matched case-insensitively, trimmed). */
|
|
9
|
+
export const LIVE_COMMANDS = ['foundation', 'audit', 'next', 'done'];
|
|
10
|
+
/** One-step walk for `next`, from every non-terminal phase. */
|
|
11
|
+
const NEXT_PHASE = {
|
|
12
|
+
idle: 'foundation',
|
|
13
|
+
foundation: 'audit',
|
|
14
|
+
audit: 'triage',
|
|
15
|
+
triage: 'report',
|
|
16
|
+
report: 'done',
|
|
17
|
+
};
|
|
18
|
+
export const LIVE_HELP = 'Commands: foundation | audit | next | done — ' +
|
|
19
|
+
'any other text is recorded and the session stays where it is.';
|
|
20
|
+
/** Fresh session: idle, silent, no facts. */
|
|
21
|
+
export function initialSession() {
|
|
22
|
+
return { phase: 'idle', transcript: [], facts: [] };
|
|
23
|
+
}
|
|
24
|
+
function toolEntry(phase, text) {
|
|
25
|
+
return { phase, kind: 'tool', text };
|
|
26
|
+
}
|
|
27
|
+
function userEntry(phase, text) {
|
|
28
|
+
return { phase, kind: 'user', text };
|
|
29
|
+
}
|
|
30
|
+
function move(state, phase, note) {
|
|
31
|
+
return {
|
|
32
|
+
phase,
|
|
33
|
+
transcript: [...state.transcript, toolEntry(state.phase, note)],
|
|
34
|
+
facts: [...state.facts],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Advances the session on one line of user input. Pure: returns a new state,
|
|
39
|
+
* never mutates, never throws — even non-string input degrades to a help
|
|
40
|
+
* line in the current phase.
|
|
41
|
+
*/
|
|
42
|
+
export function advance(state, input) {
|
|
43
|
+
try {
|
|
44
|
+
const raw = typeof input === 'string' ? input : String(input ?? '');
|
|
45
|
+
const cmd = raw.trim().toLowerCase();
|
|
46
|
+
const seen = {
|
|
47
|
+
phase: state.phase,
|
|
48
|
+
transcript: [...state.transcript, userEntry(state.phase, raw)],
|
|
49
|
+
facts: [...state.facts],
|
|
50
|
+
};
|
|
51
|
+
if (cmd === 'done')
|
|
52
|
+
return move(seen, 'done', 'Session complete.');
|
|
53
|
+
if (cmd === 'foundation')
|
|
54
|
+
return move(seen, 'foundation', 'Entering foundation.');
|
|
55
|
+
if (cmd === 'audit')
|
|
56
|
+
return move(seen, 'audit', 'Entering audit.');
|
|
57
|
+
if (cmd === 'next') {
|
|
58
|
+
const next = NEXT_PHASE[seen.phase];
|
|
59
|
+
if (next === undefined)
|
|
60
|
+
return move(seen, 'done', 'Session complete.');
|
|
61
|
+
return move(seen, next, `Entering ${next}.`);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
phase: seen.phase,
|
|
65
|
+
transcript: [...seen.transcript, toolEntry(seen.phase, LIVE_HELP)],
|
|
66
|
+
facts: seen.facts,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return {
|
|
71
|
+
phase: state.phase,
|
|
72
|
+
transcript: [...state.transcript, toolEntry(state.phase, LIVE_HELP)],
|
|
73
|
+
facts: [...state.facts],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Renders the transcript as Markdown. Deterministic: phase names, kinds, and
|
|
79
|
+
* texts only — no timestamps, no dates, no durations.
|
|
80
|
+
*/
|
|
81
|
+
export function renderTranscript(state) {
|
|
82
|
+
const out = [];
|
|
83
|
+
out.push('# Live session transcript');
|
|
84
|
+
out.push('');
|
|
85
|
+
out.push(`Phase: ${state.phase}`);
|
|
86
|
+
out.push(`Facts: ${state.facts.length > 0 ? state.facts.join(', ') : '(none)'}`);
|
|
87
|
+
out.push('');
|
|
88
|
+
out.push('## Transcript');
|
|
89
|
+
out.push('');
|
|
90
|
+
if (state.transcript.length === 0)
|
|
91
|
+
out.push('(empty)');
|
|
92
|
+
for (const entry of state.transcript) {
|
|
93
|
+
out.push(`### ${entry.phase} · ${entry.kind}`);
|
|
94
|
+
out.push('');
|
|
95
|
+
out.push(entry.text === '' ? '(empty)' : entry.text);
|
|
96
|
+
out.push('');
|
|
97
|
+
}
|
|
98
|
+
return out.join('\n');
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/live/session.ts"],"names":[],"mappings":"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"}
|