@madewithremy/admin 0.1.23 → 0.1.25

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
@@ -65,6 +65,9 @@ var PAGINATION = {
65
65
  limit: { type: "number", min: 0 },
66
66
  offset: { type: "number", min: 0 }
67
67
  };
68
+ var APP = {
69
+ app: { type: "string" }
70
+ };
68
71
  var Args = class {
69
72
  constructor(spec, positionals, flags) {
70
73
  this.spec = spec;
@@ -97,6 +100,11 @@ var Args = class {
97
100
  const value = this.flags[flag];
98
101
  return value === void 0 ? void 0 : String(value);
99
102
  }
103
+ /** A repeatable flag's values (`multiple: true`). Absent → undefined. */
104
+ list(flag) {
105
+ const value = this.flags[flag];
106
+ return Array.isArray(value) ? value : void 0;
107
+ }
100
108
  num(flag) {
101
109
  const value = this.flags[flag];
102
110
  return value === void 0 ? void 0 : Number(value);
@@ -116,6 +124,15 @@ var Args = class {
116
124
  return index;
117
125
  }
118
126
  };
127
+ function checkChoice(value, flag, flagSpec, usage) {
128
+ if (!flagSpec.choices || flagSpec.choices.includes(value)) {
129
+ return;
130
+ }
131
+ throw new UsageError(
132
+ `Invalid value "${value}" for --${flag}. Valid: ${flagSpec.choices.join("|")}.`,
133
+ usage
134
+ );
135
+ }
119
136
  function preflightUnknownFlags(argv, spec) {
120
137
  const declared = new Set(Object.keys(spec.flags ?? {}));
121
138
  for (const token of argv) {
@@ -199,7 +216,8 @@ function parseCommand(spec, argv) {
199
216
  const options = {};
200
217
  for (const [flag, flagSpec] of Object.entries(spec.flags ?? {})) {
201
218
  options[flag] = {
202
- type: flagSpec.type === "boolean" ? "boolean" : "string"
219
+ type: flagSpec.type === "boolean" ? "boolean" : "string",
220
+ ...flagSpec.multiple ? { multiple: true } : {}
203
221
  };
204
222
  }
205
223
  let parsed;
@@ -219,7 +237,20 @@ function parseCommand(spec, argv) {
219
237
  if (raw === void 0) {
220
238
  continue;
221
239
  }
222
- flags[flag] = flagSpec.type === "number" ? coerceNumber(String(raw), flag, flagSpec, spec.usage) : raw;
240
+ if (flagSpec.multiple) {
241
+ const values = raw.flatMap((v) => String(v).split(",")).map((v) => v.trim()).filter((v) => v.length > 0);
242
+ for (const value of values) {
243
+ checkChoice(value, flag, flagSpec, spec.usage);
244
+ }
245
+ flags[flag] = values;
246
+ continue;
247
+ }
248
+ if (flagSpec.type === "number") {
249
+ flags[flag] = coerceNumber(String(raw), flag, flagSpec, spec.usage);
250
+ continue;
251
+ }
252
+ checkChoice(String(raw), flag, flagSpec, spec.usage);
253
+ flags[flag] = raw;
223
254
  }
224
255
  const positionals = bindPositionals(parsed.positionals, spec);
225
256
  checkRequireAnyOf(spec, positionals, flags);
@@ -248,6 +279,12 @@ function qs(params) {
248
279
  if (value === void 0 || value === null) {
249
280
  continue;
250
281
  }
282
+ if (Array.isArray(value)) {
283
+ for (const entry of value) {
284
+ search2.append(key, String(entry));
285
+ }
286
+ continue;
287
+ }
251
288
  search2.set(key, String(value));
252
289
  }
253
290
  const text = search2.toString();
@@ -2286,11 +2323,30 @@ Examples:
2286
2323
  import fs from "fs";
2287
2324
 
2288
2325
  // src/ops/issues.ts
2326
+ function authorship(ctx) {
2327
+ return ctx.originAppId ? { originAppId: ctx.originAppId } : {};
2328
+ }
2329
+ function listQuery(params) {
2330
+ return qs({
2331
+ status: params.status,
2332
+ label: params.labels,
2333
+ originAppId: params.originAppId,
2334
+ limit: params.limit,
2335
+ cursor: params.cursor
2336
+ });
2337
+ }
2289
2338
  function list7(ctx, params = {}) {
2290
2339
  return call(
2291
2340
  ctx,
2292
2341
  "GET",
2293
- `/_internal/v2/apps/${ctx.appId}/issues${qs(params)}`
2342
+ `/_internal/v2/apps/${ctx.appId}/issues${listQuery(params)}`
2343
+ );
2344
+ }
2345
+ function filed(ctx, params = {}) {
2346
+ return call(
2347
+ ctx,
2348
+ "GET",
2349
+ `/_internal/v2/apps/${ctx.appId}/issues/filed${listQuery(params)}`
2294
2350
  );
2295
2351
  }
2296
2352
  function get6(ctx, number) {
@@ -2308,8 +2364,12 @@ function create(ctx, params) {
2308
2364
  if (params.body !== void 0) {
2309
2365
  requestBody.body = params.body;
2310
2366
  }
2311
- if (params.kind !== void 0) {
2312
- requestBody.kind = params.kind;
2367
+ if (params.labels !== void 0) {
2368
+ requestBody.labels = params.labels;
2369
+ }
2370
+ const originAppId = params.originAppId ?? ctx.originAppId;
2371
+ if (originAppId !== void 0) {
2372
+ requestBody.originAppId = originAppId;
2313
2373
  }
2314
2374
  return call(
2315
2375
  ctx,
@@ -2323,15 +2383,23 @@ function comment(ctx, number, body) {
2323
2383
  ctx,
2324
2384
  "POST",
2325
2385
  `/_internal/v2/apps/${ctx.appId}/issues/${seg(number)}/comments`,
2326
- { body, authorKind: "agent" }
2386
+ { body, authorKind: "agent", ...authorship(ctx) }
2327
2387
  );
2328
2388
  }
2329
- function close(ctx, number) {
2389
+ function close(ctx, number, comment2) {
2390
+ const requestBody = {
2391
+ status: "closed",
2392
+ authorKind: "agent",
2393
+ ...authorship(ctx)
2394
+ };
2395
+ if (comment2 !== void 0) {
2396
+ requestBody.comment = comment2;
2397
+ }
2330
2398
  return call(
2331
2399
  ctx,
2332
2400
  "POST",
2333
2401
  `/_internal/v2/apps/${ctx.appId}/issues/${seg(number)}/update`,
2334
- { status: "closed", authorKind: "agent" }
2402
+ requestBody
2335
2403
  );
2336
2404
  }
2337
2405
  function reopen(ctx, number) {
@@ -2339,19 +2407,22 @@ function reopen(ctx, number) {
2339
2407
  ctx,
2340
2408
  "POST",
2341
2409
  `/_internal/v2/apps/${ctx.appId}/issues/${seg(number)}/update`,
2342
- { status: "open", authorKind: "agent" }
2410
+ { status: "open", authorKind: "agent", ...authorship(ctx) }
2343
2411
  );
2344
2412
  }
2345
2413
  function edit(ctx, number, params) {
2346
- const requestBody = { authorKind: "agent" };
2414
+ const requestBody = {
2415
+ authorKind: "agent",
2416
+ ...authorship(ctx)
2417
+ };
2347
2418
  if (params.title !== void 0) {
2348
2419
  requestBody.title = params.title;
2349
2420
  }
2350
2421
  if (params.body !== void 0) {
2351
2422
  requestBody.body = params.body;
2352
2423
  }
2353
- if (params.kind !== void 0) {
2354
- requestBody.kind = params.kind;
2424
+ if (params.labels !== void 0) {
2425
+ requestBody.labels = params.labels;
2355
2426
  }
2356
2427
  if (params.status !== void 0) {
2357
2428
  requestBody.status = params.status;
@@ -2372,29 +2443,48 @@ function del2(ctx, number) {
2372
2443
  }
2373
2444
 
2374
2445
  // src/commands/issues.ts
2446
+ var STATES = ["open", "closed"];
2447
+ var LIST_STATES = ["open", "closed", "all"];
2375
2448
  var issuesSpecs = {
2376
2449
  "issues list": {
2377
- usage: "Usage: remy-admin issues list [--status open|closed] [--kind bug|idea|task] [--limit 50] [--cursor <c>]",
2450
+ usage: "Usage: remy-admin issues list [--app <appId>] [--state open|closed|all] [--label <l>] [--from-app <appId>] [--limit 50] [--cursor <c>]",
2378
2451
  flags: {
2379
- status: { type: "string" },
2380
- kind: { type: "string" },
2452
+ ...APP,
2453
+ state: { type: "string", choices: LIST_STATES },
2454
+ label: { type: "string", multiple: true },
2455
+ "from-app": { type: "string" },
2456
+ limit: { type: "number", min: 0 },
2457
+ cursor: { type: "string" }
2458
+ }
2459
+ },
2460
+ "issues filed": {
2461
+ usage: "Usage: remy-admin issues filed [--app <appId>] [--state open|closed|all] [--label <l>] [--limit 50] [--cursor <c>]",
2462
+ flags: {
2463
+ ...APP,
2464
+ state: { type: "string", choices: LIST_STATES },
2465
+ label: { type: "string", multiple: true },
2381
2466
  limit: { type: "number", min: 0 },
2382
2467
  cursor: { type: "string" }
2383
2468
  }
2384
2469
  },
2385
2470
  "issues get": {
2386
- usage: "Usage: remy-admin issues get <number>",
2387
- positionals: [{ name: "number", required: true }]
2471
+ usage: "Usage: remy-admin issues get <number> [--app <appId>]",
2472
+ positionals: [{ name: "number", required: true }],
2473
+ flags: { ...APP }
2388
2474
  },
2389
2475
  "issues create": {
2390
- usage: "Usage: remy-admin issues create <title> [--body <text>|--body -] [--kind bug|idea|task]",
2476
+ usage: "Usage: remy-admin issues create <title> [--app <appId>] [--body <text>|--body -] [--label <l>]",
2391
2477
  positionals: [{ name: "title", required: true }],
2392
- flags: { body: { type: "string" }, kind: { type: "string" } }
2478
+ flags: {
2479
+ ...APP,
2480
+ body: { type: "string" },
2481
+ label: { type: "string", multiple: true }
2482
+ }
2393
2483
  },
2394
2484
  "issues comment": {
2395
- usage: "Usage: remy-admin issues comment <number> <body> (or --body - to read stdin)",
2485
+ usage: "Usage: remy-admin issues comment <number> <body> [--app <appId>] (or --body - to read stdin)",
2396
2486
  positionals: [{ name: "number", required: true }, { name: "body" }],
2397
- flags: { body: { type: "string" } },
2487
+ flags: { ...APP, body: { type: "string" } },
2398
2488
  requireAnyOf: {
2399
2489
  flags: ["body"],
2400
2490
  positionals: ["body"],
@@ -2402,34 +2492,38 @@ var issuesSpecs = {
2402
2492
  }
2403
2493
  },
2404
2494
  "issues close": {
2405
- usage: "Usage: remy-admin issues close <number>",
2406
- positionals: [{ name: "number", required: true }]
2495
+ usage: "Usage: remy-admin issues close <number> [--app <appId>] [--comment <text>|--comment -]",
2496
+ positionals: [{ name: "number", required: true }],
2497
+ flags: { ...APP, comment: { type: "string" } }
2407
2498
  },
2408
2499
  "issues reopen": {
2409
- usage: "Usage: remy-admin issues reopen <number>",
2410
- positionals: [{ name: "number", required: true }]
2500
+ usage: "Usage: remy-admin issues reopen <number> [--app <appId>]",
2501
+ positionals: [{ name: "number", required: true }],
2502
+ flags: { ...APP }
2411
2503
  },
2412
2504
  "issues edit": {
2413
- usage: "Usage: remy-admin issues edit <number> [--title <t>] [--body <t>|--body -] [--kind ...] [--status open|closed]",
2505
+ usage: "Usage: remy-admin issues edit <number> [--app <appId>] [--title <t>] [--body <t>|--body -] [--label <l>] [--state open|closed]",
2414
2506
  positionals: [{ name: "number", required: true }],
2415
2507
  flags: {
2508
+ ...APP,
2416
2509
  title: { type: "string" },
2417
2510
  body: { type: "string" },
2418
- kind: { type: "string" },
2419
- status: { type: "string" }
2511
+ label: { type: "string", multiple: true },
2512
+ state: { type: "string", choices: STATES }
2420
2513
  },
2421
2514
  requireAnyOf: {
2422
- flags: ["title", "body", "kind", "status"],
2423
- message: "Provide at least one of --title, --body, --kind, --status"
2515
+ flags: ["title", "body", "label", "state"],
2516
+ message: "Provide at least one of --title, --body, --label, --state"
2424
2517
  }
2425
2518
  },
2426
2519
  "issues delete": {
2427
- usage: "Usage: remy-admin issues delete <number>",
2428
- positionals: [{ name: "number", required: true }]
2520
+ usage: "Usage: remy-admin issues delete <number> [--app <appId>]",
2521
+ positionals: [{ name: "number", required: true }],
2522
+ flags: { ...APP }
2429
2523
  }
2430
2524
  };
2431
- function readBodyFlag(a) {
2432
- const val = a.str("body");
2525
+ function readStdinFlag(a, flag) {
2526
+ const val = a.str(flag);
2433
2527
  if (val === void 0) {
2434
2528
  return void 0;
2435
2529
  }
@@ -2438,11 +2532,29 @@ function readBodyFlag(a) {
2438
2532
  }
2439
2533
  return val;
2440
2534
  }
2535
+ function readBodyFlag(a) {
2536
+ return readStdinFlag(a, "body");
2537
+ }
2538
+ function readStateFilter(a) {
2539
+ const state = a.str("state");
2540
+ return state === "all" ? void 0 : state;
2541
+ }
2441
2542
  async function issuesList(ctx, a) {
2442
2543
  out(
2443
2544
  await list7(ctx, {
2444
- status: a.str("status"),
2445
- kind: a.str("kind"),
2545
+ status: readStateFilter(a),
2546
+ labels: a.list("label"),
2547
+ originAppId: a.str("from-app"),
2548
+ limit: a.num("limit"),
2549
+ cursor: a.str("cursor")
2550
+ })
2551
+ );
2552
+ }
2553
+ async function issuesFiled(ctx, a) {
2554
+ out(
2555
+ await filed(ctx, {
2556
+ status: readStateFilter(a),
2557
+ labels: a.list("label"),
2446
2558
  limit: a.num("limit"),
2447
2559
  cursor: a.str("cursor")
2448
2560
  })
@@ -2453,12 +2565,11 @@ async function issuesGet(ctx, a) {
2453
2565
  }
2454
2566
  async function issuesCreate(ctx, a) {
2455
2567
  const issueBody = readBodyFlag(a);
2456
- const kind = a.str("kind");
2457
2568
  out(
2458
2569
  await create(ctx, {
2459
2570
  title: a.req("title"),
2460
2571
  body: issueBody,
2461
- kind
2572
+ labels: a.list("label")
2462
2573
  })
2463
2574
  );
2464
2575
  }
@@ -2467,7 +2578,7 @@ async function issuesComment(ctx, a) {
2467
2578
  out(await comment(ctx, a.req("number"), commentBody));
2468
2579
  }
2469
2580
  async function issuesClose(ctx, a) {
2470
- out(await close(ctx, a.req("number")));
2581
+ out(await close(ctx, a.req("number"), readStdinFlag(a, "comment")));
2471
2582
  }
2472
2583
  async function issuesReopen(ctx, a) {
2473
2584
  out(await reopen(ctx, a.req("number")));
@@ -2478,8 +2589,8 @@ async function issuesEdit(ctx, a) {
2478
2589
  await edit(ctx, a.req("number"), {
2479
2590
  title: a.str("title"),
2480
2591
  body: editBody,
2481
- kind: a.str("kind"),
2482
- status: a.str("status")
2592
+ labels: a.list("label"),
2593
+ status: a.str("state")
2483
2594
  })
2484
2595
  );
2485
2596
  }
@@ -2488,6 +2599,7 @@ async function issuesDelete(ctx, a) {
2488
2599
  }
2489
2600
  var issuesHandlers = {
2490
2601
  "issues list": issuesList,
2602
+ "issues filed": issuesFiled,
2491
2603
  "issues get": issuesGet,
2492
2604
  "issues create": issuesCreate,
2493
2605
  "issues comment": issuesComment,
@@ -2496,39 +2608,51 @@ var issuesHandlers = {
2496
2608
  "issues edit": issuesEdit,
2497
2609
  "issues delete": issuesDelete
2498
2610
  };
2499
- var issuesHelp = `remy-admin issues \u2014 File and manage issues (bugs, ideas, tasks) for the app.
2611
+ var issuesHelp = `remy-admin issues \u2014 File and manage issues for this app, or for another app in the workspace.
2500
2612
 
2501
2613
  Subcommands:
2502
- list List issues (newest first)
2614
+ list List issues filed in an app (newest first)
2615
+ filed List issues this app filed into other apps
2503
2616
  get Get one issue + its comment thread
2504
2617
  create File a new issue
2505
2618
  comment Post a comment on an issue's thread
2506
- close Close an issue
2619
+ close Close an issue, optionally with a closing comment
2507
2620
  reopen Reopen a closed issue
2508
- edit Edit an issue's title / body / kind / status
2621
+ edit Edit an issue's title / body / labels / state
2509
2622
  delete Delete an issue
2510
2623
 
2511
2624
  Usage:
2512
- remy-admin issues list [--status open|closed] [--kind bug|idea|task] [--limit 50] [--cursor <c>]
2513
- remy-admin issues get <number>
2514
- remy-admin issues create <title> [--body <text>|--body -] [--kind bug|idea|task]
2515
- remy-admin issues comment <number> <body> (or --body - to read stdin)
2516
- remy-admin issues close <number>
2517
- remy-admin issues reopen <number>
2518
- remy-admin issues edit <number> [--title <t>] [--body <t>|--body -] [--kind ...] [--status open|closed]
2519
- remy-admin issues delete <number>
2625
+ remy-admin issues list [--app <appId>] [--state open|closed|all] [--label <l>] [--from-app <appId>] [--limit 50] [--cursor <c>]
2626
+ remy-admin issues filed [--app <appId>] [--state open|closed|all] [--label <l>] [--limit 50] [--cursor <c>]
2627
+ remy-admin issues get <number> [--app <appId>]
2628
+ remy-admin issues create <title> [--app <appId>] [--body <text>|--body -] [--label <l>]
2629
+ remy-admin issues comment <number> <body> [--app <appId>] (or --body - to read stdin)
2630
+ remy-admin issues close <number> [--app <appId>] [--comment <text>|--comment -]
2631
+ remy-admin issues reopen <number> [--app <appId>]
2632
+ remy-admin issues edit <number> [--app <appId>] [--title <t>] [--body <t>|--body -] [--label <l>] [--state open|closed]
2633
+ remy-admin issues delete <number> [--app <appId>]
2520
2634
 
2521
2635
  Notes:
2522
2636
  - <number> is the friendly per-app issue number (e.g. 42), shown as 'number' in output.
2637
+ - '--app <appId>' targets another app in the same workspace. Every app there is reachable
2638
+ with this credential, so it is a targeting flag: the issue lands in THAT app's tracker,
2639
+ and 'originAppId' on the row records that this app filed it. Cross-reference it in prose
2640
+ as 'app#42'.
2641
+ - 'list' shows what was filed IN an app; 'filed' shows what an app sent OUT to others \u2014
2642
+ the whole fan-out in one call instead of one call per app.
2643
+ - '--label' repeats ('--label a --label b') or takes a comma-separated list ('--label a,b').
2644
+ Filtering matches an issue carrying ANY of them. Labels are an open set: pick your own.
2645
+ - '--state all' means no state filter (the default is also every state).
2523
2646
  - Issues and comments filed via this CLI are authored as the agent (authorKind: "agent").
2524
- - '--body -' reads the body from stdin \u2014 use it for long multi-line markdown.
2647
+ - '--body -' / '--comment -' read from stdin \u2014 use for long multi-line markdown.
2525
2648
 
2526
2649
  Examples:
2527
- remy-admin issues list --status open --kind bug
2528
- remy-admin issues create "Checkout 500s on empty cart" --kind bug --body "Repro in comments"
2529
- echo "Long markdown body..." | remy-admin issues create "Refactor auth flow" --kind task --body -
2650
+ remy-admin issues list --state open --label bug
2651
+ remy-admin issues create "Checkout 500s on empty cart" --label bug --body "Repro in comments"
2652
+ remy-admin issues create "Apply the new auth spec" --app 8f3c... --label fleet-patch --body -
2653
+ remy-admin issues filed --state open
2530
2654
  remy-admin issues comment 42 "Fixed in the latest release."
2531
- remy-admin issues close 42`;
2655
+ remy-admin issues close 42 --comment "Already fixed in v3 \u2014 no change needed."`;
2532
2656
 
2533
2657
  // src/ops/prerender.ts
2534
2658
  function pages(ctx, params = {}) {
@@ -6940,7 +7064,6 @@ var SETTABLE_KEYS = [
6940
7064
  "signupAllowlistEnabled",
6941
7065
  "testAccountsEnabled",
6942
7066
  "telemetryCaptureResponseBodies",
6943
- "autoTriageIssues",
6944
7067
  "analyticsExtraQueryParams"
6945
7068
  ];
6946
7069
  var settingsSpecs = {
@@ -7214,8 +7337,6 @@ Settable keys (settings set):
7214
7337
  telemetryCaptureResponseBodies Include failed-request response bodies (~1KB) in
7215
7338
  frontend error reports. Default: true; turn off if API
7216
7339
  responses may carry PII or tokens.
7217
- autoTriageIssues Auto-run the read-only triage agent on new bug issues.
7218
- Default: false.
7219
7340
  analyticsExtraQueryParams JSON array of query-param names to preserve in
7220
7341
  analytics URLs beyond the UTM/ad-click defaults.
7221
7342
 
@@ -8295,7 +8416,7 @@ Commands:
8295
8416
  secrets Manage app secrets (env vars)
8296
8417
  methods List and invoke methods
8297
8418
  data Sync databases between dev and live (lift-from-dev / lift-from-live)
8298
- issues File and manage issues (bugs, ideas, tasks)
8419
+ issues File and manage issues, in this app or another app in the workspace
8299
8420
  prerender Manage + verify prerendered snapshots served to bots/crawlers
8300
8421
  files Store, retrieve, share (signed links) + manage files in the app's stores
8301
8422
  datasources Build and query searchable document corpora (RAG)
@@ -8415,9 +8536,21 @@ async function main() {
8415
8536
  if (!apiKey) {
8416
8537
  fatal("MINDSTUDIO_API_KEY environment variable is not set");
8417
8538
  }
8539
+ const appIdOverride = a.str("app");
8540
+ let originAppId;
8541
+ if (appIdOverride) {
8542
+ try {
8543
+ const workspaceAppId = loadWorkspaceAppId();
8544
+ if (workspaceAppId !== appIdOverride) {
8545
+ originAppId = workspaceAppId;
8546
+ }
8547
+ } catch {
8548
+ }
8549
+ }
8418
8550
  const ctx = {
8419
8551
  apiKey,
8420
- appId: loadWorkspaceAppId(),
8552
+ appId: appIdOverride ?? loadWorkspaceAppId(),
8553
+ originAppId,
8421
8554
  baseUrl: process.env["API_BASE_URL"] || DEFAULT_BASE_URL
8422
8555
  };
8423
8556
  return HANDLERS[route.key](ctx, a);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madewithremy/admin",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Admin SDK + CLI for managing production Remy apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",