claude-code-infinite 1.0.30 → 1.0.32
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 +54 -47
- package/dist/claude-auth-status.d.ts +50 -0
- package/dist/claude-auth-status.d.ts.map +1 -0
- package/dist/claude-auth-status.js +213 -0
- package/dist/claude-auth-status.js.map +1 -0
- package/dist/claude-auth.d.ts +2 -1
- package/dist/claude-auth.d.ts.map +1 -1
- package/dist/claude-auth.js +2 -1
- package/dist/claude-auth.js.map +1 -1
- package/dist/claude-plan-warning.d.ts +13 -40
- package/dist/claude-plan-warning.d.ts.map +1 -1
- package/dist/claude-plan-warning.js +24 -75
- package/dist/claude-plan-warning.js.map +1 -1
- package/dist/cli-args.d.ts +10 -0
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +30 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli-main.js +119 -17
- package/dist/cli-main.js.map +1 -1
- package/dist/diagnostics-schema.d.ts +5 -2
- package/dist/diagnostics-schema.d.ts.map +1 -1
- package/dist/diagnostics-schema.js +26 -6
- package/dist/diagnostics-schema.js.map +1 -1
- package/dist/diagnostics.d.ts +5 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +7 -2
- package/dist/diagnostics.js.map +1 -1
- package/dist/hooks.d.ts +41 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +79 -4
- package/dist/hooks.js.map +1 -1
- package/dist/memtree-mcp.d.ts +7 -0
- package/dist/memtree-mcp.d.ts.map +1 -1
- package/dist/memtree-mcp.js +16 -1
- package/dist/memtree-mcp.js.map +1 -1
- package/dist/memtree.d.ts +9 -0
- package/dist/memtree.d.ts.map +1 -1
- package/dist/memtree.js +16 -0
- package/dist/memtree.js.map +1 -1
- package/dist/model-context.d.ts +80 -0
- package/dist/model-context.d.ts.map +1 -0
- package/dist/model-context.js +192 -0
- package/dist/model-context.js.map +1 -0
- package/dist/notices.d.ts +2 -0
- package/dist/notices.d.ts.map +1 -1
- package/dist/notices.js +2 -0
- package/dist/notices.js.map +1 -1
- package/dist/payment-gate.d.ts +2 -0
- package/dist/payment-gate.d.ts.map +1 -1
- package/dist/payment-gate.js +1 -1
- package/dist/payment-gate.js.map +1 -1
- package/dist/proxy.d.ts +28 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +332 -42
- package/dist/proxy.js.map +1 -1
- package/dist/reqlog.d.ts +11 -2
- package/dist/reqlog.d.ts.map +1 -1
- package/dist/reqlog.js.map +1 -1
- package/dist/request-sizing.d.ts +2 -0
- package/dist/request-sizing.d.ts.map +1 -1
- package/dist/request-sizing.js +5 -0
- package/dist/request-sizing.js.map +1 -1
- package/dist/resume-guidance.d.ts +102 -0
- package/dist/resume-guidance.d.ts.map +1 -0
- package/dist/resume-guidance.js +182 -0
- package/dist/resume-guidance.js.map +1 -0
- package/dist/route-fallback.d.ts +23 -0
- package/dist/route-fallback.d.ts.map +1 -1
- package/dist/route-fallback.js +44 -0
- package/dist/route-fallback.js.map +1 -1
- package/dist/sign-in-notice.d.ts +137 -0
- package/dist/sign-in-notice.d.ts.map +1 -0
- package/dist/sign-in-notice.js +300 -0
- package/dist/sign-in-notice.js.map +1 -0
- package/dist/subagent-hint.d.ts +31 -0
- package/dist/subagent-hint.d.ts.map +1 -0
- package/dist/subagent-hint.js +47 -0
- package/dist/subagent-hint.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What ccc says about Claude Code's sign-in before Claude Code starts, and the
|
|
3
|
+
* diagnostics that show whether it helped.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code's own answer (claude-auth-status.ts) decides when it is
|
|
6
|
+
* available; otherwise the config-file guess does, as before
|
|
7
|
+
* (claude-plan-warning.ts). Not signed in at all is the case that stalls new
|
|
8
|
+
* users (they open Claude Code, never finish its sign-in and never send a
|
|
9
|
+
* message), so in a terminal that message waits for Enter: Claude Code's
|
|
10
|
+
* screen would cover a printed line within a second. API billing (a Console
|
|
11
|
+
* sign-in or an API key) is said without blocking, again inside Claude Code
|
|
12
|
+
* at its first SessionStart.
|
|
13
|
+
*
|
|
14
|
+
* The sign-in type is kept between launches (SIGN_IN_STATE_FILE, a type name
|
|
15
|
+
* and a time, nothing else) so a later launch can tell that the user signed
|
|
16
|
+
* in after a warning and how long that took.
|
|
17
|
+
*/
|
|
18
|
+
import type { AuthProbe } from "./claude-auth-status.js";
|
|
19
|
+
import type { ApiKeyOverride, ApiKeySource, ClaudeAuthType } from "./claude-auth.js";
|
|
20
|
+
import { type PlanWarningInput } from "./claude-plan-warning.js";
|
|
21
|
+
export declare const PLAN_URL = "https://claude.ai/upgrade";
|
|
22
|
+
export declare const MEMTREE_CREDIT_LINE = "Your MemTree credit covers MemTree, not Claude itself.";
|
|
23
|
+
export declare const NOT_SIGNED_IN_LINES: readonly ["Claude Code isn't signed in to a Claude plan yet. ccc needs Claude Pro or Max.", string, " - Don't have one? Get Pro at https://claude.ai/upgrade, then run /login.", "Your MemTree credit covers MemTree, not Claude itself."];
|
|
24
|
+
export declare const PRESS_ENTER_TEXT = "Press Enter to continue to Claude Code.";
|
|
25
|
+
/** Which message was shown (diagnostics no_plan_warning.kind). */
|
|
26
|
+
export declare const SIGN_IN_WARNING_KINDS: readonly ["not_signed_in", "api_billing", "unknown", "credit_reminder", "key_override"];
|
|
27
|
+
export type SignInWarningKind = (typeof SIGN_IN_WARNING_KINDS)[number];
|
|
28
|
+
/** The file in ccc's config directory holding the last sign-in type Claude Code reported. */
|
|
29
|
+
export declare const SIGN_IN_STATE_FILE = "claude-sign-in-state.json";
|
|
30
|
+
export interface SignInNoticeInput {
|
|
31
|
+
probe: AuthProbe;
|
|
32
|
+
/** The config-file guess and the last sign-in a request showed (claude-plan-warning.ts). */
|
|
33
|
+
fallback: PlanWarningInput;
|
|
34
|
+
/** A credit refusal from an earlier session is on file. */
|
|
35
|
+
creditRefused: boolean;
|
|
36
|
+
override: ApiKeyOverride | undefined;
|
|
37
|
+
color: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface SignInNotice {
|
|
40
|
+
kind: SignInWarningKind;
|
|
41
|
+
lines: string[];
|
|
42
|
+
/** Wait for Enter before Claude Code takes the terminal. */
|
|
43
|
+
pause: boolean;
|
|
44
|
+
/** Repeated inside Claude Code at its first SessionStart. */
|
|
45
|
+
sessionLine?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether the sign-in message applies this launch: not right after ccc installed Claude
|
|
49
|
+
* Code (the installer has just said Claude Code asks to sign in). `locateClaude()` gives
|
|
50
|
+
* null, not undefined, when Claude Code was missing (release 1.0.32 review).
|
|
51
|
+
*/
|
|
52
|
+
export declare function signInNoticeApplies(foundBeforeInstall: object | null | undefined): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The probe as this session will see it. `claude auth status` runs non-interactively,
|
|
55
|
+
* so it counts an ANTHROPIC_API_KEY the user rejected at Claude Code's prompt; the
|
|
56
|
+
* interactive session skips that key (apiKeyOverride gives no ANTHROPIC_API_KEY
|
|
57
|
+
* override), so the probe's "api_key" says nothing about it: treated as unknown and left
|
|
58
|
+
* to the config files (release 1.0.32 review r1).
|
|
59
|
+
*/
|
|
60
|
+
export declare function sessionProbe(probe: AuthProbe, override: ApiKeyOverride | undefined): AuthProbe;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the notice may wait for Enter: a terminal that shows the prompt (stderr), and
|
|
63
|
+
* not CI, where a pseudo-terminal has nobody to press Enter (release 1.0.32 review r1).
|
|
64
|
+
*/
|
|
65
|
+
export declare function mayWaitForEnter(interactive: boolean, stderrIsTty: boolean, env: NodeJS.ProcessEnv): boolean;
|
|
66
|
+
/** The sign-in message before Claude Code starts, or undefined when there is nothing to say. */
|
|
67
|
+
export declare function signInNotice(input: SignInNoticeInput): SignInNotice | undefined;
|
|
68
|
+
/** The lines on stderr (stdout stays Claude Code's in print runs). */
|
|
69
|
+
export declare function printSignInNotice(notice: SignInNotice): void;
|
|
70
|
+
export interface PresentOptions {
|
|
71
|
+
/** A terminal on both ends that Claude Code's TUI will take over, stderr included. */
|
|
72
|
+
interactive: boolean;
|
|
73
|
+
/** The sign-in type for the diagnostics event. */
|
|
74
|
+
auth: ClaudeAuthType;
|
|
75
|
+
record: (name: string, fields: Record<string, unknown>) => void;
|
|
76
|
+
tracker: SignInTracker;
|
|
77
|
+
wait?: () => Promise<{
|
|
78
|
+
ms: number;
|
|
79
|
+
quit: boolean;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Print the notice, wait for Enter when it asks to (interactive only), and
|
|
84
|
+
* record it. Resolves false when the user quit at the prompt (Ctrl+C).
|
|
85
|
+
*/
|
|
86
|
+
export declare function presentSignInNotice(notice: SignInNotice, opts: PresentOptions): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Wait for Enter (or Ctrl+C / end of input) so the message is read before
|
|
89
|
+
* Claude Code covers it. Resolves with how long it waited; never rejects.
|
|
90
|
+
*/
|
|
91
|
+
export declare function waitForEnter(input: NodeJS.ReadableStream, output: NodeJS.WritableStream, now?: () => number): Promise<{
|
|
92
|
+
ms: number;
|
|
93
|
+
quit: boolean;
|
|
94
|
+
}>;
|
|
95
|
+
export interface SignInState {
|
|
96
|
+
auth: ClaudeAuthType;
|
|
97
|
+
/** Epoch ms of the last warning, kept until a Claude plan sign-in is seen. */
|
|
98
|
+
warnedAt?: number;
|
|
99
|
+
}
|
|
100
|
+
export declare function readSignInState(configDir: string): SignInState | undefined;
|
|
101
|
+
/** Never throws: the next launch only loses the between-starts comparison. */
|
|
102
|
+
export declare function writeSignInState(configDir: string, state: SignInState): void;
|
|
103
|
+
export interface SignInEvent {
|
|
104
|
+
from: ClaudeAuthType;
|
|
105
|
+
auth: ClaudeAuthType;
|
|
106
|
+
where: "between_starts" | "mid_session";
|
|
107
|
+
since_warning_ms?: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Follows the sign-in from launch to launch and through the session: a
|
|
111
|
+
* sign-in that turns into a Claude plan after ccc warned (or after "none"),
|
|
112
|
+
* reported once per process through `report`.
|
|
113
|
+
*/
|
|
114
|
+
export declare class SignInTracker {
|
|
115
|
+
private readonly configDir;
|
|
116
|
+
private readonly report;
|
|
117
|
+
private readonly now;
|
|
118
|
+
private state;
|
|
119
|
+
private reported;
|
|
120
|
+
private warnedAt;
|
|
121
|
+
constructor(configDir: string, report: (event: SignInEvent) => void, now?: () => number);
|
|
122
|
+
/** Claude Code's answer at launch (probe ok only): compares with the last launch's. */
|
|
123
|
+
started(auth: ClaudeAuthType): void;
|
|
124
|
+
/** ccc showed a sign-in warning now. */
|
|
125
|
+
warned(): void;
|
|
126
|
+
/** The sign-in a request's auth header showed (subscription or api_key). */
|
|
127
|
+
requestAuth(auth: ClaudeAuthType): void;
|
|
128
|
+
/** Milliseconds since this process's warning, or undefined when none was shown. */
|
|
129
|
+
sinceWarningMs(): number | undefined;
|
|
130
|
+
private emit;
|
|
131
|
+
private save;
|
|
132
|
+
}
|
|
133
|
+
/** The API-billing message, naming the env variable or setting when one is known. */
|
|
134
|
+
export declare function apiBillingText(source: ApiKeySource | undefined, asks: boolean): string;
|
|
135
|
+
/** A claude.ai account on the free plan: Claude Code bills it like an API account. */
|
|
136
|
+
export declare const FREE_PLAN_TEXT: string;
|
|
137
|
+
//# sourceMappingURL=sign-in-notice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-in-notice.d.ts","sourceRoot":"","sources":["../src/sign-in-notice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What ccc says about Claude Code's sign-in before Claude Code starts, and the
|
|
3
|
+
* diagnostics that show whether it helped.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code's own answer (claude-auth-status.ts) decides when it is
|
|
6
|
+
* available; otherwise the config-file guess does, as before
|
|
7
|
+
* (claude-plan-warning.ts). Not signed in at all is the case that stalls new
|
|
8
|
+
* users (they open Claude Code, never finish its sign-in and never send a
|
|
9
|
+
* message), so in a terminal that message waits for Enter: Claude Code's
|
|
10
|
+
* screen would cover a printed line within a second. API billing (a Console
|
|
11
|
+
* sign-in or an API key) is said without blocking, again inside Claude Code
|
|
12
|
+
* at its first SessionStart.
|
|
13
|
+
*
|
|
14
|
+
* The sign-in type is kept between launches (SIGN_IN_STATE_FILE, a type name
|
|
15
|
+
* and a time, nothing else) so a later launch can tell that the user signed
|
|
16
|
+
* in after a warning and how long that took.
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from "node:fs";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
import * as readline from "node:readline";
|
|
21
|
+
import { CLAUDE_AUTH_TYPES } from "./claude-auth.js";
|
|
22
|
+
import { isCi } from "./install-ping.js";
|
|
23
|
+
import { apiKeyOverrideText, creditReminderText, needsCreditReminder, needsPlanWarning, PAID_PLANS, } from "./claude-plan-warning.js";
|
|
24
|
+
export const PLAN_URL = "https://claude.ai/upgrade";
|
|
25
|
+
export const MEMTREE_CREDIT_LINE = "Your MemTree credit covers MemTree, not Claude itself.";
|
|
26
|
+
export const NOT_SIGNED_IN_LINES = [
|
|
27
|
+
"Claude Code isn't signed in to a Claude plan yet. ccc needs Claude Pro or Max.",
|
|
28
|
+
" - Have one? Choose \"Claude account with subscription\" when Claude Code asks, " +
|
|
29
|
+
"or run /login.",
|
|
30
|
+
` - Don't have one? Get Pro at ${PLAN_URL}, then run /login.`,
|
|
31
|
+
MEMTREE_CREDIT_LINE,
|
|
32
|
+
];
|
|
33
|
+
export const PRESS_ENTER_TEXT = "Press Enter to continue to Claude Code.";
|
|
34
|
+
const SWITCH_TO_PLAN = "To use Claude Pro or Max instead, run /login in Claude Code and choose " +
|
|
35
|
+
"\"Claude account with subscription\".";
|
|
36
|
+
/** Which message was shown (diagnostics no_plan_warning.kind). */
|
|
37
|
+
export const SIGN_IN_WARNING_KINDS = [
|
|
38
|
+
"not_signed_in", "api_billing", "unknown", "credit_reminder", "key_override",
|
|
39
|
+
];
|
|
40
|
+
/** The file in ccc's config directory holding the last sign-in type Claude Code reported. */
|
|
41
|
+
export const SIGN_IN_STATE_FILE = "claude-sign-in-state.json";
|
|
42
|
+
const CLOUD_AUTH = ["bedrock", "vertex", "foundry"];
|
|
43
|
+
/**
|
|
44
|
+
* Whether the sign-in message applies this launch: not right after ccc installed Claude
|
|
45
|
+
* Code (the installer has just said Claude Code asks to sign in). `locateClaude()` gives
|
|
46
|
+
* null, not undefined, when Claude Code was missing (release 1.0.32 review).
|
|
47
|
+
*/
|
|
48
|
+
export function signInNoticeApplies(foundBeforeInstall) {
|
|
49
|
+
return foundBeforeInstall !== null && foundBeforeInstall !== undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The probe as this session will see it. `claude auth status` runs non-interactively,
|
|
53
|
+
* so it counts an ANTHROPIC_API_KEY the user rejected at Claude Code's prompt; the
|
|
54
|
+
* interactive session skips that key (apiKeyOverride gives no ANTHROPIC_API_KEY
|
|
55
|
+
* override), so the probe's "api_key" says nothing about it: treated as unknown and left
|
|
56
|
+
* to the config files (release 1.0.32 review r1).
|
|
57
|
+
*/
|
|
58
|
+
export function sessionProbe(probe, override) {
|
|
59
|
+
const status = probe.status;
|
|
60
|
+
if (status?.auth !== "api_key" || status.keySource !== "ANTHROPIC_API_KEY")
|
|
61
|
+
return probe;
|
|
62
|
+
if (override?.source === "ANTHROPIC_API_KEY")
|
|
63
|
+
return probe;
|
|
64
|
+
return { result: probe.result, ms: probe.ms };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether the notice may wait for Enter: a terminal that shows the prompt (stderr), and
|
|
68
|
+
* not CI, where a pseudo-terminal has nobody to press Enter (release 1.0.32 review r1).
|
|
69
|
+
*/
|
|
70
|
+
export function mayWaitForEnter(interactive, stderrIsTty, env) {
|
|
71
|
+
return interactive && stderrIsTty && !isCi(env);
|
|
72
|
+
}
|
|
73
|
+
/** The sign-in message before Claude Code starts, or undefined when there is nothing to say. */
|
|
74
|
+
export function signInNotice(input) {
|
|
75
|
+
const status = input.probe.status;
|
|
76
|
+
const auth = status?.auth ?? input.fallback.auth;
|
|
77
|
+
if (CLOUD_AUTH.includes(auth))
|
|
78
|
+
return undefined;
|
|
79
|
+
const plan = PAID_PLANS.includes(status?.plan ?? "unknown") ? status.plan : input.fallback.plan;
|
|
80
|
+
if (needsCreditReminder({ refused: input.creditRefused, plan }) && auth !== "none") {
|
|
81
|
+
// A skipped probe (--settings, --setting-sources, --bare): the key's source as read
|
|
82
|
+
// from the config files may not be this session's, so it isn't named.
|
|
83
|
+
const skipped = input.probe.result === "skipped";
|
|
84
|
+
const source = input.override?.asks || skipped ? undefined : input.override?.source;
|
|
85
|
+
return notice("credit_reminder", [yellow(creditReminderText(source), input.color)]);
|
|
86
|
+
}
|
|
87
|
+
if (status && status.auth !== "unknown") {
|
|
88
|
+
return noticeFromStatus(status.auth, status.plan, status.keySource, input);
|
|
89
|
+
}
|
|
90
|
+
// --settings, --setting-sources or --bare: the session doesn't read the config files
|
|
91
|
+
// the way the fallback does, so it has nothing reliable to say.
|
|
92
|
+
if (input.probe.result === "skipped")
|
|
93
|
+
return undefined;
|
|
94
|
+
return noticeFromConfig(input);
|
|
95
|
+
}
|
|
96
|
+
/** The lines on stderr (stdout stays Claude Code's in print runs). */
|
|
97
|
+
export function printSignInNotice(notice) {
|
|
98
|
+
for (const line of notice.lines)
|
|
99
|
+
process.stderr.write(`${line}\n`);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Print the notice, wait for Enter when it asks to (interactive only), and
|
|
103
|
+
* record it. Resolves false when the user quit at the prompt (Ctrl+C).
|
|
104
|
+
*/
|
|
105
|
+
export async function presentSignInNotice(notice, opts) {
|
|
106
|
+
printSignInNotice(notice);
|
|
107
|
+
// A subscriber whose key beats their login has a plan: not a sign-in warning (as before).
|
|
108
|
+
if (notice.kind === "key_override")
|
|
109
|
+
return true;
|
|
110
|
+
opts.tracker.warned();
|
|
111
|
+
const waited = notice.pause && opts.interactive
|
|
112
|
+
? await (opts.wait ?? (() => waitForEnter(process.stdin, process.stderr)))()
|
|
113
|
+
: undefined;
|
|
114
|
+
opts.record("no_plan_warning", {
|
|
115
|
+
auth: opts.auth, kind: notice.kind, ...(waited ? { waited_ms: waited.ms } : {}),
|
|
116
|
+
});
|
|
117
|
+
return waited?.quit !== true;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Wait for Enter (or Ctrl+C / end of input) so the message is read before
|
|
121
|
+
* Claude Code covers it. Resolves with how long it waited; never rejects.
|
|
122
|
+
*/
|
|
123
|
+
export function waitForEnter(input, output, now = Date.now) {
|
|
124
|
+
const started = now();
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
const rl = readline.createInterface({ input, output });
|
|
127
|
+
let answered = false;
|
|
128
|
+
rl.on("close", () => {
|
|
129
|
+
if (!answered)
|
|
130
|
+
resolve({ ms: now() - started, quit: true });
|
|
131
|
+
});
|
|
132
|
+
rl.on("SIGINT", () => rl.close());
|
|
133
|
+
rl.question(`${PRESS_ENTER_TEXT} `, () => {
|
|
134
|
+
answered = true;
|
|
135
|
+
rl.close();
|
|
136
|
+
resolve({ ms: now() - started, quit: false });
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export function readSignInState(configDir) {
|
|
141
|
+
try {
|
|
142
|
+
const raw = JSON.parse(fs.readFileSync(path.join(configDir, SIGN_IN_STATE_FILE), "utf8"));
|
|
143
|
+
if (typeof raw?.auth !== "string")
|
|
144
|
+
return undefined;
|
|
145
|
+
const warnedAt = Number.isFinite(raw.warnedAt) ? { warnedAt: raw.warnedAt } : {};
|
|
146
|
+
if (!CLAUDE_AUTH_TYPES.includes(raw.auth))
|
|
147
|
+
return undefined;
|
|
148
|
+
return { auth: raw.auth, ...warnedAt };
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Never throws: the next launch only loses the between-starts comparison. */
|
|
155
|
+
export function writeSignInState(configDir, state) {
|
|
156
|
+
try {
|
|
157
|
+
fs.writeFileSync(path.join(configDir, SIGN_IN_STATE_FILE), `${JSON.stringify(state)}\n`, { mode: 0o600 });
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Best effort.
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Follows the sign-in from launch to launch and through the session: a
|
|
165
|
+
* sign-in that turns into a Claude plan after ccc warned (or after "none"),
|
|
166
|
+
* reported once per process through `report`.
|
|
167
|
+
*/
|
|
168
|
+
export class SignInTracker {
|
|
169
|
+
configDir;
|
|
170
|
+
report;
|
|
171
|
+
now;
|
|
172
|
+
state;
|
|
173
|
+
reported = false;
|
|
174
|
+
warnedAt;
|
|
175
|
+
constructor(configDir, report, now = Date.now) {
|
|
176
|
+
this.configDir = configDir;
|
|
177
|
+
this.report = report;
|
|
178
|
+
this.now = now;
|
|
179
|
+
this.state = readSignInState(configDir);
|
|
180
|
+
}
|
|
181
|
+
/** Claude Code's answer at launch (probe ok only): compares with the last launch's. */
|
|
182
|
+
started(auth) {
|
|
183
|
+
const before = this.state;
|
|
184
|
+
// From "unknown" (Claude Code couldn't be asked) is no evidence of a new sign-in.
|
|
185
|
+
if (before && before.auth !== "unknown" && signedInToPlan(before.auth, auth)) {
|
|
186
|
+
this.emit(before.auth, auth, "between_starts", before.warnedAt);
|
|
187
|
+
}
|
|
188
|
+
this.save({ auth, ...(auth !== "subscription" && before?.warnedAt
|
|
189
|
+
? { warnedAt: before.warnedAt } : {}) });
|
|
190
|
+
}
|
|
191
|
+
/** ccc showed a sign-in warning now. */
|
|
192
|
+
warned() {
|
|
193
|
+
this.warnedAt = this.now();
|
|
194
|
+
this.save({ auth: this.state?.auth ?? "unknown", warnedAt: this.warnedAt });
|
|
195
|
+
}
|
|
196
|
+
/** The sign-in a request's auth header showed (subscription or api_key). */
|
|
197
|
+
requestAuth(auth) {
|
|
198
|
+
const before = this.state?.auth;
|
|
199
|
+
if (before === undefined || before === auth)
|
|
200
|
+
return;
|
|
201
|
+
if (before !== "unknown" && (signedInToPlan(before, auth) || before === "none")) {
|
|
202
|
+
this.emit(before, auth, "mid_session", this.warnedAt ?? this.state?.warnedAt);
|
|
203
|
+
}
|
|
204
|
+
const keep = auth !== "subscription" && this.state?.warnedAt !== undefined
|
|
205
|
+
? { warnedAt: this.state.warnedAt } : {};
|
|
206
|
+
this.save({ auth, ...keep });
|
|
207
|
+
}
|
|
208
|
+
/** Milliseconds since this process's warning, or undefined when none was shown. */
|
|
209
|
+
sinceWarningMs() {
|
|
210
|
+
return this.warnedAt === undefined ? undefined : Math.max(0, this.now() - this.warnedAt);
|
|
211
|
+
}
|
|
212
|
+
emit(from, auth, where, warnedAt) {
|
|
213
|
+
if (this.reported)
|
|
214
|
+
return;
|
|
215
|
+
this.reported = true;
|
|
216
|
+
const since = warnedAt === undefined
|
|
217
|
+
? {} : { since_warning_ms: Math.max(0, this.now() - warnedAt) };
|
|
218
|
+
this.report({ from, auth, where, ...since });
|
|
219
|
+
}
|
|
220
|
+
save(state) {
|
|
221
|
+
this.state = state;
|
|
222
|
+
writeSignInState(this.configDir, state);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
// Helpers
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
function noticeFromStatus(auth, plan, source, input) {
|
|
229
|
+
if (auth === "none")
|
|
230
|
+
return notSignedIn(input.color, true);
|
|
231
|
+
if (auth === "api_key") {
|
|
232
|
+
// A Claude plan on file that a key beats: the key's own line says how to drop it.
|
|
233
|
+
if (input.override && input.fallback.subscriptionLogin === true) {
|
|
234
|
+
return notice("key_override", [apiKeyOverrideText(input.override, input.color)]);
|
|
235
|
+
}
|
|
236
|
+
const asks = input.override?.source === source && input.override?.asks === true;
|
|
237
|
+
return apiBilling(source ?? input.override?.source, asks, input.color);
|
|
238
|
+
}
|
|
239
|
+
if (auth === "subscription" && plan === "free")
|
|
240
|
+
return freePlan(input.color);
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
/** Claude Code could not be asked: the config files' guess, without blocking. */
|
|
244
|
+
function noticeFromConfig(input) {
|
|
245
|
+
const { fallback, override, color } = input;
|
|
246
|
+
if (needsPlanWarning(fallback)) {
|
|
247
|
+
if (fallback.auth === "api_key" || fallback.seen === "api_key") {
|
|
248
|
+
return apiBilling(override?.source, override?.asks, color);
|
|
249
|
+
}
|
|
250
|
+
const shown = notSignedIn(color, false);
|
|
251
|
+
return { ...shown, kind: "unknown" };
|
|
252
|
+
}
|
|
253
|
+
if (override && fallback.subscriptionLogin === true) {
|
|
254
|
+
return notice("key_override", [apiKeyOverrideText(override, color)]);
|
|
255
|
+
}
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
function notSignedIn(color, pause) {
|
|
259
|
+
return { kind: "not_signed_in", lines: NOT_SIGNED_IN_LINES.map((l) => yellow(l, color)), pause };
|
|
260
|
+
}
|
|
261
|
+
function apiBilling(source, asks, color) {
|
|
262
|
+
const text = apiBillingText(source, asks === true);
|
|
263
|
+
return { ...notice("api_billing", [yellow(text, color)]), sessionLine: text };
|
|
264
|
+
}
|
|
265
|
+
/** The API-billing message, naming the env variable or setting when one is known. */
|
|
266
|
+
export function apiBillingText(source, asks) {
|
|
267
|
+
if (source === "apiKeyHelper") {
|
|
268
|
+
return "Claude Code's settings set an apiKeyHelper, so Claude bills that API key per " +
|
|
269
|
+
`token, not a Claude plan. ${MEMTREE_CREDIT_LINE} To use Claude Pro or Max instead, ` +
|
|
270
|
+
"remove apiKeyHelper from settings.json, then run /login.";
|
|
271
|
+
}
|
|
272
|
+
if (source && asks) {
|
|
273
|
+
return `${source} is set: if Claude Code asks whether to use it, Yes bills that API key ` +
|
|
274
|
+
`per token. ${MEMTREE_CREDIT_LINE} To use Claude Pro or Max, answer No and sign in ` +
|
|
275
|
+
"with \"Claude account with subscription\".";
|
|
276
|
+
}
|
|
277
|
+
if (source) {
|
|
278
|
+
return `${source} is set, so Claude bills that API key per token, not a Claude plan. ` +
|
|
279
|
+
`${MEMTREE_CREDIT_LINE} To use Claude Pro or Max instead, unset it, then run /login.`;
|
|
280
|
+
}
|
|
281
|
+
return "Claude Code is signed in for API billing (an Anthropic Console account), so Claude " +
|
|
282
|
+
`bills that account per token, not a Claude plan. ${MEMTREE_CREDIT_LINE} ${SWITCH_TO_PLAN}`;
|
|
283
|
+
}
|
|
284
|
+
/** A claude.ai account on the free plan: Claude Code bills it like an API account. */
|
|
285
|
+
export const FREE_PLAN_TEXT = "Claude Code is signed in to a Claude account without Pro or Max, so Claude bills its " +
|
|
286
|
+
`usage separately, not a plan. ${MEMTREE_CREDIT_LINE} Get Pro at ${PLAN_URL}, then run /login.`;
|
|
287
|
+
function freePlan(color) {
|
|
288
|
+
return { ...notice("api_billing", [yellow(FREE_PLAN_TEXT, color)]), sessionLine: FREE_PLAN_TEXT };
|
|
289
|
+
}
|
|
290
|
+
function notice(kind, lines) {
|
|
291
|
+
return { kind, lines, pause: false };
|
|
292
|
+
}
|
|
293
|
+
function yellow(text, color) {
|
|
294
|
+
return color ? `\x1b[33m${text}\x1b[39m` : text;
|
|
295
|
+
}
|
|
296
|
+
/** From not signed in, unknown or API billing to a Claude login. */
|
|
297
|
+
function signedInToPlan(before, after) {
|
|
298
|
+
return after === "subscription" && before !== "subscription";
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=sign-in-notice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-in-notice.js","sourceRoot":"","sources":["../src/sign-in-notice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a subagent is told about its parent's memory.
|
|
3
|
+
*
|
|
4
|
+
* A subagent (Claude Code's Agent/Task tool, foreground or background) starts
|
|
5
|
+
* with only its prompt: the parent's earlier decisions, findings and commands
|
|
6
|
+
* are in the parent's MemTree, which it can search with the memtree tools
|
|
7
|
+
* (loaded up front there too: the server's `alwaysLoad`). So the proxy answers
|
|
8
|
+
* Claude Code's SubagentStart hook with one short `additionalContext` naming
|
|
9
|
+
* the parent session and its newest tree. Claude Code adds it once, to the
|
|
10
|
+
* start of the subagent's own conversation, so it is cached with that prefix
|
|
11
|
+
* and never changes for the subagent's later turns.
|
|
12
|
+
*
|
|
13
|
+
* Said only while MemTree works (not paused, not off, not before it first
|
|
14
|
+
* answered), only when the session has the `search` tool it names, and only
|
|
15
|
+
* when the server named the parent's newest tree: a parent without one has
|
|
16
|
+
* little to re-derive.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Whether subagents get the hint: on while the session has the memtree
|
|
20
|
+
* `search` tool, off once ccc could not register the server after all.
|
|
21
|
+
*/
|
|
22
|
+
export declare class SubagentMemoryHint {
|
|
23
|
+
private disabled;
|
|
24
|
+
disable(): void;
|
|
25
|
+
get enabled(): boolean;
|
|
26
|
+
}
|
|
27
|
+
/** The hint for a subagent of `sessionId`, or undefined when either id looks wrong. */
|
|
28
|
+
export declare function subagentMemoryHintText(sessionId: string, treeRef: string): string | undefined;
|
|
29
|
+
/** The SubagentStart hook's answer carrying `context` to the subagent. */
|
|
30
|
+
export declare function subagentStartOutput(context: string): Record<string, unknown>;
|
|
31
|
+
//# sourceMappingURL=subagent-hint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-hint.d.ts","sourceRoot":"","sources":["../src/subagent-hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,IAAI,IAAI;IAIf,IAAI,OAAO,IAAI,OAAO,CAErB;CACF;AAED,uFAAuF;AACvF,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAQpB;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE5E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a subagent is told about its parent's memory.
|
|
3
|
+
*
|
|
4
|
+
* A subagent (Claude Code's Agent/Task tool, foreground or background) starts
|
|
5
|
+
* with only its prompt: the parent's earlier decisions, findings and commands
|
|
6
|
+
* are in the parent's MemTree, which it can search with the memtree tools
|
|
7
|
+
* (loaded up front there too: the server's `alwaysLoad`). So the proxy answers
|
|
8
|
+
* Claude Code's SubagentStart hook with one short `additionalContext` naming
|
|
9
|
+
* the parent session and its newest tree. Claude Code adds it once, to the
|
|
10
|
+
* start of the subagent's own conversation, so it is cached with that prefix
|
|
11
|
+
* and never changes for the subagent's later turns.
|
|
12
|
+
*
|
|
13
|
+
* Said only while MemTree works (not paused, not off, not before it first
|
|
14
|
+
* answered), only when the session has the `search` tool it names, and only
|
|
15
|
+
* when the server named the parent's newest tree: a parent without one has
|
|
16
|
+
* little to re-derive.
|
|
17
|
+
*/
|
|
18
|
+
import { SESSION_ID } from "./memtree-newest.js";
|
|
19
|
+
/** The server's tree refs (`<uuid>-v1-own`). */
|
|
20
|
+
const TREE_REF = /^[A-Za-z0-9][A-Za-z0-9-]{0,99}$/;
|
|
21
|
+
/**
|
|
22
|
+
* Whether subagents get the hint: on while the session has the memtree
|
|
23
|
+
* `search` tool, off once ccc could not register the server after all.
|
|
24
|
+
*/
|
|
25
|
+
export class SubagentMemoryHint {
|
|
26
|
+
disabled = false;
|
|
27
|
+
disable() {
|
|
28
|
+
this.disabled = true;
|
|
29
|
+
}
|
|
30
|
+
get enabled() {
|
|
31
|
+
return !this.disabled;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** The hint for a subagent of `sessionId`, or undefined when either id looks wrong. */
|
|
35
|
+
export function subagentMemoryHintText(sessionId, treeRef) {
|
|
36
|
+
if (!SESSION_ID.test(sessionId) || !TREE_REF.test(treeRef))
|
|
37
|
+
return undefined;
|
|
38
|
+
return (`ccc: You are a subagent of session ${sessionId}, whose memory is MemTree tree ` +
|
|
39
|
+
`${treeRef}; your own work is indexed too. Before re-deriving earlier decisions, ` +
|
|
40
|
+
"findings or commands from the parent's work, search its memory: mcp__memtree__search " +
|
|
41
|
+
`with tree ${treeRef} (or without tree to search all sessions).`);
|
|
42
|
+
}
|
|
43
|
+
/** The SubagentStart hook's answer carrying `context` to the subagent. */
|
|
44
|
+
export function subagentStartOutput(context) {
|
|
45
|
+
return { hookSpecificOutput: { hookEventName: "SubagentStart", additionalContext: context } };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=subagent-hint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-hint.js","sourceRoot":"","sources":["../src/subagent-hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,gDAAgD;AAChD,MAAM,QAAQ,GAAG,iCAAiC,CAAC;AAEnD;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACrB,QAAQ,GAAG,KAAK,CAAC;IAEzB,OAAO;QACL,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;IACxB,CAAC;CACF;AAED,uFAAuF;AACvF,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,OAAe;IAEf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7E,OAAO,CACL,sCAAsC,SAAS,iCAAiC;QAChF,GAAG,OAAO,wEAAwE;QAClF,uFAAuF;QACvF,aAAa,OAAO,4CAA4C,CACjE,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,EAAE,kBAAkB,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,CAAC;AAChG,CAAC"}
|