wraptc 1.0.2 → 1.0.4

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.
Files changed (71) hide show
  1. package/bin/wraptc +4 -4
  2. package/package.json +2 -2
  3. package/src/cli/__tests__/cli.test.ts +337 -0
  4. package/src/cli/index.ts +149 -0
  5. package/src/core/__tests__/fixtures/configs/project-config.json +14 -0
  6. package/src/core/__tests__/fixtures/configs/system-config.json +14 -0
  7. package/src/core/__tests__/fixtures/configs/user-config.json +15 -0
  8. package/src/core/__tests__/integration/integration.test.ts +241 -0
  9. package/src/core/__tests__/integration/mock-coder-adapter.test.ts +243 -0
  10. package/src/core/__tests__/test-utils.ts +136 -0
  11. package/src/core/__tests__/unit/adapters/runner.test.ts +302 -0
  12. package/src/core/__tests__/unit/basic-test.test.ts +44 -0
  13. package/src/core/__tests__/unit/basic.test.ts +12 -0
  14. package/src/core/__tests__/unit/config.test.ts +244 -0
  15. package/src/core/__tests__/unit/error-patterns.test.ts +181 -0
  16. package/src/core/__tests__/unit/memory-monitor.test.ts +354 -0
  17. package/src/core/__tests__/unit/plugin/registry.test.ts +356 -0
  18. package/src/core/__tests__/unit/providers/codex.test.ts +173 -0
  19. package/src/core/__tests__/unit/providers/configurable.test.ts +429 -0
  20. package/src/core/__tests__/unit/providers/gemini.test.ts +251 -0
  21. package/src/core/__tests__/unit/providers/opencode.test.ts +258 -0
  22. package/src/core/__tests__/unit/providers/qwen-code.test.ts +195 -0
  23. package/src/core/__tests__/unit/providers/simple-codex.test.ts +18 -0
  24. package/src/core/__tests__/unit/router.test.ts +967 -0
  25. package/src/core/__tests__/unit/state.test.ts +1079 -0
  26. package/src/core/__tests__/unit/unified/capabilities.test.ts +186 -0
  27. package/src/core/__tests__/unit/wrap-terminalcoder.test.ts +32 -0
  28. package/src/core/adapters/builtin/codex.ts +35 -0
  29. package/src/core/adapters/builtin/gemini.ts +34 -0
  30. package/src/core/adapters/builtin/index.ts +31 -0
  31. package/src/core/adapters/builtin/mock-coder.ts +148 -0
  32. package/src/core/adapters/builtin/qwen.ts +34 -0
  33. package/src/core/adapters/define.ts +48 -0
  34. package/src/core/adapters/index.ts +43 -0
  35. package/src/core/adapters/loader.ts +143 -0
  36. package/src/core/adapters/provider-bridge.ts +190 -0
  37. package/src/core/adapters/runner.ts +437 -0
  38. package/src/core/adapters/types.ts +172 -0
  39. package/src/core/config.ts +290 -0
  40. package/src/core/define-provider.ts +212 -0
  41. package/src/core/error-patterns.ts +147 -0
  42. package/src/core/index.ts +130 -0
  43. package/src/core/memory-monitor.ts +171 -0
  44. package/src/core/plugin/builtin.ts +87 -0
  45. package/src/core/plugin/index.ts +34 -0
  46. package/src/core/plugin/registry.ts +350 -0
  47. package/src/core/plugin/types.ts +209 -0
  48. package/src/core/provider-factory.ts +397 -0
  49. package/src/core/provider-loader.ts +171 -0
  50. package/src/core/providers/codex.ts +56 -0
  51. package/src/core/providers/configurable.ts +637 -0
  52. package/src/core/providers/custom.ts +261 -0
  53. package/src/core/providers/gemini.ts +41 -0
  54. package/src/core/providers/index.ts +383 -0
  55. package/src/core/providers/opencode.ts +168 -0
  56. package/src/core/providers/qwen-code.ts +41 -0
  57. package/src/core/router.ts +370 -0
  58. package/src/core/state.ts +258 -0
  59. package/src/core/types.ts +206 -0
  60. package/src/core/unified/capabilities.ts +184 -0
  61. package/src/core/unified/errors.ts +141 -0
  62. package/src/core/unified/index.ts +29 -0
  63. package/src/core/unified/output.ts +189 -0
  64. package/src/core/wrap-terminalcoder.ts +245 -0
  65. package/src/mcp/__tests__/server.test.ts +295 -0
  66. package/src/mcp/server.ts +284 -0
  67. package/src/test-fixtures/mock-coder.sh +194 -0
  68. package/dist/cli/index.js +0 -16501
  69. package/dist/core/index.js +0 -7531
  70. package/dist/mcp/server.js +0 -14568
  71. package/dist/wraptc-1.0.2.tgz +0 -0
@@ -0,0 +1,130 @@
1
+ // Main entry point for wrap-terminalcoder core
2
+ export * from "./wrap-terminalcoder";
3
+ export * from "./router";
4
+ export * from "./config";
5
+ export * from "./state";
6
+ export * from "./types";
7
+ export * from "./memory-monitor";
8
+ export * from "./provider-factory";
9
+
10
+ // Provider exports
11
+ export * from "./providers/index";
12
+ export { CustomProvider } from "./providers/custom";
13
+ export { ConfigurableProvider, createConfigurableProvider } from "./providers/configurable";
14
+ export { GeminiProvider } from "./providers/gemini";
15
+ export { QwenCodeProvider } from "./providers/qwen-code";
16
+ export { CodexProvider } from "./providers/codex";
17
+
18
+ // Provider definition helper - for creating custom providers via .ts config files
19
+ export {
20
+ defineProvider,
21
+ type ProviderDefinition,
22
+ type ProviderDefinitionInput,
23
+ ProviderDefinitionSchema,
24
+ InputConfigSchema,
25
+ OutputConfigSchema,
26
+ StreamingConfigSchema,
27
+ ArgsConfigSchema,
28
+ RetryConfigSchema,
29
+ ErrorPatternsSchema,
30
+ DEFAULT_ERROR_PATTERNS,
31
+ } from "./define-provider";
32
+
33
+ // Provider loader - for loading .ts config files
34
+ export {
35
+ loadProviderConfigs,
36
+ getProviderDirectories,
37
+ ensureUserProviderDir,
38
+ } from "./provider-loader";
39
+
40
+ // ============================================================================
41
+ // NEW: Adapter System - Lightweight terminal coder wrappers
42
+ // ============================================================================
43
+ export {
44
+ // Types
45
+ type AdapterConfig,
46
+ type AdapterDefinition,
47
+ type AdapterHooks,
48
+ type AdapterInvokeOptions,
49
+ type AdapterResult,
50
+ type AdapterInfo,
51
+ type InputMethod,
52
+ type OutputFormat,
53
+ type StreamingMode,
54
+ type StreamChunk,
55
+ type ErrorPatterns,
56
+ // Core functionality
57
+ defineAdapter,
58
+ AdapterRunner,
59
+ AdapterError,
60
+ // Loading
61
+ loadUserAdapters,
62
+ loadAllAdapters,
63
+ getAdapterDirectories,
64
+ ensureUserAdapterDir,
65
+ // Provider bridge
66
+ AdapterProviderBridge,
67
+ createProviderFromAdapter,
68
+ // Built-in adapters
69
+ geminiAdapter,
70
+ qwenAdapter,
71
+ codexAdapter,
72
+ builtInAdapters,
73
+ getBuiltInAdapter,
74
+ getBuiltInAdapterIds,
75
+ } from "./adapters";
76
+
77
+ // ============================================================================
78
+ // NEW: Plugin System - Formal plugin registry with lifecycle hooks
79
+ // ============================================================================
80
+ export {
81
+ // Types
82
+ type PluginDefinition,
83
+ type PluginRegistrationOptions,
84
+ type PluginRegistrationResult,
85
+ type PluginInfo,
86
+ type CreateProviderOptions,
87
+ type ManagedProvider,
88
+ type PluginContext,
89
+ type IPluginRegistry,
90
+ type IPluginLifecycle,
91
+ type ProviderFactory,
92
+ type PluginConfigType,
93
+ isLifecycleProvider,
94
+ // Registry
95
+ PluginRegistry,
96
+ getPluginRegistry,
97
+ // Built-in plugins
98
+ geminiPlugin,
99
+ qwenCodePlugin,
100
+ codexPlugin,
101
+ builtInPlugins,
102
+ registerBuiltInPlugins,
103
+ areBuiltInPluginsRegistered,
104
+ getBuiltInPluginTypes,
105
+ } from "./plugin";
106
+
107
+ // ============================================================================
108
+ // NEW: Unified Interface - Consistent types across all providers
109
+ // ============================================================================
110
+ export {
111
+ // Capabilities
112
+ Capability,
113
+ type CapabilityType,
114
+ type ICapabilities,
115
+ ProviderCapabilities,
116
+ // Output
117
+ type IOutput,
118
+ type IOutputMeta,
119
+ type UnifiedStreamChunk,
120
+ type NormalizerConfig,
121
+ DEFAULT_NORMALIZER_CONFIG,
122
+ OutputNormalizer,
123
+ // Errors
124
+ type IProviderError,
125
+ ProviderError,
126
+ classifyErrorMessage,
127
+ } from "./unified";
128
+
129
+ // Re-export integration tests for convenience
130
+ export { describe, test, expect } from "bun:test";
@@ -0,0 +1,171 @@
1
+ // Memory monitoring utilities for wrap-terminalcoder
2
+ // Helps prevent memory leaks and monitor memory usage
3
+
4
+ export interface MemoryStats {
5
+ heapUsed: number;
6
+ heapTotal: number;
7
+ external: number;
8
+ rss: number;
9
+ arrayBuffers: number;
10
+ }
11
+
12
+ export interface MemoryThresholds {
13
+ warning: number; // e.g., 0.8 for 80%
14
+ critical: number; // e.g., 0.9 for 90%
15
+ }
16
+
17
+ export class MemoryMonitor {
18
+ private static instance: MemoryMonitor;
19
+ private isMonitoring = false;
20
+ private intervalId: NodeJS.Timeout | null = null;
21
+ private thresholds: MemoryThresholds = { warning: 0.8, critical: 0.9 };
22
+
23
+ private constructor() {}
24
+
25
+ static getInstance(): MemoryMonitor {
26
+ if (!MemoryMonitor.instance) {
27
+ MemoryMonitor.instance = new MemoryMonitor();
28
+ }
29
+ return MemoryMonitor.instance;
30
+ }
31
+
32
+ /**
33
+ * Get current memory usage statistics
34
+ */
35
+ getMemoryStats(): MemoryStats {
36
+ const usage = process.memoryUsage();
37
+ return {
38
+ heapUsed: Math.round(usage.heapUsed / 1024 / 1024), // MB
39
+ heapTotal: Math.round(usage.heapTotal / 1024 / 1024), // MB
40
+ external: Math.round(usage.external / 1024 / 1024), // MB
41
+ rss: Math.round(usage.rss / 1024 / 1024), // MB
42
+ arrayBuffers: Math.round((usage as any).arrayBuffers / 1024 / 1024), // MB
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Check if memory usage is within acceptable limits
48
+ */
49
+ checkMemoryLimit(threshold = 0.85): boolean {
50
+ const usage = process.memoryUsage();
51
+ const heapUsedPercent = usage.heapUsed / usage.heapTotal;
52
+ return heapUsedPercent < threshold;
53
+ }
54
+
55
+ /**
56
+ * Get memory usage as a percentage
57
+ */
58
+ getMemoryUsagePercent(): number {
59
+ const usage = process.memoryUsage();
60
+ return Math.round((usage.heapUsed / usage.heapTotal) * 100);
61
+ }
62
+
63
+ /**
64
+ * Format memory stats for logging
65
+ */
66
+ formatMemoryStats(stats?: MemoryStats): string {
67
+ const s = stats || this.getMemoryStats();
68
+ return `Heap: ${s.heapUsed}MB/${s.heapTotal}MB (${this.getMemoryUsagePercent()}%) | RSS: ${s.rss}MB | Buffers: ${s.arrayBuffers}MB`;
69
+ }
70
+
71
+ /**
72
+ * Start periodic memory monitoring
73
+ */
74
+ startMonitoring(intervalMs = 30000, logLevel: "info" | "warn" | "error" = "info"): void {
75
+ if (this.isMonitoring) {
76
+ console.log("[MemoryMonitor] Already monitoring memory usage");
77
+ return;
78
+ }
79
+
80
+ this.isMonitoring = true;
81
+ this.intervalId = setInterval(() => {
82
+ const stats = this.getMemoryStats();
83
+ const usagePercent = this.getMemoryUsagePercent();
84
+
85
+ if (usagePercent >= this.thresholds.critical * 100) {
86
+ console.error(`[MemoryMonitor] CRITICAL: ${this.formatMemoryStats(stats)}`);
87
+ this.triggerMemoryAlert("critical", stats);
88
+ } else if (usagePercent >= this.thresholds.warning * 100) {
89
+ console.warn(`[MemoryMonitor] WARNING: ${this.formatMemoryStats(stats)}`);
90
+ this.triggerMemoryAlert("warning", stats);
91
+ } else if (logLevel === "info") {
92
+ console.log(`[MemoryMonitor] ${this.formatMemoryStats(stats)}`);
93
+ }
94
+ }, intervalMs);
95
+
96
+ console.log(`[MemoryMonitor] Started monitoring memory usage every ${intervalMs}ms`);
97
+ }
98
+
99
+ /**
100
+ * Stop periodic memory monitoring
101
+ */
102
+ stopMonitoring(): void {
103
+ if (this.intervalId) {
104
+ clearInterval(this.intervalId);
105
+ this.intervalId = null;
106
+ }
107
+ this.isMonitoring = false;
108
+ console.log("[MemoryMonitor] Stopped monitoring");
109
+ }
110
+
111
+ /**
112
+ * Set memory usage thresholds
113
+ */
114
+ setThresholds(thresholds: MemoryThresholds): void {
115
+ this.thresholds = thresholds;
116
+ }
117
+
118
+ /**
119
+ * Force garbage collection if available (Node.js with --expose-gc)
120
+ */
121
+ forceGC(): void {
122
+ if (global.gc) {
123
+ global.gc();
124
+ console.log("[MemoryMonitor] Garbage collection triggered");
125
+ } else {
126
+ console.log("[MemoryMonitor] Garbage collection not available (run with --expose-gc flag)");
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Log detailed memory report
132
+ */
133
+ logMemoryReport(): void {
134
+ const stats = this.getMemoryStats();
135
+ console.log("[MemoryMonitor] === MEMORY REPORT ===");
136
+ console.log(`Heap Used: ${stats.heapUsed}MB`);
137
+ console.log(`Heap Total: ${stats.heapTotal}MB`);
138
+ console.log(`RSS: ${stats.rss}MB`);
139
+ console.log(`External: ${stats.external}MB`);
140
+ console.log(`Array Buffers: ${stats.arrayBuffers}MB`);
141
+ console.log(`Usage: ${this.getMemoryUsagePercent()}%`);
142
+ console.log("[MemoryMonitor] ====================");
143
+ }
144
+
145
+ private triggerMemoryAlert(level: "warning" | "critical", stats: MemoryStats): void {
146
+ // Emit event or call alerting system
147
+ if (level === "critical") {
148
+ console.error(`[MemoryMonitor] Memory usage critical! Consider:
149
+ 1. Restarting the application
150
+ 2. Reducing concurrent requests
151
+ 3. Implementing streaming limits
152
+ 4. Adding more memory monitoring`);
153
+ }
154
+ }
155
+ }
156
+
157
+ // Export singleton instance
158
+ export const memoryMonitor = MemoryMonitor.getInstance();
159
+
160
+ // Helper function to format bytes
161
+ export function formatBytes(bytes: number, decimals = 2): string {
162
+ if (bytes === 0) return "0 Bytes";
163
+
164
+ const k = 1024;
165
+ const dm = decimals < 0 ? 0 : decimals;
166
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
167
+
168
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
169
+
170
+ return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
171
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Built-in Plugins
3
+ *
4
+ * Wraps the built-in adapters as plugins for the registry.
5
+ */
6
+
7
+ import { codexAdapter, geminiAdapter, qwenAdapter } from "../adapters/builtin";
8
+ import { createProviderFromAdapter } from "../adapters/provider-bridge";
9
+ import { PluginRegistry } from "./registry";
10
+ import type { PluginDefinition } from "./types";
11
+
12
+ /**
13
+ * Gemini CLI plugin
14
+ */
15
+ export const geminiPlugin: PluginDefinition = {
16
+ type: "gemini",
17
+ displayName: "Gemini CLI",
18
+ description: "Google Gemini CLI for AI-assisted coding",
19
+ version: "1.0.0",
20
+ binary: "gemini",
21
+ capabilities: ["generate", "edit", "explain", "test"],
22
+ hasLifecycle: false,
23
+ factory: () => createProviderFromAdapter(geminiAdapter),
24
+ };
25
+
26
+ /**
27
+ * Qwen Code CLI plugin
28
+ */
29
+ export const qwenCodePlugin: PluginDefinition = {
30
+ type: "qwen-code",
31
+ displayName: "Qwen Code CLI",
32
+ description: "Qwen Code CLI for AI-assisted coding",
33
+ version: "1.0.0",
34
+ binary: "qwen",
35
+ capabilities: ["generate", "edit", "explain", "test"],
36
+ hasLifecycle: false,
37
+ factory: () => createProviderFromAdapter(qwenAdapter),
38
+ };
39
+
40
+ /**
41
+ * Codex CLI plugin
42
+ */
43
+ export const codexPlugin: PluginDefinition = {
44
+ type: "codex",
45
+ displayName: "Codex CLI",
46
+ description: "OpenAI Codex CLI for code generation",
47
+ version: "1.0.0",
48
+ binary: "codex",
49
+ capabilities: ["generate", "edit", "test"],
50
+ hasLifecycle: false,
51
+ factory: () => createProviderFromAdapter(codexAdapter),
52
+ };
53
+
54
+ /**
55
+ * All built-in plugins
56
+ */
57
+ export const builtInPlugins: PluginDefinition[] = [geminiPlugin, qwenCodePlugin, codexPlugin];
58
+
59
+ /**
60
+ * Register all built-in plugins
61
+ */
62
+ export async function registerBuiltInPlugins(
63
+ registry: PluginRegistry = PluginRegistry.getInstance(),
64
+ ): Promise<void> {
65
+ for (const plugin of builtInPlugins) {
66
+ const result = registry.registerSync(plugin, { builtIn: true });
67
+ if (!result.success) {
68
+ console.warn(`Failed to register built-in plugin ${plugin.type}:`, result.message);
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Check if built-in plugins are registered
75
+ */
76
+ export function areBuiltInPluginsRegistered(
77
+ registry: PluginRegistry = PluginRegistry.getInstance(),
78
+ ): boolean {
79
+ return builtInPlugins.every((plugin) => registry.has(plugin.type));
80
+ }
81
+
82
+ /**
83
+ * Get built-in plugin types
84
+ */
85
+ export function getBuiltInPluginTypes(): string[] {
86
+ return builtInPlugins.map((p) => p.type);
87
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Plugin System Exports
3
+ */
4
+
5
+ // Types
6
+ export type {
7
+ PluginDefinition,
8
+ PluginRegistrationOptions,
9
+ PluginRegistrationResult,
10
+ PluginInfo,
11
+ CreateProviderOptions,
12
+ ManagedProvider,
13
+ PluginContext,
14
+ IPluginRegistry,
15
+ IPluginLifecycle,
16
+ ProviderFactory,
17
+ PluginConfigType,
18
+ } from "./types";
19
+
20
+ export { isLifecycleProvider } from "./types";
21
+
22
+ // Registry
23
+ export { PluginRegistry, getPluginRegistry } from "./registry";
24
+
25
+ // Built-in plugins
26
+ export {
27
+ geminiPlugin,
28
+ qwenCodePlugin,
29
+ codexPlugin,
30
+ builtInPlugins,
31
+ registerBuiltInPlugins,
32
+ areBuiltInPluginsRegistered,
33
+ getBuiltInPluginTypes,
34
+ } from "./builtin";