Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
91 changes: 62 additions & 29 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,87 @@
name: CI

on:
# The per-feature PRs are a stack whose bases are other `ds/*` branches; with the
# trigger list limited to the integration branches, none of them could ever run CI.
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/**']
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
run: node --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

15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +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