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
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
English | <a href="https://github.com/lencx/opsail/blob/main/README.zh-CN.md">简体中文</a>
</p>

<a href="https://www.buymeacoffee.com/lencx" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
<a href="https://www.buymeacoffee.com/lencx" target="_blank"><img height="40" width="145" src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee"></a>

Opsail is a modular native toolkit that gives software agents small, composable, and reliable capabilities through one command-line entry point. Its Rust crates keep acquisition, browser control, content extraction, and application-specific refits behind explicit boundaries, while the Node.js package makes the same native runtime easy to embed.

Expand All @@ -33,13 +33,13 @@ opsail read https://example.com/article
opsail read https://example.com/app --launch
```

See [`opsail-read`](crates/opsail-read/README.md) for acquisition, extraction, result contracts, and Rust APIs. See [`opsail-chrome`](crates/opsail-chrome/README.md) for Chrome discovery, owned launch, borrowed CDP, navigation, and rendered DOM capture.
See [`opsail-read`](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md) for acquisition, extraction, result contracts, and Rust APIs. See [`opsail-chrome`](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md) for Chrome discovery, owned launch, borrowed CDP, navigation, and rendered DOM capture.

### Refit Codex

`opsail refit codex` provides a reversible, target-validated Codex adapter. Its first feature adds localized remaining-usage information to the Codex sidebar using the renderer's existing local bridge, without model calls or changes to the application bundle.

![refit-codex](assets/refit-codex.png)
![refit-codex](https://raw.githubusercontent.com/lencx/opsail/main/assets/refit-codex.png)

The refit target is implemented for the signed macOS application and the current-user Microsoft Store application on Windows; Linux is not supported. Windows release targets are x64 and ARM64; no 32-bit x86/ia32 artifact is provided. Opsail resolves the exact package family and AUMID, derives the application executable from the installed signed manifest (currently `app\ChatGPT.exe`), and protects its Local AppData state with an explicit current-user-and-SYSTEM DACL. Native CI and npm packaging targets are configured for both Windows architectures. A Windows 11 ARM64 canary against the installed Store application validates package activation, listener ownership, renderer discovery, bridge injection, persistence, and cleanup; a real installed-application x64 canary remains pending, while hosted CI covers the no-installed-package path.

Expand All @@ -51,17 +51,17 @@ Persistent mode starts a validated background manager and returns after its heal

Interactive waits show their current validated lifecycle stage on `stderr`, while the final machine-readable JSON remains isolated on `stdout`.

See [`opsail-refit-codex`](crates/opsail-refit-codex/README.md) for supported targets, attach and launch modes, lifecycle semantics, renderer updates, localization, security checks, and library APIs.
See [`opsail-refit-codex`](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md) for supported targets, attach and launch modes, lifecycle semantics, renderer updates, localization, security checks, and library APIs.

## Packages

| Package | Responsibility | Documentation |
| --- | --- | --- |
| [`opsail`](https://crates.io/crates/opsail) | Native CLI and unified command entry point | Run `opsail --help` |
| [`opsail-read`](https://crates.io/crates/opsail-read) | Content acquisition, extraction, sanitization, and result contracts | [README](crates/opsail-read/README.md) |
| [`opsail-chrome`](https://crates.io/crates/opsail-chrome) | Cross-platform Chrome lifecycle, CDP transport, and rendered capture | [README](crates/opsail-chrome/README.md) |
| [`opsail-refit-codex`](https://crates.io/crates/opsail-refit-codex) | Validated Codex refit lifecycle, usage semantics, localization, and UI payload | [README](crates/opsail-refit-codex/README.md) |
| [`opsail`](https://www.npmjs.com/package/opsail) for Node.js | ESM API and native binary distribution | [README](packages/node/README.md) |
| [`opsail-read`](https://crates.io/crates/opsail-read) | Content acquisition, extraction, sanitization, and result contracts | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md) |
| [`opsail-chrome`](https://crates.io/crates/opsail-chrome) | Cross-platform Chrome lifecycle, CDP transport, and rendered capture | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md) |
| [`opsail-refit-codex`](https://crates.io/crates/opsail-refit-codex) | Validated Codex refit lifecycle, usage semantics, localization, and UI payload | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md) |
| [`opsail`](https://www.npmjs.com/package/opsail) for Node.js | ESM API and native binary distribution | [README](https://github.com/lencx/opsail/blob/main/packages/node/README.md) |

## Install

Expand All @@ -77,15 +77,15 @@ Install the Node.js API and CLI from npm:
npm install opsail
```

Prebuilt native binaries are available from [GitHub Releases](https://github.com/lencx/opsail/releases/latest). Agent hosts can use the reviewed [`bootstrap-opsail` Skill](skills/bootstrap-opsail/SKILL.md) to reconcile the CLI and runtime Skill with explicit approval.
Prebuilt native binaries are available from [GitHub Releases](https://github.com/lencx/opsail/releases/latest). Agent hosts can use the reviewed [`bootstrap-opsail` Skill](https://github.com/lencx/opsail/blob/main/skills/bootstrap-opsail/SKILL.md) to reconcile the CLI and runtime Skill with explicit approval.

## Project documentation

- [Content extraction and result model](crates/opsail-read/README.md)
- [Chrome and CDP integration](crates/opsail-chrome/README.md)
- [Codex sidebar refit](crates/opsail-refit-codex/README.md)
- [Node.js API and packaging](packages/node/README.md)
- [Development and contribution guide](CONTRIBUTING.md)
- [Content extraction and result model](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md)
- [Chrome and CDP integration](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md)
- [Codex sidebar refit](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md)
- [Node.js API and packaging](https://github.com/lencx/opsail/blob/main/packages/node/README.md)
- [Development and contribution guide](https://github.com/lencx/opsail/blob/main/CONTRIBUTING.md)

## License

Expand Down
28 changes: 14 additions & 14 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<a href="https://github.com/lencx/opsail/blob/main/README.md">English</a> | 简体中文
</p>

<a href="https://www.buymeacoffee.com/lencx" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" style="height: 40px !important;width: 145px !important;" ></a>
<a href="https://www.buymeacoffee.com/lencx" target="_blank"><img height="40" width="145" src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee"></a>

Opsail 是一个模块化原生工具集,通过统一的命令行入口,为软件 Agent 提供小而可组合、行为可靠的能力。它使用职责清晰的 Rust crate 隔离内容获取、浏览器控制、正文提取和应用适配,并通过 Node.js 包方便地嵌入同一套原生运行时。

Expand All @@ -33,13 +33,13 @@ opsail read https://example.com/article
opsail read https://example.com/app --launch
```

内容获取、正文提取、结果契约和 Rust API 请参阅 [`opsail-read`](crates/opsail-read/README.md);Chrome 发现、自有启动、借用 CDP、页面导航和渲染 DOM 捕获请参阅 [`opsail-chrome`](crates/opsail-chrome/README.md)。
内容获取、正文提取、结果契约和 Rust API 请参阅 [`opsail-read`](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md);Chrome 发现、自有启动、借用 CDP、页面导航和渲染 DOM 捕获请参阅 [`opsail-chrome`](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md)。

### Codex Refit

`opsail refit codex` 提供可逆且经过目标校验的 Codex 适配器。它的首个功能通过 renderer 已有的本地 bridge,在 Codex 左侧栏显示本地化的剩余额度信息,不调用模型,也不修改应用包。

![refit-codex](assets/refit-codex.png)
![refit-codex](https://raw.githubusercontent.com/lencx/opsail/main/assets/refit-codex.png)

Refit 目标已实现对签名 macOS 应用和 Windows 当前用户 Microsoft Store 应用的支持;Linux 不支持。Windows 发布目标为 x64 和 ARM64,不提供 32 位 x86/ia32 产物。Windows 实现使用精确的包家族名和 AUMID 定位应用,从已安装的签名 manifest 中解析可执行文件(当前为 `app\ChatGPT.exe`),并使用仅授权当前用户和 SYSTEM 的显式 DACL 保护 Local AppData 状态。Windows x64 和 ARM64 都已配置原生 CI 与 npm 打包目标;已在 Windows 11 ARM64 的 Store 应用上完成包激活、端口归属、renderer 发现、bridge 注入、持久模式与清理的端到端验证,真实 x64 Store 应用 canary 仍待完成,托管 CI 覆盖未安装目标包的路径。

Expand All @@ -51,17 +51,17 @@ opsail refit codex enable usage --launch

交互式等待会在 `stderr` 中显示当前经过校验的生命周期阶段,最终供程序读取的 JSON 仍只写入 `stdout`。

支持目标、附加与启动模式、生命周期语义、renderer 更新、多语言、安全校验和库 API 请参阅 [`opsail-refit-codex`](crates/opsail-refit-codex/README.md)。
支持目标、附加与启动模式、生命周期语义、renderer 更新、多语言、安全校验和库 API 请参阅 [`opsail-refit-codex`](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md)。

## 包结构

| 包 | 职责 | 文档 |
| --- | --- | --- |
| [`opsail`](https://crates.io/crates/opsail) | 原生 CLI 与统一命令入口 | 运行 `opsail --help` |
| [`opsail-read`](https://crates.io/crates/opsail-read) | 内容获取、正文提取、清理和结果契约 | [README](crates/opsail-read/README.md) |
| [`opsail-chrome`](https://crates.io/crates/opsail-chrome) | 跨平台 Chrome 生命周期、CDP 传输和渲染捕获 | [README](crates/opsail-chrome/README.md) |
| [`opsail-refit-codex`](https://crates.io/crates/opsail-refit-codex) | Codex 适配生命周期、额度语义、多语言和 UI payload | [README](crates/opsail-refit-codex/README.md) |
| Node.js [`opsail`](https://www.npmjs.com/package/opsail) | ESM API 与原生二进制分发 | [README](packages/node/README.md) |
| [`opsail-read`](https://crates.io/crates/opsail-read) | 内容获取、正文提取、清理和结果契约 | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md) |
| [`opsail-chrome`](https://crates.io/crates/opsail-chrome) | 跨平台 Chrome 生命周期、CDP 传输和渲染捕获 | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md) |
| [`opsail-refit-codex`](https://crates.io/crates/opsail-refit-codex) | Codex 适配生命周期、额度语义、多语言和 UI payload | [README](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md) |
| Node.js [`opsail`](https://www.npmjs.com/package/opsail) | ESM API 与原生二进制分发 | [README](https://github.com/lencx/opsail/blob/main/packages/node/README.md) |

## 安装

Expand All @@ -77,15 +77,15 @@ cargo install opsail
npm install opsail
```

预编译原生二进制可从 [GitHub Releases](https://github.com/lencx/opsail/releases/latest) 下载。Agent 宿主可以在明确授权后,使用经过审阅的 [`bootstrap-opsail` Skill](skills/bootstrap-opsail/SKILL.md) 同步 CLI 和运行时 Skill。
预编译原生二进制可从 [GitHub Releases](https://github.com/lencx/opsail/releases/latest) 下载。Agent 宿主可以在明确授权后,使用经过审阅的 [`bootstrap-opsail` Skill](https://github.com/lencx/opsail/blob/main/skills/bootstrap-opsail/SKILL.md) 同步 CLI 和运行时 Skill。

## 项目文档

- [内容提取与结果模型](crates/opsail-read/README.md)
- [Chrome 与 CDP 集成](crates/opsail-chrome/README.md)
- [Codex 左侧栏 Refit](crates/opsail-refit-codex/README.md)
- [Node.js API 与打包](packages/node/README.md)
- [开发与贡献指南](CONTRIBUTING.md)
- [内容提取与结果模型](https://github.com/lencx/opsail/blob/main/crates/opsail-read/README.md)
- [Chrome 与 CDP 集成](https://github.com/lencx/opsail/blob/main/crates/opsail-chrome/README.md)
- [Codex 左侧栏 Refit](https://github.com/lencx/opsail/blob/main/crates/opsail-refit-codex/README.md)
- [Node.js API 与打包](https://github.com/lencx/opsail/blob/main/packages/node/README.md)
- [开发与贡献指南](https://github.com/lencx/opsail/blob/main/CONTRIBUTING.md)

## 许可证

Expand Down
24 changes: 20 additions & 4 deletions packages/node/test/skill.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const opsailSkillPath = path.join(
"SKILL.md",
);
const readmePath = path.join(repositoryRoot, "README.md");
const readmeZhPath = path.join(repositoryRoot, "README.zh-CN.md");
const releaseWorkflowPath = path.join(
repositoryRoot,
".github",
Expand Down Expand Up @@ -120,16 +121,31 @@ test("bootstrap is independently versioned and runtime matches the public packag
});

test("root README stays concise and release workflow keeps one installer source", async () => {
const [readme, releaseWorkflow] = await Promise.all([
const [readme, readmeZh, releaseWorkflow] = await Promise.all([
readFile(readmePath, "utf8"),
readFile(readmeZhPath, "utf8"),
readFile(releaseWorkflowPath, "utf8"),
]);

assert.match(readme, /## Core characteristics/);
assert.match(readme, /See \[`opsail-read`\]\(crates\/opsail-read\/README\.md\)/);
assert.match(readme, /See \[`opsail-refit-codex`\]\(crates\/opsail-refit-codex\/README\.md\)/);
assert.match(
readme,
/See \[`opsail-read`\]\(https:\/\/github\.com\/lencx\/opsail\/blob\/main\/crates\/opsail-read\/README\.md\)/,
);
assert.match(
readme,
/See \[`opsail-refit-codex`\]\(https:\/\/github\.com\/lencx\/opsail\/blob\/main\/crates\/opsail-refit-codex\/README\.md\)/,
);
assert.match(readme, /\[GitHub Releases\]\(https:\/\/github\.com\/lencx\/opsail\/releases\/latest\)/);
assert.match(readme, /\[`bootstrap-opsail` Skill\]\(skills\/bootstrap-opsail\/SKILL\.md\)/);
assert.match(
readme,
/\[`bootstrap-opsail` Skill\]\(https:\/\/github\.com\/lencx\/opsail\/blob\/main\/skills\/bootstrap-opsail\/SKILL\.md\)/,
);
for (const source of [readme, readmeZh]) {
assert.doesNotMatch(source, /!?\[[^\]]*\]\((?!https:\/\/|#)[^)]+\)/);
assert.doesNotMatch(source, /(?:href|src)="(?!https:\/\/|#)[^"]+"/);
assert.doesNotMatch(source, /^\s*\[[^\]]+\]:\s*(?!https:\/\/|#)\S+/m);
}
assert.ok(readme.split("\n").length <= 100);
assert.doesNotMatch(
readme,
Expand Down