xmemory-cli 0.1.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/README.md +315 -0
- package/bin/xmemory-cli.cjs +4382 -0
- package/bin/xmemory-cli.js +277 -0
- package/bin/xmemory-cli.mjs +4160 -0
- package/package.json +36 -0
- package/src/api/client.ts +144 -0
- package/src/commands/add.ts +36 -0
- package/src/commands/delete.ts +25 -0
- package/src/commands/get.ts +35 -0
- package/src/commands/graph.ts +90 -0
- package/src/commands/list.ts +36 -0
- package/src/commands/search.ts +46 -0
- package/src/commands/spaces.ts +88 -0
- package/src/commands/tags.ts +28 -0
- package/src/config/index.ts +179 -0
- package/src/index.ts +31 -0
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xmemory-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "xMemory CLI - Command-line interface for xMemory knowledge base",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"xmemory",
|
|
7
|
+
"cli",
|
|
8
|
+
"memory",
|
|
9
|
+
"knowledge-base",
|
|
10
|
+
"ai"
|
|
11
|
+
],
|
|
12
|
+
"bin": {
|
|
13
|
+
"xmemory-cli": "./bin/xmemory-cli.cjs"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "node build.mjs",
|
|
21
|
+
"start": "node bin/xmemory-cli.cjs",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"commander": "^12.1.0",
|
|
26
|
+
"chalk": "^5.3.0",
|
|
27
|
+
"ora": "^8.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.11.0",
|
|
31
|
+
"esbuild": "^0.24.0"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Config } from "../config/index.js";
|
|
2
|
+
|
|
3
|
+
export class Client {
|
|
4
|
+
private baseUrl: string;
|
|
5
|
+
private apiKey: string;
|
|
6
|
+
private timeout: number;
|
|
7
|
+
|
|
8
|
+
constructor(config: Config) {
|
|
9
|
+
this.baseUrl = config.apiBaseUrl.replace(/\/$/, "");
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
this.timeout = 30000;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private async request<T>(
|
|
15
|
+
method: string,
|
|
16
|
+
path: string,
|
|
17
|
+
body?: unknown,
|
|
18
|
+
): Promise<T> {
|
|
19
|
+
const url = `${this.baseUrl}${path}`;
|
|
20
|
+
const headers: Record<string, string> = {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if (this.apiKey) {
|
|
25
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
method,
|
|
30
|
+
headers,
|
|
31
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
32
|
+
signal: AbortSignal.timeout(this.timeout),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new Error(`API Error ${response.status}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return response.json();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async searchMemories(query: string, limit = 5, space?: string) {
|
|
43
|
+
const params = new URLSearchParams({ query, limit: limit.toString() });
|
|
44
|
+
if (space) params.append("space", space);
|
|
45
|
+
return this.request<{ results: MemoryResult[] }>(
|
|
46
|
+
`GET`,
|
|
47
|
+
`/memory?${params}`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async addMemory(
|
|
52
|
+
content: string,
|
|
53
|
+
options: {
|
|
54
|
+
space?: string;
|
|
55
|
+
spaceId?: string;
|
|
56
|
+
tags?: string[];
|
|
57
|
+
source?: string;
|
|
58
|
+
},
|
|
59
|
+
) {
|
|
60
|
+
return this.request<{ id: string; memoryId: string }>("POST", "/memory", {
|
|
61
|
+
content,
|
|
62
|
+
...options,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getMemory(id: string) {
|
|
67
|
+
return this.request<MemoryResult>("GET", `/memory/${id}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async deleteMemory(id: string) {
|
|
71
|
+
return this.request<{ success: boolean }>("DELETE", `/memory/${id}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async listSpaces() {
|
|
75
|
+
return this.request<{ spaces: Space[] }>("GET", "/spaces");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async createSpace(name: string, description?: string) {
|
|
79
|
+
return this.request<{ space: Space }>("POST", "/spaces", {
|
|
80
|
+
name,
|
|
81
|
+
description,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async deleteSpace(id: string) {
|
|
86
|
+
return this.request<{ success: boolean }>("DELETE", `/space?id=${id}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async getSpaceDetails(id: string) {
|
|
90
|
+
return this.request<{ space: SpaceDetails }>("GET", `/space?id=${id}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async listTags(spaceId?: string) {
|
|
94
|
+
const params = spaceId ? `?spaceId=${spaceId}` : "";
|
|
95
|
+
return this.request<{ tags: Tag[] }>("GET", `/tags${params}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async queryGraph(entityName?: string, tag?: string, spaceId?: string) {
|
|
99
|
+
const params = new URLSearchParams();
|
|
100
|
+
if (entityName) params.append("entityName", entityName);
|
|
101
|
+
if (tag) params.append("tag", tag);
|
|
102
|
+
if (spaceId) params.append("spaceId", spaceId);
|
|
103
|
+
return this.request<GraphResult>("GET", `/graph?${params}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface MemoryResult {
|
|
108
|
+
id: string;
|
|
109
|
+
content: string;
|
|
110
|
+
createdAt: string;
|
|
111
|
+
updatedAt: string;
|
|
112
|
+
tags?: string[];
|
|
113
|
+
source?: string;
|
|
114
|
+
similarity?: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface Space {
|
|
118
|
+
id: string;
|
|
119
|
+
name: string;
|
|
120
|
+
description?: string;
|
|
121
|
+
createdAt: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface SpaceDetails extends Space {
|
|
125
|
+
stats?: {
|
|
126
|
+
memoryCount: number;
|
|
127
|
+
};
|
|
128
|
+
latestMemories?: MemoryResult[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface Tag {
|
|
132
|
+
name: string;
|
|
133
|
+
count: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface GraphResult {
|
|
137
|
+
nodes?: { id: string; name: string; type: string }[];
|
|
138
|
+
entity?: { name: string; type: string };
|
|
139
|
+
relationships?: {
|
|
140
|
+
outgoing?: { relation: string; targetName: string; description?: string }[];
|
|
141
|
+
incoming?: { relation: string; sourceName: string; description?: string }[];
|
|
142
|
+
};
|
|
143
|
+
message?: string;
|
|
144
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function AddCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
content: string,
|
|
7
|
+
options: {
|
|
8
|
+
space?: string;
|
|
9
|
+
spaceId?: string;
|
|
10
|
+
tags?: string[];
|
|
11
|
+
source?: string;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
},
|
|
14
|
+
) {
|
|
15
|
+
try {
|
|
16
|
+
const result = await client.addMemory(content, {
|
|
17
|
+
space: options.space,
|
|
18
|
+
spaceId: options.spaceId,
|
|
19
|
+
tags: options.tags,
|
|
20
|
+
source: options.source,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (options.json) {
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log(chalk.green(`Memory added successfully!`));
|
|
29
|
+
console.log(chalk.cyan(`ID: ${result.id || result.memoryId}`));
|
|
30
|
+
if (options.space) {
|
|
31
|
+
console.log(chalk.gray(`Space: ${options.space}`));
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new Error(`Add memory failed: ${error}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function DeleteCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
id: string,
|
|
7
|
+
options: { json?: boolean },
|
|
8
|
+
) {
|
|
9
|
+
try {
|
|
10
|
+
const result = await client.deleteMemory(id);
|
|
11
|
+
|
|
12
|
+
if (options.json) {
|
|
13
|
+
console.log(JSON.stringify(result, null, 2));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (result.success) {
|
|
18
|
+
console.log(chalk.green(`Memory ${id} deleted successfully.`));
|
|
19
|
+
} else {
|
|
20
|
+
console.log(chalk.yellow(`Failed to delete memory ${id}.`));
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Delete memory failed: ${error}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function GetCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
id: string,
|
|
7
|
+
options: { json?: boolean },
|
|
8
|
+
) {
|
|
9
|
+
try {
|
|
10
|
+
const memory = await client.getMemory(id);
|
|
11
|
+
|
|
12
|
+
if (options.json) {
|
|
13
|
+
console.log(JSON.stringify(memory, null, 2));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
console.log(chalk.bold(`\nMemory [${memory.id}]\n`));
|
|
18
|
+
console.log(memory.content);
|
|
19
|
+
console.log();
|
|
20
|
+
if (memory.tags && memory.tags.length > 0) {
|
|
21
|
+
console.log(chalk.cyan(`Tags: ${memory.tags.join(", ")}`));
|
|
22
|
+
}
|
|
23
|
+
if (memory.source) {
|
|
24
|
+
console.log(chalk.gray(`Source: ${memory.source}`));
|
|
25
|
+
}
|
|
26
|
+
console.log(
|
|
27
|
+
chalk.gray(`Created: ${new Date(memory.createdAt).toLocaleString()}`),
|
|
28
|
+
);
|
|
29
|
+
console.log(
|
|
30
|
+
chalk.gray(`Updated: ${new Date(memory.updatedAt).toLocaleString()}`),
|
|
31
|
+
);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw new Error(`Get memory failed: ${error}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function GraphCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
options: { entity?: string; tag?: string; spaceId?: string; json?: boolean },
|
|
7
|
+
) {
|
|
8
|
+
try {
|
|
9
|
+
const result = await client.queryGraph(
|
|
10
|
+
options.entity,
|
|
11
|
+
options.tag,
|
|
12
|
+
options.spaceId,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
if (options.json) {
|
|
16
|
+
console.log(JSON.stringify(result, null, 2));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (result.message) {
|
|
21
|
+
console.log(chalk.yellow(result.message));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (result.nodes && result.nodes.length > 0) {
|
|
26
|
+
console.log(
|
|
27
|
+
chalk.bold(`\nKnowledge Graph Nodes (${result.nodes.length}):\n`),
|
|
28
|
+
);
|
|
29
|
+
for (const node of result.nodes) {
|
|
30
|
+
console.log(
|
|
31
|
+
chalk.cyan(` ${node.name}`) + chalk.gray(` (${node.type})`),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (result.entity && result.relationships) {
|
|
38
|
+
console.log(
|
|
39
|
+
chalk.bold(
|
|
40
|
+
`\nKnowledge Graph: ${result.entity.name} (${result.entity.type})\n`,
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
result.relationships.outgoing &&
|
|
46
|
+
result.relationships.outgoing.length > 0
|
|
47
|
+
) {
|
|
48
|
+
console.log(chalk.green("Outgoing Relationships:"));
|
|
49
|
+
for (const rel of result.relationships.outgoing) {
|
|
50
|
+
console.log(
|
|
51
|
+
chalk.cyan(` -> [${rel.relation}]`) + ` ${rel.targetName}`,
|
|
52
|
+
);
|
|
53
|
+
if (rel.description) {
|
|
54
|
+
console.log(chalk.gray(` ${rel.description}`));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
console.log();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (
|
|
61
|
+
result.relationships.incoming &&
|
|
62
|
+
result.relationships.incoming.length > 0
|
|
63
|
+
) {
|
|
64
|
+
console.log(chalk.blue("Incoming Relationships:"));
|
|
65
|
+
for (const rel of result.relationships.incoming) {
|
|
66
|
+
console.log(
|
|
67
|
+
chalk.cyan(`<- [${rel.relation}]`) + ` ${rel.sourceName}`,
|
|
68
|
+
);
|
|
69
|
+
if (rel.description) {
|
|
70
|
+
console.log(chalk.gray(` ${rel.description}`));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (
|
|
76
|
+
(!result.relationships.outgoing ||
|
|
77
|
+
result.relationships.outgoing.length === 0) &&
|
|
78
|
+
(!result.relationships.incoming ||
|
|
79
|
+
result.relationships.incoming.length === 0)
|
|
80
|
+
) {
|
|
81
|
+
console.log(chalk.yellow("No relationships found."));
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log(chalk.yellow("No graph data found."));
|
|
87
|
+
} catch (error) {
|
|
88
|
+
throw new Error(`Graph query failed: ${error}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function ListCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
options: { space?: string; json?: boolean },
|
|
7
|
+
) {
|
|
8
|
+
try {
|
|
9
|
+
const { spaces } = await client.listSpaces();
|
|
10
|
+
|
|
11
|
+
if (options.json) {
|
|
12
|
+
console.log(JSON.stringify(spaces, null, 2));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (spaces.length === 0) {
|
|
17
|
+
console.log(chalk.yellow("No spaces found."));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log(chalk.bold(`\nSpaces (${spaces.length}):\n`));
|
|
22
|
+
for (const space of spaces) {
|
|
23
|
+
console.log(chalk.cyan(`[${space.id}]`));
|
|
24
|
+
console.log(chalk.bold(` ${space.name}`));
|
|
25
|
+
if (space.description) {
|
|
26
|
+
console.log(chalk.gray(` ${space.description}`));
|
|
27
|
+
}
|
|
28
|
+
console.log(
|
|
29
|
+
chalk.gray(` Created: ${new Date(space.createdAt).toLocaleString()}`),
|
|
30
|
+
);
|
|
31
|
+
console.log();
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new Error(`List spaces failed: ${error}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function SearchCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
query: string,
|
|
7
|
+
options: { limit?: number; space?: string; json?: boolean },
|
|
8
|
+
) {
|
|
9
|
+
try {
|
|
10
|
+
const { results } = await client.searchMemories(
|
|
11
|
+
query,
|
|
12
|
+
options.limit || 5,
|
|
13
|
+
options.space,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
if (options.json) {
|
|
17
|
+
console.log(JSON.stringify(results, null, 2));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (results.length === 0) {
|
|
22
|
+
console.log(chalk.yellow("No memories found."));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(chalk.bold(`\nFound ${results.length} memories:\n`));
|
|
27
|
+
for (const mem of results) {
|
|
28
|
+
const similarity = mem.similarity
|
|
29
|
+
? ` (${(mem.similarity * 100).toFixed(1)}% match)`
|
|
30
|
+
: "";
|
|
31
|
+
console.log(chalk.cyan(`[${mem.id}]${similarity}`));
|
|
32
|
+
console.log(
|
|
33
|
+
mem.content.substring(0, 200) + (mem.content.length > 200 ? "..." : ""),
|
|
34
|
+
);
|
|
35
|
+
if (mem.tags && mem.tags.length > 0) {
|
|
36
|
+
console.log(chalk.gray(`Tags: ${mem.tags.join(", ")}`));
|
|
37
|
+
}
|
|
38
|
+
console.log(
|
|
39
|
+
chalk.gray(`Created: ${new Date(mem.createdAt).toLocaleString()}`),
|
|
40
|
+
);
|
|
41
|
+
console.log();
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
throw new Error(`Search failed: ${error}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function SpacesCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
options: {
|
|
7
|
+
action?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
json?: boolean;
|
|
12
|
+
},
|
|
13
|
+
) {
|
|
14
|
+
try {
|
|
15
|
+
if (options.action === "create") {
|
|
16
|
+
if (!options.name) {
|
|
17
|
+
throw new Error("Space name is required for create action");
|
|
18
|
+
}
|
|
19
|
+
const result = await client.createSpace(
|
|
20
|
+
options.name,
|
|
21
|
+
options.description,
|
|
22
|
+
);
|
|
23
|
+
if (options.json) {
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
25
|
+
} else {
|
|
26
|
+
console.log(chalk.green(`Space created successfully!`));
|
|
27
|
+
console.log(chalk.cyan(`ID: ${result.space.id}`));
|
|
28
|
+
console.log(chalk.gray(`Name: ${result.space.name}`));
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (options.action === "delete") {
|
|
34
|
+
if (!options.id) {
|
|
35
|
+
throw new Error("Space ID is required for delete action");
|
|
36
|
+
}
|
|
37
|
+
const result = await client.deleteSpace(options.id);
|
|
38
|
+
if (options.json) {
|
|
39
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40
|
+
} else {
|
|
41
|
+
console.log(chalk.green(`Space ${options.id} deleted successfully.`));
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (options.action === "info") {
|
|
47
|
+
if (!options.id) {
|
|
48
|
+
throw new Error("Space ID is required for info action");
|
|
49
|
+
}
|
|
50
|
+
const { space } = await client.getSpaceDetails(options.id);
|
|
51
|
+
if (options.json) {
|
|
52
|
+
console.log(JSON.stringify(space, null, 2));
|
|
53
|
+
} else {
|
|
54
|
+
console.log(chalk.bold(`\nSpace: ${space.name}`));
|
|
55
|
+
console.log(chalk.cyan(`ID: ${space.id}`));
|
|
56
|
+
if (space.description) {
|
|
57
|
+
console.log(chalk.gray(`Description: ${space.description}`));
|
|
58
|
+
}
|
|
59
|
+
if (space.stats) {
|
|
60
|
+
console.log(chalk.gray(`Memory Count: ${space.stats.memoryCount}`));
|
|
61
|
+
}
|
|
62
|
+
console.log(
|
|
63
|
+
chalk.gray(`Created: ${new Date(space.createdAt).toLocaleString()}`),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const { spaces } = await client.listSpaces();
|
|
70
|
+
if (options.json) {
|
|
71
|
+
console.log(JSON.stringify(spaces, null, 2));
|
|
72
|
+
} else {
|
|
73
|
+
if (spaces.length === 0) {
|
|
74
|
+
console.log(chalk.yellow("No spaces found."));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
console.log(chalk.bold(`\nSpaces (${spaces.length}):\n`));
|
|
78
|
+
for (const space of spaces) {
|
|
79
|
+
console.log(chalk.cyan(`[${space.id}] ${space.name}`));
|
|
80
|
+
if (space.description) {
|
|
81
|
+
console.log(chalk.gray(` ${space.description}`));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
throw new Error(`Spaces command failed: ${error}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Client } from "../api/client.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
export async function TagsCommand(
|
|
5
|
+
client: Client,
|
|
6
|
+
options: { spaceId?: string; json?: boolean },
|
|
7
|
+
) {
|
|
8
|
+
try {
|
|
9
|
+
const { tags } = await client.listTags(options.spaceId);
|
|
10
|
+
|
|
11
|
+
if (options.json) {
|
|
12
|
+
console.log(JSON.stringify(tags, null, 2));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (tags.length === 0) {
|
|
17
|
+
console.log(chalk.yellow("No tags found."));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log(chalk.bold(`\nPopular Tags (${tags.length}):\n`));
|
|
22
|
+
for (const tag of tags) {
|
|
23
|
+
console.log(chalk.cyan(` ${tag.name}`) + chalk.gray(` (${tag.count})`));
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
throw new Error(`Tags command failed: ${error}`);
|
|
27
|
+
}
|
|
28
|
+
}
|