cueme 0.1.1 → 0.1.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 +11 -9
- package/bin/cue-command.js +0 -0
- package/package.json +2 -2
- package/src/cli.js +25 -14
- package/src/db.js +24 -17
- package/src/handler.js +2 -36
package/README.md
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
# cueme
|
|
2
2
|
|
|
3
|
-
A command protocol adapter for Cue
|
|
3
|
+
A command protocol adapter for Cue, compatible with the existing SQLite mailbox (`~/.cue/cue.db`).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick start (2 steps)
|
|
6
|
+
|
|
7
|
+
### Step 1: Install cueme
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install -g cueme
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
### Step 2: Configure the protocol.md as your system prompt
|
|
14
|
+
|
|
15
|
+
Add the contents of `cue-command/protocol.md` to your tool's system prompt / rules.
|
|
16
|
+
|
|
17
|
+
This file defines the Human Agent Protocol (HAP) rules and the `cueme` command interface.
|
|
18
|
+
|
|
11
19
|
## Usage
|
|
12
20
|
|
|
13
21
|
### join
|
|
@@ -34,13 +42,7 @@ cueme cue --agent_id "tavilron" --prompt "What should I do next?" --timeout 600
|
|
|
34
42
|
cueme pause --agent_id "tavilron" --prompt "Waiting..."
|
|
35
43
|
```
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
echo '{"cmd":"join"}' | cueme rpc
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
All commands output one JSON object to stdout.
|
|
45
|
+
All commands output plain text to stdout.
|
|
44
46
|
|
|
45
47
|
## Release
|
|
46
48
|
|
package/bin/cue-command.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cueme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Cue command protocol adapter (stdin/stdout JSON)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"files": [
|
|
@@ -20,6 +20,6 @@
|
|
|
20
20
|
"prepare": "node -c src/cli.js && node -c src/handler.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"sqlite3": "^
|
|
23
|
+
"better-sqlite3": "^11.7.0"
|
|
24
24
|
}
|
|
25
25
|
}
|
package/src/cli.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const { readAllStdin } = require('./io');
|
|
2
1
|
const { handleCommand } = require('./handler');
|
|
3
2
|
|
|
4
3
|
function parseArgs(argv) {
|
|
@@ -25,6 +24,26 @@ function parseArgs(argv) {
|
|
|
25
24
|
return out;
|
|
26
25
|
}
|
|
27
26
|
|
|
27
|
+
function extractTextFromResult(result) {
|
|
28
|
+
if (!result || typeof result !== 'object') return '';
|
|
29
|
+
if (result.ok === false) return result.error ? String(result.error) : '';
|
|
30
|
+
|
|
31
|
+
const data = result.data;
|
|
32
|
+
if (!data || typeof data !== 'object') return '';
|
|
33
|
+
|
|
34
|
+
const contents = Array.isArray(data.contents) ? data.contents : [];
|
|
35
|
+
const textParts = [];
|
|
36
|
+
for (const c of contents) {
|
|
37
|
+
if (c && c.type === 'text' && typeof c.text === 'string' && c.text.length > 0) {
|
|
38
|
+
textParts.push(c.text);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (textParts.length > 0) return textParts.join('');
|
|
42
|
+
|
|
43
|
+
if (typeof data.message === 'string') return data.message;
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
|
|
28
47
|
async function main() {
|
|
29
48
|
const parsed = parseArgs(process.argv);
|
|
30
49
|
const sub = parsed._[0];
|
|
@@ -32,31 +51,23 @@ async function main() {
|
|
|
32
51
|
if (!sub || sub === 'help' || sub === '-h' || sub === '--help') {
|
|
33
52
|
process.stdout.write(
|
|
34
53
|
[
|
|
35
|
-
'cueme
|
|
54
|
+
'cueme',
|
|
36
55
|
'',
|
|
37
56
|
'Usage:',
|
|
38
57
|
' cueme join',
|
|
39
58
|
' cueme recall --hints "..."',
|
|
40
59
|
' cueme cue --agent_id "..." --prompt "..." [--payload "{...}"] [--timeout 600]',
|
|
41
60
|
' cueme pause --agent_id "..." [--prompt "..."]',
|
|
42
|
-
' cueme rpc # read one JSON object from stdin: {"cmd":...}',
|
|
43
61
|
'',
|
|
44
|
-
'
|
|
62
|
+
'Output:',
|
|
63
|
+
' - join/recall/cue/pause: plain text (stdout)',
|
|
45
64
|
].join('\n') + '\n'
|
|
46
65
|
);
|
|
47
66
|
return;
|
|
48
67
|
}
|
|
49
68
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const raw = await readAllStdin();
|
|
53
|
-
if (raw.trim().length > 0) {
|
|
54
|
-
input = JSON.parse(raw);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const result = await handleCommand({ subcommand: sub, args: parsed, input });
|
|
59
|
-
process.stdout.write(JSON.stringify(result) + '\n');
|
|
69
|
+
const result = await handleCommand({ subcommand: sub, args: parsed });
|
|
70
|
+
process.stdout.write(extractTextFromResult(result) + '\n');
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
module.exports = { main };
|
package/src/db.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const
|
|
4
|
+
const Database = require('better-sqlite3');
|
|
5
5
|
|
|
6
6
|
function getDbPath() {
|
|
7
7
|
return path.join(os.homedir(), '.cue', 'cue.db');
|
|
@@ -15,26 +15,18 @@ function ensureDbDir() {
|
|
|
15
15
|
|
|
16
16
|
function openDb() {
|
|
17
17
|
const dbPath = ensureDbDir();
|
|
18
|
-
const db = new
|
|
18
|
+
const db = new Database(dbPath);
|
|
19
19
|
return { db, dbPath };
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function run(db, sql, params = []) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (err) return reject(err);
|
|
26
|
-
resolve({ lastID: this.lastID, changes: this.changes });
|
|
27
|
-
});
|
|
28
|
-
});
|
|
22
|
+
async function run(db, sql, params = []) {
|
|
23
|
+
const info = db.prepare(sql).run(params);
|
|
24
|
+
return { lastID: info.lastInsertRowid, changes: info.changes };
|
|
29
25
|
}
|
|
30
26
|
|
|
31
|
-
function get(db, sql, params = []) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (err) return reject(err);
|
|
35
|
-
resolve(row || null);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
27
|
+
async function get(db, sql, params = []) {
|
|
28
|
+
const row = db.prepare(sql).get(params);
|
|
29
|
+
return row || null;
|
|
38
30
|
}
|
|
39
31
|
|
|
40
32
|
async function initSchema(db) {
|
|
@@ -74,7 +66,22 @@ async function initSchema(db) {
|
|
|
74
66
|
}
|
|
75
67
|
|
|
76
68
|
function nowIso() {
|
|
77
|
-
|
|
69
|
+
const now = new Date();
|
|
70
|
+
const offset = -now.getTimezoneOffset();
|
|
71
|
+
const sign = offset >= 0 ? '+' : '-';
|
|
72
|
+
const pad = (n) => String(Math.abs(n)).padStart(2, '0');
|
|
73
|
+
const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
|
|
74
|
+
const offsetMinutes = pad(Math.abs(offset) % 60);
|
|
75
|
+
|
|
76
|
+
const year = now.getFullYear();
|
|
77
|
+
const month = pad(now.getMonth() + 1);
|
|
78
|
+
const day = pad(now.getDate());
|
|
79
|
+
const hours = pad(now.getHours());
|
|
80
|
+
const minutes = pad(now.getMinutes());
|
|
81
|
+
const seconds = pad(now.getSeconds());
|
|
82
|
+
const ms = String(now.getMilliseconds()).padStart(3, '0');
|
|
83
|
+
|
|
84
|
+
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${ms}${sign}${offsetHours}:${offsetMinutes}`;
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
module.exports = { openDb, initSchema, run, get, nowIso, getDbPath };
|
package/src/handler.js
CHANGED
|
@@ -86,7 +86,7 @@ async function handleJoin(db) {
|
|
|
86
86
|
async function handleRecall(db, hints) {
|
|
87
87
|
const row = await get(
|
|
88
88
|
db,
|
|
89
|
-
|
|
89
|
+
"SELECT agent_id FROM cue_requests WHERE agent_id != '' AND prompt LIKE ? ORDER BY created_at DESC LIMIT 1",
|
|
90
90
|
[`%${hints}%`]
|
|
91
91
|
);
|
|
92
92
|
|
|
@@ -220,15 +220,6 @@ async function handleCueLike(db, { mode, agent_id, prompt, payload, timeoutSecon
|
|
|
220
220
|
};
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
if (mode === 'cue') {
|
|
224
|
-
const updated_at = nowIso();
|
|
225
|
-
await run(
|
|
226
|
-
db,
|
|
227
|
-
'UPDATE cue_requests SET status = ?, updated_at = ? WHERE request_id = ?',
|
|
228
|
-
['COMPLETED', updated_at, request_id]
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
223
|
return {
|
|
233
224
|
ok: true,
|
|
234
225
|
data: {
|
|
@@ -287,36 +278,11 @@ async function handlePause(db, { agent_id, prompt }) {
|
|
|
287
278
|
});
|
|
288
279
|
}
|
|
289
280
|
|
|
290
|
-
async function handleCommand({ subcommand, args
|
|
281
|
+
async function handleCommand({ subcommand, args }) {
|
|
291
282
|
const { db, dbPath } = openDb();
|
|
292
283
|
try {
|
|
293
284
|
await initSchema(db);
|
|
294
285
|
|
|
295
|
-
if (subcommand === 'rpc') {
|
|
296
|
-
if (!input || typeof input !== 'object') {
|
|
297
|
-
return { ok: false, error: 'rpc expects a JSON object on stdin' };
|
|
298
|
-
}
|
|
299
|
-
const cmd = input.cmd;
|
|
300
|
-
if (cmd === 'join') return await handleJoin(db);
|
|
301
|
-
if (cmd === 'recall') return await handleRecall(db, String(input.hints || ''));
|
|
302
|
-
if (cmd === 'cue') {
|
|
303
|
-
return await handleCueLike(db, {
|
|
304
|
-
mode: 'cue',
|
|
305
|
-
agent_id: String(input.agent_id || ''),
|
|
306
|
-
prompt: String(input.prompt || ''),
|
|
307
|
-
payload: input.payload == null ? null : String(input.payload),
|
|
308
|
-
timeoutSeconds: input.timeout == null ? 600 : Number(input.timeout),
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
if (cmd === 'pause') {
|
|
312
|
-
return await handlePause(db, {
|
|
313
|
-
agent_id: String(input.agent_id || ''),
|
|
314
|
-
prompt: input.prompt == null ? null : String(input.prompt),
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
return { ok: false, error: `unknown cmd: ${cmd}` };
|
|
318
|
-
}
|
|
319
|
-
|
|
320
286
|
if (subcommand === 'join') return await handleJoin(db);
|
|
321
287
|
|
|
322
288
|
if (subcommand === 'recall') {
|