@wrongstack/core 0.306.4 → 0.307.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 +957 -953
- package/dist/chronicle/metrics-ingest.d.ts +55 -0
- package/dist/chronicle/metrics-schema.d.ts +86 -0
- package/dist/chronicle/metrics-store.d.ts +5 -120
- package/dist/chronicle/project-server.js +1083 -1084
- package/dist/chronicle/sqlite-journal-quota.d.ts +39 -0
- package/dist/chronicle/sqlite-journal-schema.d.ts +25 -0
- package/dist/chronicle/sqlite-journal.d.ts +12 -177
- package/dist/coordination/agents/index.js +1803 -1701
- package/dist/coordination/agents/project-agent-capture.d.ts +48 -0
- package/dist/coordination/agents/project-agent-identity.d.ts +3 -129
- package/dist/coordination/agents/project-agent-roster.d.ts +17 -0
- package/dist/coordination/agents/types.d.ts +6 -9
- package/dist/coordination/index.js +6051 -5880
- package/dist/coordination/mail-tools.d.ts +1 -1
- package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
- package/dist/coordination/mailbox-http-router.d.ts +0 -48
- package/dist/coordination/mailbox-http-sse.d.ts +12 -0
- package/dist/coordination/mailbox-message-types.d.ts +71 -0
- package/dist/coordination/mailbox-predicates.d.ts +13 -0
- package/dist/coordination/mailbox-project-server.js +1 -1
- package/dist/coordination/mailbox-session-sync.d.ts +8 -0
- package/dist/coordination/mailbox-types.d.ts +6 -793
- package/dist/core/agent-loop-context.d.ts +28 -0
- package/dist/core/agent-loop-detector.d.ts +25 -0
- package/dist/core/fallback-doctor.d.ts +72 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1859 -1335
- package/dist/defaults/index.js +3647 -3559
- package/dist/execution/autonomy-brain-llm.d.ts +55 -0
- package/dist/execution/autonomy-brain.d.ts +3 -156
- package/dist/execution/compaction-budget.d.ts +38 -0
- package/dist/execution/compaction-core.d.ts +3 -170
- package/dist/execution/compaction-elision.d.ts +58 -0
- package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
- package/dist/execution/council-orchestrator.d.ts +3 -42
- package/dist/execution/council-response-parser.d.ts +56 -0
- package/dist/execution/index.js +2475 -2449
- package/dist/execution/prompt-enhancer.js +11 -3
- package/dist/execution/tool-executor-guard.d.ts +18 -0
- package/dist/execution/tool-executor-runner.d.ts +12 -0
- package/dist/execution/tool-executor.d.ts +0 -75
- package/dist/goal/index.js +19 -6
- package/dist/hq/index.js +8 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8021 -7405
- package/dist/infrastructure/index.js +3 -1
- package/dist/kernel/events/agent-events.d.ts +2 -0
- package/dist/kernel/events/provider-events.d.ts +13 -0
- package/dist/plugin/index.js +2590 -2561
- package/dist/plugins/auto-review-config.d.ts +53 -0
- package/dist/plugins/auto-review-git.d.ts +19 -0
- package/dist/plugins/auto-review-plugin.d.ts +2 -140
- package/dist/plugins/review-finding-verification.d.ts +7 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +601 -0
- package/dist/prompts/prompt-journal.d.ts +103 -0
- package/dist/security/index.js +627 -652
- package/dist/security/permission-explain.d.ts +19 -0
- package/dist/security/permission-policy.d.ts +0 -101
- package/dist/security/yolo-risk.d.ts +5 -4
- package/dist/session-catalog/index.js +220 -212
- package/dist/session-catalog/project-server.js +227 -219
- package/dist/session-catalog/store-rebuild.d.ts +9 -0
- package/dist/session-catalog/store-schema.d.ts +48 -0
- package/dist/session-catalog/store.d.ts +0 -17
- package/dist/storage/director-state.d.ts +6 -0
- package/dist/storage/file-session-writer.d.ts +2 -58
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +2057 -1925
- package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
- package/dist/storage/queue-store.d.ts +6 -0
- package/dist/storage/session-recovery.d.ts +9 -0
- package/dist/storage/session-store/rename-session.d.ts +16 -0
- package/dist/storage/session-store/resume-session.d.ts +26 -0
- package/dist/storage/session-store/session-store-clear.d.ts +11 -0
- package/dist/storage/session-store/session-store-index.d.ts +13 -0
- package/dist/storage/session-store.d.ts +1 -129
- package/dist/storage/session-summary-tracker.d.ts +39 -0
- package/dist/storage/session-write-buffer.d.ts +43 -0
- package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
- package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
- package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
- package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
- package/dist/tools/fallback-manage-tools.d.ts +8 -45
- package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
- package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
- package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
- package/dist/tools/index.js +5124 -5071
- package/dist/types/config/root.d.ts +7 -2
- package/dist/types/default-config.d.ts +1 -1
- package/dist/types/index.d.ts +54 -55
- package/dist/types/index.js +953 -932
- package/dist/types/runtime-capability-manifest.d.ts +5 -5
- package/dist/types/session-markers.d.ts +12 -0
- package/dist/types/session-markers.js +19 -0
- package/dist/worktree/worktree-manager.d.ts +1 -1
- package/instructions/agents/architect.md +2 -0
- package/instructions/agents/code-reviewer.md +1 -0
- package/instructions/agents/debugger.md +2 -0
- package/instructions/agents/executor.md +2 -0
- package/instructions/agents/explore.md +3 -1
- package/instructions/agents/refactor.md +2 -0
- package/instructions/agents/reviewer.md +1 -0
- package/instructions/coordination/subagent-baseline.md +68 -7
- package/instructions/llm/prompt-enhancer.md +2 -1
- package/instructions/sections/tool/common-patterns.md +30 -0
- package/instructions/sections/tool/delegation-compact.md +3 -1
- package/instructions/sections/tool/delegation-full.md +5 -1
- package/instructions/system-lite.md +32 -4
- package/instructions/system-pro.md +63 -9
- package/instructions/system.md +56 -11
- package/package.json +9 -5
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
// src/types/prompt-registry.ts
|
|
2
|
+
var SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3
|
+
var CHECKSUM_RE = /^[a-f0-9]{64}$/;
|
|
4
|
+
var MAX_STR = 4096;
|
|
5
|
+
function validateRegistryManifest(raw) {
|
|
6
|
+
const errors = [];
|
|
7
|
+
if (!raw || typeof raw !== "object") return { ok: false, errors: ["manifest is not an object"] };
|
|
8
|
+
const m = raw;
|
|
9
|
+
if (m["registryVersion"] !== 1) errors.push("registryVersion must be 1");
|
|
10
|
+
if (typeof m["source"] !== "string" || !m["source"])
|
|
11
|
+
errors.push("source must be a non-empty string");
|
|
12
|
+
if (typeof m["generatedAt"] !== "string") errors.push("generatedAt must be a string");
|
|
13
|
+
if (!Array.isArray(m["prompts"])) {
|
|
14
|
+
errors.push("prompts must be an array");
|
|
15
|
+
return { ok: false, errors };
|
|
16
|
+
}
|
|
17
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18
|
+
const refs = [];
|
|
19
|
+
m["prompts"].forEach((p, i) => {
|
|
20
|
+
if (!p || typeof p !== "object") {
|
|
21
|
+
errors.push(`prompts[${i}] is not an object`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const r = p;
|
|
25
|
+
const slug = r["slug"];
|
|
26
|
+
if (typeof slug !== "string" || !SLUG_RE.test(slug)) {
|
|
27
|
+
errors.push(`prompts[${i}].slug invalid (must be kebab-case)`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (seen.has(slug)) {
|
|
31
|
+
errors.push(`prompts[${i}].slug "${slug}" duplicated`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
seen.add(slug);
|
|
35
|
+
if (typeof r["checksum"] !== "string" || !CHECKSUM_RE.test(r["checksum"])) {
|
|
36
|
+
errors.push(`prompts[${i}].checksum must be a 64-char sha256 hex`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const field of ["id", "title", "description", "category"]) {
|
|
40
|
+
const v = r[field];
|
|
41
|
+
if (typeof v !== "string" || v.length === 0 || v.length > MAX_STR) {
|
|
42
|
+
errors.push(`prompts[${i}].${field} must be a non-empty string under ${MAX_STR} chars`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const tags = Array.isArray(r["tags"]) ? r["tags"].filter((t) => typeof t === "string") : [];
|
|
47
|
+
refs.push({
|
|
48
|
+
id: r["id"],
|
|
49
|
+
slug,
|
|
50
|
+
title: r["title"],
|
|
51
|
+
description: r["description"],
|
|
52
|
+
category: r["category"],
|
|
53
|
+
tags,
|
|
54
|
+
checksum: r["checksum"],
|
|
55
|
+
version: typeof r["version"] === "string" ? r["version"] : void 0,
|
|
56
|
+
license: typeof r["license"] === "string" ? r["license"] : void 0,
|
|
57
|
+
url: typeof r["url"] === "string" ? r["url"] : void 0
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
manifest: {
|
|
64
|
+
registryVersion: 1,
|
|
65
|
+
source: m["source"],
|
|
66
|
+
generatedAt: m["generatedAt"],
|
|
67
|
+
prompts: refs
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function diffRegistry(local, manifest) {
|
|
72
|
+
const localBySlug = new Map(local.map((e) => [e.slug, e.checksum]));
|
|
73
|
+
const diff = { added: [], updated: [], unchanged: [] };
|
|
74
|
+
for (const ref of manifest.prompts) {
|
|
75
|
+
if (!localBySlug.has(ref.slug)) diff.added.push(ref);
|
|
76
|
+
else if (localBySlug.get(ref.slug) !== ref.checksum) diff.updated.push(ref);
|
|
77
|
+
else diff.unchanged.push(ref);
|
|
78
|
+
}
|
|
79
|
+
return diff;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/types/errors.ts
|
|
83
|
+
var ERROR_CODES = {
|
|
84
|
+
// Provider
|
|
85
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
86
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
87
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
88
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
89
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
90
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
91
|
+
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
92
|
+
// Tool
|
|
93
|
+
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
94
|
+
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
95
|
+
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
96
|
+
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
97
|
+
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
98
|
+
// Config
|
|
99
|
+
CONFIG_INVALID: "CONFIG_INVALID",
|
|
100
|
+
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
101
|
+
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
102
|
+
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
103
|
+
// Plugin
|
|
104
|
+
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
105
|
+
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
106
|
+
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
107
|
+
// Agent
|
|
108
|
+
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
109
|
+
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
110
|
+
AGENT_ABORTED: "AGENT_ABORTED",
|
|
111
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
112
|
+
// Session
|
|
113
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
114
|
+
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
115
|
+
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
116
|
+
// Container / Registry
|
|
117
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
118
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
119
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
120
|
+
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
121
|
+
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
122
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
123
|
+
// File system
|
|
124
|
+
FS_READ_FAILED: "FS_READ_FAILED",
|
|
125
|
+
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
126
|
+
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
127
|
+
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
128
|
+
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
129
|
+
// SDD (Spec-Driven Development)
|
|
130
|
+
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
131
|
+
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
132
|
+
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
133
|
+
SDD_NOT_READY: "SDD_NOT_READY",
|
|
134
|
+
// General
|
|
135
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
136
|
+
PARSE_FAILED: "PARSE_FAILED",
|
|
137
|
+
UNKNOWN: "UNKNOWN"
|
|
138
|
+
};
|
|
139
|
+
var WrongStackError = class extends Error {
|
|
140
|
+
code;
|
|
141
|
+
subsystem;
|
|
142
|
+
severity;
|
|
143
|
+
recoverable;
|
|
144
|
+
context;
|
|
145
|
+
constructor(opts) {
|
|
146
|
+
super(opts.message, { cause: opts.cause });
|
|
147
|
+
this.name = "WrongStackError";
|
|
148
|
+
this.code = opts.code;
|
|
149
|
+
this.subsystem = opts.subsystem;
|
|
150
|
+
this.severity = opts.severity ?? "error";
|
|
151
|
+
this.recoverable = opts.recoverable ?? false;
|
|
152
|
+
this.context = opts.context;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Render a one-line user-facing description.
|
|
156
|
+
* Subclasses should override for domain-specific formatting.
|
|
157
|
+
*/
|
|
158
|
+
describe() {
|
|
159
|
+
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
160
|
+
return `${this.code}: ${this.message}${ctx}`;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
function formatContext(ctx) {
|
|
164
|
+
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
165
|
+
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
166
|
+
}
|
|
167
|
+
var FsError = class extends WrongStackError {
|
|
168
|
+
path;
|
|
169
|
+
constructor(opts) {
|
|
170
|
+
super({
|
|
171
|
+
message: opts.message,
|
|
172
|
+
code: opts.code,
|
|
173
|
+
subsystem: "fs",
|
|
174
|
+
severity: "error",
|
|
175
|
+
recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,
|
|
176
|
+
context: { path: opts.path, ...opts.context },
|
|
177
|
+
cause: opts.cause
|
|
178
|
+
});
|
|
179
|
+
this.name = "FsError";
|
|
180
|
+
this.path = opts.path;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var FetchError = class extends WrongStackError {
|
|
184
|
+
status;
|
|
185
|
+
constructor(opts) {
|
|
186
|
+
super({
|
|
187
|
+
message: opts.message,
|
|
188
|
+
code: ERROR_CODES.VALIDATION_ERROR,
|
|
189
|
+
subsystem: "general",
|
|
190
|
+
severity: "error",
|
|
191
|
+
recoverable: opts.status === 429 || opts.status >= 500,
|
|
192
|
+
context: { status: opts.status, ...opts.context },
|
|
193
|
+
cause: opts.cause
|
|
194
|
+
});
|
|
195
|
+
this.name = "FetchError";
|
|
196
|
+
this.status = opts.status;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
var ParseError = class extends WrongStackError {
|
|
200
|
+
source;
|
|
201
|
+
constructor(opts) {
|
|
202
|
+
super({
|
|
203
|
+
message: opts.message,
|
|
204
|
+
code: ERROR_CODES.PARSE_FAILED,
|
|
205
|
+
subsystem: "general",
|
|
206
|
+
severity: "error",
|
|
207
|
+
recoverable: false,
|
|
208
|
+
context: { source: opts.source, ...opts.context },
|
|
209
|
+
cause: opts.cause
|
|
210
|
+
});
|
|
211
|
+
this.name = "ParseError";
|
|
212
|
+
this.source = opts.source;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// src/prompts/prompt-installer.ts
|
|
217
|
+
var defaultFetcher = async (url) => {
|
|
218
|
+
const res = await fetch(url);
|
|
219
|
+
if (!res.ok) {
|
|
220
|
+
throw new FetchError({
|
|
221
|
+
message: `registry fetch failed: ${res.status} ${res.statusText}`,
|
|
222
|
+
status: res.status,
|
|
223
|
+
context: { op: "fetchManifest" }
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return res.json();
|
|
227
|
+
};
|
|
228
|
+
var PromptInstaller = class {
|
|
229
|
+
fetcher;
|
|
230
|
+
constructor(opts = {}) {
|
|
231
|
+
this.fetcher = opts.fetcher ?? defaultFetcher;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Fetch + validate a manifest and report what a sync WOULD change. Read-only.
|
|
235
|
+
* @param manifestUrl URL to the registry's `registry.json`.
|
|
236
|
+
* @param local The prompts the caller already has (slug + checksum).
|
|
237
|
+
*/
|
|
238
|
+
async pull(manifestUrl, local) {
|
|
239
|
+
const raw = await this.fetcher(manifestUrl);
|
|
240
|
+
const validated = validateRegistryManifest(raw);
|
|
241
|
+
if (!validated.ok) {
|
|
242
|
+
throw new ParseError({
|
|
243
|
+
message: `Invalid prompt registry manifest:
|
|
244
|
+
- ${validated.errors.join("\n - ")}`,
|
|
245
|
+
source: "prompt-registry-manifest"
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
const diff = diffRegistry(local, validated.manifest);
|
|
249
|
+
return { manifest: validated.manifest, diff, dryRun: true };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* EXTENSION POINT (not yet wired): download the prompt bodies for the given
|
|
253
|
+
* registry refs and write them into the user layer as `source:'synced'`,
|
|
254
|
+
* recording each in the installed-prompts manifest. Intentionally unimplemented
|
|
255
|
+
* — pulling real content over the network is gated behind a future change so
|
|
256
|
+
* the format/diff path can ship and be reviewed first.
|
|
257
|
+
*/
|
|
258
|
+
async install() {
|
|
259
|
+
throw new Error(
|
|
260
|
+
"Prompt sync is not implemented yet. `pull()` reports the diff; installing remote prompt bodies will land in a follow-up."
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// src/prompts/prompt-manifest-store.ts
|
|
266
|
+
import * as fs from "node:fs/promises";
|
|
267
|
+
import * as path from "node:path";
|
|
268
|
+
|
|
269
|
+
// src/utils/atomic-write.ts
|
|
270
|
+
import {
|
|
271
|
+
createPersistencePrimitives
|
|
272
|
+
} from "@wrongstack/persistence";
|
|
273
|
+
var primitives = createPersistencePrimitives({
|
|
274
|
+
createLockTimeoutError: ({ targetPath, timeoutMs }) => new FsError({
|
|
275
|
+
message: `Timed out waiting for file lock: ${targetPath}`,
|
|
276
|
+
code: "FS_ATOMIC_WRITE_FAILED",
|
|
277
|
+
path: targetPath,
|
|
278
|
+
context: { timeoutMs }
|
|
279
|
+
})
|
|
280
|
+
});
|
|
281
|
+
var atomicWrite = primitives.atomicWrite;
|
|
282
|
+
var atomicReplaceWithWriter = primitives.atomicReplaceWithWriter;
|
|
283
|
+
var ensureDir = primitives.ensureDir;
|
|
284
|
+
var withFileLock = primitives.withFileLock;
|
|
285
|
+
|
|
286
|
+
// src/prompts/prompt-manifest-store.ts
|
|
287
|
+
var PromptManifestStore = class {
|
|
288
|
+
constructor(manifestPath) {
|
|
289
|
+
this.manifestPath = manifestPath;
|
|
290
|
+
}
|
|
291
|
+
manifestPath;
|
|
292
|
+
async load() {
|
|
293
|
+
try {
|
|
294
|
+
const raw = JSON.parse(await fs.readFile(this.manifestPath, "utf8"));
|
|
295
|
+
if (raw && typeof raw === "object" && Array.isArray(raw.entries)) {
|
|
296
|
+
return { version: 1, entries: raw.entries };
|
|
297
|
+
}
|
|
298
|
+
} catch {
|
|
299
|
+
}
|
|
300
|
+
return { version: 1, entries: [] };
|
|
301
|
+
}
|
|
302
|
+
async save(data) {
|
|
303
|
+
await ensureDir(path.dirname(this.manifestPath));
|
|
304
|
+
await atomicWrite(this.manifestPath, JSON.stringify(data, null, 2));
|
|
305
|
+
}
|
|
306
|
+
/** Upsert one entry keyed by slug. */
|
|
307
|
+
async record(entry) {
|
|
308
|
+
const data = await this.load();
|
|
309
|
+
const idx = data.entries.findIndex((e) => e.slug === entry.slug);
|
|
310
|
+
if (idx === -1) data.entries.push(entry);
|
|
311
|
+
else data.entries[idx] = entry;
|
|
312
|
+
await this.save(data);
|
|
313
|
+
}
|
|
314
|
+
async remove(slug) {
|
|
315
|
+
const data = await this.load();
|
|
316
|
+
const next = data.entries.filter((e) => e.slug !== slug);
|
|
317
|
+
if (next.length === data.entries.length) return false;
|
|
318
|
+
await this.save({ version: 1, entries: next });
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
async list() {
|
|
322
|
+
return (await this.load()).entries;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/prompts/prompt-journal.ts
|
|
327
|
+
import * as fs2 from "node:fs/promises";
|
|
328
|
+
import * as path2 from "node:path";
|
|
329
|
+
var PROMPT_JOURNAL_RAW_MARKER = "promptJournal.raw";
|
|
330
|
+
async function ensureGitignore(projectRoot) {
|
|
331
|
+
const gitignorePath = path2.join(projectRoot, ".gitignore");
|
|
332
|
+
try {
|
|
333
|
+
let content = "";
|
|
334
|
+
try {
|
|
335
|
+
content = await fs2.readFile(gitignorePath, "utf8");
|
|
336
|
+
} catch {
|
|
337
|
+
content = "";
|
|
338
|
+
}
|
|
339
|
+
if (!content.includes(".wrongstack") && !content.includes(".wrongstack/")) {
|
|
340
|
+
const addition = content.endsWith("\n") || content.length === 0 ? ".wrongstack/\n" : "\n.wrongstack/\n";
|
|
341
|
+
await fs2.writeFile(gitignorePath, content + addition, "utf8");
|
|
342
|
+
}
|
|
343
|
+
} catch {
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function sessionFileId(sessionId) {
|
|
347
|
+
const leaf = sessionId.split(/[\\/]/u).pop();
|
|
348
|
+
return leaf && leaf.trim().length > 0 ? leaf : "general";
|
|
349
|
+
}
|
|
350
|
+
async function recordPromptJournalEntry(opts) {
|
|
351
|
+
const now = /* @__PURE__ */ new Date();
|
|
352
|
+
const timestamp = now.toISOString();
|
|
353
|
+
const dateStr = timestamp.slice(0, 10);
|
|
354
|
+
const monthStr = dateStr.slice(0, 7);
|
|
355
|
+
const sessionId = opts.sessionId && opts.sessionId.trim() ? opts.sessionId.trim() : "general";
|
|
356
|
+
const id = `pmt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
357
|
+
const content = opts.content ?? "";
|
|
358
|
+
const lines = content.split("\n");
|
|
359
|
+
const characterCount = content.length;
|
|
360
|
+
const lineCount = lines.length;
|
|
361
|
+
const tokenEstimate = Math.ceil(characterCount / 4);
|
|
362
|
+
const entry = {
|
|
363
|
+
id,
|
|
364
|
+
timestamp,
|
|
365
|
+
sessionId,
|
|
366
|
+
projectRoot: opts.projectRoot,
|
|
367
|
+
role: opts.role ?? (opts.category === "system_prompt" ? "system" : "user"),
|
|
368
|
+
category: opts.category,
|
|
369
|
+
content,
|
|
370
|
+
rawContent: opts.rawContent,
|
|
371
|
+
metadata: {
|
|
372
|
+
model: opts.model,
|
|
373
|
+
provider: opts.provider,
|
|
374
|
+
iterationIndex: opts.iterationIndex,
|
|
375
|
+
tokenEstimate,
|
|
376
|
+
characterCount,
|
|
377
|
+
lineCount,
|
|
378
|
+
activeTools: opts.activeTools,
|
|
379
|
+
contextFiles: opts.contextFiles,
|
|
380
|
+
durationMs: opts.durationMs,
|
|
381
|
+
decisionReason: opts.decisionReason,
|
|
382
|
+
tags: opts.tags
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
const basePromptsDir = path2.join(opts.projectRoot, ".wrongstack", "prompts");
|
|
386
|
+
const dayDir = path2.join(basePromptsDir, monthStr, dateStr);
|
|
387
|
+
try {
|
|
388
|
+
await fs2.mkdir(dayDir, { recursive: true });
|
|
389
|
+
await ensureGitignore(opts.projectRoot);
|
|
390
|
+
const sessionJsonlFile = path2.join(dayDir, `session-${sessionFileId(sessionId)}.jsonl`);
|
|
391
|
+
await fs2.appendFile(sessionJsonlFile, JSON.stringify(entry) + "\n", "utf8");
|
|
392
|
+
const sessionMdFile = path2.join(dayDir, `session-${sessionFileId(sessionId)}.md`);
|
|
393
|
+
const mdSection = formatEntryMarkdown(entry);
|
|
394
|
+
await fs2.appendFile(sessionMdFile, mdSection, "utf8");
|
|
395
|
+
const dailySummaryFile = path2.join(dayDir, "daily-summary.md");
|
|
396
|
+
await updateDailySummary(dailySummaryFile, dateStr, entry);
|
|
397
|
+
await updateRootCatalog(basePromptsDir, monthStr, dateStr, sessionId, entry);
|
|
398
|
+
} catch (err) {
|
|
399
|
+
console.error?.(`Failed to write hierarchical prompt journal: ${err}`);
|
|
400
|
+
}
|
|
401
|
+
return entry;
|
|
402
|
+
}
|
|
403
|
+
function formatEntryMarkdown(entry) {
|
|
404
|
+
const tagList = [
|
|
405
|
+
`**Category:** \`${entry.category}\``,
|
|
406
|
+
`**Role:** \`${entry.role}\``,
|
|
407
|
+
entry.metadata.model ? `**Model:** \`${entry.metadata.model}\`` : null,
|
|
408
|
+
`**Tokens (est):** ~${entry.metadata.tokenEstimate}`,
|
|
409
|
+
entry.metadata.iterationIndex !== void 0 ? `**Iteration:** #${entry.metadata.iterationIndex}` : null,
|
|
410
|
+
`**Session:** \`${entry.sessionId}\``
|
|
411
|
+
].filter(Boolean).join(" | ");
|
|
412
|
+
let md = `
|
|
413
|
+
### \u{1F4DD} [${entry.timestamp}] \`${entry.id}\`
|
|
414
|
+
${tagList}
|
|
415
|
+
|
|
416
|
+
`;
|
|
417
|
+
if (entry.metadata.decisionReason) {
|
|
418
|
+
md += `> **Rationale:** ${entry.metadata.decisionReason}
|
|
419
|
+
|
|
420
|
+
`;
|
|
421
|
+
}
|
|
422
|
+
if (entry.metadata.activeTools && entry.metadata.activeTools.length > 0) {
|
|
423
|
+
md += `*Active Tools:* \`${entry.metadata.activeTools.join("`, `")}\`
|
|
424
|
+
|
|
425
|
+
`;
|
|
426
|
+
}
|
|
427
|
+
if (entry.rawContent && entry.rawContent !== entry.content) {
|
|
428
|
+
md += `**Raw Input:**
|
|
429
|
+
\`\`\`text
|
|
430
|
+
${entry.rawContent.trim()}
|
|
431
|
+
\`\`\`
|
|
432
|
+
|
|
433
|
+
`;
|
|
434
|
+
md += `**Refined / Injected Prompt:**
|
|
435
|
+
\`\`\`text
|
|
436
|
+
${entry.content.trim()}
|
|
437
|
+
\`\`\`
|
|
438
|
+
|
|
439
|
+
`;
|
|
440
|
+
} else {
|
|
441
|
+
md += `**Prompt Content:**
|
|
442
|
+
\`\`\`text
|
|
443
|
+
${entry.content.trim()}
|
|
444
|
+
\`\`\`
|
|
445
|
+
|
|
446
|
+
`;
|
|
447
|
+
}
|
|
448
|
+
md += `---
|
|
449
|
+
`;
|
|
450
|
+
return md;
|
|
451
|
+
}
|
|
452
|
+
async function updateDailySummary(summaryFile, dateStr, entry) {
|
|
453
|
+
try {
|
|
454
|
+
let content = "";
|
|
455
|
+
try {
|
|
456
|
+
content = await fs2.readFile(summaryFile, "utf8");
|
|
457
|
+
} catch {
|
|
458
|
+
content = `# \u{1F4C5} Daily Prompt Summary \u2014 ${dateStr}
|
|
459
|
+
|
|
460
|
+
| Time | ID | Session | Category | Model | Tokens | Rationale |
|
|
461
|
+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
462
|
+
`;
|
|
463
|
+
}
|
|
464
|
+
const time = entry.timestamp.slice(11, 19);
|
|
465
|
+
const model = entry.metadata.model ?? "-";
|
|
466
|
+
const reason = entry.metadata.decisionReason ? entry.metadata.decisionReason.slice(0, 40) : "-";
|
|
467
|
+
const row = `| ${time} | [\`${entry.id}\`](session-${sessionFileId(entry.sessionId)}.md) | \`${entry.sessionId}\` | \`${entry.category}\` | ${model} | ~${entry.metadata.tokenEstimate} | ${reason} |
|
|
468
|
+
`;
|
|
469
|
+
await fs2.writeFile(summaryFile, content + row, "utf8");
|
|
470
|
+
} catch {
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
async function updateRootCatalog(baseDir, monthStr, dateStr, sessionId, entry) {
|
|
474
|
+
const indexJsonFile = path2.join(baseDir, "index.json");
|
|
475
|
+
const indexMdFile = path2.join(baseDir, "index.md");
|
|
476
|
+
let catalog;
|
|
477
|
+
try {
|
|
478
|
+
const raw = await fs2.readFile(indexJsonFile, "utf8");
|
|
479
|
+
catalog = JSON.parse(raw);
|
|
480
|
+
} catch {
|
|
481
|
+
catalog = {
|
|
482
|
+
updatedAt: entry.timestamp,
|
|
483
|
+
totalPrompts: 0,
|
|
484
|
+
totalTokensEstimated: 0,
|
|
485
|
+
months: {}
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
catalog.updatedAt = entry.timestamp;
|
|
489
|
+
catalog.totalPrompts += 1;
|
|
490
|
+
catalog.totalTokensEstimated += entry.metadata.tokenEstimate;
|
|
491
|
+
if (!catalog.months[monthStr]) {
|
|
492
|
+
catalog.months[monthStr] = { days: {} };
|
|
493
|
+
}
|
|
494
|
+
const monthData = catalog.months[monthStr];
|
|
495
|
+
if (!monthData.days[dateStr]) {
|
|
496
|
+
monthData.days[dateStr] = { sessions: {} };
|
|
497
|
+
}
|
|
498
|
+
const dayData = monthData.days[dateStr];
|
|
499
|
+
if (!dayData.sessions[sessionId]) {
|
|
500
|
+
dayData.sessions[sessionId] = {
|
|
501
|
+
promptCount: 0,
|
|
502
|
+
tokenEstimate: 0,
|
|
503
|
+
lastTimestamp: entry.timestamp,
|
|
504
|
+
categories: {}
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
const sessionData = dayData.sessions[sessionId];
|
|
508
|
+
sessionData.promptCount += 1;
|
|
509
|
+
sessionData.tokenEstimate += entry.metadata.tokenEstimate;
|
|
510
|
+
sessionData.lastTimestamp = entry.timestamp;
|
|
511
|
+
sessionData.categories[entry.category] = (sessionData.categories[entry.category] ?? 0) + 1;
|
|
512
|
+
try {
|
|
513
|
+
await fs2.writeFile(indexJsonFile, JSON.stringify(catalog, null, 2), "utf8");
|
|
514
|
+
let md = `# \u{1F5C2}\uFE0F Prompt Journal Navigation Index
|
|
515
|
+
|
|
516
|
+
`;
|
|
517
|
+
md += `* **Total Prompts Logged:** ${catalog.totalPrompts}
|
|
518
|
+
`;
|
|
519
|
+
md += `* **Total Tokens (est):** ~${catalog.totalTokensEstimated.toLocaleString()}
|
|
520
|
+
`;
|
|
521
|
+
md += `* **Last Recorded Activity:** ${catalog.updatedAt}
|
|
522
|
+
|
|
523
|
+
`;
|
|
524
|
+
md += `## \u{1F4C5} Recorded Dates & Sessions
|
|
525
|
+
|
|
526
|
+
`;
|
|
527
|
+
md += `| Date | Session | Prompts | Tokens (est) | Daily Log | Session Log |
|
|
528
|
+
`;
|
|
529
|
+
md += `| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
530
|
+
`;
|
|
531
|
+
for (const [m, mObj] of Object.entries(catalog.months).sort().reverse()) {
|
|
532
|
+
for (const [d, dObj] of Object.entries(mObj.days).sort().reverse()) {
|
|
533
|
+
for (const [sId, sData] of Object.entries(dObj.sessions)) {
|
|
534
|
+
const dailyLink = `[daily-summary.md](./${m}/${d}/daily-summary.md)`;
|
|
535
|
+
const sessionLink = `[session-${sessionFileId(sId)}.md](./${m}/${d}/session-${sessionFileId(sId)}.md)`;
|
|
536
|
+
md += `| **${d}** | \`${sId}\` | ${sData.promptCount} | ~${sData.tokenEstimate.toLocaleString()} | ${dailyLink} | ${sessionLink} |
|
|
537
|
+
`;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
await fs2.writeFile(indexMdFile, md, "utf8");
|
|
542
|
+
} catch {
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
async function getPromptJournalEntries(projectRoot, filter = {}) {
|
|
546
|
+
const basePromptsDir = path2.join(projectRoot, ".wrongstack", "prompts");
|
|
547
|
+
const results = [];
|
|
548
|
+
try {
|
|
549
|
+
const months = await fs2.readdir(basePromptsDir);
|
|
550
|
+
for (const month of months) {
|
|
551
|
+
if (!/^\d{4}-\d{2}$/.test(month)) continue;
|
|
552
|
+
if (filter.month && filter.month !== month) continue;
|
|
553
|
+
const monthDir = path2.join(basePromptsDir, month);
|
|
554
|
+
const days = await fs2.readdir(monthDir);
|
|
555
|
+
for (const day of days) {
|
|
556
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) continue;
|
|
557
|
+
if (filter.date && filter.date !== day) continue;
|
|
558
|
+
const dayDir = path2.join(monthDir, day);
|
|
559
|
+
const files = await fs2.readdir(dayDir);
|
|
560
|
+
const jsonlFiles = files.filter((f) => f.startsWith("session-") && f.endsWith(".jsonl"));
|
|
561
|
+
for (const jsonlFile of jsonlFiles) {
|
|
562
|
+
const sessionMatch = jsonlFile.match(/^session-(.+)\.jsonl$/);
|
|
563
|
+
const sId = sessionMatch ? sessionMatch[1] : void 0;
|
|
564
|
+
if (filter.sessionId && sId !== sessionFileId(filter.sessionId)) continue;
|
|
565
|
+
const filePath = path2.join(dayDir, jsonlFile);
|
|
566
|
+
const content = await fs2.readFile(filePath, "utf8");
|
|
567
|
+
const lines = content.split("\n");
|
|
568
|
+
for (const line of lines) {
|
|
569
|
+
if (!line.trim()) continue;
|
|
570
|
+
try {
|
|
571
|
+
const entry = JSON.parse(line);
|
|
572
|
+
if (filter.sessionId && sessionFileId(entry.sessionId) !== sessionFileId(filter.sessionId)) {
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
if (filter.category && entry.category !== filter.category) continue;
|
|
576
|
+
if (filter.since && entry.timestamp < filter.since) continue;
|
|
577
|
+
results.push(entry);
|
|
578
|
+
} catch {
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
} catch {
|
|
585
|
+
return [];
|
|
586
|
+
}
|
|
587
|
+
results.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
588
|
+
if (filter.limit && results.length > filter.limit) {
|
|
589
|
+
return results.slice(-filter.limit);
|
|
590
|
+
}
|
|
591
|
+
return results;
|
|
592
|
+
}
|
|
593
|
+
export {
|
|
594
|
+
PROMPT_JOURNAL_RAW_MARKER,
|
|
595
|
+
PromptInstaller,
|
|
596
|
+
PromptManifestStore,
|
|
597
|
+
ensureGitignore,
|
|
598
|
+
getPromptJournalEntries,
|
|
599
|
+
recordPromptJournalEntry
|
|
600
|
+
};
|
|
601
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchical Prompt Journal & Detailed Interaction Trace Logger.
|
|
3
|
+
*
|
|
4
|
+
* Persists comprehensive prompt history within a clean date & session folder hierarchy
|
|
5
|
+
* at `<projectRoot>/.wrongstack/prompts/`:
|
|
6
|
+
*
|
|
7
|
+
* ├── index.json <-- High-level catalog of dates, sessions & stats
|
|
8
|
+
* ├── index.md <-- Visual navigation board linking to daily journals
|
|
9
|
+
* └── YYYY-MM/ <-- Month folder (e.g. 2026-08)
|
|
10
|
+
* └── YYYY-MM-DD/ <-- Day folder (e.g. 2026-08-15)
|
|
11
|
+
* ├── daily-summary.md <-- Day's overview & interaction breakdown
|
|
12
|
+
* ├── session-<id>.md <-- Rich Markdown journal for that session
|
|
13
|
+
* └── session-<id>.jsonl <-- Machine-readable JSONL for that session
|
|
14
|
+
*
|
|
15
|
+
* Automatically ensures `.wrongstack/` is in `.gitignore` so traces are never
|
|
16
|
+
* accidentally committed to version control.
|
|
17
|
+
*/
|
|
18
|
+
export type PromptCategory = 'raw_user' | 'refined_user' | 'system_prompt' | 'autonomous_next_step' | 'self_healing_retry' | 'clarify_interaction' | 'subagent_delegation';
|
|
19
|
+
export interface PromptJournalEntry {
|
|
20
|
+
id: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
sessionId: string;
|
|
23
|
+
projectRoot: string;
|
|
24
|
+
role: 'user' | 'system' | 'assistant' | 'tool';
|
|
25
|
+
category: PromptCategory;
|
|
26
|
+
content: string;
|
|
27
|
+
rawContent?: string | undefined;
|
|
28
|
+
metadata: {
|
|
29
|
+
model?: string | undefined;
|
|
30
|
+
provider?: string | undefined;
|
|
31
|
+
iterationIndex?: number | undefined;
|
|
32
|
+
tokenEstimate: number;
|
|
33
|
+
characterCount: number;
|
|
34
|
+
lineCount: number;
|
|
35
|
+
activeTools?: string[] | undefined;
|
|
36
|
+
contextFiles?: string[] | undefined;
|
|
37
|
+
durationMs?: number | undefined;
|
|
38
|
+
decisionReason?: string | undefined;
|
|
39
|
+
tags?: string[] | undefined;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface RecordPromptOptions {
|
|
43
|
+
projectRoot: string;
|
|
44
|
+
sessionId?: string | undefined;
|
|
45
|
+
role?: 'user' | 'system' | 'assistant' | 'tool' | undefined;
|
|
46
|
+
category: PromptCategory;
|
|
47
|
+
content: string;
|
|
48
|
+
rawContent?: string | undefined;
|
|
49
|
+
model?: string | undefined;
|
|
50
|
+
provider?: string | undefined;
|
|
51
|
+
iterationIndex?: number | undefined;
|
|
52
|
+
activeTools?: string[] | undefined;
|
|
53
|
+
contextFiles?: string[] | undefined;
|
|
54
|
+
durationMs?: number | undefined;
|
|
55
|
+
decisionReason?: string | undefined;
|
|
56
|
+
tags?: string[] | undefined;
|
|
57
|
+
}
|
|
58
|
+
export interface PromptJournalFilter {
|
|
59
|
+
sessionId?: string | undefined;
|
|
60
|
+
category?: PromptCategory | undefined;
|
|
61
|
+
date?: string | undefined;
|
|
62
|
+
month?: string | undefined;
|
|
63
|
+
since?: string | undefined;
|
|
64
|
+
limit?: number | undefined;
|
|
65
|
+
}
|
|
66
|
+
export interface PromptJournalIndex {
|
|
67
|
+
updatedAt: string;
|
|
68
|
+
totalPrompts: number;
|
|
69
|
+
totalTokensEstimated: number;
|
|
70
|
+
months: Record<string, {
|
|
71
|
+
days: Record<string, {
|
|
72
|
+
sessions: Record<string, {
|
|
73
|
+
promptCount: number;
|
|
74
|
+
tokenEstimate: number;
|
|
75
|
+
lastTimestamp: string;
|
|
76
|
+
categories: Record<string, number>;
|
|
77
|
+
}>;
|
|
78
|
+
}>;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* `ctx.meta` key the TUI's submit path stamps with the raw (pre-refinement)
|
|
83
|
+
* user prompt text when the refiner rewrote the prompt. The CLI's
|
|
84
|
+
* prompt-journal recorder consumes the marker to label the turn
|
|
85
|
+
* `refined_user` (with `rawContent` preserved) instead of `raw_user`.
|
|
86
|
+
*
|
|
87
|
+
* Shared here so the two sides (TUI stamp, CLI consumer) cannot drift.
|
|
88
|
+
*/
|
|
89
|
+
export declare const PROMPT_JOURNAL_RAW_MARKER = "promptJournal.raw";
|
|
90
|
+
/**
|
|
91
|
+
* Ensures `<projectRoot>/.gitignore` contains `.wrongstack/` to keep all
|
|
92
|
+
* prompt logs, telemetry, and indexes out of version control.
|
|
93
|
+
*/
|
|
94
|
+
export declare function ensureGitignore(projectRoot: string): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Record a comprehensive prompt entry into the hierarchical date-based prompt journal.
|
|
97
|
+
*/
|
|
98
|
+
export declare function recordPromptJournalEntry(opts: RecordPromptOptions): Promise<PromptJournalEntry>;
|
|
99
|
+
/**
|
|
100
|
+
* Read prompt journal entries hierarchically across all date directories.
|
|
101
|
+
*/
|
|
102
|
+
export declare function getPromptJournalEntries(projectRoot: string, filter?: PromptJournalFilter): Promise<PromptJournalEntry[]>;
|
|
103
|
+
//# sourceMappingURL=prompt-journal.d.ts.map
|