Class: Ace::Idea::Molecules::IdeaCreator

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/idea/molecules/idea_creator.rb

Overview

Creates new ideas with b36ts IDs, folder/file creation. Supports –clipboard, –llm-enhance, and –move-to options.

Defined Under Namespace

Classes: IdCollisionError

Instance Method Summary collapse

Constructor Details

#initialize(root_dir:, config: {}) ⇒ IdeaCreator

Returns a new instance of IdeaCreator.

Parameters:

  • root_dir (String)

    Root directory for ideas

  • config (Hash) (defaults to: {})

    Configuration hash



23
24
25
26
# File 'lib/ace/idea/molecules/idea_creator.rb', line 23

def initialize(root_dir:, config: {})
  @root_dir = root_dir
  @config = config
end

Instance Method Details

#create(content = nil, title: nil, tags: [], move_to: nil, clipboard: false, llm_enhance: false, time: Time.now.utc, prepared_payload: nil) ⇒ Idea

Create a new idea

Parameters:

  • content (String) (defaults to: nil)

    Raw idea content/text

  • title (String, nil) (defaults to: nil)

    Optional title (extracted from content if nil)

  • tags (Array<String>) (defaults to: [])

    Tags for the idea

  • move_to (String, nil) (defaults to: nil)

    Target folder for the idea

  • clipboard (Boolean) (defaults to: false)

    Capture from system clipboard

  • llm_enhance (Boolean) (defaults to: false)

    Enhance with LLM

  • time (Time) (defaults to: Time.now.utc)

    Creation time (default: now)

Returns:

  • (Idea)

    Created idea object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ace/idea/molecules/idea_creator.rb', line 37

def create(content = nil, title: nil, tags: [], move_to: nil,
  clipboard: false, llm_enhance: false, time: Time.now.utc, prepared_payload: nil)
  payload = prepared_payload || prepare_create_payload(content, clipboard: clipboard, llm_enhance: llm_enhance)
  enhanced_body = payload.fetch(:enhanced_body)
  attachments_to_save = payload.fetch(:attachments_to_save)

  # Step 3: Generate ID and slugs
  id = Atoms::IdeaIdFormatter.generate(time)
  with_id_reservation(id) do
    raise IdCollisionError, "Idea ID collision detected for #{id}" if idea_id_exists?(id)

    slug_title = title || extract_title(enhanced_body)
    folder_slug = generate_folder_slug(slug_title)
    file_slug = generate_file_slug(slug_title)

    # Step 4: Determine target directory
    target_dir = determine_target_dir(move_to)
    FileUtils.mkdir_p(target_dir)

    # Step 5: Create idea folder
    folder_name, _ = unique_folder_name(id, folder_slug, target_dir)
    idea_dir = File.join(target_dir, folder_name)
    FileUtils.mkdir_p(idea_dir)

    begin
      # Step 6: Handle attachments
      if attachments_to_save.any?
        enhanced_body = save_attachments_and_inject_refs(attachments_to_save, idea_dir, enhanced_body)
      end

      # Step 7: Write spec file
      effective_title = title || extract_title(enhanced_body) || "Untitled Idea"
      frontmatter = Atoms::IdeaFrontmatterDefaults.build(
        id: id,
        title: effective_title,
        tags: tags,
        status: "pending",
        created_at: time
      )

      file_content = build_file_content(frontmatter, enhanced_body, effective_title)
      spec_filename = Atoms::IdeaFilePattern.spec_filename(id, file_slug)
      spec_file = File.join(idea_dir, spec_filename)
      File.write(spec_file, file_content)

      # Step 8: Load and return the created idea
      loader = IdeaLoader.new
      special_folder = Ace::Support::Items::Atoms::SpecialFolderDetector.detect_in_path(
        idea_dir, root: @root_dir
      )
      loader.load(idea_dir, id: id, special_folder: special_folder)
    rescue StandardError
      FileUtils.rm_rf(idea_dir) if Dir.exist?(idea_dir)
      raise
    end
  end
end

#prepare_create_payload(content, clipboard: false, llm_enhance: false) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ace/idea/molecules/idea_creator.rb', line 95

def prepare_create_payload(content, clipboard: false, llm_enhance: false)
  body, attachments_to_save = gather_content(content, clipboard: clipboard)

  if body.nil? || body.strip.empty?
    raise ArgumentError, "No content provided. Provide text or use --clipboard."
  end

  enhanced_body = if llm_enhance
    enhance_with_llm(body, config: @config)
  else
    body
  end

  {
    enhanced_body: enhanced_body,
    attachments_to_save: attachments_to_save
  }
end