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.
- package/AGENTS.md +112 -318
- package/ARCHITECTURE.md +107 -0
- package/CHANGELOG.md +79 -0
- package/README.md +186 -18
- package/dist/cli.js +131 -25
- package/dist/cli.js.map +1 -1
- package/dist/commands/cart-list.js +2 -1
- package/dist/commands/cart-list.js.map +1 -1
- package/dist/commands/checkout-confirm.js +8 -8
- package/dist/commands/checkout-confirm.js.map +1 -1
- package/dist/commands/compare.js +107 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/doctor.js +64 -47
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/inbox.js +1 -1
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/login.js +14 -14
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +6 -4
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/offer.js +7 -5
- package/dist/commands/offer.js.map +1 -1
- package/dist/commands/order-list.js +4 -2
- package/dist/commands/order-list.js.map +1 -1
- package/dist/commands/order-logistics.js +4 -2
- package/dist/commands/order-logistics.js.map +1 -1
- package/dist/commands/profile.js +25 -9
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/research.js +142 -0
- package/dist/commands/research.js.map +1 -0
- package/dist/commands/search.js +59 -18
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/seller-chat.js +1 -1
- package/dist/commands/seller-chat.js.map +1 -1
- package/dist/commands/seller-inquire.js +1 -1
- package/dist/commands/seller-inquire.js.map +1 -1
- package/dist/commands/seller-messages.js +8 -5
- package/dist/commands/seller-messages.js.map +1 -1
- package/dist/commands/sourcing-utils.js +438 -0
- package/dist/commands/sourcing-utils.js.map +1 -0
- package/dist/commands/supplier-inspect.js +559 -0
- package/dist/commands/supplier-inspect.js.map +1 -0
- package/dist/commands/supplier-search.js +522 -0
- package/dist/commands/supplier-search.js.map +1 -0
- package/dist/commands/whoami.js +6 -3
- package/dist/commands/whoami.js.map +1 -1
- package/dist/daemon/client.js +10 -6
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/manager.js +53 -37
- package/dist/daemon/manager.js.map +1 -1
- package/dist/daemon/protocol.js +2 -1
- package/dist/daemon/protocol.js.map +1 -1
- package/dist/daemon/server.js +26 -22
- package/dist/daemon/server.js.map +1 -1
- package/dist/session/context.js +1 -1
- package/dist/session/context.js.map +1 -1
- package/dist/session/dispatch.js +25 -22
- package/dist/session/dispatch.js.map +1 -1
- package/dist/session/im-ws.js +8 -5
- package/dist/session/im-ws.js.map +1 -1
- package/dist/session/lock.js +14 -14
- package/dist/session/lock.js.map +1 -1
- package/dist/session/paths.js +50 -16
- package/dist/session/paths.js.map +1 -1
- package/dist/session/search-mtop.js +53 -0
- package/dist/session/search-mtop.js.map +1 -1
- package/dist/session/shared.js +17 -7
- package/dist/session/shared.js.map +1 -1
- package/dist/session/state.js +7 -7
- package/dist/session/state.js.map +1 -1
- package/dist/session/supplier-search.js +403 -0
- package/dist/session/supplier-search.js.map +1 -0
- package/dist/util/encoding.js +8 -0
- package/dist/util/encoding.js.map +1 -0
- package/dist/util/temp.js +6 -0
- package/dist/util/temp.js.map +1 -0
- package/docs/AGENT_MAPS_PLAN.md +171 -0
- package/docs/AGENT_WORKING_PRINCIPLES.md +143 -0
- package/docs/COMMANDS.md +205 -0
- package/docs/FEATURES.md +45 -0
- package/docs/JSON_CONTRACTS.md +476 -0
- package/docs/QUALITY_SCORE.md +61 -0
- package/docs/README.md +36 -0
- package/docs/RELIABILITY.md +69 -0
- package/docs/SAFETY.md +99 -0
- package/docs/WORKFLOW.md +82 -0
- package/docs/exec-plans/README.md +9 -0
- package/docs/exec-plans/active/README.md +4 -0
- package/docs/exec-plans/completed/2026-05-28-sourcing-research-v1.md +125 -0
- package/docs/exec-plans/completed/2026-05-31-supplier-inspect-v1.md +113 -0
- package/docs/exec-plans/completed/2026-06-04-supplier-search-v1.md +81 -0
- package/docs/exec-plans/completed/2026-06-07-windows-cli-compatibility.md +138 -0
- package/docs/exec-plans/completed/2026-06-16-profile-daemon.md +146 -0
- package/docs/exec-plans/completed/README.md +4 -0
- package/docs/exec-plans/tech-debt-tracker.md +5 -0
- package/docs/generated/command-index.md +54 -0
- package/docs/generated/json-shapes.md +111 -0
- package/docs/generated/module-map.md +13 -0
- package/docs/generated/test-index.md +34 -0
- package/docs/playbooks/add-command.md +15 -0
- package/docs/playbooks/add-mtop-capture.md +13 -0
- package/docs/playbooks/change-json-output.md +11 -0
- package/docs/playbooks/debug-risk-control.md +12 -0
- package/docs/playbooks/update-cli-release.md +61 -0
- package/docs/records/release-omissions.md +34 -0
- package/docs/specs/checkout-and-orders.md +30 -0
- package/docs/specs/index.md +9 -0
- package/docs/specs/profile-daemon.md +114 -0
- package/docs/specs/seller-im.md +28 -0
- package/docs/specs/sourcing-research.md +186 -0
- package/docs/specs/supplier-inspect.md +144 -0
- package/docs/specs/supplier-search.md +179 -0
- package/docs/specs/windows-cli-compatibility.md +123 -0
- package/package.json +21 -4
- package/scripts/check_agent_map.mjs +87 -0
- package/scripts/check_release.mjs +40 -0
- package/scripts/fix_bin_mode.mjs +18 -0
- package/scripts/generate_agent_context.mjs +253 -0
- 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.
|