forge_primitives/options.rs
1//! Pure-data option enums shared across forge-* crates.
2//!
3//! `Options` itself stays in forge-sdk because it carries callback
4//! `Arc<dyn …>` fields - but every wire-shape enum it embeds is data
5//! that the agent + UI also need to reason about.
6
7use serde::{Deserialize, Serialize};
8
9pub use crate::permission::PermissionMode;
10
11/// System-prompt configuration. Wraps the CLI's discriminated union of
12/// `str | SystemPromptPreset | SystemPromptFile`.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum SystemPromptKind {
15 /// Plain string override - `--system-prompt <text>`.
16 Inline(String),
17 /// Preset (currently only `claude_code`) with optional append + the
18 /// `exclude_dynamic_sections` signal that rides along inside the
19 /// `initialize` `control_request` instead of argv.
20 Preset {
21 /// Optional append text that lands on argv as
22 /// `--append-system-prompt <text>`.
23 append: Option<String>,
24 /// When `Some`, sent in the `initialize` body as
25 /// `excludeDynamicSections`. `None` omits the field, matching
26 /// the CLI's conditional.
27 exclude_dynamic_sections: Option<bool>,
28 },
29 /// File-backed prompt - `--system-prompt-file <path>`.
30 File(std::path::PathBuf),
31}
32
33impl SystemPromptKind {
34 /// Convenience constructor for the `claude_code` preset with an
35 /// append string. Wire shape:
36 /// `{"type": "preset", "preset": "claude_code", "append": ...}`.
37 pub fn preset_append(append: impl Into<String>) -> Self {
38 Self::Preset { append: Some(append.into()), exclude_dynamic_sections: None }
39 }
40}
41
42/// Plugin config. Wraps the CLI's `SdkPluginConfig`
43/// (`{"type": "local", "path": str}`).
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45#[serde(tag = "type", rename_all = "lowercase")]
46pub enum SdkPluginConfig {
47 /// Local filesystem plugin - emits `--plugin-dir <path>`.
48 Local {
49 /// Plugin directory path.
50 path: std::path::PathBuf,
51 },
52}