@nocoo/zhe 1.19.3 → 1.24.1

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 (106) hide show
  1. package/README.md +31 -0
  2. package/dist/api/client.d.ts +12 -2
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.js +32 -11
  5. package/dist/api/client.js.map +1 -1
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/commands/connector.d.ts +2 -0
  8. package/dist/commands/connector.d.ts.map +1 -0
  9. package/dist/commands/connector.js +103 -0
  10. package/dist/commands/connector.js.map +1 -0
  11. package/dist/commands/create.d.ts.map +1 -1
  12. package/dist/commands/create.js +1 -1
  13. package/dist/commands/create.js.map +1 -1
  14. package/dist/commands/delete.js +1 -1
  15. package/dist/commands/delete.js.map +1 -1
  16. package/dist/commands/folder.d.ts.map +1 -1
  17. package/dist/commands/folder.js +1 -1
  18. package/dist/commands/folder.js.map +1 -1
  19. package/dist/commands/folders.js +1 -1
  20. package/dist/commands/folders.js.map +1 -1
  21. package/dist/commands/get.js +1 -1
  22. package/dist/commands/get.js.map +1 -1
  23. package/dist/commands/idea/add.d.ts.map +1 -1
  24. package/dist/commands/idea/add.js +1 -1
  25. package/dist/commands/idea/add.js.map +1 -1
  26. package/dist/commands/idea/delete.js +1 -1
  27. package/dist/commands/idea/delete.js.map +1 -1
  28. package/dist/commands/idea/get.d.ts.map +1 -1
  29. package/dist/commands/idea/get.js +2 -2
  30. package/dist/commands/idea/get.js.map +1 -1
  31. package/dist/commands/idea/helpers.d.ts.map +1 -1
  32. package/dist/commands/idea/helpers.js +1 -1
  33. package/dist/commands/idea/helpers.js.map +1 -1
  34. package/dist/commands/idea/list.d.ts.map +1 -1
  35. package/dist/commands/idea/list.js +2 -2
  36. package/dist/commands/idea/list.js.map +1 -1
  37. package/dist/commands/idea/update.d.ts.map +1 -1
  38. package/dist/commands/idea/update.js +1 -1
  39. package/dist/commands/idea/update.js.map +1 -1
  40. package/dist/commands/idea.js +1 -1
  41. package/dist/commands/idea.js.map +1 -1
  42. package/dist/commands/inbox.js +1 -1
  43. package/dist/commands/inbox.js.map +1 -1
  44. package/dist/commands/list.d.ts.map +1 -1
  45. package/dist/commands/list.js +3 -4
  46. package/dist/commands/list.js.map +1 -1
  47. package/dist/commands/login.d.ts.map +1 -1
  48. package/dist/commands/login.js +3 -3
  49. package/dist/commands/login.js.map +1 -1
  50. package/dist/commands/logout.js +1 -1
  51. package/dist/commands/logout.js.map +1 -1
  52. package/dist/commands/open.js +1 -1
  53. package/dist/commands/open.js.map +1 -1
  54. package/dist/commands/tag.d.ts.map +1 -1
  55. package/dist/commands/tag.js +1 -1
  56. package/dist/commands/tag.js.map +1 -1
  57. package/dist/commands/tags.js +1 -1
  58. package/dist/commands/tags.js.map +1 -1
  59. package/dist/commands/update.d.ts.map +1 -1
  60. package/dist/commands/update.js +1 -1
  61. package/dist/commands/update.js.map +1 -1
  62. package/dist/config.d.ts +1 -1
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +1 -1
  65. package/dist/config.js.map +1 -1
  66. package/dist/connector/core.d.ts +64 -0
  67. package/dist/connector/core.d.ts.map +1 -0
  68. package/dist/connector/core.js +237 -0
  69. package/dist/connector/core.js.map +1 -0
  70. package/dist/connector/dns.d.ts +3 -0
  71. package/dist/connector/dns.d.ts.map +1 -0
  72. package/dist/connector/dns.js +92 -0
  73. package/dist/connector/dns.js.map +1 -0
  74. package/dist/connector/download.d.ts +5 -0
  75. package/dist/connector/download.d.ts.map +1 -0
  76. package/dist/connector/download.js +190 -0
  77. package/dist/connector/download.js.map +1 -0
  78. package/dist/connector/log.d.ts +24 -0
  79. package/dist/connector/log.d.ts.map +1 -0
  80. package/dist/connector/log.js +145 -0
  81. package/dist/connector/log.js.map +1 -0
  82. package/dist/connector/opencli.d.ts +6 -0
  83. package/dist/connector/opencli.d.ts.map +1 -0
  84. package/dist/connector/opencli.js +136 -0
  85. package/dist/connector/opencli.js.map +1 -0
  86. package/dist/connector/runtime.d.ts +13 -0
  87. package/dist/connector/runtime.d.ts.map +1 -0
  88. package/dist/connector/runtime.js +179 -0
  89. package/dist/connector/runtime.js.map +1 -0
  90. package/dist/connector/types.d.ts +42 -0
  91. package/dist/connector/types.d.ts.map +1 -0
  92. package/dist/connector/types.js +2 -0
  93. package/dist/connector/types.js.map +1 -0
  94. package/dist/index.js +3 -1
  95. package/dist/index.js.map +1 -1
  96. package/dist/utils/format.d.ts.map +1 -1
  97. package/dist/utils/format.js.map +1 -1
  98. package/dist/utils/resolve.d.ts.map +1 -1
  99. package/dist/utils/resolve.js +1 -1
  100. package/dist/utils/resolve.js.map +1 -1
  101. package/dist/utils.d.ts.map +1 -1
  102. package/dist/utils.js +1 -1
  103. package/dist/utils.js.map +1 -1
  104. package/dist/version.d.ts.map +1 -1
  105. package/dist/version.js.map +1 -1
  106. package/package.json +13 -7
@@ -0,0 +1,24 @@
1
+ import type { PollResult } from "./runtime.js";
2
+ import type { ConnectorProgress, ConnectorStatus } from "./types.js";
3
+ /** Only known codes become log text; upstream errors may contain cookies or response bodies. */
4
+ export declare function connectorErrorHint(error: unknown): string;
5
+ export declare class ConnectorLogger {
6
+ private json;
7
+ private started;
8
+ private lastProgress;
9
+ private active?;
10
+ private queueSnapshot;
11
+ private totalMedia;
12
+ private stats;
13
+ constructor(json?: boolean);
14
+ private write;
15
+ start(): void;
16
+ queue(status: ConnectorStatus): void;
17
+ progress: (event: ConnectorProgress) => void;
18
+ tick(): void;
19
+ result(result: PollResult, durationMs: number, watching?: boolean): void;
20
+ offline(error: unknown): void;
21
+ private summary;
22
+ stop(): void;
23
+ }
24
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/connector/log.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0BrE,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUzD;AAED,qBAAa,eAAe;IAiBd,OAAO,CAAC,IAAI;IAhBxB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,MAAM,CAAC,CAAoB;IACnC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,KAAK,CASX;IAEF,YAAoB,IAAI,UAAQ,EAAI;IAEpC,OAAO,CAAC,KAAK;IAkBb,KAAK,SAKJ;IAED,KAAK,CAAC,MAAM,EAAE,eAAe,QAU5B;IAED,QAAQ,UAAW,iBAAiB,UAclC;IAEF,IAAI,SAMH;IAED,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,UAAQ,QAkB9D;IAED,OAAO,CAAC,KAAK,EAAE,OAAO,QAOrB;IAED,OAAO,CAAC,OAAO;IAKf,IAAI,SAMH;CACF"}
@@ -0,0 +1,145 @@
1
+ import { formatDuration, formatSize, pc } from "@nocoo/base-cli";
2
+ import { ApiClientError } from "../api/client.js";
3
+ import { CLI_VERSION } from "../version.js";
4
+ import { ConnectorError } from "./core.js";
5
+ const fallbackHint = "Connector processing failed. Check the connection and retry.";
6
+ const hints = {
7
+ 0: "Cannot reach Zhe. Check the network connection.",
8
+ 401: "API Key missing, invalid or revoked. Run `zhe login` with a valid key.",
9
+ 403: "Connector permission missing or expired. Use a key with `connector:write` created within 30 days.",
10
+ 409: "This job's lease is no longer valid; it will not be overwritten.",
11
+ 429: "API rate limit reached. Waiting before the next poll.",
12
+ needs_login: "Connect the OpenCLI browser extension and sign in to X.",
13
+ opencli_unavailable: "OpenCLI is unavailable. Check its browser extension and connection.",
14
+ unsupported_opencli_version: "OpenCLI version mismatch. Reinstall the Zhe CLI dependencies.",
15
+ adapter_contract_changed: "OpenCLI adapter changed. Update the Zhe CLI.",
16
+ post_unavailable: "The saved X post is unavailable or protected.",
17
+ invalid_post_id: "The saved X post ID is invalid.",
18
+ invalid_media: "Media has an unsupported type or exceeds the size limit.",
19
+ decode_failed: "Media verification failed. Check FFmpeg and ffprobe are installed.",
20
+ download_failed: "Media download failed. The saved text is retained for retry.",
21
+ size_mismatch: "Media download was incomplete or its size changed.",
22
+ unsafe_redirect: "The media redirect could not be verified.",
23
+ unsafe_media_address: "The media address could not be verified.",
24
+ media_dns_unavailable: "Media DNS lookup failed. Check the network connection.",
25
+ interrupted: "Processing interrupted; unfinished work can be retried.",
26
+ connector_error: fallbackHint,
27
+ };
28
+ /** Only known codes become log text; upstream errors may contain cookies or response bodies. */
29
+ export function connectorErrorHint(error) {
30
+ const code = error instanceof ApiClientError
31
+ ? error.status
32
+ : error instanceof ConnectorError
33
+ ? error.code
34
+ : error;
35
+ return (typeof code === "string" || typeof code === "number") && typeof hints[code] === "string"
36
+ ? hints[code]
37
+ : fallbackHint;
38
+ }
39
+ export class ConnectorLogger {
40
+ json;
41
+ started = Date.now();
42
+ lastProgress = Date.now();
43
+ active;
44
+ queueSnapshot = "";
45
+ totalMedia = 0;
46
+ stats = {
47
+ complete: 0,
48
+ partial: 0,
49
+ failed: 0,
50
+ interrupted: 0,
51
+ media: 0,
52
+ skipped: 0,
53
+ bytes: 0,
54
+ errors: 0,
55
+ };
56
+ constructor(json = false) {
57
+ this.json = json;
58
+ }
59
+ write(event, message, fields = {}) {
60
+ const time = new Date();
61
+ if (this.json) {
62
+ console.log(JSON.stringify({ time: time.toISOString(), event, message, ...fields }));
63
+ return;
64
+ }
65
+ const color = ["failed", "offline"].includes(event)
66
+ ? pc.red
67
+ : ["warning", "partial", "interrupted"].includes(event)
68
+ ? pc.yellow
69
+ : ["complete", "uploaded", "saved"].includes(event)
70
+ ? pc.green
71
+ : pc.cyan;
72
+ console.log(`${pc.dim(time.toLocaleTimeString("en-GB", { hour12: false }))} ${color(event.toUpperCase().padEnd(11))} ${message}`);
73
+ }
74
+ start() {
75
+ this.write("ready", `Zhe · X Connector ${CLI_VERSION} · one job at a time · 20s between polls · Ctrl+C to stop`);
76
+ }
77
+ queue(status) {
78
+ const states = Object.fromEntries(status.states.map(({ state, count }) => [state, count]));
79
+ const snapshot = JSON.stringify([states, status.expiresAt]);
80
+ if (snapshot === this.queueSnapshot)
81
+ return;
82
+ this.queueSnapshot = snapshot;
83
+ this.write("queue", `${["pending", "running", "complete", "partial", "failed", "unavailable"].map((state) => `${states[state] ?? 0} ${state}`).join(" · ")} · key expires ${new Date(status.expiresAt).toISOString().slice(0, 10)}`, { states, expiresAt: status.expiresAt });
84
+ }
85
+ progress = (event) => {
86
+ this.active = event;
87
+ this.lastProgress = Date.now();
88
+ if (event.stage === "claim")
89
+ this.totalMedia = 0;
90
+ if (event.stage === "capture")
91
+ this.totalMedia = event.total ?? 0;
92
+ if (event.stage === "uploaded")
93
+ this.stats.bytes += event.bytes ?? 0;
94
+ if (event.stage === "skipped")
95
+ this.stats.skipped++;
96
+ let message = event.message;
97
+ if (event.stage === "download" && event.bytes) {
98
+ const percent = Math.min(100, Math.floor(((event.received ?? 0) / event.bytes) * 100));
99
+ const filled = Math.floor(percent / 10);
100
+ message += ` [${"━".repeat(filled)}${"·".repeat(10 - filled)}] ${percent}% · ${formatSize(event.received ?? 0)} / ${formatSize(event.bytes)}`;
101
+ }
102
+ else if (event.bytes)
103
+ message += ` · ${formatSize(event.bytes)}`;
104
+ this.write(event.stage, message, { ...event, message });
105
+ };
106
+ tick() {
107
+ if (!this.active || Date.now() - this.lastProgress < 10_000)
108
+ return;
109
+ this.write("working", `${this.active.stage}: ${this.active.message} · still running (${formatDuration(Date.now() - this.lastProgress)} since last progress)`);
110
+ }
111
+ result(result, durationMs, watching = false) {
112
+ this.active = undefined;
113
+ const interrupted = result.error === "interrupted";
114
+ if (result.status !== "idle") {
115
+ this.stats[interrupted ? "interrupted" : result.status]++;
116
+ this.stats.media += result.media;
117
+ }
118
+ const detail = result.status === "idle"
119
+ ? "No job ready"
120
+ : `${result.media}/${this.totalMedia} media archived · ${formatDuration(durationMs)}${result.error ? ` · ${connectorErrorHint(result.errorStatus ?? result.error)}` : ""}`;
121
+ this.write(interrupted ? "interrupted" : result.status, `${detail}${watching ? " · next poll in 20s" : ""}`, { ...result, durationMs, stats: { ...this.stats } });
122
+ if (result.status !== "idle")
123
+ this.write("session", this.summary(), { stats: { ...this.stats } });
124
+ }
125
+ offline(error) {
126
+ this.active = undefined;
127
+ this.stats.errors++;
128
+ this.write("offline", `${connectorErrorHint(error)} Next poll in 20s.`, {
129
+ status: "offline",
130
+ code: error instanceof ApiClientError ? error.status : "connector_error",
131
+ });
132
+ }
133
+ summary() {
134
+ const s = this.stats;
135
+ return `${s.complete} complete · ${s.partial} partial · ${s.failed} failed · ${s.interrupted} interrupted · ${s.media} media · ${s.skipped} skipped · ${formatSize(s.bytes)} uploaded · ${s.errors} connection errors · uptime ${formatDuration(Date.now() - this.started)}`;
136
+ }
137
+ stop() {
138
+ this.active = undefined;
139
+ this.write("stopped", this.summary(), {
140
+ stats: { ...this.stats },
141
+ durationMs: Date.now() - this.started,
142
+ });
143
+ }
144
+ }
145
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/connector/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type XCapture } from "./core.js";
2
+ export declare function readInChild(postId: string): Promise<XCapture>;
3
+ /** Isolate raw browser responses and upstream logs; IPC only carries the normalized focal post. */
4
+ export declare function readPost(postId: string, signal?: AbortSignal): Promise<XCapture>;
5
+ export declare function runIsolated(postId: string): Promise<void>;
6
+ //# sourceMappingURL=opencli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencli.d.ts","sourceRoot":"","sources":["../../src/connector/opencli.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AAgBnB,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsEnE;AAED,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkChF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB/D"}
@@ -0,0 +1,136 @@
1
+ import { fork } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { readFile } from "node:fs/promises";
4
+ import { createRequire } from "node:module";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+ import { ConnectorError, collectTweetEntities, normalizeXPost, record, } from "./core.js";
8
+ export async function readInChild(postId) {
9
+ const root = process.env.ZHE_OPENCLI_ROOT ??
10
+ resolve(dirname(createRequire(import.meta.url).resolve("@jackwener/opencli/registry")), "../..");
11
+ const manifest = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
12
+ if (manifest.version !== "1.8.6")
13
+ throw new ConnectorError("unsupported_opencli_version");
14
+ const { BrowserBridge } = (await import(pathToFileURL(join(root, "dist/src/browser/bridge.js")).href));
15
+ const { getRegistry } = (await import(pathToFileURL(join(root, "dist/src/registry.js")).href));
16
+ await import(pathToFileURL(join(root, "clis/twitter/thread.js")).href);
17
+ const bridge = new BrowserBridge();
18
+ let page;
19
+ const entities = new Map();
20
+ try {
21
+ page = await bridge.connect({
22
+ session: `zhe-connector-${randomUUID()}`,
23
+ windowMode: "background",
24
+ siteSession: "ephemeral",
25
+ });
26
+ await page.goto(`https://x.com/i/status/${postId}`, { waitUntil: "none" });
27
+ await new Promise((r) => setTimeout(r, 1200));
28
+ const proxy = new Proxy(page, {
29
+ get(target, key) {
30
+ if (key === "goto")
31
+ return (url) => target.goto(url, { waitUntil: "none" });
32
+ if (key === "evaluate")
33
+ return async (code) => {
34
+ const value = await target.evaluate(code);
35
+ if (code.includes("TweetDetail")) {
36
+ for (const [id, post] of collectTweetEntities(value))
37
+ entities.set(id, post);
38
+ // Stop reply pagination: the task only concerns its saved focal post.
39
+ const instructions = record(record(record(value).data).threaded_conversation_with_injections_v2).instructions;
40
+ if (Array.isArray(instructions))
41
+ for (const instruction of instructions) {
42
+ const item = record(instruction);
43
+ if (Array.isArray(item.entries))
44
+ item.entries = item.entries.filter((e) => !String(record(e).entryId ?? "").startsWith("cursor-") &&
45
+ !record(record(e).content).cursorType);
46
+ }
47
+ }
48
+ return value;
49
+ };
50
+ const value = Reflect.get(target, key);
51
+ return typeof value === "function" ? value.bind(target) : value;
52
+ },
53
+ });
54
+ const adapter = getRegistry().get("twitter/thread");
55
+ if (adapter?.access !== "read")
56
+ throw new ConnectorError("adapter_contract_changed");
57
+ await adapter.func(proxy, { "tweet-id": postId, limit: 1 });
58
+ const capture = normalizeXPost(entities.get(postId), postId);
59
+ if (!capture)
60
+ throw new ConnectorError("post_unavailable");
61
+ return capture;
62
+ }
63
+ catch (error) {
64
+ throw error instanceof ConnectorError ? error : new ConnectorError("needs_login");
65
+ }
66
+ finally {
67
+ await page?.closeWindow().catch(() => { });
68
+ await bridge.close().catch(() => { });
69
+ }
70
+ }
71
+ /** Isolate raw browser responses and upstream logs; IPC only carries the normalized focal post. */
72
+ export function readPost(postId, signal) {
73
+ if (!/^\d{1,22}$/.test(postId))
74
+ throw new ConnectorError("invalid_post_id");
75
+ return new Promise((resolveResult, reject) => {
76
+ const child = fork(fileURLToPath(import.meta.url), ["--isolated", postId], {
77
+ stdio: ["ignore", "ignore", "ignore", "ipc"],
78
+ });
79
+ const finish = () => {
80
+ clearTimeout(timer);
81
+ signal?.removeEventListener("abort", abort);
82
+ };
83
+ const abort = () => {
84
+ child.kill("SIGTERM");
85
+ finish();
86
+ reject(new ConnectorError("interrupted"));
87
+ };
88
+ const timer = setTimeout(abort, 120_000);
89
+ signal?.addEventListener("abort", abort, { once: true });
90
+ child.once("message", (message) => {
91
+ finish();
92
+ const value = record(message);
93
+ if (value.ok === true)
94
+ resolveResult(value.capture);
95
+ else
96
+ reject(new ConnectorError(typeof value.code === "string" ? value.code : "connector_error"));
97
+ });
98
+ child.once("error", () => {
99
+ finish();
100
+ reject(new ConnectorError("opencli_unavailable"));
101
+ });
102
+ child.once("close", () => {
103
+ finish();
104
+ reject(new ConnectorError("opencli_unavailable"));
105
+ });
106
+ if (signal?.aborted)
107
+ abort();
108
+ });
109
+ }
110
+ export async function runIsolated(postId) {
111
+ let result;
112
+ try {
113
+ result = { ok: true, capture: await readInChild(postId) };
114
+ }
115
+ catch (error) {
116
+ result = {
117
+ ok: false,
118
+ code: error instanceof ConnectorError ? error.code : "opencli_unavailable",
119
+ };
120
+ }
121
+ try {
122
+ await new Promise((done, reject) => {
123
+ if (!process.send)
124
+ return reject(new ConnectorError("opencli_unavailable"));
125
+ process.send(result, (error) => (error ? reject(error) : done()));
126
+ });
127
+ }
128
+ finally {
129
+ process.disconnect?.();
130
+ }
131
+ }
132
+ if (process.argv[2] === "--isolated" &&
133
+ process.argv[1] &&
134
+ resolve(process.argv[1]) === fileURLToPath(import.meta.url))
135
+ await runIsolated(process.argv[3] ?? "");
136
+ //# sourceMappingURL=opencli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencli.js","sourceRoot":"","sources":["../../src/connector/opencli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { ApiClient } from "../api/client.js";
2
+ import type { ReportProgress } from "./types.js";
3
+ export interface PollResult {
4
+ status: "idle" | "complete" | "partial" | "failed";
5
+ media: number;
6
+ error?: string;
7
+ errorStatus?: number;
8
+ }
9
+ export declare function authenticatedClient(): ApiClient;
10
+ export declare function processOne(client: ApiClient, parent?: AbortSignal, progress?: ReportProgress): Promise<PollResult>;
11
+ export declare function runOnce(signal?: AbortSignal, progress?: ReportProgress): Promise<PollResult>;
12
+ export declare function watchConnector(signal: AbortSignal, json?: boolean): Promise<void>;
13
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/connector/runtime.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAkB,MAAM,kBAAkB,CAAC;AAM7D,OAAO,KAAK,EAAqC,cAAc,EAAQ,MAAM,YAAY,CAAC;AAE1F,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,IAAI,SAAS,CAI/C;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,UAAU,CAAC,CAuGrB;AAiCD,wBAAsB,OAAO,CAC3B,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BrF"}
@@ -0,0 +1,179 @@
1
+ import { mkdtemp, rm } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { setTimeout as delay } from "node:timers/promises";
5
+ import { ApiClient, ApiClientError } from "../api/client.js";
6
+ import { getApiKey } from "../config.js";
7
+ import { ConnectorError } from "./core.js";
8
+ import { downloadMedia, makePoster } from "./download.js";
9
+ import { ConnectorLogger, connectorErrorHint } from "./log.js";
10
+ import { readPost } from "./opencli.js";
11
+ export function authenticatedClient() {
12
+ const key = getApiKey();
13
+ if (!key)
14
+ throw new ApiClientError(401, "Not authenticated. Run `zhe login` first.");
15
+ return new ApiClient(key);
16
+ }
17
+ export async function processOne(client, parent, progress) {
18
+ const { job } = await client.claimXJob(parent);
19
+ if (!job)
20
+ return { status: "idle", media: 0 };
21
+ progress?.({
22
+ stage: "claim",
23
+ message: `Link #${job.linkId} · X post ${job.postId} · attempt ${job.attempts}`,
24
+ });
25
+ const controller = new AbortController();
26
+ const signal = parent ? AbortSignal.any([parent, controller.signal]) : controller.signal;
27
+ let renewing;
28
+ const heartbeat = setInterval(() => {
29
+ if (renewing)
30
+ return;
31
+ renewing = client
32
+ .connectorAction(job, { action: "renew" }, signal)
33
+ .then(() => { })
34
+ .catch(() => controller.abort())
35
+ .finally(() => {
36
+ renewing = undefined;
37
+ });
38
+ }, 30_000);
39
+ let dir;
40
+ let archived = 0;
41
+ let incomplete = false;
42
+ try {
43
+ dir = await mkdtemp(join(tmpdir(), "zhe-connector-"));
44
+ progress?.({ stage: "read", message: "Reading the saved post through the local X session" });
45
+ const capture = await readPost(job.postId, signal);
46
+ progress?.({
47
+ stage: "capture",
48
+ message: `Saving ${capture.tweet.text.length} characters · ${capture.media.length} media found`,
49
+ total: capture.media.length,
50
+ });
51
+ await client.connectorAction(job, { action: "capture", capture }, signal);
52
+ for (const [index, media] of capture.media.entries()) {
53
+ signal.throwIfAborted();
54
+ const reportMedia = (event) => progress?.({
55
+ ...event,
56
+ current: index + 1,
57
+ total: capture.media.length,
58
+ message: `${media.type} ${index + 1}/${capture.media.length} · ${event.message}`,
59
+ });
60
+ try {
61
+ reportMedia({ stage: "download", message: "Connecting to X media" });
62
+ const file = await downloadMedia(media, dir, signal, (phase, received, bytes) => {
63
+ reportMedia({
64
+ stage: phase,
65
+ message: phase === "download" ? "Downloading" : "Verifying format and full decode",
66
+ received,
67
+ bytes,
68
+ });
69
+ });
70
+ const kind = media.type === "PHOTO" ? "photo" : "video";
71
+ if (!(await archive(client, job, media.id, kind, file, signal, reportMedia)))
72
+ continue;
73
+ media.width = file.width;
74
+ media.height = file.height;
75
+ media.duration = file.duration;
76
+ archived++;
77
+ if (kind === "video") {
78
+ reportMedia({ stage: "poster", message: "Generating video poster" });
79
+ const poster = await makePoster(file.path, signal);
80
+ if (poster)
81
+ await archive(client, job, media.id, "poster", poster, signal, reportMedia);
82
+ else
83
+ reportMedia({ stage: "warning", message: "Poster unavailable; video is archived" });
84
+ }
85
+ }
86
+ catch (error) {
87
+ if (signal.aborted ||
88
+ (error instanceof ApiClientError && [401, 403, 409].includes(error.status)))
89
+ throw error;
90
+ incomplete = true;
91
+ reportMedia({ stage: "warning", message: connectorErrorHint(error) });
92
+ }
93
+ }
94
+ signal.throwIfAborted();
95
+ capture.tweet.media = capture.media;
96
+ progress?.({
97
+ stage: "publish",
98
+ message: `Saving the enriched post · ${archived}/${capture.media.length} media archived`,
99
+ });
100
+ await client.connectorAction(job, { action: "capture", capture }, signal);
101
+ await client.connectorAction(job, { action: "complete" }, signal);
102
+ return { status: incomplete ? "partial" : "complete", media: archived };
103
+ }
104
+ catch (error) {
105
+ const code = error instanceof ConnectorError
106
+ ? error.code
107
+ : signal.aborted
108
+ ? "interrupted"
109
+ : "connector_error";
110
+ await client.connectorAction(job, { action: "fail", code }).catch(() => { });
111
+ return {
112
+ status: "failed",
113
+ media: archived,
114
+ error: code,
115
+ ...(error instanceof ApiClientError ? { errorStatus: error.status } : {}),
116
+ };
117
+ }
118
+ finally {
119
+ clearInterval(heartbeat);
120
+ controller.abort();
121
+ await renewing;
122
+ if (dir)
123
+ await rm(dir, { recursive: true, force: true });
124
+ }
125
+ }
126
+ async function archive(client, job, mediaId, kind, file, signal, progress) {
127
+ progress?.({ stage: "upload", message: `Preparing ${kind} archive` });
128
+ const { asset } = await client.connectorAction(job, {
129
+ action: "reserve",
130
+ media: { mediaId, kind, size: file.size, mime: file.mime, sha256: file.sha256 },
131
+ }, signal);
132
+ if (asset.skipped) {
133
+ progress?.({ stage: "skipped", message: `${kind} was explicitly deleted; keeping it deleted` });
134
+ return false;
135
+ }
136
+ if (!asset.uploaded) {
137
+ progress?.({ stage: "upload", message: `Uploading ${kind} to Zhe`, bytes: file.size });
138
+ await client.uploadXMedia(job, asset, file, signal);
139
+ progress?.({ stage: "uploaded", message: `${kind} upload confirmed`, bytes: file.size });
140
+ }
141
+ else
142
+ progress?.({ stage: "saved", message: `${kind} already archived; reusing the saved file` });
143
+ return true;
144
+ }
145
+ export async function runOnce(signal, progress) {
146
+ // Read the shared CLI configuration on each poll, so logout/rotation takes effect.
147
+ return processOne(authenticatedClient(), signal, progress);
148
+ }
149
+ export async function watchConnector(signal, json = false) {
150
+ const log = new ConnectorLogger(json);
151
+ const activity = setInterval(() => log.tick(), 10_000);
152
+ log.start();
153
+ try {
154
+ while (!signal.aborted) {
155
+ const started = Date.now();
156
+ try {
157
+ const client = authenticatedClient();
158
+ // Queue statistics are optional; a failed status lookup must not block enrichment.
159
+ const status = await client.connectorStatus(signal).catch(() => undefined);
160
+ if (signal.aborted)
161
+ break;
162
+ if (status)
163
+ log.queue(status);
164
+ log.result(await processOne(client, signal, log.progress), Date.now() - started, !signal.aborted);
165
+ }
166
+ catch (error) {
167
+ if (!signal.aborted)
168
+ log.offline(error);
169
+ }
170
+ if (!signal.aborted)
171
+ await delay(20_000, undefined, { signal }).catch(() => { });
172
+ }
173
+ }
174
+ finally {
175
+ clearInterval(activity);
176
+ log.stop();
177
+ }
178
+ }
179
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/connector/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export interface XJob {
2
+ linkId: number;
3
+ userId: string;
4
+ postId: string;
5
+ sourceUrl: string;
6
+ leaseToken: string;
7
+ leaseUntil: number;
8
+ attempts: number;
9
+ }
10
+ export interface MediaReservation {
11
+ id: string;
12
+ key: string;
13
+ uploaded: boolean;
14
+ skipped?: false;
15
+ }
16
+ export interface DownloadedMedia {
17
+ path: string;
18
+ size: number;
19
+ sha256: string;
20
+ mime: string;
21
+ width?: number | undefined;
22
+ height?: number | undefined;
23
+ duration?: number | undefined;
24
+ }
25
+ export interface ConnectorStatus {
26
+ states: {
27
+ state: string;
28
+ count: number;
29
+ }[];
30
+ keyPrefix: string;
31
+ expiresAt: number;
32
+ }
33
+ export interface ConnectorProgress {
34
+ stage: "claim" | "read" | "capture" | "download" | "verify" | "upload" | "uploaded" | "poster" | "saved" | "skipped" | "warning" | "publish";
35
+ message: string;
36
+ current?: number;
37
+ total?: number;
38
+ received?: number;
39
+ bytes?: number;
40
+ }
41
+ export type ReportProgress = (event: ConnectorProgress) => void;
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/connector/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EACD,OAAO,GACP,MAAM,GACN,SAAS,GACT,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,OAAO,GACP,SAAS,GACT,SAAS,GACT,SAAS,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/connector/types.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -2,7 +2,8 @@
2
2
  /**
3
3
  * zhe CLI — Manage zhe.to short links
4
4
  */
5
- import { defineCommand, runMain } from "@nocoo/cli-base";
5
+ import { defineCommand, runMain } from "@nocoo/base-cli";
6
+ import { connectorCommand } from "./commands/connector.js";
6
7
  import { createCommand } from "./commands/create.js";
7
8
  import { deleteCommand } from "./commands/delete.js";
8
9
  import { folderCommand } from "./commands/folder.js";
@@ -39,6 +40,7 @@ const main = defineCommand({
39
40
  update: updateCommand,
40
41
  delete: deleteCommand,
41
42
  open: openCommand,
43
+ connector: connectorCommand,
42
44
  },
43
45
  });
44
46
  runMain(main);