Skip to content

Commit bfff080

Browse files
cailmdaleyclaude
andcommitted
feat: auto-clone tapestries template + viewer setup reference
felt tapestry export now offers to clone the template repo if ~/.felt/tapestries/ doesn't exist. Added references/viewer-setup.md to the tapestry skill covering local serving, GitHub Pages, and data layout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 96fea28 commit bfff080

File tree

3 files changed

+112
-4
lines changed

3 files changed

+112
-4
lines changed

cmd/skills/tapestry/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,7 @@ A tapestry grows through phases, and you can't skip them:
141141
3. **Living** — the tapestry continues to grow. New analyses add nodes; shaping keeps the narrative coherent.
142142

143143
A constitution (see `/constitution`) can drive each phase.
144+
145+
## References
146+
147+
- [references/viewer-setup.md](references/viewer-setup.md) — cloning the template, serving locally, GitHub Pages, data layout
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Tapestry Viewer Setup
2+
3+
The tapestry viewer is a static site that renders felt DAGs as navigable graphs. It lives in a standalone repo that you clone once; `felt tapestry export` writes data into it.
4+
5+
## First Time
6+
7+
```bash
8+
felt tapestry export # auto-clones the template if ~/.felt/tapestries/ doesn't exist
9+
```
10+
11+
Or manually:
12+
13+
```bash
14+
git clone --depth 1 https://github.com/cailmdaley/tapestries.git ~/.felt/tapestries
15+
```
16+
17+
## Exporting
18+
19+
From any project with `.felt/` fibers and `tapestry:` tags:
20+
21+
```bash
22+
felt tapestry export # writes to ~/.felt/tapestries/data/{project}/
23+
felt tapestry export --all-fibers # include all fibers for sidebar
24+
felt tapestry export --force # re-copy all artifacts
25+
felt tapestry export --name foo # override project name
26+
felt tapestry export --out /path/ # override output directory
27+
```
28+
29+
## Serving Locally
30+
31+
```bash
32+
npx serve -s ~/.felt/tapestries
33+
```
34+
35+
Open `http://localhost:3000`. The landing page lists available tapestries from `data/manifest.json`.
36+
37+
## GitHub Pages
38+
39+
1. Create a new repo from the [tapestries template](https://github.com/cailmdaley/tapestries)
40+
2. Enable Pages: Settings → Pages → Deploy from branch `main`, folder `/`
41+
3. Export and push:
42+
43+
```bash
44+
felt tapestry export --out /path/to/your-repo/data/myproject
45+
cd /path/to/your-repo
46+
git add -A && git commit -m "update tapestry" && git push
47+
```
48+
49+
Your tapestries will be at `https://<user>.github.io/<repo>/`.
50+
51+
## Data Layout
52+
53+
```
54+
~/.felt/tapestries/
55+
index.html # viewer (from template, rarely changes)
56+
assets/ # JS/CSS bundles
57+
data/
58+
manifest.json # city list (auto-updated by export)
59+
myproject/
60+
tapestry.json # DAG: nodes, links, evidence, staleness
61+
tapestry/ # artifact images
62+
specname/
63+
figure.png
64+
files/ # linked files (optional)
65+
```
66+
67+
## Keeping History Small
68+
69+
Artifact images accumulate. To cap repo size, periodically squash history:
70+
71+
```bash
72+
cd ~/.felt/tapestries
73+
KEEP=5
74+
COUNT=$(git rev-list --count HEAD)
75+
if [ "$COUNT" -gt "$KEEP" ]; then
76+
CUTPOINT=$(git rev-list HEAD | sed -n "${KEEP}p")
77+
REMOTE_URL=$(git remote get-url origin)
78+
git replace --graft "$CUTPOINT"
79+
git filter-repo --force --quiet
80+
git remote add origin "$REMOTE_URL"
81+
git push --force --set-upstream origin main
82+
fi
83+
```

cmd/tapestry.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package cmd
22

33
import (
4+
"bufio"
45
"fmt"
56
"os"
7+
"os/exec"
68
"path/filepath"
9+
"strings"
710

811
"github.com/cailmdaley/felt/internal/felt"
912
"github.com/cailmdaley/felt/internal/tapestry"
@@ -68,6 +71,8 @@ func init() {
6871
tapestryExportCmd.Flags().StringVar(&tapestryOut, "out", "", "Override output directory")
6972
}
7073

74+
const tapestriesTemplateURL = "https://github.com/cailmdaley/tapestries.git"
75+
7176
func defaultTapestriesRepo() (string, error) {
7277
home, err := os.UserHomeDir()
7378
if err != nil {
@@ -79,8 +84,24 @@ func defaultTapestriesRepo() (string, error) {
7984
return repoDir, nil
8085
}
8186

82-
return "", fmt.Errorf(
83-
"No tapestries repo found at %s/\nClone it: git clone git@github.com:cailmdaley/tapestries.git %s",
84-
repoDir, repoDir,
85-
)
87+
fmt.Printf("No tapestries repo found at %s/\n", repoDir)
88+
fmt.Printf("Clone the template viewer? [Y/n] ")
89+
reader := bufio.NewReader(os.Stdin)
90+
answer, _ := reader.ReadString('\n')
91+
answer = strings.TrimSpace(strings.ToLower(answer))
92+
if answer != "" && answer != "y" && answer != "yes" {
93+
return "", fmt.Errorf("aborted")
94+
}
95+
96+
fmt.Printf("Cloning %s...\n", tapestriesTemplateURL)
97+
clone := exec.Command("git", "clone", "--depth", "1", tapestriesTemplateURL, repoDir)
98+
clone.Stdout = os.Stdout
99+
clone.Stderr = os.Stderr
100+
if err := clone.Run(); err != nil {
101+
return "", fmt.Errorf("clone failed: %w", err)
102+
}
103+
104+
fmt.Printf("Tapestries viewer ready at %s\n", repoDir)
105+
fmt.Println("Serve locally: npx serve -s " + repoDir)
106+
return repoDir, nil
86107
}

0 commit comments

Comments
 (0)