openzca 0.1.16 → 0.1.17

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 (3) hide show
  1. package/README.md +3 -8
  2. package/dist/cli.js +98 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,13 +1,8 @@
1
1
  # openzca
2
2
 
3
- Free and open-source CLI for Zalo, built on [zca-js](https://github.com/nicenathapong/zca-js). Command structure compatible with [zca-cli.dev/docs](https://zca-cli.dev/docs).
3
+ Free and open-source CLI for Zalo, built on [zca-js](https://github.com/RFS-ADRENO/zca-js). Command structure compatible with [zca-cli.dev/docs](https://zca-cli.dev/docs).
4
4
 
5
- ## Integrate with OpenClaw ZaloUser plugin
6
-
7
- Prompt:
8
- ```
9
- help me to enable zalouser openclaw plugin. However, don't install zca cli follow their instruction, please use: npm install -g openzca@latest
10
- ```
5
+ ## Integrate with OpenClaw OpenZalo plugin (including legacy `zalouser`)
11
6
 
12
7
 
13
8
  ## Install
@@ -296,7 +291,7 @@ Supervised mode notes:
296
291
 
297
292
  ## Multi-account profiles
298
293
 
299
- Use `--profile <name>` or set `ZCA_PROFILE=<name>` to switch between accounts. Manage profiles with the `account` commands.
294
+ Use `--profile <name>` or set `OPENZCA_PROFILE=<name>` (or legacy `ZCA_PROFILE=<name>`) to switch between accounts. Manage profiles with the `account` commands.
300
295
 
301
296
  Profile data is stored in `~/.openzca/` (override with `OPENZCA_HOME`):
302
297
 
package/dist/cli.js CHANGED
@@ -164,7 +164,7 @@ async function removeProfile(name) {
164
164
  }
165
165
  async function resolveProfileName(flagProfile) {
166
166
  const db = await ensureProfilesDb();
167
- const picked = flagProfile && flagProfile.trim() || process.env.ZCA_PROFILE && process.env.ZCA_PROFILE.trim() || db.defaultProfile || DEFAULT_PROFILE;
167
+ const picked = flagProfile && flagProfile.trim() || (process.env.OPENZCA_PROFILE?.trim() || process.env.ZCA_PROFILE?.trim()) || db.defaultProfile || DEFAULT_PROFILE;
168
168
  if (!db.profiles[picked]) {
169
169
  if (picked === DEFAULT_PROFILE) {
170
170
  await ensureProfile(DEFAULT_PROFILE);
@@ -765,7 +765,7 @@ async function currentProfile(_command) {
765
765
  async function profileForLogin() {
766
766
  const opts = program.opts();
767
767
  const explicit = opts.profile?.trim();
768
- const fromEnv = process.env.ZCA_PROFILE?.trim();
768
+ const fromEnv = process.env.OPENZCA_PROFILE?.trim() || process.env.ZCA_PROFILE?.trim();
769
769
  if (explicit) {
770
770
  await ensureProfile(explicit);
771
771
  return explicit;
@@ -1653,7 +1653,7 @@ program.hook("preAction", (_parent, actionCommand) => {
1653
1653
  argv: process.argv.slice(2),
1654
1654
  cwd: process.cwd(),
1655
1655
  profileFlag: getDebugOptions(actionCommand).profile ?? null,
1656
- envProfile: process.env.ZCA_PROFILE ?? null
1656
+ envProfile: process.env.OPENZCA_PROFILE ?? process.env.ZCA_PROFILE ?? null
1657
1657
  },
1658
1658
  actionCommand
1659
1659
  );
@@ -2082,6 +2082,32 @@ msg.command("undo <msgId> <cliMsgId> <threadId>").option("-g, --group", "Undo in
2082
2082
  }
2083
2083
  )
2084
2084
  );
2085
+ msg.command("edit <msgId> <cliMsgId> <threadId> <message>").option("-g, --group", "Edit in group").description("Edit message (compatibility shim: recall old message then resend new text)").action(
2086
+ wrapAction(
2087
+ async (msgId, cliMsgId, threadId, message, opts, command) => {
2088
+ const { api } = await requireApi(command);
2089
+ const type = asThreadType(opts.group);
2090
+ const undoResponse = await api.undo(
2091
+ {
2092
+ msgId,
2093
+ cliMsgId
2094
+ },
2095
+ threadId,
2096
+ type
2097
+ );
2098
+ const sendResponse = await api.sendMessage(message, threadId, type);
2099
+ output(
2100
+ {
2101
+ mode: "undo+send",
2102
+ nativeEditSupported: false,
2103
+ undo: undoResponse,
2104
+ send: sendResponse
2105
+ },
2106
+ false
2107
+ );
2108
+ }
2109
+ )
2110
+ );
2085
2111
  msg.command("upload <arg1> [arg2]").option("-u, --url <url>", "File URL (repeatable)", collectValues, []).option("-g, --group", "Upload in group").description("Upload and send file(s)").action(
2086
2112
  wrapAction(
2087
2113
  async (arg1, arg2, opts, command) => {
@@ -2164,6 +2190,75 @@ msg.command("recent <threadId>").option("-g, --group", "List recent messages for
2164
2190
  }
2165
2191
  )
2166
2192
  );
2193
+ msg.command("pin <threadId>").option("-g, --group", "Pin group conversation").description("Pin conversation").action(
2194
+ wrapAction(async (threadId, opts, command) => {
2195
+ const { api } = await requireApi(command);
2196
+ const type = asThreadType(opts.group);
2197
+ const response = await api.setPinnedConversations(true, threadId, type);
2198
+ output(
2199
+ {
2200
+ threadId,
2201
+ threadType: type === ThreadType.Group ? "group" : "user",
2202
+ pinned: true,
2203
+ response
2204
+ },
2205
+ false
2206
+ );
2207
+ })
2208
+ );
2209
+ msg.command("unpin <threadId>").option("-g, --group", "Unpin group conversation").description("Unpin conversation").action(
2210
+ wrapAction(async (threadId, opts, command) => {
2211
+ const { api } = await requireApi(command);
2212
+ const type = asThreadType(opts.group);
2213
+ const response = await api.setPinnedConversations(false, threadId, type);
2214
+ output(
2215
+ {
2216
+ threadId,
2217
+ threadType: type === ThreadType.Group ? "group" : "user",
2218
+ pinned: false,
2219
+ response
2220
+ },
2221
+ false
2222
+ );
2223
+ })
2224
+ );
2225
+ msg.command("list-pins").option("-j, --json", "JSON output").description("List pinned conversations").action(
2226
+ wrapAction(async (opts, command) => {
2227
+ const { api } = await requireApi(command);
2228
+ const response = await api.getPinConversations();
2229
+ if (opts.json) {
2230
+ output(response, true);
2231
+ return;
2232
+ }
2233
+ output(
2234
+ response.conversations.map((threadId) => ({
2235
+ threadId,
2236
+ pinned: true
2237
+ })),
2238
+ false
2239
+ );
2240
+ })
2241
+ );
2242
+ msg.command("member-info <userId>").option("-j, --json", "JSON output").description("Get member/user profile info").action(
2243
+ wrapAction(async (userId, opts, command) => {
2244
+ const { api } = await requireApi(command);
2245
+ const response = await api.getUserInfo(userId);
2246
+ if (opts.json) {
2247
+ output(response, true);
2248
+ return;
2249
+ }
2250
+ const profiles = response.changed_profiles ?? {};
2251
+ const matchedProfile = profiles[userId] ?? profiles[`${userId}_0`] ?? Object.values(profiles)[0] ?? null;
2252
+ output(
2253
+ {
2254
+ userId,
2255
+ found: Boolean(matchedProfile),
2256
+ profile: matchedProfile
2257
+ },
2258
+ false
2259
+ );
2260
+ })
2261
+ );
2167
2262
  var group = program.command("group").description("Group management");
2168
2263
  group.command("list").option("-j, --json", "JSON output").description("List groups").action(
2169
2264
  wrapAction(async (opts, command) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzca",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Open-source zca-compatible CLI to integrate Zalo with OpenClaw",
5
5
  "type": "module",
6
6
  "bin": {