@whittlelabs/sifter 0.17.0 → 0.19.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.
Files changed (3) hide show
  1. package/bin.js +67 -50
  2. package/bin.js.map +2 -2
  3. package/package.json +1 -1
package/bin.js CHANGED
@@ -3180,6 +3180,14 @@ var require_device_code = __commonJS({
3180
3180
  });
3181
3181
  log(opts.brand.strings?.pairingDoneMessage ?? `Paired ${displayName}.`);
3182
3182
  }
3183
+ const jobPools = await discoverMemberPools({
3184
+ keepApiUrl: reg.keepApiUrl,
3185
+ jobsApiUrl: reg.jobsApiUrl,
3186
+ clientId: token.clientId,
3187
+ clientSecret: token.clientSecret,
3188
+ fetcher,
3189
+ brand: opts.brand
3190
+ });
3183
3191
  return {
3184
3192
  schemaVersion: 1,
3185
3193
  keepApiUrl: reg.keepApiUrl,
@@ -3195,9 +3203,38 @@ var require_device_code = __commonJS({
3195
3203
  hostname: (0, os_1.hostname)(),
3196
3204
  user: (0, os_1.userInfo)().username
3197
3205
  },
3198
- jobPools: token.jobPools
3206
+ jobPools
3199
3207
  };
3200
3208
  }
3209
+ async function discoverMemberPools(opts) {
3210
+ const tokenUrl = `${opts.keepApiUrl.replace(/\/$/, "")}/api/agent-tokens`;
3211
+ const tokenRes = await opts.fetcher(tokenUrl, {
3212
+ method: "POST",
3213
+ headers: { "Content-Type": "application/json" },
3214
+ body: JSON.stringify({
3215
+ clientId: opts.clientId,
3216
+ clientSecret: opts.clientSecret
3217
+ })
3218
+ });
3219
+ (0, version_check_1.checkResponseMinVersion)({
3220
+ response: tokenRes,
3221
+ currentVersion: opts.brand.product.version,
3222
+ packageName: opts.brand.product.packageName
3223
+ });
3224
+ const tokenJson = await readJson(tokenRes);
3225
+ const poolsUrl = `${opts.jobsApiUrl.replace(/\/$/, "")}/api/my/pools`;
3226
+ const poolsRes = await opts.fetcher(poolsUrl, {
3227
+ method: "GET",
3228
+ headers: { Authorization: `Bearer ${tokenJson.data.token}` }
3229
+ });
3230
+ (0, version_check_1.checkResponseMinVersion)({
3231
+ response: poolsRes,
3232
+ currentVersion: opts.brand.product.version,
3233
+ packageName: opts.brand.product.packageName
3234
+ });
3235
+ const poolsJson = await readJson(poolsRes);
3236
+ return poolsJson.data.pools;
3237
+ }
3201
3238
  async function startDeviceCode(opts) {
3202
3239
  const url = `${opts.keepApiUrl.replace(/\/$/, "")}/api/oauth/device`;
3203
3240
  const response = await opts.fetcher(url, {
@@ -18064,7 +18101,8 @@ var require_canonicalise = __commonJS({
18064
18101
  return {
18065
18102
  name: workflow.name,
18066
18103
  description: workflow.description ?? null,
18067
- ownerOrgId: opts.ownerOrgId,
18104
+ ownerClass: opts.ownerClass,
18105
+ ownerId: opts.ownerId,
18068
18106
  retainPublishedVersions: workflow.retain?.publishedVersions ?? null,
18069
18107
  ...opts.publish !== void 0 ? { publish: opts.publish } : {},
18070
18108
  nodes,
@@ -18226,18 +18264,28 @@ var require_seed_workflows = __commonJS({
18226
18264
  }
18227
18265
  const results = [];
18228
18266
  for (const workflow of opts.workflows) {
18229
- const ownerOrgId = opts.ownerSlugToOrgId[workflow.owner.slug];
18230
- if (ownerOrgId === void 0) {
18231
- throw new errors_1.SeedWorkflowsError(workflow.name, `seedWorkflows: owner.slug "${workflow.owner.slug}" not present in ownerSlugToOrgId map`);
18267
+ let ownerClass;
18268
+ let ownerId;
18269
+ if ("service" in workflow.owner) {
18270
+ ownerClass = "service";
18271
+ ownerId = workflow.owner.service;
18272
+ } else {
18273
+ const orgId = opts.ownerSlugToOrgId[workflow.owner.orgSlug];
18274
+ if (orgId === void 0) {
18275
+ throw new errors_1.SeedWorkflowsError(workflow.name, `seedWorkflows: owner.orgSlug "${workflow.owner.orgSlug}" not present in ownerSlugToOrgId map`);
18276
+ }
18277
+ ownerClass = "org";
18278
+ ownerId = orgId;
18232
18279
  }
18233
- const opts2 = { ownerOrgId };
18280
+ const opts2 = { ownerClass, ownerId };
18234
18281
  if (opts.env !== void 0)
18235
18282
  opts2.env = opts.env;
18236
18283
  if (opts.publish !== void 0)
18237
18284
  opts2.publish = opts.publish;
18238
18285
  const body = await (0, canonicalise_1.canonicaliseWorkflow)(workflow, opts2);
18239
18286
  logger.info(`seeding workflow ${workflow.name}`, {
18240
- ownerOrgId,
18287
+ ownerClass,
18288
+ ownerId,
18241
18289
  nodes: body.nodes.length,
18242
18290
  transitions: body.transitions.length
18243
18291
  });
@@ -18511,50 +18559,20 @@ var require_client2 = __commonJS({
18511
18559
  constructor(config) {
18512
18560
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
18513
18561
  this.headers = { "Content-Type": "application/json" };
18514
- if (config.serviceSecret) {
18515
- this.headers["X-Service-Secret"] = config.serviceSecret;
18516
- }
18517
18562
  if (config.serviceToken) {
18518
18563
  this.headers["Authorization"] = `Bearer ${config.serviceToken}`;
18519
18564
  } else if (config.accessToken) {
18520
18565
  this.headers["Authorization"] = `Bearer ${config.accessToken}`;
18521
18566
  }
18522
18567
  }
18523
- // ── Claims ──────────────────────────────────────────────────────
18524
- async checkClaim(subject, scope, resource) {
18525
- return this.request("POST", "/api/claims", {
18526
- subject,
18527
- scope,
18528
- resource
18529
- });
18530
- }
18531
- async checkClaimsBatch(subject, claims) {
18532
- return this.request("POST", "/api/claims/batch", {
18533
- subject,
18534
- claims
18535
- });
18536
- }
18537
- async getEffectivePermissions(subject, context) {
18538
- return this.request("POST", "/api/claims/effective", {
18539
- subject,
18540
- context
18541
- });
18542
- }
18543
- // ── API Key Verification ────────────────────────────────────────
18544
- async verifyApiKey(key) {
18545
- return this.request("POST", "/api/keys/claims", { key });
18546
- }
18547
- // ── Service Tokens ──────────────────────────────────────────────
18548
- async exchangeServiceToken(clientId, clientSecret) {
18549
- return this.request("POST", "/api/service-tokens", {
18550
- clientId,
18551
- clientSecret
18552
- });
18553
- }
18554
- async verifyServiceToken(token) {
18555
- return this.request("POST", "/api/service-tokens/claims", {
18556
- token
18557
- });
18568
+ // ── Actor Tokens ────────────────────────────────────────────────
18569
+ /**
18570
+ * Mint a short-lived `act_` token for an end user, with this client's
18571
+ * service identity recorded as the conduit. Requires this client to be
18572
+ * constructed with a service token holding `keep:actor-tokens:mint`.
18573
+ */
18574
+ async mintActorToken(actor) {
18575
+ return this.request("POST", "/api/actor-tokens", { actor });
18558
18576
  }
18559
18577
  // ── Identity ────────────────────────────────────────────────────
18560
18578
  async createAccount(email, password, name) {
@@ -18646,10 +18664,9 @@ var require_client2 = __commonJS({
18646
18664
  return this.request("POST", `/api/users/${request.ownerPrincipalId}/service-identities`, request);
18647
18665
  }
18648
18666
  /**
18649
- * Bind a role (by name) to a service identity. Pool-scoped bindings
18650
- * pass `scopeRefs: [{kind: 'jobPool', poolId: ...}]`. User-owned
18651
- * pools pass `userId` as the structural principal; team/org-owned
18652
- * pools pass `teamId`/`orgId`.
18667
+ * Bind a role (by name) to a service identity, anchored to a
18668
+ * structural principal: user-owned Sifters pass `userId`;
18669
+ * team/org-anchored bindings pass `teamId`/`orgId`.
18653
18670
  *
18654
18671
  * Requires `keep:role-bindings:write`.
18655
18672
  */
@@ -21981,7 +21998,7 @@ var import_path = require("path");
21981
21998
  var import_promises = require("fs/promises");
21982
21999
  var import_yaml = __toESM(require_dist());
21983
22000
  var import_shuttle = __toESM(require_dist5());
21984
- var buildVersion = true ? "0.17.0" : pkg.version;
22001
+ var buildVersion = true ? "0.19.0" : pkg.version;
21985
22002
  var sifterBrand = {
21986
22003
  product: {
21987
22004
  id: "sifter",