@harness-engineering/cli 2.5.0 → 2.6.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/{agents-md-KAD3L2NO.js → agents-md-2JUQ4FE2.js} +4 -4
- package/dist/{analyzer-VY6DJVOU-NI56JRFK.js → analyzer-VY6DJVOU-4AHIJLNS.js} +2 -2
- package/dist/{architecture-OC7TFCFF.js → architecture-CXAVNB5X.js} +5 -5
- package/dist/{assess-project-ZGMRPTS3.js → assess-project-M626SSPN.js} +1 -1
- package/dist/bin/harness-mcp.js +15 -15
- package/dist/bin/harness.js +24 -24
- package/dist/{check-phase-gate-PD5MVEZT.js → check-phase-gate-XMU6LLUQ.js} +5 -5
- package/dist/{chunk-N6VWCISQ.js → chunk-24KCOJJG.js} +2 -2
- package/dist/{chunk-XIW24BJY.js → chunk-43M3RLFQ.js} +3 -3
- package/dist/{chunk-2RNGLYOG.js → chunk-5JNSFYZU.js} +2 -2
- package/dist/{chunk-XSI3RDH6.js → chunk-6AX6R3LM.js} +7 -7
- package/dist/{chunk-DOUS4ULX.js → chunk-GWE5LL3R.js} +6 -6
- package/dist/{chunk-7DOGGXQU.js → chunk-GWF2OILZ.js} +2 -2
- package/dist/{chunk-TCSNO7YW.js → chunk-HFOB2MPQ.js} +2 -2
- package/dist/{chunk-6SRKI77C.js → chunk-HMW3VKUF.js} +3 -3
- package/dist/{chunk-IXKGMPMT.js → chunk-HYTRDAHV.js} +2 -2
- package/dist/{chunk-NOOPJD5R.js → chunk-I6K43QQS.js} +3 -3
- package/dist/{chunk-IGBQIXPS.js → chunk-JFZOWO7D.js} +2 -2
- package/dist/{chunk-57TS3UGN.js → chunk-K246XQ2L.js} +2 -2
- package/dist/{chunk-A3EBWI7U.js → chunk-L5BCZ5XS.js} +2 -2
- package/dist/{chunk-UCL3UZIC.js → chunk-NX6A24DS.js} +1588 -925
- package/dist/{chunk-65MJPWFN.js → chunk-OA6SWTU4.js} +6 -6
- package/dist/{chunk-2LPUIBVH.js → chunk-OH3NXXUY.js} +121 -2
- package/dist/{chunk-LT244Y6E.js → chunk-ORNMAYHB.js} +196 -75
- package/dist/{chunk-4CWFVEVV.js → chunk-PFZEADQM.js} +1 -1
- package/dist/{chunk-JE5GQVCQ.js → chunk-Q6ZR2L6Q.js} +2 -2
- package/dist/{chunk-UF7BKRH4.js → chunk-QOKMDDBJ.js} +4 -4
- package/dist/{chunk-IWRYCUDO.js → chunk-SZEFU6XC.js} +1 -1
- package/dist/{chunk-HIZXUWWC.js → chunk-VTTNIZJL.js} +21 -2
- package/dist/{chunk-ELMV6QU2.js → chunk-YP7I25SL.js} +2 -2
- package/dist/{chunk-KQ6TDRPS.js → chunk-YYRQCQPZ.js} +425 -173
- package/dist/{ci-workflow-WAG4TOV6.js → ci-workflow-3JNDZQYD.js} +4 -4
- package/dist/{dist-HVJUGPSY.js → dist-E3SAAHCM.js} +23 -1
- package/dist/{dist-TKHVYUWZ.js → dist-OHDQBTSO.js} +43 -3
- package/dist/{docs-4WPBYSCF.js → docs-5RYMDHN3.js} +5 -5
- package/dist/{engine-5BXDQT5T.js → engine-KZ3PPUYE.js} +4 -4
- package/dist/{entropy-7FIUFACI.js → entropy-DQTAPSSE.js} +4 -4
- package/dist/{feedback-ER2HRTFD.js → feedback-WH6XPQJS.js} +1 -1
- package/dist/{generate-agent-definitions-5PV4O3BD.js → generate-agent-definitions-SZA4QIHN.js} +5 -5
- package/dist/index.d.ts +47 -0
- package/dist/index.js +24 -24
- package/dist/{loader-6RTEYN5Q.js → loader-BNKGM23C.js} +4 -4
- package/dist/{mcp-QWSDEYMN.js → mcp-GZH4EYGD.js} +15 -15
- package/dist/{performance-AZJAT35R.js → performance-54TMJOEU.js} +5 -5
- package/dist/{review-pipeline-4VF73V4V.js → review-pipeline-OTDDVPNY.js} +4 -4
- package/dist/{runtime-SAZGLILX.js → runtime-W5THSNAL.js} +4 -4
- package/dist/{security-ZWRABJNE.js → security-27HW7CYT.js} +1 -1
- package/dist/{tool-tiers-LTQNNAFU.js → tool-tiers-B7JC2XC3.js} +3 -1
- package/dist/{validate-AFJVI4OX.js → validate-QRVCD4GP.js} +5 -5
- package/dist/{validate-cross-check-7PO7CBVT.js → validate-cross-check-BUAGBAPO.js} +4 -4
- package/package.json +6 -6
|
@@ -31,13 +31,15 @@ import {
|
|
|
31
31
|
resetParserCache,
|
|
32
32
|
resolveFileToLayer,
|
|
33
33
|
validateDependencies
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-SZEFU6XC.js";
|
|
35
35
|
import {
|
|
36
36
|
AuthAuditEntrySchema,
|
|
37
37
|
AuthTokenPublicSchema,
|
|
38
38
|
AuthTokenSchema,
|
|
39
39
|
BridgeKindSchema,
|
|
40
40
|
DEFAULT_SKILL_CONTEXT_BUDGET,
|
|
41
|
+
EditProposalInputSchema,
|
|
42
|
+
EmitSkillProposalInputSchema,
|
|
41
43
|
Err,
|
|
42
44
|
GatewayEventSchema,
|
|
43
45
|
INDEXED_FILE_KINDS,
|
|
@@ -53,10 +55,19 @@ import {
|
|
|
53
55
|
OTLPSpanSchema,
|
|
54
56
|
Ok,
|
|
55
57
|
PromptCacheStatsSchema,
|
|
58
|
+
ProposalContentSchema,
|
|
59
|
+
ProposalDecisionSchema,
|
|
60
|
+
ProposalGateFindingSchema,
|
|
61
|
+
ProposalGateSchema,
|
|
62
|
+
ProposalKindSchema,
|
|
63
|
+
ProposalSourceSchema,
|
|
64
|
+
ProposalStatusSchema,
|
|
56
65
|
SESSIONS_DEFAULTS,
|
|
57
66
|
SESSION_SECTION_NAMES,
|
|
58
67
|
STANDARD_COGNITIVE_MODES,
|
|
59
68
|
SessionSummarySchema,
|
|
69
|
+
SkillProposalSchema,
|
|
70
|
+
SkillProvenanceSchema,
|
|
60
71
|
TokenScopeSchema,
|
|
61
72
|
TrajectoryMetadataSchema,
|
|
62
73
|
WebhookDeliverySchema,
|
|
@@ -66,7 +77,7 @@ import {
|
|
|
66
77
|
init_dist,
|
|
67
78
|
isErr,
|
|
68
79
|
isOk
|
|
69
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-OH3NXXUY.js";
|
|
70
81
|
import {
|
|
71
82
|
DEFAULT_SKIP_DIRS,
|
|
72
83
|
GraphStore,
|
|
@@ -1296,10 +1307,12 @@ __export(dist_exports, {
|
|
|
1296
1307
|
ETagStore: () => ETagStore,
|
|
1297
1308
|
EVIDENCE_SATURATION: () => EVIDENCE_SATURATION,
|
|
1298
1309
|
EXTENSION_MAP: () => EXTENSION_MAP,
|
|
1310
|
+
EditProposalInputSchema: () => EditProposalInputSchema,
|
|
1299
1311
|
EmergenceConfidenceSchema: () => EmergenceConfidenceSchema,
|
|
1300
1312
|
EmergenceResultSchema: () => EmergenceResultSchema,
|
|
1301
1313
|
EmergentConstraintSuggestionSchema: () => EmergentConstraintSuggestionSchema,
|
|
1302
1314
|
EmitInteractionInputSchema: () => EmitInteractionInputSchema,
|
|
1315
|
+
EmitSkillProposalInputSchema: () => EmitSkillProposalInputSchema,
|
|
1303
1316
|
EntropyAnalyzer: () => EntropyAnalyzer,
|
|
1304
1317
|
EntropyConfigSchema: () => EntropyConfigSchema,
|
|
1305
1318
|
Err: () => Err,
|
|
@@ -1354,6 +1367,15 @@ __export(dist_exports, {
|
|
|
1354
1367
|
PredictionWarningSchema: () => PredictionWarningSchema,
|
|
1355
1368
|
ProjectScanner: () => ProjectScanner,
|
|
1356
1369
|
PromptCacheStatsSchema: () => PromptCacheStatsSchema,
|
|
1370
|
+
ProposalConflictError: () => ProposalConflictError,
|
|
1371
|
+
ProposalContentSchema: () => ProposalContentSchema,
|
|
1372
|
+
ProposalDecisionSchema: () => ProposalDecisionSchema,
|
|
1373
|
+
ProposalGateFindingSchema: () => ProposalGateFindingSchema,
|
|
1374
|
+
ProposalGateSchema: () => ProposalGateSchema,
|
|
1375
|
+
ProposalKindSchema: () => ProposalKindSchema,
|
|
1376
|
+
ProposalNotFoundError: () => ProposalNotFoundError,
|
|
1377
|
+
ProposalSourceSchema: () => ProposalSourceSchema,
|
|
1378
|
+
ProposalStatusSchema: () => ProposalStatusSchema,
|
|
1357
1379
|
PulseAdapterAlreadyRegisteredError: () => PulseAdapterAlreadyRegisteredError,
|
|
1358
1380
|
PulseConfigSchema: () => PulseConfigSchema,
|
|
1359
1381
|
PulseDbSourceSchema: () => PulseDbSourceSchema,
|
|
@@ -1384,6 +1406,8 @@ __export(dist_exports, {
|
|
|
1384
1406
|
SharableLayerSchema: () => SharableLayerSchema,
|
|
1385
1407
|
SharableSecurityRulesSchema: () => SharableSecurityRulesSchema,
|
|
1386
1408
|
SkillEventSchema: () => SkillEventSchema,
|
|
1409
|
+
SkillProposalSchema: () => SkillProposalSchema,
|
|
1410
|
+
SkillProvenanceSchema: () => SkillProvenanceSchema,
|
|
1387
1411
|
SolutionDocFrontmatterSchema: () => SolutionDocFrontmatterSchema,
|
|
1388
1412
|
SpanKind: () => SpanKind,
|
|
1389
1413
|
SpecImpactEstimateSchema: () => SpecImpactEstimateSchema,
|
|
@@ -1487,7 +1511,9 @@ __export(dist_exports, {
|
|
|
1487
1511
|
createFixes: () => createFixes,
|
|
1488
1512
|
createForbiddenImportFixes: () => createForbiddenImportFixes,
|
|
1489
1513
|
createOrphanedDepFixes: () => createOrphanedDepFixes,
|
|
1514
|
+
createOsvClient: () => createOsvClient,
|
|
1490
1515
|
createParseError: () => createParseError,
|
|
1516
|
+
createProposal: () => createProposal,
|
|
1491
1517
|
createRegionMap: () => createRegionMap,
|
|
1492
1518
|
createSelfReview: () => createSelfReview,
|
|
1493
1519
|
createStream: () => createStream,
|
|
@@ -1499,6 +1525,7 @@ __export(dist_exports, {
|
|
|
1499
1525
|
deepMergeConstraints: () => deepMergeConstraints,
|
|
1500
1526
|
defaultCollectors: () => defaultCollectors,
|
|
1501
1527
|
defineLayer: () => defineLayer,
|
|
1528
|
+
deriveSkillUsage: () => deriveSkillUsage,
|
|
1502
1529
|
deserializationRules: () => deserializationRules,
|
|
1503
1530
|
detectChangeType: () => detectChangeType,
|
|
1504
1531
|
detectCircularDeps: () => detectCircularDeps,
|
|
@@ -1551,6 +1578,7 @@ __export(dist_exports, {
|
|
|
1551
1578
|
getOutline: () => getOutline,
|
|
1552
1579
|
getParser: () => getParser,
|
|
1553
1580
|
getPhaseCategories: () => getPhaseCategories,
|
|
1581
|
+
getProposal: () => getProposal,
|
|
1554
1582
|
getPulseAdapter: () => getPulseAdapter,
|
|
1555
1583
|
getRoadmapMode: () => getRoadmapMode,
|
|
1556
1584
|
getStreamForBranch: () => getStreamForBranch,
|
|
@@ -1572,6 +1600,7 @@ __export(dist_exports, {
|
|
|
1572
1600
|
isUpdateCheckEnabled: () => isUpdateCheckEnabled,
|
|
1573
1601
|
isoWeek: () => isoWeek,
|
|
1574
1602
|
listActiveSessions: () => listActiveSessions,
|
|
1603
|
+
listProposals: () => listProposals,
|
|
1575
1604
|
listPulseAdapters: () => listPulseAdapters,
|
|
1576
1605
|
listStreams: () => listStreams,
|
|
1577
1606
|
listTaintedSessions: () => listTaintedSessions,
|
|
@@ -1622,6 +1651,7 @@ __export(dist_exports, {
|
|
|
1622
1651
|
previewFix: () => previewFix,
|
|
1623
1652
|
projectValue: () => projectValue,
|
|
1624
1653
|
promoteSessionLearnings: () => promoteSessionLearnings,
|
|
1654
|
+
proposalsDir: () => proposalsDir,
|
|
1625
1655
|
pruneLearnings: () => pruneLearnings,
|
|
1626
1656
|
reactRules: () => reactRules,
|
|
1627
1657
|
readAdoptionRecords: () => readAdoptionRecords,
|
|
@@ -1694,6 +1724,7 @@ __export(dist_exports, {
|
|
|
1694
1724
|
trackAction: () => trackAction,
|
|
1695
1725
|
unfoldRange: () => unfoldRange,
|
|
1696
1726
|
unfoldSymbol: () => unfoldSymbol,
|
|
1727
|
+
updateProposal: () => updateProposal,
|
|
1697
1728
|
updateSessionEntryStatus: () => updateSessionEntryStatus,
|
|
1698
1729
|
updateSessionIndex: () => updateSessionIndex,
|
|
1699
1730
|
validateAgentConfigs: () => validateAgentConfigs,
|
|
@@ -1828,71 +1859,76 @@ import { minimatch as minimatch3 } from "minimatch";
|
|
|
1828
1859
|
import { z as z9 } from "zod";
|
|
1829
1860
|
import * as fs28 from "fs";
|
|
1830
1861
|
import * as path25 from "path";
|
|
1862
|
+
import * as fs30 from "fs";
|
|
1863
|
+
import * as path26 from "path";
|
|
1831
1864
|
import { readFileSync as readFileSync22, writeFileSync as writeFileSync14, unlinkSync as unlinkSync2, mkdirSync as mkdirSync13, readdirSync as readdirSync3 } from "fs";
|
|
1832
|
-
import { join as
|
|
1865
|
+
import { join as join382, dirname as dirname10 } from "path";
|
|
1833
1866
|
import { createHash as createHash32 } from "crypto";
|
|
1834
1867
|
import { z as z10 } from "zod";
|
|
1835
1868
|
import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, renameSync as renameSync72, mkdirSync as mkdirSync14, existsSync as existsSync342 } from "fs";
|
|
1836
1869
|
import { execSync as execSync3 } from "child_process";
|
|
1837
1870
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
1838
|
-
import { isAbsolute as isAbsolute4, join as
|
|
1839
|
-
import * as path26 from "path";
|
|
1871
|
+
import { isAbsolute as isAbsolute4, join as join39, relative as relative3, dirname as dirname11 } from "path";
|
|
1840
1872
|
import * as path27 from "path";
|
|
1841
1873
|
import * as path28 from "path";
|
|
1842
1874
|
import * as path29 from "path";
|
|
1843
|
-
import * as fs30 from "fs";
|
|
1844
1875
|
import * as path30 from "path";
|
|
1845
1876
|
import * as fs31 from "fs";
|
|
1846
1877
|
import * as path31 from "path";
|
|
1847
1878
|
import * as fs32 from "fs";
|
|
1848
|
-
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
1849
|
-
import * as fs33 from "fs";
|
|
1850
1879
|
import * as path32 from "path";
|
|
1880
|
+
import * as fs33 from "fs";
|
|
1881
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
1851
1882
|
import * as fs34 from "fs";
|
|
1852
1883
|
import * as path33 from "path";
|
|
1853
|
-
import
|
|
1884
|
+
import * as fs35 from "fs";
|
|
1854
1885
|
import * as path34 from "path";
|
|
1855
|
-
import {
|
|
1856
|
-
import * as fs35 from "fs/promises";
|
|
1886
|
+
import { createHash as createHash4 } from "crypto";
|
|
1857
1887
|
import * as path35 from "path";
|
|
1888
|
+
import { z as z11 } from "zod";
|
|
1858
1889
|
import * as fs36 from "fs/promises";
|
|
1859
1890
|
import * as path36 from "path";
|
|
1860
|
-
import * as
|
|
1861
|
-
import * as fs37 from "fs";
|
|
1891
|
+
import * as fs37 from "fs/promises";
|
|
1862
1892
|
import * as path37 from "path";
|
|
1893
|
+
import * as ejs from "ejs";
|
|
1894
|
+
import * as fs38 from "fs";
|
|
1895
|
+
import * as path38 from "path";
|
|
1863
1896
|
import * as os from "os";
|
|
1864
1897
|
import { spawn as spawn2 } from "child_process";
|
|
1865
|
-
import * as
|
|
1866
|
-
import * as path38 from "path";
|
|
1867
|
-
import * as fs39 from "fs";
|
|
1898
|
+
import * as fs39 from "fs/promises";
|
|
1868
1899
|
import * as path39 from "path";
|
|
1869
1900
|
import * as fs40 from "fs";
|
|
1870
1901
|
import * as path40 from "path";
|
|
1871
|
-
import * as os2 from "os";
|
|
1872
1902
|
import * as fs41 from "fs";
|
|
1873
1903
|
import * as path41 from "path";
|
|
1904
|
+
import * as os2 from "os";
|
|
1874
1905
|
import * as fs42 from "fs";
|
|
1875
1906
|
import * as path42 from "path";
|
|
1876
|
-
import * as fs44 from "fs";
|
|
1877
|
-
import * as path44 from "path";
|
|
1878
|
-
import { execFileSync as execFileSync2 } from "child_process";
|
|
1879
1907
|
import * as fs43 from "fs";
|
|
1880
1908
|
import * as path43 from "path";
|
|
1881
|
-
import * as crypto4 from "crypto";
|
|
1882
1909
|
import * as fs45 from "fs";
|
|
1883
1910
|
import * as path45 from "path";
|
|
1911
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
1912
|
+
import * as fs44 from "fs";
|
|
1913
|
+
import * as path44 from "path";
|
|
1914
|
+
import * as crypto4 from "crypto";
|
|
1884
1915
|
import * as fs46 from "fs";
|
|
1885
|
-
import * as fs47 from "fs";
|
|
1886
1916
|
import * as path46 from "path";
|
|
1917
|
+
import * as fs47 from "fs";
|
|
1918
|
+
import * as fs48 from "fs";
|
|
1919
|
+
import * as path47 from "path";
|
|
1887
1920
|
import { readFileSync as readFileSync392 } from "fs";
|
|
1888
1921
|
import { fileURLToPath } from "url";
|
|
1889
|
-
import { dirname as
|
|
1922
|
+
import { dirname as dirname16, join as join612 } from "path";
|
|
1890
1923
|
import { execFile } from "child_process";
|
|
1891
1924
|
import { promisify as promisify2 } from "util";
|
|
1892
1925
|
import { execFile as execFile2 } from "child_process";
|
|
1893
1926
|
import { promisify as promisify3 } from "util";
|
|
1894
|
-
import * as
|
|
1895
|
-
import * as
|
|
1927
|
+
import * as fs49 from "fs/promises";
|
|
1928
|
+
import * as path48 from "path";
|
|
1929
|
+
import * as fs50 from "fs";
|
|
1930
|
+
import * as path49 from "path";
|
|
1931
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1896
1932
|
function isBadPort(port) {
|
|
1897
1933
|
return BAD_PORT_SET.has(port);
|
|
1898
1934
|
}
|
|
@@ -1938,15 +1974,15 @@ function validateConfig(data, schema) {
|
|
|
1938
1974
|
let message = "Configuration validation failed";
|
|
1939
1975
|
const suggestions = [];
|
|
1940
1976
|
if (firstError) {
|
|
1941
|
-
const
|
|
1942
|
-
const pathDisplay =
|
|
1977
|
+
const path50 = firstError.path.join(".");
|
|
1978
|
+
const pathDisplay = path50 ? ` at "${path50}"` : "";
|
|
1943
1979
|
if (firstError.code === "invalid_type") {
|
|
1944
1980
|
const received = firstError.received;
|
|
1945
1981
|
const expected = firstError.expected;
|
|
1946
1982
|
if (received === "undefined") {
|
|
1947
1983
|
code = "MISSING_FIELD";
|
|
1948
1984
|
message = `Missing required field${pathDisplay}: ${firstError.message}`;
|
|
1949
|
-
suggestions.push(`Field "${
|
|
1985
|
+
suggestions.push(`Field "${path50}" is required and must be of type "${expected}"`);
|
|
1950
1986
|
} else {
|
|
1951
1987
|
code = "INVALID_TYPE";
|
|
1952
1988
|
message = `Invalid type${pathDisplay}: ${firstError.message}`;
|
|
@@ -2280,16 +2316,16 @@ function makeFinding(input) {
|
|
|
2280
2316
|
if (input.suggestion) finding.suggestion = input.suggestion;
|
|
2281
2317
|
return finding;
|
|
2282
2318
|
}
|
|
2283
|
-
function readTextSafe(
|
|
2319
|
+
function readTextSafe(path50) {
|
|
2284
2320
|
try {
|
|
2285
|
-
return readFileSync2(
|
|
2321
|
+
return readFileSync2(path50, "utf-8");
|
|
2286
2322
|
} catch {
|
|
2287
2323
|
return null;
|
|
2288
2324
|
}
|
|
2289
2325
|
}
|
|
2290
|
-
function safeFileSize(
|
|
2326
|
+
function safeFileSize(path50) {
|
|
2291
2327
|
try {
|
|
2292
|
-
return statSync(
|
|
2328
|
+
return statSync(path50).size;
|
|
2293
2329
|
} catch {
|
|
2294
2330
|
return null;
|
|
2295
2331
|
}
|
|
@@ -2834,27 +2870,27 @@ function extractSections(content) {
|
|
|
2834
2870
|
}
|
|
2835
2871
|
return sections.map((section) => buildAgentMapSection(section, lines));
|
|
2836
2872
|
}
|
|
2837
|
-
function isExternalLink(
|
|
2838
|
-
return
|
|
2873
|
+
function isExternalLink(path50) {
|
|
2874
|
+
return path50.startsWith("http://") || path50.startsWith("https://") || path50.startsWith("#") || path50.startsWith("mailto:");
|
|
2839
2875
|
}
|
|
2840
2876
|
function resolveLinkPath(linkPath, baseDir) {
|
|
2841
2877
|
return linkPath.startsWith(".") ? join8(baseDir, linkPath) : linkPath;
|
|
2842
2878
|
}
|
|
2843
|
-
async function validateAgentsMap(
|
|
2844
|
-
const contentResult = await readFileContent(
|
|
2879
|
+
async function validateAgentsMap(path50 = "./AGENTS.md") {
|
|
2880
|
+
const contentResult = await readFileContent(path50);
|
|
2845
2881
|
if (!contentResult.ok) {
|
|
2846
2882
|
return Err(
|
|
2847
2883
|
createError(
|
|
2848
2884
|
"PARSE_ERROR",
|
|
2849
2885
|
`Failed to read AGENTS.md: ${contentResult.error.message}`,
|
|
2850
|
-
{ path:
|
|
2886
|
+
{ path: path50 },
|
|
2851
2887
|
["Ensure the file exists", "Check file permissions"]
|
|
2852
2888
|
)
|
|
2853
2889
|
);
|
|
2854
2890
|
}
|
|
2855
2891
|
const content = contentResult.value;
|
|
2856
2892
|
const sections = extractSections(content);
|
|
2857
|
-
const baseDir = dirname22(
|
|
2893
|
+
const baseDir = dirname22(path50);
|
|
2858
2894
|
const sectionTitles = sections.map((s) => s.title);
|
|
2859
2895
|
const missingSections = REQUIRED_SECTIONS.filter(
|
|
2860
2896
|
(required) => !sectionTitles.some((title) => title.toLowerCase().includes(required.toLowerCase()))
|
|
@@ -3402,8 +3438,8 @@ async function checkDocCoverage(domain, options = {}) {
|
|
|
3402
3438
|
);
|
|
3403
3439
|
}
|
|
3404
3440
|
}
|
|
3405
|
-
function suggestFix(
|
|
3406
|
-
const targetName = basename3(
|
|
3441
|
+
function suggestFix(path50, existingFiles) {
|
|
3442
|
+
const targetName = basename3(path50).toLowerCase();
|
|
3407
3443
|
const similar = existingFiles.find((file) => {
|
|
3408
3444
|
const fileName = basename3(file).toLowerCase();
|
|
3409
3445
|
return fileName.includes(targetName) || targetName.includes(fileName);
|
|
@@ -3411,7 +3447,7 @@ function suggestFix(path48, existingFiles) {
|
|
|
3411
3447
|
if (similar) {
|
|
3412
3448
|
return `Did you mean "${similar}"?`;
|
|
3413
3449
|
}
|
|
3414
|
-
return `Create the file "${
|
|
3450
|
+
return `Create the file "${path50}" or remove the link`;
|
|
3415
3451
|
}
|
|
3416
3452
|
async function validateKnowledgeMap(rootDir = process.cwd()) {
|
|
3417
3453
|
const agentsPath = join14(rootDir, "AGENTS.md");
|
|
@@ -3769,8 +3805,8 @@ function createBoundaryValidator(schema, name) {
|
|
|
3769
3805
|
return Ok(result.data);
|
|
3770
3806
|
}
|
|
3771
3807
|
const suggestions = result.error.issues.map((issue) => {
|
|
3772
|
-
const
|
|
3773
|
-
return
|
|
3808
|
+
const path50 = issue.path.join(".");
|
|
3809
|
+
return path50 ? `${path50}: ${issue.message}` : issue.message;
|
|
3774
3810
|
});
|
|
3775
3811
|
return Err(
|
|
3776
3812
|
createError(
|
|
@@ -4775,7 +4811,7 @@ function arrayLen(arr) {
|
|
|
4775
4811
|
return Array.isArray(arr) ? arr.length : 0;
|
|
4776
4812
|
}
|
|
4777
4813
|
async function gatherEntropyBlock(projectPath) {
|
|
4778
|
-
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./analyzer-VY6DJVOU-
|
|
4814
|
+
const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./analyzer-VY6DJVOU-4AHIJLNS.js");
|
|
4779
4815
|
const analyzer = new EntropyAnalyzer2({
|
|
4780
4816
|
rootDir: projectPath,
|
|
4781
4817
|
include: ["src/**/*.ts", "src/**/*.tsx", "packages/*/src/**/*.ts"],
|
|
@@ -4971,12 +5007,12 @@ function parseDiffHeader(part) {
|
|
|
4971
5007
|
return headerMatch[2];
|
|
4972
5008
|
}
|
|
4973
5009
|
function parseDiffPart(part) {
|
|
4974
|
-
const
|
|
4975
|
-
if (!
|
|
5010
|
+
const path50 = parseDiffHeader(part);
|
|
5011
|
+
if (!path50) return null;
|
|
4976
5012
|
const additionRegex = /^\+(?!\+\+)/gm;
|
|
4977
5013
|
const deletionRegex = /^-(?!--)/gm;
|
|
4978
5014
|
return {
|
|
4979
|
-
path:
|
|
5015
|
+
path: path50,
|
|
4980
5016
|
status: detectFileStatus(part),
|
|
4981
5017
|
additions: (part.match(additionRegex) || []).length,
|
|
4982
5018
|
deletions: (part.match(deletionRegex) || []).length
|
|
@@ -7614,6 +7650,91 @@ function parseHarnessIgnore(line, ruleId) {
|
|
|
7614
7650
|
const text = match[2]?.trim();
|
|
7615
7651
|
return { ruleId, justification: text || null };
|
|
7616
7652
|
}
|
|
7653
|
+
function createOsvClient(options = {}) {
|
|
7654
|
+
const cacheDir = options.cacheDir ?? DEFAULT_CACHE_DIR;
|
|
7655
|
+
const ttlMs = (options.cacheTtlHours ?? DEFAULT_TTL_HOURS) * 60 * 60 * 1e3;
|
|
7656
|
+
const fetchFn = options.fetchFn ?? globalThis.fetch;
|
|
7657
|
+
const logger = options.logger ?? { warn: (m, ctx) => console.warn(m, ctx) };
|
|
7658
|
+
const strict = options.strict ?? false;
|
|
7659
|
+
return {
|
|
7660
|
+
async check(pkg) {
|
|
7661
|
+
const cacheKey = `${pkg.ecosystem}-${sanitizePkgName(pkg.name)}@${pkg.version ?? "latest"}.json`;
|
|
7662
|
+
const cachePath = path26.join(cacheDir, cacheKey);
|
|
7663
|
+
const cached = await readCache(cachePath, ttlMs);
|
|
7664
|
+
if (cached) {
|
|
7665
|
+
return { ...cached, source: "cache" };
|
|
7666
|
+
}
|
|
7667
|
+
try {
|
|
7668
|
+
const advisories = await queryOsv(fetchFn, pkg);
|
|
7669
|
+
const result = classify(advisories);
|
|
7670
|
+
await writeCache(cachePath, result);
|
|
7671
|
+
return { ...result, source: "network" };
|
|
7672
|
+
} catch (err) {
|
|
7673
|
+
const message = `OSV query failed for ${pkg.name}@${pkg.version ?? "latest"}: ${String(err)}`;
|
|
7674
|
+
if (strict) {
|
|
7675
|
+
throw new Error(message, { cause: err });
|
|
7676
|
+
}
|
|
7677
|
+
logger.warn(message, { pkg });
|
|
7678
|
+
return { malicious: [], other: [], source: "fail-open" };
|
|
7679
|
+
}
|
|
7680
|
+
},
|
|
7681
|
+
async clearCache() {
|
|
7682
|
+
try {
|
|
7683
|
+
await fs30.promises.rm(cacheDir, { recursive: true, force: true });
|
|
7684
|
+
} catch {
|
|
7685
|
+
}
|
|
7686
|
+
}
|
|
7687
|
+
};
|
|
7688
|
+
}
|
|
7689
|
+
async function queryOsv(fetchFn, pkg) {
|
|
7690
|
+
const body = {
|
|
7691
|
+
package: { ecosystem: pkg.ecosystem, name: pkg.name }
|
|
7692
|
+
};
|
|
7693
|
+
if (pkg.version) body.version = pkg.version;
|
|
7694
|
+
const response = await fetchFn(OSV_ENDPOINT, {
|
|
7695
|
+
method: "POST",
|
|
7696
|
+
headers: { "content-type": "application/json" },
|
|
7697
|
+
body: JSON.stringify(body)
|
|
7698
|
+
});
|
|
7699
|
+
if (!response.ok) {
|
|
7700
|
+
throw new Error(`OSV returned HTTP ${response.status}`);
|
|
7701
|
+
}
|
|
7702
|
+
const json = await response.json();
|
|
7703
|
+
return json.vulns ?? [];
|
|
7704
|
+
}
|
|
7705
|
+
function classify(advisories) {
|
|
7706
|
+
const malicious = [];
|
|
7707
|
+
const other = [];
|
|
7708
|
+
for (const a of advisories) {
|
|
7709
|
+
if (typeof a?.id === "string" && a.id.startsWith("MAL-")) {
|
|
7710
|
+
malicious.push(a);
|
|
7711
|
+
} else {
|
|
7712
|
+
other.push(a);
|
|
7713
|
+
}
|
|
7714
|
+
}
|
|
7715
|
+
return { malicious, other };
|
|
7716
|
+
}
|
|
7717
|
+
async function readCache(cachePath, ttlMs) {
|
|
7718
|
+
try {
|
|
7719
|
+
const stat2 = await fs30.promises.stat(cachePath);
|
|
7720
|
+
if (Date.now() - stat2.mtimeMs > ttlMs) return null;
|
|
7721
|
+
const buf = await fs30.promises.readFile(cachePath, "utf-8");
|
|
7722
|
+
const parsed = JSON.parse(buf);
|
|
7723
|
+
return { malicious: parsed.malicious ?? [], other: parsed.other ?? [] };
|
|
7724
|
+
} catch {
|
|
7725
|
+
return null;
|
|
7726
|
+
}
|
|
7727
|
+
}
|
|
7728
|
+
async function writeCache(cachePath, payload) {
|
|
7729
|
+
try {
|
|
7730
|
+
await fs30.promises.mkdir(path26.dirname(cachePath), { recursive: true });
|
|
7731
|
+
await fs30.promises.writeFile(cachePath, JSON.stringify(payload, null, 2), "utf-8");
|
|
7732
|
+
} catch {
|
|
7733
|
+
}
|
|
7734
|
+
}
|
|
7735
|
+
function sanitizePkgName(name) {
|
|
7736
|
+
return name.replace(/[/\\]/g, "__");
|
|
7737
|
+
}
|
|
7617
7738
|
function scanForInjection(text) {
|
|
7618
7739
|
const findings = [];
|
|
7619
7740
|
const lines = text.split("\n");
|
|
@@ -7643,7 +7764,7 @@ function getInjectionPatterns() {
|
|
|
7643
7764
|
}
|
|
7644
7765
|
function getTaintFilePath(projectRoot, sessionId) {
|
|
7645
7766
|
const id = sessionId || DEFAULT_SESSION_ID;
|
|
7646
|
-
return
|
|
7767
|
+
return join382(projectRoot, ".harness", `session-taint-${id}.json`);
|
|
7647
7768
|
}
|
|
7648
7769
|
function readTaint(projectRoot, sessionId) {
|
|
7649
7770
|
const filePath = getTaintFilePath(projectRoot, sessionId);
|
|
@@ -7693,7 +7814,7 @@ function writeTaint(projectRoot, sessionId, reason, findings, source) {
|
|
|
7693
7814
|
const id = sessionId || DEFAULT_SESSION_ID;
|
|
7694
7815
|
const filePath = getTaintFilePath(projectRoot, id);
|
|
7695
7816
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7696
|
-
const dir =
|
|
7817
|
+
const dir = dirname10(filePath);
|
|
7697
7818
|
mkdirSync13(dir, { recursive: true });
|
|
7698
7819
|
const existing = readTaint(projectRoot, id);
|
|
7699
7820
|
const maxSeverity = findings.some((f) => f.severity === "high") ? "high" : "medium";
|
|
@@ -7725,14 +7846,14 @@ function clearTaint(projectRoot, sessionId) {
|
|
|
7725
7846
|
return 0;
|
|
7726
7847
|
}
|
|
7727
7848
|
}
|
|
7728
|
-
const harnessDir =
|
|
7849
|
+
const harnessDir = join382(projectRoot, ".harness");
|
|
7729
7850
|
let count = 0;
|
|
7730
7851
|
try {
|
|
7731
7852
|
const files = readdirSync3(harnessDir);
|
|
7732
7853
|
for (const file of files) {
|
|
7733
7854
|
if (file.startsWith("session-taint-") && file.endsWith(".json")) {
|
|
7734
7855
|
try {
|
|
7735
|
-
unlinkSync2(
|
|
7856
|
+
unlinkSync2(join382(harnessDir, file));
|
|
7736
7857
|
count++;
|
|
7737
7858
|
} catch {
|
|
7738
7859
|
}
|
|
@@ -7743,7 +7864,7 @@ function clearTaint(projectRoot, sessionId) {
|
|
|
7743
7864
|
return count;
|
|
7744
7865
|
}
|
|
7745
7866
|
function listTaintedSessions(projectRoot) {
|
|
7746
|
-
const harnessDir =
|
|
7867
|
+
const harnessDir = join382(projectRoot, ".harness");
|
|
7747
7868
|
const sessions = [];
|
|
7748
7869
|
try {
|
|
7749
7870
|
const files = readdirSync3(harnessDir);
|
|
@@ -7815,7 +7936,7 @@ function securityFindingId(finding) {
|
|
|
7815
7936
|
}
|
|
7816
7937
|
async function runValidateCheck(projectRoot, config) {
|
|
7817
7938
|
const issues = [];
|
|
7818
|
-
const agentsPath =
|
|
7939
|
+
const agentsPath = path27.join(projectRoot, config.agentsMapPath ?? "AGENTS.md");
|
|
7819
7940
|
const result = await validateAgentsMap(agentsPath);
|
|
7820
7941
|
if (!result.ok) {
|
|
7821
7942
|
issues.push({ severity: "error", message: result.error.message });
|
|
@@ -7872,7 +7993,7 @@ async function runDepsCheck(projectRoot, config) {
|
|
|
7872
7993
|
}
|
|
7873
7994
|
async function runDocsCheck(projectRoot, config) {
|
|
7874
7995
|
const issues = [];
|
|
7875
|
-
const docsDir =
|
|
7996
|
+
const docsDir = path27.join(projectRoot, config.docsDir ?? "docs");
|
|
7876
7997
|
const entropyConfig = config.entropy || {};
|
|
7877
7998
|
const result = await checkDocCoverage("project", {
|
|
7878
7999
|
docsDir,
|
|
@@ -8051,7 +8172,7 @@ async function runTraceabilityCheck(projectRoot, config) {
|
|
|
8051
8172
|
const issues = [];
|
|
8052
8173
|
const traceConfig = config.traceability || {};
|
|
8053
8174
|
if (traceConfig.enabled === false) return issues;
|
|
8054
|
-
const graphDir =
|
|
8175
|
+
const graphDir = path27.join(projectRoot, ".harness", "graph");
|
|
8055
8176
|
const store = new GraphStore();
|
|
8056
8177
|
const loaded = await store.load(graphDir);
|
|
8057
8178
|
if (!loaded) {
|
|
@@ -8229,7 +8350,7 @@ async function runMechanicalChecks(options) {
|
|
|
8229
8350
|
};
|
|
8230
8351
|
if (!skip.includes("validate")) {
|
|
8231
8352
|
try {
|
|
8232
|
-
const agentsPath =
|
|
8353
|
+
const agentsPath = path28.join(projectRoot, config.agentsMapPath ?? "AGENTS.md");
|
|
8233
8354
|
const result = await validateAgentsMap(agentsPath);
|
|
8234
8355
|
if (!result.ok) {
|
|
8235
8356
|
statuses.validate = "fail";
|
|
@@ -8266,7 +8387,7 @@ async function runMechanicalChecks(options) {
|
|
|
8266
8387
|
statuses.validate = "fail";
|
|
8267
8388
|
findings.push({
|
|
8268
8389
|
tool: "validate",
|
|
8269
|
-
file:
|
|
8390
|
+
file: path28.join(projectRoot, "AGENTS.md"),
|
|
8270
8391
|
message: err instanceof Error ? err.message : String(err),
|
|
8271
8392
|
severity: "error"
|
|
8272
8393
|
});
|
|
@@ -8330,7 +8451,7 @@ async function runMechanicalChecks(options) {
|
|
|
8330
8451
|
(async () => {
|
|
8331
8452
|
const localFindings = [];
|
|
8332
8453
|
try {
|
|
8333
|
-
const docsDir =
|
|
8454
|
+
const docsDir = path28.join(projectRoot, config.docsDir ?? "docs");
|
|
8334
8455
|
const result = await checkDocCoverage("project", { docsDir });
|
|
8335
8456
|
if (!result.ok) {
|
|
8336
8457
|
statuses["check-docs"] = "warn";
|
|
@@ -8357,7 +8478,7 @@ async function runMechanicalChecks(options) {
|
|
|
8357
8478
|
statuses["check-docs"] = "warn";
|
|
8358
8479
|
localFindings.push({
|
|
8359
8480
|
tool: "check-docs",
|
|
8360
|
-
file:
|
|
8481
|
+
file: path28.join(projectRoot, "docs"),
|
|
8361
8482
|
message: err instanceof Error ? err.message : String(err),
|
|
8362
8483
|
severity: "warning"
|
|
8363
8484
|
});
|
|
@@ -8454,18 +8575,18 @@ function computeContextBudget(diffLines) {
|
|
|
8454
8575
|
return diffLines;
|
|
8455
8576
|
}
|
|
8456
8577
|
function isWithinProject(absPath, projectRoot) {
|
|
8457
|
-
const resolvedRoot =
|
|
8458
|
-
const resolvedPath =
|
|
8459
|
-
return resolvedPath.startsWith(resolvedRoot) || resolvedPath ===
|
|
8578
|
+
const resolvedRoot = path29.resolve(projectRoot) + path29.sep;
|
|
8579
|
+
const resolvedPath = path29.resolve(absPath);
|
|
8580
|
+
return resolvedPath.startsWith(resolvedRoot) || resolvedPath === path29.resolve(projectRoot);
|
|
8460
8581
|
}
|
|
8461
8582
|
async function readContextFile(projectRoot, filePath, reason) {
|
|
8462
|
-
const absPath =
|
|
8583
|
+
const absPath = path29.isAbsolute(filePath) ? filePath : path29.join(projectRoot, filePath);
|
|
8463
8584
|
if (!isWithinProject(absPath, projectRoot)) return null;
|
|
8464
8585
|
const result = await readFileContent(absPath);
|
|
8465
8586
|
if (!result.ok) return null;
|
|
8466
8587
|
const content = result.value;
|
|
8467
8588
|
const lines = content.split("\n").length;
|
|
8468
|
-
const relPath2 =
|
|
8589
|
+
const relPath2 = path29.isAbsolute(filePath) ? relativePosix(projectRoot, filePath) : filePath;
|
|
8469
8590
|
return { path: relPath2, content, reason, lines };
|
|
8470
8591
|
}
|
|
8471
8592
|
function extractImportSources2(content) {
|
|
@@ -8480,24 +8601,24 @@ function extractImportSources2(content) {
|
|
|
8480
8601
|
}
|
|
8481
8602
|
async function resolveImportPath(projectRoot, fromFile, importSource) {
|
|
8482
8603
|
if (!importSource.startsWith(".")) return null;
|
|
8483
|
-
const fromDir =
|
|
8484
|
-
const basePath =
|
|
8604
|
+
const fromDir = path29.dirname(path29.join(projectRoot, fromFile));
|
|
8605
|
+
const basePath = path29.resolve(fromDir, importSource);
|
|
8485
8606
|
if (!isWithinProject(basePath, projectRoot)) return null;
|
|
8486
8607
|
const relBase = relativePosix(projectRoot, basePath);
|
|
8487
|
-
const sourceExt =
|
|
8608
|
+
const sourceExt = path29.extname(relBase);
|
|
8488
8609
|
const candidates = [];
|
|
8489
8610
|
const fallbacks = JS_EXT_FALLBACKS[sourceExt];
|
|
8490
8611
|
if (fallbacks) {
|
|
8491
8612
|
const stripped = relBase.slice(0, -sourceExt.length);
|
|
8492
8613
|
for (const ext of fallbacks) candidates.push(stripped + ext);
|
|
8493
|
-
candidates.push(
|
|
8494
|
-
candidates.push(
|
|
8495
|
-
candidates.push(
|
|
8614
|
+
candidates.push(path29.join(stripped, "index.ts"));
|
|
8615
|
+
candidates.push(path29.join(stripped, "index.tsx"));
|
|
8616
|
+
candidates.push(path29.join(stripped, "index.jsx"));
|
|
8496
8617
|
}
|
|
8497
8618
|
candidates.push(relBase + ".ts", relBase + ".tsx", relBase + ".mts");
|
|
8498
|
-
candidates.push(
|
|
8619
|
+
candidates.push(path29.join(relBase, "index.ts"));
|
|
8499
8620
|
for (const candidate of candidates) {
|
|
8500
|
-
const absCandidate =
|
|
8621
|
+
const absCandidate = path29.join(projectRoot, candidate);
|
|
8501
8622
|
if (await fileExists(absCandidate)) {
|
|
8502
8623
|
return candidate;
|
|
8503
8624
|
}
|
|
@@ -8505,7 +8626,7 @@ async function resolveImportPath(projectRoot, fromFile, importSource) {
|
|
|
8505
8626
|
return null;
|
|
8506
8627
|
}
|
|
8507
8628
|
async function findTestFiles(projectRoot, sourceFile) {
|
|
8508
|
-
const baseName =
|
|
8629
|
+
const baseName = path29.basename(sourceFile, path29.extname(sourceFile));
|
|
8509
8630
|
const pattern = `**/${baseName}.{test,spec}.{ts,tsx,mts}`;
|
|
8510
8631
|
const results = await findFiles(pattern, projectRoot);
|
|
8511
8632
|
return results.map((f) => relativePosix(projectRoot, f));
|
|
@@ -9273,7 +9394,7 @@ function normalizePath(filePath, projectRoot) {
|
|
|
9273
9394
|
let normalized = filePath;
|
|
9274
9395
|
normalized = normalized.replace(/\\/g, "/");
|
|
9275
9396
|
const normalizedRoot = projectRoot.replace(/\\/g, "/");
|
|
9276
|
-
if (
|
|
9397
|
+
if (path30.isAbsolute(normalized)) {
|
|
9277
9398
|
const root = normalizedRoot.endsWith("/") ? normalizedRoot : normalizedRoot + "/";
|
|
9278
9399
|
if (normalized.startsWith(root)) {
|
|
9279
9400
|
normalized = normalized.slice(root.length);
|
|
@@ -9285,12 +9406,12 @@ function normalizePath(filePath, projectRoot) {
|
|
|
9285
9406
|
return normalized;
|
|
9286
9407
|
}
|
|
9287
9408
|
function resolveImportPath2(currentFile, importPath) {
|
|
9288
|
-
const dir =
|
|
9289
|
-
let resolved =
|
|
9409
|
+
const dir = path30.dirname(currentFile);
|
|
9410
|
+
let resolved = path30.join(dir, importPath).replace(/\\/g, "/");
|
|
9290
9411
|
if (!resolved.match(/\.(ts|tsx|js|jsx)$/)) {
|
|
9291
9412
|
resolved += ".ts";
|
|
9292
9413
|
}
|
|
9293
|
-
return
|
|
9414
|
+
return path30.normalize(resolved).replace(/\\/g, "/");
|
|
9294
9415
|
}
|
|
9295
9416
|
function enqueueImports(content, current, visited, queue, maxDepth) {
|
|
9296
9417
|
const importRegex = /import\s+.*?from\s+['"]([^'"]+)['"]/g;
|
|
@@ -9322,7 +9443,7 @@ function isMechanicallyExcluded(finding, exclusionSet, projectRoot) {
|
|
|
9322
9443
|
const normalizedFile = normalizePath(finding.file, projectRoot);
|
|
9323
9444
|
if (exclusionSet.isExcluded(normalizedFile, finding.lineRange)) return true;
|
|
9324
9445
|
if (exclusionSet.isExcluded(finding.file, finding.lineRange)) return true;
|
|
9325
|
-
const absoluteFile =
|
|
9446
|
+
const absoluteFile = path30.isAbsolute(finding.file) ? finding.file : path30.join(projectRoot, finding.file).replace(/\\/g, "/");
|
|
9326
9447
|
return exclusionSet.isExcluded(absoluteFile, finding.lineRange);
|
|
9327
9448
|
}
|
|
9328
9449
|
async function validateWithGraph(crossFileRefs, graph) {
|
|
@@ -10330,7 +10451,7 @@ function isRegression(from, to) {
|
|
|
10330
10451
|
}
|
|
10331
10452
|
function collectAutopilotStatuses(autopilotPath, featurePlans, allTaskStatuses) {
|
|
10332
10453
|
try {
|
|
10333
|
-
const raw =
|
|
10454
|
+
const raw = fs31.readFileSync(autopilotPath, "utf-8");
|
|
10334
10455
|
const autopilot = JSON.parse(raw);
|
|
10335
10456
|
if (!autopilot.phases) return;
|
|
10336
10457
|
const linkedPhases = autopilot.phases.filter(
|
|
@@ -10362,10 +10483,10 @@ function inferStatus(feature, projectPath, allFeatures) {
|
|
|
10362
10483
|
const featuresWithPlans = allFeatures.filter((f) => f.plans.length > 0);
|
|
10363
10484
|
const useRootState = featuresWithPlans.length <= 1;
|
|
10364
10485
|
if (useRootState) {
|
|
10365
|
-
const rootStatePath =
|
|
10366
|
-
if (
|
|
10486
|
+
const rootStatePath = path31.join(projectPath, ".harness", "state.json");
|
|
10487
|
+
if (fs31.existsSync(rootStatePath)) {
|
|
10367
10488
|
try {
|
|
10368
|
-
const raw =
|
|
10489
|
+
const raw = fs31.readFileSync(rootStatePath, "utf-8");
|
|
10369
10490
|
const state = JSON.parse(raw);
|
|
10370
10491
|
if (state.progress) {
|
|
10371
10492
|
for (const status of Object.values(state.progress)) {
|
|
@@ -10376,14 +10497,14 @@ function inferStatus(feature, projectPath, allFeatures) {
|
|
|
10376
10497
|
}
|
|
10377
10498
|
}
|
|
10378
10499
|
}
|
|
10379
|
-
const sessionsDir =
|
|
10380
|
-
if (
|
|
10500
|
+
const sessionsDir = path31.join(projectPath, ".harness", "sessions");
|
|
10501
|
+
if (fs31.existsSync(sessionsDir)) {
|
|
10381
10502
|
try {
|
|
10382
|
-
const sessionDirs =
|
|
10503
|
+
const sessionDirs = fs31.readdirSync(sessionsDir, { withFileTypes: true });
|
|
10383
10504
|
for (const entry of sessionDirs) {
|
|
10384
10505
|
if (!entry.isDirectory()) continue;
|
|
10385
|
-
const autopilotPath =
|
|
10386
|
-
if (!
|
|
10506
|
+
const autopilotPath = path31.join(sessionsDir, entry.name, "autopilot-state.json");
|
|
10507
|
+
if (!fs31.existsSync(autopilotPath)) continue;
|
|
10387
10508
|
collectAutopilotStatuses(autopilotPath, feature.plans, allTaskStatuses);
|
|
10388
10509
|
}
|
|
10389
10510
|
} catch {
|
|
@@ -10498,9 +10619,9 @@ function isValidTrackerShape(tracker) {
|
|
|
10498
10619
|
}
|
|
10499
10620
|
function loadTrackerSyncConfig(projectRoot) {
|
|
10500
10621
|
try {
|
|
10501
|
-
const configPath =
|
|
10502
|
-
if (!
|
|
10503
|
-
const raw =
|
|
10622
|
+
const configPath = path32.join(projectRoot, "harness.config.json");
|
|
10623
|
+
if (!fs32.existsSync(configPath)) return null;
|
|
10624
|
+
const raw = fs32.readFileSync(configPath, "utf-8");
|
|
10504
10625
|
const config = JSON.parse(raw);
|
|
10505
10626
|
const tracker = config.roadmap?.tracker;
|
|
10506
10627
|
if (!isValidTrackerShape(tracker)) return null;
|
|
@@ -10620,7 +10741,7 @@ async function fullSync(roadmapPath, adapter2, config, options) {
|
|
|
10620
10741
|
});
|
|
10621
10742
|
await previousSync;
|
|
10622
10743
|
try {
|
|
10623
|
-
const raw =
|
|
10744
|
+
const raw = fs33.readFileSync(roadmapPath, "utf-8");
|
|
10624
10745
|
const parseResult = parseRoadmap(raw);
|
|
10625
10746
|
if (!parseResult.ok) {
|
|
10626
10747
|
return {
|
|
@@ -10633,7 +10754,7 @@ async function fullSync(roadmapPath, adapter2, config, options) {
|
|
|
10633
10754
|
const tickets = fetchResult.ok ? fetchResult.value : void 0;
|
|
10634
10755
|
const pushResult = await syncToExternal(roadmap, adapter2, config, tickets);
|
|
10635
10756
|
const pullResult = await syncFromExternal(roadmap, adapter2, config, options);
|
|
10636
|
-
|
|
10757
|
+
fs33.writeFileSync(roadmapPath, serializeRoadmap(roadmap), "utf-8");
|
|
10637
10758
|
return {
|
|
10638
10759
|
created: pushResult.created,
|
|
10639
10760
|
updated: pushResult.updated,
|
|
@@ -10986,9 +11107,9 @@ function makeTrackerConflictBody(err, opts = {}) {
|
|
|
10986
11107
|
}
|
|
10987
11108
|
function loadProjectRoadmapMode(projectRoot) {
|
|
10988
11109
|
try {
|
|
10989
|
-
const configPath =
|
|
10990
|
-
if (!
|
|
10991
|
-
const raw =
|
|
11110
|
+
const configPath = path33.join(projectRoot, "harness.config.json");
|
|
11111
|
+
if (!fs34.existsSync(configPath)) return getRoadmapMode(null);
|
|
11112
|
+
const raw = fs34.readFileSync(configPath, "utf-8");
|
|
10992
11113
|
const parsed = JSON.parse(raw);
|
|
10993
11114
|
return getRoadmapMode(parsed);
|
|
10994
11115
|
} catch {
|
|
@@ -10997,11 +11118,11 @@ function loadProjectRoadmapMode(projectRoot) {
|
|
|
10997
11118
|
}
|
|
10998
11119
|
function loadTrackerClientConfigFromProject(projectRoot) {
|
|
10999
11120
|
try {
|
|
11000
|
-
const configPath =
|
|
11001
|
-
if (!
|
|
11121
|
+
const configPath = path34.join(projectRoot, "harness.config.json");
|
|
11122
|
+
if (!fs35.existsSync(configPath)) {
|
|
11002
11123
|
return Err(new Error("harness.config.json not found"));
|
|
11003
11124
|
}
|
|
11004
|
-
const cfg = JSON.parse(
|
|
11125
|
+
const cfg = JSON.parse(fs35.readFileSync(configPath, "utf-8"));
|
|
11005
11126
|
const tracker = cfg.roadmap?.tracker;
|
|
11006
11127
|
if (!tracker) {
|
|
11007
11128
|
return Err(
|
|
@@ -11207,10 +11328,10 @@ function mapAction(action) {
|
|
|
11207
11328
|
}
|
|
11208
11329
|
async function runMigrationPlan(plan, deps, opts) {
|
|
11209
11330
|
const projectRoot = opts.projectRoot;
|
|
11210
|
-
const roadmapPath =
|
|
11211
|
-
const archivedPath =
|
|
11212
|
-
const configPath =
|
|
11213
|
-
const configBackupPath =
|
|
11331
|
+
const roadmapPath = path35.join(projectRoot, "docs", "roadmap.md");
|
|
11332
|
+
const archivedPath = path35.join(projectRoot, "docs", "roadmap.md.archived");
|
|
11333
|
+
const configPath = path35.join(projectRoot, "harness.config.json");
|
|
11334
|
+
const configBackupPath = path35.join(projectRoot, "harness.config.json.pre-migration");
|
|
11214
11335
|
const createdSoFar = [];
|
|
11215
11336
|
const report = {
|
|
11216
11337
|
created: 0,
|
|
@@ -11322,7 +11443,7 @@ async function runMigrationPlan(plan, deps, opts) {
|
|
|
11322
11443
|
}
|
|
11323
11444
|
function getStatePath() {
|
|
11324
11445
|
const home = process.env["HOME"] || os.homedir();
|
|
11325
|
-
return
|
|
11446
|
+
return path38.join(home, ".harness", "update-check.json");
|
|
11326
11447
|
}
|
|
11327
11448
|
function isUpdateCheckEnabled(configInterval) {
|
|
11328
11449
|
if (process.env["HARNESS_NO_UPDATE_CHECK"] === "1") return false;
|
|
@@ -11335,13 +11456,13 @@ function shouldRunCheck(state, intervalMs) {
|
|
|
11335
11456
|
}
|
|
11336
11457
|
function invalidateCheckState() {
|
|
11337
11458
|
try {
|
|
11338
|
-
|
|
11459
|
+
fs38.unlinkSync(getStatePath());
|
|
11339
11460
|
} catch {
|
|
11340
11461
|
}
|
|
11341
11462
|
}
|
|
11342
11463
|
function readCheckState() {
|
|
11343
11464
|
try {
|
|
11344
|
-
const raw =
|
|
11465
|
+
const raw = fs38.readFileSync(getStatePath(), "utf-8");
|
|
11345
11466
|
const parsed = JSON.parse(raw);
|
|
11346
11467
|
if (typeof parsed === "object" && parsed !== null && "lastCheckTime" in parsed && typeof parsed.lastCheckTime === "number" && "currentVersion" in parsed && typeof parsed.currentVersion === "string") {
|
|
11347
11468
|
const state = parsed;
|
|
@@ -11358,7 +11479,7 @@ function readCheckState() {
|
|
|
11358
11479
|
}
|
|
11359
11480
|
function spawnBackgroundCheck(currentVersion) {
|
|
11360
11481
|
const statePath = getStatePath();
|
|
11361
|
-
const stateDir =
|
|
11482
|
+
const stateDir = path38.dirname(statePath);
|
|
11362
11483
|
const script = `
|
|
11363
11484
|
const { execSync } = require('child_process');
|
|
11364
11485
|
const fs = require('fs');
|
|
@@ -11601,14 +11722,14 @@ function getModelPrice(model, dataset) {
|
|
|
11601
11722
|
return pricing;
|
|
11602
11723
|
}
|
|
11603
11724
|
function getCachePath(projectRoot) {
|
|
11604
|
-
return
|
|
11725
|
+
return path39.join(projectRoot, ".harness", "cache", "pricing.json");
|
|
11605
11726
|
}
|
|
11606
11727
|
function getStalenessMarkerPath(projectRoot) {
|
|
11607
|
-
return
|
|
11728
|
+
return path39.join(projectRoot, ".harness", "cache", "staleness-marker.json");
|
|
11608
11729
|
}
|
|
11609
11730
|
async function readDiskCache(projectRoot) {
|
|
11610
11731
|
try {
|
|
11611
|
-
const raw = await
|
|
11732
|
+
const raw = await fs39.readFile(getCachePath(projectRoot), "utf-8");
|
|
11612
11733
|
return JSON.parse(raw);
|
|
11613
11734
|
} catch {
|
|
11614
11735
|
return null;
|
|
@@ -11616,8 +11737,8 @@ async function readDiskCache(projectRoot) {
|
|
|
11616
11737
|
}
|
|
11617
11738
|
async function writeDiskCache(projectRoot, data) {
|
|
11618
11739
|
const cachePath = getCachePath(projectRoot);
|
|
11619
|
-
await
|
|
11620
|
-
await
|
|
11740
|
+
await fs39.mkdir(path39.dirname(cachePath), { recursive: true });
|
|
11741
|
+
await fs39.writeFile(cachePath, JSON.stringify(data, null, 2));
|
|
11621
11742
|
}
|
|
11622
11743
|
async function fetchFromNetwork() {
|
|
11623
11744
|
try {
|
|
@@ -11644,7 +11765,7 @@ function loadFallbackDataset() {
|
|
|
11644
11765
|
async function checkAndWarnStaleness(projectRoot) {
|
|
11645
11766
|
const markerPath = getStalenessMarkerPath(projectRoot);
|
|
11646
11767
|
try {
|
|
11647
|
-
const raw = await
|
|
11768
|
+
const raw = await fs39.readFile(markerPath, "utf-8");
|
|
11648
11769
|
const marker = JSON.parse(raw);
|
|
11649
11770
|
const firstUse = new Date(marker.firstFallbackUse).getTime();
|
|
11650
11771
|
const now = Date.now();
|
|
@@ -11656,8 +11777,8 @@ async function checkAndWarnStaleness(projectRoot) {
|
|
|
11656
11777
|
}
|
|
11657
11778
|
} catch {
|
|
11658
11779
|
try {
|
|
11659
|
-
await
|
|
11660
|
-
await
|
|
11780
|
+
await fs39.mkdir(path39.dirname(markerPath), { recursive: true });
|
|
11781
|
+
await fs39.writeFile(
|
|
11661
11782
|
markerPath,
|
|
11662
11783
|
JSON.stringify({ firstFallbackUse: (/* @__PURE__ */ new Date()).toISOString() })
|
|
11663
11784
|
);
|
|
@@ -11667,7 +11788,7 @@ async function checkAndWarnStaleness(projectRoot) {
|
|
|
11667
11788
|
}
|
|
11668
11789
|
async function clearStalenessMarker(projectRoot) {
|
|
11669
11790
|
try {
|
|
11670
|
-
await
|
|
11791
|
+
await fs39.unlink(getStalenessMarkerPath(projectRoot));
|
|
11671
11792
|
} catch {
|
|
11672
11793
|
}
|
|
11673
11794
|
}
|
|
@@ -11904,10 +12025,10 @@ function parseLine(line, lineNumber) {
|
|
|
11904
12025
|
return record;
|
|
11905
12026
|
}
|
|
11906
12027
|
function readCostRecords(projectRoot) {
|
|
11907
|
-
const costsFile =
|
|
12028
|
+
const costsFile = path40.join(projectRoot, ".harness", "metrics", "costs.jsonl");
|
|
11908
12029
|
let raw;
|
|
11909
12030
|
try {
|
|
11910
|
-
raw =
|
|
12031
|
+
raw = fs40.readFileSync(costsFile, "utf-8");
|
|
11911
12032
|
} catch {
|
|
11912
12033
|
return [];
|
|
11913
12034
|
}
|
|
@@ -11957,7 +12078,7 @@ function parseCCLine(line, filePath, lineNumber) {
|
|
|
11957
12078
|
entry = JSON.parse(line);
|
|
11958
12079
|
} catch {
|
|
11959
12080
|
console.warn(
|
|
11960
|
-
`[harness usage] Skipping malformed CC JSONL line ${lineNumber} in ${
|
|
12081
|
+
`[harness usage] Skipping malformed CC JSONL line ${lineNumber} in ${path41.basename(filePath)}`
|
|
11961
12082
|
);
|
|
11962
12083
|
return null;
|
|
11963
12084
|
}
|
|
@@ -11971,7 +12092,7 @@ function parseCCLine(line, filePath, lineNumber) {
|
|
|
11971
12092
|
function readCCFile(filePath) {
|
|
11972
12093
|
let raw;
|
|
11973
12094
|
try {
|
|
11974
|
-
raw =
|
|
12095
|
+
raw = fs41.readFileSync(filePath, "utf-8");
|
|
11975
12096
|
} catch {
|
|
11976
12097
|
return [];
|
|
11977
12098
|
}
|
|
@@ -11993,10 +12114,10 @@ function readCCFile(filePath) {
|
|
|
11993
12114
|
}
|
|
11994
12115
|
function parseCCRecords() {
|
|
11995
12116
|
const homeDir = process.env.HOME ?? os2.homedir();
|
|
11996
|
-
const projectsDir =
|
|
12117
|
+
const projectsDir = path41.join(homeDir, ".claude", "projects");
|
|
11997
12118
|
let projectDirs;
|
|
11998
12119
|
try {
|
|
11999
|
-
projectDirs =
|
|
12120
|
+
projectDirs = fs41.readdirSync(projectsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => path41.join(projectsDir, d.name));
|
|
12000
12121
|
} catch {
|
|
12001
12122
|
return [];
|
|
12002
12123
|
}
|
|
@@ -12004,7 +12125,7 @@ function parseCCRecords() {
|
|
|
12004
12125
|
for (const dir of projectDirs) {
|
|
12005
12126
|
let files;
|
|
12006
12127
|
try {
|
|
12007
|
-
files =
|
|
12128
|
+
files = fs41.readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) => path41.join(dir, f));
|
|
12008
12129
|
} catch {
|
|
12009
12130
|
continue;
|
|
12010
12131
|
}
|
|
@@ -12032,10 +12153,10 @@ function parseLine2(line, lineNumber) {
|
|
|
12032
12153
|
}
|
|
12033
12154
|
}
|
|
12034
12155
|
function readAdoptionRecords(projectRoot) {
|
|
12035
|
-
const adoptionFile =
|
|
12156
|
+
const adoptionFile = path42.join(projectRoot, ".harness", "metrics", "adoption.jsonl");
|
|
12036
12157
|
let raw;
|
|
12037
12158
|
try {
|
|
12038
|
-
raw =
|
|
12159
|
+
raw = fs42.readFileSync(adoptionFile, "utf-8");
|
|
12039
12160
|
} catch {
|
|
12040
12161
|
return [];
|
|
12041
12162
|
}
|
|
@@ -12108,13 +12229,13 @@ function topSkills(records, n) {
|
|
|
12108
12229
|
return aggregateBySkill(records).slice(0, n);
|
|
12109
12230
|
}
|
|
12110
12231
|
function loadNotificationsConfig(projectRoot) {
|
|
12111
|
-
const configPath =
|
|
12112
|
-
if (!
|
|
12232
|
+
const configPath = path43.join(projectRoot, "harness.config.json");
|
|
12233
|
+
if (!fs43.existsSync(configPath)) {
|
|
12113
12234
|
return Ok({ sinks: [] });
|
|
12114
12235
|
}
|
|
12115
12236
|
let raw;
|
|
12116
12237
|
try {
|
|
12117
|
-
raw =
|
|
12238
|
+
raw = fs43.readFileSync(configPath, "utf-8");
|
|
12118
12239
|
} catch (err) {
|
|
12119
12240
|
return Err(err instanceof Error ? err : new Error(String(err)));
|
|
12120
12241
|
}
|
|
@@ -12215,25 +12336,25 @@ function resolveStability(contentType) {
|
|
|
12215
12336
|
return STABILITY_LOOKUP[contentType] ?? "ephemeral";
|
|
12216
12337
|
}
|
|
12217
12338
|
function getOrCreateInstallId(projectRoot) {
|
|
12218
|
-
const harnessDir =
|
|
12219
|
-
const installIdFile =
|
|
12339
|
+
const harnessDir = path44.join(projectRoot, ".harness");
|
|
12340
|
+
const installIdFile = path44.join(harnessDir, ".install-id");
|
|
12220
12341
|
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
12221
12342
|
try {
|
|
12222
|
-
const existing =
|
|
12343
|
+
const existing = fs44.readFileSync(installIdFile, "utf-8").trim();
|
|
12223
12344
|
if (UUID_V4_RE.test(existing)) {
|
|
12224
12345
|
return existing;
|
|
12225
12346
|
}
|
|
12226
12347
|
} catch {
|
|
12227
12348
|
}
|
|
12228
12349
|
const id = crypto4.randomUUID();
|
|
12229
|
-
|
|
12230
|
-
|
|
12350
|
+
fs44.mkdirSync(harnessDir, { recursive: true });
|
|
12351
|
+
fs44.writeFileSync(installIdFile, id, { encoding: "utf-8", mode: 384 });
|
|
12231
12352
|
return id;
|
|
12232
12353
|
}
|
|
12233
12354
|
function parseIdentityFromTelemetryFile(filePath) {
|
|
12234
12355
|
const identity = {};
|
|
12235
12356
|
try {
|
|
12236
|
-
const raw =
|
|
12357
|
+
const raw = fs45.readFileSync(filePath, "utf-8");
|
|
12237
12358
|
const parsed = JSON.parse(raw);
|
|
12238
12359
|
const src = parsed?.identity;
|
|
12239
12360
|
if (!src || typeof src !== "object") return identity;
|
|
@@ -12246,7 +12367,7 @@ function parseIdentityFromTelemetryFile(filePath) {
|
|
|
12246
12367
|
}
|
|
12247
12368
|
function readProjectNameFallback(configPath) {
|
|
12248
12369
|
try {
|
|
12249
|
-
const raw =
|
|
12370
|
+
const raw = fs45.readFileSync(configPath, "utf-8");
|
|
12250
12371
|
const config = JSON.parse(raw);
|
|
12251
12372
|
return typeof config?.name === "string" ? config.name : void 0;
|
|
12252
12373
|
} catch {
|
|
@@ -12267,10 +12388,10 @@ function readGitAliasFallback(cwd) {
|
|
|
12267
12388
|
}
|
|
12268
12389
|
}
|
|
12269
12390
|
function readIdentity(projectRoot) {
|
|
12270
|
-
const filePath =
|
|
12391
|
+
const filePath = path45.join(projectRoot, ".harness", "telemetry.json");
|
|
12271
12392
|
const identity = parseIdentityFromTelemetryFile(filePath);
|
|
12272
12393
|
if (!identity.project) {
|
|
12273
|
-
const fallbackProject = readProjectNameFallback(
|
|
12394
|
+
const fallbackProject = readProjectNameFallback(path45.join(projectRoot, "harness.config.json"));
|
|
12274
12395
|
if (fallbackProject) identity.project = fallbackProject;
|
|
12275
12396
|
}
|
|
12276
12397
|
if (!identity.alias) {
|
|
@@ -12367,12 +12488,12 @@ function acquireCompoundLock(category, opts = {}) {
|
|
|
12367
12488
|
);
|
|
12368
12489
|
}
|
|
12369
12490
|
const cwd = opts.cwd ?? process.cwd();
|
|
12370
|
-
const lockDir =
|
|
12371
|
-
|
|
12372
|
-
const lockPath =
|
|
12491
|
+
const lockDir = path46.join(cwd, ".harness", "locks");
|
|
12492
|
+
fs46.mkdirSync(lockDir, { recursive: true });
|
|
12493
|
+
const lockPath = path46.join(lockDir, `compound-${category}.lock`);
|
|
12373
12494
|
let fd;
|
|
12374
12495
|
try {
|
|
12375
|
-
fd =
|
|
12496
|
+
fd = fs46.openSync(lockPath, "wx");
|
|
12376
12497
|
} catch (e) {
|
|
12377
12498
|
const err = e;
|
|
12378
12499
|
if (err.code === "EEXIST") {
|
|
@@ -12381,14 +12502,14 @@ function acquireCompoundLock(category, opts = {}) {
|
|
|
12381
12502
|
}
|
|
12382
12503
|
throw err;
|
|
12383
12504
|
}
|
|
12384
|
-
|
|
12385
|
-
|
|
12505
|
+
fs46.writeSync(fd, String(process.pid));
|
|
12506
|
+
fs46.closeSync(fd);
|
|
12386
12507
|
let released = false;
|
|
12387
12508
|
const release = () => {
|
|
12388
12509
|
if (released) return;
|
|
12389
12510
|
released = true;
|
|
12390
12511
|
try {
|
|
12391
|
-
|
|
12512
|
+
fs46.unlinkSync(lockPath);
|
|
12392
12513
|
} catch {
|
|
12393
12514
|
}
|
|
12394
12515
|
process.removeListener("exit", onExit);
|
|
@@ -12414,7 +12535,7 @@ function acquireCompoundLock(category, opts = {}) {
|
|
|
12414
12535
|
}
|
|
12415
12536
|
function readHolderPid(lockPath) {
|
|
12416
12537
|
try {
|
|
12417
|
-
const raw =
|
|
12538
|
+
const raw = fs46.readFileSync(lockPath, "utf-8").trim();
|
|
12418
12539
|
const n = Number.parseInt(raw, 10);
|
|
12419
12540
|
return Number.isFinite(n) ? n : -1;
|
|
12420
12541
|
} catch {
|
|
@@ -12439,10 +12560,10 @@ function assertSanitized(value) {
|
|
|
12439
12560
|
}
|
|
12440
12561
|
function writePulseConfig(config, opts) {
|
|
12441
12562
|
PulseConfigSchema.parse(config);
|
|
12442
|
-
if (!
|
|
12563
|
+
if (!fs47.existsSync(opts.configPath)) {
|
|
12443
12564
|
throw new Error(`harness.config.json not found at ${opts.configPath}`);
|
|
12444
12565
|
}
|
|
12445
|
-
const raw =
|
|
12566
|
+
const raw = fs47.readFileSync(opts.configPath, "utf-8");
|
|
12446
12567
|
let parsed;
|
|
12447
12568
|
try {
|
|
12448
12569
|
parsed = JSON.parse(raw);
|
|
@@ -12450,18 +12571,18 @@ function writePulseConfig(config, opts) {
|
|
|
12450
12571
|
throw new Error(`Invalid JSON in ${opts.configPath}: ${e.message}`, { cause: e });
|
|
12451
12572
|
}
|
|
12452
12573
|
const bakPath = `${opts.configPath}.bak`;
|
|
12453
|
-
if (!opts.skipBackup && !
|
|
12454
|
-
|
|
12574
|
+
if (!opts.skipBackup && !fs47.existsSync(bakPath)) {
|
|
12575
|
+
fs47.writeFileSync(bakPath, raw, "utf-8");
|
|
12455
12576
|
}
|
|
12456
12577
|
parsed.pulse = config;
|
|
12457
12578
|
const serialized = JSON.stringify(parsed, null, 2) + "\n";
|
|
12458
12579
|
const tmpPath = `${opts.configPath}.tmp-${process.pid}`;
|
|
12459
|
-
|
|
12580
|
+
fs47.writeFileSync(tmpPath, serialized, "utf-8");
|
|
12460
12581
|
try {
|
|
12461
|
-
|
|
12582
|
+
fs47.renameSync(tmpPath, opts.configPath);
|
|
12462
12583
|
} catch (e) {
|
|
12463
12584
|
try {
|
|
12464
|
-
|
|
12585
|
+
fs47.unlinkSync(tmpPath);
|
|
12465
12586
|
} catch {
|
|
12466
12587
|
}
|
|
12467
12588
|
throw e;
|
|
@@ -12469,12 +12590,12 @@ function writePulseConfig(config, opts) {
|
|
|
12469
12590
|
}
|
|
12470
12591
|
function seedFromStrategy(opts = {}) {
|
|
12471
12592
|
const cwd = opts.cwd ?? process.cwd();
|
|
12472
|
-
const strategyPath =
|
|
12593
|
+
const strategyPath = path47.join(cwd, "STRATEGY.md");
|
|
12473
12594
|
const warnings = [];
|
|
12474
|
-
if (!
|
|
12595
|
+
if (!fs48.existsSync(strategyPath)) {
|
|
12475
12596
|
return { name: null, keyMetrics: [], warnings: ["STRATEGY.md not found"] };
|
|
12476
12597
|
}
|
|
12477
|
-
const raw =
|
|
12598
|
+
const raw = fs48.readFileSync(strategyPath, "utf-8");
|
|
12478
12599
|
let name = null;
|
|
12479
12600
|
const fmMatch = /^---\s*\n([\s\S]*?)\n---\s*\n/.exec(raw);
|
|
12480
12601
|
const fm = fmMatch?.[1];
|
|
@@ -12625,8 +12746,8 @@ function loadTemplate() {
|
|
|
12625
12746
|
try {
|
|
12626
12747
|
const url = import.meta?.url;
|
|
12627
12748
|
if (!url) return INLINE_TEMPLATE;
|
|
12628
|
-
const here =
|
|
12629
|
-
return readFileSync392(
|
|
12749
|
+
const here = dirname16(fileURLToPath(url));
|
|
12750
|
+
return readFileSync392(join612(here, "template.md"), "utf-8");
|
|
12630
12751
|
} catch {
|
|
12631
12752
|
return INLINE_TEMPLATE;
|
|
12632
12753
|
}
|
|
@@ -12815,11 +12936,11 @@ async function computeHotspots(opts) {
|
|
|
12815
12936
|
}
|
|
12816
12937
|
const counts = /* @__PURE__ */ new Map();
|
|
12817
12938
|
for (const line of stdout.split("\n")) {
|
|
12818
|
-
const
|
|
12819
|
-
if (
|
|
12820
|
-
counts.set(
|
|
12939
|
+
const path50 = line.trim();
|
|
12940
|
+
if (path50.length === 0) continue;
|
|
12941
|
+
counts.set(path50, (counts.get(path50) ?? 0) + 1);
|
|
12821
12942
|
}
|
|
12822
|
-
return [...counts.entries()].filter(([, c]) => c > opts.threshold).map(([
|
|
12943
|
+
return [...counts.entries()].filter(([, c]) => c > opts.threshold).map(([path50, churn]) => ({ path: path50, churn })).sort((a, b) => b.churn - a.churn);
|
|
12823
12944
|
}
|
|
12824
12945
|
function tokenize(text) {
|
|
12825
12946
|
return new Set(
|
|
@@ -12829,12 +12950,12 @@ function tokenize(text) {
|
|
|
12829
12950
|
async function* walk2(dir) {
|
|
12830
12951
|
let entries;
|
|
12831
12952
|
try {
|
|
12832
|
-
entries = await
|
|
12953
|
+
entries = await fs49.readdir(dir, { withFileTypes: true });
|
|
12833
12954
|
} catch {
|
|
12834
12955
|
return;
|
|
12835
12956
|
}
|
|
12836
12957
|
for (const e of entries) {
|
|
12837
|
-
const p =
|
|
12958
|
+
const p = path48.join(dir, e.name);
|
|
12838
12959
|
if (e.isDirectory()) yield* walk2(p);
|
|
12839
12960
|
else if (e.isFile() && e.name.endsWith(".md")) yield p;
|
|
12840
12961
|
}
|
|
@@ -12843,11 +12964,11 @@ async function readDocumentedTokens(solutionsDir) {
|
|
|
12843
12964
|
const docs = [];
|
|
12844
12965
|
for (const [track, categories] of TRACK_CATEGORIES2) {
|
|
12845
12966
|
for (const category of categories) {
|
|
12846
|
-
const dir =
|
|
12967
|
+
const dir = path48.join(solutionsDir, track, category);
|
|
12847
12968
|
for await (const file of walk2(dir)) {
|
|
12848
|
-
const raw = await
|
|
12969
|
+
const raw = await fs49.readFile(file, "utf-8");
|
|
12849
12970
|
const m = /^#\s+(.+)$/m.exec(raw);
|
|
12850
|
-
const title = m?.[1] ??
|
|
12971
|
+
const title = m?.[1] ?? path48.basename(file, ".md");
|
|
12851
12972
|
docs.push(tokenize(title));
|
|
12852
12973
|
}
|
|
12853
12974
|
}
|
|
@@ -12910,7 +13031,113 @@ function assembleCandidateReport(input) {
|
|
|
12910
13031
|
}
|
|
12911
13032
|
return lines.join("\n");
|
|
12912
13033
|
}
|
|
12913
|
-
|
|
13034
|
+
function proposalsDir(projectPath) {
|
|
13035
|
+
return path49.join(projectPath, ".harness", "proposals");
|
|
13036
|
+
}
|
|
13037
|
+
function proposalPath(projectPath, id) {
|
|
13038
|
+
return path49.join(proposalsDir(projectPath), `${id}.json`);
|
|
13039
|
+
}
|
|
13040
|
+
function ensureDir(dir) {
|
|
13041
|
+
fs50.mkdirSync(dir, { recursive: true });
|
|
13042
|
+
}
|
|
13043
|
+
function writeAtomic(filePath, content) {
|
|
13044
|
+
const tmpPath = `${filePath}.tmp`;
|
|
13045
|
+
fs50.writeFileSync(tmpPath, content);
|
|
13046
|
+
fs50.renameSync(tmpPath, filePath);
|
|
13047
|
+
}
|
|
13048
|
+
async function createProposal(projectPath, input) {
|
|
13049
|
+
const validated = EmitSkillProposalInputSchema.parse(input);
|
|
13050
|
+
const id = `proposal_${randomUUID2().replace(/-/g, "")}`;
|
|
13051
|
+
const proposal = SkillProposalSchema.parse({
|
|
13052
|
+
id,
|
|
13053
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13054
|
+
kind: validated.kind,
|
|
13055
|
+
targetSkill: validated.targetSkill,
|
|
13056
|
+
proposedBy: validated.proposedBy,
|
|
13057
|
+
source: {
|
|
13058
|
+
sessionId: validated.sessionId,
|
|
13059
|
+
taskId: validated.taskId,
|
|
13060
|
+
justification: validated.justification
|
|
13061
|
+
},
|
|
13062
|
+
content: validated.content,
|
|
13063
|
+
status: "open"
|
|
13064
|
+
});
|
|
13065
|
+
if (proposal.kind === "refinement" && proposal.targetSkill) {
|
|
13066
|
+
const existing = await listProposals(projectPath, { status: "open" });
|
|
13067
|
+
const clash = existing.find(
|
|
13068
|
+
(p) => p.kind === "refinement" && p.targetSkill === proposal.targetSkill
|
|
13069
|
+
);
|
|
13070
|
+
if (clash) {
|
|
13071
|
+
throw new ProposalConflictError(
|
|
13072
|
+
`An open refinement proposal already exists for skill "${proposal.targetSkill}" (id: ${clash.id})`
|
|
13073
|
+
);
|
|
13074
|
+
}
|
|
13075
|
+
}
|
|
13076
|
+
const dir = proposalsDir(projectPath);
|
|
13077
|
+
ensureDir(dir);
|
|
13078
|
+
writeAtomic(proposalPath(projectPath, id), JSON.stringify(proposal, null, 2));
|
|
13079
|
+
return proposal;
|
|
13080
|
+
}
|
|
13081
|
+
async function getProposal(projectPath, id) {
|
|
13082
|
+
const file = proposalPath(projectPath, id);
|
|
13083
|
+
try {
|
|
13084
|
+
const raw = fs50.readFileSync(file, "utf-8");
|
|
13085
|
+
const parsed = SkillProposalSchema.safeParse(JSON.parse(raw));
|
|
13086
|
+
return parsed.success ? parsed.data : null;
|
|
13087
|
+
} catch {
|
|
13088
|
+
return null;
|
|
13089
|
+
}
|
|
13090
|
+
}
|
|
13091
|
+
async function listProposals(projectPath, opts = {}) {
|
|
13092
|
+
const dir = proposalsDir(projectPath);
|
|
13093
|
+
let files;
|
|
13094
|
+
try {
|
|
13095
|
+
files = fs50.readdirSync(dir);
|
|
13096
|
+
} catch {
|
|
13097
|
+
return [];
|
|
13098
|
+
}
|
|
13099
|
+
const out = [];
|
|
13100
|
+
for (const file of files) {
|
|
13101
|
+
if (!file.endsWith(".json")) continue;
|
|
13102
|
+
const id = file.slice(0, -".json".length);
|
|
13103
|
+
const proposal = await getProposal(projectPath, id);
|
|
13104
|
+
if (!proposal) continue;
|
|
13105
|
+
if (opts.status && opts.status !== "all" && proposal.status !== opts.status) continue;
|
|
13106
|
+
out.push(proposal);
|
|
13107
|
+
}
|
|
13108
|
+
out.sort((a, b) => a.createdAt > b.createdAt ? -1 : a.createdAt < b.createdAt ? 1 : 0);
|
|
13109
|
+
return out;
|
|
13110
|
+
}
|
|
13111
|
+
async function updateProposal(projectPath, id, patch) {
|
|
13112
|
+
const current = await getProposal(projectPath, id);
|
|
13113
|
+
if (!current) throw new ProposalNotFoundError(id);
|
|
13114
|
+
const next = SkillProposalSchema.parse({
|
|
13115
|
+
...current,
|
|
13116
|
+
...patch,
|
|
13117
|
+
id: current.id,
|
|
13118
|
+
createdAt: current.createdAt,
|
|
13119
|
+
kind: current.kind
|
|
13120
|
+
});
|
|
13121
|
+
writeAtomic(proposalPath(projectPath, id), JSON.stringify(next, null, 2));
|
|
13122
|
+
return next;
|
|
13123
|
+
}
|
|
13124
|
+
function deriveSkillUsage(projectRoot, skillName, windowDays = 30) {
|
|
13125
|
+
const records = readAdoptionRecords(projectRoot);
|
|
13126
|
+
const cutoffMs = Date.now() - windowDays * 24 * 60 * 60 * 1e3;
|
|
13127
|
+
let count = 0;
|
|
13128
|
+
let lastUsed;
|
|
13129
|
+
for (const rec of records) {
|
|
13130
|
+
if (rec.skill !== skillName) continue;
|
|
13131
|
+
const startedMs = Date.parse(rec.startedAt);
|
|
13132
|
+
if (Number.isFinite(startedMs) && startedMs < cutoffMs) continue;
|
|
13133
|
+
count += 1;
|
|
13134
|
+
if (!lastUsed || rec.startedAt > lastUsed) lastUsed = rec.startedAt;
|
|
13135
|
+
}
|
|
13136
|
+
const stats = { count, windowDays };
|
|
13137
|
+
if (lastUsed) stats.lastUsed = lastUsed;
|
|
13138
|
+
return stats;
|
|
13139
|
+
}
|
|
13140
|
+
var WHATWG_BAD_PORTS, BAD_PORT_SET, VALID_TYPES, CONVENTIONAL_PATTERN, LOOKBACK_PATTERN, PulseDbSourceSchema, PulseSourcesSchema, PulseConfigSchema, BUG_TRACK_CATEGORIES, KNOWLEDGE_TRACK_CATEGORIES, ALL_SOLUTION_CATEGORIES, ISO_DATE, BugTrackSchema, KnowledgeTrackSchema, BaseFrontmatter, SolutionDocFrontmatterSchema, TRACK_CATEGORIES, DEFAULT_AGNIX_TIMEOUT_MS, HARNESS_AGNIX_DISABLE, HARNESS_AGNIX_BIN, CLAUDE_MD_WARN_BYTES, CLAUDE_MD_ERROR_BYTES, CONTEXT_FILES, MIN_DESCRIPTION_LENGTH, SETTINGS_PATHS, KNOWN_HOOK_EVENTS, MCP_SETTINGS_FILES, REQUIRED_SECTIONS, SETTINGS_FILES, KNOWN_AGNIX_TOOLS, KEBAB_CASE, TICKET_ID, DEFAULT_SECTIONS, DEFAULT_RATIOS, NODE_TYPE_TO_CATEGORY, SECTION_LEVEL_MAP, DEFAULT_LEVEL, DEFAULT_BUDGET, DEFAULT_LOADER_CONFIG, LEVEL_FRACTIONS, PHASE_PRIORITIES, ManifestSchema, BundleConstraintsSchema, BundleSchema, ContributionsSchema, LockfilePackageSchema, LockfileSchema, SharableLayerSchema, SharableForbiddenImportSchema, SharableBoundaryConfigSchema, SharableSecurityRulesSchema, VALID_SCOPES, LINE_PATTERN, START_PATTERN, END_PATTERN, readFile62, writeFile32, unlink22, mkdir22, copyFile2, DEFAULT_FIX_CONFIG, EXPORT_TYPE_KEYWORD, ALWAYS_UNSAFE_TYPES, idCounter, DEAD_CODE_FIX_ACTIONS, MustExportRuleSchema, MustExportDefaultRuleSchema, NoExportRuleSchema, MustImportRuleSchema, NoImportRuleSchema, NamingRuleSchema, MaxExportsRuleSchema, MaxLinesRuleSchema, RequireJSDocRuleSchema, RuleSchema, ConfigPatternSchema, PatternConfigSchema, DriftConfigSchema, DeadCodeConfigSchema, EntropyConfigSchema, BaselineManager, BenchmarkRunner, RegressionDetector, SOURCE_EXTENSIONS, FUNCTION_DECL_RE, CONST_DECL_RE, CriticalPathResolver, NoOpTelemetryAdapter, NoOpExecutor, ConsoleSink, feedbackConfig, ChecklistBuilder, AgentActionEmitter, globalEmitter, FileSink, NoOpSink, ConfidenceTierSchema, RegressionResultSchema, DirectionSchema, CategoryForecastSchema, SpecImpactSignalsSchema, SpecImpactEstimateSchema, ContributingFeatureSchema, AdjustedForecastSchema, PredictionWarningSchema, StabilityForecastSchema, PredictionResultSchema, PredictionOptionsSchema, VALID_STATUSES, EM_DASH, VALID_PRIORITIES, ALL_CATEGORIES, DIRECTION_THRESHOLD, PredictionEngine, DEFAULT_COEFFICIENTS, SpecImpactEstimator, EMPTY_HISTORY, ViolationHistoryManager, NORMALIZERS, MAX_SAMPLES, DEFAULT_WINDOW_WEEKS, DEFAULT_MIN_OCCURRENCES, FailureEntrySchema, HandoffSchema, GateCheckSchema, GateResultSchema, GateConfigSchema, HarnessStateSchema, DEFAULT_STATE, StreamInfoSchema, StreamIndexSchema, DEFAULT_STREAM_INDEX, HARNESS_DIR, STATE_FILE, LEARNINGS_FILE, FAILURES_FILE, HANDOFF_FILE, GATE_CONFIG_FILE, INDEX_FILE, SESSIONS_DIR, SESSION_INDEX_FILE, SUMMARY_FILE, SESSION_STATE_FILE, ARCHIVE_DIR, CONTENT_HASHES_FILE, EVENTS_FILE, STREAMS_DIR, STREAM_NAME_REGEX, branchCache, BRANCH_CACHE_TTL_MS, STATE_FILES, MAX_CACHE_ENTRIES, learningsCacheMap, WEIGHTS, LOCK_RETRIES, LOCK_BACKOFFS, PROMOTABLE_OUTCOMES, failuresCacheMap, FAILURE_LINE_REGEX, SAFE_GATE_COMMAND, SkillEventSchema, knownHashesCache, EVENT_FORMATTERS, RuleRegistry, DEFAULT_SECURITY_CONFIG, RuleOverrideSchema, SecurityConfigSchema, secretRules, injectionRules, xssRules, cryptoRules, pathTraversalRules, networkRules, deserializationRules, agentConfigRules, mcpRules, insecureDefaultsRules, sharpEdgesRules, nodeRules, expressRules, reactRules, goRules, SecurityScanner, OSV_ENDPOINT, DEFAULT_CACHE_DIR, DEFAULT_TTL_HOURS, hiddenUnicodePatterns, reRolingPatterns, permissionEscalationPatterns, encodedPayloadPatterns, indirectInjectionPatterns, contextManipulationPatterns, socialEngineeringPatterns, suspiciousPatterns, ALL_PATTERNS, DESTRUCTIVE_BASH, TAINT_DURATION_MS, DEFAULT_SESSION_ID, SecurityCategorySnapshotSchema, SupplyChainSnapshotSchema, SecurityTimelineSnapshotSchema, FindingLifecycleSchema, SecurityTimelineFileSchema, DirectionSchema2, SecurityTrendLineSchema, TrendAttributionSchema, SecurityTrendResultSchema, TimeToFixStatsSchema, TimeToFixResultSchema, EMPTY_SUPPLY_CHAIN, SecurityTimelineManager, ALL_CHECKS, STATUS_ICONS, CINotifier, ExclusionSet, PREFIX_PATTERNS, TEST_FILE_PATTERN, MD_FILE_PATTERN, ALL_DOMAINS, SECURITY_PATTERNS, JS_EXT_FALLBACKS, SEVERITY_RANK, SEVERITY_ORDER, SEVERITY_LABELS, VALIDATED_BY_RANK, VALIDATION_SCORES, DOMAIN_BASELINES, FACTOR_WEIGHTS, EVIDENCE_SATURATION, CORROBORATED_AGREEMENT, STANDALONE_AGREEMENT, AGREEMENT_LINE_GAP, COMPLIANCE_DESCRIPTOR, EXPORT_RE, BUG_DETECTION_DESCRIPTOR, SECURITY_DESCRIPTOR, EVAL_PATTERN, SECRET_PATTERNS, SQL_CONCAT_PATTERN, SHELL_EXEC_PATTERN, ARCHITECTURE_DESCRIPTOR, LARGE_FILE_THRESHOLD, VIOLATION_FILE_RE, LEARNINGS_DESCRIPTOR, RELEVANCE_THRESHOLD, AGENT_DESCRIPTORS, AGENT_RUNNERS, DOWNGRADE_MAP, DEFAULT_PROVIDER_TIERS, SMALL_SUGGESTION_LINE_LIMIT, FILE_LINE_RANGE_PATTERN, FILE_LINE_PATTERN, FILE_ONLY_PATTERN, SECURITY_SENSITIVE_PATH, MIGRATION_PATH, TEST_PATH, CONFIG_PATH, STAGE_DOMAINS, EM_DASH2, STATUS_RANK, RETRY_DEFAULTS, GitHubIssuesSyncAdapter, syncMutex, PRIORITY_RANK, PRIORITY_RANK2, POSITION_WEIGHT, DEPENDENTS_WEIGHT, AFFINITY_WEIGHT, ConflictError, DEFAULTS, GitHubHttp, ETagStore, START_MARKER, END_MARKER, SERIALIZER_FIELDS, GitHubIssuesTrackerAdapter, migrate_exports, HASH_RE, InteractionTypeSchema, QuestionSchema, ConfirmationSchema, TransitionSchema, EmitInteractionInputSchema, ProjectScanner, SHELL_TEMPLATE, STYLES, SCRIPTS, MockLLMService, llmService, ContentPipeline, BlueprintGenerator, TOKENS_PER_MILLION, fallback_default, LITELLM_PRICING_URL, CACHE_TTL_MS, STALENESS_WARNING_DAYS, MICRODOLLARS_PER_DOLLAR, TOKENS_PER_MILLION2, StructuralStrategy, DEFAULT_TOKEN_BUDGET, CHARS_PER_TOKEN, TRUNCATION_MARKER, TruncationStrategy, CompactionPipeline, STABILITY_LOOKUP, TIER_ORDER, AnthropicCacheAdapter, TIER_ORDER2, OpenAICacheAdapter, TIER_ORDER3, CACHED_CONTENT_MARKER, GeminiCacheAdapter, VERSION, POSTHOG_BATCH_URL, MAX_ATTEMPTS, TIMEOUT_MS, DEFAULT_CAPACITY, CacheMetricsRecorder, RETRY_BACKOFFS_MS, OTLPExporter, SpanKind, CompoundLockHeldError, KNOWN_CATEGORIES, ALLOWED_FIELD_KEYS, PII_TOKENS, PII_FIELD_DENYLIST, PII_LINE_RE, ALLOWED_SET, PulseAdapterAlreadyRegisteredError, REGISTRY, MOCK_ADAPTER_NAME, ALLOWED_FIELD_SET, adapter, LOOKBACK_RE, MAX_LINES, INLINE_TEMPLATE, TRUNCATION_MARKER2, execFileAsync, FIX_RE, EMPTY_REPO_RE, execFileAsync2, TRACK_CATEGORIES2, STOPWORDS, KEYWORD_TO_CATEGORY, ProposalNotFoundError, ProposalConflictError;
|
|
12914
13141
|
var init_dist3 = __esm({
|
|
12915
13142
|
"../core/dist/index.mjs"() {
|
|
12916
13143
|
init_chunk_FYTJQ2ZY();
|
|
@@ -12936,6 +13163,7 @@ var init_dist3 = __esm({
|
|
|
12936
13163
|
init_dist();
|
|
12937
13164
|
init_dist();
|
|
12938
13165
|
init_dist2();
|
|
13166
|
+
init_dist();
|
|
12939
13167
|
WHATWG_BAD_PORTS = Object.freeze([
|
|
12940
13168
|
1,
|
|
12941
13169
|
7,
|
|
@@ -15893,6 +16121,9 @@ var init_dist3 = __esm({
|
|
|
15893
16121
|
};
|
|
15894
16122
|
}
|
|
15895
16123
|
};
|
|
16124
|
+
OSV_ENDPOINT = "https://api.osv.dev/v1/query";
|
|
16125
|
+
DEFAULT_CACHE_DIR = path26.join(".harness", "cache", "osv");
|
|
16126
|
+
DEFAULT_TTL_HOURS = 24;
|
|
15896
16127
|
hiddenUnicodePatterns = [
|
|
15897
16128
|
{
|
|
15898
16129
|
ruleId: "INJ-UNI-001",
|
|
@@ -16198,7 +16429,7 @@ var init_dist3 = __esm({
|
|
|
16198
16429
|
timelinePath;
|
|
16199
16430
|
constructor(rootDir) {
|
|
16200
16431
|
this.rootDir = rootDir;
|
|
16201
|
-
this.timelinePath =
|
|
16432
|
+
this.timelinePath = join39(rootDir, ".harness", "security", "timeline.json");
|
|
16202
16433
|
}
|
|
16203
16434
|
/**
|
|
16204
16435
|
* Load timeline from disk.
|
|
@@ -16242,7 +16473,7 @@ var init_dist3 = __esm({
|
|
|
16242
16473
|
* Save timeline to disk using atomic write (temp file + rename).
|
|
16243
16474
|
*/
|
|
16244
16475
|
save(timeline) {
|
|
16245
|
-
const dir =
|
|
16476
|
+
const dir = dirname11(this.timelinePath);
|
|
16246
16477
|
if (!existsSync342(dir)) {
|
|
16247
16478
|
mkdirSync14(dir, { recursive: true });
|
|
16248
16479
|
}
|
|
@@ -17879,10 +18110,10 @@ ${JSON.stringify(event)}`;
|
|
|
17879
18110
|
}
|
|
17880
18111
|
rootDir;
|
|
17881
18112
|
async scan() {
|
|
17882
|
-
let projectName =
|
|
18113
|
+
let projectName = path36.basename(this.rootDir);
|
|
17883
18114
|
try {
|
|
17884
|
-
const pkgPath =
|
|
17885
|
-
const pkgRaw = await
|
|
18115
|
+
const pkgPath = path36.join(this.rootDir, "package.json");
|
|
18116
|
+
const pkgRaw = await fs36.readFile(pkgPath, "utf-8");
|
|
17886
18117
|
const pkg = JSON.parse(pkgRaw);
|
|
17887
18118
|
if (pkg.name) projectName = pkg.name;
|
|
17888
18119
|
} catch {
|
|
@@ -17995,8 +18226,8 @@ console.log('Blueprint player initialized.');
|
|
|
17995
18226
|
styles: STYLES,
|
|
17996
18227
|
scripts: SCRIPTS
|
|
17997
18228
|
});
|
|
17998
|
-
await
|
|
17999
|
-
await
|
|
18229
|
+
await fs37.mkdir(options.outputDir, { recursive: true });
|
|
18230
|
+
await fs37.writeFile(path37.join(options.outputDir, "index.html"), html);
|
|
18000
18231
|
}
|
|
18001
18232
|
};
|
|
18002
18233
|
TOKENS_PER_MILLION = 1e6;
|
|
@@ -18547,6 +18778,18 @@ console.log('Blueprint player initialized.');
|
|
|
18547
18778
|
[/\b(runtime|crash|exception|panic)\b/i, "bug-track/runtime-errors"],
|
|
18548
18779
|
[/\(orchestrator\)|\bintegrat|\blease\b|\brace\b|\bconcurren/i, "bug-track/integration-issues"]
|
|
18549
18780
|
];
|
|
18781
|
+
ProposalNotFoundError = class extends Error {
|
|
18782
|
+
constructor(id) {
|
|
18783
|
+
super(`proposal not found: ${id}`);
|
|
18784
|
+
this.name = "ProposalNotFoundError";
|
|
18785
|
+
}
|
|
18786
|
+
};
|
|
18787
|
+
ProposalConflictError = class extends Error {
|
|
18788
|
+
constructor(message) {
|
|
18789
|
+
super(message);
|
|
18790
|
+
this.name = "ProposalConflictError";
|
|
18791
|
+
}
|
|
18792
|
+
};
|
|
18550
18793
|
}
|
|
18551
18794
|
});
|
|
18552
18795
|
|
|
@@ -18782,6 +19025,7 @@ export {
|
|
|
18782
19025
|
goRules,
|
|
18783
19026
|
parseHarnessIgnore,
|
|
18784
19027
|
SecurityScanner,
|
|
19028
|
+
createOsvClient,
|
|
18785
19029
|
scanForInjection,
|
|
18786
19030
|
getInjectionPatterns,
|
|
18787
19031
|
DESTRUCTIVE_BASH,
|
|
@@ -18959,6 +19203,14 @@ export {
|
|
|
18959
19203
|
crossReferenceUndocumentedFixes,
|
|
18960
19204
|
suggestCategory,
|
|
18961
19205
|
assembleCandidateReport,
|
|
19206
|
+
proposalsDir,
|
|
19207
|
+
ProposalNotFoundError,
|
|
19208
|
+
ProposalConflictError,
|
|
19209
|
+
createProposal,
|
|
19210
|
+
getProposal,
|
|
19211
|
+
listProposals,
|
|
19212
|
+
updateProposal,
|
|
19213
|
+
deriveSkillUsage,
|
|
18962
19214
|
dist_exports,
|
|
18963
19215
|
init_dist3 as init_dist
|
|
18964
19216
|
};
|