takomi 2.1.13 → 2.1.15

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.
Files changed (39) hide show
  1. package/.pi/agents/architect.md +73 -73
  2. package/.pi/agents/coder.md +70 -70
  3. package/.pi/agents/designer.md +72 -72
  4. package/.pi/agents/orchestrator.md +122 -122
  5. package/.pi/agents/reviewer.md +71 -71
  6. package/.pi/extensions/oauth-router/provider.ts +3 -1
  7. package/.pi/extensions/takomi-context-manager/config.ts +48 -48
  8. package/.pi/extensions/takomi-context-manager/context-router.ts +57 -57
  9. package/.pi/extensions/takomi-context-manager/diagnostics-tools.ts +28 -28
  10. package/.pi/extensions/takomi-context-manager/diagnostics.ts +55 -55
  11. package/.pi/extensions/takomi-context-manager/extension-conflicts.ts +56 -56
  12. package/.pi/extensions/takomi-context-manager/index.ts +56 -56
  13. package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +228 -206
  14. package/.pi/extensions/takomi-context-manager/policy-registry.ts +97 -97
  15. package/.pi/extensions/takomi-context-manager/policy-tools.ts +35 -35
  16. package/.pi/extensions/takomi-context-manager/prerequisite-gates.ts +39 -39
  17. package/.pi/extensions/takomi-context-manager/prompt-rewriter.ts +100 -100
  18. package/.pi/extensions/takomi-context-manager/skill-registry.ts +87 -87
  19. package/.pi/extensions/takomi-context-manager/skill-tools.ts +80 -80
  20. package/.pi/extensions/takomi-context-manager/state.ts +68 -68
  21. package/.pi/extensions/takomi-context-manager/types.ts +77 -77
  22. package/.pi/extensions/takomi-runtime/command-text.ts +10 -2
  23. package/.pi/extensions/takomi-runtime/commands.ts +78 -5
  24. package/.pi/extensions/takomi-runtime/routing-policy.ts +187 -145
  25. package/.pi/extensions/takomi-subagents/native-render.ts +41 -41
  26. package/.pi/extensions/takomi-subagents/pi-subagents-internal.ts +35 -32
  27. package/.pi/extensions/takomi-subagents/run-types.ts +25 -25
  28. package/.pi/prompts/build-prompt.md +259 -259
  29. package/.pi/prompts/design-prompt.md +95 -95
  30. package/.pi/prompts/genesis-prompt.md +140 -140
  31. package/.pi/prompts/prime-prompt.md +110 -110
  32. package/.pi/themes/takomi-aurora.json +88 -88
  33. package/README.md +2 -4
  34. package/assets/.agent/skills/21st-dev-components/SKILL.md +244 -244
  35. package/assets/.agent/skills/anti-gravity/SKILL.md +112 -0
  36. package/assets/.agent/skills/gemini/SKILL.md +14 -223
  37. package/assets/.agent/skills/git-commit-generation/SKILL.md +195 -0
  38. package/package.json +1 -1
  39. package/src/pi-takomi-core/validation.ts +135 -135
@@ -1,145 +1,187 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- export const TAKOMI_ROUTING_POLICY_RELATIVE = path.join(".pi", "takomi", "model-routing.md");
6
- export const BUNDLED_TAKOMI_ROUTING_POLICY_PATH = path.resolve(
7
- path.dirname(fileURLToPath(import.meta.url)),
8
- "..",
9
- "..",
10
- "takomi",
11
- "model-routing.md",
12
- );
13
-
14
- export type RoutingPolicyInstallResult = {
15
- policyPath: string;
16
- settingsPath: string;
17
- settingsUpdated: boolean;
18
- detectedDefaults: string[];
19
- };
20
-
21
- export type RoutingPolicySource = "project" | "bundled" | "missing";
22
-
23
- export type ResolvedRoutingPolicy = {
24
- source: RoutingPolicySource;
25
- policyPath?: string;
26
- text?: string;
27
- };
28
-
29
- type JsonObject = Record<string, unknown>;
30
-
31
- function asObject(value: unknown): JsonObject {
32
- return value && typeof value === "object" && !Array.isArray(value) ? value as JsonObject : {};
33
- }
34
-
35
- async function readJsonObject(filePath: string): Promise<JsonObject> {
36
- try {
37
- return asObject(JSON.parse(await readFile(filePath, "utf8")));
38
- } catch {
39
- return {};
40
- }
41
- }
42
-
43
- async function readPolicyText(filePath: string): Promise<string | undefined> {
44
- try {
45
- const text = (await readFile(filePath, "utf8")).trim();
46
- return text || undefined;
47
- } catch {
48
- return undefined;
49
- }
50
- }
51
-
52
- function extractQuotedPolicy(text: string): string {
53
- const triple = text.match(/"""([\s\S]*?)"""|```(?:\w+)?\s*([\s\S]*?)```/);
54
- const raw = (triple?.[1] ?? triple?.[2] ?? text).trim();
55
- return raw.replace(/^update\s+(?:takomi\s+)?(?:model\s+)?routing\s+(?:logic|policy|philosophy)\s*:?/i, "").trim();
56
- }
57
-
58
- function deriveSubagentDefaults(policy: string): { overrides: JsonObject; detected: string[] } {
59
- const lower = policy.toLowerCase();
60
- const has55 = /gpt[- ]?5\.5/.test(lower);
61
- const has54 = /gpt[- ]?5\.4(?!\s*mini)/.test(lower);
62
- const hasMini = /gpt[- ]?5\.4\s*mini/.test(lower);
63
- if (!has55 && !has54 && !hasMini) return { overrides: {}, detected: [] };
64
-
65
- const model55 = "oauth-router/gpt-5.5";
66
- const model54 = "oauth-router/gpt-5.4";
67
- const modelMini = "oauth-router/gpt-5.4-mini";
68
- const overrides: JsonObject = {};
69
- const detected: string[] = [];
70
-
71
- if (has55) {
72
- overrides.oracle = { model: model55, thinking: "high" };
73
- overrides.reviewer = { model: model55, thinking: "high" };
74
- overrides.planner = { model: model55, thinking: "medium" };
75
- detected.push("oracle/reviewer GPT-5.5 high", "planner → GPT-5.5 medium");
76
- }
77
- if (has54) {
78
- overrides.worker = { model: model54, thinking: "high", fallbackModels: has55 ? [`${model55}:low`] : undefined };
79
- overrides.contextBuilder = { model: model54, thinking: "high" };
80
- overrides["context-builder"] = { model: model54, thinking: "high" };
81
- detected.push("worker/context-builder GPT-5.4 high");
82
- }
83
- if (hasMini) {
84
- overrides.scout = { model: modelMini, thinking: "high" };
85
- overrides.delegate = { model: modelMini, thinking: "high" };
86
- detected.push("scout/delegate → GPT-5.4 Mini high");
87
- }
88
- return { overrides, detected };
89
- }
90
-
91
- export async function resolveTakomiRoutingPolicy(cwd: string): Promise<ResolvedRoutingPolicy> {
92
- const settingsPath = path.join(cwd, ".pi", "settings.json");
93
- const settings = await readJsonObject(settingsPath);
94
- const takomi = asObject(settings.takomi);
95
- const configured = typeof takomi.modelRoutingPolicyFile === "string"
96
- ? takomi.modelRoutingPolicyFile
97
- : TAKOMI_ROUTING_POLICY_RELATIVE;
98
- const configuredPath = path.isAbsolute(configured) ? configured : path.join(cwd, configured);
99
- const configuredText = await readPolicyText(configuredPath);
100
- if (configuredText) {
101
- return { source: "project", policyPath: configuredPath, text: configuredText };
102
- }
103
-
104
- const bundledText = await readPolicyText(BUNDLED_TAKOMI_ROUTING_POLICY_PATH);
105
- if (bundledText) {
106
- return {
107
- source: "bundled",
108
- policyPath: BUNDLED_TAKOMI_ROUTING_POLICY_PATH,
109
- text: bundledText,
110
- };
111
- }
112
-
113
- return { source: "missing" };
114
- }
115
-
116
- export async function installTakomiRoutingPolicy(cwd: string, input: string): Promise<RoutingPolicyInstallResult> {
117
- const policy = extractQuotedPolicy(input);
118
- if (!policy) throw new Error("No routing policy text found. Paste the policy after /takomi routing or inside triple quotes.");
119
-
120
- const policyPath = path.join(cwd, TAKOMI_ROUTING_POLICY_RELATIVE);
121
- const settingsPath = path.join(cwd, ".pi", "settings.json");
122
- await mkdir(path.dirname(policyPath), { recursive: true });
123
- await mkdir(path.dirname(settingsPath), { recursive: true });
124
- await writeFile(policyPath, `# Takomi Model Routing Policy\n\n${policy}\n`, "utf8");
125
-
126
- const settings = await readJsonObject(settingsPath);
127
- const takomi = asObject(settings.takomi);
128
- takomi.modelRoutingPolicyFile = TAKOMI_ROUTING_POLICY_RELATIVE.replaceAll(path.sep, "/");
129
- settings.takomi = takomi;
130
-
131
- const { overrides, detected } = deriveSubagentDefaults(policy);
132
- if (Object.keys(overrides).length > 0) {
133
- const subagents = asObject(settings.subagents);
134
- const existingOverrides = asObject(subagents.agentOverrides);
135
- subagents.agentOverrides = { ...existingOverrides, ...overrides };
136
- settings.subagents = subagents;
137
- }
138
-
139
- await writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
140
- return { policyPath, settingsPath, settingsUpdated: true, detectedDefaults: detected };
141
- }
142
-
143
- export async function loadTakomiRoutingPolicy(cwd: string): Promise<string | undefined> {
144
- return (await resolveTakomiRoutingPolicy(cwd)).text;
145
- }
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ export const TAKOMI_ROUTING_POLICY_RELATIVE = path.join(".pi", "takomi", "model-routing.md");
7
+ export const GLOBAL_TAKOMI_ROUTING_POLICY_PATH = path.join(os.homedir(), ".pi", "takomi", "model-routing.md");
8
+ export const GLOBAL_PI_SETTINGS_PATH = path.join(os.homedir(), ".pi", "agent", "settings.json");
9
+ export const PROJECT_PI_SETTINGS_RELATIVE = path.join(".pi", "settings.json");
10
+ export const BUNDLED_TAKOMI_ROUTING_POLICY_PATH = path.resolve(
11
+ path.dirname(fileURLToPath(import.meta.url)),
12
+ "..",
13
+ "..",
14
+ "takomi",
15
+ "model-routing.md",
16
+ );
17
+
18
+ export type RoutingPolicyInstallResult = {
19
+ policyPath: string;
20
+ settingsPath: string;
21
+ settingsUpdated: boolean;
22
+ detectedDefaults: string[];
23
+ };
24
+
25
+ export type RoutingPolicyInstallScope = "global" | "project";
26
+ export type RoutingPolicySource = "project" | "global" | "bundled" | "missing";
27
+
28
+ export type ResolvedRoutingPolicy = {
29
+ source: RoutingPolicySource;
30
+ policyPath?: string;
31
+ text?: string;
32
+ };
33
+
34
+ type JsonObject = Record<string, unknown>;
35
+
36
+ function asObject(value: unknown): JsonObject {
37
+ return value && typeof value === "object" && !Array.isArray(value) ? value as JsonObject : {};
38
+ }
39
+
40
+ async function readJsonObject(filePath: string): Promise<JsonObject> {
41
+ try {
42
+ return asObject(JSON.parse(await readFile(filePath, "utf8")));
43
+ } catch {
44
+ return {};
45
+ }
46
+ }
47
+
48
+ async function readPolicyText(filePath: string): Promise<string | undefined> {
49
+ try {
50
+ const text = (await readFile(filePath, "utf8")).trim();
51
+ return text || undefined;
52
+ } catch {
53
+ return undefined;
54
+ }
55
+ }
56
+
57
+ function extractQuotedPolicy(text: string): string {
58
+ const triple = text.match(/"""([\s\S]*?)"""|```(?:\w+)?\s*([\s\S]*?)```/);
59
+ const raw = (triple?.[1] ?? triple?.[2] ?? text).trim();
60
+ return raw.replace(/^update\s+(?:takomi\s+)?(?:model\s+)?routing\s+(?:logic|policy|philosophy)\s*:?/i, "").trim();
61
+ }
62
+
63
+ function normalizeForSettings(filePath: string): string {
64
+ return filePath.replaceAll(path.sep, "/");
65
+ }
66
+
67
+ function deriveSubagentDefaults(policy: string): { overrides: JsonObject; detected: string[] } {
68
+ const lower = policy.toLowerCase();
69
+ const has55 = /gpt[- ]?5\.5/.test(lower);
70
+ const has54 = /gpt[- ]?5\.4(?!\s*mini)/.test(lower);
71
+ const hasMini = /gpt[- ]?5\.4\s*mini/.test(lower);
72
+ if (!has55 && !has54 && !hasMini) return { overrides: {}, detected: [] };
73
+
74
+ const model55 = "oauth-router/gpt-5.5";
75
+ const model54 = "oauth-router/gpt-5.4";
76
+ const modelMini = "oauth-router/gpt-5.4-mini";
77
+ const overrides: JsonObject = {};
78
+ const detected: string[] = [];
79
+
80
+ if (has55) {
81
+ overrides.oracle = { model: model55, thinking: "high" };
82
+ overrides.reviewer = { model: model55, thinking: "high" };
83
+ overrides.planner = { model: model55, thinking: "medium" };
84
+ detected.push("oracle/reviewer GPT-5.5 high", "planner → GPT-5.5 medium");
85
+ }
86
+ if (has54) {
87
+ overrides.worker = { model: model54, thinking: "high", fallbackModels: has55 ? [`${model55}:low`] : undefined };
88
+ overrides.contextBuilder = { model: model54, thinking: "high" };
89
+ overrides["context-builder"] = { model: model54, thinking: "high" };
90
+ detected.push("worker/context-builder → GPT-5.4 high");
91
+ }
92
+ if (hasMini) {
93
+ overrides.scout = { model: modelMini, thinking: "high" };
94
+ overrides.delegate = { model: modelMini, thinking: "high" };
95
+ detected.push("scout/delegate GPT-5.4 Mini high");
96
+ }
97
+ return { overrides, detected };
98
+ }
99
+
100
+ export async function resolveTakomiRoutingPolicy(cwd: string): Promise<ResolvedRoutingPolicy> {
101
+ const projectSettingsPath = path.join(cwd, PROJECT_PI_SETTINGS_RELATIVE);
102
+ const projectSettings = await readJsonObject(projectSettingsPath);
103
+ const projectTakomi = asObject(projectSettings.takomi);
104
+ const configuredProject = typeof projectTakomi.modelRoutingPolicyFile === "string"
105
+ ? projectTakomi.modelRoutingPolicyFile
106
+ : TAKOMI_ROUTING_POLICY_RELATIVE;
107
+ const configuredProjectPath = path.isAbsolute(configuredProject) ? configuredProject : path.join(cwd, configuredProject);
108
+ const configuredProjectText = await readPolicyText(configuredProjectPath);
109
+ if (configuredProjectText) {
110
+ return { source: "project", policyPath: configuredProjectPath, text: configuredProjectText };
111
+ }
112
+
113
+ const defaultProjectPath = path.join(cwd, TAKOMI_ROUTING_POLICY_RELATIVE);
114
+ if (path.resolve(defaultProjectPath) !== path.resolve(configuredProjectPath)) {
115
+ const defaultProjectText = await readPolicyText(defaultProjectPath);
116
+ if (defaultProjectText) {
117
+ return { source: "project", policyPath: defaultProjectPath, text: defaultProjectText };
118
+ }
119
+ }
120
+
121
+ const globalSettings = await readJsonObject(GLOBAL_PI_SETTINGS_PATH);
122
+ const globalTakomi = asObject(globalSettings.takomi);
123
+ const configuredGlobal = typeof globalTakomi.modelRoutingPolicyFile === "string"
124
+ ? globalTakomi.modelRoutingPolicyFile
125
+ : GLOBAL_TAKOMI_ROUTING_POLICY_PATH;
126
+ const configuredGlobalPath = path.isAbsolute(configuredGlobal) ? configuredGlobal : path.join(os.homedir(), configuredGlobal);
127
+ const configuredGlobalText = await readPolicyText(configuredGlobalPath);
128
+ if (configuredGlobalText) {
129
+ return { source: "global", policyPath: configuredGlobalPath, text: configuredGlobalText };
130
+ }
131
+
132
+ if (path.resolve(configuredGlobalPath) !== path.resolve(GLOBAL_TAKOMI_ROUTING_POLICY_PATH)) {
133
+ const globalText = await readPolicyText(GLOBAL_TAKOMI_ROUTING_POLICY_PATH);
134
+ if (globalText) {
135
+ return { source: "global", policyPath: GLOBAL_TAKOMI_ROUTING_POLICY_PATH, text: globalText };
136
+ }
137
+ }
138
+
139
+ const bundledText = await readPolicyText(BUNDLED_TAKOMI_ROUTING_POLICY_PATH);
140
+ if (bundledText) {
141
+ return {
142
+ source: "bundled",
143
+ policyPath: BUNDLED_TAKOMI_ROUTING_POLICY_PATH,
144
+ text: bundledText,
145
+ };
146
+ }
147
+
148
+ return { source: "missing" };
149
+ }
150
+
151
+ export async function installTakomiRoutingPolicy(cwd: string, input: string, options: { scope?: RoutingPolicyInstallScope } = {}): Promise<RoutingPolicyInstallResult> {
152
+ const policy = extractQuotedPolicy(input);
153
+ if (!policy) throw new Error("No routing policy text found. Paste the policy after /takomi routing or inside triple quotes.");
154
+
155
+ const scope = options.scope ?? "global";
156
+ const policyPath = scope === "project"
157
+ ? path.join(cwd, TAKOMI_ROUTING_POLICY_RELATIVE)
158
+ : GLOBAL_TAKOMI_ROUTING_POLICY_PATH;
159
+ const settingsPath = scope === "project"
160
+ ? path.join(cwd, PROJECT_PI_SETTINGS_RELATIVE)
161
+ : GLOBAL_PI_SETTINGS_PATH;
162
+ await mkdir(path.dirname(policyPath), { recursive: true });
163
+ await mkdir(path.dirname(settingsPath), { recursive: true });
164
+ await writeFile(policyPath, `# Takomi Model Routing Policy\n\n${policy}\n`, "utf8");
165
+
166
+ const settings = await readJsonObject(settingsPath);
167
+ const takomi = asObject(settings.takomi);
168
+ takomi.modelRoutingPolicyFile = scope === "project"
169
+ ? normalizeForSettings(TAKOMI_ROUTING_POLICY_RELATIVE)
170
+ : normalizeForSettings(GLOBAL_TAKOMI_ROUTING_POLICY_PATH);
171
+ settings.takomi = takomi;
172
+
173
+ const { overrides, detected } = deriveSubagentDefaults(policy);
174
+ if (Object.keys(overrides).length > 0) {
175
+ const subagents = asObject(settings.subagents);
176
+ const existingOverrides = asObject(subagents.agentOverrides);
177
+ subagents.agentOverrides = { ...existingOverrides, ...overrides };
178
+ settings.subagents = subagents;
179
+ }
180
+
181
+ await writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
182
+ return { policyPath, settingsPath, settingsUpdated: true, detectedDefaults: detected };
183
+ }
184
+
185
+ export async function loadTakomiRoutingPolicy(cwd: string): Promise<string | undefined> {
186
+ return (await resolveTakomiRoutingPolicy(cwd)).text;
187
+ }
@@ -1,41 +1,41 @@
1
- import type { AgentToolResult } from "@mariozechner/pi-agent-core";
2
- import type { Theme } from "@mariozechner/pi-coding-agent";
3
- import { Text } from "@mariozechner/pi-tui";
4
- import type { TakomiSubagentToolParams } from "./tool-runner";
5
- import type { Details } from "./pi-subagents-internal";
6
-
7
- type ToolResult = AgentToolResult<Details>;
8
-
9
- function taskList(params: TakomiSubagentToolParams): Array<{ agent: string; task: string }> {
10
- if (params.chain?.length) return params.chain;
11
- if (params.tasks?.length) return params.tasks;
12
- if (params.agent || params.task) return [{ agent: params.agent ?? "...", task: params.task ?? "..." }];
13
- return [];
14
- }
15
-
16
- export function renderTakomiSubagentCall(params: TakomiSubagentToolParams, theme: Theme) {
17
- const tasks = taskList(params);
18
- const mode = params.chain?.length ? "chain" : params.tasks?.length ? "parallel" : "single";
19
- if (tasks.length === 1) {
20
- return new Text(
21
- `${theme.fg("toolTitle", theme.bold("takomi_subagent "))}${theme.fg("accent", tasks[0]?.agent || "?")}`,
22
- 0,
23
- 0,
24
- );
25
- }
26
- return new Text(
27
- `${theme.fg("toolTitle", theme.bold("takomi_subagent "))}${mode} (${tasks.length})`,
28
- 0,
29
- 0,
30
- );
31
- }
32
-
33
- export function renderTakomiSubagentResult(result: ToolResult, _options: { expanded?: boolean; isPartial?: boolean }, theme: Theme, _context: any) {
34
- const status = (result as any)?.error ? "failed" : "completed";
35
- const text = typeof (result as any)?.content === "string"
36
- ? (result as any).content
37
- : Array.isArray((result as any)?.content)
38
- ? (result as any).content.map((part: any) => part?.text ?? "").filter(Boolean).join("\n")
39
- : JSON.stringify((result as any)?.details ?? {}, null, 2);
40
- return new Text(`${theme.fg("toolTitle", theme.bold(`takomi_subagent ${status}`))}\n${text || "No result content."}`, 0, 0);
41
- }
1
+ import type { AgentToolResult } from "@mariozechner/pi-agent-core";
2
+ import type { Theme } from "@mariozechner/pi-coding-agent";
3
+ import { Text } from "@mariozechner/pi-tui";
4
+ import type { TakomiSubagentToolParams } from "./tool-runner";
5
+ import type { Details } from "./pi-subagents-internal";
6
+
7
+ type ToolResult = AgentToolResult<Details>;
8
+
9
+ function taskList(params: TakomiSubagentToolParams): Array<{ agent: string; task: string }> {
10
+ if (params.chain?.length) return params.chain;
11
+ if (params.tasks?.length) return params.tasks;
12
+ if (params.agent || params.task) return [{ agent: params.agent ?? "...", task: params.task ?? "..." }];
13
+ return [];
14
+ }
15
+
16
+ export function renderTakomiSubagentCall(params: TakomiSubagentToolParams, theme: Theme) {
17
+ const tasks = taskList(params);
18
+ const mode = params.chain?.length ? "chain" : params.tasks?.length ? "parallel" : "single";
19
+ if (tasks.length === 1) {
20
+ return new Text(
21
+ `${theme.fg("toolTitle", theme.bold("takomi_subagent "))}${theme.fg("accent", tasks[0]?.agent || "?")}`,
22
+ 0,
23
+ 0,
24
+ );
25
+ }
26
+ return new Text(
27
+ `${theme.fg("toolTitle", theme.bold("takomi_subagent "))}${mode} (${tasks.length})`,
28
+ 0,
29
+ 0,
30
+ );
31
+ }
32
+
33
+ export function renderTakomiSubagentResult(result: ToolResult, _options: { expanded?: boolean; isPartial?: boolean }, theme: Theme, _context: any) {
34
+ const status = (result as any)?.error ? "failed" : "completed";
35
+ const text = typeof (result as any)?.content === "string"
36
+ ? (result as any).content
37
+ : Array.isArray((result as any)?.content)
38
+ ? (result as any).content.map((part: any) => part?.text ?? "").filter(Boolean).join("\n")
39
+ : JSON.stringify((result as any)?.details ?? {}, null, 2);
40
+ return new Text(`${theme.fg("toolTitle", theme.bold(`takomi_subagent ${status}`))}\n${text || "No result content."}`, 0, 0);
41
+ }
@@ -1,32 +1,35 @@
1
- // Centralizes Takomi's current pi-subagents internal imports.
2
- // pi-subagents ships TS internals rather than a stable public JS API. Import them
3
- // dynamically with computed specifiers so Takomi's own tsc does not type-check
4
- // dependency source, while Pi's runtime TS loader can still load them.
5
-
6
- const dynamicImport = new Function("specifier", "return import(specifier)") as <T = any>(specifier: string) => Promise<T>;
7
- const spec = (path: string) => `pi-subagents/${path}.ts`;
8
-
9
- export async function loadPiSubagentsInternals() {
10
- const [executorModule, agentsModule, sharedTypesModule, renderModule] = await Promise.all([
11
- dynamicImport(spec("src/runs/foreground/subagent-executor")),
12
- dynamicImport(spec("src/agents/agents")),
13
- dynamicImport(spec("src/shared/types")),
14
- dynamicImport(spec("src/tui/render")),
15
- ]);
16
-
17
- return {
18
- createSubagentExecutor: executorModule.createSubagentExecutor,
19
- discoverPiAgents: agentsModule.discoverAgents,
20
- DEFAULT_ARTIFACT_CONFIG: sharedTypesModule.DEFAULT_ARTIFACT_CONFIG,
21
- TEMP_ARTIFACTS_DIR: sharedTypesModule.TEMP_ARTIFACTS_DIR,
22
- renderSubagentResult: renderModule.renderSubagentResult,
23
- syncResultAnimation: renderModule.syncResultAnimation,
24
- };
25
- }
26
-
27
- export type SubagentParamsLike = any;
28
- export type AgentConfig = any;
29
- export type AgentScope = "user" | "project" | "both";
30
- export type Details = any;
31
- export type ExtensionConfig = any;
32
- export type SubagentState = any;
1
+ // Centralizes Takomi's current pi-subagents internal imports.
2
+ // pi-subagents ships TS internals rather than a stable public JS API. Import them
3
+ // dynamically with computed specifiers so Takomi's own tsc does not type-check
4
+ // dependency source, while Pi's runtime TS loader can still load them.
5
+ // Do not hide import() inside Function/eval: Pi's extension VM does not provide
6
+ // a dynamic import callback for that path and fails with
7
+ // "A dynamic import callback was not specified."
8
+
9
+ const dynamicImport = async <T = any>(specifier: string): Promise<T> => import(specifier) as Promise<T>;
10
+ const spec = (path: string) => `pi-subagents/${path}.ts`;
11
+
12
+ export async function loadPiSubagentsInternals() {
13
+ const [executorModule, agentsModule, sharedTypesModule, renderModule] = await Promise.all([
14
+ dynamicImport(spec("src/runs/foreground/subagent-executor")),
15
+ dynamicImport(spec("src/agents/agents")),
16
+ dynamicImport(spec("src/shared/types")),
17
+ dynamicImport(spec("src/tui/render")),
18
+ ]);
19
+
20
+ return {
21
+ createSubagentExecutor: executorModule.createSubagentExecutor,
22
+ discoverPiAgents: agentsModule.discoverAgents,
23
+ DEFAULT_ARTIFACT_CONFIG: sharedTypesModule.DEFAULT_ARTIFACT_CONFIG,
24
+ TEMP_ARTIFACTS_DIR: sharedTypesModule.TEMP_ARTIFACTS_DIR,
25
+ renderSubagentResult: renderModule.renderSubagentResult,
26
+ syncResultAnimation: renderModule.syncResultAnimation,
27
+ };
28
+ }
29
+
30
+ export type SubagentParamsLike = any;
31
+ export type AgentConfig = any;
32
+ export type AgentScope = "user" | "project" | "both";
33
+ export type Details = any;
34
+ export type ExtensionConfig = any;
35
+ export type SubagentState = any;
@@ -1,25 +1,25 @@
1
- import type { TakomiThinkingLevel } from "../../../src/pi-takomi-core";
2
-
3
- export type TakomiDispatchResult = {
4
- agent: string;
5
- task: string;
6
- workflow?: string;
7
- model?: string;
8
- warning?: string;
9
- thinking?: TakomiThinkingLevel;
10
- conversationId: string;
11
- code: number;
12
- output: string;
13
- stderr: string;
14
- preflight: string;
15
- startedAt?: number;
16
- endedAt?: number;
17
- lastActivityAt?: number;
18
- currentTool?: string;
19
- currentToolArgs?: string;
20
- currentToolStartedAt?: number;
21
- recentTools?: Array<{ tool: string; args: string; endMs: number }>;
22
- recentOutput?: string[];
23
- toolCount?: number;
24
- sessionFile?: string;
25
- };
1
+ import type { TakomiThinkingLevel } from "../../../src/pi-takomi-core";
2
+
3
+ export type TakomiDispatchResult = {
4
+ agent: string;
5
+ task: string;
6
+ workflow?: string;
7
+ model?: string;
8
+ warning?: string;
9
+ thinking?: TakomiThinkingLevel;
10
+ conversationId: string;
11
+ code: number;
12
+ output: string;
13
+ stderr: string;
14
+ preflight: string;
15
+ startedAt?: number;
16
+ endedAt?: number;
17
+ lastActivityAt?: number;
18
+ currentTool?: string;
19
+ currentToolArgs?: string;
20
+ currentToolStartedAt?: number;
21
+ recentTools?: Array<{ tool: string; args: string; endMs: number }>;
22
+ recentOutput?: string[];
23
+ toolCount?: number;
24
+ sessionFile?: string;
25
+ };