Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
05ff594
docs(v2): freeze the dot-skill v2 contract before parallel work
titanwings Sep 12, 2026
d58a474
test(v2): add the acceptance corpus fixture and its licence note
titanwings Sep 12, 2026
b5b5c5f
docs(v2): write the acceptance protocol (holdout, three blind roles, …
titanwings Sep 12, 2026
8db01a0
test(v2): add the recorded view template for the acceptance corpus
titanwings Sep 12, 2026
7eed33a
test(v2): add the end-to-end acceptance harness
titanwings Sep 12, 2026
d912455
docs(v2): track which branch delivers what and how to verify it
titanwings Sep 12, 2026
d1a5c65
docs(v2): correct the fixture cue count in the corpus notes
titanwings Sep 12, 2026
b8307c1
feat(v2): add the coding-agent support matrix as shared host data
titanwings Sep 12, 2026
dba29b7
docs(v2): note that the host matrix ships from the integration branch
titanwings Sep 12, 2026
42f7e1b
docs(v2): split keys from schema and add the release task
titanwings Sep 12, 2026
e1fda41
docs(v2): add the Python-to-Node migration ledger
titanwings Sep 12, 2026
402b378
docs(v2): record that the acceptance harness passes against a referen…
titanwings Sep 12, 2026
52d4050
fix(v2): verify every AgentSkills cliId against the upstream registry
titanwings Sep 12, 2026
161e5ef
wip(recovery): 从会话记录重建的文件(第一次检查点)
titanwings Sep 15, 2026
05e8826
wip(recovery): 把 read 观测与 bash heredoc 并入时间线重建
titanwings Sep 15, 2026
9d4d49f
wip(recovery): 候选版本择优 + 重建损伤归一化
titanwings Sep 15, 2026
6c2a64c
wip(recovery): 修掉误判截断的过滤器,补回被重建覆盖的导出
titanwings Sep 15, 2026
5e2b5aa
wip(recovery): 补回四个缺失导出(payloadEntries / anchorProblem / parseMcpArgs…
titanwings Sep 15, 2026
0f32340
wip(recovery): 重建 CLI 入口,命令注册表接回来
titanwings Sep 15, 2026
a8d08bf
wip(recovery): 补 normalizeView,CLI 全命令面可用
titanwings Sep 15, 2026
28c09e6
fix(recovery): 注册表自己装载命令模块,不再依赖 bin 的副作用 import
titanwings Sep 15, 2026
3e4cbe1
fix(recovery): 剔除插件分支的污染,恢复双语 prompt 层(prompt-lint 归零)
titanwings Sep 15, 2026
98e9daf
fix(recovery): 认 /private/tmp 这个根,捞回 ds/05 的适配矩阵
titanwings Sep 15, 2026
6adaadd
fix(recovery): 证据脊柱的渲染契约与归因链路
titanwings Sep 15, 2026
e736ab4
fix(recovery): Slack 时间戳归一化 + 归因测试夹具自洽
titanwings Sep 15, 2026
8b57358
fix(recovery): 字幕字节区间、溯源认亲、`loadLedger` 宽容形态
titanwings Sep 15, 2026
697ab88
feat(derive): 补齐 retrospect 的六个维度,夹具特征全中
titanwings Sep 15, 2026
21dfa5e
fix(recovery): 打通 view check/render 全链路,验收 8/9 → 11/12
titanwings Sep 15, 2026
6b53730
feat(release): schema v4、安装器携带证据脊柱、删掉 Python —— 发布检查 7/7
titanwings Sep 15, 2026
9b933b1
fix(recovery): PLANNED 在补丁里清空,推送状态审计如实报告
titanwings Sep 15, 2026
a646013
fix(audit): 目标审计 15/15,端到端验收两个语料各 12/12
titanwings Sep 15, 2026
749a6dc
fix(parse): 飞书检测器返回 null、飞书兜底认领、requiredKeys 真的必填
titanwings Sep 15, 2026
e14da75
chore(recovery): 重建流程改成可验证的快照叠加,并清掉两类污染
titanwings Sep 15, 2026
8202b61
fix(parse): 补回解析夹具,parseArchive 收路径、parseCsv 返回单元格
titanwings Sep 15, 2026
6f1f662
fix(repo): 补回 .gitattributes 的字节保真规则
titanwings Sep 15, 2026
c98080e
fix(parse): 聊天导出的形状判定与定位纪律
titanwings Sep 15, 2026
8236916
fix(slug): 拼音表的词频正则、覆盖范围与音节拼装
titanwings Sep 15, 2026
b15baed
fix(knowledge): 同一目录的多份导出不再共用一个正文文件
titanwings Sep 15, 2026
c5f1762
fix(cli): 命令帮助补上双语标记与 consent 的子命令用法
titanwings Sep 15, 2026
c0c3933
fix(collect): 渠道模块用数字返回的退出码不再被吞掉
titanwings Sep 15, 2026
6c648f8
fix(commands): listCommands() 恢复为「命令名数组」的对外契约
titanwings Sep 15, 2026
6a20a03
fix(skill): celebrity preset 不再指向已退役的 Python 研究脚本
titanwings Sep 15, 2026
e07743d
feat(commands): 补回 parse-doc / parse-archive,并补齐命令表面的三处缺口
titanwings Sep 15, 2026
742d5d6
fix(parse): parseArchive 接受原始字节、路由可读成员、拒绝无可读文本的归档
titanwings Sep 15, 2026
d6d7b13
fix(parse): OOXML 成员按文本解码、命名空间前缀、8 位头部、records 暴露
titanwings Sep 15, 2026
989a53e
fix(tests): 去掉重建残留的 require 与未定义符号
titanwings Sep 15, 2026
9c180cf
fix(knowledge): 让锚点真的能回指字节,并把编码判定结果透出来
titanwings Sep 15, 2026
34921cc
test(knowledge): 恢复分支最终的编码与锚点断言
titanwings Sep 15, 2026
30bc454
fix(harvest): JSON 导出不再被一律当成飞书
titanwings Sep 15, 2026
7e66281
fix(collect): --json 不再被吞、失败补救不再消失、浏览器采集记下 URL
titanwings Sep 15, 2026
6dc053d
fix(hosts): 适配矩阵按上游注册表核实,全局帮助列出宿主
titanwings Sep 15, 2026
b1b1f9f
fix(parse): 锚点可回读原始字节、parse-chat 认得飞书、--format 真正生效
titanwings Sep 15, 2026
48eba05
feat(doctor): 体检真的数锚点,三种 --base-dir 写法各归其位
titanwings Sep 15, 2026
8e8cf1a
fix(install/doctor/ci): install --path 不再崩、备份路径不再丢、CI 不再收脚本当测试
titanwings Sep 15, 2026
c335c3c
fix(audit): 渠道行不再空口通过,推送行不再谎报缺口
titanwings Sep 15, 2026
ca473fe
fix(parse-chat): 被编辑的分支不再混进正文、碎片消息有包络区间、时间戳标签对齐
titanwings Sep 15, 2026
4a5065b
fix(collect): 凭据来源进入账本,Discord 说话人用显示名,文本文件断言不再靠目录顺序
titanwings Sep 15, 2026
e700d2a
fix(collect): 采集来源与凭据文件名进入账本;Discord 用显示名;文本文件断言不再靠目录顺序
titanwings Sep 15, 2026
daf9bbd
fix(collect): Gmail 采集的凭据来源进入账本;Reddit 401 的断言按分支最终版对齐
titanwings Sep 15, 2026
089dc43
fix(browser): 抓取的原始字节真的按原样存,同意补救文案指名正确渠道
titanwings Sep 15, 2026
8ce68b0
fix(blind-test/render): 盲测装置真的产出可读页面;声明为缺口的段落可以渲染
titanwings Sep 15, 2026
57db341
fix(migrate): 找回技能的目录遍历(require 在 ESM 里抛错被 catch 吞掉)
titanwings Sep 15, 2026
36d2101
fix(subtitle): 锚点区间是整条字幕块;时间码留在元数据而不进正文
titanwings Sep 15, 2026
b2fc233
feat(collect): 补回 feishu MCP 的 CLI 入口;飞书消息的时间戳归一化为 ISO
titanwings Sep 15, 2026
0999b65
fix(tests+identity): 修掉三条永远不可能通过的断言与一处重复计数
titanwings Sep 15, 2026
221da76
test(hosts): 补提交 agents.test.mjs 的安装器断言
titanwings Sep 15, 2026
7fe9a8a
test(hosts): 清掉 bin 解析路线的残留(parseBinHosts / evaluateHostTarget / binS…
titanwings Sep 15, 2026
eba6fc8
chore(visual-check): 不再输出移动端截图(375px 的检查保留)
titanwings Sep 15, 2026
3b9b401
feat(corpus): 收一份真实的公共领域语料,并修掉它顶出来的四个缺陷
titanwings Sep 15, 2026
6d4909b
fix(derive): 时间线不再编造 1970 的日期,也不再和正文粘在一起
titanwings Sep 15, 2026
dafd393
fix(parse): 长句后的句中换人不再被丢掉
titanwings Sep 15, 2026
d0749bd
feat(parse): 中文字幕的说话人不再整份丢失
titanwings Sep 15, 2026
2c90893
fix(ci): 两个让 CI 每一次都红的门禁缺陷
titanwings Sep 15, 2026
2551c9b
fix(tests): 测试不再读开发机真实 home 里的凭据
titanwings Sep 15, 2026
a467934
fix(tests): 一条只在大小写不敏感文件系统上通过的路径断言
titanwings Sep 15, 2026
3273de5
docs(evidence): PR-21 的结论不成立,补一节更正
titanwings Sep 15, 2026
c3390b8
docs: nuwa-skill 对照 —— 它怎么做、我们该抄什么
titanwings Sep 15, 2026
f3538c4
fix(cli): `--base-dir` 统一为工作区根,存储根改名 `--skills-dir`
titanwings Sep 15, 2026
1b066bc
test(cli): 测试不再依赖开发机装没装 DSH 的 distilly
titanwings Sep 15, 2026
1f1a816
docs(skill): 写明在宿主里怎么调 CLI,并给 bin/distilly.mjs 加执行位
titanwings Sep 15, 2026
f5a4a94
feat(acceptance): 把真正的交付物压进门禁(12 项 → 17 项)
titanwings Sep 15, 2026
967663a
ci: 让 CI 覆盖 ds/* 堆叠分支(否则 19 个 PR 永远跑不到)
titanwings Sep 15, 2026
2383fff
fix(audit): 修掉两行空转/弱判据(绿就是绿)
titanwings Sep 16, 2026
7f9c9d6
docs: README / STATUS / PRD 与实现对齐
titanwings Sep 16, 2026
cabdff4
docs(status): 更新子功能 PR 的真实 CI 状态(8 绿 / 1 结构性红 / 10 不修)
titanwings Sep 16, 2026
97d48f4
feat(doctor): 交付物的引用也算数,悬空引用从"警告"变成"判定"
titanwings Sep 16, 2026
36e27c3
feat(doctor): 前置语料体检 —— 在蒸之前先问「这份材料撑不撑得起一个人」
titanwings Sep 16, 2026
57486b6
docs(status): 效果层的装置已就绪,只差一个不是蒸馏者的裁判
titanwings Sep 16, 2026
00eb771
fix(audit): 单 ref 检出时那一行记为缺口,而不是失败(CI 刚因此变红)
titanwings Sep 16, 2026
e16cc8a
docs(evidence): pr-13 补更正 —— 那两条判据当时是假绿
titanwings Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Fixtures are byte-exact inputs: line endings, BOMs and legacy encodings are
# exactly what the parsers are being tested on, so git must not normalise them on
# checkout. Without this a CRLF fixture arrives as LF and its byte ranges drift.
tests/fixtures/** -text -diff
# The bundled derivation fixtures resolve anchors to raw byte ranges as well.
src/derive/fixtures/** -text -diff
100 changes: 71 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,96 @@
name: CI

on:
# `ds/**` is not decoration: the 19 per-feature PRs are a **stack** — each targets
# the branch before it (`ds/02` → `ds/01`, … , `ds/21` → `ds/20`), and `ds/01`
# targets `pre-v2-baseline`. With this list limited to the three integration
# branches, not one of them could ever run CI: every PR sat at "no checks
# reported" while its body claimed tests. A base branch that no trigger matches is
# a gate that does not exist.
push:
branches: [dot-skill, main]
branches: [dot-skill-test, dot-skill, main, 'ds/**']
pull_request:
branches: [dot-skill, main]
branches: [dot-skill-test, dot-skill, main, 'ds/**']
# Manual re-runs without pushing anything.
workflow_dispatch:

jobs:
test:
name: Python ${{ matrix.python-version }}
name: Node ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.11"]
node-version: ["20", "22"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
- uses: actions/setup-node@v4
with:
python-version: ${{ matrix.python-version }}
cache: pip
node-version: ${{ matrix.node-version }}

- name: Install dependencies
- name: Syntax-check every module
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
find bin src scripts tests -name '*.mjs' -print0 | xargs -0 -n1 node --check

- name: Compile all Python sources
run: python -m compileall -q tools
- name: Unit tests
# `npm test`, not a bare `node --test`: the bare form also collects
# `scripts/blind-test.mjs` (it matches `**/*-test.mjs`) and records its
# usage error as a failing test, so CI went red while every local command
# looked green.
run: npm test

- name: Run unit tests
run: |
if [ -d tests ]; then
python -m unittest discover -s tests -p 'test_*.py' -v
else
echo "No tests/ directory yet — skipping unittest discover."
fi

lint:
name: Ruff
- name: Prompt contract lint
run: node scripts/prompt-lint.mjs

- name: Skill template freshness
run: node scripts/generate-template.mjs --check

# Every demand of the v2 objective, mapped to the artefact that proves it.
# Acceptance itself runs in the next job, so this is scope-only.
- name: Objective audit
run: node scripts/audit-objective.mjs --skip-acceptance

# Release hygiene: versions, schema marker, carried directories, gates.
- name: Release check
run: node scripts/check_release.mjs

acceptance:
name: Acceptance (public corpus)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5

- uses: actions/setup-node@v4
with:
node-version: "22"

# The visual-check phase drives a real browser; playwright is a dev
# dependency and never ships with the package.
- name: Install Playwright
run: |
npm install --no-save playwright@1.62.1
npx playwright install --with-deps chromium

- name: End-to-end acceptance on the bundled corpus
run: node scripts/acceptance.mjs --evidence "$RUNNER_TEMP/evidence"

# The second public corpus is multi-source (two chat exports + a document)
# and dated, so the same phases run on a corpus the derivation was designed for.
- name: End-to-end acceptance on the multi-source corpus
run: node scripts/acceptance.mjs --corpus tests/fixtures/public-corpus/synthetic-multisource --evidence "$RUNNER_TEMP/evidence-multisource"

# Scope audit *with* the acceptance run it normally performs.
- name: Objective audit (includes acceptance)
run: DISTILLY_PLAYWRIGHT_ROOT="$PWD" node scripts/audit-objective.mjs

- uses: actions/upload-artifact@v4
if: always()
with:
python-version: "3.11"
- name: Install ruff
run: pip install ruff
- name: Run ruff (non-blocking for now)
run: ruff check tools/ || true
name: acceptance-evidence
path: |
${{ runner.temp }}/evidence
${{ runner.temp }}/evidence-multisource
if-no-files-found: ignore

19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,27 @@ playwright-data/
/tmp/feishu_*.txt
/tmp/email_*.txt
/tmp/dingtalk_*.txt

# Every `knowledge/` is user data, wherever the person directory lives. This is an
# unanchored directory pattern, so it also matches source and fixture directories of
# the same name; the re-includes below must come *after* it, otherwise the later
# `knowledge/` rule excludes them again. Tracked files are unaffected either way,
# so only a newly added module would be lost — and it would be lost silently.
knowledge/
# ...except the synthetic ledger fixtures, which are test data and must be tracked
!src/derive/fixtures/**/knowledge/
!src/derive/fixtures/**/knowledge/**
# ...and except the source modules: `src/knowledge/**` is code, not an export
!src/knowledge/
!src/knowledge/**

# OS
.DS_Store
Thumbs.db

# 本地证据(截图/回执/diff),不入库
dst-evidence/
# 根级渲染产物:契约 §2 把页面放在 evidence/renders/。
# 前导斜杠是必须的 —— 裸写 evidence/ 会匹配 docs/evidence/,那里的文字证据是要入库的。
/evidence/
*.evidence.local
37 changes: 37 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,44 @@

---

<a id="v2-hosts"></a>

## v2:命令入口与宿主适配

v2 只有一个命令入口:**`bin/distilly.mjs`**(Node ≥ 20,零依赖,见 `docs/v2/CONTRACT.md`)。

```bash
node bin/distilly.mjs install <host> # 装到该宿主的全局 Skill 目录
node bin/distilly.mjs install <host> --force # 已有安装先备份成 *.backup-<时间戳> 再替换
node bin/distilly.mjs install --path <p> # 装到自定义路径(末段目录必须叫 distilly)
node bin/distilly.mjs --help
```

- **宿主 id、全局/项目级目录、确切安装命令、双语注意事项、装完怎么验证**:见
**[docs/v2/HOSTS.md](docs/v2/HOSTS.md)**。该表由 `src/hosts/agents.mjs` 生成,`tests/agents.test.mjs`
强制它与 `bin/distilly.mjs` 的落盘目录一致。
- 当前支持 8 个宿主:`claude-code` · `codex` · `opencode` · `openclaw` · `hermes` · `deepseek-harness` ·
`grok-build` · `pi`。别名:`claude`、`deepseek`、`grok`。
- 两条路线等价:`npx -y skills add titanwings/distilly --skill distilly …`(AgentSkills CLI)或直接
`git clone https://github.com/titanwings/distilly <目标目录>`;逐字命令同样在 `docs/v2/HOSTS.md`。

<a id="deprecated-python-installers"></a>

### ⚠️ Deprecated:`python3 tools/*.py` 安装器

下面「选择你的平台」各节里的 `python3 tools/install_*_skill.py` 与手工 `git clone` 是**迁移期兼容路径,已废弃**:
v2 不再要求用户手动跑 Python。契约(`docs/v2/CONTRACT.md` §1)约定旧的 `python3 tools/xxx.py` 调用由
`bin/distilly.mjs` 转发并打印 deprecation 警告,转发层在 PR③ 删除;在当前集成分支上这些命令仍然等价于
直接执行对应的 Python 脚本。旧内容只为排查老安装而保留,**新安装请走 `bin/distilly.mjs` 或
`docs/v2/HOSTS.md` 里的一行命令**。

---

## 选择你的平台

> ⚠️ **Deprecated(旧安装路径)**:本节保留旧版按平台展开的说明。宿主目录与确切命令的最新版本在
> **[docs/v2/HOSTS.md](docs/v2/HOSTS.md)**;下面的 `python3 tools/*.py` 调用见上一节的废弃说明。

### A. Claude Code(推荐)

本项目遵循官方 [AgentSkills](https://agentskills.io) 标准,整个 repo 就是 skill 目录。克隆到 Claude skills 目录即可:
Expand Down Expand Up @@ -533,3 +569,4 @@ distilly/ ← clone 到宿主的 skills/distilly/(例如 .claude
├── versions/ # 历史版本
└── knowledge/ # 原始材料归档
```

46 changes: 46 additions & 0 deletions INSTALL_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,53 @@
> Distilly was formerly known as **Colleague Skill / colleague-skill**. The creator
> name and canonical install directory are now `distilly`.

<a id="v2-hosts"></a>

## v2: command entrypoint and host adaptation

v2 has exactly one command entrypoint: **`bin/distilly.mjs`** (Node >= 20, zero
dependencies, see `docs/v2/CONTRACT.md`).

```bash
node bin/distilly.mjs install <host> # install into that host's global Skill directory
node bin/distilly.mjs install <host> --force # back up an existing install as *.backup-<timestamp>, then replace
node bin/distilly.mjs install --path <p> # install into a custom path (final directory must be `distilly`)
node bin/distilly.mjs --help
```

- **Host ids, global/project directories, the exact install commands, bilingual
notes and how to verify an install** live in
**[docs/v2/HOSTS.md](docs/v2/HOSTS.md)**. That table is generated from
`src/hosts/agents.mjs`, and `tests/agents.test.mjs` forces it to agree with the
destinations in `bin/distilly.mjs`.
- Eight hosts are supported today: `claude-code`, `codex`, `opencode`,
`openclaw`, `hermes`, `deepseek-harness`, `grok-build`, `pi`. Aliases:
`claude`, `deepseek`, `grok`.
- The two routes are equivalent — `npx -y skills add titanwings/distilly
--skill distilly …` (AgentSkills CLI) or a plain
`git clone https://github.com/titanwings/distilly <target>`; both are quoted
verbatim in `docs/v2/HOSTS.md`.

<a id="deprecated-python-installers"></a>

### ⚠️ Deprecated: the `python3 tools/*.py` installers

The `python3 tools/install_*_skill.py` calls and manual clones below are
**migration-era compatibility paths and are deprecated**: v2 no longer asks users
to run Python by hand. The contract (`docs/v2/CONTRACT.md` §1) says the entrypoint
forwards the old `python3 tools/xxx.py` calls with a deprecation warning and that
the forwarding layer is removed in PR③; on the current integration branch those
commands are still equivalent to running the Python script directly. The old
sections are kept for troubleshooting legacy installs only — **use
`bin/distilly.mjs` or the one-liners in `docs/v2/HOSTS.md` for new installs**.

## Install Distilly

> ⚠️ **Deprecated (legacy install path)**: this section keeps the old per-host
> walkthrough. The current host directories and exact commands are in
> **[docs/v2/HOSTS.md](docs/v2/HOSTS.md)**; the `python3 tools/*.py` calls are
> explained in the deprecation note above.

Clone the repository into a Skills directory discovered by your host, keeping
the destination directory name `distilly`:

Expand Down Expand Up @@ -157,3 +202,4 @@ keep only copyright-safe paraphrases with source URLs in research notes, and
delete the temporary file after review.

Xquik is independent of X Corp. “Twitter” and “X” are trademarks of X Corp.

Loading
Loading