moshcode 0.24.0

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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +580 -0
  3. package/bin/moshcode.mjs +674 -0
  4. package/bin/moshscript.mjs +29 -0
  5. package/examples/alive.mosh +6 -0
  6. package/examples/scripting-the-cli.mosh +21 -0
  7. package/examples/team-secrets.mosh +20 -0
  8. package/examples/templates/bun-caddy-sqlite/.env.example +14 -0
  9. package/examples/templates/bun-caddy-sqlite/Caddyfile +18 -0
  10. package/examples/templates/bun-caddy-sqlite/README.md +97 -0
  11. package/examples/templates/bun-caddy-sqlite/deploy/moshcode-dns.service +39 -0
  12. package/examples/templates/bun-caddy-sqlite/deploy/moshpit-service.service +38 -0
  13. package/examples/templates/bun-caddy-sqlite/package.json +15 -0
  14. package/examples/templates/bun-caddy-sqlite/src/db.ts +47 -0
  15. package/examples/templates/bun-caddy-sqlite/src/server.ts +44 -0
  16. package/examples/templates/bun-caddy-sqlite/template.json +10 -0
  17. package/examples/templates/caddy-proxy/Caddyfile +36 -0
  18. package/examples/templates/caddy-proxy/README.md +104 -0
  19. package/examples/templates/caddy-proxy/deploy/moshcode-dns.service +39 -0
  20. package/examples/templates/caddy-proxy/template.json +8 -0
  21. package/examples/templates/caddy-static/Caddyfile +16 -0
  22. package/examples/templates/caddy-static/README.md +90 -0
  23. package/examples/templates/caddy-static/deploy/moshcode-dns.service +39 -0
  24. package/examples/templates/caddy-static/site/index.html +11 -0
  25. package/examples/templates/caddy-static/template.json +8 -0
  26. package/install.sh +194 -0
  27. package/package.json +28 -0
  28. package/prd/0000-template.md +49 -0
  29. package/prd/0001-wrap-ugig-and-coinpay-clis.md +121 -0
  30. package/prd/0002-separate-agent-and-raw-engine-launches.md +113 -0
  31. package/prd/0003-cross-engine-mcp-and-skill-installation.md +165 -0
  32. package/prd/0004-moshscript-run-programmable-moshcode.md +344 -0
  33. package/prd/0005-hosted-moshpit-resolver.md +192 -0
  34. package/prd/0006-help.md +359 -0
  35. package/prd/0007-profullstack-site-init.md +1183 -0
  36. package/prd/README.md +26 -0
  37. package/src/ads.mjs +58 -0
  38. package/src/auth.mjs +193 -0
  39. package/src/cli-schema.mjs +533 -0
  40. package/src/cli.mjs +118 -0
  41. package/src/commands.mjs +259 -0
  42. package/src/completion.mjs +594 -0
  43. package/src/console.mjs +244 -0
  44. package/src/dns-system.mjs +404 -0
  45. package/src/dns.mjs +2872 -0
  46. package/src/doh-server.mjs +256 -0
  47. package/src/doh.mjs +218 -0
  48. package/src/engines.mjs +385 -0
  49. package/src/escalate.mjs +85 -0
  50. package/src/help.mjs +443 -0
  51. package/src/integrations.mjs +265 -0
  52. package/src/mcp-catalog.mjs +50 -0
  53. package/src/mcp.mjs +155 -0
  54. package/src/mirror.mjs +187 -0
  55. package/src/notify.mjs +86 -0
  56. package/src/open-url.mjs +34 -0
  57. package/src/parking-http.mjs +65 -0
  58. package/src/pins.mjs +190 -0
  59. package/src/pit-url.mjs +13 -0
  60. package/src/prd.mjs +341 -0
  61. package/src/pty.mjs +176 -0
  62. package/src/pwd.mjs +103 -0
  63. package/src/registry.mjs +37 -0
  64. package/src/release-install.mjs +191 -0
  65. package/src/runtime.mjs +161 -0
  66. package/src/selfupdate.mjs +215 -0
  67. package/src/serve.mjs +502 -0
  68. package/src/skills.mjs +93 -0
  69. package/src/tabs.mjs +144 -0
  70. package/src/templates.mjs +456 -0
  71. package/src/tools.mjs +231 -0
  72. package/src/trade.mjs +137 -0
  73. package/src/trust.mjs +712 -0
  74. package/src/tui.mjs +736 -0
  75. package/src/ui.mjs +49 -0
  76. package/src/uninstall.mjs +113 -0
  77. package/src/upgrade.mjs +217 -0
@@ -0,0 +1,90 @@
1
+ # caddy-static
2
+
3
+ A static site at a Moshpit name. No runtime, no database, no service to keep
4
+ alive — Caddy and a directory of files.
5
+
6
+ Reach for [`bun-caddy-sqlite`](../bun-caddy-sqlite) instead when you need
7
+ something that runs.
8
+
9
+ ## The part that surprises people
10
+
11
+ Three machines' worth of concerns, and they fail independently:
12
+
13
+ | | needs the resolver? | what it does |
14
+ |---|---|---|
15
+ | the box serving the name | **no** | Caddy matches a `Host` header, nothing more |
16
+ | the registry | — | holds the address the name points at |
17
+ | every visitor | **yes** | `sudo moshcode dns enable`, or the name resolves to nothing |
18
+
19
+ Nothing on the server ever resolves its own name. That is why there is no DNS
20
+ software in this template.
21
+
22
+ ## Setup
23
+
24
+ 1. **Point the name at the box.** In the Pit, set `points at` to its public
25
+ IPv6 address — bare, no scheme, no brackets, no port:
26
+
27
+ ```sh
28
+ ip -6 addr show scope global | grep inet6
29
+ ```
30
+
31
+ Pick the globally routable one. An `fd..`/`fc..` address is unique-local
32
+ (Tailscale and friends live there) and the registry refuses it, because a
33
+ name pointed at one resolves somewhere only you can reach.
34
+
35
+ 2. **Put the files where the Caddyfile expects them.** `SITE_ROOT` defaults to
36
+ `/srv/moshpit-site`; `site/` here is a placeholder to replace.
37
+
38
+ ```sh
39
+ sudo mkdir -p /srv/moshpit-site
40
+ sudo cp -r site/. /srv/moshpit-site/
41
+ ```
42
+
43
+ 3. **Serve it.**
44
+
45
+ ```sh
46
+ export MOSHPIT_NAME=foo.whatever
47
+ export SITE_ROOT=/srv/moshpit-site
48
+ sudo cp Caddyfile /etc/caddy/Caddyfile
49
+ sudo systemctl enable --now caddy
50
+ sudo ufw allow 80/tcp
51
+ ```
52
+
53
+ 4. **Reach it,** on any machine that should see the name:
54
+
55
+ ```sh
56
+ sudo moshcode dns enable
57
+ sudo cp deploy/moshcode-dns.service /etc/systemd/system/ # survives reboot
58
+ sudo systemctl enable --now moshcode-dns
59
+ ```
60
+
61
+ ## Verifying, one layer at a time
62
+
63
+ A failure at any layer looks identical in a browser, so do not start there.
64
+
65
+ ```sh
66
+ # Server only — no DNS involved. Proves Caddy and the firewall.
67
+ curl -6 -H "Host: foo.whatever" http://[YOUR:V6:ADDR]/
68
+
69
+ # Resolver only. Proves the registry and the bridge.
70
+ moshcode dns resolve foo.whatever
71
+
72
+ # Both.
73
+ curl -6 http://foo.whatever/
74
+ ```
75
+
76
+ If the first works and the last does not, it is DNS. If the first fails, stop
77
+ looking at DNS.
78
+
79
+ ## Known limits
80
+
81
+ - **No HTTPS, ever.** No CA will issue for an ending outside the DNS root. That
82
+ rules out secure cookies, service workers, and WebCrypto in the browser. The
83
+ `http://` in the Caddyfile is what stops Caddy trying and failing.
84
+ - **Only machines running the resolver can reach the name.** Not phones, not a
85
+ colleague who has not installed it, not webhooks.
86
+ `pit.moshcode.sh/n/foo.whatever` is the URL for people who installed nothing.
87
+ - **One level deep.** `foo.whatever` works; `www.foo.whatever` does not.
88
+ - **Port 80 only** on the resolver path. A DNS record carries an address and has
89
+ nowhere to put a port, so a target like `[addr]:8080` only works through the
90
+ `/n/` gateway.
@@ -0,0 +1,39 @@
1
+ # The Moshpit resolver, kept running across reboots.
2
+ #
3
+ # `moshcode dns enable` sets up two halves: a systemd-resolved drop-in that
4
+ # routes Moshpit endings at the bridge, and the bridge process itself. The
5
+ # drop-in is a file and survives a reboot on its own. The process does not —
6
+ # so after a restart the routing still points at a port with nothing behind it,
7
+ # and every Moshpit name stops resolving with no obvious cause. This unit is
8
+ # the missing half.
9
+ #
10
+ # sudo cp deploy/moshcode-dns.service /etc/systemd/system/
11
+ # sudo systemctl enable --now moshcode-dns
12
+ #
13
+ # Install this on machines that need to REACH Moshpit names. A box that only
14
+ # serves one does not need it — Caddy answers whatever Host header arrives and
15
+ # never resolves its own name.
16
+
17
+ [Unit]
18
+ Description=Moshpit DNS bridge
19
+ After=network-online.target
20
+ Wants=network-online.target
21
+ Before=systemd-resolved.service
22
+
23
+ [Service]
24
+ Type=simple
25
+ # Port 5354 is unprivileged, so this does not need root. The trade-off is that
26
+ # the parking responder cannot take port 80 and falls back to the public
27
+ # parking address — which only affects names that point nowhere yet.
28
+ ExecStart=/usr/bin/env moshcode dns start --port 5354
29
+ Restart=always
30
+ RestartSec=2
31
+
32
+ DynamicUser=yes
33
+ NoNewPrivileges=yes
34
+ PrivateTmp=yes
35
+ ProtectSystem=strict
36
+ ProtectHome=yes
37
+
38
+ [Install]
39
+ WantedBy=multi-user.target
@@ -0,0 +1,11 @@
1
+ <!doctype html>
2
+ <meta charset="utf-8">
3
+ <title>served at a moshpit name</title>
4
+ <h1>It resolved.</h1>
5
+ <p>
6
+ Your resolver answered this name out of the Moshpit registry and connected
7
+ straight to the box holding it. Nothing proxied, nothing redirected.
8
+ </p>
9
+ <p>
10
+ Replace this file. It lives in whatever <code>SITE_ROOT</code> points at.
11
+ </p>
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "caddy-static",
3
+ "description": "Caddy serving a static site at a Moshpit name — no runtime, no service to keep alive",
4
+ "vars": {
5
+ "MOSHPIT_NAME": "the registered name to serve, e.g. foo.whatever",
6
+ "SITE_ROOT": "directory of files to serve (default /srv/moshpit-site)"
7
+ }
8
+ }
package/install.sh ADDED
@@ -0,0 +1,194 @@
1
+ #!/bin/sh
2
+ # moshcode — one-line installer 🤘
3
+ #
4
+ # Usage:
5
+ # curl -fsSL https://moshcoding.com/install.sh | sh
6
+ # curl -fsSL https://moshcoding.com/install.sh | sh -s -- update (alias: upgrade)
7
+ # curl -fsSL https://moshcoding.com/install.sh | sh -s -- remove (alias: uninstall)
8
+ #
9
+ # (also works straight from GitHub:)
10
+ # curl -fsSL https://raw.githubusercontent.com/moshcoder/moshcode/main/install.sh | sh
11
+ #
12
+ # What it does — dead simple, no build step:
13
+ # 1. Checks for Node.js 18+ (moshcode is zero-dependency ESM — needs a node).
14
+ # 2. Downloads the latest release tarball of moshcoder/moshcode from GitHub
15
+ # (falls back to the main branch if no release is published yet).
16
+ # 3. Unpacks it to $MOSHCODE_HOME (default: $HOME/.moshcode).
17
+ # 4. Drops a `moshcode` wrapper at $MOSHCODE_BIN (default: $HOME/.local/bin)
18
+ # that just exec's `node $MOSHCODE_HOME/bin/moshcode.mjs "$@"`.
19
+ # 5. Ensures that bin dir is on your PATH.
20
+ #
21
+ # Env overrides:
22
+ # MOSHCODE_HOME=/path install dir (default: $HOME/.moshcode)
23
+ # MOSHCODE_BIN=/path/dir wrapper bin dir (default: $HOME/.local/bin)
24
+ # MOSHCODE_REF=vX.Y.Z pin a tag/branch (default: latest release, else main)
25
+ # MOSHCODE_ALLOW_ROOT=1 install as root anyway (see below)
26
+ #
27
+ # Do not install this with sudo. moshcode is a user-level CLI, and every path
28
+ # here is derived from $HOME — under sudo that is /root, so the payload and the
29
+ # wrapper land in root's home where your own user cannot read them. Nothing
30
+ # fails at install time; it surfaces later as "permission denied" on a binary
31
+ # that looks installed. The installer refuses that case and tells you how.
32
+ #
33
+ # Re-running updates an existing install in place.
34
+
35
+ set -eu
36
+
37
+ REPO="moshcoder/moshcode"
38
+ INSTALL_URL="https://moshcoding.com/install.sh"
39
+ MOSHCODE_HOME="${MOSHCODE_HOME:-$HOME/.moshcode}"
40
+ MOSHCODE_BIN="${MOSHCODE_BIN:-$HOME/.local/bin}"
41
+ WRAPPER="$MOSHCODE_BIN/moshcode"
42
+ SCRIPT_WRAPPER="$MOSHCODE_BIN/moshscript"
43
+
44
+ # ---- pretty output (acid-lime, matching the CLI) --------------------------
45
+ if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
46
+ ACID=$(printf '\033[38;2;158;240;26m'); ASH=$(printf '\033[38;2;139;147;138m')
47
+ RED=$(printf '\033[31m'); BOLD=$(printf '\033[1m'); RESET=$(printf '\033[0m')
48
+ else
49
+ ACID=''; ASH=''; RED=''; BOLD=''; RESET=''
50
+ fi
51
+ info() { printf '%s·%s %s\n' "$ASH" "$RESET" "$*"; }
52
+ ok() { printf '%s✓%s %s\n' "$ACID" "$RESET" "$*"; }
53
+ fail() { printf '%s✗%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; }
54
+
55
+ # ---- prerequisites --------------------------------------------------------
56
+ need() { command -v "$1" >/dev/null 2>&1 || fail "$1 is required but not found."; }
57
+
58
+ # Installing under sudo silently installs for the wrong user. Every path here
59
+ # comes from $HOME, which sudo sets to /root, so the payload and wrappers land
60
+ # in a directory mode 0700 root — invisible to the user who ran the command.
61
+ # The install reports success and only breaks later, at first use.
62
+ #
63
+ # A bare root shell (containers, CI images, root-only boxes) has no SUDO_USER
64
+ # and is a legitimate way to install, so only the sudo-from-a-real-user case is
65
+ # refused, and MOSHCODE_ALLOW_ROOT overrides even that.
66
+ check_not_sudo() {
67
+ [ "$(id -u)" = "0" ] || return 0
68
+ [ -n "${SUDO_USER:-}" ] || return 0
69
+ if [ -n "${MOSHCODE_ALLOW_ROOT:-}" ]; then
70
+ info "MOSHCODE_ALLOW_ROOT set — installing as root into $MOSHCODE_HOME"
71
+ return 0
72
+ fi
73
+ fail "don't install moshcode with sudo.
74
+
75
+ Every path is based on \$HOME, which sudo has set to $HOME, so this would
76
+ install for root and leave $SUDO_USER unable to run it.
77
+
78
+ Run it as yourself instead:
79
+ curl -fsSL $INSTALL_URL | sh
80
+
81
+ If you really do want it system-wide, choose the paths explicitly:
82
+ sudo MOSHCODE_ALLOW_ROOT=1 MOSHCODE_HOME=/opt/moshcode \\
83
+ MOSHCODE_BIN=/usr/local/bin sh -c 'curl -fsSL $INSTALL_URL | sh'"
84
+ }
85
+
86
+ check_node() {
87
+ command -v node >/dev/null 2>&1 || fail \
88
+ "Node.js 18+ is required. Install it (https://nodejs.org) and re-run."
89
+ _major="$(node -v 2>/dev/null | sed 's/^v//' | cut -d. -f1)"
90
+ [ "${_major:-0}" -ge 18 ] || fail "Node.js 18+ required, found $(node -v)."
91
+ ok "Node.js $(node -v)"
92
+ unset _major
93
+ }
94
+
95
+ # Resolve the download URL for the latest release tag, or fall back to main.
96
+ resolve_ref() {
97
+ if [ -n "${MOSHCODE_REF:-}" ]; then
98
+ echo "$MOSHCODE_REF"; return 0
99
+ fi
100
+ # Ask GitHub for the latest release tag (no auth needed for public repos).
101
+ _tag="$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" 2>/dev/null \
102
+ | grep '"tag_name"' | head -1 | sed 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/')"
103
+ if [ -n "$_tag" ]; then echo "$_tag"; else echo "main"; fi
104
+ unset _tag
105
+ }
106
+
107
+ fetch_and_unpack() {
108
+ _ref="$1"
109
+ _url="https://codeload.github.com/$REPO/tar.gz/$_ref"
110
+ info "downloading moshcode@$_ref"
111
+ _tmp="$(mktemp -d 2>/dev/null || mktemp -d -t moshcode)"
112
+ if ! curl -fsSL "$_url" | tar -xz -C "$_tmp" 2>/dev/null; then
113
+ rm -rf "$_tmp"; fail "download failed ($_url) — check the ref/network."
114
+ fi
115
+ # Tarball extracts to a single top-level dir (e.g. moshcode-main/).
116
+ _src="$(find "$_tmp" -maxdepth 1 -type d -name 'moshcode-*' | head -1)"
117
+ [ -n "$_src" ] && [ -f "$_src/bin/moshcode.mjs" ] || { rm -rf "$_tmp"; fail "unexpected tarball layout."; }
118
+ rm -rf "$MOSHCODE_HOME"
119
+ mkdir -p "$(dirname "$MOSHCODE_HOME")"
120
+ mv "$_src" "$MOSHCODE_HOME"
121
+ rm -rf "$_tmp"
122
+ chmod +x "$MOSHCODE_HOME/bin/moshcode.mjs" 2>/dev/null || true
123
+ ok "installed to $MOSHCODE_HOME"
124
+ unset _ref _url _tmp _src
125
+ }
126
+
127
+ write_wrapper() {
128
+ mkdir -p "$MOSHCODE_BIN"
129
+ cat > "$WRAPPER" <<WRAP_EOF
130
+ #!/bin/sh
131
+ # moshcode wrapper — installed by $INSTALL_URL. Re-run the installer to update.
132
+ exec node "$MOSHCODE_HOME/bin/moshcode.mjs" "\$@"
133
+ WRAP_EOF
134
+ chmod +x "$WRAPPER"
135
+ ok "wrapper at $WRAPPER"
136
+
137
+ # moshscript — thin alias for `moshcode run`, so .mosh files can use
138
+ # #!/usr/bin/env moshscript as a shebang and run like shell scripts.
139
+ cat > "$SCRIPT_WRAPPER" <<SCRIPT_EOF
140
+ #!/bin/sh
141
+ # moshscript wrapper — installed by $INSTALL_URL. Re-run the installer to update.
142
+ exec node "$MOSHCODE_HOME/bin/moshcode.mjs" run "\$@"
143
+ SCRIPT_EOF
144
+ chmod +x "$SCRIPT_WRAPPER"
145
+ ok "wrapper at $SCRIPT_WRAPPER"
146
+ }
147
+
148
+ ensure_path() {
149
+ case ":$PATH:" in *":$MOSHCODE_BIN:"*) return 0 ;; esac
150
+ for rc in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.profile"; do
151
+ [ -f "$rc" ] || continue
152
+ grep -q "$MOSHCODE_BIN" "$rc" 2>/dev/null && continue
153
+ printf '\n# Added by moshcode installer\nexport PATH="%s:$PATH"\n' "$MOSHCODE_BIN" >> "$rc"
154
+ done
155
+ info "add $MOSHCODE_BIN to PATH in this shell: export PATH=\"$MOSHCODE_BIN:\$PATH\""
156
+ }
157
+
158
+ # ---- commands -------------------------------------------------------------
159
+ run_install() {
160
+ printf '\n%smoshcode installer%s %s— code hard, mosh harder 🤘%s\n\n' "$BOLD" "$RESET" "$ASH" "$RESET"
161
+ check_not_sudo
162
+ need curl; need tar
163
+ check_node
164
+ _ref="$(resolve_ref)"
165
+ fetch_and_unpack "$_ref"
166
+ write_wrapper
167
+ ensure_path
168
+ printf '\n%sdone.%s run:\n' "$ACID" "$RESET"
169
+ printf ' moshcode # open the TUI shell\n'
170
+ printf ' moshcode start claude # raw engine session (use agents for autonomous)\n'
171
+ printf ' moshcode prd "your idea" # plan with a numbered OpenPRD\n'
172
+ printf ' moshcode tools # install/run UGig and CoinPay CLIs\n'
173
+ printf ' moshcode help\n\n'
174
+ unset _ref
175
+ }
176
+
177
+ run_remove() {
178
+ info "removing moshcode"
179
+ rm -f "$WRAPPER" 2>/dev/null || true
180
+ rm -f "$SCRIPT_WRAPPER" 2>/dev/null || true
181
+ rm -rf "$MOSHCODE_HOME" 2>/dev/null || true
182
+ ok "removed $WRAPPER, $SCRIPT_WRAPPER, and $MOSHCODE_HOME. 🤘"
183
+ }
184
+
185
+ CMD="${1:-install}"
186
+ if [ $# -gt 0 ]; then shift; fi
187
+ case "$CMD" in
188
+ install) run_install ;;
189
+ update|upgrade) run_install ;; # re-fetch latest, same path
190
+ remove|uninstall) run_remove ;;
191
+ -h|--help|help)
192
+ sed -n '2,33p' "$0" 2>/dev/null || printf 'moshcode installer — install | update | remove\n' ;;
193
+ *) fail "unknown command: $CMD (try: install | update | remove)" ;;
194
+ esac
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "moshcode",
3
+ "version": "0.24.0",
4
+ "type": "module",
5
+ "description": "moshcode — a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript",
6
+ "bin": {
7
+ "moshcode": "./bin/moshcode.mjs",
8
+ "moshscript": "./bin/moshscript.mjs"
9
+ },
10
+ "scripts": {
11
+ "start": "node bin/moshcode.mjs",
12
+ "demo": "node bin/moshcode.mjs run examples/alive.mosh",
13
+ "test": "node --test"
14
+ },
15
+ "files": [
16
+ "bin",
17
+ "src",
18
+ "examples",
19
+ "prd",
20
+ "install.sh",
21
+ "README.md"
22
+ ],
23
+ "license": "MIT",
24
+ "packageManager": "pnpm@10.32.1",
25
+ "devDependencies": {
26
+ "@moshcoder/moshpit-dns": "^0.5.0"
27
+ }
28
+ }
@@ -0,0 +1,49 @@
1
+ ---
2
+ openprd: "0.2"
3
+ id: "0000"
4
+ title: "Short imperative title — start with a verb if possible"
5
+ status: Draft
6
+ authors:
7
+ - you@example.com
8
+ created: 2026-01-01
9
+ updated: 2026-01-01
10
+ repo:
11
+ discussion:
12
+ implementation:
13
+ tags:
14
+ supersedes:
15
+ superseded-by:
16
+ ---
17
+
18
+ ## Problem
19
+
20
+ The user/business problem, and why it matters now.
21
+
22
+ ## Goals
23
+
24
+ What success looks like, as outcomes (not features).
25
+
26
+ ## Non-Goals
27
+
28
+ Explicitly out of scope, to bound the work.
29
+
30
+ ## Users
31
+
32
+ Who this is for; personas or segments.
33
+
34
+ ## Requirements
35
+
36
+ - R1 [P0] First required capability.
37
+ - R2 [P1] Next capability.
38
+
39
+ ## UX Notes
40
+
41
+ Flows, states, and constraints that shape the experience.
42
+
43
+ ## Success Metrics
44
+
45
+ How the goals will be measured.
46
+
47
+ ## Risks & Open Questions
48
+
49
+ - Known risk or decision still owed.
@@ -0,0 +1,121 @@
1
+ ---
2
+ openprd: "0.2"
3
+ id: "0001"
4
+ title: Wrap the UGig and CoinPay CLIs
5
+ status: Accepted
6
+ authors:
7
+ - anthony@chovy.com
8
+ created: 2026-07-13
9
+ updated: 2026-07-13
10
+ repo: https://github.com/moshcoder/moshcode
11
+ discussion:
12
+ implementation:
13
+ tags:
14
+ - cli
15
+ - ugig
16
+ - coinpay
17
+ - orchestration
18
+ supersedes:
19
+ superseded-by:
20
+ ---
21
+
22
+ ## Problem
23
+
24
+ MoshCode already installs and delegates to coding engines, but users and coding
25
+ agents must leave its workflow to discover paid work through UGig or operate the
26
+ CoinPay payment rail. Both products already ship broad native CLIs. Rebuilding
27
+ their APIs in MoshCode would duplicate authentication, command semantics, and
28
+ release cadence; omitting them leaves a gap between finding work, doing it, and
29
+ getting paid.
30
+
31
+ ## Goals
32
+
33
+ - Make the native `ugig` and `coinpay` CLIs installable and discoverable through
34
+ MoshCode.
35
+ - Provide transparent top-level and TUI delegation without changing native CLI
36
+ behavior.
37
+ - Include installed external tools in MoshCode's existing upgrade workflow.
38
+ - Keep ownership clear: UGig owns marketplace state, CoinPay owns payment state,
39
+ and MoshCode only conducts the installed CLIs.
40
+
41
+ ## Non-Goals
42
+
43
+ - Reimplementing UGig or CoinPay API clients or command trees in MoshCode.
44
+ - Adding composed `gigs`, invoice, escrow, or settlement workflows in this
45
+ release.
46
+ - Adding irreversible payment operations to moshscript.
47
+ - Normalizing or parsing either tool's human-readable or JSON output.
48
+ - Managing UGig or CoinPay credentials on MoshCode's behalf.
49
+
50
+ ## Users
51
+
52
+ - Developers using MoshCode who want to find and manage UGig work from the same
53
+ terminal workflow.
54
+ - Coding agents that need machine-readable UGig output or direct CoinPay access.
55
+ - Operators who want one installation and upgrade surface for their coding
56
+ engines and adjacent workflow tools.
57
+
58
+ ## Requirements
59
+
60
+ - R1 [P0] MoshCode MUST define UGig and CoinPay in a `TOOLS` registry separate
61
+ from the coding-engine registry. Each entry MUST declare its executable and
62
+ official package installation/upgrade command.
63
+ - R2 [P0] `moshcode tools` MUST list both tools and report whether each native
64
+ executable is on `PATH`.
65
+ - R3 [P0] `moshcode install ugig` and `moshcode install coinpay` MUST install the
66
+ official npm packages; existing engine installation behavior MUST remain
67
+ compatible.
68
+ - R4 [P0] `moshcode ugig [args…]` and `moshcode coinpay [args…]` MUST pass
69
+ arguments, stdin, stdout, stderr, the working directory, and environment
70
+ through unchanged and MUST propagate the native process exit result.
71
+ - R5 [P0] The interactive shell MUST accept `/ugig [args…]` and
72
+ `/coinpay [args…]`, hand terminal control to the native CLI, and return to the
73
+ MoshCode prompt when it exits.
74
+ - R6 [P0] `moshcode upgrade` MUST update installed tools as well as installed
75
+ engines. `upgrade tools`, `upgrade ugig`, and `upgrade coinpay` MUST be valid
76
+ narrower targets.
77
+ - R7 [P1] Missing executables and unknown install/upgrade targets MUST produce
78
+ actionable errors that identify the correct MoshCode command.
79
+ - R8 [P1] Help text and the README MUST document installation, status,
80
+ passthrough, authentication ownership, and upgrade behavior.
81
+ - R9 [P1] Automated tests MUST cover tool resolution and transparent
82
+ passthrough, including arguments, standard streams, and non-zero exit codes.
83
+
84
+ ## UX Notes
85
+
86
+ ```sh
87
+ moshcode tools
88
+ moshcode install ugig
89
+ moshcode install coinpay
90
+
91
+ moshcode ugig --json gigs list
92
+ moshcode coinpay wallet balance
93
+
94
+ moshcode upgrade tools
95
+ ```
96
+
97
+ `moshcode tools` distinguishes adjacent workflow tools from `/agents` and
98
+ `moshcode engines`. The wrappers do not insert banners or status messages into
99
+ native stdout because that would corrupt JSON pipelines. Native authentication
100
+ continues to use each tool's config files and environment variables.
101
+
102
+ CoinPay currently requires Node.js 20 or newer while MoshCode itself supports
103
+ Node.js 18. Its npm installer remains the authority for enforcing that package
104
+ requirement; MoshCode documents it rather than changing its own runtime floor.
105
+
106
+ ## Success Metrics
107
+
108
+ - All P0 requirements have automated coverage or direct CLI verification.
109
+ - Native `ugig` and `coinpay` help/output can be invoked through MoshCode without
110
+ MoshCode text appearing on stdout.
111
+ - A native non-zero exit code is observed unchanged by a calling shell or agent.
112
+ - Existing MoshCode tests and coding-engine commands continue to pass.
113
+
114
+ ## Risks & Open Questions
115
+
116
+ - CoinPay's machine-readable output is not yet uniform across commands. MoshCode
117
+ will preserve it verbatim; CoinPay should standardize JSON-only stdout and
118
+ diagnostics on stderr before agents depend on every command in pipelines.
119
+ - Composed gig-to-invoice or escrow flows may be valuable later, but should be
120
+ based on observed usage and require explicit confirmation for irreversible
121
+ payment actions.
@@ -0,0 +1,113 @@
1
+ ---
2
+ openprd: "0.2"
3
+ id: "0002"
4
+ title: Separate autonomous agent and raw engine launches
5
+ status: Accepted
6
+ authors:
7
+ - anthony@chovy.com
8
+ created: 2026-07-13
9
+ updated: 2026-07-13
10
+ repo: https://github.com/moshcoder/moshcode
11
+ discussion:
12
+ implementation:
13
+ tags:
14
+ - cli
15
+ - agents
16
+ - permissions
17
+ - orchestration
18
+ supersedes:
19
+ superseded-by:
20
+ ---
21
+
22
+ ## Problem
23
+
24
+ MoshCode currently treats `/agents <engine>` as an ordinary native CLI launch.
25
+ That name implies an autonomous coding session, but the underlying engines still
26
+ pause for their normal permission or approval prompts. At the same time, users
27
+ need an explicit way to start the unmodified native CLI when they want its normal
28
+ safety model or need to supply their own flags.
29
+
30
+ ## Goals
31
+
32
+ - Make `/agents <engine>` a predictable autonomous launch across every supported
33
+ coding engine.
34
+ - Provide `/start <engine>` as an explicit raw passthrough that injects no flags.
35
+ - Preserve the existing bare `moshcode <engine>` raw behavior for compatibility.
36
+ - Make the dangerous nature of autonomous mode visible before handoff.
37
+
38
+ ## Non-Goals
39
+
40
+ - Bypassing administrator policies that disable an engine's autonomous mode.
41
+ - Claiming that every engine provides identical sandbox or permission semantics.
42
+ - Applying autonomous flags to UGig, CoinPay, installers, upgrades, or moshscript.
43
+ - Parsing or rewriting user-supplied native engine arguments.
44
+
45
+ ## Users
46
+
47
+ - Developers who intentionally want uninterrupted agent execution in an
48
+ isolated or otherwise trusted workspace.
49
+ - Developers who want a memorable raw-start command for normal interactive use.
50
+ - Scripts that need the same distinction outside the MoshCode TUI.
51
+
52
+ ## Requirements
53
+
54
+ - R1 [P0] Every coding-engine registry entry MUST declare the engine's current
55
+ autonomous or auto-approval arguments.
56
+ - R2 [P0] The autonomous mappings MUST be Claude
57
+ `--dangerously-skip-permissions`, Codex
58
+ `--dangerously-bypass-approvals-and-sandbox`, Gemini
59
+ `--approval-mode=yolo`, Aider `--yes-always`, and OpenCode `--auto`.
60
+ - R3 [P0] `/agents <engine> [args…]` MUST prepend the registered autonomous
61
+ arguments and then preserve all user-supplied arguments.
62
+ - R4 [P0] `/start <engine> [args…]` MUST launch the engine with only the
63
+ user-supplied arguments.
64
+ - R5 [P0] `moshcode agents <engine> [args…]` and
65
+ `moshcode start <engine> [args…]` MUST provide the equivalent non-TUI paths.
66
+ - R6 [P0] Bare `moshcode <engine> [args…]` and bare engine names in the TUI MUST
67
+ remain raw passthroughs for backward compatibility.
68
+ - R7 [P1] Agent-mode launches MUST show a warning that permission or approval
69
+ protections are being bypassed or auto-approved.
70
+ - R8 [P1] `/agents` and `moshcode agents` with no engine MUST continue listing
71
+ engines and their install status.
72
+ - R9 [P1] Automated tests MUST verify the registered mappings, autonomous
73
+ argument order, and raw-start behavior for every engine.
74
+
75
+ ## UX Notes
76
+
77
+ ```sh
78
+ # Autonomous: MoshCode injects the engine-specific bypass/auto-approve flag.
79
+ moshcode agents claude
80
+ moshcode agents codex --model gpt-5
81
+
82
+ # Raw: MoshCode injects nothing.
83
+ moshcode start claude
84
+ moshcode start codex --sandbox workspace-write
85
+
86
+ # Backward-compatible raw shorthand.
87
+ moshcode claude
88
+ ```
89
+
90
+ TUI equivalents are `/agents claude`, `/start claude`, and bare `claude`.
91
+ `/agents` remains the status list when no engine name follows it.
92
+
93
+ The mappings are intentionally not described as identical. Claude and Codex
94
+ offer explicit full-bypass flags. Gemini and Aider auto-approve confirmations.
95
+ OpenCode's `--auto` approves requests that are not explicitly denied, so deny
96
+ rules remain effective.
97
+
98
+ ## Success Metrics
99
+
100
+ - Each engine receives exactly its registered autonomous arguments through the
101
+ agent-mode path.
102
+ - Raw starts receive no MoshCode-injected engine arguments.
103
+ - Existing engine aliases, environment scrubbing, stdio, cwd, and exit behavior
104
+ remain intact.
105
+ - The full MoshCode test suite passes.
106
+
107
+ ## Risks & Open Questions
108
+
109
+ - Full-bypass modes can execute destructive or prompt-injected actions. Users
110
+ should reserve `/agents` for isolated containers, VMs, or trusted workspaces.
111
+ - Engine flags can change between releases. Their own installers and help output
112
+ remain authoritative, and the registry mappings need maintenance when upstream
113
+ CLIs rename a mode.