takomi 2.1.13 → 2.1.15

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 (39) hide show
  1. package/.pi/agents/architect.md +73 -73
  2. package/.pi/agents/coder.md +70 -70
  3. package/.pi/agents/designer.md +72 -72
  4. package/.pi/agents/orchestrator.md +122 -122
  5. package/.pi/agents/reviewer.md +71 -71
  6. package/.pi/extensions/oauth-router/provider.ts +3 -1
  7. package/.pi/extensions/takomi-context-manager/config.ts +48 -48
  8. package/.pi/extensions/takomi-context-manager/context-router.ts +57 -57
  9. package/.pi/extensions/takomi-context-manager/diagnostics-tools.ts +28 -28
  10. package/.pi/extensions/takomi-context-manager/diagnostics.ts +55 -55
  11. package/.pi/extensions/takomi-context-manager/extension-conflicts.ts +56 -56
  12. package/.pi/extensions/takomi-context-manager/index.ts +56 -56
  13. package/.pi/extensions/takomi-context-manager/model-policy-gate.ts +228 -206
  14. package/.pi/extensions/takomi-context-manager/policy-registry.ts +97 -97
  15. package/.pi/extensions/takomi-context-manager/policy-tools.ts +35 -35
  16. package/.pi/extensions/takomi-context-manager/prerequisite-gates.ts +39 -39
  17. package/.pi/extensions/takomi-context-manager/prompt-rewriter.ts +100 -100
  18. package/.pi/extensions/takomi-context-manager/skill-registry.ts +87 -87
  19. package/.pi/extensions/takomi-context-manager/skill-tools.ts +80 -80
  20. package/.pi/extensions/takomi-context-manager/state.ts +68 -68
  21. package/.pi/extensions/takomi-context-manager/types.ts +77 -77
  22. package/.pi/extensions/takomi-runtime/command-text.ts +10 -2
  23. package/.pi/extensions/takomi-runtime/commands.ts +78 -5
  24. package/.pi/extensions/takomi-runtime/routing-policy.ts +187 -145
  25. package/.pi/extensions/takomi-subagents/native-render.ts +41 -41
  26. package/.pi/extensions/takomi-subagents/pi-subagents-internal.ts +35 -32
  27. package/.pi/extensions/takomi-subagents/run-types.ts +25 -25
  28. package/.pi/prompts/build-prompt.md +259 -259
  29. package/.pi/prompts/design-prompt.md +95 -95
  30. package/.pi/prompts/genesis-prompt.md +140 -140
  31. package/.pi/prompts/prime-prompt.md +110 -110
  32. package/.pi/themes/takomi-aurora.json +88 -88
  33. package/README.md +2 -4
  34. package/assets/.agent/skills/21st-dev-components/SKILL.md +244 -244
  35. package/assets/.agent/skills/anti-gravity/SKILL.md +112 -0
  36. package/assets/.agent/skills/gemini/SKILL.md +14 -223
  37. package/assets/.agent/skills/git-commit-generation/SKILL.md +195 -0
  38. package/package.json +1 -1
  39. package/src/pi-takomi-core/validation.ts +135 -135
@@ -1,135 +1,135 @@
1
- import type {
2
- OrchestratorSessionState,
3
- OrchestratorTask,
4
- OrchestratorTaskStatus,
5
- TakomiWorkflowId,
6
- VibeLifecycleStage,
7
- } from "./types";
8
- import { workflowToStage } from "./orchestration";
9
-
10
- export type TakomiValidationSeverity = "error" | "warning" | "advisory";
11
-
12
- export type TakomiValidationIssue = {
13
- severity: TakomiValidationSeverity;
14
- code: string;
15
- message: string;
16
- taskId?: string;
17
- };
18
-
19
- export type TakomiValidationReport = {
20
- ok: boolean;
21
- errors: TakomiValidationIssue[];
22
- warnings: TakomiValidationIssue[];
23
- advisories: TakomiValidationIssue[];
24
- issues: TakomiValidationIssue[];
25
- };
26
-
27
- const STAGES: VibeLifecycleStage[] = ["genesis", "design", "build"];
28
- const STATUSES: OrchestratorTaskStatus[] = ["pending", "in-progress", "completed", "blocked"];
29
- const LONG_PROSE_FIELDS: Array<keyof OrchestratorTask> = [
30
- "objective",
31
- "scope",
32
- "definitionOfDone",
33
- "expectedArtifacts",
34
- "reviewCheckpoint",
35
- "instructions",
36
- "notes",
37
- ];
38
-
39
- function issue(severity: TakomiValidationSeverity, code: string, message: string, taskId?: string): TakomiValidationIssue {
40
- return { severity, code, message, taskId };
41
- }
42
-
43
- function hasLongProse(value: unknown): boolean {
44
- if (typeof value === "string") return value.length > 280;
45
- if (Array.isArray(value)) return value.some((item) => typeof item === "string" && item.length > 180) || value.length > 12;
46
- return false;
47
- }
48
-
49
- function taskWorkflowStageMismatch(task: OrchestratorTask): boolean {
50
- const workflowStage = workflowToStage(task.workflow as TakomiWorkflowId | undefined);
51
- return Boolean(task.stage && workflowStage && task.stage !== workflowStage);
52
- }
53
-
54
- function finish(issues: TakomiValidationIssue[]): TakomiValidationReport {
55
- const errors = issues.filter((entry) => entry.severity === "error");
56
- const warnings = issues.filter((entry) => entry.severity === "warning");
57
- const advisories = issues.filter((entry) => entry.severity === "advisory");
58
- return { ok: errors.length === 0, errors, warnings, advisories, issues };
59
- }
60
-
61
- export function validateSessionState(state: OrchestratorSessionState): TakomiValidationReport {
62
- const issues: TakomiValidationIssue[] = [];
63
-
64
- if (!/^orch-\d{8}-\d{6}/.test(state.sessionId)) {
65
- issues.push(issue("warning", "session-id-format", `Session ID does not match orch-YYYYMMDD-HHMMSS: ${state.sessionId}`));
66
- }
67
- if (!state.title?.trim()) issues.push(issue("error", "missing-title", "Session title is required."));
68
- if (state.mode !== "hybrid") issues.push(issue("error", "invalid-mode", `Unsupported session mode: ${String(state.mode)}`));
69
- if (!state.lifecycle) issues.push(issue("error", "missing-lifecycle", "Lifecycle state is required."));
70
- if (!Array.isArray(state.tasks)) issues.push(issue("error", "missing-tasks", "Session tasks must be an array."));
71
-
72
- const taskIds = new Set<string>();
73
- for (const task of state.tasks ?? []) {
74
- if (!task.id?.trim()) issues.push(issue("error", "missing-task-id", `Task is missing an ID: ${task.title || "(untitled)"}`));
75
- if (taskIds.has(task.id)) issues.push(issue("error", "duplicate-task-id", `Duplicate task ID: ${task.id}`, task.id));
76
- taskIds.add(task.id);
77
-
78
- if (!task.title?.trim()) issues.push(issue("error", "missing-task-title", "Task title is required.", task.id));
79
- if (!STATUSES.includes(task.status)) issues.push(issue("error", "invalid-task-status", `Invalid status: ${String(task.status)}`, task.id));
80
- if (taskWorkflowStageMismatch(task)) {
81
- issues.push(issue("error", "stage-workflow-mismatch", `Task stage ${task.stage} conflicts with workflow ${task.workflow}.`, task.id));
82
- }
83
- for (const dependency of task.dependencies ?? []) {
84
- if (!taskIds.has(dependency) && !(state.tasks ?? []).some((candidate) => candidate.id === dependency)) {
85
- issues.push(issue("error", "missing-dependency", `Task depends on missing task: ${dependency}`, task.id));
86
- }
87
- }
88
- if (task.status === "completed" && task.checklist?.some((item) => !item.done)) {
89
- issues.push(issue("error", "completed-task-incomplete-checklist", "Completed task has incomplete checklist items.", task.id));
90
- }
91
- for (const field of LONG_PROSE_FIELDS) {
92
- if (hasLongProse(task[field])) {
93
- issues.push(issue("warning", "json-prose-field", `Task JSON contains substantial prose in ${String(field)}; prefer authored markdown for long-form content.`, task.id));
94
- }
95
- }
96
- if (task.skills?.length && task.skills.length > 12) {
97
- issues.push(issue("warning", "too-many-skill-overlays", "Task lists more than 12 skill/context overlays.", task.id));
98
- }
99
- }
100
-
101
- for (const stage of STAGES) {
102
- const lifecycle = state.lifecycle?.[stage];
103
- if (!lifecycle) {
104
- issues.push(issue("error", "missing-stage", `Lifecycle stage is missing: ${stage}`));
105
- continue;
106
- }
107
- for (const taskId of lifecycle.taskIds ?? []) {
108
- if (!taskIds.has(taskId)) issues.push(issue("error", "lifecycle-missing-task", `Lifecycle stage ${stage} references missing task ${taskId}.`));
109
- }
110
- const stageTasks = state.tasks.filter((task) => task.stage === stage || workflowToStage(task.workflow) === stage);
111
- if (lifecycle.status === "completed" && stageTasks.some((task) => task.status !== "completed")) {
112
- issues.push(issue("error", "stage-completed-with-open-tasks", `Stage ${stage} is completed but contains non-completed tasks.`));
113
- }
114
- if (lifecycle.status === "in-progress" && !stageTasks.some((task) => task.status === "in-progress")) {
115
- issues.push(issue("warning", "stage-in-progress-without-task", `Stage ${stage} is in-progress but has no in-progress task.`));
116
- }
117
- if (lifecycle.status === "blocked" && !stageTasks.some((task) => task.status === "blocked")) {
118
- issues.push(issue("warning", "stage-blocked-without-task", `Stage ${stage} is blocked but has no blocked task.`));
119
- }
120
- }
121
-
122
- if (state.sessionIntent === "full-project" && state.tasks.length === 1) {
123
- issues.push(issue("warning", "broad-session-single-task", "Full-project session has one task; add a justification or decompose when scope is broad."));
124
- }
125
-
126
- return finish(issues);
127
- }
128
-
129
- export function renderValidationReport(report: TakomiValidationReport): string {
130
- if (report.issues.length === 0) return "Takomi session validation: PASS";
131
- return [
132
- `Takomi session validation: ${report.ok ? "WARNINGS" : "ERRORS"}`,
133
- ...report.issues.map((entry) => `- [${entry.severity.toUpperCase()}] ${entry.code}${entry.taskId ? ` (${entry.taskId})` : ""}: ${entry.message}`),
134
- ].join("\n");
135
- }
1
+ import type {
2
+ OrchestratorSessionState,
3
+ OrchestratorTask,
4
+ OrchestratorTaskStatus,
5
+ TakomiWorkflowId,
6
+ VibeLifecycleStage,
7
+ } from "./types";
8
+ import { workflowToStage } from "./orchestration";
9
+
10
+ export type TakomiValidationSeverity = "error" | "warning" | "advisory";
11
+
12
+ export type TakomiValidationIssue = {
13
+ severity: TakomiValidationSeverity;
14
+ code: string;
15
+ message: string;
16
+ taskId?: string;
17
+ };
18
+
19
+ export type TakomiValidationReport = {
20
+ ok: boolean;
21
+ errors: TakomiValidationIssue[];
22
+ warnings: TakomiValidationIssue[];
23
+ advisories: TakomiValidationIssue[];
24
+ issues: TakomiValidationIssue[];
25
+ };
26
+
27
+ const STAGES: VibeLifecycleStage[] = ["genesis", "design", "build"];
28
+ const STATUSES: OrchestratorTaskStatus[] = ["pending", "in-progress", "completed", "blocked"];
29
+ const LONG_PROSE_FIELDS: Array<keyof OrchestratorTask> = [
30
+ "objective",
31
+ "scope",
32
+ "definitionOfDone",
33
+ "expectedArtifacts",
34
+ "reviewCheckpoint",
35
+ "instructions",
36
+ "notes",
37
+ ];
38
+
39
+ function issue(severity: TakomiValidationSeverity, code: string, message: string, taskId?: string): TakomiValidationIssue {
40
+ return { severity, code, message, taskId };
41
+ }
42
+
43
+ function hasLongProse(value: unknown): boolean {
44
+ if (typeof value === "string") return value.length > 280;
45
+ if (Array.isArray(value)) return value.some((item) => typeof item === "string" && item.length > 180) || value.length > 12;
46
+ return false;
47
+ }
48
+
49
+ function taskWorkflowStageMismatch(task: OrchestratorTask): boolean {
50
+ const workflowStage = workflowToStage(task.workflow as TakomiWorkflowId | undefined);
51
+ return Boolean(task.stage && workflowStage && task.stage !== workflowStage);
52
+ }
53
+
54
+ function finish(issues: TakomiValidationIssue[]): TakomiValidationReport {
55
+ const errors = issues.filter((entry) => entry.severity === "error");
56
+ const warnings = issues.filter((entry) => entry.severity === "warning");
57
+ const advisories = issues.filter((entry) => entry.severity === "advisory");
58
+ return { ok: errors.length === 0, errors, warnings, advisories, issues };
59
+ }
60
+
61
+ export function validateSessionState(state: OrchestratorSessionState): TakomiValidationReport {
62
+ const issues: TakomiValidationIssue[] = [];
63
+
64
+ if (!/^orch-\d{8}-\d{6}/.test(state.sessionId)) {
65
+ issues.push(issue("warning", "session-id-format", `Session ID does not match orch-YYYYMMDD-HHMMSS: ${state.sessionId}`));
66
+ }
67
+ if (!state.title?.trim()) issues.push(issue("error", "missing-title", "Session title is required."));
68
+ if (state.mode !== "hybrid") issues.push(issue("error", "invalid-mode", `Unsupported session mode: ${String(state.mode)}`));
69
+ if (!state.lifecycle) issues.push(issue("error", "missing-lifecycle", "Lifecycle state is required."));
70
+ if (!Array.isArray(state.tasks)) issues.push(issue("error", "missing-tasks", "Session tasks must be an array."));
71
+
72
+ const taskIds = new Set<string>();
73
+ for (const task of state.tasks ?? []) {
74
+ if (!task.id?.trim()) issues.push(issue("error", "missing-task-id", `Task is missing an ID: ${task.title || "(untitled)"}`));
75
+ if (taskIds.has(task.id)) issues.push(issue("error", "duplicate-task-id", `Duplicate task ID: ${task.id}`, task.id));
76
+ taskIds.add(task.id);
77
+
78
+ if (!task.title?.trim()) issues.push(issue("error", "missing-task-title", "Task title is required.", task.id));
79
+ if (!STATUSES.includes(task.status)) issues.push(issue("error", "invalid-task-status", `Invalid status: ${String(task.status)}`, task.id));
80
+ if (taskWorkflowStageMismatch(task)) {
81
+ issues.push(issue("error", "stage-workflow-mismatch", `Task stage ${task.stage} conflicts with workflow ${task.workflow}.`, task.id));
82
+ }
83
+ for (const dependency of task.dependencies ?? []) {
84
+ if (!taskIds.has(dependency) && !(state.tasks ?? []).some((candidate) => candidate.id === dependency)) {
85
+ issues.push(issue("error", "missing-dependency", `Task depends on missing task: ${dependency}`, task.id));
86
+ }
87
+ }
88
+ if (task.status === "completed" && task.checklist?.some((item) => !item.done)) {
89
+ issues.push(issue("error", "completed-task-incomplete-checklist", "Completed task has incomplete checklist items.", task.id));
90
+ }
91
+ for (const field of LONG_PROSE_FIELDS) {
92
+ if (hasLongProse(task[field])) {
93
+ issues.push(issue("warning", "json-prose-field", `Task JSON contains substantial prose in ${String(field)}; prefer authored markdown for long-form content.`, task.id));
94
+ }
95
+ }
96
+ if (task.skills?.length && task.skills.length > 12) {
97
+ issues.push(issue("warning", "too-many-skill-overlays", "Task lists more than 12 skill/context overlays.", task.id));
98
+ }
99
+ }
100
+
101
+ for (const stage of STAGES) {
102
+ const lifecycle = state.lifecycle?.[stage];
103
+ if (!lifecycle) {
104
+ issues.push(issue("error", "missing-stage", `Lifecycle stage is missing: ${stage}`));
105
+ continue;
106
+ }
107
+ for (const taskId of lifecycle.taskIds ?? []) {
108
+ if (!taskIds.has(taskId)) issues.push(issue("error", "lifecycle-missing-task", `Lifecycle stage ${stage} references missing task ${taskId}.`));
109
+ }
110
+ const stageTasks = state.tasks.filter((task) => task.stage === stage || workflowToStage(task.workflow) === stage);
111
+ if (lifecycle.status === "completed" && stageTasks.some((task) => task.status !== "completed")) {
112
+ issues.push(issue("error", "stage-completed-with-open-tasks", `Stage ${stage} is completed but contains non-completed tasks.`));
113
+ }
114
+ if (lifecycle.status === "in-progress" && !stageTasks.some((task) => task.status === "in-progress")) {
115
+ issues.push(issue("warning", "stage-in-progress-without-task", `Stage ${stage} is in-progress but has no in-progress task.`));
116
+ }
117
+ if (lifecycle.status === "blocked" && !stageTasks.some((task) => task.status === "blocked")) {
118
+ issues.push(issue("warning", "stage-blocked-without-task", `Stage ${stage} is blocked but has no blocked task.`));
119
+ }
120
+ }
121
+
122
+ if (state.sessionIntent === "full-project" && state.tasks.length === 1) {
123
+ issues.push(issue("warning", "broad-session-single-task", "Full-project session has one task; add a justification or decompose when scope is broad."));
124
+ }
125
+
126
+ return finish(issues);
127
+ }
128
+
129
+ export function renderValidationReport(report: TakomiValidationReport): string {
130
+ if (report.issues.length === 0) return "Takomi session validation: PASS";
131
+ return [
132
+ `Takomi session validation: ${report.ok ? "WARNINGS" : "ERRORS"}`,
133
+ ...report.issues.map((entry) => `- [${entry.severity.toUpperCase()}] ${entry.code}${entry.taskId ? ` (${entry.taskId})` : ""}: ${entry.message}`),
134
+ ].join("\n");
135
+ }