Class: Aidp::Watch::SubIssueCreator

Inherits:
Object
  • Object
show all
Includes:
MessageDisplay
Defined in:
lib/aidp/watch/sub_issue_creator.rb

Overview

Creates sub-issues from a hierarchical plan during watch mode. Links sub-issues to parent, adds them to projects, and sets custom fields.

Constant Summary collapse

UnresolvedDependenciesError =
Class.new(StandardError)

Constants included from MessageDisplay

MessageDisplay::COLOR_MAP, MessageDisplay::CRITICAL_TYPES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MessageDisplay

#display_message, included, #message_display_prompt, #quiet_mode?

Constructor Details

#initialize(repository_client:, state_store:, project_id: nil, build_label: "aidp-build", blocked_label: "aidp-blocked") ⇒ SubIssueCreator

Returns a new instance of SubIssueCreator.



16
17
18
19
20
21
22
# File 'lib/aidp/watch/sub_issue_creator.rb', line 16

def initialize(repository_client:, state_store:, project_id: nil, build_label: "aidp-build", blocked_label: "aidp-blocked")
  @repository_client = repository_client
  @state_store = state_store
  @project_id = project_id
  @build_label = build_label
  @blocked_label = blocked_label
end

Instance Attribute Details

#project_idObject (readonly)

Returns the value of attribute project_id.



14
15
16
# File 'lib/aidp/watch/sub_issue_creator.rb', line 14

def project_id
  @project_id
end

#repository_clientObject (readonly)

Returns the value of attribute repository_client.



14
15
16
# File 'lib/aidp/watch/sub_issue_creator.rb', line 14

def repository_client
  @repository_client
end

#state_storeObject (readonly)

Returns the value of attribute state_store.



14
15
16
# File 'lib/aidp/watch/sub_issue_creator.rb', line 14

def state_store
  @state_store
end

Instance Method Details

#create_sub_issues(parent_issue, sub_issues_data) ⇒ Array<Hash>

Creates sub-issues from hierarchical plan data

Parameters:

  • parent_issue (Hash)

    The parent issue data

  • sub_issues_data (Array<Hash>)

    Array of sub-issue specifications

Returns:

  • (Array<Hash>)

    Created sub-issue details



28
29
30
31
32
33
34
35
36
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
# File 'lib/aidp/watch/sub_issue_creator.rb', line 28

def create_sub_issues(parent_issue, sub_issues_data)
  parent_number = parent_issue[:number]
  Aidp.log_debug("sub_issue_creator", "create_sub_issues", parent: parent_number, count: sub_issues_data.size)

  display_message("🔨 Creating #{sub_issues_data.size} sub-issues for ##{parent_number}", type: :info)

  created_issues = []
  creation_failed = false

  sub_issues_data.each_with_index do |sub_data, index|
    issue = create_single_sub_issue(parent_issue, sub_data, index + 1)
    created_issues << issue
    display_message("  ✓ Created sub-issue ##{issue[:number]}: #{sub_data[:title]}", type: :success)
  rescue => e
    creation_failed = true
    Aidp.log_error("sub_issue_creator", "Failed to create sub-issue", parent: parent_number, index: index, error: e.message)
    display_message("  ✗ Failed to create sub-issue #{index + 1}: #{e.message}", type: :error)
    break
  end

  return handle_partial_creation_failure(parent_number, created_issues) if creation_failed

  record_dependencies(created_issues)

  # Link all created issues to project if project_id is configured
  if @project_id && created_issues.any?
    link_issues_to_project(parent_number, created_issues.map { |i| i[:number] })
  end

  # Persist the hierarchy only after creation and dependency resolution succeed.
  @state_store.record_sub_issues(parent_number, created_issues.map { |i| i[:number] })

  # Post summary comment on parent issue
  post_sub_issues_summary(parent_issue, created_issues)

  Aidp.log_debug("sub_issue_creator", "create_sub_issues_complete", parent: parent_number, created: created_issues.size)
  created_issues
rescue UnresolvedDependenciesError
  cleanup_created_issues(parent_number, created_issues)
  raise
end

#planned_sub_issue_attributes(parent_issue, sub_data, sequence_number) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/aidp/watch/sub_issue_creator.rb', line 70

def planned_sub_issue_attributes(parent_issue, sub_data, sequence_number)
  dependencies = sub_issue_dependencies(sub_data)
  title = sub_data[:title]
  title = "#{parent_issue[:title]} - Part #{sequence_number}" if title.to_s.strip.empty?

  {
    title: title,
    body: build_sub_issue_body(parent_issue, sub_data, sequence_number),
    labels: sub_issue_labels(sub_data, dependencies),
    assignees: Array(sub_data[:assignees]),
    dependencies: dependencies
  }
end