scream-code 0.13.6 → 0.13.8

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.
@@ -4,8 +4,8 @@ import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
- import { $ as toTerminalHyperlink, $t as parseStreamingArgs, A as highlightLines, An as CLI_UI_MODE, At as ENABLE_TERMINAL_THEME_REPORTING, B as AssistantMessageComponent, Bn as flushDiagnosticLogs, Bt as isBusy, C as UserMessageComponent, Cn as saveTuiConfig, Ct as contrastTextHex, D as ToolCallComponent, Dn as getLogDir, Dt as DISABLE_TERMINAL_FOCUS_REPORTING, E as toggleEmptySessionHint, En as getInputHistoryFile, Et as parseOsc11BackgroundTheme, F as getSharedSpeedTracker, Fn as saveCatalogCache, Ft as QUERY_TERMINAL_THEME, G as resetBreathingClock, Gn as ErrorCodes, H as WelcomeComponent, Hn as resolveGlobalLogPath, Ht as FooterComponent, I as SkillActivationComponent, In as ScreamHarness, It as TERMINAL_FOCUS_IN, Jt as STATUS_BULLET, K as clearGoalState, Kn as SCREAM_ERROR_INFO, L as ReadGroupComponent, Lt as TERMINAL_FOCUS_OUT, M as CachedContainer, Mn as PRODUCT_NAME, Mt as OSC11_RESPONSE, N as ThinkingComponent, Nn as DEFAULT_CATALOG_URL, Nt as OSC11_RESPONSE_PREFIX, O as renderDiffLines, On as detectInstallSource, Ot as DISABLE_TERMINAL_THEME_REPORTING, P as estimateTokens, Pn as fetchCatalog, Pt as OSC11_RESPONSE_PREFIX_NO_ESC, Qt as isTodoItemShape, R as parseReadGroupOutput, Rn as resolveScreamHome, Rt as TERMINAL_THEME_DARK, Sn as loadTuiConfig, St as createThemeStyles, T as isTurnElapsedEnabled, Tn as getDataDir, Tt as detectTerminalTheme, U as BREATHE_CYCLE_MS, Un as isScreamError, V as AgentGroupComponent, Vn as log, Vt as isStreaming, W as getBreathingFrame, Wn as isOrphanedToolCallError, Xt as argsRecord, Yt as appendStreamingArgsPreview, Zt as formatErrorMessage, _ as readUpdateCache, _n as setExperimentalFlags, an as EXIT_CONFIRM_WINDOW_MS, at as handleFusionPlanCommand, bn as TuiConfigParseError, bt as createEditorTheme, c as isPlanExpandable, cn as TIP_ROTATION_INTERVAL_MS, dn as getLlmNotSetMessage, en as serializeToolResultOutput, et as changeThinkingLevel, fn as getNoActiveSessionMessage, g as refreshUpdateCache, gn as isExperimentalFlagEnabled, gt as clearInfoPanelState, h as selectUpdateTarget, hn as sortSlashCommands, ht as supportsBalance, i as buildRoleAdditionalText, in as EMPTY_SESSION_HINT_URL, j as langFromPath, jn as CLI_USER_AGENT_PRODUCT, jt as OSC11_QUERY, k as renderDiffLinesClustered, kn as CLI_COMMAND_NAME, kt as ENABLE_TERMINAL_FOCUS_REPORTING, l as MoonLoader, ln as getCtrlCHint, mn as BUILTIN_SLASH_COMMANDS, mt as refreshProviderBalance, n as clearEvalPanelState, nn as truncateErrorMessage, o as disposeChildren, on as MAIN_AGENT_ID, pn as buildSkillSlashCommands, q as refineGoal, qt as printableChar, r as openUrl, rn as CHARS_PER_TOKEN, s as hasDispose, sn as SESSION_TIPS, st as handlePlanCommand, t as dispatchInput, tn as stringValue, tt as getModelCycleLevel, u as formatMemoryMemoForInjection, un as getCtrlDHint, v as appendJsonlLine, vn as PIXEL_PULSE_FRAMES, w as isEmptySessionHintDismissed, wn as detectShellEnvironment, wt as getColorPalette, x as getDaemonInstructions, xn as TuiLikePreferencesSchema, xt as createMarkdownTheme, y as readJsonlFile, yn as PULSE_WAVE_FRAMES, yt as resolveThemeSync, z as BackgroundAgentStatusComponent, zn as MemoryMemoStore, zt as TERMINAL_THEME_LIGHT } from "./dispatch-CEemtjRD.mjs";
8
- import { a as setLocale, o as t } from "./text-input-dialog-DstXBOl9.mjs";
7
+ import { $t as isTodoItemShape, A as renderDiffLinesClustered, An as CLI_COMMAND_NAME, At as ENABLE_TERMINAL_FOCUS_REPORTING, B as BackgroundAgentStatusComponent, Bn as MemoryMemoStore, Bt as TERMINAL_THEME_LIGHT, Cn as loadTuiConfig, Ct as createThemeStyles, D as toggleEmptySessionHint, Dn as getInputHistoryFile, Dt as parseOsc11BackgroundTheme, E as isTurnElapsedEnabled, En as getDataDir, Et as detectTerminalTheme, F as estimateTokens, Fn as fetchCatalog, Ft as OSC11_RESPONSE_PREFIX_NO_ESC, G as getBreathingFrame, Gn as isOrphanedToolCallError, H as AgentGroupComponent, Hn as log, Ht as isStreaming, I as getSharedSpeedTracker, In as saveCatalogCache, It as QUERY_TERMINAL_THEME, J as refineGoal, Jt as printableChar, K as resetBreathingClock, Kn as ErrorCodes, L as SkillActivationComponent, Ln as ScreamHarness, Lt as TERMINAL_FOCUS_IN, M as langFromPath, Mn as CLI_USER_AGENT_PRODUCT, Mt as OSC11_QUERY, N as CachedContainer, Nn as PRODUCT_NAME, Nt as OSC11_RESPONSE, O as ToolCallComponent, On as getLogDir, Ot as DISABLE_TERMINAL_FOCUS_REPORTING, P as ThinkingComponent, Pn as DEFAULT_CATALOG_URL, Pt as OSC11_RESPONSE_PREFIX, Qt as formatErrorMessage, R as ReadGroupComponent, Rt as TERMINAL_FOCUS_OUT, S as getDaemonInstructions, Sn as TuiLikePreferencesSchema, St as createMarkdownTheme, T as isEmptySessionHintDismissed, Tn as detectShellEnvironment, Tt as getColorPalette, U as WelcomeComponent, Un as resolveGlobalLogPath, Ut as FooterComponent, V as AssistantMessageComponent, Vn as flushDiagnosticLogs, Vt as isBusy, W as BREATHE_CYCLE_MS, Wn as isScreamError, Xt as appendStreamingArgsPreview, Yt as STATUS_BULLET, Zt as argsRecord, _ as refreshUpdateCache, _n as isExperimentalFlagEnabled, _t as clearInfoPanelState, an as EMPTY_SESSION_HINT_URL, b as readJsonlFile, bn as PULSE_WAVE_FRAMES, bt as resolveThemeSync, c as hasDispose, cn as SESSION_TIPS, ct as handlePlanCommand, d as formatMemoryMemoForInjection, dn as getCtrlDHint, en as parseStreamingArgs, et as toTerminalHyperlink, fn as getLlmNotSetMessage, g as selectUpdateTarget, gn as sortSlashCommands, gt as supportsBalance, hn as BUILTIN_SLASH_COMMANDS, ht as refreshProviderBalance, i as buildRoleAdditionalText, in as CHARS_PER_TOKEN, j as highlightLines, jn as CLI_UI_MODE, jt as ENABLE_TERMINAL_THEME_REPORTING, k as renderDiffLines, kn as detectInstallSource, kt as DISABLE_TERMINAL_THEME_REPORTING, l as isPlanExpandable, ln as TIP_ROTATION_INTERVAL_MS, mn as buildSkillSlashCommands, n as clearEvalPanelState, nn as stringValue, nt as getModelCycleLevel, on as EXIT_CONFIRM_WINDOW_MS, ot as handleFusionPlanCommand, pn as getNoActiveSessionMessage, q as clearGoalState, qn as SCREAM_ERROR_INFO, r as openUrl, rn as truncateErrorMessage, s as disposeChildren, sn as MAIN_AGENT_ID, t as dispatchInput, tn as serializeToolResultOutput, tt as changeThinkingLevel, u as MoonLoader, un as getCtrlCHint, v as readUpdateCache, vn as setExperimentalFlags, w as UserMessageComponent, wn as saveTuiConfig, wt as contrastTextHex, xn as TuiConfigParseError, xt as createEditorTheme, y as appendJsonlLine, yn as PIXEL_PULSE_FRAMES, z as parseReadGroupOutput, zn as resolveScreamHome, zt as TERMINAL_THEME_DARK } from "./dispatch-DevL-OSj.mjs";
8
+ import { a as setLocale, o as t } from "./text-input-dialog-B9Klg3re.mjs";
9
9
  import { createRequire } from "node:module";
10
10
  import { randomUUID } from "node:crypto";
11
11
  import { access, mkdir, mkdtemp, readFile, readdir, realpath, rm, unlink, writeFile } from "node:fs/promises";
@@ -30,7 +30,7 @@ function optionalBuildString(value) {
30
30
  return typeof value === "string" && value.length > 0 ? value : void 0;
31
31
  }
32
32
  const SCREAM_BUILD_INFO = {
33
- version: optionalBuildString("0.13.6"),
33
+ version: optionalBuildString("0.13.8"),
34
34
  channel: optionalBuildString(""),
35
35
  commit: optionalBuildString(""),
36
36
  buildTarget: optionalBuildString("darwin-arm64")
@@ -12192,7 +12192,7 @@ var ScreamTUI = class {
12192
12192
  const card = new OnboardingCardComponent({
12193
12193
  colors: this.state.theme.colors,
12194
12194
  onConfigure: () => {
12195
- import("./dispatch-BlGMsyFT.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12195
+ import("./dispatch-D5doFUQU.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12196
12196
  this.restoreEditor();
12197
12197
  });
12198
12198
  },
@@ -3,5 +3,5 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
3
3
  import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
- import { Gt as handleConnectCommand } from "./dispatch-CEemtjRD.mjs";
6
+ import { Kt as handleConnectCommand } from "./dispatch-DevL-OSj.mjs";
7
7
  export { handleConnectCommand };
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-D90kvbyJ.mjs";
7
7
  import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize, x as dirname$2, y as KnowledgeStore } from "./src-BH9W5k24.mjs";
8
8
  import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
9
- import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-DstXBOl9.mjs";
9
+ import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-B9Klg3re.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
12
12
  import * as fs$1 from "node:fs/promises";
@@ -59275,7 +59275,8 @@ const DOCUMENTATION_MARKDOWN_LOWER$1 = new Set([
59275
59275
  "code_of_conduct.md",
59276
59276
  "architecture.md",
59277
59277
  "design.md",
59278
- "notes.md"
59278
+ "notes.md",
59279
+ "agents.md"
59279
59280
  ]);
59280
59281
  async function resolveSkillRoots(options) {
59281
59282
  const isDir = options.isDir ?? defaultIsDir;
@@ -66386,7 +66387,6 @@ const BARE_SKILL_PATH = "SKILL.md";
66386
66387
  const UNSUPPORTED_RUNTIME_FIELDS = [
66387
66388
  "tools",
66388
66389
  "commands",
66389
- "hooks",
66390
66390
  "apps",
66391
66391
  "inject",
66392
66392
  "configFile",
@@ -66485,6 +66485,8 @@ async function parseManifest(pluginRoot) {
66485
66485
  const skillInstructions = typeof raw["skillInstructions"] === "string" ? raw["skillInstructions"] : void 0;
66486
66486
  const config = typeof raw["config"] === "object" && raw["config"] !== null && !Array.isArray(raw["config"]) ? raw["config"] : void 0;
66487
66487
  recordUnsupportedRuntimeFields(raw, diagnostics);
66488
+ const entryPoint = await readEntryPoint(pluginRoot, raw["entryPoint"], diagnostics);
66489
+ const hooks = readHooks(pluginRoot, raw["hooks"], diagnostics);
66488
66490
  return {
66489
66491
  manifest: {
66490
66492
  name,
@@ -66499,7 +66501,9 @@ async function parseManifest(pluginRoot) {
66499
66501
  mcpServers: await readMcpServers(pluginRoot, raw["mcpServers"], diagnostics),
66500
66502
  interface: readInterface(raw["interface"]),
66501
66503
  skillInstructions,
66502
- config
66504
+ config,
66505
+ entryPoint,
66506
+ hooks
66503
66507
  },
66504
66508
  manifestKind,
66505
66509
  manifestPath,
@@ -66516,6 +66520,75 @@ function recordUnsupportedRuntimeFields(raw, diagnostics) {
66516
66520
  });
66517
66521
  }
66518
66522
  }
66523
+ async function readEntryPoint(pluginRoot, raw, diagnostics) {
66524
+ if (raw === void 0) return void 0;
66525
+ if (typeof raw !== "string") {
66526
+ diagnostics.push({
66527
+ severity: "warn",
66528
+ message: "\"entryPoint\" must be a string"
66529
+ });
66530
+ return;
66531
+ }
66532
+ return resolvePluginPathField({
66533
+ pluginRoot,
66534
+ field: "entryPoint",
66535
+ value: raw,
66536
+ diagnostics
66537
+ });
66538
+ }
66539
+ /**
66540
+ * Parse a plugin's declared hooks (external-command HookEngine channel). Each
66541
+ * entry mirrors {@link HookDef}: event, optional matcher, command (a `./`
66542
+ * relative command is resolved against the plugin root), optional timeout.
66543
+ * Unknown event names are kept (cast): they can never match a HookEngine
66544
+ * trigger, so they are inert rather than harmful.
66545
+ */
66546
+ function readHooks(pluginRoot, raw, diagnostics) {
66547
+ if (raw === void 0) return void 0;
66548
+ if (!Array.isArray(raw)) {
66549
+ diagnostics.push({
66550
+ severity: "warn",
66551
+ message: "\"hooks\" must be an array"
66552
+ });
66553
+ return;
66554
+ }
66555
+ const out = [];
66556
+ for (const entry of raw) {
66557
+ if (!isObject(entry)) {
66558
+ diagnostics.push({
66559
+ severity: "warn",
66560
+ message: "\"hooks\" entries must be objects"
66561
+ });
66562
+ continue;
66563
+ }
66564
+ const event = stringField$1(entry, "event");
66565
+ if (event === void 0) {
66566
+ diagnostics.push({
66567
+ severity: "warn",
66568
+ message: "\"hooks\" entry is missing \"event\""
66569
+ });
66570
+ continue;
66571
+ }
66572
+ let command = stringField$1(entry, "command");
66573
+ if (command === void 0) {
66574
+ diagnostics.push({
66575
+ severity: "warn",
66576
+ message: "\"hooks\" entry is missing \"command\""
66577
+ });
66578
+ continue;
66579
+ }
66580
+ if (command.startsWith("./")) command = path.resolve(pluginRoot, command);
66581
+ const timeout = typeof entry["timeout"] === "number" ? entry["timeout"] : void 0;
66582
+ const hook = {
66583
+ event,
66584
+ command,
66585
+ ...stringField$1(entry, "matcher") !== void 0 ? { matcher: stringField$1(entry, "matcher") } : {},
66586
+ ...timeout !== void 0 ? { timeout } : {}
66587
+ };
66588
+ out.push(hook);
66589
+ }
66590
+ return out.length > 0 ? out : void 0;
66591
+ }
66519
66592
  async function resolveSkillsField(pluginRoot, raw, diagnostics) {
66520
66593
  if (raw === void 0) return [];
66521
66594
  const entries = [];
@@ -76454,6 +76527,63 @@ function buildBackgroundTaskNotificationBody(info, isAgentTask) {
76454
76527
  ].join("\n")}`;
76455
76528
  }
76456
76529
  //#endregion
76530
+ //#region ../../packages/agent-core/src/agent/events.ts
76531
+ /**
76532
+ * In-process subscription bus for {@link AgentEvent}s.
76533
+ *
76534
+ * Mirrors the events the agent already broadcasts to the host via
76535
+ * `rpc.emitEvent`, so third-party extensions running inside the agent process
76536
+ * can subscribe without round-tripping through the host. This is the
76537
+ * read-side companion to {@link import('./index').Agent.emitEvent}.
76538
+ *
76539
+ * Lifecycle: extensions call `subscribe()` when activated and must call
76540
+ * `clear()` (or the returned unsubscribe) when deactivated to avoid leaking
76541
+ * handlers across sessions/restarts.
76542
+ */
76543
+ var EventSubscriptionBus = class {
76544
+ byType = /* @__PURE__ */ new Map();
76545
+ wildcard = /* @__PURE__ */ new Set();
76546
+ /**
76547
+ * Subscribe to a specific event type (or `'*'` for all events).
76548
+ * Returns an unsubscribe function.
76549
+ */
76550
+ subscribe(type, handler) {
76551
+ if (type === "*") {
76552
+ this.wildcard.add(handler);
76553
+ return () => {
76554
+ this.wildcard.delete(handler);
76555
+ };
76556
+ }
76557
+ let set = this.byType.get(type);
76558
+ if (set === void 0) {
76559
+ set = /* @__PURE__ */ new Set();
76560
+ this.byType.set(type, set);
76561
+ }
76562
+ set.add(handler);
76563
+ return () => {
76564
+ set.delete(handler);
76565
+ };
76566
+ }
76567
+ /** Drop every subscriber (used on deactivate / session switch). */
76568
+ clear() {
76569
+ this.byType.clear();
76570
+ this.wildcard.clear();
76571
+ }
76572
+ /**
76573
+ * Deliver an event to matching handlers. A handler that throws is isolated
76574
+ * so a subscriber bug can never break the agent's event loop.
76575
+ */
76576
+ dispatch(event) {
76577
+ const typed = this.byType.get(event.type);
76578
+ if (typed !== void 0) for (const handler of typed) try {
76579
+ handler(event);
76580
+ } catch {}
76581
+ if (this.wildcard.size > 0) for (const handler of this.wildcard) try {
76582
+ handler(event);
76583
+ } catch {}
76584
+ }
76585
+ };
76586
+ //#endregion
76457
76587
  //#region ../../packages/agent-core/src/agent/context/projector.ts
76458
76588
  /** Synthetic error text used when a tool result is missing and must be
76459
76589
  * filled in so the provider accepts the message sequence. */
@@ -80033,6 +80163,39 @@ var HookEngine = class {
80033
80163
  for (const [event, hooks] of this.byEvent.entries()) result[event] = hooks.length;
80034
80164
  return result;
80035
80165
  }
80166
+ /**
80167
+ * Register a hook at runtime (e.g. when a plugin activates). Returns an
80168
+ * unregister function for symmetric removal when the plugin deactivates.
80169
+ * The existing constructor-injected hooks are unaffected; the byEvent map
80170
+ * stays the single source of truth so trigger paths need no changes.
80171
+ */
80172
+ register(hook) {
80173
+ const entries = this.byEvent.get(hook.event) ?? [];
80174
+ entries.push(hook);
80175
+ this.byEvent.set(hook.event, entries);
80176
+ return () => {
80177
+ this.unregister(hook);
80178
+ };
80179
+ }
80180
+ /**
80181
+ * Register several hooks at once (e.g. a plugin's manifest hooks). Returns
80182
+ * a single function that unregisters all of them.
80183
+ */
80184
+ registerAll(hooks) {
80185
+ const unregisters = hooks.map((hook) => this.register(hook));
80186
+ return () => {
80187
+ for (const unregister of unregisters) unregister();
80188
+ };
80189
+ }
80190
+ unregister(hook) {
80191
+ const entries = this.byEvent.get(hook.event);
80192
+ if (entries === void 0) return;
80193
+ const index = entries.lastIndexOf(hook);
80194
+ if (index >= 0) {
80195
+ entries.splice(index, 1);
80196
+ if (entries.length === 0) this.byEvent.delete(hook.event);
80197
+ }
80198
+ }
80036
80199
  trigger(event, args = {}) {
80037
80200
  try {
80038
80201
  return this.triggerInner(event, args).catch(() => []);
@@ -98631,6 +98794,8 @@ var Agent = class {
98631
98794
  mcp;
98632
98795
  hooks;
98633
98796
  log;
98797
+ /** In-process event bus for extensions running inside the agent process. */
98798
+ eventBus;
98634
98799
  blobStore;
98635
98800
  records;
98636
98801
  fullCompaction;
@@ -98674,6 +98839,7 @@ var Agent = class {
98674
98839
  this.subagentHost = options.subagentHost;
98675
98840
  this.mcp = options.mcp;
98676
98841
  this.hooks = options.hookEngine;
98842
+ this.eventBus = new EventSubscriptionBus();
98677
98843
  const embedCacheDir = options.screamHomeDir !== void 0 ? join$1(options.screamHomeDir, "cache", "fastembed") : void 0;
98678
98844
  this.sharedEmbeddingEngine = createFastEmbedEngine(embedCacheDir);
98679
98845
  this.log = options.log ?? log;
@@ -99240,6 +99406,7 @@ var Agent = class {
99240
99406
  }
99241
99407
  emitEvent(event) {
99242
99408
  if (this.records.restoring) return;
99409
+ this.eventBus.dispatch(event);
99243
99410
  this.rpc?.emitEvent?.(event)?.catch(() => {});
99244
99411
  }
99245
99412
  emitStatusUpdated() {
@@ -104275,6 +104442,90 @@ function createRPC() {
104275
104442
  return [leftClient, rightClient];
104276
104443
  }
104277
104444
  //#endregion
104445
+ //#region ../../packages/agent-core/src/plugin/runtime/extension.ts
104446
+ /**
104447
+ * Loads and activates code-entry plugins inside the agent process.
104448
+ *
104449
+ * Responsibilities:
104450
+ * - `discover()` — pick plugins whose manifest declares an `entryPoint`
104451
+ * - `load()` — dynamic-import the entry point (cached per path)
104452
+ * - `activate()` — inject declared manifest hooks into the agent's HookEngine,
104453
+ * then call the plugin's `activate(context)`; tools are registered by the
104454
+ * plugin itself via `context.services.tools.registerUserTool`
104455
+ * - `deactivate()` — symmetric removal (hooks + deactivate hook), isolated so
104456
+ * a failing plugin never breaks the agent
104457
+ *
104458
+ * Activation is deliberately lazy (a `/plugin activate` command or explicit
104459
+ * config opt-in), so merely installing a plugin never executes its code.
104460
+ */
104461
+ var ExtensionRuntime = class {
104462
+ loaded = /* @__PURE__ */ new Map();
104463
+ activations = /* @__PURE__ */ new Map();
104464
+ /** Plugins that declare a code entry point, in installation order. */
104465
+ discover(plugins) {
104466
+ const result = [];
104467
+ for (const plugin of plugins) {
104468
+ if (plugin.manifest?.entryPoint === void 0) continue;
104469
+ result.push({
104470
+ pluginId: plugin.id,
104471
+ entryPoint: plugin.manifest.entryPoint,
104472
+ manifest: plugin.manifest
104473
+ });
104474
+ }
104475
+ return result;
104476
+ }
104477
+ /** Import (and cache) an entry point module. Rejects for non-conforming modules. */
104478
+ async load(entryPoint) {
104479
+ const cached = this.loaded.get(entryPoint);
104480
+ if (cached !== void 0) return cached;
104481
+ const module = normalizeExtensionModule(await import(entryPoint));
104482
+ this.loaded.set(entryPoint, module);
104483
+ return module;
104484
+ }
104485
+ /** Activate a discovered plugin against a live agent. */
104486
+ async activate(agent, extension) {
104487
+ if (this.activations.has(extension.pluginId)) throw new Error(`Plugin "${extension.pluginId}" is already active`);
104488
+ const module = await this.load(extension.entryPoint);
104489
+ let hooksUnregister;
104490
+ if (extension.manifest.hooks !== void 0 && extension.manifest.hooks.length > 0) hooksUnregister = agent.hooks?.registerAll(extension.manifest.hooks);
104491
+ const context = {
104492
+ services: agent.services,
104493
+ events: agent.eventBus,
104494
+ config: extension.manifest.config,
104495
+ pluginId: extension.pluginId
104496
+ };
104497
+ try {
104498
+ await module.activate(context);
104499
+ } catch (error) {
104500
+ hooksUnregister?.();
104501
+ throw error;
104502
+ }
104503
+ this.activations.set(extension.pluginId, {
104504
+ module,
104505
+ hooksUnregister
104506
+ });
104507
+ }
104508
+ /** Deactivate a plugin: remove its hooks and call its deactivate hook. */
104509
+ async deactivate(pluginId) {
104510
+ const activation = this.activations.get(pluginId);
104511
+ if (activation === void 0) return;
104512
+ activation.hooksUnregister?.();
104513
+ this.activations.delete(pluginId);
104514
+ await activation.module.deactivate?.();
104515
+ }
104516
+ isActive(pluginId) {
104517
+ return this.activations.has(pluginId);
104518
+ }
104519
+ activePluginIds() {
104520
+ return [...this.activations.keys()];
104521
+ }
104522
+ };
104523
+ function normalizeExtensionModule(mod) {
104524
+ const candidate = mod?.default ?? mod;
104525
+ if (candidate === void 0 || typeof candidate.activate !== "function") throw new Error("Plugin entry point must export an activate(context) function");
104526
+ return candidate;
104527
+ }
104528
+ //#endregion
104278
104529
  //#region ../../packages/agent-core/src/tools/providers/fetch-cache.ts
104279
104530
  /**
104280
104531
  * Simple in-memory LRU cache for URL fetch results.
@@ -120593,6 +120844,8 @@ var ScreamCore = class {
120593
120844
  subagentModelBindings;
120594
120845
  sessionStore;
120595
120846
  plugins;
120847
+ /** Loads/activates code-entry plugins (manifest `entryPoint`). */
120848
+ extensionRuntime = new ExtensionRuntime();
120596
120849
  pluginsReady;
120597
120850
  pluginsLoadError;
120598
120851
  constructor(rpcClient, options = {}) {
@@ -120892,6 +121145,37 @@ var ScreamCore = class {
120892
121145
  registerTool({ sessionId, ...payload }) {
120893
121146
  return this.sessionApi(sessionId).registerTool(payload);
120894
121147
  }
121148
+ /**
121149
+ * Activate a code plugin (one with a manifest `entryPoint`) on the session's
121150
+ * main agent: injects declared manifest hooks into the agent's HookEngine and
121151
+ * calls the plugin's `activate(context)`.
121152
+ */
121153
+ async activatePlugin({ sessionId, pluginId }) {
121154
+ await this.pluginsReady;
121155
+ const session = this.sessions.get(sessionId);
121156
+ if (session === void 0) throw new ScreamError(ErrorCodes.SESSION_NOT_FOUND, `Session "${sessionId}" was not found`, { details: { sessionId } });
121157
+ const agent = session.agents.get("main");
121158
+ if (agent === void 0) throw new ScreamError(ErrorCodes.AGENT_NOT_FOUND, `Session "${sessionId}" has no main agent`, { details: { sessionId } });
121159
+ const plugin = this.plugins.list().find((record) => record.id === pluginId);
121160
+ if (plugin === void 0) throw new ScreamError(ErrorCodes.PLUGIN_NOT_FOUND, `Plugin "${pluginId}" was not found`, { details: { pluginId } });
121161
+ const [extension] = this.extensionRuntime.discover([plugin]);
121162
+ if (extension === void 0) throw new ScreamError(ErrorCodes.PLUGIN_NOT_FOUND, `Plugin "${pluginId}" has no code entry point`, { details: { pluginId } });
121163
+ await this.extensionRuntime.activate(agent, extension);
121164
+ }
121165
+ /** Deactivate a code plugin (removes its hooks and runs its deactivate). */
121166
+ async deactivatePlugin({ pluginId }) {
121167
+ await this.pluginsReady;
121168
+ await this.extensionRuntime.deactivate(pluginId);
121169
+ }
121170
+ /** Code plugins the runtime can load, with their activation state. */
121171
+ async pluginExtensionStatus() {
121172
+ await this.pluginsReady;
121173
+ return this.extensionRuntime.discover(this.plugins.list()).map((extension) => ({
121174
+ pluginId: extension.pluginId,
121175
+ entryPoint: extension.entryPoint,
121176
+ active: this.extensionRuntime.isActive(extension.pluginId)
121177
+ }));
121178
+ }
120895
121179
  unregisterTool({ sessionId, ...payload }) {
120896
121180
  return this.sessionApi(sessionId).unregisterTool(payload);
120897
121181
  }
@@ -121792,6 +122076,18 @@ var SDKRpcClient = class {
121792
122076
  args: input.args
121793
122077
  });
121794
122078
  }
122079
+ async activatePlugin(input) {
122080
+ return (await this.getRpc()).activatePlugin({
122081
+ sessionId: input.sessionId,
122082
+ pluginId: input.pluginId
122083
+ });
122084
+ }
122085
+ async deactivatePlugin(input) {
122086
+ return (await this.getRpc()).deactivatePlugin({ pluginId: input.pluginId });
122087
+ }
122088
+ async pluginExtensionStatus(input) {
122089
+ return (await this.getRpc()).pluginExtensionStatus({ sessionId: input.sessionId });
122090
+ }
121795
122091
  async undoHistory(input) {
121796
122092
  return (await this.getRpc()).undoHistory({
121797
122093
  sessionId: input.sessionId,
@@ -122261,6 +122557,30 @@ var Session = class {
122261
122557
  });
122262
122558
  }
122263
122559
  /**
122560
+ * Activate a code-entry plugin (manifest `entryPoint`) on the session's main
122561
+ * agent. Lazy and isolated: the plugin's code runs only after this call.
122562
+ */
122563
+ async activatePlugin(pluginId) {
122564
+ this.ensureOpen();
122565
+ await this.rpc.activatePlugin({
122566
+ sessionId: this.id,
122567
+ pluginId
122568
+ });
122569
+ }
122570
+ /** Deactivate a code-entry plugin (removes its hooks, runs its deactivate). */
122571
+ async deactivatePlugin(pluginId) {
122572
+ this.ensureOpen();
122573
+ await this.rpc.deactivatePlugin({
122574
+ sessionId: this.id,
122575
+ pluginId
122576
+ });
122577
+ }
122578
+ /** Code plugins the runtime can load, with their activation state. */
122579
+ async pluginExtensionStatus() {
122580
+ this.ensureOpen();
122581
+ return this.rpc.pluginExtensionStatus({ sessionId: this.id });
122582
+ }
122583
+ /**
122264
122584
  * Remove the last N user-prompt turns from the conversation history.
122265
122585
  * The TUI is responsible for cleaning up the corresponding transcript
122266
122586
  * entries and UI components after this call succeeds.
@@ -123214,16 +123534,20 @@ const BUILTIN_SLASH_COMMANDS = [
123214
123534
  availability: "always"
123215
123535
  },
123216
123536
  {
123217
- name: "skill",
123218
- aliases: [
123219
- "skills",
123220
- "plugin",
123221
- "plugins"
123222
- ],
123223
- description: "registry.skill_desc",
123537
+ name: "plugin",
123538
+ aliases: ["skills", "plugins"],
123539
+ hiddenAliases: ["skill"],
123540
+ description: "registry.plugin_desc",
123224
123541
  priority: 202,
123225
123542
  availability: "always"
123226
123543
  },
123544
+ {
123545
+ name: "extension",
123546
+ aliases: ["extensions"],
123547
+ description: "registry.extension_desc",
123548
+ priority: 203,
123549
+ availability: "always"
123550
+ },
123227
123551
  {
123228
123552
  name: "fork",
123229
123553
  aliases: [],
@@ -123400,7 +123724,7 @@ const BUILTIN_SLASH_COMMANDS = [
123400
123724
  }
123401
123725
  ];
123402
123726
  function findBuiltInSlashCommand(commandName) {
123403
- return BUILTIN_SLASH_COMMANDS.find((command) => command.name === commandName || command.aliases.includes(commandName));
123727
+ return BUILTIN_SLASH_COMMANDS.find((command) => command.name === commandName || command.aliases.includes(commandName) || command.hiddenAliases?.includes(commandName) === true);
123404
123728
  }
123405
123729
  function resolveSlashCommandAvailability(command, args) {
123406
123730
  const availability = command.availability ?? "idle-only";
@@ -129093,7 +129417,7 @@ async function guidedGoalSetup(host) {
129093
129417
  host.showNotice(t("goal.storm_breaker"), t("goal.conflict_loop"));
129094
129418
  return;
129095
129419
  }
129096
- const { TextInputDialogComponent } = await import("./text-input-dialog-D8QuZFfe.mjs");
129420
+ const { TextInputDialogComponent } = await import("./text-input-dialog-Bnu3s0gP.mjs");
129097
129421
  const initialDesc = await promptText(host, TextInputDialogComponent, {
129098
129422
  title: t("goal.setup_title_initial"),
129099
129423
  subtitle: t("goal.setup_desc_hint"),
@@ -129114,7 +129438,7 @@ async function guidedGoalSetup(host) {
129114
129438
  await showGoalConfigWizard(host, session, confirmed.trim() || objective, false);
129115
129439
  }
129116
129440
  async function showGoalConfigWizard(host, session, objective, replace) {
129117
- const { TextInputDialogComponent } = await import("./text-input-dialog-D8QuZFfe.mjs");
129441
+ const { TextInputDialogComponent } = await import("./text-input-dialog-Bnu3s0gP.mjs");
129118
129442
  const turnInput = await promptNumber(host, TextInputDialogComponent, {
129119
129443
  title: t("goal.wizard_title", { objective }),
129120
129444
  subtitle: t("goal.budget_turns_hint"),
@@ -133929,6 +134253,42 @@ function confirmCcConnectUninstall(host, summary) {
133929
134253
  });
133930
134254
  }
133931
134255
  //#endregion
134256
+ //#region src/cli/update/prefix.ts
134257
+ /**
134258
+ * The npm global prefix the running Scream Code was installed into, derived
134259
+ * from the entry script path. Example:
134260
+ *
134261
+ * /Users/tod/.npm-global/lib/node_modules/scream-code/dist/main.mjs
134262
+ * → prefix /Users/tod/.npm-global
134263
+ *
134264
+ * `npm install -g` without `--prefix` uses the user's configured npm prefix,
134265
+ * which may point at a root-owned directory (e.g. /usr/local) and fail with
134266
+ * EACCES even though Scream Code itself lives in a user-writable prefix.
134267
+ * Returns undefined when the layout is unrecognized — the install then falls
134268
+ * back to the default prefix behavior.
134269
+ */
134270
+ function globalPrefixForScream() {
134271
+ const entry = process.argv[1];
134272
+ if (!entry) return void 0;
134273
+ const parts = entry.split(path.sep);
134274
+ const idx = parts.lastIndexOf("node_modules");
134275
+ if (idx < 2 || parts[idx - 1] !== "lib") return void 0;
134276
+ return parts.slice(0, idx - 1).join(path.sep);
134277
+ }
134278
+ /**
134279
+ * Build the `npm install -g scream-code@latest` argument list, adding
134280
+ * `--prefix` when the running Scream Code's global directory can be resolved.
134281
+ */
134282
+ function installLatestArgs() {
134283
+ const prefix = globalPrefixForScream();
134284
+ return [
134285
+ "install",
134286
+ "-g",
134287
+ "scream-code@latest",
134288
+ ...prefix !== void 0 ? ["--prefix", prefix] : []
134289
+ ];
134290
+ }
134291
+ //#endregion
133932
134292
  //#region src/utils/persistence.ts
133933
134293
  /**
133934
134294
  * Small persistence helpers for CLI-owned data files.
@@ -134191,11 +134551,7 @@ async function handleUpdateCommand(host) {
134191
134551
  }
134192
134552
  host.showStatus(t("update.updating", { version: target.version }));
134193
134553
  host.showStatus(t("update.npm_install"));
134194
- const result = await runInstallStep(npmExecutable(), [
134195
- "install",
134196
- "-g",
134197
- "scream-code@latest"
134198
- ], void 0, t("update.install_label"));
134554
+ const result = await runInstallStep(npmExecutable(), installLatestArgs(), void 0, t("update.install_label"));
134199
134555
  if (!result.ok) {
134200
134556
  host.showError(`❌ ${result.message}`);
134201
134557
  return;
@@ -135124,13 +135480,13 @@ function disposeChildren(container) {
135124
135480
  const SKILL_DESC_MAX = 60;
135125
135481
  async function handleSkillCommand(host, _args) {
135126
135482
  if (!host.session) {
135127
- host.showError(t("skill.no_session"));
135483
+ host.showError(t("plugin.no_session"));
135128
135484
  return;
135129
135485
  }
135130
135486
  await openSkillCenter(host);
135131
135487
  }
135132
135488
  async function openSkillCenter(host) {
135133
- const loading = new SkillCenterLoadingComponent(host, t("skill.loading"));
135489
+ const loading = new SkillCenterLoadingComponent(host, t("plugin.loading"));
135134
135490
  host.mountEditorReplacement(loading);
135135
135491
  const [skillsResult, pluginsResult, marketplaceResult] = await Promise.allSettled([
135136
135492
  loadActivatableSkills(host),
@@ -135145,12 +135501,12 @@ async function openSkillCenter(host) {
135145
135501
  const options = buildOptions(host, skills, plugins, marketplace);
135146
135502
  if (options.length === 0) {
135147
135503
  host.restoreEditor();
135148
- host.showNotice(t("skill.center_title"), t("skill.no_skills"));
135504
+ host.showNotice(t("plugin.center_title"), t("plugin.no_plugins"));
135149
135505
  return;
135150
135506
  }
135151
135507
  const picker = new ChoicePickerComponent({
135152
- title: t("skill.center_title"),
135153
- hint: t("skill.footer_hint"),
135508
+ title: t("plugin.center_title"),
135509
+ hint: t("plugin.footer_hint"),
135154
135510
  options,
135155
135511
  colors: host.state.theme.colors,
135156
135512
  searchable: true,
@@ -135230,7 +135586,7 @@ function buildOptions(host, skills, plugins, marketplace) {
135230
135586
  if (skills.length > 0) {
135231
135587
  options.push({
135232
135588
  value: "__section__installed",
135233
- label: "── " + t("skill.installed") + " ──"
135589
+ label: "── " + t("plugin.installed") + " ──"
135234
135590
  });
135235
135591
  for (const skill of skills) {
135236
135592
  const actionKeys = {};
@@ -135257,12 +135613,12 @@ function buildOptions(host, skills, plugins, marketplace) {
135257
135613
  if (installable.length > 0) {
135258
135614
  options.push({
135259
135615
  value: "__section__installable",
135260
- label: "── " + t("skill.installable") + " ──"
135616
+ label: "── " + t("plugin.installable") + " ──"
135261
135617
  });
135262
135618
  for (const entry of installable) options.push({
135263
135619
  value: `install:${entry.source}`,
135264
135620
  label: entry.displayName,
135265
- description: entry.description ? `${truncate(entry.description, SKILL_DESC_MAX)} [${t("skill.not_installed")}]` : `[${t("skill.not_installed")}]`,
135621
+ description: entry.description ? `${truncate(entry.description, SKILL_DESC_MAX)} [${t("plugin.not_installed")}]` : `[${t("plugin.not_installed")}]`,
135266
135622
  actionKeys: { i: () => {
135267
135623
  host.restoreEditor();
135268
135624
  installInjectActivate(host, entry.source);
@@ -135289,12 +135645,12 @@ async function handleSelect(host, value, skills, _plugins, _marketplace) {
135289
135645
  async function activateSkillByName(host, name, skills) {
135290
135646
  const session = host.session;
135291
135647
  if (!session) {
135292
- host.showError(t("skill.no_session_activate"));
135648
+ host.showError(t("plugin.no_session_activate"));
135293
135649
  return;
135294
135650
  }
135295
135651
  const skill = skills.find((s) => s.name === name);
135296
135652
  if (!skill) {
135297
- host.showError(t("skill.not_found"));
135653
+ host.showError(t("plugin.not_found"));
135298
135654
  return;
135299
135655
  }
135300
135656
  host.sendSkillActivation(session, skill.name, "");
@@ -135302,20 +135658,20 @@ async function activateSkillByName(host, name, skills) {
135302
135658
  async function installInjectActivate(host, source) {
135303
135659
  const session = host.session;
135304
135660
  if (!session) {
135305
- host.showError(t("skill.no_session_activate"));
135661
+ host.showError(t("plugin.no_session_activate"));
135306
135662
  return;
135307
135663
  }
135308
- const spinner = host.showProgressSpinner(t("skill.installing_package"));
135664
+ const spinner = host.showProgressSpinner(t("plugin.installing_package"));
135309
135665
  try {
135310
135666
  const summary = await session.installPlugin(source);
135311
135667
  await session.injectPlugin(summary.id);
135312
135668
  spinner.stop({
135313
135669
  ok: true,
135314
- label: `"${summary.displayName}" ${t("skill.installed_injected")}`
135670
+ label: `"${summary.displayName}" ${t("plugin.installed_injected")}`
135315
135671
  });
135316
135672
  const pluginSkills = (await session.listSkills()).filter((s) => s.pluginId === summary.id && isUserActivatableSkill(s));
135317
135673
  if (pluginSkills.length === 0) {
135318
- host.showNotice(t("skill.plugin_installed"), `${summary.displayName} ${t("skill.no_manual_skill")}`);
135674
+ host.showNotice(t("plugin.plugin_installed"), `${summary.displayName} ${t("plugin.no_manual_plugin")}`);
135319
135675
  return;
135320
135676
  }
135321
135677
  if (pluginSkills.length === 1) {
@@ -135327,9 +135683,9 @@ async function installInjectActivate(host, source) {
135327
135683
  } catch (error) {
135328
135684
  spinner.stop({
135329
135685
  ok: false,
135330
- label: t("skill.install_failed")
135686
+ label: t("plugin.install_failed")
135331
135687
  });
135332
- host.showError(t("skill.install_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135688
+ host.showError(t("plugin.install_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135333
135689
  }
135334
135690
  }
135335
135691
  async function pickAndActivateSkill(host, skills, plugins = []) {
@@ -135341,8 +135697,8 @@ async function pickAndActivateSkill(host, skills, plugins = []) {
135341
135697
  description: formatSkillDescription(skill, plugins)
135342
135698
  }));
135343
135699
  const picker = new ChoicePickerComponent({
135344
- title: t("skill.select_activate"),
135345
- hint: t("skill.select_hint"),
135700
+ title: t("plugin.select_activate"),
135701
+ hint: t("plugin.select_hint"),
135346
135702
  options,
135347
135703
  colors: host.state.theme.colors,
135348
135704
  searchable: true,
@@ -135360,7 +135716,7 @@ async function pickAndActivateSkill(host, skills, plugins = []) {
135360
135716
  async function uninstallByPluginId(host, pluginId, plugin) {
135361
135717
  const session = host.session;
135362
135718
  if (!session) {
135363
- host.showError(t("skill.no_session_activate"));
135719
+ host.showError(t("plugin.no_session_activate"));
135364
135720
  return;
135365
135721
  }
135366
135722
  if (plugin === void 0) try {
@@ -135368,24 +135724,24 @@ async function uninstallByPluginId(host, pluginId, plugin) {
135368
135724
  } catch {}
135369
135725
  const label = plugin?.displayName ?? pluginId;
135370
135726
  const skillCount = plugin?.skillCount;
135371
- if (!await confirmUninstall(host, label, skillCount !== void 0 && skillCount > 0 ? t("skill.uninstall_whole_pkg", { count: skillCount }) : t("skill.uninstall_single"))) {
135727
+ if (!await confirmUninstall(host, label, skillCount !== void 0 && skillCount > 0 ? t("plugin.uninstall_whole_pkg", { count: skillCount }) : t("plugin.uninstall_single"))) {
135372
135728
  await openSkillCenter(host);
135373
135729
  return;
135374
135730
  }
135375
- const spinner = host.showProgressSpinner(`${t("skill.uninstalling")} "${label}"…`);
135731
+ const spinner = host.showProgressSpinner(`${t("plugin.uninstalling")} "${label}"…`);
135376
135732
  try {
135377
135733
  await session.removePlugin(pluginId);
135378
135734
  spinner.stop({
135379
135735
  ok: true,
135380
- label: `"${label}" ${t("skill.uninstalled")}`
135736
+ label: `"${label}" ${t("plugin.uninstalled")}`
135381
135737
  });
135382
- host.showNotice(t("skill.plugin_uninstalled"), t("skill.plugin_removed"));
135738
+ host.showNotice(t("plugin.plugin_uninstalled"), t("plugin.plugin_removed"));
135383
135739
  } catch (error) {
135384
135740
  spinner.stop({
135385
135741
  ok: false,
135386
- label: t("skill.uninstall_failed")
135742
+ label: t("plugin.uninstall_failed")
135387
135743
  });
135388
- host.showError(t("skill.uninstall_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135744
+ host.showError(t("plugin.uninstall_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135389
135745
  } finally {
135390
135746
  await openSkillCenter(host);
135391
135747
  }
@@ -135393,27 +135749,27 @@ async function uninstallByPluginId(host, pluginId, plugin) {
135393
135749
  async function uninstallManualSkill(host, skill) {
135394
135750
  const session = host.session;
135395
135751
  if (!session) {
135396
- host.showError(t("skill.no_session_activate"));
135752
+ host.showError(t("plugin.no_session_activate"));
135397
135753
  return;
135398
135754
  }
135399
- if (!await confirmUninstall(host, skill.name, t("skill.deleting_skill"))) {
135755
+ if (!await confirmUninstall(host, skill.name, t("plugin.deleting_plugin"))) {
135400
135756
  await openSkillCenter(host);
135401
135757
  return;
135402
135758
  }
135403
- const spinner = host.showProgressSpinner(`${t("skill.deleting")} "${skill.name}"…`);
135759
+ const spinner = host.showProgressSpinner(`${t("plugin.deleting")} "${skill.name}"…`);
135404
135760
  try {
135405
135761
  await session.removeSkill(skill.name);
135406
135762
  spinner.stop({
135407
135763
  ok: true,
135408
- label: `"${skill.name}" ${t("skill.deleted")}`
135764
+ label: `"${skill.name}" ${t("plugin.deleted")}`
135409
135765
  });
135410
- host.showNotice(t("skill.skill_deleted"), t("skill.skill_removed"));
135766
+ host.showNotice(t("plugin.plugin_deleted"), t("plugin.skill_removed"));
135411
135767
  } catch (error) {
135412
135768
  spinner.stop({
135413
135769
  ok: false,
135414
- label: t("skill.delete_failed")
135770
+ label: t("plugin.delete_failed")
135415
135771
  });
135416
- host.showError(t("skill.delete_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135772
+ host.showError(t("plugin.delete_failed_msg", { msg: error instanceof Error ? error.message : String(error) }));
135417
135773
  } finally {
135418
135774
  await openSkillCenter(host);
135419
135775
  }
@@ -135421,14 +135777,14 @@ async function uninstallManualSkill(host, skill) {
135421
135777
  async function confirmUninstall(host, label, description) {
135422
135778
  return new Promise((resolve) => {
135423
135779
  const picker = new ChoicePickerComponent({
135424
- title: t("skill.confirm_uninstall", { label }),
135425
- hint: t("skill.uninstall_reversible"),
135780
+ title: t("plugin.confirm_uninstall", { label }),
135781
+ hint: t("plugin.uninstall_reversible"),
135426
135782
  options: [{
135427
135783
  value: "no",
135428
135784
  label: t("common.cancel")
135429
135785
  }, {
135430
135786
  value: "yes",
135431
- label: t("skill.uninstall_yes"),
135787
+ label: t("plugin.uninstall_yes"),
135432
135788
  tone: "danger",
135433
135789
  description
135434
135790
  }],
@@ -135447,10 +135803,10 @@ async function confirmUninstall(host, label, description) {
135447
135803
  }
135448
135804
  function formatSkillDescription(skill, plugins = []) {
135449
135805
  const parts = [];
135450
- if (skill.source) parts.push(`${t("skill.source_label")} ${skill.source}`);
135806
+ if (skill.source) parts.push(`${t("plugin.source_label")} ${skill.source}`);
135451
135807
  if (skill.pluginId !== void 0) {
135452
135808
  const label = plugins.find((p) => p.id === skill.pluginId)?.displayName ?? skill.pluginId;
135453
- parts.push(`${t("skill.plugin_label")} ${label}`);
135809
+ parts.push(`${t("plugin.plugin_label")} ${label}`);
135454
135810
  }
135455
135811
  if (skill.description) parts.push(truncate(skill.description, SKILL_DESC_MAX));
135456
135812
  return parts.join(" · ");
@@ -135459,6 +135815,68 @@ function truncate(value, max) {
135459
135815
  return value.length > max ? `${value.slice(0, max)}…` : value;
135460
135816
  }
135461
135817
  //#endregion
135818
+ //#region src/tui/commands/extension.ts
135819
+ /**
135820
+ * /extension activate|deactivate|status [pluginId]
135821
+ *
135822
+ * Activates and deactivates code-entry plugins (manifests that declare an
135823
+ * `entryPoint`) on the session's main agent, or lists them with their
135824
+ * activation state. Activation is lazy and isolated: a failing extension never
135825
+ * breaks the agent.
135826
+ */
135827
+ async function handleExtensionCommand(host, args) {
135828
+ const session = host.session;
135829
+ if (!session) {
135830
+ host.showError(t("extension.no_session"));
135831
+ return;
135832
+ }
135833
+ const [action, ...rest] = args.trim().split(/\s+/);
135834
+ const pluginId = rest.join(" ").trim();
135835
+ switch (action === "" || action === void 0 ? "status" : action) {
135836
+ case "activate":
135837
+ if (!pluginId) {
135838
+ host.showError(t("extension.missing_id", { action: "activate" }));
135839
+ return;
135840
+ }
135841
+ try {
135842
+ await session.activatePlugin(pluginId);
135843
+ host.showStatus(t("extension.activated", { pluginId }));
135844
+ } catch (error) {
135845
+ host.showError(getErrorMessage(error));
135846
+ }
135847
+ return;
135848
+ case "deactivate":
135849
+ if (!pluginId) {
135850
+ host.showError(t("extension.missing_id", { action: "deactivate" }));
135851
+ return;
135852
+ }
135853
+ try {
135854
+ await session.deactivatePlugin(pluginId);
135855
+ host.showStatus(t("extension.deactivated", { pluginId }));
135856
+ } catch (error) {
135857
+ host.showError(getErrorMessage(error));
135858
+ }
135859
+ return;
135860
+ case "status":
135861
+ try {
135862
+ const extensions = await session.pluginExtensionStatus();
135863
+ if (extensions.length === 0) {
135864
+ host.showStatus(t("extension.no_extensions"));
135865
+ return;
135866
+ }
135867
+ for (const ext of extensions) host.showStatus(`${ext.active ? "●" : "○"} ${ext.pluginId}`);
135868
+ } catch (error) {
135869
+ host.showError(getErrorMessage(error));
135870
+ }
135871
+ return;
135872
+ default: host.showError(t("extension.usage"));
135873
+ }
135874
+ }
135875
+ function getErrorMessage(error) {
135876
+ if (error === null || error === void 0) return String(error);
135877
+ return String(error?.message ?? error);
135878
+ }
135879
+ //#endregion
135462
135880
  //#region src/tui/commands/btw.ts
135463
135881
  /**
135464
135882
  * /btw — Fast side question without interrupting the main conversation.
@@ -138473,13 +138891,16 @@ async function handleBuiltInSlashCommand(host, name, args) {
138473
138891
  case "make-skill":
138474
138892
  await handleMakeSkillCommand(host, args);
138475
138893
  return;
138476
- case "skill":
138894
+ case "plugin":
138477
138895
  await handleSkillCommand(host, args);
138478
138896
  return;
138897
+ case "extension":
138898
+ await handleExtensionCommand(host, args);
138899
+ return;
138479
138900
  default:
138480
138901
  host.showError(`Unknown slash command: /${String(name)}`);
138481
138902
  return;
138482
138903
  }
138483
138904
  }
138484
138905
  //#endregion
138485
- export { toTerminalHyperlink as $, parseStreamingArgs as $t, highlightLines as A, CLI_UI_MODE as An, ENABLE_TERMINAL_THEME_REPORTING as At, AssistantMessageComponent as B, flushDiagnosticLogs as Bn, isBusy as Bt, UserMessageComponent as C, saveTuiConfig as Cn, contrastTextHex as Ct, ToolCallComponent as D, getLogDir as Dn, DISABLE_TERMINAL_FOCUS_REPORTING as Dt, toggleEmptySessionHint as E, getInputHistoryFile as En, parseOsc11BackgroundTheme as Et, getSharedSpeedTracker as F, saveCatalogCache as Fn, QUERY_TERMINAL_THEME as Ft, resetBreathingClock as G, ErrorCodes as Gn, handleConnectCommand as Gt, WelcomeComponent as H, resolveGlobalLogPath as Hn, FooterComponent as Ht, SkillActivationComponent as I, ScreamHarness as In, TERMINAL_FOCUS_IN as It, handleExportDebugZipCommand as J, STATUS_BULLET as Jt, clearGoalState as K, SCREAM_ERROR_INFO as Kn, handleLogoutCommand as Kt, ReadGroupComponent as L, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as Ln, TERMINAL_FOCUS_OUT as Lt, CachedContainer as M, PRODUCT_NAME as Mn, OSC11_RESPONSE as Mt, ThinkingComponent as N, DEFAULT_CATALOG_URL as Nn, OSC11_RESPONSE_PREFIX as Nt, renderDiffLines as O, detectInstallSource as On, DISABLE_TERMINAL_THEME_REPORTING as Ot, estimateTokens as P, fetchCatalog as Pn, OSC11_RESPONSE_PREFIX_NO_ESC as Pt, handleTitleCommand as Q, isTodoItemShape as Qt, parseReadGroupOutput as R, resolveScreamHome as Rn, TERMINAL_THEME_DARK as Rt, handleRevokeCommand as S, loadTuiConfig as Sn, createThemeStyles as St, isTurnElapsedEnabled as T, getDataDir as Tn, detectTerminalTheme as Tt, BREATHE_CYCLE_MS as U, isScreamError as Un, handleTraceCommand as Ut, AgentGroupComponent as V, log as Vn, isStreaming as Vt, getBreathingFrame as W, isOrphanedToolCallError as Wn, handleSearchCommand as Wt, handleForkCommand as X, argsRecord as Xt, handleExportMdCommand as Y, appendStreamingArgsPreview as Yt, handleInitCommand as Z, formatErrorMessage as Zt, readUpdateCache as _, setExperimentalFlags as _n, showStatusReport as _t, handleSkillCommand as a, EXIT_CONFIRM_WINDOW_MS as an, handleFusionPlanCommand as at, handleCcCommand as b, TuiConfigParseError as bn, createEditorTheme as bt, isPlanExpandable as c, TIP_ROTATION_INTERVAL_MS as cn, handleThemeCommand as ct, handleMemoryCommand as d, getLlmNotSetMessage as dn, showModelPicker as dt, serializeToolResultOutput as en, changeThinkingLevel as et, handleChannelCommand as f, getNoActiveSessionMessage as fn, showPermissionPicker as ft, refreshUpdateCache as g, isExperimentalFlagEnabled as gn, clearInfoPanelState as gt, selectUpdateTarget as h, sortSlashCommands as hn, supportsBalance as ht, buildRoleAdditionalText as i, EMPTY_SESSION_HINT_URL as in, handleEditorCommand as it, langFromPath as j, CLI_USER_AGENT_PRODUCT as jn, OSC11_QUERY as jt, renderDiffLinesClustered as k, CLI_COMMAND_NAME as kn, ENABLE_TERMINAL_FOCUS_REPORTING as kt, MoonLoader as l, getCtrlCHint as ln, handleWolfpackCommand as lt, handleUpdateCommand as m, BUILTIN_SLASH_COMMANDS as mn, refreshProviderBalance as mt, clearEvalPanelState as n, truncateErrorMessage as nn, handleAutoCommand as nt, disposeChildren as o, MAIN_AGENT_ID$1 as on, handleModelCommand as ot, handleMcpCommand as p, buildSkillSlashCommands as pn, showSettingsSelector as pt, refineGoal as q, printableChar as qt, openUrl as r, CHARS_PER_TOKEN as rn, handleCompactCommand as rt, hasDispose as s, SESSION_TIPS as sn, handlePlanCommand as st, dispatchInput as t, stringValue as tn, getModelCycleLevel as tt, formatMemoryMemoForInjection as u, getCtrlDHint as un, handleYoloCommand as ut, appendJsonlLine as v, PIXEL_PULSE_FRAMES as vn, showUsage as vt, isEmptySessionHintDismissed as w, detectShellEnvironment as wn, getColorPalette as wt, getDaemonInstructions as x, TuiLikePreferencesSchema as xn, createMarkdownTheme as xt, readJsonlFile as y, PULSE_WAVE_FRAMES as yn, resolveThemeSync as yt, BackgroundAgentStatusComponent as z, MemoryMemoStore as zn, TERMINAL_THEME_LIGHT as zt };
138906
+ export { handleTitleCommand as $, isTodoItemShape as $t, renderDiffLinesClustered as A, CLI_COMMAND_NAME as An, ENABLE_TERMINAL_FOCUS_REPORTING as At, BackgroundAgentStatusComponent as B, MemoryMemoStore as Bn, TERMINAL_THEME_LIGHT as Bt, handleRevokeCommand as C, loadTuiConfig as Cn, createThemeStyles as Ct, toggleEmptySessionHint as D, getInputHistoryFile as Dn, parseOsc11BackgroundTheme as Dt, isTurnElapsedEnabled as E, getDataDir as En, detectTerminalTheme as Et, estimateTokens as F, fetchCatalog as Fn, OSC11_RESPONSE_PREFIX_NO_ESC as Ft, getBreathingFrame as G, isOrphanedToolCallError as Gn, handleSearchCommand as Gt, AgentGroupComponent as H, log as Hn, isStreaming as Ht, getSharedSpeedTracker as I, saveCatalogCache as In, QUERY_TERMINAL_THEME as It, refineGoal as J, printableChar as Jt, resetBreathingClock as K, ErrorCodes as Kn, handleConnectCommand as Kt, SkillActivationComponent as L, ScreamHarness as Ln, TERMINAL_FOCUS_IN as Lt, langFromPath as M, CLI_USER_AGENT_PRODUCT as Mn, OSC11_QUERY as Mt, CachedContainer as N, PRODUCT_NAME as Nn, OSC11_RESPONSE as Nt, ToolCallComponent as O, getLogDir as On, DISABLE_TERMINAL_FOCUS_REPORTING as Ot, ThinkingComponent as P, DEFAULT_CATALOG_URL as Pn, OSC11_RESPONSE_PREFIX as Pt, handleInitCommand as Q, formatErrorMessage as Qt, ReadGroupComponent as R, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as Rn, TERMINAL_FOCUS_OUT as Rt, getDaemonInstructions as S, TuiLikePreferencesSchema as Sn, createMarkdownTheme as St, isEmptySessionHintDismissed as T, detectShellEnvironment as Tn, getColorPalette as Tt, WelcomeComponent as U, resolveGlobalLogPath as Un, FooterComponent as Ut, AssistantMessageComponent as V, flushDiagnosticLogs as Vn, isBusy as Vt, BREATHE_CYCLE_MS as W, isScreamError as Wn, handleTraceCommand as Wt, handleExportMdCommand as X, appendStreamingArgsPreview as Xt, handleExportDebugZipCommand as Y, STATUS_BULLET as Yt, handleForkCommand as Z, argsRecord as Zt, refreshUpdateCache as _, isExperimentalFlagEnabled as _n, clearInfoPanelState as _t, handleExtensionCommand as a, EMPTY_SESSION_HINT_URL as an, handleEditorCommand as at, readJsonlFile as b, PULSE_WAVE_FRAMES as bn, resolveThemeSync as bt, hasDispose as c, SESSION_TIPS as cn, handlePlanCommand as ct, formatMemoryMemoForInjection as d, getCtrlDHint as dn, handleYoloCommand as dt, parseStreamingArgs as en, toTerminalHyperlink as et, handleMemoryCommand as f, getLlmNotSetMessage as fn, showModelPicker as ft, selectUpdateTarget as g, sortSlashCommands as gn, supportsBalance as gt, handleUpdateCommand as h, BUILTIN_SLASH_COMMANDS as hn, refreshProviderBalance as ht, buildRoleAdditionalText as i, CHARS_PER_TOKEN as in, handleCompactCommand as it, highlightLines as j, CLI_UI_MODE as jn, ENABLE_TERMINAL_THEME_REPORTING as jt, renderDiffLines as k, detectInstallSource as kn, DISABLE_TERMINAL_THEME_REPORTING as kt, isPlanExpandable as l, TIP_ROTATION_INTERVAL_MS as ln, handleThemeCommand as lt, handleMcpCommand as m, buildSkillSlashCommands as mn, showSettingsSelector as mt, clearEvalPanelState as n, stringValue as nn, getModelCycleLevel as nt, handleSkillCommand as o, EXIT_CONFIRM_WINDOW_MS as on, handleFusionPlanCommand as ot, handleChannelCommand as p, getNoActiveSessionMessage as pn, showPermissionPicker as pt, clearGoalState as q, SCREAM_ERROR_INFO as qn, handleLogoutCommand as qt, openUrl as r, truncateErrorMessage as rn, handleAutoCommand as rt, disposeChildren as s, MAIN_AGENT_ID$1 as sn, handleModelCommand as st, dispatchInput as t, serializeToolResultOutput as tn, changeThinkingLevel as tt, MoonLoader as u, getCtrlCHint as un, handleWolfpackCommand as ut, readUpdateCache as v, setExperimentalFlags as vn, showStatusReport as vt, UserMessageComponent as w, saveTuiConfig as wn, contrastTextHex as wt, handleCcCommand as x, TuiConfigParseError as xn, createEditorTheme as xt, appendJsonlLine as y, PIXEL_PULSE_FRAMES as yn, showUsage as yt, parseReadGroupOutput as z, resolveScreamHome as zn, TERMINAL_THEME_DARK as zt };
package/dist/main.mjs CHANGED
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
7
  //#region src/main.ts
8
8
  try {
9
- (await import("./app-CbuCmlQV.mjs")).main();
9
+ (await import("./app-CJGX8qct.mjs")).main();
10
10
  } catch (error) {
11
11
  process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
12
12
  process.exit(1);
@@ -572,42 +572,48 @@ const dictionaries = {
572
572
  "memory.experience_label": "经验: ",
573
573
  "memory.note_label": "笔记: ",
574
574
  "memory.detail_nav_hint": " Enter/Esc 返回 | i 注入 | d 删除",
575
- "skill.no_session": "请先创建或恢复一个会话,再使用 Skill 中心。",
576
- "skill.loading": "正在加载 Skill 中心…",
577
- "skill.center_title": "Skill 中心",
578
- "skill.no_skills": "当前没有已安装 Skill 也没有可安装 Skill 包。",
579
- "skill.footer_hint": "Enter 激活/安装 · d 卸载 · i 安装并注入 · Esc 返回",
580
- "skill.installed": "已安装的 Skill",
581
- "skill.installable": "可安装的 Skill 包",
582
- "skill.not_installed": "未安装",
583
- "skill.no_session_activate": "未连接到会话。请先创建或恢复一个会话。",
584
- "skill.not_found": "未找到 Skill",
585
- "skill.installing_package": "正在安装 Skill 包…",
586
- "skill.installed_injected": "已安装并注入当前会话。",
587
- "skill.plugin_installed": "插件已安装",
588
- "skill.no_manual_skill": "已成功安装,但该包没有可手动激活的 Skill。",
589
- "skill.install_failed": "安装失败。",
590
- "skill.install_failed_msg": "安装失败: {msg}",
591
- "skill.select_activate": "选择一个 Skill 激活",
592
- "skill.select_hint": "Enter 激活 · Esc 返回",
593
- "skill.uninstall_whole_pkg": "将卸载整个包(共 {count} 个 Skill),无法只删除单个 Skill",
594
- "skill.uninstall_single": "将卸载整个 Skill 包",
595
- "skill.uninstalling": "正在卸载",
596
- "skill.uninstalled": "已卸载。",
597
- "skill.plugin_uninstalled": "插件已卸载",
598
- "skill.plugin_removed": "该插件的 Skill 已从当前会话中移除,无需重启会话。",
599
- "skill.uninstall_failed": "卸载失败。",
600
- "skill.uninstall_failed_msg": "卸载失败: {msg}",
601
- "skill.deleting_skill": "将删除该 Skill 的安装目录及子 Skill",
602
- "skill.deleting": "正在删除",
603
- "skill.deleted": "已删除。",
604
- "skill.skill_deleted": "Skill 已删除",
605
- "skill.skill_removed": "该 Skill 及其子 Skill 已从当前会话中移除。",
606
- "skill.delete_failed": "删除失败。",
607
- "skill.delete_failed_msg": "删除失败: {msg}",
608
- "skill.confirm_uninstall": "确认卸载 \"{label}\"?",
609
- "skill.uninstall_reversible": "卸载后可在 Skill 中心重新安装",
610
- "skill.uninstall_yes": "是,卸载",
575
+ "plugin.no_session": "请先创建或恢复一个会话,再使用 Plugin 中心。",
576
+ "extension.no_session": "请先创建或恢复一个会话,再使用扩展命令。",
577
+ "extension.usage": "用法:/extension activate|deactivate|status [pluginId]",
578
+ "extension.missing_id": "缺少扩展 id:/extension {action} <pluginId>",
579
+ "extension.activated": "扩展 {pluginId} 已激活。",
580
+ "extension.deactivated": "扩展 {pluginId} 已停用。",
581
+ "extension.no_extensions": "没有安装代码插件(entryPoint)。",
582
+ "plugin.loading": "正在加载 Plugin 中心…",
583
+ "plugin.center_title": "Plugin 中心",
584
+ "plugin.no_plugins": "当前没有已安装 Plugin 也没有可安装 Plugin 包。",
585
+ "plugin.footer_hint": "Enter 激活/安装 · d 卸载 · i 安装并注入 · Esc 返回",
586
+ "plugin.installed": "已安装的 Plugin",
587
+ "plugin.installable": "可安装的 Plugin 包",
588
+ "plugin.not_installed": "未安装",
589
+ "plugin.no_session_activate": "未连接到会话。请先创建或恢复一个会话。",
590
+ "plugin.not_found": "未找到 Plugin",
591
+ "plugin.installing_package": "正在安装 Plugin 包…",
592
+ "plugin.installed_injected": "已安装并注入当前会话。",
593
+ "plugin.plugin_installed": "插件已安装",
594
+ "plugin.no_manual_plugin": "已成功安装,但该包没有可手动激活的 Plugin。",
595
+ "plugin.install_failed": "安装失败。",
596
+ "plugin.install_failed_msg": "安装失败: {msg}",
597
+ "plugin.select_activate": "选择一个 Plugin 激活",
598
+ "plugin.select_hint": "Enter 激活 · Esc 返回",
599
+ "plugin.uninstall_whole_pkg": "将卸载整个包(共 {count} 个 Plugin),无法只删除单个 Plugin",
600
+ "plugin.uninstall_single": "将卸载整个 Plugin 包",
601
+ "plugin.uninstalling": "正在卸载",
602
+ "plugin.uninstalled": "已卸载。",
603
+ "plugin.plugin_uninstalled": "插件已卸载",
604
+ "plugin.plugin_removed": "该插件的 Plugin 已从当前会话中移除,无需重启会话。",
605
+ "plugin.uninstall_failed": "卸载失败。",
606
+ "plugin.uninstall_failed_msg": "卸载失败: {msg}",
607
+ "plugin.deleting_plugin": "将删除该 Plugin 的安装目录及子 Plugin",
608
+ "plugin.deleting": "正在删除",
609
+ "plugin.deleted": "已删除。",
610
+ "plugin.plugin_deleted": "Plugin 已删除",
611
+ "plugin.skill_removed": "该 Plugin 及其子 Plugin 已从当前会话中移除。",
612
+ "plugin.delete_failed": "删除失败。",
613
+ "plugin.delete_failed_msg": "删除失败: {msg}",
614
+ "plugin.confirm_uninstall": "确认卸载 \"{label}\"?",
615
+ "plugin.uninstall_reversible": "卸载后可在 Plugin 中心重新安装",
616
+ "plugin.uninstall_yes": "是,卸载",
611
617
  "toolcall.bg_agent_lost": "后台 agent 丢失(会话在完成前已重启)",
612
618
  "toolcall.bg_agent_terminated": "后台 agent 已终止",
613
619
  "toolcall.bg_agent_failed": "后台 agent 失败",
@@ -695,8 +701,8 @@ const dictionaries = {
695
701
  "replay.bg_failed_suffix": " 在后台失败",
696
702
  "replay.bg_lost_suffix": " 在后台丢失",
697
703
  "replay.bg_stopped_suffix": " stopped",
698
- "skill.source_label": "来源:",
699
- "skill.plugin_label": "插件:",
704
+ "plugin.source_label": "来源:",
705
+ "plugin.plugin_label": "插件:",
700
706
  "taskbrowser.running": "运行中",
701
707
  "taskbrowser.awaiting": "等待中",
702
708
  "taskbrowser.completed": "已完成",
@@ -877,7 +883,7 @@ const dictionaries = {
877
883
  "skillact.user_trigger": "(用户触发)",
878
884
  "skillact.model_trigger": "(模型调用)",
879
885
  "skillact.nested_trigger": "(嵌套调用)",
880
- "skillact.activated": "▶ 已激活 skill:",
886
+ "skillact.activated": "▶ 已激活插件:",
881
887
  "mediaurl.audio": "音频",
882
888
  "mediaurl.image": "图片",
883
889
  "mediaurl.video": "视频",
@@ -885,7 +891,7 @@ const dictionaries = {
885
891
  "transcript.assistant": "助手:",
886
892
  "transcript.thinking": "思考:",
887
893
  "transcript.tool_name": "工具 {name}:",
888
- "transcript.activated_skill": "已激活技能:{name}",
894
+ "transcript.activated_skill": "已激活插件:{name}",
889
895
  "transcript.more_history": "↑ 还有 {count} 条历史消息",
890
896
  "compaction.done": "压缩完成",
891
897
  "compaction.canceled": "压缩已取消",
@@ -1110,7 +1116,8 @@ const dictionaries = {
1110
1116
  "onboarding.hint": "Enter=确认 Up/Down=选择 Esc=跳过",
1111
1117
  "registry.like_desc": "设置你的偏好(昵称、语气、其他偏好)",
1112
1118
  "registry.mcp_desc": "管理 MCP 服务器(安装/停用/卸载)",
1113
- "registry.skill_desc": "技能中心,管理 Skill 技能,含激活、安装、卸载等",
1119
+ "registry.plugin_desc": "插件中心,管理插件,含激活、安装、卸载等",
1120
+ "registry.extension_desc": "代码扩展,激活或停用插件入口",
1114
1121
  "registry.cc_desc": "操控你的cc(启动/关闭/重启)",
1115
1122
  "registry.cc_connect_desc": "cc-connect 快速通道配置(需先安装)",
1116
1123
  "registry.revoke_desc": "撤回上一次对话(可指定轮数,如 /revoke 3)",
@@ -1645,42 +1652,48 @@ const dictionaries = {
1645
1652
  "memory.experience_label": "Experience: ",
1646
1653
  "memory.note_label": "Note: ",
1647
1654
  "memory.detail_nav_hint": " Enter/Esc Back | i Inject | d Delete",
1648
- "skill.no_session": "Please create or resume a session before using the Skill center.",
1649
- "skill.loading": "Loading Skill center…",
1650
- "skill.center_title": "Skill Center",
1651
- "skill.no_skills": "No skills installed and no skill packages available.",
1652
- "skill.footer_hint": "Enter activate/install · d uninstall · i install & inject · Esc back",
1653
- "skill.installed": "Installed Skills",
1654
- "skill.installable": "Available Skill Packages",
1655
- "skill.not_installed": "Not installed",
1656
- "skill.no_session_activate": "Not connected to a session. Please create or resume one first.",
1657
- "skill.not_found": "Skill not found",
1658
- "skill.installing_package": "Installing skill package…",
1659
- "skill.installed_injected": "Installed and injected into current session.",
1660
- "skill.plugin_installed": "Plugin installed",
1661
- "skill.no_manual_skill": "Installed successfully, but this package has no manually activatable skills.",
1662
- "skill.install_failed": "Install failed.",
1663
- "skill.install_failed_msg": "Install failed: {msg}",
1664
- "skill.select_activate": "Select a Skill to activate",
1665
- "skill.select_hint": "Enter to activate · Esc to go back",
1666
- "skill.uninstall_whole_pkg": "Will uninstall the entire package ({count} skills). Cannot remove individual skills.",
1667
- "skill.uninstall_single": "Will uninstall the entire Skill package",
1668
- "skill.uninstalling": "Uninstalling",
1669
- "skill.uninstalled": "Uninstalled.",
1670
- "skill.plugin_uninstalled": "Plugin uninstalled",
1671
- "skill.plugin_removed": "This plugin's skills have been removed from the current session. No restart needed.",
1672
- "skill.uninstall_failed": "Uninstall failed.",
1673
- "skill.uninstall_failed_msg": "Uninstall failed: {msg}",
1674
- "skill.deleting_skill": "Will delete the skill directory and sub-skills",
1675
- "skill.deleting": "Deleting",
1676
- "skill.deleted": "Deleted.",
1677
- "skill.skill_deleted": "Skill deleted",
1678
- "skill.skill_removed": "This skill and its sub-skills have been removed from the current session.",
1679
- "skill.delete_failed": "Delete failed.",
1680
- "skill.delete_failed_msg": "Delete failed: {msg}",
1681
- "skill.confirm_uninstall": "Uninstall \"{label}\"?",
1682
- "skill.uninstall_reversible": "You can reinstall from the Skill center later",
1683
- "skill.uninstall_yes": "Yes, uninstall",
1655
+ "plugin.no_session": "Please create or resume a session before using the Plugin center.",
1656
+ "extension.no_session": "Please create or resume a session before using extension commands.",
1657
+ "extension.usage": "Usage: /extension activate|deactivate|status [pluginId]",
1658
+ "extension.missing_id": "Missing plugin id: /extension {action} <pluginId>",
1659
+ "extension.activated": "Extension {pluginId} activated.",
1660
+ "extension.deactivated": "Extension {pluginId} deactivated.",
1661
+ "extension.no_extensions": "No code extensions (entryPoint) installed.",
1662
+ "plugin.loading": "Loading Plugin center…",
1663
+ "plugin.center_title": "Plugin Center",
1664
+ "plugin.no_plugins": "No plugins installed and no plugin packages available.",
1665
+ "plugin.footer_hint": "Enter activate/install · d uninstall · i install & inject · Esc back",
1666
+ "plugin.installed": "Installed Plugins",
1667
+ "plugin.installable": "Available Plugin Packages",
1668
+ "plugin.not_installed": "Not installed",
1669
+ "plugin.no_session_activate": "Not connected to a session. Please create or resume one first.",
1670
+ "plugin.not_found": "Plugin not found",
1671
+ "plugin.installing_package": "Installing plugin package…",
1672
+ "plugin.installed_injected": "Installed and injected into current session.",
1673
+ "plugin.plugin_installed": "Plugin installed",
1674
+ "plugin.no_manual_plugin": "Installed successfully, but this package has no manually activatable plugins.",
1675
+ "plugin.install_failed": "Install failed.",
1676
+ "plugin.install_failed_msg": "Install failed: {msg}",
1677
+ "plugin.select_activate": "Select a Plugin to activate",
1678
+ "plugin.select_hint": "Enter to activate · Esc to go back",
1679
+ "plugin.uninstall_whole_pkg": "Will uninstall the entire package ({count} plugins). Cannot remove individual plugins.",
1680
+ "plugin.uninstall_single": "Will uninstall the entire Plugin package",
1681
+ "plugin.uninstalling": "Uninstalling",
1682
+ "plugin.uninstalled": "Uninstalled.",
1683
+ "plugin.plugin_uninstalled": "Plugin uninstalled",
1684
+ "plugin.plugin_removed": "This plugin's plugins have been removed from the current session. No restart needed.",
1685
+ "plugin.uninstall_failed": "Uninstall failed.",
1686
+ "plugin.uninstall_failed_msg": "Uninstall failed: {msg}",
1687
+ "plugin.deleting_plugin": "Will delete the plugin directory and sub-plugins",
1688
+ "plugin.deleting": "Deleting",
1689
+ "plugin.deleted": "Deleted.",
1690
+ "plugin.plugin_deleted": "Plugin deleted",
1691
+ "plugin.skill_removed": "This plugin and its sub-plugins have been removed from the current session.",
1692
+ "plugin.delete_failed": "Delete failed.",
1693
+ "plugin.delete_failed_msg": "Delete failed: {msg}",
1694
+ "plugin.confirm_uninstall": "Uninstall \"{label}\"?",
1695
+ "plugin.uninstall_reversible": "You can reinstall from the Plugin center later",
1696
+ "plugin.uninstall_yes": "Yes, uninstall",
1684
1697
  "toolcall.bg_agent_lost": "Background agent lost (session restarted before completion)",
1685
1698
  "toolcall.bg_agent_terminated": "Background agent terminated",
1686
1699
  "toolcall.bg_agent_failed": "Background agent failed",
@@ -1768,8 +1781,8 @@ const dictionaries = {
1768
1781
  "replay.bg_failed_suffix": " failed in background",
1769
1782
  "replay.bg_lost_suffix": " lost in background",
1770
1783
  "replay.bg_stopped_suffix": " stopped",
1771
- "skill.source_label": "Source:",
1772
- "skill.plugin_label": "Plugin:",
1784
+ "plugin.source_label": "Source:",
1785
+ "plugin.plugin_label": "Plugin:",
1773
1786
  "taskbrowser.running": "running",
1774
1787
  "taskbrowser.awaiting": "awaiting",
1775
1788
  "taskbrowser.completed": "completed",
@@ -1950,7 +1963,7 @@ const dictionaries = {
1950
1963
  "skillact.user_trigger": "(user triggered)",
1951
1964
  "skillact.model_trigger": "(model invoked)",
1952
1965
  "skillact.nested_trigger": "(nested call)",
1953
- "skillact.activated": "▶ Activated skill: ",
1966
+ "skillact.activated": "▶ Activated plugin: ",
1954
1967
  "mediaurl.audio": "Audio",
1955
1968
  "mediaurl.image": "Image",
1956
1969
  "mediaurl.video": "Video",
@@ -1958,7 +1971,7 @@ const dictionaries = {
1958
1971
  "transcript.assistant": "Assistant: ",
1959
1972
  "transcript.thinking": "Thinking: ",
1960
1973
  "transcript.tool_name": "Tool {name}: ",
1961
- "transcript.activated_skill": "Activated skill: {name}",
1974
+ "transcript.activated_skill": "Activated plugin: {name}",
1962
1975
  "transcript.more_history": "↑ {count} more history message(s)",
1963
1976
  "compaction.done": "Compaction complete",
1964
1977
  "compaction.canceled": "Compaction cancelled",
@@ -2183,7 +2196,8 @@ const dictionaries = {
2183
2196
  "onboarding.hint": "Enter=confirm Up/Down=choose Esc=skip",
2184
2197
  "registry.like_desc": "Set your preferences (nickname, tone, other)",
2185
2198
  "registry.mcp_desc": "Manage MCP servers (install/disable/uninstall)",
2186
- "registry.skill_desc": "Skill center, manage Skills including activate, install, uninstall",
2199
+ "registry.plugin_desc": "Plugin center, manage plugins including activate, install, uninstall",
2200
+ "registry.extension_desc": "Code extensions, activate or deactivate a plugin entry point",
2187
2201
  "registry.cc_desc": "Control your cc (start/stop/restart)",
2188
2202
  "registry.cc_connect_desc": "cc-connect quick channel setup (requires installation)",
2189
2203
  "registry.revoke_desc": "Undo last conversation round (specify rounds, e.g. /revoke 3)",
@@ -3,5 +3,5 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
3
3
  import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
- import { t as TextInputDialogComponent } from "./text-input-dialog-DstXBOl9.mjs";
6
+ import { t as TextInputDialogComponent } from "./text-input-dialog-B9Klg3re.mjs";
7
7
  export { TextInputDialogComponent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scream-code",
3
- "version": "0.13.6",
3
+ "version": "0.13.8",
4
4
  "description": "A terminal-native AI agent for builders",
5
5
  "license": "MIT",
6
6
  "author": "ScreamCli",