- Rust 94.7%
- TypeScript 4%
- Shell 0.7%
- JavaScript 0.3%
- WebAssembly 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| apps/piwke-harness | ||
| assets | ||
| crates | ||
| docs | ||
| examples | ||
| experiments | ||
| packages/piwke-assembly | ||
| vendor | ||
| wit | ||
| .envrc | ||
| .gitignore | ||
| .muxrun.toml | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CONTEXT.md | ||
| devenv.lock | ||
| devenv.nix | ||
| devenv.yaml | ||
| HANDOFF.md | ||
| justfile | ||
| README.md | ||
| rust-toolchain.toml | ||
piwke
Cordis core / Loader 的 Rust + Wasm 实现
本仓库是 piwke:把论文第 5 章 Cordis core(effect / coeffect / context)与 component loader(pp57–69)的可观察语义实现为 Rust + Wasm Component Model。下面的 harness / devenv 内容说明承载它的开发环境,不是项目本体。
最短运行(在本仓库根,TypeScript 装配 demo):
npm --prefix packages/piwke-assembly ci
node examples/assembly-demo/dev.ts run # 普通宿主:只打印框架 ready / HMR / shutdown
node examples/assembly-demo/dev.ts run 构建后调用领域无关的 piwke-host,只输出框架
ready / HMR / shutdown 日志,不打印 [A:hello] 等业务观察。需要真实 typed 业务观察
时用 node examples/assembly-demo/tests/dev.ts run(测试 watch 同理);端到端验收用
node examples/assembly-demo/tests/verify.ts(或
npm --prefix examples/assembly-demo run verify)。
详解见 assembly demo README。本次重构的主验收证据 (Rust 合计 550、SDK 42 + strict tsc)见 assembly demo 重构结果记录。更早一轮的 Rust 合计 541 是 2026-10-06 单独的历史记录,见 assembly demo 验收记录,与本次结果分开。
旧的原生 Cordis core + Loader 入口保留:先
examples/composition/async-demo/scripts/build.sh,再
cargo run -p piwke-cargo --example cordis-demo;其 P0–P11 历史验收为 exit 0、
536 passed / 0 failed,见进度台账第 6.27 节。
本轮交付的 TypeScript 装配 SDK 只从真实组件生成 descriptor 并写出既有 Loader JSON,不是
此前延期的 typed 新圈层;HTTP、typed 新圈层扩展、builtin native provider、DSH volatile 仍按
决策延期。索引:guest SDK、
Loader、Cargo 构建工具、
文档索引。
中文
一个精简、可复现的 OpenCode 项目骨架:devenv + direnv 负责环境,Just 提供 入口,项目自身的 LLM agent 约束与启动实现已移除,统一复用 gjz010/harness。
首次使用
宿主机需要预先安装支持 flakes 的 Nix、devenv 和 direnv。当前固定的 harness
仅支持 x86_64-linux;启动需要宿主内核与容器/安全策略允许 bubblewrap 创建
所需 namespaces(包括非特权 user namespace、PID 和 IPC namespace)。受限容器
可能拒绝启动;just check 通过并不证明沙箱可运行。
direnv allow # 首次必须由宿主手动审查并授权 .envrc
just check
just opencode # 或 just opencode-web
direnv allow 是宿主侧的安全授权动作,agent 不会代为执行。首次进入 shell 会让
devenv 求值并下载 harness;完成后 harness 即可用。
从旧版本迁移后,在宿主审查修改后的 .envrc,再执行以下操作(agent 不代为授权):
direnv allow .
direnv reload
direnv export json >/dev/null
最后一条立即求值并检查错误,不打印环境值;当前终端需通过 direnv shell hook
加载新环境,然后重启 OpenCode。以后修改 devenv 配置同样需要 reload/export;
只有 .envrc 改动需要重新审查授权。
使用入口
| 命令 | 作用 |
|---|---|
just |
列出全部 recipe |
just check |
校验配置、Nix 与 shell/recipe 语法 |
just opencode [ARGS...] |
启动 harness 包装的 OpenCode TUI |
just opencode-web [ARGS...] |
启动 harness 包装的 OpenCode Web |
just update-harness |
通过 devenv update harness 更新固定版本并写入 lock |
直接使用 harness [web] [--workspace DIR] [-- OpenCode ARGS...] 时,workspace
默认是当前目录,OpenCode 参数放在 -- 之后。Just 入口已代为插入这个 --,
因此参数直接跟在 recipe 之后:
just opencode --agent normal
just opencode-web --port 43118
环境与 runtime
- 所有开发者共享的软件包写在
devenv.nix;新增 input 需同步修改devenv.yaml并重新生成devenv.lock。 - harness 的 runtime 环境变量默认从
${XDG_CONFIG_HOME:-$HOME/.config}/gjz010/harness/env读取。需要固定其他位置 时显式设置GJZ010_HARNESS_ENV_FILE。需要这些设置时,文件由用户自行创建和 维护,launcher 仅在启动时 source;默认文件不存在不会阻止启动,但显式指定的 文件必须存在。该文件是可执行 shell 代码,只使用可信内容;不要把秘密写入 Nix 表达式、store、日志或提交文件。 - 宿主的 OpenCode config、auth、data 与 cache 由 harness 共享,不再由本项目 隔离或覆盖。
- 修改 config、skills、instructions、MCP、agents、commands、plugins 或安装包 后,需要重启 OpenCode;新建 chat session 不等于重载。
旧的 profile 选择机制(Git 身份匹配、VIBE_DEVELOPER、项目内 bubblewrap
启动器、项目内 skills 同步与签名实现)已整体移除,签名与 skills 由 harness
提供。
维护
- 需要升级 harness 时运行
just update-harness,提交更新后的devenv.lock。 不要手工编辑 lock 或填入 hash。 - 需要升级其他 input 时使用
devenv update,并把devenv.lock一并提交。
English
This repository is piwke: the Rust + Wasm Component Model implementation of the paper's Chapter 5 Cordis core (effect / coeffect / context) and component loader (pp57–69). The harness / devenv material below describes the development environment, not the project itself.
Shortest run (from the repository root, TypeScript assembly demo):
npm --prefix packages/piwke-assembly ci
node examples/assembly-demo/dev.ts run # ordinary host: framework ready / HMR / shutdown only
node examples/assembly-demo/dev.ts run builds and then calls the domain-agnostic
piwke-host; it prints only framework ready / HMR / shutdown logs and no business
observation such as [A:hello]. For real typed business observation use
node examples/assembly-demo/tests/dev.ts run (the test watch works the same way); for
end-to-end acceptance use node examples/assembly-demo/tests/verify.ts (or
npm --prefix examples/assembly-demo run verify).
Details are in the assembly demo README. This refactor's main acceptance evidence (Rust total 550; SDK 42 plus strict tsc) is in the assembly demo refactor results. The earlier Rust total 541 is a separate 2026-10-06 historical record, the assembly demo results.
The old native Cordis core + Loader entry is kept: run
examples/composition/async-demo/scripts/build.sh then
cargo run -p piwke-cargo --example cordis-demo; its historical P0–P11 acceptance was exit 0,
536 passed / 0 failed (see progress ledger §6.27).
The TypeScript assembly SDK delivered this round only generates descriptors from real components
and writes the existing Loader JSON; it is not the previously deferred typed realm extension.
HTTP, typed realm extensions, builtin native providers and DSH volatile remain deferred.
Index: guest SDK,
Loader, Cargo tool,
docs.
A minimal, reproducible OpenCode project skeleton: devenv + direnv provide the environment, Just provides entrypoints, and the project's own LLM-agent constraints and launcher implementation have been removed in favor of gjz010/harness.
First Use
The host requires Nix with flakes, devenv, and direnv. The pinned harness supports
only x86_64-linux. Its launcher requires the host kernel and container/security
policy to allow bubblewrap's namespaces (including unprivileged user, PID, and
IPC namespaces). Restricted containers may reject startup; passing just check
does not prove that the sandbox can run.
direnv allow # first authorization must be reviewed and granted on the host
just check
just opencode # or just opencode-web
The first shell entry makes devenv evaluate and fetch harness.
After migrating from the old version, review the changed .envrc on the host,
then run these commands yourself (the agent does not grant authorization):
direnv allow .
direnv reload
direnv export json >/dev/null
The last command evaluates immediately to expose errors without printing
environment values. Let the direnv shell hook load the new environment in your
terminal, then restart OpenCode. Later devenv changes also need reload/export;
only .envrc changes require renewed review and authorization.
Entrypoints
| Command | Purpose |
|---|---|
just |
List all recipes |
just check |
Validate config, Nix formatting, and shell/recipe syntax |
just opencode [ARGS...] |
Launch the harnessed OpenCode TUI |
just opencode-web [ARGS...] |
Launch the harnessed OpenCode Web |
just update-harness |
Update the pinned harness input through devenv update harness |
When invoking harness [web] [--workspace DIR] [-- OpenCode ARGS...] directly,
the workspace defaults to the current directory and OpenCode arguments go after
--. The Just entrypoints insert that -- for you, so pass arguments directly
after the recipe:
just opencode --agent normal
just opencode-web --port 43118
Environment And Runtime
- Shared packages belong in
devenv.nix; a new input also changesdevenv.yamland regeneratesdevenv.lock. - Harness reads its runtime environment from
${XDG_CONFIG_HOME:-$HOME/.config}/gjz010/harness/envby default. SetGJZ010_HARNESS_ENV_FILEto pin another path. Users must create and maintain this file when needed; the launcher only sources it at startup. A missing default file is allowed, but an explicitly selected file must exist. It is executable shell code: use only trusted content and keep secrets out of Nix expressions, the store, logs, and committed files. - Host OpenCode config, auth, data, and cache are shared with harness instead of being isolated or overridden by this project.
- Restart OpenCode after changing config, skills, instructions, MCP, agents, commands, plugins, or packages; a new chat session is not a reload.
The old profile-selection mechanism (Git-identity matching, VIBE_DEVELOPER,
the project bubblewrap launcher, and project-local skill sync and signing) has
been removed entirely.
Maintenance
- Run
just update-harnessand commit the updateddevenv.lockto upgrade harness. Never hand-edit the lock or paste hashes. - Use
devenv updatefor other inputs and commitdevenv.lockwith them.