sello 0.1.4 → 0.1.5

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/cli/sello.js CHANGED
@@ -44,6 +44,25 @@ import { createSelloService } from "../sdk/service.js";
44
44
 
45
45
 
46
46
 
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
47
66
 
48
67
 
49
68
  const textEncoder = new TextEncoder();
@@ -285,16 +304,17 @@ async function handleDevRequest(input
285
304
  const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
286
305
 
287
306
  if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/actions")) {
288
- const result = verifyReceipts({
289
- authorizationTokenBytes: textEncoder.encode(state.agentToken),
290
- trustedLogs: [log],
291
- registry,
292
- ownerPrivateKey: normalizeHpkePrivateKey(state.ownerKey),
293
- });
307
+ const result = verifyDevActions({ log, state, registry });
294
308
  sendHtml(response, renderActionsHtml(result));
295
309
  return;
296
310
  }
297
311
 
312
+ if (request.method === "GET" && url.pathname === "/api/actions") {
313
+ const result = verifyDevActions({ log, state, registry });
314
+ sendJson(response, 200, actionsViewModel(result));
315
+ return;
316
+ }
317
+
298
318
  if (request.method === "POST" && url.pathname === "/api/entries") {
299
319
  const body = await readJson(request);
300
320
  if (!isRecord(body) || typeof body.envelope !== "string") {
@@ -326,6 +346,19 @@ async function handleDevRequest(input
326
346
  sendJson(response, 404, { error: "not found" });
327
347
  }
328
348
 
349
+ function verifyDevActions(input
350
+
351
+
352
+
353
+ ) {
354
+ return verifyReceipts({
355
+ authorizationTokenBytes: textEncoder.encode(input.state.agentToken),
356
+ trustedLogs: [input.log],
357
+ registry: input.registry,
358
+ ownerPrivateKey: normalizeHpkePrivateKey(input.state.ownerKey),
359
+ });
360
+ }
361
+
329
362
  async function loadViewerRegistry(devState ) {
330
363
  if (process.env.SELLO_REGISTRY_PATH) {
331
364
  return parseRegistry(readFileBytes(process.env.SELLO_REGISTRY_PATH));
@@ -461,16 +494,38 @@ function printActions(result ) {
461
494
  }
462
495
  }
463
496
 
497
+ function actionsViewModel(result ) {
498
+ return {
499
+ receipts: result.receipts.map((record) => ({
500
+ integratedTime: record.integratedTime,
501
+ serviceIdentifier: record.serviceIdentifier,
502
+ actionType: record.receipt["action-type"],
503
+ resultStatus: record.receipt["result-status"],
504
+ status: record.status,
505
+ logUrl: record.logUrl,
506
+ logCompleteness: record.logCompleteness,
507
+ sameSecondActivity: record.sameSecondActivity,
508
+ })),
509
+ rejected: result.rejected.map((record) => ({
510
+ code: record.code,
511
+ message: record.message,
512
+ ...(record.logUrl === undefined ? {} : { logUrl: record.logUrl }),
513
+ ...(record.integratedTime === undefined ? {} : { integratedTime: record.integratedTime }),
514
+ })),
515
+ };
516
+ }
517
+
464
518
  function renderActionsHtml(result ) {
465
- const rows = result.receipts.map((record) => `
519
+ const view = actionsViewModel(result);
520
+ const rows = view.receipts.map((record) => `
466
521
  <tr>
467
522
  <td>${escapeHtml(record.integratedTime)}</td>
468
523
  <td>${escapeHtml(record.serviceIdentifier)}</td>
469
- <td>${escapeHtml(record.receipt["action-type"])}</td>
470
- <td>${escapeHtml(record.receipt["result-status"])}</td>
524
+ <td>${escapeHtml(record.actionType)}</td>
525
+ <td>${escapeHtml(record.resultStatus)}</td>
471
526
  <td>${escapeHtml(record.status)}</td>
472
527
  </tr>`).join("");
473
- const rejected = result.rejected.map((record) => `
528
+ const rejected = view.rejected.map((record) => `
474
529
  <li><strong>${escapeHtml(record.code)}</strong>: ${escapeHtml(record.message)}</li>`).join("");
475
530
 
476
531
  return `<!doctype html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sello",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Reference implementation of the Sello protocol for service-signed AI agent receipts.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/cli/sello.ts CHANGED
@@ -47,6 +47,25 @@ type DevState = {
47
47
  registryJson: string;
48
48
  };
49
49
 
50
+ type ActionsViewModel = {
51
+ receipts: {
52
+ integratedTime: string;
53
+ serviceIdentifier: string;
54
+ actionType: string;
55
+ resultStatus: string;
56
+ status: string;
57
+ logUrl: string;
58
+ logCompleteness: string;
59
+ sameSecondActivity: boolean;
60
+ }[];
61
+ rejected: {
62
+ code: string;
63
+ message: string;
64
+ logUrl?: string;
65
+ integratedTime?: string;
66
+ }[];
67
+ };
68
+
50
69
  const textEncoder = new TextEncoder();
51
70
  const textDecoder = new TextDecoder();
52
71
  const command = process.argv[2] ?? "help";
@@ -286,16 +305,17 @@ async function handleDevRequest(input: {
286
305
  const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
287
306
 
288
307
  if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/actions")) {
289
- const result = verifyReceipts({
290
- authorizationTokenBytes: textEncoder.encode(state.agentToken),
291
- trustedLogs: [log],
292
- registry,
293
- ownerPrivateKey: normalizeHpkePrivateKey(state.ownerKey),
294
- });
308
+ const result = verifyDevActions({ log, state, registry });
295
309
  sendHtml(response, renderActionsHtml(result));
296
310
  return;
297
311
  }
298
312
 
313
+ if (request.method === "GET" && url.pathname === "/api/actions") {
314
+ const result = verifyDevActions({ log, state, registry });
315
+ sendJson(response, 200, actionsViewModel(result));
316
+ return;
317
+ }
318
+
299
319
  if (request.method === "POST" && url.pathname === "/api/entries") {
300
320
  const body = await readJson(request);
301
321
  if (!isRecord(body) || typeof body.envelope !== "string") {
@@ -327,6 +347,19 @@ async function handleDevRequest(input: {
327
347
  sendJson(response, 404, { error: "not found" });
328
348
  }
329
349
 
350
+ function verifyDevActions(input: {
351
+ log: MockTransparencyLog;
352
+ state: DevState;
353
+ registry: ReturnType<typeof parseRegistry>;
354
+ }): ReturnType<typeof verifyReceipts> {
355
+ return verifyReceipts({
356
+ authorizationTokenBytes: textEncoder.encode(input.state.agentToken),
357
+ trustedLogs: [input.log],
358
+ registry: input.registry,
359
+ ownerPrivateKey: normalizeHpkePrivateKey(input.state.ownerKey),
360
+ });
361
+ }
362
+
330
363
  async function loadViewerRegistry(devState: DevState | undefined) {
331
364
  if (process.env.SELLO_REGISTRY_PATH) {
332
365
  return parseRegistry(readFileBytes(process.env.SELLO_REGISTRY_PATH));
@@ -462,16 +495,38 @@ function printActions(result: ReturnType<typeof verifyReceipts>): void {
462
495
  }
463
496
  }
464
497
 
498
+ function actionsViewModel(result: ReturnType<typeof verifyReceipts>): ActionsViewModel {
499
+ return {
500
+ receipts: result.receipts.map((record) => ({
501
+ integratedTime: record.integratedTime,
502
+ serviceIdentifier: record.serviceIdentifier,
503
+ actionType: record.receipt["action-type"],
504
+ resultStatus: record.receipt["result-status"],
505
+ status: record.status,
506
+ logUrl: record.logUrl,
507
+ logCompleteness: record.logCompleteness,
508
+ sameSecondActivity: record.sameSecondActivity,
509
+ })),
510
+ rejected: result.rejected.map((record) => ({
511
+ code: record.code,
512
+ message: record.message,
513
+ ...(record.logUrl === undefined ? {} : { logUrl: record.logUrl }),
514
+ ...(record.integratedTime === undefined ? {} : { integratedTime: record.integratedTime }),
515
+ })),
516
+ };
517
+ }
518
+
465
519
  function renderActionsHtml(result: ReturnType<typeof verifyReceipts>): string {
466
- const rows = result.receipts.map((record) => `
520
+ const view = actionsViewModel(result);
521
+ const rows = view.receipts.map((record) => `
467
522
  <tr>
468
523
  <td>${escapeHtml(record.integratedTime)}</td>
469
524
  <td>${escapeHtml(record.serviceIdentifier)}</td>
470
- <td>${escapeHtml(record.receipt["action-type"])}</td>
471
- <td>${escapeHtml(record.receipt["result-status"])}</td>
525
+ <td>${escapeHtml(record.actionType)}</td>
526
+ <td>${escapeHtml(record.resultStatus)}</td>
472
527
  <td>${escapeHtml(record.status)}</td>
473
528
  </tr>`).join("");
474
- const rejected = result.rejected.map((record) => `
529
+ const rejected = view.rejected.map((record) => `
475
530
  <li><strong>${escapeHtml(record.code)}</strong>: ${escapeHtml(record.message)}</li>`).join("");
476
531
 
477
532
  return `<!doctype html>