pwsh-guide 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/package.json +1 -1
- package/scripts/probe.windows.ps1 +2 -1
- package/src/meta.js +2 -0
- package/src/probe.js +25 -4
- package/src/render.js +22 -2
- package/templates/SKILL.powershell.md +7 -3
- package/templates/SKILL.pwsh.md +91 -0
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ AI 代理执行命令失败,本质是"生成即采样":模型先验以 bash
|
|
|
8
8
|
|
|
9
9
|
v0.3 起补上"验证闭环":`init`/`refresh` 生成快照(`.meta.json`)→ `check` 检测环境漂移 → SKILL.md 内嵌快速自检指令;环境变化后 AI 先 refresh 再继续,不再用过期的指南。
|
|
10
10
|
|
|
11
|
+
v0.4 起按"默认 shell 变体"渲染:Windows 上区分 `pwsh`(PowerShell 7)与 `powershell.exe`(Windows PowerShell 5.1)——pwsh 指南默认 UTF-8、无需输入侧编码 hack,并包含 `-Parallel`/`??`/三元等特性;5.1 指南保留输入侧 hack。两个实测参数陷阱(内联 splatting、特殊字符内联拼接)已固化进两变体模板。
|
|
12
|
+
|
|
11
13
|
- Windows 下生成 PowerShell 指南;macOS/Linux 下生成 bash/zsh 指南(只生成当前环境可用内容,省 token)
|
|
12
14
|
- 平台无关探测全部用 Node 原生实现(`os` / `process.env` / `fs`),不依赖特定 shell
|
|
13
15
|
- 工具版本并行探测;项目上下文以 git 根为基准,并按 lock 文件推断推荐包管理器与项目命令
|
|
@@ -43,7 +45,7 @@ npx pwsh-guide --version
|
|
|
43
45
|
|
|
44
46
|
- 平台与 OS:`os.platform()` / `os.release()` / `os.arch()` / 主机名 / 用户与临时目录
|
|
45
47
|
- shell(按平台深度探测):
|
|
46
|
-
- Windows:PowerShell 版本 / PSEdition / 控制台输出编码 / `$OutputEncoding` / chcp / 执行策略 / pwsh 7
|
|
48
|
+
- Windows:PowerShell 版本 / PSEdition / shell 变体(`pwsh` 或 `powershell`,按 `$env:SHELL` 判定,可用 `PWSH_GUIDE_SHELL=pwsh` 强制)/ 控制台输出编码 / `$OutputEncoding` / chcp / 执行策略 / pwsh 7 可用性;powershell.exe 探测失败时自动用 pwsh 重试
|
|
47
49
|
- macOS/Linux:默认 shell(`$SHELL`)/ 可用 shell(bash / zsh / fish)/ locale(LANG / LC_ALL / LC_CTYPE)/ WSL 标注
|
|
48
50
|
- 工具:git、node、npm、npx、pnpm、yarn、bun、python、py、uv、pip、docker、make、rg、gh、pwsh、cargo、go 的可用性与版本(PATH 遍历 + `--version`,并行探测,超时/缺失记为 null)
|
|
49
51
|
- 项目(以 git 根为基准):标记文件、venv、package.json scripts、推荐包管理器(lock 文件推断)、README / Makefile 目标 / Docker Compose、项目根第一层子目录
|
|
@@ -54,11 +56,12 @@ npx pwsh-guide --version
|
|
|
54
56
|
bin/pwsh-guide.js CLI 入口(init / refresh / check / --dry-run)
|
|
55
57
|
src/probe.js 跨平台主探测(Node 原生;并行工具探测;项目根基准)
|
|
56
58
|
src/detect.js 仓库根判定与双输出目录解析
|
|
57
|
-
src/render.js 按 shell
|
|
59
|
+
src/render.js 按 shell 族与变体渲染 SKILL.md / environment.md / commands.md
|
|
58
60
|
src/meta.js 生成快照与漂移对比(check 用)
|
|
59
61
|
scripts/probe.windows.ps1 Windows 深度探测(PS 5.1 兼容,输出 UTF-8 JSON)
|
|
60
62
|
scripts/probe.unix.sh Unix 深度探测(POSIX sh 兼容,输出 UTF-8 JSON)
|
|
61
|
-
templates/SKILL.powershell.md PowerShell
|
|
63
|
+
templates/SKILL.powershell.md PowerShell 5.1 变体 SKILL.md 模板({{占位符}} 由 render.js 填充)
|
|
64
|
+
templates/SKILL.pwsh.md pwsh 7 变体 SKILL.md 模板
|
|
62
65
|
templates/SKILL.unix.md Unix 族 SKILL.md 模板
|
|
63
66
|
test/probe.test.js 单元测试(node --test)
|
|
64
67
|
.github/workflows/ci.yml 三平台(windows/ubuntu/macos)测试与集成验证
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pwsh-guide",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Generate a project-level Agent Skill: probe the current environment (Windows PowerShell / macOS / Linux shell) and produce a reliable command guide (SKILL.md + references) for agents such as Codex and Claude Code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,11 +17,12 @@ try {
|
|
|
17
17
|
} catch { $chcp = $null }
|
|
18
18
|
|
|
19
19
|
$result = [pscustomobject]@{
|
|
20
|
-
defaultShell = 'powershell.exe'
|
|
20
|
+
defaultShell = if ($PSVersionTable.PSEdition -eq 'Core') { 'pwsh' } else { 'powershell.exe' }
|
|
21
21
|
psVersion = $PSVersionTable.PSVersion.ToString()
|
|
22
22
|
psEdition = $PSVersionTable.PSEdition
|
|
23
23
|
hostName = $Host.Name
|
|
24
24
|
pwsh7Available = ($null -ne (Get-Command pwsh -ErrorAction SilentlyContinue))
|
|
25
|
+
ps51Available = ($null -ne (Get-Command powershell.exe -ErrorAction SilentlyContinue))
|
|
25
26
|
osVersion = [System.Environment]::OSVersion.VersionString
|
|
26
27
|
consoleOutputEncoding = $originalConsoleEncoding
|
|
27
28
|
outputEncoding = $OutputEncoding.WebName
|
package/src/meta.js
CHANGED
|
@@ -24,6 +24,7 @@ export function buildMeta(env, generatorVersion) {
|
|
|
24
24
|
arch: (env.os && env.os.arch) || null,
|
|
25
25
|
shell: {
|
|
26
26
|
defaultShell: shell.defaultShell || null,
|
|
27
|
+
variant: shell.variant || null,
|
|
27
28
|
psVersion: shell.psVersion || null,
|
|
28
29
|
psEdition: shell.psEdition || null,
|
|
29
30
|
chcp: shell.chcp ?? null,
|
|
@@ -86,6 +87,7 @@ export function compareEnv(env, meta) {
|
|
|
86
87
|
['OS 版本', (env.os && env.os.release) || null, meta.osRelease || null],
|
|
87
88
|
['架构', (env.os && env.os.arch) || null, meta.arch || null],
|
|
88
89
|
['默认 shell', shell.defaultShell || null, expectShell.defaultShell || null],
|
|
90
|
+
['shell 变体', shell.variant || null, expectShell.variant || null],
|
|
89
91
|
['PowerShell 版本', shell.psVersion || null, expectShell.psVersion || null],
|
|
90
92
|
['chcp', shell.chcp ?? null, expectShell.chcp ?? null],
|
|
91
93
|
['控制台输出编码', shell.consoleOutputEncoding || null, expectShell.consoleOutputEncoding || null],
|
package/src/probe.js
CHANGED
|
@@ -92,6 +92,7 @@ export async function probeEnvironment(cwd) {
|
|
|
92
92
|
defaultShell,
|
|
93
93
|
defaultShellName: defaultShell.split(/[\\/]/).pop().toLowerCase(),
|
|
94
94
|
...deepShell,
|
|
95
|
+
variant: resolveShellVariant(platform, process.env, deepShell),
|
|
95
96
|
},
|
|
96
97
|
tools,
|
|
97
98
|
project,
|
|
@@ -103,14 +104,34 @@ function resolveDefaultShell(platform, deepShell) {
|
|
|
103
104
|
if (platform === 'win32') return 'powershell.exe';
|
|
104
105
|
return process.env.SHELL || '/bin/sh';
|
|
105
106
|
}
|
|
107
|
+
// Windows shell 变体判定(可测纯函数):'pwsh' | 'powershell' | null(非 Windows)
|
|
108
|
+
// 优先级:PWSH_GUIDE_SHELL 覆盖 > $env:SHELL 指向 > 深度探测实际运行 shell > 默认 powershell
|
|
109
|
+
export function resolveShellVariant(platform, env, deepShell) {
|
|
110
|
+
if (platform !== 'win32') return null;
|
|
111
|
+
const override = String(env.PWSH_GUIDE_SHELL || '').trim().toLowerCase();
|
|
112
|
+
if (override) return override.includes('pwsh') ? 'pwsh' : 'powershell';
|
|
113
|
+
const shellPath = String(env.SHELL || '').replace(/\\/g, '/').toLowerCase();
|
|
114
|
+
if (shellPath && /(^|\/)pwsh(\.exe)?$/.test(shellPath)) return 'pwsh';
|
|
115
|
+
if (shellPath && /(^|\/)powershell(\.exe)?$/.test(shellPath)) return 'powershell';
|
|
116
|
+
const deep = String((deepShell && deepShell.defaultShell) || '').toLowerCase();
|
|
117
|
+
if (deep.includes('pwsh')) return 'pwsh';
|
|
118
|
+
return 'powershell';
|
|
119
|
+
}
|
|
106
120
|
|
|
107
121
|
// 分平台深度探测:失败时降级为空对象,不中断主探测
|
|
108
122
|
function runDeepProbe(platform, cwd) {
|
|
109
123
|
const script = DEEP_SCRIPTS[platform] || DEEP_SCRIPTS.unix;
|
|
110
|
-
if (platform
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
124
|
+
if (platform !== 'win32') return runDeepScript('/bin/sh', [script], cwd);
|
|
125
|
+
const args = ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-File', script];
|
|
126
|
+
const pwshPath = findToolPath('pwsh');
|
|
127
|
+
const preferred = resolveShellVariant(platform, process.env, {}) === 'pwsh' && pwshPath ? pwshPath : 'powershell.exe';
|
|
128
|
+
return runDeepScript(preferred, args, cwd).then((result) => {
|
|
129
|
+
if (Object.keys(result).length > 0) return result;
|
|
130
|
+
// 首选失败:若有 pwsh 且首选不是 pwsh,用 pwsh 重试一次;仍失败则降级
|
|
131
|
+
if (!pwshPath || preferred === pwshPath) return result;
|
|
132
|
+
console.warn('[pwsh-guide] powershell.exe 深度探测失败,改用 pwsh 重试...');
|
|
133
|
+
return runDeepScript(pwshPath, args, cwd);
|
|
134
|
+
});
|
|
114
135
|
}
|
|
115
136
|
|
|
116
137
|
function runDeepScript(file, args, cwd) {
|
package/src/render.js
CHANGED
|
@@ -10,6 +10,7 @@ const TEMPLATES_DIR = path.resolve(__dirname, '..', 'templates');
|
|
|
10
10
|
|
|
11
11
|
const SKILL_TEMPLATES = {
|
|
12
12
|
powershell: path.join(TEMPLATES_DIR, 'SKILL.powershell.md'),
|
|
13
|
+
pwsh: path.join(TEMPLATES_DIR, 'SKILL.pwsh.md'),
|
|
13
14
|
unix: path.join(TEMPLATES_DIR, 'SKILL.unix.md'),
|
|
14
15
|
};
|
|
15
16
|
|
|
@@ -28,6 +29,12 @@ function resolveFamily(env) {
|
|
|
28
29
|
return env.family === 'unix' ? 'unix' : 'powershell';
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
// Windows 上按 shell 变体选模板:pwsh -> SKILL.pwsh.md,否则 -> SKILL.powershell.md
|
|
33
|
+
function resolveTemplateKey(env) {
|
|
34
|
+
if (env.family === 'unix') return 'unix';
|
|
35
|
+
return (env.shell && env.shell.variant) === 'pwsh' ? 'pwsh' : 'powershell';
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
function fill(template, values) {
|
|
32
39
|
let out = template;
|
|
33
40
|
const placeholderRe = /\{\{([a-zA-Z0-9_]+)\}\}/g;
|
|
@@ -175,19 +182,29 @@ function renderSearchGuide(env) {
|
|
|
175
182
|
}
|
|
176
183
|
|
|
177
184
|
export function renderSkill(env) {
|
|
185
|
+
const tplKey = resolveTemplateKey(env);
|
|
178
186
|
const family = resolveFamily(env);
|
|
179
187
|
const shell = env.shell || {};
|
|
180
188
|
const os = env.os || {};
|
|
189
|
+
const pwshTool = getTool(env, 'pwsh');
|
|
190
|
+
const pwshVersion = (pwshTool && pwshTool.version) || '未知';
|
|
191
|
+
const ps51Installed = Boolean(shell.psVersion && /^5\./.test(shell.psVersion));
|
|
181
192
|
const values = {
|
|
182
193
|
generatedAt: new Date().toISOString(),
|
|
183
194
|
generatorVersion: pkg.version,
|
|
184
195
|
osVersion: `${os.platform || ''} ${os.release || ''}`.trim() || '未知',
|
|
185
196
|
shellName: shell.defaultShellName || shell.defaultShell || (family === 'powershell' ? 'powershell' : 'sh'),
|
|
186
197
|
psVersion: shell.psVersion || '未知',
|
|
198
|
+
pwshVersion,
|
|
187
199
|
consoleOutputEncoding: shell.consoleOutputEncoding || '未知',
|
|
188
200
|
chcp: shell.chcp ?? '未知',
|
|
189
201
|
executionPolicySummary: executionPolicySummary(env),
|
|
190
|
-
pwsh7Note: shell.pwsh7Available
|
|
202
|
+
pwsh7Note: shell.pwsh7Available
|
|
203
|
+
? `本机也装有 pwsh ${pwshVersion === '未知' ? '7' : pwshVersion}(PowerShell 7)。如实际执行环境是 pwsh:\`&&\`/\`??\` 等新语法可用、中文参数默认 UTF-8 不乱码,可优先使用 \`pwsh\`。`
|
|
204
|
+
: '',
|
|
205
|
+
ps51Note: (shell.ps51Available || ps51Installed)
|
|
206
|
+
? '本机也装有 Windows PowerShell 5.1(powershell.exe)。若实际执行环境是 powershell.exe:`&&`/`??` 等新语法不可用、`$OutputEncoding` 默认非 UTF-8(中文参数需先设置)。'
|
|
207
|
+
: '',
|
|
191
208
|
localeSummary: localeSummary(env),
|
|
192
209
|
langValue: langValue(env),
|
|
193
210
|
fishNote: shell.defaultShellName === 'fish' ? '注意:默认 shell 是 fish,语法与 bash/zsh 不同(本文以 bash/zsh 为主)。' : '',
|
|
@@ -198,7 +215,7 @@ export function renderSkill(env) {
|
|
|
198
215
|
projectCommands: renderProjectCommands(env),
|
|
199
216
|
searchGuide: renderSearchGuide(env),
|
|
200
217
|
};
|
|
201
|
-
return fill(loadTemplate(
|
|
218
|
+
return fill(loadTemplate(tplKey), values);
|
|
202
219
|
}
|
|
203
220
|
|
|
204
221
|
function renderEnvironment(env) {
|
|
@@ -206,6 +223,7 @@ function renderEnvironment(env) {
|
|
|
206
223
|
const shell = env.shell || {};
|
|
207
224
|
const os = env.os || {};
|
|
208
225
|
const p = env.project || {};
|
|
226
|
+
const pwshTool = getTool(env, 'pwsh');
|
|
209
227
|
const lines = [];
|
|
210
228
|
lines.push('# 环境事实(pwsh-guide 探测结果)');
|
|
211
229
|
lines.push('');
|
|
@@ -218,10 +236,12 @@ function renderEnvironment(env) {
|
|
|
218
236
|
if (family === 'powershell') {
|
|
219
237
|
lines.push(`| OS | ${os.release ?? '-'} |`);
|
|
220
238
|
lines.push(`| 默认 shell | ${shell.defaultShell ?? '-'} |`);
|
|
239
|
+
lines.push(`| shell 变体 | ${shell.variant === 'pwsh' ? 'pwsh(PowerShell 7)' : shell.variant === 'powershell' ? 'powershell.exe(Windows PowerShell 5.1)' : '-'} |`);
|
|
221
240
|
lines.push(`| PowerShell 版本 | ${shell.psVersion ?? '-'} |`);
|
|
222
241
|
lines.push(`| PSEdition | ${shell.psEdition ?? '-'} |`);
|
|
223
242
|
lines.push(`| 主机 | ${shell.hostName ?? '-'} |`);
|
|
224
243
|
lines.push(`| pwsh 7 可用 | ${shell.pwsh7Available ? '是' : '否'} |`);
|
|
244
|
+
lines.push(`| pwsh 7 版本 | ${(pwshTool && pwshTool.version) ?? '-'} |`);
|
|
225
245
|
lines.push(`| 控制台输出编码 | ${shell.consoleOutputEncoding ?? '-'} |`);
|
|
226
246
|
lines.push(`| $OutputEncoding | ${shell.outputEncoding ?? '-'} |`);
|
|
227
247
|
lines.push(`| 代码页 chcp | ${shell.chcp ?? '-'} |`);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pwsh-guide
|
|
3
|
-
description: 本项目的 PowerShell
|
|
3
|
+
description: 本项目的 PowerShell(Windows PowerShell 5.1)命令执行指南。需要执行 shell 命令、遇到 PowerShell 报错、中文乱码或不确定命令语法时使用;含本机环境事实、命令模板、快速自检与失败诊断。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# PowerShell
|
|
6
|
+
# PowerShell 操作指南(本环境 · Windows PowerShell 5.1)
|
|
7
7
|
|
|
8
8
|
> 由 `pwsh-guide v{{generatorVersion}}` 生成于 {{generatedAt}}。环境变化后运行 `pwsh-guide refresh` 更新;`pwsh-guide check` 可检测环境漂移。
|
|
9
9
|
|
|
@@ -25,6 +25,8 @@ description: 本项目的 PowerShell 命令执行指南。需要执行 shell 命
|
|
|
25
25
|
5. 只读操作优先;删除等危险操作先 `-WhatIf` 或展示计划再执行。
|
|
26
26
|
6. 长命令优先写成 `.ps1` 再以 `-File` 执行,避免内联引号地狱。
|
|
27
27
|
7. 含中文参数的原生命令(git/node/npm 等)先按第 4 节设置输入编码。
|
|
28
|
+
8. 传参用具名参数或变量 splatting:先 `$h = @{ ... }` 再 `命令 @h`;**禁止 `命令 @{ ... }`**(内联 splatting 不生效,会把 hashtable 当普通参数)。
|
|
29
|
+
9. 含特殊字符(引号/逗号/中文)的参数:禁止内联拼接进 `-Command "..."` 字符串(会被拆碎);改用 `.ps1` 脚本 `param()`、环境变量或参数数组传递。
|
|
28
30
|
|
|
29
31
|
## 3. 常用命令模板
|
|
30
32
|
|
|
@@ -49,6 +51,8 @@ description: 本项目的 PowerShell 命令执行指南。需要执行 shell 命
|
|
|
49
51
|
| 命令找不到 | PATH 缺失 / 拼写错 | `Get-Command <name>` 确认;查看 `references/environment.md` 工具表 |
|
|
50
52
|
| 中文乱码 | 代码页与输出编码不匹配 | 按第 4 节切换 UTF-8(含 $OutputEncoding 输入侧) |
|
|
51
53
|
| 引号/转义报错 | 内联 `-Command` 引号地狱 | 改用 `-File` 脚本或参数数组 |
|
|
54
|
+
| 参数被拆分/丢失 | 特殊字符内联拼接进 `-Command` | 改用 `.ps1` 脚本 `param()` / 环境变量 / 参数数组 |
|
|
55
|
+
| 参数收到 Hashtable | 误用内联 splatting `命令 @{...}` | 先存变量 `$h = @{...}` 再 `命令 @h` |
|
|
52
56
|
| 权限拒绝 | 执行策略 / ACL | `Get-ExecutionPolicy -List`;脚本加 `-ExecutionPolicy Bypass` |
|
|
53
57
|
| 路径找不到 | 空格/中文/反斜杠 | 单引号包裹;先 `Test-Path` |
|
|
54
58
|
| 程序假死 | 交互式命令等待输入 | 加 `-NonInteractive`,或 `echo y | <cmd>` |
|
|
@@ -76,7 +80,7 @@ description: 本项目的 PowerShell 命令执行指南。需要执行 shell 命
|
|
|
76
80
|
|
|
77
81
|
## 10. 禁止事项
|
|
78
82
|
|
|
79
|
-
- 禁止 bash 语法:`ls -la`、`grep`、`cat`、`rm -rf`、`export
|
|
83
|
+
- 禁止 bash 语法:`ls -la`、`grep`、`cat`、`rm -rf`、`export`、`dir`、`copy`。
|
|
80
84
|
- 删除一律用 `Remove-Item -Path <path> -Recurse -Force`,且先确认路径再执行。
|
|
81
85
|
- 未读文件内容不得修改;不得批量格式化无关代码。
|
|
82
86
|
- 仓库 AGENTS.md 规则优先于本文件。
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwsh-guide
|
|
3
|
+
description: 本项目的 PowerShell(pwsh 7)命令执行指南。需要执行 shell 命令、遇到 PowerShell 报错、中文乱码或不确定命令语法时使用;含本机环境事实、命令模板、快速自检与失败诊断。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PowerShell 操作指南(本环境 · pwsh 7)
|
|
7
|
+
|
|
8
|
+
> 由 `pwsh-guide v{{generatorVersion}}` 生成于 {{generatedAt}}。环境变化后运行 `pwsh-guide refresh` 更新;`pwsh-guide check` 可检测环境漂移。
|
|
9
|
+
|
|
10
|
+
## 1. 执行命令前先确认
|
|
11
|
+
|
|
12
|
+
- 默认 shell 是 `{{shellName}}`(pwsh {{psVersion}}),**不是 bash/cmd**:禁止 `ls -la`、`grep`、`cat`、`rm -rf`、`export`、`dir`、`copy`。
|
|
13
|
+
- OS:{{osVersion}}。{{ps51Note}}
|
|
14
|
+
- 编码:`$OutputEncoding` 与 `[Console]::OutputEncoding` 均为 UTF-8,中文参数/输出一般不会乱码(代码页 chcp {{chcp}})。
|
|
15
|
+
- 执行策略:{{executionPolicySummary}}。
|
|
16
|
+
- 当前目录:`{{cwd}}`;git 根:`{{gitRoot}}`。
|
|
17
|
+
- 完整环境事实见 `references/environment.md`;可用命令模板见 `references/commands.md`。
|
|
18
|
+
|
|
19
|
+
## 2. 命令执行铁律
|
|
20
|
+
|
|
21
|
+
1. 一条命令一次执行;pwsh 7 支持 `&&`/`||`,但链式出错时难以定位,仍建议一次一条。
|
|
22
|
+
2. 执行后检查退出状态:外部命令看 `$LASTEXITCODE`,cmdlet 看 `$?`,并查看 stderr。
|
|
23
|
+
3. 路径含空格或中文时用单引号包裹:`Get-Content 'E:\path with 中文\file.txt'`。
|
|
24
|
+
4. 环境变量读取 `$env:NAME`,写入 `$env:NAME = 'value'`(仅当前会话)。
|
|
25
|
+
5. 只读操作优先;删除等危险操作先 `-WhatIf` 或展示计划再执行。
|
|
26
|
+
6. 长命令优先写成 `.ps1` 再以 `pwsh -File` 执行,避免内联引号地狱。
|
|
27
|
+
7. 含特殊字符(引号/逗号/中文)的参数:禁止内联拼接进 `-Command "..."` 字符串(会被拆碎);改用 `.ps1` 脚本 `param()`、环境变量或参数数组传递。
|
|
28
|
+
8. 传参用具名参数或变量 splatting:先 `$h = @{ ... }` 再 `命令 @h`;**禁止 `命令 @{ ... }`**(内联 splatting 不生效,会把 hashtable 当普通参数)。
|
|
29
|
+
|
|
30
|
+
## 3. 常用命令模板
|
|
31
|
+
|
|
32
|
+
可用工具与命令见 `references/commands.md`。本机探测到的工具:
|
|
33
|
+
|
|
34
|
+
{{toolsSummary}}
|
|
35
|
+
|
|
36
|
+
## 4. 编码与乱码处理
|
|
37
|
+
|
|
38
|
+
- pwsh 7 默认 UTF-8:`$OutputEncoding` 与 `[Console]::OutputEncoding` 均为 UTF-8,中文一般不会乱码。
|
|
39
|
+
- 写文件指定编码:`Set-Content -Path <file> -Value <text> -Encoding utf8`(pwsh 7 写 UTF-8 无 BOM);`Out-File -Encoding utf8` 同理。
|
|
40
|
+
- 读文件乱码:`Get-Content -Path <file> -Encoding UTF8`。
|
|
41
|
+
- 读 GBK 旧文件:`[System.IO.File]::ReadAllText('<file>', [System.Text.Encoding]::GetEncoding('GBK'))`。
|
|
42
|
+
- 仍乱码时:确认 `[Console]::OutputEncoding.WebName` 为 `utf-8`;必要时 `chcp 65001`。
|
|
43
|
+
|
|
44
|
+
## 5. 失败分类诊断
|
|
45
|
+
|
|
46
|
+
| 症状 | 常见原因 | 处理 |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| 命令找不到 | PATH 缺失 / 拼写错 | `Get-Command <name>` 确认;查看 `references/environment.md` 工具表 |
|
|
49
|
+
| 中文乱码 | 代码页与输出编码不匹配 | 按第 4 节处理(pwsh 默认 UTF-8,一般不会出现) |
|
|
50
|
+
| 引号/转义报错 | 内联 `-Command` 引号地狱 | 改用 `-File` 脚本或参数数组 |
|
|
51
|
+
| 参数被拆分/丢失 | 特殊字符内联拼接进 `-Command` | 改用 `.ps1` 脚本 `param()` / 环境变量 / 参数数组 |
|
|
52
|
+
| 参数收到 Hashtable | 误用内联 splatting `命令 @{...}` | 先存变量 `$h = @{...}` 再 `命令 @h` |
|
|
53
|
+
| 新语法报错 | 实际 shell 是 powershell.exe 5.1 | `&&`/`??`/三元仅在 pwsh 7 可用;确认实际执行 shell |
|
|
54
|
+
| 权限拒绝 | 执行策略 / ACL | `Get-ExecutionPolicy -List`;脚本加 `-ExecutionPolicy Bypass` |
|
|
55
|
+
| 路径找不到 | 空格/中文/反斜杠 | 单引号包裹;先 `Test-Path` |
|
|
56
|
+
| 程序假死 | 交互式命令等待输入 | 加 `-NonInteractive`,或 `echo y | <cmd>` |
|
|
57
|
+
| npm/网络报错 | registry/代理/锁文件不匹配 | `npm config get registry`、`npm ping`;确认包管理器与锁文件一致 |
|
|
58
|
+
| 端口被占用 | 端口冲突 | `Get-NetTCPConnection -LocalPort <port>` 找 PID,确认后 `Stop-Process -Id <pid> -Force` |
|
|
59
|
+
| git 凭据弹窗 | 需要认证 | 先确认凭据;必要时 `$env:GIT_TERMINAL_PROMPT = '0'` 避免挂起 |
|
|
60
|
+
|
|
61
|
+
## 6. 快速自检(环境是否已变化)
|
|
62
|
+
|
|
63
|
+
- 复核 shell:`pwsh --version` 应为 `{{pwshVersion}}`;`$OutputEncoding.WebName` 应为 `utf-8`。
|
|
64
|
+
- 复核工具:逐一运行第 3 节每个工具的 `--version`,输出应与列出的版本一致。
|
|
65
|
+
- 规则:任一自检项与期望不符,或同一命令连续失败两次,先运行 `npx pwsh-guide refresh` 并重读本文件,不要继续猜测。
|
|
66
|
+
|
|
67
|
+
## 7. 代码库检索指引
|
|
68
|
+
|
|
69
|
+
{{searchGuide}}
|
|
70
|
+
|
|
71
|
+
## 8. 项目上下文(来自探测)
|
|
72
|
+
|
|
73
|
+
{{projectContext}}
|
|
74
|
+
|
|
75
|
+
## 9. 项目命令(推荐)
|
|
76
|
+
|
|
77
|
+
{{projectCommands}}
|
|
78
|
+
|
|
79
|
+
## 10. pwsh 7 特性(与 powershell.exe 5.1 的差异)
|
|
80
|
+
|
|
81
|
+
- `&&`/`||`、空合并 `??`、三元 `?:`、`Get-Content -Raw` 等新语法仅 pwsh 7 可用(5.1 会报错)。
|
|
82
|
+
- 并行:`1..10 | ForEach-Object -Parallel { <块> } -ThrottleLimit 4`;块内用 `$using:变量` 读外部变量,输出顺序不保证。
|
|
83
|
+
- JSON:`Get-Content -Raw -Encoding utf8 | ConvertFrom-Json -AsHashtable`(保留键大小写)。
|
|
84
|
+
- 原生命令非 0 退出触发错误处理:`$PSNativeCommandUseErrorActionPreference = $true`(谨慎使用,会影响所有原生命令)。
|
|
85
|
+
|
|
86
|
+
## 11. 禁止事项
|
|
87
|
+
|
|
88
|
+
- 禁止 bash 语法:`ls -la`、`grep`、`cat`、`rm -rf`、`export`、`dir`、`copy`。
|
|
89
|
+
- 删除一律用 `Remove-Item -Path <path> -Recurse -Force`,且先确认路径再执行。
|
|
90
|
+
- 未读文件内容不得修改;不得批量格式化无关代码。
|
|
91
|
+
- 仓库 AGENTS.md 规则优先于本文件。
|