@automagik/omni 2.260430.3 → 2.260430.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/trust.d.ts +19 -0
- package/dist/commands/trust.d.ts.map +1 -0
- package/dist/index.js +98 -1
- package/dist/server/index.js +49 -2
- package/package.json +10 -10
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Commands — manage genie host fingerprint registrations.
|
|
3
|
+
*
|
|
4
|
+
* omni trust list List active genie hosts
|
|
5
|
+
* omni trust get <id> Show one host (active or revoked)
|
|
6
|
+
* omni trust update <id> --scope <a,b,c> Replace host scopes wholesale
|
|
7
|
+
* omni trust revoke <id> Soft-delete (stamps revoked_at)
|
|
8
|
+
*
|
|
9
|
+
* Wish: omni-host-fingerprint-trust, Group 1.2. Talks to the
|
|
10
|
+
* `/api/v2/trust/hosts` endpoints landed in Group 1.1 (#556).
|
|
11
|
+
*
|
|
12
|
+
* Why raw fetch instead of the OmniClient SDK: trust types aren't in the
|
|
13
|
+
* OpenAPI spec yet (the SDK is generated from there). Adding them requires
|
|
14
|
+
* a regen + version bump; out of scope for this PR. We use the same
|
|
15
|
+
* baseUrl / apiKey the SDK uses, so behavior is identical.
|
|
16
|
+
*/
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
export declare function createTrustCommand(): Command;
|
|
19
|
+
//# sourceMappingURL=trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/commands/trust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwHpC,wBAAgB,kBAAkB,IAAI,OAAO,CAmB5C"}
|
package/dist/index.js
CHANGED
|
@@ -113981,7 +113981,7 @@ import { fileURLToPath } from "url";
|
|
|
113981
113981
|
// package.json
|
|
113982
113982
|
var package_default = {
|
|
113983
113983
|
name: "@automagik/omni",
|
|
113984
|
-
version: "2.260430.
|
|
113984
|
+
version: "2.260430.4",
|
|
113985
113985
|
description: "LLM-optimized CLI for Omni",
|
|
113986
113986
|
type: "module",
|
|
113987
113987
|
bin: {
|
|
@@ -124980,6 +124980,97 @@ function createStopCommand() {
|
|
|
124980
124980
|
return new Command("stop").description("Stop all omni PM2 processes").action(runStop);
|
|
124981
124981
|
}
|
|
124982
124982
|
|
|
124983
|
+
// src/commands/trust.ts
|
|
124984
|
+
init_config();
|
|
124985
|
+
init_output();
|
|
124986
|
+
function trustEndpoint(path) {
|
|
124987
|
+
if (!hasAuth()) {
|
|
124988
|
+
error("Not authenticated. Run: omni auth login --api-key <key>", undefined, 2);
|
|
124989
|
+
}
|
|
124990
|
+
const config2 = loadConfig();
|
|
124991
|
+
const baseUrl = (config2.apiUrl ?? "http://localhost:8882").replace(/\/+$/, "");
|
|
124992
|
+
return `${baseUrl}/api/v2/trust${path}`;
|
|
124993
|
+
}
|
|
124994
|
+
function authHeaders() {
|
|
124995
|
+
const config2 = loadConfig();
|
|
124996
|
+
const headers = { "Content-Type": "application/json" };
|
|
124997
|
+
if (config2.apiKey) {
|
|
124998
|
+
headers.Authorization = `Bearer ${config2.apiKey}`;
|
|
124999
|
+
}
|
|
125000
|
+
return headers;
|
|
125001
|
+
}
|
|
125002
|
+
async function callApi(method, path, body) {
|
|
125003
|
+
const res = await fetch(trustEndpoint(path), {
|
|
125004
|
+
method,
|
|
125005
|
+
headers: authHeaders(),
|
|
125006
|
+
body: body === undefined ? undefined : JSON.stringify(body)
|
|
125007
|
+
});
|
|
125008
|
+
if (!res.ok) {
|
|
125009
|
+
const text3 = await res.text().catch(() => "");
|
|
125010
|
+
throw new Error(`HTTP ${res.status} ${res.statusText}${text3 ? `: ${text3}` : ""}`);
|
|
125011
|
+
}
|
|
125012
|
+
return await res.json();
|
|
125013
|
+
}
|
|
125014
|
+
function formatHostRow(host) {
|
|
125015
|
+
return {
|
|
125016
|
+
id: host.id.slice(0, 8),
|
|
125017
|
+
hostname: host.hostname,
|
|
125018
|
+
scopes: host.scopes.join(", ") || "(none)",
|
|
125019
|
+
pubkeyPrefix: `${host.pubkey.slice(0, 12)}\u2026`,
|
|
125020
|
+
lastSeen: host.lastSeenAt ? new Date(host.lastSeenAt).toISOString().replace("T", " ").slice(0, 16) : "never",
|
|
125021
|
+
status: host.revokedAt ? "revoked" : "active"
|
|
125022
|
+
};
|
|
125023
|
+
}
|
|
125024
|
+
async function handleList4() {
|
|
125025
|
+
try {
|
|
125026
|
+
const { items } = await callApi("GET", "/hosts");
|
|
125027
|
+
list(items.map(formatHostRow), {
|
|
125028
|
+
emptyMessage: "No genie hosts registered. Run `genie omni handshake` from a genie installation to register one.",
|
|
125029
|
+
rawData: items
|
|
125030
|
+
});
|
|
125031
|
+
} catch (err2) {
|
|
125032
|
+
error(`Failed to list genie hosts: ${err2 instanceof Error ? err2.message : "Unknown error"}`);
|
|
125033
|
+
}
|
|
125034
|
+
}
|
|
125035
|
+
async function handleGet3(id) {
|
|
125036
|
+
try {
|
|
125037
|
+
const { data: data2 } = await callApi("GET", `/hosts/${encodeURIComponent(id)}`);
|
|
125038
|
+
data(data2);
|
|
125039
|
+
} catch (err2) {
|
|
125040
|
+
error(`Failed to get genie host: ${err2 instanceof Error ? err2.message : "Unknown error"}`);
|
|
125041
|
+
}
|
|
125042
|
+
}
|
|
125043
|
+
async function handleUpdate3(id, options3) {
|
|
125044
|
+
const scopes = options3.scope.split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
125045
|
+
if (scopes.length === 0) {
|
|
125046
|
+
error("--scope must contain at least one scope (use `omni trust revoke <id>` to deny everything).");
|
|
125047
|
+
}
|
|
125048
|
+
try {
|
|
125049
|
+
const { data: data2 } = await callApi("PATCH", `/hosts/${encodeURIComponent(id)}`, { scopes });
|
|
125050
|
+
success(`Updated genie host ${data2.id} scopes: ${data2.scopes.join(", ")}`);
|
|
125051
|
+
data(data2);
|
|
125052
|
+
} catch (err2) {
|
|
125053
|
+
error(`Failed to update genie host: ${err2 instanceof Error ? err2.message : "Unknown error"}`);
|
|
125054
|
+
}
|
|
125055
|
+
}
|
|
125056
|
+
async function handleRevoke2(id) {
|
|
125057
|
+
try {
|
|
125058
|
+
const { data: data2 } = await callApi("DELETE", `/hosts/${encodeURIComponent(id)}`);
|
|
125059
|
+
success(`Revoked genie host ${data2.id} (${data2.hostname}). Tombstone kept for audit.`);
|
|
125060
|
+
data(data2);
|
|
125061
|
+
} catch (err2) {
|
|
125062
|
+
error(`Failed to revoke genie host: ${err2 instanceof Error ? err2.message : "Unknown error"}`);
|
|
125063
|
+
}
|
|
125064
|
+
}
|
|
125065
|
+
function createTrustCommand() {
|
|
125066
|
+
const trust = new Command("trust").description("Manage genie host fingerprint registrations");
|
|
125067
|
+
trust.command("list").description("List active (non-revoked) genie hosts").action(handleList4);
|
|
125068
|
+
trust.command("get <id>").description("Show details for one genie host (active or revoked)").action(handleGet3);
|
|
125069
|
+
trust.command("update <id>").description("Replace a genie host scopes (comma-separated)").requiredOption("--scope <list>", 'Comma-separated scope list, e.g. "agents:write,providers:write"').action(handleUpdate3);
|
|
125070
|
+
trust.command("revoke <id>").description("Revoke a genie host (irreversible \u2014 re-register with a fresh keypair to restore trust)").action(handleRevoke2);
|
|
125071
|
+
return trust;
|
|
125072
|
+
}
|
|
125073
|
+
|
|
124983
125074
|
// src/commands/tts.ts
|
|
124984
125075
|
init_output();
|
|
124985
125076
|
function createTtsCommand() {
|
|
@@ -126213,6 +126304,12 @@ var COMMANDS = [
|
|
|
126213
126304
|
helpGroup: "Management",
|
|
126214
126305
|
helpDescription: "API key management"
|
|
126215
126306
|
},
|
|
126307
|
+
{
|
|
126308
|
+
create: createTrustCommand,
|
|
126309
|
+
category: "advanced",
|
|
126310
|
+
helpGroup: "Management",
|
|
126311
|
+
helpDescription: "Genie host fingerprint trust (omni-host-fingerprint-trust wish)"
|
|
126312
|
+
},
|
|
126216
126313
|
{
|
|
126217
126314
|
create: createAccessCommand,
|
|
126218
126315
|
category: "advanced",
|
package/dist/server/index.js
CHANGED
|
@@ -224556,7 +224556,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
224556
224556
|
var require_package8 = __commonJS((exports, module) => {
|
|
224557
224557
|
module.exports = {
|
|
224558
224558
|
name: "@omni/api",
|
|
224559
|
-
version: "2.260430.
|
|
224559
|
+
version: "2.260430.4",
|
|
224560
224560
|
type: "module",
|
|
224561
224561
|
exports: {
|
|
224562
224562
|
".": {
|
|
@@ -281176,6 +281176,21 @@ class GenieHostsService {
|
|
|
281176
281176
|
async touchLastSeen(id) {
|
|
281177
281177
|
await this.db.update(genieHosts).set({ lastSeenAt: new Date, updatedAt: new Date }).where(and2(eq(genieHosts.id, id), isNull2(genieHosts.revokedAt)));
|
|
281178
281178
|
}
|
|
281179
|
+
async updateScopes(id, scopes) {
|
|
281180
|
+
const [updated] = await this.db.update(genieHosts).set({ scopes, updatedAt: new Date }).where(and2(eq(genieHosts.id, id), isNull2(genieHosts.revokedAt))).returning();
|
|
281181
|
+
if (updated) {
|
|
281182
|
+
log87.info("genie host scopes updated", { hostId: updated.id, scopes });
|
|
281183
|
+
}
|
|
281184
|
+
return updated ?? null;
|
|
281185
|
+
}
|
|
281186
|
+
async revoke(id) {
|
|
281187
|
+
const now = new Date;
|
|
281188
|
+
const [revoked] = await this.db.update(genieHosts).set({ revokedAt: now, updatedAt: now }).where(and2(eq(genieHosts.id, id), isNull2(genieHosts.revokedAt))).returning();
|
|
281189
|
+
if (revoked) {
|
|
281190
|
+
log87.info("genie host revoked", { hostId: revoked.id, hostname: revoked.hostname });
|
|
281191
|
+
}
|
|
281192
|
+
return revoked ?? null;
|
|
281193
|
+
}
|
|
281179
281194
|
}
|
|
281180
281195
|
var log87;
|
|
281181
281196
|
var init_genie_hosts = __esm(() => {
|
|
@@ -302631,7 +302646,7 @@ var init_settings3 = __esm(() => {
|
|
|
302631
302646
|
});
|
|
302632
302647
|
|
|
302633
302648
|
// ../api/src/routes/v2/trust.ts
|
|
302634
|
-
var trustRoutes, PUBKEY_PATTERN, handshakeSchema;
|
|
302649
|
+
var trustRoutes, PUBKEY_PATTERN, handshakeSchema, idParamSchema6, updateScopesSchema;
|
|
302635
302650
|
var init_trust = __esm(() => {
|
|
302636
302651
|
init_dist6();
|
|
302637
302652
|
init_dist2();
|
|
@@ -302658,6 +302673,38 @@ var init_trust = __esm(() => {
|
|
|
302658
302673
|
const items = await services.genieHosts.listActive();
|
|
302659
302674
|
return c.json({ items });
|
|
302660
302675
|
});
|
|
302676
|
+
idParamSchema6 = exports_external.object({ id: exports_external.string().uuid() });
|
|
302677
|
+
trustRoutes.get("/hosts/:id", zValidator("param", idParamSchema6), async (c) => {
|
|
302678
|
+
const { id } = c.req.valid("param");
|
|
302679
|
+
const services = c.get("services");
|
|
302680
|
+
const host = await services.genieHosts.findById(id);
|
|
302681
|
+
if (!host) {
|
|
302682
|
+
return c.json({ error: { code: "NOT_FOUND", message: `genie host ${id} not found` } }, 404);
|
|
302683
|
+
}
|
|
302684
|
+
return c.json({ data: host });
|
|
302685
|
+
});
|
|
302686
|
+
updateScopesSchema = exports_external.object({
|
|
302687
|
+
scopes: exports_external.array(exports_external.string().min(1)).max(64)
|
|
302688
|
+
});
|
|
302689
|
+
trustRoutes.patch("/hosts/:id", zValidator("param", idParamSchema6), zValidator("json", updateScopesSchema), async (c) => {
|
|
302690
|
+
const { id } = c.req.valid("param");
|
|
302691
|
+
const { scopes } = c.req.valid("json");
|
|
302692
|
+
const services = c.get("services");
|
|
302693
|
+
const host = await services.genieHosts.updateScopes(id, scopes);
|
|
302694
|
+
if (!host) {
|
|
302695
|
+
return c.json({ error: { code: "NOT_FOUND", message: `genie host ${id} not found or revoked` } }, 404);
|
|
302696
|
+
}
|
|
302697
|
+
return c.json({ data: host });
|
|
302698
|
+
});
|
|
302699
|
+
trustRoutes.delete("/hosts/:id", zValidator("param", idParamSchema6), async (c) => {
|
|
302700
|
+
const { id } = c.req.valid("param");
|
|
302701
|
+
const services = c.get("services");
|
|
302702
|
+
const host = await services.genieHosts.revoke(id);
|
|
302703
|
+
if (!host) {
|
|
302704
|
+
return c.json({ error: { code: "NOT_FOUND", message: `genie host ${id} not found or already revoked` } }, 404);
|
|
302705
|
+
}
|
|
302706
|
+
return c.json({ data: host });
|
|
302707
|
+
});
|
|
302661
302708
|
});
|
|
302662
302709
|
|
|
302663
302710
|
// ../api/src/routes/v2/turns.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automagik/omni",
|
|
3
|
-
"version": "2.260430.
|
|
3
|
+
"version": "2.260430.4",
|
|
4
4
|
"description": "LLM-optimized CLI for Omni",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,15 +50,15 @@
|
|
|
50
50
|
"qrcode-terminal": "^0.12.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@omni/api": "2.260430.
|
|
54
|
-
"@omni/channel-discord": "2.260430.
|
|
55
|
-
"@omni/channel-gupshup": "2.260430.
|
|
56
|
-
"@omni/channel-sdk": "2.260430.
|
|
57
|
-
"@omni/channel-slack": "2.260430.
|
|
58
|
-
"@omni/channel-telegram": "2.260430.
|
|
59
|
-
"@omni/channel-whatsapp": "2.260430.
|
|
60
|
-
"@omni/core": "2.260430.
|
|
61
|
-
"@omni/sdk": "2.260430.
|
|
53
|
+
"@omni/api": "2.260430.3",
|
|
54
|
+
"@omni/channel-discord": "2.260430.3",
|
|
55
|
+
"@omni/channel-gupshup": "2.260430.3",
|
|
56
|
+
"@omni/channel-sdk": "2.260430.3",
|
|
57
|
+
"@omni/channel-slack": "2.260430.3",
|
|
58
|
+
"@omni/channel-telegram": "2.260430.3",
|
|
59
|
+
"@omni/channel-whatsapp": "2.260430.3",
|
|
60
|
+
"@omni/core": "2.260430.3",
|
|
61
|
+
"@omni/sdk": "2.260430.3",
|
|
62
62
|
"@types/node": "^22.10.3",
|
|
63
63
|
"@types/qrcode-terminal": "^0.12.2",
|
|
64
64
|
"typescript": "^5.7.3"
|