mcpField
N
nushell-pro

nushell-pro

github.com/hustcer开发252.6k 次安装5 周前更新
代码仓库

关于 nushell-pro

nushell-pro 是指导 Nushell 脚本编写、调试、审查和迁移的技能,适合需要维护 Nu 项目的开发者。它强调版本兼容、类型与数据流约定,以及命令执行和路径处理的安全检查。

主要功能

  1. 01指导脚本编写、调试与重构
  2. 02按任务加载相关参考资料
  3. 03检查版本兼容性与类型约定
  4. 04审查命令、路径和凭据安全
  5. 05推荐解析与测试验证流程

适用场景

  1. 01编写或审查 Nushell 脚本
  2. 02将 Bash 脚本迁移到 Nushell
  3. 03检查路径操作和外部命令的安全性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hustcer/nushell-pro --skill nushell-pro

安装后在 Claude Code 中输入/nushell-pro确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
.env-example
README.md
test-prompts.json
.agents/skills/update-nu/references/
validation.md
.claude/skills/darwin-skill/
results.tsv
docs/
scripting-validation-evidence.md
nushell-0.114-fact-check-independent.md
references/
advanced-patterns.md
bash-to-nushell.md
daemon-and-e2e-smoke-tests.md
anti-patterns.md
data-and-types.md
nu-0.114-migration.md
modules-and-scripts.md
nu-0.116-migration.md
dataframes.md
security.md
string-formats.md
script-review.md
nu-0.115-migration.md
references/archive/
README.md
tests/
nu-0.116-smoke.nu
strings-and-validation-smoke.nu
nu-0.115-smoke.nu
validation-and-daemon-smoke.nu

详细介绍

Nushell Pro

编写安全、地道、可移植且可测试的 Nushell。将主工作流保留在此文件中;仅在任务需要时加载详细参考内容。

操作工作流

  1. 明确任务类型:新脚本、调试、审查、重构、模块设计、 迁移、性能优化、安全审计,或 Bash 转换。

  2. 在修改代码之前,先阅读目标 .nu 文件、相关测试、AGENTS.md 以及项目现有的 约定。

  3. 同时确定项目支持的 Nu 版本范围(来自 CI、文档或 项目配置)和当前本地活动版本。不要假定本地 二进制文件定义了兼容性目标。优先使用官方英文文档; 翻译可能滞后。当本地文档/源码检出可用时,请检查 它们,并将其修订版本与已安装的 Nu 版本分开记录。 在任何 shell 中,优先使用:

    nu --version
    

    当已经处于 Nushell 中或需要结构化版本数据时,使用:

    version | get version
    
  4. 加载最小且相关的参考集:

    任务参考
    Nu 0.116 迁移、补全、标志展开、清理Nu 0.116 Migration
    Nu 0.115 迁移、YAML、CLI 参数、命令变更Nu 0.115 Migration
    Nu 0.114 迁移与版本兼容性Nu 0.114 Migration
    字符串、正则/通配符、生成的 JS/JSONString Formats
    安全、路径、凭据、破坏性操作Security
    脚本/代码审查Script Review and Anti-Patterns
    Bash/POSIX 转换Bash to Nushell
    模块、导出、脚本、测试Modules & Scripts
    守护进程、后台作业、端到端冒烟测试Daemon & E2E Smoke Tests
    类型、记录、列表、转换Data & Type System
    流式处理、闭包、性能、诊断Advanced Patterns
    大型列式数据Dataframes
    常见错误Anti-Patterns

    此处仅列出最新的三个迁移指南。对于更早的版本, 请查阅迁移归档。

  5. 在进行风格或性能清理之前,先应用下面的横切防护措施。

  6. 在生成的脚本首次真正运行之前,在预期范围内使用 nu-check --debug。 对棘手的字符串/序列化负载断言精确输出, 然后运行相关测试;仅靠解析无法检测到非预期但 有效的插值。当需要结构化诊断时,使用 --ide-check。

  7. 在风格和性能说明之前,先报告安全/正确性问题。

如果引用的文件不可用,请说明情况并继续使用本文件, 而不是编造其内容。

跨领域护栏

这些规则适用于各种任务类型。在依赖 Nushell 各版本之间发生变化的行为或语法之前,先加载已路由的参考文档。

类型与管道契约
  • 在 I/O 签名中声明管道输入,而不是作为位置参数。当需要复用 $in 时只捕获一次,因为流可能是单次遍历的。
  • 为导出的命令参数以及输入/输出签名标注类型。
  • 将外部/配置记录视为不可信;使用可选访问方式,例如 $record.field?,并验证结果的类型/值。
  • 记住 default 会急切求值其回退参数。当回退逻辑可能失败或开销较大时,要使其对 null 安全或显式分支。
  • 保持返回类型一致。除非函数确实是多态的,否则避免使用 any。
  • 仅当 CLI 必须保留调用方的 token 拼写、而不能应用 Nushell 字面量强制转换时,才在 main 参数上使用 external_arg。在 Nu 0.115 中它会生成 glob/list<glob> 值,因此在将其视为结构化应用数据之前,要先验证或转换它们。
  • 对同一个值的多个分支优先使用 match;对一次性的布尔判断使用 if。
  • 在 Nu 0.116 中,record 展开会将命名标志传递给内部/自定义命令。Null 会省略标志,除非其类型接受 nothing;开关的 false/null 也会省略该标志。验证转发的键并保留默认/null 意图。
外部命令与错误
  • 将外部参数作为独立的值传递,绝不要作为插值后的命令字符串。当状态重要时使用 complete 并检查 exit_code。
  • 对于结构化的进程内错误,优先使用 try/catch 和 $err.details。
  • 在 Nu 0.115 中,带 span 的 error make 标签形状为 {text: ..., span: {start: ..., end: ...}}。不要使用已过时的扁平 {text, start, end} 形式。
  • 在 Nu 0.115.0 中,直接嵌套在外层 try(其处理器为 catch)内的 try/finally 会静默跳过内层的 finally。为外层块添加 finally,或将内层块置于 do/命令边界之后,并断言所拥有的状态已消失。此缺陷在 0.116 中已修复;仅当所支持的版本需要时才保留此变通方法。
  • 将渲染后的嵌套 Nu 诊断信息视为展示文本,而非稳定的协议。对于 CLI 测试,在匹配较长的领域特定短语之前,先规范化 ANSI 样式、装订线和 PTY 换行。
安全停止检查点

在批准会执行命令、删除文件、读取凭据或接受路径/模式的代码之前,确认以下边界:

  • 绝不将不可信的字符串传给 nu -c、source、run、^sh -c、 ^bash -c 或 ^cmd.exe /C。
  • 将外部命令参数作为独立的值传递,而不是插值后的 shell 命令字符串。
  • 对于限制在某个基础目录内的现有路径,展开两条路径并使用 path relative-to 来证明包含关系。字符串 starts-with 检查是不安全的,因为 /safe/base2 以 /safe/base 开头。
  • 优先使用 Nu 内置的 mktemp/mktemp --directory;它可移植并直接返回路径。不要使用可预测的临时名称。
  • 使用 with-env 限定密钥的作用域;当存在 stdin/配置文件机制时,不要记录它们或通过 argv 传递它们。
  • 防范破坏性路径为根目录、$nu.home-dir、意外类型和不可信的 glob。考虑 TOCTOU 和部分成功行为。

对于尚不存在的输出路径,使用相同的包含规则验证已存在的父目录,然后只拼接经过验证的叶子名称。

字符串与格式化
  • 优先使用简单字面量和原始正则字符串;仅在确实需要转义时才使用双引号。
  • 请记住,$'...' 会进行插值,但不会处理转义序列。
  • 插值中直接出现的字面量 ( 需要使用 $"..."。 由于 $'...' 不进行转义处理, 其中的每个 ( 都会开启一个插值表达式,而 \( 无法阻止这一点。 应写 $"\(abc)($var)",绝不要写 $'\(abc)($var)'。这种失败通常是静默的, 而不会报错:$'(1 + 1) items' 会求值为 2 items。参见 字符串格式。对于包含大量分隔符的生成代码, 应改为拼接纯字面量片段和序列化数据。
  • 在不同解释器之间保持代码与数据分离:将 argv/stdin/JSON 传给固定的程序。 如果某个 API 只接受源代码,请使用固定且可信的模板,并采用目标语言的序列化方式; 当接收工具会对其求值时,单个 argv 字符串仍然是代码。不要将原始值拼接进源代码。
  • 命令/标志使用 kebab-case,变量/参数使用 snake_case,环境变量使用 SCREAMING_SNAKE_CASE。
数据格式与分组
  • from xml 会丢失 XML 命名空间标识(在 Nu 0.115.1 上复现):它 仅为元素和属性存储本地名称,结果中没有命名空间 URI 或声明。例如, <x xmlns:r="urn:r" id="plain" r:id="rel"/> 会变成一个 attributes 记录, 其中仅包含 id: rel;交换这两个属性的顺序则会留下 id: plain。 当本地名称冲突时,后面的属性会覆盖前面的属性。 不要将此记录用于对命名空间敏感的 XML 查找、编辑或 往返转换。请使用能感知命名空间的 XML 解析器;或者在 query xml 插件 可用时,使用带 --namespaces 的 XPath(当名称重要时再加上 --output-names)。 应匹配命名空间 URI 加本地名称,而不是前缀拼写。
  • Nu 0.115 使 from yaml 默认采用 YAML 1.2,并严格处理非字符串键 和标签。当输入契约由另一个系统控制时,请固定 --spec、--multiple、标签处理和键解析, 而不是意外继承默认值。
  • 让 to yaml 默认拒绝不可往返转换的值。仅当这种数据丢失是 文档化契约的一部分时才选择退出,并为该值加引号: --non-roundtrip 'null' 在 0.115/0.116 上均可工作;裸 null 从 0.116 起可用。仅在 0.116.0 上,单独使用 --non-roundtrip 'lossy' 仍会被拒绝,因此当确实需要 有损编码时,请使用 --serialize。在 0.116 上,请将 --compact-list-indent 替换为 --list-indent compact|indented。
  • group-by 的记录输出无法表示 null 键,并且会在 Nu 0.115 中省略该分组。当必须保留 null 分组或 将其与空字符串区分开时,请使用 group-by --to-table。
数据流与性能
  • 优先使用管道和不可变的 let 绑定。
  • 使用 where、select、update、insert、items、transpose、reduce 和 enumerate,而不是手动解析和可变累加。
  • 不要在闭包中捕获 mut 变量。
  • for 适用于顺序副作用,但不是转换表达式;当需要列表结果时, 请使用 each。
  • 仅在并发安全且有益时使用 par-each;当顺序或顺序副作用重要时, 请保留 each。
  • 当打算逐行进行流式解析时,请在 parse 之前加上 lines。
  • 在 Nu 0.116 上,流式错误会传递到 length、columns、is-empty 和 each while;请在测试中消费流,并修复上游失败。在 take until 等行条件命令中, 请将标志放在谓词之前。
  • 在 Nu 0.115 上,对于简单的 any/all 谓词,优先使用直接行条件; 当谓词需要设置、解构或复用时,请保留闭包。
  • 对于小型交互式数据,使用原生表格;对于大型列式 group-by/join/聚合工作负载,使用 Polars。
模块与脚本
  • 只导出预期的 API;将辅助函数保持私有。
  • 当命令应与模块名一致时,使用 export def main。
  • 对调用方可见的环境变更,使用 def --env/export def --env。
  • 不要用解析器关键字命名命令、别名、模块或导出项。 在 Nu 0.115 中,还要将 $ans 视为保留名称;重命名旧的 ans 绑定。
  • source、use 和 run 的目标必须可信,并在解析时可用。
  • 在正确的接缝处测试:稳定结构化错误用直接函数,参数解析/进程边界用 CLI 子进程,必要时两者都用。
  • 对于 Nu 0.116 的补全器,使用具名的 token/place/buffer 输入,并用 place.command 表示 shell 词。通过 commandline complete 测试;加载 0.116 迁移指南以了解输出/回退规则和 @interactive 归属。

审查顺序

审查代码时,按以下顺序报告发现的问题:

  1. 安全性:注入、路径遍历、凭据、破坏性操作、临时 文件、环境投毒。
  2. 正确性:类型、null 处理、解析时约束、退出码、 清理/回滚、数据格式契约、平台/版本行为、稳定的 测试。
  3. 可维护性:命名、模块边界、重复、文档。
  4. 性能:流式处理、不必要的收集、安全并行、Polars。

跳过项目格式化工具/linter 已强制的问题,除非工具 输出显示它们当前正失败。

验证

对于普通的脚本/模块验证,优先使用 nu-check --debug。它会解析目标,但不运行目标的顶层命令,并报告解析期的类型错误以及语法错误。请使用匹配的解析模式:

nu --no-config-file -c 'nu-check --debug path/to/script.nu'
nu --no-config-file -c 'nu-check --debug --as-module path/to/module.nu'
nu --no-config-file path/to/test-script.nu
  • 不使用 --debug 时,无效内容会返回 false,而外围的 nu 进程仍可能以 0 退出;请显式消费该布尔值。使用 --debug 时,解析错误会抛出,因此未被捕获的失败会以非零状态退出。文件缺失属于错误。这两种模式都不能证明运行时正确性,也不提供沙箱。
  • 检查带有相对导入的已保存脚本时,请直接传入文件路径。将其文本通过管道传给 nu-check 时检查的是匿名源;当存在管道输入时,可选路径不会恢复该文件的导入上下文。
  • 对于需要 span 和诊断记录的编辑器/CI 集成,请使用 nu --no-config-file --ide-check 100 path/to/script.nu。
  • --ide-check 会向 stdout 输出 JSON Lines,并且当某条记录具有 type: "diagnostic" 和 severity: "Error" 时,仍可能以退出码 0 退出。在旧版本中,对于缺失的文件,它也会以 0 退出并输出为空;0.116 用非零退出修复了这种情况。进行跨版本检查时请验证路径。用 from json 解析每一行非空输出;不要仅依赖进程退出码。将 severity: "Error" 诊断视为阻塞项,将 Warning 等其他严重级别呈现出来但不阻塞,并忽略 type: "hint" 记录。将非零退出码或 stderr 单独作为 CLI 启动或 I/O 失败处理。
  • 对于可复现的独立检查,优先使用 --no-config-file。当脚本有意依赖用户配置中的命令或环境时,请省略它,并记录该依赖。
  • source 会执行顶层代码;它不是语法检查。仅在有意加载已审计的定义/设置时使用它。使用 nu-check/--ide-check 验证有副作用的脚本,然后在专用的临时 fixture 中执行。保存结构化值时,请使用可识别的数据扩展名,或在 save 之前显式序列化(to json、to yaml、to nuon 等)。
  • 在 Nu 0.115+ 中不要使用 nu --testbin。请用 Nushell 本身或专门构建的测试 fixture 重新实现所需行为。
  • 当涉及诊断或表格时,请在窄 PTY 下复现对终端敏感的测试,例如 stty cols 24 && nu tests/example.nu。
  • 完成前检查 diff 中的调试标记和意外更改。
  • 如果验证失败,请修复最小的可复现问题,并在扩大测试套件之前重新运行完全相同的失败命令。

评论

支持 Markdown