agentspeak-cli 0.14.1 → 0.15.1
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/dist/api.d.ts +23 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -0
- package/dist/api.js.map +1 -1
- package/dist/commands/friends.d.ts +10 -0
- package/dist/commands/friends.d.ts.map +1 -0
- package/dist/commands/friends.js +153 -0
- package/dist/commands/friends.js.map +1 -0
- package/dist/commands/invite.d.ts +20 -0
- package/dist/commands/invite.d.ts.map +1 -0
- package/dist/commands/invite.js +184 -0
- package/dist/commands/invite.js.map +1 -0
- package/dist/commands/tutorial.d.ts.map +1 -1
- package/dist/commands/tutorial.js +82 -3
- package/dist/commands/tutorial.js.map +1 -1
- package/dist/commands/watch.d.ts +15 -2
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +91 -6
- package/dist/commands/watch.js.map +1 -1
- package/dist/friends.d.ts +80 -0
- package/dist/friends.d.ts.map +1 -0
- package/dist/friends.js +124 -0
- package/dist/friends.js.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/pending-invites.d.ts +56 -0
- package/dist/pending-invites.d.ts.map +1 -0
- package/dist/pending-invites.js +91 -0
- package/dist/pending-invites.js.map +1 -0
- package/dist/skill-template.d.ts +1 -1
- package/dist/skill-template.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -46,4 +46,27 @@ export interface MeetingStatus {
|
|
|
46
46
|
maxTurns?: number;
|
|
47
47
|
}
|
|
48
48
|
export declare function getMeetingStatus(ctx: ApiCtx, meetingId: string): Promise<MeetingStatus>;
|
|
49
|
+
/**
|
|
50
|
+
* Ask the server to re-fire a human-visible wake via the agent's
|
|
51
|
+
* already-configured `wake_config`. Used by the watch daemon when it
|
|
52
|
+
* queues an invite for human approval so the operator gets a Discord /
|
|
53
|
+
* webhook ping with the exact `invite approve <notifId>` commands.
|
|
54
|
+
*
|
|
55
|
+
* Returns a structured result; a `pull_not_human_visible` reason means
|
|
56
|
+
* the agent is on long-poll-only and the human will NOT see a Discord
|
|
57
|
+
* alert until they configure a push transport.
|
|
58
|
+
*/
|
|
59
|
+
export interface WakeHumanResult {
|
|
60
|
+
delivered: boolean;
|
|
61
|
+
reason: string;
|
|
62
|
+
transport: string;
|
|
63
|
+
status?: number;
|
|
64
|
+
}
|
|
65
|
+
export declare function postWakeHuman(ctx: ApiCtx, body: {
|
|
66
|
+
kind: 'pending_approval';
|
|
67
|
+
meetingId: string;
|
|
68
|
+
notificationId: string;
|
|
69
|
+
inviterAgentId: string;
|
|
70
|
+
inviterName?: string;
|
|
71
|
+
}): Promise<WakeHumanResult>;
|
|
49
72
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,QAAS,SAAQ,KAAK;IACd,MAAM,EAAE,MAAM;IAAS,IAAI,EAAE,MAAM;gBAAnC,MAAM,EAAE,MAAM,EAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAGzE;AAwCD,eAAO,MAAM,GAAG;UACR,CAAC,iBAAiB,MAAM,QAAQ,MAAM,SAAS;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;WAEpE,CAAC,iBACD,MAAM,QACL,MAAM,QACN,OAAO,SACN;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;UAE3D,CAAC,iBAAiB,MAAM,QAAQ,MAAM,QAAQ,OAAO;UAErD,CAAC,iBACA,MAAM,QACL,MAAM,SACL,OAAO,SACP;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;CAElE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,WAAW,SAAK,GACf,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC,CAsB/E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAE7F"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,QAAS,SAAQ,KAAK;IACd,MAAM,EAAE,MAAM;IAAS,IAAI,EAAE,MAAM;gBAAnC,MAAM,EAAE,MAAM,EAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAGzE;AAwCD,eAAO,MAAM,GAAG;UACR,CAAC,iBAAiB,MAAM,QAAQ,MAAM,SAAS;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;WAEpE,CAAC,iBACD,MAAM,QACL,MAAM,QACN,OAAO,SACN;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;UAE3D,CAAC,iBAAiB,MAAM,QAAQ,MAAM,QAAQ,OAAO;UAErD,CAAC,iBACA,MAAM,QACL,MAAM,SACL,OAAO,SACP;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;CAElE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,WAAW,SAAK,GACf,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC,CAsB/E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAE7F;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,eAAe,CAAC,CAI1B"}
|
package/dist/api.js
CHANGED
|
@@ -89,4 +89,9 @@ export async function pollMyTurn(ctx, meetingId, agentId, waitSeconds = 25) {
|
|
|
89
89
|
export async function getMeetingStatus(ctx, meetingId) {
|
|
90
90
|
return api.get(ctx, `/api/meetings/${meetingId}/status`);
|
|
91
91
|
}
|
|
92
|
+
export async function postWakeHuman(ctx, body) {
|
|
93
|
+
return api.post(ctx, '/api/agents/me/wake-human', body, {
|
|
94
|
+
timeoutMs: 10_000,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
92
97
|
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Parsed } from '../cli.js';
|
|
2
|
+
/**
|
|
3
|
+
* `agentspeak-cli friends <subcommand>` — manage the client-side
|
|
4
|
+
* trusted-senders allowlist. See packages/cli/src/friends.ts for the
|
|
5
|
+
* threat model. The CLI surface is intentionally tiny because most of
|
|
6
|
+
* the time the `invite approve --remember always` flow ends up
|
|
7
|
+
* populating this file; direct editing is a power-user escape hatch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cmdFriends(parsed: Parsed): Promise<number>;
|
|
10
|
+
//# sourceMappingURL=friends.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friends.d.ts","sourceRoot":"","sources":["../../src/commands/friends.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAaxC;;;;;;GAMG;AAEH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB1D"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { flagBool, flagStr } from '../cli.js';
|
|
2
|
+
import { addAllow, addBlock, friendsFilePath, loadFriends, removeAllow, removeBlock, } from '../friends.js';
|
|
3
|
+
/**
|
|
4
|
+
* `agentspeak-cli friends <subcommand>` — manage the client-side
|
|
5
|
+
* trusted-senders allowlist. See packages/cli/src/friends.ts for the
|
|
6
|
+
* threat model. The CLI surface is intentionally tiny because most of
|
|
7
|
+
* the time the `invite approve --remember always` flow ends up
|
|
8
|
+
* populating this file; direct editing is a power-user escape hatch.
|
|
9
|
+
*/
|
|
10
|
+
export function cmdFriends(parsed) {
|
|
11
|
+
const sub = parsed.positionals[0];
|
|
12
|
+
if (!sub || sub === 'help' || sub === '--help') {
|
|
13
|
+
process.stdout.write(SUB_HELP);
|
|
14
|
+
return Promise.resolve(0);
|
|
15
|
+
}
|
|
16
|
+
switch (sub) {
|
|
17
|
+
case 'list':
|
|
18
|
+
return Promise.resolve(cmdFriendsList(parsed));
|
|
19
|
+
case 'add':
|
|
20
|
+
return Promise.resolve(cmdFriendsAdd(parsed));
|
|
21
|
+
case 'remove':
|
|
22
|
+
return Promise.resolve(cmdFriendsRemove(parsed));
|
|
23
|
+
case 'block':
|
|
24
|
+
return Promise.resolve(cmdFriendsBlock(parsed));
|
|
25
|
+
case 'unblock':
|
|
26
|
+
return Promise.resolve(cmdFriendsUnblock(parsed));
|
|
27
|
+
case 'where':
|
|
28
|
+
return Promise.resolve(cmdFriendsWhere());
|
|
29
|
+
default:
|
|
30
|
+
process.stderr.write(`agentspeak-cli friends: unknown subcommand "${sub}"\n${SUB_HELP}`);
|
|
31
|
+
return Promise.resolve(2);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const SUB_HELP = `agentspeak-cli friends <subcommand>
|
|
35
|
+
|
|
36
|
+
list Show agents on your allow + block list.
|
|
37
|
+
add <agentId> Add an agent to the allow list (auto-join their invites).
|
|
38
|
+
remove <id> Remove an agent from the allow list.
|
|
39
|
+
block <id> Add an agent to the block list (drop their invites silently).
|
|
40
|
+
unblock <id> Remove an agent from the block list.
|
|
41
|
+
where Print the path of friends.json.
|
|
42
|
+
|
|
43
|
+
FLAGS
|
|
44
|
+
--name "..." Optional display name stamped on the entry.
|
|
45
|
+
--memo "..." Optional free-form note (e.g. "met at OpenClaw hackathon").
|
|
46
|
+
--json Machine-readable output for \`list\`.
|
|
47
|
+
|
|
48
|
+
EXAMPLES
|
|
49
|
+
agentspeak-cli friends add agent_abc123 --name "Hermes" --memo "personal assistant"
|
|
50
|
+
agentspeak-cli friends block agent_spammer --memo "burned my tokens 2026-04"
|
|
51
|
+
agentspeak-cli friends list --json
|
|
52
|
+
`;
|
|
53
|
+
function requireAgentId(parsed, sub) {
|
|
54
|
+
const id = parsed.positionals[1];
|
|
55
|
+
if (!id) {
|
|
56
|
+
process.stderr.write(`agentspeak-cli friends ${sub}: missing <agentId>\n`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return id;
|
|
60
|
+
}
|
|
61
|
+
function cmdFriendsList(parsed) {
|
|
62
|
+
const file = loadFriends();
|
|
63
|
+
if (flagBool(parsed.flags, 'json')) {
|
|
64
|
+
process.stdout.write(JSON.stringify(listForJson(file), null, 2) + '\n');
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const allow = Object.values(file.allow).sort((a, b) => a.agentId.localeCompare(b.agentId));
|
|
68
|
+
const block = Object.values(file.block).sort((a, b) => a.agentId.localeCompare(b.agentId));
|
|
69
|
+
if (allow.length === 0 && block.length === 0) {
|
|
70
|
+
process.stdout.write(`(empty — run \`agentspeak-cli friends add <agentId>\` to trust an inviter)\n`);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
if (allow.length > 0) {
|
|
74
|
+
process.stdout.write(`ALLOW (${allow.length})\n`);
|
|
75
|
+
for (const e of allow)
|
|
76
|
+
process.stdout.write(formatEntry(e) + '\n');
|
|
77
|
+
}
|
|
78
|
+
if (block.length > 0) {
|
|
79
|
+
if (allow.length > 0)
|
|
80
|
+
process.stdout.write('\n');
|
|
81
|
+
process.stdout.write(`BLOCK (${block.length})\n`);
|
|
82
|
+
for (const e of block)
|
|
83
|
+
process.stdout.write(formatEntry(e) + '\n');
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
function listForJson(file) {
|
|
88
|
+
return {
|
|
89
|
+
allow: Object.values(file.allow),
|
|
90
|
+
block: Object.values(file.block),
|
|
91
|
+
path: friendsFilePath(),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function formatEntry(e) {
|
|
95
|
+
const parts = [` ${e.agentId}`];
|
|
96
|
+
if (e.name)
|
|
97
|
+
parts.push(`(${e.name})`);
|
|
98
|
+
parts.push(`since=${e.since.slice(0, 10)}`);
|
|
99
|
+
if (e.memo)
|
|
100
|
+
parts.push(`memo="${e.memo}"`);
|
|
101
|
+
return parts.join(' ');
|
|
102
|
+
}
|
|
103
|
+
function cmdFriendsAdd(parsed) {
|
|
104
|
+
const id = requireAgentId(parsed, 'add');
|
|
105
|
+
if (!id)
|
|
106
|
+
return 2;
|
|
107
|
+
const entry = addAllow(id, {
|
|
108
|
+
name: flagStr(parsed.flags, 'name'),
|
|
109
|
+
memo: flagStr(parsed.flags, 'memo'),
|
|
110
|
+
});
|
|
111
|
+
process.stdout.write(`agentspeak-cli friends: added ${entry.agentId} to allow list (since ${entry.since.slice(0, 10)}).\n`);
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
function cmdFriendsRemove(parsed) {
|
|
115
|
+
const id = requireAgentId(parsed, 'remove');
|
|
116
|
+
if (!id)
|
|
117
|
+
return 2;
|
|
118
|
+
const removed = removeAllow(id);
|
|
119
|
+
if (!removed) {
|
|
120
|
+
process.stdout.write(`agentspeak-cli friends: ${id} is not on the allow list.\n`);
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
process.stdout.write(`agentspeak-cli friends: removed ${id} from allow list.\n`);
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
function cmdFriendsBlock(parsed) {
|
|
127
|
+
const id = requireAgentId(parsed, 'block');
|
|
128
|
+
if (!id)
|
|
129
|
+
return 2;
|
|
130
|
+
const entry = addBlock(id, {
|
|
131
|
+
name: flagStr(parsed.flags, 'name'),
|
|
132
|
+
memo: flagStr(parsed.flags, 'memo'),
|
|
133
|
+
});
|
|
134
|
+
process.stdout.write(`agentspeak-cli friends: added ${entry.agentId} to block list. Future invites will be silently dropped.\n`);
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
function cmdFriendsUnblock(parsed) {
|
|
138
|
+
const id = requireAgentId(parsed, 'unblock');
|
|
139
|
+
if (!id)
|
|
140
|
+
return 2;
|
|
141
|
+
const removed = removeBlock(id);
|
|
142
|
+
if (!removed) {
|
|
143
|
+
process.stdout.write(`agentspeak-cli friends: ${id} is not on the block list.\n`);
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
process.stdout.write(`agentspeak-cli friends: removed ${id} from block list.\n`);
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
function cmdFriendsWhere() {
|
|
150
|
+
process.stdout.write(friendsFilePath() + '\n');
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=friends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friends.js","sourceRoot":"","sources":["../../src/commands/friends.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,GAGZ,MAAM,eAAe,CAAC;AAEvB;;;;;;GAMG;AAEH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACjD,KAAK,KAAK;YACR,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QACpD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;QAC5C;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,GAAG,MAAM,QAAQ,EAAE,CAAC,CAAC;YACzF,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;CAkBhB,CAAC;AAEF,SAAS,cAAc,CAAC,MAAc,EAAE,GAAW;IACjD,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,GAAG,uBAAuB,CAAC,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACxE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3F,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8EAA8E,CAC/E,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,WAAW,CAAC,IAAiB;IAKpC,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,IAAI,EAAE,eAAe,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,CAAc;IACjC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,EAAE;QACzB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;QACnC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iCAAiC,KAAK,CAAC,OAAO,yBAAyB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CACtG,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc;IACtC,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAClB,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,8BAA8B,CAAC,CAAC;QAClF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,qBAAqB,CAAC,CAAC;IACjF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,EAAE;QACzB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;QACnC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iCAAiC,KAAK,CAAC,OAAO,4DAA4D,CAC3G,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IAClB,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,8BAA8B,CAAC,CAAC;QAClF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,qBAAqB,CAAC,CAAC;IACjF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/C,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Parsed } from '../cli.js';
|
|
2
|
+
/**
|
|
3
|
+
* `agentspeak-cli invite <subcommand>` — resolve the pending-invite
|
|
4
|
+
* queue. This is the other half of the friends-allowlist feature:
|
|
5
|
+
*
|
|
6
|
+
* 1. The watch daemon puts unknown-inviter rows into
|
|
7
|
+
* ~/.agentspeak/pending-invites/.
|
|
8
|
+
* 2. The agent's LLM runtime pulls the queue via `invite pending
|
|
9
|
+
* --json` on every check-in loop and surfaces each entry to the
|
|
10
|
+
* human (see skill "Pending invite approvals" section).
|
|
11
|
+
* 3. The human answers 1/2/3/4 and the LLM translates that to ONE
|
|
12
|
+
* call to `invite approve <id> --decision accept|reject
|
|
13
|
+
* [--remember always]`.
|
|
14
|
+
*
|
|
15
|
+
* `--remember always` + `--decision accept` adds to the friends allow
|
|
16
|
+
* list; + `--decision reject` adds to the block list. Without
|
|
17
|
+
* `--remember always`, the decision applies to this one invite only.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cmdInvite(parsed: Parsed): Promise<number>;
|
|
20
|
+
//# sourceMappingURL=invite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invite.d.ts","sourceRoot":"","sources":["../../src/commands/invite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAYxC;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAezD"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { flagBool, flagStr } from '../cli.js';
|
|
2
|
+
import { addAllow, addBlock } from '../friends.js';
|
|
3
|
+
import { deletePending, listPending, loadPending, pendingInvitesDir, } from '../pending-invites.js';
|
|
4
|
+
import { isRunAlive, runJoin, spawnRunForMeeting } from '../run-spawner.js';
|
|
5
|
+
/**
|
|
6
|
+
* `agentspeak-cli invite <subcommand>` — resolve the pending-invite
|
|
7
|
+
* queue. This is the other half of the friends-allowlist feature:
|
|
8
|
+
*
|
|
9
|
+
* 1. The watch daemon puts unknown-inviter rows into
|
|
10
|
+
* ~/.agentspeak/pending-invites/.
|
|
11
|
+
* 2. The agent's LLM runtime pulls the queue via `invite pending
|
|
12
|
+
* --json` on every check-in loop and surfaces each entry to the
|
|
13
|
+
* human (see skill "Pending invite approvals" section).
|
|
14
|
+
* 3. The human answers 1/2/3/4 and the LLM translates that to ONE
|
|
15
|
+
* call to `invite approve <id> --decision accept|reject
|
|
16
|
+
* [--remember always]`.
|
|
17
|
+
*
|
|
18
|
+
* `--remember always` + `--decision accept` adds to the friends allow
|
|
19
|
+
* list; + `--decision reject` adds to the block list. Without
|
|
20
|
+
* `--remember always`, the decision applies to this one invite only.
|
|
21
|
+
*/
|
|
22
|
+
export function cmdInvite(parsed) {
|
|
23
|
+
const sub = parsed.positionals[0];
|
|
24
|
+
if (!sub || sub === 'help' || sub === '--help') {
|
|
25
|
+
process.stdout.write(SUB_HELP);
|
|
26
|
+
return Promise.resolve(0);
|
|
27
|
+
}
|
|
28
|
+
switch (sub) {
|
|
29
|
+
case 'pending':
|
|
30
|
+
return Promise.resolve(cmdInvitePending(parsed));
|
|
31
|
+
case 'approve':
|
|
32
|
+
return Promise.resolve(cmdInviteApprove(parsed));
|
|
33
|
+
default:
|
|
34
|
+
process.stderr.write(`agentspeak-cli invite: unknown subcommand "${sub}"\n${SUB_HELP}`);
|
|
35
|
+
return Promise.resolve(2);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const SUB_HELP = `agentspeak-cli invite <subcommand>
|
|
39
|
+
|
|
40
|
+
pending List invites awaiting human approval.
|
|
41
|
+
approve <id> Resolve a pending invite (see flags below).
|
|
42
|
+
|
|
43
|
+
FLAGS
|
|
44
|
+
--json Machine-readable output for \`pending\`.
|
|
45
|
+
--decision accept|reject Required for \`approve\`.
|
|
46
|
+
--remember always Upgrade the decision to a lasting
|
|
47
|
+
trust change: accept→friends add,
|
|
48
|
+
reject→friends block.
|
|
49
|
+
|
|
50
|
+
EXAMPLES
|
|
51
|
+
# Agent runtime: pull the queue, show it to the human, parse reply.
|
|
52
|
+
agentspeak-cli invite pending --json
|
|
53
|
+
|
|
54
|
+
# Human said "yes, always trust this one":
|
|
55
|
+
agentspeak-cli invite approve notif_abc --decision accept --remember always
|
|
56
|
+
|
|
57
|
+
# Human said "just this one, don't remember":
|
|
58
|
+
agentspeak-cli invite approve notif_abc --decision accept
|
|
59
|
+
|
|
60
|
+
# Human said "no, block them":
|
|
61
|
+
agentspeak-cli invite approve notif_abc --decision reject --remember always
|
|
62
|
+
|
|
63
|
+
# Human said "no, but don't block":
|
|
64
|
+
agentspeak-cli invite approve notif_abc --decision reject
|
|
65
|
+
`;
|
|
66
|
+
function cmdInvitePending(parsed) {
|
|
67
|
+
const rows = listPending();
|
|
68
|
+
if (flagBool(parsed.flags, 'json')) {
|
|
69
|
+
process.stdout.write(JSON.stringify({ pending: rows, dir: pendingInvitesDir() }, null, 2) + '\n');
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
if (rows.length === 0) {
|
|
73
|
+
process.stdout.write('(no pending invites)\n');
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
process.stdout.write(`PENDING (${rows.length})\n`);
|
|
77
|
+
for (const r of rows) {
|
|
78
|
+
process.stdout.write(` ${r.notificationId}\n` +
|
|
79
|
+
` meeting ${r.meetingId}\n` +
|
|
80
|
+
` inviter ${r.inviterAgentId ?? '<unspecified>'}${r.inviterName ? ` (${r.inviterName})` : ''}\n` +
|
|
81
|
+
` received ${r.receivedAt}\n` +
|
|
82
|
+
` actionUrl ${r.actionUrl}\n` +
|
|
83
|
+
(r.message ? ` message ${r.message}\n` : ''));
|
|
84
|
+
}
|
|
85
|
+
process.stdout.write(`\nResolve each with:\n` +
|
|
86
|
+
` agentspeak-cli invite approve <notifId> --decision accept|reject [--remember always]\n`);
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
function cmdInviteApprove(parsed) {
|
|
90
|
+
const idArg = parsed.positionals[1];
|
|
91
|
+
if (!idArg) {
|
|
92
|
+
process.stderr.write('agentspeak-cli invite approve: missing <notificationId> | <meetingId>\n');
|
|
93
|
+
return 2;
|
|
94
|
+
}
|
|
95
|
+
const decisionRaw = flagStr(parsed.flags, 'decision');
|
|
96
|
+
if (decisionRaw !== 'accept' && decisionRaw !== 'reject') {
|
|
97
|
+
process.stderr.write('agentspeak-cli invite approve: --decision must be accept or reject.\n');
|
|
98
|
+
return 2;
|
|
99
|
+
}
|
|
100
|
+
const decision = decisionRaw;
|
|
101
|
+
const rememberRaw = flagStr(parsed.flags, 'remember');
|
|
102
|
+
if (rememberRaw != null && rememberRaw !== 'always' && rememberRaw !== 'once') {
|
|
103
|
+
process.stderr.write('agentspeak-cli invite approve: --remember must be "always" or "once" (default once).\n');
|
|
104
|
+
return 2;
|
|
105
|
+
}
|
|
106
|
+
const rememberAlways = rememberRaw === 'always';
|
|
107
|
+
let record;
|
|
108
|
+
try {
|
|
109
|
+
record = loadPending(idArg);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
process.stderr.write(`agentspeak-cli invite approve: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
113
|
+
return 2;
|
|
114
|
+
}
|
|
115
|
+
if (!record) {
|
|
116
|
+
process.stderr.write(`agentspeak-cli invite approve: no pending invite matching "${idArg}". ` +
|
|
117
|
+
`Run \`agentspeak-cli invite pending\` to see the queue.\n`);
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
if (decision === 'reject') {
|
|
121
|
+
if (rememberAlways) {
|
|
122
|
+
if (!record.inviterAgentId) {
|
|
123
|
+
process.stderr.write(`agentspeak-cli invite approve: cannot block (inviter agent_id unknown for ${record.notificationId}).\n`);
|
|
124
|
+
return 2;
|
|
125
|
+
}
|
|
126
|
+
addBlock(record.inviterAgentId, {
|
|
127
|
+
name: record.inviterName,
|
|
128
|
+
memo: `blocked via invite reject at ${new Date().toISOString().slice(0, 10)}`,
|
|
129
|
+
});
|
|
130
|
+
process.stdout.write(`Rejected and blocked ${record.inviterAgentId}. Future invites from this agent will be silently dropped.\n`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
process.stdout.write(`Rejected ${record.notificationId} (this one only — inviter not added to block list).\n`);
|
|
134
|
+
}
|
|
135
|
+
deletePending(record.notificationId);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
if (rememberAlways) {
|
|
139
|
+
if (!record.inviterAgentId) {
|
|
140
|
+
process.stderr.write(`agentspeak-cli invite approve: cannot add to friends (inviter agent_id unknown ` +
|
|
141
|
+
`for ${record.notificationId}). Re-run with --decision accept (no --remember) ` +
|
|
142
|
+
`to accept this one invite only.\n`);
|
|
143
|
+
return 2;
|
|
144
|
+
}
|
|
145
|
+
addAllow(record.inviterAgentId, {
|
|
146
|
+
name: record.inviterName,
|
|
147
|
+
memo: `added via invite approve at ${new Date().toISOString().slice(0, 10)}`,
|
|
148
|
+
});
|
|
149
|
+
process.stdout.write(`Added ${record.inviterAgentId} to friends. Future invites from this agent will auto-join.\n`);
|
|
150
|
+
}
|
|
151
|
+
// Run the delayed join + run-loop spawn — same flow dispatchInvite
|
|
152
|
+
// would have used for an already-allowed inviter. We consciously
|
|
153
|
+
// DO NOT re-check friends here: the human's decision trumps any
|
|
154
|
+
// race where an out-of-band edit changed the list between queue
|
|
155
|
+
// and approve.
|
|
156
|
+
const alive = isRunAlive(record.meetingId);
|
|
157
|
+
if (alive.alive && alive.pid) {
|
|
158
|
+
process.stdout.write(`Run loop for ${record.meetingId} already alive (pid=${alive.pid}); nothing to do beyond friends list update.\n`);
|
|
159
|
+
deletePending(record.notificationId);
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
const joinRes = runJoin({ inviteUrl: record.actionUrl, meetingId: record.meetingId });
|
|
163
|
+
if (!joinRes.ok) {
|
|
164
|
+
process.stderr.write(`agentspeak-cli invite approve: auto-join failed for ${record.meetingId} ` +
|
|
165
|
+
`(exit=${joinRes.exitCode}); see ${joinRes.logPath}. The pending record is kept so ` +
|
|
166
|
+
`you can retry.\n`);
|
|
167
|
+
return 1;
|
|
168
|
+
}
|
|
169
|
+
const run = spawnRunForMeeting({ meetingId: record.meetingId });
|
|
170
|
+
deletePending(record.notificationId);
|
|
171
|
+
if (run.started && run.pid) {
|
|
172
|
+
process.stdout.write(`Accepted ${record.notificationId}: joined ${record.meetingId} and spawned run loop pid=${run.pid}.\n`);
|
|
173
|
+
}
|
|
174
|
+
else if (run.reused && run.pid) {
|
|
175
|
+
process.stdout.write(`Accepted ${record.notificationId}: joined ${record.meetingId}; run loop already alive pid=${run.pid}.\n`);
|
|
176
|
+
}
|
|
177
|
+
else if (run.reason) {
|
|
178
|
+
process.stdout.write(`Accepted ${record.notificationId}: joined ${record.meetingId} but could not spawn run ` +
|
|
179
|
+
`loop (${run.reason}). Start manually with ` +
|
|
180
|
+
`\`agentspeak-cli run --meeting ${record.meetingId} --exec ~/.agentspeak/reply.sh\`.\n`);
|
|
181
|
+
}
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=invite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invite.js","sourceRoot":"","sources":["../../src/commands/invite.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tutorial.d.ts","sourceRoot":"","sources":["../../src/commands/tutorial.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tutorial.d.ts","sourceRoot":"","sources":["../../src/commands/tutorial.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAClE;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAiFD,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CA2QrE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { api, ApiError, pollMyTurn } from '../api.js';
|
|
2
2
|
import { discoverMeetingFromInvite } from './join.js';
|
|
3
3
|
import { runShim } from '../exec.js';
|
|
4
|
+
import { loadFriends } from '../friends.js';
|
|
4
5
|
import { CLI_SKILL_VERSION, detectRuntime, renderRootSkill, renderStepSkill } from '../skill-template.js';
|
|
5
6
|
import { verifyRuntimeLoaded, writeSkills } from '../skill-writer.js';
|
|
6
7
|
import { loadIdentity, saveMeeting } from '../state.js';
|
|
@@ -247,7 +248,7 @@ export async function cmdTutorial(opts) {
|
|
|
247
248
|
// agent runs by hand -- useful when you want full control of the
|
|
248
249
|
// skills cache.
|
|
249
250
|
emitSkillsConsolidation(runtime, opts);
|
|
250
|
-
printFinishSummary(result, opts);
|
|
251
|
+
await printFinishSummary(result, opts, { baseUrl: identity.baseUrl, token: identity.coordinatorToken });
|
|
251
252
|
return 0;
|
|
252
253
|
}
|
|
253
254
|
/**
|
|
@@ -357,10 +358,10 @@ async function runStrictPath(args) {
|
|
|
357
358
|
const result = await api.post(ctx, '/api/onboarding/tutorial/finish', {
|
|
358
359
|
meetingId,
|
|
359
360
|
});
|
|
360
|
-
printFinishSummary(result, opts);
|
|
361
|
+
await printFinishSummary(result, opts, ctx);
|
|
361
362
|
return 0;
|
|
362
363
|
}
|
|
363
|
-
function printFinishSummary(result, opts) {
|
|
364
|
+
async function printFinishSummary(result, opts, ctx) {
|
|
364
365
|
if (opts.json) {
|
|
365
366
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
366
367
|
return;
|
|
@@ -379,6 +380,84 @@ function printFinishSummary(result, opts) {
|
|
|
379
380
|
' npx -y agentspeak-cli join <invite-url>\n\n' +
|
|
380
381
|
'And create meetings:\n' +
|
|
381
382
|
' npx -y agentspeak-cli meeting create --title "Sync" --invite alice,bob\n');
|
|
383
|
+
await printSecuritySetupHint(result.agentId, ctx);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Print a focused security-setup block after every successful tutorial
|
|
387
|
+
* run (both fast path and strict path). We want EVERY newly-certified
|
|
388
|
+
* agent to immediately understand the friends allowlist so they don't
|
|
389
|
+
* wonder why their first invite from a new coordinator gets queued
|
|
390
|
+
* instead of auto-joined.
|
|
391
|
+
*
|
|
392
|
+
* The block is intentionally imperative ("run this now") rather than
|
|
393
|
+
* explanatory — the full rationale lives in the skill docs
|
|
394
|
+
* ("Pending invite approvals" section of root.md). Here we just give
|
|
395
|
+
* the agent the three commands they need to know.
|
|
396
|
+
*/
|
|
397
|
+
async function printSecuritySetupHint(agentId, ctx) {
|
|
398
|
+
// Load the current friends file so we can tailor the hint. A brand-
|
|
399
|
+
// new agent will have an empty list (or no file at all). An agent
|
|
400
|
+
// refreshing skills after an upgrade may already have entries.
|
|
401
|
+
let allowCount = 0;
|
|
402
|
+
let blockCount = 0;
|
|
403
|
+
try {
|
|
404
|
+
const f = loadFriends();
|
|
405
|
+
allowCount = Object.keys(f.allow).length;
|
|
406
|
+
blockCount = Object.keys(f.block).length;
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
// Shouldn't happen in production; show the generic hint anyway.
|
|
410
|
+
}
|
|
411
|
+
const friendsSummary = allowCount > 0
|
|
412
|
+
? ` Your friends list: ${allowCount} allowed, ${blockCount} blocked.`
|
|
413
|
+
: ` Your friends list is EMPTY — every invite will be queued for your approval\n` +
|
|
414
|
+
` until you add at least one trusted sender. If you know which agent_id will\n` +
|
|
415
|
+
` invite you first, add them now:`;
|
|
416
|
+
// Fetch the agent's wake_config so we can warn if the human wouldn't
|
|
417
|
+
// get a Discord/webhook notification when an invite queues for
|
|
418
|
+
// approval. pull/none transports work fine for machine-to-machine
|
|
419
|
+
// wakes but have no way to reach the human proactively.
|
|
420
|
+
let wakeWarning = '';
|
|
421
|
+
try {
|
|
422
|
+
const wake = await api.get(ctx, '/api/agents/me/wake-config');
|
|
423
|
+
const transport = wake?.wakeConfig?.transport ?? 'none';
|
|
424
|
+
if (transport === 'none' || transport === 'pull' || transport === 'gateway') {
|
|
425
|
+
wakeWarning =
|
|
426
|
+
`\n WARNING: your wake_config.transport=${transport} cannot reach a human.\n` +
|
|
427
|
+
` When the daemon queues a pending invite, it tries to re-fire a\n` +
|
|
428
|
+
` human-visible wake through wake_config — but with transport=${transport}\n` +
|
|
429
|
+
` that push is a no-op, so you (the operator) will only see the pending\n` +
|
|
430
|
+
` invite if you manually run \`agentspeak-cli invite pending\`.\n` +
|
|
431
|
+
` Configure a push transport to get Discord/webhook alerts:\n` +
|
|
432
|
+
` npx -y agentspeak-cli wake-config set --transport discord_webhook \\\n` +
|
|
433
|
+
` --url https://discord.com/api/webhooks/<id>/<token> --user-id <your-id>\n` +
|
|
434
|
+
` (or discord_mention / http_webhook / openclaw_webhook — see /setup-wake)\n`;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
// Network error fetching wake_config is non-fatal; just skip the
|
|
439
|
+
// transport-specific warning.
|
|
440
|
+
}
|
|
441
|
+
process.stdout.write(`\n─────────────────────────────────────────────────────────────────────\n` +
|
|
442
|
+
`[security-setup] INVITE GATING (new in CLI 0.15.0)\n` +
|
|
443
|
+
`─────────────────────────────────────────────────────────────────────\n` +
|
|
444
|
+
`The background watch daemon no longer auto-joins every invite it\n` +
|
|
445
|
+
`receives. Only invites from agents on your FRIENDS list auto-join;\n` +
|
|
446
|
+
`all others are queued so you can approve or reject them.\n\n` +
|
|
447
|
+
friendsSummary +
|
|
448
|
+
`\n\n` +
|
|
449
|
+
` # Trust a coordinator/agent so their invites auto-join:\n` +
|
|
450
|
+
` npx -y agentspeak-cli friends add <agentId> --name "Their name"\n\n` +
|
|
451
|
+
` # See pending invites from unknown senders:\n` +
|
|
452
|
+
` npx -y agentspeak-cli invite pending --json\n\n` +
|
|
453
|
+
` # Approve one (accept/reject, optionally remember always):\n` +
|
|
454
|
+
` npx -y agentspeak-cli invite approve <notifId> --decision accept --remember always\n\n` +
|
|
455
|
+
`ADD THE FOLLOWING TO YOUR CHECK-IN LOOP (after \`watch --once --json\`):\n` +
|
|
456
|
+
` npx -y agentspeak-cli invite pending --json # step 4 in check-in sequence\n` +
|
|
457
|
+
wakeWarning +
|
|
458
|
+
`\nFull docs: see "Pending invite approvals" in your root skill (root.md).\n` +
|
|
459
|
+
`Agent: ${agentId}\n` +
|
|
460
|
+
`─────────────────────────────────────────────────────────────────────\n`);
|
|
382
461
|
}
|
|
383
462
|
function emitSkillsConsolidation(runtime, opts) {
|
|
384
463
|
const wantWrite = opts.writeSkills !== false;
|