thevoidforge 21.0.5 → 21.0.6
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/wizard/api/blueprint.d.ts +0 -11
- package/dist/wizard/api/blueprint.js +13 -38
- package/dist/wizard/api/project.js +2 -1
- package/dist/wizard/lib/autonomy-controller.d.ts +2 -2
- package/dist/wizard/lib/autonomy-controller.js +9 -8
- package/dist/wizard/lib/campaign-proposer.js +4 -3
- package/dist/wizard/lib/correlation-engine.js +13 -12
- package/dist/wizard/lib/deep-current.d.ts +9 -9
- package/dist/wizard/lib/deep-current.js +27 -14
- package/package.json +1 -1
|
@@ -32,14 +32,3 @@ export declare function executeBlueprintMerge(projectRoot: string, directivesPat
|
|
|
32
32
|
merged: boolean;
|
|
33
33
|
reason: string;
|
|
34
34
|
}>;
|
|
35
|
-
/**
|
|
36
|
-
* Handle blueprint API requests. Mount at /api/blueprint/*
|
|
37
|
-
*
|
|
38
|
-
* GET /api/blueprint/detect?dir=<path> — Check if PRD exists
|
|
39
|
-
* GET /api/blueprint/validate?dir=<path> — Full validation
|
|
40
|
-
* POST /api/blueprint/merge — Execute CLAUDE.md merge
|
|
41
|
-
*/
|
|
42
|
-
export declare function handleBlueprintRequest(method: string, path: string, body: unknown): Promise<{
|
|
43
|
-
status: number;
|
|
44
|
-
body: unknown;
|
|
45
|
-
} | null>;
|
|
@@ -109,38 +109,15 @@ export async function executeBlueprintMerge(projectRoot, directivesPath) {
|
|
|
109
109
|
* GET /api/blueprint/validate?dir=<path> — Full validation
|
|
110
110
|
* POST /api/blueprint/merge — Execute CLAUDE.md merge
|
|
111
111
|
*/
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
status: 200,
|
|
123
|
-
body: {
|
|
124
|
-
detected: true,
|
|
125
|
-
name: frontmatter.name ?? 'Unnamed',
|
|
126
|
-
description: frontmatter.type ?? 'Unknown type',
|
|
127
|
-
},
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
return { status: 200, body: { detected: false } };
|
|
131
|
-
}
|
|
132
|
-
if (method === 'GET' && path === '/api/blueprint/validate') {
|
|
133
|
-
const projectRoot = process.cwd();
|
|
134
|
-
const result = await validateBlueprint(projectRoot);
|
|
135
|
-
return { status: 200, body: result };
|
|
136
|
-
}
|
|
137
|
-
if (method === 'POST' && path === '/api/blueprint/merge') {
|
|
138
|
-
const projectRoot = process.cwd();
|
|
139
|
-
const params = body;
|
|
140
|
-
const result = await executeBlueprintMerge(projectRoot, params?.directivesPath ?? null);
|
|
141
|
-
return { status: 200, body: result };
|
|
142
|
-
}
|
|
143
|
-
return null; // Not a blueprint route
|
|
112
|
+
// Resolve project root from request query param, falling back to marker discovery.
|
|
113
|
+
// The wizard is standalone (v21.0) — CWD is NOT a project directory.
|
|
114
|
+
import { findProjectRoot } from '../lib/marker.js';
|
|
115
|
+
function resolveProjectRoot(req) {
|
|
116
|
+
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
|
|
117
|
+
const dirParam = url.searchParams.get('dir');
|
|
118
|
+
if (dirParam && dirParam !== 'undefined')
|
|
119
|
+
return dirParam;
|
|
120
|
+
return findProjectRoot() ?? process.cwd();
|
|
144
121
|
}
|
|
145
122
|
// ── JSON Response Helper ────────────────────────────
|
|
146
123
|
function sendJson(res, status, data) {
|
|
@@ -149,9 +126,7 @@ function sendJson(res, status, data) {
|
|
|
149
126
|
}
|
|
150
127
|
// ── Route Registration ──────────────────────────────
|
|
151
128
|
addRoute('GET', '/api/blueprint/detect', async (req, res) => {
|
|
152
|
-
const
|
|
153
|
-
const dirParam = url.searchParams.get('dir');
|
|
154
|
-
const projectRoot = dirParam && dirParam !== 'undefined' ? dirParam : process.cwd();
|
|
129
|
+
const projectRoot = resolveProjectRoot(req);
|
|
155
130
|
const prdPath = join(projectRoot, 'docs/PRD.md');
|
|
156
131
|
if (existsSync(prdPath)) {
|
|
157
132
|
const content = await readFile(prdPath, 'utf-8');
|
|
@@ -166,8 +141,8 @@ addRoute('GET', '/api/blueprint/detect', async (req, res) => {
|
|
|
166
141
|
sendJson(res, 200, { detected: false });
|
|
167
142
|
}
|
|
168
143
|
});
|
|
169
|
-
addRoute('GET', '/api/blueprint/validate', async (
|
|
170
|
-
const projectRoot =
|
|
144
|
+
addRoute('GET', '/api/blueprint/validate', async (req, res) => {
|
|
145
|
+
const projectRoot = resolveProjectRoot(req);
|
|
171
146
|
const result = await validateBlueprint(projectRoot);
|
|
172
147
|
sendJson(res, 200, result);
|
|
173
148
|
});
|
|
@@ -180,7 +155,7 @@ addRoute('POST', '/api/blueprint/merge', async (req, res) => {
|
|
|
180
155
|
params = JSON.parse(body);
|
|
181
156
|
}
|
|
182
157
|
catch { /* empty body is fine — directivesPath defaults to null */ }
|
|
183
|
-
const projectRoot =
|
|
158
|
+
const projectRoot = resolveProjectRoot(req);
|
|
184
159
|
const result = await executeBlueprintMerge(projectRoot, params.directivesPath ?? null);
|
|
185
160
|
sendJson(res, 200, result);
|
|
186
161
|
});
|
|
@@ -41,8 +41,9 @@ addRoute('POST', '/api/project/validate', async (req, res) => {
|
|
|
41
41
|
// Directory doesn't exist — that's fine
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
const homeDir = process.env['HOME'] ?? process.env['USERPROFILE'] ?? '/tmp';
|
|
44
45
|
const suggestedDir = body.name
|
|
45
|
-
? resolve(
|
|
46
|
+
? resolve(homeDir, 'Projects', sanitizeDirName(body.name))
|
|
46
47
|
: undefined;
|
|
47
48
|
sendJson(res, 200, { valid: errors.length === 0, errors, suggestedDir });
|
|
48
49
|
});
|
|
@@ -33,7 +33,7 @@ interface AutonomyState {
|
|
|
33
33
|
endHour: number;
|
|
34
34
|
}>;
|
|
35
35
|
}
|
|
36
|
-
declare
|
|
36
|
+
declare function getAutonomyStatePath(): string;
|
|
37
37
|
declare const DEFAULT_STATE: AutonomyState;
|
|
38
38
|
export declare function loadAutonomyState(): Promise<AutonomyState>;
|
|
39
39
|
export declare function saveAutonomyState(state: AutonomyState): Promise<void>;
|
|
@@ -73,4 +73,4 @@ interface SoftLimits {
|
|
|
73
73
|
}
|
|
74
74
|
declare const DEFAULT_SOFT_LIMITS: SoftLimits;
|
|
75
75
|
export type { AutonomyState, CircuitBreakerResult, SoftLimits };
|
|
76
|
-
export { DEFAULT_STATE, DEFAULT_SOFT_LIMITS,
|
|
76
|
+
export { DEFAULT_STATE, DEFAULT_SOFT_LIMITS, getAutonomyStatePath };
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
import { existsSync } from 'node:fs';
|
|
10
10
|
import { readFile, open, rename, mkdir } from 'node:fs/promises';
|
|
11
11
|
import { join } from 'node:path';
|
|
12
|
-
import {
|
|
13
|
-
|
|
12
|
+
import { deepCurrentDir } from './deep-current.js';
|
|
13
|
+
import { findProjectRoot } from './marker.js';
|
|
14
|
+
function getAutonomyStatePath() { return join(deepCurrentDir(findProjectRoot() ?? process.cwd()), 'autonomy-state.json'); }
|
|
14
15
|
const DEFAULT_STATE = {
|
|
15
16
|
tier: 1,
|
|
16
17
|
active: false,
|
|
@@ -29,10 +30,10 @@ const DEFAULT_STATE = {
|
|
|
29
30
|
};
|
|
30
31
|
// ── State Persistence ─────────────────────────────────
|
|
31
32
|
export async function loadAutonomyState() {
|
|
32
|
-
if (!existsSync(
|
|
33
|
+
if (!existsSync(getAutonomyStatePath()))
|
|
33
34
|
return { ...DEFAULT_STATE };
|
|
34
35
|
try {
|
|
35
|
-
const content = await readFile(
|
|
36
|
+
const content = await readFile(getAutonomyStatePath(), 'utf-8');
|
|
36
37
|
return JSON.parse(content);
|
|
37
38
|
}
|
|
38
39
|
catch {
|
|
@@ -48,9 +49,9 @@ function serialized(fn) {
|
|
|
48
49
|
}
|
|
49
50
|
export function saveAutonomyState(state) {
|
|
50
51
|
return serialized(async () => {
|
|
51
|
-
await mkdir(
|
|
52
|
+
await mkdir(deepCurrentDir(findProjectRoot() ?? process.cwd()), { recursive: true });
|
|
52
53
|
// IG-R4 LOKI-001: Atomic write — temp+fsync+rename prevents kill switch reset on crash
|
|
53
|
-
const tmpPath =
|
|
54
|
+
const tmpPath = getAutonomyStatePath() + '.tmp';
|
|
54
55
|
const fh = await open(tmpPath, 'w', 0o600);
|
|
55
56
|
try {
|
|
56
57
|
await fh.writeFile(JSON.stringify(state, null, 2));
|
|
@@ -59,7 +60,7 @@ export function saveAutonomyState(state) {
|
|
|
59
60
|
finally {
|
|
60
61
|
await fh.close();
|
|
61
62
|
}
|
|
62
|
-
await rename(tmpPath,
|
|
63
|
+
await rename(tmpPath, getAutonomyStatePath());
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
/**
|
|
@@ -180,4 +181,4 @@ const DEFAULT_SOFT_LIMITS = {
|
|
|
180
181
|
lessonDecayHalfLifeDays: 90,
|
|
181
182
|
minRoasBeforeFreeze: 1.0,
|
|
182
183
|
};
|
|
183
|
-
export { DEFAULT_STATE, DEFAULT_SOFT_LIMITS,
|
|
184
|
+
export { DEFAULT_STATE, DEFAULT_SOFT_LIMITS, getAutonomyStatePath };
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import { mkdir, writeFile as writeFileAsync } from 'node:fs/promises';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { randomUUID } from 'node:crypto';
|
|
12
|
-
import {
|
|
12
|
+
import { proposalsDir } from './deep-current.js';
|
|
13
|
+
import { findProjectRoot } from './marker.js';
|
|
13
14
|
import { findWeakestDimension } from './gap-analysis.js';
|
|
14
15
|
// ── Proposal Templates Per Dimension ──────────────────
|
|
15
16
|
function proposeForFeatureCompleteness(model) {
|
|
@@ -144,11 +145,11 @@ export function generateProposal(model) {
|
|
|
144
145
|
* Save a proposal to disk as markdown.
|
|
145
146
|
*/
|
|
146
147
|
export async function saveProposal(proposal) {
|
|
147
|
-
await mkdir(
|
|
148
|
+
await mkdir(proposalsDir(findProjectRoot() ?? process.cwd()), { recursive: true });
|
|
148
149
|
const date = new Date().toISOString().split('T')[0];
|
|
149
150
|
const slug = proposal.name.toLowerCase().replace(/\s+/g, '-');
|
|
150
151
|
const filename = `${date}-${slug}.md`;
|
|
151
|
-
const filepath = join(
|
|
152
|
+
const filepath = join(proposalsDir(findProjectRoot() ?? process.cwd()), filename);
|
|
152
153
|
const content = `# Campaign Proposal — ${proposal.name}
|
|
153
154
|
## Generated by: The Deep Current (Tuvok)
|
|
154
155
|
## Date: ${proposal.generatedAt}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { appendFile, readFile, mkdir } from 'node:fs/promises';
|
|
11
11
|
import { existsSync } from 'node:fs';
|
|
12
|
-
import {
|
|
12
|
+
import { correlationsPath, predictionsPath, deepCurrentDir } from './deep-current.js';
|
|
13
|
+
import { findProjectRoot } from './marker.js';
|
|
13
14
|
// ── Event Logging ─────────────────────────────────────
|
|
14
15
|
async function appendEvent(entry) {
|
|
15
|
-
await mkdir(
|
|
16
|
-
await appendFile(
|
|
16
|
+
await mkdir(deepCurrentDir(findProjectRoot() ?? process.cwd()), { recursive: true });
|
|
17
|
+
await appendFile(correlationsPath(findProjectRoot() ?? process.cwd()), JSON.stringify(entry) + '\n', 'utf-8');
|
|
17
18
|
}
|
|
18
19
|
export async function logCampaignComplete(name, missions, dimension) {
|
|
19
20
|
await appendEvent({
|
|
@@ -40,9 +41,9 @@ export async function logMetric(metric, value, source) {
|
|
|
40
41
|
* Uses before/after comparison with configurable lag windows.
|
|
41
42
|
*/
|
|
42
43
|
export async function detectCorrelations(lagDays = 7) {
|
|
43
|
-
if (!existsSync(
|
|
44
|
+
if (!existsSync(correlationsPath(findProjectRoot() ?? process.cwd())))
|
|
44
45
|
return [];
|
|
45
|
-
const content = await readFile(
|
|
46
|
+
const content = await readFile(correlationsPath(findProjectRoot() ?? process.cwd()), 'utf-8');
|
|
46
47
|
const lines = content.trim().split('\n').filter(Boolean);
|
|
47
48
|
const events = lines.map(l => { try {
|
|
48
49
|
return JSON.parse(l);
|
|
@@ -97,20 +98,20 @@ export async function detectCorrelations(lagDays = 7) {
|
|
|
97
98
|
return correlations;
|
|
98
99
|
}
|
|
99
100
|
export async function recordPrediction(proposal) {
|
|
100
|
-
await mkdir(
|
|
101
|
+
await mkdir(deepCurrentDir(findProjectRoot() ?? process.cwd()), { recursive: true });
|
|
101
102
|
const record = {
|
|
102
103
|
proposalId: proposal.id,
|
|
103
104
|
proposalName: proposal.name,
|
|
104
105
|
predictedImpact: proposal.expectedImpact,
|
|
105
106
|
recordedAt: new Date().toISOString(),
|
|
106
107
|
};
|
|
107
|
-
await appendFile(
|
|
108
|
+
await appendFile(predictionsPath(findProjectRoot() ?? process.cwd()), JSON.stringify(record) + '\n', 'utf-8');
|
|
108
109
|
}
|
|
109
110
|
export async function evaluatePrediction(proposalId, actualImpact, accuracy) {
|
|
110
111
|
// Read existing predictions, find the matching one, update it
|
|
111
|
-
if (!existsSync(
|
|
112
|
+
if (!existsSync(predictionsPath(findProjectRoot() ?? process.cwd())))
|
|
112
113
|
return;
|
|
113
|
-
const content = await readFile(
|
|
114
|
+
const content = await readFile(predictionsPath(findProjectRoot() ?? process.cwd()), 'utf-8');
|
|
114
115
|
const lines = content.trim().split('\n').filter(Boolean);
|
|
115
116
|
const updated = lines.map(line => {
|
|
116
117
|
try {
|
|
@@ -127,15 +128,15 @@ export async function evaluatePrediction(proposalId, actualImpact, accuracy) {
|
|
|
127
128
|
}
|
|
128
129
|
});
|
|
129
130
|
const { writeFile: wf } = await import('node:fs/promises');
|
|
130
|
-
await wf(
|
|
131
|
+
await wf(predictionsPath(findProjectRoot() ?? process.cwd()), updated.join('\n') + '\n');
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
134
|
* Calculate average prediction accuracy across all evaluated predictions.
|
|
134
135
|
*/
|
|
135
136
|
export async function getAveragePredictionAccuracy() {
|
|
136
|
-
if (!existsSync(
|
|
137
|
+
if (!existsSync(predictionsPath(findProjectRoot() ?? process.cwd())))
|
|
137
138
|
return 0;
|
|
138
|
-
const content = await readFile(
|
|
139
|
+
const content = await readFile(predictionsPath(findProjectRoot() ?? process.cwd()), 'utf-8');
|
|
139
140
|
const records = content.trim().split('\n').filter(Boolean)
|
|
140
141
|
.map(l => { try {
|
|
141
142
|
return JSON.parse(l);
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
* PRD Reference: ROADMAP v12.0, docs/methods/DEEP_CURRENT.md
|
|
9
9
|
*/
|
|
10
10
|
import type { SiteScanResult } from './site-scanner.js';
|
|
11
|
-
declare
|
|
12
|
-
declare
|
|
13
|
-
declare
|
|
14
|
-
declare
|
|
15
|
-
declare
|
|
11
|
+
declare function deepCurrentDir(projectDir: string): string;
|
|
12
|
+
declare function situationPath(projectDir: string): string;
|
|
13
|
+
declare function proposalsDir(projectDir: string): string;
|
|
14
|
+
declare function predictionsPath(projectDir: string): string;
|
|
15
|
+
declare function correlationsPath(projectDir: string): string;
|
|
16
16
|
type ProjectState = 'GREENFIELD' | 'IDEA_PRD' | 'PARTIAL' | 'DEPLOYED' | 'OPERATING';
|
|
17
17
|
interface ProjectClassification {
|
|
18
18
|
state: ProjectState;
|
|
@@ -59,8 +59,8 @@ interface SituationModel {
|
|
|
59
59
|
autonomyTier: 1 | 2 | 3;
|
|
60
60
|
lastSiteScan?: SiteScanResult;
|
|
61
61
|
}
|
|
62
|
-
export declare function loadSituation(): Promise<SituationModel | null>;
|
|
63
|
-
export declare function saveSituation(model: SituationModel): Promise<void>;
|
|
62
|
+
export declare function loadSituation(projectDir: string): Promise<SituationModel | null>;
|
|
63
|
+
export declare function saveSituation(projectDir: string, model: SituationModel): Promise<void>;
|
|
64
64
|
export declare function sense(model: SituationModel): Promise<SituationModel>;
|
|
65
65
|
interface IntakeResult {
|
|
66
66
|
classification: ProjectClassification;
|
|
@@ -72,6 +72,6 @@ interface IntakeResult {
|
|
|
72
72
|
* Cold start intake: classify the project, scan if deployed, create situation model.
|
|
73
73
|
* Returns the initial situation and a recommended first action.
|
|
74
74
|
*/
|
|
75
|
-
export declare function intake(projectName: string): Promise<IntakeResult>;
|
|
75
|
+
export declare function intake(projectName: string, projectDir?: string): Promise<IntakeResult>;
|
|
76
76
|
export type { ProjectState, ProjectClassification, SituationModel, DimensionScore, CampaignRecord, IntakeResult };
|
|
77
|
-
export {
|
|
77
|
+
export { deepCurrentDir, situationPath, proposalsDir, predictionsPath, correlationsPath };
|
|
@@ -12,11 +12,23 @@ import { join } from 'node:path';
|
|
|
12
12
|
import { existsSync } from 'node:fs';
|
|
13
13
|
import { homedir } from 'node:os';
|
|
14
14
|
import { scanSite, scoreScan } from './site-scanner.js';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// Lazy path resolution — project dir is passed by callers, not assumed from CWD.
|
|
16
|
+
// The wizard is standalone (v21.0) — CWD is NOT a project directory.
|
|
17
|
+
function deepCurrentDir(projectDir) {
|
|
18
|
+
return join(projectDir, 'logs', 'deep-current');
|
|
19
|
+
}
|
|
20
|
+
function situationPath(projectDir) {
|
|
21
|
+
return join(deepCurrentDir(projectDir), 'situation.json');
|
|
22
|
+
}
|
|
23
|
+
function proposalsDir(projectDir) {
|
|
24
|
+
return join(deepCurrentDir(projectDir), 'proposals');
|
|
25
|
+
}
|
|
26
|
+
function predictionsPath(projectDir) {
|
|
27
|
+
return join(deepCurrentDir(projectDir), 'predictions.jsonl');
|
|
28
|
+
}
|
|
29
|
+
function correlationsPath(projectDir) {
|
|
30
|
+
return join(deepCurrentDir(projectDir), 'correlations.jsonl');
|
|
31
|
+
}
|
|
20
32
|
/**
|
|
21
33
|
* Classify the current project's state by checking for key files and config.
|
|
22
34
|
*/
|
|
@@ -84,20 +96,21 @@ function createEmptyModel(projectName, state) {
|
|
|
84
96
|
};
|
|
85
97
|
}
|
|
86
98
|
// ── Persistence ───────────────────────────────────────
|
|
87
|
-
export async function loadSituation() {
|
|
88
|
-
|
|
99
|
+
export async function loadSituation(projectDir) {
|
|
100
|
+
const path = situationPath(projectDir);
|
|
101
|
+
if (!existsSync(path))
|
|
89
102
|
return null;
|
|
90
103
|
try {
|
|
91
|
-
const content = await readFile(
|
|
104
|
+
const content = await readFile(path, 'utf-8');
|
|
92
105
|
return JSON.parse(content);
|
|
93
106
|
}
|
|
94
107
|
catch {
|
|
95
108
|
return null;
|
|
96
109
|
}
|
|
97
110
|
}
|
|
98
|
-
export async function saveSituation(model) {
|
|
99
|
-
await mkdir(
|
|
100
|
-
await writeFileAsync(
|
|
111
|
+
export async function saveSituation(projectDir, model) {
|
|
112
|
+
await mkdir(deepCurrentDir(projectDir), { recursive: true });
|
|
113
|
+
await writeFileAsync(situationPath(projectDir), JSON.stringify(model, null, 2));
|
|
101
114
|
}
|
|
102
115
|
// ── SENSE Step — Update situation model from scans ────
|
|
103
116
|
export async function sense(model) {
|
|
@@ -167,7 +180,7 @@ function buildGrowthGaps(scan) {
|
|
|
167
180
|
* Cold start intake: classify the project, scan if deployed, create situation model.
|
|
168
181
|
* Returns the initial situation and a recommended first action.
|
|
169
182
|
*/
|
|
170
|
-
export async function intake(projectName) {
|
|
183
|
+
export async function intake(projectName, projectDir = process.cwd()) {
|
|
171
184
|
const classification = await classifyProject();
|
|
172
185
|
const model = createEmptyModel(projectName, classification.state);
|
|
173
186
|
let siteScan;
|
|
@@ -209,7 +222,7 @@ export async function intake(projectName) {
|
|
|
209
222
|
break;
|
|
210
223
|
}
|
|
211
224
|
// Save the model
|
|
212
|
-
await saveSituation(model);
|
|
225
|
+
await saveSituation(projectDir, model);
|
|
213
226
|
return { classification, situation: model, siteScan, recommendedFirstAction };
|
|
214
227
|
}
|
|
215
228
|
function findLowestDimension(model) {
|
|
@@ -231,4 +244,4 @@ function findLowestDimension(model) {
|
|
|
231
244
|
};
|
|
232
245
|
return `${labels[lowest]} (${lowestScore}/100)`;
|
|
233
246
|
}
|
|
234
|
-
export {
|
|
247
|
+
export { deepCurrentDir, situationPath, proposalsDir, predictionsPath, correlationsPath };
|