@bilalimamoglu/sift 0.4.3 → 0.4.4
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 +1 -0
- package/dist/cli.js +63 -34
- package/dist/index.js +35 -10
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -266,6 +266,7 @@ sift rerun --goal diagnose --format json
|
|
|
266
266
|
- CLI reference: [docs/cli-reference.md](docs/cli-reference.md)
|
|
267
267
|
- Worked examples: [docs/examples](docs/examples)
|
|
268
268
|
- Benchmark methodology: [BENCHMARK_NOTES.md](BENCHMARK_NOTES.md)
|
|
269
|
+
- Contributing and development notes: [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
269
270
|
- Release notes: [release-notes](release-notes)
|
|
270
271
|
|
|
271
272
|
---
|
package/dist/cli.js
CHANGED
|
@@ -5,13 +5,15 @@ import { createRequire } from "module";
|
|
|
5
5
|
import { cac } from "cac";
|
|
6
6
|
|
|
7
7
|
// src/config/load.ts
|
|
8
|
-
import
|
|
8
|
+
import fs2 from "fs";
|
|
9
9
|
import path2 from "path";
|
|
10
10
|
import YAML from "yaml";
|
|
11
11
|
|
|
12
12
|
// src/constants.ts
|
|
13
|
+
import fs from "fs";
|
|
13
14
|
import os from "os";
|
|
14
15
|
import path from "path";
|
|
16
|
+
import crypto from "crypto";
|
|
15
17
|
var DEFAULT_CONFIG_FILENAME = "sift.config.yaml";
|
|
16
18
|
function getDefaultCodexGlobalInstructionsPath(homeDir = os.homedir()) {
|
|
17
19
|
return path.join(homeDir, ".codex", "AGENTS.md");
|
|
@@ -28,6 +30,26 @@ function getDefaultGlobalStateDir(homeDir = os.homedir()) {
|
|
|
28
30
|
function getDefaultTestStatusStatePath(homeDir = os.homedir()) {
|
|
29
31
|
return path.join(getDefaultGlobalStateDir(homeDir), "last-test-status.json");
|
|
30
32
|
}
|
|
33
|
+
function getDefaultScopedTestStatusStateDir(homeDir = os.homedir()) {
|
|
34
|
+
return path.join(getDefaultGlobalStateDir(homeDir), "test-status", "by-cwd");
|
|
35
|
+
}
|
|
36
|
+
function getScopedTestStatusStatePath(cwd, homeDir = os.homedir()) {
|
|
37
|
+
const normalizedCwd = normalizeScopedCacheCwd(cwd);
|
|
38
|
+
const baseName = slugCachePathSegment(path.basename(normalizedCwd)) || "root";
|
|
39
|
+
const shortHash = crypto.createHash("sha256").update(normalizedCwd).digest("hex").slice(0, 10);
|
|
40
|
+
return path.join(getDefaultScopedTestStatusStateDir(homeDir), `${baseName}-${shortHash}.json`);
|
|
41
|
+
}
|
|
42
|
+
function slugCachePathSegment(value) {
|
|
43
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
44
|
+
}
|
|
45
|
+
function normalizeScopedCacheCwd(cwd) {
|
|
46
|
+
const absoluteCwd = path.resolve(cwd);
|
|
47
|
+
try {
|
|
48
|
+
return fs.realpathSync.native(absoluteCwd);
|
|
49
|
+
} catch {
|
|
50
|
+
return absoluteCwd;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
31
53
|
function getDefaultConfigSearchPaths() {
|
|
32
54
|
return [
|
|
33
55
|
path.resolve(process.cwd(), "sift.config.yaml"),
|
|
@@ -44,13 +66,13 @@ var CAPTURE_OMITTED_MARKER = "\n...[captured output omitted]...\n";
|
|
|
44
66
|
function findConfigPath(explicitPath) {
|
|
45
67
|
if (explicitPath) {
|
|
46
68
|
const resolved = path2.resolve(explicitPath);
|
|
47
|
-
if (!
|
|
69
|
+
if (!fs2.existsSync(resolved)) {
|
|
48
70
|
throw new Error(`Config file not found: ${resolved}`);
|
|
49
71
|
}
|
|
50
72
|
return resolved;
|
|
51
73
|
}
|
|
52
74
|
for (const candidate of getDefaultConfigSearchPaths()) {
|
|
53
|
-
if (
|
|
75
|
+
if (fs2.existsSync(candidate)) {
|
|
54
76
|
return candidate;
|
|
55
77
|
}
|
|
56
78
|
}
|
|
@@ -61,7 +83,7 @@ function loadRawConfig(explicitPath) {
|
|
|
61
83
|
if (!configPath) {
|
|
62
84
|
return {};
|
|
63
85
|
}
|
|
64
|
-
const content =
|
|
86
|
+
const content = fs2.readFileSync(configPath, "utf8");
|
|
65
87
|
return YAML.parse(content) ?? {};
|
|
66
88
|
}
|
|
67
89
|
|
|
@@ -472,7 +494,7 @@ function resolveConfig(options = {}) {
|
|
|
472
494
|
}
|
|
473
495
|
|
|
474
496
|
// src/config/write.ts
|
|
475
|
-
import
|
|
497
|
+
import fs3 from "fs";
|
|
476
498
|
import path3 from "path";
|
|
477
499
|
import YAML2 from "yaml";
|
|
478
500
|
function writeExampleConfig(options = {}) {
|
|
@@ -480,41 +502,41 @@ function writeExampleConfig(options = {}) {
|
|
|
480
502
|
throw new Error("Use either --path <path> or --global, not both.");
|
|
481
503
|
}
|
|
482
504
|
const resolved = options.global ? getDefaultGlobalConfigPath() : path3.resolve(options.targetPath ?? DEFAULT_CONFIG_FILENAME);
|
|
483
|
-
if (
|
|
505
|
+
if (fs3.existsSync(resolved)) {
|
|
484
506
|
throw new Error(`Config file already exists at ${resolved}`);
|
|
485
507
|
}
|
|
486
508
|
const yaml = YAML2.stringify(defaultConfig);
|
|
487
|
-
|
|
488
|
-
|
|
509
|
+
fs3.mkdirSync(path3.dirname(resolved), { recursive: true });
|
|
510
|
+
fs3.writeFileSync(resolved, yaml, {
|
|
489
511
|
encoding: "utf8",
|
|
490
512
|
mode: 384
|
|
491
513
|
});
|
|
492
514
|
try {
|
|
493
|
-
|
|
515
|
+
fs3.chmodSync(resolved, 384);
|
|
494
516
|
} catch {
|
|
495
517
|
}
|
|
496
518
|
return resolved;
|
|
497
519
|
}
|
|
498
520
|
function writeConfigFile(options) {
|
|
499
521
|
const resolved = path3.resolve(options.targetPath);
|
|
500
|
-
if (!options.overwrite &&
|
|
522
|
+
if (!options.overwrite && fs3.existsSync(resolved)) {
|
|
501
523
|
throw new Error(`Config file already exists at ${resolved}`);
|
|
502
524
|
}
|
|
503
525
|
const yaml = YAML2.stringify(options.config);
|
|
504
|
-
|
|
505
|
-
|
|
526
|
+
fs3.mkdirSync(path3.dirname(resolved), { recursive: true });
|
|
527
|
+
fs3.writeFileSync(resolved, yaml, {
|
|
506
528
|
encoding: "utf8",
|
|
507
529
|
mode: 384
|
|
508
530
|
});
|
|
509
531
|
try {
|
|
510
|
-
|
|
532
|
+
fs3.chmodSync(resolved, 384);
|
|
511
533
|
} catch {
|
|
512
534
|
}
|
|
513
535
|
return resolved;
|
|
514
536
|
}
|
|
515
537
|
|
|
516
538
|
// src/config/editable.ts
|
|
517
|
-
import
|
|
539
|
+
import fs4 from "fs";
|
|
518
540
|
import path4 from "path";
|
|
519
541
|
function isRecord2(value) {
|
|
520
542
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -527,7 +549,7 @@ function resolveEditableConfigPath(explicitPath) {
|
|
|
527
549
|
}
|
|
528
550
|
function loadEditableConfig(explicitPath) {
|
|
529
551
|
const resolvedPath = resolveEditableConfigPath(explicitPath);
|
|
530
|
-
const existed =
|
|
552
|
+
const existed = fs4.existsSync(resolvedPath);
|
|
531
553
|
const rawConfig = existed ? loadRawConfig(resolvedPath) : {};
|
|
532
554
|
const config = siftConfigSchema.parse(
|
|
533
555
|
mergeDefined(defaultConfig, isRecord2(rawConfig) ? rawConfig : {})
|
|
@@ -1164,7 +1186,7 @@ function configUse(provider, configPath, env = process.env) {
|
|
|
1164
1186
|
}
|
|
1165
1187
|
|
|
1166
1188
|
// src/commands/agent.ts
|
|
1167
|
-
import
|
|
1189
|
+
import fs5 from "fs";
|
|
1168
1190
|
import os2 from "os";
|
|
1169
1191
|
import path6 from "path";
|
|
1170
1192
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
@@ -1794,20 +1816,20 @@ function joinAroundRemoval(before, after, eol) {
|
|
|
1794
1816
|
return `${left}${eol}${eol}${right}`;
|
|
1795
1817
|
}
|
|
1796
1818
|
function readOptionalFile(targetPath) {
|
|
1797
|
-
if (!
|
|
1819
|
+
if (!fs5.existsSync(targetPath)) {
|
|
1798
1820
|
return void 0;
|
|
1799
1821
|
}
|
|
1800
|
-
const stats =
|
|
1822
|
+
const stats = fs5.statSync(targetPath);
|
|
1801
1823
|
if (!stats.isFile()) {
|
|
1802
1824
|
throw new Error(`${targetPath} exists but is not a file.`);
|
|
1803
1825
|
}
|
|
1804
|
-
return
|
|
1826
|
+
return fs5.readFileSync(targetPath, "utf8");
|
|
1805
1827
|
}
|
|
1806
1828
|
function writeTextFileAtomic(targetPath, content) {
|
|
1807
|
-
|
|
1829
|
+
fs5.mkdirSync(path6.dirname(targetPath), { recursive: true });
|
|
1808
1830
|
const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
|
|
1809
|
-
|
|
1810
|
-
|
|
1831
|
+
fs5.writeFileSync(tempPath, content, "utf8");
|
|
1832
|
+
fs5.renameSync(tempPath, targetPath);
|
|
1811
1833
|
}
|
|
1812
1834
|
function escapeRegExp(value) {
|
|
1813
1835
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -1983,6 +2005,7 @@ var OpenAIProvider = class {
|
|
|
1983
2005
|
signal: controller.signal,
|
|
1984
2006
|
headers: {
|
|
1985
2007
|
"content-type": "application/json",
|
|
2008
|
+
connection: "close",
|
|
1986
2009
|
...this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}
|
|
1987
2010
|
},
|
|
1988
2011
|
body: JSON.stringify({
|
|
@@ -2083,6 +2106,7 @@ var OpenAICompatibleProvider = class {
|
|
|
2083
2106
|
signal: controller.signal,
|
|
2084
2107
|
headers: {
|
|
2085
2108
|
"content-type": "application/json",
|
|
2109
|
+
connection: "close",
|
|
2086
2110
|
...this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}
|
|
2087
2111
|
},
|
|
2088
2112
|
body: JSON.stringify({
|
|
@@ -8265,7 +8289,7 @@ function emitStatsFooter(args) {
|
|
|
8265
8289
|
}
|
|
8266
8290
|
|
|
8267
8291
|
// src/core/testStatusState.ts
|
|
8268
|
-
import
|
|
8292
|
+
import fs6 from "fs";
|
|
8269
8293
|
import path7 from "path";
|
|
8270
8294
|
import { z as z3 } from "zod";
|
|
8271
8295
|
var detailSchema = z3.enum(["standard", "focused", "verbose"]);
|
|
@@ -8715,7 +8739,7 @@ function migrateCachedTestStatusRun(state) {
|
|
|
8715
8739
|
function readCachedTestStatusRun(statePath = getDefaultTestStatusStatePath()) {
|
|
8716
8740
|
let raw = "";
|
|
8717
8741
|
try {
|
|
8718
|
-
raw =
|
|
8742
|
+
raw = fs6.readFileSync(statePath, "utf8");
|
|
8719
8743
|
} catch (error) {
|
|
8720
8744
|
if (error.code === "ENOENT") {
|
|
8721
8745
|
throw new MissingCachedTestStatusRunError();
|
|
@@ -8736,10 +8760,10 @@ function tryReadCachedTestStatusRun(statePath = getDefaultTestStatusStatePath())
|
|
|
8736
8760
|
}
|
|
8737
8761
|
}
|
|
8738
8762
|
function writeCachedTestStatusRun(state, statePath = getDefaultTestStatusStatePath()) {
|
|
8739
|
-
|
|
8763
|
+
fs6.mkdirSync(path7.dirname(statePath), {
|
|
8740
8764
|
recursive: true
|
|
8741
8765
|
});
|
|
8742
|
-
|
|
8766
|
+
fs6.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}
|
|
8743
8767
|
`, "utf8");
|
|
8744
8768
|
}
|
|
8745
8769
|
function getNextEscalationDetail(detail) {
|
|
@@ -8901,7 +8925,8 @@ function resolveEscalationDetail(state, requested, showRaw = false) {
|
|
|
8901
8925
|
return nextDetail;
|
|
8902
8926
|
}
|
|
8903
8927
|
async function runEscalate(request) {
|
|
8904
|
-
const
|
|
8928
|
+
const scopedStatePath = getScopedTestStatusStatePath(process.cwd());
|
|
8929
|
+
const state = readCachedTestStatusRun(scopedStatePath);
|
|
8905
8930
|
const detail = resolveEscalationDetail(state, request.detail, request.showRaw);
|
|
8906
8931
|
if (request.verbose) {
|
|
8907
8932
|
process.stderr.write(
|
|
@@ -8949,10 +8974,13 @@ async function runEscalate(request) {
|
|
|
8949
8974
|
quiet: Boolean(request.quiet)
|
|
8950
8975
|
});
|
|
8951
8976
|
try {
|
|
8952
|
-
writeCachedTestStatusRun(
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8977
|
+
writeCachedTestStatusRun(
|
|
8978
|
+
{
|
|
8979
|
+
...state,
|
|
8980
|
+
detail
|
|
8981
|
+
},
|
|
8982
|
+
scopedStatePath
|
|
8983
|
+
);
|
|
8956
8984
|
} catch (error) {
|
|
8957
8985
|
if (request.verbose) {
|
|
8958
8986
|
const reason = error instanceof Error ? error.message : "unknown_error";
|
|
@@ -9293,10 +9321,11 @@ async function runExec(request) {
|
|
|
9293
9321
|
const shellPath = process.env.SHELL || "/bin/bash";
|
|
9294
9322
|
const commandPreview = buildCommandPreview(request);
|
|
9295
9323
|
const commandCwd = request.cwd ?? process.cwd();
|
|
9324
|
+
const scopedStatePath = getScopedTestStatusStatePath(commandCwd);
|
|
9296
9325
|
const isTestStatusPreset = request.presetName === "test-status";
|
|
9297
9326
|
const readCachedBaseline = isTestStatusPreset && (request.readCachedBaseline ?? true);
|
|
9298
9327
|
const writeCachedBaselineRequested = isTestStatusPreset && (request.writeCachedBaseline ?? (request.skipCacheWrite ? false : true));
|
|
9299
|
-
const previousCachedRun = readCachedBaseline ? tryReadCachedTestStatusRun() : null;
|
|
9328
|
+
const previousCachedRun = readCachedBaseline ? tryReadCachedTestStatusRun(scopedStatePath) : null;
|
|
9300
9329
|
if (request.config.runtime.verbose) {
|
|
9301
9330
|
process.stderr.write(
|
|
9302
9331
|
`${pc5.dim("sift")} exec mode=${hasShellCommand ? "shell" : "argv"} command=${commandPreview}
|
|
@@ -9499,7 +9528,7 @@ ${output}`;
|
|
|
9499
9528
|
}
|
|
9500
9529
|
if (currentCachedRun && shouldWriteCachedBaseline) {
|
|
9501
9530
|
try {
|
|
9502
|
-
writeCachedTestStatusRun(currentCachedRun);
|
|
9531
|
+
writeCachedTestStatusRun(currentCachedRun, scopedStatePath);
|
|
9503
9532
|
} catch (error) {
|
|
9504
9533
|
if (request.config.runtime.verbose) {
|
|
9505
9534
|
const reason = error instanceof Error ? error.message : "unknown_error";
|
|
@@ -9535,7 +9564,7 @@ ${output}`;
|
|
|
9535
9564
|
|
|
9536
9565
|
// src/core/rerun.ts
|
|
9537
9566
|
async function runRerun(request) {
|
|
9538
|
-
const state = readCachedTestStatusRun();
|
|
9567
|
+
const state = readCachedTestStatusRun(getScopedTestStatusStatePath(process.cwd()));
|
|
9539
9568
|
if (!request.remaining) {
|
|
9540
9569
|
return runExec({
|
|
9541
9570
|
...request,
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,10 @@ import { constants as osConstants } from "os";
|
|
|
4
4
|
import pc3 from "picocolors";
|
|
5
5
|
|
|
6
6
|
// src/constants.ts
|
|
7
|
+
import fs from "fs";
|
|
7
8
|
import os from "os";
|
|
8
9
|
import path from "path";
|
|
10
|
+
import crypto from "crypto";
|
|
9
11
|
function getDefaultGlobalConfigPath(homeDir = os.homedir()) {
|
|
10
12
|
return path.join(homeDir, ".config", "sift", "config.yaml");
|
|
11
13
|
}
|
|
@@ -15,6 +17,26 @@ function getDefaultGlobalStateDir(homeDir = os.homedir()) {
|
|
|
15
17
|
function getDefaultTestStatusStatePath(homeDir = os.homedir()) {
|
|
16
18
|
return path.join(getDefaultGlobalStateDir(homeDir), "last-test-status.json");
|
|
17
19
|
}
|
|
20
|
+
function getDefaultScopedTestStatusStateDir(homeDir = os.homedir()) {
|
|
21
|
+
return path.join(getDefaultGlobalStateDir(homeDir), "test-status", "by-cwd");
|
|
22
|
+
}
|
|
23
|
+
function getScopedTestStatusStatePath(cwd, homeDir = os.homedir()) {
|
|
24
|
+
const normalizedCwd = normalizeScopedCacheCwd(cwd);
|
|
25
|
+
const baseName = slugCachePathSegment(path.basename(normalizedCwd)) || "root";
|
|
26
|
+
const shortHash = crypto.createHash("sha256").update(normalizedCwd).digest("hex").slice(0, 10);
|
|
27
|
+
return path.join(getDefaultScopedTestStatusStateDir(homeDir), `${baseName}-${shortHash}.json`);
|
|
28
|
+
}
|
|
29
|
+
function slugCachePathSegment(value) {
|
|
30
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
31
|
+
}
|
|
32
|
+
function normalizeScopedCacheCwd(cwd) {
|
|
33
|
+
const absoluteCwd = path.resolve(cwd);
|
|
34
|
+
try {
|
|
35
|
+
return fs.realpathSync.native(absoluteCwd);
|
|
36
|
+
} catch {
|
|
37
|
+
return absoluteCwd;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
18
40
|
function getDefaultConfigSearchPaths() {
|
|
19
41
|
return [
|
|
20
42
|
path.resolve(process.cwd(), "sift.config.yaml"),
|
|
@@ -4741,6 +4763,7 @@ var OpenAIProvider = class {
|
|
|
4741
4763
|
signal: controller.signal,
|
|
4742
4764
|
headers: {
|
|
4743
4765
|
"content-type": "application/json",
|
|
4766
|
+
connection: "close",
|
|
4744
4767
|
...this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}
|
|
4745
4768
|
},
|
|
4746
4769
|
body: JSON.stringify({
|
|
@@ -4841,6 +4864,7 @@ var OpenAICompatibleProvider = class {
|
|
|
4841
4864
|
signal: controller.signal,
|
|
4842
4865
|
headers: {
|
|
4843
4866
|
"content-type": "application/json",
|
|
4867
|
+
connection: "close",
|
|
4844
4868
|
...this.apiKey ? { authorization: `Bearer ${this.apiKey}` } : {}
|
|
4845
4869
|
},
|
|
4846
4870
|
body: JSON.stringify({
|
|
@@ -6413,7 +6437,7 @@ function emitStatsFooter(args) {
|
|
|
6413
6437
|
}
|
|
6414
6438
|
|
|
6415
6439
|
// src/core/testStatusState.ts
|
|
6416
|
-
import
|
|
6440
|
+
import fs2 from "fs";
|
|
6417
6441
|
import path2 from "path";
|
|
6418
6442
|
import { z as z2 } from "zod";
|
|
6419
6443
|
var detailSchema = z2.enum(["standard", "focused", "verbose"]);
|
|
@@ -6863,7 +6887,7 @@ function migrateCachedTestStatusRun(state) {
|
|
|
6863
6887
|
function readCachedTestStatusRun(statePath = getDefaultTestStatusStatePath()) {
|
|
6864
6888
|
let raw = "";
|
|
6865
6889
|
try {
|
|
6866
|
-
raw =
|
|
6890
|
+
raw = fs2.readFileSync(statePath, "utf8");
|
|
6867
6891
|
} catch (error) {
|
|
6868
6892
|
if (error.code === "ENOENT") {
|
|
6869
6893
|
throw new MissingCachedTestStatusRunError();
|
|
@@ -6884,10 +6908,10 @@ function tryReadCachedTestStatusRun(statePath = getDefaultTestStatusStatePath())
|
|
|
6884
6908
|
}
|
|
6885
6909
|
}
|
|
6886
6910
|
function writeCachedTestStatusRun(state, statePath = getDefaultTestStatusStatePath()) {
|
|
6887
|
-
|
|
6911
|
+
fs2.mkdirSync(path2.dirname(statePath), {
|
|
6888
6912
|
recursive: true
|
|
6889
6913
|
});
|
|
6890
|
-
|
|
6914
|
+
fs2.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}
|
|
6891
6915
|
`, "utf8");
|
|
6892
6916
|
}
|
|
6893
6917
|
function buildTargetDelta(args) {
|
|
@@ -7273,10 +7297,11 @@ async function runExec(request) {
|
|
|
7273
7297
|
const shellPath = process.env.SHELL || "/bin/bash";
|
|
7274
7298
|
const commandPreview = buildCommandPreview(request);
|
|
7275
7299
|
const commandCwd = request.cwd ?? process.cwd();
|
|
7300
|
+
const scopedStatePath = getScopedTestStatusStatePath(commandCwd);
|
|
7276
7301
|
const isTestStatusPreset = request.presetName === "test-status";
|
|
7277
7302
|
const readCachedBaseline = isTestStatusPreset && (request.readCachedBaseline ?? true);
|
|
7278
7303
|
const writeCachedBaselineRequested = isTestStatusPreset && (request.writeCachedBaseline ?? (request.skipCacheWrite ? false : true));
|
|
7279
|
-
const previousCachedRun = readCachedBaseline ? tryReadCachedTestStatusRun() : null;
|
|
7304
|
+
const previousCachedRun = readCachedBaseline ? tryReadCachedTestStatusRun(scopedStatePath) : null;
|
|
7280
7305
|
if (request.config.runtime.verbose) {
|
|
7281
7306
|
process.stderr.write(
|
|
7282
7307
|
`${pc3.dim("sift")} exec mode=${hasShellCommand ? "shell" : "argv"} command=${commandPreview}
|
|
@@ -7479,7 +7504,7 @@ ${output}`;
|
|
|
7479
7504
|
}
|
|
7480
7505
|
if (currentCachedRun && shouldWriteCachedBaseline) {
|
|
7481
7506
|
try {
|
|
7482
|
-
writeCachedTestStatusRun(currentCachedRun);
|
|
7507
|
+
writeCachedTestStatusRun(currentCachedRun, scopedStatePath);
|
|
7483
7508
|
} catch (error) {
|
|
7484
7509
|
if (request.config.runtime.verbose) {
|
|
7485
7510
|
const reason = error instanceof Error ? error.message : "unknown_error";
|
|
@@ -7585,19 +7610,19 @@ var defaultConfig = {
|
|
|
7585
7610
|
};
|
|
7586
7611
|
|
|
7587
7612
|
// src/config/load.ts
|
|
7588
|
-
import
|
|
7613
|
+
import fs3 from "fs";
|
|
7589
7614
|
import path3 from "path";
|
|
7590
7615
|
import YAML from "yaml";
|
|
7591
7616
|
function findConfigPath(explicitPath) {
|
|
7592
7617
|
if (explicitPath) {
|
|
7593
7618
|
const resolved = path3.resolve(explicitPath);
|
|
7594
|
-
if (!
|
|
7619
|
+
if (!fs3.existsSync(resolved)) {
|
|
7595
7620
|
throw new Error(`Config file not found: ${resolved}`);
|
|
7596
7621
|
}
|
|
7597
7622
|
return resolved;
|
|
7598
7623
|
}
|
|
7599
7624
|
for (const candidate of getDefaultConfigSearchPaths()) {
|
|
7600
|
-
if (
|
|
7625
|
+
if (fs3.existsSync(candidate)) {
|
|
7601
7626
|
return candidate;
|
|
7602
7627
|
}
|
|
7603
7628
|
}
|
|
@@ -7608,7 +7633,7 @@ function loadRawConfig(explicitPath) {
|
|
|
7608
7633
|
if (!configPath) {
|
|
7609
7634
|
return {};
|
|
7610
7635
|
}
|
|
7611
|
-
const content =
|
|
7636
|
+
const content = fs3.readFileSync(configPath, "utf8");
|
|
7612
7637
|
return YAML.parse(content) ?? {};
|
|
7613
7638
|
}
|
|
7614
7639
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bilalimamoglu/sift",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Agent-first command-output reduction layer for agents, CI, and automation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,8 +25,10 @@
|
|
|
25
25
|
"bench:report": "node --import tsx scripts/bench/generate-progress-report.ts",
|
|
26
26
|
"dev": "tsx src/cli.ts",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
|
-
"test": "vitest run",
|
|
29
|
-
"test:
|
|
28
|
+
"test": "vitest run --config vitest.config.ts",
|
|
29
|
+
"test:smoke": "vitest run --config vitest.config.ts test/*.smoke.test.ts",
|
|
30
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts test/*.e2e.test.ts",
|
|
31
|
+
"test:coverage": "vitest run --config vitest.config.ts --coverage --exclude=\"test/**/*.smoke.test.ts\" --exclude=\"test/**/*.e2e.test.ts\"",
|
|
30
32
|
"test:watch": "vitest",
|
|
31
33
|
"prepublishOnly": "npm run typecheck && npm run test:coverage && npm run build"
|
|
32
34
|
},
|