impel-cli 0.17.4 → 0.17.5
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 +83 -29
package/package.json
CHANGED
package/src/apps.js
CHANGED
|
@@ -93,6 +93,14 @@ const CLAUDE_AGENT_MENTION_FILTER = 'return e.filter(e=>"user"===e.source&&(!s||
|
|
|
93
93
|
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)';
|
|
94
94
|
const CLAUDE_AGENT_MENTION_SELECT = 'onSelect:t=>(e(String(t)),Promise.resolve(null))';
|
|
95
95
|
const IMPEL_CLAUDE_BOUND_AGENT_MENTION_SELECT = 'onSelect:t=>"string"==typeof y?Promise.resolve({chipText:String(t)}):(e(String(t)),Promise.resolve(null))';
|
|
96
|
+
// Claude's Code-disabled screens link Back to "/", but the root router honors
|
|
97
|
+
// its separately persisted last Code mode and immediately returns to the same
|
|
98
|
+
// disabled screen. Route directly to the pinned build's canonical Chat page;
|
|
99
|
+
// its normal mode effect then reconciles both renderer and desktop preference.
|
|
100
|
+
const CLAUDE_CODE_DISABLED_BACK_LINK = 'function Fi(){return e.jsxs("a",{href:"/",className:"inline-flex items-center text-sm text-text-400 hover:text-text-300 outline-none"';
|
|
101
|
+
const IMPEL_CLAUDE_CODE_DISABLED_BACK_LINK = 'function Fi(){return e.jsxs("a",{href:"/chat/new",className:"inline-flex items-center text-sm text-text-400 hover:text-text-300 outline-none"';
|
|
102
|
+
const CLAUDE_CODE_NO_SEAT_BACK_LINK = 'b.jsx(D,{variant:"ghost",href:"/",icon:"ArrowLeft",children:b.jsx(A,{defaultMessage:"Back to Claude",id:"e4M0bJ/pZc"})})';
|
|
103
|
+
const IMPEL_CLAUDE_CODE_NO_SEAT_BACK_LINK = 'b.jsx(D,{variant:"ghost",href:"/chat/new",icon:"ArrowLeft",children:b.jsx(A,{defaultMessage:"Back to Claude",id:"e4M0bJ/pZc"})})';
|
|
96
104
|
const LEGACY_CLAUDE_SAFE_STORAGE_NAME = "Claude";
|
|
97
105
|
const CLAUDE_SAFE_STORAGE_METADATA = "safe-storage.json";
|
|
98
106
|
|
|
@@ -174,7 +182,7 @@ export const CURRENT_CONFIG_VERSION = 16;
|
|
|
174
182
|
// — which is what made every `impel update` re-trigger macOS permission
|
|
175
183
|
// prompts. Bump this ONLY when a code change alters the bytes of a built
|
|
176
184
|
// bundle; leave it alone for changes that don't touch bundle contents.
|
|
177
|
-
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-07-20.
|
|
185
|
+
export const BUNDLE_BUILD_FINGERPRINT = "bundle-2026-07-20.2";
|
|
178
186
|
|
|
179
187
|
/** Parse the tenant's install manifest, or null when absent/corrupt. */
|
|
180
188
|
export function readTenantManifest(homeDir = os.homedir(), tenantId = null) {
|
|
@@ -245,6 +253,8 @@ export function bundleIsCurrent(status, {
|
|
|
245
253
|
compatibility.patches?.followupBoundAgentEnable === 1
|
|
246
254
|
&& compatibility.patches?.followupBoundAgentFilter === 1
|
|
247
255
|
&& compatibility.patches?.followupBoundAgentChip === 1
|
|
256
|
+
&& compatibility.patches?.codeDisabledBack === 1
|
|
257
|
+
&& compatibility.patches?.codeNoSeatBack === 1
|
|
248
258
|
&& managedClaudeRendererMatchesCompatibility(status, compatibility)
|
|
249
259
|
))
|
|
250
260
|
&& (status.target !== "chatgpt" || (
|
|
@@ -280,8 +290,12 @@ function wrapperLaunchesOnTahoe(status) {
|
|
|
280
290
|
|
|
281
291
|
function managedClaudeRendererMatchesCompatibility(status, compatibility) {
|
|
282
292
|
try {
|
|
283
|
-
const
|
|
284
|
-
|
|
293
|
+
const groups = [
|
|
294
|
+
compatibility.rendererAssets?.agentMentions,
|
|
295
|
+
compatibility.rendererAssets?.codeDisabledBack,
|
|
296
|
+
];
|
|
297
|
+
if (groups.some((renderers) => !Array.isArray(renderers) || renderers.length === 0)) return false;
|
|
298
|
+
const renderers = groups.flat();
|
|
285
299
|
const root = path.resolve(status.launcher, "Contents", "Resources", "ion-dist");
|
|
286
300
|
return renderers.every((renderer) => {
|
|
287
301
|
if (!renderer?.path || !renderer.sha256 || path.isAbsolute(renderer.path)) return false;
|
|
@@ -1365,6 +1379,7 @@ function writeVendoredClaudeBundle(paths, vendorPath, gatewayUrl, safeStorageNam
|
|
|
1365
1379
|
}
|
|
1366
1380
|
|
|
1367
1381
|
const agentMentionPatches = patchClaudeFollowupAgentMentions(staging);
|
|
1382
|
+
const codeDisabledBackPatches = patchClaudeCodeDisabledBackRouting(staging);
|
|
1368
1383
|
const oldAsarHash = asarHeaderHash(asarPath);
|
|
1369
1384
|
let planUsageGuardPatchCount = 0;
|
|
1370
1385
|
let planUsageRequestPatchCount = 0;
|
|
@@ -1407,7 +1422,7 @@ function writeVendoredClaudeBundle(paths, vendorPath, gatewayUrl, safeStorageNam
|
|
|
1407
1422
|
const vendorExecutable = path.join(macos, executableName);
|
|
1408
1423
|
const signingIdentity = resolveVendoredAppSigningIdentity(vendorExecutable);
|
|
1409
1424
|
writeAtomic(path.join(staging, "Contents", "Resources", "impel-compatibility.json"), JSON.stringify({
|
|
1410
|
-
schemaVersion:
|
|
1425
|
+
schemaVersion: 6,
|
|
1411
1426
|
cliVersion: CLI_VERSION,
|
|
1412
1427
|
bundleFingerprint: BUNDLE_BUILD_FINGERPRINT,
|
|
1413
1428
|
signingMode: signingModeForIdentity(signingIdentity),
|
|
@@ -1426,9 +1441,12 @@ function writeVendoredClaudeBundle(paths, vendorPath, gatewayUrl, safeStorageNam
|
|
|
1426
1441
|
followupBoundAgentEnable: agentMentionPatches.enable,
|
|
1427
1442
|
followupBoundAgentFilter: agentMentionPatches.filter,
|
|
1428
1443
|
followupBoundAgentChip: agentMentionPatches.chip,
|
|
1444
|
+
codeDisabledBack: codeDisabledBackPatches.disabled,
|
|
1445
|
+
codeNoSeatBack: codeDisabledBackPatches.noSeat,
|
|
1429
1446
|
},
|
|
1430
1447
|
rendererAssets: {
|
|
1431
1448
|
agentMentions: agentMentionPatches.assets,
|
|
1449
|
+
codeDisabledBack: codeDisabledBackPatches.assets,
|
|
1432
1450
|
},
|
|
1433
1451
|
asarHeaderSha256: newAsarHash,
|
|
1434
1452
|
}, null, 2) + "\n", 0o644);
|
|
@@ -1565,31 +1583,72 @@ function linkVendoredChatGPTResources(bundle, vendorBundleName) {
|
|
|
1565
1583
|
}
|
|
1566
1584
|
|
|
1567
1585
|
function patchClaudeFollowupAgentMentions(bundle) {
|
|
1586
|
+
const assets = patchClaudeRendererContracts(bundle, {
|
|
1587
|
+
supportLabel: "follow-up agent mentions",
|
|
1588
|
+
patchLabel: "follow-up agent-mention",
|
|
1589
|
+
contracts: [
|
|
1590
|
+
{
|
|
1591
|
+
key: "enable",
|
|
1592
|
+
original: CLAUDE_DRAFT_AGENT_MENTIONS,
|
|
1593
|
+
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTIONS,
|
|
1594
|
+
},
|
|
1595
|
+
{
|
|
1596
|
+
key: "filter",
|
|
1597
|
+
original: CLAUDE_AGENT_MENTION_FILTER,
|
|
1598
|
+
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTION_FILTER,
|
|
1599
|
+
},
|
|
1600
|
+
{
|
|
1601
|
+
key: "chip",
|
|
1602
|
+
original: CLAUDE_AGENT_MENTION_SELECT,
|
|
1603
|
+
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTION_SELECT,
|
|
1604
|
+
},
|
|
1605
|
+
],
|
|
1606
|
+
});
|
|
1607
|
+
return {
|
|
1608
|
+
enable: 1,
|
|
1609
|
+
filter: 1,
|
|
1610
|
+
chip: 1,
|
|
1611
|
+
assets,
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
function patchClaudeCodeDisabledBackRouting(bundle) {
|
|
1616
|
+
const assets = patchClaudeRendererContracts(bundle, {
|
|
1617
|
+
supportLabel: "Code-disabled Back routing",
|
|
1618
|
+
patchLabel: "Code-disabled Back routing",
|
|
1619
|
+
contracts: [
|
|
1620
|
+
{
|
|
1621
|
+
key: "disabled",
|
|
1622
|
+
original: CLAUDE_CODE_DISABLED_BACK_LINK,
|
|
1623
|
+
replacement: IMPEL_CLAUDE_CODE_DISABLED_BACK_LINK,
|
|
1624
|
+
},
|
|
1625
|
+
{
|
|
1626
|
+
key: "noSeat",
|
|
1627
|
+
original: CLAUDE_CODE_NO_SEAT_BACK_LINK,
|
|
1628
|
+
replacement: IMPEL_CLAUDE_CODE_NO_SEAT_BACK_LINK,
|
|
1629
|
+
},
|
|
1630
|
+
],
|
|
1631
|
+
});
|
|
1632
|
+
return {
|
|
1633
|
+
disabled: 1,
|
|
1634
|
+
noSeat: 1,
|
|
1635
|
+
assets,
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
function patchClaudeRendererContracts(bundle, {
|
|
1640
|
+
supportLabel,
|
|
1641
|
+
patchLabel,
|
|
1642
|
+
contracts,
|
|
1643
|
+
}) {
|
|
1568
1644
|
const version = bundleVersion(bundle);
|
|
1569
1645
|
if (version !== PINNED_VENDOR_APPS.claude.version) {
|
|
1570
1646
|
throw new Error(
|
|
1571
|
-
`Claude
|
|
1647
|
+
`Claude ${supportLabel} support is pinned to ${PINNED_VENDOR_APPS.claude.version}; found ${version || "unknown"}`,
|
|
1572
1648
|
);
|
|
1573
1649
|
}
|
|
1574
1650
|
|
|
1575
1651
|
const ionDist = path.join(bundle, "Contents", "Resources", "ion-dist");
|
|
1576
|
-
const contracts = [
|
|
1577
|
-
{
|
|
1578
|
-
key: "enable",
|
|
1579
|
-
original: CLAUDE_DRAFT_AGENT_MENTIONS,
|
|
1580
|
-
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTIONS,
|
|
1581
|
-
},
|
|
1582
|
-
{
|
|
1583
|
-
key: "filter",
|
|
1584
|
-
original: CLAUDE_AGENT_MENTION_FILTER,
|
|
1585
|
-
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTION_FILTER,
|
|
1586
|
-
},
|
|
1587
|
-
{
|
|
1588
|
-
key: "chip",
|
|
1589
|
-
original: CLAUDE_AGENT_MENTION_SELECT,
|
|
1590
|
-
replacement: IMPEL_CLAUDE_BOUND_AGENT_MENTION_SELECT,
|
|
1591
|
-
},
|
|
1592
|
-
];
|
|
1593
1652
|
const sources = new Map(listJavaScriptFiles(ionDist).map((candidate) => [
|
|
1594
1653
|
candidate,
|
|
1595
1654
|
fs.readFileSync(candidate, "utf8"),
|
|
@@ -1604,7 +1663,7 @@ function patchClaudeFollowupAgentMentions(bundle) {
|
|
|
1604
1663
|
for (const contract of contracts) {
|
|
1605
1664
|
const count = matches.get(contract.key).reduce((total, match) => total + match.count, 0);
|
|
1606
1665
|
if (count !== 1) {
|
|
1607
|
-
throw new Error(`Claude
|
|
1666
|
+
throw new Error(`Claude ${patchLabel} ${contract.key} patch expected 1 match, found ${count}`);
|
|
1608
1667
|
}
|
|
1609
1668
|
}
|
|
1610
1669
|
|
|
@@ -1626,12 +1685,7 @@ function patchClaudeFollowupAgentMentions(bundle) {
|
|
|
1626
1685
|
});
|
|
1627
1686
|
}
|
|
1628
1687
|
|
|
1629
|
-
return
|
|
1630
|
-
enable: 1,
|
|
1631
|
-
filter: 1,
|
|
1632
|
-
chip: 1,
|
|
1633
|
-
assets,
|
|
1634
|
-
};
|
|
1688
|
+
return assets;
|
|
1635
1689
|
}
|
|
1636
1690
|
|
|
1637
1691
|
function listJavaScriptFiles(root) {
|