async fn completion(&self, _: CompletionParams) -> LspResult<Option<CompletionResponse>> {
        let packages = self
            .package_discovery()
            .await
            .map_err(|_e| Error::internal_error())?;

        let package_jsons = packages
            .workspaces
            .into_iter()
            .flat_map(|wd| PackageJson::load(&wd.package_json).ok()) // if we can't parse a package.json, then we can't infer its tasks
            .collect::<Vec<_>>();

        let tasks = package_jsons
            .iter()
            .flat_map(|p| p.scripts.keys())
            .unique()
            .map(|s| CompletionItem {
                label: s.to_owned(),
                kind: Some(CompletionItemKind::FIELD),
                ..Default::default()
            });

        let keys = package_jsons
            .iter()
            .flat_map(|p| p.scripts.keys().map(move |k| (p.name.clone(), k)))
            .map(|(package, s)| CompletionItem {
                label: format!("{}#{}", package.unwrap_or_default().into_inner(), s),
                kind: Some(CompletionItemKind::FIELD),
                ..Default::default()
            });

        Ok(Some(CompletionResponse::Array(keys.chain(tasks).collect())))
    }
Provide intellisense completions for package / task names

- get all packages
- get all package jsons
- produce all unique script names
- flatmap producing all package#script combos
- chain them
crates/turborepo-lsp/src/lib.rs