@nextclaw/kernel 0.6.3 → 0.6.5

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.
package/dist/index.js CHANGED
@@ -8904,15 +8904,6 @@ const createToolCallStyleContextProvider = () => staticBlock([
8904
8904
  "Keep narration brief and value-dense; avoid repeating obvious steps.",
8905
8905
  "Use plain human language for narration unless in a technical context."
8906
8906
  ]);
8907
- const createInlineInteractiveSurfaceContextProvider = () => staticBlock([
8908
- "## Inline Interactive Surfaces",
8909
- "Do not make every UI an inline card. Choose inline only when the intended result is a compact, immediately usable card or short interaction; use the side panel for normal Panel Apps, long reading, rich editing, file browsing, large tables, multi-page workflows, or sustained workspaces.",
8910
- "Inline Panel App display is Markdown-only: in the final reply, output a `nextclaw-inline` fenced JSON block so the display remains message content.",
8911
- "`show_panel_app` is side-panel only. Never call `show_panel_app` for inline display, including when the user asks which Panel Apps are suitable for inline display or says \"show/display them inline\".",
8912
- "For ordinary local HTML files or page prototypes, call `show_file` with `path` and `viewer=\"rendered\"`; use `viewer=\"source\"` when the user needs to inspect source text. Markdown file links open source by default; append `?viewer=rendered` only when the link itself should open the rendered HTML view. Do not convert a plain HTML file into a Panel App just to preview it.",
8913
- "A Panel Card must be designed card-first: prefer a landscape composition where width carries the main information and the card is wider than it is tall; collapse to one column only in narrow containers. Core value must be visible in the first 220-420px, with no horizontal scrolling, no reliance on document-level internal scrolling, compact controls, at most one primary action, clear loading/empty/error states, and an obvious expand path for details.",
8914
- "Typical Panel Card fits: weather cards, calculators, timers, checklists, pickers, compact forms, previews, and small dashboards. If the UI needs more space than a card, use the side panel instead. Inline hosts may pass `nextclawDisplayMode=card` and `nextclawPlacement=inline`; use those hints to render a compact card layout instead of a full page."
8915
- ]);
8916
8907
  const createChatComposerTokensContextProvider = () => staticBlock([
8917
8908
  "## Chat Composer Tokens",
8918
8909
  "When a user message contains tokens like `$weather` or `$web-search`, treat each `$<skill-spec>` token as a user-visible marker that the corresponding skill was explicitly selected in the chat composer.",
@@ -9066,7 +9057,28 @@ var ProjectContextProvider = class {
9066
9057
  //#endregion
9067
9058
  //#region src/contributions/context-provider/providers/reply-format-context.provider.ts
9068
9059
  var ReplyFormatContextProvider = class {
9069
- provide = (_request) => ["## Reply Formatting Contract\nGoal: openable files in user-visible replies must be clickable, and inert inline display declarations are only for content that should appear as part of the reply.\nFile links: use Markdown links only, with a plain text label and an openable href: [MEMORY.md](MEMORY.md), [file](packages/example/file.ts), [notes.md](/Users/example/Documents/notes.md). Use project-relative hrefs for files under the active/session project root, and absolute hrefs for local files outside it. File links open source by default; use a viewer query such as [preview.html](preview.html?viewer=rendered) only when the link should open the rendered HTML view.\nInline display: when the final reply should include a non-clickable inline display placeholder, output a fenced `nextclaw-inline` JSON block:\n```nextclaw-inline\n{\"target\":{\"type\":\"panel_app\",\"payload\":{\"appId\":\"timer\"}},\"title\":\"Timer\"}\n```\nSupported targets are `panel_app`, `json`, `file`, and `url`. Prefer `panel_app` for inline Panel App display; use `file` and `url` only as non-clickable placeholders when a clickable link is not intended; use `json` for inert JSON snapshots.\nIt is display-only: no opening, executing, or tool action. Never call `show_panel_app` for inline display; `show_panel_app` is only for immediately opening a Panel App outside the final reply in the side panel. Use Markdown links for clickable resources and show_file/show_url/show_panel_app tools only when you want the UI to immediately show or run content outside the final reply.\nForbidden forms: bare file names or paths, inline-code file names, bold-only file names, code-styled link labels, code blocks for file references, action semantics inside `nextclaw-inline`, tool calls for inline display, and unlinked comma-separated file lists.\nExamples: bad `MEMORY.md` -> good [MEMORY.md](MEMORY.md); bad `memory/` -> good [memory/](memory/); bad `2026-03-07.md` / `feishu-notes.md` -> good [2026-03-07.md](memory/2026-03-07.md) / [feishu-notes.md](memory/feishu-notes.md).\nSelf-check before sending: scan the final visible reply for local file names or paths. If every concrete file cannot be linked or intentionally represented by `nextclaw-inline`, remove the exact names and summarize instead."];
9060
+ provide = (_request) => [[
9061
+ "## Agent Output & Reply Formatting Contract",
9062
+ "Goal: make the directly visible final reply self-contained, concise, and easy to act on; make openable files clickable, show local images directly when appropriate, and use richer display surfaces only when they improve delivery.",
9063
+ "Visible final reply: after a completed assistant turn, the UI collapses reasoning and tool activity through the last tool call under a Processed summary. Content after the last tool call remains directly visible. Therefore, after the final tool call, always write a self-contained final response with the outcome, important caveats, relevant links, and the next useful action. Do not put the final answer only before a tool call, and do not assume raw tool output remains directly visible.",
9064
+ "Progress narration before or between tool calls may be brief and contextual, but do not repeat it in the final reply. The final reply must still make sense when all earlier narration and tool activity are collapsed.",
9065
+ "Markdown structure: prefer short paragraphs. Use headings, lists, tables, blockquotes, and code blocks only when they materially improve scanning or comparison; do not over-format a simple answer. Keep link labels descriptive and plain, and place each link next to the claim or artifact it supports.",
9066
+ "Mermaid diagrams: use a fenced `mermaid` block when a relationship, flow, sequence, state transition, or hierarchy is materially clearer as a diagram than as short prose or a small list. Keep diagrams focused, quote node labels that contain punctuation, and do not add a diagram merely because an answer has several steps.",
9067
+ "File links: every concrete local file or directory mentioned in the final reply must be clickable. Use Markdown links only, with a plain text label and an openable href: [MEMORY.md](MEMORY.md), [report.docx](report.docx), [file](packages/example/file.ts), [notes.md](/Users/example/Documents/notes.md). Use project-relative hrefs for files under the active/session project root, and absolute hrefs for local files outside it. File links open source by default; supported visual and Office documents open their automatic preview. Use a viewer query such as [diagram.svg](diagram.svg?viewer=source) when source is explicitly required, or [preview.html](preview.html?viewer=rendered) when an HTML link should open rendered output.",
9068
+ "Markdown syntax and resource availability are separate: emit a proper Markdown link even when you cannot verify that its target still exists. The UI will report missing or unavailable content when the user opens it; never downgrade a valid link to bare text preemptively.",
9069
+ "Local images: prefer standard Markdown image syntax when the image should be visible in the reply: ![chart](assets/chart.png) or ![diagram](/Users/example/Pictures/diagram.svg). Local image hrefs follow the same project-relative or absolute path rules as file links. Do not invent an internal API URL or a file:// URL. Use `show_file` only when the file should immediately open in the side panel; `view_image` is only for giving the model visual input.",
9070
+ "Display choice: Do not make every UI an inline card. Choose inline only for a compact, immediately usable card or short interaction. Use the side panel for normal Panel Apps, long reading, rich editing, file browsing, large tables, multi-page workflows, or sustained workspaces.",
9071
+ "Inline display: when the final reply should include a non-clickable inline display placeholder, output a fenced `nextclaw-inline` JSON block:",
9072
+ "```nextclaw-inline\n{\"target\":{\"type\":\"panel_app\",\"payload\":{\"appId\":\"timer\"}},\"title\":\"Timer\"}\n```",
9073
+ "Supported targets are `panel_app`, `json`, `file`, and `url`. Prefer `panel_app` for inline Panel App display; use `file` and `url` only as non-clickable placeholders when a clickable link is not intended; use `json` for inert JSON snapshots.",
9074
+ "Inline display is Markdown-only and display-only: no opening, executing, or tool action. Never call `show_panel_app` for inline display, including when the user asks which Panel Apps are suitable for inline display or says to show them inline. `show_panel_app` is only for immediately opening a Panel App outside the final reply in the side panel. Use Markdown links for clickable resources and `show_file` / `show_url` / `show_panel_app` only when the UI should immediately show or run content outside the final reply.",
9075
+ "For ordinary local HTML files or page prototypes, call `show_file` with `path` and `viewer=\"rendered\"`; use `viewer=\"source\"` when the user needs source text. Markdown file links open source by default; append `?viewer=rendered` only when the link itself should open the rendered HTML view. Do not convert a plain HTML file into a Panel App just to preview it.",
9076
+ "A Panel Card must be card-first: prefer a landscape composition where width carries the main information and the card is wider than it is tall; collapse to one column only in narrow containers. Core value must be visible in the first 220-420px, with no horizontal scrolling, no reliance on document-level internal scrolling, compact controls, at most one primary action, clear loading/empty/error states, and an obvious expand path for details.",
9077
+ "Typical Panel Card fits: weather cards, calculators, timers, checklists, pickers, compact forms, previews, and small dashboards. If the UI needs more space than a card, use the side panel. Inline hosts may pass `nextclawDisplayMode=card` and `nextclawPlacement=inline`; use those hints to render a compact card layout instead of a full page.",
9078
+ "Forbidden forms: bare file names or paths, inline-code file names, bold-only file names, code-styled link labels, code blocks for file references, file:// URLs, internal API URLs, action semantics inside `nextclaw-inline`, tool calls for inline display, and unlinked comma-separated file lists.",
9079
+ "Examples: bad `MEMORY.md` -> good [MEMORY.md](MEMORY.md); bad `memory/` -> good [memory/](memory/); bad `report.docx` -> good [report.docx](report.docx); bad `/Users/example/chart.png` -> good ![chart](/Users/example/chart.png); bad `2026-03-07.md` / `feishu-notes.md` -> good [2026-03-07.md](memory/2026-03-07.md) / [feishu-notes.md](memory/feishu-notes.md).",
9080
+ "Self-check before sending: scan the final visible reply for local file names, paths, and images. Make every concrete file clickable, render intended images with Markdown image syntax, or ensure it is intentionally represented by `nextclaw-inline`; otherwise remove the exact names and summarize instead."
9081
+ ].join("\n")];
9070
9082
  };
9071
9083
  //#endregion
9072
9084
  //#region src/contributions/context-provider/providers/skills-context.provider.ts
@@ -9082,7 +9094,7 @@ function renderActiveSkillsSection(skills, skillSelectors) {
9082
9094
  if (!manifest) return "";
9083
9095
  return [
9084
9096
  "# Active Skills",
9085
- "These always-on skills are already active for this session context.",
9097
+ "These user-selected or always-on skills are active for this request.",
9086
9098
  "If an active skill covers the user's intent, follow it before considering unrelated available skills.",
9087
9099
  "For NextClaw self-management intents, read the built-in NextClaw self-management guide before loading any unrelated generic skill.",
9088
9100
  "Skill refs are unique identities; names may repeat.",
@@ -9091,12 +9103,23 @@ function renderActiveSkillsSection(skills, skillSelectors) {
9091
9103
  wrapSkillTag("active_skills", manifest)
9092
9104
  ].join("\n\n");
9093
9105
  }
9106
+ function renderSkillSourcesSection(params) {
9107
+ return [
9108
+ "## Skill Sources",
9109
+ "Skills in <available_skills> are grouped by source.",
9110
+ params.projectSkillsRoot ? `- project: project-only skills. When creating or updating a skill specifically for this active project, use \`${params.projectSkillsRoot}/<skill-name>/SKILL.md\`.` : "- project: no session-bound project is active, so do not invent a project skill location.",
9111
+ `- workspace: skills installed for NextClaw in \`${params.hostWorkspace}/skills\`.`,
9112
+ "- global: user-wide Agent Skills loaded from ~/.agents/skills.",
9113
+ "- builtin: skills packaged with NextClaw.",
9114
+ "A project's AGENTS.md is loaded separately in Agent Bootstrap Context; it is not a skill."
9115
+ ].join("\n");
9116
+ }
9094
9117
  function renderAvailableSkillsSection(skills) {
9095
9118
  const summary = skills.buildSkillsSummary();
9096
9119
  if (!summary) return "";
9097
9120
  return [
9098
9121
  "## Skills (mandatory)",
9099
- "Always-on skills in <active_skills> take precedence over this list.",
9122
+ "User-selected and always-on skills in <active_skills> take precedence over this list.",
9100
9123
  "Before replying: first check whether any entry in <available_skills> may be relevant to the user's intent, task type, or requested output. Do not skip this check just because the task seems familiar.",
9101
9124
  "- If one skill looks like the best relevant match, read its SKILL.md at <location> with `read_file`, then decide whether following it is actually helpful.",
9102
9125
  "- If a SKILL.md read says `Use offset=... to continue`, continue reading until the relevant trigger, required workflow, constraints, and output requirements are covered.",
@@ -9127,15 +9150,19 @@ var SkillsContextProvider = class {
9127
9150
  this.context = context;
9128
9151
  }
9129
9152
  provide = async (request) => {
9130
- const { projectContext } = await this.context.resolve(request);
9153
+ const { projectContext, runContext } = await this.context.resolve(request);
9131
9154
  const skills = new SkillsLoader({
9132
9155
  workspace: projectContext.hostWorkspace,
9133
- projectRoot: projectContext.projectRoot
9156
+ projectRoot: projectContext.projectRoot,
9157
+ includeGlobal: true
9134
9158
  });
9135
- const blocks = [];
9136
- const alwaysSkills = skills.getAlwaysSkills();
9137
- if (alwaysSkills.length) {
9138
- const activeSection = renderActiveSkillsSection(skills, alwaysSkills);
9159
+ const blocks = [renderSkillSourcesSection({
9160
+ hostWorkspace: projectContext.hostWorkspace,
9161
+ projectSkillsRoot: projectContext.projectSkillsRoot
9162
+ })];
9163
+ const activeSkills = [...runContext.requestedSkills.selectors, ...skills.getAlwaysSkills()];
9164
+ if (activeSkills.length) {
9165
+ const activeSection = renderActiveSkillsSection(skills, activeSkills);
9139
9166
  if (activeSection) blocks.push(activeSection);
9140
9167
  }
9141
9168
  const availableSkillsSection = renderAvailableSkillsSection(skills);
@@ -9208,6 +9235,8 @@ function buildAgentRunRequestMetadata(params) {
9208
9235
  const model = normalizeString(request.model ?? session?.model);
9209
9236
  return {
9210
9237
  ...structuredClone(session?.metadata ?? {}),
9238
+ ...structuredClone(request.message.metadata ?? {}),
9239
+ ...structuredClone(request.metadata ?? {}),
9211
9240
  agentId,
9212
9241
  projectRoot,
9213
9242
  project_root: projectRoot,
@@ -9319,7 +9348,6 @@ var ContextProviderContribution = class {
9319
9348
  createAssistantIdentityContextProvider(),
9320
9349
  new ToolingContextProvider(context),
9321
9350
  createToolCallStyleContextProvider(),
9322
- createInlineInteractiveSurfaceContextProvider(),
9323
9351
  createChatComposerTokensContextProvider(),
9324
9352
  createSafetyContextProvider(),
9325
9353
  createCliQuickReferenceContextProvider(),
@@ -10182,7 +10210,7 @@ function normalizeShowFileArgs(args) {
10182
10210
  path: readRequiredString(params.path, "path"),
10183
10211
  line: readOptionalPositiveInteger(params.line, "line"),
10184
10212
  column: readOptionalPositiveInteger(params.column, "column"),
10185
- viewer: readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS) ?? "source"
10213
+ viewer: readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS) ?? "auto"
10186
10214
  }
10187
10215
  },
10188
10216
  ...readCommonRequestFields(params, FILE_PURPOSES)
@@ -10251,7 +10279,7 @@ var ShowContentDisplayTool = class {
10251
10279
  const SHOW_CONTENT_TOOL_SPECS = [
10252
10280
  {
10253
10281
  name: "show_file",
10254
- description: "Show a local file in the current chat UI. Defaults to source text. Use viewer=\"rendered\" for rendered HTML/page previews and viewer=\"source\" for source text.",
10282
+ description: "Show a local file in the current chat UI. The automatic viewer displays images (including SVG), PDF, media, and supported documents, while text remains source. Use viewer=\"rendered\" for HTML/page previews or viewer=\"source\" to force source text.",
10255
10283
  parameters: {
10256
10284
  type: "object",
10257
10285
  properties: {