Skip to content

Commit 60b7c5d

Browse files
committed
fix(ai): prevent UI flicker on entitlement refresh and enforce absolute paths
Track current entitlement state so _checkEntitlementAndInit skips re-rendering when the state hasn't changed (e.g. background token refresh). Also add system prompt instruction to always use full absolute paths for file operations.
1 parent 27b39f5 commit 60b7c5d

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

src-node/claude-code-agent.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ async function _runQuery(requestId, prompt, projectPath, model, signal, locale,
363363
"multiple Edit calls to make targeted changes rather than rewriting the entire " +
364364
"file with Write. This is critical because Write replaces the entire file content " +
365365
"which is slow and loses undo history." +
366+
"\n\nAlways use full absolute paths for all file operations (Read, Edit, Write, " +
367+
"controlEditor). Never use relative paths." +
366368
"\n\nWhen a tool response mentions the user has typed a clarification, immediately " +
367369
"call getUserClarification to read it and incorporate the user's feedback into your current work." +
368370
(locale && !locale.startsWith("en")

src/core-ai/AIChatPanel.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ define(function (require, exports, module) {
4545
const _KernalModeTrust = window.KernalModeTrust;
4646

4747
let _nodeConnector = null;
48+
let _currentEntitlementState = null; // "chat" | "login" | "upsell" | "adminDisabled" | null
4849
let _isStreaming = false;
4950
let _queuedMessage = null; // text queued by user while AI is streaming
5051
let _currentRequestId = null;
@@ -240,15 +241,20 @@ define(function (require, exports, module) {
240241
* upsell screen if no AI plan, or proceeds to CLI availability check if entitled.
241242
*/
242243
function _checkEntitlementAndInit() {
243-
_removeCurrentPanel();
244244
const EntitlementsManager = _KernalModeTrust && _KernalModeTrust.EntitlementsManager;
245245
if (!EntitlementsManager) {
246246
// No entitlement system (test env or dev) — skip straight to CLI check
247-
_checkAvailability();
247+
if (_currentEntitlementState !== "chat") {
248+
_removeCurrentPanel();
249+
_checkAvailability();
250+
}
248251
return;
249252
}
250253
if (!EntitlementsManager.isLoggedIn()) {
251-
_renderLoginUI();
254+
if (_currentEntitlementState !== "login") {
255+
_removeCurrentPanel();
256+
_renderLoginUI();
257+
}
252258
return;
253259
}
254260
// TODO: Switch to EntitlementsManager.getAIEntitlement() once AI entitlement is
@@ -267,19 +273,29 @@ define(function (require, exports, module) {
267273
// });
268274
EntitlementsManager.getLiveEditEntitlement().then(function (entitlement) {
269275
if (entitlement.activated) {
270-
_checkAvailability();
276+
if (_currentEntitlementState !== "chat") {
277+
_removeCurrentPanel();
278+
_checkAvailability();
279+
}
271280
} else {
272-
_renderUpsellUI(entitlement);
281+
if (_currentEntitlementState !== "upsell") {
282+
_removeCurrentPanel();
283+
_renderUpsellUI(entitlement);
284+
}
273285
}
274286
}).catch(function () {
275-
_checkAvailability(); // fallback on error
287+
if (_currentEntitlementState !== "chat") {
288+
_removeCurrentPanel();
289+
_checkAvailability(); // fallback on error
290+
}
276291
});
277292
}
278293

279294
/**
280295
* Render the login prompt UI (user not signed in).
281296
*/
282297
function _renderLoginUI() {
298+
_currentEntitlementState = "login";
283299
const html =
284300
'<div class="ai-chat-panel">' +
285301
'<div class="ai-unavailable">' +
@@ -302,6 +318,7 @@ define(function (require, exports, module) {
302318
* Render the upsell UI (user logged in but no AI plan).
303319
*/
304320
function _renderUpsellUI(entitlement) {
321+
_currentEntitlementState = "upsell";
305322
const html =
306323
'<div class="ai-chat-panel">' +
307324
'<div class="ai-unavailable">' +
@@ -325,6 +342,7 @@ define(function (require, exports, module) {
325342
* Render the admin-disabled UI (AI turned off by system administrator).
326343
*/
327344
function _renderAdminDisabledUI() {
345+
_currentEntitlementState = "adminDisabled";
328346
const html =
329347
'<div class="ai-chat-panel">' +
330348
'<div class="ai-unavailable">' +
@@ -359,6 +377,7 @@ define(function (require, exports, module) {
359377
* Render the full chat UI.
360378
*/
361379
function _renderChatUI() {
380+
_currentEntitlementState = "chat";
362381
$panel = $(PANEL_HTML);
363382
$messages = $panel.find(".ai-chat-messages");
364383
$status = $panel.find(".ai-chat-status");
@@ -567,6 +586,7 @@ define(function (require, exports, module) {
567586
* Render the unavailable UI (CLI not found).
568587
*/
569588
function _renderUnavailableUI(error) {
589+
_currentEntitlementState = "chat";
570590
const $unavailable = $(UNAVAILABLE_HTML);
571591
$unavailable.find(".ai-retry-btn").on("click", function () {
572592
_checkAvailability();

0 commit comments

Comments
 (0)