@alva-ai/toolkit 0.3.1 → 0.4.1

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.js CHANGED
@@ -252,7 +252,8 @@ var ReleaseResource = class {
252
252
  version: params.version,
253
253
  cronjob_id: params.cronjob_id,
254
254
  view_json: params.view_json,
255
- description: params.description
255
+ description: params.description,
256
+ changelog: params.changelog
256
257
  }
257
258
  });
258
259
  }
@@ -264,8 +265,7 @@ var ReleaseResource = class {
264
265
  display_name: params.display_name,
265
266
  description: params.description,
266
267
  feeds: params.feeds,
267
- trading_symbols: params.trading_symbols,
268
- changelog: params.changelog
268
+ trading_symbols: params.trading_symbols
269
269
  }
270
270
  });
271
271
  }
@@ -577,6 +577,127 @@ var ArraysJwtResource = class {
577
577
  }
578
578
  };
579
579
 
580
+ // src/resources/notifications.ts
581
+ var NotificationsResource = class {
582
+ constructor(client) {
583
+ this.client = client;
584
+ }
585
+ client;
586
+ /**
587
+ * List the caller's notification history for one playbook
588
+ * `(username, name)`. Returns `NOT_FOUND` when the playbook is
589
+ * private or does not exist (the two cases are deliberately
590
+ * indistinguishable to prevent namespace enumeration).
591
+ */
592
+ async listPlaybook(params) {
593
+ this.client._requireAuth();
594
+ const path = `/api/v1/playbook/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/notifications`;
595
+ return this.client._request("GET", path, {
596
+ query: buildQuery(params)
597
+ });
598
+ }
599
+ /**
600
+ * List the caller's notification history for one feed
601
+ * `(username, name)`. Authorization is alfs read on
602
+ * `/alva/home/<username>/feeds/<name>`.
603
+ */
604
+ async listFeed(params) {
605
+ this.client._requireAuth();
606
+ const path = `/api/v1/feed/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/notifications`;
607
+ return this.client._request("GET", path, {
608
+ query: buildQuery(params)
609
+ });
610
+ }
611
+ };
612
+ function buildQuery(params) {
613
+ const q = {};
614
+ if (params.channel) q.channel = params.channel;
615
+ if (params.status) q.status = params.status;
616
+ if (params.since_time !== void 0 && params.since_time > 0) {
617
+ q.since_time = String(params.since_time);
618
+ }
619
+ if (params.first !== void 0 && params.first > 0) {
620
+ q.first = String(params.first);
621
+ }
622
+ if (params.cursor) q.cursor = params.cursor;
623
+ return q;
624
+ }
625
+
626
+ // src/resources/pushSubscriptions.ts
627
+ var PushSubscriptionsResource = class {
628
+ constructor(client) {
629
+ this.client = client;
630
+ }
631
+ client;
632
+ /**
633
+ * Opt into personal push for one playbook `(username, name)`.
634
+ * Fires for any feed of that playbook. Idempotent. Auth: callers must
635
+ * be able to read the playbook (public/paid pass; private requires
636
+ * explicit alfs grant).
637
+ */
638
+ async subscribePlaybook(params) {
639
+ this.client._requireAuth();
640
+ const path = `/api/v1/playbook/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/push-subscription`;
641
+ return this.client._request(
642
+ "POST",
643
+ path
644
+ );
645
+ }
646
+ /**
647
+ * Soft-disable personal push for one playbook `(username, name)`.
648
+ * Does NOT remove any social follow. Idempotent.
649
+ */
650
+ async unsubscribePlaybook(params) {
651
+ this.client._requireAuth();
652
+ const path = `/api/v1/playbook/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/push-subscription`;
653
+ return this.client._request(
654
+ "DELETE",
655
+ path
656
+ );
657
+ }
658
+ /**
659
+ * Opt into personal push for one feed `(username, name)`. Fires for
660
+ * that specific feed regardless of which playbook(s) consume it; if
661
+ * the feed is shared across playbooks the subscriber receives one
662
+ * push per playbook context. Idempotent.
663
+ */
664
+ async subscribeFeed(params) {
665
+ this.client._requireAuth();
666
+ const path = `/api/v1/feed/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/push-subscription`;
667
+ return this.client._request(
668
+ "POST",
669
+ path
670
+ );
671
+ }
672
+ /**
673
+ * Soft-disable personal push for one feed `(username, name)`.
674
+ * Idempotent.
675
+ */
676
+ async unsubscribeFeed(params) {
677
+ this.client._requireAuth();
678
+ const path = `/api/v1/feed/${encodeURIComponent(params.username)}/${encodeURIComponent(params.name)}/push-subscription`;
679
+ return this.client._request(
680
+ "DELETE",
681
+ path
682
+ );
683
+ }
684
+ /**
685
+ * List the caller's personal push subscriptions across all targets
686
+ * (playbook + feed). Defaults to currently-active rows only; pass
687
+ * `include_history=true` to also return previously-unsubscribed rows.
688
+ */
689
+ async list(params = {}) {
690
+ this.client._requireAuth();
691
+ const query = {};
692
+ if (params.include_history !== void 0) {
693
+ query.include_history = String(params.include_history);
694
+ }
695
+ return this.client._request("GET", "/api/v1/me/push-subscriptions", {
696
+ query
697
+ });
698
+ }
699
+ };
700
+
580
701
  // src/client.ts
581
702
  var DEFAULT_BASE_URL = "https://api-llm.prd.alva.ai";
582
703
  var DEFAULT_ARRAYS_BASE_URL = "https://data-tools.prd.space.id";
@@ -598,6 +719,8 @@ var AlvaClient = class {
598
719
  _user;
599
720
  _trading;
600
721
  _arraysJwt;
722
+ _notifications;
723
+ _pushSubscriptions;
601
724
  constructor(config) {
602
725
  this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
603
726
  this.arraysBaseUrl = config.arraysBaseUrl ?? DEFAULT_ARRAYS_BASE_URL;
@@ -643,6 +766,12 @@ var AlvaClient = class {
643
766
  get arraysJwt() {
644
767
  return this._arraysJwt ??= new ArraysJwtResource(this);
645
768
  }
769
+ get notifications() {
770
+ return this._notifications ??= new NotificationsResource(this);
771
+ }
772
+ get pushSubscriptions() {
773
+ return this._pushSubscriptions ??= new PushSubscriptionsResource(this);
774
+ }
646
775
  _requireAuth() {
647
776
  if (!this.viewer_token && !this.apiKey) {
648
777
  throw new AlvaError(
@@ -1002,7 +1131,7 @@ async function runPostConfigureHooks(client, deps) {
1002
1131
  import * as fs from "fs";
1003
1132
  import * as os2 from "os";
1004
1133
  import * as fsPromises2 from "fs/promises";
1005
- var CLI_VERSION = true ? "0.3.1" : "dev";
1134
+ var CLI_VERSION = true ? "0.4.1" : "dev";
1006
1135
  function isVersionOlderThan(a, b) {
1007
1136
  const parse = (v) => {
1008
1137
  if (!v) return null;
@@ -1034,6 +1163,7 @@ Commands:
1034
1163
  sdk SDK documentation (doc, partitions, partition-summary)
1035
1164
  skills Data-skill documentation from the Arrays backend (list, summary, endpoint)
1036
1165
  comments Playbook comments (create, pin, unpin)
1166
+ push-subscriptions Personal push opt-in (subscribe-playbook, unsubscribe-playbook, subscribe-feed, unsubscribe-feed, list)
1037
1167
  remix Save playbook remix lineage
1038
1168
  trading Trading operations (accounts, portfolio, orders, subscriptions, equity-history, risk-rules, subscribe, unsubscribe, execute, update-risk-rules)
1039
1169
  auth Authentication (login)
@@ -1312,12 +1442,12 @@ Feed flags:
1312
1442
  --cronjob-id <id> ID of the backing cronjob (required)
1313
1443
  --view-json <json> View configuration JSON
1314
1444
  --description <text> Feed description
1445
+ --changelog <text> Per-major changelog summary
1315
1446
 
1316
1447
  Playbook-draft flags:
1317
1448
  --name <name> URL-safe playbook name, unique per user (required)
1318
1449
  --display-name <name> Human-readable title, max 40 chars (required)
1319
1450
  --feeds <json> JSON array of {feed_id, feed_major?} (required)
1320
- --changelog <text> Release changelog
1321
1451
  --description <text> Playbook description
1322
1452
  --trading-symbols <json> JSON array of tickers, e.g. '["BTC","ETH"]' (max 50)
1323
1453
 
@@ -1336,7 +1466,7 @@ Display name conventions:
1336
1466
  Examples:
1337
1467
  alva release feed --name btc-ema --version 1.0.0 --cronjob-id 42
1338
1468
  alva release feed --name nvda-insiders --version 1.0.0 --cronjob-id 43 --description "NVDA insider trading activity"
1339
- alva release playbook-draft --name btc-dashboard --display-name "BTC Trend Dashboard" --feeds '[{"feed_id":100}]' --changelog "Initial release" --trading-symbols '["BTC"]'
1469
+ alva release playbook-draft --name btc-dashboard --display-name "BTC Trend Dashboard" --feeds '[{"feed_id":100}]' --trading-symbols '["BTC"]'
1340
1470
  alva release playbook --name btc-dashboard --version v1.0.0 --feeds '[{"feed_id":100}]' --changelog "Initial release"`,
1341
1471
  secrets: `Usage: alva secrets <subcommand> [options]
1342
1472
 
@@ -1441,6 +1571,32 @@ Examples:
1441
1571
  alva comments create --username alice --name btc-dashboard --content "Thanks!" --parent-id 5
1442
1572
  alva comments pin --comment-id 12
1443
1573
  alva comments unpin --comment-id 12`,
1574
+ "push-subscriptions": `Usage: alva push-subscriptions <subcommand> [options]
1575
+
1576
+ Personal opt-in for DM/web push notifications. Independent of social
1577
+ follow: subscribing does not start following, unsubscribing does not
1578
+ unfollow. Following a playbook elsewhere will compound-subscribe
1579
+ automatically.
1580
+
1581
+ Subcommands:
1582
+ subscribe-playbook Opt into push for a playbook (any of its feeds)
1583
+ unsubscribe-playbook Opt out of push for a playbook (soft-disable)
1584
+ subscribe-feed Opt into push for a single feed
1585
+ unsubscribe-feed Opt out of push for a single feed (soft-disable)
1586
+ list List the caller's push subscriptions
1587
+
1588
+ Subscribe/unsubscribe flags (playbook + feed):
1589
+ --username <user> Owner's username (required)
1590
+ --name <name> URL-safe playbook or feed name (required)
1591
+
1592
+ List flags:
1593
+ --include-history Also return rows previously unsubscribed (default: false)
1594
+
1595
+ Examples:
1596
+ alva push-subscriptions subscribe-playbook --username alice --name btc-dashboard
1597
+ alva push-subscriptions subscribe-feed --username alice --name btc-ema-cross
1598
+ alva push-subscriptions unsubscribe-feed --username alice --name btc-ema-cross
1599
+ alva push-subscriptions list --include-history`,
1444
1600
  remix: `Usage: alva remix --child-username <u> --child-name <n> --parents <json>
1445
1601
 
1446
1602
  Record remix lineage when creating a playbook based on existing playbooks.
@@ -1877,7 +2033,8 @@ async function dispatch(client, args, meta) {
1877
2033
  version: requireFlag(flags, "version", "release feed"),
1878
2034
  cronjob_id: requireNumericFlag(flags, "cronjob-id", "release feed"),
1879
2035
  view_json: jsonParse(flags["view-json"]),
1880
- description: flags["description"]
2036
+ description: flags["description"],
2037
+ changelog: flags["changelog"]
1881
2038
  });
1882
2039
  case "playbook-draft":
1883
2040
  return client.release.playbookDraft({
@@ -1891,8 +2048,7 @@ async function dispatch(client, args, meta) {
1891
2048
  feeds: jsonParse(
1892
2049
  requireFlag(flags, "feeds", "release playbook-draft")
1893
2050
  ),
1894
- trading_symbols: flags["trading-symbols"] ? jsonParse(flags["trading-symbols"]) : void 0,
1895
- changelog: flags["changelog"]
2051
+ trading_symbols: flags["trading-symbols"] ? jsonParse(flags["trading-symbols"]) : void 0
1896
2052
  });
1897
2053
  case "playbook":
1898
2054
  return client.release.playbook({
@@ -2014,6 +2170,76 @@ async function dispatch(client, args, meta) {
2014
2170
  );
2015
2171
  }
2016
2172
  }
2173
+ case "push-subscriptions": {
2174
+ if (!subcommand)
2175
+ throw new CliUsageError(
2176
+ "Missing subcommand for push-subscriptions",
2177
+ "push-subscriptions"
2178
+ );
2179
+ switch (subcommand) {
2180
+ case "subscribe-playbook":
2181
+ return client.pushSubscriptions.subscribePlaybook({
2182
+ username: requireFlag(
2183
+ flags,
2184
+ "username",
2185
+ "push-subscriptions subscribe-playbook"
2186
+ ),
2187
+ name: requireFlag(
2188
+ flags,
2189
+ "name",
2190
+ "push-subscriptions subscribe-playbook"
2191
+ )
2192
+ });
2193
+ case "unsubscribe-playbook":
2194
+ return client.pushSubscriptions.unsubscribePlaybook({
2195
+ username: requireFlag(
2196
+ flags,
2197
+ "username",
2198
+ "push-subscriptions unsubscribe-playbook"
2199
+ ),
2200
+ name: requireFlag(
2201
+ flags,
2202
+ "name",
2203
+ "push-subscriptions unsubscribe-playbook"
2204
+ )
2205
+ });
2206
+ case "subscribe-feed":
2207
+ return client.pushSubscriptions.subscribeFeed({
2208
+ username: requireFlag(
2209
+ flags,
2210
+ "username",
2211
+ "push-subscriptions subscribe-feed"
2212
+ ),
2213
+ name: requireFlag(
2214
+ flags,
2215
+ "name",
2216
+ "push-subscriptions subscribe-feed"
2217
+ )
2218
+ });
2219
+ case "unsubscribe-feed":
2220
+ return client.pushSubscriptions.unsubscribeFeed({
2221
+ username: requireFlag(
2222
+ flags,
2223
+ "username",
2224
+ "push-subscriptions unsubscribe-feed"
2225
+ ),
2226
+ name: requireFlag(
2227
+ flags,
2228
+ "name",
2229
+ "push-subscriptions unsubscribe-feed"
2230
+ )
2231
+ });
2232
+ case "list":
2233
+ return client.pushSubscriptions.list({
2234
+ include_history: flags["include-history"] !== void 0
2235
+ });
2236
+ default:
2237
+ throw new CliUsageError(
2238
+ `Unknown subcommand: push-subscriptions ${subcommand}`,
2239
+ "push-subscriptions"
2240
+ );
2241
+ }
2242
+ }
2017
2243
  case "remix":
2018
2244
  return client.remix.save({
2019
2245
  child: {