@madewithremy/admin 0.1.51 → 0.1.52

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/prod.js CHANGED
@@ -1023,7 +1023,7 @@ async function dashboardLive(ctx) {
1023
1023
  "GET",
1024
1024
  `/_internal/v2/apps/${ctx.appId}/dashboard`
1025
1025
  );
1026
- return dashboard.liveRelease;
1026
+ return dashboard.liveRelease ? { ...dashboard.liveRelease, primaryUrl: dashboard.primaryUrl } : null;
1027
1027
  }
1028
1028
  async function primaryUrl(ctx) {
1029
1029
  const dashboard = await call(
@@ -1041,7 +1041,8 @@ function summarizeRelease(release) {
1041
1041
  status: release.status,
1042
1042
  buildDurationMs: release.buildDurationMs ?? null,
1043
1043
  publishedAt: release.publishedAt ?? null,
1044
- ...release.previewUrl ? { previewUrl: release.previewUrl } : {}
1044
+ ...release.previewUrl ? { previewUrl: release.previewUrl } : {},
1045
+ ...release.primaryUrl ? { primaryUrl: release.primaryUrl } : {}
1045
1046
  };
1046
1047
  const readers = (release.dataSources ?? []).filter((d) => d.reader);
1047
1048
  if (readers.length > 0 && release.status === "live") {
@@ -1285,7 +1286,7 @@ var releasesHelp = `remy-admin releases \u2014 View and monitor releases.
1285
1286
  Subcommands:
1286
1287
  list List releases, newest first (--limit N, default 20, max 100)
1287
1288
  get Get full details of a specific release
1288
- current Get the currently live release
1289
+ current Get the currently live release, with the address it's served on
1289
1290
  status Check a release's status by id (optionally poll until complete)
1290
1291
  wait Wait for the release built from a commit to go live
1291
1292
 
@@ -1298,8 +1299,11 @@ Usage:
1298
1299
 
1299
1300
  'releases wait' is the "publish and wait until live" primitive. After a
1300
1301
  'git push', run it to block until the pushed commit's release is terminal.
1301
- A push to a non-default branch resolves to status 'preview' and the result
1302
- carries 'previewUrl' \u2014 the gated URL that build is reachable at.
1302
+ A push to the default branch that goes live carries 'primaryUrl', the
1303
+ address the app is served on (its custom domain, else its subdomain, else
1304
+ its id's own host), which 'releases current' also returns. A push to a
1305
+ non-default branch resolves to status 'preview' and the result carries
1306
+ 'previewUrl' \u2014 the gated URL that build is reachable at.
1303
1307
  --commit defaults to the workspace HEAD; abbreviated SHAs (7+ hex chars,
1304
1308
  e.g. from push output) are accepted. It prints one JSON object and sets
1305
1309
  the exit code so you can branch on $? without parsing:
@@ -2008,6 +2012,12 @@ Usage:
2008
2012
  remy-admin domains zone add acmebakery.com --type TXT --host @ --answer "google-site-verification=abc"
2009
2013
 
2010
2014
  Notes:
2015
+ - 'check' says why a subdomain isn't available: reason 'reserved' (the
2016
+ platform's own, never any app's: offer a different name), 'taken' (another
2017
+ app has it, freed only from that app) or 'invalid' (not 1 to 63 letters,
2018
+ digits and hyphens, or shaped like an app's ID). 'set' refuses the same
2019
+ names, with subdomain_not_allowed (reserved or invalid) or unavailable
2020
+ (taken), and says which.
2011
2021
  - 'add' with an apex (e.g. acme.com) auto-creates the www.apex pair and
2012
2022
  returns both. 'remove' on an apex also removes its paired www.
2013
2023
  - 'list'/'records'/'status' read a CF-synced cache that can be up to ~5
@@ -3179,7 +3189,7 @@ Notes:
3179
3189
  - '--app <appId>' targets another app in the same workspace. Every app there is reachable
3180
3190
  with this credential, so it is a targeting flag: the issue lands in THAT app's tracker,
3181
3191
  and 'originAppId' on the row records that this app filed it. Cross-reference it in prose
3182
- as 'app#42'.
3192
+ as 'app#42'. 'remy-admin apps list --search <name>' finds another app's id by its name.
3183
3193
  - 'list' shows what was filed IN an app; 'filed' shows what an app sent OUT to others \u2014
3184
3194
  the whole fan-out in one call instead of one call per app.
3185
3195
  - '--label' repeats ('--label a --label b') or takes a comma-separated list ('--label a,b').
@@ -3196,6 +3206,82 @@ Examples:
3196
3206
  remy-admin issues comment 42 "Fixed in the latest release."
3197
3207
  remy-admin issues close 42 --comment "Already fixed in v3 \u2014 no change needed."`;
3198
3208
 
3209
+ // src/ops/apps.ts
3210
+ var PAGE_SIZE = 500;
3211
+ async function list9(ctx, params = {}) {
3212
+ const words = (params.search ?? "").toLowerCase().split(/\s+/).filter(Boolean);
3213
+ const apps = [];
3214
+ let cursor;
3215
+ while (true) {
3216
+ const page = await call(
3217
+ ctx,
3218
+ "GET",
3219
+ `/_internal/v2/apps${qs({ status: params.status, limit: PAGE_SIZE, cursor })}`
3220
+ );
3221
+ for (const app of page.apps) {
3222
+ const text = `${app.name} ${app.customSubdomain ?? ""}`.toLowerCase();
3223
+ if (words.every((word) => text.includes(word))) {
3224
+ apps.push({
3225
+ appId: app.appId,
3226
+ name: app.name,
3227
+ subdomain: app.customSubdomain,
3228
+ isPublished: app.isPublished,
3229
+ lastDeployedAt: app.lastDeployedAt,
3230
+ createdBy: app.createdBy.name
3231
+ });
3232
+ }
3233
+ }
3234
+ if (!page.nextCursor) {
3235
+ return { apps };
3236
+ }
3237
+ cursor = page.nextCursor;
3238
+ }
3239
+ }
3240
+
3241
+ // src/commands/apps.ts
3242
+ var appsSpecs = {
3243
+ "apps list": {
3244
+ usage: "Usage: remy-admin apps list [--search <words>] [--status draft|published]",
3245
+ flags: {
3246
+ search: { type: "string" },
3247
+ status: { type: "string", choices: ["draft", "published"] }
3248
+ }
3249
+ }
3250
+ };
3251
+ async function appsList(ctx, a) {
3252
+ out(
3253
+ await list9(ctx, {
3254
+ search: a.str("search"),
3255
+ status: a.str("status")
3256
+ })
3257
+ );
3258
+ }
3259
+ var appsHandlers = {
3260
+ "apps list": appsList
3261
+ };
3262
+ var appsHelp = `remy-admin apps \u2014 The apps in this app's workspace.
3263
+
3264
+ Subcommands:
3265
+ list List the workspace's apps, last active first, with their ids
3266
+
3267
+ Usage:
3268
+ remy-admin apps list [--search <words>] [--status draft|published]
3269
+
3270
+ Notes:
3271
+ - Lists every published app in the workspace, and your own drafts (another
3272
+ member's draft isn't listed). This app is in it too.
3273
+ - Each app has appId, name, subdomain (null if it has none), isPublished,
3274
+ lastDeployedAt and createdBy. Its appId is what '--app' takes elsewhere,
3275
+ as in 'issues create --app <appId>'.
3276
+ - '--search' keeps the apps whose name or subdomain contains every word, in
3277
+ any case. When the user names an app, search for it rather than asking for
3278
+ its id; when more than one matches, ask which.
3279
+
3280
+ Examples:
3281
+ remy-admin apps list
3282
+ remy-admin apps list --search "marketing site"
3283
+ remy-admin apps list --status published`;
3284
+
3199
3285
  // src/ops/prerender.ts
3200
3286
  function pages(ctx, params = {}) {
3201
3287
  return call(
@@ -3808,7 +3894,7 @@ async function waitForCandidate(ctx, params) {
3808
3894
  const timeoutMs = params.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;
3809
3895
  const outcome = await pollUntil(
3810
3896
  async () => {
3811
- const { dataSources } = await list9(ctx);
3897
+ const { dataSources } = await list10(ctx);
3812
3898
  const source = dataSources.find((s) => s.slug === params.slug);
3813
3899
  if (!source) {
3814
3900
  throw new Error(`Data source "${params.slug}" not found.`);
@@ -3890,7 +3976,7 @@ async function allDocuments(ctx, params) {
3890
3976
  }
3891
3977
  return out2;
3892
3978
  }
3893
- function list9(ctx) {
3979
+ function list10(ctx) {
3894
3980
  return call(ctx, "GET", base(ctx.appId));
3895
3981
  }
3896
3982
  function search2(ctx, params) {
@@ -4009,7 +4095,7 @@ async function waitForMove(ctx, params) {
4009
4095
  const timeoutMs = params.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;
4010
4096
  const outcome = await pollUntil(
4011
4097
  async () => {
4012
- const { dataSources } = await list9(ctx);
4098
+ const { dataSources } = await list10(ctx);
4013
4099
  const source2 = dataSources.find((s) => s.slug === params.slug);
4014
4100
  if (!source2) {
4015
4101
  throw new Error(`Data source "${params.slug}" not found.`);
@@ -4210,7 +4296,7 @@ async function uploadManifest(ctx, params) {
4210
4296
  await uploadDirect(token.upload, params.content, "manifest.jsonl");
4211
4297
  return { key: token.key };
4212
4298
  }
4213
- function list10(ctx, params) {
4299
+ function list11(ctx, params) {
4214
4300
  return call(
4215
4301
  ctx,
4216
4302
  "GET",
@@ -4649,7 +4735,7 @@ async function waitForHydration(ctx, params) {
4649
4735
  const timeoutMs = params.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS3;
4650
4736
  const outcome = await pollUntil(
4651
4737
  async () => {
4652
- const { dataSources } = await list9(ctx);
4738
+ const { dataSources } = await list10(ctx);
4653
4739
  const source2 = dataSources.find((s) => s.slug === params.slug);
4654
4740
  if (!source2) {
4655
4741
  throw new Error(`Data source "${params.slug}" not found.`);
@@ -5626,7 +5712,7 @@ async function jobsStart(ctx, a) {
5626
5712
  }
5627
5713
  async function jobsList(ctx, a) {
5628
5714
  const slug = a.str("source");
5629
- out(await list10(ctx, slug ? { slug } : void 0));
5715
+ out(await list11(ctx, slug ? { slug } : void 0));
5630
5716
  }
5631
5717
  async function jobsStatus(ctx, a) {
5632
5718
  const id = a.req("id");
@@ -6643,7 +6729,7 @@ async function dataSourcesAdd(ctx, a) {
6643
6729
  });
6644
6730
  }
6645
6731
  async function dataSourcesList(ctx) {
6646
- out(await list9(ctx));
6732
+ out(await list10(ctx));
6647
6733
  }
6648
6734
  async function dataSourcesStatus(ctx, a) {
6649
6735
  const slug = sourceOf(a);
@@ -6662,7 +6748,7 @@ async function dataSourcesStatus(ctx, a) {
6662
6748
  });
6663
6749
  return;
6664
6750
  }
6665
- const { dataSources: sources2 } = await list9(ctx);
6751
+ const { dataSources: sources2 } = await list10(ctx);
6666
6752
  const source = sources2.find((s) => s.slug === slug);
6667
6753
  if (!source) {
6668
6754
  out({ dataSource: slug, exists: false });
@@ -7636,7 +7722,7 @@ Notes:
7636
7722
  and error. Client tools run in the browser, so they have no requestId.`;
7637
7723
 
7638
7724
  // src/ops/tasks.ts
7639
- function list11(ctx, params = {}) {
7725
+ function list12(ctx, params = {}) {
7640
7726
  return call(
7641
7727
  ctx,
7642
7728
  "GET",
@@ -7665,9 +7751,9 @@ var tasksSpecs = {
7665
7751
  positionals: [{ name: "traceId", required: true }]
7666
7752
  }
7667
7753
  };
7668
- async function list12(ctx, a) {
7754
+ async function list13(ctx, a) {
7669
7755
  out(
7670
- await list11(ctx, {
7756
+ await list12(ctx, {
7671
7757
  limit: a.num("limit"),
7672
7758
  cursor: a.str("cursor")
7673
7759
  })
@@ -7677,7 +7763,7 @@ async function get10(ctx, a) {
7677
7763
  out(await get9(ctx, a.req("traceId")));
7678
7764
  }
7679
7765
  var tasksHandlers = {
7680
- "tasks list": list12,
7766
+ "tasks list": list13,
7681
7767
  "tasks get": get10
7682
7768
  };
7683
7769
  var tasksHelp = `remy-admin tasks \u2014 Log of the app's task agents (runTask), kept 90 days.
@@ -8663,7 +8749,7 @@ async function resolveDomainId(ctx, direction, domain) {
8663
8749
  }
8664
8750
  return match.id;
8665
8751
  }
8666
- function list13(ctx, params = {}) {
8752
+ function list14(ctx, params = {}) {
8667
8753
  return call(
8668
8754
  ctx,
8669
8755
  "GET",
@@ -8862,7 +8948,7 @@ var emailSpecs = {
8862
8948
  };
8863
8949
  async function emailList(ctx, a) {
8864
8950
  out(
8865
- await list13(ctx, {
8951
+ await list14(ctx, {
8866
8952
  status: a.str("status"),
8867
8953
  kind: a.str("kind"),
8868
8954
  recipient: a.str("recipient"),
@@ -9033,7 +9119,12 @@ Custom domains \u2014 two independent directions:
9033
9119
  bounces.<domain>) \u2014 hand these to the user to create at
9034
9120
  their DNS host, then 'verify <domain>' to re-check now.
9035
9121
  'list' also returns effectiveSender: what the app currently
9036
- sends as, and which tier that address comes from.
9122
+ sends as, which tier that address comes from, and
9123
+ anyRecipient. anyRecipient false is the shared platform
9124
+ address, which only mails the app's verified users and its
9125
+ workspace's members, in dev and live alike (anyone else is
9126
+ refused with unverified_recipients). A subdomain
9127
+ ('domains set') or a verified sending domain lifts it.
9037
9128
  'inbound-domains' receive mail at the user's own domain via one MX record
9038
9129
  ('check' returns it up front \u2014 no registration needed to
9039
9130
  see it). Apps already receive at *@<slug>.madewithremy.com
@@ -9060,7 +9151,7 @@ Examples:
9060
9151
  `;
9061
9152
 
9062
9153
  // src/ops/cron.ts
9063
- function list14(ctx, params = {}) {
9154
+ function list15(ctx, params = {}) {
9064
9155
  return call(
9065
9156
  ctx,
9066
9157
  "GET",
@@ -9089,7 +9180,7 @@ var cronSpecs = {
9089
9180
  }
9090
9181
  };
9091
9182
  async function cronList(ctx, a) {
9092
- out(await list14(ctx, { runs: a.num("runs") }));
9183
+ out(await list15(ctx, { runs: a.num("runs") }));
9093
9184
  }
9094
9185
  async function cronRun(ctx, a) {
9095
9186
  out(await run2(ctx, a.req("route")));
@@ -9190,7 +9281,7 @@ var POLL_MS5 = 3e3;
9190
9281
  function base7(appId) {
9191
9282
  return `/_internal/v2/apps/${appId}/infra`;
9192
9283
  }
9193
- function list15(ctx, params) {
9284
+ function list16(ctx, params) {
9194
9285
  return call(
9195
9286
  ctx,
9196
9287
  "GET",
@@ -9382,7 +9473,7 @@ async function waitAndReport2(ctx, a, id, phases, summary2, until) {
9382
9473
  }
9383
9474
  }
9384
9475
  async function infraList(ctx, a) {
9385
- out(await list15(ctx, { includeDestroyed: a.bool("include-destroyed") }));
9476
+ out(await list16(ctx, { includeDestroyed: a.bool("include-destroyed") }));
9386
9477
  }
9387
9478
  async function infraGet(ctx, a) {
9388
9479
  out(await get12(ctx, { id: a.req("id") }));
@@ -9874,6 +9965,7 @@ var SPECS = {
9874
9965
  ...methodsSpecs,
9875
9966
  ...dataSpecs,
9876
9967
  ...issuesSpecs,
9968
+ ...appsSpecs,
9877
9969
  ...prerenderSpecs,
9878
9970
  ...filesSpecs,
9879
9971
  ...dataSourcesSpecs,
@@ -9909,6 +10001,7 @@ var HANDLERS = {
9909
10001
  ...methodsHandlers,
9910
10002
  ...dataHandlers,
9911
10003
  ...issuesHandlers,
10004
+ ...appsHandlers,
9912
10005
  ...prerenderHandlers,
9913
10006
  ...filesHandlers,
9914
10007
  ...dataSourcesHandlers,
@@ -9944,6 +10037,7 @@ var GROUP_HELP = {
9944
10037
  methods: methodsHelp,
9945
10038
  data: dataHelp,
9946
10039
  issues: issuesHelp,
10040
+ apps: appsHelp,
9947
10041
  prerender: prerenderHelp,
9948
10042
  files: filesHelp,
9949
10043
  datasources: dataSourcesHelp,
@@ -10030,6 +10124,7 @@ Commands:
10030
10124
  methods List and invoke methods
10031
10125
  data Sync databases between dev and live (lift-from-dev / lift-from-live)
10032
10126
  issues File and manage issues, in this app or another app in the workspace
10127
+ apps The workspace's apps by name, with the ids '--app' takes
10033
10128
  prerender Manage + verify prerendered snapshots served to bots/crawlers
10034
10129
  files Store, retrieve, share (signed links) + manage files in the app's stores
10035
10130
  datasources Build and query searchable document corpora (RAG)
@@ -10067,6 +10162,7 @@ var GROUPS = [
10067
10162
  "methods",
10068
10163
  "data",
10069
10164
  "issues",
10165
+ "apps",
10070
10166
  "prerender",
10071
10167
  "files",
10072
10168
  "datasources",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madewithremy/admin",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "description": "Admin SDK + CLI for managing production Remy apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",