@gjermundgaraba/clankercreds 0.3.0 → 0.5.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.
@@ -1,4 +1,4 @@
1
- import { a as NeedsSignIn, d as ProviderUnavailable, i as Name, l as scopes, n as Conflict, o as NotFound, r as Host, s as UpstreamUnavailable, u as CurrentPrincipal } from "./shared-DBK2cCkw.mjs";
1
+ import { a as Name, c as SecretKind, d as scopes, f as CurrentPrincipal, i as LoginKind, l as UpstreamUnavailable, n as Conflict, o as NeedsSignIn, p as ProviderUnavailable, r as Host, s as NotFound } from "./shared-DyTG-WFI.mjs";
2
2
  import { Config, Console, Effect, Option, Redacted, Schema } from "effect";
3
3
  import * as Action from "@gjermundgaraba/effect-actions/Action";
4
4
  import * as ActionHttp from "@gjermundgaraba/effect-actions/ActionHttp";
@@ -12,8 +12,6 @@ import * as ActionCli from "@gjermundgaraba/effect-actions/ActionCli";
12
12
  //#region ../../packages/api/src/admin.ts
13
13
  /** Written by the service, always ISO. What an operator enters is decoded as a date instead. */
14
14
  const Timestamp = Schema.String;
15
- /** The kinds an operator stores a value for. A ChatGPT login only ever comes from a sign-in. */
16
- const SecretKind = Schema.Literals(["gh", "claude"]);
17
15
  /** A stored secret's state. The value itself is never read back out. */
18
16
  const SecretStatus = Schema.Struct({
19
17
  name: Name,
@@ -24,20 +22,21 @@ const SecretStatus = Schema.Struct({
24
22
  createdAt: Timestamp,
25
23
  updatedAt: Timestamp
26
24
  });
27
- /** A ChatGPT login's state. It exists from the first completed sign-in on. */
28
- const ChatgptStatus = Schema.Struct({
25
+ /** A login's state. It exists from the first completed sign-in on. */
26
+ const LoginStatus = Schema.Struct({
29
27
  name: Name,
30
- kind: Schema.Literal("chatgpt"),
28
+ kind: LoginKind,
31
29
  needsSignIn: Schema.Boolean,
32
30
  email: Schema.NullOr(Schema.String),
33
- accountId: Schema.String,
31
+ /** The ChatGPT account a ChatGPT login is for; null for every other kind. */
32
+ accountId: Schema.NullOr(Schema.String),
34
33
  accessExpiresAt: Timestamp,
35
34
  lastRefreshAt: Timestamp,
36
35
  lastError: Schema.NullOr(Schema.String),
37
36
  createdAt: Timestamp,
38
37
  updatedAt: Timestamp
39
38
  });
40
- const CredentialStatus = Schema.Union([SecretStatus, ChatgptStatus]);
39
+ const CredentialStatus = Schema.Union([SecretStatus, LoginStatus]);
41
40
  /** The clankerauth id of a machine key. */
42
41
  const KeyId = Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(256));
43
42
  /**
@@ -65,16 +64,21 @@ const ClaudeSignIn = Schema.Struct({
65
64
  * `authorizeUrl`. An approval that left out a scope the token needs ends it: start again.
66
65
  */
67
66
  var SignInRefused = class extends Schema.TaggedError()("SignInRefused", { message: Schema.String }, { httpApiStatus: 422 }) {};
67
+ /**
68
+ * A login's sign-in: open `verificationUrl` and approve, entering `userCode` where the
69
+ * provider asks for one. Cursor's link carries everything and has no code.
70
+ */
68
71
  const SignInState = Schema.Struct({
69
72
  signInId: Schema.String,
70
73
  credential: Name,
74
+ kind: LoginKind,
71
75
  status: Schema.Literals([
72
76
  "pending",
73
77
  "complete",
74
78
  "failed",
75
79
  "expired"
76
80
  ]),
77
- userCode: Schema.String,
81
+ userCode: Schema.NullOr(Schema.String),
78
82
  verificationUrl: Schema.String,
79
83
  expiresAt: Timestamp,
80
84
  message: Schema.optionalKey(Schema.String)
@@ -108,10 +112,10 @@ const AuditQuery = Schema.Struct({
108
112
  clientId: Schema.optionalKey(Schema.String)
109
113
  });
110
114
  /**
111
- * A read whose user code signs a ChatGPT account in: exported so the server's authorization
115
+ * A read whose code or link signs an account in: exported so the server's authorization
112
116
  * rule can name it.
113
117
  */
114
- const GetChatgptSignIn = Action.make("getChatgptSignIn", {
118
+ const GetSignIn = Action.make("getSignIn", {
115
119
  readOnly: true,
116
120
  caller: CurrentPrincipal,
117
121
  description: "Read a sign-in. The service holds one in memory only, until the next sign-in starts after it expired; one it no longer holds is not found.",
@@ -124,17 +128,18 @@ const Admin = [
124
128
  Action.make("listCredentials", {
125
129
  readOnly: true,
126
130
  caller: CurrentPrincipal,
127
- description: "Every credential with its state: expiry, last refresh, last error and whether a ChatGPT login needs a new sign-in. Values are never returned.",
131
+ description: "Every credential with its state: expiry, last refresh, last error and whether a login needs a new sign-in. Values are never returned.",
128
132
  success: Schema.Struct({ credentials: Schema.Array(CredentialStatus) })
129
133
  }),
130
134
  Action.make("putCredential", {
131
135
  readOnly: false,
132
136
  caller: CurrentPrincipal,
133
- description: "Store a secret under a name, or replace its value and expiry. A `gh` token is for `host`, github.com unless given. A credential's kind and host never change; remove it and put it again instead. Machines receive it on their next sync.",
137
+ description: "Store a secret under a name, or replace its value and expiry: a `gh` or `claude` token a machine places, or a `token`, any other service's API key, which a service such as clankerusage reads. A `gh` token is for `host`, github.com unless given. A credential's kind and host never change; remove it and put it again instead. Keys granted it receive it on their next sync.",
134
138
  input: Schema.Struct({
135
139
  name: Name,
136
140
  kind: SecretKind,
137
- value: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(16384)),
141
+ /** Surrounding whitespace, such as a pasted line ending, is not part of a secret: a value carrying any is refused, never altered. */
142
+ value: Schema.Trimmed.check(Schema.isMinLength(1), Schema.isMaxLength(16384)),
138
143
  host: Schema.optionalKey(Host),
139
144
  /** Any date string JavaScript parses; a typo is refused, so alerting never loses it. Left out, it does not expire. */
140
145
  expiresAt: Schema.optionalKey(Schema.DateFromString)
@@ -153,21 +158,24 @@ const Admin = [
153
158
  success: Schema.Void,
154
159
  error: [NotFound, Conflict]
155
160
  }),
156
- Action.make("startChatgptSignIn", {
161
+ Action.make("startSignIn", {
157
162
  readOnly: false,
158
163
  caller: CurrentPrincipal,
159
- description: "Start a device-code sign-in for a ChatGPT credential; the credential is created, or its login replaced, when the sign-in completes. Approve the code at the returned URL, then poll getChatgptSignIn.",
160
- input: Schema.Struct({ name: Name }),
164
+ description: "Start a sign-in for a ChatGPT, Grok or Cursor login; the credential is created, or its login replaced, when the sign-in completes. Open the returned verificationUrl and approve, entering userCode where one is given, then poll getSignIn.",
165
+ input: Schema.Struct({
166
+ name: Name,
167
+ kind: LoginKind
168
+ }),
161
169
  success: SignInState,
162
170
  error: [Conflict, UpstreamUnavailable]
163
171
  }),
164
- GetChatgptSignIn,
165
- Action.make("refreshChatgptCredential", {
172
+ GetSignIn,
173
+ Action.make("refreshCredential", {
166
174
  readOnly: false,
167
175
  caller: CurrentPrincipal,
168
- description: "Refresh one ChatGPT login now instead of waiting for its schedule.",
176
+ description: "Refresh one login now instead of waiting for its schedule.",
169
177
  input: Schema.Struct({ name: Name }),
170
- success: ChatgptStatus,
178
+ success: LoginStatus,
171
179
  error: [
172
180
  NotFound,
173
181
  Conflict,
@@ -236,7 +244,7 @@ const AdminHttp = ActionHttp.make(Admin, {
236
244
  });
237
245
  //#endregion
238
246
  //#region package.json
239
- var version = "0.3.0";
247
+ var version = "0.5.0";
240
248
  //#endregion
241
249
  //#region src/admin.ts
242
250
  /** A refusal of this command's own, printed as its message on stderr, exiting 1. */
@@ -287,11 +295,11 @@ const operator = Effect.gen(function* () {
287
295
  });
288
296
  /**
289
297
  * The secret's value, from stdin: a flag would leave it in the process list and the shell's
290
- * history. Line endings a pipe adds, such as `op read`'s, are not part of it.
298
+ * history. Surrounding whitespace, such as the line ending `op read` adds, is not part of it.
291
299
  */
292
300
  const valueFromStdin = Effect.gen(function* () {
293
301
  if (process.stdin.isTTY) return yield* refused("Pipe the value in, such as `op read 'op://…' | clankercreds admin put-credential …`; it is never taken from a flag or the terminal.");
294
- const value = (yield* Effect.promise(() => text(process.stdin))).replace(/[\r\n]+$/, "");
302
+ const value = (yield* Effect.promise(() => text(process.stdin))).trim();
295
303
  if (value === "") return yield* refused("The value on stdin is empty.");
296
304
  return value;
297
305
  });
@@ -299,7 +307,7 @@ const json = (value) => Console.log(JSON.stringify(value, null, 2));
299
307
  /** `putCredential`, its value read from stdin and every other field a flag. */
300
308
  const putCredential = Command.make("put-credential", {
301
309
  name: Flag.String("name").pipe(Flag.withDescription("The credential's name")),
302
- kind: Flag.Literals("kind", SecretKind.literals).pipe(Flag.withDescription("The tool the secret is for")),
310
+ kind: Flag.Literals("kind", SecretKind.literals).pipe(Flag.withDescription("What the secret is: a gh or claude token a machine places, or a token, any other service's API key")),
303
311
  host: Flag.String("host").pipe(Flag.withDescription("A gh token's host; github.com when left out"), Flag.optional),
304
312
  expiresAt: Flag.String("expires-at").pipe(Flag.withDescription("When the secret expires, any date string; it never does when left out"), Flag.optional)
305
313
  }, ({ name, kind, host, expiresAt }) => Effect.gen(function* () {
package/dist/main.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as NeedsSignIn, c as claimsOf, d as ProviderUnavailable, i as Name, o as NotFound, s as UpstreamUnavailable, t as ClientId, u as CurrentPrincipal } from "./shared-DBK2cCkw.mjs";
2
+ import { a as Name, f as CurrentPrincipal, l as UpstreamUnavailable, o as NeedsSignIn, p as ProviderUnavailable, s as NotFound, t as ClientId, u as claimsOf } from "./shared-DyTG-WFI.mjs";
3
3
  import { homedir } from "node:os";
4
4
  import { dirname, join } from "node:path";
5
5
  import { Effect, Option, Predicate, Schema } from "effect";
@@ -11,8 +11,16 @@ import { randomBytes } from "node:crypto";
11
11
  import { HttpClient, HttpClientRequest } from "effect/http";
12
12
  import { YAMLMap, isMap, parseDocument } from "yaml";
13
13
  //#region ../../packages/api/src/credentials.ts
14
- /** The credential an entry was delivered from, as the machine asked for it by name. */
15
- const fromCredential = { credential: Name };
14
+ /**
15
+ * The credential an entry was delivered from, as it was asked for by name, and when what it
16
+ * carries expires, as ISO: a secret's as the operator entered it, a login's access token's
17
+ * own. Null never expires. A login delivered past it could not be renewed in time, as when its
18
+ * provider is away: sync again later. Whether it needs a new sign-in is the operator's to see.
19
+ */
20
+ const fromCredential = {
21
+ credential: Name,
22
+ expiresAt: Schema.NullOr(Schema.String)
23
+ };
16
24
  const GhCredential = Schema.Struct({
17
25
  type: Schema.Literal("gh"),
18
26
  ...fromCredential,
@@ -48,6 +56,17 @@ const PiCredential = Schema.Struct({
48
56
  accessToken: Schema.String
49
57
  });
50
58
  /**
59
+ * A credential no machine places: an API key, or a Grok or Cursor login's access token, for
60
+ * a service such as clankerusage. `kind` is the credential's own, and any string, so a kind
61
+ * newer than the caller's contract still decodes. The client skips one a config names.
62
+ */
63
+ const TokenCredential = Schema.Struct({
64
+ type: Schema.Literal("token"),
65
+ ...fromCredential,
66
+ kind: Schema.String,
67
+ token: Schema.String
68
+ });
69
+ /**
51
70
  * The service sends typed credentials, never file contents or paths, so it cannot write
52
71
  * anything on a machine but what the client knows how to place. The cost is that a new
53
72
  * tool, or a placement fix, needs a client release, which new machines install. Each entry
@@ -64,7 +83,8 @@ const TypedCredential = Schema.Union([
64
83
  GhCredential,
65
84
  ClaudeCredential,
66
85
  CodexCredential,
67
- PiCredential
86
+ PiCredential,
87
+ TokenCredential
68
88
  ]);
69
89
  /** The types this build knows, derived from the union so there is one list. */
70
90
  const knownTypes = TypedCredential.members.map((member) => member.fields.type.literal);
@@ -75,39 +95,57 @@ const isKnownType = (type) => knownTypes.some((known) => known === type);
75
95
  * schema must not land here, or a broken credential would be placed as an empty one.
76
96
  */
77
97
  const UnknownCredential = Schema.Struct({ type: Schema.String.check(Schema.makeFilter((type) => !isKnownType(type), { message: "a known credential type must match its schema" })) });
78
- /** Everything the machine asked for, sent in full on every sync. */
98
+ /** Everything the caller asked for, sent in full on every sync. */
79
99
  const Delivery = Schema.Struct({ credentials: Schema.Array(Schema.Union([TypedCredential, UnknownCredential])) });
80
100
  //#endregion
81
101
  //#region ../../packages/api/src/machine.ts
82
102
  /**
103
+ * A credential the calling key may read, without its value. `kind` is any string, so a kind
104
+ * newer than the caller's contract does not fail the whole list.
105
+ */
106
+ const Grant = Schema.Struct({
107
+ name: Name,
108
+ kind: Schema.String
109
+ });
110
+ /**
83
111
  * What a machine key can do: read the credentials it is granted, by name, and nothing else.
84
- * The machine names what it wants; the grants on the server decide whether it may.
112
+ * The caller names what it wants; the grants on the server decide whether it may. A machine
113
+ * is one caller; a service such as clankerusage, holding a key of its own, is another.
85
114
  */
86
- const Machine = [Action.make("sync", {
87
- readOnly: false,
88
- caller: CurrentPrincipal,
89
- description: "Fetch the named credentials as typed entries. Refused whole when the calling key is not granted any one of them.",
90
- input: Schema.Struct({
91
- clientId: ClientId,
92
- credentials: Schema.Array(Name)
115
+ const Machine = [
116
+ Action.make("sync", {
117
+ readOnly: false,
118
+ caller: CurrentPrincipal,
119
+ description: "Fetch the named credentials as typed entries, each with its expiry; a login near expiry is refreshed first. Refused whole when the calling key is not granted any one of them.",
120
+ input: Schema.Struct({
121
+ clientId: ClientId,
122
+ credentials: Schema.Array(Name)
123
+ }),
124
+ success: Delivery,
125
+ error: NotFound
93
126
  }),
94
- success: Delivery,
95
- error: NotFound
96
- }), Action.make("codexLogin", {
97
- readOnly: false,
98
- caller: CurrentPrincipal,
99
- description: "The current login of a ChatGPT credential the calling key is granted, as the codex type carries it, refreshed first when it has expired.",
100
- input: Schema.Struct({
101
- clientId: ClientId,
102
- credential: Name
127
+ Action.make("codexLogin", {
128
+ readOnly: false,
129
+ caller: CurrentPrincipal,
130
+ description: "The current login of a ChatGPT credential the calling key is granted, as the codex type carries it, refreshed first when it has expired.",
131
+ input: Schema.Struct({
132
+ clientId: ClientId,
133
+ credential: Name
134
+ }),
135
+ success: CodexLogin,
136
+ error: [
137
+ NotFound,
138
+ NeedsSignIn,
139
+ UpstreamUnavailable
140
+ ]
103
141
  }),
104
- success: CodexLogin,
105
- error: [
106
- NotFound,
107
- NeedsSignIn,
108
- UpstreamUnavailable
109
- ]
110
- })];
142
+ Action.make("listGrants", {
143
+ readOnly: true,
144
+ caller: CurrentPrincipal,
145
+ description: "The names and kinds of the credentials the calling key is granted, so a caller can offer them to pick from. Values are never returned.",
146
+ success: Schema.Struct({ credentials: Schema.Array(Grant) })
147
+ })
148
+ ];
111
149
  /**
112
150
  * Codex treats a 401 as permanent and stops retrying; every other failure is transient.
113
151
  * The codes are the ones Codex classifies: `refresh_token_invalidated` reads as revoked.
@@ -582,6 +620,9 @@ const placements = {
582
620
  remove: (config) => removePi(config.home)
583
621
  }
584
622
  };
623
+ /** What this client places; anything else delivered, a token or a type it does not know, is skipped. */
624
+ const isPlaceable = (credential) => Object.hasOwn(placements, credential.type);
625
+ const placeableTypes = knownTypes.filter((type) => Object.hasOwn(placements, type));
585
626
  /** What the delivery carries of one type is placed; a type it does not carry is undone. */
586
627
  const settle = (config, identity, known, type) => {
587
628
  const credentials = known.filter((credential) => credential.type === type);
@@ -602,16 +643,17 @@ const slot = (credential) => {
602
643
  }
603
644
  };
604
645
  /**
605
- * Two credentials for one slot would leave the machine holding whichever came last, so the
646
+ * Two credentials for one slot would leave the machine holding whichever came last: the
606
647
  * whole sync is refused before anything is written.
607
648
  */
608
- const refuseShared = (known) => {
649
+ const oneEach = (placed) => {
609
650
  const claimed = /* @__PURE__ */ new Map();
610
- for (const credential of known) {
651
+ for (const credential of placed) {
611
652
  const other = claimed.get(slot(credential));
612
653
  if (other !== void 0 && other !== credential.credential) throw new Error(`${other} and ${credential.credential} are both ${slot(credential)}; a machine holds one, so config.json must name only one of them`);
613
654
  claimed.set(slot(credential), credential.credential);
614
655
  }
656
+ return placed;
615
657
  };
616
658
  /**
617
659
  * Idempotent: every credential the config names is fetched and placed every time, and every
@@ -626,15 +668,14 @@ const sync = async (config) => {
626
668
  key: config.key
627
669
  };
628
670
  const delivery = await fetchDelivery(config, identity.clientId);
629
- const known = delivery.credentials.filter((credential) => isKnownType(credential.type));
630
- refuseShared(known);
671
+ const known = oneEach(delivery.credentials.filter(isPlaceable));
631
672
  const report = {
632
673
  placed: new Array(),
633
674
  removed: new Array(),
634
- skipped: delivery.credentials.flatMap(({ type }) => isKnownType(type) ? [] : [type]),
675
+ skipped: delivery.credentials.flatMap((credential) => isPlaceable(credential) ? [] : [credential.type]),
635
676
  failed: new Array()
636
677
  };
637
- for (const type of knownTypes) try {
678
+ for (const type of placeableTypes) try {
638
679
  const outcome = settle(config, identity, known, type);
639
680
  if (outcome !== void 0) report[outcome].push(type);
640
681
  } catch (error) {
@@ -684,7 +725,7 @@ const usage = `Usage: clankercreds <command>
684
725
  `;
685
726
  const runSync = async () => {
686
727
  const report = await sync(loadConfig());
687
- for (const type of report.skipped) console.error(`warning: skipped unknown credential type "${type}"; update clankercreds`);
728
+ for (const type of report.skipped) console.error(`warning: skipped credential type "${type}", which this client does not place; if it is new, update clankercreds`);
688
729
  for (const type of report.placed) console.log(`placed ${type}`);
689
730
  for (const type of report.removed) console.log(`removed ${type}`);
690
731
  for (const { type, message } of report.failed) console.error(`error: ${type}: ${message}`);
@@ -704,7 +745,7 @@ const commandFor = (name) => {
704
745
  };
705
746
  const main = async () => {
706
747
  if (process.argv[2] === "admin") {
707
- (await import("./admin-CXDLXpaH.mjs")).run(process.argv.slice(2));
748
+ (await import("./admin-BcOFNDUc.mjs")).run(process.argv.slice(2));
708
749
  return;
709
750
  }
710
751
  const command = commandFor(process.argv[2]);
@@ -16,7 +16,7 @@ var ProviderUnavailable = class extends Schema.TaggedError()("ProviderUnavailabl
16
16
  Data.TaggedError("InsufficientScope");
17
17
  Schema.TaggedError()("ConfigurationError", { message: Schema.String });
18
18
  //#endregion
19
- //#region ../../node_modules/.pnpm/@gjermundgaraba+clankerauth-sdk@0.15.0_@gjermundgaraba+effect-actions@0.11.0_effect@4.0.2__effect@4.0.2/node_modules/@gjermundgaraba/clankerauth-sdk/dist/session.js
19
+ //#region ../../node_modules/.pnpm/@gjermundgaraba+clankerauth-sdk@0.16.0_@gjermundgaraba+effect-actions@0.11.0_effect@4.0.2__effect@4.0.2/node_modules/@gjermundgaraba/clankerauth-sdk/dist/session.js
20
20
  /**
21
21
  * The identity a browser page needs, without any verification code. This entry point is
22
22
  * browser-safe: it declares the identity a protected contract states, the `whoami` contract
@@ -62,9 +62,9 @@ const scopes = {
62
62
  var NotFound = class extends Schema.TaggedError()("NotFound", { message: Schema.String }, { httpApiStatus: 404 }) {};
63
63
  /** The change collides with what is stored: a taken name, or a credential still in use. */
64
64
  var Conflict = class extends Schema.TaggedError()("Conflict", { message: Schema.String }, { httpApiStatus: 409 }) {};
65
- /** The ChatGPT login is dead, or was never completed. Only a new device sign-in revives it. */
65
+ /** The login is dead, or was never completed. Only a new sign-in revives it. */
66
66
  var NeedsSignIn = class extends Schema.TaggedError()("NeedsSignIn", { message: Schema.String }, { httpApiStatus: 409 }) {};
67
- /** OpenAI could not be reached and no valid token is held. Waiting helps; retrying now does not. */
67
+ /** The provider could not be reached and no valid token is held. Waiting helps; retrying now does not. */
68
68
  var UpstreamUnavailable = class extends Schema.TaggedError()("UpstreamUnavailable", { message: Schema.String }, { httpApiStatus: 503 }) {};
69
69
  /**
70
70
  * Credential names: lowercase labels, because they are typed by hand and are
@@ -72,6 +72,25 @@ var UpstreamUnavailable = class extends Schema.TaggedError()("UpstreamUnavailabl
72
72
  * and `github-main` be two credentials.
73
73
  */
74
74
  const Name = Schema.String.check(Schema.isPattern(/^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/));
75
+ /**
76
+ * What an operator stores a value for: a GitHub token, a Claude token, or `token`, any other
77
+ * service's API key, which a service such as clankerusage reads and no machine places.
78
+ */
79
+ const SecretKind = Schema.Literals([
80
+ "gh",
81
+ "claude",
82
+ "token"
83
+ ]);
84
+ /**
85
+ * What a sign-in creates and the service keeps refreshed. The refresh token never leaves
86
+ * the service; only access tokens are delivered.
87
+ */
88
+ const LoginKind = Schema.Literals([
89
+ "chatgpt",
90
+ "grok",
91
+ "cursor"
92
+ ]);
93
+ Schema.Literals([...SecretKind.literals, ...LoginKind.literals]);
75
94
  /** A GitHub host, lowercase: it is written into `gh`'s and git's configuration as is. */
76
95
  const Host = Schema.String.check(Schema.isPattern(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/), Schema.isMaxLength(253));
77
96
  /**
@@ -85,7 +104,7 @@ const Claims = Schema.Struct({
85
104
  "https://api.openai.com/auth": Schema.optionalKey(Schema.Struct({ chatgpt_account_id: Schema.optionalKey(Schema.String) }))
86
105
  });
87
106
  /**
88
- * The claims of an OpenAI JWT, unverified: they are read for their timing and their
107
+ * The claims of a JWT, unverified: they are read for their timing, email and, in OpenAI's,
89
108
  * account, never trusted for anything. Anything unreadable is simply no claims.
90
109
  */
91
110
  const claimsOf = (jwt) => {
@@ -105,4 +124,4 @@ const claimsOf = (jwt) => {
105
124
  });
106
125
  };
107
126
  //#endregion
108
- export { NeedsSignIn as a, claimsOf as c, ProviderUnavailable as d, Name as i, scopes as l, Conflict as n, NotFound as o, Host as r, UpstreamUnavailable as s, ClientId as t, CurrentPrincipal as u };
127
+ export { Name as a, SecretKind as c, scopes as d, CurrentPrincipal as f, LoginKind as i, UpstreamUnavailable as l, Conflict as n, NeedsSignIn as o, ProviderUnavailable as p, Host as r, NotFound as s, ClientId as t, claimsOf as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjermundgaraba/clankercreds",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "The clankercreds command: a machine client that fetches the credentials its config names and places each where its tool expects it, and the operator's admin commands.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,14 +20,15 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@effect/platform-node": "4.0.2",
23
+ "@effect/platform-node-shared": "4.0.2",
23
24
  "@gjermundgaraba/effect-actions": "0.11.0",
24
25
  "effect": "4.0.2",
25
26
  "yaml": "2.9.1"
26
27
  },
27
28
  "devDependencies": {
28
- "@clankercreds/api": "0.0.0",
29
- "@gjermundgaraba/clankerauth-sdk": "0.15.0",
30
- "@types/node": "26.6.4",
29
+ "@gjermundgaraba/clankerauth-sdk": "0.16.0",
30
+ "@gjermundgaraba/clankercreds-api": "0.5.0",
31
+ "@types/node": "26.6.5",
31
32
  "typescript": "7.0.2",
32
33
  "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
33
34
  "vite-plus": "1.1.0"