file-brief 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zhiyi-Zhao
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,611 @@
1
+ # file-brief
2
+
3
+ [中文](#中文) · [English](#english)
4
+
5
+ `file-brief` is an agent-agnostic skill (OpenAI Codex · Claude Code · DeepSeek Harness) that turns repeated input-file inspection into reusable, task-local documentation.
6
+
7
+ ---
8
+
9
+ ## 中文
10
+
11
+ ### 为什么发布这个仓库
12
+
13
+ 当 Agent 开始数据分析、代码生成、文件转换或任何涉及本地文件的工程任务时,往往会先重复执行同一批检查:
14
+
15
+ - 文件是什么格式?
16
+ - 表格有多少列,各列是什么类型?
17
+ - JSON、YAML 或嵌套对象如何组织?
18
+ - Excel 有哪些工作表?SQLite 有哪些表和视图?
19
+ - 压缩包里有什么?XML/HTML 有哪些标签结构?
20
+ - 哪些字段存在缺失?文件是否已经变化?
21
+
22
+ 这些检查本身很有必要,但如果每个会话、每个 Agent 都重新执行,会产生三个问题:
23
+
24
+ 1. **浪费时间和上下文**:相同输入文件被反复读取,真正用于解决任务的上下文反而减少。
25
+ 2. **污染正式代码**:临时的 `head()`、`str()`、`read_csv()`、字段打印和调试逻辑容易留在最终脚本中。
26
+ 3. **难以复用知识**:即使同一文件在另一个任务或会话中再次使用,之前发现的数据结构通常没有被保存。
27
+
28
+ 这个仓库发布 `file-brief` 技能,把上述检查集中为一个可复用的预检层。技能为每个大型任务维护独立的 `.file-catalog`,生成简洁的 Markdown 说明和 SQLite 检索索引。后续 Agent 可以先读取说明,只在文件新增或变化时重新解析。
29
+
30
+ 技能本身与具体 Agent 平台无关:任何能执行 Python 命令的 Agent(OpenAI Codex、Claude Code、DeepSeek Harness 等)都可以按同一工作流使用。
31
+
32
+ ### 支持的平台与安装
33
+
34
+ | 平台 | 安装位置 | 说明 |
35
+ |---|---|---|
36
+ | OpenAI Codex | `<CODEX_HOME 或 ~/.codex>/skills/file-brief` | 原生 skill 机制 |
37
+ | Claude Code | `~/.claude/skills/file-brief` | 原生 Agent Skills 机制 |
38
+ | DeepSeek Harness | `~/.dsh/skills/` 或 `~/.agents/skills/`(也可用项目内 `.dsh/skills`、`.agents/skills`) | 自动发现 `SKILL.md` |
39
+
40
+ 一键安装(在仓库根目录):
41
+
42
+ ```powershell
43
+ # Windows PowerShell:安装到全部平台
44
+ powershell -ExecutionPolicy Bypass -File .\install.ps1
45
+ # 或指定平台:.\install.ps1 -Target codex,claude,dsh,agents
46
+ ```
47
+
48
+ ```bash
49
+ # macOS/Linux:安装到全部平台
50
+ ./install.sh
51
+ # 或指定平台:./install.sh codex claude dsh
52
+ ```
53
+
54
+ 也可以手动复制:
55
+
56
+ ```powershell
57
+ # Windows:DeepSeek Harness
58
+ Copy-Item -LiteralPath ".\skills\file-brief" -Destination "$HOME\.dsh\skills\file-brief" -Recurse
59
+ ```
60
+
61
+ ```bash
62
+ # macOS/Linux:Claude Code
63
+ mkdir -p ~/.claude/skills && cp -R skills/file-brief ~/.claude/skills/
64
+ ```
65
+
66
+ 安装后请启动一个新的 Agent 会话,使技能列表重新加载。
67
+
68
+ ### 为什么每个任务拥有自己的目录
69
+
70
+ 解释文档保存在 `<task-root>/.file-catalog`,而不是任何 Agent 的全局目录,原因是:
71
+
72
+ - 数据说明与对应任务一起移动、备份和归档。
73
+ - 不同任务不会互相污染索引。
74
+ - 任务内相对路径保持稳定,整个项目目录移动后仍能匹配。
75
+ - Markdown 说明可以选择性纳入版本控制。
76
+ - SQLite、锁文件和临时文件默认被 `.file-catalog/.gitignore` 排除。
77
+
78
+ ### 隐私设计
79
+
80
+ 技能的目标是保存“结构知识”,不是复制数据。生成的说明允许包含:
81
+
82
+ - 文件名、格式、大小、修改时间和 SHA-256;
83
+ - 字段名、键名、工作表名、表名、视图名、函数名、类名、压缩包成员名和对象名;
84
+ - 类型、维度、缺失量、样本内近似唯一值数量;
85
+ - PDF 页数、图片尺寸、文档结构计数、XML/HTML 标签计数、归档成员统计。
86
+
87
+ 说明不会保存:
88
+
89
+ - 原始数据行、单元格样例或数据库单元格值;
90
+ - 正文段落、源代码片段或 notebook 单元格内容;
91
+ - 类别的实际值或高频值;
92
+ - 图片像素、PDF 正文、压缩包成员内容。
93
+
94
+ 解析器可能在内存中读取有界样本以推断结构,但不会把样本值写入目录。
95
+
96
+ ### 一个面向未来的问题
97
+
98
+ > 未来是否会出现一种专供 AI 阅读的新文件格式,将文件内容说明、数据结构、字段语义、来源和更新状态直接整合到文件本身,从而让这些信息能够随文件在不同 Agent、工具和平台之间传播,而无需每次重新解析?
99
+
100
+ ### 支持的文件
101
+
102
+ | 类别 | 格式 | 说明 |
103
+ |---|---|---|
104
+ | 分隔表格 | CSV、TSV、TAB 及分号/竖线分隔变体 | 自动探测分隔符;采样字段类型、缺失率和近似唯一值数量 |
105
+ | 工作簿 | XLSX、XLS、XLSM、ODS | 工作表、字段和每表有界样本结构 |
106
+ | 列式数据 | Parquet、Feather、Arrow IPC | 使用元数据读取字段、行组和记录批次 |
107
+ | 数据库 | SQLite(.db/.sqlite/.sqlite3) | 只读方式列出表、视图、索引、列声明类型和行数 |
108
+ | 结构化文本 | JSON、JSONL、NDJSON、YAML、TOML | 键、嵌套层级和元素类型 |
109
+ | 归档 | ZIP/JAR/WAR/APK、TAR/TGZ/TBZ2/TXZ、GZIP | 成员清单、类型直方图和压缩统计,不读取成员内容 |
110
+ | 标记文档 | XML/XSD/SVG/KML/GPX、HTML | 标签计数、属性键、命名空间、标题/表格/链接结构 |
111
+ | Notebook | Jupyter(.ipynb) | 单元格类型分布、执行状态、内核语言,不保存单元格内容 |
112
+ | 统计软件 | Stata(.dta) | 变量名、类型与有界样本结构 |
113
+ | R 数据 | RDS、RDA、RData | 对象、类、维度、列、列表成员和缺失量 |
114
+ | 代码与文本 | Python、R、JS/TS、Java、Go、Rust、C/C++、C#、Ruby、PHP、Kotlin、Swift、Scala、Julia、Lua、Perl、Dart、Elixir、Haskell、Erlang、F#、VB、Shell、PowerShell、Markdown 及常见文本 | 编码、行数、声明、导入和标题结构 |
115
+ | 文档与媒体 | PDF、DOCX、常见图片 | 页面、段落、表格、尺寸和元数据键 |
116
+ | 其他 | 未知文本或二进制 | 至少生成 MIME 类型和基础元数据说明 |
117
+
118
+ 解析库缺失或文件无法深度读取时,技能会生成带有 `unsupported` 或 `error` 状态的通用说明,而不是静默失败。
119
+
120
+ ### 环境要求
121
+
122
+ - Python 3.9 或更高版本。
123
+ - 核心索引、SQLite/归档/XML/HTML/notebook 解析和大多数源代码分析只依赖标准库。
124
+ - 完整格式支持建议安装:
125
+
126
+ ```bash
127
+ python -m pip install pandas openpyxl pyarrow PyYAML pypdf Pillow tomli
128
+ ```
129
+
130
+ - RDS/RData 深度解析需要:
131
+ - `Rscript`;
132
+ - R 包 `jsonlite`。
133
+
134
+ Rscript 的发现顺序是:
135
+
136
+ 1. 环境变量 `R_SCRIPT_EXE`;
137
+ 2. 系统 `PATH` 中的 `Rscript`;
138
+ 3. Windows 常见 R 安装目录。
139
+
140
+ ### 使用(与语言和平台无关)
141
+
142
+ 以下示例中的 `<skill-dir>` 是已安装的 `file-brief` 技能目录。任何任务——数据分析、Web 项目、配置管线、迁移脚本——都遵循同一工作流。
143
+
144
+ #### 选择任务根目录
145
+
146
+ `--task-root` 应指向包含当前大型任务全部输入、脚本和输出的最高合理目录。
147
+
148
+ - 优先使用用户明确指定的任务目录。
149
+ - 未指定时使用当前工作目录。
150
+ - 不自动向上搜索 Git 根目录。
151
+ - 所有待建档文件必须位于任务根目录内。
152
+
153
+ #### 首次建档
154
+
155
+ ```bash
156
+ python "<skill-dir>/scripts/file_catalog.py" catalog --task-root "/work/my-task"
157
+ ```
158
+
159
+ 不提供具体文件时会递归处理整个任务目录,并跳过 `.git`、`.file-catalog`、依赖目录、虚拟环境和缓存目录。
160
+
161
+ #### 开始任务前查询
162
+
163
+ ```bash
164
+ python "<skill-dir>/scripts/file_catalog.py" lookup \
165
+ --task-root "/work/my-task" \
166
+ "data/observations.csv"
167
+ ```
168
+
169
+ 如果返回 `fresh`,Agent 应优先读取返回的 Markdown 文档,而不是再次探查源文件。需要机器可读输出时追加 `--json`。
170
+
171
+ #### 刷新增或变化的文件
172
+
173
+ ```bash
174
+ python "<skill-dir>/scripts/file_catalog.py" catalog \
175
+ --task-root "/work/my-task" \
176
+ "data/observations.csv"
177
+ ```
178
+
179
+ 技能先比较文件大小和高精度修改时间;只有缺失或变化(或解析器版本升级)的条目才重新计算 SHA-256 并解析。
180
+
181
+ #### 跨子目录搜索与目录概览
182
+
183
+ ```bash
184
+ python "<skill-dir>/scripts/file_catalog.py" search \
185
+ --task-root "/work/my-task" \
186
+ "species"
187
+
188
+ python "<skill-dir>/scripts/file_catalog.py" info \
189
+ --task-root "/work/my-task"
190
+ ```
191
+
192
+ 搜索范围包括相对路径、文件名、格式、摘要、字段名、键名和其他结构标识符。`info` 输出按状态和格式的条目统计。跳过不需要的目录或文件:`--exclude "cache,tmp.sqlite"`。
193
+
194
+ ### `.file-catalog` 的结构
195
+
196
+ ```text
197
+ <task-root>/
198
+ └── .file-catalog/
199
+ ├── INDEX.md
200
+ ├── documents/
201
+ │ └── <relative-path-hash>.md
202
+ ├── catalog.sqlite3
203
+ └── .gitignore
204
+ ```
205
+
206
+ - `INDEX.md`:适合人工浏览的紧凑索引。
207
+ - `documents/`:每个任务相对路径对应一份当前说明。
208
+ - `catalog.sqlite3`:供 `lookup` 和 `search` 使用的机器索引。
209
+ - `.gitignore`:只排除 SQLite、锁和临时文件,Markdown 可以提交。
210
+
211
+ ### 状态含义
212
+
213
+ | 状态 | 含义 | 推荐动作 |
214
+ |---|---|---|
215
+ | `fresh` | 说明存在且文件大小/修改时间一致 | 直接读取说明 |
216
+ | `stale` | 源文件自上次解析后发生变化 | 运行 `catalog` 刷新 |
217
+ | `missing` | 文件或说明不存在 | 检查路径;存在源文件时运行 `catalog` |
218
+ | `unsupported` | 没有深度解析器,但已有通用元数据 | 使用现有说明,必要时人工检查 |
219
+ | `error` | 深度解析失败,并已生成降级说明 | 阅读警告,修复依赖或文件问题后刷新 |
220
+
221
+ ### 示例结果
222
+
223
+ SQLite 说明只保留表结构,不读取单元格值:
224
+
225
+ ```json
226
+ {
227
+ "table_count": 2,
228
+ "tables": [
229
+ {"name": "measurements", "column_count": 3, "row_count": 1250,
230
+ "columns": [
231
+ {"name": "species", "declared_type": "TEXT", "notnull": true}
232
+ ]}
233
+ ]
234
+ }
235
+ ```
236
+
237
+ ZIP 归档说明列出成员与类型直方图,不读取成员内容:
238
+
239
+ ```json
240
+ {
241
+ "member_count": 42,
242
+ "member_names": ["data/a.csv", "data/b.csv", "README.md"],
243
+ "extension_histogram": [{"extension": ".csv", "count": 2}]
244
+ }
245
+ ```
246
+
247
+ CSV 说明自动记录探测到的分隔符:
248
+
249
+ ```json
250
+ {
251
+ "delimiter": ";",
252
+ "column_count": 3,
253
+ "columns": [{"name": "species", "dtype": "object", "missing_percent_in_sample": 1.2}]
254
+ }
255
+ ```
256
+
257
+ 这些示例是结构示意,不包含真实输入数据。
258
+
259
+ ### 推荐工作流
260
+
261
+ ```text
262
+ 确定 task root
263
+ → lookup 输入文件
264
+ → fresh:读取说明
265
+ → missing/stale:catalog 后读取说明
266
+ → 只有说明不足时才检查原文件
267
+ → 将实际业务逻辑写入正式代码
268
+ ```
269
+
270
+ 不要把一次性的字段打印、样本输出和格式探测重新写入生产脚本。
271
+
272
+ ### 本版本改进与下一步方向
273
+
274
+ v2 已实现:
275
+
276
+ - **平台无关化**:同一 `SKILL.md` 同时适配 OpenAI Codex、Claude Code 与 DeepSeek Harness;提供 `install.ps1` / `install.sh` 一键安装。
277
+ - **格式覆盖扩展**:SQLite、ZIP/JAR/APK、TAR/TGZ、GZIP、XML、HTML、Jupyter notebook、Stata,全部仅依赖标准库(Stata 除外)。
278
+ - **通用化**:CSV/TSV 自动探测分隔符;20+ 编程语言的表驱动结构提取;工作流与语言/技术栈无关。
279
+ - **工程改进**:`--json` 机器可读输出、`info` 子命令、`--exclude` 排除项、并行解析(有界线程池)、解析器版本化(升级后自动重新解析旧条目)、搜索通配符转义。
280
+
281
+ 未来方向(欢迎贡献):
282
+
283
+ - 数据格式侧:HDF5/NetCDF、SAS/SPSS、地理空间(GeoJSON/Shapefile)深度解析。
284
+ - 结构侧:目录级聚合说明(一个文档描述整个子目录树);跨任务全局索引。
285
+ - 语义侧:可选 LLM 摘要层,用模型生成字段语义(仍不写入原始值)。
286
+ - 格式侧:尝试为“AI 原生文件格式”提供预检支持。
287
+
288
+ ### 常见问题
289
+
290
+ **为什么没有精确统计 CSV 总行数?**
291
+ 默认使用有界样本,以避免为结构说明完整扫描超大文本表格。文档会明确标注采样范围。
292
+
293
+ **为什么某个 Excel 文件显示 `error`?**
294
+ 旧式 XLS 或特殊工作簿可能需要额外解析库。安装对应 pandas 引擎后重新运行 `catalog`。
295
+
296
+ **为什么 TOML 降级?**
297
+ Python 3.11+ 内置 `tomllib`;Python 3.9/3.10 需要安装 `tomli`。
298
+
299
+ **为什么 R 数据无法解析?**
300
+ 确认 `Rscript` 可用,并运行 `Rscript -e "install.packages('jsonlite')"`。也可以设置 `R_SCRIPT_EXE` 为可执行文件路径。
301
+
302
+ **SQLite 说明会读取我的数据吗?**
303
+ 不会。SQLite 解析以只读 URI 打开数据库并启用 `query_only`,只读取 `sqlite_master` 的 schema 信息和行数,不读取任何单元格值。
304
+
305
+ **可以提交 `.file-catalog` 吗?**
306
+ 可以提交 `INDEX.md` 和 `documents/`。SQLite 和临时文件默认被目录内 `.gitignore` 排除。
307
+
308
+ **会不会把隐私数据写入说明?**
309
+ 设计上不会保存原始行、单元格、正文、归档成员内容或类别值。对于高度敏感的数据,仍建议在提交生成的 Markdown 前进行组织自己的安全审查。
310
+
311
+ ---
312
+
313
+ ## English
314
+
315
+ ### Why this repository exists
316
+
317
+ Before an agent can analyze data, generate code, transform files, or work on any local-file engineering task, it usually repeats the same discovery work:
318
+
319
+ - What format is this file?
320
+ - Which columns exist, and what are their types?
321
+ - How are JSON, YAML, or nested objects organized?
322
+ - Which worksheets, tables, and views are present?
323
+ - What is inside an archive? Which tags does an XML/HTML document use?
324
+ - Where are values missing?
325
+ - Has the file changed since the previous task?
326
+
327
+ Those checks are necessary, but repeating them in every session creates three problems:
328
+
329
+ 1. **Time and context are wasted.** The same inputs are reopened while less context remains for the actual task.
330
+ 2. **Production code becomes noisy.** Temporary `head()`, `str()`, `read_csv()`, schema prints, and debugging logic leak into final scripts.
331
+ 3. **Knowledge is not reusable.** A later agent or session usually has to rediscover the same structure.
332
+
333
+ This repository publishes the `file-brief` skill as a reusable preflight layer. Each large task receives its own `.file-catalog` with concise Markdown explanations and a SQLite search index. Later agents can reuse those explanations and reparse only files that are new or stale.
334
+
335
+ The skill is agent-platform agnostic: any agent that can execute Python commands — OpenAI Codex, Claude Code, DeepSeek Harness, and others — uses the same workflow.
336
+
337
+ ### Supported platforms and installation
338
+
339
+ | Platform | Install location | Notes |
340
+ |---|---|---|
341
+ | OpenAI Codex | `<CODEX_HOME or ~/.codex>/skills/file-brief` | Native skill mechanism |
342
+ | Claude Code | `~/.claude/skills/file-brief` | Native Agent Skills mechanism |
343
+ | DeepSeek Harness | `~/.dsh/skills/` or `~/.agents/skills/` (project `.dsh/skills` and `.agents/skills` also work) | Auto-discovers `SKILL.md` |
344
+
345
+ One-shot install (from the repository root):
346
+
347
+ ```powershell
348
+ # Windows PowerShell: install to every platform
349
+ powershell -ExecutionPolicy Bypass -File .\install.ps1
350
+ # or select targets: .\install.ps1 -Target codex,claude,dsh,agents
351
+ ```
352
+
353
+ ```bash
354
+ # macOS/Linux: install to every platform
355
+ ./install.sh
356
+ # or select targets: ./install.sh codex claude dsh
357
+ ```
358
+
359
+ Manual copy also works:
360
+
361
+ ```bash
362
+ # macOS/Linux: Claude Code
363
+ mkdir -p ~/.claude/skills && cp -R skills/file-brief ~/.claude/skills/
364
+ ```
365
+
366
+ Start a new agent session after installation so the skill list reloads.
367
+
368
+ ### Why catalogs are task-local
369
+
370
+ Generated documentation lives under `<task-root>/.file-catalog`, not in any agent-global directory:
371
+
372
+ - Explanations move, archive, and back up with the task.
373
+ - Independent tasks cannot contaminate one another's indexes.
374
+ - Task-relative paths remain stable when the whole directory moves.
375
+ - Markdown explanations can be version-controlled when useful.
376
+ - SQLite, locks, and temporary files are ignored by the generated `.gitignore`.
377
+
378
+ ### Privacy model
379
+
380
+ The skill stores structural knowledge, not a copy of the data. Explanations may contain:
381
+
382
+ - file names, formats, sizes, timestamps, and SHA-256 hashes;
383
+ - column, key, worksheet, table, view, function, class, archive-member, and object names;
384
+ - types, dimensions, missing counts, and approximate distinct counts within a sample;
385
+ - PDF page counts, image dimensions, document structure counts, XML/HTML tag counts, and archive member statistics.
386
+
387
+ They intentionally omit:
388
+
389
+ - raw rows, cell samples, and database cell values;
390
+ - paragraph excerpts, source-code snippets, and notebook cell contents;
391
+ - actual category values and frequency lists;
392
+ - image pixels, PDF text, and archive member contents.
393
+
394
+ Parsers may inspect a bounded in-memory sample to infer structure, but sample values are not written to the catalog.
395
+
396
+ ### A question for the future
397
+
398
+ > Will a new file format emerge specifically for AI consumption—one that embeds content descriptions, data structures, field semantics, provenance, and update status directly into the file itself, allowing this knowledge to travel with the file across agents, tools, and platforms without being re-derived each time?
399
+
400
+ ### Supported files
401
+
402
+ | Category | Formats | Structural information |
403
+ |---|---|---|
404
+ | Delimited tables | CSV, TSV, TAB and semicolon/pipe variants | Automatic delimiter detection; sampled types, missing rates, and approximate distinct counts |
405
+ | Workbooks | XLSX, XLS, XLSM, ODS | Worksheets, fields, and bounded per-sheet samples |
406
+ | Columnar data | Parquet, Feather, Arrow IPC | Schema, row groups, and record batches from metadata |
407
+ | Databases | SQLite (.db/.sqlite/.sqlite3) | Read-only tables, views, indexes, declared column types, and row counts |
408
+ | Structured text | JSON, JSONL, NDJSON, YAML, TOML | Keys, nesting, and element types |
409
+ | Archives | ZIP/JAR/WAR/APK, TAR/TGZ/TBZ2/TXZ, GZIP | Member lists, type histograms, and compression stats; contents never read |
410
+ | Markup documents | XML/XSD/SVG/KML/GPX, HTML | Tag counts, attribute keys, namespaces, heading/table/link structure |
411
+ | Notebooks | Jupyter (.ipynb) | Cell-type distribution, execution state, kernel language; cell contents never stored |
412
+ | Statistical software | Stata (.dta) | Variable names, types, and bounded sample structure |
413
+ | R data | RDS, RDA, RData | Objects, classes, dimensions, columns, members, and missing counts |
414
+ | Code and text | Python, R, JS/TS, Java, Go, Rust, C/C++, C#, Ruby, PHP, Kotlin, Swift, Scala, Julia, Lua, Perl, Dart, Elixir, Haskell, Erlang, F#, VB, Shell, PowerShell, Markdown, common text | Encoding, lines, declarations, imports, and headings |
415
+ | Documents and media | PDF, DOCX, common images | Pages, paragraphs, tables, dimensions, and metadata keys |
416
+ | Other | Unknown text or binary | MIME type and generic file metadata |
417
+
418
+ When an optional parser is unavailable, the skill produces a useful `unsupported` or `error` explanation with explicit warnings.
419
+
420
+ ### Requirements
421
+
422
+ - Python 3.9 or newer.
423
+ - Core indexing, SQLite/archive/XML/HTML/notebook parsing, and most source analysis use the standard library only.
424
+ - For full format coverage, install:
425
+
426
+ ```bash
427
+ python -m pip install pandas openpyxl pyarrow PyYAML pypdf Pillow tomli
428
+ ```
429
+
430
+ - Deep RDS/RData inspection requires `Rscript` and the R package `jsonlite`.
431
+
432
+ Rscript is resolved from:
433
+
434
+ 1. `R_SCRIPT_EXE`;
435
+ 2. `Rscript` on `PATH`;
436
+ 3. common Windows R installation directories.
437
+
438
+ ### Usage (language- and platform-agnostic)
439
+
440
+ `<skill-dir>` below means the installed `file-brief` skill directory. Any task — data analysis, a web project, a config pipeline, a migration script — follows the same workflow.
441
+
442
+ #### Choose a task root
443
+
444
+ `--task-root` should be the highest sensible directory that contains the inputs, scripts, and outputs for one large task.
445
+
446
+ - Prefer a root explicitly provided by the user.
447
+ - Otherwise use the current working directory.
448
+ - Do not infer a Git root.
449
+ - Every cataloged path must remain inside the task root.
450
+
451
+ #### Create the first catalog
452
+
453
+ ```bash
454
+ python "<skill-dir>/scripts/file_catalog.py" catalog --task-root "/work/my-task"
455
+ ```
456
+
457
+ With no explicit path, `catalog` recursively processes the task while excluding `.git`, `.file-catalog`, dependency folders, virtual environments, and caches.
458
+
459
+ #### Look up an input before starting work
460
+
461
+ ```bash
462
+ python "<skill-dir>/scripts/file_catalog.py" lookup \
463
+ --task-root "/work/my-task" \
464
+ "data/observations.csv"
465
+ ```
466
+
467
+ When the result is `fresh`, read the returned Markdown explanation instead of probing the source again. Append `--json` for machine-readable output.
468
+
469
+ #### Refresh a new or changed file
470
+
471
+ ```bash
472
+ python "<skill-dir>/scripts/file_catalog.py" catalog \
473
+ --task-root "/work/my-task" \
474
+ "data/observations.csv"
475
+ ```
476
+
477
+ The skill first compares file size and high-resolution modification time. It recalculates SHA-256 and reparses only missing or changed (or parser-version-upgraded) entries.
478
+
479
+ #### Search across subdirectories and inspect the catalog
480
+
481
+ ```bash
482
+ python "<skill-dir>/scripts/file_catalog.py" search \
483
+ --task-root "/work/my-task" \
484
+ "species"
485
+
486
+ python "<skill-dir>/scripts/file_catalog.py" info \
487
+ --task-root "/work/my-task"
488
+ ```
489
+
490
+ Search covers relative paths, file names, formats, summaries, fields, keys, and other structural identifiers. `info` summarizes entries by status and format. Skip unwanted names with `--exclude "cache,tmp.sqlite"`.
491
+
492
+ ### `.file-catalog` layout
493
+
494
+ ```text
495
+ <task-root>/
496
+ └── .file-catalog/
497
+ ├── INDEX.md
498
+ ├── documents/
499
+ │ └── <relative-path-hash>.md
500
+ ├── catalog.sqlite3
501
+ └── .gitignore
502
+ ```
503
+
504
+ - `INDEX.md`: compact index for human browsing.
505
+ - `documents/`: one current explanation per task-relative path.
506
+ - `catalog.sqlite3`: machine index used by `lookup` and `search`.
507
+ - `.gitignore`: ignores SQLite, locks, and temporary files while leaving Markdown trackable.
508
+
509
+ ### Status reference
510
+
511
+ | Status | Meaning | Recommended action |
512
+ |---|---|---|
513
+ | `fresh` | Explanation exists and size/mtime still match | Read the explanation |
514
+ | `stale` | Source changed after the last analysis | Run `catalog` |
515
+ | `missing` | Source or explanation is absent | Check the path, then catalog an existing source |
516
+ | `unsupported` | No deep parser matched, but generic metadata exists | Use the metadata or inspect manually if required |
517
+ | `error` | Deep parsing failed and a fallback explanation was produced | Read the warning, fix dependencies or the file, then refresh |
518
+
519
+ ### Example structures
520
+
521
+ A SQLite explanation records table shape only, never cell values:
522
+
523
+ ```json
524
+ {
525
+ "table_count": 2,
526
+ "tables": [
527
+ {"name": "measurements", "column_count": 3, "row_count": 1250,
528
+ "columns": [
529
+ {"name": "species", "declared_type": "TEXT", "notnull": true}
530
+ ]}
531
+ ]
532
+ }
533
+ ```
534
+
535
+ A ZIP explanation lists members and a type histogram without reading contents:
536
+
537
+ ```json
538
+ {
539
+ "member_count": 42,
540
+ "member_names": ["data/a.csv", "data/b.csv", "README.md"],
541
+ "extension_histogram": [{"extension": ".csv", "count": 2}]
542
+ }
543
+ ```
544
+
545
+ A CSV explanation records the detected delimiter:
546
+
547
+ ```json
548
+ {
549
+ "delimiter": ";",
550
+ "column_count": 3,
551
+ "columns": [{"name": "species", "dtype": "object", "missing_percent_in_sample": 1.2}]
552
+ }
553
+ ```
554
+
555
+ These are structural illustrations, not real input records.
556
+
557
+ ### Recommended workflow
558
+
559
+ ```text
560
+ Choose task root
561
+ → lookup the inputs
562
+ → fresh: read explanations
563
+ → missing/stale: catalog, then read explanations
564
+ → inspect raw sources only if the explanations are insufficient
565
+ → keep production code focused on the actual task
566
+ ```
567
+
568
+ Do not reintroduce one-off schema prints, sample dumps, or format probes into production scripts.
569
+
570
+ ### What changed in v2 and where it is heading
571
+
572
+ Implemented in v2:
573
+
574
+ - **Platform-neutral**: one `SKILL.md` works with OpenAI Codex, Claude Code, and DeepSeek Harness; `install.ps1` / `install.sh` provide one-shot installation.
575
+ - **Wider format coverage**: SQLite, ZIP/JAR/APK, TAR/TGZ, GZIP, XML, HTML, Jupyter notebooks, Stata — all standard-library-only except Stata.
576
+ - **Generalization**: automatic delimiter detection for delimited tables; table-driven structural extraction for 20+ programming languages; the workflow is independent of language or tech stack.
577
+ - **Engineering**: `--json` machine-readable output, `info` subcommand, `--exclude` scan filters, bounded parallel parsing, parser versioning (upgrades re-analyze old entries), and search wildcard escaping.
578
+
579
+ Future directions (contributions welcome):
580
+
581
+ - Data formats: HDF5/NetCDF, SAS/SPSS, geospatial (GeoJSON/Shapefile) deep parsing.
582
+ - Structure: directory-level aggregate explanations; a cross-task global index.
583
+ - Semantics: an optional LLM summary layer that derives field semantics without storing raw values.
584
+ - Formats: preflight support for emerging AI-native file formats.
585
+
586
+ ### Troubleshooting and FAQ
587
+
588
+ **Why is the exact CSV row count missing?**
589
+ Delimited files use bounded sampling by default so a structural preflight does not fully scan a very large text table. The explanation records the sampling scope.
590
+
591
+ **Why does an Excel file report `error`?**
592
+ Legacy XLS files or specialized workbooks may require an additional pandas engine. Install the relevant engine and rerun `catalog`.
593
+
594
+ **Why did TOML fall back?**
595
+ Python 3.11+ includes `tomllib`; Python 3.9/3.10 require `tomli`.
596
+
597
+ **Why does R data inspection fail?**
598
+ Confirm that `Rscript` is available and run `Rscript -e "install.packages('jsonlite')"`. You may also set `R_SCRIPT_EXE` to the executable path.
599
+
600
+ **Does the SQLite analysis read my data?**
601
+ No. SQLite is opened read-only with `query_only` enabled; only `sqlite_master` schema objects and row counts are read, never cell values.
602
+
603
+ **Can `.file-catalog` be committed?**
604
+ Yes. Commit `INDEX.md` and `documents/` when useful. SQLite and temporary files are ignored by the generated `.gitignore`.
605
+
606
+ **Can private values leak into explanations?**
607
+ The implementation intentionally omits rows, cells, paragraph text, archive member contents, category values, and code snippets. Organizations handling highly sensitive data should still review generated Markdown before publishing it.
608
+
609
+ ## License
610
+
611
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,9 @@
1
+ # file-brief is a skill-type plugin: its functionality ships as a
2
+ # SKILL.md bundle that agents load from a skill root (~/.dsh/skills,
3
+ # ~/.agents/skills, ~/.claude/skills, or a Codex skills directory).
4
+ #
5
+ # The bundle patch layer is therefore intentionally empty: enabling this
6
+ # bundle must not alter the profile's plugin rows. Install the skill itself
7
+ # with install.ps1 / install.sh or by copying skills/file-brief into
8
+ # a skill root.
9
+ []