@meowlynxsea/koi 0.1.0
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/LICENSE +34 -0
- package/NOTICE +35 -0
- package/README.md +15 -0
- package/bin/koi +12 -0
- package/dist/highlights-eq9cgrbb.scm +604 -0
- package/dist/highlights-ghv9g403.scm +205 -0
- package/dist/highlights-hk7bwhj4.scm +284 -0
- package/dist/highlights-r812a2qc.scm +150 -0
- package/dist/highlights-x6tmsnaa.scm +115 -0
- package/dist/injections-73j83es3.scm +27 -0
- package/dist/main.js +489918 -0
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/package.json +51 -0
- package/src/agent/check-permissions.ts +239 -0
- package/src/agent/hooks/message-utils.ts +305 -0
- package/src/agent/hooks/types.ts +32 -0
- package/src/agent/hooks.ts +1560 -0
- package/src/agent/mode.ts +163 -0
- package/src/agent/monitor-registry.ts +308 -0
- package/src/agent/permission-ui.ts +71 -0
- package/src/agent/plan-ui.ts +74 -0
- package/src/agent/question-ui.ts +58 -0
- package/src/agent/session-fork.ts +299 -0
- package/src/agent/session-snapshots.ts +216 -0
- package/src/agent/session-store.ts +649 -0
- package/src/agent/session-tasks.ts +305 -0
- package/src/agent/session.ts +27 -0
- package/src/agent/subagent-registry.ts +176 -0
- package/src/agent/subagent.ts +194 -0
- package/src/agent/tool-orchestration.ts +55 -0
- package/src/agent/tools.ts +8 -0
- package/src/cli/args.ts +6 -0
- package/src/cli/commands.ts +5 -0
- package/src/commands/skills/index.ts +23 -0
- package/src/config/models.ts +6 -0
- package/src/config/settings.ts +392 -0
- package/src/main.tsx +64 -0
- package/src/services/mcp/client.ts +194 -0
- package/src/services/mcp/config.ts +232 -0
- package/src/services/mcp/connection-manager.ts +258 -0
- package/src/services/mcp/index.ts +80 -0
- package/src/services/mcp/mcp-commands.ts +114 -0
- package/src/services/mcp/stdio-transport.ts +246 -0
- package/src/services/mcp/types.ts +155 -0
- package/src/skills/SkillsMenu.tsx +370 -0
- package/src/skills/bundled/batch.ts +106 -0
- package/src/skills/bundled/debug.ts +86 -0
- package/src/skills/bundled/loremIpsum.ts +101 -0
- package/src/skills/bundled/remember.ts +97 -0
- package/src/skills/bundled/simplify.ts +100 -0
- package/src/skills/bundled/skillify.ts +123 -0
- package/src/skills/bundled/stuck.ts +101 -0
- package/src/skills/bundled/updateConfig.ts +228 -0
- package/src/skills/bundled.ts +46 -0
- package/src/skills/frontmatter.ts +179 -0
- package/src/skills/index.ts +87 -0
- package/src/skills/invoke.ts +231 -0
- package/src/skills/loader.ts +710 -0
- package/src/skills/substitution.ts +169 -0
- package/src/skills/types.ts +201 -0
- package/src/tools/agent.ts +143 -0
- package/src/tools/ask-user-question.ts +46 -0
- package/src/tools/bash.ts +148 -0
- package/src/tools/edit.ts +164 -0
- package/src/tools/glob.ts +102 -0
- package/src/tools/grep.ts +248 -0
- package/src/tools/index.ts +73 -0
- package/src/tools/list-mcp-resources.ts +74 -0
- package/src/tools/ls.ts +85 -0
- package/src/tools/mcp.ts +76 -0
- package/src/tools/monitor.ts +159 -0
- package/src/tools/plan-mode.ts +134 -0
- package/src/tools/read-mcp-resource.ts +79 -0
- package/src/tools/read.ts +137 -0
- package/src/tools/skill.ts +176 -0
- package/src/tools/task.ts +349 -0
- package/src/tools/types.ts +52 -0
- package/src/tools/webfetch-domains.ts +239 -0
- package/src/tools/webfetch.ts +533 -0
- package/src/tools/write.ts +101 -0
- package/src/tui/app.tsx +1178 -0
- package/src/tui/components/chat-panel.tsx +1071 -0
- package/src/tui/components/command-panel.tsx +261 -0
- package/src/tui/components/confirm-modal.tsx +135 -0
- package/src/tui/components/connect-modal.tsx +435 -0
- package/src/tui/components/connecting-modal.tsx +167 -0
- package/src/tui/components/edit-pending-modal.tsx +103 -0
- package/src/tui/components/exit-modal.tsx +131 -0
- package/src/tui/components/fork-modal.tsx +377 -0
- package/src/tui/components/image-preview-modal.tsx +141 -0
- package/src/tui/components/image-utils.ts +128 -0
- package/src/tui/components/info-bar.tsx +103 -0
- package/src/tui/components/input-box.tsx +352 -0
- package/src/tui/components/mcp/MCPSettings.tsx +386 -0
- package/src/tui/components/mcp/index.ts +7 -0
- package/src/tui/components/model-modal.tsx +310 -0
- package/src/tui/components/pending-area.tsx +88 -0
- package/src/tui/components/rename-modal.tsx +119 -0
- package/src/tui/components/session-modal.tsx +233 -0
- package/src/tui/components/side-bar.tsx +349 -0
- package/src/tui/components/tool-output.ts +6 -0
- package/src/tui/hooks/user-prompt-history.ts +114 -0
- package/src/tui/theme.ts +63 -0
- package/src/types/commands.ts +80 -0
- package/src/types/cross-spawn.d.ts +24 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool metadata and shared types for Koi's custom tool system.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
6
|
+
import type { AgentToolResult } from "@mariozechner/pi-coding-agent";
|
|
7
|
+
|
|
8
|
+
export interface ToolMetadata {
|
|
9
|
+
name: string;
|
|
10
|
+
isReadOnly: boolean;
|
|
11
|
+
isDestructive: boolean;
|
|
12
|
+
riskLevel: "low" | "medium" | "high";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const TOOL_METADATA: Record<string, ToolMetadata> = {
|
|
16
|
+
read: { name: "read", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
17
|
+
grep: { name: "grep", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
18
|
+
glob: { name: "glob", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
19
|
+
ls: { name: "ls", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
20
|
+
bash: { name: "bash", isReadOnly: false, isDestructive: true, riskLevel: "high" },
|
|
21
|
+
edit: { name: "edit", isReadOnly: false, isDestructive: false, riskLevel: "medium" },
|
|
22
|
+
write: { name: "write", isReadOnly: false, isDestructive: true, riskLevel: "medium" },
|
|
23
|
+
webfetch: { name: "webfetch", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
24
|
+
taskCreate: { name: "taskCreate", isReadOnly: false, isDestructive: false, riskLevel: "low" },
|
|
25
|
+
taskGet: { name: "taskGet", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
26
|
+
taskList: { name: "taskList", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
27
|
+
taskUpdate: { name: "taskUpdate", isReadOnly: false, isDestructive: false, riskLevel: "low" },
|
|
28
|
+
askUserQuestion: { name: "askUserQuestion", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
29
|
+
enterPlanMode: { name: "enterPlanMode", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
30
|
+
exitPlanMode: { name: "exitPlanMode", isReadOnly: true, isDestructive: false, riskLevel: "low" },
|
|
31
|
+
agent: { name: "agent", isReadOnly: false, isDestructive: false, riskLevel: "medium" },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type KoiToolName = keyof typeof TOOL_METADATA;
|
|
35
|
+
|
|
36
|
+
export function isReadOnlyTool(name: string): boolean {
|
|
37
|
+
return TOOL_METADATA[name]?.isReadOnly ?? false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isDestructiveTool(name: string): boolean {
|
|
41
|
+
return TOOL_METADATA[name]?.isDestructive ?? false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type AnyToolDefinition = ToolDefinition;
|
|
45
|
+
|
|
46
|
+
/** AgentToolResult with optional isError flag for permission denials. */
|
|
47
|
+
export type ToolResultWithError<T> = AgentToolResult<T> & { isError?: boolean };
|
|
48
|
+
|
|
49
|
+
/** Extract a readable message from an unknown error value. */
|
|
50
|
+
export function getErrorMessage(err: unknown): string {
|
|
51
|
+
return err instanceof Error ? err.message : String(err);
|
|
52
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebFetchTool — 预批准域名列表与域名检查
|
|
3
|
+
*
|
|
4
|
+
* 抽离为独立模块,避免 check-permissions.ts 与 webfetch.ts 之间的循环依赖。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** 危险/本地域名黑名单 */
|
|
8
|
+
export const DANGEROUS_DOMAINS: string[] = [
|
|
9
|
+
"localhost",
|
|
10
|
+
"127.0.0.1",
|
|
11
|
+
"0.0.0.0",
|
|
12
|
+
"[::1]",
|
|
13
|
+
"[::]",
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/** 预批准技术文档域名(127+ 条) */
|
|
17
|
+
export const PREAPPROVED_DOMAINS: string[] = [
|
|
18
|
+
/* Python */
|
|
19
|
+
"docs.python.org",
|
|
20
|
+
"python.org",
|
|
21
|
+
/* MDN / Web 标准 */
|
|
22
|
+
"developer.mozilla.org",
|
|
23
|
+
"mdn.dev",
|
|
24
|
+
/* TypeScript / JavaScript 运行时 */
|
|
25
|
+
"typescriptlang.org",
|
|
26
|
+
"nodejs.org",
|
|
27
|
+
"npmjs.com",
|
|
28
|
+
"deno.land",
|
|
29
|
+
"bun.sh",
|
|
30
|
+
/* React 生态 */
|
|
31
|
+
"react.dev",
|
|
32
|
+
"reactjs.org",
|
|
33
|
+
"nextjs.org",
|
|
34
|
+
"remix.run",
|
|
35
|
+
/* Vue / Angular / Svelte */
|
|
36
|
+
"vuejs.org",
|
|
37
|
+
"nuxt.com",
|
|
38
|
+
"angular.io",
|
|
39
|
+
"angular.cn",
|
|
40
|
+
"svelte.dev",
|
|
41
|
+
"solidjs.com",
|
|
42
|
+
/* Go */
|
|
43
|
+
"go.dev",
|
|
44
|
+
"golang.org",
|
|
45
|
+
"golang.google.cn",
|
|
46
|
+
"pkg.go.dev",
|
|
47
|
+
/* Rust */
|
|
48
|
+
"doc.rust-lang.org",
|
|
49
|
+
"rust-lang.org",
|
|
50
|
+
"docs.rs",
|
|
51
|
+
"crates.io",
|
|
52
|
+
/* Java / JVM */
|
|
53
|
+
"docs.oracle.com",
|
|
54
|
+
"spring.io",
|
|
55
|
+
"docs.spring.io",
|
|
56
|
+
"kotlinlang.org",
|
|
57
|
+
"docs.kotlinlang.org",
|
|
58
|
+
/* .NET */
|
|
59
|
+
"learn.microsoft.com",
|
|
60
|
+
"dotnet.microsoft.com",
|
|
61
|
+
"asp.net",
|
|
62
|
+
/* Swift / Apple */
|
|
63
|
+
"developer.apple.com",
|
|
64
|
+
"swift.org",
|
|
65
|
+
/* 云平台 */
|
|
66
|
+
"docs.aws.amazon.com",
|
|
67
|
+
"aws.amazon.com",
|
|
68
|
+
"cloud.google.com",
|
|
69
|
+
"developers.google.com",
|
|
70
|
+
"firebase.google.com",
|
|
71
|
+
"azure.microsoft.com",
|
|
72
|
+
"docs.digitalocean.com",
|
|
73
|
+
/* 数据库 */
|
|
74
|
+
"postgresql.org",
|
|
75
|
+
"docs.postgresql.org",
|
|
76
|
+
"mysql.com",
|
|
77
|
+
"dev.mysql.com",
|
|
78
|
+
"mongodb.com",
|
|
79
|
+
"docs.mongodb.com",
|
|
80
|
+
"redis.io",
|
|
81
|
+
"redis.com",
|
|
82
|
+
"sqlite.org",
|
|
83
|
+
"www.sqlite.org",
|
|
84
|
+
"neo4j.com",
|
|
85
|
+
"prisma.io",
|
|
86
|
+
"orm.drizzle.team",
|
|
87
|
+
"cassandra.apache.org",
|
|
88
|
+
"influxdata.com",
|
|
89
|
+
/* ML / AI / Data Science */
|
|
90
|
+
"pytorch.org",
|
|
91
|
+
"tensorflow.org",
|
|
92
|
+
"keras.io",
|
|
93
|
+
"huggingface.co",
|
|
94
|
+
"scikit-learn.org",
|
|
95
|
+
"scipy.org",
|
|
96
|
+
"numpy.org",
|
|
97
|
+
"pandas.pydata.org",
|
|
98
|
+
"matplotlib.org",
|
|
99
|
+
"jupyter.org",
|
|
100
|
+
"openai.com",
|
|
101
|
+
"platform.openai.com",
|
|
102
|
+
"docs.anthropic.com",
|
|
103
|
+
"langchain.com",
|
|
104
|
+
"python.langchain.com",
|
|
105
|
+
"docs.llamaindex.ai",
|
|
106
|
+
"mlflow.org",
|
|
107
|
+
/* 容器 / DevOps */
|
|
108
|
+
"docker.com",
|
|
109
|
+
"docs.docker.com",
|
|
110
|
+
"kubernetes.io",
|
|
111
|
+
"helm.sh",
|
|
112
|
+
"terraform.io",
|
|
113
|
+
"ansible.com",
|
|
114
|
+
"prometheus.io",
|
|
115
|
+
"grafana.com",
|
|
116
|
+
"grafana.org",
|
|
117
|
+
"nginx.org",
|
|
118
|
+
"nginx.com",
|
|
119
|
+
"traefik.io",
|
|
120
|
+
/* Git 托管 / CI */
|
|
121
|
+
"github.com",
|
|
122
|
+
"docs.github.com",
|
|
123
|
+
"gitlab.com",
|
|
124
|
+
"about.gitlab.com",
|
|
125
|
+
"bitbucket.org",
|
|
126
|
+
/* 包管理 / Registry */
|
|
127
|
+
"pypi.org",
|
|
128
|
+
"packagist.org",
|
|
129
|
+
"rubygems.org",
|
|
130
|
+
"nuget.org",
|
|
131
|
+
"mvnrepository.com",
|
|
132
|
+
/* 前端 / UI */
|
|
133
|
+
"tailwindcss.com",
|
|
134
|
+
"ui.shadcn.com",
|
|
135
|
+
"radix-ui.com",
|
|
136
|
+
"mui.com",
|
|
137
|
+
"vuetifyjs.com",
|
|
138
|
+
"ant.design",
|
|
139
|
+
"element-plus.org",
|
|
140
|
+
"storybook.js.org",
|
|
141
|
+
"figma.com",
|
|
142
|
+
"developers.figma.com",
|
|
143
|
+
/* 构建工具 */
|
|
144
|
+
"vitejs.dev",
|
|
145
|
+
"webpack.js.org",
|
|
146
|
+
"rollupjs.org",
|
|
147
|
+
"esbuild.github.io",
|
|
148
|
+
"swc.rs",
|
|
149
|
+
/* 测试 */
|
|
150
|
+
"jestjs.io",
|
|
151
|
+
"vitest.dev",
|
|
152
|
+
"cypress.io",
|
|
153
|
+
"playwright.dev",
|
|
154
|
+
/* Lint / Format */
|
|
155
|
+
"eslint.org",
|
|
156
|
+
"prettier.io",
|
|
157
|
+
/* 后端框架 */
|
|
158
|
+
"expressjs.com",
|
|
159
|
+
"fastify.dev",
|
|
160
|
+
"nestjs.com",
|
|
161
|
+
"docs.djangoproject.com",
|
|
162
|
+
"flask.palletsprojects.com",
|
|
163
|
+
"fastapi.tiangolo.com",
|
|
164
|
+
"pydantic.dev",
|
|
165
|
+
"sqlalchemy.org",
|
|
166
|
+
"laravel.com",
|
|
167
|
+
"rubyonrails.org",
|
|
168
|
+
"guides.rubyonrails.org",
|
|
169
|
+
/* 通信 / 消息队列 */
|
|
170
|
+
"kafka.apache.org",
|
|
171
|
+
"rabbitmq.com",
|
|
172
|
+
"docs.confluent.io",
|
|
173
|
+
"nats.io",
|
|
174
|
+
/* 搜索 / 大数据 */
|
|
175
|
+
"elastic.co",
|
|
176
|
+
"opensearch.org",
|
|
177
|
+
"spark.apache.org",
|
|
178
|
+
/* 文档 / 社区 */
|
|
179
|
+
"stackoverflow.com",
|
|
180
|
+
"stackexchange.com",
|
|
181
|
+
"wikipedia.org",
|
|
182
|
+
"dev.to",
|
|
183
|
+
"medium.com",
|
|
184
|
+
"github.io",
|
|
185
|
+
"gitlab.io",
|
|
186
|
+
/* API / 协议 */
|
|
187
|
+
"graphql.org",
|
|
188
|
+
"json-schema.org",
|
|
189
|
+
"openapi.org",
|
|
190
|
+
"swagger.io",
|
|
191
|
+
"postman.com",
|
|
192
|
+
/* 部署 / Serverless */
|
|
193
|
+
"vercel.com",
|
|
194
|
+
"netlify.com",
|
|
195
|
+
"cloudflare.com",
|
|
196
|
+
"workers.cloudflare.com",
|
|
197
|
+
"supabase.com",
|
|
198
|
+
"docs.supabase.com",
|
|
199
|
+
/* 移动开发 */
|
|
200
|
+
"reactnative.dev",
|
|
201
|
+
"expo.dev",
|
|
202
|
+
/* 游戏引擎 */
|
|
203
|
+
"unity.com",
|
|
204
|
+
"docs.unity3d.com",
|
|
205
|
+
"unrealengine.com",
|
|
206
|
+
"godotengine.org",
|
|
207
|
+
/* 安全 / 加密 */
|
|
208
|
+
"owasp.org",
|
|
209
|
+
"letsencrypt.org",
|
|
210
|
+
/* 版本控制 */
|
|
211
|
+
"git-scm.com",
|
|
212
|
+
/* 操作系统 / 内核 */
|
|
213
|
+
"kernel.org",
|
|
214
|
+
"man7.org",
|
|
215
|
+
"freebsd.org",
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
/** 检查主机名是否为本地/IP/危险地址 */
|
|
219
|
+
export function isDangerousHost(hostname: string): boolean {
|
|
220
|
+
const h = hostname.toLowerCase();
|
|
221
|
+
if (DANGEROUS_DOMAINS.some((d) => h === d || h.endsWith(`.${d}`))) return true;
|
|
222
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(h)) return true;
|
|
223
|
+
if (h.startsWith("[") && h.endsWith("]")) return true;
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** 判断 URL 是否属于预批准域名 */
|
|
228
|
+
export function isPreapprovedDomain(url: string): boolean {
|
|
229
|
+
try {
|
|
230
|
+
const parsed = new URL(url);
|
|
231
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
232
|
+
if (isDangerousHost(hostname)) return false;
|
|
233
|
+
return PREAPPROVED_DOMAINS.some(
|
|
234
|
+
(d) => hostname === d || hostname.endsWith(`.${d}`)
|
|
235
|
+
);
|
|
236
|
+
} catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|