@jphutchins/code-review 0.1.0-alpha.47 → 0.1.0-alpha.49
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/index.js +212 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schema/VERSIONING.md +2 -1
- package/schema/findings.schema.json +34 -0
- package/schema/prices.example.json +8 -2
- package/schema/prices.schema.json +77 -24
- package/templates/comment.eta +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jphutchins/code-review",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.49",
|
|
4
4
|
"description": "Deterministic commenter for agentic PR review — gather, render, inline, post, adapt, extract, cost, validate, print-schema",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/schema/VERSIONING.md
CHANGED
|
@@ -106,7 +106,8 @@ policy; the `main` `$id` tracks latest, tagged releases pin to the version. Its
|
|
|
106
106
|
|
|
107
107
|
| Version | Status | Notes |
|
|
108
108
|
|---|---|---|
|
|
109
|
-
| `v0.1.0` |
|
|
109
|
+
| `v0.1.0` | superseded | Initial price-map schema. Per-model `in`/`out`/`cache_read`/`cache_write` (USD per 1M tokens); `_updated` date; `_unit`. |
|
|
110
|
+
| `v0.2.0` | **current** | A model's value is now a `oneOf` (issue #170): the flat shape above, OR `{ "slots": [ { "utc_from", "utc_to", "in", "out", "cache_read", "cache_write" } ] }` — UTC time-of-day pricing (half-open `[utc_from, utc_to)` windows; `utc_to <= utc_from` wraps past midnight; slots must partition the 24h day). Additive/backward-compatible: every flat map keeps validating. |
|
|
110
111
|
|
|
111
112
|
The `_updated` field inside a price-map instance tracks **price drift** (a data concern) and is
|
|
112
113
|
distinct from the schema's semver version (a **contract** concern). Adding a new price field (e.g. a
|
|
@@ -172,6 +172,40 @@
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
},
|
|
175
|
+
"change_size": {
|
|
176
|
+
"type": "object",
|
|
177
|
+
"additionalProperties": false,
|
|
178
|
+
"description": "Best-effort (issue #182): the change's added/removed line counts bucketed by ROLE. Fill this with a LOW-effort path heuristic, no file introspection: a file under a tests directory or matching *.test.* / *_test.* is `tests`; a *.md file, anything under docs/, or a license/config doc is `docs`; everything else is `code`. Sum the diff's added and removed lines per bucket. Omit a role that did not change, or omit the whole field if you cannot estimate it. Chrome only — never affects the verdict or the convergence score. (The per-language cloc table shown beside it is supplied deterministically by the pipeline, not by you.)",
|
|
179
|
+
"properties": {
|
|
180
|
+
"code": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"additionalProperties": false,
|
|
183
|
+
"required": ["added", "removed"],
|
|
184
|
+
"properties": {
|
|
185
|
+
"added": { "type": "integer", "minimum": 0 },
|
|
186
|
+
"removed": { "type": "integer", "minimum": 0 }
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"tests": {
|
|
190
|
+
"type": "object",
|
|
191
|
+
"additionalProperties": false,
|
|
192
|
+
"required": ["added", "removed"],
|
|
193
|
+
"properties": {
|
|
194
|
+
"added": { "type": "integer", "minimum": 0 },
|
|
195
|
+
"removed": { "type": "integer", "minimum": 0 }
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"docs": {
|
|
199
|
+
"type": "object",
|
|
200
|
+
"additionalProperties": false,
|
|
201
|
+
"required": ["added", "removed"],
|
|
202
|
+
"properties": {
|
|
203
|
+
"added": { "type": "integer", "minimum": 0 },
|
|
204
|
+
"removed": { "type": "integer", "minimum": 0 }
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
},
|
|
175
209
|
"findings": {
|
|
176
210
|
"type": "array",
|
|
177
211
|
"description": "Zero or more specific findings.",
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "USD per 1,000,000 tokens. PRICES DRIFT — keep _updated current. cost = sum over models of (input*in + output*out + cache_read*cache_read + cache_write*cache_write) / 1e6. The CLI's vendor_cost_usd is vendor-priced and will be wrong for non-Anthropic backends; recompute from this map using the `models` array in the abstract result envelope (SPEC §6.1). Fill the zeros from your provider's pricing page.",
|
|
2
|
+
"_comment": "USD per 1,000,000 tokens. PRICES DRIFT — keep _updated current. cost = sum over models of (input*in + output*out + cache_read*cache_read + cache_write*cache_write) / 1e6. A model's value is EITHER a flat all-day price OR a { \"slots\": [...] } set of UTC time-of-day slots for peak/off-peak pricing (issue #170) — see schema/prices.schema.json for the rules: each slot is a half-open [utc_from, utc_to) UTC window, a slot whose utc_to <= utc_from wraps past midnight, and a model's slots must partition the 24h day with no gap or overlap. The CLI's vendor_cost_usd is vendor-priced and will be wrong for non-Anthropic backends; recompute from this map using the `models` array in the abstract result envelope (SPEC §6.1). Fill the zeros from your provider's pricing page.",
|
|
3
3
|
"_updated": "2026-07-03",
|
|
4
4
|
"_unit": "USD per 1M tokens",
|
|
5
5
|
"models": {
|
|
6
6
|
"deepseek-v4-pro": { "in": 0.0, "out": 0.0, "cache_read": 0.0, "cache_write": 0.0 },
|
|
7
|
-
"deepseek-v4-flash": { "in": 0.0, "out": 0.0, "cache_read": 0.0, "cache_write": 0.0 }
|
|
7
|
+
"deepseek-v4-flash": { "in": 0.0, "out": 0.0, "cache_read": 0.0, "cache_write": 0.0 },
|
|
8
|
+
"example-time-slotted-model": {
|
|
9
|
+
"slots": [
|
|
10
|
+
{ "utc_from": "10:00", "utc_to": "01:00", "in": 0.0, "out": 0.0, "cache_read": 0.0, "cache_write": 0.0 },
|
|
11
|
+
{ "utc_from": "01:00", "utc_to": "10:00", "in": 0.0, "out": 0.0, "cache_read": 0.0, "cache_write": 0.0 }
|
|
12
|
+
]
|
|
13
|
+
}
|
|
8
14
|
}
|
|
9
15
|
}
|
|
@@ -21,33 +21,86 @@
|
|
|
21
21
|
},
|
|
22
22
|
"models": {
|
|
23
23
|
"type": "object",
|
|
24
|
-
"description": "Map of model identifier → per-token prices. Keys are the model identifiers as they appear in the result envelope's `models[].model`.",
|
|
24
|
+
"description": "Map of model identifier → per-token prices. Keys are the model identifiers as they appear in the result envelope's `models[].model`. A model's value is EITHER a flat all-day price (unchanged) OR a set of UTC time-of-day slots (issue #170), for a provider with peak/off-peak rates.",
|
|
25
25
|
"additionalProperties": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
"oneOf": [
|
|
27
|
+
{
|
|
28
|
+
"type": "object",
|
|
29
|
+
"additionalProperties": false,
|
|
30
|
+
"required": ["in", "out", "cache_read", "cache_write"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"in": {
|
|
33
|
+
"type": "number",
|
|
34
|
+
"minimum": 0,
|
|
35
|
+
"description": "Price per 1M input tokens (cache-miss)."
|
|
36
|
+
},
|
|
37
|
+
"out": {
|
|
38
|
+
"type": "number",
|
|
39
|
+
"minimum": 0,
|
|
40
|
+
"description": "Price per 1M output tokens."
|
|
41
|
+
},
|
|
42
|
+
"cache_read": {
|
|
43
|
+
"type": "number",
|
|
44
|
+
"minimum": 0,
|
|
45
|
+
"description": "Price per 1M cache-read tokens (prompt-cache hits)."
|
|
46
|
+
},
|
|
47
|
+
"cache_write": {
|
|
48
|
+
"type": "number",
|
|
49
|
+
"minimum": 0,
|
|
50
|
+
"description": "Price per 1M cache-write tokens (prompt-cache population)."
|
|
51
|
+
}
|
|
52
|
+
}
|
|
34
53
|
},
|
|
35
|
-
|
|
36
|
-
"type": "
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
{
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": false,
|
|
57
|
+
"required": ["slots"],
|
|
58
|
+
"description": "UTC time-of-day pricing (issue #170). `slots` MUST partition the full 24h UTC day with no gap and no overlap: each is a half-open [utc_from, utc_to) window, and a slot whose utc_to <= utc_from wraps past midnight. Everything is UTC — there is no timezone or DST field. Cost recomputation selects the one slot covering the run's UTC instant; a run's time-of-day matching zero or more than one slot is a misconfiguration that warns loudly and prices that model at $0 (never silently wrong).",
|
|
59
|
+
"properties": {
|
|
60
|
+
"slots": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"minItems": 1,
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["utc_from", "utc_to", "in", "out", "cache_read", "cache_write"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"utc_from": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
|
|
71
|
+
"description": "Slot start, HH:MM in UTC (inclusive)."
|
|
72
|
+
},
|
|
73
|
+
"utc_to": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
|
|
76
|
+
"description": "Slot end, HH:MM in UTC (exclusive); a value <= utc_from wraps past midnight."
|
|
77
|
+
},
|
|
78
|
+
"in": {
|
|
79
|
+
"type": "number",
|
|
80
|
+
"minimum": 0,
|
|
81
|
+
"description": "Price per 1M input tokens (cache-miss) in this slot."
|
|
82
|
+
},
|
|
83
|
+
"out": {
|
|
84
|
+
"type": "number",
|
|
85
|
+
"minimum": 0,
|
|
86
|
+
"description": "Price per 1M output tokens in this slot."
|
|
87
|
+
},
|
|
88
|
+
"cache_read": {
|
|
89
|
+
"type": "number",
|
|
90
|
+
"minimum": 0,
|
|
91
|
+
"description": "Price per 1M cache-read tokens (prompt-cache hits) in this slot."
|
|
92
|
+
},
|
|
93
|
+
"cache_write": {
|
|
94
|
+
"type": "number",
|
|
95
|
+
"minimum": 0,
|
|
96
|
+
"description": "Price per 1M cache-write tokens in this slot."
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
49
102
|
}
|
|
50
|
-
|
|
103
|
+
]
|
|
51
104
|
}
|
|
52
105
|
}
|
|
53
106
|
}
|
package/templates/comment.eta
CHANGED
|
@@ -20,6 +20,18 @@
|
|
|
20
20
|
<% if (it.convergenceSummary) { -%>
|
|
21
21
|
<sub><%~ it.convergenceSummary %></sub>
|
|
22
22
|
<% } -%>
|
|
23
|
+
<% if (it.changeSummary) { -%>
|
|
24
|
+
<sub>**Changes:** <%~ it.changeSummary %></sub>
|
|
25
|
+
<% } -%>
|
|
26
|
+
<% if (it.clocDiff) { -%>
|
|
27
|
+
<details><summary>📏 cloc</summary>
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
<%~ it.clocDiff %>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
</details>
|
|
34
|
+
<% } -%>
|
|
23
35
|
<% if (it.metastasisNote) { -%>
|
|
24
36
|
<%~ it.metastasisNote %>
|
|
25
37
|
<% } -%>
|