heyiam 0.2.26 → 0.2.28
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/archive.js +3 -3
- package/dist/daemon-install.js +2 -2
- package/dist/db.js +4 -5
- package/dist/demo-seed.js +3 -3
- package/dist/export.js +6 -6
- package/dist/index.js +7 -7
- package/dist/routes/context.js +2 -2
- package/dist/routes/dashboard.js +1 -1
- package/dist/routes/export.js +7 -4
- package/dist/screenshot.js +1 -1
- package/dist/settings.js +11 -7
- package/package.json +1 -1
package/dist/archive.js
CHANGED
|
@@ -46,13 +46,13 @@ export async function archiveSessionFiles(sessions, configDir) {
|
|
|
46
46
|
* Preserves the relative structure under the project directory.
|
|
47
47
|
*
|
|
48
48
|
* Claude: ~/.claude/projects/{projectDir}/{sessionId}.jsonl
|
|
49
|
-
* → ~/.
|
|
49
|
+
* → ~/.local/share/heyiam/sessions/{projectDir}/{sessionId}.jsonl
|
|
50
50
|
*
|
|
51
51
|
* Codex: ~/.codex/sessions/{nested}/{rollout-xxx}.jsonl
|
|
52
|
-
* → ~/.
|
|
52
|
+
* → ~/.local/share/heyiam/sessions/{projectDir}/{rollout-xxx}.jsonl
|
|
53
53
|
*
|
|
54
54
|
* Gemini: ~/.gemini/tmp/{hash}/logs.json
|
|
55
|
-
* → ~/.
|
|
55
|
+
* → ~/.local/share/heyiam/sessions/{projectDir}/{hash}.json
|
|
56
56
|
*/
|
|
57
57
|
function archiveDestination(originalPath, archiveBase, projectDir) {
|
|
58
58
|
// Claude: find the project dir in the path and take everything after it
|
package/dist/daemon-install.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Download and install the heyiam tray daemon binary from GitHub releases.
|
|
2
2
|
//
|
|
3
3
|
// Detects platform + arch, fetches the correct binary from the latest
|
|
4
|
-
// daemon release, and saves it to ~/.
|
|
4
|
+
// daemon release, and saves it to ~/.local/share/heyiam/daemon/heyiam-tray.
|
|
5
5
|
import { createWriteStream, mkdirSync, chmodSync, existsSync, renameSync, unlinkSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
@@ -30,7 +30,7 @@ export function getAssetName() {
|
|
|
30
30
|
* Returns the directory where the daemon binary is stored.
|
|
31
31
|
*/
|
|
32
32
|
export function getDaemonDir() {
|
|
33
|
-
return join(homedir(), '.
|
|
33
|
+
return join(homedir(), '.local', 'share', 'heyiam', 'daemon');
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Returns the full path to the daemon binary.
|
package/dist/db.js
CHANGED
|
@@ -6,14 +6,13 @@ import { mkdirSync, statSync } from 'node:fs';
|
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { homedir } from 'node:os';
|
|
8
8
|
// ── Constants ────────────────────────────────────────────────
|
|
9
|
-
function
|
|
10
|
-
return process.env.
|
|
9
|
+
function getDataDir() {
|
|
10
|
+
return process.env.HEYIAM_DATA_DIR || join(homedir(), '.local', 'share', 'heyiam');
|
|
11
11
|
}
|
|
12
12
|
export function getDbPath() {
|
|
13
|
-
return join(
|
|
13
|
+
return join(getDataDir(), 'sessions.db');
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
export const DB_PATH = join(homedir(), '.config', 'heyiam', 'sessions.db');
|
|
15
|
+
export const DB_PATH = join(homedir(), '.local', 'share', 'heyiam', 'sessions.db');
|
|
17
16
|
const CURRENT_SCHEMA_VERSION = 5;
|
|
18
17
|
// ── Singleton ────────────────────────────────────────────────
|
|
19
18
|
let _db = null;
|
package/dist/demo-seed.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Seeds a demo environment with fake data for marketing recordings.
|
|
3
3
|
*
|
|
4
|
-
* Creates a self-contained directory at ~/.
|
|
4
|
+
* Creates a self-contained directory at ~/.local/share/heyiam/demo/ with:
|
|
5
5
|
* - sessions.db — SQLite database with fake sessions + FTS
|
|
6
6
|
* - enhanced/ — fake enhanced data for select sessions
|
|
7
7
|
* - project-enhance/ — cached project narrative
|
|
8
8
|
* - settings.json — onboarding complete, fake API key
|
|
9
9
|
* - sessions/ — minimal JSONL session files
|
|
10
10
|
*
|
|
11
|
-
* The real ~/.
|
|
11
|
+
* The real ~/.local/share/heyiam/ is never touched.
|
|
12
12
|
*/
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { homedir } from 'node:os';
|
|
@@ -16,7 +16,7 @@ import { mkdirSync, writeFileSync, existsSync, rmSync } from 'node:fs';
|
|
|
16
16
|
import { createHash } from 'node:crypto';
|
|
17
17
|
import { openDatabase } from './db.js';
|
|
18
18
|
import { DEMO_PROJECTS, DEMO_SESSIONS, DEMO_TRANSCRIPT, DEMO_ENHANCE_RESULT, } from './demo-data.js';
|
|
19
|
-
const DEMO_DIR = join(homedir(), '.
|
|
19
|
+
const DEMO_DIR = join(homedir(), '.local', 'share', 'heyiam', 'demo');
|
|
20
20
|
/**
|
|
21
21
|
* Seed the demo environment. Returns the path so the caller can set
|
|
22
22
|
* HEYIAM_CONFIG_DIR before starting the server.
|
package/dist/export.js
CHANGED
|
@@ -90,14 +90,14 @@ function writeAndTrack(filePath, content, files) {
|
|
|
90
90
|
return statSync(filePath).size;
|
|
91
91
|
}
|
|
92
92
|
// ── Markdown Export ────────────────────────────────────────────
|
|
93
|
-
export async function exportMarkdown(dirName, cache, sessions, outputPath) {
|
|
93
|
+
export async function exportMarkdown(dirName, cache, sessions, outputPath, opts) {
|
|
94
94
|
const files = [];
|
|
95
95
|
let totalBytes = 0;
|
|
96
96
|
mkdirSync(outputPath, { recursive: true });
|
|
97
97
|
const { result } = cache;
|
|
98
98
|
const title = cache.title ?? displayNameFromDir(dirName);
|
|
99
99
|
// README.md — project narrative
|
|
100
|
-
const readme = buildReadme(title, result, sessions);
|
|
100
|
+
const readme = buildReadme(title, result, sessions, opts?.totalFilesChanged);
|
|
101
101
|
totalBytes += writeAndTrack(join(outputPath, 'README.md'), readme, files);
|
|
102
102
|
// sessions/*.md — per-session breakdowns
|
|
103
103
|
const sessionsDir = join(outputPath, 'sessions');
|
|
@@ -113,7 +113,7 @@ export async function exportMarkdown(dirName, cache, sessions, outputPath) {
|
|
|
113
113
|
totalBytes += writeAndTrack(join(outputPath, 'project.json'), projectJson, files);
|
|
114
114
|
return { files, totalBytes, outputPath };
|
|
115
115
|
}
|
|
116
|
-
function buildReadme(title, result, sessions) {
|
|
116
|
+
function buildReadme(title, result, sessions, totalFilesChanged) {
|
|
117
117
|
const lines = [];
|
|
118
118
|
lines.push(`# ${title}\n`);
|
|
119
119
|
lines.push(result.narrative);
|
|
@@ -146,7 +146,7 @@ function buildReadme(title, result, sessions) {
|
|
|
146
146
|
lines.push(`- Sessions: ${sessions.length}`);
|
|
147
147
|
const totalLoc = sessions.reduce((sum, s) => sum + s.linesOfCode, 0);
|
|
148
148
|
const totalMin = computeMergedSessionDuration(sessions);
|
|
149
|
-
const totalFiles = sessions.
|
|
149
|
+
const totalFiles = totalFilesChanged ?? new Set(sessions.flatMap(s => s.filesChanged.map(f => f.path))).size;
|
|
150
150
|
lines.push(`- Lines of code: ${totalLoc.toLocaleString()}`);
|
|
151
151
|
lines.push(`- Total time: ${(totalMin / 60).toFixed(1)}h`);
|
|
152
152
|
lines.push(`- Files changed: ${totalFiles}`);
|
|
@@ -223,7 +223,7 @@ export async function exportHtml(dirName, cache, sessions, outputPath, username
|
|
|
223
223
|
// Compute stats the same way the dashboard does
|
|
224
224
|
const totalLoc = sessions.reduce((sum, s) => sum + s.linesOfCode, 0);
|
|
225
225
|
const totalDurationMinutes = computeMergedSessionDuration(sessions);
|
|
226
|
-
const totalFilesChanged = opts?.totalFilesChanged ?? sessions.
|
|
226
|
+
const totalFilesChanged = opts?.totalFilesChanged ?? new Set(sessions.flatMap(s => s.filesChanged.map(f => f.path))).size;
|
|
227
227
|
// Agent duration: sum child durations across all orchestrated sessions
|
|
228
228
|
const totalAgentMinutes = sessions
|
|
229
229
|
.filter((s) => s.isOrchestrated && s.children)
|
|
@@ -317,7 +317,7 @@ function buildProjectRenderInputs(dirName, cache, sessions, username, opts) {
|
|
|
317
317
|
}));
|
|
318
318
|
const totalLoc = sessions.reduce((sum, s) => sum + s.linesOfCode, 0);
|
|
319
319
|
const totalDurationMinutes = computeMergedSessionDuration(sessions);
|
|
320
|
-
const totalFilesChanged = opts?.totalFilesChanged ?? sessions.
|
|
320
|
+
const totalFilesChanged = opts?.totalFilesChanged ?? new Set(sessions.flatMap(s => s.filesChanged.map(f => f.path))).size;
|
|
321
321
|
const totalAgentMinutes = sessions
|
|
322
322
|
.filter((s) => s.isOrchestrated && s.children)
|
|
323
323
|
.reduce((sum, s) => sum + s.children.reduce((cs, c) => cs + c.durationMinutes, 0), 0);
|
package/dist/index.js
CHANGED
|
@@ -435,7 +435,7 @@ program
|
|
|
435
435
|
const { existsSync, readFileSync } = await import('node:fs');
|
|
436
436
|
const { join } = await import('node:path');
|
|
437
437
|
const { homedir } = await import('node:os');
|
|
438
|
-
const pidFile = join(homedir(), '.
|
|
438
|
+
const pidFile = join(homedir(), '.local', 'share', 'heyiam', 'daemon', 'daemon.pid');
|
|
439
439
|
let daemonRunning = false;
|
|
440
440
|
if (existsSync(pidFile)) {
|
|
441
441
|
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
@@ -446,7 +446,7 @@ program
|
|
|
446
446
|
catch { /* not running */ }
|
|
447
447
|
}
|
|
448
448
|
// Status file
|
|
449
|
-
const statusFile = join(homedir(), '.
|
|
449
|
+
const statusFile = join(homedir(), '.local', 'share', 'heyiam', 'daemon', 'status.json');
|
|
450
450
|
let lastSync = 'never';
|
|
451
451
|
if (existsSync(statusFile)) {
|
|
452
452
|
try {
|
|
@@ -489,7 +489,7 @@ daemon
|
|
|
489
489
|
const { homedir } = await import('node:os');
|
|
490
490
|
const { spawn } = await import('node:child_process');
|
|
491
491
|
const { writeFileSync, mkdirSync } = await import('node:fs');
|
|
492
|
-
const daemonDir = join(homedir(), '.
|
|
492
|
+
const daemonDir = join(homedir(), '.local', 'share', 'heyiam', 'daemon');
|
|
493
493
|
const binaryPath = join(daemonDir, 'heyiam-tray');
|
|
494
494
|
const pidFile = join(daemonDir, 'daemon.pid');
|
|
495
495
|
if (!existsSync(binaryPath)) {
|
|
@@ -522,7 +522,7 @@ daemon
|
|
|
522
522
|
const { existsSync, readFileSync, unlinkSync } = await import('node:fs');
|
|
523
523
|
const { join } = await import('node:path');
|
|
524
524
|
const { homedir } = await import('node:os');
|
|
525
|
-
const pidFile = join(homedir(), '.
|
|
525
|
+
const pidFile = join(homedir(), '.local', 'share', 'heyiam', 'daemon', 'daemon.pid');
|
|
526
526
|
if (!existsSync(pidFile)) {
|
|
527
527
|
console.log('\n Daemon is not running.\n');
|
|
528
528
|
return;
|
|
@@ -545,7 +545,7 @@ daemon
|
|
|
545
545
|
const { existsSync, readFileSync } = await import('node:fs');
|
|
546
546
|
const { join } = await import('node:path');
|
|
547
547
|
const { homedir } = await import('node:os');
|
|
548
|
-
const daemonDir = join(homedir(), '.
|
|
548
|
+
const daemonDir = join(homedir(), '.local', 'share', 'heyiam', 'daemon');
|
|
549
549
|
const pidFile = join(daemonDir, 'daemon.pid');
|
|
550
550
|
const statusFile = join(daemonDir, 'status.json');
|
|
551
551
|
const binaryPath = join(daemonDir, 'heyiam-tray');
|
|
@@ -629,7 +629,7 @@ daemon
|
|
|
629
629
|
const { join } = await import('node:path');
|
|
630
630
|
const { homedir } = await import('node:os');
|
|
631
631
|
// Stop first
|
|
632
|
-
const pidFile = join(homedir(), '.
|
|
632
|
+
const pidFile = join(homedir(), '.local', 'share', 'heyiam', 'daemon', 'daemon.pid');
|
|
633
633
|
if (existsSync(pidFile)) {
|
|
634
634
|
const pid = parseInt((await import('node:fs')).readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
635
635
|
try {
|
|
@@ -639,7 +639,7 @@ daemon
|
|
|
639
639
|
unlinkSync(pidFile);
|
|
640
640
|
}
|
|
641
641
|
// Remove binary
|
|
642
|
-
const binaryPath = join(homedir(), '.
|
|
642
|
+
const binaryPath = join(homedir(), '.local', 'share', 'heyiam', 'daemon', 'heyiam-tray');
|
|
643
643
|
if (existsSync(binaryPath))
|
|
644
644
|
unlinkSync(binaryPath);
|
|
645
645
|
// Remove auto-start registration (macOS launchd, Linux XDG)
|
package/dist/routes/context.js
CHANGED
|
@@ -212,7 +212,7 @@ export function createRouteContext(sessionsBasePath, dbPath) {
|
|
|
212
212
|
if (!basePath) {
|
|
213
213
|
const archiveResult = await archiveSessionFiles(allSessions);
|
|
214
214
|
if (archiveResult.archived > 0) {
|
|
215
|
-
console.log(`Preserved ${archiveResult.archived} sessions → ~/.
|
|
215
|
+
console.log(`Preserved ${archiveResult.archived} sessions → ~/.local/share/heyiam/sessions/`);
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
const byDir = new Map();
|
|
@@ -427,7 +427,7 @@ export function createRouteContext(sessionsBasePath, dbPath) {
|
|
|
427
427
|
const parentMetas = proj.sessions.filter(s => !s.isSubagent);
|
|
428
428
|
const allStats = await Promise.all(parentMetas.map((m) => getSessionStats(m, proj.name)));
|
|
429
429
|
const totalLoc = allStats.reduce((s, st) => s + st.loc, 0);
|
|
430
|
-
const totalFiles = allStats.reduce((s, st) => s + st.files, 0);
|
|
430
|
+
const totalFiles = db.prepare('SELECT COUNT(DISTINCT file_path) as c FROM session_files WHERE session_id IN (SELECT id FROM sessions WHERE project_dir = ?)').get(proj.dirName)?.c ?? allStats.reduce((s, st) => s + st.files, 0);
|
|
431
431
|
const naiveDuration = allStats.reduce((s, st) => s + st.duration, 0);
|
|
432
432
|
const totalDuration = computeMergedDurationFromDb(db, proj.dirName, naiveDuration);
|
|
433
433
|
let totalAgentDuration = totalDuration;
|
package/dist/routes/dashboard.js
CHANGED
|
@@ -15,7 +15,7 @@ export function createDashboardRouter(ctx) {
|
|
|
15
15
|
const sync = getSyncState();
|
|
16
16
|
// Count enhanced projects by checking the enhance cache directory
|
|
17
17
|
let enhancedCount = 0;
|
|
18
|
-
const enhanceDir = join(homedir(), '.
|
|
18
|
+
const enhanceDir = join(homedir(), '.local', 'share', 'heyiam', 'project-enhance');
|
|
19
19
|
try {
|
|
20
20
|
const files = readdirSync(enhanceDir).filter((f) => f.endsWith('.json'));
|
|
21
21
|
enhancedCount = files.length;
|
package/dist/routes/export.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from 'node:fs';
|
|
|
4
4
|
import { execFileSync } from 'node:child_process';
|
|
5
5
|
import { exportMarkdown, exportHtml, generateHtmlFiles, createZipBuffer } from '../export.js';
|
|
6
6
|
import { buildProjectDetail } from './context.js';
|
|
7
|
-
const EXPORTS_BASE = path.resolve(process.env.HOME || '~', '.
|
|
7
|
+
const EXPORTS_BASE = path.resolve(process.env.HOME || '~', '.local', 'share', 'heyiam', 'exports');
|
|
8
8
|
/** Validate that an output path is within the safe exports directory. */
|
|
9
9
|
function safeExportPath(outputPath, dirName, format) {
|
|
10
10
|
const defaultPath = path.join(EXPORTS_BASE, dirName, format);
|
|
@@ -71,8 +71,9 @@ export function createExportRouter(ctx) {
|
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
const cache = data.enhanceCache ?? buildFallbackCache(data.sessions);
|
|
74
|
+
const totalFilesChanged = data.project.totalFiles;
|
|
74
75
|
const outputPath = path.join(EXPORTS_BASE, dirName, 'markdown');
|
|
75
|
-
const result = await exportMarkdown(dirName, cache, data.sessions, outputPath);
|
|
76
|
+
const result = await exportMarkdown(dirName, cache, data.sessions, outputPath, { totalFilesChanged });
|
|
76
77
|
res.json(result);
|
|
77
78
|
}
|
|
78
79
|
catch (err) {
|
|
@@ -90,8 +91,9 @@ export function createExportRouter(ctx) {
|
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
92
93
|
const cache = data.enhanceCache ?? buildFallbackCache(data.sessions);
|
|
94
|
+
const totalFilesChanged = data.project.totalFiles;
|
|
93
95
|
const outDir = safeExportPath(outputPath, dirName, 'markdown');
|
|
94
|
-
const result = await exportMarkdown(dirName, cache, data.sessions, outDir);
|
|
96
|
+
const result = await exportMarkdown(dirName, cache, data.sessions, outDir, { totalFilesChanged });
|
|
95
97
|
res.json(result);
|
|
96
98
|
}
|
|
97
99
|
catch (err) {
|
|
@@ -153,9 +155,10 @@ export function createExportRouter(ctx) {
|
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
157
|
const cache = data.enhanceCache ?? buildFallbackCache(data.sessions);
|
|
158
|
+
const totalFilesChanged = data.project.totalFiles;
|
|
156
159
|
// Re-use exportMarkdown to a temp dir, then zip the result
|
|
157
160
|
const tmpDir = path.join(EXPORTS_BASE, '.tmp', `${dirName}-${Date.now()}`);
|
|
158
|
-
const result = await exportMarkdown(dirName, cache, data.sessions, tmpDir);
|
|
161
|
+
const result = await exportMarkdown(dirName, cache, data.sessions, tmpDir, { totalFilesChanged });
|
|
159
162
|
// Read files into memory and zip
|
|
160
163
|
const entries = result.files.map((filePath) => ({
|
|
161
164
|
path: path.relative(tmpDir, filePath),
|
package/dist/screenshot.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { homedir, platform } from 'node:os';
|
|
5
5
|
import { get as httpGet } from 'node:http';
|
|
6
|
-
export const SCREENSHOTS_DIR = join(homedir(), '.
|
|
6
|
+
export const SCREENSHOTS_DIR = join(homedir(), '.local', 'share', 'heyiam', 'screenshots');
|
|
7
7
|
/** Known Chrome binary paths by platform */
|
|
8
8
|
const CHROME_PATHS = {
|
|
9
9
|
darwin: [
|
package/dist/settings.js
CHANGED
|
@@ -6,12 +6,16 @@ import { readConfig, writeConfig } from './auth.js';
|
|
|
6
6
|
function getConfigDir() {
|
|
7
7
|
return process.env.HEYIAM_CONFIG_DIR || join(homedir(), '.config', 'heyiam');
|
|
8
8
|
}
|
|
9
|
+
/** XDG data directory — DB, enhanced data, archives, screenshots, published state. */
|
|
10
|
+
export function getDataDir() {
|
|
11
|
+
return process.env.HEYIAM_DATA_DIR || join(homedir(), '.local', 'share', 'heyiam');
|
|
12
|
+
}
|
|
9
13
|
const ENHANCED_DIR = 'enhanced';
|
|
10
14
|
const PROJECT_ENHANCE_DIR = 'project-enhance';
|
|
11
15
|
const SETTINGS_FILE = 'settings.json';
|
|
12
16
|
const SESSIONS_DIR = 'sessions';
|
|
13
17
|
/** Directory where archived session hard links are stored. */
|
|
14
|
-
export function getArchiveDir(configDir =
|
|
18
|
+
export function getArchiveDir(configDir = getDataDir()) {
|
|
15
19
|
return join(configDir, SESSIONS_DIR);
|
|
16
20
|
}
|
|
17
21
|
export function isArchiveEnabled(configDir) {
|
|
@@ -50,10 +54,10 @@ export function resetOnboarding(configDir) {
|
|
|
50
54
|
export function getAnthropicApiKey(configDir) {
|
|
51
55
|
return process.env.ANTHROPIC_API_KEY || getSettings(configDir).anthropicApiKey || undefined;
|
|
52
56
|
}
|
|
53
|
-
function enhancedDir(configDir =
|
|
57
|
+
function enhancedDir(configDir = getDataDir()) {
|
|
54
58
|
return join(configDir, ENHANCED_DIR);
|
|
55
59
|
}
|
|
56
|
-
function enhancedPath(sessionId, configDir =
|
|
60
|
+
function enhancedPath(sessionId, configDir = getDataDir()) {
|
|
57
61
|
return join(enhancedDir(configDir), `${sessionId}.json`);
|
|
58
62
|
}
|
|
59
63
|
export function saveEnhancedData(sessionId, data, configDir) {
|
|
@@ -103,10 +107,10 @@ export function buildProjectFingerprint(selectedSessionIds, configDir) {
|
|
|
103
107
|
});
|
|
104
108
|
return createHash('sha256').update(parts.join('|')).digest('hex').slice(0, 16);
|
|
105
109
|
}
|
|
106
|
-
function projectEnhanceDir(configDir =
|
|
110
|
+
function projectEnhanceDir(configDir = getDataDir()) {
|
|
107
111
|
return join(configDir, PROJECT_ENHANCE_DIR);
|
|
108
112
|
}
|
|
109
|
-
function projectEnhancePath(projectDirName, configDir =
|
|
113
|
+
function projectEnhancePath(projectDirName, configDir = getDataDir()) {
|
|
110
114
|
// Sanitize project dir name for filesystem
|
|
111
115
|
const safe = projectDirName.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
112
116
|
return join(projectEnhanceDir(configDir), `${safe}.json`);
|
|
@@ -157,10 +161,10 @@ export function deleteProjectEnhanceResult(projectDirName, configDir) {
|
|
|
157
161
|
unlinkSync(path);
|
|
158
162
|
}
|
|
159
163
|
const UPLOADED_DIR = 'published';
|
|
160
|
-
function uploadedDir(configDir =
|
|
164
|
+
function uploadedDir(configDir = getDataDir()) {
|
|
161
165
|
return join(configDir, UPLOADED_DIR);
|
|
162
166
|
}
|
|
163
|
-
function uploadedPath(projectDirName, configDir =
|
|
167
|
+
function uploadedPath(projectDirName, configDir = getDataDir()) {
|
|
164
168
|
const safe = projectDirName.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
165
169
|
return join(uploadedDir(configDir), `${safe}.json`);
|
|
166
170
|
}
|