fold-agent 0.1.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.
Files changed (74) hide show
  1. package/README.md +14 -0
  2. package/bin/fold-agent.js +2 -0
  3. package/dist/cli/app.d.ts +4 -0
  4. package/dist/cli/app.js +1113 -0
  5. package/dist/cli/app.js.map +1 -0
  6. package/dist/cli/bin.d.ts +2 -0
  7. package/dist/cli/bin.js +8 -0
  8. package/dist/cli/bin.js.map +1 -0
  9. package/dist/cli/context.d.ts +5 -0
  10. package/dist/cli/context.js +2 -0
  11. package/dist/cli/context.js.map +1 -0
  12. package/dist/cli/operations.d.ts +126 -0
  13. package/dist/cli/operations.js +1159 -0
  14. package/dist/cli/operations.js.map +1 -0
  15. package/dist/cli/output.d.ts +22 -0
  16. package/dist/cli/output.js +245 -0
  17. package/dist/cli/output.js.map +1 -0
  18. package/dist/cli/package-info.d.ts +5 -0
  19. package/dist/cli/package-info.js +12 -0
  20. package/dist/cli/package-info.js.map +1 -0
  21. package/dist/cli/results.d.ts +393 -0
  22. package/dist/cli/results.js +2 -0
  23. package/dist/cli/results.js.map +1 -0
  24. package/dist/cli/skill-install.d.ts +7 -0
  25. package/dist/cli/skill-install.js +211 -0
  26. package/dist/cli/skill-install.js.map +1 -0
  27. package/dist/deploy/public-origin.d.ts +15 -0
  28. package/dist/deploy/public-origin.js +59 -0
  29. package/dist/deploy/public-origin.js.map +1 -0
  30. package/dist/rooms/append-log-api.d.ts +16 -0
  31. package/dist/rooms/append-log-api.js +72 -0
  32. package/dist/rooms/append-log-api.js.map +1 -0
  33. package/dist/rooms/append-log-validation.d.ts +2 -0
  34. package/dist/rooms/append-log-validation.js +16 -0
  35. package/dist/rooms/append-log-validation.js.map +1 -0
  36. package/dist/rooms/comments.d.ts +63 -0
  37. package/dist/rooms/comments.js +136 -0
  38. package/dist/rooms/comments.js.map +1 -0
  39. package/dist/rooms/crypto.d.ts +11 -0
  40. package/dist/rooms/crypto.js +44 -0
  41. package/dist/rooms/crypto.js.map +1 -0
  42. package/dist/rooms/encrypted-records.d.ts +5 -0
  43. package/dist/rooms/encrypted-records.js +21 -0
  44. package/dist/rooms/encrypted-records.js.map +1 -0
  45. package/dist/rooms/markdown-snapshot.d.ts +23 -0
  46. package/dist/rooms/markdown-snapshot.js +126 -0
  47. package/dist/rooms/markdown-snapshot.js.map +1 -0
  48. package/dist/rooms/metadata.d.ts +32 -0
  49. package/dist/rooms/metadata.js +118 -0
  50. package/dist/rooms/metadata.js.map +1 -0
  51. package/dist/rooms/personas.d.ts +16 -0
  52. package/dist/rooms/personas.js +78 -0
  53. package/dist/rooms/personas.js.map +1 -0
  54. package/dist/rooms/project-state.d.ts +41 -0
  55. package/dist/rooms/project-state.js +249 -0
  56. package/dist/rooms/project-state.js.map +1 -0
  57. package/dist/rooms/proposals.d.ts +63 -0
  58. package/dist/rooms/proposals.js +254 -0
  59. package/dist/rooms/proposals.js.map +1 -0
  60. package/dist/rooms/replay.d.ts +13 -0
  61. package/dist/rooms/replay.js +19 -0
  62. package/dist/rooms/replay.js.map +1 -0
  63. package/dist/rooms/room-reference.d.ts +21 -0
  64. package/dist/rooms/room-reference.js +142 -0
  65. package/dist/rooms/room-reference.js.map +1 -0
  66. package/dist/rooms/timeline.d.ts +26 -0
  67. package/dist/rooms/timeline.js +68 -0
  68. package/dist/rooms/timeline.js.map +1 -0
  69. package/package.json +35 -0
  70. package/skills/fold/SKILL.md +81 -0
  71. package/skills/fold/agents/openai.yaml +4 -0
  72. package/skills/fold/references/cli.md +33 -0
  73. package/skills/fold/references/security.md +14 -0
  74. package/skills/fold/references/workflow.md +48 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-snapshot.js","sourceRoot":"","sources":["../../../../src/rooms/markdown-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { EncryptedMarkdownSnapshot, MarkdownDocumentSummary } from './markdown-snapshot.js';
2
+ export declare const ROOM_METADATA_VERSION = 1;
3
+ export declare const ROOM_METADATA_DIR_MODE = 448;
4
+ export declare const ROOM_METADATA_FILE_MODE = 384;
5
+ export interface RoomMetadataFile {
6
+ version: typeof ROOM_METADATA_VERSION;
7
+ rooms: RoomMetadataEntry[];
8
+ }
9
+ export interface RoomMetadataEntry {
10
+ alias?: string;
11
+ roomId: string;
12
+ appUrl?: string;
13
+ syncUrl?: string;
14
+ serverUrl: string;
15
+ roomUrl: string;
16
+ token: string;
17
+ sourcePath?: string;
18
+ createdAt: string;
19
+ updatedAt: string;
20
+ lastUsedAt?: string;
21
+ document: MarkdownDocumentSummary;
22
+ encryptedSnapshot: EncryptedMarkdownSnapshot;
23
+ }
24
+ export declare function defaultMetadataPath(cwd: string): string;
25
+ export declare function readRoomMetadata(path: string): Promise<RoomMetadataFile>;
26
+ export declare function writeRoomMetadata(path: string, metadata: RoomMetadataFile): Promise<void>;
27
+ export declare function upsertRoomMetadata(path: string, entry: RoomMetadataEntry): Promise<RoomMetadataFile>;
28
+ export declare function findRoomMetadata(path: string, roomId: string, serverUrl: string): Promise<RoomMetadataEntry | undefined>;
29
+ export declare function findRoomMetadataByAlias(path: string, alias: string): Promise<RoomMetadataEntry | undefined>;
30
+ export declare function listRoomMetadata(path: string): Promise<RoomMetadataEntry[]>;
31
+ export declare function removeRoomMetadataByAlias(path: string, alias: string): Promise<RoomMetadataFile>;
32
+ export declare function resolveSourcePath(cwd: string, filePath: string): string;
@@ -0,0 +1,118 @@
1
+ import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ export const ROOM_METADATA_VERSION = 1;
4
+ export const ROOM_METADATA_DIR_MODE = 0o700;
5
+ export const ROOM_METADATA_FILE_MODE = 0o600;
6
+ export function defaultMetadataPath(cwd) {
7
+ return join(cwd, '.fold', 'rooms.json');
8
+ }
9
+ export async function readRoomMetadata(path) {
10
+ let raw;
11
+ try {
12
+ raw = await readFile(path, 'utf8');
13
+ }
14
+ catch (error) {
15
+ if (isNotFoundError(error)) {
16
+ return emptyMetadata();
17
+ }
18
+ throw error;
19
+ }
20
+ const parsed = JSON.parse(raw);
21
+ if (!isRoomMetadataFile(parsed)) {
22
+ throw new Error(`Invalid room metadata schema at ${path}`);
23
+ }
24
+ return parsed;
25
+ }
26
+ export async function writeRoomMetadata(path, metadata) {
27
+ const directory = dirname(path);
28
+ await mkdir(directory, { recursive: true, mode: ROOM_METADATA_DIR_MODE });
29
+ await applyModeIfSupported(directory, ROOM_METADATA_DIR_MODE);
30
+ await applyModeIfSupported(path, ROOM_METADATA_FILE_MODE, { allowMissing: true });
31
+ await writeFile(path, `${JSON.stringify(metadata, null, 2)}\n`, {
32
+ encoding: 'utf8',
33
+ mode: ROOM_METADATA_FILE_MODE,
34
+ });
35
+ await applyModeIfSupported(path, ROOM_METADATA_FILE_MODE);
36
+ }
37
+ export async function upsertRoomMetadata(path, entry) {
38
+ const metadata = await readRoomMetadata(path);
39
+ const syncUrl = entry.syncUrl ?? entry.serverUrl;
40
+ const existing = metadata.rooms.findIndex((room) => ((entry.alias && room.alias === entry.alias) ||
41
+ (room.roomId === entry.roomId && (room.syncUrl ?? room.serverUrl) === syncUrl)));
42
+ const rooms = [...metadata.rooms];
43
+ if (existing === -1) {
44
+ rooms.push(entry);
45
+ }
46
+ else {
47
+ rooms[existing] = {
48
+ ...rooms[existing],
49
+ ...entry,
50
+ createdAt: rooms[existing]?.createdAt ?? entry.createdAt,
51
+ };
52
+ }
53
+ const next = {
54
+ version: ROOM_METADATA_VERSION,
55
+ rooms,
56
+ };
57
+ await writeRoomMetadata(path, next);
58
+ return next;
59
+ }
60
+ export async function findRoomMetadata(path, roomId, serverUrl) {
61
+ const metadata = await readRoomMetadata(path);
62
+ return metadata.rooms.find((room) => room.roomId === roomId && (room.syncUrl ?? room.serverUrl) === serverUrl);
63
+ }
64
+ export async function findRoomMetadataByAlias(path, alias) {
65
+ const metadata = await readRoomMetadata(path);
66
+ return metadata.rooms.find((room) => room.alias === alias);
67
+ }
68
+ export async function listRoomMetadata(path) {
69
+ return (await readRoomMetadata(path)).rooms;
70
+ }
71
+ export async function removeRoomMetadataByAlias(path, alias) {
72
+ const metadata = await readRoomMetadata(path);
73
+ const next = {
74
+ version: ROOM_METADATA_VERSION,
75
+ rooms: metadata.rooms.filter((room) => room.alias !== alias),
76
+ };
77
+ if (next.rooms.length === metadata.rooms.length) {
78
+ throw new Error(`Room alias not found: ${alias}`);
79
+ }
80
+ await writeRoomMetadata(path, next);
81
+ return next;
82
+ }
83
+ export function resolveSourcePath(cwd, filePath) {
84
+ return resolve(cwd, filePath);
85
+ }
86
+ function emptyMetadata() {
87
+ return {
88
+ version: ROOM_METADATA_VERSION,
89
+ rooms: [],
90
+ };
91
+ }
92
+ function isRoomMetadataFile(value) {
93
+ if (!value || typeof value !== 'object')
94
+ return false;
95
+ const candidate = value;
96
+ return candidate.version === ROOM_METADATA_VERSION && Array.isArray(candidate.rooms);
97
+ }
98
+ function isNotFoundError(error) {
99
+ return Boolean(error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT');
100
+ }
101
+ async function applyModeIfSupported(path, mode, options = {}) {
102
+ try {
103
+ await chmod(path, mode);
104
+ }
105
+ catch (error) {
106
+ if (options.allowMissing && isNotFoundError(error))
107
+ return;
108
+ if (isModeUnsupportedError(error))
109
+ return;
110
+ throw error;
111
+ }
112
+ }
113
+ function isModeUnsupportedError(error) {
114
+ if (!error || typeof error !== 'object' || !('code' in error))
115
+ return false;
116
+ return error.code === 'ENOSYS' || error.code === 'EINVAL' || (process.platform === 'win32' && error.code === 'EPERM');
117
+ }
118
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../../src/rooms/metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type ParticipantKind = 'human' | 'agent';
2
+ export interface RoomPersona {
3
+ schema: 'fold.persona.v1';
4
+ id: string;
5
+ kind: ParticipantKind;
6
+ name: string;
7
+ label: 'Human' | 'Agent';
8
+ color: string;
9
+ participantFingerprint: string;
10
+ }
11
+ export interface AssignPersonaOptions {
12
+ roomId: string;
13
+ participantKind: ParticipantKind;
14
+ participantFingerprint: string;
15
+ }
16
+ export declare function assignPersona(options: AssignPersonaOptions): RoomPersona;
@@ -0,0 +1,78 @@
1
+ import { createHash } from 'node:crypto';
2
+ const AGENT_NAME_PREFIXES = [
3
+ 'Patch',
4
+ 'Diff',
5
+ 'Merge',
6
+ 'Token',
7
+ 'Branch',
8
+ 'Commit',
9
+ ];
10
+ const AGENT_NAME_SUFFIXES = [
11
+ 'Pilot',
12
+ 'Lantern',
13
+ 'Signal',
14
+ 'Loom',
15
+ 'Atlas',
16
+ 'Beacon',
17
+ 'Relay',
18
+ 'Compass',
19
+ 'Anchor',
20
+ 'Marker',
21
+ ];
22
+ const HUMAN_NAME_PREFIXES = [
23
+ 'Reader',
24
+ 'Editor',
25
+ 'Reviewer',
26
+ 'Writer',
27
+ 'Archivist',
28
+ 'Curator',
29
+ ];
30
+ const HUMAN_NAME_SUFFIXES = [
31
+ 'North',
32
+ 'Vale',
33
+ 'Stone',
34
+ 'Quinn',
35
+ 'Reed',
36
+ 'Lane',
37
+ 'Hale',
38
+ 'Rowe',
39
+ 'Wynn',
40
+ 'Gray',
41
+ ];
42
+ const COLORS = [
43
+ '#1e3a8a',
44
+ '#0f766e',
45
+ '#15803d',
46
+ '#b45309',
47
+ '#be123c',
48
+ '#0369a1',
49
+ '#334155',
50
+ '#4338ca',
51
+ ];
52
+ export function assignPersona(options) {
53
+ const seed = `${options.roomId}\0${options.participantKind}\0${options.participantFingerprint}`;
54
+ const digest = createHash('sha256').update(seed).digest();
55
+ const name = options.participantKind === 'agent'
56
+ ? personaName(AGENT_NAME_PREFIXES, AGENT_NAME_SUFFIXES, digest[0], digest[2])
57
+ : personaName(HUMAN_NAME_PREFIXES, HUMAN_NAME_SUFFIXES, digest[0], digest[2]);
58
+ const color = COLORS[digest[1] % COLORS.length] ?? COLORS[0];
59
+ const id = createHash('sha256')
60
+ .update(`persona\0${seed}`)
61
+ .digest('hex')
62
+ .slice(0, 24);
63
+ return {
64
+ schema: 'fold.persona.v1',
65
+ id,
66
+ kind: options.participantKind,
67
+ name,
68
+ label: options.participantKind === 'agent' ? 'Agent' : 'Human',
69
+ color,
70
+ participantFingerprint: options.participantFingerprint,
71
+ };
72
+ }
73
+ function personaName(prefixes, suffixes, prefixSeed, suffixSeed) {
74
+ const prefix = prefixes[prefixSeed % prefixes.length] ?? prefixes[0];
75
+ const suffix = suffixes[suffixSeed % suffixes.length] ?? suffixes[0];
76
+ return `${prefix} ${suffix}`;
77
+ }
78
+ //# sourceMappingURL=personas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personas.js","sourceRoot":"","sources":["../../../../src/rooms/personas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAoBzC,MAAM,mBAAmB,GAAG;IAC1B,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;CACA,CAAC;AAEX,MAAM,mBAAmB,GAAG;IAC1B,OAAO;IACP,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,QAAQ;CACA,CAAC;AAEX,MAAM,mBAAmB,GAAG;IAC1B,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,WAAW;IACX,SAAS;CACD,CAAC;AAEX,MAAM,mBAAmB,GAAG;IAC1B,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC;AAEX,MAAM,MAAM,GAAG;IACb,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;CACD,CAAC;AAEX,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,eAAe,KAAK,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAChG,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,KAAK,OAAO;QAC9C,CAAC,CAAC,WAAW,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC,CAAC,WAAW,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC5B,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,EAAE;QACF,IAAI,EAAE,OAAO,CAAC,eAAe;QAC7B,IAAI;QACJ,KAAK,EAAE,OAAO,CAAC,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;QAC9D,KAAK;QACL,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,QAA2B,EAC3B,QAA2B,EAC3B,UAAkB,EAClB,UAAkB;IAElB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { EncryptedUpdateRecord, IncomingEncryptedUpdate } from '../server/append-log.js';
2
+ import type { MarkdownDocumentSummary } from './markdown-snapshot.js';
3
+ import type { RoomAccess } from './room-reference.js';
4
+ export declare const PROJECT_SCHEMA = "fold.project.v1";
5
+ export declare const PROJECT_UPDATE_SENDER_ID_PREFIX = "fold-cli:project";
6
+ export declare const WEB_PROJECT_FILE_SENDER_ID_PREFIX = "web-client:file";
7
+ export interface ProjectFile {
8
+ path: string;
9
+ markdown: string;
10
+ }
11
+ export interface ProjectSnapshot {
12
+ schema: typeof PROJECT_SCHEMA;
13
+ primaryPath: string;
14
+ files: ProjectFile[];
15
+ updatedAt: string;
16
+ }
17
+ export interface ProjectSummary {
18
+ canonical: 'project.markdown-files:v1';
19
+ fileCount: number;
20
+ bytes: number;
21
+ sha256: string;
22
+ primaryPath: string;
23
+ files: Array<MarkdownDocumentSummary & {
24
+ path: string;
25
+ }>;
26
+ }
27
+ export declare function readMarkdownProject(cwd: string, sourcePath: string, roomPath?: string): Promise<ProjectSnapshot>;
28
+ export declare function writeMarkdownProject(cwd: string, outputPath: string, project: ProjectSnapshot, selectedPath?: string, options?: {
29
+ forceDirectory?: boolean;
30
+ }): Promise<string[]>;
31
+ export declare function normalizeProjectSnapshot(snapshot: ProjectSnapshot): ProjectSnapshot;
32
+ export declare function singleFileProject(path: string, markdown: string): ProjectSnapshot;
33
+ export declare function replaceProjectFile(project: ProjectSnapshot, path: string, markdown: string): ProjectSnapshot;
34
+ export declare function addProjectFile(project: ProjectSnapshot, path: string, markdown: string): ProjectSnapshot;
35
+ export declare function projectFileOrThrow(project: ProjectSnapshot, path: string): ProjectFile;
36
+ export declare function summarizeProject(project: ProjectSnapshot): ProjectSummary;
37
+ export declare function createEncryptedProjectSnapshot(access: RoomAccess, project: ProjectSnapshot): Promise<IncomingEncryptedUpdate>;
38
+ export declare function decryptProjectSnapshotsFromRecords(access: RoomAccess, records: EncryptedUpdateRecord[]): Promise<ProjectSnapshot[]>;
39
+ export declare function normalizeProjectPath(input: string): string;
40
+ export declare function isStaleProjectFileSnapshot(currentUpdatedAt: string | undefined, nextUpdatedAt: string): boolean;
41
+ export declare function isStaleProjectFileSnapshotSeq(currentSeq: number | undefined, nextSeq: number): boolean;
@@ -0,0 +1,249 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readdir, readFile, stat, writeFile, mkdir } from 'node:fs/promises';
3
+ import { dirname, relative, resolve, sep } from 'node:path';
4
+ import { summarizeMarkdown } from './markdown-snapshot.js';
5
+ import { decryptJsonRecord, encryptJsonRecord } from './encrypted-records.js';
6
+ import { assertContiguousRecords } from './append-log-validation.js';
7
+ export const PROJECT_SCHEMA = 'fold.project.v1';
8
+ export const PROJECT_UPDATE_SENDER_ID_PREFIX = 'fold-cli:project';
9
+ export const WEB_PROJECT_FILE_SENDER_ID_PREFIX = 'web-client:file';
10
+ export async function readMarkdownProject(cwd, sourcePath, roomPath) {
11
+ const absolute = resolve(cwd, sourcePath);
12
+ const info = await stat(absolute);
13
+ const files = info.isDirectory()
14
+ ? await readMarkdownDirectory(absolute)
15
+ : [{
16
+ path: normalizeProjectPath(roomPath ?? defaultRoomPathForFile(sourcePath)),
17
+ markdown: await readFile(absolute, 'utf8'),
18
+ }];
19
+ if (files.length === 0) {
20
+ throw new Error(`No Markdown files found at ${sourcePath}`);
21
+ }
22
+ return normalizeProjectSnapshot({
23
+ schema: PROJECT_SCHEMA,
24
+ primaryPath: files[0].path,
25
+ files,
26
+ updatedAt: new Date().toISOString(),
27
+ });
28
+ }
29
+ export async function writeMarkdownProject(cwd, outputPath, project, selectedPath, options = {}) {
30
+ const output = resolve(cwd, outputPath);
31
+ const files = selectedPath
32
+ ? [projectFileOrThrow(project, selectedPath)]
33
+ : project.files;
34
+ if (selectedPath || (files.length === 1 && !options.forceDirectory)) {
35
+ const target = selectedPath ? output : output;
36
+ await mkdir(dirname(target), { recursive: true });
37
+ await writeFile(target, files[0].markdown, 'utf8');
38
+ return [target];
39
+ }
40
+ const written = [];
41
+ for (const file of files) {
42
+ const target = resolve(output, file.path);
43
+ await mkdir(dirname(target), { recursive: true });
44
+ await writeFile(target, file.markdown, 'utf8');
45
+ written.push(target);
46
+ }
47
+ return written;
48
+ }
49
+ export function normalizeProjectSnapshot(snapshot) {
50
+ const byPath = new Map();
51
+ for (const file of snapshot.files) {
52
+ const path = normalizeProjectPath(file.path);
53
+ if (!path.endsWith('.md')) {
54
+ throw new Error(`Project file must be Markdown: ${file.path}`);
55
+ }
56
+ byPath.set(path, { path, markdown: file.markdown });
57
+ }
58
+ const files = [...byPath.values()].sort((left, right) => left.path.localeCompare(right.path));
59
+ const primaryPath = normalizeProjectPath(snapshot.primaryPath || files[0]?.path || 'document.md');
60
+ return {
61
+ schema: PROJECT_SCHEMA,
62
+ primaryPath: files.some((file) => file.path === primaryPath) ? primaryPath : files[0]?.path ?? primaryPath,
63
+ files,
64
+ updatedAt: snapshot.updatedAt,
65
+ };
66
+ }
67
+ export function singleFileProject(path, markdown) {
68
+ return normalizeProjectSnapshot({
69
+ schema: PROJECT_SCHEMA,
70
+ primaryPath: normalizeProjectPath(path),
71
+ files: [{ path: normalizeProjectPath(path), markdown }],
72
+ updatedAt: new Date().toISOString(),
73
+ });
74
+ }
75
+ export function replaceProjectFile(project, path, markdown) {
76
+ const normalized = normalizeProjectSnapshot(project);
77
+ const targetPath = normalizeProjectPath(path);
78
+ const files = normalized.files.filter((file) => file.path !== targetPath);
79
+ files.push({ path: targetPath, markdown });
80
+ return normalizeProjectSnapshot({
81
+ schema: PROJECT_SCHEMA,
82
+ primaryPath: normalized.primaryPath || targetPath,
83
+ files,
84
+ updatedAt: new Date().toISOString(),
85
+ });
86
+ }
87
+ export function addProjectFile(project, path, markdown) {
88
+ const normalized = normalizeProjectSnapshot(project);
89
+ const targetPath = normalizeProjectPath(path);
90
+ if (normalized.files.some((file) => file.path === targetPath)) {
91
+ throw new Error(`Project file already exists: ${targetPath}`);
92
+ }
93
+ return normalizeProjectSnapshot({
94
+ schema: PROJECT_SCHEMA,
95
+ primaryPath: normalized.primaryPath,
96
+ files: [
97
+ ...normalized.files,
98
+ { path: targetPath, markdown },
99
+ ],
100
+ updatedAt: new Date().toISOString(),
101
+ });
102
+ }
103
+ export function projectFileOrThrow(project, path) {
104
+ const normalized = normalizeProjectPath(path);
105
+ const file = project.files.find((candidate) => candidate.path === normalized);
106
+ if (!file)
107
+ throw new Error(`Project file not found: ${normalized}`);
108
+ return file;
109
+ }
110
+ export function summarizeProject(project) {
111
+ const normalized = normalizeProjectSnapshot(project);
112
+ const encoded = JSON.stringify(normalized.files.map((file) => [file.path, file.markdown]));
113
+ const files = normalized.files.map((file) => ({
114
+ path: file.path,
115
+ ...summarizeMarkdown(file.markdown),
116
+ }));
117
+ return {
118
+ canonical: 'project.markdown-files:v1',
119
+ fileCount: files.length,
120
+ bytes: files.reduce((total, file) => total + file.bytes, 0),
121
+ sha256: createHash('sha256').update(encoded).digest('hex'),
122
+ primaryPath: normalized.primaryPath,
123
+ files,
124
+ };
125
+ }
126
+ export async function createEncryptedProjectSnapshot(access, project) {
127
+ return encryptJsonRecord(access, `${PROJECT_UPDATE_SENDER_ID_PREFIX}:${Date.now()}`, normalizeProjectSnapshot(project));
128
+ }
129
+ export async function decryptProjectSnapshotsFromRecords(access, records) {
130
+ assertContiguousRecords(records, access.roomId);
131
+ const snapshots = [];
132
+ const fileAppliedSeq = new Map();
133
+ let current;
134
+ for (const record of records) {
135
+ if (record.senderId.startsWith(PROJECT_UPDATE_SENDER_ID_PREFIX)) {
136
+ const value = await decryptJsonRecord(access, record, record.senderId);
137
+ if (!isProjectSnapshot(value)) {
138
+ throw new Error('Invalid encrypted project snapshot payload');
139
+ }
140
+ current = normalizeProjectSnapshot(value);
141
+ fileAppliedSeq.clear();
142
+ for (const file of current.files) {
143
+ fileAppliedSeq.set(file.path, record.seq);
144
+ }
145
+ snapshots.push(current);
146
+ continue;
147
+ }
148
+ if (record.senderId.startsWith(WEB_PROJECT_FILE_SENDER_ID_PREFIX)) {
149
+ const value = await decryptJsonRecord(access, record, record.senderId);
150
+ if (!isWebProjectFileSnapshot(value)) {
151
+ throw new Error('Invalid encrypted web project file snapshot payload');
152
+ }
153
+ const path = normalizeProjectPath(value.path);
154
+ if (isStaleProjectFileSnapshotSeq(fileAppliedSeq.get(path), record.seq)) {
155
+ continue;
156
+ }
157
+ current = replaceProjectFile(current ?? singleFileProject(value.path, value.markdown), path, value.markdown);
158
+ fileAppliedSeq.set(path, record.seq);
159
+ current = normalizeProjectSnapshot({
160
+ ...current,
161
+ updatedAt: value.updatedAt,
162
+ });
163
+ snapshots.push(current);
164
+ }
165
+ }
166
+ return snapshots;
167
+ }
168
+ export function normalizeProjectPath(input) {
169
+ const withoutLeadingSlash = input.replace(/\\/g, '/').replace(/^\/+/, '').replace(/\/+/g, '/');
170
+ const segments = withoutLeadingSlash.split('/');
171
+ if (segments.length === 0 ||
172
+ segments.some((segment) => segment === '..') ||
173
+ /^[a-zA-Z]:/.test(segments[0] ?? '')) {
174
+ throw new Error(`Invalid project path: ${input}`);
175
+ }
176
+ const normalized = segments.filter((segment) => segment && segment !== '.').join('/');
177
+ if (!normalized) {
178
+ throw new Error(`Invalid project path: ${input}`);
179
+ }
180
+ return normalized;
181
+ }
182
+ async function readMarkdownDirectory(root) {
183
+ const files = [];
184
+ await walk(root, async (absolute) => {
185
+ if (!absolute.toLowerCase().endsWith('.md'))
186
+ return;
187
+ files.push({
188
+ path: normalizeProjectPath(relative(root, absolute).split(sep).join('/')),
189
+ markdown: await readFile(absolute, 'utf8'),
190
+ });
191
+ });
192
+ return files;
193
+ }
194
+ async function walk(directory, onFile) {
195
+ const entries = await readdir(directory, { withFileTypes: true });
196
+ for (const entry of entries) {
197
+ if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === '.fold')
198
+ continue;
199
+ const absolute = resolve(directory, entry.name);
200
+ if (entry.isDirectory()) {
201
+ await walk(absolute, onFile);
202
+ }
203
+ else if (entry.isFile()) {
204
+ await onFile(absolute);
205
+ }
206
+ }
207
+ }
208
+ function isProjectSnapshot(value) {
209
+ if (!value || typeof value !== 'object')
210
+ return false;
211
+ const candidate = value;
212
+ return (candidate.schema === PROJECT_SCHEMA &&
213
+ typeof candidate.primaryPath === 'string' &&
214
+ typeof candidate.updatedAt === 'string' &&
215
+ Array.isArray(candidate.files) &&
216
+ candidate.files.every((file) => (file &&
217
+ typeof file === 'object' &&
218
+ typeof file.path === 'string' &&
219
+ typeof file.markdown === 'string')));
220
+ }
221
+ function isWebProjectFileSnapshot(value) {
222
+ if (!value || typeof value !== 'object')
223
+ return false;
224
+ const candidate = value;
225
+ return (candidate.type === 'project_file_snapshot' &&
226
+ typeof candidate.path === 'string' &&
227
+ typeof candidate.markdown === 'string' &&
228
+ typeof candidate.updatedAt === 'string');
229
+ }
230
+ export function isStaleProjectFileSnapshot(currentUpdatedAt, nextUpdatedAt) {
231
+ if (!currentUpdatedAt)
232
+ return false;
233
+ const currentTime = Date.parse(currentUpdatedAt);
234
+ const nextTime = Date.parse(nextUpdatedAt);
235
+ if (!Number.isNaN(currentTime) && !Number.isNaN(nextTime)) {
236
+ return nextTime < currentTime;
237
+ }
238
+ return nextUpdatedAt < currentUpdatedAt;
239
+ }
240
+ export function isStaleProjectFileSnapshotSeq(currentSeq, nextSeq) {
241
+ return currentSeq !== undefined && nextSeq <= currentSeq;
242
+ }
243
+ function defaultRoomPathForFile(sourcePath) {
244
+ if (sourcePath.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(sourcePath)) {
245
+ return sourcePath.split(/[\\/]/).pop() ?? 'document.md';
246
+ }
247
+ return sourcePath;
248
+ }
249
+ //# sourceMappingURL=project-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-state.js","sourceRoot":"","sources":["../../../../src/rooms/project-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { EncryptedUpdateRecord, IncomingEncryptedUpdate } from '../server/append-log.js';
2
+ import type { MarkdownDocumentSummary } from './markdown-snapshot.js';
3
+ import { type RoomPersona } from './personas.js';
4
+ import type { RoomAccess } from './room-reference.js';
5
+ import { type ProjectSnapshot, type ProjectSummary } from './project-state.js';
6
+ import { type TimelineEvent } from './timeline.js';
7
+ import { type CommentReply } from './comments.js';
8
+ export declare const PROPOSAL_SCHEMA = "fold.proposal.v1";
9
+ export declare const PROPOSAL_SENDER_ID_PREFIX = "fold-cli:proposal";
10
+ export declare const DEFAULT_AGENT_PARTICIPANT_FINGERPRINT = "fold-cli:proposal";
11
+ export type ProposalStatus = 'pending' | 'accepted' | 'rejected';
12
+ export interface ProposalRecord {
13
+ schema: typeof PROPOSAL_SCHEMA;
14
+ id: string;
15
+ kind: 'whole-document-replacement' | 'file-replacement' | 'project-replacement';
16
+ createdAt: string;
17
+ updatedAt: string;
18
+ title: string;
19
+ comment: string;
20
+ authorKind: 'agent';
21
+ authorPersonaId: string;
22
+ persona: RoomPersona;
23
+ baseVersionId: string;
24
+ base: MarkdownDocumentSummary;
25
+ proposed: MarkdownDocumentSummary & {
26
+ markdown: string;
27
+ };
28
+ proposedMarkdown: string;
29
+ baseProject?: ProjectSummary;
30
+ proposedProject?: ProjectSnapshot;
31
+ path?: string;
32
+ diff: string;
33
+ discussionThreadIds: string[];
34
+ }
35
+ export interface ProposalView extends ProposalRecord {
36
+ status: ProposalStatus;
37
+ statusUpdatedAt: string;
38
+ replies?: CommentReply[];
39
+ }
40
+ export interface ProposalReplay {
41
+ proposals: ProposalView[];
42
+ timeline: TimelineEvent[];
43
+ }
44
+ export interface CreateEncryptedProposalOptions {
45
+ access: RoomAccess;
46
+ baseMarkdown: string;
47
+ proposedMarkdown: string;
48
+ baseProject?: ProjectSnapshot;
49
+ proposedProject?: ProjectSnapshot;
50
+ path?: string;
51
+ title?: string;
52
+ comment?: string;
53
+ participantFingerprint?: string;
54
+ }
55
+ export declare function createEncryptedProposalRecord(options: CreateEncryptedProposalOptions): Promise<{
56
+ update: IncomingEncryptedUpdate;
57
+ proposal: ProposalView;
58
+ timelineEvent: TimelineEvent;
59
+ }>;
60
+ export declare function createProposalAcceptedEvent(access: RoomAccess, proposal: Pick<ProposalView, 'id' | 'proposed' | 'title' | 'proposedProject' | 'path'>, documentSha256: string, actorPersonaId: string, acceptedProject?: ProjectSnapshot): Promise<IncomingEncryptedUpdate>;
61
+ export declare function createProposalRejectedEvent(access: RoomAccess, proposal: Pick<ProposalView, 'id' | 'title'>, actorPersonaId: string, reason?: string): Promise<IncomingEncryptedUpdate>;
62
+ export declare function replayProposalsFromRecords(access: RoomAccess, records: EncryptedUpdateRecord[]): Promise<ProposalReplay>;
63
+ export declare function decryptProposalRecord(access: RoomAccess, payload: Pick<EncryptedUpdateRecord, 'nonce' | 'ciphertext'>, senderId: string): Promise<ProposalRecord>;