@transitrix/diagrams 1.8.21 → 1.10.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/activity-card/types.js +1 -1
- package/dist/agreement.d.ts +15 -0
- package/dist/agreement.js +61 -0
- package/dist/applications/index.d.ts +2 -0
- package/dist/applications/index.js +1 -0
- package/dist/applications/resolve-maturity.d.ts +16 -0
- package/dist/applications/resolve-maturity.js +57 -0
- package/dist/applications/validate.js +20 -0
- package/dist/capability-map/CapabilityCardNode.d.ts +1 -1
- package/dist/capability-map/CapabilityRootNode.d.ts +1 -1
- package/dist/capability-map/index.d.ts +2 -0
- package/dist/capability-map/index.js +1 -0
- package/dist/capability-map/resolve-maturity.d.ts +20 -0
- package/dist/capability-map/resolve-maturity.js +72 -0
- package/dist/capability-map/validate.js +1 -2
- package/dist/codex/index.d.ts +1 -1
- package/dist/codex/index.js +1 -1
- package/dist/codex/types.d.ts +9 -2
- package/dist/codex/types.js +10 -3
- package/dist/codex/validate.js +29 -3
- package/dist/compliance/classify.d.ts +21 -2
- package/dist/compliance/classify.js +68 -13
- package/dist/compliance/confidence.js +1 -1
- package/dist/compliance/gap-report.d.ts +31 -1
- package/dist/compliance/gap-report.js +55 -3
- package/dist/compliance/html.js +14 -6
- package/dist/compliance/impact.js +1 -1
- package/dist/compliance/index.d.ts +3 -1
- package/dist/compliance/index.js +2 -0
- package/dist/compliance/markdown.js +26 -4
- package/dist/compliance/reverse-index.d.ts +6 -1
- package/dist/compliance/reverse-index.js +27 -3
- package/dist/compliance/trace.js +5 -1
- package/dist/compliance/types.d.ts +70 -0
- package/dist/compliance/types.js +1 -2
- package/dist/compliance/views.js +1 -1
- package/dist/compliance-matrix/build.js +0 -0
- package/dist/compliance-matrix/types.d.ts +1 -1
- package/dist/compliance-matrix/types.js +1 -1
- package/dist/confidence/score.js +1 -1
- package/dist/constraint/validate.js +3 -0
- package/dist/edge-path.js +1 -1
- package/dist/factor/validate.js +2 -2
- package/dist/fgca/chain-table.js +1 -1
- package/dist/fgca/nodeTypes.d.ts +4 -4
- package/dist/fgca/nodes/FGCAActivityNode.d.ts +1 -1
- package/dist/fgca/nodes/FGCAChangeNode.d.ts +1 -1
- package/dist/fgca/nodes/FGCAFactorNode.d.ts +1 -1
- package/dist/fgca/nodes/FGCAGoalNode.d.ts +1 -1
- package/dist/fgca/parse-canonical.d.ts +2 -2
- package/dist/fgca/parse-canonical.js +2 -2
- package/dist/fgca/preview-layout.d.ts +1 -1
- package/dist/goals/GoalNode.d.ts +1 -1
- package/dist/goals/layout.d.ts +1 -1
- package/dist/goals/layout.js +1 -1
- package/dist/goals/parse-canonical.d.ts +1 -1
- package/dist/goals/parse-canonical.js +1 -1
- package/dist/goals/types.d.ts +1 -1
- package/dist/goals/validate.js +2 -2
- package/dist/link-suspicion.d.ts +43 -0
- package/dist/link-suspicion.js +156 -0
- package/dist/metric/index.d.ts +4 -0
- package/dist/metric/index.js +2 -0
- package/dist/metric/types.d.ts +24 -0
- package/dist/metric/types.js +7 -0
- package/dist/metric/validate.d.ts +7 -0
- package/dist/metric/validate.js +90 -0
- package/dist/need/index.d.ts +3 -0
- package/dist/need/index.js +1 -0
- package/dist/need/types.d.ts +21 -0
- package/dist/need/types.js +3 -0
- package/dist/need/validate.d.ts +7 -0
- package/dist/need/validate.js +60 -0
- package/dist/repo-validate/check-candidate-fields.d.ts +6 -0
- package/dist/repo-validate/check-candidate-fields.js +87 -0
- package/dist/repo-validate/check-versioned-attributes.d.ts +4 -0
- package/dist/repo-validate/check-versioned-attributes.js +105 -0
- package/dist/repo-validate/validate-repo.js +7 -0
- package/dist/requirement/index.d.ts +2 -2
- package/dist/requirement/index.js +1 -1
- package/dist/requirement/types.d.ts +19 -1
- package/dist/requirement/types.js +3 -1
- package/dist/requirement/validate.js +22 -1
- package/dist/risk/index.d.ts +4 -0
- package/dist/risk/index.js +2 -0
- package/dist/risk/types.d.ts +25 -0
- package/dist/risk/types.js +3 -0
- package/dist/risk/validate.d.ts +7 -0
- package/dist/risk/validate.js +108 -0
- package/dist/schema-version.d.ts +9 -6
- package/dist/schema-version.js +9 -6
- package/dist/theme/themes.js +3 -2
- package/dist/validation/index.d.ts +4 -0
- package/dist/validation/index.js +2 -0
- package/dist/validation/types.d.ts +31 -0
- package/dist/validation/types.js +21 -0
- package/dist/validation/validate.d.ts +7 -0
- package/dist/validation/validate.js +106 -0
- package/dist/verification/index.d.ts +4 -0
- package/dist/verification/index.js +2 -0
- package/dist/verification/types.d.ts +31 -0
- package/dist/verification/types.js +12 -0
- package/dist/verification/validate.d.ts +7 -0
- package/dist/verification/validate.js +104 -0
- package/dist/versioned-attribute/index.d.ts +4 -0
- package/dist/versioned-attribute/index.js +2 -0
- package/dist/versioned-attribute/resolve.d.ts +15 -0
- package/dist/versioned-attribute/resolve.js +37 -0
- package/dist/versioned-attribute/types.d.ts +12 -0
- package/dist/versioned-attribute/types.js +6 -0
- package/dist/versioned-attribute/validate.d.ts +17 -0
- package/dist/versioned-attribute/validate.js +87 -0
- package/dist/webview/entry.js +11 -4
- package/dist/webview/render-applications.d.ts +15 -1
- package/dist/webview/render-applications.js +7 -2
- package/dist/webview/render-blocks.js +6 -4
- package/dist/webview/render-capability-map.d.ts +16 -1
- package/dist/webview/render-capability-map.js +4 -1
- package/dist/webview/render-process.d.ts +1 -1
- package/dist/webview/render-process.js +5 -5
- package/package.json +9 -6
- package/src/activity-card/types.ts +1 -1
- package/src/agreement.ts +71 -0
- package/src/applications/index.ts +3 -0
- package/src/applications/resolve-maturity.ts +66 -0
- package/src/applications/validate.ts +23 -0
- package/src/capability-map/index.ts +7 -0
- package/src/capability-map/resolve-maturity.ts +84 -0
- package/src/capability-map/validate.ts +1 -2
- package/src/codex/index.ts +1 -1
- package/src/codex/types.ts +11 -3
- package/src/codex/validate.ts +30 -2
- package/src/compliance/classify.ts +87 -14
- package/src/compliance/confidence.ts +1 -1
- package/src/compliance/gap-report.ts +91 -4
- package/src/compliance/html.ts +18 -6
- package/src/compliance/impact.ts +1 -1
- package/src/compliance/index.ts +6 -0
- package/src/compliance/markdown.ts +18 -4
- package/src/compliance/reverse-index.ts +35 -4
- package/src/compliance/trace.ts +7 -1
- package/src/compliance/types.ts +75 -2
- package/src/compliance/views.ts +1 -1
- package/src/compliance-matrix/build.ts +0 -0
- package/src/compliance-matrix/types.ts +2 -2
- package/src/confidence/score.ts +1 -1
- package/src/constraint/validate.ts +4 -0
- package/src/edge-path.ts +1 -1
- package/src/factor/validate.ts +2 -2
- package/src/fgca/chain-table.ts +1 -1
- package/src/fgca/parse-canonical.ts +2 -2
- package/src/fgca/preview-layout.ts +1 -1
- package/src/goals/layout.ts +1 -1
- package/src/goals/parse-canonical.ts +1 -1
- package/src/goals/types.ts +1 -1
- package/src/goals/validate.ts +2 -2
- package/src/link-suspicion.ts +181 -0
- package/src/metric/index.ts +4 -0
- package/src/metric/types.ts +38 -0
- package/src/metric/validate.ts +102 -0
- package/src/need/index.ts +3 -0
- package/src/need/types.ts +31 -0
- package/src/need/validate.ts +71 -0
- package/src/repo-validate/check-candidate-fields.ts +93 -0
- package/src/repo-validate/check-versioned-attributes.ts +112 -0
- package/src/repo-validate/validate-repo.ts +7 -0
- package/src/requirement/index.ts +2 -2
- package/src/requirement/types.ts +26 -1
- package/src/requirement/validate.ts +25 -1
- package/src/risk/index.ts +4 -0
- package/src/risk/types.ts +35 -0
- package/src/risk/validate.ts +121 -0
- package/src/schema-version.ts +9 -6
- package/src/theme/themes.ts +3 -2
- package/src/validation/index.ts +4 -0
- package/src/validation/types.ts +57 -0
- package/src/validation/validate.ts +113 -0
- package/src/verification/index.ts +4 -0
- package/src/verification/types.ts +48 -0
- package/src/verification/validate.ts +111 -0
- package/src/versioned-attribute/index.ts +4 -0
- package/src/versioned-attribute/resolve.ts +45 -0
- package/src/versioned-attribute/types.ts +19 -0
- package/src/versioned-attribute/validate.ts +109 -0
- package/src/webview/entry.ts +13 -6
- package/src/webview/render-applications.ts +25 -2
- package/src/webview/render-blocks.ts +8 -4
- package/src/webview/render-capability-map.ts +23 -1
- package/src/webview/render-process.ts +5 -5
- package/src/webview/styles.css +6 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GateChecks } from '../requirement/types.js';
|
|
2
|
+
import type { Evidence } from '../assertion/types.js';
|
|
3
|
+
/** V&V method vocabulary (27-verification.md §3). */
|
|
4
|
+
export type VerificationMethod = 'test' | 'analysis' | 'inspection' | 'demonstration';
|
|
5
|
+
export declare const VERIFICATION_METHODS: readonly VerificationMethod[];
|
|
6
|
+
/** Pass/fail judgement vocabulary (27-verification.md §3). */
|
|
7
|
+
export type VerificationOutcome = 'pass' | 'fail' | 'inconclusive' | 'not_yet_run';
|
|
8
|
+
export declare const VERIFICATION_OUTCOMES: readonly VerificationOutcome[];
|
|
9
|
+
/** Outcomes that count as "closed" — the trace link has resolved one way or
|
|
10
|
+
* the other, distinct from still-open (`not_yet_run` / `inconclusive`)
|
|
11
|
+
* (27-verification.md §5, REQ-VERIF-COVERAGE-002). */
|
|
12
|
+
export declare const CLOSED_VERIFICATION_OUTCOMES: readonly VerificationOutcome[];
|
|
13
|
+
export interface Verification {
|
|
14
|
+
notation: 'verification';
|
|
15
|
+
id: string;
|
|
16
|
+
/** Typed ID of the REQUIREMENT this verification targets. */
|
|
17
|
+
verifies: string;
|
|
18
|
+
method: VerificationMethod;
|
|
19
|
+
protocol: string;
|
|
20
|
+
result?: string;
|
|
21
|
+
outcome: VerificationOutcome;
|
|
22
|
+
evidence?: Evidence[];
|
|
23
|
+
performed_at?: string;
|
|
24
|
+
performed_by?: string;
|
|
25
|
+
zone: 'canon';
|
|
26
|
+
admitted_at: string;
|
|
27
|
+
admitted_by: string;
|
|
28
|
+
gate_checks: GateChecks;
|
|
29
|
+
valid_from: string;
|
|
30
|
+
valid_to: string | null;
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// VERIFICATION — engineering V&V claim against a REQUIREMENT.
|
|
2
|
+
// Schema: methodology notations/elements/27-verification.md §2.
|
|
3
|
+
export const VERIFICATION_METHODS = [
|
|
4
|
+
'test', 'analysis', 'inspection', 'demonstration',
|
|
5
|
+
];
|
|
6
|
+
export const VERIFICATION_OUTCOMES = [
|
|
7
|
+
'pass', 'fail', 'inconclusive', 'not_yet_run',
|
|
8
|
+
];
|
|
9
|
+
/** Outcomes that count as "closed" — the trace link has resolved one way or
|
|
10
|
+
* the other, distinct from still-open (`not_yet_run` / `inconclusive`)
|
|
11
|
+
* (27-verification.md §5, REQ-VERIF-COVERAGE-002). */
|
|
12
|
+
export const CLOSED_VERIFICATION_OUTCOMES = ['pass', 'fail'];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ValidationResult } from '../validation-types.js';
|
|
2
|
+
import { type CanonCatalog } from '../typed-id.js';
|
|
3
|
+
export interface VerificationValidateOptions {
|
|
4
|
+
/** When provided, the resolution rules enforce artefact existence. */
|
|
5
|
+
catalog?: CanonCatalog;
|
|
6
|
+
}
|
|
7
|
+
export declare function validateVerification(input: unknown, options?: VerificationValidateOptions): ValidationResult;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// VERIFICATION validator — methodology notations/elements/27-verification.md §5.
|
|
2
|
+
//
|
|
3
|
+
// Implements VERIF-001..006. The shared HDR-/LIFECYCLE- rules and the
|
|
4
|
+
// cross-cutting REQ-VERIF-COVERAGE-001/002 reverse-trace rules are owned
|
|
5
|
+
// elsewhere (CONTRACT.md §8) and are out of scope for this single-artefact
|
|
6
|
+
// validator — same posture as `validateAssertion` (../assertion/validate.ts).
|
|
7
|
+
//
|
|
8
|
+
// Resolution rules (VERIF-002/005) that need artefact *existence* run only
|
|
9
|
+
// when a `CanonCatalog` is supplied; the TYPE check VERIF-002 also carries is
|
|
10
|
+
// derivable from the id prefix and runs either way.
|
|
11
|
+
import { typeOfId, isCanonicalIdOfType } from '../typed-id.js';
|
|
12
|
+
import { VERIFICATION_METHODS, VERIFICATION_OUTCOMES } from './types.js';
|
|
13
|
+
export function validateVerification(input, options = {}) {
|
|
14
|
+
const errors = [];
|
|
15
|
+
const warnings = [];
|
|
16
|
+
const { catalog } = options;
|
|
17
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input)) {
|
|
18
|
+
errors.push({ code: 'VERIF-001', message: 'Verification must be a YAML mapping.' });
|
|
19
|
+
return { valid: false, errors, warnings };
|
|
20
|
+
}
|
|
21
|
+
const v = input;
|
|
22
|
+
// ── VERIF-001 — id grammar + plain required fields ───────────────────────
|
|
23
|
+
if (!isCanonicalIdOfType(v.id, 'VERIFICATION')) {
|
|
24
|
+
errors.push({ code: 'VERIF-001', message: `id "${String(v.id)}" must match VERIFICATION-[<middle>-]<INTEGER>.`, path: 'id' });
|
|
25
|
+
}
|
|
26
|
+
if (v.notation !== 'verification') {
|
|
27
|
+
errors.push({ code: 'VERIF-001', message: 'notation must be the fixed value "verification".', path: 'notation' });
|
|
28
|
+
}
|
|
29
|
+
if (v.zone !== 'canon') {
|
|
30
|
+
errors.push({ code: 'VERIF-001', message: 'zone is required and must be "canon".', path: 'zone' });
|
|
31
|
+
}
|
|
32
|
+
for (const f of ['admitted_at', 'admitted_by', 'valid_from', 'protocol']) {
|
|
33
|
+
if (typeof v[f] !== 'string' || v[f].trim() === '') {
|
|
34
|
+
errors.push({ code: 'VERIF-001', message: `${f} is required.`, path: f });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (v.gate_checks === null || typeof v.gate_checks !== 'object') {
|
|
38
|
+
errors.push({ code: 'VERIF-001', message: 'gate_checks is required and must be a mapping.', path: 'gate_checks' });
|
|
39
|
+
}
|
|
40
|
+
if (!('valid_to' in v) || !(typeof v.valid_to === 'string' || v.valid_to === null)) {
|
|
41
|
+
errors.push({ code: 'VERIF-001', message: 'valid_to is required (an ISO date string or null).', path: 'valid_to' });
|
|
42
|
+
}
|
|
43
|
+
// ── VERIF-002 — verifies → REQUIREMENT ───────────────────────────────────
|
|
44
|
+
const verifies = v.verifies;
|
|
45
|
+
if (typeof verifies !== 'string' || verifies.trim() === '') {
|
|
46
|
+
errors.push({ code: 'VERIF-002', message: 'verifies is required and must be a typed REQUIREMENT id.', path: 'verifies' });
|
|
47
|
+
}
|
|
48
|
+
else if (catalog) {
|
|
49
|
+
const t = catalog.typeOf(verifies);
|
|
50
|
+
if (t === undefined) {
|
|
51
|
+
errors.push({ code: 'VERIF-002', message: `verifies "${verifies}" does not resolve to an admitted artefact.`, path: 'verifies' });
|
|
52
|
+
}
|
|
53
|
+
else if (t !== 'REQUIREMENT') {
|
|
54
|
+
errors.push({ code: 'VERIF-002', message: `verifies "${verifies}" resolves to a ${t}, not a REQUIREMENT.`, path: 'verifies' });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (typeOfId(verifies) !== 'REQUIREMENT') {
|
|
58
|
+
errors.push({ code: 'VERIF-002', message: `verifies "${verifies}" must be a REQUIREMENT typed id.`, path: 'verifies' });
|
|
59
|
+
}
|
|
60
|
+
// ── VERIF-003 — method enum ───────────────────────────────────────────────
|
|
61
|
+
const method = v.method;
|
|
62
|
+
if (method === undefined || method === null) {
|
|
63
|
+
errors.push({ code: 'VERIF-001', message: 'method is required.', path: 'method' });
|
|
64
|
+
}
|
|
65
|
+
else if (!VERIFICATION_METHODS.includes(method)) {
|
|
66
|
+
errors.push({ code: 'VERIF-003', message: `method "${String(method)}" must be one of ${VERIFICATION_METHODS.join(', ')}.`, path: 'method' });
|
|
67
|
+
}
|
|
68
|
+
// ── VERIF-004 — outcome enum ──────────────────────────────────────────────
|
|
69
|
+
const outcome = v.outcome;
|
|
70
|
+
if (outcome === undefined || outcome === null) {
|
|
71
|
+
errors.push({ code: 'VERIF-001', message: 'outcome is required.', path: 'outcome' });
|
|
72
|
+
}
|
|
73
|
+
else if (!VERIFICATION_OUTCOMES.includes(outcome)) {
|
|
74
|
+
errors.push({ code: 'VERIF-004', message: `outcome "${String(outcome)}" must be one of ${VERIFICATION_OUTCOMES.join(', ')}.`, path: 'outcome' });
|
|
75
|
+
}
|
|
76
|
+
// ── VERIF-005 — canonical_ref evidence resolves ──────────────────────────
|
|
77
|
+
if (v.evidence !== undefined) {
|
|
78
|
+
if (!Array.isArray(v.evidence)) {
|
|
79
|
+
errors.push({ code: 'VERIF-001', message: 'evidence must be a list.', path: 'evidence' });
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
v.evidence.forEach((e, i) => {
|
|
83
|
+
if (e === null || typeof e !== 'object')
|
|
84
|
+
return;
|
|
85
|
+
const entry = e;
|
|
86
|
+
if (entry.kind !== 'canonical_ref')
|
|
87
|
+
return;
|
|
88
|
+
const ref = entry.ref;
|
|
89
|
+
if (!typeOfId(ref)) {
|
|
90
|
+
errors.push({ code: 'VERIF-005', message: `evidence[${i}] canonical_ref "${String(ref)}" is not a resolvable typed ID.`, path: `evidence[${i}].ref` });
|
|
91
|
+
}
|
|
92
|
+
else if (catalog && catalog.typeOf(ref) === undefined) {
|
|
93
|
+
errors.push({ code: 'VERIF-005', message: `evidence[${i}] canonical_ref "${String(ref)}" does not resolve.`, path: `evidence[${i}].ref` });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// ── VERIF-006 (warning) — pass outcome with no evidence ──────────────────
|
|
99
|
+
const evidenceEmpty = !Array.isArray(v.evidence) || v.evidence.length === 0;
|
|
100
|
+
if (evidenceEmpty && outcome === 'pass') {
|
|
101
|
+
warnings.push({ code: 'VERIF-006', message: 'outcome "pass" has no evidence — an undefended positive claim.', path: 'evidence' });
|
|
102
|
+
}
|
|
103
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
104
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { AttributeVersionEntry, VersionedAttributeSidecar } from './types.js';
|
|
2
|
+
export { resolveAttributeValue, resolveAttributes, todayIso } from './resolve.js';
|
|
3
|
+
export type { AttributeArrayFinding } from './validate.js';
|
|
4
|
+
export { parseSidecar, validateAttributeArray, validateSidecar } from './validate.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AttributeVersionEntry, VersionedAttributeSidecar } from './types.js';
|
|
2
|
+
/** Pick the entry with the largest `valid_from <= atDate`.
|
|
3
|
+
* Returns `undefined` when no entry has taken effect yet as of `atDate`
|
|
4
|
+
* (the attribute has not yet taken its first value — CONTRACT.md §9.2 rule
|
|
5
|
+
* 4). Returns `null` when the resolved entry is itself a gap marker
|
|
6
|
+
* (`value: null` — attribute currently unset). */
|
|
7
|
+
export declare function resolveAttributeValue(entries: AttributeVersionEntry[] | undefined, atDate: string): unknown;
|
|
8
|
+
/** Resolve every attribute in a sidecar at `atDate`. An attribute with no
|
|
9
|
+
* entry yet in effect is omitted from the result (equivalent to
|
|
10
|
+
* `resolveAttributeValue` returning `undefined`) rather than reported as
|
|
11
|
+
* `null`, which is reserved for an explicit gap marker. */
|
|
12
|
+
export declare function resolveAttributes(sidecar: VersionedAttributeSidecar | null | undefined, atDate: string): Record<string, unknown>;
|
|
13
|
+
/** Today, as a quoted-ISO-8601 date string — the default projection date
|
|
14
|
+
* every resolver/renderer falls back to when the caller supplies none. */
|
|
15
|
+
export declare function todayIso(): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Current-value resolution for a versioned attribute — CONTRACT.md §9.2.
|
|
2
|
+
/** Pick the entry with the largest `valid_from <= atDate`.
|
|
3
|
+
* Returns `undefined` when no entry has taken effect yet as of `atDate`
|
|
4
|
+
* (the attribute has not yet taken its first value — CONTRACT.md §9.2 rule
|
|
5
|
+
* 4). Returns `null` when the resolved entry is itself a gap marker
|
|
6
|
+
* (`value: null` — attribute currently unset). */
|
|
7
|
+
export function resolveAttributeValue(entries, atDate) {
|
|
8
|
+
if (!entries || entries.length === 0)
|
|
9
|
+
return undefined;
|
|
10
|
+
let best;
|
|
11
|
+
for (const entry of entries) {
|
|
12
|
+
if (entry.valid_from <= atDate && (!best || entry.valid_from > best.valid_from)) {
|
|
13
|
+
best = entry;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return best ? best.value : undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Resolve every attribute in a sidecar at `atDate`. An attribute with no
|
|
19
|
+
* entry yet in effect is omitted from the result (equivalent to
|
|
20
|
+
* `resolveAttributeValue` returning `undefined`) rather than reported as
|
|
21
|
+
* `null`, which is reserved for an explicit gap marker. */
|
|
22
|
+
export function resolveAttributes(sidecar, atDate) {
|
|
23
|
+
const out = {};
|
|
24
|
+
if (!sidecar)
|
|
25
|
+
return out;
|
|
26
|
+
for (const name of Object.keys(sidecar.attribute_versions)) {
|
|
27
|
+
const value = resolveAttributeValue(sidecar.attribute_versions[name], atDate);
|
|
28
|
+
if (value !== undefined)
|
|
29
|
+
out[name] = value;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/** Today, as a quoted-ISO-8601 date string — the default projection date
|
|
34
|
+
* every resolver/renderer falls back to when the caller supplies none. */
|
|
35
|
+
export function todayIso() {
|
|
36
|
+
return new Date().toISOString().slice(0, 10);
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** One version entry in an attribute's history. `value: null` is a gap
|
|
2
|
+
* marker — the attribute is unset from `valid_from` until the next entry. */
|
|
3
|
+
export interface AttributeVersionEntry {
|
|
4
|
+
valid_from: string;
|
|
5
|
+
value: unknown;
|
|
6
|
+
}
|
|
7
|
+
/** A parsed sidecar document, keyed by attribute name. */
|
|
8
|
+
export interface VersionedAttributeSidecar {
|
|
9
|
+
/** Canonical id of the primitive this sidecar versions. */
|
|
10
|
+
target: string;
|
|
11
|
+
attribute_versions: Record<string, AttributeVersionEntry[]>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Versioned-attribute sidecar (CONTRACT.md §9) — shared shape across every
|
|
2
|
+
// notation that declares a `time_varying` field. A sidecar is a co-located
|
|
3
|
+
// `<primitive_id>.history.yaml` document: no `id`, no admission record, no
|
|
4
|
+
// lifecycle of its own — its temporal window is governed by the target
|
|
5
|
+
// primitive's own `valid_from`/`valid_to` (CONTRACT.md §9.1).
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AttributeVersionEntry, VersionedAttributeSidecar } from './types.js';
|
|
2
|
+
export interface AttributeArrayFinding {
|
|
3
|
+
code: 'VERSIONED-002' | 'VERSIONED-003' | 'VERSIONED-005';
|
|
4
|
+
severity: 'error' | 'warning';
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
/** Parse a raw parsed-YAML mapping into a typed sidecar, or `null` if it
|
|
8
|
+
* isn't shaped like one (missing `target` string or `attribute_versions`
|
|
9
|
+
* map) — not every doc under `canon/elements/**` is a sidecar. */
|
|
10
|
+
export declare function parseSidecar(data: Record<string, unknown> | null | undefined): VersionedAttributeSidecar | null;
|
|
11
|
+
/** VERSIONED-002/003/005 for one attribute's version array.
|
|
12
|
+
* `targetValidFrom`/`targetValidTo` bound VERSIONED-005 — pass `undefined`
|
|
13
|
+
* for either to skip that half of the check (e.g. the target element could
|
|
14
|
+
* not be found, which is already reported separately as VERSIONED-001). */
|
|
15
|
+
export declare function validateAttributeArray(attributeName: string, entries: AttributeVersionEntry[], targetValidFrom?: string, targetValidTo?: string | null): AttributeArrayFinding[];
|
|
16
|
+
/** Run VERSIONED-002/003/005 over every attribute in a parsed sidecar. */
|
|
17
|
+
export declare function validateSidecar(sidecar: VersionedAttributeSidecar, targetValidFrom?: string, targetValidTo?: string | null): AttributeArrayFinding[];
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Versioned-attribute sidecar validation — CONTRACT.md §9.3, `VERSIONED-00x`.
|
|
2
|
+
//
|
|
3
|
+
// Split by what each check needs to know:
|
|
4
|
+
// - `parseSidecar` + `validateAttributeArray` here cover VERSIONED-002/003/005,
|
|
5
|
+
// which only need the sidecar document itself (plus, for 005, the target
|
|
6
|
+
// primitive's own lifecycle window).
|
|
7
|
+
// - `VERSIONED-001` (target resolves to an admitted primitive) and
|
|
8
|
+
// `VERSIONED-004` (a time_varying field present inline on the primitive)
|
|
9
|
+
// both need cross-document knowledge — which ids exist, which notation a
|
|
10
|
+
// primitive is — that a single sidecar document doesn't carry. Those are
|
|
11
|
+
// repo-scope concerns; see `repo-validate/check-versioned-attributes.ts`.
|
|
12
|
+
function isAttributeVersionEntry(v) {
|
|
13
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v) && typeof v['valid_from'] === 'string';
|
|
14
|
+
}
|
|
15
|
+
/** Parse a raw parsed-YAML mapping into a typed sidecar, or `null` if it
|
|
16
|
+
* isn't shaped like one (missing `target` string or `attribute_versions`
|
|
17
|
+
* map) — not every doc under `canon/elements/**` is a sidecar. */
|
|
18
|
+
export function parseSidecar(data) {
|
|
19
|
+
if (!data)
|
|
20
|
+
return null;
|
|
21
|
+
const target = data['target'];
|
|
22
|
+
const attributeVersions = data['attribute_versions'];
|
|
23
|
+
if (typeof target !== 'string' || target.trim() === '')
|
|
24
|
+
return null;
|
|
25
|
+
if (typeof attributeVersions !== 'object' || attributeVersions === null || Array.isArray(attributeVersions))
|
|
26
|
+
return null;
|
|
27
|
+
const out = {};
|
|
28
|
+
for (const [name, value] of Object.entries(attributeVersions)) {
|
|
29
|
+
if (!Array.isArray(value))
|
|
30
|
+
continue;
|
|
31
|
+
out[name] = value.filter(isAttributeVersionEntry);
|
|
32
|
+
}
|
|
33
|
+
return { target, attribute_versions: out };
|
|
34
|
+
}
|
|
35
|
+
/** VERSIONED-002/003/005 for one attribute's version array.
|
|
36
|
+
* `targetValidFrom`/`targetValidTo` bound VERSIONED-005 — pass `undefined`
|
|
37
|
+
* for either to skip that half of the check (e.g. the target element could
|
|
38
|
+
* not be found, which is already reported separately as VERSIONED-001). */
|
|
39
|
+
export function validateAttributeArray(attributeName, entries, targetValidFrom, targetValidTo) {
|
|
40
|
+
const findings = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
let sorted = true;
|
|
43
|
+
let prev;
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
if (seen.has(entry.valid_from)) {
|
|
46
|
+
findings.push({
|
|
47
|
+
code: 'VERSIONED-002',
|
|
48
|
+
severity: 'error',
|
|
49
|
+
message: `attribute '${attributeName}': duplicate valid_from '${entry.valid_from}'.`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
seen.add(entry.valid_from);
|
|
53
|
+
if (prev !== undefined && entry.valid_from < prev)
|
|
54
|
+
sorted = false;
|
|
55
|
+
prev = entry.valid_from;
|
|
56
|
+
if (targetValidFrom !== undefined && entry.valid_from < targetValidFrom) {
|
|
57
|
+
findings.push({
|
|
58
|
+
code: 'VERSIONED-005',
|
|
59
|
+
severity: 'error',
|
|
60
|
+
message: `attribute '${attributeName}': entry valid_from '${entry.valid_from}' is before the target's valid_from '${targetValidFrom}'.`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (targetValidTo !== undefined && targetValidTo !== null && entry.valid_from > targetValidTo) {
|
|
64
|
+
findings.push({
|
|
65
|
+
code: 'VERSIONED-005',
|
|
66
|
+
severity: 'error',
|
|
67
|
+
message: `attribute '${attributeName}': entry valid_from '${entry.valid_from}' is after the target's valid_to '${targetValidTo}'.`,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!sorted) {
|
|
72
|
+
findings.push({
|
|
73
|
+
code: 'VERSIONED-003',
|
|
74
|
+
severity: 'warning',
|
|
75
|
+
message: `attribute '${attributeName}': entries are not sorted by valid_from ascending.`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return findings;
|
|
79
|
+
}
|
|
80
|
+
/** Run VERSIONED-002/003/005 over every attribute in a parsed sidecar. */
|
|
81
|
+
export function validateSidecar(sidecar, targetValidFrom, targetValidTo) {
|
|
82
|
+
const findings = [];
|
|
83
|
+
for (const [name, entries] of Object.entries(sidecar.attribute_versions)) {
|
|
84
|
+
findings.push(...validateAttributeArray(name, entries, targetValidFrom, targetValidTo));
|
|
85
|
+
}
|
|
86
|
+
return findings;
|
|
87
|
+
}
|
package/dist/webview/entry.js
CHANGED
|
@@ -28,7 +28,7 @@ import yaml from 'js-yaml';
|
|
|
28
28
|
import { validateActivities } from '../activities/index.js';
|
|
29
29
|
import { validateActivityCard } from '../activity-card/index.js';
|
|
30
30
|
import { validateApplicationsCatalogue } from '../applications/index.js';
|
|
31
|
-
import {
|
|
31
|
+
import { validateBlocks } from '../blocks/index.js';
|
|
32
32
|
import { validateCapabilityMap } from '../capability-map/validate.js';
|
|
33
33
|
import { parseCanonicalFGCA, parseCanonicalFGA } from '../fgca/parse-canonical.js';
|
|
34
34
|
import { parseCanonicalGoals } from '../goals/parse-canonical.js';
|
|
@@ -40,7 +40,7 @@ import { coerceDatesToIsoStrings } from '../yaml-normalize.js';
|
|
|
40
40
|
import { renderActivitiesSvg } from './render-activities.js';
|
|
41
41
|
import { renderActivityCardSvg } from './render-activity-card.js';
|
|
42
42
|
import { renderApplicationsHtml } from './render-applications.js';
|
|
43
|
-
import { renderBlocksSvg } from './render-blocks.js';
|
|
43
|
+
import { renderBlocksSvg, renderGridSvg } from './render-blocks.js';
|
|
44
44
|
import { renderCapabilityMapHtml } from './render-capability-map.js';
|
|
45
45
|
import { renderFgcaSvg } from './render-fgca.js';
|
|
46
46
|
import { renderGoalsSvg } from './render-goals.js';
|
|
@@ -138,8 +138,15 @@ function dispatchValidate(kind, doc) {
|
|
|
138
138
|
return renderFromValidation('action-card', validateActivityCard(doc), () => renderActivityCardSvg(doc));
|
|
139
139
|
case 'process-blueprint':
|
|
140
140
|
return renderFromValidation('process-blueprint', validateProcessBlueprint(doc), () => renderProcessBlueprintSvg(doc));
|
|
141
|
-
case 'blocks':
|
|
142
|
-
|
|
141
|
+
case 'blocks': {
|
|
142
|
+
// Two alternative root forms (08-blocks.md §4): a `nested_blocks:`
|
|
143
|
+
// containment tree, or a `grid:` matrix subset (§4a). `validateBlocks`
|
|
144
|
+
// is the shared root-form dispatcher (BL-020 on both/neither present);
|
|
145
|
+
// mirrors the VS Code path's `hasGrid` branch in `blocks-preview.ts`.
|
|
146
|
+
const raw = (doc && typeof doc === 'object' ? doc : {});
|
|
147
|
+
const hasGrid = raw['grid'] !== undefined && raw['grid'] !== null;
|
|
148
|
+
return renderFromValidation('blocks', validateBlocks(doc), () => hasGrid ? renderGridSvg(doc) : renderBlocksSvg(doc));
|
|
149
|
+
}
|
|
143
150
|
// Catalogue notations render an HTML fragment from the header nested under
|
|
144
151
|
// their top-level wrapper key (`<thing>_catalogue` / `scenario` / …).
|
|
145
152
|
case 'applications':
|
|
@@ -8,4 +8,18 @@
|
|
|
8
8
|
* `#transitrix-root` exactly the way it drops the goals SVG (Step 3 contract).
|
|
9
9
|
*/
|
|
10
10
|
import type { ApplicationsCatalogueHeader } from '../applications/types.js';
|
|
11
|
-
|
|
11
|
+
import type { ResolvedApplicationAttributes } from '../applications/resolve-maturity.js';
|
|
12
|
+
/**
|
|
13
|
+
* Resolved values for owner_role/vendor/maturity — sidecar-bound
|
|
14
|
+
* (CONTRACT.md §9.4) and never inline on an admitted catalogue entry
|
|
15
|
+
* (VERSIONED-004). The host resolves these upstream (see
|
|
16
|
+
* `applications/resolve-maturity.ts`) and passes the result in; this
|
|
17
|
+
* function stays a pure renderer of whatever it's given — no I/O, no
|
|
18
|
+
* write-back. `asOf` is the date the resolution ran at, shown so the view
|
|
19
|
+
* never states an undated value.
|
|
20
|
+
*/
|
|
21
|
+
export interface ApplicationsMaturityResolution {
|
|
22
|
+
asOf: string;
|
|
23
|
+
byAppId: Map<string, ResolvedApplicationAttributes>;
|
|
24
|
+
}
|
|
25
|
+
export declare function renderApplicationsHtml(catalogue: ApplicationsCatalogueHeader, resolution?: ApplicationsMaturityResolution): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withResolvedAttributes } from '../applications/resolve-maturity.js';
|
|
1
2
|
import { escHtml } from './render-util.js';
|
|
2
3
|
const TYPE_LABEL = {
|
|
3
4
|
application: 'Application',
|
|
@@ -68,8 +69,11 @@ function renderRow(a) {
|
|
|
68
69
|
<td class="col-owner">${a.owner_role ? escHtml(a.owner_role) : '<span class="cell-empty">—</span>'}</td>
|
|
69
70
|
</tr>`;
|
|
70
71
|
}
|
|
71
|
-
export function renderApplicationsHtml(catalogue) {
|
|
72
|
-
const
|
|
72
|
+
export function renderApplicationsHtml(catalogue, resolution) {
|
|
73
|
+
const applications = resolution
|
|
74
|
+
? catalogue.applications.map((a) => withResolvedAttributes(a, resolution.byAppId))
|
|
75
|
+
: catalogue.applications;
|
|
76
|
+
const rows = applications.map(renderRow).join('\n');
|
|
73
77
|
const emptyRow = catalogue.applications.length === 0
|
|
74
78
|
? `<tr><td colspan="7" class="empty-catalogue">No applications defined.</td></tr>`
|
|
75
79
|
: '';
|
|
@@ -81,6 +85,7 @@ export function renderApplicationsHtml(catalogue) {
|
|
|
81
85
|
${catalogue.version ? `<span class="catalogue-version">v${escHtml(catalogue.version)}</span>` : ''}
|
|
82
86
|
</div>
|
|
83
87
|
${catalogue.description ? `<div class="catalogue-subtitle">${escHtml(catalogue.description)}</div>` : ''}
|
|
88
|
+
${resolution ? `<div class="catalogue-resolved-note">Owner Role, Vendor, Maturity resolved as of ${escHtml(resolution.asOf)}</div>` : ''}
|
|
84
89
|
</header>`;
|
|
85
90
|
return `<section class="tx-catalogue tx-applications">
|
|
86
91
|
${header}
|
|
@@ -115,8 +115,6 @@ export function renderBlocksSvg(doc, options = {}) {
|
|
|
115
115
|
*/
|
|
116
116
|
const GRID_CELL_PAD_X = 8;
|
|
117
117
|
const GRID_LINE_HEIGHT = 15;
|
|
118
|
-
const GRID_EMBED_CSS = `
|
|
119
|
-
.blocks-grid-border { fill: none; stroke: var(--ts-border, #cbd5e1); }`;
|
|
120
118
|
function centeredGridCellTextSvg(lines, cls, cx, cellTop, cellHeight) {
|
|
121
119
|
const ls = lines.length > 0 ? lines : [''];
|
|
122
120
|
const firstY = cellTop + cellHeight / 2 - ((ls.length - 1) / 2) * GRID_LINE_HEIGHT;
|
|
@@ -174,7 +172,11 @@ export function renderGridBody(layout, ox, oy) {
|
|
|
174
172
|
const colLineX = ox + col.x + col.width;
|
|
175
173
|
parts.push(`<line class="diagram-edge" x1="${colLineX}" y1="${gridY1}" x2="${colLineX}" y2="${gridY2}"/>`);
|
|
176
174
|
}
|
|
177
|
-
|
|
175
|
+
// Explicit fill="none" alongside the class: this rect covers the full grid
|
|
176
|
+
// bounds and is the last (topmost) element emitted, so if `.blocks-grid-border`
|
|
177
|
+
// is ever missing from a host's CSS (as it was in the VS Code webview path —
|
|
178
|
+
// see the grid-preview regression), it must not fall back to SVG's default opaque black fill.
|
|
179
|
+
parts.push(`<rect class="blocks-grid-border" fill="none" x="${ox}" y="${oy}" width="${tw}" height="${th}"/>`);
|
|
178
180
|
return parts.join('\n');
|
|
179
181
|
}
|
|
180
182
|
/** The single grid (matrix subset) SVG emitter shared by every host. */
|
|
@@ -185,7 +187,7 @@ export function renderGridLayoutSvg(layout, options = {}) {
|
|
|
185
187
|
const ox = PAD;
|
|
186
188
|
const oy = PAD + topInset;
|
|
187
189
|
const body = renderGridBody(layout, ox, oy);
|
|
188
|
-
const styleLine = embedCssTheme ? `\n<style>${generateSvgEmbedCss(embedCssTheme)}
|
|
190
|
+
const styleLine = embedCssTheme ? `\n<style>${generateSvgEmbedCss(embedCssTheme)}</style>` : '';
|
|
189
191
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">${styleLine}
|
|
190
192
|
${title}
|
|
191
193
|
${body}
|
|
@@ -4,4 +4,19 @@
|
|
|
4
4
|
* HTML fragment for the JCEF host (Step 4 of ADR 0001).
|
|
5
5
|
*/
|
|
6
6
|
import type { CapabilityMapHeader } from '../capability-map/types.js';
|
|
7
|
-
|
|
7
|
+
import type { ResolvedCapabilityAttributes } from '../capability-map/resolve-maturity.js';
|
|
8
|
+
/**
|
|
9
|
+
* Resolved values for current_maturity/target_maturity/owner_role/
|
|
10
|
+
* target_date — sidecar-bound (CONTRACT.md §9.4) on the standalone
|
|
11
|
+
* CAPABILITY-* primitive a nested entry references (the 2026-08-05
|
|
12
|
+
* packages decision). The host resolves
|
|
13
|
+
* these upstream (see `capability-map/resolve-maturity.ts`) and passes the
|
|
14
|
+
* result in; this function stays a pure renderer of whatever it's given —
|
|
15
|
+
* no I/O, no write-back. `asOf` is the date the resolution ran at, shown so
|
|
16
|
+
* the view never states an undated value.
|
|
17
|
+
*/
|
|
18
|
+
export interface CapabilityMapMaturityResolution {
|
|
19
|
+
asOf: string;
|
|
20
|
+
byId: Map<string, ResolvedCapabilityAttributes>;
|
|
21
|
+
}
|
|
22
|
+
export declare function renderCapabilityMapHtml(rawMap: CapabilityMapHeader, resolution?: CapabilityMapMaturityResolution): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withResolvedCapabilityMap } from '../capability-map/resolve-maturity.js';
|
|
1
2
|
import { escHtml } from './render-util.js';
|
|
2
3
|
const MATURITY_LABEL = {
|
|
3
4
|
1: 'Initial',
|
|
@@ -52,7 +53,8 @@ function renderCapabilityCard(node, depth) {
|
|
|
52
53
|
${childBlock}
|
|
53
54
|
</div>`;
|
|
54
55
|
}
|
|
55
|
-
export function renderCapabilityMapHtml(
|
|
56
|
+
export function renderCapabilityMapHtml(rawMap, resolution) {
|
|
57
|
+
const map = resolution ? withResolvedCapabilityMap(rawMap, resolution.byId) : rawMap;
|
|
56
58
|
const header = `<header class="catalogue-header">
|
|
57
59
|
<div class="catalogue-title">${escHtml(map.name)}</div>
|
|
58
60
|
<div class="catalogue-meta">
|
|
@@ -60,6 +62,7 @@ export function renderCapabilityMapHtml(map) {
|
|
|
60
62
|
<span class="catalogue-updated">Assessed ${escHtml(map.assessment_date)}</span>
|
|
61
63
|
</div>
|
|
62
64
|
${map.description ? `<div class="catalogue-subtitle">${escHtml(map.description)}</div>` : ''}
|
|
65
|
+
${resolution ? `<div class="catalogue-resolved-note">Current Maturity, Target Maturity, Owner Role, Target Date resolved as of ${escHtml(resolution.asOf)}</div>` : ''}
|
|
63
66
|
</header>`;
|
|
64
67
|
if (map.capabilities.length === 0) {
|
|
65
68
|
return `<section class="tx-catalogue tx-capability-map">
|
|
@@ -70,7 +70,7 @@ export interface RenderProcessOptions {
|
|
|
70
70
|
/** Extra vertical space (px) reserved above the pool for a title block. */
|
|
71
71
|
topInset?: number;
|
|
72
72
|
}
|
|
73
|
-
export declare const BPMN_PROCESS_CSS = "\n.bpmn-pool { fill: var(--ts-bg-surface,#f8fafc); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-pool-name { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-lane { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-lane-header { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-pool-label { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; font-weight: 700; }\n.bpmn-lane-label { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; font-weight: 600; }\n.bpmn-task { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-task-name { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; text-anchor: middle; }\n.bpmn-event { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); }\n.bpmn-event-start { stroke-width: 1.5; }\n.bpmn-event-end { stroke-width: 4; }\n.bpmn-event-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }\n.bpmn-gateway { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-gateway-marker { stroke: var(--ts-node-stroke,#004d67); stroke-width: 2.5; stroke-linecap: round; fill: none; }\n.bpmn-gateway-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }\n.bpmn-seq-flow { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-default-mark { stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; stroke-linecap: round; }\n.bpmn-assoc { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1; stroke-dasharray: 4 2; }\n.bpmn-data-obj { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1; }\n.bpmn-data-obj-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }\n.bpmn-event-intermediate { fill: none; stroke: var(--ts-node-stroke,#004d67); stroke-width: 1; }\n.bpmn-event-icon { fill: none; stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }\n";
|
|
73
|
+
export declare const BPMN_PROCESS_CSS = "\n.bpmn-pool { fill: var(--ts-bg-surface,#f8fafc); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-pool-name { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-lane { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-lane-header { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }\n.bpmn-pool-label { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; font-weight: 700; }\n.bpmn-lane-label { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; font-weight: 600; }\n.bpmn-task { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-task-name { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; text-anchor: middle; }\n.bpmn-event { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); }\n.bpmn-event-start { stroke-width: 1.5; }\n.bpmn-event-end { stroke-width: 4; }\n.bpmn-event-label { fill: var(--ts-text-secondary,#516970); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 10px; text-anchor: middle; }\n.bpmn-gateway { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-gateway-marker { stroke: var(--ts-node-stroke,#004d67); stroke-width: 2.5; stroke-linecap: round; fill: none; }\n.bpmn-gateway-label { fill: var(--ts-text-secondary,#516970); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 10px; text-anchor: middle; }\n.bpmn-seq-flow { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; }\n.bpmn-default-mark { stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; stroke-linecap: round; }\n.bpmn-assoc { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1; stroke-dasharray: 4 2; }\n.bpmn-data-obj { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1; }\n.bpmn-data-obj-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }\n.bpmn-event-intermediate { fill: none; stroke: var(--ts-node-stroke,#004d67); stroke-width: 1; }\n.bpmn-event-icon { fill: none; stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }\n";
|
|
74
74
|
/**
|
|
75
75
|
* Canonical body emitter, shared by every host (VS Code, JCEF, static export).
|
|
76
76
|
*
|
|
@@ -39,17 +39,17 @@ export const BPMN_PROCESS_CSS = `
|
|
|
39
39
|
.bpmn-pool-name { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }
|
|
40
40
|
.bpmn-lane { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }
|
|
41
41
|
.bpmn-lane-header { fill: var(--ts-bg-elevated,#f1f5f9); stroke: var(--ts-node-stroke,#004d67); stroke-width: 0.75; }
|
|
42
|
-
.bpmn-pool-label { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; font-weight: 700; }
|
|
43
|
-
.bpmn-lane-label { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; font-weight: 600; }
|
|
42
|
+
.bpmn-pool-label { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; font-weight: 700; }
|
|
43
|
+
.bpmn-lane-label { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; font-weight: 600; }
|
|
44
44
|
.bpmn-task { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }
|
|
45
|
-
.bpmn-task-name { fill: var(--ts-text-primary,#0d2b35); font-size: 11px; text-anchor: middle; }
|
|
45
|
+
.bpmn-task-name { fill: var(--ts-text-primary,#0d2b35); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 11px; text-anchor: middle; }
|
|
46
46
|
.bpmn-event { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); }
|
|
47
47
|
.bpmn-event-start { stroke-width: 1.5; }
|
|
48
48
|
.bpmn-event-end { stroke-width: 4; }
|
|
49
|
-
.bpmn-event-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }
|
|
49
|
+
.bpmn-event-label { fill: var(--ts-text-secondary,#516970); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 10px; text-anchor: middle; }
|
|
50
50
|
.bpmn-gateway { fill: var(--ts-bg,#ffffff); stroke: var(--ts-node-stroke,#004d67); stroke-width: 1.5; }
|
|
51
51
|
.bpmn-gateway-marker { stroke: var(--ts-node-stroke,#004d67); stroke-width: 2.5; stroke-linecap: round; fill: none; }
|
|
52
|
-
.bpmn-gateway-label { fill: var(--ts-text-secondary,#516970); font-size: 10px; text-anchor: middle; }
|
|
52
|
+
.bpmn-gateway-label { fill: var(--ts-text-secondary,#516970); font-family: var(--vscode-font-family, system-ui, -apple-system, sans-serif); font-size: 10px; text-anchor: middle; }
|
|
53
53
|
.bpmn-seq-flow { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; }
|
|
54
54
|
.bpmn-default-mark { stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1.5; stroke-linecap: round; }
|
|
55
55
|
.bpmn-assoc { fill: none; stroke: var(--ts-edge-stroke,#004d67); stroke-width: 1; stroke-dasharray: 4 2; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transitrix/diagrams",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared rendering, validation, and pure mutations for Transitrix custom diagram formats.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"main": "dist/index.js",
|
|
17
17
|
"types": "dist/index.d.ts",
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
18
21
|
"exports": {
|
|
19
22
|
".": {
|
|
20
23
|
"types": "./dist/index.d.ts",
|
|
@@ -51,13 +54,13 @@
|
|
|
51
54
|
"devDependencies": {
|
|
52
55
|
"@testing-library/dom": "^10.4.1",
|
|
53
56
|
"@testing-library/react": "^16.3.2",
|
|
54
|
-
"@types/react": "^
|
|
55
|
-
"@types/react-dom": "^19.2.
|
|
57
|
+
"@types/react": "^19.2.17",
|
|
58
|
+
"@types/react-dom": "^19.2.4",
|
|
56
59
|
"jsdom": "^29.1.1",
|
|
57
|
-
"react": "^19.2.
|
|
58
|
-
"react-dom": "^19.2.
|
|
60
|
+
"react": "^19.2.8",
|
|
61
|
+
"react-dom": "^19.2.8",
|
|
59
62
|
"reactflow": "^11.11.4",
|
|
60
63
|
"typescript": "^5.0.0",
|
|
61
|
-
"vitest": "^
|
|
64
|
+
"vitest": "^4.1.10"
|
|
62
65
|
}
|
|
63
66
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Activity Card notation — single-project narrative view.
|
|
2
2
|
//
|
|
3
3
|
// Spec: transitrix/methodology `notations/views/18-activity-card.md` (v0.1).
|
|
4
|
-
//
|
|
4
|
+
// Studio track #134.
|
|
5
5
|
//
|
|
6
6
|
// The Activity Card is the first MULTI-DOCUMENT Studio notation. The card
|
|
7
7
|
// YAML itself holds only `id`, `project` (an Activity ID), `description`,
|