@zhongqian97-code/ecode 0.5.9 → 0.5.10

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.
Files changed (2) hide show
  1. package/dist/index.js +71 -29
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ const _ew=process.emitWarning.bind(process);process.emitWarning=function(w,...a)
3
3
 
4
4
  // src/index.ts
5
5
  import { createRequire } from "module";
6
- import { resolve as resolve6, dirname as dirname8 } from "path";
7
- import { fileURLToPath } from "url";
6
+ import { resolve as resolve5, dirname as dirname9 } from "path";
7
+ import { fileURLToPath as fileURLToPath2 } from "url";
8
8
  import React4 from "react";
9
9
  import { render } from "ink";
10
10
  import { readFileSync as readFileSync5 } from "fs";
@@ -540,13 +540,13 @@ function classifyCommand(cmd, dangerPatterns, _depth = 0) {
540
540
  import { exec } from "child_process";
541
541
  var DEFAULT_TIMEOUT_MS = 3e4;
542
542
  function executeBash(cmd, timeoutMs = DEFAULT_TIMEOUT_MS) {
543
- return new Promise((resolve7) => {
543
+ return new Promise((resolve6) => {
544
544
  exec(cmd, { timeout: timeoutMs }, (err, stdout, stderr) => {
545
545
  if (err) {
546
546
  const exitCode = err.code ?? 1;
547
- resolve7({ stdout: stdout ?? "", stderr: stderr ?? "", exitCode });
547
+ resolve6({ stdout: stdout ?? "", stderr: stderr ?? "", exitCode });
548
548
  } else {
549
- resolve7({ stdout: stdout ?? "", stderr: stderr ?? "", exitCode: 0 });
549
+ resolve6({ stdout: stdout ?? "", stderr: stderr ?? "", exitCode: 0 });
550
550
  }
551
551
  });
552
552
  });
@@ -2170,7 +2170,7 @@ function parseMouseScroll(data) {
2170
2170
 
2171
2171
  // src/ui/App.tsx
2172
2172
  import { homedir as homedir3 } from "os";
2173
- import { join as join10 } from "path";
2173
+ import { join as join11 } from "path";
2174
2174
 
2175
2175
  // src/automation/store.ts
2176
2176
  import { readFile as readFile8, writeFile as writeFile5, mkdir as mkdir2 } from "fs/promises";
@@ -2268,11 +2268,17 @@ async function executeJob(job, config2) {
2268
2268
 
2269
2269
  // src/automation/goal/evaluator.ts
2270
2270
  function parseVerdict(response) {
2271
- const lower = response.toLowerCase();
2272
- if (lower.includes("not_done")) return "not_done";
2273
- if (lower.includes("blocked")) return "blocked";
2274
- if (lower.includes("done")) return "done";
2275
- return "not_done";
2271
+ const scan = (text) => {
2272
+ if (/\bnot_done\b/.test(text)) return "not_done";
2273
+ if (/\bblocked\b/.test(text) && !/\bnot\s+blocked\b/.test(text)) return "blocked";
2274
+ if (/\bdone\b/.test(text) && !/\bnot\s+done\b/.test(text)) return "done";
2275
+ return null;
2276
+ };
2277
+ const firstLine = (response.split("\n")[0] ?? "").trim().toLowerCase();
2278
+ const fromFirstLine = scan(firstLine);
2279
+ if (fromFirstLine !== null) return fromFirstLine;
2280
+ const fromFull = scan(response.toLowerCase());
2281
+ return fromFull ?? "not_done";
2276
2282
  }
2277
2283
  function buildPrompt(input) {
2278
2284
  return [
@@ -2492,6 +2498,15 @@ async function cmdLoop(args, deps) {
2492
2498
  intervalMs = parsed.intervalMs;
2493
2499
  prompt = trimmed.slice(spaceIdx + 1).trim();
2494
2500
  }
2501
+ } else {
2502
+ const parsed = parseInterval(trimmed);
2503
+ if (parsed !== null) {
2504
+ intervalMs = parsed.intervalMs;
2505
+ prompt = "";
2506
+ }
2507
+ }
2508
+ if (!prompt.trim()) {
2509
+ return "\u7528\u6CD5\uFF1A/loop [interval] <prompt>\uFF0C\u4F8B\u5982\uFF1A/loop 10m \u68C0\u67E5 deploy \u72B6\u6001";
2495
2510
  }
2496
2511
  const now = /* @__PURE__ */ new Date();
2497
2512
  const job = {
@@ -2542,6 +2557,9 @@ async function cmdUnloop(idOrPrefix, deps) {
2542
2557
  import { randomUUID as randomUUID3 } from "crypto";
2543
2558
  async function cmdGoal(args, deps) {
2544
2559
  const condition = args.trim();
2560
+ if (!condition) {
2561
+ return "\u7528\u6CD5\uFF1A/goal <\u76EE\u6807\u6761\u4EF6>\uFF0C\u4F8B\u5982\uFF1A/goal \u6240\u6709\u6D4B\u8BD5\u901A\u8FC7";
2562
+ }
2545
2563
  const now = /* @__PURE__ */ new Date();
2546
2564
  const job = {
2547
2565
  id: randomUUID3(),
@@ -2784,11 +2802,11 @@ var AutomationManager = class {
2784
2802
  job.id,
2785
2803
  `[goal ${job.id.slice(0, 8)}] \u7B2C ${job.activeTurnCount} \u8F6E\uFF1A\u5C1A\u672A\u5B8C\u6210\uFF0C\u7EE7\u7EED\u6267\u884C\u2026`
2786
2804
  );
2787
- await new Promise((resolve7) => {
2788
- const timer = setTimeout(resolve7, 5e3);
2805
+ await new Promise((resolve6) => {
2806
+ const timer = setTimeout(resolve6, 5e3);
2789
2807
  signal.addEventListener("abort", () => {
2790
2808
  clearTimeout(timer);
2791
- resolve7();
2809
+ resolve6();
2792
2810
  }, { once: true });
2793
2811
  });
2794
2812
  }
@@ -2877,6 +2895,7 @@ function generateTitle(firstUserMessage) {
2877
2895
  // src/meta_skill/index.ts
2878
2896
  import * as fs11 from "fs";
2879
2897
  import * as path9 from "path";
2898
+ import { fileURLToPath } from "url";
2880
2899
 
2881
2900
  // src/meta_skill/task-classifier.ts
2882
2901
  var RULES = {
@@ -3591,18 +3610,41 @@ import * as os from "os";
3591
3610
  var STORE_PATH = path8.resolve(os.homedir(), ".ecode", "learning-records.jsonl");
3592
3611
 
3593
3612
  // src/meta_skill/index.ts
3613
+ function resolveBuiltinSkillsDir() {
3614
+ try {
3615
+ let dir = path9.dirname(fileURLToPath(import.meta.url));
3616
+ for (let i = 0; i < 4; i++) {
3617
+ const candidate = path9.join(dir, "skills");
3618
+ if (fs11.existsSync(candidate) && fs11.statSync(candidate).isDirectory()) {
3619
+ return candidate;
3620
+ }
3621
+ const parent = path9.dirname(dir);
3622
+ if (parent === dir) break;
3623
+ dir = parent;
3624
+ }
3625
+ } catch {
3626
+ }
3627
+ return null;
3628
+ }
3594
3629
  function runMetaAlign(input) {
3595
3630
  const taskType = input.task.type && isValidTaskType(input.task.type) ? input.task.type : classifyTask(input.task.goal);
3596
3631
  const inheritedSkills = getBaselineSkills(taskType);
3632
+ const builtinSkillsDir2 = resolveBuiltinSkillsDir();
3597
3633
  const allSteps = [];
3598
3634
  for (const skillName of inheritedSkills) {
3599
- const primaryPath = path9.resolve(process.cwd(), "skills", skillName, "SKILL.md");
3600
- const fallbackPath = path9.resolve(process.cwd(), "skills", skillName + ".md");
3635
+ const candidates = [];
3636
+ if (builtinSkillsDir2) {
3637
+ candidates.push(path9.join(builtinSkillsDir2, skillName, "SKILL.md"));
3638
+ candidates.push(path9.join(builtinSkillsDir2, skillName + ".md"));
3639
+ }
3640
+ candidates.push(path9.join(process.cwd(), "skills", skillName, "SKILL.md"));
3641
+ candidates.push(path9.join(process.cwd(), "skills", skillName + ".md"));
3601
3642
  let body = "";
3602
- if (fs11.existsSync(primaryPath)) {
3603
- body = fs11.readFileSync(primaryPath, { encoding: "utf-8" });
3604
- } else if (fs11.existsSync(fallbackPath)) {
3605
- body = fs11.readFileSync(fallbackPath, { encoding: "utf-8" });
3643
+ for (const p of candidates) {
3644
+ if (fs11.existsSync(p)) {
3645
+ body = fs11.readFileSync(p, { encoding: "utf-8" });
3646
+ break;
3647
+ }
3606
3648
  }
3607
3649
  const steps = extractWorkflowSteps(body);
3608
3650
  allSteps.push(...steps);
@@ -3790,7 +3832,7 @@ function App({ config: config2, version: version2, autoMode: autoMode2 = false,
3790
3832
  const pendingConfirmRef = useRef2(null);
3791
3833
  const abortControllerRef = useRef2(null);
3792
3834
  const llmRef = useRef2(llmClient ?? createProvider(resolveActiveProfile(config2)));
3793
- const automationDataDir = config2.logDir ? join10(config2.logDir, "automation") : join10(homedir3(), ".config", "ecode", "automation");
3835
+ const automationDataDir = config2.logDir ? join11(config2.logDir, "automation") : join11(homedir3(), ".config", "ecode", "automation");
3794
3836
  const automationManagerRef = useRef2(
3795
3837
  new AutomationManager({
3796
3838
  dataDir: automationDataDir,
@@ -3996,10 +4038,10 @@ function App({ config: config2, version: version2, autoMode: autoMode2 = false,
3996
4038
  }
3997
4039
  });
3998
4040
  const confirm = useCallback((prompt) => {
3999
- return new Promise((resolve7) => {
4041
+ return new Promise((resolve6) => {
4000
4042
  setStatus("awaiting_confirm");
4001
4043
  setConfirmPrompt(prompt);
4002
- pendingConfirmRef.current = { resolve: resolve7 };
4044
+ pendingConfirmRef.current = { resolve: resolve6 };
4003
4045
  });
4004
4046
  }, []);
4005
4047
  const runLlmLoop = useCallback(
@@ -4522,13 +4564,13 @@ async function runPipe(prompt, llm, out = process.stdout, systemPrompt) {
4522
4564
  }
4523
4565
  }
4524
4566
  function readStdin() {
4525
- return new Promise((resolve7, reject) => {
4567
+ return new Promise((resolve6, reject) => {
4526
4568
  let data = "";
4527
4569
  process.stdin.setEncoding("utf-8");
4528
4570
  process.stdin.on("data", (chunk) => {
4529
4571
  data += chunk;
4530
4572
  });
4531
- process.stdin.on("end", () => resolve7(data.trim()));
4573
+ process.stdin.on("end", () => resolve6(data.trim()));
4532
4574
  process.stdin.on("error", reject);
4533
4575
  });
4534
4576
  }
@@ -4697,10 +4739,10 @@ if (replayFile) {
4697
4739
  process.exit(1);
4698
4740
  }
4699
4741
  }
4700
- var __dirname = dirname8(fileURLToPath(import.meta.url));
4701
- var builtinSkillsDir = resolve6(__dirname, "../skills");
4702
- var userSkillsDir = resolve6(process.env.HOME ?? "~", ".ecode/skills");
4703
- var projectSkillsDir = resolve6(process.cwd(), ".ecode/skills");
4742
+ var __dirname = dirname9(fileURLToPath2(import.meta.url));
4743
+ var builtinSkillsDir = resolve5(__dirname, "../skills");
4744
+ var userSkillsDir = resolve5(process.env.HOME ?? "~", ".ecode/skills");
4745
+ var projectSkillsDir = resolve5(process.cwd(), ".ecode/skills");
4704
4746
  var registry = new SkillRegistry();
4705
4747
  for (const dir of [builtinSkillsDir, userSkillsDir, projectSkillsDir]) {
4706
4748
  const skills = await loadSkillsFromDir(dir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhongqian97-code/ecode",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "A minimal Claude Code clone with REPL interface and bash tool calling",
5
5
  "type": "module",
6
6
  "author": "zhongqian97-code",