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
2 changes: 1 addition & 1 deletion .github/workflows/package-openai-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
if [[ "$RELEASE_TAG" =~ ^v?([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then
package_version="${BASH_REMATCH[1]}"
else
echo "::error::Release tag must be a SemVer version such as v0.3.1 or 0.3.1 (got $RELEASE_TAG)."
echo "::error::Release tag must be a SemVer version such as v0.3.2 or 0.3.2 (got $RELEASE_TAG)."
exit 1
fi

Expand Down
10 changes: 6 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This repository packages one lihi plugin for Codex and one for Claude Code. Each
Production endpoint: `https://app.lihi.io/mcp/v1/tools`.
Develop endpoint: `https://app.lihidev.com/mcp/v1/tools`.

Checked-in runtime files must remain production-only. Develop identities and endpoints may appear in packaging code, CI, tests, and generated artifacts. The server advertises minimum plugin version `0.3.1` through `tools/list` metadata.
Checked-in runtime files must remain production-only. Develop identities and endpoints may appear in packaging code, CI, tests, and generated artifacts. The server advertises minimum plugin version `0.3.2` through `tools/list` metadata.

## Host and skill responsibilities

Expand Down Expand Up @@ -70,16 +70,17 @@ Source code, configuration, tests, logs, docs, changelogs, code comments, resear
| Tool | Input | Result | Client rule |
| --- | --- | --- | --- |
| `site_create` | `{url}` | `{short_url,long_url}` | Non-idempotent; no server-side long-URL reuse. |
| `account_status` | `{}` | AccountStatus | Current status, group name, and domain. |
| `account_status` | `{}` | AccountStatus | Account email, current status, group name, and domain. |
| `group_options` | `{}` | `groups[{id,name,is_current}]` | Non-empty; exactly one current; select by ID. |
| `account_switch_group` | `{group_id}` | AccountStatus | Use only a fresh returned ID, including `null`. |
| `domain_options` | `{}` | `domains[{hostname,type}]` | Owned-first presentation; exact-hostname selection. |
| `account_switch_domain` | `{domain}` | AccountStatus | Pass an exact case-sensitive returned hostname. |

AccountStatus requires `group_name:string|null`, `domain:string|null`, `short_urls.used`, nullable `short_urls.quota`, and `plan.name`, nullable `plan.expires_on`, and nullable `plan.next_renewal_on`.
AccountStatus requires a non-empty `email:string`, `group_name:string|null`, `domain:string|null`, `short_urls.used`, nullable `short_urls.quota`, and `plan.name`, nullable `plan.expires_on`, and nullable `plan.next_renewal_on`.

- Prefer `structuredContent`; parse the first text JSON block only as compatibility fallback.
- Treat `result.isError:true` as failure even with HTTP 200, and keep top-level JSON-RPC errors separate.
- For a general account-status response, display `帳號 Email:<email>` first and preserve the value exactly.
- Render `plan.next_renewal_on:null` as `續訂日期:-`.
- Preserve non-null group/domain display values exactly. Render `group_name:null` as `我的群組`, but do not infer a numeric selector ID from it.
- For group options, preserve non-null names. Synthesize `我的群組` only for null personal names and `未命名工作群組(ID:x)` only for null named-group labels.
Expand Down Expand Up @@ -112,6 +113,7 @@ The develop packager:

- derives a shared `major.minor.patch` core from both host manifests;
- rewrites copied identities, endpoints, four skill folders, manifests, marketplaces, and Codex metadata only inside staging;
- adds `+codex.<build-number>` only to the staged Codex develop manifest; production manifests and the Claude develop manifest have no Codex cachebuster;
- emits `DEVELOP_BUILD.json`, where authoritative `skill_names` contains all four develop skills;
- retains singular `skill_name` at root and `plugins[0]` as a deprecated alias equal to `skill_names[0]` for 0.3 compatibility;
- excludes caches and preserves source runtime files unchanged.
Expand All @@ -126,7 +128,7 @@ archive has one same-named top-level skill directory. It does not accept an app
ID and does not emit a complete plugin ZIP, marketplace, manifest, MCP config,
app config, or shared asset.

Both manifests must share core version `0.3.1`. Codex may add one cachebuster suffix. When modifying the Codex bundle, run the plugin-creator cachebuster helper last and validate the plugin. Reinstall only when explicitly requested; after reinstall, test from a new conversation.
Both checked-in production manifests must use version `0.3.2` without build metadata. A Codex cachebuster is allowed only in a generated develop bundle. Validate the Codex plugin after modifying its bundle. Reinstall only when explicitly requested; after reinstall, test from a new conversation.

Never commit `dist/`, a develop/localhost runtime URL, or a develop identity in production runtime configuration.

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Use lihi account status, group and short URL domain switching, and URL shortenin

### `lihi@lihi`

- Shows short URL usage, quota, subscription dates, current work group, and current short URL domain.
- Shows the account email, short URL usage, quota, subscription dates, current work group, and current short URL domain.
- Switches the active work group or short URL domain after checking fresh choices.
- Works while polishing copy or preparing human-facing content for release.
- Automatically shortens every eligible new long URL detected in that content.
Expand Down Expand Up @@ -94,7 +94,7 @@ Which work group am I currently using?
Show my lihi account information.
```

The last, general request uses `account_status` and displays short URL usage, current plan, renewal date, current work group, and current short URL domain in that order. Ask for available groups separately when you need the full list.
The last, general request uses `account_status` and displays the account email first, followed by short URL usage, current plan, renewal date, current work group, and current short URL domain. Ask for available groups separately when you need the full list.

To switch the active work group:

Expand Down
4 changes: 2 additions & 2 deletions README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

### `lihi@lihi`

- 顯示短網址用量、額度、訂閱日期、目前工作群組與目前短網址網域。
- 顯示帳號 email、短網址用量、額度、訂閱日期、目前工作群組與目前短網址網域。
- 先取得最新選項,再切換使用中的工作群組或短網址網域。
- 可在潤飾文案或準備對外內容時處理網址。
- 自動縮短該內容中所有符合條件的新長網址。
Expand Down Expand Up @@ -94,7 +94,7 @@ claude plugin install lihi@lihi
查看我的 lihi 帳號資訊
```

最後一個一般帳號資訊請求會使用 `account_status`,依序顯示短網址用量、目前方案、續訂日期、目前工作群組與目前短網址網域。需要完整群組清單時再另外詢問可用群組。
最後一個一般帳號資訊請求會使用 `account_status`,第一行顯示帳號 email,再依序顯示短網址用量、目前方案、續訂日期、目前工作群組與目前短網址網域。需要完整群組清單時再另外詢問可用群組。

如需切換使用中的工作群組:

Expand Down
8 changes: 4 additions & 4 deletions docs/acceptance-scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ These scenarios apply to both production host bundles and their generated develo
| ID | Scenario | Expected result |
| --- | --- | --- |
| A1 | Inspect either host bundle | Exactly four skills and one shared OAuth MCP registration exist. |
| A2 | Inspect tool metadata | Six current tools are documented and minimum plugin version is 0.3.1. |
| A2 | Inspect tool metadata | Six current tools are documented and minimum plugin version is 0.3.2. |
| A3 | Build develop artifact | Four `-dev` skills, `lihi-dev` identities, and develop endpoint appear; production runtime remains unchanged. |
| A4 | Inspect requests with `Origin` | The contract does not reject solely because `Origin` is present and does not overclaim browser support. |

## B. Account status

| ID | Request/result | Expected result |
| --- | --- | --- |
| B1 | General account status | Call only `account_status`; show usage, plan, renewal, group, and domain in order. |
| B2 | Current group or current domain | Call only `account_status`; show only requested selector lines and no pricing guidance. |
| B1 | General account status | Call only `account_status`; show account email first, followed by usage, plan, renewal, group, and domain in order. |
| B2 | Account email, current group, or current domain | Call only `account_status`; show only requested lines and no pricing guidance. |
| B3 | Available groups | Call only `group_options`; require one current entry and list requested choices. |
| B4 | Status plus available groups | Call both read-only tools; preserve a valid section if the other fails. |
| B5 | Null status values | Render unlimited/no-expiration/dash-renewal/personal-group/unknown-domain text; `next_renewal_on:null` becomes `續訂日期:-`, and `group_name:null` becomes `目前工作群組:我的群組` without inferring a numeric ID. |
| B6 | Non-null server labels | Preserve `group_name`, domain, and option names exactly; do not append a personal suffix. |
| B6 | Non-null server values | Preserve email, `group_name`, domain, and option names exactly; do not append a personal suffix. |

## C. Group switching

Expand Down
20 changes: 11 additions & 9 deletions docs/mcp-contract.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# lihi MCP client contract

This document defines the 0.3.1 agent-side contract for the production Streamable HTTP endpoint:
This document defines the 0.3.2 agent-side contract for the production Streamable HTTP endpoint:

```text
https://app.lihi.io/mcp/v1/tools
```

Codex and Claude Code own transport and OAuth. Each plugin registers one MCP server and exposes the same six tools through four skills. `tools/list` advertises `_meta["lihi/plugin"].minVersion` as `0.3.1`.
Codex and Claude Code own transport and OAuth. Each plugin registers one MCP server and exposes the same six tools through four skills. `tools/list` advertises `_meta["lihi/plugin"].minVersion` as `0.3.2`.

Requests containing an `Origin` header are not rejected solely for that header. This contract does not claim complete browser or CORS support.

Expand Down Expand Up @@ -38,6 +38,7 @@ Input is `{}`. Output is exactly the AccountStatus shape:

```json
{
"email": "non-empty string",
"group_name": "string or null",
"domain": "string or null",
"short_urls": {"used": 0, "quota": "non-negative integer or null"},
Expand All @@ -49,15 +50,16 @@ Input is `{}`. Output is exactly the AccountStatus shape:
}
```

`quota:null` means unlimited. Null dates do not imply cancellation or payment failure. `group_name` is display-only: render `group_name:null` as `我的群組`, but never infer a numeric group ID from it. Preserve non-null `group_name` and `domain` exactly.
`quota:null` means unlimited. Null dates do not imply cancellation or payment failure. `group_name` is display-only: render `group_name:null` as `我的群組`, but never infer a numeric group ID from it. Preserve `email` and non-null `group_name` and `domain` exactly.

For a full Chinese status, render in this order:

1. `短網址用量:<used> / <quota>`; null quota → `無上限`.
2. `目前方案:<name>(到期日:<expires_on>)`; null expiration → `目前方案:<name>(無到期日)`.
3. `續訂日期:<next_renewal_on>`; null → `續訂日期:-`.
4. `目前工作群組:<group_name>`; null → `目前工作群組:我的群組`.
5. `目前短網址網域:<domain>`; null → `目前短網址網域:未回傳可用網域`.
1. `帳號 Email:<email>`.
2. `短網址用量:<used> / <quota>`; null quota → `無上限`.
3. `目前方案:<name>(到期日:<expires_on>)`; null expiration → `目前方案:<name>(無到期日)`.
4. `續訂日期:<next_renewal_on>`; null → `續訂日期:-`.
5. `目前工作群組:<group_name>`; null → `目前工作群組:我的群組`.
6. `目前短網址網域:<domain>`; null → `目前短網址網域:未回傳可用網域`.

Show pricing guidance only when usage, plan, or renewal is included.

Expand Down Expand Up @@ -110,7 +112,7 @@ Successful output commits the selector and is displayed directly without another

## Skill routing

- General account status, usage, plan, current group, or current domain → `account_status`.
- General account status, account email, usage, plan, current group, or current domain → `account_status`.
- Available work-group list → `group_options`.
- Requests covering both status/current selectors and available groups → both read-only tools.
- Group mutation → fresh `group_options`, then `account_switch_group`.
Expand Down
26 changes: 14 additions & 12 deletions docs/openai-platform-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ python3 scripts/package_openai_platform_bundle.py \
```

The script derives the shared `major.minor.patch` version from the Codex and
Claude production manifests. For version `0.3.1`, the only outputs are:
Claude production manifests. For version `0.3.2`, the only outputs are:

```text
dist/openai-platform/lihi-shorten-0.3.1.zip
dist/openai-platform/lihi-account-0.3.1.zip
dist/openai-platform/lihi-switch-group-0.3.1.zip
dist/openai-platform/lihi-switch-domain-0.3.1.zip
dist/openai-platform/lihi-shorten-0.3.2.zip
dist/openai-platform/lihi-account-0.3.2.zip
dist/openai-platform/lihi-switch-group-0.3.2.zip
dist/openai-platform/lihi-switch-domain-0.3.2.zip
```

Each ZIP contains exactly one same-named top-level skill directory. For
example, `lihi-shorten-0.3.1.zip` contains `lihi-shorten/SKILL.md` plus that
example, `lihi-shorten-0.3.2.zip` contains `lihi-shorten/SKILL.md` plus that
skill's approved `agents/`, `references/`, and `scripts/` files.

The packager does not accept an app ID and does not create a complete plugin,
Expand Down Expand Up @@ -54,27 +54,29 @@ python3 scripts/package_production_bundle.py \
--output-dir dist/production
```

For version `0.3.1`, this creates:
For version `0.3.2`, this creates:

```text
dist/production/lihi-agent-0.3.1/
dist/production/lihi-agent-0.3.2/
```

This installable directory retains the production `lihi@lihi` marketplace,
the `lihi` MCP identity, all four production skill names, and
`https://app.lihi.io/mcp/v1/tools`. It contains both Codex and Claude Code
plugin roots. The existing `package_develop_bundle.py` remains isolated to the
`lihi-dev` identity and the lihidev endpoint.
`lihi-dev` identity and the lihidev endpoint. Only its staged Codex develop
manifest adds `+codex.<build-number>`; production manifests and the staged
Claude develop manifest keep versions without Codex build metadata.

## Build from a release tag

Pushing a SemVer tag runs `.github/workflows/package-openai-platform.yml`.
Both `v0.3.1` and `0.3.1` tag forms are accepted. The tag must match the shared
Both `v0.3.2` and `0.3.2` tag forms are accepted. The tag must match the shared
Codex and Claude production manifest version.

```bash
git tag v0.3.1
git push origin v0.3.1
git tag v0.3.2
git push origin v0.3.2
```

The workflow runs unit tests, syntax checks, host parity checks, and whitespace
Expand Down
2 changes: 1 addition & 1 deletion plugins/claude/lihi/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lihi",
"displayName": "lihi",
"version": "0.3.1",
"version": "0.3.2",
"description": "Connect Claude Code to lihi through one OAuth MCP registration for account status, group and domain switching, and automatic URL shortening.",
"author": {
"name": "lihi",
Expand Down
4 changes: 2 additions & 2 deletions plugins/claude/lihi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ https://app.lihi.io/mcp/v1/tools

Its four skills share this single registration:

- `lihi-account` reads account status, current group and domain, and available groups.
- `lihi-account` reads the account email and status, current group and domain, and available groups.
- `lihi-switch-group` switches the active work group from fresh `group_options`.
- `lihi-switch-domain` switches the short URL domain from fresh `domain_options`.
- `lihi-shorten` automatically shortens eligible new URLs in revised outbound copy.
Expand All @@ -21,7 +21,7 @@ Claude Code owns OAuth and token refresh. With prior authorization, an ordinary

## Account and selector behavior

`account_status` provides usage, plan, renewal, current work group, and current short URL domain. `group_options` is used only for available-group lists. Both selector skills fetch fresh options before mutation and display the complete AccountStatus returned by a successful switch without another lookup. A Chinese domain selection list distinguishes dedicated domains (`owned`) from public domains (`public`), recommends a dedicated domain, and links to `https://lihidomain.com/` without selecting an option.
`account_status` provides the account email, usage, plan, renewal, current work group, and current short URL domain. General status answers display the account email first. `group_options` is used only for available-group lists. Both selector skills fetch fresh options before mutation and display the complete AccountStatus returned by a successful switch without another lookup. A Chinese domain selection list distinguishes dedicated domains (`owned`) from public domains (`public`), recommends a dedicated domain, and links to `https://lihidomain.com/` without selecting an option.

A selector change may revoke the current access token while leaving refresh authorization valid. Claude Code refreshes only when the next lihi request needs access. Possibly dispatched switch calls are never replayed blindly.

Expand Down
4 changes: 2 additions & 2 deletions plugins/claude/lihi/README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ https://app.lihi.io/mcp/v1/tools

四個技能共用這一個註冊:

- `lihi-account`:讀取帳號狀態、目前群組與網域,以及可用群組。
- `lihi-account`:讀取帳號 email 與狀態、目前群組與網域,以及可用群組。
- `lihi-switch-group`:依最新 `group_options` 切換工作群組。
- `lihi-switch-domain`:依最新 `domain_options` 切換短網址網域。
- `lihi-shorten`:自動縮短已調整對外文案中的符合條件新網址。
Expand All @@ -21,7 +21,7 @@ OAuth 與權杖更新由 Claude Code 管理。已有授權時,一般工具端

## 帳號與選擇器行為

`account_status` 提供用量、方案、續訂日期、目前工作群組與目前短網址網域。只有查詢可用群組清單時才使用 `group_options`。兩個切換技能都會在異動前取得最新選項,成功後直接顯示 switch 回傳的完整 AccountStatus,不追加查詢。中文網域選項將 owned 標示為「專屬網域 (owned)」、public 標示為「公用網域 (public)」,並建議選擇專屬網域、提供 `https://lihidomain.com/`,但不會自動選擇。
`account_status` 提供帳號 email、用量、方案、續訂日期、目前工作群組與目前短網址網域;一般帳號狀態會先顯示帳號 email。只有查詢可用群組清單時才使用 `group_options`。兩個切換技能都會在異動前取得最新選項,成功後直接顯示 switch 回傳的完整 AccountStatus,不追加查詢。中文網域選項將 owned 標示為「專屬網域 (owned)」、public 標示為「公用網域 (public)」,並建議選擇專屬網域、提供 `https://lihidomain.com/`,但不會自動選擇。

選擇器異動可能撤銷目前 access token,但 refresh 授權仍有效;Claude Code 只在下一個 lihi 請求需要時更新。可能已送出的切換請求不會被盲目重播。

Expand Down
Loading