1688-cli 0.1.41 → 0.1.43

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 (119) hide show
  1. package/AGENTS.md +112 -318
  2. package/ARCHITECTURE.md +107 -0
  3. package/CHANGELOG.md +79 -0
  4. package/README.md +186 -18
  5. package/dist/cli.js +131 -25
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/cart-list.js +2 -1
  8. package/dist/commands/cart-list.js.map +1 -1
  9. package/dist/commands/checkout-confirm.js +8 -8
  10. package/dist/commands/checkout-confirm.js.map +1 -1
  11. package/dist/commands/compare.js +107 -0
  12. package/dist/commands/compare.js.map +1 -0
  13. package/dist/commands/doctor.js +64 -47
  14. package/dist/commands/doctor.js.map +1 -1
  15. package/dist/commands/inbox.js +1 -1
  16. package/dist/commands/inbox.js.map +1 -1
  17. package/dist/commands/login.js +14 -14
  18. package/dist/commands/login.js.map +1 -1
  19. package/dist/commands/logout.js +6 -4
  20. package/dist/commands/logout.js.map +1 -1
  21. package/dist/commands/offer.js +7 -5
  22. package/dist/commands/offer.js.map +1 -1
  23. package/dist/commands/order-list.js +4 -2
  24. package/dist/commands/order-list.js.map +1 -1
  25. package/dist/commands/order-logistics.js +4 -2
  26. package/dist/commands/order-logistics.js.map +1 -1
  27. package/dist/commands/profile.js +25 -9
  28. package/dist/commands/profile.js.map +1 -1
  29. package/dist/commands/research.js +142 -0
  30. package/dist/commands/research.js.map +1 -0
  31. package/dist/commands/search.js +59 -18
  32. package/dist/commands/search.js.map +1 -1
  33. package/dist/commands/seller-chat.js +1 -1
  34. package/dist/commands/seller-chat.js.map +1 -1
  35. package/dist/commands/seller-inquire.js +1 -1
  36. package/dist/commands/seller-inquire.js.map +1 -1
  37. package/dist/commands/seller-messages.js +8 -5
  38. package/dist/commands/seller-messages.js.map +1 -1
  39. package/dist/commands/sourcing-utils.js +438 -0
  40. package/dist/commands/sourcing-utils.js.map +1 -0
  41. package/dist/commands/supplier-inspect.js +559 -0
  42. package/dist/commands/supplier-inspect.js.map +1 -0
  43. package/dist/commands/supplier-search.js +522 -0
  44. package/dist/commands/supplier-search.js.map +1 -0
  45. package/dist/commands/whoami.js +6 -3
  46. package/dist/commands/whoami.js.map +1 -1
  47. package/dist/daemon/client.js +10 -6
  48. package/dist/daemon/client.js.map +1 -1
  49. package/dist/daemon/manager.js +53 -37
  50. package/dist/daemon/manager.js.map +1 -1
  51. package/dist/daemon/protocol.js +2 -1
  52. package/dist/daemon/protocol.js.map +1 -1
  53. package/dist/daemon/server.js +26 -22
  54. package/dist/daemon/server.js.map +1 -1
  55. package/dist/session/context.js +1 -1
  56. package/dist/session/context.js.map +1 -1
  57. package/dist/session/dispatch.js +25 -22
  58. package/dist/session/dispatch.js.map +1 -1
  59. package/dist/session/im-ws.js +8 -5
  60. package/dist/session/im-ws.js.map +1 -1
  61. package/dist/session/lock.js +14 -14
  62. package/dist/session/lock.js.map +1 -1
  63. package/dist/session/paths.js +50 -16
  64. package/dist/session/paths.js.map +1 -1
  65. package/dist/session/search-mtop.js +53 -0
  66. package/dist/session/search-mtop.js.map +1 -1
  67. package/dist/session/shared.js +17 -7
  68. package/dist/session/shared.js.map +1 -1
  69. package/dist/session/state.js +7 -7
  70. package/dist/session/state.js.map +1 -1
  71. package/dist/session/supplier-search.js +403 -0
  72. package/dist/session/supplier-search.js.map +1 -0
  73. package/dist/util/encoding.js +8 -0
  74. package/dist/util/encoding.js.map +1 -0
  75. package/dist/util/temp.js +6 -0
  76. package/dist/util/temp.js.map +1 -0
  77. package/docs/AGENT_MAPS_PLAN.md +171 -0
  78. package/docs/AGENT_WORKING_PRINCIPLES.md +143 -0
  79. package/docs/COMMANDS.md +205 -0
  80. package/docs/FEATURES.md +45 -0
  81. package/docs/JSON_CONTRACTS.md +476 -0
  82. package/docs/QUALITY_SCORE.md +61 -0
  83. package/docs/README.md +36 -0
  84. package/docs/RELIABILITY.md +69 -0
  85. package/docs/SAFETY.md +99 -0
  86. package/docs/WORKFLOW.md +82 -0
  87. package/docs/exec-plans/README.md +9 -0
  88. package/docs/exec-plans/active/README.md +4 -0
  89. package/docs/exec-plans/completed/2026-05-28-sourcing-research-v1.md +125 -0
  90. package/docs/exec-plans/completed/2026-05-31-supplier-inspect-v1.md +113 -0
  91. package/docs/exec-plans/completed/2026-06-04-supplier-search-v1.md +81 -0
  92. package/docs/exec-plans/completed/2026-06-07-windows-cli-compatibility.md +138 -0
  93. package/docs/exec-plans/completed/2026-06-16-profile-daemon.md +146 -0
  94. package/docs/exec-plans/completed/README.md +4 -0
  95. package/docs/exec-plans/tech-debt-tracker.md +5 -0
  96. package/docs/generated/command-index.md +54 -0
  97. package/docs/generated/json-shapes.md +111 -0
  98. package/docs/generated/module-map.md +13 -0
  99. package/docs/generated/test-index.md +34 -0
  100. package/docs/playbooks/add-command.md +15 -0
  101. package/docs/playbooks/add-mtop-capture.md +13 -0
  102. package/docs/playbooks/change-json-output.md +11 -0
  103. package/docs/playbooks/debug-risk-control.md +12 -0
  104. package/docs/playbooks/update-cli-release.md +61 -0
  105. package/docs/records/release-omissions.md +34 -0
  106. package/docs/specs/checkout-and-orders.md +30 -0
  107. package/docs/specs/index.md +9 -0
  108. package/docs/specs/profile-daemon.md +114 -0
  109. package/docs/specs/seller-im.md +28 -0
  110. package/docs/specs/sourcing-research.md +186 -0
  111. package/docs/specs/supplier-inspect.md +144 -0
  112. package/docs/specs/supplier-search.md +179 -0
  113. package/docs/specs/windows-cli-compatibility.md +123 -0
  114. package/package.json +21 -4
  115. package/scripts/check_agent_map.mjs +87 -0
  116. package/scripts/check_release.mjs +40 -0
  117. package/scripts/fix_bin_mode.mjs +18 -0
  118. package/scripts/generate_agent_context.mjs +253 -0
  119. package/scripts/postinstall.mjs +12 -4
@@ -0,0 +1,476 @@
1
+ # JSON Contracts
2
+
3
+ The CLI auto-switches to JSON when stdout is piped. Stable JSON output is part
4
+ of the agent contract. Prefer additive changes; do not rename or remove fields
5
+ without an explicit breaking-change decision.
6
+
7
+ ## Output Rules
8
+
9
+ - `--json` forces JSON in a TTY.
10
+ - `--pretty` indents JSON by two spaces.
11
+ - `--get <path>` prints one dot-path. Scalars are raw lines; objects and arrays
12
+ remain JSON.
13
+ - `--pick <paths>` emits a JSON object with each requested path as a key.
14
+ - Watch commands emit line-delimited JSON, one object per new event/message.
15
+
16
+ ## `whoami`
17
+
18
+ ```ts
19
+ { loggedIn: true, memberId: string, nick: string, lastVerifiedAt: string }
20
+ { loggedIn: false }
21
+ ```
22
+
23
+ ## `daemon status`
24
+
25
+ `daemon status` is profile-scoped. When `--profile` is omitted, `profile` is
26
+ `default`.
27
+
28
+ ```ts
29
+ {
30
+ profile: string,
31
+ running: boolean,
32
+ pid?: number,
33
+ reachable?: boolean,
34
+ version?: string | null,
35
+ expectedVersion?: string,
36
+ versionMatches?: boolean,
37
+ stats?: {
38
+ profile: string,
39
+ version: string,
40
+ startedAt: string,
41
+ pid: number,
42
+ commandCount: number,
43
+ lastRequestAt: string | null,
44
+ lastError: string | null,
45
+ uptimeMs: number,
46
+ activeClients: number,
47
+ browser: {
48
+ profile: string | null,
49
+ browserAlive: boolean,
50
+ pageCount: number,
51
+ currentUrl: string | null,
52
+ pageState: object | null,
53
+ loggedIn: boolean | null,
54
+ },
55
+ health: object,
56
+ },
57
+ }
58
+ ```
59
+
60
+ ## `profile status`
61
+
62
+ ```ts
63
+ {
64
+ profile: {
65
+ name: string,
66
+ path: string,
67
+ exists: boolean,
68
+ locked: boolean,
69
+ loggedIn: boolean,
70
+ recentRequestId: string | null,
71
+ recentStatus: string | null,
72
+ recentErrorCode: string | null,
73
+ daemon: {
74
+ profile: string,
75
+ running: boolean,
76
+ pid?: number,
77
+ reachable?: boolean,
78
+ version?: string | null,
79
+ expectedVersion?: string,
80
+ versionMatches?: boolean,
81
+ },
82
+ },
83
+ state: {
84
+ version: 1,
85
+ memberId?: string,
86
+ nick?: string,
87
+ loggedInAt?: string,
88
+ lastVerifiedAt?: string,
89
+ } | null,
90
+ }
91
+ ```
92
+
93
+ ## `doctor`
94
+
95
+ `doctor --profile <name>` checks that profile's directory, lock, state,
96
+ daemon, and live daemon socket. JSON output includes the selected `profile` and
97
+ the matching profile-scoped daemon status.
98
+
99
+ ```ts
100
+ {
101
+ ok: boolean,
102
+ profile: string,
103
+ checks: Array<{ name: string, status: "ok" | "warn" | "fail", message: string, fix?: string }>,
104
+ version: VersionInfo,
105
+ daemon: DaemonStatus | null,
106
+ }
107
+ ```
108
+
109
+ ## `search`, `similar`, `image-search`
110
+
111
+ ```ts
112
+ {
113
+ keyword?: string,
114
+ imageId?: string,
115
+ offerId?: string,
116
+ sort?: "relevance" | "best-selling" | "price-asc" | "price-desc",
117
+ filters?: object,
118
+ totalBeforeFilter?: number,
119
+ total: number,
120
+ offers: Array<{
121
+ offerId: string,
122
+ title: string,
123
+ price: { text: string, min: number | null, max: number | null },
124
+ supplier: { name: string | null, shopUrl: string | null, years: number | null },
125
+ location: { province: string | null, city: string | null },
126
+ bizType: string | null,
127
+ verified: { factory: boolean, business: boolean, superFactory: boolean },
128
+ tags: string[],
129
+ serviceTags?: string[],
130
+ productBadges?: string[],
131
+ demand?: {
132
+ orderCountText: string | null,
133
+ orderCount: number | null,
134
+ repurchaseRateText: string | null,
135
+ repurchaseRate: number | null,
136
+ },
137
+ isP4P: boolean,
138
+ turnover: string | null,
139
+ url: string,
140
+ image: string | null,
141
+ }>
142
+ }
143
+ ```
144
+
145
+ ## `research`
146
+
147
+ Normal JSON result:
148
+
149
+ ```ts
150
+ {
151
+ queries: string[],
152
+ sort: "relevance" | "best-selling" | "price-asc" | "price-desc",
153
+ filters: object,
154
+ maxPerQuery: number,
155
+ enrichTop: number,
156
+ total: number,
157
+ enrichedCount: number,
158
+ items: Array<{
159
+ sourceKeyword: string,
160
+ sourceRank: number,
161
+ globalRank: number,
162
+ offer: Offer,
163
+ demand: {
164
+ turnoverText: string | null,
165
+ orderCount: number | null,
166
+ repurchaseRate: number | null,
167
+ },
168
+ supplier: {
169
+ years: number | null,
170
+ verified: Offer["verified"],
171
+ tags: string[],
172
+ isAd: boolean,
173
+ },
174
+ score: number,
175
+ scoreBreakdown: Array<{ name: string, points: number, reason: string }>,
176
+ enriched?: OfferDetailSummary,
177
+ error?: { code: string, message: string },
178
+ }>,
179
+ }
180
+ ```
181
+
182
+ `--jsonl` emits one research item per line. `--csv` emits a CSV table.
183
+
184
+ ## `compare`
185
+
186
+ ```ts
187
+ {
188
+ total: number,
189
+ ok: number,
190
+ failed: number,
191
+ items: Array<{
192
+ offerId: string,
193
+ ok: boolean,
194
+ score: number | null,
195
+ scoreBreakdown: Array<{ name: string, points: number, reason: string }>,
196
+ summary: OfferDetailSummary | null,
197
+ error?: { code: string, message: string },
198
+ }>,
199
+ }
200
+ ```
201
+
202
+ ## `supplier inspect`
203
+
204
+ ```ts
205
+ {
206
+ target: {
207
+ input: string,
208
+ type: "offerId" | "memberId",
209
+ offerId: string | null,
210
+ memberId: string | null,
211
+ },
212
+ supplier: {
213
+ name: string | null,
214
+ loginId: string | null,
215
+ memberId: string | null,
216
+ userId: string | null,
217
+ companyId: string | null,
218
+ shopUrl: string | null,
219
+ shopUrls: Record<string, string>,
220
+ identity: string | null,
221
+ signs: Record<string, boolean>,
222
+ },
223
+ factory: {
224
+ isFactory: boolean,
225
+ superFactory: boolean,
226
+ tpYears: number | null,
227
+ medalLevel: string | null,
228
+ thirdPartyAuthProvider: string | null,
229
+ establishedAtText: string | null,
230
+ location: string | null,
231
+ address: string | null,
232
+ coordinates: { latitude: number | null, longitude: number | null },
233
+ productionService: string | null,
234
+ employeeScale: string | null,
235
+ workerCount: string | null,
236
+ profile: string | null,
237
+ tags: string[],
238
+ },
239
+ trust: {
240
+ companyLabel: string | null,
241
+ retentionRate: number | null,
242
+ companyIcons: Array<{ title: string, link: string | null }>,
243
+ shopTags: string[],
244
+ serviceScores: Array<{ key: string, label: string, score: number | null }>,
245
+ },
246
+ offers: { availableCount: number | null, source: "factory-card-dom" | null },
247
+ sources: {
248
+ offerUrl: string | null,
249
+ factoryCardUrl: string | null,
250
+ shopcardCaptured: boolean,
251
+ factoryCardCaptured: boolean,
252
+ },
253
+ warnings: string[],
254
+ }
255
+ ```
256
+
257
+ V1 supports offerId, offer URL, `b2b-*` memberId, and factory-card URL.
258
+ loginId-only input is rejected because live probing showed it can resolve to
259
+ the wrong supplier.
260
+
261
+ ## `supplier search`, `supplier research`
262
+
263
+ Supplier discovery uses 1688 company search
264
+ (`companySearchBusinessService`). It must not be treated as offer-search
265
+ supplier aggregation.
266
+
267
+ ```ts
268
+ {
269
+ queries: string[],
270
+ source: {
271
+ kind: "company-search",
272
+ endpoint: "companySearchBusinessService",
273
+ offerAggregation: false,
274
+ },
275
+ filters: {
276
+ factoryOnly: boolean,
277
+ province: string | null,
278
+ city: string | null,
279
+ minYears: number | null,
280
+ minRepeatRate: number | null,
281
+ minResponseRate: number | null,
282
+ },
283
+ maxPerQuery: number,
284
+ enrichTop: number,
285
+ totalBeforeFilter: number,
286
+ total: number,
287
+ enrichedCount: number,
288
+ items: Array<{
289
+ sourceKeyword: string,
290
+ sourceRank: number,
291
+ globalRank: number,
292
+ supplier: {
293
+ companyName: string,
294
+ loginId: string | null,
295
+ memberId: string | null,
296
+ enterpriseId: string | null,
297
+ realUserId: string | null,
298
+ companyId: string | null,
299
+ shopUrl: string | null,
300
+ factoryCardUrl: string | null,
301
+ domainUri: string | null,
302
+ location: {
303
+ province: string | null,
304
+ city: string | null,
305
+ address: string | null,
306
+ latitude: number | null,
307
+ longitude: number | null,
308
+ },
309
+ productionService: string | null,
310
+ businessMode: string | null,
311
+ tp: {
312
+ memberLevel: string | null,
313
+ serviceYears: number | null,
314
+ tpNum: number | null,
315
+ },
316
+ factory: {
317
+ isFactory: boolean,
318
+ factoryTag: string | null,
319
+ factoryLevel: string | null,
320
+ shiliFactory: boolean,
321
+ shiliCompany: boolean,
322
+ superFactory: boolean,
323
+ businessInspection: boolean,
324
+ factoryInspection: boolean,
325
+ qiJianCompany: boolean,
326
+ safePurchase: boolean,
327
+ trust: boolean,
328
+ },
329
+ service: {
330
+ compositeScore: number | null,
331
+ wwResponseRate: number | null,
332
+ repeatRate: number | null,
333
+ complianceRate: number | null,
334
+ },
335
+ demand: {
336
+ payOrderCount3m: number | null,
337
+ payAmount3m: number | null,
338
+ fuzzyPayAmount3m: string | null,
339
+ saleQuantity3m: number | null,
340
+ memberBookedCount: number | null,
341
+ },
342
+ tags: string[],
343
+ offersPreview: Array<{
344
+ offerId: string | null,
345
+ title: string,
346
+ url: string | null,
347
+ price: { text: string | null, value: number | null },
348
+ unit: string | null,
349
+ image: string | null,
350
+ bookedCount: number | null,
351
+ saleQuantity: number | null,
352
+ quantitySumMonth: number | null,
353
+ brief: string | null,
354
+ }>,
355
+ },
356
+ score: number,
357
+ scoreBreakdown: Array<{ name: string, points: number, reason: string }>,
358
+ inspect?: SupplierInspectResult,
359
+ error?: { code: string, message: string },
360
+ }>,
361
+ }
362
+ ```
363
+
364
+ `supplier search` defaults to `--enrich 0`; `supplier research` defaults to
365
+ `--enrich top:10`. `--jsonl` emits one supplier item per line. `--csv` emits a
366
+ CSV table.
367
+
368
+ ## `offer`
369
+
370
+ ```ts
371
+ {
372
+ offerId: string,
373
+ title: string,
374
+ url: string,
375
+ priceRange: string | null,
376
+ priceMin: number | null,
377
+ priceMax: number | null,
378
+ unitName: string | null,
379
+ minOrderQty: number | null,
380
+ mixOrderQty: number | null,
381
+ priceTiers: Array<{ minQty: number, price: number }>,
382
+ detailUrl: string | null,
383
+ attributes: Array<{ name: string, value: string }>,
384
+ packageInfo: Array<{
385
+ skuId: string,
386
+ spec: string,
387
+ length: number | null,
388
+ width: number | null,
389
+ height: number | null,
390
+ weight: number | null,
391
+ volume: number | null,
392
+ }>,
393
+ supplier: {
394
+ name: string | null,
395
+ loginId: string | null,
396
+ memberId: string | null,
397
+ userId: string | null,
398
+ },
399
+ freight: {
400
+ receiveAddress: string | null,
401
+ sendArea: string | null,
402
+ province: string | null,
403
+ city: string | null,
404
+ unitWeight: number | null,
405
+ },
406
+ saledCount: number | null,
407
+ categoryId: string | null,
408
+ options: Array<{ prop: string, values: Array<{ name: string, imageUrl: string | null }> }>,
409
+ skus: Array<{
410
+ skuId: string,
411
+ specs: string,
412
+ price: number | null,
413
+ multiPrice: number | null,
414
+ stock: number | null,
415
+ saleCount: number,
416
+ image: string | null,
417
+ }>,
418
+ mainImage: string | null,
419
+ images: string[],
420
+ }
421
+ ```
422
+
423
+ ## `seller messages`
424
+
425
+ One-shot result:
426
+
427
+ ```ts
428
+ {
429
+ conversation: string,
430
+ total: number,
431
+ messages: Array<{
432
+ sender: string,
433
+ time: string | null,
434
+ isMine: boolean,
435
+ content: string,
436
+ read: boolean,
437
+ kind: "text" | "offerCard" | "orderCard" | "autoReply"
438
+ | "assessment" | "image" | "other",
439
+ card?: {
440
+ title: string | null,
441
+ price: string | null,
442
+ image: string | null,
443
+ url: string | null,
444
+ },
445
+ messageId?: string,
446
+ }>,
447
+ }
448
+ ```
449
+
450
+ Watch mode emits one object per new message:
451
+
452
+ ```ts
453
+ { conversation: string, message: Message }
454
+ ```
455
+
456
+ ## `cart add`
457
+
458
+ ```ts
459
+ {
460
+ ok: boolean,
461
+ added: CartItem,
462
+ isNewRow: boolean,
463
+ addedQuantity: number,
464
+ }
465
+ ```
466
+
467
+ ## `order list`
468
+
469
+ Orders include buyer actions, service entries, and display badges. Preserve
470
+ `actions[]`, `services[]`, and `badges[]` because downstream agents use them to
471
+ decide what follow-up is possible.
472
+
473
+ ## Generated Shape Index
474
+
475
+ Run `pnpm agent-context` to refresh `docs/generated/json-shapes.md`, which
476
+ indexes exported TypeScript interfaces from command modules.
@@ -0,0 +1,61 @@
1
+ # Quality Score
2
+
3
+ This file tracks agent-readiness and known quality gaps. Keep it blunt and
4
+ mechanical; it is a map for improvement, not a blame document.
5
+
6
+ ## Current Score
7
+
8
+ Overall: 6 / 10
9
+
10
+ ## Strengths
11
+
12
+ - Clear buyer-journey command surface exists: sourcing, inquiry, cart,
13
+ checkout, tracking, and post-sale chat.
14
+ - Commands expose JSON automatically when piped and support `--json`,
15
+ `--pretty`, `--get`, and `--pick`.
16
+ - Real browser/session behavior is centralized under `src/session`.
17
+ - Profile-scoped daemons give agents warm browser contexts without forcing
18
+ unrelated profiles through one global lock.
19
+ - Checkout and feedback write actions already have explicit safety protocols.
20
+ - Deterministic Vitest coverage exists for output, mtop parsing, recovery,
21
+ page-state, inbox cards, and fixtures through `pnpm test:unit`.
22
+ - Agent map docs and generated indexes now exist.
23
+
24
+ ## Gaps Blocking Higher Agent Autonomy
25
+
26
+ - `AGENTS.md` was historically long; future work should keep it short and keep
27
+ durable detail in `docs/`.
28
+ - Generated context is heuristic and should improve as command/result types
29
+ evolve.
30
+ - Browser/live verification is not part of the default gate and needs explicit
31
+ manual/probe checks.
32
+ - Sourcing research fields such as repurchase rate, supplier scores, and
33
+ service badges are not yet normalized.
34
+ - Some probe scripts are exploratory and not documented as stable workflows.
35
+ - JSON compatibility policy exists in docs but is not yet enforced by schema
36
+ tests.
37
+
38
+ ## Last Known Verification Snapshot
39
+
40
+ On 2026-05-28, `pnpm agent-verify` passed:
41
+
42
+ - `pnpm typecheck`
43
+ - `pnpm test:unit` (22 files, 151 tests)
44
+ - `pnpm docs-check`
45
+ - `pnpm agent-map-check`
46
+
47
+ On 2026-05-28, full `pnpm test` failed in `tests/doctor-live.test.ts` because
48
+ the live doctor checks returned `DOCTOR_FAILED` in the current local
49
+ environment. The default agent gate uses `pnpm test:unit` to keep live checks
50
+ explicit.
51
+
52
+ ## Quality Targets
53
+
54
+ - 6 / 10: short map, docs map, generated indexes, and default verification
55
+ gate exist.
56
+ - 7 / 10: JSON contract tests cover all stable command outputs and docs-check
57
+ runs in CI.
58
+ - 8 / 10: browser/live verification playbooks are repeatable and key mtop
59
+ payloads have fixture-backed parsers.
60
+ - 9 / 10: sourcing research scoring, supplier-quality extraction, and
61
+ autonomous inbox workflows have deterministic harness tests.
package/docs/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Documentation Map
2
+
3
+ This directory is the canonical knowledge base for agents and humans working on
4
+ `1688-cli`. Keep `AGENTS.md` short and put durable context here.
5
+
6
+ ## Start Here
7
+
8
+ - Agent working principles: [`AGENT_WORKING_PRINCIPLES.md`](AGENT_WORKING_PRINCIPLES.md)
9
+ - Repository architecture: [`../ARCHITECTURE.md`](../ARCHITECTURE.md)
10
+ - Default workflow: [`WORKFLOW.md`](WORKFLOW.md)
11
+ - Command catalog: [`COMMANDS.md`](COMMANDS.md)
12
+ - JSON contracts: [`JSON_CONTRACTS.md`](JSON_CONTRACTS.md)
13
+ - Safety rules: [`SAFETY.md`](SAFETY.md)
14
+ - Reliability notes: [`RELIABILITY.md`](RELIABILITY.md)
15
+ - Quality score: [`QUALITY_SCORE.md`](QUALITY_SCORE.md)
16
+ - Feature backlog: [`FEATURES.md`](FEATURES.md)
17
+ - Agent maps plan: [`AGENT_MAPS_PLAN.md`](AGENT_MAPS_PLAN.md)
18
+
19
+ ## Domain Knowledge
20
+
21
+ - Specs: [`specs/`](specs/)
22
+ - Repeatable playbooks: [`playbooks/`](playbooks/)
23
+ - Records and postmortems: [`records/`](records/)
24
+ - Generated repository indexes: [`generated/`](generated/)
25
+ - Long-running plans: [`exec-plans/`](exec-plans/)
26
+
27
+ ## Maintenance Rules
28
+
29
+ - Update command docs when command names, flags, behavior, or examples change.
30
+ - Update JSON contracts when agent-facing output shape changes.
31
+ - Update safety docs when a write action, approval boundary, login flow, or
32
+ checkout behavior changes.
33
+ - Add or update a playbook when an agent repeats the same workflow twice.
34
+ - Run `pnpm agent-context` after changing commands, exported result
35
+ interfaces, source layout, or tests.
36
+ - Run `pnpm agent-verify` before handoff, or record the exact blocker.
@@ -0,0 +1,69 @@
1
+ # Reliability
2
+
3
+ `1688-cli` depends on a live website, browser automation, mtop responses, and a
4
+ real logged-in buyer session. Reliability work should make failures explicit
5
+ and recoverable for agents.
6
+
7
+ ## Daemon
8
+
9
+ Each daemon routes commands for one profile through one persistent Chromium
10
+ context. Different profiles use different daemon processes, locks, sockets or
11
+ named pipes, pid/version/log files, state files, and persistent browser
12
+ directories.
13
+
14
+ Benefits:
15
+
16
+ - Saves Chrome cold-start time.
17
+ - Keeps one continuous logged-in session per profile.
18
+ - Adds inter-command jitter.
19
+ - Allows different profiles to run at the same time without sharing one
20
+ process lock.
21
+
22
+ Use `1688 daemon start` near the beginning of a session with multiple 1688
23
+ commands. Use `1688 daemon start --profile <name>` for a non-default profile.
24
+ The daemon auto-stops after inactivity. Run `1688 daemon reload --profile
25
+ <name>` after package updates or after manually resolving profile-specific
26
+ browser issues.
27
+
28
+ `login`, `logout`, and `doctor` stay inline because they need interactive UI,
29
+ browser windows, or environment checks. `login --profile <name>` can
30
+ auto-start that profile daemon after the login state is available.
31
+
32
+ ## Watch Mode
33
+
34
+ `1688 seller messages ... --watch` is designed to stay alive.
35
+
36
+ - It prints a baseline line to stderr.
37
+ - It emits one JSON object to stdout for each newly-arrived message.
38
+ - History is not re-emitted.
39
+ - Deduplication uses server-side `messageId` when present.
40
+ - It exits cleanly on SIGINT.
41
+
42
+ Agent loops should parse stdout line by line and should not assume the process
43
+ will exit by itself.
44
+
45
+ ## Browser Recovery
46
+
47
+ Commands should detect and report:
48
+
49
+ - login redirects
50
+ - risk-control / slider pages
51
+ - closed browser windows
52
+ - empty mtop captures
53
+ - network failures
54
+
55
+ Use structured `CliError` exit codes so agents can choose the next safe step.
56
+
57
+ ## Probes And Fixtures
58
+
59
+ Probe scripts under `scripts/probe-*.mjs` are useful for discovering page
60
+ behavior, selectors, and mtop payloads. They are not stable automated tests.
61
+
62
+ Stable behavior belongs in `tests/` with fixtures where possible.
63
+
64
+ ## Live-Service Boundaries
65
+
66
+ `pnpm test:unit` is the deterministic default. `pnpm test` also runs live
67
+ doctor checks and may depend on local browser/session state. Browser or
68
+ account-mutating checks should be explicit, bounded, and documented in the
69
+ final response when they cannot be run.