pi-codex-marketplace 1.0.3 → 1.0.5
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 +2 -2
- package/extensions/pi/autocomplete.ts +2 -2
- package/extensions/pi/index.ts +1 -1
- package/package.json +4 -4
- package/src/cli/index.ts +38 -18
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pi-codex-marketplace
|
|
2
2
|
|
|
3
|
-
Bridge Package for Codex and Claude Marketplace compatibility in Pi
|
|
3
|
+
Bridge Package for Codex and Claude Marketplace compatibility in Pi(驗證於 `0.87.0`;相容下限 `0.84.2`,由 CI 把關)。
|
|
4
4
|
|
|
5
5
|
> **One-line:** `pi install npm:pi-codex-marketplace` → `/codex-marketplace add <本機資料夾|GitHub 網址>`(或 Shell 下 `npx pi-codex-marketplace add ...`)註冊 marketplace → `install <編號>` 裝到當下最新並在 Pi 可用。
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ npx pi-codex-marketplace add <本機資料夾|GitHub 網址> # Shell 下
|
|
|
19
19
|
/codex-marketplace install <編號|名稱>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Requirements: **Pi 0.84.2
|
|
22
|
+
Requirements: **Pi `0.87.0`(相容下限 `0.84.2`)** · **Node >=22.19.0** · **macOS / Linux**(Windows not supported)。`peerDependencies` 依 Pi 官方規範宣告 `*`,不鎖定 host 版本。完整安裝方式見 [docs/installation.md](./docs/installation.md),支援矩陣見 [docs/architecture.md](./docs/architecture.md#support-matrix)。
|
|
23
23
|
|
|
24
24
|
## 子命令速查
|
|
25
25
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Narrow Bridge autocomplete provider — thin Pi adapter (TUI session only) (#119, #121–#124).
|
|
3
3
|
*
|
|
4
|
-
* Pi
|
|
4
|
+
* Pi's built-in combined provider completes the slash-command name and inserts a
|
|
5
5
|
* trailing space without exposing empty-prefix argument completion (root subcommands) when
|
|
6
6
|
* the editor holds exactly `/codex-marketplace`. This wrapper intercepts that exact editor
|
|
7
7
|
* content and presents the nine root candidates. It also owns the second-level argument
|
|
8
8
|
* contexts (`install` #122, the Installation lifecycle `enable` / `disable` / `remove` #123,
|
|
9
9
|
* and the Marketplace Registration `list` / `forget` #124) on forced (Tab) requests, which
|
|
10
|
-
* Pi
|
|
10
|
+
* Pi routes to file completion instead of slash-command argument completion (its
|
|
11
11
|
* argument path only runs when `force` is false) — the wrapper returns the state-aware
|
|
12
12
|
* candidates there. `add` stays free-form (#124): its forced Tab keeps Pi's native
|
|
13
13
|
* filesystem completion, and a typed Git locator or path is never constrained by Bridge
|
package/extensions/pi/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bridge Extension — Pi runtime entry for pi-codex-marketplace
|
|
3
|
-
* Single extension "pi" package, Pi
|
|
3
|
+
* Single extension "pi" package, validated against the Pi host pinned in devDependencies.
|
|
4
4
|
*
|
|
5
5
|
* Provides:
|
|
6
6
|
* - /codex-marketplace command: Thin Pi adapter delegating to pure runCommand
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-codex-marketplace",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
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": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@earendil-works/pi-ai": "*",
|
|
33
|
-
"@earendil-works/pi-coding-agent": "
|
|
33
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
34
34
|
"@earendil-works/pi-tui": "*"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"overrides": {},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
47
|
-
"@earendil-works/pi-tui": "^0.
|
|
46
|
+
"@earendil-works/pi-coding-agent": "^0.87.0",
|
|
47
|
+
"@earendil-works/pi-tui": "^0.87.0",
|
|
48
48
|
"@types/node": "^26.2.0",
|
|
49
49
|
"typescript": "^5.7.0",
|
|
50
50
|
"vitest": "^3.0.0"
|
package/src/cli/index.ts
CHANGED
|
@@ -12,8 +12,8 @@ import { runCommand, getPackageVersion, type CommandOptions, type CommandResult
|
|
|
12
12
|
export { getPackageVersion };
|
|
13
13
|
|
|
14
14
|
export interface CliIO {
|
|
15
|
-
stdout?: { write: (chunk: string) => unknown } | ((chunk: string) => unknown);
|
|
16
|
-
stderr?: { write: (chunk: string) => unknown; isTTY?: boolean } | ((chunk: string) => unknown);
|
|
15
|
+
stdout?: { write: (chunk: string) => unknown; isTTY?: boolean } | ((chunk: string) => unknown);
|
|
16
|
+
stderr?: { write: (chunk: string) => unknown; isTTY?: boolean; columns?: number } | ((chunk: string) => unknown);
|
|
17
17
|
exit?: (code: number) => unknown;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -63,13 +63,19 @@ export async function runCli(
|
|
|
63
63
|
return exitWith(0);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const
|
|
66
|
+
const interactive = typeof io.stdout === 'object' && io.stdout.isTTY;
|
|
67
|
+
const terminal = interactive && typeof io.stderr === 'object' && io.stderr.isTTY ? io.stderr : undefined;
|
|
67
68
|
let timer: ReturnType<typeof setInterval> | undefined;
|
|
68
69
|
let frame = 0;
|
|
70
|
+
let activityVisible = false;
|
|
71
|
+
let updating = false;
|
|
69
72
|
const clearActivity = (): void => {
|
|
70
73
|
if (timer !== undefined) {
|
|
71
74
|
clearInterval(timer);
|
|
72
75
|
timer = undefined;
|
|
76
|
+
}
|
|
77
|
+
if (activityVisible) {
|
|
78
|
+
activityVisible = false;
|
|
73
79
|
try { terminal?.write('\r\x1b[2K'); } catch { /* Progress is best-effort. */ }
|
|
74
80
|
}
|
|
75
81
|
};
|
|
@@ -78,21 +84,31 @@ export async function runCli(
|
|
|
78
84
|
result = await runCommand(argv, {
|
|
79
85
|
...opts,
|
|
80
86
|
onProgress(message, kind) {
|
|
81
|
-
|
|
82
|
-
if (kind
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
updating = true; // Only update emits progress; other command formatting stays unchanged.
|
|
88
|
+
if (kind !== 'result' && terminal) {
|
|
89
|
+
clearActivity();
|
|
90
|
+
const render = (): void => {
|
|
91
|
+
// Reserve the last column to prevent wrapping into permanent history.
|
|
92
|
+
const width = Math.max(0, (terminal.columns ?? 80) - 1);
|
|
93
|
+
const text = `${['|', '/', '-', '\\'][frame++ % 4]} ${message}`;
|
|
94
|
+
let line = '';
|
|
95
|
+
let used = 0;
|
|
96
|
+
for (const char of text.replace(/[\x00-\x1f\x7f-\x9f]/g, ' ')) {
|
|
97
|
+
const cells = char.codePointAt(0)! < 128 ? 1 : 2;
|
|
98
|
+
if (used + cells > width) break;
|
|
99
|
+
line += char;
|
|
100
|
+
used += cells;
|
|
93
101
|
}
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
try {
|
|
103
|
+
activityVisible = true;
|
|
104
|
+
terminal.write(`\r\x1b[2K${line}`);
|
|
105
|
+
} catch { clearActivity(); }
|
|
106
|
+
};
|
|
107
|
+
render();
|
|
108
|
+
if (activityVisible) {
|
|
109
|
+
timer = setInterval(render, 100);
|
|
110
|
+
timer.unref();
|
|
111
|
+
}
|
|
96
112
|
}
|
|
97
113
|
opts.onProgress?.(message, kind);
|
|
98
114
|
},
|
|
@@ -100,7 +116,11 @@ export async function runCli(
|
|
|
100
116
|
} finally {
|
|
101
117
|
clearActivity();
|
|
102
118
|
}
|
|
103
|
-
const
|
|
119
|
+
const formatted = formatCliOutput(result);
|
|
120
|
+
const output = updating
|
|
121
|
+
? formatted.split('\n').filter((line) => line.length > 0)
|
|
122
|
+
.map((line) => line.replace(/^(.+? )重新抓取… /, '$1')).join('\n')
|
|
123
|
+
: formatted;
|
|
104
124
|
|
|
105
125
|
if (result.ok) {
|
|
106
126
|
if (output) {
|