JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 1773,
"has_wiki": true,
"homepage": "https://axonwatch.github.io/axon-charts/",
"languages": {
"HTML": 216840,
"JavaScript": 1332,
"TypeScript": 477182
},
"pushed_at": "2026-07-26T01:07:55Z",
"created_at": "2026-05-22T14:37:00Z",
"owner_type": "Organization",
"updated_at": "2026-07-26T01:07:59Z",
"description": "A fast, lightweight candlestick chart library optimized for AI-driven applications and LLM integration",
"is_archived": false,
"is_disabled": false,
"license_spdx": "Apache-2.0",
"default_branch": "main",
"license_spdx_raw": "Apache-2.0",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript",
"HTML"
]
},
"owner": {
"blog": null,
"name": null,
"type": "Organization",
"login": "AxonWatch",
"company": null,
"location": null,
"followers": 0,
"avatar_url": "https://avatars.githubusercontent.com/u/281991794?v=4",
"created_at": "2026-05-05T15:52:58Z",
"is_verified": null,
"public_repos": 1,
"account_age_days": 83
},
"license": {
"state": "standard",
"spdx_id": "Apache-2.0",
"raw_spdx": "Apache-2.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.5.8",
"kind": "patch",
"published_at": "2026-07-21T17:40:09Z"
},
{
"tag": "v1.5.7",
"kind": "patch",
"published_at": "2026-07-21T14:15:47Z"
},
{
"tag": "v1.5.6",
"kind": "patch",
"published_at": "2026-07-21T12:33:51Z"
},
{
"tag": "v1.5.5",
"kind": "patch",
"published_at": "2026-07-21T06:51:12Z"
},
{
"tag": "v1.5.4",
"kind": "patch",
"published_at": "2026-07-20T19:49:20Z"
},
{
"tag": "v1.5.3",
"kind": "patch",
"published_at": "2026-07-20T17:11:53Z"
},
{
"tag": "v1.5.2",
"kind": "patch",
"published_at": "2026-07-20T16:31:06Z"
},
{
"tag": "v1.5.1",
"kind": "patch",
"published_at": "2026-07-20T15:53:41Z"
},
{
"tag": "v1.5.0",
"kind": "minor",
"published_at": "2026-07-20T11:08:32Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2026-07-20T00:12:06Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2026-07-19T23:27:22Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-07-19T18:34:19Z"
},
{
"tag": "v1.2.8",
"kind": "patch",
"published_at": "2026-06-24T17:32:10Z"
},
{
"tag": "v1.2.7",
"kind": "patch",
"published_at": "2026-06-24T17:15:16Z"
},
{
"tag": "v1.2.6",
"kind": "patch",
"published_at": "2026-06-24T14:36:41Z"
},
{
"tag": "v1.2.5",
"kind": "patch",
"published_at": "2026-06-24T00:03:36Z"
},
{
"tag": "v1.2.4",
"kind": "patch",
"published_at": "2026-06-23T11:15:52Z"
},
{
"tag": "v1.2.3",
"kind": "patch",
"published_at": "2026-06-23T10:18:42Z"
},
{
"tag": "v1.2.2",
"kind": "patch",
"published_at": "2026-05-25T18:46:28Z"
},
{
"tag": "v1.2.1",
"kind": "patch",
"published_at": "2026-05-23T21:50:20Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2026-05-19T23:51:49Z"
},
{
"tag": "v1.1.1",
"kind": "patch",
"published_at": "2026-05-16T04:56:26Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2026-05-14T21:49:22Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2026-05-05T05:54:47Z"
}
],
"recent_commits": [
{
"oid": "69c285e3e4b08922717d5c0c97c29ac4e69a407f",
"body": "- Version 1.5.8 → 1.5.9 in all md/html files\n- Banner reads 'Axon Charts v1.5.9'\n\nVerification:\n - npm run build: clean (banner reads 'Axon Charts v1.5.9')\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "release: v1.5.9 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T01:00:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ec6a1885608fd0e1e8642c22883ee9e679a0b8ed",
"body": "…warmup, tooltip perf, Ichimoku projection\n\nPatch release with 5 indicator fixes:\n\n fix(indicators): Ichimoku cloud color respects A/B crossovers (Kumo twist)\n fix(indicators): VWAP daily reset respects configured timezone\n fix(indicators): Stochastic slow-%K no longer contaminated by NaN warmup\n\n[…]\ntip lookups\n fix(indicators): Ichimoku leading cloud projects into right gap\n\nBundle: 41566 -> 41712 bytes gzipped (+146 bytes).\n\nVerification:\n - npm run build: clean\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "release: v1.5.9 — Ichimoku cloud coloring, VWAP timezone, Stochastic …",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:59:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "51a31ac0f3789f68b6f426890b358cd0e463b304",
"body": "Senkou Span A and B are shifted forward by the displacement (default\n26 bars) — this is the defining feature of Ichimoku: the cloud (Kumo)\nextends into the future to show projected support/resistance. But the\nforward-shifted values were dropped when shiftedIdx >= data.length:\n\n const shiftedIdx = i\n[…]\nno shiftedIdx < len check)\n - render(): add cloudEndIdx from senkouA.length; use it for the cloud\n segmentation loop and the Span A/B line drawing\n\nVerification:\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "fix(indicators): Ichimoku leading cloud projects into right gap",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:58:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "490d1536a4fa83e745ae8686c105d943e869da47",
"body": "All 8 indicator sub-panes (RSI, MACD, Stochastic, Williams %R, CCI,\nMFI, ATR, ADX) used Array.indexOf(bar) inside getTooltipValue() to\nfind the bar's index into the computed-values array. This method is\ncalled on every render via getHoveredValue() (which updates the\nsub-pane's current-value label) a\n[…]\nndex ?? indexOf(bar)\n src/subpanes/ADXSubPane.ts: barIndex ?? indexOf(bar)\n src/subpanes/VolumeSubPane.ts: signature conformance (_barIndex unused)\n\nVerification:\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "fix(subpanes): eliminate O(n) indexOf in crosshair tooltip lookups",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:56:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ba43ad6701eec868f72030f1bbd8790adf3d7cef",
"body": "The slow stochastic smoothing (smoothK > 1) replaced NaN raw-%K values\nwith 0 before passing them to sma():\n\n const k = smoothK > 1\n ? sma(rawK.map(v => isNaN(v) ? 0 : v), smoothK)\n .map((v, i) => isNaN(rawK[i]) ? NaN : v)\n : rawK;\n\nThe re-mask only hid the output at index i where rawK\n[…]\ny sum when all smoothK values are\nnon-NaN.\n\nFiles:\n src/utils/indicators.ts:\n - stochastic(): replace sma(zero-padded) with explicit valid-window loop\n\nVerification:\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "fix(indicators): Stochastic slow-%K no longer contaminated by NaN warmup",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:53:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "71d592bae1bb66e0f4bdda02632a3894068cd34b",
"body": "VWAP's daily reset was hardcoded to UTC midnight:\n\n const day = Math.floor(bar.time / 86400000);\n\nThis split non-UTC trading sessions mid-session. A US equities trader\n(charting in EST/EDT) would see the VWAP line reset at 7-8 PM EST\ninstead of at the session boundary, invalidating all volume-weigh\n[…]\n/overlays/VWAPOverlay.ts:\n - import PriceFormatter\n - replace lastDay/UTC-floor with lastBarTime + isDifferentDay\n - read tz once before the loop\n\nVerification:\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "fix(indicators): VWAP daily reset respects configured timezone",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:53:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c0060b5a509a66acc95b370e79835f3dfa9b5144",
"body": "…wist)\n\nThe entire visible cloud was tinted green or red based on a single\nmidpoint sample of Senkou Span A vs. Span B. When the two spans crossed\nwithin the visible range (a \"Kumo twist\"), the whole cloud flipped\ncolor abruptly instead of showing the transition.\n\nRoot cause: render() built one canv\n[…]\ns:\n src/overlays/IchimokuCloudOverlay.ts:\n - render(): replace single-path/single-color cloud with segmented fills\n - add fillCloudSegment() helper\n\nVerification:\n - npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "fix(indicators): Ichimoku cloud color respects A/B crossovers (Kumo t…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-26T00:52:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a5f248a7ad42e96bb32a730ac68eb61cf6f8ea9c",
"body": "- Version 1.5.7 → 1.5.8 in all md/html files\n- v1.5.8 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.8')\n- npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "release: v1.5.8 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T17:40:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fe402b859007c05ffde57049cc4d4c1c4902cd5d",
"body": "…l gap",
"is_bot": false,
"headline": "release: v1.5.8 — separator drag fix, distinct indicator colors, labe…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T17:40:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5c16e43edcc37216e3a9beba20bd2561345749b4",
"body": "…label gap\n\nFix three issues with sub-pane indicators:\n\n## 1. Separator drag resized the wrong pane (critical)\n\nWhen multiple sub-panes were stacked (e.g. RSI + Stochastic + Volume),\ndragging any separator always resized the FIRST sub-pane, not the one\nwhose separator was grabbed. Trying to resize t\n[…]\n fallback color #f97316\nsrc/subpanes/ATRSubPane.ts: fallback color #14b8a6\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 41515 -> 41566 bytes (+51 bytes)",
"is_bot": false,
"headline": "fix(subpanes): separator drag resizes correct pane, distinct colors, …",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T17:40:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ded457652a6d1992ce8a8331d744d5e2c219991e",
"body": "- Version 1.5.6 → 1.5.7 in all md/html files\n- Bundle size unchanged at 40.5KB (41515 bytes gzipped)\n- v1.5.7 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.7')\n- npx tsc --noEmit: 0 errors",
"is_bot": false,
"headline": "release: v1.5.7 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T14:16:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8c0f1032a232a395747496cfe36f83123b7e346b",
"body": "…t-side tooltip",
"is_bot": false,
"headline": "release: v1.5.7 — fix sub-pane labels, overlay alignment, remove righ…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T14:15:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dbd8694432c038bbd72cf024124f4cfc45f0df47",
"body": "… + overlay alignment\n\nFix four issues with the indicator labels and tooltips:\n\n## 1. Sub-pane: remove unrequested right-side tooltip\nv1.5.6 accidentally added a right-aligned tooltip on each sub-pane.\nRemoved entirely — each sub-pane now shows only the top-left label.\n\n## 2. Sub-pane label: proper \n[…]\nwith colored value\n - getOverlayLabel: returns structured object instead of string\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 41313 -> 41515 bytes (+202 bytes)",
"is_bot": false,
"headline": "fix(indicators): remove right-side sub-pane tooltip, fix label format…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T14:15:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cad8b710b690c6d855530cff89eb65e494d07552",
"body": "- Version 1.5.5 → 1.5.6 in all md/html files\n- Bundle size unchanged at 40.3KB (41313 bytes gzipped)\n- v1.5.6 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.6')\n- npx tsc --noEmit: 0 errors\n- Bundle: 41313 bytes gzipped (40.3KB)",
"is_bot": false,
"headline": "release: v1.5.6 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T12:34:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7bde755110a04b8a989d1b946cf0b67713665777",
"body": "…sub-pane tooltips",
"is_bot": false,
"headline": "release: v1.5.6 — fix overlay label names, current values in labels, …",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T12:33:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "22c5d69009bbcb66d9cc793d6b4668d0f1c69d28",
"body": "…tips in own sub-pane\n\nFix three issues with indicator labels and tooltips:\n\n## 1. Overlay labels showed minified class names (V4, U4)\n\noverlay.constructor.name gets renamed by esbuild's minifier in\nproduction builds — 'SMAOverlay' becomes 'V4', 'EMAOverlay' becomes\n'U4', etc. The labels showed 'V4(\n[…]\nside its own pane (currentTop + 2)\n instead of stacking all at the first sub-pane\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 41226 -> 41313 bytes (+87 bytes)",
"is_bot": false,
"headline": "fix(indicators): proper overlay names, current values in labels, tool…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T12:33:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "471f25165e3ab124dbbc6976fc8cdb22b9d0f867",
"body": "- Version 1.5.4 → 1.5.5 in all md/html files\n- Bundle size 39.9KB → 40.3KB in README.md + html/index.html\n (actual: 41226 bytes gzipped)\n- v1.5.5 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.5')\n- npx tsc --noEmit: 0 errors\n- Bundle: 41226 bytes gzipped (40.3KB)",
"is_bot": false,
"headline": "release: v1.5.5 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T06:51:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b63f8bf1daf12075d29f3bd9aae3a5a551feb837",
"body": "… clipping fix",
"is_bot": false,
"headline": "release: v1.5.5 — text wrapping/styling, label price display, drawing…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T06:51:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f5fa8628986d2c1f411ffa53877f9e3a2c6bfe51",
"body": "…drawing clipping to chart area\n\nFix two bugs and add text/label styling options:\n\n## Bug 1: Drawings visible in sub-pane area\nrenderDrawings() was not clipping to the main chart area, so\ndrawings (trendlines, boxes, text, etc.) rendered across sub-panes\n(RSI, MACD, Volume). Now clips to chartBottom\n[…]\nh the new fields\n\nCHANGELOG.md:\n - [1.5.5] entry with Fixed/Added/Changed sections\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 40885 -> 41226 bytes (+341 bytes)",
"is_bot": false,
"headline": "fix(drawings): text wrapping + styling options, label price display, …",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-21T06:51:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f2f6350e0a176c780958b4ea3f9a9747a1593b0f",
"body": "Update all version references for the v1.5.4 release.\n\n- Version 1.5.3 → 1.5.4 in all md/html files\n- Bundle size 39.6KB → 39.9KB in README.md + html/index.html\n (actual: 40885 bytes gzipped)\n- v1.5.4 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.4')\n- npx tsc --noEmit: 0 errors\n- Bundle: 40885 bytes gzipped (39.9KB)",
"is_bot": false,
"headline": "release: v1.5.4 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T19:49:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "acadd62f115e3a7383554eec2202ef90c1f2eff1",
"body": "… registry, resetState, migrateSnapshot",
"is_bot": false,
"headline": "release: v1.5.4 — drawings + overlays in saveState/loadState, overlay…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T19:49:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f607c1c1d7fafaaa2b5adcddb5dd9523f1030709",
"body": "… registry, resetState, migrateSnapshot\n\nClose four persistence gaps in the state serialization system.\nAll changes are additive — old 1.0.0 snapshots still load fine.\n\n## Request 1: Drawings in saveState/loadState\n\nsaveState() now captures this._drawings (already plain JSON objects).\nloadState() re\n[…]\n0 errors\n- npm run build: clean\n- Bundle gzipped: 40576 -> 40885 bytes (+309 bytes for the overlay\n registry, migrateSnapshot, resetState, registerOverlayType, and\n the extended saveState/loadState)",
"is_bot": false,
"headline": "fix(persistence): drawings + overlays in saveState/loadState, overlay…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T19:49:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0d688c7f7ea1e634a8332a60de152da8aa061a99",
"body": "Update all version references and CHANGELOG for the v1.5.3 release\n(indicator labels, context menu toggles, setIndicatorOptions API).\n\n- Version 1.5.2 → 1.5.3 in all md/html files\n- Bundle size 39.1KB → 39.6KB in README.md + html/index.html\n (actual: 40576 bytes gzipped = 39.6KB)\n- CHANGELOG: new [\n[…]\nentry with Added/Changed sections\n- v1.5.3 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.3')\n- npx tsc --noEmit: 0 errors\n- Bundle: 40576 bytes gzipped (39.6KB)",
"is_bot": false,
"headline": "release: v1.5.3 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T17:12:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d5c7f057b287f0de1d364070034e01e1d80befbd",
"body": "…rOptions API",
"is_bot": false,
"headline": "release: v1.5.3 — indicator labels, context menu toggles, setIndicato…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T17:11:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8346b87079dbaa30b5c56349b92eca73610225f9",
"body": "…ptions API\n\nAdd three features that make indicators editable by the user and\nby the integrating app, without building a heavy settings UI that\nwould violate the library's minimal philosophy.\n\n## 1. On-chart indicator labels (canvas-rendered)\n\nEach active sub-pane now shows its name + key params in \n[…]\nys)\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 39989 -> 40576 bytes (+587 bytes for the labels,\n 8 context menu entries, setIndicatorOptions, onIndicatorClick)",
"is_bot": false,
"headline": "fix(indicators): on-chart labels, context menu toggles, setIndicatorO…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T17:11:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9166ce7167757df6fd0d0302cae83831ea71acef",
"body": "Update all version references and CHANGELOG for the v1.5.2 release\n(negative-value sub-pane rendering fix for MACD, CCI, Williams %R).\n\n- Version 1.5.1 → 1.5.2 in all md/html files\n- Bundle size unchanged at 39.1KB (the fix was 6 bytes)\n- CHANGELOG: new [1.5.2] entry with the two bug descriptions\n- v1.5.2 git tag created\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.2')\n- npx tsc --noEmit: 0 errors\n- Bundle: 39989 bytes gzipped (39.1KB)",
"is_bot": false,
"headline": "release: v1.5.2 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T16:31:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8e7e0fd89d2f838cce62311cd82bccf097053d55",
"body": "…illiams %R)",
"is_bot": false,
"headline": "release: v1.5.2 — fix negative-value sub-pane rendering (MACD, CCI, W…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T16:31:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "286675e91d8c853768695bf5a792552f930bcdf7",
"body": "…set)\n\nFix two bugs in the ScalePane base class that broke negative-value\nindicators (MACD, CCI, Williams %R). These were latent bugs in the\noriginal code (VolumeSubPane never triggered them because volume is\nalways positive), now exposed by the new negative-range indicators.\n\n## Bug 1 (critical): v\n[…]\nthreshold check\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 39983 -> 39989 bytes (+6 bytes — the fix is a\n one-character change in two places + a Math.abs call)",
"is_bot": false,
"headline": "fix(subpanes): negative values clipped by Math.max(getMinVisible, off…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T16:30:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "36445bf993edbd150d84c4577a6b0afb85e72b21",
"body": "Update all version references and CHANGELOG for the v1.5.1 release\n(getContext() fix exposing drawings, overlays, and sub-pane values).\n\n- Version 1.5.0 → 1.5.1 in README.md, docs/API.md, docs/SETTINGS.md,\n docs/LLM.md, html/index.html, html/demo.html, html/docs.html\n- Bundle size 38.8KB → 39.1KB i\n[…]\nes gzipped)\n- CHANGELOG: Unreleased → [1.5.1] - 2026-07-20\n\nVerification:\n- npm run build: clean (banner reads 'Axon Charts v1.5.1')\n- npx tsc --noEmit: 0 errors\n- Bundle: 39983 bytes gzipped (39.1KB)",
"is_bot": false,
"headline": "release: v1.5.1 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T15:54:19Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2013e6b6b986144d791542e0b0b04fc04c59d9c7",
"body": "…etContext()",
"is_bot": false,
"headline": "release: v1.5.1 — expose drawings, overlays, and sub-pane values in g…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T15:53:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c6cb47747e97bf14b0247674ab2833f3503d64fe",
"body": "Update the documentation to reflect the three new data blocks\nexposed by getContext(): sub-pane indicator values, drawings, and\noverlays.\n\n## Changes\n\ndocs/LLM.md:\n - Expanded the getContext() JSON example to include:\n * subPanes with values + latestValue (RSI, MACD examples)\n * drawings arra\n[…]\npanded the getContext() return shape to show the new fields:\n subPanes with values/latestValue, drawings array, overlays object\n\nCHANGELOG.md:\n - Unreleased section with the getContext() fix entry",
"is_bot": false,
"headline": "docs: update LLM.md + API.md for new getContext() structure",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T15:53:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0f30ee86d75a1196078ca890aa719e186d899ee9",
"body": "…xt()\n\nFix three gaps in the LLM context (chart.getContext()) that meant\nAI agents couldn't see the full chart state:\n\n1. Drawings were not exposed at all — if the user drew a box,\n trendline, or had open positions, the LLM had no way to see them.\n2. Overlays were not exposed — if the user added a\n[…]\nlooking at, not\n the full dataset.\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 39723 -> 39981 bytes (+258 bytes for the drawing/\n overlay/value exposure logic)",
"is_bot": false,
"headline": "feat(llm): expose drawings, overlays, and sub-pane values in getConte…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:17:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "97f28192485e1ee8c4009212ad62cb0f7ef3ad1e",
"body": "Update all version references and CHANGELOG entry for the v1.5.0\nrelease (the actual version bump + git tag were done via\n'npm version minor' in the previous commit).\n\n## What this commit does\n\n- New [1.5.0] - 2026-07-20 entry in CHANGELOG covering all 9 commits:\n * Indicators math utilities (13 \n[…]\nts v1.5.0')\n- npx tsc --noEmit: 0 errors\n- Bundle: 39723 bytes gzipped (38.8KB)\n- No stale 1.4.1 version references in any md/html file\n- v1.5.0 git tag created by 'npm version' in the previous commit",
"is_bot": false,
"headline": "release: v1.5.0 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:09:13Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e8d7f3361594708b8c0d26eb1842ce162052387a",
"body": "…cators math utils",
"is_bot": false,
"headline": "release: v1.5.0 — 8 sub-pane indicators + 4 overlay indicators + indi…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:08:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30e91e09011d29227c1f8b3f6cd01365c65a8c5c",
"body": "Add the Ichimoku Cloud (Ichimoku Kinko Hyo) overlay indicator —\nthe most complex overlay, with 5 components and a filled cloud\nregion. This completes the overlay indicator set.\n\n## What it renders\n\nFive components on the main chart:\n 1. Tenkan-sen (Conversion Line): (9-period high + low) / 2 — blue\n[…]\nandsOverlay)\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 39097 -> 39725 bytes (+628 bytes for the Ichimoku\n overlay — the most complex indicator in the library)",
"is_bot": false,
"headline": "feat(overlays): Ichimoku Cloud overlay",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:08:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c6092fa8c190320c5d9805c3951f4baa145f2532",
"body": "Add the VWAP (Volume Weighted Average Price) overlay indicator.\nRenders a single line on the main chart at the cumulative\nvolume-weighted average price, resetting at the start of each\ncalendar day by default.\n\n## What it renders\n\nA line at VWAP = cumulative(typicalPrice * volume) / cumulative(volume\n[…]\nack to typical price when volume is 0 (avoids division\n by zero)\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 38943 -> 39097 bytes (+154 bytes for VWAPOverlay)",
"is_bot": false,
"headline": "feat(overlays): VWAP overlay",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:07:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ca7a3427e07852e6a029a940c08b8d3ca5bcf607",
"body": "Add the Bollinger Bands overlay indicator. Renders three lines on\nthe main chart (middle band = SMA, upper/lower = +/- numStdDev)\nplus an optional filled region between the bands.\n\n## What it renders\n\n - Middle band: SMA(period) of the close — solid line\n - Upper band: middle + numStdDev * rollin\n[…]\nss as a template for custom overlays)\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 38425 -> 38943 bytes (+518 bytes for BB overlay +\n the rollingStdDev function)",
"is_bot": false,
"headline": "feat(overlays): Bollinger Bands overlay",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:06:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "133f93f1fb3bcb9bb60305443281e66202826def",
"body": "Add the first two overlay indicators — Simple Moving Average and\nExponential Moving Average. Both draw a single line on the main\nchart on top of candles, using the main chart's price scale.\n\n## What they render\n\nA polyline connecting the indicator values for the visible bars,\nstarting at the first b\n[…]\nrs\n- npm run build: clean\n- Bundle gzipped: 38144 -> 38425 bytes (+281 bytes for LineOverlay +\n SMAOverlay + EMAOverlay; the sma()/ema() functions were already\n pulled in by the sub-pane indicators)",
"is_bot": false,
"headline": "feat(overlays): SMA + EMA overlay indicators",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:06:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "fa1d04217e072ad1253df0dec4d3ecad24120459",
"body": "Add the Overlay plugin interface and the rendering infrastructure\nfor overlay indicators — indicators that draw on the main chart on\ntop of candles, sharing the main chart's price scale (Y-axis).\nExamples: SMA, EMA, Bollinger Bands, VWAP, Ichimoku Cloud.\n\nThis is the foundation for Phase 3 (the actu\n[…]\n Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 38004 -> 38144 bytes (+140 bytes for the Overlay\n interface + overlay stack + renderOverlays + the 3 new Chart methods)",
"is_bot": false,
"headline": "feat(overlays): add overlay stack infrastructure",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:05:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a67801246f6a7c72070732604be5cf0a26d0b56d",
"body": "Add the remaining 5 sub-pane indicators, completing the sub-pane\nindicator set. All follow the same ScalePane pattern established\nby RSI/MACD/Stochastic.\n\n## New sub-pane indicators\n\n WilliamsRSubPane — Williams %R oscillator (-100..0 range)\n Overbought -20, oversold -80 by de\n[…]\norts\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 36941 -> 38004 bytes (+1063 bytes for the 5 new\n sub-panes + the williamsR/cci/mfi/atr/adx functions pulled in)",
"is_bot": false,
"headline": "feat(indicators): Williams %R, CCI, MFI, ATR, ADX sub-panes",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:03:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "fec4bd6e9875de156300bf01b522588e810a7890",
"body": "Add the Stochastic Oscillator sub-pane indicator. Renders two\nlines (%K and %D) in a separate sub-pane below the main chart, with\noverbought/oversold reference lines at 80/20 by default.\n\n## What it renders\n\n - %K line (fast or slow depending on smoothK) — blue by default\n - %D line (SMA of %K) — \n[…]\ntructor alongside RSI and MACD.\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 36621 -> 36941 bytes (+320 bytes for\n StochasticSubPane + the stochastic() function)",
"is_bot": false,
"headline": "feat(indicators): Stochastic Oscillator sub-pane",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T11:00:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1b12b489510942be140c5e0cffba8beda16b589d",
"body": "Add the MACD (Moving Average Convergence Divergence) sub-pane\nindicator. Renders three components in a separate sub-pane below\nthe main chart: MACD line, signal line, and histogram.\n\n## What it renders\n\n - Histogram bars (MACD - Signal): green for positive, red for\n negative, at 60% opacity so t\n[…]\nExport MACDSubPane\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 36109 -> 36621 bytes (+512 bytes for MACDSubPane\n + the macd() function + ema() helper pulled in)",
"is_bot": false,
"headline": "feat(indicators): MACD sub-pane",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T10:59:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b19521fefc82d90130281070ab05c882c7291658",
"body": "Add the RSI (Relative Strength Index) sub-pane indicator — the\nmost popular oscillator. Renders as a 0-100 line in a separate\nsub-pane below the main chart, with overbought/oversold reference\nlines at 70/30 by default.\n\n## What it renders\n\n - RSI line in a separate sub-pane (configurable color, def\n[…]\n- Export RSISubPane\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 35442 -> 36109 bytes (+667 bytes for RSISubPane +\n the rsi() function pulled in by tree-shaking)",
"is_bot": false,
"headline": "feat(indicators): RSI sub-pane",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T10:57:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f9a9b02fe3fd5be4cca8fabca947d5e7a361bb7e",
"body": "Add a shared math utility module with the most common technical\nindicators, ready to be used by sub-pane indicators (RSI, MACD,\nStochastic, etc.) and overlay indicators (SMA, EMA, Bollinger\nBands, etc.).\n\n## Indicators implemented (all pure functions, no chart dependency)\n\n sma(bars|values, period,\n[…]\nytes (+1591 bytes for the module\n declaration + namespace export; the functions themselves are\n tree-shaken out since no sub-pane imports them yet — they'll be\n pulled in as each sub-pane is added)",
"is_bot": false,
"headline": "feat(indicators): add technical indicator math utilities",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T10:56:15Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "512e3437ff28b06bc7cbb00fb37cf03494add7c2",
"body": "Update all version references and CHANGELOG entry for the v1.4.1\nrelease (the actual version bump + git tag were done via\n'npm version patch' in the previous commit).\n\n## What this commit does\n\n- New [1.4.1] - 2026-07-20 entry in CHANGELOG covering all 6 fix/feat\n commits since v1.4.0:\n * Fixed:\n[…]\nts v1.4.1')\n- npx tsc --noEmit: 0 errors\n- Bundle: 33852 bytes gzipped (33.1KB)\n- No stale 1.4.0 version references in any md/html file\n- v1.4.1 git tag created by 'npm version' in the previous commit",
"is_bot": false,
"headline": "release: v1.4.1 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T04:46:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7ef5c0fd30847a78e1b4ff23c2139cc29a663210",
"body": null,
"is_bot": false,
"headline": "release: v1.4.1 — drawing interaction fixes + OHLC magnet mode",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:12:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e261e16b4da793e8c8ef66e907b221833eb97876",
"body": "Replace the inline binary search in Renderer.previewTimeToX with a\ncall to this.chart.dataManager.getBarAtTime — the same method\nresolveAnchor uses. Removes ~12 lines of duplicated search logic\nand keeps a single source of truth for time→bar lookup.\n\nThe extrapolation fallback (when the time isn't f\n[…]\ne that's a preview-specific\nbehavior not shared with resolveAnchor.\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 33901 -> 33851 bytes (-50 bytes, shrank slightly)",
"is_bot": false,
"headline": "refactor(drawings): reuse DataManager.getBarAtTime in preview",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:11:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4d37f7262f948b31eccc58b2cfa077f4b420bad4",
"body": "Replace the (this.chart as any).drawingController accesses in\nEventManager with proper IChart methods (routeDrawingMouseDown /\nrouteDrawingMouseMove) so the access goes through the type-safe\ninterface instead of bypassing it with 'as any'.\n\n## Why\n\nThe previous commits used (this.chart as any).drawi\n[…]\nith this.chart.routeDrawingMouseMove(...)\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 33880 -> 33901 bytes (+21 bytes for the two new\n routing methods on Chart)",
"is_bot": false,
"headline": "refactor(drawings): clean drawing controller access via IChart",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:11:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "301cce23d4a1bf9acd7a708a10176cd5013ac98f",
"body": "When chart.isDrawing() is true (drawing-creation mode active), set\nthe canvas cursor to 'crosshair' on mousemove. This signals to the\nuser that they're in placement mode and the next click will drop an\nanchor — the standard convention in charting tools.\n\nWithout this, the cursor stayed as 'crosshair\n[…]\nor = 'crosshair' after routing the\n move to the drawing controller\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: unchanged (33880 bytes — one cursor assignment)",
"is_bot": false,
"headline": "feat(drawings): crosshair cursor in create mode",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:10:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7330936f14cd7c08a1bd40c7a118c0335666e59c",
"body": "Add a magnet mode for drawings that snaps anchor placement and\ndragging to the nearest Open, High, Low, or Close of the bar under\nthe cursor. Mirrors the existing crosshair magnet mode (which snaps\nto bar centers) but goes one step further: it snaps to the specific\nOHLC value closest to the cursor Y\n[…]\nr\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 33634 -> 33880 bytes (+246 bytes for magnetToOHLC\n + the option + setDrawingMagnet + the resolveWithMagnet wiring)",
"is_bot": false,
"headline": "feat(drawings): OHLC magnet mode for drawing anchors",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:09:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6bc0f32e5a2906f027dddff4be1f6f7c876c6fb3",
"body": "The rubber-band preview during drawing-creation mode always drew a\nline from p1 to the cursor, regardless of the drawing type. So when\ncreating a box, the user saw a line while dragging, then the box\nappeared only after the second click — confusing and inconsistent\nwith every other charting tool.\n\nN\n[…]\n both anchors\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 33422 -> 33634 bytes (+212 bytes for the shape\n switch + getPreviewShape method + IChart/Chart wiring)",
"is_bot": false,
"headline": "fix(drawings): type-aware rubber-band preview (box shows a box)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:07:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f7e7db78f54a7a83d9173959edef1418124edbb3",
"body": "Fix four interaction-layer bugs that surfaced during testing:\n\n## Bug 1: Cursor overwritten by chart's cursor logic\n\nDrawingInteraction.onMouseMove() set the cursor when hovering a\ndrawing handle/body, but returned false — so EventManager's cursor\nlogic below it overwrote the cursor with 'crosshair'\n[…]\nections\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 33365 -> 33422 bytes (+57 bytes for hoverActive\n flag, isHovering/clearHover methods, and mouseleave wiring)",
"is_bot": false,
"headline": "fix(drawings): cursor overwrite, hover cleanup, arrow direction",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-20T00:06:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f1494fbbf216813534ca11ca4f04406b1c622653",
"body": "Update all version references and CHANGELOG entry for the v1.4.0\nrelease (the actual version bump + git tag were done via\n'npm version minor' in the previous commit).\n\n## What this commit does\n\n- Convert the new work into a dated [1.4.0] entry (2026-07-20) in\n the CHANGELOG, placed above [1.3.0]. F\n[…]\nts v1.4.0')\n- npx tsc --noEmit: 0 errors\n- Bundle: 33365 bytes gzipped (32.6KB)\n- No stale 1.3.0 version references in any md/html file\n- v1.4.0 git tag created by 'npm version' in the previous commit",
"is_bot": false,
"headline": "release: v1.4.0 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:29:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bf95463f206b7d51bbeaafc1d5e1f81844fea54a",
"body": "… create-by-click, keyboard)",
"is_bot": false,
"headline": "release: v1.4.0 — interactive drawing system (hit-test, drag, resize,…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:27:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "af0cecedd253d4496d319bb42819ae413c0a6cb2",
"body": "Add the drawing-creation flow that lets users add drawings by\nclicking on the chart instead of calling chart.addDrawing()\nprogrammatically. This is the final piece that makes the drawing\nsystem actually usable as a drawing tool.\n\n## What it adds\n\n chart.beginDrawing(type) → enter create mode for t\n[…]\nfirst endpoint\n // User moves mouse → dashed preview line follows\n // User clicks again → commits the trendline, exits create mode\n\n // Cancel mid-drawing (or press Escape)\n chart.cancelDrawing();",
"is_bot": false,
"headline": "feat(drawings): add drawing-creation mode (click-to-create new drawings)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:24:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "434b8bcd423d8ae182081c59488048b7452c9f0e",
"body": "Add keyboard event handling for the drawing interaction layer:\n Delete / Backspace — remove the currently selected drawing\n Escape — cancel an in-progress drag, then clear the selection\n\n## Why\n\nWithout keyboard support, the only way to remove a drawing was to\ncall chart.removeDrawing(id) programm\n[…]\nteners, removed in destroy()\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 32337 -> 32507 bytes (+170 bytes for the\n handleKeyDown listener + Delete/Escape logic)",
"is_bot": false,
"headline": "feat(drawings): add Delete + Escape keyboard handling",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:21:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "53560279327fb730df70e89f2b47069ee5d57e8c",
"body": "Fix the body-drag handler in DrawingInteraction so dragging the\nbody of a two-point drawing (trendline, box, measure, fib,\nhighlighter, position_closed) moves BOTH anchors by the same delta,\npreserving the drawing's shape. Previously body drag only worked for\nsingle-point drawings — two-point body d\n[…]\nate across\ndrag operations.\n\n## Verification\n- tsc --noEmit: 0 errors\n- npm run build: clean\n- Bundle gzipped: 32207 -> 32337 bytes (+130 bytes for the start\n state capture + delta computation logic)",
"is_bot": false,
"headline": "feat(drawings): support two-point body drag (move whole drawing)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:21:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2604dc35e5dc8a2ee4fd539313c01126c56a408e",
"body": "Add hitTest() and getHandles() to every drawing renderer so they\nbecome interactive: draggable, resizable, and selectable. This is\nphase 2b of the interactive drawing system — combined with the\ndispatcher from the previous commit, drawings are now fully\ndraggable on the chart.\n\nAlso adds handle + se\n[…]\nimplementations + handle rendering in\n Renderer.renderDrawings + pointToSegmentDistance helpers)\n- All 14 drawing types now respond to mousedown on their handles\n and can be dragged around the chart",
"is_bot": false,
"headline": "feat(drawings): implement hitTest + getHandles for all 14 drawing types",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T23:19:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "fb55be5c9b994a27ce26c25edd89cb2c4671ee0c",
"body": "…outing\n\nAdd the central DrawingInteraction module that EventManager delegates\nto on mousedown/mousemove/mouseup. This is phase 2a of the interactive\ndrawing system — it routes events to drawings, manages drag state,\nand updates drawing anchors in place via chart.updateDrawing().\n\nPer-type hitTest/g\n[…]\ndrag to move)\n - position_closed: 2 endpoint handles\n - highlighter: 2 edge handles + body\n - arrow_up/down/label/text: 1 body handle\n\nEach renderer adds ~20-40 lines. Bundle impact: ~+1.5KB total.",
"is_bot": false,
"headline": "feat(drawings): add interaction dispatcher for hit-testing and drag r…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T20:19:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "50ccb4496613bdd59dcc727dea7174141f2418c3",
"body": "…eenToAnchor\n\nAdd the missing core that the drawing system needs to be interactive:\nthe hit-testing + drag-handle contract on DrawingRenderer, the inverse\ncoordinate mapper (screenToAnchor), and the chart-side selection state\n(selectedDrawingId, updateDrawing, selectDrawing).\n\nThis is phase 1 of the\n[…]\n 30400 -> 30550 bytes (+150 bytes for the new\n interface types, screenToAnchor, and the 3 new Chart methods)\n- No behavior change for existing drawings (the new methods are all\n optional / additive)",
"is_bot": false,
"headline": "feat(drawings): add interaction foundation — hitTest, getHandles, scr…",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T20:16:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "977f9a7cd880e16195f28fd182af6146a520450d",
"body": "Update all version references and CHANGELOG entry for the v1.3.0\nrelease (the actual version bump + git tag were done via\n'npm version minor' in the previous commit).\n\n## What this commit does\n\n- Convert the CHANGELOG 'Unreleased' section into a dated [1.3.0]\n entry (2026-07-19). The content is unc\n[…]\nts v1.3.0')\n- npx tsc --noEmit: 0 errors\n- Bundle: 30400 bytes gzipped (29.7KB)\n- No stale 1.2.x version references in any md/html file\n- v1.3.0 git tag created by 'npm version' in the previous commit",
"is_bot": false,
"headline": "release: v1.3.0 — version reference updates",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:36:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4fed7e4f11cc4809b1fc9f9d04fc4443e69b4865",
"body": "…(9 new drawing types)",
"is_bot": false,
"headline": "release: v1.3.0 — onCandleClose callback + extensible drawing system …",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:34:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6ec2ee8db5f4ac04159ef2dca6539d23e154d400",
"body": "Add a new 'position_closed' drawing type that visualizes a closed\ntrade with entry + exit markers, a connector line, and a fixed\nrealized PnL label. Complements the 'position' drawing type:\n - position = open trade with live unrealized PnL\n - position_closed = closed trade with entry+exit a\n[…]\nme2: 1704153600000, price2: 42850.0,\n color: '#3b82f6',\n data: { side: 'long', qty: 0.5 }\n });\n // → renders entry circle + exit square + connector + realized\n // PnL label '+350.0' (green)",
"is_bot": false,
"headline": "feat: add position_closed drawing type for closed trades",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:21:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6d3cfb88d9cc659f54f7d07f1816baf2382a6c86",
"body": "Add a new 'highlighter' drawing type that renders a vertical band\nspanning the full chart height between two time anchors. Common\nuses: earnings windows, news event periods, session ranges (London\nopen, NY open), marking a specific bar range for attention.\n\n## What it renders\n\nA filled rectangle fro\n[…]\n200000, // window start\n time2: 1704153600000, // window end\n color: '#f59e0b',\n text: 'Earnings Q3',\n data: { fill: 'rgba(245, 158, 11, 0.10)', lineStyle: 'dashed' }\n });",
"is_bot": false,
"headline": "feat: add highlighter drawing type for vertical time bands",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:18:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ea5b999c525fa799811c3db5b9fc107cb36b7b01",
"body": "Add a new 'text' drawing type for multi-line freeform text annotations.\nDistinct from the simpler 'label' type (single-line, fixed 16px box,\ncentered on anchor): 'text' accepts an array of lines, sizes the box\nto content, and anchors at the top-left with auto-flip when the box\nwould overflow the rig\n[…]\n 158, 11, 0.10)'\n }\n });\n\n // Single-line convenience\n chart.addDrawing({\n id: 'note-2', type: 'text',\n time: 1704153600000, price: 41800, color: '#3b82f6',\n text: 'Support level'\n });",
"is_bot": false,
"headline": "feat: add text drawing type for multi-line annotations",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:17:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "135fe4c942e119c8688060eecd4a2a8ed206d6b6",
"body": "Add a new 'order' drawing type that visualizes a resting order on\nthe chart. Complements the 'position' drawing — where 'position'\nshows a filled trade with live PnL, 'order' shows a pending order\nthat hasn't filled yet (no entry marker, no PnL).\n\n## What it renders\n\n (a) Dashed horizontal line at \n[…]\noveDrawing('ord-1');\n chart.addDrawing({\n id: 'pos-1', type: 'position',\n time: 1704067200000, price: 42150.5, color: '#3b82f6',\n data: { side: 'long', qty: 0.5, sl: 41800, tp: 43000 }\n });",
"is_bot": false,
"headline": "feat: add order drawing type for pending limit/stop orders",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:14:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "015afa9a0bd6e8364da860a820bd274922018e49",
"body": "Add a 2-point measurement annotation — the 'drag to measure' tool.\nDraws a connector line between two anchor points with endpoint\nmarkers and a label showing the price delta, percentage change, and\nbar count between them.\n\n## What it renders\n\n (a) Connector line between the two anchors (color/lineS\n[…]\n 1704067200000, price: 42150,\n time2: 1704153600000, price2: 42850,\n color: '#3b82f6',\n data: { lineStyle: 'dashed' }\n });\n // → renders '+700.0 (+1.66%)' / '10 bars' label near 2nd anchor",
"is_bot": false,
"headline": "feat: add measure drawing type",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:10:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "445181722d9135ace6695aa7df1bdbd3d82d4d8a",
"body": "Add Fibonacci retracement levels — the most-requested indicator\ndrawing. Draws 7 horizontal levels (0%, 23.6%, 38.2%, 50%, 61.8%,\n78.6%, 100%) between a swing's two anchor points, each with a\nright-axis price label.\n\n## What it renders\n\nFor a swing defined by two anchors (start, end), the renderer d\n[…]\n: 1704067200000, price: 41800, // swing low (start)\n time2: 1704153600000, price: 42900, // swing high (end)\n color: '#3b82f6',\n text: 'Fib Retracement',\n data: { lineWidth: 1 }\n });",
"is_bot": false,
"headline": "feat: add fib_retracement drawing type",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:08:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "084e185cad54ebd7858842188314b9299fe72843",
"body": "Add a 2-point rectangle drawing for trading ranges, supply/demand\nzones, pattern completion zones, and highlight regions. Reuses the\n2-anchor pattern established by TrendlineRenderer.\n\n## What it renders\n\nA rectangle between two opposite-corner anchor points. The renderer\nnormalizes the corners (lef\n[…]\nbox',\n time: 1704067200000, price: 42800,\n time2: 1704153600000, price2: 42100,\n color: '#ef4444',\n text: 'Supply',\n data: { fill: 'rgba(239, 68, 68, 0.12)', lineStyle: 'dashed' }\n });",
"is_bot": false,
"headline": "feat: add box drawing type",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:06:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4b305554550c3b6260dc252d6d445156317c6183",
"body": "Add a 2-point trendline drawing — the most-used drawing in technical\nanalysis. Establishes the 2-anchor pattern that box, fib_retracement,\nand measure will reuse.\n\n## What it renders\n\nA straight line between two anchor points on the chart, with optional\nextension beyond the anchors and an optional e\n[…]\nline',\n time: 1704067200000, price: 42150,\n time2: 1704153600000, price2: 42500,\n color: '#3b82f6',\n text: 'Support',\n data: { extend: 'right', lineStyle: 'dashed', lineWidth: 1 }\n });",
"is_bot": false,
"headline": "feat: add trendline drawing type",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T18:04:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "58dd1f5d5c807d14cde737a499ed158b3180074a",
"body": "Add a new 'position' drawing type that renders a trading position on\nthe chart with live unrealized PnL and optional stop-loss / take-profit\nlines. This is the first drawing type built on the new plugin registry\nestablished in the previous three commits — it required zero changes\nto Renderer, Chart,\n[…]\nll future\ndrawing types: trendline, box, fib, brush, pitchfork, measure, etc.\nEach will be a single new file under src/drawings/ plus one registry\nline — no core changes, no risk to existing behavior.",
"is_bot": false,
"headline": "feat: add position drawing with live PnL, SL/TP lines",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:57:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "68b6dc8458e3edd299cfa23edbfadd6ef8522d21",
"body": "Update all documentation to reflect the new plugin-based drawing\narchitecture: extended Drawing interface, DrawingData payload,\nregisterDrawingType() for custom types, resolveAnchor() helper, and\nthe extracted built-in renderers.\n\n## Changes\n\ndocs/API.md:\n- Drawing API section rewritten:\n * Added c\n[…]\nstyle helpers\n extraction, plugin registry, interface extension + validation)\n\n## Verification\n- tsc --noEmit: 0 errors (docs-only commit, no source changes)\n- npm run build: clean (no bundle change)",
"is_bot": false,
"headline": "docs: document the extensible drawing system",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:55:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "36e2aa5e50240cb8ff45ffbc20664be06a1796ed",
"body": "Restructure the Drawing interface to support multi-anchor drawings\n(trendline, box — future) and a typed data bag for type-specific\npayloads (position side/qty/sl/tp, line width/style, fill, etc.).\nAdd validateDrawing() and expose registerDrawingType() on the Chart\nclass so external apps can add cus\n[…]\nd: clean\n- Bundle gzipped: 26878 → 27488 bytes (+610 bytes for validateDrawing,\n DrawingData interface, registerDrawingType wiring)\n- registerDrawingType and drawing.data validation present in bundle",
"is_bot": false,
"headline": "refactor: extend Drawing interface for extensible drawing types",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:53:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "876075b9482d248e5a309a53bb0649f7b23989ae",
"body": "Move the five built-in drawing types (arrow_up, arrow_down, label,\nhline, vline) out of Renderer.renderDrawings() into a per-type plugin\narchitecture under src/drawings/. This mirrors the existing\nSeriesRenderer plugin pattern used for series types (candlestick,\nline, area, bar, heiken-ashi, hollow)\n[…]\ns (+169 bytes for the registry,\n 4 renderer classes, interface, and anchor helper)\n- Registry keys (arrow_up, arrow_down, label, hline, vline) present\n in bundle; chartBottomEdge inlined by minifier",
"is_bot": false,
"headline": "refactor: extract drawing renderers to plugin registry",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:51:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "44c1d34bd80fa901f36babc24bb450b989c806eb",
"body": "Move hexToRgba() and NAMED_COLORS out of Renderer into a new shared\nmodule src/utils/style.ts so they can be reused by the upcoming\ndrawing renderer plugins (and any future module that needs the same\ncolor parsing).\n\n## Why\n\nThe drawing system refactor (next commits) introduces per-type\ndrawing rend\n[…]\n is inlined by the\n minifier; chartBottomEdge/clampYToChartArea are tree-shaken out\n since nothing uses them yet)\n- No public API change\n- No behavior change (color parsing fallback chain preserved)",
"is_bot": false,
"headline": "refactor: extract color/style helpers to shared util module",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:49:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f1bb1d152311cb1f4941a1c7a23a33823d5904ad",
"body": "Add a new callback that fires exactly once per actual candle close,\ncomplementing the existing onDataUpdate (which fires on every tick\nand is too noisy for candle-close semantics).\n\n## Implementation\n\nSource (src/):\n- types/index.ts: New CandleCloseCallback type, new onCandleClose\n option in ChartO\n[…]\n+ integration example.\n- html/docs.html: Options listing entry.\n- README.md: Events API surface.\n- CHANGELOG.md: Unreleased section entry.\n\nNo version bump (more features pending before next release).",
"is_bot": false,
"headline": "feat: add onCandleClose callback for candle-close events",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-07-19T17:35:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0f07891f4559f2046759349b5967a502b81daa2e",
"body": null,
"is_bot": false,
"headline": "docs: update version references to v1.2.8 and CHANGELOG",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:34:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c772ad8ba943054f07b363b8085945609b98eaa6",
"body": null,
"is_bot": false,
"headline": "fix: separator cursor only shows when sub-panes exist (v1.2.8)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:32:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ce13a945258a010da7b3f8d8fb72e05c44d2c62",
"body": "The ns-resize cursor was appearing near the chart/time-axis boundary\neven when no sub-panes were active. isNearSeparator checked distance\nto chartBottomEdge without verifying that sub-panes actually exist.\n\nReplace with separatorHovered, which is computed by iterating\ngetActiveSubPanes() and only returns true near real separators.\nThis also fixes a latent issue where separators between multiple\nsub-panes didn't show the resize cursor (only the first one did).",
"is_bot": false,
"headline": "fix: separator cursor only shows when sub-panes exist",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:31:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "db29230de51533a035a5564aaa86ca7a11eb32f1",
"body": null,
"is_bot": false,
"headline": "docs: update version references to v1.2.7 and CHANGELOG",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:16:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b25e2c67d6fa219a4f5063d2a3ea8eca40ca1d6",
"body": null,
"is_bot": false,
"headline": "fix: correct center preservation on resize (v1.2.7)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:15:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fdc8343a7467896a49cdf6de73368ab384683f7a",
"body": "The preserve-center resize path computed the center bar index using the\nNEW width's center pixel instead of the OLD width's center. When the\nchart was resized while in non-autoscroll mode (user had panned), the\ncentered candle shifted away from where the user was looking.\n\nCapture oldCenterX from ol\n[…]\ntent old coordinate system\n(old center pixel + old barWidth + old offsetX) to find the bar the\nuser was actually viewing, which is then re-centered at the new\nviewport center with the scaled barWidth.",
"is_bot": false,
"headline": "fix: use old width center for preserve-center resize calculation",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T17:11:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "12630318110783a25241313cc2cf56c86e62b448",
"body": null,
"is_bot": false,
"headline": "docs: update version references to v1.2.6 and CHANGELOG",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T14:37:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "18e2eda2858a5f83ad8a4218d79bd091f647de5f",
"body": null,
"is_bot": false,
"headline": "fix: preserve-center resize + crosshair label + separator hover (v1.2.6)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T14:36:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3ad032dd097c8017836598aa7a2f45d060a71867",
"body": "The separator hover check only verified mouseX >= 0 (left bound) but\nnot mouseX <= chart width (right bound). When the cursor was to the\nright of the chart area at the separator's Y position, the separator\nincorrectly highlighted.\n\nAdded mouseX <= this.chart.state.w to the condition so hover only\ntriggers when the cursor is horizontally within the chart canvas.",
"is_bot": false,
"headline": "fix: bound separator hover check to chart width",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T14:35:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4200ebbf7f9996a4003edb4820b191baf7767c4b",
"body": "The time label was centered at the crosshair X position, causing it to\nclip at the left edge (x < ~60px) and right edge (x > chartAreaWidth -\n~60px). The label is now clamped to stay within [2, chartAreaWidth -\nboxWidth - 2], with text following the adjusted box position.\n\nThe crosshair vertical line stays at the actual cursor position — only\nthe label repositions for visibility. Narrow charts center the label\nas best effort.",
"is_bot": false,
"headline": "fix: clamp time axis crosshair label to visible chart area",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T14:35:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fe288812d41e94a724e134c887db62b590fa582e",
"body": "The preserve-center resize path broke after v1.2.3's proportional\nbarWidth scaling. xToIndex was called with NEW barWidth but OLD\noffsetX, mixing coordinate systems and producing a wrong center index.\n\nPre-compute preservedCenterIdx before barWidth is scaled, when both\nbarWidth and offsetX are still old values. The saved index is then\nused in the preserve-center branch with the scaled barWidth.\n\nAuto-scroll path unchanged — it never mixed coordinate systems.",
"is_bot": false,
"headline": "fix: pre-compute center index before barWidth scaling in resize",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T13:43:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f7a83b444cd64d23dc5eadfe43f93941eca8fbe5",
"body": null,
"is_bot": false,
"headline": "docs: update version references to v1.2.5 and CHANGELOG",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T00:04:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "01dd7ac11172601c76846a2eeea2abb7e4d5ca42",
"body": null,
"is_bot": false,
"headline": "fix: guard barWidth scaling against degenerate sizes (v1.2.5)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T00:03:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4d22c5289776d918057167aa3bca72617d767191",
"body": "The proportional barWidth scaling (v1.2.3+) corrupted zoom when resize()\nwas called with degenerate sizes (e.g., 1x1 from detached containers).\nA round-trip 300→1→300 left barWidth clamped at maxBarSpacing (1000),\neffectively max-zooming the chart.\n\nGuard now requires both oldWidth and newWidth >= 5\n[…]\n0px, the chart is in transition, detached, or unusable — none\nof which should permanently alter the zoom level. State.w update stays\noutside the guard so state remains truthful during skipped scaling.",
"is_bot": false,
"headline": "fix: guard barWidth scaling against degenerate resize sizes",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-24T00:03:21Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "58539839f592f6c9817743080b074b3d80c869d2",
"body": null,
"is_bot": false,
"headline": "docs: update version references to v1.2.4 and CHANGELOG",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T11:17:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9d77241eabe67d9c47fa2ffaa1fb4a0f6298452d",
"body": null,
"is_bot": false,
"headline": "fix: buffer height resize + dynamic version loading (v1.2.4)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T11:15:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e1511e5fade82b1b8d1074f2b16c2fed86923852",
"body": "Buffer was not recreated when only chart height changed (width stayed\nthe same), causing candles to render into a stale-height buffer and\nappear invisible or distorted beyond a height threshold.\n\nAdded currentBufferHeight check to the reuse condition so the buffer\nis properly resized when height changes beyond the threshold.",
"is_bot": false,
"headline": "fix: check buffer height in createBuffer reuse logic",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T11:13:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "baef63c6d3a86efeaba11b67c4a89080c864c010",
"body": "Replace hardcoded version strings with dynamic reads from package.json,\nensuring version consistency across build banner, global registry, and\ngetContext() API. Version is now never manually updated in source files.\n\n- Create src/version.ts as single source of truth\n- Update src/index.ts global registry to use LIB_VERSION\n- Update src/core/chart.ts getContext() to use LIB_VERSION\n- Update esbuild.config.js to read version from package.json at build time",
"is_bot": false,
"headline": "refactor: dynamic version loading from package.json",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T11:12:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a7831e53c68d0f8604accc94252868ebf4f9befb",
"body": null,
"is_bot": false,
"headline": "docs: update CHANGELOG for v1.2.3",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T10:21:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "34f7098064d14c275b1f3cb1ba4a0260316a265b",
"body": "Candles now scale proportionally when chart is resized,\npreventing them from appearing cut at chart edges.",
"is_bot": false,
"headline": "fix: barWidth scaling on resize (v1.2.3)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T10:18:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "143cacd6b4a602ef6c38847928ae29ea4ee70509",
"body": "Candles now scale proportionally when the chart is resized,\npreserving the visible range and preventing them from appearing\ncut at chart edges. Respects minBarSpacing/maxBarSpacing limits.",
"is_bot": false,
"headline": "fix: scale barWidth on resize to prevent cut candles",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-06-23T10:16:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ac19f7cd5154014f99d6c51374bebc2db741338",
"body": null,
"is_bot": false,
"headline": "docs: update CHANGELOG for v1.2.2",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-05-25T18:51:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c7eae95cf9749e45ee4dbf93d36073f14b74e740",
"body": null,
"is_bot": false,
"headline": "fix: crosshair virtual time projection (v1.2.2)",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-05-25T18:46:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9047c30815dec9d102275c43c0d9223ce4280430",
"body": null,
"is_bot": false,
"headline": "fix: crosshair virtual time for empty chart areas",
"author_name": "sithon.eth",
"author_login": "sithon-eth",
"committed_at": "2026-05-25T18:44:36Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 24,
"commits_last_year": 196,
"latest_release_at": "2026-07-21T17:40:09Z",
"latest_release_tag": "v1.5.8",
"releases_from_tags": true,
"days_since_last_push": 1,
"active_weeks_last_year": 9,
"days_since_latest_release": 6,
"mean_days_between_releases": 0.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 62,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "axon-charts",
"exists": true,
"license": "Apache-2.0",
"keywords": [
"candlestick",
"chart",
"financial",
"trading",
"canvas",
"llm",
"ai",
"axon",
"fintech",
"charting",
"candlestick-chart",
"financial-chart",
"trading-chart",
"realtime"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/axon-charts",
"is_deprecated": false,
"latest_version": "1.5.9",
"repository_url": "https://github.com/AxonWatch/axon-charts",
"versions_count": 18,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 1477,
"first_published_at": "2026-05-22T14:50:49.226000Z",
"latest_published_at": "2026-07-26T01:07:43.838000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 1
}
]
},
"popularity": {
"forks": 0,
"stars": 1,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": null,
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 61125,
"source_files_sampled": 68,
"oversized_source_files": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 0,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "sithon-eth",
"commits": 196,
"avatar_url": "https://avatars.githubusercontent.com/u/183833645?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": false,
"ci_workflows": [
"static.yaml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"package-lock.json"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 10,
"reason": "GitHub workflow tokens follow principle of least privilege",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 9,
"reason": "1 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "69c285e3e4b08922717d5c0c97c29ac4e69a407f",
"ran_at": "2026-07-27T17:41:49Z",
"aggregate_score": 3.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-26T01:08:12Z",
"oldest_open_prs": [],
"last_merged_pr_at": null,
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/AxonWatch/axon-charts",
"host": "github.com",
"name": "axon-charts",
"owner": "AxonWatch"
},
"metrics": {
"overall": {
"key": "overall",
"band": "at_risk",
"name": "Overall health",
"note": null,
"notes": [],
"value": 47,
"inputs": {
"security": 38,
"vitality": 71,
"community": 38,
"governance": 32,
"engineering": 54
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 71,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"commits_last_year": 196,
"human_commit_share": 1,
"days_since_last_push": 1,
"active_weeks_last_year": 9
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "9/52 weeks with commits",
"points": 6.2,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 9
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "196 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 196
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 88,
"inputs": {
"releases_count": 24,
"latest_release_tag": "v1.5.8",
"releases_from_tags": true,
"days_since_latest_release": 6,
"mean_days_between_releases": 0.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "24 version tags (no GitHub releases)",
"points": 16.2,
"status": "partial",
"details": [
{
"code": "version_tags_no_releases",
"params": {
"count": 24
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 6 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 6
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0.2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 38,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 1,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "1 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 1
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "good",
"name": "Community health",
"note": null,
"notes": [],
"value": 70,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (Apache-2.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "Apache-2.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 53,
"inputs": {
"packages": [
"axon-charts"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 1477
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "1,477 downloads/month across npm",
"points": 42.3,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 1477,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "at_risk",
"name": "Sustainability & Governance",
"value": 32,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 10,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "critical",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution",
"pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 1,
"inputs": {
"merged_prs": 0,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "no decided pull requests or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_decided_prs_or_data",
"params": {}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 33,
"inputs": {
"followers": 0,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "AxonWatch",
"public_repos": 1,
"account_age_days": 83
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "0 followers of AxonWatch",
"points": 0,
"status": "missed",
"details": [
{
"code": "owner_followers",
"params": {
"count": 0,
"login": "AxonWatch"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "1 public repos, account ~0 yr old",
"points": 2.6,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 1
}
},
{
"code": "account_age_years",
"params": {
"years": 0
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"axon-charts"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 1
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 1 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 1
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "18 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 18
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 54,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "at_risk",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 30,
"inputs": {
"has_ci": true,
"has_tests": false,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "1 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 1
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": "https://axonwatch.github.io/axon-charts/",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://axonwatch.github.io/axon-charts/",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 38,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"packaging",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 38,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 15,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 3,
"scorecard_aggregate": 3.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "GitHub workflow tokens follow principle of least privilege",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "1 existing vulnerabilities detected",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "at_risk",
"name": "AI Readiness",
"value": 41,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 100,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "critical",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 21,
"inputs": {
"has_nix": false,
"has_tests": false,
"lockfiles": [
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 99,
"inputs": {
"primary_language": "TypeScript",
"largest_source_bytes": 61125,
"source_files_sampled": 68,
"oversized_source_files": 1
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "1/68 source files over 60KB",
"points": 54.2,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 68,
"oversized": 1
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-27T17:41:53.413872Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/AxonWatch/axon-charts.svg",
"full_name": "AxonWatch/axon-charts",
"license_state": "standard",
"license_spdx": "Apache-2.0"
}