takomi 2.1.26 → 2.1.28
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 +10 -0
- package/.pi/agents/architect.md +0 -1
- package/.pi/agents/coder.md +0 -1
- package/.pi/agents/designer.md +0 -1
- package/.pi/agents/orchestrator.md +0 -1
- package/.pi/agents/reviewer.md +0 -1
- package/.pi/extensions/takomi-context-manager/diagnostics.ts +1 -1
- package/.pi/extensions/takomi-context-manager/extension-conflicts.ts +14 -3
- package/.pi/extensions/takomi-context-manager/index.ts +6 -3
- package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +28 -13
- package/.pi/extensions/takomi-runtime/commands.ts +24 -7
- package/.pi/extensions/takomi-runtime/context-panel.ts +583 -282
- package/.pi/extensions/takomi-runtime/index.ts +101 -6
- package/.pi/extensions/takomi-runtime/model-routing-defaults.ts +296 -0
- package/.pi/extensions/takomi-runtime/routing-policy.ts +67 -17
- package/.pi/extensions/takomi-runtime/takomi-stats.js +44 -16
- package/.pi/extensions/takomi-subagents/pi-subagents-engine.ts +12 -2
- package/.pi/extensions/takomi-subagents/tool-runner.ts +4 -2
- package/.pi/settings.json +18 -20
- package/README.md +34 -4
- package/package.json +4 -2
- package/src/cli.js +326 -33
- package/src/harness.js +132 -16
- package/src/pi-harness.js +27 -6
- package/src/pi-optional-features.js +195 -0
- package/src/postinstall.js +27 -0
- package/src/skills-catalog.js +245 -0
- package/src/skills-installer.js +244 -101
- package/src/skills-selection-tui.js +200 -0
- package/src/store.js +418 -240
- package/src/takomi-stats.js +44 -16
|
@@ -40,6 +40,28 @@ function cost(model, input, cache, output, additiveCache = true) { const p = PRI
|
|
|
40
40
|
function fmtTokens(n) { if (n >= 1e9) return `${(n/1e9).toFixed(2)}B`; if (n >= 1e6) return `${(n/1e6).toFixed(1)}M`; if (n >= 1e3) return `${(n/1e3).toFixed(1)}K`; return String(Math.round(n || 0)); }
|
|
41
41
|
function fmtMoney(n) { return `$${(n || 0).toFixed(n > 100 ? 0 : 2)}`; }
|
|
42
42
|
function ms(n) { if (!n) return '-'; const s = Math.round(n/1000); if (s < 60) return `${s}s`; const m = Math.floor(s/60); if (m < 60) return `${m}m ${s%60}s`; const h = Math.floor(m/60); return `${h}h ${m%60}m`; }
|
|
43
|
+
const ACTIVE_GAP_THRESHOLD_MS = 15 * 60 * 1000;
|
|
44
|
+
function timestampMs(value) {
|
|
45
|
+
if (typeof value === 'number') return Number.isFinite(value) ? value : null;
|
|
46
|
+
if (typeof value === 'string' && value) {
|
|
47
|
+
const parsed = Date.parse(value);
|
|
48
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function addTimestamp(target, value) {
|
|
53
|
+
const parsed = timestampMs(value);
|
|
54
|
+
if (parsed !== null) target.push(parsed);
|
|
55
|
+
}
|
|
56
|
+
function activeDuration(timestamps, maxGapMs = ACTIVE_GAP_THRESHOLD_MS) {
|
|
57
|
+
const sorted = [...new Set((timestamps || []).filter(Number.isFinite))].sort((a, b) => a - b);
|
|
58
|
+
let total = 0;
|
|
59
|
+
for (let i = 1; i < sorted.length; i += 1) {
|
|
60
|
+
const delta = sorted[i] - sorted[i - 1];
|
|
61
|
+
if (delta > 0 && delta <= maxGapMs) total += delta;
|
|
62
|
+
}
|
|
63
|
+
return total;
|
|
64
|
+
}
|
|
43
65
|
function parseSince(value) {
|
|
44
66
|
if (!value) return null;
|
|
45
67
|
const raw = String(value).trim().toLowerCase();
|
|
@@ -88,14 +110,20 @@ async function files(root, suffix = '.jsonl') {
|
|
|
88
110
|
await walk(root); return out;
|
|
89
111
|
}
|
|
90
112
|
|
|
113
|
+
function pushTask(taskRows, task) {
|
|
114
|
+
if (!task?.end || task.end === task.start) return;
|
|
115
|
+
task.activeMs = activeDuration(task.activityTimestamps || []);
|
|
116
|
+
taskRows.push(task);
|
|
117
|
+
}
|
|
118
|
+
|
|
91
119
|
async function scanPiSessions(root, source, events, sessionRows = [], taskRows = []) {
|
|
92
120
|
for (const file of await files(root)) {
|
|
93
121
|
let provider = 'unknown', model = 'unknown', session = path.basename(file, '.jsonl'), cwd = '', currentTask = null;
|
|
94
|
-
const row = { key: session, session, source, file, project: projectKey(file), cwd, start: '', end: '', turns: 0, messages: 0, toolCalls: 0, subagentCalls: 0, roles: new Map(), stages: new Map(), workflows: new Map(), activeMs: 0 };
|
|
122
|
+
const row = { key: session, session, source, file, project: projectKey(file), cwd, start: '', end: '', turns: 0, messages: 0, toolCalls: 0, subagentCalls: 0, roles: new Map(), stages: new Map(), workflows: new Map(), activeMs: 0, activityTimestamps: [] };
|
|
95
123
|
const text = await fs.readFile(file, 'utf8').catch(() => '');
|
|
96
124
|
for (const line of text.split(/\r?\n/)) {
|
|
97
125
|
const obj = safeJson(line); if (!obj) continue;
|
|
98
|
-
if (obj.timestamp) { row.start ||= obj.timestamp; row.end = obj.timestamp; }
|
|
126
|
+
if (obj.timestamp) { row.start ||= obj.timestamp; row.end = obj.timestamp; addTimestamp(row.activityTimestamps, obj.timestamp); }
|
|
99
127
|
if (obj.type === 'session') { session = obj.id || session; cwd = obj.cwd || cwd; row.key = session; row.session = session; row.cwd = cwd; }
|
|
100
128
|
if (obj.type === 'model_change') { provider = obj.provider || provider; model = obj.modelId || model; }
|
|
101
129
|
if (obj.type === 'custom' && obj.customType === 'takomi-runtime-state' && obj.data) {
|
|
@@ -112,12 +140,14 @@ async function scanPiSessions(root, source, events, sessionRows = [], taskRows =
|
|
|
112
140
|
row.messages += 1;
|
|
113
141
|
const ts = obj.timestamp || msg.timestamp || '';
|
|
114
142
|
if (msg.role === 'user') {
|
|
115
|
-
|
|
143
|
+
pushTask(taskRows, currentTask);
|
|
116
144
|
row.turns += 1;
|
|
117
145
|
const textPart = (msg.content || []).find(p => p?.type === 'text')?.text || '';
|
|
118
|
-
currentTask = { source, file, session, project: projectKey(file), cwd, start: ts, end: ts, provider, model, turns: 1, toolCalls: 0, title: String(textPart).replace(/\s+/g, ' ').trim() };
|
|
146
|
+
currentTask = { source, file, session, project: projectKey(file), cwd, start: ts, end: ts, provider, model, turns: 1, toolCalls: 0, title: String(textPart).replace(/\s+/g, ' ').trim(), activityTimestamps: [] };
|
|
147
|
+
addTimestamp(currentTask.activityTimestamps, ts);
|
|
119
148
|
} else if (currentTask && ts) {
|
|
120
149
|
currentTask.end = ts;
|
|
150
|
+
addTimestamp(currentTask.activityTimestamps, ts);
|
|
121
151
|
}
|
|
122
152
|
for (const part of msg.content || []) {
|
|
123
153
|
if (!part || part.type !== 'toolCall') continue;
|
|
@@ -135,8 +165,8 @@ async function scanPiSessions(root, source, events, sessionRows = [], taskRows =
|
|
|
135
165
|
const u = msg && msg.usage;
|
|
136
166
|
if (u) events.push({ source, file, timestamp: obj.timestamp, day: dayOf(obj.timestamp), session, provider, model, project: projectKey(file), kind: 'usage', input: +u.input||0, cache: +u.cacheRead||0, output: +u.output||0, total: +u.totalTokens||0, cost: cost(model, +u.input||0, +u.cacheRead||0, +u.output||0, true) });
|
|
137
167
|
}
|
|
138
|
-
|
|
139
|
-
row.activeMs =
|
|
168
|
+
pushTask(taskRows, currentTask);
|
|
169
|
+
row.activeMs = activeDuration(row.activityTimestamps);
|
|
140
170
|
if (row.messages || row.toolCalls || row.turns) sessionRows.push(row);
|
|
141
171
|
}
|
|
142
172
|
}
|
|
@@ -336,9 +366,7 @@ function sessionDuration(row) {
|
|
|
336
366
|
return row?.activeMs || 0;
|
|
337
367
|
}
|
|
338
368
|
function taskDuration(row) {
|
|
339
|
-
|
|
340
|
-
const end = Date.parse(row?.end || '');
|
|
341
|
-
return Number.isFinite(start) && Number.isFinite(end) && end >= start ? end - start : 0;
|
|
369
|
+
return row?.activeMs ?? activeDuration(row?.activityTimestamps || []);
|
|
342
370
|
}
|
|
343
371
|
function taskLabel(row, width = 34) {
|
|
344
372
|
const label = row?.title || row?.project || row?.session || 'unknown';
|
|
@@ -379,7 +407,7 @@ function renderFocusedView(stats, opts = {}) {
|
|
|
379
407
|
` ${pc.cyan(ms(sessionDuration(r)))} ${pc.dim(r.turns + ' turns')} ${pc.dim(r.toolCalls + ' tools')}`,
|
|
380
408
|
` ${pc.dim(r.file || '')}`,
|
|
381
409
|
].join('\n'), limit);
|
|
382
|
-
if (view === 'tasks-full' || view === 'task-full') return renderFullList('Longest
|
|
410
|
+
if (view === 'tasks-full' || view === 'task-full') return renderFullList('Longest Active Turns — Full Prompts', stats.topTasks || [], (r, i) => [
|
|
383
411
|
` ${pc.dim(String(i + 1).padStart(2, '0') + '.')} ${pc.cyan(ms(taskDuration(r)))} ${pc.magenta(r.toolCalls + ' tools')} ${pc.dim(dayOf(r.start))}`,
|
|
384
412
|
` ${pc.white(indentWrap(r.title || r.project || r.session || 'unknown'))}`,
|
|
385
413
|
` ${pc.dim(r.project || '')}`,
|
|
@@ -426,7 +454,7 @@ function renderFocusedView(stats, opts = {}) {
|
|
|
426
454
|
{ width: 8, align: 'right', get: r => pc.cyan(String(r.toolCalls)) },
|
|
427
455
|
{ width: 8, align: 'left', get: () => pc.dim('tools') },
|
|
428
456
|
]],
|
|
429
|
-
tasks: ['Longest
|
|
457
|
+
tasks: ['Longest Active Turns', stats.topTasks || [], [
|
|
430
458
|
{ width: 6, align: 'left', get: r => pc.dim(dayOf(r.start).slice(5)) },
|
|
431
459
|
{ width: 9, align: 'right', get: r => pc.cyan(ms(taskDuration(r))) },
|
|
432
460
|
{ width: 11, align: 'right', get: r => pc.magenta(`${r.toolCalls} tools`) },
|
|
@@ -518,9 +546,9 @@ export function renderTakomiStats(stats, opts = {}) {
|
|
|
518
546
|
// ── Duration Cards ────────────────────────────────────────────────────
|
|
519
547
|
lines.push('');
|
|
520
548
|
const cards3 = [
|
|
521
|
-
statCard(longestSession ? ms(sessionDuration(longestSession)) : '-', 'Active Session', pc.cyan),
|
|
549
|
+
statCard(longestSession ? ms(sessionDuration(longestSession)) : '-', 'Top Active Session', pc.cyan),
|
|
522
550
|
statCard(longestSession ? String(longestSession.turns) : '-', 'Turns in Session', pc.cyan),
|
|
523
|
-
statCard(longestTask ? ms(taskDuration(longestTask)) : '-', 'Longest
|
|
551
|
+
statCard(longestTask ? ms(taskDuration(longestTask)) : '-', 'Longest Active Turn', pc.magenta),
|
|
524
552
|
statCard(longestTask ? String(longestTask.toolCalls) : '-', 'Tools in Task', pc.magenta),
|
|
525
553
|
statCard(stats.mostSubagentsSession ? String(stats.mostSubagentsSession.subagentCalls) : '0', 'Max Subagents', pc.blue),
|
|
526
554
|
];
|
|
@@ -530,7 +558,7 @@ export function renderTakomiStats(stats, opts = {}) {
|
|
|
530
558
|
|
|
531
559
|
// ── Info line ─────────────────────────────────────────────────────────
|
|
532
560
|
lines.push('');
|
|
533
|
-
const infoText = `Peak: ${peak?.key || '-'} · ${streaks.quietDays} quiet days · ${stats.totals.events.toLocaleString()} events${stats.since ? ` · since ${stats.since}` : ''}`;
|
|
561
|
+
const infoText = `Peak: ${peak?.key || '-'} · ${streaks.quietDays} quiet days · ${stats.totals.events.toLocaleString()} events · active gaps ≤15m${stats.since ? ` · since ${stats.since}` : ''}`;
|
|
534
562
|
lines.push(center(pc.dim(infoText), W));
|
|
535
563
|
|
|
536
564
|
lines.push('');
|
|
@@ -586,10 +614,10 @@ export function renderTakomiStats(stats, opts = {}) {
|
|
|
586
614
|
]));
|
|
587
615
|
}
|
|
588
616
|
|
|
589
|
-
// ── Longest
|
|
617
|
+
// ── Longest Active Turns ───────────────────────────────────────────────
|
|
590
618
|
if (stats.topTasks?.length) {
|
|
591
619
|
lines.push('');
|
|
592
|
-
lines.push(renderTable('Longest
|
|
620
|
+
lines.push(renderTable('Longest Active Turns', stats.topTasks.slice(0, 5), [
|
|
593
621
|
{ width: 6, align: 'left', get: r => pc.dim(dayOf(r.start).slice(5)) },
|
|
594
622
|
{ width: 9, align: 'right', get: r => pc.cyan(ms(taskDuration(r))) },
|
|
595
623
|
{ width: 11, align: 'right', get: r => pc.magenta(`${r.toolCalls} tools`) },
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type SubagentState,
|
|
13
13
|
} from "./pi-subagents-internal";
|
|
14
14
|
import { resolveAgentName } from "./agent-aliases";
|
|
15
|
+
import { applyTakomiRoutingDefaults, loadTakomiModelRoutingSnapshotSync } from "../takomi-runtime/model-routing-defaults";
|
|
15
16
|
import type { TakomiSubagentToolParams, TakomiSubagentToolTask } from "./tool-runner";
|
|
16
17
|
|
|
17
18
|
type ToolUpdate = (partial: AgentToolResult<Details>) => void;
|
|
@@ -135,9 +136,18 @@ function defaultChildExtensions(): string[] {
|
|
|
135
136
|
return candidates.filter((candidate) => fs.existsSync(candidate));
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
function withTakomiAgentDefaults(agent: AgentConfig): AgentConfig {
|
|
139
|
+
function withTakomiAgentDefaults(agent: AgentConfig, cwd: string): AgentConfig {
|
|
140
|
+
const routed = applyTakomiRoutingDefaults({
|
|
141
|
+
agent: agent.name,
|
|
142
|
+
model: agent.model,
|
|
143
|
+
fallbackModels: agent.fallbackModels,
|
|
144
|
+
thinking: agent.thinking,
|
|
145
|
+
}, loadTakomiModelRoutingSnapshotSync(cwd));
|
|
139
146
|
return {
|
|
140
147
|
...agent,
|
|
148
|
+
model: routed.model,
|
|
149
|
+
fallbackModels: routed.fallbackModels,
|
|
150
|
+
thinking: routed.thinking,
|
|
141
151
|
systemPromptMode: agent.systemPromptMode ?? "replace",
|
|
142
152
|
inheritProjectContext: agent.inheritProjectContext ?? true,
|
|
143
153
|
inheritSkills: agent.inheritSkills ?? false,
|
|
@@ -147,7 +157,7 @@ function withTakomiAgentDefaults(agent: AgentConfig): AgentConfig {
|
|
|
147
157
|
}
|
|
148
158
|
|
|
149
159
|
function discoverUnifiedAgents(discoverPiAgents: any, cwd: string, scope: AgentScope): { agents: AgentConfig[] } {
|
|
150
|
-
return { agents: discoverPiAgents(cwd, scope).agents.map(withTakomiAgentDefaults) };
|
|
160
|
+
return { agents: discoverPiAgents(cwd, scope).agents.map((agent: AgentConfig) => withTakomiAgentDefaults(agent, cwd)) };
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
function agentNameSet(discoverPiAgents: any, cwd: string): Set<string> {
|
|
@@ -2,6 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import type { TakomiThinkingLevel } from "../../../src/pi-takomi-core";
|
|
4
4
|
import { loadTakomiProfile } from "../takomi-runtime/profile";
|
|
5
|
+
import { applyTakomiRoutingDefaults, loadTakomiModelRoutingSnapshot } from "../takomi-runtime/model-routing-defaults";
|
|
5
6
|
import { resolveAgentName } from "./agent-aliases";
|
|
6
7
|
import { discoverTakomiAgents, type TakomiAgentConfig, type TakomiAgentScope } from "./agents";
|
|
7
8
|
import { createTakomiDelegationPlan, renderTakomiDelegationPlan } from "./delegation-plan";
|
|
@@ -202,10 +203,11 @@ export async function executeTakomiSubagentTool(
|
|
|
202
203
|
const agents = discoverTakomiAgents(rootCwd, agentScope);
|
|
203
204
|
const byName = new Map<string, TakomiAgentConfig>(agents.map((agent) => [agent.name, agent]));
|
|
204
205
|
const mode = resolveMode(params);
|
|
205
|
-
const
|
|
206
|
+
const routingSnapshot = await loadTakomiModelRoutingSnapshot(rootCwd);
|
|
207
|
+
const tasks = resolveTasks(params).map((task) => applyTakomiRoutingDefaults({
|
|
206
208
|
...task,
|
|
207
209
|
agent: resolveAgentName(task.agent, byName),
|
|
208
|
-
}));
|
|
210
|
+
}, routingSnapshot));
|
|
209
211
|
|
|
210
212
|
if (!mode) {
|
|
211
213
|
return textResult(
|
package/.pi/settings.json
CHANGED
|
@@ -5,41 +5,39 @@
|
|
|
5
5
|
},
|
|
6
6
|
"subagents": {
|
|
7
7
|
"agentOverrides": {
|
|
8
|
-
"
|
|
9
|
-
"model": "oauth-router/gpt-5.
|
|
10
|
-
"thinking": "high"
|
|
8
|
+
"general": {
|
|
9
|
+
"model": "oauth-router/gpt-5.4",
|
|
10
|
+
"thinking": "high",
|
|
11
|
+
"fallbackModels": [
|
|
12
|
+
"oauth-router/gpt-5.5:low"
|
|
13
|
+
]
|
|
11
14
|
},
|
|
12
|
-
"
|
|
15
|
+
"orchestrator": {
|
|
13
16
|
"model": "oauth-router/gpt-5.5",
|
|
14
17
|
"thinking": "high"
|
|
15
18
|
},
|
|
16
|
-
"
|
|
19
|
+
"architect": {
|
|
17
20
|
"model": "oauth-router/gpt-5.5",
|
|
18
|
-
"thinking": "
|
|
21
|
+
"thinking": "high"
|
|
19
22
|
},
|
|
20
|
-
"
|
|
23
|
+
"designer": {
|
|
21
24
|
"model": "oauth-router/gpt-5.4",
|
|
22
25
|
"thinking": "high",
|
|
23
26
|
"fallbackModels": [
|
|
24
27
|
"oauth-router/gpt-5.5:low"
|
|
25
28
|
]
|
|
26
29
|
},
|
|
27
|
-
"
|
|
30
|
+
"coder": {
|
|
28
31
|
"model": "oauth-router/gpt-5.4",
|
|
29
|
-
"thinking": "high"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"thinking": "high"
|
|
34
|
-
},
|
|
35
|
-
"scout": {
|
|
36
|
-
"model": "oauth-router/gpt-5.4-mini",
|
|
37
|
-
"thinking": "high"
|
|
32
|
+
"thinking": "high",
|
|
33
|
+
"fallbackModels": [
|
|
34
|
+
"oauth-router/gpt-5.5:low"
|
|
35
|
+
]
|
|
38
36
|
},
|
|
39
|
-
"
|
|
40
|
-
"model": "oauth-router/gpt-5.
|
|
37
|
+
"reviewer": {
|
|
38
|
+
"model": "oauth-router/gpt-5.5",
|
|
41
39
|
"thinking": "high"
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
|
-
}
|
|
43
|
+
}
|
package/README.md
CHANGED
|
@@ -29,6 +29,11 @@ Optional global skills:
|
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
31
|
takomi setup skills
|
|
32
|
+
# First install defaults to Core Skills.
|
|
33
|
+
# Repeat installs default to Leave As Is so existing selections are not pruned accidentally.
|
|
34
|
+
# Custom opens a color-coded category TUI with expandable skill rows when a TTY is available.
|
|
35
|
+
# Optional Pi feature packs can also be managed later:
|
|
36
|
+
takomi setup pi-features
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
Useful management commands:
|
|
@@ -43,6 +48,8 @@ takomi setup project
|
|
|
43
48
|
|
|
44
49
|
Legacy commands like `takomi install pi`, `takomi sync pi`, `takomi upgrade`, and `takomi init` still work, but the simpler mental model is: **setup once, refresh when stale, run `takomi` to use it.**
|
|
45
50
|
|
|
51
|
+
During `takomi setup pi` or `takomi setup pi-features`, Takomi offers optional Pi feature packs with recommended/manual/select-all/skip choices. Current defaults install **Takomi Interview** (`npm:@juicesharp/rpiv-ask-user-question`) so models can ask structured clarification questions. **Takomi Todo** (`npm:@juicesharp/rpiv-todo`), **Takomi Browser QA** (`npm:pi-chrome`), and **Takomi Doc Preview** (`npm:pi-markdown-preview`) remain opt-in. `takomi refresh` runs Pi's package updater so installed optional, custom, old, and new Pi packages are reconciled together.
|
|
52
|
+
|
|
46
53
|
### Context Manager
|
|
47
54
|
|
|
48
55
|
Takomi now ships a Pi-native `takomi-context-manager` extension. It reduces prompt bloat with progressive context loading:
|
|
@@ -69,7 +76,8 @@ npx takomi install
|
|
|
69
76
|
What happens next:
|
|
70
77
|
- 🔍 **Auto-detects** every AI harness on your machine
|
|
71
78
|
- 📦 **Creates your command center** at `~/.takomi/`
|
|
72
|
-
-
|
|
79
|
+
- 🧰 **Lets you choose Core, Present Custom, Custom, All, or Leave As Is for skills**
|
|
80
|
+
- 📡 **Syncs your selected toolkit** to every IDE automatically
|
|
73
81
|
- 🔄 **Keeps KiloCode in sync** across CLI and VS Code
|
|
74
82
|
|
|
75
83
|
### Option B: Per-Project Setup
|
|
@@ -118,7 +126,9 @@ Original Takomi-authored skills in this bundle include `21st-dev-components`, `t
|
|
|
118
126
|
|
|
119
127
|
Think of skills as specialized team members you can summon on demand. From security audits to AI video generation — there's a skill for that.
|
|
120
128
|
|
|
121
|
-
|
|
129
|
+
Takomi's own installer no longer installs every bundled skill by default. `takomi setup skills` uses **Core Skills** for first-time installs, **Leave As Is** for repeat installs, and ownership-safe cleanup when you explicitly deselect Takomi-managed skills. Manual/user-added skills are preserved. Custom selection opens a color-coded category browser with expandable rows on capable terminals, and falls back to simple prompts elsewhere. The global store/harness sync path uses the same ownership model so deselected Takomi-managed skills and workflows can be pruned from `~/.takomi/` and synced harness folders without touching manual or imported resources.
|
|
130
|
+
|
|
131
|
+
The published bundle currently ships **72 top-level skills**, including the original `21st-dev-components` workflow for guided 21st.dev integration. The `pr-comment-fix` skill is sourced from https://gist.github.com/GSonofNun/35c67304c35dac7d6b43308b5371f671.
|
|
122
132
|
|
|
123
133
|
### Interactive Search & Install
|
|
124
134
|
```bash
|
|
@@ -130,7 +140,22 @@ npx -y skills add https://github.com/JStaRFilms/VibeCode-Protocol-Suite
|
|
|
130
140
|
```
|
|
131
141
|
|
|
132
142
|
### Core Essentials (Start Here)
|
|
133
|
-
The
|
|
143
|
+
The recommended Takomi installer defaults are:
|
|
144
|
+
|
|
145
|
+
```txt
|
|
146
|
+
takomi
|
|
147
|
+
sync-docs
|
|
148
|
+
code-review
|
|
149
|
+
security-audit
|
|
150
|
+
optimize-agent-context
|
|
151
|
+
agent-recovery
|
|
152
|
+
avoid-feature-creep
|
|
153
|
+
ai-sdk
|
|
154
|
+
git-commit-generation
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
For the external `skills` CLI, install only the router skill if you want the smallest possible footprint:
|
|
158
|
+
|
|
134
159
|
```bash
|
|
135
160
|
npx -y skills add https://github.com/JStaRFilms/VibeCode-Protocol-Suite --skill takomi
|
|
136
161
|
```
|
|
@@ -466,8 +491,9 @@ This is a living system. If you discover improvements:
|
|
|
466
491
|
|
|
467
492
|
## 🙏 Acknowledgements
|
|
468
493
|
|
|
469
|
-
Externally sourced skills
|
|
494
|
+
Externally sourced skills and optional Pi packages retain credit to their upstream creators. Takomi-original skills, workflows, and Takomi runtime/orchestration extensions in this repository, including `21st-dev-components`, remain authored and maintained by J StaR Films Studios.
|
|
470
495
|
|
|
496
|
+
- **Pi Coding Agent**: Built for [Pi](https://github.com/earendil-works/pi) / `@earendil-works/pi-coding-agent` by **Mario Zechner** and Earendil Works — the MIT-licensed coding-agent runtime and extension API that powers the Pi-native Takomi harness.
|
|
471
497
|
- **Anthropic Skills**: From [anthropics/skills](https://github.com/anthropics/skills) — a massive collection including **Office Suite** (PDF/DOCX/PPTX/XLSX), **Frontend Design**, **Webapp Testing**, **Algorithmic Art**, **Monorepo Management**, and **Skill Creator**.
|
|
472
498
|
- **Inference.sh Skills**: From [inference.sh/skills](https://github.com/inference-sh/skills) — complete media & automation suite including **Marketing Videos**, **Voice Cloning**, **Social Content**, **Twitter Automation**, **Product Photography**, and **Prompt Engineering**.
|
|
473
499
|
- **Marketing Skills**: From [coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills) — the complete marketer's toolkit: **Copywriting**, **Pricing Strategy**, **Social Strategy**, **Programmatic SEO**, and **Marketing Ideas**.
|
|
@@ -483,6 +509,10 @@ Externally sourced skills in this bundle retain credit to their upstream creator
|
|
|
483
509
|
- **Google Stitch Skills**: From [google-labs-code/stitch-skills](https://github.com/google-labs-code/stitch-skills) — Design-to-code suite including **design-md**, **enhance-prompt**, **stitch-loop**, **react-components**, and **shadcn-ui**.
|
|
484
510
|
- **Jules**: From [sanjay3290/ai-skills](https://github.com/sanjay3290/ai-skills) — delegate coding tasks to Google Jules AI agent.
|
|
485
511
|
- **Subagent Execution**: Built on **[`pi-subagents`](https://github.com/nicobailon/pi-subagents)** by **Nico Bailon** — providing the underlying Pi extension for delegated subagent runs (result rendering, live progress, single/parallel/chain execution, session/artifact handling, and related subagent tooling), upon which Takomi adds its own lifecycle orchestration, model-routing policy, and workflow metadata.
|
|
512
|
+
- **Takomi Interview / Todo Optional Packs**: Optional setup integrates **[`@juicesharp/rpiv-ask-user-question`](https://github.com/juicesharp/rpiv-mono/tree/main/packages/rpiv-ask-user-question)** and **[`@juicesharp/rpiv-todo`](https://github.com/juicesharp/rpiv-mono/tree/main/packages/rpiv-todo)** by **juicesharp** — MIT-licensed Pi extensions for structured user questions and live todo overlays.
|
|
513
|
+
- **Takomi Browser QA Optional Pack**: Optional setup can install **[`pi-chrome`](https://github.com/tianrendong/pi-chrome)** by **tianrendong** — an MIT-licensed Pi extension for explicitly authorized Chrome/browser automation.
|
|
514
|
+
- **Takomi Doc Preview Optional Pack**: Optional setup can install **[`pi-markdown-preview`](https://github.com/omaclaren/pi-markdown-preview)** by **omaclaren** — an MIT-licensed Pi extension for terminal/browser/PDF markdown and LaTeX previews.
|
|
515
|
+
- **Context Mode Research / Optional Power User Tooling**: **[`context-mode`](https://github.com/mksglu/context-mode)** by **Mert Koseoğlu** is credited as an external context-window and session-continuity project. It is not bundled as a Takomi default; users can install/evaluate it separately under its own license.
|
|
486
516
|
- **Git Commit Generation**: From the **[`kilocode`](https://github.com/Kilo-Org/kilocode)** repository by **Kilo-Org** (specifically, [git-commit-generation.md](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-docs/pages/code-with-ai/features/git-commit-generation.md)) — enabling automated, high-quality conventional git commit messages based on staged changes.
|
|
487
517
|
|
|
488
518
|
## 📄 License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "takomi",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.28",
|
|
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": {
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
".pi/takomi/policies"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
|
-
"
|
|
25
|
+
"postinstall": "node src/postinstall.js",
|
|
26
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
27
|
+
"test:skills": "node scripts/test-skill-selection.js"
|
|
26
28
|
},
|
|
27
29
|
"repository": {
|
|
28
30
|
"type": "git",
|