Skip to content
Merged
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
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.1.1"
version = "0.1.2"
edition = "2024"
rust-version = "1.85"
license = "Apache-2.0"
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

Codeguard helps developers and coding agents discover existing quality configuration, run selected native checkers, and turn results into durable repair tasks. Rust owns orchestration and interpretation; Maven, P3C, Checkstyle, Javadoc, Ruff, Cargo, ESLint, and other native tools remain responsible for their checks.

> **Status:** early development, source `0.1.1`. Several native checks and local repair workflows work within explicitly bounded scopes. Full delivery gates, complete language coverage, automatic task closure, and host-plugin integration remain incomplete.
> **Status:** early development, source `0.1.2`. Several native checks and local repair workflows work within explicitly bounded scopes. Full delivery gates, complete language coverage, automatic task closure, and host-plugin integration remain incomplete.
>
> **Baseline:** The current source and [implementation evidence](openspec/changes/introduce-rust-codeguard-cli/implementation-baseline.md) define callable behavior. Declared Rust minimum `1.85`, edition `2024`, Cargo resolver `2`. `@partme.ai/codeguard@0.1.1` is published for Apple Silicon macOS; no multi-platform binary release or crates.io availability is claimed.
> **Baseline:** The current source and [implementation evidence](openspec/changes/introduce-rust-codeguard-cli/implementation-baseline.md) define callable behavior. Declared Rust minimum `1.85`, edition `2024`, Cargo resolver `2`. `@partme.ai/codeguard@0.1.2` is published for Apple Silicon macOS; no multi-platform binary release or crates.io availability is claimed.

```text
Project files + existing checker configuration
Expand Down Expand Up @@ -94,14 +94,14 @@ cargo build --locked -p codeguard-cli

Version output includes `cli_version`, `target`, and protocol information. Discovery and init preview return observations and unknowns. Dry-run creates neither `AGENTS.md` nor a project data directory. Add Cargo `--offline` only when dependencies are cached.

The workspace requires `std`. The opt-in `wasm-precheck` build feature uses a bounded Rust worker with pinned Java/TypeScript grammar candidates. It currently reaches only single-file `lint java` and `lint typescript` requests without explicit native context; it is absent from the published npm `0.1.1` package. No `no_std`, completed project-wide WASM fallback, zero-unsafe, or fastest-runtime claim is made. Runtime OS calls require safety review; a comprehensive security audit is not claimed.
The workspace requires `std`. The opt-in `wasm-precheck` build feature uses a bounded Rust worker with pinned Java/TypeScript grammar candidates. It currently reaches only single-file `lint java` and `lint typescript` requests without explicit native context; it is absent from the published npm `0.1.2` package. No `no_std`, completed project-wide WASM fallback, zero-unsafe, or fastest-runtime claim is made. Runtime OS calls require safety review; a comprehensive security audit is not claimed.

### npm installation and one-off use

On Apple Silicon macOS, the published `0.1.1` package was verified with a fresh npm cache:
On Apple Silicon macOS, the published `0.1.2` package was verified with a fresh npm cache:

```bash
npx --yes @partme.ai/codeguard@0.1.1 --version --format json
npx --yes @partme.ai/codeguard@0.1.2 --version --format json
```

For a project check, replace the arguments after the package name with the desired Codeguard command. The package is currently restricted to macOS arm64.
Expand All @@ -121,7 +121,7 @@ For a one-off Node invocation without a global installation:
npm exec --yes --package "$CODEGUARD_TARBALL" -- codeguard detect . --format json
```

The packer currently supports macOS and Linux on x64/arm64 when a matching native binary is available. It requires Node 18+, npm, and an already built Rust binary for the current host. It checks the binary's reported target and version before packaging, and writes a platform-tagged tarball under ignored `release/npm/`. The default package is private and local-only. `node scripts/pack-npm-local.mjs --public` prepares the public `@partme.ai/codeguard` package with a README, full license, and host restrictions. Version `0.1.1` is published; its registry-hosted `npx` entry and artifact hashes were verified on Apple Silicon macOS. The binary reports the candidate source commit, which is not a signed or reproducible-build attestation. Other platforms need their own verified binary packages. See the [distribution design](docs/Codeguard-Technical-Design.md) and [0.1.1 acceptance record](tests/acceptance/npm-0.1.1-candidate.md).
The packer currently supports macOS and Linux on x64/arm64 when a matching native binary is available. It requires Node 18+, npm, and an already built Rust binary for the current host. It checks the binary's reported target and version before packaging, and writes a platform-tagged tarball under ignored `release/npm/`. The default package is private and local-only. `node scripts/pack-npm-local.mjs --public` prepares the public `@partme.ai/codeguard` package with a README, full license, and host restrictions. Version `0.1.2` is published; its registry-hosted `npx` entry and artifact hashes were verified on Apple Silicon macOS. The binary reports the candidate source commit, which is not a signed or reproducible-build attestation. Other platforms need their own verified binary packages. See the [distribution design](docs/Codeguard-Technical-Design.md) and [0.1.2 acceptance record](tests/acceptance/npm-0.1.2-candidate.md).

## 5. Repair workflow

Expand Down Expand Up @@ -160,7 +160,7 @@ Supply the original checker's required tool/configuration options to `task verif
| `plan CATEGORY LANGUAGE` | Preview selections and gaps | Not a certified execution plan |
| `hook plan` | Route a versioned host event to a candidate check tier | Reads bounded JSON on stdin; exit 3, no check or host blocking |
| `hook execute` | Run read-only discovery, bounded Stop guidance, task-bound recheck, selected Python Ruff feedback, or a live pre-commit index safety preview | Explicit timeout; repair reuses `task verify` and never closes a task or approves delivery |
| `hook claude <session-start\|post-tool-use\|post-tool-use-failure\|stop>` | Map Claude Code lifecycle events to read-only discovery, bounded edit feedback, no-check failure feedback, or local next-step guidance | Candidate soft Hooks; Stop offers one task continuation at most; no plugin runtime binding or delivery gate yet |
| `hook claude <session-start\|user-prompt-submit\|post-tool-use\|post-tool-use-failure\|stop>` | Map Claude Code lifecycle events to read-only discovery, constant prompt guidance, bounded edit feedback, no-check failure feedback, or local next-step guidance | Candidate soft Hooks; Stop offers one task continuation at most; no plugin runtime binding or delivery gate yet |
| `lint python / java / typescript / go` | Run selected native checks | Adapter-specific options and scope |
| `comments rust`, `build rust` | Documentation and type checking | Build does not run project tests |
| `cve rust / python / typescript` | Native advisory observations | Database identity/freshness and full coverage remain limited |
Expand All @@ -177,7 +177,7 @@ Generic `dependencies`, generic `security`, arbitrary category/language combinat

### Native-first entry points and syntax fallback — design target

**The published `0.1.1` does not yet implement bundled WASM fallback or automatic conversation delivery.** The existing commands remain the unified entry points; native adapter-specific prerequisites still apply today:
**The published `0.1.2` does not yet implement bundled WASM fallback or automatic conversation delivery.** The existing commands remain the unified entry points; native adapter-specific prerequisites still apply today:

An opt-in source build with `--features codeguard-cli/wasm-precheck` now has narrow TypeScript and Java single-file candidate paths: without explicit native context, they return versioned [TypeScript](schemas/eslint-local-feedback-v0.3.schema.json) or [Java](schemas/java-syntax-precheck-feedback-v0.1.schema.json) feedback with suspected parser recovery positions and native `not_run`. Both remain incomplete because the bundled grammar has no accepted language/dialect range. Default and published binaries keep their previous native-context behavior. [TypeScript acceptance](tests/acceptance/typescript-syntax-fallback-candidate.md) · [Java acceptance](tests/acceptance/java-syntax-fallback-candidate.md).

Expand Down
14 changes: 7 additions & 7 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

Codeguard 面向开发者与编程智能体,识别项目已有质量配置,调用选定的原生检查器,并将结果转成持久修复任务。Rust 负责调度和结果解释;Maven、P3C、Checkstyle、Javadoc、Ruff、Cargo、ESLint 等原生工具继续负责具体检查。

> **当前状态:**早期开发阶段,源码版本 `0.1.1`。部分原生检查和本地修复流程已在明确范围内实现。完整交付门禁、全部语言覆盖、任务自动关闭和宿主插件接入仍未完成。
> **当前状态:**早期开发阶段,源码版本 `0.1.2`。部分原生检查和本地修复流程已在明确范围内实现。完整交付门禁、全部语言覆盖、任务自动关闭和宿主插件接入仍未完成。
>
> **基线:**可调用行为以当前源码和[实施证据](openspec/changes/introduce-rust-codeguard-cli/implementation-baseline.md)为准。声明 Rust 最低版本 `1.85`,edition `2024`,Cargo resolver `2`。`@partme.ai/codeguard@0.1.1` 已发布,当前仅支持 Apple Silicon macOS;不声称已有多平台二进制发行版或 crates.io 发布。
> **基线:**可调用行为以当前源码和[实施证据](openspec/changes/introduce-rust-codeguard-cli/implementation-baseline.md)为准。声明 Rust 最低版本 `1.85`,edition `2024`,Cargo resolver `2`。`@partme.ai/codeguard@0.1.2` 已发布,当前仅支持 Apple Silicon macOS;不声称已有多平台二进制发行版或 crates.io 发布。

```text
项目文件 + 已有检查器配置
Expand Down Expand Up @@ -94,14 +94,14 @@ cargo build --locked -p codeguard-cli

版本输出包含 `cli_version`、`target` 和协议信息。发现与 init 预览返回观察及未知项。Dry-run 不创建 `AGENTS.md` 或项目数据目录。仅在依赖已缓存时为 Cargo 添加 `--offline`。

工作区要求 `std`。可选 `wasm-precheck` 构建特性已用固定的 Java/TypeScript grammar 候选资产与有界 Rust worker,为缺少显式原生上下文的 `lint java`、`lint typescript` 单文件请求提供疑似语法观察;公开 npm `0.1.1` 不含该路径。不声称 `no_std`、已完成项目级 WASM 兜底、零 unsafe 或性能最快。运行层系统调用需要安全审查,当前不宣称已完成整体安全审计。
工作区要求 `std`。可选 `wasm-precheck` 构建特性已用固定的 Java/TypeScript grammar 候选资产与有界 Rust worker,为缺少显式原生上下文的 `lint java`、`lint typescript` 单文件请求提供疑似语法观察;公开 npm `0.1.2` 不含该路径。不声称 `no_std`、已完成项目级 WASM 兜底、零 unsafe 或性能最快。运行层系统调用需要安全审查,当前不宣称已完成整体安全审计。

### npm 安装与一次性调用

已在 Apple Silicon macOS 上通过全新 npm 缓存验证公开 `0.1.1` 包:
已在 Apple Silicon macOS 上通过全新 npm 缓存验证公开 `0.1.2` 包:

```bash
npx --yes @partme.ai/codeguard@0.1.1 --version --format json
npx --yes @partme.ai/codeguard@0.1.2 --version --format json
```

检查项目时,可将包名后的参数换成需要执行的 Codeguard 指令。当前公开包仅支持 macOS arm64。
Expand All @@ -121,7 +121,7 @@ codeguard --version --format json
npm exec --yes --package "$CODEGUARD_TARBALL" -- codeguard detect . --format json
```

打包器在已有匹配原生程序时支持 macOS 与 Linux 的 x64/arm64 平台。打包需要 Node 18+、npm 和预先构建的本机 Rust 二进制;打包前核对二进制报告的平台和版本,在已忽略的 `release/npm/` 写入带平台标识的 tarball。默认包标记为 private,仅用于本地分发。`node scripts/pack-npm-local.mjs --public` 准备带说明、完整许可证与平台限制的公开 `@partme.ai/codeguard` 包。`0.1.1` 已发布;其公开包在 Apple Silicon macOS 上通过全新缓存 `npx` 执行和制品摘要核对。二进制回报的候选源码提交不等于签名或可复现构建证明。其它平台仍需各自验收的二进制包。见[发行技术方案](docs/Codeguard-Technical-Design.zh_CN.md)及[0.1.1 验收记录](tests/acceptance/npm-0.1.1-candidate.md)。
打包器在已有匹配原生程序时支持 macOS 与 Linux 的 x64/arm64 平台。打包需要 Node 18+、npm 和预先构建的本机 Rust 二进制;打包前核对二进制报告的平台和版本,在已忽略的 `release/npm/` 写入带平台标识的 tarball。默认包标记为 private,仅用于本地分发。`node scripts/pack-npm-local.mjs --public` 准备带说明、完整许可证与平台限制的公开 `@partme.ai/codeguard` 包。`0.1.2` 已发布;其公开包在 Apple Silicon macOS 上通过全新缓存 `npx` 执行和制品摘要核对。二进制回报的候选源码提交不等于签名或可复现构建证明。其它平台仍需各自验收的二进制包。见[发行技术方案](docs/Codeguard-Technical-Design.zh_CN.md)及[0.1.2 验收记录](tests/acceptance/npm-0.1.2-candidate.md)。

## 5. 修复流程

Expand Down Expand Up @@ -176,7 +176,7 @@ Python 编辑快反馈可执行 `codeguard lint python . --file src/changed.py -

### 原生优先的统一入口与语法兜底——设计目标

**公开 `0.1.1` 尚未实现内置 WASM 兜底或自动对话交付。** 保留已有命令作为统一入口;当前仍须满足各原生适配器的参数和前置条件:
**公开 `0.1.2` 尚未实现内置 WASM 兜底或自动对话交付。** 保留已有命令作为统一入口;当前仍须满足各原生适配器的参数和前置条件:

可选源码构建的单文件候选路径已存在:`codeguard lint java Foo.java` 与 `codeguard lint typescript foo.ts` 在完全缺少显式原生上下文时分别输出 [Java](schemas/java-syntax-precheck-feedback-v0.1.schema.json) 与 [TypeScript](schemas/eslint-local-feedback-v0.3.schema.json) 的版本化初检反馈。疑似恢复位置仍需原生确认;无恢复节点也因 grammar 版本/方言未验收保持 incomplete。默认及公开二进制沿用既有原生上下文路径,见 [Java 局部验收](tests/acceptance/java-syntax-fallback-candidate.md) 与 [TypeScript 局部验收](tests/acceptance/typescript-syntax-fallback-candidate.md)。

Expand Down
27 changes: 25 additions & 2 deletions crates/codeguard-cli/src/claude_hook_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub fn run(args: &[String]) -> ExitCode {
return ExitCode::from(2);
};
let Some((host_event, route_event)) = mapped_event(event) else {
eprintln!("支持 session-start、post-tool-use、post-tool-use-failure、stop");
eprintln!(
"支持 session-start、user-prompt-submit、post-tool-use、post-tool-use-failure、stop"
);
return ExitCode::from(2);
};
if rest.first().is_none_or(|value| value.starts_with('-')) {
Expand Down Expand Up @@ -80,6 +82,13 @@ pub fn run(args: &[String]) -> ExitCode {
);
return ExitCode::SUCCESS;
}
if route_event == HookEvent::PromptSubmitted && !host["prompt"].is_string() {
print_context(
host_event,
"CodeGuard:用户提示事件无效;源码检查未运行,交付未评估。",
);
return ExitCode::SUCCESS;
}
if route_event == HookEvent::FileChanged
&& host_event == "PostToolUseFailure"
&& (!matches!(
Expand Down Expand Up @@ -119,7 +128,9 @@ pub fn run(args: &[String]) -> ExitCode {
event: route_event,
changed_paths: path.iter().cloned().collect(),
task_id: None,
write_outcome: if host_event == "PostToolUseFailure" {
write_outcome: if route_event != HookEvent::FileChanged {
HookWriteOutcome::Unknown
} else if host_event == "PostToolUseFailure" {
HookWriteOutcome::Failed
} else {
HookWriteOutcome::Confirmed
Expand All @@ -130,6 +141,7 @@ pub fn run(args: &[String]) -> ExitCode {
Ok((report, _)) => {
let context = match route_event {
HookEvent::SessionStart => summarize_discovery(&report),
HookEvent::PromptSubmitted => summarize_intent_guidance(&report),
HookEvent::Stop => summarize_stop(&report, host["stop_hook_active"] == true),
HookEvent::FileChanged if host_event == "PostToolUseFailure" => {
"CodeGuard:写入失败,本次源码检查未运行;请先处理工具错误,交付未评估。"
Expand Down Expand Up @@ -160,6 +172,7 @@ pub fn run(args: &[String]) -> ExitCode {
fn mapped_event(event: &str) -> Option<(&'static str, HookEvent)> {
match event {
"session-start" => Some(("SessionStart", HookEvent::SessionStart)),
"user-prompt-submit" => Some(("UserPromptSubmit", HookEvent::PromptSubmitted)),
"post-tool-use" => Some(("PostToolUse", HookEvent::FileChanged)),
"post-tool-use-failure" => Some(("PostToolUseFailure", HookEvent::FileChanged)),
"stop" => Some(("Stop", HookEvent::Stop)),
Expand Down Expand Up @@ -235,6 +248,15 @@ fn summarize_discovery(report: &Value) -> String {
)
}

fn summarize_intent_guidance(report: &Value) -> String {
if report["execution"] != "read_only_intent_guidance"
|| report["local_feedback"]["report_type"] != "hook_intent_guidance"
{
return "CodeGuard:用户提示指引未运行;源码检查未运行,交付未评估。".into();
}
"CodeGuard:本事件只提供检查时机提示;代码变更后执行局部检查,真实提交或 CI 时执行完整门禁。源码检查未运行,交付未评估。".into()
}

fn safe_task_id(report: &Value) -> Option<&str> {
report["local_feedback"]["task_id"].as_str().filter(|task| {
task.len() <= 64
Expand Down Expand Up @@ -331,6 +353,7 @@ fn print_context(event: &str, context: &str) {
} else {
let label = match event {
"SessionStart" => "CodeGuard 项目发现反馈",
"UserPromptSubmit" => "CodeGuard 检查时机提示",
"PostToolUseFailure" => "CodeGuard 写入失败反馈",
_ => "CodeGuard 局部检查反馈",
};
Expand Down
Loading
Loading