@zhongqian97-code/ecode 0.5.39 → 0.5.41
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/dist/{chunk-LAAABQR4.js → chunk-72HNTRAP.js} +4 -1
- package/dist/{chunk-C6OEWQCD.js → chunk-7RQ4D4K6.js} +1 -1
- package/dist/{chunk-3H2EMIKF.js → chunk-FPB3QTP5.js} +1 -1
- package/dist/{chunk-JG2IGHYY.js → chunk-ZPGOARYH.js} +35 -1
- package/dist/index.js +21 -7
- package/dist/{ui-FSBOFWL3.js → ui-FGG6SNSS.js} +4 -36
- package/dist/{web-L77TJPHI.js → web-YRH6C6ID.js} +16 -5
- package/package.json +1 -1
|
@@ -107,7 +107,10 @@ function loadConfig() {
|
|
|
107
107
|
systemPrompt: process.env.ECODE_SYSTEM_PROMPT ?? fileConfig.systemPrompt,
|
|
108
108
|
// providers/defaultProvider 仅支持配置文件配置,不支持环境变量注入
|
|
109
109
|
providers: fileConfig.providers,
|
|
110
|
-
defaultProvider: fileConfig.defaultProvider
|
|
110
|
+
defaultProvider: fileConfig.defaultProvider,
|
|
111
|
+
// ECODE_WEB_TOKEN 环境变量优先;未设时从配置文件读取;
|
|
112
|
+
// 两者均未设时保持 undefined,运行时由 generateAccessToken() 生成随机令牌
|
|
113
|
+
webToken: process.env.ECODE_WEB_TOKEN ?? fileConfig.webToken
|
|
111
114
|
};
|
|
112
115
|
}
|
|
113
116
|
function saveConfig(partial) {
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const _ew=process.emitWarning.bind(process);process.emitWarning=function(w,...a){if((w?.message??w)?.includes?.('punycode'))return;_ew(w,...a);};
|
|
3
3
|
|
|
4
|
+
// src/skills/resolver.ts
|
|
5
|
+
function isSkillCommand(input) {
|
|
6
|
+
return input.length > 1 && input.startsWith("/");
|
|
7
|
+
}
|
|
8
|
+
function parseSkillCommand(input) {
|
|
9
|
+
const withoutSlash = input.slice(1);
|
|
10
|
+
const spaceIndex = withoutSlash.search(/\s/);
|
|
11
|
+
if (spaceIndex === -1) {
|
|
12
|
+
return { name: withoutSlash, args: "" };
|
|
13
|
+
}
|
|
14
|
+
const name = withoutSlash.slice(0, spaceIndex);
|
|
15
|
+
const args = withoutSlash.slice(spaceIndex).trim();
|
|
16
|
+
return { name, args };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/skills/handler.ts
|
|
20
|
+
function handleSkillInput(input, registry) {
|
|
21
|
+
if (!isSkillCommand(input)) return { type: "passthrough" };
|
|
22
|
+
const { name, args } = parseSkillCommand(input);
|
|
23
|
+
const skill = registry.find(name);
|
|
24
|
+
if (!skill) {
|
|
25
|
+
const available = registry.list().map((s) => s.name).join(", ") || "none";
|
|
26
|
+
return {
|
|
27
|
+
type: "error",
|
|
28
|
+
message: `Unknown skill: /${name}. Available: ${available}`
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const content = args ? `${skill.body}
|
|
32
|
+
|
|
33
|
+
${args}` : skill.body;
|
|
34
|
+
return { type: "skill", message: { role: "user", content }, skill };
|
|
35
|
+
}
|
|
36
|
+
|
|
4
37
|
// src/automation/store.ts
|
|
5
38
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
6
39
|
import { join } from "path";
|
|
@@ -42,5 +75,6 @@ async function removeJob(dataDir, id) {
|
|
|
42
75
|
export {
|
|
43
76
|
loadJobs,
|
|
44
77
|
upsertJob,
|
|
45
|
-
removeJob
|
|
78
|
+
removeJob,
|
|
79
|
+
handleSkillInput
|
|
46
80
|
};
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
cmdSessionsInspect,
|
|
6
6
|
cmdSessionsList,
|
|
7
7
|
cmdSessionsReplay
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FPB3QTP5.js";
|
|
9
9
|
import {
|
|
10
10
|
APPLY_PATCH_TOOL,
|
|
11
11
|
BASH_TOOL,
|
|
@@ -34,14 +34,14 @@ import {
|
|
|
34
34
|
todo,
|
|
35
35
|
webFetch,
|
|
36
36
|
writeFile
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-7RQ4D4K6.js";
|
|
38
38
|
import {
|
|
39
39
|
createSessionMetadata,
|
|
40
40
|
generateTitle,
|
|
41
41
|
loadConfig,
|
|
42
42
|
updateSessionMetadata,
|
|
43
43
|
writeSessionMetadata
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-72HNTRAP.js";
|
|
45
45
|
|
|
46
46
|
// src/index.ts
|
|
47
47
|
import { createRequire } from "module";
|
|
@@ -810,15 +810,26 @@ if (rawArgs[0] === "web") {
|
|
|
810
810
|
webAutoApprove = true;
|
|
811
811
|
}
|
|
812
812
|
}
|
|
813
|
-
const { buildServer, generateAccessToken } = await import("./web-
|
|
814
|
-
const token = generateAccessToken();
|
|
813
|
+
const { buildServer, generateAccessToken } = await import("./web-YRH6C6ID.js");
|
|
814
|
+
const token = finalConfig.webToken ?? generateAccessToken();
|
|
815
815
|
const manager = new SessionManager(finalConfig);
|
|
816
|
+
const __webDirname = dirname(fileURLToPath(import.meta.url));
|
|
817
|
+
const webRegistry = new SkillRegistry();
|
|
818
|
+
for (const dir of [
|
|
819
|
+
resolve(__webDirname, "../skills"),
|
|
820
|
+
resolve(process.env.HOME ?? "~", ".ecode/skills"),
|
|
821
|
+
resolve(process.cwd(), ".ecode/skills")
|
|
822
|
+
]) {
|
|
823
|
+
const skills = await loadSkillsFromDir(dir);
|
|
824
|
+
for (const skill of skills) webRegistry.register(skill);
|
|
825
|
+
}
|
|
816
826
|
const server = await buildServer({
|
|
817
827
|
config: finalConfig,
|
|
818
828
|
manager,
|
|
819
829
|
token,
|
|
820
830
|
version: VERSION,
|
|
821
|
-
autoApprove: webAutoApprove
|
|
831
|
+
autoApprove: webAutoApprove,
|
|
832
|
+
registry: webRegistry
|
|
822
833
|
});
|
|
823
834
|
await server.listen({ port: webPort, host: webHost });
|
|
824
835
|
const browserHost = webHost === "0.0.0.0" ? "localhost" : webHost;
|
|
@@ -827,6 +838,9 @@ if (rawArgs[0] === "web") {
|
|
|
827
838
|
ecode web admin started`);
|
|
828
839
|
console.log(` Bind: ${webHost}:${webPort}`);
|
|
829
840
|
console.log(` URL: ${accessUrl}`);
|
|
841
|
+
if (finalConfig.webToken) {
|
|
842
|
+
console.log(` Token: fixed (from config)`);
|
|
843
|
+
}
|
|
830
844
|
console.log(`
|
|
831
845
|
Press Ctrl+C to stop.
|
|
832
846
|
`);
|
|
@@ -905,6 +919,6 @@ Node.js 16/18 \u8BF7\u4F7F\u7528 --web \u6216 --pipe \u6A21\u5F0F\u3002
|
|
|
905
919
|
);
|
|
906
920
|
process.exit(1);
|
|
907
921
|
}
|
|
908
|
-
const { App, React, render } = await import("./ui-
|
|
922
|
+
const { App, React, render } = await import("./ui-FGG6SNSS.js");
|
|
909
923
|
render(React.createElement(App, { config: finalConfig, version: VERSION, autoMode, registry, trustedSkillDirs, initialMessages }));
|
|
910
924
|
}
|
|
@@ -26,19 +26,20 @@ import {
|
|
|
26
26
|
todo,
|
|
27
27
|
webFetch,
|
|
28
28
|
writeFile
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7RQ4D4K6.js";
|
|
30
30
|
import {
|
|
31
|
+
handleSkillInput,
|
|
31
32
|
loadJobs,
|
|
32
33
|
removeJob,
|
|
33
34
|
upsertJob
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-ZPGOARYH.js";
|
|
35
36
|
import {
|
|
36
37
|
createSessionMetadata,
|
|
37
38
|
generateTitle,
|
|
38
39
|
getContextLimit,
|
|
39
40
|
updateSessionMetadata,
|
|
40
41
|
writeSessionMetadata
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-72HNTRAP.js";
|
|
42
43
|
|
|
43
44
|
// src/ui/index.ts
|
|
44
45
|
import { default as default2 } from "react";
|
|
@@ -48,39 +49,6 @@ import { render } from "ink";
|
|
|
48
49
|
import { useState as useState3, useCallback, useRef as useRef2, useEffect as useEffect3, useMemo } from "react";
|
|
49
50
|
import { Box as Box6, useInput as useInput2, useStdout, useStdin } from "ink";
|
|
50
51
|
|
|
51
|
-
// src/skills/resolver.ts
|
|
52
|
-
function isSkillCommand(input) {
|
|
53
|
-
return input.length > 1 && input.startsWith("/");
|
|
54
|
-
}
|
|
55
|
-
function parseSkillCommand(input) {
|
|
56
|
-
const withoutSlash = input.slice(1);
|
|
57
|
-
const spaceIndex = withoutSlash.search(/\s/);
|
|
58
|
-
if (spaceIndex === -1) {
|
|
59
|
-
return { name: withoutSlash, args: "" };
|
|
60
|
-
}
|
|
61
|
-
const name = withoutSlash.slice(0, spaceIndex);
|
|
62
|
-
const args = withoutSlash.slice(spaceIndex).trim();
|
|
63
|
-
return { name, args };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/skills/handler.ts
|
|
67
|
-
function handleSkillInput(input, registry) {
|
|
68
|
-
if (!isSkillCommand(input)) return { type: "passthrough" };
|
|
69
|
-
const { name, args } = parseSkillCommand(input);
|
|
70
|
-
const skill = registry.find(name);
|
|
71
|
-
if (!skill) {
|
|
72
|
-
const available = registry.list().map((s) => s.name).join(", ") || "none";
|
|
73
|
-
return {
|
|
74
|
-
type: "error",
|
|
75
|
-
message: `Unknown skill: /${name}. Available: ${available}`
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
const content = args ? `${skill.body}
|
|
79
|
-
|
|
80
|
-
${args}` : skill.body;
|
|
81
|
-
return { type: "skill", message: { role: "user", content }, skill };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
52
|
// src/skills/executor.ts
|
|
85
53
|
import { exec } from "child_process";
|
|
86
54
|
import { dirname } from "path";
|
|
@@ -3,19 +3,20 @@ const _ew=process.emitWarning.bind(process);process.emitWarning=function(w,...a)
|
|
|
3
3
|
import {
|
|
4
4
|
cmdSessionsFork,
|
|
5
5
|
cmdSessionsReplay
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FPB3QTP5.js";
|
|
7
7
|
import {
|
|
8
|
+
handleSkillInput,
|
|
8
9
|
loadJobs,
|
|
9
10
|
removeJob,
|
|
10
11
|
upsertJob
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ZPGOARYH.js";
|
|
12
13
|
import {
|
|
13
14
|
deleteSessionFiles,
|
|
14
15
|
findSession,
|
|
15
16
|
listSessions,
|
|
16
17
|
loadMessagesFromJsonl,
|
|
17
18
|
saveConfig
|
|
18
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-72HNTRAP.js";
|
|
19
20
|
|
|
20
21
|
// src/web/server.ts
|
|
21
22
|
import Fastify from "fastify";
|
|
@@ -1630,7 +1631,17 @@ async function chatRoutes(app, opts) {
|
|
|
1630
1631
|
if (BUSY_STATUSES.has(session.status)) {
|
|
1631
1632
|
return reply.code(409).send({ success: false, error: `Session is busy: ${session.status}` });
|
|
1632
1633
|
}
|
|
1633
|
-
|
|
1634
|
+
let messageToSubmit = body.message;
|
|
1635
|
+
if (opts.registry) {
|
|
1636
|
+
const result = handleSkillInput(body.message, opts.registry);
|
|
1637
|
+
if (result.type === "error") {
|
|
1638
|
+
return reply.code(400).send({ success: false, error: result.message });
|
|
1639
|
+
}
|
|
1640
|
+
if (result.type === "skill") {
|
|
1641
|
+
messageToSubmit = result.message.content ?? body.message;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
session.submit(messageToSubmit).catch((err) => {
|
|
1634
1645
|
app.log.error({ err, sessionId: id }, "submit \u610F\u5916\u5931\u8D25");
|
|
1635
1646
|
});
|
|
1636
1647
|
return reply.code(202).send({ success: true, queued: true });
|
|
@@ -1867,7 +1878,7 @@ async function buildServer(opts) {
|
|
|
1867
1878
|
await app.register(sessionsRoutes, { config: opts.config, manager: opts.manager });
|
|
1868
1879
|
await app.register(configRoutes, { config: opts.config, save: saveConfig });
|
|
1869
1880
|
await app.register(automationRoutes, { config: opts.config });
|
|
1870
|
-
await app.register(chatRoutes, { config: opts.config, manager: opts.manager, autoApprove: opts.autoApprove });
|
|
1881
|
+
await app.register(chatRoutes, { config: opts.config, manager: opts.manager, autoApprove: opts.autoApprove, registry: opts.registry });
|
|
1871
1882
|
await app.register(systemRoutes, { version: opts.version });
|
|
1872
1883
|
await app.register(skillsRoutes);
|
|
1873
1884
|
await app.register(sessionHubRoutes, { manager: opts.manager });
|