@code-yeongyu/senpi 2026.8.27 → 2026.8.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/core/credential-accounts.d.ts +31 -0
- package/dist/core/credential-accounts.d.ts.map +1 -0
- package/dist/core/credential-accounts.js +125 -0
- package/dist/core/credential-accounts.js.map +1 -0
- package/dist/core/extensions/builtin/account/index.d.ts +9 -0
- package/dist/core/extensions/builtin/account/index.d.ts.map +1 -0
- package/dist/core/extensions/builtin/account/index.js +69 -0
- package/dist/core/extensions/builtin/account/index.js.map +1 -0
- package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/imagegen/index.js +10 -3
- package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
- package/dist/core/extensions/builtin/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/index.js +4 -0
- package/dist/core/extensions/builtin/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +12 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/server/account.d.ts.map +1 -1
- package/dist/modes/app-server/server/account.js +5 -5
- package/dist/modes/app-server/server/account.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +11 -3
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +31 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/grok/chrome.d.ts +4 -4
- package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
- package/dist/modes/interactive/grok/chrome.js.map +1 -1
- package/dist/modes/interactive/grok/footer.d.ts +3 -3
- package/dist/modes/interactive/grok/footer.d.ts.map +1 -1
- package/dist/modes/interactive/grok/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +16 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +36 -9
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -13
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +12 -5
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +16 -3
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +43 -5
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +4 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +12 -4
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +9 -0
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +31 -3
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/docs/providers.md +48 -0
- package/docs/rpc.md +6 -4
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +14 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +13 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +15 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +14 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js +20 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/edit.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts +21 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js +27 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/post-mutate.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts +24 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/tool-context.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js +7 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/write.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/credential-store.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +3 -2
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -6,12 +6,33 @@
|
|
|
6
6
|
|
|
7
7
|
### Added
|
|
8
8
|
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
9
11
|
### Fixed
|
|
10
12
|
|
|
13
|
+
### Removed
|
|
14
|
+
|
|
15
|
+
## [2026.8.28] - 2026-08-28
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
11
19
|
### Added
|
|
12
20
|
|
|
21
|
+
- Bun-compiled binaries now embed the imagegen bundled skill so resource discovery remains available after compilation.
|
|
22
|
+
|
|
23
|
+
- `/account <provider> [list | pin <name> | unpin | remove <name>]` manages any provider's credential accounts, the TUI footer shows the active account as `(provider@account)` whenever a provider pools more than one credential, `auth check --json` reports a non-secret `accounts` array, and the account RPC/app-server surfaces (`get_provider_accounts`, `account_pin`, `account_remove`, `account/providerAccounts/*`) now work for every provider instead of only the Claude lane.
|
|
24
|
+
|
|
13
25
|
### Changed
|
|
14
26
|
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Shared interactive host sessions no longer print `Thinking level: [object Promise]` on Shift+Tab: the TUI awaits the four session reads the shared-host proxy answers over RPC (`cycleThinkingLevel`, `getAvailableThinkingLevels`, `getSessionStats`, `getUserMessagesForForking`), the thinking-level status and footer render from the `thinking_level_changed` event so every attached client converges, and `/settings` thinking options, `/fork`, and `/session` work again.
|
|
30
|
+
- User messages no longer render twice in shared-host sessions: the RPC prompt success response now carries `data.disposition` (`started`/`queued`/`handled`), delivered through client response hooks that run synchronously inside frame dispatch, so optimistic user echoes resolve exactly like the local path; `streamingBehavior` and `thinkingLevel` are forwarded again, so mid-stream submissions queue instead of failing.
|
|
31
|
+
- Resuming a session that a live shared host already holds no longer fails with `session_path_in_use`: `open_session` on a fully-open path now attaches to the existing session (same handle, `attached: true`), and the runtime is torn down only when the last attachment closes.
|
|
32
|
+
- Fire-and-forget session setters proxied to the shared host (thinking level, steering/follow-up mode, auto-compaction, session name, bash abort) now surface RPC failures through a typed warning instead of vanishing silently.
|
|
33
|
+
|
|
34
|
+
- Imagegen missing-skill diagnostics now go to stderr, keeping RPC NDJSON stdout clean when a compiled binary lacks the optional skill asset.
|
|
35
|
+
|
|
15
36
|
### Removed
|
|
16
37
|
|
|
17
38
|
## [2026.8.27] - 2026-08-27
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Credential } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { AuthStorage } from "./auth-storage.ts";
|
|
3
|
+
import { CredentialSlotRepository } from "./credential-pool/state-store.ts";
|
|
4
|
+
export type CredentialAccountSource = "login" | "import" | "env";
|
|
5
|
+
/** Account metadata safe to surface: names and health only, never key material. */
|
|
6
|
+
export type CredentialAccountSummary = {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly source: CredentialAccountSource;
|
|
9
|
+
readonly blocked: boolean;
|
|
10
|
+
readonly pinned: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function assertValidAccountName(name: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Lists a provider's credential accounts for ANY provider, not just one lane.
|
|
15
|
+
* Stored slots own the listing when a credential exists; env slots are listed
|
|
16
|
+
* only when nothing is stored, mirroring resolution precedence exactly. Health
|
|
17
|
+
* comes from the pool sidecar, so a cooldown persisted by a failover shows up
|
|
18
|
+
* here without auth.json ever carrying block state.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCredentialAccounts(storage: AuthStorage, provider: string, env?: NodeJS.ProcessEnv, repository?: CredentialSlotRepository): Promise<CredentialAccountSummary[]>;
|
|
21
|
+
/** Storage-free variant for callers that already hold the credential (e.g. auth check). */
|
|
22
|
+
export declare function summarizeCredentialAccounts(provider: string, stored: Credential | undefined, env?: NodeJS.ProcessEnv, repository?: CredentialSlotRepository): Promise<CredentialAccountSummary[]>;
|
|
23
|
+
/** Pins one slot, or clears the pin when `name` is null. */
|
|
24
|
+
export declare function pinCredentialAccount(storage: AuthStorage, provider: string, name: string | null, env?: NodeJS.ProcessEnv, repository?: CredentialSlotRepository): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Removes one stored slot. Env-backed accounts are refused: they are owned by
|
|
27
|
+
* the environment, and deleting one here would silently disagree with the
|
|
28
|
+
* variable that still defines it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function removeCredentialAccount(storage: AuthStorage, provider: string, name: string, env?: NodeJS.ProcessEnv, repository?: CredentialSlotRepository): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=credential-accounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-accounts.d.ts","sourceRoot":"","sources":["../../src/core/credential-accounts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,wBAAwB,EAAwC,MAAM,kCAAkC,CAAC;AAGlH,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjE,mFAAmF;AACnF,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CACzB,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAkCD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,UAAU,GAAE,wBAAyD,GACnE,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAErC;AAED,2FAA2F;AAC3F,wBAAsB,2BAA2B,CAChD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,UAAU,GAAE,wBAAyD,GACnE,OAAO,CAAC,wBAAwB,EAAE,CAAC,CA8BrC;AAED,4DAA4D;AAC5D,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,UAAU,GAAE,wBAAyD,GACnE,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC5C,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,UAAU,GAAE,wBAAyD,GACnE,OAAO,CAAC,IAAI,CAAC,CAaf"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { listSlots, pinSlot, removeSlot } from "@earendil-works/pi-ai/auth/pool/slots";
|
|
2
|
+
import { discoverEnvSlots } from "./credential-pool/env-slots.js";
|
|
3
|
+
import { CredentialSlotRepository, slotHealth } from "./credential-pool/state-store.js";
|
|
4
|
+
import { emitProviderAccountsChanged } from "./extensions/builtin/claude-sdk-oauth/account-events.js";
|
|
5
|
+
const ACCOUNT_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
6
|
+
export function assertValidAccountName(name) {
|
|
7
|
+
if (!ACCOUNT_NAME_PATTERN.test(name)) {
|
|
8
|
+
throw new Error(`Invalid account name '${name}': use letters, digits, '-' or '_', starting with a letter or digit`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function pooledFrom(credential) {
|
|
12
|
+
return credential === undefined ? undefined : credential;
|
|
13
|
+
}
|
|
14
|
+
function pinnedName(credential) {
|
|
15
|
+
return credential?.pinned;
|
|
16
|
+
}
|
|
17
|
+
function numberField(value, key) {
|
|
18
|
+
const found = Object.entries(value).find(([candidate]) => candidate === key)?.[1];
|
|
19
|
+
return typeof found === "number" ? found : undefined;
|
|
20
|
+
}
|
|
21
|
+
function stringField(value, key) {
|
|
22
|
+
const found = Object.entries(value).find(([candidate]) => candidate === key)?.[1];
|
|
23
|
+
return typeof found === "string" ? found : undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Block state has two sources and both are authoritative: a slot persisted by an
|
|
27
|
+
* existing provider lane carries its own `blockedUntil`/`blockReason` inside
|
|
28
|
+
* auth.json, while generic pool failover records health in the sidecar. Reading
|
|
29
|
+
* only one would silently downgrade a real block to "available".
|
|
30
|
+
*/
|
|
31
|
+
function slotBlocked(slot, sidecar, now) {
|
|
32
|
+
if (slotHealth(sidecar, now) === "blocked")
|
|
33
|
+
return true;
|
|
34
|
+
const reason = stringField(slot, "blockReason");
|
|
35
|
+
if (reason === "auth_error" || reason === "account_disabled")
|
|
36
|
+
return true;
|
|
37
|
+
const blockedUntil = numberField(slot, "blockedUntil");
|
|
38
|
+
return blockedUntil !== undefined && blockedUntil > now;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Lists a provider's credential accounts for ANY provider, not just one lane.
|
|
42
|
+
* Stored slots own the listing when a credential exists; env slots are listed
|
|
43
|
+
* only when nothing is stored, mirroring resolution precedence exactly. Health
|
|
44
|
+
* comes from the pool sidecar, so a cooldown persisted by a failover shows up
|
|
45
|
+
* here without auth.json ever carrying block state.
|
|
46
|
+
*/
|
|
47
|
+
export async function getCredentialAccounts(storage, provider, env = process.env, repository = new CredentialSlotRepository()) {
|
|
48
|
+
return summarizeCredentialAccounts(provider, storage.get(provider), env, repository);
|
|
49
|
+
}
|
|
50
|
+
/** Storage-free variant for callers that already hold the credential (e.g. auth check). */
|
|
51
|
+
export async function summarizeCredentialAccounts(provider, stored, env = process.env, repository = new CredentialSlotRepository()) {
|
|
52
|
+
const credential = pooledFrom(stored);
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
const pinned = pinnedName(credential);
|
|
55
|
+
if (credential) {
|
|
56
|
+
const state = await repository.listSlots(provider, "stored");
|
|
57
|
+
return listSlots(credential).map((slot) => ({
|
|
58
|
+
name: slot.name,
|
|
59
|
+
source: slot.source ?? "login",
|
|
60
|
+
blocked: slotBlocked(slot, state[slot.name], now),
|
|
61
|
+
pinned: pinned === slot.name,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
const state = await repository.listSlots(provider, "env");
|
|
65
|
+
const summaries = [];
|
|
66
|
+
for (const slot of discoverEnvSlots(provider, (name) => env[name])) {
|
|
67
|
+
const persisted = state[slot.name];
|
|
68
|
+
const revision = await repository.envCredentialRevision(slot.envVarName, slot.key);
|
|
69
|
+
// A block belongs to the value that earned it; a rotated env key starts clean.
|
|
70
|
+
const applicable = persisted?.credentialRevision === revision ? persisted : undefined;
|
|
71
|
+
summaries.push({
|
|
72
|
+
name: slot.name,
|
|
73
|
+
source: "env",
|
|
74
|
+
blocked: slotHealth(applicable, now) === "blocked",
|
|
75
|
+
pinned: pinned === slot.name,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return summaries;
|
|
79
|
+
}
|
|
80
|
+
/** Pins one slot, or clears the pin when `name` is null. */
|
|
81
|
+
export async function pinCredentialAccount(storage, provider, name, env = process.env, repository = new CredentialSlotRepository()) {
|
|
82
|
+
if (name !== null) {
|
|
83
|
+
assertValidAccountName(name);
|
|
84
|
+
const accounts = await getCredentialAccounts(storage, provider, env, repository);
|
|
85
|
+
if (!accounts.some((account) => account.name === name)) {
|
|
86
|
+
throw new Error(`Provider account not found: ${name}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
await storage.modify(provider, async (current) => {
|
|
90
|
+
if (current === undefined)
|
|
91
|
+
throw new Error(`No stored credential for provider: ${provider}`);
|
|
92
|
+
if (name === null) {
|
|
93
|
+
if (pinnedName(current) === undefined)
|
|
94
|
+
return current;
|
|
95
|
+
const { pinned: _pinned, ...unpinned } = { ...current, pinned: undefined };
|
|
96
|
+
return unpinned;
|
|
97
|
+
}
|
|
98
|
+
return pinSlot(current, name);
|
|
99
|
+
});
|
|
100
|
+
// Subscribed clients re-read the list after any mutation; skipping this leaves
|
|
101
|
+
// a desktop account picker showing a stale pin.
|
|
102
|
+
emitProviderAccountsChanged(provider);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Removes one stored slot. Env-backed accounts are refused: they are owned by
|
|
106
|
+
* the environment, and deleting one here would silently disagree with the
|
|
107
|
+
* variable that still defines it.
|
|
108
|
+
*/
|
|
109
|
+
export async function removeCredentialAccount(storage, provider, name, env = process.env, repository = new CredentialSlotRepository()) {
|
|
110
|
+
const accounts = await getCredentialAccounts(storage, provider, env, repository);
|
|
111
|
+
const account = accounts.find((candidate) => candidate.name === name);
|
|
112
|
+
if (!account)
|
|
113
|
+
throw new Error(`Provider account not found: ${name}`);
|
|
114
|
+
if (account.source === "env") {
|
|
115
|
+
throw new Error(`Environment provider account cannot be removed: ${name}`);
|
|
116
|
+
}
|
|
117
|
+
await storage.modify(provider, async (current) => {
|
|
118
|
+
if (current === undefined)
|
|
119
|
+
throw new Error(`No stored credential for provider: ${provider}`);
|
|
120
|
+
return removeSlot(current, name);
|
|
121
|
+
});
|
|
122
|
+
await repository.mutateSlotState(provider, "stored", name, () => undefined);
|
|
123
|
+
emitProviderAccountsChanged(provider);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=credential-accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-accounts.js","sourceRoot":"","sources":["../../src/core/credential-accounts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport { listSlots, type PooledCredential, pinSlot, removeSlot } from \"@earendil-works/pi-ai/auth/pool/slots\";\nimport type { AuthStorage } from \"./auth-storage.ts\";\nimport { discoverEnvSlots } from \"./credential-pool/env-slots.ts\";\nimport { CredentialSlotRepository, type CredentialSlotState, slotHealth } from \"./credential-pool/state-store.ts\";\nimport { emitProviderAccountsChanged } from \"./extensions/builtin/claude-sdk-oauth/account-events.ts\";\n\nexport type CredentialAccountSource = \"login\" | \"import\" | \"env\";\n\n/** Account metadata safe to surface: names and health only, never key material. */\nexport type CredentialAccountSummary = {\n\treadonly name: string;\n\treadonly source: CredentialAccountSource;\n\treadonly blocked: boolean;\n\treadonly pinned: boolean;\n};\n\nconst ACCOUNT_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;\n\nexport function assertValidAccountName(name: string): void {\n\tif (!ACCOUNT_NAME_PATTERN.test(name)) {\n\t\tthrow new Error(\n\t\t\t`Invalid account name '${name}': use letters, digits, '-' or '_', starting with a letter or digit`,\n\t\t);\n\t}\n}\n\nfunction pooledFrom(credential: Credential | undefined): PooledCredential | undefined {\n\treturn credential === undefined ? undefined : credential;\n}\n\nfunction pinnedName(credential: PooledCredential | undefined): string | undefined {\n\treturn credential?.pinned;\n}\n\nfunction numberField(value: object, key: string): number | undefined {\n\tconst found = Object.entries(value).find(([candidate]) => candidate === key)?.[1];\n\treturn typeof found === \"number\" ? found : undefined;\n}\n\nfunction stringField(value: object, key: string): string | undefined {\n\tconst found = Object.entries(value).find(([candidate]) => candidate === key)?.[1];\n\treturn typeof found === \"string\" ? found : undefined;\n}\n\n/**\n * Block state has two sources and both are authoritative: a slot persisted by an\n * existing provider lane carries its own `blockedUntil`/`blockReason` inside\n * auth.json, while generic pool failover records health in the sidecar. Reading\n * only one would silently downgrade a real block to \"available\".\n */\nfunction slotBlocked(slot: object, sidecar: CredentialSlotState | undefined, now: number): boolean {\n\tif (slotHealth(sidecar, now) === \"blocked\") return true;\n\tconst reason = stringField(slot, \"blockReason\");\n\tif (reason === \"auth_error\" || reason === \"account_disabled\") return true;\n\tconst blockedUntil = numberField(slot, \"blockedUntil\");\n\treturn blockedUntil !== undefined && blockedUntil > now;\n}\n\n/**\n * Lists a provider's credential accounts for ANY provider, not just one lane.\n * Stored slots own the listing when a credential exists; env slots are listed\n * only when nothing is stored, mirroring resolution precedence exactly. Health\n * comes from the pool sidecar, so a cooldown persisted by a failover shows up\n * here without auth.json ever carrying block state.\n */\nexport async function getCredentialAccounts(\n\tstorage: AuthStorage,\n\tprovider: string,\n\tenv: NodeJS.ProcessEnv = process.env,\n\trepository: CredentialSlotRepository = new CredentialSlotRepository(),\n): Promise<CredentialAccountSummary[]> {\n\treturn summarizeCredentialAccounts(provider, storage.get(provider), env, repository);\n}\n\n/** Storage-free variant for callers that already hold the credential (e.g. auth check). */\nexport async function summarizeCredentialAccounts(\n\tprovider: string,\n\tstored: Credential | undefined,\n\tenv: NodeJS.ProcessEnv = process.env,\n\trepository: CredentialSlotRepository = new CredentialSlotRepository(),\n): Promise<CredentialAccountSummary[]> {\n\tconst credential = pooledFrom(stored);\n\tconst now = Date.now();\n\tconst pinned = pinnedName(credential);\n\n\tif (credential) {\n\t\tconst state = await repository.listSlots(provider, \"stored\");\n\t\treturn listSlots(credential).map((slot) => ({\n\t\t\tname: slot.name,\n\t\t\tsource: slot.source ?? \"login\",\n\t\t\tblocked: slotBlocked(slot, state[slot.name], now),\n\t\t\tpinned: pinned === slot.name,\n\t\t}));\n\t}\n\n\tconst state = await repository.listSlots(provider, \"env\");\n\tconst summaries: CredentialAccountSummary[] = [];\n\tfor (const slot of discoverEnvSlots(provider, (name) => env[name])) {\n\t\tconst persisted = state[slot.name];\n\t\tconst revision = await repository.envCredentialRevision(slot.envVarName, slot.key);\n\t\t// A block belongs to the value that earned it; a rotated env key starts clean.\n\t\tconst applicable = persisted?.credentialRevision === revision ? persisted : undefined;\n\t\tsummaries.push({\n\t\t\tname: slot.name,\n\t\t\tsource: \"env\",\n\t\t\tblocked: slotHealth(applicable, now) === \"blocked\",\n\t\t\tpinned: pinned === slot.name,\n\t\t});\n\t}\n\treturn summaries;\n}\n\n/** Pins one slot, or clears the pin when `name` is null. */\nexport async function pinCredentialAccount(\n\tstorage: AuthStorage,\n\tprovider: string,\n\tname: string | null,\n\tenv: NodeJS.ProcessEnv = process.env,\n\trepository: CredentialSlotRepository = new CredentialSlotRepository(),\n): Promise<void> {\n\tif (name !== null) {\n\t\tassertValidAccountName(name);\n\t\tconst accounts = await getCredentialAccounts(storage, provider, env, repository);\n\t\tif (!accounts.some((account) => account.name === name)) {\n\t\t\tthrow new Error(`Provider account not found: ${name}`);\n\t\t}\n\t}\n\tawait storage.modify(provider, async (current) => {\n\t\tif (current === undefined) throw new Error(`No stored credential for provider: ${provider}`);\n\t\tif (name === null) {\n\t\t\tif (pinnedName(current) === undefined) return current;\n\t\t\tconst { pinned: _pinned, ...unpinned } = { ...current, pinned: undefined };\n\t\t\treturn unpinned;\n\t\t}\n\t\treturn pinSlot(current, name);\n\t});\n\t// Subscribed clients re-read the list after any mutation; skipping this leaves\n\t// a desktop account picker showing a stale pin.\n\temitProviderAccountsChanged(provider);\n}\n\n/**\n * Removes one stored slot. Env-backed accounts are refused: they are owned by\n * the environment, and deleting one here would silently disagree with the\n * variable that still defines it.\n */\nexport async function removeCredentialAccount(\n\tstorage: AuthStorage,\n\tprovider: string,\n\tname: string,\n\tenv: NodeJS.ProcessEnv = process.env,\n\trepository: CredentialSlotRepository = new CredentialSlotRepository(),\n): Promise<void> {\n\tconst accounts = await getCredentialAccounts(storage, provider, env, repository);\n\tconst account = accounts.find((candidate) => candidate.name === name);\n\tif (!account) throw new Error(`Provider account not found: ${name}`);\n\tif (account.source === \"env\") {\n\t\tthrow new Error(`Environment provider account cannot be removed: ${name}`);\n\t}\n\tawait storage.modify(provider, async (current) => {\n\t\tif (current === undefined) throw new Error(`No stored credential for provider: ${provider}`);\n\t\treturn removeSlot(current, name);\n\t});\n\tawait repository.mutateSlotState(provider, \"stored\", name, () => undefined);\n\temitProviderAccountsChanged(provider);\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "../../types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Provider-neutral `/account` command over the generic credential pool. The
|
|
4
|
+
* existing `/claude-account` and Cursor account commands stay untouched; this
|
|
5
|
+
* command is the one surface that works for every provider. Output carries
|
|
6
|
+
* names and health only, never key material.
|
|
7
|
+
*/
|
|
8
|
+
export default function accountExtension(pi: ExtensionAPI): void;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/account/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAwB5E;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAsC/D"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { getCredentialAccounts, pinCredentialAccount, removeCredentialAccount, } from "../../../credential-accounts.js";
|
|
2
|
+
function parseArgs(rawArgs) {
|
|
3
|
+
return rawArgs.trim().split(/\s+/).filter(Boolean);
|
|
4
|
+
}
|
|
5
|
+
function usage(ctx) {
|
|
6
|
+
ctx.ui.notify("Usage: /account <provider> [list | pin <name> | unpin | remove <name>]", "error");
|
|
7
|
+
}
|
|
8
|
+
function statusOf(account) {
|
|
9
|
+
const states = [account.name, account.source, account.blocked ? "blocked" : "available"];
|
|
10
|
+
if (account.pinned)
|
|
11
|
+
states.push("pinned");
|
|
12
|
+
return states.join(" | ");
|
|
13
|
+
}
|
|
14
|
+
async function showAccounts(ctx, provider) {
|
|
15
|
+
const accounts = await getCredentialAccounts(ctx.modelRegistry.authStorage, provider);
|
|
16
|
+
const lines = [`Credential accounts for ${provider}:`];
|
|
17
|
+
if (accounts.length === 0)
|
|
18
|
+
lines.push(" (none)");
|
|
19
|
+
for (const account of accounts)
|
|
20
|
+
lines.push(` ${statusOf(account)}`);
|
|
21
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Provider-neutral `/account` command over the generic credential pool. The
|
|
25
|
+
* existing `/claude-account` and Cursor account commands stay untouched; this
|
|
26
|
+
* command is the one surface that works for every provider. Output carries
|
|
27
|
+
* names and health only, never key material.
|
|
28
|
+
*/
|
|
29
|
+
export default function accountExtension(pi) {
|
|
30
|
+
pi.registerCommand("account", {
|
|
31
|
+
description: "List and manage credential accounts for any provider.",
|
|
32
|
+
argumentHint: "<provider> [list | pin <name> | unpin | remove <name>]",
|
|
33
|
+
handler: async (rawArgs, ctx) => {
|
|
34
|
+
const args = parseArgs(rawArgs);
|
|
35
|
+
const provider = args[0];
|
|
36
|
+
if (provider === undefined) {
|
|
37
|
+
usage(ctx);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const action = args[1] ?? "list";
|
|
41
|
+
try {
|
|
42
|
+
if (action === "list") {
|
|
43
|
+
await showAccounts(ctx, provider);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (action === "pin" && args[2] !== undefined) {
|
|
47
|
+
await pinCredentialAccount(ctx.modelRegistry.authStorage, provider, args[2]);
|
|
48
|
+
ctx.ui.notify(`Pinned ${provider} account '${args[2]}'.`, "info");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (action === "unpin") {
|
|
52
|
+
await pinCredentialAccount(ctx.modelRegistry.authStorage, provider, null);
|
|
53
|
+
ctx.ui.notify(`Unpinned ${provider} account.`, "info");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (action === "remove" && args[2] !== undefined) {
|
|
57
|
+
await removeCredentialAccount(ctx.modelRegistry.authStorage, provider, args[2]);
|
|
58
|
+
ctx.ui.notify(`Removed ${provider} account '${args[2]}'.`, "info");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
usage(ctx);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/account/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype CredentialAccountSummary,\n\tgetCredentialAccounts,\n\tpinCredentialAccount,\n\tremoveCredentialAccount,\n} from \"../../../credential-accounts.ts\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nfunction usage(ctx: ExtensionCommandContext): void {\n\tctx.ui.notify(\"Usage: /account <provider> [list | pin <name> | unpin | remove <name>]\", \"error\");\n}\n\nfunction statusOf(account: CredentialAccountSummary): string {\n\tconst states = [account.name, account.source, account.blocked ? \"blocked\" : \"available\"];\n\tif (account.pinned) states.push(\"pinned\");\n\treturn states.join(\" | \");\n}\n\nasync function showAccounts(ctx: ExtensionCommandContext, provider: string): Promise<void> {\n\tconst accounts = await getCredentialAccounts(ctx.modelRegistry.authStorage, provider);\n\tconst lines = [`Credential accounts for ${provider}:`];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) lines.push(` ${statusOf(account)}`);\n\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n}\n\n/**\n * Provider-neutral `/account` command over the generic credential pool. The\n * existing `/claude-account` and Cursor account commands stay untouched; this\n * command is the one surface that works for every provider. Output carries\n * names and health only, never key material.\n */\nexport default function accountExtension(pi: ExtensionAPI): void {\n\tpi.registerCommand(\"account\", {\n\t\tdescription: \"List and manage credential accounts for any provider.\",\n\t\targumentHint: \"<provider> [list | pin <name> | unpin | remove <name>]\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst args = parseArgs(rawArgs);\n\t\t\tconst provider = args[0];\n\t\t\tif (provider === undefined) {\n\t\t\t\tusage(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst action = args[1] ?? \"list\";\n\t\t\ttry {\n\t\t\t\tif (action === \"list\") {\n\t\t\t\t\tawait showAccounts(ctx, provider);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"pin\" && args[2] !== undefined) {\n\t\t\t\t\tawait pinCredentialAccount(ctx.modelRegistry.authStorage, provider, args[2]);\n\t\t\t\t\tctx.ui.notify(`Pinned ${provider} account '${args[2]}'.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"unpin\") {\n\t\t\t\t\tawait pinCredentialAccount(ctx.modelRegistry.authStorage, provider, null);\n\t\t\t\t\tctx.ui.notify(`Unpinned ${provider} account.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"remove\" && args[2] !== undefined) {\n\t\t\t\t\tawait removeCredentialAccount(ctx.modelRegistry.authStorage, provider, args[2]);\n\t\t\t\t\tctx.ui.notify(`Removed ${provider} account '${args[2]}'.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tusage(ctx);\n\t\t\t} catch (error) {\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAYrE,eAAO,MAAM,iBAAiB,6LAK7B,CAAC;AAmBF,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,SAAoB,GAAG,IAAI,CAa7F;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAEhE"}
|
|
@@ -5,6 +5,10 @@ import { resolveImageGenAuth } from "./auth.js";
|
|
|
5
5
|
import { imageGenRegistryOverride } from "./state.js";
|
|
6
6
|
import { generateImageTool } from "./tool.js";
|
|
7
7
|
const IMAGEGEN_BASE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
// Bun compile extracts imported file assets to a real path; Node dist keeps using the copied skill.
|
|
9
|
+
const embeddedSkillPath = process.versions.bun
|
|
10
|
+
? import("./skill/SKILL.md", { with: { type: "file" } }).then((module) => module.default)
|
|
11
|
+
: Promise.resolve(undefined);
|
|
8
12
|
let loggedMissingSkill = false;
|
|
9
13
|
export const IMAGE_GEN_SECTION = `
|
|
10
14
|
## Image Generation
|
|
@@ -16,13 +20,16 @@ async function isImageGenActive(ctx) {
|
|
|
16
20
|
const auth = await resolveImageGenAuth({ modelRegistry: imageGenRegistryOverride() ?? ctx.modelRegistry });
|
|
17
21
|
return auth.kind !== "none";
|
|
18
22
|
}
|
|
19
|
-
function bundledSkillPath(baseDir) {
|
|
23
|
+
async function bundledSkillPath(baseDir) {
|
|
20
24
|
const skillPath = join(baseDir, "skill", "SKILL.md");
|
|
21
25
|
if (existsSync(skillPath))
|
|
22
26
|
return skillPath;
|
|
27
|
+
const embeddedPath = await embeddedSkillPath;
|
|
28
|
+
if (baseDir === IMAGEGEN_BASE_DIR && embeddedPath !== undefined && existsSync(embeddedPath))
|
|
29
|
+
return embeddedPath;
|
|
23
30
|
if (!loggedMissingSkill) {
|
|
24
31
|
loggedMissingSkill = true;
|
|
25
|
-
console.
|
|
32
|
+
console.error(`[imagegen] bundled skill not found at ${skillPath}; skipping contribution`);
|
|
26
33
|
}
|
|
27
34
|
return undefined;
|
|
28
35
|
}
|
|
@@ -31,7 +38,7 @@ export function registerImageGenExtension(pi, baseDir = IMAGEGEN_BASE_DIR) {
|
|
|
31
38
|
pi.on("resources_discover", async (_event, ctx) => {
|
|
32
39
|
if (!(await isImageGenActive(ctx)))
|
|
33
40
|
return undefined;
|
|
34
|
-
const skillPath = bundledSkillPath(baseDir);
|
|
41
|
+
const skillPath = await bundledSkillPath(baseDir);
|
|
35
42
|
return skillPath === undefined ? undefined : { skillPaths: [skillPath] };
|
|
36
43
|
});
|
|
37
44
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAClE,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAE/B,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;CAKhC,CAAC;AAEF,KAAK,UAAU,gBAAgB,CAAC,GAAqB;IACpD,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,EAAE,aAAa,EAAE,wBAAwB,EAAE,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3G,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC7B,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { resolveImageGenAuth } from \"./auth.ts\";\nimport { imageGenRegistryOverride } from \"./state.ts\";\nimport { generateImageTool } from \"./tool.ts\";\n\nconst IMAGEGEN_BASE_DIR = dirname(fileURLToPath(import.meta.url));\n// Bun compile extracts imported file assets to a real path; Node dist keeps using the copied skill.\nconst embeddedSkillPath = process.versions.bun\n\t? import(\"./skill/SKILL.md\", { with: { type: \"file\" } }).then((module) => module.default as string)\n\t: Promise.resolve(undefined);\nlet loggedMissingSkill = false;\n\nexport const IMAGE_GEN_SECTION = `\n## Image Generation\n\nWhen image generation tooling is present, read the gpt-image-gen skill before generating.\nUse the image generation tool currently available in this session.\n`;\n\nasync function isImageGenActive(ctx: ExtensionContext): Promise<boolean> {\n\tconst auth = await resolveImageGenAuth({ modelRegistry: imageGenRegistryOverride() ?? ctx.modelRegistry });\n\treturn auth.kind !== \"none\";\n}\n\nasync function bundledSkillPath(baseDir: string): Promise<string | undefined> {\n\tconst skillPath = join(baseDir, \"skill\", \"SKILL.md\");\n\tif (existsSync(skillPath)) return skillPath;\n\tconst embeddedPath = await embeddedSkillPath;\n\tif (baseDir === IMAGEGEN_BASE_DIR && embeddedPath !== undefined && existsSync(embeddedPath)) return embeddedPath;\n\tif (!loggedMissingSkill) {\n\t\tloggedMissingSkill = true;\n\t\tconsole.error(`[imagegen] bundled skill not found at ${skillPath}; skipping contribution`);\n\t}\n\treturn undefined;\n}\n\nexport function registerImageGenExtension(pi: ExtensionAPI, baseDir = IMAGEGEN_BASE_DIR): void {\n\tpi.registerTool(generateImageTool);\n\n\tpi.on(\"resources_discover\", async (_event, ctx) => {\n\t\tif (!(await isImageGenActive(ctx))) return undefined;\n\t\tconst skillPath = await bundledSkillPath(baseDir);\n\t\treturn skillPath === undefined ? undefined : { skillPaths: [skillPath] };\n\t});\n\n\tpi.on(\"before_agent_start\", async (event, ctx) => {\n\t\tif (!(await isImageGenActive(ctx))) return undefined;\n\t\treturn { systemPrompt: `${event.systemPrompt}\\n${IMAGE_GEN_SECTION}` };\n\t});\n}\n\nexport default function imageGenExtension(pi: ExtensionAPI): void {\n\tregisterImageGenExtension(pi);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAWpD,OAAO,aAAa,MAAM,WAAW,CAAC;AACtC,OAAO,cAAc,MAAM,YAAY,CAAC;AAkBxC,OAAO,wBAAwB,MAAM,wBAAwB,CAAC;AAU9D,OAAO,YAAY,MAAM,UAAU,CAAC;AAMpC,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,gBAAgB,CAAC;CAC1B;AAED,eAAO,MAAM,yBAAyB,wDAAyD,CAAC;AAEhG,eAAO,MAAM,+BAA+B;;;;;CAKoC,CAAC;AAEjF,eAAO,MAAM,iBAAiB,EAAE,uBAAuB,EAqDtD,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import accountExtension from "./account/index.js";
|
|
1
2
|
import anthropicBashExtension from "./anthropic-bash/index.js";
|
|
2
3
|
import anthropicWebSearchExtension from "./anthropic-web-search/index.js";
|
|
3
4
|
import bashTimeoutExtension from "./bash-timeout/index.js";
|
|
@@ -89,6 +90,9 @@ export const builtinExtensions = [
|
|
|
89
90
|
{ id: "cache-keepalive", factory: cacheKeepAliveExtension },
|
|
90
91
|
{ id: "ttsr", factory: ttsrExtension },
|
|
91
92
|
{ id: "btw", factory: btwExtension },
|
|
93
|
+
// Provider-neutral account listing; sits before the provider lanes so their
|
|
94
|
+
// dedicated commands (claude-account, cursor accounts) keep their own names.
|
|
95
|
+
{ id: "account", factory: accountExtension },
|
|
92
96
|
{ id: "claude-sdk-oauth", factory: claudeSdkOauthExtension },
|
|
93
97
|
// Registers unconditionally and reports executable/auth state through its oauth check, so it stays beside the other provider lane.
|
|
94
98
|
{ id: "cursor-cli-oauth", factory: cursorCliOauthExtension },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionFactory } from \"../types.ts\";\nimport anthropicBashExtension from \"./anthropic-bash/index.ts\";\nimport anthropicWebSearchExtension from \"./anthropic-web-search/index.ts\";\nimport bashTimeoutExtension from \"./bash-timeout/index.ts\";\nimport btwExtension from \"./btw/index.ts\";\nimport cacheKeepAliveExtension from \"./cache-keepalive/index.ts\";\nimport claudeSdkOauthExtension from \"./claude-sdk-oauth/index.ts\";\nimport compactionExtension from \"./compaction/index.ts\";\nimport configReloadExtension from \"./config-reload/index.ts\";\nimport cursorCliOauthExtension from \"./cursor-cli-oauth/index.ts\";\nimport diffExtension from \"./diff.ts\";\nimport filesExtension from \"./files.ts\";\nimport goalExtension from \"./goal/index.ts\";\nimport gptApplyPatchExtension from \"./gpt-apply-patch/index.ts\";\nimport helpExtension from \"./help/index.ts\";\nimport historySearchExtension from \"./history-search/index.ts\";\nimport hooksExtension from \"./hooks/index.ts\";\nimport imageGenExtension from \"./imagegen/index.ts\";\nimport importReproExtension from \"./import-repro.ts\";\nimport lookAtExtension from \"./look-at/index.ts\";\nimport loopExtension from \"./loop/index.ts\";\nimport loopGuardExtension from \"./loop-guard/index.ts\";\nimport mcpExtension from \"./mcp/index.ts\";\nimport modelFallbackExtension from \"./model-fallback/index.ts\";\nimport nestedAgentsMdExtension from \"./nested-agents-md/index.ts\";\nimport openaiImageGenExtension from \"./openai-image-gen/index.ts\";\nimport openaiWebSearchExtension from \"./openai-web-search/index.ts\";\nimport permissionSystemExtension from \"./permission-system/index.ts\";\nimport promptPresetExtension from \"./prompt-preset/index.ts\";\nimport promptUrlWidgetExtension from \"./prompt-url-widget.ts\";\nimport reasoningExtension from \"./reasoning/index.ts\";\nimport recommendedModelsExtension from \"./recommended-models/index.ts\";\nimport redrawsExtension from \"./redraws.ts\";\nimport piRulesExtension from \"./rules/index.ts\";\nimport serviceTierExtension from \"./service-tier.ts\";\nimport terminalExtension from \"./terminal/index.ts\";\nimport todowriteExtension from \"./todotools/index.ts\";\nimport toolPairGuardExtension from \"./tool-pair-guard/index.ts\";\nimport toolSearchExtension from \"./tool-search/index.ts\";\nimport tpsExtension from \"./tps.ts\";\nimport ttsrExtension from \"./ttsr/index.ts\";\nimport videoInExtension from \"./video-in/index.ts\";\nimport webfetchExtension from \"./webfetch/index.ts\";\nimport websearchExtension from \"./websearch/index.ts\";\n\nexport interface BuiltinExtensionFactory {\n\tid: string;\n\tfactory: ExtensionFactory;\n}\n\nexport const globalDefaultExtensionIds = [\"diff\", \"files\", \"prompt-url-widget\", \"tps\"] as const;\n\nexport const globalDefaultExtensionFactories = {\n\tdiff: diffExtension,\n\tfiles: filesExtension,\n\t\"prompt-url-widget\": promptUrlWidgetExtension,\n\ttps: tpsExtension,\n} satisfies Record<(typeof globalDefaultExtensionIds)[number], ExtensionFactory>;\n\nexport const builtinExtensions: BuiltinExtensionFactory[] = [\n\t// Loop guard owns the first veto opportunity so repeated calls never re-run hooks or permission prompts.\n\t{ id: \"loop-guard\", factory: loopGuardExtension },\n\t{ id: \"hooks\", factory: hooksExtension },\n\t{ id: \"permission-system\", factory: permissionSystemExtension },\n\t{ id: \"gpt-apply-patch\", factory: gptApplyPatchExtension },\n\t{ id: \"imagegen\", factory: imageGenExtension },\n\t// Follows imagegen so the native injector's bypass wiring observes the registered client tool.\n\t{ id: \"openai-image-gen\", factory: openaiImageGenExtension },\n\t{ id: \"prompt-preset\", factory: promptPresetExtension },\n\t{ id: \"todowrite\", factory: todowriteExtension },\n\t{ id: \"redraws\", factory: redrawsExtension },\n\t{ id: \"anthropic-web-search\", factory: anthropicWebSearchExtension },\n\t{ id: \"anthropic-bash\", factory: anthropicBashExtension },\n\t{ id: \"openai-web-search\", factory: openaiWebSearchExtension },\n\t{ id: \"service-tier\", factory: serviceTierExtension },\n\t// Sits beside service-tier: both are capability-aware model-control commands that only read\n\t// the active model and notify; neither mutates payloads, so relative order is not load-bearing.\n\t{ id: \"reasoning\", factory: reasoningExtension },\n\t{ id: \"model-fallback\", factory: modelFallbackExtension },\n\t{ id: \"recommended-models\", factory: recommendedModelsExtension },\n\t{ id: \"bash-timeout\", factory: bashTimeoutExtension },\n\t// Terminal follows bash-timeout so its injected default reaches the PTY bash, and follows\n\t// anthropic-bash so mutual-exclusion (companion step-aside) is evaluated after it registers.\n\t{ id: \"terminal\", factory: terminalExtension },\n\t{ id: \"tool-pair-guard\", factory: toolPairGuardExtension },\n\t{ id: \"compaction\", factory: compactionExtension },\n\t{ id: \"history-search\", factory: historySearchExtension },\n\t{ id: \"help\", factory: helpExtension },\n\t{ id: \"import-repro\", factory: importReproExtension },\n\t{ id: \"websearch\", factory: websearchExtension },\n\t{ id: \"webfetch\", factory: webfetchExtension },\n\t{ id: \"video-in\", factory: videoInExtension },\n\t{ id: \"look-at\", factory: lookAtExtension },\n\t{ id: \"nested-agents-md\", factory: nestedAgentsMdExtension },\n\t{ id: \"rules\", factory: piRulesExtension },\n\t{ id: \"goal\", factory: goalExtension },\n\t{ id: \"loop\", factory: loopExtension },\n\t{ id: \"cache-keepalive\", factory: cacheKeepAliveExtension },\n\t{ id: \"ttsr\", factory: ttsrExtension },\n\t{ id: \"btw\", factory: btwExtension },\n\t{ id: \"claude-sdk-oauth\", factory: claudeSdkOauthExtension },\n\t// Registers unconditionally and reports executable/auth state through its oauth check, so it stays beside the other provider lane.\n\t{ id: \"cursor-cli-oauth\", factory: cursorCliOauthExtension },\n\t// Config reload follows settings-dependent builtins so reloads rebuild their resolved settings before catalog feeders observe them.\n\t{ id: \"config-reload\", factory: configReloadExtension },\n\t// Shared catalog wiring loads before MCP, which feeds its tools into the shared catalog as the final builtin.\n\t{ id: \"tool-search\", factory: toolSearchExtension },\n\t// Keep MCP last so its eventual provider-payload tap observes all co-resident builtin mutations.\n\t{ id: \"mcp\", factory: mcpExtension },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/index.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,sBAAsB,MAAM,2BAA2B,CAAC;AAC/D,OAAO,2BAA2B,MAAM,iCAAiC,CAAC;AAC1E,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,uBAAuB,MAAM,4BAA4B,CAAC;AACjE,OAAO,uBAAuB,MAAM,6BAA6B,CAAC;AAClE,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAC7D,OAAO,uBAAuB,MAAM,6BAA6B,CAAC;AAClE,OAAO,aAAa,MAAM,WAAW,CAAC;AACtC,OAAO,cAAc,MAAM,YAAY,CAAC;AACxC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,sBAAsB,MAAM,4BAA4B,CAAC;AAChE,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,sBAAsB,MAAM,2BAA2B,CAAC;AAC/D,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,oBAAoB,MAAM,mBAAmB,CAAC;AACrD,OAAO,eAAe,MAAM,oBAAoB,CAAC;AACjD,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,sBAAsB,MAAM,2BAA2B,CAAC;AAC/D,OAAO,uBAAuB,MAAM,6BAA6B,CAAC;AAClE,OAAO,uBAAuB,MAAM,6BAA6B,CAAC;AAClE,OAAO,wBAAwB,MAAM,8BAA8B,CAAC;AACpE,OAAO,yBAAyB,MAAM,8BAA8B,CAAC;AACrE,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAC7D,OAAO,wBAAwB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,0BAA0B,MAAM,+BAA+B,CAAC;AACvE,OAAO,gBAAgB,MAAM,cAAc,CAAC;AAC5C,OAAO,gBAAgB,MAAM,kBAAkB,CAAC;AAChD,OAAO,oBAAoB,MAAM,mBAAmB,CAAC;AACrD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,sBAAsB,MAAM,4BAA4B,CAAC;AAChE,OAAO,mBAAmB,MAAM,wBAAwB,CAAC;AACzD,OAAO,YAAY,MAAM,UAAU,CAAC;AACpC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AACnD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAOtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,CAAU,CAAC;AAEhG,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC9C,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,cAAc;IACrB,mBAAmB,EAAE,wBAAwB;IAC7C,GAAG,EAAE,YAAY;CAC8D,CAAC;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC3D,yGAAyG;IACzG,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE;IACjD,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE;IACxC,EAAE,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,yBAAyB,EAAE;IAC/D,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IAC1D,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAC9C,+FAA+F;IAC/F,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC5D,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,qBAAqB,EAAE;IACvD,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE;IAChD,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE;IAC5C,EAAE,EAAE,EAAE,sBAAsB,EAAE,OAAO,EAAE,2BAA2B,EAAE;IACpE,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IACzD,EAAE,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,wBAAwB,EAAE;IAC9D,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,EAAE;IACrD,4FAA4F;IAC5F,gGAAgG;IAChG,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE;IAChD,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IACzD,EAAE,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE,0BAA0B,EAAE;IACjE,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,EAAE;IACrD,0FAA0F;IAC1F,6FAA6F;IAC7F,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAC9C,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IAC1D,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB,EAAE;IAClD,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IACzD,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE;IACtC,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,EAAE;IACrD,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE;IAChD,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAC9C,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE;IAC7C,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE;IAC3C,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC5D,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE;IAC1C,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE;IACtC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE;IACtC,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC3D,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE;IACtC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE;IACpC,4EAA4E;IAC5E,6EAA6E;IAC7E,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE;IAC5C,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC5D,mIAAmI;IACnI,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC5D,oIAAoI;IACpI,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,qBAAqB,EAAE;IACvD,8GAA8G;IAC9G,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE;IACnD,iGAAiG;IACjG,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE;CACpC,CAAC","sourcesContent":["import type { ExtensionFactory } from \"../types.ts\";\nimport accountExtension from \"./account/index.ts\";\nimport anthropicBashExtension from \"./anthropic-bash/index.ts\";\nimport anthropicWebSearchExtension from \"./anthropic-web-search/index.ts\";\nimport bashTimeoutExtension from \"./bash-timeout/index.ts\";\nimport btwExtension from \"./btw/index.ts\";\nimport cacheKeepAliveExtension from \"./cache-keepalive/index.ts\";\nimport claudeSdkOauthExtension from \"./claude-sdk-oauth/index.ts\";\nimport compactionExtension from \"./compaction/index.ts\";\nimport configReloadExtension from \"./config-reload/index.ts\";\nimport cursorCliOauthExtension from \"./cursor-cli-oauth/index.ts\";\nimport diffExtension from \"./diff.ts\";\nimport filesExtension from \"./files.ts\";\nimport goalExtension from \"./goal/index.ts\";\nimport gptApplyPatchExtension from \"./gpt-apply-patch/index.ts\";\nimport helpExtension from \"./help/index.ts\";\nimport historySearchExtension from \"./history-search/index.ts\";\nimport hooksExtension from \"./hooks/index.ts\";\nimport imageGenExtension from \"./imagegen/index.ts\";\nimport importReproExtension from \"./import-repro.ts\";\nimport lookAtExtension from \"./look-at/index.ts\";\nimport loopExtension from \"./loop/index.ts\";\nimport loopGuardExtension from \"./loop-guard/index.ts\";\nimport mcpExtension from \"./mcp/index.ts\";\nimport modelFallbackExtension from \"./model-fallback/index.ts\";\nimport nestedAgentsMdExtension from \"./nested-agents-md/index.ts\";\nimport openaiImageGenExtension from \"./openai-image-gen/index.ts\";\nimport openaiWebSearchExtension from \"./openai-web-search/index.ts\";\nimport permissionSystemExtension from \"./permission-system/index.ts\";\nimport promptPresetExtension from \"./prompt-preset/index.ts\";\nimport promptUrlWidgetExtension from \"./prompt-url-widget.ts\";\nimport reasoningExtension from \"./reasoning/index.ts\";\nimport recommendedModelsExtension from \"./recommended-models/index.ts\";\nimport redrawsExtension from \"./redraws.ts\";\nimport piRulesExtension from \"./rules/index.ts\";\nimport serviceTierExtension from \"./service-tier.ts\";\nimport terminalExtension from \"./terminal/index.ts\";\nimport todowriteExtension from \"./todotools/index.ts\";\nimport toolPairGuardExtension from \"./tool-pair-guard/index.ts\";\nimport toolSearchExtension from \"./tool-search/index.ts\";\nimport tpsExtension from \"./tps.ts\";\nimport ttsrExtension from \"./ttsr/index.ts\";\nimport videoInExtension from \"./video-in/index.ts\";\nimport webfetchExtension from \"./webfetch/index.ts\";\nimport websearchExtension from \"./websearch/index.ts\";\n\nexport interface BuiltinExtensionFactory {\n\tid: string;\n\tfactory: ExtensionFactory;\n}\n\nexport const globalDefaultExtensionIds = [\"diff\", \"files\", \"prompt-url-widget\", \"tps\"] as const;\n\nexport const globalDefaultExtensionFactories = {\n\tdiff: diffExtension,\n\tfiles: filesExtension,\n\t\"prompt-url-widget\": promptUrlWidgetExtension,\n\ttps: tpsExtension,\n} satisfies Record<(typeof globalDefaultExtensionIds)[number], ExtensionFactory>;\n\nexport const builtinExtensions: BuiltinExtensionFactory[] = [\n\t// Loop guard owns the first veto opportunity so repeated calls never re-run hooks or permission prompts.\n\t{ id: \"loop-guard\", factory: loopGuardExtension },\n\t{ id: \"hooks\", factory: hooksExtension },\n\t{ id: \"permission-system\", factory: permissionSystemExtension },\n\t{ id: \"gpt-apply-patch\", factory: gptApplyPatchExtension },\n\t{ id: \"imagegen\", factory: imageGenExtension },\n\t// Follows imagegen so the native injector's bypass wiring observes the registered client tool.\n\t{ id: \"openai-image-gen\", factory: openaiImageGenExtension },\n\t{ id: \"prompt-preset\", factory: promptPresetExtension },\n\t{ id: \"todowrite\", factory: todowriteExtension },\n\t{ id: \"redraws\", factory: redrawsExtension },\n\t{ id: \"anthropic-web-search\", factory: anthropicWebSearchExtension },\n\t{ id: \"anthropic-bash\", factory: anthropicBashExtension },\n\t{ id: \"openai-web-search\", factory: openaiWebSearchExtension },\n\t{ id: \"service-tier\", factory: serviceTierExtension },\n\t// Sits beside service-tier: both are capability-aware model-control commands that only read\n\t// the active model and notify; neither mutates payloads, so relative order is not load-bearing.\n\t{ id: \"reasoning\", factory: reasoningExtension },\n\t{ id: \"model-fallback\", factory: modelFallbackExtension },\n\t{ id: \"recommended-models\", factory: recommendedModelsExtension },\n\t{ id: \"bash-timeout\", factory: bashTimeoutExtension },\n\t// Terminal follows bash-timeout so its injected default reaches the PTY bash, and follows\n\t// anthropic-bash so mutual-exclusion (companion step-aside) is evaluated after it registers.\n\t{ id: \"terminal\", factory: terminalExtension },\n\t{ id: \"tool-pair-guard\", factory: toolPairGuardExtension },\n\t{ id: \"compaction\", factory: compactionExtension },\n\t{ id: \"history-search\", factory: historySearchExtension },\n\t{ id: \"help\", factory: helpExtension },\n\t{ id: \"import-repro\", factory: importReproExtension },\n\t{ id: \"websearch\", factory: websearchExtension },\n\t{ id: \"webfetch\", factory: webfetchExtension },\n\t{ id: \"video-in\", factory: videoInExtension },\n\t{ id: \"look-at\", factory: lookAtExtension },\n\t{ id: \"nested-agents-md\", factory: nestedAgentsMdExtension },\n\t{ id: \"rules\", factory: piRulesExtension },\n\t{ id: \"goal\", factory: goalExtension },\n\t{ id: \"loop\", factory: loopExtension },\n\t{ id: \"cache-keepalive\", factory: cacheKeepAliveExtension },\n\t{ id: \"ttsr\", factory: ttsrExtension },\n\t{ id: \"btw\", factory: btwExtension },\n\t// Provider-neutral account listing; sits before the provider lanes so their\n\t// dedicated commands (claude-account, cursor accounts) keep their own names.\n\t{ id: \"account\", factory: accountExtension },\n\t{ id: \"claude-sdk-oauth\", factory: claudeSdkOauthExtension },\n\t// Registers unconditionally and reports executable/auth state through its oauth check, so it stays beside the other provider lane.\n\t{ id: \"cursor-cli-oauth\", factory: cursorCliOauthExtension },\n\t// Config reload follows settings-dependent builtins so reloads rebuild their resolved settings before catalog feeders observe them.\n\t{ id: \"config-reload\", factory: configReloadExtension },\n\t// Shared catalog wiring loads before MCP, which feeds its tools into the shared catalog as the final builtin.\n\t{ id: \"tool-search\", factory: toolSearchExtension },\n\t// Keep MCP last so its eventual provider-payload tap observes all co-resident builtin mutations.\n\t{ id: \"mcp\", factory: mcpExtension },\n];\n"]}
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAOH,OAAO,EAAE,KAAK,IAAI,EAAyD,MAAM,eAAe,CAAC;AAgCjG,OAAO,EACN,KAAK,6BAA6B,EAGlC,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAOH,OAAO,EAAE,KAAK,IAAI,EAAyD,MAAM,eAAe,CAAC;AAgCjG,OAAO,EACN,KAAK,6BAA6B,EAGlC,MAAM,kCAAkC,CAAC;AAM1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAUlE,OAAO,EAAE,KAAK,OAAO,EAAyB,MAAM,yBAAyB,CAAC;AAQ9E,OAAO,EAAwB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AA0D7D,wBAAgB,+BAA+B,CAC9C,MAAM,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAChD,6BAA6B,EAAE,CAKjC;AA2RD,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,IAAI,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,CAAC,CAoGzB;AA0HD,MAAM,WAAW,WAAW;IAC3B,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACvC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI,CAYhF;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,iBA8iB/D"}
|
package/dist/main.js
CHANGED
|
@@ -28,6 +28,7 @@ import { createAgentSessionFromServices, createAgentSessionServices, } from "./c
|
|
|
28
28
|
import { formatNoModelsAvailableMessage } from "./core/auth-guidance.js";
|
|
29
29
|
import { AuthStorage, ReadOnlyAuthStorage } from "./core/auth-storage.js";
|
|
30
30
|
import { envValue } from "./core/brand.js";
|
|
31
|
+
import { summarizeCredentialAccounts } from "./core/credential-accounts.js";
|
|
31
32
|
import { exportFromFile } from "./core/export-html/index.js";
|
|
32
33
|
import { applyHttpProxySettings, configureHttpDispatcher } from "./core/http-dispatcher.js";
|
|
33
34
|
import { getModelNarrowingPatterns, resolveCliModel, resolveModelScope, } from "./core/model-resolver.js";
|
|
@@ -188,8 +189,18 @@ async function runAuthCommand(args) {
|
|
|
188
189
|
reason: "invalid_state",
|
|
189
190
|
};
|
|
190
191
|
}
|
|
192
|
+
let accounts = [];
|
|
193
|
+
if (command.json && result.status !== "invalid") {
|
|
194
|
+
try {
|
|
195
|
+
const credentials = command.noRefresh ? new ReadOnlyAuthStorage() : AuthStorage.create();
|
|
196
|
+
accounts = await summarizeCredentialAccounts(result.provider, await credentials.read(result.provider));
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Account enrichment must never turn a readable auth state into a failure.
|
|
200
|
+
}
|
|
201
|
+
}
|
|
191
202
|
const output = command.json
|
|
192
|
-
? JSON.stringify({ ...result, ...(credential ? { credentials: credential } : {}) })
|
|
203
|
+
? JSON.stringify({ ...result, accounts, ...(credential ? { credentials: credential } : {}) })
|
|
193
204
|
: (credential ?? result.status);
|
|
194
205
|
process.stdout.write(`${output}\n`);
|
|
195
206
|
process.exitCode = result.status === "ready" ? 0 : result.status === "not_ready" ? 1 : 2;
|