@bike4mind/cli 0.2.21-feat-cli-skill-frontmatter-spec.18205 → 0.2.21-feat-github-actions-tool.18208

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.
Files changed (2) hide show
  1. package/dist/index.js +48 -203
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -2500,8 +2500,10 @@ import { z } from "zod";
2500
2500
  var flexibleString = z.union([z.string(), z.array(z.string())]).transform((val) => Array.isArray(val) ? val.join(" ") : val).optional();
2501
2501
  function needsQuoting(value) {
2502
2502
  const firstChar = value.charAt(0);
2503
- const isProtected = firstChar === '"' || firstChar === "'" || firstChar === "[" || firstChar === "{";
2504
- return value.includes(":") && !isProtected;
2503
+ const isAlreadyQuoted = firstChar === '"' || firstChar === "'";
2504
+ const isStructured = firstChar === "[" || firstChar === "{";
2505
+ const containsColon = value.includes(":");
2506
+ return containsColon && !isAlreadyQuoted && !isStructured;
2505
2507
  }
2506
2508
  function preprocessFrontmatter(content) {
2507
2509
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -2523,66 +2525,29 @@ function preprocessFrontmatter(content) {
2523
2525
  ${processedFrontmatter}
2524
2526
  ---`);
2525
2527
  }
2526
- var HooksSchema = z.object({
2527
- /** Script to run before skill execution */
2528
- "pre-invoke": z.string().optional(),
2529
- /** Script to run after successful skill execution */
2530
- "post-invoke": z.string().optional(),
2531
- /** Script to run when skill execution fails */
2532
- "on-error": z.string().optional()
2533
- }).optional();
2534
- var AgentConfigSchema = z.union([
2535
- z.string(),
2536
- // Simple: "explore"
2537
- z.object({
2538
- // Complex config
2539
- type: z.string(),
2540
- // Agent type name
2541
- thoroughness: z.enum(["quick", "medium", "very_thorough"]).optional(),
2542
- config: z.record(z.any()).optional()
2543
- // Additional agent-specific config
2544
- })
2545
- ]);
2546
- var VALID_MODELS = ["opus", "sonnet", "haiku"];
2547
2528
  var FrontmatterSchema = z.object({
2548
- // Display name for the skill (defaults to filename if not specified)
2549
- name: z.string().optional(),
2550
2529
  description: flexibleString,
2551
2530
  "argument-hint": flexibleString,
2552
- // Model override - validated against allowed values (opus, sonnet, haiku)
2553
2531
  model: z.string().optional(),
2554
2532
  // Agent integration fields
2555
- agent: AgentConfigSchema.optional(),
2533
+ agent: z.string().optional(),
2556
2534
  thoroughness: z.enum(["quick", "medium", "very_thorough"]).optional(),
2557
2535
  variables: z.record(z.string()).optional(),
2558
- // Tool filtering - restrict which tools are available during skill execution
2559
- "allowed-tools": z.array(z.string()).optional(),
2560
- // Execution context: 'inline' (default) runs in main context, 'fork' runs in subagent
2561
- context: z.enum(["fork", "inline"]).default("inline"),
2562
- // Visibility controls
2563
- /** When true, skill is hidden from AI's auto-loading in system prompt */
2564
- "disable-model-invocation": z.boolean().default(false),
2565
- /** When false, skill is hidden from /commands menu but still callable */
2566
- "user-invocable": z.boolean().default(true),
2567
- // Lifecycle hooks
2568
- hooks: HooksSchema
2569
- });
2570
- var DESCRIPTION_MAX_LENGTH = 100;
2571
- var DEFAULT_DESCRIPTION = "Custom command";
2536
+ // Future fields (ignored for now):
2537
+ "allowed-tools": z.any().optional(),
2538
+ context: z.any().optional(),
2539
+ "disable-model-invocation": z.any().optional(),
2540
+ hooks: z.any().optional()
2541
+ });
2572
2542
  function extractDescriptionFromBody(body) {
2573
2543
  const lines = body.trim().split("\n");
2574
- const firstContentLine = lines.find((line) => {
2575
- const trimmed2 = line.trim();
2576
- return trimmed2 && !trimmed2.startsWith("#");
2577
- });
2578
- if (!firstContentLine) {
2579
- return DEFAULT_DESCRIPTION;
2580
- }
2581
- const trimmed = firstContentLine.trim();
2582
- if (trimmed.length <= DESCRIPTION_MAX_LENGTH) {
2583
- return trimmed;
2544
+ for (const line of lines) {
2545
+ const trimmed = line.trim();
2546
+ if (trimmed && !trimmed.startsWith("#")) {
2547
+ return trimmed.length > 100 ? trimmed.substring(0, 97) + "..." : trimmed;
2548
+ }
2584
2549
  }
2585
- return trimmed.substring(0, DESCRIPTION_MAX_LENGTH - 3) + "...";
2550
+ return "Custom command";
2586
2551
  }
2587
2552
  function parseCommandFile(fileContent, filePath, commandName, source) {
2588
2553
  try {
@@ -2596,20 +2561,9 @@ function parseCommandFile(fileContent, filePath, commandName, source) {
2596
2561
  );
2597
2562
  }
2598
2563
  const validFrontmatter = validationResult.success ? validationResult.data : {};
2599
- const description = validFrontmatter.description || extractDescriptionFromBody(body);
2600
- if (validFrontmatter.model && !VALID_MODELS.includes(validFrontmatter.model)) {
2601
- console.warn(
2602
- `Warning: Invalid model "${validFrontmatter.model}" in ${filePath}. Valid values are: ${VALID_MODELS.join(", ")}`
2603
- );
2604
- }
2605
- if (validFrontmatter.agent && validFrontmatter.context !== "fork") {
2606
- console.warn(
2607
- `Warning: Skill "${commandName}" has "agent" specified but "context" is not "fork". The agent field is only used when context is "fork". Consider adding "context: fork" to the frontmatter.`
2608
- );
2609
- }
2564
+ const description = validFrontmatter.description || extractDescriptionFromBody(body) || "Custom command";
2610
2565
  return {
2611
2566
  name: commandName,
2612
- displayName: validFrontmatter.name,
2613
2567
  description,
2614
2568
  argumentHint: validFrontmatter["argument-hint"],
2615
2569
  model: validFrontmatter.model,
@@ -2618,14 +2572,7 @@ function parseCommandFile(fileContent, filePath, commandName, source) {
2618
2572
  filePath,
2619
2573
  agent: validFrontmatter.agent,
2620
2574
  thoroughness: validFrontmatter.thoroughness,
2621
- variables: validFrontmatter.variables,
2622
- // New Claude Code spec fields
2623
- allowedTools: validFrontmatter["allowed-tools"],
2624
- context: validFrontmatter.context || "inline",
2625
- disableModelInvocation: validFrontmatter["disable-model-invocation"] || false,
2626
- userInvocable: validFrontmatter["user-invocable"] !== false,
2627
- // Default true
2628
- hooks: validFrontmatter.hooks
2575
+ variables: validFrontmatter.variables
2629
2576
  };
2630
2577
  } catch (error) {
2631
2578
  throw new Error(
@@ -2633,9 +2580,12 @@ function parseCommandFile(fileContent, filePath, commandName, source) {
2633
2580
  );
2634
2581
  }
2635
2582
  }
2636
- var COMMAND_NAME_PATTERN = /^[a-z0-9-_:]+$/i;
2637
2583
  function isValidCommandName(name) {
2638
- return Boolean(name) && COMMAND_NAME_PATTERN.test(name);
2584
+ if (!name || name.trim().length === 0) {
2585
+ return false;
2586
+ }
2587
+ const validPattern = /^[a-z0-9-_:]+$/i;
2588
+ return validPattern.test(name);
2639
2589
  }
2640
2590
  function extractCommandName(filename) {
2641
2591
  if (!filename.endsWith(".md")) {
@@ -12312,7 +12262,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
12312
12262
  // package.json
12313
12263
  var package_default = {
12314
12264
  name: "@bike4mind/cli",
12315
- version: "0.2.21-feat-cli-skill-frontmatter-spec.18205+406977892",
12265
+ version: "0.2.21-feat-github-actions-tool.18208+9161cdf04",
12316
12266
  type: "module",
12317
12267
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
12318
12268
  license: "UNLICENSED",
@@ -12419,10 +12369,10 @@ var package_default = {
12419
12369
  },
12420
12370
  devDependencies: {
12421
12371
  "@bike4mind/agents": "0.1.0",
12422
- "@bike4mind/common": "2.45.1-feat-cli-skill-frontmatter-spec.18205+406977892",
12423
- "@bike4mind/mcp": "1.25.1-feat-cli-skill-frontmatter-spec.18205+406977892",
12424
- "@bike4mind/services": "2.43.1-feat-cli-skill-frontmatter-spec.18205+406977892",
12425
- "@bike4mind/utils": "2.3.1-feat-cli-skill-frontmatter-spec.18205+406977892",
12372
+ "@bike4mind/common": "2.45.1-feat-github-actions-tool.18208+9161cdf04",
12373
+ "@bike4mind/mcp": "1.25.1-feat-github-actions-tool.18208+9161cdf04",
12374
+ "@bike4mind/services": "2.43.1-feat-github-actions-tool.18208+9161cdf04",
12375
+ "@bike4mind/utils": "2.3.1-feat-github-actions-tool.18208+9161cdf04",
12426
12376
  "@types/better-sqlite3": "^7.6.13",
12427
12377
  "@types/diff": "^5.0.9",
12428
12378
  "@types/jsonwebtoken": "^9.0.4",
@@ -12439,7 +12389,7 @@ var package_default = {
12439
12389
  optionalDependencies: {
12440
12390
  "@vscode/ripgrep": "^1.17.0"
12441
12391
  },
12442
- gitHead: "4069778926e7f1c81c2473a3ac5c25f1a44fbdc2"
12392
+ gitHead: "9161cdf044fad2628e8edfb9fc74ad34465f47c2"
12443
12393
  };
12444
12394
 
12445
12395
  // src/config/constants.ts
@@ -13106,39 +13056,6 @@ function createTodoStore(onUpdate) {
13106
13056
  }
13107
13057
 
13108
13058
  // src/tools/skillTool.ts
13109
- import { exec } from "child_process";
13110
- import { promisify as promisify2 } from "util";
13111
- var execAsync = promisify2(exec);
13112
- async function executeHook(script, context) {
13113
- try {
13114
- const env = {
13115
- ...process.env,
13116
- SKILL_NAME: context.skillName,
13117
- SKILL_ARGS: context.args,
13118
- SKILL_RESULT: context.result || "",
13119
- SKILL_ERROR: context.error || ""
13120
- };
13121
- const { stdout, stderr } = await execAsync(script, {
13122
- env,
13123
- timeout: 3e4,
13124
- // 30 second timeout for hooks
13125
- cwd: process.cwd()
13126
- });
13127
- return { success: true, output: stdout || stderr };
13128
- } catch (error) {
13129
- const message = error instanceof Error ? error.message : String(error);
13130
- return { success: false, output: `Hook failed: ${message}` };
13131
- }
13132
- }
13133
- function parseAgentConfig(agent) {
13134
- if (!agent) {
13135
- return { name: "general-purpose", thoroughness: void 0 };
13136
- }
13137
- if (typeof agent === "string") {
13138
- return { name: agent, thoroughness: void 0 };
13139
- }
13140
- return { name: agent.type, thoroughness: agent.thoroughness };
13141
- }
13142
13059
  function parseArguments(argsString) {
13143
13060
  const args = [];
13144
13061
  let current = "";
@@ -13166,8 +13083,7 @@ function parseArguments(argsString) {
13166
13083
  }
13167
13084
  return args;
13168
13085
  }
13169
- function createSkillTool(deps) {
13170
- const { customCommandStore } = deps;
13086
+ function createSkillTool(customCommandStore) {
13171
13087
  return {
13172
13088
  toolFn: async (args) => {
13173
13089
  const params = args;
@@ -13175,84 +13091,27 @@ function createSkillTool(deps) {
13175
13091
  throw new Error("skill: skill parameter is required");
13176
13092
  }
13177
13093
  const skillName = params.skill.replace(/^\//, "");
13178
- const argsString = params.args || "";
13179
13094
  const command = customCommandStore.getCommand(skillName);
13180
13095
  if (!command) {
13181
13096
  const available = customCommandStore.getAllCommands().map((c) => c.name).join(", ");
13182
13097
  throw new Error(`skill: "${skillName}" not found. Available skills: ${available || "none"}`);
13183
13098
  }
13184
- if (command.hooks?.["pre-invoke"]) {
13185
- const hookResult = await executeHook(command.hooks["pre-invoke"], {
13186
- skillName,
13187
- args: argsString
13188
- });
13189
- if (!hookResult.success) {
13190
- throw new Error(`Pre-invoke hook failed: ${hookResult.output}`);
13191
- }
13192
- }
13193
- try {
13194
- const argsArray = params.args ? parseArguments(params.args) : [];
13195
- let expandedBody = substituteArguments(command.body, argsArray);
13196
- const processed = await processFileReferences(expandedBody);
13197
- expandedBody = processed.content;
13198
- if (processed.errors.length > 0) {
13199
- expandedBody += `
13099
+ const argsArray = params.args ? parseArguments(params.args) : [];
13100
+ let expandedBody = substituteArguments(command.body, argsArray);
13101
+ const processed = await processFileReferences(expandedBody);
13102
+ expandedBody = processed.content;
13103
+ if (processed.errors.length > 0) {
13104
+ expandedBody += `
13200
13105
 
13201
13106
  **File reference errors:**
13202
13107
  ${processed.errors.map((e) => `- ${e}`).join("\n")}`;
13203
- }
13204
- let result;
13205
- if (command.context === "fork") {
13206
- const { subagentOrchestrator, sessionId } = deps;
13207
- if (!subagentOrchestrator || !sessionId) {
13208
- const missing = !subagentOrchestrator ? "subagentOrchestrator" : "sessionId";
13209
- throw new Error(`Skill "${skillName}" requires context: fork but ${missing} is not available`);
13210
- }
13211
- const agentConfig = parseAgentConfig(command.agent);
13212
- const agentResult = await subagentOrchestrator.delegateToAgent({
13213
- task: expandedBody,
13214
- agentName: agentConfig.name,
13215
- thoroughness: agentConfig.thoroughness || command.thoroughness,
13216
- variables: command.variables,
13217
- parentSessionId: sessionId
13218
- });
13219
- const agentName = agentConfig.name;
13220
- result = `## Skill Executed: /${skillName} (via ${agentName} agent)
13221
-
13222
- ${agentResult.summary}`;
13223
- } else {
13224
- result = `## Skill Loaded: /${skillName}
13108
+ }
13109
+ return `## Skill Loaded: /${skillName}
13225
13110
 
13226
13111
  ${expandedBody}
13227
13112
 
13228
13113
  ---
13229
13114
  *Follow the instructions above. This skill was invoked programmatically.*`;
13230
- }
13231
- if (command.hooks?.["post-invoke"]) {
13232
- const hookResult = await executeHook(command.hooks["post-invoke"], {
13233
- skillName,
13234
- args: argsString,
13235
- result
13236
- });
13237
- if (!hookResult.success) {
13238
- console.warn(`Post-invoke hook warning: ${hookResult.output}`);
13239
- }
13240
- }
13241
- return result;
13242
- } catch (error) {
13243
- if (command.hooks?.["on-error"]) {
13244
- const errorMessage = error instanceof Error ? error.message : String(error);
13245
- const hookResult = await executeHook(command.hooks["on-error"], {
13246
- skillName,
13247
- args: argsString,
13248
- error: errorMessage
13249
- });
13250
- if (hookResult.output) {
13251
- console.warn(`On-error hook output: ${hookResult.output}`);
13252
- }
13253
- }
13254
- throw error;
13255
- }
13256
13115
  },
13257
13116
  toolSchema: {
13258
13117
  name: "skill",
@@ -13297,14 +13156,9 @@ ${expandedBody}
13297
13156
  }
13298
13157
 
13299
13158
  // src/core/skillsPrompt.ts
13300
- function getSkillDisplayName(cmd) {
13301
- return cmd.displayName || cmd.name;
13302
- }
13303
13159
  function formatSkillEntry(cmd) {
13304
- const displayName = getSkillDisplayName(cmd);
13305
13160
  const argHint = cmd.argumentHint ? ` ${cmd.argumentHint}` : "";
13306
- const nameDisplay = cmd.displayName && cmd.displayName !== cmd.name ? `**${displayName}** (\`${cmd.name}\`)` : `**${cmd.name}**`;
13307
- return `- ${nameDisplay}${argHint}: ${cmd.description}
13161
+ return `- **${cmd.name}**${argHint}: ${cmd.description}
13308
13162
  `;
13309
13163
  }
13310
13164
  function formatSkillGroup(heading, commands) {
@@ -13315,16 +13169,12 @@ function formatSkillGroup(heading, commands) {
13315
13169
  ### ${heading}
13316
13170
  ${commands.map(formatSkillEntry).join("")}`;
13317
13171
  }
13318
- function filterAIVisibleSkills(commands) {
13319
- return commands.filter((cmd) => !cmd.disableModelInvocation);
13320
- }
13321
13172
  function buildSkillsPromptSection(commands) {
13322
- const visibleCommands = filterAIVisibleSkills(commands);
13323
- if (visibleCommands.length === 0) {
13173
+ if (commands.length === 0) {
13324
13174
  return "";
13325
13175
  }
13326
- const projectSkills = visibleCommands.filter((c) => c.source === "project");
13327
- const globalSkills = visibleCommands.filter((c) => c.source === "global");
13176
+ const projectSkills = commands.filter((c) => c.source === "project");
13177
+ const globalSkills = commands.filter((c) => c.source === "global");
13328
13178
  return `
13329
13179
 
13330
13180
  ## Available Skills
@@ -13619,11 +13469,7 @@ function CliApp() {
13619
13469
  const todoStore = createTodoStore();
13620
13470
  const writeTodosTool = createWriteTodosTool(todoStore);
13621
13471
  const enableSkillTool = config.preferences.enableSkillTool !== false;
13622
- const skillTool = enableSkillTool ? createSkillTool({
13623
- customCommandStore: state.customCommandStore,
13624
- subagentOrchestrator: orchestrator,
13625
- sessionId: newSession.id
13626
- }) : null;
13472
+ const skillTool = enableSkillTool ? createSkillTool(state.customCommandStore) : null;
13627
13473
  const cliTools = [agentDelegateTool, writeTodosTool];
13628
13474
  if (skillTool) {
13629
13475
  cliTools.push(skillTool);
@@ -14188,18 +14034,17 @@ ${output}` : output.trim() || "(no output)",
14188
14034
  }
14189
14035
  const displayMessage = `/${command}${args.length > 0 ? " " + args.join(" ") : ""}`;
14190
14036
  if (customCommand.agent && state.orchestrator && state.agentStore) {
14191
- const agentName = typeof customCommand.agent === "string" ? customCommand.agent : customCommand.agent.type;
14192
- if (!state.agentStore.hasAgent(agentName)) {
14037
+ if (!state.agentStore.hasAgent(customCommand.agent)) {
14193
14038
  const available = state.agentStore.getAgentNames().join(", ");
14194
- console.error(`\u274C Unknown agent "${agentName}" specified in command.`);
14039
+ console.error(`\u274C Unknown agent "${customCommand.agent}" specified in command.`);
14195
14040
  console.error(` Available agents: ${available}`);
14196
14041
  return;
14197
14042
  }
14198
- console.log(`\u{1F916} Delegating to ${agentName} agent...
14043
+ console.log(`\u{1F916} Delegating to ${customCommand.agent} agent...
14199
14044
  `);
14200
14045
  const result = await state.orchestrator.delegateToAgent({
14201
14046
  task: substitutedBody,
14202
- agentName,
14047
+ agentName: customCommand.agent,
14203
14048
  thoroughness: customCommand.thoroughness,
14204
14049
  variables: customCommand.variables,
14205
14050
  parentSessionId: state.session?.id || "unknown"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.21-feat-cli-skill-frontmatter-spec.18205+406977892",
3
+ "version": "0.2.21-feat-github-actions-tool.18208+9161cdf04",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -107,10 +107,10 @@
107
107
  },
108
108
  "devDependencies": {
109
109
  "@bike4mind/agents": "0.1.0",
110
- "@bike4mind/common": "2.45.1-feat-cli-skill-frontmatter-spec.18205+406977892",
111
- "@bike4mind/mcp": "1.25.1-feat-cli-skill-frontmatter-spec.18205+406977892",
112
- "@bike4mind/services": "2.43.1-feat-cli-skill-frontmatter-spec.18205+406977892",
113
- "@bike4mind/utils": "2.3.1-feat-cli-skill-frontmatter-spec.18205+406977892",
110
+ "@bike4mind/common": "2.45.1-feat-github-actions-tool.18208+9161cdf04",
111
+ "@bike4mind/mcp": "1.25.1-feat-github-actions-tool.18208+9161cdf04",
112
+ "@bike4mind/services": "2.43.1-feat-github-actions-tool.18208+9161cdf04",
113
+ "@bike4mind/utils": "2.3.1-feat-github-actions-tool.18208+9161cdf04",
114
114
  "@types/better-sqlite3": "^7.6.13",
115
115
  "@types/diff": "^5.0.9",
116
116
  "@types/jsonwebtoken": "^9.0.4",
@@ -127,5 +127,5 @@
127
127
  "optionalDependencies": {
128
128
  "@vscode/ripgrep": "^1.17.0"
129
129
  },
130
- "gitHead": "4069778926e7f1c81c2473a3ac5c25f1a44fbdc2"
130
+ "gitHead": "9161cdf044fad2628e8edfb9fc74ad34465f47c2"
131
131
  }