Skip to content

Commit 3c2b9c1

Browse files
committed
fix: align plugin packaging with platform standards
1 parent f133ed9 commit 3c2b9c1

24 files changed

Lines changed: 465 additions & 83 deletions

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"name": "ai-inner-os",
1313
"description": "Claude Code hook-based plugin scaffold for visible AI inner monologue.",
14-
"version": "0.7.1",
14+
"version": "0.7.2",
1515
"source": "./",
1616
"author": {
1717
"name": "SummerSec",

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ai-inner-os",
3-
"version": "0.7.1",
3+
"version": "0.7.2",
44
"description": "Makes Claude Code sessions expose a visible Inner OS monologue layer in the format ▎InnerOS:...",
55
"author": {
66
"name": "SummerSec",

.cursor-plugin/marketplace.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "ai-inner-os-cursor",
3+
"metadata": {
4+
"description": "Cursor plugin packaging for AI Inner OS, exposing a visible Inner OS monologue layer through rules and hooks."
5+
},
6+
"owner": {
7+
"name": "SummerSec",
8+
"url": "https://github.com/SummerSec"
9+
},
10+
"plugins": [
11+
{
12+
"name": "ai-inner-os",
13+
"description": "Visible Inner OS monologue layer for Cursor sessions.",
14+
"version": "0.7.2",
15+
"source": "./",
16+
"author": {
17+
"name": "SummerSec",
18+
"url": "https://github.com/SummerSec"
19+
},
20+
"category": "productivity",
21+
"tags": [
22+
"agent-context",
23+
"rules",
24+
"hooks"
25+
]
26+
}
27+
]
28+
}

.cursor-plugin/plugin.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "ai-inner-os",
3+
"displayName": "AI Inner OS",
4+
"version": "0.7.2",
5+
"description": "Expose a visible Inner OS monologue layer in Cursor sessions, with optional hook-based event context and persona-aware protocol injection.",
6+
"author": {
7+
"name": "SummerSec",
8+
"url": "https://github.com/SummerSec"
9+
},
10+
"homepage": "https://github.com/SummerSec/AI-Inner-Os",
11+
"repository": "https://github.com/SummerSec/AI-Inner-Os",
12+
"license": "Apache-2.0",
13+
"keywords": [
14+
"cursor",
15+
"inner-os",
16+
"agent",
17+
"rules",
18+
"hooks",
19+
"persona"
20+
],
21+
"category": "productivity",
22+
"tags": [
23+
"agent-context",
24+
"rules",
25+
"hooks"
26+
],
27+
"rules": "./cursor/rules/",
28+
"hooks": "./cursor/hooks.json"
29+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ state/*.log
55
.claude/
66
personas/_active.json
77
docs/superpowers/
8+
.cursor/

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.7.2] - 2026-05-10
9+
10+
### Fixed
11+
12+
- **Claude Code plugin**: Store session state and active persona under `${CLAUDE_PLUGIN_DATA}` so marketplace installs keep persistent data across plugin cache updates.
13+
- **Persona switching**: Avoid modifying plugin cache source files when `/inner-os persona use` runs inside Claude Code; repository and global-install workflows still update platform adapter files.
14+
815
## [0.7.1] - 2026-04-16
916

1017
### Fixed
@@ -54,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5461

5562
- Persona system: preset personas, custom template, `/inner-os` command updates, and persona sections in platform adapter docs.
5663

64+
[0.7.2]: https://github.com/SummerSec/AI-Inner-Os/releases/tag/v0.7.2
5765
[0.7.1]: https://github.com/SummerSec/AI-Inner-Os/releases/tag/v0.7.1
5866
[0.7.0]: https://github.com/SummerSec/AI-Inner-Os/releases/tag/v0.7.0
5967
[0.6.1]: https://github.com/SummerSec/AI-Inner-Os/releases/tag/v0.6.1

CLAUDE.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,22 @@ Stop → deletes session state file
4444

4545
### Persona Switching Script
4646

47-
`scripts/switch-persona.js` handles cross-platform persona switching. It reads persona files from `personas/`, updates `personas/_active.json`, and injects the persona content between `<!-- ACTIVE_PERSONA_START -->` / `<!-- ACTIVE_PERSONA_END -->` markers in all 6 platform adapter files. The `/inner-os persona use` command calls this script via Bash.
47+
`scripts/switch-persona.js` handles persona switching for both repository/global-install workflows and Claude Code plugin runtime:
48+
49+
- Repository/global install: reads persona files from `personas/`, updates `personas/_active.json`, and injects persona content between `<!-- ACTIVE_PERSONA_START -->` / `<!-- ACTIVE_PERSONA_END -->` markers in all platform adapter files.
50+
- Claude Code plugin runtime: when `CLAUDE_PLUGIN_DATA` is present, writes the active persona to `${CLAUDE_PLUGIN_DATA}/personas/_active.json` and does **not** modify plugin cache source files.
51+
- `/inner-os persona use` calls this script via Bash from the installed Claude Code plugin.
4852

4953
### hooks/lib/ — Shared Logic
5054

5155
All hook scripts (including codex/ and cursor/ adapters) import from `hooks/lib/`:
5256

5357
- **io.js** — stdin JSON reader, stdout JSON/text writers (the I/O boundary)
54-
- **state.js** — per-session JSON files in `state/`, recent-events ring buffer (max 10), consecutive failure counter
58+
- **state.js** — per-session JSON files in `${CLAUDE_PLUGIN_DATA}/state/` for Claude Code plugin installs, falling back to repo `state/` outside plugin runtime; recent-events ring buffer (max 10), consecutive failure counter
5559
- **events.js**`inferEventType()` classifies tools by name; `inferResult()` derives success/failure; `normalizeToolEvent()` / `normalizeFailureEvent()` produce structured events; `extractToolTarget()` pulls the key field from tool input
5660
- **prompt.js** — builds all `additionalContext` strings: session-start protocol, pre-tool context, post-tool recent-event context, failure context
5761
- **session.js** — extracts session ID from various payload field names
58-
- **constants.js** — plugin ID, prefix `▎InnerOS:`, paths (STATE_DIR, SKILL_PATH), event type/result enums
62+
- **constants.js** — plugin ID, prefix `▎InnerOS:`, paths (PLUGIN_DATA_DIR, STATE_DIR, SKILL_PATH, persona paths), event type/result enums
5963

6064
### Multi-Platform Adaptation
6165

@@ -75,13 +79,39 @@ Platforms degrade gracefully in hook richness:
7579
- `hooks/hooks.json` — Claude Code hook registration (the authoritative config)
7680
- `.claude-plugin/plugin.json` — plugin identity for Claude Code
7781
- `.claude-plugin/marketplace.json` — local marketplace listing
82+
- `.cursor-plugin/plugin.json` — plugin identity and component paths for Cursor plugin packaging
83+
- `.cursor-plugin/marketplace.json` — Cursor marketplace metadata
7884
- `plugin.json` — repo-level metadata
79-
- Version must be bumped in all three `plugin.json` / `package.json` files for updates to reach installed users
85+
- Version must be bumped across all platform manifests and package metadata for updates to reach installed users: `package.json`, `plugin.json`, `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `.cursor-plugin/plugin.json`, `.cursor-plugin/marketplace.json`, and `openclaw.plugin.json`
86+
87+
### Claude Code Plugin Standards
88+
89+
Follow the Claude Code plugin reference when changing Claude plugin packaging:
90+
91+
- The Claude Code manifest lives at `.claude-plugin/plugin.json`. Only manifest files belong under `.claude-plugin/`; component directories stay at the plugin root.
92+
- Default component locations are root-level `commands/`, `skills/`, `agents/`, `hooks/hooks.json`, `.mcp.json`, `.lsp.json`, `output-styles/`, `themes/`, and `monitors/`.
93+
- Custom component paths in `.claude-plugin/plugin.json` must be relative to the plugin root and start with `./`. Do not use absolute paths or `..` traversal.
94+
- Hook commands bundled with the plugin must reference plugin files through `${CLAUDE_PLUGIN_ROOT}`. Do not assume the repository checkout path exists after marketplace installation.
95+
- Persistent state must go under `${CLAUDE_PLUGIN_DATA}`. Do not write mutable runtime data, active persona settings, caches, or generated files into the plugin root/cache.
96+
- Marketplace installs are cached by plugin version. If `.claude-plugin/plugin.json` has an explicit `version`, bump it for every published update; pushing commits alone is not enough.
97+
- Validate packaging changes with `claude plugin validate .`, then run `npm run check` and `npm test`.
98+
99+
### Cursor Plugin Standards
100+
101+
This repository also ships Cursor plugin metadata because AI Inner OS is multi-platform:
102+
103+
- Cursor plugin metadata lives in `.cursor-plugin/plugin.json`; `.cursor-plugin/marketplace.json` is the Cursor marketplace metadata entry.
104+
- The current Cursor design uses `cursor/` as the plugin component directory. `.cursor-plugin/plugin.json` points to `rules: "./cursor/rules/"` and `hooks: "./cursor/hooks.json"`.
105+
- Cursor component paths must be relative, stay inside the plugin/repository root, and must not use absolute paths or `..` traversal.
106+
- Cursor rules are `.mdc` files with YAML frontmatter. `cursor/rules/inner-os-protocol.mdc` must keep `description` and `alwaysApply: true`.
107+
- Cursor hooks use lowercase event names in this repo's Cursor adapter: `sessionStart`, `postToolUse`, and `stop`. Cursor hook output uses top-level `{ "additional_context": "..." }`.
108+
- Cursor `preToolUse` is intentionally not used for context injection because it cannot inject `additional_context`.
109+
- Keep Cursor documentation in `cursor/README.md` and `docs/install-cursor.md` aligned with `.cursor-plugin/plugin.json` and `cursor/hooks.json`.
80110

81111
### Key Patterns
82112

83113
- Every hook wraps its body in `try/catch` and fails silently — hook errors never interrupt the session
84-
- Session state files live in `state/` (gitignored), keyed by sanitized session ID
114+
- Claude Code plugin session state files live in `${CLAUDE_PLUGIN_DATA}/state/`; repo/global-install fallback state files live in `state/` (gitignored), keyed by sanitized session ID
85115
- `failureCount` increments on consecutive failures, resets to 0 on any success
86116
- Claude Code: PreToolUse uses `hookSpecificOutput.additionalContext`; PostToolUse/PostToolUseFailure output plain text to stdout
87117
- Cursor: sessionStart/postToolUse use `{ additional_context: string }` top-level format; preToolUse removed (can't inject context)

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ See [codex/README.md](codex/README.md) | [Detailed installation guide](docs/inst
9999
### Cursor
100100

101101
```bash
102-
# Copy rule file to project
103-
mkdir -p .cursor/rules
104-
cp cursor/rules/inner-os-protocol.mdc .cursor/rules/
102+
# Install Cursor adapter globally
103+
node scripts/install.js --platform cursor
105104
```
106105

106+
The repository also includes `.cursor-plugin/plugin.json`, which packages `cursor/` as a Cursor plugin component directory.
107+
107108
See [cursor/README.md](cursor/README.md) | [Detailed installation guide](docs/install-cursor.md).
108109

109110
### OpenCode CLI

README_CN.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ cp codex/hooks.json ~/.codex/hooks.json
9999
### Cursor
100100

101101
```bash
102-
# 复制规则文件到项目
103-
mkdir -p .cursor/rules
104-
cp cursor/rules/inner-os-protocol.mdc .cursor/rules/
102+
# 全局安装 Cursor 适配
103+
node scripts/install.js --platform cursor
105104
```
106105

106+
仓库也包含 `.cursor-plugin/plugin.json`,会将 `cursor/` 目录作为 Cursor 插件组件目录声明。
107+
107108
详见 [cursor/README.md](cursor/README.md) | [详细安装指南](docs/install-cursor.md)
108109

109110
### OpenCode CLI

commands/inner-os.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ argument-hint: "[status|on|off|reload|persona list|persona use <name>|persona sh
1515

1616
1. 确认 Inner OS 协议是否已注入(本命令被加载即表示插件已安装)
1717
2. 展示当前独白前缀:`▎InnerOS:`
18-
3. 读取 `personas/_active.json` 展示当前人设名称
18+
3. 读取插件数据目录中的 `personas/_active.json` 展示当前人设名称;如果不存在,视为 `default`
1919
4. 用一句 Inner OS 独白证明它正在工作
2020

2121
示例输出:
@@ -58,23 +58,24 @@ Inner OS 状态:已启用
5858

5959
1. 读取 `personas/` 目录下的所有 `.md` 文件(排除 README)
6060
2. 读取 `personas/custom/` 目录下的所有 `.md` 文件
61-
3. 从每个文件的 YAML frontmatter 中提取 `name``displayName``description`
62-
4. 以表格形式展示,标记当前激活的人设
61+
3. 读取插件数据目录中 `personas/custom/` 下的自定义 `.md` 文件
62+
4. 从每个文件的 YAML frontmatter 中提取 `name``displayName``description`
63+
5. 以表格形式展示,标记当前激活的人设
6364

6465
### `persona use <name>`
6566

6667
切换到指定人设:
6768

6869
1. 调用切换脚本:`node "${CLAUDE_PLUGIN_ROOT}/scripts/switch-persona.js" <name>`
69-
2. 脚本会自动更新 `personas/_active.json` 并将人设内容注入到所有平台适配文件中
70+
2. 在 Claude Code 插件运行时,脚本会更新 `${CLAUDE_PLUGIN_DATA}/personas/_active.json`,不会修改插件缓存中的源码文件
7071
3. 如果人设不存在,脚本会报错并提示运行 `--list` 查看可用选项
7172
4. 切换成功后,立刻用新人设的风格输出一句独白作为确认
7273

7374
### `persona show`
7475

7576
显示当前激活的人设:
7677

77-
1. 读取 `personas/_active.json` 获取当前人设名称
78+
1. 读取插件数据目录中的 `personas/_active.json` 获取当前人设名称
7879
2. 如果文件不存在或无法读取,视为 `default`
7980
3. 读取对应人设文件,展示名称和风格描述
8081

@@ -83,6 +84,6 @@ Inner OS 状态:已启用
8384
恢复到自由模式:
8485

8586
1. 调用切换脚本:`node "${CLAUDE_PLUGIN_ROOT}/scripts/switch-persona.js" default`
86-
2. 脚本会清空所有平台适配文件中的人设内容,并将 `_active.json` 设为 `default`
87+
2. 在 Claude Code 插件运行时,脚本会将 `${CLAUDE_PLUGIN_DATA}/personas/_active.json` 设为 `default`,不会修改插件缓存中的源码文件
8788
3. 确认已恢复自由模式
8889
4. 用一句自由风格的独白确认

0 commit comments

Comments
 (0)