fwdit 0.1.2__tar.gz

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 (129) hide show
  1. fwdit-0.1.2/.gitignore +14 -0
  2. fwdit-0.1.2/PKG-INFO +155 -0
  3. fwdit-0.1.2/README.md +144 -0
  4. fwdit-0.1.2/SKILL.md +76 -0
  5. fwdit-0.1.2/agents/openai.yaml +6 -0
  6. fwdit-0.1.2/dev-docs/README.md +39 -0
  7. fwdit-0.1.2/docs/README.md +20 -0
  8. fwdit-0.1.2/pyproject.toml +47 -0
  9. fwdit-0.1.2/references/agent-transfer.md +83 -0
  10. fwdit-0.1.2/references/commands-and-lifecycle.md +232 -0
  11. fwdit-0.1.2/references/targets-and-config.md +149 -0
  12. fwdit-0.1.2/src/fwd/__init__.py +22 -0
  13. fwdit-0.1.2/src/fwd/agents/README.md +71 -0
  14. fwdit-0.1.2/src/fwd/agents/__init__.py +27 -0
  15. fwdit-0.1.2/src/fwd/agents/base.py +127 -0
  16. fwdit-0.1.2/src/fwd/agents/claude.py +178 -0
  17. fwdit-0.1.2/src/fwd/agents/claude_state.py +625 -0
  18. fwdit-0.1.2/src/fwd/agents/codex.py +102 -0
  19. fwdit-0.1.2/src/fwd/agents/codex_state.py +73 -0
  20. fwdit-0.1.2/src/fwd/agents/remote_state.py +74 -0
  21. fwdit-0.1.2/src/fwd/backends/README.md +71 -0
  22. fwdit-0.1.2/src/fwd/backends/__init__.py +93 -0
  23. fwdit-0.1.2/src/fwd/backends/base.py +328 -0
  24. fwdit-0.1.2/src/fwd/backends/lambda_cloud.py +812 -0
  25. fwdit-0.1.2/src/fwd/backends/runpod.py +926 -0
  26. fwdit-0.1.2/src/fwd/backends/slurm.py +599 -0
  27. fwdit-0.1.2/src/fwd/backends/slurm_job.py +192 -0
  28. fwdit-0.1.2/src/fwd/backends/ssh.py +269 -0
  29. fwdit-0.1.2/src/fwd/cli.py +1041 -0
  30. fwdit-0.1.2/src/fwd/cli_completion.py +225 -0
  31. fwdit-0.1.2/src/fwd/cli_help.py +104 -0
  32. fwdit-0.1.2/src/fwd/command_docs.py +92 -0
  33. fwdit-0.1.2/src/fwd/completion_setup.py +73 -0
  34. fwdit-0.1.2/src/fwd/config.py +674 -0
  35. fwdit-0.1.2/src/fwd/credentials.py +188 -0
  36. fwdit-0.1.2/src/fwd/doctor.py +205 -0
  37. fwdit-0.1.2/src/fwd/github_auth.py +338 -0
  38. fwdit-0.1.2/src/fwd/launch_stream.py +173 -0
  39. fwdit-0.1.2/src/fwd/ops/__init__.py +11 -0
  40. fwdit-0.1.2/src/fwd/ops/attach.py +326 -0
  41. fwdit-0.1.2/src/fwd/ops/configcmd.py +643 -0
  42. fwdit-0.1.2/src/fwd/ops/diff.py +217 -0
  43. fwdit-0.1.2/src/fwd/ops/launch.py +810 -0
  44. fwdit-0.1.2/src/fwd/ops/lifecycle.py +543 -0
  45. fwdit-0.1.2/src/fwd/ops/machines.py +73 -0
  46. fwdit-0.1.2/src/fwd/ops/ports.py +262 -0
  47. fwdit-0.1.2/src/fwd/ops/send.py +536 -0
  48. fwdit-0.1.2/src/fwd/ops/session_select.py +286 -0
  49. fwdit-0.1.2/src/fwd/ops/target_alias.py +177 -0
  50. fwdit-0.1.2/src/fwd/ops/transfer.py +116 -0
  51. fwdit-0.1.2/src/fwd/ops/uninstall.py +277 -0
  52. fwdit-0.1.2/src/fwd/output.py +160 -0
  53. fwdit-0.1.2/src/fwd/port_forwarding.py +164 -0
  54. fwdit-0.1.2/src/fwd/remote.py +216 -0
  55. fwdit-0.1.2/src/fwd/remote_env.py +19 -0
  56. fwdit-0.1.2/src/fwd/remote_tasks.py +136 -0
  57. fwdit-0.1.2/src/fwd/rsync_transport.py +124 -0
  58. fwdit-0.1.2/src/fwd/scripts/bootstrap.sh +120 -0
  59. fwdit-0.1.2/src/fwd/scripts/codex_tui_send.py +229 -0
  60. fwdit-0.1.2/src/fwd/selection.py +226 -0
  61. fwdit-0.1.2/src/fwd/send_tasks.py +179 -0
  62. fwdit-0.1.2/src/fwd/session_columns.py +50 -0
  63. fwdit-0.1.2/src/fwd/skill_setup.py +169 -0
  64. fwdit-0.1.2/src/fwd/ssh_keys.py +232 -0
  65. fwdit-0.1.2/src/fwd/sshexec.py +480 -0
  66. fwdit-0.1.2/src/fwd/state.py +281 -0
  67. fwdit-0.1.2/src/fwd/stop_after.py +220 -0
  68. fwdit-0.1.2/src/fwd/sync.py +765 -0
  69. fwdit-0.1.2/src/fwd/task_stream.py +214 -0
  70. fwdit-0.1.2/src/fwd/tmux_config.py +87 -0
  71. fwdit-0.1.2/src/fwd/toolchains/README.md +120 -0
  72. fwdit-0.1.2/src/fwd/toolchains/__init__.py +31 -0
  73. fwdit-0.1.2/src/fwd/toolchains/javascript.py +38 -0
  74. fwdit-0.1.2/src/fwd/toolchains/python.py +28 -0
  75. fwdit-0.1.2/src/fwd/toolchains/swift.py +27 -0
  76. fwdit-0.1.2/src/fwd/tooling/__init__.py +6 -0
  77. fwdit-0.1.2/src/fwd/tooling/base.py +99 -0
  78. fwdit-0.1.2/src/fwd/tooling/requirements.py +286 -0
  79. fwdit-0.1.2/src/fwd/tooling/resolver.py +86 -0
  80. fwdit-0.1.2/src/fwd/ui.py +376 -0
  81. fwdit-0.1.2/src/fwd/wizard.py +582 -0
  82. fwdit-0.1.2/src/fwd/worktree_safety.py +92 -0
  83. fwdit-0.1.2/tests/__init__.py +0 -0
  84. fwdit-0.1.2/tests/fixtures/runpod/gpu-list.json +183 -0
  85. fwdit-0.1.2/tests/fixtures/runpod/pod-create-help.txt +51 -0
  86. fwdit-0.1.2/tests/fixtures/runpod/pod-create.json +32 -0
  87. fwdit-0.1.2/tests/fixtures/runpod/pod-get-missing.json +14 -0
  88. fwdit-0.1.2/tests/fixtures/runpod/pod-get-running.json +36 -0
  89. fwdit-0.1.2/tests/fixtures/runpod/pod-get-stopped.json +28 -0
  90. fwdit-0.1.2/tests/fixtures/runpod/pod-list-empty.json +1 -0
  91. fwdit-0.1.2/tests/fixtures/runpod/pod-list.json +20 -0
  92. fwdit-0.1.2/tests/fixtures/runpod/pod-start.json +22 -0
  93. fwdit-0.1.2/tests/fixtures/runpod/restart-persistence.txt +18 -0
  94. fwdit-0.1.2/tests/fixtures/runpod/root-help.txt +60 -0
  95. fwdit-0.1.2/tests/fixtures/runpod/rsync-test.txt +48 -0
  96. fwdit-0.1.2/tests/fixtures/runpod/ssh-info-proxy.json +11 -0
  97. fwdit-0.1.2/tests/fixtures/runpod/ssh-info-verbose.json +14 -0
  98. fwdit-0.1.2/tests/fixtures/runpod/ssh-info.json +14 -0
  99. fwdit-0.1.2/tests/fixtures/runpod/ssh-test.txt +16 -0
  100. fwdit-0.1.2/tests/fixtures/runpod/stop-test.txt +46 -0
  101. fwdit-0.1.2/tests/fixtures/runpod/subcommand-help.txt +88 -0
  102. fwdit-0.1.2/tests/fixtures/runpod/version.txt +1 -0
  103. fwdit-0.1.2/tests/fixtures/runpod/volume-persistence.txt +31 -0
  104. fwdit-0.1.2/tests/harness/docker-sshd/Dockerfile +45 -0
  105. fwdit-0.1.2/tests/harness/docker-sshd/checks.py +165 -0
  106. fwdit-0.1.2/tests/harness/docker-sshd/run_integration.sh +135 -0
  107. fwdit-0.1.2/tests/harness/docker-sshd/scenarios.py +253 -0
  108. fwdit-0.1.2/tests/test_agents.py +128 -0
  109. fwdit-0.1.2/tests/test_claude_state.py +475 -0
  110. fwdit-0.1.2/tests/test_completion.py +145 -0
  111. fwdit-0.1.2/tests/test_completion_setup.py +85 -0
  112. fwdit-0.1.2/tests/test_config_cmd.py +352 -0
  113. fwdit-0.1.2/tests/test_diff.py +111 -0
  114. fwdit-0.1.2/tests/test_ops.py +1029 -0
  115. fwdit-0.1.2/tests/test_output.py +89 -0
  116. fwdit-0.1.2/tests/test_remote.py +437 -0
  117. fwdit-0.1.2/tests/test_runpod_parse.py +494 -0
  118. fwdit-0.1.2/tests/test_send_tasks.py +318 -0
  119. fwdit-0.1.2/tests/test_session_select.py +294 -0
  120. fwdit-0.1.2/tests/test_skill_package.py +44 -0
  121. fwdit-0.1.2/tests/test_skill_setup.py +192 -0
  122. fwdit-0.1.2/tests/test_slurm.py +498 -0
  123. fwdit-0.1.2/tests/test_smoke.py +363 -0
  124. fwdit-0.1.2/tests/test_ssh_keys.py +78 -0
  125. fwdit-0.1.2/tests/test_stop_after.py +114 -0
  126. fwdit-0.1.2/tests/test_sync.py +542 -0
  127. fwdit-0.1.2/tests/test_target_alias.py +187 -0
  128. fwdit-0.1.2/tests/test_tooling.py +269 -0
  129. fwdit-0.1.2/tests/test_wizard.py +161 -0
fwdit-0.1.2/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ venv/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .benchmarks/
12
+ .coverage
13
+ htmlcov/
14
+ .DS_Store
fwdit-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: fwdit
3
+ Version: 0.1.2
4
+ Summary: Move coding work and agent sessions to remote compute
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: prompt-toolkit>=3.0
7
+ Requires-Dist: rich>=13
8
+ Requires-Dist: tomlkit>=0.13
9
+ Requires-Dist: typer>=0.12
10
+ Description-Content-Type: text/markdown
11
+
12
+ # fwd
13
+
14
+ **Move your coding project and agent session to remote compute.**
15
+
16
+ `fwd` provisions or connects to a remote target, synchronizes the current project, prepares its toolchain, and starts a persistent shell, command, Claude Code, or Codex session in tmux. Disconnect your laptop and return later: the session, durable tasks, and logs remain available.
17
+
18
+ ```text
19
+ laptop remote SSH / RunPod / Lambda / Slurm
20
+ project ───────────── sync ──────────▶ project checkout
21
+ agent context ──────── optional ──────▶ Claude or Codex state
22
+ tmux session + durable task manager
23
+ terminal ◀────────── attach / stream ── persistent work
24
+ ```
25
+
26
+ ## Install
27
+
28
+ ```sh
29
+ uv tool install fwdit
30
+ ```
31
+
32
+ Or try it without installing:
33
+
34
+ ```sh
35
+ uvx --from fwdit fwd --help
36
+ ```
37
+
38
+ Requires Python 3.12+, `ssh`, and `rsync` locally. Run `fwd doctor` to check target-specific requirements.
39
+
40
+ ## Quick start
41
+
42
+ Run fwd from the project you want to move:
43
+
44
+ ```sh
45
+ fwd # attach to this project's session, or create one interactively
46
+ fwd up runpod codex # launch Codex on RunPod; auto-attach in a human terminal
47
+ fwd up --detach runpod codex # launch Codex but stay in the local terminal
48
+ fwd up --target work # use a configured SSH/cloud/HPC target
49
+ fwd up -- python train.py # launch and stream a durable command
50
+ fwd ls # inspect sessions and live status
51
+ fwd attach SESSION # reconnect from a human terminal
52
+ ```
53
+
54
+ Bare `fwd` is the interactive reuse workflow. Agent launches auto-attach in a human terminal; pass `--detach` to stay local. Scripts and coding-agent environments remain non-attaching. Detach from tmux with `Ctrl-B D`.
55
+
56
+ Need a saved target first?
57
+
58
+ ```sh
59
+ fwd setup # interactive target setup
60
+ fwd setup ssh --host my-box --target-name work
61
+ fwd config --example runpod # current generated config reference
62
+ ```
63
+
64
+ Read [Getting started](docs/getting-started.md) for the full first-session walkthrough.
65
+
66
+ ## Choose a target
67
+
68
+ - **SSH:** an existing host, direct address, or OpenSSH alias.
69
+ - **RunPod:** CPU or GPU Pods with per-session persistent network volumes by default.
70
+ - **Lambda Cloud:** GPU instances with persistent filesystems and local-only API credentials.
71
+ - **Slurm:** allocations launched through persistent login-node tmux on shared scratch.
72
+
73
+ See [Configuration and backends](docs/configuration.md#target-setup) for setup, storage, and lifecycle differences.
74
+
75
+ ## Common workflows
76
+
77
+ ### Run durable work
78
+
79
+ ```sh
80
+ fwd send -- pytest -q
81
+ fwd send --detach -- python train.py
82
+ fwd send --ls --json
83
+ fwd send TASK_ID # reattach to its log
84
+ fwd send TASK_ID --stop # cancel the task, not the session
85
+ ```
86
+
87
+ Every command runs in remote tmux with a durable ID and log. Streaming returns the remote exit code; `Ctrl-C` cancels and `Ctrl-B` backgrounds the viewer.
88
+
89
+ ### Synchronize results
90
+
91
+ ```sh
92
+ fwd diff # compare without changing either side
93
+ fwd push # mirror local synchronized files to remote
94
+ fwd pull outputs/ # additive download; never deletes local files
95
+ ```
96
+
97
+ Sync honors `.gitignore`, `.fwdignore`, and configured exclusions. Upload includes `.git/` for remote agent continuity; pull and diff exclude Git metadata.
98
+
99
+ ### Forward a service
100
+
101
+ ```sh
102
+ fwd ports 3000 # localhost:3000 to remote localhost:3000
103
+ fwd ports work 8080:3000
104
+ fwd ports --ls
105
+ fwd ports --close 3000
106
+ ```
107
+
108
+ Forwards are loopback-only and persist through a managed SSH control connection.
109
+
110
+ ### Stop or destroy compute
111
+
112
+ ```sh
113
+ fwd stop SESSION # stop compute and retain configured persistent storage
114
+ fwd rm SESSION # permanently destroy remote resources
115
+ ```
116
+
117
+ Both commands protect a reachable dirty remote Git worktree. `rm` is irreversible; force flags explicitly accept possible loss. See [Lifecycle safety](docs/commands.md#stop-remove-and-uninstall) before automating cleanup.
118
+
119
+ ## Coding-agent skill
120
+
121
+ fwd ships an Agent Skills-compatible workflow for Codex, Claude Code, and other supporting agents. The first interactive invocation offers to install the bundled skill. It can also be installed directly:
122
+
123
+ ```sh
124
+ npx skills add Sid-MB/fwd --skill fwd -g -a codex -a claude-code
125
+ ```
126
+
127
+ Invoke it as `$fwd ...` in Codex or `/fwd ...` in Claude Code. See [Coding agents](docs/agents.md#install-the-fwd-skill) for behavior and credential guidance.
128
+
129
+ ## Documentation
130
+
131
+ ### User guide
132
+
133
+ - [Getting started](docs/getting-started.md): installation, first launch, target setup, and the everyday workflow.
134
+ - [Commands and lifecycle](docs/commands.md): durable tasks, synchronization, inspection, port forwarding, stopping, and removal.
135
+ - [Configuration and backends](docs/configuration.md): config layers, SSH, RunPod, Lambda Cloud, Slurm, toolchains, and defaults.
136
+ - [Coding agents](docs/agents.md): Claude/Codex transfer, follow-up turns, credentials, runtime policy, and skill installation.
137
+ - [Troubleshooting](docs/troubleshooting.md): diagnostics, launch recovery, dirty worktrees, sync limits, and destructive operations.
138
+ - [User documentation index](docs/README.md): the complete end-user map.
139
+
140
+ The installed CLI is the authoritative option reference:
141
+
142
+ ```sh
143
+ fwd --help
144
+ fwd COMMAND --help
145
+ fwd config --example
146
+ fwd config --schema
147
+ ```
148
+
149
+ ### Developer guide
150
+
151
+ - [Developer documentation index](dev-docs/README.md): architecture, provider notes, validation evidence, and repository map.
152
+ - [Adding a target backend](dev-docs/adding-target-backends.md)
153
+ - [Adding a project toolchain](dev-docs/adding-toolchains.md)
154
+ - [Performance benchmarking](dev-docs/benchmarking.md)
155
+ - [Contributing](CONTRIBUTING.md)
fwdit-0.1.2/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # fwd
2
+
3
+ **Move your coding project and agent session to remote compute.**
4
+
5
+ `fwd` provisions or connects to a remote target, synchronizes the current project, prepares its toolchain, and starts a persistent shell, command, Claude Code, or Codex session in tmux. Disconnect your laptop and return later: the session, durable tasks, and logs remain available.
6
+
7
+ ```text
8
+ laptop remote SSH / RunPod / Lambda / Slurm
9
+ project ───────────── sync ──────────▶ project checkout
10
+ agent context ──────── optional ──────▶ Claude or Codex state
11
+ tmux session + durable task manager
12
+ terminal ◀────────── attach / stream ── persistent work
13
+ ```
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ uv tool install fwdit
19
+ ```
20
+
21
+ Or try it without installing:
22
+
23
+ ```sh
24
+ uvx --from fwdit fwd --help
25
+ ```
26
+
27
+ Requires Python 3.12+, `ssh`, and `rsync` locally. Run `fwd doctor` to check target-specific requirements.
28
+
29
+ ## Quick start
30
+
31
+ Run fwd from the project you want to move:
32
+
33
+ ```sh
34
+ fwd # attach to this project's session, or create one interactively
35
+ fwd up runpod codex # launch Codex on RunPod; auto-attach in a human terminal
36
+ fwd up --detach runpod codex # launch Codex but stay in the local terminal
37
+ fwd up --target work # use a configured SSH/cloud/HPC target
38
+ fwd up -- python train.py # launch and stream a durable command
39
+ fwd ls # inspect sessions and live status
40
+ fwd attach SESSION # reconnect from a human terminal
41
+ ```
42
+
43
+ Bare `fwd` is the interactive reuse workflow. Agent launches auto-attach in a human terminal; pass `--detach` to stay local. Scripts and coding-agent environments remain non-attaching. Detach from tmux with `Ctrl-B D`.
44
+
45
+ Need a saved target first?
46
+
47
+ ```sh
48
+ fwd setup # interactive target setup
49
+ fwd setup ssh --host my-box --target-name work
50
+ fwd config --example runpod # current generated config reference
51
+ ```
52
+
53
+ Read [Getting started](docs/getting-started.md) for the full first-session walkthrough.
54
+
55
+ ## Choose a target
56
+
57
+ - **SSH:** an existing host, direct address, or OpenSSH alias.
58
+ - **RunPod:** CPU or GPU Pods with per-session persistent network volumes by default.
59
+ - **Lambda Cloud:** GPU instances with persistent filesystems and local-only API credentials.
60
+ - **Slurm:** allocations launched through persistent login-node tmux on shared scratch.
61
+
62
+ See [Configuration and backends](docs/configuration.md#target-setup) for setup, storage, and lifecycle differences.
63
+
64
+ ## Common workflows
65
+
66
+ ### Run durable work
67
+
68
+ ```sh
69
+ fwd send -- pytest -q
70
+ fwd send --detach -- python train.py
71
+ fwd send --ls --json
72
+ fwd send TASK_ID # reattach to its log
73
+ fwd send TASK_ID --stop # cancel the task, not the session
74
+ ```
75
+
76
+ Every command runs in remote tmux with a durable ID and log. Streaming returns the remote exit code; `Ctrl-C` cancels and `Ctrl-B` backgrounds the viewer.
77
+
78
+ ### Synchronize results
79
+
80
+ ```sh
81
+ fwd diff # compare without changing either side
82
+ fwd push # mirror local synchronized files to remote
83
+ fwd pull outputs/ # additive download; never deletes local files
84
+ ```
85
+
86
+ Sync honors `.gitignore`, `.fwdignore`, and configured exclusions. Upload includes `.git/` for remote agent continuity; pull and diff exclude Git metadata.
87
+
88
+ ### Forward a service
89
+
90
+ ```sh
91
+ fwd ports 3000 # localhost:3000 to remote localhost:3000
92
+ fwd ports work 8080:3000
93
+ fwd ports --ls
94
+ fwd ports --close 3000
95
+ ```
96
+
97
+ Forwards are loopback-only and persist through a managed SSH control connection.
98
+
99
+ ### Stop or destroy compute
100
+
101
+ ```sh
102
+ fwd stop SESSION # stop compute and retain configured persistent storage
103
+ fwd rm SESSION # permanently destroy remote resources
104
+ ```
105
+
106
+ Both commands protect a reachable dirty remote Git worktree. `rm` is irreversible; force flags explicitly accept possible loss. See [Lifecycle safety](docs/commands.md#stop-remove-and-uninstall) before automating cleanup.
107
+
108
+ ## Coding-agent skill
109
+
110
+ fwd ships an Agent Skills-compatible workflow for Codex, Claude Code, and other supporting agents. The first interactive invocation offers to install the bundled skill. It can also be installed directly:
111
+
112
+ ```sh
113
+ npx skills add Sid-MB/fwd --skill fwd -g -a codex -a claude-code
114
+ ```
115
+
116
+ Invoke it as `$fwd ...` in Codex or `/fwd ...` in Claude Code. See [Coding agents](docs/agents.md#install-the-fwd-skill) for behavior and credential guidance.
117
+
118
+ ## Documentation
119
+
120
+ ### User guide
121
+
122
+ - [Getting started](docs/getting-started.md): installation, first launch, target setup, and the everyday workflow.
123
+ - [Commands and lifecycle](docs/commands.md): durable tasks, synchronization, inspection, port forwarding, stopping, and removal.
124
+ - [Configuration and backends](docs/configuration.md): config layers, SSH, RunPod, Lambda Cloud, Slurm, toolchains, and defaults.
125
+ - [Coding agents](docs/agents.md): Claude/Codex transfer, follow-up turns, credentials, runtime policy, and skill installation.
126
+ - [Troubleshooting](docs/troubleshooting.md): diagnostics, launch recovery, dirty worktrees, sync limits, and destructive operations.
127
+ - [User documentation index](docs/README.md): the complete end-user map.
128
+
129
+ The installed CLI is the authoritative option reference:
130
+
131
+ ```sh
132
+ fwd --help
133
+ fwd COMMAND --help
134
+ fwd config --example
135
+ fwd config --schema
136
+ ```
137
+
138
+ ### Developer guide
139
+
140
+ - [Developer documentation index](dev-docs/README.md): architecture, provider notes, validation evidence, and repository map.
141
+ - [Adding a target backend](dev-docs/adding-target-backends.md)
142
+ - [Adding a project toolchain](dev-docs/adding-toolchains.md)
143
+ - [Performance benchmarking](dev-docs/benchmarking.md)
144
+ - [Contributing](CONTRIBUTING.md)
fwdit-0.1.2/SKILL.md ADDED
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: fwd
3
+ description: Move a coding project or active Claude Code/Codex workflow to remote compute with fwd. Use for remote development, SSH, RunPod, Lambda Cloud, Slurm, extra CPU/GPU/memory, persistent remote agents, durable commands, synchronization, attaching, stopping, or destroying remote sessions.
4
+ ---
5
+
6
+ # fwd remote development
7
+
8
+ Use `fwd` to provision or reuse remote compute, synchronize the current project, prepare its tools, and run a persistent coding agent or command in tmux. Invoking this skill means the user wants fwd used.
9
+
10
+ ## Workflow
11
+
12
+ 1. Preserve the user's task, requested target, hardware, and shutdown requirements. Use the caller's agent (`codex` from Codex, `claude` from Claude) unless the user specifies another.
13
+ 2. If a provider machine must be chosen, inspect exact values before launch with `fwd up --machines` or `fwd up TARGET --machines`. Prefer CPU unless the user requests a GPU; never guess or abbreviate a provider identifier.
14
+ 3. Launch without taking over the terminal: `fwd up --detach --agent AGENT`, adding `--target TARGET` and `--machine MACHINE` only when selected. Never use a bare/reuse/attach form as a tool call.
15
+ 4. Read the exact session name and live state from `fwd ls --json`.
16
+ 5. Send the preserved task with `fwd send --name SESSION agent "TASK"`. Stream and iterate by default; use `--detach` only when the user asks to background the task.
17
+ 6. Inspect changed work with `fwd diff -q SESSION`, use `fwd diff SESSION` when details matter, and retrieve accepted files with `fwd pull --name SESSION`.
18
+ 7. Report the result and exact commands the user may need, especially `fwd attach SESSION`, `fwd send --name SESSION --ls`, and `fwd stop SESSION`.
19
+
20
+ If setup is required, follow the exact flags printed by fwd. Do not open an interactive setup wizard or invent target values.
21
+
22
+ For a requested shell command instead of agent work, use `fwd send --name SESSION -- COMMAND...`. Reattach with `fwd send --name SESSION TASK_ID`; cancel only that task with `fwd send --name SESSION TASK_ID --stop`.
23
+
24
+ If `fwd` is unavailable, install the published distribution with `uv tool install fwdit`. If `uv` is unavailable, report that Python 3.12+, `uv`, `ssh`, and `rsync` are required instead of improvising another installer.
25
+
26
+ ## Safe automation
27
+
28
+ - Prefer `--json` for `fwd ls`, `fwd doctor`, `fwd info`, and task listings. Diagnostics remain on stderr.
29
+ - Never run bare `fwd`, `fwd TARGET`, `fwd attach`, `fwd a`, `fwd up --reuse`, or `fwd up --attach` as a tool call; they can take over a human terminal. Hand the exact attach command to the user.
30
+ - Do not use `--restart` unless the user authorizes restarting stopped billable compute.
31
+ - Do not use `--creds` unless the user authorizes copying live Claude credentials. GitHub setup defaults on; use `--no-setup-github` when credentials must stay local.
32
+ - Never force `stop`, `rm`, or stop-after past a dirty or unreachable worktree unless the user explicitly accepts losing remote-only changes.
33
+ - Never run `fwd rm --all --force` unless the user explicitly requests destruction of every tracked remote resource.
34
+ - Run `fwd uninstall --force` only for an explicit local-uninstall request after explaining that it does not destroy remote resources; prefer `fwd rm --all` first.
35
+ - Prefer `fwd diff -q` before push or pull. Exit 0 means synchronized, 1 different, and 2 error.
36
+ - If upload exceeds `sync.max_size_gb`, confirm the directory is intentional before using the exact project-scoped limit command printed by fwd.
37
+ - Missing `npx` or a failed optional skill refresh must not block normal fwd commands.
38
+ - If preparation fails after provisioning and sync, give the human `fwd attach SESSION --raw` for a recovery shell. This does not authorize restarting stopped compute.
39
+
40
+ ## Stop after work
41
+
42
+ For supported backends, use remote-owned shutdown so it survives local disconnection:
43
+
44
+ ```sh
45
+ fwd up --stop-after -- COMMAND...
46
+ fwd send --name SESSION --stop-after agent "TASK"
47
+ fwd send --name SESSION stopafter
48
+ fwd send --name SESSION cancel stopafter
49
+ ```
50
+
51
+ Confirm the lifecycle task with `fwd send --name SESSION --ls --json`. Stop-after refuses a dirty remote worktree; never force it without explicit acceptance of data loss.
52
+
53
+ Lambda does not support remote stop-after because its broad API key stays local. Retrieve durable results, then tell the user to run `fwd stop SESSION` from a connected machine.
54
+
55
+ ## Useful commands
56
+
57
+ ```sh
58
+ fwd up --detach --target runpod --agent codex
59
+ fwd up --detach --new --target runpod --agent codex
60
+ fwd up -- COMMAND...
61
+ fwd send --name SESSION agent "TASK"
62
+ fwd send --name SESSION -- COMMAND...
63
+ fwd send --name SESSION --ls --json
64
+ fwd diff -q SESSION
65
+ fwd pull --name SESSION outputs/
66
+ fwd ls --all-projects --json
67
+ fwd doctor --json
68
+ ```
69
+
70
+ ## References
71
+
72
+ - Read [targets and configuration](references/targets-and-config.md) for resolution, setup, defaults, machines, and backend behavior.
73
+ - Read [commands and lifecycle](references/commands-and-lifecycle.md) for launch, durable tasks, synchronization, ports, attachment, stopping, and destruction.
74
+ - Read [agent transfer](references/agent-transfer.md) before launching Claude Code or Codex when transcripts, settings, skills, authentication, or remote control matter.
75
+
76
+ `fwd --help` and `fwd COMMAND --help` are authoritative for the installed version.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "fwd Remote Development"
3
+ short_description: "Move coding work to remote compute"
4
+ default_prompt: "Use $fwd to continue this project on a remote machine."
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,39 @@
1
+ # fwd developer documentation
2
+
3
+ This folder contains architecture, extension, validation, and implementation notes for contributors working on fwd.
4
+
5
+ ## Extend fwd
6
+
7
+ - [Adding a target backend](adding-target-backends.md): backend contract, configuration schema, lifecycle safety, registration, and verification.
8
+ - [Adding a project toolchain](adding-toolchains.md): detection, requirements, installation, registration, and testing.
9
+
10
+ ## Understand provider implementations
11
+
12
+ - [RunPod notes](runpod-notes.md): observed `runpodctl` behavior, endpoint churn, persistence, and fixtures.
13
+ - [Lambda Cloud notes](lambda-notes.md): API, credential handling, deterministic ownership, storage, and lifecycle.
14
+ - [Slurm notes](slurm-notes.md): login-node tmux, allocation scripts, path guards, and shared scratch.
15
+
16
+ ## Validation and performance
17
+
18
+ - [Live end-to-end report](live-e2e-report.md): dated RunPod validation evidence and discovered regressions.
19
+ - [Session transfer notes](session-transfer-notes.md): Claude transcript relocation experiment and encoding rules.
20
+ - [Performance benchmarking](benchmarking.md): in-process command benchmarks and baseline comparison.
21
+
22
+ ## Repository map
23
+
24
+ - `src/fwd/backends/`: provider lifecycle implementations.
25
+ - `src/fwd/toolchains/` and `src/fwd/tooling.py`: project detection and remote requirements.
26
+ - `src/fwd/ops/`: launch, attach, synchronization, lifecycle, and task orchestration.
27
+ - `src/fwd/agents/`: Claude and Codex transfer/runtime integrations.
28
+ - `tests/`: offline unit and integration tests; provider fixtures are under `tests/fixtures/`.
29
+ - `references/`: compact references packaged with the coding-agent skill, not the end-user documentation site.
30
+
31
+ ## Development workflow
32
+
33
+ ```sh
34
+ uv sync
35
+ uv run pytest
36
+ uv run fwd --help
37
+ ```
38
+
39
+ See [CONTRIBUTING.md](../CONTRIBUTING.md) for contribution and publishing policy. User-facing behavior belongs in [docs](../docs/README.md), and concise project orientation belongs in the [top-level README](../README.md).
@@ -0,0 +1,20 @@
1
+ # fwd user guide
2
+
3
+ This folder contains the user documentation for `fwd`. Start with the guide that matches what you want to do:
4
+
5
+ - [Getting started](getting-started.md): install fwd, create a target, and launch your first remote session.
6
+ - [Commands and lifecycle](commands.md): launch, attach, run durable tasks, synchronize files, forward ports, stop, and remove sessions.
7
+ - [Configuration and backends](configuration.md): layered configuration, SSH, RunPod, Lambda Cloud, Slurm, defaults, and project setup.
8
+ - [Coding agents](agents.md): move Claude Code or Codex work, send follow-up turns, manage credentials, and install the fwd skill.
9
+ - [Troubleshooting](troubleshooting.md): diagnose failures, recover partial launches, and avoid data loss.
10
+
11
+ The installed CLI is the authoritative option reference:
12
+
13
+ ```sh
14
+ fwd --help
15
+ fwd COMMAND --help
16
+ fwd config --example
17
+ fwd config --schema
18
+ ```
19
+
20
+ Contributing to fwd? See the [developer documentation](../dev-docs/README.md).
@@ -0,0 +1,47 @@
1
+ [project]
2
+ name = "fwdit"
3
+ dynamic = ["version"]
4
+ description = "Move coding work and agent sessions to remote compute"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "prompt-toolkit>=3.0",
9
+ "typer>=0.12",
10
+ "rich>=13",
11
+ "tomlkit>=0.13",
12
+ ]
13
+
14
+ [project.scripts]
15
+ fwd = "fwd.cli:entrypoint"
16
+
17
+ [dependency-groups]
18
+ dev = ["pytest>=8"]
19
+
20
+ [build-system]
21
+ requires = ["hatchling", "hatch-vcs"]
22
+ build-backend = "hatchling.build"
23
+
24
+ [tool.hatch.version]
25
+ # The shared release workflow creates the next vX.Y.Z tag before building, so the wheel, sdist, Git tag, and GitHub Release all receive the same immutable version.
26
+ source = "vcs"
27
+
28
+ [tool.hatch.version.raw-options]
29
+ # Source archives without Git metadata still expose a valid diagnostic version instead of failing to build.
30
+ fallback_version = "0.0.0"
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["src/fwd"]
34
+
35
+ # bootstrap.sh must land inside the installed package so remote.BOOTSTRAP_PATH can resolve it via importlib.resources.
36
+ [tool.hatch.build.targets.wheel.force-include]
37
+ "src/fwd/scripts/bootstrap.sh" = "fwd/scripts/bootstrap.sh"
38
+ "src/fwd/scripts/codex_tui_send.py" = "fwd/scripts/codex_tui_send.py"
39
+ "SKILL.md" = "fwd/SKILL.md"
40
+ "agents" = "fwd/skill_agents"
41
+ "references" = "fwd/references"
42
+
43
+ [tool.hatch.build.targets.sdist]
44
+ include = ["src/fwd", "tests", "README.md", "/SKILL.md", "/agents", "/references"]
45
+
46
+ [tool.pytest.ini_options]
47
+ testpaths = ["tests"]
@@ -0,0 +1,83 @@
1
+ # Claude Code and Codex transfer
2
+
3
+ ## Contents
4
+
5
+ - Shared behavior
6
+ - Claude Code
7
+ - Codex
8
+ - Authentication
9
+ - Human handoff
10
+
11
+ ## Shared behavior
12
+
13
+ Both magic commands synchronize the project, bootstrap remote tooling, start a persistent tmux session, and auto-attach only from a human terminal:
14
+
15
+ ```sh
16
+ fwd up --target TARGET --agent claude
17
+ fwd up --target TARGET --agent codex
18
+ ```
19
+
20
+ Agents should run them without `--attach`. Non-interactive detection keeps the launch in the background.
21
+
22
+ On RunPod, fwd prepares agent state before tool installation because `/root` is erased on every stop. GPU pods keep
23
+ `~/.claude` or `~/.codex` beneath the persistent tool prefix and recreate the home symlink on relaunch, so remote
24
+ authentication, conversations, settings, and Codex's managed standalone payload survive. CPU pods have no persistent
25
+ volume; their full relaunch reconstructs local inputs but cannot retain state that existed only on the stopped pod.
26
+
27
+ After launch, communicate with the running remote conversation through durable send tasks:
28
+
29
+ ```sh
30
+ fwd send agent --detach "run the tests and fix failures"
31
+ fwd send --ls --json
32
+ fwd send TASK_ID
33
+ fwd send TASK_ID --stop
34
+ ```
35
+
36
+ Use `--immediate MESSAGE` when a new instruction should cancel and replace the active turn. A plain message queues
37
+ behind an active managed turn. Send-task cancellation never stops the fwd session or its remote compute.
38
+
39
+ ## Claude Code
40
+
41
+ The default `--session` mode moves the real local transcript and asks remote Claude to resume it. Transfer failures degrade to a plain Claude launch with a warning.
42
+
43
+ `--handoff` replaces transcript transfer with a generated `HANDOFF.md`; use it only when the user requests a summary handoff. `--user-config` uploads portable Claude configuration while excluding credentials and history.
44
+
45
+ ## Codex
46
+
47
+ Codex receives portable settings, configuration, and skills. It does not receive the current Codex transcript or authentication. Tell the user that the remote agent begins with the synchronized project and personal workflow configuration, not the local conversation.
48
+
49
+ Once remote Codex has started, `fwd send agent MESSAGE` resumes its most recent remote project conversation through
50
+ Codex's JSONL non-interactive interface. Human terminals receive concise text/tool events; non-interactive callers
51
+ receive the original machine-readable event stream.
52
+
53
+ Use JSON output and non-attaching commands when Codex is driving fwd:
54
+
55
+ ```sh
56
+ fwd doctor --json
57
+ fwd up codex --target TARGET
58
+ fwd ls --json
59
+ fwd diff -q TARGET
60
+ ```
61
+
62
+ ## Authentication
63
+
64
+ Prefer logging in on the remote machine for coding-agent authentication. `--creds` writes a live Claude OAuth token to remote disk and requires explicit authorization in the current conversation. Codex authentication is never copied.
65
+
66
+ GitHub authentication defaults on for development VMs and can be disabled with `[github] auth = false` or
67
+ `--no-setup-github`. Fwd resolves `GH_TOKEN`, `GITHUB_TOKEN`, the active local gh account, Git's credential helper,
68
+ then `~/.netrc`; an interactive caller can paste a PAT as the final fallback. It streams the selected credential to remote standard
69
+ input, configures HTTPS Git access, and persists the remote credential on RunPod volumes. The token never enters
70
+ project files, argv, logs, config, or session state. A direct `fwd send git push`, any sent coding-agent turn, and
71
+ `fwd attach` can repair an older session in place. Do not describe `fwd pull && git push` as a way to transfer a remote
72
+ commit: pull intentionally omits `.git/`. It can retrieve uncommitted files for a new local commit; preserving an
73
+ existing remote commit requires a remote push or an explicitly exported patch or Git bundle.
74
+
75
+ ## Human handoff
76
+
77
+ After launch, report the exact resolved target/session and tell the human:
78
+
79
+ ```sh
80
+ fwd attach SESSION
81
+ ```
82
+
83
+ If the user wants a result without attaching, use `fwd send agent`, `fwd send -- COMMAND`, or `fwd pull`.