@ouro.bot/cli 0.1.0-alpha.459 → 0.1.0-alpha.460

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/changelog.json CHANGED
@@ -1,6 +1,14 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.460",
6
+ "changes": [
7
+ "Mail read tools now distinguish an unpopulated Mailroom store from a real empty inbox: `mail_recent` and `mail_search` tell the agent when no mail has been imported or received yet instead of returning a bare `No matching mail.`",
8
+ "Empty delegated HEY/source reads now surface the configured source alias, explain that absence is onboarding/import/forwarding state rather than evidence about the human's inbox, and point the agent back to the agent-run setup/import flow.",
9
+ "The system prompt now carries the empty-Mailroom invariant plus the four Agent Mail golden paths, so agents know to validate HEY import, native Screener mail, cross-sense reaction, and Ouro Outlook audit without asking the human to remember the checklist."
10
+ ]
11
+ },
4
12
  {
5
13
  "version": "0.1.0-alpha.459",
6
14
  "changes": [
@@ -468,7 +468,9 @@ function senseRuntimeGuidance(channel, preReadStatusLines) {
468
468
  lines.push("mail setup hard rule: never tell the human to run `ouro account ensure`, `ouro connect mail`, `ouro mail import-mbox`, `ouro status`, or `ouro doctor` for setup. Say what I am about to run, run it myself, and report the result. If my current surface cannot run shell/tools, I ask for a tool-capable Ouro setup session or companion to continue; I do not offload CLI operation to the human.");
469
469
  lines.push("mail setup truth: Agent Mail uses Mailroom, not HEY OAuth/IMAP. For the full work substrate account, the agent-runnable command is `ouro account ensure --agent <agent> --owner-email <email> --source hey`; use `ouro connect mail --agent <agent> --owner-email <email> --source hey` for mail-only repair/provisioning, or `--no-delegated-source` for native-only mail. The detailed runbook is `docs/agent-mail-setup.md`.");
470
470
  lines.push("mail setup truth: HEY archive bootstrap is human-exported MBOX only. I ask for the browser-downloaded MBOX path, then I run `ouro mail import-mbox --file <path> --owner-email <email> --source hey --agent <agent>` myself and verify the import.");
471
+ lines.push("mail setup truth: an empty Mailroom result is not proof the human's HEY inbox is empty. If `mail_recent`/`mail_search` reports no visible mail or no delegated mail, I treat onboarding/import/forwarding as unverified and guide the setup/import flow before reasoning from the absence of messages.");
471
472
  lines.push("mail setup truth: verify with `ouro status`, `ouro doctor`, bounded mail tools (`mail_recent`, `mail_search`, `mail_thread`, `mail_access_log`), and the read-only Outlook Mailbox tab. `ouro doctor` is installation-wide; do not invent `ouro doctor --agent <agent>`.");
473
+ lines.push("mail validation golden paths: HEY import updates a real work object; native send/receive exercises Screener allow/discard and recovery; mail can trigger another configured sense; Ouro Outlook audits imports, decisions, sends, and access logs.");
472
474
  lines.push("mail setup boundaries: do not invent `ouro auth verify --provider mail`, HEY OAuth, HEY IMAP, `ouro mcp call mail ...`, policy flags, autonomous sending, destructive mail actions, or production MX/DNS/forwarding changes. HEY export, HEY forwarding, DNS, MX cutover, sending, and destructive actions require explicit human confirmation.");
473
475
  if (channel === "cli") {
474
476
  lines.push("cli is interactive: it is available when the user opens it, not something `ouro up` daemonizes.");
@@ -129,6 +129,63 @@ function renderAccessLog(entries) {
129
129
  })
130
130
  .join("\n");
131
131
  }
132
+ function renderSourceGrantStatus(config, agentId) {
133
+ if (!config.registryPath) {
134
+ return [
135
+ "delegated source aliases: unknown (runtime config has no registryPath).",
136
+ `agent-runnable repair: run ouro connect mail --agent ${agentId} --owner-email <human-email> --source hey.`,
137
+ ];
138
+ }
139
+ try {
140
+ const registry = readRegistry(config.registryPath);
141
+ const grants = registry.sourceGrants
142
+ .filter((grant) => grant.agentId === agentId && grant.enabled)
143
+ .map((grant) => `${grant.source}:${grant.ownerEmail} -> ${grant.aliasAddress}`);
144
+ if (grants.length === 0) {
145
+ return [
146
+ "delegated source aliases: none configured yet.",
147
+ `agent-runnable next step: run ouro account ensure --agent ${agentId} --owner-email <human-email> --source hey.`,
148
+ ];
149
+ }
150
+ return [`delegated source aliases: ${grants.join("; ")}.`];
151
+ }
152
+ catch (error) {
153
+ const message = error instanceof Error ? error.message : /* v8 ignore next -- fs and JSON.parse failures are Error instances. @preserve */ String(error);
154
+ return [
155
+ `delegated source aliases: unreadable registry (${message}).`,
156
+ `agent-runnable repair: run ouro connect mail --agent ${agentId} --owner-email <human-email> --source hey.`,
157
+ ];
158
+ }
159
+ }
160
+ async function renderEmptyMailResult(input) {
161
+ const anyVisible = await input.store.listMessages({ agentId: input.agentId, limit: 1 });
162
+ if (anyVisible.length === 0) {
163
+ return [
164
+ "No visible mail yet.",
165
+ `mail onboarding status: Mailroom is provisioned for ${input.config.mailboxAddress}, but this agent's encrypted store has 0 messages.`,
166
+ ...renderSourceGrantStatus(input.config, input.agentId),
167
+ "interpretation: this is not evidence that the human's HEY inbox is empty; Agent Mail has not yet received or imported mail visible to this agent.",
168
+ `agent next move: guide setup from docs/agent-mail-setup.md. If HEY mail is needed, ensure the delegated hey alias exists, ask the human for the exported MBOX file path, run ouro mail import-mbox --agent ${input.agentId} --owner-email <human-email> --source hey --file <mbox-path>, then verify with mail_recent/mail_search/Ouro Outlook.`,
169
+ "validation golden paths: HEY import updates a real work object; native send/receive goes through Screener; email can trigger another sense such as iMessage; Ouro Outlook audits the full story.",
170
+ ].join("\n");
171
+ }
172
+ if (input.scope === "delegated" || input.source) {
173
+ const delegated = await input.store.listMessages({
174
+ agentId: input.agentId,
175
+ compartmentKind: "delegated",
176
+ ...(input.source ? { source: input.source } : {}),
177
+ limit: 1,
178
+ });
179
+ if (delegated.length === 0) {
180
+ return [
181
+ "No delegated mail is visible for this source/scope yet.",
182
+ ...renderSourceGrantStatus(input.config, input.agentId),
183
+ "Mailroom has other mail, so check the delegated HEY import/forwarding/source filter before treating the human inbox as empty.",
184
+ ].join("\n");
185
+ }
186
+ }
187
+ return "No matching mail.";
188
+ }
132
189
  function actorFromContext(ctx, agentId) {
133
190
  const friend = ctx?.context?.friend;
134
191
  if (friend) {
@@ -293,8 +350,15 @@ exports.mailToolDefinitions = [
293
350
  tool: "mail_recent",
294
351
  reason: args.reason || "recent mail overview",
295
352
  });
296
- if (messages.length === 0)
297
- return "No matching mail.";
353
+ if (messages.length === 0) {
354
+ return renderEmptyMailResult({
355
+ agentId: resolved.agentName,
356
+ config: resolved.config,
357
+ store: resolved.store,
358
+ ...(scope ? { scope } : {}),
359
+ ...(args.source ? { source: args.source } : {}),
360
+ });
361
+ }
298
362
  return (0, file_store_1.decryptMessages)(messages, resolved.config.privateKeys).map(renderMessageSummary).join("\n\n");
299
363
  },
300
364
  summaryKeys: ["scope", "placement", "source", "limit"],
@@ -473,6 +537,15 @@ exports.mailToolDefinitions = [
473
537
  tool: "mail_search",
474
538
  reason: args.reason || `search: ${query}`,
475
539
  });
540
+ if (all.length === 0) {
541
+ return renderEmptyMailResult({
542
+ agentId: resolved.agentName,
543
+ config: resolved.config,
544
+ store: resolved.store,
545
+ ...(scope ? { scope } : {}),
546
+ ...(args.source ? { source: args.source } : {}),
547
+ });
548
+ }
476
549
  if (matching.length === 0)
477
550
  return "No matching mail.";
478
551
  return matching.map(renderMessageSummary).join("\n\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.459",
3
+ "version": "0.1.0-alpha.460",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",