@wrongstack/tools 0.296.4 → 0.298.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/dist/_spawn-stream.d.ts +2 -0
- package/dist/_util.d.ts +29 -1
- package/dist/audit.js +128 -65
- package/dist/bash.js +20 -4
- package/dist/batch-tool-use.js +70 -7
- package/dist/browser/index.js +31 -1
- package/dist/builtin.js +883 -351
- package/dist/codebase-index/index.js +95 -16
- package/dist/codebase-index/project-server-protocol.d.ts +26 -0
- package/dist/codebase-index/project-server.js +76 -16
- package/dist/codebase-index/worker.js +36 -13
- package/dist/codebase-index/writer-search-helpers.d.ts +16 -0
- package/dist/codebase-index/writer.d.ts +13 -1
- package/dist/design.d.ts +1 -1
- package/dist/design.js +4 -3
- package/dist/diff.js +11 -1
- package/dist/e2e.js +9 -6
- package/dist/edit.js +9 -6
- package/dist/exec.js +562 -516
- package/dist/format.js +131 -65
- package/dist/git.js +22 -2
- package/dist/glob.js +11 -5
- package/dist/grep.js +160 -104
- package/dist/index.js +834 -290
- package/dist/install.js +135 -68
- package/dist/json.js +64 -18
- package/dist/kanban-board-inputs.d.ts +21 -4
- package/dist/kanban.js +20 -5
- package/dist/languages/index.js +143 -71
- package/dist/lint.js +128 -65
- package/dist/next-steps.d.ts +23 -0
- package/dist/next-steps.js +4 -0
- package/dist/outdated.js +101 -26
- package/dist/pack.js +883 -351
- package/dist/patch.js +11 -1
- package/dist/plan.js +32 -10
- package/dist/process-registry.d.ts +9 -0
- package/dist/process-registry.js +15 -0
- package/dist/ps-slash.js +15 -0
- package/dist/read.js +104 -23
- package/dist/replace.js +11 -3
- package/dist/scaffold.js +9 -6
- package/dist/session-kanban.js +21 -5
- package/dist/task.js +3 -1
- package/dist/test.js +128 -65
- package/dist/todo.js +3 -1
- package/dist/tool-tier.js +883 -351
- package/dist/tool-use.d.ts +1 -1
- package/dist/tool-use.js +28 -4
- package/dist/tree.d.ts +1 -0
- package/dist/tree.js +44 -8
- package/dist/typecheck.js +128 -65
- package/dist/write.js +9 -6
- package/package.json +5 -4
- package/dist/_concurrency.d.ts.map +0 -1
- package/dist/_danger-detect.d.ts.map +0 -1
- package/dist/_edit-match.d.ts.map +0 -1
- package/dist/_env.d.ts.map +0 -1
- package/dist/_fetch-guard.d.ts.map +0 -1
- package/dist/_output-spool.d.ts.map +0 -1
- package/dist/_redact-command.d.ts.map +0 -1
- package/dist/_regex.d.ts.map +0 -1
- package/dist/_session-shell.d.ts.map +0 -1
- package/dist/_shell-pick.d.ts.map +0 -1
- package/dist/_spawn-stream.d.ts.map +0 -1
- package/dist/_syntax-check.d.ts.map +0 -1
- package/dist/_util.d.ts.map +0 -1
- package/dist/_win32-resolve.d.ts.map +0 -1
- package/dist/audit.d.ts.map +0 -1
- package/dist/audit.js.map +0 -7
- package/dist/auto-proceed-loop-guard.d.ts.map +0 -1
- package/dist/auto-proceed-loop-guard.js.map +0 -7
- package/dist/bash-kill-guard.d.ts.map +0 -1
- package/dist/bash.d.ts.map +0 -1
- package/dist/bash.js.map +0 -7
- package/dist/batch-tool-use.d.ts.map +0 -1
- package/dist/batch-tool-use.js.map +0 -7
- package/dist/browser/artifacts.d.ts.map +0 -1
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js.map +0 -7
- package/dist/browser/manager.d.ts.map +0 -1
- package/dist/browser/network-guard-proxy.d.ts.map +0 -1
- package/dist/browser/security.d.ts.map +0 -1
- package/dist/browser/tools.d.ts.map +0 -1
- package/dist/browser/types.d.ts.map +0 -1
- package/dist/builtin.d.ts.map +0 -1
- package/dist/builtin.js.map +0 -7
- package/dist/circuit-breaker.d.ts.map +0 -1
- package/dist/circuit-breaker.js.map +0 -7
- package/dist/codebase-index/background-indexer.d.ts.map +0 -1
- package/dist/codebase-index/bm25.d.ts.map +0 -1
- package/dist/codebase-index/circuit-breaker.d.ts.map +0 -1
- package/dist/codebase-index/codebase-index-tool.d.ts.map +0 -1
- package/dist/codebase-index/codebase-search-tool.d.ts.map +0 -1
- package/dist/codebase-index/codebase-stats-tool.d.ts.map +0 -1
- package/dist/codebase-index/dead-code-scan.d.ts.map +0 -1
- package/dist/codebase-index/generic-parser.d.ts.map +0 -1
- package/dist/codebase-index/gitignore.d.ts.map +0 -1
- package/dist/codebase-index/go-parser.d.ts.map +0 -1
- package/dist/codebase-index/index-service.d.ts.map +0 -1
- package/dist/codebase-index/index.d.ts.map +0 -1
- package/dist/codebase-index/index.js.map +0 -7
- package/dist/codebase-index/indexer.d.ts.map +0 -1
- package/dist/codebase-index/json-parser.d.ts.map +0 -1
- package/dist/codebase-index/languages.d.ts.map +0 -1
- package/dist/codebase-index/lsp-kind.d.ts.map +0 -1
- package/dist/codebase-index/parser-dispatch.d.ts.map +0 -1
- package/dist/codebase-index/project-server-cache.d.ts.map +0 -1
- package/dist/codebase-index/project-server-client.d.ts.map +0 -1
- package/dist/codebase-index/project-server-endpoint.d.ts.map +0 -1
- package/dist/codebase-index/project-server-protocol.d.ts.map +0 -1
- package/dist/codebase-index/project-server.d.ts.map +0 -1
- package/dist/codebase-index/project-server.js.map +0 -7
- package/dist/codebase-index/py-parser.d.ts.map +0 -1
- package/dist/codebase-index/refs-extractor.d.ts.map +0 -1
- package/dist/codebase-index/rs-parser.d.ts.map +0 -1
- package/dist/codebase-index/schema.d.ts.map +0 -1
- package/dist/codebase-index/spawn-gate.d.ts.map +0 -1
- package/dist/codebase-index/sqlite-runtime.d.ts.map +0 -1
- package/dist/codebase-index/ts-parser.d.ts.map +0 -1
- package/dist/codebase-index/worker-protocol.d.ts.map +0 -1
- package/dist/codebase-index/worker.d.ts.map +0 -1
- package/dist/codebase-index/worker.js.map +0 -7
- package/dist/codebase-index/writer-admin.d.ts.map +0 -1
- package/dist/codebase-index/writer-bulk-insert.d.ts.map +0 -1
- package/dist/codebase-index/writer-graph-helpers.d.ts.map +0 -1
- package/dist/codebase-index/writer-graph-reader.d.ts.map +0 -1
- package/dist/codebase-index/writer-helpers.d.ts.map +0 -1
- package/dist/codebase-index/writer-pragmas.d.ts.map +0 -1
- package/dist/codebase-index/writer-ref-mapper.d.ts.map +0 -1
- package/dist/codebase-index/writer-schema.d.ts.map +0 -1
- package/dist/codebase-index/writer-search-helpers.d.ts.map +0 -1
- package/dist/codebase-index/writer-store-pool.d.ts.map +0 -1
- package/dist/codebase-index/writer.d.ts.map +0 -1
- package/dist/codebase-index/yaml-parser.d.ts.map +0 -1
- package/dist/design.d.ts.map +0 -1
- package/dist/design.js.map +0 -7
- package/dist/diff.d.ts.map +0 -1
- package/dist/diff.js.map +0 -7
- package/dist/document.d.ts.map +0 -1
- package/dist/document.js.map +0 -7
- package/dist/e2e.d.ts.map +0 -1
- package/dist/e2e.js.map +0 -7
- package/dist/edit.d.ts.map +0 -1
- package/dist/edit.js.map +0 -7
- package/dist/exec-kill-guard.d.ts.map +0 -1
- package/dist/exec.d.ts.map +0 -1
- package/dist/exec.js.map +0 -7
- package/dist/fetch.d.ts.map +0 -1
- package/dist/fetch.js.map +0 -7
- package/dist/format.d.ts.map +0 -1
- package/dist/format.js.map +0 -7
- package/dist/git.d.ts.map +0 -1
- package/dist/git.js.map +0 -7
- package/dist/glob.d.ts.map +0 -1
- package/dist/glob.js.map +0 -7
- package/dist/grep.d.ts.map +0 -1
- package/dist/grep.js.map +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -7
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js.map +0 -7
- package/dist/json.d.ts.map +0 -1
- package/dist/json.js.map +0 -7
- package/dist/kanban-board-inputs.d.ts.map +0 -1
- package/dist/kanban-decomposition-actions.d.ts.map +0 -1
- package/dist/kanban-detail-actions.d.ts.map +0 -1
- package/dist/kanban-evidence-bridge.d.ts.map +0 -1
- package/dist/kanban-presence.d.ts.map +0 -1
- package/dist/kanban-split-task-handler.d.ts.map +0 -1
- package/dist/kanban-task-inputs.d.ts.map +0 -1
- package/dist/kanban-tool-results.d.ts.map +0 -1
- package/dist/kanban-tool-schema.d.ts.map +0 -1
- package/dist/kanban-tool-types.d.ts.map +0 -1
- package/dist/kanban.d.ts.map +0 -1
- package/dist/kanban.js.map +0 -7
- package/dist/languages/detect.d.ts.map +0 -1
- package/dist/languages/diagnostics.d.ts.map +0 -1
- package/dist/languages/execute-tool.d.ts.map +0 -1
- package/dist/languages/execute.d.ts.map +0 -1
- package/dist/languages/index.d.ts.map +0 -1
- package/dist/languages/index.js.map +0 -7
- package/dist/languages/legacy-bridge.d.ts.map +0 -1
- package/dist/languages/package-tool.d.ts.map +0 -1
- package/dist/languages/plan.d.ts.map +0 -1
- package/dist/languages/profile-helpers.d.ts.map +0 -1
- package/dist/languages/profiles/additional.d.ts.map +0 -1
- package/dist/languages/profiles/primary.d.ts.map +0 -1
- package/dist/languages/registry.d.ts.map +0 -1
- package/dist/languages/tool.d.ts.map +0 -1
- package/dist/languages/types.d.ts.map +0 -1
- package/dist/lint.d.ts.map +0 -1
- package/dist/lint.js.map +0 -7
- package/dist/logs.d.ts.map +0 -1
- package/dist/logs.js.map +0 -7
- package/dist/memory.d.ts.map +0 -1
- package/dist/memory.js.map +0 -7
- package/dist/mode.d.ts.map +0 -1
- package/dist/mode.js.map +0 -7
- package/dist/next-steps.d.ts.map +0 -1
- package/dist/next-steps.js.map +0 -7
- package/dist/outdated.d.ts.map +0 -1
- package/dist/outdated.js.map +0 -7
- package/dist/pack.d.ts.map +0 -1
- package/dist/pack.js.map +0 -7
- package/dist/patch.d.ts.map +0 -1
- package/dist/patch.js.map +0 -7
- package/dist/plan.d.ts.map +0 -1
- package/dist/plan.js.map +0 -7
- package/dist/process-guardian.d.ts.map +0 -1
- package/dist/process-registry-persistent.d.ts.map +0 -1
- package/dist/process-registry.d.ts.map +0 -1
- package/dist/process-registry.js.map +0 -7
- package/dist/ps-slash.d.ts.map +0 -1
- package/dist/ps-slash.js.map +0 -7
- package/dist/read.d.ts.map +0 -1
- package/dist/read.js.map +0 -7
- package/dist/replace.d.ts.map +0 -1
- package/dist/replace.js.map +0 -7
- package/dist/scaffold.d.ts.map +0 -1
- package/dist/scaffold.js.map +0 -7
- package/dist/search.d.ts.map +0 -1
- package/dist/search.js.map +0 -7
- package/dist/session-kanban.d.ts.map +0 -1
- package/dist/session-kanban.js.map +0 -7
- package/dist/set-working-dir.d.ts.map +0 -1
- package/dist/skill.d.ts.map +0 -1
- package/dist/skill.js.map +0 -7
- package/dist/spawn-background.d.ts.map +0 -1
- package/dist/task.d.ts.map +0 -1
- package/dist/task.js.map +0 -7
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js.map +0 -7
- package/dist/todo.d.ts.map +0 -1
- package/dist/todo.js.map +0 -7
- package/dist/tool-diff.d.ts.map +0 -1
- package/dist/tool-diff.js.map +0 -7
- package/dist/tool-help.d.ts.map +0 -1
- package/dist/tool-help.js.map +0 -7
- package/dist/tool-icon-map.d.ts.map +0 -1
- package/dist/tool-icons.d.ts.map +0 -1
- package/dist/tool-icons.js.map +0 -7
- package/dist/tool-search.d.ts.map +0 -1
- package/dist/tool-search.js.map +0 -7
- package/dist/tool-summary.d.ts.map +0 -1
- package/dist/tool-summary.js.map +0 -7
- package/dist/tool-tier.d.ts.map +0 -1
- package/dist/tool-tier.js.map +0 -7
- package/dist/tool-use.d.ts.map +0 -1
- package/dist/tool-use.js.map +0 -7
- package/dist/tree.d.ts.map +0 -1
- package/dist/tree.js.map +0 -7
- package/dist/typecheck.d.ts.map +0 -1
- package/dist/typecheck.js.map +0 -7
- package/dist/win32.d.ts.map +0 -1
- package/dist/win32.js.map +0 -7
- package/dist/write.d.ts.map +0 -1
- package/dist/write.js.map +0 -7
package/dist/tool-use.d.ts
CHANGED
package/dist/tool-use.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
// src/tool-use.ts
|
|
2
|
+
import {
|
|
3
|
+
GOVERNED_TOOL_EXECUTOR_META_KEY
|
|
4
|
+
} from "@wrongstack/core/types";
|
|
2
5
|
var toolUseTool = {
|
|
3
6
|
name: "tool_use",
|
|
4
7
|
category: "Meta",
|
|
5
8
|
description: "Directly execute any registered tool by its exact name, bypassing normal discovery. This is a powerful meta-tool intended for cases where the agent has a clear plan and knows precisely which tool to invoke.",
|
|
6
9
|
usageHint: "ADVANCED META TOOL \u2014 USE WITH CARE:\n\n- Only use when you are certain of the exact tool name and its expected input shape.\n- Prefer using the normal tool calling mechanism when possible.\n- Very useful in batch-tool-use or when orchestrating complex workflows programmatically.\n- The call still goes through full permission checks and capability validation.",
|
|
7
10
|
permission: "confirm",
|
|
11
|
+
// WS-046: gives permission decisions something to key on.
|
|
12
|
+
// The tool being invoked through this indirection — the whole point of a
|
|
13
|
+
// permission decision here is WHICH tool is being reached.
|
|
14
|
+
subjectKey: "tool",
|
|
8
15
|
mutating: true,
|
|
9
16
|
timeoutMs: 6e4,
|
|
10
17
|
capabilities: ["tool.mutate.any"],
|
|
@@ -23,7 +30,7 @@ var toolUseTool = {
|
|
|
23
30
|
},
|
|
24
31
|
required: ["tool"]
|
|
25
32
|
},
|
|
26
|
-
async execute(input, ctx
|
|
33
|
+
async execute(input, ctx) {
|
|
27
34
|
const start = Date.now();
|
|
28
35
|
if (!input?.tool) {
|
|
29
36
|
return {
|
|
@@ -42,6 +49,14 @@ var toolUseTool = {
|
|
|
42
49
|
executionMs: Date.now() - start
|
|
43
50
|
};
|
|
44
51
|
}
|
|
52
|
+
if (tool.name === toolUseTool.name) {
|
|
53
|
+
return {
|
|
54
|
+
tool: input.tool,
|
|
55
|
+
success: false,
|
|
56
|
+
error: "tool_use: recursive meta-tool execution is not allowed",
|
|
57
|
+
executionMs: Date.now() - start
|
|
58
|
+
};
|
|
59
|
+
}
|
|
45
60
|
if (tool.permission === "deny") {
|
|
46
61
|
return {
|
|
47
62
|
tool: input.tool,
|
|
@@ -50,12 +65,21 @@ var toolUseTool = {
|
|
|
50
65
|
executionMs: Date.now() - start
|
|
51
66
|
};
|
|
52
67
|
}
|
|
68
|
+
const governedExecute = ctx.meta[GOVERNED_TOOL_EXECUTOR_META_KEY];
|
|
69
|
+
if (typeof governedExecute !== "function") {
|
|
70
|
+
return {
|
|
71
|
+
tool: input.tool,
|
|
72
|
+
success: false,
|
|
73
|
+
error: "tool_use: governed nested execution is unavailable; call the tool directly",
|
|
74
|
+
executionMs: Date.now() - start
|
|
75
|
+
};
|
|
76
|
+
}
|
|
53
77
|
try {
|
|
54
|
-
const result = await
|
|
78
|
+
const result = await governedExecute(input.tool, input.input ?? {});
|
|
55
79
|
return {
|
|
56
80
|
tool: input.tool,
|
|
57
|
-
success:
|
|
58
|
-
result,
|
|
81
|
+
success: result.success,
|
|
82
|
+
...result.success ? { result: result.result } : { error: result.error ?? "nested tool failed" },
|
|
59
83
|
executionMs: Date.now() - start
|
|
60
84
|
};
|
|
61
85
|
} catch (e) {
|
package/dist/tree.d.ts
CHANGED
package/dist/tree.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/tree.ts
|
|
2
|
-
import { DEFAULT_WALK_IGNORE_DIRS, expectDefined } from "@wrongstack/core/utils";
|
|
3
2
|
import * as fs from "node:fs/promises";
|
|
4
3
|
import * as path2 from "node:path";
|
|
4
|
+
import { DEFAULT_WALK_IGNORE_DIRS, expectDefined } from "@wrongstack/core/utils";
|
|
5
5
|
|
|
6
6
|
// src/_util.ts
|
|
7
7
|
import * as path from "node:path";
|
|
@@ -30,6 +30,8 @@ function safeResolve(input, ctx) {
|
|
|
30
30
|
|
|
31
31
|
// src/tree.ts
|
|
32
32
|
var DEFAULT_IGNORE = [...DEFAULT_WALK_IGNORE_DIRS, ".wrongstack", ".ssh", ".gnupg", ".aws"];
|
|
33
|
+
var DEFAULT_MAX_ENTRIES = 5e3;
|
|
34
|
+
var MAX_TREE_OUTPUT_BYTES = 256 * 1024;
|
|
33
35
|
var treeTool = {
|
|
34
36
|
name: "tree",
|
|
35
37
|
category: "Filesystem",
|
|
@@ -73,6 +75,12 @@ var treeTool = {
|
|
|
73
75
|
show_hidden: {
|
|
74
76
|
type: "boolean",
|
|
75
77
|
description: "Show hidden files starting with . (default: false)"
|
|
78
|
+
},
|
|
79
|
+
max_entries: {
|
|
80
|
+
type: "integer",
|
|
81
|
+
description: `Maximum entries retained in the rendered tree (default ${DEFAULT_MAX_ENTRIES}).`,
|
|
82
|
+
minimum: 1,
|
|
83
|
+
maximum: 5e4
|
|
76
84
|
}
|
|
77
85
|
}
|
|
78
86
|
},
|
|
@@ -86,7 +94,7 @@ var treeTool = {
|
|
|
86
94
|
if (!final) throw new Error("tree: stream ended without final event");
|
|
87
95
|
return final;
|
|
88
96
|
},
|
|
89
|
-
async *executeStream(input, ctx) {
|
|
97
|
+
async *executeStream(input, ctx, opts) {
|
|
90
98
|
const basePath = input.path ? safeResolve(input.path, ctx) : ctx.cwd;
|
|
91
99
|
const maxDepth = input.depth ?? 3;
|
|
92
100
|
const showFiles = input.show_files ?? true;
|
|
@@ -94,8 +102,17 @@ var treeTool = {
|
|
|
94
102
|
const showHidden = input.show_hidden ?? false;
|
|
95
103
|
const exclude = /* @__PURE__ */ new Set([...DEFAULT_IGNORE, ...input.exclude ?? []]);
|
|
96
104
|
const filterGlob = input.glob;
|
|
105
|
+
const maxEntries = input.max_entries ?? DEFAULT_MAX_ENTRIES;
|
|
106
|
+
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
97
107
|
const lines = [basePath];
|
|
98
108
|
const totals = { totalFiles: { value: 0 }, totalDirs: { value: 0 } };
|
|
109
|
+
const retention = {
|
|
110
|
+
entries: 0,
|
|
111
|
+
outputBytes: Buffer.byteLength(basePath, "utf8"),
|
|
112
|
+
maxEntries,
|
|
113
|
+
maxOutputBytes: MAX_TREE_OUTPUT_BYTES,
|
|
114
|
+
truncated: false
|
|
115
|
+
};
|
|
99
116
|
const queue = [];
|
|
100
117
|
const FLUSH_EVERY = 200;
|
|
101
118
|
let lastEmittedTotal = 0;
|
|
@@ -122,12 +139,19 @@ var treeTool = {
|
|
|
122
139
|
isLast: true,
|
|
123
140
|
totalFiles: totals.totalFiles,
|
|
124
141
|
totalDirs: totals.totalDirs,
|
|
125
|
-
onProgress: tickProgress
|
|
142
|
+
onProgress: tickProgress,
|
|
143
|
+
retention,
|
|
144
|
+
signal
|
|
126
145
|
});
|
|
127
146
|
let walkDone = false;
|
|
128
|
-
walkPromise.
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
void walkPromise.then(
|
|
148
|
+
() => {
|
|
149
|
+
walkDone = true;
|
|
150
|
+
},
|
|
151
|
+
() => {
|
|
152
|
+
walkDone = true;
|
|
153
|
+
}
|
|
154
|
+
);
|
|
131
155
|
while (!walkDone || queue.length > 0) {
|
|
132
156
|
if (queue.length > 0) {
|
|
133
157
|
yield expectDefined(queue.shift());
|
|
@@ -150,13 +174,15 @@ var treeTool = {
|
|
|
150
174
|
tree: lines.join("\n"),
|
|
151
175
|
total_files: totals.totalFiles.value,
|
|
152
176
|
total_dirs: totals.totalDirs.value,
|
|
153
|
-
truncated:
|
|
177
|
+
truncated: retention.truncated,
|
|
154
178
|
path: basePath
|
|
155
179
|
}
|
|
156
180
|
};
|
|
157
181
|
}
|
|
158
182
|
};
|
|
159
183
|
async function walkDir(dir, depth, opts) {
|
|
184
|
+
opts.signal.throwIfAborted();
|
|
185
|
+
if (opts.retention.truncated) return;
|
|
160
186
|
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
161
187
|
const filtered = entries.filter((e) => {
|
|
162
188
|
if (!opts.showHidden && e.name.startsWith(".")) return false;
|
|
@@ -176,6 +202,8 @@ async function walkDir(dir, depth, opts) {
|
|
|
176
202
|
return a.name.localeCompare(b.name);
|
|
177
203
|
});
|
|
178
204
|
for (let i = 0; i < items.length; i++) {
|
|
205
|
+
opts.signal.throwIfAborted();
|
|
206
|
+
if (opts.retention.truncated) return;
|
|
179
207
|
const entry = items[i];
|
|
180
208
|
if (!entry) continue;
|
|
181
209
|
const isLast = i === items.length - 1;
|
|
@@ -184,7 +212,15 @@ async function walkDir(dir, depth, opts) {
|
|
|
184
212
|
const displayName = entry.name + (entry.isDirectory() ? "/" : "");
|
|
185
213
|
if (!opts.showDirs && entry.isDirectory()) continue;
|
|
186
214
|
if (!opts.showFiles && entry.isFile()) continue;
|
|
187
|
-
opts.
|
|
215
|
+
const line = opts.prefix + branch + displayName;
|
|
216
|
+
const lineBytes = Buffer.byteLength(line, "utf8") + 1;
|
|
217
|
+
if (opts.retention.entries >= opts.retention.maxEntries || opts.retention.outputBytes + lineBytes > opts.retention.maxOutputBytes) {
|
|
218
|
+
opts.retention.truncated = true;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
opts.lines.push(line);
|
|
222
|
+
opts.retention.entries++;
|
|
223
|
+
opts.retention.outputBytes += lineBytes;
|
|
188
224
|
if (entry.isDirectory() && (opts.maxDepth === 0 || depth < opts.maxDepth)) {
|
|
189
225
|
const childPrefix = opts.prefix + connector;
|
|
190
226
|
await walkDir(path2.join(dir, entry.name), depth + 1, {
|
package/dist/typecheck.js
CHANGED
|
@@ -81,11 +81,12 @@ function createOutputSpool(opts) {
|
|
|
81
81
|
return {
|
|
82
82
|
write(text) {
|
|
83
83
|
if (finalized || !text) return;
|
|
84
|
-
|
|
84
|
+
const textBytes = Buffer.byteLength(text, "utf8");
|
|
85
|
+
totalBytes += textBytes;
|
|
85
86
|
if (!stream && !failed) {
|
|
86
|
-
if (headBytes +
|
|
87
|
+
if (headBytes + textBytes <= threshold) {
|
|
87
88
|
head += text;
|
|
88
|
-
headBytes +=
|
|
89
|
+
headBytes += textBytes;
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
92
|
head += text;
|
|
@@ -95,7 +96,7 @@ function createOutputSpool(opts) {
|
|
|
95
96
|
}
|
|
96
97
|
if (stream) {
|
|
97
98
|
if (stream.writableLength > SPOOL_WRITE_HWM_BYTES) {
|
|
98
|
-
droppedBytes +=
|
|
99
|
+
droppedBytes += textBytes;
|
|
99
100
|
return;
|
|
100
101
|
}
|
|
101
102
|
stream.write(text);
|
|
@@ -117,6 +118,52 @@ function createOutputSpool(opts) {
|
|
|
117
118
|
};
|
|
118
119
|
}
|
|
119
120
|
|
|
121
|
+
// src/_win32-resolve.ts
|
|
122
|
+
import * as fs from "node:fs";
|
|
123
|
+
import * as path2 from "node:path";
|
|
124
|
+
function resolveWin32Command(cmd) {
|
|
125
|
+
if (process.platform !== "win32") return cmd;
|
|
126
|
+
if (cmd.includes("/") || cmd.includes("\\") || path2.extname(cmd.replace(/\//g, "\\"))) {
|
|
127
|
+
return cmd;
|
|
128
|
+
}
|
|
129
|
+
const pathext = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC").toLowerCase().split(";");
|
|
130
|
+
const pathDirs = (process.env["PATH"] ?? "").split(path2.delimiter);
|
|
131
|
+
for (const dir of pathDirs) {
|
|
132
|
+
const base = path2.join(dir, cmd);
|
|
133
|
+
for (const ext of pathext) {
|
|
134
|
+
const full = `${base}${ext}`;
|
|
135
|
+
try {
|
|
136
|
+
fs.accessSync(full, fs.constants.X_OK);
|
|
137
|
+
return full;
|
|
138
|
+
} catch {
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return cmd;
|
|
143
|
+
}
|
|
144
|
+
var WIN32_SHELL_META = /[&|<>"\r\n\0]/;
|
|
145
|
+
function assertSafeWin32ShellArgs(args) {
|
|
146
|
+
for (const arg of args) {
|
|
147
|
+
if (typeof arg === "string" && WIN32_SHELL_META.test(arg)) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function buildWin32CmdShimInvocation(command, args = []) {
|
|
155
|
+
assertSafeWin32ShellArgs([command, ...args]);
|
|
156
|
+
const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
157
|
+
return {
|
|
158
|
+
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
159
|
+
args: ["/d", "/c", line],
|
|
160
|
+
windowsVerbatimArguments: true
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function quoteWin32CmdArg(arg) {
|
|
164
|
+
return `"${arg}"`;
|
|
165
|
+
}
|
|
166
|
+
|
|
120
167
|
// src/process-registry.ts
|
|
121
168
|
import { spawn } from "node:child_process";
|
|
122
169
|
import * as os from "node:os";
|
|
@@ -448,6 +495,7 @@ var ProcessRegistryImpl = class {
|
|
|
448
495
|
}
|
|
449
496
|
/** Get all tracked processes. */
|
|
450
497
|
list() {
|
|
498
|
+
this._pruneAllStale();
|
|
451
499
|
return Array.from(this.processes.values());
|
|
452
500
|
}
|
|
453
501
|
/** Get processes filtered by name (e.g. 'bash', 'exec'). */
|
|
@@ -478,6 +526,7 @@ var ProcessRegistryImpl = class {
|
|
|
478
526
|
* Combined stats for observability — used by /ps and the TUI status bar.
|
|
479
527
|
*/
|
|
480
528
|
stats() {
|
|
529
|
+
this._pruneAllStale();
|
|
481
530
|
return {
|
|
482
531
|
activeCount: this.activeCount,
|
|
483
532
|
backgroundCount: this.activeBackgroundCount,
|
|
@@ -717,6 +766,19 @@ var ProcessRegistryImpl = class {
|
|
|
717
766
|
this.processes.delete(pid);
|
|
718
767
|
}
|
|
719
768
|
}
|
|
769
|
+
/**
|
|
770
|
+
* Remove every stale entry, not just one PID. `list()`/`stats()` — the
|
|
771
|
+
* surfaces the TUI status bar and `/ps` poll — must prune too: a child
|
|
772
|
+
* whose 'close' event never fires (e.g. Windows grandchildren holding stdio
|
|
773
|
+
* open) would otherwise linger in the registry until someone looks up its
|
|
774
|
+
* exact PID, and PID reuse meanwhile makes `get()`/`kill()` target the
|
|
775
|
+
* wrong process. RAM-leak audit 2026-07-31, MEDIUM.
|
|
776
|
+
*/
|
|
777
|
+
_pruneAllStale() {
|
|
778
|
+
for (const [pid, entry] of this.processes) {
|
|
779
|
+
if (this._isStaleEntry(entry)) this.processes.delete(pid);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
720
782
|
};
|
|
721
783
|
var _registry;
|
|
722
784
|
function getProcessRegistry() {
|
|
@@ -726,60 +788,17 @@ function getProcessRegistry() {
|
|
|
726
788
|
return _registry;
|
|
727
789
|
}
|
|
728
790
|
|
|
729
|
-
// src/_win32-resolve.ts
|
|
730
|
-
import * as fs from "node:fs";
|
|
731
|
-
import * as path2 from "node:path";
|
|
732
|
-
function resolveWin32Command(cmd) {
|
|
733
|
-
if (process.platform !== "win32") return cmd;
|
|
734
|
-
if (cmd.includes("/") || cmd.includes("\\") || path2.extname(cmd.replace(/\//g, "\\"))) {
|
|
735
|
-
return cmd;
|
|
736
|
-
}
|
|
737
|
-
const pathext = (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC").toLowerCase().split(";");
|
|
738
|
-
const pathDirs = (process.env["PATH"] ?? "").split(path2.delimiter);
|
|
739
|
-
for (const dir of pathDirs) {
|
|
740
|
-
const base = path2.join(dir, cmd);
|
|
741
|
-
for (const ext of pathext) {
|
|
742
|
-
const full = `${base}${ext}`;
|
|
743
|
-
try {
|
|
744
|
-
fs.accessSync(full, fs.constants.X_OK);
|
|
745
|
-
return full;
|
|
746
|
-
} catch {
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
return cmd;
|
|
751
|
-
}
|
|
752
|
-
var WIN32_SHELL_META = /[&|<>"\r\n\0]/;
|
|
753
|
-
function assertSafeWin32ShellArgs(args) {
|
|
754
|
-
for (const arg of args) {
|
|
755
|
-
if (typeof arg === "string" && WIN32_SHELL_META.test(arg)) {
|
|
756
|
-
throw new Error(
|
|
757
|
-
'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
|
|
758
|
-
);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
function buildWin32CmdShimInvocation(command, args = []) {
|
|
763
|
-
assertSafeWin32ShellArgs([command, ...args]);
|
|
764
|
-
const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
765
|
-
return {
|
|
766
|
-
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
767
|
-
args: ["/d", "/c", line],
|
|
768
|
-
windowsVerbatimArguments: true
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
function quoteWin32CmdArg(arg) {
|
|
772
|
-
return `"${arg}"`;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
791
|
// src/_spawn-stream.ts
|
|
776
792
|
var isWin = process.platform === "win32";
|
|
777
793
|
async function* spawnStream(opts) {
|
|
778
794
|
const max = opts.maxBytes ?? 2e5;
|
|
779
795
|
const flushAt = opts.flushBytes ?? 4 * 1024;
|
|
780
796
|
const maxQueue = opts.maxQueueSize ?? 500;
|
|
797
|
+
const maxQueueBytes = opts.maxQueueBytes ?? 1024 * 1024;
|
|
781
798
|
let stdout = "";
|
|
782
799
|
let stderr = "";
|
|
800
|
+
let stdoutRetainedBytes = 0;
|
|
801
|
+
let stderrRetainedBytes = 0;
|
|
783
802
|
let pending = "";
|
|
784
803
|
let error;
|
|
785
804
|
const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });
|
|
@@ -821,6 +840,7 @@ async function* spawnStream(opts) {
|
|
|
821
840
|
});
|
|
822
841
|
}
|
|
823
842
|
const queue = [];
|
|
843
|
+
let queuedBytes = 0;
|
|
824
844
|
let waiter;
|
|
825
845
|
let paused = false;
|
|
826
846
|
const wake = () => {
|
|
@@ -831,7 +851,7 @@ async function* spawnStream(opts) {
|
|
|
831
851
|
}
|
|
832
852
|
};
|
|
833
853
|
const resume = () => {
|
|
834
|
-
if (paused && queue.length
|
|
854
|
+
if (paused && queue.length <= Math.floor(maxQueue / 2) && queuedBytes <= Math.floor(maxQueueBytes / 2)) {
|
|
835
855
|
paused = false;
|
|
836
856
|
child.stdout?.resume();
|
|
837
857
|
child.stderr?.resume();
|
|
@@ -841,11 +861,16 @@ async function* spawnStream(opts) {
|
|
|
841
861
|
const s = c.toString();
|
|
842
862
|
stdoutBytes += c.byteLength;
|
|
843
863
|
emitProcessOutput({ pid, stream: "stdout", chunk: c });
|
|
844
|
-
if (
|
|
864
|
+
if (stdoutRetainedBytes < max) {
|
|
865
|
+
const retained = utf8Prefix(s, max - stdoutRetainedBytes);
|
|
866
|
+
stdout += retained;
|
|
867
|
+
stdoutRetainedBytes += Buffer.byteLength(retained, "utf8");
|
|
868
|
+
}
|
|
845
869
|
spool.write(s);
|
|
846
|
-
queue.push({ kind: "out", data: s });
|
|
870
|
+
queue.push({ kind: "out", data: s, bytes: c.byteLength });
|
|
871
|
+
queuedBytes += c.byteLength;
|
|
847
872
|
wake();
|
|
848
|
-
if (!paused && queue.length >= maxQueue) {
|
|
873
|
+
if (!paused && (queue.length >= maxQueue || queuedBytes >= maxQueueBytes)) {
|
|
849
874
|
paused = true;
|
|
850
875
|
child.stdout?.pause();
|
|
851
876
|
child.stderr?.pause();
|
|
@@ -855,11 +880,16 @@ async function* spawnStream(opts) {
|
|
|
855
880
|
const s = c.toString();
|
|
856
881
|
stderrBytes += c.byteLength;
|
|
857
882
|
emitProcessOutput({ pid, stream: "stderr", chunk: c });
|
|
858
|
-
if (
|
|
883
|
+
if (stderrRetainedBytes < max) {
|
|
884
|
+
const retained = utf8Prefix(s, max - stderrRetainedBytes);
|
|
885
|
+
stderr += retained;
|
|
886
|
+
stderrRetainedBytes += Buffer.byteLength(retained, "utf8");
|
|
887
|
+
}
|
|
859
888
|
spool.write(s);
|
|
860
|
-
queue.push({ kind: "err", data: s });
|
|
889
|
+
queue.push({ kind: "err", data: s, bytes: c.byteLength });
|
|
890
|
+
queuedBytes += c.byteLength;
|
|
861
891
|
wake();
|
|
862
|
-
if (!paused && queue.length >= maxQueue) {
|
|
892
|
+
if (!paused && (queue.length >= maxQueue || queuedBytes >= maxQueueBytes)) {
|
|
863
893
|
paused = true;
|
|
864
894
|
child.stdout?.pause();
|
|
865
895
|
child.stderr?.pause();
|
|
@@ -869,7 +899,9 @@ async function* spawnStream(opts) {
|
|
|
869
899
|
child.stderr?.on("data", onErr);
|
|
870
900
|
child.on("error", (e) => {
|
|
871
901
|
error = e.message;
|
|
872
|
-
|
|
902
|
+
const bytes = Buffer.byteLength(e.message, "utf8");
|
|
903
|
+
queue.push({ kind: "error", data: e.message, bytes });
|
|
904
|
+
queuedBytes += bytes;
|
|
873
905
|
wake();
|
|
874
906
|
});
|
|
875
907
|
const completeTelemetry = (code, signal, timedOut = false) => {
|
|
@@ -890,7 +922,13 @@ async function* spawnStream(opts) {
|
|
|
890
922
|
if (typeof pid === "number") registry.unregister(pid);
|
|
891
923
|
const exitCode2 = code ?? (signal ? 1 : 0);
|
|
892
924
|
completeTelemetry(exitCode2, signal ?? void 0);
|
|
893
|
-
queue.push({
|
|
925
|
+
queue.push({
|
|
926
|
+
kind: "close",
|
|
927
|
+
data: "",
|
|
928
|
+
bytes: 0,
|
|
929
|
+
code: exitCode2,
|
|
930
|
+
...signal ? { signal } : {}
|
|
931
|
+
});
|
|
894
932
|
wake();
|
|
895
933
|
});
|
|
896
934
|
const onAbort = () => {
|
|
@@ -902,7 +940,7 @@ async function* spawnStream(opts) {
|
|
|
902
940
|
} catch {
|
|
903
941
|
}
|
|
904
942
|
}
|
|
905
|
-
queue.push({ kind: "close", data: "", code: 124 });
|
|
943
|
+
queue.push({ kind: "close", data: "", bytes: 0, code: 124 });
|
|
906
944
|
completeTelemetry(124, "SIGKILL", true);
|
|
907
945
|
wake();
|
|
908
946
|
};
|
|
@@ -920,6 +958,7 @@ async function* spawnStream(opts) {
|
|
|
920
958
|
});
|
|
921
959
|
}
|
|
922
960
|
const chunk = queue.shift();
|
|
961
|
+
queuedBytes -= chunk.bytes;
|
|
923
962
|
resume();
|
|
924
963
|
if (chunk.kind === "close") {
|
|
925
964
|
if (!spawnFailed) exitCode = chunk.code ?? 0;
|
|
@@ -946,7 +985,7 @@ async function* spawnStream(opts) {
|
|
|
946
985
|
stdout: spooled ? stdout + spoolNote(spooled) : stdout,
|
|
947
986
|
stderr,
|
|
948
987
|
exitCode,
|
|
949
|
-
truncated:
|
|
988
|
+
truncated: stdoutBytes > stdoutRetainedBytes || stderrBytes > stderrRetainedBytes,
|
|
950
989
|
error,
|
|
951
990
|
spoolPath: spooled?.path,
|
|
952
991
|
spoolBytes: spooled?.bytes
|
|
@@ -970,6 +1009,20 @@ async function* spawnStream(opts) {
|
|
|
970
1009
|
}
|
|
971
1010
|
}
|
|
972
1011
|
}
|
|
1012
|
+
function utf8Prefix(text, maxBytes) {
|
|
1013
|
+
if (maxBytes <= 0) return "";
|
|
1014
|
+
if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
|
|
1015
|
+
let low = 0;
|
|
1016
|
+
let high = text.length;
|
|
1017
|
+
while (low < high) {
|
|
1018
|
+
const mid = Math.ceil((low + high) / 2);
|
|
1019
|
+
if (Buffer.byteLength(text.slice(0, mid), "utf8") <= maxBytes) low = mid;
|
|
1020
|
+
else high = mid - 1;
|
|
1021
|
+
}
|
|
1022
|
+
let end = low;
|
|
1023
|
+
if (end > 0 && /[\uD800-\uDBFF]/.test(text[end - 1])) end--;
|
|
1024
|
+
return text.slice(0, end);
|
|
1025
|
+
}
|
|
973
1026
|
|
|
974
1027
|
// src/_util.ts
|
|
975
1028
|
import * as path3 from "node:path";
|
|
@@ -2537,8 +2590,8 @@ async function scanDirectory(directory, depth, profiles, limits, state, extraIgn
|
|
|
2537
2590
|
collectFileEvidence(directory, fullPath, entry.name, profiles, state);
|
|
2538
2591
|
}
|
|
2539
2592
|
}
|
|
2540
|
-
function collectFileEvidence(directory, fullPath,
|
|
2541
|
-
const lower =
|
|
2593
|
+
function collectFileEvidence(directory, fullPath, basename5, profiles, state) {
|
|
2594
|
+
const lower = basename5.toLowerCase();
|
|
2542
2595
|
const extension = path4.extname(lower);
|
|
2543
2596
|
for (const profile of profiles) {
|
|
2544
2597
|
const detector = profile.detectors.find(
|
|
@@ -2549,7 +2602,7 @@ function collectFileEvidence(directory, fullPath, basename4, profiles, state) {
|
|
|
2549
2602
|
candidate.evidence.push({
|
|
2550
2603
|
kind: detector.kind,
|
|
2551
2604
|
path: fullPath,
|
|
2552
|
-
value:
|
|
2605
|
+
value: basename5,
|
|
2553
2606
|
weight: detector.weight
|
|
2554
2607
|
});
|
|
2555
2608
|
if (detector.kind === "manifest" || detector.kind === "config") {
|
|
@@ -2969,10 +3022,11 @@ var MAX_ARGUMENTS = 128;
|
|
|
2969
3022
|
var MAX_ARGUMENT_LENGTH = 4096;
|
|
2970
3023
|
var PACKAGE_NAME_RE = /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+(?:@[a-z0-9*+._~^<>=|-]+)?$/i;
|
|
2971
3024
|
var COMPOSER_PACKAGE_RE = /^[a-z0-9_.-]+\/[a-z0-9_.-]+(?::[a-z0-9*+._~^<>=|-]+)?$/i;
|
|
2972
|
-
var GO_MODULE_RE = /^(?:[a-z0-9
|
|
3025
|
+
var GO_MODULE_RE = /^(?:[a-z0-9-]+\.)+[a-z0-9-]+\/[a-z0-9._~+/@-]+$/i;
|
|
2973
3026
|
var PYTHON_PACKAGE_RE = /^[a-z0-9._-]+(?:\[[a-z0-9._,-]+\])?==[a-z0-9*+._!~-]+$/i;
|
|
2974
3027
|
async function planLanguageOperation(options) {
|
|
2975
3028
|
validateOperationOptions(options.operation, options.operationOptions?.packages);
|
|
3029
|
+
validateFilterOption(options.operationOptions?.filter);
|
|
2976
3030
|
const detection = await detectLanguageWorkspaces(options);
|
|
2977
3031
|
const candidates = detection.workspaces.filter(
|
|
2978
3032
|
(workspace) => workspace.capabilities.includes(options.operation)
|
|
@@ -3145,6 +3199,15 @@ function workspaceDepth(workspaceRoot, projectRoot) {
|
|
|
3145
3199
|
const relative5 = path6.relative(path6.resolve(projectRoot), path6.resolve(workspaceRoot));
|
|
3146
3200
|
return relative5 === "" ? 0 : relative5.split(path6.sep).length;
|
|
3147
3201
|
}
|
|
3202
|
+
function validateFilterOption(filter) {
|
|
3203
|
+
if (filter === void 0) return;
|
|
3204
|
+
if (filter.startsWith("-") || filter.includes(" --")) {
|
|
3205
|
+
throw new Error(`Invalid test filter (parsed as a runner option): "${filter}"`);
|
|
3206
|
+
}
|
|
3207
|
+
if (filter.length > MAX_ARGUMENT_LENGTH || /[\r\n\0]/.test(filter)) {
|
|
3208
|
+
throw new Error("Invalid test filter (oversized or contains a control character)");
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3148
3211
|
function validateOperationOptions(operation, packages) {
|
|
3149
3212
|
if (!operation.startsWith("package-") || !packages) return;
|
|
3150
3213
|
for (const value of packages) {
|
package/dist/write.js
CHANGED
|
@@ -117,12 +117,13 @@ function ensureInsideRoot(absPath, ctx) {
|
|
|
117
117
|
function safeResolve(input, ctx) {
|
|
118
118
|
return ensureInsideRoot(resolvePath(input, ctx), ctx);
|
|
119
119
|
}
|
|
120
|
-
async function
|
|
121
|
-
if (ctx.allowOutsideProjectRoot) return;
|
|
120
|
+
async function resolveRealInsideRoot(absPath, ctx) {
|
|
121
|
+
if (ctx.allowOutsideProjectRoot) return absPath;
|
|
122
122
|
const realRoots = await Promise.all(
|
|
123
123
|
allowedRoots(ctx).map((r) => fsp.realpath(r).catch(() => path2.resolve(r)))
|
|
124
124
|
);
|
|
125
125
|
let probe = absPath;
|
|
126
|
+
const pendingTail = [];
|
|
126
127
|
for (; ; ) {
|
|
127
128
|
let real;
|
|
128
129
|
try {
|
|
@@ -130,13 +131,16 @@ async function assertRealInsideRoot(absPath, ctx) {
|
|
|
130
131
|
} catch (err) {
|
|
131
132
|
if (err.code === "ENOENT") {
|
|
132
133
|
const parent = path2.dirname(probe);
|
|
133
|
-
if (parent === probe) return;
|
|
134
|
+
if (parent === probe) return absPath;
|
|
135
|
+
pendingTail.unshift(path2.basename(probe));
|
|
134
136
|
probe = parent;
|
|
135
137
|
continue;
|
|
136
138
|
}
|
|
137
139
|
throw err;
|
|
138
140
|
}
|
|
139
|
-
if (isInsideAny(real, realRoots))
|
|
141
|
+
if (isInsideAny(real, realRoots)) {
|
|
142
|
+
return pendingTail.length > 0 ? path2.join(real, ...pendingTail) : real;
|
|
143
|
+
}
|
|
140
144
|
throw new Error(
|
|
141
145
|
`Path "${absPath}" resolves through a symlink outside project root "${realRoots[0]}"`
|
|
142
146
|
);
|
|
@@ -144,8 +148,7 @@ async function assertRealInsideRoot(absPath, ctx) {
|
|
|
144
148
|
}
|
|
145
149
|
async function safeResolveReal(input, ctx) {
|
|
146
150
|
const abs = safeResolve(input, ctx);
|
|
147
|
-
await
|
|
148
|
-
return abs;
|
|
151
|
+
return await resolveRealInsideRoot(abs, ctx);
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
// src/write.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.298.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack built-in tools: read/write/edit, bash/exec, grep/glob, git, fetch, test, lint, and more.",
|
|
6
6
|
"repository": {
|
|
@@ -242,15 +242,16 @@
|
|
|
242
242
|
}
|
|
243
243
|
},
|
|
244
244
|
"files": [
|
|
245
|
-
"dist"
|
|
245
|
+
"dist",
|
|
246
|
+
"!dist/**/*.map"
|
|
246
247
|
],
|
|
247
248
|
"dependencies": {
|
|
248
249
|
"@playwright/test": "^1.62.0",
|
|
249
250
|
"@typescript/typescript6": "^6.0.2",
|
|
250
251
|
"turndown": "^7.2.4",
|
|
251
252
|
"undici": "^8.9.0",
|
|
252
|
-
"@wrongstack/core": "0.
|
|
253
|
-
"@wrongstack/kanban": "0.
|
|
253
|
+
"@wrongstack/core": "0.298.0",
|
|
254
|
+
"@wrongstack/kanban": "0.298.0"
|
|
254
255
|
},
|
|
255
256
|
"devDependencies": {
|
|
256
257
|
"@types/node": "^26.1.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_concurrency.d.ts","sourceRoot":"","sources":["../src/_concurrency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAC3C,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,EAAE,CAAC,CAgBd"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_danger-detect.d.ts","sourceRoot":"","sources":["../src/_danger-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA2TD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,gBAAgB,CAqBlB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_edit-match.d.ts","sourceRoot":"","sources":["../src/_edit-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,qBAAqB,GAAG,uBAAuB,GAAG,OAAO,CAAC;AAE5F,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,uEAAuE;AACvE,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAMhD,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAKlF,CAAC;AAYF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CA+CzF;AA4HD,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvD;AAyBD,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAkBrC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0B/C"}
|
package/dist/_env.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_env.d.ts","sourceRoot":"","sources":["../src/_env.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_fetch-guard.d.ts","sourceRoot":"","sources":["../src/_fetch-guard.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,aAAa,SAAwD,CAAC;AAUnF,KAAK,cAAc,GAAG,CACpB,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EACjC,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,EACzE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,KACxB,IAAI,CAAC;AAEV;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACnE,QAAQ,EAAE,cAAc,GACvB,IAAI,CAsCN;AA6CD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG7B,GACA,OAAO,CAAC,QAAQ,CAAC,CAuDnB;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDtE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_output-spool.d.ts","sourceRoot":"","sources":["../src/_output-spool.ts"],"names":[],"mappings":"AAmCA,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAwBD,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,QAAQ,IAAI,SAAS,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAIjD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,WAAW,CA+E7E"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_redact-command.d.ts","sourceRoot":"","sources":["../src/_redact-command.ts"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA6BjD"}
|
package/dist/_regex.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_regex.d.ts","sourceRoot":"","sources":["../src/_regex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAkBH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,CA2B5F;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAY,CAAC;AAEzC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_session-shell.d.ts","sourceRoot":"","sources":["../src/_session-shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAM/E;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,GAAG,EAAE;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,EAC7C,IAAI,GAAE,uBAA4B,GACjC,SAAS,GAAG,SAAS,CAYvB;AAED,MAAM,WAAW,yBAAyB;IACxC,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;IACpC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC;IACvC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,yBAA8B,GAAG,SAAS,GAAG,SAAS,CAa9F"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_shell-pick.d.ts","sourceRoot":"","sources":["../src/_shell-pick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,GAAG,MAAM,CAAC;AAEtD,wEAAwE;AACxE,eAAO,MAAM,aAAa,EAAE,SAAiB,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,YAAY,GAChB,SAAS,CAgBX;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA2D5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAuCpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAU5D;AAyCD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAKpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAgDrF"}
|