cueme 0.1.6 → 0.1.7
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/package.json +1 -1
- package/protocol.md +12 -26
- package/src/cli.js +3 -14
- package/src/envelope.js +4 -1
- package/src/handler.js +5 -38
- package/src/proto.js +25 -18
package/package.json
CHANGED
package/protocol.md
CHANGED
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
你与用户的协作交互通过命令行工具 `cueme` 完成。
|
|
4
4
|
|
|
5
|
+
- 首次连接 / 无 agent_id:先执行 `join()` 获取 agent_id,再执行 `cue()`。
|
|
6
|
+
|
|
7
|
+
- 重连 / 已有 agent_id(例如网络波动导致 cue 中断但对话仍在继续):用户再次发送 `cue` 时,优先直接用已有 agent_id 执行 `cue()`;仅当无法确认 agent_id 时才重新 `join()`。
|
|
8
|
+
|
|
5
9
|
当用户接受 HAP:你必须在每次阶段性输出或准备结束回复前调用 `cueme cue`(或 `cueme pause`)等待用户继续。
|
|
6
10
|
|
|
7
11
|
If HAP is accepted: before any phase-summary or final reply, you MUST call `cueme cue` via the terminal/tool.
|
|
8
12
|
A reply is NOT complete unless the last action is a successful cueme call.
|
|
9
13
|
|
|
10
|
-
- 首次连接 / 无 agent_id:先执行 `join()` 获取 agent_id,再执行 `cue()`。
|
|
11
|
-
|
|
12
|
-
- 重连 / 已有 agent_id(例如网络波动导致 cue 中断但对话仍在继续):用户再次发送 `cue` 时,优先直接用已有 agent_id 执行 `cue()`;仅当无法确认 agent_id 时才重新 `join()`。
|
|
13
|
-
|
|
14
14
|
## No fake tool actions
|
|
15
15
|
|
|
16
16
|
You MUST NOT claim you called cueme unless you actually executed it and got its stdout.
|
|
17
17
|
If you cannot run tools, say "TOOLS_UNAVAILABLE" and output only the exact `cueme ...` command for the human to run.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
|
|
21
21
|
## cueme (command interface)
|
|
22
22
|
|
|
23
|
+
cueme 命令不可放在后台运行.All cueme commands must run in blocking/foreground mode to ensure proper interaction flow.
|
|
24
|
+
|
|
23
25
|
### join() -> message
|
|
24
26
|
|
|
25
27
|
Command:
|
|
@@ -36,30 +38,20 @@ Returns (plain text):
|
|
|
36
38
|
- Format: lowercase, `_` only.
|
|
37
39
|
- Examples: `windsurf`, `cursor`, `vscode`, `claude_code`, `terminal`, `codex`, `kiro`, `opencode`.
|
|
38
40
|
|
|
39
|
-
###
|
|
41
|
+
### cue(agent_id: str, stdin: {prompt: str!, payload?: object | null}) -> text
|
|
40
42
|
|
|
41
|
-
Command:
|
|
42
|
-
|
|
43
|
-
- `cueme recall <hints>`
|
|
44
|
-
|
|
45
|
-
Returns (plain text):
|
|
46
|
-
|
|
47
|
-
- a short message (includes `agent_id=...`)
|
|
48
|
-
|
|
49
|
-
### cue(prompt: str, agent_id: str, payload?: object | null) -> text
|
|
50
|
-
|
|
51
|
-
Command:
|
|
43
|
+
Command (requires stdin):
|
|
52
44
|
|
|
53
45
|
`cueme cue <agent_id> -`
|
|
54
46
|
|
|
55
|
-
stdin
|
|
47
|
+
Provide via stdin (tag-block envelope, MUST NOT be empty; bash/zsh use heredoc; PowerShell use here-string):
|
|
56
48
|
|
|
57
49
|
<cueme_prompt>
|
|
58
|
-
|
|
50
|
+
Your actual prompt text here
|
|
59
51
|
</cueme_prompt>
|
|
60
52
|
|
|
61
53
|
<cueme_payload>
|
|
62
|
-
|
|
54
|
+
{"type":"confirm","text":"Continue?"}
|
|
63
55
|
</cueme_payload>
|
|
64
56
|
|
|
65
57
|
Rules:
|
|
@@ -82,12 +74,6 @@ Payload protocol (payload object):
|
|
|
82
74
|
- confirm: {"type":"confirm","text":"...","confirm_label":"Confirm","cancel_label":"Cancel"}
|
|
83
75
|
- form: {"type":"form","fields":[{"label":"...","kind":"text","options":["...",...],"allow_multiple":false}, ...]}
|
|
84
76
|
|
|
85
|
-
Minimal examples:
|
|
86
|
-
|
|
87
|
-
- choice: {"type":"choice","options":["Continue","Stop"]}
|
|
88
|
-
- confirm: {"type":"confirm","text":"Continue?"}
|
|
89
|
-
- form: {"type":"form","fields":[{"label":"Env","options":["prod","staging"]}]}
|
|
90
|
-
|
|
91
77
|
### pause(agent_id: str, prompt?: str) -> text
|
|
92
78
|
|
|
93
79
|
Command:
|
package/src/cli.js
CHANGED
|
@@ -103,7 +103,6 @@ async function main() {
|
|
|
103
103
|
' cueme proto ls',
|
|
104
104
|
' cueme proto path <agent>',
|
|
105
105
|
' cueme join <agent_runtime>',
|
|
106
|
-
' cueme recall <hints>',
|
|
107
106
|
' cueme cue <agent_id> -',
|
|
108
107
|
' cueme pause <agent_id> [prompt|-]',
|
|
109
108
|
'',
|
|
@@ -121,7 +120,7 @@ async function main() {
|
|
|
121
120
|
' </cueme_prompt>',
|
|
122
121
|
'',
|
|
123
122
|
'Output:',
|
|
124
|
-
' - join/
|
|
123
|
+
' - join/cue/pause: plain text (stdout)',
|
|
125
124
|
].join('\n') + '\n'
|
|
126
125
|
);
|
|
127
126
|
return;
|
|
@@ -133,8 +132,8 @@ async function main() {
|
|
|
133
132
|
return;
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
if (parsed.agent_id != null || parsed.prompt != null
|
|
137
|
-
process.stderr.write('error: --agent_id/--prompt
|
|
135
|
+
if (parsed.agent_id != null || parsed.prompt != null) {
|
|
136
|
+
process.stderr.write('error: --agent_id/--prompt flags are not supported; use positional args\n');
|
|
138
137
|
process.exitCode = 2;
|
|
139
138
|
return;
|
|
140
139
|
}
|
|
@@ -149,16 +148,6 @@ async function main() {
|
|
|
149
148
|
parsed.agent_runtime = String(agentRuntime);
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
if (sub === 'recall') {
|
|
153
|
-
const hints = pos[0];
|
|
154
|
-
if (!hints) {
|
|
155
|
-
process.stderr.write('error: missing <hints>\n');
|
|
156
|
-
process.exitCode = 2;
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
parsed.hints = String(hints);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
151
|
if (sub === 'proto') {
|
|
163
152
|
const action = pos[0];
|
|
164
153
|
try {
|
package/src/envelope.js
CHANGED
|
@@ -3,7 +3,10 @@ function parseTagBlocksEnvelope(raw, opts = {}) {
|
|
|
3
3
|
const text = String(raw == null ? '' : raw);
|
|
4
4
|
const trimmed = text.trim();
|
|
5
5
|
if (!trimmed) {
|
|
6
|
-
|
|
6
|
+
// Fallback: use default prompt based on command type
|
|
7
|
+
// allowPayload === true means cue command, false means pause command
|
|
8
|
+
const defaultPrompt = allowPayload ? 'hi' : 'pause';
|
|
9
|
+
return { ok: true, prompt: defaultPrompt, payload: null };
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
if (trimmed.startsWith('{')) {
|
package/src/handler.js
CHANGED
|
@@ -148,39 +148,11 @@ async function handleJoin(db, agent_runtime) {
|
|
|
148
148
|
`project_dir=${project_dir}\n` +
|
|
149
149
|
`agent_terminal=${agent_terminal}\n` +
|
|
150
150
|
`agent_runtime=${normalized_runtime}\n\n` +
|
|
151
|
-
'Use this agent_id when calling cue
|
|
152
|
-
'
|
|
153
|
-
'
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async function handleRecall(db, hints) {
|
|
159
|
-
const row = await get(
|
|
160
|
-
db,
|
|
161
|
-
"SELECT agent_id FROM cue_requests WHERE agent_id != '' AND prompt LIKE ? ORDER BY created_at DESC LIMIT 1",
|
|
162
|
-
[`%${hints}%`]
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
if (row && row.agent_id) {
|
|
166
|
-
return {
|
|
167
|
-
ok: true,
|
|
168
|
-
data: {
|
|
169
|
-
agent_id: row.agent_id,
|
|
170
|
-
message: `agent_id=${row.agent_id}\n\nUse this agent_id when calling cue(prompt, agent_id).`,
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const agent_id = generateName();
|
|
176
|
-
return {
|
|
177
|
-
ok: true,
|
|
178
|
-
data: {
|
|
179
|
-
agent_id,
|
|
180
|
-
message:
|
|
181
|
-
'No matching record found; generated a new agent_id.\n\n' +
|
|
182
|
-
`agent_id=${agent_id}\n\n` +
|
|
183
|
-
'Use this agent_id when calling cue(prompt, agent_id).',
|
|
151
|
+
'Use this agent_id when calling: cueme cue <agent_id> -\n' +
|
|
152
|
+
'Then provide stdin with tag-block envelope (stdin MUST NOT be empty):\n' +
|
|
153
|
+
'<cueme_prompt>\n...\n</cueme_prompt>\n' +
|
|
154
|
+
'<cueme_payload>\n...\n</cueme_payload>\n\n' +
|
|
155
|
+
'Remember this agent_id (but do NOT store it in any memory module). Before ending this session, call cue to provide a final summary, ask a question, or make a request.',
|
|
184
156
|
},
|
|
185
157
|
};
|
|
186
158
|
}
|
|
@@ -358,11 +330,6 @@ async function handleCommand({ subcommand, args }) {
|
|
|
358
330
|
|
|
359
331
|
if (subcommand === 'join') return await handleJoin(db, args.agent_runtime);
|
|
360
332
|
|
|
361
|
-
if (subcommand === 'recall') {
|
|
362
|
-
const hints = (args.hints ?? '').toString();
|
|
363
|
-
return await handleRecall(db, hints);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
333
|
if (subcommand === 'cue') {
|
|
367
334
|
const agent_id = (args.agent_id ?? '').toString();
|
|
368
335
|
const prompt = (args.prompt ?? '').toString();
|
package/src/proto.js
CHANGED
|
@@ -51,22 +51,22 @@ function detectVscodeCandidates({ platform }) {
|
|
|
51
51
|
const cwd = process.cwd();
|
|
52
52
|
|
|
53
53
|
// Workspace-level (if you want repo-local rules)
|
|
54
|
-
candidates.push(path.join(cwd, '.vscode', 'prompts', '
|
|
54
|
+
candidates.push(path.join(cwd, '.vscode', 'prompts', 'cueme_proto.instructions.md'));
|
|
55
55
|
|
|
56
56
|
// User-level prompts
|
|
57
57
|
const home = os.homedir();
|
|
58
58
|
if (platform === 'macos') {
|
|
59
59
|
candidates.push(
|
|
60
|
-
path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts', '
|
|
60
|
+
path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts', 'cueme_proto.instructions.md')
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
63
|
if (platform === 'linux') {
|
|
64
64
|
// User supplied: ~/.config/Code/User/prompts/
|
|
65
|
-
candidates.push(path.join(home, '.config', 'Code', 'User', 'prompts', '
|
|
65
|
+
candidates.push(path.join(home, '.config', 'Code', 'User', 'prompts', 'cueme_proto.instructions.md'));
|
|
66
66
|
}
|
|
67
67
|
if (platform === 'windows') {
|
|
68
68
|
const appData = process.env.APPDATA;
|
|
69
|
-
if (appData) candidates.push(path.join(appData, 'Code', 'User', 'prompts', '
|
|
69
|
+
if (appData) candidates.push(path.join(appData, 'Code', 'User', 'prompts', 'cueme_proto.instructions.md'));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
return candidates;
|
|
@@ -113,12 +113,12 @@ function defaultPathMapTemplate() {
|
|
|
113
113
|
'Code',
|
|
114
114
|
'User',
|
|
115
115
|
'prompts',
|
|
116
|
-
'
|
|
116
|
+
'cueme_proto.instructions.md'
|
|
117
117
|
);
|
|
118
118
|
out['windows.vscode'] = appData
|
|
119
|
-
? path.join(appData, 'Code', 'User', 'prompts', '
|
|
120
|
-
: path.join(userProfile, 'AppData', 'Roaming', 'Code', 'User', 'prompts', '
|
|
121
|
-
out['linux.vscode'] = path.join(home, '.config', 'Code', 'User', 'prompts', '
|
|
119
|
+
? path.join(appData, 'Code', 'User', 'prompts', 'cueme_proto.instructions.md')
|
|
120
|
+
: path.join(userProfile, 'AppData', 'Roaming', 'Code', 'User', 'prompts', 'cueme_proto.instructions.md');
|
|
121
|
+
out['linux.vscode'] = path.join(home, '.config', 'Code', 'User', 'prompts', 'cueme_proto.instructions.md');
|
|
122
122
|
|
|
123
123
|
// Windsurf
|
|
124
124
|
out['macos.windsurf'] = path.join(home, '.codeium', 'windsurf', 'memories', 'global_rules.md');
|
|
@@ -256,7 +256,7 @@ function buildFinalProto({ cfg, agent }) {
|
|
|
256
256
|
throw new Error('error: cannot read protocol.md');
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
return
|
|
259
|
+
return { prefix, protocol };
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
function resolveTargetPath({ cfg, agent }) {
|
|
@@ -271,15 +271,22 @@ function resolveTargetPath({ cfg, agent }) {
|
|
|
271
271
|
return path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
function makeManagedBlock({
|
|
275
|
-
const
|
|
276
|
-
const protoLines =
|
|
277
|
-
|
|
274
|
+
function makeManagedBlock({ prefix, protocol, eol }) {
|
|
275
|
+
const normalizedProto = String(protocol || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
276
|
+
const protoLines = normalizedProto.split('\n');
|
|
277
|
+
const managedBlock = [BEGIN_MARKER, ...protoLines, END_MARKER].join(eol) + eol;
|
|
278
|
+
|
|
279
|
+
if (prefix && prefix.trim()) {
|
|
280
|
+
const normalizedPrefix = String(prefix).replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
281
|
+
return normalizedPrefix + eol + eol + managedBlock;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return managedBlock;
|
|
278
285
|
}
|
|
279
286
|
|
|
280
|
-
function applyManagedBlock({ existing,
|
|
287
|
+
function applyManagedBlock({ existing, prefix, protocol }) {
|
|
281
288
|
const eol = detectEol(existing);
|
|
282
|
-
const block = makeManagedBlock({
|
|
289
|
+
const block = makeManagedBlock({ prefix, protocol, eol });
|
|
283
290
|
|
|
284
291
|
const beginMatch = existing.match(BEGIN_MARKER_RE);
|
|
285
292
|
const endMatch = existing.match(END_MARKER_RE);
|
|
@@ -333,7 +340,7 @@ function protoLs() {
|
|
|
333
340
|
function protoApply(agent) {
|
|
334
341
|
const cfg = readConfigOrThrow({ auto_init: true });
|
|
335
342
|
const targetPath = resolveTargetPath({ cfg, agent });
|
|
336
|
-
const
|
|
343
|
+
const { prefix, protocol } = buildFinalProto({ cfg, agent });
|
|
337
344
|
|
|
338
345
|
let existing = '';
|
|
339
346
|
let exists = false;
|
|
@@ -346,13 +353,13 @@ function protoApply(agent) {
|
|
|
346
353
|
}
|
|
347
354
|
|
|
348
355
|
const eol = exists ? detectEol(existing) : os.EOL;
|
|
349
|
-
const managedBlock = makeManagedBlock({
|
|
356
|
+
const managedBlock = makeManagedBlock({ prefix, protocol, eol });
|
|
350
357
|
|
|
351
358
|
let out;
|
|
352
359
|
if (!exists) {
|
|
353
360
|
out = managedBlock;
|
|
354
361
|
} else {
|
|
355
|
-
out = applyManagedBlock({ existing,
|
|
362
|
+
out = applyManagedBlock({ existing, prefix, protocol });
|
|
356
363
|
}
|
|
357
364
|
|
|
358
365
|
ensureDirForFile(targetPath);
|