@hraness/ghostget 0.18.14 → 0.18.16
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/CHANGELOG.md +9 -0
- package/README.md +6 -6
- package/dist/apple-photos-client.js +1 -1
- package/dist/beeper-client.js +1 -1
- package/dist/{imessage-direct-install-5nftwc6p.js → imessage-direct-install-akfrgtpc.js} +2 -2
- package/dist/{index-kaav16fd.js → index-k2m73ke6.js} +3 -3
- package/dist/{index-g6na3p6k.js → index-km75a0bm.js} +1 -1
- package/dist/{index-yq6maz71.js → index-wwtk6nnt.js} +8 -26
- package/dist/messaging-automation-api.js +2 -2
- package/dist/{messaging-automation-58s1366z.js → messaging-automation-w7n3j4sf.js} +1 -1
- package/dist/{messaging-native-install-c90nv501.js → messaging-native-install-wk10f605.js} +2 -2
- package/dist/{whatsapp-automation-runtime-ke1dx91p.js → whatsapp-automation-runtime-zp2fx46r.js} +1 -1
- package/package.json +14 -7
- package/skills/ghostget/references/install.md +5 -5
- package/src/accounts-auth.ts +188 -0
- package/src/args.ts +14 -0
- package/src/beeper-client-types.ts +1 -1
- package/src/derivation-network-guard.ts +37 -165
- package/src/derivation-network-proxy-helper.ts +27 -56
- package/src/derive.ts +36 -37
- package/src/ghostget.ts +43 -0
- package/src/providers/x-web-runtime.ts +11 -11
- package/src/providers/x-web.ts +36 -35
- package/src/storage.ts +8 -25
- package/src/usage.ts +2 -0
- package/src/version.ts +1 -1
package/src/providers/x-web.ts
CHANGED
|
@@ -238,43 +238,40 @@ export function bindXWebOperationMetadataValues(
|
|
|
238
238
|
export const xWebQueryDescriptorEvidenceSnapshot = Object.freeze({
|
|
239
239
|
schemaVersion: 1,
|
|
240
240
|
role: "revision-evidence-only" as const,
|
|
241
|
-
observedOn: "2026-
|
|
241
|
+
observedOn: "2026-09-17",
|
|
242
242
|
currentBundleResolutionRequired: true,
|
|
243
|
-
mainBundleUrl: "https://abs.twimg.com/responsive-web/client-web/main.
|
|
243
|
+
mainBundleUrl: "https://abs.twimg.com/responsive-web/client-web/main.52fc4dd0aada586aa.js",
|
|
244
244
|
descriptors: Object.freeze([
|
|
245
|
-
{ operationName: "HomeTimeline", operationType: "query", queryId: "
|
|
246
|
-
{ operationName: "HomeLatestTimeline", operationType: "query", queryId: "
|
|
247
|
-
{ operationName: "ListLatestTweetsTimeline", operationType: "query", queryId: "
|
|
248
|
-
{ operationName: "ListRankedTweetsTimeline", operationType: "query", queryId: "
|
|
249
|
-
{ operationName: "Bookmarks", operationType: "query", queryId: "
|
|
250
|
-
{ operationName: "BookmarkSearchTimeline", operationType: "query", queryId: "
|
|
251
|
-
{ operationName: "SearchTimeline", operationType: "query", queryId: "
|
|
252
|
-
{ operationName: "NotificationsTimeline", operationType: "query", queryId: "
|
|
253
|
-
{ operationName: "TweetDetail", operationType: "query", queryId: "
|
|
254
|
-
{ operationName: "TweetResultByRestId", operationType: "query", queryId: "
|
|
255
|
-
{ operationName: "TweetResultsByRestIds", operationType: "query", queryId: "
|
|
256
|
-
{ operationName: "UserTweets", operationType: "query", queryId: "
|
|
257
|
-
{ operationName: "UserTweetsAndReplies", operationType: "query", queryId: "
|
|
258
|
-
{ operationName: "UserMedia", operationType: "query", queryId: "
|
|
259
|
-
{ operationName: "FavoriteTweet", operationType: "mutation", queryId: "lI07N6Otwv1PhnEgXILM7A", sourceChunk: "main.
|
|
260
|
-
{ operationName: "UnfavoriteTweet", operationType: "mutation", queryId: "ZYKSe-w7KEslx3JhSIk5LA", sourceChunk: "main.
|
|
261
|
-
{ operationName: "CreateBookmark", operationType: "mutation", queryId: "aoDbu3RHznuiSkQ9aNM67Q", sourceChunk: "main.
|
|
262
|
-
{ operationName: "DeleteBookmark", operationType: "mutation", queryId: "Wlmlj2-xzyS1GN3a6cj-mQ", sourceChunk: "main.
|
|
263
|
-
{ operationName: "CreateRetweet", operationType: "mutation", queryId: "mbRO74GrOvSfRcJnlMapnQ", sourceChunk: "main.
|
|
264
|
-
{ operationName: "DeleteRetweet", operationType: "mutation", queryId: "ZyZigVsNiFO6v1dEks1eWg", sourceChunk: "main.
|
|
265
|
-
{ operationName: "CreateTweet", operationType: "mutation", queryId: "
|
|
266
|
-
{ operationName: "CreateNoteTweet", operationType: "mutation", queryId: "
|
|
267
|
-
{ operationName: "DeleteTweet", operationType: "mutation", queryId: "nxpZCY2K-I6QoFHAHeojFQ", sourceChunk: "main.
|
|
268
|
-
{ operationName: "
|
|
269
|
-
{ operationName: "
|
|
270
|
-
{ operationName: "
|
|
271
|
-
{ operationName: "
|
|
272
|
-
{ operationName: "
|
|
273
|
-
{ operationName: "
|
|
274
|
-
{ operationName: "
|
|
275
|
-
{ operationName: "ArticleEntityUpdateTitle", operationType: "mutation", queryId: "z_xdvTUbZjSVjt232b4D4A", sourceChunk: "bundle.TwitterArticles.305538ca.js", observedOn: "2026-08-14" },
|
|
276
|
-
{ operationName: "ArticleEntityPublish", operationType: "mutation", queryId: "UyL9qgpV23A8471opeYQbw", sourceChunk: "bundle.TwitterArticles.305538ca.js", observedOn: "2026-08-14" },
|
|
277
|
-
{ operationName: "ArticleEntityResultByRestId", operationType: "query", queryId: "rPdndX2XxQoXIMUafLSSJQ", sourceChunk: "bundle.TwitterArticles.305538ca.js", observedOn: "2026-08-14" },
|
|
245
|
+
{ operationName: "HomeTimeline", operationType: "query", queryId: "og4a4SdSF3WiQkkwaPCdPg", sourceChunk: "shared~bundle.LoggedInMain~bundle.HomeTimeline~bundle.Compose.d2799da549fa4165a.js", observedOn: "2026-09-17" },
|
|
246
|
+
{ operationName: "HomeLatestTimeline", operationType: "query", queryId: "OQPHTgwczzp9RMAPt6BH9A", sourceChunk: "shared~bundle.LoggedInMain~bundle.HomeTimeline~bundle.Compose.d2799da549fa4165a.js", observedOn: "2026-09-17" },
|
|
247
|
+
{ operationName: "ListLatestTweetsTimeline", operationType: "query", queryId: "qIrerw_1oakhehcLoFbaOw", sourceChunk: "shared~loader.Dock~bundle.BookmarkFolders~bundle.Bookmarks~bundle.Explore~bundle.HomeTimeline~bundle.Notifica.bd9965b893a1c830a.js", observedOn: "2026-09-17" },
|
|
248
|
+
{ operationName: "ListRankedTweetsTimeline", operationType: "query", queryId: "K3JUG9l3MeWDoLKeFYex9g", sourceChunk: "shared~loader.Dock~bundle.BookmarkFolders~bundle.Bookmarks~bundle.Explore~bundle.HomeTimeline~bundle.Notifica.bd9965b893a1c830a.js", observedOn: "2026-09-17" },
|
|
249
|
+
{ operationName: "Bookmarks", operationType: "query", queryId: "-dgKZ58Dr9YSJYrcgEb5KA", sourceChunk: "shared~bundle.BookmarkFolders~bundle.Bookmarks.12cb1875a99ef5b3a.js", observedOn: "2026-09-17" },
|
|
250
|
+
{ operationName: "BookmarkSearchTimeline", operationType: "query", queryId: "rbwiGBFqb93lmG7mw_OYZQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
251
|
+
{ operationName: "SearchTimeline", operationType: "query", queryId: "auLkqtmHqYEpRvflfvLhyQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
252
|
+
{ operationName: "NotificationsTimeline", operationType: "query", queryId: "MSUPE4KwuxyghDO60Bv5uQ", sourceChunk: "bundle.Notifications.62eab6a0a03e5036a.js", observedOn: "2026-09-17" },
|
|
253
|
+
{ operationName: "TweetDetail", operationType: "query", queryId: "zoF7_t363wZyzylk-BLfZQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
254
|
+
{ operationName: "TweetResultByRestId", operationType: "query", queryId: "Xl0tsHf4AzflMRjbw9e70A", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
255
|
+
{ operationName: "TweetResultsByRestIds", operationType: "query", queryId: "mQnBPxNdkMLfhXINDDYUSg", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
256
|
+
{ operationName: "UserTweets", operationType: "query", queryId: "jeAA-59Y9FL7FmjgBNIVPw", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
257
|
+
{ operationName: "UserTweetsAndReplies", operationType: "query", queryId: "wI-ubAWfScnG6odLK4XgCg", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
258
|
+
{ operationName: "UserMedia", operationType: "query", queryId: "TwLiEVUhRjjjKVc98IT0TQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
259
|
+
{ operationName: "FavoriteTweet", operationType: "mutation", queryId: "lI07N6Otwv1PhnEgXILM7A", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
260
|
+
{ operationName: "UnfavoriteTweet", operationType: "mutation", queryId: "ZYKSe-w7KEslx3JhSIk5LA", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
261
|
+
{ operationName: "CreateBookmark", operationType: "mutation", queryId: "aoDbu3RHznuiSkQ9aNM67Q", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
262
|
+
{ operationName: "DeleteBookmark", operationType: "mutation", queryId: "Wlmlj2-xzyS1GN3a6cj-mQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
263
|
+
{ operationName: "CreateRetweet", operationType: "mutation", queryId: "mbRO74GrOvSfRcJnlMapnQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
264
|
+
{ operationName: "DeleteRetweet", operationType: "mutation", queryId: "ZyZigVsNiFO6v1dEks1eWg", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
265
|
+
{ operationName: "CreateTweet", operationType: "mutation", queryId: "GYdIGqVWfZNho79bQ2XDoA", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
266
|
+
{ operationName: "CreateNoteTweet", operationType: "mutation", queryId: "u-Vsy3HZId2j10nbdqMI0A", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
267
|
+
{ operationName: "DeleteTweet", operationType: "mutation", queryId: "nxpZCY2K-I6QoFHAHeojFQ", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
268
|
+
{ operationName: "Viewer", operationType: "query", queryId: "9t128XgFic52jPUEkJMf6w", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
269
|
+
{ operationName: "UserByScreenName", operationType: "query", queryId: "KybxDj9RrADIITXlGG8kpw", sourceChunk: "main.52fc4dd0aada586aa.js", observedOn: "2026-09-17" },
|
|
270
|
+
{ operationName: "ArticleEntityDraftCreate", operationType: "mutation", queryId: "_rbmb_NKLqKVBr5X_MSoMQ", sourceChunk: "bundle.TwitterArticles.b3c21fed7d9db030a.js", observedOn: "2026-09-17" },
|
|
271
|
+
{ operationName: "ArticleEntityUpdateContent", operationType: "mutation", queryId: "x4Pz2ifYkOD6uSvzxOIUig", sourceChunk: "bundle.TwitterArticles.b3c21fed7d9db030a.js", observedOn: "2026-09-17" },
|
|
272
|
+
{ operationName: "ArticleEntityUpdateTitle", operationType: "mutation", queryId: "brHFCBTXXg8WOqc7BnXfAw", sourceChunk: "bundle.TwitterArticles.b3c21fed7d9db030a.js", observedOn: "2026-09-17" },
|
|
273
|
+
{ operationName: "ArticleEntityPublish", operationType: "mutation", queryId: "872mse3gUSifcgeJBBl4WA", sourceChunk: "bundle.TwitterArticles.b3c21fed7d9db030a.js", observedOn: "2026-09-17" },
|
|
274
|
+
{ operationName: "ArticleEntityResultByRestId", operationType: "query", queryId: "OF2ES8qTOPLFBU_oZWVkQw", sourceChunk: "bundle.TwitterArticles.b3c21fed7d9db030a.js", observedOn: "2026-09-17" },
|
|
278
275
|
] satisfies readonly XWebQueryDescriptorEvidence[]),
|
|
279
276
|
});
|
|
280
277
|
|
|
@@ -1138,6 +1135,10 @@ export function projectXWebProfileStats(
|
|
|
1138
1135
|
observedAt: string,
|
|
1139
1136
|
): XWebProfileStats {
|
|
1140
1137
|
const expectedHandle = normalizeXWebProfileHandle(expectedHandleValue);
|
|
1138
|
+
const profileData = responseData(response, "X profiles.by-handle response");
|
|
1139
|
+
if (profileData.user === undefined || profileData.user === null) {
|
|
1140
|
+
throw new XProfileTargetUnavailableError();
|
|
1141
|
+
}
|
|
1141
1142
|
const result = record(
|
|
1142
1143
|
extractXWebGraphQlReadResponseRoot("profiles.by-handle", response),
|
|
1143
1144
|
"X profile response result",
|
package/src/storage.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
mkdtempSync,
|
|
11
11
|
openSync,
|
|
12
12
|
opendirSync,
|
|
13
|
-
readSync,
|
|
14
13
|
realpathSync,
|
|
15
14
|
rmSync,
|
|
16
15
|
writeFileSync,
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
type Dirent,
|
|
19
18
|
} from "node:fs";
|
|
20
19
|
import { spawnSync } from "node:child_process";
|
|
20
|
+
import { readOwnedFileStableSync } from "@hraness/local-custody/private-paths";
|
|
21
21
|
import { homedir, tmpdir } from "node:os";
|
|
22
22
|
import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
@@ -363,20 +363,6 @@ function hasCode(error: unknown, code: string): boolean {
|
|
|
363
363
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
function readDescriptorBounded(descriptor: number, maximumBytes: number): Buffer {
|
|
367
|
-
const chunks: Buffer[] = [];
|
|
368
|
-
const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, maximumBytes + 1));
|
|
369
|
-
let total = 0;
|
|
370
|
-
for (;;) {
|
|
371
|
-
const remaining = maximumBytes + 1 - total;
|
|
372
|
-
const count = readSync(descriptor, buffer, 0, Math.min(buffer.byteLength, remaining), null);
|
|
373
|
-
if (count === 0) return Buffer.concat(chunks, total);
|
|
374
|
-
total += count;
|
|
375
|
-
if (total > maximumBytes) throw new Error("file grew beyond its byte bound");
|
|
376
|
-
chunks.push(Buffer.from(buffer.subarray(0, count)));
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
366
|
function pathInside(root: string, target: string): boolean {
|
|
381
367
|
const child = relative(root, target);
|
|
382
368
|
return child === "" || (!isAbsolute(child) && child !== ".." && !child.startsWith(`..${sep}`));
|
|
@@ -1037,18 +1023,17 @@ function ownedByCurrentUser(stats: { readonly uid: number | bigint }): boolean {
|
|
|
1037
1023
|
}
|
|
1038
1024
|
|
|
1039
1025
|
function readStateMarker(path: string): void {
|
|
1040
|
-
|
|
1041
|
-
const nonBlocking = "O_NONBLOCK" in constants ? constants.O_NONBLOCK : 0;
|
|
1042
|
-
const descriptor = openSync(path, constants.O_RDONLY | noFollow | nonBlocking);
|
|
1026
|
+
let bytes: Buffer;
|
|
1043
1027
|
try {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1028
|
+
bytes = readOwnedFileStableSync(path, 256).bytes;
|
|
1029
|
+
} catch (error) {
|
|
1030
|
+
throw new Error("ghostget state marker must be a private, owned regular file", { cause: error });
|
|
1031
|
+
}
|
|
1032
|
+
{
|
|
1048
1033
|
const content = new TextDecoder("utf-8", {
|
|
1049
1034
|
fatal: true,
|
|
1050
1035
|
ignoreBOM: true,
|
|
1051
|
-
}).decode(
|
|
1036
|
+
}).decode(bytes);
|
|
1052
1037
|
if (content !== stateMarkerText) throw new Error("ghostget state marker is malformed");
|
|
1053
1038
|
const value = JSON.parse(content) as unknown;
|
|
1054
1039
|
if (
|
|
@@ -1061,8 +1046,6 @@ function readStateMarker(path: string): void {
|
|
|
1061
1046
|
|| !("kind" in value)
|
|
1062
1047
|
|| value.kind !== "io-state"
|
|
1063
1048
|
) throw new Error("ghostget state marker is malformed");
|
|
1064
|
-
} finally {
|
|
1065
|
-
closeSync(descriptor);
|
|
1066
1049
|
}
|
|
1067
1050
|
}
|
|
1068
1051
|
|
package/src/usage.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* optional provider runtime is broken.
|
|
7
7
|
*/
|
|
8
8
|
export const ghostgetUsage = `Usage:
|
|
9
|
+
ghostget login [--json] Sign in to Hraness Accounts
|
|
10
|
+
ghostget logout [--json] Sign out of Hraness Accounts
|
|
9
11
|
ghostget --version Print the exact Ghostget release version
|
|
10
12
|
ghostget support [--json] View optional product updates and support
|
|
11
13
|
ghostget support protocol --json Read the optional agent closeout protocol
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Canonical immutable Ghostget package release identity. */
|
|
2
|
-
export const GHOSTGET_VERSION = "0.18.
|
|
2
|
+
export const GHOSTGET_VERSION = "0.18.16" as const;
|