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,1113 @@
1
+ import { buildApplication, buildCommand, buildRouteMap, run, buildChoiceParser, } from '@stricli/core';
2
+ import { acceptProposal, addComment, addRoomProfile, bootstrapRoom, createRoomProfile, createRoomInvite, exportMarkdown, forgetRoomProfile, listComments, listProposals, listRoomProfiles, patchMarkdown, postMarkdown, proposeMarkdown, publishMarkdown, rejectProposal, replyToComment, resumeRoom, roomContext, roomStatus, setRoomProfileUrls, showRoomProfile, showProposal, } from './operations.js';
3
+ import { installFoldSkill } from './skill-install.js';
4
+ import { writeBootstrapHuman, writeDecisionHuman, writeCommentHuman, writeCommentsHuman, writeExportHuman, writeJson, writePatchHuman, writePostHuman, writeProposalsHuman, writeProposeHuman, writePublishHuman, writeResumeHuman, writeRoomForgetHuman, writeRoomCreateHuman, writeRoomInviteHuman, writeRoomListHuman, writeRoomProfileHuman, writeShowProposalHuman, writeSkillHuman, writeStatusHuman, } from './output.js';
5
+ export const app = buildApplication(buildRouteMap({
6
+ routes: {
7
+ publish: buildCommand({
8
+ parameters: {
9
+ flags: {
10
+ server: {
11
+ kind: 'parsed',
12
+ parse: parseString,
13
+ optional: true,
14
+ brief: 'Compatibility shorthand for app and sync URL',
15
+ placeholder: 'url',
16
+ },
17
+ appUrl: {
18
+ kind: 'parsed',
19
+ parse: parseString,
20
+ optional: true,
21
+ brief: 'Human web app origin for generated room links',
22
+ placeholder: 'url',
23
+ },
24
+ syncUrl: {
25
+ kind: 'parsed',
26
+ parse: parseString,
27
+ optional: true,
28
+ brief: 'Append-log API/WebSocket origin',
29
+ placeholder: 'url',
30
+ },
31
+ alias: {
32
+ kind: 'parsed',
33
+ parse: parseString,
34
+ optional: true,
35
+ brief: 'Local room alias to save',
36
+ placeholder: 'name',
37
+ },
38
+ path: {
39
+ kind: 'parsed',
40
+ parse: parseString,
41
+ optional: true,
42
+ brief: 'Room path for a single published Markdown file',
43
+ placeholder: 'path',
44
+ },
45
+ json: {
46
+ kind: 'boolean',
47
+ default: false,
48
+ withNegated: false,
49
+ brief: 'Print a stable JSON result',
50
+ },
51
+ save: {
52
+ kind: 'boolean',
53
+ default: true,
54
+ withNegated: true,
55
+ brief: 'Save room profile in .fold/rooms.json',
56
+ },
57
+ },
58
+ positional: {
59
+ kind: 'tuple',
60
+ parameters: [
61
+ {
62
+ parse: parseString,
63
+ placeholder: 'file.md',
64
+ brief: 'Markdown file to publish',
65
+ },
66
+ ],
67
+ },
68
+ },
69
+ docs: {
70
+ brief: 'Publish Markdown into a local encrypted room foundation',
71
+ customUsage: ['<file.md> [--server <url>] [--json] [--no-save]'],
72
+ },
73
+ async func(flags, filePath) {
74
+ const result = await publishMarkdown({
75
+ cwd: this.cwd,
76
+ filePath,
77
+ serverUrl: flags.server,
78
+ appUrl: flags.appUrl,
79
+ syncUrl: flags.syncUrl,
80
+ alias: flags.alias,
81
+ path: flags.path,
82
+ save: flags.save,
83
+ });
84
+ if (flags.json)
85
+ writeJson(this, result);
86
+ else
87
+ writePublishHuman(this, result);
88
+ },
89
+ }),
90
+ export: buildCommand({
91
+ parameters: {
92
+ flags: {
93
+ room: {
94
+ kind: 'parsed',
95
+ parse: parseString,
96
+ brief: 'Room alias, URL, or token',
97
+ placeholder: 'alias-or-url-or-token',
98
+ },
99
+ output: {
100
+ kind: 'parsed',
101
+ parse: parseString,
102
+ optional: true,
103
+ brief: 'File to write exported Markdown',
104
+ placeholder: 'file',
105
+ },
106
+ path: {
107
+ kind: 'parsed',
108
+ parse: parseString,
109
+ optional: true,
110
+ brief: 'Export one project file by room path',
111
+ placeholder: 'path',
112
+ },
113
+ json: {
114
+ kind: 'boolean',
115
+ default: false,
116
+ withNegated: false,
117
+ brief: 'Print a stable JSON result',
118
+ },
119
+ },
120
+ },
121
+ docs: {
122
+ brief: 'Export Markdown from local encrypted room metadata',
123
+ customUsage: ['--room <alias-or-url-or-token> [--path <room-path>] [--output <file-or-directory>] [--json]'],
124
+ },
125
+ async func(flags) {
126
+ const result = await exportMarkdown({
127
+ cwd: this.cwd,
128
+ room: flags.room,
129
+ outputPath: flags.output,
130
+ path: flags.path,
131
+ });
132
+ if (flags.json)
133
+ writeJson(this, result);
134
+ else
135
+ writeExportHuman(this, result);
136
+ },
137
+ }),
138
+ patch: buildCommand({
139
+ parameters: {
140
+ flags: {
141
+ room: {
142
+ kind: 'parsed',
143
+ parse: parseString,
144
+ brief: 'Room alias, URL, or token',
145
+ placeholder: 'alias-or-url-or-token',
146
+ },
147
+ path: {
148
+ kind: 'parsed',
149
+ parse: parseString,
150
+ optional: true,
151
+ brief: 'Room path for a single-file proposal',
152
+ placeholder: 'path',
153
+ },
154
+ summary: {
155
+ kind: 'parsed',
156
+ parse: parseString,
157
+ optional: true,
158
+ brief: 'Human-readable patch summary',
159
+ placeholder: 'text',
160
+ },
161
+ json: {
162
+ kind: 'boolean',
163
+ default: false,
164
+ withNegated: false,
165
+ brief: 'Print a stable JSON result',
166
+ },
167
+ },
168
+ positional: {
169
+ kind: 'tuple',
170
+ parameters: [
171
+ {
172
+ parse: parseString,
173
+ placeholder: 'file.md',
174
+ brief: 'Markdown file to submit as a suggestion',
175
+ },
176
+ ],
177
+ },
178
+ },
179
+ docs: {
180
+ brief: 'Submit an encrypted whole-document patch suggestion',
181
+ customUsage: ['<file.md> --room <alias-or-url-or-token> [--path <room-path>] [--summary <text>] [--json]'],
182
+ },
183
+ async func(flags, filePath) {
184
+ const result = await patchMarkdown({
185
+ cwd: this.cwd,
186
+ filePath,
187
+ room: flags.room,
188
+ path: flags.path,
189
+ summary: flags.summary,
190
+ });
191
+ if (flags.json)
192
+ writeJson(this, result);
193
+ else
194
+ writePatchHuman(this, result);
195
+ },
196
+ }),
197
+ post: buildCommand({
198
+ parameters: {
199
+ flags: {
200
+ room: {
201
+ kind: 'parsed',
202
+ parse: parseString,
203
+ brief: 'Room alias, URL, or token',
204
+ placeholder: 'alias-or-url-or-token',
205
+ },
206
+ path: {
207
+ kind: 'parsed',
208
+ parse: parseString,
209
+ optional: true,
210
+ brief: 'Fresh room path for the posted Markdown file',
211
+ placeholder: 'path',
212
+ },
213
+ json: {
214
+ kind: 'boolean',
215
+ default: false,
216
+ withNegated: false,
217
+ brief: 'Print a stable JSON result',
218
+ },
219
+ },
220
+ positional: {
221
+ kind: 'tuple',
222
+ parameters: [
223
+ {
224
+ parse: parseString,
225
+ placeholder: 'file.md',
226
+ brief: 'Fresh Markdown file to post into accepted room state',
227
+ },
228
+ ],
229
+ },
230
+ },
231
+ docs: {
232
+ brief: 'Post a fresh Markdown file into accepted room state',
233
+ customUsage: ['<file.md> --room <alias-or-url-or-token> [--path <room-path>] [--json]'],
234
+ },
235
+ async func(flags, filePath) {
236
+ const result = await postMarkdown({
237
+ cwd: this.cwd,
238
+ filePath,
239
+ room: flags.room,
240
+ path: flags.path,
241
+ });
242
+ if (flags.json)
243
+ writeJson(this, result);
244
+ else
245
+ writePostHuman(this, result);
246
+ },
247
+ }),
248
+ propose: buildCommand({
249
+ parameters: {
250
+ flags: {
251
+ room: {
252
+ kind: 'parsed',
253
+ parse: parseString,
254
+ brief: 'Room alias, URL, or token',
255
+ placeholder: 'alias-or-url-or-token',
256
+ },
257
+ path: {
258
+ kind: 'parsed',
259
+ parse: parseString,
260
+ optional: true,
261
+ brief: 'Room path for a single-file proposal',
262
+ placeholder: 'path',
263
+ },
264
+ title: {
265
+ kind: 'parsed',
266
+ parse: parseString,
267
+ optional: true,
268
+ brief: 'Proposal title assigned to the encrypted record',
269
+ placeholder: 'text',
270
+ },
271
+ comment: {
272
+ kind: 'parsed',
273
+ parse: parseString,
274
+ optional: true,
275
+ brief: 'Proposal comment assigned to the encrypted record',
276
+ placeholder: 'text',
277
+ },
278
+ json: {
279
+ kind: 'boolean',
280
+ default: false,
281
+ withNegated: false,
282
+ brief: 'Print a stable JSON result',
283
+ },
284
+ },
285
+ positional: {
286
+ kind: 'tuple',
287
+ parameters: [
288
+ {
289
+ parse: parseString,
290
+ placeholder: 'file.md',
291
+ brief: 'Markdown file to submit as a proposal',
292
+ },
293
+ ],
294
+ },
295
+ },
296
+ docs: {
297
+ brief: 'Submit an encrypted whole-document proposal',
298
+ customUsage: ['<file-or-directory> --room <alias-or-url-or-token> [--path <room-path>] [--title <text>] [--comment <text>] [--json]'],
299
+ },
300
+ async func(flags, filePath) {
301
+ const result = await proposeMarkdown({
302
+ cwd: this.cwd,
303
+ filePath,
304
+ room: flags.room,
305
+ path: flags.path,
306
+ title: flags.title,
307
+ comment: flags.comment,
308
+ });
309
+ if (flags.json)
310
+ writeJson(this, result);
311
+ else
312
+ writeProposeHuman(this, result);
313
+ },
314
+ }),
315
+ proposals: buildCommand({
316
+ parameters: {
317
+ flags: roomOnlyFlags(),
318
+ },
319
+ docs: {
320
+ brief: 'List encrypted room proposals',
321
+ customUsage: ['--room <alias-or-url-or-token> [--json]'],
322
+ },
323
+ async func(flags) {
324
+ const result = await listProposals({
325
+ cwd: this.cwd,
326
+ room: flags.room,
327
+ });
328
+ if (flags.json)
329
+ writeJson(this, result);
330
+ else
331
+ writeProposalsHuman(this, result);
332
+ },
333
+ }),
334
+ context: buildCommand({
335
+ parameters: {
336
+ flags: roomOnlyFlags(),
337
+ },
338
+ docs: {
339
+ brief: 'Print a redacted agent context packet for a room',
340
+ customUsage: ['--room <alias-or-url-or-token> [--json]'],
341
+ },
342
+ async func(flags) {
343
+ const result = await roomContext({
344
+ cwd: this.cwd,
345
+ room: flags.room,
346
+ });
347
+ writeJson(this, result);
348
+ },
349
+ }),
350
+ resume: buildCommand({
351
+ parameters: {
352
+ flags: {
353
+ room: {
354
+ kind: 'parsed',
355
+ parse: parseString,
356
+ brief: 'Room alias, URL, or token',
357
+ placeholder: 'alias-or-url-or-token',
358
+ },
359
+ alias: {
360
+ kind: 'parsed',
361
+ parse: parseString,
362
+ optional: true,
363
+ brief: 'Local alias to save when resuming from a URL or token',
364
+ placeholder: 'name',
365
+ },
366
+ output: {
367
+ kind: 'parsed',
368
+ parse: parseString,
369
+ optional: true,
370
+ brief: 'Directory or file path for accepted Markdown export',
371
+ placeholder: 'path',
372
+ },
373
+ json: jsonFlag(),
374
+ },
375
+ },
376
+ docs: {
377
+ brief: 'Resume an encrypted room from a saved alias or explicit room reference',
378
+ customUsage: ['--room <alias-or-url-or-token> [--alias <name>] [--output <path>] [--json]'],
379
+ },
380
+ async func(flags) {
381
+ const result = await resumeRoom({
382
+ cwd: this.cwd,
383
+ room: flags.room,
384
+ alias: flags.alias,
385
+ outputPath: flags.output,
386
+ commandPrefix: this.commandPrefix,
387
+ });
388
+ if (flags.json)
389
+ writeJson(this, result);
390
+ else
391
+ writeResumeHuman(this, result);
392
+ },
393
+ }),
394
+ bootstrap: buildCommand({
395
+ parameters: {
396
+ flags: {
397
+ room: {
398
+ kind: 'parsed',
399
+ parse: parseString,
400
+ brief: 'Room alias, URL, or token',
401
+ placeholder: 'alias-or-url-or-token',
402
+ },
403
+ alias: {
404
+ kind: 'parsed',
405
+ parse: parseString,
406
+ optional: true,
407
+ brief: 'Local alias to save when bootstrapping from a URL or token',
408
+ placeholder: 'name',
409
+ },
410
+ output: {
411
+ kind: 'parsed',
412
+ parse: parseString,
413
+ brief: 'Directory for accepted Markdown project files',
414
+ placeholder: 'dir',
415
+ },
416
+ skipSkill: {
417
+ kind: 'boolean',
418
+ default: false,
419
+ withNegated: false,
420
+ brief: 'Skip bundled Fold skill install/update',
421
+ },
422
+ skillScope: {
423
+ kind: 'parsed',
424
+ parse: buildChoiceParser(['project', 'global', 'all']),
425
+ default: 'all',
426
+ brief: 'Skill install target scope',
427
+ placeholder: 'project|global|all',
428
+ },
429
+ nextCommandPrefix: {
430
+ kind: 'parsed',
431
+ parse: parseString,
432
+ optional: true,
433
+ brief: 'Override printed follow-up command prefix',
434
+ placeholder: 'command',
435
+ },
436
+ json: jsonFlag(),
437
+ },
438
+ },
439
+ docs: {
440
+ brief: 'Install the Fold skill and resume an encrypted room for agent work',
441
+ customUsage: ['--room <alias-or-url-or-token> [--alias <name>] [--output <dir>] [--json]'],
442
+ },
443
+ async func(flags) {
444
+ const result = await bootstrapRoom({
445
+ cwd: this.cwd,
446
+ room: flags.room,
447
+ alias: flags.alias,
448
+ outputPath: flags.output,
449
+ skipSkill: flags.skipSkill,
450
+ skillScope: flags.skillScope,
451
+ nextCommandPrefix: flags.nextCommandPrefix,
452
+ });
453
+ if (flags.json)
454
+ writeJson(this, result);
455
+ else
456
+ writeBootstrapHuman(this, result);
457
+ },
458
+ }),
459
+ skill: buildRouteMap({
460
+ routes: {
461
+ install: skillCommand('update'),
462
+ update: skillCommand('update'),
463
+ status: skillCommand('status'),
464
+ },
465
+ defaultCommand: 'install',
466
+ docs: {
467
+ brief: 'Install or inspect the bundled Fold agent skill',
468
+ },
469
+ }),
470
+ comments: buildCommand({
471
+ parameters: {
472
+ flags: {
473
+ room: {
474
+ kind: 'parsed',
475
+ parse: parseString,
476
+ brief: 'Room alias, URL, or token',
477
+ placeholder: 'alias-or-url-or-token',
478
+ },
479
+ path: {
480
+ kind: 'parsed',
481
+ parse: parseString,
482
+ optional: true,
483
+ brief: 'Limit comments to a room file path',
484
+ placeholder: 'path',
485
+ },
486
+ type: {
487
+ kind: 'parsed',
488
+ parse: buildChoiceParser(['all', 'comment', 'request']),
489
+ optional: true,
490
+ brief: 'Limit comments by thread type',
491
+ placeholder: 'all|comment|request',
492
+ },
493
+ open: {
494
+ kind: 'boolean',
495
+ default: false,
496
+ withNegated: false,
497
+ brief: 'Only show unresolved comments or requests',
498
+ },
499
+ json: jsonFlag(),
500
+ },
501
+ },
502
+ docs: {
503
+ brief: 'List encrypted room comments',
504
+ customUsage: ['--room <alias-or-url-or-token> [--path <room-path>] [--type all|comment|request] [--open] [--json]'],
505
+ },
506
+ async func(flags) {
507
+ const result = await listComments({
508
+ cwd: this.cwd,
509
+ room: flags.room,
510
+ path: flags.path,
511
+ type: flags.type,
512
+ open: flags.open,
513
+ });
514
+ if (flags.json)
515
+ writeJson(this, result);
516
+ else
517
+ writeCommentsHuman(this, result);
518
+ },
519
+ }),
520
+ requests: buildCommand({
521
+ parameters: {
522
+ flags: {
523
+ room: {
524
+ kind: 'parsed',
525
+ parse: parseString,
526
+ brief: 'Room alias, URL, or token',
527
+ placeholder: 'alias-or-url-or-token',
528
+ },
529
+ path: {
530
+ kind: 'parsed',
531
+ parse: parseString,
532
+ optional: true,
533
+ brief: 'Limit requests to a room file path',
534
+ placeholder: 'path',
535
+ },
536
+ open: {
537
+ kind: 'boolean',
538
+ default: true,
539
+ withNegated: true,
540
+ brief: 'Only show unresolved requests',
541
+ },
542
+ json: jsonFlag(),
543
+ },
544
+ },
545
+ docs: {
546
+ brief: 'List open encrypted agent requests',
547
+ customUsage: ['--room <alias-or-url-or-token> [--path <room-path>] [--no-open] [--json]'],
548
+ },
549
+ async func(flags) {
550
+ const result = await listComments({
551
+ cwd: this.cwd,
552
+ room: flags.room,
553
+ path: flags.path,
554
+ type: 'request',
555
+ open: flags.open,
556
+ });
557
+ if (flags.json)
558
+ writeJson(this, result);
559
+ else
560
+ writeCommentsHuman(this, result);
561
+ },
562
+ }),
563
+ comment: buildCommand({
564
+ parameters: {
565
+ flags: {
566
+ room: {
567
+ kind: 'parsed',
568
+ parse: parseString,
569
+ brief: 'Room alias, URL, or token',
570
+ placeholder: 'alias-or-url-or-token',
571
+ },
572
+ path: {
573
+ kind: 'parsed',
574
+ parse: parseString,
575
+ optional: true,
576
+ brief: 'Room file path for this comment',
577
+ placeholder: 'path',
578
+ },
579
+ quote: {
580
+ kind: 'parsed',
581
+ parse: parseString,
582
+ optional: true,
583
+ brief: 'Selected text to anchor this comment',
584
+ placeholder: 'text',
585
+ },
586
+ type: {
587
+ kind: 'parsed',
588
+ parse: buildChoiceParser(['comment', 'request']),
589
+ optional: true,
590
+ brief: 'Thread type to create',
591
+ placeholder: 'comment|request',
592
+ },
593
+ text: {
594
+ kind: 'parsed',
595
+ parse: parseString,
596
+ brief: 'Comment text assigned to the encrypted record',
597
+ placeholder: 'text',
598
+ },
599
+ json: jsonFlag(),
600
+ },
601
+ },
602
+ docs: {
603
+ brief: 'Add an encrypted comment to a room file',
604
+ customUsage: ['--room <alias-or-url-or-token> --text <text> [--path <room-path>] [--quote <text>] [--type comment|request] [--json]'],
605
+ },
606
+ async func(flags) {
607
+ const result = await addComment({
608
+ cwd: this.cwd,
609
+ room: flags.room,
610
+ path: flags.path,
611
+ quote: flags.quote,
612
+ type: flags.type === 'request' ? 'request' : 'note',
613
+ text: flags.text,
614
+ });
615
+ if (flags.json)
616
+ writeJson(this, result);
617
+ else
618
+ writeCommentHuman(this, result);
619
+ },
620
+ }),
621
+ reply: buildCommand({
622
+ parameters: {
623
+ flags: {
624
+ room: {
625
+ kind: 'parsed',
626
+ parse: parseString,
627
+ brief: 'Room alias, URL, or token',
628
+ placeholder: 'alias-or-url-or-token',
629
+ },
630
+ text: {
631
+ kind: 'parsed',
632
+ parse: parseString,
633
+ brief: 'Reply text assigned to the encrypted record',
634
+ placeholder: 'text',
635
+ },
636
+ json: jsonFlag(),
637
+ },
638
+ positional: {
639
+ kind: 'tuple',
640
+ parameters: [
641
+ {
642
+ parse: parseString,
643
+ placeholder: 'comment-id',
644
+ brief: 'Comment id to reply to',
645
+ },
646
+ ],
647
+ },
648
+ },
649
+ docs: {
650
+ brief: 'Reply to an encrypted room comment',
651
+ customUsage: ['<comment-id> --room <alias-or-url-or-token> --text <text> [--json]'],
652
+ },
653
+ async func(flags, commentId) {
654
+ const result = await replyToComment({
655
+ cwd: this.cwd,
656
+ room: flags.room,
657
+ commentId,
658
+ text: flags.text,
659
+ });
660
+ if (flags.json)
661
+ writeJson(this, result);
662
+ else
663
+ writeCommentHuman(this, result);
664
+ },
665
+ }),
666
+ 'show-proposal': buildCommand({
667
+ parameters: {
668
+ flags: roomOnlyFlags(),
669
+ positional: {
670
+ kind: 'tuple',
671
+ parameters: [
672
+ {
673
+ parse: parseString,
674
+ placeholder: 'proposal-id',
675
+ brief: 'Proposal id to decrypt and show',
676
+ },
677
+ ],
678
+ },
679
+ },
680
+ docs: {
681
+ brief: 'Show one encrypted proposal',
682
+ customUsage: ['<proposal-id> --room <alias-or-url-or-token> [--json]'],
683
+ },
684
+ async func(flags, proposalId) {
685
+ const result = await showProposal({
686
+ cwd: this.cwd,
687
+ room: flags.room,
688
+ proposalId,
689
+ });
690
+ if (flags.json)
691
+ writeJson(this, result);
692
+ else
693
+ writeShowProposalHuman(this, result);
694
+ },
695
+ }),
696
+ accept: buildCommand({
697
+ parameters: {
698
+ flags: roomOnlyFlags(),
699
+ positional: {
700
+ kind: 'tuple',
701
+ parameters: [
702
+ {
703
+ parse: parseString,
704
+ placeholder: 'proposal-id',
705
+ brief: 'Proposal id to accept',
706
+ },
707
+ ],
708
+ },
709
+ },
710
+ docs: {
711
+ brief: 'Accept an encrypted proposal and append canonical Markdown',
712
+ customUsage: ['<proposal-id> --room <alias-or-url-or-token> [--json]'],
713
+ },
714
+ async func(flags, proposalId) {
715
+ const result = await acceptProposal({
716
+ cwd: this.cwd,
717
+ room: flags.room,
718
+ proposalId,
719
+ });
720
+ if (flags.json)
721
+ writeJson(this, result);
722
+ else
723
+ writeDecisionHuman(this, result);
724
+ },
725
+ }),
726
+ reject: buildCommand({
727
+ parameters: {
728
+ flags: roomOnlyFlags(),
729
+ positional: {
730
+ kind: 'tuple',
731
+ parameters: [
732
+ {
733
+ parse: parseString,
734
+ placeholder: 'proposal-id',
735
+ brief: 'Proposal id to reject',
736
+ },
737
+ ],
738
+ },
739
+ },
740
+ docs: {
741
+ brief: 'Reject an encrypted proposal',
742
+ customUsage: ['<proposal-id> --room <alias-or-url-or-token> [--json]'],
743
+ },
744
+ async func(flags, proposalId) {
745
+ const result = await rejectProposal({
746
+ cwd: this.cwd,
747
+ room: flags.room,
748
+ proposalId,
749
+ });
750
+ if (flags.json)
751
+ writeJson(this, result);
752
+ else
753
+ writeDecisionHuman(this, result);
754
+ },
755
+ }),
756
+ room: buildRouteMap({
757
+ routes: {
758
+ create: buildCommand({
759
+ parameters: {
760
+ flags: {
761
+ alias: {
762
+ kind: 'parsed',
763
+ parse: parseString,
764
+ brief: 'Local alias for this new room',
765
+ placeholder: 'name',
766
+ },
767
+ server: {
768
+ kind: 'parsed',
769
+ parse: parseString,
770
+ optional: true,
771
+ brief: 'Compatibility shorthand for app and sync URL',
772
+ placeholder: 'url',
773
+ },
774
+ appUrl: {
775
+ kind: 'parsed',
776
+ parse: parseString,
777
+ optional: true,
778
+ brief: 'Human web app origin for generated room links',
779
+ placeholder: 'url',
780
+ },
781
+ syncUrl: {
782
+ kind: 'parsed',
783
+ parse: parseString,
784
+ optional: true,
785
+ brief: 'Append-log API/WebSocket origin',
786
+ placeholder: 'url',
787
+ },
788
+ json: jsonFlag(),
789
+ },
790
+ },
791
+ docs: {
792
+ brief: 'Create an empty encrypted project room',
793
+ customUsage: ['--alias <name> [--server <url>] [--app-url <url>] [--sync-url <url>] [--json]'],
794
+ },
795
+ async func(flags) {
796
+ const result = await createRoomProfile({
797
+ cwd: this.cwd,
798
+ alias: flags.alias,
799
+ serverUrl: flags.server,
800
+ appUrl: flags.appUrl,
801
+ syncUrl: flags.syncUrl,
802
+ });
803
+ if (flags.json)
804
+ writeJson(this, result);
805
+ else
806
+ writeRoomCreateHuman(this, result);
807
+ },
808
+ }),
809
+ add: buildCommand({
810
+ parameters: {
811
+ flags: {
812
+ alias: {
813
+ kind: 'parsed',
814
+ parse: parseString,
815
+ brief: 'Local alias for this room',
816
+ placeholder: 'name',
817
+ },
818
+ json: jsonFlag(),
819
+ },
820
+ positional: {
821
+ kind: 'tuple',
822
+ parameters: [
823
+ {
824
+ parse: parseString,
825
+ placeholder: 'url-or-token',
826
+ brief: 'Secret Fold room URL or token',
827
+ },
828
+ ],
829
+ },
830
+ },
831
+ docs: {
832
+ brief: 'Import a room URL/token and save a local alias',
833
+ customUsage: ['<url-or-token> --alias <name> [--json]'],
834
+ },
835
+ async func(flags, room) {
836
+ const result = await addRoomProfile({ cwd: this.cwd, room, alias: flags.alias });
837
+ if (flags.json)
838
+ writeJson(this, result);
839
+ else
840
+ writeRoomProfileHuman(this, result);
841
+ },
842
+ }),
843
+ list: buildCommand({
844
+ parameters: {
845
+ flags: { json: jsonFlag() },
846
+ },
847
+ docs: {
848
+ brief: 'List saved room aliases',
849
+ customUsage: ['[--json]'],
850
+ },
851
+ async func(flags) {
852
+ const result = await listRoomProfiles({ cwd: this.cwd });
853
+ if (flags.json)
854
+ writeJson(this, result);
855
+ else
856
+ writeRoomListHuman(this, result);
857
+ },
858
+ }),
859
+ show: buildCommand({
860
+ parameters: {
861
+ flags: { json: jsonFlag() },
862
+ positional: {
863
+ kind: 'tuple',
864
+ parameters: [
865
+ {
866
+ parse: parseString,
867
+ placeholder: 'alias',
868
+ brief: 'Saved room alias',
869
+ },
870
+ ],
871
+ },
872
+ },
873
+ docs: {
874
+ brief: 'Show one saved room profile',
875
+ customUsage: ['<alias> [--json]'],
876
+ },
877
+ async func(flags, alias) {
878
+ const result = await showRoomProfile({ cwd: this.cwd, alias });
879
+ if (flags.json)
880
+ writeJson(this, result);
881
+ else
882
+ writeRoomProfileHuman(this, result);
883
+ },
884
+ }),
885
+ 'set-url': buildCommand({
886
+ parameters: {
887
+ flags: {
888
+ appUrl: {
889
+ kind: 'parsed',
890
+ parse: parseString,
891
+ optional: true,
892
+ brief: 'Human web app origin',
893
+ placeholder: 'url',
894
+ },
895
+ syncUrl: {
896
+ kind: 'parsed',
897
+ parse: parseString,
898
+ optional: true,
899
+ brief: 'Append-log API/WebSocket origin',
900
+ placeholder: 'url',
901
+ },
902
+ json: jsonFlag(),
903
+ },
904
+ positional: {
905
+ kind: 'tuple',
906
+ parameters: [
907
+ {
908
+ parse: parseString,
909
+ placeholder: 'alias',
910
+ brief: 'Saved room alias',
911
+ },
912
+ ],
913
+ },
914
+ },
915
+ docs: {
916
+ brief: 'Update app/sync URLs for a saved room',
917
+ customUsage: ['<alias> [--app-url <url>] [--sync-url <url>] [--json]'],
918
+ },
919
+ async func(flags, alias) {
920
+ const result = await setRoomProfileUrls({
921
+ cwd: this.cwd,
922
+ alias,
923
+ appUrl: flags.appUrl,
924
+ syncUrl: flags.syncUrl,
925
+ });
926
+ if (flags.json)
927
+ writeJson(this, result);
928
+ else
929
+ writeRoomProfileHuman(this, result);
930
+ },
931
+ }),
932
+ forget: buildCommand({
933
+ parameters: {
934
+ flags: { json: jsonFlag() },
935
+ positional: {
936
+ kind: 'tuple',
937
+ parameters: [
938
+ {
939
+ parse: parseString,
940
+ placeholder: 'alias',
941
+ brief: 'Saved room alias',
942
+ },
943
+ ],
944
+ },
945
+ },
946
+ docs: {
947
+ brief: 'Forget a saved local room alias',
948
+ customUsage: ['<alias> [--json]'],
949
+ },
950
+ async func(flags, alias) {
951
+ const result = await forgetRoomProfile({ cwd: this.cwd, alias });
952
+ if (flags.json)
953
+ writeJson(this, result);
954
+ else
955
+ writeRoomForgetHuman(this, result);
956
+ },
957
+ }),
958
+ invite: buildCommand({
959
+ parameters: {
960
+ flags: {
961
+ for: {
962
+ kind: 'parsed',
963
+ parse: buildChoiceParser(['human', 'agent']),
964
+ default: 'human',
965
+ brief: 'Invite audience',
966
+ placeholder: 'human|agent',
967
+ },
968
+ json: jsonFlag(),
969
+ },
970
+ positional: {
971
+ kind: 'tuple',
972
+ parameters: [
973
+ {
974
+ parse: parseString,
975
+ placeholder: 'alias',
976
+ brief: 'Saved room alias',
977
+ },
978
+ ],
979
+ },
980
+ },
981
+ docs: {
982
+ brief: 'Print a human or agent invite for a saved room',
983
+ customUsage: ['<alias> [--for human|agent] [--json]'],
984
+ },
985
+ async func(flags, alias) {
986
+ const result = await createRoomInvite({ cwd: this.cwd, alias, audience: flags.for });
987
+ if (flags.json)
988
+ writeJson(this, result);
989
+ else
990
+ writeRoomInviteHuman(this, result);
991
+ },
992
+ }),
993
+ },
994
+ docs: {
995
+ brief: 'Manage saved room aliases and invites',
996
+ },
997
+ }),
998
+ status: buildCommand({
999
+ parameters: {
1000
+ flags: {
1001
+ room: {
1002
+ kind: 'parsed',
1003
+ parse: parseString,
1004
+ brief: 'Room alias, URL, or token',
1005
+ placeholder: 'alias-or-url-or-token',
1006
+ },
1007
+ json: {
1008
+ kind: 'boolean',
1009
+ default: false,
1010
+ withNegated: false,
1011
+ brief: 'Print a stable JSON result',
1012
+ },
1013
+ },
1014
+ },
1015
+ docs: {
1016
+ brief: 'Show local room metadata status',
1017
+ customUsage: ['--room <alias-or-url-or-token> [--json]'],
1018
+ },
1019
+ async func(flags) {
1020
+ const result = await roomStatus({
1021
+ cwd: this.cwd,
1022
+ room: flags.room,
1023
+ });
1024
+ if (flags.json)
1025
+ writeJson(this, result);
1026
+ else
1027
+ writeStatusHuman(this, result);
1028
+ },
1029
+ }),
1030
+ },
1031
+ docs: {
1032
+ brief: 'Encrypted Markdown room CLI',
1033
+ fullDescription: 'Publish, export, and inspect encrypted Markdown room metadata.',
1034
+ },
1035
+ }), {
1036
+ name: 'fold-agent',
1037
+ scanner: {
1038
+ caseStyle: 'allow-kebab-for-camel',
1039
+ },
1040
+ documentation: {
1041
+ caseStyle: 'convert-camel-to-kebab',
1042
+ },
1043
+ determineExitCode: () => 1,
1044
+ });
1045
+ export async function runFoldCli(inputs, context) {
1046
+ await run(app, inputs, context);
1047
+ }
1048
+ function parseString(input) {
1049
+ return input;
1050
+ }
1051
+ function roomOnlyFlags() {
1052
+ return {
1053
+ room: {
1054
+ kind: 'parsed',
1055
+ parse: parseString,
1056
+ brief: 'Room alias, URL, or token',
1057
+ placeholder: 'alias-or-url-or-token',
1058
+ },
1059
+ json: jsonFlag(),
1060
+ };
1061
+ }
1062
+ function jsonFlag() {
1063
+ return {
1064
+ kind: 'boolean',
1065
+ default: false,
1066
+ withNegated: false,
1067
+ brief: 'Print a stable JSON result',
1068
+ };
1069
+ }
1070
+ function skillCommand(mode) {
1071
+ return buildCommand({
1072
+ parameters: {
1073
+ flags: {
1074
+ scope: {
1075
+ kind: 'parsed',
1076
+ parse: buildChoiceParser(['project', 'global']),
1077
+ optional: true,
1078
+ brief: 'Skill install target scope',
1079
+ placeholder: 'project|global',
1080
+ },
1081
+ all: {
1082
+ kind: 'boolean',
1083
+ default: false,
1084
+ withNegated: false,
1085
+ brief: 'Target project and known global skill locations',
1086
+ },
1087
+ json: jsonFlag(),
1088
+ },
1089
+ },
1090
+ docs: {
1091
+ brief: mode === 'status' ? 'Inspect bundled Fold skill targets' : 'Install or update the bundled Fold skill',
1092
+ customUsage: ['[--scope project|global] [--all] [--json]'],
1093
+ },
1094
+ async func(flags) {
1095
+ const scope = skillScopeFromFlags(flags);
1096
+ const result = await installFoldSkill({
1097
+ cwd: this.cwd,
1098
+ scope,
1099
+ mode,
1100
+ });
1101
+ if (flags.json)
1102
+ writeJson(this, result);
1103
+ else
1104
+ writeSkillHuman(this, result);
1105
+ },
1106
+ });
1107
+ }
1108
+ function skillScopeFromFlags(flags) {
1109
+ if (flags.all)
1110
+ return 'all';
1111
+ return flags.scope ?? 'all';
1112
+ }
1113
+ //# sourceMappingURL=app.js.map