keystone-cli 2.0.0 → 2.0.1

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 CHANGED
@@ -237,6 +237,10 @@ storage:
237
237
 
238
238
  expression:
239
239
  strict: false
240
+
241
+ logging:
242
+ suppress_security_warning: false
243
+ suppress_ai_sdk_warnings: false
240
244
  ```
241
245
 
242
246
  ### Storage Configuration
@@ -246,6 +250,13 @@ The `storage` section controls data retention and security for workflow runs:
246
250
  - **`retention_days`**: Sets the default window used by `keystone maintenance` / `keystone prune` commands to clean up old run data.
247
251
  - **`redact_secrets_at_rest`**: Controls whether secret inputs and known secrets are redacted before storing run data (default `true`).
248
252
 
253
+ ### Logging Configuration
254
+
255
+ The `logging` section allows you to suppress warnings:
256
+
257
+ - **`suppress_security_warning`**: Silences the "Security Warning" about running workflows from untrusted sources (default `false`).
258
+ - **`suppress_ai_sdk_warnings`**: Silences internal warnings from the Vercel AI SDK, such as compatibility mode messages (default `false`).
259
+
249
260
  ### Bring Your Own Provider (BYOP)
250
261
 
251
262
  Keystone uses the **Vercel AI SDK**, allowing you to use any compatible provider. You must install the provider package (e.g., `@ai-sdk/openai`, `ai-sdk-provider-gemini-cli`) so Keystone can resolve it.
@@ -1246,6 +1257,8 @@ Request steps enforce SSRF protections and require HTTPS by default. Cross-origi
1246
1257
  graph TD
1247
1258
  CLI[CLI Entry Point] --> WR[WorkflowRunner]
1248
1259
  CLI --> MCPServer[MCP Server]
1260
+ Config[ConfigLoader] --> WR
1261
+ Config --> Adapter
1249
1262
 
1250
1263
  subgraph "Core Orchestration"
1251
1264
  WR --> Scheduler[WorkflowScheduler]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keystone-cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "A local-first, declarative, agentic workflow orchestrator built on Bun",
5
5
  "type": "module",
6
6
  "bin": {
@@ -116,6 +116,12 @@ export const ConfigSchema = z.object({
116
116
  .optional(),
117
117
  })
118
118
  .optional(),
119
+ logging: z
120
+ .object({
121
+ suppress_security_warning: z.boolean().default(false),
122
+ suppress_ai_sdk_warnings: z.boolean().default(false),
123
+ })
124
+ .default({}),
119
125
  });
120
126
 
121
127
  export type Config = z.infer<typeof ConfigSchema>;
@@ -55,7 +55,7 @@ class LocalEmbeddingModel {
55
55
  return Array.from(output.data) as number[];
56
56
  })
57
57
  );
58
- return { embeddings };
58
+ return { embeddings, warnings: [] };
59
59
  }
60
60
 
61
61
  /**
@@ -298,6 +298,11 @@ async function prepareProvider(
298
298
  }
299
299
 
300
300
  export async function getModel(model: string): Promise<LanguageModel> {
301
+ const configValues = ConfigLoader.load();
302
+ if (configValues.logging?.suppress_ai_sdk_warnings) {
303
+ process.env.AI_SDK_LOG_WARNINGS = 'false';
304
+ }
305
+
301
306
  const { provider, resolvedModel } = await prepareProvider(model);
302
307
 
303
308
  // AI SDK convention: provider(modelId)
@@ -321,6 +326,11 @@ export async function getModel(model: string): Promise<LanguageModel> {
321
326
  }
322
327
 
323
328
  export async function getEmbeddingModel(model: string): Promise<EmbeddingModel> {
329
+ const configValues = ConfigLoader.load();
330
+ if (configValues.logging?.suppress_ai_sdk_warnings) {
331
+ process.env.AI_SDK_LOG_WARNINGS = 'false';
332
+ }
333
+
324
334
  // 1. Check for local fallback
325
335
  if (model === 'local' || model === 'keystone-local') {
326
336
  return new LocalEmbeddingModel();
@@ -46,7 +46,7 @@ class RedactingLogger implements Logger {
46
46
  constructor(
47
47
  private inner: Logger,
48
48
  private redactor: Redactor
49
- ) {}
49
+ ) { }
50
50
 
51
51
  log(msg: string): void {
52
52
  this.inner.log(this.redactor.redact(msg));
@@ -193,7 +193,7 @@ export class WorkflowRunner {
193
193
 
194
194
  if (parentSignal.aborted) {
195
195
  controller.abort();
196
- return { controller, cleanup: () => {} };
196
+ return { controller, cleanup: () => { } };
197
197
  }
198
198
 
199
199
  parentSignal.addEventListener('abort', onAbort, { once: true });
@@ -816,11 +816,11 @@ export class WorkflowRunner {
816
816
  const idempotencyContextForRetry =
817
817
  idempotencyClaimed && scopedIdempotencyKey
818
818
  ? {
819
- rawKey: idempotencyKey || scopedIdempotencyKey,
820
- scopedKey: scopedIdempotencyKey,
821
- ttlSeconds: idempotencyTtlSeconds,
822
- claimed: true,
823
- }
819
+ rawKey: idempotencyKey || scopedIdempotencyKey,
820
+ scopedKey: scopedIdempotencyKey,
821
+ ttlSeconds: idempotencyTtlSeconds,
822
+ claimed: true,
823
+ }
824
824
  : undefined;
825
825
 
826
826
  let stepToExecute = step;
@@ -932,9 +932,9 @@ export class WorkflowRunner {
932
932
  try {
933
933
  const outputForValidation =
934
934
  stepToExecute.type === 'engine' &&
935
- result.output &&
936
- typeof result.output === 'object' &&
937
- 'summary' in result.output
935
+ result.output &&
936
+ typeof result.output === 'object' &&
937
+ 'summary' in result.output
938
938
  ? (result.output as { summary?: unknown }).summary
939
939
  : result.output;
940
940
  this.validator.validateSchema(
@@ -2076,12 +2076,16 @@ Revise the output to address the feedback. Return only the corrected output.`;
2076
2076
 
2077
2077
  this.logger.log(`\n🏛️ ${isResume ? 'Resuming' : 'Running'} workflow: ${this.workflow.name}`);
2078
2078
  this.logger.log(`Run ID: ${this.runId}`);
2079
- this.logger.log(
2080
- '\n⚠️ Security Warning: Only run workflows from trusted sources.\n' +
2079
+
2080
+ const config = ConfigLoader.load();
2081
+ if (!config.logging?.suppress_security_warning) {
2082
+ this.logger.log(
2083
+ '\n⚠️ Security Warning: Only run workflows from trusted sources.\n' +
2081
2084
  ' Workflows can execute arbitrary shell commands and access your environment.\n'
2082
- );
2085
+ );
2086
+ }
2083
2087
 
2084
- this.secretManager.redactAtRest = ConfigLoader.load().storage?.redact_secrets_at_rest ?? true;
2088
+ this.secretManager.redactAtRest = config.storage?.redact_secrets_at_rest ?? true;
2085
2089
 
2086
2090
  // Apply defaults and validate inputs
2087
2091
  const validated = this.validator.applyDefaultsAndValidate();