snow-flow 4.0.3 → 4.1.1

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 (39) hide show
  1. package/README.md +15 -40
  2. package/dist/cli.js +0 -81
  3. package/dist/dynamic-version.js +1 -1
  4. package/dist/index.js +3 -1
  5. package/dist/intelligence/performance-recommendations-engine.js +1 -0
  6. package/dist/mcp/servicenow-local-development-mcp.d.ts +0 -3
  7. package/dist/mcp/servicenow-local-development-mcp.js +7 -204
  8. package/dist/memory/snow-flow-memory-patterns.d.ts +29 -30
  9. package/dist/memory/snow-flow-memory-patterns.js +26 -37
  10. package/dist/snow-flow-system.js +1 -0
  11. package/dist/testing/integration-test-suite.js +1 -0
  12. package/dist/utils/artifact-local-sync.js +0 -17
  13. package/dist/utils/artifact-sync/artifact-registry.js +10 -10
  14. package/dist/utils/smart-field-fetcher.js +4 -6
  15. package/package.json +2 -2
  16. package/dist/agent/interactive.d.ts +0 -11
  17. package/dist/agent/interactive.js +0 -190
  18. package/dist/agent/session.d.ts +0 -12
  19. package/dist/agent/session.js +0 -106
  20. package/dist/cli/auth.d.ts +0 -3
  21. package/dist/cli/auth.js +0 -59
  22. package/dist/cli/session.d.ts +0 -3
  23. package/dist/cli/session.js +0 -46
  24. package/dist/llm/keys.d.ts +0 -5
  25. package/dist/llm/keys.js +0 -29
  26. package/dist/llm/providers.d.ts +0 -11
  27. package/dist/llm/providers.js +0 -77
  28. package/dist/mcp/bridge.d.ts +0 -10
  29. package/dist/mcp/bridge.js +0 -31
  30. package/dist/mcp/shared/mcp-types.d.ts +0 -37
  31. package/dist/mcp/shared/mcp-types.js +0 -7
  32. package/dist/memory/hierarchical-memory-system.d.ts +0 -32
  33. package/dist/memory/hierarchical-memory-system.js +0 -60
  34. package/dist/memory/memory-system.d.ts +0 -25
  35. package/dist/memory/memory-system.js +0 -36
  36. package/dist/session/store.d.ts +0 -47
  37. package/dist/session/store.js +0 -74
  38. package/dist/utils/chunking-manager.d.ts +0 -39
  39. package/dist/utils/chunking-manager.js +0 -142
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.IntegrationTestSuite = void 0;
11
11
  const logger_js_1 = require("../utils/logger.js");
12
12
  const servicenow_client_js_1 = require("../utils/servicenow-client.js");
13
+ const memory_system_js_1 = require("../memory/memory-system.js");
13
14
  class IntegrationTestSuite {
14
15
  constructor() {
15
16
  // Flow-related systems removed in v1.4.0
@@ -47,7 +47,6 @@ const fs = __importStar(require("fs"));
47
47
  const path = __importStar(require("path"));
48
48
  const smart_field_fetcher_js_1 = require("./smart-field-fetcher.js");
49
49
  const mcp_timeout_config_js_1 = require("./mcp-timeout-config.js");
50
- const chunking_manager_js_1 = require("./chunking-manager.js");
51
50
  const artifact_registry_1 = require("./artifact-sync/artifact-registry");
52
51
  class ArtifactLocalSync {
53
52
  constructor(client, customBaseDir) {
@@ -286,22 +285,6 @@ class ArtifactLocalSync {
286
285
  }
287
286
  // Map back to ServiceNow field
288
287
  if (file.field && file.field !== 'documentation' && file.field !== 'metadata') {
289
- // Check if field needs chunking (large server scripts)
290
- if (chunking_manager_js_1.ChunkingManager.needsChunking(processedContent)) {
291
- console.log(` ⚠️ Large field detected: ${file.field} (${processedContent.length} chars)`);
292
- // Attempt chunked update
293
- const chunkResult = await chunking_manager_js_1.ChunkingManager.attemptChunkedUpdate(this.client, config.tableName, sys_id, file.field, processedContent);
294
- if (!chunkResult.success) {
295
- // Add to validation results as a manual instruction
296
- validationResults.push({
297
- valid: false,
298
- errors: [],
299
- warnings: [`Large ${file.field} requires manual update`],
300
- hints: [chunkResult.message]
301
- });
302
- continue; // Skip adding to updates
303
- }
304
- }
305
288
  updates[file.field] = processedContent;
306
289
  console.log(` 📝 Changed: ${file.filename} (${file.field})`);
307
290
  // Validate ES5 if required
@@ -33,7 +33,7 @@ exports.ARTIFACT_REGISTRY = {
33
33
  fileExtension: 'html',
34
34
  description: 'HTML template with Angular bindings',
35
35
  wrapperHeader: '<!-- ServiceNow Widget Template: {name} -->\n<!-- Angular bindings: {{data.x}}, ng-click="method()" -->\n\n',
36
- maxTokens: 50000,
36
+ maxTokens: 20000,
37
37
  isRequired: true
38
38
  },
39
39
  {
@@ -43,7 +43,7 @@ exports.ARTIFACT_REGISTRY = {
43
43
  description: 'Server-side script (ES5 ONLY)',
44
44
  wrapperHeader: '/**\n * Server Script for Widget: {name}\n * ES5 ONLY - No arrow functions, const/let, template literals\n * Available: data, input, options, gs, $sp\n */\n\n(function() {\n',
45
45
  wrapperFooter: '\n})();',
46
- maxTokens: 50000,
46
+ maxTokens: 20000,
47
47
  isRequired: false,
48
48
  validateES5: true
49
49
  },
@@ -54,7 +54,7 @@ exports.ARTIFACT_REGISTRY = {
54
54
  description: 'Client-side AngularJS controller',
55
55
  wrapperHeader: '/**\n * Client Controller for Widget: {name}\n * AngularJS 1.x\n * Available: c (this), c.data, c.server, $scope\n */\n\nfunction(',
56
56
  wrapperFooter: ')',
57
- maxTokens: 50000,
57
+ maxTokens: 20000,
58
58
  isRequired: false
59
59
  },
60
60
  {
@@ -63,7 +63,7 @@ exports.ARTIFACT_REGISTRY = {
63
63
  fileExtension: 'css',
64
64
  description: 'Widget-specific CSS styles',
65
65
  wrapperHeader: '/* Styles for Widget: {name} */\n/* Prefix classes to avoid conflicts */\n\n',
66
- maxTokens: 50000,
66
+ maxTokens: 20000,
67
67
  isRequired: false
68
68
  },
69
69
  {
@@ -243,7 +243,7 @@ exports.ARTIFACT_REGISTRY = {
243
243
  description: 'Business rule script',
244
244
  wrapperHeader: '/**\n * Business Rule: {name}\n * Table: {collection}\n * When: {when}\n * Order: {order}\n * Available: current, previous, gs, g_scratchpad\n */\n\n(function executeRule(current, previous /*null when async*/) {\n',
245
245
  wrapperFooter: '\n})(current, previous);',
246
- maxTokens: 50000,
246
+ maxTokens: 20000,
247
247
  isRequired: true,
248
248
  validateES5: true
249
249
  },
@@ -281,7 +281,7 @@ exports.ARTIFACT_REGISTRY = {
281
281
  localFileName: '{name}.client',
282
282
  fileExtension: 'js',
283
283
  description: 'Client-side JavaScript',
284
- maxTokens: 50000,
284
+ maxTokens: 20000,
285
285
  isRequired: false
286
286
  },
287
287
  {
@@ -289,7 +289,7 @@ exports.ARTIFACT_REGISTRY = {
289
289
  localFileName: '{name}.server',
290
290
  fileExtension: 'js',
291
291
  description: 'Server-side processing script (ES5)',
292
- maxTokens: 50000,
292
+ maxTokens: 20000,
293
293
  isRequired: false,
294
294
  validateES5: true
295
295
  }
@@ -310,7 +310,7 @@ exports.ARTIFACT_REGISTRY = {
310
310
  fileExtension: 'js',
311
311
  description: 'Client-side form script',
312
312
  wrapperHeader: '/**\n * Client Script: {name}\n * Table: {table}\n * Type: {type}\n * Available: g_form, g_user, g_list\n */\n\n',
313
- maxTokens: 50000,
313
+ maxTokens: 20000,
314
314
  isRequired: true
315
315
  }
316
316
  ]
@@ -375,7 +375,7 @@ exports.ARTIFACT_REGISTRY = {
375
375
  localFileName: '{name}',
376
376
  fileExtension: 'js',
377
377
  description: 'Transform map script',
378
- maxTokens: 50000,
378
+ maxTokens: 20000,
379
379
  isRequired: false,
380
380
  validateES5: true
381
381
  }
@@ -396,7 +396,7 @@ exports.ARTIFACT_REGISTRY = {
396
396
  fileExtension: 'js',
397
397
  description: 'Scheduled job script (ES5)',
398
398
  wrapperHeader: '/**\n * Scheduled Job: {name}\n * Run as: {run_as}\n * Time zone: {time_zone}\n */\n\n',
399
- maxTokens: 50000,
399
+ maxTokens: 20000,
400
400
  isRequired: true,
401
401
  validateES5: true
402
402
  }
@@ -130,8 +130,8 @@ class SmartFieldFetcher {
130
130
  description: group.description,
131
131
  fields: group.fields
132
132
  };
133
- // FIX: getRecord returns direct object, not response.result[0]
134
- Object.assign(results, response);
133
+ // Add to flat structure for easy access
134
+ Object.assign(results, response.result[0]);
135
135
  }
136
136
  }
137
137
  catch (error) {
@@ -232,9 +232,8 @@ class SmartFieldFetcher {
232
232
  // Try using getRecord instead of searchRecords with short timeout
233
233
  const directResponse = await (0, mcp_timeout_config_js_1.withMCPTimeout)(this.client.getRecord('sp_widget', sys_id), 5000, // 5 second timeout for direct fetch
234
234
  `Direct widget fetch ${sys_id}`);
235
- if (directResponse) {
236
- // FIX: getRecord returns direct object, not nested structure
237
- const directData = directResponse;
235
+ if (directResponse && directResponse.success && directResponse.data && directResponse.data.result) {
236
+ const directData = directResponse.data.result;
238
237
  // Merge any new data we got
239
238
  Object.assign(results, directData);
240
239
  console.log(`📊 Direct API retrieved:`);
@@ -293,7 +292,6 @@ class SmartFieldFetcher {
293
292
  console.log(` 📄 Fetching field: ${field}`);
294
293
  const response = await this.client.getRecord(table, sys_id);
295
294
  if (response) {
296
- // FIX: getRecord returns direct object
297
295
  result.data[field] = response[field];
298
296
  result._field_status[field] = 'success';
299
297
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "4.0.3",
4
- "description": "KNOWLEDGE BASE VERIFICATION - v3.6.25 adds critical validation to snow_create_knowledge_article. Now throws error when non-existent knowledge base is specified, preventing orphaned articles. Includes helpful suggestions to create or discover valid knowledge bases.",
3
+ "version": "4.1.1",
4
+ "description": "ENTERPRISE SCALE - v4.1.0 removes ALL artificial limits! Built on stable v3.6.25 with enterprise-grade support for massive widgets (5MB+ scripts), 200k token fields, and 100k record queries.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
7
7
  "bin": {
@@ -1,11 +0,0 @@
1
- import type { SnowFlowConfig } from '../config/llm-config-loader';
2
- import type { ProviderOptions } from '../llm/providers';
3
- export interface InteractiveOptions extends ProviderOptions {
4
- system?: string;
5
- mcp: SnowFlowConfig['mcp'];
6
- maxSteps?: number;
7
- showReasoning?: boolean;
8
- resumeId?: string;
9
- }
10
- export declare function runInteractive(opts: InteractiveOptions): Promise<void>;
11
- //# sourceMappingURL=interactive.d.ts.map
@@ -1,190 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.runInteractive = runInteractive;
7
- const bridge_1 = require("../mcp/bridge");
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const boxen_1 = __importDefault(require("boxen"));
10
- const node_readline_1 = __importDefault(require("node:readline"));
11
- const store_js_1 = require("../session/store.js");
12
- const ora_1 = __importDefault(require("ora"));
13
- async function runInteractive(opts) {
14
- const { provider, model, baseURL, apiKeyEnv, system, mcp, maxSteps = 40, showReasoning = true, resumeId } = opts;
15
- // Resolve model
16
- // eslint-disable-next-line @typescript-eslint/no-var-requires
17
- const prov = require('../llm/providers.js');
18
- const llm = prov.getModel({ provider, model, baseURL, apiKeyEnv });
19
- const sessionId = resumeId || (0, store_js_1.createSessionId)();
20
- (0, store_js_1.startSession)({
21
- id: sessionId,
22
- startedAt: new Date().toISOString(),
23
- objective: '(interactive)',
24
- provider: { id: String(provider), model: String(model), baseURL },
25
- mcp: { cmd: mcp.cmd, args: mcp.args },
26
- });
27
- process.stdout.write(chalk_1.default.bold(`\nSnow-Flow Interactive (${provider}:${model})`) + "\n");
28
- process.stdout.write(chalk_1.default.gray('Tips: ESC ESC = vorige assistant-antwoord | /quit om te stoppen') + "\n\n");
29
- // Load tools once with spinner
30
- const spinner = (0, ora_1.default)('MCP-tools laden...').start();
31
- const { tools, close } = await (0, bridge_1.loadMCPTools)(mcp).finally(() => spinner.stop());
32
- const messages = [];
33
- if (system)
34
- messages.push({ role: 'system', content: system });
35
- // Preload previous messages if resuming
36
- if (resumeId) {
37
- try {
38
- const { readSession } = require('../session/store.js');
39
- const rec = readSession(resumeId);
40
- if (rec?.messages?.length) {
41
- const recent = rec.messages.filter((m) => m.role === 'user' || m.role === 'assistant').slice(-20);
42
- for (const m of recent)
43
- messages.push({ role: m.role, content: m.content });
44
- }
45
- }
46
- catch { }
47
- }
48
- // Key handling for ESC ESC
49
- node_readline_1.default.emitKeypressEvents(process.stdin);
50
- if (process.stdin.isTTY)
51
- process.stdin.setRawMode(true);
52
- let lastEsc = 0;
53
- let lastAssistant = null;
54
- let showTools = true;
55
- const onKeypress = (_str, key) => {
56
- if (!key)
57
- return;
58
- if (key.name === 'escape') {
59
- const now = Date.now();
60
- if (now - lastEsc < 500) {
61
- // double ESC
62
- if (lastAssistant) {
63
- const box = (0, boxen_1.default)(lastAssistant.slice(0, 1200) + (lastAssistant.length > 1200 ? '…' : ''), { padding: 1, borderColor: 'yellow', title: 'Vorige assistant', titleAlignment: 'center' });
64
- process.stdout.write('\n' + box + '\n');
65
- }
66
- else {
67
- process.stdout.write(chalk_1.default.gray('\nGeen vorige assistant-respons beschikbaar.') + '\n');
68
- }
69
- }
70
- lastEsc = now;
71
- }
72
- if (key.name === 't') {
73
- showTools = !showTools;
74
- process.stdout.write('\n' + (showTools ? chalk_1.default.gray('Tool events: ON') : chalk_1.default.gray('Tool events: OFF')) + '\n');
75
- }
76
- if (key.name === 'h') {
77
- const last = messages.slice(-6);
78
- const text = last.map(m => `${m.role}> ${m.content}`).join('\n');
79
- const panel = (0, boxen_1.default)(text, { padding: 1, borderColor: 'blue', title: 'History (tail)', titleAlignment: 'center' });
80
- process.stdout.write('\n' + panel + '\n');
81
- }
82
- if (key.name === 's') {
83
- const fs = require('fs');
84
- const out = (lastAssistant || '').toString();
85
- const outPath = `${process.env.HOME || ''}/.snow-flow/sessions/${sessionId}.txt`;
86
- try {
87
- fs.writeFileSync(outPath, out, 'utf8');
88
- }
89
- catch { }
90
- process.stdout.write(chalk_1.default.gray(`Saved assistant output to ${outPath}`) + '\n');
91
- }
92
- };
93
- process.stdin.on('keypress', onKeypress);
94
- // eslint-disable-next-line @typescript-eslint/no-var-requires
95
- const { streamText } = require('ai');
96
- const rl = node_readline_1.default.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
97
- const ask = (q) => new Promise(resolve => rl.question(q, resolve));
98
- try {
99
- const onSignal = async () => {
100
- try {
101
- await close();
102
- }
103
- catch { }
104
- (0, store_js_1.endSession)(sessionId);
105
- process.stdout.write('\n' + chalk_1.default.gray('Session ended.') + '\n');
106
- process.exit(0);
107
- };
108
- process.on('SIGINT', onSignal);
109
- process.on('SIGTERM', onSignal);
110
- // loop
111
- while (true) {
112
- const input = await ask(chalk_1.default.cyan('You: '));
113
- if (!input)
114
- continue;
115
- if (input.trim() === '/quit')
116
- break;
117
- const long = input.length > 1200;
118
- if (long) {
119
- const preview = input.slice(0, 1200) + '…';
120
- const box = (0, boxen_1.default)(preview, { padding: 1, borderColor: 'green', title: 'Preview (truncated)', titleAlignment: 'center' });
121
- process.stdout.write('\n' + box + '\n');
122
- const confirm = await ask(chalk_1.default.gray('Doorgaan met verzenden? [y/N] '));
123
- if (!/^y(es)?$/i.test(confirm.trim()))
124
- continue;
125
- }
126
- messages.push({ role: 'user', content: input });
127
- (0, store_js_1.appendMessage)(sessionId, { role: 'user', content: input, timestamp: new Date().toISOString() });
128
- const result = await streamText({
129
- model: llm,
130
- system,
131
- messages,
132
- tools,
133
- maxSteps,
134
- });
135
- let buffer = '';
136
- let inReasoning = false;
137
- const write = (s) => {
138
- buffer += s;
139
- const out = inReasoning && showReasoning ? chalk_1.default.yellow.dim(s) : s;
140
- process.stdout.write(out);
141
- };
142
- if (result.toolCallStream && typeof result.toolCallStream[Symbol.asyncIterator] === 'function') {
143
- (async () => {
144
- for await (const ev of result.toolCallStream) {
145
- const name = ev?.toolName || ev?.name || 'tool';
146
- const args = ev?.args ? JSON.stringify(ev.args).slice(0, 180) : '';
147
- if (showTools)
148
- process.stdout.write('\n' + chalk_1.default.cyan(`🔧 Tool → ${name} ${args}`) + '\n');
149
- (0, store_js_1.appendToolEvent)(sessionId, { name, argsPreview: args });
150
- }
151
- })().catch(() => { });
152
- }
153
- if (result.toolResultStream && typeof result.toolResultStream[Symbol.asyncIterator] === 'function') {
154
- (async () => {
155
- for await (const ev of result.toolResultStream) {
156
- const name = ev?.toolName || ev?.name || 'tool';
157
- const out = ev?.result ? JSON.stringify(ev.result).slice(0, 180) : '';
158
- if (showTools)
159
- process.stdout.write(chalk_1.default.magenta(`📦 Result ← ${name} ${out}`) + '\n');
160
- (0, store_js_1.appendToolEvent)(sessionId, { name, resultPreview: out });
161
- }
162
- })().catch(() => { });
163
- }
164
- process.stdout.write(chalk_1.default.green('\nAssistant: '));
165
- for await (const chunk of result.textStream) {
166
- const s = String(chunk);
167
- if (showReasoning) {
168
- if (s.includes('```reasoning') || s.toLowerCase().includes('<thinking>') || /\[\s*reasoning\s*\]/i.test(s))
169
- inReasoning = true;
170
- if (s.includes('```') || s.toLowerCase().includes('</thinking>'))
171
- inReasoning = false;
172
- }
173
- write(s);
174
- }
175
- process.stdout.write('\n');
176
- lastAssistant = buffer;
177
- messages.push({ role: 'assistant', content: buffer });
178
- (0, store_js_1.appendMessage)(sessionId, { role: 'assistant', content: buffer, timestamp: new Date().toISOString() });
179
- }
180
- }
181
- finally {
182
- rl.close();
183
- process.stdin.off('keypress', onKeypress);
184
- if (process.stdin.isTTY)
185
- process.stdin.setRawMode(false);
186
- await close();
187
- (0, store_js_1.endSession)(sessionId);
188
- }
189
- }
190
- //# sourceMappingURL=interactive.js.map
@@ -1,12 +0,0 @@
1
- import type { SnowFlowConfig } from '../config/llm-config-loader';
2
- import type { ProviderOptions } from '../llm/providers';
3
- export interface AgentRunOptions extends ProviderOptions {
4
- system?: string;
5
- user: string;
6
- mcp: SnowFlowConfig['mcp'];
7
- maxSteps?: number;
8
- showReasoning?: boolean;
9
- saveOutputPath?: string;
10
- }
11
- export declare function runAgent(opts: AgentRunOptions): Promise<void>;
12
- //# sourceMappingURL=session.d.ts.map
@@ -1,106 +0,0 @@
1
- "use strict";
2
- // Agent session placeholder to keep build green.
3
- // Will be replaced with streaming + tool-calling using the AI SDK.
4
- var __importDefault = (this && this.__importDefault) || function (mod) {
5
- return (mod && mod.__esModule) ? mod : { "default": mod };
6
- };
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.runAgent = runAgent;
9
- const bridge_1 = require("../mcp/bridge");
10
- const boxen_1 = __importDefault(require("boxen"));
11
- const chalk_1 = __importDefault(require("chalk"));
12
- const store_js_1 = require("../session/store.js");
13
- async function runAgent(opts) {
14
- const { mcp, system, user, maxSteps = 40, provider, model, baseURL, apiKeyEnv, showReasoning = true, saveOutputPath } = opts;
15
- // Resolve model via provider registry
16
- let llm;
17
- try {
18
- // eslint-disable-next-line @typescript-eslint/no-var-requires
19
- const prov = require('../llm/providers.js');
20
- llm = prov.getModel({ provider, model, baseURL, apiKeyEnv });
21
- }
22
- catch (e) {
23
- console.error('❌ LLM provider init error:', e instanceof Error ? e.message : String(e));
24
- throw e;
25
- }
26
- // Load MCP tools (if AI SDK MCP client is available)
27
- const { tools, close } = await (0, bridge_1.loadMCPTools)(mcp);
28
- // Stream using AI SDK
29
- try {
30
- // eslint-disable-next-line @typescript-eslint/no-var-requires
31
- const { streamText } = require('ai');
32
- const sessionId = (0, store_js_1.createSessionId)();
33
- (0, store_js_1.startSession)({
34
- id: sessionId,
35
- startedAt: new Date().toISOString(),
36
- objective: user,
37
- provider: { id: String(provider), model: String(model), baseURL },
38
- mcp: { cmd: mcp.cmd, args: mcp.args },
39
- });
40
- (0, store_js_1.appendMessage)(sessionId, { role: 'user', content: user, timestamp: new Date().toISOString() });
41
- const result = await streamText({
42
- model: llm,
43
- system: system ?? 'You are Snow-Flow, a ServiceNow engineering agent. Be precise. Use tools when helpful.',
44
- messages: [{ role: 'user', content: user }],
45
- tools,
46
- maxSteps,
47
- });
48
- let buffer = '';
49
- let inReasoning = false;
50
- const writeChunk = (s) => {
51
- buffer += s;
52
- const colored = inReasoning && showReasoning ? chalk_1.default.yellow.dim(s) : s;
53
- process.stdout.write(colored);
54
- };
55
- // Optional: stream tool call events if provided by SDK
56
- if (result.toolCallStream && typeof result.toolCallStream[Symbol.asyncIterator] === 'function') {
57
- (async () => {
58
- for await (const ev of result.toolCallStream) {
59
- const name = ev?.toolName || ev?.name || 'tool';
60
- const args = ev?.args ? JSON.stringify(ev.args).slice(0, 200) : '';
61
- process.stdout.write('\n' + chalk_1.default.cyan(`🔧 Tool → ${name} ${args}`) + '\n');
62
- (0, store_js_1.appendToolEvent)(sessionId, { name, argsPreview: args });
63
- }
64
- })().catch(() => { });
65
- }
66
- if (result.toolResultStream && typeof result.toolResultStream[Symbol.asyncIterator] === 'function') {
67
- (async () => {
68
- for await (const ev of result.toolResultStream) {
69
- const name = ev?.toolName || ev?.name || 'tool';
70
- const out = ev?.result ? JSON.stringify(ev.result).slice(0, 200) : '';
71
- process.stdout.write(chalk_1.default.magenta(`📦 Result ← ${name} ${out}`) + '\n');
72
- (0, store_js_1.appendToolEvent)(sessionId, { name, resultPreview: out });
73
- }
74
- })().catch(() => { });
75
- }
76
- for await (const chunk of result.textStream) {
77
- const str = String(chunk);
78
- // Heuristic: detect reasoning blocks (```reasoning, <thinking>, [reasoning])
79
- if (showReasoning) {
80
- if (str.includes('```reasoning') || str.toLowerCase().includes('<thinking>') || /\[\s*reasoning\s*\]/i.test(str))
81
- inReasoning = true;
82
- if (str.includes('```') || str.toLowerCase().includes('</thinking>'))
83
- inReasoning = false;
84
- }
85
- writeChunk(str);
86
- }
87
- // Render a boxed summary if output is long
88
- if (buffer.length > 4000) {
89
- const preview = buffer.slice(0, 1200) + '…';
90
- const box = (0, boxen_1.default)(preview, { padding: 1, borderColor: 'green', title: 'Preview (truncated)', titleAlignment: 'center' });
91
- process.stdout.write('\n' + box + '\n');
92
- process.stdout.write(chalk_1.default.gray(`Full length: ${buffer.length} chars`) + '\n');
93
- }
94
- if (saveOutputPath) {
95
- const fs = require('fs');
96
- fs.writeFileSync(saveOutputPath, buffer, 'utf8');
97
- process.stdout.write(chalk_1.default.gray(`Saved full output to ${saveOutputPath}`) + '\n');
98
- }
99
- (0, store_js_1.appendMessage)(sessionId, { role: 'assistant', content: buffer, timestamp: new Date().toISOString() });
100
- (0, store_js_1.endSession)(sessionId);
101
- }
102
- finally {
103
- await close();
104
- }
105
- }
106
- //# sourceMappingURL=session.js.map
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerAuthCommands(program: Command): void;
3
- //# sourceMappingURL=auth.d.ts.map
package/dist/cli/auth.js DELETED
@@ -1,59 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.registerAuthCommands = registerAuthCommands;
7
- const inquirer_1 = __importDefault(require("inquirer"));
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const keys_js_1 = require("../llm/keys.js");
10
- function registerAuthCommands(program) {
11
- const auth = program.command('auth').description('Manage provider API credentials for Snow-Flow');
12
- auth
13
- .command('login')
14
- .description('Interactive login to store API keys for a provider')
15
- .option('--provider <provider>', 'Provider id (openai|google|openrouter|openai-compatible|ollama)')
16
- .action(async (opts) => {
17
- const p = opts.provider || (await inquirer_1.default.prompt([{ name: 'provider', message: 'Provider', type: 'list', choices: ['openai', 'google', 'openrouter', 'openai-compatible', 'ollama'] }])).provider;
18
- const existing = (0, keys_js_1.getApiKey)(p);
19
- const { apiKey } = await inquirer_1.default.prompt([{ name: 'apiKey', message: `API key for ${p}${existing ? ' (leave blank to keep existing)' : ''}`, type: 'password', mask: '*' }]);
20
- if (!apiKey && existing) {
21
- console.log(chalk_1.default.yellow('Keeping existing key.'));
22
- return;
23
- }
24
- if (!apiKey) {
25
- console.error(chalk_1.default.red('No key entered. Aborting.'));
26
- process.exit(1);
27
- }
28
- (0, keys_js_1.setApiKey)(p, apiKey);
29
- console.log(chalk_1.default.green(`Saved API key for ${p}.`));
30
- });
31
- auth
32
- .command('set-key')
33
- .description('Set API key non-interactively')
34
- .requiredOption('--provider <provider>', 'Provider id')
35
- .requiredOption('--api-key <key>', 'API key value')
36
- .action((opts) => {
37
- (0, keys_js_1.setApiKey)(opts.provider, opts.apiKey);
38
- console.log(chalk_1.default.green(`Saved API key for ${opts.provider}.`));
39
- });
40
- auth
41
- .command('show')
42
- .description('Show configured providers (keys partially masked)')
43
- .action(() => {
44
- const entries = (0, keys_js_1.listKeys)();
45
- for (const [p, v] of Object.entries(entries)) {
46
- const mask = v ? `${v.substring(0, 4)}…${v.substring(v.length - 4)}` : '—';
47
- console.log(`${p.padEnd(18)} ${mask}`);
48
- }
49
- });
50
- auth
51
- .command('clear')
52
- .description('Clear a stored API key')
53
- .requiredOption('--provider <provider>', 'Provider id')
54
- .action((opts) => {
55
- (0, keys_js_1.clearApiKey)(opts.provider);
56
- console.log(chalk_1.default.yellow(`Cleared API key for ${opts.provider}.`));
57
- });
58
- }
59
- //# sourceMappingURL=auth.js.map
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerSessionCommands(program: Command): void;
3
- //# sourceMappingURL=session.d.ts.map
@@ -1,46 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.registerSessionCommands = registerSessionCommands;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const store_js_1 = require("../session/store.js");
9
- function registerSessionCommands(program) {
10
- const sess = program.command('session').description('Manage and inspect Snow-Flow sessions');
11
- sess
12
- .command('list')
13
- .description('List recent sessions')
14
- .action(() => {
15
- const rows = (0, store_js_1.listSessions)().slice(0, 30);
16
- if (!rows.length)
17
- return console.log('No sessions yet.');
18
- for (const r of rows) {
19
- console.log(`${chalk_1.default.gray(r.startedAt)} ${chalk_1.default.cyan(r.id)} ${r.objective}`);
20
- }
21
- });
22
- sess
23
- .command('show <id>')
24
- .description('Show session details')
25
- .action((id) => {
26
- const rec = (0, store_js_1.readSession)(id);
27
- if (!rec)
28
- return console.error(chalk_1.default.red('Session not found.'));
29
- console.log(chalk_1.default.cyan(`Session ${rec.id}`));
30
- console.log(`${chalk_1.default.gray(rec.startedAt)} → ${chalk_1.default.gray(rec.endedAt ?? '…')}`);
31
- console.log('Objective:', rec.objective);
32
- console.log('Provider:', `${rec.provider.id} ${rec.provider.model}`);
33
- console.log('MCP:', `${rec.mcp.cmd} ${(rec.mcp.args || []).join(' ')}`);
34
- console.log('\nMessages:');
35
- for (const m of rec.messages) {
36
- console.log(`- ${chalk_1.default.yellow(m.role)} ${chalk_1.default.gray(m.timestamp)}\n ${m.content.slice(0, 400)}${m.content.length > 400 ? '…' : ''}`);
37
- }
38
- if (rec.toolEvents?.length) {
39
- console.log('\nTool events:');
40
- for (const ev of rec.toolEvents) {
41
- console.log(` 🔧 ${ev.name} ${chalk_1.default.gray(ev.when)} ${ev.argsPreview ? ('args:' + ev.argsPreview) : ''} ${ev.resultPreview ? ('res:' + ev.resultPreview) : ''}`);
42
- }
43
- }
44
- });
45
- }
46
- //# sourceMappingURL=session.js.map
@@ -1,5 +0,0 @@
1
- export declare function setApiKey(provider: string, value: string): void;
2
- export declare function getApiKey(provider: string): string | undefined;
3
- export declare function clearApiKey(provider: string): void;
4
- export declare function listKeys(): Record<string, string | undefined>;
5
- //# sourceMappingURL=keys.d.ts.map
package/dist/llm/keys.js DELETED
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.setApiKey = setApiKey;
7
- exports.getApiKey = getApiKey;
8
- exports.clearApiKey = clearApiKey;
9
- exports.listKeys = listKeys;
10
- const conf_1 = __importDefault(require("conf"));
11
- // Avoid generic type for broader compatibility with shimmed types
12
- const store = new conf_1.default({ projectName: 'snow-flow' });
13
- function setApiKey(provider, value) {
14
- store.set(`keys.${provider}`, value);
15
- }
16
- function getApiKey(provider) {
17
- return store.get(`keys.${provider}`);
18
- }
19
- function clearApiKey(provider) {
20
- store.delete(`keys.${provider}`);
21
- }
22
- function listKeys() {
23
- const providers = ['openai', 'google', 'openrouter', 'openai-compatible', 'ollama'];
24
- const out = {};
25
- for (const p of providers)
26
- out[p] = getApiKey(p);
27
- return out;
28
- }
29
- //# sourceMappingURL=keys.js.map