@ghostlygawd/codeweb 0.9.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/.claude-plugin/plugin.json +30 -0
- package/CHANGELOG.md +480 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/agents/codeweb-dissector.md +56 -0
- package/agents/codeweb-domain-mapper.md +63 -0
- package/commands/codeweb.md +57 -0
- package/hooks/hooks.json +47 -0
- package/hooks/post-edit-diff.mjs +83 -0
- package/hooks/pre-edit-impact.mjs +94 -0
- package/hooks/session-brief.mjs +53 -0
- package/package.json +64 -0
- package/scripts/annotate.mjs +46 -0
- package/scripts/bench-ts-engine.mjs +59 -0
- package/scripts/bench.mjs +133 -0
- package/scripts/break-cycles.mjs +0 -0
- package/scripts/brief.mjs +28 -0
- package/scripts/build-report.mjs +182 -0
- package/scripts/campaign.mjs +61 -0
- package/scripts/check-consistency.mjs +45 -0
- package/scripts/ci-gate.mjs +86 -0
- package/scripts/cluster3.mjs +112 -0
- package/scripts/codemod.mjs +130 -0
- package/scripts/context-pack.mjs +118 -0
- package/scripts/deadcode.mjs +96 -0
- package/scripts/diff.mjs +0 -0
- package/scripts/explain.mjs +87 -0
- package/scripts/extract-symbols.mjs +1307 -0
- package/scripts/find-similar.mjs +86 -0
- package/scripts/find.mjs +50 -0
- package/scripts/fitness.mjs +90 -0
- package/scripts/grammars/PROVENANCE.md +36 -0
- package/scripts/grammars/tree-sitter-c-sharp.wasm +0 -0
- package/scripts/grammars/tree-sitter-go.wasm +0 -0
- package/scripts/grammars/tree-sitter-java.wasm +0 -0
- package/scripts/grammars/tree-sitter-python.wasm +0 -0
- package/scripts/grammars/tree-sitter-rust.wasm +0 -0
- package/scripts/grammars/tree-sitter-typescript.wasm +0 -0
- package/scripts/hotspots.mjs +53 -0
- package/scripts/lib/annotations.mjs +51 -0
- package/scripts/lib/bench-core.mjs +178 -0
- package/scripts/lib/brief-core.mjs +92 -0
- package/scripts/lib/campaign.mjs +73 -0
- package/scripts/lib/claims-check.mjs +44 -0
- package/scripts/lib/cli.mjs +140 -0
- package/scripts/lib/complexity.mjs +68 -0
- package/scripts/lib/dup-check.mjs +51 -0
- package/scripts/lib/find-core.mjs +85 -0
- package/scripts/lib/gate-md.mjs +50 -0
- package/scripts/lib/graph-ops.mjs +319 -0
- package/scripts/lib/hotspots.mjs +34 -0
- package/scripts/lib/query-core.mjs +85 -0
- package/scripts/lib/reading-order.mjs +53 -0
- package/scripts/lib/reliance.mjs +143 -0
- package/scripts/lib/risk.mjs +18 -0
- package/scripts/lib/shingles.mjs +39 -0
- package/scripts/lib/skeleton.mjs +41 -0
- package/scripts/lib/stats.mjs +92 -0
- package/scripts/lib/ts-engine.mjs +605 -0
- package/scripts/mcp-server.mjs +370 -0
- package/scripts/optimize.mjs +152 -0
- package/scripts/overlap.mjs +380 -0
- package/scripts/placement.mjs +93 -0
- package/scripts/query.mjs +94 -0
- package/scripts/reading-order.mjs +36 -0
- package/scripts/refresh.mjs +73 -0
- package/scripts/release-utils.mjs +158 -0
- package/scripts/release.mjs +62 -0
- package/scripts/report-template.html +730 -0
- package/scripts/review.mjs +112 -0
- package/scripts/risk.mjs +77 -0
- package/scripts/run.mjs +96 -0
- package/scripts/screenshot.mjs +104 -0
- package/scripts/simulate-edit.mjs +70 -0
- package/scripts/stats.mjs +31 -0
- package/scripts/trend.mjs +147 -0
- package/scripts/version-sync.mjs +19 -0
- package/skills/codebase-anatomy/SKILL.md +174 -0
- package/skills/codebase-anatomy/references/engine-detection.md +49 -0
- package/skills/codebase-anatomy/references/graph-schema.md +120 -0
- package/skills/codebase-anatomy/references/overlap-heuristics.md +52 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codeweb",
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "Dissect a codebase to its atomic parts (functions, classes, symbols), wire them into a living system web (call/import graph), tag each node's domain, and surface cross-domain overlap and consolidation opportunities. Renders a self-contained interactive HTML map for humans, and exposes 24 deterministic read-only query tools over MCP (impact, callers, duplication, risk, dead code, …) so a coding agent can check what already exists and what an edit breaks before writing. Works on the current project or any external repo you want to review before adopting.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "rhenmcleod",
|
|
7
|
+
"email": "rhenmcleod@gmail.com"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/GhostlyGawd/codeweb",
|
|
10
|
+
"repository": "https://github.com/GhostlyGawd/codeweb",
|
|
11
|
+
"hooks": "./hooks/hooks.json",
|
|
12
|
+
"mcpServers": {
|
|
13
|
+
"codeweb": {
|
|
14
|
+
"command": "node",
|
|
15
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/mcp-server.mjs"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"codebase-analysis",
|
|
20
|
+
"dependency-graph",
|
|
21
|
+
"call-graph",
|
|
22
|
+
"architecture",
|
|
23
|
+
"duplication",
|
|
24
|
+
"refactoring",
|
|
25
|
+
"domain-mapping",
|
|
26
|
+
"code-review",
|
|
27
|
+
"visualization"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT"
|
|
30
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **codeweb** are recorded here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
Beyond the usual change groups, releases also carry **Research** and **Capabilities**
|
|
8
|
+
notes so validated results, papers, and new tools never get lost in commit history.
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
_Nothing yet. Open work lands here before it ships in the next tagged release._
|
|
13
|
+
|
|
14
|
+
## [0.9.0] - 2026-07-19
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **Warm refreshes stop paying the AST tax (Spec A).** The tree-sitter engine now initializes
|
|
18
|
+
lazily — a cheap availability probe decides cache namespaces and meta stamps up front, and
|
|
19
|
+
the WASM runtime loads only at the first file that actually needs a parse. AST products
|
|
20
|
+
(qualified methods, dispatch edges, exact per-node complexity) ride the scan cache, so a
|
|
21
|
+
warm cached extraction on codeweb itself dropped **1.89s → 0.38s (5×)** with byte-identical
|
|
22
|
+
fragments — felt directly by the MCP auto-refresh, the post-edit hook, and every staleness
|
|
23
|
+
check. The banner now reports the tier's state (`ast: loaded|idle|off`).
|
|
24
|
+
- **The AST performance gate finally has a committed verdict**
|
|
25
|
+
(`bench/results/ts-engine-bench.json`): cold extraction costs 3.6–4.3× regex
|
|
26
|
+
(~+1.35 ms/symbol, axios + self) — paid once per changed file — and the warm path is
|
|
27
|
+
engine-free, so default-on stands. Also fixes the bench's regex arm, which had silently
|
|
28
|
+
benchmarked tree-sitter against itself ever since the tier went default-on.
|
|
29
|
+
- **The pipeline memoizes its downstream stages (Spec B).** cluster/overlap/optimize/report
|
|
30
|
+
are pure functions of the extracted fragment (+ `CODEWEB_*` levers), so a re-run whose
|
|
31
|
+
fragment is byte-identical reuses their outputs — wall-time changes, never a byte
|
|
32
|
+
(property-tested modulo the `generatedAt` stamp). Extract itself now rides the scan cache
|
|
33
|
+
inside `run.mjs`, making a no-change re-map of codeweb **~0.4s end to end**. `--full`
|
|
34
|
+
forces a recompute.
|
|
35
|
+
- **Overlap survives monorepo scale — with declared caps.** Mapping TypeScript's `src/`
|
|
36
|
+
exposed two quadratic passes (overlap sat at 100% CPU for 8+ minutes): all-pairs body
|
|
37
|
+
confirmation inside huge same-name groups, and twin seeding through hub labels with
|
|
38
|
+
thousands of callers. Same-name groups now body-confirm on a deterministic 12-node sample
|
|
39
|
+
(the finding's evidence says so), >50-caller hub labels are excluded from twin seeding, a
|
|
40
|
+
200k global pair budget seeds smallest groups first, and 400+-line bodies shingle their
|
|
41
|
+
first 400 lines — every cap counted in the md header. Deterministic, reported, never silent.
|
|
42
|
+
- **Fixed: an input-dependent HANG in the shared tokenizer.** The string-literal regex in
|
|
43
|
+
`lib/shingles.mjs` (`(?:\\.|(?!\1).)*`) backtracked exponentially on unterminated-quote
|
|
44
|
+
content — one lone apostrophe in a big real-world body (TypeScript's testRunner fixtures)
|
|
45
|
+
pinned the whole overlap stage at 100% CPU for 15+ minutes. Replaced with a linear-time
|
|
46
|
+
matcher (each char consumed exactly one way) + a regression test; identical semantics.
|
|
47
|
+
Found by the Spec B scale test; this also protects `find_similar` and the edit-time
|
|
48
|
+
duplication check, which share the tokenizer.
|
|
49
|
+
- **The scale verdict is committed** (`bench/results/scale-typescript.json`): TypeScript
|
|
50
|
+
`src/` — 16,286 symbols, 44,640 edges, 709 files including `checker.ts` — maps in **43s
|
|
51
|
+
cold, 4s memoized re-run**, queries answer in ~200ms on the 13.5MB graph, and the top
|
|
52
|
+
findings are real compiler duplication (`substituteExpression` ×9, drifted). On that
|
|
53
|
+
evidence `lib/shards.mjs` is **deleted**: monolithic graphs hold with 10× headroom, the
|
|
54
|
+
sharding layer had zero consumers, and git history keeps it if a 100k-symbol case ever
|
|
55
|
+
materializes.
|
|
56
|
+
- **codeweb consolidated itself** (`bench/results/self-campaign.json`): the campaign's three
|
|
57
|
+
product-true merges are executed — `findTarget` (both hooks; the duplication had hidden
|
|
58
|
+
REAL drift, one hook's language list was seven languages stale), `load()` (diff/review →
|
|
59
|
+
the canonical `loadGraph`, with better errors), and `edgeKey` (break-cycles/diff →
|
|
60
|
+
graph-ops, NUL-separated collision-safe variant). Before/after gate: −22 nodes, −2
|
|
61
|
+
duplication findings, coupling −25, **zero structural regressions**. The 65 DELETE steps
|
|
62
|
+
are honestly skipped as false orphans (walker closures dispatched through function tables —
|
|
63
|
+
exactly the `--orphans` cross-check caveat, applied to ourselves).
|
|
64
|
+
- **`npm run bench:all` — the standing benchmark suite behind every published number**
|
|
65
|
+
(Spec C): pipeline timings, a representative 12-call MCP session (bytes/≈tokens/validity),
|
|
66
|
+
per-tool response budgets, and the ts-engine gate, written to `bench/results/benchmarks.json`
|
|
67
|
+
(+ a site mirror). A new CI job runs it with `--gate`: budgets live in `bench/budgets.json`,
|
|
68
|
+
and breaking one fails the build. `check-consistency` now also audits that every evidence
|
|
69
|
+
source cited by the ledger and README exists — claims physically can't rot.
|
|
70
|
+
- **Replay A/B gains cost-to-coverage (Spec D).** The workflow runs cells sequentially and
|
|
71
|
+
records each cell's true token cost from the harness's own `budget.spent()` deltas (never
|
|
72
|
+
solver self-report); the analyzer reports per-condition means and `costToFullCoverageTokens`
|
|
73
|
+
— the discriminator when both arms hit the coverage ceiling. Old cells without cost report
|
|
74
|
+
null and are counted, not fabricated. **Corpus v3 is frozen** after nine mining runs across
|
|
75
|
+
six repos (funnels committed as `bench/results/replay-mine-*.json`): the miner re-derived
|
|
76
|
+
the v2 task independently at a wider follow-up window (identical answer key — the instrument
|
|
77
|
+
reproduces its own ground truth), one new 4-caller candidate was rejected under
|
|
78
|
+
hand-verification (a feature-PR rewrite mentioning the symbol, not a caller fix), and the
|
|
79
|
+
corpus stays at one fully-verified task — honestly. True-breakage tasks are rare; that is
|
|
80
|
+
the finding.
|
|
81
|
+
- **Role overrides (Spec E).** `codeweb.rules.json` gains `roles: [{glob, role}]` — heuristics
|
|
82
|
+
can't know a repo's private layout, so the repo says it once and extraction honors it (first
|
|
83
|
+
match wins, invalid roles fail loudly, absent config is byte-identical to before). codeweb's
|
|
84
|
+
own config marks `docs/**` as `generated` (it's the built website), completing the
|
|
85
|
+
vite-playground precision lesson on our own map.
|
|
86
|
+
- **Python, Go, and Rust join the dispatch tier (Spec F).** Three vendored pinned grammars +
|
|
87
|
+
dedicated tree walkers wire the calls regex precision-gates away: `self.m()`/`cls.m()`,
|
|
88
|
+
Go receiver methods, Rust `self.m()`, and typed-receiver calls (`p: Pipe`, `q Pipe`,
|
|
89
|
+
`p: &Pipe`) resolved globally under the one-owner rule — ambiguity drops and is counted,
|
|
90
|
+
never guessed. Nodes stay byte-identical between engines; products ride the scan cache.
|
|
91
|
+
- **Caller-reliance contracts v2 (Spec G).** The explain card (and the ambient pre-edit card)
|
|
92
|
+
now also reports: callers that try/catch or `.catch()` the symbol ("thrown types are
|
|
93
|
+
contract"), callees that mutate a named parameter ("callers share that object"), and callers
|
|
94
|
+
that null-check the result ("keep null/undefined returns possible"). Same conservatism as
|
|
95
|
+
v1 — line-visible evidence or no claim.
|
|
96
|
+
- **Type-3 (near-miss) clone detection (Spec H).** The AST tier fingerprints each function's
|
|
97
|
+
statements (identifier/literal-normalized, order-independent multiset); overlap pairs bodies
|
|
98
|
+
sharing ≥70% of them — reordered or lightly-edited copies the exact and Type-2 passes cannot
|
|
99
|
+
see. A distinct `near-miss-clone` finding kind, REVIEW-only by construction, bounded and
|
|
100
|
+
deterministic.
|
|
101
|
+
- **Ruby, PHP, Kotlin, and Swift on the deterministic fast path (Spec I)** — eleven native
|
|
102
|
+
languages. Discovery with owner-qualified methods (Ruby `def self.`, Kotlin extension
|
|
103
|
+
`fun Type.name`, Swift `extension` members), visibility-as-export per language's own rules,
|
|
104
|
+
comment/string masking, precision-gated calls, test-role detection (`spec/`, `_spec.rb`,
|
|
105
|
+
`*Test.php`, `*Tests.swift`), and package manifests (Gemfile, composer.json, Package.swift).
|
|
106
|
+
Verified on sinatra (1,173 symbols), monolog (1,622), okio (3,874, mixed Kotlin+Java),
|
|
107
|
+
and Alamofire (2,616) — zero keyword phantoms, deterministic.
|
|
108
|
+
- **The report closes the loop to the editor (Spec J).** The inspector shows `Open in editor`
|
|
109
|
+
(`vscode://file/...`) once the viewer supplies their project root — stored in localStorage,
|
|
110
|
+
client-side only, because the shipped report still never embeds the absolute source path
|
|
111
|
+
(the standing privacy invariant, now pinned by a second test).
|
|
112
|
+
- **npm + VS Code distribution, prepared (Spec J).** The package is publish-ready (`codeweb` +
|
|
113
|
+
`codeweb-mcp` bins with shebangs, files whitelist, LICENSE, zero runtime deps — verified by
|
|
114
|
+
an `npm pack` test); the release workflow builds and attaches the `.vsix` to every GitHub
|
|
115
|
+
Release and carries npm/Marketplace publish steps that no-op until `NPM_TOKEN`/`VSCE_PAT`
|
|
116
|
+
are configured. Publishing stays a human decision; the prep is done.
|
|
117
|
+
|
|
118
|
+
### Changed
|
|
119
|
+
- **The paper program is archived; the receipts stay.** `paper/` is retired from `main`:
|
|
120
|
+
the runnable instruments and every frozen result (nulls and the discarded pilot included)
|
|
121
|
+
now live in **`bench/`** as the product's benchmark suite (`bench/README.md`,
|
|
122
|
+
`node bench/run-all.mjs`), and the site's Paper page is gone — the evidence ledger on the
|
|
123
|
+
Research page (now including the 2026 blind replay A/B null) plus the CHANGELOG's Research
|
|
124
|
+
notes are the public record. The manuscript, pre-registration (H1–H18), and figure
|
|
125
|
+
apparatus remain in git history, last present at tag `v0.8.0`. README and ROADMAP
|
|
126
|
+
rewritten to point at receipts instead of the manuscript.
|
|
127
|
+
|
|
128
|
+
## [0.8.0] - 2026-07-19
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
- **Java and C# call wiring (tree-sitter dispatch tier).** The regex engine still finds every
|
|
132
|
+
symbol; for Java/C# files an optional AST pass now adds the call edges regex could never
|
|
133
|
+
claim safely: `this.helper()` calls inside a class, and `receiver.method()` calls where the
|
|
134
|
+
receiver's declared type names exactly one class in the repo (two classes with the same name
|
|
135
|
+
→ the edge is dropped and counted in the banner, never guessed). Nodes are untouched —
|
|
136
|
+
identical between engines — so determinism holds. Grammars vendored from
|
|
137
|
+
`@vscode/tree-sitter-wasm@0.3.1` (`scripts/grammars/PROVENANCE.md` records the ABI trap that
|
|
138
|
+
rules out the older grammar package). Spec: `docs/specs/java-cs-tree-sitter.md`.
|
|
139
|
+
- **The ledger now counts whether advice was FOLLOWED, not just delivered.** When a pre-edit
|
|
140
|
+
card names caller files and a later edit in the same session touches one of them (30-minute
|
|
141
|
+
window, once per file, the changed symbol's own file excluded), the ledger bumps
|
|
142
|
+
`cardCallersFollowed` and the session brief reports "N card-named caller(s) followed" —
|
|
143
|
+
the difference between "we showed advice" and "the advice changed what happened."
|
|
144
|
+
Spec: `docs/specs/card-correlation.md`.
|
|
145
|
+
|
|
146
|
+
### Research
|
|
147
|
+
- **The replay miner is tested and honest about its funnel.** `paper/experiments/replay-mine.mjs`
|
|
148
|
+
(mines real commits that changed a function's definition and — per the repo's own later
|
|
149
|
+
fixes — missed caller files) gained a TDD suite on synthetic git histories
|
|
150
|
+
(`tests/replay-mine.test.mjs`, P1–P5) and a stage-by-stage funnel report. The tests + a
|
|
151
|
+
hand-audit of the first frozen corpus exposed and fixed three miner bugs: a prefilter that
|
|
152
|
+
silently zeroed every Java/C# candidate, a raw def-line comparison that read a prettier
|
|
153
|
+
reformat as a "signature change" (which had produced 2 invalid tasks), and instructions
|
|
154
|
+
truncated mid-hunk at 4KB (now: complete-or-rejected). Spec: `docs/specs/replay-corpus.md`.
|
|
155
|
+
- **The replay A/B protocol went blind before spending.** The v1 pilot leaked its own answer
|
|
156
|
+
key three ways (the grading list pasted into solver prompts, self-reported coverage, and
|
|
157
|
+
full-history isolation that let solvers read the historical fix commit). It is preserved —
|
|
158
|
+
discarded — in `paper/results/replay-ab-pilot.json`; the v2 harness solves in a
|
|
159
|
+
history-free export of the base revision and the workflow itself computes coverage as
|
|
160
|
+
`filesChanged ∩ missedByChange`. Spec amendments: `docs/specs/replay-run.md`.
|
|
161
|
+
- **Replay A/B result: both arms at ceiling (honest null).** The v2 corpus froze at ONE
|
|
162
|
+
fully-verified task — axios `buildFullPath` gaining `allowAbsoluteUrls`, where the real 2025
|
|
163
|
+
change missed 2 of its 3 caller files and axios needed two follow-up PRs (#6810, #6814).
|
|
164
|
+
Blind-replayed 4× per arm: all 8 cells covered both missed files with 0 structural
|
|
165
|
+
regressions — with or without codeweb. On a 3-caller single-package change, a capable
|
|
166
|
+
agent's grep saturates; the historical miss does not reproduce, so ambient context is
|
|
167
|
+
bounded near zero **on this task shape**. The run proves the instrument (leak-free,
|
|
168
|
+
fixed-function grading, ambient engagement verified in every treatment cell — the card's
|
|
169
|
+
caller list matched ground truth exactly) and shows guarded mining makes true breakage
|
|
170
|
+
tasks RARE: 2 of 3 v1 tasks and the only new candidate died under scrutiny. Discriminating
|
|
171
|
+
between the arms needs many-caller cross-package tasks or cost-to-coverage metrics —
|
|
172
|
+
recorded as the corpus growth path. Full data: `paper/results/replay-ab{,-raw}.json`.
|
|
173
|
+
|
|
174
|
+
## [0.7.1] - 2026-07-19
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
- **README screenshots crop to content.** The regenerated shots were uniform full-page
|
|
178
|
+
frames — squeezed into README boxes, the matrix rendered ~170px wide and the blast
|
|
179
|
+
shot's inspector was unreadable. `scripts/screenshot.mjs` now crops each frame to what
|
|
180
|
+
it shows: the graph to its drawn bounding box, the blast shot to the LIT selection
|
|
181
|
+
(tracked from the draw pass) + inspector at a tighter zoom, the matrix to its table +
|
|
182
|
+
legend. README display sizes and the stale corpus line ("274 symbols across 8
|
|
183
|
+
domains" → the real 334/11) synced; shots remain one-command regenerable.
|
|
184
|
+
|
|
185
|
+
## [0.7.0] - 2026-07-19
|
|
186
|
+
|
|
187
|
+
### Changed (the report finally looks like the product it is)
|
|
188
|
+
- **A validated color system replaces generated hues.** Area colors were `hsl(i × 137.5°)` —
|
|
189
|
+
unbounded spun hues; the treemap ramped green→red at full saturation (measured deutan
|
|
190
|
+
ΔE 2.2 — invisible to red-green-deficient viewers). Now: a fixed-order 8-slot categorical
|
|
191
|
+
palette validated against the actual dark surface (worst adjacent ΔE 8.4 protan / 19.3
|
|
192
|
+
normal, all ≥3:1; 9th+ areas fold to neutral), a single-hue slate→red lightness ramp for
|
|
193
|
+
duplication density (with an on-canvas legend), reserved status colors for finding
|
|
194
|
+
severity, and the brand lime demoted to what it should be: UI accent (selection, focus),
|
|
195
|
+
never a data series.
|
|
196
|
+
- **The graph is drawn like a product.** Focus + context replaces expand-everything: every
|
|
197
|
+
area starts as a bubble and clicking one expands ITS symbols in place — the all-at-once
|
|
198
|
+
hairball is impossible unless explicitly asked for. Curved weight-scaled edges; node fills
|
|
199
|
+
with darker same-hue rings; halo labels in the real UI font (the canvas font stack fell
|
|
200
|
+
back to a serif before); the tangle color only appears where it means something; search
|
|
201
|
+
reveals a hidden symbol's area instead of saying "no matches"; positions persist across
|
|
202
|
+
expansions; layout is seeded — the same repo always draws the same map.
|
|
203
|
+
- **Treemap/matrix polish**: cell gaps + rounded corners, styled area headers with color
|
|
204
|
+
chips, readable in-cell numbers (they were dark-on-dark), chip legends instead of prose.
|
|
205
|
+
- **First paint earns its pixels**: the inspector opens with the repo overview (largest
|
|
206
|
+
areas, findings counts, how-to-read) instead of "Pick an item"; engine jargon moved out
|
|
207
|
+
of the masthead into a tooltip; a logomark anchors the header.
|
|
208
|
+
- **Deterministic demo shots** (`scripts/screenshot.mjs`): staged states (top hotspot
|
|
209
|
+
selected, its area expanded, inspector populated) at 2× retina with fixed framing — every
|
|
210
|
+
committed screenshot (`assets/screens/`) regenerates from the real report in one command.
|
|
211
|
+
The live demo (`docs/demo/`) rebuilt on the new template.
|
|
212
|
+
|
|
213
|
+
## [0.6.0] - 2026-07-19
|
|
214
|
+
|
|
215
|
+
### Added
|
|
216
|
+
- **The local outcome ledger** (`scripts/stats.mjs`, `npm run stats`): codeweb now counts what
|
|
217
|
+
it actually does during real work — session briefs injected, pre-edit cards delivered,
|
|
218
|
+
post-edit checks run, regressions flagged before landing, queries served, auto-refreshes —
|
|
219
|
+
written by the hooks and the MCP server beside the graph (`stats.json`). Strictly local
|
|
220
|
+
(never transmitted; counter names + integers only; `CODEWEB_NO_STATS=1` disables), fail-open
|
|
221
|
+
by construction. The brief carries a one-line receipt ("codeweb this month: …") — the value
|
|
222
|
+
made visible where it accrued.
|
|
223
|
+
|
|
224
|
+
### Research
|
|
225
|
+
- **Evidence program moves into the product** (`paper/STATUS.md`): the manuscript is frozen as
|
|
226
|
+
a reproducible artifact; claims live in the site's evidence ledger + these Research notes.
|
|
227
|
+
- **Replay benchmark** (`paper/experiments/replay-mine.mjs` + `replay-ab.workflow.js`): mine
|
|
228
|
+
git history for commits that changed a depended-on signature and provably missed caller
|
|
229
|
+
files a later commit had to fix — each hit is a task with a built-in answer key (no invented
|
|
230
|
+
tasks, no floor effect). First verified mining run on axios (1,647 commits, funnel reported
|
|
231
|
+
at every stage): 2 ground-truth tasks, e.g. `forEach` — 9 caller files, 8 missed, fixed in a
|
|
232
|
+
follow-up. The replay workflow runs control vs ambient codeweb over the mined set, graded on
|
|
233
|
+
historical-miss coverage + the deterministic gate.
|
|
234
|
+
|
|
235
|
+
## [0.5.0] - 2026-07-19
|
|
236
|
+
|
|
237
|
+
### Added (fewer mistakes per token)
|
|
238
|
+
- **Day-one briefing** (`codeweb_brief`, 24th MCP tool + `scripts/brief.mjs` + a SessionStart
|
|
239
|
+
hook): one ~2KB page — areas with summaries, the most depended-on symbols, entry points
|
|
240
|
+
(heuristic), test layout, known issues — injected automatically when a session starts in a
|
|
241
|
+
mapped repo. Replaces the first 20-50k tokens of exploratory orientation with pre-computed
|
|
242
|
+
answers; served in-process from the cached graph.
|
|
243
|
+
- **Caller-reliance contracts** (`lib/reliance.mjs`): the explain card (and therefore the
|
|
244
|
+
pre-edit hook, which embeds its summary) now reads the actual call sites and says what
|
|
245
|
+
callers depend on — destructured/member-accessed result fields ("callers use {timeout,
|
|
246
|
+
retries} — keep those"), awaited fraction, and the argument-count range in use. Targets the
|
|
247
|
+
most common breaking edit: changing a return shape a caller still destructures.
|
|
248
|
+
Conservative: only call-site-line patterns count; no sites → no claim.
|
|
249
|
+
- **Confidence calibration** (extractor v10): symbols reachable from a package entrypoint
|
|
250
|
+
(package.json main/module/browser/bin/exports, followed through named + star re-export
|
|
251
|
+
chains) are stamped `pub` — "0 in-repo callers" on a public symbol now answers with
|
|
252
|
+
"⚠ public API — external callers likely; renames are breaking" instead of false confidence.
|
|
253
|
+
Files using dynamic dispatch (computed member calls, getattr, non-literal require, emitters)
|
|
254
|
+
are recorded in `meta.dynamic`, and empty callers/dependents answers cite them ("absence of
|
|
255
|
+
callers is weaker evidence"). Confident answers stay caveat-free — no noise.
|
|
256
|
+
|
|
257
|
+
### Research
|
|
258
|
+
- **H18-v2 prepped** (`paper/experiments/agent-ab2-ambient.workflow.js` + `agent-ab2.README.md`):
|
|
259
|
+
the agent A/B rerun as one funded command — v1's null was a floor effect (both arms ~0
|
|
260
|
+
regressions on easy tasks), so v2 pre-registers hard tasks (graph-verified fan-in ≥ 5 /
|
|
261
|
+
shape changes) and an AMBIENT treatment arm mirroring what the hooks now inject (brief +
|
|
262
|
+
explain cards with reliance/caveats — context delivered, not offered). The analyzer takes
|
|
263
|
+
raw/out paths so v1 results stay frozen.
|
|
264
|
+
|
|
265
|
+
## [0.4.0] - 2026-07-19
|
|
266
|
+
|
|
267
|
+
### Added
|
|
268
|
+
- **Java + C# on the deterministic fast path** (extractor v8): class/interface/enum/
|
|
269
|
+
record/struct discovery with visibility-as-export, owner-qualified method ids
|
|
270
|
+
(constructors included), Allman-brace + expression-bodied members (C#), `extends` /
|
|
271
|
+
base-list inheritance edges, control-flow phantom guards, Maven/Gradle test-layout
|
|
272
|
+
and `*Test.java` / `*Tests.cs` role detection, and pom.xml / build.gradle / .csproj
|
|
273
|
+
package boundaries. Verified on square/javapoet (497 symbols, 0 phantoms, 0.7s) and
|
|
274
|
+
restsharp/RestSharp (1,542 symbols, Allman style, 0.9s). Method-dispatch recall
|
|
275
|
+
(`obj.Method()`) stays precision-gated as in the JS regex tier — a tree-sitter tier
|
|
276
|
+
for Java/C# is the next increment.
|
|
277
|
+
|
|
278
|
+
### Added (recall ceiling + ambient loop)
|
|
279
|
+
- **Tree-sitter tier default-on** when web-tree-sitter is installed (`--engine regex`
|
|
280
|
+
opts out; absent dependency degrades to regex byte-identically). Class-field arrow
|
|
281
|
+
methods survive the AST handoff.
|
|
282
|
+
- **Barrels are dependents** (the measured recall gap): `export { X } from` edges the
|
|
283
|
+
barrel's `<module>` to the resolved symbol; `export * from` chains resolve
|
|
284
|
+
transitively AND edge the barrel to the target module. Oracle A/B moved from
|
|
285
|
+
recall 0.94 to **1.00** (precision 0.94 vs grep 0.87) on both the fixed and a
|
|
286
|
+
fresh-seeded 30-task sample.
|
|
287
|
+
- **Ambient loop**: the pre-edit hook now injects the ~1KB explain card (identity, top
|
|
288
|
+
callers, tests) instead of a pointer — blast radius arrives with zero agent
|
|
289
|
+
discipline; the MCP server **auto-refreshes a stale graph inline** (~1s incremental,
|
|
290
|
+
throttled, CODEWEB_NO_AUTOREFRESH=1 opts out) before structural queries, and
|
|
291
|
+
per-DIRECTORY mtime stamps make brand-new files trip the staleness check (per-file
|
|
292
|
+
stamps cannot see a file that didn't exist).
|
|
293
|
+
|
|
294
|
+
### Added (the proof, the surfaces, the last query family)
|
|
295
|
+
- **`codeweb bench`** (`scripts/bench.mjs`, `npm run bench`): the oracle A/B packaged as a
|
|
296
|
+
one-command benchmark on YOUR repo — context cost per dependents task + blast-radius cost
|
|
297
|
+
always; recall/precision graded by the TypeScript LanguageService when `typescript` is
|
|
298
|
+
resolvable; ripgrep optional. The engine moved verbatim into `scripts/lib/bench-core.mjs`
|
|
299
|
+
(the paper experiment is now a thin wrapper over it — reproduction against the committed
|
|
300
|
+
canonical run is byte-identical), so published numbers and user-generated numbers can
|
|
301
|
+
never measure different things.
|
|
302
|
+
- **The gate now posts its review**: `ci-gate --md` renders the structural delta (blocking
|
|
303
|
+
regressions, new cycles/duplications, symbols that lost all callers, renames-not-churn)
|
|
304
|
+
as a budgeted digest and the `codeweb gate` workflow posts/updates it as a sticky PR
|
|
305
|
+
comment on pass AND fail — visible where reviewers already look, verdict unchanged.
|
|
306
|
+
- **Editor CodeLens** (`editor/vscode-codeweb`): zero-dependency VS Code extension showing
|
|
307
|
+
`N callers · blast M` above every mapped symbol from the nearest `.codeweb/graph.json`
|
|
308
|
+
(identical semantics to `codeweb_callers`/`codeweb_impact`), click-through to
|
|
309
|
+
`report.html#s=<id>`.
|
|
310
|
+
- **`codeweb_find` — concept search** (23rd MCP tool + `scripts/find.mjs`): free text
|
|
311
|
+
("where is retry handled?") → ranked symbols, deterministically — camelCase/snake_case
|
|
312
|
+
token match with light stemming over identifiers/files/domains, weighted by exports,
|
|
313
|
+
role (tests only when asked for), and fan-in. Served in-process from the cached graph,
|
|
314
|
+
budgeted, staleness-annotated. Closes the last gap: every other query tool needs a name;
|
|
315
|
+
this one turns an idea into the right starting symbol.
|
|
316
|
+
|
|
317
|
+
### Research
|
|
318
|
+
- **Oracle A/B** (`paper/experiments/oracle-ab.mjs`, results in
|
|
319
|
+
`paper/results/oracle-ab.json`): dependents-discovery graded by the TypeScript
|
|
320
|
+
compiler's own reference finder over 30 seeded vite symbols — codeweb recall 0.94 /
|
|
321
|
+
precision 0.89 at **1/3 of an idealized grep's context cost** (0.8KB vs 2.5KB per
|
|
322
|
+
task); blast-radius ("what transitively breaks") in one ~1KB call vs a recursive
|
|
323
|
+
grep loop's ~130KB (**126× on the canonical run**, simulated generously for grep). Mechanical and
|
|
324
|
+
reproducible — complements (does not replace) the frozen frontier-agent pilot,
|
|
325
|
+
whose run stays the evidence for agent-loop behavior (+0.27 recall, ~44% fewer
|
|
326
|
+
tokens). The 6/30 under-recalled symbols are the known dispatch/re-export gap.
|
|
327
|
+
|
|
328
|
+
## [0.3.0] - 2026-07-18
|
|
329
|
+
|
|
330
|
+
The agent-efficiency release: outputs that can't corrupt, answers that fit a context
|
|
331
|
+
window, and a map that tells you when it's stale. Driven by the measured product review
|
|
332
|
+
(`PRODUCT-REVIEW.md`).
|
|
333
|
+
|
|
334
|
+
### Fixed
|
|
335
|
+
- **Flush-safe output everywhere**: `process.exit()` after a large stdout write silently
|
|
336
|
+
truncated anything past the 64KB pipe buffer (piped CLI JSON cut at exactly 65,536
|
|
337
|
+
bytes; MCP responses clipped mid-string). All CLIs now end naturally via
|
|
338
|
+
`lib/cli.mjs` emitters; `| head` (EPIPE) exits cleanly.
|
|
339
|
+
- `run.mjs` resolves a relative `<SRC>` against the caller's cwd (it resolved against the
|
|
340
|
+
plugin root while `--out-dir` used the cwd) and reports stage failures in one clean
|
|
341
|
+
line instead of a raw `execFileSync` stack. `--open` is parsed and forwarded (it was
|
|
342
|
+
documented but inert).
|
|
343
|
+
- Campaign delete steps ranked ROI 0: `deadcode` now emits `loc` per item and the
|
|
344
|
+
planner reads it (`locSaved` stays as a legacy alias).
|
|
345
|
+
- Same-file same-name methods collided into one node id: v6/v7 extraction emits
|
|
346
|
+
owner-qualified ids (`file:Type.method`) in every tier (Python classes, Rust impls,
|
|
347
|
+
Go receivers, JS/TS classes), with member-access resolution following.
|
|
348
|
+
- Body spans no longer desync on multi-line template literals / block comments (bodies
|
|
349
|
+
swallowed whole neighboring functions — a 5-line helper recorded as 550 loc on vite,
|
|
350
|
+
poisoning complexity, context-pack, and body-confirmation). Extents are measured on
|
|
351
|
+
masked lines.
|
|
352
|
+
- `mcp-server` advertised version 0.1.0 on a 0.2.0 product; `serverInfo.version` now
|
|
353
|
+
derives from package.json and `check-consistency` audits it.
|
|
354
|
+
- Signal-B twins de-duplicate by label pair (several `<module>` nodes produced N
|
|
355
|
+
byte-identical findings).
|
|
356
|
+
|
|
357
|
+
### Added
|
|
358
|
+
- **Budgeted MCP responses**: list-heavy tools default to a one-line `summary` + top-N
|
|
359
|
+
most-relevant items + TRUE totals + explicit `more.remaining`; `full: true` or
|
|
360
|
+
`limit`/`offset` override. `codeweb_context` returns call-site windows (±3 lines)
|
|
361
|
+
instead of whole caller bodies (~300KB → ~10KB on a busy vite symbol).
|
|
362
|
+
- **`codeweb_map`**: build/rebuild the graph over MCP; `graph` becomes
|
|
363
|
+
optional on every tool (nearest `.codeweb/graph.json` above cwd, or `CODEWEB_WS`),
|
|
364
|
+
and a missing graph returns an actionable error naming the fix.
|
|
365
|
+
- **`codeweb_explain`**: one ~1KB card (identity, contract, dependents, blast radius,
|
|
366
|
+
findings) answering "tell me about X" — previously 3-4 calls. 22 tools total.
|
|
367
|
+
- **Plugin auto-registration**: `.claude-plugin/plugin.json` now carries `mcpServers`,
|
|
368
|
+
so `/plugin install codeweb` delivers the tools without a manual `claude mcp add`.
|
|
369
|
+
- **Code roles**: every node carries `role` (product|test|fixture|example|bench|
|
|
370
|
+
generated). Overlap findings, deadcode tiers, and the report's default view scope to
|
|
371
|
+
product code (`CODEWEB_ALL_ROLES=1` / an in-report toggle widen it).
|
|
372
|
+
- **Interface-pattern detection**: ≥4 same-named implementations that nothing in-repo
|
|
373
|
+
calls demote from "merge these" to an informational `interface-pattern` finding
|
|
374
|
+
(framework hooks like a bundler plugin's `resolveId()`).
|
|
375
|
+
- **Workspace scoping**: bare-name call resolution never crosses a package (manifest)
|
|
376
|
+
boundary — cross-package name collisions no longer fabricate edges in monorepos.
|
|
377
|
+
- **Staleness awareness**: the extractor stamps per-file size+mtime into
|
|
378
|
+
`meta.sources`; query/context results annotate when the graph no longer matches disk
|
|
379
|
+
and point at `codeweb_refresh`.
|
|
380
|
+
- **Pre-edit hook**: one advisory line of blast radius before an edit lands in a mapped
|
|
381
|
+
target (PreToolUse; fail-open). The post-edit hook re-extracts incrementally
|
|
382
|
+
(`--cache`) instead of full-scanning per edit.
|
|
383
|
+
- Bare-identifier arguments become `ref` edges (a callback passed is a reference, not an
|
|
384
|
+
invocation); class-field arrow methods (`handleClick = () => {}`) are discovered and
|
|
385
|
+
owner-qualified.
|
|
386
|
+
- Report: product-only filter, interface-pattern section, search that navigates
|
|
387
|
+
(Enter cycles + selects matches), `#s=<id>` deep links, keyboard/ARIA support, and
|
|
388
|
+
`prefers-reduced-motion` (layout settles without animation).
|
|
389
|
+
- `lib/cli.mjs`: the shared CLI harness (die/emit/loadGraph/capList/staleness) —
|
|
390
|
+
deleting the die()×16 / graph-load×13 duplication codeweb's own overlap report flagged.
|
|
391
|
+
|
|
392
|
+
- **In-process query serving**: the MCP server answers structural queries from a
|
|
393
|
+
cached parsed graph (4–6ms vs 75–122ms spawn+parse), via the same
|
|
394
|
+
`lib/query-core.mjs` the CLI ships — one truth, two transports.
|
|
395
|
+
- **Rename-aware diff**: a removed+added pair with an identifier-normalized
|
|
396
|
+
(Type-2) body match ≥85% reports as `renamed[]` instead of delete+add churn.
|
|
397
|
+
- Domain summaries are genuinely descriptive: size, file count, exported-first
|
|
398
|
+
key symbols, and role composition ("mostly test code").
|
|
399
|
+
|
|
400
|
+
### Changed
|
|
401
|
+
- `campaign` batches its delete simulation (one clone instead of one per step):
|
|
402
|
+
8.9s → 1.25s on a 3k-symbol monorepo.
|
|
403
|
+
- MCP `initialize` returns workflow `instructions` and negotiates a SUPPORTED protocol
|
|
404
|
+
version instead of echoing arbitrary client strings; tool calls get a 120s timeout.
|
|
405
|
+
- `codeweb_find_similar` accepts `body` (stdin plumbing) + `structural` over MCP;
|
|
406
|
+
`codeweb_review` accepts `before` + `gate`; `codeweb_reading_order` accepts
|
|
407
|
+
scope/value/budget — previously CLI-only capability, now agent-reachable.
|
|
408
|
+
|
|
409
|
+
## [0.2.0] - 2026-06-23
|
|
410
|
+
|
|
411
|
+
The first managed release: codeweb gets a real public front and the machinery to keep
|
|
412
|
+
product, marketing, and research in lock-step.
|
|
413
|
+
|
|
414
|
+
### Added
|
|
415
|
+
|
|
416
|
+
- **Public website** built from a zero-dependency Node builder (`site/build.mjs`) into
|
|
417
|
+
`docs/` — Home, Product, Research, Get Started, and Changelog pages, all self-contained
|
|
418
|
+
with zero third-party requests, served by GitHub Pages.
|
|
419
|
+
- **Design system** (`site/tokens.css` + `site/styles.css`): the engine's palette codified
|
|
420
|
+
into reusable tokens and components, plus a polished animated hero.
|
|
421
|
+
- **Evidence ledger** on the Research page — every claim tagged `Validated`,
|
|
422
|
+
`Preliminary`, or `Null` with its exact number, sample size, and source file.
|
|
423
|
+
- **Single source of truth** (`site/data/product.json`) for the tagline, the 20 MCP tools,
|
|
424
|
+
the Tier 0–3 map, supported languages, and the claim ledger.
|
|
425
|
+
- **Release ecosystem**: this `CHANGELOG.md`, plus `scripts/version-sync.mjs`,
|
|
426
|
+
`scripts/check-consistency.mjs`, and `scripts/release.mjs`.
|
|
427
|
+
- Shared navigation injected into the existing interactive demo and research paper, so
|
|
428
|
+
they are no longer orphaned pages.
|
|
429
|
+
|
|
430
|
+
### Changed
|
|
431
|
+
|
|
432
|
+
- Corrected the Claude Code plugin manifest, which advertised **15** query tools; the real
|
|
433
|
+
surface is **20**. The tool count is now derived from the MCP server and verified in CI.
|
|
434
|
+
- README updated for the new site, version, and a `Versioning & Releases` section.
|
|
435
|
+
|
|
436
|
+
### Fixed
|
|
437
|
+
|
|
438
|
+
- Per-page Open Graph metadata and favicon (the Pages root previously 404'd — there was no
|
|
439
|
+
landing page at all).
|
|
440
|
+
|
|
441
|
+
### Research
|
|
442
|
+
|
|
443
|
+
- Surfaced the **efficiency pilot**: frontier-agent caller discovery improves by
|
|
444
|
+
**+0.265 ± 0.045** recall and **~34% fewer steps** vs grep over 8 engine-frozen reps
|
|
445
|
+
(`paper/experiments/efficiency-pilot.reps8.json`). Labelled preliminary.
|
|
446
|
+
|
|
447
|
+
## [0.1.0] - 2026-06-22
|
|
448
|
+
|
|
449
|
+
The deterministic engine and its evidence base.
|
|
450
|
+
|
|
451
|
+
### Added
|
|
452
|
+
|
|
453
|
+
- **Core pipeline** — extract → cluster → overlap → render: a parse-free, zero-dependency
|
|
454
|
+
code-structure graph with a self-contained interactive `report.html`.
|
|
455
|
+
- **Ten features across four tiers** (F1–F10): scoped context, live refresh, the
|
|
456
|
+
duplication-delta gate, hotspots, campaign planning, structural clone detection,
|
|
457
|
+
suppression memory, reading order, incremental edge derivation, and sharded subgraphs.
|
|
458
|
+
- **20 deterministic MCP tools** spanning structural queries, write-time, review-time,
|
|
459
|
+
optimize-time, freshness, and comparison.
|
|
460
|
+
- **Five-language fast path**: JavaScript, TypeScript, Python, Rust, and Go.
|
|
461
|
+
- **CI gate** — a GitHub Action that fails a PR on a new cycle, a new duplication, or a
|
|
462
|
+
symbol that loses all callers.
|
|
463
|
+
|
|
464
|
+
### Research
|
|
465
|
+
|
|
466
|
+
- **Pre-registered effectiveness study** — 32 of 33 checks pass; 0 disagreements across
|
|
467
|
+
~490k oracle comparisons; the study found and fixed two real engine bugs the 286-test
|
|
468
|
+
suite had missed (`paper/`).
|
|
469
|
+
|
|
470
|
+
[Unreleased]: https://github.com/GhostlyGawd/codeweb/compare/v0.9.0...HEAD
|
|
471
|
+
[0.9.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.8.0...v0.9.0
|
|
472
|
+
[0.8.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.7.1...v0.8.0
|
|
473
|
+
[0.7.1]: https://github.com/GhostlyGawd/codeweb/compare/v0.7.0...v0.7.1
|
|
474
|
+
[0.7.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.6.0...v0.7.0
|
|
475
|
+
[0.6.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.5.0...v0.6.0
|
|
476
|
+
[0.5.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.4.0...v0.5.0
|
|
477
|
+
[0.4.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.3.0...v0.4.0
|
|
478
|
+
[0.3.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.2.0...v0.3.0
|
|
479
|
+
[0.2.0]: https://github.com/GhostlyGawd/codeweb/compare/v0.1.0...v0.2.0
|
|
480
|
+
[0.1.0]: https://github.com/GhostlyGawd/codeweb/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GhostlyGawd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|