opencode-pilot 0.1.0 → 0.2.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.
@@ -8,7 +8,7 @@ set -euo pipefail
8
8
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
9
 
10
10
  echo "========================================"
11
- echo " opencode-ntfy test suite"
11
+ echo " opencode-pilot test suite"
12
12
  echo "========================================"
13
13
  echo ""
14
14
 
@@ -62,7 +62,7 @@ test_actions_uses_opencode_run() {
62
62
  }
63
63
 
64
64
  test_actions_prompt_template() {
65
- grep -q "prompt_template\|promptTemplate" "$SERVICE_DIR/actions.js" || {
65
+ grep -q "prompt_template\|promptTemplate\|buildPromptFromTemplate" "$SERVICE_DIR/actions.js" || {
66
66
  echo "Prompt template support not found"
67
67
  return 1
68
68
  }
@@ -104,7 +104,7 @@ test_actions_build_local_command() {
104
104
 
105
105
  const config = {
106
106
  repo_path: '~/code/myrepo',
107
- session: { name_template: 'issue-{number}' }
107
+ session: { name: 'issue-{number}' }
108
108
  };
109
109
 
110
110
  const cmd = buildCommand(item, config);
@@ -130,7 +130,7 @@ test_actions_build_local_command() {
130
130
  fi
131
131
  }
132
132
 
133
- test_actions_prompt_template_expansion() {
133
+ test_actions_session_name_template() {
134
134
  if ! command -v node &>/dev/null; then
135
135
  echo "SKIP: node not available"
136
136
  return 0
@@ -138,33 +138,19 @@ test_actions_prompt_template_expansion() {
138
138
 
139
139
  local result
140
140
  result=$(node --experimental-vm-modules -e "
141
- import { buildCommand } from './service/actions.js';
141
+ import { buildSessionName } from './service/actions.js';
142
142
 
143
143
  const item = {
144
- title: 'Fix bug',
145
- body: 'Details here',
146
- number: 456
147
- };
148
-
149
- // Config with custom prompt template (e.g., for devcontainer)
150
- const config = {
151
- repo_path: '~/code/myrepo',
152
- session: {
153
- name_template: 'issue-{number}',
154
- prompt_template: '/devcontainer issue-{number}\n\n{title}\n\n{body}'
155
- }
144
+ number: 42,
145
+ repo_key: 'myorg/backend',
146
+ repo_short: 'backend'
156
147
  };
157
148
 
158
- const cmd = buildCommand(item, config);
149
+ const template = 'issue-{repo_short}-{number}';
150
+ const name = buildSessionName(template, item);
159
151
 
160
- // Should include the expanded template
161
- if (!cmd.includes('/devcontainer issue-456')) {
162
- console.log('FAIL: Command should include expanded prompt template');
163
- console.log('Got: ' + cmd);
164
- process.exit(1);
165
- }
166
- if (!cmd.includes('Fix bug')) {
167
- console.log('FAIL: Command should include title from template');
152
+ if (name !== 'issue-backend-42') {
153
+ console.log('FAIL: Expected issue-backend-42, got ' + name);
168
154
  process.exit(1);
169
155
  }
170
156
  console.log('PASS');
@@ -179,7 +165,7 @@ test_actions_prompt_template_expansion() {
179
165
  fi
180
166
  }
181
167
 
182
- test_actions_session_name_template() {
168
+ test_actions_expand_template() {
183
169
  if ! command -v node &>/dev/null; then
184
170
  echo "SKIP: node not available"
185
171
  return 0
@@ -187,19 +173,18 @@ test_actions_session_name_template() {
187
173
 
188
174
  local result
189
175
  result=$(node --experimental-vm-modules -e "
190
- import { buildSessionName } from './service/actions.js';
176
+ import { expandTemplate } from './service/actions.js';
191
177
 
192
178
  const item = {
193
- number: 42,
194
- repo_key: 'myorg/backend',
195
- repo_short: 'backend'
179
+ title: 'Fix bug',
180
+ number: 456
196
181
  };
197
182
 
198
- const template = 'issue-{repo_short}-{number}';
199
- const name = buildSessionName(template, item);
183
+ const template = 'Issue #{number}: {title}';
184
+ const expanded = expandTemplate(template, item);
200
185
 
201
- if (name !== 'issue-backend-42') {
202
- console.log('FAIL: Expected issue-backend-42, got ' + name);
186
+ if (expanded !== 'Issue #456: Fix bug') {
187
+ console.log('FAIL: Expected \"Issue #456: Fix bug\", got \"' + expanded + '\"');
203
188
  process.exit(1);
204
189
  }
205
190
  console.log('PASS');
@@ -254,8 +239,8 @@ echo "Functional Tests:"
254
239
 
255
240
  for test_func in \
256
241
  test_actions_build_local_command \
257
- test_actions_prompt_template_expansion \
258
- test_actions_session_name_template
242
+ test_actions_session_name_template \
243
+ test_actions_expand_template
259
244
  do
260
245
  run_test "${test_func#test_}" "$test_func"
261
246
  done
@@ -51,9 +51,9 @@ test_cli_help_shows_usage() {
51
51
  }
52
52
  }
53
53
 
54
- test_cli_help_shows_setup_command() {
55
- "$CLI_PATH" help 2>&1 | grep -q "setup" || {
56
- echo "help command should show setup command"
54
+ test_cli_help_shows_start_command() {
55
+ "$CLI_PATH" help 2>&1 | grep -q "start" || {
56
+ echo "help command should show start command"
57
57
  return 1
58
58
  }
59
59
  }
@@ -65,6 +65,13 @@ test_cli_help_shows_status_command() {
65
65
  }
66
66
  }
67
67
 
68
+ test_cli_help_shows_config_command() {
69
+ "$CLI_PATH" help 2>&1 | grep -q "config" || {
70
+ echo "help command should show config command"
71
+ return 1
72
+ }
73
+ }
74
+
68
75
  test_cli_default_shows_help() {
69
76
  "$CLI_PATH" 2>&1 | grep -q "Usage:" || {
70
77
  echo "default should show usage"
@@ -87,34 +94,23 @@ test_cli_unknown_command_shows_error() {
87
94
  # Status Command Tests
88
95
  # =============================================================================
89
96
 
90
- test_cli_status_shows_plugin_info() {
91
- local output
92
- output=$("$CLI_PATH" status 2>&1) || true
93
-
94
- echo "$output" | grep -qi "plugin" || {
95
- echo "status should show plugin info"
96
- echo "Output: $output"
97
- return 1
98
- }
99
- }
100
-
101
- test_cli_status_shows_notification_config() {
97
+ test_cli_status_shows_service_info() {
102
98
  local output
103
99
  output=$("$CLI_PATH" status 2>&1) || true
104
100
 
105
- echo "$output" | grep -qi "notification\|topic" || {
106
- echo "status should show notification config"
101
+ echo "$output" | grep -qi "service" || {
102
+ echo "status should show service info"
107
103
  echo "Output: $output"
108
104
  return 1
109
105
  }
110
106
  }
111
107
 
112
- test_cli_status_shows_polling_config() {
108
+ test_cli_status_shows_config_info() {
113
109
  local output
114
110
  output=$("$CLI_PATH" status 2>&1) || true
115
111
 
116
- echo "$output" | grep -qi "polling\|repos.yaml" || {
117
- echo "status should show polling config"
112
+ echo "$output" | grep -qi "config" || {
113
+ echo "status should show config info"
118
114
  echo "Output: $output"
119
115
  return 1
120
116
  }
@@ -139,8 +135,9 @@ echo "Help Command Tests:"
139
135
 
140
136
  for test_func in \
141
137
  test_cli_help_shows_usage \
142
- test_cli_help_shows_setup_command \
138
+ test_cli_help_shows_start_command \
143
139
  test_cli_help_shows_status_command \
140
+ test_cli_help_shows_config_command \
144
141
  test_cli_default_shows_help \
145
142
  test_cli_unknown_command_shows_error
146
143
  do
@@ -151,9 +148,8 @@ echo ""
151
148
  echo "Status Command Tests:"
152
149
 
153
150
  for test_func in \
154
- test_cli_status_shows_plugin_info \
155
- test_cli_status_shows_notification_config \
156
- test_cli_status_shows_polling_config
151
+ test_cli_status_shows_service_info \
152
+ test_cli_status_shows_config_info
157
153
  do
158
154
  run_test "${test_func#test_}" "$test_func"
159
155
  done
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
- # Tests for service/io.opencode.ntfy.plist - LaunchAgent plist for brew services
4
- # Issue #13: Separate callback server as brew service
3
+ # Tests for service/io.opencode.pilot.plist - LaunchAgent plist for brew services
5
4
  #
6
5
 
7
6
  set -euo pipefail
@@ -19,7 +18,7 @@ echo ""
19
18
  # =============================================================================
20
19
 
21
20
  test_plist_file_exists() {
22
- assert_file_exists "$SERVICE_DIR/io.opencode.ntfy.plist"
21
+ assert_file_exists "$SERVICE_DIR/io.opencode.pilot.plist"
23
22
  }
24
23
 
25
24
  test_plist_is_valid_xml() {
@@ -27,7 +26,7 @@ test_plist_is_valid_xml() {
27
26
  echo "SKIP: plutil not available (macOS only)"
28
27
  return 0
29
28
  fi
30
- plutil -lint "$SERVICE_DIR/io.opencode.ntfy.plist" 2>&1 || {
29
+ plutil -lint "$SERVICE_DIR/io.opencode.pilot.plist" 2>&1 || {
31
30
  echo "plist is not valid XML"
32
31
  return 1
33
32
  }
@@ -38,56 +37,56 @@ test_plist_is_valid_xml() {
38
37
  # =============================================================================
39
38
 
40
39
  test_plist_has_label() {
41
- grep -q "<string>io.opencode.ntfy</string>" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
40
+ grep -q "<string>io.opencode.pilot</string>" "$SERVICE_DIR/io.opencode.pilot.plist" || {
42
41
  echo "Label not found in plist"
43
42
  return 1
44
43
  }
45
44
  }
46
45
 
47
46
  test_plist_has_program_arguments() {
48
- grep -q "<key>ProgramArguments</key>" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
47
+ grep -q "<key>ProgramArguments</key>" "$SERVICE_DIR/io.opencode.pilot.plist" || {
49
48
  echo "ProgramArguments not found in plist"
50
49
  return 1
51
50
  }
52
51
  }
53
52
 
54
53
  test_plist_runs_node() {
55
- grep -q "node" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
54
+ grep -q "node" "$SERVICE_DIR/io.opencode.pilot.plist" || {
56
55
  echo "node command not found in plist"
57
56
  return 1
58
57
  }
59
58
  }
60
59
 
61
60
  test_plist_runs_server_js() {
62
- grep -q "server.js" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
61
+ grep -q "server.js" "$SERVICE_DIR/io.opencode.pilot.plist" || {
63
62
  echo "server.js not found in plist"
64
63
  return 1
65
64
  }
66
65
  }
67
66
 
68
67
  test_plist_has_keep_alive() {
69
- grep -q "<key>KeepAlive</key>" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
68
+ grep -q "<key>KeepAlive</key>" "$SERVICE_DIR/io.opencode.pilot.plist" || {
70
69
  echo "KeepAlive not found in plist"
71
70
  return 1
72
71
  }
73
72
  }
74
73
 
75
74
  test_plist_has_run_at_load() {
76
- grep -q "<key>RunAtLoad</key>" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
75
+ grep -q "<key>RunAtLoad</key>" "$SERVICE_DIR/io.opencode.pilot.plist" || {
77
76
  echo "RunAtLoad not found in plist"
78
77
  return 1
79
78
  }
80
79
  }
81
80
 
82
81
  test_plist_has_stdout_log() {
83
- grep -q "stdout\|StandardOutPath" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
82
+ grep -q "stdout\|StandardOutPath" "$SERVICE_DIR/io.opencode.pilot.plist" || {
84
83
  echo "Stdout logging not found in plist"
85
84
  return 1
86
85
  }
87
86
  }
88
87
 
89
88
  test_plist_has_stderr_log() {
90
- grep -q "stderr\|StandardErrorPath" "$SERVICE_DIR/io.opencode.ntfy.plist" || {
89
+ grep -q "stderr\|StandardErrorPath" "$SERVICE_DIR/io.opencode.pilot.plist" || {
91
90
  echo "Stderr logging not found in plist"
92
91
  return 1
93
92
  }
@@ -43,30 +43,23 @@ test_poller_exports_create_poller() {
43
43
  }
44
44
  }
45
45
 
46
- test_poller_exports_poll_source() {
47
- grep -q "export.*function pollSource\|export.*pollSource" "$SERVICE_DIR/poller.js" || {
48
- echo "pollSource export not found in poller.js"
46
+ test_poller_exports_poll_generic_source() {
47
+ grep -q "export.*function pollGenericSource\|export.*pollGenericSource" "$SERVICE_DIR/poller.js" || {
48
+ echo "pollGenericSource export not found in poller.js"
49
49
  return 1
50
50
  }
51
51
  }
52
52
 
53
- # =============================================================================
54
- # Implementation Tests
55
- # =============================================================================
56
-
57
- test_poller_supports_github_issues() {
58
- grep -q "github_issue\|github-issue" "$SERVICE_DIR/poller.js" || {
59
- echo "GitHub issue source type not found in poller.js"
53
+ test_poller_exports_apply_mappings() {
54
+ grep -q "export.*function applyMappings\|export.*applyMappings" "$SERVICE_DIR/poller.js" || {
55
+ echo "applyMappings export not found in poller.js"
60
56
  return 1
61
57
  }
62
58
  }
63
59
 
64
- test_poller_supports_linear_issues() {
65
- grep -q "linear_issue\|linear-issue" "$SERVICE_DIR/poller.js" || {
66
- echo "Linear issue source type not found in poller.js"
67
- return 1
68
- }
69
- }
60
+ # =============================================================================
61
+ # Implementation Tests
62
+ # =============================================================================
70
63
 
71
64
  test_poller_uses_mcp_client() {
72
65
  grep -q "@modelcontextprotocol/sdk" "$SERVICE_DIR/poller.js" || {
@@ -82,6 +75,13 @@ test_poller_tracks_processed_items() {
82
75
  }
83
76
  }
84
77
 
78
+ test_poller_supports_generic_tools() {
79
+ grep -q "tool" "$SERVICE_DIR/poller.js" || {
80
+ echo "Tool-based polling not found in poller.js"
81
+ return 1
82
+ }
83
+ }
84
+
85
85
  # =============================================================================
86
86
  # Run Tests
87
87
  # =============================================================================
@@ -100,7 +100,8 @@ echo "Export Tests:"
100
100
 
101
101
  for test_func in \
102
102
  test_poller_exports_create_poller \
103
- test_poller_exports_poll_source
103
+ test_poller_exports_poll_generic_source \
104
+ test_poller_exports_apply_mappings
104
105
  do
105
106
  run_test "${test_func#test_}" "$test_func"
106
107
  done
@@ -109,10 +110,9 @@ echo ""
109
110
  echo "Implementation Tests:"
110
111
 
111
112
  for test_func in \
112
- test_poller_supports_github_issues \
113
- test_poller_supports_linear_issues \
114
113
  test_poller_uses_mcp_client \
115
- test_poller_tracks_processed_items
114
+ test_poller_tracks_processed_items \
115
+ test_poller_supports_generic_tools
116
116
  do
117
117
  run_test "${test_func#test_}" "$test_func"
118
118
  done
@@ -68,23 +68,16 @@ test_repo_config_supports_yaml() {
68
68
  }
69
69
  }
70
70
 
71
- test_repo_config_supports_prefix_matching() {
72
- grep -q "prefix\|endsWith.*/" "$SERVICE_DIR/repo-config.js" || {
73
- echo "Prefix matching not found"
71
+ test_repo_config_supports_source_config() {
72
+ grep -q "sources" "$SERVICE_DIR/repo-config.js" || {
73
+ echo "Sources support not found"
74
74
  return 1
75
75
  }
76
76
  }
77
77
 
78
- test_repo_config_merges_configs() {
79
- grep -q "merge\|deep.*merge" "$SERVICE_DIR/repo-config.js" || {
80
- echo "Config merging not found"
81
- return 1
82
- }
83
- }
84
-
85
- test_repo_config_expands_placeholders() {
86
- grep -q "{repo}\|placeholder" "$SERVICE_DIR/repo-config.js" || {
87
- echo "Placeholder expansion not found"
78
+ test_repo_config_supports_tool_mappings() {
79
+ grep -q "mappings\|tools" "$SERVICE_DIR/repo-config.js" || {
80
+ echo "Tool mappings support not found"
88
81
  return 1
89
82
  }
90
83
  }
@@ -93,7 +86,7 @@ test_repo_config_expands_placeholders() {
93
86
  # Functional Tests
94
87
  # =============================================================================
95
88
 
96
- test_repo_config_defaults() {
89
+ test_repo_config_returns_empty_for_unknown_repo() {
97
90
  if ! command -v node &>/dev/null; then
98
91
  echo "SKIP: node not available"
99
92
  return 0
@@ -103,15 +96,11 @@ test_repo_config_defaults() {
103
96
  result=$(node --experimental-vm-modules -e "
104
97
  import { getRepoConfig } from './service/repo-config.js';
105
98
 
106
- // Get config for non-existent repo should return defaults
99
+ // Get config for non-existent repo should return empty object
107
100
  const config = getRepoConfig('nonexistent/repo');
108
101
 
109
- if (!config.readiness) {
110
- console.log('FAIL: Missing readiness in defaults');
111
- process.exit(1);
112
- }
113
- if (!config.readiness.labels) {
114
- console.log('FAIL: Missing readiness.labels in defaults');
102
+ if (typeof config !== 'object') {
103
+ console.log('FAIL: Expected object for unknown repo');
115
104
  process.exit(1);
116
105
  }
117
106
  console.log('PASS');
@@ -126,7 +115,7 @@ test_repo_config_defaults() {
126
115
  fi
127
116
  }
128
117
 
129
- test_repo_config_prefix_matching() {
118
+ test_repo_config_gets_sources() {
130
119
  if ! command -v node &>/dev/null; then
131
120
  echo "SKIP: node not available"
132
121
  return 0
@@ -134,206 +123,15 @@ test_repo_config_prefix_matching() {
134
123
 
135
124
  local result
136
125
  result=$(node --experimental-vm-modules -e "
137
- import { loadRepoConfig, getRepoConfig } from './service/repo-config.js';
138
-
139
- // Load test config
140
- const testConfig = {
141
- repos: {
142
- 'myorg/': {
143
- repo_path: '~/code/{repo}',
144
- readiness: { labels: { any_of: ['ready'] } }
145
- },
146
- 'myorg/backend': {
147
- readiness: { labels: { any_of: ['backend-ready'] } }
148
- }
149
- }
150
- };
151
-
152
- loadRepoConfig(testConfig);
126
+ import { getAllSources } from './service/repo-config.js';
153
127
 
154
- // Get config for myorg/backend - should merge prefix + exact
155
- const config = getRepoConfig('myorg/backend');
156
-
157
- // Should have readiness from exact match
158
- if (!config.readiness.labels.any_of.includes('backend-ready')) {
159
- console.log('FAIL: Expected any_of to include backend-ready from exact match');
160
- process.exit(1);
161
- }
162
-
163
- // Get config for myorg/frontend - should get prefix config
164
- const frontendConfig = getRepoConfig('myorg/frontend');
165
- if (!frontendConfig.readiness.labels.any_of.includes('ready')) {
166
- console.log('FAIL: Expected any_of to include ready from prefix');
167
- process.exit(1);
168
- }
169
-
170
- // repo_path should have {repo} expanded
171
- if (frontendConfig.repo_path !== '~/code/frontend') {
172
- console.log('FAIL: Expected expanded repo_path, got ' + frontendConfig.repo_path);
173
- process.exit(1);
174
- }
175
-
176
- console.log('PASS');
177
- " 2>&1) || {
178
- echo "Functional test failed: $result"
179
- return 1
180
- }
181
-
182
- if ! echo "$result" | grep -q "PASS"; then
183
- echo "$result"
184
- return 1
185
- fi
186
- }
187
-
188
- # =============================================================================
189
- # Default Sources Tests
190
- # =============================================================================
191
-
192
- test_repo_config_default_sources() {
193
- if ! command -v node &>/dev/null; then
194
- echo "SKIP: node not available"
195
- return 0
196
- fi
197
-
198
- local result
199
- result=$(node --experimental-vm-modules -e "
200
- import { loadRepoConfig, getRepoConfig, getAllSources } from './service/repo-config.js';
201
-
202
- // Load config with repo that has no sources specified
203
- const testConfig = {
204
- repos: {
205
- 'myorg/': {
206
- repo_path: '~/code/{repo}'
207
- },
208
- 'myorg/backend': {} // No sources specified
209
- }
210
- };
211
-
212
- loadRepoConfig(testConfig);
213
-
214
- // Get config - should have default github_issue source
215
- const config = getRepoConfig('myorg/backend');
216
-
217
- if (!config.sources || config.sources.length === 0) {
218
- console.log('FAIL: Expected default sources, got empty array');
219
- process.exit(1);
220
- }
221
-
222
- const defaultSource = config.sources[0];
223
- if (defaultSource.type !== 'github_issue') {
224
- console.log('FAIL: Expected default source type github_issue, got ' + defaultSource.type);
225
- process.exit(1);
226
- }
227
-
228
- if (!defaultSource.fetch || defaultSource.fetch.assignee !== '@me') {
229
- console.log('FAIL: Expected default fetch.assignee=@me, got ' + JSON.stringify(defaultSource.fetch));
230
- process.exit(1);
231
- }
232
-
233
- if (!defaultSource.fetch || defaultSource.fetch.state !== 'open') {
234
- console.log('FAIL: Expected default fetch.state=open, got ' + JSON.stringify(defaultSource.fetch));
235
- process.exit(1);
236
- }
237
-
238
- console.log('PASS');
239
- " 2>&1) || {
240
- echo "Functional test failed: $result"
241
- return 1
242
- }
243
-
244
- if ! echo "$result" | grep -q "PASS"; then
245
- echo "$result"
246
- return 1
247
- fi
248
- }
249
-
250
- test_repo_config_explicit_sources_override_defaults() {
251
- if ! command -v node &>/dev/null; then
252
- echo "SKIP: node not available"
253
- return 0
254
- fi
255
-
256
- local result
257
- result=$(node --experimental-vm-modules -e "
258
- import { loadRepoConfig, getRepoConfig } from './service/repo-config.js';
259
-
260
- // Load config with explicit sources
261
- const testConfig = {
262
- repos: {
263
- 'myorg/backend': {
264
- sources: [
265
- { type: 'github_pr', fetch: { state: 'open' } }
266
- ]
267
- }
268
- }
269
- };
270
-
271
- loadRepoConfig(testConfig);
272
-
273
- // Get config - should have explicit sources, not defaults
274
- const config = getRepoConfig('myorg/backend');
275
-
276
- if (config.sources.length !== 1) {
277
- console.log('FAIL: Expected 1 source, got ' + config.sources.length);
278
- process.exit(1);
279
- }
280
-
281
- if (config.sources[0].type !== 'github_pr') {
282
- console.log('FAIL: Expected explicit github_pr source, got ' + config.sources[0].type);
283
- process.exit(1);
284
- }
285
-
286
- console.log('PASS');
287
- " 2>&1) || {
288
- echo "Functional test failed: $result"
289
- return 1
290
- }
291
-
292
- if ! echo "$result" | grep -q "PASS"; then
293
- echo "$result"
294
- return 1
295
- fi
296
- }
297
-
298
- test_repo_config_get_all_sources_includes_defaults() {
299
- if ! command -v node &>/dev/null; then
300
- echo "SKIP: node not available"
301
- return 0
302
- fi
303
-
304
- local result
305
- result=$(node --experimental-vm-modules -e "
306
- import { loadRepoConfig, getAllSources } from './service/repo-config.js';
307
-
308
- // Load config with repo that has no sources specified
309
- const testConfig = {
310
- repos: {
311
- 'myorg/backend': {
312
- repo_path: '~/code/backend'
313
- }
314
- }
315
- };
316
-
317
- loadRepoConfig(testConfig);
318
-
319
- // getAllSources should include the default source
128
+ // getAllSources should return an array
320
129
  const sources = getAllSources();
321
130
 
322
- if (sources.length !== 1) {
323
- console.log('FAIL: Expected 1 source from getAllSources, got ' + sources.length);
324
- process.exit(1);
325
- }
326
-
327
- if (sources[0].type !== 'github_issue') {
328
- console.log('FAIL: Expected github_issue source, got ' + sources[0].type);
131
+ if (!Array.isArray(sources)) {
132
+ console.log('FAIL: Expected array from getAllSources');
329
133
  process.exit(1);
330
134
  }
331
-
332
- if (sources[0].repo_key !== 'myorg/backend') {
333
- console.log('FAIL: Expected repo_key myorg/backend, got ' + sources[0].repo_key);
334
- process.exit(1);
335
- }
336
-
337
135
  console.log('PASS');
338
136
  " 2>&1) || {
339
137
  echo "Functional test failed: $result"
@@ -375,9 +173,8 @@ echo "Implementation Tests:"
375
173
 
376
174
  for test_func in \
377
175
  test_repo_config_supports_yaml \
378
- test_repo_config_supports_prefix_matching \
379
- test_repo_config_merges_configs \
380
- test_repo_config_expands_placeholders
176
+ test_repo_config_supports_source_config \
177
+ test_repo_config_supports_tool_mappings
381
178
  do
382
179
  run_test "${test_func#test_}" "$test_func"
383
180
  done
@@ -386,19 +183,8 @@ echo ""
386
183
  echo "Functional Tests:"
387
184
 
388
185
  for test_func in \
389
- test_repo_config_defaults \
390
- test_repo_config_prefix_matching
391
- do
392
- run_test "${test_func#test_}" "$test_func"
393
- done
394
-
395
- echo ""
396
- echo "Default Sources Tests:"
397
-
398
- for test_func in \
399
- test_repo_config_default_sources \
400
- test_repo_config_explicit_sources_override_defaults \
401
- test_repo_config_get_all_sources_includes_defaults
186
+ test_repo_config_returns_empty_for_unknown_repo \
187
+ test_repo_config_gets_sources
402
188
  do
403
189
  run_test "${test_func#test_}" "$test_func"
404
190
  done