@leemour/max-cli 0.2.0 → 0.4.0
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/README.md +10 -3
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -0
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/schema.d.ts +4 -1
- package/dist/cache/schema.d.ts.map +1 -1
- package/dist/cache/schema.js +89 -2
- package/dist/cache/schema.js.map +1 -1
- package/dist/cache/store.d.ts +38 -11
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +123 -17
- package/dist/cache/store.js.map +1 -1
- package/dist/client.d.ts +41 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +188 -49
- package/dist/client.js.map +1 -1
- package/dist/commands/account.js +1 -1
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/body.d.ts +23 -0
- package/dist/commands/body.d.ts.map +1 -0
- package/dist/commands/body.js +36 -0
- package/dist/commands/body.js.map +1 -0
- package/dist/commands/cache.js +2 -2
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/chats.d.ts.map +1 -1
- package/dist/commands/chats.js +24 -3
- package/dist/commands/chats.js.map +1 -1
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +55 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +8 -3
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/context.d.ts +27 -3
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +45 -8
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/doctor.d.ts +18 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +72 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/messages.d.ts.map +1 -1
- package/dist/commands/messages.js +129 -5
- package/dist/commands/messages.js.map +1 -1
- package/dist/commands/paging.d.ts +6 -3
- package/dist/commands/paging.d.ts.map +1 -1
- package/dist/commands/paging.js +14 -3
- package/dist/commands/paging.js.map +1 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/runs.js +4 -6
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/session.js +2 -2
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/skill.d.ts +3 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +23 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/config.d.ts +46 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +103 -9
- package/dist/config.js.map +1 -1
- package/dist/deadline.d.ts +30 -0
- package/dist/deadline.d.ts.map +1 -0
- package/dist/deadline.js +45 -0
- package/dist/deadline.js.map +1 -0
- package/dist/diagnose.d.ts +68 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +115 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/domain/map.d.ts.map +1 -1
- package/dist/domain/map.js +42 -3
- package/dist/domain/map.js.map +1 -1
- package/dist/domain/models.d.ts +46 -0
- package/dist/domain/models.d.ts.map +1 -1
- package/dist/domain/models.js +11 -1
- package/dist/domain/models.js.map +1 -1
- package/dist/output.d.ts +7 -4
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +8 -11
- package/dist/output.js.map +1 -1
- package/dist/program.d.ts +2 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +15 -2
- package/dist/program.js.map +1 -1
- package/dist/protocol/connection.d.ts +10 -0
- package/dist/protocol/connection.d.ts.map +1 -1
- package/dist/protocol/connection.js +20 -3
- package/dist/protocol/connection.js.map +1 -1
- package/dist/rendering/messages.d.ts +19 -0
- package/dist/rendering/messages.d.ts.map +1 -0
- package/dist/rendering/messages.js +138 -0
- package/dist/rendering/messages.js.map +1 -0
- package/dist/runs/events.d.ts +1 -1
- package/dist/runs/recording.d.ts +2 -2
- package/dist/runs/recording.d.ts.map +1 -1
- package/dist/runs/recording.js +3 -3
- package/dist/runs/recording.js.map +1 -1
- package/dist/testing/mock-max.d.ts.map +1 -1
- package/dist/testing/mock-max.js +16 -2
- package/dist/testing/mock-max.js.map +1 -1
- package/dist/testing/sandbox.d.ts +2 -0
- package/dist/testing/sandbox.d.ts.map +1 -0
- package/dist/testing/sandbox.js +31 -0
- package/dist/testing/sandbox.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
- package/skills/max-cli/SKILL.md +83 -0
package/dist/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { CliError, configFilePath, loadConfigFile, resolvePaths } from "@leemour/cli-core";
|
|
2
3
|
import * as v from "valibot";
|
|
3
4
|
import { DEFAULT_PROFILE, usableProfileName } from "./profile.js";
|
|
@@ -20,6 +21,7 @@ const profileSettings = v.strictObject({
|
|
|
20
21
|
limit: v.optional(count),
|
|
21
22
|
timeoutMs: v.optional(count),
|
|
22
23
|
color: v.optional(v.boolean()),
|
|
24
|
+
senderColors: v.optional(v.boolean()),
|
|
23
25
|
/** The run log reads these two; nothing records anything until it exists. */
|
|
24
26
|
record: v.optional(v.boolean()),
|
|
25
27
|
keepRunsForDays: v.optional(count),
|
|
@@ -28,10 +30,22 @@ export const configSchema = v.strictObject({
|
|
|
28
30
|
defaultProfile: v.optional(v.string()),
|
|
29
31
|
profiles: v.optional(v.record(v.string(), profileSettings), {}),
|
|
30
32
|
});
|
|
33
|
+
/** The first given value wins, and says which it was. */
|
|
34
|
+
const first = (candidates, fallback) => {
|
|
35
|
+
for (const [from, value] of candidates)
|
|
36
|
+
if (value !== undefined)
|
|
37
|
+
return { value, from };
|
|
38
|
+
return { value: fallback, from: "default" };
|
|
39
|
+
};
|
|
31
40
|
/**
|
|
32
41
|
* **Flag, then environment, then the configuration file, then the built-in default.** One place,
|
|
33
42
|
* so no command can decide the order differently from another.
|
|
34
43
|
*
|
|
44
|
+
* ⚠ **Only two settings actually have the middle step** — `MAX_PROFILE` and `MAX_TIMEOUT` — and
|
|
45
|
+
* that is deliberate rather than unfinished (`NEED-119`). They are the two an agent sets once for
|
|
46
|
+
* a whole process. A variable for `--json` or `--color` would be worse than missing: one left set
|
|
47
|
+
* in a shell silently changes the output of a command that never asked for it.
|
|
48
|
+
*
|
|
35
49
|
* Two things already jump this queue and are documented rather than re-litigated here:
|
|
36
50
|
* `MAX_TOKEN` outranks the keyring (`cli-core`'s `Credentials.read`), and `MAX_CONFIG_DIR`,
|
|
37
51
|
* `MAX_STATE_DIR` or `MAX_CACHE_DIR` move the whole installation — including which keyring entry
|
|
@@ -41,21 +55,62 @@ export const resolveSettings = (flags = {}, { env = process.env, configDir } = {
|
|
|
41
55
|
const paths = resolvePaths({ appName: APP, prefix: "MAX", env });
|
|
42
56
|
const configPath = configFilePath(configDir ?? paths.config);
|
|
43
57
|
const config = readConfig(configPath);
|
|
44
|
-
const profile =
|
|
45
|
-
|
|
58
|
+
const profile = first([
|
|
59
|
+
["first word", flags.profile],
|
|
60
|
+
["MAX_PROFILE", given(env.MAX_PROFILE)],
|
|
61
|
+
["config file", config.defaultProfile],
|
|
62
|
+
], DEFAULT_PROFILE);
|
|
63
|
+
const configured = config.profiles[usableProfileName(profile.value)] ?? {};
|
|
64
|
+
const limit = first([
|
|
65
|
+
["flag", flags.limit],
|
|
66
|
+
["config file", configured.limit],
|
|
67
|
+
], DEFAULT_LIMIT);
|
|
68
|
+
const timeoutMs = first([["config file", configured.timeoutMs]], undefined);
|
|
69
|
+
const color = first([["config file", configured.color]], undefined);
|
|
70
|
+
const senderColors = first([["config file", configured.senderColors]], false);
|
|
71
|
+
const record = first([
|
|
72
|
+
["flag", flags.record],
|
|
73
|
+
["config file", configured.record],
|
|
74
|
+
], false);
|
|
75
|
+
const keepRunsForDays = first([["config file", configured.keepRunsForDays]], DEFAULT_KEEP_RUNS_FOR_DAYS);
|
|
76
|
+
/**
|
|
77
|
+
* ⚠ **The only setting with no `config file` row, on purpose.** A budget for one command is
|
|
78
|
+
* about a particular run, not a habit, and a timeout written into a file is one somebody trips
|
|
79
|
+
* over months later without remembering they set it.
|
|
80
|
+
*/
|
|
81
|
+
const timeout = first([
|
|
82
|
+
["flag", flags.timeout],
|
|
83
|
+
["MAX_TIMEOUT", given(env.MAX_TIMEOUT)],
|
|
84
|
+
], undefined);
|
|
46
85
|
const settings = {
|
|
47
|
-
profile,
|
|
86
|
+
profile: usableProfileName(profile.value),
|
|
48
87
|
json: flags.json === true,
|
|
88
|
+
jsonl: flags.jsonl === true,
|
|
49
89
|
quiet: flags.quiet === true,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
90
|
+
detail: Math.min(2, Math.max(0, flags.verbose ?? 0)),
|
|
91
|
+
trace: flags.trace === true,
|
|
92
|
+
color: color.value,
|
|
93
|
+
senderColors: senderColors.value,
|
|
94
|
+
limit: limit.value,
|
|
53
95
|
page: flags.page ?? 1,
|
|
54
96
|
all: flags.all === true,
|
|
55
|
-
timeoutMs:
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
timeoutMs: timeoutMs.value,
|
|
98
|
+
commandTimeoutMs: durationMs(timeout.value, timeout.from),
|
|
99
|
+
record: record.value,
|
|
100
|
+
keepRunsForDays: keepRunsForDays.value,
|
|
58
101
|
configPath,
|
|
102
|
+
configFound: existsSync(configPath),
|
|
103
|
+
configuredProfiles: Object.keys(config.profiles),
|
|
104
|
+
sources: {
|
|
105
|
+
profile: profile.from,
|
|
106
|
+
limit: limit.from,
|
|
107
|
+
timeoutMs: timeoutMs.from,
|
|
108
|
+
commandTimeoutMs: timeout.from,
|
|
109
|
+
color: color.from,
|
|
110
|
+
senderColors: senderColors.from,
|
|
111
|
+
record: record.from,
|
|
112
|
+
keepRunsForDays: keepRunsForDays.from,
|
|
113
|
+
},
|
|
59
114
|
};
|
|
60
115
|
// The file was checked by the schema; a flag was not, and `--limit abc` is `NaN` by the time it
|
|
61
116
|
// gets here, which slices an array to nothing without complaining.
|
|
@@ -72,6 +127,45 @@ export const resolveSettings = (flags = {}, { env = process.env, configDir } = {
|
|
|
72
127
|
}
|
|
73
128
|
return settings;
|
|
74
129
|
};
|
|
130
|
+
/**
|
|
131
|
+
* The profile names written in the configuration file.
|
|
132
|
+
*
|
|
133
|
+
* ⚠ **This is not every profile that works.** `max <name> session start` stores a token under any
|
|
134
|
+
* name without writing anything to the file, so a profile can be in daily use and absent here.
|
|
135
|
+
* Whoever prints this has to say so, or it reads as a complete list and quietly is not.
|
|
136
|
+
*/
|
|
137
|
+
export const configuredProfiles = ({ env = process.env, configDir } = {}) => {
|
|
138
|
+
const paths = resolvePaths({ appName: APP, prefix: "MAX", env });
|
|
139
|
+
return Object.keys(readConfig(configFilePath(configDir ?? paths.config)).profiles).sort();
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* `30s`, `2m`, `500ms` — **the unit is required, and a bare number is refused.**
|
|
143
|
+
*
|
|
144
|
+
* `--timeout 30` is ambiguous in a way that costs real time: the neighbouring setting in the
|
|
145
|
+
* configuration file is called `timeoutMs` and is milliseconds, while every other tool that spells
|
|
146
|
+
* it this way means seconds. Guessing either one is a thirty-fold surprise in one direction or the
|
|
147
|
+
* other, so this asks instead — the same rule as `--kind`, and the reason is the same.
|
|
148
|
+
*
|
|
149
|
+
* The refusal names whichever of the two supplied the value — see `durationMs`.
|
|
150
|
+
*/
|
|
151
|
+
const DURATION = /^(\d+)(ms|s|m)$/;
|
|
152
|
+
const UNIT_MS = { ms: 1, s: 1000, m: 60_000 };
|
|
153
|
+
const durationMs = (value, from) => {
|
|
154
|
+
if (value === undefined)
|
|
155
|
+
return undefined;
|
|
156
|
+
// Named by where it came from, so somebody who set `MAX_TIMEOUT` in a shell profile weeks ago is
|
|
157
|
+
// told which thing is wrong rather than shown a flag they never typed.
|
|
158
|
+
const source = from === "MAX_TIMEOUT" ? "MAX_TIMEOUT" : "--timeout";
|
|
159
|
+
const match = DURATION.exec(value.trim());
|
|
160
|
+
if (!match?.[1] || !match[2]) {
|
|
161
|
+
throw new CliError("validation_error", `${source} takes a duration with a unit — 30s, 2m or 500ms — not "${value}"`);
|
|
162
|
+
}
|
|
163
|
+
const ms = Number(match[1]) * (UNIT_MS[match[2]] ?? 0);
|
|
164
|
+
if (ms <= 0) {
|
|
165
|
+
throw new CliError("validation_error", `${source} has to be more than zero, and "${value}" is not`);
|
|
166
|
+
}
|
|
167
|
+
return ms;
|
|
168
|
+
};
|
|
75
169
|
/**
|
|
76
170
|
* A missing file is not an error — it is a program nobody has configured. A malformed one is, in
|
|
77
171
|
* every output mode: an agent reading JSON deserves the same refusal a person gets, and silently
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC1F,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEjE,MAAM,GAAG,GAAG,SAAS,CAAA;AACrB,MAAM,aAAa,GAAG,EAAE,CAAA;AACxB,MAAM,0BAA0B,GAAG,EAAE,CAAA;AAErC,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAE5D;;;;;;;;;;GAUG;AACH,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IACxB,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/B,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;CACnC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC;IACzC,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,EAAE,EAAE,CAAC;CAChE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Anything holding something that would keep the process alive. A `MaxClient` is one. */
|
|
2
|
+
export interface Closeable {
|
|
3
|
+
close(): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Stops the whole command at `ms`, and **closes what it was holding on the way out**.
|
|
7
|
+
*
|
|
8
|
+
* ⚠ The closing is the part that matters, and it is what a plain `Promise.race` does not do.
|
|
9
|
+
* Racing only decides which answer is printed; the losing work carries on, and an open WebSocket
|
|
10
|
+
* keeps Node alive — so a command that reported a timeout would then sit there, which is the
|
|
11
|
+
* defect §18 forbids and worse than the wait it was cutting short. A test covers exactly that, by
|
|
12
|
+
* taking the closing away and watching what is left behind.
|
|
13
|
+
*
|
|
14
|
+
* Closing a connection with a request still in flight used to strand the caller forever; it now
|
|
15
|
+
* rejects it (`BUG-24`), which is what lets the body unwind through its own `finally` rather than
|
|
16
|
+
* hanging somewhere underneath this.
|
|
17
|
+
*
|
|
18
|
+
* ⚠ **It bounds everything, not only what talks to MAX.** `max messages search` never opens a
|
|
19
|
+
* socket at all and still has to fit the budget: an agent handing out thirty seconds does not
|
|
20
|
+
* know which commands are the networked ones, and a bound that quietly did not apply to some of
|
|
21
|
+
* them would be worse than no bound.
|
|
22
|
+
*
|
|
23
|
+
* It lives here rather than under `commands/` because it is about the lifetime of a process, not
|
|
24
|
+
* about any command — and because a command may not reach the transport, while the thing that
|
|
25
|
+
* shuts the transport down has to.
|
|
26
|
+
*
|
|
27
|
+
* Without a bound there is no timer and no race: the ordinary path is exactly what it was.
|
|
28
|
+
*/
|
|
29
|
+
export declare const withDeadline: <T>(ms: number | undefined, closeables: Closeable[], body: () => Promise<T>) => Promise<T>;
|
|
30
|
+
//# sourceMappingURL=deadline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline.d.ts","sourceRoot":"","sources":["../src/deadline.ts"],"names":[],"mappings":"AAEA,0FAA0F;AAC1F,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,YAAY,GAAU,CAAC,EAClC,IAAI,MAAM,GAAG,SAAS,EACtB,YAAY,SAAS,EAAE,EACvB,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KACrB,OAAO,CAAC,CAAC,CAmBX,CAAA"}
|
package/dist/deadline.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { CliError } from "@leemour/cli-core";
|
|
2
|
+
/**
|
|
3
|
+
* Stops the whole command at `ms`, and **closes what it was holding on the way out**.
|
|
4
|
+
*
|
|
5
|
+
* ⚠ The closing is the part that matters, and it is what a plain `Promise.race` does not do.
|
|
6
|
+
* Racing only decides which answer is printed; the losing work carries on, and an open WebSocket
|
|
7
|
+
* keeps Node alive — so a command that reported a timeout would then sit there, which is the
|
|
8
|
+
* defect §18 forbids and worse than the wait it was cutting short. A test covers exactly that, by
|
|
9
|
+
* taking the closing away and watching what is left behind.
|
|
10
|
+
*
|
|
11
|
+
* Closing a connection with a request still in flight used to strand the caller forever; it now
|
|
12
|
+
* rejects it (`BUG-24`), which is what lets the body unwind through its own `finally` rather than
|
|
13
|
+
* hanging somewhere underneath this.
|
|
14
|
+
*
|
|
15
|
+
* ⚠ **It bounds everything, not only what talks to MAX.** `max messages search` never opens a
|
|
16
|
+
* socket at all and still has to fit the budget: an agent handing out thirty seconds does not
|
|
17
|
+
* know which commands are the networked ones, and a bound that quietly did not apply to some of
|
|
18
|
+
* them would be worse than no bound.
|
|
19
|
+
*
|
|
20
|
+
* It lives here rather than under `commands/` because it is about the lifetime of a process, not
|
|
21
|
+
* about any command — and because a command may not reach the transport, while the thing that
|
|
22
|
+
* shuts the transport down has to.
|
|
23
|
+
*
|
|
24
|
+
* Without a bound there is no timer and no race: the ordinary path is exactly what it was.
|
|
25
|
+
*/
|
|
26
|
+
export const withDeadline = async (ms, closeables, body) => {
|
|
27
|
+
if (ms === undefined)
|
|
28
|
+
return body();
|
|
29
|
+
let timer;
|
|
30
|
+
const expired = new Promise((_, reject) => {
|
|
31
|
+
timer = setTimeout(() => {
|
|
32
|
+
// Sockets first, then the message: the rejection is what the person reads, and the closing
|
|
33
|
+
// is what lets the process actually end once they have read it.
|
|
34
|
+
void Promise.allSettled(closeables.map((closeable) => closeable.close())).then(() => reject(new CliError("timeout", `the command did not finish within ${ms}ms — \`--timeout\` ended it`)));
|
|
35
|
+
}, ms);
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
return await Promise.race([body(), expired]);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
if (timer)
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=deadline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deadline.js","sourceRoot":"","sources":["../src/deadline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAO5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,EAAsB,EACtB,UAAuB,EACvB,IAAsB,EACV,EAAE;IACd,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,IAAI,EAAE,CAAA;IAEnC,IAAI,KAAiC,CAAA;IACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC/C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,2FAA2F;YAC3F,gEAAgE;YAChE,KAAK,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAClF,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS,EAAE,qCAAqC,EAAE,6BAA6B,CAAC,CAAC,CACtG,CAAA;QACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IAC9C,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface DiagnoseOptions {
|
|
2
|
+
profile: string;
|
|
3
|
+
env?: NodeJS.ProcessEnv;
|
|
4
|
+
/** Tests point these at a temporary directory; nothing else should need them. */
|
|
5
|
+
stateDir?: string;
|
|
6
|
+
cacheDir?: string;
|
|
7
|
+
/** Injected so a test needs no SQLite file and no keyring. */
|
|
8
|
+
readSchemaVersion?: (file: string) => Promise<number | undefined>;
|
|
9
|
+
hasKeyringToken?: (profile: string) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export type TokenSource = "environment" | "keyring" | "none";
|
|
12
|
+
export interface Diagnosis {
|
|
13
|
+
/** ⚠ Never the token, and never a prefix or a length of it — only whether one is reachable. */
|
|
14
|
+
token: {
|
|
15
|
+
present: boolean;
|
|
16
|
+
from: TokenSource;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* ⚠ **The trap this command exists for.** `MAX_CONFIG_DIR` and its two siblings change the
|
|
20
|
+
* keyring entry a profile means, so a login performed with them set answers "no session"
|
|
21
|
+
* without them — and nothing else in the tool can show that.
|
|
22
|
+
*/
|
|
23
|
+
keyring: {
|
|
24
|
+
service: string;
|
|
25
|
+
movedByEnvironment: boolean;
|
|
26
|
+
};
|
|
27
|
+
session: {
|
|
28
|
+
stateFile: string;
|
|
29
|
+
/** `false` on a machine nobody has logged in on. Reading it must not create it. */
|
|
30
|
+
exists: boolean;
|
|
31
|
+
deviceId: boolean;
|
|
32
|
+
viewerId: boolean;
|
|
33
|
+
/** What `RISK-2` wants counted: a token that stops working can then be explained. */
|
|
34
|
+
logins: number | null;
|
|
35
|
+
lastLoginAt: string | null;
|
|
36
|
+
};
|
|
37
|
+
loggedInProfiles: string[];
|
|
38
|
+
cache: {
|
|
39
|
+
file: string;
|
|
40
|
+
exists: boolean;
|
|
41
|
+
/** What is written in the file, which is not always what this build speaks. */
|
|
42
|
+
schemaVersion: number | undefined;
|
|
43
|
+
speaks: number;
|
|
44
|
+
/** A file from a newer `max` is refused rather than written to — and that looks like a bug. */
|
|
45
|
+
readable: boolean;
|
|
46
|
+
};
|
|
47
|
+
runs: {
|
|
48
|
+
directory: string;
|
|
49
|
+
kept: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Everything a command depends on, read from disk and **never from MAX**.
|
|
54
|
+
*
|
|
55
|
+
* It is a separate function rather than the body of the command because `forCommand` builds its
|
|
56
|
+
* own renderer over the real streams, so anything left inside a command action cannot be asserted
|
|
57
|
+
* on (`CLI-15`, and `src/session/adopt.ts` moved for the same reason).
|
|
58
|
+
*
|
|
59
|
+
* ⚠ **It must work when everything is broken**, which is the only time anybody runs it: no
|
|
60
|
+
* session, no configuration file, a cache from a newer version, a keyring that will not open. Each
|
|
61
|
+
* of those is a field in the answer, never an exception.
|
|
62
|
+
*
|
|
63
|
+
* ⚠ **It reads the state file directly instead of calling `readState`**, which invents a device
|
|
64
|
+
* identity and writes it out on first read. A diagnosis that creates the thing it is reporting on
|
|
65
|
+
* is not a diagnosis.
|
|
66
|
+
*/
|
|
67
|
+
export declare const diagnose: ({ profile, env, stateDir, cacheDir, readSchemaVersion, hasKeyringToken, }: DiagnoseOptions) => Promise<Diagnosis>;
|
|
68
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACjE,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;CAC/C;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,CAAA;AAE5D,MAAM,WAAW,SAAS;IACxB,+FAA+F;IAC/F,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAA;IAC9C;;;;OAIG;IACH,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,OAAO,CAAA;KAAE,CAAA;IACzD,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAA;QACjB,mFAAmF;QACnF,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE,OAAO,CAAA;QACjB,QAAQ,EAAE,OAAO,CAAA;QACjB,qFAAqF;QACrF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAC3B,CAAA;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,+EAA+E;QAC/E,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;QACjC,MAAM,EAAE,MAAM,CAAA;QACd,+FAA+F;QAC/F,QAAQ,EAAE,OAAO,CAAA;KAClB,CAAA;IACD,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,GAAU,2EAO5B,eAAe,KAAG,OAAO,CAAC,SAAS,CA0CrC,CAAA"}
|
package/dist/diagnose.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { pathsAreOverridden, resolvePaths } from "@leemour/cli-core";
|
|
4
|
+
import { openCache } from "./cache/open.js";
|
|
5
|
+
import { SCHEMA_VERSION } from "./cache/schema.js";
|
|
6
|
+
/**
|
|
7
|
+
* Everything a command depends on, read from disk and **never from MAX**.
|
|
8
|
+
*
|
|
9
|
+
* It is a separate function rather than the body of the command because `forCommand` builds its
|
|
10
|
+
* own renderer over the real streams, so anything left inside a command action cannot be asserted
|
|
11
|
+
* on (`CLI-15`, and `src/session/adopt.ts` moved for the same reason).
|
|
12
|
+
*
|
|
13
|
+
* ⚠ **It must work when everything is broken**, which is the only time anybody runs it: no
|
|
14
|
+
* session, no configuration file, a cache from a newer version, a keyring that will not open. Each
|
|
15
|
+
* of those is a field in the answer, never an exception.
|
|
16
|
+
*
|
|
17
|
+
* ⚠ **It reads the state file directly instead of calling `readState`**, which invents a device
|
|
18
|
+
* identity and writes it out on first read. A diagnosis that creates the thing it is reporting on
|
|
19
|
+
* is not a diagnosis.
|
|
20
|
+
*/
|
|
21
|
+
export const diagnose = async ({ profile, env = process.env, stateDir, cacheDir, readSchemaVersion = schemaVersionOf, hasKeyringToken = () => false, }) => {
|
|
22
|
+
const paths = resolvePaths({ appName: "max-cli", prefix: "MAX", env });
|
|
23
|
+
const state = stateDir ?? paths.state;
|
|
24
|
+
const cacheHome = cacheDir ?? paths.cache;
|
|
25
|
+
const moved = pathsAreOverridden({ appName: "max-cli", prefix: "MAX", env });
|
|
26
|
+
const fromEnvironment = (env.MAX_TOKEN ?? "").trim() !== "";
|
|
27
|
+
const inKeyring = fromEnvironment ? false : hasKeyringToken(profile);
|
|
28
|
+
const stateFile = join(state, "profiles", `${profile}.json`);
|
|
29
|
+
const stored = readState(stateFile);
|
|
30
|
+
const cacheFile = join(cacheHome, `${profile}.db`);
|
|
31
|
+
const cacheExists = existsSync(cacheFile);
|
|
32
|
+
const schemaVersion = cacheExists ? await readSchemaVersion(cacheFile) : undefined;
|
|
33
|
+
const runsDirectory = join(state, "runs");
|
|
34
|
+
return {
|
|
35
|
+
token: {
|
|
36
|
+
present: fromEnvironment || inKeyring,
|
|
37
|
+
from: fromEnvironment ? "environment" : inKeyring ? "keyring" : "none",
|
|
38
|
+
},
|
|
39
|
+
keyring: { service: moved ? `max-cli:${paths.config}` : "max-cli", movedByEnvironment: moved },
|
|
40
|
+
session: {
|
|
41
|
+
stateFile,
|
|
42
|
+
exists: stored !== undefined,
|
|
43
|
+
deviceId: typeof stored?.deviceId === "string" && stored.deviceId !== "",
|
|
44
|
+
viewerId: typeof stored?.viewerId === "string" && stored.viewerId !== "",
|
|
45
|
+
logins: typeof stored?.logins === "number" ? stored.logins : null,
|
|
46
|
+
lastLoginAt: typeof stored?.lastLoginAt === "string" ? stored.lastLoginAt : null,
|
|
47
|
+
},
|
|
48
|
+
loggedInProfiles: profilesWithState(join(state, "profiles")),
|
|
49
|
+
cache: {
|
|
50
|
+
file: cacheFile,
|
|
51
|
+
exists: cacheExists,
|
|
52
|
+
schemaVersion,
|
|
53
|
+
speaks: SCHEMA_VERSION,
|
|
54
|
+
readable: !cacheExists || (schemaVersion !== undefined && schemaVersion <= SCHEMA_VERSION),
|
|
55
|
+
},
|
|
56
|
+
runs: { directory: runsDirectory, kept: countEntries(runsDirectory) },
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
/** A file that is missing, unreadable or not JSON is "no session", never a thrown error. */
|
|
60
|
+
const readState = (file) => {
|
|
61
|
+
try {
|
|
62
|
+
const parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
63
|
+
return typeof parsed === "object" && parsed !== null ? parsed : undefined;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* **Which profiles have been logged in**, which is not the same list as the configured ones —
|
|
71
|
+
* `config show` says so and cannot answer it, because a profile needs no configuration entry.
|
|
72
|
+
*/
|
|
73
|
+
const profilesWithState = (directory) => {
|
|
74
|
+
try {
|
|
75
|
+
return readdirSync(directory)
|
|
76
|
+
.filter((name) => name.endsWith(".json"))
|
|
77
|
+
.map((name) => name.slice(0, -".json".length))
|
|
78
|
+
.sort();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const countEntries = (directory) => {
|
|
85
|
+
try {
|
|
86
|
+
return readdirSync(directory).filter((name) => statSync(join(directory, name)).isDirectory()).length;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* The schema version written in the file, read **without migrating it**.
|
|
94
|
+
*
|
|
95
|
+
* It goes through `openCache`, the one seam that knows which SQLite this runtime has — and
|
|
96
|
+
* crucially `openCache` does **not** migrate: `migrate` runs inside `openStore`. So this reads the
|
|
97
|
+
* number the file already carries rather than the number it would carry after being upgraded,
|
|
98
|
+
* which is the whole point. A command asked to describe the state must not change it.
|
|
99
|
+
*/
|
|
100
|
+
const schemaVersionOf = async (file) => {
|
|
101
|
+
try {
|
|
102
|
+
const database = await openCache(file);
|
|
103
|
+
try {
|
|
104
|
+
const row = database.prepare("PRAGMA user_version").get();
|
|
105
|
+
return typeof row?.user_version === "number" ? row.user_version : undefined;
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
database.close();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=diagnose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/domain/map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAc,IAAI,EAAY,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/domain/map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAc,IAAI,EAAY,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAA;AAE3G;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,sFAAsF;IACtF,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACvB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,CAAA;CACd;AAED,eAAO,MAAM,MAAM,GAAI,KAAK,OAAO,KAAG,IAOpC,CAAA;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAQ,UAAe,KAAG,OAe7E,CAAA;AA0BD,oGAAoG;AACpG,eAAO,MAAM,SAAS,GAAI,KAAK,OAAO,KAAG,OAMvC,CAAA;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,OAAO,KAAG,OAQxC,CAAA;AAED,oGAAoG;AACpG,eAAO,MAAM,SAAS,GAAI,UAAU,OAAO,KAAG,GAAG,CAAC,EAAE,EAAE,MAAM,CAY3D,CAAA"}
|
package/dist/domain/map.js
CHANGED
|
@@ -19,6 +19,29 @@ export const toMessage = (raw, chatId, lookup = {}) => {
|
|
|
19
19
|
text: text(raw.text) ?? "",
|
|
20
20
|
outgoing: lookup.viewerId === undefined || senderId === undefined ? null : senderId === lookup.viewerId,
|
|
21
21
|
attachments: attachments(raw.attaches),
|
|
22
|
+
...linked(raw.link, lookup),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/** Measured 2026-09-22: `link: { type: "REPLY" | "FORWARD", chatId, message: { id, sender, text, time, attaches } }`. */
|
|
26
|
+
const linked = (value, lookup) => {
|
|
27
|
+
const link = asRecord(value);
|
|
28
|
+
const quoted = asRecord(link?.message);
|
|
29
|
+
const message = quoted ? toQuoted(quoted, lookup) : null;
|
|
30
|
+
return {
|
|
31
|
+
replyTo: link?.type === "REPLY" ? message : null,
|
|
32
|
+
forwardedFrom: link?.type === "FORWARD" ? message : null,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const toQuoted = (raw, lookup) => {
|
|
36
|
+
const senderId = asId(raw.sender) ?? null;
|
|
37
|
+
return {
|
|
38
|
+
id: asId(raw.id) ?? "",
|
|
39
|
+
senderId,
|
|
40
|
+
senderName: senderId ? (lookup.names?.get(senderId) ?? null) : null,
|
|
41
|
+
timestamp: timestamp(raw.time),
|
|
42
|
+
text: text(raw.text) ?? "",
|
|
43
|
+
attachments: attachments(raw.attaches),
|
|
44
|
+
outgoing: lookup.viewerId === undefined || senderId === null ? null : senderId === lookup.viewerId,
|
|
22
45
|
};
|
|
23
46
|
};
|
|
24
47
|
/** `lastMessagedAt` is always `null` here: MAX puts it on the chat, and only the store has both. */
|
|
@@ -95,8 +118,8 @@ const phone = (value) => {
|
|
|
95
118
|
return text(number) ?? (typeof number === "number" || typeof number === "bigint" ? `+${number}` : null);
|
|
96
119
|
};
|
|
97
120
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
121
|
+
* What an attachment is and where it lives — never its bytes. The link fields are the ones
|
|
122
|
+
* `pnpm probe:attachments` measured on 2026-09-22: `baseUrl` on a photo, `url` on a share.
|
|
100
123
|
*/
|
|
101
124
|
const attachments = (value) => {
|
|
102
125
|
if (!Array.isArray(value))
|
|
@@ -104,6 +127,22 @@ const attachments = (value) => {
|
|
|
104
127
|
return value
|
|
105
128
|
.map(asRecord)
|
|
106
129
|
.filter((entry) => entry !== undefined)
|
|
107
|
-
.map((entry) =>
|
|
130
|
+
.map((entry) => {
|
|
131
|
+
const url = text(entry.baseUrl) ?? text(entry.url);
|
|
132
|
+
const width = count(entry.width);
|
|
133
|
+
const height = count(entry.height);
|
|
134
|
+
const title = text(entry.title);
|
|
135
|
+
const name = text(entry.name);
|
|
136
|
+
const size = count(entry.size);
|
|
137
|
+
return {
|
|
138
|
+
kind: typeof entry._type === "string" ? entry._type.toLowerCase() : "unknown",
|
|
139
|
+
...(url ? { url } : {}),
|
|
140
|
+
...(width !== null ? { width } : {}),
|
|
141
|
+
...(height !== null ? { height } : {}),
|
|
142
|
+
...(title ? { title } : {}),
|
|
143
|
+
...(name ? { name } : {}),
|
|
144
|
+
...(size !== null ? { size } : {}),
|
|
145
|
+
};
|
|
146
|
+
});
|
|
108
147
|
};
|
|
109
148
|
//# sourceMappingURL=map.js.map
|
package/dist/domain/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/domain/map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,sBAAsB,CAAA;AAkBzD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAY,EAAQ,EAAE,CAAC,CAAC;IAC7C,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;IACtB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IACtB,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IACxB,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;IACnC,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC9E,iBAAiB,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC;CAChD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,MAAU,EAAE,SAAqB,EAAE,EAAW,EAAE;IACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAEjC,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;QACtB,MAAM;QACN,QAAQ,EAAE,QAAQ,IAAI,IAAI;QAC1B,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACnE,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;QAC3D,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;QAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ;QACvG,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/domain/map.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/models.d.ts
CHANGED
|
@@ -19,6 +19,30 @@ export interface Chat {
|
|
|
19
19
|
export interface Attachment {
|
|
20
20
|
/** Lower-cased MAX type: `photo`, `video`, `file`, `share`, `call`, `control`, `sticker`… */
|
|
21
21
|
kind: string;
|
|
22
|
+
/**
|
|
23
|
+
* A photo's image or a shared page. ⚠ Measured 2026-09-22: a photo link opens with no cookie and
|
|
24
|
+
* no token, so whoever holds it sees the picture.
|
|
25
|
+
*/
|
|
26
|
+
url?: string;
|
|
27
|
+
width?: number;
|
|
28
|
+
height?: number;
|
|
29
|
+
/** A shared page's title. */
|
|
30
|
+
title?: string;
|
|
31
|
+
/** ⚠ Not measured: no file has been seen on the wire yet. Read if present. */
|
|
32
|
+
name?: string;
|
|
33
|
+
size?: number;
|
|
34
|
+
}
|
|
35
|
+
/** The message a reply answers or a forward carries — MAX sends it whole, inside the one that links to it. */
|
|
36
|
+
export interface QuotedMessage {
|
|
37
|
+
id: Id;
|
|
38
|
+
senderId: Id | null;
|
|
39
|
+
senderName: string | null;
|
|
40
|
+
/** ISO 8601, or `null` when the quote did not say. */
|
|
41
|
+
timestamp: string | null;
|
|
42
|
+
text: string;
|
|
43
|
+
attachments: Attachment[];
|
|
44
|
+
/** Whether this account wrote it. `null` when we do not know who we are. */
|
|
45
|
+
outgoing: boolean | null;
|
|
22
46
|
}
|
|
23
47
|
export interface Message {
|
|
24
48
|
id: Id;
|
|
@@ -40,6 +64,18 @@ export interface Message {
|
|
|
40
64
|
/** Whether this account sent it. `null` when we do not know who we are. */
|
|
41
65
|
outgoing: boolean | null;
|
|
42
66
|
attachments: Attachment[];
|
|
67
|
+
replyTo: QuotedMessage | null;
|
|
68
|
+
forwardedFrom: QuotedMessage | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A message found by searching, carrying the chat's name as well as its id.
|
|
72
|
+
*
|
|
73
|
+
* A search spans every chat, so an answer that named only the id would make the reader look each
|
|
74
|
+
* one up to understand their own results. The title is what the store already holds; it is `null`
|
|
75
|
+
* for a chat MAX never titled.
|
|
76
|
+
*/
|
|
77
|
+
export interface MessageHit extends Message {
|
|
78
|
+
chatTitle: string | null;
|
|
43
79
|
}
|
|
44
80
|
export interface Contact {
|
|
45
81
|
id: Id;
|
|
@@ -72,4 +108,14 @@ export interface Profile {
|
|
|
72
108
|
name: string | null;
|
|
73
109
|
phone: string | null;
|
|
74
110
|
}
|
|
111
|
+
/** One message of a window around another, which carries `anchor: true`. */
|
|
112
|
+
export type WindowedMessage = Message & {
|
|
113
|
+
anchor?: true;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* When a message was sent, read from its id: **`id >> 16` is the send time in milliseconds**, the
|
|
117
|
+
* low 16 bits a counter. Measured 2026-09-22 on three messages across two days, exact every time.
|
|
118
|
+
* `undefined` for anything that is not a message id.
|
|
119
|
+
*/
|
|
120
|
+
export declare const timeOfMessageId: (id: Id) => number | undefined;
|
|
75
121
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/domain/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2GAA2G;AAC3G,MAAM,MAAM,EAAE,GAAG,MAAM,CAAA;AAEvB,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;AAEjE,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,EAAE,CAAA;IACN,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,QAAQ,CAAA;IACd,mEAAmE;IACnE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/domain/models.ts"],"names":[],"mappings":"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"}
|