takomi 2.1.45 → 2.5.1
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/README.md +5 -5
- package/.pi/agents/architect.md +2 -2
- package/.pi/agents/designer.md +2 -2
- package/.pi/agents/worker.md +32 -0
- package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +15 -103
- package/.pi/extensions/takomi-runtime/command-text.ts +5 -4
- package/.pi/extensions/takomi-runtime/commands.ts +17 -17
- package/.pi/extensions/takomi-runtime/index.ts +278 -86
- package/.pi/extensions/takomi-runtime/model-routing-defaults.ts +262 -326
- package/.pi/extensions/takomi-runtime/profile.ts +9 -8
- package/.pi/extensions/takomi-runtime/routing-policy.ts +84 -65
- package/.pi/extensions/takomi-runtime/shared.ts +7 -30
- package/.pi/extensions/takomi-runtime/tool-renderers.ts +1 -1
- package/.pi/extensions/takomi-subagents/agents.ts +5 -0
- package/.pi/extensions/takomi-subagents/index.ts +4 -0
- package/.pi/extensions/takomi-subagents/pi-subagents-engine.ts +7 -1
- package/.pi/extensions/takomi-subagents/tool-runner.ts +40 -1
- package/.pi/settings.json +39 -36
- package/.pi/takomi/model-routing.md +6 -0
- package/.pi/takomi-profile.json +54 -50
- package/package.json +2 -2
- package/src/pi-takomi-core/orchestration.ts +39 -21
- package/src/pi-takomi-core/routing.ts +8 -8
- package/src/pi-takomi-core/types.ts +25 -5
- package/src/pi-takomi-core/workflows.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "takomi",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"description": "🎯 Stop wrestling with AI. Start building with purpose. The artisan's toolkit for agent workflows, Codex skills, and original Takomi capabilities like 21st.dev integration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"postinstall": "node src/postinstall.js",
|
|
40
40
|
"test": "npm run test:typecheck && npm run test:regressions && npm run test:context-manager && npm run test:skills",
|
|
41
41
|
"test:typecheck": "tsc --noEmit",
|
|
42
|
-
"test:regressions": "node scripts/test-regressions.js && node scripts/test-subagent-renderers.js && node scripts/test-subagent-heartbeat.js && node scripts/test-subagent-production-lifecycle.js && node scripts/test-subagent-acceptance.js && node scripts/test-takomi-runtime-renderers.js && node scripts/test-workflow-catalog.js && node scripts/test-oauth-router-report-ui.js && node --experimental-specifier-resolution=node scripts/test-takomi-board-errors.js && node scripts/test-takomi-gate-provenance.js && node scripts/test-subagent-project-trust.js",
|
|
42
|
+
"test:regressions": "node scripts/test-regressions.js && node scripts/test-subagent-renderers.js && node scripts/test-subagent-heartbeat.js && node scripts/test-subagent-production-lifecycle.js && node scripts/test-subagent-acceptance.js && node scripts/test-takomi-runtime-renderers.js && node scripts/test-workflow-catalog.js && node scripts/test-oauth-router-report-ui.js && node --experimental-specifier-resolution=node scripts/test-takomi-board-errors.js && node scripts/test-takomi-gate-provenance.js && node scripts/test-takomi-routing-safety.js && node scripts/test-subagent-project-trust.js",
|
|
43
43
|
"test:context-manager": "node --experimental-specifier-resolution=node scripts/test-context-manager-renderers.js",
|
|
44
44
|
"test:skills": "node scripts/test-skill-selection.js",
|
|
45
45
|
"takomi-flow:doctor": "node plugins/takomi-flow/scripts/takomi-flow.mjs doctor",
|
|
@@ -5,7 +5,8 @@ import type {
|
|
|
5
5
|
OrchestratorTask,
|
|
6
6
|
OrchestratorTaskStatus,
|
|
7
7
|
SessionIntent,
|
|
8
|
-
|
|
8
|
+
LegacyTakomiRole,
|
|
9
|
+
TakomiPersona,
|
|
9
10
|
TaskChecklistItem,
|
|
10
11
|
VibeLifecycleStage,
|
|
11
12
|
} from "./types";
|
|
@@ -57,18 +58,24 @@ export function workflowToStage(workflow?: OrchestratorTask["workflow"]): VibeLi
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
function
|
|
61
|
+
export function canonicalizeTakomiPersona(role: TakomiPersona | LegacyTakomiRole): TakomiPersona {
|
|
61
62
|
switch (role) {
|
|
62
|
-
case "
|
|
63
|
-
|
|
64
|
-
case "
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
case "design": return "designer";
|
|
64
|
+
case "code": return "coder";
|
|
65
|
+
case "review": return "reviewer";
|
|
66
|
+
case "general": return "worker";
|
|
67
|
+
default: return role;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function defaultStageForRole(role: TakomiPersona): VibeLifecycleStage | undefined {
|
|
72
|
+
switch (role) {
|
|
73
|
+
case "architect": return "genesis";
|
|
74
|
+
case "designer": return "design";
|
|
75
|
+
case "coder":
|
|
76
|
+
case "worker":
|
|
77
|
+
case "reviewer":
|
|
78
|
+
case "orchestrator": return "build";
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
|
|
@@ -123,19 +130,21 @@ export function normalizeChecklist(checklist?: Array<string | TaskChecklistItem>
|
|
|
123
130
|
return checklist.map((item) => typeof item === "string" ? { text: item, done: false } : { text: item.text, done: item.done ?? false });
|
|
124
131
|
}
|
|
125
132
|
|
|
126
|
-
export function createTask(id: string, title: string, role:
|
|
127
|
-
const
|
|
128
|
-
const
|
|
133
|
+
export function createTask(id: string, title: string, role: TakomiPersona | LegacyTakomiRole, extras?: Partial<OrchestratorTask>): OrchestratorTask {
|
|
134
|
+
const persona = canonicalizeTakomiPersona(role);
|
|
135
|
+
const preferredAgent = extras?.preferredAgent ?? persona;
|
|
136
|
+
const stage = extras?.stage ?? workflowToStage(extras?.workflow) ?? defaultStageForRole(persona);
|
|
129
137
|
return {
|
|
130
138
|
id,
|
|
131
139
|
title,
|
|
132
|
-
role,
|
|
140
|
+
role: persona,
|
|
133
141
|
status: "pending",
|
|
134
142
|
...extras,
|
|
135
143
|
stage,
|
|
136
144
|
preferredAgent,
|
|
137
145
|
conversationId: extras?.conversationId ?? createConversationId(preferredAgent, id),
|
|
138
146
|
preferredModel: extras?.preferredModel,
|
|
147
|
+
preferredModelConfirmed: extras?.preferredModelConfirmed,
|
|
139
148
|
preferredModelHint: extras?.preferredModelHint,
|
|
140
149
|
preferredThinking: extras?.preferredThinking,
|
|
141
150
|
fallbackModels: extras?.fallbackModels,
|
|
@@ -392,10 +401,13 @@ export function buildSessionState(
|
|
|
392
401
|
title: string,
|
|
393
402
|
tasks: OrchestratorTask[],
|
|
394
403
|
now = new Date(),
|
|
395
|
-
extras?: Partial<Pick<OrchestratorSessionState, "sessionIntent" | "lifecycle">>,
|
|
404
|
+
extras?: Partial<Pick<OrchestratorSessionState, "sessionIntent" | "lifecycle" | "artifacts">>,
|
|
396
405
|
): OrchestratorSessionState {
|
|
397
406
|
const stamp = now.toISOString();
|
|
398
|
-
const normalizedTasks = tasks.map((task) =>
|
|
407
|
+
const normalizedTasks = tasks.map((task) => {
|
|
408
|
+
const role = canonicalizeTakomiPersona(task.role as TakomiPersona | LegacyTakomiRole);
|
|
409
|
+
return { ...task, role, preferredAgent: task.preferredAgent ?? role, stage: task.stage ?? workflowToStage(task.workflow) ?? defaultStageForRole(role) };
|
|
410
|
+
});
|
|
399
411
|
return {
|
|
400
412
|
sessionId,
|
|
401
413
|
title,
|
|
@@ -404,6 +416,7 @@ export function buildSessionState(
|
|
|
404
416
|
mode: "hybrid",
|
|
405
417
|
lifecycle: deriveLifecycleFromTasks(normalizedTasks, extras?.lifecycle),
|
|
406
418
|
sessionIntent: extras?.sessionIntent ?? "full-project",
|
|
419
|
+
artifacts: extras?.artifacts,
|
|
407
420
|
tasks: normalizedTasks,
|
|
408
421
|
};
|
|
409
422
|
}
|
|
@@ -411,7 +424,10 @@ export function buildSessionState(
|
|
|
411
424
|
export function normalizeSessionState(
|
|
412
425
|
session: Partial<OrchestratorSessionState> & Pick<OrchestratorSessionState, "sessionId" | "title">,
|
|
413
426
|
): OrchestratorSessionState {
|
|
414
|
-
const tasks = (session.tasks ?? []).map((task) =>
|
|
427
|
+
const tasks = (session.tasks ?? []).map((task) => {
|
|
428
|
+
const role = canonicalizeTakomiPersona(task.role as TakomiPersona | LegacyTakomiRole);
|
|
429
|
+
return { ...task, role, preferredAgent: task.preferredAgent ?? role, stage: task.stage ?? workflowToStage(task.workflow) ?? defaultStageForRole(role) };
|
|
430
|
+
});
|
|
415
431
|
const normalized = buildSessionState(
|
|
416
432
|
session.sessionId,
|
|
417
433
|
session.title,
|
|
@@ -420,6 +436,7 @@ export function normalizeSessionState(
|
|
|
420
436
|
{
|
|
421
437
|
sessionIntent: session.sessionIntent ?? "full-project",
|
|
422
438
|
lifecycle: session.lifecycle,
|
|
439
|
+
artifacts: session.artifacts,
|
|
423
440
|
},
|
|
424
441
|
);
|
|
425
442
|
|
|
@@ -428,6 +445,7 @@ export function normalizeSessionState(
|
|
|
428
445
|
createdAt: session.createdAt ?? normalized.createdAt,
|
|
429
446
|
updatedAt: session.updatedAt ?? normalized.updatedAt,
|
|
430
447
|
mode: "hybrid",
|
|
448
|
+
artifacts: session.artifacts ?? normalized.artifacts,
|
|
431
449
|
};
|
|
432
450
|
}
|
|
433
451
|
|
|
@@ -458,10 +476,10 @@ export function createLifecycleStarterSession(
|
|
|
458
476
|
): OrchestratorSessionState {
|
|
459
477
|
const sessionId = options?.sessionId ?? createSessionId(options?.now);
|
|
460
478
|
const tasks = [
|
|
461
|
-
createTask("01", "Genesis foundation", "
|
|
479
|
+
createTask("01", "Genesis foundation", "architect", {
|
|
462
480
|
stage: "genesis",
|
|
463
481
|
workflow: "vibe-genesis",
|
|
464
|
-
preferredAgent: "
|
|
482
|
+
preferredAgent: "architect",
|
|
465
483
|
objective: "Establish the project foundation, produce the required planning docs, and decide what should split next.",
|
|
466
484
|
scope: [
|
|
467
485
|
"Clarify scope and mission",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getWorkflowDefinition } from "./workflows";
|
|
2
|
-
import type { RouteDecision,
|
|
2
|
+
import type { RouteDecision, TakomiPersona, TakomiWorkflowId, VibeLifecycleStage } from "./types";
|
|
3
3
|
|
|
4
4
|
function stageToWorkflow(stage: VibeLifecycleStage): TakomiWorkflowId {
|
|
5
5
|
switch (stage) {
|
|
@@ -15,19 +15,19 @@ function stageToWorkflow(stage: VibeLifecycleStage): TakomiWorkflowId {
|
|
|
15
15
|
|
|
16
16
|
export function detectLifecycleStage(text: string): VibeLifecycleStage | undefined {
|
|
17
17
|
const lowered = text.toLowerCase();
|
|
18
|
-
if (/(\bgenesis\b|\brequirements\b|\bprd\b|\bscope\b|\bplan first\b|\bblueprint\b)/.test(lowered)) return "genesis";
|
|
19
|
-
if (/(\
|
|
18
|
+
if (/(\bgenesis\b|\brequirements\b|\bprd\b|\bscope\b|\bplan first\b|\bblueprint\b|\barchitecture\b|\bdesign the system\b|\btechnical plan\b)/.test(lowered)) return "genesis";
|
|
19
|
+
if (/(\bui\b|\bux\b|\bui design\b|\bux design\b|\buser interface\b|\bmockup\b|\bwireframe\b|\bvisual system\b)/.test(lowered)) return "design";
|
|
20
20
|
if (/(\bbuild\b|\bimplement\b|\bcode\b|\bship\b|\bwire up\b|\bfeature\b)/.test(lowered)) return "build";
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function detectRole(text: string):
|
|
24
|
+
export function detectRole(text: string): TakomiPersona | undefined {
|
|
25
25
|
const lowered = text.toLowerCase();
|
|
26
26
|
if (/(\borchestrate\b|\bcoordinate\b|\bbreak this down\b|\bmulti-step\b|\bmulti step\b|\borchestration session\b)/.test(lowered)) return "orchestrator";
|
|
27
27
|
if (/(\barchitect\b|\bdesign the system\b|\bplan\b|\bspec\b)/.test(lowered)) return "architect";
|
|
28
|
-
if (/(\
|
|
29
|
-
if (/(\bcode\b|\bimplement\b|\bbuild\b|\bfix\b)/.test(lowered)) return "
|
|
30
|
-
if (/(\breview\b|\baudit\b|\bcheck\b|\bqa\b)/.test(lowered)) return "
|
|
28
|
+
if (/(\bui\b|\bux\b|\bdesigner\b|\bmockup\b|\bwireframe\b|\bvisual system\b|\buser interface\b)/.test(lowered)) return "designer";
|
|
29
|
+
if (/(\bcode\b|\bimplement\b|\bbuild\b|\bfix\b)/.test(lowered)) return "coder";
|
|
30
|
+
if (/(\breview\b|\baudit\b|\bcheck\b|\bqa\b)/.test(lowered)) return "reviewer";
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -83,7 +83,7 @@ export function decideRoute(text: string): RouteDecision {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
return {
|
|
86
|
-
role: "
|
|
86
|
+
role: "worker",
|
|
87
87
|
executionMode: "direct",
|
|
88
88
|
sessionRecommendation: followUp ? "consider" : "none",
|
|
89
89
|
reason: followUp
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type TakomiPersona = "orchestrator" | "architect" | "designer" | "coder" | "worker" | "reviewer";
|
|
2
|
+
|
|
3
|
+
/** @deprecated Runtime and persisted tasks should use TakomiPersona names. */
|
|
4
|
+
export type LegacyTakomiRole = "general" | "design" | "code" | "review";
|
|
5
|
+
|
|
6
|
+
export type TakomiRole = TakomiPersona | "general";
|
|
7
|
+
|
|
8
|
+
export type TakomiMainMode = "idle" | "code" | "review" | "orchestrate";
|
|
2
9
|
|
|
3
10
|
export type TakomiWorkflowId = "vibe-genesis" | "vibe-design" | "vibe-build";
|
|
4
11
|
|
|
@@ -38,7 +45,7 @@ export type TakomiProfile = {
|
|
|
38
45
|
foreground?: boolean;
|
|
39
46
|
background?: boolean;
|
|
40
47
|
reviewAfterImplementation?: boolean;
|
|
41
|
-
roles?: Partial<Record<
|
|
48
|
+
roles?: Partial<Record<TakomiPersona, TakomiDispatchDefaults>>;
|
|
42
49
|
stages?: Partial<Record<VibeLifecycleStage, TakomiDispatchDefaults>>;
|
|
43
50
|
review?: TakomiReviewProfile;
|
|
44
51
|
};
|
|
@@ -111,7 +118,7 @@ export type WorkflowDefinition = {
|
|
|
111
118
|
stage: VibeLifecycleStage;
|
|
112
119
|
title: string;
|
|
113
120
|
purpose: string;
|
|
114
|
-
preferredRole:
|
|
121
|
+
preferredRole: TakomiPersona;
|
|
115
122
|
preferredAgent?: string;
|
|
116
123
|
preferredModelHint?: string;
|
|
117
124
|
nextStage?: VibeLifecycleStage;
|
|
@@ -119,7 +126,7 @@ export type WorkflowDefinition = {
|
|
|
119
126
|
};
|
|
120
127
|
|
|
121
128
|
export type RouteDecision = {
|
|
122
|
-
role:
|
|
129
|
+
role: TakomiPersona;
|
|
123
130
|
workflow?: TakomiWorkflowId;
|
|
124
131
|
stage?: VibeLifecycleStage;
|
|
125
132
|
executionMode: "direct" | "orchestrate";
|
|
@@ -137,13 +144,14 @@ export type TaskChecklistItem = {
|
|
|
137
144
|
export type OrchestratorTask = {
|
|
138
145
|
id: string;
|
|
139
146
|
title: string;
|
|
140
|
-
role:
|
|
147
|
+
role: TakomiPersona;
|
|
141
148
|
stage?: VibeLifecycleStage;
|
|
142
149
|
workflow?: TakomiWorkflowId;
|
|
143
150
|
parentTaskId?: string;
|
|
144
151
|
preferredAgent?: string;
|
|
145
152
|
preferredModelHint?: string;
|
|
146
153
|
preferredModel?: string;
|
|
154
|
+
preferredModelConfirmed?: boolean;
|
|
147
155
|
preferredThinking?: TakomiThinkingLevel;
|
|
148
156
|
fallbackModels?: string[];
|
|
149
157
|
dispatchPolicy?: TakomiDispatchPolicy;
|
|
@@ -153,6 +161,7 @@ export type OrchestratorTask = {
|
|
|
153
161
|
scope?: string[];
|
|
154
162
|
definitionOfDone?: string[];
|
|
155
163
|
expectedArtifacts?: string[];
|
|
164
|
+
requiredCapabilities?: string[];
|
|
156
165
|
dependencies?: string[];
|
|
157
166
|
reviewCheckpoint?: string;
|
|
158
167
|
instructions?: string[];
|
|
@@ -171,6 +180,14 @@ export type LifecycleStageState = {
|
|
|
171
180
|
|
|
172
181
|
export type SessionIntent = "full-project" | "feature-scope" | "follow-up-task";
|
|
173
182
|
|
|
183
|
+
export type MasterPlanOwner = "human" | "board" | "caller";
|
|
184
|
+
|
|
185
|
+
export type MasterPlanArtifactProvenance = {
|
|
186
|
+
owner: MasterPlanOwner;
|
|
187
|
+
sha256: string;
|
|
188
|
+
lastSeenAt: string;
|
|
189
|
+
};
|
|
190
|
+
|
|
174
191
|
export type OrchestratorSessionState = {
|
|
175
192
|
sessionId: string;
|
|
176
193
|
title: string;
|
|
@@ -179,5 +196,8 @@ export type OrchestratorSessionState = {
|
|
|
179
196
|
mode: "hybrid";
|
|
180
197
|
lifecycle: Record<VibeLifecycleStage, LifecycleStageState>;
|
|
181
198
|
sessionIntent?: SessionIntent;
|
|
199
|
+
artifacts?: {
|
|
200
|
+
masterPlan?: MasterPlanArtifactProvenance;
|
|
201
|
+
};
|
|
182
202
|
tasks: OrchestratorTask[];
|
|
183
203
|
};
|
|
@@ -40,15 +40,15 @@ const WORKFLOW_IMPLEMENTATIONS: Record<TakomiWorkflowId, Omit<WorkflowDefinition
|
|
|
40
40
|
playbook: VIBE_GENESIS_PLAYBOOK,
|
|
41
41
|
},
|
|
42
42
|
"vibe-design": {
|
|
43
|
-
preferredRole: "
|
|
43
|
+
preferredRole: "designer",
|
|
44
44
|
preferredAgent: "designer",
|
|
45
45
|
preferredModelHint: "Prefer Gemini 3.1 Pro Preview or another strong design-capable model actually available in Pi.",
|
|
46
46
|
nextStage: "build",
|
|
47
47
|
playbook: VIBE_DESIGN_PLAYBOOK,
|
|
48
48
|
},
|
|
49
49
|
"vibe-build": {
|
|
50
|
-
preferredRole: "
|
|
51
|
-
preferredAgent: "
|
|
50
|
+
preferredRole: "coder",
|
|
51
|
+
preferredAgent: "coder",
|
|
52
52
|
playbook: VIBE_BUILD_PLAYBOOK,
|
|
53
53
|
},
|
|
54
54
|
};
|