From 4aab848317367408efa5c9355fd5a774e514e92a Mon Sep 17 00:00:00 2001 From: meidad Date: Fri, 12 Jun 2026 20:24:46 -0700 Subject: [PATCH 1/2] feat(mobile): consumer Advanced, Today, Inbox, and Brain surfaces Wire the iOS app's drawer destinations to real daemon data via MobileApi, with consumer-curated view models and per-user controls. View models (pure, unit-tested, dependency-free): - cron/loop-view.ts: surface managed background loops (auto-dream, style-analyze) with friendly labels; cron/loop-overrides.ts adds per-user opt-out, honored at fire time by a gate in daemon/cron-engine.ts. - cron/task-view.ts + cron/schedule-format.ts: curate user-scheduled tasks with prettified every/cron/at schedules. - skills/skill-view.ts: filter consumer-facing skills, hide dev/internal/channel tooling, resolve human-readable names. - plugins/builtin-tools.ts: read-only built-in tool listing for the Plugins page. Daemon data composers: - daemon/inbox.ts: pending drafts to approve + CATE agent requests. - daemon/today.ts: agenda + commitments + tasks, gated on the daily briefing. - memory/brain.ts: knowledge-graph overview for the Brain page. MobileApi (proto + handlers): GetInbox/GetToday/GetBrain, ListTasks/UpdateTask/ DeleteTask, ListLoops/SetLoopEnabled, ListSkills/ToggleSkill, ListPlugins, ApproveDraftWithEdit (captures edits as a learning signal), and agent avatar in the identity RPCs. sdk/tools.ts tags agent-scheduled tasks source:"agent". Evals: eval/feature-manifest.ts declares the new surfaces (managed-loop-override, scheduled-tasks, brain/inbox/today overviews) and corrects the draft-edit-learning effect SQL to category='fact' key LIKE 'correction_%'. Co-Authored-By: Claude Opus 4.8 (1M context) --- eval/feature-manifest.ts | 142 +++++++++- proto/nomos.proto | 169 ++++++++++++ src/cron/loop-overrides.ts | 29 +++ src/cron/loop-view.test.ts | 109 ++++++++ src/cron/loop-view.ts | 73 ++++++ src/cron/schedule-format.ts | 58 +++++ src/cron/task-view.test.ts | 61 +++++ src/cron/task-view.ts | 48 ++++ src/daemon/cron-engine.ts | 11 + src/daemon/inbox.ts | 125 +++++++++ src/daemon/mobile-api.ts | 472 ++++++++++++++++++++++++++-------- src/daemon/today.ts | 126 +++++++++ src/memory/brain.ts | 107 ++++++++ src/plugins/builtin-tools.ts | 26 ++ src/sdk/tools.ts | 1 + src/skills/skill-view.test.ts | 89 +++++++ src/skills/skill-view.ts | 111 ++++++++ 17 files changed, 1642 insertions(+), 115 deletions(-) create mode 100644 src/cron/loop-overrides.ts create mode 100644 src/cron/loop-view.test.ts create mode 100644 src/cron/loop-view.ts create mode 100644 src/cron/schedule-format.ts create mode 100644 src/cron/task-view.test.ts create mode 100644 src/cron/task-view.ts create mode 100644 src/daemon/inbox.ts create mode 100644 src/daemon/today.ts create mode 100644 src/memory/brain.ts create mode 100644 src/plugins/builtin-tools.ts create mode 100644 src/skills/skill-view.test.ts create mode 100644 src/skills/skill-view.ts diff --git a/eval/feature-manifest.ts b/eval/feature-manifest.ts index b7a9aef4..bf13f95e 100644 --- a/eval/feature-manifest.ts +++ b/eval/feature-manifest.ts @@ -369,6 +369,34 @@ export const FEATURES: FeatureSpec[] = [ "agent-created loops carry source='agent' + the owner's user_id (auditable + per-owner scoped)", ], }, + { + id: "managed-loop-override", + summary: + "Consumer Loops audit + control surface (MobileApi.ListLoops/SetLoopEnabled). The hosted user owns none of the instance's `system`-owned background loops, so ListLoops also surfaces a curated managed set (auto-dream -> 'Brain consolidation', style-analyze -> 'Writing style learning') under friendly labels. Toggling one writes a per-user app.userLoop..enabled config override (setLoopUserEnabled) instead of mutating the shared system row; cron-engine honors it at fire time as an AND-gate (isLoopUserDisabled).", + trigger: { kind: "turn" }, + entry: [ + "curateConsumerLoops", + "isLoopUserDisabled", + "setLoopUserEnabled", + "userLoopOverrideKey", + ], + effects: [ + { + claim: "toggling a managed loop persists app.userLoop..enabled in the config table", + sql: { + query: "SELECT count(*) FROM config WHERE key LIKE 'app.userLoop.%'", + expect: "nonzero", + }, + notExercised: true, + }, + ], + invariants: [ + "managed loops display friendly labels but toggle/delete key off the real job name", + "AND-gate: a managed loop fires only if its system row is enabled AND the user has not opted out", + "the shared system cron_jobs row is never mutated per-user (per-customer DB scoping)", + "infra plumbing (wiki/graph/magic-docs/delta-sync) + the proactive family are hidden from the consumer surface", + ], + }, // ── Wired runtime helpers (dormant-prone) ── { @@ -673,20 +701,27 @@ export const FEATURES: FeatureSpec[] = [ }, { id: "draft-edit-learning", - summary: "Capture user edits to drafts as corrections that update the user model.", + summary: + "Capture user edits to drafts as corrections that update the user model (approveWithEdit -> captureDraftEdit -> updateUserModel). Only an actual edit (edited != original) is captured; a plain approve is not.", trigger: { kind: "turn" }, entry: ["approveWithEdit"], effects: [ { - claim: "edits land as user_model corrections", + // A correction is stored as a fact whose key is `correction_` and + // whose value is { text: corrected, original } (see updateUserModel). + claim: "edits land as user_model corrections (category='fact', key LIKE 'correction_%')", sql: { - query: "SELECT count(*) FROM user_model WHERE category='correction'", + query: + "SELECT count(*) FROM user_model WHERE category = 'fact' AND key LIKE 'correction_%'", expect: "nonzero", }, notExercised: true, }, ], - invariants: ["per-owner scoped"], + invariants: [ + "per-owner scoped", + "only an actual edit is learned (plain approve writes no correction)", + ], }, { id: "shadow-observer", @@ -756,6 +791,105 @@ export const FEATURES: FeatureSpec[] = [ }, ], }, + { + id: "consumer-advanced-surface", + summary: + "Hosted Advanced curation (MobileApi.ListSkills/ToggleSkill/ListPlugins). ListSkills filters the full skill catalog to consumer-facing skills (operator-curated external Google skills + an allowlist of bundled consumer skills like pdf/xlsx/weather), under friendly labels, with each skill's persisted on/off folded in (skill..enabled). ToggleSkill resolves the friendly label back to the raw name (resolveSkillName) before persisting. ListPlugins returns a curated read-only built-in tool set instead of the developer marketplace plugins.", + trigger: { kind: "turn" }, + entry: ["curateConsumerSkills", "resolveSkillName", "isConsumerSkill"], + effects: [ + { + claim: "toggling a skill persists skill..enabled in the config table", + sql: { + query: "SELECT count(*) FROM config WHERE key LIKE 'skill.%.enabled'", + expect: "nonzero", + }, + notExercised: true, + }, + ], + invariants: [ + "consumer skills = external (operator-curated) + an allowlist of bundled consumer skills; dev/internal/channel skills are hidden", + "skills display friendly labels but the toggle round-trips back to the raw skill name", + "ListPlugins surfaces the curated built-in tool set (read-only), not the developer marketplace plugins", + ], + }, + { + id: "scheduled-tasks", + summary: + "Consumer Tasks surface (MobileApi.ListTasks/UpdateTask/DeleteTask). ListTasks returns the user's own scheduled cron_jobs (one-off 'at' reminders + recurring jobs created via schedule_task/loop_create), owner-scoped by user_id so the instance's system-owned background loops never appear. UpdateTask reschedules/renames/edits the instruction/enables; DeleteTask removes one. Both assert ownership before mutating.", + trigger: { kind: "turn" }, + entry: ["curateConsumerTasks", "toConsumerTask"], + effects: [ + { + claim: "the user's scheduled tasks are stored as owner-scoped cron_jobs", + sql: { + query: "SELECT count(*) FROM cron_jobs WHERE source IN ('agent','user')", + expect: "nonzero", + }, + notExercised: true, + }, + ], + invariants: [ + "Tasks are owner-scoped (user_id); managed/system loops never appear on this surface", + "UpdateTask/DeleteTask assert job.userId === the resolved owner before mutating", + "schedule_task stamps source='agent' (a user-owned task, not infra)", + ], + }, + { + id: "brain-overview", + summary: + "Consumer Brain page (MobileApi.GetBrain). Composes the read model from real per-user memory: the knowledge graph (kg_nodes/kg_edges via getProjection) drives the map + entities, and the accumulated user_model drives the recently-learned facts feed. Owner-scoped via TenantContext.", + trigger: { kind: "turn" }, + entry: ["getBrainOverview", "getProjection"], + effects: [ + { + claim: "the brain map reads nodes from the per-user knowledge graph", + sql: { query: "SELECT count(*) FROM kg_nodes", expect: "nonzero" }, + notExercised: true, + }, + ], + invariants: [ + "owner-scoped: nodes/edges/facts filtered by user_id", + "facts come from user_model (confidence binned to 0..3); entities/edges from kg_nodes/kg_edges", + ], + }, + { + id: "inbox-overview", + summary: + "Consumer Inbox (MobileApi.GetInbox). Two owner-scoped sections: the agent's drafted replies awaiting approval (draft_messages: pending=needs-you, approved/sent=handled) and the CATE agent-to-agent inbound queue (cate_inbound, best-effort). Draft actions reuse ApproveDraft/RejectDraft; CATE via ActOnInboxItem.", + trigger: { kind: "turn" }, + entry: ["getInboxOverview"], + effects: [ + { + claim: "pending drafts awaiting approval are owner-scoped in draft_messages", + sql: { query: "SELECT count(*) FROM draft_messages", expect: "nonzero" }, + notExercised: true, + }, + ], + invariants: [ + "owner-scoped by user_id", + "drafts + CATE merged read-only; mutations via existing draft/inbox RPCs", + ], + }, + { + id: "today-overview", + summary: + "Consumer Today brief (MobileApi.GetToday). Composes today's Google Calendar events (live via gapiFetch, best-effort -- empty when Google isn't connected), pending commitments, and the user's scheduled tasks. briefingEnabled=false (proactive autonomy off) tells the client to show the enable-briefing deep link.", + trigger: { kind: "turn" }, + entry: ["getTodayOverview"], + effects: [ + { + claim: "commitments feeding the brief are owner-scoped", + sql: { query: "SELECT count(*) FROM commitments", expect: "nonzero" }, + notExercised: true, + }, + ], + invariants: [ + "owner-scoped", + "calendar is best-effort (empty when Google isn't connected)", + "gated on app.inboxAutonomy != 'off'", + ], + }, // ── Consent-aware drafting ── { diff --git a/proto/nomos.proto b/proto/nomos.proto index ccab57f1..b0eaeb48 100644 --- a/proto/nomos.proto +++ b/proto/nomos.proto @@ -164,6 +164,7 @@ service MobileApi { // Skills tab rpc ListSkills (Empty) returns (MSkillsResponse); rpc ToggleSkill (MSkillToggleRequest) returns (MSkillToggleResponse); + rpc ListPlugins (Empty) returns (MPluginsResponse); // Earnings tab rpc GetEarnings (MEarningsRequest) returns (MEarningsResponse); @@ -178,6 +179,8 @@ service MobileApi { rpc UpdateConsent (MConsentRequest) returns (MAck); rpc UpdateTrustTier (MTrustTierRequest) returns (MAck); rpc UpdatePermission (MPermissionRequest) returns (MAck); + rpc UpdateAppSetting (MAppSettingRequest) returns (MAck); + rpc UpdateAgentIdentity (MAgentIdentityRequest) returns (MAck); rpc ListIntegrations (Empty) returns (MIntegrationsResponse); rpc StartConnectIntegration (MStartConnectRequest) returns (MStartConnectResponse); rpc ConnectGoogleAccount (MConnectGoogleRequest) returns (MAck); @@ -198,6 +201,23 @@ service MobileApi { rpc ListLoops (Empty) returns (MLoopsResponse); rpc SetLoopEnabled (MSetLoopEnabledRequest) returns (MAck); rpc DeleteLoop (MLoopDeleteRequest) returns (MAck); + + // Tasks tab (the user's scheduled tasks: one-off reminders + recurring jobs, + // editable: reschedule, rename, edit instruction, enable/disable, delete) + rpc ListTasks (Empty) returns (MTasksResponse); + rpc UpdateTask (MTaskUpdateRequest) returns (MAck); + rpc DeleteTask (MTaskDeleteRequest) returns (MAck); + + // Brain tab (the user's knowledge graph + learned facts, for the feed + map) + rpc GetBrain (Empty) returns (MBrainResponse); + + // Inbox tab (drafts to approve + CATE agent requests). Actions reuse + // ApproveDraft/RejectDraft (drafts) + ActOnInboxItem (CATE). + rpc GetInbox (Empty) returns (MGetInboxResponse); + + // Today tab (the daily brief: calendar + commitments + tasks, gated on the + // daily briefing being enabled). + rpc GetToday (Empty) returns (MTodayResponse); } // Loops (autonomous recurring jobs) @@ -222,6 +242,109 @@ message MLoopDeleteRequest { string name = 1; } +// Tasks (the user's scheduled tasks) +message MTask { + string id = 1; + string name = 2; + string prompt = 3; // the instruction the task runs + string schedule = 4; // raw: "15m" | cron expr | ISO timestamp + string schedule_type = 5; // every | cron | at + string display_schedule = 6; // friendly, display-only + bool enabled = 7; + string source = 8; + string last_run = 9; // ISO-8601, empty if never run +} +message MTasksResponse { + repeated MTask tasks = 1; +} +// Full-state update (the client sends the edited task); empty name/schedule are +// ignored so a toggle-only call never blanks fields. +message MTaskUpdateRequest { + string id = 1; + string name = 2; + string prompt = 3; + string schedule = 4; + string schedule_type = 5; + bool enabled = 6; +} +message MTaskDeleteRequest { + string id = 1; +} + +// Brain (knowledge graph + learned facts) +message MBrainNode { + string id = 1; + string label = 2; + string kind = 3; // person | org | topic | decision | project | value | event | wiki | vault + string summary = 4; + int32 degree = 5; // connection count within the returned subgraph + double confidence = 6; +} +message MBrainEdge { + string src = 1; + string dst = 2; + string relation = 3; +} +message MBrainFact { + string text = 1; + string source = 2; + int32 confidence = 3; // 0..3 + string learned_at = 4; // ISO-8601 +} +message MBrainResponse { + repeated MBrainNode nodes = 1; + repeated MBrainEdge edges = 2; + repeated MBrainFact facts = 3; + int32 entity_count = 4; + int32 fact_count = 5; +} + +// Inbox (drafts + CATE agent requests) +message MInboxDraft { + string id = 1; + string recipient = 2; + string preview = 3; + string status = 4; // pending | approved | sent + string platform = 5; + string created_at = 6; +} +message MInboxCate { + string id = 1; + string from_label = 2; + string trust_tier = 3; + string subject = 4; + string bond_amount = 5; + string created_at = 6; +} +message MGetInboxResponse { + repeated MInboxDraft drafts = 1; + repeated MInboxCate cate = 2; + int32 blocked_count = 3; +} + +// Today (the daily brief) +message MTodayEvent { + string time = 1; + string title = 2; + string meta = 3; +} +message MTodayCommitment { + string id = 1; + string description = 2; + string due = 3; +} +message MTodayTask { + string id = 1; + string name = 2; + string schedule = 3; +} +message MTodayResponse { + bool briefing_enabled = 1; + repeated MTodayEvent events = 2; + repeated MTodayCommitment commitments = 3; + repeated MTodayTask tasks = 4; +} + message MAck { bool success = 1; string message = 2; @@ -360,6 +483,16 @@ message MSkillsResponse { repeated MSkill skills = 1; } +message MPlugin { + string name = 1; + string description = 2; + string marketplace = 3; +} + +message MPluginsResponse { + repeated MPlugin plugins = 1; +} + message MSkillToggleRequest { string name = 1; bool enabled = 2; @@ -466,6 +599,42 @@ message MSettingsResponse { repeated MTrustTier trust_tiers = 2; repeated MPermission permissions = 3; repeated MIntegration integrations = 4; + repeated MConsentEntry consent = 5; + MAgentIdentity identity = 6; + repeated MAppToggle app_toggles = 7; + MProactive proactive = 8; +} + +message MProactive { + string mode = 1; // off | passive | active (app.inboxAutonomy) + string briefing = 2; // cron for the daily briefing (app.briefingCron) +} + +message MConsentEntry { + string platform = 1; + string mode = 2; // always_ask | auto_approve | notify_only +} + +message MAgentIdentity { + string name = 1; + string voice = 2; // personality / voice & tone (the SOUL) + string avatar = 3; // chosen avatar (an emoji), empty = monogram fallback +} + +message MAppToggle { + string key = 1; // app. config key + bool enabled = 2; +} + +message MAppSettingRequest { + string key = 1; // app. config key (consumer-safe subset only) + string value = 2; // "true"/"false" for bools, raw string otherwise +} + +message MAgentIdentityRequest { + string name = 1; + string voice = 2; + string avatar = 3; } message MConsentRequest { diff --git a/src/cron/loop-overrides.ts b/src/cron/loop-overrides.ts new file mode 100644 index 00000000..17e89f01 --- /dev/null +++ b/src/cron/loop-overrides.ts @@ -0,0 +1,29 @@ +/** + * Per-user (per-customer DB) enable/disable override for a managed background + * loop. + * + * The instance's always-on loops (auto-dream, style-analyze, ...) live as a + * single cron_jobs row owned by the synthetic `system` tenant, so they must not + * be mutated per-user. Instead the consumer Loops UI toggles a config flag here, + * and cron-engine consults it at fire time as an AND-gate: a managed loop runs + * only if its system row is enabled AND the user has not opted out. Absent flag + * = enabled (default on). In a per-customer DB the config table is the customer's + * own, so this flag is effectively per-user. + */ + +import { getConfigValue, setConfigValue } from "../db/config.ts"; + +export function userLoopOverrideKey(name: string): string { + return `app.userLoop.${name}.enabled`; +} + +/** True when the user has explicitly turned this loop off. */ +export async function isLoopUserDisabled(name: string): Promise { + const v = await getConfigValue(userLoopOverrideKey(name)); + return v === false || v === "false"; +} + +/** Persist the user's on/off choice for a managed loop. */ +export async function setLoopUserEnabled(name: string, enabled: boolean): Promise { + await setConfigValue(userLoopOverrideKey(name), enabled); +} diff --git a/src/cron/loop-view.test.ts b/src/cron/loop-view.test.ts new file mode 100644 index 00000000..3c9f7d98 --- /dev/null +++ b/src/cron/loop-view.test.ts @@ -0,0 +1,109 @@ +import { describe, it, expect } from "vitest"; +import { curateConsumerLoops, prettifySchedule, MANAGED_LABEL_TO_NAME } from "./loop-view.ts"; +import type { CronJob } from "./types.ts"; + +function job(p: Partial): CronJob { + return { + id: p.id ?? p.name ?? "id", + userId: p.userId ?? "system", + name: p.name ?? "job", + schedule: p.schedule ?? "6h", + scheduleType: p.scheduleType ?? "every", + sessionTarget: "isolated", + deliveryMode: "none", + prompt: p.prompt ?? "", + enabled: p.enabled ?? true, + errorCount: p.errorCount ?? 0, + lastRun: p.lastRun, + createdAt: new Date(0), + source: p.source, + }; +} + +// Mirrors the live customer DB: 4 system loops + bundled examples (owned by +// "local", so absent from both partitions) + agent-created loops. +const SYSTEM = [ + job({ name: "auto-dream", schedule: "6h", source: "system" }), + job({ name: "style-analyze", schedule: "24h", source: "system" }), + job({ name: "graph-semantic", schedule: "6h", source: "system" }), + job({ name: "magic-docs-refresh", schedule: "1h", source: "system" }), + job({ name: "wiki-compile", schedule: "2h", source: "system" }), + job({ + name: "proactive:morning-briefing", + schedule: "0 8 * * *", + scheduleType: "cron", + source: "system", + }), +]; + +describe("curateConsumerLoops", () => { + it("surfaces only the managed system loops under friendly labels", () => { + const out = curateConsumerLoops(SYSTEM, new Set()); + const names = out.map((l) => l.name); + expect(names).toEqual(["Brain consolidation", "Writing style learning"]); + // Infra plumbing + proactive family are hidden. + for (const hidden of [ + "graph-semantic", + "magic-docs-refresh", + "wiki-compile", + "proactive:morning-briefing", + ]) { + expect(names).not.toContain(hidden); + } + }); + + it("marks managed loops source=managed so the client renders a toggle", () => { + const out = curateConsumerLoops(SYSTEM, new Set()); + expect(out.every((l) => l.source === "managed")).toBe(true); + }); + + it("folds the per-user opt-out into enabled without mutating the row", () => { + const on = curateConsumerLoops(SYSTEM, new Set()); + expect(on.find((l) => l.name === "Brain consolidation")?.enabled).toBe(true); + + const off = curateConsumerLoops(SYSTEM, new Set(["auto-dream"])); + expect(off.find((l) => l.name === "Brain consolidation")?.enabled).toBe(false); + // The other managed loop is unaffected. + expect(off.find((l) => l.name === "Writing style learning")?.enabled).toBe(true); + }); + + it("a disabled system row reads disabled even without an opt-out", () => { + const out = curateConsumerLoops( + [job({ name: "auto-dream", source: "system", enabled: false })], + new Set(), + ); + expect(out.find((l) => l.name === "Brain consolidation")?.enabled).toBe(false); + }); + + it("does not surface user/agent jobs (those are the Tasks surface)", () => { + const out = curateConsumerLoops( + [job({ name: "weekly-report", source: "agent", userId: "ba_user" })], + new Set(), + ); + // Only managed system loops by name are surfaced; an agent job is not managed. + expect(out).toHaveLength(0); + }); + + it("round-trips managed friendly labels back to real job names for toggling", () => { + expect(MANAGED_LABEL_TO_NAME.get("Brain consolidation")).toBe("auto-dream"); + expect(MANAGED_LABEL_TO_NAME.get("Writing style learning")).toBe("style-analyze"); + }); +}); + +describe("prettifySchedule", () => { + it("renders 'every' cadences", () => { + expect(prettifySchedule("6h", "every")).toBe("Every 6 hours"); + expect(prettifySchedule("1h", "every")).toBe("Hourly"); + expect(prettifySchedule("24h", "every")).toBe("Daily"); + expect(prettifySchedule("15m", "every")).toBe("Every 15 minutes"); + }); + + it("renders daily cron expressions", () => { + expect(prettifySchedule("0 8 * * *", "cron")).toBe("Daily at 8:00 AM"); + expect(prettifySchedule("30 17 * * *", "cron")).toBe("Daily at 5:30 PM"); + }); + + it("falls back to the raw string for unrecognized shapes", () => { + expect(prettifySchedule("0 9 * * 1", "cron")).toBe("0 9 * * 1"); + }); +}); diff --git a/src/cron/loop-view.ts b/src/cron/loop-view.ts new file mode 100644 index 00000000..bf71b7dd --- /dev/null +++ b/src/cron/loop-view.ts @@ -0,0 +1,73 @@ +/** + * Consumer Loops view model -- the pure shaping logic behind MobileApi.ListLoops. + * + * The instance runs its background loops as single rows owned by the synthetic + * `system` tenant, so a hosted user owns none of them and a naive per-user query + * returns nothing. The consumer Loops page is an audit + control surface, so we + * ALSO surface a curated set of the always-on "managed" loops under friendly + * labels. Pure + dependency-free so it is unit-testable in isolation. + */ + +import type { CronJob } from "./types.ts"; +import { prettifySchedule } from "./schedule-format.ts"; + +export { prettifySchedule }; + +export interface ConsumerLoop { + id: string; + name: string; + schedule: string; + enabled: boolean; + source: string; + errorCount: number; + lastRun: string; + prompt: string; +} + +/** system loop name -> friendly consumer label. Only these `system`-owned loops + * are surfaced; every other system loop (wiki/graph/magic-docs/delta-sync + the + * proactive family) is hidden from the consumer. */ +export const MANAGED_LOOPS: Record = { + "auto-dream": "Brain consolidation", + "style-analyze": "Writing style learning", +}; + +export const MANAGED_LABEL_TO_NAME = new Map( + Object.entries(MANAGED_LOOPS).map(([name, label]) => [label, name]), +); + +function toWire(j: CronJob, over: Partial = {}): ConsumerLoop { + return { + id: j.id, + name: over.name ?? j.name, + schedule: prettifySchedule(j.schedule, j.scheduleType), + enabled: over.enabled ?? j.enabled, + source: over.source ?? j.source ?? "user", + errorCount: j.errorCount, + lastRun: j.lastRun ? j.lastRun.toISOString() : "", + prompt: "", + }; +} + +/** + * Build the consumer Loops audit list: a curated, friendly-labeled managed set + * (auto-dream -> "Brain consolidation", style-analyze -> "Writing style + * learning") owned by the `system` tenant, with the per-user override folded into + * `enabled`. `optedOut` is the set of managed job NAMES the user has disabled. + * + * The user's / agent's own scheduled jobs are NOT shown here -- those are the + * Tasks surface (see cron/task-view.ts). Loops = the assistant's always-on + * background behaviors; Tasks = what you/the assistant scheduled. + */ +export function curateConsumerLoops(system: CronJob[], optedOut: Set): ConsumerLoop[] { + return system + .filter((j) => MANAGED_LOOPS[j.name]) + .map((j) => + toWire(j, { + name: MANAGED_LOOPS[j.name], + source: "managed", + enabled: j.enabled && !optedOut.has(j.name), + }), + ) + .sort((a, b) => a.name.localeCompare(b.name)); +} diff --git a/src/cron/schedule-format.ts b/src/cron/schedule-format.ts new file mode 100644 index 00000000..9e3acd8a --- /dev/null +++ b/src/cron/schedule-format.ts @@ -0,0 +1,58 @@ +/** + * Human-readable rendering of a cron_jobs schedule, shared by the consumer Loops + * and Tasks surfaces. The wire `schedule` stays the raw string (clients edit it + * and toggle/delete key off the id/name); this is display-only. + */ + +export function prettifySchedule(schedule: string, scheduleType: string): string { + const s = schedule.trim(); + + if (scheduleType === "every") { + const m = s.match(/^(\d+)\s*([smhd])$/i); + if (m) { + const n = Number(m[1]); + switch (m[2].toLowerCase()) { + case "h": + return n === 1 ? "Hourly" : n === 24 ? "Daily" : `Every ${n} hours`; + case "m": + return `Every ${n} minute${n === 1 ? "" : "s"}`; + case "d": + return n === 1 ? "Daily" : `Every ${n} days`; + case "s": + return `Every ${n} second${n === 1 ? "" : "s"}`; + } + } + return `Every ${s}`; + } + + if (scheduleType === "cron") { + const parts = s.split(/\s+/); + if (parts.length === 5) { + const [min, hour, dom, , dow] = parts; + if (/^\d+$/.test(min) && /^\d+$/.test(hour) && dom === "*" && dow === "*") { + return `Daily at ${formatClock(Number(hour), min)}`; + } + } + return s; + } + + if (scheduleType === "at") { + const d = new Date(s); + if (!Number.isNaN(d.getTime())) { + return `Once, ${d.toLocaleString("en-US", { + month: "short", + day: "numeric", + hour: "numeric", + minute: "2-digit", + })}`; + } + return s; + } + + return s; +} + +function formatClock(hour: number, min: string): string { + const h12 = hour % 12 === 0 ? 12 : hour % 12; + return `${h12}:${min.padStart(2, "0")} ${hour < 12 ? "AM" : "PM"}`; +} diff --git a/src/cron/task-view.test.ts b/src/cron/task-view.test.ts new file mode 100644 index 00000000..7f124875 --- /dev/null +++ b/src/cron/task-view.test.ts @@ -0,0 +1,61 @@ +import { describe, it, expect } from "vitest"; +import { curateConsumerTasks, toConsumerTask } from "./task-view.ts"; +import { prettifySchedule } from "./schedule-format.ts"; +import type { CronJob } from "./types.ts"; + +function job(p: Partial): CronJob { + return { + id: p.id ?? p.name ?? "id", + userId: p.userId ?? "ba_user", + name: p.name ?? "task", + schedule: p.schedule ?? "15m", + scheduleType: p.scheduleType ?? "every", + sessionTarget: "isolated", + deliveryMode: "none", + prompt: p.prompt ?? "do the thing", + enabled: p.enabled ?? true, + errorCount: p.errorCount ?? 0, + lastRun: p.lastRun, + createdAt: new Date(0), + source: p.source ?? "agent", + }; +} + +describe("toConsumerTask", () => { + it("carries the raw schedule + type AND a friendly display string", () => { + const t = toConsumerTask(job({ name: "check-email", schedule: "15m", scheduleType: "every" })); + expect(t.schedule).toBe("15m"); + expect(t.scheduleType).toBe("every"); + expect(t.displaySchedule).toBe("Every 15 minutes"); + expect(t.prompt).toBe("do the thing"); + }); + + it("renders a one-off 'at' task time", () => { + const t = toConsumerTask(job({ schedule: "2026-06-13T17:00:00Z", scheduleType: "at" })); + expect(t.displaySchedule.startsWith("Once,")).toBe(true); + }); +}); + +describe("curateConsumerTasks", () => { + it("sorts enabled first, then alphabetical", () => { + const out = curateConsumerTasks([ + job({ name: "zebra", enabled: true }), + job({ name: "apple", enabled: false }), + job({ name: "mango", enabled: true }), + ]); + expect(out.map((t) => t.name)).toEqual(["mango", "zebra", "apple"]); + }); + + it("passes through every owned job (filtering is done by the per-user query)", () => { + const out = curateConsumerTasks([job({ name: "a" }), job({ name: "b" })]); + expect(out).toHaveLength(2); + }); +}); + +describe("prettifySchedule (shared)", () => { + it("handles every / cron / at", () => { + expect(prettifySchedule("1h", "every")).toBe("Hourly"); + expect(prettifySchedule("0 9 * * *", "cron")).toBe("Daily at 9:00 AM"); + expect(prettifySchedule("not-a-date", "at")).toBe("not-a-date"); + }); +}); diff --git a/src/cron/task-view.ts b/src/cron/task-view.ts new file mode 100644 index 00000000..b3a0261b --- /dev/null +++ b/src/cron/task-view.ts @@ -0,0 +1,48 @@ +/** + * Consumer Tasks view model -- the pure shaping behind MobileApi.ListTasks. + * + * A "task" is any cron_jobs row the user owns: one-off reminders ("at") and + * recurring jobs ("every"/"cron") that the user or the assistant scheduled on + * their behalf. The instance's always-on background loops are owned by the + * synthetic `system` tenant, so a per-user query (user_id = resolved owner) never + * includes them -- Loops and Tasks stay cleanly separate. + */ + +import type { CronJob } from "./types.ts"; +import { prettifySchedule } from "./schedule-format.ts"; + +export interface ConsumerTask { + id: string; + name: string; + prompt: string; + /** Raw schedule string (the client edits this). */ + schedule: string; + /** every | cron | at */ + scheduleType: string; + /** Friendly, display-only cadence (e.g. "Every 15 minutes", "Once, Jun 13 at 5:00 PM"). */ + displaySchedule: string; + enabled: boolean; + source: string; + lastRun: string; +} + +export function toConsumerTask(j: CronJob): ConsumerTask { + return { + id: j.id, + name: j.name, + prompt: j.prompt, + schedule: j.schedule, + scheduleType: j.scheduleType, + displaySchedule: prettifySchedule(j.schedule, j.scheduleType), + enabled: j.enabled, + source: j.source ?? "user", + lastRun: j.lastRun ? j.lastRun.toISOString() : "", + }; +} + +/** The user's scheduled tasks, enabled first then alphabetical. */ +export function curateConsumerTasks(jobs: CronJob[]): ConsumerTask[] { + return jobs + .map(toConsumerTask) + .sort((a, b) => Number(b.enabled) - Number(a.enabled) || a.name.localeCompare(b.name)); +} diff --git a/src/daemon/cron-engine.ts b/src/daemon/cron-engine.ts index e3223400..8013217f 100644 --- a/src/daemon/cron-engine.ts +++ b/src/daemon/cron-engine.ts @@ -12,6 +12,7 @@ import type { ChannelManager } from "./channel-manager.ts"; import type { AgentEvent } from "./types.ts"; import { createLogger } from "../lib/logger.ts"; import { stripHeartbeatToken } from "../auto-reply/heartbeat.ts"; +import { isLoopUserDisabled } from "../cron/loop-overrides.ts"; const log = createLogger("cron-engine"); @@ -66,6 +67,16 @@ export class CronEngine { } private async handleCronJob(job: CronJob): Promise { + // Per-user (per-customer DB) loop opt-out. The consumer Loops UI toggles a + // config override rather than mutating the shared `system` row, so honor it + // here: a managed loop the user turned off must actually stop firing. Absent + // flag = enabled (default on). Keyed generically by job name so any future + // override is covered without special-casing. + if (await isLoopUserDisabled(job.name)) { + log.info(`Skipping ${job.name}: disabled by user`); + return; + } + // Intercept delta-sync sentinel prompts -- route to ingest scheduler // instead of the agent message queue. if (job.prompt.startsWith("__delta_sync__:")) { diff --git a/src/daemon/inbox.ts b/src/daemon/inbox.ts new file mode 100644 index 00000000..321fae06 --- /dev/null +++ b/src/daemon/inbox.ts @@ -0,0 +1,125 @@ +/** + * Inbox overview -- the read model behind MobileApi.GetInbox. + * + * Two sections: (1) the agent's drafted replies awaiting the user's approval + * (`draft_messages`: pending = "needs you", approved/sent = "handled"), and + * (2) the CATE agent-to-agent inbound queue (`cate_inbound`, trust tiers + bonds). + * Owner-scoped. Draft actions reuse ApproveDraft/RejectDraft; CATE actions reuse + * ActOnInboxItem. + */ + +import type { TenantContext } from "../auth/tenant-context.ts"; +import { listPendingDrafts, type DraftRow } from "../db/drafts.ts"; +import { getKysely } from "../db/client.ts"; +import { sql } from "kysely"; + +export interface InboxDraft { + id: string; + recipient: string; + preview: string; + status: string; // pending | approved | sent + platform: string; + createdAt: string; +} +export interface InboxCate { + id: string; + fromLabel: string; + trustTier: string; + subject: string; + bondAmount: string; + createdAt: string; +} +export interface InboxOverview { + drafts: InboxDraft[]; + cate: InboxCate[]; + blockedCount: number; +} + +function draftRecipient(d: DraftRow): string { + // context is a jsonb column; the driver may hand it back as an object or as a + // raw JSON string -- handle both. + let c: Record = {}; + const raw: unknown = d.context; + if (typeof raw === "string") { + try { + c = JSON.parse(raw) as Record; + } catch { + c = {}; + } + } else if (raw && typeof raw === "object") { + c = raw as Record; + } + for (const key of ["contactName", "recipient", "to", "sender"]) { + const v = c[key]; + if (typeof v === "string" && v.trim()) return v; + } + return d.platform.charAt(0).toUpperCase() + d.platform.slice(1); +} + +function toInboxDraft(d: DraftRow): InboxDraft { + return { + id: d.id, + recipient: draftRecipient(d), + // Full draft text (the client truncates the list row; the edit sheet needs all of it). + preview: d.content, + status: d.status, + platform: d.platform, + createdAt: d.created_at.toISOString(), + }; +} + +export async function getInboxOverview(ctx: TenantContext): Promise { + const userId = ctx.userId; + const db = getKysely(); + + const pending = await listPendingDrafts(userId); + const handled = (await db + .selectFrom("draft_messages") + .selectAll() + .where("user_id", "=", userId) + .where("status", "in", ["approved", "sent"]) + .orderBy("created_at", "desc") + .limit(5) + .execute()) as unknown as DraftRow[]; + + const drafts = [...pending.map(toInboxDraft), ...handled.map(toInboxDraft)]; + + let cate: InboxCate[] = []; + let blockedCount = 0; + try { + const rows = await db.executeQuery( + sql<{ + id: string; + from_label: string | null; + trust_tier: string; + subject: string | null; + bond_amount: string | null; + created_at: Date; + }>` + SELECT id, from_label, trust_tier, subject, bond_amount::text AS bond_amount, created_at + FROM cate_inbound WHERE user_id = ${userId} AND status = 'pending' + ORDER BY created_at DESC LIMIT 50 + `.compile(db), + ); + cate = rows.rows.map((r) => ({ + id: r.id, + fromLabel: r.from_label ?? "", + trustTier: r.trust_tier, + subject: r.subject ?? "", + bondAmount: r.bond_amount ?? "", + createdAt: r.created_at.toISOString(), + })); + const blocked = await db.executeQuery( + sql<{ + count: string; + }>`SELECT COUNT(*)::text AS count FROM cate_inbound WHERE user_id = ${userId} AND status = 'denied'`.compile( + db, + ), + ); + blockedCount = Number(blocked.rows[0]?.count ?? 0); + } catch { + // pre-Phase-5b: no cate_inbound table -> drafts only. + } + + return { drafts, cate, blockedCount }; +} diff --git a/src/daemon/mobile-api.ts b/src/daemon/mobile-api.ts index 0741d91a..cbaf45f0 100644 --- a/src/daemon/mobile-api.ts +++ b/src/daemon/mobile-api.ts @@ -22,6 +22,8 @@ import type { DraftManager } from "./draft-manager.ts"; import type { AgentEvent, IncomingMessage } from "./types.ts"; import { getKysely } from "../db/client.ts"; import { listIntegrations } from "../db/integrations.ts"; +import { getConfigValue, setConfigValue } from "../db/config.ts"; +import { setConsentMode, listConsentModes, type ConsentMode } from "../db/consent-config.ts"; import { buildAuthUrl, exchangeCode, @@ -36,15 +38,34 @@ import { verifyOAuthState, } from "../auth/google-integration.ts"; import { loadSkills } from "../skills/loader.ts"; +import { + curateConsumerSkills, + resolveSkillName, + isConsumerSkill, + type ConsumerSkill, +} from "../skills/skill-view.ts"; +import { BUILTIN_TOOLS } from "../plugins/builtin-tools.ts"; import { getProjection, neighborhood, searchNodes } from "../memory/graph.ts"; import type { GraphNode, GraphEdge } from "../memory/graph.ts"; import { withAuthUnary, withAuthStream } from "../auth/grpc-interceptor.ts"; import { registerDevice, unregisterDevice } from "./push-notifications.ts"; import { vaultDelete, vaultList, vaultRead, vaultWrite } from "../memory/vault.ts"; import { CronStore } from "../cron/store.ts"; +import { isLoopUserDisabled, setLoopUserEnabled } from "../cron/loop-overrides.ts"; +import { + curateConsumerLoops, + MANAGED_LOOPS, + MANAGED_LABEL_TO_NAME, + type ConsumerLoop, +} from "../cron/loop-view.ts"; +import { curateConsumerTasks, type ConsumerTask } from "../cron/task-view.ts"; +import type { CronJobUpdate, ScheduleType } from "../cron/types.ts"; +import { getBrainOverview } from "../memory/brain.ts"; +import { getInboxOverview } from "./inbox.ts"; +import { getTodayOverview } from "./today.ts"; import { createLogger } from "../lib/logger.ts"; import type { TenantContext } from "../auth/tenant-context.ts"; -import { resolveMemoryUserId } from "../auth/tenant-context.ts"; +import { resolveMemoryUserId, systemTenant } from "../auth/tenant-context.ts"; const log = createLogger("mobile-api"); @@ -84,6 +105,7 @@ export function buildMobileApiHandlers(deps: MobileApiDeps) { ), ListSkills: withAuthUnary("/nomos.MobileApi/ListSkills", () => handleListSkills()), ToggleSkill: withAuthUnary("/nomos.MobileApi/ToggleSkill", (call) => handleToggleSkill(call)), + ListPlugins: withAuthUnary("/nomos.MobileApi/ListPlugins", () => handleListPlugins()), GetEarnings: withAuthUnary("/nomos.MobileApi/GetEarnings", () => handleGetEarnings()), GetGraph: withAuthUnary("/nomos.MobileApi/GetGraph", (call, ctx) => handleGetGraph(call, ctx)), GetGraphNeighbors: withAuthUnary("/nomos.MobileApi/GetGraphNeighbors", (call, ctx) => @@ -102,6 +124,12 @@ export function buildMobileApiHandlers(deps: MobileApiDeps) { UpdatePermission: withAuthUnary("/nomos.MobileApi/UpdatePermission", (call) => handleUpdatePermission(call), ), + UpdateAppSetting: withAuthUnary("/nomos.MobileApi/UpdateAppSetting", (call) => + handleUpdateAppSetting(call), + ), + UpdateAgentIdentity: withAuthUnary("/nomos.MobileApi/UpdateAgentIdentity", (call) => + handleUpdateAgentIdentity(call), + ), ListIntegrations: withAuthUnary("/nomos.MobileApi/ListIntegrations", (_, ctx) => handleListIntegrations(ctx), ), @@ -143,6 +171,16 @@ export function buildMobileApiHandlers(deps: MobileApiDeps) { DeleteLoop: withAuthUnary("/nomos.MobileApi/DeleteLoop", (call, ctx) => handleDeleteLoop(call, ctx), ), + ListTasks: withAuthUnary("/nomos.MobileApi/ListTasks", (_, ctx) => handleListTasks(ctx)), + UpdateTask: withAuthUnary("/nomos.MobileApi/UpdateTask", (call, ctx) => + handleUpdateTask(call, ctx), + ), + DeleteTask: withAuthUnary("/nomos.MobileApi/DeleteTask", (call, ctx) => + handleDeleteTask(call, ctx), + ), + GetBrain: withAuthUnary("/nomos.MobileApi/GetBrain", (_, ctx) => handleGetBrain(ctx)), + GetInbox: withAuthUnary("/nomos.MobileApi/GetInbox", (_, ctx) => handleGetInbox(ctx)), + GetToday: withAuthUnary("/nomos.MobileApi/GetToday", (_, ctx) => handleGetToday(ctx)), }; } @@ -515,43 +553,42 @@ async function handleActOnInboxItem( // ──────────── Skills ──────────── -async function handleListSkills(): Promise<{ - skills: Array<{ - name: string; - description: string; - source: string; - enabled: boolean; - certs: string[]; - price: string; - }>; -}> { - const skills = loadSkills().map((s) => ({ - name: s.name, - description: s.description ?? "", - source: s.source, - enabled: true, - certs: [] as string[], - price: "Free", - })); - return { skills }; +async function handleListSkills(): Promise<{ skills: ConsumerSkill[] }> { + const all = loadSkills(); + // Resolve each surfaced skill's persisted on/off (default on) before curating. + const enabled = new Map(); + for (const s of all) { + if (isConsumerSkill(s)) { + enabled.set(s.name, (await getConfigValue(`skill.${s.name}.enabled`)) ?? true); + } + } + return { skills: curateConsumerSkills(all, (name) => enabled.get(name) ?? true) }; } async function handleToggleSkill( call: grpc.ServerUnaryCall, ): Promise<{ success: boolean; message: string }> { - const db = getKysely(); - const key = `skill.${(call.request as any).name}.enabled`; - await db - .insertInto("config") - .values({ key, value: JSON.stringify((call.request as any).enabled) }) - .onConflict((oc) => - oc.column("key").doUpdateSet({ - value: JSON.stringify((call.request as any).enabled), - updated_at: new Date(), - }), - ) - .execute(); - return { success: true, message: (call.request as any).enabled ? "enabled" : "disabled" }; + const req = call.request as { name?: string; enabled?: boolean }; + if (!req.name) return { success: false, message: "missing_name" }; + // The client sends the friendly label; resolve it back to the raw skill name. + const name = resolveSkillName(loadSkills(), req.name); + await setConfigValue(`skill.${name}.enabled`, Boolean(req.enabled)); + return { success: true, message: req.enabled ? "enabled" : "disabled" }; +} + +/** Read-only list of the assistant's out-of-the-box capabilities. The Claude + * marketplace plugins are all developer tools, so consumers see this curated + * built-in set instead (marketplace install is a later iteration). */ +async function handleListPlugins(): Promise<{ + plugins: Array<{ name: string; description: string; marketplace: string }>; +}> { + return { + plugins: BUILTIN_TOOLS.map((t) => ({ + name: t.name, + description: t.description, + marketplace: "built-in", + })), + }; } // ──────────── Earnings (stub) ──────────── @@ -574,58 +611,170 @@ async function handleGetEarnings(): Promise<{ // ──────────── Settings ──────────── +// Catalog of consumer permissions + trust tiers. Labels/defaults are fixed; the +// actual on/off + tier mode are read back from the config table (where the +// UpdatePermission / UpdateTrustTier handlers persist them), so settings +// round-trip instead of returning literals. +const PERMISSION_DEFS = [ + { id: "p1", label: "Read emails", def: true }, + { id: "p2", label: "Draft replies", def: true }, + { id: "p3", label: "Send (with approval)", def: true }, + { id: "p4", label: "Send (auto)", def: false }, + { id: "p5", label: "Schedule meetings", def: true }, + { id: "p6", label: "Make purchases", def: false }, +] as const; + +const TRUST_TIER_DEFS = [ + { id: "friends", name: "Friends", description: "Always allowed", mode: "free", bondAmount: "" }, + { + id: "healthcare", + name: "Healthcare", + description: "Verified professionals", + mode: "free", + bondAmount: "", + }, + { + id: "brands", + name: "Brands", + description: "Min bid per impression", + mode: "bond", + bondAmount: "0.05", + }, + { + id: "unknown", + name: "Unknown", + description: "No identity = blocked", + mode: "blocked", + bondAmount: "", + }, +] as const; + async function handleGetSettings(ctx: TenantContext) { const integrations = await listIntegrationsForUser(ctx.userId); + + const permissions = await Promise.all( + PERMISSION_DEFS.map(async (p) => ({ + id: p.id, + label: p.label, + enabled: (await getConfigValue(`permission.${p.id}`)) ?? p.def, + })), + ); + + const trustTiers = await Promise.all( + TRUST_TIER_DEFS.map(async (t) => { + const stored = await getConfigValue<{ mode?: string; bondAmount?: string }>( + `trust_tier.${t.id}`, + ); + return { + id: t.id, + name: t.name, + description: t.description, + mode: stored?.mode ?? t.mode, + bondAmount: stored?.bondAmount ?? t.bondAmount, + }; + }), + ); + + // Usage: real message count for this user; plan/name from config (consumer + // onboarding sets these; earned/saved stay 0 until CATE bond receipts land). + const messageCount = await countUserMessages(ctx.userId); + const profile = { + name: (await getConfigValue("profile.name")) ?? "", + plan: (await getConfigValue("profile.plan")) ?? "Free", + messageCount, + earnedCents: 0, + savedCents: 0, + }; + + // Per-platform consent modes (so the app's picker reflects current state). + const consentModes = await listConsentModes(); + const consent = Object.entries(consentModes).map(([platform, mode]) => ({ platform, mode })); + + // Agent identity (name + voice/tone), and the consumer behavior toggles. + const identity = { + name: (await getConfigValue("agent.name")) ?? "Nomos", + voice: (await getConfigValue("agent.soul")) ?? "", + avatar: (await getConfigValue("agent.avatar")) ?? "", + }; + const appToggles = await Promise.all( + CONSUMER_TOGGLE_KEYS.map(async (key) => ({ + key, + enabled: (await getConfigValue(key)) ?? true, + })), + ); + + // Proactive agency: autonomy level + daily-briefing schedule. + const proactive = { + mode: (await getConfigValue("app.inboxAutonomy")) ?? "passive", + briefing: (await getConfigValue("app.briefingCron")) ?? "", + }; + return { - profile: { - name: "Nomos", - plan: "Pro", - messageCount: 0, - earnedCents: 0, - savedCents: 0, - }, - trustTiers: [ - { - id: "friends", - name: "Friends", - description: "Always allowed", - mode: "free", - bondAmount: "", - }, - { - id: "healthcare", - name: "Healthcare", - description: "Verified professionals", - mode: "free", - bondAmount: "", - }, - { - id: "brands", - name: "Brands", - description: "Min bid per impression", - mode: "bond", - bondAmount: "0.05", - }, - { - id: "unknown", - name: "Unknown", - description: "No identity = blocked", - mode: "blocked", - bondAmount: "", - }, - ], - permissions: [ - { id: "p1", label: "Read emails", enabled: true }, - { id: "p2", label: "Draft replies", enabled: true }, - { id: "p3", label: "Send (with approval)", enabled: true }, - { id: "p4", label: "Send (auto)", enabled: false }, - { id: "p5", label: "Schedule meetings", enabled: true }, - { id: "p6", label: "Make purchases", enabled: false }, - ], + profile, + trustTiers, + permissions, integrations, + consent, + identity, + appToggles, + proactive, }; } +/** App-config keys the mobile app may read/flip (consumer-safe bool toggles). */ +const CONSUMER_TOGGLE_KEYS = [ + "app.adaptiveMemory", + "app.commitmentTracking", + "app.styleMatching", +] as const; + +/** Consumer-safe string app-config keys (proactive scheduling, DM policy). */ +const CONSUMER_STRING_KEYS = [ + "app.inboxAutonomy", + "app.briefingCron", + "app.defaultDmPolicy", +] as const; + +async function handleUpdateAppSetting( + call: grpc.ServerUnaryCall, +): Promise<{ success: boolean; message: string }> { + const req = call.request as { key?: string; value?: string }; + if (req.key && (CONSUMER_TOGGLE_KEYS as readonly string[]).includes(req.key)) { + await setConfigValue(req.key, req.value === "true"); + return { success: true, message: "ok" }; + } + if (req.key && (CONSUMER_STRING_KEYS as readonly string[]).includes(req.key)) { + await setConfigValue(req.key, req.value ?? ""); + return { success: true, message: "ok" }; + } + return { success: false, message: "key_not_allowed" }; +} + +async function handleUpdateAgentIdentity( + call: grpc.ServerUnaryCall, +): Promise<{ success: boolean; message: string }> { + const req = call.request as { name?: string; voice?: string; avatar?: string }; + if (req.name !== undefined) await setConfigValue("agent.name", req.name); + if (req.voice !== undefined) await setConfigValue("agent.soul", req.voice); + if (req.avatar !== undefined) await setConfigValue("agent.avatar", req.avatar); + return { success: true, message: "ok" }; +} + +/** Count transcript messages belonging to this user (best-effort; 0 on error). */ +async function countUserMessages(userId: string): Promise { + try { + const db = getKysely(); + const row = await db + .selectFrom("transcript_messages") + .select((eb) => eb.fn.countAll().as("n")) + .where("user_id", "=", userId) + .executeTakeFirst(); + return row ? Number(row.n) : 0; + } catch { + return 0; + } +} + async function setConfigKey(key: string, value: unknown): Promise { const db = getKysely(); await db @@ -643,8 +792,16 @@ async function setConfigKey(key: string, value: unknown): Promise { async function handleUpdateConsent( call: grpc.ServerUnaryCall, ): Promise<{ success: boolean; message: string }> { - await setConfigKey(`consent.${(call.request as any).platform}`, (call.request as any).mode); - return { success: true, message: "ok" }; + const req = call.request as { platform?: string; mode?: string }; + if (!req.platform) return { success: false, message: "missing_platform" }; + try { + // Writes `consent.mode.` (what DraftManager reads) and validates + // against always_ask / auto_approve / notify_only. + await setConsentMode(req.platform, req.mode as ConsentMode); + return { success: true, message: "ok" }; + } catch (err) { + return { success: false, message: err instanceof Error ? err.message : "invalid_mode" }; + } } async function handleUpdateTrustTier( @@ -838,38 +995,30 @@ async function handleDeleteVaultNote( } // ──────────── Loops (autonomous recurring jobs) ──────────── -// Owner-scoped via the JWT-resolved user. System infra jobs are never mutable -// here (they belong to the daemon); these handlers run in the daemon process, so -// they emit cron:refresh directly to apply a change live. +// The instance runs its background loops under the synthetic `system` owner +// (see gateway.ts + proactive/scheduler.ts), so a hosted user owns none of them +// and a naive per-user query returns nothing. The consumer Loops page is an +// audit + control surface, so we ALSO surface a curated set of the always-on +// "managed" loops the assistant runs on the user's behalf -- under a friendly +// label, with a per-user enable/disable override. Those rows are permanently +// enabled, so the override (an AND-gate honored by cron-engine at fire time) can +// meaningfully turn them off without mutating the shared `system` row. Pure infra +// plumbing (wiki/graph/magic-docs/delta-sync) and the proactive family (gated by +// the Proactive setting) are hidden. User/agent-created loops show under their +// real name and toggle the row directly. -async function handleListLoops(ctx: TenantContext): Promise<{ - loops: Array<{ - id: string; - name: string; - schedule: string; - enabled: boolean; - source: string; - errorCount: number; - lastRun: string; - prompt: string; - }>; -}> { - const userId = resolveMemoryUserId(ctx.userId); - const jobs = await new CronStore().listJobs({ userId }); - return { - loops: jobs - .sort((a, b) => a.name.localeCompare(b.name)) - .map((j) => ({ - id: j.id, - name: j.name, - schedule: j.schedule, - enabled: j.enabled, - source: j.source ?? "system", - errorCount: j.errorCount, - lastRun: j.lastRun ? j.lastRun.toISOString() : "", - prompt: j.prompt, - })), - }; +async function handleListLoops(_ctx: TenantContext): Promise<{ loops: ConsumerLoop[] }> { + // Loops = the assistant's always-on background behaviors (owned by the `system` + // tenant). The user's own scheduled jobs live on the Tasks surface, not here. + const system = await new CronStore().listJobs({ userId: systemTenant().userId }); + + // Which managed loops the user has turned off (folded into `enabled`). + const optedOut = new Set(); + for (const j of system) { + if (MANAGED_LOOPS[j.name] && (await isLoopUserDisabled(j.name))) optedOut.add(j.name); + } + + return { loops: curateConsumerLoops(system, optedOut) }; } async function handleSetLoopEnabled( @@ -878,6 +1027,17 @@ async function handleSetLoopEnabled( ): Promise<{ success: boolean; message: string }> { const req = call.request as { name?: string; enabled?: boolean }; if (!req.name) return { success: false, message: "missing_name" }; + + // Managed loop: the client sends the friendly label. Persist a per-user + // override (honored by cron-engine at fire time) instead of mutating the + // shared `system` row. + const managedName = MANAGED_LABEL_TO_NAME.get(req.name); + if (managedName) { + await setLoopUserEnabled(managedName, Boolean(req.enabled)); + process.emit("cron:refresh" as never); + return { success: true, message: req.enabled ? "enabled" : "disabled" }; + } + const userId = resolveMemoryUserId(ctx.userId); const store = new CronStore(); const job = await store.getJobByName(req.name); @@ -904,6 +1064,96 @@ async function handleDeleteLoop( return { success: true, message: "deleted" }; } +// ──────────── Tasks (the user's scheduled tasks) ──────────── +// Owner-scoped by user_id: a per-user query never returns the instance's +// `system`-owned background loops, so Tasks and Loops stay cleanly separate. +// Update/Delete additionally assert ownership before mutating. + +async function handleListTasks(ctx: TenantContext): Promise<{ tasks: ConsumerTask[] }> { + const userId = resolveMemoryUserId(ctx.userId); + const jobs = await new CronStore().listJobs({ userId }); + return { tasks: curateConsumerTasks(jobs) }; +} + +async function handleUpdateTask( + call: grpc.ServerUnaryCall, + ctx: TenantContext, +): Promise<{ success: boolean; message: string }> { + const req = call.request as { + id?: string; + name?: string; + prompt?: string; + schedule?: string; + scheduleType?: string; + enabled?: boolean; + }; + if (!req.id) return { success: false, message: "missing_id" }; + const userId = resolveMemoryUserId(ctx.userId); + const store = new CronStore(); + const job = await store.getJob(req.id); + if (!job || job.userId !== userId) return { success: false, message: "task_not_found" }; + + // Full-state update from the editor; empty name/schedule are ignored so a + // toggle-only call (which still sends the whole proto) never blanks a field. + const updates: CronJobUpdate = { enabled: Boolean(req.enabled) }; + if (req.name?.trim()) updates.name = req.name.trim(); + if (req.prompt?.trim()) updates.prompt = req.prompt; + if (req.schedule?.trim()) { + updates.schedule = req.schedule.trim(); + updates.scheduleType = (req.scheduleType as ScheduleType) || job.scheduleType; + } + await store.updateJob(job.id, updates); + process.emit("cron:refresh" as never); + return { success: true, message: "updated" }; +} + +async function handleDeleteTask( + call: grpc.ServerUnaryCall, + ctx: TenantContext, +): Promise<{ success: boolean; message: string }> { + const req = call.request as { id?: string }; + if (!req.id) return { success: false, message: "missing_id" }; + const userId = resolveMemoryUserId(ctx.userId); + const store = new CronStore(); + const job = await store.getJob(req.id); + if (!job || job.userId !== userId) return { success: false, message: "task_not_found" }; + await store.deleteJob(job.id); + process.emit("cron:refresh" as never); + return { success: true, message: "deleted" }; +} + +// ──────────── Brain (knowledge graph + learned facts) ──────────── + +async function handleGetBrain(ctx: TenantContext): Promise<{ + nodes: Array<{ + id: string; + label: string; + kind: string; + summary: string; + degree: number; + confidence: number; + }>; + edges: Array<{ src: string; dst: string; relation: string }>; + facts: Array<{ text: string; source: string; confidence: number; learnedAt: string }>; + entityCount: number; + factCount: number; +}> { + // The graph + user_model are already owner-scoped by the TenantContext. + const overview = await getBrainOverview({ + orgId: ctx.orgId, + userId: resolveMemoryUserId(ctx.userId), + }); + return overview; +} + +async function handleGetInbox(ctx: TenantContext) { + return getInboxOverview({ orgId: ctx.orgId, userId: resolveMemoryUserId(ctx.userId) }); +} + +async function handleGetToday(ctx: TenantContext) { + return getTodayOverview({ orgId: ctx.orgId, userId: resolveMemoryUserId(ctx.userId) }); +} + // Helpers async function listIntegrationsForUser(userId: string) { const all = await listIntegrations(); diff --git a/src/daemon/today.ts b/src/daemon/today.ts new file mode 100644 index 00000000..34c90711 --- /dev/null +++ b/src/daemon/today.ts @@ -0,0 +1,126 @@ +/** + * Today overview -- the read model behind MobileApi.GetToday. + * + * Composes the day's brief from: today's Google Calendar events (live, best-effort + * -- empty when Google isn't connected), pending commitments, and the user's + * scheduled tasks. Gated on the daily briefing: when proactive autonomy is off, + * `briefingEnabled` is false and the client shows a deep-link to enable it. + */ + +import type { TenantContext } from "../auth/tenant-context.ts"; +import { getConfigValue } from "../db/config.ts"; +import { getPendingCommitments } from "../proactive/commitment-tracker.ts"; +import { CronStore } from "../cron/store.ts"; +import { curateConsumerTasks } from "../cron/task-view.ts"; +import { gapiFetch } from "../sdk/google-rest-mcp.ts"; +import { createLogger } from "../lib/logger.ts"; + +const log = createLogger("today"); +const CALENDAR_API = "https://www.googleapis.com/calendar/v3"; + +export interface TodayEvent { + time: string; + title: string; + meta: string; +} +export interface TodayCommitment { + id: string; + description: string; + due: string; +} +export interface TodayTask { + id: string; + name: string; + schedule: string; +} +export interface TodayOverview { + briefingEnabled: boolean; + events: TodayEvent[]; + commitments: TodayCommitment[]; + tasks: TodayTask[]; +} + +export async function getTodayOverview(ctx: TenantContext): Promise { + const userId = ctx.userId; + // The Today brief is the in-app face of the daily briefing; it's "on" whenever + // proactive autonomy is on (default passive). Off -> the client shows the CTA. + const mode = (await getConfigValue("app.inboxAutonomy")) ?? "passive"; + const briefingEnabled = mode !== "off"; + + const [events, commitmentRows, jobs] = await Promise.all([ + fetchTodayEvents(userId), + getPendingCommitments(userId).catch(() => []), + new CronStore().listJobs({ userId }), + ]); + + const commitments: TodayCommitment[] = commitmentRows.slice(0, 8).map((c) => ({ + id: c.id, + description: c.description, + due: c.deadline ? relativeDay(c.deadline) : "", + })); + + const tasks: TodayTask[] = curateConsumerTasks(jobs) + .filter((t) => t.enabled) + .slice(0, 6) + .map((t) => ({ id: t.id, name: t.name, schedule: t.displaySchedule })); + + return { briefingEnabled, events, commitments, tasks }; +} + +async function fetchTodayEvents(userId: string): Promise { + try { + const start = new Date(); + start.setHours(0, 0, 0, 0); + const end = new Date(); + end.setHours(23, 59, 59, 999); + const data = (await gapiFetch({ + userId, + method: "GET", + url: `${CALENDAR_API}/calendars/primary/events`, + query: { + timeMin: start.toISOString(), + timeMax: end.toISOString(), + singleEvents: true, + orderBy: "startTime", + maxResults: 12, + }, + })) as { + items?: Array<{ + summary?: string; + location?: string; + start?: { dateTime?: string; date?: string }; + }>; + }; + return (data.items ?? []).map((e) => ({ + time: formatEventTime(e.start), + title: e.summary ?? "(busy)", + meta: e.location ?? "", + })); + } catch (err) { + // No connected Google account / revoked token -> no calendar section. + log.debug({ err: err instanceof Error ? err.message : err }, "today: no calendar events"); + return []; + } +} + +function formatEventTime(start?: { dateTime?: string; date?: string }): string { + if (start?.date) return "All day"; + if (!start?.dateTime) return ""; + return new Date(start.dateTime).toLocaleTimeString("en-US", { + hour: "numeric", + minute: "2-digit", + }); +} + +function relativeDay(deadline: Date): string { + const dayMs = 86_400_000; + const d0 = new Date(deadline); + d0.setHours(0, 0, 0, 0); + const today = new Date(); + today.setHours(0, 0, 0, 0); + const diff = Math.round((d0.getTime() - today.getTime()) / dayMs); + if (diff < 0) return "Overdue"; + if (diff === 0) return "Today"; + if (diff === 1) return "Tomorrow"; + return new Date(deadline).toLocaleDateString("en-US", { month: "short", day: "numeric" }); +} diff --git a/src/memory/brain.ts b/src/memory/brain.ts new file mode 100644 index 00000000..3bfd1dac --- /dev/null +++ b/src/memory/brain.ts @@ -0,0 +1,107 @@ +/** + * Brain overview -- the read model behind MobileApi.GetBrain. + * + * Composes the consumer Brain page from real per-user memory: the knowledge + * graph (kg_nodes / kg_edges, via getProjection) for the map + entities, and the + * accumulated user_model for the "recently learned" facts feed. Owner-scoped via + * the TenantContext that every query already threads. + */ + +import type { TenantContext } from "../auth/tenant-context.ts"; +import { getProjection } from "./graph.ts"; +import { getUserModel, type UserModelEntry } from "../db/user-model.ts"; +import { getKysely } from "../db/client.ts"; + +export interface BrainNodeView { + id: string; + label: string; + kind: string; // person | org | topic | decision | project | value | event | wiki | vault | ... + summary: string; + degree: number; + confidence: number; +} + +export interface BrainEdgeView { + src: string; + dst: string; + relation: string; +} + +export interface BrainFactView { + text: string; + source: string; + confidence: number; // 0..3 (binned from the 0..1 model confidence) + learnedAt: string; // ISO-8601 +} + +export interface BrainOverview { + nodes: BrainNodeView[]; + edges: BrainEdgeView[]; + facts: BrainFactView[]; + entityCount: number; + factCount: number; +} + +function factText(e: UserModelEntry): string { + const v = e.value; + if (typeof v === "string") return v; + if (v == null) return e.key; + if (typeof v === "object") return `${e.key}: ${JSON.stringify(v)}`; + return `${e.key}: ${String(v)}`; +} + +export async function getBrainOverview( + ctx: TenantContext, + opts: { nodeLimit?: number; factLimit?: number } = {}, +): Promise { + const nodeLimit = opts.nodeLimit ?? 48; + const factLimit = opts.factLimit ?? 12; + + // Map: the most-recent slice of the graph + the edges within it. + const sub = await getProjection(ctx, { limit: nodeLimit }); + + const degree = new Map(); + for (const e of sub.edges) { + degree.set(e.srcId, (degree.get(e.srcId) ?? 0) + 1); + degree.set(e.dstId, (degree.get(e.dstId) ?? 0) + 1); + } + + const nodes: BrainNodeView[] = sub.nodes.map((n) => ({ + id: n.id, + label: n.name, + kind: n.kind, + summary: n.summary ?? "", + degree: degree.get(n.id) ?? 0, + confidence: n.confidence, + })); + + const edges: BrainEdgeView[] = sub.edges.map((e) => ({ + src: e.srcId, + dst: e.dstId, + relation: e.relType.replace(/_/g, " "), + })); + + // Facts: the accumulated user model (already ordered confidence desc, recent). + const model = await getUserModel(ctx.userId); + const facts: BrainFactView[] = model.slice(0, factLimit).map((e) => ({ + text: factText(e), + source: e.category, + confidence: Math.max(0, Math.min(3, Math.round((e.confidence ?? 0.5) * 3))), + learnedAt: e.updatedAt ? new Date(e.updatedAt).toISOString() : "", + })); + + const db = getKysely(); + const counted = await db + .selectFrom("kg_nodes") + .select((eb) => eb.fn.countAll().as("c")) + .where("user_id", "=", ctx.userId) + .executeTakeFirst(); + + return { + nodes, + edges, + facts, + entityCount: Number(counted?.c ?? nodes.length), + factCount: model.length, + }; +} diff --git a/src/plugins/builtin-tools.ts b/src/plugins/builtin-tools.ts new file mode 100644 index 00000000..d496351a --- /dev/null +++ b/src/plugins/builtin-tools.ts @@ -0,0 +1,26 @@ +/** + * The assistant's out-of-the-box capabilities, surfaced read-only in the + * consumer "Built-in tools" page (Advanced). + * + * The Claude marketplace plugins (loadInstalledPlugins) are all developer tools + * (code-review, terraform, mcp-server-dev, ...), so they are not shown to + * consumers. Instead this curated list communicates what the assistant can do + * out of the box, distinct from the user-facing Skills. A real consumer + * marketplace is a later iteration. + */ + +export interface BuiltinTool { + name: string; + description: string; +} + +export const BUILTIN_TOOLS: readonly BuiltinTool[] = [ + { name: "Web search", description: "Searches the web for current information." }, + { name: "Web browser", description: "Opens and reads websites to get things done." }, + { + name: "Long-term memory", + description: "Remembers facts, preferences, and past conversations.", + }, + { name: "File reading & writing", description: "Reads and creates documents and files." }, + { name: "Image generation", description: "Generates images from a description." }, +]; diff --git a/src/sdk/tools.ts b/src/sdk/tools.ts index d9eb5b82..84b8b23a 100644 --- a/src/sdk/tools.ts +++ b/src/sdk/tools.ts @@ -623,6 +623,7 @@ export function createMemoryMcpServer(userId: string = "local"): McpSdkServerCon channelId, enabled: true, errorCount: 0, + source: "agent", // a task the agent scheduled on the user's behalf (not infra) }); // Notify cron engine to refresh (if running in daemon) diff --git a/src/skills/skill-view.test.ts b/src/skills/skill-view.test.ts new file mode 100644 index 00000000..1c11deb5 --- /dev/null +++ b/src/skills/skill-view.test.ts @@ -0,0 +1,89 @@ +import { describe, it, expect } from "vitest"; +import { curateConsumerSkills, resolveSkillName, isConsumerSkill } from "./skill-view.ts"; +import type { Skill } from "./types.ts"; + +function skill(name: string, source: string, description = ""): Skill { + return { name, description, content: "", filePath: `/x/${name}/SKILL.md`, source }; +} + +// Mirrors the real hosted catalog: operator external (Google) + bundled consumer +// + bundled dev/internal/channel skills that must be hidden. +const ALL: Skill[] = [ + skill( + "google-calendar-meeting-prep", + "external", + "Build a practical meeting prep brief from a connected Google Calendar that is long enough to need truncation.", + ), + skill("gmail-inbox-triage", "external", "Triage a Gmail inbox into actionable buckets."), + skill("google-drive", "external", "Find, read, and organize files in Google Drive."), + skill("pdf", "bundled", "Work with PDF files."), + skill("xlsx", "bundled", "Read and write spreadsheets."), + skill("run-evals", "bundled", "Run the Nomos eval suite."), + skill("self-improve", "bundled", "Clone the repo and improve the code."), + skill("skill-creator", "bundled", "Create new skills."), + skill("slack", "bundled", "Interact with Slack workspaces."), +]; + +describe("isConsumerSkill", () => { + it("accepts external + allowlisted bundled, rejects dev/internal/channel", () => { + expect(isConsumerSkill(skill("google-drive", "external"))).toBe(true); + expect(isConsumerSkill(skill("pdf", "bundled"))).toBe(true); + expect(isConsumerSkill(skill("run-evals", "bundled"))).toBe(false); + expect(isConsumerSkill(skill("slack", "bundled"))).toBe(false); + expect(isConsumerSkill(skill("skill-creator", "bundled"))).toBe(false); + }); +}); + +describe("curateConsumerSkills", () => { + it("surfaces only consumer skills, under friendly labels", () => { + const names = curateConsumerSkills(ALL, () => true).map((s) => s.name); + expect(names).toEqual(["Drive", "Inbox triage", "Meeting prep", "PDF tools", "Spreadsheets"]); + }); + + it("hides every dev/internal/channel skill", () => { + const out = curateConsumerSkills(ALL, () => true); + for (const raw of ["run-evals", "self-improve", "skill-creator", "slack"]) { + expect(out.some((s) => resolveSkillName(ALL, s.name) === raw)).toBe(false); + } + }); + + it("badges google skills 'google' and bundled consumer skills 'built-in'", () => { + const out = curateConsumerSkills(ALL, () => true); + expect(out.find((s) => s.name === "Drive")?.source).toBe("google"); + expect(out.find((s) => s.name === "PDF tools")?.source).toBe("built-in"); + }); + + it("folds the persisted enabled state in (default on)", () => { + const off = new Set(["pdf"]); + const out = curateConsumerSkills(ALL, (n) => !off.has(n)); + expect(out.find((s) => s.name === "PDF tools")?.enabled).toBe(false); + expect(out.find((s) => s.name === "Drive")?.enabled).toBe(true); + }); + + it("truncates long descriptions", () => { + const mp = curateConsumerSkills(ALL, () => true).find((s) => s.name === "Meeting prep"); + expect(mp!.description.length).toBeLessThanOrEqual(88); + expect(mp!.description.endsWith("...")).toBe(true); + }); + + it("sanitizes em dashes out of consumer-facing descriptions", () => { + const out = curateConsumerSkills( + [skill("weather", "bundled", "Forecasts — no API key needed.")], + () => true, + ); + expect(out[0].description).not.toContain("—"); + expect(out[0].description).toBe("Forecasts - no API key needed."); + }); +}); + +describe("resolveSkillName", () => { + it("round-trips a friendly label back to the raw skill name for toggling", () => { + expect(resolveSkillName(ALL, "Meeting prep")).toBe("google-calendar-meeting-prep"); + expect(resolveSkillName(ALL, "PDF tools")).toBe("pdf"); + expect(resolveSkillName(ALL, "Drive")).toBe("google-drive"); + }); + + it("falls back to the input when no friendly label matches", () => { + expect(resolveSkillName(ALL, "already-raw")).toBe("already-raw"); + }); +}); diff --git a/src/skills/skill-view.ts b/src/skills/skill-view.ts new file mode 100644 index 00000000..9fa1f75d --- /dev/null +++ b/src/skills/skill-view.ts @@ -0,0 +1,111 @@ +/** + * Consumer Skills view model -- the pure shaping behind MobileApi.ListSkills. + * + * loadSkills() returns the full power-user catalog: bundled dev/internal skills + * (run-evals, self-improve, skill-creator, ...), channel adapters, AND the + * operator-curated external skills (NOMOS_SKILLS_DIR). A consumer should only + * see the genuinely user-facing ones, under friendly labels. Pure + + * dependency-free so it is unit-testable in isolation. + */ + +import type { Skill } from "./types.ts"; + +export interface ConsumerSkill { + /** Friendly label. Also the toggle round-trip key (resolved back server-side). */ + name: string; + description: string; + /** Display badge: google | built-in | add-on. */ + source: string; + enabled: boolean; + certs: string[]; + price: string; +} + +/** Bundled skills appropriate for a consumer. Everything else bundled is + * dev/internal/channel tooling and is hidden. Operator-curated external skills + * (source="external") are always surfaced. */ +export const CONSUMER_BUNDLED_SKILLS = new Set([ + "pdf", + "docx", + "pptx", + "xlsx", + "weather", + "doc-coauthoring", + "internal-comms", +]); + +/** raw skill name -> friendly label. Covers every surfaced skill so both the + * display and the toggle round-trip are deterministic. */ +export const SKILL_LABELS: Record = { + // Operator-curated Google Workspace skills (external). + "gmail-inbox-triage": "Inbox triage", + "google-gmail": "Gmail", + "google-calendar": "Calendar", + "google-calendar-daily-brief": "Daily calendar brief", + "google-calendar-free-up-time": "Free up time", + "google-calendar-group-scheduler": "Group scheduler", + "google-calendar-meeting-prep": "Meeting prep", + "google-drive": "Drive", + // Consumer bundled skills. + pdf: "PDF tools", + docx: "Word documents", + pptx: "Presentations", + xlsx: "Spreadsheets", + weather: "Weather", + "doc-coauthoring": "Document co-authoring", + "internal-comms": "Writing assistant", +}; + +function titleCase(s: string): string { + return s + .split(/[-_]/) + .map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w)) + .join(" "); +} + +export function friendlySkillName(name: string): string { + return SKILL_LABELS[name] ?? titleCase(name); +} + +function skillBadge(s: Skill): string { + if (/gmail|google|calendar|drive|gws/i.test(s.name)) return "google"; + return s.source === "external" ? "add-on" : "built-in"; +} + +function consumerDescription(s: Skill): string { + // Sanitize author-written copy for the consumer UI (em dashes -> hyphens). + const d = (s.description ?? "").replace(/\s*—\s*/g, " - ").trim(); + return d.length > 88 ? `${d.slice(0, 85).trimEnd()}...` : d; +} + +export function isConsumerSkill(s: Skill): boolean { + return s.source === "external" || CONSUMER_BUNDLED_SKILLS.has(s.name); +} + +/** + * Curate the consumer Skills list: filter to consumer-facing skills, friendly + * labels + badges, with the user's enable/disable state folded in. + * `enabledOf(name)` resolves the persisted toggle (default true). + */ +export function curateConsumerSkills( + skills: Skill[], + enabledOf: (name: string) => boolean, +): ConsumerSkill[] { + return skills + .filter(isConsumerSkill) + .map((s) => ({ + name: friendlySkillName(s.name), + description: consumerDescription(s), + source: skillBadge(s), + enabled: enabledOf(s.name), + certs: [] as string[], + price: "", + })) + .sort((a, b) => a.name.localeCompare(b.name)); +} + +/** Resolve a friendly label back to the raw skill name for the toggle round-trip. + * Falls back to the label itself (already a raw name) when no match. */ +export function resolveSkillName(skills: Skill[], label: string): string { + return skills.find((s) => friendlySkillName(s.name) === label)?.name ?? label; +} From cb25f7b63bbbd511f4a777d34baf624269c5b0d9 Mon Sep 17 00:00:00 2001 From: meidad Date: Tue, 16 Jun 2026 21:37:23 -0700 Subject: [PATCH 2/2] chore: oxfmt the regenerated nomos_pb.ts (post-codegen format) Co-Authored-By: Claude Opus 4.8 (1M context) --- src/gen/nomos_pb.ts | 634 +++++++++++++++++++++++++------------------- 1 file changed, 358 insertions(+), 276 deletions(-) diff --git a/src/gen/nomos_pb.ts b/src/gen/nomos_pb.ts index 1597f9bd..53fd9cd8 100644 --- a/src/gen/nomos_pb.ts +++ b/src/gen/nomos_pb.ts @@ -9,21 +9,20 @@ import type { Message } from "@bufbuild/protobuf"; /** * Describes the file nomos.proto. */ -export const file_nomos: GenFile = /*@__PURE__*/ - fileDesc("Cgtub21vcy5wcm90bxIFbm9tb3MiBwoFRW1wdHkijgEKCExvb3BJbmZvEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEAoIc2NoZWR1bGUYAyABKAkSDwoHZW5hYmxlZBgEIAEoCBIOCgZzb3VyY2UYBSABKAkSEwoLZXJyb3JfY291bnQYBiABKAUSEAoIbGFzdF9ydW4YByABKAkSDgoGcHJvbXB0GAggASgJIioKCExvb3BMaXN0Eh4KBWxvb3BzGAEgAygLMg8ubm9tb3MuTG9vcEluZm8iNgoVU2V0TG9vcEVuYWJsZWRSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHZW5hYmxlZBgCIAEoCCIhChFMb29wRGVsZXRlUmVxdWVzdBIMCgRuYW1lGAEgASgJIjYKEkxvb3BBY3Rpb25SZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiMwoLQ2hhdFJlcXVlc3QSDwoHY29udGVudBgBIAEoCRITCgtzZXNzaW9uX2tleRgCIAEoCSIwCgpBZ2VudEV2ZW50EgwKBHR5cGUYASABKAkSFAoManNvbl9wYXlsb2FkGAIgASgJIjYKDkNvbW1hbmRSZXF1ZXN0Eg8KB2NvbW1hbmQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkiMwoPQ29tbWFuZFJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSJPCg5TdGF0dXNSZXNwb25zZRIPCgdydW5uaW5nGAEgASgIEhkKEWNvbm5lY3RlZF9jbGllbnRzGAIgASgFEhEKCXBsYXRmb3JtcxgDIAMoCSIlCg5TZXNzaW9uUmVxdWVzdBITCgtzZXNzaW9uX2tleRgBIAEoCSJVCg9TZXNzaW9uUmVzcG9uc2USCgoCaWQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkSDQoFbW9kZWwYAyABKAkSEgoKY3JlYXRlZF9hdBgEIAEoCSI3CgtTZXNzaW9uTGlzdBIoCghzZXNzaW9ucxgBIAMoCzIWLm5vbW9zLlNlc3Npb25SZXNwb25zZSIfCgtEcmFmdEFjdGlvbhIQCghkcmFmdF9pZBgBIAEoCSIxCg1EcmFmdFJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSItCglEcmFmdExpc3QSIAoGZHJhZnRzGAEgAygLMhAubm9tb3MuRHJhZnRJdGVtInIKCURyYWZ0SXRlbRIKCgJpZBgBIAEoCRIPCgdjb250ZW50GAIgASgJEhAKCHBsYXRmb3JtGAMgASgJEhIKCmNoYW5uZWxfaWQYBCABKAkSDgoGc3RhdHVzGAUgASgJEhIKCmNyZWF0ZWRfYXQYBiABKAkiIQoMUG9uZ1Jlc3BvbnNlEhEKCXRpbWVzdGFtcBgBIAEoAyKLAQoFTUxvb3ASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIQCghzY2hlZHVsZRgDIAEoCRIPCgdlbmFibGVkGAQgASgIEg4KBnNvdXJjZRgFIAEoCRITCgtlcnJvcl9jb3VudBgGIAEoBRIQCghsYXN0X3J1bhgHIAEoCRIOCgZwcm9tcHQYCCABKAkiLQoOTUxvb3BzUmVzcG9uc2USGwoFbG9vcHMYASADKAsyDC5ub21vcy5NTG9vcCI3ChZNU2V0TG9vcEVuYWJsZWRSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHZW5hYmxlZBgCIAEoCCIiChJNTG9vcERlbGV0ZVJlcXVlc3QSDAoEbmFtZRgBIAEoCSKnAQoFTVRhc2sSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIOCgZwcm9tcHQYAyABKAkSEAoIc2NoZWR1bGUYBCABKAkSFQoNc2NoZWR1bGVfdHlwZRgFIAEoCRIYChBkaXNwbGF5X3NjaGVkdWxlGAYgASgJEg8KB2VuYWJsZWQYByABKAgSDgoGc291cmNlGAggASgJEhAKCGxhc3RfcnVuGAkgASgJIi0KDk1UYXNrc1Jlc3BvbnNlEhsKBXRhc2tzGAEgAygLMgwubm9tb3MuTVRhc2sieAoSTVRhc2tVcGRhdGVSZXF1ZXN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDgoGcHJvbXB0GAMgASgJEhAKCHNjaGVkdWxlGAQgASgJEhUKDXNjaGVkdWxlX3R5cGUYBSABKAkSDwoHZW5hYmxlZBgGIAEoCCIgChJNVGFza0RlbGV0ZVJlcXVlc3QSCgoCaWQYASABKAkiagoKTUJyYWluTm9kZRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSDgoGZGVncmVlGAUgASgFEhIKCmNvbmZpZGVuY2UYBiABKAEiOAoKTUJyYWluRWRnZRILCgNzcmMYASABKAkSCwoDZHN0GAIgASgJEhAKCHJlbGF0aW9uGAMgASgJIlIKCk1CcmFpbkZhY3QSDAoEdGV4dBgBIAEoCRIOCgZzb3VyY2UYAiABKAkSEgoKY29uZmlkZW5jZRgDIAEoBRISCgpsZWFybmVkX2F0GAQgASgJIqABCg5NQnJhaW5SZXNwb25zZRIgCgVub2RlcxgBIAMoCzIRLm5vbW9zLk1CcmFpbk5vZGUSIAoFZWRnZXMYAiADKAsyES5ub21vcy5NQnJhaW5FZGdlEiAKBWZhY3RzGAMgAygLMhEubm9tb3MuTUJyYWluRmFjdBIUCgxlbnRpdHlfY291bnQYBCABKAUSEgoKZmFjdF9jb3VudBgFIAEoBSJzCgtNSW5ib3hEcmFmdBIKCgJpZBgBIAEoCRIRCglyZWNpcGllbnQYAiABKAkSDwoHcHJldmlldxgDIAEoCRIOCgZzdGF0dXMYBCABKAkSEAoIcGxhdGZvcm0YBSABKAkSEgoKY3JlYXRlZF9hdBgGIAEoCSJ6CgpNSW5ib3hDYXRlEgoKAmlkGAEgASgJEhIKCmZyb21fbGFiZWwYAiABKAkSEgoKdHJ1c3RfdGllchgDIAEoCRIPCgdzdWJqZWN0GAQgASgJEhMKC2JvbmRfYW1vdW50GAUgASgJEhIKCmNyZWF0ZWRfYXQYBiABKAkibwoRTUdldEluYm94UmVzcG9uc2USIgoGZHJhZnRzGAEgAygLMhIubm9tb3MuTUluYm94RHJhZnQSHwoEY2F0ZRgCIAMoCzIRLm5vbW9zLk1JbmJveENhdGUSFQoNYmxvY2tlZF9jb3VudBgDIAEoBSI4CgtNVG9kYXlFdmVudBIMCgR0aW1lGAEgASgJEg0KBXRpdGxlGAIgASgJEgwKBG1ldGEYAyABKAkiQAoQTVRvZGF5Q29tbWl0bWVudBIKCgJpZBgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRILCgNkdWUYAyABKAkiOAoKTVRvZGF5VGFzaxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCHNjaGVkdWxlGAMgASgJIp4BCg5NVG9kYXlSZXNwb25zZRIYChBicmllZmluZ19lbmFibGVkGAEgASgIEiIKBmV2ZW50cxgCIAMoCzISLm5vbW9zLk1Ub2RheUV2ZW50EiwKC2NvbW1pdG1lbnRzGAMgAygLMhcubm9tb3MuTVRvZGF5Q29tbWl0bWVudBIgCgV0YXNrcxgEIAMoCzIRLm5vbW9zLk1Ub2RheVRhc2siKAoETUFjaxIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiIwoRTVZhdWx0TGlzdFJlcXVlc3QSDgoGcHJlZml4GAEgASgJIkQKEU1WYXVsdE5vdGVTdW1tYXJ5EgwKBHBhdGgYASABKAkSDQoFdGl0bGUYAiABKAkSEgoKdXBkYXRlZF9hdBgDIAEoCSI9ChJNVmF1bHRMaXN0UmVzcG9uc2USJwoFbm90ZXMYASADKAsyGC5ub21vcy5NVmF1bHROb3RlU3VtbWFyeSIgChBNVmF1bHRHZXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiXgoKTVZhdWx0Tm90ZRIMCgRwYXRoGAEgASgJEg0KBXRpdGxlGAIgASgJEg8KB2NvbnRlbnQYAyABKAkSEgoKdXBkYXRlZF9hdBgEIAEoCRIOCgZleGlzdHMYBSABKAgiQgoSTVZhdWx0V3JpdGVSZXF1ZXN0EgwKBHBhdGgYASABKAkSDwoHY29udGVudBgCIAEoCRINCgV0aXRsZRgDIAEoCSIjChNNVmF1bHREZWxldGVSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMTUNoYXRSZXF1ZXN0Eg8KB2NvbnRlbnQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkiMAoKTUNoYXRFdmVudBIMCgR0eXBlGAEgASgJEhQKDGpzb25fcGF5bG9hZBgCIAEoCSJMChNNR2V0TWVzc2FnZXNSZXF1ZXN0EhMKC3Nlc3Npb25fa2V5GAEgASgJEg0KBWxpbWl0GAIgASgFEhEKCWJlZm9yZV9pZBgDIAEoCSJJCghNTWVzc2FnZRIKCgJpZBgBIAEoCRIMCgRyb2xlGAIgASgJEg8KB2NvbnRlbnQYAyABKAkSEgoKY3JlYXRlZF9hdBgEIAEoCSI5ChRNR2V0TWVzc2FnZXNSZXNwb25zZRIhCghtZXNzYWdlcxgBIAMoCzIPLm5vbW9zLk1NZXNzYWdlIiAKDE1EcmFmdEFjdGlvbhIQCghkcmFmdF9pZBgBIAEoCSI9ChRNRHJhZnRBY3Rpb25XaXRoRWRpdBIQCghkcmFmdF9pZBgBIAEoCRITCgtlZGl0ZWRfdGV4dBgCIAEoCSI4ChRNRHJhZnRBY3Rpb25SZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiLgoNTUluYm94UmVxdWVzdBIOCgZzdGF0dXMYASABKAkSDQoFbGltaXQYAiABKAUimAEKCk1JbmJveEl0ZW0SCgoCaWQYASABKAkSEgoKZnJvbV9sYWJlbBgCIAEoCRISCgp0cnVzdF90aWVyGAMgASgJEg8KB3N1YmplY3QYBCABKAkSDAoEdGltZRgFIAEoCRITCgtib25kX2Ftb3VudBgGIAEoCRIOCgZ1bnJlYWQYByABKAgSEgoKY3JlYXRlZF9hdBgIIAEoCSJJCg5NSW5ib3hSZXNwb25zZRIgCgVpdGVtcxgBIAMoCzIRLm5vbW9zLk1JbmJveEl0ZW0SFQoNYmxvY2tlZF9jb3VudBgCIAEoBSIkChBNRW52ZWxvcGVSZXF1ZXN0EhAKCGluYm94X2lkGAEgASgJIo0BCg1NQ2F0ZUVudmVsb3BlEgsKA2RpZBgBIAEoCRISCgp0cnVzdF90aWVyGAIgASgJEg4KBmludGVudBgDIAEoCRIVCg1jb25zZW50X2dyYW50GAQgASgJEg0KBXN0YW1wGAUgASgJEhMKC2JvbmRfYW1vdW50GAYgASgJEhAKCHJhd19qc29uGAcgASgJIjcKE01JbmJveEFjdGlvblJlcXVlc3QSEAoIaW5ib3hfaWQYASABKAkSDgoGYWN0aW9uGAIgASgJIjgKFE1JbmJveEFjdGlvblJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSJqCgZNU2tpbGwSDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIOCgZzb3VyY2UYAyABKAkSDwoHZW5hYmxlZBgEIAEoCBINCgVjZXJ0cxgFIAMoCRINCgVwcmljZRgGIAEoCSIwCg9NU2tpbGxzUmVzcG9uc2USHQoGc2tpbGxzGAEgAygLMg0ubm9tb3MuTVNraWxsIkEKB01QbHVnaW4SDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRITCgttYXJrZXRwbGFjZRgDIAEoCSIzChBNUGx1Z2luc1Jlc3BvbnNlEh8KB3BsdWdpbnMYASADKAsyDi5ub21vcy5NUGx1Z2luIjQKE01Ta2lsbFRvZ2dsZVJlcXVlc3QSDAoEbmFtZRgBIAEoCRIPCgdlbmFibGVkGAIgASgIIjgKFE1Ta2lsbFRvZ2dsZVJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSIiChBNRWFybmluZ3NSZXF1ZXN0Eg4KBnBlcmlvZBgBIAEoCSKKAQoRTUVhcm5pbmdzUmVzcG9uc2USGQoRdGhpc19wZXJpb2RfY2VudHMYASABKAMSEwoLYm9uZHNfY291bnQYAiABKAMSFgoOYXZnX2JvbmRfY2VudHMYAyABKAMSFwoPYWNjZXB0X3JhdGVfcGN0GAQgASgFEhQKDHNlcmllc19jZW50cxgFIAMoAyItCg1NR3JhcGhSZXF1ZXN0Eg0KBWtpbmRzGAEgAygJEg0KBWxpbWl0GAIgASgFIl4KFk1HcmFwaE5laWdoYm9yc1JlcXVlc3QSDwoHbm9kZV9pZBgBIAEoCRINCgVkZXB0aBgCIAEoBRIRCglyZWxfdHlwZXMYAyADKAkSEQoJZGlyZWN0aW9uGAQgASgJIjMKE01HcmFwaFNlYXJjaFJlcXVlc3QSDQoFcXVlcnkYASABKAkSDQoFbGltaXQYAiABKAUilwEKCk1HcmFwaE5vZGUSCgoCaWQYASABKAkSDAoEa2luZBgCIAEoCRIMCgRuYW1lGAMgASgJEg8KB2FsaWFzZXMYBCADKAkSDwoHc3VtbWFyeRgFIAEoCRISCgpjb25maWRlbmNlGAYgASgBEhUKDWV4dGVybmFsX2tpbmQYByABKAkSFAoMZXh0ZXJuYWxfcmVmGAggASgJImgKCk1HcmFwaEVkZ2USCgoCaWQYASABKAkSDgoGc3JjX2lkGAIgASgJEg4KBmRzdF9pZBgDIAEoCRIQCghyZWxfdHlwZRgEIAEoCRIMCgRmYWN0GAUgASgJEg4KBndlaWdodBgGIAEoASJUCg5NR3JhcGhSZXNwb25zZRIgCgVub2RlcxgBIAMoCzIRLm5vbW9zLk1HcmFwaE5vZGUSIAoFZWRnZXMYAiADKAsyES5ub21vcy5NR3JhcGhFZGdlIl4KCk1UcnVzdFRpZXISCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIMCgRtb2RlGAQgASgJEhMKC2JvbmRfYW1vdW50GAUgASgJIjkKC01QZXJtaXNzaW9uEgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEg8KB2VuYWJsZWQYAyABKAgiiQEKDE1JbnRlZ3JhdGlvbhIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRIMCgRpY29uGAMgASgJEhEKCWNvbm5lY3RlZBgEIAEoCBIVCg1hY2NvdW50X2VtYWlsGAUgASgJEhQKDHNlbmRfZW5hYmxlZBgGIAEoCBIQCghwcm92aWRlchgHIAEoCSJoCghNUHJvZmlsZRIMCgRuYW1lGAEgASgJEgwKBHBsYW4YAiABKAkSFQoNbWVzc2FnZV9jb3VudBgDIAEoAxIUCgxlYXJuZWRfY2VudHMYBCABKAMSEwoLc2F2ZWRfY2VudHMYBSABKAMizwIKEU1TZXR0aW5nc1Jlc3BvbnNlEiAKB3Byb2ZpbGUYASABKAsyDy5ub21vcy5NUHJvZmlsZRImCgt0cnVzdF90aWVycxgCIAMoCzIRLm5vbW9zLk1UcnVzdFRpZXISJwoLcGVybWlzc2lvbnMYAyADKAsyEi5ub21vcy5NUGVybWlzc2lvbhIpCgxpbnRlZ3JhdGlvbnMYBCADKAsyEy5ub21vcy5NSW50ZWdyYXRpb24SJQoHY29uc2VudBgFIAMoCzIULm5vbW9zLk1Db25zZW50RW50cnkSJwoIaWRlbnRpdHkYBiABKAsyFS5ub21vcy5NQWdlbnRJZGVudGl0eRImCgthcHBfdG9nZ2xlcxgHIAMoCzIRLm5vbW9zLk1BcHBUb2dnbGUSJAoJcHJvYWN0aXZlGAggASgLMhEubm9tb3MuTVByb2FjdGl2ZSIsCgpNUHJvYWN0aXZlEgwKBG1vZGUYASABKAkSEAoIYnJpZWZpbmcYAiABKAkiLwoNTUNvbnNlbnRFbnRyeRIQCghwbGF0Zm9ybRgBIAEoCRIMCgRtb2RlGAIgASgJIj0KDk1BZ2VudElkZW50aXR5EgwKBG5hbWUYASABKAkSDQoFdm9pY2UYAiABKAkSDgoGYXZhdGFyGAMgASgJIioKCk1BcHBUb2dnbGUSCwoDa2V5GAEgASgJEg8KB2VuYWJsZWQYAiABKAgiMAoSTUFwcFNldHRpbmdSZXF1ZXN0EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCSJEChVNQWdlbnRJZGVudGl0eVJlcXVlc3QSDAoEbmFtZRgBIAEoCRINCgV2b2ljZRgCIAEoCRIOCgZhdmF0YXIYAyABKAkiMQoPTUNvbnNlbnRSZXF1ZXN0EhAKCHBsYXRmb3JtGAEgASgJEgwKBG1vZGUYAiABKAkiQgoRTVRydXN0VGllclJlcXVlc3QSCgoCaWQYASABKAkSDAoEbW9kZRgCIAEoCRITCgtib25kX2Ftb3VudBgDIAEoCSIxChJNUGVybWlzc2lvblJlcXVlc3QSCgoCaWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCCJCChVNSW50ZWdyYXRpb25zUmVzcG9uc2USKQoMaW50ZWdyYXRpb25zGAEgAygLMhMubm9tb3MuTUludGVncmF0aW9uIigKFE1TdGFydENvbm5lY3RSZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJIioKFU1TdGFydENvbm5lY3RSZXNwb25zZRIRCglvYXV0aF91cmwYASABKAkiQwoSTURpc2Nvbm5lY3RSZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJEhUKDWFjY291bnRfZW1haWwYAiABKAkiNAoVTUNvbm5lY3RHb29nbGVSZXF1ZXN0EgwKBGNvZGUYASABKAkSDQoFc3RhdGUYAiABKAkiPwoVTVNldEdvb2dsZVNlbmRSZXF1ZXN0EhUKDWFjY291bnRfZW1haWwYASABKAkSDwoHZW5hYmxlZBgCIAEoCCJRCg9NRGV2aWNlUmVnaXN0ZXISFwoPZXhwb19wdXNoX3Rva2VuGAEgASgJEhAKCHBsYXRmb3JtGAIgASgJEhMKC2FwcF92ZXJzaW9uGAMgASgJIiwKEU1EZXZpY2VVbnJlZ2lzdGVyEhcKD2V4cG9fcHVzaF90b2tlbhgBIAEoCSLsAQoORGVwb3NpdFJlcXVlc3QSEAoIcHJvdmlkZXIYASABKAkSDwoHdXNlcl9pZBgCIAEoCRIUCgxhY2Nlc3NfdG9rZW4YAyABKAkSFQoNcmVmcmVzaF90b2tlbhgEIAEoCRISCgpleHBpcmVzX2F0GAUgASgDEg4KBnNjb3BlcxgGIAEoCRI1CghtZXRhZGF0YRgHIAMoCzIjLm5vbW9zLkRlcG9zaXRSZXF1ZXN0Lk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIksKD0RlcG9zaXRSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkSFgoOaW50ZWdyYXRpb25faWQYAyABKAkibQoZTVN0dWRpb0NyZWF0ZUFzc2V0UmVxdWVzdBIMCgRtaW1lGAEgASgJEhQKDGNvbnRlbnRfaGFzaBgCIAEoCRINCgV3aWR0aBgDIAEoBRIOCgZoZWlnaHQYBCABKAUSDQoFYnl0ZXMYBSABKAUiagoaTVN0dWRpb0NyZWF0ZUFzc2V0UmVzcG9uc2USEAoIYXNzZXRfaWQYASABKAkSEgoKdXBsb2FkX3VybBgCIAEoCRISCgpvYmplY3Rfa2V5GAMgASgJEhIKCmV4cGlyZXNfYXQYBCABKAMiNQoPTVN0dWRpb0Fzc2V0UmVmEhAKCGFzc2V0X2lkGAEgASgJEhAKCG9yaWdpbmFsGAIgASgIIjoKF01TdHVkaW9Bc3NldFVybFJlc3BvbnNlEgsKA3VybBgBIAEoCRISCgpleHBpcmVzX2F0GAIgASgDIp8BChJNU3R1ZGlvRWRpdFJlcXVlc3QSEAoIYXNzZXRfaWQYASABKAkSCgoCb3AYAiABKAkSEwoLcGFyYW1zX2pzb24YAyABKAkSFgoOcGFyZW50X2VkaXRfaWQYBCABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAUgASgJEhAKCG1hc2tfa2V5GAYgASgJEhMKC2lucHV0X2ltYWdlGAcgASgMIokBCgxNU3R1ZGlvRXZlbnQSDAoEa2luZBgBIAEoCRIPCgdlZGl0X2lkGAIgASgJEg4KBnN0YXR1cxgDIAEoCRITCgtwcmV2aWV3X2tleRgEIAEoCRISCgpvdXRwdXRfa2V5GAUgASgJEhAKCGNvc3RfdXNkGAYgASgBEg8KB21lc3NhZ2UYByABKAkinAEKC01TdHVkaW9FZGl0EgoKAmlkGAEgASgJEgoKAm9wGAIgASgJEg4KBnN0YXR1cxgDIAEoCRITCgtwcmV2aWV3X2tleRgEIAEoCRISCgpvdXRwdXRfa2V5GAUgASgJEhAKCGNvc3RfdXNkGAYgASgBEhYKDnBhcmVudF9lZGl0X2lkGAcgASgJEhIKCmNyZWF0ZWRfYXQYCCABKAkiUQoWTVN0dWRpb0hpc3RvcnlSZXNwb25zZRIhCgVlZGl0cxgBIAMoCzISLm5vbW9zLk1TdHVkaW9FZGl0EhQKDGhlYWRfZWRpdF9pZBgCIAEoCSI3ChVNU3R1ZGlvSWRlbnRpdHlSZXBvcnQSDwoHZWRpdF9pZBgBIAEoCRINCgVzY29yZRgCIAEoASIpChhNU3R1ZGlvTGlzdEFzc2V0c1JlcXVlc3QSDQoFbGltaXQYASABKAUinAEKE01TdHVkaW9Bc3NldFN1bW1hcnkSEAoIYXNzZXRfaWQYASABKAkSEwoLcHJldmlld191cmwYAiABKAkSEgoKdXBkYXRlZF9hdBgDIAEoAxIRCglmaW5hbGl6ZWQYBCABKAgSEgoKZWRpdF9jb3VudBgFIAEoBRIPCgdoZWFkX29wGAYgASgJEhIKCmV4cGlyZXNfYXQYByABKAMiRwoZTVN0dWRpb0xpc3RBc3NldHNSZXNwb25zZRIqCgZhc3NldHMYASADKAsyGi5ub21vcy5NU3R1ZGlvQXNzZXRTdW1tYXJ5IjIKEU1TdHVkaW9TdWdnZXN0aW9uEg0KBWxhYmVsGAEgASgJEg4KBnByb21wdBgCIAEoCSJLChpNU3R1ZGlvU3VnZ2VzdGlvbnNSZXNwb25zZRItCgtzdWdnZXN0aW9ucxgBIAMoCzIYLm5vbW9zLk1TdHVkaW9TdWdnZXN0aW9uMp4FCgpOb21vc0FnZW50Ei8KBENoYXQSEi5ub21vcy5DaGF0UmVxdWVzdBoRLm5vbW9zLkFnZW50RXZlbnQwARI4CgdDb21tYW5kEhUubm9tb3MuQ29tbWFuZFJlcXVlc3QaFi5ub21vcy5Db21tYW5kUmVzcG9uc2USMAoJR2V0U3RhdHVzEgwubm9tb3MuRW1wdHkaFS5ub21vcy5TdGF0dXNSZXNwb25zZRIwCgxMaXN0U2Vzc2lvbnMSDC5ub21vcy5FbXB0eRoSLm5vbW9zLlNlc3Npb25MaXN0EjsKCkdldFNlc3Npb24SFS5ub21vcy5TZXNzaW9uUmVxdWVzdBoWLm5vbW9zLlNlc3Npb25SZXNwb25zZRIsCgpMaXN0RHJhZnRzEgwubm9tb3MuRW1wdHkaEC5ub21vcy5EcmFmdExpc3QSOAoMQXBwcm92ZURyYWZ0EhIubm9tb3MuRHJhZnRBY3Rpb24aFC5ub21vcy5EcmFmdFJlc3BvbnNlEjcKC1JlamVjdERyYWZ0EhIubm9tb3MuRHJhZnRBY3Rpb24aFC5ub21vcy5EcmFmdFJlc3BvbnNlEioKCUxpc3RMb29wcxIMLm5vbW9zLkVtcHR5Gg8ubm9tb3MuTG9vcExpc3QSSQoOU2V0TG9vcEVuYWJsZWQSHC5ub21vcy5TZXRMb29wRW5hYmxlZFJlcXVlc3QaGS5ub21vcy5Mb29wQWN0aW9uUmVzcG9uc2USQQoKRGVsZXRlTG9vcBIYLm5vbW9zLkxvb3BEZWxldGVSZXF1ZXN0Ghkubm9tb3MuTG9vcEFjdGlvblJlc3BvbnNlEikKBFBpbmcSDC5ub21vcy5FbXB0eRoTLm5vbW9zLlBvbmdSZXNwb25zZTLxFwoJTW9iaWxlQXBpEjAKBENoYXQSEy5ub21vcy5NQ2hhdFJlcXVlc3QaES5ub21vcy5NQ2hhdEV2ZW50MAESRgoLR2V0TWVzc2FnZXMSGi5ub21vcy5NR2V0TWVzc2FnZXNSZXF1ZXN0Ghsubm9tb3MuTUdldE1lc3NhZ2VzUmVzcG9uc2USQAoMQXBwcm92ZURyYWZ0EhMubm9tb3MuTURyYWZ0QWN0aW9uGhsubm9tb3MuTURyYWZ0QWN0aW9uUmVzcG9uc2USPwoLUmVqZWN0RHJhZnQSEy5ub21vcy5NRHJhZnRBY3Rpb24aGy5ub21vcy5NRHJhZnRBY3Rpb25SZXNwb25zZRJQChRBcHByb3ZlRHJhZnRXaXRoRWRpdBIbLm5vbW9zLk1EcmFmdEFjdGlvbldpdGhFZGl0Ghsubm9tb3MuTURyYWZ0QWN0aW9uUmVzcG9uc2USOAoJTGlzdEluYm94EhQubm9tb3MuTUluYm94UmVxdWVzdBoVLm5vbW9zLk1JbmJveFJlc3BvbnNlEkAKD0dldENhdGVFbnZlbG9wZRIXLm5vbW9zLk1FbnZlbG9wZVJlcXVlc3QaFC5ub21vcy5NQ2F0ZUVudmVsb3BlEkkKDkFjdE9uSW5ib3hJdGVtEhoubm9tb3MuTUluYm94QWN0aW9uUmVxdWVzdBobLm5vbW9zLk1JbmJveEFjdGlvblJlc3BvbnNlEjIKCkxpc3RTa2lsbHMSDC5ub21vcy5FbXB0eRoWLm5vbW9zLk1Ta2lsbHNSZXNwb25zZRJGCgtUb2dnbGVTa2lsbBIaLm5vbW9zLk1Ta2lsbFRvZ2dsZVJlcXVlc3QaGy5ub21vcy5NU2tpbGxUb2dnbGVSZXNwb25zZRI0CgtMaXN0UGx1Z2lucxIMLm5vbW9zLkVtcHR5Ghcubm9tb3MuTVBsdWdpbnNSZXNwb25zZRJACgtHZXRFYXJuaW5ncxIXLm5vbW9zLk1FYXJuaW5nc1JlcXVlc3QaGC5ub21vcy5NRWFybmluZ3NSZXNwb25zZRI3CghHZXRHcmFwaBIULm5vbW9zLk1HcmFwaFJlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRJJChFHZXRHcmFwaE5laWdoYm9ycxIdLm5vbW9zLk1HcmFwaE5laWdoYm9yc1JlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRJACgtTZWFyY2hHcmFwaBIaLm5vbW9zLk1HcmFwaFNlYXJjaFJlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRI1CgtHZXRTZXR0aW5ncxIMLm5vbW9zLkVtcHR5Ghgubm9tb3MuTVNldHRpbmdzUmVzcG9uc2USNAoNVXBkYXRlQ29uc2VudBIWLm5vbW9zLk1Db25zZW50UmVxdWVzdBoLLm5vbW9zLk1BY2sSOAoPVXBkYXRlVHJ1c3RUaWVyEhgubm9tb3MuTVRydXN0VGllclJlcXVlc3QaCy5ub21vcy5NQWNrEjoKEFVwZGF0ZVBlcm1pc3Npb24SGS5ub21vcy5NUGVybWlzc2lvblJlcXVlc3QaCy5ub21vcy5NQWNrEjoKEFVwZGF0ZUFwcFNldHRpbmcSGS5ub21vcy5NQXBwU2V0dGluZ1JlcXVlc3QaCy5ub21vcy5NQWNrEkAKE1VwZGF0ZUFnZW50SWRlbnRpdHkSHC5ub21vcy5NQWdlbnRJZGVudGl0eVJlcXVlc3QaCy5ub21vcy5NQWNrEj4KEExpc3RJbnRlZ3JhdGlvbnMSDC5ub21vcy5FbXB0eRocLm5vbW9zLk1JbnRlZ3JhdGlvbnNSZXNwb25zZRJUChdTdGFydENvbm5lY3RJbnRlZ3JhdGlvbhIbLm5vbW9zLk1TdGFydENvbm5lY3RSZXF1ZXN0Ghwubm9tb3MuTVN0YXJ0Q29ubmVjdFJlc3BvbnNlEkEKFENvbm5lY3RHb29nbGVBY2NvdW50Ehwubm9tb3MuTUNvbm5lY3RHb29nbGVSZXF1ZXN0Ggsubm9tb3MuTUFjaxI6Cg1TZXRHb29nbGVTZW5kEhwubm9tb3MuTVNldEdvb2dsZVNlbmRSZXF1ZXN0Ggsubm9tb3MuTUFjaxI/ChVEaXNjb25uZWN0SW50ZWdyYXRpb24SGS5ub21vcy5NRGlzY29ubmVjdFJlcXVlc3QaCy5ub21vcy5NQWNrEjUKDlJlZ2lzdGVyRGV2aWNlEhYubm9tb3MuTURldmljZVJlZ2lzdGVyGgsubm9tb3MuTUFjaxI5ChBVbnJlZ2lzdGVyRGV2aWNlEhgubm9tb3MuTURldmljZVVucmVnaXN0ZXIaCy5ub21vcy5NQWNrEkUKDkxpc3RWYXVsdE5vdGVzEhgubm9tb3MuTVZhdWx0TGlzdFJlcXVlc3QaGS5ub21vcy5NVmF1bHRMaXN0UmVzcG9uc2USOgoMR2V0VmF1bHROb3RlEhcubm9tb3MuTVZhdWx0R2V0UmVxdWVzdBoRLm5vbW9zLk1WYXVsdE5vdGUSOAoOV3JpdGVWYXVsdE5vdGUSGS5ub21vcy5NVmF1bHRXcml0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjoKD0RlbGV0ZVZhdWx0Tm90ZRIaLm5vbW9zLk1WYXVsdERlbGV0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjAKCUxpc3RMb29wcxIMLm5vbW9zLkVtcHR5GhUubm9tb3MuTUxvb3BzUmVzcG9uc2USPAoOU2V0TG9vcEVuYWJsZWQSHS5ub21vcy5NU2V0TG9vcEVuYWJsZWRSZXF1ZXN0Ggsubm9tb3MuTUFjaxI0CgpEZWxldGVMb29wEhkubm9tb3MuTUxvb3BEZWxldGVSZXF1ZXN0Ggsubm9tb3MuTUFjaxIwCglMaXN0VGFza3MSDC5ub21vcy5FbXB0eRoVLm5vbW9zLk1UYXNrc1Jlc3BvbnNlEjQKClVwZGF0ZVRhc2sSGS5ub21vcy5NVGFza1VwZGF0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjQKCkRlbGV0ZVRhc2sSGS5ub21vcy5NVGFza0RlbGV0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEi8KCEdldEJyYWluEgwubm9tb3MuRW1wdHkaFS5ub21vcy5NQnJhaW5SZXNwb25zZRIyCghHZXRJbmJveBIMLm5vbW9zLkVtcHR5Ghgubm9tb3MuTUdldEluYm94UmVzcG9uc2USLwoIR2V0VG9kYXkSDC5ub21vcy5FbXB0eRoVLm5vbW9zLk1Ub2RheVJlc3BvbnNlElgKEVN0dWRpb0NyZWF0ZUFzc2V0EiAubm9tb3MuTVN0dWRpb0NyZWF0ZUFzc2V0UmVxdWVzdBohLm5vbW9zLk1TdHVkaW9DcmVhdGVBc3NldFJlc3BvbnNlEksKEVN0dWRpb0dldEFzc2V0VXJsEhYubm9tb3MuTVN0dWRpb0Fzc2V0UmVmGh4ubm9tb3MuTVN0dWRpb0Fzc2V0VXJsUmVzcG9uc2USPgoKU3R1ZGlvRWRpdBIZLm5vbW9zLk1TdHVkaW9FZGl0UmVxdWVzdBoTLm5vbW9zLk1TdHVkaW9FdmVudDABEkYKDVN0dWRpb0hpc3RvcnkSFi5ub21vcy5NU3R1ZGlvQXNzZXRSZWYaHS5ub21vcy5NU3R1ZGlvSGlzdG9yeVJlc3BvbnNlElUKEFN0dWRpb0xpc3RBc3NldHMSHy5ub21vcy5NU3R1ZGlvTGlzdEFzc2V0c1JlcXVlc3QaIC5ub21vcy5NU3R1ZGlvTGlzdEFzc2V0c1Jlc3BvbnNlEk8KElN0dWRpb1N1Z2dlc3RFZGl0cxIWLm5vbW9zLk1TdHVkaW9Bc3NldFJlZhohLm5vbW9zLk1TdHVkaW9TdWdnZXN0aW9uc1Jlc3BvbnNlEkEKFFN0dWRpb1JlcG9ydElkZW50aXR5Ehwubm9tb3MuTVN0dWRpb0lkZW50aXR5UmVwb3J0Ggsubm9tb3MuTUFjazJICgxPQXV0aERlcG9zaXQSOAoHRGVwb3NpdBIVLm5vbW9zLkRlcG9zaXRSZXF1ZXN0GhYubm9tb3MuRGVwb3NpdFJlc3BvbnNlYgZwcm90bzM"); +export const file_nomos: GenFile /*@__PURE__*/ = fileDesc( + "Cgtub21vcy5wcm90bxIFbm9tb3MiBwoFRW1wdHkijgEKCExvb3BJbmZvEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEAoIc2NoZWR1bGUYAyABKAkSDwoHZW5hYmxlZBgEIAEoCBIOCgZzb3VyY2UYBSABKAkSEwoLZXJyb3JfY291bnQYBiABKAUSEAoIbGFzdF9ydW4YByABKAkSDgoGcHJvbXB0GAggASgJIioKCExvb3BMaXN0Eh4KBWxvb3BzGAEgAygLMg8ubm9tb3MuTG9vcEluZm8iNgoVU2V0TG9vcEVuYWJsZWRSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHZW5hYmxlZBgCIAEoCCIhChFMb29wRGVsZXRlUmVxdWVzdBIMCgRuYW1lGAEgASgJIjYKEkxvb3BBY3Rpb25SZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiMwoLQ2hhdFJlcXVlc3QSDwoHY29udGVudBgBIAEoCRITCgtzZXNzaW9uX2tleRgCIAEoCSIwCgpBZ2VudEV2ZW50EgwKBHR5cGUYASABKAkSFAoManNvbl9wYXlsb2FkGAIgASgJIjYKDkNvbW1hbmRSZXF1ZXN0Eg8KB2NvbW1hbmQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkiMwoPQ29tbWFuZFJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSJPCg5TdGF0dXNSZXNwb25zZRIPCgdydW5uaW5nGAEgASgIEhkKEWNvbm5lY3RlZF9jbGllbnRzGAIgASgFEhEKCXBsYXRmb3JtcxgDIAMoCSIlCg5TZXNzaW9uUmVxdWVzdBITCgtzZXNzaW9uX2tleRgBIAEoCSJVCg9TZXNzaW9uUmVzcG9uc2USCgoCaWQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkSDQoFbW9kZWwYAyABKAkSEgoKY3JlYXRlZF9hdBgEIAEoCSI3CgtTZXNzaW9uTGlzdBIoCghzZXNzaW9ucxgBIAMoCzIWLm5vbW9zLlNlc3Npb25SZXNwb25zZSIfCgtEcmFmdEFjdGlvbhIQCghkcmFmdF9pZBgBIAEoCSIxCg1EcmFmdFJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSItCglEcmFmdExpc3QSIAoGZHJhZnRzGAEgAygLMhAubm9tb3MuRHJhZnRJdGVtInIKCURyYWZ0SXRlbRIKCgJpZBgBIAEoCRIPCgdjb250ZW50GAIgASgJEhAKCHBsYXRmb3JtGAMgASgJEhIKCmNoYW5uZWxfaWQYBCABKAkSDgoGc3RhdHVzGAUgASgJEhIKCmNyZWF0ZWRfYXQYBiABKAkiIQoMUG9uZ1Jlc3BvbnNlEhEKCXRpbWVzdGFtcBgBIAEoAyKLAQoFTUxvb3ASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIQCghzY2hlZHVsZRgDIAEoCRIPCgdlbmFibGVkGAQgASgIEg4KBnNvdXJjZRgFIAEoCRITCgtlcnJvcl9jb3VudBgGIAEoBRIQCghsYXN0X3J1bhgHIAEoCRIOCgZwcm9tcHQYCCABKAkiLQoOTUxvb3BzUmVzcG9uc2USGwoFbG9vcHMYASADKAsyDC5ub21vcy5NTG9vcCI3ChZNU2V0TG9vcEVuYWJsZWRSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHZW5hYmxlZBgCIAEoCCIiChJNTG9vcERlbGV0ZVJlcXVlc3QSDAoEbmFtZRgBIAEoCSKnAQoFTVRhc2sSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIOCgZwcm9tcHQYAyABKAkSEAoIc2NoZWR1bGUYBCABKAkSFQoNc2NoZWR1bGVfdHlwZRgFIAEoCRIYChBkaXNwbGF5X3NjaGVkdWxlGAYgASgJEg8KB2VuYWJsZWQYByABKAgSDgoGc291cmNlGAggASgJEhAKCGxhc3RfcnVuGAkgASgJIi0KDk1UYXNrc1Jlc3BvbnNlEhsKBXRhc2tzGAEgAygLMgwubm9tb3MuTVRhc2sieAoSTVRhc2tVcGRhdGVSZXF1ZXN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDgoGcHJvbXB0GAMgASgJEhAKCHNjaGVkdWxlGAQgASgJEhUKDXNjaGVkdWxlX3R5cGUYBSABKAkSDwoHZW5hYmxlZBgGIAEoCCIgChJNVGFza0RlbGV0ZVJlcXVlc3QSCgoCaWQYASABKAkiagoKTUJyYWluTm9kZRIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRIMCgRraW5kGAMgASgJEg8KB3N1bW1hcnkYBCABKAkSDgoGZGVncmVlGAUgASgFEhIKCmNvbmZpZGVuY2UYBiABKAEiOAoKTUJyYWluRWRnZRILCgNzcmMYASABKAkSCwoDZHN0GAIgASgJEhAKCHJlbGF0aW9uGAMgASgJIlIKCk1CcmFpbkZhY3QSDAoEdGV4dBgBIAEoCRIOCgZzb3VyY2UYAiABKAkSEgoKY29uZmlkZW5jZRgDIAEoBRISCgpsZWFybmVkX2F0GAQgASgJIqABCg5NQnJhaW5SZXNwb25zZRIgCgVub2RlcxgBIAMoCzIRLm5vbW9zLk1CcmFpbk5vZGUSIAoFZWRnZXMYAiADKAsyES5ub21vcy5NQnJhaW5FZGdlEiAKBWZhY3RzGAMgAygLMhEubm9tb3MuTUJyYWluRmFjdBIUCgxlbnRpdHlfY291bnQYBCABKAUSEgoKZmFjdF9jb3VudBgFIAEoBSJzCgtNSW5ib3hEcmFmdBIKCgJpZBgBIAEoCRIRCglyZWNpcGllbnQYAiABKAkSDwoHcHJldmlldxgDIAEoCRIOCgZzdGF0dXMYBCABKAkSEAoIcGxhdGZvcm0YBSABKAkSEgoKY3JlYXRlZF9hdBgGIAEoCSJ6CgpNSW5ib3hDYXRlEgoKAmlkGAEgASgJEhIKCmZyb21fbGFiZWwYAiABKAkSEgoKdHJ1c3RfdGllchgDIAEoCRIPCgdzdWJqZWN0GAQgASgJEhMKC2JvbmRfYW1vdW50GAUgASgJEhIKCmNyZWF0ZWRfYXQYBiABKAkibwoRTUdldEluYm94UmVzcG9uc2USIgoGZHJhZnRzGAEgAygLMhIubm9tb3MuTUluYm94RHJhZnQSHwoEY2F0ZRgCIAMoCzIRLm5vbW9zLk1JbmJveENhdGUSFQoNYmxvY2tlZF9jb3VudBgDIAEoBSI4CgtNVG9kYXlFdmVudBIMCgR0aW1lGAEgASgJEg0KBXRpdGxlGAIgASgJEgwKBG1ldGEYAyABKAkiQAoQTVRvZGF5Q29tbWl0bWVudBIKCgJpZBgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRILCgNkdWUYAyABKAkiOAoKTVRvZGF5VGFzaxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCHNjaGVkdWxlGAMgASgJIp4BCg5NVG9kYXlSZXNwb25zZRIYChBicmllZmluZ19lbmFibGVkGAEgASgIEiIKBmV2ZW50cxgCIAMoCzISLm5vbW9zLk1Ub2RheUV2ZW50EiwKC2NvbW1pdG1lbnRzGAMgAygLMhcubm9tb3MuTVRvZGF5Q29tbWl0bWVudBIgCgV0YXNrcxgEIAMoCzIRLm5vbW9zLk1Ub2RheVRhc2siKAoETUFjaxIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiIwoRTVZhdWx0TGlzdFJlcXVlc3QSDgoGcHJlZml4GAEgASgJIkQKEU1WYXVsdE5vdGVTdW1tYXJ5EgwKBHBhdGgYASABKAkSDQoFdGl0bGUYAiABKAkSEgoKdXBkYXRlZF9hdBgDIAEoCSI9ChJNVmF1bHRMaXN0UmVzcG9uc2USJwoFbm90ZXMYASADKAsyGC5ub21vcy5NVmF1bHROb3RlU3VtbWFyeSIgChBNVmF1bHRHZXRSZXF1ZXN0EgwKBHBhdGgYASABKAkiXgoKTVZhdWx0Tm90ZRIMCgRwYXRoGAEgASgJEg0KBXRpdGxlGAIgASgJEg8KB2NvbnRlbnQYAyABKAkSEgoKdXBkYXRlZF9hdBgEIAEoCRIOCgZleGlzdHMYBSABKAgiQgoSTVZhdWx0V3JpdGVSZXF1ZXN0EgwKBHBhdGgYASABKAkSDwoHY29udGVudBgCIAEoCRINCgV0aXRsZRgDIAEoCSIjChNNVmF1bHREZWxldGVSZXF1ZXN0EgwKBHBhdGgYASABKAkiNAoMTUNoYXRSZXF1ZXN0Eg8KB2NvbnRlbnQYASABKAkSEwoLc2Vzc2lvbl9rZXkYAiABKAkiMAoKTUNoYXRFdmVudBIMCgR0eXBlGAEgASgJEhQKDGpzb25fcGF5bG9hZBgCIAEoCSJMChNNR2V0TWVzc2FnZXNSZXF1ZXN0EhMKC3Nlc3Npb25fa2V5GAEgASgJEg0KBWxpbWl0GAIgASgFEhEKCWJlZm9yZV9pZBgDIAEoCSJJCghNTWVzc2FnZRIKCgJpZBgBIAEoCRIMCgRyb2xlGAIgASgJEg8KB2NvbnRlbnQYAyABKAkSEgoKY3JlYXRlZF9hdBgEIAEoCSI5ChRNR2V0TWVzc2FnZXNSZXNwb25zZRIhCghtZXNzYWdlcxgBIAMoCzIPLm5vbW9zLk1NZXNzYWdlIiAKDE1EcmFmdEFjdGlvbhIQCghkcmFmdF9pZBgBIAEoCSI9ChRNRHJhZnRBY3Rpb25XaXRoRWRpdBIQCghkcmFmdF9pZBgBIAEoCRITCgtlZGl0ZWRfdGV4dBgCIAEoCSI4ChRNRHJhZnRBY3Rpb25SZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkiLgoNTUluYm94UmVxdWVzdBIOCgZzdGF0dXMYASABKAkSDQoFbGltaXQYAiABKAUimAEKCk1JbmJveEl0ZW0SCgoCaWQYASABKAkSEgoKZnJvbV9sYWJlbBgCIAEoCRISCgp0cnVzdF90aWVyGAMgASgJEg8KB3N1YmplY3QYBCABKAkSDAoEdGltZRgFIAEoCRITCgtib25kX2Ftb3VudBgGIAEoCRIOCgZ1bnJlYWQYByABKAgSEgoKY3JlYXRlZF9hdBgIIAEoCSJJCg5NSW5ib3hSZXNwb25zZRIgCgVpdGVtcxgBIAMoCzIRLm5vbW9zLk1JbmJveEl0ZW0SFQoNYmxvY2tlZF9jb3VudBgCIAEoBSIkChBNRW52ZWxvcGVSZXF1ZXN0EhAKCGluYm94X2lkGAEgASgJIo0BCg1NQ2F0ZUVudmVsb3BlEgsKA2RpZBgBIAEoCRISCgp0cnVzdF90aWVyGAIgASgJEg4KBmludGVudBgDIAEoCRIVCg1jb25zZW50X2dyYW50GAQgASgJEg0KBXN0YW1wGAUgASgJEhMKC2JvbmRfYW1vdW50GAYgASgJEhAKCHJhd19qc29uGAcgASgJIjcKE01JbmJveEFjdGlvblJlcXVlc3QSEAoIaW5ib3hfaWQYASABKAkSDgoGYWN0aW9uGAIgASgJIjgKFE1JbmJveEFjdGlvblJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSJqCgZNU2tpbGwSDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIOCgZzb3VyY2UYAyABKAkSDwoHZW5hYmxlZBgEIAEoCBINCgVjZXJ0cxgFIAMoCRINCgVwcmljZRgGIAEoCSIwCg9NU2tpbGxzUmVzcG9uc2USHQoGc2tpbGxzGAEgAygLMg0ubm9tb3MuTVNraWxsIkEKB01QbHVnaW4SDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRITCgttYXJrZXRwbGFjZRgDIAEoCSIzChBNUGx1Z2luc1Jlc3BvbnNlEh8KB3BsdWdpbnMYASADKAsyDi5ub21vcy5NUGx1Z2luIjQKE01Ta2lsbFRvZ2dsZVJlcXVlc3QSDAoEbmFtZRgBIAEoCRIPCgdlbmFibGVkGAIgASgIIjgKFE1Ta2lsbFRvZ2dsZVJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgSDwoHbWVzc2FnZRgCIAEoCSIiChBNRWFybmluZ3NSZXF1ZXN0Eg4KBnBlcmlvZBgBIAEoCSKKAQoRTUVhcm5pbmdzUmVzcG9uc2USGQoRdGhpc19wZXJpb2RfY2VudHMYASABKAMSEwoLYm9uZHNfY291bnQYAiABKAMSFgoOYXZnX2JvbmRfY2VudHMYAyABKAMSFwoPYWNjZXB0X3JhdGVfcGN0GAQgASgFEhQKDHNlcmllc19jZW50cxgFIAMoAyItCg1NR3JhcGhSZXF1ZXN0Eg0KBWtpbmRzGAEgAygJEg0KBWxpbWl0GAIgASgFIl4KFk1HcmFwaE5laWdoYm9yc1JlcXVlc3QSDwoHbm9kZV9pZBgBIAEoCRINCgVkZXB0aBgCIAEoBRIRCglyZWxfdHlwZXMYAyADKAkSEQoJZGlyZWN0aW9uGAQgASgJIjMKE01HcmFwaFNlYXJjaFJlcXVlc3QSDQoFcXVlcnkYASABKAkSDQoFbGltaXQYAiABKAUilwEKCk1HcmFwaE5vZGUSCgoCaWQYASABKAkSDAoEa2luZBgCIAEoCRIMCgRuYW1lGAMgASgJEg8KB2FsaWFzZXMYBCADKAkSDwoHc3VtbWFyeRgFIAEoCRISCgpjb25maWRlbmNlGAYgASgBEhUKDWV4dGVybmFsX2tpbmQYByABKAkSFAoMZXh0ZXJuYWxfcmVmGAggASgJImgKCk1HcmFwaEVkZ2USCgoCaWQYASABKAkSDgoGc3JjX2lkGAIgASgJEg4KBmRzdF9pZBgDIAEoCRIQCghyZWxfdHlwZRgEIAEoCRIMCgRmYWN0GAUgASgJEg4KBndlaWdodBgGIAEoASJUCg5NR3JhcGhSZXNwb25zZRIgCgVub2RlcxgBIAMoCzIRLm5vbW9zLk1HcmFwaE5vZGUSIAoFZWRnZXMYAiADKAsyES5ub21vcy5NR3JhcGhFZGdlIl4KCk1UcnVzdFRpZXISCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIMCgRtb2RlGAQgASgJEhMKC2JvbmRfYW1vdW50GAUgASgJIjkKC01QZXJtaXNzaW9uEgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEg8KB2VuYWJsZWQYAyABKAgiiQEKDE1JbnRlZ3JhdGlvbhIKCgJpZBgBIAEoCRINCgVsYWJlbBgCIAEoCRIMCgRpY29uGAMgASgJEhEKCWNvbm5lY3RlZBgEIAEoCBIVCg1hY2NvdW50X2VtYWlsGAUgASgJEhQKDHNlbmRfZW5hYmxlZBgGIAEoCBIQCghwcm92aWRlchgHIAEoCSJoCghNUHJvZmlsZRIMCgRuYW1lGAEgASgJEgwKBHBsYW4YAiABKAkSFQoNbWVzc2FnZV9jb3VudBgDIAEoAxIUCgxlYXJuZWRfY2VudHMYBCABKAMSEwoLc2F2ZWRfY2VudHMYBSABKAMizwIKEU1TZXR0aW5nc1Jlc3BvbnNlEiAKB3Byb2ZpbGUYASABKAsyDy5ub21vcy5NUHJvZmlsZRImCgt0cnVzdF90aWVycxgCIAMoCzIRLm5vbW9zLk1UcnVzdFRpZXISJwoLcGVybWlzc2lvbnMYAyADKAsyEi5ub21vcy5NUGVybWlzc2lvbhIpCgxpbnRlZ3JhdGlvbnMYBCADKAsyEy5ub21vcy5NSW50ZWdyYXRpb24SJQoHY29uc2VudBgFIAMoCzIULm5vbW9zLk1Db25zZW50RW50cnkSJwoIaWRlbnRpdHkYBiABKAsyFS5ub21vcy5NQWdlbnRJZGVudGl0eRImCgthcHBfdG9nZ2xlcxgHIAMoCzIRLm5vbW9zLk1BcHBUb2dnbGUSJAoJcHJvYWN0aXZlGAggASgLMhEubm9tb3MuTVByb2FjdGl2ZSIsCgpNUHJvYWN0aXZlEgwKBG1vZGUYASABKAkSEAoIYnJpZWZpbmcYAiABKAkiLwoNTUNvbnNlbnRFbnRyeRIQCghwbGF0Zm9ybRgBIAEoCRIMCgRtb2RlGAIgASgJIj0KDk1BZ2VudElkZW50aXR5EgwKBG5hbWUYASABKAkSDQoFdm9pY2UYAiABKAkSDgoGYXZhdGFyGAMgASgJIioKCk1BcHBUb2dnbGUSCwoDa2V5GAEgASgJEg8KB2VuYWJsZWQYAiABKAgiMAoSTUFwcFNldHRpbmdSZXF1ZXN0EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCSJEChVNQWdlbnRJZGVudGl0eVJlcXVlc3QSDAoEbmFtZRgBIAEoCRINCgV2b2ljZRgCIAEoCRIOCgZhdmF0YXIYAyABKAkiMQoPTUNvbnNlbnRSZXF1ZXN0EhAKCHBsYXRmb3JtGAEgASgJEgwKBG1vZGUYAiABKAkiQgoRTVRydXN0VGllclJlcXVlc3QSCgoCaWQYASABKAkSDAoEbW9kZRgCIAEoCRITCgtib25kX2Ftb3VudBgDIAEoCSIxChJNUGVybWlzc2lvblJlcXVlc3QSCgoCaWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCCJCChVNSW50ZWdyYXRpb25zUmVzcG9uc2USKQoMaW50ZWdyYXRpb25zGAEgAygLMhMubm9tb3MuTUludGVncmF0aW9uIigKFE1TdGFydENvbm5lY3RSZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJIioKFU1TdGFydENvbm5lY3RSZXNwb25zZRIRCglvYXV0aF91cmwYASABKAkiQwoSTURpc2Nvbm5lY3RSZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJEhUKDWFjY291bnRfZW1haWwYAiABKAkiNAoVTUNvbm5lY3RHb29nbGVSZXF1ZXN0EgwKBGNvZGUYASABKAkSDQoFc3RhdGUYAiABKAkiPwoVTVNldEdvb2dsZVNlbmRSZXF1ZXN0EhUKDWFjY291bnRfZW1haWwYASABKAkSDwoHZW5hYmxlZBgCIAEoCCJRCg9NRGV2aWNlUmVnaXN0ZXISFwoPZXhwb19wdXNoX3Rva2VuGAEgASgJEhAKCHBsYXRmb3JtGAIgASgJEhMKC2FwcF92ZXJzaW9uGAMgASgJIiwKEU1EZXZpY2VVbnJlZ2lzdGVyEhcKD2V4cG9fcHVzaF90b2tlbhgBIAEoCSLsAQoORGVwb3NpdFJlcXVlc3QSEAoIcHJvdmlkZXIYASABKAkSDwoHdXNlcl9pZBgCIAEoCRIUCgxhY2Nlc3NfdG9rZW4YAyABKAkSFQoNcmVmcmVzaF90b2tlbhgEIAEoCRISCgpleHBpcmVzX2F0GAUgASgDEg4KBnNjb3BlcxgGIAEoCRI1CghtZXRhZGF0YRgHIAMoCzIjLm5vbW9zLkRlcG9zaXRSZXF1ZXN0Lk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIksKD0RlcG9zaXRSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIEg8KB21lc3NhZ2UYAiABKAkSFgoOaW50ZWdyYXRpb25faWQYAyABKAkibQoZTVN0dWRpb0NyZWF0ZUFzc2V0UmVxdWVzdBIMCgRtaW1lGAEgASgJEhQKDGNvbnRlbnRfaGFzaBgCIAEoCRINCgV3aWR0aBgDIAEoBRIOCgZoZWlnaHQYBCABKAUSDQoFYnl0ZXMYBSABKAUiagoaTVN0dWRpb0NyZWF0ZUFzc2V0UmVzcG9uc2USEAoIYXNzZXRfaWQYASABKAkSEgoKdXBsb2FkX3VybBgCIAEoCRISCgpvYmplY3Rfa2V5GAMgASgJEhIKCmV4cGlyZXNfYXQYBCABKAMiNQoPTVN0dWRpb0Fzc2V0UmVmEhAKCGFzc2V0X2lkGAEgASgJEhAKCG9yaWdpbmFsGAIgASgIIjoKF01TdHVkaW9Bc3NldFVybFJlc3BvbnNlEgsKA3VybBgBIAEoCRISCgpleHBpcmVzX2F0GAIgASgDIp8BChJNU3R1ZGlvRWRpdFJlcXVlc3QSEAoIYXNzZXRfaWQYASABKAkSCgoCb3AYAiABKAkSEwoLcGFyYW1zX2pzb24YAyABKAkSFgoOcGFyZW50X2VkaXRfaWQYBCABKAkSFwoPaWRlbXBvdGVuY3lfa2V5GAUgASgJEhAKCG1hc2tfa2V5GAYgASgJEhMKC2lucHV0X2ltYWdlGAcgASgMIokBCgxNU3R1ZGlvRXZlbnQSDAoEa2luZBgBIAEoCRIPCgdlZGl0X2lkGAIgASgJEg4KBnN0YXR1cxgDIAEoCRITCgtwcmV2aWV3X2tleRgEIAEoCRISCgpvdXRwdXRfa2V5GAUgASgJEhAKCGNvc3RfdXNkGAYgASgBEg8KB21lc3NhZ2UYByABKAkinAEKC01TdHVkaW9FZGl0EgoKAmlkGAEgASgJEgoKAm9wGAIgASgJEg4KBnN0YXR1cxgDIAEoCRITCgtwcmV2aWV3X2tleRgEIAEoCRISCgpvdXRwdXRfa2V5GAUgASgJEhAKCGNvc3RfdXNkGAYgASgBEhYKDnBhcmVudF9lZGl0X2lkGAcgASgJEhIKCmNyZWF0ZWRfYXQYCCABKAkiUQoWTVN0dWRpb0hpc3RvcnlSZXNwb25zZRIhCgVlZGl0cxgBIAMoCzISLm5vbW9zLk1TdHVkaW9FZGl0EhQKDGhlYWRfZWRpdF9pZBgCIAEoCSI3ChVNU3R1ZGlvSWRlbnRpdHlSZXBvcnQSDwoHZWRpdF9pZBgBIAEoCRINCgVzY29yZRgCIAEoASIpChhNU3R1ZGlvTGlzdEFzc2V0c1JlcXVlc3QSDQoFbGltaXQYASABKAUinAEKE01TdHVkaW9Bc3NldFN1bW1hcnkSEAoIYXNzZXRfaWQYASABKAkSEwoLcHJldmlld191cmwYAiABKAkSEgoKdXBkYXRlZF9hdBgDIAEoAxIRCglmaW5hbGl6ZWQYBCABKAgSEgoKZWRpdF9jb3VudBgFIAEoBRIPCgdoZWFkX29wGAYgASgJEhIKCmV4cGlyZXNfYXQYByABKAMiRwoZTVN0dWRpb0xpc3RBc3NldHNSZXNwb25zZRIqCgZhc3NldHMYASADKAsyGi5ub21vcy5NU3R1ZGlvQXNzZXRTdW1tYXJ5IjIKEU1TdHVkaW9TdWdnZXN0aW9uEg0KBWxhYmVsGAEgASgJEg4KBnByb21wdBgCIAEoCSJLChpNU3R1ZGlvU3VnZ2VzdGlvbnNSZXNwb25zZRItCgtzdWdnZXN0aW9ucxgBIAMoCzIYLm5vbW9zLk1TdHVkaW9TdWdnZXN0aW9uMp4FCgpOb21vc0FnZW50Ei8KBENoYXQSEi5ub21vcy5DaGF0UmVxdWVzdBoRLm5vbW9zLkFnZW50RXZlbnQwARI4CgdDb21tYW5kEhUubm9tb3MuQ29tbWFuZFJlcXVlc3QaFi5ub21vcy5Db21tYW5kUmVzcG9uc2USMAoJR2V0U3RhdHVzEgwubm9tb3MuRW1wdHkaFS5ub21vcy5TdGF0dXNSZXNwb25zZRIwCgxMaXN0U2Vzc2lvbnMSDC5ub21vcy5FbXB0eRoSLm5vbW9zLlNlc3Npb25MaXN0EjsKCkdldFNlc3Npb24SFS5ub21vcy5TZXNzaW9uUmVxdWVzdBoWLm5vbW9zLlNlc3Npb25SZXNwb25zZRIsCgpMaXN0RHJhZnRzEgwubm9tb3MuRW1wdHkaEC5ub21vcy5EcmFmdExpc3QSOAoMQXBwcm92ZURyYWZ0EhIubm9tb3MuRHJhZnRBY3Rpb24aFC5ub21vcy5EcmFmdFJlc3BvbnNlEjcKC1JlamVjdERyYWZ0EhIubm9tb3MuRHJhZnRBY3Rpb24aFC5ub21vcy5EcmFmdFJlc3BvbnNlEioKCUxpc3RMb29wcxIMLm5vbW9zLkVtcHR5Gg8ubm9tb3MuTG9vcExpc3QSSQoOU2V0TG9vcEVuYWJsZWQSHC5ub21vcy5TZXRMb29wRW5hYmxlZFJlcXVlc3QaGS5ub21vcy5Mb29wQWN0aW9uUmVzcG9uc2USQQoKRGVsZXRlTG9vcBIYLm5vbW9zLkxvb3BEZWxldGVSZXF1ZXN0Ghkubm9tb3MuTG9vcEFjdGlvblJlc3BvbnNlEikKBFBpbmcSDC5ub21vcy5FbXB0eRoTLm5vbW9zLlBvbmdSZXNwb25zZTLxFwoJTW9iaWxlQXBpEjAKBENoYXQSEy5ub21vcy5NQ2hhdFJlcXVlc3QaES5ub21vcy5NQ2hhdEV2ZW50MAESRgoLR2V0TWVzc2FnZXMSGi5ub21vcy5NR2V0TWVzc2FnZXNSZXF1ZXN0Ghsubm9tb3MuTUdldE1lc3NhZ2VzUmVzcG9uc2USQAoMQXBwcm92ZURyYWZ0EhMubm9tb3MuTURyYWZ0QWN0aW9uGhsubm9tb3MuTURyYWZ0QWN0aW9uUmVzcG9uc2USPwoLUmVqZWN0RHJhZnQSEy5ub21vcy5NRHJhZnRBY3Rpb24aGy5ub21vcy5NRHJhZnRBY3Rpb25SZXNwb25zZRJQChRBcHByb3ZlRHJhZnRXaXRoRWRpdBIbLm5vbW9zLk1EcmFmdEFjdGlvbldpdGhFZGl0Ghsubm9tb3MuTURyYWZ0QWN0aW9uUmVzcG9uc2USOAoJTGlzdEluYm94EhQubm9tb3MuTUluYm94UmVxdWVzdBoVLm5vbW9zLk1JbmJveFJlc3BvbnNlEkAKD0dldENhdGVFbnZlbG9wZRIXLm5vbW9zLk1FbnZlbG9wZVJlcXVlc3QaFC5ub21vcy5NQ2F0ZUVudmVsb3BlEkkKDkFjdE9uSW5ib3hJdGVtEhoubm9tb3MuTUluYm94QWN0aW9uUmVxdWVzdBobLm5vbW9zLk1JbmJveEFjdGlvblJlc3BvbnNlEjIKCkxpc3RTa2lsbHMSDC5ub21vcy5FbXB0eRoWLm5vbW9zLk1Ta2lsbHNSZXNwb25zZRJGCgtUb2dnbGVTa2lsbBIaLm5vbW9zLk1Ta2lsbFRvZ2dsZVJlcXVlc3QaGy5ub21vcy5NU2tpbGxUb2dnbGVSZXNwb25zZRI0CgtMaXN0UGx1Z2lucxIMLm5vbW9zLkVtcHR5Ghcubm9tb3MuTVBsdWdpbnNSZXNwb25zZRJACgtHZXRFYXJuaW5ncxIXLm5vbW9zLk1FYXJuaW5nc1JlcXVlc3QaGC5ub21vcy5NRWFybmluZ3NSZXNwb25zZRI3CghHZXRHcmFwaBIULm5vbW9zLk1HcmFwaFJlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRJJChFHZXRHcmFwaE5laWdoYm9ycxIdLm5vbW9zLk1HcmFwaE5laWdoYm9yc1JlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRJACgtTZWFyY2hHcmFwaBIaLm5vbW9zLk1HcmFwaFNlYXJjaFJlcXVlc3QaFS5ub21vcy5NR3JhcGhSZXNwb25zZRI1CgtHZXRTZXR0aW5ncxIMLm5vbW9zLkVtcHR5Ghgubm9tb3MuTVNldHRpbmdzUmVzcG9uc2USNAoNVXBkYXRlQ29uc2VudBIWLm5vbW9zLk1Db25zZW50UmVxdWVzdBoLLm5vbW9zLk1BY2sSOAoPVXBkYXRlVHJ1c3RUaWVyEhgubm9tb3MuTVRydXN0VGllclJlcXVlc3QaCy5ub21vcy5NQWNrEjoKEFVwZGF0ZVBlcm1pc3Npb24SGS5ub21vcy5NUGVybWlzc2lvblJlcXVlc3QaCy5ub21vcy5NQWNrEjoKEFVwZGF0ZUFwcFNldHRpbmcSGS5ub21vcy5NQXBwU2V0dGluZ1JlcXVlc3QaCy5ub21vcy5NQWNrEkAKE1VwZGF0ZUFnZW50SWRlbnRpdHkSHC5ub21vcy5NQWdlbnRJZGVudGl0eVJlcXVlc3QaCy5ub21vcy5NQWNrEj4KEExpc3RJbnRlZ3JhdGlvbnMSDC5ub21vcy5FbXB0eRocLm5vbW9zLk1JbnRlZ3JhdGlvbnNSZXNwb25zZRJUChdTdGFydENvbm5lY3RJbnRlZ3JhdGlvbhIbLm5vbW9zLk1TdGFydENvbm5lY3RSZXF1ZXN0Ghwubm9tb3MuTVN0YXJ0Q29ubmVjdFJlc3BvbnNlEkEKFENvbm5lY3RHb29nbGVBY2NvdW50Ehwubm9tb3MuTUNvbm5lY3RHb29nbGVSZXF1ZXN0Ggsubm9tb3MuTUFjaxI6Cg1TZXRHb29nbGVTZW5kEhwubm9tb3MuTVNldEdvb2dsZVNlbmRSZXF1ZXN0Ggsubm9tb3MuTUFjaxI/ChVEaXNjb25uZWN0SW50ZWdyYXRpb24SGS5ub21vcy5NRGlzY29ubmVjdFJlcXVlc3QaCy5ub21vcy5NQWNrEjUKDlJlZ2lzdGVyRGV2aWNlEhYubm9tb3MuTURldmljZVJlZ2lzdGVyGgsubm9tb3MuTUFjaxI5ChBVbnJlZ2lzdGVyRGV2aWNlEhgubm9tb3MuTURldmljZVVucmVnaXN0ZXIaCy5ub21vcy5NQWNrEkUKDkxpc3RWYXVsdE5vdGVzEhgubm9tb3MuTVZhdWx0TGlzdFJlcXVlc3QaGS5ub21vcy5NVmF1bHRMaXN0UmVzcG9uc2USOgoMR2V0VmF1bHROb3RlEhcubm9tb3MuTVZhdWx0R2V0UmVxdWVzdBoRLm5vbW9zLk1WYXVsdE5vdGUSOAoOV3JpdGVWYXVsdE5vdGUSGS5ub21vcy5NVmF1bHRXcml0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjoKD0RlbGV0ZVZhdWx0Tm90ZRIaLm5vbW9zLk1WYXVsdERlbGV0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjAKCUxpc3RMb29wcxIMLm5vbW9zLkVtcHR5GhUubm9tb3MuTUxvb3BzUmVzcG9uc2USPAoOU2V0TG9vcEVuYWJsZWQSHS5ub21vcy5NU2V0TG9vcEVuYWJsZWRSZXF1ZXN0Ggsubm9tb3MuTUFjaxI0CgpEZWxldGVMb29wEhkubm9tb3MuTUxvb3BEZWxldGVSZXF1ZXN0Ggsubm9tb3MuTUFjaxIwCglMaXN0VGFza3MSDC5ub21vcy5FbXB0eRoVLm5vbW9zLk1UYXNrc1Jlc3BvbnNlEjQKClVwZGF0ZVRhc2sSGS5ub21vcy5NVGFza1VwZGF0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEjQKCkRlbGV0ZVRhc2sSGS5ub21vcy5NVGFza0RlbGV0ZVJlcXVlc3QaCy5ub21vcy5NQWNrEi8KCEdldEJyYWluEgwubm9tb3MuRW1wdHkaFS5ub21vcy5NQnJhaW5SZXNwb25zZRIyCghHZXRJbmJveBIMLm5vbW9zLkVtcHR5Ghgubm9tb3MuTUdldEluYm94UmVzcG9uc2USLwoIR2V0VG9kYXkSDC5ub21vcy5FbXB0eRoVLm5vbW9zLk1Ub2RheVJlc3BvbnNlElgKEVN0dWRpb0NyZWF0ZUFzc2V0EiAubm9tb3MuTVN0dWRpb0NyZWF0ZUFzc2V0UmVxdWVzdBohLm5vbW9zLk1TdHVkaW9DcmVhdGVBc3NldFJlc3BvbnNlEksKEVN0dWRpb0dldEFzc2V0VXJsEhYubm9tb3MuTVN0dWRpb0Fzc2V0UmVmGh4ubm9tb3MuTVN0dWRpb0Fzc2V0VXJsUmVzcG9uc2USPgoKU3R1ZGlvRWRpdBIZLm5vbW9zLk1TdHVkaW9FZGl0UmVxdWVzdBoTLm5vbW9zLk1TdHVkaW9FdmVudDABEkYKDVN0dWRpb0hpc3RvcnkSFi5ub21vcy5NU3R1ZGlvQXNzZXRSZWYaHS5ub21vcy5NU3R1ZGlvSGlzdG9yeVJlc3BvbnNlElUKEFN0dWRpb0xpc3RBc3NldHMSHy5ub21vcy5NU3R1ZGlvTGlzdEFzc2V0c1JlcXVlc3QaIC5ub21vcy5NU3R1ZGlvTGlzdEFzc2V0c1Jlc3BvbnNlEk8KElN0dWRpb1N1Z2dlc3RFZGl0cxIWLm5vbW9zLk1TdHVkaW9Bc3NldFJlZhohLm5vbW9zLk1TdHVkaW9TdWdnZXN0aW9uc1Jlc3BvbnNlEkEKFFN0dWRpb1JlcG9ydElkZW50aXR5Ehwubm9tb3MuTVN0dWRpb0lkZW50aXR5UmVwb3J0Ggsubm9tb3MuTUFjazJICgxPQXV0aERlcG9zaXQSOAoHRGVwb3NpdBIVLm5vbW9zLkRlcG9zaXRSZXF1ZXN0GhYubm9tb3MuRGVwb3NpdFJlc3BvbnNlYgZwcm90bzM", +); /** * @generated from message nomos.Empty */ -export type Empty = Message<"nomos.Empty"> & { -}; +export type Empty = Message<"nomos.Empty"> & {}; /** * Describes the message nomos.Empty. * Use `create(EmptySchema)` to create a new message. */ -export const EmptySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 0); +export const EmptySchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 0); /** * @generated from message nomos.LoopInfo @@ -78,8 +77,7 @@ export type LoopInfo = Message<"nomos.LoopInfo"> & { * Describes the message nomos.LoopInfo. * Use `create(LoopInfoSchema)` to create a new message. */ -export const LoopInfoSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 1); +export const LoopInfoSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 1); /** * @generated from message nomos.LoopList @@ -95,8 +93,7 @@ export type LoopList = Message<"nomos.LoopList"> & { * Describes the message nomos.LoopList. * Use `create(LoopListSchema)` to create a new message. */ -export const LoopListSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 2); +export const LoopListSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 2); /** * @generated from message nomos.SetLoopEnabledRequest @@ -117,7 +114,7 @@ export type SetLoopEnabledRequest = Message<"nomos.SetLoopEnabledRequest"> & { * Describes the message nomos.SetLoopEnabledRequest. * Use `create(SetLoopEnabledRequestSchema)` to create a new message. */ -export const SetLoopEnabledRequestSchema: GenMessage = /*@__PURE__*/ +export const SetLoopEnabledRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 3); /** @@ -134,8 +131,10 @@ export type LoopDeleteRequest = Message<"nomos.LoopDeleteRequest"> & { * Describes the message nomos.LoopDeleteRequest. * Use `create(LoopDeleteRequestSchema)` to create a new message. */ -export const LoopDeleteRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 4); +export const LoopDeleteRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 4, +); /** * @generated from message nomos.LoopActionResponse @@ -156,8 +155,10 @@ export type LoopActionResponse = Message<"nomos.LoopActionResponse"> & { * Describes the message nomos.LoopActionResponse. * Use `create(LoopActionResponseSchema)` to create a new message. */ -export const LoopActionResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 5); +export const LoopActionResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 5, +); /** * @generated from message nomos.ChatRequest @@ -178,8 +179,7 @@ export type ChatRequest = Message<"nomos.ChatRequest"> & { * Describes the message nomos.ChatRequest. * Use `create(ChatRequestSchema)` to create a new message. */ -export const ChatRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 6); +export const ChatRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 6); /** * @generated from message nomos.AgentEvent @@ -204,8 +204,7 @@ export type AgentEvent = Message<"nomos.AgentEvent"> & { * Describes the message nomos.AgentEvent. * Use `create(AgentEventSchema)` to create a new message. */ -export const AgentEventSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 7); +export const AgentEventSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 7); /** * @generated from message nomos.CommandRequest @@ -226,8 +225,10 @@ export type CommandRequest = Message<"nomos.CommandRequest"> & { * Describes the message nomos.CommandRequest. * Use `create(CommandRequestSchema)` to create a new message. */ -export const CommandRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 8); +export const CommandRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 8, +); /** * @generated from message nomos.CommandResponse @@ -248,8 +249,10 @@ export type CommandResponse = Message<"nomos.CommandResponse"> & { * Describes the message nomos.CommandResponse. * Use `create(CommandResponseSchema)` to create a new message. */ -export const CommandResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 9); +export const CommandResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 9, +); /** * @generated from message nomos.StatusResponse @@ -275,8 +278,10 @@ export type StatusResponse = Message<"nomos.StatusResponse"> & { * Describes the message nomos.StatusResponse. * Use `create(StatusResponseSchema)` to create a new message. */ -export const StatusResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 10); +export const StatusResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 10, +); /** * @generated from message nomos.SessionRequest @@ -292,8 +297,10 @@ export type SessionRequest = Message<"nomos.SessionRequest"> & { * Describes the message nomos.SessionRequest. * Use `create(SessionRequestSchema)` to create a new message. */ -export const SessionRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 11); +export const SessionRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 11, +); /** * @generated from message nomos.SessionResponse @@ -324,8 +331,10 @@ export type SessionResponse = Message<"nomos.SessionResponse"> & { * Describes the message nomos.SessionResponse. * Use `create(SessionResponseSchema)` to create a new message. */ -export const SessionResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 12); +export const SessionResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 12, +); /** * @generated from message nomos.SessionList @@ -341,8 +350,7 @@ export type SessionList = Message<"nomos.SessionList"> & { * Describes the message nomos.SessionList. * Use `create(SessionListSchema)` to create a new message. */ -export const SessionListSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 13); +export const SessionListSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 13); /** * @generated from message nomos.DraftAction @@ -358,8 +366,7 @@ export type DraftAction = Message<"nomos.DraftAction"> & { * Describes the message nomos.DraftAction. * Use `create(DraftActionSchema)` to create a new message. */ -export const DraftActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 14); +export const DraftActionSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 14); /** * @generated from message nomos.DraftResponse @@ -380,8 +387,10 @@ export type DraftResponse = Message<"nomos.DraftResponse"> & { * Describes the message nomos.DraftResponse. * Use `create(DraftResponseSchema)` to create a new message. */ -export const DraftResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 15); +export const DraftResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 15, +); /** * @generated from message nomos.DraftList @@ -397,8 +406,7 @@ export type DraftList = Message<"nomos.DraftList"> & { * Describes the message nomos.DraftList. * Use `create(DraftListSchema)` to create a new message. */ -export const DraftListSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 16); +export const DraftListSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 16); /** * @generated from message nomos.DraftItem @@ -439,8 +447,7 @@ export type DraftItem = Message<"nomos.DraftItem"> & { * Describes the message nomos.DraftItem. * Use `create(DraftItemSchema)` to create a new message. */ -export const DraftItemSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 17); +export const DraftItemSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 17); /** * @generated from message nomos.PongResponse @@ -456,8 +463,10 @@ export type PongResponse = Message<"nomos.PongResponse"> & { * Describes the message nomos.PongResponse. * Use `create(PongResponseSchema)` to create a new message. */ -export const PongResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 18); +export const PongResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 18, +); /** * Loops (autonomous recurring jobs) @@ -514,8 +523,7 @@ export type MLoop = Message<"nomos.MLoop"> & { * Describes the message nomos.MLoop. * Use `create(MLoopSchema)` to create a new message. */ -export const MLoopSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 19); +export const MLoopSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 19); /** * @generated from message nomos.MLoopsResponse @@ -531,8 +539,10 @@ export type MLoopsResponse = Message<"nomos.MLoopsResponse"> & { * Describes the message nomos.MLoopsResponse. * Use `create(MLoopsResponseSchema)` to create a new message. */ -export const MLoopsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 20); +export const MLoopsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 20, +); /** * @generated from message nomos.MSetLoopEnabledRequest @@ -553,7 +563,7 @@ export type MSetLoopEnabledRequest = Message<"nomos.MSetLoopEnabledRequest"> & { * Describes the message nomos.MSetLoopEnabledRequest. * Use `create(MSetLoopEnabledRequestSchema)` to create a new message. */ -export const MSetLoopEnabledRequestSchema: GenMessage = /*@__PURE__*/ +export const MSetLoopEnabledRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 21); /** @@ -570,8 +580,10 @@ export type MLoopDeleteRequest = Message<"nomos.MLoopDeleteRequest"> & { * Describes the message nomos.MLoopDeleteRequest. * Use `create(MLoopDeleteRequestSchema)` to create a new message. */ -export const MLoopDeleteRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 22); +export const MLoopDeleteRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 22, +); /** * Tasks (the user's scheduled tasks) @@ -639,8 +651,7 @@ export type MTask = Message<"nomos.MTask"> & { * Describes the message nomos.MTask. * Use `create(MTaskSchema)` to create a new message. */ -export const MTaskSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 23); +export const MTaskSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 23); /** * @generated from message nomos.MTasksResponse @@ -656,8 +667,10 @@ export type MTasksResponse = Message<"nomos.MTasksResponse"> & { * Describes the message nomos.MTasksResponse. * Use `create(MTasksResponseSchema)` to create a new message. */ -export const MTasksResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 24); +export const MTasksResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 24, +); /** * Full-state update (the client sends the edited task); empty name/schedule are @@ -701,8 +714,10 @@ export type MTaskUpdateRequest = Message<"nomos.MTaskUpdateRequest"> & { * Describes the message nomos.MTaskUpdateRequest. * Use `create(MTaskUpdateRequestSchema)` to create a new message. */ -export const MTaskUpdateRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 25); +export const MTaskUpdateRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 25, +); /** * @generated from message nomos.MTaskDeleteRequest @@ -718,8 +733,10 @@ export type MTaskDeleteRequest = Message<"nomos.MTaskDeleteRequest"> & { * Describes the message nomos.MTaskDeleteRequest. * Use `create(MTaskDeleteRequestSchema)` to create a new message. */ -export const MTaskDeleteRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 26); +export const MTaskDeleteRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 26, +); /** * Brain (knowledge graph + learned facts) @@ -766,8 +783,7 @@ export type MBrainNode = Message<"nomos.MBrainNode"> & { * Describes the message nomos.MBrainNode. * Use `create(MBrainNodeSchema)` to create a new message. */ -export const MBrainNodeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 27); +export const MBrainNodeSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 27); /** * @generated from message nomos.MBrainEdge @@ -793,8 +809,7 @@ export type MBrainEdge = Message<"nomos.MBrainEdge"> & { * Describes the message nomos.MBrainEdge. * Use `create(MBrainEdgeSchema)` to create a new message. */ -export const MBrainEdgeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 28); +export const MBrainEdgeSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 28); /** * @generated from message nomos.MBrainFact @@ -829,8 +844,7 @@ export type MBrainFact = Message<"nomos.MBrainFact"> & { * Describes the message nomos.MBrainFact. * Use `create(MBrainFactSchema)` to create a new message. */ -export const MBrainFactSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 29); +export const MBrainFactSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 29); /** * @generated from message nomos.MBrainResponse @@ -866,8 +880,10 @@ export type MBrainResponse = Message<"nomos.MBrainResponse"> & { * Describes the message nomos.MBrainResponse. * Use `create(MBrainResponseSchema)` to create a new message. */ -export const MBrainResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 30); +export const MBrainResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 30, +); /** * Inbox (drafts + CATE agent requests) @@ -912,8 +928,7 @@ export type MInboxDraft = Message<"nomos.MInboxDraft"> & { * Describes the message nomos.MInboxDraft. * Use `create(MInboxDraftSchema)` to create a new message. */ -export const MInboxDraftSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 31); +export const MInboxDraftSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 31); /** * @generated from message nomos.MInboxCate @@ -954,8 +969,7 @@ export type MInboxCate = Message<"nomos.MInboxCate"> & { * Describes the message nomos.MInboxCate. * Use `create(MInboxCateSchema)` to create a new message. */ -export const MInboxCateSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 32); +export const MInboxCateSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 32); /** * @generated from message nomos.MGetInboxResponse @@ -981,8 +995,10 @@ export type MGetInboxResponse = Message<"nomos.MGetInboxResponse"> & { * Describes the message nomos.MGetInboxResponse. * Use `create(MGetInboxResponseSchema)` to create a new message. */ -export const MGetInboxResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 33); +export const MGetInboxResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 33, +); /** * Today (the daily brief) @@ -1010,8 +1026,7 @@ export type MTodayEvent = Message<"nomos.MTodayEvent"> & { * Describes the message nomos.MTodayEvent. * Use `create(MTodayEventSchema)` to create a new message. */ -export const MTodayEventSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 34); +export const MTodayEventSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 34); /** * @generated from message nomos.MTodayCommitment @@ -1037,8 +1052,10 @@ export type MTodayCommitment = Message<"nomos.MTodayCommitment"> & { * Describes the message nomos.MTodayCommitment. * Use `create(MTodayCommitmentSchema)` to create a new message. */ -export const MTodayCommitmentSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 35); +export const MTodayCommitmentSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 35, +); /** * @generated from message nomos.MTodayTask @@ -1064,8 +1081,7 @@ export type MTodayTask = Message<"nomos.MTodayTask"> & { * Describes the message nomos.MTodayTask. * Use `create(MTodayTaskSchema)` to create a new message. */ -export const MTodayTaskSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 36); +export const MTodayTaskSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 36); /** * @generated from message nomos.MTodayResponse @@ -1096,8 +1112,10 @@ export type MTodayResponse = Message<"nomos.MTodayResponse"> & { * Describes the message nomos.MTodayResponse. * Use `create(MTodayResponseSchema)` to create a new message. */ -export const MTodayResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 37); +export const MTodayResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 37, +); /** * @generated from message nomos.MAck @@ -1118,8 +1136,7 @@ export type MAck = Message<"nomos.MAck"> & { * Describes the message nomos.MAck. * Use `create(MAckSchema)` to create a new message. */ -export const MAckSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 38); +export const MAckSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 38); /** * Vault (long-term memory / knowledge base) @@ -1137,8 +1154,10 @@ export type MVaultListRequest = Message<"nomos.MVaultListRequest"> & { * Describes the message nomos.MVaultListRequest. * Use `create(MVaultListRequestSchema)` to create a new message. */ -export const MVaultListRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 39); +export const MVaultListRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 39, +); /** * @generated from message nomos.MVaultNoteSummary @@ -1164,8 +1183,10 @@ export type MVaultNoteSummary = Message<"nomos.MVaultNoteSummary"> & { * Describes the message nomos.MVaultNoteSummary. * Use `create(MVaultNoteSummarySchema)` to create a new message. */ -export const MVaultNoteSummarySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 40); +export const MVaultNoteSummarySchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 40, +); /** * @generated from message nomos.MVaultListResponse @@ -1181,8 +1202,10 @@ export type MVaultListResponse = Message<"nomos.MVaultListResponse"> & { * Describes the message nomos.MVaultListResponse. * Use `create(MVaultListResponseSchema)` to create a new message. */ -export const MVaultListResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 41); +export const MVaultListResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 41, +); /** * @generated from message nomos.MVaultGetRequest @@ -1198,8 +1221,10 @@ export type MVaultGetRequest = Message<"nomos.MVaultGetRequest"> & { * Describes the message nomos.MVaultGetRequest. * Use `create(MVaultGetRequestSchema)` to create a new message. */ -export const MVaultGetRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 42); +export const MVaultGetRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 42, +); /** * @generated from message nomos.MVaultNote @@ -1235,8 +1260,7 @@ export type MVaultNote = Message<"nomos.MVaultNote"> & { * Describes the message nomos.MVaultNote. * Use `create(MVaultNoteSchema)` to create a new message. */ -export const MVaultNoteSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 43); +export const MVaultNoteSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 43); /** * @generated from message nomos.MVaultWriteRequest @@ -1262,8 +1286,10 @@ export type MVaultWriteRequest = Message<"nomos.MVaultWriteRequest"> & { * Describes the message nomos.MVaultWriteRequest. * Use `create(MVaultWriteRequestSchema)` to create a new message. */ -export const MVaultWriteRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 44); +export const MVaultWriteRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 44, +); /** * @generated from message nomos.MVaultDeleteRequest @@ -1279,8 +1305,10 @@ export type MVaultDeleteRequest = Message<"nomos.MVaultDeleteRequest"> & { * Describes the message nomos.MVaultDeleteRequest. * Use `create(MVaultDeleteRequestSchema)` to create a new message. */ -export const MVaultDeleteRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 45); +export const MVaultDeleteRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 45, +); /** * Chat @@ -1303,8 +1331,10 @@ export type MChatRequest = Message<"nomos.MChatRequest"> & { * Describes the message nomos.MChatRequest. * Use `create(MChatRequestSchema)` to create a new message. */ -export const MChatRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 46); +export const MChatRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 46, +); /** * @generated from message nomos.MChatEvent @@ -1325,8 +1355,7 @@ export type MChatEvent = Message<"nomos.MChatEvent"> & { * Describes the message nomos.MChatEvent. * Use `create(MChatEventSchema)` to create a new message. */ -export const MChatEventSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 47); +export const MChatEventSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 47); /** * @generated from message nomos.MGetMessagesRequest @@ -1352,8 +1381,10 @@ export type MGetMessagesRequest = Message<"nomos.MGetMessagesRequest"> & { * Describes the message nomos.MGetMessagesRequest. * Use `create(MGetMessagesRequestSchema)` to create a new message. */ -export const MGetMessagesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 48); +export const MGetMessagesRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 48, +); /** * @generated from message nomos.MMessage @@ -1386,8 +1417,7 @@ export type MMessage = Message<"nomos.MMessage"> & { * Describes the message nomos.MMessage. * Use `create(MMessageSchema)` to create a new message. */ -export const MMessageSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 49); +export const MMessageSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 49); /** * @generated from message nomos.MGetMessagesResponse @@ -1403,7 +1433,7 @@ export type MGetMessagesResponse = Message<"nomos.MGetMessagesResponse"> & { * Describes the message nomos.MGetMessagesResponse. * Use `create(MGetMessagesResponseSchema)` to create a new message. */ -export const MGetMessagesResponseSchema: GenMessage = /*@__PURE__*/ +export const MGetMessagesResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 50); /** @@ -1420,8 +1450,10 @@ export type MDraftAction = Message<"nomos.MDraftAction"> & { * Describes the message nomos.MDraftAction. * Use `create(MDraftActionSchema)` to create a new message. */ -export const MDraftActionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 51); +export const MDraftActionSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 51, +); /** * @generated from message nomos.MDraftActionWithEdit @@ -1442,7 +1474,7 @@ export type MDraftActionWithEdit = Message<"nomos.MDraftActionWithEdit"> & { * Describes the message nomos.MDraftActionWithEdit. * Use `create(MDraftActionWithEditSchema)` to create a new message. */ -export const MDraftActionWithEditSchema: GenMessage = /*@__PURE__*/ +export const MDraftActionWithEditSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 52); /** @@ -1464,7 +1496,7 @@ export type MDraftActionResponse = Message<"nomos.MDraftActionResponse"> & { * Describes the message nomos.MDraftActionResponse. * Use `create(MDraftActionResponseSchema)` to create a new message. */ -export const MDraftActionResponseSchema: GenMessage = /*@__PURE__*/ +export const MDraftActionResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 53); /** @@ -1490,8 +1522,10 @@ export type MInboxRequest = Message<"nomos.MInboxRequest"> & { * Describes the message nomos.MInboxRequest. * Use `create(MInboxRequestSchema)` to create a new message. */ -export const MInboxRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 54); +export const MInboxRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 54, +); /** * @generated from message nomos.MInboxItem @@ -1548,8 +1582,7 @@ export type MInboxItem = Message<"nomos.MInboxItem"> & { * Describes the message nomos.MInboxItem. * Use `create(MInboxItemSchema)` to create a new message. */ -export const MInboxItemSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 55); +export const MInboxItemSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 55); /** * @generated from message nomos.MInboxResponse @@ -1570,8 +1603,10 @@ export type MInboxResponse = Message<"nomos.MInboxResponse"> & { * Describes the message nomos.MInboxResponse. * Use `create(MInboxResponseSchema)` to create a new message. */ -export const MInboxResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 56); +export const MInboxResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 56, +); /** * @generated from message nomos.MEnvelopeRequest @@ -1587,8 +1622,10 @@ export type MEnvelopeRequest = Message<"nomos.MEnvelopeRequest"> & { * Describes the message nomos.MEnvelopeRequest. * Use `create(MEnvelopeRequestSchema)` to create a new message. */ -export const MEnvelopeRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 57); +export const MEnvelopeRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 57, +); /** * @generated from message nomos.MCateEnvelope @@ -1634,8 +1671,10 @@ export type MCateEnvelope = Message<"nomos.MCateEnvelope"> & { * Describes the message nomos.MCateEnvelope. * Use `create(MCateEnvelopeSchema)` to create a new message. */ -export const MCateEnvelopeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 58); +export const MCateEnvelopeSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 58, +); /** * @generated from message nomos.MInboxActionRequest @@ -1658,8 +1697,10 @@ export type MInboxActionRequest = Message<"nomos.MInboxActionRequest"> & { * Describes the message nomos.MInboxActionRequest. * Use `create(MInboxActionRequestSchema)` to create a new message. */ -export const MInboxActionRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 59); +export const MInboxActionRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 59, +); /** * @generated from message nomos.MInboxActionResponse @@ -1680,7 +1721,7 @@ export type MInboxActionResponse = Message<"nomos.MInboxActionResponse"> & { * Describes the message nomos.MInboxActionResponse. * Use `create(MInboxActionResponseSchema)` to create a new message. */ -export const MInboxActionResponseSchema: GenMessage = /*@__PURE__*/ +export const MInboxActionResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 60); /** @@ -1726,8 +1767,7 @@ export type MSkill = Message<"nomos.MSkill"> & { * Describes the message nomos.MSkill. * Use `create(MSkillSchema)` to create a new message. */ -export const MSkillSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 61); +export const MSkillSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 61); /** * @generated from message nomos.MSkillsResponse @@ -1743,8 +1783,10 @@ export type MSkillsResponse = Message<"nomos.MSkillsResponse"> & { * Describes the message nomos.MSkillsResponse. * Use `create(MSkillsResponseSchema)` to create a new message. */ -export const MSkillsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 62); +export const MSkillsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 62, +); /** * @generated from message nomos.MPlugin @@ -1770,8 +1812,7 @@ export type MPlugin = Message<"nomos.MPlugin"> & { * Describes the message nomos.MPlugin. * Use `create(MPluginSchema)` to create a new message. */ -export const MPluginSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 63); +export const MPluginSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 63); /** * @generated from message nomos.MPluginsResponse @@ -1787,8 +1828,10 @@ export type MPluginsResponse = Message<"nomos.MPluginsResponse"> & { * Describes the message nomos.MPluginsResponse. * Use `create(MPluginsResponseSchema)` to create a new message. */ -export const MPluginsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 64); +export const MPluginsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 64, +); /** * @generated from message nomos.MSkillToggleRequest @@ -1809,8 +1852,10 @@ export type MSkillToggleRequest = Message<"nomos.MSkillToggleRequest"> & { * Describes the message nomos.MSkillToggleRequest. * Use `create(MSkillToggleRequestSchema)` to create a new message. */ -export const MSkillToggleRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 65); +export const MSkillToggleRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 65, +); /** * @generated from message nomos.MSkillToggleResponse @@ -1831,7 +1876,7 @@ export type MSkillToggleResponse = Message<"nomos.MSkillToggleResponse"> & { * Describes the message nomos.MSkillToggleResponse. * Use `create(MSkillToggleResponseSchema)` to create a new message. */ -export const MSkillToggleResponseSchema: GenMessage = /*@__PURE__*/ +export const MSkillToggleResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 66); /** @@ -1852,8 +1897,10 @@ export type MEarningsRequest = Message<"nomos.MEarningsRequest"> & { * Describes the message nomos.MEarningsRequest. * Use `create(MEarningsRequestSchema)` to create a new message. */ -export const MEarningsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 67); +export const MEarningsRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 67, +); /** * @generated from message nomos.MEarningsResponse @@ -1893,8 +1940,10 @@ export type MEarningsResponse = Message<"nomos.MEarningsResponse"> & { * Describes the message nomos.MEarningsResponse. * Use `create(MEarningsResponseSchema)` to create a new message. */ -export const MEarningsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 68); +export const MEarningsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 68, +); /** * Brain (knowledge graph) @@ -1921,8 +1970,10 @@ export type MGraphRequest = Message<"nomos.MGraphRequest"> & { * Describes the message nomos.MGraphRequest. * Use `create(MGraphRequestSchema)` to create a new message. */ -export const MGraphRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 69); +export const MGraphRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 69, +); /** * @generated from message nomos.MGraphNeighborsRequest @@ -1959,7 +2010,7 @@ export type MGraphNeighborsRequest = Message<"nomos.MGraphNeighborsRequest"> & { * Describes the message nomos.MGraphNeighborsRequest. * Use `create(MGraphNeighborsRequestSchema)` to create a new message. */ -export const MGraphNeighborsRequestSchema: GenMessage = /*@__PURE__*/ +export const MGraphNeighborsRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 70); /** @@ -1981,8 +2032,10 @@ export type MGraphSearchRequest = Message<"nomos.MGraphSearchRequest"> & { * Describes the message nomos.MGraphSearchRequest. * Use `create(MGraphSearchRequestSchema)` to create a new message. */ -export const MGraphSearchRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 71); +export const MGraphSearchRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 71, +); /** * @generated from message nomos.MGraphNode @@ -2035,8 +2088,7 @@ export type MGraphNode = Message<"nomos.MGraphNode"> & { * Describes the message nomos.MGraphNode. * Use `create(MGraphNodeSchema)` to create a new message. */ -export const MGraphNodeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 72); +export const MGraphNodeSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 72); /** * @generated from message nomos.MGraphEdge @@ -2077,8 +2129,7 @@ export type MGraphEdge = Message<"nomos.MGraphEdge"> & { * Describes the message nomos.MGraphEdge. * Use `create(MGraphEdgeSchema)` to create a new message. */ -export const MGraphEdgeSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 73); +export const MGraphEdgeSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 73); /** * @generated from message nomos.MGraphResponse @@ -2099,8 +2150,10 @@ export type MGraphResponse = Message<"nomos.MGraphResponse"> & { * Describes the message nomos.MGraphResponse. * Use `create(MGraphResponseSchema)` to create a new message. */ -export const MGraphResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 74); +export const MGraphResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 74, +); /** * Settings @@ -2140,8 +2193,7 @@ export type MTrustTier = Message<"nomos.MTrustTier"> & { * Describes the message nomos.MTrustTier. * Use `create(MTrustTierSchema)` to create a new message. */ -export const MTrustTierSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 75); +export const MTrustTierSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 75); /** * @generated from message nomos.MPermission @@ -2167,8 +2219,7 @@ export type MPermission = Message<"nomos.MPermission"> & { * Describes the message nomos.MPermission. * Use `create(MPermissionSchema)` to create a new message. */ -export const MPermissionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 76); +export const MPermissionSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 76); /** * @generated from message nomos.MIntegration @@ -2220,8 +2271,10 @@ export type MIntegration = Message<"nomos.MIntegration"> & { * Describes the message nomos.MIntegration. * Use `create(MIntegrationSchema)` to create a new message. */ -export const MIntegrationSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 77); +export const MIntegrationSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 77, +); /** * @generated from message nomos.MProfile @@ -2257,8 +2310,7 @@ export type MProfile = Message<"nomos.MProfile"> & { * Describes the message nomos.MProfile. * Use `create(MProfileSchema)` to create a new message. */ -export const MProfileSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 78); +export const MProfileSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 78); /** * @generated from message nomos.MSettingsResponse @@ -2309,8 +2361,10 @@ export type MSettingsResponse = Message<"nomos.MSettingsResponse"> & { * Describes the message nomos.MSettingsResponse. * Use `create(MSettingsResponseSchema)` to create a new message. */ -export const MSettingsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 79); +export const MSettingsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 79, +); /** * @generated from message nomos.MProactive @@ -2335,8 +2389,7 @@ export type MProactive = Message<"nomos.MProactive"> & { * Describes the message nomos.MProactive. * Use `create(MProactiveSchema)` to create a new message. */ -export const MProactiveSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 80); +export const MProactiveSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 80); /** * @generated from message nomos.MConsentEntry @@ -2359,8 +2412,10 @@ export type MConsentEntry = Message<"nomos.MConsentEntry"> & { * Describes the message nomos.MConsentEntry. * Use `create(MConsentEntrySchema)` to create a new message. */ -export const MConsentEntrySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 81); +export const MConsentEntrySchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 81, +); /** * @generated from message nomos.MAgentIdentity @@ -2390,8 +2445,10 @@ export type MAgentIdentity = Message<"nomos.MAgentIdentity"> & { * Describes the message nomos.MAgentIdentity. * Use `create(MAgentIdentitySchema)` to create a new message. */ -export const MAgentIdentitySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 82); +export const MAgentIdentitySchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 82, +); /** * @generated from message nomos.MAppToggle @@ -2414,8 +2471,7 @@ export type MAppToggle = Message<"nomos.MAppToggle"> & { * Describes the message nomos.MAppToggle. * Use `create(MAppToggleSchema)` to create a new message. */ -export const MAppToggleSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 83); +export const MAppToggleSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 83); /** * @generated from message nomos.MAppSettingRequest @@ -2440,8 +2496,10 @@ export type MAppSettingRequest = Message<"nomos.MAppSettingRequest"> & { * Describes the message nomos.MAppSettingRequest. * Use `create(MAppSettingRequestSchema)` to create a new message. */ -export const MAppSettingRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 84); +export const MAppSettingRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 84, +); /** * @generated from message nomos.MAgentIdentityRequest @@ -2467,7 +2525,7 @@ export type MAgentIdentityRequest = Message<"nomos.MAgentIdentityRequest"> & { * Describes the message nomos.MAgentIdentityRequest. * Use `create(MAgentIdentityRequestSchema)` to create a new message. */ -export const MAgentIdentityRequestSchema: GenMessage = /*@__PURE__*/ +export const MAgentIdentityRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 85); /** @@ -2491,8 +2549,10 @@ export type MConsentRequest = Message<"nomos.MConsentRequest"> & { * Describes the message nomos.MConsentRequest. * Use `create(MConsentRequestSchema)` to create a new message. */ -export const MConsentRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 86); +export const MConsentRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 86, +); /** * @generated from message nomos.MTrustTierRequest @@ -2518,8 +2578,10 @@ export type MTrustTierRequest = Message<"nomos.MTrustTierRequest"> & { * Describes the message nomos.MTrustTierRequest. * Use `create(MTrustTierRequestSchema)` to create a new message. */ -export const MTrustTierRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 87); +export const MTrustTierRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 87, +); /** * @generated from message nomos.MPermissionRequest @@ -2540,8 +2602,10 @@ export type MPermissionRequest = Message<"nomos.MPermissionRequest"> & { * Describes the message nomos.MPermissionRequest. * Use `create(MPermissionRequestSchema)` to create a new message. */ -export const MPermissionRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 88); +export const MPermissionRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 88, +); /** * @generated from message nomos.MIntegrationsResponse @@ -2557,7 +2621,7 @@ export type MIntegrationsResponse = Message<"nomos.MIntegrationsResponse"> & { * Describes the message nomos.MIntegrationsResponse. * Use `create(MIntegrationsResponseSchema)` to create a new message. */ -export const MIntegrationsResponseSchema: GenMessage = /*@__PURE__*/ +export const MIntegrationsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 89); /** @@ -2576,7 +2640,7 @@ export type MStartConnectRequest = Message<"nomos.MStartConnectRequest"> & { * Describes the message nomos.MStartConnectRequest. * Use `create(MStartConnectRequestSchema)` to create a new message. */ -export const MStartConnectRequestSchema: GenMessage = /*@__PURE__*/ +export const MStartConnectRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 90); /** @@ -2597,7 +2661,7 @@ export type MStartConnectResponse = Message<"nomos.MStartConnectResponse"> & { * Describes the message nomos.MStartConnectResponse. * Use `create(MStartConnectResponseSchema)` to create a new message. */ -export const MStartConnectResponseSchema: GenMessage = /*@__PURE__*/ +export const MStartConnectResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 91); /** @@ -2621,8 +2685,10 @@ export type MDisconnectRequest = Message<"nomos.MDisconnectRequest"> & { * Describes the message nomos.MDisconnectRequest. * Use `create(MDisconnectRequestSchema)` to create a new message. */ -export const MDisconnectRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 92); +export const MDisconnectRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 92, +); /** * Relay an OAuth authorization code from the (web/mobile) callback to the daemon, @@ -2647,7 +2713,7 @@ export type MConnectGoogleRequest = Message<"nomos.MConnectGoogleRequest"> & { * Describes the message nomos.MConnectGoogleRequest. * Use `create(MConnectGoogleRequestSchema)` to create a new message. */ -export const MConnectGoogleRequestSchema: GenMessage = /*@__PURE__*/ +export const MConnectGoogleRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 93); /** @@ -2669,7 +2735,7 @@ export type MSetGoogleSendRequest = Message<"nomos.MSetGoogleSendRequest"> & { * Describes the message nomos.MSetGoogleSendRequest. * Use `create(MSetGoogleSendRequestSchema)` to create a new message. */ -export const MSetGoogleSendRequestSchema: GenMessage = /*@__PURE__*/ +export const MSetGoogleSendRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 94); /** @@ -2698,8 +2764,10 @@ export type MDeviceRegister = Message<"nomos.MDeviceRegister"> & { * Describes the message nomos.MDeviceRegister. * Use `create(MDeviceRegisterSchema)` to create a new message. */ -export const MDeviceRegisterSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 95); +export const MDeviceRegisterSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 95, +); /** * @generated from message nomos.MDeviceUnregister @@ -2715,8 +2783,10 @@ export type MDeviceUnregister = Message<"nomos.MDeviceUnregister"> & { * Describes the message nomos.MDeviceUnregister. * Use `create(MDeviceUnregisterSchema)` to create a new message. */ -export const MDeviceUnregisterSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 96); +export const MDeviceUnregisterSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 96, +); /** * @generated from message nomos.DepositRequest @@ -2773,8 +2843,10 @@ export type DepositRequest = Message<"nomos.DepositRequest"> & { * Describes the message nomos.DepositRequest. * Use `create(DepositRequestSchema)` to create a new message. */ -export const DepositRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 97); +export const DepositRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 97, +); /** * @generated from message nomos.DepositResponse @@ -2802,8 +2874,10 @@ export type DepositResponse = Message<"nomos.DepositResponse"> & { * Describes the message nomos.DepositResponse. * Use `create(DepositResponseSchema)` to create a new message. */ -export const DepositResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 98); +export const DepositResponseSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 98, +); /** * ── Studio (hosted-only feature) ────────────────────────────────────── @@ -2848,7 +2922,7 @@ export type MStudioCreateAssetRequest = Message<"nomos.MStudioCreateAssetRequest * Describes the message nomos.MStudioCreateAssetRequest. * Use `create(MStudioCreateAssetRequestSchema)` to create a new message. */ -export const MStudioCreateAssetRequestSchema: GenMessage = /*@__PURE__*/ +export const MStudioCreateAssetRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 99); /** @@ -2884,7 +2958,7 @@ export type MStudioCreateAssetResponse = Message<"nomos.MStudioCreateAssetRespon * Describes the message nomos.MStudioCreateAssetResponse. * Use `create(MStudioCreateAssetResponseSchema)` to create a new message. */ -export const MStudioCreateAssetResponseSchema: GenMessage = /*@__PURE__*/ +export const MStudioCreateAssetResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 100); /** @@ -2908,8 +2982,10 @@ export type MStudioAssetRef = Message<"nomos.MStudioAssetRef"> & { * Describes the message nomos.MStudioAssetRef. * Use `create(MStudioAssetRefSchema)` to create a new message. */ -export const MStudioAssetRefSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 101); +export const MStudioAssetRefSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 101, +); /** * @generated from message nomos.MStudioAssetUrlResponse @@ -2932,7 +3008,7 @@ export type MStudioAssetUrlResponse = Message<"nomos.MStudioAssetUrlResponse"> & * Describes the message nomos.MStudioAssetUrlResponse. * Use `create(MStudioAssetUrlResponseSchema)` to create a new message. */ -export const MStudioAssetUrlResponseSchema: GenMessage = /*@__PURE__*/ +export const MStudioAssetUrlResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 102); /** @@ -2988,8 +3064,10 @@ export type MStudioEditRequest = Message<"nomos.MStudioEditRequest"> & { * Describes the message nomos.MStudioEditRequest. * Use `create(MStudioEditRequestSchema)` to create a new message. */ -export const MStudioEditRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 103); +export const MStudioEditRequestSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 103, +); /** * @generated from message nomos.MStudioEvent @@ -3039,8 +3117,10 @@ export type MStudioEvent = Message<"nomos.MStudioEvent"> & { * Describes the message nomos.MStudioEvent. * Use `create(MStudioEventSchema)` to create a new message. */ -export const MStudioEventSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 104); +export const MStudioEventSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 104, +); /** * @generated from message nomos.MStudioEdit @@ -3091,8 +3171,10 @@ export type MStudioEdit = Message<"nomos.MStudioEdit"> & { * Describes the message nomos.MStudioEdit. * Use `create(MStudioEditSchema)` to create a new message. */ -export const MStudioEditSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 105); +export const MStudioEditSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 105, +); /** * @generated from message nomos.MStudioHistoryResponse @@ -3113,7 +3195,7 @@ export type MStudioHistoryResponse = Message<"nomos.MStudioHistoryResponse"> & { * Describes the message nomos.MStudioHistoryResponse. * Use `create(MStudioHistoryResponseSchema)` to create a new message. */ -export const MStudioHistoryResponseSchema: GenMessage = /*@__PURE__*/ +export const MStudioHistoryResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 106); /** @@ -3137,7 +3219,7 @@ export type MStudioIdentityReport = Message<"nomos.MStudioIdentityReport"> & { * Describes the message nomos.MStudioIdentityReport. * Use `create(MStudioIdentityReportSchema)` to create a new message. */ -export const MStudioIdentityReportSchema: GenMessage = /*@__PURE__*/ +export const MStudioIdentityReportSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 107); /** @@ -3158,7 +3240,7 @@ export type MStudioListAssetsRequest = Message<"nomos.MStudioListAssetsRequest"> * Describes the message nomos.MStudioListAssetsRequest. * Use `create(MStudioListAssetsRequestSchema)` to create a new message. */ -export const MStudioListAssetsRequestSchema: GenMessage = /*@__PURE__*/ +export const MStudioListAssetsRequestSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 108); /** @@ -3215,8 +3297,10 @@ export type MStudioAssetSummary = Message<"nomos.MStudioAssetSummary"> & { * Describes the message nomos.MStudioAssetSummary. * Use `create(MStudioAssetSummarySchema)` to create a new message. */ -export const MStudioAssetSummarySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 109); +export const MStudioAssetSummarySchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 109, +); /** * @generated from message nomos.MStudioListAssetsResponse @@ -3232,7 +3316,7 @@ export type MStudioListAssetsResponse = Message<"nomos.MStudioListAssetsResponse * Describes the message nomos.MStudioListAssetsResponse. * Use `create(MStudioListAssetsResponseSchema)` to create a new message. */ -export const MStudioListAssetsResponseSchema: GenMessage = /*@__PURE__*/ +export const MStudioListAssetsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 110); /** @@ -3256,8 +3340,10 @@ export type MStudioSuggestion = Message<"nomos.MStudioSuggestion"> & { * Describes the message nomos.MStudioSuggestion. * Use `create(MStudioSuggestionSchema)` to create a new message. */ -export const MStudioSuggestionSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_nomos, 111); +export const MStudioSuggestionSchema: GenMessage /*@__PURE__*/ = messageDesc( + file_nomos, + 111, +); /** * @generated from message nomos.MStudioSuggestionsResponse @@ -3273,7 +3359,7 @@ export type MStudioSuggestionsResponse = Message<"nomos.MStudioSuggestionsRespon * Describes the message nomos.MStudioSuggestionsResponse. * Use `create(MStudioSuggestionsResponseSchema)` to create a new message. */ -export const MStudioSuggestionsResponseSchema: GenMessage = /*@__PURE__*/ +export const MStudioSuggestionsResponseSchema: GenMessage /*@__PURE__*/ = messageDesc(file_nomos, 112); /** @@ -3289,7 +3375,7 @@ export const NomosAgent: GenService<{ methodKind: "server_streaming"; input: typeof ChatRequestSchema; output: typeof AgentEventSchema; - }, + }; /** * Send a command (e.g., /compact) * @@ -3299,7 +3385,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof CommandRequestSchema; output: typeof CommandResponseSchema; - }, + }; /** * Get daemon status * @@ -3309,7 +3395,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof StatusResponseSchema; - }, + }; /** * Session management * @@ -3319,7 +3405,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof SessionListSchema; - }, + }; /** * @generated from rpc nomos.NomosAgent.GetSession */ @@ -3327,7 +3413,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof SessionRequestSchema; output: typeof SessionResponseSchema; - }, + }; /** * Draft management (Slack User Mode approve-before-send) * @@ -3337,7 +3423,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof DraftListSchema; - }, + }; /** * @generated from rpc nomos.NomosAgent.ApproveDraft */ @@ -3345,7 +3431,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof DraftActionSchema; output: typeof DraftResponseSchema; - }, + }; /** * @generated from rpc nomos.NomosAgent.RejectDraft */ @@ -3353,7 +3439,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof DraftActionSchema; output: typeof DraftResponseSchema; - }, + }; /** * Autonomous loops (recurring background jobs — audit + disable) * @@ -3363,7 +3449,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof LoopListSchema; - }, + }; /** * @generated from rpc nomos.NomosAgent.SetLoopEnabled */ @@ -3371,7 +3457,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof SetLoopEnabledRequestSchema; output: typeof LoopActionResponseSchema; - }, + }; /** * @generated from rpc nomos.NomosAgent.DeleteLoop */ @@ -3379,7 +3465,7 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof LoopDeleteRequestSchema; output: typeof LoopActionResponseSchema; - }, + }; /** * Health check * @@ -3389,9 +3475,8 @@ export const NomosAgent: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof PongResponseSchema; - }, -}> = /*@__PURE__*/ - serviceDesc(file_nomos, 0); + }; +}> /*@__PURE__*/ = serviceDesc(file_nomos, 0); /** * @generated from service nomos.MobileApi @@ -3406,7 +3491,7 @@ export const MobileApi: GenService<{ methodKind: "server_streaming"; input: typeof MChatRequestSchema; output: typeof MChatEventSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.GetMessages */ @@ -3414,7 +3499,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MGetMessagesRequestSchema; output: typeof MGetMessagesResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ApproveDraft */ @@ -3422,7 +3507,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDraftActionSchema; output: typeof MDraftActionResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.RejectDraft */ @@ -3430,7 +3515,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDraftActionSchema; output: typeof MDraftActionResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ApproveDraftWithEdit */ @@ -3438,7 +3523,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDraftActionWithEditSchema; output: typeof MDraftActionResponseSchema; - }, + }; /** * Inbox tab (CATE inbound queue — Phase 5b) * @@ -3448,7 +3533,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MInboxRequestSchema; output: typeof MInboxResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.GetCateEnvelope */ @@ -3456,7 +3541,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MEnvelopeRequestSchema; output: typeof MCateEnvelopeSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ActOnInboxItem */ @@ -3464,7 +3549,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MInboxActionRequestSchema; output: typeof MInboxActionResponseSchema; - }, + }; /** * Skills tab * @@ -3474,7 +3559,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MSkillsResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ToggleSkill */ @@ -3482,7 +3567,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MSkillToggleRequestSchema; output: typeof MSkillToggleResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ListPlugins */ @@ -3490,7 +3575,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MPluginsResponseSchema; - }, + }; /** * Earnings tab * @@ -3500,7 +3585,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MEarningsRequestSchema; output: typeof MEarningsResponseSchema; - }, + }; /** * Brain tab (knowledge graph) * @@ -3510,7 +3595,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MGraphRequestSchema; output: typeof MGraphResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.GetGraphNeighbors */ @@ -3518,7 +3603,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MGraphNeighborsRequestSchema; output: typeof MGraphResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.SearchGraph */ @@ -3526,7 +3611,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MGraphSearchRequestSchema; output: typeof MGraphResponseSchema; - }, + }; /** * Settings tab * @@ -3536,7 +3621,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MSettingsResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdateConsent */ @@ -3544,7 +3629,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MConsentRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdateTrustTier */ @@ -3552,7 +3637,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MTrustTierRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdatePermission */ @@ -3560,7 +3645,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MPermissionRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdateAppSetting */ @@ -3568,7 +3653,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MAppSettingRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdateAgentIdentity */ @@ -3576,7 +3661,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MAgentIdentityRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ListIntegrations */ @@ -3584,7 +3669,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MIntegrationsResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.StartConnectIntegration */ @@ -3592,7 +3677,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStartConnectRequestSchema; output: typeof MStartConnectResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.ConnectGoogleAccount */ @@ -3600,7 +3685,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MConnectGoogleRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.SetGoogleSend */ @@ -3608,7 +3693,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MSetGoogleSendRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.DisconnectIntegration */ @@ -3616,7 +3701,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDisconnectRequestSchema; output: typeof MAckSchema; - }, + }; /** * Push notifications * @@ -3626,7 +3711,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDeviceRegisterSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UnregisterDevice */ @@ -3634,7 +3719,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MDeviceUnregisterSchema; output: typeof MAckSchema; - }, + }; /** * Vault tab (long-term memory / knowledge base) * @@ -3644,7 +3729,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MVaultListRequestSchema; output: typeof MVaultListResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.GetVaultNote */ @@ -3652,7 +3737,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MVaultGetRequestSchema; output: typeof MVaultNoteSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.WriteVaultNote */ @@ -3660,7 +3745,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MVaultWriteRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.DeleteVaultNote */ @@ -3668,7 +3753,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MVaultDeleteRequestSchema; output: typeof MAckSchema; - }, + }; /** * Loops tab (autonomous recurring jobs — audit + disable agent-created loops) * @@ -3678,7 +3763,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MLoopsResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.SetLoopEnabled */ @@ -3686,7 +3771,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MSetLoopEnabledRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.DeleteLoop */ @@ -3694,7 +3779,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MLoopDeleteRequestSchema; output: typeof MAckSchema; - }, + }; /** * Tasks tab (the user's scheduled tasks: one-off reminders + recurring jobs, * editable: reschedule, rename, edit instruction, enable/disable, delete) @@ -3705,7 +3790,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MTasksResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.UpdateTask */ @@ -3713,7 +3798,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MTaskUpdateRequestSchema; output: typeof MAckSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.DeleteTask */ @@ -3721,7 +3806,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MTaskDeleteRequestSchema; output: typeof MAckSchema; - }, + }; /** * Brain tab (the user's knowledge graph + learned facts, for the feed + map) * @@ -3731,7 +3816,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MBrainResponseSchema; - }, + }; /** * Inbox tab (drafts to approve + CATE agent requests). Actions reuse * ApproveDraft/RejectDraft (drafts) + ActOnInboxItem (CATE). @@ -3742,7 +3827,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MGetInboxResponseSchema; - }, + }; /** * Today tab (the daily brief: calendar + commitments + tasks, gated on the * daily briefing being enabled). @@ -3753,7 +3838,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof EmptySchema; output: typeof MTodayResponseSchema; - }, + }; /** * Studio (hosted-only feature). Blobs move via presigned PUT/GET, never gRPC. * @@ -3763,7 +3848,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioCreateAssetRequestSchema; output: typeof MStudioCreateAssetResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.StudioGetAssetUrl */ @@ -3771,7 +3856,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioAssetRefSchema; output: typeof MStudioAssetUrlResponseSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.StudioEdit */ @@ -3779,7 +3864,7 @@ export const MobileApi: GenService<{ methodKind: "server_streaming"; input: typeof MStudioEditRequestSchema; output: typeof MStudioEventSchema; - }, + }; /** * @generated from rpc nomos.MobileApi.StudioHistory */ @@ -3787,7 +3872,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioAssetRefSchema; output: typeof MStudioHistoryResponseSchema; - }, + }; /** * Recent editing sessions for the Home launchpad ("Pick up where you left off"). * @@ -3797,7 +3882,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioListAssetsRequestSchema; output: typeof MStudioListAssetsResponseSchema; - }, + }; /** * AI-native: a vision model looks at the photo and proposes tap-to-apply edits. * @@ -3807,7 +3892,7 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioAssetRefSchema; output: typeof MStudioSuggestionsResponseSchema; - }, + }; /** * The on-device identity check reports its score for an edit (0..1). * @@ -3817,9 +3902,8 @@ export const MobileApi: GenService<{ methodKind: "unary"; input: typeof MStudioIdentityReportSchema; output: typeof MAckSchema; - }, -}> = /*@__PURE__*/ - serviceDesc(file_nomos, 1); + }; +}> /*@__PURE__*/ = serviceDesc(file_nomos, 1); /** * @generated from service nomos.OAuthDeposit @@ -3832,7 +3916,5 @@ export const OAuthDeposit: GenService<{ methodKind: "unary"; input: typeof DepositRequestSchema; output: typeof DepositResponseSchema; - }, -}> = /*@__PURE__*/ - serviceDesc(file_nomos, 2); - + }; +}> /*@__PURE__*/ = serviceDesc(file_nomos, 2);