Skip to content

Commit bf24b1c

Browse files
author
codejunkie99
committed
feat: add transfer tui wizard
1 parent f17b27e commit bf24b1c

20 files changed

Lines changed: 1509 additions & 14 deletions

Formula/agentic-stack.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class AgenticStack < Formula
88

99
def install
1010
# install the brain + adapters alongside install.sh so relative paths hold
11-
pkgshare.install ".agent", "adapters", "harness_manager", "install.sh",
11+
pkgshare.install ".agent", "adapters", "harness_manager", "scripts", "install.sh",
1212
"onboard.py", "onboard_ui.py", "onboard_widgets.py",
1313
"onboard_render.py", "onboard_write.py",
1414
"onboard_features.py"
@@ -23,6 +23,7 @@ def install
2323
test do
2424
output = shell_output("#{bin}/agentic-stack 2>&1", 2)
2525
assert_match "usage", output
26+
assert_match "agentic-stack transfer", shell_output("#{bin}/agentic-stack transfer --help")
2627
# Wizard --yes must write PREFERENCES.md AND .features.json into a temp project dir
2728
(testpath/".agent/memory/personal").mkpath
2829
system "#{bin}/agentic-stack", "claude-code", testpath.to_s, "--yes"

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ verb-style subcommands (works with both `install.sh` and `install.ps1`):
134134
./install.sh status # one-screen view: which adapters, brain stats
135135
./install.sh doctor # read-only audit; green / yellow / red per adapter
136136
./install.sh manage # interactive TUI: header pane + menu loop for add/remove/audit
137+
./install.sh transfer # onboarding-style wizard: export/import memory as a curl bridge
137138
./install.sh remove cursor # confirm prompt + delete; no quarantine, no undo
138139
```
139140

@@ -192,6 +193,29 @@ agentic-stack claude-code --reconfigure # re-run the wizard on an existing proj
192193
Edit `.agent/memory/personal/PREFERENCES.md` any time to refine your
193194
conventions, or `.agent/memory/.features.json` to flip feature toggles.
194195

196+
## Transfer wizard
197+
198+
Move the portable parts of one project brain into Codex, Cursor, Windsurf,
199+
or a terminal-only project with the onboarding-style TUI:
200+
201+
```bash
202+
./install.sh transfer
203+
```
204+
205+
The wizard turns a plain-language intent into a transfer plan, lets you
206+
review target harnesses and memory scopes, redacts risky content by default,
207+
and emits a one-line curl command the next environment can run. The importer
208+
unpacks the bundle, verifies its SHA-256 digest, merges preferences and
209+
accepted lessons, copies selected skills, and installs the matching adapter
210+
files.
211+
212+
For scripted handoff:
213+
214+
```bash
215+
./install.sh transfer export --intent "move my preferences and lessons into Codex" --print-curl
216+
./install.sh transfer import --payload-file transfer.txt --sha256 <digest> --target codex
217+
```
218+
195219
## Review protocol (host-agent CLI)
196220

197221
The nightly `auto_dream.py` cycle only **stages** candidate lessons. It
@@ -306,7 +330,7 @@ The index is stored at `.agent/memory/.index/` and gitignored.
306330
adapters/ # one small shim per harness, each with adapter.json manifest
307331
├── claude-code/ (CLAUDE.md + settings.json hooks — $CLAUDE_PROJECT_DIR wired, closes #18)
308332
├── cursor/ (.cursor/rules/*.mdc)
309-
├── windsurf/ (.windsurfrules)
333+
├── windsurf/ (.windsurf/rules/*.md + legacy .windsurfrules)
310334
├── opencode/ (AGENTS.md + opencode.json)
311335
├── openclaw/ (AGENTS.md + system-prompt include; auto-registers per-project agent)
312336
├── hermes/ (AGENTS.md)
@@ -323,6 +347,9 @@ harness_manager/ # v0.9.0 manifest-driven Python backend
323347
├── remove.py # safe uninstall with shared-file detection + ownership handoff
324348
├── post_install.py # named built-ins (openclaw_register_workspace)
325349
├── manage_tui.py # interactive menu loop for add/remove/audit
350+
├── transfer_tui.py # onboarding-style memory transfer wizard
351+
├── transfer_plan.py # natural-language target/scope planning
352+
├── transfer_bundle.py # export/import bundle codec + merge logic
326353
└── cli.py # argparse dispatcher for install.sh / install.ps1
327354
328355
docs/ # architecture, getting-started, per-harness
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
trigger: always_on
3+
---
4+
5+
# Windsurf rules — agentic-stack portable brain
6+
7+
This project uses a portable brain in `.agent/`. It is authoritative for
8+
memory, skills, and protocols.
9+
10+
## Startup sequence
11+
1. Read `.agent/AGENTS.md`
12+
2. Read `.agent/memory/personal/PREFERENCES.md`
13+
3. Read `.agent/memory/semantic/LESSONS.md`
14+
4. Read `.agent/protocols/permissions.md`
15+
16+
## Recall before non-trivial tasks
17+
For deploy / ship / release / migration / schema / timestamp / timezone /
18+
date / failing test / debug / investigate / refactor, run recall first:
19+
20+
```bash
21+
python3 .agent/tools/recall.py "<short description>"
22+
```
23+
24+
Show surfaced lessons in a `Consulted lessons before acting:` block and
25+
follow them.
26+
27+
## During work
28+
- Consult `.agent/skills/_index.md`. Load a full `SKILL.md` only when its
29+
triggers match the current task.
30+
- Update `.agent/memory/working/WORKSPACE.md` as the task evolves.
31+
- After significant actions, call
32+
`python3 .agent/tools/memory_reflect.py <skill> <action> <outcome>`.
33+
- Quick state: `python3 .agent/tools/show.py`.
34+
- Teach a rule in one shot:
35+
`python3 .agent/tools/learn.py "<rule>" --rationale "<why>"`.
36+
37+
## Hard rules
38+
- Never force push to `main`, `production`, or `staging`.
39+
- Never delete memory entries; archive only.
40+
- Never modify `.agent/protocols/permissions.md`.

adapters/windsurf/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Install
44
```bash
5+
mkdir -p .windsurf/rules
6+
cp adapters/windsurf/.windsurf/rules/agentic-stack.md ./.windsurf/rules/agentic-stack.md
57
cp adapters/windsurf/.windsurfrules ./.windsurfrules
68
```
79

@@ -11,8 +13,9 @@ Or:
1113
```
1214

1315
## What it wires up
14-
Windsurf's Cascade reads `.windsurfrules` from the project root on every
15-
session and prepends it to the system prompt.
16+
Windsurf's Cascade reads workspace rules from `.windsurf/rules/*.md`.
17+
The adapter also writes legacy `.windsurfrules` for users on older
18+
Windsurf builds.
1619

1720
## Verify
1821
Ask Cascade "What's in your lessons file?" — it should read

adapters/windsurf/adapter.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{
22
"name": "windsurf",
3-
"description": "Windsurf — .windsurfrules instruction text. No hooks today.",
3+
"description": "Windsurf — modern .windsurf/rules instruction file plus legacy .windsurfrules compatibility. No hooks today.",
44
"files": [
5+
{
6+
"src": ".windsurf/rules/agentic-stack.md",
7+
"dst": ".windsurf/rules/agentic-stack.md",
8+
"merge_policy": "overwrite"
9+
},
510
{
611
"src": ".windsurfrules",
712
"dst": ".windsurfrules",

docs/per-harness/windsurf.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
# Windsurf setup
22

33
## What the adapter installs
4-
- `.windsurfrules` at project root
4+
- `.windsurf/rules/agentic-stack.md` for current Windsurf workspace rules
5+
- `.windsurfrules` at project root for legacy Windsurf compatibility
56

67
## Install
78
```bash
89
./install.sh windsurf
910
```
1011

1112
## How it works
12-
Windsurf's Cascade reads `.windsurfrules` on session start and prepends it
13-
to the system prompt. Keep the file under ~200 lines; it's read every time.
13+
Windsurf's Cascade discovers workspace rules in `.windsurf/rules/` and
14+
uses their frontmatter to decide activation. The agentic-stack rule is
15+
`always_on`, so Cascade receives it every session. The legacy
16+
`.windsurfrules` file remains installed so older Windsurf builds still
17+
see the portable brain.
1418

1519
## Logging note
1620
Windsurf does not have a first-class post-tool hook. The rule file asks
@@ -19,5 +23,7 @@ want automatic logging, wrap Windsurf in a watcher or run the standalone-
1923
python conductor as a side channel.
2024

2125
## Troubleshooting
22-
- If the agent ignores the file, make sure it's at the exact project root
23-
(Windsurf doesn't search subdirectories).
26+
- If the agent ignores the modern rule, make sure
27+
`.windsurf/rules/agentic-stack.md` exists in the workspace.
28+
- If you're on an older Windsurf build, make sure `.windsurfrules` exists
29+
at the project root.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Transfer TUI Wizard Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Build `agentic-stack transfer` as an onboarding-style TUI wizard that exports/imports portable `.agent` memory bundles and wires Codex, Cursor, Windsurf, or terminal adapters.
6+
7+
**Architecture:** Add pure transfer planning and bundle modules under `harness_manager/`, then wrap them with an onboarding-style wizard that reuses `onboard_ui.py` and `onboard_widgets.py`. Route the new `transfer` verb through `harness_manager.cli`, use existing adapter manifests for installation, and add shell/PowerShell import bootstrap scripts.
8+
9+
**Tech Stack:** Python stdlib, existing `harness_manager`, existing onboarding TUI primitives, unittest, bash, PowerShell.
10+
11+
---
12+
13+
### Task 1: Transfer Planning
14+
15+
**Files:**
16+
- Create: `harness_manager/transfer_plan.py`
17+
- Create: `test_transfer_plan.py`
18+
19+
- [x] **Step 1: Write failing tests for target, operation, and scope parsing**
20+
21+
Cover Codex/Cursor/Windsurf/terminal aliases, `all`, curl/export/apply intent, default scopes, sensitive scope opt-in, and adapter preview paths from manifests.
22+
23+
- [x] **Step 2: Run `python3 -m unittest test_transfer_plan.py -v` and verify it fails because `harness_manager.transfer_plan` is missing**
24+
25+
- [x] **Step 3: Implement `transfer_plan.py` with dataclasses, deterministic keyword parsing, target normalization, default scope selection, and manifest-backed adapter preview**
26+
27+
- [x] **Step 4: Run `python3 -m unittest test_transfer_plan.py -v` and verify it passes**
28+
29+
### Task 2: Bundle Export/Import
30+
31+
**Files:**
32+
- Create: `harness_manager/transfer_bundle.py`
33+
- Create: `test_transfer_bundle.py`
34+
35+
- [x] **Step 1: Write failing tests for bundle round-trip, digest verification, preferences merge, accepted lesson idempotency, and secret scan blocking**
36+
37+
- [x] **Step 2: Run `python3 -m unittest test_transfer_bundle.py -v` and verify it fails because `harness_manager.transfer_bundle` is missing**
38+
39+
- [x] **Step 3: Implement canonical JSON, gzip/base64 payloads, SHA-256 digests, safe file allowlisting, export from `.agent`, and import into temp projects**
40+
41+
- [x] **Step 4: Run `python3 -m unittest test_transfer_bundle.py -v` and verify it passes**
42+
43+
### Task 3: CLI and Wizard
44+
45+
**Files:**
46+
- Create: `harness_manager/transfer_tui.py`
47+
- Modify: `harness_manager/cli.py`
48+
- Create: `test_transfer_cli.py`
49+
50+
- [x] **Step 1: Write failing tests for non-interactive `transfer --help`, `transfer export`, `transfer import`, and non-TTY wizard refusal**
51+
52+
- [x] **Step 2: Run `python3 -m unittest test_transfer_cli.py -v` and verify it fails because the verb is absent**
53+
54+
- [x] **Step 3: Add the `transfer` verb, argparse routing, non-interactive export/import helpers, and onboarding-style wizard flow**
55+
56+
- [x] **Step 4: Run `python3 -m unittest test_transfer_cli.py -v` and verify it passes**
57+
58+
### Task 4: Bootstrap Scripts and Windsurf Modernization
59+
60+
**Files:**
61+
- Create: `scripts/import-transfer.sh`
62+
- Create: `scripts/import-transfer.ps1`
63+
- Create: `adapters/windsurf/.windsurf/rules/agentic-stack.md`
64+
- Modify: `adapters/windsurf/adapter.json`
65+
- Modify: `adapters/windsurf/README.md`
66+
- Modify: `docs/per-harness/windsurf.md`
67+
- Modify: `Formula/agentic-stack.rb`
68+
- Create: `test_transfer_scripts.py`
69+
70+
- [x] **Step 1: Write failing tests that assert scripts exist, Windsurf manifest installs both modern and legacy rule files, and Formula packages scripts**
71+
72+
- [x] **Step 2: Run `python3 -m unittest test_transfer_scripts.py -v` and verify expected failures**
73+
74+
- [x] **Step 3: Add import bootstrap scripts, add modern Windsurf rule file, update manifest/docs, and ensure Formula packages `scripts`**
75+
76+
- [x] **Step 4: Run `python3 -m unittest test_transfer_scripts.py -v` and verify it passes**
77+
78+
### Task 5: Full Verification
79+
80+
**Files:**
81+
- All touched code and docs
82+
83+
- [x] **Step 1: Run focused transfer tests**
84+
85+
Command:
86+
87+
```bash
88+
python3 -m unittest test_transfer_plan.py test_transfer_bundle.py test_transfer_cli.py test_transfer_scripts.py -v
89+
```
90+
91+
- [x] **Step 2: Run existing relevant regression tests**
92+
93+
Command:
94+
95+
```bash
96+
python3 -m unittest test_memory_search.py test_data_layer_export.py test_data_flywheel_export.py -v
97+
```
98+
99+
- [x] **Step 3: Run repository smoke checks**
100+
101+
Command:
102+
103+
```bash
104+
python3 -m harness_manager.cli transfer --help
105+
python3 -m harness_manager.cli transfer export --target codex --print-curl --yes
106+
git diff --check
107+
```
108+
109+
- [x] **Step 4: Commit implementation**
110+
111+
Command:
112+
113+
```bash
114+
git add docs/superpowers/plans/2026-05-02-transfer-tui-wizard.md harness_manager/transfer_plan.py harness_manager/transfer_bundle.py harness_manager/transfer_tui.py harness_manager/cli.py scripts/import-transfer.sh scripts/import-transfer.ps1 adapters/windsurf/.windsurf/rules/agentic-stack.md adapters/windsurf/adapter.json adapters/windsurf/README.md docs/per-harness/windsurf.md Formula/agentic-stack.rb test_transfer_plan.py test_transfer_bundle.py test_transfer_cli.py test_transfer_scripts.py
115+
git commit -m "feat: add transfer tui wizard"
116+
```

harness_manager/cli.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Argparse dispatcher. install.sh and install.ps1 invoke this.
22
3-
Verbs (subcommands): add, remove, doctor, status.
3+
Verbs (subcommands): add, remove, doctor, status, manage, transfer.
44
Anything else in first position → treated as an adapter name (existing
55
`./install.sh <adapter>` UX preserved).
66
"""
@@ -19,7 +19,7 @@
1919
from . import __version__
2020

2121

22-
VERBS = {"add", "remove", "doctor", "status", "manage"}
22+
VERBS = {"add", "remove", "doctor", "status", "manage", "transfer"}
2323

2424

2525
def _stack_root() -> Path:
@@ -247,6 +247,11 @@ def cmd_manage(target: Path) -> int:
247247
return manage_tui.run(target_root=target, stack_root=_stack_root())
248248

249249

250+
def cmd_transfer(args: list[str], target: Path) -> int:
251+
from . import transfer_tui
252+
return transfer_tui.run(args, target_root=target, stack_root=_stack_root())
253+
254+
250255
def cmd_bare(target: Path, wizard_flags: list[str]) -> int:
251256
"""`./install.sh` with no args.
252257
@@ -319,7 +324,8 @@ def cmd_bare(target: Path, wizard_flags: list[str]) -> int:
319324
print(" ./install.sh status # quick read-only view")
320325
print(" ./install.sh add <name> # install another adapter")
321326
print(" ./install.sh remove <name> # remove an adapter (with confirm)")
322-
print(" ./install.sh manage # interactive TUI for everything")
327+
print(" ./install.sh manage # interactive TUI for adapter management")
328+
print(" ./install.sh transfer # onboarding-style memory transfer wizard")
323329
return 2
324330

325331

@@ -450,6 +456,8 @@ def main(argv: list[str] | None = None) -> int:
450456
if verb == "manage":
451457
target = Path(rest[1]) if len(rest) >= 2 else Path.cwd()
452458
return cmd_manage(target)
459+
if verb == "transfer":
460+
return cmd_transfer(rest[1:], Path.cwd())
453461

454462
# Treat as adapter name (existing UX)
455463
adapter = first

harness_manager/doctor.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
(".claude/settings.json", "strong"),
3030
],
3131
"cursor": [(".cursor/rules/agentic-stack.mdc", "strong")],
32-
"windsurf": [(".windsurfrules", "strong")],
32+
"windsurf": [
33+
(".windsurf/rules/agentic-stack.md", "strong"),
34+
(".windsurfrules", "strong"),
35+
],
3336
"openclaw": [(".openclaw-system.md", "strong")],
3437
"pi": [(".pi/extensions/memory-hook.ts", "strong")],
3538
"codex": [(".agents/skills", "strong")],

0 commit comments

Comments
 (0)