impel-cli 0.18.16 → 0.18.17
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 +108 -1
package/package.json
CHANGED
package/src/apps.js
CHANGED
|
@@ -130,6 +130,10 @@ const MAX_REASONING_LEVEL = { effort: "max", description: "Maximum reasoning dep
|
|
|
130
130
|
const ULTRA_REASONING_LEVEL = { effort: "ultra", description: "Maximum reasoning with automatic task delegation" };
|
|
131
131
|
const FAST_SERVICE_TIER = { id: "priority", name: "Fast", description: "1.5x speed, increased usage" };
|
|
132
132
|
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;
|
|
133
|
+
const CHATGPT_THREAD_START_PROVIDER = /serviceName:([A-Za-z_$][\w$]*)\.serviceName\?\?this\.options\.defaultServiceName,threadSource:\1\.threadSource===void 0\?`user`:\1\.threadSource/gu;
|
|
134
|
+
const CHATGPT_THREAD_FORK_PROVIDER = /let ([A-Za-z_$][\w$]*)=\{\.\.\.([A-Za-z_$][\w$]*),threadSource:\2\.threadSource===void 0\?`user`:\2\.threadSource\}/gu;
|
|
135
|
+
const CHATGPT_THREAD_RESUME_PROVIDER = /modelProvider:null,cwd:([A-Za-z_$][\w$]*)\?\.cwd\?\?null,approvalPolicy:null,sandbox:null,config:\1\?\.config\?\?null,developerInstructions:\1\?\.developerInstructions\?\?void 0/gu;
|
|
136
|
+
const CHATGPT_STRUCTURED_PROVIDER_FALLBACK = /allowProviderModelFallback:!0/gu;
|
|
133
137
|
const CHATGPT_RESOURCE_ROOT = "linked_vendor_resources_with_patched_asar";
|
|
134
138
|
const CLAUDE_PLAN_USAGE_GUARD = "if(!PSe()){cz();return}if(!Ge().hasOrgPolicyBackend())return;if((r=ar())";
|
|
135
139
|
const IMPEL_CLAUDE_PLAN_USAGE_GUARD = `if(!PSe()){cz();return}${"".padEnd("if(!Ge().hasOrgPolicyBackend())return;".length, " ")}if((r=ar())`;
|
|
@@ -271,7 +275,7 @@ export const CURRENT_CONFIG_VERSION = 26;
|
|
|
271
275
|
// — which is what made every `impel update` re-trigger macOS permission
|
|
272
276
|
// prompts. Bump this ONLY when a code change alters the bytes of a built
|
|
273
277
|
// bundle; leave it alone for changes that don't touch bundle contents.
|
|
274
|
-
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-
|
|
278
|
+
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-08-01.1";
|
|
275
279
|
|
|
276
280
|
/** Parse the tenant's install manifest, or null when absent/corrupt. */
|
|
277
281
|
export function readTenantManifest(homeDir = os.homedir(), tenantId = null) {
|
|
@@ -349,6 +353,10 @@ export function bundleIsCurrent(status, {
|
|
|
349
353
|
compatibility.vendorSignaturesPreserved === true
|
|
350
354
|
&& compatibility.resourceRoot === CHATGPT_RESOURCE_ROOT
|
|
351
355
|
&& compatibility.patches?.fastModeForGatewayAuth > 0
|
|
356
|
+
&& compatibility.patches?.threadStartProviderOverride === 1
|
|
357
|
+
&& compatibility.patches?.threadForkProviderOverride === 1
|
|
358
|
+
&& compatibility.patches?.threadResumeProviderOverride === 1
|
|
359
|
+
&& compatibility.patches?.structuredProviderFallbackDisabled === 2
|
|
352
360
|
&& compatibility.patches?.tenantDisplayNamePreload === 2
|
|
353
361
|
)),
|
|
354
362
|
);
|
|
@@ -1729,6 +1737,8 @@ function writeVendoredChatGPTBundleLocked(paths, vendorPath, gatewayUrl, homeDir
|
|
|
1729
1737
|
linkVendoredChatGPTResources(staging, vendorBundleName);
|
|
1730
1738
|
const runtimeAsarPath = path.join(staging, "Contents", "Resources", "app.asar");
|
|
1731
1739
|
const fastModePatchCount = patchFastModeAuthGate(runtimeAsarPath);
|
|
1740
|
+
const threadProviderPatches = patchChatGPTThreadRouting(runtimeAsarPath);
|
|
1741
|
+
const structuredFallbackPatchCount = patchChatGPTStructuredProviderFallback(runtimeAsarPath);
|
|
1732
1742
|
const asarHash = asarHeaderHash(runtimeAsarPath);
|
|
1733
1743
|
const vendorExecutable = path.join(vendorBundle, "Contents", "MacOS", executableName);
|
|
1734
1744
|
const signingIdentity = resolveVendoredAppSigningIdentity(vendorExecutable);
|
|
@@ -1773,6 +1783,10 @@ function writeVendoredChatGPTBundleLocked(paths, vendorPath, gatewayUrl, homeDir
|
|
|
1773
1783
|
browserData: paths.chatgpt.browserData,
|
|
1774
1784
|
patches: {
|
|
1775
1785
|
fastModeForGatewayAuth: fastModePatchCount,
|
|
1786
|
+
threadStartProviderOverride: threadProviderPatches.start,
|
|
1787
|
+
threadForkProviderOverride: threadProviderPatches.fork,
|
|
1788
|
+
threadResumeProviderOverride: threadProviderPatches.resume,
|
|
1789
|
+
structuredProviderFallbackDisabled: structuredFallbackPatchCount,
|
|
1776
1790
|
desktopAPIForGatewayAuth: 0,
|
|
1777
1791
|
tenantDisplayNamePreload: 2,
|
|
1778
1792
|
},
|
|
@@ -1995,6 +2009,99 @@ function patchFastModeAuthGate(asarPath) {
|
|
|
1995
2009
|
return applyFixedWidthAsarPatches(asarPath, archive, patches, "ChatGPT/Codex Fast-mode eligibility contract");
|
|
1996
2010
|
}
|
|
1997
2011
|
|
|
2012
|
+
/**
|
|
2013
|
+
* Force every desktop app-server thread request onto the tenant's configured
|
|
2014
|
+
* Impel provider. The pinned renderer passes null for internal metadata turns,
|
|
2015
|
+
* which otherwise lets those turns escape to native OpenAI authentication.
|
|
2016
|
+
*/
|
|
2017
|
+
function patchChatGPTThreadRouting(asarPath) {
|
|
2018
|
+
const archive = fs.readFileSync(asarPath);
|
|
2019
|
+
const source = archive.toString("latin1");
|
|
2020
|
+
const provider = JSON.stringify(RUNTIME_BRAND.cli.providerId);
|
|
2021
|
+
const contracts = [
|
|
2022
|
+
{
|
|
2023
|
+
name: "start",
|
|
2024
|
+
pattern: CHATGPT_THREAD_START_PROVIDER,
|
|
2025
|
+
replacement: (match) => (
|
|
2026
|
+
`modelProvider:${provider},serviceName:${match[1]}.serviceName??this.options.defaultServiceName,`
|
|
2027
|
+
+ `threadSource:${match[1]}.threadSource??\`user\``
|
|
2028
|
+
),
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
name: "fork",
|
|
2032
|
+
pattern: CHATGPT_THREAD_FORK_PROVIDER,
|
|
2033
|
+
replacement: (match) => (
|
|
2034
|
+
`let ${match[1]}={...${match[2]},modelProvider:${provider},`
|
|
2035
|
+
+ `threadSource:${match[2]}.threadSource??\`user\`}`
|
|
2036
|
+
),
|
|
2037
|
+
},
|
|
2038
|
+
{
|
|
2039
|
+
name: "resume",
|
|
2040
|
+
pattern: CHATGPT_THREAD_RESUME_PROVIDER,
|
|
2041
|
+
replacement: (match) => (
|
|
2042
|
+
`modelProvider:${provider},cwd:${match[1]}?.cwd??null,approvalPolicy:null,sandbox:null,`
|
|
2043
|
+
+ `config:${match[1]}?.config??null,developerInstructions:${match[1]}?.developerInstructions`
|
|
2044
|
+
),
|
|
2045
|
+
},
|
|
2046
|
+
];
|
|
2047
|
+
const counts = {};
|
|
2048
|
+
const patches = [];
|
|
2049
|
+
for (const contract of contracts) {
|
|
2050
|
+
const matches = [...source.matchAll(contract.pattern)];
|
|
2051
|
+
if (matches.length !== 1) {
|
|
2052
|
+
throw new Error(
|
|
2053
|
+
`ChatGPT/Codex thread-${contract.name} provider patch expected 1 match, found ${matches.length}`,
|
|
2054
|
+
);
|
|
2055
|
+
}
|
|
2056
|
+
const match = matches[0];
|
|
2057
|
+
const replacement = contract.replacement(match);
|
|
2058
|
+
if (replacement.length > match[0].length) {
|
|
2059
|
+
throw new Error(
|
|
2060
|
+
`ChatGPT/Codex thread-${contract.name} provider replacement no longer fits the vendor ASAR contract`,
|
|
2061
|
+
);
|
|
2062
|
+
}
|
|
2063
|
+
patches.push({
|
|
2064
|
+
offset: match.index,
|
|
2065
|
+
original: match[0],
|
|
2066
|
+
replacement: replacement.padEnd(match[0].length, " "),
|
|
2067
|
+
});
|
|
2068
|
+
counts[contract.name] = 1;
|
|
2069
|
+
}
|
|
2070
|
+
applyFixedWidthAsarPatches(
|
|
2071
|
+
asarPath,
|
|
2072
|
+
archive,
|
|
2073
|
+
patches,
|
|
2074
|
+
"ChatGPT/Codex thread-provider routing contract",
|
|
2075
|
+
);
|
|
2076
|
+
return counts;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
/**
|
|
2080
|
+
* Structured title, description, and classification turns opt into falling
|
|
2081
|
+
* back to another provider in the pinned renderer. Keep those turns fail
|
|
2082
|
+
* closed on Impel by changing the two reviewed boolean literals in place.
|
|
2083
|
+
*/
|
|
2084
|
+
function patchChatGPTStructuredProviderFallback(asarPath) {
|
|
2085
|
+
const archive = fs.readFileSync(asarPath);
|
|
2086
|
+
const source = archive.toString("latin1");
|
|
2087
|
+
const matches = [...source.matchAll(CHATGPT_STRUCTURED_PROVIDER_FALLBACK)];
|
|
2088
|
+
if (matches.length !== 2) {
|
|
2089
|
+
throw new Error(
|
|
2090
|
+
`ChatGPT/Codex structured provider-fallback patch expected 2 matches, found ${matches.length}`,
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
2093
|
+
return applyFixedWidthAsarPatches(
|
|
2094
|
+
asarPath,
|
|
2095
|
+
archive,
|
|
2096
|
+
matches.map((match) => ({
|
|
2097
|
+
offset: match.index,
|
|
2098
|
+
original: match[0],
|
|
2099
|
+
replacement: "allowProviderModelFallback:!1",
|
|
2100
|
+
})),
|
|
2101
|
+
"ChatGPT/Codex structured provider-fallback contract",
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
|
|
1998
2105
|
function applyFixedWidthAsarPatches(asarPath, archive, patches, label) {
|
|
1999
2106
|
if (patches.length === 0) {
|
|
2000
2107
|
throw new Error(`this desktop app version has an unsupported ${label}; update impel-cli before installing it`);
|