ask-coding-providers 0.1.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 +7 -0
- data/lib/ask/coding_providers/acp/adapter.rb +175 -0
- data/lib/ask/coding_providers/acp.rb +11 -0
- data/lib/ask/coding_providers/adapter.rb +152 -0
- data/lib/ask/coding_providers/ask_agent/adapter.rb +182 -0
- data/lib/ask/coding_providers/ask_agent.rb +19 -0
- data/lib/ask/coding_providers/claude/adapter.rb +182 -0
- data/lib/ask/coding_providers/claude.rb +11 -0
- data/lib/ask/coding_providers/codex/adapter.rb +200 -0
- data/lib/ask/coding_providers/codex/app_server_client.rb +261 -0
- data/lib/ask/coding_providers/codex/codex_db.rb +210 -0
- data/lib/ask/coding_providers/codex.rb +14 -0
- data/lib/ask/coding_providers/version.rb +7 -0
- data/lib/ask/coding_providers/zcode/zcode_db.rb +195 -0
- data/lib/ask/coding_providers/zcode.rb +12 -0
- data/lib/ask/coding_providers.rb +53 -0
- data/lib/ask-coding-providers.rb +3 -0
- metadata +115 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Ask
|
|
6
|
+
module CodingProviders
|
|
7
|
+
module Codex
|
|
8
|
+
# Queries Codex's SQLite database for thread/project data.
|
|
9
|
+
#
|
|
10
|
+
# Codex stores sessions in `~/.codex/state_5.sqlite` (threads table)
|
|
11
|
+
# and full message history in JSONL rollout files.
|
|
12
|
+
class CodexDB
|
|
13
|
+
DEFAULT_DB = File.expand_path("~/.codex/state_5.sqlite")
|
|
14
|
+
|
|
15
|
+
def initialize(db_path = nil)
|
|
16
|
+
@db_path = db_path || DEFAULT_DB
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def available?
|
|
20
|
+
File.exist?(@db_path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# List all projects (directories with threads), ordered by most recent.
|
|
24
|
+
# Returns [{project_id:, directory:, session_count:}] or [].
|
|
25
|
+
def list_projects
|
|
26
|
+
return [] unless available?
|
|
27
|
+
|
|
28
|
+
db = open_db
|
|
29
|
+
rows = db.execute(<<~SQL)
|
|
30
|
+
SELECT cwd AS directory,
|
|
31
|
+
COUNT(*) AS session_count,
|
|
32
|
+
MAX(updated_at) AS last_active
|
|
33
|
+
FROM threads
|
|
34
|
+
WHERE archived = 0
|
|
35
|
+
GROUP BY cwd
|
|
36
|
+
ORDER BY last_active DESC
|
|
37
|
+
LIMIT 20
|
|
38
|
+
SQL
|
|
39
|
+
rows.map do |r|
|
|
40
|
+
{
|
|
41
|
+
project_id: r["directory"],
|
|
42
|
+
directory: r["directory"],
|
|
43
|
+
session_count: r["session_count"].to_i
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
rescue => e
|
|
47
|
+
[]
|
|
48
|
+
ensure
|
|
49
|
+
db&.close
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Find sessions in a given directory.
|
|
53
|
+
# Returns [{session_id:, title:, updated:}] or [].
|
|
54
|
+
def find_sessions(directory:, limit: 20)
|
|
55
|
+
return [] unless available?
|
|
56
|
+
|
|
57
|
+
db = open_db
|
|
58
|
+
rows = db.execute(<<~SQL, [directory, directory])
|
|
59
|
+
SELECT id, title, updated_at, preview
|
|
60
|
+
FROM threads
|
|
61
|
+
WHERE (cwd = ? OR ? LIKE cwd || '/%')
|
|
62
|
+
AND archived = 0
|
|
63
|
+
ORDER BY updated_at DESC
|
|
64
|
+
LIMIT ?
|
|
65
|
+
SQL
|
|
66
|
+
rows.map do |r|
|
|
67
|
+
{
|
|
68
|
+
session_id: r["id"],
|
|
69
|
+
title: r["title"].to_s.empty? ? (r["preview"] || "(untitled)") : r["title"],
|
|
70
|
+
updated: r["updated_at"]
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
rescue => e
|
|
74
|
+
[]
|
|
75
|
+
ensure
|
|
76
|
+
db&.close
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Find the most recent session across all projects.
|
|
80
|
+
# Returns {session_id:, directory:} or nil.
|
|
81
|
+
def find_recent_session
|
|
82
|
+
return nil unless available?
|
|
83
|
+
|
|
84
|
+
db = open_db
|
|
85
|
+
row = db.get_first_row(<<~SQL)
|
|
86
|
+
SELECT id, cwd FROM threads
|
|
87
|
+
WHERE archived = 0
|
|
88
|
+
ORDER BY updated_at DESC LIMIT 1
|
|
89
|
+
SQL
|
|
90
|
+
row ? { session_id: row["id"], directory: row["cwd"] } : nil
|
|
91
|
+
rescue => e
|
|
92
|
+
nil
|
|
93
|
+
ensure
|
|
94
|
+
db&.close
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Find the most recent TUI session in a workspace.
|
|
98
|
+
def find_recent_tui_session(workspace_path)
|
|
99
|
+
return nil unless available?
|
|
100
|
+
|
|
101
|
+
db = open_db
|
|
102
|
+
row = db.get_first_row(<<~SQL, workspace_path, workspace_path)
|
|
103
|
+
SELECT id, title, cwd FROM threads
|
|
104
|
+
WHERE (cwd = ? OR ? LIKE cwd || '/%')
|
|
105
|
+
AND archived = 0
|
|
106
|
+
ORDER BY updated_at DESC LIMIT 1
|
|
107
|
+
SQL
|
|
108
|
+
return nil unless row
|
|
109
|
+
{
|
|
110
|
+
session_id: row["id"],
|
|
111
|
+
title: row["title"],
|
|
112
|
+
directory: row["cwd"]
|
|
113
|
+
}
|
|
114
|
+
rescue => e
|
|
115
|
+
nil
|
|
116
|
+
ensure
|
|
117
|
+
db&.close
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Look up a session's workspace directory by ID.
|
|
121
|
+
def session_directory(session_id)
|
|
122
|
+
return nil unless available?
|
|
123
|
+
|
|
124
|
+
db = open_db
|
|
125
|
+
row = db.get_first_row("SELECT cwd FROM threads WHERE id = ?", [session_id])
|
|
126
|
+
row&.dig("cwd")
|
|
127
|
+
rescue => e
|
|
128
|
+
nil
|
|
129
|
+
ensure
|
|
130
|
+
db&.close
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Get session message history from the rollout JSONL file.
|
|
134
|
+
# Returns [{text:, role:, origin:}] or [].
|
|
135
|
+
def session_history(session_id, limit: 100)
|
|
136
|
+
return [] unless available?
|
|
137
|
+
|
|
138
|
+
db = open_db
|
|
139
|
+
row = db.get_first_row("SELECT rollout_path, title, preview FROM threads WHERE id = ?", [session_id])
|
|
140
|
+
return [] unless row
|
|
141
|
+
|
|
142
|
+
rollout_path = row["rollout_path"]
|
|
143
|
+
return [] unless rollout_path && File.exist?(rollout_path)
|
|
144
|
+
|
|
145
|
+
parse_rollout(rollout_path, limit)
|
|
146
|
+
rescue => e
|
|
147
|
+
[]
|
|
148
|
+
ensure
|
|
149
|
+
db&.close
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# List recent sessions across all projects.
|
|
153
|
+
# Returns [{session_id:, title:, updated:, msg_count:}] or [].
|
|
154
|
+
def recent_sessions
|
|
155
|
+
return [] unless available?
|
|
156
|
+
|
|
157
|
+
db = open_db
|
|
158
|
+
rows = db.execute(<<~SQL)
|
|
159
|
+
SELECT id, title, updated_at, preview
|
|
160
|
+
FROM threads
|
|
161
|
+
WHERE archived = 0
|
|
162
|
+
ORDER BY updated_at DESC
|
|
163
|
+
LIMIT 50
|
|
164
|
+
SQL
|
|
165
|
+
rows.map do |r|
|
|
166
|
+
{
|
|
167
|
+
session_id: r["id"],
|
|
168
|
+
title: r["title"].to_s.empty? ? (r["preview"] || "(untitled)") : r["title"],
|
|
169
|
+
updated: r["updated_at"],
|
|
170
|
+
msg_count: 0
|
|
171
|
+
}
|
|
172
|
+
end
|
|
173
|
+
rescue => e
|
|
174
|
+
[]
|
|
175
|
+
ensure
|
|
176
|
+
db&.close
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
private
|
|
180
|
+
|
|
181
|
+
def open_db
|
|
182
|
+
require "sqlite3"
|
|
183
|
+
db = SQLite3::Database.new(@db_path, readonly: true)
|
|
184
|
+
db.results_as_hash = true
|
|
185
|
+
db
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def parse_rollout(path, limit)
|
|
189
|
+
messages = []
|
|
190
|
+
File.readlines(path).each do |line|
|
|
191
|
+
begin
|
|
192
|
+
event = JSON.parse(line)
|
|
193
|
+
rescue JSON::ParserError
|
|
194
|
+
next
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
case event["type"]
|
|
198
|
+
when "user_message"
|
|
199
|
+
messages << { text: event["content"].to_s, role: "You", origin: "real_user" }
|
|
200
|
+
when "agent_message"
|
|
201
|
+
messages << { text: event["content"].to_s, role: "Agent", origin: nil }
|
|
202
|
+
end
|
|
203
|
+
break if messages.length >= limit * 2
|
|
204
|
+
end
|
|
205
|
+
messages.last(limit)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "codex/app_server_client"
|
|
4
|
+
require_relative "codex/adapter"
|
|
5
|
+
require_relative "codex/codex_db"
|
|
6
|
+
|
|
7
|
+
module Ask
|
|
8
|
+
module CodingProviders
|
|
9
|
+
module Codex
|
|
10
|
+
class Error < Ask::CodingProviders::Error; end
|
|
11
|
+
class TimeoutError < Ask::CodingProviders::TimeoutError; end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Ask
|
|
6
|
+
module CodingProviders
|
|
7
|
+
module ZCode
|
|
8
|
+
# Wraps the ZCode SQLite database, centralizing all session/project queries.
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# db = ZCodeDB.new
|
|
12
|
+
# projects = db.list_projects
|
|
13
|
+
# sessions = db.find_sessions(directory: "/path")
|
|
14
|
+
#
|
|
15
|
+
# All methods return nil or empty arrays on error (never raise).
|
|
16
|
+
# This makes it safe to use from any context without wrapping every call.
|
|
17
|
+
class ZCodeDB
|
|
18
|
+
def initialize(db_path = nil)
|
|
19
|
+
@db_path = db_path || File.expand_path("~/.zcode/cli/db/db.sqlite")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def available?
|
|
23
|
+
File.exist?(@db_path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# List all projects with session counts, ordered by most recently updated.
|
|
27
|
+
# Returns [{project_id:, directory:, session_count:}] or [].
|
|
28
|
+
def list_projects
|
|
29
|
+
return [] unless available?
|
|
30
|
+
|
|
31
|
+
db = open_db
|
|
32
|
+
rows = db.execute(<<~SQL)
|
|
33
|
+
SELECT project_id, directory, count(*) as session_count
|
|
34
|
+
FROM session
|
|
35
|
+
WHERE task_type = 'interactive' AND time_archived IS NULL
|
|
36
|
+
GROUP BY project_id
|
|
37
|
+
ORDER BY MAX(time_updated) DESC
|
|
38
|
+
LIMIT 10
|
|
39
|
+
SQL
|
|
40
|
+
rows.map { |r| { project_id: r["project_id"], directory: r["directory"], session_count: r["session_count"].to_i } }
|
|
41
|
+
rescue => e
|
|
42
|
+
nil
|
|
43
|
+
ensure
|
|
44
|
+
db&.close
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Find sessions in a given directory (exact or prefix match).
|
|
48
|
+
# Returns [{session_id:, title:, updated:}] or [].
|
|
49
|
+
def find_sessions(directory:, limit: 20)
|
|
50
|
+
return [] unless available?
|
|
51
|
+
|
|
52
|
+
db = open_db
|
|
53
|
+
rows = db.execute(<<~SQL, [directory, directory, limit])
|
|
54
|
+
SELECT id, title, time_updated
|
|
55
|
+
FROM session
|
|
56
|
+
WHERE (directory = ? OR ? LIKE directory || '/%')
|
|
57
|
+
AND time_archived IS NULL AND task_type = 'interactive'
|
|
58
|
+
ORDER BY time_updated DESC
|
|
59
|
+
LIMIT ?
|
|
60
|
+
SQL
|
|
61
|
+
rows.map { |r| { session_id: r["id"], title: r["title"], updated: r["time_updated"] } }
|
|
62
|
+
rescue => e
|
|
63
|
+
[]
|
|
64
|
+
ensure
|
|
65
|
+
db&.close
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Find the single most recent session across all projects.
|
|
69
|
+
# Returns {session_id:, directory:} or nil.
|
|
70
|
+
def find_recent_session
|
|
71
|
+
return nil unless available?
|
|
72
|
+
|
|
73
|
+
db = open_db
|
|
74
|
+
row = db.get_first_row(<<~SQL)
|
|
75
|
+
SELECT id, directory FROM session
|
|
76
|
+
WHERE time_archived IS NULL AND task_type = 'interactive'
|
|
77
|
+
ORDER BY time_updated DESC LIMIT 1
|
|
78
|
+
SQL
|
|
79
|
+
row ? { session_id: row["id"], directory: row["directory"] } : nil
|
|
80
|
+
rescue => e
|
|
81
|
+
nil
|
|
82
|
+
ensure
|
|
83
|
+
db&.close
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Find the most recent TUI session in a workspace path.
|
|
87
|
+
# Returns {session_id:, title:, directory:} or nil.
|
|
88
|
+
def find_recent_tui_session(workspace_path)
|
|
89
|
+
return nil unless available?
|
|
90
|
+
|
|
91
|
+
db = open_db
|
|
92
|
+
row = db.get_first_row(<<~SQL, [workspace_path, workspace_path])
|
|
93
|
+
SELECT id, title, directory
|
|
94
|
+
FROM session
|
|
95
|
+
WHERE (directory = ? OR ? LIKE directory || '/%')
|
|
96
|
+
AND time_archived IS NULL AND task_type = 'interactive'
|
|
97
|
+
ORDER BY time_updated DESC
|
|
98
|
+
LIMIT 1
|
|
99
|
+
SQL
|
|
100
|
+
row ? { session_id: row["id"], title: row["title"], directory: row["directory"] } : nil
|
|
101
|
+
rescue => e
|
|
102
|
+
nil
|
|
103
|
+
ensure
|
|
104
|
+
db&.close
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Look up a session's workspace directory by its ID.
|
|
108
|
+
# Returns the directory string, or nil.
|
|
109
|
+
def session_directory(session_id)
|
|
110
|
+
return nil unless available?
|
|
111
|
+
|
|
112
|
+
db = open_db
|
|
113
|
+
row = db.get_first_row("SELECT directory FROM session WHERE id = ?", [session_id])
|
|
114
|
+
row&.dig("directory")
|
|
115
|
+
rescue => e
|
|
116
|
+
nil
|
|
117
|
+
ensure
|
|
118
|
+
db&.close
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Load the last N text parts from a session, newest first.
|
|
122
|
+
# Returns [{text:, role:, origin:}] or [].
|
|
123
|
+
def session_history(session_id, limit: 100)
|
|
124
|
+
return [] unless available?
|
|
125
|
+
|
|
126
|
+
db = open_db
|
|
127
|
+
rows = db.execute(<<~SQL, [session_id, limit])
|
|
128
|
+
SELECT p.data, m.data as msg_data FROM part p
|
|
129
|
+
JOIN message m ON p.message_id = m.id
|
|
130
|
+
WHERE p.session_id = ? AND p.data LIKE '%"type":"text"%'
|
|
131
|
+
ORDER BY p.time_created DESC
|
|
132
|
+
LIMIT ?
|
|
133
|
+
SQL
|
|
134
|
+
|
|
135
|
+
rows.filter_map do |r|
|
|
136
|
+
part = JSON.parse(r["data"]) rescue next
|
|
137
|
+
content = part["text"] || ""
|
|
138
|
+
next if content.empty?
|
|
139
|
+
|
|
140
|
+
msg_data = JSON.parse(r["msg_data"]) rescue {}
|
|
141
|
+
role = msg_data["role"] == "user" ? "You" : "Agent"
|
|
142
|
+
origin = msg_data.dig("semantics", "origin") rescue nil
|
|
143
|
+
|
|
144
|
+
# Skip system-generated messages masquerading as user
|
|
145
|
+
next if role == "You" && origin != "real_user" && origin != nil
|
|
146
|
+
|
|
147
|
+
{ text: content, role: role, origin: origin }
|
|
148
|
+
end
|
|
149
|
+
rescue => e
|
|
150
|
+
[]
|
|
151
|
+
ensure
|
|
152
|
+
db&.close
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# List recent sessions across all projects.
|
|
156
|
+
# Returns [{session_id:, title:, updated:, msg_count:}] or [].
|
|
157
|
+
def recent_sessions
|
|
158
|
+
return [] unless available?
|
|
159
|
+
|
|
160
|
+
db = open_db
|
|
161
|
+
rows = db.execute(<<~SQL)
|
|
162
|
+
SELECT s.id AS session_id, s.title AS title,
|
|
163
|
+
s.time_updated AS updated,
|
|
164
|
+
(SELECT count(*) FROM message m WHERE m.session_id = s.id) AS msg_count
|
|
165
|
+
FROM session s
|
|
166
|
+
WHERE s.task_type = 'interactive' AND s.time_archived IS NULL
|
|
167
|
+
ORDER BY s.time_updated DESC
|
|
168
|
+
LIMIT 20
|
|
169
|
+
SQL
|
|
170
|
+
rows.map do |r|
|
|
171
|
+
{
|
|
172
|
+
session_id: r["session_id"],
|
|
173
|
+
title: r["title"],
|
|
174
|
+
updated: r["updated"],
|
|
175
|
+
msg_count: r["msg_count"].to_i
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
rescue => e
|
|
179
|
+
[]
|
|
180
|
+
ensure
|
|
181
|
+
db&.close
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
def open_db
|
|
187
|
+
require "sqlite3"
|
|
188
|
+
db = SQLite3::Database.new(@db_path, readonly: true)
|
|
189
|
+
db.results_as_hash = true
|
|
190
|
+
db
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "zcode/zcode_db"
|
|
4
|
+
|
|
5
|
+
module Ask
|
|
6
|
+
module CodingProviders
|
|
7
|
+
# ZCode database reader — queries ZCode's SQLite session store.
|
|
8
|
+
# See {ZCodeDB} for session/project lookup methods.
|
|
9
|
+
module ZCode
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "coding_providers/version"
|
|
4
|
+
require_relative "coding_providers/adapter"
|
|
5
|
+
|
|
6
|
+
module Ask
|
|
7
|
+
module CodingProviders
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
class ConfigurationError < Error; end
|
|
10
|
+
class ConnectionError < Error; end
|
|
11
|
+
class TimeoutError < Error; end
|
|
12
|
+
|
|
13
|
+
# Registry of coding provider adapters by name.
|
|
14
|
+
# Adapters register themselves via {register_adapter}.
|
|
15
|
+
# The CLI resolves the active adapter via {build_adapter}.
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# adapter = Ask::CodingProviders.build_adapter("acp", workspace_path: Dir.pwd)
|
|
19
|
+
# adapter = Ask::CodingProviders.build_adapter("ask_agent", model: "deepseek-v4-flash")
|
|
20
|
+
@adapter_registry = {}
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
# Register a coding adapter class under a name.
|
|
24
|
+
# Called automatically by adapter files when loaded.
|
|
25
|
+
def register_adapter(name, klass)
|
|
26
|
+
@adapter_registry[name.to_s] = klass
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Resolve an adapter class by name.
|
|
30
|
+
# @raise [ConfigurationError] if unknown
|
|
31
|
+
def resolve_adapter(name)
|
|
32
|
+
@adapter_registry[name.to_s] || raise(
|
|
33
|
+
ConfigurationError,
|
|
34
|
+
"Unknown coding provider: #{name.inspect}. " \
|
|
35
|
+
"Available: #{@adapter_registry.keys.join(', ')}. " \
|
|
36
|
+
"Set CODING_PROVIDER in your environment."
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Build an adapter instance by name, passing config options.
|
|
41
|
+
# Each adapter's .from_config class method decides how to use the config.
|
|
42
|
+
def build_adapter(name, **config)
|
|
43
|
+
resolve_adapter(name).from_config(**config)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
require_relative "coding_providers/zcode"
|
|
50
|
+
require_relative "coding_providers/ask_agent"
|
|
51
|
+
require_relative "coding_providers/codex"
|
|
52
|
+
require_relative "coding_providers/acp"
|
|
53
|
+
require_relative "coding_providers/claude"
|
metadata
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ask-coding-providers
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kaka Ruto
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '5.25'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '5.25'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mocha
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.1'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: simplecov
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.22'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.22'
|
|
68
|
+
description: Coding agent adapter interface and implementations (ACP, Codex, Claude,
|
|
69
|
+
AskAgent) for the askoda ecosystem.
|
|
70
|
+
email:
|
|
71
|
+
- kaka@myrrlabs.com
|
|
72
|
+
executables: []
|
|
73
|
+
extensions: []
|
|
74
|
+
extra_rdoc_files: []
|
|
75
|
+
files:
|
|
76
|
+
- lib/ask-coding-providers.rb
|
|
77
|
+
- lib/ask/coding_providers.rb
|
|
78
|
+
- lib/ask/coding_providers/acp.rb
|
|
79
|
+
- lib/ask/coding_providers/acp/adapter.rb
|
|
80
|
+
- lib/ask/coding_providers/adapter.rb
|
|
81
|
+
- lib/ask/coding_providers/ask_agent.rb
|
|
82
|
+
- lib/ask/coding_providers/ask_agent/adapter.rb
|
|
83
|
+
- lib/ask/coding_providers/claude.rb
|
|
84
|
+
- lib/ask/coding_providers/claude/adapter.rb
|
|
85
|
+
- lib/ask/coding_providers/codex.rb
|
|
86
|
+
- lib/ask/coding_providers/codex/adapter.rb
|
|
87
|
+
- lib/ask/coding_providers/codex/app_server_client.rb
|
|
88
|
+
- lib/ask/coding_providers/codex/codex_db.rb
|
|
89
|
+
- lib/ask/coding_providers/version.rb
|
|
90
|
+
- lib/ask/coding_providers/zcode.rb
|
|
91
|
+
- lib/ask/coding_providers/zcode/zcode_db.rb
|
|
92
|
+
homepage: https://github.com/ask-rb/ask-coding-providers
|
|
93
|
+
licenses:
|
|
94
|
+
- MIT
|
|
95
|
+
metadata:
|
|
96
|
+
homepage_uri: https://github.com/ask-rb/ask-coding-providers
|
|
97
|
+
source_code_uri: https://github.com/ask-rb/ask-coding-providers
|
|
98
|
+
rdoc_options: []
|
|
99
|
+
require_paths:
|
|
100
|
+
- lib
|
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '3.2'
|
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
requirements: []
|
|
112
|
+
rubygems_version: 4.0.3
|
|
113
|
+
specification_version: 4
|
|
114
|
+
summary: Coding agent adapters for the ask-rb ecosystem
|
|
115
|
+
test_files: []
|