Skip to content

Commit 615c3ab

Browse files
committed
release(sdk): align with cccc automation+messaging contracts and harden release docs
1 parent f00a056 commit 615c3ab

18 files changed

Lines changed: 484 additions & 1175 deletions

File tree

.github/workflows/ts-ci.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: ts-ci
2+
3+
on:
4+
push:
5+
paths:
6+
- "ts/**"
7+
- ".github/workflows/ts-ci.yml"
8+
pull_request:
9+
paths:
10+
- "ts/**"
11+
- ".github/workflows/ts-ci.yml"
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: "20"
23+
cache: npm
24+
cache-dependency-path: ts/package-lock.json
25+
26+
- name: Install
27+
working-directory: ts
28+
run: npm ci
29+
30+
- name: Typecheck
31+
working-directory: ts
32+
run: npm run typecheck
33+
34+
- name: Build
35+
working-directory: ts
36+
run: npm run build

README.ja.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[English](README.md) | [中文](README.zh-CN.md) | **日本語**
44

5-
> ステータス:**0.4.0rc1**(Release Candidate)。契約(contracts)と SDK の使い勝手を硬化中です。
5+
> ステータス:**0.4.x RC**(Release Candidate)。契約(contracts)と SDK の使い勝手を硬化中です。
66
77
CCCC SDK は、**CCCC daemon**(単一 writer の協調カーネル)の上に、より高度なアプリケーションを作るための **クライアント SDK** です。
88

@@ -32,7 +32,7 @@ cccc
3232
```bash
3333
python -m pip install --index-url https://pypi.org/simple \
3434
--extra-index-url https://test.pypi.org/simple \
35-
cccc-sdk==0.4.0rc1
35+
cccc-sdk==0.4.0rcN
3636
```
3737

3838
3) 互換性チェック(推奨):
@@ -69,7 +69,7 @@ python python/examples/auto_ack_attention.py --group g_xxx --actor user
6969
## バージョニング(RC 番号が CCCC と一致しない理由)
7070

7171
SDK は **CCCC 0.4.0** に major/minor を合わせますが、**RC の連番は SDK 側で管理**します:
72-
- 例:`cccc-sdk==0.4.0rc1``cccc==0.4.0rc16` と互換な場合があります。
72+
- 例:`cccc-sdk==0.4.0rcN``cccc==0.4.x` と互換な場合があります。
7373

7474
互換性は “契約/能力” で保証します(RC 連番の厳密一致には依存しません):
7575
- IPC バージョン(`ipc_v`
@@ -84,7 +84,7 @@ SDK は **CCCC 0.4.0** に major/minor を合わせますが、**RC の連番は
8484

8585
- `spec/` — SDK 開発用の契約文書ミラー
8686
- `python/` — Python パッケージ(PyPI 名:`cccc-sdk`、import:`cccc_sdk`
87-
- `ts/` — TypeScript SDK(予定
87+
- `ts/` — TypeScript SDK(Node.js
8888

8989
---
9090

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**English** | [中文](README.zh-CN.md) | [日本語](README.ja.md)
44

5-
> Status: **0.4.0rc1** (Release Candidate). Contracts and SDK ergonomics are still being hardened.
5+
> Status: **0.4.x RC** (Release Candidate). Contracts and SDK ergonomics are still being hardened.
66
77
CCCC SDK is a set of **client SDKs** for building higher-level applications on top of the
88
**CCCC daemon** (the single-writer collaboration kernel).
@@ -34,7 +34,7 @@ cccc
3434
```bash
3535
python -m pip install --index-url https://pypi.org/simple \
3636
--extra-index-url https://test.pypi.org/simple \
37-
cccc-sdk==0.4.0rc1
37+
cccc-sdk==0.4.0rcN
3838
```
3939

4040
3) Compatibility check (recommended):
@@ -71,7 +71,7 @@ python python/examples/auto_ack_attention.py --group g_xxx --actor user
7171
## Versioning (why RC numbers may not match CCCC)
7272

7373
SDK versions match **CCCC major/minor** (`0.4.0`), but the **RC sequence is SDK-owned**:
74-
- Example: `cccc-sdk==0.4.0rc1` can be compatible with `cccc==0.4.0rc16`.
74+
- Example: `cccc-sdk==0.4.0rcN` can be compatible with `cccc==0.4.x`.
7575

7676
Compatibility is enforced by **contracts**, not by strict RC number matching:
7777
- IPC version (`ipc_v`)
@@ -86,7 +86,7 @@ See `python/examples/compat_check.py`.
8686

8787
- `spec/` — contract documents mirrored for SDK development
8888
- `python/` — Python package (`cccc-sdk`, import `cccc_sdk`)
89-
- `ts/` — TypeScript SDK (planned)
89+
- `ts/` — TypeScript SDK (Node.js)
9090

9191
---
9292

README.zh-CN.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[English](README.md) | **中文** | [日本語](README.ja.md)
44

5-
> 状态:**0.4.0rc1**(Release Candidate)。我们仍在打磨契约与 SDK 易用性,RC 期间可能有行为变化。
5+
> 状态:**0.4.x RC**(Release Candidate)。我们仍在打磨契约与 SDK 易用性,RC 期间可能有行为变化。
66
77
CCCC SDK 是一套**客户端 SDK**,用于在 **CCCC daemon**(单写入者协作内核)之上构建更上层的应用。
88

@@ -32,7 +32,7 @@ cccc
3232
```bash
3333
python -m pip install --index-url https://pypi.org/simple \
3434
--extra-index-url https://test.pypi.org/simple \
35-
cccc-sdk==0.4.0rc1
35+
cccc-sdk==0.4.0rcN
3636
```
3737

3838
3) 兼容性检查(推荐先跑一次):
@@ -69,7 +69,7 @@ python python/examples/auto_ack_attention.py --group g_xxx --actor user
6969
## 版本策略(为什么 RC 编号不一定和 CCCC 一致)
7070

7171
SDK 的 major/minor 会对齐 **CCCC 0.4.0**,但 **RC 序号由 SDK 自己维护**
72-
- 例如:`cccc-sdk==0.4.0rc1` 也可以兼容 `cccc==0.4.0rc16`
72+
- 例如:`cccc-sdk==0.4.0rcN` 也可以兼容 `cccc==0.4.x`
7373

7474
我们保证兼容性的手段是“契约/能力”,而不是强行对齐 RC 序号:
7575
- IPC 版本(`ipc_v`
@@ -84,7 +84,7 @@ SDK 的 major/minor 会对齐 **CCCC 0.4.0**,但 **RC 序号由 SDK 自己维
8484

8585
- `spec/` — 合约文档镜像(用于 SDK 开发)
8686
- `python/` — Python 包(PyPI 名称 `cccc-sdk`,import 名称 `cccc_sdk`
87-
- `ts/` — TypeScript SDK(规划中
87+
- `ts/` — TypeScript SDK(Node.js
8888

8989
---
9090

RELEASING.md

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,105 @@
1-
# Releasing `cccc-sdk` (Python)
1+
# Releasing `cccc-sdk`
22

3-
This repo is a monorepo. The Python package lives under `python/`.
3+
This repo is a monorepo with two deliverables:
4+
- Python package: `python/` (PyPI name: `cccc-sdk`)
5+
- TypeScript package: `ts/` (npm name: `cccc-sdk`)
46

5-
## Prerequisites (one-time)
6-
7-
### 1) Create accounts
7+
## Versioning policy
88

9-
- Create a TestPyPI account (for RC dry-runs).
10-
- Create a PyPI account (for real releases).
11-
- Enable 2FA on both accounts (recommended).
9+
- SDK major/minor tracks CCCC: `0.4.0`.
10+
- RC sequence is SDK-owned (`0.4.0rcN` for Python, `0.4.0-rc.N` for npm).
11+
- Compatibility is enforced by contracts/capabilities/op-probing, not by matching RC numbers.
1212

13-
### 2) Create API tokens
13+
## 0) Sync specs (recommended)
1414

15-
You’ll need **two** tokens:
16-
- one for TestPyPI
17-
- one for PyPI
15+
```bash
16+
./scripts/sync_specs_from_cccc.sh ../cccc
17+
```
1818

19-
For the **very first upload** (when the project does not exist yet), TestPyPI/PyPI may only allow an
20-
**account-scoped** token. After the project exists, prefer a **project-scoped** token and revoke the
21-
account-scoped one.
19+
## 1) Python release (PyPI/TestPyPI)
2220

23-
### 3) Configure GitHub Actions secrets
21+
### Prerequisites
2422

25-
In the GitHub repo `ChesterRa/cccc-sdk`:
23+
- TestPyPI and PyPI accounts
24+
- Repository secrets in `ChesterRa/cccc-sdk`:
25+
- `TEST_PYPI_API_TOKEN`
26+
- `PYPI_API_TOKEN`
2627

27-
`Settings → Secrets and variables → Actions → New repository secret`
28+
### Bump version
2829

29-
Add:
30-
- `TEST_PYPI_API_TOKEN` (from TestPyPI)
31-
- `PYPI_API_TOKEN` (from PyPI)
30+
Edit `python/pyproject.toml` (`project.version`).
3231

33-
## Versioning policy
32+
### Local checks
3433

35-
- The SDK version matches **CCCC major/minor**: `0.4.0`.
36-
- Pre-releases use PEP 440: `0.4.0rc1`, `0.4.0rc2`, ...
37-
- RC numbers are **SDK-owned** and do not need to match the daemon’s RC sequence.
38-
- Compatibility is enforced via:
39-
- `ipc_v` (ping)
40-
- `capabilities` (ping)
41-
- op probing (`unknown_op`)
34+
```bash
35+
./.venv/bin/python -m unittest discover -s python/tests -p "test_*.py" -v
36+
```
4237

43-
## 0) Sync specs (recommended)
38+
### Publish RC to TestPyPI
4439

4540
```bash
46-
./scripts/sync_specs_from_cccc.sh ../cccc
41+
git tag v0.4.0rcN
42+
git push origin v0.4.0rcN
4743
```
4844

49-
## 1) Bump version
45+
This triggers `.github/workflows/python-publish-testpypi.yml`.
5046

51-
Edit:
52-
- `python/pyproject.toml` (`project.version`)
53-
54-
## 2) Run local checks
47+
Install check:
5548

5649
```bash
57-
PYTHONPATH=python/src python -m unittest discover -s python/tests -p "test_*.py" -v
50+
python -m pip install --index-url https://pypi.org/simple \
51+
--extra-index-url https://test.pypi.org/simple \
52+
cccc-sdk==0.4.0rcN
5853
```
5954

60-
Optional build check (requires a venv because many systems are PEP 668 locked):
55+
### Publish stable to PyPI
6156

6257
```bash
63-
python -m venv .venv
64-
. .venv/bin/activate
65-
python -m pip install -U pip build
66-
python -m build python
58+
git tag v0.4.0
59+
git push origin v0.4.0
6760
```
6861

69-
## 3) Publish to TestPyPI (recommended for RCs)
62+
This triggers `.github/workflows/python-publish.yml`.
63+
64+
## 2) TypeScript release (npm)
65+
66+
### Bump version
7067

71-
1) Confirm `python/pyproject.toml` version is the one you want to publish.
72-
2) Tag and push (auto publishes to TestPyPI):
68+
Edit `ts/package.json` (`version`).
69+
70+
Examples:
71+
- RC: `0.4.0-rc.N`
72+
- Stable: `0.4.0`
73+
74+
### Local checks
7375

7476
```bash
75-
git tag v0.4.0rc1
76-
git push origin v0.4.0rc1
77+
cd ts
78+
npm ci
79+
npm run typecheck
80+
npm run build
7781
```
7882

79-
This triggers `python-publish-testpypi.yml`.
83+
### Publish RC
8084

81-
Install:
85+
```bash
86+
cd ts
87+
npm publish --tag rc --access public
88+
```
89+
90+
### Publish stable
8291

8392
```bash
84-
python -m pip install --index-url https://pypi.org/simple \
85-
--extra-index-url https://test.pypi.org/simple \
86-
cccc-sdk==0.4.0rc1
93+
cd ts
94+
npm publish --access public
8795
```
8896

89-
## 4) Publish to PyPI
97+
## 3) Post-release sanity
9098

91-
1) Confirm `python/pyproject.toml` version is the one you want to publish.
92-
2) Tag and push (recommended):
99+
- Run Python compat check against a running daemon:
93100

94101
```bash
95-
git tag v0.4.0
96-
git push origin v0.4.0
102+
python python/examples/compat_check.py
97103
```
98104

99-
This triggers `python-publish.yml`.
105+
- Verify npm package installs and can `import { CCCCClient } from 'cccc-sdk'`.

python/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ It requires a running CCCC daemon. The SDK does **not** ship a daemon.
77
## Versioning
88

99
This SDK matches **CCCC major/minor** (`0.4.0`), but the **RC sequence is SDK-owned**:
10-
- Example: `cccc-sdk==0.4.0rc1` can be compatible with `cccc==0.4.0rc16`.
10+
- Example: `cccc-sdk==0.4.0rcN` can be compatible with `cccc==0.4.x`.
1111

1212
## Daemon endpoint discovery
1313

@@ -23,7 +23,7 @@ The SDK connects to the daemon endpoint described by:
2323
```bash
2424
python -m pip install --index-url https://pypi.org/simple \
2525
--extra-index-url https://test.pypi.org/simple \
26-
cccc-sdk==0.4.0rc1
26+
cccc-sdk==0.4.0rcN
2727
```
2828

2929
### From source (development)

python/examples/send.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ def main() -> int:
1313
ap.add_argument("--by", default="user", help="principal id (default: user)")
1414
ap.add_argument("--to", default="", help="comma-separated recipient tokens (empty = broadcast)")
1515
ap.add_argument("--priority", default="normal", choices=["normal", "attention"], help="message priority")
16+
ap.add_argument("--reply-required", action="store_true", help="mark this message as requiring a reply")
1617
args = ap.parse_args()
1718

1819
to = [t.strip() for t in args.to.split(",") if t.strip()] if args.to else None
1920

2021
c = CCCCClient()
21-
res = c.send(group_id=args.group, text=args.text, by=args.by, to=to, priority=args.priority)
22+
res = c.send(group_id=args.group, text=args.text, by=args.by, to=to, priority=args.priority, reply_required=args.reply_required)
2223
print(json.dumps(res, ensure_ascii=False))
2324
return 0
2425

python/examples/send_cross_group.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ def main() -> int:
1414
ap.add_argument("--by", default="user", help="principal id (default: user)")
1515
ap.add_argument("--to", default="", help="comma-separated destination recipient tokens (optional)")
1616
ap.add_argument("--priority", default="normal", choices=["normal", "attention"], help="message priority")
17+
ap.add_argument("--reply-required", action="store_true", help="mark this message as requiring a reply")
1718
args = ap.parse_args()
1819

1920
to = [t.strip() for t in args.to.split(",") if t.strip()] if args.to else None
2021

2122
c = CCCCClient()
22-
res = c.send_cross_group(group_id=args.src, dst_group_id=args.dst, text=args.text, by=args.by, to=to, priority=args.priority)
23+
res = c.send_cross_group(group_id=args.src, dst_group_id=args.dst, text=args.text, by=args.by, to=to, priority=args.priority, reply_required=args.reply_required)
2324
print(json.dumps(res, ensure_ascii=False))
2425
return 0
2526

0 commit comments

Comments
 (0)