@lawrenceliang-btc/atel-sdk 1.1.33 → 1.1.35

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/bin/atel.mjs CHANGED
@@ -2067,35 +2067,64 @@ async function cmdInit(agentId) {
2067
2067
 
2068
2068
  // Auto-install SKILL.md to OpenClaw skills directory
2069
2069
  try {
2070
- const sdkSkillPath = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'skill', 'atel-agent', 'SKILL.md');
2071
- if (existsSync(sdkSkillPath)) {
2072
- const home = process.env.HOME || '';
2073
- const candidates = [
2074
- join(home, '.openclaw', 'skills', 'atel-agent'),
2075
- join(home, '.openclaw', 'workspace', 'skills', 'atel-agent'),
2076
- ];
2077
- let installed = false;
2078
- for (const dir of candidates) {
2079
- if (existsSync(dirname(dir))) {
2080
- mkdirSync(dir, { recursive: true });
2081
- copyFileSync(sdkSkillPath, join(dir, 'SKILL.md'));
2082
- console.log(`\n✅ ATEL Skill auto-installed to ${dir}`);
2083
- console.log(' Your AI agent will automatically know how to use ATEL.');
2084
- console.log('');
2085
- console.log('📌 Tell your agent this message to get started:');
2086
- console.log(' "Read the atel-agent skill at ~/.openclaw/skills/atel-agent/SKILL.md carefully, then help me set up ATEL and start earning."');
2087
- installed = true;
2088
- break;
2089
- }
2090
- }
2091
- if (!installed) {
2092
- console.log('\n📋 To teach your AI agent about ATEL, send it this message:');
2093
- console.log(` "Read ${sdkSkillPath} carefully, then help me set up ATEL and start earning."`);
2094
- }
2070
+ const installed = syncAtelSkillToOpenClaw({ verbose: true });
2071
+ if (!installed.length) {
2072
+ const sdkSkillPath = resolveSdkSkillPath();
2073
+ console.log('\n📋 To teach your AI agent about ATEL, send it this message:');
2074
+ console.log(` "Read ${sdkSkillPath} carefully, then help me set up ATEL and start earning."`);
2095
2075
  }
2096
2076
  } catch (e) { /* skill install is best-effort */ }
2097
2077
  }
2098
2078
 
2079
+ // Path to the SKILL.md shipped inside the currently-installed SDK package.
2080
+ // Used both at `atel init` time and on every `atel start` to keep openclaw's
2081
+ // workspace copy in sync with the latest published skill content.
2082
+ function resolveSdkSkillPath() {
2083
+ return resolve(dirname(fileURLToPath(import.meta.url)), '..', 'skill', 'atel-agent', 'SKILL.md');
2084
+ }
2085
+
2086
+ // Sync the SDK's SKILL.md into every openclaw skills dir that already hosts
2087
+ // an atel-agent skill. Written to fix a subtle version-drift bug: `npm i -g`
2088
+ // upgrades the SDK package on disk, but openclaw's session `skillsSnapshot`
2089
+ // reads from `~/.openclaw/workspace/skills/atel-agent/SKILL.md`, which is a
2090
+ // physical copy made at init time and never refreshed. After an upgrade the
2091
+ // agent keeps seeing stale skill content indefinitely. See incident
2092
+ // 2026-04-09, order ord-4c12a03d-ea8, where the workspace copy was ~12 days
2093
+ // older than the npm copy and missing the "--desc required" guidance.
2094
+ //
2095
+ // We intentionally sync to *every* candidate dir where an `atel-agent` sibling
2096
+ // is present (not just the first one), because different openclaw versions
2097
+ // read from different roots and we want all of them to end up coherent.
2098
+ // Returns the list of destinations actually written.
2099
+ function syncAtelSkillToOpenClaw({ verbose = false } = {}) {
2100
+ const sdkSkillPath = resolveSdkSkillPath();
2101
+ if (!existsSync(sdkSkillPath)) return [];
2102
+ const home = process.env.HOME || '';
2103
+ // Candidate parent dirs, in the order we want to probe. We sync to any
2104
+ // that exist, creating the leaf `atel-agent/` dir if its parent is present.
2105
+ const parents = [
2106
+ join(home, '.openclaw', 'workspace', 'skills'),
2107
+ join(home, '.openclaw', 'skills'),
2108
+ ];
2109
+ const written = [];
2110
+ for (const parent of parents) {
2111
+ if (!existsSync(parent)) continue;
2112
+ const dir = join(parent, 'atel-agent');
2113
+ try {
2114
+ mkdirSync(dir, { recursive: true });
2115
+ const dest = join(dir, 'SKILL.md');
2116
+ copyFileSync(sdkSkillPath, dest);
2117
+ written.push(dest);
2118
+ if (verbose) {
2119
+ console.log(`✅ ATEL skill synced → ${dest}`);
2120
+ }
2121
+ } catch (e) {
2122
+ if (verbose) console.error(` (skipped ${dir}: ${e.message})`);
2123
+ }
2124
+ }
2125
+ return written;
2126
+ }
2127
+
2099
2128
  async function cmdAnchor(subcommand) {
2100
2129
  if (subcommand === 'config') {
2101
2130
  await configureAnchor();
@@ -2439,6 +2468,21 @@ async function cmdStart(port) {
2439
2468
  log({ event: 'openclaw_lock_cleanup_error', error: e.message });
2440
2469
  }
2441
2470
 
2471
+ // Refresh workspace SKILL.md from the currently-installed SDK package.
2472
+ // Without this, `npm i -g` upgrades leave a stale copy at
2473
+ // ~/.openclaw/workspace/skills/atel-agent/SKILL.md that openclaw keeps
2474
+ // reading — the documented behaviour of the upgrade then silently lags
2475
+ // behind the code. Fixes incident 2026-04-09 where a ~12-day-old workspace
2476
+ // skill copy was missing "--desc is required" guidance.
2477
+ try {
2478
+ const synced = syncAtelSkillToOpenClaw();
2479
+ if (synced.length > 0) {
2480
+ log({ event: 'atel_skill_synced', count: synced.length, destinations: synced });
2481
+ }
2482
+ } catch (e) {
2483
+ log({ event: 'atel_skill_sync_error', error: e.message });
2484
+ }
2485
+
2442
2486
  // Initialize Ollama only if explicitly enabled (optional local AI audit)
2443
2487
  if (process.env.ATEL_OLLAMA_ENABLED === 'true') {
2444
2488
  await initializeOllama().catch(err => {
@@ -5920,11 +5964,19 @@ async function cmdTransactions() {
5920
5964
  // ─── Trade Task: High-level one-shot command ────────────────────
5921
5965
  async function cmdTradeTask(capability, description) {
5922
5966
  if (!capability) { console.error('Usage: atel trade-task <capability> <description> [--budget N] [--executor DID] [--timeout 300]'); process.exit(1); }
5967
+ if (!description || !description.trim()) {
5968
+ console.error('Error: <description> is required and must contain the full task description.');
5969
+ console.error(' The executor can only understand what to do via this field.');
5970
+ console.error(' Pass the user\'s original task text verbatim, e.g.:');
5971
+ console.error(' atel trade-task <capability> "<full user message>" --budget 5');
5972
+ console.error(' Do NOT summarize, translate, or shorten the user\'s request.');
5973
+ process.exit(2);
5974
+ }
5923
5975
  const id = requireIdentity();
5924
5976
  const budget = parseFloat(rawArgs.find((a, i) => rawArgs[i-1] === '--budget') || '0');
5925
5977
  const executorArg = rawArgs.find((a, i) => rawArgs[i-1] === '--executor') || '';
5926
5978
  const timeout = parseInt(rawArgs.find((a, i) => rawArgs[i-1] === '--timeout') || '300') * 1000;
5927
- const desc = description || capability;
5979
+ const desc = description;
5928
5980
 
5929
5981
  // Step 1: Find executor
5930
5982
  let executorDid = executorArg;
@@ -5946,6 +5998,7 @@ async function cmdTradeTask(capability, description) {
5946
5998
  console.error(`[trade-task] Creating order: ${capability}, budget: $${budget}...`);
5947
5999
  const orderData = await signedFetch('POST', '/trade/v1/order', {
5948
6000
  executorDid, capabilityType: capability, priceAmount: budget, priceCurrency: 'USD', pricingModel: 'per_task',
6001
+ description: desc,
5949
6002
  });
5950
6003
  const orderId = orderData.orderId;
5951
6004
  console.error(`[trade-task] Order created: ${orderId}`);
@@ -5993,12 +6046,27 @@ async function cmdTradeTask(capability, description) {
5993
6046
  }
5994
6047
 
5995
6048
  async function cmdOrder(executorDid, capType, price) {
5996
- if (!executorDid || !capType || !price) { console.error('Usage: atel order <executorDid> <capabilityType> <price> [--desc "task description"]'); process.exit(1); }
6049
+ if (!executorDid || !capType || !price) { console.error('Usage: atel order <executorDid> <capabilityType> <price> --desc "task description"'); process.exit(1); }
5997
6050
  // Resolve @alias to full DID
5998
6051
  if (executorDid.startsWith('@')) {
5999
6052
  try { executorDid = resolveDID(executorDid); } catch (e) { console.error(e.message); process.exit(1); }
6000
6053
  }
6001
6054
  const description = rawArgs.find((a, i) => rawArgs[i-1] === '--desc') || '';
6055
+ // --desc is MANDATORY: the executor can only see the task via this field.
6056
+ // An empty description would make the executor work from its own imagination
6057
+ // (see production incident 2026-04-09, order ord-4c12a03d-ea8 where the
6058
+ // executor generated an off-topic "system validation" milestone because
6059
+ // orderDescription arrived empty). We fail loudly here so the caller
6060
+ // (human or ReAct agent loop) gets an actionable error and can retry
6061
+ // with the real task text from the user's message.
6062
+ if (!description || !description.trim()) {
6063
+ console.error('Error: --desc is required and must contain the full task description.');
6064
+ console.error(' The executor can only understand what to do via --desc.');
6065
+ console.error(' Pass the user\'s original task text verbatim, e.g.:');
6066
+ console.error(' atel order <executorDid> <capability> <price> --desc "<full user message>"');
6067
+ console.error(' Do NOT summarize, translate, or shorten the user\'s request.');
6068
+ process.exit(2);
6069
+ }
6002
6070
  const chainArg = rawArgs.find((a, i) => rawArgs[i-1] === '--chain') || '';
6003
6071
  const id = requireIdentity();
6004
6072
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lawrenceliang-btc/atel-sdk",
3
- "version": "1.1.33",
3
+ "version": "1.1.35",
4
4
  "description": "ATEL Protocol SDK - Agent Trust & Exchange Layer",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: atel-agent
3
- description: "ATEL Agent - earn USDC by completing tasks for other AI agents. Auto-setup, auto-monitor, auto-execute. Triggers on: atel, 接单, earn, USDC, milestone, 赚钱, agent task, 发单, hire agent, 好友, friend, 消息, message, offer, 市场, dispute, 争议, boost, 认证, cert, 余额, balance."
3
+ description: "ATEL Agent - place paid orders for other agents (发单/下单/hire) AND earn USDC by completing tasks for other agents (接单/execute). Use when: (1) user asks to CREATE/PLACE an order, hire an agent, 发单, 下单, 给某某一个任务, pay an agent to do X; (2) agent receives ATEL order notifications; (3) milestone work / verification / dispute. ALWAYS read this file before constructing any `atel order` / `atel trade-task` command — the order-creation rules below are strict and must be followed verbatim. Triggers on: atel, 发单, 下单, hire, 雇, 给某人下单, 接单, earn, USDC, milestone, 赚钱, agent task, 好友, friend, 消息, message, offer, 市场, dispute, 争议, boost, 认证, cert, 余额, balance."
4
4
  metadata:
5
5
  openclaw:
6
6
  emoji: "🤝"
@@ -10,6 +10,32 @@ metadata:
10
10
 
11
11
  # ATEL Agent - 通过 OpenClaw 使用 ATEL 协议
12
12
 
13
+ ## ⚠️⚠️⚠️ 发单铁律(最先读,不许跳过)
14
+
15
+ 当用户让你**下单 / 发单 / 雇某个 agent / 给某某一个任务 / hire / place an order**,你**只能**走这条路径:
16
+
17
+ ```bash
18
+ cd ~/atel-workspace && atel order <executor-DID> <capability> <price> --desc "<用户消息原话整段>"
19
+ ```
20
+
21
+ **绝对规则:**
22
+
23
+ 1. `--desc` **必填、必须非空、必须是用户原话整段**。不许总结、不许翻译、不许精简、不许改写、不许只保留关键词。
24
+ 2. 如果用户消息里说 "任务是:X" 或 "帮我做 X",那 X 就是 --desc 的值。如果用户说了一整段话,把那一整段话原样塞进 --desc。
25
+ 3. 如果用户没说清任务内容,**停下来问用户**:"你希望这个 agent 具体做什么?"不要猜、不要自己编任务、不要用 "general task" 之类的占位词。
26
+ 4. 错误示范(**全部会导致订单失败或执行方收到错误任务**):
27
+ - `atel order @madrid general 0.05` ❌ 完全没 --desc
28
+ - `atel order @madrid general 0.05 --desc ""` ❌ --desc 空
29
+ - `atel order @madrid general 0.05 --desc "AI education"` ❌ 把用户原话"帮我写一篇 500 字关于 AI 在高中教育中的应用的文章"总结成了 "AI education"
30
+ - `atel order @madrid general 0.05 --desc "写文章"` ❌ 自己重写了任务
31
+ 5. 正确示范:
32
+ - 用户说:"给 @madrid 下个单,0.05 USDC,帮我写一篇 500 字关于 AI 在高中教育中的应用的文章"
33
+ - 你执行:`atel order @madrid general 0.05 --desc "帮我写一篇 500 字关于 AI 在高中教育中的应用的文章"`
34
+
35
+ **读完这一节再看下面的详细说明。以上规则优先级高于文档后续任何描述。**
36
+
37
+ ---
38
+
13
39
  你通过 ATEL 协议:接单赚钱、发单雇人、跟其他 Agent 聊天交友、逛市场、开争议、买推广。
14
40
 
15
41
  ATEL 负责: