takomi 2.1.44 → 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 +9 -8
- package/.pi/agents/architect.md +2 -2
- package/.pi/agents/designer.md +2 -2
- package/.pi/agents/worker.md +32 -0
- package/.pi/extensions/oauth-router/commands.ts +66 -35
- package/.pi/extensions/oauth-router/index.ts +51 -7
- package/.pi/extensions/oauth-router/report-ui.ts +205 -0
- package/.pi/extensions/takomi-context-manager/diagnostics-tools.ts +41 -3
- package/.pi/extensions/takomi-context-manager/diagnostics.ts +26 -0
- package/.pi/extensions/takomi-context-manager/index.ts +3 -2
- package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +50 -117
- package/.pi/extensions/takomi-context-manager/policy-tools.ts +93 -42
- package/.pi/extensions/takomi-context-manager/skill-categories.d.ts +11 -0
- package/.pi/extensions/takomi-context-manager/skill-categories.js +212 -0
- package/.pi/extensions/takomi-context-manager/skill-registry.ts +179 -8
- package/.pi/extensions/takomi-context-manager/skill-tools.ts +208 -103
- package/.pi/extensions/takomi-context-manager/tool-renderers.ts +112 -0
- package/.pi/extensions/takomi-context-manager/types.ts +6 -0
- package/.pi/extensions/takomi-runtime/command-text.ts +5 -4
- package/.pi/extensions/takomi-runtime/commands.ts +58 -25
- package/.pi/extensions/takomi-runtime/gate-provenance.ts +24 -0
- package/.pi/extensions/takomi-runtime/index.ts +385 -124
- 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 +97 -66
- package/.pi/extensions/takomi-runtime/shared.ts +7 -30
- package/.pi/extensions/takomi-runtime/takomi-stats.js +46 -26
- package/.pi/extensions/takomi-runtime/tool-renderers.ts +234 -0
- package/.pi/extensions/takomi-runtime/workflow-catalog.ts +54 -0
- package/.pi/extensions/takomi-subagents/agents.ts +9 -0
- package/.pi/extensions/takomi-subagents/async-lifecycle.ts +401 -0
- package/.pi/extensions/takomi-subagents/detached-results.ts +940 -0
- package/.pi/extensions/takomi-subagents/index.ts +50 -1
- package/.pi/extensions/takomi-subagents/native-render.ts +250 -188
- package/.pi/extensions/takomi-subagents/pi-subagents-engine.ts +62 -47
- package/.pi/extensions/takomi-subagents/pi-subagents-internal.ts +11 -5
- package/.pi/extensions/takomi-subagents/result-heartbeat.ts +55 -0
- package/.pi/extensions/takomi-subagents/subagent-ux.ts +162 -0
- package/.pi/extensions/takomi-subagents/tool-runner.ts +198 -29
- package/.pi/settings.json +39 -36
- package/.pi/takomi/model-routing.md +288 -3
- package/.pi/takomi-profile.json +54 -50
- package/assets/.agent/skills/shared-resend-portfolio/SKILL.md +124 -0
- package/package.json +4 -3
- 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 +35 -5
- package/src/pi-takomi-core/workflows.ts +86 -45
- package/src/skills-catalog.js +2 -202
- package/src/skills-installer.js +4 -1
|
@@ -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
|
};
|
|
@@ -96,12 +103,22 @@ export type TakomiSubagentRunGroup = {
|
|
|
96
103
|
sessionId?: string;
|
|
97
104
|
};
|
|
98
105
|
|
|
106
|
+
export type WorkflowAvailability = "embedded";
|
|
107
|
+
|
|
108
|
+
export type WorkflowCatalogEntry = {
|
|
109
|
+
id: TakomiWorkflowId;
|
|
110
|
+
stage: VibeLifecycleStage;
|
|
111
|
+
name: string;
|
|
112
|
+
description: string;
|
|
113
|
+
availability: WorkflowAvailability;
|
|
114
|
+
};
|
|
115
|
+
|
|
99
116
|
export type WorkflowDefinition = {
|
|
100
117
|
id: TakomiWorkflowId;
|
|
101
118
|
stage: VibeLifecycleStage;
|
|
102
119
|
title: string;
|
|
103
120
|
purpose: string;
|
|
104
|
-
preferredRole:
|
|
121
|
+
preferredRole: TakomiPersona;
|
|
105
122
|
preferredAgent?: string;
|
|
106
123
|
preferredModelHint?: string;
|
|
107
124
|
nextStage?: VibeLifecycleStage;
|
|
@@ -109,7 +126,7 @@ export type WorkflowDefinition = {
|
|
|
109
126
|
};
|
|
110
127
|
|
|
111
128
|
export type RouteDecision = {
|
|
112
|
-
role:
|
|
129
|
+
role: TakomiPersona;
|
|
113
130
|
workflow?: TakomiWorkflowId;
|
|
114
131
|
stage?: VibeLifecycleStage;
|
|
115
132
|
executionMode: "direct" | "orchestrate";
|
|
@@ -127,13 +144,14 @@ export type TaskChecklistItem = {
|
|
|
127
144
|
export type OrchestratorTask = {
|
|
128
145
|
id: string;
|
|
129
146
|
title: string;
|
|
130
|
-
role:
|
|
147
|
+
role: TakomiPersona;
|
|
131
148
|
stage?: VibeLifecycleStage;
|
|
132
149
|
workflow?: TakomiWorkflowId;
|
|
133
150
|
parentTaskId?: string;
|
|
134
151
|
preferredAgent?: string;
|
|
135
152
|
preferredModelHint?: string;
|
|
136
153
|
preferredModel?: string;
|
|
154
|
+
preferredModelConfirmed?: boolean;
|
|
137
155
|
preferredThinking?: TakomiThinkingLevel;
|
|
138
156
|
fallbackModels?: string[];
|
|
139
157
|
dispatchPolicy?: TakomiDispatchPolicy;
|
|
@@ -143,6 +161,7 @@ export type OrchestratorTask = {
|
|
|
143
161
|
scope?: string[];
|
|
144
162
|
definitionOfDone?: string[];
|
|
145
163
|
expectedArtifacts?: string[];
|
|
164
|
+
requiredCapabilities?: string[];
|
|
146
165
|
dependencies?: string[];
|
|
147
166
|
reviewCheckpoint?: string;
|
|
148
167
|
instructions?: string[];
|
|
@@ -161,6 +180,14 @@ export type LifecycleStageState = {
|
|
|
161
180
|
|
|
162
181
|
export type SessionIntent = "full-project" | "feature-scope" | "follow-up-task";
|
|
163
182
|
|
|
183
|
+
export type MasterPlanOwner = "human" | "board" | "caller";
|
|
184
|
+
|
|
185
|
+
export type MasterPlanArtifactProvenance = {
|
|
186
|
+
owner: MasterPlanOwner;
|
|
187
|
+
sha256: string;
|
|
188
|
+
lastSeenAt: string;
|
|
189
|
+
};
|
|
190
|
+
|
|
164
191
|
export type OrchestratorSessionState = {
|
|
165
192
|
sessionId: string;
|
|
166
193
|
title: string;
|
|
@@ -169,5 +196,8 @@ export type OrchestratorSessionState = {
|
|
|
169
196
|
mode: "hybrid";
|
|
170
197
|
lifecycle: Record<VibeLifecycleStage, LifecycleStageState>;
|
|
171
198
|
sessionIntent?: SessionIntent;
|
|
199
|
+
artifacts?: {
|
|
200
|
+
masterPlan?: MasterPlanArtifactProvenance;
|
|
201
|
+
};
|
|
172
202
|
tasks: OrchestratorTask[];
|
|
173
203
|
};
|
|
@@ -1,45 +1,86 @@
|
|
|
1
|
-
import type { TakomiWorkflowId, WorkflowDefinition } from "./types";
|
|
2
|
-
|
|
3
|
-
const VIBE_GENESIS_PLAYBOOK = `Genesis fallback summary: author the project foundation in markdown, with PRD, FR issues, coding guidelines, architecture decisions, data models, API contracts, implementation strategy, and a clean handoff. For broad projects, Genesis may also create the orchestration session that carries the work into UI/UX Design and Build. The runtime should prefer .pi/prompts/genesis-prompt.md; this string exists only as a compatibility fallback.`;
|
|
4
|
-
const VIBE_DESIGN_PLAYBOOK = `Design fallback summary: define UI/UX only: visual system, user journeys, interaction flows, mockups, accessibility expectations, and frontend builder constraints in markdown. Technical architecture, data models, and API contracts belong in Genesis or Architect planning. The runtime should prefer .pi/prompts/design-prompt.md; this string exists only as a compatibility fallback.`;
|
|
5
|
-
const VIBE_BUILD_PLAYBOOK = `Build fallback summary: implement the approved plan with FR-driven work, strict verification, mockup adherence, and explicit handoff reporting. The runtime should prefer .pi/prompts/build-prompt.md; this string exists only as a compatibility fallback.`;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
1
|
+
import type { TakomiWorkflowId, WorkflowCatalogEntry, WorkflowDefinition } from "./types";
|
|
2
|
+
|
|
3
|
+
const VIBE_GENESIS_PLAYBOOK = `Genesis fallback summary: author the project foundation in markdown, with PRD, FR issues, coding guidelines, architecture decisions, data models, API contracts, implementation strategy, and a clean handoff. For broad projects, Genesis may also create the orchestration session that carries the work into UI/UX Design and Build. The runtime should prefer .pi/prompts/genesis-prompt.md; this string exists only as a compatibility fallback.`;
|
|
4
|
+
const VIBE_DESIGN_PLAYBOOK = `Design fallback summary: define UI/UX only: visual system, user journeys, interaction flows, mockups, accessibility expectations, and frontend builder constraints in markdown. Technical architecture, data models, and API contracts belong in Genesis or Architect planning. The runtime should prefer .pi/prompts/design-prompt.md; this string exists only as a compatibility fallback.`;
|
|
5
|
+
const VIBE_BUILD_PLAYBOOK = `Build fallback summary: implement the approved plan with FR-driven work, strict verification, mockup adherence, and explicit handoff reporting. The runtime should prefer .pi/prompts/build-prompt.md; this string exists only as a compatibility fallback.`;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Canonical model-facing lifecycle metadata. Runtime tools may frame this
|
|
9
|
+
* catalog differently, but must not maintain their own workflow wording.
|
|
10
|
+
*/
|
|
11
|
+
export const WORKFLOW_CATALOG: readonly WorkflowCatalogEntry[] = [
|
|
12
|
+
{
|
|
13
|
+
id: "vibe-genesis",
|
|
14
|
+
stage: "genesis",
|
|
15
|
+
name: "Vibe Genesis",
|
|
16
|
+
description: "Initialize a project with markdown blueprints, technical planning, and a clean handoff into UI/UX Design or Build. See .pi/prompts/genesis-prompt.md for the canonical behavior.",
|
|
17
|
+
availability: "embedded",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "vibe-design",
|
|
21
|
+
stage: "design",
|
|
22
|
+
name: "Vibe Design",
|
|
23
|
+
description: "Define UI/UX only: visual system, user journeys, interaction flows, mockups, accessibility expectations, and frontend builder constraints before implementation begins. See .pi/prompts/design-prompt.md for the canonical behavior.",
|
|
24
|
+
availability: "embedded",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "vibe-build",
|
|
28
|
+
stage: "build",
|
|
29
|
+
name: "Vibe Build",
|
|
30
|
+
description: "Execute the approved plan with FR-based implementation, strict verification, mockup adherence, and explicit handoff reporting. See .pi/prompts/build-prompt.md for the canonical behavior.",
|
|
31
|
+
availability: "embedded",
|
|
32
|
+
},
|
|
33
|
+
] as const;
|
|
34
|
+
|
|
35
|
+
const WORKFLOW_IMPLEMENTATIONS: Record<TakomiWorkflowId, Omit<WorkflowDefinition, "id" | "stage" | "title" | "purpose">> = {
|
|
36
|
+
"vibe-genesis": {
|
|
37
|
+
preferredRole: "architect",
|
|
38
|
+
preferredAgent: "architect",
|
|
39
|
+
nextStage: "design",
|
|
40
|
+
playbook: VIBE_GENESIS_PLAYBOOK,
|
|
41
|
+
},
|
|
42
|
+
"vibe-design": {
|
|
43
|
+
preferredRole: "designer",
|
|
44
|
+
preferredAgent: "designer",
|
|
45
|
+
preferredModelHint: "Prefer Gemini 3.1 Pro Preview or another strong design-capable model actually available in Pi.",
|
|
46
|
+
nextStage: "build",
|
|
47
|
+
playbook: VIBE_DESIGN_PLAYBOOK,
|
|
48
|
+
},
|
|
49
|
+
"vibe-build": {
|
|
50
|
+
preferredRole: "coder",
|
|
51
|
+
preferredAgent: "coder",
|
|
52
|
+
playbook: VIBE_BUILD_PLAYBOOK,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const WORKFLOWS: Record<TakomiWorkflowId, WorkflowDefinition> = Object.fromEntries(
|
|
57
|
+
WORKFLOW_CATALOG.map((workflow) => [
|
|
58
|
+
workflow.id,
|
|
59
|
+
{
|
|
60
|
+
...WORKFLOW_IMPLEMENTATIONS[workflow.id],
|
|
61
|
+
id: workflow.id,
|
|
62
|
+
stage: workflow.stage,
|
|
63
|
+
title: workflow.name,
|
|
64
|
+
purpose: workflow.description,
|
|
65
|
+
},
|
|
66
|
+
]),
|
|
67
|
+
) as Record<TakomiWorkflowId, WorkflowDefinition>;
|
|
68
|
+
|
|
69
|
+
export function listWorkflowCatalog(): readonly WorkflowCatalogEntry[] {
|
|
70
|
+
return WORKFLOW_CATALOG;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function listWorkflowDefinitions(): WorkflowDefinition[] {
|
|
74
|
+
return Object.values(WORKFLOWS);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getWorkflowCatalogEntry(id: TakomiWorkflowId): WorkflowCatalogEntry {
|
|
78
|
+
const workflow = WORKFLOW_CATALOG.find((entry) => entry.id === id);
|
|
79
|
+
if (!workflow) throw new Error(`Unknown Takomi workflow: ${id}`);
|
|
80
|
+
return workflow;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Loads the direct-playbook payload for takomi_workflow without board framing. */
|
|
84
|
+
export function getWorkflowDefinition(id: TakomiWorkflowId): WorkflowDefinition {
|
|
85
|
+
return WORKFLOWS[id];
|
|
86
|
+
}
|
package/src/skills-catalog.js
CHANGED
|
@@ -2,209 +2,9 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import { PATHS } from './utils.js';
|
|
5
|
+
import { CORE_SKILLS, SKILL_CATEGORIES } from '../.pi/extensions/takomi-context-manager/skill-categories.js';
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
'takomi',
|
|
8
|
-
'sync-docs',
|
|
9
|
-
'code-review',
|
|
10
|
-
'security-audit',
|
|
11
|
-
'optimize-agent-context',
|
|
12
|
-
'agent-recovery',
|
|
13
|
-
'avoid-feature-creep',
|
|
14
|
-
'ai-sdk',
|
|
15
|
-
'git-commit-generation',
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
export const SKILL_CATEGORIES = [
|
|
19
|
-
{
|
|
20
|
-
id: 'core',
|
|
21
|
-
title: 'Core / Recommended',
|
|
22
|
-
color: 'cyan',
|
|
23
|
-
description: 'Essential skills for efficient Takomi usage.',
|
|
24
|
-
skills: CORE_SKILLS,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: 'developer',
|
|
28
|
-
title: 'Developer / Frameworks',
|
|
29
|
-
color: 'blue',
|
|
30
|
-
description: 'Framework, repo, and developer workflow helpers.',
|
|
31
|
-
skills: [
|
|
32
|
-
'ai-sdk',
|
|
33
|
-
'nextjs-standards',
|
|
34
|
-
'context7',
|
|
35
|
-
'monorepo-management',
|
|
36
|
-
'upgrading-expo',
|
|
37
|
-
'github-ops',
|
|
38
|
-
'git-worktree',
|
|
39
|
-
'git-commit-generation',
|
|
40
|
-
'pr-comment-fix',
|
|
41
|
-
'jules',
|
|
42
|
-
'gemini',
|
|
43
|
-
'anti-gravity',
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: 'security',
|
|
48
|
-
title: 'Security / Review',
|
|
49
|
-
color: 'red',
|
|
50
|
-
description: 'Security, audit, and review workflows.',
|
|
51
|
-
skills: [
|
|
52
|
-
'security-audit',
|
|
53
|
-
'audit-website',
|
|
54
|
-
'code-review',
|
|
55
|
-
'jstar-reviewer',
|
|
56
|
-
'convex-security-audit',
|
|
57
|
-
'convex-security-check',
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
id: 'convex',
|
|
62
|
-
title: 'Convex',
|
|
63
|
-
color: 'green',
|
|
64
|
-
description: 'Convex framework skills and best practices.',
|
|
65
|
-
skills: [
|
|
66
|
-
'convex',
|
|
67
|
-
'convex-agents',
|
|
68
|
-
'convex-best-practices',
|
|
69
|
-
'convex-component-authoring',
|
|
70
|
-
'convex-cron-jobs',
|
|
71
|
-
'convex-file-storage',
|
|
72
|
-
'convex-functions',
|
|
73
|
-
'convex-http-actions',
|
|
74
|
-
'convex-migrations',
|
|
75
|
-
'convex-realtime',
|
|
76
|
-
'convex-schema-validator',
|
|
77
|
-
'convex-security-audit',
|
|
78
|
-
'convex-security-check',
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
id: 'frontend',
|
|
83
|
-
title: 'Frontend / UI',
|
|
84
|
-
color: 'magenta',
|
|
85
|
-
description: 'Frontend implementation, UI/UX, components, and testing.',
|
|
86
|
-
skills: [
|
|
87
|
-
'frontend-design',
|
|
88
|
-
'web-design-guidelines',
|
|
89
|
-
'building-native-ui',
|
|
90
|
-
'ui-ux-pro-max',
|
|
91
|
-
'component-analysis',
|
|
92
|
-
'21st-dev-components',
|
|
93
|
-
'stitch',
|
|
94
|
-
'webapp-testing',
|
|
95
|
-
'figma',
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
id: 'docs-office',
|
|
100
|
-
title: 'Docs / Office / Extraction',
|
|
101
|
-
color: 'yellow',
|
|
102
|
-
description: 'Document formats, extraction, and README support.',
|
|
103
|
-
skills: [
|
|
104
|
-
'pdf',
|
|
105
|
-
'docx',
|
|
106
|
-
'pptx',
|
|
107
|
-
'xlsx',
|
|
108
|
-
'high-fidelity-extraction',
|
|
109
|
-
'crafting-effective-readmes',
|
|
110
|
-
'exam-creator-skill',
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: 'marketing',
|
|
115
|
-
title: 'Marketing / SEO / Copy',
|
|
116
|
-
color: 'green',
|
|
117
|
-
description: 'Marketing, SEO, naming, pricing, and social strategy.',
|
|
118
|
-
skills: [
|
|
119
|
-
'copywriting',
|
|
120
|
-
'marketing-ideas',
|
|
121
|
-
'pricing-strategy',
|
|
122
|
-
'programmatic-seo',
|
|
123
|
-
'seo-ready',
|
|
124
|
-
'social-content',
|
|
125
|
-
'twitter-automation',
|
|
126
|
-
'google-trends',
|
|
127
|
-
'domain-name-brainstormer',
|
|
128
|
-
'global-brand-namer',
|
|
129
|
-
'youtube-pipeline',
|
|
130
|
-
],
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
id: 'ai-media',
|
|
134
|
-
title: 'AI Media / Content Creation',
|
|
135
|
-
color: 'magenta',
|
|
136
|
-
description: 'Optional AI media/content skills. Not installed by default.',
|
|
137
|
-
skills: [
|
|
138
|
-
'ai-avatar-video',
|
|
139
|
-
'ai-marketing-videos',
|
|
140
|
-
'ai-podcast-creation',
|
|
141
|
-
'ai-product-photography',
|
|
142
|
-
'ai-social-media-content',
|
|
143
|
-
'ai-voice-cloning',
|
|
144
|
-
'takomi-flow',
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
id: 'creative-video',
|
|
149
|
-
title: 'Creative / Video / Art',
|
|
150
|
-
color: 'blue',
|
|
151
|
-
description: 'Creative visuals, video, animation, and art workflows.',
|
|
152
|
-
skills: [
|
|
153
|
-
'algorithmic-art',
|
|
154
|
-
'blender-mcp-scene-director',
|
|
155
|
-
'takomi-flow',
|
|
156
|
-
'remotion',
|
|
157
|
-
'remotion-real-ui-video',
|
|
158
|
-
'youtube-pipeline',
|
|
159
|
-
'ai-avatar-video',
|
|
160
|
-
'ai-marketing-videos',
|
|
161
|
-
'photo-book-builder',
|
|
162
|
-
'hyperframes',
|
|
163
|
-
'general-video',
|
|
164
|
-
'motion-graphics',
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
id: 'hyperframes',
|
|
169
|
-
title: 'HyperFrames',
|
|
170
|
-
color: 'magenta',
|
|
171
|
-
description: 'HTML-native video creation and animation framework.',
|
|
172
|
-
skills: [
|
|
173
|
-
'hyperframes',
|
|
174
|
-
'hyperframes-core',
|
|
175
|
-
'hyperframes-keyframes',
|
|
176
|
-
'hyperframes-animation',
|
|
177
|
-
'hyperframes-creative',
|
|
178
|
-
'hyperframes-media',
|
|
179
|
-
'hyperframes-registry',
|
|
180
|
-
'hyperframes-cli',
|
|
181
|
-
'remotion-to-hyperframes',
|
|
182
|
-
'media-use',
|
|
183
|
-
'embedded-captions',
|
|
184
|
-
'faceless-explainer',
|
|
185
|
-
'general-video',
|
|
186
|
-
'motion-graphics',
|
|
187
|
-
'music-to-video',
|
|
188
|
-
'pr-to-video',
|
|
189
|
-
'product-launch-video',
|
|
190
|
-
'slideshow',
|
|
191
|
-
'talking-head-recut',
|
|
192
|
-
'website-to-video',
|
|
193
|
-
],
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
id: 'skill-building',
|
|
197
|
-
title: 'Skill Building / Prompting / Orchestration',
|
|
198
|
-
color: 'cyan',
|
|
199
|
-
description: 'Skill authoring, prompt engineering, and optional orchestration helpers.',
|
|
200
|
-
skills: [
|
|
201
|
-
'skill-creator',
|
|
202
|
-
'prompt-engineering',
|
|
203
|
-
'subagent-driven-development',
|
|
204
|
-
'spawn-task',
|
|
205
|
-
],
|
|
206
|
-
},
|
|
207
|
-
];
|
|
7
|
+
export { CORE_SKILLS, SKILL_CATEGORIES, getSkillCategory } from '../.pi/extensions/takomi-context-manager/skill-categories.js';
|
|
208
8
|
|
|
209
9
|
const colorFns = {
|
|
210
10
|
cyan: pc.cyan,
|
package/src/skills-installer.js
CHANGED
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import crypto from 'crypto';
|
|
5
5
|
import pc from 'picocolors';
|
|
6
6
|
import { PATHS } from './utils.js';
|
|
7
|
-
import { getValidCoreSkills, listBundledSkillNames } from './skills-catalog.js';
|
|
7
|
+
import { getSkillCategory, getValidCoreSkills, listBundledSkillNames } from './skills-catalog.js';
|
|
8
8
|
|
|
9
9
|
const HOME = os.homedir();
|
|
10
10
|
const TAKOMI_HOME = process.env.TAKOMI_HOME_DIR || path.join(HOME, '.takomi');
|
|
@@ -45,6 +45,7 @@ function normalizeOwnedEntry(name, entry) {
|
|
|
45
45
|
targetPath: path.join(SKILLS_ROOT, name),
|
|
46
46
|
installedAt: undefined,
|
|
47
47
|
takomiVersion: undefined,
|
|
48
|
+
category: getSkillCategory(name),
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
return {
|
|
@@ -53,6 +54,7 @@ function normalizeOwnedEntry(name, entry) {
|
|
|
53
54
|
targetPath: entry.targetPath || path.join(SKILLS_ROOT, name),
|
|
54
55
|
installedAt: entry.installedAt,
|
|
55
56
|
takomiVersion: entry.takomiVersion,
|
|
57
|
+
category: entry.category || getSkillCategory(name),
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -163,6 +165,7 @@ export async function installBundledSkills(version = 'unknown', options = {}) {
|
|
|
163
165
|
targetPath: dest,
|
|
164
166
|
installedAt: new Date().toISOString(),
|
|
165
167
|
takomiVersion: version,
|
|
168
|
+
category: getSkillCategory(name),
|
|
166
169
|
};
|
|
167
170
|
installed.push(name);
|
|
168
171
|
}
|