Repository: val-town/vt
Pull request #50: Add push to jsr github action
Author: login: maxmcd
Created: 2025-03-18T20:29:01Z | Merged: 2025-03-18T21:44:03Z



Diff:
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 00000000..04eee262
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,19 @@
+name: Publish
+
+on:
+  push:
+    branches:
+      - main
+
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+      id-token: write
+
+    steps:
+      - uses: actions/checkout@v4
+      - name: Publish package
+        run: npx jsr publish
diff --git a/README.md b/README.md
index 5c64f4b1..e238ad17 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,8 @@ This is the cli to work with projects in the [Val Town](https://val.town)
 platform.
 
 ```
-$ vt
 Usage:   vt
-Version: 0.0.1
+Version: 0.0.3
 
 Options:
 
@@ -20,6 +19,7 @@ Commands:
   push                                            - Push local changes to a val town project
   status                                          - Show the working tree status
   branch                                          - List all project branches
+  browse                                          - Open a project in a web browser
   watch                                           - Watch for changes and automatically sync with Val Town
   checkout  [existingBranchName]                  - Check out a different branch
   create    <projectName> [targetDir]             - Create a new Val Town project
@@ -27,16 +27,16 @@ Commands:
 
 ## Installation
 
-Install with:
+To install or update to the latest version, run:
 
 ```bash
-deno install -A -g -n=vt https://raw.githubusercontent.com/val-town/vt/refs/heads/main/install.ts
+deno install -gAfr jsr:@valtown/vt
 ```
 
 Or if you would prefer a more descriptive command with minimal permissions:
 
 ```bash
-deno install --allow-read --allow-write --allow-run --allow-env --global --name=vt https://raw.githubusercontent.com/val-town/vt/refs/heads/main/install.ts
+deno install --global --force --reload --allow-read --allow-write --allow-env --allow-net jsr:@valtown/vt
 ```
 
 Set the `VAL_TOWN_API_KEY` environment variable to authenticate. Either as an
@@ -53,7 +53,7 @@ Run `vt` to confirm everything is working:
 
 ```bash
 $ vt --version
-vt 0.0.1
+vt 0.0.3
 ```
 
 ## Getting Started
diff --git a/deno.json b/deno.json
index 5f91c92e..f7dbe15b 100644
--- a/deno.json
+++ b/deno.json
@@ -1,6 +1,9 @@
 {
-  "version": "0.0.1",
+  "name": "@valtown/vt",
+  "description": "The Val Town CLI",
+  "version": "0.0.5",
   "exports": "./vt.ts",
+  "license": "MIT",
   "tasks": {
     "run": "./vt.ts",
     "test": "deno test -A",
@@ -10,23 +13,23 @@
   "imports": {
     "gitignore-parser": "jsr:@cfa/gitignore-parser@^0.1.4",
     "@cliffy/ansi": "jsr:@cliffy/ansi@^1.0.0-rc.7",
+    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@cliffy/prompt": "jsr:@cliffy/prompt@^1.0.0-rc.7",
     "@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.7",
     "@deno-library/logger": "jsr:@deno-library/logger@^1.1.9",
-    "@std/async": "jsr:@std/async@^1.0.11",
-    "@std/fs": "jsr:@std/fs@^1.0.13",
-    "@std/path": "jsr:@std/path@^1.0.8",
-    "zod": "npm:zod@^3.24.2",
-    "~/": "./src/",
-    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@std/assert": "jsr:@std/assert@1",
+    "@std/async": "jsr:@std/async@^1.0.11",
     "@std/dotenv": "jsr:@std/dotenv@^0.225.3",
     "@std/encoding": "jsr:@std/encoding@^1.0.7",
+    "@std/fs": "jsr:@std/fs@^1.0.13",
+    "@std/path": "jsr:@std/path@^1.0.8",
     "@valtown/sdk": "jsr:@valtown/sdk@^0.36.0",
+    "~/": "./src/",
     "emphasize": "npm:emphasize@^7.0.0",
-    "open": "npm:open@^10.1.0",
     "highlight.js": "npm:highlight.js@^11.11.1",
-    "kia": "https://deno.land/x/kia@0.4.1/mod.ts"
+    "kia": "jsr:@jonasschiano/kia@0.0.120",
+    "open": "npm:open@^10.1.0",
+    "zod": "npm:zod@^3.24.2"
   },
   "compilerOptions": {
     "noUnusedLocals": true,
diff --git a/deno.lock b/deno.lock
index 749c86e3..60d98133 100644
--- a/deno.lock
+++ b/deno.lock
@@ -11,19 +11,23 @@
     "jsr:@cliffy/prompt@^1.0.0-rc.7": "1.0.0-rc.7",
     "jsr:@cliffy/table@1.0.0-rc.7": "1.0.0-rc.7",
     "jsr:@deno-library/logger@^1.1.9": "1.1.9",
+    "jsr:@jonasschiano/kia@0.0.120": "0.0.120",
     "jsr:@std/assert@1": "1.0.11",
     "jsr:@std/assert@~1.0.6": "1.0.11",
     "jsr:@std/async@*": "1.0.11",
     "jsr:@std/async@^1.0.11": "1.0.11",
+    "jsr:@std/bytes@^1.0.5": "1.0.5",
     "jsr:@std/dotenv@~0.225.3": "0.225.3",
     "jsr:@std/encoding@^1.0.7": "1.0.7",
     "jsr:@std/encoding@~1.0.5": "1.0.7",
     "jsr:@std/fmt@1.0.3": "1.0.3",
+    "jsr:@std/fmt@1.0.5": "1.0.5",
     "jsr:@std/fmt@~1.0.2": "1.0.6",
     "jsr:@std/fs@^1.0.13": "1.0.14",
     "jsr:@std/fs@^1.0.6": "1.0.14",
     "jsr:@std/internal@^1.0.5": "1.0.5",
     "jsr:@std/io@~0.224.9": "0.224.9",
+    "jsr:@std/io@~0.225.2": "0.225.2",
     "jsr:@std/path@^1.0.8": "1.0.8",
     "jsr:@std/path@~1.0.6": "1.0.8",
     "jsr:@std/text@~1.0.7": "1.0.11",
@@ -45,7 +49,7 @@
         "jsr:@cliffy/internal",
         "jsr:@std/encoding@~1.0.5",
         "jsr:@std/fmt@~1.0.2",
-        "jsr:@std/io"
+        "jsr:@std/io@~0.224.9"
       ]
     },
     "@cliffy/command@1.0.0-rc.7": {
@@ -78,7 +82,8 @@
         "jsr:@cliffy/keycode",
         "jsr:@std/assert@~1.0.6",
         "jsr:@std/fmt@~1.0.2",
-        "jsr:@std/io",
+        "jsr:@std/io@~0.224.9",
+        "jsr:@std/io@~0.225.2",
         "jsr:@std/path@~1.0.6",
         "jsr:@std/text"
       ]
@@ -96,6 +101,13 @@
         "jsr:@std/fs@^1.0.6"
       ]
     },
+    "@jonasschiano/kia@0.0.120": {
+      "integrity": "6b88a98a10788ada17bde6accae2d807cabc4a610eff86446f7c7c05c8429309",
+      "dependencies": [
+        "jsr:@std/fmt@1.0.5",
+        "jsr:@std/io@~0.225.2"
+      ]
+    },
     "@std/assert@1.0.11": {
       "integrity": "2461ef3c368fe88bc60e186e7744a93112f16fd110022e113a0849e94d1c83c1",
       "dependencies": [
@@ -105,6 +117,9 @@
     "@std/async@1.0.11": {
       "integrity": "eee0d3405275506638a9c8efaa849cf0d35873120c69b7caa1309c9a9e5b6f85"
     },
+    "@std/bytes@1.0.5": {
+      "integrity": "4465dd739d7963d964c809202ebea6d5c6b8e3829ef25c6a224290fbb8a1021e"
+    },
     "@std/dotenv@0.225.3": {
       "integrity": "a95e5b812c27b0854c52acbae215856d9cce9d4bbf774d938c51d212711e8d4a"
     },
@@ -114,6 +129,9 @@
     "@std/fmt@1.0.3": {
       "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f"
     },
+    "@std/fmt@1.0.5": {
+      "integrity": "0cfab43364bc36650d83c425cd6d99910fc20c4576631149f0f987eddede1a4d"
+    },
     "@std/fmt@1.0.6": {
       "integrity": "a2c56a69a2369876ddb3ad6a500bb6501b5bad47bb3ea16bfb0c18974d2661fc"
     },
@@ -129,6 +147,12 @@
     "@std/io@0.224.9": {
       "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3"
     },
+    "@std/io@0.225.2": {
+      "integrity": "3c740cd4ee4c082e6cfc86458f47e2ab7cb353dc6234d5e9b1f91a2de5f4d6c7",
+      "dependencies": [
+        "jsr:@std/bytes"
+      ]
+    },
     "@std/path@1.0.8": {
       "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
     },
@@ -299,6 +323,7 @@
       "jsr:@cliffy/prompt@^1.0.0-rc.7",
       "jsr:@cliffy/table@1.0.0-rc.7",
       "jsr:@deno-library/logger@^1.1.9",
+      "jsr:@jonasschiano/kia@0.0.120",
       "jsr:@std/assert@1",
       "jsr:@std/async@^1.0.11",
       "jsr:@std/dotenv@~0.225.3",
diff --git a/src/vt/git/checkout.ts b/src/vt/git/checkout.ts
index 004bc907..fbecaed8 100644
--- a/src/vt/git/checkout.ts
+++ b/src/vt/git/checkout.ts
@@ -2,7 +2,7 @@ import { cleanDirectory, doAtomically } from "~/vt/git/utils.ts";
 import { clone } from "~/vt/git/clone.ts";
 import sdk from "~/sdk.ts";
 import { copy } from "@std/fs";
-import ValTown from "@valtown/sdk";
+import type ValTown from "@valtown/sdk";
 
 export interface CheckoutResult {
   fromBranch: ValTown.Projects.BranchCreateResponse;
diff --git a/src/vt/git/paths.ts b/src/vt/git/paths.ts
index 48a1b17b..db7487b0 100644
--- a/src/vt/git/paths.ts
+++ b/src/vt/git/paths.ts
@@ -1,4 +1,4 @@
-import { DEFAULT_VAL_TYPE, ProjectItem } from "~/consts.ts";
+import { DEFAULT_VAL_TYPE, type ProjectItem } from "~/consts.ts";
 import { filePathToFile } from "~/sdk.ts";
 import { compile as compileGitignore } from "gitignore-parser";
 
diff --git a/src/vt/git/tests/cases.ts b/src/vt/git/tests/cases.ts
index f900128a..1c51c853 100644
--- a/src/vt/git/tests/cases.ts
+++ b/src/vt/git/tests/cases.ts
@@ -1,4 +1,4 @@
-import { ExpectedProjectInode } from "~/vt/git/tests/utils.ts";
+import type { ExpectedProjectInode } from "~/vt/git/tests/utils.ts";
 
 export interface TestCaseBranchData {
   version: number;
diff --git a/src/vt/git/tests/status_test.ts b/src/vt/git/tests/status_test.ts
index fee01a08..7e2025ea 100644
--- a/src/vt/git/tests/status_test.ts
+++ b/src/vt/git/tests/status_test.ts
@@ -1,9 +1,9 @@
-import { FileStatus, status, StatusResult } from "~/vt/git/status.ts";
+import { type FileStatus, status, type StatusResult } from "~/vt/git/status.ts";
 import * as path from "@std/path";
 import { doWithTempDir } from "~/vt/git/utils.ts";
 import { clone } from "~/vt/git/clone.ts";
 import { assert } from "@std/assert";
-import { TestCaseBranchData, testCases } from "~/vt/git/tests/cases.ts";
+import { type TestCaseBranchData, testCases } from "~/vt/git/tests/cases.ts";
 
 for (const testCase of testCases) {
   for (const branchId in testCase.branches) {
diff --git a/src/vt/git/utils.ts b/src/vt/git/utils.ts
index 8db7f088..61ea3f94 100644
--- a/src/vt/git/utils.ts
+++ b/src/vt/git/utils.ts
@@ -1,4 +1,4 @@
-import { StatusResult } from "~/vt/git/status.ts";
+import type { StatusResult } from "~/vt/git/status.ts";
 import * as path from "@std/path";
 import { shouldIgnore } from "~/vt/git/paths.ts";
 import ValTown from "@valtown/sdk";
diff --git a/src/vt/vt/VTClient.ts b/src/vt/vt/VTClient.ts
index 0e14a569..95d617f1 100644
--- a/src/vt/vt/VTClient.ts
+++ b/src/vt/vt/VTClient.ts
@@ -2,7 +2,7 @@ import { clone } from "~/vt/git/clone.ts";
 import VTMeta from "~/vt/vt/VTMeta.ts";
 import { pull } from "~/vt/git/pull.ts";
 import { push } from "~/vt/git/push.ts";
-import { status, StatusResult } from "~/vt/git/status.ts";
+import { status, type StatusResult } from "~/vt/git/status.ts";
 import { denoJson, vtIgnore } from "~/vt/vt/editor/mod.ts";
 import { join } from "@std/path";
 import { checkout, CheckoutResult } from "~/vt/git/checkout.ts";
diff --git a/src/vt/vt/VTMeta.ts b/src/vt/vt/VTMeta.ts
index 827be343..294516f6 100644
--- a/src/vt/vt/VTMeta.ts
+++ b/src/vt/vt/VTMeta.ts
@@ -1,4 +1,4 @@
-import z from "zod";
+import type z from "zod";
 import { VTMetaConfigJsonSchema } from "~/vt/vt/schemas.ts";
 import {
   ALWAYS_IGNORE_PATTERNS,


Reviews:
user: login: maxmcd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:01:54Z
user: login: 404Wolf
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:36:20Z
user: login: 404Wolf
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:36:58Z
user: login: 404Wolf
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:37:22Z
user: login: 404Wolf
body: How does auth for the CI work? If you're sure it works as is then otherwise lgtm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:38:06Z
user: login: maxmcd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:38:34Z
user: login: maxmcd
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:40:02Z
user: login: 404Wolf
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:41:08Z

Review comments:
diff_hunk: @@ -9,21 +12,21 @@
   },
   "imports": {
     "@cliffy/ansi": "jsr:@cliffy/ansi@^1.0.0-rc.7",
+    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.7",
     "@deno-library/logger": "jsr:@deno-library/logger@^1.1.9",
-    "@std/async": "jsr:@std/async@^1.0.11",
-    "@std/fs": "jsr:@std/fs@^1.0.13",
-    "@std/path": "jsr:@std/path@^1.0.8",
-    "zod": "npm:zod@^3.24.2",
-    "~/": "./src/",
-    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@std/assert": "jsr:@std/assert@1",
+    "@std/async": "jsr:@std/async@^1.0.11",
     "@std/dotenv": "jsr:@std/dotenv@^0.225.3",
     "@std/encoding": "jsr:@std/encoding@^1.0.7",
+    "@std/fs": "jsr:@std/fs@^1.0.13",
+    "@std/path": "jsr:@std/path@^1.0.8",
     "@valtown/sdk": "jsr:@valtown/sdk@^0.36.0",
+    "~/": "./src/",
     "emphasize": "npm:emphasize@^7.0.0",
-    "open": "npm:open@^10.1.0",
     "highlight.js": "npm:highlight.js@^11.11.1",
-    "kia": "https://deno.land/x/kia@0.4.1/mod.ts"
path: deno.json
user: login: maxmcd
body: this disallow https imports, so I had to replace this. otherwise I just sorted the list
created_at: 2025-03-18T21:01:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,5 +1,5 @@
 import * as path from "@std/path";
-import { DEFAULT_VAL_TYPE, ProjectItem } from "~/consts.ts";
+import { DEFAULT_VAL_TYPE, type ProjectItem } from "~/consts.ts";
path: src/vt/git/paths.ts
user: login: maxmcd
body: deno lint errors
created_at: 2025-03-18T21:01:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -11,7 +11,10 @@ import { DEFAULT_IGNORE_PATTERNS } from "~/consts.ts";
 import Kia from "kia";
 import { APIError } from "@valtown/sdk";
 
-const cmd = new Command()
+/**
+ * The fully configured cliffy Command class that defines the Val Town cli.
path: src/cmd/root.ts
user: login: maxmcd
body: this improves our "package score", prob not actually useful, was mostly curious
created_at: 2025-03-18T21:01:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+name: Publish
+
+on:
+  push:
+    branches:
+      - main
+
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+      id-token: write
+
+    steps:
+      - uses: actions/checkout@v4
+      - name: Publish package
+        run: npx jsr publish
path: .github/workflows/publish.yml
user: login: 404Wolf
body: I might be missing something, but how does auth work? I don't see an env: here. I haven't used jsr publish so maybe there's something automagic about it running from github CI?
created_at: 2025-03-18T21:36:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -4,9 +4,8 @@ This is the cli to work with projects in the [Val Town](https://val.town)
 platform.
 
 ```
-$ vt
path: README.md
user: login: 404Wolf
body: We should eventually figure out a way to not have to manually maintain this :/
created_at: 2025-03-18T21:36:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,21 +12,21 @@
   },
   "imports": {
     "@cliffy/ansi": "jsr:@cliffy/ansi@^1.0.0-rc.7",
+    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.7",
     "@deno-library/logger": "jsr:@deno-library/logger@^1.1.9",
-    "@std/async": "jsr:@std/async@^1.0.11",
-    "@std/fs": "jsr:@std/fs@^1.0.13",
-    "@std/path": "jsr:@std/path@^1.0.8",
-    "zod": "npm:zod@^3.24.2",
-    "~/": "./src/",
-    "@cliffy/command": "jsr:@cliffy/command@^1.0.0-rc.7",
     "@std/assert": "jsr:@std/assert@1",
+    "@std/async": "jsr:@std/async@^1.0.11",
     "@std/dotenv": "jsr:@std/dotenv@^0.225.3",
     "@std/encoding": "jsr:@std/encoding@^1.0.7",
+    "@std/fs": "jsr:@std/fs@^1.0.13",
+    "@std/path": "jsr:@std/path@^1.0.8",
     "@valtown/sdk": "jsr:@valtown/sdk@^0.36.0",
+    "~/": "./src/",
     "emphasize": "npm:emphasize@^7.0.0",
-    "open": "npm:open@^10.1.0",
     "highlight.js": "npm:highlight.js@^11.11.1",
-    "kia": "https://deno.land/x/kia@0.4.1/mod.ts"
path: deno.json
user: login: 404Wolf
body: Sounds good. Can you check the current version to see if it looks ok, I merged main into it and might have messed up your order.
created_at: 2025-03-18T21:37:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+name: Publish
+
+on:
+  push:
+    branches:
+      - main
+
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+      id-token: write
+
+    steps:
+      - uses: actions/checkout@v4
+      - name: Publish package
+        run: npx jsr publish
path: .github/workflows/publish.yml
user: login: maxmcd
body: https://jsr.io/docs/publishing-packages#publishing-from-github-actions

It's oidc, the action is using a github token to auth with jsr, and jsr knows what github repo we'll be making requests from. 
created_at: 2025-03-18T21:38:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+name: Publish
+
+on:
+  push:
+    branches:
+      - main
+
+jobs:
+  publish:
+    runs-on: ubuntu-latest
+
+    permissions:
+      contents: read
+      id-token: write
+
+    steps:
+      - uses: actions/checkout@v4
+      - name: Publish package
+        run: npx jsr publish
path: .github/workflows/publish.yml
user: login: maxmcd
body: I think the trick is this part:

    permissions:
      contents: read
      id-token: write
      
Which is giving some kind of github token permission.
created_at: 2025-03-18T21:39:58Z
author_association: CONTRIBUTOR

PR comments:
user: login: maxmcd
created_at: 2025-03-18T21:00:16Z
body: Hey @404Wolf this is good to go. Feel free to make edits to the branch directly if you think any of this should be changed, just trying to get it all working/updated.
author_association: CONTRIBUTOR
user: login: maxmcd
created_at: 2025-03-18T21:39:17Z
body: Yep, there are successful runs and it is published: https://github.com/val-town/vt/actions/runs/13933260142/job/38995332374
https://jsr.io/@valtown/vt

author_association: CONTRIBUTOR
user: login: 404Wolf
created_at: 2025-03-18T21:40:51Z
body: > Yep, there are successful runs and it is published: https://github.com/val-town/vt/actions/runs/13933260142/job/38995332374 https://jsr.io/@valtown/vt

Sweet! How does it work though? I merged in main so you can squash this now if you want!
author_association: CONTRIBUTOR
user: login: maxmcd
created_at: 2025-03-18T21:41:48Z
body: When we bump the deno.json version to a higher number it will be published to jsr on merge to main.
author_association: CONTRIBUTOR
user: login: maxmcd
created_at: 2025-03-18T21:42:20Z
body: I'll merge in the changes and bump the version so that we get a publish on main. 
author_association: CONTRIBUTOR