@seasonkoh/webaz 0.1.23 → 0.1.24

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.
@@ -43,10 +43,16 @@ const TELEMETRY_ENABLED = (process.env.WEBAZ_TELEMETRY ?? 'off').toLowerCase() =
43
43
  const WEBAZ_API_URL = (process.env.WEBAZ_API_URL ?? 'https://webaz.xyz').replace(/\/+$/, '');
44
44
  const WEBAZ_API_KEY = process.env.WEBAZ_API_KEY ?? '';
45
45
  const WEBAZ_MODE_ENV = (process.env.WEBAZ_MODE ?? '').toLowerCase();
46
- // 模式:显式 WEBAZ_MODE 优先;否则有 api_key → network,无 → sandbox
46
+ // 模式:显式 WEBAZ_MODE 优先;否则有 api_key → network,无 key network_readonly(装完即见真网络)。
47
+ // network_readonly(L1 onboarding,2026-06-08):无 key 默认。公共读匿名打 webaz.xyz(真 catalog/协议),
48
+ // 需身份的写/读返回"设 WEBAZ_API_KEY(到 #welcome 申请邀请)"。离线本地 playground 改为【显式】 WEBAZ_MODE=sandbox。
49
+ // —— 治"装完=空沙盒劝退"的死首体验;route/guard 与 network 同路(见 isNetworkMode),只是无 Bearer + 文案不同。
47
50
  const MODE = WEBAZ_MODE_ENV === 'network' ? 'network'
48
51
  : WEBAZ_MODE_ENV === 'sandbox' ? 'sandbox'
49
- : (WEBAZ_API_KEY ? 'network' : 'sandbox');
52
+ : WEBAZ_MODE_ENV === 'network_readonly' ? 'network_readonly'
53
+ : (WEBAZ_API_KEY ? 'network' : 'network_readonly');
54
+ // network 或 network_readonly 都"走真网络"(后者无 Bearer)。sandbox 才是本地。
55
+ const isNetworkMode = () => MODE === 'network' || MODE === 'network_readonly';
50
56
  // 已迁移到 NETWORK 的工具名。P1/P2 逐个加入;未在集合里的工具仍走 sandbox(本地)。
51
57
  // P1(读工具): 纯公开读,无写无 Passkey,作"MCP 连得上生产网络"的首验证。
52
58
  const NETWORK_TOOLS = new Set([
@@ -103,9 +109,10 @@ function pushRecentCall(c) {
103
109
  if (recentCalls.length > 8)
104
110
  recentCalls.shift(); // 只留最近 8 条
105
111
  }
106
- // 单个工具实际后端:仅当全局 network 且该工具已迁移,才走网络;否则 sandbox。
112
+ // 单个工具实际后端:network network_readonly 下、且该工具已迁移,才走网络;否则 sandbox。
113
+ // readonly 无 Bearer:公共读拿真数据,需身份的端点服务端返 401(诚实)→ 不会静默落本地。
107
114
  function toolBackend(tool) {
108
- return (MODE === 'network' && NETWORK_TOOLS.has(tool)) ? 'network' : 'sandbox';
115
+ return (isNetworkMode() && NETWORK_TOOLS.has(tool)) ? 'network' : 'sandbox';
109
116
  }
110
117
  // 未在 NETWORK_TOOLS 名单、但 NETWORK 模式下仍可本地运行的"自省/引导"工具(非数据操作)。
111
118
  // info = 本地自省(并拉 live 网络状态);register = 引导真人去 webaz.xyz。其余未迁工具一律硬失败。
@@ -166,11 +173,14 @@ async function apiCall(path, opts = {}) {
166
173
  // 启动 banner(stderr)+ status 声明用 —— 让用户/agent 一眼知道现在是真网络还是沙盒
167
174
  function modeBanner() {
168
175
  if (MODE === 'network') {
169
- return `🟢 NETWORK mode — webaz.xyz (${WEBAZ_API_URL}). Migrated tools: ${NETWORK_TOOLS.size}/${TOOLS.length}`
170
- + (NETWORK_TOOLS.size === 0 ? ' ⚠️ network client not active yet (P0 scaffold) — all tools still SANDBOX/local.' : '');
176
+ return `🟢 NETWORK mode — webaz.xyz (${WEBAZ_API_URL}), authenticated. Migrated tools: ${NETWORK_TOOLS.size}/${TOOLS.length}`;
171
177
  }
172
- return `🟡 SANDBOX mode — local-only (~/.webaz/webaz.db), NOT the live network. Data is private to this machine.`
173
- + (WEBAZ_API_KEY ? '' : ' Set WEBAZ_API_KEY (register at webaz.xyz) to join the network.');
178
+ if (MODE === 'network_readonly') {
179
+ return `🟢 NETWORK (read-only) no api_key: public reads (search / leaderboard / price history / browse) hit the LIVE webaz.xyz network. `
180
+ + `To transact (register/order/list/etc.), set WEBAZ_API_KEY — request an invite at ${WEBAZ_API_URL}/#welcome.`;
181
+ }
182
+ return `🟡 SANDBOX mode — local-only (~/.webaz/webaz.db), NOT the live network. Data is private to this machine. `
183
+ + `(Explicit dev/demo mode; unset WEBAZ_MODE to use the live network read-only by default.)`;
174
184
  }
175
185
  // ─── 初始化 ──────────────────────────────────────────────────
176
186
  const db = initDatabase();
@@ -1534,7 +1544,7 @@ async function handleInfo() {
1534
1544
  // RFC-003 Batch 0:NETWORK 模式下,best-effort 拉 webaz.xyz 的 live 协议状态,
1535
1545
  // 让带 key 的 agent 拿到【真网络】数字,而非只看本机本地 live_stats(下方仍保留并标注为本地)。
1536
1546
  let network_live = null;
1537
- if (MODE === 'network') {
1547
+ if (isNetworkMode()) {
1538
1548
  try {
1539
1549
  const ps = await apiCall('/api/protocol-status');
1540
1550
  network_live = { source: `${WEBAZ_API_URL}/api/protocol-status (live, fetched this call)`, ...ps };
@@ -1587,11 +1597,13 @@ async function handleInfo() {
1587
1597
  // 佣金按【功能】中性描述(commission_model),不做"自证不是X"的辩护——正常机制无需自证。
1588
1598
  network_state: {
1589
1599
  // RFC-003 P3:显式声明当前客户端模式,让 agent 一眼分清"真网络 vs 本机沙盒"
1590
- mode: MODE, // 'network' | 'sandbox'
1600
+ mode: MODE, // 'network' | 'network_readonly' | 'sandbox'
1591
1601
  mode_banner: modeBanner(),
1592
1602
  mode_meaning: MODE === 'network'
1593
1603
  ? '🟢 NETWORK:核心交易工具(下单/上架/履约/比价等)走 webaz.xyz 共享生产网络。真网络规模见下方 network_live(本次实时拉取);live_stats 仍是本机本地缓存,仅供参考。'
1594
- : '🟡 SANDBOX:所有工具都在本机本地 SQLite 运行,与 webaz.xyz 全网隔离。任何计数 / 账号 / 订单仅本机有效,不是真实网络状态。设 WEBAZ_API_KEY 可切到 NETWORK。',
1604
+ : MODE === 'network_readonly'
1605
+ ? '🟢 NETWORK(只读):无 api_key。公共读(搜索/榜单/价格史/浏览)打 webaz.xyz 真网络(见 network_live)。要交易(注册/下单/上架等)请设 WEBAZ_API_KEY —— 到 ' + WEBAZ_API_URL + '/#welcome 申请邀请。'
1606
+ : '🟡 SANDBOX:所有工具都在本机本地 SQLite 运行,与 webaz.xyz 全网隔离(显式 dev/demo 模式)。任何计数 / 账号 / 订单仅本机有效。不设 WEBAZ_MODE 则默认走真网络只读。',
1595
1607
  phase: 'pre_launch',
1596
1608
  real_users_on_canonical: 0,
1597
1609
  canonical_endpoint: 'https://webaz.xyz',
@@ -1674,10 +1686,10 @@ async function handleInfo() {
1674
1686
  function handleRegister(args) {
1675
1687
  // ─── RFC-003 P3:NETWORK 模式不自助建号 ────────────────────────
1676
1688
  // 自助注册会绕过邀请码 / captcha / 责任制;且 CHARTER §4 I-5 要求账号必须由已绑 Passkey
1677
- // 的真人创建("每个 agent 背后有可问责的真人")。NETWORK 模式下改为引导真人去 webaz.xyz 拿 key。
1678
- if (MODE === 'network') {
1689
+ // 的真人创建("每个 agent 背后有可问责的真人")。NETWORK / 无 key 只读模式下都引导真人去 webaz.xyz 拿 key。
1690
+ if (isNetworkMode()) {
1679
1691
  return {
1680
- _mode: 'network',
1692
+ _mode: MODE,
1681
1693
  registration: 'must_be_done_by_human_at_webaz_xyz',
1682
1694
  message: '🟢 NETWORK 模式下不支持 agent 自助注册。开放协议的信任来自"每个 agent 背后有可问责的真人",所以注册这一步刻意留给真人在 webaz.xyz 完成。请按三步加入共享网络:',
1683
1695
  steps: [
@@ -3919,9 +3931,9 @@ async function readEndpoint(tool, subpath) {
3919
3931
  }
3920
3932
  }
3921
3933
  async function pwaApi(method, path, apiKey, body) {
3922
- // RFC-003:NETWORK 模式 → 走 webaz.xyz 共享网络(Bearer api_key)。仅 NETWORK_TOOLS 里的工具会到这里
3923
- // (其余未迁工具在 dispatch 被 Batch 0 守卫拦下);SANDBOX 模式仍转发本地 PWA(localhost)。
3924
- if (MODE === 'network') {
3934
+ // RFC-003:NETWORK / network_readonly → 走 webaz.xyz(Bearer 可空)。仅 NETWORK_TOOLS 里的工具会到这里
3935
+ // (其余未迁工具在 dispatch 被 Batch 0 守卫拦下);SANDBOX 才转发本地 PWA(localhost)。
3936
+ if (isNetworkMode()) {
3925
3937
  return apiCall(path.startsWith('/api') ? path : '/api' + path, { method, apiKey, body });
3926
3938
  }
3927
3939
  const opts = {
@@ -4848,7 +4860,7 @@ export async function startMCPServer() {
4848
4860
  // ─── RFC-003 Batch 0 安全网:NETWORK 模式下未迁移的工具【硬失败】,不静默落本地沙盒 ───
4849
4861
  // 例外:info / register(NETWORK_SELF_AWARE)有专门 network-aware 处理,照常放行。
4850
4862
  let handled = false;
4851
- if (MODE === 'network' && !NETWORK_TOOLS.has(name) && !NETWORK_SELF_AWARE.has(name)) {
4863
+ if (isNetworkMode() && !NETWORK_TOOLS.has(name) && !NETWORK_SELF_AWARE.has(name)) {
4852
4864
  result = networkMigrationPending(name);
4853
4865
  handled = true;
4854
4866
  }
@@ -4991,7 +5003,9 @@ export async function startMCPServer() {
4991
5003
  }
4992
5004
  // RFC-003 P0: 给每个工具结果盖模式戳(诚实可见,防把 sandbox 当 live 网络)
4993
5005
  // P3: handler 可自行预设 _mode(如 register 在 network 模式返回引导,不是 sandbox 结果)→ 不覆盖。
4994
- const backend = toolBackend(name);
5006
+ // self-aware 工具(info/register)按全局 MODE 盖戳,不按 toolBackend(它们不在 NETWORK_TOOLS 但本就网络感知),
5007
+ // 否则 network_readonly/network 下 info 会被误盖 sandbox 戳,与其自身 network_state 矛盾。
5008
+ const backend = NETWORK_SELF_AWARE.has(name) ? (isNetworkMode() ? 'network' : 'sandbox') : toolBackend(name);
4995
5009
  if (result && typeof result === 'object' && !Array.isArray(result)) {
4996
5010
  const r = result;
4997
5011
  if (!('_mode' in r))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seasonkoh/webaz",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "[PRE-LAUNCH] Agent-native decentralized commerce protocol. Humans and AI agents trade on the same protocol via MCP tools. ⚠️ Repository currently private until W8 public launch — GitHub links may return 404. See https://webaz.xyz for status.",
5
5
  "main": "dist/mcp.js",
6
6
  "bin": {