@project-ava-supernova/core 0.2.71 → 0.2.72
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/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +138 -38
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/mode-tags.d.ts +72 -0
- package/dist/agent/mode-tags.d.ts.map +1 -0
- package/dist/agent/mode-tags.js +84 -0
- package/dist/agent/mode-tags.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +16 -2
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +133 -24
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/brainstorm/brainstorm-store.d.ts +42 -0
- package/dist/brainstorm/brainstorm-store.d.ts.map +1 -0
- package/dist/brainstorm/brainstorm-store.js +164 -0
- package/dist/brainstorm/brainstorm-store.js.map +1 -0
- package/dist/brainstorm/types.d.ts +64 -0
- package/dist/brainstorm/types.d.ts.map +1 -0
- package/dist/brainstorm/types.js +20 -0
- package/dist/brainstorm/types.js.map +1 -0
- package/dist/config/project.d.ts.map +1 -1
- package/dist/config/project.js +3 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/schema.d.ts +13 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/dataset/capture.d.ts.map +1 -1
- package/dist/dataset/capture.js +6 -14
- package/dist/dataset/capture.js.map +1 -1
- package/dist/history/conversation-title.d.ts +5 -4
- package/dist/history/conversation-title.d.ts.map +1 -1
- package/dist/history/conversation-title.js +6 -19
- package/dist/history/conversation-title.js.map +1 -1
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +41 -13
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +41 -13
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +38 -10
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +41 -13
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +41 -13
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +41 -13
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +41 -13
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/id.d.ts.map +1 -1
- package/dist/i18n/locales/id.js +41 -13
- package/dist/i18n/locales/id.js.map +1 -1
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +41 -13
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +41 -13
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/ko.d.ts.map +1 -1
- package/dist/i18n/locales/ko.js +41 -13
- package/dist/i18n/locales/ko.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +41 -13
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +41 -13
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +41 -13
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +41 -13
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/th.d.ts.map +1 -1
- package/dist/i18n/locales/th.js +41 -13
- package/dist/i18n/locales/th.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +41 -13
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/uk.d.ts.map +1 -1
- package/dist/i18n/locales/uk.js +41 -13
- package/dist/i18n/locales/uk.js.map +1 -1
- package/dist/i18n/locales/vi.d.ts.map +1 -1
- package/dist/i18n/locales/vi.js +41 -13
- package/dist/i18n/locales/vi.js.map +1 -1
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.js +41 -13
- package/dist/i18n/locales/zh-CN.js.map +1 -1
- package/dist/i18n/locales/zh-TW.d.ts.map +1 -1
- package/dist/i18n/locales/zh-TW.js +41 -13
- package/dist/i18n/locales/zh-TW.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/journal/journal-manager.d.ts +22 -1
- package/dist/journal/journal-manager.d.ts.map +1 -1
- package/dist/journal/journal-manager.js +47 -2
- package/dist/journal/journal-manager.js.map +1 -1
- package/dist/personas/conductor.d.ts +11 -0
- package/dist/personas/conductor.d.ts.map +1 -1
- package/dist/personas/conductor.js +56 -12
- package/dist/personas/conductor.js.map +1 -1
- package/dist/personas/definitions.d.ts +15 -4
- package/dist/personas/definitions.d.ts.map +1 -1
- package/dist/personas/definitions.js +184 -19
- package/dist/personas/definitions.js.map +1 -1
- package/dist/personas/types.d.ts +1 -1
- package/dist/personas/types.d.ts.map +1 -1
- package/dist/projects/project-data.d.ts +73 -0
- package/dist/projects/project-data.d.ts.map +1 -0
- package/dist/projects/project-data.js +126 -0
- package/dist/projects/project-data.js.map +1 -0
- package/dist/projects/projects-home.d.ts +33 -0
- package/dist/projects/projects-home.d.ts.map +1 -0
- package/dist/projects/projects-home.js +43 -0
- package/dist/projects/projects-home.js.map +1 -0
- package/dist/projects/storage-categories.d.ts +45 -0
- package/dist/projects/storage-categories.d.ts.map +1 -0
- package/dist/projects/storage-categories.js +86 -0
- package/dist/projects/storage-categories.js.map +1 -0
- package/dist/tools/authoring/export-document.d.ts +45 -0
- package/dist/tools/authoring/export-document.d.ts.map +1 -0
- package/dist/tools/authoring/export-document.js +132 -0
- package/dist/tools/authoring/export-document.js.map +1 -0
- package/dist/tools/authoring/export-formats.d.ts +37 -0
- package/dist/tools/authoring/export-formats.d.ts.map +1 -0
- package/dist/tools/authoring/export-formats.js +50 -0
- package/dist/tools/authoring/export-formats.js.map +1 -0
- package/dist/tools/authoring/index.d.ts +6 -1
- package/dist/tools/authoring/index.d.ts.map +1 -1
- package/dist/tools/authoring/index.js +9 -0
- package/dist/tools/authoring/index.js.map +1 -1
- package/dist/tools/authoring/render-odf.d.ts +22 -0
- package/dist/tools/authoring/render-odf.d.ts.map +1 -0
- package/dist/tools/authoring/render-odf.js +604 -0
- package/dist/tools/authoring/render-odf.js.map +1 -0
- package/dist/tools/authoring/zip.d.ts +33 -0
- package/dist/tools/authoring/zip.d.ts.map +1 -0
- package/dist/tools/authoring/zip.js +125 -0
- package/dist/tools/authoring/zip.js.map +1 -0
- package/dist/tools/brainstorm-session.d.ts +29 -0
- package/dist/tools/brainstorm-session.d.ts.map +1 -0
- package/dist/tools/brainstorm-session.js +184 -0
- package/dist/tools/brainstorm-session.js.map +1 -0
- package/dist/tools/document-author.d.ts +1 -1
- package/dist/tools/document-author.d.ts.map +1 -1
- package/dist/tools/document-author.js +22 -5
- package/dist/tools/document-author.js.map +1 -1
- package/dist/tools/security.d.ts +25 -0
- package/dist/tools/security.d.ts.map +1 -1
- package/dist/tools/security.js +35 -0
- package/dist/tools/security.js.map +1 -1
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +4 -0
- package/dist/tools/tool-registry.js.map +1 -1
- package/dist/tools/verification-trust.d.ts +2 -2
- package/dist/tools/verification-trust.d.ts.map +1 -1
- package/dist/tools/verification-trust.js +11 -13
- package/dist/tools/verification-trust.js.map +1 -1
- package/dist/tools/write-video-post.d.ts.map +1 -1
- package/dist/tools/write-video-post.js +89 -13
- package/dist/tools/write-video-post.js.map +1 -1
- package/package.json +26 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where Ava's per-project data lives, and which project it belongs to.
|
|
3
|
+
*
|
|
4
|
+
* `~/.ava/projects/<hash>/` holds what Ava knows about a project — verification
|
|
5
|
+
* trust, brainstorm sessions — keyed by a hash of the project's path. Note what
|
|
6
|
+
* that is NOT: it is not where projects live. The user's code is wherever they
|
|
7
|
+
* made it. A row in the storage bar called "Projects" pointing here would say
|
|
8
|
+
* something false.
|
|
9
|
+
*
|
|
10
|
+
* Two things brought this module into being.
|
|
11
|
+
*
|
|
12
|
+
* The hash was implemented TWICE — `projectHash` in brainstorm-store.ts and
|
|
13
|
+
* `cwdHash` in verification-trust.ts — byte-identical and independently
|
|
14
|
+
* maintained. They agree today. If either drifted, the same project would
|
|
15
|
+
* silently split into two folders and Ava would lose her trust history and her
|
|
16
|
+
* brainstorming for it, with nothing failing loudly enough to notice.
|
|
17
|
+
*
|
|
18
|
+
* And the hash is ONE-WAY. Nothing recorded which path produced it, so Ava
|
|
19
|
+
* could never answer "which projects do I know about?" — you could only ask
|
|
20
|
+
* about a project you already had in your hand. `project.json` fixes that: the
|
|
21
|
+
* directory now says what it belongs to.
|
|
22
|
+
*/
|
|
23
|
+
import { projectsHomeFrom, DEFAULT_PROJECTS_DIRNAME } from './projects-home.js';
|
|
24
|
+
export { projectsHomeFrom, DEFAULT_PROJECTS_DIRNAME };
|
|
25
|
+
/** Ava's data root. */
|
|
26
|
+
export declare function avaHome(): string;
|
|
27
|
+
/**
|
|
28
|
+
* The folder new projects are created in.
|
|
29
|
+
*
|
|
30
|
+
* `~/Ava Projects` unless the user has pointed `preferences.projectsHome`
|
|
31
|
+
* somewhere else. Visible on purpose, and deliberately NOT under `~/.ava` —
|
|
32
|
+
* that is application data and it is hidden; source code in a dotfolder gets
|
|
33
|
+
* lost and gets skipped by backup tools.
|
|
34
|
+
*
|
|
35
|
+
* Resolved here rather than in each surface so the IDE, the extension and the
|
|
36
|
+
* CLI cannot disagree about where a project went. That is the mistake this
|
|
37
|
+
* module already exists to correct once.
|
|
38
|
+
*/
|
|
39
|
+
export declare function projectsHome(configured?: string | null): string;
|
|
40
|
+
/**
|
|
41
|
+
* Stable id for a project path.
|
|
42
|
+
*
|
|
43
|
+
* Canonicalised first so a trailing slash or Windows drive-letter casing
|
|
44
|
+
* cannot produce separate buckets for one project.
|
|
45
|
+
*/
|
|
46
|
+
export declare function projectHash(projectPath: string): string;
|
|
47
|
+
/** Directory holding Ava's data for one project. Does not create it. */
|
|
48
|
+
export declare function projectDataDir(projectPath: string, globalDir?: string): string;
|
|
49
|
+
/** What `project.json` records — the path the hash was made from. */
|
|
50
|
+
export interface ProjectRecord {
|
|
51
|
+
version: 1;
|
|
52
|
+
/** Absolute path, as resolved when first seen. */
|
|
53
|
+
path: string;
|
|
54
|
+
firstSeenAt: string;
|
|
55
|
+
lastSeenAt: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Ensure the project's data directory exists and knows which project it is.
|
|
59
|
+
*
|
|
60
|
+
* Called by anything about to write per-project data. Cheap and idempotent:
|
|
61
|
+
* an existing record only has its `lastSeenAt` refreshed, so a project that
|
|
62
|
+
* moved keeps its original first-seen date rather than looking new.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ensureProjectData(projectPath: string, globalDir?: string): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Every project Ava has data for, newest-seen first.
|
|
67
|
+
*
|
|
68
|
+
* Skips directories with no `project.json` — those predate this record and
|
|
69
|
+
* their path is genuinely unrecoverable, the hash being one-way. They are not
|
|
70
|
+
* an error; they are simply not listable.
|
|
71
|
+
*/
|
|
72
|
+
export declare function listKnownProjects(globalDir?: string): Promise<ProjectRecord[]>;
|
|
73
|
+
//# sourceMappingURL=project-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-data.d.ts","sourceRoot":"","sources":["../../src/projects/project-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,CAAC;AAEtD,uBAAuB;AACvB,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBhG;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAoBpF"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where Ava's per-project data lives, and which project it belongs to.
|
|
3
|
+
*
|
|
4
|
+
* `~/.ava/projects/<hash>/` holds what Ava knows about a project — verification
|
|
5
|
+
* trust, brainstorm sessions — keyed by a hash of the project's path. Note what
|
|
6
|
+
* that is NOT: it is not where projects live. The user's code is wherever they
|
|
7
|
+
* made it. A row in the storage bar called "Projects" pointing here would say
|
|
8
|
+
* something false.
|
|
9
|
+
*
|
|
10
|
+
* Two things brought this module into being.
|
|
11
|
+
*
|
|
12
|
+
* The hash was implemented TWICE — `projectHash` in brainstorm-store.ts and
|
|
13
|
+
* `cwdHash` in verification-trust.ts — byte-identical and independently
|
|
14
|
+
* maintained. They agree today. If either drifted, the same project would
|
|
15
|
+
* silently split into two folders and Ava would lose her trust history and her
|
|
16
|
+
* brainstorming for it, with nothing failing loudly enough to notice.
|
|
17
|
+
*
|
|
18
|
+
* And the hash is ONE-WAY. Nothing recorded which path produced it, so Ava
|
|
19
|
+
* could never answer "which projects do I know about?" — you could only ask
|
|
20
|
+
* about a project you already had in your hand. `project.json` fixes that: the
|
|
21
|
+
* directory now says what it belongs to.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { join, resolve } from 'node:path';
|
|
26
|
+
import { mkdir, readFile, writeFile, readdir } from 'node:fs/promises';
|
|
27
|
+
// The path rule itself lives in a dependency-free leaf, because the IDE
|
|
28
|
+
// renderer needs the same answer and cannot import node:fs.
|
|
29
|
+
import { projectsHomeFrom, DEFAULT_PROJECTS_DIRNAME } from './projects-home.js';
|
|
30
|
+
export { projectsHomeFrom, DEFAULT_PROJECTS_DIRNAME };
|
|
31
|
+
/** Ava's data root. */
|
|
32
|
+
export function avaHome() {
|
|
33
|
+
return join(homedir(), '.ava');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The folder new projects are created in.
|
|
37
|
+
*
|
|
38
|
+
* `~/Ava Projects` unless the user has pointed `preferences.projectsHome`
|
|
39
|
+
* somewhere else. Visible on purpose, and deliberately NOT under `~/.ava` —
|
|
40
|
+
* that is application data and it is hidden; source code in a dotfolder gets
|
|
41
|
+
* lost and gets skipped by backup tools.
|
|
42
|
+
*
|
|
43
|
+
* Resolved here rather than in each surface so the IDE, the extension and the
|
|
44
|
+
* CLI cannot disagree about where a project went. That is the mistake this
|
|
45
|
+
* module already exists to correct once.
|
|
46
|
+
*/
|
|
47
|
+
export function projectsHome(configured) {
|
|
48
|
+
return projectsHomeFrom(homedir(), configured);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Stable id for a project path.
|
|
52
|
+
*
|
|
53
|
+
* Canonicalised first so a trailing slash or Windows drive-letter casing
|
|
54
|
+
* cannot produce separate buckets for one project.
|
|
55
|
+
*/
|
|
56
|
+
export function projectHash(projectPath) {
|
|
57
|
+
const canonical = resolve(projectPath).replace(/[\\/]+$/, '').toLowerCase();
|
|
58
|
+
return createHash('sha256').update(canonical).digest('hex').slice(0, 16);
|
|
59
|
+
}
|
|
60
|
+
/** Directory holding Ava's data for one project. Does not create it. */
|
|
61
|
+
export function projectDataDir(projectPath, globalDir) {
|
|
62
|
+
return join(globalDir ?? avaHome(), 'projects', projectHash(projectPath));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Ensure the project's data directory exists and knows which project it is.
|
|
66
|
+
*
|
|
67
|
+
* Called by anything about to write per-project data. Cheap and idempotent:
|
|
68
|
+
* an existing record only has its `lastSeenAt` refreshed, so a project that
|
|
69
|
+
* moved keeps its original first-seen date rather than looking new.
|
|
70
|
+
*/
|
|
71
|
+
export async function ensureProjectData(projectPath, globalDir) {
|
|
72
|
+
const dir = projectDataDir(projectPath, globalDir);
|
|
73
|
+
await mkdir(dir, { recursive: true });
|
|
74
|
+
const file = join(dir, 'project.json');
|
|
75
|
+
const now = new Date().toISOString();
|
|
76
|
+
let record = {
|
|
77
|
+
version: 1,
|
|
78
|
+
path: resolve(projectPath),
|
|
79
|
+
firstSeenAt: now,
|
|
80
|
+
lastSeenAt: now,
|
|
81
|
+
};
|
|
82
|
+
try {
|
|
83
|
+
const existing = JSON.parse(await readFile(file, 'utf8'));
|
|
84
|
+
if (existing?.firstSeenAt)
|
|
85
|
+
record = { ...record, firstSeenAt: existing.firstSeenAt };
|
|
86
|
+
}
|
|
87
|
+
catch { /* first time, or unreadable — rewrite it */ }
|
|
88
|
+
// Best-effort: failing to record the path must never stop the caller from
|
|
89
|
+
// doing the work it actually came here for.
|
|
90
|
+
try {
|
|
91
|
+
await writeFile(file, JSON.stringify(record, null, 2), 'utf8');
|
|
92
|
+
}
|
|
93
|
+
catch { /* ignore */ }
|
|
94
|
+
return dir;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Every project Ava has data for, newest-seen first.
|
|
98
|
+
*
|
|
99
|
+
* Skips directories with no `project.json` — those predate this record and
|
|
100
|
+
* their path is genuinely unrecoverable, the hash being one-way. They are not
|
|
101
|
+
* an error; they are simply not listable.
|
|
102
|
+
*/
|
|
103
|
+
export async function listKnownProjects(globalDir) {
|
|
104
|
+
const root = join(globalDir ?? avaHome(), 'projects');
|
|
105
|
+
let entries;
|
|
106
|
+
try {
|
|
107
|
+
entries = (await readdir(root, { withFileTypes: true }))
|
|
108
|
+
.filter((e) => e.isDirectory())
|
|
109
|
+
.map((e) => e.name);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
const records = [];
|
|
115
|
+
for (const hash of entries) {
|
|
116
|
+
try {
|
|
117
|
+
const raw = await readFile(join(root, hash, 'project.json'), 'utf8');
|
|
118
|
+
const rec = JSON.parse(raw);
|
|
119
|
+
if (rec?.path)
|
|
120
|
+
records.push(rec);
|
|
121
|
+
}
|
|
122
|
+
catch { /* pre-record directory, or unreadable */ }
|
|
123
|
+
}
|
|
124
|
+
return records.sort((a, b) => (b.lastSeenAt ?? '').localeCompare(a.lastSeenAt ?? ''));
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=project-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-data.js","sourceRoot":"","sources":["../../src/projects/project-data.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where new projects go — and nothing else.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free on purpose, like routing-modes.ts and the authoring format
|
|
5
|
+
* leaf. Four places need this answer and they do not share a runtime: core and
|
|
6
|
+
* the extension host are Node, the IDE renderer reaches the filesystem through
|
|
7
|
+
* Tauri, and the webviews have no filesystem at all. A file that imports
|
|
8
|
+
* nothing can be reached from all of them, so "where did Ava put my project?"
|
|
9
|
+
* has one answer instead of four that drift.
|
|
10
|
+
*
|
|
11
|
+
* The home directory is passed IN rather than read here, because that is the
|
|
12
|
+
* one thing each runtime discovers differently (`os.homedir()` in Node,
|
|
13
|
+
* `homeDir()` from Tauri in the renderer).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The default folder name, under the user's home directory.
|
|
17
|
+
*
|
|
18
|
+
* Visible on purpose, and deliberately NOT under `~/.ava`: that is application
|
|
19
|
+
* data and it is hidden. Source code in a dotfolder is a trap — people lose
|
|
20
|
+
* it, and backup tools routinely skip dotfolders.
|
|
21
|
+
*/
|
|
22
|
+
export declare const DEFAULT_PROJECTS_DIRNAME = "Ava Projects";
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the projects home.
|
|
25
|
+
*
|
|
26
|
+
* `configured` is `preferences.projectsHome` — an absolute path the user chose.
|
|
27
|
+
* Empty or unset means the default. A default, not a prison: developers have
|
|
28
|
+
* settled habits about `~/dev` or `D:\work`, and the point is to remove a
|
|
29
|
+
* decision from someone who does not yet have one, not to overrule someone
|
|
30
|
+
* who does.
|
|
31
|
+
*/
|
|
32
|
+
export declare function projectsHomeFrom(homeDir: string, configured?: string | null): string;
|
|
33
|
+
//# sourceMappingURL=projects-home.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects-home.d.ts","sourceRoot":"","sources":["../../src/projects/projects-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAQvD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAIpF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where new projects go — and nothing else.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free on purpose, like routing-modes.ts and the authoring format
|
|
5
|
+
* leaf. Four places need this answer and they do not share a runtime: core and
|
|
6
|
+
* the extension host are Node, the IDE renderer reaches the filesystem through
|
|
7
|
+
* Tauri, and the webviews have no filesystem at all. A file that imports
|
|
8
|
+
* nothing can be reached from all of them, so "where did Ava put my project?"
|
|
9
|
+
* has one answer instead of four that drift.
|
|
10
|
+
*
|
|
11
|
+
* The home directory is passed IN rather than read here, because that is the
|
|
12
|
+
* one thing each runtime discovers differently (`os.homedir()` in Node,
|
|
13
|
+
* `homeDir()` from Tauri in the renderer).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* The default folder name, under the user's home directory.
|
|
17
|
+
*
|
|
18
|
+
* Visible on purpose, and deliberately NOT under `~/.ava`: that is application
|
|
19
|
+
* data and it is hidden. Source code in a dotfolder is a trap — people lose
|
|
20
|
+
* it, and backup tools routinely skip dotfolders.
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_PROJECTS_DIRNAME = 'Ava Projects';
|
|
23
|
+
/** Join two path segments without caring which separator the platform uses. */
|
|
24
|
+
function joinPath(base, name) {
|
|
25
|
+
const sep = base.includes('\\') && !base.includes('/') ? '\\' : '/';
|
|
26
|
+
return base.replace(/[\\/]+$/, '') + sep + name;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the projects home.
|
|
30
|
+
*
|
|
31
|
+
* `configured` is `preferences.projectsHome` — an absolute path the user chose.
|
|
32
|
+
* Empty or unset means the default. A default, not a prison: developers have
|
|
33
|
+
* settled habits about `~/dev` or `D:\work`, and the point is to remove a
|
|
34
|
+
* decision from someone who does not yet have one, not to overrule someone
|
|
35
|
+
* who does.
|
|
36
|
+
*/
|
|
37
|
+
export function projectsHomeFrom(homeDir, configured) {
|
|
38
|
+
const trimmed = configured?.trim();
|
|
39
|
+
if (trimmed)
|
|
40
|
+
return trimmed.replace(/[\\/]+$/, '');
|
|
41
|
+
return joinPath(homeDir, DEFAULT_PROJECTS_DIRNAME);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=projects-home.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects-home.js","sourceRoot":"","sources":["../../src/projects/projects-home.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AAEvD,+EAA+E;AAC/E,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAY;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;AAClD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,UAA0B;IAC1E,MAAM,OAAO,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each thing in `~/.ava` counts as, and what the user is told it is.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free, and shared. The extension host and the IDE each carried
|
|
5
|
+
* their own copy of this map — same keys, same labels, same `categoryOf`,
|
|
6
|
+
* separately maintained. Adding one category to two files is how the two
|
|
7
|
+
* surfaces end up reporting a user's disk differently, which is a strange
|
|
8
|
+
* thing for a local-first product to do.
|
|
9
|
+
*
|
|
10
|
+
* The scanning itself stays per-surface: the host walks with `node:fs`, the
|
|
11
|
+
* IDE through Tauri. Only the rules live here.
|
|
12
|
+
*/
|
|
13
|
+
/** Which half of the bar a category belongs to. */
|
|
14
|
+
export type StorageFamily = 'ava' | 'projects';
|
|
15
|
+
export declare const CATEGORY_LABEL: Record<string, string>;
|
|
16
|
+
/** Stable display order; largest-first is applied after, this breaks ties. */
|
|
17
|
+
export declare const CATEGORY_ORDER: string[];
|
|
18
|
+
/** Map a top-level entry name in `~/.ava` to a storage category. */
|
|
19
|
+
export declare function categoryOf(name: string): string;
|
|
20
|
+
/** What the user's projects folder costs. Measured separately from `~/.ava`,
|
|
21
|
+
* because it is their work rather than Ava's footprint — and because it is
|
|
22
|
+
* expensive enough that it cannot be measured on every render. */
|
|
23
|
+
export interface ProjectsUsage {
|
|
24
|
+
/** The projects home this figure describes. */
|
|
25
|
+
path: string;
|
|
26
|
+
bytes: number;
|
|
27
|
+
/** ISO timestamp. Shown to the user, because a cached number that does not
|
|
28
|
+
* say how old it is invites being read as live. */
|
|
29
|
+
measuredAt: string;
|
|
30
|
+
/** How many project folders were counted, when known. */
|
|
31
|
+
projectCount?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Is a cached projects measurement worth reusing?
|
|
35
|
+
*
|
|
36
|
+
* A source tree is not a config folder — an Unreal project's `Intermediate`,
|
|
37
|
+
* `Binaries` and `DerivedDataCache` run to tens of gigabytes, and walking that
|
|
38
|
+
* on every page render would stall the UI every time. So the number is cached
|
|
39
|
+
* and shown with its age, and re-measured only on request or once it is stale.
|
|
40
|
+
*/
|
|
41
|
+
export declare const PROJECTS_USAGE_TTL_MS: number;
|
|
42
|
+
export declare function isUsageStale(usage: ProjectsUsage | null | undefined, now?: number): boolean;
|
|
43
|
+
/** "measured 2h ago" — deliberately coarse; the point is age, not precision. */
|
|
44
|
+
export declare function measuredAgo(usage: ProjectsUsage | null | undefined, now?: number): string | null;
|
|
45
|
+
//# sourceMappingURL=storage-categories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-categories.d.ts","sourceRoot":"","sources":["../../src/projects/storage-categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,UAAU,CAAC;AAE/C,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAcjD,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,cAAc,UAG1B,CAAC;AAEF,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW/C;AAED;;mEAEmE;AACnE,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;wDACoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,QAAqB,CAAC;AAExD,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,SAAa,GAAG,OAAO,CAI/F;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI,CAUpG"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each thing in `~/.ava` counts as, and what the user is told it is.
|
|
3
|
+
*
|
|
4
|
+
* Dependency-free, and shared. The extension host and the IDE each carried
|
|
5
|
+
* their own copy of this map — same keys, same labels, same `categoryOf`,
|
|
6
|
+
* separately maintained. Adding one category to two files is how the two
|
|
7
|
+
* surfaces end up reporting a user's disk differently, which is a strange
|
|
8
|
+
* thing for a local-first product to do.
|
|
9
|
+
*
|
|
10
|
+
* The scanning itself stays per-surface: the host walks with `node:fs`, the
|
|
11
|
+
* IDE through Tauri. Only the rules live here.
|
|
12
|
+
*/
|
|
13
|
+
export const CATEGORY_LABEL = {
|
|
14
|
+
models: 'Models',
|
|
15
|
+
runtime: 'Runtime',
|
|
16
|
+
creative: 'Creative',
|
|
17
|
+
memory: 'Memory',
|
|
18
|
+
journal: 'Journal',
|
|
19
|
+
datasets: 'Datasets',
|
|
20
|
+
// NOT "Projects". `~/.ava/projects/` holds what Ava knows ABOUT a project —
|
|
21
|
+
// trust state, brainstorm sessions — keyed by a hash of its path. The user's
|
|
22
|
+
// code is wherever they made it. A row called "Projects" reading 1 KB would
|
|
23
|
+
// say something false about where their work lives.
|
|
24
|
+
projects: 'Project data',
|
|
25
|
+
backups: 'Old backups',
|
|
26
|
+
other: 'Other',
|
|
27
|
+
};
|
|
28
|
+
/** Stable display order; largest-first is applied after, this breaks ties. */
|
|
29
|
+
export const CATEGORY_ORDER = [
|
|
30
|
+
'models', 'runtime', 'creative', 'memory', 'journal',
|
|
31
|
+
'datasets', 'projects', 'backups', 'other',
|
|
32
|
+
];
|
|
33
|
+
/** Map a top-level entry name in `~/.ava` to a storage category. */
|
|
34
|
+
export function categoryOf(name) {
|
|
35
|
+
const n = name.toLowerCase();
|
|
36
|
+
if (/backup/.test(n))
|
|
37
|
+
return 'backups';
|
|
38
|
+
if (n === 'models')
|
|
39
|
+
return 'models';
|
|
40
|
+
if (n === 'bin')
|
|
41
|
+
return 'runtime';
|
|
42
|
+
if (n === 'creative')
|
|
43
|
+
return 'creative';
|
|
44
|
+
if (n === 'memory' || n === 'memory.json' || n === 'memory.md' || n === 'embeddings' || n === 'graph.json')
|
|
45
|
+
return 'memory';
|
|
46
|
+
if (n === 'journal')
|
|
47
|
+
return 'journal';
|
|
48
|
+
if (n === 'datasets')
|
|
49
|
+
return 'datasets';
|
|
50
|
+
if (n === 'projects')
|
|
51
|
+
return 'projects';
|
|
52
|
+
return 'other';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Is a cached projects measurement worth reusing?
|
|
56
|
+
*
|
|
57
|
+
* A source tree is not a config folder — an Unreal project's `Intermediate`,
|
|
58
|
+
* `Binaries` and `DerivedDataCache` run to tens of gigabytes, and walking that
|
|
59
|
+
* on every page render would stall the UI every time. So the number is cached
|
|
60
|
+
* and shown with its age, and re-measured only on request or once it is stale.
|
|
61
|
+
*/
|
|
62
|
+
export const PROJECTS_USAGE_TTL_MS = 6 * 60 * 60 * 1000; // 6 hours
|
|
63
|
+
export function isUsageStale(usage, now = Date.now()) {
|
|
64
|
+
if (!usage?.measuredAt)
|
|
65
|
+
return true;
|
|
66
|
+
const at = Date.parse(usage.measuredAt);
|
|
67
|
+
return Number.isNaN(at) || now - at > PROJECTS_USAGE_TTL_MS;
|
|
68
|
+
}
|
|
69
|
+
/** "measured 2h ago" — deliberately coarse; the point is age, not precision. */
|
|
70
|
+
export function measuredAgo(usage, now = Date.now()) {
|
|
71
|
+
if (!usage?.measuredAt)
|
|
72
|
+
return null;
|
|
73
|
+
const at = Date.parse(usage.measuredAt);
|
|
74
|
+
if (Number.isNaN(at))
|
|
75
|
+
return null;
|
|
76
|
+
const mins = Math.max(0, Math.floor((now - at) / 60000));
|
|
77
|
+
if (mins < 1)
|
|
78
|
+
return 'just now';
|
|
79
|
+
if (mins < 60)
|
|
80
|
+
return `${mins}m ago`;
|
|
81
|
+
const hours = Math.floor(mins / 60);
|
|
82
|
+
if (hours < 24)
|
|
83
|
+
return `${hours}h ago`;
|
|
84
|
+
return `${Math.floor(hours / 24)}d ago`;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=storage-categories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-categories.js","sourceRoot":"","sources":["../../src/projects/storage-categories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export a stored document to a chosen format.
|
|
3
|
+
*
|
|
4
|
+
* The Library is where documents are kept, exported and opened, and both the
|
|
5
|
+
* extension and the IDE mount that same tab. This module is the shared body
|
|
6
|
+
* behind both mounts: one place that decides what can be exported, what the
|
|
7
|
+
* output is called, and what a failure says. Two hosts calling one function is
|
|
8
|
+
* the only version of "one feature, two mounts" that does not quietly drift.
|
|
9
|
+
*
|
|
10
|
+
* Only sources we can faithfully re-render are exportable. A `.docx` is not
|
|
11
|
+
* offered as an `.odt` here, because that is a conversion with fidelity loss
|
|
12
|
+
* dressed up as an export — the honest answer for an already-built file is
|
|
13
|
+
* Open or Reveal, not a second lossy copy of it.
|
|
14
|
+
*/
|
|
15
|
+
import { type RenderTarget } from './export-formats.js';
|
|
16
|
+
export interface ExportRequest {
|
|
17
|
+
/** Absolute path of the source document. */
|
|
18
|
+
sourcePath: string;
|
|
19
|
+
format: RenderTarget;
|
|
20
|
+
/** Absolute output path. Defaults to the source's name with a new extension. */
|
|
21
|
+
outPath?: string;
|
|
22
|
+
loadDocx?: () => Promise<unknown>;
|
|
23
|
+
loadPdf?: () => Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
export type ExportResult = {
|
|
26
|
+
ok: true;
|
|
27
|
+
path: string;
|
|
28
|
+
bytes: number;
|
|
29
|
+
} | {
|
|
30
|
+
ok: false;
|
|
31
|
+
error: string;
|
|
32
|
+
};
|
|
33
|
+
/** Where the export lands: beside its source, which is how `document_author
|
|
34
|
+
* build` already behaves, so an exported file stays in the Library. */
|
|
35
|
+
export declare function deriveExportPath(sourcePath: string, format: RenderTarget): string;
|
|
36
|
+
export declare function exportDocument(req: ExportRequest): Promise<ExportResult>;
|
|
37
|
+
/**
|
|
38
|
+
* RFC 4180 enough: quoted fields, doubled quotes, and — the case a
|
|
39
|
+
* split-on-newline parser gets wrong — newlines inside quoted fields.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseCsv(raw: string): {
|
|
42
|
+
headers: string[];
|
|
43
|
+
rows: string[][];
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=export-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-document.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/export-document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;wEACwE;AACxE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAOjF;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAoC9E;AAID;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,CA8B7E"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export a stored document to a chosen format.
|
|
3
|
+
*
|
|
4
|
+
* The Library is where documents are kept, exported and opened, and both the
|
|
5
|
+
* extension and the IDE mount that same tab. This module is the shared body
|
|
6
|
+
* behind both mounts: one place that decides what can be exported, what the
|
|
7
|
+
* output is called, and what a failure says. Two hosts calling one function is
|
|
8
|
+
* the only version of "one feature, two mounts" that does not quietly drift.
|
|
9
|
+
*
|
|
10
|
+
* Only sources we can faithfully re-render are exportable. A `.docx` is not
|
|
11
|
+
* offered as an `.odt` here, because that is a conversion with fidelity loss
|
|
12
|
+
* dressed up as an export — the honest answer for an already-built file is
|
|
13
|
+
* Open or Reveal, not a second lossy copy of it.
|
|
14
|
+
*/
|
|
15
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
16
|
+
import { basename, dirname, extname, join } from 'node:path';
|
|
17
|
+
import { textInline } from './doc-model.js';
|
|
18
|
+
import { parseMarkdown } from './md-parse.js';
|
|
19
|
+
import { renderDocument } from './index.js';
|
|
20
|
+
// The format question is answered in a dependency-free leaf, because the
|
|
21
|
+
// webviews need the same answer and cannot import this file.
|
|
22
|
+
import { canExport } from './export-formats.js';
|
|
23
|
+
/** Where the export lands: beside its source, which is how `document_author
|
|
24
|
+
* build` already behaves, so an exported file stays in the Library. */
|
|
25
|
+
export function deriveExportPath(sourcePath, format) {
|
|
26
|
+
const dir = dirname(sourcePath);
|
|
27
|
+
const stem = basename(sourcePath, extname(sourcePath));
|
|
28
|
+
// join, not string concatenation: on Windows the source arrives with
|
|
29
|
+
// backslashes and a hand-built '/' would hand back a mixed-separator path
|
|
30
|
+
// that every later comparison gets subtly wrong.
|
|
31
|
+
return join(dir, `${stem}.${format}`);
|
|
32
|
+
}
|
|
33
|
+
export async function exportDocument(req) {
|
|
34
|
+
const ext = extname(req.sourcePath).toLowerCase();
|
|
35
|
+
if (!canExport(req.sourcePath)) {
|
|
36
|
+
return { ok: false, error: `${ext || 'This file'} cannot be exported — it is already a built document. Open or reveal it instead.` };
|
|
37
|
+
}
|
|
38
|
+
let source;
|
|
39
|
+
try {
|
|
40
|
+
source = await readFile(req.sourcePath, 'utf8');
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
return { ok: false, error: `Could not read ${basename(req.sourcePath)}: ${e.message}` };
|
|
44
|
+
}
|
|
45
|
+
const model = ext === '.csv' ? csvToModel(source, basename(req.sourcePath, ext)) : parseMarkdown(source);
|
|
46
|
+
const opts = {
|
|
47
|
+
loadDocx: req.loadDocx,
|
|
48
|
+
loadPdf: req.loadPdf,
|
|
49
|
+
baseDir: dirname(req.sourcePath),
|
|
50
|
+
};
|
|
51
|
+
let rendered;
|
|
52
|
+
try {
|
|
53
|
+
rendered = await renderDocument(model, req.format, opts);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
return { ok: false, error: e.message };
|
|
57
|
+
}
|
|
58
|
+
const outPath = req.outPath ?? deriveExportPath(req.sourcePath, req.format);
|
|
59
|
+
const data = typeof rendered === 'string' ? Buffer.from(rendered, 'utf8') : rendered;
|
|
60
|
+
try {
|
|
61
|
+
await writeFile(outPath, data);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
return { ok: false, error: `Could not write ${basename(outPath)}: ${e.message}` };
|
|
65
|
+
}
|
|
66
|
+
return { ok: true, path: outPath, bytes: data.length };
|
|
67
|
+
}
|
|
68
|
+
// ── CSV ──────────────────────────────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* RFC 4180 enough: quoted fields, doubled quotes, and — the case a
|
|
71
|
+
* split-on-newline parser gets wrong — newlines inside quoted fields.
|
|
72
|
+
*/
|
|
73
|
+
export function parseCsv(raw) {
|
|
74
|
+
const rows = [];
|
|
75
|
+
let row = [];
|
|
76
|
+
let field = '';
|
|
77
|
+
let quoted = false;
|
|
78
|
+
let started = false;
|
|
79
|
+
const endField = () => { row.push(field); field = ''; started = false; };
|
|
80
|
+
const endRow = () => { endField(); rows.push(row); row = []; };
|
|
81
|
+
for (let i = 0; i < raw.length; i++) {
|
|
82
|
+
const ch = raw[i];
|
|
83
|
+
if (quoted) {
|
|
84
|
+
if (ch === '"' && raw[i + 1] === '"') {
|
|
85
|
+
field += '"';
|
|
86
|
+
i++;
|
|
87
|
+
}
|
|
88
|
+
else if (ch === '"')
|
|
89
|
+
quoted = false;
|
|
90
|
+
else
|
|
91
|
+
field += ch;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (ch === '"' && !started) {
|
|
95
|
+
quoted = true;
|
|
96
|
+
started = true;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (ch === ',') {
|
|
100
|
+
endField();
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (ch === '\r')
|
|
104
|
+
continue;
|
|
105
|
+
if (ch === '\n') {
|
|
106
|
+
endRow();
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
field += ch;
|
|
110
|
+
started = true;
|
|
111
|
+
}
|
|
112
|
+
// A trailing newline ends the last row; anything else means one is still open.
|
|
113
|
+
if (field !== '' || row.length > 0)
|
|
114
|
+
endRow();
|
|
115
|
+
const headers = rows.shift() ?? [];
|
|
116
|
+
return { headers, rows };
|
|
117
|
+
}
|
|
118
|
+
/** A CSV is a single table; wrapping it in a DocModel lets it reach every
|
|
119
|
+
* renderer, so the same file can leave as .ods, .docx or .pdf. */
|
|
120
|
+
function csvToModel(raw, title) {
|
|
121
|
+
const { headers, rows } = parseCsv(raw);
|
|
122
|
+
const cells = (values) => values.map((v) => textInline(v));
|
|
123
|
+
return {
|
|
124
|
+
meta: { title },
|
|
125
|
+
blocks: [{
|
|
126
|
+
type: 'table',
|
|
127
|
+
headers: cells(headers),
|
|
128
|
+
rows: rows.map(cells),
|
|
129
|
+
}],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=export-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-document.js","sourceRoot":"","sources":["../../../src/tools/authoring/export-document.ts"],"names":[],"mappings":"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"}
|