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.
Files changed (50) hide show
  1. package/.pi/README.md +9 -8
  2. package/.pi/agents/architect.md +2 -2
  3. package/.pi/agents/designer.md +2 -2
  4. package/.pi/agents/worker.md +32 -0
  5. package/.pi/extensions/oauth-router/commands.ts +66 -35
  6. package/.pi/extensions/oauth-router/index.ts +51 -7
  7. package/.pi/extensions/oauth-router/report-ui.ts +205 -0
  8. package/.pi/extensions/takomi-context-manager/diagnostics-tools.ts +41 -3
  9. package/.pi/extensions/takomi-context-manager/diagnostics.ts +26 -0
  10. package/.pi/extensions/takomi-context-manager/index.ts +3 -2
  11. package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +50 -117
  12. package/.pi/extensions/takomi-context-manager/policy-tools.ts +93 -42
  13. package/.pi/extensions/takomi-context-manager/skill-categories.d.ts +11 -0
  14. package/.pi/extensions/takomi-context-manager/skill-categories.js +212 -0
  15. package/.pi/extensions/takomi-context-manager/skill-registry.ts +179 -8
  16. package/.pi/extensions/takomi-context-manager/skill-tools.ts +208 -103
  17. package/.pi/extensions/takomi-context-manager/tool-renderers.ts +112 -0
  18. package/.pi/extensions/takomi-context-manager/types.ts +6 -0
  19. package/.pi/extensions/takomi-runtime/command-text.ts +5 -4
  20. package/.pi/extensions/takomi-runtime/commands.ts +58 -25
  21. package/.pi/extensions/takomi-runtime/gate-provenance.ts +24 -0
  22. package/.pi/extensions/takomi-runtime/index.ts +385 -124
  23. package/.pi/extensions/takomi-runtime/model-routing-defaults.ts +262 -326
  24. package/.pi/extensions/takomi-runtime/profile.ts +9 -8
  25. package/.pi/extensions/takomi-runtime/routing-policy.ts +97 -66
  26. package/.pi/extensions/takomi-runtime/shared.ts +7 -30
  27. package/.pi/extensions/takomi-runtime/takomi-stats.js +46 -26
  28. package/.pi/extensions/takomi-runtime/tool-renderers.ts +234 -0
  29. package/.pi/extensions/takomi-runtime/workflow-catalog.ts +54 -0
  30. package/.pi/extensions/takomi-subagents/agents.ts +9 -0
  31. package/.pi/extensions/takomi-subagents/async-lifecycle.ts +401 -0
  32. package/.pi/extensions/takomi-subagents/detached-results.ts +940 -0
  33. package/.pi/extensions/takomi-subagents/index.ts +50 -1
  34. package/.pi/extensions/takomi-subagents/native-render.ts +250 -188
  35. package/.pi/extensions/takomi-subagents/pi-subagents-engine.ts +62 -47
  36. package/.pi/extensions/takomi-subagents/pi-subagents-internal.ts +11 -5
  37. package/.pi/extensions/takomi-subagents/result-heartbeat.ts +55 -0
  38. package/.pi/extensions/takomi-subagents/subagent-ux.ts +162 -0
  39. package/.pi/extensions/takomi-subagents/tool-runner.ts +198 -29
  40. package/.pi/settings.json +39 -36
  41. package/.pi/takomi/model-routing.md +288 -3
  42. package/.pi/takomi-profile.json +54 -50
  43. package/assets/.agent/skills/shared-resend-portfolio/SKILL.md +124 -0
  44. package/package.json +4 -3
  45. package/src/pi-takomi-core/orchestration.ts +39 -21
  46. package/src/pi-takomi-core/routing.ts +8 -8
  47. package/src/pi-takomi-core/types.ts +35 -5
  48. package/src/pi-takomi-core/workflows.ts +86 -45
  49. package/src/skills-catalog.js +2 -202
  50. package/src/skills-installer.js +4 -1
@@ -5,7 +5,8 @@ import type {
5
5
  OrchestratorTask,
6
6
  OrchestratorTaskStatus,
7
7
  SessionIntent,
8
- TakomiRole,
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 defaultStageForRole(role: TakomiRole): VibeLifecycleStage | undefined {
61
+ export function canonicalizeTakomiPersona(role: TakomiPersona | LegacyTakomiRole): TakomiPersona {
61
62
  switch (role) {
62
- case "architect":
63
- return "genesis";
64
- case "design":
65
- return "design";
66
- case "code":
67
- case "review":
68
- case "orchestrator":
69
- return "build";
70
- default:
71
- return undefined;
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: TakomiRole, extras?: Partial<OrchestratorTask>): OrchestratorTask {
127
- const preferredAgent = extras?.preferredAgent ?? (role === "design" ? "designer" : role === "architect" ? "architect" : role === "review" ? "reviewer" : role === "code" ? "coder" : "orchestrator");
128
- const stage = extras?.stage ?? workflowToStage(extras?.workflow) ?? defaultStageForRole(role);
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) => ({ ...task, stage: task.stage ?? workflowToStage(task.workflow) ?? defaultStageForRole(task.role) }));
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) => ({ ...task, stage: task.stage ?? workflowToStage(task.workflow) ?? defaultStageForRole(task.role) }));
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", "orchestrator", {
479
+ createTask("01", "Genesis foundation", "architect", {
462
480
  stage: "genesis",
463
481
  workflow: "vibe-genesis",
464
- preferredAgent: "orchestrator",
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, TakomiRole, TakomiWorkflowId, VibeLifecycleStage } from "./types";
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 (/(\bdesign\b|\bux\b|\bui\b|\bmockup\b|\bwireframe\b|\bvisual\b)/.test(lowered)) return "design";
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): TakomiRole | undefined {
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 (/(\bdesign\b|\bdesigner\b|\bmockup\b|\bvisual\b)/.test(lowered)) return "design";
29
- if (/(\bcode\b|\bimplement\b|\bbuild\b|\bfix\b)/.test(lowered)) return "code";
30
- if (/(\breview\b|\baudit\b|\bcheck\b|\bqa\b)/.test(lowered)) return "review";
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: "general",
86
+ role: "worker",
87
87
  executionMode: "direct",
88
88
  sessionRecommendation: followUp ? "consider" : "none",
89
89
  reason: followUp
@@ -1,4 +1,11 @@
1
- export type TakomiRole = "general" | "orchestrator" | "architect" | "design" | "code" | "review";
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<TakomiRole, TakomiDispatchDefaults>>;
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: TakomiRole;
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: TakomiRole;
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: TakomiRole;
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
- export const WORKFLOWS: Record<TakomiWorkflowId, WorkflowDefinition> = {
7
- "vibe-genesis": {
8
- id: "vibe-genesis",
9
- stage: "genesis",
10
- title: "Vibe Genesis",
11
- purpose: "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.",
12
- preferredRole: "architect",
13
- preferredAgent: "architect",
14
- nextStage: "design",
15
- playbook: VIBE_GENESIS_PLAYBOOK,
16
- },
17
- "vibe-design": {
18
- id: "vibe-design",
19
- stage: "design",
20
- title: "Vibe Design",
21
- purpose: "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.",
22
- preferredRole: "design",
23
- preferredAgent: "designer",
24
- preferredModelHint: "Prefer Gemini 3.1 Pro Preview or another strong design-capable model actually available in Pi.",
25
- nextStage: "build",
26
- playbook: VIBE_DESIGN_PLAYBOOK,
27
- },
28
- "vibe-build": {
29
- id: "vibe-build",
30
- stage: "build",
31
- title: "Vibe Build",
32
- purpose: "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.",
33
- preferredRole: "orchestrator",
34
- preferredAgent: "orchestrator",
35
- playbook: VIBE_BUILD_PLAYBOOK,
36
- },
37
- };
38
-
39
- export function listWorkflowDefinitions(): WorkflowDefinition[] {
40
- return Object.values(WORKFLOWS);
41
- }
42
-
43
- export function getWorkflowDefinition(id: TakomiWorkflowId): WorkflowDefinition {
44
- return WORKFLOWS[id];
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
+ }
@@ -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 const CORE_SKILLS = [
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,
@@ -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
  }