Initial commit: shiro-neko 0.1.0-beta.1
Agentic coding CLI on Bun, Ink, and the AI SDK. Core: streamText loop with SDK-level tool approval so a denied call provably never executes; endpoint fallback for OpenAI reasoning models; retry with backoff. Tools: read/write/edit/glob/grep/bash, path-jailed, gitignore-aware, ripgrep with a JS fallback, binary rejection, live bash streaming. Agents: five variants crossing thinking level with tool restriction; plan and review withhold mutating tools from the model. Extensibility: frontmatter skills with on-demand bodies, plugin host with blocking hooks, MCP stdio and HTTP, read-only subagents. State: durable per-project memory, session task lists, session persistence, compaction that repairs provider-item dependencies. Distribution: five-platform cross-compiled binaries with checksums, install scripts, CI on three operating systems. 404 tests, typecheck clean.
This commit is contained in:
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
const send = (o: unknown) => process.stdout.write(`${JSON.stringify(o)}\n`);
|
||||
|
||||
const TOOLS = [
|
||||
{
|
||||
name: 'ping',
|
||||
description: 'Returns pong plus whatever you send',
|
||||
inputSchema: { type: 'object', properties: { note: { type: 'string' } }, required: ['note'] },
|
||||
},
|
||||
{
|
||||
name: 'search',
|
||||
description: 'Pretends to search',
|
||||
inputSchema: { type: 'object', properties: { q: { type: 'string' } }, required: ['q'] },
|
||||
},
|
||||
];
|
||||
|
||||
const dec = new TextDecoder();
|
||||
let buf = '';
|
||||
|
||||
for await (const chunk of Bun.stdin.stream()) {
|
||||
buf += dec.decode(chunk);
|
||||
let nl: number;
|
||||
while ((nl = buf.indexOf('\n')) !== -1) {
|
||||
const line = buf.slice(0, nl).trim();
|
||||
buf = buf.slice(nl + 1);
|
||||
if (!line) continue;
|
||||
|
||||
const msg = JSON.parse(line) as { id?: number; method: string; params?: Record<string, any> };
|
||||
|
||||
if (msg.method === 'initialize') {
|
||||
send({
|
||||
jsonrpc: '2.0',
|
||||
id: msg.id,
|
||||
result: {
|
||||
protocolVersion: '2024-11-05',
|
||||
capabilities: { tools: {} },
|
||||
serverInfo: { name: 'stub-mcp', version: '0.0.1' },
|
||||
},
|
||||
});
|
||||
} else if (msg.method === 'tools/list') {
|
||||
send({ jsonrpc: '2.0', id: msg.id, result: { tools: TOOLS } });
|
||||
} else if (msg.method === 'tools/call') {
|
||||
const name = msg.params?.['name'];
|
||||
const args = msg.params?.['arguments'] ?? {};
|
||||
const text = name === 'ping' ? `pong: ${args['note']}` : `searched: ${args['q']}`;
|
||||
send({ jsonrpc: '2.0', id: msg.id, result: { content: [{ type: 'text', text }] } });
|
||||
} else if (msg.id !== undefined) {
|
||||
send({ jsonrpc: '2.0', id: msg.id, error: { code: -32601, message: `no method ${msg.method}` } });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user