mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 11:53:10 +08:00
fix: recover legacy Windows session workdirs
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'bun:test'
|
||||
import * as path from 'node:path'
|
||||
import { isOutsideWorkDir } from '../path-safety.js'
|
||||
|
||||
// ---------- helpers extracted from feishu/index.ts for testability ----------
|
||||
|
||||
@@ -209,14 +209,6 @@ function summarizeToolCall(toolName: string, input: unknown): ToolCallSummary {
|
||||
}
|
||||
}
|
||||
|
||||
function isOutsideWorkDir(filePath: string, workDir: string): boolean {
|
||||
const abs = path.isAbsolute(filePath)
|
||||
? path.normalize(filePath)
|
||||
: path.resolve(workDir, filePath)
|
||||
const normWork = path.normalize(workDir).replace(/\/+$/, '')
|
||||
return abs !== normWork && !abs.startsWith(normWork + path.sep)
|
||||
}
|
||||
|
||||
function truncateTarget(s: string, maxLen = 160): string {
|
||||
if (s.length <= maxLen) return s
|
||||
return s.slice(0, maxLen - 1) + '…'
|
||||
|
||||
@@ -37,6 +37,7 @@ import { AttachmentStore } from '../common/attachment/attachment-store.js'
|
||||
import { checkAttachmentLimit } from '../common/attachment/attachment-limits.js'
|
||||
import { ImageBlockWatcher } from '../common/attachment/image-block-watcher.js'
|
||||
import type { PendingUpload } from '../common/attachment/attachment-types.js'
|
||||
import { isOutsideWorkDir } from './path-safety.js'
|
||||
|
||||
// ---------- init ----------
|
||||
|
||||
@@ -502,16 +503,6 @@ function summarizeToolCall(toolName: string, input: unknown): ToolCallSummary {
|
||||
}
|
||||
}
|
||||
|
||||
/** True if `filePath` resolves to a location outside of `workDir`.
|
||||
* Relative paths are resolved against workDir first. */
|
||||
function isOutsideWorkDir(filePath: string, workDir: string): boolean {
|
||||
const abs = path.isAbsolute(filePath)
|
||||
? path.normalize(filePath)
|
||||
: path.resolve(workDir, filePath)
|
||||
const normWork = path.normalize(workDir).replace(/\/+$/, '')
|
||||
return abs !== normWork && !abs.startsWith(normWork + path.sep)
|
||||
}
|
||||
|
||||
/** Truncate a single-line target preview (e.g. shell command) to maxLen. */
|
||||
function truncateTarget(s: string, maxLen = 160): string {
|
||||
if (s.length <= maxLen) return s
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import * as path from 'node:path'
|
||||
|
||||
/** True if `filePath` resolves to a location outside of `workDir`.
|
||||
* Relative paths are resolved against workDir first. */
|
||||
export function isOutsideWorkDir(filePath: string, workDir: string): boolean {
|
||||
const pathApi = usesWindowsPath(filePath) || usesWindowsPath(workDir) ? path.win32 : path.posix
|
||||
const abs = pathApi.isAbsolute(filePath)
|
||||
? pathApi.normalize(filePath)
|
||||
: pathApi.resolve(workDir, filePath)
|
||||
const normWork = stripTrailingSeparators(pathApi.normalize(workDir), pathApi)
|
||||
const relative = pathApi.relative(normWork, abs)
|
||||
return relative !== '' && (relative.startsWith('..') || pathApi.isAbsolute(relative))
|
||||
}
|
||||
|
||||
function usesWindowsPath(value: string): boolean {
|
||||
return /^[a-zA-Z]:[\\/]/.test(value) || value.startsWith('\\\\')
|
||||
}
|
||||
|
||||
function stripTrailingSeparators(value: string, pathApi: typeof path.posix | typeof path.win32): string {
|
||||
const root = pathApi.parse(value).root
|
||||
if (value === root) return value
|
||||
return value.replace(/[\\/]+$/, '')
|
||||
}
|
||||
Reference in New Issue
Block a user