@leemour/max-cli 0.4.0 → 0.6.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 +14 -5
- package/dist/bin/max.js +0 -0
- package/dist/cache/store.d.ts +14 -8
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +30 -5
- package/dist/cache/store.js.map +1 -1
- package/dist/client.d.ts +93 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +347 -59
- package/dist/client.js.map +1 -1
- package/dist/commands/chats.d.ts.map +1 -1
- package/dist/commands/chats.js +20 -0
- package/dist/commands/chats.js.map +1 -1
- package/dist/commands/commands.d.ts +8 -0
- package/dist/commands/commands.d.ts.map +1 -0
- package/dist/commands/commands.js +36 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +29 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +18 -0
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/context.d.ts +18 -0
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +22 -0
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/inbox.d.ts +14 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +90 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/messages.d.ts.map +1 -1
- package/dist/commands/messages.js +55 -4
- package/dist/commands/messages.js.map +1 -1
- package/dist/commands/reactions.d.ts +3 -0
- package/dist/commands/reactions.d.ts.map +1 -0
- package/dist/commands/reactions.js +26 -0
- package/dist/commands/reactions.js.map +1 -0
- package/dist/commands/recipients.d.ts +9 -0
- package/dist/commands/recipients.d.ts.map +1 -0
- package/dist/commands/recipients.js +68 -0
- package/dist/commands/recipients.js.map +1 -0
- package/dist/commands/sends.d.ts +4 -0
- package/dist/commands/sends.d.ts.map +1 -0
- package/dist/commands/sends.js +21 -0
- package/dist/commands/sends.js.map +1 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +80 -15
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +2 -1
- package/dist/commands/skill.js.map +1 -1
- package/dist/config.d.ts +54 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +98 -16
- package/dist/config.js.map +1 -1
- package/dist/domain/map.d.ts +3 -1
- package/dist/domain/map.d.ts.map +1 -1
- package/dist/domain/map.js +15 -1
- package/dist/domain/map.js.map +1 -1
- package/dist/domain/models.d.ts +55 -1
- package/dist/domain/models.d.ts.map +1 -1
- package/dist/domain/models.js.map +1 -1
- package/dist/download.d.ts +15 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +60 -0
- package/dist/download.js.map +1 -0
- package/dist/generated/client.generated.d.ts +14 -0
- package/dist/generated/client.generated.d.ts.map +1 -1
- package/dist/generated/client.generated.js +14 -0
- package/dist/generated/client.generated.js.map +1 -1
- package/dist/generated/opcodes.generated.d.ts +15 -0
- package/dist/generated/opcodes.generated.d.ts.map +1 -1
- package/dist/generated/opcodes.generated.js +15 -0
- package/dist/generated/opcodes.generated.js.map +1 -1
- package/dist/generated/operations.generated.d.ts +99 -1
- package/dist/generated/operations.generated.d.ts.map +1 -1
- package/dist/generated/operations.generated.js +13 -1
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/markdown.d.ts +18 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +52 -0
- package/dist/markdown.js.map +1 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +10 -0
- package/dist/program.js.map +1 -1
- package/dist/rendering/messages.d.ts.map +1 -1
- package/dist/rendering/messages.js +6 -0
- package/dist/rendering/messages.js.map +1 -1
- package/dist/resolve.d.ts +15 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +48 -0
- package/dist/resolve.js.map +1 -0
- package/dist/runs/recording.d.ts.map +1 -1
- package/dist/runs/recording.js +7 -0
- package/dist/runs/recording.js.map +1 -1
- package/dist/runs/run.d.ts +2 -0
- package/dist/runs/run.d.ts.map +1 -1
- package/dist/runs/run.js +1 -0
- package/dist/runs/run.js.map +1 -1
- package/dist/sends/guard.d.ts +26 -0
- package/dist/sends/guard.d.ts.map +1 -0
- package/dist/sends/guard.js +48 -0
- package/dist/sends/guard.js.map +1 -0
- package/dist/sends/journal.d.ts +29 -0
- package/dist/sends/journal.d.ts.map +1 -0
- package/dist/sends/journal.js +40 -0
- package/dist/sends/journal.js.map +1 -0
- package/dist/sends/recipients.d.ts +29 -0
- package/dist/sends/recipients.d.ts.map +1 -0
- package/dist/sends/recipients.js +62 -0
- package/dist/sends/recipients.js.map +1 -0
- package/dist/session/adopt.d.ts.map +1 -1
- package/dist/session/adopt.js +7 -6
- package/dist/session/adopt.js.map +1 -1
- package/dist/session/browser.d.ts +55 -0
- package/dist/session/browser.d.ts.map +1 -0
- package/dist/session/browser.js +292 -0
- package/dist/session/browser.js.map +1 -0
- package/dist/session/handshake.d.ts +3 -1
- package/dist/session/handshake.d.ts.map +1 -1
- package/dist/session/handshake.js +3 -1
- package/dist/session/handshake.js.map +1 -1
- package/dist/session/login.d.ts +20 -0
- package/dist/session/login.d.ts.map +1 -0
- package/dist/session/login.js +66 -0
- package/dist/session/login.js.map +1 -0
- package/dist/session/prompt.d.ts +3 -1
- package/dist/session/prompt.d.ts.map +1 -1
- package/dist/session/prompt.js +2 -2
- package/dist/session/prompt.js.map +1 -1
- package/dist/session/qr-terminal.d.ts +9 -0
- package/dist/session/qr-terminal.d.ts.map +1 -0
- package/dist/session/qr-terminal.js +34 -0
- package/dist/session/qr-terminal.js.map +1 -0
- package/dist/session/store.d.ts +2 -0
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +2 -0
- package/dist/session/store.js.map +1 -1
- package/dist/spec/index.d.ts.map +1 -1
- package/dist/spec/index.js +14 -1
- package/dist/spec/index.js.map +1 -1
- package/dist/spec/operations/attachments.d.ts +15 -0
- package/dist/spec/operations/attachments.d.ts.map +1 -0
- package/dist/spec/operations/attachments.js +38 -0
- package/dist/spec/operations/attachments.js.map +1 -0
- package/dist/spec/operations/login.d.ts +64 -0
- package/dist/spec/operations/login.d.ts.map +1 -0
- package/dist/spec/operations/login.js +99 -0
- package/dist/spec/operations/login.js.map +1 -0
- package/dist/spec/operations/messages.d.ts +27 -1
- package/dist/spec/operations/messages.d.ts.map +1 -1
- package/dist/spec/operations/messages.js +46 -2
- package/dist/spec/operations/messages.js.map +1 -1
- package/dist/testing/mock-max.d.ts +10 -4
- package/dist/testing/mock-max.d.ts.map +1 -1
- package/dist/testing/mock-max.js +5 -1
- package/dist/testing/mock-max.js.map +1 -1
- package/dist/testing/sandbox.js +3 -0
- package/dist/testing/sandbox.js.map +1 -1
- package/dist/testing/unscripted.d.ts +2 -0
- package/dist/testing/unscripted.d.ts.map +1 -0
- package/dist/testing/unscripted.js +18 -0
- package/dist/testing/unscripted.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +31 -22
- package/skills/max-cli/SKILL.md +25 -6
- package/dist/commands/login.d.ts +0 -15
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -43
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -10
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js +0 -22
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/me.d.ts +0 -3
- package/dist/commands/me.d.ts.map +0 -1
- package/dist/commands/me.js +0 -18
- package/dist/commands/me.js.map +0 -1
- package/dist/commands/send.d.ts +0 -10
- package/dist/commands/send.d.ts.map +0 -1
- package/dist/commands/send.js +0 -30
- package/dist/commands/send.js.map +0 -1
- package/dist/protocol/session.d.ts +0 -54
- package/dist/protocol/session.d.ts.map +0 -1
- package/dist/protocol/session.js +0 -57
- package/dist/protocol/session.js.map +0 -1
- package/dist/spec/operations/auth.d.ts +0 -42
- package/dist/spec/operations/auth.d.ts.map +0 -1
package/dist/runs/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runs/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAmB,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runs/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Id } from "../domain/models.js";
|
|
2
|
+
import type { SendEntry, SendJournal, SendKind } from "./journal.js";
|
|
3
|
+
import type { RecipientList } from "./recipients.js";
|
|
4
|
+
/** What `MaxClient.messages.send` asks before it sends, and tells after — on every outcome. */
|
|
5
|
+
export interface SendGuard {
|
|
6
|
+
check(chatId: Id, kind?: SendKind): void;
|
|
7
|
+
record(entry: Omit<SendEntry, "at" | "profile">): void;
|
|
8
|
+
}
|
|
9
|
+
export interface SendGuardOptions {
|
|
10
|
+
profile: string;
|
|
11
|
+
readOnly: boolean;
|
|
12
|
+
/** Named in the refusal, so the owner can find what decided it. */
|
|
13
|
+
readOnlyFrom: string;
|
|
14
|
+
sendsPerHour: number;
|
|
15
|
+
journal: SendJournal;
|
|
16
|
+
recipients: RecipientList;
|
|
17
|
+
warn: (message: string) => void;
|
|
18
|
+
now?: () => Date;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* These stop a model that was talked into sending by a message it read. They do **not** stop an
|
|
22
|
+
* agent that edits the configuration itself — that needs a boundary outside this process
|
|
23
|
+
* (`docs/security.md`).
|
|
24
|
+
*/
|
|
25
|
+
export declare const sendGuard: ({ profile, readOnly, readOnlyFrom, sendsPerHour, journal, recipients, warn, now, }: SendGuardOptions) => SendGuard;
|
|
26
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/sends/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAIpD,+FAA+F;AAC/F,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IACxC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,CAAA;CACvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,WAAW,CAAA;IACpB,UAAU,EAAE,aAAa,CAAA;IACzB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,oFASvB,gBAAgB,KAAG,SAoDpB,CAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { CliError } from "@leemour/cli-core";
|
|
2
|
+
const HOUR_MS = 60 * 60 * 1000;
|
|
3
|
+
/**
|
|
4
|
+
* These stop a model that was talked into sending by a message it read. They do **not** stop an
|
|
5
|
+
* agent that edits the configuration itself — that needs a boundary outside this process
|
|
6
|
+
* (`docs/security.md`).
|
|
7
|
+
*/
|
|
8
|
+
export const sendGuard = ({ profile, readOnly, readOnlyFrom, sendsPerHour, journal, recipients, warn, now = () => new Date(), }) => ({
|
|
9
|
+
check: (chatId, kind = "message") => {
|
|
10
|
+
if (readOnly) {
|
|
11
|
+
throw new CliError("permission_error", `profile ${profile} is read-only (readOnly, from the ${readOnlyFrom}) — it cannot send or react`);
|
|
12
|
+
}
|
|
13
|
+
const allowed = recipients.read();
|
|
14
|
+
if (allowed && !allowed.some((chat) => chat.id === chatId)) {
|
|
15
|
+
throw new CliError("confirmation_required", `chat ${chatId} is not on the recipient list of profile ${profile} — ` +
|
|
16
|
+
`the owner adds it with \`max ${profile} recipients add ${chatId}\``, { chatId });
|
|
17
|
+
}
|
|
18
|
+
// The limit is about messages, by the owner's ruling (`NEED-168`): a reaction wakes nobody up.
|
|
19
|
+
if (kind === "reaction")
|
|
20
|
+
return;
|
|
21
|
+
const since = now().getTime() - HOUR_MS;
|
|
22
|
+
const counted = journal
|
|
23
|
+
.entries()
|
|
24
|
+
.filter((entry) => entry.kind !== "reaction")
|
|
25
|
+
.filter((entry) => entry.outcome === "sent" || entry.outcome === "outcome_unknown")
|
|
26
|
+
.map((entry) => Date.parse(entry.at))
|
|
27
|
+
.filter((time) => time > since)
|
|
28
|
+
.sort((a, b) => a - b);
|
|
29
|
+
if (counted.length >= sendsPerHour) {
|
|
30
|
+
// The limit may have been lowered below what the last hour already holds.
|
|
31
|
+
const nextMs = (counted[counted.length - sendsPerHour] ?? 0) + HOUR_MS;
|
|
32
|
+
const next = new Date(nextMs).toISOString();
|
|
33
|
+
throw new CliError("rate_limited", `profile ${profile} has sent ${counted.length} messages in the last hour, and its limit is ` +
|
|
34
|
+
`${sendsPerHour} (sendsPerHour) — the next send is possible at ${next}`, { retryAfterMs: nextMs - now().getTime(), retryAt: next });
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
// After a send, a failure to write here must not become the command's answer: the message is
|
|
38
|
+
// already with a person, and an error would invite the caller to send it again.
|
|
39
|
+
record: (entry) => {
|
|
40
|
+
try {
|
|
41
|
+
journal.append({ at: now().toISOString(), profile, ...entry });
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
warn(`this send is not in the send journal: ${error instanceof Error ? error.message : String(error)}`);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/sends/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Id } from "../domain/models.js";
|
|
2
|
+
export type SendOutcome = "sent" | "outcome_unknown" | "refused" | "failed";
|
|
3
|
+
/** Absent in the journal means a message: that is every line written before reactions were guarded. */
|
|
4
|
+
export type SendKind = "message" | "reaction";
|
|
5
|
+
/** One attempt to send. **Never the text** — only its length. */
|
|
6
|
+
export interface SendEntry {
|
|
7
|
+
at: string;
|
|
8
|
+
profile: string;
|
|
9
|
+
chatId: Id;
|
|
10
|
+
outcome: SendOutcome;
|
|
11
|
+
kind?: SendKind;
|
|
12
|
+
messageId?: Id;
|
|
13
|
+
cid?: number;
|
|
14
|
+
length?: number;
|
|
15
|
+
errorCode?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* `<state dir>/sends/<profile>.jsonl` — beside `runs`, never in the cache directory, so that
|
|
19
|
+
* `max cache clear` cannot erase what was sent in the owner's name (the reason of `NEED-51`).
|
|
20
|
+
*/
|
|
21
|
+
export declare const sendsPathFor: (profile: string, env?: NodeJS.ProcessEnv) => string;
|
|
22
|
+
export declare class SendJournal {
|
|
23
|
+
readonly path: string;
|
|
24
|
+
constructor(path: string);
|
|
25
|
+
append(entry: SendEntry): void;
|
|
26
|
+
/** Oldest first. A line that does not parse is skipped: a torn last write must not block sending. */
|
|
27
|
+
entries(): SendEntry[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/sends/journal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAE7C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,iBAAiB,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3E,uGAAuG;AACvG,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7C,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,EAAE,CAAA;IACV,OAAO,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,SAAS,CAAC,EAAE,EAAE,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,MAAK,MAAM,CAAC,UAAwB,KAAG,MACc,CAAA;AAEnG,qBAAa,WAAW;IACV,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAEjC,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAK9B,qGAAqG;IACrG,OAAO,IAAI,SAAS,EAAE;CAkBvB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { resolvePaths } from "@leemour/cli-core";
|
|
4
|
+
/**
|
|
5
|
+
* `<state dir>/sends/<profile>.jsonl` — beside `runs`, never in the cache directory, so that
|
|
6
|
+
* `max cache clear` cannot erase what was sent in the owner's name (the reason of `NEED-51`).
|
|
7
|
+
*/
|
|
8
|
+
export const sendsPathFor = (profile, env = process.env) => join(resolvePaths({ appName: "max-cli", prefix: "MAX", env }).state, "sends", `${profile}.jsonl`);
|
|
9
|
+
export class SendJournal {
|
|
10
|
+
path;
|
|
11
|
+
constructor(path) {
|
|
12
|
+
this.path = path;
|
|
13
|
+
}
|
|
14
|
+
append(entry) {
|
|
15
|
+
mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 });
|
|
16
|
+
appendFileSync(this.path, `${JSON.stringify(entry)}\n`, { mode: 0o600 });
|
|
17
|
+
}
|
|
18
|
+
/** Oldest first. A line that does not parse is skipped: a torn last write must not block sending. */
|
|
19
|
+
entries() {
|
|
20
|
+
let text;
|
|
21
|
+
try {
|
|
22
|
+
text = readFileSync(this.path, "utf8");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return text
|
|
28
|
+
.split("\n")
|
|
29
|
+
.filter((line) => line.trim() !== "")
|
|
30
|
+
.flatMap((line) => {
|
|
31
|
+
try {
|
|
32
|
+
return [JSON.parse(line)];
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/sends/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAqBhD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG,EAAU,EAAE,CAC5F,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,QAAQ,CAAC,CAAA;AAEnG,MAAM,OAAO,WAAW;IACD;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAErC,MAAM,CAAC,KAAgB;QACrB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/D,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC1E,CAAC;IAED,qGAAqG;IACrG,OAAO;QACL,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,IAAI;aACR,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;aACpC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAChB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC,CAAA;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC,CAAC,CAAA;IACN,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Id } from "../domain/models.js";
|
|
2
|
+
export interface Recipient {
|
|
3
|
+
id: Id;
|
|
4
|
+
title: string | null;
|
|
5
|
+
addedAt: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A state file, not a setting: the configuration schema has deliberately no place for a chat id
|
|
9
|
+
* (`src/config.ts`), and this list is data about a profile rather than a preference.
|
|
10
|
+
*/
|
|
11
|
+
export declare const recipientsPathFor: (profile: string, env?: NodeJS.ProcessEnv) => string;
|
|
12
|
+
/**
|
|
13
|
+
* The chats a profile may send to. **No file means the check is off**; a file with no chats in it
|
|
14
|
+
* means nowhere. Optional by the owner's ruling (`NEED-159`).
|
|
15
|
+
*/
|
|
16
|
+
export declare class RecipientList {
|
|
17
|
+
#private;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
constructor(path: string);
|
|
20
|
+
/** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
|
|
21
|
+
read(): Recipient[] | undefined;
|
|
22
|
+
/** Whether it was new. */
|
|
23
|
+
add(recipient: Recipient): boolean;
|
|
24
|
+
/** The id or the title as it was stored; `undefined` when neither matched. */
|
|
25
|
+
remove(reference: string): Recipient | undefined;
|
|
26
|
+
/** Whether there was a list to turn off. */
|
|
27
|
+
off(): boolean;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=recipients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.d.ts","sourceRoot":"","sources":["../../src/sends/recipients.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAE7C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,EAAE,CAAA;IACN,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,EAAE,MAAK,MAAM,CAAC,UAAwB,KAAG,MACsB,CAAA;AAEhH;;;GAGG;AACH,qBAAa,aAAa;;IACZ,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAEjC,mGAAmG;IACnG,IAAI,IAAI,SAAS,EAAE,GAAG,SAAS;IAe/B,0BAA0B;IAC1B,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;IAOlC,8EAA8E;IAC9E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAUhD,4CAA4C;IAC5C,GAAG,IAAI,OAAO;CASf"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { CliError, resolvePaths, writeSecurely } from "@leemour/cli-core";
|
|
4
|
+
/**
|
|
5
|
+
* A state file, not a setting: the configuration schema has deliberately no place for a chat id
|
|
6
|
+
* (`src/config.ts`), and this list is data about a profile rather than a preference.
|
|
7
|
+
*/
|
|
8
|
+
export const recipientsPathFor = (profile, env = process.env) => join(resolvePaths({ appName: "max-cli", prefix: "MAX", env }).state, "profiles", `${profile}.recipients.json`);
|
|
9
|
+
/**
|
|
10
|
+
* The chats a profile may send to. **No file means the check is off**; a file with no chats in it
|
|
11
|
+
* means nowhere. Optional by the owner's ruling (`NEED-159`).
|
|
12
|
+
*/
|
|
13
|
+
export class RecipientList {
|
|
14
|
+
path;
|
|
15
|
+
constructor(path) {
|
|
16
|
+
this.path = path;
|
|
17
|
+
}
|
|
18
|
+
/** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
|
|
19
|
+
read() {
|
|
20
|
+
if (!existsSync(this.path))
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(readFileSync(this.path, "utf8"));
|
|
24
|
+
if (!Array.isArray(parsed.chats))
|
|
25
|
+
throw new Error("no `chats` array");
|
|
26
|
+
return parsed.chats;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
throw new CliError("configuration_error", `the recipient list ${this.path} cannot be read (${error instanceof Error ? error.message : String(error)}) — ` +
|
|
30
|
+
"fix the file or turn the list off with `max recipients off`");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Whether it was new. */
|
|
34
|
+
add(recipient) {
|
|
35
|
+
const chats = this.read() ?? [];
|
|
36
|
+
if (chats.some((chat) => chat.id === recipient.id))
|
|
37
|
+
return false;
|
|
38
|
+
this.#write([...chats, recipient]);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
/** The id or the title as it was stored; `undefined` when neither matched. */
|
|
42
|
+
remove(reference) {
|
|
43
|
+
const chats = this.read() ?? [];
|
|
44
|
+
const wanted = reference.trim();
|
|
45
|
+
const gone = chats.find((chat) => chat.id === wanted) ??
|
|
46
|
+
chats.find((chat) => chat.title?.toLocaleLowerCase() === wanted.toLocaleLowerCase());
|
|
47
|
+
if (gone)
|
|
48
|
+
this.#write(chats.filter((chat) => chat !== gone));
|
|
49
|
+
return gone;
|
|
50
|
+
}
|
|
51
|
+
/** Whether there was a list to turn off. */
|
|
52
|
+
off() {
|
|
53
|
+
if (!existsSync(this.path))
|
|
54
|
+
return false;
|
|
55
|
+
rmSync(this.path);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
#write(chats) {
|
|
59
|
+
writeSecurely(this.path, `${JSON.stringify({ chats }, null, 2)}\n`, 0o600);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=recipients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.js","sourceRoot":"","sources":["../../src/sends/recipients.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../src/session/adopt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GAAU,QAAQ,SAAS,EAAE,OAAO,YAAY,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../src/session/adopt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GAAU,QAAQ,SAAS,EAAE,OAAO,YAAY,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAUpG,CAAA"}
|
package/dist/session/adopt.js
CHANGED
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
* cannot be driven by a test — and this ordering is too expensive to hold on trust.
|
|
18
18
|
*/
|
|
19
19
|
export const adoptToken = async (client, store, token) => {
|
|
20
|
+
const before = store.readToken();
|
|
20
21
|
await client.connect({ token });
|
|
21
|
-
// ⚠ **Only if the login did not already leave a better one.** MAX answers
|
|
22
|
-
//
|
|
23
|
-
// would
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
if (store.readToken() ===
|
|
22
|
+
// ⚠ **Only if the login did not already leave a better one.** MAX answers a login with a fresh
|
|
23
|
+
// token when the one presented has aged, and `connect` keeps it (`MAX-11`); overwriting that here
|
|
24
|
+
// would put back the older credential. Comparing with what was stored before, rather than asking
|
|
25
|
+
// whether anything is stored, is what lets a new login replace an old session at all — until
|
|
26
|
+
// 2026-09-24 a profile that already held a token kept it, and the command still said "stored".
|
|
27
|
+
if (store.readToken() === before)
|
|
27
28
|
store.writeToken(token);
|
|
28
29
|
};
|
|
29
30
|
//# sourceMappingURL=adopt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/session/adopt.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAiB,EAAE,KAAmB,EAAE,KAAa,EAAiB,EAAE;IACvG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAE/B,
|
|
1
|
+
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/session/adopt.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAiB,EAAE,KAAmB,EAAE,KAAa,EAAiB,EAAE;IACvG,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAA;IAChC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAE/B,+FAA+F;IAC/F,kGAAkG;IAClG,iGAAiG;IACjG,6FAA6F;IAC7F,+FAA+F;IAC/F,IAAI,KAAK,CAAC,SAAS,EAAE,KAAK,MAAM;QAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAC3D,CAAC,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
import type { Closeable } from "../deadline.js";
|
|
3
|
+
/**
|
|
4
|
+
* What `session start` needs from a browser. Injected in tests, which must never open a window on
|
|
5
|
+
* the owner's desktop — the real ones refuse inside the test sandbox.
|
|
6
|
+
*/
|
|
7
|
+
export interface BrowserDoors {
|
|
8
|
+
/** Shows a page in whatever browser the system opens links with. */
|
|
9
|
+
open: (url: string) => Promise<void>;
|
|
10
|
+
/** Opens web.max.ru in a Chromium-family browser and waits for the page to be logged in. */
|
|
11
|
+
chromiumToken: (options: {
|
|
12
|
+
track: (closeable: Closeable) => void;
|
|
13
|
+
waitMs: number;
|
|
14
|
+
}) => Promise<string>;
|
|
15
|
+
}
|
|
16
|
+
export declare const realBrowser: BrowserDoors;
|
|
17
|
+
/**
|
|
18
|
+
* The QR page, served from `127.0.0.1` rather than written to a file: a browser installed as a
|
|
19
|
+
* snap cannot read our temporary directory, and a file would leave the link on disk. The path is
|
|
20
|
+
* random, so another local user guessing the port finds nothing.
|
|
21
|
+
*/
|
|
22
|
+
export declare const serveQrPage: (link: string) => Promise<{
|
|
23
|
+
url: string;
|
|
24
|
+
} & Closeable>;
|
|
25
|
+
export declare const openUrl: (url: string) => Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Chrome, Chromium, Edge or Brave — any browser that speaks the DevTools protocol. `MAX_BROWSER`
|
|
28
|
+
* names another. A snap build is skipped: it keeps its own `/tmp`, so the profile we hand it would
|
|
29
|
+
* land where we cannot delete it.
|
|
30
|
+
*/
|
|
31
|
+
export declare const findChromium: () => string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* web.max.ru logs itself in — it asks MAX for the QR code, or sends the SMS — in a real browser with
|
|
34
|
+
* a profile of its own, and we read the token it stores once it has one. MAX sees its own web
|
|
35
|
+
* client do the login, not our socket.
|
|
36
|
+
*
|
|
37
|
+
* ⚠ The profile holds a live session, so it is deleted on every way out: success, a closed window,
|
|
38
|
+
* `--timeout`, Ctrl-C.
|
|
39
|
+
*/
|
|
40
|
+
export declare const tokenFromChromium: ({ track, waitMs, }: {
|
|
41
|
+
track: (closeable: Closeable) => void;
|
|
42
|
+
waitMs: number;
|
|
43
|
+
}) => Promise<string>;
|
|
44
|
+
export declare class ChromiumSession implements Closeable {
|
|
45
|
+
#private;
|
|
46
|
+
constructor(child: ChildProcess, profile: string, port: number, graceMs?: number);
|
|
47
|
+
waitForToken(waitMs: number): Promise<string>;
|
|
48
|
+
close(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The stored value is JSON holding the token, or the token itself — which one is not measured yet.
|
|
52
|
+
* Either way nothing here prints it.
|
|
53
|
+
*/
|
|
54
|
+
export declare const tokenIn: (stored: string) => string | undefined;
|
|
55
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/session/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAA;AAW7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,4FAA4F;IAC5F,aAAa,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACvG;AAED,eAAO,MAAM,WAAW,EAAE,YAGzB,CAAA;AAKD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAkCnF,CAAA;AASD,eAAO,MAAM,OAAO,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,IAAI,CAmBvD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAO,MAAM,GAAG,SA0CxC,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAU,oBAGrC;IACD,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACrC,MAAM,EAAE,MAAM,CAAA;CACf,KAAG,OAAO,CAAC,MAAM,CAiCjB,CAAA;AAED,qBAAa,eAAgB,YAAW,SAAS;;gBAQnC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,SAAQ;IAWzE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAuCvB;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,SAWjD,CAAA"}
|