@chanl/cli 2.0.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/agents.test.js +574 -0
- package/dist/__tests__/agents.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +2 -0
- package/dist/__tests__/auth.test.js +87 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/calls.test.d.ts +2 -0
- package/dist/__tests__/calls.test.js +115 -0
- package/dist/__tests__/calls.test.js.map +1 -0
- package/dist/__tests__/chat.test.d.ts +2 -0
- package/dist/__tests__/chat.test.js +357 -0
- package/dist/__tests__/chat.test.js.map +1 -0
- package/dist/__tests__/cli-base.test.d.ts +2 -0
- package/dist/__tests__/cli-base.test.js +87 -0
- package/dist/__tests__/cli-base.test.js.map +1 -0
- package/dist/__tests__/cli-missing.test.d.ts +2 -0
- package/dist/__tests__/cli-missing.test.js +546 -0
- package/dist/__tests__/cli-missing.test.js.map +1 -0
- package/dist/__tests__/helpers.d.ts +234 -0
- package/dist/__tests__/helpers.js +314 -0
- package/dist/__tests__/helpers.js.map +1 -0
- package/dist/__tests__/mcp.test.d.ts +2 -0
- package/dist/__tests__/mcp.test.js +470 -0
- package/dist/__tests__/mcp.test.js.map +1 -0
- package/dist/__tests__/prompts.test.d.ts +2 -0
- package/dist/__tests__/prompts.test.js +227 -0
- package/dist/__tests__/prompts.test.js.map +1 -0
- package/dist/__tests__/scenarios.test.d.ts +2 -0
- package/dist/__tests__/scenarios.test.js +270 -0
- package/dist/__tests__/scenarios.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +2 -0
- package/dist/__tests__/tools.test.js +331 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/__tests__/toolsets.test.d.ts +2 -0
- package/dist/__tests__/toolsets.test.js +196 -0
- package/dist/__tests__/toolsets.test.js.map +1 -0
- package/dist/__tests__/workspaces.test.d.ts +2 -0
- package/dist/__tests__/workspaces.test.js +155 -0
- package/dist/__tests__/workspaces.test.js.map +1 -0
- package/dist/commands/agents.js +96 -6
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/chat.js +2 -2
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/config.js +24 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/memory.js +134 -1
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/prompts.js +148 -1
- package/dist/commands/prompts.js.map +1 -1
- package/dist/commands/scorecards.js +3 -3
- package/dist/commands/scorecards.js.map +1 -1
- package/dist/utils/config-store.d.ts +8 -0
- package/dist/utils/config-store.js +18 -1
- package/dist/utils/config-store.js.map +1 -1
- package/dist/utils/sdk-factory.js +15 -3
- package/dist/utils/sdk-factory.js.map +1 -1
- package/package.json +4 -4
- package/dist/__tests__/cli.test.js +0 -2308
- package/dist/__tests__/cli.test.js.map +0 -1
- /package/dist/__tests__/{cli.test.d.ts → agents.test.d.ts} +0 -0
package/dist/commands/config.js
CHANGED
|
@@ -14,6 +14,9 @@ import {
|
|
|
14
14
|
const VALID_KEYS = [
|
|
15
15
|
"apiKey",
|
|
16
16
|
"baseUrl",
|
|
17
|
+
"server",
|
|
18
|
+
"deployment",
|
|
19
|
+
"apiPrefix",
|
|
17
20
|
"workspaceId",
|
|
18
21
|
"defaultFormat"
|
|
19
22
|
];
|
|
@@ -25,6 +28,9 @@ const KEY_DESCRIPTIONS = {
|
|
|
25
28
|
jwtToken: "JWT access token (from browser login)",
|
|
26
29
|
refreshToken: "JWT refresh token (from browser login)",
|
|
27
30
|
baseUrl: "Base URL for the Chanl API",
|
|
31
|
+
server: "Alias for baseUrl (e.g. http://localhost:18005)",
|
|
32
|
+
deployment: "local | cloud \u2014 local rewrites /api/v1 paths for OSS scenario servers",
|
|
33
|
+
apiPrefix: "Override API prefix; empty string for flat /scenarios routes",
|
|
28
34
|
workspaceId: "Default workspace ID",
|
|
29
35
|
appUrl: "App URL for browser-based flows",
|
|
30
36
|
defaultFormat: "Default output format (table or json)"
|
|
@@ -143,16 +149,24 @@ function handleConfigSet(key, value) {
|
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
configStore.set(typedKey, value);
|
|
152
|
+
const clearedServer = typedKey === "baseUrl" && configStore.has("server");
|
|
153
|
+
if (clearedServer) {
|
|
154
|
+
configStore.delete("server");
|
|
155
|
+
}
|
|
146
156
|
if (isJsonOutput()) {
|
|
147
157
|
printJson({
|
|
148
158
|
success: true,
|
|
149
159
|
key,
|
|
150
|
-
value: key === "apiKey" ? maskString(value) : value
|
|
160
|
+
value: key === "apiKey" ? maskString(value) : value,
|
|
161
|
+
...clearedServer && { clearedServer: true }
|
|
151
162
|
});
|
|
152
163
|
return;
|
|
153
164
|
}
|
|
154
165
|
const displayValue = key === "apiKey" ? maskString(value) : value;
|
|
155
166
|
printSuccess(`Set ${key} = ${displayValue}`);
|
|
167
|
+
if (clearedServer) {
|
|
168
|
+
printLabel("Note", "cleared 'server' (alias for baseUrl) so this change takes effect");
|
|
169
|
+
}
|
|
156
170
|
}
|
|
157
171
|
function handleConfigDelete(key) {
|
|
158
172
|
if (!isValidKey(key)) {
|
|
@@ -215,15 +229,23 @@ function handleConfigUse(environment) {
|
|
|
215
229
|
return;
|
|
216
230
|
}
|
|
217
231
|
configStore.set("baseUrl", url);
|
|
232
|
+
const clearedServer = configStore.has("server");
|
|
233
|
+
if (clearedServer) {
|
|
234
|
+
configStore.delete("server");
|
|
235
|
+
}
|
|
218
236
|
if (isJsonOutput()) {
|
|
219
237
|
printJson({
|
|
220
238
|
success: true,
|
|
221
239
|
environment: env,
|
|
222
|
-
baseUrl: url
|
|
240
|
+
baseUrl: url,
|
|
241
|
+
...clearedServer && { clearedServer: true }
|
|
223
242
|
});
|
|
224
243
|
return;
|
|
225
244
|
}
|
|
226
245
|
printSuccess(`Switched to ${env}: ${url}`);
|
|
246
|
+
if (clearedServer) {
|
|
247
|
+
printLabel("Note", "cleared 'server' (alias for baseUrl) so this change takes effect");
|
|
248
|
+
}
|
|
227
249
|
}
|
|
228
250
|
export {
|
|
229
251
|
createConfigCommand
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { configStore, type ChanlCliConfig } from '../utils/config-store.js';\nimport {\n printSuccess,\n printError,\n printLabel,\n printBlank,\n printTable,\n isJsonOutput,\n printJson,\n maskString,\n} from '../utils/output.js';\n\n/**\n * Valid configuration keys\n */\nconst VALID_KEYS: (keyof ChanlCliConfig)[] = [\n 'apiKey',\n 'baseUrl',\n 'workspaceId',\n 'defaultFormat',\n];\n\n/**\n * Environment presets for quick switching\n * Only production is exposed publicly. Use `chanl config set baseUrl <url>` for custom endpoints.\n */\nconst ENVIRONMENT_PRESETS: Record<string, string> = {\n production: 'https://platform.chanl.ai',\n};\n\n/**\n * Configuration key descriptions\n */\nconst KEY_DESCRIPTIONS: Record<keyof ChanlCliConfig, string> = {\n apiKey: 'Chanl API key for authentication',\n jwtToken: 'JWT access token (from browser login)',\n refreshToken: 'JWT refresh token (from browser login)',\n baseUrl: 'Base URL for the Chanl API',\n workspaceId: 'Default workspace ID',\n appUrl: 'App URL for browser-based flows',\n defaultFormat: 'Default output format (table or json)',\n};\n\n/**\n * Create the config command group\n */\nexport function createConfigCommand(): Command {\n const config = new Command('config').description('Manage CLI configuration');\n\n // `chanl config list` subcommand\n config\n .command('list')\n .description('List all configuration values')\n .action(handleConfigList);\n\n // `chanl config get <key>` subcommand\n config\n .command('get <key>')\n .description('Get a configuration value')\n .action(handleConfigGet);\n\n // `chanl config set <key> <value>` subcommand\n config\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action(handleConfigSet);\n\n // `chanl config delete <key>` subcommand\n config\n .command('delete <key>')\n .alias('unset')\n .description('Delete a configuration value')\n .action(handleConfigDelete);\n\n // `chanl config path` subcommand\n config\n .command('path')\n .description('Show path to configuration file')\n .action(handleConfigPath);\n\n // `chanl config use <environment>` subcommand\n config\n .command('use <environment>')\n .description('Reset to production API (or set a custom base URL with `config set baseUrl`)')\n .action(handleConfigUse);\n\n return config;\n}\n\n/**\n * Handle config list command\n */\nfunction handleConfigList(): void {\n const allConfig = configStore.getAll();\n\n if (isJsonOutput()) {\n // Mask sensitive values in JSON output\n const safeConfig = {\n ...allConfig,\n apiKey: allConfig.apiKey ? maskString(allConfig.apiKey) : undefined,\n };\n printJson(safeConfig);\n return;\n }\n\n printBlank();\n\n const rows = VALID_KEYS.map((key) => {\n let value = allConfig[key];\n const source = getConfigSource(key);\n\n // Mask API key\n if (key === 'apiKey' && typeof value === 'string') {\n value = maskString(value);\n }\n\n return {\n key,\n value: value ?? chalk.dim('(not set)'),\n source,\n description: KEY_DESCRIPTIONS[key],\n };\n });\n\n printTable(\n [\n { header: 'Key', key: 'key', width: 15 },\n { header: 'Value', key: 'value', width: 30 },\n { header: 'Source', key: 'source', width: 10 },\n ],\n rows\n );\n\n printBlank();\n printLabel('Config file', configStore.getPath());\n printBlank();\n}\n\n/**\n * Handle config get command\n */\nfunction handleConfigGet(key: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n let value: string | undefined;\n\n // Get value with env var fallback\n switch (typedKey) {\n case 'apiKey':\n value = configStore.getApiKey();\n break;\n case 'baseUrl':\n value = configStore.getBaseUrl();\n break;\n case 'workspaceId':\n value = configStore.getWorkspaceId();\n break;\n default:\n value = configStore.get(typedKey) as string | undefined;\n }\n\n if (isJsonOutput()) {\n printJson({\n key,\n value: key === 'apiKey' && value ? maskString(value) : value,\n source: getConfigSource(typedKey),\n });\n return;\n }\n\n if (value === undefined) {\n console.log(chalk.dim('(not set)'));\n return;\n }\n\n // Mask API key even in regular output\n if (key === 'apiKey') {\n console.log(maskString(value));\n } else {\n console.log(value);\n }\n}\n\n/**\n * Handle config set command\n */\nfunction handleConfigSet(key: string, value: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n\n // Validate specific keys\n if (typedKey === 'defaultFormat') {\n if (value !== 'table' && value !== 'json') {\n printError(`Invalid format: ${value}`);\n printLabel('Valid values', 'table, json');\n process.exitCode = 1;\n return;\n }\n }\n\n if (typedKey === 'baseUrl') {\n try {\n new URL(value);\n } catch {\n printError(`Invalid URL: ${value}`);\n process.exitCode = 1;\n return;\n }\n }\n\n // Set the value\n configStore.set(typedKey, value as never);\n\n if (isJsonOutput()) {\n printJson({\n success: true,\n key,\n value: key === 'apiKey' ? maskString(value) : value,\n });\n return;\n }\n\n const displayValue = key === 'apiKey' ? maskString(value) : value;\n printSuccess(`Set ${key} = ${displayValue}`);\n}\n\n/**\n * Handle config delete command\n */\nfunction handleConfigDelete(key: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n\n // Check if key exists\n if (!configStore.has(typedKey)) {\n if (isJsonOutput()) {\n printJson({ success: true, key, message: 'Key was not set' });\n } else {\n printSuccess(`${key} was not set`);\n }\n return;\n }\n\n configStore.delete(typedKey);\n\n if (isJsonOutput()) {\n printJson({ success: true, key, message: 'Deleted' });\n return;\n }\n\n printSuccess(`Deleted ${key}`);\n}\n\n/**\n * Handle config path command\n */\nfunction handleConfigPath(): void {\n const path = configStore.getPath();\n\n if (isJsonOutput()) {\n printJson({ path });\n return;\n }\n\n console.log(path);\n}\n\n/**\n * Check if a key is a valid configuration key\n */\nfunction isValidKey(key: string): key is keyof ChanlCliConfig {\n return VALID_KEYS.includes(key as keyof ChanlCliConfig);\n}\n\n/**\n * Get the source of a configuration value\n */\nfunction getConfigSource(key: keyof ChanlCliConfig): string {\n const envVarMap: Partial<Record<keyof ChanlCliConfig, string>> = {\n apiKey: 'CHANL_API_KEY',\n baseUrl: 'CHANL_BASE_URL',\n workspaceId: 'CHANL_WORKSPACE_ID',\n };\n\n const envVar = envVarMap[key];\n if (envVar && process.env[envVar]) {\n return chalk.cyan('env');\n }\n\n if (configStore.has(key)) {\n return chalk.green('config');\n }\n\n return chalk.dim('default');\n}\n\n/**\n * Handle config use command - switch to a preset environment\n */\nfunction handleConfigUse(environment: string): void {\n const env = environment.toLowerCase();\n const url = ENVIRONMENT_PRESETS[env];\n\n if (!url) {\n printError(`Unknown environment: ${environment}`);\n printBlank();\n printLabel('Available environments', Object.keys(ENVIRONMENT_PRESETS).join(', '));\n process.exitCode = 1;\n return;\n }\n\n configStore.set('baseUrl', url);\n\n if (isJsonOutput()) {\n printJson({\n success: true,\n environment: env,\n baseUrl: url,\n });\n return;\n }\n\n printSuccess(`Switched to ${env}: ${url}`);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/config.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { configStore, type ChanlCliConfig } from '../utils/config-store.js';\nimport {\n printSuccess,\n printError,\n printLabel,\n printBlank,\n printTable,\n isJsonOutput,\n printJson,\n maskString,\n} from '../utils/output.js';\n\n/**\n * Valid configuration keys\n */\nconst VALID_KEYS: (keyof ChanlCliConfig)[] = [\n 'apiKey',\n 'baseUrl',\n 'server',\n 'deployment',\n 'apiPrefix',\n 'workspaceId',\n 'defaultFormat',\n];\n\n/**\n * Environment presets for quick switching\n * Only production is exposed publicly. Use `chanl config set baseUrl <url>` for custom endpoints.\n */\nconst ENVIRONMENT_PRESETS: Record<string, string> = {\n production: 'https://platform.chanl.ai',\n};\n\n/**\n * Configuration key descriptions\n */\nconst KEY_DESCRIPTIONS: Record<keyof ChanlCliConfig, string> = {\n apiKey: 'Chanl API key for authentication',\n jwtToken: 'JWT access token (from browser login)',\n refreshToken: 'JWT refresh token (from browser login)',\n baseUrl: 'Base URL for the Chanl API',\n server: 'Alias for baseUrl (e.g. http://localhost:18005)',\n deployment: 'local | cloud — local rewrites /api/v1 paths for OSS scenario servers',\n apiPrefix: 'Override API prefix; empty string for flat /scenarios routes',\n workspaceId: 'Default workspace ID',\n appUrl: 'App URL for browser-based flows',\n defaultFormat: 'Default output format (table or json)',\n};\n\n/**\n * Create the config command group\n */\nexport function createConfigCommand(): Command {\n const config = new Command('config').description('Manage CLI configuration');\n\n // `chanl config list` subcommand\n config\n .command('list')\n .description('List all configuration values')\n .action(handleConfigList);\n\n // `chanl config get <key>` subcommand\n config\n .command('get <key>')\n .description('Get a configuration value')\n .action(handleConfigGet);\n\n // `chanl config set <key> <value>` subcommand\n config\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action(handleConfigSet);\n\n // `chanl config delete <key>` subcommand\n config\n .command('delete <key>')\n .alias('unset')\n .description('Delete a configuration value')\n .action(handleConfigDelete);\n\n // `chanl config path` subcommand\n config\n .command('path')\n .description('Show path to configuration file')\n .action(handleConfigPath);\n\n // `chanl config use <environment>` subcommand\n config\n .command('use <environment>')\n .description('Reset to production API (or set a custom base URL with `config set baseUrl`)')\n .action(handleConfigUse);\n\n return config;\n}\n\n/**\n * Handle config list command\n */\nfunction handleConfigList(): void {\n const allConfig = configStore.getAll();\n\n if (isJsonOutput()) {\n // Mask sensitive values in JSON output\n const safeConfig = {\n ...allConfig,\n apiKey: allConfig.apiKey ? maskString(allConfig.apiKey) : undefined,\n };\n printJson(safeConfig);\n return;\n }\n\n printBlank();\n\n const rows = VALID_KEYS.map((key) => {\n let value = allConfig[key];\n const source = getConfigSource(key);\n\n // Mask API key\n if (key === 'apiKey' && typeof value === 'string') {\n value = maskString(value);\n }\n\n return {\n key,\n value: value ?? chalk.dim('(not set)'),\n source,\n description: KEY_DESCRIPTIONS[key],\n };\n });\n\n printTable(\n [\n { header: 'Key', key: 'key', width: 15 },\n { header: 'Value', key: 'value', width: 30 },\n { header: 'Source', key: 'source', width: 10 },\n ],\n rows\n );\n\n printBlank();\n printLabel('Config file', configStore.getPath());\n printBlank();\n}\n\n/**\n * Handle config get command\n */\nfunction handleConfigGet(key: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n let value: string | undefined;\n\n // Get value with env var fallback\n switch (typedKey) {\n case 'apiKey':\n value = configStore.getApiKey();\n break;\n case 'baseUrl':\n value = configStore.getBaseUrl();\n break;\n case 'workspaceId':\n value = configStore.getWorkspaceId();\n break;\n default:\n value = configStore.get(typedKey) as string | undefined;\n }\n\n if (isJsonOutput()) {\n printJson({\n key,\n value: key === 'apiKey' && value ? maskString(value) : value,\n source: getConfigSource(typedKey),\n });\n return;\n }\n\n if (value === undefined) {\n console.log(chalk.dim('(not set)'));\n return;\n }\n\n // Mask API key even in regular output\n if (key === 'apiKey') {\n console.log(maskString(value));\n } else {\n console.log(value);\n }\n}\n\n/**\n * Handle config set command\n */\nfunction handleConfigSet(key: string, value: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n\n // Validate specific keys\n if (typedKey === 'defaultFormat') {\n if (value !== 'table' && value !== 'json') {\n printError(`Invalid format: ${value}`);\n printLabel('Valid values', 'table, json');\n process.exitCode = 1;\n return;\n }\n }\n\n if (typedKey === 'baseUrl') {\n try {\n new URL(value);\n } catch {\n printError(`Invalid URL: ${value}`);\n process.exitCode = 1;\n return;\n }\n }\n\n // Set the value\n configStore.set(typedKey, value as never);\n\n // `server` is an alias for `baseUrl` that takes priority in getBaseUrl().\n // Setting baseUrl while a stale `server` is still around would silently\n // have no effect, so clear it here to keep the two in sync.\n const clearedServer = typedKey === 'baseUrl' && configStore.has('server');\n if (clearedServer) {\n configStore.delete('server');\n }\n\n if (isJsonOutput()) {\n printJson({\n success: true,\n key,\n value: key === 'apiKey' ? maskString(value) : value,\n ...(clearedServer && { clearedServer: true }),\n });\n return;\n }\n\n const displayValue = key === 'apiKey' ? maskString(value) : value;\n printSuccess(`Set ${key} = ${displayValue}`);\n if (clearedServer) {\n printLabel('Note', \"cleared 'server' (alias for baseUrl) so this change takes effect\");\n }\n}\n\n/**\n * Handle config delete command\n */\nfunction handleConfigDelete(key: string): void {\n if (!isValidKey(key)) {\n printError(`Unknown configuration key: ${key}`);\n printBlank();\n printLabel('Valid keys', VALID_KEYS.join(', '));\n process.exitCode = 1;\n return;\n }\n\n const typedKey = key as keyof ChanlCliConfig;\n\n // Check if key exists\n if (!configStore.has(typedKey)) {\n if (isJsonOutput()) {\n printJson({ success: true, key, message: 'Key was not set' });\n } else {\n printSuccess(`${key} was not set`);\n }\n return;\n }\n\n configStore.delete(typedKey);\n\n if (isJsonOutput()) {\n printJson({ success: true, key, message: 'Deleted' });\n return;\n }\n\n printSuccess(`Deleted ${key}`);\n}\n\n/**\n * Handle config path command\n */\nfunction handleConfigPath(): void {\n const path = configStore.getPath();\n\n if (isJsonOutput()) {\n printJson({ path });\n return;\n }\n\n console.log(path);\n}\n\n/**\n * Check if a key is a valid configuration key\n */\nfunction isValidKey(key: string): key is keyof ChanlCliConfig {\n return VALID_KEYS.includes(key as keyof ChanlCliConfig);\n}\n\n/**\n * Get the source of a configuration value\n */\nfunction getConfigSource(key: keyof ChanlCliConfig): string {\n const envVarMap: Partial<Record<keyof ChanlCliConfig, string>> = {\n apiKey: 'CHANL_API_KEY',\n baseUrl: 'CHANL_BASE_URL',\n workspaceId: 'CHANL_WORKSPACE_ID',\n };\n\n const envVar = envVarMap[key];\n if (envVar && process.env[envVar]) {\n return chalk.cyan('env');\n }\n\n if (configStore.has(key)) {\n return chalk.green('config');\n }\n\n return chalk.dim('default');\n}\n\n/**\n * Handle config use command - switch to a preset environment\n */\nfunction handleConfigUse(environment: string): void {\n const env = environment.toLowerCase();\n const url = ENVIRONMENT_PRESETS[env];\n\n if (!url) {\n printError(`Unknown environment: ${environment}`);\n printBlank();\n printLabel('Available environments', Object.keys(ENVIRONMENT_PRESETS).join(', '));\n process.exitCode = 1;\n return;\n }\n\n configStore.set('baseUrl', url);\n\n // Same reasoning as `config set baseUrl`: `server` overrides baseUrl in\n // getBaseUrl(), so leaving a stale `server` in place would make this\n // command a no-op from the caller's perspective.\n const clearedServer = configStore.has('server');\n if (clearedServer) {\n configStore.delete('server');\n }\n\n if (isJsonOutput()) {\n printJson({\n success: true,\n environment: env,\n baseUrl: url,\n ...(clearedServer && { clearedServer: true }),\n });\n return;\n }\n\n printSuccess(`Switched to ${env}: ${url}`);\n if (clearedServer) {\n printLabel('Note', \"cleared 'server' (alias for baseUrl) so this change takes effect\");\n }\n}\n"],"mappings":"AAAA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,SAAS,mBAAwC;AACjD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP,MAAM,aAAuC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMA,MAAM,sBAA8C;AAAA,EAClD,YAAY;AACd;AAKA,MAAM,mBAAyD;AAAA,EAC7D,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc;AAAA,EACd,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,eAAe;AACjB;AAKO,SAAS,sBAA+B;AAC7C,QAAM,SAAS,IAAI,QAAQ,QAAQ,EAAE,YAAY,0BAA0B;AAG3E,SACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,gBAAgB;AAG1B,SACG,QAAQ,WAAW,EACnB,YAAY,2BAA2B,EACvC,OAAO,eAAe;AAGzB,SACG,QAAQ,mBAAmB,EAC3B,YAAY,2BAA2B,EACvC,OAAO,eAAe;AAGzB,SACG,QAAQ,cAAc,EACtB,MAAM,OAAO,EACb,YAAY,8BAA8B,EAC1C,OAAO,kBAAkB;AAG5B,SACG,QAAQ,MAAM,EACd,YAAY,iCAAiC,EAC7C,OAAO,gBAAgB;AAG1B,SACG,QAAQ,mBAAmB,EAC3B,YAAY,8EAA8E,EAC1F,OAAO,eAAe;AAEzB,SAAO;AACT;AAKA,SAAS,mBAAyB;AAChC,QAAM,YAAY,YAAY,OAAO;AAErC,MAAI,aAAa,GAAG;AAElB,UAAM,aAAa;AAAA,MACjB,GAAG;AAAA,MACH,QAAQ,UAAU,SAAS,WAAW,UAAU,MAAM,IAAI;AAAA,IAC5D;AACA,cAAU,UAAU;AACpB;AAAA,EACF;AAEA,aAAW;AAEX,QAAM,OAAO,WAAW,IAAI,CAAC,QAAQ;AACnC,QAAI,QAAQ,UAAU,GAAG;AACzB,UAAM,SAAS,gBAAgB,GAAG;AAGlC,QAAI,QAAQ,YAAY,OAAO,UAAU,UAAU;AACjD,cAAQ,WAAW,KAAK;AAAA,IAC1B;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO,SAAS,MAAM,IAAI,WAAW;AAAA,MACrC;AAAA,MACA,aAAa,iBAAiB,GAAG;AAAA,IACnC;AAAA,EACF,CAAC;AAED;AAAA,IACE;AAAA,MACE,EAAE,QAAQ,OAAO,KAAK,OAAO,OAAO,GAAG;AAAA,MACvC,EAAE,QAAQ,SAAS,KAAK,SAAS,OAAO,GAAG;AAAA,MAC3C,EAAE,QAAQ,UAAU,KAAK,UAAU,OAAO,GAAG;AAAA,IAC/C;AAAA,IACA;AAAA,EACF;AAEA,aAAW;AACX,aAAW,eAAe,YAAY,QAAQ,CAAC;AAC/C,aAAW;AACb;AAKA,SAAS,gBAAgB,KAAmB;AAC1C,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,eAAW,8BAA8B,GAAG,EAAE;AAC9C,eAAW;AACX,eAAW,cAAc,WAAW,KAAK,IAAI,CAAC;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,WAAW;AACjB,MAAI;AAGJ,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,cAAQ,YAAY,UAAU;AAC9B;AAAA,IACF,KAAK;AACH,cAAQ,YAAY,WAAW;AAC/B;AAAA,IACF,KAAK;AACH,cAAQ,YAAY,eAAe;AACnC;AAAA,IACF;AACE,cAAQ,YAAY,IAAI,QAAQ;AAAA,EACpC;AAEA,MAAI,aAAa,GAAG;AAClB,cAAU;AAAA,MACR;AAAA,MACA,OAAO,QAAQ,YAAY,QAAQ,WAAW,KAAK,IAAI;AAAA,MACvD,QAAQ,gBAAgB,QAAQ;AAAA,IAClC,CAAC;AACD;AAAA,EACF;AAEA,MAAI,UAAU,QAAW;AACvB,YAAQ,IAAI,MAAM,IAAI,WAAW,CAAC;AAClC;AAAA,EACF;AAGA,MAAI,QAAQ,UAAU;AACpB,YAAQ,IAAI,WAAW,KAAK,CAAC;AAAA,EAC/B,OAAO;AACL,YAAQ,IAAI,KAAK;AAAA,EACnB;AACF;AAKA,SAAS,gBAAgB,KAAa,OAAqB;AACzD,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,eAAW,8BAA8B,GAAG,EAAE;AAC9C,eAAW;AACX,eAAW,cAAc,WAAW,KAAK,IAAI,CAAC;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,WAAW;AAGjB,MAAI,aAAa,iBAAiB;AAChC,QAAI,UAAU,WAAW,UAAU,QAAQ;AACzC,iBAAW,mBAAmB,KAAK,EAAE;AACrC,iBAAW,gBAAgB,aAAa;AACxC,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,WAAW;AAC1B,QAAI;AACF,UAAI,IAAI,KAAK;AAAA,IACf,QAAQ;AACN,iBAAW,gBAAgB,KAAK,EAAE;AAClC,cAAQ,WAAW;AACnB;AAAA,IACF;AAAA,EACF;AAGA,cAAY,IAAI,UAAU,KAAc;AAKxC,QAAM,gBAAgB,aAAa,aAAa,YAAY,IAAI,QAAQ;AACxE,MAAI,eAAe;AACjB,gBAAY,OAAO,QAAQ;AAAA,EAC7B;AAEA,MAAI,aAAa,GAAG;AAClB,cAAU;AAAA,MACR,SAAS;AAAA,MACT;AAAA,MACA,OAAO,QAAQ,WAAW,WAAW,KAAK,IAAI;AAAA,MAC9C,GAAI,iBAAiB,EAAE,eAAe,KAAK;AAAA,IAC7C,CAAC;AACD;AAAA,EACF;AAEA,QAAM,eAAe,QAAQ,WAAW,WAAW,KAAK,IAAI;AAC5D,eAAa,OAAO,GAAG,MAAM,YAAY,EAAE;AAC3C,MAAI,eAAe;AACjB,eAAW,QAAQ,kEAAkE;AAAA,EACvF;AACF;AAKA,SAAS,mBAAmB,KAAmB;AAC7C,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,eAAW,8BAA8B,GAAG,EAAE;AAC9C,eAAW;AACX,eAAW,cAAc,WAAW,KAAK,IAAI,CAAC;AAC9C,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,WAAW;AAGjB,MAAI,CAAC,YAAY,IAAI,QAAQ,GAAG;AAC9B,QAAI,aAAa,GAAG;AAClB,gBAAU,EAAE,SAAS,MAAM,KAAK,SAAS,kBAAkB,CAAC;AAAA,IAC9D,OAAO;AACL,mBAAa,GAAG,GAAG,cAAc;AAAA,IACnC;AACA;AAAA,EACF;AAEA,cAAY,OAAO,QAAQ;AAE3B,MAAI,aAAa,GAAG;AAClB,cAAU,EAAE,SAAS,MAAM,KAAK,SAAS,UAAU,CAAC;AACpD;AAAA,EACF;AAEA,eAAa,WAAW,GAAG,EAAE;AAC/B;AAKA,SAAS,mBAAyB;AAChC,QAAM,OAAO,YAAY,QAAQ;AAEjC,MAAI,aAAa,GAAG;AAClB,cAAU,EAAE,KAAK,CAAC;AAClB;AAAA,EACF;AAEA,UAAQ,IAAI,IAAI;AAClB;AAKA,SAAS,WAAW,KAA0C;AAC5D,SAAO,WAAW,SAAS,GAA2B;AACxD;AAKA,SAAS,gBAAgB,KAAmC;AAC1D,QAAM,YAA2D;AAAA,IAC/D,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAEA,QAAM,SAAS,UAAU,GAAG;AAC5B,MAAI,UAAU,QAAQ,IAAI,MAAM,GAAG;AACjC,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB;AAEA,MAAI,YAAY,IAAI,GAAG,GAAG;AACxB,WAAO,MAAM,MAAM,QAAQ;AAAA,EAC7B;AAEA,SAAO,MAAM,IAAI,SAAS;AAC5B;AAKA,SAAS,gBAAgB,aAA2B;AAClD,QAAM,MAAM,YAAY,YAAY;AACpC,QAAM,MAAM,oBAAoB,GAAG;AAEnC,MAAI,CAAC,KAAK;AACR,eAAW,wBAAwB,WAAW,EAAE;AAChD,eAAW;AACX,eAAW,0BAA0B,OAAO,KAAK,mBAAmB,EAAE,KAAK,IAAI,CAAC;AAChF,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,cAAY,IAAI,WAAW,GAAG;AAK9B,QAAM,gBAAgB,YAAY,IAAI,QAAQ;AAC9C,MAAI,eAAe;AACjB,gBAAY,OAAO,QAAQ;AAAA,EAC7B;AAEA,MAAI,aAAa,GAAG;AAClB,cAAU;AAAA,MACR,SAAS;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,GAAI,iBAAiB,EAAE,eAAe,KAAK;AAAA,IAC7C,CAAC;AACD;AAAA,EACF;AAEA,eAAa,eAAe,GAAG,KAAK,GAAG,EAAE;AACzC,MAAI,eAAe;AACjB,eAAW,QAAQ,kEAAkE;AAAA,EACvF;AACF;","names":[]}
|
package/dist/commands/memory.js
CHANGED
|
@@ -71,15 +71,32 @@ Examples:
|
|
|
71
71
|
$ chanl memory delete 680a1b2c3d4e5f6789012345 # With confirmation
|
|
72
72
|
$ chanl memory delete 680a1b2c3d4e5f6789012345 -y # Skip confirmation`
|
|
73
73
|
).action(handleMemoryDelete);
|
|
74
|
-
memory.command("search").description("Search memories using semantic similarity").option("--entity-type <type>", "Entity type (required): customer, session, agent, conversation").option("--entity-id <id>", "Entity ID (required)").option("--query <text>", "Search query text (required)").option("--agent-id <id>", "Optional agent scope filter").option("-l, --limit <number>", "Maximum results").option("--min-score <number>", "Minimum relevance score (0-1)").addHelpText(
|
|
74
|
+
memory.command("search").description("Search memories using semantic similarity").option("--entity-type <type>", "Entity type (required): customer, session, agent, conversation").option("--entity-id <id>", "Entity ID (required)").option("--query <text>", "Search query text (required)").option("--agent-id <id>", "Optional agent scope filter").option("-l, --limit <number>", "Maximum results").option("--min-score <number>", "Minimum relevance score (0-1)").option("--min-confidence <number>", "Minimum extraction confidence (0-1)").option("--created-after <iso>", "Only memories created at/after this ISO-8601 timestamp").option("--created-before <iso>", "Only memories created at/before this ISO-8601 timestamp").addHelpText(
|
|
75
75
|
"after",
|
|
76
76
|
`
|
|
77
77
|
Examples:
|
|
78
78
|
$ chanl memory search --entity-type customer --entity-id cust_123 --query "email preferences"
|
|
79
79
|
$ chanl memory search --entity-type customer --entity-id cust_123 --query "contact" --limit 5
|
|
80
80
|
$ chanl memory search --entity-type customer --entity-id cust_123 --query "VIP" --min-score 0.8
|
|
81
|
+
$ chanl memory search --entity-type customer --entity-id cust_123 --query "recent" --created-after 2026-05-01T00:00:00Z
|
|
81
82
|
$ chanl memory search --entity-type customer --entity-id cust_123 --query "test" --json`
|
|
82
83
|
).action(handleMemorySearch);
|
|
84
|
+
memory.command("search-global").description("Search ALL memories in the workspace (no entity scope)").option("--query <text>", "Search query text (required)").option("--entity-type <type>", "Optional: narrow to an entity type").option("--agent-id <id>", "Optional agent scope filter").option("--source <source>", "Filter by source: conversation, manual, extraction").option("-l, --limit <number>", "Maximum results").option("--min-score <number>", "Minimum relevance score (0-1)").addHelpText(
|
|
85
|
+
"after",
|
|
86
|
+
`
|
|
87
|
+
Examples:
|
|
88
|
+
$ chanl memory search-global --query "billing preferences"
|
|
89
|
+
$ chanl memory search-global --query "VIP" --entity-type customer --limit 10
|
|
90
|
+
$ chanl memory search-global --query "test" --json`
|
|
91
|
+
).action(handleMemorySearchGlobal);
|
|
92
|
+
memory.command("stats").description("Aggregate memory statistics (totals, by type/source, top-accessed)").option("--entity-type <type>", "Optionally scope stats to an entity type").option("--entity-id <id>", "Optionally scope stats to an entity ID").addHelpText(
|
|
93
|
+
"after",
|
|
94
|
+
`
|
|
95
|
+
Examples:
|
|
96
|
+
$ chanl memory stats # Workspace-wide
|
|
97
|
+
$ chanl memory stats --entity-type customer --entity-id cust_123
|
|
98
|
+
$ chanl memory stats --json`
|
|
99
|
+
).action(handleMemoryStats);
|
|
83
100
|
return memory;
|
|
84
101
|
}
|
|
85
102
|
function truncate(str, maxLen) {
|
|
@@ -336,6 +353,15 @@ async function handleMemorySearch(options) {
|
|
|
336
353
|
if (options.minScore) {
|
|
337
354
|
input.minScore = parseFloat(options.minScore);
|
|
338
355
|
}
|
|
356
|
+
if (options.minConfidence) {
|
|
357
|
+
input.minConfidence = parseFloat(options.minConfidence);
|
|
358
|
+
}
|
|
359
|
+
if (options.createdAfter) {
|
|
360
|
+
input.createdAfter = options.createdAfter;
|
|
361
|
+
}
|
|
362
|
+
if (options.createdBefore) {
|
|
363
|
+
input.createdBefore = options.createdBefore;
|
|
364
|
+
}
|
|
339
365
|
const spinner = ora("Searching memories...").start();
|
|
340
366
|
try {
|
|
341
367
|
const response = await sdk.memory.search(input);
|
|
@@ -374,6 +400,113 @@ async function handleMemorySearch(options) {
|
|
|
374
400
|
process.exitCode = 1;
|
|
375
401
|
}
|
|
376
402
|
}
|
|
403
|
+
async function handleMemorySearchGlobal(options) {
|
|
404
|
+
if (!options.query) {
|
|
405
|
+
printError("Missing required option", "Provide --query");
|
|
406
|
+
printInfo("Run 'chanl memory search-global --help' for usage");
|
|
407
|
+
process.exitCode = 1;
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const sdk = createSdk();
|
|
411
|
+
if (!sdk) return;
|
|
412
|
+
const input = { query: options.query };
|
|
413
|
+
if (options.entityType) input.entityType = options.entityType;
|
|
414
|
+
if (options.agentId) input.agentId = options.agentId;
|
|
415
|
+
if (options.source) input.source = options.source;
|
|
416
|
+
if (options.limit) input.limit = parseInt(options.limit, 10);
|
|
417
|
+
if (options.minScore) input.minScore = parseFloat(options.minScore);
|
|
418
|
+
const spinner = ora("Searching all memories...").start();
|
|
419
|
+
try {
|
|
420
|
+
const response = await sdk.memory.searchGlobal(input);
|
|
421
|
+
spinner.stop();
|
|
422
|
+
if (!response.success || !response.data) {
|
|
423
|
+
printError("Failed to search memories", response.message);
|
|
424
|
+
process.exitCode = 1;
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const { memories } = response.data;
|
|
428
|
+
if (isJsonOutput()) {
|
|
429
|
+
printJson({ memories });
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (memories.length === 0) {
|
|
433
|
+
printInfo("No matching memories found");
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
printBlank();
|
|
437
|
+
printSimpleTable(
|
|
438
|
+
["ID", "Score", "Content", "Entity Type", "Entity ID"],
|
|
439
|
+
memories.map((m) => [
|
|
440
|
+
truncate(m.id, 12),
|
|
441
|
+
(m.score ?? 0).toFixed(2),
|
|
442
|
+
truncate(m.content, 50),
|
|
443
|
+
m.entityType,
|
|
444
|
+
m.entityId
|
|
445
|
+
])
|
|
446
|
+
);
|
|
447
|
+
printBlank();
|
|
448
|
+
printInfo(`Found ${memories.length} matching memories`);
|
|
449
|
+
} catch (error) {
|
|
450
|
+
spinner.fail("Failed to search memories");
|
|
451
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
452
|
+
printError("Error", message);
|
|
453
|
+
process.exitCode = 1;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async function handleMemoryStats(options) {
|
|
457
|
+
const sdk = createSdk();
|
|
458
|
+
if (!sdk) return;
|
|
459
|
+
const spinner = ora("Aggregating memory stats...").start();
|
|
460
|
+
try {
|
|
461
|
+
const response = await sdk.memory.stats({
|
|
462
|
+
entityType: options.entityType,
|
|
463
|
+
entityId: options.entityId
|
|
464
|
+
});
|
|
465
|
+
spinner.stop();
|
|
466
|
+
if (!response.success || !response.data) {
|
|
467
|
+
printError("Failed to fetch memory stats", response.message);
|
|
468
|
+
process.exitCode = 1;
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const stats = response.data;
|
|
472
|
+
if (isJsonOutput()) {
|
|
473
|
+
printJson(stats);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
printBlank();
|
|
477
|
+
printLabel("Total", String(stats.total));
|
|
478
|
+
printLabel("Active", chalk.green(String(stats.active)));
|
|
479
|
+
printLabel("Inactive", String(stats.inactive));
|
|
480
|
+
printLabel("Expired", stats.expired > 0 ? chalk.yellow(String(stats.expired)) : "0");
|
|
481
|
+
printLabel("Avg confidence", stats.avgConfidence.toFixed(3));
|
|
482
|
+
printBlank();
|
|
483
|
+
printInfo("By type:");
|
|
484
|
+
printSimpleTable(
|
|
485
|
+
["Entity Type", "Count"],
|
|
486
|
+
Object.entries(stats.byType).map(([k, v]) => [k, String(v)])
|
|
487
|
+
);
|
|
488
|
+
printBlank();
|
|
489
|
+
printInfo("By source:");
|
|
490
|
+
printSimpleTable(
|
|
491
|
+
["Source", "Count"],
|
|
492
|
+
Object.entries(stats.bySource).map(([k, v]) => [k, String(v)])
|
|
493
|
+
);
|
|
494
|
+
if (stats.topAccessed.length > 0) {
|
|
495
|
+
printBlank();
|
|
496
|
+
printInfo("Top accessed:");
|
|
497
|
+
printSimpleTable(
|
|
498
|
+
["ID", "Access Count", "Content"],
|
|
499
|
+
stats.topAccessed.map((t) => [truncate(t.id, 12), String(t.accessCount), truncate(t.content, 50)])
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
printBlank();
|
|
503
|
+
} catch (error) {
|
|
504
|
+
spinner.fail("Failed to fetch memory stats");
|
|
505
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
506
|
+
printError("Error", message);
|
|
507
|
+
process.exitCode = 1;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
377
510
|
function printMemoryDetails(memory) {
|
|
378
511
|
printLabel("ID", memory.id);
|
|
379
512
|
printLabel("Entity Type", memory.entityType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/memory.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFile } from 'fs/promises';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport type {\n Memory,\n MemorySearchResult,\n CreateMemoryInput,\n UpdateMemoryInput,\n SearchMemoryInput,\n MemoryEntityType,\n MemorySource,\n} from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the memory command group\n */\nexport function createMemoryCommand(): Command {\n const memory = new Command('memory').description('Manage agent memory');\n\n // memory list\n memory\n .command('list')\n .description('List memories with optional filters')\n .option('--entity-type <type>', 'Filter by entity type: customer, session, agent, conversation')\n .option('--entity-id <id>', 'Filter by entity ID')\n .option('--agent-id <id>', 'Filter by agent ID')\n .option('--source <source>', 'Filter by source: conversation, manual, extraction')\n .option('-l, --limit <number>', 'Items per page (default: 20)', '20')\n .option('-p, --page <number>', 'Page number (default: 1)', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory list # List all memories\n $ chanl memory list --entity-type customer # Filter by entity type\n $ chanl memory list --entity-id cust_123 --limit 10 # Filter by entity ID\n $ chanl memory list --agent-id agent_abc # Filter by agent\n $ chanl memory list --source manual # Filter by source\n $ chanl memory list --json # Output as JSON`\n )\n .action(handleMemoryList);\n\n // memory get <id>\n memory\n .command('get <id>')\n .description('Get detailed info about a memory')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory get 680a1b2c3d4e5f6789012345\n $ chanl memory get 680a1b2c3d4e5f6789012345 --json`\n )\n .action(handleMemoryGet);\n\n // memory create\n memory\n .command('create')\n .description('Create a new memory')\n .option('--entity-type <type>', 'Entity type: customer, session, agent, conversation')\n .option('--entity-id <id>', 'Entity ID')\n .option('--content <text>', 'Memory content text')\n .option('--agent-id <id>', 'Optional agent scope')\n .option('--source <source>', 'Source: conversation, manual, extraction')\n .option('--ttl <seconds>', 'Time-to-live in seconds')\n .option('-f, --file <path>', 'Path to JSON file with memory definition (overrides other options)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"Prefers email\"\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"VIP\" --source manual\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"Note\" --ttl 86400\n $ chanl memory create -f memory.json\n\nRequired (unless using -f):\n --entity-type Entity type\n --entity-id Entity ID\n --content Memory content text\n\nOptional:\n --agent-id Scope to a specific agent\n --source Memory source (sets metadata.source)\n --ttl TTL in seconds\n -f, --file JSON file (overrides all other options)`\n )\n .action(handleMemoryCreate);\n\n // memory update <id>\n memory\n .command('update <id>')\n .description('Update an existing memory')\n .option('--content <text>', 'Updated content text')\n .option('--deactivate', 'Deactivate the memory (sets isActive: false)')\n .option('--activate', 'Reactivate the memory (sets isActive: true)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory update 680a1b2c3d4e5f6789012345 --content \"Updated preference\"\n $ chanl memory update 680a1b2c3d4e5f6789012345 --deactivate\n $ chanl memory update 680a1b2c3d4e5f6789012345 --activate\n $ chanl memory update 680a1b2c3d4e5f6789012345 --content \"New text\" --deactivate`\n )\n .action(handleMemoryUpdate);\n\n // memory delete <id>\n memory\n .command('delete <id>')\n .description('Delete a memory permanently')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory delete 680a1b2c3d4e5f6789012345 # With confirmation\n $ chanl memory delete 680a1b2c3d4e5f6789012345 -y # Skip confirmation`\n )\n .action(handleMemoryDelete);\n\n // memory search\n memory\n .command('search')\n .description('Search memories using semantic similarity')\n .option('--entity-type <type>', 'Entity type (required): customer, session, agent, conversation')\n .option('--entity-id <id>', 'Entity ID (required)')\n .option('--query <text>', 'Search query text (required)')\n .option('--agent-id <id>', 'Optional agent scope filter')\n .option('-l, --limit <number>', 'Maximum results')\n .option('--min-score <number>', 'Minimum relevance score (0-1)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"email preferences\"\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"contact\" --limit 5\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"VIP\" --min-score 0.8\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"test\" --json`\n )\n .action(handleMemorySearch);\n\n return memory;\n}\n\n// ============================================================================\n// Helpers (module-local)\n// ============================================================================\n\n/**\n * Truncate a string to a max length, appending '...' if truncated\n */\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.substring(0, maxLen - 3) + '...';\n}\n\n// ============================================================================\n// Command Handlers\n// ============================================================================\n\n/**\n * Handle memory list command\n */\nasync function handleMemoryList(options: {\n entityType?: string;\n entityId?: string;\n agentId?: string;\n source?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching memories...').start();\n\n try {\n const response = await sdk.memory.list({\n entityType: options.entityType as MemoryEntityType | undefined,\n entityId: options.entityId,\n agentId: options.agentId,\n source: options.source as MemorySource | undefined,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch memories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { memories, total, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson({ memories, total, pagination });\n return;\n }\n\n if (memories.length === 0) {\n printInfo('No memories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Entity Type', 'Entity ID', 'Content', 'Source', 'Active', 'Created'],\n memories.map((m: Memory) => [\n truncate(m.id, 12),\n m.entityType,\n m.entityId,\n truncate(m.content, 50),\n m.metadata?.source || 'unknown',\n m.isActive ? chalk.green('Yes') : chalk.red('No'),\n formatDate(m.createdAt),\n ])\n );\n\n printBlank();\n if (pagination) {\n printInfo(`Total: ${total} memories (Page ${pagination.page} of ${pagination.totalPages})`);\n } else {\n printInfo(`Total: ${total} memories`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch memories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory get command\n */\nasync function handleMemoryGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching memory...').start();\n\n try {\n const response = await sdk.memory.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson(memory);\n return;\n }\n\n printBlank();\n printMemoryDetails(memory);\n } catch (error) {\n spinner.fail('Failed to fetch memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory create command\n */\nasync function handleMemoryCreate(options: {\n entityType?: string;\n entityId?: string;\n content?: string;\n agentId?: string;\n source?: string;\n ttl?: string;\n file?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let input: CreateMemoryInput;\n\n if (options.file) {\n // Read from JSON file\n try {\n const content = await readFile(options.file, 'utf-8');\n input = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else {\n // Build from individual options\n if (!options.entityType || !options.entityId || !options.content) {\n printError(\n 'Missing required options',\n \"Provide --entity-type, --entity-id, and --content, or use '-f <path>' for JSON file\"\n );\n printInfo(\"Run 'chanl memory create --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n input = {\n entityType: options.entityType as MemoryEntityType,\n entityId: options.entityId,\n content: options.content,\n };\n\n if (options.agentId) {\n input.agentId = options.agentId;\n }\n\n if (options.source) {\n input.metadata = { ...input.metadata, source: options.source as MemorySource };\n }\n\n if (options.ttl) {\n const ttl = parseInt(options.ttl, 10);\n if (isNaN(ttl) || ttl <= 0) {\n printError('Invalid TTL value', 'TTL must be a positive number of seconds');\n process.exitCode = 1;\n return;\n }\n input.ttlSeconds = ttl;\n }\n }\n\n const spinner = ora('Creating memory...').start();\n\n try {\n const response = await sdk.memory.create(input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, memory });\n return;\n }\n\n printSuccess(`Created memory: ${memory.id}`);\n } catch (error) {\n spinner.fail('Failed to create memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory update command\n */\nasync function handleMemoryUpdate(\n id: string,\n options: {\n content?: string;\n deactivate?: boolean;\n activate?: boolean;\n }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const input: UpdateMemoryInput = {};\n\n if (options.content) {\n input.content = options.content;\n }\n\n if (options.deactivate) {\n input.isActive = false;\n }\n\n if (options.activate) {\n input.isActive = true;\n }\n\n if (!options.content && !options.deactivate && !options.activate) {\n printError('No updates specified', 'Provide --content, --deactivate, or --activate');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Updating memory...').start();\n\n try {\n const response = await sdk.memory.update(id, input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, memory });\n return;\n }\n\n printSuccess(`Updated memory: ${memory.id}`);\n } catch (error) {\n spinner.fail('Failed to update memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory delete command\n */\nasync function handleMemoryDelete(id: string, options: { yes?: boolean }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Confirm deletion unless --yes flag is provided\n if (!options.yes) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete memory '${id}'?`,\n default: false,\n });\n\n if (!confirmed) {\n printInfo('Deletion cancelled');\n return;\n }\n } catch {\n // User cancelled (Ctrl+C)\n printBlank();\n printInfo('Deletion cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting memory...').start();\n\n try {\n const response = await sdk.memory.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: true, id });\n return;\n }\n\n printSuccess(`Deleted memory: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory search command\n */\nasync function handleMemorySearch(options: {\n entityType?: string;\n entityId?: string;\n query?: string;\n agentId?: string;\n limit?: string;\n minScore?: string;\n}): Promise<void> {\n if (!options.entityType || !options.entityId || !options.query) {\n printError('Missing required options', 'Provide --entity-type, --entity-id, and --query');\n printInfo(\"Run 'chanl memory search --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n const input: SearchMemoryInput = {\n entityType: options.entityType as MemoryEntityType,\n entityId: options.entityId,\n query: options.query,\n };\n\n if (options.agentId) {\n input.agentId = options.agentId;\n }\n\n if (options.limit) {\n input.limit = parseInt(options.limit, 10);\n }\n\n if (options.minScore) {\n input.minScore = parseFloat(options.minScore);\n }\n\n const spinner = ora('Searching memories...').start();\n\n try {\n const response = await sdk.memory.search(input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to search memories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { memories } = response.data;\n\n if (isJsonOutput()) {\n printJson({ memories });\n return;\n }\n\n if (memories.length === 0) {\n printInfo('No matching memories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Score', 'Content', 'Entity Type', 'Entity ID'],\n memories.map((m: MemorySearchResult) => [\n truncate(m.id, 12),\n (m.score ?? 0).toFixed(2),\n truncate(m.content, 50),\n m.entityType,\n m.entityId,\n ])\n );\n\n printBlank();\n printInfo(`Found ${memories.length} matching memories`);\n } catch (error) {\n spinner.fail('Failed to search memories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n// ============================================================================\n// Display Helpers\n// ============================================================================\n\n/**\n * Print memory details in formatted output\n */\nfunction printMemoryDetails(memory: Memory): void {\n printLabel('ID', memory.id);\n printLabel('Entity Type', memory.entityType);\n printLabel('Entity ID', memory.entityId);\n\n printBlank();\n printInfo('Content:');\n console.log(chalk.gray(memory.content));\n\n if (memory.agentId) {\n printBlank();\n printLabel('Agent ID', memory.agentId);\n }\n\n printBlank();\n printLabel('Active', memory.isActive ? chalk.green('Yes') : chalk.red('No'));\n\n if (memory.metadata && Object.keys(memory.metadata).length > 0) {\n printBlank();\n printInfo('Metadata:');\n console.log(chalk.gray(JSON.stringify(memory.metadata, null, 2)));\n }\n\n if (memory.expiresAt) {\n printLabel('Expires', formatDate(memory.expiresAt));\n }\n\n printBlank();\n printLabel('Created', formatDate(memory.createdAt));\n if (memory.updatedAt) {\n printLabel('Updated', formatDate(memory.updatedAt));\n }\n printBlank();\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/memory.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFile } from 'fs/promises';\nimport { confirm } from '@inquirer/prompts';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport type {\n Memory,\n MemorySearchResult,\n CreateMemoryInput,\n UpdateMemoryInput,\n SearchMemoryInput,\n GlobalSearchMemoryInput,\n MemoryStats,\n MemoryEntityType,\n MemorySource,\n} from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printSuccess,\n printError,\n printInfo,\n printLabel,\n printBlank,\n printSimpleTable,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the memory command group\n */\nexport function createMemoryCommand(): Command {\n const memory = new Command('memory').description('Manage agent memory');\n\n // memory list\n memory\n .command('list')\n .description('List memories with optional filters')\n .option('--entity-type <type>', 'Filter by entity type: customer, session, agent, conversation')\n .option('--entity-id <id>', 'Filter by entity ID')\n .option('--agent-id <id>', 'Filter by agent ID')\n .option('--source <source>', 'Filter by source: conversation, manual, extraction')\n .option('-l, --limit <number>', 'Items per page (default: 20)', '20')\n .option('-p, --page <number>', 'Page number (default: 1)', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory list # List all memories\n $ chanl memory list --entity-type customer # Filter by entity type\n $ chanl memory list --entity-id cust_123 --limit 10 # Filter by entity ID\n $ chanl memory list --agent-id agent_abc # Filter by agent\n $ chanl memory list --source manual # Filter by source\n $ chanl memory list --json # Output as JSON`\n )\n .action(handleMemoryList);\n\n // memory get <id>\n memory\n .command('get <id>')\n .description('Get detailed info about a memory')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory get 680a1b2c3d4e5f6789012345\n $ chanl memory get 680a1b2c3d4e5f6789012345 --json`\n )\n .action(handleMemoryGet);\n\n // memory create\n memory\n .command('create')\n .description('Create a new memory')\n .option('--entity-type <type>', 'Entity type: customer, session, agent, conversation')\n .option('--entity-id <id>', 'Entity ID')\n .option('--content <text>', 'Memory content text')\n .option('--agent-id <id>', 'Optional agent scope')\n .option('--source <source>', 'Source: conversation, manual, extraction')\n .option('--ttl <seconds>', 'Time-to-live in seconds')\n .option('-f, --file <path>', 'Path to JSON file with memory definition (overrides other options)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"Prefers email\"\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"VIP\" --source manual\n $ chanl memory create --entity-type customer --entity-id cust_123 --content \"Note\" --ttl 86400\n $ chanl memory create -f memory.json\n\nRequired (unless using -f):\n --entity-type Entity type\n --entity-id Entity ID\n --content Memory content text\n\nOptional:\n --agent-id Scope to a specific agent\n --source Memory source (sets metadata.source)\n --ttl TTL in seconds\n -f, --file JSON file (overrides all other options)`\n )\n .action(handleMemoryCreate);\n\n // memory update <id>\n memory\n .command('update <id>')\n .description('Update an existing memory')\n .option('--content <text>', 'Updated content text')\n .option('--deactivate', 'Deactivate the memory (sets isActive: false)')\n .option('--activate', 'Reactivate the memory (sets isActive: true)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory update 680a1b2c3d4e5f6789012345 --content \"Updated preference\"\n $ chanl memory update 680a1b2c3d4e5f6789012345 --deactivate\n $ chanl memory update 680a1b2c3d4e5f6789012345 --activate\n $ chanl memory update 680a1b2c3d4e5f6789012345 --content \"New text\" --deactivate`\n )\n .action(handleMemoryUpdate);\n\n // memory delete <id>\n memory\n .command('delete <id>')\n .description('Delete a memory permanently')\n .option('-y, --yes', 'Skip confirmation prompt')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory delete 680a1b2c3d4e5f6789012345 # With confirmation\n $ chanl memory delete 680a1b2c3d4e5f6789012345 -y # Skip confirmation`\n )\n .action(handleMemoryDelete);\n\n // memory search\n memory\n .command('search')\n .description('Search memories using semantic similarity')\n .option('--entity-type <type>', 'Entity type (required): customer, session, agent, conversation')\n .option('--entity-id <id>', 'Entity ID (required)')\n .option('--query <text>', 'Search query text (required)')\n .option('--agent-id <id>', 'Optional agent scope filter')\n .option('-l, --limit <number>', 'Maximum results')\n .option('--min-score <number>', 'Minimum relevance score (0-1)')\n .option('--min-confidence <number>', 'Minimum extraction confidence (0-1)')\n .option('--created-after <iso>', 'Only memories created at/after this ISO-8601 timestamp')\n .option('--created-before <iso>', 'Only memories created at/before this ISO-8601 timestamp')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"email preferences\"\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"contact\" --limit 5\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"VIP\" --min-score 0.8\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"recent\" --created-after 2026-05-01T00:00:00Z\n $ chanl memory search --entity-type customer --entity-id cust_123 --query \"test\" --json`\n )\n .action(handleMemorySearch);\n\n // memory search-global\n memory\n .command('search-global')\n .description('Search ALL memories in the workspace (no entity scope)')\n .option('--query <text>', 'Search query text (required)')\n .option('--entity-type <type>', 'Optional: narrow to an entity type')\n .option('--agent-id <id>', 'Optional agent scope filter')\n .option('--source <source>', 'Filter by source: conversation, manual, extraction')\n .option('-l, --limit <number>', 'Maximum results')\n .option('--min-score <number>', 'Minimum relevance score (0-1)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory search-global --query \"billing preferences\"\n $ chanl memory search-global --query \"VIP\" --entity-type customer --limit 10\n $ chanl memory search-global --query \"test\" --json`\n )\n .action(handleMemorySearchGlobal);\n\n // memory stats\n memory\n .command('stats')\n .description('Aggregate memory statistics (totals, by type/source, top-accessed)')\n .option('--entity-type <type>', 'Optionally scope stats to an entity type')\n .option('--entity-id <id>', 'Optionally scope stats to an entity ID')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl memory stats # Workspace-wide\n $ chanl memory stats --entity-type customer --entity-id cust_123\n $ chanl memory stats --json`\n )\n .action(handleMemoryStats);\n\n return memory;\n}\n\n// ============================================================================\n// Helpers (module-local)\n// ============================================================================\n\n/**\n * Truncate a string to a max length, appending '...' if truncated\n */\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.substring(0, maxLen - 3) + '...';\n}\n\n// ============================================================================\n// Command Handlers\n// ============================================================================\n\n/**\n * Handle memory list command\n */\nasync function handleMemoryList(options: {\n entityType?: string;\n entityId?: string;\n agentId?: string;\n source?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching memories...').start();\n\n try {\n const response = await sdk.memory.list({\n entityType: options.entityType as MemoryEntityType | undefined,\n entityId: options.entityId,\n agentId: options.agentId,\n source: options.source as MemorySource | undefined,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch memories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { memories, total, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson({ memories, total, pagination });\n return;\n }\n\n if (memories.length === 0) {\n printInfo('No memories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Entity Type', 'Entity ID', 'Content', 'Source', 'Active', 'Created'],\n memories.map((m: Memory) => [\n truncate(m.id, 12),\n m.entityType,\n m.entityId,\n truncate(m.content, 50),\n m.metadata?.source || 'unknown',\n m.isActive ? chalk.green('Yes') : chalk.red('No'),\n formatDate(m.createdAt),\n ])\n );\n\n printBlank();\n if (pagination) {\n printInfo(`Total: ${total} memories (Page ${pagination.page} of ${pagination.totalPages})`);\n } else {\n printInfo(`Total: ${total} memories`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch memories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory get command\n */\nasync function handleMemoryGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching memory...').start();\n\n try {\n const response = await sdk.memory.get(id);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson(memory);\n return;\n }\n\n printBlank();\n printMemoryDetails(memory);\n } catch (error) {\n spinner.fail('Failed to fetch memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory create command\n */\nasync function handleMemoryCreate(options: {\n entityType?: string;\n entityId?: string;\n content?: string;\n agentId?: string;\n source?: string;\n ttl?: string;\n file?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n let input: CreateMemoryInput;\n\n if (options.file) {\n // Read from JSON file\n try {\n const content = await readFile(options.file, 'utf-8');\n input = JSON.parse(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Failed to read file', message);\n process.exitCode = 1;\n return;\n }\n } else {\n // Build from individual options\n if (!options.entityType || !options.entityId || !options.content) {\n printError(\n 'Missing required options',\n \"Provide --entity-type, --entity-id, and --content, or use '-f <path>' for JSON file\"\n );\n printInfo(\"Run 'chanl memory create --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n input = {\n entityType: options.entityType as MemoryEntityType,\n entityId: options.entityId,\n content: options.content,\n };\n\n if (options.agentId) {\n input.agentId = options.agentId;\n }\n\n if (options.source) {\n input.metadata = { ...input.metadata, source: options.source as MemorySource };\n }\n\n if (options.ttl) {\n const ttl = parseInt(options.ttl, 10);\n if (isNaN(ttl) || ttl <= 0) {\n printError('Invalid TTL value', 'TTL must be a positive number of seconds');\n process.exitCode = 1;\n return;\n }\n input.ttlSeconds = ttl;\n }\n }\n\n const spinner = ora('Creating memory...').start();\n\n try {\n const response = await sdk.memory.create(input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, memory });\n return;\n }\n\n printSuccess(`Created memory: ${memory.id}`);\n } catch (error) {\n spinner.fail('Failed to create memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory update command\n */\nasync function handleMemoryUpdate(\n id: string,\n options: {\n content?: string;\n deactivate?: boolean;\n activate?: boolean;\n }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const input: UpdateMemoryInput = {};\n\n if (options.content) {\n input.content = options.content;\n }\n\n if (options.deactivate) {\n input.isActive = false;\n }\n\n if (options.activate) {\n input.isActive = true;\n }\n\n if (!options.content && !options.deactivate && !options.activate) {\n printError('No updates specified', 'Provide --content, --deactivate, or --activate');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Updating memory...').start();\n\n try {\n const response = await sdk.memory.update(id, input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n const memory = response.data;\n\n if (isJsonOutput()) {\n printJson({ success: true, memory });\n return;\n }\n\n printSuccess(`Updated memory: ${memory.id}`);\n } catch (error) {\n spinner.fail('Failed to update memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory delete command\n */\nasync function handleMemoryDelete(id: string, options: { yes?: boolean }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n // Confirm deletion unless --yes flag is provided\n if (!options.yes) {\n try {\n const confirmed = await confirm({\n message: `Are you sure you want to delete memory '${id}'?`,\n default: false,\n });\n\n if (!confirmed) {\n printInfo('Deletion cancelled');\n return;\n }\n } catch {\n // User cancelled (Ctrl+C)\n printBlank();\n printInfo('Deletion cancelled');\n return;\n }\n }\n\n const spinner = ora('Deleting memory...').start();\n\n try {\n const response = await sdk.memory.delete(id);\n\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete memory', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson({ success: true, deleted: true, id });\n return;\n }\n\n printSuccess(`Deleted memory: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete memory');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory search command\n */\nasync function handleMemorySearch(options: {\n entityType?: string;\n entityId?: string;\n query?: string;\n agentId?: string;\n limit?: string;\n minScore?: string;\n minConfidence?: string;\n createdAfter?: string;\n createdBefore?: string;\n}): Promise<void> {\n if (!options.entityType || !options.entityId || !options.query) {\n printError('Missing required options', 'Provide --entity-type, --entity-id, and --query');\n printInfo(\"Run 'chanl memory search --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n const input: SearchMemoryInput = {\n entityType: options.entityType as MemoryEntityType,\n entityId: options.entityId,\n query: options.query,\n };\n\n if (options.agentId) {\n input.agentId = options.agentId;\n }\n\n if (options.limit) {\n input.limit = parseInt(options.limit, 10);\n }\n\n if (options.minScore) {\n input.minScore = parseFloat(options.minScore);\n }\n\n if (options.minConfidence) {\n input.minConfidence = parseFloat(options.minConfidence);\n }\n\n if (options.createdAfter) {\n input.createdAfter = options.createdAfter;\n }\n\n if (options.createdBefore) {\n input.createdBefore = options.createdBefore;\n }\n\n const spinner = ora('Searching memories...').start();\n\n try {\n const response = await sdk.memory.search(input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to search memories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { memories } = response.data;\n\n if (isJsonOutput()) {\n printJson({ memories });\n return;\n }\n\n if (memories.length === 0) {\n printInfo('No matching memories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Score', 'Content', 'Entity Type', 'Entity ID'],\n memories.map((m: MemorySearchResult) => [\n truncate(m.id, 12),\n (m.score ?? 0).toFixed(2),\n truncate(m.content, 50),\n m.entityType,\n m.entityId,\n ])\n );\n\n printBlank();\n printInfo(`Found ${memories.length} matching memories`);\n } catch (error) {\n spinner.fail('Failed to search memories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory search-global command\n */\nasync function handleMemorySearchGlobal(options: {\n query?: string;\n entityType?: string;\n agentId?: string;\n source?: string;\n limit?: string;\n minScore?: string;\n}): Promise<void> {\n if (!options.query) {\n printError('Missing required option', 'Provide --query');\n printInfo(\"Run 'chanl memory search-global --help' for usage\");\n process.exitCode = 1;\n return;\n }\n\n const sdk = createSdk();\n if (!sdk) return;\n\n const input: GlobalSearchMemoryInput = { query: options.query };\n if (options.entityType) input.entityType = options.entityType as MemoryEntityType;\n if (options.agentId) input.agentId = options.agentId;\n if (options.source) input.source = options.source as MemorySource;\n if (options.limit) input.limit = parseInt(options.limit, 10);\n if (options.minScore) input.minScore = parseFloat(options.minScore);\n\n const spinner = ora('Searching all memories...').start();\n\n try {\n const response = await sdk.memory.searchGlobal(input);\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to search memories', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { memories } = response.data;\n\n if (isJsonOutput()) {\n printJson({ memories });\n return;\n }\n\n if (memories.length === 0) {\n printInfo('No matching memories found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Score', 'Content', 'Entity Type', 'Entity ID'],\n memories.map((m: MemorySearchResult) => [\n truncate(m.id, 12),\n (m.score ?? 0).toFixed(2),\n truncate(m.content, 50),\n m.entityType,\n m.entityId,\n ])\n );\n\n printBlank();\n printInfo(`Found ${memories.length} matching memories`);\n } catch (error) {\n spinner.fail('Failed to search memories');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n/**\n * Handle memory stats command\n */\nasync function handleMemoryStats(options: {\n entityType?: string;\n entityId?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Aggregating memory stats...').start();\n\n try {\n const response = await sdk.memory.stats({\n entityType: options.entityType as MemoryEntityType | undefined,\n entityId: options.entityId,\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch memory stats', response.message);\n process.exitCode = 1;\n return;\n }\n\n const stats: MemoryStats = response.data;\n\n if (isJsonOutput()) {\n printJson(stats);\n return;\n }\n\n printBlank();\n printLabel('Total', String(stats.total));\n printLabel('Active', chalk.green(String(stats.active)));\n printLabel('Inactive', String(stats.inactive));\n printLabel('Expired', stats.expired > 0 ? chalk.yellow(String(stats.expired)) : '0');\n printLabel('Avg confidence', stats.avgConfidence.toFixed(3));\n\n printBlank();\n printInfo('By type:');\n printSimpleTable(\n ['Entity Type', 'Count'],\n Object.entries(stats.byType).map(([k, v]) => [k, String(v)])\n );\n\n printBlank();\n printInfo('By source:');\n printSimpleTable(\n ['Source', 'Count'],\n Object.entries(stats.bySource).map(([k, v]) => [k, String(v)])\n );\n\n if (stats.topAccessed.length > 0) {\n printBlank();\n printInfo('Top accessed:');\n printSimpleTable(\n ['ID', 'Access Count', 'Content'],\n stats.topAccessed.map((t) => [truncate(t.id, 12), String(t.accessCount), truncate(t.content, 50)])\n );\n }\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch memory stats');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\n// ============================================================================\n// Display Helpers\n// ============================================================================\n\n/**\n * Print memory details in formatted output\n */\nfunction printMemoryDetails(memory: Memory): void {\n printLabel('ID', memory.id);\n printLabel('Entity Type', memory.entityType);\n printLabel('Entity ID', memory.entityId);\n\n printBlank();\n printInfo('Content:');\n console.log(chalk.gray(memory.content));\n\n if (memory.agentId) {\n printBlank();\n printLabel('Agent ID', memory.agentId);\n }\n\n printBlank();\n printLabel('Active', memory.isActive ? chalk.green('Yes') : chalk.red('No'));\n\n if (memory.metadata && Object.keys(memory.metadata).length > 0) {\n printBlank();\n printInfo('Metadata:');\n console.log(chalk.gray(JSON.stringify(memory.metadata, null, 2)));\n }\n\n if (memory.expiresAt) {\n printLabel('Expires', formatDate(memory.expiresAt));\n }\n\n printBlank();\n printLabel('Created', formatDate(memory.createdAt));\n if (memory.updatedAt) {\n printLabel('Updated', formatDate(memory.updatedAt));\n }\n printBlank();\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/prompts.js
CHANGED
|
@@ -73,6 +73,12 @@ Examples:
|
|
|
73
73
|
$ chanl prompts delete abc123
|
|
74
74
|
$ chanl prompts delete abc123 --yes # Skip confirmation`
|
|
75
75
|
).action(handlePromptsDelete);
|
|
76
|
+
prompts.command("versions").description("Prompt version operations").addCommand(
|
|
77
|
+
new Command("list").argument("<id>", "Prompt ID").description("List version history for a prompt").action(handlePromptsVersionsList)
|
|
78
|
+
);
|
|
79
|
+
prompts.command("revert <id>").description("Revert a prompt to a previous version").requiredOption("--to-version <number>", "Version number to revert to").action(handlePromptsRevert);
|
|
80
|
+
prompts.command("resolve <id>").description("Resolve template variables in prompt content").option("-f, --file <path>", 'JSON file with { "variables": { ... } }').action(handlePromptsResolve);
|
|
81
|
+
prompts.command("apply <id>").description("Apply a prompt to an agent").requiredOption("-a, --agent <agentId>", "Agent ID").option("--sync", "Sync agent to external platform after apply").action(handlePromptsApply);
|
|
76
82
|
return prompts;
|
|
77
83
|
}
|
|
78
84
|
function formatStatus(status) {
|
|
@@ -105,7 +111,8 @@ async function handlePromptsList(options) {
|
|
|
105
111
|
process.exitCode = 1;
|
|
106
112
|
return;
|
|
107
113
|
}
|
|
108
|
-
const
|
|
114
|
+
const data = response.data;
|
|
115
|
+
const prompts = Array.isArray(data) ? data : data?.prompts ?? [];
|
|
109
116
|
if (isJsonOutput()) {
|
|
110
117
|
printJson(prompts);
|
|
111
118
|
return;
|
|
@@ -289,6 +296,146 @@ async function handlePromptsDelete(id, options) {
|
|
|
289
296
|
process.exitCode = 1;
|
|
290
297
|
}
|
|
291
298
|
}
|
|
299
|
+
async function handlePromptsVersionsList(id) {
|
|
300
|
+
const sdk = createSdk();
|
|
301
|
+
if (!sdk) return;
|
|
302
|
+
const spinner = ora("Fetching versions...").start();
|
|
303
|
+
try {
|
|
304
|
+
const response = await sdk.prompts.getVersions(id);
|
|
305
|
+
spinner.stop();
|
|
306
|
+
if (!response.success || !response.data) {
|
|
307
|
+
printError("Failed to fetch versions", response.message);
|
|
308
|
+
process.exitCode = 1;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const versions = Array.isArray(response.data) ? response.data : [];
|
|
312
|
+
if (isJsonOutput()) {
|
|
313
|
+
printJson(versions);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (versions.length === 0) {
|
|
317
|
+
printInfo("No versions found");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
printBlank();
|
|
321
|
+
printSimpleTable(
|
|
322
|
+
["Version", "Name", "Active", "Created"],
|
|
323
|
+
versions.map((v) => [
|
|
324
|
+
String(v.version ?? "-"),
|
|
325
|
+
(v.versionName || "-").slice(0, 30),
|
|
326
|
+
v.isActive ? chalk.green("yes") : chalk.gray("no"),
|
|
327
|
+
formatDate(v.createdAt)
|
|
328
|
+
])
|
|
329
|
+
);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
spinner.fail("Failed to fetch versions");
|
|
332
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
333
|
+
printError("Error", message);
|
|
334
|
+
process.exitCode = 1;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
async function handlePromptsRevert(id, options) {
|
|
338
|
+
const sdk = createSdk();
|
|
339
|
+
if (!sdk) return;
|
|
340
|
+
const version = parseInt(options.toVersion, 10);
|
|
341
|
+
if (Number.isNaN(version)) {
|
|
342
|
+
printError("Invalid version", "Version must be a number");
|
|
343
|
+
process.exitCode = 1;
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const spinner = ora("Reverting prompt...").start();
|
|
347
|
+
try {
|
|
348
|
+
const response = await sdk.prompts.revert(id, { version });
|
|
349
|
+
spinner.stop();
|
|
350
|
+
if (!response.success || !response.data) {
|
|
351
|
+
printError("Failed to revert prompt", response.message);
|
|
352
|
+
process.exitCode = 1;
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (isJsonOutput()) {
|
|
356
|
+
printJson(response.data);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
printSuccess(`Prompt reverted to version ${version}`);
|
|
360
|
+
printLabel("ID", response.data.id);
|
|
361
|
+
printLabel("Current version", String(response.data.version ?? version));
|
|
362
|
+
} catch (error) {
|
|
363
|
+
spinner.fail("Failed to revert prompt");
|
|
364
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
365
|
+
printError("Error", message);
|
|
366
|
+
process.exitCode = 1;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async function handlePromptsResolve(id, options) {
|
|
370
|
+
const sdk = createSdk();
|
|
371
|
+
if (!sdk) return;
|
|
372
|
+
let variables;
|
|
373
|
+
if (options.file) {
|
|
374
|
+
try {
|
|
375
|
+
const content = readFileSync(options.file, "utf-8");
|
|
376
|
+
const parsed = JSON.parse(content);
|
|
377
|
+
variables = parsed.variables ?? parsed;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
380
|
+
printError("Failed to read file", message);
|
|
381
|
+
process.exitCode = 1;
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const spinner = ora("Resolving variables...").start();
|
|
386
|
+
try {
|
|
387
|
+
const response = await sdk.prompts.resolve(id, variables ? { variables } : void 0);
|
|
388
|
+
spinner.stop();
|
|
389
|
+
if (!response.success || !response.data) {
|
|
390
|
+
printError("Failed to resolve prompt", response.message);
|
|
391
|
+
process.exitCode = 1;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (isJsonOutput()) {
|
|
395
|
+
printJson(response.data);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
printBlank();
|
|
399
|
+
console.log(chalk.bold("Resolved content:"));
|
|
400
|
+
console.log(response.data.content);
|
|
401
|
+
if (response.data.unresolvedVariables?.length) {
|
|
402
|
+
printBlank();
|
|
403
|
+
printInfo(`Unresolved: ${response.data.unresolvedVariables.join(", ")}`);
|
|
404
|
+
}
|
|
405
|
+
} catch (error) {
|
|
406
|
+
spinner.fail("Failed to resolve prompt");
|
|
407
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
408
|
+
printError("Error", message);
|
|
409
|
+
process.exitCode = 1;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function handlePromptsApply(id, options) {
|
|
413
|
+
const sdk = createSdk();
|
|
414
|
+
if (!sdk) return;
|
|
415
|
+
const spinner = ora("Applying prompt to agent...").start();
|
|
416
|
+
try {
|
|
417
|
+
const response = await sdk.prompts.apply(id, {
|
|
418
|
+
agentId: options.agent,
|
|
419
|
+
syncToPlatform: options.sync
|
|
420
|
+
});
|
|
421
|
+
spinner.stop();
|
|
422
|
+
if (!response.success) {
|
|
423
|
+
printError("Failed to apply prompt", response.message);
|
|
424
|
+
process.exitCode = 1;
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (isJsonOutput()) {
|
|
428
|
+
printJson(response.data ?? { success: true });
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
printSuccess(`Prompt applied to agent ${options.agent}`);
|
|
432
|
+
} catch (error) {
|
|
433
|
+
spinner.fail("Failed to apply prompt");
|
|
434
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
435
|
+
printError("Error", message);
|
|
436
|
+
process.exitCode = 1;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
292
439
|
export {
|
|
293
440
|
createPromptsCommand
|
|
294
441
|
};
|