@songsid/agend 2.1.6-beta.6 → 2.1.6-beta.7

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 (39) hide show
  1. package/dist/channel/adapters/discord.d.ts +14 -0
  2. package/dist/channel/adapters/discord.js +59 -1
  3. package/dist/channel/adapters/discord.js.map +1 -1
  4. package/dist/channel/adapters/telegram.d.ts +6 -0
  5. package/dist/channel/adapters/telegram.js +36 -0
  6. package/dist/channel/adapters/telegram.js.map +1 -1
  7. package/dist/channel/types.d.ts +18 -0
  8. package/dist/config-validator.js +3 -0
  9. package/dist/config-validator.js.map +1 -1
  10. package/dist/connection-secrets.d.ts +96 -0
  11. package/dist/connection-secrets.js +25 -0
  12. package/dist/connection-secrets.js.map +1 -0
  13. package/dist/daemon.d.ts +29 -0
  14. package/dist/daemon.js +145 -77
  15. package/dist/daemon.js.map +1 -1
  16. package/dist/fleet-manager.d.ts +171 -0
  17. package/dist/fleet-manager.js +954 -5
  18. package/dist/fleet-manager.js.map +1 -1
  19. package/dist/provider-probe.d.ts +3 -0
  20. package/dist/provider-probe.js +12 -2
  21. package/dist/provider-probe.js.map +1 -1
  22. package/dist/provider-secret-registry.d.ts +98 -0
  23. package/dist/provider-secret-registry.js +334 -0
  24. package/dist/provider-secret-registry.js.map +1 -0
  25. package/dist/quickstart-api.d.ts +1 -1
  26. package/dist/quickstart-api.js +14 -4
  27. package/dist/quickstart-api.js.map +1 -1
  28. package/dist/secret-store.d.ts +25 -0
  29. package/dist/secret-store.js +165 -0
  30. package/dist/secret-store.js.map +1 -0
  31. package/dist/settings-api.d.ts +101 -0
  32. package/dist/settings-api.js +404 -4
  33. package/dist/settings-api.js.map +1 -1
  34. package/dist/types.d.ts +2 -0
  35. package/dist/ui/settings.html +171 -6
  36. package/dist/usage/usage-api.d.ts +12 -0
  37. package/dist/usage/usage-api.js +39 -0
  38. package/dist/usage/usage-api.js.map +1 -1
  39. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ export declare const SECRET_ENV_KEY: RegExp;
2
+ export interface SecretSnapshot {
3
+ exists: boolean;
4
+ content: string;
5
+ }
6
+ export interface SecretStoreOptions {
7
+ /** A test seam; production uses fsync and atomic rename below. */
8
+ fsync?: (fd: number) => void;
9
+ }
10
+ /** Replace one KEY=value while retaining comments and unrelated variables. */
11
+ export declare function upsertSecretEnvLine(existing: string, key: string, value: string): string;
12
+ export declare class SecretStore {
13
+ readonly path: string;
14
+ private readonly allowedKeys;
15
+ private readonly fsync;
16
+ constructor(path: string, allowedKeys?: ReadonlySet<string>, opts?: SecretStoreOptions);
17
+ private rejectSymlink;
18
+ private validateKey;
19
+ snapshot(): SecretSnapshot;
20
+ /** Atomic replacement; callers should retain snapshot() for rollback. */
21
+ replace(content: string): void;
22
+ private fsyncDirectory;
23
+ restore(snapshot: SecretSnapshot): void;
24
+ write(key: string, value: string): SecretSnapshot;
25
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Small, deliberately boring secret store for the running Settings API.
3
+ *
4
+ * Secrets live in the existing .env file for compatibility with the CLI, but
5
+ * all writes go through this module. The write is same-directory atomic,
6
+ * owner-only, and returns a snapshot that can be restored when an adapter
7
+ * rebuild fails. No exception from this module includes the secret value.
8
+ */
9
+ import { closeSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeSync, chmodSync, } from "node:fs";
10
+ import { randomBytes } from "node:crypto";
11
+ import { dirname, join } from "node:path";
12
+ export const SECRET_ENV_KEY = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
13
+ const RESERVED_ENV_KEYS = new Set([
14
+ "PATH", "HOME", "PWD", "SHELL", "ENV", "BASH_ENV", "NODE_OPTIONS", "LD_PRELOAD",
15
+ ]);
16
+ function fsyncDirectory(path, fsync) {
17
+ const fd = openSync(path, "r");
18
+ try {
19
+ fsync(fd);
20
+ }
21
+ finally {
22
+ closeSync(fd);
23
+ }
24
+ }
25
+ /** Replace one KEY=value while retaining comments and unrelated variables. */
26
+ export function upsertSecretEnvLine(existing, key, value) {
27
+ const lines = existing.split(/\r?\n/);
28
+ let replaced = false;
29
+ const next = lines.map(line => {
30
+ const match = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/);
31
+ if (!match || match[1] !== key)
32
+ return line;
33
+ replaced = true;
34
+ return `${key}=${value}`;
35
+ });
36
+ if (!replaced) {
37
+ while (next.length && next[next.length - 1] === "")
38
+ next.pop();
39
+ next.push(`${key}=${value}`);
40
+ }
41
+ return next.join("\n").replace(/\n*$/, "\n");
42
+ }
43
+ export class SecretStore {
44
+ path;
45
+ allowedKeys;
46
+ fsync;
47
+ constructor(path, allowedKeys = new Set(), opts = {}) {
48
+ this.path = path;
49
+ this.allowedKeys = allowedKeys;
50
+ this.fsync = opts.fsync ?? fsyncSync;
51
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
52
+ this.rejectSymlink(path);
53
+ }
54
+ rejectSymlink(path) {
55
+ try {
56
+ if (lstatSync(path).isSymbolicLink())
57
+ throw new Error("secret file must not be a symlink");
58
+ }
59
+ catch (err) {
60
+ if (err.code !== "ENOENT")
61
+ throw err;
62
+ }
63
+ }
64
+ validateKey(key) {
65
+ if (!SECRET_ENV_KEY.test(key) || RESERVED_ENV_KEYS.has(key))
66
+ throw new Error("secret key is not allowed");
67
+ if (this.allowedKeys.size > 0 && !this.allowedKeys.has(key))
68
+ throw new Error("secret key is not configured for a connection");
69
+ }
70
+ snapshot() {
71
+ this.rejectSymlink(this.path);
72
+ try {
73
+ return { exists: true, content: readFileSync(this.path, "utf8") };
74
+ }
75
+ catch (err) {
76
+ if (err.code === "ENOENT")
77
+ return { exists: false, content: "" };
78
+ throw new Error("secret file could not be read");
79
+ }
80
+ }
81
+ /** Atomic replacement; callers should retain snapshot() for rollback. */
82
+ replace(content) {
83
+ this.rejectSymlink(this.path);
84
+ const dir = dirname(this.path);
85
+ const temp = join(dir, `.${this.path.split(/[\\/]/).pop() ?? "env"}.${process.pid}.${randomBytes(8).toString("hex")}.tmp`);
86
+ let fd;
87
+ try {
88
+ fd = openSync(temp, "wx", 0o600);
89
+ writeSync(fd, content, undefined, "utf8");
90
+ this.fsync(fd);
91
+ closeSync(fd);
92
+ fd = undefined;
93
+ // chmod is deliberately a hard error: a successful rename with loose
94
+ // permissions is never reported as an applied secret.
95
+ chmodSync(temp, 0o600);
96
+ this.rejectSymlink(temp);
97
+ renameSync(temp, this.path);
98
+ this.fsyncDirectory(dir);
99
+ }
100
+ catch (err) {
101
+ if (fd !== undefined) {
102
+ try {
103
+ closeSync(fd);
104
+ }
105
+ catch { /* best effort */ }
106
+ }
107
+ try {
108
+ unlinkSync(temp);
109
+ }
110
+ catch { /* best effort */ }
111
+ if (err instanceof Error && /secret file must not be a symlink/.test(err.message))
112
+ throw err;
113
+ throw new Error("secret file could not be written atomically");
114
+ }
115
+ }
116
+ fsyncDirectory(path) {
117
+ try {
118
+ fsyncDirectory(path, this.fsync);
119
+ }
120
+ catch {
121
+ throw new Error("secret directory could not be synced");
122
+ }
123
+ }
124
+ restore(snapshot) {
125
+ if (snapshot.exists)
126
+ this.replace(snapshot.content);
127
+ else {
128
+ this.rejectSymlink(this.path);
129
+ try {
130
+ unlinkSync(this.path);
131
+ }
132
+ catch (err) {
133
+ if (err.code !== "ENOENT")
134
+ throw new Error("secret rollback could not remove file");
135
+ }
136
+ try {
137
+ this.fsyncDirectory(dirname(this.path));
138
+ }
139
+ catch {
140
+ throw new Error("secret rollback could not sync directory");
141
+ }
142
+ }
143
+ }
144
+ write(key, value) {
145
+ this.validateKey(key);
146
+ if (!value || /[\r\n\0]/.test(value))
147
+ throw new Error("secret value is invalid");
148
+ const before = this.snapshot();
149
+ try {
150
+ this.replace(upsertSecretEnvLine(before.content, key, value));
151
+ }
152
+ catch (err) {
153
+ // A directory fsync can fail after rename has already replaced the
154
+ // target. Restore the snapshot here so callers never see a failed write
155
+ // with a new secret left on disk.
156
+ try {
157
+ this.restore(before);
158
+ }
159
+ catch { /* caller reports rollback failure */ }
160
+ throw err;
161
+ }
162
+ return before;
163
+ }
164
+ }
165
+ //# sourceMappingURL=secret-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-store.js","sourceRoot":"","sources":["../src/secret-store.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,8 @@ import type { IncomingMessage, ServerResponse } from "node:http";
26
26
  import type { Logger } from "./logger.js";
27
27
  import type { FleetConfig, RawFleetConfig } from "./types.js";
28
28
  import { type ApplyJob, type ApplyJobStore, type SelfRestartResult } from "./apply-job.js";
29
+ import { type ConnectionMetadata, type ConnectionBinding, type BindingProbe, type SecretApplyJob, type ProviderSecretApplyJob } from "./connection-secrets.js";
30
+ import type { ProviderSecretStatus } from "./provider-secret-registry.js";
29
31
  export interface SettingsApiContext {
30
32
  fleetConfig: FleetConfig | null;
31
33
  configPath: string | null;
@@ -54,6 +56,105 @@ export interface SettingsApiContext {
54
56
  fleetSignatureMismatchKeys?(): string[] | null;
55
57
  /** True when a running adapter is already long-polling this bot token. */
56
58
  isBotTokenInUse?(token: string): boolean;
59
+ /** Secure Connections & Bots operations. The outer fleet HTTP server has
60
+ * already authenticated the Settings web session before this handler runs. */
61
+ listSecureConnections?(): ConnectionMetadata[];
62
+ verifyConnectionSecret?(input: {
63
+ connectionId: string;
64
+ secret: string;
65
+ sessionBinding: string;
66
+ idempotencyKey: string;
67
+ }): Promise<{
68
+ ok: true;
69
+ verification_id: string;
70
+ expires_at: number;
71
+ identity?: {
72
+ id: string | null;
73
+ username: string | null;
74
+ };
75
+ } | {
76
+ ok: false;
77
+ error: string;
78
+ }>;
79
+ startConnectionSecretApply?(input: {
80
+ connectionId: string;
81
+ verificationId: string;
82
+ sessionBinding: string;
83
+ idempotencyKey: string;
84
+ }): {
85
+ job: SecretApplyJob;
86
+ reused: boolean;
87
+ } | {
88
+ busy: SecretApplyJob | null;
89
+ } | {
90
+ error: string;
91
+ };
92
+ getConnectionSecretApply?(jobId: string, sessionBinding: string): SecretApplyJob | null;
93
+ /** Generic provider API-key verifier registry (#861). */
94
+ providerSecretsEnabled?(): boolean;
95
+ listProviderSecrets?(): ProviderSecretStatus[];
96
+ verifyProviderSecret?(input: {
97
+ specId: string;
98
+ secret: string;
99
+ sessionBinding: string;
100
+ idempotencyKey: string;
101
+ }): Promise<{
102
+ ok: true;
103
+ verification_id: string;
104
+ expires_at: number;
105
+ spec_id: string;
106
+ activation: "next_use" | "reload_hook";
107
+ } | {
108
+ ok: false;
109
+ status: string;
110
+ error: string;
111
+ }>;
112
+ startProviderSecretApply?(input: {
113
+ specId: string;
114
+ verificationId: string;
115
+ sessionBinding: string;
116
+ idempotencyKey: string;
117
+ }): {
118
+ job: ProviderSecretApplyJob;
119
+ reused: boolean;
120
+ } | {
121
+ busy: ProviderSecretApplyJob | null;
122
+ } | {
123
+ error: string;
124
+ };
125
+ getProviderSecretApply?(jobId: string, sessionBinding: string): ProviderSecretApplyJob | null;
126
+ verifyConnectionBinding?(input: {
127
+ connectionId: string;
128
+ binding: {
129
+ group_id?: unknown;
130
+ general_channel_id?: unknown;
131
+ };
132
+ sessionBinding: string;
133
+ idempotencyKey: string;
134
+ }): Promise<{
135
+ ok: true;
136
+ verification_id: string;
137
+ expires_at: number;
138
+ binding: ConnectionBinding;
139
+ probe: BindingProbe;
140
+ } | {
141
+ ok: false;
142
+ error: string;
143
+ }>;
144
+ startConnectionBindingApply?(input: {
145
+ connectionId: string;
146
+ verificationId: string;
147
+ sessionBinding: string;
148
+ idempotencyKey: string;
149
+ }): {
150
+ job: SecretApplyJob;
151
+ reused: boolean;
152
+ } | {
153
+ busy: SecretApplyJob | null;
154
+ } | {
155
+ error: string;
156
+ };
157
+ getConnectionBindingApply?(jobId: string, sessionBinding: string): SecretApplyJob | null;
57
158
  }
58
159
  /** An explicit user-authored YAML mutation that must be persisted even when
59
160
  * its value equals the defaults-expanded runtime snapshot. */