envpkt 0.13.2 → 0.13.4
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 +33 -0
- package/dist/cli.js +928 -685
- package/dist/index.d.ts +44 -1
- package/dist/index.js +115 -1
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -583,6 +583,49 @@ declare const quoteDotenvValue: (value: string) => string;
|
|
|
583
583
|
/** Serialize entries to dotenv text (no trailing newline). */
|
|
584
584
|
declare const formatDotenv: (entries: ReadonlyArray<DotenvEntry>, options?: FormatDotenvOptions) => string;
|
|
585
585
|
//#endregion
|
|
586
|
+
//#region src/core/diff.d.ts
|
|
587
|
+
/** A single field that differs between two entries. `undefined` means the field is absent on that side. */
|
|
588
|
+
type FieldChange = {
|
|
589
|
+
readonly field: string;
|
|
590
|
+
readonly a: string | undefined;
|
|
591
|
+
readonly b: string | undefined;
|
|
592
|
+
};
|
|
593
|
+
/** An entry present in both configs whose metadata differs. */
|
|
594
|
+
type ChangedEntry = {
|
|
595
|
+
readonly key: string;
|
|
596
|
+
readonly changes: ReadonlyArray<FieldChange>;
|
|
597
|
+
};
|
|
598
|
+
/** Diff of one keyed section (`[secret.*]` or `[env.*]`). Key lists are sorted. */
|
|
599
|
+
type SectionDiff = {
|
|
600
|
+
readonly onlyA: ReadonlyArray<string>;
|
|
601
|
+
readonly onlyB: ReadonlyArray<string>;
|
|
602
|
+
readonly changed: ReadonlyArray<ChangedEntry>;
|
|
603
|
+
};
|
|
604
|
+
type ConfigDiff = {
|
|
605
|
+
readonly secret: SectionDiff;
|
|
606
|
+
readonly env: SectionDiff;
|
|
607
|
+
readonly identical: boolean;
|
|
608
|
+
};
|
|
609
|
+
/** Compare two configs by their `[secret.*]` and `[env.*]` entries (metadata, not ciphertext). */
|
|
610
|
+
declare const diffConfigs: (a: EnvpktConfig, b: EnvpktConfig) => ConfigDiff;
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region src/core/copy.d.ts
|
|
613
|
+
/**
|
|
614
|
+
* The SecretMeta to write into the destination on copy.
|
|
615
|
+
* - `created` is reset to today: the entry is new *here*, regardless of the source's age.
|
|
616
|
+
* - `last_rotated_at` is dropped — it's the source's rotation history, not the copy's.
|
|
617
|
+
* - `encryptedValue` re-derives the ciphertext: `Some(cipher)` sets the resealed value,
|
|
618
|
+
* `None` strips it entirely (a metadata-only copy of a secret with no sealed value).
|
|
619
|
+
*/
|
|
620
|
+
declare const copyableSecretMeta: (meta: SecretMeta, opts: {
|
|
621
|
+
readonly today: string;
|
|
622
|
+
readonly encryptedValue: Option<string>;
|
|
623
|
+
}) => SecretMeta;
|
|
624
|
+
/** Serialize a `[secret.<name>]` block from its metadata, round-trippable by the TOML parser. */
|
|
625
|
+
declare const serializeSecretBlock: (name: string, meta: SecretMeta) => string;
|
|
626
|
+
/** Serialize an `[env.<name>]` block from its metadata. */
|
|
627
|
+
declare const serializeEnvBlock: (name: string, meta: EnvMeta) => string;
|
|
628
|
+
//#endregion
|
|
586
629
|
//#region src/core/toml-edit.d.ts
|
|
587
630
|
/**
|
|
588
631
|
* Remove a TOML section (e.g. `[secret.X]`) and all its fields through the next section or EOF.
|
|
@@ -668,4 +711,4 @@ type ToolDef = {
|
|
|
668
711
|
declare const toolDefinitions: readonly ToolDef[];
|
|
669
712
|
declare const callTool: (name: string, args: Record<string, unknown>) => CallToolResult;
|
|
670
713
|
//#endregion
|
|
671
|
-
export { type AgentIdentity, AgentIdentitySchema, type AliasError, type AliasTable, type AuditResult, type BootError, type BootOptions, type BootResult, type CallbackConfig, CallbackConfigSchema, type CatalogError, type CheckResult, type ConfidenceLevel, type ConfigError, type ConfigSource, ConsumerType, type CredentialPattern, type DirectLogger, type DirectTestLoggerHandle, type DotenvEntry, type DriftEntry, type DriftStatus, type EnvAuditResult, type EnvDriftEntry, type EnvDriftStatus, type EnvMeta, EnvMetaSchema, EnvpktBootError, type EnvpktConfig, EnvpktConfigSchema, type FleetAgent, type FleetHealth, type FnoxConfig, type FnoxError, type FnoxSecret, type FormatDotenvOptions, type FormatPacketOptions, type HealthStatus, type Identity, type IdentityError, IdentitySchema, type KeygenError, type KeygenResult, type LifecycleConfig, LifecycleConfigSchema, type LogEntry, type LogLevel, type LogMetadata, type MatchResult, type ResolveOptions, type ResolveResult, type ResolvedPath, type ScanOptions, type ScanResult, type SealError, type SecretDisplay, type SecretHealth, type SecretMeta, SecretMetaSchema, type SecretStatus, type TomlEditError, type ToolsConfig, ToolsConfigSchema, ageAvailable, ageDecrypt, ageEncrypt, appendSection, boot, bootSafe, callTool, compareFnoxAndEnvpkt, computeAudit, computeEnvAudit, createDirectConsoleLogger, createDirectTestLogger, createServer, deriveServiceFromName, detectFnox, directSilentLogger, discoverConfig, envCheck, envScan, extractFnoxKeys, findConfigPath, fnoxAvailable, fnoxExport, fnoxGet, formatAliasError, formatDotenv, formatPacket, generateKeypair, generateTomlFromScan, isEnvAlias, isSecretAlias, loadCatalog, loadConfig, loadConfigFromCwd, maskValue, matchEnvVar, matchValueShape, parseToml, quoteDotenvValue, readConfigFile, readFnoxConfig, readResource, removeSection, renameSection, resolveConfig, resolveConfigPath, resolveInlineKey, resolveKeyPath, resolveSecrets, resolveValues, resourceDefinitions, scanEnv, scanFleet, sealSecrets, startServer, toolDefinitions, unsealSecrets, unwrapAgentKey, updateConfigIdentity, updateSectionFields, validateAliases, validateConfig };
|
|
714
|
+
export { type AgentIdentity, AgentIdentitySchema, type AliasError, type AliasTable, type AuditResult, type BootError, type BootOptions, type BootResult, type CallbackConfig, CallbackConfigSchema, type CatalogError, type ChangedEntry, type CheckResult, type ConfidenceLevel, type ConfigDiff, type ConfigError, type ConfigSource, ConsumerType, type CredentialPattern, type DirectLogger, type DirectTestLoggerHandle, type DotenvEntry, type DriftEntry, type DriftStatus, type EnvAuditResult, type EnvDriftEntry, type EnvDriftStatus, type EnvMeta, EnvMetaSchema, EnvpktBootError, type EnvpktConfig, EnvpktConfigSchema, type FieldChange, type FleetAgent, type FleetHealth, type FnoxConfig, type FnoxError, type FnoxSecret, type FormatDotenvOptions, type FormatPacketOptions, type HealthStatus, type Identity, type IdentityError, IdentitySchema, type KeygenError, type KeygenResult, type LifecycleConfig, LifecycleConfigSchema, type LogEntry, type LogLevel, type LogMetadata, type MatchResult, type ResolveOptions, type ResolveResult, type ResolvedPath, type ScanOptions, type ScanResult, type SealError, type SecretDisplay, type SecretHealth, type SecretMeta, SecretMetaSchema, type SecretStatus, type SectionDiff, type TomlEditError, type ToolsConfig, ToolsConfigSchema, ageAvailable, ageDecrypt, ageEncrypt, appendSection, boot, bootSafe, callTool, compareFnoxAndEnvpkt, computeAudit, computeEnvAudit, copyableSecretMeta, createDirectConsoleLogger, createDirectTestLogger, createServer, deriveServiceFromName, detectFnox, diffConfigs, directSilentLogger, discoverConfig, envCheck, envScan, extractFnoxKeys, findConfigPath, fnoxAvailable, fnoxExport, fnoxGet, formatAliasError, formatDotenv, formatPacket, generateKeypair, generateTomlFromScan, isEnvAlias, isSecretAlias, loadCatalog, loadConfig, loadConfigFromCwd, maskValue, matchEnvVar, matchValueShape, parseToml, quoteDotenvValue, readConfigFile, readFnoxConfig, readResource, removeSection, renameSection, resolveConfig, resolveConfigPath, resolveInlineKey, resolveKeyPath, resolveSecrets, resolveValues, resourceDefinitions, scanEnv, scanFleet, sealSecrets, serializeEnvBlock, serializeSecretBlock, startServer, toolDefinitions, unsealSecrets, unwrapAgentKey, updateConfigIdentity, updateSectionFields, validateAliases, validateConfig };
|
package/dist/index.js
CHANGED
|
@@ -2306,6 +2306,120 @@ const formatDotenv = (entries, options) => {
|
|
|
2306
2306
|
return header ? `${header}\n\n${body}` : body;
|
|
2307
2307
|
};
|
|
2308
2308
|
//#endregion
|
|
2309
|
+
//#region src/core/diff.ts
|
|
2310
|
+
/** Normalize a metadata value to a comparable/displayable string (`undefined` = absent). */
|
|
2311
|
+
const serialize = (value) => value === void 0 ? void 0 : typeof value === "string" ? value : JSON.stringify(value);
|
|
2312
|
+
/**
|
|
2313
|
+
* Field-level diff of two entries. `encrypted_value` is excluded from value comparison — the same
|
|
2314
|
+
* secret re-encrypts to different ciphertext, so diffing it is noise — but a change in *sealed
|
|
2315
|
+
* status* (present ↔ absent) is reported as a synthetic `sealed` field.
|
|
2316
|
+
*/
|
|
2317
|
+
const metaDiff = (a, b) => {
|
|
2318
|
+
const ar = a;
|
|
2319
|
+
const br = b;
|
|
2320
|
+
const sealedChange = !!ar["encrypted_value"] === !!br["encrypted_value"] ? [] : [{
|
|
2321
|
+
field: "sealed",
|
|
2322
|
+
a: ar["encrypted_value"] ? "yes" : "no",
|
|
2323
|
+
b: br["encrypted_value"] ? "yes" : "no"
|
|
2324
|
+
}];
|
|
2325
|
+
const fieldChanges = [...Object.keys(ar), ...Object.keys(br)].filter((k, i, arr) => k !== "encrypted_value" && arr.indexOf(k) === i).flatMap((field) => {
|
|
2326
|
+
const av = serialize(ar[field]);
|
|
2327
|
+
const bv = serialize(br[field]);
|
|
2328
|
+
return av === bv ? [] : [{
|
|
2329
|
+
field,
|
|
2330
|
+
a: av,
|
|
2331
|
+
b: bv
|
|
2332
|
+
}];
|
|
2333
|
+
});
|
|
2334
|
+
return [...sealedChange, ...fieldChanges.sort((x, y) => x.field.localeCompare(y.field))];
|
|
2335
|
+
};
|
|
2336
|
+
const sectionDiff = (a, b) => {
|
|
2337
|
+
const aKeys = Object.keys(a);
|
|
2338
|
+
const bKeys = Object.keys(b);
|
|
2339
|
+
return {
|
|
2340
|
+
onlyA: aKeys.filter((k) => !(k in b)).sort(),
|
|
2341
|
+
onlyB: bKeys.filter((k) => !(k in a)).sort(),
|
|
2342
|
+
changed: aKeys.filter((k) => k in b).sort().flatMap((key) => {
|
|
2343
|
+
const changes = metaDiff(a[key], b[key]);
|
|
2344
|
+
return changes.length === 0 ? [] : [{
|
|
2345
|
+
key,
|
|
2346
|
+
changes
|
|
2347
|
+
}];
|
|
2348
|
+
})
|
|
2349
|
+
};
|
|
2350
|
+
};
|
|
2351
|
+
const isEmpty = (s) => s.onlyA.length === 0 && s.onlyB.length === 0 && s.changed.length === 0;
|
|
2352
|
+
/** Compare two configs by their `[secret.*]` and `[env.*]` entries (metadata, not ciphertext). */
|
|
2353
|
+
const diffConfigs = (a, b) => {
|
|
2354
|
+
const secret = sectionDiff(a.secret ?? {}, b.secret ?? {});
|
|
2355
|
+
const env = sectionDiff(a.env ?? {}, b.env ?? {});
|
|
2356
|
+
return {
|
|
2357
|
+
secret,
|
|
2358
|
+
env,
|
|
2359
|
+
identical: isEmpty(secret) && isEmpty(env)
|
|
2360
|
+
};
|
|
2361
|
+
};
|
|
2362
|
+
//#endregion
|
|
2363
|
+
//#region src/core/copy.ts
|
|
2364
|
+
/** Escape a string for a TOML basic (double-quoted) string. */
|
|
2365
|
+
const tomlString = (s) => `"${s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n")}"`;
|
|
2366
|
+
const tomlStringArray = (arr) => `[${arr.map(tomlString).join(", ")}]`;
|
|
2367
|
+
const tomlInlineTable = (rec) => {
|
|
2368
|
+
const entries = Object.entries(rec);
|
|
2369
|
+
return entries.length === 0 ? "{}" : `{ ${entries.map(([k, v]) => `${k} = ${tomlString(v)}`).join(", ")} }`;
|
|
2370
|
+
};
|
|
2371
|
+
/**
|
|
2372
|
+
* The SecretMeta to write into the destination on copy.
|
|
2373
|
+
* - `created` is reset to today: the entry is new *here*, regardless of the source's age.
|
|
2374
|
+
* - `last_rotated_at` is dropped — it's the source's rotation history, not the copy's.
|
|
2375
|
+
* - `encryptedValue` re-derives the ciphertext: `Some(cipher)` sets the resealed value,
|
|
2376
|
+
* `None` strips it entirely (a metadata-only copy of a secret with no sealed value).
|
|
2377
|
+
*/
|
|
2378
|
+
const copyableSecretMeta = (meta, opts) => {
|
|
2379
|
+
const { last_rotated_at: _lra, encrypted_value: _ev, ...rest } = meta;
|
|
2380
|
+
return opts.encryptedValue.fold(() => ({
|
|
2381
|
+
...rest,
|
|
2382
|
+
created: opts.today
|
|
2383
|
+
}), (cipher) => ({
|
|
2384
|
+
...rest,
|
|
2385
|
+
created: opts.today,
|
|
2386
|
+
encrypted_value: cipher
|
|
2387
|
+
}));
|
|
2388
|
+
};
|
|
2389
|
+
/** Serialize a `[secret.<name>]` block from its metadata, round-trippable by the TOML parser. */
|
|
2390
|
+
const serializeSecretBlock = (name, meta) => {
|
|
2391
|
+
const lines = [`[secret.${name}]`];
|
|
2392
|
+
if (meta.service !== void 0) lines.push(`service = ${tomlString(meta.service)}`);
|
|
2393
|
+
if (meta.purpose !== void 0) lines.push(`purpose = ${tomlString(meta.purpose)}`);
|
|
2394
|
+
if (meta.comment !== void 0) lines.push(`comment = ${tomlString(meta.comment)}`);
|
|
2395
|
+
if (meta.created !== void 0) lines.push(`created = ${tomlString(meta.created)}`);
|
|
2396
|
+
if (meta.expires !== void 0) lines.push(`expires = ${tomlString(meta.expires)}`);
|
|
2397
|
+
if (meta.rotates !== void 0) lines.push(`rotates = ${tomlString(meta.rotates)}`);
|
|
2398
|
+
if (meta.rate_limit !== void 0) lines.push(`rate_limit = ${tomlString(meta.rate_limit)}`);
|
|
2399
|
+
if (meta.model_hint !== void 0) lines.push(`model_hint = ${tomlString(meta.model_hint)}`);
|
|
2400
|
+
if (meta.source !== void 0) lines.push(`source = ${tomlString(meta.source)}`);
|
|
2401
|
+
if (meta.rotation_url !== void 0) lines.push(`rotation_url = ${tomlString(meta.rotation_url)}`);
|
|
2402
|
+
if (meta.last_rotated_at !== void 0) lines.push(`last_rotated_at = ${tomlString(meta.last_rotated_at)}`);
|
|
2403
|
+
if (meta.required !== void 0) lines.push(`required = ${meta.required ? "true" : "false"}`);
|
|
2404
|
+
if (meta.capabilities !== void 0) lines.push(`capabilities = ${tomlStringArray(meta.capabilities)}`);
|
|
2405
|
+
if (meta.tags !== void 0) lines.push(`tags = ${tomlInlineTable(meta.tags)}`);
|
|
2406
|
+
if (meta.namespace !== void 0) lines.push(`namespace = ${tomlString(meta.namespace)}`);
|
|
2407
|
+
if (meta.from_key !== void 0) lines.push(`from_key = ${tomlString(meta.from_key)}`);
|
|
2408
|
+
if (meta.encrypted_value !== void 0 && meta.encrypted_value !== "") lines.push(`encrypted_value = """`, meta.encrypted_value, `"""`);
|
|
2409
|
+
return `${lines.join("\n")}\n`;
|
|
2410
|
+
};
|
|
2411
|
+
/** Serialize an `[env.<name>]` block from its metadata. */
|
|
2412
|
+
const serializeEnvBlock = (name, meta) => {
|
|
2413
|
+
const lines = [`[env.${name}]`];
|
|
2414
|
+
if (meta.value !== void 0) lines.push(`value = ${tomlString(meta.value)}`);
|
|
2415
|
+
if (meta.from_key !== void 0) lines.push(`from_key = ${tomlString(meta.from_key)}`);
|
|
2416
|
+
if (meta.purpose !== void 0) lines.push(`purpose = ${tomlString(meta.purpose)}`);
|
|
2417
|
+
if (meta.comment !== void 0) lines.push(`comment = ${tomlString(meta.comment)}`);
|
|
2418
|
+
if (meta.tags !== void 0) lines.push(`tags = ${tomlInlineTable(meta.tags)}`);
|
|
2419
|
+
if (meta.namespace !== void 0) lines.push(`namespace = ${tomlString(meta.namespace)}`);
|
|
2420
|
+
return `${lines.join("\n")}\n`;
|
|
2421
|
+
};
|
|
2422
|
+
//#endregion
|
|
2309
2423
|
//#region src/core/toml-edit.ts
|
|
2310
2424
|
const SECTION_RE = /^\[.+\]\s*$/;
|
|
2311
2425
|
const MULTILINE_OPEN = "\"\"\"";
|
|
@@ -2804,4 +2918,4 @@ const startServer = async () => {
|
|
|
2804
2918
|
await server.connect(transport);
|
|
2805
2919
|
};
|
|
2806
2920
|
//#endregion
|
|
2807
|
-
export { AgentIdentitySchema, CallbackConfigSchema, ConsumerType, EnvMetaSchema, EnvpktBootError, EnvpktConfigSchema, IdentitySchema, LifecycleConfigSchema, SecretMetaSchema, ToolsConfigSchema, ageAvailable, ageDecrypt, ageEncrypt, appendSection, boot, bootSafe, callTool, compareFnoxAndEnvpkt, computeAudit, computeEnvAudit, createDirectConsoleLogger, createDirectTestLogger, createServer, deriveServiceFromName, detectFnox, directSilentLogger, discoverConfig, envCheck, envScan, extractFnoxKeys, findConfigPath, fnoxAvailable, fnoxExport, fnoxGet, formatAliasError, formatDotenv, formatPacket, generateKeypair, generateTomlFromScan, isEnvAlias, isSecretAlias, loadCatalog, loadConfig, loadConfigFromCwd, maskValue, matchEnvVar, matchValueShape, parseToml, quoteDotenvValue, readConfigFile, readFnoxConfig, readResource, removeSection, renameSection, resolveConfig, resolveConfigPath, resolveInlineKey, resolveKeyPath, resolveSecrets, resolveValues, resourceDefinitions, scanEnv, scanFleet, sealSecrets, startServer, toolDefinitions, unsealSecrets, unwrapAgentKey, updateConfigIdentity, updateSectionFields, validateAliases, validateConfig };
|
|
2921
|
+
export { AgentIdentitySchema, CallbackConfigSchema, ConsumerType, EnvMetaSchema, EnvpktBootError, EnvpktConfigSchema, IdentitySchema, LifecycleConfigSchema, SecretMetaSchema, ToolsConfigSchema, ageAvailable, ageDecrypt, ageEncrypt, appendSection, boot, bootSafe, callTool, compareFnoxAndEnvpkt, computeAudit, computeEnvAudit, copyableSecretMeta, createDirectConsoleLogger, createDirectTestLogger, createServer, deriveServiceFromName, detectFnox, diffConfigs, directSilentLogger, discoverConfig, envCheck, envScan, extractFnoxKeys, findConfigPath, fnoxAvailable, fnoxExport, fnoxGet, formatAliasError, formatDotenv, formatPacket, generateKeypair, generateTomlFromScan, isEnvAlias, isSecretAlias, loadCatalog, loadConfig, loadConfigFromCwd, maskValue, matchEnvVar, matchValueShape, parseToml, quoteDotenvValue, readConfigFile, readFnoxConfig, readResource, removeSection, renameSection, resolveConfig, resolveConfigPath, resolveInlineKey, resolveKeyPath, resolveSecrets, resolveValues, resourceDefinitions, scanEnv, scanFleet, sealSecrets, serializeEnvBlock, serializeSecretBlock, startServer, toolDefinitions, unsealSecrets, unwrapAgentKey, updateConfigIdentity, updateSectionFields, validateAliases, validateConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envpkt",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.4",
|
|
4
4
|
"description": "Credential lifecycle and fleet management for AI agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"credentials",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
43
43
|
"@sinclair/typebox": "^0.34.49",
|
|
44
44
|
"commander": "^15.0.0",
|
|
45
|
-
"functype": "^1.3
|
|
46
|
-
"functype-log": "^1.3
|
|
47
|
-
"functype-os": "^1.3
|
|
45
|
+
"functype": "^1.4.3",
|
|
46
|
+
"functype-log": "^1.4.3",
|
|
47
|
+
"functype-os": "^1.4.3",
|
|
48
48
|
"smol-toml": "^1.6.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@types/node": "^24.13.
|
|
52
|
-
"ts-builds": "^3.0
|
|
51
|
+
"@types/node": "^24.13.2",
|
|
52
|
+
"ts-builds": "^3.2.0",
|
|
53
53
|
"tsdown": "^0.22.2",
|
|
54
54
|
"tsx": "^4.22.4"
|
|
55
55
|
},
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"schemas"
|
|
72
72
|
],
|
|
73
73
|
"prettier": "ts-builds/prettier",
|
|
74
|
-
"packageManager": "pnpm@11.
|
|
74
|
+
"packageManager": "pnpm@11.7.0+sha512.19cc852c120c7125760f2443ee6be0ca5b40f9f50598de1a09a1f177503e010e57c23c77646e01e761de59bf874fb22a3398c33ab9691fc13eb946b6f0f4d620"
|
|
75
75
|
}
|