@minko-ai/minko 0.1.0 → 0.1.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.
- package/README.md +577 -2
- package/assets/mascot-preview.png +0 -0
- package/assets/mascot-preview.txt +46 -0
- package/assets/mascot-source.png +0 -0
- package/assets/skills/README.md +21 -0
- package/assets/skills/brainstorming/LICENSE +21 -0
- package/assets/skills/brainstorming/SKILL.md +316 -0
- package/assets/skills/buddhist-method/LICENSE +21 -0
- package/assets/skills/buddhist-method/SKILL.md +137 -0
- package/assets/skills/buddhist-method/references/ariyasacca-debug.md +57 -0
- package/assets/skills/buddhist-method/references/extended-principles.md +100 -0
- package/assets/skills/code-humanizer/LICENSE +21 -0
- package/assets/skills/code-humanizer/SKILL.md +174 -0
- package/assets/skills/code-review/LICENSE +21 -0
- package/assets/skills/code-review/SKILL.md +232 -0
- package/assets/skills/code-review/reference/angular.md +768 -0
- package/assets/skills/code-review/reference/architecture-review-guide.md +472 -0
- package/assets/skills/code-review/reference/c.md +890 -0
- package/assets/skills/code-review/reference/code-quality-universal.md +488 -0
- package/assets/skills/code-review/reference/code-review-best-practices.md +136 -0
- package/assets/skills/code-review/reference/common-bugs-checklist.md +302 -0
- package/assets/skills/code-review/reference/cpp.md +893 -0
- package/assets/skills/code-review/reference/cross-cutting/async-concurrency-patterns.md +515 -0
- package/assets/skills/code-review/reference/cross-cutting/error-handling-principles.md +492 -0
- package/assets/skills/code-review/reference/cross-cutting/n-plus-one-queries.md +309 -0
- package/assets/skills/code-review/reference/cross-cutting/sql-injection-prevention.md +308 -0
- package/assets/skills/code-review/reference/cross-cutting/xss-prevention.md +264 -0
- package/assets/skills/code-review/reference/csharp.md +525 -0
- package/assets/skills/code-review/reference/css-less-sass.md +661 -0
- package/assets/skills/code-review/reference/dart.md +670 -0
- package/assets/skills/code-review/reference/django.md +985 -0
- package/assets/skills/code-review/reference/fastapi.md +580 -0
- package/assets/skills/code-review/reference/go.md +993 -0
- package/assets/skills/code-review/reference/java.md +409 -0
- package/assets/skills/code-review/reference/java8.md +586 -0
- package/assets/skills/code-review/reference/kotlin.md +1018 -0
- package/assets/skills/code-review/reference/nestjs.md +593 -0
- package/assets/skills/code-review/reference/performance-review-guide.md +816 -0
- package/assets/skills/code-review/reference/php.md +684 -0
- package/assets/skills/code-review/reference/python.md +1073 -0
- package/assets/skills/code-review/reference/qt.md +757 -0
- package/assets/skills/code-review/reference/react.md +871 -0
- package/assets/skills/code-review/reference/ruby.md +964 -0
- package/assets/skills/code-review/reference/rust.md +846 -0
- package/assets/skills/code-review/reference/security-review-guide.md +494 -0
- package/assets/skills/code-review/reference/svelte.md +1064 -0
- package/assets/skills/code-review/reference/swift.md +936 -0
- package/assets/skills/code-review/reference/typescript.md +1016 -0
- package/assets/skills/code-review/reference/vue.md +924 -0
- package/assets/skills/code-review/reference/zig.md +440 -0
- package/assets/skills/cyclomatic-complexity/LICENSE +201 -0
- package/assets/skills/cyclomatic-complexity/SKILL.md +69 -0
- package/assets/skills/five-whys/LICENSE +21 -0
- package/assets/skills/five-whys/SKILL.md +247 -0
- package/assets/skills/five-whys/examples/performance-regression.md +161 -0
- package/assets/skills/five-whys/examples/production-incident.md +134 -0
- package/assets/skills/five-whys/references/software-patterns.md +284 -0
- package/assets/skills/five-whys/references/toyota-origins.md +257 -0
- package/assets/skills/systematic-debugging/LICENSE +21 -0
- package/assets/skills/systematic-debugging/SKILL.md +283 -0
- package/assets/skills/test-driven-development/LICENSE +21 -0
- package/assets/skills/test-driven-development/SKILL.md +330 -0
- package/assets/skills/verification-before-completion/LICENSE +21 -0
- package/assets/skills/verification-before-completion/SKILL.md +120 -0
- package/assets/skills/vibe-sec/LICENSE +201 -0
- package/assets/skills/vibe-sec/SKILL.md +758 -0
- package/assets/skills/writing-plans/LICENSE +21 -0
- package/assets/skills/writing-plans/SKILL.md +204 -0
- package/bin/minko.js +2 -2
- package/dist/agent/approvalTokens.js +224 -0
- package/dist/agent/branchLock.js +315 -0
- package/dist/agent/compact.js +182 -0
- package/dist/agent/context.js +183 -0
- package/dist/agent/cron.js +326 -0
- package/dist/agent/hooks.js +211 -0
- package/dist/agent/lanes.js +511 -0
- package/dist/agent/loop.js +337 -0
- package/dist/agent/memory.js +159 -0
- package/dist/agent/permissions.js +71 -0
- package/dist/agent/plan.js +118 -0
- package/dist/agent/prompt.js +120 -0
- package/dist/agent/subagent.js +67 -0
- package/dist/agent/tasks.js +449 -0
- package/dist/agent/transcript.js +62 -0
- package/dist/agent/workerStore.js +172 -0
- package/dist/agent/workerTypes.js +1 -0
- package/dist/agent/workers.js +503 -0
- package/dist/cli/app.js +261 -0
- package/dist/cli/argv.js +206 -0
- package/dist/cli/commandsCommand.js +12 -0
- package/dist/cli/configCommand.js +170 -0
- package/dist/cli/doctorCommand.js +112 -0
- package/dist/cli/exportCommand.js +85 -0
- package/dist/cli/forkCommand.js +24 -0
- package/dist/cli/linkCommand.js +272 -0
- package/dist/cli/loginCommand.js +69 -0
- package/dist/cli/mcpLoginCommand.js +68 -0
- package/dist/cli/pluginCommand.js +113 -0
- package/dist/cli/powerCommand.js +174 -0
- package/dist/cli/promptFooter.js +74 -0
- package/dist/cli/relayCommand.js +38 -0
- package/dist/cli/sandboxCommand.js +31 -0
- package/dist/cli/serveCommand.js +104 -0
- package/dist/cli/statusCommand.js +120 -0
- package/dist/cli/tui.js +1104 -0
- package/dist/commands/registry.js +99 -0
- package/dist/config/paths.js +81 -0
- package/dist/config/store.js +605 -0
- package/dist/index.js +199 -0
- package/dist/link/protocol.js +159 -0
- package/dist/link/relay.js +184 -0
- package/dist/link/server.js +566 -0
- package/dist/link/tunnel.js +90 -0
- package/dist/lsp/client.js +340 -0
- package/dist/lsp/tool.js +177 -0
- package/dist/mcp/client.js +469 -0
- package/dist/mcp/httpClient.js +191 -0
- package/dist/mcp/server.js +206 -0
- package/dist/mcp/tools.js +173 -0
- package/dist/oauth/device.js +111 -0
- package/dist/oauth/store.js +56 -0
- package/dist/plugins/loader.js +291 -0
- package/dist/plugins/market.js +98 -0
- package/dist/providers/anthropic.js +279 -0
- package/dist/providers/factory.js +109 -0
- package/dist/providers/openai.js +182 -0
- package/dist/providers/retry.js +95 -0
- package/dist/providers/sse.js +67 -0
- package/dist/providers/types.js +10 -0
- package/dist/rag/embeddings.js +171 -0
- package/dist/rag/index.js +373 -0
- package/dist/rag/server.js +167 -0
- package/dist/rag/tool.js +148 -0
- package/dist/sandbox/index.js +55 -0
- package/dist/sdk/server.js +150 -0
- package/dist/sdk/session.js +104 -0
- package/dist/session/liveness.js +148 -0
- package/dist/session/recorder.js +49 -0
- package/dist/session/store.js +171 -0
- package/dist/skills/index.js +428 -0
- package/dist/theme.js +30 -0
- package/dist/tools/fs.js +195 -0
- package/dist/tools/notebook.js +109 -0
- package/dist/tools/registry.js +32 -0
- package/dist/tools/search.js +130 -0
- package/dist/tools/shell.js +200 -0
- package/dist/tools/structured.js +83 -0
- package/dist/tools/types.js +1 -0
- package/dist/ui/ansi.js +135 -0
- package/dist/ui/banner.js +103 -0
- package/dist/ui/input.js +49 -0
- package/dist/ui/inputModel.js +113 -0
- package/dist/ui/keyboard.js +142 -0
- package/dist/ui/mascot.js +34 -0
- package/dist/ui/mascotData.js +96 -0
- package/dist/ui/md.js +183 -0
- package/dist/ui/screen.js +49 -0
- package/dist/ui/spinner.js +52 -0
- package/dist/ui/transcript.js +287 -0
- package/dist/util/clipboard.js +53 -0
- package/dist/util/errors.js +50 -0
- package/dist/util/version.js +12 -0
- package/dist/web/fetch.js +168 -0
- package/dist/web/search.js +97 -0
- package/package.json +45 -36
- package/src/agent/loop.ts +0 -159
- package/src/agent/prompt.ts +0 -45
- package/src/cli/app.ts +0 -396
- package/src/cli/argv.ts +0 -139
- package/src/cli/configCommand.ts +0 -175
- package/src/config/paths.ts +0 -20
- package/src/config/store.ts +0 -149
- package/src/index.ts +0 -120
- package/src/providers/anthropic.ts +0 -215
- package/src/providers/openai.ts +0 -158
- package/src/providers/sse.ts +0 -57
- package/src/providers/types.ts +0 -59
- package/src/session/store.ts +0 -125
- package/src/theme.ts +0 -41
- package/src/tools/fs.ts +0 -143
- package/src/tools/registry.ts +0 -19
- package/src/tools/shell.ts +0 -120
- package/src/tools/types.ts +0 -26
- package/src/ui/ansi.ts +0 -110
- package/src/ui/banner.ts +0 -39
- package/src/ui/input.ts +0 -54
- package/src/ui/md.ts +0 -160
- package/src/ui/spinner.ts +0 -58
- package/src/util/errors.ts +0 -48
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const INTERRUPTED_TOOL_RESULT = '工具没有执行:本轮被中断或者没有返回结果。';
|
|
2
|
+
/**
|
|
3
|
+
* Every assistant tool call must be followed by a tool result. Providers
|
|
4
|
+
* reject a resumed transcript that contains an orphaned tool call.
|
|
5
|
+
*/
|
|
6
|
+
export function transcriptProblems(messages) {
|
|
7
|
+
const problems = [];
|
|
8
|
+
let pending = [];
|
|
9
|
+
const flush = () => {
|
|
10
|
+
for (const call of pending) {
|
|
11
|
+
problems.push('tool call ' + call.id + ' (' + call.name + ') 没有 tool_result');
|
|
12
|
+
}
|
|
13
|
+
pending = [];
|
|
14
|
+
};
|
|
15
|
+
for (const message of messages) {
|
|
16
|
+
if (message.role === 'assistant') {
|
|
17
|
+
flush();
|
|
18
|
+
pending = message.toolCalls.slice();
|
|
19
|
+
}
|
|
20
|
+
else if (message.role === 'tool') {
|
|
21
|
+
pending = pending.filter((call) => call.id !== message.toolCallId);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
flush();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
flush();
|
|
28
|
+
return problems;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fills unanswered tool calls with an explicit error result so the transcript
|
|
32
|
+
* stays valid across interrupts and resumed sessions.
|
|
33
|
+
*/
|
|
34
|
+
export function repairTranscript(messages, reason = INTERRUPTED_TOOL_RESULT) {
|
|
35
|
+
const out = [];
|
|
36
|
+
let pending = [];
|
|
37
|
+
let added = 0;
|
|
38
|
+
const flush = () => {
|
|
39
|
+
for (const call of pending) {
|
|
40
|
+
out.push({ role: 'tool', toolCallId: call.id, name: call.name, content: reason });
|
|
41
|
+
added += 1;
|
|
42
|
+
}
|
|
43
|
+
pending = [];
|
|
44
|
+
};
|
|
45
|
+
for (const message of messages) {
|
|
46
|
+
if (message.role === 'assistant') {
|
|
47
|
+
flush();
|
|
48
|
+
out.push(message);
|
|
49
|
+
pending = message.toolCalls.slice();
|
|
50
|
+
}
|
|
51
|
+
else if (message.role === 'tool') {
|
|
52
|
+
out.push(message);
|
|
53
|
+
pending = pending.filter((call) => call.id !== message.toolCallId);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
flush();
|
|
57
|
+
out.push(message);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
flush();
|
|
61
|
+
return { messages: out, added };
|
|
62
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { minkoHome } from "../config/paths.js";
|
|
4
|
+
import { repairTranscript } from "./transcript.js";
|
|
5
|
+
const STATES = ['queued', 'running', 'done', 'failed', 'stopped'];
|
|
6
|
+
/** Durable worker records and transcripts under ~/.minko/workers. */
|
|
7
|
+
export class WorkerStore {
|
|
8
|
+
dir;
|
|
9
|
+
constructor(dir = path.join(minkoHome(), 'workers')) {
|
|
10
|
+
this.dir = dir;
|
|
11
|
+
}
|
|
12
|
+
save(info, pid = process.pid) {
|
|
13
|
+
try {
|
|
14
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
15
|
+
const record = {
|
|
16
|
+
...info,
|
|
17
|
+
pid,
|
|
18
|
+
updatedAt: new Date().toISOString(),
|
|
19
|
+
};
|
|
20
|
+
const file = this.metaFile(info.id);
|
|
21
|
+
const payload = JSON.stringify(record, null, 2);
|
|
22
|
+
const temporary = file + '.tmp';
|
|
23
|
+
fs.writeFileSync(temporary, payload, 'utf8');
|
|
24
|
+
try {
|
|
25
|
+
fs.renameSync(temporary, file);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
fs.writeFileSync(file, payload, 'utf8');
|
|
29
|
+
try {
|
|
30
|
+
fs.unlinkSync(temporary);
|
|
31
|
+
}
|
|
32
|
+
catch { /* best effort */ }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Persistence is advisory; the worker keeps running.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
appendMessage(id, message) {
|
|
40
|
+
try {
|
|
41
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
42
|
+
fs.appendFileSync(this.messagesFile(id), JSON.stringify(message) + '\n', 'utf8');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Ignore transcript write failures.
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
loadMessages(id) {
|
|
49
|
+
try {
|
|
50
|
+
const lines = fs.readFileSync(this.messagesFile(id), 'utf8').split('\n');
|
|
51
|
+
const messages = [];
|
|
52
|
+
for (const line of lines) {
|
|
53
|
+
if (line.trim().length === 0) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(line);
|
|
58
|
+
if (parsed && typeof parsed === 'object' && typeof parsed.role === 'string') {
|
|
59
|
+
messages.push(parsed);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Skip a torn line.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return repairTranscript(messages).messages;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
list() {
|
|
73
|
+
let names;
|
|
74
|
+
try {
|
|
75
|
+
names = fs.readdirSync(this.dir);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const workers = [];
|
|
81
|
+
for (const name of names) {
|
|
82
|
+
if (!name.endsWith('.json') || name.endsWith('.messages.jsonl')) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const id = name.slice(0, -'.json'.length);
|
|
86
|
+
if (!/^[A-Za-z0-9._-]+$/.test(id)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const raw = JSON.parse(fs.readFileSync(path.join(this.dir, name), 'utf8'));
|
|
91
|
+
const record = parseRecord(id, raw);
|
|
92
|
+
if (record) {
|
|
93
|
+
workers.push(record);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Skip a corrupt record.
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
workers.sort((a, b) => (b.updatedAt ?? '').localeCompare(a.updatedAt ?? ''));
|
|
101
|
+
return workers;
|
|
102
|
+
}
|
|
103
|
+
get(id) {
|
|
104
|
+
const worker = this.list().find((entry) => entry.id === id);
|
|
105
|
+
if (!worker) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
return { worker, messages: this.loadMessages(id) };
|
|
109
|
+
}
|
|
110
|
+
/** Marks workers from previous processes as stopped. */
|
|
111
|
+
markStale() {
|
|
112
|
+
for (const worker of this.list()) {
|
|
113
|
+
if ((worker.state === 'running' || worker.state === 'queued')
|
|
114
|
+
&& worker.pid !== undefined && worker.pid !== process.pid) {
|
|
115
|
+
this.save({
|
|
116
|
+
...worker,
|
|
117
|
+
state: 'stopped',
|
|
118
|
+
error: '进程已退出(持久化恢复)',
|
|
119
|
+
endedAt: worker.endedAt ?? new Date().toISOString(),
|
|
120
|
+
}, process.pid);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
remove(id) {
|
|
125
|
+
let removed = false;
|
|
126
|
+
try {
|
|
127
|
+
fs.unlinkSync(this.metaFile(id));
|
|
128
|
+
removed = true;
|
|
129
|
+
}
|
|
130
|
+
catch { /* missing */ }
|
|
131
|
+
try {
|
|
132
|
+
fs.unlinkSync(this.messagesFile(id));
|
|
133
|
+
}
|
|
134
|
+
catch { /* missing */ }
|
|
135
|
+
return removed;
|
|
136
|
+
}
|
|
137
|
+
metaFile(id) {
|
|
138
|
+
return path.join(this.dir, safeId(id) + '.json');
|
|
139
|
+
}
|
|
140
|
+
messagesFile(id) {
|
|
141
|
+
return path.join(this.dir, safeId(id) + '.messages.jsonl');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function parseRecord(id, raw) {
|
|
145
|
+
if (typeof raw.name !== 'string' || typeof raw.prompt !== 'string'
|
|
146
|
+
|| typeof raw.createdAt !== 'string' || typeof raw.allowWrite !== 'boolean'
|
|
147
|
+
|| typeof raw.state !== 'string' || !STATES.includes(raw.state)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
id,
|
|
152
|
+
name: raw.name,
|
|
153
|
+
prompt: raw.prompt,
|
|
154
|
+
team: typeof raw.team === 'string' ? raw.team : undefined,
|
|
155
|
+
cwd: typeof raw.cwd === 'string' ? raw.cwd : undefined,
|
|
156
|
+
allowWrite: raw.allowWrite,
|
|
157
|
+
state: raw.state,
|
|
158
|
+
result: typeof raw.result === 'string' ? raw.result : undefined,
|
|
159
|
+
error: typeof raw.error === 'string' ? raw.error : undefined,
|
|
160
|
+
createdAt: raw.createdAt,
|
|
161
|
+
startedAt: typeof raw.startedAt === 'string' ? raw.startedAt : undefined,
|
|
162
|
+
endedAt: typeof raw.endedAt === 'string' ? raw.endedAt : undefined,
|
|
163
|
+
pid: typeof raw.pid === 'number' ? raw.pid : undefined,
|
|
164
|
+
updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : undefined,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function safeId(id) {
|
|
168
|
+
if (!/^[A-Za-z0-9._-]+$/.test(id)) {
|
|
169
|
+
throw new Error('非法的 worker id');
|
|
170
|
+
}
|
|
171
|
+
return id;
|
|
172
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|