@tokenfactory/acc-runner 0.40.9 → 0.40.10
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/dist/companion-identity.d.ts +144 -0
- package/dist/companion-identity.d.ts.map +1 -0
- package/dist/companion-identity.js +189 -0
- package/dist/companion-identity.js.map +1 -0
- package/dist/companion-run.d.ts +6 -1
- package/dist/companion-run.d.ts.map +1 -1
- package/dist/companion-run.js +41 -26
- package/dist/companion-run.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COMPANION-IDENTITY-DISCOVERY: self-discovery + honest binding of the
|
|
3
|
+
* companion's enrollment identity.
|
|
4
|
+
*
|
|
5
|
+
* The bug this fixes: plain `acc-runner companion` (what the post-ENROLL-FIX
|
|
6
|
+
* enrollment guidance tells the operator to run) only ever bound an identity —
|
|
7
|
+
* and therefore only ever wrote `runner_ids` / `probe_tier` — when the operator
|
|
8
|
+
* had hand-set `ACC_RUNNER_COMPANION_IDENTITY`. Nothing anywhere mentioned that
|
|
9
|
+
* env var, so the flagless command came online GREEN-AND-SILENT while never
|
|
10
|
+
* serving provider status. Third seam defect in this flow.
|
|
11
|
+
*
|
|
12
|
+
* The fix has three pure pieces, all here so they are exercised without a
|
|
13
|
+
* network, a `claude` binary, or the live-wiring in companion-run.ts:
|
|
14
|
+
*
|
|
15
|
+
* 1. `discoverCompanionIdentities` — the authenticated GET /api/identities/
|
|
16
|
+
* discover call. It is ALSO the pre-online SESSION PING: a dead/expired
|
|
17
|
+
* session yields 401/403 and `sessionOk:false`, which is what lets the CLI
|
|
18
|
+
* refuse to print "online" on a zombie session.
|
|
19
|
+
* 2. `resolveBinding` — turn the discovery outcome (+ optional env override)
|
|
20
|
+
* into a binding decision: exactly one match ⇒ bound; multiple ⇒ unbound +
|
|
21
|
+
* list; zero ⇒ unbound + "no enrollment"; unreachable ⇒ unbound + degraded.
|
|
22
|
+
* 3. `companionBanner` — the HONESTY invariant: a bound companion gets a green
|
|
23
|
+
* headline naming the bound identity; anything else gets a yellow headline
|
|
24
|
+
* that literally contains "UNBOUND". `tone === "ok"` iff `binding.kind ===
|
|
25
|
+
* "bound"`, so green-and-silent-while-unbound is structurally impossible.
|
|
26
|
+
*
|
|
27
|
+
* The env var stays as a documented override (a machine with more than one
|
|
28
|
+
* enrolled subscription of the same engine picks one explicitly).
|
|
29
|
+
*/
|
|
30
|
+
/** One owner-bound companion identity the runner may serve. */
|
|
31
|
+
export interface DiscoveredIdentity {
|
|
32
|
+
id: string;
|
|
33
|
+
provider: string;
|
|
34
|
+
engine: string;
|
|
35
|
+
status: string;
|
|
36
|
+
/** null ⇒ pending (never probed); set ⇒ already adopted/probed. */
|
|
37
|
+
lastProbeAt: string | null;
|
|
38
|
+
}
|
|
39
|
+
/** The outcome of the discovery call — matches plus session/reachability facts. */
|
|
40
|
+
export interface DiscoveryOutcome {
|
|
41
|
+
/** False ONLY when the registry rejected the token (401/403). Refuse to come online. */
|
|
42
|
+
sessionOk: boolean;
|
|
43
|
+
/** False when the registry could not be reached / returned a non-auth error. */
|
|
44
|
+
reachable: boolean;
|
|
45
|
+
/** Owner-bound companion identities matching (owner, provider?, engine?). */
|
|
46
|
+
matches: DiscoveredIdentity[];
|
|
47
|
+
/** Best-effort human note (never key material). */
|
|
48
|
+
detail?: string;
|
|
49
|
+
}
|
|
50
|
+
/** The runner's binding decision. */
|
|
51
|
+
export type IdentityBinding = {
|
|
52
|
+
kind: "bound";
|
|
53
|
+
identityId: string;
|
|
54
|
+
/** The discovered row when known (null for a blind env override). */
|
|
55
|
+
identity: DiscoveredIdentity | null;
|
|
56
|
+
source: "discovery" | "override";
|
|
57
|
+
} | {
|
|
58
|
+
kind: "unbound";
|
|
59
|
+
reason: "no_enrollment" | "multiple" | "unreachable";
|
|
60
|
+
/** Candidate rows to show the operator (populated for `multiple`). */
|
|
61
|
+
matches: DiscoveredIdentity[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Best-effort engine → LLM provider map, used only to NARROW discovery to the
|
|
65
|
+
* caller's rows for that provider. Unknown engines omit the provider filter (the
|
|
66
|
+
* server then matches on owner + engine alone), so this is advisory, never a gate.
|
|
67
|
+
*/
|
|
68
|
+
export declare function providerForEngine(engineId: string): string | undefined;
|
|
69
|
+
/** Injected deps for the discovery call (fetch is a seam for tests). */
|
|
70
|
+
export interface DiscoverDeps {
|
|
71
|
+
publicUrl: string;
|
|
72
|
+
accessToken: string;
|
|
73
|
+
engineId: string;
|
|
74
|
+
provider?: string;
|
|
75
|
+
fetchImpl?: typeof fetch;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Call GET /api/identities/discover under the runner's session. This doubles as
|
|
79
|
+
* the pre-online session ping: a 401/403 is a dead session (`sessionOk:false`),
|
|
80
|
+
* a network error or non-auth HTTP error is "unreachable" (`reachable:false`,
|
|
81
|
+
* but `sessionOk:true` — we cannot disprove the session), and a 200 returns the
|
|
82
|
+
* matching owner-bound companion identities.
|
|
83
|
+
*/
|
|
84
|
+
export declare function discoverCompanionIdentities(deps: DiscoverDeps): Promise<DiscoveryOutcome>;
|
|
85
|
+
/**
|
|
86
|
+
* Decide the binding from the discovery outcome and the optional env override.
|
|
87
|
+
* The override ALWAYS wins (escape hatch) once the session is known-good; it
|
|
88
|
+
* binds even to an id not in `matches` (a blind bind), because an operator who
|
|
89
|
+
* hand-sets the id has authoritatively chosen it. Callers must first check
|
|
90
|
+
* `outcome.sessionOk` — this function assumes the session ping already passed.
|
|
91
|
+
*/
|
|
92
|
+
export declare function resolveBinding(outcome: DiscoveryOutcome, override: string | undefined | null): IdentityBinding;
|
|
93
|
+
/**
|
|
94
|
+
* The registration payload the companion reports once bound: which runner is
|
|
95
|
+
* serving which identity, at what probed tier + capacity. `tier`/`capacity` are
|
|
96
|
+
* kept as plain strings so this module stays free of the engine capability
|
|
97
|
+
* enums (companion-run.ts passes the narrower union values through).
|
|
98
|
+
*/
|
|
99
|
+
export interface ProbeReportPayload {
|
|
100
|
+
identityId: string;
|
|
101
|
+
runnerId: string;
|
|
102
|
+
tier: string | null;
|
|
103
|
+
capacity: string;
|
|
104
|
+
}
|
|
105
|
+
/** Injected deps for the probe POST (fetch is a transport seam only). */
|
|
106
|
+
export interface ReportProbeDeps {
|
|
107
|
+
publicUrl: string;
|
|
108
|
+
accessToken: string;
|
|
109
|
+
fetchImpl?: typeof fetch;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* POST the companion registration to /api/identities/probe. This is the WRITE
|
|
113
|
+
* side of the bind: the server folds `tier` into `probe_tier`/`last_probe_at`
|
|
114
|
+
* (via acc.set_ai_identity_probe) and unions `runnerId` into the identity's
|
|
115
|
+
* `runner_ids` roster — the two columns that, left NULL/empty, made the flagless
|
|
116
|
+
* companion come online green-and-silent while provider-status could never
|
|
117
|
+
* confirm it. Shared by companion-run.ts (production) and the write-path test so
|
|
118
|
+
* the exact same request is exercised in both. Throws on a non-2xx response so
|
|
119
|
+
* CompanionRunner's registration-persist catch can log it (best-effort).
|
|
120
|
+
*/
|
|
121
|
+
export declare function reportIdentityProbe(deps: ReportProbeDeps, payload: ProbeReportPayload): Promise<void>;
|
|
122
|
+
/** The env var whose presence overrides self-discovery with an explicit id. */
|
|
123
|
+
export declare const COMPANION_IDENTITY_OVERRIDE_HINT = "ACC_RUNNER_COMPANION_IDENTITY";
|
|
124
|
+
export type BannerTone = "ok" | "warn";
|
|
125
|
+
/** A rendered (but colour-free) startup banner — the caller applies chalk. */
|
|
126
|
+
export interface CompanionBanner {
|
|
127
|
+
tone: BannerTone;
|
|
128
|
+
/** The single headline line. `tone==="ok"` iff the companion is bound. */
|
|
129
|
+
headline: string;
|
|
130
|
+
/** Follow-up guidance lines (empty for a clean bound start). */
|
|
131
|
+
lines: string[];
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Build the startup banner. HONESTY invariant (asserted by the tests):
|
|
135
|
+
* - a BOUND companion → tone "ok", headline names the bound identity id;
|
|
136
|
+
* - ANY unbound state → tone "warn", headline CONTAINS "UNBOUND" and the
|
|
137
|
+
* words "not serving provider status".
|
|
138
|
+
* There is no path to a green headline that does not name a bound identity, so a
|
|
139
|
+
* green-and-silent-while-unbound banner cannot be produced.
|
|
140
|
+
*/
|
|
141
|
+
export declare function companionBanner(binding: IdentityBinding, ctx: {
|
|
142
|
+
email: string;
|
|
143
|
+
}): CompanionBanner;
|
|
144
|
+
//# sourceMappingURL=companion-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-identity.d.ts","sourceRoot":"","sources":["../src/companion-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;IACnB,gFAAgF;IAChF,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GACvB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC;CAClC,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,eAAe,GAAG,UAAU,GAAG,aAAa,CAAC;IACrD,sEAAsE;IACtE,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B,CAAC;AAEN;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWtE;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAUD;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyC/F;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAClC,eAAe,CAiBjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,+EAA+E;AAC/E,eAAO,MAAM,gCAAgC,kCAAkC,CAAC;AAEhF,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvC,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAQD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACrB,eAAe,CAqCjB"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COMPANION-IDENTITY-DISCOVERY: self-discovery + honest binding of the
|
|
3
|
+
* companion's enrollment identity.
|
|
4
|
+
*
|
|
5
|
+
* The bug this fixes: plain `acc-runner companion` (what the post-ENROLL-FIX
|
|
6
|
+
* enrollment guidance tells the operator to run) only ever bound an identity —
|
|
7
|
+
* and therefore only ever wrote `runner_ids` / `probe_tier` — when the operator
|
|
8
|
+
* had hand-set `ACC_RUNNER_COMPANION_IDENTITY`. Nothing anywhere mentioned that
|
|
9
|
+
* env var, so the flagless command came online GREEN-AND-SILENT while never
|
|
10
|
+
* serving provider status. Third seam defect in this flow.
|
|
11
|
+
*
|
|
12
|
+
* The fix has three pure pieces, all here so they are exercised without a
|
|
13
|
+
* network, a `claude` binary, or the live-wiring in companion-run.ts:
|
|
14
|
+
*
|
|
15
|
+
* 1. `discoverCompanionIdentities` — the authenticated GET /api/identities/
|
|
16
|
+
* discover call. It is ALSO the pre-online SESSION PING: a dead/expired
|
|
17
|
+
* session yields 401/403 and `sessionOk:false`, which is what lets the CLI
|
|
18
|
+
* refuse to print "online" on a zombie session.
|
|
19
|
+
* 2. `resolveBinding` — turn the discovery outcome (+ optional env override)
|
|
20
|
+
* into a binding decision: exactly one match ⇒ bound; multiple ⇒ unbound +
|
|
21
|
+
* list; zero ⇒ unbound + "no enrollment"; unreachable ⇒ unbound + degraded.
|
|
22
|
+
* 3. `companionBanner` — the HONESTY invariant: a bound companion gets a green
|
|
23
|
+
* headline naming the bound identity; anything else gets a yellow headline
|
|
24
|
+
* that literally contains "UNBOUND". `tone === "ok"` iff `binding.kind ===
|
|
25
|
+
* "bound"`, so green-and-silent-while-unbound is structurally impossible.
|
|
26
|
+
*
|
|
27
|
+
* The env var stays as a documented override (a machine with more than one
|
|
28
|
+
* enrolled subscription of the same engine picks one explicitly).
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Best-effort engine → LLM provider map, used only to NARROW discovery to the
|
|
32
|
+
* caller's rows for that provider. Unknown engines omit the provider filter (the
|
|
33
|
+
* server then matches on owner + engine alone), so this is advisory, never a gate.
|
|
34
|
+
*/
|
|
35
|
+
export function providerForEngine(engineId) {
|
|
36
|
+
switch ((engineId ?? "").trim()) {
|
|
37
|
+
case "claude-code":
|
|
38
|
+
return "anthropic";
|
|
39
|
+
case "codex":
|
|
40
|
+
return "openai";
|
|
41
|
+
case "gemini":
|
|
42
|
+
return "google";
|
|
43
|
+
default:
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Call GET /api/identities/discover under the runner's session. This doubles as
|
|
49
|
+
* the pre-online session ping: a 401/403 is a dead session (`sessionOk:false`),
|
|
50
|
+
* a network error or non-auth HTTP error is "unreachable" (`reachable:false`,
|
|
51
|
+
* but `sessionOk:true` — we cannot disprove the session), and a 200 returns the
|
|
52
|
+
* matching owner-bound companion identities.
|
|
53
|
+
*/
|
|
54
|
+
export async function discoverCompanionIdentities(deps) {
|
|
55
|
+
const base = (deps.publicUrl ?? "").replace(/\/+$/, "");
|
|
56
|
+
const params = new URLSearchParams();
|
|
57
|
+
if (deps.engineId)
|
|
58
|
+
params.set("engine", deps.engineId);
|
|
59
|
+
if (deps.provider)
|
|
60
|
+
params.set("provider", deps.provider);
|
|
61
|
+
const url = `${base}/api/identities/discover${params.toString() ? `?${params.toString()}` : ""}`;
|
|
62
|
+
const f = deps.fetchImpl ?? fetch;
|
|
63
|
+
let res;
|
|
64
|
+
try {
|
|
65
|
+
res = await f(url, { headers: { Authorization: `Bearer ${deps.accessToken}` } });
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
return { sessionOk: true, reachable: false, matches: [], detail: err.message };
|
|
69
|
+
}
|
|
70
|
+
if (res.status === 401 || res.status === 403) {
|
|
71
|
+
return { sessionOk: false, reachable: true, matches: [], detail: `discover HTTP ${res.status}` };
|
|
72
|
+
}
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
return { sessionOk: true, reachable: false, matches: [], detail: `discover HTTP ${res.status}` };
|
|
75
|
+
}
|
|
76
|
+
const json = (await res.json().catch(() => null));
|
|
77
|
+
if (!json || json.ok !== true || !Array.isArray(json.matches)) {
|
|
78
|
+
return { sessionOk: true, reachable: false, matches: [], detail: "malformed discover response" };
|
|
79
|
+
}
|
|
80
|
+
const matches = json.matches
|
|
81
|
+
.filter((m) => !!m && typeof m === "object")
|
|
82
|
+
.map((m) => ({
|
|
83
|
+
id: String(m.id ?? ""),
|
|
84
|
+
provider: String(m.provider ?? ""),
|
|
85
|
+
engine: String(m.engine ?? ""),
|
|
86
|
+
status: String(m.status ?? ""),
|
|
87
|
+
lastProbeAt: typeof m.last_probe_at === "string" ? m.last_probe_at : null,
|
|
88
|
+
}))
|
|
89
|
+
.filter((m) => m.id);
|
|
90
|
+
return { sessionOk: true, reachable: true, matches };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Decide the binding from the discovery outcome and the optional env override.
|
|
94
|
+
* The override ALWAYS wins (escape hatch) once the session is known-good; it
|
|
95
|
+
* binds even to an id not in `matches` (a blind bind), because an operator who
|
|
96
|
+
* hand-sets the id has authoritatively chosen it. Callers must first check
|
|
97
|
+
* `outcome.sessionOk` — this function assumes the session ping already passed.
|
|
98
|
+
*/
|
|
99
|
+
export function resolveBinding(outcome, override) {
|
|
100
|
+
const ov = (override ?? "").trim();
|
|
101
|
+
if (ov) {
|
|
102
|
+
const identity = outcome.matches.find((m) => m.id === ov) ?? null;
|
|
103
|
+
return { kind: "bound", identityId: ov, identity, source: "override" };
|
|
104
|
+
}
|
|
105
|
+
if (!outcome.reachable) {
|
|
106
|
+
return { kind: "unbound", reason: "unreachable", matches: [] };
|
|
107
|
+
}
|
|
108
|
+
if (outcome.matches.length === 1) {
|
|
109
|
+
const only = outcome.matches[0];
|
|
110
|
+
return { kind: "bound", identityId: only.id, identity: only, source: "discovery" };
|
|
111
|
+
}
|
|
112
|
+
if (outcome.matches.length === 0) {
|
|
113
|
+
return { kind: "unbound", reason: "no_enrollment", matches: [] };
|
|
114
|
+
}
|
|
115
|
+
return { kind: "unbound", reason: "multiple", matches: outcome.matches };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* POST the companion registration to /api/identities/probe. This is the WRITE
|
|
119
|
+
* side of the bind: the server folds `tier` into `probe_tier`/`last_probe_at`
|
|
120
|
+
* (via acc.set_ai_identity_probe) and unions `runnerId` into the identity's
|
|
121
|
+
* `runner_ids` roster — the two columns that, left NULL/empty, made the flagless
|
|
122
|
+
* companion come online green-and-silent while provider-status could never
|
|
123
|
+
* confirm it. Shared by companion-run.ts (production) and the write-path test so
|
|
124
|
+
* the exact same request is exercised in both. Throws on a non-2xx response so
|
|
125
|
+
* CompanionRunner's registration-persist catch can log it (best-effort).
|
|
126
|
+
*/
|
|
127
|
+
export async function reportIdentityProbe(deps, payload) {
|
|
128
|
+
const url = `${(deps.publicUrl ?? "").replace(/\/+$/, "")}/api/identities/probe`;
|
|
129
|
+
const f = deps.fetchImpl ?? fetch;
|
|
130
|
+
const res = await f(url, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "application/json",
|
|
134
|
+
Authorization: `Bearer ${deps.accessToken}`,
|
|
135
|
+
},
|
|
136
|
+
body: JSON.stringify({
|
|
137
|
+
identity_id: payload.identityId,
|
|
138
|
+
runner_id: payload.runnerId,
|
|
139
|
+
tier: payload.tier ?? undefined,
|
|
140
|
+
capacity: payload.capacity,
|
|
141
|
+
status: "active",
|
|
142
|
+
}),
|
|
143
|
+
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
throw new Error(`probe report HTTP ${res.status}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** The env var whose presence overrides self-discovery with an explicit id. */
|
|
149
|
+
export const COMPANION_IDENTITY_OVERRIDE_HINT = "ACC_RUNNER_COMPANION_IDENTITY";
|
|
150
|
+
function identityLabel(identity) {
|
|
151
|
+
if (!identity)
|
|
152
|
+
return "identity";
|
|
153
|
+
const pe = [identity.provider, identity.engine].filter(Boolean).join("·");
|
|
154
|
+
return pe || "identity";
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Build the startup banner. HONESTY invariant (asserted by the tests):
|
|
158
|
+
* - a BOUND companion → tone "ok", headline names the bound identity id;
|
|
159
|
+
* - ANY unbound state → tone "warn", headline CONTAINS "UNBOUND" and the
|
|
160
|
+
* words "not serving provider status".
|
|
161
|
+
* There is no path to a green headline that does not name a bound identity, so a
|
|
162
|
+
* green-and-silent-while-unbound banner cannot be produced.
|
|
163
|
+
*/
|
|
164
|
+
export function companionBanner(binding, ctx) {
|
|
165
|
+
const who = ctx.email || "this runner";
|
|
166
|
+
if (binding.kind === "bound") {
|
|
167
|
+
const via = binding.source === "override" ? " (via env override)" : "";
|
|
168
|
+
return {
|
|
169
|
+
tone: "ok",
|
|
170
|
+
headline: `✓ Companion online for ${who} — bound to ${identityLabel(binding.identity)}, identity ${binding.identityId}${via}`,
|
|
171
|
+
lines: [],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const headline = `⚠ Companion online for ${who} — UNBOUND, not serving provider status (serving drafts only)`;
|
|
175
|
+
const lines = [];
|
|
176
|
+
switch (binding.reason) {
|
|
177
|
+
case "no_enrollment":
|
|
178
|
+
lines.push(" No enrollment found for this owner + engine. Enroll in Admin ▸ AI providers,", " then restart the companion so it can bind and report a chat-auth probe.");
|
|
179
|
+
break;
|
|
180
|
+
case "multiple":
|
|
181
|
+
lines.push(" More than one enrollment matches — the companion will not guess. Set", ` ${COMPANION_IDENTITY_OVERRIDE_HINT}=<id> to pick one, then restart:`, ...binding.matches.map((m) => ` • ${m.id} (${identityLabel(m)}${m.lastProbeAt ? ", probed" : ", pending"})`));
|
|
182
|
+
break;
|
|
183
|
+
case "unreachable":
|
|
184
|
+
lines.push(" Could not reach the identity registry to self-discover (network / deploy).", ` Serving drafts only; set ${COMPANION_IDENTITY_OVERRIDE_HINT}=<id> to bind explicitly.`);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
return { tone: "warn", headline, lines };
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=companion-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-identity.js","sourceRoot":"","sources":["../src/companion-identity.ts"],"names":[],"mappings":"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"}
|
package/dist/companion-run.d.ts
CHANGED
|
@@ -4,7 +4,12 @@ export interface CompanionHandle {
|
|
|
4
4
|
}
|
|
5
5
|
/** Env var seeding the owner's conversations the companion should serve at boot. */
|
|
6
6
|
export declare const COMPANION_CONVERSATIONS_ENV = "ACC_RUNNER_COMPANION_CONVERSATIONS";
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Optional OVERRIDE naming the acc.ai_identities row this companion serves. The
|
|
9
|
+
* default is self-discovery (see companion-identity.ts) — this env var only
|
|
10
|
+
* short-circuits it, for a host that has more than one enrolled subscription of
|
|
11
|
+
* the same engine and must pick one explicitly.
|
|
12
|
+
*/
|
|
8
13
|
export declare const COMPANION_IDENTITY_ENV = "ACC_RUNNER_COMPANION_IDENTITY";
|
|
9
14
|
/**
|
|
10
15
|
* Start companion mode. Registers the owner-bound identity, serves the owner's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion-run.d.ts","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"companion-run.d.ts","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"AA6CA,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,uCAAuC,CAAC;AAChF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAEtE;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC,CAgMjE;AAED,+DAA+D;AAC/D,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB5D;AAED,8DAA8D;AAC9D,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wCAAwC;AACxC,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/D"}
|
package/dist/companion-run.js
CHANGED
|
@@ -18,10 +18,16 @@ import { ChatCircuitBreaker, getChatCircuit } from "./runtime/chat-circuit-break
|
|
|
18
18
|
import { CompanionMirrorSocket } from "./companion-mirror-socket.js";
|
|
19
19
|
import { CompanionRunner, OwnerConversationSource, createIdentityBroadcaster, deriveMirrorToken, resolveCompanionConfig, } from "./companion.js";
|
|
20
20
|
import { companionStatusLine, defaultAutostartHost, installAutostart, uninstallAutostart, } from "./companion-autostart.js";
|
|
21
|
+
import { companionBanner, discoverCompanionIdentities, providerForEngine, reportIdentityProbe, resolveBinding, } from "./companion-identity.js";
|
|
21
22
|
import { PACKAGE_VERSION } from "./pkg-version.js";
|
|
22
23
|
/** Env var seeding the owner's conversations the companion should serve at boot. */
|
|
23
24
|
export const COMPANION_CONVERSATIONS_ENV = "ACC_RUNNER_COMPANION_CONVERSATIONS";
|
|
24
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Optional OVERRIDE naming the acc.ai_identities row this companion serves. The
|
|
27
|
+
* default is self-discovery (see companion-identity.ts) — this env var only
|
|
28
|
+
* short-circuits it, for a host that has more than one enrolled subscription of
|
|
29
|
+
* the same engine and must pick one explicitly.
|
|
30
|
+
*/
|
|
25
31
|
export const COMPANION_IDENTITY_ENV = "ACC_RUNNER_COMPANION_IDENTITY";
|
|
26
32
|
/**
|
|
27
33
|
* Start companion mode. Registers the owner-bound identity, serves the owner's
|
|
@@ -88,31 +94,34 @@ export async function companionCommand() {
|
|
|
88
94
|
const broadcaster = createIdentityBroadcaster(supabase, session.user_id, {
|
|
89
95
|
onLog: (line) => console.log(chalk.gray(line)),
|
|
90
96
|
});
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
97
|
+
// COMPANION-IDENTITY-DISCOVERY: self-discover the enrollment identity so plain
|
|
98
|
+
// `acc-runner companion` binds with ZERO env vars. This authenticated call is
|
|
99
|
+
// ALSO the pre-online SESSION PING — a dead session yields 401 here, and we
|
|
100
|
+
// refuse to come online rather than print a green banner on a zombie session
|
|
101
|
+
// (the exact failure the operator hit). The env var remains an explicit
|
|
102
|
+
// override for a host with more than one enrolled subscription of an engine.
|
|
103
|
+
const override = (process.env[COMPANION_IDENTITY_ENV] ?? "").trim() || undefined;
|
|
104
|
+
const discovery = await discoverCompanionIdentities({
|
|
105
|
+
publicUrl: cfg.publicUrl,
|
|
106
|
+
accessToken: session.access_token,
|
|
107
|
+
engineId: engine.id,
|
|
108
|
+
provider: providerForEngine(engine.id),
|
|
109
|
+
});
|
|
110
|
+
if (!discovery.sessionOk) {
|
|
111
|
+
throw new Error("Session verification failed — the identity registry rejected this runner's " +
|
|
112
|
+
"token (likely expired). Run `acc-runner login` again; refusing to come " +
|
|
113
|
+
"online on a dead session.");
|
|
114
|
+
}
|
|
115
|
+
const binding = resolveBinding(discovery, override);
|
|
116
|
+
const identityId = binding.kind === "bound" ? binding.identityId : undefined;
|
|
117
|
+
// CHAT-LANE-BRIDGE: when bound, start() persists the runner_ids binding + probe
|
|
118
|
+
// tier onto the row via POST /api/identities/probe, so provider-status can
|
|
119
|
+
// confirm a live companion. Unbound ⇒ no probe (nothing to bind), draft-only.
|
|
95
120
|
const reportRegistration = identityId
|
|
96
|
-
?
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
headers: {
|
|
101
|
-
"Content-Type": "application/json",
|
|
102
|
-
Authorization: `Bearer ${session.access_token}`,
|
|
103
|
-
},
|
|
104
|
-
body: JSON.stringify({
|
|
105
|
-
identity_id: payload.identityId,
|
|
106
|
-
runner_id: payload.runnerId,
|
|
107
|
-
tier: payload.tier ?? undefined,
|
|
108
|
-
capacity: payload.capacity,
|
|
109
|
-
status: "active",
|
|
110
|
-
}),
|
|
111
|
-
});
|
|
112
|
-
if (!res.ok) {
|
|
113
|
-
throw new Error(`probe report HTTP ${res.status}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
121
|
+
? (payload) =>
|
|
122
|
+
// Read session.access_token at CALL time so a token rotation (refreshAuth)
|
|
123
|
+
// is reflected if the registration is retried on the fresh JWT.
|
|
124
|
+
reportIdentityProbe({ publicUrl: cfg.publicUrl, accessToken: session.access_token }, payload)
|
|
116
125
|
: undefined;
|
|
117
126
|
// AUTH-REFRESH: rotate the ACC session in place. Called proactively (token
|
|
118
127
|
// near expiry) and reactively (ONE per auth-failure streak) by CompanionRunner.
|
|
@@ -180,7 +189,13 @@ export async function companionCommand() {
|
|
|
180
189
|
onLog: (line) => console.log(chalk.gray(line)),
|
|
181
190
|
});
|
|
182
191
|
await runner.start();
|
|
183
|
-
|
|
192
|
+
// HONESTY: the banner states the bound identity (green) or "UNBOUND — not
|
|
193
|
+
// serving provider status" (yellow) with the reason + how to fix. `tone==="ok"`
|
|
194
|
+
// iff bound, so a green-and-silent-while-unbound banner is impossible.
|
|
195
|
+
const banner = companionBanner(binding, { email: session.email ?? session.user_id });
|
|
196
|
+
console.log((banner.tone === "ok" ? chalk.green : chalk.yellow.bold)(banner.headline));
|
|
197
|
+
for (const line of banner.lines)
|
|
198
|
+
console.log(chalk.gray(line));
|
|
184
199
|
console.log(chalk.gray(` serving ${conversations.size()} conversation(s)` +
|
|
185
200
|
(mirror ? `; mirror on 127.0.0.1:${mirror.port()}` : "; mirror disabled")));
|
|
186
201
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"companion-run.js","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOnD,oFAAoF;AACpF,MAAM,CAAC,MAAM,2BAA2B,GAAG,oCAAoC,CAAC;AAChF
|
|
1
|
+
{"version":3,"file":"companion-run.js","sourceRoot":"","sources":["../src/companion-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOnD,oFAAoF;AACpF,MAAM,CAAC,MAAM,2BAA2B,GAAG,oCAAoC,CAAC;AAChF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,+BAA+B,CAAC;AAEtE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;IACvB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,8EAA8E;IAC9E,4EAA4E;IAC5E,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,OAAO,GAAkB,MAAM,CAAC;IACpC,GAAG,GAAG,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEzC,+EAA+E;IAC/E,8EAA8E;IAC9E,oEAAoE;IACpE,IAAI,aAAa,CAAC,UAAU,EAAE,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,yBAAyB,EAAE,CAAC;gBAC7C,MAAM,GAAG,CAAC,CAAC,2DAA2D;YACxE,CAAC;YACD,uEAAuE;YACvE,yEAAyE;YACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kDAAmD,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtF,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACzC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,0EAA0E;IAC1E,+EAA+E;IAC/E,+EAA+E;IAC/E,qDAAqD;IACrD,MAAM,SAAS,GAAG,2BAA2B,CAAC,QAAQ,EAAE;QACtD,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE;KAC5D,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,sBAAsB,EAAE,CAAC;IAC9C,MAAM,IAAI,GAAG,wBAAwB,EAAE,CAAC;IAExC,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa;QACvC,CAAC,CAAC,IAAI,qBAAqB,CAAC;YACxB,aAAa,EAAE,YAAY,CAAC,WAAW,IAAI,iBAAiB,CAAC,OAAO,CAAC;YACrE,IAAI,EAAE,YAAY,CAAC,UAAU;YAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC/C,CAAC;QACJ,CAAC,CAAC,IAAI,CAAC;IAET,6EAA6E;IAC7E,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;SAC7D,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,IAAI,uBAAuB,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE5E,MAAM,WAAW,GAAG,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE;QACvE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/C,CAAC,CAAC;IAEH,+EAA+E;IAC/E,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,wEAAwE;IACxE,6EAA6E;IAC7E,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACjF,MAAM,SAAS,GAAG,MAAM,2BAA2B,CAAC;QAClD,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW,EAAE,OAAO,CAAC,YAAY;QACjC,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6EAA6E;YAC3E,yEAAyE;YACzE,2BAA2B,CAC9B,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7E,gFAAgF;IAChF,2EAA2E;IAC3E,8EAA8E;IAC9E,MAAM,kBAAkB,GAAG,UAAU;QACnC,CAAC,CAAC,CAAC,OAKA,EAAE,EAAE;QACH,2EAA2E;QAC3E,gEAAgE;QAChE,mBAAmB,CACjB,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,YAAY,EAAE,EAC/D,OAAO,CACR;QACL,CAAC,CAAC,SAAS,CAAC;IAEd,2EAA2E;IAC3E,gFAAgF;IAChF,8EAA8E;IAC9E,yEAAyE;IACzE,iFAAiF;IACjF,MAAM,WAAW,GAAG,KAAK,IAAsB,EAAE;QAC/C,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;YAAE,OAAO,KAAK,CAAC;QAC9C,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,yBAAyB,EAAE,CAAC;gBAC7C,uEAAuE;gBACvE,yEAAyE;gBACzE,mDAAmD;gBACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACrE,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,GAAG,CAAC,CAAC,4EAA4E;QACzF,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3C,6CAA6C;QAC/C,CAAC,CAAC,CAAC;QACH,QAAQ,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAClF,MAAM,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACvE,mEAAmE;QACrE,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,QAAQ,EAAE,OAAO,CAAC,SAAS;QAC3B,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,MAAM;QACN,SAAS;QACT,OAAO;QACP,aAAa;QACb,gBAAgB,EAAE,IAAI,CAAC,WAAW;QAClC,wEAAwE;QACxE,kDAAkD;QAClD,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE,MAAM;QACf,MAAM;QACN,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAClE,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,kBAAkB,EAAE;gBACvD,IAAI,EAAE,OAAO,CAAC,SAAS;gBACvB,SAAS,EAAE,eAAe;aAC3B,CAAC,CAAC;YACH,IAAI,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,8EAA8E;QAC9E,4EAA4E;QAC5E,uDAAuD;QACvD,GAAG,CAAC,aAAa,CAAC,UAAU,EAAE;YAC5B,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE;YAChF,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,EAAE,GAAG,CAAC,QAAQ;QACjB,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/C,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,0EAA0E;IAC1E,gFAAgF;IAChF,uEAAuE;IACvE,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,aAAa,aAAa,CAAC,IAAI,EAAE,kBAAkB;QACjD,CAAC,MAAM,CAAC,CAAC,CAAC,yBAAyB,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAC5E,CACF,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,IAAI;YACR,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,sBAAsB,EAAE,CAAC;IACrC,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,mCAAmC;IACnC,OAAO,CAAC,GAAG,CACT,mBAAmB,CAAC;QAClB,MAAM,EAAE,OAAO,KAAK,IAAI;QACxB,UAAU,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI;QAClC,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,OAAO,KAAK,IAAI;QAC7B,MAAM,EAAE,GAAG,CAAC,aAAa;KAC1B,CAAC,CACH,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,wCAAwC;AACxC,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACpC,CAAC"}
|