aidp 0.13.0 → 0.14.0
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 +4 -4
- data/README.md +7 -0
- data/lib/aidp/cli/first_run_wizard.rb +28 -303
- data/lib/aidp/cli/issue_importer.rb +359 -0
- data/lib/aidp/cli.rb +151 -3
- data/lib/aidp/daemon/process_manager.rb +146 -0
- data/lib/aidp/daemon/runner.rb +232 -0
- data/lib/aidp/execute/async_work_loop_runner.rb +216 -0
- data/lib/aidp/execute/future_work_backlog.rb +411 -0
- data/lib/aidp/execute/guard_policy.rb +246 -0
- data/lib/aidp/execute/instruction_queue.rb +131 -0
- data/lib/aidp/execute/interactive_repl.rb +335 -0
- data/lib/aidp/execute/repl_macros.rb +651 -0
- data/lib/aidp/execute/steps.rb +8 -0
- data/lib/aidp/execute/work_loop_runner.rb +322 -36
- data/lib/aidp/execute/work_loop_state.rb +162 -0
- data/lib/aidp/harness/config_schema.rb +88 -0
- data/lib/aidp/harness/configuration.rb +48 -1
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +2 -0
- data/lib/aidp/init/doc_generator.rb +256 -0
- data/lib/aidp/init/project_analyzer.rb +343 -0
- data/lib/aidp/init/runner.rb +83 -0
- data/lib/aidp/init.rb +5 -0
- data/lib/aidp/logger.rb +279 -0
- data/lib/aidp/setup/wizard.rb +777 -0
- data/lib/aidp/tooling_detector.rb +115 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +282 -0
- data/lib/aidp/watch/plan_generator.rb +166 -0
- data/lib/aidp/watch/plan_processor.rb +83 -0
- data/lib/aidp/watch/repository_client.rb +243 -0
- data/lib/aidp/watch/runner.rb +93 -0
- data/lib/aidp/watch/state_store.rb +105 -0
- data/lib/aidp/watch.rb +9 -0
- data/lib/aidp.rb +14 -0
- data/templates/implementation/simple_task.md +36 -0
- metadata +26 -1
@@ -0,0 +1,243 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "net/http"
|
5
|
+
require "open3"
|
6
|
+
require "uri"
|
7
|
+
|
8
|
+
module Aidp
|
9
|
+
module Watch
|
10
|
+
# Lightweight adapter around GitHub for watch mode. Prefers the GitHub CLI
|
11
|
+
# (works for private repositories) and falls back to public REST endpoints
|
12
|
+
# when the CLI is unavailable.
|
13
|
+
class RepositoryClient
|
14
|
+
attr_reader :owner, :repo
|
15
|
+
|
16
|
+
def self.parse_issues_url(issues_url)
|
17
|
+
case issues_url
|
18
|
+
when %r{\Ahttps://github\.com/([^/]+)/([^/]+)(?:/issues)?/?\z}
|
19
|
+
[$1, $2]
|
20
|
+
when %r{\A([^/]+)/([^/]+)\z}
|
21
|
+
[$1, $2]
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Unsupported issues URL: #{issues_url}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(owner:, repo:, gh_available: nil)
|
28
|
+
@owner = owner
|
29
|
+
@repo = repo
|
30
|
+
@gh_available = gh_available.nil? ? gh_cli_available? : gh_available
|
31
|
+
end
|
32
|
+
|
33
|
+
def gh_available?
|
34
|
+
@gh_available
|
35
|
+
end
|
36
|
+
|
37
|
+
def full_repo
|
38
|
+
"#{owner}/#{repo}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def list_issues(labels: [], state: "open")
|
42
|
+
gh_available? ? list_issues_via_gh(labels: labels, state: state) : list_issues_via_api(labels: labels, state: state)
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_issue(number)
|
46
|
+
gh_available? ? fetch_issue_via_gh(number) : fetch_issue_via_api(number)
|
47
|
+
end
|
48
|
+
|
49
|
+
def post_comment(number, body)
|
50
|
+
gh_available? ? post_comment_via_gh(number, body) : post_comment_via_api(number, body)
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_pull_request(title:, body:, head:, base:, issue_number:)
|
54
|
+
gh_available? ? create_pull_request_via_gh(title: title, body: body, head: head, base: base, issue_number: issue_number) : raise("GitHub CLI not available - cannot create PR")
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def gh_cli_available?
|
60
|
+
_stdout, _stderr, status = Open3.capture3("gh", "--version")
|
61
|
+
status.success?
|
62
|
+
rescue Errno::ENOENT
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def list_issues_via_gh(labels:, state:)
|
67
|
+
json_fields = %w[number title labels updatedAt state url assignees]
|
68
|
+
cmd = ["gh", "issue", "list", "--repo", full_repo, "--state", state, "--json", json_fields.join(",")]
|
69
|
+
labels.each do |label|
|
70
|
+
cmd += ["--label", label]
|
71
|
+
end
|
72
|
+
|
73
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
74
|
+
unless status.success?
|
75
|
+
warn("GitHub CLI list failed: #{stderr}")
|
76
|
+
return []
|
77
|
+
end
|
78
|
+
|
79
|
+
JSON.parse(stdout).map { |raw| normalize_issue(raw) }
|
80
|
+
rescue JSON::ParserError => e
|
81
|
+
warn("Failed to parse GH CLI response: #{e.message}")
|
82
|
+
[]
|
83
|
+
end
|
84
|
+
|
85
|
+
def list_issues_via_api(labels:, state:)
|
86
|
+
label_param = labels.join(",")
|
87
|
+
uri = URI("https://api.github.com/repos/#{full_repo}/issues?state=#{state}")
|
88
|
+
uri.query = [uri.query, "labels=#{URI.encode_www_form_component(label_param)}"].compact.join("&") unless label_param.empty?
|
89
|
+
|
90
|
+
response = Net::HTTP.get_response(uri)
|
91
|
+
return [] unless response.code == "200"
|
92
|
+
|
93
|
+
JSON.parse(response.body).reject { |item| item["pull_request"] }.map { |raw| normalize_issue_api(raw) }
|
94
|
+
rescue => e
|
95
|
+
warn("GitHub API list failed: #{e.message}")
|
96
|
+
[]
|
97
|
+
end
|
98
|
+
|
99
|
+
def fetch_issue_via_gh(number)
|
100
|
+
fields = %w[number title body comments labels state assignees url updatedAt author]
|
101
|
+
cmd = ["gh", "issue", "view", number.to_s, "--repo", full_repo, "--json", fields.join(",")]
|
102
|
+
|
103
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
104
|
+
raise "GitHub CLI error: #{stderr.strip}" unless status.success?
|
105
|
+
|
106
|
+
data = JSON.parse(stdout)
|
107
|
+
normalize_issue_detail(data)
|
108
|
+
rescue JSON::ParserError => e
|
109
|
+
raise "Failed to parse GitHub CLI issue response: #{e.message}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def fetch_issue_via_api(number)
|
113
|
+
uri = URI("https://api.github.com/repos/#{full_repo}/issues/#{number}")
|
114
|
+
response = Net::HTTP.get_response(uri)
|
115
|
+
raise "GitHub API error (#{response.code})" unless response.code == "200"
|
116
|
+
|
117
|
+
data = JSON.parse(response.body)
|
118
|
+
comments = fetch_comments_via_api(number)
|
119
|
+
data["comments"] = comments
|
120
|
+
normalize_issue_detail_api(data)
|
121
|
+
end
|
122
|
+
|
123
|
+
def fetch_comments_via_api(number)
|
124
|
+
uri = URI("https://api.github.com/repos/#{full_repo}/issues/#{number}/comments")
|
125
|
+
response = Net::HTTP.get_response(uri)
|
126
|
+
return [] unless response.code == "200"
|
127
|
+
|
128
|
+
JSON.parse(response.body).map do |raw|
|
129
|
+
{
|
130
|
+
"body" => raw["body"],
|
131
|
+
"author" => raw.dig("user", "login"),
|
132
|
+
"createdAt" => raw["created_at"]
|
133
|
+
}
|
134
|
+
end
|
135
|
+
rescue
|
136
|
+
[]
|
137
|
+
end
|
138
|
+
|
139
|
+
def post_comment_via_gh(number, body)
|
140
|
+
cmd = ["gh", "issue", "comment", number.to_s, "--repo", full_repo, "--body", body]
|
141
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
142
|
+
raise "Failed to post comment via gh: #{stderr.strip}" unless status.success?
|
143
|
+
|
144
|
+
stdout.strip
|
145
|
+
end
|
146
|
+
|
147
|
+
def post_comment_via_api(number, body)
|
148
|
+
uri = URI("https://api.github.com/repos/#{full_repo}/issues/#{number}/comments")
|
149
|
+
request = Net::HTTP::Post.new(uri)
|
150
|
+
request["Content-Type"] = "application/json"
|
151
|
+
request.body = JSON.dump({body: body})
|
152
|
+
|
153
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
154
|
+
http.request(request)
|
155
|
+
end
|
156
|
+
|
157
|
+
raise "GitHub API comment failed (#{response.code})" unless response.code.start_with?("2")
|
158
|
+
response.body
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_pull_request_via_gh(title:, body:, head:, base:, issue_number:)
|
162
|
+
cmd = [
|
163
|
+
"gh", "pr", "create",
|
164
|
+
"--repo", full_repo,
|
165
|
+
"--title", title,
|
166
|
+
"--body", body,
|
167
|
+
"--head", head,
|
168
|
+
"--base", base
|
169
|
+
]
|
170
|
+
cmd += ["--issue", issue_number.to_s] if issue_number
|
171
|
+
|
172
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
173
|
+
raise "Failed to create PR via gh: #{stderr.strip}" unless status.success?
|
174
|
+
|
175
|
+
stdout.strip
|
176
|
+
end
|
177
|
+
|
178
|
+
def normalize_issue(raw)
|
179
|
+
{
|
180
|
+
number: raw["number"],
|
181
|
+
title: raw["title"],
|
182
|
+
labels: Array(raw["labels"]).map { |label| label.is_a?(Hash) ? label["name"] : label },
|
183
|
+
updated_at: raw["updatedAt"],
|
184
|
+
state: raw["state"],
|
185
|
+
url: raw["url"],
|
186
|
+
assignees: Array(raw["assignees"]).map { |assignee| assignee.is_a?(Hash) ? assignee["login"] : assignee }
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
def normalize_issue_api(raw)
|
191
|
+
{
|
192
|
+
number: raw["number"],
|
193
|
+
title: raw["title"],
|
194
|
+
labels: Array(raw["labels"]).map { |label| label["name"] },
|
195
|
+
updated_at: raw["updated_at"],
|
196
|
+
state: raw["state"],
|
197
|
+
url: raw["html_url"],
|
198
|
+
assignees: Array(raw["assignees"]).map { |assignee| assignee["login"] }
|
199
|
+
}
|
200
|
+
end
|
201
|
+
|
202
|
+
def normalize_issue_detail(raw)
|
203
|
+
{
|
204
|
+
number: raw["number"],
|
205
|
+
title: raw["title"],
|
206
|
+
body: raw["body"] || "",
|
207
|
+
comments: Array(raw["comments"]).map { |comment| normalize_comment(comment) },
|
208
|
+
labels: Array(raw["labels"]).map { |label| label.is_a?(Hash) ? label["name"] : label },
|
209
|
+
state: raw["state"],
|
210
|
+
assignees: Array(raw["assignees"]).map { |assignee| assignee.is_a?(Hash) ? assignee["login"] : assignee },
|
211
|
+
url: raw["url"],
|
212
|
+
updated_at: raw["updatedAt"]
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
def normalize_issue_detail_api(raw)
|
217
|
+
{
|
218
|
+
number: raw["number"],
|
219
|
+
title: raw["title"],
|
220
|
+
body: raw["body"] || "",
|
221
|
+
comments: Array(raw["comments"]).map { |comment| normalize_comment(comment) },
|
222
|
+
labels: Array(raw["labels"]).map { |label| label["name"] },
|
223
|
+
state: raw["state"],
|
224
|
+
assignees: Array(raw["assignees"]).map { |assignee| assignee["login"] },
|
225
|
+
url: raw["html_url"],
|
226
|
+
updated_at: raw["updated_at"]
|
227
|
+
}
|
228
|
+
end
|
229
|
+
|
230
|
+
def normalize_comment(comment)
|
231
|
+
if comment.is_a?(Hash)
|
232
|
+
{
|
233
|
+
"body" => comment["body"],
|
234
|
+
"author" => comment["author"] || comment.dig("user", "login"),
|
235
|
+
"createdAt" => comment["createdAt"] || comment["created_at"]
|
236
|
+
}
|
237
|
+
else
|
238
|
+
{"body" => comment.to_s}
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-prompt"
|
4
|
+
|
5
|
+
require_relative "../message_display"
|
6
|
+
require_relative "repository_client"
|
7
|
+
require_relative "state_store"
|
8
|
+
require_relative "plan_generator"
|
9
|
+
require_relative "plan_processor"
|
10
|
+
require_relative "build_processor"
|
11
|
+
|
12
|
+
module Aidp
|
13
|
+
module Watch
|
14
|
+
# Coordinates the watch mode loop: monitors issues, handles plan/build
|
15
|
+
# triggers, and keeps running until interrupted.
|
16
|
+
class Runner
|
17
|
+
include Aidp::MessageDisplay
|
18
|
+
|
19
|
+
DEFAULT_INTERVAL = 30
|
20
|
+
|
21
|
+
def initialize(issues_url:, interval: DEFAULT_INTERVAL, provider_name: nil, gh_available: nil, project_dir: Dir.pwd, once: false, prompt: TTY::Prompt.new)
|
22
|
+
@prompt = prompt
|
23
|
+
@interval = interval
|
24
|
+
@once = once
|
25
|
+
@project_dir = project_dir
|
26
|
+
|
27
|
+
owner, repo = RepositoryClient.parse_issues_url(issues_url)
|
28
|
+
@repository_client = RepositoryClient.new(owner: owner, repo: repo, gh_available: gh_available)
|
29
|
+
@state_store = StateStore.new(project_dir: project_dir, repository: "#{owner}/#{repo}")
|
30
|
+
@plan_processor = PlanProcessor.new(
|
31
|
+
repository_client: @repository_client,
|
32
|
+
state_store: @state_store,
|
33
|
+
plan_generator: PlanGenerator.new(provider_name: provider_name)
|
34
|
+
)
|
35
|
+
@build_processor = BuildProcessor.new(
|
36
|
+
repository_client: @repository_client,
|
37
|
+
state_store: @state_store,
|
38
|
+
project_dir: project_dir
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def start
|
43
|
+
display_message("👀 Watch mode enabled for #{@repository_client.full_repo}", type: :highlight)
|
44
|
+
display_message("Polling every #{@interval} seconds. Press Ctrl+C to stop.", type: :muted)
|
45
|
+
|
46
|
+
loop do
|
47
|
+
process_cycle
|
48
|
+
break if @once
|
49
|
+
sleep @interval
|
50
|
+
end
|
51
|
+
rescue Interrupt
|
52
|
+
display_message("\n⏹️ Watch mode interrupted by user", type: :warning)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def process_cycle
|
58
|
+
process_plan_triggers
|
59
|
+
process_build_triggers
|
60
|
+
end
|
61
|
+
|
62
|
+
def process_plan_triggers
|
63
|
+
issues = @repository_client.list_issues(labels: [PlanProcessor::PLAN_LABEL], state: "open")
|
64
|
+
issues.each do |issue|
|
65
|
+
next unless issue_has_label?(issue, PlanProcessor::PLAN_LABEL)
|
66
|
+
|
67
|
+
detailed = @repository_client.fetch_issue(issue[:number])
|
68
|
+
@plan_processor.process(detailed)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def process_build_triggers
|
73
|
+
issues = @repository_client.list_issues(labels: [BuildProcessor::BUILD_LABEL], state: "open")
|
74
|
+
issues.each do |issue|
|
75
|
+
next unless issue_has_label?(issue, BuildProcessor::BUILD_LABEL)
|
76
|
+
|
77
|
+
status = @state_store.build_status(issue[:number])
|
78
|
+
next if status["status"] == "completed"
|
79
|
+
|
80
|
+
detailed = @repository_client.fetch_issue(issue[:number])
|
81
|
+
@build_processor.process(detailed)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def issue_has_label?(issue, label)
|
86
|
+
Array(issue[:labels]).any? do |issue_label|
|
87
|
+
name = issue_label.is_a?(Hash) ? issue_label["name"] : issue_label.to_s
|
88
|
+
name.casecmp(label).zero?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "fileutils"
|
5
|
+
require "time"
|
6
|
+
|
7
|
+
module Aidp
|
8
|
+
module Watch
|
9
|
+
# Persists watch mode progress for each repository/issue pair. Used to
|
10
|
+
# avoid re-processing plan/build triggers and to retain generated plan
|
11
|
+
# context between runs.
|
12
|
+
class StateStore
|
13
|
+
attr_reader :path
|
14
|
+
|
15
|
+
def initialize(project_dir:, repository:)
|
16
|
+
@project_dir = project_dir
|
17
|
+
@repository = repository
|
18
|
+
@path = File.join(project_dir, ".aidp", "watch", "#{sanitize_repository(repository)}.yml")
|
19
|
+
ensure_directory
|
20
|
+
end
|
21
|
+
|
22
|
+
def plan_processed?(issue_number)
|
23
|
+
plans.key?(issue_number.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
def plan_data(issue_number)
|
27
|
+
plans[issue_number.to_s]
|
28
|
+
end
|
29
|
+
|
30
|
+
def record_plan(issue_number, data)
|
31
|
+
payload = {
|
32
|
+
"summary" => data[:summary],
|
33
|
+
"tasks" => data[:tasks],
|
34
|
+
"questions" => data[:questions],
|
35
|
+
"comment_body" => data[:comment_body],
|
36
|
+
"comment_hint" => data[:comment_hint],
|
37
|
+
"posted_at" => data[:posted_at] || Time.now.utc.iso8601
|
38
|
+
}.compact
|
39
|
+
|
40
|
+
plans[issue_number.to_s] = payload
|
41
|
+
save!
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_status(issue_number)
|
45
|
+
builds[issue_number.to_s] || {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def record_build_status(issue_number, status:, details: {})
|
49
|
+
builds[issue_number.to_s] = {
|
50
|
+
"status" => status,
|
51
|
+
"updated_at" => Time.now.utc.iso8601
|
52
|
+
}.merge(stringify_keys(details))
|
53
|
+
save!
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def ensure_directory
|
59
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
60
|
+
end
|
61
|
+
|
62
|
+
def sanitize_repository(repository)
|
63
|
+
repository.tr("/", "_")
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_state
|
67
|
+
@state ||= if File.exist?(@path)
|
68
|
+
YAML.safe_load_file(@path, permitted_classes: [Time]) || {}
|
69
|
+
else
|
70
|
+
{}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def save!
|
75
|
+
File.write(@path, YAML.dump(state))
|
76
|
+
end
|
77
|
+
|
78
|
+
def state
|
79
|
+
@state = nil if @state && !@state.is_a?(Hash)
|
80
|
+
@state ||= begin
|
81
|
+
base = load_state
|
82
|
+
base["plans"] ||= {}
|
83
|
+
base["builds"] ||= {}
|
84
|
+
base
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def plans
|
89
|
+
state["plans"]
|
90
|
+
end
|
91
|
+
|
92
|
+
def builds
|
93
|
+
state["builds"]
|
94
|
+
end
|
95
|
+
|
96
|
+
def stringify_keys(hash)
|
97
|
+
return {} unless hash
|
98
|
+
|
99
|
+
hash.each_with_object({}) do |(key, value), memo|
|
100
|
+
memo[key.to_s] = value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/aidp/watch.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "message_display"
|
4
|
+
require_relative "watch/repository_client"
|
5
|
+
require_relative "watch/state_store"
|
6
|
+
require_relative "watch/plan_generator"
|
7
|
+
require_relative "watch/plan_processor"
|
8
|
+
require_relative "watch/build_processor"
|
9
|
+
require_relative "watch/runner"
|
data/lib/aidp.rb
CHANGED
@@ -8,6 +8,9 @@ require_relative "aidp/version"
|
|
8
8
|
require_relative "aidp/config"
|
9
9
|
require_relative "aidp/util"
|
10
10
|
require_relative "aidp/message_display"
|
11
|
+
require_relative "aidp/setup/wizard"
|
12
|
+
require_relative "aidp/init"
|
13
|
+
require_relative "aidp/watch"
|
11
14
|
require_relative "aidp/cli"
|
12
15
|
|
13
16
|
# Jobs and background execution
|
@@ -54,6 +57,17 @@ require_relative "aidp/execute/runner"
|
|
54
57
|
require_relative "aidp/execute/progress"
|
55
58
|
require_relative "aidp/execute/checkpoint"
|
56
59
|
require_relative "aidp/execute/checkpoint_display"
|
60
|
+
require_relative "aidp/execute/work_loop_state"
|
61
|
+
require_relative "aidp/execute/instruction_queue"
|
62
|
+
require_relative "aidp/execute/async_work_loop_runner"
|
63
|
+
require_relative "aidp/execute/interactive_repl"
|
64
|
+
|
65
|
+
# Logging
|
66
|
+
require_relative "aidp/logger"
|
67
|
+
|
68
|
+
# Daemon mode
|
69
|
+
require_relative "aidp/daemon/process_manager"
|
70
|
+
require_relative "aidp/daemon/runner"
|
57
71
|
|
58
72
|
# Harness mode
|
59
73
|
require_relative "aidp/harness/configuration"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Simple Task Execution
|
2
|
+
|
3
|
+
You are executing a simple, focused task within the AIDP work loop.
|
4
|
+
|
5
|
+
## Your Task
|
6
|
+
|
7
|
+
{{task_description}}
|
8
|
+
|
9
|
+
## Important Instructions
|
10
|
+
|
11
|
+
1. **Read the task above carefully**
|
12
|
+
2. **Execute the task exactly as described**
|
13
|
+
3. **Verify your work** by running any validation commands specified
|
14
|
+
4. **Edit this PROMPT.md** to track progress and mark complete when done
|
15
|
+
|
16
|
+
## Completion Criteria
|
17
|
+
|
18
|
+
When the task is 100% complete:
|
19
|
+
|
20
|
+
1. The task description requirements are fully met
|
21
|
+
2. Any specified validation commands pass
|
22
|
+
3. You've added this line to PROMPT.md:
|
23
|
+
|
24
|
+
```
|
25
|
+
STATUS: COMPLETE
|
26
|
+
```
|
27
|
+
|
28
|
+
## Context
|
29
|
+
|
30
|
+
{{additional_context}}
|
31
|
+
|
32
|
+
## Notes
|
33
|
+
|
34
|
+
- Keep your changes minimal and focused on the task
|
35
|
+
- If the task involves running commands, show the command output
|
36
|
+
- If the task involves fixing issues, list what was fixed
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aidp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bart Agapinan
|
@@ -250,21 +250,31 @@ files:
|
|
250
250
|
- lib/aidp/cli/checkpoint_command.rb
|
251
251
|
- lib/aidp/cli/enhanced_input.rb
|
252
252
|
- lib/aidp/cli/first_run_wizard.rb
|
253
|
+
- lib/aidp/cli/issue_importer.rb
|
253
254
|
- lib/aidp/cli/jobs_command.rb
|
254
255
|
- lib/aidp/cli/mcp_dashboard.rb
|
255
256
|
- lib/aidp/cli/terminal_io.rb
|
256
257
|
- lib/aidp/config.rb
|
257
258
|
- lib/aidp/config/paths.rb
|
258
259
|
- lib/aidp/core_ext/class_attribute.rb
|
260
|
+
- lib/aidp/daemon/process_manager.rb
|
261
|
+
- lib/aidp/daemon/runner.rb
|
259
262
|
- lib/aidp/debug_logger.rb
|
260
263
|
- lib/aidp/debug_mixin.rb
|
264
|
+
- lib/aidp/execute/async_work_loop_runner.rb
|
261
265
|
- lib/aidp/execute/checkpoint.rb
|
262
266
|
- lib/aidp/execute/checkpoint_display.rb
|
267
|
+
- lib/aidp/execute/future_work_backlog.rb
|
268
|
+
- lib/aidp/execute/guard_policy.rb
|
269
|
+
- lib/aidp/execute/instruction_queue.rb
|
270
|
+
- lib/aidp/execute/interactive_repl.rb
|
263
271
|
- lib/aidp/execute/progress.rb
|
264
272
|
- lib/aidp/execute/prompt_manager.rb
|
273
|
+
- lib/aidp/execute/repl_macros.rb
|
265
274
|
- lib/aidp/execute/runner.rb
|
266
275
|
- lib/aidp/execute/steps.rb
|
267
276
|
- lib/aidp/execute/work_loop_runner.rb
|
277
|
+
- lib/aidp/execute/work_loop_state.rb
|
268
278
|
- lib/aidp/execute/workflow_selector.rb
|
269
279
|
- lib/aidp/harness/completion_checker.rb
|
270
280
|
- lib/aidp/harness/condition_detector.rb
|
@@ -311,7 +321,12 @@ files:
|
|
311
321
|
- lib/aidp/harness/ui/status_widget.rb
|
312
322
|
- lib/aidp/harness/ui/workflow_controller.rb
|
313
323
|
- lib/aidp/harness/user_interface.rb
|
324
|
+
- lib/aidp/init.rb
|
325
|
+
- lib/aidp/init/doc_generator.rb
|
326
|
+
- lib/aidp/init/project_analyzer.rb
|
327
|
+
- lib/aidp/init/runner.rb
|
314
328
|
- lib/aidp/jobs/background_runner.rb
|
329
|
+
- lib/aidp/logger.rb
|
315
330
|
- lib/aidp/message_display.rb
|
316
331
|
- lib/aidp/provider_manager.rb
|
317
332
|
- lib/aidp/providers/anthropic.rb
|
@@ -322,11 +337,20 @@ files:
|
|
322
337
|
- lib/aidp/providers/github_copilot.rb
|
323
338
|
- lib/aidp/providers/macos_ui.rb
|
324
339
|
- lib/aidp/providers/opencode.rb
|
340
|
+
- lib/aidp/setup/wizard.rb
|
325
341
|
- lib/aidp/storage/csv_storage.rb
|
326
342
|
- lib/aidp/storage/file_manager.rb
|
327
343
|
- lib/aidp/storage/json_storage.rb
|
344
|
+
- lib/aidp/tooling_detector.rb
|
328
345
|
- lib/aidp/util.rb
|
329
346
|
- lib/aidp/version.rb
|
347
|
+
- lib/aidp/watch.rb
|
348
|
+
- lib/aidp/watch/build_processor.rb
|
349
|
+
- lib/aidp/watch/plan_generator.rb
|
350
|
+
- lib/aidp/watch/plan_processor.rb
|
351
|
+
- lib/aidp/watch/repository_client.rb
|
352
|
+
- lib/aidp/watch/runner.rb
|
353
|
+
- lib/aidp/watch/state_store.rb
|
330
354
|
- lib/aidp/workflows/definitions.rb
|
331
355
|
- lib/aidp/workflows/guided_agent.rb
|
332
356
|
- lib/aidp/workflows/selector.rb
|
@@ -356,6 +380,7 @@ files:
|
|
356
380
|
- templates/implementation/plan_delivery.md
|
357
381
|
- templates/implementation/review_post_release.md
|
358
382
|
- templates/implementation/setup_scaffolding.md
|
383
|
+
- templates/implementation/simple_task.md
|
359
384
|
- templates/planning/ask_architecture_questions.md
|
360
385
|
- templates/planning/create_prd.md
|
361
386
|
- templates/planning/create_tasks.md
|