@sweny-ai/core 0.1.204 → 0.1.206

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.
@@ -528,12 +528,19 @@ export class ClaudeCodeHarness {
528
528
  // `sweny tool-bridge` stdio shim instead, so no in-process server is built.
529
529
  const useBridge = this.toolBridge && tools.length > 0;
530
530
  const sdkTools = useBridge ? [] : tools.map((t) => coreToolToSdkTool(t, this.defaultContext));
531
- // Create in-process MCP server
531
+ // Create in-process MCP server. `alwaysLoad`: Claude Code defers every MCP
532
+ // server's tools behind ToolSearch by default and starts MCP servers
533
+ // without waiting, so a node's skill tools were not on the model's first
534
+ // turn and it could answer without them (dogfood run 42884113267: the
535
+ // pr-risk-review scope node called only StructuredOutput). These are the
536
+ // few tools the node was given to do its job; they load up front, and the
537
+ // query waits for the server before the first turn.
532
538
  const mcpServer = useBridge
533
539
  ? undefined
534
540
  : createSdkMcpServer({
535
541
  name: "sweny-core",
536
542
  tools: sdkTools,
543
+ alwaysLoad: true,
537
544
  });
538
545
  let bridge;
539
546
  // Build prompt. Context (workflow input such as issues/alerts, plus prior
@@ -565,6 +572,14 @@ export class ClaudeCodeHarness {
565
572
  const allMcpServers = mcpWithheld(!!readOnly, agentAccess)
566
573
  ? {}
567
574
  : { ...this.defaultMcpServers, ...opts.mcpServers, ...this.mcpServers };
575
+ // A server the node's own skills declare (stdio or http) carries tools the
576
+ // node's checks require, so it loads up front like sweny-core below
577
+ // (Claude Code otherwise defers them behind ToolSearch). An explicit
578
+ // `alwaysLoad` in the server config wins.
579
+ for (const name of Object.keys(opts.mcpServers ?? {})) {
580
+ if (allMcpServers[name])
581
+ allMcpServers[name] = { alwaysLoad: true, ...allMcpServers[name] };
582
+ }
568
583
  if (useBridge) {
569
584
  // Only `tools` (already allow/deny and dry-run filtered by the
570
585
  // executor) are exposed. Under readOnly it is still the only MCP
@@ -575,7 +590,8 @@ export class ClaudeCodeHarness {
575
590
  logger: this.logger,
576
591
  ...(this.toolBridgeShim ? { shimCommand: this.toolBridgeShim } : {}),
577
592
  });
578
- allMcpServers["sweny-core"] = bridge.mcpServer;
593
+ // Same reason as the in-process server: the node's tools load up front.
594
+ allMcpServers["sweny-core"] = { ...bridge.mcpServer, alwaysLoad: true };
579
595
  }
580
596
  else if (sdkTools.length > 0) {
581
597
  allMcpServers["sweny-core"] = mcpServer;
@@ -618,6 +634,19 @@ export class ClaudeCodeHarness {
618
634
  },
619
635
  });
620
636
  for await (const message of stream) {
637
+ if (message.type === "system" && message.subtype === "init") {
638
+ // What the agent was actually given: the tool list (--verbose) and,
639
+ // loudly, a node tool server that did not come up.
640
+ const init = message;
641
+ if (Array.isArray(init.tools))
642
+ this.logger.debug(` agent tools: ${init.tools.join(", ")}`);
643
+ const core = Array.isArray(init.mcp_servers)
644
+ ? init.mcp_servers.find((s) => s?.name === "sweny-core")
645
+ : undefined;
646
+ if (allMcpServers["sweny-core"] && core && core.status !== "connected") {
647
+ this.logger.warn(` sweny-core tool server is ${core.status} at start; the node's skill tools may be missing`);
648
+ }
649
+ }
621
650
  if (message.type === "tool_progress") {
622
651
  const tp = message;
623
652
  if (tp.tool_name && typeof tp.elapsed_time_seconds === "number") {
package/dist/index.d.ts CHANGED
@@ -65,3 +65,10 @@ export { SWENY_TAGLINE, PALETTE, ROLE_COLORS, SURFACE_COLORS, GLYPHS, SPINNER_FR
65
65
  export type { ColorRole, GlyphKey, GlyphSet, TicketBox, DiagramNodeStatus } from "./theme.js";
66
66
  export { loadConfigFile } from "./cli/config-file.js";
67
67
  export type { FileConfig } from "./cli/config-file.js";
68
+ export { listRuns, RUN_HISTORY_DIR } from "./cli/run-history.js";
69
+ export type { RunRecord, RunNodeRecord, RunTotals, RunStatus, RunKindSpend } from "./cli/run-history.js";
70
+ export { readRunAnswers, compareAnswers } from "./cli/run-answers.js";
71
+ export type { RunAnswers, AnswersComparison, AnswerDiff } from "./cli/run-answers.js";
72
+ export { printableRun, pickRunsForDiff, formatRunsTable } from "./cli/runs.js";
73
+ export { sanitizeTerminal } from "./cli/terminal.js";
74
+ export { skillEnvWarnings } from "./cli/skill-env.js";
package/dist/index.js CHANGED
@@ -66,3 +66,10 @@ export { toMermaid, toMermaidBlock } from "./mermaid.js";
66
66
  export { SWENY_TAGLINE, PALETTE, ROLE_COLORS, SURFACE_COLORS, GLYPHS, SPINNER_FRAMES, SPINNER_INTERVAL_MS, TICKET_BOX, MERMAID_CLASS_DEFS, MERMAID_EDGE_STYLES, } from "./theme.js";
67
67
  // Config file
68
68
  export { loadConfigFile } from "./cli/config-file.js";
69
+ // Run history and `sweny runs` / `sweny runs diff` (read-only; history is untrusted, see run-history.ts)
70
+ export { listRuns, RUN_HISTORY_DIR } from "./cli/run-history.js";
71
+ export { readRunAnswers, compareAnswers } from "./cli/run-answers.js";
72
+ export { printableRun, pickRunsForDiff, formatRunsTable } from "./cli/runs.js";
73
+ export { sanitizeTerminal } from "./cli/terminal.js";
74
+ // `sweny workflow validate`: skill-env warnings
75
+ export { skillEnvWarnings } from "./cli/skill-env.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweny-ai/core",
3
- "version": "0.1.204",
3
+ "version": "0.1.206",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sweny": "./dist/cli/main.js"