@tmddev/tmd 0.3.0 → 0.3.2
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 +56 -215
- package/dist/cli.js +292 -6
- package/dist/commands/config.d.ts +11 -0
- package/dist/commands/config.js +199 -0
- package/dist/commands/feishu.d.ts +13 -0
- package/dist/commands/feishu.js +388 -0
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.js +117 -0
- package/dist/commands/plan.d.ts +1 -1
- package/dist/commands/plan.js +140 -19
- package/dist/commands/server.d.ts +7 -0
- package/dist/commands/server.js +38 -0
- package/dist/commands/skills.js +116 -30
- package/dist/commands/spec.d.ts +19 -0
- package/dist/commands/spec.js +73 -0
- package/dist/commands/ui.d.ts +2 -0
- package/dist/commands/ui.js +33 -0
- package/dist/commands/validate.js +31 -0
- package/dist/tmd-config +0 -0
- package/dist/tmd-feishu +0 -0
- package/dist/tmd-knowledge +0 -0
- package/dist/tmd-plan-gen +0 -0
- package/dist/tmd-server +0 -0
- package/dist/tmd-skills +0 -0
- package/dist/tmd-spec +0 -0
- package/dist/types.d.ts +8 -2
- package/dist/utils/execution-plan.d.ts +56 -0
- package/dist/utils/execution-plan.js +109 -0
- package/dist/utils/llm-plan.d.ts +38 -0
- package/dist/utils/llm-plan.js +159 -0
- package/dist/utils/openspec.js +2 -2
- package/dist/utils/paths.d.ts +5 -0
- package/dist/utils/paths.js +11 -0
- package/dist/utils/skills.js +1 -2
- package/dist/utils/task-status.d.ts +1 -0
- package/dist/utils/task-status.js +11 -0
- package/package.json +3 -4
- package/dist/utils/skillssh.d.ts +0 -12
- package/dist/utils/skillssh.js +0 -147
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { spawnSync } from 'child_process';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
const _dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const TMD_CONFIG_BIN = join(_dirname, '..', process.platform === 'win32' ? 'tmd-config.exe' : 'tmd-config');
|
|
8
|
+
function runTmdConfig(args) {
|
|
9
|
+
if (!existsSync(TMD_CONFIG_BIN)) {
|
|
10
|
+
console.error(chalk.red('✗ tmd-config binary not found. Run pnpm build.'));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const r = spawnSync(TMD_CONFIG_BIN, args, {
|
|
14
|
+
encoding: 'utf8',
|
|
15
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
16
|
+
});
|
|
17
|
+
if (r.status !== 0) {
|
|
18
|
+
process.exit(r.status ?? 1);
|
|
19
|
+
}
|
|
20
|
+
return r.stdout;
|
|
21
|
+
}
|
|
22
|
+
export function configCommand(action, key, valueOrOptions, options) {
|
|
23
|
+
const cwd = process.cwd();
|
|
24
|
+
const base = () => ['--app-data-dir', cwd];
|
|
25
|
+
// Handle options - if valueOrOptions is an object, it's actually options
|
|
26
|
+
let actualOptions = {};
|
|
27
|
+
let actualValue;
|
|
28
|
+
if (typeof valueOrOptions === 'object') {
|
|
29
|
+
actualOptions = valueOrOptions;
|
|
30
|
+
}
|
|
31
|
+
else if (typeof valueOrOptions === 'string') {
|
|
32
|
+
actualValue = valueOrOptions;
|
|
33
|
+
actualOptions = options || {};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
actualOptions = options || {};
|
|
37
|
+
}
|
|
38
|
+
if (!action || action === 'list') {
|
|
39
|
+
const args = ['list', ...base()];
|
|
40
|
+
if (actualOptions['page-no']) {
|
|
41
|
+
args.push('--page-no', String(actualOptions['page-no']));
|
|
42
|
+
}
|
|
43
|
+
if (actualOptions['page-size']) {
|
|
44
|
+
args.push('--page-size', String(actualOptions['page-size']));
|
|
45
|
+
}
|
|
46
|
+
const out = runTmdConfig(args);
|
|
47
|
+
const configs = JSON.parse(out || '[]');
|
|
48
|
+
if (configs.length === 0) {
|
|
49
|
+
console.log(chalk.yellow('No configurations found.'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log(chalk.bold('\nConfigurations:'));
|
|
53
|
+
console.log('─'.repeat(80));
|
|
54
|
+
for (const config of configs) {
|
|
55
|
+
console.log(chalk.cyan(` ${config.data_id}`));
|
|
56
|
+
console.log(chalk.gray(` Type: ${config.type || 'yaml'}`));
|
|
57
|
+
if (config.description) {
|
|
58
|
+
console.log(chalk.gray(` Description: ${config.description}`));
|
|
59
|
+
}
|
|
60
|
+
const date = new Date(config.gmt_modified * 1000).toLocaleString();
|
|
61
|
+
console.log(chalk.gray(` Modified: ${date}`));
|
|
62
|
+
console.log('');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (action === 'get') {
|
|
66
|
+
// If key is provided, get value by key from default config
|
|
67
|
+
// If key is not provided, get entire default config
|
|
68
|
+
const args = key ? ['get', key, ...base()] : ['get', ...base()];
|
|
69
|
+
const out = runTmdConfig(args);
|
|
70
|
+
const config = JSON.parse(out);
|
|
71
|
+
console.log(chalk.bold(`\nConfiguration: ${chalk.cyan(config.data_id || key || 'default')}`));
|
|
72
|
+
console.log('─'.repeat(80));
|
|
73
|
+
console.log(chalk.gray(`Type: ${config.type || 'yaml'}`));
|
|
74
|
+
if (config.description) {
|
|
75
|
+
console.log(chalk.gray(`Description: ${config.description}`));
|
|
76
|
+
}
|
|
77
|
+
if (config.tags) {
|
|
78
|
+
console.log(chalk.gray(`Tags: ${config.tags}`));
|
|
79
|
+
}
|
|
80
|
+
console.log(chalk.bold('\nContent:'));
|
|
81
|
+
console.log(config.content);
|
|
82
|
+
}
|
|
83
|
+
else if (action === 'set') {
|
|
84
|
+
// data-id defaults to "default" if not provided
|
|
85
|
+
const dataId = key || 'default';
|
|
86
|
+
if (!actualValue) {
|
|
87
|
+
console.error(chalk.red('✗ Value required'));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const args = ['set', dataId, actualValue, ...base()];
|
|
91
|
+
if (actualOptions.type) {
|
|
92
|
+
args.push('--type', actualOptions.type);
|
|
93
|
+
}
|
|
94
|
+
const out = runTmdConfig(args);
|
|
95
|
+
const config = JSON.parse(out);
|
|
96
|
+
console.log(chalk.green(`✓ Configuration set: ${config.data_id}`));
|
|
97
|
+
}
|
|
98
|
+
else if (action === 'delete') {
|
|
99
|
+
if (!key) {
|
|
100
|
+
console.error(chalk.red('✗ Key required'));
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const out = runTmdConfig(['delete', key, ...base()]);
|
|
104
|
+
const result = JSON.parse(out);
|
|
105
|
+
if (result.success) {
|
|
106
|
+
console.log(chalk.green(`✓ Configuration deleted: ${key}`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (action === 'search') {
|
|
110
|
+
if (!key) {
|
|
111
|
+
console.error(chalk.red('✗ Keywords required'));
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
const out = runTmdConfig(['search', key, ...base()]);
|
|
115
|
+
const configs = JSON.parse(out || '[]');
|
|
116
|
+
if (configs.length === 0) {
|
|
117
|
+
console.log(chalk.yellow(`No configurations found matching: ${key}`));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
console.log(chalk.bold(`\nSearch results for "${key}":`));
|
|
121
|
+
console.log('─'.repeat(80));
|
|
122
|
+
for (const config of configs) {
|
|
123
|
+
console.log(chalk.cyan(` ${config.data_id}`));
|
|
124
|
+
console.log(chalk.gray(` Type: ${config.type || 'yaml'}`));
|
|
125
|
+
if (config.description) {
|
|
126
|
+
console.log(chalk.gray(` Description: ${config.description}`));
|
|
127
|
+
}
|
|
128
|
+
console.log('');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (action === 'history') {
|
|
132
|
+
if (!key) {
|
|
133
|
+
console.error(chalk.red('✗ Key required'));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const out = runTmdConfig(['history', key, ...base()]);
|
|
137
|
+
const history = JSON.parse(out || '[]');
|
|
138
|
+
if (history.length === 0) {
|
|
139
|
+
console.log(chalk.yellow(`No history found for: ${key}`));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
console.log(chalk.bold(`\nHistory for: ${chalk.cyan(key)}`));
|
|
143
|
+
console.log('─'.repeat(80));
|
|
144
|
+
for (const entry of history) {
|
|
145
|
+
const date = new Date(entry.gmt_create * 1000).toLocaleString();
|
|
146
|
+
console.log(chalk.gray(` [${entry.nid}] ${entry.op_type} - ${date}`));
|
|
147
|
+
if (entry.md5) {
|
|
148
|
+
console.log(chalk.gray(` MD5: ${entry.md5}`));
|
|
149
|
+
}
|
|
150
|
+
console.log('');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else if (action === 'rollback') {
|
|
154
|
+
if (!key) {
|
|
155
|
+
console.error(chalk.red('✗ Key required'));
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
const nid = actualValue;
|
|
159
|
+
if (!nid) {
|
|
160
|
+
console.error(chalk.red('✗ History ID (nid) required'));
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
const out = runTmdConfig(['rollback', key, nid, ...base()]);
|
|
164
|
+
const config = JSON.parse(out);
|
|
165
|
+
console.log(chalk.green(`✓ Configuration rolled back: ${config.data_id} to version ${nid}`));
|
|
166
|
+
}
|
|
167
|
+
else if (action === 'export') {
|
|
168
|
+
const args = ['export', ...base()];
|
|
169
|
+
if (actualOptions.output) {
|
|
170
|
+
args.push('--output', actualOptions.output);
|
|
171
|
+
}
|
|
172
|
+
const out = runTmdConfig(args);
|
|
173
|
+
const result = JSON.parse(out);
|
|
174
|
+
if (result.success) {
|
|
175
|
+
console.log(chalk.green(`✓ Configurations exported to: ${result.file}`));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (action === 'import') {
|
|
179
|
+
if (!key) {
|
|
180
|
+
console.error(chalk.red('✗ File path required'));
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
const args = ['import', key, ...base()];
|
|
184
|
+
if (actualOptions.policy) {
|
|
185
|
+
args.push('--policy', actualOptions.policy);
|
|
186
|
+
}
|
|
187
|
+
const out = runTmdConfig(args);
|
|
188
|
+
const result = JSON.parse(out);
|
|
189
|
+
if (result.success) {
|
|
190
|
+
console.log(chalk.green('✓ Configurations imported successfully'));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
console.error(chalk.red(`✗ Unknown action: ${action}`));
|
|
195
|
+
console.log(chalk.gray('Available actions: list, get, set, delete, search, history, rollback, export, import'));
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function feishuChatsCommand(json: boolean): void;
|
|
2
|
+
export declare function feishuMessagesCommand(chatId: string, pageSize: string | undefined, sortType: string | undefined, json: boolean): void;
|
|
3
|
+
export declare function feishuMessageSendCommand(chatId: string, message: string): void;
|
|
4
|
+
export declare function feishuMessageReplyCommand(messageId: string, message: string): void;
|
|
5
|
+
export declare function feishuMessageGetCommand(messageId: string, json: boolean): void;
|
|
6
|
+
export declare function feishuDocumentsGetCommand(documentId: string, raw: boolean, json: boolean): void;
|
|
7
|
+
export declare function feishuBitableGetCommand(sheetId: string, json: boolean): void;
|
|
8
|
+
export declare function feishuBitableTablesCommand(sheetId: string, json: boolean): void;
|
|
9
|
+
export declare function feishuBitableViewsCommand(sheetId: string, tableId: string, json: boolean): void;
|
|
10
|
+
export declare function feishuBitableViewCommand(sheetId: string, tableId: string, viewId: string, json: boolean): void;
|
|
11
|
+
export declare function feishuBitableRecordsCommand(sheetId: string, tableId: string, json: boolean): void;
|
|
12
|
+
export declare function feishuBitableRecordCommand(sheetId: string, tableId: string, recordId: string, json: boolean): void;
|
|
13
|
+
//# sourceMappingURL=feishu.d.ts.map
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
const _dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const TMD_FEISHU_BIN = join(_dirname, '..', process.platform === 'win32' ? 'tmd-feishu.exe' : 'tmd-feishu');
|
|
8
|
+
function runTmdFeishu(args) {
|
|
9
|
+
if (!existsSync(TMD_FEISHU_BIN)) {
|
|
10
|
+
console.error(chalk.red('✗ tmd-feishu binary not found. Run pnpm build.'));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const r = spawnSync(TMD_FEISHU_BIN, args, {
|
|
14
|
+
encoding: 'utf8',
|
|
15
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
16
|
+
});
|
|
17
|
+
if (r.status !== 0) {
|
|
18
|
+
process.exit(r.status ?? 1);
|
|
19
|
+
}
|
|
20
|
+
return r.stdout;
|
|
21
|
+
}
|
|
22
|
+
function formatChatsOutput(jsonStr, json) {
|
|
23
|
+
if (json) {
|
|
24
|
+
console.log(jsonStr);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const data = JSON.parse(jsonStr);
|
|
29
|
+
if (data.data?.items) {
|
|
30
|
+
const chats = data.data.items;
|
|
31
|
+
if (chats.length === 0) {
|
|
32
|
+
console.log('No chats found.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log(`Found ${chats.length} chat(s):\n`);
|
|
36
|
+
for (const chat of chats) {
|
|
37
|
+
console.log(` ${chalk.bold(chat.chat_id || chat.id || 'N/A')} - ${chat.name || 'Unnamed'}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(jsonStr);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
console.log(jsonStr);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function formatMessagesOutput(jsonStr, json) {
|
|
49
|
+
if (json) {
|
|
50
|
+
console.log(jsonStr);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const data = JSON.parse(jsonStr);
|
|
55
|
+
if (data.data?.items) {
|
|
56
|
+
const messages = data.data.items;
|
|
57
|
+
if (messages.length === 0) {
|
|
58
|
+
console.log('No messages found.');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log(`Found ${messages.length} message(s):\n`);
|
|
62
|
+
for (const msg of messages) {
|
|
63
|
+
const content = msg.body?.content ? JSON.parse(msg.body.content) : {};
|
|
64
|
+
const text = content.text || 'N/A';
|
|
65
|
+
const time = msg.create_time || 'N/A';
|
|
66
|
+
const sender = msg.sender?.name || msg.sender?.id || 'Unknown';
|
|
67
|
+
console.log(` [${time}] ${chalk.bold(sender)}: ${text}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log(jsonStr);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
console.log(jsonStr);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function feishuChatsCommand(json) {
|
|
79
|
+
const output = runTmdFeishu(['chats']);
|
|
80
|
+
formatChatsOutput(output, json);
|
|
81
|
+
}
|
|
82
|
+
export function feishuMessagesCommand(chatId, pageSize, sortType, json) {
|
|
83
|
+
if (!chatId) {
|
|
84
|
+
console.error(chalk.red('✗ --chat-id is required'));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const args = ['messages', '--chat-id', chatId];
|
|
88
|
+
if (pageSize) {
|
|
89
|
+
args.push('--page-size', pageSize);
|
|
90
|
+
}
|
|
91
|
+
if (sortType) {
|
|
92
|
+
args.push('--sort-type', sortType);
|
|
93
|
+
}
|
|
94
|
+
const output = runTmdFeishu(args);
|
|
95
|
+
formatMessagesOutput(output, json);
|
|
96
|
+
}
|
|
97
|
+
export function feishuMessageSendCommand(chatId, message) {
|
|
98
|
+
if (!chatId) {
|
|
99
|
+
console.error(chalk.red('✗ --chat-id is required'));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
if (!message) {
|
|
103
|
+
console.error(chalk.red('✗ --message is required'));
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
const output = runTmdFeishu(['send', '--chat-id', chatId, '--message', message]);
|
|
107
|
+
try {
|
|
108
|
+
const data = JSON.parse(output);
|
|
109
|
+
if (data.data?.message_id) {
|
|
110
|
+
console.log(chalk.green(`✓ Message sent successfully. Message ID: ${data.data.message_id}`));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.log(output);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
console.log(output);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export function feishuMessageReplyCommand(messageId, message) {
|
|
121
|
+
if (!messageId) {
|
|
122
|
+
console.error(chalk.red('✗ --message-id is required'));
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
if (!message) {
|
|
126
|
+
console.error(chalk.red('✗ --message is required'));
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
const output = runTmdFeishu(['reply', '--message-id', messageId, '--message', message]);
|
|
130
|
+
try {
|
|
131
|
+
const data = JSON.parse(output);
|
|
132
|
+
if (data.data?.message_id) {
|
|
133
|
+
console.log(chalk.green(`✓ Message replied successfully. Message ID: ${data.data.message_id}`));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
console.log(output);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
console.log(output);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function formatMessageOutput(jsonStr, json) {
|
|
144
|
+
if (json) {
|
|
145
|
+
console.log(jsonStr);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const data = JSON.parse(jsonStr);
|
|
150
|
+
// API returns message in data.items array (same format as list)
|
|
151
|
+
if (data.data?.items && data.data.items.length > 0) {
|
|
152
|
+
const msg = data.data.items[0];
|
|
153
|
+
const content = msg.body?.content ? JSON.parse(msg.body.content) : {};
|
|
154
|
+
const text = content.text || 'N/A';
|
|
155
|
+
const time = msg.create_time || 'N/A';
|
|
156
|
+
const sender = msg.sender?.name || msg.sender?.id || 'Unknown';
|
|
157
|
+
const msgType = msg.msg_type || 'N/A';
|
|
158
|
+
console.log(`Message ID: ${chalk.bold(msg.message_id || 'N/A')}`);
|
|
159
|
+
console.log(`Type: ${msgType}`);
|
|
160
|
+
console.log(`Time: ${time}`);
|
|
161
|
+
console.log(`Sender: ${chalk.bold(sender)}`);
|
|
162
|
+
console.log(`Content: ${text}`);
|
|
163
|
+
if (msg.chat_id) {
|
|
164
|
+
console.log(`Chat ID: ${msg.chat_id}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (data.data) {
|
|
168
|
+
// Fallback: try direct data object
|
|
169
|
+
const msg = data.data;
|
|
170
|
+
const content = msg.body?.content ? JSON.parse(msg.body.content) : {};
|
|
171
|
+
const text = content.text || 'N/A';
|
|
172
|
+
const time = msg.create_time || 'N/A';
|
|
173
|
+
const sender = msg.sender?.name || msg.sender?.id || 'Unknown';
|
|
174
|
+
const msgType = msg.msg_type || 'N/A';
|
|
175
|
+
console.log(`Message ID: ${chalk.bold(msg.message_id || 'N/A')}`);
|
|
176
|
+
console.log(`Type: ${msgType}`);
|
|
177
|
+
console.log(`Time: ${time}`);
|
|
178
|
+
console.log(`Sender: ${chalk.bold(sender)}`);
|
|
179
|
+
console.log(`Content: ${text}`);
|
|
180
|
+
if (msg.chat_id) {
|
|
181
|
+
console.log(`Chat ID: ${msg.chat_id}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
console.log(jsonStr);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
console.log(jsonStr);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export function feishuMessageGetCommand(messageId, json) {
|
|
193
|
+
if (!messageId) {
|
|
194
|
+
console.error(chalk.red('✗ --message-id is required'));
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const output = runTmdFeishu(['get', '--message-id', messageId]);
|
|
198
|
+
formatMessageOutput(output, json);
|
|
199
|
+
}
|
|
200
|
+
function formatDocumentOutput(jsonStr, json, raw) {
|
|
201
|
+
if (json) {
|
|
202
|
+
console.log(jsonStr);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
const data = JSON.parse(jsonStr);
|
|
207
|
+
if (raw) {
|
|
208
|
+
// Raw content output
|
|
209
|
+
if (data.data?.content) {
|
|
210
|
+
console.log(data.data.content);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
console.log(jsonStr);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
// Metadata output
|
|
218
|
+
if (data.data) {
|
|
219
|
+
// DocumentInfo has { document: {...} } structure
|
|
220
|
+
const docData = data.data.document || data.data;
|
|
221
|
+
console.log(`Document ID: ${chalk.bold(docData.document_id || 'N/A')}`);
|
|
222
|
+
console.log(`Title: ${docData.title || 'N/A'}`);
|
|
223
|
+
if (docData.revision_id) {
|
|
224
|
+
console.log(`Revision ID: ${docData.revision_id}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log(jsonStr);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
console.log(jsonStr);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export function feishuDocumentsGetCommand(documentId, raw, json) {
|
|
237
|
+
if (!documentId) {
|
|
238
|
+
console.error(chalk.red('✗ --document-id is required'));
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const args = ['documents', 'get', '--document-id', documentId];
|
|
242
|
+
if (raw) {
|
|
243
|
+
args.push('--raw');
|
|
244
|
+
}
|
|
245
|
+
const output = runTmdFeishu(args);
|
|
246
|
+
formatDocumentOutput(output, json, raw);
|
|
247
|
+
}
|
|
248
|
+
function formatBitableOutput(jsonStr, json, type) {
|
|
249
|
+
if (json) {
|
|
250
|
+
console.log(jsonStr);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
const data = JSON.parse(jsonStr);
|
|
255
|
+
if (data.data?.items) {
|
|
256
|
+
const items = data.data.items;
|
|
257
|
+
if (items.length === 0) {
|
|
258
|
+
console.log(`No ${type} found.`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
console.log(`Found ${items.length} ${type}(s):\n`);
|
|
262
|
+
for (const item of items) {
|
|
263
|
+
if (type === 'table') {
|
|
264
|
+
console.log(` ${chalk.bold(item.table_id || 'N/A')} - ${item.name || 'Unnamed'}`);
|
|
265
|
+
}
|
|
266
|
+
else if (type === 'view') {
|
|
267
|
+
console.log(` ${chalk.bold(item.view_id || 'N/A')} - ${item.view_name || item.name || 'Unnamed'} (${item.view_type || 'N/A'})`);
|
|
268
|
+
}
|
|
269
|
+
else if (type === 'record') {
|
|
270
|
+
const recordId = item.record_id || 'N/A';
|
|
271
|
+
const fields = item.fields ? Object.keys(item.fields).join(', ') : 'No fields';
|
|
272
|
+
console.log(` ${chalk.bold(recordId)} - Fields: ${fields}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else if (data.data) {
|
|
277
|
+
// Single item output
|
|
278
|
+
const item = data.data;
|
|
279
|
+
if (type === 'metadata') {
|
|
280
|
+
// BitableMetadata has { app: {...} } structure
|
|
281
|
+
const app = item.app || item;
|
|
282
|
+
console.log(`App Token: ${chalk.bold(app.app_token || 'N/A')}`);
|
|
283
|
+
console.log(`Name: ${app.name || 'N/A'}`);
|
|
284
|
+
if (app.revision) {
|
|
285
|
+
console.log(`Revision: ${app.revision}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else if (type === 'view') {
|
|
289
|
+
// Handle both direct view object and wrapped { view: {...} } response
|
|
290
|
+
const view = item.view || item;
|
|
291
|
+
console.log(`View ID: ${chalk.bold(view.view_id || 'N/A')}`);
|
|
292
|
+
console.log(`Name: ${view.view_name || view.name || 'N/A'}`);
|
|
293
|
+
console.log(`Type: ${view.view_type || 'N/A'}`);
|
|
294
|
+
}
|
|
295
|
+
else if (type === 'record') {
|
|
296
|
+
// Handle both direct record object and wrapped { record: {...} } response
|
|
297
|
+
const record = item.record || item;
|
|
298
|
+
const recordId = record.record_id || 'N/A';
|
|
299
|
+
console.log(`Record ID: ${chalk.bold(recordId)}`);
|
|
300
|
+
if (record.fields) {
|
|
301
|
+
console.log('Fields:');
|
|
302
|
+
for (const [key, value] of Object.entries(record.fields)) {
|
|
303
|
+
console.log(` ${key}: ${JSON.stringify(value)}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
console.log(jsonStr);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
console.log(jsonStr);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
export function feishuBitableGetCommand(sheetId, json) {
|
|
317
|
+
if (!sheetId) {
|
|
318
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
const output = runTmdFeishu(['bitable', 'get', '--sheet-id', sheetId]);
|
|
322
|
+
formatBitableOutput(output, json, 'metadata');
|
|
323
|
+
}
|
|
324
|
+
export function feishuBitableTablesCommand(sheetId, json) {
|
|
325
|
+
if (!sheetId) {
|
|
326
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
const output = runTmdFeishu(['bitable', 'tables', '--sheet-id', sheetId]);
|
|
330
|
+
formatBitableOutput(output, json, 'table');
|
|
331
|
+
}
|
|
332
|
+
export function feishuBitableViewsCommand(sheetId, tableId, json) {
|
|
333
|
+
if (!sheetId) {
|
|
334
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
335
|
+
process.exit(1);
|
|
336
|
+
}
|
|
337
|
+
if (!tableId) {
|
|
338
|
+
console.error(chalk.red('✗ --table-id is required'));
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
const output = runTmdFeishu(['bitable', 'views', '--sheet-id', sheetId, '--table-id', tableId]);
|
|
342
|
+
formatBitableOutput(output, json, 'view');
|
|
343
|
+
}
|
|
344
|
+
export function feishuBitableViewCommand(sheetId, tableId, viewId, json) {
|
|
345
|
+
if (!sheetId) {
|
|
346
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
349
|
+
if (!tableId) {
|
|
350
|
+
console.error(chalk.red('✗ --table-id is required'));
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
if (!viewId) {
|
|
354
|
+
console.error(chalk.red('✗ --view-id is required'));
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
357
|
+
const output = runTmdFeishu(['bitable', 'view', '--sheet-id', sheetId, '--table-id', tableId, '--view-id', viewId]);
|
|
358
|
+
formatBitableOutput(output, json, 'view');
|
|
359
|
+
}
|
|
360
|
+
export function feishuBitableRecordsCommand(sheetId, tableId, json) {
|
|
361
|
+
if (!sheetId) {
|
|
362
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
if (!tableId) {
|
|
366
|
+
console.error(chalk.red('✗ --table-id is required'));
|
|
367
|
+
process.exit(1);
|
|
368
|
+
}
|
|
369
|
+
const output = runTmdFeishu(['bitable', 'records', '--sheet-id', sheetId, '--table-id', tableId]);
|
|
370
|
+
formatBitableOutput(output, json, 'record');
|
|
371
|
+
}
|
|
372
|
+
export function feishuBitableRecordCommand(sheetId, tableId, recordId, json) {
|
|
373
|
+
if (!sheetId) {
|
|
374
|
+
console.error(chalk.red('✗ --sheet-id is required'));
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
if (!tableId) {
|
|
378
|
+
console.error(chalk.red('✗ --table-id is required'));
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
if (!recordId) {
|
|
382
|
+
console.error(chalk.red('✗ --record-id is required'));
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
const output = runTmdFeishu(['bitable', 'record', '--sheet-id', sheetId, '--table-id', tableId, '--record-id', recordId]);
|
|
386
|
+
formatBitableOutput(output, json, 'record');
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=feishu.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface KnowledgeCommandOptions {
|
|
2
|
+
create?: boolean;
|
|
3
|
+
knowledgeId?: string;
|
|
4
|
+
dir?: string;
|
|
5
|
+
agentId?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function knowledgeCommand(action: string, options: KnowledgeCommandOptions): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=knowledge.d.ts.map
|