ucn 3.0.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.

Potentially problematic release.


This version of ucn might be problematic. Click here for more details.

Files changed (45) hide show
  1. package/.claude/skills/ucn/SKILL.md +77 -0
  2. package/LICENSE +21 -0
  3. package/README.md +135 -0
  4. package/cli/index.js +2437 -0
  5. package/core/discovery.js +513 -0
  6. package/core/imports.js +558 -0
  7. package/core/output.js +1274 -0
  8. package/core/parser.js +279 -0
  9. package/core/project.js +3261 -0
  10. package/index.js +52 -0
  11. package/languages/go.js +653 -0
  12. package/languages/index.js +267 -0
  13. package/languages/java.js +826 -0
  14. package/languages/javascript.js +1346 -0
  15. package/languages/python.js +667 -0
  16. package/languages/rust.js +950 -0
  17. package/languages/utils.js +457 -0
  18. package/package.json +42 -0
  19. package/test/fixtures/go/go.mod +3 -0
  20. package/test/fixtures/go/main.go +257 -0
  21. package/test/fixtures/go/service.go +187 -0
  22. package/test/fixtures/java/DataService.java +279 -0
  23. package/test/fixtures/java/Main.java +287 -0
  24. package/test/fixtures/java/Utils.java +199 -0
  25. package/test/fixtures/java/pom.xml +6 -0
  26. package/test/fixtures/javascript/main.js +109 -0
  27. package/test/fixtures/javascript/package.json +1 -0
  28. package/test/fixtures/javascript/service.js +88 -0
  29. package/test/fixtures/javascript/utils.js +67 -0
  30. package/test/fixtures/python/main.py +198 -0
  31. package/test/fixtures/python/pyproject.toml +3 -0
  32. package/test/fixtures/python/service.py +166 -0
  33. package/test/fixtures/python/utils.py +118 -0
  34. package/test/fixtures/rust/Cargo.toml +3 -0
  35. package/test/fixtures/rust/main.rs +253 -0
  36. package/test/fixtures/rust/service.rs +210 -0
  37. package/test/fixtures/rust/utils.rs +154 -0
  38. package/test/fixtures/typescript/main.ts +154 -0
  39. package/test/fixtures/typescript/package.json +1 -0
  40. package/test/fixtures/typescript/repository.ts +149 -0
  41. package/test/fixtures/typescript/types.ts +114 -0
  42. package/test/parser.test.js +3661 -0
  43. package/test/public-repos-test.js +477 -0
  44. package/test/systematic-test.js +619 -0
  45. package/ucn.js +8 -0
@@ -0,0 +1,257 @@
1
+ // Package main provides test fixtures for Go parsing.
2
+ package main
3
+
4
+ import (
5
+ "context"
6
+ "errors"
7
+ "fmt"
8
+ "sync"
9
+ )
10
+
11
+ // Status represents the status of a task.
12
+ type Status string
13
+
14
+ const (
15
+ StatusPending Status = "pending"
16
+ StatusActive Status = "active"
17
+ StatusCompleted Status = "completed"
18
+ StatusFailed Status = "failed"
19
+ )
20
+
21
+ // Task represents a task entity.
22
+ type Task struct {
23
+ ID string
24
+ Name string
25
+ Status Status
26
+ Priority int
27
+ Metadata map[string]interface{}
28
+ }
29
+
30
+ // TaskManager manages tasks.
31
+ type TaskManager struct {
32
+ tasks []*Task
33
+ mu sync.RWMutex
34
+ service *DataService
35
+ }
36
+
37
+ // NewTaskManager creates a new task manager.
38
+ func NewTaskManager(service *DataService) *TaskManager {
39
+ return &TaskManager{
40
+ tasks: make([]*Task, 0),
41
+ service: service,
42
+ }
43
+ }
44
+
45
+ // AddTask adds a task to the manager.
46
+ func (tm *TaskManager) AddTask(task *Task) error {
47
+ if err := ValidateTask(task); err != nil {
48
+ return err
49
+ }
50
+ tm.mu.Lock()
51
+ defer tm.mu.Unlock()
52
+ tm.tasks = append(tm.tasks, task)
53
+ return nil
54
+ }
55
+
56
+ // GetTask retrieves a task by ID.
57
+ func (tm *TaskManager) GetTask(id string) (*Task, error) {
58
+ tm.mu.RLock()
59
+ defer tm.mu.RUnlock()
60
+ for _, task := range tm.tasks {
61
+ if task.ID == id {
62
+ return task, nil
63
+ }
64
+ }
65
+ return nil, errors.New("task not found")
66
+ }
67
+
68
+ // GetTasks returns all tasks, optionally filtered.
69
+ func (tm *TaskManager) GetTasks(filter func(*Task) bool) []*Task {
70
+ tm.mu.RLock()
71
+ defer tm.mu.RUnlock()
72
+ if filter == nil {
73
+ result := make([]*Task, len(tm.tasks))
74
+ copy(result, tm.tasks)
75
+ return result
76
+ }
77
+ var result []*Task
78
+ for _, task := range tm.tasks {
79
+ if filter(task) {
80
+ result = append(result, task)
81
+ }
82
+ }
83
+ return result
84
+ }
85
+
86
+ // UpdateTask updates a task by ID.
87
+ func (tm *TaskManager) UpdateTask(id string, updates map[string]interface{}) (*Task, error) {
88
+ tm.mu.Lock()
89
+ defer tm.mu.Unlock()
90
+ for _, task := range tm.tasks {
91
+ if task.ID == id {
92
+ applyUpdates(task, updates)
93
+ return task, nil
94
+ }
95
+ }
96
+ return nil, errors.New("task not found")
97
+ }
98
+
99
+ // DeleteTask removes a task by ID.
100
+ func (tm *TaskManager) DeleteTask(id string) bool {
101
+ tm.mu.Lock()
102
+ defer tm.mu.Unlock()
103
+ for i, task := range tm.tasks {
104
+ if task.ID == id {
105
+ tm.tasks = append(tm.tasks[:i], tm.tasks[i+1:]...)
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ }
111
+
112
+ // SyncTasks syncs tasks with the service.
113
+ func (tm *TaskManager) SyncTasks(ctx context.Context) error {
114
+ tm.mu.RLock()
115
+ defer tm.mu.RUnlock()
116
+ for _, task := range tm.tasks {
117
+ if err := tm.service.Save(ctx, task); err != nil {
118
+ return err
119
+ }
120
+ }
121
+ return nil
122
+ }
123
+
124
+ // ValidateTask validates a task.
125
+ func ValidateTask(task *Task) error {
126
+ if task == nil {
127
+ return errors.New("task cannot be nil")
128
+ }
129
+ if task.ID == "" {
130
+ return errors.New("task ID is required")
131
+ }
132
+ if task.Name == "" {
133
+ return errors.New("task name is required")
134
+ }
135
+ return nil
136
+ }
137
+
138
+ // applyUpdates applies updates to a task.
139
+ func applyUpdates(task *Task, updates map[string]interface{}) {
140
+ if name, ok := updates["name"].(string); ok {
141
+ task.Name = name
142
+ }
143
+ if status, ok := updates["status"].(Status); ok {
144
+ task.Status = status
145
+ }
146
+ if priority, ok := updates["priority"].(int); ok {
147
+ task.Priority = priority
148
+ }
149
+ }
150
+
151
+ // CreateTask is a factory function for tasks.
152
+ func CreateTask(name string, priority int) *Task {
153
+ return &Task{
154
+ ID: generateID(),
155
+ Name: name,
156
+ Status: StatusPending,
157
+ Priority: priority,
158
+ Metadata: make(map[string]interface{}),
159
+ }
160
+ }
161
+
162
+ // generateID generates a unique ID.
163
+ func generateID() string {
164
+ return fmt.Sprintf("task-%d", idCounter)
165
+ }
166
+
167
+ var idCounter = 0
168
+
169
+ // FilterByStatus filters tasks by status.
170
+ func FilterByStatus(tasks []*Task, status Status) []*Task {
171
+ var result []*Task
172
+ for _, task := range tasks {
173
+ if task.Status == status {
174
+ result = append(result, task)
175
+ }
176
+ }
177
+ return result
178
+ }
179
+
180
+ // FilterByPriority filters tasks by minimum priority.
181
+ func FilterByPriority(tasks []*Task, minPriority int) []*Task {
182
+ var result []*Task
183
+ for _, task := range tasks {
184
+ if task.Priority >= minPriority {
185
+ result = append(result, task)
186
+ }
187
+ }
188
+ return result
189
+ }
190
+
191
+ // TaskProcessor processes tasks.
192
+ type TaskProcessor struct {
193
+ manager *TaskManager
194
+ }
195
+
196
+ // NewTaskProcessor creates a new task processor.
197
+ func NewTaskProcessor(manager *TaskManager) *TaskProcessor {
198
+ return &TaskProcessor{manager: manager}
199
+ }
200
+
201
+ // ProcessAll processes all tasks.
202
+ func (tp *TaskProcessor) ProcessAll() ([]map[string]interface{}, error) {
203
+ tasks := tp.manager.GetTasks(nil)
204
+ results := make([]map[string]interface{}, 0, len(tasks))
205
+ for _, task := range tasks {
206
+ result, err := tp.processTask(task)
207
+ if err != nil {
208
+ return nil, err
209
+ }
210
+ results = append(results, result)
211
+ }
212
+ return results, nil
213
+ }
214
+
215
+ // ProcessPending processes only pending tasks.
216
+ func (tp *TaskProcessor) ProcessPending() ([]map[string]interface{}, error) {
217
+ tasks := tp.manager.GetTasks(func(t *Task) bool {
218
+ return t.Status == StatusPending
219
+ })
220
+ results := make([]map[string]interface{}, 0, len(tasks))
221
+ for _, task := range tasks {
222
+ result, err := tp.processTask(task)
223
+ if err != nil {
224
+ return nil, err
225
+ }
226
+ results = append(results, result)
227
+ }
228
+ return results, nil
229
+ }
230
+
231
+ // processTask processes a single task.
232
+ func (tp *TaskProcessor) processTask(task *Task) (map[string]interface{}, error) {
233
+ return FormatTask(task), nil
234
+ }
235
+
236
+ // FormatTask formats a task as a map.
237
+ func FormatTask(task *Task) map[string]interface{} {
238
+ return map[string]interface{}{
239
+ "id": task.ID,
240
+ "name": task.Name,
241
+ "status": task.Status,
242
+ "priority": task.Priority,
243
+ }
244
+ }
245
+
246
+ // unusedFunction is a function that's never called.
247
+ func unusedFunction() string {
248
+ return "never used"
249
+ }
250
+
251
+ func main() {
252
+ service := NewDataService(nil)
253
+ manager := NewTaskManager(service)
254
+ task := CreateTask("Test Task", 1)
255
+ manager.AddTask(task)
256
+ fmt.Printf("Created task: %s\n", task.Name)
257
+ }
@@ -0,0 +1,187 @@
1
+ // Package main provides service implementations.
2
+ package main
3
+
4
+ import (
5
+ "context"
6
+ "errors"
7
+ "sync"
8
+ "time"
9
+ )
10
+
11
+ // Config holds service configuration.
12
+ type Config struct {
13
+ APIURL string
14
+ Timeout time.Duration
15
+ Retries int
16
+ Debug bool
17
+ }
18
+
19
+ // DefaultConfig returns the default configuration.
20
+ func DefaultConfig() *Config {
21
+ return &Config{
22
+ APIURL: "https://api.example.com",
23
+ Timeout: 5 * time.Second,
24
+ Retries: 3,
25
+ Debug: false,
26
+ }
27
+ }
28
+
29
+ // DataService provides data operations.
30
+ type DataService struct {
31
+ config *Config
32
+ storage map[string]interface{}
33
+ mu sync.RWMutex
34
+ }
35
+
36
+ // NewDataService creates a new data service.
37
+ func NewDataService(config *Config) *DataService {
38
+ if config == nil {
39
+ config = DefaultConfig()
40
+ }
41
+ return &DataService{
42
+ config: config,
43
+ storage: make(map[string]interface{}),
44
+ }
45
+ }
46
+
47
+ // Save saves an entity.
48
+ func (ds *DataService) Save(ctx context.Context, entity interface{}) error {
49
+ id, err := getEntityID(entity)
50
+ if err != nil {
51
+ return err
52
+ }
53
+ ds.mu.Lock()
54
+ defer ds.mu.Unlock()
55
+ ds.storage[id] = entity
56
+ return nil
57
+ }
58
+
59
+ // Find finds an entity by ID.
60
+ func (ds *DataService) Find(ctx context.Context, id string) (interface{}, error) {
61
+ ds.mu.RLock()
62
+ defer ds.mu.RUnlock()
63
+ if entity, ok := ds.storage[id]; ok {
64
+ return entity, nil
65
+ }
66
+ return nil, errors.New("entity not found")
67
+ }
68
+
69
+ // FindAll returns all entities.
70
+ func (ds *DataService) FindAll(ctx context.Context) []interface{} {
71
+ ds.mu.RLock()
72
+ defer ds.mu.RUnlock()
73
+ result := make([]interface{}, 0, len(ds.storage))
74
+ for _, entity := range ds.storage {
75
+ result = append(result, entity)
76
+ }
77
+ return result
78
+ }
79
+
80
+ // Delete removes an entity.
81
+ func (ds *DataService) Delete(ctx context.Context, id string) error {
82
+ ds.mu.Lock()
83
+ defer ds.mu.Unlock()
84
+ if _, ok := ds.storage[id]; !ok {
85
+ return errors.New("entity not found")
86
+ }
87
+ delete(ds.storage, id)
88
+ return nil
89
+ }
90
+
91
+ // Clear removes all entities.
92
+ func (ds *DataService) Clear() {
93
+ ds.mu.Lock()
94
+ defer ds.mu.Unlock()
95
+ ds.storage = make(map[string]interface{})
96
+ }
97
+
98
+ // getEntityID extracts the ID from an entity.
99
+ func getEntityID(entity interface{}) (string, error) {
100
+ if task, ok := entity.(*Task); ok {
101
+ return task.ID, nil
102
+ }
103
+ return "", errors.New("unknown entity type")
104
+ }
105
+
106
+ // CacheService provides caching.
107
+ type CacheService struct {
108
+ ttl time.Duration
109
+ cache map[string]interface{}
110
+ timestamps map[string]time.Time
111
+ mu sync.RWMutex
112
+ }
113
+
114
+ // NewCacheService creates a new cache service.
115
+ func NewCacheService(ttl time.Duration) *CacheService {
116
+ return &CacheService{
117
+ ttl: ttl,
118
+ cache: make(map[string]interface{}),
119
+ timestamps: make(map[string]time.Time),
120
+ }
121
+ }
122
+
123
+ // Get retrieves a value from cache.
124
+ func (cs *CacheService) Get(key string) (interface{}, bool) {
125
+ cs.mu.RLock()
126
+ defer cs.mu.RUnlock()
127
+ if value, ok := cs.cache[key]; ok {
128
+ if time.Since(cs.timestamps[key]) < cs.ttl {
129
+ return value, true
130
+ }
131
+ }
132
+ return nil, false
133
+ }
134
+
135
+ // Set stores a value in cache.
136
+ func (cs *CacheService) Set(key string, value interface{}) {
137
+ cs.mu.Lock()
138
+ defer cs.mu.Unlock()
139
+ cs.cache[key] = value
140
+ cs.timestamps[key] = time.Now()
141
+ }
142
+
143
+ // Delete removes a value from cache.
144
+ func (cs *CacheService) Delete(key string) bool {
145
+ cs.mu.Lock()
146
+ defer cs.mu.Unlock()
147
+ if _, ok := cs.cache[key]; ok {
148
+ delete(cs.cache, key)
149
+ delete(cs.timestamps, key)
150
+ return true
151
+ }
152
+ return false
153
+ }
154
+
155
+ // Clear removes all values from cache.
156
+ func (cs *CacheService) Clear() {
157
+ cs.mu.Lock()
158
+ defer cs.mu.Unlock()
159
+ cs.cache = make(map[string]interface{})
160
+ cs.timestamps = make(map[string]time.Time)
161
+ }
162
+
163
+ // CleanupExpired removes expired entries.
164
+ func (cs *CacheService) CleanupExpired() int {
165
+ cs.mu.Lock()
166
+ defer cs.mu.Unlock()
167
+ count := 0
168
+ for key, ts := range cs.timestamps {
169
+ if time.Since(ts) >= cs.ttl {
170
+ delete(cs.cache, key)
171
+ delete(cs.timestamps, key)
172
+ count++
173
+ }
174
+ }
175
+ return count
176
+ }
177
+
178
+ // Repository defines the repository interface.
179
+ type Repository interface {
180
+ Save(ctx context.Context, entity interface{}) error
181
+ Find(ctx context.Context, id string) (interface{}, error)
182
+ FindAll(ctx context.Context) []interface{}
183
+ Delete(ctx context.Context, id string) error
184
+ }
185
+
186
+ // Ensure DataService implements Repository.
187
+ var _ Repository = (*DataService)(nil)
@@ -0,0 +1,279 @@
1
+ package fixtures;
2
+
3
+ import java.util.*;
4
+ import java.util.concurrent.ConcurrentHashMap;
5
+ import java.time.Instant;
6
+
7
+ /**
8
+ * Data service for managing entities.
9
+ * @param <T> The entity type
10
+ */
11
+ public class DataService<T> {
12
+ private final Map<String, T> storage;
13
+ private final Config config;
14
+
15
+ public DataService() {
16
+ this(new Config());
17
+ }
18
+
19
+ public DataService(Config config) {
20
+ this.storage = new ConcurrentHashMap<>();
21
+ this.config = config;
22
+ }
23
+
24
+ /**
25
+ * Save an entity.
26
+ */
27
+ public void save(T entity) {
28
+ String id = getEntityId(entity);
29
+ storage.put(id, entity);
30
+ }
31
+
32
+ /**
33
+ * Find an entity by ID.
34
+ */
35
+ public Optional<T> find(String id) {
36
+ return Optional.ofNullable(storage.get(id));
37
+ }
38
+
39
+ /**
40
+ * Find all entities.
41
+ */
42
+ public List<T> findAll() {
43
+ return new ArrayList<>(storage.values());
44
+ }
45
+
46
+ /**
47
+ * Delete an entity by ID.
48
+ */
49
+ public boolean delete(String id) {
50
+ return storage.remove(id) != null;
51
+ }
52
+
53
+ /**
54
+ * Clear all entities.
55
+ */
56
+ public void clear() {
57
+ storage.clear();
58
+ }
59
+
60
+ /**
61
+ * Get the config.
62
+ */
63
+ public Config getConfig() {
64
+ return config;
65
+ }
66
+
67
+ /**
68
+ * Get the entity ID using reflection.
69
+ */
70
+ @SuppressWarnings("unchecked")
71
+ private String getEntityId(T entity) {
72
+ try {
73
+ var method = entity.getClass().getMethod("getId");
74
+ return (String) method.invoke(entity);
75
+ } catch (Exception e) {
76
+ throw new RuntimeException("Entity must have getId() method", e);
77
+ }
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Configuration class.
83
+ */
84
+ class Config {
85
+ private String apiUrl;
86
+ private int timeout;
87
+ private int retries;
88
+ private boolean debug;
89
+
90
+ public Config() {
91
+ this.apiUrl = "https://api.example.com";
92
+ this.timeout = 5000;
93
+ this.retries = 3;
94
+ this.debug = false;
95
+ }
96
+
97
+ public String getApiUrl() {
98
+ return apiUrl;
99
+ }
100
+
101
+ public void setApiUrl(String apiUrl) {
102
+ this.apiUrl = apiUrl;
103
+ }
104
+
105
+ public int getTimeout() {
106
+ return timeout;
107
+ }
108
+
109
+ public void setTimeout(int timeout) {
110
+ this.timeout = timeout;
111
+ }
112
+
113
+ public int getRetries() {
114
+ return retries;
115
+ }
116
+
117
+ public void setRetries(int retries) {
118
+ this.retries = retries;
119
+ }
120
+
121
+ public boolean isDebug() {
122
+ return debug;
123
+ }
124
+
125
+ public void setDebug(boolean debug) {
126
+ this.debug = debug;
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Repository interface.
132
+ * @param <T> The entity type
133
+ */
134
+ interface Repository<T> {
135
+ void save(T entity);
136
+ Optional<T> find(String id);
137
+ List<T> findAll();
138
+ boolean delete(String id);
139
+ }
140
+
141
+ /**
142
+ * Cache service with TTL.
143
+ * @param <T> The cached value type
144
+ */
145
+ class CacheService<T> {
146
+ private final Map<String, CacheEntry<T>> cache;
147
+ private final long ttlMillis;
148
+
149
+ public CacheService(long ttlMillis) {
150
+ this.cache = new ConcurrentHashMap<>();
151
+ this.ttlMillis = ttlMillis;
152
+ }
153
+
154
+ /**
155
+ * Get a value from cache.
156
+ */
157
+ public Optional<T> get(String key) {
158
+ CacheEntry<T> entry = cache.get(key);
159
+ if (entry != null && !entry.isExpired(ttlMillis)) {
160
+ return Optional.of(entry.getValue());
161
+ }
162
+ return Optional.empty();
163
+ }
164
+
165
+ /**
166
+ * Set a value in cache.
167
+ */
168
+ public void set(String key, T value) {
169
+ cache.put(key, new CacheEntry<>(value));
170
+ }
171
+
172
+ /**
173
+ * Delete a value from cache.
174
+ */
175
+ public boolean delete(String key) {
176
+ return cache.remove(key) != null;
177
+ }
178
+
179
+ /**
180
+ * Clear all values from cache.
181
+ */
182
+ public void clear() {
183
+ cache.clear();
184
+ }
185
+
186
+ /**
187
+ * Remove expired entries.
188
+ */
189
+ public int cleanupExpired() {
190
+ List<String> expired = new ArrayList<>();
191
+ for (Map.Entry<String, CacheEntry<T>> entry : cache.entrySet()) {
192
+ if (entry.getValue().isExpired(ttlMillis)) {
193
+ expired.add(entry.getKey());
194
+ }
195
+ }
196
+ for (String key : expired) {
197
+ cache.remove(key);
198
+ }
199
+ return expired.size();
200
+ }
201
+
202
+ /**
203
+ * Cache entry with timestamp.
204
+ */
205
+ private static class CacheEntry<T> {
206
+ private final T value;
207
+ private final Instant timestamp;
208
+
209
+ CacheEntry(T value) {
210
+ this.value = value;
211
+ this.timestamp = Instant.now();
212
+ }
213
+
214
+ T getValue() {
215
+ return value;
216
+ }
217
+
218
+ boolean isExpired(long ttlMillis) {
219
+ return Instant.now().toEpochMilli() - timestamp.toEpochMilli() >= ttlMillis;
220
+ }
221
+ }
222
+ }
223
+
224
+ /**
225
+ * API client for HTTP requests.
226
+ */
227
+ class ApiClient {
228
+ private final Config config;
229
+
230
+ public ApiClient(Config config) {
231
+ this.config = config;
232
+ }
233
+
234
+ /**
235
+ * Make a GET request.
236
+ */
237
+ public Map<String, Object> get(String path) {
238
+ String url = buildUrl(path);
239
+ return request("GET", url, null);
240
+ }
241
+
242
+ /**
243
+ * Make a POST request.
244
+ */
245
+ public Map<String, Object> post(String path, Map<String, Object> data) {
246
+ String url = buildUrl(path);
247
+ return request("POST", url, data);
248
+ }
249
+
250
+ /**
251
+ * Make a DELETE request.
252
+ */
253
+ public Map<String, Object> delete(String path) {
254
+ String url = buildUrl(path);
255
+ return request("DELETE", url, null);
256
+ }
257
+
258
+ /**
259
+ * Build the full URL.
260
+ */
261
+ private String buildUrl(String path) {
262
+ if (path.startsWith("http")) {
263
+ return path;
264
+ }
265
+ return config.getApiUrl() + path;
266
+ }
267
+
268
+ /**
269
+ * Make an HTTP request.
270
+ */
271
+ private Map<String, Object> request(String method, String url, Map<String, Object> data) {
272
+ // Simulated request
273
+ Map<String, Object> result = new HashMap<>();
274
+ result.put("status", 200);
275
+ result.put("method", method);
276
+ result.put("url", url);
277
+ return result;
278
+ }
279
+ }