pi-code 1.0.53 → 1.0.54
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/extensions/commands.ts
CHANGED
|
@@ -174,10 +174,19 @@ export function shellExecutionDisabled(cwd: string, home: string, trusted: boole
|
|
|
174
174
|
if (readManagedSettings().disableSkillShellExecution === true) return true
|
|
175
175
|
const files = claudeSettingsChain(cwd, home, trusted)
|
|
176
176
|
return files.some((file) => {
|
|
177
|
+
let raw: string
|
|
177
178
|
try {
|
|
178
|
-
|
|
179
|
+
raw = fs.readFileSync(file, 'utf-8')
|
|
179
180
|
} catch {
|
|
180
|
-
return false //
|
|
181
|
+
return false // no such file: genuinely not a policy statement
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
return (JSON.parse(raw) as Record<string, unknown>).disableSkillShellExecution === true
|
|
185
|
+
} catch {
|
|
186
|
+
// Present but unreadable: the user may believe this file disables skill shells, so
|
|
187
|
+
// say so rather than silently leaving them enabled.
|
|
188
|
+
console.warn(`pi-code: ignoring ${file}: not valid JSON; skill shell execution stays as the other settings leave it`)
|
|
189
|
+
return false
|
|
181
190
|
}
|
|
182
191
|
})
|
|
183
192
|
}
|
|
@@ -210,7 +210,7 @@ export default function gitCheckpointExtension(pi: ExtensionAPI) {
|
|
|
210
210
|
}
|
|
211
211
|
// Written on every start, so repos that predate the sidecar pick it up too.
|
|
212
212
|
rememberWorkTree(shadowDir, ctx.cwd)
|
|
213
|
-
await mirrorLocalExcludes(ctx
|
|
213
|
+
await mirrorLocalExcludes(ctx)
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/** git reads ignore rules from the tree's .gitignore files, the user's global excludes,
|
|
@@ -219,7 +219,8 @@ export default function gitCheckpointExtension(pi: ExtensionAPI) {
|
|
|
219
219
|
* would be snapshotted and restored. Mirror it into the shadow on every start; the
|
|
220
220
|
* global excludes stay untouched (core.excludesFile is single-valued, so pointing it
|
|
221
221
|
* at the repo file would replace them). */
|
|
222
|
-
async function mirrorLocalExcludes(
|
|
222
|
+
async function mirrorLocalExcludes(ctx: ExtensionContext): Promise<void> {
|
|
223
|
+
const cwd = ctx.cwd
|
|
223
224
|
if (!shadowDir) return
|
|
224
225
|
// Resolved through git so a linked worktree maps to its common dir; outside a repo
|
|
225
226
|
// git exits 128 and there is nothing to mirror.
|
|
@@ -233,8 +234,10 @@ export default function gitCheckpointExtension(pi: ExtensionAPI) {
|
|
|
233
234
|
} else {
|
|
234
235
|
fs.rmSync(target, { force: true })
|
|
235
236
|
}
|
|
236
|
-
} catch {
|
|
237
|
-
//
|
|
237
|
+
} catch (error) {
|
|
238
|
+
// Without the mirror, files the user excluded locally are snapshotted into the
|
|
239
|
+
// checkpoint store and restored by /rewind, so this is not a silent fallback.
|
|
240
|
+
ctx.ui.notify(`Checkpoints cannot honor this repository's .git/info/exclude: ${error instanceof Error ? error.message : String(error)}`, 'warning')
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
|
|
@@ -28,6 +28,12 @@ function asOAuthRequiredError(name: string, error: unknown): OAuthRequiredError
|
|
|
28
28
|
* (stored-token) connects do not pass through here and stay fully parallel. */
|
|
29
29
|
let oauthQueue: Promise<unknown> = Promise.resolve()
|
|
30
30
|
|
|
31
|
+
/** Test seam: the queue is module state that outlives a test, so one login left pending
|
|
32
|
+
* would serialize every later login in the same file behind it. */
|
|
33
|
+
export function resetOAuthQueue(): void {
|
|
34
|
+
oauthQueue = Promise.resolve()
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
export function serializeInteractiveOAuth<T>(run: () => Promise<T>): Promise<T> {
|
|
32
38
|
const result = oauthQueue.then(run, run)
|
|
33
39
|
oauthQueue = result.then(
|
package/extensions/mcp/policy.ts
CHANGED
|
@@ -97,11 +97,19 @@ function parsePolicyEntry(entry: unknown): McpPolicyEntry | undefined {
|
|
|
97
97
|
* honored scope sets the key; an empty list is an explicit lockdown (deny all). */
|
|
98
98
|
export function mcpAllowDeny(scopeFiles: string[] = [], managedFile: string = managedSettingsFile()): McpPolicy {
|
|
99
99
|
const read = (file: string): Record<string, unknown> => {
|
|
100
|
+
let raw: string
|
|
100
101
|
try {
|
|
101
|
-
|
|
102
|
+
raw = fs.readFileSync(file, 'utf-8')
|
|
103
|
+
} catch {
|
|
104
|
+
return {} // no such file: genuinely no policy
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(raw)
|
|
102
108
|
return parsed && typeof parsed === 'object' ? parsed : {}
|
|
103
109
|
} catch {
|
|
104
|
-
//
|
|
110
|
+
// Present but unreadable: its allow and deny lists are not in force, and a deny list
|
|
111
|
+
// silently dropped leaves every server allowed.
|
|
112
|
+
console.warn(`pi-code-mcp: ignoring ${file}: not valid JSON; its MCP allow and deny lists are not applied`)
|
|
105
113
|
return {}
|
|
106
114
|
}
|
|
107
115
|
}
|
|
@@ -336,9 +336,11 @@ export async function connectWithRetries(name: string, config: ServerConfig, aut
|
|
|
336
336
|
* environment helperEnv built. It runs through the platform shell (/bin/sh; Git Bash
|
|
337
337
|
* or PowerShell on Windows). A failure, a 10s timeout, or a machine with no shell
|
|
338
338
|
* yields no extra headers rather than blocking the connection. */
|
|
339
|
-
function runHeadersHelper(command: string, env: NodeJS.ProcessEnv): Promise<Record<string, string>> {
|
|
339
|
+
export function runHeadersHelper(command: string, env: NodeJS.ProcessEnv, resolve_ = resolveShell): Promise<Record<string, string>> {
|
|
340
340
|
return new Promise((resolve) => {
|
|
341
|
-
|
|
341
|
+
// The resolver is a parameter so a test can drive both outcomes on any platform:
|
|
342
|
+
// stubbing the platform cannot produce a shell-less host on a machine that has one.
|
|
343
|
+
const shell = resolve_(undefined)
|
|
342
344
|
if (!shell) {
|
|
343
345
|
resolve({})
|
|
344
346
|
return
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.54",
|
|
4
4
|
"description": "Claude Code experience for the pi coding agent: reads your .claude config (rules, commands, skills, hooks, output styles, MCP servers, agents) and adds todo, checkpoints, memory, web, subagents, and goals",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|