@trim21/personal-pi-extensions 0.0.343 → 0.0.346
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 +1 -1
- package/package.json +1 -1
- package/src/aft/ast-edit.ts +0 -1
- package/src/aft/imports.ts +0 -1
- package/src/aft/refactor.ts +0 -1
- package/src/aft/tools.ts +0 -1
- package/src/lib/pendant.ts +0 -6
- package/src/opencode/todo.ts +0 -1
- package/src/spawn-agent.ts +0 -2
- package/src/talk/core.ts +19 -4
- package/src/talk/index.ts +48 -16
- package/src/talk/registry.ts +2 -0
- package/src/vision-agent.ts +0 -2
package/README.md
CHANGED
|
@@ -321,7 +321,7 @@ sqlite 文件路径按优先级取第一个可用值:
|
|
|
321
321
|
```
|
|
322
322
|
/talk-group-join # 无参:自动创建一个新 group(uuid 作为组名)并加入
|
|
323
323
|
/talk-group-join <name> # 加入名为 name 的 group;不存在则创建(名字允许字母/数字/-/_)
|
|
324
|
-
/talk-group-join-last # 加入最近创建的 group(方便新开 session
|
|
324
|
+
/talk-group-join-last # 加入最近创建的 group(方便新开 session 快速归队);支持 --name <alias> 设置显示名
|
|
325
325
|
/talk-group-leave # 离开当前 group(组空了自动删除)
|
|
326
326
|
/talk-group-list # 列出所有 group 及其成员,最新创建的在前
|
|
327
327
|
/talk-group-del <name> # 删除指定 group(成员随之变为未入组)
|
package/package.json
CHANGED
package/src/aft/ast-edit.ts
CHANGED
package/src/aft/imports.ts
CHANGED
package/src/aft/refactor.ts
CHANGED
package/src/aft/tools.ts
CHANGED
package/src/lib/pendant.ts
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* 工具 execute 返回的 details 里可携带一个可折叠的 markdown 面板,TUI 会把它
|
|
5
5
|
* 与本次工具调用的消息一起渲染:
|
|
6
6
|
* - `markdown`: 面板正文(完整 markdown),建议以 `## ` 标题开头、末尾 trim
|
|
7
|
-
* - `expanded`: 面板是否默认展开;识别/结果这类需要立即看到的内容用 true,
|
|
8
|
-
* 列表等常驻信息用 false
|
|
9
7
|
*/
|
|
10
8
|
export interface ToolPendant {
|
|
11
9
|
/**
|
|
@@ -20,8 +18,4 @@ export interface ToolPendant {
|
|
|
20
18
|
* 面板正文(完整 markdown),建议以 `## ` 标题开头、末尾 trim
|
|
21
19
|
*/
|
|
22
20
|
markdown?: string;
|
|
23
|
-
/**
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
expanded?: boolean;
|
|
27
21
|
}
|
package/src/opencode/todo.ts
CHANGED
package/src/spawn-agent.ts
CHANGED
|
@@ -711,7 +711,6 @@ export default function spawnAgent(pi: ExtensionAPI) {
|
|
|
711
711
|
...result,
|
|
712
712
|
pendant: {
|
|
713
713
|
markdown: formatPendantMarkdown(params.task, message),
|
|
714
|
-
expanded: true,
|
|
715
714
|
} satisfies ToolPendant,
|
|
716
715
|
},
|
|
717
716
|
isError: true,
|
|
@@ -729,7 +728,6 @@ export default function spawnAgent(pi: ExtensionAPI) {
|
|
|
729
728
|
...result,
|
|
730
729
|
pendant: {
|
|
731
730
|
markdown: formatPendantMarkdown(params.task, text),
|
|
732
|
-
expanded: false,
|
|
733
731
|
} satisfies ToolPendant,
|
|
734
732
|
},
|
|
735
733
|
};
|
package/src/talk/core.ts
CHANGED
|
@@ -530,7 +530,7 @@ export class TalkCore {
|
|
|
530
530
|
return `Invalid group name '${name}'. Allowed: letters, digits, '-' and '_' (max 64 chars).`;
|
|
531
531
|
}
|
|
532
532
|
if (agentName !== undefined) {
|
|
533
|
-
await this.writeSelf({ name: agentName });
|
|
533
|
+
await this.writeSelf({ name: agentName, alias: agentName });
|
|
534
534
|
}
|
|
535
535
|
const nameNote = agentName === undefined ? "" : ` You are visible as "${agentName}".`;
|
|
536
536
|
const existing = await readGroup(this.storage, name);
|
|
@@ -556,12 +556,15 @@ export class TalkCore {
|
|
|
556
556
|
return `Created group ${name}.${nameNote} Other agents join it with /talk-group-join ${name}.`;
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
-
/**
|
|
560
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Join the most recently created group; no-op when already in it. When
|
|
561
|
+
* `agentName` is given, the agent's display name is set to it.
|
|
562
|
+
*/
|
|
563
|
+
async groupJoinLast(agentName?: string): Promise<string> {
|
|
561
564
|
const groups = await listGroups(this.storage);
|
|
562
565
|
if (groups.length === 0) return "No groups. Create one with /talk-group-join.";
|
|
563
566
|
const latest = groups.reduce((a, b) => (b.createdAt > a.createdAt ? b : a));
|
|
564
|
-
return this.groupJoin(latest.id);
|
|
567
|
+
return this.groupJoin(latest.id, agentName);
|
|
565
568
|
}
|
|
566
569
|
|
|
567
570
|
/** Leave the current group; an emptied group is deleted. */
|
|
@@ -618,6 +621,18 @@ export class TalkCore {
|
|
|
618
621
|
return `Groups (${groups.length}):\n${lines.join("\n")}`;
|
|
619
622
|
}
|
|
620
623
|
|
|
624
|
+
/**
|
|
625
|
+
* Status-bar text for the caller: "alias@group" when an explicit alias was
|
|
626
|
+
* set via `talk-group-join --name`, "@group" otherwise; undefined when the
|
|
627
|
+
* caller is in no group (the adapter clears its status bar).
|
|
628
|
+
*/
|
|
629
|
+
async groupStatus(): Promise<string | undefined> {
|
|
630
|
+
const self = this.requireSelf();
|
|
631
|
+
const group = await groupForAgent(this.storage, self.agentId);
|
|
632
|
+
if (!group) return undefined;
|
|
633
|
+
return self.alias ? `${self.alias}@${group.id}` : `@${group.id}`;
|
|
634
|
+
}
|
|
635
|
+
|
|
621
636
|
async send(to: string, body: string): Promise<string> {
|
|
622
637
|
if (!to) return 'send requires "to".';
|
|
623
638
|
if (!body) return 'send requires "message".';
|
package/src/talk/index.ts
CHANGED
|
@@ -14,7 +14,9 @@ import * as path from "node:path";
|
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
type ExtensionAPI,
|
|
17
|
+
type ExtensionCommandContext,
|
|
17
18
|
type ExtensionContext,
|
|
19
|
+
type ExtensionUIContext,
|
|
18
20
|
getAgentDir,
|
|
19
21
|
truncateToVisualLines,
|
|
20
22
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -161,6 +163,19 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
161
163
|
return undefined;
|
|
162
164
|
}
|
|
163
165
|
|
|
166
|
+
/** Refresh the talk footer/status-bar text: "alias@group", or "@group" with no explicit alias. */
|
|
167
|
+
function refreshGroupStatus(ui: ExtensionUIContext): void {
|
|
168
|
+
void (async () => {
|
|
169
|
+
if (!self) return;
|
|
170
|
+
try {
|
|
171
|
+
const text = await core.groupStatus();
|
|
172
|
+
ui.setStatus("talk", text && ui.theme.fg("accent", text));
|
|
173
|
+
} catch {
|
|
174
|
+
// status bar is best-effort; never break the agent
|
|
175
|
+
}
|
|
176
|
+
})();
|
|
177
|
+
}
|
|
178
|
+
|
|
164
179
|
// ── Lifecycle ──────────────────────────────────────────────────────────
|
|
165
180
|
|
|
166
181
|
pi.on("session_start", (_event, ctx: ExtensionContext) => {
|
|
@@ -177,7 +192,7 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
177
192
|
lastSeenAt: now,
|
|
178
193
|
status: "idle",
|
|
179
194
|
};
|
|
180
|
-
void core.start(self);
|
|
195
|
+
void core.start(self).then(() => refreshGroupStatus(ctx.ui));
|
|
181
196
|
});
|
|
182
197
|
|
|
183
198
|
pi.on("agent_start", () => core.setWorking());
|
|
@@ -278,6 +293,7 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
278
293
|
function handleCommand<TFlags extends TObject>(
|
|
279
294
|
spec: CommandSpec<TFlags>,
|
|
280
295
|
args: string,
|
|
296
|
+
ctx: ExtensionCommandContext,
|
|
281
297
|
run: (parsed: OkResult<TFlags>) => Promise<string> | string,
|
|
282
298
|
): Promise<void> {
|
|
283
299
|
const parsed = parseCommand(spec, args);
|
|
@@ -289,6 +305,9 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
289
305
|
const initError = requireInit();
|
|
290
306
|
const text = initError ?? (await run(parsed));
|
|
291
307
|
pi.sendMessage({ customType: LIST_TYPE, content: text, display: true });
|
|
308
|
+
// Group membership can change under any of these commands; keep the
|
|
309
|
+
// footer/status-bar text in sync.
|
|
310
|
+
refreshGroupStatus(ctx.ui);
|
|
292
311
|
})();
|
|
293
312
|
}
|
|
294
313
|
|
|
@@ -327,9 +346,13 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
327
346
|
|
|
328
347
|
const TALK_GROUP_JOIN_LAST_SPEC = {
|
|
329
348
|
name: "talk-group-join-last",
|
|
330
|
-
usage: "",
|
|
331
|
-
description:
|
|
332
|
-
|
|
349
|
+
usage: "[options]",
|
|
350
|
+
description:
|
|
351
|
+
"Join the most recently created agent group (no-op when already in it); --name <alias> additionally sets this agent's display name",
|
|
352
|
+
flags: Type.Object({
|
|
353
|
+
name: Type.Optional(Type.String({ description: "Set this agent's display name" })),
|
|
354
|
+
}),
|
|
355
|
+
flagMeta: { name: { short: "n", valuePlaceholder: "<alias>" } },
|
|
333
356
|
arity: { max: 0 },
|
|
334
357
|
};
|
|
335
358
|
|
|
@@ -368,13 +391,13 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
368
391
|
|
|
369
392
|
pi.registerCommand("talk", {
|
|
370
393
|
description: TALK_SPEC.description,
|
|
371
|
-
handler: (args) => handleCommand(TALK_SPEC, args, async () => core.list()),
|
|
394
|
+
handler: (args, ctx) => handleCommand(TALK_SPEC, args, ctx, async () => core.list()),
|
|
372
395
|
});
|
|
373
396
|
|
|
374
397
|
pi.registerCommand("talk-dead", {
|
|
375
398
|
description: TALK_DEAD_SPEC.description,
|
|
376
|
-
handler: (args) =>
|
|
377
|
-
handleCommand(TALK_DEAD_SPEC, args, async (parsed) => {
|
|
399
|
+
handler: (args, ctx) =>
|
|
400
|
+
handleCommand(TALK_DEAD_SPEC, args, ctx, async (parsed) => {
|
|
378
401
|
if (parsed.flags.all && parsed.args.length > 0) {
|
|
379
402
|
return "--all cannot be combined with an agent id.\nTry '/talk-dead --help' for usage.";
|
|
380
403
|
}
|
|
@@ -388,8 +411,8 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
388
411
|
|
|
389
412
|
pi.registerCommand("talk-group-join", {
|
|
390
413
|
description: TALK_GROUP_JOIN_SPEC.description,
|
|
391
|
-
handler: (args) =>
|
|
392
|
-
handleCommand(TALK_GROUP_JOIN_SPEC, args, async (parsed) => {
|
|
414
|
+
handler: (args, ctx) =>
|
|
415
|
+
handleCommand(TALK_GROUP_JOIN_SPEC, args, ctx, async (parsed) => {
|
|
393
416
|
const agentName = parsed.flags.name?.trim() || undefined;
|
|
394
417
|
if (agentName !== undefined) explicitName = agentName;
|
|
395
418
|
return core.groupJoin(parsed.args[0], agentName);
|
|
@@ -398,29 +421,38 @@ export default function talk(pi: ExtensionAPI) {
|
|
|
398
421
|
|
|
399
422
|
pi.registerCommand("talk-group-join-last", {
|
|
400
423
|
description: TALK_GROUP_JOIN_LAST_SPEC.description,
|
|
401
|
-
handler: (args) =>
|
|
402
|
-
handleCommand(TALK_GROUP_JOIN_LAST_SPEC, args, async () =>
|
|
424
|
+
handler: (args, ctx) =>
|
|
425
|
+
handleCommand(TALK_GROUP_JOIN_LAST_SPEC, args, ctx, async (parsed) => {
|
|
426
|
+
const agentName = parsed.flags.name?.trim() || undefined;
|
|
427
|
+
if (agentName !== undefined) explicitName = agentName;
|
|
428
|
+
return core.groupJoinLast(agentName);
|
|
429
|
+
}),
|
|
403
430
|
});
|
|
404
431
|
|
|
405
432
|
pi.registerCommand("talk-group-leave", {
|
|
406
433
|
description: TALK_GROUP_LEAVE_SPEC.description,
|
|
407
|
-
handler: (args
|
|
434
|
+
handler: (args, ctx) =>
|
|
435
|
+
handleCommand(TALK_GROUP_LEAVE_SPEC, args, ctx, async () => core.groupLeave()),
|
|
408
436
|
});
|
|
409
437
|
|
|
410
438
|
pi.registerCommand("talk-group-list", {
|
|
411
439
|
description: TALK_GROUP_LIST_SPEC.description,
|
|
412
|
-
handler: (args
|
|
440
|
+
handler: (args, ctx) =>
|
|
441
|
+
handleCommand(TALK_GROUP_LIST_SPEC, args, ctx, async () => core.groupList()),
|
|
413
442
|
});
|
|
414
443
|
|
|
415
444
|
pi.registerCommand("talk-group-del", {
|
|
416
445
|
description: TALK_GROUP_DEL_SPEC.description,
|
|
417
|
-
handler: (args) =>
|
|
418
|
-
handleCommand(TALK_GROUP_DEL_SPEC, args, async (parsed) =>
|
|
446
|
+
handler: (args, ctx) =>
|
|
447
|
+
handleCommand(TALK_GROUP_DEL_SPEC, args, ctx, async (parsed) =>
|
|
448
|
+
core.groupDelete(parsed.args[0]),
|
|
449
|
+
),
|
|
419
450
|
});
|
|
420
451
|
|
|
421
452
|
pi.registerCommand("talk-group-clear", {
|
|
422
453
|
description: TALK_GROUP_CLEAR_SPEC.description,
|
|
423
|
-
handler: (args
|
|
454
|
+
handler: (args, ctx) =>
|
|
455
|
+
handleCommand(TALK_GROUP_CLEAR_SPEC, args, ctx, async () => core.groupClear()),
|
|
424
456
|
});
|
|
425
457
|
|
|
426
458
|
// ── Delivery card ──────────────────────────────────────────────────────
|
package/src/talk/registry.ts
CHANGED
|
@@ -36,6 +36,8 @@ export const AgentRecordSchema = Type.Object({
|
|
|
36
36
|
addr: Type.String(),
|
|
37
37
|
agentId: Type.String(),
|
|
38
38
|
name: Type.String(),
|
|
39
|
+
/** Display name explicitly set via `talk-group-join --name`, distinct from the session name. */
|
|
40
|
+
alias: Type.Optional(Type.String()),
|
|
39
41
|
cwd: Type.String(),
|
|
40
42
|
pid: Type.Number(),
|
|
41
43
|
pidStart: Type.Optional(Type.Number()),
|
package/src/vision-agent.ts
CHANGED
|
@@ -445,7 +445,6 @@ export default function visionAgent(pi: ExtensionAPI) {
|
|
|
445
445
|
count: paths.length,
|
|
446
446
|
pendant: {
|
|
447
447
|
markdown,
|
|
448
|
-
expanded: true,
|
|
449
448
|
} satisfies ToolPendant,
|
|
450
449
|
},
|
|
451
450
|
};
|
|
@@ -465,7 +464,6 @@ export default function visionAgent(pi: ExtensionAPI) {
|
|
|
465
464
|
error: message,
|
|
466
465
|
pendant: {
|
|
467
466
|
markdown: `## 图片识别失败\n\n${message}`,
|
|
468
|
-
expanded: true,
|
|
469
467
|
} satisfies ToolPendant,
|
|
470
468
|
},
|
|
471
469
|
};
|