Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:36:17.764Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

vscode_debug_format.rs

195 lines · 6.4 KB · rust
1use collections::HashMap;
2use serde::Deserialize;
3use util::ResultExt as _;
4
5use crate::{
6    DebugScenario, DebugTaskFile, EnvVariableReplacer, TcpArgumentsTemplate, VariableName,
7};
8
9// TODO support preLaunchTask linkage with other tasks
10#[derive(Clone, Debug, Deserialize, PartialEq)]
11#[serde(rename_all = "camelCase")]
12struct VsCodeDebugTaskDefinition {
13    r#type: String,
14    name: String,
15    #[serde(default)]
16    port: Option<u16>,
17    #[serde(flatten)]
18    other_attributes: serde_json::Value,
19}
20
21impl VsCodeDebugTaskDefinition {
22    fn try_to_zed(mut self, replacer: &EnvVariableReplacer) -> anyhow::Result<DebugScenario> {
23        let label = replacer.replace(&self.name);
24        let mut config = replacer.replace_value(self.other_attributes);
25        let adapter = task_type_to_adapter_name(&self.r#type);
26        if let Some(config) = config.as_object_mut()
27            && adapter == "JavaScript"
28        {
29            config.insert("type".to_owned(), self.r#type.clone().into());
30            if let Some(port) = self.port.take() {
31                config.insert("port".to_owned(), port.into());
32            }
33        }
34        let definition = DebugScenario {
35            label: label.into(),
36            build: None,
37            adapter: adapter.into(),
38            tcp_connection: self.port.map(|port| TcpArgumentsTemplate {
39                port: Some(port),
40                host: None,
41                timeout: None,
42            }),
43            config,
44        };
45        Ok(definition)
46    }
47}
48
49#[derive(Clone, Debug, Deserialize, PartialEq)]
50#[serde(rename_all = "camelCase")]
51pub struct VsCodeDebugTaskFile {
52    #[serde(default)]
53    version: Option<String>,
54    configurations: Vec<VsCodeDebugTaskDefinition>,
55}
56
57impl TryFrom<VsCodeDebugTaskFile> for DebugTaskFile {
58    type Error = anyhow::Error;
59
60    fn try_from(file: VsCodeDebugTaskFile) -> Result<Self, Self::Error> {
61        let replacer = EnvVariableReplacer::new(HashMap::from_iter([
62            (
63                "workspaceFolder".to_owned(),
64                VariableName::WorktreeRoot.to_string(),
65            ),
66            (
67                "relativeFile".to_owned(),
68                VariableName::RelativeFile.to_string(),
69            ),
70            ("file".to_owned(), VariableName::File.to_string()),
71        ]))
72        .with_commands([(
73            "pickMyProcess".to_owned(),
74            VariableName::PickProcessId.to_string(),
75        )]);
76        let templates = file
77            .configurations
78            .into_iter()
79            .filter_map(|config| config.try_to_zed(&replacer).log_err())
80            .collect::<Vec<_>>();
81        Ok(DebugTaskFile(templates))
82    }
83}
84
85fn task_type_to_adapter_name(task_type: &str) -> String {
86    match task_type {
87        "pwa-node" | "node" | "node-terminal" | "chrome" | "pwa-chrome" | "edge" | "pwa-edge"
88        | "msedge" | "pwa-msedge" => "JavaScript",
89        "go" => "Delve",
90        "php" => "Xdebug",
91        "cppdbg" | "lldb" => "CodeLLDB",
92        "debugpy" => "Debugpy",
93        "rdbg" => "rdbg",
94        _ => task_type,
95    }
96    .to_owned()
97}
98
99#[cfg(test)]
100mod tests {
101    use serde_json::json;
102
103    use crate::{DebugScenario, DebugTaskFile, VariableName};
104
105    use super::VsCodeDebugTaskFile;
106
107    #[test]
108    fn test_parsing_vscode_launch_json() {
109        let raw = r#"
110            {
111                "version": "0.2.0",
112                "configurations": [
113                    {
114                        "name": "Debug my JS app",
115                        "request": "launch",
116                        "type": "node",
117                        "program": "${workspaceFolder}/xyz.js",
118                        "showDevDebugOutput": false,
119                        "stopOnEntry": true,
120                        "args": ["--foo", "${workspaceFolder}/thing"],
121                        "cwd": "${workspaceFolder}/${env:FOO}/sub",
122                        "env": {
123                            "X": "Y"
124                        },
125                        "port": 17
126                    },
127                ]
128            }
129        "#;
130        let parsed: VsCodeDebugTaskFile =
131            serde_json_lenient::from_str(raw).expect("deserializing launch.json");
132        let zed = DebugTaskFile::try_from(parsed).expect("converting to Zed debug templates");
133        pretty_assertions::assert_eq!(
134            zed,
135            DebugTaskFile(vec![DebugScenario {
136                label: "Debug my JS app".into(),
137                adapter: "JavaScript".into(),
138                config: json!({
139                    "request": "launch",
140                    "program": "${ZED_WORKTREE_ROOT}/xyz.js",
141                    "showDevDebugOutput": false,
142                    "stopOnEntry": true,
143                    "args": [
144                        "--foo",
145                        "${ZED_WORKTREE_ROOT}/thing",
146                    ],
147                    "cwd": "${ZED_WORKTREE_ROOT}/${FOO}/sub",
148                    "env": {
149                        "X": "Y",
150                    },
151                    "type": "node",
152                    "port": 17,
153                }),
154                tcp_connection: None,
155                build: None
156            }])
157        );
158    }
159
160    #[test]
161    fn test_command_pickmyprocess_replacement() {
162        let raw = r#"
163            {
164                "version": "0.2.0",
165                "configurations": [
166                    {
167                        "name": "Attach to Process",
168                        "request": "attach",
169                        "type": "cppdbg",
170                        "processId": "${command:pickMyProcess}"
171                    }
172                ]
173            }
174        "#;
175        let parsed: VsCodeDebugTaskFile =
176            serde_json_lenient::from_str(raw).expect("deserializing launch.json");
177        let zed = DebugTaskFile::try_from(parsed).expect("converting to Zed debug templates");
178
179        let expected_placeholder = format!("${{{}}}", VariableName::PickProcessId);
180        pretty_assertions::assert_eq!(
181            zed,
182            DebugTaskFile(vec![DebugScenario {
183                label: "Attach to Process".into(),
184                adapter: "CodeLLDB".into(),
185                config: json!({
186                    "request": "attach",
187                    "processId": expected_placeholder,
188                }),
189                tcp_connection: None,
190                build: None
191            }])
192        );
193    }
194}
195
Served at tenant.openagents/omega Member data and write actions are omitted.