@aigne/afs-cli 1.11.0-beta.11 → 1.11.0-beta.12

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 (154) hide show
  1. package/dist/cli.cjs +3 -2
  2. package/dist/cli.mjs +3 -2
  3. package/dist/cli.mjs.map +1 -1
  4. package/dist/config/afs-loader.cjs +64 -315
  5. package/dist/config/afs-loader.d.cts.map +1 -1
  6. package/dist/config/afs-loader.d.mts +2 -1
  7. package/dist/config/afs-loader.d.mts.map +1 -1
  8. package/dist/config/afs-loader.mjs +59 -310
  9. package/dist/config/afs-loader.mjs.map +1 -1
  10. package/dist/config/credential-helpers.cjs +291 -0
  11. package/dist/config/credential-helpers.d.mts +2 -0
  12. package/dist/config/credential-helpers.mjs +288 -0
  13. package/dist/config/credential-helpers.mjs.map +1 -0
  14. package/dist/config/loader.cjs +3 -1
  15. package/dist/config/loader.mjs +3 -2
  16. package/dist/config/loader.mjs.map +1 -1
  17. package/dist/config/program-install.cjs +276 -0
  18. package/dist/config/program-install.d.mts +1 -0
  19. package/dist/config/program-install.mjs +273 -0
  20. package/dist/config/program-install.mjs.map +1 -0
  21. package/dist/core/commands/connect.cjs +53 -0
  22. package/dist/core/commands/connect.d.mts +2 -0
  23. package/dist/core/commands/connect.mjs +55 -0
  24. package/dist/core/commands/connect.mjs.map +1 -0
  25. package/dist/core/commands/daemon.cjs +207 -0
  26. package/dist/core/commands/daemon.d.mts +2 -0
  27. package/dist/core/commands/daemon.mjs +208 -0
  28. package/dist/core/commands/daemon.mjs.map +1 -0
  29. package/dist/core/commands/explain.cjs +3 -1
  30. package/dist/core/commands/explain.mjs +3 -1
  31. package/dist/core/commands/explain.mjs.map +1 -1
  32. package/dist/core/commands/explore.cjs +47 -12
  33. package/dist/core/commands/explore.mjs +47 -12
  34. package/dist/core/commands/explore.mjs.map +1 -1
  35. package/dist/core/commands/gen-agent-md.cjs +126 -0
  36. package/dist/core/commands/gen-agent-md.d.mts +2 -0
  37. package/dist/core/commands/gen-agent-md.mjs +125 -0
  38. package/dist/core/commands/gen-agent-md.mjs.map +1 -0
  39. package/dist/core/commands/index.cjs +13 -1
  40. package/dist/core/commands/index.d.cts.map +1 -1
  41. package/dist/core/commands/index.d.mts +6 -0
  42. package/dist/core/commands/index.d.mts.map +1 -1
  43. package/dist/core/commands/index.mjs +13 -1
  44. package/dist/core/commands/index.mjs.map +1 -1
  45. package/dist/core/commands/install.cjs +91 -0
  46. package/dist/core/commands/install.d.mts +2 -0
  47. package/dist/core/commands/install.mjs +92 -0
  48. package/dist/core/commands/install.mjs.map +1 -0
  49. package/dist/core/commands/ls.cjs +14 -2
  50. package/dist/core/commands/ls.d.cts +2 -0
  51. package/dist/core/commands/ls.d.cts.map +1 -1
  52. package/dist/core/commands/ls.d.mts +2 -0
  53. package/dist/core/commands/ls.d.mts.map +1 -1
  54. package/dist/core/commands/ls.mjs +14 -2
  55. package/dist/core/commands/ls.mjs.map +1 -1
  56. package/dist/core/commands/mcp-bridge.cjs +201 -0
  57. package/dist/core/commands/mcp-bridge.d.mts +2 -0
  58. package/dist/core/commands/mcp-bridge.mjs +201 -0
  59. package/dist/core/commands/mcp-bridge.mjs.map +1 -0
  60. package/dist/core/commands/read.cjs +20 -7
  61. package/dist/core/commands/read.d.cts +2 -0
  62. package/dist/core/commands/read.d.cts.map +1 -1
  63. package/dist/core/commands/read.d.mts +2 -0
  64. package/dist/core/commands/read.d.mts.map +1 -1
  65. package/dist/core/commands/read.mjs +20 -7
  66. package/dist/core/commands/read.mjs.map +1 -1
  67. package/dist/core/commands/search.cjs +5 -1
  68. package/dist/core/commands/search.mjs +5 -1
  69. package/dist/core/commands/search.mjs.map +1 -1
  70. package/dist/core/commands/stat.mjs.map +1 -1
  71. package/dist/core/commands/types.d.cts +2 -0
  72. package/dist/core/commands/types.d.cts.map +1 -1
  73. package/dist/core/commands/types.d.mts +2 -0
  74. package/dist/core/commands/types.d.mts.map +1 -1
  75. package/dist/core/commands/types.mjs.map +1 -1
  76. package/dist/core/commands/vault.cjs +289 -0
  77. package/dist/core/commands/vault.d.mts +2 -0
  78. package/dist/core/commands/vault.mjs +289 -0
  79. package/dist/core/commands/vault.mjs.map +1 -0
  80. package/dist/core/commands/write.cjs +19 -6
  81. package/dist/core/commands/write.d.cts +2 -1
  82. package/dist/core/commands/write.d.cts.map +1 -1
  83. package/dist/core/commands/write.d.mts +2 -1
  84. package/dist/core/commands/write.d.mts.map +1 -1
  85. package/dist/core/commands/write.mjs +19 -6
  86. package/dist/core/commands/write.mjs.map +1 -1
  87. package/dist/core/executor/index.cjs +95 -19
  88. package/dist/core/executor/index.d.cts +4 -0
  89. package/dist/core/executor/index.d.cts.map +1 -1
  90. package/dist/core/executor/index.d.mts +4 -0
  91. package/dist/core/executor/index.d.mts.map +1 -1
  92. package/dist/core/executor/index.mjs +95 -19
  93. package/dist/core/executor/index.mjs.map +1 -1
  94. package/dist/core/formatters/index.d.mts +1 -0
  95. package/dist/core/formatters/install.cjs +21 -0
  96. package/dist/core/formatters/install.d.mts +1 -0
  97. package/dist/core/formatters/install.mjs +19 -0
  98. package/dist/core/formatters/install.mjs.map +1 -0
  99. package/dist/core/formatters/vault.cjs +36 -0
  100. package/dist/core/formatters/vault.mjs +32 -0
  101. package/dist/core/formatters/vault.mjs.map +1 -0
  102. package/dist/credential/index.d.mts +2 -1
  103. package/dist/credential/mcp-auth-context.cjs +21 -5
  104. package/dist/credential/mcp-auth-context.mjs +21 -5
  105. package/dist/credential/mcp-auth-context.mjs.map +1 -1
  106. package/dist/credential/resolver.cjs +7 -2
  107. package/dist/credential/resolver.mjs +7 -2
  108. package/dist/credential/resolver.mjs.map +1 -1
  109. package/dist/credential/vault-store.d.mts +1 -0
  110. package/dist/daemon/config-manager.cjs +279 -0
  111. package/dist/daemon/config-manager.mjs +279 -0
  112. package/dist/daemon/config-manager.mjs.map +1 -0
  113. package/dist/daemon/manager.cjs +164 -0
  114. package/dist/daemon/manager.mjs +157 -0
  115. package/dist/daemon/manager.mjs.map +1 -0
  116. package/dist/daemon/server.cjs +220 -0
  117. package/dist/daemon/server.mjs +220 -0
  118. package/dist/daemon/server.mjs.map +1 -0
  119. package/dist/mcp/http-transport.cjs +14 -1
  120. package/dist/mcp/http-transport.mjs +14 -1
  121. package/dist/mcp/http-transport.mjs.map +1 -1
  122. package/dist/mcp/server.cjs +4 -2
  123. package/dist/mcp/server.mjs +4 -2
  124. package/dist/mcp/server.mjs.map +1 -1
  125. package/dist/mcp/tools.cjs +62 -12
  126. package/dist/mcp/tools.mjs +62 -12
  127. package/dist/mcp/tools.mjs.map +1 -1
  128. package/dist/program/daemon-integration.cjs +46 -0
  129. package/dist/program/daemon-integration.mjs +45 -0
  130. package/dist/program/daemon-integration.mjs.map +1 -0
  131. package/dist/program/program-manager.cjs +162 -0
  132. package/dist/program/program-manager.mjs +162 -0
  133. package/dist/program/program-manager.mjs.map +1 -0
  134. package/dist/program/trigger-scanner.cjs +148 -0
  135. package/dist/program/trigger-scanner.mjs +148 -0
  136. package/dist/program/trigger-scanner.mjs.map +1 -0
  137. package/dist/providers/vault/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
  138. package/dist/providers/vault/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +11 -0
  139. package/dist/providers/vault/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs.map +1 -0
  140. package/dist/providers/vault/dist/encrypted-file.cjs +158 -0
  141. package/dist/providers/vault/dist/encrypted-file.mjs +153 -0
  142. package/dist/providers/vault/dist/encrypted-file.mjs.map +1 -0
  143. package/dist/providers/vault/dist/index.cjs +405 -0
  144. package/dist/providers/vault/dist/index.mjs +400 -0
  145. package/dist/providers/vault/dist/index.mjs.map +1 -0
  146. package/dist/providers/vault/dist/key-resolver.cjs +181 -0
  147. package/dist/providers/vault/dist/key-resolver.mjs +180 -0
  148. package/dist/providers/vault/dist/key-resolver.mjs.map +1 -0
  149. package/dist/repl.cjs +105 -14
  150. package/dist/repl.d.cts.map +1 -1
  151. package/dist/repl.d.mts.map +1 -1
  152. package/dist/repl.mjs +105 -14
  153. package/dist/repl.mjs.map +1 -1
  154. package/package.json +29 -22
@@ -0,0 +1,405 @@
1
+ const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
2
+ const require_encrypted_file = require('./encrypted-file.cjs');
3
+ const require_decorate = require('./_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs');
4
+ const require_key_resolver = require('./key-resolver.cjs');
5
+ let ufo = require("ufo");
6
+ let _aigne_afs = require("@aigne/afs");
7
+ let zod = require("zod");
8
+ let _aigne_afs_provider = require("@aigne/afs/provider");
9
+
10
+ //#region ../../providers/vault/dist/index.mjs
11
+ /**
12
+ * AFS Vault Provider — Encrypted secret storage.
13
+ *
14
+ * Tree: /vault/{group}/{name} → secret value (string)
15
+ * Encryption: AES-256-GCM, master key from keychain/env/passphrase
16
+ * Security: admin (readwrite) + system (readonly) profiles
17
+ * No exec — vault is passive storage.
18
+ */
19
+ const afsVaultOptionsSchema = zod.z.object({
20
+ name: zod.z.string().optional().describe("Module name"),
21
+ description: zod.z.string().optional().describe("Module description"),
22
+ vaultPath: zod.z.string().describe("Path to the encrypted vault file"),
23
+ accessMode: zod.z.enum(["readonly", "readwrite"]).optional().describe("Access mode")
24
+ });
25
+ /** Prototype pollution guard — reject dangerous path segments. */
26
+ const DANGEROUS_NAMES = new Set([
27
+ "__proto__",
28
+ "constructor",
29
+ "prototype"
30
+ ]);
31
+ function assertSafeName(segment) {
32
+ if (DANGEROUS_NAMES.has(segment)) throw new Error(`Forbidden path segment: ${segment}`);
33
+ }
34
+ var AFSVault = class AFSVault extends _aigne_afs_provider.AFSBaseProvider {
35
+ name;
36
+ description;
37
+ accessMode;
38
+ vaultPath;
39
+ _masterKey;
40
+ _data = null;
41
+ _loaded = false;
42
+ constructor(options) {
43
+ super();
44
+ this.name = options.name || "vault";
45
+ this.description = options.description || "Encrypted secret storage";
46
+ this.accessMode = options.accessMode || "readwrite";
47
+ this.vaultPath = options.vaultPath;
48
+ this._masterKey = options.masterKey;
49
+ }
50
+ static securityProfiles() {
51
+ return {
52
+ admin: {
53
+ actionPolicy: "full",
54
+ accessMode: "readwrite"
55
+ },
56
+ system: {
57
+ actionPolicy: "full",
58
+ accessMode: "readonly"
59
+ }
60
+ };
61
+ }
62
+ static schema() {
63
+ return afsVaultOptionsSchema;
64
+ }
65
+ static treeSchema() {
66
+ return {
67
+ operations: [
68
+ "list",
69
+ "read",
70
+ "write",
71
+ "delete",
72
+ "search",
73
+ "stat",
74
+ "explain"
75
+ ],
76
+ tree: {
77
+ "/": {
78
+ kind: "vault:root",
79
+ operations: ["list", "read"]
80
+ },
81
+ "/{group}": {
82
+ kind: "vault:group",
83
+ operations: [
84
+ "list",
85
+ "read",
86
+ "delete"
87
+ ],
88
+ destructive: ["delete"]
89
+ },
90
+ "/{group}/{name}": {
91
+ kind: "vault:secret",
92
+ operations: [
93
+ "read",
94
+ "write",
95
+ "delete"
96
+ ],
97
+ destructive: ["delete"]
98
+ }
99
+ },
100
+ auth: {
101
+ type: "custom",
102
+ env: ["AFS_VAULT_KEY"]
103
+ },
104
+ bestFor: ["secret storage", "API key management"],
105
+ notFor: ["large file storage"]
106
+ };
107
+ }
108
+ static manifest() {
109
+ return {
110
+ name: "vault",
111
+ description: "Encrypted secret storage.\n- Store API keys, tokens, and passwords with AES-256-GCM encryption\n- Secrets organized in groups: /vault/{group}/{name}\n- Security profiles: admin (readwrite), system (readonly)",
112
+ uriTemplate: "vault://{vaultPath+}",
113
+ category: "security",
114
+ schema: zod.z.object({ vaultPath: zod.z.string() }),
115
+ tags: [
116
+ "vault",
117
+ "secrets",
118
+ "encryption",
119
+ "credentials"
120
+ ],
121
+ capabilityTags: [
122
+ "read-write",
123
+ "crud",
124
+ "search",
125
+ "auth:none",
126
+ "local"
127
+ ],
128
+ security: {
129
+ riskLevel: "local",
130
+ resourceAccess: ["local-filesystem"],
131
+ dataSensitivity: ["credentials"],
132
+ notes: ["Stores encrypted secrets in a local file (AES-256-GCM)", "Master key stored in OS keychain or derived from passphrase"]
133
+ },
134
+ capabilities: {
135
+ filesystem: {
136
+ read: true,
137
+ write: true
138
+ },
139
+ secrets: ["vault/master-key"]
140
+ }
141
+ };
142
+ }
143
+ static async load({ config } = {}) {
144
+ return new AFSVault(afsVaultOptionsSchema.parse(config || {}));
145
+ }
146
+ async ensureLoaded() {
147
+ if (!this._loaded && this._masterKey) {
148
+ this._data = await require_encrypted_file.readEncryptedVault(this.vaultPath, this._masterKey);
149
+ this._loaded = true;
150
+ }
151
+ if (!this._data) {
152
+ this._data = { secrets: {} };
153
+ this._loaded = true;
154
+ }
155
+ return this._data;
156
+ }
157
+ async save() {
158
+ if (!this._masterKey) throw new Error("Vault master key not set — cannot write");
159
+ if (!this._data) return;
160
+ await require_encrypted_file.writeEncryptedVault(this.vaultPath, this._data, this._masterKey);
161
+ }
162
+ /** Set the master key at runtime (for lazy initialization). */
163
+ setMasterKey(key) {
164
+ this._masterKey = key;
165
+ this._loaded = false;
166
+ }
167
+ buildGroupEntry(group, secrets) {
168
+ return this.buildEntry((0, ufo.joinURL)("/", group), { meta: { childrenCount: Object.keys(secrets).length } });
169
+ }
170
+ buildSecretEntry(group, name, value, includeContent = false) {
171
+ return this.buildEntry((0, ufo.joinURL)("/", group, name), {
172
+ content: includeContent ? value : void 0,
173
+ meta: { size: value.length }
174
+ });
175
+ }
176
+ buildRootEntry(data) {
177
+ return this.buildEntry("/", { meta: {
178
+ childrenCount: Object.keys(data.secrets).length,
179
+ provider: "vault",
180
+ encrypted: true
181
+ } });
182
+ }
183
+ parsePath(ctx) {
184
+ return (ctx.params?.path || "").split("/").filter(Boolean);
185
+ }
186
+ async handleMeta(ctx) {
187
+ const data = await this.ensureLoaded();
188
+ const parts = this.parsePath(ctx);
189
+ const metaPath = parts.length === 0 ? "/.meta" : (0, ufo.joinURL)("/", ...parts, ".meta");
190
+ if (parts.length === 0) return this.buildEntry(metaPath, { meta: {
191
+ childrenCount: Object.keys(data.secrets).length,
192
+ provider: "vault",
193
+ encrypted: true
194
+ } });
195
+ if (parts.length === 1) {
196
+ const group = parts[0];
197
+ const secrets = data.secrets[group];
198
+ if (!secrets) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group));
199
+ return this.buildEntry(metaPath, { meta: { childrenCount: Object.keys(secrets).length } });
200
+ }
201
+ if (parts.length === 2) {
202
+ const group = parts[0];
203
+ const name = parts[1];
204
+ const secrets = data.secrets[group];
205
+ if (!secrets || !(name in secrets)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group, name));
206
+ return this.buildEntry(metaPath, { meta: { size: secrets[name].length } });
207
+ }
208
+ throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", ...parts));
209
+ }
210
+ async handleList(ctx) {
211
+ const data = await this.ensureLoaded();
212
+ const parts = this.parsePath(ctx);
213
+ if (parts.length === 0) return { data: Object.keys(data.secrets).sort().map((g) => this.buildGroupEntry(g, data.secrets[g])) };
214
+ if (parts.length === 1) {
215
+ const group = parts[0];
216
+ const secrets = data.secrets[group];
217
+ if (!secrets) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group));
218
+ return { data: Object.keys(secrets).sort().map((n) => this.buildSecretEntry(group, n, secrets[n], false)) };
219
+ }
220
+ if (parts.length === 2) {
221
+ const group = parts[0];
222
+ const name = parts[1];
223
+ const secrets = data.secrets[group];
224
+ if (!secrets || !(name in secrets)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group, name));
225
+ return { data: [] };
226
+ }
227
+ throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", ...parts));
228
+ }
229
+ async handleReadCapabilities() {
230
+ const operations = this.getOperationsDeclaration();
231
+ const manifest = {
232
+ schemaVersion: 1,
233
+ provider: this.name,
234
+ description: this.description,
235
+ tools: [],
236
+ actions: [],
237
+ operations
238
+ };
239
+ return this.buildEntry("/.meta/.capabilities", {
240
+ content: manifest,
241
+ meta: {
242
+ kind: "afs:capabilities",
243
+ operations
244
+ }
245
+ });
246
+ }
247
+ async handleRead(ctx) {
248
+ const data = await this.ensureLoaded();
249
+ const parts = this.parsePath(ctx);
250
+ if (parts.length === 0) return this.buildRootEntry(data);
251
+ if (parts.length === 1) {
252
+ const group = parts[0];
253
+ const secrets = data.secrets[group];
254
+ if (!secrets) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group));
255
+ return this.buildGroupEntry(group, secrets);
256
+ }
257
+ if (parts.length === 2) {
258
+ const group = parts[0];
259
+ const name = parts[1];
260
+ const secrets = data.secrets[group];
261
+ if (!secrets || !(name in secrets)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group, name));
262
+ return this.buildSecretEntry(group, name, secrets[name], true);
263
+ }
264
+ throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", ...parts));
265
+ }
266
+ async handleStat(ctx) {
267
+ const data = await this.ensureLoaded();
268
+ const parts = this.parsePath(ctx);
269
+ if (parts.length === 0) return { data: this.buildRootEntry(data) };
270
+ if (parts.length === 1) {
271
+ const group = parts[0];
272
+ const secrets = data.secrets[group];
273
+ if (!secrets) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group));
274
+ return { data: this.buildGroupEntry(group, secrets) };
275
+ }
276
+ if (parts.length === 2) {
277
+ const group = parts[0];
278
+ const name = parts[1];
279
+ const secrets = data.secrets[group];
280
+ if (!secrets || !(name in secrets)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group, name));
281
+ return { data: this.buildSecretEntry(group, name, secrets[name], false) };
282
+ }
283
+ throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", ...parts));
284
+ }
285
+ async handleWrite(ctx, payload) {
286
+ const data = await this.ensureLoaded();
287
+ const group = ctx.params.group;
288
+ const name = ctx.params.name;
289
+ assertSafeName(group);
290
+ assertSafeName(name);
291
+ const content = payload?.content;
292
+ if (typeof content !== "string") throw new Error("Vault secrets must be string values");
293
+ if (!data.secrets[group]) data.secrets[group] = {};
294
+ data.secrets[group][name] = content;
295
+ await this.save();
296
+ return { data: this.buildSecretEntry(group, name, content, true) };
297
+ }
298
+ async handleDelete(ctx) {
299
+ const data = await this.ensureLoaded();
300
+ const group = ctx.params.group;
301
+ const name = ctx.params.name;
302
+ const secrets = data.secrets[group];
303
+ if (!secrets || !(name in secrets)) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group, name));
304
+ delete secrets[name];
305
+ if (Object.keys(secrets).length === 0) delete data.secrets[group];
306
+ await this.save();
307
+ return { message: `Deleted secret: ${(0, ufo.joinURL)("/", group, name)}` };
308
+ }
309
+ async handleDeleteGroup(ctx) {
310
+ const data = await this.ensureLoaded();
311
+ const group = ctx.params.group;
312
+ if (!data.secrets[group]) throw new _aigne_afs.AFSNotFoundError((0, ufo.joinURL)("/", group));
313
+ delete data.secrets[group];
314
+ await this.save();
315
+ return { message: `Deleted group: ${(0, ufo.joinURL)("/", group)}` };
316
+ }
317
+ async handleSearch(ctx, query, options) {
318
+ const data = await this.ensureLoaded();
319
+ const pattern = (query || "").toLowerCase();
320
+ const groupFilter = this.parsePath(ctx)[0];
321
+ const limit = options?.limit;
322
+ const results = [];
323
+ const groups = groupFilter ? [groupFilter] : Object.keys(data.secrets);
324
+ for (const group of groups) {
325
+ const secrets = data.secrets[group];
326
+ if (!secrets) continue;
327
+ if (!groupFilter && group.toLowerCase().includes(pattern)) {
328
+ results.push(this.buildGroupEntry(group, secrets));
329
+ if (limit && results.length >= limit) break;
330
+ }
331
+ for (const name of Object.keys(secrets)) {
332
+ if (limit && results.length >= limit) break;
333
+ if (name.toLowerCase().includes(pattern)) results.push(this.buildSecretEntry(group, name, secrets[name], false));
334
+ }
335
+ if (limit && results.length >= limit) break;
336
+ }
337
+ return { data: limit ? results.slice(0, limit) : results };
338
+ }
339
+ async handleExplain(ctx) {
340
+ const parts = this.parsePath(ctx);
341
+ let content;
342
+ if (parts.length >= 2) content = `Secret "${parts[1]}" in group "${parts[0]}". Read to get the secret value.`;
343
+ else if (parts.length === 1) content = `Secret group "${parts[0]}". List to see available secrets.`;
344
+ else content = "AFS Vault — encrypted secret storage. List to see secret groups.";
345
+ return {
346
+ format: "text",
347
+ content
348
+ };
349
+ }
350
+ /** Get a secret value directly (bypasses AFS routing). */
351
+ async getSecret(group, name) {
352
+ return (await this.ensureLoaded()).secrets[group]?.[name];
353
+ }
354
+ /** Set a secret value directly. */
355
+ async setSecret(group, name, value) {
356
+ const data = await this.ensureLoaded();
357
+ if (!data.secrets[group]) data.secrets[group] = {};
358
+ data.secrets[group][name] = value;
359
+ await this.save();
360
+ }
361
+ /** Delete a secret directly. */
362
+ async deleteSecret(group, name) {
363
+ const data = await this.ensureLoaded();
364
+ const secrets = data.secrets[group];
365
+ if (!secrets || !(name in secrets)) return false;
366
+ delete secrets[name];
367
+ if (Object.keys(secrets).length === 0) delete data.secrets[group];
368
+ await this.save();
369
+ return true;
370
+ }
371
+ /** List all groups, or all secrets in a group. */
372
+ async listSecrets(group) {
373
+ const data = await this.ensureLoaded();
374
+ if (!group) return Object.keys(data.secrets).sort();
375
+ const secrets = data.secrets[group];
376
+ if (!secrets) return [];
377
+ return Object.keys(secrets).sort();
378
+ }
379
+ /** Get all secrets as flat map: "group/name" → value. Used for migration. */
380
+ async getAllSecrets() {
381
+ const data = await this.ensureLoaded();
382
+ const result = {};
383
+ for (const [group, secrets] of Object.entries(data.secrets)) for (const [name, value] of Object.entries(secrets)) result[`${group}/${name}`] = value;
384
+ return result;
385
+ }
386
+ };
387
+ require_decorate.__decorate([(0, _aigne_afs_provider.Meta)("/:path*")], AFSVault.prototype, "handleMeta", null);
388
+ require_decorate.__decorate([(0, _aigne_afs_provider.List)("/:path*")], AFSVault.prototype, "handleList", null);
389
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/.meta/.capabilities")], AFSVault.prototype, "handleReadCapabilities", null);
390
+ require_decorate.__decorate([(0, _aigne_afs_provider.Read)("/:path*")], AFSVault.prototype, "handleRead", null);
391
+ require_decorate.__decorate([(0, _aigne_afs_provider.Stat)("/:path*")], AFSVault.prototype, "handleStat", null);
392
+ require_decorate.__decorate([(0, _aigne_afs_provider.Write)("/:group/:name")], AFSVault.prototype, "handleWrite", null);
393
+ require_decorate.__decorate([(0, _aigne_afs_provider.Delete)("/:group/:name")], AFSVault.prototype, "handleDelete", null);
394
+ require_decorate.__decorate([(0, _aigne_afs_provider.Delete)("/:group")], AFSVault.prototype, "handleDeleteGroup", null);
395
+ require_decorate.__decorate([(0, _aigne_afs_provider.Search)("/:path*")], AFSVault.prototype, "handleSearch", null);
396
+ require_decorate.__decorate([(0, _aigne_afs_provider.Explain)("/:path*")], AFSVault.prototype, "handleExplain", null);
397
+ AFSVault.load = AFSVault.load;
398
+
399
+ //#endregion
400
+ exports.AFSVault = AFSVault;
401
+ exports.generateMasterKey = require_encrypted_file.generateMasterKey;
402
+ exports.resolveMasterKey = require_key_resolver.resolveMasterKey;
403
+ exports.storeKeychain = require_key_resolver.storeKeychain;
404
+ exports.vaultFileExists = require_encrypted_file.vaultFileExists;
405
+ exports.writeEncryptedVault = require_encrypted_file.writeEncryptedVault;