init claude-code
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { feature } from 'bun:bundle'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useNotifications } from 'src/context/notifications.js'
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js'
|
||||
import { useAppState } from '../../state/AppState.js'
|
||||
import type { PermissionMode } from '../../utils/permissions/PermissionMode.js'
|
||||
import {
|
||||
getAutoModeUnavailableNotification,
|
||||
getAutoModeUnavailableReason,
|
||||
} from '../../utils/permissions/permissionSetup.js'
|
||||
import { hasAutoModeOptIn } from '../../utils/settings/settings.js'
|
||||
|
||||
/**
|
||||
* Shows a one-shot notification when the shift-tab carousel wraps past where
|
||||
* auto mode would have been. Covers all reasons (settings, circuit-breaker,
|
||||
* org-allowlist). The startup case (defaultMode: auto silently downgraded) is
|
||||
* handled by verifyAutoModeGateAccess → checkAndDisableAutoModeIfNeeded.
|
||||
*/
|
||||
export function useAutoModeUnavailableNotification(): void {
|
||||
const { addNotification } = useNotifications()
|
||||
const mode = useAppState(s => s.toolPermissionContext.mode)
|
||||
const isAutoModeAvailable = useAppState(
|
||||
s => s.toolPermissionContext.isAutoModeAvailable,
|
||||
)
|
||||
const shownRef = useRef(false)
|
||||
const prevModeRef = useRef<PermissionMode>(mode)
|
||||
|
||||
useEffect(() => {
|
||||
const prevMode = prevModeRef.current
|
||||
prevModeRef.current = mode
|
||||
|
||||
if (!feature('TRANSCRIPT_CLASSIFIER')) return
|
||||
if (getIsRemoteMode()) return
|
||||
if (shownRef.current) return
|
||||
|
||||
const wrappedPastAutoSlot =
|
||||
mode === 'default' &&
|
||||
prevMode !== 'default' &&
|
||||
prevMode !== 'auto' &&
|
||||
!isAutoModeAvailable &&
|
||||
hasAutoModeOptIn()
|
||||
|
||||
if (!wrappedPastAutoSlot) return
|
||||
|
||||
const reason = getAutoModeUnavailableReason()
|
||||
if (!reason) return
|
||||
|
||||
shownRef.current = true
|
||||
addNotification({
|
||||
key: 'auto-mode-unavailable',
|
||||
text: getAutoModeUnavailableNotification(reason),
|
||||
color: 'warning',
|
||||
priority: 'medium',
|
||||
})
|
||||
}, [mode, isAutoModeAvailable, addNotification])
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,44 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useNotifications } from 'src/context/notifications.js';
|
||||
import { getModelDeprecationWarning } from 'src/utils/model/deprecation.js';
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js';
|
||||
export function useDeprecationWarningNotification(model) {
|
||||
const $ = _c(4);
|
||||
const {
|
||||
addNotification
|
||||
} = useNotifications();
|
||||
const lastWarningRef = useRef(null);
|
||||
let t0;
|
||||
let t1;
|
||||
if ($[0] !== addNotification || $[1] !== model) {
|
||||
t0 = () => {
|
||||
if (getIsRemoteMode()) {
|
||||
return;
|
||||
}
|
||||
const deprecationWarning = getModelDeprecationWarning(model);
|
||||
if (deprecationWarning && deprecationWarning !== lastWarningRef.current) {
|
||||
lastWarningRef.current = deprecationWarning;
|
||||
addNotification({
|
||||
key: "model-deprecation-warning",
|
||||
text: deprecationWarning,
|
||||
color: "warning",
|
||||
priority: "high"
|
||||
});
|
||||
}
|
||||
if (!deprecationWarning) {
|
||||
lastWarningRef.current = null;
|
||||
}
|
||||
};
|
||||
t1 = [model, addNotification];
|
||||
$[0] = addNotification;
|
||||
$[1] = model;
|
||||
$[2] = t0;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
t1 = $[3];
|
||||
}
|
||||
useEffect(t0, t1);
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VFZmZlY3QiLCJ1c2VSZWYiLCJ1c2VOb3RpZmljYXRpb25zIiwiZ2V0TW9kZWxEZXByZWNhdGlvbldhcm5pbmciLCJnZXRJc1JlbW90ZU1vZGUiLCJ1c2VEZXByZWNhdGlvbldhcm5pbmdOb3RpZmljYXRpb24iLCJtb2RlbCIsIiQiLCJfYyIsImFkZE5vdGlmaWNhdGlvbiIsImxhc3RXYXJuaW5nUmVmIiwidDAiLCJ0MSIsImRlcHJlY2F0aW9uV2FybmluZyIsImN1cnJlbnQiLCJrZXkiLCJ0ZXh0IiwiY29sb3IiLCJwcmlvcml0eSJdLCJzb3VyY2VzIjpbInVzZURlcHJlY2F0aW9uV2FybmluZ05vdGlmaWNhdGlvbi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZU5vdGlmaWNhdGlvbnMgfSBmcm9tICdzcmMvY29udGV4dC9ub3RpZmljYXRpb25zLmpzJ1xuaW1wb3J0IHsgZ2V0TW9kZWxEZXByZWNhdGlvbldhcm5pbmcgfSBmcm9tICdzcmMvdXRpbHMvbW9kZWwvZGVwcmVjYXRpb24uanMnXG5pbXBvcnQgeyBnZXRJc1JlbW90ZU1vZGUgfSBmcm9tICcuLi8uLi9ib290c3RyYXAvc3RhdGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VEZXByZWNhdGlvbldhcm5pbmdOb3RpZmljYXRpb24obW9kZWw6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCB7IGFkZE5vdGlmaWNhdGlvbiB9ID0gdXNlTm90aWZpY2F0aW9ucygpXG4gIGNvbnN0IGxhc3RXYXJuaW5nUmVmID0gdXNlUmVmPHN0cmluZyB8IG51bGw+KG51bGwpXG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZ2V0SXNSZW1vdGVNb2RlKCkpIHJldHVyblxuICAgIGNvbnN0IGRlcHJlY2F0aW9uV2FybmluZyA9IGdldE1vZGVsRGVwcmVjYXRpb25XYXJuaW5nKG1vZGVsKVxuXG4gICAgLy8gU2hvdyB3YXJuaW5nIGlmIG1vZGVsIGlzIGRlcHJlY2F0ZWQgYW5kIHdlIGhhdmVuJ3Qgc2hvd24gdGhpcyBleGFjdCB3YXJuaW5nIHlldFxuICAgIGlmIChkZXByZWNhdGlvbldhcm5pbmcgJiYgZGVwcmVjYXRpb25XYXJuaW5nICE9PSBsYXN0V2FybmluZ1JlZi5jdXJyZW50KSB7XG4gICAgICBsYXN0V2FybmluZ1JlZi5jdXJyZW50ID0gZGVwcmVjYXRpb25XYXJuaW5nXG4gICAgICBhZGROb3RpZmljYXRpb24oe1xuICAgICAgICBrZXk6ICdtb2RlbC1kZXByZWNhdGlvbi13YXJuaW5nJyxcbiAgICAgICAgdGV4dDogZGVwcmVjYXRpb25XYXJuaW5nLFxuICAgICAgICBjb2xvcjogJ3dhcm5pbmcnLFxuICAgICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyBSZXNldCB0cmFja2luZyBpZiBtb2RlbCBjaGFuZ2VzIHRvIG5vbi1kZXByZWNhdGVkXG4gICAgaWYgKCFkZXByZWNhdGlvbldhcm5pbmcpIHtcbiAgICAgIGxhc3RXYXJuaW5nUmVmLmN1cnJlbnQgPSBudWxsXG4gICAgfVxuICB9LCBbbW9kZWwsIGFkZE5vdGlmaWNhdGlvbl0pXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxTQUFTQSxTQUFTLEVBQUVDLE1BQU0sUUFBUSxPQUFPO0FBQ3pDLFNBQVNDLGdCQUFnQixRQUFRLDhCQUE4QjtBQUMvRCxTQUFTQywwQkFBMEIsUUFBUSxnQ0FBZ0M7QUFDM0UsU0FBU0MsZUFBZSxRQUFRLDBCQUEwQjtBQUUxRCxPQUFPLFNBQUFDLGtDQUFBQyxLQUFBO0VBQUEsTUFBQUMsQ0FBQSxHQUFBQyxFQUFBO0VBQ0w7SUFBQUM7RUFBQSxJQUE0QlAsZ0JBQWdCLENBQUMsQ0FBQztFQUM5QyxNQUFBUSxjQUFBLEdBQXVCVCxNQUFNLENBQWdCLElBQUksQ0FBQztFQUFBLElBQUFVLEVBQUE7RUFBQSxJQUFBQyxFQUFBO0VBQUEsSUFBQUwsQ0FBQSxRQUFBRSxlQUFBLElBQUFGLENBQUEsUUFBQUQsS0FBQTtJQUV4Q0ssRUFBQSxHQUFBQSxDQUFBO01BQ1IsSUFBSVAsZUFBZSxDQUFDLENBQUM7UUFBQTtNQUFBO01BQ3JCLE1BQUFTLGtCQUFBLEdBQTJCViwwQkFBMEIsQ0FBQ0csS0FBSyxDQUFDO01BRzVELElBQUlPLGtCQUFtRSxJQUE3Q0Esa0JBQWtCLEtBQUtILGNBQWMsQ0FBQUksT0FBUTtRQUNyRUosY0FBYyxDQUFBSSxPQUFBLEdBQVdELGtCQUFIO1FBQ3RCSixlQUFlLENBQUM7VUFBQU0sR0FBQSxFQUNULDJCQUEyQjtVQUFBQyxJQUFBLEVBQzFCSCxrQkFBa0I7VUFBQUksS0FBQSxFQUNqQixTQUFTO1VBQUFDLFFBQUEsRUFDTjtRQUNaLENBQUMsQ0FBQztNQUFBO01BSUosSUFBSSxDQUFDTCxrQkFBa0I7UUFDckJILGNBQWMsQ0FBQUksT0FBQSxHQUFXLElBQUg7TUFBQTtJQUN2QixDQUNGO0lBQUVGLEVBQUEsSUFBQ04sS0FBSyxFQUFFRyxlQUFlLENBQUM7SUFBQUYsQ0FBQSxNQUFBRSxlQUFBO0lBQUFGLENBQUEsTUFBQUQsS0FBQTtJQUFBQyxDQUFBLE1BQUFJLEVBQUE7SUFBQUosQ0FBQSxNQUFBSyxFQUFBO0VBQUE7SUFBQUQsRUFBQSxHQUFBSixDQUFBO0lBQUFLLEVBQUEsR0FBQUwsQ0FBQTtFQUFBO0VBbkIzQlAsU0FBUyxDQUFDVyxFQW1CVCxFQUFFQyxFQUF3QixDQUFDO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,26 @@
|
||||
import { checkInstall } from 'src/utils/nativeInstaller/index.js';
|
||||
import { useStartupNotification } from './useStartupNotification.js';
|
||||
export function useInstallMessages() {
|
||||
useStartupNotification(_temp2);
|
||||
}
|
||||
async function _temp2() {
|
||||
const messages = await checkInstall();
|
||||
return messages.map(_temp);
|
||||
}
|
||||
function _temp(message, index) {
|
||||
let priority = "low";
|
||||
if (message.type === "error" || message.userActionRequired) {
|
||||
priority = "high";
|
||||
} else {
|
||||
if (message.type === "path" || message.type === "alias") {
|
||||
priority = "medium";
|
||||
}
|
||||
}
|
||||
return {
|
||||
key: `install-message-${index}-${message.type}`,
|
||||
text: message.message,
|
||||
priority,
|
||||
color: message.type === "error" ? "error" : "warning"
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjaGVja0luc3RhbGwiLCJ1c2VTdGFydHVwTm90aWZpY2F0aW9uIiwidXNlSW5zdGFsbE1lc3NhZ2VzIiwiX3RlbXAyIiwibWVzc2FnZXMiLCJtYXAiLCJfdGVtcCIsIm1lc3NhZ2UiLCJpbmRleCIsInByaW9yaXR5IiwidHlwZSIsInVzZXJBY3Rpb25SZXF1aXJlZCIsImtleSIsInRleHQiLCJjb2xvciJdLCJzb3VyY2VzIjpbInVzZUluc3RhbGxNZXNzYWdlcy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2hlY2tJbnN0YWxsIH0gZnJvbSAnc3JjL3V0aWxzL25hdGl2ZUluc3RhbGxlci9pbmRleC5qcydcbmltcG9ydCB7IHVzZVN0YXJ0dXBOb3RpZmljYXRpb24gfSBmcm9tICcuL3VzZVN0YXJ0dXBOb3RpZmljYXRpb24uanMnXG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VJbnN0YWxsTWVzc2FnZXMoKTogdm9pZCB7XG4gIHVzZVN0YXJ0dXBOb3RpZmljYXRpb24oYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gYXdhaXQgY2hlY2tJbnN0YWxsKClcbiAgICByZXR1cm4gbWVzc2FnZXMubWFwKChtZXNzYWdlLCBpbmRleCkgPT4ge1xuICAgICAgbGV0IHByaW9yaXR5OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnIHwgJ2ltbWVkaWF0ZScgPSAnbG93J1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gJ2Vycm9yJyB8fCBtZXNzYWdlLnVzZXJBY3Rpb25SZXF1aXJlZCkge1xuICAgICAgICBwcmlvcml0eSA9ICdoaWdoJ1xuICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnR5cGUgPT09ICdwYXRoJyB8fCBtZXNzYWdlLnR5cGUgPT09ICdhbGlhcycpIHtcbiAgICAgICAgcHJpb3JpdHkgPSAnbWVkaXVtJ1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBgaW5zdGFsbC1tZXNzYWdlLSR7aW5kZXh9LSR7bWVzc2FnZS50eXBlfWAsXG4gICAgICAgIHRleHQ6IG1lc3NhZ2UubWVzc2FnZSxcbiAgICAgICAgcHJpb3JpdHksXG4gICAgICAgIGNvbG9yOiBtZXNzYWdlLnR5cGUgPT09ICdlcnJvcicgPyAnZXJyb3InIDogJ3dhcm5pbmcnLFxuICAgICAgfVxuICAgIH0pXG4gIH0pXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFlBQVksUUFBUSxvQ0FBb0M7QUFDakUsU0FBU0Msc0JBQXNCLFFBQVEsNkJBQTZCO0FBRXBFLE9BQU8sU0FBQUMsbUJBQUE7RUFDTEQsc0JBQXNCLENBQUNFLE1BZ0J0QixDQUFDO0FBQUE7QUFqQkcsZUFBQUEsT0FBQTtFQUVILE1BQUFDLFFBQUEsR0FBaUIsTUFBTUosWUFBWSxDQUFDLENBQUM7RUFBQSxPQUM5QkksUUFBUSxDQUFBQyxHQUFJLENBQUNDLEtBYW5CLENBQUM7QUFBQTtBQWhCQyxTQUFBQSxNQUFBQyxPQUFBLEVBQUFDLEtBQUE7RUFJRCxJQUFBQyxRQUFBLEdBQXdELEtBQUs7RUFDN0QsSUFBSUYsT0FBTyxDQUFBRyxJQUFLLEtBQUssT0FBcUMsSUFBMUJILE9BQU8sQ0FBQUksa0JBQW1CO0lBQ3hERixRQUFBLENBQUFBLENBQUEsQ0FBV0EsTUFBTTtFQUFUO0lBQ0gsSUFBSUYsT0FBTyxDQUFBRyxJQUFLLEtBQUssTUFBa0MsSUFBeEJILE9BQU8sQ0FBQUcsSUFBSyxLQUFLLE9BQU87TUFDNURELFFBQUEsQ0FBQUEsQ0FBQSxDQUFXQSxRQUFRO0lBQVg7RUFDVDtFQUFBLE9BQ007SUFBQUcsR0FBQSxFQUNBLG1CQUFtQkosS0FBSyxJQUFJRCxPQUFPLENBQUFHLElBQUssRUFBRTtJQUFBRyxJQUFBLEVBQ3pDTixPQUFPLENBQUFBLE9BQVE7SUFBQUUsUUFBQTtJQUFBSyxLQUFBLEVBRWRQLE9BQU8sQ0FBQUcsSUFBSyxLQUFLLE9BQTZCLEdBQTlDLE9BQThDLEdBQTlDO0VBQ1QsQ0FBQztBQUFBIiwiaWdub3JlTGlzdCI6W119
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
import { isInBundledMode } from 'src/utils/bundledMode.js';
|
||||
import { getCurrentInstallationType } from 'src/utils/doctorDiagnostic.js';
|
||||
import { isEnvTruthy } from 'src/utils/envUtils.js';
|
||||
import { useStartupNotification } from './useStartupNotification.js';
|
||||
const NPM_DEPRECATION_MESSAGE = 'Claude Code has switched from npm to native installer. Run `claude install` or see https://docs.anthropic.com/en/docs/claude-code/getting-started for more options.';
|
||||
export function useNpmDeprecationNotification() {
|
||||
useStartupNotification(_temp);
|
||||
}
|
||||
async function _temp() {
|
||||
if (isInBundledMode() || isEnvTruthy(process.env.DISABLE_INSTALLATION_CHECKS)) {
|
||||
return null;
|
||||
}
|
||||
const installationType = await getCurrentInstallationType();
|
||||
if (installationType === "development") {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
timeoutMs: 15000,
|
||||
key: "npm-deprecation-warning",
|
||||
text: NPM_DEPRECATION_MESSAGE,
|
||||
color: "warning",
|
||||
priority: "high"
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc0luQnVuZGxlZE1vZGUiLCJnZXRDdXJyZW50SW5zdGFsbGF0aW9uVHlwZSIsImlzRW52VHJ1dGh5IiwidXNlU3RhcnR1cE5vdGlmaWNhdGlvbiIsIk5QTV9ERVBSRUNBVElPTl9NRVNTQUdFIiwidXNlTnBtRGVwcmVjYXRpb25Ob3RpZmljYXRpb24iLCJfdGVtcCIsInByb2Nlc3MiLCJlbnYiLCJESVNBQkxFX0lOU1RBTExBVElPTl9DSEVDS1MiLCJpbnN0YWxsYXRpb25UeXBlIiwidGltZW91dE1zIiwia2V5IiwidGV4dCIsImNvbG9yIiwicHJpb3JpdHkiXSwic291cmNlcyI6WyJ1c2VOcG1EZXByZWNhdGlvbk5vdGlmaWNhdGlvbi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNJbkJ1bmRsZWRNb2RlIH0gZnJvbSAnc3JjL3V0aWxzL2J1bmRsZWRNb2RlLmpzJ1xuaW1wb3J0IHsgZ2V0Q3VycmVudEluc3RhbGxhdGlvblR5cGUgfSBmcm9tICdzcmMvdXRpbHMvZG9jdG9yRGlhZ25vc3RpYy5qcydcbmltcG9ydCB7IGlzRW52VHJ1dGh5IH0gZnJvbSAnc3JjL3V0aWxzL2VudlV0aWxzLmpzJ1xuaW1wb3J0IHsgdXNlU3RhcnR1cE5vdGlmaWNhdGlvbiB9IGZyb20gJy4vdXNlU3RhcnR1cE5vdGlmaWNhdGlvbi5qcydcblxuY29uc3QgTlBNX0RFUFJFQ0FUSU9OX01FU1NBR0UgPVxuICAnQ2xhdWRlIENvZGUgaGFzIHN3aXRjaGVkIGZyb20gbnBtIHRvIG5hdGl2ZSBpbnN0YWxsZXIuIFJ1biBgY2xhdWRlIGluc3RhbGxgIG9yIHNlZSBodHRwczovL2RvY3MuYW50aHJvcGljLmNvbS9lbi9kb2NzL2NsYXVkZS1jb2RlL2dldHRpbmctc3RhcnRlZCBmb3IgbW9yZSBvcHRpb25zLidcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZU5wbURlcHJlY2F0aW9uTm90aWZpY2F0aW9uKCk6IHZvaWQge1xuICB1c2VTdGFydHVwTm90aWZpY2F0aW9uKGFzeW5jICgpID0+IHtcbiAgICBpZiAoXG4gICAgICBpc0luQnVuZGxlZE1vZGUoKSB8fFxuICAgICAgaXNFbnZUcnV0aHkocHJvY2Vzcy5lbnYuRElTQUJMRV9JTlNUQUxMQVRJT05fQ0hFQ0tTKVxuICAgICkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gICAgY29uc3QgaW5zdGFsbGF0aW9uVHlwZSA9IGF3YWl0IGdldEN1cnJlbnRJbnN0YWxsYXRpb25UeXBlKClcbiAgICBpZiAoaW5zdGFsbGF0aW9uVHlwZSA9PT0gJ2RldmVsb3BtZW50JykgcmV0dXJuIG51bGxcbiAgICByZXR1cm4ge1xuICAgICAgdGltZW91dE1zOiAxNTAwMCxcbiAgICAgIGtleTogJ25wbS1kZXByZWNhdGlvbi13YXJuaW5nJyxcbiAgICAgIHRleHQ6IE5QTV9ERVBSRUNBVElPTl9NRVNTQUdFLFxuICAgICAgY29sb3I6ICd3YXJuaW5nJyxcbiAgICAgIHByaW9yaXR5OiAnaGlnaCcsXG4gICAgfVxuICB9KVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxlQUFlLFFBQVEsMEJBQTBCO0FBQzFELFNBQVNDLDBCQUEwQixRQUFRLCtCQUErQjtBQUMxRSxTQUFTQyxXQUFXLFFBQVEsdUJBQXVCO0FBQ25ELFNBQVNDLHNCQUFzQixRQUFRLDZCQUE2QjtBQUVwRSxNQUFNQyx1QkFBdUIsR0FDM0IscUtBQXFLO0FBRXZLLE9BQU8sU0FBQUMsOEJBQUE7RUFDTEYsc0JBQXNCLENBQUNHLEtBZ0J0QixDQUFDO0FBQUE7QUFqQkcsZUFBQUEsTUFBQTtFQUVILElBQ0VOLGVBQWUsQ0FDb0MsQ0FBQyxJQUFwREUsV0FBVyxDQUFDSyxPQUFPLENBQUFDLEdBQUksQ0FBQUMsMkJBQTRCLENBQUM7SUFBQSxPQUU3QyxJQUFJO0VBQUE7RUFFYixNQUFBQyxnQkFBQSxHQUF5QixNQUFNVCwwQkFBMEIsQ0FBQyxDQUFDO0VBQzNELElBQUlTLGdCQUFnQixLQUFLLGFBQWE7SUFBQSxPQUFTLElBQUk7RUFBQTtFQUFBLE9BQzVDO0lBQUFDLFNBQUEsRUFDTSxLQUFLO0lBQUFDLEdBQUEsRUFDWCx5QkFBeUI7SUFBQUMsSUFBQSxFQUN4QlQsdUJBQXVCO0lBQUFVLEtBQUEsRUFDdEIsU0FBUztJQUFBQyxRQUFBLEVBQ047RUFDWixDQUFDO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useNotifications } from 'src/context/notifications.js';
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js';
|
||||
import { getSettingsWithAllErrors } from '../../utils/settings/allErrors.js';
|
||||
import type { ValidationError } from '../../utils/settings/validation.js';
|
||||
import { useSettingsChange } from '../useSettingsChange.js';
|
||||
const SETTINGS_ERRORS_NOTIFICATION_KEY = 'settings-errors';
|
||||
export function useSettingsErrors() {
|
||||
const $ = _c(6);
|
||||
const {
|
||||
addNotification,
|
||||
removeNotification
|
||||
} = useNotifications();
|
||||
const [errors_0, setErrors] = useState(_temp);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = () => {
|
||||
const {
|
||||
errors: errors_1
|
||||
} = getSettingsWithAllErrors();
|
||||
setErrors(errors_1);
|
||||
};
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const handleSettingsChange = t0;
|
||||
useSettingsChange(handleSettingsChange);
|
||||
let t1;
|
||||
let t2;
|
||||
if ($[1] !== addNotification || $[2] !== errors_0 || $[3] !== removeNotification) {
|
||||
t1 = () => {
|
||||
if (getIsRemoteMode()) {
|
||||
return;
|
||||
}
|
||||
if (errors_0.length > 0) {
|
||||
const message = `Found ${errors_0.length} settings ${errors_0.length === 1 ? "issue" : "issues"} · /doctor for details`;
|
||||
addNotification({
|
||||
key: SETTINGS_ERRORS_NOTIFICATION_KEY,
|
||||
text: message,
|
||||
color: "warning",
|
||||
priority: "high",
|
||||
timeoutMs: 60000
|
||||
});
|
||||
} else {
|
||||
removeNotification(SETTINGS_ERRORS_NOTIFICATION_KEY);
|
||||
}
|
||||
};
|
||||
t2 = [errors_0, addNotification, removeNotification];
|
||||
$[1] = addNotification;
|
||||
$[2] = errors_0;
|
||||
$[3] = removeNotification;
|
||||
$[4] = t1;
|
||||
$[5] = t2;
|
||||
} else {
|
||||
t1 = $[4];
|
||||
t2 = $[5];
|
||||
}
|
||||
useEffect(t1, t2);
|
||||
return errors_0;
|
||||
}
|
||||
function _temp() {
|
||||
const {
|
||||
errors
|
||||
} = getSettingsWithAllErrors();
|
||||
return errors;
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1c2VDYWxsYmFjayIsInVzZUVmZmVjdCIsInVzZVN0YXRlIiwidXNlTm90aWZpY2F0aW9ucyIsImdldElzUmVtb3RlTW9kZSIsImdldFNldHRpbmdzV2l0aEFsbEVycm9ycyIsIlZhbGlkYXRpb25FcnJvciIsInVzZVNldHRpbmdzQ2hhbmdlIiwiU0VUVElOR1NfRVJST1JTX05PVElGSUNBVElPTl9LRVkiLCJ1c2VTZXR0aW5nc0Vycm9ycyIsIiQiLCJfYyIsImFkZE5vdGlmaWNhdGlvbiIsInJlbW92ZU5vdGlmaWNhdGlvbiIsImVycm9yc18wIiwic2V0RXJyb3JzIiwiX3RlbXAiLCJ0MCIsIlN5bWJvbCIsImZvciIsImVycm9ycyIsImVycm9yc18xIiwiaGFuZGxlU2V0dGluZ3NDaGFuZ2UiLCJ0MSIsInQyIiwibGVuZ3RoIiwibWVzc2FnZSIsImtleSIsInRleHQiLCJjb2xvciIsInByaW9yaXR5IiwidGltZW91dE1zIl0sInNvdXJjZXMiOlsidXNlU2V0dGluZ3NFcnJvcnMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VFZmZlY3QsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnXG5pbXBvcnQgeyB1c2VOb3RpZmljYXRpb25zIH0gZnJvbSAnc3JjL2NvbnRleHQvbm90aWZpY2F0aW9ucy5qcydcbmltcG9ydCB7IGdldElzUmVtb3RlTW9kZSB9IGZyb20gJy4uLy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB7IGdldFNldHRpbmdzV2l0aEFsbEVycm9ycyB9IGZyb20gJy4uLy4uL3V0aWxzL3NldHRpbmdzL2FsbEVycm9ycy5qcydcbmltcG9ydCB0eXBlIHsgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvc2V0dGluZ3MvdmFsaWRhdGlvbi5qcydcbmltcG9ydCB7IHVzZVNldHRpbmdzQ2hhbmdlIH0gZnJvbSAnLi4vdXNlU2V0dGluZ3NDaGFuZ2UuanMnXG5cbmNvbnN0IFNFVFRJTkdTX0VSUk9SU19OT1RJRklDQVRJT05fS0VZID0gJ3NldHRpbmdzLWVycm9ycydcblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVNldHRpbmdzRXJyb3JzKCk6IFZhbGlkYXRpb25FcnJvcltdIHtcbiAgY29uc3QgeyBhZGROb3RpZmljYXRpb24sIHJlbW92ZU5vdGlmaWNhdGlvbiB9ID0gdXNlTm90aWZpY2F0aW9ucygpXG4gIGNvbnN0IFtlcnJvcnMsIHNldEVycm9yc10gPSB1c2VTdGF0ZTxWYWxpZGF0aW9uRXJyb3JbXT4oKCkgPT4ge1xuICAgIGNvbnN0IHsgZXJyb3JzIH0gPSBnZXRTZXR0aW5nc1dpdGhBbGxFcnJvcnMoKVxuICAgIHJldHVybiBlcnJvcnNcbiAgfSlcblxuICBjb25zdCBoYW5kbGVTZXR0aW5nc0NoYW5nZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCB7IGVycm9ycyB9ID0gZ2V0U2V0dGluZ3NXaXRoQWxsRXJyb3JzKClcbiAgICBzZXRFcnJvcnMoZXJyb3JzKVxuICB9LCBbXSlcblxuICB1c2VTZXR0aW5nc0NoYW5nZShoYW5kbGVTZXR0aW5nc0NoYW5nZSlcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChnZXRJc1JlbW90ZU1vZGUoKSkgcmV0dXJuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYEZvdW5kICR7ZXJyb3JzLmxlbmd0aH0gc2V0dGluZ3MgJHtlcnJvcnMubGVuZ3RoID09PSAxID8gJ2lzc3VlJyA6ICdpc3N1ZXMnfSDCtyAvZG9jdG9yIGZvciBkZXRhaWxzYFxuICAgICAgYWRkTm90aWZpY2F0aW9uKHtcbiAgICAgICAga2V5OiBTRVRUSU5HU19FUlJPUlNfTk9USUZJQ0FUSU9OX0tFWSxcbiAgICAgICAgdGV4dDogbWVzc2FnZSxcbiAgICAgICAgY29sb3I6ICd3YXJuaW5nJyxcbiAgICAgICAgcHJpb3JpdHk6ICdoaWdoJyxcbiAgICAgICAgdGltZW91dE1zOiA2MDAwMCxcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHJlbW92ZU5vdGlmaWNhdGlvbihTRVRUSU5HU19FUlJPUlNfTk9USUZJQ0FUSU9OX0tFWSlcbiAgICB9XG4gIH0sIFtlcnJvcnMsIGFkZE5vdGlmaWNhdGlvbiwgcmVtb3ZlTm90aWZpY2F0aW9uXSlcblxuICByZXR1cm4gZXJyb3JzXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxTQUFTQSxXQUFXLEVBQUVDLFNBQVMsRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDeEQsU0FBU0MsZ0JBQWdCLFFBQVEsOEJBQThCO0FBQy9ELFNBQVNDLGVBQWUsUUFBUSwwQkFBMEI7QUFDMUQsU0FBU0Msd0JBQXdCLFFBQVEsbUNBQW1DO0FBQzVFLGNBQWNDLGVBQWUsUUFBUSxvQ0FBb0M7QUFDekUsU0FBU0MsaUJBQWlCLFFBQVEseUJBQXlCO0FBRTNELE1BQU1DLGdDQUFnQyxHQUFHLGlCQUFpQjtBQUUxRCxPQUFPLFNBQUFDLGtCQUFBO0VBQUEsTUFBQUMsQ0FBQSxHQUFBQyxFQUFBO0VBQ0w7SUFBQUMsZUFBQTtJQUFBQztFQUFBLElBQWdEVixnQkFBZ0IsQ0FBQyxDQUFDO0VBQ2xFLE9BQUFXLFFBQUEsRUFBQUMsU0FBQSxJQUE0QmIsUUFBUSxDQUFvQmMsS0FHdkQsQ0FBQztFQUFBLElBQUFDLEVBQUE7RUFBQSxJQUFBUCxDQUFBLFFBQUFRLE1BQUEsQ0FBQUMsR0FBQTtJQUV1Q0YsRUFBQSxHQUFBQSxDQUFBO01BQ3ZDO1FBQUFHLE1BQUEsRUFBQUM7TUFBQSxJQUFtQmhCLHdCQUF3QixDQUFDLENBQUM7TUFDN0NVLFNBQVMsQ0FBQ0ssUUFBTSxDQUFDO0lBQUEsQ0FDbEI7SUFBQVYsQ0FBQSxNQUFBTyxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBUCxDQUFBO0VBQUE7RUFIRCxNQUFBWSxvQkFBQSxHQUE2QkwsRUFHdkI7RUFFTlYsaUJBQWlCLENBQUNlLG9CQUFvQixDQUFDO0VBQUEsSUFBQUMsRUFBQTtFQUFBLElBQUFDLEVBQUE7RUFBQSxJQUFBZCxDQUFBLFFBQUFFLGVBQUEsSUFBQUYsQ0FBQSxRQUFBSSxRQUFBLElBQUFKLENBQUEsUUFBQUcsa0JBQUE7SUFFN0JVLEVBQUEsR0FBQUEsQ0FBQTtNQUNSLElBQUluQixlQUFlLENBQUMsQ0FBQztRQUFBO01BQUE7TUFDckIsSUFBSWdCLFFBQU0sQ0FBQUssTUFBTyxHQUFHLENBQUM7UUFDbkIsTUFBQUMsT0FBQSxHQUFnQixTQUFTTixRQUFNLENBQUFLLE1BQU8sYUFBYUwsUUFBTSxDQUFBSyxNQUFPLEtBQUssQ0FBc0IsR0FBeEMsT0FBd0MsR0FBeEMsUUFBd0Msd0JBQXdCO1FBQ25IYixlQUFlLENBQUM7VUFBQWUsR0FBQSxFQUNUbkIsZ0NBQWdDO1VBQUFvQixJQUFBLEVBQy9CRixPQUFPO1VBQUFHLEtBQUEsRUFDTixTQUFTO1VBQUFDLFFBQUEsRUFDTixNQUFNO1VBQUFDLFNBQUEsRUFDTDtRQUNiLENBQUMsQ0FBQztNQUFBO1FBRUZsQixrQkFBa0IsQ0FBQ0wsZ0NBQWdDLENBQUM7TUFBQTtJQUNyRCxDQUNGO0lBQUVnQixFQUFBLElBQUNKLFFBQU0sRUFBRVIsZUFBZSxFQUFFQyxrQkFBa0IsQ0FBQztJQUFBSCxDQUFBLE1BQUFFLGVBQUE7SUFBQUYsQ0FBQSxNQUFBSSxRQUFBO0lBQUFKLENBQUEsTUFBQUcsa0JBQUE7SUFBQUgsQ0FBQSxNQUFBYSxFQUFBO0lBQUFiLENBQUEsTUFBQWMsRUFBQTtFQUFBO0lBQUFELEVBQUEsR0FBQWIsQ0FBQTtJQUFBYyxFQUFBLEdBQUFkLENBQUE7RUFBQTtFQWRoRFQsU0FBUyxDQUFDc0IsRUFjVCxFQUFFQyxFQUE2QyxDQUFDO0VBQUEsT0FFMUNKLFFBQU07QUFBQTtBQTlCUixTQUFBSixNQUFBO0VBR0g7SUFBQUk7RUFBQSxJQUFtQmYsd0JBQXdCLENBQUMsQ0FBQztFQUFBLE9BQ3RDZSxNQUFNO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js'
|
||||
import {
|
||||
type Notification,
|
||||
useNotifications,
|
||||
} from '../../context/notifications.js'
|
||||
import { logError } from '../../utils/log.js'
|
||||
|
||||
type Result = Notification | Notification[] | null
|
||||
|
||||
/**
|
||||
* Fires notification(s) once on mount. Encapsulates the remote-mode gate and
|
||||
* once-per-session ref guard that was hand-rolled across 10+ notifs/ hooks.
|
||||
*
|
||||
* The compute fn runs exactly once on first effect. Return null to skip,
|
||||
* a Notification to fire one, or an array to fire several. Sync or async.
|
||||
* Rejections are routed to logError.
|
||||
*/
|
||||
export function useStartupNotification(
|
||||
compute: () => Result | Promise<Result>,
|
||||
): void {
|
||||
const { addNotification } = useNotifications()
|
||||
const hasRunRef = useRef(false)
|
||||
const computeRef = useRef(compute)
|
||||
computeRef.current = compute
|
||||
|
||||
useEffect(() => {
|
||||
if (getIsRemoteMode() || hasRunRef.current) return
|
||||
hasRunRef.current = true
|
||||
|
||||
void Promise.resolve()
|
||||
.then(() => computeRef.current())
|
||||
.then(result => {
|
||||
if (!result) return
|
||||
for (const n of Array.isArray(result) ? result : [result]) {
|
||||
addNotification(n)
|
||||
}
|
||||
})
|
||||
.catch(logError)
|
||||
}, [addNotification])
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js'
|
||||
import {
|
||||
type Notification,
|
||||
useNotifications,
|
||||
} from '../../context/notifications.js'
|
||||
import { useAppState } from '../../state/AppState.js'
|
||||
import { isInProcessTeammateTask } from '../../tasks/InProcessTeammateTask/types.js'
|
||||
|
||||
function parseCount(notif: Notification): number {
|
||||
if (!('text' in notif)) {
|
||||
return 1
|
||||
}
|
||||
const match = notif.text.match(/^(\d+)/)
|
||||
return match?.[1] ? parseInt(match[1], 10) : 1
|
||||
}
|
||||
|
||||
function foldSpawn(acc: Notification, _incoming: Notification): Notification {
|
||||
return makeSpawnNotif(parseCount(acc) + 1)
|
||||
}
|
||||
|
||||
function makeSpawnNotif(count: number): Notification {
|
||||
return {
|
||||
key: 'teammate-spawn',
|
||||
text: count === 1 ? '1 agent spawned' : `${count} agents spawned`,
|
||||
priority: 'low',
|
||||
timeoutMs: 5000,
|
||||
fold: foldSpawn,
|
||||
}
|
||||
}
|
||||
|
||||
function foldShutdown(
|
||||
acc: Notification,
|
||||
_incoming: Notification,
|
||||
): Notification {
|
||||
return makeShutdownNotif(parseCount(acc) + 1)
|
||||
}
|
||||
|
||||
function makeShutdownNotif(count: number): Notification {
|
||||
return {
|
||||
key: 'teammate-shutdown',
|
||||
text: count === 1 ? '1 agent shut down' : `${count} agents shut down`,
|
||||
priority: 'low',
|
||||
timeoutMs: 5000,
|
||||
fold: foldShutdown,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires batched notifications when in-process teammates spawn or shut down.
|
||||
* Uses fold() to combine repeated events into a single notification
|
||||
* like "3 agents spawned" or "2 agents shut down".
|
||||
*/
|
||||
export function useTeammateLifecycleNotification(): void {
|
||||
const tasks = useAppState(s => s.tasks)
|
||||
const { addNotification } = useNotifications()
|
||||
const seenRunningRef = useRef<Set<string>>(new Set())
|
||||
const seenCompletedRef = useRef<Set<string>>(new Set())
|
||||
|
||||
useEffect(() => {
|
||||
if (getIsRemoteMode()) return
|
||||
for (const [id, task] of Object.entries(tasks)) {
|
||||
if (!isInProcessTeammateTask(task)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (task.status === 'running' && !seenRunningRef.current.has(id)) {
|
||||
seenRunningRef.current.add(id)
|
||||
addNotification(makeSpawnNotif(1))
|
||||
}
|
||||
|
||||
if (task.status === 'completed' && !seenCompletedRef.current.has(id)) {
|
||||
seenCompletedRef.current.add(id)
|
||||
addNotification(makeShutdownNotif(1))
|
||||
}
|
||||
}
|
||||
}, [tasks, addNotification])
|
||||
}
|
||||
Reference in New Issue
Block a user