@hatchway/cli 0.50.59 → 0.50.60

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
@@ -4419,11 +4419,41 @@ function createNativeClaudeQuery(modelId = DEFAULT_CLAUDE_MODEL_ID, abortControl
4419
4419
  }
4420
4420
  yield transformed;
4421
4421
  }
4422
- // Log system init message to verify skill discovery
4422
+ // Capture SDK init message this is the authoritative source for skill discovery
4423
4423
  if (sdkMessage.type === 'system' && sdkMessage.subtype === 'init') {
4424
4424
  const initMsg = sdkMessage;
4425
- process.stderr.write(`[native-sdk] SDK init - skills: ${JSON.stringify(initMsg.skills ?? [])}\n`);
4426
- process.stderr.write(`[native-sdk] SDK init - tools: ${(initMsg.tools ?? []).length} tools loaded\n`);
4425
+ const discoveredSkills = initMsg.skills ?? [];
4426
+ const loadedPlugins = initMsg.plugins ?? [];
4427
+ const toolCount = (initMsg.tools ?? []).length;
4428
+ process.stderr.write(`[native-sdk] SDK init — skills: [${discoveredSkills.join(', ')}] (${discoveredSkills.length})\n`);
4429
+ process.stderr.write(`[native-sdk] SDK init — plugins: ${JSON.stringify(loadedPlugins)}\n`);
4430
+ process.stderr.write(`[native-sdk] SDK init — tools: ${toolCount} loaded\n`);
4431
+ if (discoveredSkills.length > 0) {
4432
+ Sentry.logger.info('SDK initialized with skills', {
4433
+ skillCount: String(discoveredSkills.length),
4434
+ skills: discoveredSkills.join(', '),
4435
+ pluginCount: String(loadedPlugins.length),
4436
+ plugins: loadedPlugins.map(p => p.name).join(', '),
4437
+ toolCount: String(toolCount),
4438
+ model: initMsg.model ?? modelId,
4439
+ workingDirectory,
4440
+ });
4441
+ }
4442
+ else {
4443
+ Sentry.logger.warn('SDK initialized but no skills discovered', {
4444
+ pluginCount: String(loadedPlugins.length),
4445
+ plugins: JSON.stringify(loadedPlugins),
4446
+ toolCount: String(toolCount),
4447
+ model: initMsg.model ?? modelId,
4448
+ workingDirectory,
4449
+ platformPluginDir: platformPluginDir ?? 'null',
4450
+ });
4451
+ }
4452
+ }
4453
+ // Capture tool_use_summary messages — these indicate skill content loading
4454
+ if (sdkMessage.type === 'tool_use_summary') {
4455
+ const summaryMsg = sdkMessage;
4456
+ process.stderr.write(`[native-sdk] Tool use summary: ${summaryMsg.summary}\n`);
4427
4457
  }
4428
4458
  // Log result messages
4429
4459
  if (sdkMessage.type === 'result') {
@@ -7940,6 +7970,29 @@ function transformAgentMessageToSSE(agentMessage) {
7940
7970
  return cleaned;
7941
7971
  };
7942
7972
  for (const block of message.content) {
7973
+ // Detect skill invocations: the SDK loads skills via Read tool calls to SKILL.md files
7974
+ if (block.type === 'tool_use' && block.name === 'Read') {
7975
+ const filePath = block.input?.file_path || block.input?.filePath || block.input?.path || '';
7976
+ if (typeof filePath === 'string' && filePath.includes('SKILL.md')) {
7977
+ // Extract skill name from path: .../skills/<skill-name>/SKILL.md
7978
+ const skillMatch = filePath.match(/skills\/([^/]+)\/SKILL\.md/);
7979
+ const skillName = skillMatch ? skillMatch[1] : 'unknown';
7980
+ // Emit a skill-invocation event so the frontend can display it
7981
+ events.push({
7982
+ type: 'tool-input-available',
7983
+ toolCallId: block.id,
7984
+ toolName: 'SkillLoad',
7985
+ input: {
7986
+ skillName,
7987
+ filePath,
7988
+ },
7989
+ });
7990
+ // Store tool name as SkillLoad so output is also tagged
7991
+ transformerState.toolNames.set(block.id, 'SkillLoad');
7992
+ // Skip normal tool_use processing for this block
7993
+ continue;
7994
+ }
7995
+ }
7943
7996
  if (block.type === 'text' && block.text) {
7944
7997
  let text = String(block.text);
7945
7998
  // CRITICAL: Remove ALL task status formats from text BEFORE processing