@qzhuli/qzhuli-cli 0.5.1 → 0.5.2

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/dist/cmd.js CHANGED
@@ -11203,6 +11203,7 @@ var commands = {
11203
11203
  searchDesc: "Search user",
11204
11204
  searchArgDesc: "Query string (default: Q\u52A9\u53F7)",
11205
11205
  searchByUid: "Search by UID",
11206
+ searchByQNumber: "Search by Q\u52A9\u53F7",
11206
11207
  addDesc: "Add friend by Q\u52A9\u53F7",
11207
11208
  addArgDesc: "Q\u52A9\u53F7",
11208
11209
  searchNotFound: "No user found with that Q\u52A9\u53F7.",
@@ -11216,6 +11217,7 @@ var commands = {
11216
11217
  profileArgDesc: "Query string (default: nickname)",
11217
11218
  profileByUid: "Search by UID",
11218
11219
  profileByRemark: "Search by remark",
11220
+ profileByNickname: "Search by nickname",
11219
11221
  pageOption: "Page number",
11220
11222
  pageSizeOption: "Page size",
11221
11223
  noFriends: "No friends or contacts found.",
@@ -11253,11 +11255,17 @@ var commands = {
11253
11255
  profileArgDesc: "Conversation ID",
11254
11256
  typeOption: "Conversation type (1=private, 2=group, auto-detect if omitted)",
11255
11257
  profileSuccess: "Conversation details retrieved.",
11256
- searchDesc: "Find all conversations with a user by Q\u52A9\u53F7 or UID",
11257
- searchArgDesc: "Query string (default: Q\u52A9\u53F7)",
11258
- searchByUid: "Search by UID",
11258
+ searchDesc: "Find conversations by conversation ID, name, or user",
11259
+ searchArgDesc: "Query string (default: conversation ID)",
11260
+ searchByQNumber: "Search by user Q\u52A9\u53F7",
11261
+ searchByUid: "Search by user UID",
11262
+ searchByName: "Search by conversation name",
11263
+ searchByCid: "Search by conversation ID",
11259
11264
  searchNotFound: "No conversations found with {name}.",
11260
- searchSuccess: "Found {count} conversation(s) with {name}."
11265
+ searchSuccess: "Found {count} conversation(s) with {name}.",
11266
+ searchByIdSuccess: "Found conversation {id}.",
11267
+ searchByNameNotFound: 'No conversations found with name containing "{name}".',
11268
+ searchByNameSuccess: 'Found {count} conversation(s) with name containing "{name}".'
11261
11269
  },
11262
11270
  cache: {
11263
11271
  desc: "Manage local cache",
@@ -11301,7 +11309,7 @@ __export(zh_exports, {
11301
11309
  });
11302
11310
  init_cjs_shims();
11303
11311
  var cli2 = {
11304
- banner: "qz \u2014 CLI for Q\u52A9\u7406."
11312
+ banner: "qz \u2014 CLI for Q \u52A9\u7406\u3002"
11305
11313
  };
11306
11314
  var options2 = {
11307
11315
  version: "\u8F93\u51FA\u7248\u672C\u53F7",
@@ -11320,7 +11328,7 @@ var auth2 = {
11320
11328
  // 扫码登录
11321
11329
  qrLogin: "\u626B\u7801\u767B\u5F55",
11322
11330
  creatingQr: "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801...",
11323
- qrInstruction: "\u8BF7\u4F7F\u7528Q\u52A9\u7406\u624B\u673AApp\u626B\u63CF\u4E0B\u65B9\u4E8C\u7EF4\u7801",
11331
+ qrInstruction: "\u8BF7\u4F7F\u7528 Q \u52A9\u7406\u624B\u673A App \u626B\u63CF\u4E0B\u65B9\u4E8C\u7EF4\u7801\u3002",
11324
11332
  qrWaiting: "\u7B49\u5F85\u626B\u7801\u4E2D...",
11325
11333
  qrLoginSuccess: "\u767B\u5F55\u6210\u529F\uFF01",
11326
11334
  qrLoginSuccessWithName: "\u767B\u5F55\u6210\u529F\uFF01\u6B22\u8FCE\uFF0C{name}",
@@ -11348,12 +11356,13 @@ var commands2 = {
11348
11356
  user: {
11349
11357
  desc: "\u7528\u6237\u64CD\u4F5C",
11350
11358
  searchDesc: "\u641C\u7D22\u7528\u6237",
11351
- searchArgDesc: "\u67E5\u8BE2\u5185\u5BB9\uFF08\u9ED8\u8BA4\u6309 Q\u52A9\u53F7\uFF09",
11359
+ searchArgDesc: "\u67E5\u8BE2\u5185\u5BB9\uFF08\u9ED8\u8BA4\u6309 Q \u52A9\u53F7\uFF09",
11352
11360
  searchByUid: "\u6309 UID \u641C\u7D22",
11353
- addDesc: "\u901A\u8FC7 Q\u52A9\u53F7\u6DFB\u52A0\u597D\u53CB",
11354
- addArgDesc: "Q\u52A9\u53F7",
11355
- searchNotFound: "\u672A\u627E\u5230\u8BE5 Q\u52A9\u53F7\u7684\u7528\u6237\u3002",
11356
- addNoAgentId: "\u7528\u6237\u6CA1\u6709\u52A9\u7406ID\uFF0C\u65E0\u6CD5\u6DFB\u52A0\u3002",
11361
+ searchByQNumber: "\u6309 Q \u52A9\u53F7\u641C\u7D22",
11362
+ addDesc: "\u901A\u8FC7 Q \u52A9\u53F7\u6DFB\u52A0\u597D\u53CB",
11363
+ addArgDesc: "Q \u52A9\u53F7",
11364
+ searchNotFound: "\u672A\u627E\u5230\u8BE5 Q \u52A9\u53F7\u7684\u7528\u6237\u3002",
11365
+ addNoAgentId: "\u7528\u6237\u6CA1\u6709\u52A9\u7406 ID\uFF0C\u65E0\u6CD5\u6DFB\u52A0\u3002",
11357
11366
  addSuccess: "\u5DF2\u6DFB\u52A0\u597D\u53CB {name}\u3002"
11358
11367
  },
11359
11368
  friend: {
@@ -11363,6 +11372,7 @@ var commands2 = {
11363
11372
  profileArgDesc: "\u67E5\u8BE2\u5185\u5BB9\uFF08\u9ED8\u8BA4\u6309\u6635\u79F0\uFF09",
11364
11373
  profileByUid: "\u6309 UID \u641C\u7D22",
11365
11374
  profileByRemark: "\u6309\u5907\u6CE8\u641C\u7D22",
11375
+ profileByNickname: "\u6309\u6635\u79F0\u641C\u7D22",
11366
11376
  pageOption: "\u9875\u7801",
11367
11377
  pageSizeOption: "\u6BCF\u9875\u6570\u91CF",
11368
11378
  noFriends: "\u672A\u627E\u5230\u597D\u53CB\u6216\u8054\u7CFB\u4EBA\u3002",
@@ -11393,18 +11403,24 @@ var commands2 = {
11393
11403
  limitOption: "\u6700\u5927\u4F1A\u8BDD\u6570",
11394
11404
  offsetOption: "\u8DF3\u8FC7\u524D N \u6761\u4F1A\u8BDD",
11395
11405
  createDesc: "\u521B\u5EFA\u4F1A\u8BDD",
11396
- createArgDesc: "\u7528\u6237UID",
11397
- createAgentIdOption: "\u52A9\u7406ID",
11406
+ createArgDesc: "\u7528\u6237 UID",
11407
+ createAgentIdOption: "\u52A9\u7406 ID",
11398
11408
  createSuccess: "\u4F1A\u8BDD\u521B\u5EFA\u6210\u529F\u3002",
11399
11409
  profileDesc: "\u67E5\u8BE2\u4F1A\u8BDD\u8BE6\u60C5",
11400
- profileArgDesc: "\u4F1A\u8BDDID",
11401
- typeOption: "\u4F1A\u8BDD\u7C7B\u578B\uFF081=\u79C1\u804A, 2=\u7FA4\u804A\uFF0C\u4E0D\u4F20\u81EA\u52A8\u5224\u65AD\uFF09",
11410
+ profileArgDesc: "\u4F1A\u8BDD ID",
11411
+ typeOption: "\u4F1A\u8BDD\u7C7B\u578B\uFF081 = \u79C1\u804A, 2 = \u7FA4\u804A\uFF0C\u4E0D\u4F20\u81EA\u52A8\u5224\u65AD\uFF09",
11402
11412
  profileSuccess: "\u5DF2\u83B7\u53D6\u4F1A\u8BDD\u8BE6\u60C5\u3002",
11403
- searchDesc: "\u901A\u8FC7Q\u52A9\u53F7\u6216UID\u67E5\u627E\u4E0E\u67D0\u7528\u6237\u7684\u6240\u6709\u4F1A\u8BDD",
11404
- searchArgDesc: "\u67E5\u8BE2\u5185\u5BB9\uFF08\u9ED8\u8BA4\u6309 Q\u52A9\u53F7\uFF09",
11405
- searchByUid: "\u6309 UID \u641C\u7D22",
11413
+ searchDesc: "\u901A\u8FC7\u4F1A\u8BDD ID\u3001\u4F1A\u8BDD\u540D\u79F0\u6216\u7528\u6237\u67E5\u627E\u4F1A\u8BDD",
11414
+ searchArgDesc: "\u67E5\u8BE2\u5185\u5BB9\uFF08\u9ED8\u8BA4\u6309\u4F1A\u8BDD ID\uFF09",
11415
+ searchByQNumber: "\u6309\u7528\u6237 Q \u52A9\u53F7\u641C\u7D22",
11416
+ searchByUid: "\u6309\u7528\u6237 UID \u641C\u7D22",
11417
+ searchByName: "\u6309\u4F1A\u8BDD\u540D\u79F0\u641C\u7D22",
11418
+ searchByCid: "\u6309\u4F1A\u8BDD ID \u641C\u7D22",
11406
11419
  searchNotFound: "\u672A\u627E\u5230\u4E0E {name} \u7684\u4F1A\u8BDD\u3002",
11407
- searchSuccess: "\u627E\u5230\u4E0E {name} \u7684 {count} \u4E2A\u4F1A\u8BDD\u3002"
11420
+ searchSuccess: "\u627E\u5230\u4E0E {name} \u7684 {count} \u4E2A\u4F1A\u8BDD\u3002",
11421
+ searchByIdSuccess: "\u627E\u5230\u4F1A\u8BDD {id}\u3002",
11422
+ searchByNameNotFound: '\u672A\u627E\u5230\u540D\u79F0\u5305\u542B "{name}" \u7684\u4F1A\u8BDD\u3002',
11423
+ searchByNameSuccess: '\u627E\u5230 {count} \u4E2A\u540D\u79F0\u5305\u542B "{name}" \u7684\u4F1A\u8BDD\u3002'
11408
11424
  },
11409
11425
  cache: {
11410
11426
  desc: "\u7BA1\u7406\u672C\u5730\u7F13\u5B58",
@@ -12557,7 +12573,96 @@ function profileToItem(profile) {
12557
12573
  };
12558
12574
  }
12559
12575
  async function conversationSearchRun(factory, opts) {
12560
- const userResult = opts.byUid ? await factory.repos.user.findUserById(opts.query) : await factory.repos.user.searchUserById(opts.query);
12576
+ if (opts.byCid || !opts.byQNumber && !opts.byUid && !opts.byName) {
12577
+ return searchByConversationId(factory, opts.query);
12578
+ }
12579
+ if (opts.byQNumber) {
12580
+ return searchByQNumber(factory, opts.query);
12581
+ }
12582
+ if (opts.byUid) {
12583
+ return searchByUid(factory, opts.query);
12584
+ }
12585
+ return searchByName(factory, opts.query);
12586
+ }
12587
+ async function searchByConversationId(factory, conversationId) {
12588
+ const profileResult = await factory.repos.conversation.getProfile(conversationId);
12589
+ if (!profileResult.ok) {
12590
+ return {
12591
+ status: "error",
12592
+ code: profileResult.code,
12593
+ message: profileResult.code === "AUTH_FAILED" /* AUTH_FAILED */ ? t("auth.notAuthenticated") : profileResult.message,
12594
+ data: null
12595
+ };
12596
+ }
12597
+ const profile = profileToItem(profileResult.data);
12598
+ const firstUser = profile.users[0];
12599
+ if (!firstUser) {
12600
+ return {
12601
+ status: "success",
12602
+ code: "NOT_FOUND" /* NOT_FOUND */,
12603
+ message: t("commands.conversation.searchNotFound"),
12604
+ data: null
12605
+ };
12606
+ }
12607
+ const result = {
12608
+ id: firstUser.id,
12609
+ uid: firstUser.uid,
12610
+ nickname: firstUser.nickname,
12611
+ conversations: [profile]
12612
+ };
12613
+ return {
12614
+ status: "success",
12615
+ code: "CONVERSATION_LIST" /* CONVERSATION_LIST */,
12616
+ message: t("commands.conversation.searchByIdSuccess").replace("{id}", conversationId),
12617
+ data: result
12618
+ };
12619
+ }
12620
+ async function searchByQNumber(factory, qNumber) {
12621
+ const userResult = await factory.repos.user.searchUserById(qNumber);
12622
+ if (!userResult.ok) {
12623
+ return {
12624
+ status: "error",
12625
+ code: userResult.code,
12626
+ message: userResult.code === "AUTH_FAILED" /* AUTH_FAILED */ ? t("auth.notAuthenticated") : userResult.message,
12627
+ data: null
12628
+ };
12629
+ }
12630
+ if (!userResult.data) {
12631
+ return {
12632
+ status: "error",
12633
+ code: "USER_NOT_FOUND_NEEDS_RESOLUTION" /* USER_NOT_FOUND_NEEDS_RESOLUTION */,
12634
+ message: t("messages.notFound"),
12635
+ data: null
12636
+ };
12637
+ }
12638
+ const targetId = userResult.data.id;
12639
+ const targetUid = userResult.data.uid;
12640
+ const nickname = userResult.data.nickname;
12641
+ const profilesResult = await factory.repos.conversation.searchByUid(targetUid);
12642
+ if (!profilesResult.ok || profilesResult.data.length === 0) {
12643
+ return {
12644
+ status: "success",
12645
+ code: "NOT_FOUND" /* NOT_FOUND */,
12646
+ message: t("commands.conversation.searchNotFound").replace("{name}", nickname),
12647
+ data: null
12648
+ };
12649
+ }
12650
+ const results = profilesResult.data.map(profileToItem);
12651
+ const result = {
12652
+ id: targetId,
12653
+ uid: targetUid,
12654
+ nickname,
12655
+ conversations: results
12656
+ };
12657
+ return {
12658
+ status: "success",
12659
+ code: "CONVERSATION_LIST" /* CONVERSATION_LIST */,
12660
+ message: t("commands.conversation.searchSuccess").replace("{name}", nickname).replace("{count}", String(results.length)),
12661
+ data: result
12662
+ };
12663
+ }
12664
+ async function searchByUid(factory, uid) {
12665
+ const userResult = await factory.repos.user.findUserById(uid);
12561
12666
  if (!userResult.ok) {
12562
12667
  return {
12563
12668
  status: "error",
@@ -12600,6 +12705,72 @@ async function conversationSearchRun(factory, opts) {
12600
12705
  data: result
12601
12706
  };
12602
12707
  }
12708
+ async function searchByName(factory, name) {
12709
+ const listResult = await factory.repos.conversation.queryAll({ limit: 0, offset: 0 });
12710
+ if (!listResult.ok) {
12711
+ return {
12712
+ status: "error",
12713
+ code: listResult.code,
12714
+ message: listResult.code === "AUTH_FAILED" /* AUTH_FAILED */ ? t("auth.notAuthenticated") : listResult.message,
12715
+ data: null
12716
+ };
12717
+ }
12718
+ const conversations3 = listResult.data ?? [];
12719
+ const matchedIds = conversations3.filter((c) => c.name?.includes(name)).map((c) => c.id);
12720
+ if (matchedIds.length === 0) {
12721
+ return {
12722
+ status: "success",
12723
+ code: "NOT_FOUND" /* NOT_FOUND */,
12724
+ message: t("commands.conversation.searchByNameNotFound").replace("{name}", name),
12725
+ data: null
12726
+ };
12727
+ }
12728
+ const profileResults = await Promise.all(
12729
+ matchedIds.map((convId) => factory.repos.conversation.getProfile(convId))
12730
+ );
12731
+ const profiles = profileResults.filter((r) => r.ok).map((r) => r.data);
12732
+ if (profiles.length === 0) {
12733
+ return {
12734
+ status: "success",
12735
+ code: "NOT_FOUND" /* NOT_FOUND */,
12736
+ message: t("commands.conversation.searchByNameNotFound").replace("{name}", name),
12737
+ data: null
12738
+ };
12739
+ }
12740
+ const items = profiles.map(profileToItem);
12741
+ const groupedByUid = /* @__PURE__ */ new Map();
12742
+ for (const item of items) {
12743
+ const primaryUser = item.users[0];
12744
+ if (!primaryUser) continue;
12745
+ const uid = primaryUser.uid;
12746
+ const existing = groupedByUid.get(uid);
12747
+ if (existing) {
12748
+ existing.conversations.push(item);
12749
+ } else {
12750
+ groupedByUid.set(uid, {
12751
+ id: primaryUser.id,
12752
+ uid,
12753
+ nickname: primaryUser.nickname,
12754
+ conversations: [item]
12755
+ });
12756
+ }
12757
+ }
12758
+ const results = [...groupedByUid.values()];
12759
+ if (results.length === 0) {
12760
+ return {
12761
+ status: "success",
12762
+ code: "NOT_FOUND" /* NOT_FOUND */,
12763
+ message: t("commands.conversation.searchByNameNotFound").replace("{name}", name),
12764
+ data: null
12765
+ };
12766
+ }
12767
+ return {
12768
+ status: "success",
12769
+ code: "CONVERSATION_LIST" /* CONVERSATION_LIST */,
12770
+ message: t("commands.conversation.searchByNameSuccess").replace("{name}", name).replace("{count}", String(results.length)),
12771
+ data: results
12772
+ };
12773
+ }
12603
12774
 
12604
12775
  // src/commands/conversation/index.ts
12605
12776
  function NewCmdConversation(factory) {
@@ -12622,10 +12793,18 @@ function NewCmdConversation(factory) {
12622
12793
  const result = await conversationCreateRun(factory, { uid, agentId: opts.agentId });
12623
12794
  handleCommand(result);
12624
12795
  });
12625
- cmd.command("search").description(t("commands.conversation.searchDesc")).argument("<query>", t("commands.conversation.searchArgDesc")).option("--uid", t("commands.conversation.searchByUid")).action(async (query, opts) => {
12626
- const result = await conversationSearchRun(factory, { query, byUid: opts.uid });
12627
- handleCommand(result);
12628
- });
12796
+ cmd.command("search").description(t("commands.conversation.searchDesc")).argument("<query>", t("commands.conversation.searchArgDesc")).option("--qnumber", t("commands.conversation.searchByQNumber")).option("--uid", t("commands.conversation.searchByUid")).option("--name", t("commands.conversation.searchByName")).option("--cid", t("commands.conversation.searchByCid")).action(
12797
+ async (query, opts) => {
12798
+ const result = await conversationSearchRun(factory, {
12799
+ query,
12800
+ byQNumber: opts.qnumber,
12801
+ byUid: opts.uid,
12802
+ byName: opts.name,
12803
+ byCid: opts.cid
12804
+ });
12805
+ handleCommand(result);
12806
+ }
12807
+ );
12629
12808
  return cmd;
12630
12809
  }
12631
12810
 
@@ -12789,14 +12968,17 @@ function NewCmdFriend(factory) {
12789
12968
  const result = await friendListRun(factory);
12790
12969
  handleCommand(result);
12791
12970
  });
12792
- cmd.command("profile").description(t("commands.friend.profileDesc")).argument("<query>", t("commands.friend.profileArgDesc")).option("--uid", t("commands.friend.profileByUid")).option("--remark", t("commands.friend.profileByRemark")).action(async (query, opts) => {
12793
- const result = await friendProfileRun(factory, {
12794
- query,
12795
- byUid: opts.uid,
12796
- byRemark: opts.remark
12797
- });
12798
- handleCommand(result);
12799
- });
12971
+ cmd.command("profile").description(t("commands.friend.profileDesc")).argument("<query>", t("commands.friend.profileArgDesc")).option("--uid", t("commands.friend.profileByUid")).option("--remark", t("commands.friend.profileByRemark")).option("--nickname", t("commands.friend.profileByNickname")).action(
12972
+ async (query, opts) => {
12973
+ const result = await friendProfileRun(factory, {
12974
+ query,
12975
+ byUid: opts.uid,
12976
+ byRemark: opts.remark,
12977
+ byNickname: opts.nickname
12978
+ });
12979
+ handleCommand(result);
12980
+ }
12981
+ );
12800
12982
  return cmd;
12801
12983
  }
12802
12984
 
@@ -13065,8 +13247,12 @@ async function userSearchRun(factory, opts) {
13065
13247
  // src/commands/user/index.ts
13066
13248
  function NewCmdUser(factory) {
13067
13249
  const cmd = new import_commander8.Command("user").description(t("commands.user.desc"));
13068
- cmd.command("search").description(t("commands.user.searchDesc")).argument("<query>", t("commands.user.searchArgDesc")).option("--uid", t("commands.user.searchByUid")).action(async (query, opts) => {
13069
- const result = await userSearchRun(factory, { query, byUid: opts.uid });
13250
+ cmd.command("search").description(t("commands.user.searchDesc")).argument("<query>", t("commands.user.searchArgDesc")).option("--uid", t("commands.user.searchByUid")).option("--qnumber", t("commands.user.searchByQNumber")).action(async (query, opts) => {
13251
+ const result = await userSearchRun(factory, {
13252
+ query,
13253
+ byUid: opts.uid,
13254
+ byQNumber: opts.qnumber
13255
+ });
13070
13256
  handleCommand(result);
13071
13257
  });
13072
13258
  cmd.command("add").description(t("commands.user.addDesc")).argument("<q-number>", t("commands.user.addArgDesc")).action(async (qNumber) => {
@@ -14921,7 +15107,7 @@ async function main() {
14921
15107
  ${t("cli.banner")}` : t("cli.banner");
14922
15108
  program.addHelpText("beforeAll", `${banner}
14923
15109
  `);
14924
- program.name("qz").version(`v${"0.5.1"}`, "-v, --version", t("options.version")).helpOption("-h, --help", t("options.help")).option("-q, --jq <expr>", t("options.jq")).option("--dry-run", t("options.dryRun"));
15110
+ program.name("qz").version(`v${"0.5.2"}`, "-v, --version", t("options.version")).helpOption("-h, --help", t("options.help")).option("-q, --jq <expr>", t("options.jq")).option("--dry-run", t("options.dryRun"));
14925
15111
  program.usage("<command> [subcommand] [options]");
14926
15112
  program.hook("preAction", () => {
14927
15113
  const opts = program.opts();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzhuli/qzhuli-cli",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "CLI tool for Q助理 (QZhuli)",
5
5
  "main": "dist/cmd.js",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: qzhuli-cli
3
3
  description: Use when operating the QZhuli CLI (`qz`), including login, auth status, config, friends, relations, users, conversations, messages, cache management, JSON filtering, dry-run, command help, and interpreting test-environment banners or config files.
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  ---
6
6
 
7
7
  # QZhuli CLI
@@ -62,12 +62,12 @@ When sending messages, determine the role based on the user's wording:
62
62
 
63
63
  The CLI uses 4 distinct ID types. **Using the wrong type will fail silently or hit the wrong target.**
64
64
 
65
- | ID Type | Field Name | Format | Example | Used By |
66
- |-----------------|------------------|-------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------|
67
- | Q助号 | `id` | Number, short | `10003` | `user add <q-number>`, `user search`, `conversation search` (default) |
68
- | UID | `uid` | 32-char hex string | `d5b6308e3abad6bc96573c58` | `relation get/set`, `friend profile --uid`, `user search --uid`, `conversation search --uid`, `conversation create` |
69
- | Conversation ID | `conversationId` | Base64-like long string | `9boGaR7iii2Jdjhmb5LSo37...` | `message send`, `message history`, `conversation profile` |
70
- | Agent ID | `agent.id` | Number | `5` | `conversation create --agent-id` |
65
+ | ID Type | Field Name | Format | Example | Used By |
66
+ |-----------------|------------------|-------------------------|------------------------------|--------------------------------------------------------------------------------------------|
67
+ | Q助号 | `id` | Number, short | `10003` | `user add <q-number>`, `user search`, `conversation search` (with `--qnumber`) |
68
+ | UID | `uid` | 32-char hex string | `d5b6308e3abad6bc96573c58` | `relation get/set`, `friend profile --uid`, `user search --uid`, `conversation create` |
69
+ | Conversation ID | `conversationId` | Base64-like long string | `9boGaR7iii2Jdjhmb5LSo37...` | `message send`, `message history`, `conversation profile`, `conversation search` (default) |
70
+ | Agent ID | `agent.id` | Number | `5` | `conversation create --agent-id` |
71
71
 
72
72
  **Common mistake**: Using UID for `message send` instead of conversationId. Always resolve via `conversation search` or
73
73
  `conversation list` first.
@@ -105,32 +105,36 @@ qz --jq ".data" conversation list --limit 5
105
105
 
106
106
  ## Command Map
107
107
 
108
- | Goal | Command |
109
- |----------------------------|-----------------------------------------------------------------------------------------------|
110
- | Check login | `qz auth status` |
111
- | QR login | `qz auth login [--method qr-code]` |
112
- | Clear credentials | `qz auth logout` |
113
- | Show preferences | `qz config` |
114
- | Update preferences | `qz config [--locale en\|zh] [--debug\|--no-debug]` |
115
- | Search user (Q助号) | `qz user search <q-number>` |
116
- | Search user (UID) | `qz user search <uid> --uid` |
117
- | Add friend (Q助号) | `qz user add <q-number>` |
118
- | List friends | `qz friend list` |
119
- | Resolve profile (nickname) | `qz friend profile <nickname>` |
120
- | Resolve profile (UID) | `qz friend profile <uid> --uid` |
121
- | Resolve profile (remark) | `qz friend profile <remark> --remark` |
122
- | Read relation | `qz relation get <uid>` |
123
- | Update relation | `qz relation set <uid> [-r, --remark <name>] [-t, --type <type>]` |
124
- | List conversations | `qz conversation list [--limit <n>] [--offset <n>]` |
125
- | Get conversation profile | `qz conversation profile <conversation-id> [--type <n>]` |
126
- | Create conversation | `qz conversation create <uid> --agent-id <id>` |
127
- | Search conversations (Q助号) | `qz conversation search <q-number>` |
128
- | Search conversations (UID) | `qz conversation search <uid> --uid` |
129
- | Send message | `qz message send <conversation-id> <content> [--role <n>]` |
130
- | Read message history | `qz message history <conversation-id> [--from <id>] [--direction newer\|older] [--limit <n>]` |
131
- | Sync cache | `qz cache sync` |
132
- | Cache status | `qz cache status` |
133
- | Clear cache | `qz cache clear [--table <name>]` |
108
+ | Goal | Command |
109
+ |--------------------------------------|-----------------------------------------------------------------------------------------------|
110
+ | Check login | `qz auth status` |
111
+ | QR login | `qz auth login [--method qr-code]` |
112
+ | Clear credentials | `qz auth logout` |
113
+ | Show preferences | `qz config` |
114
+ | Update preferences | `qz config [--locale en\|zh] [--debug\|--no-debug]` |
115
+ | Search user (Q助号) | `qz user search <q-number>` |
116
+ | Search user (Q助号, explicit) | `qz user search <q-number> --qnumber` |
117
+ | Search user (UID) | `qz user search <uid> --uid` |
118
+ | Add friend (Q助号) | `qz user add <q-number>` |
119
+ | List friends | `qz friend list` |
120
+ | Resolve profile (nickname) | `qz friend profile <nickname>` |
121
+ | Resolve profile (nickname, explicit) | `qz friend profile <nickname> --nickname` |
122
+ | Resolve profile (UID) | `qz friend profile <uid> --uid` |
123
+ | Resolve profile (remark) | `qz friend profile <remark> --remark` |
124
+ | Read relation | `qz relation get <uid>` |
125
+ | Update relation | `qz relation set <uid> [-r, --remark <name>] [-t, --type <type>]` |
126
+ | List conversations | `qz conversation list [--limit <n>] [--offset <n>]` |
127
+ | Get conversation profile | `qz conversation profile <conversation-id> [--type <n>]` |
128
+ | Create conversation | `qz conversation create <uid> --agent-id <id>` |
129
+ | Search conversations (ID) | `qz conversation search <conversation-id>` |
130
+ | Search conversations (name) | `qz conversation search <name> --name` |
131
+ | Search conversations (Q助号) | `qz conversation search <q-number> --qnumber` |
132
+ | Search conversations (UID) | `qz conversation search <uid> --uid` |
133
+ | Send message | `qz message send <conversation-id> <content> [--role <n>]` |
134
+ | Read message history | `qz message history <conversation-id> [--from <id>] [--direction newer\|older] [--limit <n>]` |
135
+ | Sync cache | `qz cache sync` |
136
+ | Cache status | `qz cache status` |
137
+ | Clear cache | `qz cache clear [--table <name>]` |
134
138
 
135
139
  Relation type values: `0=stranger`, `1=friend`, `2=family`, `3=colleague`.
136
140
 
@@ -160,8 +164,10 @@ Relation type values: `0=stranger`, `1=friend`, `2=family`, `3=colleague`.
160
164
  ### Find All Conversations with a User
161
165
 
162
166
  ```bash
163
- qz conversation search <q-number>
164
- qz conversation search <uid> --uid
167
+ qz conversation search <conversation-id> # default: by conversation ID
168
+ qz conversation search <name> --name # by conversation name
169
+ qz conversation search <q-number> --qnumber # by user Q助号
170
+ qz conversation search <uid> --uid # by user UID
165
171
  ```
166
172
 
167
173
  Response includes `id`, `uid`, and `conversations` with full profile data. Each entry contains `conversationId`,
@@ -170,8 +176,9 @@ Response includes `id`, `uid`, and `conversations` with full profile data. Each
170
176
  ### Send a Message
171
177
 
172
178
  1. Confirm auth: `qz auth status`
173
- 2. **Check existing conversation**: Use `conversation search <q-number>` or `conversation search <uid> --uid` to find
174
- conversations with the target user.
179
+ 2. **Check existing conversation**: If you have a `conversationId`, use `conversation search <conversation-id>`
180
+ directly. Otherwise, use `conversation search <q-number> --qnumber`, `conversation search <uid> --uid`,
181
+ or `conversation search <name> --name` to find conversations with the target user.
175
182
  3. **Decision**:
176
183
  - If conversations exist → pick the relevant `conversationId`.
177
184
  - If no conversation exists → **ask the user first** whether to create one, then