@sylphx/flow 1.7.0 → 1.8.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.
- package/CHANGELOG.md +78 -0
- package/assets/agents/coder.md +72 -119
- package/assets/agents/orchestrator.md +26 -90
- package/assets/agents/reviewer.md +76 -47
- package/assets/agents/writer.md +82 -63
- package/assets/output-styles/silent.md +141 -8
- package/assets/rules/code-standards.md +9 -33
- package/assets/rules/core.md +67 -59
- package/package.json +2 -12
- package/src/commands/flow/execute.ts +470 -0
- package/src/commands/flow/index.ts +11 -0
- package/src/commands/flow/prompt.ts +35 -0
- package/src/commands/flow/setup.ts +312 -0
- package/src/commands/flow/targets.ts +18 -0
- package/src/commands/flow/types.ts +47 -0
- package/src/commands/flow-command.ts +18 -967
- package/src/commands/flow-orchestrator.ts +14 -5
- package/src/commands/hook-command.ts +1 -1
- package/src/commands/init-core.ts +12 -3
- package/src/commands/run-command.ts +1 -1
- package/src/config/rules.ts +1 -1
- package/src/core/error-handling.ts +1 -1
- package/src/core/loop-controller.ts +1 -1
- package/src/core/state-detector.ts +1 -1
- package/src/core/target-manager.ts +1 -1
- package/src/index.ts +1 -1
- package/src/shared/files/index.ts +1 -1
- package/src/shared/processing/index.ts +1 -1
- package/src/targets/claude-code.ts +3 -3
- package/src/targets/opencode.ts +3 -3
- package/src/utils/agent-enhancer.ts +2 -2
- package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
- package/src/utils/{paths.ts → config/paths.ts} +1 -1
- package/src/utils/{settings.ts → config/settings.ts} +1 -1
- package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
- package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
- package/src/utils/display/banner.ts +25 -0
- package/src/utils/display/status.ts +55 -0
- package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
- package/src/utils/files/jsonc.ts +36 -0
- package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
- package/src/utils/index.ts +42 -61
- package/src/utils/version.ts +47 -0
- package/src/components/benchmark-monitor.tsx +0 -331
- package/src/components/reindex-progress.tsx +0 -261
- package/src/composables/functional/index.ts +0 -14
- package/src/composables/functional/useEnvironment.ts +0 -171
- package/src/composables/functional/useFileSystem.ts +0 -139
- package/src/composables/index.ts +0 -4
- package/src/composables/useEnv.ts +0 -13
- package/src/composables/useRuntimeConfig.ts +0 -27
- package/src/core/ai-sdk.ts +0 -603
- package/src/core/app-factory.ts +0 -381
- package/src/core/builtin-agents.ts +0 -9
- package/src/core/command-system.ts +0 -550
- package/src/core/config-system.ts +0 -550
- package/src/core/connection-pool.ts +0 -390
- package/src/core/di-container.ts +0 -155
- package/src/core/headless-display.ts +0 -96
- package/src/core/interfaces/index.ts +0 -22
- package/src/core/interfaces/repository.interface.ts +0 -91
- package/src/core/interfaces/service.interface.ts +0 -133
- package/src/core/interfaces.ts +0 -96
- package/src/core/result.ts +0 -351
- package/src/core/service-config.ts +0 -252
- package/src/core/session-service.ts +0 -121
- package/src/core/storage-factory.ts +0 -115
- package/src/core/stream-handler.ts +0 -288
- package/src/core/type-utils.ts +0 -427
- package/src/core/unified-storage.ts +0 -456
- package/src/core/validation/limit.ts +0 -46
- package/src/core/validation/query.ts +0 -20
- package/src/db/auto-migrate.ts +0 -322
- package/src/db/base-database-client.ts +0 -144
- package/src/db/cache-db.ts +0 -218
- package/src/db/cache-schema.ts +0 -75
- package/src/db/database.ts +0 -70
- package/src/db/index.ts +0 -252
- package/src/db/memory-db.ts +0 -153
- package/src/db/memory-schema.ts +0 -29
- package/src/db/schema.ts +0 -289
- package/src/db/session-repository.ts +0 -733
- package/src/domains/index.ts +0 -6
- package/src/domains/utilities/index.ts +0 -6
- package/src/domains/utilities/time/index.ts +0 -5
- package/src/domains/utilities/time/tools.ts +0 -291
- package/src/services/agent-service.ts +0 -273
- package/src/services/evaluation-service.ts +0 -271
- package/src/services/functional/evaluation-logic.ts +0 -296
- package/src/services/functional/file-processor.ts +0 -273
- package/src/services/functional/index.ts +0 -12
- package/src/services/memory.service.ts +0 -476
- package/src/types/api/batch.ts +0 -108
- package/src/types/api/errors.ts +0 -118
- package/src/types/api/index.ts +0 -55
- package/src/types/api/requests.ts +0 -76
- package/src/types/api/responses.ts +0 -180
- package/src/types/api/websockets.ts +0 -85
- package/src/types/benchmark.ts +0 -49
- package/src/types/database.types.ts +0 -510
- package/src/types/memory-types.ts +0 -63
- package/src/utils/advanced-tokenizer.ts +0 -191
- package/src/utils/ai-model-fetcher.ts +0 -19
- package/src/utils/async-file-operations.ts +0 -516
- package/src/utils/audio-player.ts +0 -345
- package/src/utils/codebase-helpers.ts +0 -211
- package/src/utils/console-ui.ts +0 -79
- package/src/utils/database-errors.ts +0 -140
- package/src/utils/debug-logger.ts +0 -49
- package/src/utils/file-scanner.ts +0 -259
- package/src/utils/help.ts +0 -20
- package/src/utils/immutable-cache.ts +0 -106
- package/src/utils/jsonc.ts +0 -158
- package/src/utils/memory-tui.ts +0 -414
- package/src/utils/models-dev.ts +0 -91
- package/src/utils/parallel-operations.ts +0 -487
- package/src/utils/process-manager.ts +0 -155
- package/src/utils/prompts.ts +0 -120
- package/src/utils/search-tool-builder.ts +0 -214
- package/src/utils/session-manager.ts +0 -168
- package/src/utils/session-title.ts +0 -87
- package/src/utils/simplified-errors.ts +0 -410
- package/src/utils/template-engine.ts +0 -94
- package/src/utils/test-audio.ts +0 -71
- package/src/utils/todo-context.ts +0 -46
- package/src/utils/token-counter.ts +0 -288
- /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
- /package/src/utils/{logger.ts → display/logger.ts} +0 -0
- /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
- /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
- /package/src/utils/{security.ts → security/security.ts} +0 -0
package/src/utils/jsonc.ts
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSONC (JSON with Comments) utilities
|
|
3
|
-
* Provides functions to parse and stringify JSONC files while preserving comments
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Parse JSONC content (JSON with Comments)
|
|
10
|
-
* @param content - The JSONC string to parse
|
|
11
|
-
* @returns The parsed JavaScript object
|
|
12
|
-
*/
|
|
13
|
-
export function parseJSONC(content: string): unknown {
|
|
14
|
-
try {
|
|
15
|
-
// Remove single-line comments (//) but not inside strings
|
|
16
|
-
let cleaned = removeComments(content);
|
|
17
|
-
|
|
18
|
-
// Remove trailing commas before closing brackets/braces
|
|
19
|
-
cleaned = cleaned.replace(/,(\s*[}\]])/g, '$1');
|
|
20
|
-
|
|
21
|
-
return JSON.parse(cleaned);
|
|
22
|
-
} catch (error) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
`Failed to parse JSONC: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Remove comments from JSON content while preserving strings
|
|
31
|
-
*/
|
|
32
|
-
function removeComments(content: string): string {
|
|
33
|
-
let result = '';
|
|
34
|
-
let inString = false;
|
|
35
|
-
let inSingleLineComment = false;
|
|
36
|
-
let inMultiLineComment = false;
|
|
37
|
-
let escapeNext = false;
|
|
38
|
-
|
|
39
|
-
for (let i = 0; i < content.length; i++) {
|
|
40
|
-
const char = content[i];
|
|
41
|
-
const nextChar = content[i + 1];
|
|
42
|
-
|
|
43
|
-
if (escapeNext) {
|
|
44
|
-
result += char;
|
|
45
|
-
escapeNext = false;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (char === '\\' && inString) {
|
|
50
|
-
result += char;
|
|
51
|
-
escapeNext = true;
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (inString) {
|
|
56
|
-
if (char === '"') {
|
|
57
|
-
inString = false;
|
|
58
|
-
}
|
|
59
|
-
result += char;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (inSingleLineComment) {
|
|
64
|
-
if (char === '\n') {
|
|
65
|
-
inSingleLineComment = false;
|
|
66
|
-
result += char;
|
|
67
|
-
}
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (inMultiLineComment) {
|
|
72
|
-
if (char === '*' && nextChar === '/') {
|
|
73
|
-
inMultiLineComment = false;
|
|
74
|
-
i++; // Skip the '/'
|
|
75
|
-
}
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (char === '"') {
|
|
80
|
-
inString = true;
|
|
81
|
-
result += char;
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (char === '/' && nextChar === '/') {
|
|
86
|
-
inSingleLineComment = true;
|
|
87
|
-
i++; // Skip the second '/'
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (char === '/' && nextChar === '*') {
|
|
92
|
-
inMultiLineComment = true;
|
|
93
|
-
i++; // Skip the '*'
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
result += char;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return result;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Stringify an object to JSON format with optional schema
|
|
105
|
-
* @param obj - The object to stringify
|
|
106
|
-
* @param schema - Optional schema URL to include
|
|
107
|
-
* @param indent - Indentation spaces (default: 2)
|
|
108
|
-
* @returns The formatted JSON string
|
|
109
|
-
*/
|
|
110
|
-
export function stringifyJSONC(obj: Record<string, unknown>, schema?: string, indent = 2): string {
|
|
111
|
-
const config = { ...obj };
|
|
112
|
-
|
|
113
|
-
// Add schema if provided and not already present
|
|
114
|
-
if (schema && !config.$schema) {
|
|
115
|
-
config.$schema = schema;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const json = JSON.stringify(config, null, indent);
|
|
119
|
-
|
|
120
|
-
// Add helpful comments for MCP configuration
|
|
121
|
-
if (config.mcp && Object.keys(config.mcp).length > 0) {
|
|
122
|
-
return json.replace(
|
|
123
|
-
/(\s*)"mcp": {/,
|
|
124
|
-
`$1// MCP (Model Context Protocol) server configuration
|
|
125
|
-
$1// See https://modelcontextprotocol.io for more information
|
|
126
|
-
$1"mcp": {`
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return json;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Read and parse a JSONC file
|
|
135
|
-
* @param filePath - Path to the JSONC file
|
|
136
|
-
* @returns The parsed object
|
|
137
|
-
*/
|
|
138
|
-
export async function readJSONCFile(filePath: string): Promise<any> {
|
|
139
|
-
const content = await readFile(filePath, 'utf8');
|
|
140
|
-
return parseJSONC(content);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Write an object to a JSONC file
|
|
145
|
-
* @param filePath - Path to the JSONC file
|
|
146
|
-
* @param obj - The object to write
|
|
147
|
-
* @param schema - Optional schema URL
|
|
148
|
-
* @param indent - Indentation spaces
|
|
149
|
-
*/
|
|
150
|
-
export async function writeJSONCFile(
|
|
151
|
-
filePath: string,
|
|
152
|
-
obj: Record<string, unknown>,
|
|
153
|
-
schema?: string,
|
|
154
|
-
indent = 2
|
|
155
|
-
): Promise<void> {
|
|
156
|
-
const content = stringifyJSONC(obj, schema, indent);
|
|
157
|
-
await writeFile(filePath, content, 'utf8');
|
|
158
|
-
}
|
package/src/utils/memory-tui.ts
DELETED
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
import inquirer from 'inquirer';
|
|
4
|
-
import { DrizzleMemoryStorage, type MemoryEntry } from '../utils/drizzle-storage.js';
|
|
5
|
-
|
|
6
|
-
interface MemoryEntryChoice extends inquirer.ChoiceBase {
|
|
7
|
-
value: MemoryEntry;
|
|
8
|
-
name: string;
|
|
9
|
-
short: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface MemoryActionChoice extends inquirer.ChoiceBase {
|
|
13
|
-
value: string;
|
|
14
|
-
name: string;
|
|
15
|
-
short: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface MemoryFormData {
|
|
19
|
-
namespace: string;
|
|
20
|
-
key: string;
|
|
21
|
-
value: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class MemoryTUI {
|
|
25
|
-
private memory: DrizzleMemoryStorage;
|
|
26
|
-
private entries: MemoryEntry[] = [];
|
|
27
|
-
private running = true;
|
|
28
|
-
|
|
29
|
-
constructor() {
|
|
30
|
-
this.memory = new DrizzleMemoryStorage();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async start(): Promise<void> {
|
|
34
|
-
console.clear();
|
|
35
|
-
console.log(chalk.cyan.bold('🧠 Memory Manager'));
|
|
36
|
-
console.log(chalk.gray('Interactive memory management for Sylphx Flow\n'));
|
|
37
|
-
|
|
38
|
-
await this.loadEntries();
|
|
39
|
-
|
|
40
|
-
while (this.running) {
|
|
41
|
-
try {
|
|
42
|
-
await this.showMainMenu();
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.error(chalk.red(`Error: ${error}`));
|
|
45
|
-
await inquirer.prompt([
|
|
46
|
-
{
|
|
47
|
-
type: 'input',
|
|
48
|
-
name: 'continue',
|
|
49
|
-
message: 'Press Enter to continue...',
|
|
50
|
-
},
|
|
51
|
-
]);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private async loadEntries(): Promise<void> {
|
|
57
|
-
try {
|
|
58
|
-
this.entries = await this.memory.getAll();
|
|
59
|
-
this.entries.sort(
|
|
60
|
-
(a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()
|
|
61
|
-
);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.error(chalk.red(`Failed to load entries: ${error}`));
|
|
64
|
-
this.entries = [];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private async showMainMenu(): Promise<void> {
|
|
69
|
-
if (this.entries.length === 0) {
|
|
70
|
-
console.log(chalk.yellow('No memory entries found.'));
|
|
71
|
-
|
|
72
|
-
const { action } = await inquirer.prompt([
|
|
73
|
-
{
|
|
74
|
-
type: 'list',
|
|
75
|
-
name: 'action',
|
|
76
|
-
message: 'What would you like to do?',
|
|
77
|
-
choices: [
|
|
78
|
-
{ name: '➕ Add new entry', value: 'add' },
|
|
79
|
-
{ name: '🔄 Refresh entries', value: 'refresh' },
|
|
80
|
-
{ name: '✗ Exit', value: 'exit' },
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
]);
|
|
84
|
-
|
|
85
|
-
if (action === 'add') {
|
|
86
|
-
await this.showAddEntry();
|
|
87
|
-
} else if (action === 'refresh') {
|
|
88
|
-
await this.loadEntries();
|
|
89
|
-
} else {
|
|
90
|
-
this.running = false;
|
|
91
|
-
}
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const choices: MemoryActionChoice[] = [
|
|
96
|
-
{ name: '📝 View entry details', value: 'view', short: 'View' },
|
|
97
|
-
{ name: '✏️ Edit entry', value: 'edit', short: 'Edit' },
|
|
98
|
-
{ name: '➕ Add new entry', value: 'add', short: 'Add' },
|
|
99
|
-
{ name: '🗑️ Delete entry', value: 'delete', short: 'Delete' },
|
|
100
|
-
{ name: '🔍 Search entries', value: 'search', short: 'Search' },
|
|
101
|
-
{ name: '🔄 Refresh entries', value: 'refresh', short: 'Refresh' },
|
|
102
|
-
{ name: '✗ Exit', value: 'exit', short: 'Exit' },
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
const { action } = await inquirer.prompt([
|
|
106
|
-
{
|
|
107
|
-
type: 'list',
|
|
108
|
-
name: 'action',
|
|
109
|
-
message: 'What would you like to do?',
|
|
110
|
-
choices,
|
|
111
|
-
},
|
|
112
|
-
]);
|
|
113
|
-
|
|
114
|
-
switch (action) {
|
|
115
|
-
case 'view':
|
|
116
|
-
await this.showViewEntry();
|
|
117
|
-
break;
|
|
118
|
-
case 'edit':
|
|
119
|
-
await this.showEditEntry();
|
|
120
|
-
break;
|
|
121
|
-
case 'add':
|
|
122
|
-
await this.showAddEntry();
|
|
123
|
-
break;
|
|
124
|
-
case 'delete':
|
|
125
|
-
await this.showDeleteEntry();
|
|
126
|
-
break;
|
|
127
|
-
case 'search':
|
|
128
|
-
await this.showSearchEntries();
|
|
129
|
-
break;
|
|
130
|
-
case 'refresh':
|
|
131
|
-
await this.loadEntries();
|
|
132
|
-
console.log(chalk.green('✓ Entries refreshed'));
|
|
133
|
-
break;
|
|
134
|
-
case 'exit':
|
|
135
|
-
this.running = false;
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
private async selectEntry(message: string, allowEmpty = false): Promise<MemoryEntry | null> {
|
|
141
|
-
if (this.entries.length === 0) {
|
|
142
|
-
if (allowEmpty) {
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
throw new Error('No entries available');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const choices: MemoryEntryChoice[] = this.entries.map((entry, index) => ({
|
|
149
|
-
value: entry,
|
|
150
|
-
name: `${chalk.cyan(`${index + 1}.`)} ${chalk.bold(entry.namespace)}:${chalk.bold(entry.key)}`,
|
|
151
|
-
short: `${entry.namespace}:${entry.key}`,
|
|
152
|
-
}));
|
|
153
|
-
|
|
154
|
-
if (allowEmpty) {
|
|
155
|
-
choices.unshift({ name: '← Back to menu', value: null as any, short: 'Back' });
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const { selected } = await inquirer.prompt([
|
|
159
|
-
{
|
|
160
|
-
type: 'list',
|
|
161
|
-
name: 'selected',
|
|
162
|
-
message,
|
|
163
|
-
choices,
|
|
164
|
-
pageSize: 15,
|
|
165
|
-
},
|
|
166
|
-
]);
|
|
167
|
-
|
|
168
|
-
return selected;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private async showViewEntry(): Promise<void> {
|
|
172
|
-
const entry = await this.selectEntry('Select entry to view:', true);
|
|
173
|
-
if (!entry) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
console.clear();
|
|
178
|
-
console.log(chalk.cyan.bold('📄 Entry Details'));
|
|
179
|
-
console.log(chalk.gray('─'.repeat(50)));
|
|
180
|
-
|
|
181
|
-
console.log(chalk.blue.bold('Namespace:'), entry.namespace);
|
|
182
|
-
console.log(chalk.blue.bold('Key:'), entry.key);
|
|
183
|
-
console.log(chalk.blue.bold('Updated:'), entry.updated_at);
|
|
184
|
-
|
|
185
|
-
console.log(chalk.blue.bold('\nValue:'));
|
|
186
|
-
const valueStr = JSON.stringify(entry.value, null, 2);
|
|
187
|
-
console.log(chalk.gray(valueStr));
|
|
188
|
-
|
|
189
|
-
await inquirer.prompt([
|
|
190
|
-
{
|
|
191
|
-
type: 'input',
|
|
192
|
-
name: 'continue',
|
|
193
|
-
message: 'Press Enter to continue...',
|
|
194
|
-
},
|
|
195
|
-
]);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
private async showEditEntry(): Promise<void> {
|
|
199
|
-
const entry = await this.selectEntry('Select entry to edit:', true);
|
|
200
|
-
if (!entry) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
console.clear();
|
|
205
|
-
console.log(chalk.yellow.bold('✏️ Edit Entry'));
|
|
206
|
-
console.log(chalk.gray('─'.repeat(50)));
|
|
207
|
-
console.log(`${chalk.blue('Editing:')} ${entry.namespace}:${entry.key}\n`);
|
|
208
|
-
|
|
209
|
-
const formData: MemoryFormData = await inquirer.prompt([
|
|
210
|
-
{
|
|
211
|
-
type: 'input',
|
|
212
|
-
name: 'namespace',
|
|
213
|
-
message: 'Namespace:',
|
|
214
|
-
default: entry.namespace,
|
|
215
|
-
validate: (input) => input.trim().length > 0 || 'Namespace is required',
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
type: 'input',
|
|
219
|
-
name: 'key',
|
|
220
|
-
message: 'Key:',
|
|
221
|
-
default: entry.key,
|
|
222
|
-
validate: (input) => input.trim().length > 0 || 'Key is required',
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
type: 'editor',
|
|
226
|
-
name: 'value',
|
|
227
|
-
message: 'Value (JSON):',
|
|
228
|
-
default: JSON.stringify(entry.value, null, 2),
|
|
229
|
-
validate: (input) => {
|
|
230
|
-
try {
|
|
231
|
-
JSON.parse(input);
|
|
232
|
-
return true;
|
|
233
|
-
} catch {
|
|
234
|
-
return 'Invalid JSON format';
|
|
235
|
-
}
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
]);
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
const parsedValue = JSON.parse(formData.value);
|
|
242
|
-
await this.memory.set(formData.key, parsedValue, formData.namespace);
|
|
243
|
-
|
|
244
|
-
// Remove old entry if namespace or key changed
|
|
245
|
-
if (formData.namespace !== entry.namespace || formData.key !== entry.key) {
|
|
246
|
-
await this.memory.delete(entry.key, entry.namespace);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
await this.loadEntries();
|
|
250
|
-
console.log(chalk.green(`✓ Updated ${formData.namespace}:${formData.key}`));
|
|
251
|
-
} catch (error) {
|
|
252
|
-
console.error(chalk.red(`Failed to update entry: ${error}`));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
await inquirer.prompt([
|
|
256
|
-
{
|
|
257
|
-
type: 'input',
|
|
258
|
-
name: 'continue',
|
|
259
|
-
message: 'Press Enter to continue...',
|
|
260
|
-
},
|
|
261
|
-
]);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
private async showAddEntry(): Promise<void> {
|
|
265
|
-
console.clear();
|
|
266
|
-
console.log(chalk.green.bold('➕ Add New Entry'));
|
|
267
|
-
console.log(chalk.gray('─'.repeat(50)));
|
|
268
|
-
|
|
269
|
-
const formData: MemoryFormData = await inquirer.prompt([
|
|
270
|
-
{
|
|
271
|
-
type: 'input',
|
|
272
|
-
name: 'namespace',
|
|
273
|
-
message: 'Namespace:',
|
|
274
|
-
default: 'default',
|
|
275
|
-
validate: (input) => input.trim().length > 0 || 'Namespace is required',
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
type: 'input',
|
|
279
|
-
name: 'key',
|
|
280
|
-
message: 'Key:',
|
|
281
|
-
validate: (input) => input.trim().length > 0 || 'Key is required',
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
type: 'editor',
|
|
285
|
-
name: 'value',
|
|
286
|
-
message: 'Value (JSON):',
|
|
287
|
-
default: '{\n \n}',
|
|
288
|
-
validate: (input) => {
|
|
289
|
-
try {
|
|
290
|
-
JSON.parse(input);
|
|
291
|
-
return true;
|
|
292
|
-
} catch {
|
|
293
|
-
return 'Invalid JSON format';
|
|
294
|
-
}
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
]);
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
const parsedValue = JSON.parse(formData.value);
|
|
301
|
-
await this.memory.set(formData.key, parsedValue, formData.namespace);
|
|
302
|
-
await this.loadEntries();
|
|
303
|
-
console.log(chalk.green(`✓ Added ${formData.namespace}:${formData.key}`));
|
|
304
|
-
} catch (error) {
|
|
305
|
-
console.error(chalk.red(`Failed to add entry: ${error}`));
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
await inquirer.prompt([
|
|
309
|
-
{
|
|
310
|
-
type: 'input',
|
|
311
|
-
name: 'continue',
|
|
312
|
-
message: 'Press Enter to continue...',
|
|
313
|
-
},
|
|
314
|
-
]);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
private async showDeleteEntry(): Promise<void> {
|
|
318
|
-
const entry = await this.selectEntry('Select entry to delete:', true);
|
|
319
|
-
if (!entry) {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
console.clear();
|
|
324
|
-
console.log(chalk.red.bold('🗑️ Delete Entry'));
|
|
325
|
-
console.log(chalk.gray('─'.repeat(50)));
|
|
326
|
-
console.log(`${chalk.blue('Entry:')} ${entry.namespace}:${entry.key}`);
|
|
327
|
-
|
|
328
|
-
const valuePreview = JSON.stringify(entry.value);
|
|
329
|
-
const preview =
|
|
330
|
-
valuePreview.length > 100 ? `${valuePreview.substring(0, 100)}...` : valuePreview;
|
|
331
|
-
console.log(`${chalk.blue('Value:')} ${chalk.gray(preview)}`);
|
|
332
|
-
|
|
333
|
-
const { confirmed } = await inquirer.prompt([
|
|
334
|
-
{
|
|
335
|
-
type: 'confirm',
|
|
336
|
-
name: 'confirmed',
|
|
337
|
-
message: chalk.yellow('Are you sure you want to delete this entry?'),
|
|
338
|
-
default: false,
|
|
339
|
-
},
|
|
340
|
-
]);
|
|
341
|
-
|
|
342
|
-
if (confirmed) {
|
|
343
|
-
try {
|
|
344
|
-
await this.memory.delete(entry.key, entry.namespace);
|
|
345
|
-
await this.loadEntries();
|
|
346
|
-
console.log(chalk.green(`✓ Deleted ${entry.namespace}:${entry.key}`));
|
|
347
|
-
} catch (error) {
|
|
348
|
-
console.error(chalk.red(`Failed to delete entry: ${error}`));
|
|
349
|
-
}
|
|
350
|
-
} else {
|
|
351
|
-
console.log(chalk.gray('Delete cancelled'));
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
await inquirer.prompt([
|
|
355
|
-
{
|
|
356
|
-
type: 'input',
|
|
357
|
-
name: 'continue',
|
|
358
|
-
message: 'Press Enter to continue...',
|
|
359
|
-
},
|
|
360
|
-
]);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
private async showSearchEntries(): Promise<void> {
|
|
364
|
-
console.clear();
|
|
365
|
-
console.log(chalk.magenta.bold('🔍 Search Entries'));
|
|
366
|
-
console.log(chalk.gray('─'.repeat(50)));
|
|
367
|
-
|
|
368
|
-
const { query } = await inquirer.prompt([
|
|
369
|
-
{
|
|
370
|
-
type: 'input',
|
|
371
|
-
name: 'query',
|
|
372
|
-
message: 'Search query:',
|
|
373
|
-
validate: (input) => input.trim().length > 0 || 'Search query is required',
|
|
374
|
-
},
|
|
375
|
-
]);
|
|
376
|
-
|
|
377
|
-
const filteredEntries = this.entries.filter(
|
|
378
|
-
(entry) =>
|
|
379
|
-
entry.namespace.toLowerCase().includes(query.toLowerCase()) ||
|
|
380
|
-
entry.key.toLowerCase().includes(query.toLowerCase()) ||
|
|
381
|
-
JSON.stringify(entry.value).toLowerCase().includes(query.toLowerCase())
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
if (filteredEntries.length === 0) {
|
|
385
|
-
console.log(chalk.yellow('No entries found matching your search.'));
|
|
386
|
-
} else {
|
|
387
|
-
console.log(chalk.cyan(`\nFound ${filteredEntries.length} matching entries:\n`));
|
|
388
|
-
|
|
389
|
-
filteredEntries.forEach((entry, index) => {
|
|
390
|
-
const valuePreview = JSON.stringify(entry.value);
|
|
391
|
-
const preview =
|
|
392
|
-
valuePreview.length > 80 ? `${valuePreview.substring(0, 80)}...` : valuePreview;
|
|
393
|
-
|
|
394
|
-
console.log(
|
|
395
|
-
`${chalk.cyan(`${index + 1}.`)} ${chalk.bold(entry.namespace)}:${chalk.bold(entry.key)}`
|
|
396
|
-
);
|
|
397
|
-
console.log(` ${chalk.gray(preview)}\n`);
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
await inquirer.prompt([
|
|
402
|
-
{
|
|
403
|
-
type: 'input',
|
|
404
|
-
name: 'continue',
|
|
405
|
-
message: 'Press Enter to continue...',
|
|
406
|
-
},
|
|
407
|
-
]);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
export const handleMemoryTui = async (): Promise<void> => {
|
|
412
|
-
const tui = new MemoryTUI();
|
|
413
|
-
await tui.start();
|
|
414
|
-
};
|
package/src/utils/models-dev.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Models.dev API Integration
|
|
3
|
-
* Fetch model metadata as fallback source
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface ModelMetadata {
|
|
7
|
-
id: string;
|
|
8
|
-
name?: string;
|
|
9
|
-
contextLength?: number;
|
|
10
|
-
maxOutput?: number;
|
|
11
|
-
inputPrice?: number;
|
|
12
|
-
outputPrice?: number;
|
|
13
|
-
provider?: string;
|
|
14
|
-
description?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ModelsDevResponse {
|
|
18
|
-
models: Array<{
|
|
19
|
-
id: string;
|
|
20
|
-
name?: string;
|
|
21
|
-
context_length?: number;
|
|
22
|
-
max_output?: number;
|
|
23
|
-
pricing?: {
|
|
24
|
-
input?: number;
|
|
25
|
-
output?: number;
|
|
26
|
-
};
|
|
27
|
-
provider?: string;
|
|
28
|
-
description?: string;
|
|
29
|
-
}>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
let cachedModels: Map<string, ModelMetadata> | null = null;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Fetch model metadata from models.dev
|
|
36
|
-
*/
|
|
37
|
-
export async function fetchModelsMetadata(): Promise<Map<string, ModelMetadata>> {
|
|
38
|
-
if (cachedModels) {
|
|
39
|
-
return cachedModels;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
const response = await fetch('https://models.dev/api.json', {
|
|
44
|
-
headers: {
|
|
45
|
-
'User-Agent': 'sylphx-flow/1.0',
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
throw new Error(`Failed to fetch models.dev: ${response.status}`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const data = (await response.json()) as ModelsDevResponse;
|
|
54
|
-
|
|
55
|
-
const models = new Map<string, ModelMetadata>();
|
|
56
|
-
|
|
57
|
-
for (const model of data.models) {
|
|
58
|
-
models.set(model.id, {
|
|
59
|
-
id: model.id,
|
|
60
|
-
name: model.name,
|
|
61
|
-
contextLength: model.context_length,
|
|
62
|
-
maxOutput: model.max_output,
|
|
63
|
-
inputPrice: model.pricing?.input,
|
|
64
|
-
outputPrice: model.pricing?.output,
|
|
65
|
-
provider: model.provider,
|
|
66
|
-
description: model.description,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
cachedModels = models;
|
|
71
|
-
return models;
|
|
72
|
-
} catch (error) {
|
|
73
|
-
console.error('Failed to fetch models.dev:', error);
|
|
74
|
-
return new Map();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Get metadata for a specific model
|
|
80
|
-
*/
|
|
81
|
-
export async function getModelMetadata(modelId: string): Promise<ModelMetadata | null> {
|
|
82
|
-
const models = await fetchModelsMetadata();
|
|
83
|
-
return models.get(modelId) || null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Clear cache (for testing or forcing refresh)
|
|
88
|
-
*/
|
|
89
|
-
export function clearModelsCache(): void {
|
|
90
|
-
cachedModels = null;
|
|
91
|
-
}
|