pi-codex-marketplace 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -3
- package/bin/pi-codex-marketplace.js +12 -0
- package/bin/ts-resolver.mjs +15 -0
- package/extensions/pi/autocomplete.ts +90 -0
- package/extensions/pi/index.ts +19 -0
- package/package.json +6 -2
- package/src/bridge/command.ts +102 -208
- package/src/bridge/completion.ts +521 -0
- package/src/bridge/plugin-query.ts +233 -0
- package/src/cli/index.ts +85 -0
package/README.md
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Bridge Package for Codex and Claude Marketplace compatibility in Pi (`Pi 0.84.2`).
|
|
4
4
|
|
|
5
|
-
> **One-line:** `pi install npm:pi-codex-marketplace` → `/codex-marketplace add <本機資料夾|GitHub
|
|
5
|
+
> **One-line:** `pi install npm:pi-codex-marketplace` → `/codex-marketplace add <本機資料夾|GitHub 網址>`(或 Shell 下 `npx pi-codex-marketplace add ...`)註冊 marketplace → `install <編號>` 裝到當下最新並在 Pi 可用。
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
+
### Pi Extension(TUI / 互動環境)
|
|
10
|
+
|
|
9
11
|
```bash
|
|
10
12
|
pi install npm:pi-codex-marketplace # Global package (writes to ~/.pi/agent/settings.json)
|
|
11
13
|
pi install npm:pi-codex-marketplace -l # Project package location (.pi/settings.json; Pi host package setting only)
|
|
@@ -19,6 +21,17 @@ pi list # List installed packages
|
|
|
19
21
|
pi config # Enable/disable resources
|
|
20
22
|
```
|
|
21
23
|
|
|
24
|
+
### Headless CLI(Shell / CI/CD 自動化)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 免安裝直接以 npx 執行
|
|
28
|
+
npx pi-codex-marketplace [subcommand]
|
|
29
|
+
|
|
30
|
+
# 或全域安裝使用
|
|
31
|
+
npm install -g pi-codex-marketplace
|
|
32
|
+
pi-codex-marketplace [subcommand]
|
|
33
|
+
```
|
|
34
|
+
|
|
22
35
|
Source types follow `docs/packages.md`: `npm:` for registry, `git:`/`https://` for git, and absolute/relative paths for local. Ephemeral runs use `pi -e <source>` (not `pi install -e`). This package declares a single `pi` extension entry (`extensions/pi/index.ts`) loaded via `jiti` and requires no build step.
|
|
23
36
|
|
|
24
37
|
> [!NOTE]
|
|
@@ -53,6 +66,28 @@ Nine subcommands, no arguments = 總覽:
|
|
|
53
66
|
- 安裝成功後由指令層主動要求 reload;reload 失敗不影響已記錄狀態,下次 session start 或 `/reload` 仍生效。
|
|
54
67
|
- `--no-skills` 啟動 Pi 不影響 Bridge 投影。
|
|
55
68
|
|
|
69
|
+
### Autocomplete(Pi 原生,TUI 限定)
|
|
70
|
+
|
|
71
|
+
互動(TUI)模式下,`/codex-marketplace` 以 **Pi 原生 autocomplete** 提供兩層、狀態感知的候選。**純文字指令表面維持權威不變**:九個子命令、指令參數、輸出與語意完全不受 autocomplete 影響;RPC/JSON/print 模式根本不註冊 terminal-only provider。
|
|
72
|
+
|
|
73
|
+
**第一層——九個根層子命令。** 輸入完整的 `/codex-marketplace` 後按 Tab,候選清單顯示全部九個子命令(`add`/`list`/`install`/`update`/`disable`/`enable`/`remove`/`forget`/`help`)與各自說明,支援不分大小寫的模糊搜尋。選取需要參數的子命令(`add`/`list`/`install`/`disable`/`enable`/`remove`/`forget`)會自動補上一個尾隨空格,可直接繼續輸入;`update` 與 `help` 不加。
|
|
74
|
+
|
|
75
|
+
**第二層——再按一次 Tab 開啟狀態感知候選。** 需要參數的子命令套用後,**再按一次 Tab** 依當下 Bridge State 只列出當下可執行的選項(空集合不給假候選);**不承諾自動重開 selector**(Pi 0.84.2 在套用候選後不會自動再開一層補完選單,鍵盤流程固定是「輸入 command → Tab 選子命令 → 需要參數時再按一次 Tab」):
|
|
76
|
+
|
|
77
|
+
| 子命令 | 候選範圍 | 歧義處理 |
|
|
78
|
+
|--------|----------|----------|
|
|
79
|
+
| `install` | 可安裝/可重裝的 plugin(**不含 Unavailable Entry**) | 名稱在完整 enumeration 唯一=插入名稱;同名(含 unavailable sibling)=插入 enumeration 編號(`#N`),描述顯示 `[marketplace]` 與狀態 |
|
|
80
|
+
| `enable` | 僅**已停用**的 Installation | 名稱無法唯一解析的記錄不給候選 |
|
|
81
|
+
| `disable` | 僅**已啟用**的 Installation | 同上 |
|
|
82
|
+
| `remove` | 全部已安裝 plugin(不分啟用/停用) | 同上 |
|
|
83
|
+
| `list` | Marketplace Registrations | 名稱無法唯一解析=依序改插唯一可解析的 alias、其次 Registration id |
|
|
84
|
+
| `forget` | Marketplace Registrations | 同上 |
|
|
85
|
+
| `add` | **不提供 Bridge 候選**:Tab 委派 Pi 原生路徑 completion,Git locator 維持自由輸入 | — |
|
|
86
|
+
|
|
87
|
+
補完只提議當下可執行的動作,候選反映最新 Bridge State,且**被動讀取**——按 Tab 絕不會重置或重寫損壞的 state 文件。其餘輸入(其他 slash 指令、一般文字、檔案/路徑補完)一律原樣委派 Pi 既有 provider;安裝本套件不影響任何其他指令的 autocomplete。
|
|
88
|
+
|
|
89
|
+
> 沒有 custom TUI、沒有自動第二層 selector:所有操作也都可以照舊以純文字輸入完成,autocomplete 只是 discoverability 與輸入效率層。
|
|
90
|
+
|
|
56
91
|
### 私有 Git repo:Credentialed Acquisition(核准式取得)
|
|
57
92
|
|
|
58
93
|
對私有 HTTPS repo,`add`/`update` **開箱即用**:預設會自動偵測本機已存在的憑證來源並逐次核准(**固定白名單**,不讀本機 gitconfig 的任意 helper;偵測結果只限該次呼叫、永不持久化):
|
|
@@ -93,6 +128,61 @@ Credentialed Acquisition 語意(安全線):
|
|
|
93
128
|
- 憑證由 SSH agent 提供,整個取得過程不互動(`BatchMode=yes`)、無任何提示;
|
|
94
129
|
- SSH 定位器本身仍維持 credential-free:不得內嵌密碼(`user:pass@` 拒絕);憑證只能經由 SSH agent 或 Credentialed Acquisition 到達取得流程。
|
|
95
130
|
|
|
131
|
+
## Headless Bridge CLI — `pi-codex-marketplace`
|
|
132
|
+
|
|
133
|
+
Bridge Package 除了提供 Pi Extension TUI 指令,亦內建純 Node 輕量 CLI bin shim(`pi-codex-marketplace` / `npx pi-codex-marketplace`),專為 CI/CD 流程、自動化腳本與純 Shell 環境設計。無須啟動 Pi TUI 或 Pi runtime,即可直接管理 Marketplace 註冊與外掛安裝。
|
|
134
|
+
|
|
135
|
+
### 執行方式
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 1. 無參數:總覽(列出已註冊 Marketplace、已安裝外掛與指令用法)
|
|
139
|
+
npx pi-codex-marketplace
|
|
140
|
+
|
|
141
|
+
# 2. 版本與說明
|
|
142
|
+
npx pi-codex-marketplace --version # 或 -v
|
|
143
|
+
npx pi-codex-marketplace help
|
|
144
|
+
|
|
145
|
+
# 3. 執行子命令(與 TUI 指令完全一致)
|
|
146
|
+
npx pi-codex-marketplace add <路徑|網址>
|
|
147
|
+
npx pi-codex-marketplace list [名稱]
|
|
148
|
+
npx pi-codex-marketplace install <編號|名稱>
|
|
149
|
+
npx pi-codex-marketplace update
|
|
150
|
+
npx pi-codex-marketplace disable <名稱>
|
|
151
|
+
npx pi-codex-marketplace enable <名稱>
|
|
152
|
+
npx pi-codex-marketplace remove <名稱>
|
|
153
|
+
npx pi-codex-marketplace forget <名稱>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 九個子命令一覽
|
|
157
|
+
|
|
158
|
+
| 子命令 | 行為 |
|
|
159
|
+
|--------|------|
|
|
160
|
+
| `add <路徑\|網址>` | 註冊 marketplace(本機資料夾、GitHub 完整網址、`owner/repo` 簡寫或 SSH 定位器),自動偵測並回報格式。重複來源拒絕。私有 HTTPS repo 支援固定白名單自動偵測與 `PI_CODEX_MARKETPLACE_CREDENTIAL_HELPERS` 環境變數。 |
|
|
161
|
+
| `list [名稱]` | 列出 plugins(編號/所屬 marketplace/狀態:可安裝・已裝啟用・已裝停用・unavailable+原因),支援 marketplace 名稱過濾。 |
|
|
162
|
+
| `install <編號\|名稱>` | 裝到當下最新並自動啟用。重複安裝=重抓最新覆寫(重裝=更新)。衝突時提示同名未投影警告。 |
|
|
163
|
+
| `update` | 對全部已註冊 marketplace 重抓最新並更新有變化的外掛。 |
|
|
164
|
+
| `disable <名稱>` / `enable <名稱>` | 停用/啟用 plugin。 |
|
|
165
|
+
| `remove <名稱>` | 移除單支 plugin(不動 marketplace 與來源資料)。 |
|
|
166
|
+
| `forget <名稱>` | 移除整個 marketplace 及其全部安裝。 |
|
|
167
|
+
| `help` | 輸出子命令清單與用法。 |
|
|
168
|
+
|
|
169
|
+
### 輸出與退出代碼契約(Output & Exit Contract)
|
|
170
|
+
|
|
171
|
+
CLI 遵循嚴格的標準命令列契約,確保 CI/CD 與腳本整合的確定性:
|
|
172
|
+
|
|
173
|
+
- **標準輸出(stdout)**:所有正常操作輸出(總覽、說明、版本、查詢清單、成功訊息)寫入 `stdout`,退出代碼為 `0`。
|
|
174
|
+
- **標準錯誤(stderr)**:所有錯誤情況(未知子命令、缺少或非法參數、重複註冊、目標不存在或歧義、Git 取得失敗等)寫入 `stderr`,退出代碼為非零(`1`)。
|
|
175
|
+
- **絕對免提示(Never prompt)**:全流程不發起任何終端互動提示(no interactive prompts),遇到歧義或錯誤立即明確報錯並退出,背景執行安全無虞。
|
|
176
|
+
|
|
177
|
+
### 狀態生效時機(Same-State Caveat)
|
|
178
|
+
|
|
179
|
+
- **單一 Global Scope 一致性**:CLI 與 Extension 共用相同的 `getAgentDir()` 與 Bridge State 儲存位址(`~/.pi/agent/codex-marketplace/state.json`),完全支援 `PI_CODING_AGENT_DIR` / `PI_AGENT_DIR` 環境變數覆寫。
|
|
180
|
+
- **無 In-process Reload 提示語轉換**:CLI 執行於 Pi 外部獨立 Node 行程,無 Pi runtime 內部的即時 reload 機制(`ctx.reload`)。狀態變更指令(`install`、`enable`、`update`)輸出將 TUI 的「已重新載入生效」替換為:
|
|
181
|
+
```
|
|
182
|
+
已寫入 Bridge State · 下次 pi session//reload 生效
|
|
183
|
+
```
|
|
184
|
+
- **投影時機**:CLI 寫入的變更已持久化至 Bridge State,將在下次啟動 Pi session 或於 Pi TUI 內執行 `/reload` 時,經由 Pi host 資源發現接縫(`resources_discover`)自動完成技能投影。
|
|
185
|
+
|
|
96
186
|
## Bridge State storage
|
|
97
187
|
|
|
98
188
|
Bridge State 是唯一權威,存於**單一 Global Scope 文件** `{getAgentDir()}/codex-marketplace/state.json`(`~/.pi/agent/codex-marketplace/state.json`):
|
|
@@ -118,7 +208,7 @@ See `src/bridge/state.ts`(Minimal Bridge State)、`src/bridge-state/atomic.t
|
|
|
118
208
|
| OS | **macOS**, **Linux** | Windows not supported (path containment, symlink, `flock` semantics are POSIX-only) |
|
|
119
209
|
| Node | **>=22.19.0** | `engines.node` enforced |
|
|
120
210
|
| Pi host | **0.84.2** | `peerDependencies` exact `0.84.2`; expected compatible range `^0.84.2` (devDeps). `pi-ai`/`pi-tui` peers `*` per Pi extension docs. |
|
|
121
|
-
| Semantics | `pi install` / `pi -e` / `pi install -l` / `pi update` / `pi remove` / `pi list` / `pi config` | Single `pi` extension package; `files` ships `extensions/`, `src/`, `README.md`, `LICENSE` only |
|
|
211
|
+
| Semantics | `pi install` / `pi -e` / `pi install -l` / `pi update` / `pi remove` / `pi list` / `pi config` + `npx pi-codex-marketplace` / `bin/pi-codex-marketplace.js` CLI | Single `pi` extension package + headless CLI bin; `files` ships `bin/`, `extensions/`, `src/`, `README.md`, `LICENSE` only |
|
|
122
212
|
|
|
123
213
|
Peer declaration (dual): **精確 `0.84.2`** in `peerDependencies` (exact host that this version was validated against) + **預期 `^0.84.2`** in `devDependencies` (range expected to remain compatible). `pi-ai` and `pi-tui` remain `*` because they are bundled by Pi.
|
|
124
214
|
|
|
@@ -137,7 +227,7 @@ Every row is a **release blocker**: `v*` may not publish unless the full matrix
|
|
|
137
227
|
| unit — 縫層 | `runCommand` 指令分派(add/list/install/update/disable/enable/remove/forget/help、重複註冊拒絕、重裝覆寫、衝突未投影清單、corrupt→重置、unavailable 顯示、git 重抓)、Minimal Bridge State 原子持久化 |
|
|
138
228
|
| unit — 低層 | 雙格式 catalog 解析(codex+claude、open 政策、unavailable entry)、git locator/source-key(fixed `default` selector)、contained path/symlink、collision、投影(exposure)、source-cache(store/hit/LRU/pin/flock)、git acquisition(mock executor) |
|
|
139
229
|
| integration | 真 Pi 縫:extension 註冊 `resources_discover` → 投影 skillPaths(startup/reload 一致、trust flag 無關、被動不變異) |
|
|
140
|
-
| E2E | `/codex-marketplace` 薄 Pi adapter
|
|
230
|
+
| E2E | `/codex-marketplace` 薄 Pi adapter 與 `pi-codex-marketplace` CLI 適配層(overview/help、--version、雙格式 add/list、install/update、lifecycle 停用啟用移除、狀態變更 reload 提示轉換、確定性退出碼與環境隔離) |
|
|
141
231
|
|
|
142
232
|
Fixtures: `tests/fixtures/synthetic/`, `tests/fixtures/pinned/`(captured `SamWang32191/codex-plugins@98e78ca` snapshot)、`tests/fixtures/adversarial/`。See `tests/acceptance/` for the matrix runner that enforces per-row gating (any row failure blocks publish).
|
|
143
233
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { register } from "node:module";
|
|
3
|
+
|
|
4
|
+
try {
|
|
5
|
+
register("./ts-resolver.mjs", import.meta.url);
|
|
6
|
+
} catch {
|
|
7
|
+
// Module registration unsupported or already active
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { runCli } = await import("../src/cli/index.js");
|
|
11
|
+
const code = await runCli(process.argv.slice(2), process);
|
|
12
|
+
process.exitCode = code;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
2
|
+
try {
|
|
3
|
+
return await nextResolve(specifier, context);
|
|
4
|
+
} catch (err) {
|
|
5
|
+
if (specifier.endsWith(".js")) {
|
|
6
|
+
const tsSpecifier = specifier.slice(0, -3) + ".ts";
|
|
7
|
+
try {
|
|
8
|
+
return await nextResolve(tsSpecifier, context);
|
|
9
|
+
} catch {
|
|
10
|
+
// Fall back to original error
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
throw err;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrow Bridge autocomplete provider — thin Pi adapter (TUI session only) (#119, #121–#124).
|
|
3
|
+
*
|
|
4
|
+
* Pi 0.84.2's built-in combined provider completes the slash-command name and inserts a
|
|
5
|
+
* trailing space without exposing empty-prefix argument completion (root subcommands) when
|
|
6
|
+
* the editor holds exactly `/codex-marketplace`. This wrapper intercepts that exact editor
|
|
7
|
+
* content and presents the nine root candidates. It also owns the second-level argument
|
|
8
|
+
* contexts (`install` #122, the Installation lifecycle `enable` / `disable` / `remove` #123,
|
|
9
|
+
* and the Marketplace Registration `list` / `forget` #124) on forced (Tab) requests, which
|
|
10
|
+
* Pi 0.84.2 routes to file completion instead of slash-command argument completion (its
|
|
11
|
+
* argument path only runs when `force` is false) — the wrapper returns the state-aware
|
|
12
|
+
* candidates there. `add` stays free-form (#124): its forced Tab keeps Pi's native
|
|
13
|
+
* filesystem completion, and a typed Git locator or path is never constrained by Bridge
|
|
14
|
+
* candidates. Everything else — other slash commands, text, file/path completion, suggestion
|
|
15
|
+
* generation and completion application — delegates unchanged to the host's current provider.
|
|
16
|
+
*
|
|
17
|
+
* The wrapper is installed from a `session_start` handler via `ctx.ui.addAutocompleteProvider`,
|
|
18
|
+
* which interactive (TUI) mode wires into the editor and RPC/JSON/print modes no-op, so a
|
|
19
|
+
* terminal-only provider is never registered outside a TUI session.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { AutocompleteProvider } from '@earendil-works/pi-tui';
|
|
23
|
+
|
|
24
|
+
import { completeArguments, type CompletionReadOptions } from '../../src/bridge/completion.js';
|
|
25
|
+
|
|
26
|
+
/** The exact editor content this provider owns. */
|
|
27
|
+
export const EXACT_COMMAND = '/codex-marketplace';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The Bridge-owned second-level argument contexts on forced requests: `install` plus the
|
|
31
|
+
* installation lifecycle actions plus the Marketplace Registration commands — each followed
|
|
32
|
+
* by the trailing space root candidates insert. `add` is deliberately absent (#124): its
|
|
33
|
+
* argument is an arbitrary path or Git locator that stays under Pi's native completion.
|
|
34
|
+
*/
|
|
35
|
+
export const SECOND_LEVEL_ARGUMENT_RE = /^\/codex-marketplace (?:install|list|forget|enable|disable|remove) /;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Wrap the host's current autocomplete provider. Suggestion generation intercepts only the
|
|
39
|
+
* Bridge-owned editor contexts (the exact `/codex-marketplace` line and the forced `install `
|
|
40
|
+
* argument context); completion application and file-trigger decisions delegate to the
|
|
41
|
+
* current provider's semantics, so selection behavior stays Pi-native.
|
|
42
|
+
*/
|
|
43
|
+
export function createBridgeAutocompleteProvider(
|
|
44
|
+
current: AutocompleteProvider,
|
|
45
|
+
readOptions: CompletionReadOptions = {},
|
|
46
|
+
): AutocompleteProvider {
|
|
47
|
+
return {
|
|
48
|
+
async getSuggestions(lines, cursorLine, cursorCol, options) {
|
|
49
|
+
const line = lines[cursorLine] ?? '';
|
|
50
|
+
// Root-level interception (#121): only when the editor content is exactly the complete
|
|
51
|
+
// command text — a mid-command cursor or trailing text after the command is not
|
|
52
|
+
// "editor 內容恰為 /codex-marketplace" and must fall through to the host provider.
|
|
53
|
+
if (line === EXACT_COMMAND && cursorCol === EXACT_COMMAND.length) {
|
|
54
|
+
const items = completeArguments('', readOptions);
|
|
55
|
+
if (items && items.length > 0) {
|
|
56
|
+
// The intercepted prefix is the whole line before the cursor (prefix ''), so the
|
|
57
|
+
// insertion value must carry the separator space the editor content lacks.
|
|
58
|
+
return {
|
|
59
|
+
items: items.map((item) => ({ ...item, value: ` ${item.value}` })),
|
|
60
|
+
prefix: '',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Second-level argument interception (#122, #123, #124): forced (Tab) requests inside a
|
|
65
|
+
// Bridge-owned argument context (`install ` / `enable ` / `disable ` / `remove ` /
|
|
66
|
+
// `list ` / `forget `) are Bridge-owned — the host's combined provider would route them
|
|
67
|
+
// to file completion. Natural typing (force=false) is delegated and reaches the same
|
|
68
|
+
// candidates through the command's getArgumentCompletions. Like the root branch, the
|
|
69
|
+
// cursor must be at the end of the line: a mid-line cursor with trailing text would
|
|
70
|
+
// otherwise produce a malformed line after applying a candidate. The prefix returned is
|
|
71
|
+
// the text after the command name (`install <query>` etc.), matching the host's
|
|
72
|
+
// argument-text semantics. `add ` is not Bridge-owned (#124), so a forced Tab there
|
|
73
|
+
// falls through to the host provider's filesystem completion unchanged.
|
|
74
|
+
if (options.force && cursorCol === line.length && SECOND_LEVEL_ARGUMENT_RE.test(line)) {
|
|
75
|
+
const argumentText = line.slice(EXACT_COMMAND.length + 1, cursorCol);
|
|
76
|
+
const items = completeArguments(argumentText, readOptions);
|
|
77
|
+
if (items) {
|
|
78
|
+
return { items, prefix: argumentText };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return current.getSuggestions(lines, cursorLine, cursorCol, options);
|
|
82
|
+
},
|
|
83
|
+
applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
|
|
84
|
+
return current.applyCompletion(lines, cursorLine, cursorCol, item, prefix);
|
|
85
|
+
},
|
|
86
|
+
shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
|
|
87
|
+
return current.shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? true;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
package/extensions/pi/index.ts
CHANGED
|
@@ -14,8 +14,22 @@ import type { ExtensionAPI, ExtensionCommandContext } from '@earendil-works/pi-c
|
|
|
14
14
|
|
|
15
15
|
import { runCommand } from '../../src/bridge/command.js';
|
|
16
16
|
import { discoverProjectedSkillPaths } from '../../src/projection/exposure.js';
|
|
17
|
+
import { completeArguments } from '../../src/bridge/completion.js';
|
|
18
|
+
import { createBridgeAutocompleteProvider } from './autocomplete.js';
|
|
17
19
|
|
|
18
20
|
export default function (pi: ExtensionAPI) {
|
|
21
|
+
// Root-level autocomplete (#121) + second-level autocomplete (#122–#124): stack a narrow
|
|
22
|
+
// provider for the exact `/codex-marketplace` editor text and the forced `install `,
|
|
23
|
+
// Installation lifecycle (`enable ` / `disable ` / `remove `), and Marketplace Registration
|
|
24
|
+
// (`list ` / `forget `) argument contexts (Pi otherwise completes just the command name
|
|
25
|
+
// plus a space, and routes forced argument Tabs to file completion). `add ` stays free-form
|
|
26
|
+
// (#124): forced Tabs keep Pi's native filesystem completion and typed Git locators are
|
|
27
|
+
// never constrained. session_start supplies the full TUI ui context;
|
|
28
|
+
// RPC/JSON/print modes no-op ctx.ui.addAutocompleteProvider, so a terminal-only provider is
|
|
29
|
+
// never registered outside a TUI session and command execution is unchanged.
|
|
30
|
+
pi.on('session_start', (_event, ctx) => {
|
|
31
|
+
ctx.ui.addAutocompleteProvider((current) => createBridgeAutocompleteProvider(current));
|
|
32
|
+
});
|
|
19
33
|
// Runtime Skill Exposure (ADR 0001): contribute Projected Skills through Pi's
|
|
20
34
|
// resource-discovery seam at every startup and reload. Passive existence inspection over the
|
|
21
35
|
// current Effective State only — no fingerprint validation and no Bridge State mutation.
|
|
@@ -33,6 +47,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
33
47
|
|
|
34
48
|
pi.registerCommand('codex-marketplace', {
|
|
35
49
|
description: 'codex / claude marketplace 管理(add/list/install/update/disable/enable/remove/forget/help)',
|
|
50
|
+
// Standard argument completion (#121–#124): typed subcommand and `install <query>` /
|
|
51
|
+
// lifecycle `<query>` / Registration (`list` / `forget`) `<query>` prefixes go through
|
|
52
|
+
// Pi's normal autocomplete; unowned syntax (including `add`'s free-form argument) returns
|
|
53
|
+
// null so Pi falls through to its own behavior.
|
|
54
|
+
getArgumentCompletions: (argumentPrefix: string) => completeArguments(argumentPrefix),
|
|
36
55
|
handler: async (args: string, ctx: ExtensionCommandContext) => {
|
|
37
56
|
const rawArgs = (args ?? '').trim();
|
|
38
57
|
const argv = rawArgs.length > 0 ? rawArgs.split(/\s+/) : [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-codex-marketplace",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Bridge Package for Codex and Claude Marketplace compatibility in Pi — 極簡 /codex-marketplace
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Bridge Package for Codex and Claude Marketplace compatibility in Pi — 極簡 /codex-marketplace 純文字指令與 Headless CLI(add/list/install/update/disable/enable/remove/forget)、單一 Global Bridge State、當下最新安裝與即時投影",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi-package",
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=22.19.0"
|
|
22
22
|
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"pi-codex-marketplace": "./bin/pi-codex-marketplace.js"
|
|
25
|
+
},
|
|
23
26
|
"pi": {
|
|
24
27
|
"extensions": [
|
|
25
28
|
"./extensions/pi/index.ts"
|
|
@@ -56,6 +59,7 @@
|
|
|
56
59
|
"prepublishOnly": "npm run typecheck && npm test"
|
|
57
60
|
},
|
|
58
61
|
"files": [
|
|
62
|
+
"bin",
|
|
59
63
|
"extensions",
|
|
60
64
|
"src",
|
|
61
65
|
"README.md",
|