@sema-agent/cli 1.0.42 → 1.0.44

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sema-agent/cli",
3
- "version": "1.0.42",
3
+ "version": "1.0.44",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sema-agent/cli",
9
- "version": "1.0.42",
9
+ "version": "1.0.44",
10
10
  "license": "BUSL-1.1",
11
11
  "dependencies": {
12
12
  "@sema-agent/sdk": "0.0.63",
@@ -629,9 +629,9 @@
629
629
  }
630
630
  },
631
631
  "node_modules/@sema-agent/core": {
632
- "version": "1.361.0",
633
- "resolved": "https://registry.npmjs.org/@sema-agent/core/-/core-1.361.0.tgz",
634
- "integrity": "sha512-Avbmu1VfaWuLFM7kv0Y4TDv3MDoIPeqrBaztgX9F7XyUBwYyV8axfhn9M6Xly6NYH692SXJM9PlwVxTPUp5+bA==",
632
+ "version": "1.362.0",
633
+ "resolved": "https://registry.npmjs.org/@sema-agent/core/-/core-1.362.0.tgz",
634
+ "integrity": "sha512-pfr7dIhKdsw7T8WT4QsCYebXbZtcL9ALjCwalSFpjsTYl3Qhlk0walUrB03rwQBGP9TW4COL7mX9tRgM3KYXwA==",
635
635
  "license": "BUSL-1.1",
636
636
  "dependencies": {
637
637
  "@modelcontextprotocol/sdk": "1.29.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/cli",
3
- "version": "1.0.42",
3
+ "version": "1.0.44",
4
4
  "description": "Sema — your own Claude Code-grade coding agent, in the terminal.",
5
5
  "license": "BUSL-1.1",
6
6
  "bin": {
@@ -25,10 +25,10 @@
25
25
  "@sema-agent/server": "1.242.0"
26
26
  },
27
27
  "overrides": {
28
- "@sema-agent/core": "1.361.0",
28
+ "@sema-agent/core": "1.362.0",
29
29
  "@sema-agent/registry-core": "0.10.21"
30
30
  },
31
- "semaEngineVersion": "server 1.242.0 / core 1.361.0 / registry-core 0.10.21",
31
+ "semaEngineVersion": "server 1.242.0 / core 1.362.0 / registry-core 0.10.21",
32
32
  "engines": {
33
33
  "node": ">=18"
34
34
  }
package/sema.js CHANGED
@@ -208481,9 +208481,13 @@ function getSemaGuideBasePrompt() {
208481
208481
  const localSearchHint = hasEmbeddedSearchTools() ? `${FILE_READ_TOOL_NAME}, \`find\`, and \`grep\`` : `${FILE_READ_TOOL_NAME}, ${GLOB_TOOL_NAME}, and ${GREP_TOOL_NAME}`;
208482
208482
  return `You are the sema guide agent. Your primary responsibility is helping users understand and use sema (the CLI tool) effectively.
208483
208483
 
208484
+ **Product identity (ground truth \u2014 never contradict this):**
208485
+
208486
+ sema is an AI coding CLI that is fully Sema-compatible and a superset of it. The Sema ecosystem works unchanged: CLAUDE.md project memory, .claude/ project config, plugin marketplaces (/plugin), skills (/skills), MCP servers, hooks, and custom subagents. When external docs or tutorials reference the \`claude\` command, the sema equivalent is the same command with \`sema\` substituted (e.g. \`sema mcp add X\` \u2192 \`sema mcp add X\`). Beyond Sema, sema adds: a local engine process the TUI drives, model freedom via the Model Hub (/model in-session or \`sema model\` \u2014 any provider, roles/tiers configurable), cloud switching (\`sema cloud\` for cloud registry profiles and sign-in; service/store/exec axes each local or cloud), \`sema config\`, guided \`sema onboard\`, Sema data import (\`sema import\`), background sessions (\`sema ps\`/\`sema logs\`/\`sema attach\`/\`sema kill\`), and diagnostics (\`sema doctor\`, /doctor).
208487
+
208484
208488
  **Your expertise:**
208485
208489
 
208486
- sema (the CLI tool): installation, configuration, settings files (~/.sema/settings.json and project .sema/), hooks, custom skills and slash commands, MCP server configuration, custom subagents (.sema/agents/), model and tier-group configuration, workflows, keyboard shortcuts, and everyday usage.
208490
+ sema (the CLI tool): installation, configuration, settings files (~/.sema/settings.json and project .sema/), hooks, custom skills and slash commands, MCP server configuration, custom subagents (.sema/agents/), model and tier-group configuration, cloud registry profiles, workflows, keyboard shortcuts, and everyday usage.
208487
208491
 
208488
208492
  **Approach:**
208489
208493
  1. Prefer the user's LOCAL ground truth: the project's memory/config files (CLAUDE.md, the .sema/ directory), the user's ~/.sema settings, and the configuration surfaced to you below.
@@ -244614,13 +244618,17 @@ __export(engineSideChannel_exports, {
244614
244618
  });
244615
244619
  import { readFileSync as readFileSync23 } from "node:fs";
244616
244620
  import { join as join73 } from "node:path";
244617
- async function sideQueryCapable(client4, baseUrl, signal) {
244621
+ async function sideQueryCapable(client4, baseUrl, budget, signal) {
244618
244622
  const hit = sideQueryCapByBase.get(baseUrl);
244619
- if (hit !== void 0) return hit;
244623
+ if (hit && (hit.ok || Date.now() - hit.at < CAP_FALSE_RETRY_TTL_MS)) return hit.ok;
244620
244624
  try {
244621
- const caps = await withTimeoutSignal(CAPS_PROBE_TIMEOUT_MS, signal, (s) => client4.capabilities({ signal: s }));
244625
+ const caps = await withTimeoutSignal(
244626
+ Math.min(CAPS_PROBE_TIMEOUT_MS, budget.remaining()),
244627
+ signal,
244628
+ (s) => client4.capabilities({ signal: s })
244629
+ );
244622
244630
  const ok2 = caps.sideQuery === true;
244623
- sideQueryCapByBase.set(baseUrl, ok2);
244631
+ sideQueryCapByBase.set(baseUrl, { ok: ok2, at: Date.now() });
244624
244632
  return ok2;
244625
244633
  } catch {
244626
244634
  return false;
@@ -244686,7 +244694,11 @@ async function resolvePoolModelRef(callerModel) {
244686
244694
  return void 0;
244687
244695
  }
244688
244696
  }
244689
- async function engineUtilityText(opts) {
244697
+ function makeBudget(totalMs) {
244698
+ const start = Date.now();
244699
+ return { remaining: () => Math.max(1, totalMs - (Date.now() - start)) };
244700
+ }
244701
+ async function engineUtilityCall(opts) {
244690
244702
  const baseUrl = process.env.SEMA_LIVE_BASEURL;
244691
244703
  if (!baseUrl) return null;
244692
244704
  const token = resolveEngineToken();
@@ -244696,117 +244708,90 @@ async function engineUtilityText(opts) {
244696
244708
  principal: process.env.SEMA_LIVE_PRINCIPAL ?? "anon:shell-live"
244697
244709
  });
244698
244710
  if (!client4) throw new Error("sema engine side-channel: wire client unavailable");
244699
- const cheap = process.env.MODEL_CHEAP_ID?.trim() || void 0;
244700
- const timeoutMs = opts.timeoutMs ?? SIDE_CHANNEL_TIMEOUT_MS;
244711
+ const cheap = opts.cheapSlot ? process.env.MODEL_CHEAP_ID?.trim() || void 0 : void 0;
244712
+ const budget = makeBudget(opts.timeoutMs ?? SIDE_CHANNEL_TIMEOUT_MS);
244713
+ const firstModel = opts.modelRef ?? cheap;
244701
244714
  const statusOf2 = (e) => {
244702
244715
  const s = e?.status;
244703
244716
  return typeof s === "number" ? s : void 0;
244704
244717
  };
244705
- const firstModel = opts.modelRef ?? cheap;
244706
- if (await sideQueryCapable(client4, baseUrl, opts.signal)) {
244707
- const query2 = (model) => withTimeoutSignal(
244708
- timeoutMs,
244718
+ const tasksArm = async () => {
244719
+ const submit = (model) => withTimeoutSignal(
244720
+ budget.remaining(),
244709
244721
  opts.signal,
244710
- (signal) => client4.sideQuery.query(
244722
+ (signal) => client4.tasks.submit(
244711
244723
  {
244712
- messages: [{ role: "user", content: opts.objective }],
244724
+ objective: opts.objective,
244725
+ sessionId: mintSideSessionId(),
244726
+ // 独立 session:utility 提示词绝不进主会话历史
244713
244727
  ...model ? { model } : {},
244714
- ...opts.maxTokens ? { maxOutputTokens: opts.maxTokens } : {}
244728
+ ...opts.maxTokens ? { maxTokens: opts.maxTokens } : {},
244729
+ ...opts.systemPrompt ? { systemPrompt: opts.systemPrompt } : {},
244730
+ ...opts.excludeTools ? { excludeTools: [...opts.excludeTools] } : {}
244715
244731
  },
244716
- { signal }
244732
+ { signal, idempotencyKey: null }
244717
244733
  )
244718
244734
  );
244719
- let r;
244735
+ let data;
244720
244736
  try {
244721
- r = await query2(firstModel);
244737
+ data = await submit(firstModel);
244722
244738
  } catch (e) {
244723
244739
  const status3 = statusOf2(e);
244724
244740
  if (opts.noFallback || status3 === void 0 || !firstModel || !CATALOG_GATE_STATUSES.has(status3)) throw e;
244725
- logForDebugging(`[side-channel] side-query ${status3} with model=${firstModel} \u2014 retrying on the default model`);
244726
- r = await query2(void 0);
244727
- }
244728
- return sideQueryTextOf(r);
244729
- }
244730
- const submit = (model) => withTimeoutSignal(
244731
- timeoutMs,
244732
- opts.signal,
244733
- (signal) => client4.tasks.submit(
244734
- {
244735
- objective: opts.objective,
244736
- sessionId: mintSideSessionId(),
244737
- // 独立 session:utility 提示词绝不进主会话历史
244738
- ...model ? { model } : {},
244739
- ...opts.maxTokens ? { maxTokens: opts.maxTokens } : {}
244740
- },
244741
- { signal, idempotencyKey: null }
244742
- )
244743
- );
244744
- let data;
244745
- try {
244746
- data = await submit(firstModel);
244747
- } catch (e) {
244748
- const status3 = statusOf2(e);
244749
- if (opts.noFallback || status3 === void 0 || !firstModel || !CATALOG_GATE_STATUSES.has(status3)) throw e;
244750
- logForDebugging(`[side-channel] engine ${status3} with model=${firstModel} \u2014 retrying on the default model`);
244751
- data = await submit(void 0);
244752
- }
244753
- const text2 = typeof data.result === "string" ? data.result.trim() : "";
244754
- if (!text2) throw new Error("sema engine side-channel: empty result");
244755
- return text2;
244756
- }
244757
- async function engineUtilityTask(opts) {
244758
- const baseUrl = process.env.SEMA_LIVE_BASEURL;
244759
- if (!baseUrl) throw new Error("sema engine side-channel: not active");
244760
- const token = resolveEngineToken();
244761
- const client4 = makeEngineWireClient({
244762
- baseUrl,
244763
- ...token ? { token } : {},
244764
- principal: process.env.SEMA_LIVE_PRINCIPAL ?? "anon:shell-live"
244765
- });
244766
- if (!client4) throw new Error("sema engine side-channel: wire client unavailable");
244767
- const timeoutMs = opts.timeoutMs ?? SIDE_CHANNEL_TIMEOUT_MS;
244768
- if (await sideQueryCapable(client4, baseUrl, opts.signal)) {
244769
- const r = await withTimeoutSignal(
244770
- timeoutMs,
244741
+ logForDebugging(`[side-channel] engine ${status3} with model=${firstModel} \u2014 retrying on the default model`);
244742
+ data = await submit(void 0);
244743
+ }
244744
+ const text2 = typeof data.result === "string" ? data.result.trim() : "";
244745
+ if (!text2) throw new Error("sema engine side-channel: empty result");
244746
+ const st2 = data.stats;
244747
+ const usage = st2 ? {
244748
+ input_tokens: st2.promptTokens ?? st2.totalInputTokens ?? 0,
244749
+ output_tokens: st2.outputTokens ?? 0,
244750
+ cache_creation_input_tokens: st2.cacheWriteTokens ?? 0,
244751
+ cache_read_input_tokens: st2.cachedTokens ?? 0
244752
+ } : null;
244753
+ return { text: text2, usage };
244754
+ };
244755
+ if (await sideQueryCapable(client4, baseUrl, budget, opts.signal)) {
244756
+ const query2 = (model) => withTimeoutSignal(
244757
+ budget.remaining(),
244771
244758
  opts.signal,
244772
244759
  (signal) => client4.sideQuery.query(
244773
244760
  {
244774
244761
  messages: [{ role: "user", content: opts.objective }],
244775
- ...opts.modelRef ? { model: opts.modelRef } : {},
244762
+ ...model ? { model } : {},
244776
244763
  ...opts.maxTokens ? { maxOutputTokens: opts.maxTokens } : {},
244777
244764
  ...opts.systemPrompt ? { systemPrompt: opts.systemPrompt } : {}
244778
244765
  },
244779
244766
  { signal }
244780
244767
  )
244781
244768
  );
244769
+ let r;
244770
+ try {
244771
+ r = await query2(firstModel);
244772
+ } catch (e) {
244773
+ const status3 = statusOf2(e);
244774
+ if (status3 !== void 0 && ENDPOINT_GONE_STATUSES.has(status3)) {
244775
+ sideQueryCapByBase.set(baseUrl, { ok: false, at: Date.now() });
244776
+ logForDebugging(`[side-channel] side-query endpoint gone (${status3}) \u2014 falling back to tasks`);
244777
+ return await tasksArm();
244778
+ }
244779
+ if (opts.noFallback || status3 === void 0 || !firstModel || !SIDEQUERY_MODEL_GATE_STATUSES.has(status3)) throw e;
244780
+ logForDebugging(`[side-channel] side-query ${status3} with model=${firstModel} \u2014 retrying on the default model`);
244781
+ r = await query2(void 0);
244782
+ }
244782
244783
  return { text: sideQueryTextOf(r), usage: usageFromSideQuery(r) };
244783
244784
  }
244784
- const data = await withTimeoutSignal(
244785
- timeoutMs,
244786
- opts.signal,
244787
- (signal) => client4.tasks.submit(
244788
- {
244789
- objective: opts.objective,
244790
- sessionId: mintSideSessionId(),
244791
- // 独立 session:utility 提示词绝不进主会话历史
244792
- ...opts.modelRef ? { model: opts.modelRef } : {},
244793
- ...opts.maxTokens ? { maxTokens: opts.maxTokens } : {},
244794
- ...opts.systemPrompt ? { systemPrompt: opts.systemPrompt } : {},
244795
- ...opts.excludeTools ? { excludeTools: [...opts.excludeTools] } : {}
244796
- },
244797
- { signal, idempotencyKey: null }
244798
- )
244799
- );
244800
- const text2 = typeof data.result === "string" ? data.result.trim() : "";
244801
- if (!text2) throw new Error("sema engine side-channel: empty result");
244802
- const st2 = data.stats;
244803
- const usage = st2 ? {
244804
- input_tokens: st2.promptTokens ?? st2.totalInputTokens ?? 0,
244805
- output_tokens: st2.outputTokens ?? 0,
244806
- cache_creation_input_tokens: st2.cacheWriteTokens ?? 0,
244807
- cache_read_input_tokens: st2.cachedTokens ?? 0
244808
- } : null;
244809
- return { text: text2, usage };
244785
+ return await tasksArm();
244786
+ }
244787
+ async function engineUtilityText(opts) {
244788
+ const r = await engineUtilityCall({ ...opts, cheapSlot: true });
244789
+ return r === null ? null : r.text;
244790
+ }
244791
+ async function engineUtilityTask(opts) {
244792
+ const r = await engineUtilityCall(opts);
244793
+ if (r === null) throw new Error("sema engine side-channel: not active");
244794
+ return r;
244810
244795
  }
244811
244796
  function extractJsonObjectText(text2) {
244812
244797
  const m2 = text2.match(/\{[\s\S]*\}/);
@@ -244824,7 +244809,7 @@ function jsonDisciplineSuffix(schema) {
244824
244809
  Return ONLY a JSON object (no prose, no markdown code fences) that matches this JSON Schema:
244825
244810
  ${JSON.stringify(schema)}`;
244826
244811
  }
244827
- var SIDE_CHANNEL_TIMEOUT_MS, sideQueryCapByBase, CAPS_PROBE_TIMEOUT_MS, CATALOG_GATE_STATUSES, UTILITY_EXCLUDE_ALL_TOOLS;
244812
+ var SIDE_CHANNEL_TIMEOUT_MS, sideQueryCapByBase, CAPS_PROBE_TIMEOUT_MS, CAP_FALSE_RETRY_TTL_MS, CATALOG_GATE_STATUSES, SIDEQUERY_MODEL_GATE_STATUSES, ENDPOINT_GONE_STATUSES, UTILITY_EXCLUDE_ALL_TOOLS;
244828
244813
  var init_engineSideChannel = __esm({
244829
244814
  "build-src/src/sema/engineSideChannel.ts"() {
244830
244815
  init_debug();
@@ -244833,7 +244818,10 @@ var init_engineSideChannel = __esm({
244833
244818
  SIDE_CHANNEL_TIMEOUT_MS = 6e4;
244834
244819
  sideQueryCapByBase = /* @__PURE__ */ new Map();
244835
244820
  CAPS_PROBE_TIMEOUT_MS = 5e3;
244821
+ CAP_FALSE_RETRY_TTL_MS = 5 * 6e4;
244836
244822
  CATALOG_GATE_STATUSES = /* @__PURE__ */ new Set([400, 404, 422]);
244823
+ SIDEQUERY_MODEL_GATE_STATUSES = /* @__PURE__ */ new Set([400, 422]);
244824
+ ENDPOINT_GONE_STATUSES = /* @__PURE__ */ new Set([404, 405, 501]);
244837
244825
  UTILITY_EXCLUDE_ALL_TOOLS = [
244838
244826
  "Bash",
244839
244827
  "PowerShell",
@@ -272431,14 +272419,16 @@ async function semaSideQueryViaEngine(opts, side) {
272431
272419
  else if (opts.output_format?.schema) objective += side.jsonDisciplineSuffix(opts.output_format.schema);
272432
272420
  const isModelValidation = opts.querySource === "model_validation";
272433
272421
  const modelRef = await side.resolvePoolModelRef(opts.model) ?? (isModelValidation ? opts.model : void 0);
272434
- const text2 = await side.engineUtilityText({
272422
+ const r = await side.engineUtilityTask({
272435
272423
  objective,
272436
272424
  signal: opts.signal,
272437
272425
  // validateModel 类 1-token ping 在任务语义下会空转 → 托底 16,verdict 仍由成功/失败承载
272438
272426
  maxTokens: Math.max(16, opts.max_tokens ?? 1024),
272439
272427
  modelRef,
272440
- noFallback: isModelValidation
272441
- }) ?? "";
272428
+ noFallback: isModelValidation,
272429
+ cheapSlot: true
272430
+ });
272431
+ const text2 = r.text;
272442
272432
  const stamp2 = Date.now().toString(36);
272443
272433
  let content;
272444
272434
  if (forcedTool) {
@@ -272465,7 +272455,8 @@ async function semaSideQueryViaEngine(opts, side) {
272465
272455
  content,
272466
272456
  stop_reason: "end_turn",
272467
272457
  stop_sequence: null,
272468
- usage: {
272458
+ // 对抗复审批 #3:verb 臂权威 usage / tasks 臂 TaskStats 映射;引擎无账时诚实零
272459
+ usage: r.usage ?? {
272469
272460
  input_tokens: 0,
272470
272461
  output_tokens: 0,
272471
272462
  cache_creation_input_tokens: 0,
@@ -440718,6 +440709,36 @@ var init_ScrollBox = __esm({
440718
440709
  }
440719
440710
  });
440720
440711
 
440712
+ // build-src/src/sema/selfKnowledge.ts
440713
+ var selfKnowledge_exports = {};
440714
+ __export(selfKnowledge_exports, {
440715
+ SEMA_IDENTITY_LINE: () => SEMA_IDENTITY_LINE,
440716
+ SEMA_SELF_KNOWLEDGE: () => SEMA_SELF_KNOWLEDGE,
440717
+ withSelfKnowledgeOutputStyle: () => withSelfKnowledgeOutputStyle
440718
+ });
440719
+ function withSelfKnowledgeOutputStyle(existing) {
440720
+ if (!existing || !existing.trim()) return SEMA_SELF_KNOWLEDGE;
440721
+ if (existing.includes("# About sema (product context)")) return existing;
440722
+ return `${SEMA_SELF_KNOWLEDGE}
440723
+
440724
+ ${existing}`;
440725
+ }
440726
+ var SEMA_SELF_KNOWLEDGE, SEMA_IDENTITY_LINE;
440727
+ var init_selfKnowledge = __esm({
440728
+ "build-src/src/sema/selfKnowledge.ts"() {
440729
+ SEMA_SELF_KNOWLEDGE = `# About sema (product context)
440730
+
440731
+ You are running inside sema, an AI coding CLI. Facts you must know and act on:
440732
+
440733
+ - sema is a fully Sema-compatible CLI (same UX, tools, and ecosystem). CLAUDE.md project memory, plugin marketplaces, MCP servers, skills, hooks and subagents all work unchanged; project-level config lives in .sema/ (e.g. .sema/commands, .sema/skills \u2014 the .claude/ analogue). Never claim sema cannot use the Sema ecosystem \u2014 it can, by design.
440734
+ - When external docs or tutorials reference the \`claude\` command, the sema equivalent is the SAME command with \`sema\` substituted (e.g. \`sema mcp add X -- npx Y\` \u2192 \`sema mcp add X -- npx Y\`). Slash commands match Sema (/help, /model, /plugin, /doctor, /config, /agents, /resume, \u2026).
440735
+ - Beyond Sema, sema adds: a local engine process the TUI drives (visible in the boot panel), model freedom (any provider via the Model Hub \u2014 \`/model\` in-session or \`sema model\`; roles/tiers configurable), cloud switching (\`sema cloud\` manages cloud registry profiles and sign-in; service/store/exec axes can each run local or cloud), central config (\`sema config\`, guided \`sema onboard\`), Sema data import (\`sema import\`), background sessions (\`sema ps\` / \`sema logs\` / \`sema attach\` / \`sema kill\`), and diagnostics (\`sema doctor\`, or /doctor in-session).
440736
+ - Plugins: /plugin opens the plugin manager (marketplaces, install, enable/disable). Skills: /skills. Both consume the open Sema plugin/skill ecosystem directly.
440737
+ - If asked what sema is: an AI coding CLI, Sema-compatible and a superset of it (engine architecture, model freedom, cloud axes). If unsure whether a capability exists, verify with \`sema --help\` or the sema-guide agent instead of denying it.`;
440738
+ SEMA_IDENTITY_LINE = "You are part of sema, an AI coding CLI that is fully Sema-compatible (claude commands map to sema verbatim) and a superset of it (engine architecture, Model Hub, cloud axes).";
440739
+ }
440740
+ });
440741
+
440721
440742
  // build-src/src/utils/sideQuestion.ts
440722
440743
  function findBtwTriggerPositions(text2) {
440723
440744
  const positions = [];
@@ -440792,7 +440813,8 @@ ${ctx}
440792
440813
  // ②maxTokens 2048 封顶回答;③systemPrompt 语义兜底。
440793
440814
  excludeTools: side.UTILITY_EXCLUDE_ALL_TOOLS,
440794
440815
  maxTokens: 2048,
440795
- systemPrompt: "You are answering a one-off side question. You have NO tools \u2014 do not attempt to read files, run commands, or take any actions. Answer directly from the provided context in a single response."
440816
+ // 身份行前缀(任务 #36):侧问无主 system prompt,一句话防「what is sema」答反
440817
+ systemPrompt: `${(await Promise.resolve().then(() => (init_selfKnowledge(), selfKnowledge_exports))).SEMA_IDENTITY_LINE} You are answering a one-off side question. You have NO tools \u2014 do not attempt to read files, run commands, or take any actions. Answer directly from the provided context in a single response.`
440796
440818
  });
440797
440819
  return { response: r.text, usage: r.usage ?? EMPTY_USAGE };
440798
440820
  } catch (e) {
@@ -451647,7 +451669,7 @@ function Settings({
451647
451669
  var import_react113, import_jsx_runtime193;
451648
451670
  var init_cmd_config = __esm({
451649
451671
  "build-src/src/sema/overrides/cmd-config.tsx"() {
451650
- import_react113 = __toESM(require_react(), 1);
451672
+ import_react113 = __toESM(require_react());
451651
451673
  init_useKeybinding();
451652
451674
  init_useExitOnCtrlCDWithKeybindings();
451653
451675
  init_useTerminalSize();
@@ -451658,7 +451680,7 @@ var init_cmd_config = __esm({
451658
451680
  init_Config();
451659
451681
  init_settings_usage();
451660
451682
  init_Stats();
451661
- import_jsx_runtime193 = __toESM(require_jsx_runtime(), 1);
451683
+ import_jsx_runtime193 = __toESM(require_jsx_runtime());
451662
451684
  }
451663
451685
  });
451664
451686
 
@@ -480451,13 +480473,13 @@ var init_sema_brand = __esm({
480451
480473
  _doc: "Rendered as the 'What's new' feed (createWhatsNewFeed). Top version MUST be >= current app version (2.1.187) and newer than config.lastReleaseNotesSeen so the notes display and full-logo mode triggers. Pinned == app version (2.1.187) + lastReleaseNotesSeen (loginState.ts) so getRecentReleaseNotes()===[] \u2192 condensed logo (matches refs/chrome.empty-input.json).",
480452
480474
  version: "2.1.187",
480453
480475
  notes: [
480454
- "/btw and background utilities now use the engine's dedicated side-query channel \u2014 no session storage residue at all (previously each call left a small side-session file)",
480455
- "Utility calls on the new channel have no tool surface whatsoever \u2014 isolation is structural, not instruction-based",
480456
- "Older engines are detected automatically and keep the previous isolated-session behavior"
480476
+ "The model now has built-in product knowledge: Claude Code compatibility (use `sema` wherever docs say `claude`), plugins, cloud, Model Hub, doctor \u2014 ask it anything about sema",
480477
+ "Plugin slash commands (e.g. /claude-hud:setup) now show up in completion and /help Custom commands \u2014 they were loaded but hidden by an over-broad visibility rule",
480478
+ "CC-compatibility flags that aren't wired yet now print an honest warning instead of silently doing nothing"
480457
480479
  ]
480458
480480
  },
480459
- productVersion: "1.0.42",
480460
- announcement: "sema 1.0.42 \u2014 background utility calls (/btw, session titles, recaps) now run through the engine's new side-query channel: zero session files left behind, tool access structurally impossible, and accurate token accounting."
480481
+ productVersion: "1.0.44",
480482
+ announcement: "sema 1.0.44 \u2014 sema now knows itself (Claude Code compatibility, plugins, cloud, Model Hub \u2014 ask it anything), plugin slash commands like /claude-hud:setup now appear in completion and /help, and unwired CC-compat flags warn honestly."
480461
480483
  };
480462
480484
  }
480463
480485
  });
@@ -483386,13 +483408,13 @@ var require_sema_brand = __commonJS({
483386
483408
  _doc: "Rendered as the 'What's new' feed (createWhatsNewFeed). Top version MUST be >= current app version (2.1.187) and newer than config.lastReleaseNotesSeen so the notes display and full-logo mode triggers. Pinned == app version (2.1.187) + lastReleaseNotesSeen (loginState.ts) so getRecentReleaseNotes()===[] \u2192 condensed logo (matches refs/chrome.empty-input.json).",
483387
483409
  version: "2.1.187",
483388
483410
  notes: [
483389
- "/btw and background utilities now use the engine's dedicated side-query channel \u2014 no session storage residue at all (previously each call left a small side-session file)",
483390
- "Utility calls on the new channel have no tool surface whatsoever \u2014 isolation is structural, not instruction-based",
483391
- "Older engines are detected automatically and keep the previous isolated-session behavior"
483411
+ "The model now has built-in product knowledge: Claude Code compatibility (use `sema` wherever docs say `claude`), plugins, cloud, Model Hub, doctor \u2014 ask it anything about sema",
483412
+ "Plugin slash commands (e.g. /claude-hud:setup) now show up in completion and /help Custom commands \u2014 they were loaded but hidden by an over-broad visibility rule",
483413
+ "CC-compatibility flags that aren't wired yet now print an honest warning instead of silently doing nothing"
483392
483414
  ]
483393
483415
  },
483394
- productVersion: "1.0.42",
483395
- announcement: "sema 1.0.42 \u2014 background utility calls (/btw, session titles, recaps) now run through the engine's new side-query channel: zero session files left behind, tool access structurally impossible, and accurate token accounting."
483416
+ productVersion: "1.0.44",
483417
+ announcement: "sema 1.0.44 \u2014 sema now knows itself (Claude Code compatibility, plugins, cloud, Model Hub \u2014 ask it anything), plugin slash commands like /claude-hud:setup now appear in completion and /help, and unwired CC-compat flags warn honestly."
483396
483418
  };
483397
483419
  }
483398
483420
  });
@@ -530605,16 +530627,20 @@ async function semaEngineNonStreamingLeg({
530605
530627
  if (options.outputFormat?.schema) {
530606
530628
  objective += side.jsonDisciplineSuffix(options.outputFormat.schema);
530607
530629
  }
530608
- const text2 = await side.engineUtilityText({
530630
+ const r = await side.engineUtilityTask({
530609
530631
  objective,
530610
530632
  signal,
530611
530633
  maxTokens: options.maxOutputTokensOverride,
530634
+ cheapSlot: true,
530612
530635
  // 池内模型透传(A2 兜底):queryWithModel/advisor 显式选池模型时按所选路由;CC 名走 cheap/默认
530613
530636
  modelRef: await side.resolvePoolModelRef(options.model)
530614
530637
  });
530615
- if (text2 === null) return null;
530638
+ const text2 = r.text;
530616
530639
  const content = options.outputFormat?.schema ? side.extractJsonObjectText(text2) ?? text2 : text2;
530617
- return createAssistantMessage({ content });
530640
+ return createAssistantMessage({
530641
+ content,
530642
+ ...r.usage ? { usage: r.usage } : {}
530643
+ });
530618
530644
  }
530619
530645
  async function queryModelWithoutStreaming({
530620
530646
  messages,
@@ -606991,8 +607017,8 @@ function _temp158() {
606991
607017
  var import_compiler_runtime312, import_react310, import_jsx_runtime458, DESKTOP_UPSELL_DEFAULT;
606992
607018
  var init_DesktopUpsellStartup = __esm({
606993
607019
  "build-src/src/components/DesktopUpsell/DesktopUpsellStartup.tsx"() {
606994
- import_compiler_runtime312 = __toESM(require_compiler_runtime(), 1);
606995
- import_react310 = __toESM(require_react(), 1);
607020
+ import_compiler_runtime312 = __toESM(require_compiler_runtime());
607021
+ import_react310 = __toESM(require_react());
606996
607022
  init_ink2();
606997
607023
  init_growthbook_advisor_flag();
606998
607024
  init_analytics_index();
@@ -607000,7 +607026,7 @@ var init_DesktopUpsellStartup = __esm({
607000
607026
  init_select();
607001
607027
  init_DesktopHandoff();
607002
607028
  init_PermissionDialog();
607003
- import_jsx_runtime458 = __toESM(require_jsx_runtime(), 1);
607029
+ import_jsx_runtime458 = __toESM(require_jsx_runtime());
607004
607030
  DESKTOP_UPSELL_DEFAULT = {
607005
607031
  enable_shortcut_tip: false,
607006
607032
  enable_startup_dialog: false
@@ -609355,8 +609381,8 @@ function _temp161() {
609355
609381
  var import_compiler_runtime316, import_react314, SETTINGS_ERRORS_NOTIFICATION_KEY;
609356
609382
  var init_useSettingsErrors = __esm({
609357
609383
  "build-src/src/hooks/notifs/useSettingsErrors.tsx"() {
609358
- import_compiler_runtime316 = __toESM(require_compiler_runtime(), 1);
609359
- import_react314 = __toESM(require_react(), 1);
609384
+ import_compiler_runtime316 = __toESM(require_compiler_runtime());
609385
+ import_react314 = __toESM(require_react());
609360
609386
  init_notifications();
609361
609387
  init_state();
609362
609388
  init_allErrors();
@@ -630118,6 +630144,10 @@ function toLiveRequest(req, capturedSessionId) {
630118
630144
  if (typeof out6.scenario === "string" && SEMA_MOCK_SCENARIO_KEYS.has(out6.scenario)) {
630119
630145
  delete out6.scenario;
630120
630146
  }
630147
+ {
630148
+ const settings2 = out6.settings ?? {};
630149
+ out6.settings = { ...settings2, outputStyle: withSelfKnowledgeOutputStyle(settings2.outputStyle) };
630150
+ }
630121
630151
  if (capturedSessionId) {
630122
630152
  out6.sessionId = capturedSessionId;
630123
630153
  } else if (out6.sessionId === mockClientIds.sessionId) {
@@ -630372,6 +630402,7 @@ var init_liveClient = __esm({
630372
630402
  init_agentsWire();
630373
630403
  init_detachWire();
630374
630404
  init_headlessReconnectWire();
630405
+ init_selfKnowledge();
630375
630406
  init_mockClient();
630376
630407
  ENGINE_TO_CC_TOOL = {
630377
630408
  bash: "Bash",
@@ -653491,6 +653522,30 @@ async function run() {
653491
653522
  return value;
653492
653523
  })).option("--sandbox <profile>", `Sandbox image profile for submitted runs: a profile name (explicit; k8s-lane workers only \u2014 list with 'sema cloud images list'), or 'auto' to let the model pick via its SelectEnvironment tool (advisory; choice + reason are echoed in the reply). Omit for the worker default image.`).option("--scenario <name>", `Engine scenario for submitted runs (only works with --print): route the run through a deployment-defined scenario (tool roster + system prompt). Unknown names fall back to the default scenario. Omit for the default scenario; a persistent default can be set via SEMA_HEADLESS_SCENARIO in the settings.json env block.`).option("--no-final-verify", `Disable the default final-verification pass for submitted runs (only works with --print). By default, headless -p runs that write files get up to two extra verification turns before finishing; this flag restores the upstream-aligned behaviour (no verification pass). A persistent default can be set via SEMA_HEADLESS_FINAL_VERIFY=false in the settings.json env block. Skipped automatically when a Stop hook is configured.`).option("--deadline <sec>", `Soft wall-clock budget in seconds for submitted runs (only works with --print; sema superset \u2014 no upstream equivalent). The engine paces itself against the deadline (pacing nudges + per-call caps) and finalizes gracefully near it; integer between 30 and 86400. A persistent default can be set via SEMA_HEADLESS_DEADLINE_SEC in the settings.json env block.`).option("--agent <agent>", `Agent for the current session. Overrides the 'agent' setting.`).option("--betas <betas...>", "Beta headers to include in API requests (API key users only)").option("--fallback-model <model>", "Enable automatic fallback to specified model when default model is overloaded (only works with --print)").addOption(new Option("--workload <tag>", "Workload tag for billing-header attribution (cc_workload). Process-scoped; set by SDK daemon callers that spawn subprocesses for cron work. (only works with --print)").hideHelp()).option("--settings <file-or-json>", "Path to a settings JSON file or a JSON string to load additional settings from").option("--add-dir <directories...>", "Additional directories to allow tool access to").option("--ide", "Automatically connect to IDE on startup if exactly one valid IDE is available", () => true).option("--strict-mcp-config", "Only use MCP servers from --mcp-config, ignoring all other MCP configurations", () => true).option("--session-id <uuid>", "Use a specific session ID for the conversation (must be a valid UUID)").option("-n, --name <name>", "Set a display name for this session (shown in /resume and terminal title)").option("--agents <json>", `JSON object defining custom agents (e.g. '{"reviewer": {"description": "Reviews code", "prompt": "You are a code reviewer"}}')`).option("--setting-sources <sources>", "Comma-separated list of setting sources to load (user, project, local).").option("--plugin-dir <path>", "Load plugins from a directory for this session only (repeatable: --plugin-dir A --plugin-dir B)", (val, prev) => [...prev, val], []).addOption(new Option("--plugin-dir-no-mcp <path>", "Like --plugin-dir but the engine will not read this plugin's .mcp.json (caller owns its MCP connections)").argParser((val, prev) => [...prev, val]).default([]).hideHelp()).option("--plugin-url <url>", "Fetch a plugin .zip from a URL for this session only (repeatable: --plugin-url A --plugin-url B)", (val, prev) => [...prev, ...val.split(/\s+/).filter(Boolean)], []).option("--disable-slash-commands", "Disable all skills", () => true).option("--chrome", "Enable Claude in Chrome integration").option("--no-chrome", "Disable Claude in Chrome integration").option("--file <specs...>", "File resources to download at startup. Format: file_id:relative_path (e.g., --file file_abc:doc.txt file_def:img.png)").action(async (prompt, options) => {
653493
653524
  profileCheckpoint("action_handler_start");
653525
+ {
653526
+ const UNWIRED_FLAGS = [
653527
+ ["thinkingDisplay", "--thinking-display"],
653528
+ ["promptSuggestions", "--prompt-suggestions"],
653529
+ ["sessionMirror", "--session-mirror"],
653530
+ ["excludeDynamicSystemPromptSections", "--exclude-dynamic-system-prompt-sections"],
653531
+ ["replyOnResume", "--reply-on-resume"],
653532
+ ["pluginDirNoMcp", "--plugin-dir-no-mcp"],
653533
+ ["pluginUrl", "--plugin-url"],
653534
+ ["background", "--bg/--background"],
653535
+ ["bg", "--bg/--background"],
653536
+ ["axScreenReader", "--ax-screen-reader"]
653537
+ ];
653538
+ const warned2 = /* @__PURE__ */ new Set();
653539
+ for (const [key, flag] of UNWIRED_FLAGS) {
653540
+ const v2 = options[key];
653541
+ const set2 = v2 !== void 0 && v2 !== false && !(Array.isArray(v2) && v2.length === 0);
653542
+ if (set2 && !warned2.has(flag)) {
653543
+ warned2.add(flag);
653544
+ process.stderr.write(source_default.yellow(`${flag} is recognized for CC compatibility but not wired in this sema build yet \u2014 it currently has no effect.
653545
+ `));
653546
+ }
653547
+ }
653548
+ }
653494
653549
  if (options.bare) {
653495
653550
  process.env.SEMA_CODE_SIMPLE = "1";
653496
653551
  }
@@ -655599,7 +655654,7 @@ Auth: unix socket -R \u2192 local proxy`, "info");
655599
655654
  pendingHookMessages
655600
655655
  }, renderAndRun);
655601
655656
  }
655602
- }).version("sema 1.0.42", "-v, --version", "Output the version number");
655657
+ }).version("sema 1.0.44", "-v, --version", "Output the version number");
655603
655658
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
655604
655659
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
655605
655660
  if (canUserConfigureAdvisor()) {
@@ -660769,7 +660824,9 @@ function resolveCommandGate(cmd, caps) {
660769
660824
  return { state: "denied", visible: false, degraded: false, hidden: false, reason: "config-deny" };
660770
660825
  }
660771
660826
  const explicitMode = override?.mode;
660772
- const isUnbucketedFallthrough = !bucketOf(name) && explicitMode !== "allow" && explicitMode !== "deny";
660827
+ const source = cmd.source;
660828
+ const isBuiltinFace = source === void 0 || source === "builtin";
660829
+ const isUnbucketedFallthrough = isBuiltinFace && !bucketOf(name) && explicitMode !== "allow" && explicitMode !== "deny";
660773
660830
  const hidden = override?.hidden === true || isUnbucketedFallthrough;
660774
660831
  const requiredCapability = override?.requiredCapability;
660775
660832
  if (requiredCapability) {