siftctl 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -24,6 +24,17 @@ export async function capabilities() {
24
24
  throw new ApiError(`Capabilities failed: ${res.status}`, res.status);
25
25
  return (await res.json());
26
26
  }
27
+ export async function groupStatus(token) {
28
+ const res = await request('/sync/status', { token });
29
+ if (res.status === 404)
30
+ return { groupFingerprint: null }; // server predates the endpoint
31
+ if (res.status === 401)
32
+ throw new ApiError('Unauthorized — token revoked or invalid; run `siftctl pair` again', 401);
33
+ if (!res.ok)
34
+ throw new ApiError(`Status failed: ${res.status}`, res.status);
35
+ const body = (await res.json());
36
+ return { groupFingerprint: typeof body.groupFingerprint === 'string' ? body.groupFingerprint : null };
37
+ }
27
38
  export async function redeemToken(code) {
28
39
  const res = await request('/sync/tokens/redeem', {
29
40
  method: 'POST',
package/dist/cli.js CHANGED
@@ -2,14 +2,14 @@
2
2
  import { realpathSync } from 'node:fs';
3
3
  import { pathToFileURL } from 'node:url';
4
4
  import { baseUrl, readToken, writeToken } from './config.js';
5
- import { ApiError, capabilities, pull, push, redeemToken } from './api.js';
5
+ import { ApiError, capabilities, groupStatus, pull, push, redeemToken } from './api.js';
6
6
  import { tokenFingerprint } from './fingerprint.js';
7
7
  import { fetchItems } from './items.js';
8
8
  const USAGE = `siftctl — control your Sift subscriptions
9
9
 
10
10
  Usage:
11
11
  siftctl pair <code> Redeem an agent pairing code from Sift Settings
12
- siftctl status [--json] Show API status, base URL, and token fingerprint
12
+ siftctl status [--json] Show API status, base URL, group code, and token fingerprint
13
13
  siftctl feeds [--json] List subscribed feeds
14
14
  siftctl feed add <url> Subscribe to a feed
15
15
  siftctl feed remove <url> --yes Unsubscribe from a feed
@@ -56,12 +56,21 @@ async function cmdStatus(json) {
56
56
  const cap = await capabilities();
57
57
  const token = readToken();
58
58
  if (json) {
59
- out({ sync: cap.sync, url: baseUrl(), paired: token !== null, fingerprint: token ? await tokenFingerprint(token) : null });
59
+ out({
60
+ sync: cap.sync,
61
+ url: baseUrl(),
62
+ paired: token !== null,
63
+ groupFingerprint: token ? (await groupStatus(token)).groupFingerprint : null,
64
+ fingerprint: token ? await tokenFingerprint(token) : null,
65
+ });
60
66
  return;
61
67
  }
62
68
  console.log(`Sync: ${cap.sync ? 'available' : 'unavailable'}`);
63
69
  console.log(`URL: ${baseUrl()}`);
64
70
  if (token) {
71
+ const group = (await groupStatus(token)).groupFingerprint;
72
+ if (group)
73
+ console.log(`Group: ${group}`);
65
74
  console.log(`Paired: yes (fingerprint ${await tokenFingerprint(token)})`);
66
75
  }
67
76
  else {
@@ -1,3 +1,4 @@
1
+ import { webcrypto } from 'node:crypto';
1
2
  /** Crockford base32 alphabet (0-9 and A-Z minus I, L, O, U). */
2
3
  const CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
3
4
  /**
@@ -6,7 +7,7 @@ const CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
6
7
  * so `siftctl status` shows the same string as the Settings agents list.
7
8
  */
8
9
  export async function tokenFingerprint(token) {
9
- const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(token));
10
+ const digest = await webcrypto.subtle.digest('SHA-256', new TextEncoder().encode(token));
10
11
  const bytes = new Uint8Array(digest);
11
12
  const value = ((bytes[0] << 16) | (bytes[1] << 8) | bytes[2]) & 0xFFFFF;
12
13
  return (CROCKFORD[(value >> 15) & 31] +
package/package.json CHANGED
@@ -26,5 +26,5 @@
26
26
  "build": "tsc -p tsconfig.json"
27
27
  },
28
28
  "type": "module",
29
- "version": "0.55.0"
29
+ "version": "0.56.0"
30
30
  }