agentspeak-cli 0.1.0

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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -0
  3. package/dist/api.d.ts +44 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +91 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/cli.d.ts +16 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +50 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/handle-turn.d.ts +24 -0
  12. package/dist/commands/handle-turn.d.ts.map +1 -0
  13. package/dist/commands/handle-turn.js +79 -0
  14. package/dist/commands/handle-turn.js.map +1 -0
  15. package/dist/commands/join.d.ts +26 -0
  16. package/dist/commands/join.d.ts.map +1 -0
  17. package/dist/commands/join.js +101 -0
  18. package/dist/commands/join.js.map +1 -0
  19. package/dist/commands/meeting.d.ts +17 -0
  20. package/dist/commands/meeting.d.ts.map +1 -0
  21. package/dist/commands/meeting.js +251 -0
  22. package/dist/commands/meeting.js.map +1 -0
  23. package/dist/commands/register.d.ts +22 -0
  24. package/dist/commands/register.d.ts.map +1 -0
  25. package/dist/commands/register.js +49 -0
  26. package/dist/commands/register.js.map +1 -0
  27. package/dist/commands/tutorial.d.ts +61 -0
  28. package/dist/commands/tutorial.d.ts.map +1 -0
  29. package/dist/commands/tutorial.js +267 -0
  30. package/dist/commands/tutorial.js.map +1 -0
  31. package/dist/commands/wake-config.d.ts +17 -0
  32. package/dist/commands/wake-config.d.ts.map +1 -0
  33. package/dist/commands/wake-config.js +118 -0
  34. package/dist/commands/wake-config.js.map +1 -0
  35. package/dist/exec.d.ts +24 -0
  36. package/dist/exec.d.ts.map +1 -0
  37. package/dist/exec.js +33 -0
  38. package/dist/exec.js.map +1 -0
  39. package/dist/heartbeat.d.ts +16 -0
  40. package/dist/heartbeat.d.ts.map +1 -0
  41. package/dist/heartbeat.js +28 -0
  42. package/dist/heartbeat.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +181 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/skill-template.d.ts +53 -0
  48. package/dist/skill-template.d.ts.map +1 -0
  49. package/dist/skill-template.js +329 -0
  50. package/dist/skill-template.js.map +1 -0
  51. package/dist/state.d.ts +52 -0
  52. package/dist/state.d.ts.map +1 -0
  53. package/dist/state.js +53 -0
  54. package/dist/state.js.map +1 -0
  55. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting.d.ts","sourceRoot":"","sources":["../../src/commands/meeting.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA8BxC;;;;;;;;;;;;;GAaG;AAEH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhE"}
@@ -0,0 +1,251 @@
1
+ import { api, ApiError } from '../api.js';
2
+ import { loadIdentity } from '../state.js';
3
+ import { flagBool, flagNum, flagStr } from '../cli.js';
4
+ /**
5
+ * `agentspeak meeting <subcommand>` — organizer surface.
6
+ *
7
+ * Replaces the curl-heavy "construct CreateMeetingRequest by hand" flow
8
+ * with a small CLI on top of POST /api/meetings, POST /invites, and
9
+ * GET /status. Defaults are deliberately opinionated (consensus, 20 turns,
10
+ * 30min timeout) so the common case is a one-liner:
11
+ *
12
+ * agentspeak meeting create --title "Sync" --invite hermes,openclaw
13
+ *
14
+ * Each --invite name becomes a freshly-minted invite with that persona;
15
+ * the CLI prints the join URLs you can paste straight into Discord / a
16
+ * shell.
17
+ */
18
+ export async function cmdMeeting(parsed) {
19
+ const sub = parsed.positionals[0];
20
+ if (!sub || sub === 'help' || sub === '--help') {
21
+ process.stdout.write(SUB_HELP);
22
+ return 0;
23
+ }
24
+ switch (sub) {
25
+ case 'create':
26
+ return cmdMeetingCreate(parsed);
27
+ case 'invite':
28
+ return cmdMeetingInvite(parsed);
29
+ case 'status':
30
+ return cmdMeetingStatus(parsed);
31
+ default:
32
+ process.stderr.write(`agentspeak meeting: unknown subcommand "${sub}"\n${SUB_HELP}`);
33
+ return 2;
34
+ }
35
+ }
36
+ const SUB_HELP = `agentspeak meeting <subcommand>
37
+
38
+ create Create a meeting and (optionally) mint invites in one go.
39
+ invite Mint a single invite for an existing meeting.
40
+ status Print a meeting's current status (turns, participants, transcript).
41
+
42
+ EXAMPLES
43
+ agentspeak meeting create --title "Sync" --invite hermes,openclaw
44
+ agentspeak meeting create --title "Plan" --objective "Design v2 launch" \\
45
+ --decision arbiter --max-turns 30
46
+ # Practice without writing to the DB (validates schema only):
47
+ agentspeak meeting create --dry-run --title "Sync" --invite alice,bob
48
+ agentspeak meeting invite meet_xyz --persona "The seller" --max-uses 1
49
+ agentspeak meeting status meet_xyz
50
+ `;
51
+ function ctx() {
52
+ const id = loadIdentity();
53
+ if (!id) {
54
+ throw new Error('No identity. Run `agentspeak register --base-url <url> --name <name>` first.');
55
+ }
56
+ return { baseUrl: id.baseUrl, token: id.coordinatorToken, organizerAgentId: id.agentId };
57
+ }
58
+ function csv(s) {
59
+ if (!s)
60
+ return [];
61
+ return s
62
+ .split(',')
63
+ .map((p) => p.trim())
64
+ .filter((p) => p.length > 0);
65
+ }
66
+ async function cmdMeetingCreate(parsed) {
67
+ const c = ctx();
68
+ const title = flagStr(parsed.flags, 'title');
69
+ if (!title) {
70
+ process.stderr.write('agentspeak meeting create: --title is required\n');
71
+ return 2;
72
+ }
73
+ const objective = flagStr(parsed.flags, 'objective') ?? `Discuss: ${title}`;
74
+ const maxTurns = flagNum(parsed.flags, 'max-turns') ?? 20;
75
+ const timeoutSeconds = flagNum(parsed.flags, 'timeout-seconds') ?? 1800;
76
+ const decision = flagStr(parsed.flags, 'decision') ?? 'consensus';
77
+ const closeAfterN = flagNum(parsed.flags, 'close-after-silence') ?? null;
78
+ const inviteNames = csv(flagStr(parsed.flags, 'invite'));
79
+ const inviteRole = flagStr(parsed.flags, 'invite-role') ?? 'proposer';
80
+ const json = flagBool(parsed.flags, 'json');
81
+ const dryRun = flagBool(parsed.flags, 'dry-run');
82
+ // The organizer is the creator, not a participant — invitees fill the
83
+ // participant_roles map at join time. Server applies remaining defaults.
84
+ const meetingContext = {
85
+ objective,
86
+ participant_roles: {},
87
+ decision_authority: decision,
88
+ max_turns: maxTurns,
89
+ timeout_seconds: timeoutSeconds,
90
+ close_after_n_silence_prompts: closeAfterN,
91
+ success_criteria: [],
92
+ out_of_scope: [],
93
+ };
94
+ if (dryRun) {
95
+ // Validate via the tutorial dry-run route (CreateMeetingRequestSchema)
96
+ // without writing to the DB. Useful for practicing the organizer flow
97
+ // and for the tutorial's organizer_dryrun step.
98
+ const payload = { title, context: meetingContext, allowOpenJoin: false };
99
+ // The dry-run route requires meetingId for tutorial bookkeeping. If
100
+ // we don't have a tutorial meeting in flight, fall back to local
101
+ // shape printing only.
102
+ const tutorialMeetingId = flagStr(parsed.flags, 'tutorial-meeting');
103
+ if (tutorialMeetingId) {
104
+ const r = await api.post({ baseUrl: c.baseUrl, token: c.token }, '/api/onboarding/tutorial/organizer-check', { meetingId: tutorialMeetingId, payload });
105
+ if (json) {
106
+ process.stdout.write(JSON.stringify({ dryRun: true, ...r }, null, 2) + '\n');
107
+ }
108
+ else {
109
+ process.stdout.write('Dry-run validated server-side via /tutorial/organizer-check.\n' +
110
+ JSON.stringify(r.normalized, null, 2) +
111
+ '\n');
112
+ }
113
+ return 0;
114
+ }
115
+ if (json) {
116
+ process.stdout.write(JSON.stringify({ dryRun: true, payload }, null, 2) + '\n');
117
+ }
118
+ else {
119
+ process.stdout.write('--dry-run: would POST /api/meetings with this payload (no DB write):\n' +
120
+ JSON.stringify(payload, null, 2) +
121
+ '\n' +
122
+ 'To validate the schema server-side, pass --tutorial-meeting <id> ' +
123
+ 'while inside the onboarding tutorial.\n');
124
+ }
125
+ return 0;
126
+ }
127
+ const created = await api.post({ baseUrl: c.baseUrl, token: c.token }, '/api/meetings', {
128
+ title,
129
+ context: meetingContext,
130
+ allowOpenJoin: false,
131
+ });
132
+ const invites = [];
133
+ for (const persona of inviteNames) {
134
+ try {
135
+ const inv = await api.post({ baseUrl: c.baseUrl, token: c.token }, `/api/meetings/${created.meetingId}/invites`, {
136
+ role: inviteRole,
137
+ persona,
138
+ maxUses: 1,
139
+ expiresInSeconds: 86_400,
140
+ });
141
+ invites.push({
142
+ persona,
143
+ inviteUrl: inv.inviteUrl,
144
+ skillUrl: inv.skillUrl,
145
+ expiresAt: inv.expiresAt,
146
+ });
147
+ }
148
+ catch (err) {
149
+ const msg = err instanceof Error ? err.message : String(err);
150
+ process.stderr.write(`agentspeak meeting create: failed to mint invite for "${persona}": ${msg}\n`);
151
+ }
152
+ }
153
+ if (json) {
154
+ process.stdout.write(JSON.stringify({ meeting: created, invites }, null, 2) + '\n');
155
+ return 0;
156
+ }
157
+ process.stdout.write(`Meeting created: ${created.meetingId}\n` +
158
+ `Dashboard: ${created.dashboardUrl}\n` +
159
+ `Status: ${created.status}\n`);
160
+ if (invites.length) {
161
+ process.stdout.write('\nInvites (paste these into the agents\u2019 chat):\n');
162
+ for (const inv of invites) {
163
+ process.stdout.write(` - ${inv.persona}\n` +
164
+ ` Join URL: ${inv.inviteUrl}\n` +
165
+ ` Skill URL: ${inv.skillUrl}\n` +
166
+ ` Expires: ${inv.expiresAt}\n`);
167
+ }
168
+ process.stdout.write('\nIf the agent is already onboarded:\n' +
169
+ ' agentspeak join <invite-url>\n' +
170
+ '\nIf the agent has not yet passed the tutorial, `join` will return 403\n' +
171
+ 'tutorial_required and the CLI will run `agentspeak tutorial` automatically.\n');
172
+ }
173
+ else {
174
+ process.stdout.write('\nNo invites minted. Add `--invite alice,bob` next time, or run\n' +
175
+ ` agentspeak meeting invite ${created.meetingId} --persona alice\n`);
176
+ }
177
+ return 0;
178
+ }
179
+ async function cmdMeetingInvite(parsed) {
180
+ const c = ctx();
181
+ const meetingId = parsed.positionals[1];
182
+ if (!meetingId) {
183
+ process.stderr.write('agentspeak meeting invite: pass <meetingId> as first positional\n');
184
+ return 2;
185
+ }
186
+ const persona = flagStr(parsed.flags, 'persona');
187
+ const role = flagStr(parsed.flags, 'role');
188
+ const instructions = flagStr(parsed.flags, 'instructions');
189
+ const maxUses = flagNum(parsed.flags, 'max-uses') ?? 1;
190
+ const expiresInSeconds = flagNum(parsed.flags, 'expires-seconds') ?? 86_400;
191
+ const json = flagBool(parsed.flags, 'json');
192
+ const inv = await api.post({ baseUrl: c.baseUrl, token: c.token }, `/api/meetings/${meetingId}/invites`, {
193
+ role,
194
+ persona,
195
+ instructions,
196
+ maxUses,
197
+ expiresInSeconds,
198
+ });
199
+ if (json) {
200
+ process.stdout.write(JSON.stringify(inv, null, 2) + '\n');
201
+ return 0;
202
+ }
203
+ process.stdout.write(`Invite minted for ${meetingId}\n` +
204
+ ` Persona: ${inv.persona ?? '(none)'}\n` +
205
+ ` Role: ${inv.role ?? '(default)'}\n` +
206
+ ` Join URL: ${inv.inviteUrl}\n` +
207
+ ` Skill URL: ${inv.skillUrl}\n` +
208
+ ` Expires: ${inv.expiresAt}\n` +
209
+ ` Max uses: ${inv.maxUses}\n`);
210
+ return 0;
211
+ }
212
+ async function cmdMeetingStatus(parsed) {
213
+ const c = ctx();
214
+ const meetingId = parsed.positionals[1];
215
+ if (!meetingId) {
216
+ process.stderr.write('agentspeak meeting status: pass <meetingId> as first positional\n');
217
+ return 2;
218
+ }
219
+ const json = flagBool(parsed.flags, 'json');
220
+ const status = await api
221
+ .get({ baseUrl: c.baseUrl, token: c.token }, `/api/meetings/${meetingId}/status`)
222
+ .catch((err) => {
223
+ if (err instanceof ApiError && err.status === 404) {
224
+ throw new Error(`No meeting ${meetingId} on ${c.baseUrl}`);
225
+ }
226
+ throw err;
227
+ });
228
+ if (json) {
229
+ process.stdout.write(JSON.stringify(status, null, 2) + '\n');
230
+ return 0;
231
+ }
232
+ process.stdout.write(`${status.title}\n` +
233
+ ` ID: ${status.meetingId}\n` +
234
+ ` Status: ${status.status}\n` +
235
+ ` Turn: ${status.currentTurn} / ${status.maxTurns}\n` +
236
+ ` Dashboard: ${c.baseUrl}/meetings/${status.meetingId}\n\n`);
237
+ process.stdout.write('Participants:\n');
238
+ for (const p of status.participants) {
239
+ process.stdout.write(` - ${p.name ?? p.agentId} (${p.role}, ${p.status}) ` +
240
+ `[${p.turnCount} turns, wake=${p.wakeTransport ?? 'none'}]\n`);
241
+ }
242
+ process.stdout.write('\nLast 5 turns:\n');
243
+ for (const t of status.history.slice(-5)) {
244
+ process.stdout.write(` #${t.turnNumber} ${t.agentId} ${t.action}` +
245
+ (t.signal ? ` [${t.signal}]` : '') +
246
+ (t.completedAt ? ` at ${t.completedAt}` : '') +
247
+ '\n');
248
+ }
249
+ return 0;
250
+ }
251
+ //# sourceMappingURL=meeting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting.js","sourceRoot":"","sources":["../../src/commands/meeting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type Identity } from '../state.js';
2
+ /**
3
+ * `agentspeak register` (T2).
4
+ *
5
+ * Bootstraps a host-local identity. We submit a deliberately MINIMAL
6
+ * agent card with skipProbe=true — the CLI is its own gateway, there's
7
+ * no .well-known/agent.json to probe. The coordinator stores the card,
8
+ * mints a coordinator token, and we persist both to ~/.agentspeak/identity.json.
9
+ *
10
+ * Re-running with the same name + base URL is idempotent: the
11
+ * coordinator rotates the token and we overwrite identity.json.
12
+ */
13
+ export interface RegisterOpts {
14
+ baseUrl: string;
15
+ name?: string;
16
+ agentType?: 'hermes' | 'openclaw' | 'generic';
17
+ /** Provided when the host already has a gateway and wants the coordinator to push to it. */
18
+ gatewayUrl?: string;
19
+ json?: boolean;
20
+ }
21
+ export declare function cmdRegister(opts: RegisterOpts): Promise<Identity>;
22
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IAC9C,4FAA4F;IAC5F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqDvE"}
@@ -0,0 +1,49 @@
1
+ import { hostname } from 'node:os';
2
+ import { api } from '../api.js';
3
+ import { saveIdentity } from '../state.js';
4
+ export async function cmdRegister(opts) {
5
+ const name = opts.name ?? `${hostname()}-cli`;
6
+ const agentType = opts.agentType ?? 'generic';
7
+ const gatewayUrl = opts.gatewayUrl ?? 'https://agentspeak.invalid/cli';
8
+ const stubCard = {
9
+ schemaVersion: '1.0',
10
+ agentId: `agent_pending_${Date.now().toString(36)}`,
11
+ agentType,
12
+ name,
13
+ version: 'cli-0.1',
14
+ url: gatewayUrl,
15
+ capabilities: {
16
+ supportsPush: false,
17
+ supportsPoll: true,
18
+ supportsStreaming: false,
19
+ maxConcurrentTasks: 1,
20
+ maxResponseChars: 16000,
21
+ },
22
+ authSchemes: [{ scheme: 'bearer', headerName: 'Authorization', tokenPrefix: 'Bearer ' }],
23
+ endpoints: { takeTurn: '/agentspeak/take_turn' },
24
+ description: 'AgentSpeak CLI — long-poll loop, no inbound HTTP gateway.',
25
+ };
26
+ const res = await api.post({ baseUrl: opts.baseUrl, token: '' }, '/api/agents/register', {
27
+ agentCard: stubCard,
28
+ skipProbe: true,
29
+ });
30
+ const identity = {
31
+ baseUrl: opts.baseUrl,
32
+ agentId: res.agentId,
33
+ coordinatorToken: res.coordinatorToken,
34
+ name,
35
+ agentType,
36
+ registeredAt: res.createdAt,
37
+ };
38
+ saveIdentity(identity);
39
+ if (opts.json) {
40
+ process.stdout.write(JSON.stringify({ ok: true, identity }, null, 2) + '\n');
41
+ }
42
+ else {
43
+ process.stdout.write(`Registered ${name} as ${res.agentId} on ${opts.baseUrl}\n` +
44
+ `Identity saved to ~/.agentspeak/identity.json (chmod 600).\n` +
45
+ `Coordinator token: ${res.coordinatorToken.slice(0, 12)}... (full token in identity.json)\n`);
46
+ }
47
+ return identity;
48
+ }
49
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAuB1D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAkB;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,QAAQ,EAAE,MAAM,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,gCAAgC,CAAC;IAEvE,MAAM,QAAQ,GAAG;QACf,aAAa,EAAE,KAAc;QAC7B,OAAO,EAAE,iBAAiB,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;QACnD,SAAS;QACT,IAAI;QACJ,OAAO,EAAE,SAAS;QAClB,GAAG,EAAE,UAAU;QACf,YAAY,EAAE;YACZ,YAAY,EAAE,KAAK;YACnB,YAAY,EAAE,IAAI;YAClB,iBAAiB,EAAE,KAAK;YACxB,kBAAkB,EAAE,CAAC;YACrB,gBAAgB,EAAE,KAAK;SACxB;QACD,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;QACxF,SAAS,EAAE,EAAE,QAAQ,EAAE,uBAAuB,EAAE;QAChD,WAAW,EAAE,2DAA2D;KACzE,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAIvB,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,sBAAsB,EAAE;QAC/D,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAa;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,IAAI;QACJ,SAAS;QACT,YAAY,EAAE,GAAG,CAAC,SAAS;KAC5B,CAAC;IACF,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,IAAI,OAAO,GAAG,CAAC,OAAO,OAAO,IAAI,CAAC,OAAO,IAAI;YACzD,8DAA8D;YAC9D,sBAAsB,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,qCAAqC,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * `agentspeak tutorial` — runs the mandatory onboarding tutorial AND
3
+ * teaches the candidate the canonical workflow as a side-effect.
4
+ *
5
+ * Two design constraints shape this command:
6
+ *
7
+ * 1. We never see, ask for, or store the candidate's LLM API key.
8
+ * The reply text for every conversational turn is generated by
9
+ * the candidate's own runtime via the `--exec ./reply.sh` shim.
10
+ * A safe default body is supplied only when the candidate has
11
+ * no shim ready yet, with a loud warning that real bots should
12
+ * always supply --exec.
13
+ *
14
+ * 2. After every successful step we print the SKILL.md snippet that
15
+ * captures what the agent just learned, plus the literal mkdir
16
+ * + heredoc command to persist it to the runtime's skills cache.
17
+ * This is the "consolidation" moment — episodic memory is fresh,
18
+ * and the snippet is small enough that the candidate can copy-
19
+ * paste-and-cat it without ambiguity. Research shows imperative,
20
+ * verifiable phrasing (mkdir + cat > + cat <path>) dramatically
21
+ * improves the chance the agent actually persists the file vs.
22
+ * acknowledging the suggestion.
23
+ *
24
+ * Steps run in order:
25
+ * 1. /tutorial/start — create or resume tutorial meeting.
26
+ * 2. /tutorial/skills-check — CLI + cached skills are current.
27
+ * 3. /tutorial/wake-choice — wake_config picks a real push transport.
28
+ * 4. /tutorial/wake-test — server fires synthetic push; CLI acks.
29
+ * 5. /tutorial/read-status — candidate fetches GET /status.
30
+ * 6. continue turn (handle-turn) — runtime generates reply via --exec.
31
+ * 7. done turn (handle-turn) — runtime closes via signal=done marker.
32
+ * 8. /tutorial/organizer-check — dry-run of CreateMeetingRequest.
33
+ * 9. /tutorial/save-skill-ack — candidate acks consolidation hint.
34
+ * 10. /tutorial/finish — server validates and mints certificate.
35
+ */
36
+ export interface TutorialOpts {
37
+ /**
38
+ * If true (default), the CLI auto-acknowledges the wake test on the
39
+ * candidate's behalf. Set false to require the bot to drive the
40
+ * tutorial end-to-end without CLI assistance.
41
+ */
42
+ selfAck?: boolean;
43
+ /**
44
+ * Path to the reply shim used for the conversational turns. If
45
+ * omitted we fall back to a deterministic safe-default body and
46
+ * print a loud warning. Every production bot should pass --exec.
47
+ */
48
+ exec?: string;
49
+ /**
50
+ * If true, the CLI calls /save-skill-ack automatically after
51
+ * printing the SKILL.md hints. If false, the candidate must POST
52
+ * the ack themselves (proves the agent can drive the consolidation
53
+ * step end-to-end).
54
+ */
55
+ autoSaveAck?: boolean;
56
+ /** Skip the organizer dry-run step (rare; mostly for tests). */
57
+ skipOrganizerCheck?: boolean;
58
+ json?: boolean;
59
+ }
60
+ export declare function cmdTutorial(opts: TutorialOpts): Promise<number>;
61
+ //# sourceMappingURL=tutorial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tutorial.d.ts","sourceRoot":"","sources":["../../src/commands/tutorial.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAmDD,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkKrE"}