init claude-code
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* /reload-plugins — Layer-3 refresh. Applies pending plugin changes to the
|
||||
* running session. Implementation lazy-loaded.
|
||||
*/
|
||||
import type { Command } from '../../commands.js'
|
||||
|
||||
const reloadPlugins = {
|
||||
type: 'local',
|
||||
name: 'reload-plugins',
|
||||
description: 'Activate pending plugin changes in the current session',
|
||||
// SDK callers use query.reloadPlugins() (control request) instead of
|
||||
// sending this as a text prompt — that returns structured data
|
||||
// (commands, agents, plugins, mcpServers) for UI updates.
|
||||
supportsNonInteractive: false,
|
||||
load: () => import('./reload-plugins.js'),
|
||||
} satisfies Command
|
||||
|
||||
export default reloadPlugins
|
||||
@@ -0,0 +1,61 @@
|
||||
import { feature } from 'bun:bundle'
|
||||
import { getIsRemoteMode } from '../../bootstrap/state.js'
|
||||
import { redownloadUserSettings } from '../../services/settingsSync/index.js'
|
||||
import type { LocalCommandCall } from '../../types/command.js'
|
||||
import { isEnvTruthy } from '../../utils/envUtils.js'
|
||||
import { refreshActivePlugins } from '../../utils/plugins/refresh.js'
|
||||
import { settingsChangeDetector } from '../../utils/settings/changeDetector.js'
|
||||
import { plural } from '../../utils/stringUtils.js'
|
||||
|
||||
export const call: LocalCommandCall = async (_args, context) => {
|
||||
// CCR: re-pull user settings before the cache sweep so enabledPlugins /
|
||||
// extraKnownMarketplaces pushed from the user's local CLI (settingsSync)
|
||||
// take effect. Non-CCR headless (e.g. vscode SDK subprocess) shares disk
|
||||
// with whoever writes settings — the file watcher delivers changes, no
|
||||
// re-pull needed there.
|
||||
//
|
||||
// Managed settings intentionally NOT re-fetched: it already polls hourly
|
||||
// (POLLING_INTERVAL_MS), and policy enforcement is eventually-consistent
|
||||
// by design (stale-cache fallback on fetch failure). Interactive
|
||||
// /reload-plugins has never re-fetched it either.
|
||||
//
|
||||
// No retries: user-initiated command, one attempt + fail-open. The user
|
||||
// can re-run /reload-plugins to retry. Startup path keeps its retries.
|
||||
if (
|
||||
feature('DOWNLOAD_USER_SETTINGS') &&
|
||||
(isEnvTruthy(process.env.CLAUDE_CODE_REMOTE) || getIsRemoteMode())
|
||||
) {
|
||||
const applied = await redownloadUserSettings()
|
||||
// applyRemoteEntriesToLocal uses markInternalWrite to suppress the
|
||||
// file watcher (correct for startup, nothing listening yet); fire
|
||||
// notifyChange here so mid-session applySettingsChange runs.
|
||||
if (applied) {
|
||||
settingsChangeDetector.notifyChange('userSettings')
|
||||
}
|
||||
}
|
||||
|
||||
const r = await refreshActivePlugins(context.setAppState)
|
||||
|
||||
const parts = [
|
||||
n(r.enabled_count, 'plugin'),
|
||||
n(r.command_count, 'skill'),
|
||||
n(r.agent_count, 'agent'),
|
||||
n(r.hook_count, 'hook'),
|
||||
// "plugin MCP/LSP" disambiguates from user-config/built-in servers,
|
||||
// which /reload-plugins doesn't touch. Commands/hooks are plugin-only;
|
||||
// agent_count is total agents (incl. built-ins). (gh-31321)
|
||||
n(r.mcp_count, 'plugin MCP server'),
|
||||
n(r.lsp_count, 'plugin LSP server'),
|
||||
]
|
||||
let msg = `Reloaded: ${parts.join(' · ')}`
|
||||
|
||||
if (r.error_count > 0) {
|
||||
msg += `\n${n(r.error_count, 'error')} during load. Run /doctor for details.`
|
||||
}
|
||||
|
||||
return { type: 'text', value: msg }
|
||||
}
|
||||
|
||||
function n(count: number, noun: string): string {
|
||||
return `${count} ${plural(count, noun)}`
|
||||
}
|
||||
Reference in New Issue
Block a user