@wrongstack/core 0.310.1 → 0.313.1
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/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34323
- package/dist/coordination/mailbox-project-server.js +48 -3220
- package/dist/coordination/mailbox-types.d.ts +13 -1
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/coordination/sqlite-mailbox.d.ts +2 -1
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12479
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21887
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92655
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
- package/dist/kernel/events.d.ts +16 -7
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9589
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/tools.d.ts +2 -2
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1341
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +92 -4
- package/dist/wiring/proxy-rewrite.js +20 -61
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// src/utils/wstack-paths.ts
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as os from "node:os";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
function canonicalProjectRoot(absRoot) {
|
|
7
|
+
const checkoutRoot = path.resolve(absRoot);
|
|
8
|
+
const dotGit = path.join(checkoutRoot, ".git");
|
|
9
|
+
try {
|
|
10
|
+
if (!fs.statSync(dotGit).isFile()) return checkoutRoot;
|
|
11
|
+
const gitDirLine = fs.readFileSync(dotGit, "utf8").trim();
|
|
12
|
+
const match = /^gitdir:\s*(.+)$/i.exec(gitDirLine);
|
|
13
|
+
if (!match?.[1]) return checkoutRoot;
|
|
14
|
+
const gitDir = path.resolve(checkoutRoot, match[1].trim());
|
|
15
|
+
const commonDirFile = path.join(gitDir, "commondir");
|
|
16
|
+
if (!fs.statSync(commonDirFile).isFile()) return checkoutRoot;
|
|
17
|
+
const commonDir = path.resolve(gitDir, fs.readFileSync(commonDirFile, "utf8").trim());
|
|
18
|
+
const worktreesDir = path.dirname(gitDir);
|
|
19
|
+
if (path.basename(worktreesDir).toLowerCase() !== "worktrees") return checkoutRoot;
|
|
20
|
+
if (path.resolve(worktreesDir, "..") !== commonDir) return checkoutRoot;
|
|
21
|
+
if (path.basename(commonDir).toLowerCase() !== ".git") return checkoutRoot;
|
|
22
|
+
return path.dirname(commonDir);
|
|
23
|
+
} catch {
|
|
24
|
+
return checkoutRoot;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function projectHash(absRoot) {
|
|
28
|
+
return createHash("sha256").update(canonicalProjectRoot(absRoot)).digest("hex").slice(0, 12);
|
|
29
|
+
}
|
|
30
|
+
function projectSlug(absRoot) {
|
|
31
|
+
const identityRoot = canonicalProjectRoot(absRoot);
|
|
32
|
+
const base = slugify(path.basename(identityRoot));
|
|
33
|
+
const hash = createHash("sha256").update(identityRoot).digest("hex").slice(0, 6);
|
|
34
|
+
return `${base}-${hash}`;
|
|
35
|
+
}
|
|
36
|
+
function slugify(name) {
|
|
37
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
|
|
38
|
+
}
|
|
39
|
+
function safeProfileName(name) {
|
|
40
|
+
const safe = (name ?? "").replace(/[/\\:]/g, "_").replace(/\.\./g, "_").trim();
|
|
41
|
+
return safe || "default";
|
|
42
|
+
}
|
|
43
|
+
function bootstrapProfileName(globalRoot) {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(globalRoot, "config.json"), "utf8"));
|
|
46
|
+
return safeProfileName(
|
|
47
|
+
typeof parsed.activeProfile === "string" ? parsed.activeProfile : void 0
|
|
48
|
+
);
|
|
49
|
+
} catch {
|
|
50
|
+
return "default";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function wstackGlobalRoot() {
|
|
54
|
+
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
55
|
+
if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);
|
|
56
|
+
return path.join(os.homedir(), ".wrongstack");
|
|
57
|
+
}
|
|
58
|
+
function resolveWstackPaths(opts) {
|
|
59
|
+
const globalRoot = opts.globalRoot ?? (opts.userHome ? path.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
60
|
+
const homeDir = opts.userHome ?? os.homedir();
|
|
61
|
+
const profileName = safeProfileName(opts.profileName ?? bootstrapProfileName(globalRoot));
|
|
62
|
+
const profileDir = path.join(globalRoot, "profiles", profileName);
|
|
63
|
+
const hash = projectHash(opts.projectRoot);
|
|
64
|
+
const slug = projectSlug(opts.projectRoot);
|
|
65
|
+
const projectDir = path.join(globalRoot, "projects", slug);
|
|
66
|
+
return {
|
|
67
|
+
globalRoot,
|
|
68
|
+
profileName,
|
|
69
|
+
profileDir,
|
|
70
|
+
projectRoot: opts.projectRoot,
|
|
71
|
+
homeDir,
|
|
72
|
+
configDir: profileDir,
|
|
73
|
+
globalConfig: path.join(globalRoot, "config.json"),
|
|
74
|
+
profilesDir: path.join(globalRoot, "profiles"),
|
|
75
|
+
profileConfig: (name) => {
|
|
76
|
+
return path.join(globalRoot, "profiles", safeProfileName(name), "config.json");
|
|
77
|
+
},
|
|
78
|
+
profileStatuslineConfig: (name) => {
|
|
79
|
+
return path.join(globalRoot, "profiles", safeProfileName(name), "statusline.json");
|
|
80
|
+
},
|
|
81
|
+
profileModeConfig: (name) => {
|
|
82
|
+
return path.join(globalRoot, "profiles", safeProfileName(name), "mode.json");
|
|
83
|
+
},
|
|
84
|
+
profileProviderStatus: (name) => {
|
|
85
|
+
return path.join(globalRoot, "profiles", safeProfileName(name), "provider-status.json");
|
|
86
|
+
},
|
|
87
|
+
profileUpdateCache: (name) => {
|
|
88
|
+
return path.join(globalRoot, "profiles", safeProfileName(name), "update-cache.json");
|
|
89
|
+
},
|
|
90
|
+
secretsKey: path.join(globalRoot, ".key"),
|
|
91
|
+
globalMemory: path.join(profileDir, "memory.md"),
|
|
92
|
+
globalSkills: path.join(profileDir, "skills"),
|
|
93
|
+
globalClaudeSkills: path.join(homeDir, ".claude", "skills"),
|
|
94
|
+
globalDesignKits: path.join(profileDir, "design-kits"),
|
|
95
|
+
globalPrompts: path.join(profileDir, "prompts"),
|
|
96
|
+
globalInstructions: path.join(profileDir, "instructions"),
|
|
97
|
+
promptUsage: path.join(profileDir, "prompt-usage.json"),
|
|
98
|
+
cacheDir: path.join(globalRoot, "cache"),
|
|
99
|
+
modelsCache: path.join(globalRoot, "cache", "models.dev.json"),
|
|
100
|
+
modelsOverlayCache: path.join(globalRoot, "cache", "models-overlay.json"),
|
|
101
|
+
historyFile: path.join(profileDir, "history"),
|
|
102
|
+
logFile: path.join(globalRoot, "logs", "wrongstack.log"),
|
|
103
|
+
projectDir,
|
|
104
|
+
projectCodebaseIndex: path.join(projectDir, "codebase-index"),
|
|
105
|
+
projectMemory: path.join(projectDir, "memory.md"),
|
|
106
|
+
projectSessions: path.join(projectDir, "sessions"),
|
|
107
|
+
projectTrust: path.join(projectDir, "trust.json"),
|
|
108
|
+
projectMeta: path.join(projectDir, "meta.json"),
|
|
109
|
+
projectLocalConfig: path.join(projectDir, "config.local.json"),
|
|
110
|
+
inProjectConfig: path.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
111
|
+
inProjectAgentsFile: path.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
112
|
+
inProjectSkills: path.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
113
|
+
inProjectClaudeSkills: path.join(opts.projectRoot, ".claude", "skills"),
|
|
114
|
+
inProjectPrompts: path.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
115
|
+
inProjectInstructions: path.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
116
|
+
inProjectDesignKits: path.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
117
|
+
inProjectWorktrees: path.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
118
|
+
projectHash: hash,
|
|
119
|
+
projectSlug: slug,
|
|
120
|
+
projectGoal: path.join(projectDir, "goal.json"),
|
|
121
|
+
projectInputHistory: path.join(projectDir, "input-history.json"),
|
|
122
|
+
projectSpecs: path.join(projectDir, "specs"),
|
|
123
|
+
projectTaskGraphs: path.join(projectDir, "task-graphs"),
|
|
124
|
+
projectSddSession: path.join(projectDir, "sdd-session.json"),
|
|
125
|
+
projectPlan: path.join(projectDir, "plan.json"),
|
|
126
|
+
projectAutophase: path.join(projectDir, "autophase"),
|
|
127
|
+
projectSddBoards: path.join(projectDir, "sdd-boards"),
|
|
128
|
+
projectRequirementIntakes: path.join(projectDir, "requirement-intakes"),
|
|
129
|
+
syncConfig: path.join(profileDir, "sync.json"),
|
|
130
|
+
configHistoryDir: path.join(globalRoot, "config-history"),
|
|
131
|
+
projectStatus: (statusProjectSlug) => {
|
|
132
|
+
if (!/^[a-z0-9](?:[a-z0-9-]{0,39})-[a-f0-9]{6}$/.test(statusProjectSlug)) {
|
|
133
|
+
throw new Error(`Invalid project slug: ${statusProjectSlug}`);
|
|
134
|
+
}
|
|
135
|
+
return path.join(globalRoot, "projects", statusProjectSlug, "status.json");
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export {
|
|
141
|
+
canonicalProjectRoot,
|
|
142
|
+
projectHash,
|
|
143
|
+
projectSlug,
|
|
144
|
+
safeProfileName,
|
|
145
|
+
bootstrapProfileName,
|
|
146
|
+
wstackGlobalRoot,
|
|
147
|
+
resolveWstackPaths
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=chunk-YNCVSFGF.js.map
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DefaultSecretScrubber
|
|
3
|
+
} from "./chunk-3E244UDA.js";
|
|
4
|
+
|
|
5
|
+
// src/prompts/prompt-journal.ts
|
|
6
|
+
import * as fs from "node:fs/promises";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
var defaultScrubber = new DefaultSecretScrubber();
|
|
9
|
+
var PROMPT_JOURNAL_RAW_MARKER = "promptJournal.raw";
|
|
10
|
+
async function ensureGitignore(projectRoot) {
|
|
11
|
+
const gitignorePath = path.join(projectRoot, ".gitignore");
|
|
12
|
+
try {
|
|
13
|
+
let content = "";
|
|
14
|
+
try {
|
|
15
|
+
content = await fs.readFile(gitignorePath, "utf8");
|
|
16
|
+
} catch {
|
|
17
|
+
content = "";
|
|
18
|
+
}
|
|
19
|
+
if (!content.includes(".wrongstack") && !content.includes(".wrongstack/")) {
|
|
20
|
+
const addition = content.endsWith("\n") || content.length === 0 ? ".wrongstack/\n" : "\n.wrongstack/\n";
|
|
21
|
+
await fs.writeFile(gitignorePath, content + addition, "utf8");
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function sessionFileId(sessionId) {
|
|
27
|
+
const leaf = sessionId.split(/[\\/]/u).pop();
|
|
28
|
+
return leaf && leaf.trim().length > 0 ? leaf : "general";
|
|
29
|
+
}
|
|
30
|
+
async function recordPromptJournalEntry(opts) {
|
|
31
|
+
const now = /* @__PURE__ */ new Date();
|
|
32
|
+
const timestamp = now.toISOString();
|
|
33
|
+
const dateStr = timestamp.slice(0, 10);
|
|
34
|
+
const monthStr = dateStr.slice(0, 7);
|
|
35
|
+
const sessionId = opts.sessionId && opts.sessionId.trim() ? opts.sessionId.trim() : "general";
|
|
36
|
+
const id = `pmt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
37
|
+
const content = defaultScrubber.scrub(opts.content ?? "");
|
|
38
|
+
const rawContent = typeof opts.rawContent === "string" && opts.rawContent.length > 0 ? defaultScrubber.scrub(opts.rawContent) : opts.rawContent;
|
|
39
|
+
const decisionReason = typeof opts.decisionReason === "string" && opts.decisionReason.length > 0 ? defaultScrubber.scrub(opts.decisionReason) : opts.decisionReason;
|
|
40
|
+
const lines = content.split("\n");
|
|
41
|
+
const characterCount = content.length;
|
|
42
|
+
const lineCount = lines.length;
|
|
43
|
+
const tokenEstimate = Math.ceil(characterCount / 4);
|
|
44
|
+
const entry = {
|
|
45
|
+
id,
|
|
46
|
+
timestamp,
|
|
47
|
+
sessionId,
|
|
48
|
+
projectRoot: opts.projectRoot,
|
|
49
|
+
role: opts.role ?? (opts.category === "system_prompt" ? "system" : "user"),
|
|
50
|
+
category: opts.category,
|
|
51
|
+
content,
|
|
52
|
+
rawContent,
|
|
53
|
+
metadata: {
|
|
54
|
+
model: opts.model,
|
|
55
|
+
provider: opts.provider,
|
|
56
|
+
iterationIndex: opts.iterationIndex,
|
|
57
|
+
tokenEstimate,
|
|
58
|
+
characterCount,
|
|
59
|
+
lineCount,
|
|
60
|
+
activeTools: opts.activeTools,
|
|
61
|
+
contextFiles: opts.contextFiles,
|
|
62
|
+
durationMs: opts.durationMs,
|
|
63
|
+
decisionReason,
|
|
64
|
+
tags: opts.tags
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const basePromptsDir = path.join(opts.projectRoot, ".wrongstack", "prompts");
|
|
68
|
+
const dayDir = path.join(basePromptsDir, monthStr, dateStr);
|
|
69
|
+
try {
|
|
70
|
+
await fs.mkdir(dayDir, { recursive: true });
|
|
71
|
+
await ensureGitignore(opts.projectRoot);
|
|
72
|
+
const sessionJsonlFile = path.join(dayDir, `session-${sessionFileId(sessionId)}.jsonl`);
|
|
73
|
+
await fs.appendFile(sessionJsonlFile, JSON.stringify(entry) + "\n", "utf8");
|
|
74
|
+
const sessionMdFile = path.join(dayDir, `session-${sessionFileId(sessionId)}.md`);
|
|
75
|
+
const mdSection = formatEntryMarkdown(entry);
|
|
76
|
+
await fs.appendFile(sessionMdFile, mdSection, "utf8");
|
|
77
|
+
const dailySummaryFile = path.join(dayDir, "daily-summary.md");
|
|
78
|
+
await updateDailySummary(dailySummaryFile, dateStr, entry);
|
|
79
|
+
await updateRootCatalog(basePromptsDir, monthStr, dateStr, sessionId, entry);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
console.error?.(`Failed to write hierarchical prompt journal: ${err}`);
|
|
82
|
+
}
|
|
83
|
+
return entry;
|
|
84
|
+
}
|
|
85
|
+
function formatEntryMarkdown(entry) {
|
|
86
|
+
const tagList = [
|
|
87
|
+
`**Category:** \`${entry.category}\``,
|
|
88
|
+
`**Role:** \`${entry.role}\``,
|
|
89
|
+
entry.metadata.model ? `**Model:** \`${entry.metadata.model}\`` : null,
|
|
90
|
+
`**Tokens (est):** ~${entry.metadata.tokenEstimate}`,
|
|
91
|
+
entry.metadata.iterationIndex !== void 0 ? `**Iteration:** #${entry.metadata.iterationIndex}` : null,
|
|
92
|
+
`**Session:** \`${entry.sessionId}\``
|
|
93
|
+
].filter(Boolean).join(" | ");
|
|
94
|
+
let md = `
|
|
95
|
+
### \u{1F4DD} [${entry.timestamp}] \`${entry.id}\`
|
|
96
|
+
${tagList}
|
|
97
|
+
|
|
98
|
+
`;
|
|
99
|
+
if (entry.metadata.decisionReason) {
|
|
100
|
+
md += `> **Rationale:** ${entry.metadata.decisionReason}
|
|
101
|
+
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
if (entry.metadata.activeTools && entry.metadata.activeTools.length > 0) {
|
|
105
|
+
md += `*Active Tools:* \`${entry.metadata.activeTools.join("`, `")}\`
|
|
106
|
+
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
if (entry.rawContent && entry.rawContent !== entry.content) {
|
|
110
|
+
md += `**Raw Input:**
|
|
111
|
+
\`\`\`text
|
|
112
|
+
${entry.rawContent.trim()}
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
`;
|
|
116
|
+
md += `**Refined / Injected Prompt:**
|
|
117
|
+
\`\`\`text
|
|
118
|
+
${entry.content.trim()}
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
`;
|
|
122
|
+
} else {
|
|
123
|
+
md += `**Prompt Content:**
|
|
124
|
+
\`\`\`text
|
|
125
|
+
${entry.content.trim()}
|
|
126
|
+
\`\`\`
|
|
127
|
+
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
md += `---
|
|
131
|
+
`;
|
|
132
|
+
return md;
|
|
133
|
+
}
|
|
134
|
+
async function updateDailySummary(summaryFile, dateStr, entry) {
|
|
135
|
+
try {
|
|
136
|
+
let content = "";
|
|
137
|
+
try {
|
|
138
|
+
content = await fs.readFile(summaryFile, "utf8");
|
|
139
|
+
} catch {
|
|
140
|
+
content = `# \u{1F4C5} Daily Prompt Summary \u2014 ${dateStr}
|
|
141
|
+
|
|
142
|
+
| Time | ID | Session | Category | Model | Tokens | Rationale |
|
|
143
|
+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
const time = entry.timestamp.slice(11, 19);
|
|
147
|
+
const model = entry.metadata.model ?? "-";
|
|
148
|
+
const reason = entry.metadata.decisionReason ? entry.metadata.decisionReason.slice(0, 40) : "-";
|
|
149
|
+
const row = `| ${time} | [\`${entry.id}\`](session-${sessionFileId(entry.sessionId)}.md) | \`${entry.sessionId}\` | \`${entry.category}\` | ${model} | ~${entry.metadata.tokenEstimate} | ${reason} |
|
|
150
|
+
`;
|
|
151
|
+
await fs.writeFile(summaryFile, content + row, "utf8");
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function updateRootCatalog(baseDir, monthStr, dateStr, sessionId, entry) {
|
|
156
|
+
const indexJsonFile = path.join(baseDir, "index.json");
|
|
157
|
+
const indexMdFile = path.join(baseDir, "index.md");
|
|
158
|
+
let catalog;
|
|
159
|
+
try {
|
|
160
|
+
const raw = await fs.readFile(indexJsonFile, "utf8");
|
|
161
|
+
catalog = JSON.parse(raw);
|
|
162
|
+
} catch {
|
|
163
|
+
catalog = {
|
|
164
|
+
updatedAt: entry.timestamp,
|
|
165
|
+
totalPrompts: 0,
|
|
166
|
+
totalTokensEstimated: 0,
|
|
167
|
+
months: {}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catalog.updatedAt = entry.timestamp;
|
|
171
|
+
catalog.totalPrompts += 1;
|
|
172
|
+
catalog.totalTokensEstimated += entry.metadata.tokenEstimate;
|
|
173
|
+
if (!catalog.months[monthStr]) {
|
|
174
|
+
catalog.months[monthStr] = { days: {} };
|
|
175
|
+
}
|
|
176
|
+
const monthData = catalog.months[monthStr];
|
|
177
|
+
if (!monthData.days[dateStr]) {
|
|
178
|
+
monthData.days[dateStr] = { sessions: {} };
|
|
179
|
+
}
|
|
180
|
+
const dayData = monthData.days[dateStr];
|
|
181
|
+
if (!dayData.sessions[sessionId]) {
|
|
182
|
+
dayData.sessions[sessionId] = {
|
|
183
|
+
promptCount: 0,
|
|
184
|
+
tokenEstimate: 0,
|
|
185
|
+
lastTimestamp: entry.timestamp,
|
|
186
|
+
categories: {}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const sessionData = dayData.sessions[sessionId];
|
|
190
|
+
sessionData.promptCount += 1;
|
|
191
|
+
sessionData.tokenEstimate += entry.metadata.tokenEstimate;
|
|
192
|
+
sessionData.lastTimestamp = entry.timestamp;
|
|
193
|
+
sessionData.categories[entry.category] = (sessionData.categories[entry.category] ?? 0) + 1;
|
|
194
|
+
try {
|
|
195
|
+
await fs.writeFile(indexJsonFile, JSON.stringify(catalog, null, 2), "utf8");
|
|
196
|
+
let md = `# \u{1F5C2}\uFE0F Prompt Journal Navigation Index
|
|
197
|
+
|
|
198
|
+
`;
|
|
199
|
+
md += `* **Total Prompts Logged:** ${catalog.totalPrompts}
|
|
200
|
+
`;
|
|
201
|
+
md += `* **Total Tokens (est):** ~${catalog.totalTokensEstimated.toLocaleString()}
|
|
202
|
+
`;
|
|
203
|
+
md += `* **Last Recorded Activity:** ${catalog.updatedAt}
|
|
204
|
+
|
|
205
|
+
`;
|
|
206
|
+
md += `## \u{1F4C5} Recorded Dates & Sessions
|
|
207
|
+
|
|
208
|
+
`;
|
|
209
|
+
md += `| Date | Session | Prompts | Tokens (est) | Daily Log | Session Log |
|
|
210
|
+
`;
|
|
211
|
+
md += `| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
212
|
+
`;
|
|
213
|
+
for (const [m, mObj] of Object.entries(catalog.months).sort().reverse()) {
|
|
214
|
+
for (const [d, dObj] of Object.entries(mObj.days).sort().reverse()) {
|
|
215
|
+
for (const [sId, sData] of Object.entries(dObj.sessions)) {
|
|
216
|
+
const dailyLink = `[daily-summary.md](./${m}/${d}/daily-summary.md)`;
|
|
217
|
+
const sessionLink = `[session-${sessionFileId(sId)}.md](./${m}/${d}/session-${sessionFileId(sId)}.md)`;
|
|
218
|
+
md += `| **${d}** | \`${sId}\` | ${sData.promptCount} | ~${sData.tokenEstimate.toLocaleString()} | ${dailyLink} | ${sessionLink} |
|
|
219
|
+
`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
await fs.writeFile(indexMdFile, md, "utf8");
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async function getPromptJournalEntries(projectRoot, filter = {}) {
|
|
228
|
+
const basePromptsDir = path.join(projectRoot, ".wrongstack", "prompts");
|
|
229
|
+
const results = [];
|
|
230
|
+
try {
|
|
231
|
+
const months = await fs.readdir(basePromptsDir);
|
|
232
|
+
for (const month of months) {
|
|
233
|
+
if (!/^\d{4}-\d{2}$/.test(month)) continue;
|
|
234
|
+
if (filter.month && filter.month !== month) continue;
|
|
235
|
+
const monthDir = path.join(basePromptsDir, month);
|
|
236
|
+
const days = await fs.readdir(monthDir);
|
|
237
|
+
for (const day of days) {
|
|
238
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) continue;
|
|
239
|
+
if (filter.date && filter.date !== day) continue;
|
|
240
|
+
const dayDir = path.join(monthDir, day);
|
|
241
|
+
const files = await fs.readdir(dayDir);
|
|
242
|
+
const jsonlFiles = files.filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
243
|
+
for (const jsonlFile of jsonlFiles) {
|
|
244
|
+
const sessionMatch = jsonlFile.match(/^session-(.+)\.jsonl$/);
|
|
245
|
+
const sId = sessionMatch ? sessionMatch[1] : void 0;
|
|
246
|
+
if (filter.sessionId && sId !== sessionFileId(filter.sessionId)) continue;
|
|
247
|
+
const filePath = path.join(dayDir, jsonlFile);
|
|
248
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
249
|
+
const lines = content.split("\n");
|
|
250
|
+
for (const line of lines) {
|
|
251
|
+
if (!line.trim()) continue;
|
|
252
|
+
try {
|
|
253
|
+
const entry = JSON.parse(line);
|
|
254
|
+
if (filter.sessionId && sessionFileId(entry.sessionId) !== sessionFileId(filter.sessionId)) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (filter.category && entry.category !== filter.category) continue;
|
|
258
|
+
if (filter.since && entry.timestamp < filter.since) continue;
|
|
259
|
+
results.push(entry);
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} catch {
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
results.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
270
|
+
if (filter.limit && results.length > filter.limit) {
|
|
271
|
+
return results.slice(-filter.limit);
|
|
272
|
+
}
|
|
273
|
+
return results;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export {
|
|
277
|
+
PROMPT_JOURNAL_RAW_MARKER,
|
|
278
|
+
ensureGitignore,
|
|
279
|
+
recordPromptJournalEntry,
|
|
280
|
+
getPromptJournalEntries
|
|
281
|
+
};
|
|
282
|
+
//# sourceMappingURL=chunk-YUPMXOGP.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/security/config-secrets.ts
|
|
2
|
+
function decryptConfigSecrets(cfg, vault, opts) {
|
|
3
|
+
const warn = opts?.warn ?? ((msg) => console.warn(msg));
|
|
4
|
+
return walk(cfg, vault, (v, key) => {
|
|
5
|
+
try {
|
|
6
|
+
return vault.decrypt(v);
|
|
7
|
+
} catch (err) {
|
|
8
|
+
warn(
|
|
9
|
+
`[secret-vault] Failed to decrypt "${key}": ${err instanceof Error ? err.message : err}`
|
|
10
|
+
);
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function encryptConfigSecrets(cfg, vault, _opts) {
|
|
16
|
+
return walk(cfg, vault, (v) => vault.encrypt(v));
|
|
17
|
+
}
|
|
18
|
+
function walk(node, vault, transform) {
|
|
19
|
+
if (node === null || node === void 0) return node;
|
|
20
|
+
if (typeof node !== "object") return node;
|
|
21
|
+
if (Array.isArray(node)) {
|
|
22
|
+
return node.map((item) => walk(item, vault, transform));
|
|
23
|
+
}
|
|
24
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
25
|
+
for (const [k, v] of Object.entries(node)) {
|
|
26
|
+
if (typeof v === "string" && isSecretField(k)) {
|
|
27
|
+
out[k] = transform(v, k);
|
|
28
|
+
} else if (typeof v === "object" && v !== null) {
|
|
29
|
+
out[k] = walk(v, vault, transform);
|
|
30
|
+
} else {
|
|
31
|
+
out[k] = v;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
var SECRET_KEY_PATTERN = /(?:api[-_]?key|auth[-_]?token|authorization|proxy-authorization|cookie|bearer|secret|password|passwd|pwd|refresh[-_]?token|session[-_]?key|access[_-]?token|private[_-]?key|token\b)/i;
|
|
37
|
+
var NON_SECRET_OVERRIDES = /* @__PURE__ */ new Set(["publickey", "public_key"]);
|
|
38
|
+
function isSecretField(name) {
|
|
39
|
+
const lc = name.toLowerCase();
|
|
40
|
+
if (NON_SECRET_OVERRIDES.has(lc)) return false;
|
|
41
|
+
return SECRET_KEY_PATTERN.test(lc);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
decryptConfigSecrets,
|
|
46
|
+
encryptConfigSecrets,
|
|
47
|
+
isSecretField
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=chunk-YY6APYUM.js.map
|