@zhongqian97-code/ecode 0.5.40 → 0.5.42

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.
@@ -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
@@ -372,10 +372,11 @@ var SessionRuntime = class {
372
372
  const signal = this.abortController.signal;
373
373
  try {
374
374
  await this.runAgenticLoop(signal);
375
- } catch {
375
+ } catch (err) {
376
376
  if (!signal.aborted) {
377
377
  this._status = "error";
378
- this.bus.emit({ type: "session.error", sessionId: this.id, error: "Unexpected error in agentic loop" });
378
+ const errorMsg = err instanceof Error ? err.message : String(err);
379
+ this.bus.emit({ type: "session.error", sessionId: this.id, error: errorMsg });
379
380
  }
380
381
  return;
381
382
  } finally {
@@ -429,7 +430,7 @@ var SessionRuntime = class {
429
430
  this.bus.emit({ type: "message.delta", messageId, text: chunk.text });
430
431
  assistantText += chunk.text;
431
432
  }
432
- if (chunk.reasoning) {
433
+ if (chunk.reasoning && !chunk.done) {
433
434
  this.bus.emit({ type: "message.reasoning", messageId, text: chunk.reasoning });
434
435
  }
435
436
  if (chunk.done) {
@@ -810,15 +811,26 @@ if (rawArgs[0] === "web") {
810
811
  webAutoApprove = true;
811
812
  }
812
813
  }
813
- const { buildServer, generateAccessToken } = await import("./web-JLLCAFXF.js");
814
+ const { buildServer, generateAccessToken } = await import("./web-YRH6C6ID.js");
814
815
  const token = finalConfig.webToken ?? generateAccessToken();
815
816
  const manager = new SessionManager(finalConfig);
817
+ const __webDirname = dirname(fileURLToPath(import.meta.url));
818
+ const webRegistry = new SkillRegistry();
819
+ for (const dir of [
820
+ resolve(__webDirname, "../skills"),
821
+ resolve(process.env.HOME ?? "~", ".ecode/skills"),
822
+ resolve(process.cwd(), ".ecode/skills")
823
+ ]) {
824
+ const skills = await loadSkillsFromDir(dir);
825
+ for (const skill of skills) webRegistry.register(skill);
826
+ }
816
827
  const server = await buildServer({
817
828
  config: finalConfig,
818
829
  manager,
819
830
  token,
820
831
  version: VERSION,
821
- autoApprove: webAutoApprove
832
+ autoApprove: webAutoApprove,
833
+ registry: webRegistry
822
834
  });
823
835
  await server.listen({ port: webPort, host: webHost });
824
836
  const browserHost = webHost === "0.0.0.0" ? "localhost" : webHost;
@@ -908,6 +920,6 @@ Node.js 16/18 \u8BF7\u4F7F\u7528 --web \u6216 --pipe \u6A21\u5F0F\u3002
908
920
  );
909
921
  process.exit(1);
910
922
  }
911
- const { App, React, render } = await import("./ui-3AW6W2SI.js");
923
+ const { App, React, render } = await import("./ui-FGG6SNSS.js");
912
924
  render(React.createElement(App, { config: finalConfig, version: VERSION, autoMode, registry, trustedSkillDirs, initialMessages }));
913
925
  }
@@ -28,10 +28,11 @@ import {
28
28
  writeFile
29
29
  } from "./chunk-7RQ4D4K6.js";
30
30
  import {
31
+ handleSkillInput,
31
32
  loadJobs,
32
33
  removeJob,
33
34
  upsertJob
34
- } from "./chunk-JG2IGHYY.js";
35
+ } from "./chunk-ZPGOARYH.js";
35
36
  import {
36
37
  createSessionMetadata,
37
38
  generateTitle,
@@ -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";
@@ -5,10 +5,11 @@ import {
5
5
  cmdSessionsReplay
6
6
  } from "./chunk-FPB3QTP5.js";
7
7
  import {
8
+ handleSkillInput,
8
9
  loadJobs,
9
10
  removeJob,
10
11
  upsertJob
11
- } from "./chunk-JG2IGHYY.js";
12
+ } from "./chunk-ZPGOARYH.js";
12
13
  import {
13
14
  deleteSessionFiles,
14
15
  findSession,
@@ -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
- session.submit(body.message).catch((err) => {
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 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhongqian97-code/ecode",
3
- "version": "0.5.40",
3
+ "version": "0.5.42",
4
4
  "description": "A minimal Claude Code clone with REPL interface and bash tool calling",
5
5
  "type": "module",
6
6
  "author": "zhongqian97-code",