@ace-sdk/cli 2.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.
Files changed (150) hide show
  1. package/README.md +61 -0
  2. package/dist/cli.d.ts +14 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +427 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/bootstrap.d.ts +19 -0
  7. package/dist/commands/bootstrap.d.ts.map +1 -0
  8. package/dist/commands/bootstrap.js +157 -0
  9. package/dist/commands/bootstrap.js.map +1 -0
  10. package/dist/commands/cache.d.ts +19 -0
  11. package/dist/commands/cache.d.ts.map +1 -0
  12. package/dist/commands/cache.js +101 -0
  13. package/dist/commands/cache.js.map +1 -0
  14. package/dist/commands/clear.d.ts +12 -0
  15. package/dist/commands/clear.d.ts.map +1 -0
  16. package/dist/commands/clear.js +50 -0
  17. package/dist/commands/clear.js.map +1 -0
  18. package/dist/commands/config.d.ts +34 -0
  19. package/dist/commands/config.d.ts.map +1 -0
  20. package/dist/commands/config.js +423 -0
  21. package/dist/commands/config.js.map +1 -0
  22. package/dist/commands/delta.d.ts +14 -0
  23. package/dist/commands/delta.d.ts.map +1 -0
  24. package/dist/commands/delta.js +140 -0
  25. package/dist/commands/delta.js.map +1 -0
  26. package/dist/commands/doctor.d.ts +8 -0
  27. package/dist/commands/doctor.d.ts.map +1 -0
  28. package/dist/commands/doctor.js +187 -0
  29. package/dist/commands/doctor.js.map +1 -0
  30. package/dist/commands/export.d.ts +12 -0
  31. package/dist/commands/export.d.ts.map +1 -0
  32. package/dist/commands/export.js +45 -0
  33. package/dist/commands/export.js.map +1 -0
  34. package/dist/commands/import.d.ts +13 -0
  35. package/dist/commands/import.d.ts.map +1 -0
  36. package/dist/commands/import.js +87 -0
  37. package/dist/commands/import.js.map +1 -0
  38. package/dist/commands/learn.d.ts +17 -0
  39. package/dist/commands/learn.d.ts.map +1 -0
  40. package/dist/commands/learn.js +193 -0
  41. package/dist/commands/learn.js.map +1 -0
  42. package/dist/commands/patterns.d.ts +13 -0
  43. package/dist/commands/patterns.d.ts.map +1 -0
  44. package/dist/commands/patterns.js +76 -0
  45. package/dist/commands/patterns.js.map +1 -0
  46. package/dist/commands/plugin.d.ts +26 -0
  47. package/dist/commands/plugin.d.ts.map +1 -0
  48. package/dist/commands/plugin.js +267 -0
  49. package/dist/commands/plugin.js.map +1 -0
  50. package/dist/commands/projects.d.ts +15 -0
  51. package/dist/commands/projects.d.ts.map +1 -0
  52. package/dist/commands/projects.js +122 -0
  53. package/dist/commands/projects.js.map +1 -0
  54. package/dist/commands/record.d.ts +32 -0
  55. package/dist/commands/record.d.ts.map +1 -0
  56. package/dist/commands/record.js +307 -0
  57. package/dist/commands/record.js.map +1 -0
  58. package/dist/commands/search.d.ts +16 -0
  59. package/dist/commands/search.d.ts.map +1 -0
  60. package/dist/commands/search.js +125 -0
  61. package/dist/commands/search.js.map +1 -0
  62. package/dist/commands/status.d.ts +8 -0
  63. package/dist/commands/status.d.ts.map +1 -0
  64. package/dist/commands/status.js +63 -0
  65. package/dist/commands/status.js.map +1 -0
  66. package/dist/commands/summarize.d.ts +17 -0
  67. package/dist/commands/summarize.d.ts.map +1 -0
  68. package/dist/commands/summarize.js +167 -0
  69. package/dist/commands/summarize.js.map +1 -0
  70. package/dist/commands/top.d.ts +14 -0
  71. package/dist/commands/top.d.ts.map +1 -0
  72. package/dist/commands/top.js +58 -0
  73. package/dist/commands/top.js.map +1 -0
  74. package/dist/commands/tune.d.ts +36 -0
  75. package/dist/commands/tune.d.ts.map +1 -0
  76. package/dist/commands/tune.js +354 -0
  77. package/dist/commands/tune.js.map +1 -0
  78. package/dist/formatters/playbook-formatter.d.ts +19 -0
  79. package/dist/formatters/playbook-formatter.d.ts.map +1 -0
  80. package/dist/formatters/playbook-formatter.js +56 -0
  81. package/dist/formatters/playbook-formatter.js.map +1 -0
  82. package/dist/formatters/search-formatter.d.ts +28 -0
  83. package/dist/formatters/search-formatter.d.ts.map +1 -0
  84. package/dist/formatters/search-formatter.js +48 -0
  85. package/dist/formatters/search-formatter.js.map +1 -0
  86. package/dist/formatters/status-formatter.d.ts +25 -0
  87. package/dist/formatters/status-formatter.d.ts.map +1 -0
  88. package/dist/formatters/status-formatter.js +46 -0
  89. package/dist/formatters/status-formatter.js.map +1 -0
  90. package/dist/services/config-loader.d.ts +8 -0
  91. package/dist/services/config-loader.d.ts.map +1 -0
  92. package/dist/services/config-loader.js +7 -0
  93. package/dist/services/config-loader.js.map +1 -0
  94. package/dist/services/initialization.d.ts +128 -0
  95. package/dist/services/initialization.d.ts.map +1 -0
  96. package/dist/services/initialization.js +874 -0
  97. package/dist/services/initialization.js.map +1 -0
  98. package/dist/services/language-detector.d.ts +63 -0
  99. package/dist/services/language-detector.d.ts.map +1 -0
  100. package/dist/services/language-detector.js +123 -0
  101. package/dist/services/language-detector.js.map +1 -0
  102. package/dist/services/logger.d.ts +97 -0
  103. package/dist/services/logger.d.ts.map +1 -0
  104. package/dist/services/logger.js +229 -0
  105. package/dist/services/logger.js.map +1 -0
  106. package/dist/services/plugin-loader.d.ts +84 -0
  107. package/dist/services/plugin-loader.d.ts.map +1 -0
  108. package/dist/services/plugin-loader.js +282 -0
  109. package/dist/services/plugin-loader.js.map +1 -0
  110. package/dist/services/recorder.d.ts +80 -0
  111. package/dist/services/recorder.d.ts.map +1 -0
  112. package/dist/services/recorder.js +267 -0
  113. package/dist/services/recorder.js.map +1 -0
  114. package/dist/services/server-client.d.ts +32 -0
  115. package/dist/services/server-client.d.ts.map +1 -0
  116. package/dist/services/server-client.js +68 -0
  117. package/dist/services/server-client.js.map +1 -0
  118. package/dist/services/session-storage.d.ts +20 -0
  119. package/dist/services/session-storage.d.ts.map +1 -0
  120. package/dist/services/session-storage.js +29 -0
  121. package/dist/services/session-storage.js.map +1 -0
  122. package/dist/types/config.d.ts +33 -0
  123. package/dist/types/config.d.ts.map +1 -0
  124. package/dist/types/config.js +63 -0
  125. package/dist/types/config.js.map +1 -0
  126. package/dist/types/pattern.d.ts +8 -0
  127. package/dist/types/pattern.d.ts.map +1 -0
  128. package/dist/types/pattern.js +7 -0
  129. package/dist/types/pattern.js.map +1 -0
  130. package/dist/types/plugin.d.ts +87 -0
  131. package/dist/types/plugin.d.ts.map +1 -0
  132. package/dist/types/plugin.js +5 -0
  133. package/dist/types/plugin.js.map +1 -0
  134. package/dist/types/recorder.d.ts +44 -0
  135. package/dist/types/recorder.d.ts.map +1 -0
  136. package/dist/types/recorder.js +5 -0
  137. package/dist/types/recorder.js.map +1 -0
  138. package/dist/utils/code-extractor.d.ts +8 -0
  139. package/dist/utils/code-extractor.d.ts.map +1 -0
  140. package/dist/utils/code-extractor.js +7 -0
  141. package/dist/utils/code-extractor.js.map +1 -0
  142. package/dist/utils/semver.d.ts +13 -0
  143. package/dist/utils/semver.d.ts.map +1 -0
  144. package/dist/utils/semver.js +14 -0
  145. package/dist/utils/semver.js.map +1 -0
  146. package/dist/utils/version-checker.d.ts +27 -0
  147. package/dist/utils/version-checker.d.ts.map +1 -0
  148. package/dist/utils/version-checker.js +141 -0
  149. package/dist/utils/version-checker.js.map +1 -0
  150. package/package.json +64 -0
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Session summarization command
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
5
+ import { getRecorder } from '../services/recorder.js';
6
+ import { globalOptions } from '../cli.js';
7
+ import { Logger } from '../services/logger.js';
8
+ import { createContext } from '../types/config.js';
9
+ import { ACEServerClient } from '../services/server-client.js';
10
+ import chalk from 'chalk';
11
+ /**
12
+ * Summarize a recorded session
13
+ */
14
+ export async function summarizeCommand(sessionIdOrFile, options = {}) {
15
+ const logger = new Logger(globalOptions);
16
+ try {
17
+ // Determine if input is a session ID, file path, or stdin
18
+ let sessionData;
19
+ let sessionId;
20
+ if (options.stdin) {
21
+ // Read from stdin
22
+ logger.debug('Loading session from stdin');
23
+ const stdinData = readFileSync(0, 'utf8'); // fd 0 is stdin
24
+ sessionData = JSON.parse(stdinData.trim());
25
+ sessionId = sessionData.metadata?.id || 'stdin';
26
+ }
27
+ else if (!sessionIdOrFile) {
28
+ throw new Error('Must provide either a session ID/file or use --stdin');
29
+ }
30
+ else if (existsSync(sessionIdOrFile)) {
31
+ // It's a file path
32
+ logger.debug(`Loading session from file: ${sessionIdOrFile}`);
33
+ const fileContent = readFileSync(sessionIdOrFile, 'utf8');
34
+ sessionData = JSON.parse(fileContent);
35
+ sessionId = sessionData.metadata?.id || 'unknown';
36
+ }
37
+ else {
38
+ // It's a session ID - load from recorder
39
+ logger.debug(`Loading session from recorder: ${sessionIdOrFile}`);
40
+ const recorder = getRecorder();
41
+ sessionData = recorder.getSession(sessionIdOrFile);
42
+ sessionId = sessionIdOrFile;
43
+ }
44
+ // Get config and create client
45
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
46
+ const client = new ACEServerClient(context, logger);
47
+ // Fetch server config for defaults
48
+ const serverConfig = await client.getConfig();
49
+ const runtimeSettings = serverConfig?.runtime_settings || {};
50
+ const effectiveStyle = runtimeSettings.summarizationStyle || 'short';
51
+ const effectiveMaxTokens = runtimeSettings.summarizationMaxTokens || 1000;
52
+ logger.debug(`Summarization settings: style=${effectiveStyle}, max_tokens=${effectiveMaxTokens}`);
53
+ // Show spinner
54
+ const spinner = logger.spinner('Analyzing session...');
55
+ // Send to server for summarization (server will use runtime settings)
56
+ const summary = await client.summarizeSession(sessionData);
57
+ spinner?.succeed();
58
+ // Format output based on requested format (CLI option > 'text' default)
59
+ const format = options.format || 'text';
60
+ if (logger.isJson() || format === 'json') {
61
+ // JSON output
62
+ const output = {
63
+ session_id: sessionId,
64
+ summary: summary.summary,
65
+ key_events: summary.key_events,
66
+ insights: summary.insights,
67
+ duration_ms: summary.duration_ms,
68
+ event_count: summary.event_count
69
+ };
70
+ if (options.output) {
71
+ writeFileSync(options.output, JSON.stringify(output, null, 2));
72
+ logger.success(`Summary saved to ${options.output}`);
73
+ }
74
+ else {
75
+ logger.output(output);
76
+ }
77
+ }
78
+ else if (format === 'markdown') {
79
+ // Markdown output
80
+ const markdown = formatSummaryAsMarkdown(sessionId, summary);
81
+ if (options.output) {
82
+ writeFileSync(options.output, markdown);
83
+ logger.success(`Summary saved to ${options.output}`);
84
+ }
85
+ else {
86
+ console.log(markdown);
87
+ }
88
+ }
89
+ else {
90
+ // Text output (default)
91
+ displaySummaryAsText(logger, sessionId, summary);
92
+ if (options.output) {
93
+ const markdown = formatSummaryAsMarkdown(sessionId, summary);
94
+ writeFileSync(options.output, markdown);
95
+ logger.success(`\nSummary saved to ${options.output}`);
96
+ }
97
+ }
98
+ }
99
+ catch (error) {
100
+ if (logger.isJson()) {
101
+ logger.output({
102
+ success: false,
103
+ error: error instanceof Error ? error.message : String(error)
104
+ });
105
+ }
106
+ else {
107
+ logger.error('Failed to summarize session', error instanceof Error ? error : String(error));
108
+ }
109
+ process.exit(1);
110
+ }
111
+ }
112
+ /**
113
+ * Display summary as formatted text
114
+ */
115
+ function displaySummaryAsText(logger, sessionId, summary) {
116
+ logger.info(chalk.bold(`\n📊 Session Summary: ${sessionId}\n`));
117
+ // Duration and event count
118
+ const durationSeconds = (summary.duration_ms / 1000).toFixed(1);
119
+ logger.info(chalk.dim(`Duration: ${durationSeconds}s | Events: ${summary.event_count}\n`));
120
+ // Summary
121
+ logger.info(chalk.bold('Summary:'));
122
+ logger.info(summary.summary);
123
+ logger.info('');
124
+ // Key events
125
+ if (summary.key_events && summary.key_events.length > 0) {
126
+ logger.info(chalk.bold('Key Events:'));
127
+ for (const event of summary.key_events) {
128
+ const timestamp = new Date(event.timestamp).toLocaleTimeString();
129
+ logger.info(chalk.dim(` [${timestamp}]`) + ` ${event.type}: ${event.description}`);
130
+ }
131
+ logger.info('');
132
+ }
133
+ // Insights
134
+ if (summary.insights && summary.insights.length > 0) {
135
+ logger.info(chalk.bold('Insights:'));
136
+ for (const insight of summary.insights) {
137
+ logger.info(chalk.cyan(` • ${insight}`));
138
+ }
139
+ logger.info('');
140
+ }
141
+ }
142
+ /**
143
+ * Format summary as markdown
144
+ */
145
+ function formatSummaryAsMarkdown(sessionId, summary) {
146
+ const durationSeconds = (summary.duration_ms / 1000).toFixed(1);
147
+ let markdown = `# Session Summary: ${sessionId}\n\n`;
148
+ markdown += `**Duration:** ${durationSeconds}s | **Events:** ${summary.event_count}\n\n`;
149
+ markdown += `## Summary\n\n${summary.summary}\n\n`;
150
+ if (summary.key_events && summary.key_events.length > 0) {
151
+ markdown += `## Key Events\n\n`;
152
+ for (const event of summary.key_events) {
153
+ const timestamp = new Date(event.timestamp).toLocaleTimeString();
154
+ markdown += `- **[${timestamp}]** ${event.type}: ${event.description}\n`;
155
+ }
156
+ markdown += '\n';
157
+ }
158
+ if (summary.insights && summary.insights.length > 0) {
159
+ markdown += `## Insights\n\n`;
160
+ for (const insight of summary.insights) {
161
+ markdown += `- ${insight}\n`;
162
+ }
163
+ markdown += '\n';
164
+ }
165
+ return markdown;
166
+ }
167
+ //# sourceMappingURL=summarize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../src/commands/summarize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Top patterns command
3
+ */
4
+ interface TopOptions {
5
+ section?: string;
6
+ limit?: number;
7
+ minHelpful?: number;
8
+ }
9
+ /**
10
+ * Show top-rated patterns
11
+ */
12
+ export declare function topCommand(options: TopOptions): Promise<void>;
13
+ export {};
14
+ //# sourceMappingURL=top.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top.d.ts","sourceRoot":"","sources":["../../src/commands/top.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,UAAU,UAAU;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,iBAmDnD"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Top patterns command
3
+ */
4
+ import { globalOptions } from '../cli.js';
5
+ import { createContext } from '../types/config.js';
6
+ import { ACEServerClient } from '../services/server-client.js';
7
+ import { formatSearchResults } from '../formatters/search-formatter.js';
8
+ import { Logger } from '../services/logger.js';
9
+ import chalk from 'chalk';
10
+ /**
11
+ * Show top-rated patterns
12
+ */
13
+ export async function topCommand(options) {
14
+ const logger = new Logger(globalOptions);
15
+ const spinner = logger.spinner('Fetching top patterns...');
16
+ try {
17
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
18
+ const client = new ACEServerClient(context, logger);
19
+ // Fetch server config for defaults
20
+ const serverConfig = await client.getConfig();
21
+ const runtimeSettings = serverConfig?.runtime_settings || {};
22
+ // NOTE: search_top_k is a top-level server config field (tune command), not in runtime_settings
23
+ const effectiveLimit = options.limit ?? serverConfig?.search_top_k ?? 10;
24
+ const effectiveMinHelpful = options.minHelpful ?? runtimeSettings.patternMinHelpful ?? 0;
25
+ logger.debug(`Top patterns: limit=${effectiveLimit}, min_helpful=${effectiveMinHelpful}`);
26
+ const patterns = await client.getTopPatterns({
27
+ section: options.section,
28
+ limit: effectiveLimit,
29
+ min_helpful: effectiveMinHelpful
30
+ });
31
+ spinner?.succeed(`Found ${patterns.length} top patterns`);
32
+ if (logger.isJson()) {
33
+ logger.output({ patterns });
34
+ }
35
+ else {
36
+ if (!patterns || patterns.length === 0) {
37
+ logger.info(chalk.yellow('\n⚠️ No patterns found\n'));
38
+ return;
39
+ }
40
+ logger.info(chalk.bold(`\n⭐ Top ${effectiveLimit} Patterns\n`));
41
+ formatSearchResults(patterns, {
42
+ showRank: true,
43
+ verbose: logger.isVerbose()
44
+ });
45
+ }
46
+ }
47
+ catch (error) {
48
+ spinner?.fail('Failed to fetch top patterns');
49
+ if (logger.isJson()) {
50
+ logger.error(error instanceof Error ? error.message : String(error));
51
+ }
52
+ else {
53
+ logger.error(chalk.red(`\nError: ${error instanceof Error ? error.message : String(error)}\n`));
54
+ }
55
+ process.exit(1);
56
+ }
57
+ }
58
+ //# sourceMappingURL=top.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top.js","sourceRoot":"","sources":["../../src/commands/top.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAmB;IAClD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAChG,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEpD,mCAAmC;QACnC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAC9C,MAAM,eAAe,GAAG,YAAY,EAAE,gBAAgB,IAAI,EAAE,CAAC;QAE7D,gGAAgG;QAChG,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,YAAY,IAAI,EAAE,CAAC;QACzE,MAAM,mBAAmB,GAAG,OAAO,CAAC,UAAU,IAAI,eAAe,CAAC,iBAAiB,IAAI,CAAC,CAAC;QAEzF,MAAM,CAAC,KAAK,CAAC,uBAAuB,cAAc,iBAAiB,mBAAmB,EAAE,CAAC,CAAC;QAE1F,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC;YAC3C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,cAAc;YACrB,WAAW,EAAE,mBAAmB;SACjC,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,CAAC,SAAS,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC;QAE1D,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,cAAc,aAAa,CAAC,CAAC,CAAC;YAEhE,mBAAmB,CAAC,QAAQ,EAAE;gBAC5B,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE;aAC5B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAE9C,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Tune command - Adjust ACE thresholds and settings
3
+ */
4
+ /**
5
+ * Tune command options - maps to actual server ConfigUpdateRequest fields
6
+ */
7
+ interface TuneOptions {
8
+ scope?: 'project';
9
+ dedupSimilarityThreshold?: number;
10
+ dedupEnabled?: boolean;
11
+ constitutionThreshold?: number;
12
+ pruningThreshold?: number;
13
+ maxPlaybookTokens?: number;
14
+ tokenBudgetEnforcement?: boolean;
15
+ maxBatchSize?: number;
16
+ autoLearningEnabled?: boolean;
17
+ reflectorEnabled?: boolean;
18
+ curatorEnabled?: boolean;
19
+ searchTopK?: number;
20
+ }
21
+ /**
22
+ * Tune command - Interactive or flags mode
23
+ */
24
+ export declare function tuneCommand(options?: TuneOptions): Promise<void>;
25
+ /**
26
+ * Show current effective configuration
27
+ */
28
+ export declare function tuneShowCommand(): Promise<void>;
29
+ /**
30
+ * Reset configuration to defaults
31
+ */
32
+ export declare function tuneResetCommand(options?: {
33
+ scope?: 'project';
34
+ }): Promise<void>;
35
+ export {};
36
+ //# sourceMappingURL=tune.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tune.d.ts","sourceRoot":"","sources":["../../src/commands/tune.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH;;GAEG;AACH,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,iBAa1D;AAoRD;;GAEG;AACH,wBAAsB,eAAe,kBAmDpC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAA;CAAO,iBA8BzE"}
@@ -0,0 +1,354 @@
1
+ /**
2
+ * Tune command - Adjust ACE thresholds and settings
3
+ */
4
+ import { createInterface } from 'readline';
5
+ import { globalOptions } from '../cli.js';
6
+ import { createContext } from '../types/config.js';
7
+ import { ACEServerClient } from '../services/server-client.js';
8
+ import { Logger } from '../services/logger.js';
9
+ import chalk from 'chalk';
10
+ /**
11
+ * Tune command - Interactive or flags mode
12
+ */
13
+ export async function tuneCommand(options = {}) {
14
+ const logger = new Logger(globalOptions);
15
+ // Check if any flags were provided (non-interactive mode)
16
+ const hasFlags = Object.keys(options).length > 1 || (Object.keys(options).length === 1 && !options.scope);
17
+ if (hasFlags) {
18
+ // Flags mode (automation-friendly)
19
+ return await tuneNonInteractive(options, logger);
20
+ }
21
+ else {
22
+ // Interactive mode
23
+ return await tuneInteractive(options, logger);
24
+ }
25
+ }
26
+ /**
27
+ * Non-interactive tune mode (flags)
28
+ */
29
+ async function tuneNonInteractive(options, logger) {
30
+ const spinner = logger.spinner('Updating configuration...');
31
+ try {
32
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
33
+ const client = new ACEServerClient(context, logger);
34
+ // Build settings object from flags using actual server field names
35
+ const settings = {};
36
+ if (options.dedupSimilarityThreshold !== undefined)
37
+ settings.dedup_similarity_threshold = options.dedupSimilarityThreshold;
38
+ if (options.dedupEnabled !== undefined)
39
+ settings.dedup_enabled = options.dedupEnabled;
40
+ if (options.constitutionThreshold !== undefined)
41
+ settings.constitution_threshold = options.constitutionThreshold;
42
+ if (options.pruningThreshold !== undefined)
43
+ settings.pruning_threshold = options.pruningThreshold;
44
+ if (options.maxPlaybookTokens !== undefined)
45
+ settings.max_playbook_tokens = options.maxPlaybookTokens;
46
+ if (options.tokenBudgetEnforcement !== undefined)
47
+ settings.token_budget_enforcement = options.tokenBudgetEnforcement;
48
+ if (options.maxBatchSize !== undefined)
49
+ settings.max_batch_size = options.maxBatchSize;
50
+ if (options.autoLearningEnabled !== undefined)
51
+ settings.auto_learning_enabled = options.autoLearningEnabled;
52
+ if (options.reflectorEnabled !== undefined)
53
+ settings.reflector_enabled = options.reflectorEnabled;
54
+ if (options.curatorEnabled !== undefined)
55
+ settings.curator_enabled = options.curatorEnabled;
56
+ if (options.searchTopK !== undefined)
57
+ settings.search_top_k = options.searchTopK;
58
+ if (Object.keys(settings).length === 0) {
59
+ throw new Error('No settings provided. Use --dedup-threshold, --constitution-threshold, etc.');
60
+ }
61
+ const scope = options.scope || 'project';
62
+ const result = await client.updateConfig(settings, scope);
63
+ spinner?.succeed('Configuration updated');
64
+ if (logger.isJson()) {
65
+ logger.output({
66
+ success: true,
67
+ scope,
68
+ updated: settings,
69
+ config: result
70
+ });
71
+ }
72
+ else {
73
+ logger.info(chalk.green('\n✅ Configuration updated successfully\n'));
74
+ logger.info(chalk.bold('Updated Settings:'));
75
+ for (const [key, value] of Object.entries(settings)) {
76
+ logger.info(` ${chalk.cyan(key)}: ${value}`);
77
+ }
78
+ logger.info('');
79
+ }
80
+ }
81
+ catch (error) {
82
+ spinner?.fail('Failed to update configuration');
83
+ if (logger.isJson()) {
84
+ logger.error(error instanceof Error ? error.message : String(error));
85
+ }
86
+ else {
87
+ logger.error(chalk.red(`\nError: ${error instanceof Error ? error.message : String(error)}\n`));
88
+ }
89
+ process.exit(1);
90
+ }
91
+ }
92
+ /**
93
+ * Interactive tune mode (wizard)
94
+ */
95
+ async function tuneInteractive(_options, logger) {
96
+ logger.info(chalk.bold('\n🎛️ ACE Configuration Tuner\n'));
97
+ const rl = createInterface({
98
+ input: process.stdin,
99
+ output: process.stdout
100
+ });
101
+ const question = (prompt) => {
102
+ return new Promise((resolve) => rl.question(prompt, resolve));
103
+ };
104
+ try {
105
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
106
+ const client = new ACEServerClient(context, logger);
107
+ // Fetch current settings
108
+ logger.info(chalk.dim('Fetching current configuration...'));
109
+ const serverConfig = await client.getConfig();
110
+ const current = serverConfig || {};
111
+ logger.info(chalk.green('✓ Current configuration loaded\n'));
112
+ // Display current effective values (actual server fields)
113
+ logger.info(chalk.bold('Current Settings:'));
114
+ logger.info(chalk.dim('────────────────────────────────────────────────────────────────'));
115
+ logger.info(` Constitution Threshold: ${chalk.cyan(current.constitution_threshold ?? 0.7)} (retrieval similarity)`);
116
+ logger.info(` Search Top K: ${chalk.cyan(current.search_top_k ?? 10)} (max results)`);
117
+ logger.info(` Dedup Similarity Threshold: ${chalk.cyan(current.dedup_similarity_threshold ?? 0.85)}`);
118
+ logger.info(` Dedup Enabled: ${chalk.cyan(current.dedup_enabled ?? true)}`);
119
+ logger.info(` Pruning Threshold: ${chalk.cyan(current.pruning_threshold ?? 0.3)}`);
120
+ logger.info(` Max Playbook Tokens: ${chalk.cyan(current.max_playbook_tokens ?? 'unlimited')}`);
121
+ logger.info(` Token Budget Enforcement: ${chalk.cyan(current.token_budget_enforcement ?? false)}`);
122
+ logger.info(` Max Batch Size: ${chalk.cyan(current.max_batch_size ?? 50)}`);
123
+ logger.info(` Auto Learning Enabled: ${chalk.cyan(current.auto_learning_enabled ?? true)}`);
124
+ logger.info(` Reflector Enabled: ${chalk.cyan(current.reflector_enabled ?? true)}`);
125
+ logger.info(` Curator Enabled: ${chalk.cyan(current.curator_enabled ?? true)}`);
126
+ logger.info(chalk.dim('────────────────────────────────────────────────────────────────\n'));
127
+ // Ask which setting to change
128
+ logger.info(chalk.bold('Which setting would you like to change?\n'));
129
+ logger.info(' 1. Constitution Threshold (retrieval similarity, 0.0-1.0)');
130
+ logger.info(' 2. Search Top K (max search results, 1-100)');
131
+ logger.info(' 3. Dedup Similarity Threshold (0.0-1.0)');
132
+ logger.info(' 4. Pruning Threshold (min confidence to keep pattern)');
133
+ logger.info(' 5. Max Playbook Tokens (token budget limit)');
134
+ logger.info(' 6. Auto Learning Enabled (toggle automatic learning)');
135
+ logger.info(' 7. Max Batch Size (patterns per batch, 1-100)');
136
+ logger.info(' 8. Dedup Enabled (toggle deduplication)');
137
+ logger.info(' 9. Token Budget Enforcement (enforce token limits)');
138
+ logger.info(' A. Reflector/Curator Enabled (toggle agents)');
139
+ logger.info(' R. Reset to defaults');
140
+ logger.info(' 0. Cancel\n');
141
+ const choice = await question(chalk.cyan('Enter choice: '));
142
+ const settings = {};
143
+ switch (choice.trim().toLowerCase()) {
144
+ case '1': {
145
+ const value = await question(chalk.cyan(`Enter new constitution threshold (0.0-1.0, current: ${current.constitution_threshold ?? 0.7}): `));
146
+ const threshold = parseFloat(value);
147
+ if (isNaN(threshold) || threshold < 0 || threshold > 1) {
148
+ throw new Error('Invalid threshold. Must be between 0.0 and 1.0');
149
+ }
150
+ settings.constitution_threshold = threshold;
151
+ break;
152
+ }
153
+ case '2': {
154
+ const value = await question(chalk.cyan(`Enter new search top K (1-100, current: ${current.search_top_k ?? 10}): `));
155
+ const topK = parseInt(value, 10);
156
+ if (isNaN(topK) || topK < 1 || topK > 100) {
157
+ throw new Error('Invalid top K. Must be between 1 and 100');
158
+ }
159
+ settings.search_top_k = topK;
160
+ break;
161
+ }
162
+ case '3': {
163
+ const value = await question(chalk.cyan(`Enter new dedup similarity threshold (0.0-1.0, current: ${current.dedup_similarity_threshold ?? 0.85}): `));
164
+ const threshold = parseFloat(value);
165
+ if (isNaN(threshold) || threshold < 0 || threshold > 1) {
166
+ throw new Error('Invalid threshold. Must be between 0.0 and 1.0');
167
+ }
168
+ settings.dedup_similarity_threshold = threshold;
169
+ break;
170
+ }
171
+ case '4': {
172
+ const value = await question(chalk.cyan(`Enter new pruning threshold (0.0-1.0, current: ${current.pruning_threshold ?? 0.3}): `));
173
+ const threshold = parseFloat(value);
174
+ if (isNaN(threshold) || threshold < 0 || threshold > 1) {
175
+ throw new Error('Invalid threshold. Must be between 0.0 and 1.0');
176
+ }
177
+ settings.pruning_threshold = threshold;
178
+ break;
179
+ }
180
+ case '5': {
181
+ const value = await question(chalk.cyan(`Enter max playbook tokens (number or 'null' for unlimited, current: ${current.max_playbook_tokens ?? 'null'}): `));
182
+ if (value.trim().toLowerCase() === 'null') {
183
+ settings.max_playbook_tokens = null;
184
+ }
185
+ else {
186
+ const tokens = parseInt(value, 10);
187
+ if (isNaN(tokens) || tokens < 1) {
188
+ throw new Error('Invalid token count. Must be >= 1 or "null"');
189
+ }
190
+ settings.max_playbook_tokens = tokens;
191
+ }
192
+ break;
193
+ }
194
+ case '6': {
195
+ const value = await question(chalk.cyan(`Enable auto learning? (yes/no, current: ${current.auto_learning_enabled ?? true}): `));
196
+ settings.auto_learning_enabled = value.trim().toLowerCase() === 'yes';
197
+ break;
198
+ }
199
+ case '7': {
200
+ const value = await question(chalk.cyan(`Enter max batch size (1-100, current: ${current.max_batch_size ?? 50}): `));
201
+ const size = parseInt(value, 10);
202
+ if (isNaN(size) || size < 1 || size > 100) {
203
+ throw new Error('Invalid batch size. Must be between 1 and 100');
204
+ }
205
+ settings.max_batch_size = size;
206
+ break;
207
+ }
208
+ case '8': {
209
+ const value = await question(chalk.cyan(`Enable deduplication? (yes/no, current: ${current.dedup_enabled ?? true}): `));
210
+ settings.dedup_enabled = value.trim().toLowerCase() === 'yes';
211
+ break;
212
+ }
213
+ case '9': {
214
+ const value = await question(chalk.cyan(`Enable token budget enforcement? (yes/no, current: ${current.token_budget_enforcement ?? false}): `));
215
+ settings.token_budget_enforcement = value.trim().toLowerCase() === 'yes';
216
+ break;
217
+ }
218
+ case 'a': {
219
+ logger.info(chalk.bold('\nAgent Settings:\n'));
220
+ const reflector = await question(chalk.cyan(`Enable Reflector? (yes/no, current: ${current.reflector_enabled ?? true}): `));
221
+ const curator = await question(chalk.cyan(`Enable Curator? (yes/no, current: ${current.curator_enabled ?? true}): `));
222
+ settings.reflector_enabled = reflector.trim().toLowerCase() === 'yes';
223
+ settings.curator_enabled = curator.trim().toLowerCase() === 'yes';
224
+ break;
225
+ }
226
+ case 'r': {
227
+ const confirm = await question(chalk.yellow('\n⚠️ Reset ALL settings to defaults? (yes/no): '));
228
+ if (confirm.trim().toLowerCase() !== 'yes') {
229
+ logger.info(chalk.dim('\nCancelled'));
230
+ rl.close();
231
+ return;
232
+ }
233
+ logger.info(chalk.dim('\nResetting configuration...'));
234
+ await client.resetConfig('project');
235
+ rl.close();
236
+ logger.info(chalk.green('\n✅ Configuration reset to defaults\n'));
237
+ return;
238
+ }
239
+ case '0':
240
+ logger.info(chalk.dim('\nCancelled'));
241
+ rl.close();
242
+ return;
243
+ default:
244
+ throw new Error('Invalid choice');
245
+ }
246
+ rl.close();
247
+ if (Object.keys(settings).length === 0) {
248
+ logger.info(chalk.dim('\nNo changes made'));
249
+ return;
250
+ }
251
+ // Confirm and save
252
+ logger.info(chalk.dim('\nSaving configuration...'));
253
+ await client.updateConfig(settings, 'project');
254
+ logger.info(chalk.green('\n✅ Configuration updated successfully\n'));
255
+ logger.info(chalk.bold('Updated Settings:'));
256
+ for (const [key, value] of Object.entries(settings)) {
257
+ logger.info(` ${chalk.cyan(key)}: ${value}`);
258
+ }
259
+ logger.info('');
260
+ }
261
+ catch (error) {
262
+ rl.close();
263
+ if (logger.isJson()) {
264
+ logger.error(error instanceof Error ? error.message : String(error));
265
+ }
266
+ else {
267
+ logger.error(chalk.red(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}\n`));
268
+ }
269
+ process.exit(1);
270
+ }
271
+ }
272
+ /**
273
+ * Show current effective configuration
274
+ */
275
+ export async function tuneShowCommand() {
276
+ const logger = new Logger(globalOptions);
277
+ try {
278
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
279
+ const client = new ACEServerClient(context, logger);
280
+ const serverConfig = await client.getConfig();
281
+ const config = serverConfig || {};
282
+ if (logger.isJson()) {
283
+ logger.output({
284
+ project_id: context.projectId,
285
+ org_id: context.orgId,
286
+ config: config
287
+ });
288
+ }
289
+ else {
290
+ logger.info(chalk.bold('\n🎛️ ACE Configuration\n'));
291
+ logger.info(chalk.dim(`Project: ${context.projectId}`));
292
+ logger.info(chalk.dim(`Organization: ${context.orgId}\n`));
293
+ logger.info(chalk.bold('Search/Retrieval:'));
294
+ logger.info(` Constitution Threshold: ${chalk.cyan(config.constitution_threshold ?? 0.7)} (similarity)`);
295
+ logger.info(` Search Top K: ${chalk.cyan(config.search_top_k ?? 10)} (max results)`);
296
+ logger.info(chalk.bold('\nPattern Quality:'));
297
+ logger.info(` Dedup Similarity: ${chalk.cyan(config.dedup_similarity_threshold ?? 0.85)}`);
298
+ logger.info(` Pruning Threshold: ${chalk.cyan(config.pruning_threshold ?? 0.3)}`);
299
+ logger.info(chalk.bold('\nToken Management:'));
300
+ logger.info(` Max Playbook Tokens: ${chalk.cyan(config.max_playbook_tokens ?? 'unlimited')}`);
301
+ logger.info(` Budget Enforcement: ${chalk.cyan(config.token_budget_enforcement ?? false)}`);
302
+ logger.info(chalk.bold('\nProcessing:'));
303
+ logger.info(` Dedup Enabled: ${chalk.cyan(config.dedup_enabled ?? true)}`);
304
+ logger.info(` Max Batch Size: ${chalk.cyan(config.max_batch_size ?? 50)}`);
305
+ logger.info(chalk.bold('\nACE Agents:'));
306
+ logger.info(` Auto Learning: ${chalk.cyan(config.auto_learning_enabled ?? true)}`);
307
+ logger.info(` Reflector: ${chalk.cyan(config.reflector_enabled ?? true)}`);
308
+ logger.info(` Curator: ${chalk.cyan(config.curator_enabled ?? true)}`);
309
+ logger.info('');
310
+ }
311
+ }
312
+ catch (error) {
313
+ if (logger.isJson()) {
314
+ logger.error(error instanceof Error ? error.message : String(error));
315
+ }
316
+ else {
317
+ logger.error(chalk.red(`\nError: ${error instanceof Error ? error.message : String(error)}\n`));
318
+ }
319
+ process.exit(1);
320
+ }
321
+ }
322
+ /**
323
+ * Reset configuration to defaults
324
+ */
325
+ export async function tuneResetCommand(options = {}) {
326
+ const logger = new Logger(globalOptions);
327
+ const spinner = logger.spinner('Resetting configuration...');
328
+ try {
329
+ const context = await createContext({ org: globalOptions.org, project: globalOptions.project });
330
+ const client = new ACEServerClient(context, logger);
331
+ const scope = options.scope || 'project';
332
+ const result = await client.resetConfig(scope);
333
+ spinner?.succeed('Configuration reset');
334
+ if (logger.isJson()) {
335
+ logger.output(result);
336
+ }
337
+ else {
338
+ logger.info(chalk.green('\n✅ Configuration reset to defaults\n'));
339
+ logger.info(chalk.dim(`Scope: ${scope}`));
340
+ logger.info(chalk.dim('Run "ce-ace tune show" to see current settings\n'));
341
+ }
342
+ }
343
+ catch (error) {
344
+ spinner?.fail('Failed to reset configuration');
345
+ if (logger.isJson()) {
346
+ logger.error(error instanceof Error ? error.message : String(error));
347
+ }
348
+ else {
349
+ logger.error(chalk.red(`\nError: ${error instanceof Error ? error.message : String(error)}\n`));
350
+ }
351
+ process.exit(1);
352
+ }
353
+ }
354
+ //# sourceMappingURL=tune.js.map