@rubytech/create-maxy-code 0.1.96 → 0.1.98

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 (35) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  3. package/payload/platform/plugins/founder-pack/.claude-plugin/plugin.json +8 -0
  4. package/payload/platform/plugins/founder-pack/skills/investor-data-room/SKILL.md +218 -0
  5. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/business-plan-template.md +61 -0
  6. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/compliance-research-checklist.md +53 -0
  7. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/data-room-structure.md +77 -0
  8. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/deck-blueprint-template.md +38 -0
  9. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/design-tokens-application.md +79 -0
  10. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/html-pdf-pipeline.md +236 -0
  11. package/payload/platform/plugins/founder-pack/skills/investor-data-room/references/internal-workings-scrub.md +33 -0
  12. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  13. package/payload/platform/services/claude-session-manager/dist/http-server.js +125 -95
  14. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  15. package/payload/platform/services/claude-session-manager/scripts/stash-cleanup.sh +410 -0
  16. package/payload/premium-plugins/.claude-plugin/marketplace.json +5 -0
  17. package/payload/premium-plugins/founder-pack/.claude-plugin/plugin.json +8 -0
  18. package/payload/premium-plugins/founder-pack/skills/investor-data-room/SKILL.md +218 -0
  19. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/business-plan-template.md +61 -0
  20. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/compliance-research-checklist.md +53 -0
  21. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/data-room-structure.md +77 -0
  22. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/deck-blueprint-template.md +38 -0
  23. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/design-tokens-application.md +79 -0
  24. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/html-pdf-pipeline.md +236 -0
  25. package/payload/premium-plugins/founder-pack/skills/investor-data-room/references/internal-workings-scrub.md +33 -0
  26. package/payload/server/public/assets/{admin-Bt4mImui.js → admin-WyIfDMQG.js} +5 -5
  27. package/payload/server/public/assets/{data-laRW9zIG.js → data-D2aPJB7w.js} +1 -1
  28. package/payload/server/public/assets/{graph-SnA01HCP.js → graph-B5UWg8zV.js} +1 -1
  29. package/payload/server/public/assets/graph-labels-BzMN9eev.js +1 -0
  30. package/payload/server/public/assets/{page-8KS8gKWq.js → page--nZ_z-z7.js} +1 -1
  31. package/payload/server/public/assets/{page-BSgRQNig.js → page-D93GZ3YQ.js} +1 -1
  32. package/payload/server/public/data.html +3 -3
  33. package/payload/server/public/graph.html +3 -3
  34. package/payload/server/public/index.html +4 -4
  35. package/payload/server/public/assets/graph-labels-BGa1MHXG.js +0 -1
@@ -0,0 +1,410 @@
1
+ #!/usr/bin/env bash
2
+ # Task 273 — one-time JSONL stash-composite cleanup.
3
+ #
4
+ # For each `<uuid>.<unix-ms>.jsonl` file under a CLAUDE_STATE_ROOT/projects
5
+ # directory (top-level and archive/ subdir), pair it with the canonical
6
+ # `<uuid>.jsonl`. Keep the larger of the two as the canonical; move the
7
+ # smaller (with its sidecar) to QUARANTINE_ROOT, preserving the original
8
+ # basename. If only the timestamped sibling exists (no canonical), promote
9
+ # it to the canonical name. The quarantine path sits outside any directory
10
+ # the fs-watcher scans, so quarantined files do not appear in the sidebar.
11
+ #
12
+ # Safety rails:
13
+ # 1. Refuse to run if any PID file exists under CLAUDE_STATE_ROOT/sessions/.
14
+ # A live PTY holding one of the affected UUIDs is the failure mode this
15
+ # check guards against.
16
+ # 2. Refuse to overwrite an existing quarantine target — if the same
17
+ # timestamped basename already sits in quarantine from a prior run,
18
+ # surface the conflict and skip rather than clobber.
19
+ # 3. Sidecar `.meta.json` files follow the same disposition as their JSONL.
20
+ # 4. A `.log` audit trail records every rename and quarantine move with
21
+ # from=, to=, bytes=, mtime=. The transcript is the operator's
22
+ # audit before approving permanent deletion in a follow-up task.
23
+ #
24
+ # Usage:
25
+ # stash-cleanup.sh <claude-state-root> [--dry-run]
26
+ # e.g. ~/.realagent-code/.claude
27
+ #
28
+ # stash-cleanup.sh --self-test
29
+ # Seeds a temp dir with collision pairs, runs the cleanup against it,
30
+ # asserts post-conditions, and cleans up. Exits non-zero on failure.
31
+
32
+ set -euo pipefail
33
+
34
+ usage() {
35
+ cat <<USAGE
36
+ Task 273 JSONL stash-cleanup.
37
+
38
+ Usage:
39
+ $0 <claude-state-root> [--dry-run]
40
+ $0 --self-test
41
+
42
+ Arguments:
43
+ <claude-state-root> e.g. ~/.realagent-code/.claude
44
+
45
+ Flags:
46
+ --dry-run Plan-only: log what would happen, change nothing on disk.
47
+ --self-test Run the embedded smoke test; exits 0 on PASS.
48
+ USAGE
49
+ }
50
+
51
+ log() { printf '[stash-cleanup] %s\n' "$*"; }
52
+ err() { printf '[stash-cleanup] ERROR: %s\n' "$*" >&2; }
53
+
54
+ # Returns 0 if the basename matches `<uuid>.<unix-ms>.jsonl`. UUID is
55
+ # 36 chars including dashes; ms timestamp is exactly 13 digits.
56
+ is_stash_composite_basename() {
57
+ local name="$1"
58
+ [[ "$name" =~ ^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\.[0-9]{13}\.jsonl$ ]]
59
+ }
60
+
61
+ # Extract the canonical `<uuid>.jsonl` basename from a stash composite.
62
+ canonical_basename_for() {
63
+ local stash="$1"
64
+ printf '%s.jsonl\n' "${stash:0:36}"
65
+ }
66
+
67
+ bytes_of() {
68
+ if [[ -f "$1" ]]; then
69
+ stat -f%z "$1" 2>/dev/null || stat -c%s "$1"
70
+ else
71
+ printf '0\n'
72
+ fi
73
+ }
74
+
75
+ mtime_of() {
76
+ if [[ -f "$1" ]]; then
77
+ stat -f%m "$1" 2>/dev/null || stat -c%Y "$1"
78
+ else
79
+ printf '0\n'
80
+ fi
81
+ }
82
+
83
+ # Move a JSONL file (and its sidecar if present) to quarantine, preserving
84
+ # the original basename. Refuses to clobber.
85
+ move_to_quarantine() {
86
+ local src="$1" qdir="$2" reason="$3"
87
+ local bn dst sidecar_src sidecar_dst
88
+ bn=$(basename "$src")
89
+ dst="$qdir/$bn"
90
+
91
+ if [[ -e "$dst" ]]; then
92
+ err "quarantine target already exists, skipping: $dst"
93
+ return 1
94
+ fi
95
+
96
+ local sz mt
97
+ sz=$(bytes_of "$src")
98
+ mt=$(mtime_of "$src")
99
+ if [[ "$DRY_RUN" == "yes" ]]; then
100
+ log "DRY quarantine reason=$reason from=$src to=$dst bytes=$sz mtime=$mt"
101
+ else
102
+ mkdir -p "$qdir"
103
+ mv "$src" "$dst"
104
+ log "quarantine reason=$reason from=$src to=$dst bytes=$sz mtime=$mt"
105
+ fi
106
+
107
+ # Sidecar follows: `<base>.meta.json` where <base> is the JSONL path minus
108
+ # the trailing `.jsonl`.
109
+ sidecar_src="${src%.jsonl}.meta.json"
110
+ sidecar_dst="${dst%.jsonl}.meta.json"
111
+ if [[ -f "$sidecar_src" ]]; then
112
+ if [[ -e "$sidecar_dst" ]]; then
113
+ err "sidecar quarantine target already exists, skipping: $sidecar_dst"
114
+ return 1
115
+ fi
116
+ local ssz smt
117
+ ssz=$(bytes_of "$sidecar_src")
118
+ smt=$(mtime_of "$sidecar_src")
119
+ if [[ "$DRY_RUN" == "yes" ]]; then
120
+ log "DRY quarantine-sidecar from=$sidecar_src to=$sidecar_dst bytes=$ssz mtime=$smt"
121
+ else
122
+ mv "$sidecar_src" "$sidecar_dst"
123
+ log "quarantine-sidecar from=$sidecar_src to=$sidecar_dst bytes=$ssz mtime=$smt"
124
+ fi
125
+ fi
126
+ }
127
+
128
+ # Promote `src` to `dst` by renaming. Sidecar follows.
129
+ promote_in_place() {
130
+ local src="$1" dst="$2" reason="$3"
131
+ local sidecar_src sidecar_dst
132
+ local sz mt
133
+ sz=$(bytes_of "$src")
134
+ mt=$(mtime_of "$src")
135
+ if [[ "$DRY_RUN" == "yes" ]]; then
136
+ log "DRY promote reason=$reason from=$src to=$dst bytes=$sz mtime=$mt"
137
+ else
138
+ mv "$src" "$dst"
139
+ log "promote reason=$reason from=$src to=$dst bytes=$sz mtime=$mt"
140
+ fi
141
+
142
+ sidecar_src="${src%.jsonl}.meta.json"
143
+ sidecar_dst="${dst%.jsonl}.meta.json"
144
+ if [[ -f "$sidecar_src" ]]; then
145
+ local ssz smt
146
+ ssz=$(bytes_of "$sidecar_src")
147
+ smt=$(mtime_of "$sidecar_src")
148
+ if [[ "$DRY_RUN" == "yes" ]]; then
149
+ log "DRY promote-sidecar from=$sidecar_src to=$sidecar_dst bytes=$ssz mtime=$smt"
150
+ else
151
+ mv "$sidecar_src" "$sidecar_dst"
152
+ log "promote-sidecar from=$sidecar_src to=$sidecar_dst bytes=$ssz mtime=$smt"
153
+ fi
154
+ fi
155
+ }
156
+
157
+ # Process one directory (top-level or archive/). For each stash composite,
158
+ # pair with canonical; resolve.
159
+ process_dir() {
160
+ local dir="$1" qdir="$2"
161
+ [[ -d "$dir" ]] || { log "skip: $dir does not exist"; return 0; }
162
+
163
+ local handled=0
164
+ shopt -s nullglob
165
+ for path in "$dir"/*.jsonl; do
166
+ local bn
167
+ bn=$(basename "$path")
168
+ is_stash_composite_basename "$bn" || continue
169
+ handled=$((handled + 1))
170
+
171
+ local canonical_bn canonical_path
172
+ canonical_bn=$(canonical_basename_for "$bn")
173
+ canonical_path="$dir/$canonical_bn"
174
+
175
+ if [[ -f "$canonical_path" ]]; then
176
+ local stash_sz canonical_sz
177
+ stash_sz=$(bytes_of "$path")
178
+ canonical_sz=$(bytes_of "$canonical_path")
179
+ log "pair dir=$dir uuid=${bn:0:8} stash=$bn stash-bytes=$stash_sz canonical-bytes=$canonical_sz"
180
+
181
+ if (( stash_sz > canonical_sz )); then
182
+ # Stash wins. Quarantine canonical first (preserving its name),
183
+ # then promote stash to canonical.
184
+ local canonical_quarantine_name="$canonical_bn.canonical"
185
+ local canonical_qdst="$qdir/$canonical_quarantine_name"
186
+ if [[ -e "$canonical_qdst" ]]; then
187
+ err "canonical quarantine target exists, skipping pair: $canonical_qdst"
188
+ continue
189
+ fi
190
+ local csz cmt
191
+ csz=$(bytes_of "$canonical_path")
192
+ cmt=$(mtime_of "$canonical_path")
193
+ if [[ "$DRY_RUN" == "yes" ]]; then
194
+ log "DRY quarantine reason=smaller-canonical from=$canonical_path to=$canonical_qdst bytes=$csz mtime=$cmt"
195
+ else
196
+ mkdir -p "$qdir"
197
+ mv "$canonical_path" "$canonical_qdst"
198
+ log "quarantine reason=smaller-canonical from=$canonical_path to=$canonical_qdst bytes=$csz mtime=$cmt"
199
+ fi
200
+ # Canonical sidecar follows with the same suffix.
201
+ local csc_src="${canonical_path%.jsonl}.meta.json"
202
+ local csc_dst="${canonical_qdst%.jsonl}.meta.json"
203
+ if [[ -f "$csc_src" ]]; then
204
+ if [[ "$DRY_RUN" == "yes" ]]; then
205
+ log "DRY quarantine-sidecar from=$csc_src to=$csc_dst"
206
+ else
207
+ mv "$csc_src" "$csc_dst"
208
+ log "quarantine-sidecar from=$csc_src to=$csc_dst"
209
+ fi
210
+ fi
211
+ promote_in_place "$path" "$canonical_path" "stash-larger-than-canonical"
212
+ else
213
+ # Canonical wins (or equal). Quarantine stash with its original
214
+ # timestamped basename.
215
+ move_to_quarantine "$path" "$qdir" "smaller-stash" || true
216
+ fi
217
+ else
218
+ # No canonical on disk. Promote the stash to canonical.
219
+ log "lone-stash dir=$dir uuid=${bn:0:8} stash=$bn"
220
+ promote_in_place "$path" "$canonical_path" "no-canonical-present"
221
+ fi
222
+ done
223
+ shopt -u nullglob
224
+
225
+ log "summary dir=$dir composites-handled=$handled"
226
+ }
227
+
228
+ # Walks every project directory under <state-root>/projects/ and processes
229
+ # top-level + archive/ for each.
230
+ run_cleanup() {
231
+ local state_root="$1"
232
+ local projects_root="$state_root/projects"
233
+ local sessions_root="$state_root/sessions"
234
+ local quarantine_root="$state_root/quarantine"
235
+
236
+ [[ -d "$projects_root" ]] || { err "projects root not found: $projects_root"; return 2; }
237
+
238
+ # Pre-flight: no live PTY may be running. The sessions/ directory holds
239
+ # one PID file per live PTY (Task 199 contract); empty = no live PTYs.
240
+ if [[ -d "$sessions_root" ]]; then
241
+ shopt -s nullglob
242
+ local pids=("$sessions_root"/*.json)
243
+ shopt -u nullglob
244
+ if (( ${#pids[@]} > 0 )); then
245
+ err "live PTY detected — ${#pids[@]} PID file(s) under $sessions_root; refuse to touch on-disk state"
246
+ err "stop the affected sessions first, then retry"
247
+ return 3
248
+ fi
249
+ fi
250
+ log "pre-flight pid-files=0 sessions-root=$sessions_root"
251
+
252
+ shopt -s nullglob
253
+ local project_dirs=("$projects_root"/*/)
254
+ shopt -u nullglob
255
+ log "projects-found count=${#project_dirs[@]}"
256
+
257
+ for project_dir in "${project_dirs[@]}"; do
258
+ local slug
259
+ slug=$(basename "$project_dir")
260
+ local qdir="$quarantine_root/$slug"
261
+ log "project-begin slug=$slug"
262
+ process_dir "${project_dir%/}" "$qdir"
263
+ process_dir "${project_dir%/}/archive" "$qdir/archive"
264
+ log "project-end slug=$slug"
265
+ done
266
+
267
+ log "done state-root=$state_root quarantine-root=$quarantine_root dry-run=$DRY_RUN"
268
+ }
269
+
270
+ # ----- self-test --------------------------------------------------------
271
+
272
+ self_test() {
273
+ local tmp
274
+ tmp=$(mktemp -d)
275
+ # Expand at trap-set time so the path survives function-local scope.
276
+ trap "rm -rf '$tmp'" EXIT
277
+
278
+ local state="$tmp/state"
279
+ mkdir -p "$state/projects/slug-A" "$state/projects/slug-A/archive" "$state/sessions"
280
+
281
+ # Pair 1: timestamped sibling is larger; should win.
282
+ local uuid1="4bfe4274-1111-4111-8111-111111111111"
283
+ local big="payload-big"
284
+ local small="x"
285
+ printf '%s' "$big" > "$state/projects/slug-A/${uuid1}.1779477697566.jsonl"
286
+ printf '%s' "$small" > "$state/projects/slug-A/${uuid1}.jsonl"
287
+
288
+ # Pair 2: canonical is larger; sibling loses.
289
+ local uuid2="9c26cc66-2222-4222-8222-222222222222"
290
+ printf '%s' "big-canonical" > "$state/projects/slug-A/${uuid2}.jsonl"
291
+ printf '%s' "tiny" > "$state/projects/slug-A/${uuid2}.1779477700000.jsonl"
292
+
293
+ # Pair 3 (archive): canonical wins (matches the be23f93a archive-pair shape).
294
+ local uuid3="654f5fe5-3333-4333-8333-333333333333"
295
+ printf '%s' "archived-big-history" > "$state/projects/slug-A/archive/${uuid3}.jsonl"
296
+ printf '%s' "tiny" > "$state/projects/slug-A/archive/${uuid3}.1779477705000.jsonl"
297
+
298
+ # Pair 4: lone stash, no canonical present.
299
+ local uuid4="abcdef01-4444-4444-8444-444444444444"
300
+ printf '%s' "lone-stash-content" > "$state/projects/slug-A/${uuid4}.1779477710000.jsonl"
301
+
302
+ # Sidecar on uuid1's stash (the winner) — should travel with the rename
303
+ # to canonical. Sidecar on uuid2's stash (the loser) — should follow to
304
+ # quarantine.
305
+ printf '{"meta":"win"}' > "$state/projects/slug-A/${uuid1}.1779477697566.meta.json"
306
+ printf '{"meta":"lose"}' > "$state/projects/slug-A/${uuid2}.1779477700000.meta.json"
307
+
308
+ DRY_RUN=no run_cleanup "$state" >/tmp/stash-cleanup-selftest.log 2>&1 \
309
+ || { cat /tmp/stash-cleanup-selftest.log; err "self-test: run_cleanup failed"; exit 1; }
310
+
311
+ local fail=0
312
+ local q="$state/quarantine/slug-A"
313
+ local qa="$state/quarantine/slug-A/archive"
314
+
315
+ # uuid1: canonical now holds "payload-big"; old canonical lives in
316
+ # quarantine with the `.canonical` suffix.
317
+ if [[ "$(cat "$state/projects/slug-A/${uuid1}.jsonl" 2>/dev/null)" != "$big" ]]; then
318
+ err "uuid1 canonical did not receive stash content"; fail=1
319
+ fi
320
+ if [[ -e "$state/projects/slug-A/${uuid1}.1779477697566.jsonl" ]]; then
321
+ err "uuid1 stash sibling still on disk after promotion"; fail=1
322
+ fi
323
+ if [[ "$(cat "$q/${uuid1}.jsonl.canonical" 2>/dev/null)" != "$small" ]]; then
324
+ err "uuid1 old canonical not in quarantine"; fail=1
325
+ fi
326
+ # Sidecar followed promotion.
327
+ if [[ "$(cat "$state/projects/slug-A/${uuid1}.meta.json" 2>/dev/null)" != '{"meta":"win"}' ]]; then
328
+ err "uuid1 sidecar did not follow promotion"; fail=1
329
+ fi
330
+
331
+ # uuid2: canonical untouched; stash sibling in quarantine.
332
+ if [[ "$(cat "$state/projects/slug-A/${uuid2}.jsonl" 2>/dev/null)" != "big-canonical" ]]; then
333
+ err "uuid2 canonical altered"; fail=1
334
+ fi
335
+ if [[ ! -f "$q/${uuid2}.1779477700000.jsonl" ]]; then
336
+ err "uuid2 stash sibling not quarantined"; fail=1
337
+ fi
338
+ if [[ "$(cat "$q/${uuid2}.1779477700000.meta.json" 2>/dev/null)" != '{"meta":"lose"}' ]]; then
339
+ err "uuid2 sidecar did not follow to quarantine"; fail=1
340
+ fi
341
+
342
+ # uuid3 (archive): canonical wins; stash sibling in archive-quarantine.
343
+ if [[ "$(cat "$state/projects/slug-A/archive/${uuid3}.jsonl" 2>/dev/null)" != "archived-big-history" ]]; then
344
+ err "uuid3 archive canonical altered"; fail=1
345
+ fi
346
+ if [[ ! -f "$qa/${uuid3}.1779477705000.jsonl" ]]; then
347
+ err "uuid3 archive stash sibling not quarantined under archive/"; fail=1
348
+ fi
349
+
350
+ # uuid4: lone stash promoted in place; no quarantine.
351
+ if [[ "$(cat "$state/projects/slug-A/${uuid4}.jsonl" 2>/dev/null)" != "lone-stash-content" ]]; then
352
+ err "uuid4 lone stash not promoted to canonical"; fail=1
353
+ fi
354
+ if [[ -e "$state/projects/slug-A/${uuid4}.1779477710000.jsonl" ]]; then
355
+ err "uuid4 stash file still on disk after promotion"; fail=1
356
+ fi
357
+
358
+ # No <uuid>.<unix-ms>.jsonl siblings remain in the projects scan scope.
359
+ local residual
360
+ residual=$(find "$state/projects" -type f -name '*.jsonl' \
361
+ | awk -F/ '{ print $NF }' \
362
+ | grep -cE '^[a-f0-9-]{36}\.[0-9]{13}\.jsonl$' || true)
363
+ if (( residual > 0 )); then
364
+ err "self-test: $residual timestamped siblings still present"; fail=1
365
+ fi
366
+
367
+ # Live-PTY guard: seed a PID file and confirm the script refuses.
368
+ printf '{"pid":1234}' > "$state/sessions/1234.json"
369
+ if DRY_RUN=no run_cleanup "$state" >>/tmp/stash-cleanup-selftest.log 2>&1; then
370
+ err "self-test: live-PTY guard did not refuse"; fail=1
371
+ fi
372
+ rm -f "$state/sessions/1234.json"
373
+
374
+ if (( fail > 0 )); then
375
+ cat /tmp/stash-cleanup-selftest.log
376
+ err "self-test: FAILED"
377
+ exit 1
378
+ fi
379
+
380
+ log "self-test: PASS"
381
+ }
382
+
383
+ # ----- entry point ------------------------------------------------------
384
+
385
+ DRY_RUN=no
386
+ case "${1:-}" in
387
+ -h|--help|"")
388
+ usage
389
+ exit 0
390
+ ;;
391
+ --self-test)
392
+ self_test
393
+ exit 0
394
+ ;;
395
+ *)
396
+ STATE_ROOT="${1:-}"
397
+ shift || true
398
+ while (( $# > 0 )); do
399
+ case "$1" in
400
+ --dry-run) DRY_RUN=yes ;;
401
+ *) err "unknown flag: $1"; usage; exit 2 ;;
402
+ esac
403
+ shift
404
+ done
405
+ [[ -n "$STATE_ROOT" ]] || { usage; exit 2; }
406
+ # Expand ~ since the caller may pass it.
407
+ STATE_ROOT="${STATE_ROOT/#\~/$HOME}"
408
+ run_cleanup "$STATE_ROOT" || exit $?
409
+ ;;
410
+ esac
@@ -4,6 +4,11 @@
4
4
  "name": "Rubytech LLC"
5
5
  },
6
6
  "plugins": [
7
+ {
8
+ "name": "founder-pack",
9
+ "source": "./founder-pack",
10
+ "version": "0.1.0"
11
+ },
7
12
  {
8
13
  "name": "teaching",
9
14
  "source": "./teaching",
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "founder-pack",
3
+ "description": "founder-pack plugin",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "Rubytech LLC"
7
+ }
8
+ }
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: investor-data-room
3
+ description: Use when a UK-domiciled founder needs to produce a full seed-raise pack from idea to deliverables: graph-structured data room, 15-section business plan, 12-slide deck blueprint, print-ready HTML+PDF for both. Trigger phrases include "build me a data room", "draft a business plan", "deck from the business plan", "print-ready PDF for the prospectus", "from office hours to investor pack", "set up the fundraise repo". The skill never speculates on financial figures or cap-table values: every number traces to a Companies House filing, a financial model worksheet, or a source citation. Public-facing artefacts contain zero internal workings (no "reconciliation pending", no "open Q" markers, no comparison-to-baseline commentary). Design tokens are harmonised across business plan, deck, and prospectus per `realagent-site/.docs/design-tokens.md`.
4
+ allowed-tools:
5
+ - Bash
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Glob
10
+ - Grep
11
+ - WebSearch
12
+ - WebFetch
13
+ ---
14
+
15
+ # investor-data-room
16
+
17
+ Build a UK seed-raise pack in five stages. Each stage has an outcome contract; do not advance until the contract is met.
18
+
19
+ ## Outcome contract (whole skill)
20
+
21
+ Complete when the data room contains:
22
+
23
+ ```
24
+ <project-site>/.docs/data-room/
25
+ README.md # data-room index, status snapshot, doctrine
26
+ 01-narrative/
27
+ office-hours-design.md # ideation working scratchpad
28
+ business-plan.md # 15-section business plan
29
+ deck-blueprint.md # 12-slide blueprint
30
+ 02-corporate-legal/
31
+ README.md # incorporation filings, articles, board minutes
32
+ incorporation-<co-house-no>-<date>.pdf # IN01 + statement of capital + cap table
33
+ 03-cap-table/
34
+ README.md # pre/post-investment cap table with PSC notes
35
+ 04-financials/
36
+ README.md
37
+ model_worksheet.md # opening cash, capex, burn, MRR ramp, two-round
38
+ 05-commercial/
39
+ README.md
40
+ <gtm-partner-1>.md # one file per named partner
41
+ <gtm-partner-1>-proposal.pdf
42
+ 06-product-ip/
43
+ README.md
44
+ encrypted-document-sharing.md # if applicable
45
+ 07-team/
46
+ README.md
47
+ <founder-1>.pdf # CV per foregrounded founder
48
+ 08-market/
49
+ README.md
50
+ sources.md # every market figure with citation
51
+ competitor-value-claims-rebuttal.md
52
+ 09-operations/
53
+ README.md
54
+ 10-supporting/
55
+ README.md
56
+ html/
57
+ business-plan/
58
+ index.html # A4 portrait, design tokens, premium register
59
+ render-pdf.mjs # Playwright + img2pdf + qpdf pipeline
60
+ business-plan.pdf # rendered output
61
+ logo-light.png logo-dark.png
62
+ prospectus/
63
+ index.html
64
+ render-pdf.mjs
65
+ prospectus.pdf
66
+ deck/ # NOT YET BUILT in the reference project
67
+ index.html
68
+ render-pdf.mjs
69
+ deck.pdf
70
+ ```
71
+
72
+ Skip stages that are already complete; do not regenerate stale artefacts blindly.
73
+
74
+ ## Stage 1 — Office-hours ideation
75
+
76
+ Drive a conversational discovery session using the `/office-hours` skill (or equivalent YC-style forcing questions: demand reality, status quo, desperate specificity, narrowest wedge, observation, future-fit). Output a single `office-hours-design.md` capturing:
77
+
78
+ - Problem statement
79
+ - Demand evidence (with numbers and dates)
80
+ - Status quo
81
+ - Target user and narrowest wedge
82
+ - Constraints
83
+ - Six to eight numbered premises (founder-confirmed)
84
+ - Two to four narrative-shape alternatives with a recommendation
85
+ - Financials / use-of-funds placeholders flagged as open questions
86
+ - Founder Signal Reflection
87
+
88
+ This file is the working substrate. It stays internal-only. Every later artefact derives from it.
89
+
90
+ **Doctrine.** Never speculate on numbers; flag them as open questions until the founder confirms.
91
+
92
+ ## Stage 2 — Data room scaffold
93
+
94
+ Build the directory tree above. Each section gets a `README.md` that doubles as a content checklist (purpose, expected contents, current state, gaps). The graph structure is fixed: ten numbered sections (`01-narrative` through `10-supporting`) plus a top-level README and an `html/` subdirectory for rendered deliverables.
95
+
96
+ **File-naming conventions:**
97
+
98
+ - `<co-house-no>` for Companies House filings (e.g. `incorporation-17237239-2026-05-22.pdf`).
99
+ - `<founder-firstname>-<lastname>.pdf` for CVs.
100
+ - `<gtm-partner>.md` + `<gtm-partner>-proposal.pdf` for each commercial partner.
101
+ - All `README.md` files are markdown only.
102
+
103
+ **Where the published URL lives.** If the project hosts a public prospectus or marketing microsite, keep the published artefacts at a stable path (e.g. `realagent.chat/sites/<slug>/`); the rendered HTML inside `html/<artefact>/index.html` is the source of truth and republishes from there.
104
+
105
+ References: `references/data-room-structure.md` for the section-by-section purpose statements.
106
+
107
+ ## Stage 3 — Business plan synthesis
108
+
109
+ Generate `01-narrative/business-plan.md` with **15 sections** following the canonical structure:
110
+
111
+ 1. Executive Summary
112
+ 2. Vision and Mission (Vision / Mission / Doctrine triad)
113
+ 3. The Company (legal entity table + pre-investment cap table)
114
+ 4. The Market (TAM/SAM/SOM + structural tailwind + self-employed wedge + domestic adjacency + international upside + pricing)
115
+ 5. The Product (what it is + wedge product + upsell path + substrate moat + conversation ingestion + network + Anthropic asymmetric capture + human-services layer)
116
+ 6. The Business Model (revenue streams + unit economics)
117
+ 7. Go-to-Market (Wedge → Beachhead → Blitzscale framework + demand evidence + GTM partners + horse-before-cart logic + geography)
118
+ 8. Competition (three failing categories + RANL differentiation + most-direct-competitor counter)
119
+ 9. Operations (technology stack + data sovereignty + IP ownership chain + compliance posture summary)
120
+ 10. Compliance and regulatory positioning (UK consumer protection + UK data/AI regime + EU AI Act + adjacent UK obligations + moat-not-tax close)
121
+ 11. Team (founders + strategic shareholders + hiring plan)
122
+ 12. Financial Plan (12.1 opening balance sheet through 12.7 use of funds)
123
+ 13. Risks and Mitigations
124
+ 14. Milestones (the N-month thesis)
125
+ 15. The bottom line (summary table + close)
126
+ + Appendices (titled documents only; no internal-only file pointers)
127
+
128
+ **Critical rules** (all enforced; recurrence is a P0 violation):
129
+
130
+ - **No internal workings** in body text. No "reconciliation pending", no "open Q", no comparison-to-baseline ("loss has grown from X to Y because…"), no cross-references to `office-hours-design.md` or any working file.
131
+ - **Cap table is authoritative from the IN01.** Reconcile the share-capital line (`500,000 ordinary @ £0.001 nominal` vs `@ £0.01`) before writing the opening balance sheet. Inception premium (e.g. one founder paying £4,500 above nominal) reconciles £5k inception cash against £500 nominal.
132
+ - **Every market figure cites a source.** Maintain `08-market/sources.md` with every figure used in the business plan; the body references "Appendix B" by title, never an internal file path.
133
+ - **Financial figures derive from the model worksheet.** Cite "Appendix A" by title.
134
+ - **No em-dashes between alphabetic words** in user-facing prose (recurring style violation in this project's history; see `references/internal-workings-scrub.md`).
135
+
136
+ Compliance research is mandatory before drafting Section 10. WebSearch (or equivalent) for: DMCC Act (UK consumer protection for estate-agency), ICO ADM framework (Articles 22A–22D under UK GDPR + ICO 2025 strategy), EU AI Act (force date, high-risk classification for property-financing decisions). Cite each.
137
+
138
+ References: `references/business-plan-template.md` for the section-by-section template; `references/compliance-research-checklist.md` for the UK + EU regulatory regimes to verify.
139
+
140
+ ## Stage 4 — Deck blueprint synthesis
141
+
142
+ Generate `01-narrative/deck-blueprint.md` as a **12-slide brief** the deck designer can execute. Each slide has Purpose, Headline (one-line message), Body (bullets + figures pulled from the business plan), Visual suggestion, and Source reference. The 12 slides:
143
+
144
+ 1. Cover (raise headline + founders)
145
+ 2. Vision (Vision / Mission / Doctrine)
146
+ 3. The Market (TAM + tailwind + wedge)
147
+ 4. Business Model (subscription + service layer + unit economics)
148
+ 5. Go-to-Market (Wedge → Beachhead → Blitzscale + named partners)
149
+ 6. The Product (substrate + wedge + network + asymmetric capture + services layer)
150
+ 7. Competition (three failing categories + most-direct counter)
151
+ 8. The Team (founders + strategic shareholders)
152
+ 9. Economics (P&L summary + cash flow + break-even)
153
+ 10. The Raise (size, valuation, dilution, instrument, use of funds, IP transfer, follow-on round)
154
+ 11. Milestones (M0 to M-final timeline)
155
+ 12. Other Information (compliance + platform dependency + contact)
156
+
157
+ Production notes attached: format (16:9 landscape, PDF + source deck), design tokens reference (`realagent-site/.docs/design-tokens.md` or project equivalent), chart-source consistency with the financial model, speaker-note attribution.
158
+
159
+ References: `references/deck-blueprint-template.md`.
160
+
161
+ ## Stage 5 — HTML + PDF render pipeline
162
+
163
+ For each artefact that ships as a print-ready PDF (business plan, prospectus, deck), produce three files under `html/<artefact>/`:
164
+
165
+ ```
166
+ index.html # A4 portrait single HTML file, premium design tokens, sectioned by <section class="page">
167
+ render-pdf.mjs # Playwright + img2pdf + qpdf pipeline (image-only PDF, linearized)
168
+ <artefact>.pdf # rendered output (regenerate after every HTML edit)
169
+ ```
170
+
171
+ **Hard constraints** (from the `property-brochure:a4-print-documents` skill):
172
+
173
+ - A4 portrait: `@page { size: A4 portrait; margin: 18mm 16mm 20mm; }`
174
+ - One `<section class="page">` per A4 page; renderer aborts if `scrollHeight` exceeds 1123px + 2px slack.
175
+ - Page numbers via CSS counter in `.page::after { content: counter(pagenum); }`. The renderer screenshots each section, so `@page @bottom-center` rules do NOT propagate.
176
+ - Image-only PDF: Playwright captures one PNG per section at deviceScaleFactor 3.125 (300 dpi); `img2pdf --pagesize 210mmx297mm` binds them; `qpdf --linearize --object-streams=disable` linearises.
177
+ - Even page count for booklet binding (multiple of 4 ideal). Add or remove a supporting page if parity breaks.
178
+ - Cover and backpage are full-bleed `--surface-deep` with `@page :first { margin: 0 }` and named `@page backpage-full`.
179
+ - Screen-only chrome (e.g. a Download PDF pill button) uses `@media print { display: none !important; }` per the skill.
180
+ - `execFileSync` for img2pdf and qpdf (never `execSync` with template strings: shell-injection class).
181
+ - Verify: `qpdf --check`, `pdfinfo | grep -E "Pages|Optimized"`, **and read every page visually**. `pdfinfo` reporting "25 pages, A4" is not verification.
182
+
183
+ **Design tokens.** Reference the project's `design-tokens.md` Tier 1 (raw) + Tier 2 (semantic aliases) + Tier 3 (component) layers. Premium register defaults: `--paper-25` near-white page surface, `--teal-900` ink, `--gold-500` accent, `--paper-100` cool mist (`#ECF1F2`) tinted-band surface. Update token values in one place; CSS `:root` mirrors the spec.
184
+
185
+ **Logo placement.** Copy the light and dark icon variants from the project's public assets (`logo-light.png` for dark cover/backpage, `logo-dark.png` reserved for light content pages if needed) into the artefact directory. Cover top-left pairs the icon with the wordmark; backpage top-left does the same.
186
+
187
+ References: `references/html-pdf-pipeline.md` for the canonical `render-pdf.mjs` source and CSS scaffold.
188
+
189
+ ## Doctrine (enforced across all stages)
190
+
191
+ - **No internal workings in public artefacts.** Comparison-to-baseline, reconciliation-pending, open-Q markers, internal cross-references all stay in working files (`01-narrative/office-hours-design.md`, section READMEs). Public artefacts (business plan, deck, prospectus, PDFs) state the current position as a fact.
192
+ - **Every claim cites a source.** Companies House for the cap table. The model worksheet for every financial figure. A named publication for every market figure. A specific vendor page for every competitor claim.
193
+ - **Design tokens are the visual contract.** Update once in the tokens spec; the business plan CSS, the prospectus CSS, and the deck CSS all consume the same tokens. Never hardcode hex values inside component CSS.
194
+ - **Even page count for booklet binding.** Multiple of 4 ideally; minimum even. Add or remove a supporting page to maintain parity if a section change breaks it.
195
+ - **Verify by reading every rendered page.** `pdfinfo` page count is not verification. The bottom 30% of every page must reach the content margin without significant whitespace.
196
+
197
+ ## Pitfalls to avoid (collected from the reference project)
198
+
199
+ - **Renaming a directory after the URL is published.** Keep `<project-site>/.docs/data-room/html/<artefact>/index.html` stable; if the URL changes, downstream investor links break.
200
+ - **Letting Round-2 hires inflate the Year-1 P&L.** Only Round-1 hires belong in the Year-1 income statement. Customer-success and product-engineer hires that trigger in Round 1 are in; senior platform engineer, head of growth, and CS team scale that Round 2 funds are not.
201
+ - **Mixing "Year 1" (12-month) and "Round 1 runway" (9-month).** If the £350k buys 9 months, present a 9-month forecast; do not present a 12-month forecast that implicitly assumes Round 2 closes mid-period without modelling the Round-2 cash injection.
202
+ - **Generic AI-bolted-onto-cloud-CRM competitors.** Treat the competitive set as three failing categories: incumbents (cloud CRM + bolted AI), Anthropic horizontal AI (inaccessible to non-tech-wizard users), and new-build cloud-SaaS AI-OS replacements (migration-required, same lock-in pattern as incumbents). Name each vendor, cite each claim from the vendor's own page, rebut with the substrate-AI inversion.
203
+ - **Forgetting Priestley / equivalent founder-thesis anchor.** Any founder who built the same thesis years before AI made it structurally apparent should reference it: book title, first-publication date, founder's costly-signal action (e.g. "bought 200 copies and distributed them to operators in his network"). This dates the conviction and lifts the deck's signal weight.
204
+ - **Letting the page background go light brown.** Premium register page surface (`--paper-25`) is near-white (`#FBFAF6`), not ivory. The screen-preview body background stays plain white (`#FFFFFF`).
205
+
206
+ ## References
207
+
208
+ - `references/data-room-structure.md` — section-by-section README templates
209
+ - `references/business-plan-template.md` — 15-section business plan template
210
+ - `references/deck-blueprint-template.md` — 12-slide deck brief template
211
+ - `references/html-pdf-pipeline.md` — render-pdf.mjs canonical source + CSS scaffold
212
+ - `references/compliance-research-checklist.md` — UK + EU regulatory regimes to verify
213
+ - `references/internal-workings-scrub.md` — the public-vs-internal doctrine, patterns to scrub, recurrence list
214
+ - `references/design-tokens-application.md` — how to consume `realagent-site/.docs/design-tokens.md` from an artefact's `:root` block
215
+
216
+ ## Reference project
217
+
218
+ The first execution of this skill produced `realagent-site/.docs/data-room/` for Real Agent Network Limited (Companies House 17237239). Read that directory as the canonical example; the skill's job is to reproduce its structure and doctrine for any subsequent UK seed raise.