metame-cli 1.3.16 → 1.3.18
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 +86 -24
- package/index.js +269 -38
- package/package.json +1 -1
- package/scripts/daemon-default.yaml +23 -7
- package/scripts/daemon.js +794 -224
- package/scripts/feishu-adapter.js +76 -5
- package/scripts/signal-capture.js +0 -6
|
@@ -38,7 +38,7 @@ function createBot(config) {
|
|
|
38
38
|
* Send a plain text message
|
|
39
39
|
*/
|
|
40
40
|
async sendMessage(chatId, text) {
|
|
41
|
-
await client.im.message.create({
|
|
41
|
+
const res = await client.im.message.create({
|
|
42
42
|
params: { receive_id_type: 'chat_id' },
|
|
43
43
|
data: {
|
|
44
44
|
receive_id: chatId,
|
|
@@ -46,20 +46,91 @@ function createBot(config) {
|
|
|
46
46
|
content: JSON.stringify({ text }),
|
|
47
47
|
},
|
|
48
48
|
});
|
|
49
|
+
// Return Telegram-compatible shape so daemon can edit it later
|
|
50
|
+
const msgId = res?.data?.message_id;
|
|
51
|
+
return msgId ? { message_id: msgId } : null;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
async editMessage(chatId, messageId, text) {
|
|
55
|
+
try {
|
|
56
|
+
await client.im.message.patch({
|
|
57
|
+
path: { message_id: messageId },
|
|
58
|
+
data: { content: JSON.stringify({ text }) },
|
|
59
|
+
});
|
|
60
|
+
} catch { /* non-fatal */ }
|
|
49
61
|
},
|
|
50
62
|
|
|
51
63
|
/**
|
|
52
|
-
* Send markdown
|
|
64
|
+
* Send markdown as Feishu interactive card (lark_md renders bold, lists, code, links)
|
|
53
65
|
*/
|
|
54
66
|
async sendMarkdown(chatId, markdown) {
|
|
55
|
-
|
|
67
|
+
// Convert standard markdown → lark_md compatible format
|
|
68
|
+
let content = markdown
|
|
69
|
+
.replace(/^(#{1,3})\s+(.+)$/gm, '**$2**') // headers → bold
|
|
70
|
+
.replace(/^---+$/gm, '─────────────────────'); // hr → unicode line
|
|
71
|
+
|
|
72
|
+
// Split into chunks if too long (lark_md element limit ~4000 chars)
|
|
73
|
+
const MAX_CHUNK = 3800;
|
|
74
|
+
const chunks = [];
|
|
75
|
+
if (content.length <= MAX_CHUNK) {
|
|
76
|
+
chunks.push(content);
|
|
77
|
+
} else {
|
|
78
|
+
// Split on double newlines to avoid breaking mid-paragraph
|
|
79
|
+
const paragraphs = content.split(/\n\n/);
|
|
80
|
+
let buf = '';
|
|
81
|
+
for (const p of paragraphs) {
|
|
82
|
+
if (buf.length + p.length + 2 > MAX_CHUNK && buf) {
|
|
83
|
+
chunks.push(buf);
|
|
84
|
+
buf = p;
|
|
85
|
+
} else {
|
|
86
|
+
buf = buf ? buf + '\n\n' + p : p;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (buf) chunks.push(buf);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const elements = chunks.map(c => ({
|
|
93
|
+
tag: 'div',
|
|
94
|
+
text: { tag: 'lark_md', content: c },
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
const card = {
|
|
98
|
+
config: { wide_screen_mode: true },
|
|
99
|
+
elements,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const res = await client.im.message.create({
|
|
56
103
|
params: { receive_id_type: 'chat_id' },
|
|
57
104
|
data: {
|
|
58
105
|
receive_id: chatId,
|
|
59
|
-
msg_type: '
|
|
60
|
-
content: JSON.stringify(
|
|
106
|
+
msg_type: 'interactive',
|
|
107
|
+
content: JSON.stringify(card),
|
|
61
108
|
},
|
|
62
109
|
});
|
|
110
|
+
const msgId = res?.data?.message_id;
|
|
111
|
+
return msgId ? { message_id: msgId } : null;
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Send a colored interactive card (for project-tagged notifications)
|
|
116
|
+
* @param {string} chatId
|
|
117
|
+
* @param {string} title - card header text
|
|
118
|
+
* @param {string} body - card body (lark markdown)
|
|
119
|
+
* @param {string} color - header color: blue|orange|green|red|grey|purple|turquoise
|
|
120
|
+
*/
|
|
121
|
+
async sendCard(chatId, { title, body, color = 'blue' }) {
|
|
122
|
+
const elements = body ? [{ tag: 'div', text: { tag: 'lark_md', content: body } }] : [];
|
|
123
|
+
const card = {
|
|
124
|
+
config: { wide_screen_mode: true },
|
|
125
|
+
header: { title: { tag: 'plain_text', content: title }, template: color },
|
|
126
|
+
elements,
|
|
127
|
+
};
|
|
128
|
+
const res = await client.im.message.create({
|
|
129
|
+
params: { receive_id_type: 'chat_id' },
|
|
130
|
+
data: { receive_id: chatId, msg_type: 'interactive', content: JSON.stringify(card) },
|
|
131
|
+
});
|
|
132
|
+
const msgId = res?.data?.message_id;
|
|
133
|
+
return msgId ? { message_id: msgId } : null;
|
|
63
134
|
},
|
|
64
135
|
|
|
65
136
|
/**
|
|
@@ -13,7 +13,6 @@ const path = require('path');
|
|
|
13
13
|
const os = require('os');
|
|
14
14
|
|
|
15
15
|
const BUFFER_FILE = path.join(os.homedir(), '.metame', 'raw_signals.jsonl');
|
|
16
|
-
const MAX_BUFFER_LINES = 50; // Safety cap to avoid unbounded growth
|
|
17
16
|
|
|
18
17
|
// === CONFIDENCE PATTERNS ===
|
|
19
18
|
|
|
@@ -110,11 +109,6 @@ process.stdin.on('end', () => {
|
|
|
110
109
|
|
|
111
110
|
existingLines.push(JSON.stringify(entry));
|
|
112
111
|
|
|
113
|
-
// Keep only the most recent entries (drop oldest)
|
|
114
|
-
if (existingLines.length > MAX_BUFFER_LINES) {
|
|
115
|
-
existingLines = existingLines.slice(-MAX_BUFFER_LINES);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
112
|
fs.writeFileSync(BUFFER_FILE, existingLines.join('\n') + '\n');
|
|
119
113
|
|
|
120
114
|
} catch {
|