@geminixiang/mikan 1.0.0-beta.73 → 1.0.0-beta.74

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/CHANGELOG.md CHANGED
@@ -9,6 +9,16 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.74]
13
+
14
+ ### Security
15
+
16
+ - Host sandbox tool output (bash, read, and every other agent tool) is now scrubbed of any configured secret env var's value before it reaches the model or the durable session transcript. Host sandbox mode does not isolate environment variables, so a command like `echo $OPENROUTER_API_KEY` previously returned the key in plain text with no defense beyond the model choosing not to repeat it; it is now replaced with a `[SECRET:VAR_NAME]` placeholder using mikan's existing secret env var inventory.
17
+
18
+ ### Fixed
19
+
20
+ - Stop and shutdown-restart notices ("Stopping…", "Stopped.", the restart notice) are now recorded in the conversation's `log.jsonl`, matching every other agent reply. Previously these control messages reached the platform but left no trace in the human-readable history the agent (and operators) grep, so a stopped run looked, on later review, like it had never been interrupted.
21
+
12
22
  ## [1.0.0-beta.73]
13
23
 
14
24
  ### Changed
@@ -1428,7 +1428,9 @@ const ICONS = {
1428
1428
  /** One entry in the settings rail: an icon, a label, and the pane id it activates. */
1429
1429
  function railLink(id, label, icon, active = false) {
1430
1430
  const svg = ICONS[icon];
1431
- return `<button class="rail-link${active ? " active" : ""}" type="button" data-pane="${id}" aria-current="${active ? "page" : "false"}">${svg}<span>${esc(label)}</span></button>`;
1431
+ // The label span is hidden below 860px, so mirror it into aria-label/title to
1432
+ // keep an accessible name and a hover hint once the text disappears.
1433
+ return `<button class="rail-link${active ? " active" : ""}" type="button" data-pane="${id}" aria-current="${active ? "page" : "false"}" aria-label="${esc(label)}" title="${esc(label)}">${svg}<span>${esc(label)}</span></button>`;
1432
1434
  }
1433
1435
  /**
1434
1436
  * One settings pane: an eyebrow-free header (icon lives in the rail, not
@@ -1474,33 +1476,33 @@ const adminViewBody = `<div class="settings-shell">
1474
1476
 
1475
1477
  <div class="settings-panels">
1476
1478
  <div class="tab-panel active" id="panel-conversation">
1477
- ${settingsPane("settings", "Settings", "Model, thinking level, auto-reply, and workspace visibility for this conversation.", '<button class="refresh-btn" onclick="loadSettings()">↻</button>', '<div id="settings-content"><div class="loading-msg">Loading…</div></div>')}
1479
+ ${settingsPane("settings", "Settings", "Model, thinking level, auto-reply, and workspace visibility for this conversation.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadSettings()">↻</button>', '<div id="settings-content"><div class="loading-msg">Loading…</div></div>')}
1478
1480
 
1479
- ${settingsPane("workspace", "Workspace", "Read-only browser for this conversation's files on disk.", '<button class="refresh-btn" onclick="loadWorkspace()">↻</button>', '<div class="workspace-split"><div id="workspace-tree" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="workspace-preview" class="workspace-preview"><div class="placeholder-msg">Click a file to preview</div></div></div>')}
1481
+ ${settingsPane("workspace", "Workspace", "Read-only browser for this conversation's files on disk.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadWorkspace()">↻</button>', '<div class="workspace-split"><div id="workspace-tree" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="workspace-preview" class="workspace-preview"><div class="placeholder-msg">Click a file to preview</div></div></div>')}
1480
1482
 
1481
- ${settingsPane("skills", "Skills", "Instructions the agent can load for specific tasks in this conversation.", '<button class="primary-action-btn" onclick="openSkillDialog(\'conversation\')">+ New skill</button><button class="refresh-btn" onclick="loadSkills()">↻</button>', '<div class="workspace-split"><div id="skills-content" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="skills-preview" class="workspace-preview"><div class="placeholder-msg">Click a skill to preview SKILL.md</div></div></div>')}
1483
+ ${settingsPane("skills", "Skills", "Instructions the agent can load for specific tasks in this conversation.", '<button class="primary-action-btn" onclick="openSkillDialog(\'conversation\')">+ New skill</button><button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadSkills()">↻</button>', '<div class="workspace-split"><div id="skills-content" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="skills-preview" class="workspace-preview"><div class="placeholder-msg">Click a skill to preview SKILL.md</div></div></div>')}
1482
1484
 
1483
- ${settingsPane("mcp", "MCP servers", "External tools this conversation can call during a run.", '<button class="refresh-btn" onclick="loadMcpServers()">↻</button>', '<div id="mcp-conv-msg" class="status-msg" style="display:none"></div><div id="mcp-conv-content"><div class="loading-msg">Loading…</div></div>')}
1485
+ ${settingsPane("mcp", "MCP servers", "External tools this conversation can call during a run.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadMcpServers()">↻</button>', '<div id="mcp-conv-msg" class="status-msg" style="display:none"></div><div id="mcp-conv-content"><div class="loading-msg">Loading…</div></div>')}
1484
1486
 
1485
1487
  ${settingsPane("vault", "Vault", "Credentials scoped to this conversation.", '<button class="primary-action-btn" onclick="openLogin()">Open in new tab ↗</button>', '<div id="vault-link-result" class="link-result" style="display:none"></div><p class="card-desc">Opens the one-time credential form for this conversation\'s vault in a new tab.</p>')}
1486
1488
 
1487
- ${settingsPane("events", "Events", "Scheduled and one-shot events tied to this conversation.", '<button class="refresh-btn" onclick="loadConversationEvents()">↻</button>', '<div id="events-content"><div class="loading-msg">Loading…</div></div>')}
1489
+ ${settingsPane("events", "Events", "Scheduled and one-shot events tied to this conversation.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadConversationEvents()">↻</button>', '<div id="events-content"><div class="loading-msg">Loading…</div></div>')}
1488
1490
 
1489
1491
  ${settingsPane("session", "Session view", "The full message and tool-call timeline for this conversation.", '<button class="primary-action-btn" onclick="openSessionView()">Open in new tab ↗</button>', '<div id="session-link-result" class="link-result" style="display:none"></div><p class="card-desc">Opens the session timeline for this conversation in a new tab.</p>')}
1490
1492
  </div>
1491
1493
 
1492
1494
  <div class="tab-panel" id="panel-global">
1493
- ${settingsPane("g-overview", "All conversations", "Every registered conversation across every platform.", '<button class="refresh-btn" onclick="loadAllConversations()">↻</button>', '<div id="all-conv-content"><div class="loading-msg">Loading…</div></div>')}
1495
+ ${settingsPane("g-overview", "All conversations", "Every registered conversation across every platform.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadAllConversations()">↻</button>', '<div id="all-conv-content"><div class="loading-msg">Loading…</div></div>')}
1494
1496
 
1495
- ${settingsPane("g-usage", "Token usage", "Spend and volume across every conversation.", '<button class="refresh-btn" onclick="loadTokenUsage()">↻</button>', '<h3 class="card-subtitle">Top 20 sessions</h3><div id="session-usage-content"><div class="loading-msg">Loading…</div></div><h3 class="card-subtitle" style="margin-top:24px">Usage timeline</h3><div class="timeline-controls"><label>Conversation<select id="timeline-conv" onchange="loadUsageTimeline()"></select></label></div><div id="usage-timeline-content"><div class="loading-msg">Loading…</div></div>')}
1497
+ ${settingsPane("g-usage", "Token usage", "Spend and volume across every conversation.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadTokenUsage()">↻</button>', '<h3 class="card-subtitle">Top 20 sessions</h3><div id="session-usage-content"><div class="loading-msg">Loading…</div></div><h3 class="card-subtitle" style="margin-top:24px">Usage timeline</h3><div class="timeline-controls"><label>Conversation<select id="timeline-conv" onchange="loadUsageTimeline()"></select></label></div><div id="usage-timeline-content"><div class="loading-msg">Loading…</div></div>')}
1496
1498
 
1497
- ${settingsPane("g-settings", "Workspace defaults", "The fallback model, sandbox limits, and Slack behavior every conversation inherits.", '<button class="refresh-btn" onclick="loadGlobalSettings()">↻</button>', '<div id="global-settings-content"><div class="loading-msg">Loading…</div></div>')}
1499
+ ${settingsPane("g-settings", "Workspace defaults", "The fallback model, sandbox limits, and Slack behavior every conversation inherits.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadGlobalSettings()">↻</button>', '<div id="global-settings-content"><div class="loading-msg">Loading…</div></div>')}
1498
1500
 
1499
- ${settingsPane("g-mcp", "MCP servers", "External tools available to every conversation in this workspace.", '<button class="refresh-btn" onclick="loadMcpServers()">↻</button>', '<div id="mcp-global-msg" class="status-msg" style="display:none"></div><div id="mcp-global-content"><div class="loading-msg">Loading…</div></div>')}
1501
+ ${settingsPane("g-mcp", "MCP servers", "External tools available to every conversation in this workspace.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadMcpServers()">↻</button>', '<div id="mcp-global-msg" class="status-msg" style="display:none"></div><div id="mcp-global-content"><div class="loading-msg">Loading…</div></div>')}
1500
1502
 
1501
- ${settingsPane("g-skills", "Skills", "Shared instructions available to every conversation in this workspace.", '<button class="primary-action-btn" onclick="openSkillDialog(\'global\')">+ New global skill</button><button class="refresh-btn" onclick="loadGlobalSkills()">↻</button>', '<div class="workspace-split"><div id="global-skills-content" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="global-skills-preview" class="workspace-preview"><div class="placeholder-msg">Click a skill to preview SKILL.md</div></div></div>')}
1503
+ ${settingsPane("g-skills", "Skills", "Shared instructions available to every conversation in this workspace.", '<button class="primary-action-btn" onclick="openSkillDialog(\'global\')">+ New global skill</button><button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadGlobalSkills()">↻</button>', '<div class="workspace-split"><div id="global-skills-content" class="workspace-tree"><div class="loading-msg">Loading…</div></div><div id="global-skills-preview" class="workspace-preview"><div class="placeholder-msg">Click a skill to preview SKILL.md</div></div></div>')}
1502
1504
 
1503
- ${settingsPane("g-events", "Global events", "Every scheduled event across the whole workspace.", '<button class="refresh-btn" onclick="loadEvents()">↻</button>', '<div id="global-events-content"><div class="loading-msg">Loading…</div></div>')}
1505
+ ${settingsPane("g-events", "Global events", "Every scheduled event across the whole workspace.", '<button class="refresh-btn" type="button" aria-label="Refresh" title="Refresh" onclick="loadEvents()">↻</button>', '<div id="global-events-content"><div class="loading-msg">Loading…</div></div>')}
1504
1506
  </div>
1505
1507
  </div>
1506
1508
  </div>
@@ -2983,6 +2985,9 @@ const adminViewStyles = `
2983
2985
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
2984
2986
  }
2985
2987
  .config-block { display: flex; flex-direction: column; gap: 10px; }
2988
+ /* Config blocks are flex columns, so a plain child button stretches to the
2989
+ full column width. Keep the save action a normal-sized button instead. */
2990
+ .config-block .primary-action-btn { align-self: flex-start; min-width: 132px; justify-content: center; }
2986
2991
  .config-row { display: grid; grid-template-columns: 110px 1fr; gap: 10px; align-items: center; }
2987
2992
  .config-row.config-row-stack { grid-template-columns: 1fr; }
2988
2993
  .config-row label { font-size: 0.82rem; color: var(--muted); }
@@ -3060,14 +3065,14 @@ const adminViewStyles = `
3060
3065
  .skill-row {
3061
3066
  padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px;
3062
3067
  background: rgba(0,0,0,0.02);
3063
- display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
3068
+ display: flex; flex-direction: column; align-items: stretch; gap: 6px;
3064
3069
  }
3065
3070
  .skill-row-btn {
3066
3071
  flex: 1 1 auto; min-width: 0; text-align: left; cursor: pointer; font-family: inherit;
3067
3072
  background: transparent; border: none; padding: 0;
3068
3073
  }
3069
3074
  .skill-row-btn:hover .skill-name { color: var(--accent); }
3070
- .skill-row-actions { display: flex; gap: 6px; flex-shrink: 0; }
3075
+ .skill-row-actions { display: flex; gap: 6px; flex-shrink: 0; justify-content: flex-end; }
3071
3076
  .skill-name {
3072
3077
  font-weight: 650; font-size: 0.9rem; color: var(--text);
3073
3078
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
@@ -3379,9 +3384,20 @@ const adminViewStyles = `
3379
3384
  @media (max-width: 860px) {
3380
3385
  .settings-shell { grid-template-columns: 1fr; }
3381
3386
  .settings-rail { position: static; }
3382
- .rail-nav { flex-direction: row; flex-wrap: wrap; }
3383
- .rail-link span { display: none; }
3384
- .rail-link { padding: 9px; }
3387
+ /* Keep labels on narrow screens: a scrollable chip row is far easier to
3388
+ scan than a row of bare icons with no text. */
3389
+ .rail-nav {
3390
+ flex-direction: row; flex-wrap: nowrap; gap: 6px;
3391
+ overflow-x: auto; padding-bottom: 6px;
3392
+ /* Without min-width:0 a nowrap flex row refuses to shrink and blows the
3393
+ page width out instead of scrolling. */
3394
+ min-width: 0; max-width: 100%;
3395
+ scrollbar-width: thin; -webkit-overflow-scrolling: touch;
3396
+ }
3397
+ .settings-rail { min-width: 0; }
3398
+ .rail-nav[hidden] { display: none; }
3399
+ .rail-link { flex: 0 0 auto; padding: 7px 11px; }
3400
+ .rail-link span { white-space: nowrap; }
3385
3401
  }
3386
3402
 
3387
3403
  @media (max-width: 640px) {