@theholocron/cli 2.0.0-alpha.0 → 2.0.0-alpha.5
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/README.md +15 -11
- package/dist/capabilities/index.d.mts +2 -2
- package/dist/capabilities/index.mjs +1 -1
- package/dist/{capabilities-QjjhVlDd.mjs → capabilities-DapaKOlX.mjs} +6 -2
- package/dist/cli.mjs +1927 -24
- package/dist/{index-DDxKXqtR.d.mts → index-jxPVFH7-.d.mts} +84 -34
- package/dist/index.d.mts +90 -5
- package/dist/index.mjs +3 -3
- package/dist/{config-DWlIfFZm.mjs → keyring-DwNEmrBc.mjs} +73 -2
- package/package.json +2 -1
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* See `.notes/tech-architecture.spec.md` for the design narrative
|
|
12
12
|
* (status: proposed, issue: #74).
|
|
13
13
|
*/
|
|
14
|
-
type CapabilityKey =
|
|
15
|
-
type Cardinality =
|
|
14
|
+
type CapabilityKey = "source" | "ci" | "secrets" | "environments" | "issues" | "deployment" | "storage" | "auth" | "vault" | "dns" | "tooling" | "notifications" | "analytics" | "observability";
|
|
15
|
+
type Cardinality = "single" | "many";
|
|
16
16
|
declare const CARDINALITY: {
|
|
17
17
|
readonly source: "single";
|
|
18
18
|
readonly ci: "single";
|
|
@@ -29,7 +29,11 @@ declare const CARDINALITY: {
|
|
|
29
29
|
readonly analytics: "many";
|
|
30
30
|
readonly observability: "many";
|
|
31
31
|
};
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* No capabilities are strictly required — repos without secrets (e.g. org
|
|
34
|
+
* community health repos) legitimately omit vault. Plugins validate their
|
|
35
|
+
* own requirements at call time.
|
|
36
|
+
*/
|
|
33
37
|
declare const REQUIRED_CAPABILITIES: readonly CapabilityKey[];
|
|
34
38
|
interface ProviderIdentity {
|
|
35
39
|
readonly key: CapabilityKey;
|
|
@@ -50,7 +54,7 @@ declare class ProviderApiError extends Error {
|
|
|
50
54
|
interface Ruleset {
|
|
51
55
|
id: number;
|
|
52
56
|
name: string;
|
|
53
|
-
enforcement:
|
|
57
|
+
enforcement: "active" | "evaluate" | "disabled";
|
|
54
58
|
target?: string;
|
|
55
59
|
}
|
|
56
60
|
interface RepoSettings {
|
|
@@ -58,10 +62,14 @@ interface RepoSettings {
|
|
|
58
62
|
allow_merge_commit?: boolean;
|
|
59
63
|
allow_rebase_merge?: boolean;
|
|
60
64
|
allow_auto_merge?: boolean;
|
|
65
|
+
/** Always suggest updating PR branches when the base branch has new commits. */
|
|
66
|
+
allow_update_branch?: boolean;
|
|
61
67
|
delete_branch_on_merge?: boolean;
|
|
62
68
|
default_branch?: string;
|
|
63
69
|
has_issues?: boolean;
|
|
64
70
|
has_discussions?: boolean;
|
|
71
|
+
has_projects?: boolean;
|
|
72
|
+
has_wiki?: boolean;
|
|
65
73
|
}
|
|
66
74
|
interface RepoRef {
|
|
67
75
|
owner: string;
|
|
@@ -69,7 +77,7 @@ interface RepoRef {
|
|
|
69
77
|
defaultBranch: string;
|
|
70
78
|
}
|
|
71
79
|
interface Source extends ProviderIdentity {
|
|
72
|
-
readonly key:
|
|
80
|
+
readonly key: "source";
|
|
73
81
|
/** Auth sanity-check. Throws ProviderApiError on auth failure. */
|
|
74
82
|
whoami(): Promise<{
|
|
75
83
|
login: string;
|
|
@@ -79,16 +87,41 @@ interface Source extends ProviderIdentity {
|
|
|
79
87
|
createRuleset(payload: Record<string, unknown>): Promise<Ruleset>;
|
|
80
88
|
updateRuleset(id: number, payload: Record<string, unknown>): Promise<Ruleset>;
|
|
81
89
|
updateRepoSettings(settings: RepoSettings): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Classic branch protection — fallback for private repos on free plans
|
|
92
|
+
* where the Rulesets API (requires Team+) returns 403.
|
|
93
|
+
*/
|
|
94
|
+
protectBranch(branch: string, payload: Record<string, unknown>): Promise<void>;
|
|
82
95
|
enableVulnerabilityAlerts(): Promise<void>;
|
|
83
96
|
enableAutomatedSecurityFixes(): Promise<void>;
|
|
84
97
|
enableSecretScanning(): Promise<void>;
|
|
85
98
|
enablePrivateVulnerabilityReporting(): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Enables the dependency graph and automatic dependency snapshot
|
|
101
|
+
* submission. Also enables secret-scanning validity checks and
|
|
102
|
+
* non-provider pattern detection — these require GitHub Advanced
|
|
103
|
+
* Security at the org level; the call is accepted but may be a no-op
|
|
104
|
+
* until that is configured.
|
|
105
|
+
*/
|
|
106
|
+
enableDependencyGraph(): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Enables CodeQL default setup with the extended query suite and
|
|
109
|
+
* `threat_model: all` (scans both remote and local exploit paths).
|
|
110
|
+
* Triggers a new analysis run; returns the run id.
|
|
111
|
+
*/
|
|
112
|
+
enableCodeScanning(): Promise<string>;
|
|
86
113
|
listWorkflowFiles(): Promise<string[]>;
|
|
87
114
|
readWorkflowFile(name: string): Promise<string | null>;
|
|
88
115
|
writeWorkflowFile(name: string, contents: string): Promise<void>;
|
|
89
116
|
removeWorkflowFile(name: string): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Write an arbitrary file relative to the repo root. Used for
|
|
119
|
+
* provisioning config files that live outside `.github/workflows/`
|
|
120
|
+
* (e.g. `.github/dependabot.yml`).
|
|
121
|
+
*/
|
|
122
|
+
writeRepoFile(path: string, contents: string): Promise<void>;
|
|
90
123
|
}
|
|
91
|
-
type CiRunStatus =
|
|
124
|
+
type CiRunStatus = "queued" | "in_progress" | "completed" | "cancelled" | "failure" | "success" | "skipped";
|
|
92
125
|
interface CiRun {
|
|
93
126
|
id: string | number;
|
|
94
127
|
workflowName: string;
|
|
@@ -105,21 +138,21 @@ interface CiRunFilter {
|
|
|
105
138
|
limit?: number;
|
|
106
139
|
}
|
|
107
140
|
interface Ci extends ProviderIdentity {
|
|
108
|
-
readonly key:
|
|
141
|
+
readonly key: "ci";
|
|
109
142
|
listRuns(filter?: CiRunFilter): Promise<CiRun[]>;
|
|
110
143
|
getRun(id: string | number): Promise<CiRun>;
|
|
111
144
|
}
|
|
112
145
|
type SecretScope = {
|
|
113
|
-
kind:
|
|
146
|
+
kind: "repo";
|
|
114
147
|
} | {
|
|
115
|
-
kind:
|
|
148
|
+
kind: "environment";
|
|
116
149
|
name: string;
|
|
117
150
|
} | {
|
|
118
|
-
kind:
|
|
151
|
+
kind: "organization";
|
|
119
152
|
name: string;
|
|
120
153
|
};
|
|
121
154
|
interface Secrets extends ProviderIdentity {
|
|
122
|
-
readonly key:
|
|
155
|
+
readonly key: "secrets";
|
|
123
156
|
/** List secret NAMES (not values) at the given scope. */
|
|
124
157
|
listSecrets(scope: SecretScope): Promise<string[]>;
|
|
125
158
|
/** Idempotent upsert. Adapter handles encryption. */
|
|
@@ -127,7 +160,7 @@ interface Secrets extends ProviderIdentity {
|
|
|
127
160
|
deleteSecret(scope: SecretScope, name: string): Promise<void>;
|
|
128
161
|
}
|
|
129
162
|
interface EnvironmentReviewer {
|
|
130
|
-
type:
|
|
163
|
+
type: "User" | "Team";
|
|
131
164
|
/** Numeric id — GitHub's reviewer API silently ignores login strings. */
|
|
132
165
|
id: number;
|
|
133
166
|
}
|
|
@@ -138,13 +171,13 @@ interface Environment {
|
|
|
138
171
|
preventSelfReview?: boolean;
|
|
139
172
|
}
|
|
140
173
|
interface Environments extends ProviderIdentity {
|
|
141
|
-
readonly key:
|
|
174
|
+
readonly key: "environments";
|
|
142
175
|
listEnvironments(): Promise<Environment[]>;
|
|
143
176
|
upsertEnvironment(env: Environment): Promise<void>;
|
|
144
177
|
deleteEnvironment(name: string): Promise<void>;
|
|
145
178
|
}
|
|
146
|
-
type LifecycleSlot =
|
|
147
|
-
type StatusCategory =
|
|
179
|
+
type LifecycleSlot = "inProgress" | "inReview" | "done";
|
|
180
|
+
type StatusCategory = "open" | "in-progress" | "in-review" | "done" | "other";
|
|
148
181
|
interface TrackerUser {
|
|
149
182
|
id: string;
|
|
150
183
|
displayName: string;
|
|
@@ -165,7 +198,7 @@ interface Issue {
|
|
|
165
198
|
}
|
|
166
199
|
interface IssueSearchFilter {
|
|
167
200
|
/** Restrict to issues assigned to a specific id, or 'currentUser'. */
|
|
168
|
-
assignee?: string |
|
|
201
|
+
assignee?: string | "currentUser";
|
|
169
202
|
/** Exclude issues in the `done` category. */
|
|
170
203
|
openOnly?: boolean;
|
|
171
204
|
/** Max number of issues to return. Adapters apply a sensible default. */
|
|
@@ -202,7 +235,7 @@ interface TrackerDoctorReport {
|
|
|
202
235
|
}>;
|
|
203
236
|
}
|
|
204
237
|
interface Issues extends ProviderIdentity {
|
|
205
|
-
readonly key:
|
|
238
|
+
readonly key: "issues";
|
|
206
239
|
/** Currently-authenticated user. */
|
|
207
240
|
getMyself(): Promise<TrackerUser>;
|
|
208
241
|
search(filter: IssueSearchFilter): Promise<Issue[]>;
|
|
@@ -221,12 +254,12 @@ interface Issues extends ProviderIdentity {
|
|
|
221
254
|
doctor(): Promise<TrackerDoctorReport>;
|
|
222
255
|
}
|
|
223
256
|
/** Env-var scope on the deploy platform. */
|
|
224
|
-
type DeploymentTarget =
|
|
257
|
+
type DeploymentTarget = "development" | "preview" | "production";
|
|
225
258
|
/**
|
|
226
259
|
* Named deployment trigger target — `undefined` means a branch
|
|
227
260
|
* preview (no named environment).
|
|
228
261
|
*/
|
|
229
|
-
type DeploymentTrigger =
|
|
262
|
+
type DeploymentTrigger = "production" | "staging";
|
|
230
263
|
interface DeploymentProject {
|
|
231
264
|
id: string;
|
|
232
265
|
name: string;
|
|
@@ -248,10 +281,10 @@ interface DeploymentRecord {
|
|
|
248
281
|
branch: string | null;
|
|
249
282
|
/** Named environment if one was targeted; undefined for branch previews. */
|
|
250
283
|
target?: DeploymentTrigger;
|
|
251
|
-
status:
|
|
284
|
+
status: "queued" | "building" | "ready" | "error" | "cancelled";
|
|
252
285
|
}
|
|
253
286
|
interface Deployment extends ProviderIdentity {
|
|
254
|
-
readonly key:
|
|
287
|
+
readonly key: "deployment";
|
|
255
288
|
listProjects(): Promise<DeploymentProject[]>;
|
|
256
289
|
/** Create if missing, otherwise return existing. Idempotent. */
|
|
257
290
|
ensureProject(input: {
|
|
@@ -287,7 +320,7 @@ interface ConnectionStringOptions {
|
|
|
287
320
|
pooled?: boolean;
|
|
288
321
|
}
|
|
289
322
|
interface Storage extends ProviderIdentity {
|
|
290
|
-
readonly key:
|
|
323
|
+
readonly key: "storage";
|
|
291
324
|
/**
|
|
292
325
|
* Connection string for the given scope. Scope is provider-specific:
|
|
293
326
|
*
|
|
@@ -343,7 +376,7 @@ interface WebhookDashboardInfo {
|
|
|
343
376
|
url: string;
|
|
344
377
|
}
|
|
345
378
|
interface Auth extends ProviderIdentity {
|
|
346
|
-
readonly key:
|
|
379
|
+
readonly key: "auth";
|
|
347
380
|
/** Env-var keys the runtime app needs. */
|
|
348
381
|
describe(): Promise<AuthDescription>;
|
|
349
382
|
/** Reachability probe — proves the configured key works. */
|
|
@@ -362,7 +395,7 @@ interface Auth extends ProviderIdentity {
|
|
|
362
395
|
secretRef: string;
|
|
363
396
|
}): Promise<void>;
|
|
364
397
|
}
|
|
365
|
-
type AuthEventType =
|
|
398
|
+
type AuthEventType = "user.created" | "user.updated" | "user.deleted";
|
|
366
399
|
interface NormalizedAuthUser {
|
|
367
400
|
id: string;
|
|
368
401
|
email: string;
|
|
@@ -388,8 +421,12 @@ interface ParseWebhookInput {
|
|
|
388
421
|
declare class WebhookVerificationError extends Error {
|
|
389
422
|
name: string;
|
|
390
423
|
}
|
|
424
|
+
interface EnsureResult {
|
|
425
|
+
/** True when the resource already existed (idempotent no-op). */
|
|
426
|
+
alreadyExists: boolean;
|
|
427
|
+
}
|
|
391
428
|
interface Vault extends ProviderIdentity {
|
|
392
|
-
readonly key:
|
|
429
|
+
readonly key: "vault";
|
|
393
430
|
/**
|
|
394
431
|
* Read a secret by reference. The reference format is
|
|
395
432
|
* provider-specific (1P: "op://Vault/Item/field"; HashiCorp Vault:
|
|
@@ -413,8 +450,21 @@ interface Vault extends ProviderIdentity {
|
|
|
413
450
|
* destinations (CI secrets, deployment env vars, local .env).
|
|
414
451
|
*/
|
|
415
452
|
readEnvironment?(environmentId: string): Promise<Record<string, string>>;
|
|
453
|
+
/**
|
|
454
|
+
* Optional — create the top-level project container in the vault
|
|
455
|
+
* if it does not exist. Idempotent: `alreadyExists: true` when the
|
|
456
|
+
* project was already there. Providers whose data model has no
|
|
457
|
+
* project notion (or that gate this behind a paid tier) omit this.
|
|
458
|
+
*/
|
|
459
|
+
ensureProject?(name: string): Promise<EnsureResult>;
|
|
460
|
+
/**
|
|
461
|
+
* Optional — create a named environment/config inside a project
|
|
462
|
+
* (e.g., Doppler config `dev` / `stg` / `prd`). Idempotent.
|
|
463
|
+
* Providers whose data model has a single flat namespace omit this.
|
|
464
|
+
*/
|
|
465
|
+
ensureEnvironment?(project: string, name: string): Promise<EnsureResult>;
|
|
416
466
|
}
|
|
417
|
-
type DnsRecordType =
|
|
467
|
+
type DnsRecordType = "A" | "AAAA" | "CNAME" | "TXT" | "MX" | "NS" | "SRV" | "CAA";
|
|
418
468
|
interface DnsRecord {
|
|
419
469
|
id?: string;
|
|
420
470
|
type: DnsRecordType;
|
|
@@ -424,7 +474,7 @@ interface DnsRecord {
|
|
|
424
474
|
priority?: number;
|
|
425
475
|
}
|
|
426
476
|
interface Dns extends ProviderIdentity {
|
|
427
|
-
readonly key:
|
|
477
|
+
readonly key: "dns";
|
|
428
478
|
listRecords(domain: string): Promise<DnsRecord[]>;
|
|
429
479
|
upsertRecord(domain: string, record: DnsRecord): Promise<DnsRecord>;
|
|
430
480
|
deleteRecord(domain: string, id: string): Promise<void>;
|
|
@@ -434,13 +484,13 @@ interface ToolingDoctorReport {
|
|
|
434
484
|
message: string;
|
|
435
485
|
}
|
|
436
486
|
interface Tooling extends ProviderIdentity {
|
|
437
|
-
readonly key:
|
|
487
|
+
readonly key: "tooling";
|
|
438
488
|
/** Sync the tool's authoritative state from the repo. */
|
|
439
489
|
sync(): Promise<void>;
|
|
440
490
|
doctor(): Promise<ToolingDoctorReport>;
|
|
441
491
|
}
|
|
442
492
|
interface Notifications extends ProviderIdentity {
|
|
443
|
-
readonly key:
|
|
493
|
+
readonly key: "notifications";
|
|
444
494
|
/**
|
|
445
495
|
* Send a message. `channel` is provider-specific (Slack channel id,
|
|
446
496
|
* Discord webhook url-name, etc.); adapters resolve from config.
|
|
@@ -448,14 +498,14 @@ interface Notifications extends ProviderIdentity {
|
|
|
448
498
|
send(channel: string, message: string): Promise<void>;
|
|
449
499
|
}
|
|
450
500
|
interface Analytics extends ProviderIdentity {
|
|
451
|
-
readonly key:
|
|
501
|
+
readonly key: "analytics";
|
|
452
502
|
describe(): Promise<{
|
|
453
503
|
provider: string;
|
|
454
504
|
dsnEnvKey: string;
|
|
455
505
|
}>;
|
|
456
506
|
}
|
|
457
507
|
interface Observability extends ProviderIdentity {
|
|
458
|
-
readonly key:
|
|
508
|
+
readonly key: "observability";
|
|
459
509
|
describe(): Promise<{
|
|
460
510
|
provider: string;
|
|
461
511
|
dsnEnvKey: string;
|
|
@@ -479,7 +529,7 @@ interface CapabilityImpls {
|
|
|
479
529
|
}
|
|
480
530
|
type CardinalityFor<K extends CapabilityKey> = (typeof CARDINALITY)[K];
|
|
481
531
|
/** Resolved runtime shape: single → one impl; many → array. */
|
|
482
|
-
type ResolvedCapability<K extends CapabilityKey> = CardinalityFor<K> extends
|
|
483
|
-
declare function isMulti<K extends CapabilityKey>(key: K): CardinalityFor<K> extends
|
|
532
|
+
type ResolvedCapability<K extends CapabilityKey> = CardinalityFor<K> extends "many" ? CapabilityImpls[K][] : CapabilityImpls[K];
|
|
533
|
+
declare function isMulti<K extends CapabilityKey>(key: K): CardinalityFor<K> extends "many" ? true : false;
|
|
484
534
|
//#endregion
|
|
485
|
-
export {
|
|
535
|
+
export { StorageBranch as $, EnvironmentReviewer as A, ParseWebhookInput as B, DeploymentTarget as C, DnsRecordType as D, DnsRecord as E, LifecycleResult as F, RepoSettings as G, ProviderIdentity as H, LifecycleSlot as I, SecretScope as J, ResolvedCapability as K, NormalizedAuthUser as L, Issue as M, IssueSearchFilter as N, EnsureResult as O, Issues as P, Storage as Q, Notifications as R, DeploymentRecord as S, Dns as T, REQUIRED_CAPABILITIES as U, ProviderApiError as V, RepoRef as W, Source as X, Secrets as Y, StatusCategory as Z, ConnectionStringOptions as _, AuthEventType as a, WebhookDashboardInfo as at, DeploymentProject as b, CARDINALITY as c, Cardinality as d, Tooling as et, CardinalityFor as f, CiRunStatus as g, CiRunFilter as h, AuthEvent as i, Vault as it, Environments as j, Environment as k, CapabilityImpls as l, CiRun as m, Auth as n, TrackerDoctorReport as nt, AuthIdentity as o, WebhookVerificationError as ot, Ci as p, Ruleset as q, AuthDescription as r, TrackerUser as rt, AuthUser as s, isMulti as st, Analytics as t, ToolingDoctorReport as tt, CapabilityKey as u, CreateAuthUserInput as v, DeploymentTrigger as w, DeploymentProjectSettings as x, Deployment as y, Observability as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as StorageBranch, A as EnvironmentReviewer, B as ParseWebhookInput, C as DeploymentTarget, D as DnsRecordType, E as DnsRecord, F as LifecycleResult, G as RepoSettings, H as ProviderIdentity, I as LifecycleSlot, J as SecretScope, K as ResolvedCapability, L as NormalizedAuthUser, M as Issue, N as IssueSearchFilter, O as EnsureResult, P as Issues, Q as Storage, R as Notifications, S as DeploymentRecord, T as Dns, U as REQUIRED_CAPABILITIES, V as ProviderApiError, W as RepoRef, X as Source, Y as Secrets, Z as StatusCategory, _ as ConnectionStringOptions, a as AuthEventType, at as WebhookDashboardInfo, b as DeploymentProject, c as CARDINALITY, d as Cardinality, et as Tooling, f as CardinalityFor, g as CiRunStatus, h as CiRunFilter, i as AuthEvent, it as Vault, j as Environments, k as Environment, l as CapabilityImpls, m as CiRun, n as Auth, nt as TrackerDoctorReport, o as AuthIdentity, ot as WebhookVerificationError, p as Ci, q as Ruleset, r as AuthDescription, rt as TrackerUser, s as AuthUser, st as isMulti, t as Analytics, tt as ToolingDoctorReport, u as CapabilityKey, v as CreateAuthUserInput, w as DeploymentTrigger, x as DeploymentProjectSettings, y as Deployment, z as Observability } from "./index-jxPVFH7-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/config.d.ts
|
|
4
4
|
type ProviderOptions = Record<string, unknown>;
|
|
@@ -6,6 +6,22 @@ type SingleEntry = string | [provider: string, options: ProviderOptions];
|
|
|
6
6
|
type MultiEntry = Array<string | [provider: string, options: ProviderOptions]>;
|
|
7
7
|
type RawProviderEntry = SingleEntry | MultiEntry;
|
|
8
8
|
type RawProvidersConfig = Partial<Record<CapabilityKey, RawProviderEntry>>;
|
|
9
|
+
interface RepoPolicyConfig {
|
|
10
|
+
/**
|
|
11
|
+
* "balanced" — squash-only merges, delete-branch-on-merge, issues/discussions/projects
|
|
12
|
+
* enabled, auto-merge enabled, web sign-off required, always suggest updating, no wiki;
|
|
13
|
+
* plus a ruleset that blocks force-push + deletion and requires a pull request (0 reviews).
|
|
14
|
+
*
|
|
15
|
+
* "strict" — everything in "balanced" plus required status checks from `requiredChecks`.
|
|
16
|
+
*
|
|
17
|
+
* "none" — skips repo settings + ruleset entirely.
|
|
18
|
+
*
|
|
19
|
+
* @default "balanced"
|
|
20
|
+
*/
|
|
21
|
+
preset?: "balanced" | "strict" | "none";
|
|
22
|
+
/** CI check context names required on the default branch (used by "strict"). */
|
|
23
|
+
requiredChecks?: string[];
|
|
24
|
+
}
|
|
9
25
|
interface AppConfig {
|
|
10
26
|
name: string;
|
|
11
27
|
path: string;
|
|
@@ -18,6 +34,31 @@ interface HolocronConfig {
|
|
|
18
34
|
project: {
|
|
19
35
|
name: string;
|
|
20
36
|
description?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Repo coord — `"owner/name"`. When set, `PluginLoader` injects
|
|
39
|
+
* it into every plugin's `RuntimeContext.repo` so plugins that
|
|
40
|
+
* need a repo (github, etc.) don't require `--repo` on every
|
|
41
|
+
* invocation. `--repo` on the command line still overrides.
|
|
42
|
+
*/
|
|
43
|
+
repo?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Repo-level policy applied by `holocron setup`. Defines merge
|
|
46
|
+
* strategy, branch protection rulesets, and security defaults.
|
|
47
|
+
* Requires `source` capability to be configured.
|
|
48
|
+
*/
|
|
49
|
+
repoPolicy?: RepoPolicyConfig;
|
|
50
|
+
/**
|
|
51
|
+
* CI workflow names to install as thin wrappers during `holocron setup`.
|
|
52
|
+
* Each name maps to a reusable workflow in `theholocron/.github`.
|
|
53
|
+
*
|
|
54
|
+
* Supported values: "lint" | "test" | "typecheck" | "codeql" | "review" |
|
|
55
|
+
* "release" | "stale" | "greetings" | "dependencies" | "bookkeeping-pr" | "audit"
|
|
56
|
+
*
|
|
57
|
+
* `holocron setup` writes `.github/workflows/<name>.yml` for each entry,
|
|
58
|
+
* calling the corresponding `ci-<name>.yml@main` reusable workflow.
|
|
59
|
+
* Files are overwritten on each run — they are generated artifacts.
|
|
60
|
+
*/
|
|
61
|
+
workflows?: string[];
|
|
21
62
|
};
|
|
22
63
|
providers: RawProvidersConfig;
|
|
23
64
|
apps?: AppConfig[];
|
|
@@ -30,15 +71,15 @@ interface ResolvedTuple {
|
|
|
30
71
|
options: ProviderOptions;
|
|
31
72
|
}
|
|
32
73
|
type ResolvedProviderEntry = {
|
|
33
|
-
cardinality:
|
|
74
|
+
cardinality: "single";
|
|
34
75
|
tuple: ResolvedTuple;
|
|
35
76
|
} | {
|
|
36
|
-
cardinality:
|
|
77
|
+
cardinality: "many";
|
|
37
78
|
tuples: ResolvedTuple[];
|
|
38
79
|
};
|
|
39
80
|
type ResolvedProvidersConfig = Partial<Record<CapabilityKey, ResolvedProviderEntry>>;
|
|
40
81
|
interface ResolvedHolocronConfig {
|
|
41
|
-
project: HolocronConfig[
|
|
82
|
+
project: HolocronConfig["project"];
|
|
42
83
|
providers: ResolvedProvidersConfig;
|
|
43
84
|
apps: AppConfig[];
|
|
44
85
|
doctor: DoctorConfig;
|
|
@@ -55,4 +96,48 @@ declare function resolvePluginPackage(provider: string): string;
|
|
|
55
96
|
declare function resolveEntry(key: CapabilityKey, raw: RawProviderEntry): ResolvedProviderEntry;
|
|
56
97
|
declare function resolveConfig(raw: HolocronConfig): ResolvedHolocronConfig;
|
|
57
98
|
//#endregion
|
|
58
|
-
|
|
99
|
+
//#region src/keyring.d.ts
|
|
100
|
+
/**
|
|
101
|
+
* Keyring-backed bootstrap credential store.
|
|
102
|
+
*
|
|
103
|
+
* Every holocron plugin's bootstrap token (the one it needs before it
|
|
104
|
+
* can talk to its vendor's API) can be stored in the OS keyring under
|
|
105
|
+
* a single reverse-DNS service scope. Managed via `holocron auth`
|
|
106
|
+
* subcommands; consulted at position 4 in every plugin's auth
|
|
107
|
+
* precedence chain (after --token / HOLOCRON_<X>_TOKEN / <native>_TOKEN).
|
|
108
|
+
*
|
|
109
|
+
* See `.notes/tech-auth-bootstrap.spec.md` for the design rationale.
|
|
110
|
+
*
|
|
111
|
+
* Failure model: keyring access is best-effort. Platforms without a
|
|
112
|
+
* supported credential store (some Linux CI images, sandboxed
|
|
113
|
+
* environments) will throw from the underlying library. Every export
|
|
114
|
+
* here catches and returns a null/empty result rather than propagating
|
|
115
|
+
* — the plugin's precedence chain then falls through to
|
|
116
|
+
* env-var-only paths, which is exactly how CI is meant to work.
|
|
117
|
+
*/
|
|
118
|
+
/**
|
|
119
|
+
* Store or overwrite a bootstrap token for a provider. Returns true on
|
|
120
|
+
* success, false when the underlying keyring is unsupported or errored.
|
|
121
|
+
*/
|
|
122
|
+
declare function setToken(provider: string, token: string): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Read the bootstrap token for a provider. Returns `null` for both
|
|
125
|
+
* "not stored" and "keyring unavailable" — callers can treat them the
|
|
126
|
+
* same way (fall through to env-var precedence).
|
|
127
|
+
*/
|
|
128
|
+
declare function getToken(provider: string): string | null;
|
|
129
|
+
/**
|
|
130
|
+
* Delete a stored token. Returns true when a token was removed, false
|
|
131
|
+
* when there was nothing to delete or the keyring is unavailable.
|
|
132
|
+
* Distinguishing the two cases isn't worth the surface area — the
|
|
133
|
+
* command output makes the situation clear either way.
|
|
134
|
+
*/
|
|
135
|
+
declare function deleteToken(provider: string): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* List provider slugs with a stored token in this service scope.
|
|
138
|
+
* Uses the library's `findCredentials(service)` — supported on all
|
|
139
|
+
* platforms the underlying credential store supports.
|
|
140
|
+
*/
|
|
141
|
+
declare function listStoredProviders(): string[];
|
|
142
|
+
//#endregion
|
|
143
|
+
export { Analytics, AppConfig, Auth, AuthDescription, AuthEvent, AuthEventType, AuthIdentity, AuthUser, CARDINALITY, CapabilityImpls, CapabilityKey, Cardinality, CardinalityFor, Ci, CiRun, CiRunFilter, CiRunStatus, ConfigError, ConnectionStringOptions, CreateAuthUserInput, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, Dns, DnsRecord, DnsRecordType, DoctorConfig, EnsureResult, Environment, EnvironmentReviewer, Environments, HolocronConfig, Issue, IssueSearchFilter, Issues, LifecycleResult, LifecycleSlot, MultiEntry, NormalizedAuthUser, Notifications, Observability, ParseWebhookInput, ProviderApiError, ProviderIdentity, ProviderOptions, REQUIRED_CAPABILITIES, RawProviderEntry, RawProvidersConfig, RepoPolicyConfig, RepoRef, RepoSettings, ResolvedCapability, ResolvedHolocronConfig, ResolvedProviderEntry, ResolvedProvidersConfig, ResolvedTuple, Ruleset, SecretScope, Secrets, SingleEntry, Source, StatusCategory, Storage, StorageBranch, Tooling, ToolingDoctorReport, TrackerDoctorReport, TrackerUser, Vault, WebhookDashboardInfo, WebhookVerificationError, deleteToken, getToken, isMulti, listStoredProviders, resolveConfig, resolveEntry, resolvePluginPackage, setToken };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as isMulti, i as WebhookVerificationError, n as ProviderApiError, r as REQUIRED_CAPABILITIES, t as CARDINALITY } from "./capabilities-
|
|
2
|
-
import {
|
|
3
|
-
export { CARDINALITY, ConfigError, ProviderApiError, REQUIRED_CAPABILITIES, WebhookVerificationError, isMulti, resolveConfig, resolveEntry, resolvePluginPackage };
|
|
1
|
+
import { a as isMulti, i as WebhookVerificationError, n as ProviderApiError, r as REQUIRED_CAPABILITIES, t as CARDINALITY } from "./capabilities-DapaKOlX.mjs";
|
|
2
|
+
import { a as ConfigError, c as resolvePluginPackage, i as setToken, n as getToken, o as resolveConfig, r as listStoredProviders, s as resolveEntry, t as deleteToken } from "./keyring-DwNEmrBc.mjs";
|
|
3
|
+
export { CARDINALITY, ConfigError, ProviderApiError, REQUIRED_CAPABILITIES, WebhookVerificationError, deleteToken, getToken, isMulti, listStoredProviders, resolveConfig, resolveEntry, resolvePluginPackage, setToken };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { r as REQUIRED_CAPABILITIES, t as CARDINALITY } from "./capabilities-
|
|
1
|
+
import { r as REQUIRED_CAPABILITIES, t as CARDINALITY } from "./capabilities-DapaKOlX.mjs";
|
|
2
|
+
import { Entry, findCredentials } from "@napi-rs/keyring";
|
|
2
3
|
//#region src/config.ts
|
|
3
4
|
/**
|
|
4
5
|
* `holocron.config.json` schema, parser, and provider resolution.
|
|
@@ -110,4 +111,74 @@ function resolveConfig(raw) {
|
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
113
|
//#endregion
|
|
113
|
-
|
|
114
|
+
//#region src/keyring.ts
|
|
115
|
+
/**
|
|
116
|
+
* Keyring-backed bootstrap credential store.
|
|
117
|
+
*
|
|
118
|
+
* Every holocron plugin's bootstrap token (the one it needs before it
|
|
119
|
+
* can talk to its vendor's API) can be stored in the OS keyring under
|
|
120
|
+
* a single reverse-DNS service scope. Managed via `holocron auth`
|
|
121
|
+
* subcommands; consulted at position 4 in every plugin's auth
|
|
122
|
+
* precedence chain (after --token / HOLOCRON_<X>_TOKEN / <native>_TOKEN).
|
|
123
|
+
*
|
|
124
|
+
* See `.notes/tech-auth-bootstrap.spec.md` for the design rationale.
|
|
125
|
+
*
|
|
126
|
+
* Failure model: keyring access is best-effort. Platforms without a
|
|
127
|
+
* supported credential store (some Linux CI images, sandboxed
|
|
128
|
+
* environments) will throw from the underlying library. Every export
|
|
129
|
+
* here catches and returns a null/empty result rather than propagating
|
|
130
|
+
* — the plugin's precedence chain then falls through to
|
|
131
|
+
* env-var-only paths, which is exactly how CI is meant to work.
|
|
132
|
+
*/
|
|
133
|
+
const SERVICE = "com.theholocron.cli";
|
|
134
|
+
/**
|
|
135
|
+
* Store or overwrite a bootstrap token for a provider. Returns true on
|
|
136
|
+
* success, false when the underlying keyring is unsupported or errored.
|
|
137
|
+
*/
|
|
138
|
+
function setToken(provider, token) {
|
|
139
|
+
try {
|
|
140
|
+
new Entry(SERVICE, provider).setPassword(token);
|
|
141
|
+
return true;
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Read the bootstrap token for a provider. Returns `null` for both
|
|
148
|
+
* "not stored" and "keyring unavailable" — callers can treat them the
|
|
149
|
+
* same way (fall through to env-var precedence).
|
|
150
|
+
*/
|
|
151
|
+
function getToken(provider) {
|
|
152
|
+
try {
|
|
153
|
+
return new Entry(SERVICE, provider).getPassword();
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Delete a stored token. Returns true when a token was removed, false
|
|
160
|
+
* when there was nothing to delete or the keyring is unavailable.
|
|
161
|
+
* Distinguishing the two cases isn't worth the surface area — the
|
|
162
|
+
* command output makes the situation clear either way.
|
|
163
|
+
*/
|
|
164
|
+
function deleteToken(provider) {
|
|
165
|
+
try {
|
|
166
|
+
return new Entry(SERVICE, provider).deletePassword();
|
|
167
|
+
} catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* List provider slugs with a stored token in this service scope.
|
|
173
|
+
* Uses the library's `findCredentials(service)` — supported on all
|
|
174
|
+
* platforms the underlying credential store supports.
|
|
175
|
+
*/
|
|
176
|
+
function listStoredProviders() {
|
|
177
|
+
try {
|
|
178
|
+
return findCredentials(SERVICE).map((c) => c.account);
|
|
179
|
+
} catch {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { ConfigError as a, resolvePluginPackage as c, setToken as i, getToken as n, resolveConfig as o, listStoredProviders as r, resolveEntry as s, deleteToken as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/cli",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.5",
|
|
4
4
|
"description": "The Holocron CLI — a pluggable, capability-based orchestrator for spinning up and operating software projects.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/cli#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"README.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@napi-rs/keyring": "^1.3.0",
|
|
36
37
|
"yargs": "^18.0.0",
|
|
37
38
|
"@theholocron/cli-utils": "0.0.0"
|
|
38
39
|
},
|