@aexol/spectral 0.9.245 → 0.9.247
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/CHANGELOG.md +18 -0
- package/dist/cli.js +6 -0
- package/dist/commands/secret.d.ts +16 -0
- package/dist/commands/secret.d.ts.map +1 -0
- package/dist/commands/secret.js +153 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +21 -0
- package/dist/extensions/list-secrets.d.ts +14 -0
- package/dist/extensions/list-secrets.d.ts.map +1 -0
- package/dist/extensions/list-secrets.js +63 -0
- package/dist/generated/zeus/const.d.ts.map +1 -1
- package/dist/generated/zeus/const.js +16 -0
- package/dist/generated/zeus/index.d.ts +73 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/relay/routing.d.ts +1 -1
- package/dist/relay/routing.d.ts.map +1 -1
- package/dist/relay/routing.js +93 -17
- package/dist/sdk/coding-agent/utils/shell.d.ts.map +1 -1
- package/dist/sdk/coding-agent/utils/shell.js +15 -1
- package/dist/secrets/index.d.ts +11 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +10 -0
- package/dist/secrets/store.d.ts +109 -0
- package/dist/secrets/store.d.ts.map +1 -0
- package/dist/secrets/store.js +415 -0
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +20 -2
- package/dist/server/attachments/cleanup.d.ts +42 -0
- package/dist/server/attachments/cleanup.d.ts.map +1 -0
- package/dist/server/attachments/cleanup.js +100 -0
- package/dist/server/attachments/persist.d.ts +131 -0
- package/dist/server/attachments/persist.d.ts.map +1 -0
- package/dist/server/attachments/persist.js +406 -0
- package/dist/server/handlers/secrets.d.ts +40 -0
- package/dist/server/handlers/secrets.d.ts.map +1 -0
- package/dist/server/handlers/secrets.js +78 -0
- package/dist/server/session-stream.d.ts +5 -0
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +51 -1
- package/dist/server/storage.d.ts +6 -0
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/server/storage.js +9 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to `@aexol/spectral` are documented here. Format follows
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.9.247] - 2026-10-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added a public built-in model catalog: new `publicModelCatalog` GraphQL
|
|
13
|
+
query (`BuiltInModelCatalogEntry`) exposing built-in UserModels with credit
|
|
14
|
+
pricing per 1M tokens, measured average TPS (output tokens over measured
|
|
15
|
+
duration rows only), owner-configured fallback tok/s on BaseModel,
|
|
16
|
+
last-request time, 30-day request count, and status. The `/models` landing
|
|
17
|
+
page was rebuilt around `models-catalog-section.tsx`.
|
|
18
|
+
- Added `durationMs` capture on CreditUsageEvent in the backend generate and
|
|
19
|
+
refine flows, with database migrations `20261004122612` and
|
|
20
|
+
`20261004135152`.
|
|
21
|
+
- Added cli-node attachment support: persist and cleanup in
|
|
22
|
+
`src/server/attachments` with tests, plus serve, agent-bridge,
|
|
23
|
+
session-stream, and storage changes.
|
|
24
|
+
- Added a Fallback tok/s input to the admin base-models tab.
|
|
25
|
+
|
|
8
26
|
## [0.9.231] - 2026-09-23
|
|
9
27
|
|
|
10
28
|
### Added
|
package/dist/cli.js
CHANGED
|
@@ -39,6 +39,7 @@ function printHeader() {
|
|
|
39
39
|
" spectral desktop Start the agent in the background and open the UI",
|
|
40
40
|
" spectral bind Link this directory to an Aexol Studio project",
|
|
41
41
|
" spectral unbind Remove the Aexol Studio project binding",
|
|
42
|
+
" spectral secret Manage local secrets (set/list/rm)",
|
|
42
43
|
" spectral update Check for and install the latest Spectral version",
|
|
43
44
|
" spectral ports Diagnose port collisions across local projects",
|
|
44
45
|
" spectral --version Print version and exit",
|
|
@@ -135,6 +136,11 @@ async function main() {
|
|
|
135
136
|
await runUnbind();
|
|
136
137
|
process.exit(0);
|
|
137
138
|
}
|
|
139
|
+
if (first === "secret") {
|
|
140
|
+
const { runSecret } = await import("./commands/secret.js");
|
|
141
|
+
await runSecret(args.slice(1));
|
|
142
|
+
process.exit(0);
|
|
143
|
+
}
|
|
138
144
|
if (first === "update") {
|
|
139
145
|
const { runUpdate } = await import("./commands/update.js");
|
|
140
146
|
await runUpdate(args.slice(1));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `spectral secret` — manage the local encrypted secret store.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* spectral secret set NAME create/update a secret; value is read from
|
|
6
|
+
* STDIN (piped or hidden interactive prompt) and
|
|
7
|
+
* is NEVER passed as a command-line argument
|
|
8
|
+
* spectral secret list list names + timestamps — values are never shown
|
|
9
|
+
* spectral secret rm NAME delete a secret
|
|
10
|
+
*
|
|
11
|
+
* Shares the exact same store as the /api/secrets relay API and the
|
|
12
|
+
* `list_secrets` agent tool. Secrets set here are injected as env vars into
|
|
13
|
+
* the agent's bash tool (see src/secrets/store.ts).
|
|
14
|
+
*/
|
|
15
|
+
export declare function runSecret(args: string[]): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/commands/secret.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAsEH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyG7D"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `spectral secret` — manage the local encrypted secret store.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* spectral secret set NAME create/update a secret; value is read from
|
|
6
|
+
* STDIN (piped or hidden interactive prompt) and
|
|
7
|
+
* is NEVER passed as a command-line argument
|
|
8
|
+
* spectral secret list list names + timestamps — values are never shown
|
|
9
|
+
* spectral secret rm NAME delete a secret
|
|
10
|
+
*
|
|
11
|
+
* Shares the exact same store as the /api/secrets relay API and the
|
|
12
|
+
* `list_secrets` agent tool. Secrets set here are injected as env vars into
|
|
13
|
+
* the agent's bash tool (see src/secrets/store.ts).
|
|
14
|
+
*/
|
|
15
|
+
import { createInterface } from "node:readline";
|
|
16
|
+
import { Writable } from "node:stream";
|
|
17
|
+
import pc from "picocolors";
|
|
18
|
+
import { SecretNameError, SecretStoreCorruptError, SecretValueError, deleteSecret, listSecrets, setSecret, } from "../secrets/index.js";
|
|
19
|
+
/**
|
|
20
|
+
* Read the secret value from STDIN. Never from argv — argv is visible in
|
|
21
|
+
* shell history and the process table.
|
|
22
|
+
*
|
|
23
|
+
* - Piped input: the entire stdin is consumed; a single trailing newline
|
|
24
|
+
* (from `echo "value" | …`) is stripped, everything else is preserved.
|
|
25
|
+
* - Interactive TTY: a single line is read with the typed characters hidden
|
|
26
|
+
* (readline with a swallowing output stream).
|
|
27
|
+
*/
|
|
28
|
+
function readValueFromStdin(name) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
if (process.stdin.isTTY) {
|
|
31
|
+
// Hide input: swallow every echoed chunk; the prompt goes to real stdout.
|
|
32
|
+
const muted = new Writable({
|
|
33
|
+
write(_chunk, _enc, cb) {
|
|
34
|
+
cb();
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
const rl = createInterface({ input: process.stdin, output: muted, terminal: true });
|
|
38
|
+
process.stdout.write(`Enter value for ${name} (input hidden): `);
|
|
39
|
+
rl.question("", (answer) => {
|
|
40
|
+
rl.close();
|
|
41
|
+
process.stdout.write("\n");
|
|
42
|
+
resolve(answer);
|
|
43
|
+
});
|
|
44
|
+
rl.on("error", reject);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const chunks = [];
|
|
48
|
+
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
49
|
+
process.stdin.on("error", reject);
|
|
50
|
+
process.stdin.on("end", () => {
|
|
51
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
52
|
+
// Strip exactly one trailing newline/CR from `echo`-style pipes; keep
|
|
53
|
+
// any other whitespace — the value is preserved verbatim otherwise.
|
|
54
|
+
const value = raw.replace(/\r?\n$/, "");
|
|
55
|
+
resolve(value);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function fail(err) {
|
|
60
|
+
if (err instanceof SecretNameError ||
|
|
61
|
+
err instanceof SecretValueError ||
|
|
62
|
+
err instanceof SecretStoreCorruptError) {
|
|
63
|
+
process.stderr.write(pc.red(`${err.message}\n`));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
process.stderr.write(pc.red(`Secret operation failed: ${err instanceof Error ? err.message : String(err)}\n`));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
export async function runSecret(args) {
|
|
70
|
+
const sub = args[0];
|
|
71
|
+
if (sub === "set") {
|
|
72
|
+
const nameArg = args[1];
|
|
73
|
+
if (!nameArg || nameArg.trim() === "") {
|
|
74
|
+
process.stderr.write(pc.red('Usage: spectral secret set NAME (value is read from STDIN, e.g. `echo -n "value" | spectral secret set NAME`)\n'));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
let value;
|
|
78
|
+
try {
|
|
79
|
+
value = await readValueFromStdin(nameArg.trim());
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
fail(err);
|
|
83
|
+
}
|
|
84
|
+
if (value.length === 0) {
|
|
85
|
+
process.stderr.write(pc.red("Secret value is empty — pipe a non-empty value on STDIN, e.g. `echo -n \"value\" | spectral secret set NAME`\n"));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const meta = setSecret(nameArg.trim(), value);
|
|
90
|
+
process.stdout.write(pc.green(`✓ Secret ${meta.name} stored (encrypted at rest, injected as env var into the agent bash tool)\n`));
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
fail(err);
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (sub === "list") {
|
|
98
|
+
try {
|
|
99
|
+
const secrets = listSecrets();
|
|
100
|
+
if (secrets.length === 0) {
|
|
101
|
+
process.stdout.write("No secrets stored.\n");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const nameW = Math.max(5, ...secrets.map((s) => s.name.length));
|
|
105
|
+
process.stdout.write([
|
|
106
|
+
`${secrets.length} stored secret(s) (values are never shown):`,
|
|
107
|
+
"",
|
|
108
|
+
`${"NAME".padEnd(nameW)} Created Updated`,
|
|
109
|
+
`${"─".repeat(nameW)} ${"─".repeat(19)} ${"─".repeat(19)}`,
|
|
110
|
+
...secrets.map((s) => `${s.name.padEnd(nameW)} ${s.createdAt.padEnd(19)} ${s.updatedAt}`),
|
|
111
|
+
].join("\n") + "\n");
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
fail(err);
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (sub === "rm") {
|
|
119
|
+
const nameArg = args[1];
|
|
120
|
+
if (!nameArg || nameArg.trim() === "") {
|
|
121
|
+
process.stderr.write(pc.red("Usage: spectral secret rm NAME\n"));
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const deleted = deleteSecret(nameArg.trim());
|
|
126
|
+
if (!deleted) {
|
|
127
|
+
process.stderr.write(pc.red(`Secret ${nameArg.trim().toUpperCase()} not found\n`));
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
process.stdout.write(pc.green(`✓ Secret ${nameArg.trim().toUpperCase()} removed\n`));
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
fail(err);
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (sub === "--help" || sub === "-h") {
|
|
138
|
+
process.stdout.write([
|
|
139
|
+
"Usage:",
|
|
140
|
+
" spectral secret set NAME create/update a secret (value read from STDIN, never argv)",
|
|
141
|
+
" spectral secret list list names + timestamps (values are never shown)",
|
|
142
|
+
" spectral secret rm NAME delete a secret",
|
|
143
|
+
"",
|
|
144
|
+
"Stored secrets are encrypted at rest (AES-256-GCM) and injected as env vars",
|
|
145
|
+
"into the agent's bash tool. Manage them remotely via the /api/secrets API.",
|
|
146
|
+
"",
|
|
147
|
+
].join("\n"));
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}
|
|
150
|
+
process.stderr.write(pc.red(`Unknown secret subcommand: ${sub ?? ""}\n`) +
|
|
151
|
+
pc.dim("Use `spectral secret --help` for usage.\n"));
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAwBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAwBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAgBlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAsBrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC9E;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAurBlF;AAmFD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAsB5E"}
|
package/dist/commands/serve.js
CHANGED
|
@@ -43,6 +43,8 @@ import { getFanoutManager } from "../server/fanout/fanout-manager.js";
|
|
|
43
43
|
import { detachAllSubscribers, handleAutoOptimizeFrame, handleAutoResearchFrame, handleCancelTurn, handleClientMessage, handleRestRequest, handleStopToolCall, handleSubscribe, } from "../relay/dispatcher.js";
|
|
44
44
|
import { ensureMachineRegistered } from "../relay/registration.js";
|
|
45
45
|
import { saveMachine } from "../relay/machine-store.js";
|
|
46
|
+
import { sweepAttachments } from "../server/attachments/cleanup.js";
|
|
47
|
+
import { attachmentsRootFor } from "../server/attachments/persist.js";
|
|
46
48
|
import { SessionStreamManager } from "../server/session-stream.js";
|
|
47
49
|
import { gracefulShutdown } from "../server/shutdown.js";
|
|
48
50
|
import { getLiveMcpState } from "../mcp/state-getter.js";
|
|
@@ -175,6 +177,25 @@ export async function runServe(opts = {}) {
|
|
|
175
177
|
// Best-effort.
|
|
176
178
|
}
|
|
177
179
|
});
|
|
180
|
+
// GC for stale persisted chat attachments (`.spectral/attachments/<id>/`).
|
|
181
|
+
// Fire-and-forget like the offload sweep: never blocks server startup and
|
|
182
|
+
// never takes down serving. Sweeps every known project root (attachments
|
|
183
|
+
// live under the session's project cwd) plus the fallback cwd.
|
|
184
|
+
setImmediate(() => {
|
|
185
|
+
try {
|
|
186
|
+
const activeSessionIds = new Set(store.listAllSessionIds());
|
|
187
|
+
const roots = new Set([attachmentsRootFor(cwd)]);
|
|
188
|
+
for (const project of store.listProjects()) {
|
|
189
|
+
roots.add(attachmentsRootFor(project.path));
|
|
190
|
+
}
|
|
191
|
+
for (const root of roots) {
|
|
192
|
+
sweepAttachments({ root, activeSessionIds });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Best-effort.
|
|
197
|
+
}
|
|
198
|
+
});
|
|
178
199
|
// Mutable holder for the meta-event publisher. Bound below once we
|
|
179
200
|
// have both `relay` (the send target) and `registration.record.machineId`
|
|
180
201
|
// (the canonical machineId the backend uses to fan out). The manager
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `list_secrets` tool extension.
|
|
3
|
+
*
|
|
4
|
+
* Lets the agent see which local secrets are stored (names + timestamps) so it
|
|
5
|
+
* can reason about what env vars will be injected into its bash tool.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: this tool returns ONLY names and timestamps. Secret values are
|
|
8
|
+
* never returned by this tool, by the relay GET API, or by anything else —
|
|
9
|
+
* values exist solely as env vars injected into the agent's bash environment
|
|
10
|
+
* (see src/secrets/store.ts `getSecretEnvVars`).
|
|
11
|
+
*/
|
|
12
|
+
import type { ExtensionAPI } from "../sdk/coding-agent/index.js";
|
|
13
|
+
export default function listSecretsExtension(ext: ExtensionAPI): void;
|
|
14
|
+
//# sourceMappingURL=list-secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-secrets.d.ts","sourceRoot":"","sources":["../../src/extensions/list-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,8BAA8B,CAAC;AAGnF,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA4DpE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `list_secrets` tool extension.
|
|
3
|
+
*
|
|
4
|
+
* Lets the agent see which local secrets are stored (names + timestamps) so it
|
|
5
|
+
* can reason about what env vars will be injected into its bash tool.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: this tool returns ONLY names and timestamps. Secret values are
|
|
8
|
+
* never returned by this tool, by the relay GET API, or by anything else —
|
|
9
|
+
* values exist solely as env vars injected into the agent's bash environment
|
|
10
|
+
* (see src/secrets/store.ts `getSecretEnvVars`).
|
|
11
|
+
*/
|
|
12
|
+
import { getSecretEnvVars, listSecrets } from "../secrets/index.js";
|
|
13
|
+
export default function listSecretsExtension(ext) {
|
|
14
|
+
ext.registerTool({
|
|
15
|
+
name: "list_secrets",
|
|
16
|
+
label: "List Secrets",
|
|
17
|
+
description: "List the locally stored secret env vars that will be injected into your bash tool environment " +
|
|
18
|
+
"(e.g. GITHUB_TOKEN). Returns ONLY names and timestamps — secret values are never returned by " +
|
|
19
|
+
"this tool or any other; they exist solely as environment variables in your bash sessions. " +
|
|
20
|
+
"Manage secrets with the `spectral secret` CLI command or the /api/secrets relay API.",
|
|
21
|
+
parameters: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {},
|
|
24
|
+
},
|
|
25
|
+
async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
|
|
26
|
+
try {
|
|
27
|
+
const secrets = listSecrets();
|
|
28
|
+
if (secrets.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: "No secrets stored. Add one with `spectral secret set NAME` (value read from STDIN) " +
|
|
34
|
+
"or POST /api/secrets. Stored secrets are injected as env vars into your bash tool.",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
details: { isError: false },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const envNames = Object.keys(getSecretEnvVars());
|
|
41
|
+
const lines = [
|
|
42
|
+
`${secrets.length} stored secret(s) (values are never returned — they are injected as env vars):`,
|
|
43
|
+
"",
|
|
44
|
+
...secrets.map((s) => ` ${s.name} created ${s.createdAt} updated ${s.updatedAt}` +
|
|
45
|
+
(envNames.includes(s.name) ? "" : " (not injected: reserved name)")),
|
|
46
|
+
"",
|
|
47
|
+
"These are available as environment variables in your bash tool sessions.",
|
|
48
|
+
];
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
51
|
+
details: { isError: false },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
+
return {
|
|
57
|
+
content: [{ type: "text", text: `Error reading secrets: ${msg}` }],
|
|
58
|
+
details: { isError: true },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/generated/zeus/const.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CAy0B5C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/generated/zeus/const.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CAy0B5C,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAC,GAAG,CAqpC1C,CAAA;AAED,eAAO,MAAM,GAAG;;;;CAIf,CAAA"}
|
|
@@ -1018,6 +1018,7 @@ export const ReturnTypes = {
|
|
|
1018
1018
|
subscriptionCompatibleModels: "UserModel",
|
|
1019
1019
|
baseModelCatalog: "CatalogModel",
|
|
1020
1020
|
availableModels: "AvailableModel",
|
|
1021
|
+
publicModelCatalog: "BuiltInModelCatalogEntry",
|
|
1021
1022
|
availablePlans: "PlanInfo",
|
|
1022
1023
|
availableCreditPacks: "CreditPack",
|
|
1023
1024
|
teamSubscription: "BillingSubscription",
|
|
@@ -1524,6 +1525,20 @@ export const ReturnTypes = {
|
|
|
1524
1525
|
supportsImages: "Boolean",
|
|
1525
1526
|
supportsReasoning: "Boolean"
|
|
1526
1527
|
},
|
|
1528
|
+
BuiltInModelCatalogEntry: {
|
|
1529
|
+
slug: "String",
|
|
1530
|
+
name: "String",
|
|
1531
|
+
baseModel: "String",
|
|
1532
|
+
contextWindow: "Int",
|
|
1533
|
+
creditInputPer1M: "Int",
|
|
1534
|
+
creditOutputPer1M: "Int",
|
|
1535
|
+
visibleInStudio: "Boolean",
|
|
1536
|
+
agentEnabled: "Boolean",
|
|
1537
|
+
lastRequestAt: "DateTime",
|
|
1538
|
+
avgTps: "Float",
|
|
1539
|
+
fallbackTps: "Float",
|
|
1540
|
+
requestCount30d: "Int"
|
|
1541
|
+
},
|
|
1527
1542
|
AvailableModel: {
|
|
1528
1543
|
name: "String",
|
|
1529
1544
|
provider: "String",
|
|
@@ -1561,6 +1576,7 @@ export const ReturnTypes = {
|
|
|
1561
1576
|
creditCacheWritePer1M: "Int",
|
|
1562
1577
|
creditPerImage: "Float",
|
|
1563
1578
|
creditPerVideoSecond: "Float",
|
|
1579
|
+
fallbackTps: "Float",
|
|
1564
1580
|
capabilities: "JSON",
|
|
1565
1581
|
family: "String",
|
|
1566
1582
|
enabled: "Boolean",
|
|
@@ -1246,6 +1246,7 @@ export type ValueTypes = {
|
|
|
1246
1246
|
scope?: ValueTypes["ModelScope"] | undefined | null | Variable<any, string>;
|
|
1247
1247
|
teamId?: ValueTypes["ID"] | undefined | null | Variable<any, string>;
|
|
1248
1248
|
}, ValueTypes["AvailableModel"]];
|
|
1249
|
+
publicModelCatalog?: ValueTypes["BuiltInModelCatalogEntry"];
|
|
1249
1250
|
availablePlans?: ValueTypes["PlanInfo"];
|
|
1250
1251
|
availableCreditPacks?: ValueTypes["CreditPack"];
|
|
1251
1252
|
teamSubscription?: [{
|
|
@@ -2460,6 +2461,22 @@ export type ValueTypes = {
|
|
|
2460
2461
|
__typename?: boolean | `@${string}`;
|
|
2461
2462
|
['...on CatalogModel']?: Omit<ValueTypes["CatalogModel"], "...on CatalogModel">;
|
|
2462
2463
|
}>;
|
|
2464
|
+
["BuiltInModelCatalogEntry"]: AliasType<{
|
|
2465
|
+
slug?: boolean | `@${string}`;
|
|
2466
|
+
name?: boolean | `@${string}`;
|
|
2467
|
+
baseModel?: boolean | `@${string}`;
|
|
2468
|
+
contextWindow?: boolean | `@${string}`;
|
|
2469
|
+
creditInputPer1M?: boolean | `@${string}`;
|
|
2470
|
+
creditOutputPer1M?: boolean | `@${string}`;
|
|
2471
|
+
visibleInStudio?: boolean | `@${string}`;
|
|
2472
|
+
agentEnabled?: boolean | `@${string}`;
|
|
2473
|
+
lastRequestAt?: boolean | `@${string}`;
|
|
2474
|
+
avgTps?: boolean | `@${string}`;
|
|
2475
|
+
fallbackTps?: boolean | `@${string}`;
|
|
2476
|
+
requestCount30d?: boolean | `@${string}`;
|
|
2477
|
+
__typename?: boolean | `@${string}`;
|
|
2478
|
+
['...on BuiltInModelCatalogEntry']?: Omit<ValueTypes["BuiltInModelCatalogEntry"], "...on BuiltInModelCatalogEntry">;
|
|
2479
|
+
}>;
|
|
2463
2480
|
["AvailableModel"]: AliasType<{
|
|
2464
2481
|
name?: boolean | `@${string}`;
|
|
2465
2482
|
provider?: boolean | `@${string}`;
|
|
@@ -2499,6 +2516,7 @@ export type ValueTypes = {
|
|
|
2499
2516
|
creditCacheWritePer1M?: boolean | `@${string}`;
|
|
2500
2517
|
creditPerImage?: boolean | `@${string}`;
|
|
2501
2518
|
creditPerVideoSecond?: boolean | `@${string}`;
|
|
2519
|
+
fallbackTps?: boolean | `@${string}`;
|
|
2502
2520
|
capabilities?: boolean | `@${string}`;
|
|
2503
2521
|
family?: boolean | `@${string}`;
|
|
2504
2522
|
enabled?: boolean | `@${string}`;
|
|
@@ -2534,6 +2552,7 @@ export type ValueTypes = {
|
|
|
2534
2552
|
creditCacheWritePer1M?: number | undefined | null | Variable<any, string>;
|
|
2535
2553
|
creditPerImage?: number | undefined | null | Variable<any, string>;
|
|
2536
2554
|
creditPerVideoSecond?: number | undefined | null | Variable<any, string>;
|
|
2555
|
+
fallbackTps?: number | undefined | null | Variable<any, string>;
|
|
2537
2556
|
family?: string | undefined | null | Variable<any, string>;
|
|
2538
2557
|
isDefault?: boolean | undefined | null | Variable<any, string>;
|
|
2539
2558
|
isVisionDefault?: boolean | undefined | null | Variable<any, string>;
|
|
@@ -3597,6 +3616,7 @@ export type ResolverInputTypes = {
|
|
|
3597
3616
|
scope?: ResolverInputTypes["ModelScope"] | undefined | null;
|
|
3598
3617
|
teamId?: ResolverInputTypes["ID"] | undefined | null;
|
|
3599
3618
|
}, ResolverInputTypes["AvailableModel"]];
|
|
3619
|
+
publicModelCatalog?: ResolverInputTypes["BuiltInModelCatalogEntry"];
|
|
3600
3620
|
availablePlans?: ResolverInputTypes["PlanInfo"];
|
|
3601
3621
|
availableCreditPacks?: ResolverInputTypes["CreditPack"];
|
|
3602
3622
|
teamSubscription?: [{
|
|
@@ -4783,6 +4803,21 @@ export type ResolverInputTypes = {
|
|
|
4783
4803
|
supportsReasoning?: boolean | `@${string}`;
|
|
4784
4804
|
__typename?: boolean | `@${string}`;
|
|
4785
4805
|
}>;
|
|
4806
|
+
["BuiltInModelCatalogEntry"]: AliasType<{
|
|
4807
|
+
slug?: boolean | `@${string}`;
|
|
4808
|
+
name?: boolean | `@${string}`;
|
|
4809
|
+
baseModel?: boolean | `@${string}`;
|
|
4810
|
+
contextWindow?: boolean | `@${string}`;
|
|
4811
|
+
creditInputPer1M?: boolean | `@${string}`;
|
|
4812
|
+
creditOutputPer1M?: boolean | `@${string}`;
|
|
4813
|
+
visibleInStudio?: boolean | `@${string}`;
|
|
4814
|
+
agentEnabled?: boolean | `@${string}`;
|
|
4815
|
+
lastRequestAt?: boolean | `@${string}`;
|
|
4816
|
+
avgTps?: boolean | `@${string}`;
|
|
4817
|
+
fallbackTps?: boolean | `@${string}`;
|
|
4818
|
+
requestCount30d?: boolean | `@${string}`;
|
|
4819
|
+
__typename?: boolean | `@${string}`;
|
|
4820
|
+
}>;
|
|
4786
4821
|
["AvailableModel"]: AliasType<{
|
|
4787
4822
|
name?: boolean | `@${string}`;
|
|
4788
4823
|
provider?: boolean | `@${string}`;
|
|
@@ -4821,6 +4856,7 @@ export type ResolverInputTypes = {
|
|
|
4821
4856
|
creditCacheWritePer1M?: boolean | `@${string}`;
|
|
4822
4857
|
creditPerImage?: boolean | `@${string}`;
|
|
4823
4858
|
creditPerVideoSecond?: boolean | `@${string}`;
|
|
4859
|
+
fallbackTps?: boolean | `@${string}`;
|
|
4824
4860
|
capabilities?: boolean | `@${string}`;
|
|
4825
4861
|
family?: boolean | `@${string}`;
|
|
4826
4862
|
enabled?: boolean | `@${string}`;
|
|
@@ -4854,6 +4890,7 @@ export type ResolverInputTypes = {
|
|
|
4854
4890
|
creditCacheWritePer1M?: number | undefined | null;
|
|
4855
4891
|
creditPerImage?: number | undefined | null;
|
|
4856
4892
|
creditPerVideoSecond?: number | undefined | null;
|
|
4893
|
+
fallbackTps?: number | undefined | null;
|
|
4857
4894
|
family?: string | undefined | null;
|
|
4858
4895
|
isDefault?: boolean | undefined | null;
|
|
4859
4896
|
isVisionDefault?: boolean | undefined | null;
|
|
@@ -5774,6 +5811,7 @@ export type ModelTypes = {
|
|
|
5774
5811
|
subscriptionCompatibleModels: Array<ModelTypes["UserModel"]>;
|
|
5775
5812
|
baseModelCatalog: Array<ModelTypes["CatalogModel"]>;
|
|
5776
5813
|
availableModels: Array<ModelTypes["AvailableModel"]>;
|
|
5814
|
+
publicModelCatalog: Array<ModelTypes["BuiltInModelCatalogEntry"]>;
|
|
5777
5815
|
availablePlans: Array<ModelTypes["PlanInfo"]>;
|
|
5778
5816
|
availableCreditPacks: Array<ModelTypes["CreditPack"]>;
|
|
5779
5817
|
teamSubscription?: ModelTypes["BillingSubscription"] | undefined | null;
|
|
@@ -6432,6 +6470,20 @@ export type ModelTypes = {
|
|
|
6432
6470
|
supportsImages?: boolean | undefined | null;
|
|
6433
6471
|
supportsReasoning?: boolean | undefined | null;
|
|
6434
6472
|
};
|
|
6473
|
+
["BuiltInModelCatalogEntry"]: {
|
|
6474
|
+
slug: string;
|
|
6475
|
+
name: string;
|
|
6476
|
+
baseModel: string;
|
|
6477
|
+
contextWindow?: number | undefined | null;
|
|
6478
|
+
creditInputPer1M?: number | undefined | null;
|
|
6479
|
+
creditOutputPer1M?: number | undefined | null;
|
|
6480
|
+
visibleInStudio: boolean;
|
|
6481
|
+
agentEnabled: boolean;
|
|
6482
|
+
lastRequestAt?: ModelTypes["DateTime"] | undefined | null;
|
|
6483
|
+
avgTps?: number | undefined | null;
|
|
6484
|
+
fallbackTps?: number | undefined | null;
|
|
6485
|
+
requestCount30d: number;
|
|
6486
|
+
};
|
|
6435
6487
|
["AvailableModel"]: {
|
|
6436
6488
|
name: string;
|
|
6437
6489
|
provider: string;
|
|
@@ -6469,6 +6521,7 @@ export type ModelTypes = {
|
|
|
6469
6521
|
creditCacheWritePer1M?: number | undefined | null;
|
|
6470
6522
|
creditPerImage?: number | undefined | null;
|
|
6471
6523
|
creditPerVideoSecond?: number | undefined | null;
|
|
6524
|
+
fallbackTps?: number | undefined | null;
|
|
6472
6525
|
capabilities?: ModelTypes["JSON"] | undefined | null;
|
|
6473
6526
|
family?: string | undefined | null;
|
|
6474
6527
|
enabled: boolean;
|
|
@@ -6500,6 +6553,7 @@ export type ModelTypes = {
|
|
|
6500
6553
|
creditCacheWritePer1M?: number | undefined | null;
|
|
6501
6554
|
creditPerImage?: number | undefined | null;
|
|
6502
6555
|
creditPerVideoSecond?: number | undefined | null;
|
|
6556
|
+
fallbackTps?: number | undefined | null;
|
|
6503
6557
|
family?: string | undefined | null;
|
|
6504
6558
|
isDefault?: boolean | undefined | null;
|
|
6505
6559
|
isVisionDefault?: boolean | undefined | null;
|
|
@@ -7518,6 +7572,7 @@ export type GraphQLTypes = {
|
|
|
7518
7572
|
subscriptionCompatibleModels: Array<GraphQLTypes["UserModel"]>;
|
|
7519
7573
|
baseModelCatalog: Array<GraphQLTypes["CatalogModel"]>;
|
|
7520
7574
|
availableModels: Array<GraphQLTypes["AvailableModel"]>;
|
|
7575
|
+
publicModelCatalog: Array<GraphQLTypes["BuiltInModelCatalogEntry"]>;
|
|
7521
7576
|
availablePlans: Array<GraphQLTypes["PlanInfo"]>;
|
|
7522
7577
|
availableCreditPacks: Array<GraphQLTypes["CreditPack"]>;
|
|
7523
7578
|
teamSubscription?: GraphQLTypes["BillingSubscription"] | undefined | null;
|
|
@@ -8237,6 +8292,22 @@ export type GraphQLTypes = {
|
|
|
8237
8292
|
supportsReasoning?: boolean | undefined | null;
|
|
8238
8293
|
['...on CatalogModel']: Omit<GraphQLTypes["CatalogModel"], "...on CatalogModel">;
|
|
8239
8294
|
};
|
|
8295
|
+
["BuiltInModelCatalogEntry"]: {
|
|
8296
|
+
__typename: "BuiltInModelCatalogEntry";
|
|
8297
|
+
slug: string;
|
|
8298
|
+
name: string;
|
|
8299
|
+
baseModel: string;
|
|
8300
|
+
contextWindow?: number | undefined | null;
|
|
8301
|
+
creditInputPer1M?: number | undefined | null;
|
|
8302
|
+
creditOutputPer1M?: number | undefined | null;
|
|
8303
|
+
visibleInStudio: boolean;
|
|
8304
|
+
agentEnabled: boolean;
|
|
8305
|
+
lastRequestAt?: GraphQLTypes["DateTime"] | undefined | null;
|
|
8306
|
+
avgTps?: number | undefined | null;
|
|
8307
|
+
fallbackTps?: number | undefined | null;
|
|
8308
|
+
requestCount30d: number;
|
|
8309
|
+
['...on BuiltInModelCatalogEntry']: Omit<GraphQLTypes["BuiltInModelCatalogEntry"], "...on BuiltInModelCatalogEntry">;
|
|
8310
|
+
};
|
|
8240
8311
|
["AvailableModel"]: {
|
|
8241
8312
|
__typename: "AvailableModel";
|
|
8242
8313
|
name: string;
|
|
@@ -8277,6 +8348,7 @@ export type GraphQLTypes = {
|
|
|
8277
8348
|
creditCacheWritePer1M?: number | undefined | null;
|
|
8278
8349
|
creditPerImage?: number | undefined | null;
|
|
8279
8350
|
creditPerVideoSecond?: number | undefined | null;
|
|
8351
|
+
fallbackTps?: number | undefined | null;
|
|
8280
8352
|
capabilities?: GraphQLTypes["JSON"] | undefined | null;
|
|
8281
8353
|
family?: string | undefined | null;
|
|
8282
8354
|
enabled: boolean;
|
|
@@ -8311,6 +8383,7 @@ export type GraphQLTypes = {
|
|
|
8311
8383
|
creditCacheWritePer1M?: number | undefined | null;
|
|
8312
8384
|
creditPerImage?: number | undefined | null;
|
|
8313
8385
|
creditPerVideoSecond?: number | undefined | null;
|
|
8386
|
+
fallbackTps?: number | undefined | null;
|
|
8314
8387
|
family?: string | undefined | null;
|
|
8315
8388
|
isDefault?: boolean | undefined | null;
|
|
8316
8389
|
isVisionDefault?: boolean | undefined | null;
|