@openparachute/vault 0.6.5-rc.15 → 0.6.5-rc.16
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/core/src/seed-packs.test.ts +31 -1
- package/core/src/seed-packs.ts +142 -35
- package/package.json +1 -1
- package/src/onboarding-seed.test.ts +5 -2
- package/src/vault-create.test.ts +1 -1
|
@@ -23,6 +23,9 @@ import {
|
|
|
23
23
|
applySeedPack,
|
|
24
24
|
CAPTURE_ANYTHING_PATH,
|
|
25
25
|
CONNECT_AI_PATH,
|
|
26
|
+
DEFAULT_VAULT_DESCRIPTION,
|
|
27
|
+
IMPORTED_VAULT_DESCRIPTION,
|
|
28
|
+
YOURS_TO_KEEP_PATH,
|
|
26
29
|
GETTING_STARTED_CONTENT,
|
|
27
30
|
GETTING_STARTED_PACK,
|
|
28
31
|
GETTING_STARTED_PATH,
|
|
@@ -282,11 +285,38 @@ describe("getting-started pack", () => {
|
|
|
282
285
|
// exist. It names the pack + the way to add it.
|
|
283
286
|
expect(GETTING_STARTED_CONTENT).not.toContain("[[Surface Starter]]");
|
|
284
287
|
expect(GETTING_STARTED_CONTENT).toContain("Surface Starter");
|
|
285
|
-
|
|
288
|
+
// Points at the add-pack flow (console affordance / CLI) without spelling
|
|
289
|
+
// out a terminal command — de-emphasise the CLI (Aaron 2026-07-06).
|
|
290
|
+
expect(GETTING_STARTED_CONTENT).toContain("add-pack");
|
|
286
291
|
// The surface packages are still named for discoverability.
|
|
287
292
|
expect(GETTING_STARTED_CONTENT).toContain("@openparachute/surface-client");
|
|
288
293
|
expect(GETTING_STARTED_CONTENT).toContain("@openparachute/surface-render");
|
|
289
294
|
});
|
|
295
|
+
|
|
296
|
+
test("Getting Started is onboarding-first + carries no dead CLI guidance (2026-07-06 rewrite)", () => {
|
|
297
|
+
// Two-part structure: onboarding conversation leads, mechanics reference follows.
|
|
298
|
+
expect(GETTING_STARTED_CONTENT).toContain("## Part 1 — Onboarding the person");
|
|
299
|
+
expect(GETTING_STARTED_CONTENT).toContain("## Part 2 — Vault mechanics");
|
|
300
|
+
// Points the person at the five human guides by name (all resolve to seeds).
|
|
301
|
+
for (const g of [WELCOME_PATH, CAPTURE_ANYTHING_PATH, TAGS_GRAPH_PATH, CONNECT_AI_PATH, YOURS_TO_KEEP_PATH]) {
|
|
302
|
+
expect(GETTING_STARTED_CONTENT).toContain("[[" + g + "]]");
|
|
303
|
+
}
|
|
304
|
+
// The old live bug: it told cloud AIs to run a CLI that doesn't exist there.
|
|
305
|
+
expect(GETTING_STARTED_CONTENT).not.toContain("parachute-vault import");
|
|
306
|
+
// Data-in leads with the import UI + MCP bridge, not the terminal.
|
|
307
|
+
expect(GETTING_STARTED_CONTENT).toContain("Import button");
|
|
308
|
+
expect(GETTING_STARTED_CONTENT).toContain("over MCP");
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("default vault-description constants orient + tell the AI to self-replace them", () => {
|
|
312
|
+
for (const d of [DEFAULT_VAULT_DESCRIPTION, IMPORTED_VAULT_DESCRIPTION]) {
|
|
313
|
+
expect(d.length).toBeGreaterThan(100);
|
|
314
|
+
expect(d).toContain("Getting Started");
|
|
315
|
+
expect(d).toContain("vault-info { description:"); // the self-replace instruction
|
|
316
|
+
}
|
|
317
|
+
expect(DEFAULT_VAULT_DESCRIPTION).toContain("brand-new");
|
|
318
|
+
expect(IMPORTED_VAULT_DESCRIPTION).toContain("imported");
|
|
319
|
+
});
|
|
290
320
|
});
|
|
291
321
|
|
|
292
322
|
describe("surface-starter pack", () => {
|
package/core/src/seed-packs.ts
CHANGED
|
@@ -34,6 +34,32 @@
|
|
|
34
34
|
|
|
35
35
|
import type { Store, TagFieldSchema } from "./types.ts";
|
|
36
36
|
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Default vault descriptions — the single source of truth
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The `vault-info` description a **brand-new** vault ships with. It's the first
|
|
43
|
+
* thing a connected AI reads about the vault, so it doubles as a nudge: orient
|
|
44
|
+
* the person, read the Getting Started brief, do one small real thing, and — once
|
|
45
|
+
* real structure lands — REPLACE this text with a current picture of the vault.
|
|
46
|
+
*
|
|
47
|
+
* Exported as the single source of truth; the runtimes (bun vault default seed +
|
|
48
|
+
* cloud vault DO) consume it in a follow-up PR. Not wired into `applySeedPack`
|
|
49
|
+
* here — a description is vault metadata, not a pack note.
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_VAULT_DESCRIPTION =
|
|
52
|
+
'This is a brand-new personal vault — just its starter guides so far; the person it belongs to is probably new to Parachute. Before helping them set it up, read the "Getting Started" note — it\'s your onboarding brief. Short version: start with a conversation, not a filing system; learn how they want to use this and where their notes live today; do one small real thing first. When the vault has real structure, replace this description (vault-info { description: "..." }) with a current picture of what lives here and how to work it — so every future session, yours or another AI\'s, starts oriented.';
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The `vault-info` description a vault gets when it was **imported/restored** —
|
|
56
|
+
* it arrived with content. Flips the AI's first job from seed-it to learn-it:
|
|
57
|
+
* orient over the existing shape, reflect it back, and only then replace this
|
|
58
|
+
* text with a current picture.
|
|
59
|
+
*/
|
|
60
|
+
export const IMPORTED_VAULT_DESCRIPTION =
|
|
61
|
+
'This vault was imported — it arrived with its own notes, tags, and history. Orient before you write: vault-info { include_stats: true }, list-tags, read a sample, and read "Getting Started" if present. Your first job is to learn the shape that\'s already here and reflect it back to the person — not to propose new structure cold. When you understand it, replace this description (vault-info { description: "..." }) with a current picture.';
|
|
62
|
+
|
|
37
63
|
// ---------------------------------------------------------------------------
|
|
38
64
|
// Pack shape
|
|
39
65
|
// ---------------------------------------------------------------------------
|
|
@@ -306,24 +332,98 @@ export const SURFACE_STARTER_PATH = "Surface Starter";
|
|
|
306
332
|
/**
|
|
307
333
|
* Body of the seeded `Getting Started` note.
|
|
308
334
|
*
|
|
309
|
-
* Voice: addressed to the connected AI ("you"), practical, SKILL.md-style.
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
335
|
+
* Voice: addressed to the connected AI ("you"), warm and practical, SKILL.md-style.
|
|
336
|
+
* ONE note, two labeled parts:
|
|
337
|
+
* - Part 1 — Onboarding the person: lead with a real conversation, leverage
|
|
338
|
+
* prior context, offer to survey their content, do one small real thing
|
|
339
|
+
* first, the data-in menu (import UI / MCP bridge / paste-and-file — NOT the
|
|
340
|
+
* CLI, NOT Obsidian-first), the arrived-with-content branch, and closing the
|
|
341
|
+
* loop by updating the vault description (see DEFAULT_VAULT_DESCRIPTION).
|
|
342
|
+
* - Part 2 — Vault mechanics: the preserved reference — what a vault is + the
|
|
343
|
+
* tool list, tags-vs-paths-vs-schemas, write gotchas, the custom-surface
|
|
344
|
+
* pointer, and "Adapt this note."
|
|
345
|
+
*
|
|
346
|
+
* Deliberately points AIs at the import UI + MCP bridge, never at a
|
|
347
|
+
* `parachute-vault import` CLI (that verb doesn't exist on cloud — the old copy
|
|
348
|
+
* shipped that live bug to every hosted user). Mentions the Surface Starter PACK
|
|
349
|
+
* by name (no wikilink — the note isn't seeded by default, and a dangling
|
|
350
|
+
* `[[Surface Starter]]` would sit unresolved on every fresh vault).
|
|
315
351
|
*/
|
|
316
352
|
export const GETTING_STARTED_CONTENT = `# Getting Started
|
|
317
353
|
|
|
318
|
-
This is the **start-here guide** for this Parachute vault —
|
|
319
|
-
\`SKILL.md
|
|
320
|
-
|
|
321
|
-
need to re-read it every session. It
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
354
|
+
This is the **start-here guide** for this Parachute vault — instructions for a
|
|
355
|
+
connected AI (you), like a \`SKILL.md\`. Read it when the vault is new, when
|
|
356
|
+
you're orienting yourself, or when the person says *"help me set up my
|
|
357
|
+
parachute."* You don't need to re-read it every session. It has two parts:
|
|
358
|
+
**how to onboard the person** (start there if they're new) and **vault
|
|
359
|
+
mechanics** (reference for operating the vault). It's a starting point, not a
|
|
360
|
+
script — and it's editable (see "Adapt this note" at the end).
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Part 1 — Onboarding the person
|
|
365
|
+
|
|
366
|
+
### Start with a conversation, not a filing system
|
|
367
|
+
|
|
368
|
+
If this vault is fresh, this is probably the person's first real session with
|
|
369
|
+
it. Don't start building — orient them, briefly, in your own words: this vault
|
|
370
|
+
is **their** memory, one place every AI they choose to connect can read and
|
|
371
|
+
write, and they can export all of it anytime as plain markdown. Then have a
|
|
372
|
+
real conversation:
|
|
373
|
+
|
|
374
|
+
- **How do they imagine using this?** A journal, a project brain, a people
|
|
375
|
+
directory, meeting notes, a commonplace book — or they don't know yet
|
|
376
|
+
(that's fine; capture-first works).
|
|
377
|
+
- **Where do their notes and data live now?** Another app, a pile of markdown,
|
|
378
|
+
another Parachute — or nowhere yet.
|
|
379
|
+
- **What's alive for them right now?** A project, a decision, a trip, a draft.
|
|
380
|
+
The first note should be about something real.
|
|
381
|
+
|
|
382
|
+
**Use what you already know.** If you have memory or context about this person
|
|
383
|
+
from working with them, bring it — propose the two or three kinds of
|
|
384
|
+
information *they specifically* would want here ("you mention a lot of book
|
|
385
|
+
ideas — want a place for those?"). Propose, confirm, then write; never
|
|
386
|
+
bulk-create structure they didn't agree to. You can also **offer to survey**
|
|
387
|
+
what they already have — "want me to look through what you've brought in and
|
|
388
|
+
suggest a few ways to organize it?" — then read a sample and propose, don't
|
|
389
|
+
impose.
|
|
390
|
+
|
|
391
|
+
### Do one small real thing first
|
|
392
|
+
|
|
393
|
+
The failure mode of every notes tool is over-organizing an empty vault. So:
|
|
394
|
+
**one small real thing this session.** Capture a thought they actually have,
|
|
395
|
+
file one document, or bring in one small batch — then stop and show them what
|
|
396
|
+
happened. Structure grows from real notes (that's Part 2's design vocabulary).
|
|
397
|
+
Setup is a relationship over many sessions, not an install step.
|
|
398
|
+
|
|
399
|
+
Five short guides ship in this vault for the person to read (tagged \`#guide\`):
|
|
400
|
+
[[Welcome to your vault 🪂]], [[Capture anything]], [[Tags and the graph]],
|
|
401
|
+
[[Connect your AI]], and [[Yours to keep]]. Point them there for anything you'd
|
|
402
|
+
otherwise lecture about — they're the return-point between sessions. If a
|
|
403
|
+
session ends mid-setup, leave a breadcrumb (update this note or the vault
|
|
404
|
+
description) so the next one picks up where you left off.
|
|
405
|
+
|
|
406
|
+
### If this vault already has content
|
|
407
|
+
|
|
408
|
+
Some vaults arrive full — an import, a restore, months of use. Then your first
|
|
409
|
+
job is to **learn it, not seed it**: \`vault-info { include_stats: true }\`,
|
|
410
|
+
\`list-tags\`, read a sample (\`query-notes { search: "..." }\`), then reflect the
|
|
411
|
+
shape back to the person and ask what's missing or wrong. Propose structure
|
|
412
|
+
only once you can describe what's already there.
|
|
413
|
+
|
|
414
|
+
### Close the loop: describe the vault
|
|
415
|
+
|
|
416
|
+
When the first real structure lands, update the vault description —
|
|
417
|
+
\`vault-info { description: "..." }\` — so every future session (yours or another
|
|
418
|
+
AI's) starts oriented: what this vault is for, its main tags, its conventions.
|
|
419
|
+
The default description says "brand-new vault"; once that stops being true,
|
|
420
|
+
replace it. Keep it a few sentences (the projection carries the schema detail,
|
|
421
|
+
and this note carries the richer conventions — see "Adapt this note"). Bringing
|
|
422
|
+
their existing data in is covered under "Bringing existing notes in" below.
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Part 2 — Vault mechanics
|
|
327
427
|
|
|
328
428
|
## What a Parachute vault is
|
|
329
429
|
|
|
@@ -417,33 +517,40 @@ A few behaviors worth knowing before you write at scale:
|
|
|
417
517
|
|
|
418
518
|
(Full design guide, with copy-paste examples: https://parachute.computer/scripting/)
|
|
419
519
|
|
|
420
|
-
##
|
|
520
|
+
## Bringing existing notes in
|
|
521
|
+
|
|
522
|
+
If the person already keeps notes somewhere, help them bring what matters —
|
|
523
|
+
start with what's alive for them, not the whole archive. What works today:
|
|
421
524
|
|
|
422
|
-
|
|
423
|
-
|
|
525
|
+
- **Connect the source over MCP (the flexible path).** If their AI client can
|
|
526
|
+
add other MCP servers — a Google Drive server, a Notion server, a filesystem
|
|
527
|
+
server — connect it alongside this vault in the same session. Then read from
|
|
528
|
+
there and \`create-note\` here: a selective, conversational migration, no
|
|
529
|
+
export file needed.
|
|
530
|
+
- **Paste and file.** They paste anything — a doc, a list, an export — and you
|
|
531
|
+
\`create-note\` it (batch mode for many at once).
|
|
532
|
+
- **Import a Parachute export.** Moving between Parachute vaults (cloud ⇄
|
|
533
|
+
self-host) is lossless — on Parachute Cloud, the console's Import button —
|
|
534
|
+
ids, tags, links, schemas, and attachments round-trip.
|
|
424
535
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
- **Ad hoc / pasted content:** just \`create-note\` it. Then help the operator tag
|
|
431
|
-
and schematize: read a sample of imported notes, propose a small tag
|
|
432
|
-
vocabulary, and apply it.
|
|
536
|
+
Bringing a whole Obsidian or Markdown library in is getting easier, and a
|
|
537
|
+
flexible import is on the way; for now the connect-over-MCP and paste paths
|
|
538
|
+
handle it without anyone touching a terminal. Whatever they bring, offer to
|
|
539
|
+
survey it and suggest a first structure — read a sample, propose a small tag
|
|
540
|
+
vocabulary, confirm, then apply. Don't impose structure silently.
|
|
433
541
|
|
|
434
|
-
After
|
|
435
|
-
\`list-tags\`
|
|
436
|
-
spot-check.
|
|
542
|
+
After bringing content in, orient: \`vault-info\` for the schema picture,
|
|
543
|
+
\`list-tags\` for the vocabulary that arrived, \`query-notes { search: "..." }\`
|
|
544
|
+
to spot-check.
|
|
437
545
|
|
|
438
546
|
## Later: a custom surface
|
|
439
547
|
|
|
440
548
|
Building a custom UI over the vault (a dashboard, a notes app) is usually **not**
|
|
441
|
-
the starting point — get the notes and structure right first.
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
\`
|
|
445
|
-
|
|
446
|
-
\`@openparachute/surface-client\` + \`@openparachute/surface-render\`.
|
|
549
|
+
the starting point — get the notes and structure right first. When the person
|
|
550
|
+
wants one, add the **Surface Starter** guide to this vault — an optional pack
|
|
551
|
+
(not installed by default) that covers building a surface with
|
|
552
|
+
\`@openparachute/surface-client\` + \`@openparachute/surface-render\`. On Parachute
|
|
553
|
+
Cloud it's the console's add-pack affordance.
|
|
447
554
|
|
|
448
555
|
## Adapt this note
|
|
449
556
|
|
package/package.json
CHANGED
|
@@ -82,7 +82,10 @@ describe("seedOnboardingNotes — default packs (welcome + getting-started)", ()
|
|
|
82
82
|
expect(gs!.content).toContain("Tags = types");
|
|
83
83
|
expect(gs!.content).toContain("Paths = organization");
|
|
84
84
|
expect(gs!.content).toContain("Schemas = typed metadata fields");
|
|
85
|
-
|
|
85
|
+
// Data-in leads with the import UI + MCP bridge; the old `parachute-vault
|
|
86
|
+
// import` CLI line (a live bug on cloud) is gone (2026-07-06 rewrite).
|
|
87
|
+
expect(gs!.content).not.toContain("parachute-vault import");
|
|
88
|
+
expect(gs!.content).toContain("Bringing existing notes in");
|
|
86
89
|
expect(gs!.content).toContain("Adapt this note");
|
|
87
90
|
|
|
88
91
|
// The welcome ring: five person-voiced guide notes.
|
|
@@ -200,7 +203,7 @@ describe("seedOnboardingNotes — default packs (welcome + getting-started)", ()
|
|
|
200
203
|
// Getting Started mentions the surface-starter PACK — not a wikilink to a
|
|
201
204
|
// note that the default seed no longer creates.
|
|
202
205
|
expect(gs!.content).not.toContain("[[Surface Starter]]");
|
|
203
|
-
expect(gs!.content).toContain("add-pack
|
|
206
|
+
expect(gs!.content).toContain("add-pack");
|
|
204
207
|
});
|
|
205
208
|
|
|
206
209
|
test("idempotent: a second seed run skips all notes (does not duplicate)", async () => {
|
package/src/vault-create.test.ts
CHANGED
|
@@ -414,7 +414,7 @@ describe("vault create — default pack seeding (welcome + getting-started)", ()
|
|
|
414
414
|
// Surface Starter is out of the default seed — no note, no dangling link.
|
|
415
415
|
expect(notes.find((n) => n.path === "Surface Starter")).toBeUndefined();
|
|
416
416
|
expect(gs!.content).not.toContain("[[Surface Starter]]");
|
|
417
|
-
expect(gs!.content).toContain("add-pack
|
|
417
|
+
expect(gs!.content).toContain("add-pack");
|
|
418
418
|
|
|
419
419
|
// The capture tag Notes requires arrives with the welcome pack, alongside
|
|
420
420
|
// the guide (skill-file) + pinned tags — and nothing else (fresh-vault
|