ccgauge 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +42 -42
  3. package/.next/standalone/.next/app-path-routes-manifest.json +9 -9
  4. package/.next/standalone/.next/build-manifest.json +2 -2
  5. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  6. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  7. package/.next/standalone/.next/server/app/api/blocks/route_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/api/export/usage/route_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/api/pricing/route_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/api/projects/route.js +1 -1
  11. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  12. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/api/scan/route_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/api/sessions/route.js +1 -1
  15. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  16. package/.next/standalone/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/api/usage/route.js +1 -1
  18. package/.next/standalone/.next/server/app/api/usage/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/usage/route_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/models/page.js +2 -2
  21. package/.next/standalone/.next/server/app/models/page.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/models/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/page.js +2 -2
  24. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/projects/[id]/page.js +2 -2
  27. package/.next/standalone/.next/server/app/projects/[id]/page.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/projects/[id]/page_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app/projects/page.js +1 -1
  30. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/sessions/[id]/page.js +2 -2
  33. package/.next/standalone/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/sessions/page.js +1 -1
  36. package/.next/standalone/.next/server/app/sessions/page.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  39. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/usage/page.js +3 -3
  41. package/.next/standalone/.next/server/app/usage/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app-paths-manifest.json +9 -9
  44. package/.next/standalone/.next/server/chunks/287.js +1 -0
  45. package/.next/standalone/.next/server/chunks/517.js +1 -1
  46. package/.next/standalone/.next/server/chunks/567.js +2 -2
  47. package/.next/standalone/.next/server/chunks/730.js +1 -0
  48. package/.next/standalone/.next/server/chunks/98.js +1 -1
  49. package/.next/standalone/.next/server/functions-config-manifest.json +2 -2
  50. package/.next/standalone/.next/server/pages/500.html +1 -1
  51. package/.next/standalone/.next/static/chunks/148-6c2eaf5508bfe739.js +1 -0
  52. package/.next/standalone/.next/static/chunks/930-ca5c6f8b5cb6ac3d.js +1 -0
  53. package/.next/standalone/.next/static/chunks/app/layout-4f3538437c5e8366.js +1 -0
  54. package/.next/standalone/.next/static/chunks/app/page-3cda7f70ecf5017a.js +1 -0
  55. package/.next/standalone/.next/static/chunks/app/settings/page-1ba7c4a4c0fae2f8.js +1 -0
  56. package/.next/standalone/.next/static/css/{406e067663b8b429.css → fbd2c395e5bf32cb.css} +1 -1
  57. package/.next/standalone/node_modules/next/node_modules/@img/sharp-darwin-arm64/LICENSE +191 -0
  58. package/.next/standalone/node_modules/next/node_modules/@img/sharp-darwin-arm64/lib/sharp-darwin-arm64.node +0 -0
  59. package/.next/standalone/node_modules/next/node_modules/@img/sharp-darwin-arm64/package.json +40 -0
  60. package/.next/standalone/node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64/lib/index.js +1 -0
  61. package/.next/standalone/node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64/lib/libvips-cpp.8.17.3.dylib +0 -0
  62. package/.next/standalone/node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64/package.json +36 -0
  63. package/.next/standalone/node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64/versions.json +30 -0
  64. package/.next/standalone/node_modules/next/node_modules/sharp/lib/channel.js +177 -0
  65. package/.next/standalone/node_modules/next/node_modules/sharp/lib/colour.js +195 -0
  66. package/.next/standalone/node_modules/next/node_modules/sharp/lib/composite.js +212 -0
  67. package/.next/standalone/node_modules/next/node_modules/sharp/lib/constructor.js +499 -0
  68. package/.next/standalone/node_modules/next/node_modules/sharp/lib/index.js +16 -0
  69. package/.next/standalone/node_modules/next/node_modules/sharp/lib/input.js +809 -0
  70. package/.next/standalone/node_modules/next/node_modules/sharp/lib/is.js +143 -0
  71. package/.next/standalone/node_modules/next/node_modules/sharp/lib/libvips.js +207 -0
  72. package/.next/standalone/node_modules/next/node_modules/sharp/lib/operation.js +1016 -0
  73. package/.next/standalone/node_modules/next/node_modules/sharp/lib/output.js +1666 -0
  74. package/.next/standalone/node_modules/next/node_modules/sharp/lib/resize.js +595 -0
  75. package/.next/standalone/node_modules/next/node_modules/sharp/lib/sharp.js +121 -0
  76. package/.next/standalone/node_modules/next/node_modules/sharp/lib/utility.js +291 -0
  77. package/.next/standalone/node_modules/next/node_modules/sharp/package.json +202 -0
  78. package/.next/standalone/node_modules/semver/classes/comparator.js +143 -0
  79. package/.next/standalone/node_modules/semver/classes/range.js +557 -0
  80. package/.next/standalone/node_modules/semver/classes/semver.js +333 -0
  81. package/.next/standalone/node_modules/semver/functions/cmp.js +54 -0
  82. package/.next/standalone/node_modules/semver/functions/coerce.js +62 -0
  83. package/.next/standalone/node_modules/semver/functions/compare.js +7 -0
  84. package/.next/standalone/node_modules/semver/functions/eq.js +5 -0
  85. package/.next/standalone/node_modules/semver/functions/gt.js +5 -0
  86. package/.next/standalone/node_modules/semver/functions/gte.js +5 -0
  87. package/.next/standalone/node_modules/semver/functions/lt.js +5 -0
  88. package/.next/standalone/node_modules/semver/functions/lte.js +5 -0
  89. package/.next/standalone/node_modules/semver/functions/neq.js +5 -0
  90. package/.next/standalone/node_modules/semver/functions/parse.js +18 -0
  91. package/.next/standalone/node_modules/semver/functions/satisfies.js +12 -0
  92. package/.next/standalone/node_modules/semver/internal/constants.js +37 -0
  93. package/.next/standalone/node_modules/semver/internal/debug.js +11 -0
  94. package/.next/standalone/node_modules/semver/internal/identifiers.js +29 -0
  95. package/.next/standalone/node_modules/semver/internal/lrucache.js +42 -0
  96. package/.next/standalone/node_modules/semver/internal/parse-options.js +17 -0
  97. package/.next/standalone/node_modules/semver/internal/re.js +223 -0
  98. package/.next/standalone/node_modules/semver/package.json +78 -0
  99. package/.next/standalone/package.json +13 -2
  100. package/.next/standalone/public/codex-logo.png +0 -0
  101. package/.next/standalone/public/favicon.svg +19 -5
  102. package/CHANGELOG.md +287 -0
  103. package/README.md +8 -2
  104. package/README.zh-CN.md +11 -4
  105. package/bin/cli.mjs +404 -92
  106. package/dist/mcp/server.mjs +16 -16
  107. package/dist/report/index.mjs +196 -30
  108. package/package.json +14 -3
  109. package/.next/standalone/.next/server/chunks/971.js +0 -1
  110. package/.next/standalone/.next/static/chunks/148-0a1e1b0207b89e3f.js +0 -1
  111. package/.next/standalone/.next/static/chunks/930-3035d0b294080d0b.js +0 -1
  112. package/.next/standalone/.next/static/chunks/app/layout-2512ccdfb13aeb17.js +0 -1
  113. package/.next/standalone/.next/static/chunks/app/page-19d3e77d4aa35a63.js +0 -1
  114. package/.next/standalone/.next/static/chunks/app/settings/page-cfeb089549c94f88.js +0 -1
  115. /package/.next/standalone/.next/static/{alqi5oQtTQUdpxp2x0yAt → kdpS1dOlXPsnKYuNBuMt9}/_buildManifest.js +0 -0
  116. /package/.next/standalone/.next/static/{alqi5oQtTQUdpxp2x0yAt → kdpS1dOlXPsnKYuNBuMt9}/_ssgManifest.js +0 -0
@@ -0,0 +1,223 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ MAX_SAFE_COMPONENT_LENGTH,
5
+ MAX_SAFE_BUILD_LENGTH,
6
+ MAX_LENGTH,
7
+ } = require('./constants')
8
+ const debug = require('./debug')
9
+ exports = module.exports = {}
10
+
11
+ // The actual regexps go on exports.re
12
+ const re = exports.re = []
13
+ const safeRe = exports.safeRe = []
14
+ const src = exports.src = []
15
+ const safeSrc = exports.safeSrc = []
16
+ const t = exports.t = {}
17
+ let R = 0
18
+
19
+ const LETTERDASHNUMBER = '[a-zA-Z0-9-]'
20
+
21
+ // Replace some greedy regex tokens to prevent regex dos issues. These regex are
22
+ // used internally via the safeRe object since all inputs in this library get
23
+ // normalized first to trim and collapse all extra whitespace. The original
24
+ // regexes are exported for userland consumption and lower level usage. A
25
+ // future breaking change could export the safer regex only with a note that
26
+ // all input should have extra whitespace removed.
27
+ const safeRegexReplacements = [
28
+ ['\\s', 1],
29
+ ['\\d', MAX_LENGTH],
30
+ [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
31
+ ]
32
+
33
+ const makeSafeRegex = (value) => {
34
+ for (const [token, max] of safeRegexReplacements) {
35
+ value = value
36
+ .split(`${token}*`).join(`${token}{0,${max}}`)
37
+ .split(`${token}+`).join(`${token}{1,${max}}`)
38
+ }
39
+ return value
40
+ }
41
+
42
+ const createToken = (name, value, isGlobal) => {
43
+ const safe = makeSafeRegex(value)
44
+ const index = R++
45
+ debug(name, index, value)
46
+ t[name] = index
47
+ src[index] = value
48
+ safeSrc[index] = safe
49
+ re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
50
+ safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined)
51
+ }
52
+
53
+ // The following Regular Expressions can be used for tokenizing,
54
+ // validating, and parsing SemVer version strings.
55
+
56
+ // ## Numeric Identifier
57
+ // A single `0`, or a non-zero digit followed by zero or more digits.
58
+
59
+ createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
60
+ createToken('NUMERICIDENTIFIERLOOSE', '\\d+')
61
+
62
+ // ## Non-numeric Identifier
63
+ // Zero or more digits, followed by a letter or hyphen, and then zero or
64
+ // more letters, digits, or hyphens.
65
+
66
+ createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`)
67
+
68
+ // ## Main Version
69
+ // Three dot-separated numeric identifiers.
70
+
71
+ createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
72
+ `(${src[t.NUMERICIDENTIFIER]})\\.` +
73
+ `(${src[t.NUMERICIDENTIFIER]})`)
74
+
75
+ createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
76
+ `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
77
+ `(${src[t.NUMERICIDENTIFIERLOOSE]})`)
78
+
79
+ // ## Pre-release Version Identifier
80
+ // A numeric identifier, or a non-numeric identifier.
81
+ // Non-numeric identifiers include numeric identifiers but can be longer.
82
+ // Therefore non-numeric identifiers must go first.
83
+
84
+ createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER]
85
+ }|${src[t.NUMERICIDENTIFIER]})`)
86
+
87
+ createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER]
88
+ }|${src[t.NUMERICIDENTIFIERLOOSE]})`)
89
+
90
+ // ## Pre-release Version
91
+ // Hyphen, followed by one or more dot-separated pre-release version
92
+ // identifiers.
93
+
94
+ createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
95
+ }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`)
96
+
97
+ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
98
+ }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`)
99
+
100
+ // ## Build Metadata Identifier
101
+ // Any combination of digits, letters, or hyphens.
102
+
103
+ createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`)
104
+
105
+ // ## Build Metadata
106
+ // Plus sign, followed by one or more period-separated build metadata
107
+ // identifiers.
108
+
109
+ createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
110
+ }(?:\\.${src[t.BUILDIDENTIFIER]})*))`)
111
+
112
+ // ## Full Version String
113
+ // A main version, followed optionally by a pre-release version and
114
+ // build metadata.
115
+
116
+ // Note that the only major, minor, patch, and pre-release sections of
117
+ // the version string are capturing groups. The build metadata is not a
118
+ // capturing group, because it should not ever be used in version
119
+ // comparison.
120
+
121
+ createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
122
+ }${src[t.PRERELEASE]}?${
123
+ src[t.BUILD]}?`)
124
+
125
+ createToken('FULL', `^${src[t.FULLPLAIN]}$`)
126
+
127
+ // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
128
+ // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
129
+ // common in the npm registry.
130
+ createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
131
+ }${src[t.PRERELEASELOOSE]}?${
132
+ src[t.BUILD]}?`)
133
+
134
+ createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`)
135
+
136
+ createToken('GTLT', '((?:<|>)?=?)')
137
+
138
+ // Something like "2.*" or "1.2.x".
139
+ // Note that "x.x" is a valid xRange identifer, meaning "any version"
140
+ // Only the first item is strictly required.
141
+ createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`)
142
+ createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`)
143
+
144
+ createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
145
+ `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
146
+ `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
147
+ `(?:${src[t.PRERELEASE]})?${
148
+ src[t.BUILD]}?` +
149
+ `)?)?`)
150
+
151
+ createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
152
+ `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
153
+ `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
154
+ `(?:${src[t.PRERELEASELOOSE]})?${
155
+ src[t.BUILD]}?` +
156
+ `)?)?`)
157
+
158
+ createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`)
159
+ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`)
160
+
161
+ // Coercion.
162
+ // Extract anything that could conceivably be a part of a valid semver
163
+ createToken('COERCEPLAIN', `${'(^|[^\\d])' +
164
+ '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
165
+ `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
166
+ `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`)
167
+ createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`)
168
+ createToken('COERCEFULL', src[t.COERCEPLAIN] +
169
+ `(?:${src[t.PRERELEASE]})?` +
170
+ `(?:${src[t.BUILD]})?` +
171
+ `(?:$|[^\\d])`)
172
+ createToken('COERCERTL', src[t.COERCE], true)
173
+ createToken('COERCERTLFULL', src[t.COERCEFULL], true)
174
+
175
+ // Tilde ranges.
176
+ // Meaning is "reasonably at or greater than"
177
+ createToken('LONETILDE', '(?:~>?)')
178
+
179
+ createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true)
180
+ exports.tildeTrimReplace = '$1~'
181
+
182
+ createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`)
183
+ createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`)
184
+
185
+ // Caret ranges.
186
+ // Meaning is "at least and backwards compatible with"
187
+ createToken('LONECARET', '(?:\\^)')
188
+
189
+ createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true)
190
+ exports.caretTrimReplace = '$1^'
191
+
192
+ createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`)
193
+ createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`)
194
+
195
+ // A simple gt/lt/eq thing, or just "" to indicate "any version"
196
+ createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`)
197
+ createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`)
198
+
199
+ // An expression to strip any whitespace between the gtlt and the thing
200
+ // it modifies, so that `> 1.2.3` ==> `>1.2.3`
201
+ createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
202
+ }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true)
203
+ exports.comparatorTrimReplace = '$1$2$3'
204
+
205
+ // Something like `1.2.3 - 1.2.4`
206
+ // Note that these all use the loose form, because they'll be
207
+ // checked against either the strict or loose comparator form
208
+ // later.
209
+ createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
210
+ `\\s+-\\s+` +
211
+ `(${src[t.XRANGEPLAIN]})` +
212
+ `\\s*$`)
213
+
214
+ createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
215
+ `\\s+-\\s+` +
216
+ `(${src[t.XRANGEPLAINLOOSE]})` +
217
+ `\\s*$`)
218
+
219
+ // Star ranges basically just allow anything at all.
220
+ createToken('STAR', '(<|>)?=?\\s*\\*')
221
+ // >=0.0.0 is like a star
222
+ createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
223
+ createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "semver",
3
+ "version": "7.7.4",
4
+ "description": "The semantic version parser used by npm.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "tap",
8
+ "snap": "tap",
9
+ "lint": "npm run eslint",
10
+ "postlint": "template-oss-check",
11
+ "lintfix": "npm run eslint -- --fix",
12
+ "posttest": "npm run lint",
13
+ "template-oss-apply": "template-oss-apply --force",
14
+ "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
15
+ },
16
+ "devDependencies": {
17
+ "@npmcli/eslint-config": "^6.0.0",
18
+ "@npmcli/template-oss": "4.29.0",
19
+ "benchmark": "^2.1.4",
20
+ "tap": "^16.0.0"
21
+ },
22
+ "license": "ISC",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/npm/node-semver.git"
26
+ },
27
+ "bin": {
28
+ "semver": "bin/semver.js"
29
+ },
30
+ "files": [
31
+ "bin/",
32
+ "lib/",
33
+ "classes/",
34
+ "functions/",
35
+ "internal/",
36
+ "ranges/",
37
+ "index.js",
38
+ "preload.js",
39
+ "range.bnf"
40
+ ],
41
+ "tap": {
42
+ "timeout": 30,
43
+ "coverage-map": "map.js",
44
+ "nyc-arg": [
45
+ "--exclude",
46
+ "tap-snapshots/**"
47
+ ]
48
+ },
49
+ "engines": {
50
+ "node": ">=10"
51
+ },
52
+ "author": "GitHub Inc.",
53
+ "templateOSS": {
54
+ "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
55
+ "version": "4.29.0",
56
+ "engines": ">=10",
57
+ "distPaths": [
58
+ "classes/",
59
+ "functions/",
60
+ "internal/",
61
+ "ranges/",
62
+ "index.js",
63
+ "preload.js",
64
+ "range.bnf"
65
+ ],
66
+ "allowPaths": [
67
+ "/classes/",
68
+ "/functions/",
69
+ "/internal/",
70
+ "/ranges/",
71
+ "/index.js",
72
+ "/preload.js",
73
+ "/range.bnf",
74
+ "/benchmarks"
75
+ ],
76
+ "publish": "true"
77
+ }
78
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccgauge",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Local web dashboard for Claude Code and OpenAI Codex CLI token usage and cost",
5
5
  "keywords": [
6
6
  "claude",
@@ -64,10 +64,16 @@
64
64
  "start:next": "next start -p 3737",
65
65
  "lint": "eslint .",
66
66
  "typecheck": "tsc --noEmit",
67
- "test": "node --experimental-strip-types --no-warnings scripts/test-codex-parser.mjs",
67
+ "test": "node --experimental-strip-types --no-warnings scripts/test-codex-parser.mjs && node --experimental-strip-types --no-warnings scripts/test-turns.mjs && node --experimental-strip-types --no-warnings scripts/test-source-merge.mjs && node --experimental-strip-types --no-warnings scripts/test-cost-from-usage.mjs && node --experimental-strip-types --no-warnings scripts/test-range.mjs && node scripts/check-parser-versions.mjs && node scripts/check-readme-images.mjs",
68
68
  "test:mcp": "node scripts/test-mcp-server.mjs",
69
69
  "clean": "node -e \"for (const p of ['.next','node_modules','tsconfig.tsbuildinfo']) require('node:fs').rmSync(p,{recursive:true,force:true})\"",
70
70
  "screenshots": "node scripts/screenshots.mjs",
71
+ "site:dev": "cd site && astro dev --port 4321",
72
+ "site:build": "cd site && astro build",
73
+ "site:preview": "cd site && astro preview --port 4322",
74
+ "site:check": "cd site && astro check",
75
+ "site:gen:placeholders": "node site/scripts/gen-placeholders.mjs",
76
+ "site:clean": "node -e \"for (const p of ['site/dist','site/.astro','site/node_modules']) require('node:fs').rmSync(p,{recursive:true,force:true})\"",
71
77
  "prepack": "pnpm build"
72
78
  },
73
79
  "dependencies": {
@@ -77,10 +83,15 @@
77
83
  "open": "^10.1.0"
78
84
  },
79
85
  "devDependencies": {
86
+ "@astrojs/check": "^0.9.4",
87
+ "@astrojs/tailwind": "^5.1.4",
80
88
  "@eslint/eslintrc": "^3.3.5",
89
+ "@fontsource-variable/geist": "^5.1.1",
90
+ "@fontsource-variable/geist-mono": "^5.1.1",
81
91
  "@types/node": "^22.10.0",
82
92
  "@types/react": "^19.0.0",
83
93
  "@types/react-dom": "^19.0.0",
94
+ "astro": "^4.16.18",
84
95
  "autoprefixer": "^10.4.20",
85
96
  "clsx": "^2.1.1",
86
97
  "date-fns": "^4.1.0",
@@ -1,7 +1,21 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
- <rect width="64" height="64" rx="14" fill="#4F46E5"/>
3
- <path d="M14 41 A18 18 0 0 1 50 41" stroke="#fff" stroke-opacity="0.32" stroke-width="4.5" stroke-linecap="round"/>
4
- <path d="M14 41 A18 18 0 0 1 43.2 25.4" stroke="#fff" stroke-width="4.5" stroke-linecap="round"/>
5
- <line x1="32" y1="41" x2="42" y2="27" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/>
6
- <circle cx="32" cy="41" r="3" fill="#fff"/>
2
+ <title>ccgauge</title>
3
+ <rect x="3" y="3" width="58" height="58" rx="16" fill="#6366F1"/>
4
+ <rect x="3.75" y="3.75" width="56.5" height="56.5" rx="15.25" stroke="#FFFFFF" stroke-opacity="0.18" stroke-width="1.5"/>
5
+ <path d="M15 39.5 A17 17 0 0 1 49 39.5" stroke="#FFFFFF" stroke-opacity="0.24" stroke-width="5" stroke-linecap="round"/>
6
+ <path d="M20.8 39.5 A11.2 11.2 0 0 1 43.2 39.5" stroke="#FFFFFF" stroke-opacity="0.2" stroke-width="1.8" stroke-linecap="round"/>
7
+ <path d="M15 39.5 A17 17 0 0 1 42.8 26" stroke="#FFFFFF" stroke-width="5" stroke-linecap="round"/>
8
+ <g stroke="#FFFFFF" stroke-linecap="round" stroke-width="2" stroke-opacity="0.54">
9
+ <path d="M18.1 34.2 L15 32.4"/>
10
+ <path d="M24 28.5 L22.3 25.5"/>
11
+ <path d="M32 26.2 L32 22.8"/>
12
+ <path d="M40 28.5 L41.7 25.5"/>
13
+ <path d="M45.9 34.2 L49 32.4"/>
14
+ </g>
15
+ <path d="M32 39.5 L42.8 26" stroke="#FFFFFF" stroke-width="3.4" stroke-linecap="round"/>
16
+ <circle cx="32" cy="39.5" r="4.8" fill="#FFFFFF"/>
17
+ <circle cx="32" cy="39.5" r="2" fill="#4F46E5"/>
18
+ <rect x="17" y="46" width="7" height="5" rx="2" fill="#34D399"/>
19
+ <rect x="28.5" y="43" width="7" height="8" rx="2" fill="#FBBF24"/>
20
+ <rect x="40" y="45" width="7" height="6" rx="2" fill="#93C5FD"/>
7
21
  </svg>
package/CHANGELOG.md CHANGED
@@ -5,6 +5,291 @@ All notable changes to **ccgauge** are documented here.
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
6
6
  this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.5] — 2026-05-19
9
+
10
+ CLI ergonomics overhaul + a brand-new `turns` / `conversations`
11
+ metric exposed in MCP and CLI report. Plus one P1 fix that resurrected
12
+ `ccgauge mcp` (silently exiting since 1.0.3's in-process refactor).
13
+
14
+ ### Highlights
15
+
16
+ - **`turns` / "Conversations" metric** added to MCP responses and CLI
17
+ report. A turn is one user prompt — the same unit the dashboard's
18
+ usage table rows, and `usage trend → Conversations` toggle, already
19
+ count. A single turn typically fans out to 10–20× more `requests`
20
+ via tool loops, reasoning steps, and sub-agents, so `turns` is the
21
+ better signal for "how often did I actually talk to the model".
22
+ All three surfaces now share `lib/turns.ts → summarizeTurns()`.
23
+ - **15+ CLI fixes + UX polish** — `ccgauge -r 7d` now produces a
24
+ helpful root error instead of `start: unknown option`; bare
25
+ `ccgauge` is the documented shortcut for `ccgauge start` again;
26
+ `ccgauge status` returns systemd-style exit 3 when not running;
27
+ `ccgauge stop` no longer kills unrelated processes after a reboot
28
+ (PID identity is verified); `ccgauge logs -f` no longer
29
+ duplicates lines under heavy write rates; foreground server starts
30
+ via `spawn` (matches background path); and a dozen smaller things.
31
+ - **New `ccgauge doctor` command** — one-screen diagnostic dumping
32
+ version, environment, build artifacts, background-service state,
33
+ and per-provider scan stats. The recommended first step for any
34
+ bug report.
35
+ - **P1 fix: `ccgauge mcp` now stays alive.** 1.0.3 refactored the
36
+ subcommand to run in-process via `await import()`, but a stray
37
+ `process.exit(0)` after `runStdioServer()` killed the process right
38
+ after the JSON-RPC transport opened, before any LLM client could
39
+ finish `initialize`. The smoke test now drives `node bin/cli.mjs
40
+ mcp` directly so this CLI-wrapper layer can never regress silently
41
+ again.
42
+
43
+ ### Added
44
+
45
+ - **`ccgauge doctor`** — single-shot diagnostic command. Prints
46
+ ccgauge version + node / platform, ccgauge-relevant env vars
47
+ (`CCGAUGE_*`, `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `NO_COLOR`,
48
+ `FORCE_COLOR`), build-artifact presence, background-service state,
49
+ and the indexer probe from `ccgauge mcp --check`. Plain text so
50
+ it pastes into a GitHub issue cleanly.
51
+ - **MCP `turns` field** in every analytical tool's response shape:
52
+ - `usage_summary` — `totals.turns`, `bySource.{claude,codex}.turns`.
53
+ - `usage_by_time` — `buckets[i].totals.turns` and per-source
54
+ breakdown; turns attribute to the bucket of their **earliest**
55
+ record (same convention as the dashboard's overview chart).
56
+ - `usage_by_model` — `models[i].turns` (turn is counted under
57
+ the model of its first record; sums across models equal the
58
+ scope's `totals.turns`).
59
+ - `usage_by_project` — `projects[i].turns` (by turn's first cwd).
60
+ - `usage_by_session` — `sessions[i].turns` (one session can hold
61
+ many turns; CLI users / LLMs comparing "long session vs many
62
+ short sessions" finally have the right number).
63
+ - `daily_summary`, `weekly_summary`, `recent_activity` — same
64
+ fields flow through their nested totals / per_day / sessions.
65
+ - `cost_estimator` is unchanged (pure pricing, no turn concept).
66
+ - **CLI report `Convos` field** in `ccgauge report` output:
67
+ - **Tokens section** gets a new `Convos / Requests` line, so the
68
+ two activity counts read side-by-side.
69
+ - **Top-N breakdown table** (model / project / session) gets a
70
+ new `Convos` column between the dimension label and `Reqs`.
71
+ - JSON output (`--json`) carries `totals.turns`, `trend[i].turns`,
72
+ `breakdown[i].turns`.
73
+ - **`lib/turns.ts → summarizeTurns()`** helper — given a (filtered)
74
+ record slice plus the full user / parent context, returns one
75
+ `TurnSummary` per distinct turn root with its `firstTimestamp`,
76
+ `firstModel`, `cwd`, `sessionId`, `source`. The single source of
77
+ truth shared by dashboard / MCP / CLI report.
78
+ - **`SessionSummary.projectLabel`** — worktree-aware display label
79
+ (`"ai-self-web (playwright)"` instead of bare `"playwright"`),
80
+ matching the usage table. Drives the `/sessions` page, the
81
+ session-detail header, and CLI report's session breakdown.
82
+
83
+ ### Changed
84
+
85
+ - **`ccgauge` (no subcommand)** is the documented shortcut for
86
+ `ccgauge start` again. A regression in 1.0.4's `normalizeArgv`
87
+ refactor made bare `ccgauge` print root help and exit 1.
88
+ - **`ccgauge status` exit code** is now systemd-style 3 when no
89
+ background service is running, so shell scripts can `if ccgauge
90
+ status; then …`. **`--json` mode** intentionally still exits 0
91
+ (the consumer is a script that should read `payload.running`),
92
+ so `ccgauge status --json | jq` under `set -e` keeps working.
93
+ - **`ccgauge mcp` runs in-process via `await import()` + the bundle
94
+ exports `runStdioServer` / `printCheck`.** Saves ~80–150 ms vs
95
+ the old spawn-a-child design and removes a brittle signal-
96
+ forwarding shim. (1.0.3 introduced this; 1.0.5 fixes the
97
+ `process.exit(0)` regression that broke it for real users.)
98
+ - **`ccgauge mcp --check`** — verifies the bundle, boots the
99
+ indexer, prints one line per provider with scanned dirs + record
100
+ counts, and exits. Lets users debug "Claude Desktop doesn't see
101
+ ccgauge tools" without spinning up an MCP client.
102
+ - **`--color` / `--no-color` / `FORCE_COLOR` / `NO_COLOR`** all
103
+ resolve through a single `shouldUseColor()` helper now, with the
104
+ documented precedence (`--no-color` highest, then env vars, then
105
+ `isTTY`). Previously the report's color flag was hard-AND'd with
106
+ `isTTY`, so `FORCE_COLOR=1 ccgauge report | tee log` lost colour.
107
+ - **`ccgauge start` foreground** uses `spawn` instead of `fork`.
108
+ Next.js standalone doesn't use IPC; `fork` was opening an unused
109
+ channel and the parent's `process.exit(0)` was racing the child's
110
+ teardown on Ctrl+C. Now matches the background path's `spawn` +
111
+ exit-code forwarding.
112
+ - **`--quiet`** silences Next.js's stderr too. Previously only stdout
113
+ was ignored, so warnings still leaked. (Background mode is
114
+ unaffected — it has always logged to a file.)
115
+ - **`ccgauge restart --dir ""`** clears the inherited override
116
+ instead of silently re-reading the previous run's `dataDir` from
117
+ `state.json`. Uses commander's `getOptionValueSource('dir') ===
118
+ 'cli'` instead of `!opts.dir` truthy check.
119
+ - **Background-start failure messages** now include the last 5
120
+ lines of `~/.ccgauge/ccgauge.log`, so users don't have to discover
121
+ `ccgauge logs` to learn that EADDRINUSE / their override path
122
+ doesn't exist / etc. caused the silent timeout.
123
+ - **"Build artifact not found"** errors from `start` / `report` /
124
+ `mcp` are unified into one `missingArtifactError(...)` helper.
125
+ Includes `node --version` / `ccgauge --version` / `platform` so
126
+ bug reports don't lose those.
127
+ - **`[ccgauge] error:`** prefix is now consistent on stderr
128
+ diagnostics (was a mix of `[ccgauge]`, `[ccgauge-mcp]`, and bare
129
+ prose). stdout user-facing messages stay unprefixed.
130
+ - **`/sessions` project column** uses `projectLabel` (worktree-aware)
131
+ so rows for `…/.claude/worktrees/playwright` read
132
+ `ai-self-web (playwright)` — matching the usage table.
133
+ - **CLI report's session breakdown** (`--by session`) `sub` text
134
+ also uses `projectLabel`, for the same reason.
135
+ - **README / README.zh-CN** Commands table gains `ccgauge doctor`;
136
+ Troubleshooting gains a "anything unexpected → ccgauge doctor"
137
+ lead; MCP troubleshooting points at `ccgauge mcp --check`.
138
+
139
+ ### Fixed
140
+
141
+ - **`ccgauge mcp` exited immediately after the JSON-RPC handshake**
142
+ (P1 regression from 1.0.3): the in-process CLI wrapper called
143
+ `process.exit(0)` after `await runStdioServer()`, but
144
+ `runStdioServer` returns as soon as `server.connect(transport)`
145
+ finishes the handshake — the long-running stdin readline is what
146
+ holds the process alive. Removed the exit; documented with a
147
+ `CRITICAL:` comment so it can't come back. Smoke test now runs
148
+ through `node bin/cli.mjs mcp` so the CLI wrapper is on the
149
+ covered path.
150
+ - **`ccgauge -r 7d -s codex` reported `start: unknown option '-r'`**
151
+ instead of "did you mean `report`?". `normalizeArgv` now only
152
+ injects `start` when every flag belongs to `start`'s own option
153
+ set; otherwise it leaves argv alone and lets commander surface
154
+ its own root-level error (which lists subcommands).
155
+ - **`ccgauge logs -f` duplicated lines under heavy write rates.**
156
+ The follow loop used `stat().size` as the read cursor but didn't
157
+ cap the `createReadStream`'s upper bound, so a chunk written
158
+ between `stat` and the read could appear in both ticks. Now
159
+ pins `end: s.size - 1`.
160
+ - **`ccgauge stop` could kill unrelated processes after a reboot.**
161
+ `process.kill(pid, 0)` only checks PID liveness, and PID space
162
+ recycles aggressively across boots. `state.json` now records a
163
+ `bootId` (~ system uptime) and a `cmdMarker` (`"next-server"`),
164
+ and `isProcessRunning` verifies both — falling back to the bare
165
+ kill(0) on Windows where `ps` isn't available.
166
+ - **`test-mcp-server.mjs` flake** caused by top-N truncation: a
167
+ tool that's in claude-only top-10 can land #11 in the merged
168
+ all top-10 once codex contributes more competitors. The
169
+ per-tool count comparison now skips tools that didn't survive
170
+ the merged truncation (the broader "source filter is a no-op"
171
+ check below catches the real bug it was originally meant to).
172
+ - **`/usage` project filter listed worktree leaves** as if they
173
+ were independent projects (`affectionate-sammet-00dc35`,
174
+ `agitated-diffie-5c15fe`, …), out of sync with `/projects`
175
+ which already collapses worktrees under their canonical repo
176
+ root. The dropdown now lists canonical cwds only; the
177
+ `projects` URL param semantics changed from exact-cwd to
178
+ canonical-cwd matching, and the aggregator's `projects` filter
179
+ is bypassed in favour of a canonical-aware pre-filter so a
180
+ single record under `…/.claude/worktrees/X` still counts when
181
+ the user picks its main repo.
182
+
183
+ ### Performance
184
+
185
+ - **Aggregator hot loop** — `withinRange` predicate used to call
186
+ `Date#toISOString()` + `Array.includes()` once per record. Each
187
+ entry-point function now hoists those into a `prepareOpts` step:
188
+ ISO strings computed once, `models` / `projects` materialized as
189
+ `Set` for O(1) membership. Measurable on the MCP `weekly_summary`
190
+ / `usage_by_*` paths over year-scale histories; invisible for the
191
+ single-pass dashboard aggregators.
192
+ - **MCP indexer's 30 s polling fallback** is now **off by default**.
193
+ fs.watch's `recursive: true` handles changes reliably on modern
194
+ macOS / Linux / Windows; the polling fallback was originally
195
+ there for flaky network mounts and FUSE setups. The web
196
+ dashboard's indexer **keeps polling ON** (user expects fresh
197
+ data when they alt-tab back). Override either default with
198
+ `CCGAUGE_POLL_FALLBACK={0,1}`.
199
+ - **`get-port` / `open` are lazy-imported** — only loaded by `start`
200
+ / `restart` / `open`. Short-lived commands like `mcp`, `status`,
201
+ `logs`, `report`, `--version` shave ~20–30 ms cold-start each.
202
+ Matters most for `ccgauge mcp`, which LLM clients spawn per
203
+ conversation.
204
+
205
+ ### Internal
206
+
207
+ - **`summarizeTurns()`** in `lib/turns.ts` is the single source of
208
+ truth for turn-level metadata; dashboard, MCP, and CLI report all
209
+ consume it. Same parent-chain walk + synthetic-user skip as
210
+ `buildTurnIndex` (which it builds on top of).
211
+ - **`TurnsContext`** in `lib/mcp/formatters.ts` packages
212
+ `{ users, parentMap }` so per-source aggregator helpers can
213
+ re-derive turn boundaries without re-plumbing args through every
214
+ call site.
215
+ - **`SessionSummary` carries `projectLabel`** (worktree-aware) in
216
+ addition to `projectName` (plain basename). Populated once by
217
+ `aggregateBySession` via `resolveProjectLabel` (per-cwd cache).
218
+ - **`bootId()` helper** in `bin/cli.mjs` (`Date.now() - os.uptime()
219
+ * 1000`, rounded) — a coarse system-boot timestamp used to tell
220
+ pre-reboot PIDs from post-reboot ones.
221
+ - **`shouldUseColor()` + `ansiPalette()`** in `bin/cli.mjs` — used
222
+ by `printReady` so the startup banner respects `NO_COLOR` and
223
+ doesn't leave `^[[1m...` mojibake when piped to `tee` / CI.
224
+ - **Smoke test runs through the CLI wrapper.** `scripts/test-mcp-
225
+ server.mjs` now spawns `node bin/cli.mjs mcp` instead of `node
226
+ dist/mcp/server.mjs`, so any regression in the CLI wrapper
227
+ (signal handling, lifecycle, exit-code shaping) is caught here.
228
+
229
+ ## [1.0.4] — 2026-05-18
230
+
231
+ Correctness fixes + much stronger test coverage, plus a brand refresh
232
+ and a marketing-site restructure. No new runtime features.
233
+
234
+ ### Fixed
235
+
236
+ - **Windows path sanitization.** `sanitizeForUser` now also strips
237
+ forward-slashed, JSON-escaped, and long-path (`\\?\`) variants of
238
+ `homedir()`, not just the literal `C:\Users\<name>` form. macOS /
239
+ Linux behaviour unchanged.
240
+ - **5h-block empty state** follows the active source —
241
+ `?source=codex` no longer says "Send a message in Claude Code".
242
+ Same fix on the Codex tab inside the All view.
243
+ - **`combineTimeBuckets` shared-reference bug.** Shallow-cloned model
244
+ entries were aliased back into the indexer's aggregator cache, so
245
+ downstream mutations could poison subsequent reads. Deep-cloned on
246
+ insertion; pinned by a new test.
247
+ - **`safeMcpHandler` non-Error throws** are now wrapped + scrubbed
248
+ before re-throw; the previous branch silently fell through, shipping
249
+ unscrubbed payloads into the MCP envelope.
250
+
251
+ ### Added
252
+
253
+ - **6 test / drift scripts**, all wired into `pnpm test`:
254
+ `test-turns`, `test-source-merge`, `test-cost-from-usage`,
255
+ `test-range` (fixture-based unit tests for the four core code
256
+ paths), plus `check-parser-versions` and `check-readme-images` (CI
257
+ drift guards for silently-stale-cache and broken-npm-image
258
+ regressions).
259
+
260
+ ### Changed
261
+
262
+ - **Refined gauge brand mark**, unified across the dashboard, the
263
+ marketing site, and both favicons. Cleaner geometry (centre at
264
+ (32, 41), radius 18; arc + needle terminating on the dial rim),
265
+ Indigo-400 → -600 gradient background, white-ring pivot. New shared
266
+ `<LogoMark>` component on the marketing site so its Nav + Footer
267
+ now use the same mark as the dashboard.
268
+ - **Marketing site is source-only.** Removed `site/package.json` and
269
+ `site/pnpm-lock.yaml`; Astro deps live in root `devDependencies`,
270
+ commands are explicit `pnpm site:*`. Still excluded from the npm
271
+ tarball (`pnpm pack --dry-run | grep -c '^site/'` → `0`).
272
+ - **Theme-aware product screenshots.** New `<ThemedScreenshot>`
273
+ component swaps between dark / light captures via the
274
+ `.theme-light` class on `<html>`. 24 captures (6 pages × 2 locales
275
+ × 2 themes) generated by an expanded `scripts/screenshots.mjs`.
276
+ - **OG cards** regenerated at higher fidelity.
277
+ - **`cost_estimator` MCP tool** description spells out that reasoning
278
+ tokens are already counted inside `output_tokens` — don't
279
+ double-count.
280
+ - **Activity heatmap tooltip** finally renders the share / of-peak
281
+ labels that were defined but never used.
282
+ - **`CacheCreationBlock` type** extracted in `parse-jsonl.ts`.
283
+ - **CLI `readState()`** type-guards `pid` / `url` / `logFile`.
284
+
285
+ ### Internal
286
+
287
+ - MCP server warm-up comment clarifies the fire-and-forget
288
+ `getMcpIndexerReady()` is a cold-start shave — tool handlers still
289
+ await the same memoized init promise.
290
+ - `AGENTS.md` + bundled READMEs updated for the source-only site
291
+ layout and the new `pnpm site:*` command set.
292
+
8
293
  ## [1.0.3] — 2026-05-15
9
294
 
10
295
  A focused **MCP server** correctness + performance + ergonomics pass,
@@ -678,6 +963,8 @@ of HTML to the browser.
678
963
  - Initial public release as `ccgauge`: local Next.js dashboard for
679
964
  Claude Code token usage, cost, and 5-hour block tracking.
680
965
 
966
+ [1.0.5]: https://github.com/chengzuopeng/ccgauge/compare/v1.0.4...v1.0.5
967
+ [1.0.4]: https://github.com/chengzuopeng/ccgauge/compare/v1.0.3...v1.0.4
681
968
  [1.0.3]: https://github.com/chengzuopeng/ccgauge/compare/v1.0.2...v1.0.3
682
969
  [1.0.2]: https://github.com/chengzuopeng/ccgauge/compare/v1.0.1...v1.0.2
683
970
  [1.0.1]: https://github.com/chengzuopeng/ccgauge/compare/v1.0.0...v1.0.1