openclacky 0.9.32 → 0.9.33

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4dd6332b6e7425bea0dd817603ad5af83e4d23b5742b79f5ca97f2d0fc18a0c
4
- data.tar.gz: 640788854a81c8760999e866dce8364c6e2547603098f24582f6b6b51837797b
3
+ metadata.gz: c1e2a5b101fac2a1079e97a31598bdb183dc9649714bc54a5f2f949688a5d70a
4
+ data.tar.gz: c30e593f71f54293dec3f0b862b8fd77536a07a101b04acdec329282c3b91255
5
5
  SHA512:
6
- metadata.gz: 96423895e7df89b17c5eb7196aca0f829e1f5544c14def222d888faddb35a39c78f3df1bdea40d3ce884c9d3edf7b3a4ac8f8447e5ab7394e569ed9d9ffd8038
7
- data.tar.gz: 2f85e85244ddfa8720a9c2cf6fc053d68671e051ce0d2ccafbbb01581b3fc460e1c7cd10c4a05dc93a88614c3f6505e61aaa4510f821a283a39974069f2694a6
6
+ metadata.gz: 2574bc424afc1137f366df2eb14d8e27b54272713329d8bfb18daea5901208ef0878e8e23c0c21a22a0c90920fd07d851fb1cba14969af7eb8a4179fae124b30
7
+ data.tar.gz: 3860a3573c05cd0824029363bd9ea13c3c2e11c46ed9679231a9dd370a98630923d043cc2f83df00ec682ef5dbb5f2361b3acb24862a8129c2166ba4a5cdfcba
data/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.33] - 2026-04-20
11
+
12
+ ### Fixed
13
+ - **Skill evolution targets only user skills**: auto-evolution (skill auto-creation and skill reflection) now skips default and brand skills — only user-created skills in `~/.clacky/skills/` or `.clacky/skills/` are eligible for improvement
14
+ - **Skill auto-creation and reflection run in isolated subagents**: these background analysis tasks no longer inject messages into the main conversation history; they now fork a dedicated subagent that runs fully independently, preventing any interference with the current session
15
+ - **User feedback prompt no longer interrupts agent flow**: removed stray `STOP.` prefix from the in-conversation user-feedback message, allowing the agent to handle feedback naturally without halting unexpectedly
16
+
10
17
  ## [0.9.32] - 2026-04-20
11
18
 
12
19
  ### Added
@@ -5,10 +5,10 @@ module Clacky
5
5
  # Scenario 1: Auto-create new skills from complex task patterns.
6
6
  #
7
7
  # After completing a complex task (high iteration count, no existing skill used),
8
- # inject a system prompt asking the LLM to analyze if the workflow is reusable
9
- # and worth capturing as a new skill.
8
+ # forks a subagent to analyze if the workflow is reusable and worth capturing
9
+ # as a new skill.
10
10
  #
11
- # If the LLM determines it's valuable, it can invoke skill-creator in "quick mode"
11
+ # If the LLM determines it's valuable, it invokes skill-creator in "quick mode"
12
12
  # to generate a new skill automatically.
13
13
  module SkillAutoCreator
14
14
  # Default minimum iterations to consider auto-creating a skill
@@ -19,7 +19,11 @@ module Clacky
19
19
  def maybe_create_skill_from_task
20
20
  return unless should_auto_create_skill?
21
21
 
22
- inject_skill_creation_prompt
22
+ @ui&.show_info("Analyzing task for skill creation opportunity...")
23
+
24
+ # Fork an isolated subagent to evaluate + create — does NOT touch main history
25
+ subagent = fork_subagent
26
+ subagent.run(build_skill_creation_prompt)
23
27
  end
24
28
 
25
29
  # Determine if this task is a candidate for skill auto-creation
@@ -47,19 +51,6 @@ module Clacky
47
51
  }
48
52
  end
49
53
 
50
- # Inject skill creation prompt as a system message
51
- # The LLM will analyze and decide whether to create a new skill
52
- private def inject_skill_creation_prompt
53
- @history.append({
54
- role: "user",
55
- content: build_skill_creation_prompt,
56
- system_injected: true,
57
- skill_auto_create: true
58
- })
59
-
60
- @ui&.show_info("Analyzing task for skill creation opportunity...")
61
- end
62
-
63
54
  # Build the skill auto-creation prompt content
64
55
  # @return [String]
65
56
  private def build_skill_creation_prompt
@@ -205,7 +205,8 @@ module Clacky
205
205
  skill_name: skill.identifier,
206
206
  start_iteration: @iterations,
207
207
  arguments: arguments,
208
- slash_command: slash_command
208
+ slash_command: slash_command,
209
+ source: skill.source
209
210
  }
210
211
 
211
212
  # For encrypted brand skills with supporting scripts: decrypt to a tmpdir so the
@@ -4,12 +4,12 @@ module Clacky
4
4
  class Agent
5
5
  # Scenario 2: Reflect on skill execution and suggest improvements.
6
6
  #
7
- # After a skill completes, inject a system prompt asking the LLM to analyze:
7
+ # After a skill completes, forks a subagent to analyze:
8
8
  # - Were instructions clear enough?
9
9
  # - Any missing edge cases?
10
10
  # - Any improvements needed?
11
11
  #
12
- # If the LLM identifies concrete improvements, it can invoke skill-creator
12
+ # If the LLM identifies concrete improvements, it invokes skill-creator
13
13
  # to update the skill.
14
14
  module SkillReflector
15
15
  # Minimum iterations for a skill execution to warrant reflection.
@@ -27,6 +27,11 @@ module Clacky
27
27
  # platform-management skills invoked incidentally should not be reflected on.
28
28
  return unless @skill_execution_context[:slash_command]
29
29
 
30
+ # Skip default and brand skills — they are system-owned and should not be
31
+ # auto-improved by the evolution system.
32
+ source = @skill_execution_context[:source]
33
+ return if source == :default || source == :brand
34
+
30
35
  skill_name = @skill_execution_context[:skill_name]
31
36
  start_iteration = @skill_execution_context[:start_iteration]
32
37
  iterations = @iterations - start_iteration
@@ -34,28 +39,15 @@ module Clacky
34
39
  # Only reflect if the skill actually ran for a meaningful number of iterations
35
40
  return if iterations < MIN_SKILL_ITERATIONS
36
41
 
37
- inject_skill_reflection_prompt(skill_name, iterations)
42
+ # Fork an isolated subagent to reflect + improve — does NOT touch main history
43
+ @ui&.show_info("Reflecting on skill execution: #{skill_name}")
44
+ subagent = fork_subagent
45
+ subagent.run(build_skill_reflection_prompt(skill_name, iterations))
38
46
 
39
47
  # Clear the context so we don't reflect again
40
48
  @skill_execution_context = nil
41
49
  end
42
50
 
43
- # Inject reflection prompt into history as a system message
44
- # The LLM will respond in the next user interaction (non-blocking)
45
- #
46
- # @param skill_name [String] Identifier of the skill that was executed
47
- # @param iterations [Integer] Number of iterations the skill ran for
48
- private def inject_skill_reflection_prompt(skill_name, iterations)
49
- @history.append({
50
- role: "user",
51
- content: build_skill_reflection_prompt(skill_name, iterations),
52
- system_injected: true,
53
- skill_reflection: true
54
- })
55
-
56
- @ui&.show_info("Reflecting on skill execution: #{skill_name}")
57
- end
58
-
59
51
  # Build the reflection prompt content
60
52
  # @param skill_name [String]
61
53
  # @param iterations [Integer]
data/lib/clacky/agent.rb CHANGED
@@ -395,7 +395,7 @@ module Clacky
395
395
  # Add user feedback as a new user message with system_injected marker
396
396
  @history.append({
397
397
  role: "user",
398
- content: "STOP. The user has a question/feedback for you: #{action_result[:feedback]}\n\nPlease respond to the user's question/feedback before continuing with any actions.",
398
+ content: "The user has a question/feedback for you: #{action_result[:feedback]}\n\nPlease respond to the user's question/feedback before continuing with any actions.",
399
399
  system_injected: true
400
400
  })
401
401
  # Continue loop to let agent respond to feedback
data/lib/clacky/skill.rb CHANGED
@@ -36,6 +36,11 @@ module Clacky
36
36
  attr_reader :fork_agent, :model, :forbidden_tools, :auto_summarize
37
37
  attr_reader :brand_skill, :brand_config
38
38
 
39
+ # Source location of this skill — set by SkillLoader after registration.
40
+ # One of: :default, :global_claude, :global_clacky, :project_claude, :project_clacky, :brand
41
+ # @return [Symbol, nil]
42
+ attr_accessor :source
43
+
39
44
  # Warnings accumulated during load (e.g. name was invalid and fell back to dir name).
40
45
  # Non-empty means the skill loaded but something was auto-corrected.
41
46
  # @return [Array<String>]
@@ -433,6 +433,7 @@ module Clacky
433
433
 
434
434
  @skills[id] = skill
435
435
  @loaded_from[id] = source
436
+ skill.source = source
436
437
 
437
438
  # Invalid skills have no usable slug — skip slash command registration but
438
439
  # still keep them in @skills so they appear (greyed-out) in the UI.
@@ -466,16 +467,7 @@ module Clacky
466
467
 
467
468
  begin
468
469
  skill = Skill.new(Pathname.new(skill_dir))
469
-
470
- # Check for duplicates (higher priority skills override)
471
- if @skills.key?(skill.identifier)
472
- next # Skip if already loaded from higher priority location
473
- end
474
-
475
- # Register skill
476
- @skills[skill.identifier] = skill
477
- @skills_by_command[skill.slash_command] = skill
478
- @loaded_from[skill.identifier] = :default
470
+ register_skill(skill, source: :default)
479
471
  rescue StandardError => e
480
472
  @errors << "Failed to load default skill #{skill_name}: #{e.message}"
481
473
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clacky
4
- VERSION = "0.9.32"
4
+ VERSION = "0.9.33"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openclacky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.32
4
+ version: 0.9.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - windy