pi-naming 0.2.1 → 0.4.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 +3 -3
- package/README.zh-CN.md +3 -3
- package/SKILL.md +2 -2
- package/package.json +8 -8
- package/src/index.ts +24 -7
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ File: `<pi-agent-dir>/extensions/pi-naming/config.json`; respects `PI_CODING_AGE
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
`automaticNaming` and `manualNaming` independently control the automatic input hook and `/rename`. `targets` controls session, workspace and tab separately; all default to enabled. Disable both terminal targets for session-only naming without loading the terminal module.
|
|
45
|
+
`automaticNaming` and `manualNaming` independently control the automatic input hook and `/rename`. `targets` directly controls session, workspace and tab separately; all targets default to enabled. Disable both terminal targets for session-only naming without loading the terminal module.
|
|
46
46
|
|
|
47
47
|
| Title field | Default | Meaning |
|
|
48
48
|
| --- | --- | --- |
|
|
@@ -64,9 +64,9 @@ For longer English titles use `maxLength: 60`, `preferredLength: 40`, `language:
|
|
|
64
64
|
- tmux/WezTerm/Otty/Orca splits do not prove exclusive window/tab ownership. Unverified targets are skipped with an explanation rather than expanding the operation's scope.
|
|
65
65
|
- With `pi-interactive-subagents`, explicitly include this package's entrypoint in `subagentExtensions`. Installing it in the parent does not bypass child extension isolation.
|
|
66
66
|
|
|
67
|
-
Ordinary sessions
|
|
67
|
+
Ordinary sessions request every enabled target with an explicit ID, including supported tmux and Herdr targets. This target-resolution path deliberately ignores the legacy `PI_SUBAGENT_RENAME_TMUX_WINDOW`, `PI_SUBAGENT_RENAME_TMUX_SESSION` and `PI_SUBAGENT_RENAME_HERDR_WORKSPACE` switches; those variables remain only for terminal-mux's older public rename APIs. A disabled `targets` entry does not run even if an environment variable is set. Missing IDs never fall back to current focus or the first tab.
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
`pi-naming` requires a published `pi-terminal-mux` version that exports `resolveTerminalRenameTargets` and `renameTerminalTarget`. Release-please updates workspace dependency ranges in release PRs. When one release publishes both packages, CI publishes terminal-mux first and publishes naming only after that npm publication succeeds; a naming-only release uses the already published compatible mux. Do not manually publish or preemptively raise the range to an unpublished version.
|
|
70
70
|
|
|
71
71
|
## Validation
|
|
72
72
|
|
package/README.zh-CN.md
CHANGED
|
@@ -42,7 +42,7 @@ pi install npm:pi-naming
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
`automaticNaming` 和 `manualNaming` 独立控制自动入口和 `/rename` 命令。`targets`
|
|
45
|
+
`automaticNaming` 和 `manualNaming` 独立控制自动入口和 `/rename` 命令。`targets` 直接分别控制 session、workspace、tab,三个目标默认开启。仅需 session 命名时关闭两个终端目标,此时不加载终端模块。
|
|
46
46
|
|
|
47
47
|
| 标题字段 | 默认值 | 含义 |
|
|
48
48
|
| --- | --- | --- |
|
|
@@ -64,9 +64,9 @@ pi install npm:pi-naming
|
|
|
64
64
|
- tmux/WezTerm/Otty/Orca 分屏不代表独占 window/tab,归属无法确认时跳过并说明原因,不扩大操作范围。
|
|
65
65
|
- 使用 `pi-interactive-subagents` 时,需在它的 `subagentExtensions` 中显式加载本包入口;仅在主会话安装本包不会绕过子代理的扩展隔离设置。
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
普通会话会请求每个启用且具备明确 ID 的目标,包括受支持的 tmux 和 Herdr 目标。此目标解析路径刻意忽略旧变量 `PI_SUBAGENT_RENAME_TMUX_WINDOW`、`PI_SUBAGENT_RENAME_TMUX_SESSION`、`PI_SUBAGENT_RENAME_HERDR_WORKSPACE`;它们仅保留给 terminal-mux 的旧公开改名接口。即使环境变量为 `1`,关闭的 `targets` 也绝不执行。终端目标缺少 ID 时不会使用当前焦点或第一个 tab 代替。实际目标可能是 pane、tab、window、workspace 或 session,结果中会说明。
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
`pi-naming` 依赖已发布且导出 `resolveTerminalRenameTargets`、`renameTerminalTarget` 的 `pi-terminal-mux` 版本。release-please 会在 Release PR 中更新 workspace 依赖范围;同一次发布同时包含两包时,CI 先发布 terminal-mux,只有其 npm 发布成功后才发布 naming;仅发布 naming 时使用已发布的兼容 mux。不手动发布,也不预先把范围改成未发布版本。
|
|
70
70
|
|
|
71
71
|
## 验证
|
|
72
72
|
|
package/SKILL.md
CHANGED
|
@@ -9,9 +9,9 @@ description: 配置 Pi 统一 /rename、首条消息命名和终端目标归属
|
|
|
9
9
|
|
|
10
10
|
Use `/config:naming` to open the normal TUI settings menu; use `reset` for defaults and reload after saving.
|
|
11
11
|
|
|
12
|
-
- `automaticNaming` / `manualNaming` 控制自动输入和 `/rename [名称]`,`targets`
|
|
12
|
+
- `automaticNaming` / `manualNaming` 控制自动输入和 `/rename [名称]`,`targets` 直接分别控制 session/workspace/tab。Control automatic input and `/rename [name]`; `targets` directly selects session/workspace/tab.
|
|
13
13
|
- `title` 控制长度、语言、补充提示和超时;模型鉴权复用 Pi。Controls length, language, instructions and timeout; model authentication comes from Pi.
|
|
14
|
-
- 无终端也可命名 session
|
|
14
|
+
- 无终端也可命名 session;终端失败与跳过必须报告。普通会话明确目标路径不受旧 `PI_SUBAGENT_RENAME_*` 变量影响;关闭 target 即使变量为 `1` 也不执行。Session naming works without a terminal; report terminal failures and skips. The ordinary-session explicit-target path ignores legacy `PI_SUBAGENT_RENAME_*` variables; a disabled target never runs even when a variable is `1`.
|
|
15
15
|
- 子进程归属由启动方通过 mux 协议提供,不把 pane 扩大为共享 tab,不修改父 workspace。Launchers grant child targets through the mux protocol; never expand a pane to a shared tab or rename the parent workspace.
|
|
16
16
|
- 子代理需要显式配置 `subagentExtensions` 加载 naming。Child extension isolation requires explicitly loading naming in `subagentExtensions`.
|
|
17
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-naming",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Configurable Pi session naming and manual terminal workspace/tab renaming",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -57,19 +57,19 @@
|
|
|
57
57
|
"workspace"
|
|
58
58
|
],
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"pi-extensions-i18n": "^0.
|
|
61
|
-
"pi-terminal-mux": "^0.
|
|
60
|
+
"pi-extensions-i18n": "^0.5.0",
|
|
61
|
+
"pi-terminal-mux": "^0.6.2"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@earendil-works/pi-coding-agent": ">=0.80.0
|
|
65
|
-
"@earendil-works/pi-ai": ">=0.80.0
|
|
64
|
+
"@earendil-works/pi-coding-agent": ">=0.80.0",
|
|
65
|
+
"@earendil-works/pi-ai": ">=0.80.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
68
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
69
69
|
"@types/node": "24.12.4",
|
|
70
|
-
"pi-terminal-mux": "^0.
|
|
70
|
+
"pi-terminal-mux": "^0.6.2",
|
|
71
71
|
"tsx": "4.23.1",
|
|
72
72
|
"typescript": "5.9.3",
|
|
73
|
-
"@earendil-works/pi-ai": "0.
|
|
73
|
+
"@earendil-works/pi-ai": "0.85.1"
|
|
74
74
|
}
|
|
75
75
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,14 @@ import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@e
|
|
|
2
2
|
import type { TerminalRenameOutcome, TerminalRenameTarget, ResolveRenameOptions } from "pi-terminal-mux";
|
|
3
3
|
import { configPath, loadConfig, parseConfig, saveConfig, type NamingConfig } from "./config.ts";
|
|
4
4
|
import { i18n } from "./i18n.ts";
|
|
5
|
+
import { notifyWithSource, type NoticeColor, type NoticeSource } from "pi-extensions-i18n";
|
|
6
|
+
|
|
7
|
+
/** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
|
|
8
|
+
const NOTICE_TAG = "naming";
|
|
9
|
+
/** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
|
|
10
|
+
const NOTICE_COLOR: NoticeColor = "toolTitle";
|
|
11
|
+
/** 本扩展的提示来源。 */
|
|
12
|
+
const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
|
|
5
13
|
import { getCurrentSessionUserMessages, requestSessionNameWithTimeout, type SessionNameRequester } from "./session-name.ts";
|
|
6
14
|
|
|
7
15
|
const RENAME_COMMAND = "rename";
|
|
@@ -44,12 +52,21 @@ function errorMessage(error: unknown): string {
|
|
|
44
52
|
/** 无交互 UI 时仍通过 Pi 消息报告结果,不静默吞错。 */
|
|
45
53
|
function report(pi: ExtensionAPI, ctx: ExtensionContext, notice: { message: string; level: "info" | "warning" | "error" }): void {
|
|
46
54
|
const { message, level } = notice;
|
|
47
|
-
if (ctx.hasUI) ctx
|
|
55
|
+
if (ctx.hasUI) notifyWithSource({ ctx, source: NOTICE_SOURCE, level, message });
|
|
48
56
|
else pi.sendMessage({ customType: MESSAGE_TYPE, content: message, display: true }, { triggerTurn: false });
|
|
49
57
|
}
|
|
50
58
|
|
|
59
|
+
export interface NamingConfigStore {
|
|
60
|
+
load(): NamingConfig;
|
|
61
|
+
save(config: NamingConfig): void;
|
|
62
|
+
path(): string;
|
|
63
|
+
}
|
|
64
|
+
|
|
51
65
|
/** 注册配置命令,通过 TUI 菜单和输入框修改命名配置。 */
|
|
52
|
-
function registerNamingConfigCommand(
|
|
66
|
+
export function registerNamingConfigCommand(
|
|
67
|
+
pi: ExtensionAPI,
|
|
68
|
+
store: NamingConfigStore = { load: loadConfig, save: saveConfig, path: configPath },
|
|
69
|
+
): void {
|
|
53
70
|
const command = {
|
|
54
71
|
description: i18n.t("configCommandDescription"),
|
|
55
72
|
getArgumentCompletions: () => [{ value: CONFIG_RESET_COMMAND, label: CONFIG_RESET_COMMAND }],
|
|
@@ -61,9 +78,9 @@ function registerNamingConfigCommand(pi: ExtensionAPI): void {
|
|
|
61
78
|
}
|
|
62
79
|
if (argument === CONFIG_RESET_COMMAND) {
|
|
63
80
|
try {
|
|
64
|
-
|
|
81
|
+
store.save(parseConfig({}));
|
|
65
82
|
report(pi, ctx, {
|
|
66
|
-
message: i18n.t("configCommandSaved", { path:
|
|
83
|
+
message: i18n.t("configCommandSaved", { path: store.path() }),
|
|
67
84
|
level: "info",
|
|
68
85
|
});
|
|
69
86
|
} catch (error) {
|
|
@@ -78,7 +95,7 @@ function registerNamingConfigCommand(pi: ExtensionAPI): void {
|
|
|
78
95
|
|
|
79
96
|
let config: NamingConfig;
|
|
80
97
|
try {
|
|
81
|
-
config =
|
|
98
|
+
config = store.load();
|
|
82
99
|
} catch (error) {
|
|
83
100
|
report(pi, ctx, { message: i18n.t("configCommandInvalid", { error: errorMessage(error) }), level: "error" });
|
|
84
101
|
return;
|
|
@@ -87,9 +104,9 @@ function registerNamingConfigCommand(pi: ExtensionAPI): void {
|
|
|
87
104
|
/** Saves one validated menu change and reports its result. */
|
|
88
105
|
const save = (next: NamingConfig): boolean => {
|
|
89
106
|
try {
|
|
90
|
-
|
|
107
|
+
store.save(next);
|
|
91
108
|
config = next;
|
|
92
|
-
report(pi, ctx, { message: i18n.t("configCommandSaved", { path:
|
|
109
|
+
report(pi, ctx, { message: i18n.t("configCommandSaved", { path: store.path() }), level: "info" });
|
|
93
110
|
return true;
|
|
94
111
|
} catch (error) {
|
|
95
112
|
report(pi, ctx, { message: i18n.t("configCommandInvalid", { error: errorMessage(error) }), level: "error" });
|