guish
guish (goo-ish) 是一个动态数据管道 UI,允许用户以可视化方式构建并执行复杂的命令行管道。它为串联各种 Unix 命令和自定义插件提供了直观的界面,使构建和理解数据处理工作流变得更加容易。它还具备可选的 LLM 支持,可通过自然语言界面更新管道。
Motivation
这是一个探索性项目,旨在观察程序化文本输入、自然语言输入和 GUI 输入如何以新颖的方式相互补充。
我从事大量数据科学工作,在命令行、Jupyter notebooks、R Studio、VS Code 以及越来越多的 Claude 和 ChatGPT 之间切换,但它们都有一些令人不满足之处。将 SQL 查询嵌入 R 等其他语言中,会使 SQL 处于次要地位。命令行将每种语言置于同等地位,但对于编辑代码来说是一个相当糟糕的界面。本应用试图弥合这些差距。
对提示的更新会被解析为 AST 并用于更新 GUI。GUI 中的更新会被用于构建 AST 以更新提示。管道中每个命令的输出都显示在输入区域下方的类终端显示中。对于 HTML 输出,渲染结果显示在右侧面板中。
而不是必须将类似以下内容写入行编辑器,有时对于初步方法来说更优=,
pg -d test_database -c 'SELECT * from test_table;' | tsvtocsv | ggplot 'ggplot(df, aes(as.Date(date), value)) +
geom_col(fill = "red") +
labs(x = "date") +
theme_minimal()' | pngcopyhtml
可以写成,
pg | tsvtocsv | ggplot | pngcopyhtml
然后,使用像 Monaco 这样功能完备的代码编辑器,在 GUI 中填写空白处,同时查看流水线中每个步骤的输出。
命令在 shell 进程中按原样执行。应用程序仅用于构建命令管道的工具。
功能
- 命令行管道的可视化表示
- 管道中每个命令执行后的可见输出
- 命令的实时解析
- 支持自定义插件和命令模块
- 来自 CLI 或 GUI 命令模块的双向更新
- 多种输出显示格式:
- 原始文本输出
- 用于结构化数据的 JSON 查看器
- 用于 CSV/TSV 数据的表格视图
- 命令输出的 HTML 渲染
- 基于 Electron 的桌面应用程序,支持跨平台
- 复杂命令的代码编辑器集成(例如,SQL、AWK、R、Python、Ruby、F#)
- 快速执行命令的键盘快捷键(Alt+Enter)
- 通过
.guish配置文件可配置的 shell 和预加载脚本 - 用于管道脚本的文件操作(新建、打开、保存、另存为)
- 用于
cd命令的目录选择 - 管道输出的复制到剪贴板功能
- AI 辅助的命令生成和更新(当配置了 OpenAI API 密钥时)
- 可最小化的命令模块,以更好地管理工作区
- PostgreSQL 模式集成,以改进数据库查询的 AI 辅助
- 改进的错误处理和用户反馈
实时演示
双向管道构建
本第一个演示展示了如何通过同时使用命令的 CLI 和 GUI 接口来构建流水线。这允许在快速构建流水线后,使用图形用户界面进行迭代和修改。
LLM 指令
下一个演示展示了如何利用提供给 LLM 的指令来更新流水线中的命令。这种方法开辟了一个新的程序设计空间,用户提供的输入可以改变代码本身。用户不再受限于软件开发者预先设定的约束和条件,而是能够掌控创建一个完全符合其特定需求的新程序。
截图
这些截图由本项目 ./demo 目录中包含的 shell 脚本生成。
支持的 GUI 命令模块
guish 目前支持以下带有 GUI 模块的标准 UNIX 命令:
- echo
- cat
- grep
- sed
- awk
- sort
- uniq
- wc
- head
- tr
- cut
- tee
- xargs
- paste
- jq
- curl
- node
- python
- ruby
以及这些自定义函数和 shell 脚本:
- pg
- ggplot
- prependcss
- fsharp
此外,对于尚未拥有 GUI 模块的命令,也提供了通用命令支持。
入门
先决条件
- Node.js (v14 或更高版本)
- npm (v6 或更高版本)
安装
-
克隆仓库:
git clone https://github.com/williamcotton/guish.git cd guish -
安装依赖项:
npm install
配置
guish 使用位于 ~/.guish 的配置文件来自定义其行为。如果该文件不存在,guish 将使用默认设置。
要创建或修改配置,请在主目录中创建一个名为 .guish 的文件,内容如下:
{
"shell": "zsh",
"preloadScript": "",
"openaiApiKey": ""
}
shell: 指定用于执行命令的 shell(默认:"zsh")preloadScript: 在执行每条命令之前运行的脚本(默认:"")openaiApiKey: 用于 AI 辅助功能的 OpenAI API 密钥(可选)
例如,如果您希望在每条命令之前加载您自己的自定义函数并使用 AI 助手,您可以设置:
{
"shell": "zsh",
"preloadScript": "source ~/.zshrc",
"openaiApiKey": "your-api-key-here"
}
运行应用程序
要在开发模式下启动应用程序:
npm start
这将启动启用了热重载的 Electron 应用。
用法
- 在屏幕底部的输入区域中输入您的命令管道。
- 管道将被解析,并以一系列模块的形式进行可视化表示。
- 使用提供的 UI 组件或在 CLI 中修改单个命令参数。
- 点击“Execute”按钮或按 Alt+Enter 运行管道。
- 在每个模块下方的类终端显示中查看输出。
- 对于 HTML 输出,请在右侧面板中查看渲染结果。
- 使用 File 菜单或键盘快捷键创建新管道、打开现有管道或保存您的工作。
- 如果启用了 OpenAI 集成,请使用顶部的输入字段获取 AI 辅助的管道更新。
- 通过点击 chevron 图标来最小化模块,以更高效地管理您的工作区。
- 对于 PostgreSQL 查询,AI 助手将自动获取并使用数据库模式以改进建议。
自定义命令
以下自定义命令通过 shell-functions.sh 文件自动包含在 shell 执行运行时中。要使用这些命令,请确保您的系统上已安装以下先决条件:
先决条件
psql:PostgreSQL 命令行工具rush:数据处理工具 (https://jeroenjanssens.github.io/rush/)R配合tidyverse库:用于ggplot功能dotnet:用于 F# 支持的 .NET SDKnode配合react和react-dom:用于 JSX 支持python3:用于各种实用函数esbuild:JavaScript 打包器(用于nodejsx)
可用命令
pg:执行 PostgreSQL 查询ggplot:使用 R 的 ggplot2 生成图表fsharp:执行 F# 代码nodejsx:使用 Node.js 执行 JSX 代码prependcss:将 CSS 前置到 HTML 内容pngcopyhtml:将 PNG 转换为 HTML 并复制到剪贴板(需要impbcopy)pngtohtml:将 PNG 转换为 HTMLtsvtohtml:将 TSV 转换为 HTML 表格tablecho:回显表格数据tsvtocsv:将 TSV 转换为 CSV
这些命令在 guish 环境中自动可用,无需手动将其添加到您的 shell 配置中。
注意:这些命令的实际实现由 guish 内部处理,因此您无需担心具体的 shell 函数定义。
impbcopy
impbcopy 需要在主机系统上安装 swift 并编译如下:
swiftc impbcopy.swift -o impbcopy
// impbcopy.swift
import Cocoa
func copyToClipboard(path: String) -> Bool {
guard let image: NSImage = {
if path == "-" {
let input = FileHandle.standardInput
return NSImage(data: input.readDataToEndOfFile())
} else {
return NSImage(contentsOfFile: path)
}
}() else {
return false
}
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
let copiedObjects = [image]
let copied = pasteboard.writeObjects(copiedObjects)
return copied
}
let arguments = CommandLine.arguments
if arguments.count < 2 {
print("""
Usage:
Copy file to clipboard:
./impbcopy path/to/file
Copy stdin to clipboard:
cat /path/to/file | ./impbcopy -
""")
exit(EXIT_FAILURE)
}
let path = arguments[1]
let success = copyToClipboard(path: path)
exit(success ? EXIT_SUCCESS : EXIT_FAILURE)
贡献
欢迎贡献!请随时提交 Pull Request,或至少打开一个详细的 Issue。
- Fork 该仓库
- 创建你的功能分支 (
git checkout -b feature/AmazingFeature) - 提交你的更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开一个 Pull Request
许可证
本项目基于 ISC License 授权。
致谢
- 本项目使用了各种开源库和工具。我们感谢这些项目的开发者和贡献者。
- 特别感谢 Electron、React 和 Tailwind CSS 社区,感谢他们出色的框架和文档。
- 额外感谢 Claude Projects 的 Artifacts 插件、ChatGPT 和 GitHub Copilot Workspaces,它们让我有时间与精力进行此类实验。