@pi-ohm/subagents 0.3.0-dev.22083116751.1.d12e548

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 ADDED
@@ -0,0 +1,20 @@
1
+ # @pi-ohm/subagents
2
+
3
+ Install only subagent delegation support for Pi.
4
+
5
+ ```bash
6
+ pi install npm:@pi-ohm/subagents
7
+ ```
8
+
9
+ Scaffolded subagents:
10
+
11
+ - `librarian` — multi-repo code understanding
12
+ - `oracle` — reasoning-heavy advisor/reviewer
13
+ - `finder` — intelligent behavior-based search
14
+ - `task` — isolated parallel execution worker
15
+ - `painter` — explicit-request image generation/editing helper
16
+
17
+ Commands:
18
+
19
+ - `/ohm-subagents`
20
+ - `/ohm-subagent <id>`
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@pi-ohm/subagents",
3
+ "version": "0.3.0-dev.22083116751.1.d12e548",
4
+ "type": "module",
5
+ "main": "src/extension.ts",
6
+ "types": "src/extension.ts",
7
+ "files": [
8
+ "src/",
9
+ "README.md"
10
+ ],
11
+ "pi": {
12
+ "extensions": [
13
+ "./src/extension.ts"
14
+ ]
15
+ },
16
+ "dependencies": {
17
+ "@mariozechner/pi-coding-agent": "^0.52.0",
18
+ "@pi-ohm/config": "0.3.0-dev.22083116751.1.d12e548"
19
+ },
20
+ "peerDependencies": {
21
+ "@mariozechner/pi-coding-agent": "*"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "provenance": true
26
+ }
27
+ }
package/src/catalog.ts ADDED
@@ -0,0 +1,80 @@
1
+ export type OhmSubagentId = "librarian" | "oracle" | "finder" | "task" | "painter";
2
+
3
+ export interface OhmSubagentDefinition {
4
+ id: OhmSubagentId;
5
+ name: string;
6
+ summary: string;
7
+ whenToUse: string[];
8
+ scaffoldPrompt: string;
9
+ requiresPackage?: string;
10
+ }
11
+
12
+ export const OHM_SUBAGENT_CATALOG: readonly OhmSubagentDefinition[] = [
13
+ {
14
+ id: "librarian",
15
+ name: "Librarian",
16
+ summary: "Multi-repo codebase understanding subagent (GitHub/Bitbucket architecture analysis).",
17
+ whenToUse: [
18
+ "Understand architecture across multiple repositories",
19
+ "Build implementation maps before migration/refactor",
20
+ "Trace ownership boundaries across services",
21
+ ],
22
+ scaffoldPrompt:
23
+ "Analyze this codebase (and linked repos if provided). Build an architecture map: boundaries, key modules, integration points, and risky coupling.",
24
+ },
25
+ {
26
+ id: "oracle",
27
+ name: "Oracle",
28
+ summary:
29
+ "Reasoning-heavy advisor for code review, architecture feedback, complex debugging, and planning.",
30
+ whenToUse: [
31
+ "Get second-opinion architecture critique",
32
+ "Review risky design decisions before implementation",
33
+ "Debug ambiguous failures with hypothesis ranking",
34
+ ],
35
+ scaffoldPrompt:
36
+ "Act as a critical reviewer. Challenge assumptions, rank risks, and provide a concrete implementation plan with trade-offs.",
37
+ },
38
+ {
39
+ id: "finder",
40
+ name: "Finder",
41
+ summary: "Concept/behavior-based search subagent for multi-step codebase discovery.",
42
+ whenToUse: [
43
+ "Find all call sites for a behavior, not just symbol references",
44
+ "Map data flow across modules",
45
+ "Locate implicit coupling and duplicated logic",
46
+ ],
47
+ scaffoldPrompt:
48
+ "Search this codebase for all implementations and call paths related to the requested behavior. Return files, rationale, and confidence.",
49
+ },
50
+ {
51
+ id: "task",
52
+ name: "Task",
53
+ summary: "Independent execution subagent for parallelizable tasks with isolated tool context.",
54
+ whenToUse: [
55
+ "Parallelize work across unrelated app areas",
56
+ "Delegate focused implementation tasks",
57
+ "Run isolated experiments without polluting main context",
58
+ ],
59
+ scaffoldPrompt:
60
+ "Execute this focused implementation task independently. Return a concise summary of changes, validation, and follow-up risks.",
61
+ },
62
+ {
63
+ id: "painter",
64
+ name: "Painter",
65
+ summary: "Image generation/editing subagent used only on explicit request.",
66
+ whenToUse: [
67
+ "Generate concept/mock images",
68
+ "Edit existing images based on prompt instructions",
69
+ "Produce visual assets when user explicitly asks for image output",
70
+ ],
71
+ scaffoldPrompt:
72
+ "Generate or edit an image per user request. Confirm intent first, then return prompt + provider/model metadata with result notes.",
73
+ requiresPackage: "@pi-ohm/painter",
74
+ },
75
+ ] as const;
76
+
77
+ export function getSubagentById(id: string): OhmSubagentDefinition | undefined {
78
+ const needle = id.trim().toLowerCase();
79
+ return OHM_SUBAGENT_CATALOG.find((agent) => agent.id === needle);
80
+ }
@@ -0,0 +1,128 @@
1
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
+ import { loadOhmRuntimeConfig, registerOhmSettings } from "@pi-ohm/config";
3
+ import { getSubagentById, OHM_SUBAGENT_CATALOG } from "./catalog";
4
+
5
+ function normalizeCommandArgs(args: unknown): string[] {
6
+ if (Array.isArray(args)) {
7
+ return args.filter((value): value is string => typeof value === "string");
8
+ }
9
+
10
+ if (typeof args === "string") {
11
+ return args
12
+ .split(/\s+/)
13
+ .map((part) => part.trim())
14
+ .filter((part) => part.length > 0);
15
+ }
16
+
17
+ if (args && typeof args === "object") {
18
+ const asRecord = args as { args?: unknown; raw?: unknown };
19
+
20
+ if (Array.isArray(asRecord.args)) {
21
+ return asRecord.args.filter((value): value is string => typeof value === "string");
22
+ }
23
+
24
+ if (typeof asRecord.raw === "string") {
25
+ return asRecord.raw
26
+ .split(/\s+/)
27
+ .map((part) => part.trim())
28
+ .filter((part) => part.length > 0);
29
+ }
30
+ }
31
+
32
+ return [];
33
+ }
34
+
35
+ export default function registerSubagentsExtension(pi: ExtensionAPI): void {
36
+ registerOhmSettings(pi);
37
+
38
+ pi.on("session_start", async (_event, ctx) => {
39
+ const { config } = await loadOhmRuntimeConfig(ctx.cwd);
40
+ if (!ctx.hasUI) return;
41
+
42
+ const enabled = config.features.subagents ? "on" : "off";
43
+ ctx.ui.setStatus("ohm-subagents", `subagents:${enabled} · backend:${config.subagentBackend}`);
44
+ });
45
+
46
+ pi.registerCommand("ohm-subagents", {
47
+ description: "Show scaffolded subagents and backend status",
48
+ handler: async (_args, ctx) => {
49
+ const { config, loadedFrom } = await loadOhmRuntimeConfig(ctx.cwd);
50
+
51
+ const lines = OHM_SUBAGENT_CATALOG.map((agent) => {
52
+ const needsPainterPackage = agent.id === "painter";
53
+ const available = !needsPainterPackage || config.features.painterImagegen;
54
+ const availability = available ? "available" : "requires painter feature/package";
55
+ return `- ${agent.name} (${agent.id}): ${agent.summary} [${availability}]`;
56
+ });
57
+
58
+ const text = [
59
+ "Pi OHM: subagents",
60
+ "",
61
+ `enabled: ${config.features.subagents ? "yes" : "no"}`,
62
+ `backend: ${config.subagentBackend}`,
63
+ "",
64
+ "Scaffolded subagents:",
65
+ ...lines,
66
+ "",
67
+ "Use /ohm-subagent <id> to inspect one profile.",
68
+ `loadedFrom: ${loadedFrom.length > 0 ? loadedFrom.join(", ") : "defaults + extension settings"}`,
69
+ ].join("\n");
70
+
71
+ if (!ctx.hasUI) {
72
+ console.log(text);
73
+ return;
74
+ }
75
+
76
+ await ctx.ui.editor("pi-ohm subagents", text);
77
+ },
78
+ });
79
+
80
+ pi.registerCommand("ohm-subagent", {
81
+ description: "Inspect one subagent scaffold (librarian|oracle|finder|task|painter)",
82
+ handler: async (args, ctx) => {
83
+ const { config } = await loadOhmRuntimeConfig(ctx.cwd);
84
+ const [requested = ""] = normalizeCommandArgs(args);
85
+ const match = getSubagentById(requested);
86
+
87
+ if (!match) {
88
+ const usage = [
89
+ "Usage: /ohm-subagent <id>",
90
+ "",
91
+ `Valid ids: ${OHM_SUBAGENT_CATALOG.map((agent) => agent.id).join(", ")}`,
92
+ ].join("\n");
93
+
94
+ if (!ctx.hasUI) {
95
+ console.log(usage);
96
+ return;
97
+ }
98
+
99
+ await ctx.ui.editor("pi-ohm subagent usage", usage);
100
+ return;
101
+ }
102
+
103
+ const isAvailable = match.id !== "painter" || config.features.painterImagegen;
104
+
105
+ const text = [
106
+ `Subagent: ${match.name}`,
107
+ `id: ${match.id}`,
108
+ `available: ${isAvailable ? "yes" : "no"}`,
109
+ match.requiresPackage
110
+ ? `requiresPackage: ${match.requiresPackage}`
111
+ : "requiresPackage: none",
112
+ "",
113
+ "When to use:",
114
+ ...match.whenToUse.map((line) => `- ${line}`),
115
+ "",
116
+ "Scaffold prompt:",
117
+ match.scaffoldPrompt,
118
+ ].join("\n");
119
+
120
+ if (!ctx.hasUI) {
121
+ console.log(text);
122
+ return;
123
+ }
124
+
125
+ await ctx.ui.editor(`pi-ohm ${match.id} subagent`, text);
126
+ },
127
+ });
128
+ }