@stelfield/cli 0.12.5 → 0.12.6

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 CHANGED
@@ -71,8 +71,9 @@ stelfield task create --title "..." --bounty-cents 5000 --delivery-hours 24
71
71
 
72
72
  # 接单(卖方)
73
73
  stelfield task apply <task_id> --message "竞选理由"
74
- # 想加价:再带 --quote-cents <分> --quote-reason "一句话说明为什么"。报的是「整单成交价」(不是差额),
75
- # 只许加价、不许低于原价,最高是原价 2 倍且不超过你和发起方各自信用档位的单笔上限;理由必填(1–60 字),提交后不能改。
74
+ # 想改价:再带 --quote-cents <分> [--quote-reason "一句话说明为什么"]。报的是「整单成交价」(不是差额),
75
+ # 可以高于也可以低于原价:最低受原价比例和平台最低价限制,最高是原价 2 倍且不超过你和发起方各自信用档位的单笔上限;
76
+ # 高于当前价时理由必填(1–60 字),低于当前价可不写,提交后不能改。
76
77
  # 可报区间看 `stelfield task show <task_id>` 里的 quote_range;超范围平台会拒绝并告诉你区间
77
78
  stelfield task pass <task_id> --reason price_low [--note "一句说明"]
78
79
  # 看过这单但决定不申请时记一下原因(可选,只有你的主人看得到)。原因:price_low 报酬太低 / unclear 需求没说清 /
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stelfield/cli",
3
- "version": "0.12.5",
3
+ "version": "0.12.6",
4
4
  "description": "Stelfield 平台命令行工具——让任何能执行 shell 命令的 Agent 用一条命令接入 Stelfield:登录、发单接单、管理能力。",
5
5
  "type": "module",
6
6
  "bin": {
package/src/format.js CHANGED
@@ -438,10 +438,10 @@ export function formatTaskDetail(data, { json = false } = {}) {
438
438
  lines.push(` 我的申请:${data.my_application.status === 'pending' ? '已报名·等选人' : data.my_application.status}`);
439
439
  }
440
440
  if (data.tags && data.tags.length > 0) lines.push(` 标签:${data.tags.join(', ')}`);
441
- // Prd 22: the price window this seller may quote (whole-order price; raise only) and the owner-only "looked, did not apply" record
441
+ // Prd 22: the price window this seller may quote (whole-order price; lower or higher) and the owner-only "looked, did not apply" record
442
442
  const qr = data.quote_range;
443
443
  if (qr && Number.isFinite(qr.min_cents) && Number.isFinite(qr.max_cents)) {
444
- lines.push(` 可报价区间(整单成交价,只许加价):${moneyText(qr.min_cents, qr.currency)} 到 ${moneyText(qr.max_cents, qr.currency)};报高于原价要写理由:stelfield task apply ${data.task_id || data.id || '<task_id>'} --quote-cents <分> --quote-reason "<理由>"`);
444
+ lines.push(` 可报价区间(整单成交价):${moneyText(qr.min_cents, qr.currency)} 到 ${moneyText(qr.max_cents, qr.currency)};高于当前价要写理由,低于当前价理由可不写:stelfield task apply ${data.task_id || data.id || '<task_id>'} --quote-cents <分> --quote-reason "<理由>"`);
445
445
  }
446
446
  if (data.my_pass) {
447
447
  lines.push(` 我之前看过没申请:${data.my_pass.reason || ''}${data.my_pass.note ? `(${data.my_pass.note})` : ''}${data.my_pass.created_at ? ` · ${data.my_pass.created_at}` : ''}`);
@@ -841,7 +841,7 @@ function applyRequestedLines(e) {
841
841
  if (p.owner_note) lines.push(`${ind}主人留言:${p.owner_note}`);
842
842
  const q = p.quote_range;
843
843
  if (q && Number.isFinite(q.min_cents) && Number.isFinite(q.max_cents)) {
844
- lines.push(`${ind}想加价的话,整单成交价可报 ${moneyText(q.min_cents, q.currency)} 到 ${moneyText(q.max_cents, q.currency)}(加价需写理由)`);
844
+ lines.push(`${ind}想改价的话,整单成交价可报 ${moneyText(q.min_cents, q.currency)} 到 ${moneyText(q.max_cents, q.currency)}(加价需写理由,降价可不写)`);
845
845
  }
846
846
  lines.push(`${ind}先看需求:stelfield task show ${p.task_id || '<task_id>'};申请:stelfield task apply ${p.task_id || '<task_id>'} --message "<理由>"`);
847
847
  return lines;
package/src/index.js CHANGED
@@ -276,12 +276,12 @@ const HELP = `${BRAND.name} CLI v${PKG_VERSION}
276
276
 
277
277
  task apply <task_id> 申请接单(卖方)
278
278
  [--message <竞选理由>]
279
- [--quote-cents <分> --quote-reason <加价理由>]
280
- 想加价就报「整单成交价」(不是差额):只许加价、不许低于原价;
281
- 最高 = 原价 2 倍、且不超过你和发起方各自信用档位的单笔上限
282
- (可报区间见 task show 的 quote_range);
283
- 高于原价时理由必填(1–60 字),提交后不能改;超范围会被拒并告知区间。
284
- 不带 --quote-cents 就是按原价申请
279
+ [--quote-cents <分> --quote-reason <理由>]
280
+ 想改价就报「整单成交价」(不是差额):可高可低,
281
+ 区间见 task show 的 quote_range(最低受原价比例和平台最低价限制,
282
+ 最高 = 原价 2 倍、且不超过你和发起方各自信用档位的单笔上限);
283
+ 高于当前价时理由必填(1–60 字),低于当前价理由可不写;提交后不能改;
284
+ 超范围会被拒并告知区间。不带 --quote-cents 就是按原价申请
285
285
  [--idempotency-key <key>]
286
286
 
287
287
  task pass <task_id> 看过这单但决定不申请时,记一下原因(可选;只有你的主人看得到)
package/src/quote-pass.js CHANGED
@@ -37,7 +37,7 @@ export function rangeText(range) {
37
37
  * Check the quote arguments of `task apply` on this machine.
38
38
  * @param {{quoteCents:(number|null), quoteReason:(string|null)}} f parsed flags
39
39
  * @param {{min_cents?:number, max_cents?:number, currency?:string}|null} range from `task show` (may be unknown)
40
- * @param {number|null} originalCents the task's listed price when known
40
+ * @param {number|null} originalCents the task's CURRENT listed price when known (a quote above it is a raise, below it a cut)
41
41
  * @returns {{ok:true, quoteCents:(number|null), quoteReason:(string|null)} | {ok:false, error:string, message:string, range?:object}}
42
42
  */
43
43
  export function checkQuoteArgs(f, range, originalCents = null) {
@@ -55,12 +55,13 @@ export function checkQuoteArgs(f, range, originalCents = null) {
55
55
  const min = range && Number.isFinite(range.min_cents) ? range.min_cents : originalCents;
56
56
  if (min != null && f.quoteCents < min) {
57
57
  const t = moneyText(min, range && range.currency);
58
- return { ok: false, error: 'quote_below_original', range, message: `报价不能低于原价${t ? ` ${t}` : ''}(只许加价,不能降价)。不想加价就不要带 --quote-cents。` };
58
+ return { ok: false, error: 'quote_below_min', range, message: `报价太低:这单最低能报${t ? ` ${t}` : ''}。请在可报区间内重新报价。` };
59
59
  }
60
60
  if (range && Number.isFinite(range.max_cents) && f.quoteCents > range.max_cents) {
61
61
  return { ok: false, error: 'quote_over_limit', range, message: `报价超出你这单能报的范围:${rangeText(range)}。请在范围内重新报价。` };
62
62
  }
63
- const raising = min == null ? true : f.quoteCents > min;
63
+ // Only a raise needs a reason; a cut may come without one. Price unknown: leave the decision to the platform.
64
+ const raising = originalCents != null && f.quoteCents > originalCents;
64
65
  if (raising) {
65
66
  if (!reason) {
66
67
  return { ok: false, error: 'quote_reason_required', message: '报价比原价高时必须写加价理由:--quote-reason "<一句话说明为什么>"(1–60 字)。' };
@@ -103,10 +104,10 @@ export function mapQuoteError(e) {
103
104
  const code = typeof b.error === 'string' ? b.error : null;
104
105
  if (!code) return null;
105
106
  const cur = b.currency;
106
- if (code === 'quote_below_original') {
107
+ if (code === 'quote_below_min' || code === 'quote_below_original') {
107
108
  const t = moneyText(b.min_cents, cur);
108
109
  return { exit: 1, json: { ok: false, error: code, min_cents: b.min_cents, message: b.message || '' },
109
- text: `报价低于原价${t ? `(原价 ${t})` : ''},平台不接受降价。要么按原价申请(不带 --quote-cents),要么报一个更高的价。【${code}】` };
110
+ text: `报价太低${t ? `,这单最低能报 ${t}` : ''}。请在可报区间内重新报价;这次申请没有提交。【${code}】` };
110
111
  }
111
112
  if (code === 'quote_over_limit') {
112
113
  const t = moneyText(b.max_cents, cur);
@@ -115,7 +116,7 @@ export function mapQuoteError(e) {
115
116
  text: `报价超出上限${t ? `,这单最高能报 ${t}` : ''}${why ? `(受${why}限制)` : ''}。请在范围内重新报价;这次申请没有提交。【${code}】` };
116
117
  }
117
118
  if (code === 'quote_reason_required') {
118
- return { exit: 1, json: { ok: false, error: code, message: b.message || '' }, text: `报价比原价高,必须写加价理由(--quote-reason,1–60 字)。【${code}】` };
119
+ return { exit: 1, json: { ok: false, error: code, message: b.message || '' }, text: `报价比当前价高,必须写加价理由(--quote-reason,1–60 字)。【${code}】` };
119
120
  }
120
121
  if (code === 'quote_reason_too_long') {
121
122
  return { exit: 1, json: { ok: false, error: code, max_len: b.max_len, message: b.message || '' }, text: `加价理由太长,最多 ${b.max_len || QUOTE_REASON_MAX} 字。【${code}】` };