@repo-os/repoos 0.5.57 → 0.5.58
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.
- package/README.md +9 -1
- package/dist/.build-info.json +2 -2
- package/dist/.build-stamp.json +1 -1
- package/dist/cli/index.js +19 -3
- package/dist/commands/check.js +5 -0
- package/dist/commands/init.d.ts +7 -1
- package/dist/commands/init.js +147 -13
- package/dist/commands/serve.js +20 -1
- package/dist/commands/shot.d.ts +31 -0
- package/dist/commands/shot.js +427 -0
- package/dist/commands/tasks.js +2 -2
- package/dist/core/agent-compatibility.json +20 -0
- package/dist/core/agent-contract.js +67 -11
- package/dist/core/agent-updates.js +3 -0
- package/dist/core/areas.d.ts +102 -0
- package/dist/core/areas.js +145 -0
- package/dist/core/canary-repo.d.ts +12 -0
- package/dist/core/canary-repo.js +111 -0
- package/dist/core/canary-repo.test.d.ts +1 -0
- package/dist/core/canary-repo.test.js +71 -0
- package/dist/core/canary.d.ts +21 -7
- package/dist/core/canary.js +80 -12
- package/dist/core/canary.test.d.ts +1 -0
- package/dist/core/canary.test.js +73 -0
- package/dist/core/check-failure-summary.d.ts +11 -0
- package/dist/core/check-failure-summary.js +29 -0
- package/dist/core/check-store.d.ts +5 -0
- package/dist/core/check-store.js +29 -14
- package/dist/core/config.d.ts +13 -2
- package/dist/core/config.js +90 -0
- package/dist/core/context-pack.js +9 -4
- package/dist/core/detect.js +13 -0
- package/dist/core/doctor.js +106 -0
- package/dist/core/git-activity.d.ts +35 -0
- package/dist/core/git-activity.js +26 -0
- package/dist/core/git.d.ts +53 -6
- package/dist/core/git.js +135 -27
- package/dist/core/models.js +27 -1
- package/dist/core/repoos.d.ts +6 -1
- package/dist/core/repoos.js +20 -1
- package/dist/core/shot-targets.d.ts +90 -0
- package/dist/core/shot-targets.js +191 -0
- package/dist/core/tailscale.d.ts +15 -0
- package/dist/core/tailscale.js +76 -1
- package/dist/core/task.js +35 -2
- package/dist/core/types.d.ts +45 -1
- package/dist/server/agents.d.ts +69 -3
- package/dist/server/agents.js +280 -9
- package/dist/server/area-migration.d.ts +24 -0
- package/dist/server/area-migration.js +131 -0
- package/dist/server/freeform.d.ts +4 -1
- package/dist/server/freeform.js +52 -33
- package/dist/server/handoff.js +5 -0
- package/dist/server/integration-orchestrator.js +4 -0
- package/dist/server/live-index.d.ts +11 -0
- package/dist/server/live-index.js +1 -0
- package/dist/server/local-token.d.ts +10 -0
- package/dist/server/local-token.js +62 -0
- package/dist/server/preview.js +30 -10
- package/dist/server/repo-status.d.ts +95 -0
- package/dist/server/repo-status.js +313 -0
- package/dist/server/review.js +1 -1
- package/dist/server/routes/config.js +91 -1
- package/dist/server/routes/info.js +4 -2
- package/dist/server/routes/repo-log.d.ts +11 -0
- package/dist/server/routes/repo-log.js +15 -0
- package/dist/server/routes/tasks.d.ts +3 -0
- package/dist/server/routes/tasks.js +67 -3
- package/dist/server/server.js +119 -30
- package/dist/server/shot-context.d.ts +21 -0
- package/dist/server/shot-context.js +30 -0
- package/dist/server/shots.d.ts +42 -0
- package/dist/server/shots.js +170 -0
- package/dist/server/watcher.d.ts +38 -0
- package/dist/server/watcher.js +109 -2
- package/dist/server/write.d.ts +6 -1
- package/dist/server/write.js +20 -2
- package/dist/ui/assets/{AgentModelModal-Ced4h4sp.js → AgentModelModal-DzP177gt.js} +1 -1
- package/dist/ui/assets/{AgentsView-fJc8ZQRN.js → AgentsView-CA6vNzB_.js} +1 -1
- package/dist/ui/assets/{ChecksView-DK2wcClf.css → ChecksView-DXaRYvbW.css} +1 -1
- package/dist/ui/assets/ChecksView-k-3IMvCn.js +0 -0
- package/dist/ui/assets/{ContextView-CTGAeIvz.css → ContextView-CE7UCqYM.css} +1 -1
- package/dist/ui/assets/ContextView-DIn7440o.js +4 -0
- package/dist/ui/assets/{DashboardView-BlSDOM4G.js → DashboardView-Dycyb_k9.js} +1 -1
- package/dist/ui/assets/{DiffView-nH7u0JwJ.js → DiffView-DMGq4a2J.js} +1 -1
- package/dist/ui/assets/{InputsView-BZ3T5jsY.js → InputsView-DLdABoFS.js} +1 -1
- package/dist/ui/assets/{LoginView-CX6blOC4.js → LoginView-DJRB0cU8.js} +1 -1
- package/dist/ui/assets/ReleasesView-CURY5err.css +1 -0
- package/dist/ui/assets/{ReleasesView-C5PaQX6n.js → ReleasesView-UavG0AWn.js} +2 -2
- package/dist/ui/assets/SettingsView-B0CnWYfh.js +4 -0
- package/dist/ui/assets/StoriesView-D1Rm_igY.js +1 -0
- package/dist/ui/assets/{VoiceDictate-CifZUkzt.js → VoiceDictate-CCJfAGJk.js} +1 -1
- package/dist/ui/assets/WorkView-DoN6rK5X.js +2 -0
- package/dist/ui/assets/{abnfDiagram-VCTEODGH-CxKkcu03.js → abnfDiagram-VCTEODGH-DNJeaBue.js} +1 -1
- package/dist/ui/assets/architecture-7GRP2DOG-CE8k1klh.js +1 -0
- package/dist/ui/assets/{architectureDiagram-5GKGNRK7-B7yFyWIW.js → architectureDiagram-5GKGNRK7-CFYttSDP.js} +1 -1
- package/dist/ui/assets/{blockDiagram-I7D4REHJ-Dqn5piZv.js → blockDiagram-I7D4REHJ-D4x6ObYp.js} +1 -1
- package/dist/ui/assets/{c4Diagram-7LVT6UL2-BDourwGX.js → c4Diagram-7LVT6UL2-CxtP3-uN.js} +1 -1
- package/dist/ui/assets/channel-YsXE3acZ.js +1 -0
- package/dist/ui/assets/{chunk-4HAMMTFA-BGxQ0vmo.js → chunk-4HAMMTFA-CuuPSpo5.js} +1 -1
- package/dist/ui/assets/{chunk-75Z2AOVW-CoD1HiQQ.js → chunk-75Z2AOVW-DA5zPl9A.js} +1 -1
- package/dist/ui/assets/{chunk-DU6HZSFF-WQx_PGDE.js → chunk-DU6HZSFF-_OVfIMg9.js} +1 -1
- package/dist/ui/assets/{chunk-F27PBJKO-BmtJFWYx.js → chunk-F27PBJKO-DmAfAXfg.js} +1 -1
- package/dist/ui/assets/{chunk-GMAD6QVW-kRmn1tqd.js → chunk-GMAD6QVW-7rYiJcfH.js} +1 -1
- package/dist/ui/assets/{chunk-GVQU2GXP-C2SMD4HM.js → chunk-GVQU2GXP-DUvM8o5c.js} +1 -1
- package/dist/ui/assets/{chunk-IMKFNOWR-DRm68yqu.js → chunk-IMKFNOWR-Dug5EN3L.js} +1 -1
- package/dist/ui/assets/{chunk-L3NEJ4N5-Bdd0UO7i.js → chunk-L3NEJ4N5-B__JCALV.js} +1 -1
- package/dist/ui/assets/{chunk-OSK3NFVY-DzFP_5D1.js → chunk-OSK3NFVY-DNSy5va-.js} +1 -1
- package/dist/ui/assets/{chunk-P2QGCYS3-CxTbTe1z.js → chunk-P2QGCYS3-jZiRM4I9.js} +1 -1
- package/dist/ui/assets/{chunk-POPQ4Y6H-1sMFzZlT.js → chunk-POPQ4Y6H-DUE_WVHL.js} +1 -1
- package/dist/ui/assets/{chunk-PWAF6VOD-qwo7mGDG.js → chunk-PWAF6VOD-CbMevpLH.js} +1 -1
- package/dist/ui/assets/{chunk-SHT3W25Y-t7arLGqg.js → chunk-SHT3W25Y-MuvL_buO.js} +1 -1
- package/dist/ui/assets/{chunk-SVP7TREG-CDGoMrDa.js → chunk-SVP7TREG-lOHx_pKr.js} +1 -1
- package/dist/ui/assets/{chunk-TICWLB2K-DdCRvOgF.js → chunk-TICWLB2K-11z-MDx9.js} +1 -1
- package/dist/ui/assets/classDiagram-ZZMXUADV-DpeLlC2e.js +1 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-DpeLlC2e.js +1 -0
- package/dist/ui/assets/config-j80hL8dN.js +1 -0
- package/dist/ui/assets/{cynefin-OW5HDTMX-Dphr1hkJ.js → cynefin-OW5HDTMX-D8Tbtioe.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-BmNfqRyY.js → cynefinDiagram-5FMLGOSQ-DykcYZa1.js} +1 -1
- package/dist/ui/assets/{dagre-GXQ25YYZ-0__5BzkZ.js → dagre-GXQ25YYZ-BCjGpohz.js} +1 -1
- package/dist/ui/assets/{diagram-S7CK7UJ4-BCSWodGD.js → diagram-S7CK7UJ4-DrO95VpH.js} +1 -1
- package/dist/ui/assets/{diagram-UQ7AKVKN-DNY_hqmH.js → diagram-UQ7AKVKN-Bl2XIcjq.js} +1 -1
- package/dist/ui/assets/{diagram-VSXAHHWV-DgEipWnL.js → diagram-VSXAHHWV-D88EBlA1.js} +1 -1
- package/dist/ui/assets/{diagram-VX7I27RA-CXqwFFDY.js → diagram-VX7I27RA-Dd9fRIfD.js} +1 -1
- package/dist/ui/assets/{diagram-Z3DM3KII-DqGMJic1.js → diagram-Z3DM3KII-CDvHYGee.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-PWID7BFC-O7OLADLR.js → ebnfDiagram-PWID7BFC-ROLkMsCj.js} +1 -1
- package/dist/ui/assets/{erDiagram-RLTQ6QDP-BLybCuiJ.js → erDiagram-RLTQ6QDP-hgEdVaDk.js} +1 -1
- package/dist/ui/assets/eventmodeling-NTZA5JFV-D4JrdfJN.js +1 -0
- package/dist/ui/assets/flowDiagram-HODETNUW-BuBvXaQp.js +1 -0
- package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-PP7LUoJk.js → ganttDiagram-EL5Y4UJY-DyNYXsDm.js} +1 -1
- package/dist/ui/assets/{gitGraph-4MIJSDKK-jLh6GWq3.js → gitGraph-4MIJSDKK-DrwHooXn.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-BpQqVPAf.js → gitGraphDiagram-WWUBYQGX-_DOOuskB.js} +1 -1
- package/dist/ui/assets/index-BqREmSY8.js +46 -0
- package/dist/ui/assets/index-RS-D6B89.css +1 -0
- package/dist/ui/assets/{info-A6RAGUB7-MKojffEb.js → info-A6RAGUB7-Bp4WG9KV.js} +1 -1
- package/dist/ui/assets/{infoDiagram-27XIBGKW-CDsY5bPn.js → infoDiagram-27XIBGKW-Bp9BY3BX.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-DlkSFpW_.js → ishikawaDiagram-5VMMS53U-Dmxsu_I6.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-3NMN7TZE-BQerIcFQ.js → journeyDiagram-3NMN7TZE-DyCFShcT.js} +1 -1
- package/dist/ui/assets/{kanban-definition-UXKFOSKX-DcOUAWHk.js → kanban-definition-UXKFOSKX-BY6mL0nV.js} +1 -1
- package/dist/ui/assets/{line-CWe6TPQq.js → line-CFvZJFGP.js} +1 -1
- package/dist/ui/assets/{mermaid-parser.core-B6lGkbHf.js → mermaid-parser.core-BlWQycY8.js} +3 -3
- package/dist/ui/assets/{mermaid.core-usGEYfph.js → mermaid.core-kuwSwalt.js} +4 -4
- package/dist/ui/assets/{mindmap-definition-YA3MSWOX-CRr1hJ6k.js → mindmap-definition-YA3MSWOX-Da8T6fiA.js} +1 -1
- package/dist/ui/assets/{packet-AYTQ26CC-Vrb5eklN.js → packet-AYTQ26CC-uA_F87fL.js} +1 -1
- package/dist/ui/assets/{pegDiagram-XKGWAZYB-DWgbaT0F.js → pegDiagram-XKGWAZYB-DlT4Tua4.js} +1 -1
- package/dist/ui/assets/{pie-WAS4IAKB-EBSi28Ou.js → pie-WAS4IAKB-CMlL534n.js} +1 -1
- package/dist/ui/assets/{pieDiagram-E7YTZNPT-CY7kTdf6.js → pieDiagram-E7YTZNPT-Dc1lWF3q.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-DapXMfW1.js → quadrantDiagram-AXDQQJYC-BqVcYO8d.js} +1 -1
- package/dist/ui/assets/{radar-RG4KPBEZ-B4g4t9_Y.js → radar-RG4KPBEZ-Dolxtcln.js} +1 -1
- package/dist/ui/assets/{railroad-74A4TZTK-DbL2DZlM.js → railroad-74A4TZTK-WQOQGRUO.js} +1 -1
- package/dist/ui/assets/railroad-abnf-HS5TGJTU-oeSeN2iQ.js +1 -0
- package/dist/ui/assets/railroad-ebnf-LZEXJU2U-CXhtQ5k4.js +1 -0
- package/dist/ui/assets/railroad-peg-WCYAUIDC-CZQ_zKCz.js +1 -0
- package/dist/ui/assets/{railroadDiagram-O6MQD6OU-Bq4-JY0m.js → railroadDiagram-O6MQD6OU-BvlFISOo.js} +1 -1
- package/dist/ui/assets/repo-CPWzR4oq.js +1 -0
- package/dist/ui/assets/{requirementDiagram-BXWQKSXE-CVI43xef.js → requirementDiagram-BXWQKSXE-BYKoXbW1.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-6igeb8Iu.js → sankeyDiagram-P5KCCOFB-ClkaPNXM.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-LYhNaHRI.js → sequenceDiagram-WJ2MYXX4-CnLXWS23.js} +1 -1
- package/dist/ui/assets/{stateDiagram-D77RDMKH-VQcHODiY.js → stateDiagram-D77RDMKH-SURchdbJ.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-3QeI6zO7.js +1 -0
- package/dist/ui/assets/{swimlanes-42K2YHIH-C5U1l1mo.js → swimlanes-42K2YHIH-ETHZRcl1.js} +1 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-2inBpL8s.js +8 -0
- package/dist/ui/assets/{timeline-definition-24CTP7MA-C8YMVaeD.js → timeline-definition-24CTP7MA-CzmcMnEC.js} +1 -1
- package/dist/ui/assets/{treeView-Q6P3EWNA-B4Opgu8L.js → treeView-Q6P3EWNA-DpYbsVnL.js} +1 -1
- package/dist/ui/assets/{treemap-WGGIJYW6-BWpYq891.js → treemap-WGGIJYW6-CprmPbH2.js} +1 -1
- package/dist/ui/assets/{vennDiagram-4TSXK5OY-BZ7_jhEK.js → vennDiagram-4TSXK5OY-h5jxvp23.js} +1 -1
- package/dist/ui/assets/{wardley-WFR3VGLG-DSF6DKt8.js → wardley-WFR3VGLG-C9hsSVZz.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-ChfzNSSI.js → wardleyDiagram-VM6X3IG4-D58m5Tfi.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-CwDvFw4R.js → xychartDiagram-S5SC5T6Z-WeCot50K.js} +1 -1
- package/dist/ui/index.html +6 -6
- package/dist/ui/sw.js +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/ChecksView-CpGuGL1P.js +0 -0
- package/dist/ui/assets/ContextView-C2ElRI0s.js +0 -4
- package/dist/ui/assets/ReleasesView-DaX_TFoT.css +0 -1
- package/dist/ui/assets/SettingsView-C1xiIbbq.js +0 -4
- package/dist/ui/assets/StoriesView-BCJnrDOc.js +0 -1
- package/dist/ui/assets/WorkView-CrQ8R4xr.js +0 -2
- package/dist/ui/assets/architecture-7GRP2DOG-BKXNQ9fY.js +0 -1
- package/dist/ui/assets/channel-DXJt6aEW.js +0 -1
- package/dist/ui/assets/classDiagram-ZZMXUADV-CuXQhOCc.js +0 -1
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-CuXQhOCc.js +0 -1
- package/dist/ui/assets/config-CxRkBtUj.js +0 -1
- package/dist/ui/assets/eventmodeling-NTZA5JFV-BXXaF1fS.js +0 -1
- package/dist/ui/assets/flowDiagram-HODETNUW-HB2tiq05.js +0 -1
- package/dist/ui/assets/index-C9k_vHM5.js +0 -46
- package/dist/ui/assets/index-DKDq8ZAh.css +0 -1
- package/dist/ui/assets/railroad-abnf-HS5TGJTU-SDQCarTw.js +0 -1
- package/dist/ui/assets/railroad-ebnf-LZEXJU2U-D9NI_tLh.js +0 -1
- package/dist/ui/assets/railroad-peg-WCYAUIDC-kSMa3Mxd.js +0 -1
- package/dist/ui/assets/repo-OUIxzvAy.js +0 -1
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-L8aM9etd.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-Dj94QI7O.js +0 -8
package/README.md
CHANGED
|
@@ -96,7 +96,7 @@ install, `repoos upgrade` prints the matching package-manager command instead.
|
|
|
96
96
|
Then in any repo:
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
|
-
repoos init # scaffold work/, docs/, repoos.toml, AGENTS.md (idempotent)
|
|
99
|
+
repoos init # scaffold repoos/work/, repoos/docs/, repoos.toml, AGENTS.md (idempotent)
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
Zero config required. `repoos init` walks up to find your repo root, creates the
|
|
@@ -219,6 +219,14 @@ your other Tailscale devices and from localhost-only tools on the same machine
|
|
|
219
219
|
(e.g. a Cloudflare Tunnel's local origin). Pass `--host 127.0.0.1` explicitly
|
|
220
220
|
to restrict it to localhost only.
|
|
221
221
|
|
|
222
|
+
In that mode `repoos serve` also runs `tailscale serve` for you and prints an
|
|
223
|
+
`https://<machine>.<tailnet>.ts.net` URL. Use it: a plain-`http://` Tailscale IP
|
|
224
|
+
isn't a browser secure context, so some UI features can't work there. It is
|
|
225
|
+
tailnet-only (not Funnel), never overwrites another `tailscale serve` mapping
|
|
226
|
+
(it falls back to port 8443, then 10000), and needs MagicDNS + HTTPS
|
|
227
|
+
Certificates enabled in the Tailscale admin console (`serve` prints a hint if
|
|
228
|
+
not). Pass `--no-tailscale-https` to skip it.
|
|
229
|
+
|
|
222
230
|
### Endpoints
|
|
223
231
|
|
|
224
232
|
```
|
package/dist/.build-info.json
CHANGED
package/dist/.build-stamp.json
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { cmdList, cmdShow, cmdMv, cmdUpdate, cmdNew, cmdIndex, cmdNote, } from "
|
|
|
8
8
|
import { cmdNewDoc } from "../commands/docs.js";
|
|
9
9
|
import { cmdGc } from "../commands/gc.js";
|
|
10
10
|
import { cmdCheck } from "../commands/check.js";
|
|
11
|
+
import { cmdShot } from "../commands/shot.js";
|
|
11
12
|
import { cmdServe, serveProcessTitle, setServeProcessTitle } from "../commands/serve.js";
|
|
12
13
|
import { cmdStop } from "../commands/stop.js";
|
|
13
14
|
import { cmdTunnel } from "../commands/tunnel.js";
|
|
@@ -89,6 +90,7 @@ function help() {
|
|
|
89
90
|
cmdRow("check --profile full", "Run every declared step, including ones held back from a routine run"),
|
|
90
91
|
cmdRow("check --changed main", "Fast pre-review pass over steps affected by changed paths"),
|
|
91
92
|
cmdRow("check --print-plan", "Print the resolved plan as [[check.steps]] TOML to commit"),
|
|
93
|
+
cmdRow("shot [<route|url>]", `Capture preview screenshots into the task's shots folder ${c.dim("flags: --target --selector --task --base --wait --full-page")}`),
|
|
92
94
|
cmdRow("init [name]", "Scaffold work/, repoos.toml, AGENTS.md; outside a git repo runs a guided flow that can launch the web console"),
|
|
93
95
|
cmdRow("list [status]", `Show the board (or one column: ${c.dim("inbox|ready|active|review|done")})`),
|
|
94
96
|
cmdRow("status [--json]", "One-screen health snapshot: server, build freshness, board, worktrees, tunnel, git"),
|
|
@@ -103,7 +105,7 @@ function help() {
|
|
|
103
105
|
cmdRow('new-doc "<desc>"', "Create a document from a description via PM agent"),
|
|
104
106
|
cmdRow("index [--json]", "Rebuild the derived index cache"),
|
|
105
107
|
cmdRow("gc [--yes|--dry-run]", "Collect leaked task worktrees/branches (done/absent tasks, integrate candidates)"),
|
|
106
|
-
cmdRow("serve [--port N]", `Start the local server (live API + SSE stream) ${c.dim("flags: --host, --preview-overrides, --no-preview-overrides")}`),
|
|
108
|
+
cmdRow("serve [--port N]", `Start the local server (live API + SSE stream) ${c.dim("flags: --host, --no-tailscale-https, --preview-overrides, --no-preview-overrides")}`),
|
|
107
109
|
cmdRow("stop [--port N]", "Stop this repo's serve process (by its own lockfile)"),
|
|
108
110
|
cmdRow("service [sub]", `Manage background services ${c.dim("list|status|install|start|stop|restart|enable|disable|remove")}`),
|
|
109
111
|
cmdRow("tunnel <sub>", `Publish local apps via Cloudflare Tunnel + Zero Trust ${c.dim("(setup|create|allow|deny|rename|destroy|start|install|stop|list|status)")}`),
|
|
@@ -113,13 +115,16 @@ function help() {
|
|
|
113
115
|
const exampleLines = [
|
|
114
116
|
exRow("repoos init"),
|
|
115
117
|
exRow("repoos init myproject", "guided new-project flow outside a git repo"),
|
|
116
|
-
exRow('repoos new "Add company dashboard" --ai --type feature --area web --priority p1'),
|
|
118
|
+
exRow('repoos new "Add company dashboard" --ai --type feature --area web,server --priority p1'),
|
|
117
119
|
exRow('repoos new-doc "API design doc for the payment system"'),
|
|
118
120
|
exRow("repoos mv 0012 active"),
|
|
119
121
|
exRow('repoos mv 0012 active --note "Fix the regression in checkout; see review"'),
|
|
120
122
|
exRow('repoos note 0012 "Handle the reviewer\'s suggestions before the next review"'),
|
|
121
|
-
exRow('repoos update 0012 --title "New title" --area web'),
|
|
123
|
+
exRow('repoos update 0012 --title "New title" --area web,core'),
|
|
122
124
|
exRow("repoos list ready"),
|
|
125
|
+
exRow("repoos shot", "screenshot the task preview for the current worktree"),
|
|
126
|
+
exRow("repoos shot /repo/commits/abc123", "capture one route"),
|
|
127
|
+
exRow("repoos shot --target 'Docs site' --selector '.sidebar'"),
|
|
123
128
|
exRow("repoos status", "one-screen health snapshot"),
|
|
124
129
|
exRow("repoos status --json", "machine-readable, for agents/tools"),
|
|
125
130
|
exRow("repoos index --json", "machine-readable, for agents/tools"),
|
|
@@ -264,6 +269,17 @@ function main() {
|
|
|
264
269
|
case "check":
|
|
265
270
|
void cmdCheck(rest);
|
|
266
271
|
break;
|
|
272
|
+
case "shot":
|
|
273
|
+
void cmdShot(rest)
|
|
274
|
+
.then((code) => {
|
|
275
|
+
if (code !== 0)
|
|
276
|
+
process.exitCode = code;
|
|
277
|
+
})
|
|
278
|
+
.catch((err) => {
|
|
279
|
+
console.error(c.red(` ✗ shot failed: ${err.message}`));
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
});
|
|
282
|
+
break;
|
|
267
283
|
case "tunnel":
|
|
268
284
|
void cmdTunnel(rest);
|
|
269
285
|
break;
|
package/dist/commands/check.js
CHANGED
|
@@ -31,6 +31,7 @@ import { preferBunForDevTasks } from "../core/runtime.js";
|
|
|
31
31
|
import { blockingFailures, DEFAULT_PROFILE, describeStep, formatPlanToml, resolveCheckPlan, selectSteps, } from "../core/check-plan.js";
|
|
32
32
|
import { detectRepoMarkers, missingBinaries, prereqDetail, runCommand, stepCwd, } from "../core/check-runner.js";
|
|
33
33
|
import { writeCheckRun } from "../core/check-results-store.js";
|
|
34
|
+
import { extractFailedTests } from "../core/check-failure-summary.js";
|
|
34
35
|
import { envToRunContext, getCheckStore, localMachineName } from "../core/check-store.js";
|
|
35
36
|
import { mainCheckoutRoot } from "../core/git.js";
|
|
36
37
|
import { Logger } from "../core/logger.js";
|
|
@@ -1640,6 +1641,9 @@ export async function cmdCheck(argv = []) {
|
|
|
1640
1641
|
failedStep: gatingFailures[0]?.name ?? null,
|
|
1641
1642
|
skippedSteps: results.filter((r) => r.status === "skipped").map((r) => r.name),
|
|
1642
1643
|
detail: gatingFailures[0]?.detail ?? null,
|
|
1644
|
+
// The stored detail is a short log tail that routinely loses the failing
|
|
1645
|
+
// test's name; keep the names themselves so "which test?" is a query.
|
|
1646
|
+
failedTests: gatingFailures.flatMap((r) => extractFailedTests(r.output ?? "")),
|
|
1643
1647
|
});
|
|
1644
1648
|
process.exit(gatingFailures.length > 0 ? 1 : 0);
|
|
1645
1649
|
}
|
|
@@ -1672,6 +1676,7 @@ function recordRunHistoryRow(row) {
|
|
|
1672
1676
|
failedStep: row.failedStep,
|
|
1673
1677
|
skippedSteps: row.skippedSteps,
|
|
1674
1678
|
detail: row.detail,
|
|
1679
|
+
failedTests: row.failedTests,
|
|
1675
1680
|
});
|
|
1676
1681
|
}
|
|
1677
1682
|
catch {
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Blockquote every line, so a multi-line (pasted markdown) description stays one quote. */
|
|
2
|
+
export declare function quoteBlock(text: string): string;
|
|
1
3
|
/** Marker makes the optional existing-repo addition safe to offer repeatedly. */
|
|
2
4
|
export declare const REPOOS_AGENTS_SECTION_MARKER = "<!-- repoos:managed-instructions -->";
|
|
3
5
|
/**
|
|
@@ -19,7 +21,11 @@ export declare function repoOSAgentsSectionAddition(existing: string, workDir?:
|
|
|
19
21
|
type ScaffoldLayout = string;
|
|
20
22
|
/** Which starter task to seed beyond 0001 — a blank project or an existing repo. */
|
|
21
23
|
type ScaffoldKind = "new" | "existing";
|
|
22
|
-
export declare function scaffoldInto(root: string, description: string, layout?: ScaffoldLayout, kind?: ScaffoldKind
|
|
24
|
+
export declare function scaffoldInto(root: string, description: string, layout?: ScaffoldLayout, kind?: ScaffoldKind,
|
|
25
|
+
/** Areas collected at init time (#0583) — real `[[areas]]` rows when given. */
|
|
26
|
+
areas?: string[],
|
|
27
|
+
/** When true, scaffold commented `[[preview.targets]]` stubs for those areas. */
|
|
28
|
+
previewStub?: boolean): {
|
|
23
29
|
created: string[];
|
|
24
30
|
skipped: string[];
|
|
25
31
|
};
|
package/dist/commands/init.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* guided, interactive flow that creates a brand-new RepoOS project from
|
|
7
7
|
* scratch: optionally in a subdirectory, with a choice of layout (repo root
|
|
8
8
|
* vs. a `repoos/` subfolder, config file at root either way), an optional
|
|
9
|
-
*
|
|
9
|
+
* project description, one or many lines (seeded into the sample task) and an optional
|
|
10
10
|
* initial commit.
|
|
11
11
|
*/
|
|
12
12
|
import { spawn } from "node:child_process";
|
|
@@ -15,6 +15,8 @@ import { createServer } from "node:net";
|
|
|
15
15
|
import { join, resolve } from "node:path";
|
|
16
16
|
import { createInterface } from "node:readline/promises";
|
|
17
17
|
import { stdin as input, stdout as output } from "node:process";
|
|
18
|
+
import { canaryGitignoreIgnore, canaryGitignoreNegation, canaryRelPath } from "../core/canary.js";
|
|
19
|
+
import { scaffoldCanaryFile } from "../core/canary-repo.js";
|
|
18
20
|
import { deriveServePort, findRepoRoot, loadConfig } from "../core/config.js";
|
|
19
21
|
import { CHECK_PLAN_PROPOSAL_FILE, proposeCheckPlan } from "../core/check-plan-proposal.js";
|
|
20
22
|
import { formatPlanToml } from "../core/check-plan.js";
|
|
@@ -58,12 +60,19 @@ running \`repoos init\` already satisfies everything above. There's nothing to
|
|
|
58
60
|
Status is a frontmatter field — never move files between folders. Keep diffs
|
|
59
61
|
small. Read AGENTS.md before starting any task.
|
|
60
62
|
`;
|
|
63
|
+
/** Blockquote every line, so a multi-line (pasted markdown) description stays one quote. */
|
|
64
|
+
export function quoteBlock(text) {
|
|
65
|
+
return text
|
|
66
|
+
.split("\n")
|
|
67
|
+
.map((line) => (line.trim() === "" ? ">" : `> ${line}`))
|
|
68
|
+
.join("\n");
|
|
69
|
+
}
|
|
61
70
|
/**
|
|
62
71
|
* The first *workable* task a guided new-project init leaves on the board.
|
|
63
72
|
* 0001 is deliberately `done` (scaffolding is the whole of it), so this is what
|
|
64
73
|
* a new user — or their first agent — actually picks up. `repoos init` runs
|
|
65
74
|
* before any server or agent exists, so the body itself is the prompt: it
|
|
66
|
-
* embeds the
|
|
75
|
+
* embeds the description collected at init and carries the questions
|
|
67
76
|
* that turn that description into docs and real tasks later.
|
|
68
77
|
*/
|
|
69
78
|
const NEW_PROJECT_STARTER_TASK = (id, description, workDir = "work", docsDir = "docs") => `---
|
|
@@ -79,15 +88,15 @@ branch: ""
|
|
|
79
88
|
---
|
|
80
89
|
## Overview
|
|
81
90
|
|
|
82
|
-
This project started from a
|
|
91
|
+
This project started from a short description. This task turns it into
|
|
83
92
|
something a team can actually build from — a shared vision, an initial
|
|
84
93
|
architecture, and a first batch of concrete work.
|
|
85
94
|
|
|
86
95
|
## Project description
|
|
87
96
|
|
|
88
97
|
${description
|
|
89
|
-
?
|
|
90
|
-
: "_No description was given at init time. Start by writing
|
|
98
|
+
? quoteBlock(description)
|
|
99
|
+
: "_No description was given at init time. Start by writing a short description that says what this project is and who it's for._"}
|
|
91
100
|
|
|
92
101
|
## What to do
|
|
93
102
|
|
|
@@ -202,6 +211,15 @@ a candidate merge. Do not erase a task's branch metadata to force this path.
|
|
|
202
211
|
|
|
203
212
|
## Rules
|
|
204
213
|
|
|
214
|
+
- **\`repoos.toml\` owns the layout.** \`workDir\` (\`${workDir}\`) and \`docsDir\`
|
|
215
|
+
(\`${docsDir}\`) are authoritative: tasks live under \`${workDir}/\` and project
|
|
216
|
+
docs under \`${docsDir}/\` because the config says so. Never move, rename or
|
|
217
|
+
relocate those directories, and never "fix" a layout you think is wrong by
|
|
218
|
+
moving files. If project docs or a person's own notes disagree with the
|
|
219
|
+
config, report the mismatch — the fix is to update \`repoos.toml\` with human
|
|
220
|
+
approval (or correct the docs), never to move directories on your own. Do not
|
|
221
|
+
invent ownership rules for RepoOS directories; the config is the only source
|
|
222
|
+
of truth for layout.
|
|
205
223
|
- **Never** move task files between folders. Status lives in frontmatter.
|
|
206
224
|
- **Never write directly to \`${workDir}/*.md\` files.** All task creation and
|
|
207
225
|
manipulation goes through \`repoos\` commands or HTTP API endpoints
|
|
@@ -249,7 +267,10 @@ export const REPOOS_AGENTS_SECTION = (workDir) => `${REPOOS_AGENTS_SECTION_MARKE
|
|
|
249
267
|
## RepoOS
|
|
250
268
|
|
|
251
269
|
RepoOS keeps tasks as Markdown under \`${workDir}/\` and runs task work in dedicated
|
|
252
|
-
Git worktrees.
|
|
270
|
+
Git worktrees. The layout is set by \`repoos.toml\` (\`workDir\`/\`docsDir\`/\`cacheDir\`):
|
|
271
|
+
those paths are authoritative, so never move or rename them — if project docs
|
|
272
|
+
disagree with the config, ask the human instead of relocating directories.
|
|
273
|
+
Use the RepoOS UI or \`repoos\` commands to create and update
|
|
253
274
|
tasks; do not hand-edit task files. Read the relevant project docs before
|
|
254
275
|
starting work, run \`repoos check\` before handoff, and await human approval
|
|
255
276
|
through RepoOS's **Move to done**. The reviewer is advisory. A Git remote does
|
|
@@ -267,7 +288,7 @@ export function repoOSAgentsSectionAddition(existing, workDir = "work") {
|
|
|
267
288
|
}
|
|
268
289
|
return (existing.endsWith("\n") ? "\n" : "\n\n") + REPOOS_AGENTS_SECTION(workDir);
|
|
269
290
|
}
|
|
270
|
-
function repoosToml(namespace) {
|
|
291
|
+
function repoosToml(namespace, areas = [], previewStub = false) {
|
|
271
292
|
const ns = namespace
|
|
272
293
|
? `workDir = "${namespace}/work"\ndocsDir = "${namespace}/docs"\ncacheDir = "${namespace}/.repoos"\n`
|
|
273
294
|
: "";
|
|
@@ -305,8 +326,45 @@ defaultAssignee = "unassigned"
|
|
|
305
326
|
# active = "In progress"
|
|
306
327
|
# review = "Code review"
|
|
307
328
|
# done = "Shipped"
|
|
329
|
+
${areaRows(areas)}
|
|
330
|
+
${previewStub ? previewTargetRows(areas) : ""}
|
|
308
331
|
`;
|
|
309
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* The `[areas]` block: the vocabulary collected at init time as real
|
|
335
|
+
* `[[areas]]` rows, or the commented-out stub when skipped (#0583).
|
|
336
|
+
*/
|
|
337
|
+
function areaRows(areas) {
|
|
338
|
+
if (!areas.length) {
|
|
339
|
+
return [
|
|
340
|
+
"# [[areas]] # the task-area vocabulary (#0583)",
|
|
341
|
+
'# name = "web" # offered in the area picker + the PM prompt',
|
|
342
|
+
'# description = "The main web app"',
|
|
343
|
+
"# Every [[preview.targets]] area is offered automatically, even when not",
|
|
344
|
+
"# declared here. With none declared the area field is free text only.",
|
|
345
|
+
].join("\n");
|
|
346
|
+
}
|
|
347
|
+
return areas.map((a) => `[[areas]]\nname = "${a}"`).join("\n\n");
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* The commented `[[preview.targets]]` skeleton offered when an area vocabulary
|
|
351
|
+
* was seeded at init (#0583) — the wiring for when the project has something
|
|
352
|
+
* previewable, referencing the areas the picker now offers.
|
|
353
|
+
*/
|
|
354
|
+
function previewTargetRows(areas) {
|
|
355
|
+
const areaList = areas.length ? JSON.stringify(areas) : '["web"]';
|
|
356
|
+
return [
|
|
357
|
+
"# [preview] # read-only task previews",
|
|
358
|
+
`# command = "bun run dev --port {port} --host {host}"`,
|
|
359
|
+
`# # default when no target matches`,
|
|
360
|
+
"",
|
|
361
|
+
`# [[preview.targets]]`,
|
|
362
|
+
`# name = "Main app"`,
|
|
363
|
+
`# areas = ${areaList}`,
|
|
364
|
+
`# command = "bun run dev --port {port} --host {host}"`,
|
|
365
|
+
`# readyTimeoutMs = 240000 # raise for a command that also builds`,
|
|
366
|
+
].join("\n");
|
|
367
|
+
}
|
|
310
368
|
const ENV_EXAMPLE = `# Copy to .env and fill in what you need — .env is gitignored, this file is
|
|
311
369
|
# tracked so the repo documents which secrets a full setup expects.
|
|
312
370
|
# repoos serve auto-loads .env at startup; real shell/process-supervisor env
|
|
@@ -380,7 +438,11 @@ function findStarter(root, workDir, slug) {
|
|
|
380
438
|
return null;
|
|
381
439
|
}
|
|
382
440
|
}
|
|
383
|
-
export function scaffoldInto(root, description, layout = "", kind = "new"
|
|
441
|
+
export function scaffoldInto(root, description, layout = "", kind = "new",
|
|
442
|
+
/** Areas collected at init time (#0583) — real `[[areas]]` rows when given. */
|
|
443
|
+
areas = [],
|
|
444
|
+
/** When true, scaffold commented `[[preview.targets]]` stubs for those areas. */
|
|
445
|
+
previewStub = false) {
|
|
384
446
|
const created = [];
|
|
385
447
|
const skipped = [];
|
|
386
448
|
let aborted = false;
|
|
@@ -425,7 +487,7 @@ export function scaffoldInto(root, description, layout = "", kind = "new") {
|
|
|
425
487
|
// Write config first so workDir/docsDir/cacheDir overrides are in effect
|
|
426
488
|
// before the dirs are created (namespace layout) — or so an existing
|
|
427
489
|
// config is respected untouched (existing-repo path).
|
|
428
|
-
ensureFile("repoos.toml", repoosToml(layout));
|
|
490
|
+
ensureFile("repoos.toml", repoosToml(layout, areas, previewStub));
|
|
429
491
|
const config = loadConfig(root);
|
|
430
492
|
ensureDir(config.workDir);
|
|
431
493
|
ensureDir(config.docsDir);
|
|
@@ -449,10 +511,17 @@ export function scaffoldInto(root, description, layout = "", kind = "new") {
|
|
|
449
511
|
ensureFile(join(config.workDir, `${starterId}-${starter.slug}.md`), starter.build(starterId, description, config.workDir, config.docsDir));
|
|
450
512
|
}
|
|
451
513
|
ensureFile(".env.example", ENV_EXAMPLE);
|
|
514
|
+
if (scaffoldCanaryFile(root, config.cacheDir)) {
|
|
515
|
+
created.push(canaryRelPath(config.cacheDir));
|
|
516
|
+
}
|
|
452
517
|
// gitignore the derived cache and local secrets
|
|
453
518
|
const giPath = join(root, ".gitignore");
|
|
454
519
|
const ignoreLines = [
|
|
455
|
-
{ comment: "# RepoOS derived index cache", line:
|
|
520
|
+
{ comment: "# RepoOS derived index cache", line: canaryGitignoreIgnore(config.cacheDir) },
|
|
521
|
+
{
|
|
522
|
+
comment: "# RepoOS canary flow-test counter (tracked)",
|
|
523
|
+
line: canaryGitignoreNegation(config.cacheDir),
|
|
524
|
+
},
|
|
456
525
|
{ comment: "# Local secrets — see .env.example", line: ".env" },
|
|
457
526
|
];
|
|
458
527
|
const existingLines = existsSync(giPath) ? readFileSync(giPath, "utf8").split(/\r?\n/) : [];
|
|
@@ -521,6 +590,46 @@ async function ask(question) {
|
|
|
521
590
|
rl.close();
|
|
522
591
|
}
|
|
523
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* Like `ask`, but accepts multi-line input. On a TTY, a pasted block arrives as
|
|
595
|
+
* a burst of lines, so after each line we wait briefly for more; a typed line
|
|
596
|
+
* ending in `\\` also continues onto the next line. Non-TTY input (pipes, CI)
|
|
597
|
+
* stays strictly one line so later prompts' answers aren't swallowed.
|
|
598
|
+
*/
|
|
599
|
+
async function askMultiline(question) {
|
|
600
|
+
if (!input.isTTY)
|
|
601
|
+
return ask(question);
|
|
602
|
+
const rl = createInterface({ input, output });
|
|
603
|
+
return new Promise((resolvePromise) => {
|
|
604
|
+
const lines = [];
|
|
605
|
+
let timer;
|
|
606
|
+
let done = false;
|
|
607
|
+
const finish = () => {
|
|
608
|
+
if (done)
|
|
609
|
+
return;
|
|
610
|
+
done = true;
|
|
611
|
+
if (timer)
|
|
612
|
+
clearTimeout(timer);
|
|
613
|
+
rl.close();
|
|
614
|
+
resolvePromise(lines.join("\n").trim());
|
|
615
|
+
};
|
|
616
|
+
rl.on("close", finish);
|
|
617
|
+
rl.on("line", (line) => {
|
|
618
|
+
if (timer)
|
|
619
|
+
clearTimeout(timer);
|
|
620
|
+
if (line.endsWith("\\")) {
|
|
621
|
+
lines.push(line.slice(0, -1));
|
|
622
|
+
rl.setPrompt(" … ");
|
|
623
|
+
rl.prompt();
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
lines.push(line);
|
|
627
|
+
timer = setTimeout(finish, 75);
|
|
628
|
+
});
|
|
629
|
+
rl.setPrompt(question);
|
|
630
|
+
rl.prompt();
|
|
631
|
+
});
|
|
632
|
+
}
|
|
524
633
|
async function confirm(question, dflt) {
|
|
525
634
|
const hint = dflt ? " [Y/n]" : " [y/N]";
|
|
526
635
|
const answer = (await ask(question + c.dim(hint) + " ")).toLowerCase();
|
|
@@ -854,9 +963,34 @@ async function guidedNewRepo(args) {
|
|
|
854
963
|
console.log(c.yellow("\n Cancelled — nothing was created."));
|
|
855
964
|
return;
|
|
856
965
|
}
|
|
857
|
-
const description = await
|
|
858
|
-
c.dim(" —
|
|
966
|
+
const description = await askMultiline(" Project description" +
|
|
967
|
+
c.dim(" — gives the AI context to suggest next steps; paste multi-line markdown or end a line with \\ to continue (optional, Enter to skip)") +
|
|
968
|
+
": ");
|
|
969
|
+
// The task-area vocabulary (#0583) — reinforced with preview targets, since
|
|
970
|
+
// a `[[preview.targets]]` area is offered in the picker automatically even
|
|
971
|
+
// when not declared here. Skipped means free text only; never blocking.
|
|
972
|
+
const areasInput = await ask(" Task areas to seed the area picker" +
|
|
973
|
+
c.dim(" — comma-separated (e.g. web, cli, api; Enter to skip)") +
|
|
859
974
|
": ");
|
|
975
|
+
const areas = areasInput
|
|
976
|
+
? areasInput
|
|
977
|
+
.split(",")
|
|
978
|
+
.map((a) => a.trim())
|
|
979
|
+
.filter(Boolean)
|
|
980
|
+
: [];
|
|
981
|
+
if (areas.length) {
|
|
982
|
+
console.log(c.dim(" Preview targets route a task preview by its area — the picker and"));
|
|
983
|
+
console.log(c.dim(" the PM prompt offer target areas automatically; see user-docs/configuration.md's Previews section."));
|
|
984
|
+
}
|
|
985
|
+
// Preview targets reinforce areas ("define them together"): when an area
|
|
986
|
+
// vocabulary was given, offer to scaffold the commented `[[preview.targets]]`
|
|
987
|
+
// skeleton those areas feed, so the wiring sits where preview setup happens
|
|
988
|
+
// later. A brand-new project has nothing runnable yet — never a live
|
|
989
|
+
// preview command, just the commented shape to fill in.
|
|
990
|
+
let previewStub = false;
|
|
991
|
+
if (areas.length) {
|
|
992
|
+
previewStub = await confirm(" Scaffold commented preview-target stubs for these areas?", false);
|
|
993
|
+
}
|
|
860
994
|
if (!existsSync(target))
|
|
861
995
|
mkdirSync(target, { recursive: true });
|
|
862
996
|
// git health warnings — fail-soft, scaffold regardless
|
|
@@ -869,7 +1003,7 @@ async function guidedNewRepo(args) {
|
|
|
869
1003
|
console.log(c.dim(" git may auto-detect it, or the initial commit may fail. Set it with:"));
|
|
870
1004
|
console.log(c.dim(' git config --global user.name "You" && git config --global user.email you@example.com'));
|
|
871
1005
|
}
|
|
872
|
-
const { created, skipped } = scaffoldInto(target, description, layout);
|
|
1006
|
+
const { created, skipped } = scaffoldInto(target, description, layout, "new", areas, previewStub);
|
|
873
1007
|
reportInit(target, created, skipped);
|
|
874
1008
|
await offerCheckPlanProposal(target);
|
|
875
1009
|
if (!gitOk) {
|
package/dist/commands/serve.js
CHANGED
|
@@ -8,7 +8,7 @@ import { PREVIEW_REQUEST_SIGNAL } from "../server/agents.js";
|
|
|
8
8
|
import { isBun } from "../core/runtime.js";
|
|
9
9
|
import { findRepoRoot } from "../core/config.js";
|
|
10
10
|
import { c, statusColor } from "../cli/colors.js";
|
|
11
|
-
import { detectTailscaleIPv4 } from "../core/tailscale.js";
|
|
11
|
+
import { detectTailscaleIPv4, ensureTailscaleHttps } from "../core/tailscale.js";
|
|
12
12
|
/**
|
|
13
13
|
* The OS-visible process title for a `repoos serve` instance:
|
|
14
14
|
* `repoos-<project>`, where `<project>` is the managed root's directory name.
|
|
@@ -128,6 +128,7 @@ export async function cmdServe(args, opts = {}) {
|
|
|
128
128
|
let port;
|
|
129
129
|
let explicitHost;
|
|
130
130
|
let quiet = false;
|
|
131
|
+
let tailscaleHttps = true;
|
|
131
132
|
for (let i = 0; i < args.length; i++) {
|
|
132
133
|
if (args[i] === "--port" || args[i] === "-p")
|
|
133
134
|
port = Number(args[++i]);
|
|
@@ -135,6 +136,8 @@ export async function cmdServe(args, opts = {}) {
|
|
|
135
136
|
explicitHost = args[++i];
|
|
136
137
|
else if (args[i] === "--quiet" || args[i] === "-q")
|
|
137
138
|
quiet = true;
|
|
139
|
+
else if (args[i] === "--no-tailscale-https")
|
|
140
|
+
tailscaleHttps = false;
|
|
138
141
|
}
|
|
139
142
|
// Preview-only config overlay (#0464). A managed preview child
|
|
140
143
|
// (REPOOS_PREVIEW_CHILD=1, set by PreviewManager) applies the repo's
|
|
@@ -196,6 +199,22 @@ export async function cmdServe(args, opts = {}) {
|
|
|
196
199
|
c.cyan("--host 127.0.0.1") +
|
|
197
200
|
c.dim(" to restrict to localhost only."));
|
|
198
201
|
}
|
|
202
|
+
// HTTPS for tailnet devices (a plain-http IP isn't a secure context, so
|
|
203
|
+
// crypto.randomUUID etc. are missing). Skipped for managed previews, which
|
|
204
|
+
// must not touch the machine's `tailscale serve` config.
|
|
205
|
+
if (tailscaleDetected && tailscaleHttps && process.env.REPOOS_PREVIEW_CHILD !== "1") {
|
|
206
|
+
const https = await ensureTailscaleHttps(handle.port);
|
|
207
|
+
if (https.url) {
|
|
208
|
+
console.log(c.dim(" Tailscale HTTPS — open ") +
|
|
209
|
+
c.cyan(https.url) +
|
|
210
|
+
c.dim(" from your tailnet (secure context; ") +
|
|
211
|
+
c.cyan("--no-tailscale-https") +
|
|
212
|
+
c.dim(" to skip)."));
|
|
213
|
+
}
|
|
214
|
+
else if (https.reason) {
|
|
215
|
+
console.log(c.yellow(" Tailscale HTTPS unavailable: ") + c.dim(https.reason));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
199
218
|
console.log(c.dim(" press ^C to stop\n"));
|
|
200
219
|
// Fires only now that the server is actually listening (handle.url is a
|
|
201
220
|
// live, bound address) — a caller opening a browser tab any earlier races
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface CmdShotOptions {
|
|
2
|
+
route?: string;
|
|
3
|
+
target?: string;
|
|
4
|
+
selector?: string;
|
|
5
|
+
taskId?: string;
|
|
6
|
+
base: string;
|
|
7
|
+
waitMs: number;
|
|
8
|
+
viewport: {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
};
|
|
12
|
+
fullPage: boolean;
|
|
13
|
+
/** Set when an argument is unknown or malformed; cmdShot prints and exits. */
|
|
14
|
+
error?: string;
|
|
15
|
+
/** Set for `-h`/`--help`; cmdShot prints usage and exits 0. */
|
|
16
|
+
help?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* True when a browser-launch failure is the optional Playwright/WebKit package
|
|
20
|
+
* being absent or missing its binary — a clean skip with install advice, not a
|
|
21
|
+
* crash. Mirrors `ui-smoke.ts`'s classification for the same dependency.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isShotCaptureUnavailable(err: unknown): boolean;
|
|
24
|
+
/** Parse `repoos shot [<route|url>] [flags]`; unknown/malformed args set `error`. */
|
|
25
|
+
export declare function parseShotArgs(args: string[]): CmdShotOptions;
|
|
26
|
+
/**
|
|
27
|
+
* `repoos shot` entrypoint. Returns the process exit code: 0 on success (or a
|
|
28
|
+
* clean skip has already been reported), 1 on a real failure.
|
|
29
|
+
*/
|
|
30
|
+
export declare function cmdShot(args: string[]): Promise<number>;
|
|
31
|
+
export {};
|