takomi 2.1.32 → 2.1.34
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/.pi/extensions/oauth-router/config.ts +14 -5
- package/.pi/extensions/oauth-router/index.ts +130 -130
- package/.pi/extensions/oauth-router/provider.ts +29 -0
- package/.pi/extensions/oauth-router/state.ts +372 -372
- package/.pi/extensions/oauth-router/types.ts +1 -1
- package/.pi/extensions/takomi-runtime/command-text.ts +2 -4
- package/.pi/extensions/takomi-runtime/commands.ts +15 -21
- package/.pi/extensions/takomi-runtime/index.ts +127 -53
- package/.pi/extensions/takomi-runtime/model-routing-defaults.ts +296 -296
- package/.pi/extensions/takomi-runtime/ui.ts +18 -11
- package/.pi/extensions/takomi-subagents/index.ts +2 -0
- package/.pi/extensions/takomi-subagents/native-render.ts +27 -5
- package/.pi/extensions/takomi-subagents/pi-subagents-engine.ts +1 -1
- package/.pi/extensions/takomi-subagents/tool-runner.ts +1 -0
- package/assets/.agent/skills/photo-book-builder/SKILL.md +96 -0
- package/assets/.agent/skills/photo-book-builder/references/layout_templates.md +72 -0
- package/assets/.agent/skills/photo-book-builder/scripts/create_full_bleed_layouts.py +212 -0
- package/assets/.agent/skills/photo-book-builder/scripts/organize_photos.py +99 -0
- package/assets/.agent/skills/photo-book-builder/scripts/revert_organization.py +61 -0
- package/assets/.agent/skills/photo-book-builder/scripts/upscale_covers.py +47 -0
- package/assets/.agent/skills/youtube-pipeline/SKILL.md +73 -62
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Application.md +1 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Phase 1.md +86 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Phase 2.md +106 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Phase 3.md +112 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Phase 4.md +90 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Phased Outline.md +58 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Repurposing.md +1 -0
- package/assets/.agent/skills/youtube-pipeline/resources/knowledge/Research.md +438 -0
- package/assets/.agent/skills/youtube-pipeline/resources/prompts/Shorts Bridge Protocol.md +159 -0
- package/assets/.agent/skills/youtube-pipeline/resources/prompts/Title Thumbnail Picker Prompt.md +144 -0
- package/assets/.agent/skills/youtube-pipeline/resources/prompts/Transcription Extraction Prompt v2.md +190 -0
- package/assets/.agent/skills/youtube-pipeline/resources/prompts/Transcription Extraction Prompt.md +156 -0
- package/assets/.agent/skills/youtube-pipeline/resources/prompts/Video QA Prompt.md +133 -0
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-phase1-strategy.md +28 -18
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-phase2-packaging.md +2 -2
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-phase3-scripting.md +2 -2
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-phase3.5-shorts.md +2 -2
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-phase4-production.md +2 -2
- package/assets/.agent/skills/youtube-pipeline/resources/youtube-pipeline.md +15 -15
- package/assets/.agent/skills/youtube-pipeline/scripts/google-trends/package.json +17 -0
- package/assets/.agent/skills/youtube-pipeline/scripts/google-trends/pnpm-lock.yaml +31 -0
- package/assets/.agent/skills/youtube-pipeline/scripts/google-trends/search.js +168 -0
- package/package.json +1 -1
- package/src/cli.js +13 -4
- package/src/pi-harness.js +36 -14
- package/src/pi-optional-features.js +190 -190
- package/src/postinstall.js +27 -27
- package/src/skills-catalog.js +245 -245
- package/src/skills-installer.js +244 -244
- package/src/skills-selection-tui.js +200 -200
- package/src/store.js +418 -418
- package/src/takomi-stats.d.ts +3 -3
- package/src/takomi-stats.js +442 -35
|
@@ -213,7 +213,7 @@ export interface DelegateSelection {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
export interface FailureClassification {
|
|
216
|
-
kind: "rate-limit" | "auth" | "transient" | "client-network" | "fatal";
|
|
216
|
+
kind: "rate-limit" | "auth" | "transient" | "client-network" | "context-overflow" | "fatal";
|
|
217
217
|
status?: number;
|
|
218
218
|
retryAfterMs?: number;
|
|
219
219
|
message: string;
|
|
@@ -35,9 +35,6 @@ const SUBCOMMAND_COMPLETIONS: Record<string, TakomiCompletion[]> = {
|
|
|
35
35
|
{ value: "status", label: "status", description: "Show active subagents" },
|
|
36
36
|
{ value: "on", label: "on", description: "Allow subagent delegation" },
|
|
37
37
|
{ value: "off", label: "off", description: "Disable subagent delegation" },
|
|
38
|
-
{ value: "expand", label: "expand", description: "Expand native tool results" },
|
|
39
|
-
{ value: "collapse", label: "collapse", description: "Collapse native tool results" },
|
|
40
|
-
{ value: "toggle", label: "toggle", description: "Toggle native tool result expansion" },
|
|
41
38
|
],
|
|
42
39
|
stats: [
|
|
43
40
|
{ value: "overview", label: "overview", description: "Show the full profile-card dashboard" },
|
|
@@ -98,7 +95,7 @@ export function commandHelp(): string {
|
|
|
98
95
|
"/takomi plan [title]",
|
|
99
96
|
"/takomi mode <direct|orchestrate|review>",
|
|
100
97
|
"/takomi gate <auto|review>",
|
|
101
|
-
"/takomi subagents <on|off|status
|
|
98
|
+
"/takomi subagents <on|off|status>",
|
|
102
99
|
"/takomi stats [overview|daily|models|projects|projects-full|sessions|sessions-full|tasks|tasks-full|tools|subagents|sources] [since 7d]",
|
|
103
100
|
"/takomi routing [show|where]",
|
|
104
101
|
"/takomi routing <policy text> # updates global policy",
|
|
@@ -134,6 +131,7 @@ export function statusText(state: TakomiRuntimeCommandState, subagentController:
|
|
|
134
131
|
return [
|
|
135
132
|
`Takomi: ${state.enabled ? "on" : "off"}`,
|
|
136
133
|
`Mode: ${state.role}`,
|
|
134
|
+
`Source: ${state.modeSource ?? "idle"}${state.modeReason ? ` (${state.modeReason})` : ""}`,
|
|
137
135
|
`Stage: ${state.stage ?? "-"}`,
|
|
138
136
|
`Workflow: ${state.workflow ?? "-"}`,
|
|
139
137
|
`Plan bias: ${state.planMode ? "on" : "off"}`,
|
|
@@ -20,6 +20,8 @@ export type TakomiRuntimeCommandState = {
|
|
|
20
20
|
workflow?: TakomiWorkflowId;
|
|
21
21
|
activeSessionId?: string;
|
|
22
22
|
subagentsEnabled: boolean;
|
|
23
|
+
modeSource?: "idle" | "manual" | "model" | "board";
|
|
24
|
+
modeReason?: string;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
type RegisterTakomiCommandOptions = {
|
|
@@ -36,6 +38,8 @@ export function registerTakomiCommands(pi: ExtensionAPI, options: RegisterTakomi
|
|
|
36
38
|
async function handleStage(ctx: ExtensionCommandContext, stage: VibeLifecycleStage, prompt?: string): Promise<void> {
|
|
37
39
|
await options.updateState(ctx, () => {
|
|
38
40
|
options.getState().enabled = true;
|
|
41
|
+
options.getState().modeSource = "manual";
|
|
42
|
+
options.getState().modeReason = `/${stage}`;
|
|
39
43
|
options.setStageAndWorkflow(stage, { preserveRole: stage === "genesis" && options.getState().role === "orchestrator" });
|
|
40
44
|
options.getState().planMode = stage !== "build";
|
|
41
45
|
}, workflowPrompt(stage, prompt));
|
|
@@ -54,17 +58,27 @@ export function registerTakomiCommands(pi: ExtensionAPI, options: RegisterTakomi
|
|
|
54
58
|
state.autoOrch = false;
|
|
55
59
|
state.planMode = false;
|
|
56
60
|
state.role = "general";
|
|
61
|
+
state.stage = undefined;
|
|
62
|
+
state.workflow = undefined;
|
|
63
|
+
state.modeSource = "idle";
|
|
64
|
+
state.modeReason = undefined;
|
|
57
65
|
} else if (mode === "orchestrate") {
|
|
58
66
|
state.autoOrch = true;
|
|
59
67
|
state.planMode = true;
|
|
60
68
|
state.role = "orchestrator";
|
|
61
69
|
state.stage = hasGenesis ? "build" : "genesis";
|
|
62
70
|
state.workflow = hasGenesis ? "vibe-build" : "vibe-genesis";
|
|
71
|
+
state.modeSource = "manual";
|
|
72
|
+
state.modeReason = "/takomi mode orchestrate";
|
|
63
73
|
} else {
|
|
64
74
|
state.autoOrch = false;
|
|
65
75
|
state.planMode = true;
|
|
66
76
|
state.launchMode = "manual";
|
|
67
77
|
state.role = "review";
|
|
78
|
+
state.stage = undefined;
|
|
79
|
+
state.workflow = undefined;
|
|
80
|
+
state.modeSource = "manual";
|
|
81
|
+
state.modeReason = "/takomi mode review";
|
|
68
82
|
}
|
|
69
83
|
}, () => `Takomi mode set to ${mode}`);
|
|
70
84
|
}
|
|
@@ -198,27 +212,7 @@ export function registerTakomiCommands(pi: ExtensionAPI, options: RegisterTakomi
|
|
|
198
212
|
ctx.ui.notify(statusText(options.getState(), controller), controller.hasRuns() ? "info" : "warning");
|
|
199
213
|
return;
|
|
200
214
|
}
|
|
201
|
-
|
|
202
|
-
ctx.ui.setToolsExpanded(true);
|
|
203
|
-
ctx.ui.notify("Expanded native tool results for Takomi subagent output.", "info");
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
if (action === "collapse") {
|
|
207
|
-
ctx.ui.setToolsExpanded(false);
|
|
208
|
-
ctx.ui.notify("Collapsed native tool results.", "info");
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
if (action === "toggle") {
|
|
212
|
-
const expanded = !ctx.ui.getToolsExpanded();
|
|
213
|
-
ctx.ui.setToolsExpanded(expanded);
|
|
214
|
-
ctx.ui.notify(`${expanded ? "Expanded" : "Collapsed"} native tool results.`, "info");
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (action === "next" || action === "prev") {
|
|
218
|
-
ctx.ui.notify("Takomi now uses Pi's native inline result UI. Subagent navigation is handled by the transcript/tool results.", "info");
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
ctx.ui.notify("Usage: /takomi subagents <on|off|status|expand|collapse|toggle>", "warning");
|
|
215
|
+
ctx.ui.notify("Usage: /takomi subagents <on|off|status>", "warning");
|
|
222
216
|
}
|
|
223
217
|
|
|
224
218
|
pi.registerCommand("takomi", {
|
|
@@ -58,6 +58,8 @@ import {
|
|
|
58
58
|
} from "./profile";
|
|
59
59
|
import { installTakomiRoutingPolicy, previewTakomiRoutingPolicy, renderRoutingPolicyPreview, resolveTakomiRoutingPolicy } from "./routing-policy";
|
|
60
60
|
|
|
61
|
+
type TakomiModeSource = "idle" | "manual" | "model" | "board";
|
|
62
|
+
|
|
61
63
|
type TakomiState = {
|
|
62
64
|
enabled: boolean;
|
|
63
65
|
autoOrch: boolean;
|
|
@@ -69,15 +71,18 @@ type TakomiState = {
|
|
|
69
71
|
activeSessionId?: string;
|
|
70
72
|
subagentsEnabled: boolean;
|
|
71
73
|
lastFullPromptKey?: string;
|
|
74
|
+
modeSource?: TakomiModeSource;
|
|
75
|
+
modeReason?: string;
|
|
72
76
|
};
|
|
73
77
|
|
|
74
78
|
const DEFAULT_STATE: TakomiState = {
|
|
75
79
|
enabled: true,
|
|
76
|
-
autoOrch:
|
|
80
|
+
autoOrch: false,
|
|
77
81
|
launchMode: "auto",
|
|
78
82
|
planMode: false,
|
|
79
83
|
role: "general",
|
|
80
84
|
subagentsEnabled: true,
|
|
85
|
+
modeSource: "idle",
|
|
81
86
|
};
|
|
82
87
|
|
|
83
88
|
const STATE_ENTRY = "takomi-runtime-state";
|
|
@@ -97,6 +102,8 @@ const ThinkingSchema = Type.Union([
|
|
|
97
102
|
Type.Literal("xhigh"),
|
|
98
103
|
]);
|
|
99
104
|
|
|
105
|
+
const TakomiModeSchema = StringEnum(["idle", "code", "orchestrate", "review", "genesis", "design", "build"] as const);
|
|
106
|
+
|
|
100
107
|
function cloneState(state: TakomiState): TakomiState {
|
|
101
108
|
return { ...state };
|
|
102
109
|
}
|
|
@@ -111,6 +118,8 @@ function formatState(state: TakomiState): string {
|
|
|
111
118
|
`launch=${state.launchMode}`,
|
|
112
119
|
`plan=${state.planMode ? "on" : "off"}`,
|
|
113
120
|
`subagents=${state.subagentsEnabled ? "on" : "off"}`,
|
|
121
|
+
`source=${state.modeSource ?? "idle"}`,
|
|
122
|
+
state.modeReason ? `reason=${state.modeReason}` : "",
|
|
114
123
|
state.activeSessionId ? `session=${state.activeSessionId}` : "",
|
|
115
124
|
].filter(Boolean).join(" | ");
|
|
116
125
|
}
|
|
@@ -766,6 +775,8 @@ export default function takomiRuntime(pi: ExtensionAPI) {
|
|
|
766
775
|
state.stage = "genesis";
|
|
767
776
|
state.workflow = "vibe-genesis";
|
|
768
777
|
state.role = "orchestrator";
|
|
778
|
+
state.modeSource = "manual";
|
|
779
|
+
state.modeReason = "/takomi plan";
|
|
769
780
|
});
|
|
770
781
|
return `Takomi plan created session ${session.sessionId}\nMaster plan: ${paths.masterPlan}`;
|
|
771
782
|
},
|
|
@@ -783,34 +794,82 @@ export default function takomiRuntime(pi: ExtensionAPI) {
|
|
|
783
794
|
},
|
|
784
795
|
});
|
|
785
796
|
|
|
786
|
-
pi.registerShortcut("alt+t", {
|
|
787
|
-
description: "Toggle native tool result expansion",
|
|
788
|
-
handler: async (ctx) => {
|
|
789
|
-
const expanded = !ctx.ui.getToolsExpanded();
|
|
790
|
-
ctx.ui.setToolsExpanded(expanded);
|
|
791
|
-
ctx.ui.notify(`${expanded ? "Expanded" : "Collapsed"} native tool results.`, "info");
|
|
792
|
-
},
|
|
793
|
-
});
|
|
794
797
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
798
|
+
async function applyTakomiMode(ctx: ExtensionContext, mode: string, source: TakomiModeSource, reason?: string): Promise<string> {
|
|
799
|
+
const hasGenesis = await hasGenesisArtifacts(ctx.cwd);
|
|
800
|
+
state.enabled = true;
|
|
801
|
+
state.modeSource = source;
|
|
802
|
+
state.modeReason = reason?.trim() || undefined;
|
|
803
|
+
|
|
804
|
+
switch (mode) {
|
|
805
|
+
case "idle":
|
|
806
|
+
state.modeSource = "idle";
|
|
807
|
+
state.modeReason = undefined;
|
|
808
|
+
state.autoOrch = false;
|
|
809
|
+
state.planMode = false;
|
|
810
|
+
state.role = "general";
|
|
811
|
+
state.stage = undefined;
|
|
812
|
+
state.workflow = undefined;
|
|
813
|
+
break;
|
|
814
|
+
case "code":
|
|
815
|
+
state.autoOrch = false;
|
|
816
|
+
state.planMode = false;
|
|
817
|
+
state.role = "code";
|
|
818
|
+
state.stage = undefined;
|
|
819
|
+
state.workflow = undefined;
|
|
820
|
+
break;
|
|
821
|
+
case "review":
|
|
822
|
+
state.autoOrch = false;
|
|
823
|
+
state.planMode = true;
|
|
824
|
+
state.launchMode = "manual";
|
|
825
|
+
state.role = "review";
|
|
826
|
+
state.stage = undefined;
|
|
827
|
+
state.workflow = undefined;
|
|
828
|
+
break;
|
|
829
|
+
case "orchestrate":
|
|
830
|
+
state.autoOrch = true;
|
|
831
|
+
state.planMode = true;
|
|
832
|
+
state.role = "orchestrator";
|
|
833
|
+
state.stage = hasGenesis ? "build" : "genesis";
|
|
834
|
+
state.workflow = hasGenesis ? "vibe-build" : "vibe-genesis";
|
|
835
|
+
break;
|
|
836
|
+
case "genesis":
|
|
837
|
+
case "design":
|
|
838
|
+
case "build":
|
|
839
|
+
setStageAndWorkflow(state, mode);
|
|
840
|
+
state.autoOrch = mode === "build";
|
|
841
|
+
state.planMode = mode !== "build";
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
802
844
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}
|
|
808
|
-
}
|
|
845
|
+
persistState();
|
|
846
|
+
syncContextPanelState();
|
|
847
|
+
await refreshUi(ctx, state);
|
|
848
|
+
const label = state.modeSource === "idle" ? "idle" : `${state.modeSource}:${state.stage ?? state.role}`;
|
|
849
|
+
return `Takomi mode set to ${label}${state.modeReason ? ` (${state.modeReason})` : ""}.`;
|
|
850
|
+
}
|
|
809
851
|
|
|
810
|
-
pi.
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
852
|
+
pi.registerTool({
|
|
853
|
+
name: "takomi_mode",
|
|
854
|
+
label: "Takomi Mode",
|
|
855
|
+
description: "Set or clear the visible Takomi runtime mode after the active model decides a task benefits from code, review, lifecycle, or orchestration handling.",
|
|
856
|
+
promptSnippet: "Optional: call takomi_mode when you decide the current request should visibly enter Takomi code/review/orchestration/lifecycle mode. Do not call it for normal creative/general conversation. Use mode=idle to clear Takomi mode.",
|
|
857
|
+
promptGuidelines: [
|
|
858
|
+
"Let the user's request drive the choice; do not switch modes just because a vague word like code/review/build appears alone.",
|
|
859
|
+
"Prefer mode=code for direct coding in the current chat, mode=orchestrate only for broad/multi-step durable work, and mode=review for critique/audit/QA.",
|
|
860
|
+
"Use mode=idle when the user asks normal non-coding/non-Takomi questions and Takomi should get out of the way.",
|
|
861
|
+
],
|
|
862
|
+
parameters: Type.Object({
|
|
863
|
+
mode: TakomiModeSchema,
|
|
864
|
+
reason: Type.Optional(Type.String({ description: "Short human-readable reason for the switch" })),
|
|
865
|
+
}),
|
|
866
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
867
|
+
const text = await applyTakomiMode(ctx, params.mode, "model", params.reason);
|
|
868
|
+
ctx.ui.notify(text, "info");
|
|
869
|
+
return {
|
|
870
|
+
content: [{ type: "text", text }],
|
|
871
|
+
details: { mode: params.mode, source: state.modeSource, reason: state.modeReason, role: state.role, stage: state.stage, workflow: state.workflow },
|
|
872
|
+
};
|
|
814
873
|
},
|
|
815
874
|
});
|
|
816
875
|
|
|
@@ -1007,6 +1066,12 @@ ${stateJson}`
|
|
|
1007
1066
|
}
|
|
1008
1067
|
}
|
|
1009
1068
|
sessionState.tasks[idx] = nextTask;
|
|
1069
|
+
state.activeSessionId = params.sessionId;
|
|
1070
|
+
state.modeSource = state.modeSource === "idle" ? "board" : state.modeSource;
|
|
1071
|
+
state.modeReason = state.modeReason ?? "board task update";
|
|
1072
|
+
persistState();
|
|
1073
|
+
syncContextPanelState();
|
|
1074
|
+
await refreshUi(ctx, state);
|
|
1010
1075
|
const nextState = buildSessionState(
|
|
1011
1076
|
sessionState.sessionId,
|
|
1012
1077
|
sessionState.title,
|
|
@@ -1062,8 +1127,11 @@ ${stateJson}`
|
|
|
1062
1127
|
}
|
|
1063
1128
|
}
|
|
1064
1129
|
state.activeSessionId = nextState.sessionId;
|
|
1130
|
+
state.modeSource = "board";
|
|
1131
|
+
state.modeReason = `expanded ${params.stage} stage`;
|
|
1065
1132
|
persistState();
|
|
1066
1133
|
syncContextPanelState();
|
|
1134
|
+
await refreshUi(ctx, state);
|
|
1067
1135
|
|
|
1068
1136
|
return {
|
|
1069
1137
|
content: [{ type: "text", text: `Expanded ${params.stage} stage in session ${nextState.sessionId}.\n\nDocs: ${paths.root}\nState: ${paths.stateFile}\n\n${buildTaskRows(nextState.tasks)}` }],
|
|
@@ -1104,8 +1172,11 @@ ${stateJson}`
|
|
|
1104
1172
|
state.role = "orchestrator";
|
|
1105
1173
|
state.stage = nextState.lifecycle.genesis.status === "completed" ? "build" : "genesis";
|
|
1106
1174
|
state.workflow = state.stage === "genesis" ? "vibe-genesis" : "vibe-build";
|
|
1175
|
+
state.modeSource = "board";
|
|
1176
|
+
state.modeReason = "orchestrator session";
|
|
1107
1177
|
persistState();
|
|
1108
1178
|
syncContextPanelState();
|
|
1179
|
+
await refreshUi(ctx, state);
|
|
1109
1180
|
|
|
1110
1181
|
return {
|
|
1111
1182
|
content: [{ type: "text", text: `Created Takomi orchestrator session ${nextState.sessionId} in hybrid mode\n\nDocs: ${paths.root}\nState: ${paths.stateFile}\n\n${buildTaskRows(nextState.tasks) || "No tasks provided."}` }],
|
|
@@ -1152,11 +1223,15 @@ ${stateJson}`
|
|
|
1152
1223
|
|
|
1153
1224
|
if (lowered === "use takomi") {
|
|
1154
1225
|
state.enabled = true;
|
|
1226
|
+
state.modeSource = "manual";
|
|
1227
|
+
state.modeReason = "explicit user request";
|
|
1155
1228
|
return { action: "transform", text: "Use the Takomi runtime, identify the correct lifecycle stage, and proceed accordingly." };
|
|
1156
1229
|
}
|
|
1157
1230
|
|
|
1158
1231
|
if (lowered.startsWith("use takomi ")) {
|
|
1159
1232
|
state.enabled = true;
|
|
1233
|
+
state.modeSource = "manual";
|
|
1234
|
+
state.modeReason = "explicit user request";
|
|
1160
1235
|
const route = decideRoute(text.slice("use takomi ".length));
|
|
1161
1236
|
if (route.stage) setStageAndWorkflow(state, route.stage, { preserveRole: state.role === "orchestrator" && route.stage === "genesis" });
|
|
1162
1237
|
else if (route.role !== "general") state.role = route.role;
|
|
@@ -1164,14 +1239,20 @@ ${stateJson}`
|
|
|
1164
1239
|
}
|
|
1165
1240
|
|
|
1166
1241
|
if (/\bvibe genesis\b/i.test(text)) {
|
|
1242
|
+
state.modeSource = "manual";
|
|
1243
|
+
state.modeReason = "vibe genesis";
|
|
1167
1244
|
setStageAndWorkflow(state, "genesis", { preserveRole: state.role === "orchestrator" });
|
|
1168
1245
|
return { action: "transform", text };
|
|
1169
1246
|
}
|
|
1170
1247
|
if (/\bvibe design\b/i.test(text)) {
|
|
1248
|
+
state.modeSource = "manual";
|
|
1249
|
+
state.modeReason = "vibe design";
|
|
1171
1250
|
setStageAndWorkflow(state, "design");
|
|
1172
1251
|
return { action: "transform", text };
|
|
1173
1252
|
}
|
|
1174
1253
|
if (/\bvibe build\b/i.test(text)) {
|
|
1254
|
+
state.modeSource = "manual";
|
|
1255
|
+
state.modeReason = "vibe build";
|
|
1175
1256
|
setStageAndWorkflow(state, "build");
|
|
1176
1257
|
return { action: "transform", text };
|
|
1177
1258
|
}
|
|
@@ -1180,43 +1261,36 @@ ${stateJson}`
|
|
|
1180
1261
|
});
|
|
1181
1262
|
|
|
1182
1263
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
1183
|
-
if (!state.enabled) return;
|
|
1264
|
+
if (!state.enabled || (state.modeSource ?? "idle") === "idle") return;
|
|
1184
1265
|
|
|
1185
1266
|
let effectiveState = cloneState(state);
|
|
1186
1267
|
const runtimeCwd = ctx.cwd;
|
|
1187
1268
|
const genesisExists = await hasGenesisArtifacts(runtimeCwd);
|
|
1188
1269
|
const route = decideRoute(event.prompt);
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
effectiveState.workflow = genesisExists ? "vibe-build" : "vibe-genesis";
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
const shouldHonorRoute = route.stage || route.role !== "general" || route.sessionRecommendation !== "none";
|
|
1196
|
-
if (shouldHonorRoute && route.stage) {
|
|
1197
|
-
effectiveState.stage = route.stage;
|
|
1198
|
-
effectiveState.workflow = route.workflow;
|
|
1199
|
-
effectiveState.role = effectiveState.role === "orchestrator" && route.stage === "genesis" ? "orchestrator" : route.role;
|
|
1200
|
-
} else if (shouldHonorRoute && route.role !== "general") {
|
|
1201
|
-
effectiveState.role = route.role;
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
let routingNote = route.reason;
|
|
1270
|
+
let routingNote = state.modeReason
|
|
1271
|
+
? `Takomi mode selected by ${state.modeSource}: ${state.modeReason}.`
|
|
1272
|
+
: `Takomi mode selected by ${state.modeSource ?? "runtime"}.`;
|
|
1205
1273
|
const explicitLifecycleWaiver = /skip genesis|waive genesis|genesis complete|already have (a )?(prd|requirements)|design complete|jump straight to build/i.test(event.prompt);
|
|
1206
|
-
const orchestrationActive = effectiveState.role === "orchestrator"
|
|
1274
|
+
const orchestrationActive = effectiveState.role === "orchestrator";
|
|
1207
1275
|
if (!genesisExists && orchestrationActive && !explicitLifecycleWaiver) {
|
|
1208
1276
|
effectiveState.stage = "genesis";
|
|
1209
1277
|
effectiveState.workflow = "vibe-genesis";
|
|
1210
1278
|
routingNote = "Blank project detected; orchestrator remains in control and must honor Genesis → Design → Build.";
|
|
1211
1279
|
}
|
|
1280
|
+
if (effectiveState.stage !== state.stage || effectiveState.workflow !== state.workflow || effectiveState.role !== state.role) {
|
|
1281
|
+
state.role = effectiveState.role;
|
|
1282
|
+
state.stage = effectiveState.stage;
|
|
1283
|
+
state.workflow = effectiveState.workflow;
|
|
1284
|
+
}
|
|
1212
1285
|
|
|
1213
1286
|
const promptKey = `${effectiveState.role}:${effectiveState.workflow ?? "none"}`;
|
|
1214
1287
|
const includeFullWorkflow = Boolean(effectiveState.workflow && effectiveState.lastFullPromptKey !== promptKey);
|
|
1215
1288
|
if (includeFullWorkflow) {
|
|
1216
1289
|
state.lastFullPromptKey = promptKey;
|
|
1217
|
-
persistState();
|
|
1218
|
-
syncContextPanelState();
|
|
1219
1290
|
}
|
|
1291
|
+
persistState();
|
|
1292
|
+
syncContextPanelState();
|
|
1293
|
+
await refreshUi(ctx, state);
|
|
1220
1294
|
|
|
1221
1295
|
const routingPolicy = await resolveTakomiRoutingPolicy(runtimeCwd);
|
|
1222
1296
|
const optionalFeatureContext = (() => {
|
|
@@ -1263,14 +1337,14 @@ ${stateJson}`
|
|
|
1263
1337
|
`Execution mode: ${route.executionMode}. Session recommendation: ${route.sessionRecommendation}.`,
|
|
1264
1338
|
`Takomi execution gate: ${effectiveState.launchMode === "manual" ? "review" : "auto"}. In review gate mode, show the delegation plan before launching and return to the user after each task with results, verification guidance, and the recommended next step.`,
|
|
1265
1339
|
!effectiveState.subagentsEnabled ? "Takomi subagents are disabled for this session. Do not call takomi_subagent or subagent until the user enables subagents." : "",
|
|
1266
|
-
!genesisExists ? "Project foundation is missing or incomplete. Do not skip Genesis unless the user explicitly waives it." : "",
|
|
1267
|
-
"
|
|
1268
|
-
"Task fan-out is flexible. Do not force exactly three tasks; decompose Genesis, Design, and Build work to fit the actual scope.",
|
|
1269
|
-
"A new orchestration session should usually begin with one Genesis foundation task that creates or updates the required markdown artifacts, then expand later stages only when the scope justifies it.",
|
|
1270
|
-
"If a follow-up request is small, one-shot it. If it is multi-part or large, create or expand an orchestration session instead of pretending it is a single task.",
|
|
1340
|
+
orchestrationActive && !genesisExists ? "Project foundation is missing or incomplete. Do not skip Genesis unless the user explicitly waives it." : "",
|
|
1341
|
+
"Do not escalate to orchestration or review just because this is coding-related; stay in the selected Takomi mode unless the user asks or a durable board/session is genuinely needed.",
|
|
1342
|
+
orchestrationActive ? "Task fan-out is flexible. Do not force exactly three tasks; decompose Genesis, Design, and Build work to fit the actual scope." : "",
|
|
1343
|
+
orchestrationActive ? "A new orchestration session should usually begin with one Genesis foundation task that creates or updates the required markdown artifacts, then expand later stages only when the scope justifies it." : "",
|
|
1344
|
+
orchestrationActive ? "If a follow-up request is small, one-shot it. If it is multi-part or large, create or expand an orchestration session instead of pretending it is a single task." : "",
|
|
1271
1345
|
"Before any Takomi subagent dispatch or model override, use the injected Pi model-registry context and project routing policy. Prefer provider-qualified model IDs. Do not run `pi --list-models` unless the registry context is missing or the user asks for a visible diagnostic.",
|
|
1272
|
-
"When useful, state the current Takomi stage and the recommended next
|
|
1273
|
-
effectiveState.stage === "build"
|
|
1346
|
+
"When useful, state the current Takomi mode/stage and the recommended next step.",
|
|
1347
|
+
orchestrationActive && effectiveState.stage === "build"
|
|
1274
1348
|
? "For build orchestration, use takomi_subagent to dispatch work to specialist subagents, then record the result on takomi_board; reuse the same conversation id when sending fixes back to the agent."
|
|
1275
1349
|
: "",
|
|
1276
1350
|
].filter(Boolean);
|