@parall/cli 1.34.0 → 1.35.0
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/commands/wiki.d.ts.map +1 -1
- package/dist/commands/wiki.js +38 -22
- package/dist/lib/wiki-frontmatter.d.ts +9 -0
- package/dist/lib/wiki-frontmatter.d.ts.map +1 -0
- package/dist/lib/wiki-frontmatter.js +64 -0
- package/dist/lib/wiki.d.ts +33 -15
- package/dist/lib/wiki.d.ts.map +1 -1
- package/dist/lib/wiki.js +436 -147
- package/package.json +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAy3BpD"}
|
package/dist/commands/wiki.js
CHANGED
|
@@ -33,10 +33,10 @@ export function registerWikiCommands(program) {
|
|
|
33
33
|
.command('sync')
|
|
34
34
|
.description('Sync wiki files to local workspace. First run downloads all files; subsequent runs pull updates.')
|
|
35
35
|
.argument('[wiki]', 'Wiki ID or slug (omit to sync all wikis)')
|
|
36
|
-
.action(async (
|
|
36
|
+
.action(async (wikiRef) => {
|
|
37
37
|
try {
|
|
38
38
|
const ctx = resolveCredentials();
|
|
39
|
-
const result = await syncAllMounts(ctx);
|
|
39
|
+
const result = await syncAllMounts(ctx, wikiRef);
|
|
40
40
|
for (const entry of result.synced) {
|
|
41
41
|
process.stderr.write(`wiki ${entry.slug} synced → ${entry.path}\n`);
|
|
42
42
|
}
|
|
@@ -55,22 +55,21 @@ export function registerWikiCommands(program) {
|
|
|
55
55
|
});
|
|
56
56
|
wiki
|
|
57
57
|
.command('status')
|
|
58
|
-
.description('Show local changes
|
|
58
|
+
.description('Show local changes and pending changesets.')
|
|
59
59
|
.argument('[wiki]', 'Wiki ID or slug (auto-resolves if org has one wiki)')
|
|
60
60
|
.action(async (wikiRef) => {
|
|
61
61
|
try {
|
|
62
62
|
const ctx = resolveCredentials();
|
|
63
63
|
const result = await getAfcsStatus(ctx, wikiRef);
|
|
64
64
|
process.stderr.write(`Wiki: ${result.wiki_name} (${result.wiki_slug})\n`);
|
|
65
|
-
process.stderr.write(`Mount: ${result.mount_path}\n`);
|
|
66
|
-
process.stderr.write(`Mode: ${result.mode}\n\n`);
|
|
65
|
+
process.stderr.write(`Mount: ${result.mount_path}\n\n`);
|
|
67
66
|
if (result.local_changes.length === 0) {
|
|
68
67
|
process.stderr.write('Local changes: none\n');
|
|
69
68
|
}
|
|
70
69
|
else {
|
|
71
70
|
process.stderr.write('Local changes:\n');
|
|
72
71
|
for (const file of result.local_changes) {
|
|
73
|
-
const s = file.
|
|
72
|
+
const s = file.action === 'create' ? 'A' : file.action === 'delete' ? 'D' : 'M';
|
|
74
73
|
process.stderr.write(` ${s} ${file.path} (+${file.additions} -${file.deletions})\n`);
|
|
75
74
|
}
|
|
76
75
|
}
|
|
@@ -87,11 +86,6 @@ export function registerWikiCommands(program) {
|
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
|
-
if (result.permissions) {
|
|
91
|
-
process.stderr.write('\nPermissions:\n');
|
|
92
|
-
process.stderr.write(` Read: ${result.permissions.readable_prefixes.join(', ')}\n`);
|
|
93
|
-
process.stderr.write(` Write: ${result.permissions.writable_prefixes.join(', ') || 'none'}\n`);
|
|
94
|
-
}
|
|
95
89
|
printJson(result);
|
|
96
90
|
}
|
|
97
91
|
catch (error) {
|
|
@@ -121,7 +115,7 @@ export function registerWikiCommands(program) {
|
|
|
121
115
|
});
|
|
122
116
|
wiki
|
|
123
117
|
.command('reset')
|
|
124
|
-
.description('Discard all local changes and restore files to the last synced state
|
|
118
|
+
.description('Discard all local changes and restore files to the last synced state.')
|
|
125
119
|
.argument('[wiki]', 'Wiki ID or slug (auto-resolves if org has one wiki)')
|
|
126
120
|
.action(async (wikiRef) => {
|
|
127
121
|
try {
|
|
@@ -134,6 +128,23 @@ export function registerWikiCommands(program) {
|
|
|
134
128
|
printError(error);
|
|
135
129
|
}
|
|
136
130
|
});
|
|
131
|
+
wiki
|
|
132
|
+
.command('access')
|
|
133
|
+
.description('Show your access level (read / maintain / admin) for a wiki path')
|
|
134
|
+
.argument('<path>', 'Path to check (e.g. docs/ops/)')
|
|
135
|
+
.argument('[wiki]', 'Wiki ID or slug (auto-resolves if org has one wiki)')
|
|
136
|
+
.action(async (targetPath, wikiRef) => {
|
|
137
|
+
try {
|
|
138
|
+
const ctx = resolveCredentials();
|
|
139
|
+
const { resolveWikiRefOrDefault } = await import('../lib/wiki.js');
|
|
140
|
+
const wiki = await resolveWikiRefOrDefault(ctx, wikiRef);
|
|
141
|
+
const result = await ctx.client.getWikiAccessStatus(ctx.orgId, wiki.id, targetPath);
|
|
142
|
+
printJson(result);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
printError(error);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
137
148
|
wiki
|
|
138
149
|
.command('request-access')
|
|
139
150
|
.description('Request read/write access to a locked wiki path. Creates an approval card for a maintainer.')
|
|
@@ -153,9 +164,9 @@ export function registerWikiCommands(program) {
|
|
|
153
164
|
});
|
|
154
165
|
wiki
|
|
155
166
|
.command('log')
|
|
156
|
-
.description(
|
|
167
|
+
.description("Show history. With a path: that file's commit history. Without: recent wiki operations.")
|
|
157
168
|
.argument('[wiki]', 'Wiki ID or slug (auto-resolves if org has one wiki)')
|
|
158
|
-
.argument('[path]', 'File path for per-file history')
|
|
169
|
+
.argument('[path]', 'File path for per-file commit history')
|
|
159
170
|
.action(async (wikiRef, filePath) => {
|
|
160
171
|
try {
|
|
161
172
|
const ctx = resolveCredentials();
|
|
@@ -166,7 +177,8 @@ export function registerWikiCommands(program) {
|
|
|
166
177
|
else {
|
|
167
178
|
for (const entry of result.entries) {
|
|
168
179
|
const pathSuffix = entry.path ? ` ${entry.path}` : '';
|
|
169
|
-
|
|
180
|
+
const who = entry.author_name ?? entry.actor_id ?? '';
|
|
181
|
+
process.stderr.write(`${entry.id.slice(0, 8)} ${entry.created_at} ${entry.action}${who ? ` (${who})` : ''}${pathSuffix}\n`);
|
|
170
182
|
}
|
|
171
183
|
}
|
|
172
184
|
printJson(result);
|
|
@@ -345,7 +357,7 @@ export function registerWikiCommands(program) {
|
|
|
345
357
|
// ---- Content browsing (search, query, outline, section) ----
|
|
346
358
|
wiki
|
|
347
359
|
.command('search')
|
|
348
|
-
.description('
|
|
360
|
+
.description('Keyword search over wiki sections. Searches your local workspace copy when synced; otherwise fetches from the server.')
|
|
349
361
|
.argument('<query>', 'Search query')
|
|
350
362
|
.argument('[wiki]', 'Wiki ID or slug')
|
|
351
363
|
.option('--path <path>', 'Restrict to a path prefix')
|
|
@@ -377,8 +389,8 @@ export function registerWikiCommands(program) {
|
|
|
377
389
|
});
|
|
378
390
|
wiki
|
|
379
391
|
.command('query')
|
|
380
|
-
.description('
|
|
381
|
-
.argument('<query>', '
|
|
392
|
+
.description('Heading-aware keyword search that also ranks whole documents. Same lexical scoring as `search` (not semantic), better for multi-word questions.')
|
|
393
|
+
.argument('<query>', 'Query keywords (multi-word supported)')
|
|
382
394
|
.argument('[wiki]', 'Wiki ID or slug')
|
|
383
395
|
.option('--path <path>', 'Restrict to a path prefix')
|
|
384
396
|
.option('--limit <n>', 'Max results (default 5)')
|
|
@@ -453,14 +465,18 @@ export function registerWikiCommands(program) {
|
|
|
453
465
|
});
|
|
454
466
|
wiki
|
|
455
467
|
.command('cat')
|
|
456
|
-
.description('
|
|
468
|
+
.description('Print a wiki file. Reads your local workspace copy when synced (includes your unproposed edits); falls back to the server.')
|
|
457
469
|
.argument('<path>', 'File path (e.g. docs/auth.md)')
|
|
458
470
|
.argument('[wiki]', 'Wiki ID or slug')
|
|
459
|
-
.
|
|
471
|
+
.option('--remote', 'Read the server version even when a local workspace copy exists')
|
|
472
|
+
.action(async (filePath, wikiRef, options) => {
|
|
460
473
|
try {
|
|
461
474
|
const ctx = resolveCredentials();
|
|
462
|
-
const result = await getWikiBlob(ctx, wikiRef, {
|
|
463
|
-
|
|
475
|
+
const result = await getWikiBlob(ctx, wikiRef, {
|
|
476
|
+
path: filePath,
|
|
477
|
+
remote: options.remote,
|
|
478
|
+
});
|
|
479
|
+
process.stderr.write(`${filePath} (${result.size} bytes, source: ${result.source})\n\n`);
|
|
464
480
|
process.stdout.write(result.content);
|
|
465
481
|
if (result.content && !result.content.endsWith('\n'))
|
|
466
482
|
process.stdout.write('\n');
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ParsedFrontMatter {
|
|
2
|
+
type?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
tags?: string[];
|
|
5
|
+
}
|
|
6
|
+
/** True when any OKF field was extracted. */
|
|
7
|
+
export declare function hasFrontMatter(fm: ParsedFrontMatter): boolean;
|
|
8
|
+
export declare function parseFrontMatter(lines: string[], frontMatterEnd: number): ParsedFrontMatter;
|
|
9
|
+
//# sourceMappingURL=wiki-frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-frontmatter.d.ts","sourceRoot":"","sources":["../../src/lib/wiki-frontmatter.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAE7D;AAQD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,iBAAiB,CAyB3F"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Frontmatter (OKF-inspired) parsing for wiki markdown files.
|
|
2
|
+
//
|
|
3
|
+
// This mirrors the Go implementation in server/pkg/markdown/section.go — keep
|
|
4
|
+
// the two behaviorally consistent. It lives in its own module (rather than
|
|
5
|
+
// growing the already-oversized wiki.ts) per the repo's file-size discipline.
|
|
6
|
+
import { load as loadYaml } from 'js-yaml';
|
|
7
|
+
/** True when any OKF field was extracted. */
|
|
8
|
+
export function hasFrontMatter(fm) {
|
|
9
|
+
return fm.type !== undefined || fm.description !== undefined || fm.tags !== undefined;
|
|
10
|
+
}
|
|
11
|
+
// parseFrontMatter extracts the optional OKF fields (type, description, tags)
|
|
12
|
+
// from the leading YAML frontmatter block. Permissive by design: only
|
|
13
|
+
// `---`-delimited YAML is parsed (a `+++` TOML block is detected for section
|
|
14
|
+
// boundaries by detectFrontMatterEnd but its fields are not extracted); any
|
|
15
|
+
// parse error / missing field / wrong-typed value degrades to undefined so a
|
|
16
|
+
// malformed field never discards a valid one.
|
|
17
|
+
export function parseFrontMatter(lines, frontMatterEnd) {
|
|
18
|
+
// frontMatterEnd is one past the closing fence; opening fence is line 0 and
|
|
19
|
+
// the closing fence is line frontMatterEnd-1, so a block needs >= 2 lines.
|
|
20
|
+
if (frontMatterEnd < 2 || lines.length === 0) {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
if (lines[0].trim() !== '---') {
|
|
24
|
+
return {}; // only YAML frontmatter carries OKF fields
|
|
25
|
+
}
|
|
26
|
+
const body = lines.slice(1, frontMatterEnd - 1).join('\n');
|
|
27
|
+
let raw;
|
|
28
|
+
try {
|
|
29
|
+
raw = loadYaml(body);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
const obj = raw;
|
|
38
|
+
return {
|
|
39
|
+
type: frontMatterString(obj.type),
|
|
40
|
+
description: frontMatterString(obj.description),
|
|
41
|
+
tags: frontMatterTags(obj.tags),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function frontMatterString(v) {
|
|
45
|
+
if (typeof v !== 'string') {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const s = v.trim();
|
|
49
|
+
return s === '' ? undefined : s;
|
|
50
|
+
}
|
|
51
|
+
function frontMatterTags(v) {
|
|
52
|
+
if (typeof v === 'string') {
|
|
53
|
+
const s = v.trim();
|
|
54
|
+
return s === '' ? undefined : [s];
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(v)) {
|
|
57
|
+
const out = v
|
|
58
|
+
.filter((e) => typeof e === 'string')
|
|
59
|
+
.map((e) => e.trim())
|
|
60
|
+
.filter((e) => e !== '');
|
|
61
|
+
return out.length > 0 ? out : undefined;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
package/dist/lib/wiki.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ParallClient, type Wiki, type WikiChangeset, type WikiDiff, type WikiDiffFile, type WikiTreeEntry } from '@parall/sdk';
|
|
2
|
+
export { type ParsedFrontMatter, parseFrontMatter } from './wiki-frontmatter.js';
|
|
2
3
|
export type ParallContext = {
|
|
3
4
|
client: ParallClient;
|
|
4
5
|
orgId: string;
|
|
@@ -26,6 +27,9 @@ export type WikiNodeSection = {
|
|
|
26
27
|
level: number;
|
|
27
28
|
start_line: number;
|
|
28
29
|
end_line: number;
|
|
30
|
+
type?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
tags?: string[];
|
|
29
33
|
};
|
|
30
34
|
export type WikiOutlineResult = {
|
|
31
35
|
wiki_id: string;
|
|
@@ -143,10 +147,12 @@ export declare function getWikiTree(ctx: ParallContext, wikiRef?: string, option
|
|
|
143
147
|
}>;
|
|
144
148
|
export declare function getWikiBlob(ctx: ParallContext, wikiRef: string | undefined, options: {
|
|
145
149
|
path: string;
|
|
150
|
+
remote?: boolean;
|
|
146
151
|
}): Promise<{
|
|
147
152
|
wiki: Wiki;
|
|
148
153
|
content: string;
|
|
149
154
|
size: number;
|
|
155
|
+
source: WikiContentSource;
|
|
150
156
|
}>;
|
|
151
157
|
export declare function getWikiOutline(ctx: ParallContext, wikiRef?: string, options?: {
|
|
152
158
|
ref?: string;
|
|
@@ -166,14 +172,11 @@ export type AfcsStatusResult = {
|
|
|
166
172
|
wiki_slug: string;
|
|
167
173
|
wiki_name: string;
|
|
168
174
|
mount_path: string;
|
|
169
|
-
mode: string;
|
|
170
175
|
default_ref: string;
|
|
171
176
|
/** Local workspace changes vs last-synced manifest. */
|
|
172
177
|
local_changes: WikiDiffFile[];
|
|
173
178
|
/** Pending changesets created by this agent. */
|
|
174
179
|
changesets: AfcsChangesetSummary[];
|
|
175
|
-
/** Permission summary — null if the API is not yet available. */
|
|
176
|
-
permissions: AfcsPermissionSummary | null;
|
|
177
180
|
};
|
|
178
181
|
export type AfcsChangesetSummary = {
|
|
179
182
|
id: string;
|
|
@@ -184,10 +187,6 @@ export type AfcsChangesetSummary = {
|
|
|
184
187
|
created_at: string;
|
|
185
188
|
updated_at: string;
|
|
186
189
|
};
|
|
187
|
-
export type AfcsPermissionSummary = {
|
|
188
|
-
readable_prefixes: string[];
|
|
189
|
-
writable_prefixes: string[];
|
|
190
|
-
};
|
|
191
190
|
export declare function getAfcsStatus(ctx: ParallContext, wikiRef?: string): Promise<AfcsStatusResult>;
|
|
192
191
|
export type AfcsDiffResult = {
|
|
193
192
|
wiki_id: string;
|
|
@@ -202,12 +201,15 @@ export declare function getAfcsDiff(ctx: ParallContext, wikiRef?: string): Promi
|
|
|
202
201
|
export declare function proposeWikiChangeset(ctx: ParallContext, wikiRef: string | undefined, options: WikiProposeOptions): Promise<WikiProposeResult>;
|
|
203
202
|
/**
|
|
204
203
|
* Discard all local changes and restore files to the last synced state.
|
|
205
|
-
*
|
|
204
|
+
* Restores from the local baseline object store (network only as a
|
|
205
|
+
* SHA-verified fallback for pre-objects mounts), so the workspace lands
|
|
206
|
+
* exactly on the manifest baseline — `wiki status` reports clean afterwards.
|
|
206
207
|
*/
|
|
207
208
|
export declare function resetWikiWorkspace(ctx: ParallContext, wikiRef?: string): Promise<{
|
|
208
209
|
wiki_id: string;
|
|
209
210
|
wiki_slug: string;
|
|
210
211
|
files_restored: number;
|
|
212
|
+
unrestorable_paths: string[];
|
|
211
213
|
}>;
|
|
212
214
|
export type AfcsChangesetsResult = {
|
|
213
215
|
wiki_id: string;
|
|
@@ -234,12 +236,14 @@ export type AfcsAccessRequestResult = {
|
|
|
234
236
|
};
|
|
235
237
|
export declare function requestWikiAccess(ctx: ParallContext, wikiRef: string | undefined, targetPath: string, reason?: string): Promise<AfcsAccessRequestResult>;
|
|
236
238
|
export type AfcsLogEntry = {
|
|
237
|
-
type: '
|
|
239
|
+
type: 'commit' | 'operation';
|
|
238
240
|
id: string;
|
|
239
241
|
path?: string;
|
|
240
242
|
action: string;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
+
/** Parall actor ID — operation entries only (git commits carry no Parall identity). */
|
|
244
|
+
actor_id?: string;
|
|
245
|
+
/** Git author display name — commit entries only. */
|
|
246
|
+
author_name?: string;
|
|
243
247
|
created_at: string;
|
|
244
248
|
};
|
|
245
249
|
export type AfcsLogResult = {
|
|
@@ -249,6 +253,10 @@ export type AfcsLogResult = {
|
|
|
249
253
|
path?: string;
|
|
250
254
|
entries: AfcsLogEntry[];
|
|
251
255
|
};
|
|
256
|
+
/**
|
|
257
|
+
* Wiki history. Without a path: recent wiki operations (audit log). With a
|
|
258
|
+
* path: that file's commit history from the default branch.
|
|
259
|
+
*/
|
|
252
260
|
export declare function getWikiLog(ctx: ParallContext, wikiRef?: string, filePath?: string): Promise<AfcsLogResult>;
|
|
253
261
|
export type SyncResult = {
|
|
254
262
|
/** True iff every wiki's per-path action ran without failure. Conflicts do
|
|
@@ -267,11 +275,13 @@ export type SyncResult = {
|
|
|
267
275
|
}[];
|
|
268
276
|
};
|
|
269
277
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
278
|
+
* Sync wiki workspaces via REST (manifest comparison + bulk download).
|
|
279
|
+
* Without `wikiRef`: every accessible wiki is synced and stale mount
|
|
280
|
+
* directories are pruned. With `wikiRef`: only that wiki is synced and
|
|
281
|
+
* pruning is skipped — other wikis' workspaces must survive a scoped sync.
|
|
272
282
|
* Mount path is determined client-side: {mountRoot}/{slug}/
|
|
273
283
|
*/
|
|
274
|
-
export declare function syncAllMounts(ctx: ParallContext): Promise<SyncResult>;
|
|
284
|
+
export declare function syncAllMounts(ctx: ParallContext, wikiRef?: string): Promise<SyncResult>;
|
|
275
285
|
/**
|
|
276
286
|
* Run {@link syncAllMounts} in a loop, sleeping `intervalSec` between
|
|
277
287
|
* iterations. Returns a `stop` callback to break the loop.
|
|
@@ -370,5 +380,13 @@ export declare function syncSingleWiki(ctx: ParallContext, wiki: import('@parall
|
|
|
370
380
|
*/
|
|
371
381
|
export declare function writeConflictMarker(mountRoot: string, sourcePath: string, suffix: string, content: Buffer): Promise<string>;
|
|
372
382
|
export declare function computeGitBlobSHA(content: Buffer): string;
|
|
373
|
-
|
|
383
|
+
/**
|
|
384
|
+
* Mirror of the server's text classifier (filetype.IsText): content-type
|
|
385
|
+
* magic sniff, valid UTF-8, and no NUL bytes — kept aligned so content the
|
|
386
|
+
* CLI accepts cannot bounce off the server's 422 USE_UPLOAD later. The
|
|
387
|
+
* shared fixture table (test/testdata/text-classifier-cases.json) is
|
|
388
|
+
* verified by both this implementation's tests and the Go package's tests.
|
|
389
|
+
*/
|
|
390
|
+
export declare function isWikiTextContent(content: Buffer): boolean;
|
|
391
|
+
export declare function detectFrontMatterEnd(lines: string[]): number;
|
|
374
392
|
//# sourceMappingURL=wiki.d.ts.map
|
package/dist/lib/wiki.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/lib/wiki.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../../src/lib/wiki.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/wiki.js
CHANGED
|
@@ -2,17 +2,28 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { ApiError, } from '@parall/sdk';
|
|
5
|
+
import { structuredPatch } from 'diff';
|
|
6
|
+
import { hasFrontMatter, parseFrontMatter } from './wiki-frontmatter.js';
|
|
7
|
+
// Re-exported so consumers (and tests) can reach the frontmatter parser via the
|
|
8
|
+
// wiki module surface alongside detectFrontMatterEnd.
|
|
9
|
+
export { parseFrontMatter } from './wiki-frontmatter.js';
|
|
5
10
|
// ---------------------------------------------------------------------------
|
|
6
11
|
// Constants
|
|
7
12
|
// ---------------------------------------------------------------------------
|
|
8
13
|
const MARKDOWN_HEADING_RE = /^\s{0,3}(#{1,6})[ \t]+(.+?)\s*$/;
|
|
9
14
|
const TRAILING_FENCE_RE = /\s+#+\s*$/;
|
|
10
|
-
|
|
15
|
+
// Bumped 2 → 3 for the frontmatter (type/description/tags) fields: invalidates
|
|
16
|
+
// caches built before frontmatter parsing so existing local mounts re-parse and
|
|
17
|
+
// pick up the metadata even when a file's size / mtime is unchanged.
|
|
18
|
+
const LOCAL_NODE_SECTION_ARTIFACT_VERSION = 3;
|
|
11
19
|
const LOCAL_MANIFEST_FILE = 'manifest.json';
|
|
12
20
|
const PRLL_WIKI_DIR = '.parall-wiki';
|
|
13
21
|
const CONFLICTS_DIR = 'conflicts';
|
|
22
|
+
const OBJECTS_DIR = 'objects';
|
|
14
23
|
const REMOTE_CONFLICT_SUFFIX = '.remote';
|
|
15
24
|
const REMOTE_DELETED_MARKER_SUFFIX = '.remote-deleted';
|
|
25
|
+
/** Server-side text ceiling for changeset file content (mirrors filetype.TextMaxBytes). */
|
|
26
|
+
const TEXT_MAX_BYTES = 10 * 1024 * 1024;
|
|
16
27
|
// ---------------------------------------------------------------------------
|
|
17
28
|
// Wiki resolution helpers
|
|
18
29
|
// ---------------------------------------------------------------------------
|
|
@@ -34,7 +45,10 @@ export async function resolveWikiRef(ctx, wikiRef) {
|
|
|
34
45
|
if (fuzzy) {
|
|
35
46
|
return fuzzy;
|
|
36
47
|
}
|
|
37
|
-
|
|
48
|
+
const available = wikis.length > 0
|
|
49
|
+
? ` Available wikis: ${wikis.map((w) => w.slug).join(', ')}`
|
|
50
|
+
: ' This organization has no wikis yet.';
|
|
51
|
+
throw new Error(`wiki not found: ${wikiRef}.${available}`);
|
|
38
52
|
}
|
|
39
53
|
/**
|
|
40
54
|
* Resolve wiki reference. If wikiRef is omitted or empty, auto-resolves to
|
|
@@ -70,22 +84,55 @@ export async function getWikiTree(ctx, wikiRef, options = {}) {
|
|
|
70
84
|
}
|
|
71
85
|
export async function getWikiBlob(ctx, wikiRef, options) {
|
|
72
86
|
const wiki = await resolveWikiRef(ctx, wikiRef);
|
|
87
|
+
const normalizedPath = normalizeRequiredWikiPath(options.path);
|
|
88
|
+
// Local mount first (same data source as search/section/outline) so reads
|
|
89
|
+
// reflect the agent's own in-progress edits. Files absent locally AND
|
|
90
|
+
// absent from the manifest (never synced, or ACL-filtered) fall through to
|
|
91
|
+
// the API; files in the manifest but missing on disk are pending local
|
|
92
|
+
// deletes — surfacing the server copy there would make a delete look like
|
|
93
|
+
// it failed.
|
|
94
|
+
if (!options.remote) {
|
|
95
|
+
const mount = await resolveLocalWikiMount(ctx, wiki);
|
|
96
|
+
if (mount) {
|
|
97
|
+
const target = resolvePathInsideRoot(mount.root, normalizedPath);
|
|
98
|
+
const stat = await fs.stat(target).catch(() => null);
|
|
99
|
+
if (stat?.isFile()) {
|
|
100
|
+
const content = await fs.readFile(target);
|
|
101
|
+
if (looksBinary(content)) {
|
|
102
|
+
throw new Error(`wiki file is binary, not printable text: ${normalizedPath}. ` +
|
|
103
|
+
'Binary files are viewable in the web UI.');
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
wiki,
|
|
107
|
+
content: content.toString('utf8'),
|
|
108
|
+
size: content.length,
|
|
109
|
+
source: 'local_mount',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const manifest = await readLocalManifest(mount.root);
|
|
113
|
+
if (manifest.files[normalizedPath]) {
|
|
114
|
+
throw new Error(`${normalizedPath} is deleted in your local workspace (pending delete). ` +
|
|
115
|
+
'Run `parall wiki changeset create` to propose the deletion, ' +
|
|
116
|
+
'`parall wiki reset` to restore it, or `parall wiki cat --remote` to read the server version.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
73
120
|
const blob = await ctx.client.getWikiBlob(ctx.orgId, wiki.id, {
|
|
74
|
-
path:
|
|
121
|
+
path: normalizedPath,
|
|
75
122
|
});
|
|
76
123
|
// Phase 2 widened WikiBlob to allow encoding='signed_url' (binary served
|
|
77
124
|
// via preview URL) and still admits the legacy 'base64' inline shape,
|
|
78
125
|
// both of which omit or encode `content` in ways the CLI's string surface
|
|
79
|
-
// cannot use. Only utf-8 text is safe to return verbatim
|
|
80
|
-
// gets a clear error — callers that want bytes should fetch via the
|
|
81
|
-
// signed_url flow.
|
|
126
|
+
// cannot use. Only utf-8 text is safe to return verbatim.
|
|
82
127
|
if (blob.encoding !== 'utf-8' || blob.content == null) {
|
|
83
|
-
throw new Error(`wiki
|
|
128
|
+
throw new Error(`wiki file is binary, not printable text (encoding=${blob.encoding}): ${normalizedPath}. ` +
|
|
129
|
+
'Binary files are viewable in the web UI.');
|
|
84
130
|
}
|
|
85
131
|
return {
|
|
86
132
|
wiki,
|
|
87
133
|
content: blob.content,
|
|
88
134
|
size: blob.size,
|
|
135
|
+
source: 'api',
|
|
89
136
|
};
|
|
90
137
|
}
|
|
91
138
|
// ---------------------------------------------------------------------------
|
|
@@ -259,20 +306,17 @@ export async function getAfcsStatus(ctx, wikiRef) {
|
|
|
259
306
|
catch {
|
|
260
307
|
// Changesets API may fail — non-fatal for status
|
|
261
308
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
};
|
|
309
|
+
// No permissions block: per-path access is queryable via `parall wiki
|
|
310
|
+
// access <path>`; a whole-tree writability summary needs the path-scope
|
|
311
|
+
// semantics still moving in the restriction-layer work.
|
|
266
312
|
return {
|
|
267
313
|
wiki_id: wiki.id,
|
|
268
314
|
wiki_slug: wiki.slug,
|
|
269
315
|
wiki_name: wiki.name,
|
|
270
316
|
mount_path: mount.root,
|
|
271
|
-
mode: 'read_write',
|
|
272
317
|
default_ref: wiki.default_branch,
|
|
273
318
|
local_changes: localChanges,
|
|
274
319
|
changesets,
|
|
275
|
-
permissions,
|
|
276
320
|
};
|
|
277
321
|
}
|
|
278
322
|
export async function getAfcsDiff(ctx, wikiRef) {
|
|
@@ -295,7 +339,7 @@ export async function getAfcsDiff(ctx, wikiRef) {
|
|
|
295
339
|
// ---------------------------------------------------------------------------
|
|
296
340
|
export async function proposeWikiChangeset(ctx, wikiRef, options) {
|
|
297
341
|
const wiki = await resolveWikiRef(ctx, wikiRef);
|
|
298
|
-
const mount = await requireLocalWikiMount(ctx, wiki
|
|
342
|
+
const mount = await requireLocalWikiMount(ctx, wiki);
|
|
299
343
|
const title = options.title.trim();
|
|
300
344
|
if (!title) {
|
|
301
345
|
throw new Error('title is required');
|
|
@@ -303,7 +347,38 @@ export async function proposeWikiChangeset(ctx, wikiRef, options) {
|
|
|
303
347
|
const manifest = await readLocalManifest(mount.root);
|
|
304
348
|
const diff = await computeLocalDiff(mount, manifest);
|
|
305
349
|
if (diff.changedPaths.length === 0) {
|
|
306
|
-
throw new Error(`no changes to propose for wiki ${wiki.slug}`
|
|
350
|
+
throw new Error(`no changes to propose for wiki ${wiki.slug} — edit files under ${mount.root} first, ` +
|
|
351
|
+
'then run `parall wiki diff` to confirm what will be proposed');
|
|
352
|
+
}
|
|
353
|
+
// Stale-base precheck (fail-closed): compare each changed path's sync
|
|
354
|
+
// baseline against the server's CURRENT manifest. Proposing from a stale
|
|
355
|
+
// baseline would upload full content that silently rolls back concurrent
|
|
356
|
+
// edits. The server re-validates via base_sha (authoritative — this check
|
|
357
|
+
// just fails earlier with the complete file list).
|
|
358
|
+
const serverManifest = (await wikiServiceFetch(mount.manifestUrl, requireMountToken(mount)));
|
|
359
|
+
const serverShaByPath = new Map(serverManifest.data.map((e) => [e.path, e.sha]));
|
|
360
|
+
const staleLines = [];
|
|
361
|
+
for (const filePath of diff.changedPaths) {
|
|
362
|
+
const baseSha = diff.baseShaByPath.get(filePath);
|
|
363
|
+
const serverSha = serverShaByPath.get(filePath);
|
|
364
|
+
if (baseSha === undefined) {
|
|
365
|
+
// Locally created file — stale if the server got one in the meantime.
|
|
366
|
+
if (serverSha !== undefined) {
|
|
367
|
+
staleLines.push(`${filePath} (created on the server since your last sync)`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else if (serverSha === undefined) {
|
|
371
|
+
staleLines.push(`${filePath} (deleted on the server since your last sync)`);
|
|
372
|
+
}
|
|
373
|
+
else if (serverSha !== baseSha) {
|
|
374
|
+
staleLines.push(`${filePath} (modified on the server since your last sync)`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (staleLines.length > 0) {
|
|
378
|
+
throw new Error(`cannot propose: ${staleLines.length} file(s) changed on the server since your last sync:\n` +
|
|
379
|
+
staleLines.map((l) => ` ${l}`).join('\n') +
|
|
380
|
+
'\nRun `parall wiki sync` to pull the latest content (your local edits are preserved; ' +
|
|
381
|
+
'conflicting files get a marker under .parall-wiki/conflicts/), resolve if needed, then propose again.');
|
|
307
382
|
}
|
|
308
383
|
// Build file_changes for the changeset API
|
|
309
384
|
const fileChanges = [];
|
|
@@ -316,25 +391,43 @@ export async function proposeWikiChangeset(ctx, wikiRef, options) {
|
|
|
316
391
|
fileChanges.push({
|
|
317
392
|
path: filePath,
|
|
318
393
|
action: 'delete',
|
|
394
|
+
base_sha: baseEntry?.sha,
|
|
319
395
|
});
|
|
320
396
|
}
|
|
321
397
|
else {
|
|
322
398
|
const content = await fs.readFile(localPath);
|
|
399
|
+
// The changeset API is text-only (the server rejects binary with 422
|
|
400
|
+
// USE_UPLOAD, pointing at an endpoint the CLI does not wrap). Reject
|
|
401
|
+
// locally with a clear boundary statement instead.
|
|
402
|
+
if (looksBinary(content)) {
|
|
403
|
+
throw new Error(`cannot propose ${filePath}: wiki changesets support text files only. ` +
|
|
404
|
+
'Remove the binary from the workspace (binary uploads go through the web UI).');
|
|
405
|
+
}
|
|
406
|
+
if (content.length > TEXT_MAX_BYTES) {
|
|
407
|
+
throw new Error(`cannot propose ${filePath}: file is ${content.length} bytes, ` +
|
|
408
|
+
`over the ${TEXT_MAX_BYTES}-byte changeset limit. Split the file or remove it from the workspace.`);
|
|
409
|
+
}
|
|
323
410
|
fileChanges.push({
|
|
324
411
|
path: filePath,
|
|
325
412
|
action: baseEntry ? 'update' : 'create',
|
|
326
413
|
content_base64: content.toString('base64'),
|
|
414
|
+
base_sha: baseEntry?.sha,
|
|
327
415
|
});
|
|
328
416
|
}
|
|
329
417
|
}
|
|
330
418
|
let changeset;
|
|
331
419
|
const existingChangesetId = normalizeOptionalString(options.changesetId);
|
|
332
420
|
if (existingChangesetId) {
|
|
333
|
-
// Re-propose
|
|
421
|
+
// Re-propose: replace_files makes the workspace diff define the
|
|
422
|
+
// changeset's FULL content — the server resets the feature branch to
|
|
423
|
+
// default HEAD first, so a change withdrawn locally (file reverted to
|
|
424
|
+
// baseline) actually disappears from the proposal instead of silently
|
|
425
|
+
// surviving on the branch.
|
|
334
426
|
changeset = await ctx.client.updateWikiChangeset(ctx.orgId, wiki.id, existingChangesetId, {
|
|
335
427
|
title,
|
|
336
428
|
message: normalizeOptionalString(options.message),
|
|
337
429
|
file_changes: fileChanges,
|
|
430
|
+
replace_files: true,
|
|
338
431
|
});
|
|
339
432
|
}
|
|
340
433
|
else {
|
|
@@ -407,34 +500,52 @@ function describeProposeNextAction(changeset, postMergeSync, postMergeSyncError)
|
|
|
407
500
|
// ---------------------------------------------------------------------------
|
|
408
501
|
/**
|
|
409
502
|
* Discard all local changes and restore files to the last synced state.
|
|
410
|
-
*
|
|
503
|
+
* Restores from the local baseline object store (network only as a
|
|
504
|
+
* SHA-verified fallback for pre-objects mounts), so the workspace lands
|
|
505
|
+
* exactly on the manifest baseline — `wiki status` reports clean afterwards.
|
|
411
506
|
*/
|
|
412
507
|
export async function resetWikiWorkspace(ctx, wikiRef) {
|
|
413
508
|
const wiki = await resolveWikiRef(ctx, wikiRef);
|
|
414
509
|
const mount = await requireLocalWikiMount(ctx, wiki);
|
|
415
510
|
const manifest = await readLocalManifest(mount.root);
|
|
416
|
-
//
|
|
511
|
+
// Only touch files that actually diverged from the baseline.
|
|
417
512
|
const changes = await computeLocalChanges(mount);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
await fs.
|
|
429
|
-
await
|
|
513
|
+
if (changes.length === 0) {
|
|
514
|
+
return { wiki_id: wiki.id, wiki_slug: wiki.slug, files_restored: 0, unrestorable_paths: [] };
|
|
515
|
+
}
|
|
516
|
+
let restored = 0;
|
|
517
|
+
const unrestorable = [];
|
|
518
|
+
for (const change of changes) {
|
|
519
|
+
const entry = manifest.files[change.path];
|
|
520
|
+
const fullPath = resolvePathInsideRoot(mount.root, change.path);
|
|
521
|
+
if (!entry) {
|
|
522
|
+
// Locally created file — discard.
|
|
523
|
+
await fs.rm(fullPath, { force: true });
|
|
524
|
+
await removeEmptyParents(mount.root, path.dirname(fullPath));
|
|
525
|
+
restored++;
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
const baseline = await loadBaselineContent(mount, change.path, entry.sha);
|
|
529
|
+
if (!baseline) {
|
|
530
|
+
// No baseline available (pre-objects mount, server moved on). Leave the
|
|
531
|
+
// local file untouched rather than overwriting it with non-baseline
|
|
532
|
+
// content; `parall wiki sync` is the path that reconciles this state.
|
|
533
|
+
unrestorable.push(change.path);
|
|
534
|
+
continue;
|
|
430
535
|
}
|
|
536
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
537
|
+
await fs.writeFile(fullPath, baseline);
|
|
538
|
+
restored++;
|
|
539
|
+
}
|
|
540
|
+
if (unrestorable.length > 0) {
|
|
541
|
+
console.warn(`[wiki reset] ${unrestorable.length} file(s) had no recoverable baseline and were left as-is: ` +
|
|
542
|
+
`${unrestorable.join(', ')} — run \`parall wiki sync\` to reconcile`);
|
|
431
543
|
}
|
|
432
|
-
// Remove any local file not in manifest
|
|
433
|
-
await removeFilesNotInManifest(mount.root, manifest);
|
|
434
544
|
return {
|
|
435
545
|
wiki_id: wiki.id,
|
|
436
546
|
wiki_slug: wiki.slug,
|
|
437
|
-
files_restored:
|
|
547
|
+
files_restored: restored,
|
|
548
|
+
unrestorable_paths: unrestorable,
|
|
438
549
|
};
|
|
439
550
|
}
|
|
440
551
|
export async function listWikiChangesets(ctx, wikiRef) {
|
|
@@ -495,10 +606,32 @@ export async function requestWikiAccess(ctx, wikiRef, targetPath, reason) {
|
|
|
495
606
|
message: 'Access request submitted. Waiting for approval.',
|
|
496
607
|
};
|
|
497
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* Wiki history. Without a path: recent wiki operations (audit log). With a
|
|
611
|
+
* path: that file's commit history from the default branch.
|
|
612
|
+
*/
|
|
498
613
|
export async function getWikiLog(ctx, wikiRef, filePath) {
|
|
499
614
|
const wiki = await resolveWikiRef(ctx, wikiRef);
|
|
500
|
-
|
|
501
|
-
|
|
615
|
+
// Same normalization as every other path entry point — `./docs/a.md` or
|
|
616
|
+
// `/docs/a.md` would otherwise reach the server un-normalized and read
|
|
617
|
+
// back as an empty history.
|
|
618
|
+
const normalizedPath = filePath?.trim() ? normalizeRequiredWikiPath(filePath) : undefined;
|
|
619
|
+
if (normalizedPath) {
|
|
620
|
+
const commits = await ctx.client.getWikiFileCommits(ctx.orgId, wiki.id, normalizedPath);
|
|
621
|
+
return {
|
|
622
|
+
wiki_id: wiki.id,
|
|
623
|
+
wiki_slug: wiki.slug,
|
|
624
|
+
wiki_name: wiki.name,
|
|
625
|
+
path: normalizedPath,
|
|
626
|
+
entries: commits.data.map((c) => ({
|
|
627
|
+
type: 'commit',
|
|
628
|
+
id: c.sha,
|
|
629
|
+
path: normalizedPath,
|
|
630
|
+
action: c.title,
|
|
631
|
+
author_name: c.author_name,
|
|
632
|
+
created_at: c.date,
|
|
633
|
+
})),
|
|
634
|
+
};
|
|
502
635
|
}
|
|
503
636
|
const ops = await ctx.client.getWikiOperations(ctx.orgId, wiki.id);
|
|
504
637
|
const entries = ops.data.map((op) => ({
|
|
@@ -516,12 +649,16 @@ export async function getWikiLog(ctx, wikiRef, filePath) {
|
|
|
516
649
|
};
|
|
517
650
|
}
|
|
518
651
|
/**
|
|
519
|
-
*
|
|
520
|
-
*
|
|
652
|
+
* Sync wiki workspaces via REST (manifest comparison + bulk download).
|
|
653
|
+
* Without `wikiRef`: every accessible wiki is synced and stale mount
|
|
654
|
+
* directories are pruned. With `wikiRef`: only that wiki is synced and
|
|
655
|
+
* pruning is skipped — other wikis' workspaces must survive a scoped sync.
|
|
521
656
|
* Mount path is determined client-side: {mountRoot}/{slug}/
|
|
522
657
|
*/
|
|
523
|
-
export async function syncAllMounts(ctx) {
|
|
524
|
-
const
|
|
658
|
+
export async function syncAllMounts(ctx, wikiRef) {
|
|
659
|
+
const allWikis = await ctx.client.getWikis(ctx.orgId);
|
|
660
|
+
const target = wikiRef?.trim() ? await resolveWikiRef(ctx, wikiRef) : undefined;
|
|
661
|
+
const wikis = target ? allWikis.filter((w) => w.id === target.id) : allWikis;
|
|
525
662
|
const mountRoot = ctx.mountRoot?.trim() || process.env.PRLL_WIKI_MOUNT_ROOT?.trim();
|
|
526
663
|
const activeMountPaths = new Set();
|
|
527
664
|
const synced = [];
|
|
@@ -538,7 +675,9 @@ export async function syncAllMounts(ctx) {
|
|
|
538
675
|
failed: outcome.failed,
|
|
539
676
|
});
|
|
540
677
|
}
|
|
541
|
-
|
|
678
|
+
if (!target) {
|
|
679
|
+
await pruneStaleMounts(mountRoot, activeMountPaths);
|
|
680
|
+
}
|
|
542
681
|
const ok = synced.every((s) => s.failed.length === 0);
|
|
543
682
|
return { ok, mounts: wikis.length, synced };
|
|
544
683
|
}
|
|
@@ -695,6 +834,7 @@ export async function syncSingleWiki(ctx, wiki, mountPath) {
|
|
|
695
834
|
}
|
|
696
835
|
// 5. Apply actions and start with the previous manifest, mutating per action.
|
|
697
836
|
const newFiles = { ...localManifest.files };
|
|
837
|
+
const downloadedBySha = new Map();
|
|
698
838
|
const conflicts = [];
|
|
699
839
|
const failed = [];
|
|
700
840
|
let applied = 0;
|
|
@@ -763,6 +903,7 @@ export async function syncSingleWiki(ctx, wiki, mountPath) {
|
|
|
763
903
|
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
764
904
|
await fs.writeFile(fullPath, buf);
|
|
765
905
|
newFiles[action.path] = { sha: action.remoteSha, size: action.remoteSize };
|
|
906
|
+
downloadedBySha.set(action.remoteSha, buf);
|
|
766
907
|
applied++;
|
|
767
908
|
break;
|
|
768
909
|
}
|
|
@@ -853,13 +994,16 @@ export async function syncSingleWiki(ctx, wiki, mountPath) {
|
|
|
853
994
|
}
|
|
854
995
|
}
|
|
855
996
|
}
|
|
856
|
-
// 6. Persist new manifest
|
|
997
|
+
// 6. Persist new manifest + refresh the baseline object store so diff and
|
|
998
|
+
// reset can always reproduce the exact synced content locally.
|
|
857
999
|
const newManifest = {
|
|
858
1000
|
wiki_id: wiki.id,
|
|
859
1001
|
synced_at: new Date().toISOString(),
|
|
860
1002
|
files: newFiles,
|
|
861
1003
|
};
|
|
862
1004
|
await writeLocalManifest(mountPath, newManifest);
|
|
1005
|
+
await ensureBaselineObjects(mountPath, newFiles, downloadedBySha);
|
|
1006
|
+
await gcBaselineObjects(mountPath, newFiles);
|
|
863
1007
|
if (conflicts.length > 0) {
|
|
864
1008
|
for (const c of conflicts) {
|
|
865
1009
|
const where = c.remoteCopyPath ? ` → ${path.relative(mountPath, c.remoteCopyPath)}` : '';
|
|
@@ -949,6 +1093,104 @@ async function writeLocalManifest(mountRoot, manifest) {
|
|
|
949
1093
|
await fs.writeFile(path.join(metaDir, LOCAL_MANIFEST_FILE), JSON.stringify(manifest, null, 2), 'utf8');
|
|
950
1094
|
}
|
|
951
1095
|
// ---------------------------------------------------------------------------
|
|
1096
|
+
// Baseline object store (.parall-wiki/objects/<sha>)
|
|
1097
|
+
//
|
|
1098
|
+
// Content-addressed copies of the last-synced version of every manifest file.
|
|
1099
|
+
// diff/status/reset read the true sync baseline from here instead of fetching
|
|
1100
|
+
// the server's CURRENT content (which is the wrong base whenever the server
|
|
1101
|
+
// has moved past the local sync point).
|
|
1102
|
+
// ---------------------------------------------------------------------------
|
|
1103
|
+
function baselineObjectPath(mountRoot, sha) {
|
|
1104
|
+
return path.join(mountRoot, PRLL_WIKI_DIR, OBJECTS_DIR, sha);
|
|
1105
|
+
}
|
|
1106
|
+
async function readBaselineObject(mountRoot, sha) {
|
|
1107
|
+
try {
|
|
1108
|
+
return await fs.readFile(baselineObjectPath(mountRoot, sha));
|
|
1109
|
+
}
|
|
1110
|
+
catch {
|
|
1111
|
+
return null;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
async function writeBaselineObject(mountRoot, sha, content) {
|
|
1115
|
+
const target = baselineObjectPath(mountRoot, sha);
|
|
1116
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
1117
|
+
await fs.writeFile(target, content);
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Make sure every manifest entry has its baseline object on disk.
|
|
1121
|
+
* Content sources, in order: bytes downloaded during this sync
|
|
1122
|
+
* (`contentBySha`), then the local working-tree file when its blob SHA still
|
|
1123
|
+
* matches the manifest (clean file — typical for pre-objects mounts being
|
|
1124
|
+
* upgraded). Files that are locally dirty AND missing an object stay absent;
|
|
1125
|
+
* diff falls back per-file (see loadBaselineContent).
|
|
1126
|
+
*/
|
|
1127
|
+
async function ensureBaselineObjects(mountRoot, files, contentBySha) {
|
|
1128
|
+
for (const [relPath, entry] of Object.entries(files)) {
|
|
1129
|
+
if (await pathExists(baselineObjectPath(mountRoot, entry.sha))) {
|
|
1130
|
+
continue;
|
|
1131
|
+
}
|
|
1132
|
+
const downloaded = contentBySha?.get(entry.sha);
|
|
1133
|
+
if (downloaded) {
|
|
1134
|
+
await writeBaselineObject(mountRoot, entry.sha, downloaded);
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
const probe = await probeLocalGitBlob(mountRoot, relPath);
|
|
1138
|
+
if (probe.kind === 'file' && probe.sha === entry.sha) {
|
|
1139
|
+
const fullPath = resolvePathInsideRoot(mountRoot, relPath);
|
|
1140
|
+
await writeBaselineObject(mountRoot, entry.sha, await fs.readFile(fullPath));
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
/** Drop baseline objects no longer referenced by any manifest entry. */
|
|
1145
|
+
async function gcBaselineObjects(mountRoot, files) {
|
|
1146
|
+
const objectsDir = path.join(mountRoot, PRLL_WIKI_DIR, OBJECTS_DIR);
|
|
1147
|
+
let names;
|
|
1148
|
+
try {
|
|
1149
|
+
names = await fs.readdir(objectsDir);
|
|
1150
|
+
}
|
|
1151
|
+
catch {
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const live = new Set(Object.values(files).map((e) => e.sha));
|
|
1155
|
+
for (const name of names) {
|
|
1156
|
+
if (!live.has(name)) {
|
|
1157
|
+
await fs.rm(path.join(objectsDir, name), { force: true });
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Load the baseline (last-synced) content for a manifest entry. Objects store
|
|
1163
|
+
* first; when absent (mount predates the objects store and the file is
|
|
1164
|
+
* locally dirty), fall back to downloading the server's current content and
|
|
1165
|
+
* accept it ONLY if its blob SHA matches the manifest base — otherwise the
|
|
1166
|
+
* server has moved and no true baseline is available (returns null).
|
|
1167
|
+
*/
|
|
1168
|
+
async function loadBaselineContent(mount, relPath, expectedSha) {
|
|
1169
|
+
const cached = await readBaselineObject(mount.root, expectedSha);
|
|
1170
|
+
if (cached) {
|
|
1171
|
+
return cached;
|
|
1172
|
+
}
|
|
1173
|
+
if (!mount.token) {
|
|
1174
|
+
return null;
|
|
1175
|
+
}
|
|
1176
|
+
try {
|
|
1177
|
+
const entries = await bulkDownloadFiles(mount.bulkDownloadUrl, mount.token, [relPath]);
|
|
1178
|
+
const entry = entries[0];
|
|
1179
|
+
if (!entry || entry.error) {
|
|
1180
|
+
return null;
|
|
1181
|
+
}
|
|
1182
|
+
const content = Buffer.from(entry.content_base64, 'base64');
|
|
1183
|
+
if (computeGitBlobSHA(content) !== expectedSha) {
|
|
1184
|
+
return null;
|
|
1185
|
+
}
|
|
1186
|
+
await writeBaselineObject(mount.root, expectedSha, content);
|
|
1187
|
+
return content;
|
|
1188
|
+
}
|
|
1189
|
+
catch {
|
|
1190
|
+
return null;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
// ---------------------------------------------------------------------------
|
|
952
1194
|
// REST helpers for wiki-service
|
|
953
1195
|
// ---------------------------------------------------------------------------
|
|
954
1196
|
function resolveApiToken(ctx) {
|
|
@@ -1011,54 +1253,92 @@ export function computeGitBlobSHA(content) {
|
|
|
1011
1253
|
const header = Buffer.from(`blob ${content.length}\0`, 'utf8');
|
|
1012
1254
|
return createHash('sha1').update(header).update(content).digest('hex');
|
|
1013
1255
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1256
|
+
// Exact mirror of the magic signatures where the server's classifier
|
|
1257
|
+
// (filetype.IsText → Go http.DetectContentType → isBinaryContentType)
|
|
1258
|
+
// rejects content that could still be NUL-free, UTF-8-decodable bytes.
|
|
1259
|
+
// Signatures whose match requires NUL or non-UTF-8 bytes (PNG, JPEG, OGG,
|
|
1260
|
+
// MIDI, ICO, …) are deliberately omitted — the UTF-8 + NUL checks below
|
|
1261
|
+
// already cover them. Keep this table in lockstep with the Go sniffing
|
|
1262
|
+
// rules; test/testdata/text-classifier-cases.json is the shared contract
|
|
1263
|
+
// both sides verify against.
|
|
1264
|
+
const BINARY_MAGIC_PREFIXES = [
|
|
1265
|
+
Buffer.from('GIF87a'), // image/gif
|
|
1266
|
+
Buffer.from('GIF89a'), // image/gif
|
|
1267
|
+
Buffer.from('%PDF-'), // application/pdf
|
|
1268
|
+
Buffer.from('BM'), // image/bmp (yes, bare "BM" — Go sniffs it as BMP)
|
|
1269
|
+
Buffer.from('ID3'), // audio/mpeg
|
|
1270
|
+
Buffer.from([0x50, 0x4b, 0x03, 0x04]), // application/zip
|
|
1271
|
+
Buffer.from([0x1f, 0x8b, 0x08]), // application/x-gzip
|
|
1272
|
+
];
|
|
1273
|
+
// Container formats Go sniffs via offset-masked signatures: 4-byte container
|
|
1274
|
+
// tag at offset 0, format tag at offset 8.
|
|
1275
|
+
const BINARY_CONTAINER_SIGS = [
|
|
1276
|
+
{ head: 'RIFF', at8: 'WAVE' }, // audio/wave
|
|
1277
|
+
{ head: 'RIFF', at8: 'AVI ' }, // video/avi
|
|
1278
|
+
{ head: 'RIFF', at8: 'WEBPVP' }, // image/webp
|
|
1279
|
+
{ head: 'FORM', at8: 'AIFF' }, // audio/aiff
|
|
1280
|
+
];
|
|
1281
|
+
const utf8Strict = new TextDecoder('utf-8', { fatal: true });
|
|
1282
|
+
/**
|
|
1283
|
+
* Mirror of the server's text classifier (filetype.IsText): content-type
|
|
1284
|
+
* magic sniff, valid UTF-8, and no NUL bytes — kept aligned so content the
|
|
1285
|
+
* CLI accepts cannot bounce off the server's 422 USE_UPLOAD later. The
|
|
1286
|
+
* shared fixture table (test/testdata/text-classifier-cases.json) is
|
|
1287
|
+
* verified by both this implementation's tests and the Go package's tests.
|
|
1288
|
+
*/
|
|
1289
|
+
export function isWikiTextContent(content) {
|
|
1290
|
+
for (const magic of BINARY_MAGIC_PREFIXES) {
|
|
1291
|
+
if (content.subarray(0, magic.length).equals(magic)) {
|
|
1292
|
+
return false;
|
|
1039
1293
|
}
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
diffFiles.push({ path: filePath, additions: 0, deletions });
|
|
1294
|
+
}
|
|
1295
|
+
for (const sig of BINARY_CONTAINER_SIGS) {
|
|
1296
|
+
if (content.subarray(0, 4).equals(Buffer.from(sig.head)) &&
|
|
1297
|
+
content.subarray(8, 8 + sig.at8.length).equals(Buffer.from(sig.at8))) {
|
|
1298
|
+
return false;
|
|
1046
1299
|
}
|
|
1047
1300
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1301
|
+
if (content.includes(0)) {
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
try {
|
|
1305
|
+
utf8Strict.decode(content);
|
|
1306
|
+
}
|
|
1307
|
+
catch {
|
|
1308
|
+
return false;
|
|
1309
|
+
}
|
|
1310
|
+
return true;
|
|
1050
1311
|
}
|
|
1051
|
-
|
|
1312
|
+
function looksBinary(content) {
|
|
1313
|
+
return !isWikiTextContent(content);
|
|
1314
|
+
}
|
|
1315
|
+
/** Compute list of changed files by comparing local disk to local manifest. */
|
|
1316
|
+
async function computeLocalChanges(mount) {
|
|
1317
|
+
const manifest = await readLocalManifest(mount.root);
|
|
1318
|
+
const diff = await computeLocalDiff(mount, manifest);
|
|
1319
|
+
return diff.diffFiles;
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Compute the local workspace diff against the last-synced baseline. Base
|
|
1323
|
+
* content comes from the local objects store (with a SHA-verified network
|
|
1324
|
+
* fallback for pre-objects mounts), so the diff base is always the true sync
|
|
1325
|
+
* point — never the server's current content.
|
|
1326
|
+
*/
|
|
1052
1327
|
async function computeLocalDiff(mount, manifest) {
|
|
1053
1328
|
const diffFiles = [];
|
|
1054
1329
|
const patchParts = [];
|
|
1055
1330
|
const visited = new Set();
|
|
1056
|
-
const
|
|
1331
|
+
const baseShaByPath = new Map();
|
|
1332
|
+
const loadBase = async (relPath, entry) => {
|
|
1333
|
+
const base = await loadBaselineContent(mount, relPath, entry.sha);
|
|
1334
|
+
// A missing baseline (pre-objects mount with a locally dirty file and a
|
|
1335
|
+
// server that has since moved) degrades to an empty base: the patch shows
|
|
1336
|
+
// the full local content as additions. propose() still carries the right
|
|
1337
|
+
// base_sha, so staleness is caught server-side regardless.
|
|
1338
|
+
return base ? base.toString('utf8') : '';
|
|
1339
|
+
};
|
|
1057
1340
|
// Walk local files to find modified/added
|
|
1058
1341
|
await walkLocalFiles(mount.root, mount.root, async (fullPath, relativePath) => {
|
|
1059
|
-
if (!matchesAllowedPrefix(relativePath, [])) {
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
1342
|
visited.add(relativePath);
|
|
1063
1343
|
const localContent = await fs.readFile(fullPath);
|
|
1064
1344
|
const localSha = computeGitBlobSHA(localContent);
|
|
@@ -1066,83 +1346,62 @@ async function computeLocalDiff(mount, manifest) {
|
|
|
1066
1346
|
if (!manifestEntry) {
|
|
1067
1347
|
// New file
|
|
1068
1348
|
const localText = localContent.toString('utf8');
|
|
1069
|
-
|
|
1070
|
-
diffFiles.push({ path: relativePath, additions: localLines.length, deletions: 0 });
|
|
1071
|
-
patchParts.push(buildUnifiedDiff(relativePath, '', localText));
|
|
1349
|
+
appendFileDiff(diffFiles, patchParts, relativePath, '', localText, 'create');
|
|
1072
1350
|
}
|
|
1073
1351
|
else if (localSha !== manifestEntry.sha) {
|
|
1074
|
-
// Modified file
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
const baseEntries = await bulkDownloadFiles(mount.bulkDownloadUrl, token, [relativePath]);
|
|
1079
|
-
if (baseEntries.length > 0) {
|
|
1080
|
-
baseText = Buffer.from(baseEntries[0].content_base64, 'base64').toString('utf8');
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
catch {
|
|
1084
|
-
// If we can't fetch base, treat as full addition
|
|
1085
|
-
}
|
|
1086
|
-
const localLines = localText.split('\n');
|
|
1087
|
-
const baseLines = baseText.split('\n');
|
|
1088
|
-
diffFiles.push({
|
|
1089
|
-
path: relativePath,
|
|
1090
|
-
additions: localLines.length,
|
|
1091
|
-
deletions: baseLines.length,
|
|
1092
|
-
});
|
|
1093
|
-
patchParts.push(buildUnifiedDiff(relativePath, baseText, localText));
|
|
1352
|
+
// Modified file
|
|
1353
|
+
baseShaByPath.set(relativePath, manifestEntry.sha);
|
|
1354
|
+
const baseText = await loadBase(relativePath, manifestEntry);
|
|
1355
|
+
appendFileDiff(diffFiles, patchParts, relativePath, baseText, localContent.toString('utf8'), 'update');
|
|
1094
1356
|
}
|
|
1095
1357
|
});
|
|
1096
1358
|
// Find deleted files
|
|
1097
1359
|
for (const [filePath, entry] of Object.entries(manifest.files)) {
|
|
1098
1360
|
if (!visited.has(filePath)) {
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
if (baseEntries.length > 0) {
|
|
1103
|
-
baseText = Buffer.from(baseEntries[0].content_base64, 'base64').toString('utf8');
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
catch {
|
|
1107
|
-
// Estimate
|
|
1108
|
-
}
|
|
1109
|
-
const baseLines = baseText.split('\n');
|
|
1110
|
-
diffFiles.push({ path: filePath, additions: 0, deletions: baseLines.length });
|
|
1111
|
-
patchParts.push(buildUnifiedDiff(filePath, baseText, ''));
|
|
1361
|
+
baseShaByPath.set(filePath, entry.sha);
|
|
1362
|
+
const baseText = await loadBase(filePath, entry);
|
|
1363
|
+
appendFileDiff(diffFiles, patchParts, filePath, baseText, '', 'delete');
|
|
1112
1364
|
}
|
|
1113
1365
|
}
|
|
1114
1366
|
diffFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
1115
1367
|
const changedPaths = diffFiles.map((f) => f.path);
|
|
1116
1368
|
const patch = patchParts.join('');
|
|
1117
|
-
return { changedPaths, diffFiles, patch };
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
function
|
|
1121
|
-
const
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1369
|
+
return { changedPaths, diffFiles, patch, baseShaByPath };
|
|
1370
|
+
}
|
|
1371
|
+
/** Append one file's real (Myers) unified diff and +/- counts. */
|
|
1372
|
+
function appendFileDiff(diffFiles, patchParts, filePath, oldText, newText, action) {
|
|
1373
|
+
const hunks = structuredPatch(filePath, filePath, oldText, newText, undefined, undefined, {
|
|
1374
|
+
context: 3,
|
|
1375
|
+
}).hunks;
|
|
1376
|
+
let additions = 0;
|
|
1377
|
+
let deletions = 0;
|
|
1125
1378
|
const parts = [`diff --git a/${filePath} b/${filePath}\n`];
|
|
1126
|
-
if (
|
|
1379
|
+
if (action === 'create') {
|
|
1127
1380
|
parts.push('new file mode 100644\n');
|
|
1128
1381
|
}
|
|
1129
|
-
else if (
|
|
1382
|
+
else if (action === 'delete') {
|
|
1130
1383
|
parts.push('deleted file mode 100644\n');
|
|
1131
1384
|
}
|
|
1132
|
-
parts.push(`--- ${
|
|
1133
|
-
parts.push(`+++ ${
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1385
|
+
parts.push(`--- ${action === 'create' ? '/dev/null' : `a/${filePath}`}\n`);
|
|
1386
|
+
parts.push(`+++ ${action === 'delete' ? '/dev/null' : `b/${filePath}`}\n`);
|
|
1387
|
+
for (const hunk of hunks) {
|
|
1388
|
+
parts.push(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\n`);
|
|
1389
|
+
for (const line of hunk.lines) {
|
|
1390
|
+
parts.push(`${line}\n`);
|
|
1391
|
+
if (line.startsWith('+'))
|
|
1392
|
+
additions++;
|
|
1393
|
+
else if (line.startsWith('-'))
|
|
1394
|
+
deletions++;
|
|
1395
|
+
}
|
|
1137
1396
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1397
|
+
diffFiles.push({ path: filePath, action, additions, deletions });
|
|
1398
|
+
// An empty-file create/delete produces zero hunks but is still a real
|
|
1399
|
+
// change — emit the header-only entry so the patch lists every changed
|
|
1400
|
+
// path. Only a hunk-less UPDATE (identical content, e.g. mode-only noise)
|
|
1401
|
+
// is genuinely nothing to show.
|
|
1402
|
+
if (hunks.length > 0 || action !== 'update') {
|
|
1403
|
+
patchParts.push(parts.join(''));
|
|
1140
1404
|
}
|
|
1141
|
-
return parts.join('');
|
|
1142
|
-
}
|
|
1143
|
-
/** Estimate number of lines from file size (rough: ~40 bytes per line). */
|
|
1144
|
-
function estimateLines(sizeBytes) {
|
|
1145
|
-
return Math.max(1, Math.round(sizeBytes / 40));
|
|
1146
1405
|
}
|
|
1147
1406
|
// ---------------------------------------------------------------------------
|
|
1148
1407
|
// File system helpers
|
|
@@ -1244,13 +1503,11 @@ async function resolveLocalWikiMount(ctx, wiki) {
|
|
|
1244
1503
|
changesetsUrl: `${wikiBase}/changesets`,
|
|
1245
1504
|
};
|
|
1246
1505
|
}
|
|
1247
|
-
async function requireLocalWikiMount(ctx, wiki
|
|
1506
|
+
async function requireLocalWikiMount(ctx, wiki) {
|
|
1248
1507
|
const mount = await resolveLocalWikiMount(ctx, wiki);
|
|
1249
1508
|
if (!mount) {
|
|
1250
|
-
throw new Error(`wiki ${wiki.slug}
|
|
1251
|
-
|
|
1252
|
-
if (options.requireWrite && 'read_write' !== 'read_write') {
|
|
1253
|
-
throw new Error(`wiki ${wiki.slug} mount is read-only`);
|
|
1509
|
+
throw new Error(`wiki ${wiki.slug} has no local workspace yet — run \`parall wiki sync\` to download it ` +
|
|
1510
|
+
'(the sync output prints the workspace path)');
|
|
1254
1511
|
}
|
|
1255
1512
|
return mount;
|
|
1256
1513
|
}
|
|
@@ -1539,14 +1796,21 @@ function stripNodeSectionContent(section) {
|
|
|
1539
1796
|
}
|
|
1540
1797
|
function buildIndexNodes(sections) {
|
|
1541
1798
|
const nodes = [];
|
|
1799
|
+
// File-level frontmatter folds into only the first section of each file
|
|
1800
|
+
// (matching the indexed search-indexer's section-0 gating) so a
|
|
1801
|
+
// frontmatter-only query returns one hit per document, not one per section.
|
|
1802
|
+
const seenFile = new Set();
|
|
1542
1803
|
for (const section of sections) {
|
|
1543
|
-
|
|
1804
|
+
const includeFrontmatter = !seenFile.has(section.path);
|
|
1805
|
+
seenFile.add(section.path);
|
|
1806
|
+
nodes.push(buildIndexedNode(section, includeFrontmatter));
|
|
1544
1807
|
}
|
|
1545
1808
|
return nodes;
|
|
1546
1809
|
}
|
|
1547
1810
|
function parseMarkdownFile(wiki, file) {
|
|
1548
1811
|
const lines = file.content.split('\n');
|
|
1549
1812
|
const frontMatterEnd = detectFrontMatterEnd(lines);
|
|
1813
|
+
const fm = parseFrontMatter(lines, frontMatterEnd);
|
|
1550
1814
|
const headings = extractMarkdownHeadings(lines, frontMatterEnd);
|
|
1551
1815
|
const fileTitle = defaultFileTitle(file.path);
|
|
1552
1816
|
if (headings.length === 0) {
|
|
@@ -1560,7 +1824,11 @@ function parseMarkdownFile(wiki, file) {
|
|
|
1560
1824
|
endLine: lines.length,
|
|
1561
1825
|
content: lines.slice(frontMatterEnd).join('\n').trim(),
|
|
1562
1826
|
});
|
|
1563
|
-
|
|
1827
|
+
// Keep an empty-body doc node when it carries frontmatter, so a
|
|
1828
|
+
// frontmatter-only page still exposes its metadata — matching the Go
|
|
1829
|
+
// parser, which always returns the doc section for a no-heading file.
|
|
1830
|
+
const keep = !!docNode.content || hasFrontMatter(fm);
|
|
1831
|
+
return applyFrontMatter(keep ? [docNode] : [], fm);
|
|
1564
1832
|
}
|
|
1565
1833
|
const nodes = [];
|
|
1566
1834
|
const firstHeadingLine = headings[0].line;
|
|
@@ -1597,7 +1865,24 @@ function parseMarkdownFile(wiki, file) {
|
|
|
1597
1865
|
.trim(),
|
|
1598
1866
|
}));
|
|
1599
1867
|
}
|
|
1600
|
-
return nodes;
|
|
1868
|
+
return applyFrontMatter(nodes, fm);
|
|
1869
|
+
}
|
|
1870
|
+
// applyFrontMatter copies file-level frontmatter onto every section parsed from
|
|
1871
|
+
// the file (frontmatter is a document-level property in OKF). Mirrors the Go
|
|
1872
|
+
// implementation in server/pkg/markdown/section.go. No-op when empty.
|
|
1873
|
+
function applyFrontMatter(sections, fm) {
|
|
1874
|
+
if (!hasFrontMatter(fm)) {
|
|
1875
|
+
return sections;
|
|
1876
|
+
}
|
|
1877
|
+
for (const section of sections) {
|
|
1878
|
+
if (fm.type !== undefined)
|
|
1879
|
+
section.type = fm.type;
|
|
1880
|
+
if (fm.description !== undefined)
|
|
1881
|
+
section.description = fm.description;
|
|
1882
|
+
if (fm.tags !== undefined)
|
|
1883
|
+
section.tags = fm.tags;
|
|
1884
|
+
}
|
|
1885
|
+
return sections;
|
|
1601
1886
|
}
|
|
1602
1887
|
function buildNodeSection(wiki, input) {
|
|
1603
1888
|
const content = input.content.trim();
|
|
@@ -1617,11 +1902,14 @@ function buildNodeSection(wiki, input) {
|
|
|
1617
1902
|
content,
|
|
1618
1903
|
};
|
|
1619
1904
|
}
|
|
1620
|
-
function buildIndexedNode(section) {
|
|
1905
|
+
function buildIndexedNode(section, includeFrontmatter) {
|
|
1621
1906
|
const searchText = [
|
|
1622
1907
|
section.path,
|
|
1623
1908
|
section.title,
|
|
1624
1909
|
section.heading_path?.join(' ') ?? '',
|
|
1910
|
+
...(includeFrontmatter
|
|
1911
|
+
? [section.type ?? '', section.description ?? '', section.tags?.join(' ') ?? '']
|
|
1912
|
+
: []),
|
|
1625
1913
|
section.content,
|
|
1626
1914
|
]
|
|
1627
1915
|
.join('\n')
|
|
@@ -1965,7 +2253,8 @@ function extractMarkdownHeadings(lines, startIndex) {
|
|
|
1965
2253
|
}
|
|
1966
2254
|
return headings;
|
|
1967
2255
|
}
|
|
1968
|
-
|
|
2256
|
+
// Exported for unit testing; mirrors server/pkg/markdown/section.go.
|
|
2257
|
+
export function detectFrontMatterEnd(lines) {
|
|
1969
2258
|
if (lines.length === 0) {
|
|
1970
2259
|
return 0;
|
|
1971
2260
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.35.0",
|
|
4
4
|
"description": "CLI client for Parall — universal agent & human access to Parall API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,12 +33,16 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
35
35
|
"commander": "^13.0.0",
|
|
36
|
+
"diff": "^8.0.3",
|
|
37
|
+
"js-yaml": "^4.1.0",
|
|
36
38
|
"zod": "^4.3.6",
|
|
37
|
-
"@parall/sdk": "1.
|
|
39
|
+
"@parall/sdk": "1.35.0"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
42
|
+
"@types/js-yaml": "^4.0.9",
|
|
40
43
|
"@types/node": "^22.0.0",
|
|
41
|
-
"typescript": "^5.7.0"
|
|
44
|
+
"typescript": "^5.7.0",
|
|
45
|
+
"@parall/agent-core": "1.35.0"
|
|
42
46
|
},
|
|
43
47
|
"scripts": {
|
|
44
48
|
"build": "tsc",
|