@ivorycanvas/qamap 0.3.5 → 0.4.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +19 -14
  3. package/dist/behavior-intent.d.ts +6 -0
  4. package/dist/behavior-intent.js +172 -0
  5. package/dist/behavior-intent.js.map +1 -0
  6. package/dist/behavior-manifest.d.ts +6 -0
  7. package/dist/behavior-manifest.js +221 -0
  8. package/dist/behavior-manifest.js.map +1 -0
  9. package/dist/behavior.d.ts +143 -0
  10. package/dist/behavior.js +458 -0
  11. package/dist/behavior.js.map +1 -0
  12. package/dist/change-intent.d.ts +71 -0
  13. package/dist/change-intent.js +744 -0
  14. package/dist/change-intent.js.map +1 -0
  15. package/dist/cli.js +6 -5
  16. package/dist/cli.js.map +1 -1
  17. package/dist/e2e.d.ts +16 -1
  18. package/dist/e2e.js +286 -23
  19. package/dist/e2e.js.map +1 -1
  20. package/dist/index.d.ts +9 -1
  21. package/dist/index.js +4 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/qa.d.ts +1 -0
  24. package/dist/qa.js +73 -1
  25. package/dist/qa.js.map +1 -1
  26. package/dist/terminal.js +1 -1
  27. package/dist/terminal.js.map +1 -1
  28. package/dist/version.d.ts +1 -1
  29. package/dist/version.js +1 -1
  30. package/docs/adoption.md +11 -10
  31. package/docs/agent-format.md +9 -7
  32. package/docs/agent-skill.md +5 -2
  33. package/docs/architecture.md +131 -0
  34. package/docs/benchmarking.md +20 -3
  35. package/docs/commands.md +13 -7
  36. package/docs/e2e-output-examples.md +22 -8
  37. package/docs/quickstart-demo.md +9 -2
  38. package/docs/release-validation.md +32 -6
  39. package/docs/releasing.md +13 -0
  40. package/docs/roadmap.md +20 -10
  41. package/package.json +4 -2
  42. package/schema/qamap-agent.schema.json +42 -1
  43. package/schema/qamap-behavior.schema.json +307 -0
  44. package/skills/qamap-pr-qa/SKILL.md +16 -11
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.4.0 - 2026-07-12
6
+
7
+ ### Added
8
+
9
+ - Added the first framework-neutral Behavior Graph contract with stable content-derived node and edge ids, evidence provenance, direct and propagated impact, deterministic graph merging, adapter diagnostics, and an analyzer adapter interface for future language and framework support.
10
+ - Added a compatibility adapter that maps existing inferred flows, entrypoints, steps, assertions, selectors, fixtures, and changed source files into the graph.
11
+ - Added a verification-manifest Behavior Graph adapter. Matched domains, flows, checks, routes, selectors, and source files now retain reviewed manifest provenance and package-scoped impact inside the graph.
12
+ - Added deterministic Change Intent analysis. Behavior-bearing commits are grouped by normalized product evidence, connected to added diff symbols, assigned confidence and review requirements, and converted into ordered trigger, condition, action, state-change, side-effect, and observable-outcome lifecycles.
13
+ - Added runner-independent primary, failure, boundary, and state-transition QA scenarios derived from each lifecycle. Medium- and high-confidence intent now replaces generic `primary journey` and `smoke flow` candidates before Playwright, Maestro, or manual draft compilation.
14
+ - Added the `qamap.change-intent` Behavior Graph adapter with commit provenance, intent contracts, lifecycle nodes, scenario assertions, source links, and direct or propagated impact.
15
+ - Added Change Intent, lifecycle, and QA scenarios to Markdown, JSON, dry-run, and the additive `qamap.qa` agent format contract.
16
+ - Added public Vue and SvelteKit branch fixtures that require changed selectors, success signals, exact routes, draft paths, and Behavior Graph node kinds to remain useful without React-specific assumptions.
17
+ - Added synthetic web preferences and mobile reminder lifecycle benchmarks. The public matrix now rejects generic titles and directly requires intent names, lifecycle stages, QA scenario axes, commit-backed graph nodes, selectors, outcomes, and draft paths.
18
+ - Added a shipped Behavior Graph JSON Schema and exported runtime enum constants so local consumers and future adapters can validate graph version 1 without an LLM or cloud service.
19
+
20
+ ### Changed
21
+
22
+ - Human reports now present change intent and QA design before runner setup. Playwright, Maestro, and manual output are labeled automation adapters rather than the primary recommendation.
23
+ - Documented the architecture and conservative pre-1.0 version policy: compatible analyzer and adapter improvements remain patch work, while the next minor is reserved for explicit temporary execution and normalized evidence.
24
+
25
+ ### Fixed
26
+
27
+ - Test and benchmark fixtures no longer make a CLI repository look like a design-token or data-catalog project, and a real `package.json` bin entry takes precedence over incidental artifact files.
28
+ - SvelteKit convention files such as `+page.svelte` now resolve to their containing route (`/settings`) instead of adding a false `/page` segment.
29
+ - Language syntax such as TypeScript `export` and `async` no longer contaminates intent clustering or lifecycle state inference, and ordinary web click handlers no longer fabricate external entry-payload scenarios.
30
+
5
31
  ## 0.3.5 - 2026-07-11
6
32
 
7
33
  ### Added
package/README.md CHANGED
@@ -4,14 +4,15 @@
4
4
  [![npm version](https://img.shields.io/npm/v/@ivorycanvas/qamap.svg)](https://www.npmjs.com/package/@ivorycanvas/qamap)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
6
 
7
- **A local-first QA skill for AI-generated PRs. QAMap turns a PR diff into affected flows, missing evidence, and E2E drafts. No cloud. No LLM token.**
7
+ **A local, zero-LLM PR QA designer. QAMap turns commit intent and code diffs into evidence-backed behavior lifecycles, missing QA, and deterministic automation drafts. No cloud. No source upload. No token.**
8
8
 
9
- QAMap reads git changes, project structure, runner signals, selectors, and optional repo QA memory, then answers the question every reviewer asks: *"This PR looks plausible which user flow could it break, and what should we verify before merge?"* It focuses on the judgment step ("what deserves testing"), not on competing with LLMs at writing test code.
9
+ QAMap reads commit subjects and bodies, git changes, project structure, selectors, existing tests, and optional repo QA memory, then answers the question every reviewer asks: *"What behavior did this PR intend to change, how does that behavior move through the product, and what should we verify before merge?"* Playwright, Maestro, and manual checklists are output adapters after that judgment, not the product recommendation itself.
10
10
 
11
11
  ```txt
12
- PR diff
12
+ PR commits + diff
13
13
  -> qamap qa
14
- -> affected flows + missing evidence + PR checklist + E2E starter draft
14
+ -> change intent + behavior lifecycle + QA scenarios + missing evidence
15
+ -> optional Playwright / Maestro / manual draft
15
16
 
16
17
  Optional team memory (.qamap/manifest.yaml)
17
18
  -> sharper recommendations on every future PR
@@ -23,17 +24,19 @@ Optional team memory (.qamap/manifest.yaml)
23
24
 
24
25
  A real, unedited recording on a Next.js app with **zero committed tests**: `qamap qa` names the affected flow, `qamap e2e setup` writes the Playwright config and a starter spec, and `npm run test:e2e` finishes with `1 passed`. First-run assertions are smoke checks — the point is a runnable starting point, not finished coverage.
25
26
 
26
- Every report now opens with the verdict (trimmed real output):
27
+ Every report opens with intent and behavior before automation tooling (trimmed output):
27
28
 
28
29
  ```txt
29
30
  ## At a Glance
30
31
 
31
- - Affected behavior: Checkout Submit
32
- - Verify before merge: ... this outcome is verified: visible text "Order confirmed" appears?
32
+ - Change intent: Submit checkout and persist the confirmed order [high]
33
+ - Behavior lifecycle: trigger: submit checkout -> side-effect: create order -> observable-outcome: show order confirmation
34
+ - Affected behavior: Submit checkout and persist the confirmed order
35
+ - Verify before merge: the confirmed order is visible and survives re-entry
33
36
  - Evidence found: changed file src/pages/checkout/index.tsx; route: /checkout (high); web-test-id: checkout-submit (...)
34
37
  - Proposed draft: `tests/e2e/checkout-submit.spec.ts` (near runnable)
35
- - Next command: `qamap e2e setup . --runner playwright`
36
38
  - Missing before trust: Add deterministic fixture or mock data for /api/checkout (...)
39
+ - Automation adapter: Playwright
37
40
  ```
38
41
 
39
42
  ## Install & Quick Start
@@ -56,11 +59,12 @@ Stop re-explaining the same QA context to your agent on every PR:
56
59
  qamap qa --format agent
57
60
  ```
58
61
 
59
- One minified JSON object (`schema: qamap.qa`, ~2 KB for a small PR) with affected flows, draft paths, required evidence, and the PR checklist the decision content of the full report at a fraction of the context cost. The shape is a documented, versioned contract: [agent format contract](docs/agent-format.md). To make agents run this themselves, run `qamap init --agent` once: it adds a Pre-PR QA section to `AGENTS.md` and installs the packaged skill ([skills/qamap-pr-qa/SKILL.md](skills/qamap-pr-qa/SKILL.md)) into `.claude/skills/`. Details: [agent skill guide](docs/agent-skill.md).
62
+ One minified JSON object (`schema: qamap.qa`) with change intents, lifecycle stages, QA scenarios, affected flows, required evidence, and draft paths. It carries the decision content of the full report at a fraction of the context cost. The shape is a documented, versioned contract: [agent format contract](docs/agent-format.md). To make agents run this themselves, run `qamap init --agent` once: it adds a Pre-PR QA section to `AGENTS.md` and installs the packaged skill ([skills/qamap-pr-qa/SKILL.md](skills/qamap-pr-qa/SKILL.md)) into `.claude/skills/`. Details: [agent skill guide](docs/agent-skill.md).
60
63
 
61
64
  ## Why QAMap
62
65
 
63
- - **Judgment first, generation second.** LLMs write test code well; deciding *what deserves testing* for a given diff is the missing layer. QAMap fills it statically, deterministically, for free.
66
+ - **Intent and lifecycle before runner choice.** QAMap groups behavior-bearing commits, connects them to diff symbols, and proposes success, failure, boundary, and state-transition QA before selecting an automation adapter.
67
+ - **Judgment first, generation second.** Deciding *what deserves testing* for a given change is the missing layer. QAMap makes that judgment statically, deterministically, and locally for free.
64
68
  - **The repo remembers.** Team QA knowledge lives in `.qamap/manifest.yaml`, reviewed once and reused on every PR — instead of re-prompting an agent each session.
65
69
  - **Honest output.** Drafts state what blocks them from being trusted; changed endpoints are observed, never mocked away; generated specs never assert what cannot pass. Configuration, docs, generated artifacts, and changed tests stay in verification mode instead of fabricating a product-journey E2E.
66
70
 
@@ -69,15 +73,15 @@ Positioning against recorders, LLM test generation, and impact-analysis tools: [
69
73
  <details>
70
74
  <summary>한국어 소개</summary>
71
75
 
72
- QAMap는 AI 코딩 에이전트가 만든 PR을 리뷰하기 전에 로컬에서 실행하는 QA 초안 CLI입니다.
76
+ QAMap는 PR을 리뷰하기 전에 로컬에서 실행하는 zero-LLM QA 설계 CLI입니다.
73
77
 
74
- PR diff repo 구조를 읽고 어떤 사용자 플로우가 영향받았는지, 어떤 E2E 또는 체크리스트가 필요한지, fixture/selector/assertion/runner/validation 근거 무엇이 부족한지 정리합니다. 클라우드나 LLM 토큰을 쓰지 않습니다.
78
+ PR 커밋 의도와 diff, repo 구조를 읽고 변경 의도, 기능 생명주기, 정상·실패·경계·상태 전환 QA, 부족한 fixture/selector/assertion 근거를 정리합니다. 다음 기존 테스트 환경에 맞춰 Playwright, Maestro 또는 수동 체크리스트 초안을 제시합니다. 클라우드나 LLM 토큰을 쓰지 않습니다.
75
79
 
76
80
  ```sh
77
81
  pnpm dlx @ivorycanvas/qamap qa . --base origin/main --head HEAD
78
82
  ```
79
83
 
80
- 에이전트에게 넘길 때는 `--format agent`를 붙이면 같은 판단 내용을 2KB의 JSON으로 받을 수 있어, 매 세션 repo 탐색에 토큰을 쓰지 않아도 됩니다.
84
+ 에이전트에게 넘길 때는 `--format agent`를 붙이면 같은 판단 내용을 압축된 JSON으로 받을 수 있어, 매 세션 repo 탐색에 토큰을 반복해서 쓰지 않아도 됩니다.
81
85
 
82
86
  목표는 거대한 QA 플랫폼이 아니라, 유지보수자가 매번 에이전트에게 프로젝트 맥락과 검증 방법을 다시 설명하느라 쓰는 시간을 줄여주는 작고 선명한 도구입니다. Manifest 없이 바로 시작하고, 반복해서 틀리는 추천은 `.qamap/manifest.yaml`에 팀의 QA 언어로 보정해 향후 PR 추천을 개선합니다.
83
87
 
@@ -97,8 +101,9 @@ pnpm dlx @ivorycanvas/qamap qa . --base origin/main --head HEAD
97
101
  | [Configuration](docs/configuration.md) | `qamap.config.json` policy options |
98
102
  | [GitHub Action](docs/github-action.md) | PR annotations, summaries, and comments in CI |
99
103
  | [Benchmarking](docs/benchmarking.md) | Scoring output quality against pinned repositories |
104
+ | [Architecture](docs/architecture.md) | Behavior Graph, adapter boundaries, execution safety, and migration order |
100
105
  | [Roadmap](docs/roadmap.md) | Where this is going |
101
106
 
102
107
  ## Project Status
103
108
 
104
- QAMap is early and pre-`1.0`; the public API may change. Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). QAMap does not replace review, tests, or security tooling; it removes the blank-page work that makes teams skip good verification.
109
+ QAMap is early and pre-`1.0`; the public API may change. Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). QAMap does not replace review, tests, or security tooling; it removes the blank-page work that makes teams skip good verification. AI-assisted PRs are an important use case, not a requirement.
@@ -0,0 +1,6 @@
1
+ import { type BehaviorAnalyzerAdapter } from "./behavior.js";
2
+ import type { ChangeIntentAnalysis } from "./change-intent.js";
3
+ export interface ChangeIntentBehaviorAdapterOptions {
4
+ analysis: ChangeIntentAnalysis;
5
+ }
6
+ export declare function createChangeIntentBehaviorAdapter(options: ChangeIntentBehaviorAdapterOptions): BehaviorAnalyzerAdapter;
@@ -0,0 +1,172 @@
1
+ import { createBehaviorEdge, createBehaviorNodeId, } from "./behavior.js";
2
+ export function createChangeIntentBehaviorAdapter(options) {
3
+ return {
4
+ id: "qamap.change-intent",
5
+ version: "1",
6
+ detect: () => ({
7
+ confidence: detectionConfidence(options.analysis.intents),
8
+ reason: options.analysis.intents.length > 0
9
+ ? "Behavior-bearing commit and diff evidence produced runner-independent change intents."
10
+ : "No behavior-bearing change intent was available.",
11
+ evidence: options.analysis.intents.slice(0, 8).map((intent) => intent.title),
12
+ }),
13
+ analyze: (context) => buildChangeIntentFragment(context, options.analysis.intents),
14
+ };
15
+ }
16
+ function buildChangeIntentFragment(context, intents) {
17
+ const nodes = [];
18
+ const edges = [];
19
+ const changedFiles = new Set(context.changedFiles.map((file) => file.path));
20
+ for (const intent of intents) {
21
+ const confidence = behaviorConfidence(intent.confidence);
22
+ const intentFiles = uniqueStrings(intent.files);
23
+ const directlyChangedFiles = intentFiles.filter((file) => changedFiles.has(file));
24
+ const impactFiles = directlyChangedFiles.length > 0
25
+ ? directlyChangedFiles
26
+ : context.changedFiles.map((file) => file.path).slice(0, 12);
27
+ const contractId = createBehaviorNodeId("contract", "change-intent", intent.id);
28
+ nodes.push({
29
+ id: contractId,
30
+ kind: "contract",
31
+ label: intent.title,
32
+ confidence,
33
+ evidence: intent.evidence.map(toBehaviorEvidence),
34
+ attributes: {
35
+ contractType: "change-intent",
36
+ intentId: intent.id,
37
+ summary: intent.summary,
38
+ reviewRequired: intent.reviewRequired,
39
+ commitCount: intent.commits.length,
40
+ },
41
+ impact: impactFiles.length > 0
42
+ ? {
43
+ kind: directlyChangedFiles.length > 0 ? "direct" : "propagated",
44
+ changedFiles: uniqueStrings(impactFiles),
45
+ }
46
+ : undefined,
47
+ });
48
+ for (const file of intentFiles) {
49
+ const sourceId = createBehaviorNodeId("source", file);
50
+ const direct = changedFiles.has(file);
51
+ nodes.push({
52
+ id: sourceId,
53
+ kind: "source",
54
+ label: file,
55
+ confidence: "high",
56
+ evidence: [{ kind: direct ? "diff" : "source", value: file, file }],
57
+ attributes: { path: file },
58
+ impact: direct ? { kind: "direct", changedFiles: [file] } : undefined,
59
+ });
60
+ edges.push(direct
61
+ ? createBehaviorEdge("impacts", sourceId, contractId, "high", [{ kind: "diff", value: file, file }])
62
+ : createBehaviorEdge("implemented-by", contractId, sourceId, "medium", [{ kind: "source", value: file, file }]));
63
+ }
64
+ let previousStageId;
65
+ intent.lifecycle.forEach((stage, index) => {
66
+ const stageKind = nodeKindForLifecycle(stage);
67
+ const stageId = createBehaviorNodeId(stageKind, "change-intent", intent.id, stage.id);
68
+ const stageFiles = uniqueStrings([
69
+ ...stage.files,
70
+ ...stage.evidence.map((item) => item.file).filter((file) => Boolean(file)),
71
+ ]);
72
+ nodes.push({
73
+ id: stageId,
74
+ kind: stageKind,
75
+ label: stage.label,
76
+ confidence: behaviorConfidence(stage.confidence),
77
+ evidence: stage.evidence.map(toBehaviorEvidence),
78
+ attributes: {
79
+ intentId: intent.id,
80
+ lifecyclePhase: stage.kind,
81
+ order: index + 1,
82
+ },
83
+ impact: stageFiles.length > 0
84
+ ? { kind: "direct", changedFiles: stageFiles }
85
+ : impactFiles.length > 0
86
+ ? { kind: "propagated", changedFiles: uniqueStrings(impactFiles) }
87
+ : undefined,
88
+ });
89
+ edges.push(createBehaviorEdge(stage.kind === "observable-outcome" ? "expects" : "contains", contractId, stageId, behaviorConfidence(stage.confidence), stage.evidence.map(toBehaviorEvidence)));
90
+ if (previousStageId) {
91
+ edges.push(createBehaviorEdge("precedes", previousStageId, stageId, behaviorConfidence(stage.confidence)));
92
+ }
93
+ previousStageId = stageId;
94
+ for (const file of stageFiles) {
95
+ const sourceId = createBehaviorNodeId("source", file);
96
+ if (intentFiles.includes(file)) {
97
+ edges.push(createBehaviorEdge("implemented-by", stageId, sourceId, "high", [
98
+ { kind: changedFiles.has(file) ? "diff" : "source", value: file, file },
99
+ ]));
100
+ }
101
+ }
102
+ });
103
+ for (const scenario of intent.scenarios) {
104
+ for (const [assertionIndex, assertion] of scenario.assertions.entries()) {
105
+ const assertionId = createBehaviorNodeId("assertion", "change-intent", intent.id, scenario.id, String(assertionIndex), assertion);
106
+ nodes.push({
107
+ id: assertionId,
108
+ kind: "assertion",
109
+ label: assertion,
110
+ confidence: scenario.priority === "critical" ? confidence : "medium",
111
+ evidence: scenario.evidence.map(toBehaviorEvidence),
112
+ attributes: {
113
+ intentId: intent.id,
114
+ scenarioId: scenario.id,
115
+ scenarioKind: scenario.kind,
116
+ scenarioTitle: scenario.title,
117
+ priority: scenario.priority,
118
+ },
119
+ impact: impactFiles.length > 0
120
+ ? { kind: "propagated", changedFiles: uniqueStrings(impactFiles) }
121
+ : undefined,
122
+ });
123
+ edges.push(createBehaviorEdge("expects", contractId, assertionId, scenario.priority === "critical" ? confidence : "medium"));
124
+ }
125
+ }
126
+ }
127
+ return { nodes, edges };
128
+ }
129
+ function nodeKindForLifecycle(stage) {
130
+ if (stage.kind === "condition" || stage.kind === "state-change") {
131
+ return "state";
132
+ }
133
+ if (stage.kind === "side-effect") {
134
+ return "effect";
135
+ }
136
+ if (stage.kind === "observable-outcome") {
137
+ return "assertion";
138
+ }
139
+ return "action";
140
+ }
141
+ function toBehaviorEvidence(evidence) {
142
+ if (evidence.kind === "commit") {
143
+ return {
144
+ kind: "commit",
145
+ value: evidence.commit ? `${evidence.commit.slice(0, 12)} ${evidence.value}` : evidence.value,
146
+ };
147
+ }
148
+ return {
149
+ kind: evidence.kind,
150
+ value: evidence.symbol ? `${evidence.symbol}: ${evidence.value}` : evidence.value,
151
+ file: evidence.file,
152
+ };
153
+ }
154
+ function detectionConfidence(intents) {
155
+ if (intents.length === 0) {
156
+ return "none";
157
+ }
158
+ if (intents.some((intent) => intent.confidence === "high")) {
159
+ return "high";
160
+ }
161
+ if (intents.some((intent) => intent.confidence === "medium")) {
162
+ return "medium";
163
+ }
164
+ return "low";
165
+ }
166
+ function behaviorConfidence(confidence) {
167
+ return confidence;
168
+ }
169
+ function uniqueStrings(values) {
170
+ return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
171
+ }
172
+ //# sourceMappingURL=behavior-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-intent.js","sourceRoot":"","sources":["../src/behavior-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type BehaviorAnalyzerAdapter } from "./behavior.js";
2
+ import type { VerificationManifestMatch } from "./manifest.js";
3
+ export interface ManifestBehaviorAdapterOptions {
4
+ matches: VerificationManifestMatch[];
5
+ }
6
+ export declare function createManifestBehaviorAdapter(options: ManifestBehaviorAdapterOptions): BehaviorAnalyzerAdapter;
@@ -0,0 +1,221 @@
1
+ import path from "node:path";
2
+ import { createBehaviorEdge, createBehaviorNodeId, } from "./behavior.js";
3
+ export function createManifestBehaviorAdapter(options) {
4
+ return {
5
+ id: "qamap.verification-manifest",
6
+ version: "1",
7
+ detect: () => ({
8
+ confidence: manifestDetectionConfidence(options.matches),
9
+ reason: options.matches.length > 0
10
+ ? "The repository verification manifest matched this branch and can supply reviewed behavior evidence."
11
+ : "No verification manifest entries matched this branch.",
12
+ evidence: uniqueStrings(options.matches.map((match) => match.manifestPath)).slice(0, 12),
13
+ }),
14
+ analyze: (context) => buildManifestBehaviorFragment(context, options.matches),
15
+ };
16
+ }
17
+ function buildManifestBehaviorFragment(context, matches) {
18
+ const nodes = [];
19
+ const edges = [];
20
+ const changedFiles = new Set(context.changedFiles.map((file) => file.path));
21
+ const flowMatches = new Map(matches.filter((match) => match.kind === "flow").map((match) => [match.id, match]));
22
+ const domainNodes = [];
23
+ const flowNodes = [];
24
+ for (const match of [...matches].sort(compareManifestMatches)) {
25
+ const files = manifestFilesForContext(context, match.matchedFiles);
26
+ const nodeKind = nodeKindForMatch(match);
27
+ const nodeId = manifestNodeId(nodeKind, match.id);
28
+ const impact = manifestImpact(context, files, changedFiles);
29
+ const evidence = manifestEvidence(match, files);
30
+ nodes.push({
31
+ id: nodeId,
32
+ kind: nodeKind,
33
+ label: match.name,
34
+ confidence: match.confidence,
35
+ evidence,
36
+ attributes: manifestAttributes(match),
37
+ impact,
38
+ });
39
+ if (match.kind === "domain") {
40
+ domainNodes.push({ match, nodeId, files });
41
+ }
42
+ else if (match.kind === "flow") {
43
+ flowNodes.push({ match, nodeId, files });
44
+ }
45
+ for (const file of files) {
46
+ const sourceId = createBehaviorNodeId("source", file);
47
+ const direct = changedFiles.has(file);
48
+ nodes.push({
49
+ id: sourceId,
50
+ kind: "source",
51
+ label: file,
52
+ confidence: "high",
53
+ evidence: [
54
+ { kind: direct ? "diff" : "source", value: file, file },
55
+ { kind: "manifest", value: match.manifestPath, file },
56
+ ],
57
+ attributes: { path: file },
58
+ impact: direct ? { kind: "direct", changedFiles: [file] } : undefined,
59
+ });
60
+ edges.push(direct
61
+ ? createBehaviorEdge("impacts", sourceId, nodeId, "high", [{ kind: "manifest", value: match.manifestPath, file }])
62
+ : createBehaviorEdge("implemented-by", nodeId, sourceId, match.confidence, [
63
+ { kind: "manifest", value: match.manifestPath, file },
64
+ ]));
65
+ }
66
+ if (match.kind === "flow" && match.entryRoute) {
67
+ const surfaceId = createBehaviorNodeId("surface", "manifest-route", match.entryRoute, match.id);
68
+ nodes.push({
69
+ id: surfaceId,
70
+ kind: "surface",
71
+ label: `route: ${match.entryRoute}`,
72
+ confidence: match.confidence,
73
+ evidence: [{ kind: "manifest", value: match.manifestPath }],
74
+ attributes: { entrypointKind: "route", value: match.entryRoute, surface: "web", source: "manifest" },
75
+ });
76
+ edges.push(createBehaviorEdge("enters-at", nodeId, surfaceId, match.confidence, evidence));
77
+ }
78
+ if (match.kind === "check") {
79
+ const flowId = parentFlowId(match.id);
80
+ const parentMatch = flowMatches.get(flowId);
81
+ const parentNodeId = manifestNodeId("flow", flowId);
82
+ if (!parentMatch) {
83
+ nodes.push({
84
+ id: parentNodeId,
85
+ kind: "flow",
86
+ label: flowId,
87
+ confidence: match.confidence,
88
+ evidence,
89
+ attributes: { manifestId: flowId, source: "manifest" },
90
+ impact,
91
+ });
92
+ }
93
+ edges.push(createBehaviorEdge("expects", parentNodeId, nodeId, match.confidence, evidence));
94
+ if (match.checkSelector) {
95
+ const locatorId = createBehaviorNodeId("locator", "manifest", match.checkSelector, match.id);
96
+ nodes.push({
97
+ id: locatorId,
98
+ kind: "locator",
99
+ label: `manifest selector: ${match.checkSelector}`,
100
+ confidence: match.confidence,
101
+ evidence: [{ kind: "manifest", value: match.manifestPath }],
102
+ attributes: { value: match.checkSelector, source: "manifest" },
103
+ });
104
+ edges.push(createBehaviorEdge("located-by", nodeId, locatorId, match.confidence, evidence));
105
+ }
106
+ }
107
+ }
108
+ for (const domain of domainNodes) {
109
+ for (const flow of flowNodes) {
110
+ if (!filesOverlap(domain.files, flow.files)) {
111
+ continue;
112
+ }
113
+ edges.push(createBehaviorEdge("contains", domain.nodeId, flow.nodeId, weakerConfidence(domain.match.confidence, flow.match.confidence), [
114
+ { kind: "manifest", value: domain.match.manifestPath },
115
+ { kind: "manifest", value: flow.match.manifestPath },
116
+ ]));
117
+ }
118
+ }
119
+ return { nodes, edges };
120
+ }
121
+ function manifestNodeId(kind, id) {
122
+ return createBehaviorNodeId(kind, "manifest", id);
123
+ }
124
+ function nodeKindForMatch(match) {
125
+ if (match.kind === "domain") {
126
+ return "domain";
127
+ }
128
+ if (match.kind === "flow") {
129
+ return "flow";
130
+ }
131
+ return "assertion";
132
+ }
133
+ function manifestDetectionConfidence(matches) {
134
+ if (matches.some((match) => match.kind === "flow" || match.kind === "check")) {
135
+ return "high";
136
+ }
137
+ return matches.length > 0 ? "medium" : "none";
138
+ }
139
+ function manifestImpact(context, matchedFiles, changedFiles) {
140
+ const directFiles = uniqueStrings(matchedFiles).filter((file) => changedFiles.has(file));
141
+ if (directFiles.length > 0) {
142
+ return { kind: "direct", changedFiles: directFiles };
143
+ }
144
+ const propagatedFiles = context.changedFiles.map((file) => file.path).slice(0, 12);
145
+ return propagatedFiles.length > 0 ? { kind: "propagated", changedFiles: propagatedFiles } : undefined;
146
+ }
147
+ function manifestEvidence(match, files) {
148
+ return [
149
+ { kind: "manifest", value: match.manifestPath },
150
+ ...match.evidenceSources.map((source) => ({ kind: "manifest", value: source })),
151
+ ...files.slice(0, 12).map((file) => ({ kind: "source", value: file, file })),
152
+ ];
153
+ }
154
+ function manifestFilesForContext(context, matchedFiles) {
155
+ const workspaceRoot = context.workspaceRoot ? path.resolve(context.workspaceRoot) : undefined;
156
+ const root = path.resolve(context.root);
157
+ if (!workspaceRoot || workspaceRoot === root) {
158
+ return uniqueStrings(matchedFiles.map(toPosixPath));
159
+ }
160
+ const packagePrefix = toPosixPath(path.relative(workspaceRoot, root)).replace(/^\.\/+|\/+$/g, "");
161
+ if (!packagePrefix || packagePrefix.startsWith("..")) {
162
+ return uniqueStrings(matchedFiles.map(toPosixPath));
163
+ }
164
+ return uniqueStrings(matchedFiles.map((file) => {
165
+ const normalized = toPosixPath(file).replace(/^\.\/+/, "");
166
+ return normalized.startsWith(`${packagePrefix}/`) ? normalized.slice(packagePrefix.length + 1) : normalized;
167
+ }));
168
+ }
169
+ function manifestAttributes(match) {
170
+ const attributes = {
171
+ manifestId: match.id,
172
+ matchKind: match.kind,
173
+ source: "manifest",
174
+ updatePath: match.updatePath,
175
+ };
176
+ if (match.criticality) {
177
+ attributes.criticality = match.criticality;
178
+ }
179
+ if (match.runner) {
180
+ attributes.runner = match.runner;
181
+ }
182
+ if (match.entryRoute) {
183
+ attributes.entryRoute = match.entryRoute;
184
+ }
185
+ if (match.checkType) {
186
+ attributes.checkType = match.checkType;
187
+ }
188
+ if (match.checkSelector) {
189
+ attributes.checkSelector = match.checkSelector;
190
+ }
191
+ if (match.checkValue) {
192
+ attributes.checkValue = match.checkValue;
193
+ }
194
+ if (match.checkSteps && match.checkSteps.length > 0) {
195
+ attributes.checkSteps = match.checkSteps;
196
+ }
197
+ return attributes;
198
+ }
199
+ function parentFlowId(checkId) {
200
+ const parts = checkId.split(".");
201
+ return parts.length > 1 ? parts.slice(0, -1).join(".") : checkId;
202
+ }
203
+ function filesOverlap(left, right) {
204
+ const leftFiles = new Set(left);
205
+ return right.some((file) => leftFiles.has(file));
206
+ }
207
+ function weakerConfidence(left, right) {
208
+ const rank = { low: 1, medium: 2, high: 3 };
209
+ return rank[left] <= rank[right] ? left : right;
210
+ }
211
+ function compareManifestMatches(left, right) {
212
+ const kindRank = { domain: 0, flow: 1, check: 2 };
213
+ return kindRank[left.kind] - kindRank[right.kind] || left.id.localeCompare(right.id);
214
+ }
215
+ function uniqueStrings(items) {
216
+ return [...new Set(items.map((item) => item.trim()).filter(Boolean))];
217
+ }
218
+ function toPosixPath(value) {
219
+ return value.split(path.sep).join("/");
220
+ }
221
+ //# sourceMappingURL=behavior-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-manifest.js","sourceRoot":"","sources":["../src/behavior-manifest.ts"],"names":[],"mappings":"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"}