codex-skill-analytics 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DESIGN.md ADDED
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: Codex Skill Analytics
3
+ description: 面向本地 Codex Skill 证据的工程运行审计台
4
+ colors:
5
+ canvas: "#eef2f3"
6
+ surface: "#ffffff"
7
+ surface-muted: "#f6f8f9"
8
+ ink: "#17242a"
9
+ muted: "#66777f"
10
+ line: "#d4dde0"
11
+ line-strong: "#adbdc3"
12
+ rail: "#152228"
13
+ rail-active: "#203139"
14
+ signal: "#007b94"
15
+ signal-deep: "#005c70"
16
+ scope-amber: "#bd6728"
17
+ danger: "#a63f3f"
18
+ scope-green: "#17766d"
19
+ scope-violet: "#7057a4"
20
+ scope-repo: "#3f659b"
21
+ focus: "#00a2c4"
22
+ typography:
23
+ headline:
24
+ fontFamily: '"DIN Alternate", "Avenir Next Condensed", sans-serif'
25
+ fontSize: "21px"
26
+ fontWeight: 600
27
+ lineHeight: 1.1
28
+ letterSpacing: ".01em"
29
+ title:
30
+ fontFamily: '"DIN Alternate", "Avenir Next Condensed", sans-serif'
31
+ fontSize: "14px"
32
+ fontWeight: 600
33
+ lineHeight: 1.2
34
+ letterSpacing: ".015em"
35
+ body:
36
+ fontFamily: '"Avenir Next", "PingFang SC", sans-serif'
37
+ fontSize: "13px"
38
+ label:
39
+ fontFamily: "ui-monospace, SFMono-Regular, monospace"
40
+ fontSize: "8px"
41
+ fontWeight: 600
42
+ letterSpacing: ".09em"
43
+ data:
44
+ fontFamily: "ui-monospace, SFMono-Regular, monospace"
45
+ fontSize: "23px"
46
+ fontWeight: 650
47
+ lineHeight: 1
48
+ letterSpacing: "-.03em"
49
+ rounded:
50
+ quiet: "4px"
51
+ control: "5px"
52
+ nav: "6px"
53
+ round: "50%"
54
+ spacing:
55
+ compact: "4px"
56
+ tight: "8px"
57
+ control: "10px"
58
+ panel: "14px"
59
+ section: "16px"
60
+ workspace: "20px"
61
+ rail: "24px"
62
+ components:
63
+ action-button:
64
+ backgroundColor: "{colors.signal-deep}"
65
+ textColor: "{colors.surface}"
66
+ rounded: "{rounded.control}"
67
+ padding: "0 13px"
68
+ height: "34px"
69
+ action-button-hover:
70
+ backgroundColor: "{colors.signal}"
71
+ textColor: "{colors.surface}"
72
+ rounded: "{rounded.control}"
73
+ padding: "0 13px"
74
+ height: "34px"
75
+ quiet-button:
76
+ backgroundColor: "{colors.surface}"
77
+ textColor: "{colors.signal-deep}"
78
+ rounded: "{rounded.quiet}"
79
+ padding: "5px 8px"
80
+ field:
81
+ backgroundColor: "{colors.surface}"
82
+ textColor: "{colors.ink}"
83
+ rounded: "{rounded.control}"
84
+ padding: "0 9px"
85
+ height: "34px"
86
+ nav-item:
87
+ backgroundColor: "transparent"
88
+ textColor: "#aebdc3"
89
+ rounded: "{rounded.nav}"
90
+ padding: "0 10px"
91
+ height: "42px"
92
+ nav-item-active:
93
+ backgroundColor: "{colors.rail-active}"
94
+ textColor: "{colors.surface}"
95
+ rounded: "{rounded.nav}"
96
+ padding: "0 10px"
97
+ height: "42px"
98
+ panel:
99
+ backgroundColor: "{colors.surface}"
100
+ textColor: "{colors.ink}"
101
+ selectable-data-row:
102
+ backgroundColor: "{colors.surface}"
103
+ textColor: "{colors.ink}"
104
+ padding: "0 11px"
105
+ height: "36px"
106
+ selectable-data-row-selected:
107
+ backgroundColor: "#e1f0f3"
108
+ textColor: "{colors.ink}"
109
+ padding: "0 11px"
110
+ height: "36px"
111
+ ---
112
+
113
+ # Design System: Codex Skill Analytics
114
+
115
+ ## Overview
116
+
117
+ **Creative North Star: "工程运行审计台"**
118
+
119
+ Codex Skill Analytics 的界面像一张长期打开的工程审计工作台:深色工作区导航承担稳定方位,冷白高密度画布承载筛选、指标、图表、表格与证据。视觉权威来自清楚的结构、可比较的数据和可追溯的状态,而不是营销式叙事。
120
+
121
+ 系统以细边界、紧凑间距和等宽数字建立秩序,以克制青色标记主要动作、聚焦与选择。它明确拒绝营销 Hero、夸张装饰和玩具式卡片堆叠;数据关系只表达观察证据,不借视觉暗示夸大为源码依赖。
122
+
123
+ **Key Characteristics:**
124
+
125
+ - 深色固定工作区导航与冷白分析画布形成稳定分区。
126
+ - 高密度排布、细结构线和紧凑控制优先服务快速扫描。
127
+ - 青色是稀缺的操作与聚焦信号,作用域色只编码数据语义。
128
+ - 数字、标识和状态采用等宽字形,文本标题采用窄体工程字体。
129
+ - 表面默认扁平,层级主要由色调和边界建立。
130
+
131
+ ## Colors
132
+
133
+ 以冷灰白与深青黑构成工作区,青色只承担操作信号;紫、绿、橙、蓝等作用域色仅用于数据分类。
134
+
135
+ ### Primary
136
+
137
+ - **审计信号青** (`signal`): 用于唯一主动作、选中边线、关系箭头和当前聚焦状态。
138
+ - **深审计青** (`signal-deep`): 用于主动作静止态与低调的文字动作,保证青色不会泛滥。
139
+
140
+ ### Secondary
141
+
142
+ - **作用域琥珀** (`scope-amber`): 标识插件作用域,并在关系图中强调当前活动边。
143
+ - **作用域绿** (`scope-green`): 标识用户共享 Skill 与在线状态。
144
+ - **作用域紫** (`scope-violet`): 标识系统 Skill。
145
+ - **仓库蓝** (`scope-repo`): 标识项目仓库 Skill。
146
+
147
+ ### Tertiary
148
+
149
+ - **危险红** (`danger`): 保留给失败或危险语义,不作为装饰色。
150
+ - **焦点亮青** (`focus`): 仅用于键盘焦点环等无障碍反馈。
151
+
152
+ ### Neutral
153
+
154
+ - **冷雾画布** (`canvas`): 包围所有分析面板的页面底色。
155
+ - **冷白表面** (`surface`): 命令栏、面板、字段和数据行的主表面。
156
+ - **次级冷白** (`surface-muted`): 表头和轻度分区,不制造卡片层叠。
157
+ - **工程墨色** (`ink`): 标题、正文与关键数据的默认前景色。
158
+ - **审计灰** (`muted`): 辅助说明、标签和元数据。
159
+ - **细规则线** (`line`): 面板、分隔和表格结构。
160
+ - **强规则线** (`line-strong`): 输入和低调动作的边界。
161
+ - **工作区深青黑** (`rail`): 固定导航轨道。
162
+ - **工作区激活面** (`rail-active`): 当前导航项的低对比度选中面。
163
+
164
+ ### Named Rules
165
+
166
+ **The Signal Scarcity Rule.** 青色只标记操作、焦点和选择;不要用它填充普通容器或装饰大面积背景。
167
+
168
+ **The Semantic Scope Rule.** 作用域色只编码 system、user、plugin、repo 等真实类别,绝不拿来制造无含义的视觉变化。
169
+
170
+ ## Typography
171
+
172
+ **Display Font:** 不设营销展示字体;本系统没有 Hero 层级。
173
+ **Body Font:** Avenir Next(中文回退 PingFang SC)
174
+ **Label/Mono Font:** ui-monospace(回退 SFMono-Regular 与 monospace)
175
+
176
+ **Character:** 窄体标题提供工程控制台的清晰骨架,正文保持 macOS 原生阅读感;等宽数据让数量、权重、索引、时间和状态可以纵向比较。
177
+
178
+ ### Hierarchy
179
+
180
+ - **Headline** (600, `headline`): 只用于页面标题,保持紧凑而非宣传化。
181
+ - **Title** (600, `title`): 用于面板标题和检查器标题。
182
+ - **Body** (常规, `body`): 用于控件内容、行文本与简短说明。
183
+ - **Data** (650, `data`): 用于指标值,启用表格数字并保持对齐。
184
+ - **Label** (600, `label`, uppercase): 用于字段标签、表头、索引和状态元数据。
185
+
186
+ ### Named Rules
187
+
188
+ **The Monospace Evidence Rule.** 数字、权重、时间、索引与状态使用等宽字;叙述文本不使用等宽字制造伪技术感。
189
+
190
+ ## Layout
191
+
192
+ 桌面使用 228px 深色导航轨与可伸缩工作区;工作区顶部是 72px 命令栏,主体以 20px 横向内边距和 14px 面板间距组织。数量页主分析区是内容区加 330px 图例栏,关系页是内容区加 340px 检查器栏;指标条为五列或四列的连续分段表面,而不是独立卡片。
193
+
194
+ 在 1100px 以下,数量页主图、图例和下方区域依次堆叠;在 1050px 以下,关系图与检查器分层,两个检查器并列。在 980px 以下,导航轨缩至 72px,隐藏辅助文字,五项指标改为三列折行。在 680px 以下,导航转为顶部横条,命令控件全宽单列,指标改为两列;关系图保留 960px 全尺寸 SVG 并允许内部横向滑动,避免把网络压缩到不可读。
195
+
196
+ **The Data Before Decoration Rule.** 首屏顺序始终是方位、筛选、紧凑指标和主数据视图;不插入 Hero、口号区或装饰模块。
197
+
198
+ ## Elevation & Depth
199
+
200
+ 系统默认扁平。画布、命令栏、面板、表头和数据行通过冷白色调差与 1px 细边界分层;常规面板不使用阴影。阴影只出现在键盘焦点、在线状态点、选中行内嵌信号和关系节点等明确状态反馈中。
201
+
202
+ ### Shadow Vocabulary
203
+
204
+ - **Reserved ambient** (`shadow`): 源码中保留的低幅环境阴影 token,当前常规面板未使用。
205
+ - **Focus ring** (`0 0 0 3px rgba(0,162,196,.25)`): 键盘焦点反馈。
206
+ - **Status halo** (`0 0 0 3px rgba(73,183,165,.13)`): 在线状态点的低幅光环。
207
+ - **Selected inset** (`inset 3px 0 0 var(--signal)`): 聚焦 Skill 行的非颜色唯一选择标记。
208
+ - **Graph node lift** (`drop-shadow(0 3px 4px rgba(23,36,42,.16))`): 仅让可拖动关系节点与图谱底面分离。
209
+
210
+ **The Flat-by-Default Rule.** 静止表面依靠色调与边界分层;阴影必须对应焦点、选择、在线或可拖动状态。
211
+
212
+ ## Shapes
213
+
214
+ 主体面板和指标条保持直角,以强化连续审计画布;字段与主动作采用轻微圆角,导航项稍柔和,数据节点和作用域点使用圆形。所有边界保持细而克制,不使用胶囊按钮或夸张圆角卡片。
215
+
216
+ **The Structural Corner Rule.** 容器保持直角;只有可交互控件、导航项和真实点状数据标记使用已定义圆角。
217
+
218
+ ## Components
219
+
220
+ ### Buttons
221
+
222
+ - **Shape:** 主动作使用紧凑轻圆角 (`control`) 和 34px 高度;低调动作使用更小圆角 (`quiet`)。
223
+ - **Primary:** 深审计青底、冷白文字与 13px 水平内边距;hover 转为审计信号青。
224
+ - **Hover / Focus:** hover 只做色调变化;focus-visible 使用 3px 亮青透明焦点环;disabled 降至 55% 不透明度并显示等待光标。
225
+ - **Quiet:** 冷白底、强规则线边框和深审计青文字;hover 使用极淡青白底。
226
+
227
+ ### Cards / Containers
228
+
229
+ - **Corner Style:** 主面板无圆角。
230
+ - **Background:** 冷白表面,表头可使用次级冷白。
231
+ - **Shadow Strategy:** 常规状态无阴影。
232
+ - **Border:** 1px 细规则线;面板标题栏以同样规则线分隔。
233
+ - **Internal Padding:** 标题栏水平 16px;内容根据数据类型使用 8–16px 的紧凑节奏。
234
+
235
+ ### Inputs / Fields
236
+
237
+ - **Style:** 34px 高度、冷白底、1px 强规则线和轻圆角 (`control`),水平内边距 9px。
238
+ - **Focus:** 使用统一亮青透明焦点环,保留原有边框以避免布局跳动。
239
+ - **Responsive:** 680px 以下字段与主动作扩展为整行,不挤压输入内容。
240
+
241
+ ### Navigation
242
+
243
+ - **Style:** 桌面为 228px 深色纵向工作区轨,项目高 42px、轻圆角 (`nav`);索引和计数使用等宽字。
244
+ - **States:** hover 使用更亮深青面;active 使用工作区激活面、可见边界和白色文字,索引变为浅青。
245
+ - **Responsive:** 980px 以下缩成图标式窄轨;680px 以下变为顶部横向导航并保留文字标签。
246
+
247
+ ### Metrics Strip
248
+
249
+ - **Style:** 多个指标共享一块冷白连续表面,用 1px 规则线分段;数值使用等宽 Data 层级。
250
+ - **Responsive:** 五列或四列按断点折成三列、两列,不拆成悬浮卡片。
251
+
252
+ ### Selectable Data Rows
253
+
254
+ - **Style:** 图例行和关系列使用全宽、无外框的紧凑按钮行,底部细线分隔。
255
+ - **States:** hover 只改变冷白色调;选中 Skill 行同时使用浅青底和 3px 左侧内嵌信号,避免仅靠颜色表达选择。
256
+
257
+ ### Graph Nodes
258
+
259
+ - **Style:** 圆形节点按调用量缩放,填色只来自作用域语义;名称使用正文粗体,作用域标签使用等宽小写标签。
260
+ - **States:** hover、selected 与 keyboard focus 都以深色加粗描边确认交互状态;非匹配节点降低不透明度但保留网络上下文。
261
+ - **Mobile:** 不缩小全图;在 680px 以下让 960px 图谱在容器内横向滑动。
262
+
263
+ ## Do's and Don'ts
264
+
265
+ ### Do:
266
+
267
+ - **Do** 让导航、筛选和主数据视图在首屏形成连续操作路径。
268
+ - **Do** 使用细边界、冷白色调差和紧凑间距表达层级。
269
+ - **Do** 用等宽字呈现可比较的数字、时间、权重、索引和状态。
270
+ - **Do** 为选择提供边线、描边或结构变化,不能只改变颜色。
271
+ - **Do** 在窄屏保留图表的可读尺度,并让超宽数据视图内部滚动。
272
+
273
+ ### Don't:
274
+
275
+ - **Don't** 添加营销 Hero、巨大口号、客户证明或与本地证据无关的品牌叙事。
276
+ - **Don't** 把每项指标拆成带阴影、厚圆角的玩具式卡片。
277
+ - **Don't** 大面积铺设青色或把作用域色用于非语义装饰。
278
+ - **Don't** 用阴影代替结构线,也不要让静止面板悬浮。
279
+ - **Don't** 把观察到的顺序、共现或相邻关系描述成声明式依赖。
package/PRODUCT.md ADDED
@@ -0,0 +1,54 @@
1
+ # Product
2
+
3
+ <!-- impeccable:product-schema 1 -->
4
+
5
+ ## Platform
6
+
7
+ web
8
+
9
+ ## Stack
10
+
11
+ Existing implementation: Python 3.11 standard library HTTP server, SQLite, and dependency-free HTML/CSS/JavaScript. No framework migration is authorized by the current request.
12
+
13
+ ## Users
14
+
15
+ Inferred from the explicit brief: the primary user is a local Codex power user or agent-infrastructure engineer who needs to inspect Skill behavior repeatedly, not a first-time visitor viewing a product demo.
16
+
17
+ ## Product Purpose
18
+
19
+ Codex Skill Analytics is a read-only sidecar for local Codex history. It turns deterministic Skill invocation evidence into an operational view of invocation volume, time trends, recent events, and observed Skill-to-Skill relationships. Success means the user can compare all Skills quickly, isolate one Skill without losing context, and trace every result back to local event metadata.
20
+
21
+ ## Positioning
22
+
23
+ The product derives reproducible analytics from local rollout evidence without semantic classification, model inference, or changes to Codex. It distinguishes per-turn Invocation counts from document/script Access evidence.
24
+
25
+ ## Operating Context
26
+
27
+ The Web runs on localhost and reads an independent SQLite database populated incrementally from `~/.codex/sessions` and `~/.codex/archived_sessions`. It is used alongside Codex as an engineering observability surface. The two primary workflows are volume analysis and relationship analysis.
28
+
29
+ ## Capabilities and Constraints
30
+
31
+ - Two separate pages are required: invocation quantity and invocation relationships.
32
+ - The quantity page must show every Skill as its own time-series line and allow any Skill to be focused interactively.
33
+ - The relationship page must support observed sequence, same-turn co-occurrence, and next-in-thread relationships.
34
+ - The system must remain local-only, deterministic, and free of LLM or model API dependencies.
35
+ - It must not store user messages, assistant messages, reasoning, complete commands, or tool output.
36
+ - The local rollout schema is internal and may drift; unknown records are skipped rather than guessed.
37
+
38
+ ## Evidence on Hand
39
+
40
+ - The current local database contains real Codex invocation, access, thread, turn, trend, and relationship records.
41
+ - Source and tests live in this repository; generated screenshots under `reports/` are verification evidence, not brand assets.
42
+ - No customer logos, testimonials, commercial claims, or external benchmark data exist and none may be fabricated.
43
+
44
+ ## Product Principles
45
+
46
+ - Operational clarity before decoration.
47
+ - Dense comparison with controlled focus, not isolated vanity metrics.
48
+ - Observed evidence must never be presented as declared dependency.
49
+ - Every filter and count must remain honest about its scope.
50
+ - Local privacy and reproducibility are product behavior, not marketing copy.
51
+
52
+ ## Accessibility & Inclusion
53
+
54
+ Keyboard focus, reduced-motion behavior, responsive layouts, readable contrast, and non-color-only selection states are required for both Web pages.
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # Codex Skill Analytics
2
+
3
+ 一个完全本地、纯工程实现的 Codex Skill 旁路分析器。它只读扫描 Codex rollout JSONL,
4
+ 确定性识别 Skill 文档读取、Skill 脚本运行和可识别的显式 Skill 注入,然后增量写入独立
5
+ SQLite 数据库。运行时不调用任何模型,也不修改或拦截 Codex。
6
+
7
+ ## 统计口径
8
+
9
+ - **Invocation**:同一轮中同一 Skill 只计一次,与 Codex 当前源码的去重口径一致。
10
+ - **Access**:每次可验证的 `SKILL.md` 读取或 `scripts/` 脚本执行均计一次。
11
+ - **Same turn**:两个 Skill 在同一轮共同调用。
12
+ - **Sequence**:同一轮中相邻的 Skill 调用方向。
13
+ - **Next in thread**:同一线程中相邻的 Skill 调用方向,关系弱于同轮序列。
14
+
15
+ 仅有名称提及、系统 Skill 清单、代码示例和搜索结果不会被算作调用。
16
+
17
+ ## 一条命令启动 Web
18
+
19
+ 需要 Python 3.11 或更高版本,以及本机 Codex 产生的 `~/.codex/sessions` 或
20
+ `~/.codex/archived_sessions` 历史。
21
+
22
+ 拿到仓库后直接运行:
23
+
24
+ ```bash
25
+ ./run.sh
26
+ ```
27
+
28
+ 脚本不安装第三方依赖,会自动增量同步本机 Codex 历史、启动本地服务,并在默认浏览器打开:
29
+
30
+ ```text
31
+ http://127.0.0.1:8765/
32
+ ```
33
+
34
+ 首次从 GitHub 获取私有仓库时,可使用一行命令:
35
+
36
+ ```bash
37
+ gh repo clone NauJson/codex-skill-analytics && cd codex-skill-analytics && ./run.sh
38
+ ```
39
+
40
+ 停止服务按 `Ctrl-C`。再次运行仍是增量同步,不会重复计数。如果机器上没有 Codex 历史,Web
41
+ 仍能打开,但统计结果为空。
42
+
43
+ ## NPM / NPX CLI
44
+
45
+ 安装发布包后,可直接启动并打开 Web:
46
+
47
+ ```bash
48
+ npx codex-skill-analytics
49
+ ```
50
+
51
+ 或全局安装,两个命令名都可用:
52
+
53
+ ```bash
54
+ npm install --global codex-skill-analytics
55
+ codex-skill-analytics
56
+ # 简写
57
+ csa
58
+ ```
59
+
60
+ 不带参数时,CLI 会先增量同步本机历史,然后打开 Web。原有子命令可以直接透传:
61
+
62
+ ```bash
63
+ csa sync
64
+ csa summary --days 30
65
+ csa events --days 30 --limit 100
66
+ csa relations --days 30 --type sequence
67
+ csa graph --days 30 --type sequence --output skill-graph.html
68
+ csa serve --open
69
+ ```
70
+
71
+ NPM 包不携带、不上传用户的 Codex 历史或 SQLite 数据。它包含 Node 启动器和纯标准库 Python
72
+ 分析内核;运行机器仍需安装 Python 3.11 或更高版本。可通过
73
+ `CSA_PYTHON=/path/to/python csa` 显式指定解释器。
74
+
75
+ ## 开发安装与命令行使用
76
+
77
+ ```bash
78
+ git clone https://github.com/NauJson/codex-skill-analytics.git
79
+ cd codex-skill-analytics
80
+ python3 -m venv .venv
81
+ .venv/bin/pip install -e .
82
+
83
+ .venv/bin/codex-skill-analytics sync
84
+ .venv/bin/codex-skill-analytics summary --days 30
85
+ .venv/bin/codex-skill-analytics events --days 30 --limit 100
86
+ .venv/bin/codex-skill-analytics trend --days 30
87
+ .venv/bin/codex-skill-analytics relations --days 30 --type same-turn
88
+ .venv/bin/codex-skill-analytics relations --days 30 --type sequence
89
+ .venv/bin/codex-skill-analytics graph --days 30 --type sequence \
90
+ --min-weight 2 --output skill-dependency-graph.html
91
+ .venv/bin/codex-skill-analytics serve --open
92
+ ```
93
+
94
+ 默认数据库位于:
95
+
96
+ ```text
97
+ ~/.local/share/codex-skill-analytics/analytics.sqlite3
98
+ ```
99
+
100
+ 可用 `--db /path/to/file.sqlite3` 指定其他位置。
101
+
102
+ `graph` 会生成不依赖网络的单文件交互式 HTML。默认的 `sequence` 图中,`A → B` 表示同一轮
103
+ 内 A 后紧接着调用了 B;这是一种从历史观察到的应用依赖,不代表 Skill 源码声明了硬依赖。
104
+ 也可用 `--type same-turn` 查看无方向共现,或用 `--type next-in-thread` 查看线程内跨轮衔接。
105
+
106
+ `serve` 默认只监听 `127.0.0.1:8765`,提供两个独立页面:
107
+
108
+ - `/`:调用数量、每日趋势、Skill 排名、作用域分布和最近调用;
109
+ - `/relations`:调用顺序、同轮共现和线程内相邻调用图谱。
110
+
111
+ 页面只通过本机 API 查询同一个 SQLite;“同步最新历史”仍然只读 Codex rollout,并把新增事件
112
+ 写入旁路数据库。
113
+
114
+ ## 隐私边界
115
+
116
+ 数据库不保存用户消息、助手消息、推理内容、完整 shell 命令或工具输出。只保存:
117
+
118
+ - Skill 名称、规范化路径和作用域;
119
+ - 线程 ID、轮次 ID、时间戳和当时的工作目录;
120
+ - 证据类型、源 JSONL 路径和行号;
121
+ - 增量读取的文件偏移量。
122
+
123
+ rollout 是 Codex 的本地内部格式,不是公开稳定 API。解析器对未知事件采取跳过策略,并通过
124
+ 源文件偏移量和稳定事件 ID 保证重复同步不会重复计数。
125
+
126
+ 为保证处理超大历史文件时内存有明确上限,单条 JSONL 记录最多读取 16 MiB;超过上限的记录
127
+ 会跳过并单独计入 `oversized_lines`,不会混入 `malformed_lines`。Skill 工具调用记录通常远小于
128
+ 该上限,但被跳过的记录不会声称已经覆盖。
package/npm/cli.mjs ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn, spawnSync } from "node:child_process";
4
+ import { existsSync } from "node:fs";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
9
+ const localPython = process.platform === "win32"
10
+ ? path.join(packageRoot, ".venv", "Scripts", "python.exe")
11
+ : path.join(packageRoot, ".venv", "bin", "python");
12
+
13
+ const candidates = [];
14
+ if (process.env.CSA_PYTHON) {
15
+ candidates.push({ command: process.env.CSA_PYTHON, prefix: [] });
16
+ }
17
+ if (existsSync(localPython)) {
18
+ candidates.push({ command: localPython, prefix: [] });
19
+ }
20
+ for (const command of ["python3.13", "python3.12", "python3.11", "python3"]) {
21
+ candidates.push({ command, prefix: [] });
22
+ }
23
+ if (process.platform === "win32") {
24
+ for (const version of ["-3.13", "-3.12", "-3.11"]) {
25
+ candidates.push({ command: "py", prefix: [version] });
26
+ }
27
+ candidates.push({ command: "python", prefix: [] });
28
+ }
29
+
30
+ const versionCheck = "import sys; raise SystemExit(sys.version_info < (3, 11))";
31
+ const python = candidates.find(({ command, prefix }) => {
32
+ const result = spawnSync(command, [...prefix, "-c", versionCheck], { stdio: "ignore" });
33
+ return result.status === 0;
34
+ });
35
+
36
+ if (!python) {
37
+ console.error("Codex Skill Analytics 需要 Python 3.11 或更高版本。");
38
+ console.error("安装新版 Python,或设置 CSA_PYTHON=/path/to/python 后重试。");
39
+ process.exit(1);
40
+ }
41
+
42
+ const environment = {
43
+ ...process.env,
44
+ PYTHONPATH: [path.join(packageRoot, "src"), process.env.PYTHONPATH]
45
+ .filter(Boolean)
46
+ .join(path.delimiter),
47
+ };
48
+
49
+ function pythonArgs(cliArgs) {
50
+ return [...python.prefix, "-m", "codex_skill_analytics.cli", ...cliArgs];
51
+ }
52
+
53
+ function runSync(cliArgs) {
54
+ return spawnSync(python.command, pythonArgs(cliArgs), {
55
+ env: environment,
56
+ stdio: "inherit",
57
+ });
58
+ }
59
+
60
+ function runInteractive(cliArgs) {
61
+ const child = spawn(python.command, pythonArgs(cliArgs), {
62
+ env: environment,
63
+ stdio: "inherit",
64
+ });
65
+ child.on("error", (error) => {
66
+ console.error(`启动失败:${error.message}`);
67
+ process.exitCode = 1;
68
+ });
69
+ child.on("exit", (code, signal) => {
70
+ if (signal) {
71
+ process.kill(process.pid, signal);
72
+ return;
73
+ }
74
+ process.exitCode = code ?? 1;
75
+ });
76
+ }
77
+
78
+ const args = process.argv.slice(2);
79
+ if (args.length === 0) {
80
+ console.log("正在增量同步本机 Codex Skill 调用历史…");
81
+ const syncResult = runSync(["sync"]);
82
+ if (syncResult.status !== 0) {
83
+ process.exit(syncResult.status ?? 1);
84
+ }
85
+ console.log("正在打开 Codex Skill Analytics…");
86
+ runInteractive(["serve", "--open"]);
87
+ } else {
88
+ runInteractive(args);
89
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "codex-skill-analytics",
3
+ "version": "0.1.0",
4
+ "description": "Local, deterministic CLI and Web analytics for Codex Skill usage",
5
+ "type": "module",
6
+ "bin": {
7
+ "codex-skill-analytics": "npm/cli.mjs",
8
+ "csa": "npm/cli.mjs"
9
+ },
10
+ "files": [
11
+ "npm/",
12
+ "src/codex_skill_analytics/*.py",
13
+ "README.md",
14
+ "DESIGN.md",
15
+ "PRODUCT.md"
16
+ ],
17
+ "scripts": {
18
+ "test": "node --check npm/cli.mjs",
19
+ "prepack": "npm test"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/NauJson/codex-skill-analytics.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/NauJson/codex-skill-analytics/issues"
30
+ },
31
+ "homepage": "https://github.com/NauJson/codex-skill-analytics#readme",
32
+ "keywords": [
33
+ "codex",
34
+ "skills",
35
+ "analytics",
36
+ "sqlite",
37
+ "cli"
38
+ ],
39
+ "license": "UNLICENSED",
40
+ "publishConfig": {
41
+ "access": "public"
42
+ }
43
+ }
@@ -0,0 +1,4 @@
1
+ """Local, deterministic Codex Skill analytics."""
2
+
3
+ __version__ = "0.1.0"
4
+