impel-cli 0.18.9 → 0.18.11-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/apps.js +70 -54
- package/src/commands/doctor.js +0 -1
- package/src/commands/sessions.js +1 -1
- package/src/installRecovery/inference.js +6 -1
- package/src/sessionCollector.js +3 -5
package/package.json
CHANGED
package/src/apps.js
CHANGED
|
@@ -42,42 +42,41 @@ const APP_DEFINITIONS = {
|
|
|
42
42
|
// CLI release therefore installs and accepts only the exact app builds tested
|
|
43
43
|
// with its compatibility patches. Updating a pin requires a new CLI release.
|
|
44
44
|
export const PINNED_VENDOR_APPS = Object.freeze({
|
|
45
|
-
// 1.22209.3
|
|
46
|
-
// the
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
// re-upgrade without a verified fix for the Code-surface routing contract.
|
|
45
|
+
// 1.22209.3 routed managed 3P gateway profiles into /code/disabled because
|
|
46
|
+
// it did not translate the managed desktop-Code switch into renderer access.
|
|
47
|
+
// 1.24012.9 restores that contract by synthesizing claude_code and
|
|
48
|
+
// claude_code_desktop access from the configured code surface. The pinned
|
|
49
|
+
// contract test asserts that source path directly so this regression cannot
|
|
50
|
+
// hide behind otherwise-valid configLibrary schema markers again.
|
|
52
51
|
claude: Object.freeze({
|
|
53
|
-
version: "1.
|
|
54
|
-
claudeCodeVersion: "2.1.
|
|
55
|
-
claudeCodeCommit: "
|
|
52
|
+
version: "1.24012.9",
|
|
53
|
+
claudeCodeVersion: "2.1.219",
|
|
54
|
+
claudeCodeCommit: "7006c4c3acac98e554d3997baeda6a7fa4d1ff7c",
|
|
56
55
|
bundleName: "Claude.app",
|
|
57
56
|
windows: Object.freeze({
|
|
58
57
|
packageName: "Claude",
|
|
59
|
-
packageVersion: "1.
|
|
58
|
+
packageVersion: "1.24012.9.0",
|
|
60
59
|
publisher: 'CN="Anthropic, PBC", O="Anthropic, PBC", L=San Francisco, S=California, C=US, SERIALNUMBER=4860621, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, OID.1.3.6.1.4.1.311.60.2.1.3=US',
|
|
61
60
|
executable: "app\\Claude.exe",
|
|
62
61
|
downloads: Object.freeze({
|
|
63
62
|
arm64: Object.freeze({
|
|
64
|
-
url: "https://downloads.claude.ai/releases/win32/arm64/1.
|
|
65
|
-
sha256: "
|
|
63
|
+
url: "https://downloads.claude.ai/releases/win32/arm64/1.24012.9/Claude-03c61d06f8e01a4db2273b9514e225f21d2ba62e.msix",
|
|
64
|
+
sha256: "52ed0402ca70fc95e064417ff9bdf3a6336fe5dbf0612f7797937fd0d35ecdba",
|
|
66
65
|
}),
|
|
67
66
|
x64: Object.freeze({
|
|
68
|
-
url: "https://downloads.claude.ai/releases/win32/x64/1.
|
|
69
|
-
sha256: "
|
|
67
|
+
url: "https://downloads.claude.ai/releases/win32/x64/1.24012.9/Claude-03c61d06f8e01a4db2273b9514e225f21d2ba62e.msix",
|
|
68
|
+
sha256: "c7d61479f06a3490bd2598405aa95a428abb9fe31ed97f9e0a1fba7cd2745fe2",
|
|
70
69
|
}),
|
|
71
70
|
}),
|
|
72
71
|
}),
|
|
73
72
|
downloads: Object.freeze({
|
|
74
73
|
arm64: Object.freeze({
|
|
75
|
-
url: "https://downloads.claude.ai/releases/darwin/universal/1.
|
|
76
|
-
sha256: "
|
|
74
|
+
url: "https://downloads.claude.ai/releases/darwin/universal/1.24012.9/Claude-03c61d06f8e01a4db2273b9514e225f21d2ba62e.zip",
|
|
75
|
+
sha256: "39ad2d181e2b1b017c5506f66c08399c23575c802d8b63927f40128e77103a9b",
|
|
77
76
|
}),
|
|
78
77
|
x64: Object.freeze({
|
|
79
|
-
url: "https://downloads.claude.ai/releases/darwin/universal/1.
|
|
80
|
-
sha256: "
|
|
78
|
+
url: "https://downloads.claude.ai/releases/darwin/universal/1.24012.9/Claude-03c61d06f8e01a4db2273b9514e225f21d2ba62e.zip",
|
|
79
|
+
sha256: "39ad2d181e2b1b017c5506f66c08399c23575c802d8b63927f40128e77103a9b",
|
|
81
80
|
}),
|
|
82
81
|
}),
|
|
83
82
|
}),
|
|
@@ -109,16 +108,14 @@ const ULTRA_REASONING_LEVEL = { effort: "ultra", description: "Maximum reasoning
|
|
|
109
108
|
const FAST_SERVICE_TIER = { id: "priority", name: "Fast", description: "1.5x speed, increased usage" };
|
|
110
109
|
const FAST_MODE_AUTH_GATE = /([A-Za-z_$][\w$]*)=([A-Za-z_$][\w$]*)&&!([A-Za-z_$][\w$]*)&&([A-Za-z_$][\w$]*)!=null&&\4\?\.requirements\?\.featureRequirements\?\.fast_mode!==!1/gu;
|
|
111
110
|
const CHATGPT_RESOURCE_ROOT = "linked_vendor_resources_with_patched_asar";
|
|
112
|
-
const CLAUDE_PLAN_USAGE_GUARD = "if(!
|
|
113
|
-
const IMPEL_CLAUDE_PLAN_USAGE_GUARD =
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
const CLAUDE_AGENT_MENTION_FILTER = 'return e.filter(e=>"user"===e.source&&(!s||e.name.toLowerCase().includes(s))).slice(0,10)';
|
|
119
|
-
const IMPEL_CLAUDE_BOUND_AGENT_MENTION_FILTER = 'return e.filter(e=>"user"===e.source&&(!s||e.name.toLowerCase().includes(s))&&("string"!=typeof y||e.name===y)).slice(0,10)';
|
|
111
|
+
const CLAUDE_PLAN_USAGE_GUARD = "if(!PSe()){cz();return}if(!Ge().hasOrgPolicyBackend())return;if((r=ar())";
|
|
112
|
+
const IMPEL_CLAUDE_PLAN_USAGE_GUARD = `if(!PSe()){cz();return}${"".padEnd("if(!Ge().hasOrgPolicyBackend())return;".length, " ")}if((r=ar())`;
|
|
113
|
+
const CLAUDE_DRAFT_AGENT_MENTIONS = 'agentMentionsEnabled:"draft"===Ge&&t';
|
|
114
|
+
const IMPEL_CLAUDE_BOUND_AGENT_MENTIONS = 'agentMentionsEnabled:"draft"===Ge?t:Ue?.agent??!1';
|
|
115
|
+
const CLAUDE_AGENT_MENTION_FILTER = 'return e.filter(e=>"user"===e.source&&(!n||e.name.toLowerCase().includes(n))).slice(0,10)';
|
|
116
|
+
const IMPEL_CLAUDE_BOUND_AGENT_MENTION_FILTER = 'return e.filter(e=>"user"===e.source&&(!n||e.name.toLowerCase().includes(n))&&("string"!=typeof x||e.name===x)).slice(0,10)';
|
|
120
117
|
const CLAUDE_AGENT_MENTION_SELECT = 'onSelect:t=>(e(String(t)),Promise.resolve(null))';
|
|
121
|
-
const IMPEL_CLAUDE_BOUND_AGENT_MENTION_SELECT = 'onSelect:t=>"string"==typeof
|
|
118
|
+
const IMPEL_CLAUDE_BOUND_AGENT_MENTION_SELECT = 'onSelect:t=>"string"==typeof x?Promise.resolve({chipText:String(t)}):(e(String(t)),Promise.resolve(null))';
|
|
122
119
|
const LEGACY_CLAUDE_SAFE_STORAGE_NAME = "Claude";
|
|
123
120
|
const CLAUDE_SAFE_STORAGE_METADATA = "safe-storage.json";
|
|
124
121
|
// The pinned Claude renderer decides desktop-vs-web mode SOLELY by matching its
|
|
@@ -157,7 +154,8 @@ const escapedDisplayPrefix = RUNTIME_BRAND.apps.displayPrefix.replace(/[.*+?^${}
|
|
|
157
154
|
const LEGACY_TRAPPED_CLAUDE_NAME = new RegExp(`^${escapedDisplayPrefix} Claude( \\[[^\\]]+\\])?$`, "u");
|
|
158
155
|
|
|
159
156
|
export const FALLBACK_MODELS = [
|
|
160
|
-
{ id: "claude-opus-
|
|
157
|
+
{ id: "claude-opus-5", provider: "claude", display_name: "Claude Opus 5", family: "opus", family_default: true, default: true, supports_1m: true, context_window: 1000000 },
|
|
158
|
+
{ id: "claude-opus-4-8", provider: "claude", display_name: "Claude Opus 4.8", family: "opus", supports_1m: true, context_window: 1000000 },
|
|
161
159
|
{ id: "claude-sonnet-5", provider: "claude", display_name: "Claude Sonnet 5", family: "sonnet", family_default: true, context_window: 200000 },
|
|
162
160
|
{ id: "claude-sonnet-4-6", provider: "claude", display_name: "Claude Sonnet 4.6", family: "sonnet", context_window: 200000 },
|
|
163
161
|
{ id: "claude-haiku-4-5", provider: "claude", display_name: "Claude Haiku 4.5", family: "haiku", family_default: true, context_window: 200000 },
|
|
@@ -240,7 +238,7 @@ export const CURRENT_CONFIG_VERSION = 21;
|
|
|
240
238
|
// — which is what made every `impel update` re-trigger macOS permission
|
|
241
239
|
// prompts. Bump this ONLY when a code change alters the bytes of a built
|
|
242
240
|
// bundle; leave it alone for changes that don't touch bundle contents.
|
|
243
|
-
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-07-
|
|
241
|
+
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-07-25.1";
|
|
244
242
|
|
|
245
243
|
/** Parse the tenant's install manifest, or null when absent/corrupt. */
|
|
246
244
|
export function readTenantManifest(homeDir = os.homedir(), tenantId = null) {
|
|
@@ -835,10 +833,21 @@ export function isVendableVendorApp(target, appPath) {
|
|
|
835
833
|
const hasExecutable = definition.executableNames.some((name) =>
|
|
836
834
|
fs.existsSync(path.join(appPath, "Contents", "MacOS", name)),
|
|
837
835
|
);
|
|
836
|
+
const hasClaudeSimulator = target !== "claude" || (
|
|
837
|
+
fs.existsSync(path.join(
|
|
838
|
+
appPath,
|
|
839
|
+
"Contents", "Helpers", "Claude iOS Sim.app", "Contents", "Info.plist",
|
|
840
|
+
))
|
|
841
|
+
&& fs.existsSync(path.join(
|
|
842
|
+
appPath,
|
|
843
|
+
"Contents", "Helpers", "Claude iOS Sim.app", "Contents", "MacOS", "claude-ios-sim",
|
|
844
|
+
))
|
|
845
|
+
);
|
|
838
846
|
return (
|
|
839
847
|
hasExecutable
|
|
840
848
|
&& fs.existsSync(path.join(appPath, "Contents", "Info.plist"))
|
|
841
849
|
&& fs.existsSync(path.join(appPath, "Contents", "Resources", "app.asar"))
|
|
850
|
+
&& hasClaudeSimulator
|
|
842
851
|
);
|
|
843
852
|
}
|
|
844
853
|
|
|
@@ -1022,11 +1031,7 @@ function writeClaudeConfig(paths, config, models) {
|
|
|
1022
1031
|
const experimental = crossAppModelsEnabled(config);
|
|
1023
1032
|
const claudeModels = experimental
|
|
1024
1033
|
? projectClaudeDesktopModels(models)
|
|
1025
|
-
: models.filter((model) => model.provider === "claude").map(
|
|
1026
|
-
name: model.id,
|
|
1027
|
-
...(model.family ? { anthropicFamilyTier: model.family } : {}),
|
|
1028
|
-
...(model.family_default ? { isFamilyDefault: true } : {}),
|
|
1029
|
-
}));
|
|
1034
|
+
: models.filter((model) => model.provider === "claude").map(nativeClaudeDesktopModel);
|
|
1030
1035
|
const body = {
|
|
1031
1036
|
inferenceProvider: "gateway",
|
|
1032
1037
|
inferenceGatewayBaseUrl: experimental
|
|
@@ -1061,6 +1066,28 @@ function writeClaudeConfig(paths, config, models) {
|
|
|
1061
1066
|
}, null, 2) + "\n", 0o600);
|
|
1062
1067
|
}
|
|
1063
1068
|
|
|
1069
|
+
function nativeClaudeDesktopModel(model) {
|
|
1070
|
+
const capability = model.client_capabilities?.claude_desktop;
|
|
1071
|
+
const label = typeof capability?.label === "string" && capability.label.trim()
|
|
1072
|
+
? capability.label
|
|
1073
|
+
: null;
|
|
1074
|
+
const family = typeof capability?.anthropic_family_tier === "string"
|
|
1075
|
+
&& capability.anthropic_family_tier
|
|
1076
|
+
? capability.anthropic_family_tier
|
|
1077
|
+
: model.family;
|
|
1078
|
+
return {
|
|
1079
|
+
name: model.id,
|
|
1080
|
+
...(label ? { labelOverride: label } : {}),
|
|
1081
|
+
...(family ? { anthropicFamilyTier: family } : {}),
|
|
1082
|
+
...(capability?.family_default === true || model.family_default === true
|
|
1083
|
+
? { isFamilyDefault: true }
|
|
1084
|
+
: {}),
|
|
1085
|
+
...(capability?.supports_1m === true || model.supports_1m === true
|
|
1086
|
+
? { supports1m: true }
|
|
1087
|
+
: {}),
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1064
1091
|
function writeClaudeCodeSettings(paths) {
|
|
1065
1092
|
const settingsPath = path.join(paths.claude.userData, "settings.json");
|
|
1066
1093
|
let settings = {};
|
|
@@ -1484,6 +1511,12 @@ exec "$NODE" "$CLI" token${tenantArgs}
|
|
|
1484
1511
|
|
|
1485
1512
|
function writeVendoredClaudeBundle(paths, vendorPath, gatewayUrl, safeStorageName) {
|
|
1486
1513
|
if (!vendorPath) throw new Error("Claude vendor app is unavailable");
|
|
1514
|
+
if (!isVendableVendorApp("claude", vendorPath)) {
|
|
1515
|
+
const bundleId = readBundleIdentifier(vendorPath);
|
|
1516
|
+
throw new Error(
|
|
1517
|
+
`unsupported Claude bundle layout in ${vendorPath}${bundleId ? ` (bundle id ${bundleId})` : ""}`,
|
|
1518
|
+
);
|
|
1519
|
+
}
|
|
1487
1520
|
const executableName = APP_DEFINITIONS.claude.executableNames.find((name) => (
|
|
1488
1521
|
fs.existsSync(path.join(vendorPath, "Contents", "MacOS", name))
|
|
1489
1522
|
));
|
|
@@ -1832,23 +1865,6 @@ function patchFixedWidthAsarString(asarPath, original, replacement, label) {
|
|
|
1832
1865
|
function patchClaudePlanUsageRequest(asarPath) {
|
|
1833
1866
|
const archive = fs.readFileSync(asarPath);
|
|
1834
1867
|
const source = archive.toString("latin1");
|
|
1835
|
-
const legacyPatches = [];
|
|
1836
|
-
for (
|
|
1837
|
-
let offset = source.indexOf(CLAUDE_PLAN_USAGE_REQUEST);
|
|
1838
|
-
offset !== -1;
|
|
1839
|
-
offset = source.indexOf(CLAUDE_PLAN_USAGE_REQUEST, offset + CLAUDE_PLAN_USAGE_REQUEST.length)
|
|
1840
|
-
) {
|
|
1841
|
-
legacyPatches.push({
|
|
1842
|
-
offset,
|
|
1843
|
-
original: CLAUDE_PLAN_USAGE_REQUEST,
|
|
1844
|
-
replacement: IMPEL_CLAUDE_PLAN_USAGE_REQUEST,
|
|
1845
|
-
});
|
|
1846
|
-
}
|
|
1847
|
-
if (legacyPatches.length > 0) {
|
|
1848
|
-
return applyFixedWidthAsarPatches(
|
|
1849
|
-
asarPath, archive, legacyPatches, "Claude plan-usage gateway request",
|
|
1850
|
-
);
|
|
1851
|
-
}
|
|
1852
1868
|
const credentialAccessor = source.match(
|
|
1853
1869
|
/function ([A-Za-z_$][\w$]*)\(e\)\{var t;return [\s\S]{0,500}?\[custom-3p\] Credentials loaded from managed config/u,
|
|
1854
1870
|
)?.[1];
|
|
@@ -1864,10 +1880,10 @@ function patchClaudePlanUsageRequest(asarPath) {
|
|
|
1864
1880
|
return applyFixedWidthAsarPatches(asarPath, archive, [], "Claude plan-usage gateway request");
|
|
1865
1881
|
}
|
|
1866
1882
|
|
|
1867
|
-
const requestPattern = /([A-Za-z_$][\w$]*)
|
|
1883
|
+
const requestPattern = /const ([A-Za-z_$][\w$]*)=`\$\{[A-Za-z_$][\w$]*\(\)\}\/api\/organizations\/\$\{[A-Za-z_$][\w$]*\}\/usage\$\{[A-Za-z_$][\w$]*\?"\?skip_spend=1":""\}`,([A-Za-z_$][\w$]*)=await ([A-Za-z_$][\w$]*)\.net\.fetch\(\1,\{signal:AbortSignal\.timeout\([A-Za-z_$][\w$]*\)\}\)/gu;
|
|
1868
1884
|
const patches = [...source.matchAll(requestPattern)].map((match) => {
|
|
1869
1885
|
const original = match[0];
|
|
1870
|
-
const replacement =
|
|
1886
|
+
const replacement = `const ${match[1]}="https://gateway.useimpel.com/ui/a/u",${match[2]}=await ${match[3]}.net.fetch(${match[1]},{headers:{key:${credentialAccessor}(${configAccessor}()).apiKey}})`;
|
|
1871
1887
|
if (replacement.length > original.length) {
|
|
1872
1888
|
throw new Error("Claude plan-usage gateway request replacement no longer fits the vendor ASAR contract");
|
|
1873
1889
|
}
|
package/src/commands/doctor.js
CHANGED
package/src/commands/sessions.js
CHANGED
|
@@ -21,7 +21,7 @@ import { brandedEnvironmentName, RUNTIME_BRAND } from "../runtimeBrand.js";
|
|
|
21
21
|
const MANAGED_SESSION_HOOK_FLAG = `${RUNTIME_BRAND.cli.command}-managed-session-hook-v1`;
|
|
22
22
|
|
|
23
23
|
function environmentValue(suffix) {
|
|
24
|
-
return process.env[brandedEnvironmentName(suffix)]
|
|
24
|
+
return process.env[brandedEnvironmentName(suffix)];
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const SPEC = {
|
|
@@ -12,7 +12,12 @@ import { tenantCredential } from "../tenants.js";
|
|
|
12
12
|
export const DEFAULT_RECOVERY_ORG = "impel";
|
|
13
13
|
const REQUEST_TIMEOUT_MS = 90_000;
|
|
14
14
|
const MAX_RETRIES = 2;
|
|
15
|
-
const FALLBACK_MODELS = [
|
|
15
|
+
const FALLBACK_MODELS = [
|
|
16
|
+
"claude-sonnet-5",
|
|
17
|
+
"claude-haiku-4-5",
|
|
18
|
+
"claude-opus-5",
|
|
19
|
+
"claude-opus-4-8",
|
|
20
|
+
];
|
|
16
21
|
|
|
17
22
|
function recoveryOrgCandidates(config, environment) {
|
|
18
23
|
const preferred = String(environment.IMPEL_RECOVERY_ORG || DEFAULT_RECOVERY_ORG).trim();
|
package/src/sessionCollector.js
CHANGED
|
@@ -24,9 +24,7 @@ const SAFE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u;
|
|
|
24
24
|
const TASK_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
25
25
|
|
|
26
26
|
function brandedEnvironmentValue(suffix) {
|
|
27
|
-
|
|
28
|
-
if (branded !== undefined) return branded;
|
|
29
|
-
return process.env[`IMPEL_${suffix}`];
|
|
27
|
+
return process.env[brandedEnvironmentName(suffix)];
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
function stateRoot() {
|
|
@@ -509,7 +507,7 @@ function repositoryMetadata(cwd) {
|
|
|
509
507
|
};
|
|
510
508
|
}
|
|
511
509
|
|
|
512
|
-
function
|
|
510
|
+
export function resolveSessionsUrl(config) {
|
|
513
511
|
return String(
|
|
514
512
|
brandedEnvironmentValue("SESSIONS_URL")
|
|
515
513
|
|| config?.sessionsUrl
|
|
@@ -545,7 +543,7 @@ async function apiRequest(config, tenantId, route, options = {}) {
|
|
|
545
543
|
const controller = new AbortController();
|
|
546
544
|
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
547
545
|
try {
|
|
548
|
-
const response = await fetch(`${
|
|
546
|
+
const response = await fetch(`${resolveSessionsUrl(config)}${route}`, {
|
|
549
547
|
...options,
|
|
550
548
|
headers: requestHeaders(config, tenantId, options.headers),
|
|
551
549
|
signal: controller.signal,
|