Skip to content

Commit b9ff547

Browse files
Merge branch 'main' into chore/changelog-v1.12.0
2 parents 5cfb0f9 + 64c0a56 commit b9ff547

15 files changed

Lines changed: 605 additions & 30 deletions

catalogue/README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,16 @@ fields stay required. `pilotctl` decodes the index directly into
5858
`catalogueEntry` in `cmd/pilotctl/appstore_catalogue.go` — any field added
5959
here must also land there.
6060

61-
`bundles` (v3) is the per-platform map keyed by `"os/arch"`. When present,
62-
`install` picks the host's entry and **errors** if the host platform isn't
63-
listed (rather than installing a binary that can't exec). `bundle_url` /
64-
`bundle_sha256` stay as the back-compat primary (linux/amd64) that pre-v3
65-
clients fetch, so a `bundles`-bearing entry still installs on old `pilotctl`
66-
for that one platform. An entry that omits `bundles` behaves exactly as v1/v2
67-
(single-platform, top-level `bundle_url`).
61+
`bundles` is the per-platform map keyed by `"os/arch"`. It is an **optional v2
62+
field — keep `"version": 2`, do NOT bump to 3.** `loadCatalogue` fail-closes on
63+
any version other than 1 or 2, so a version-3 catalogue is rejected wholesale by
64+
every client; `bundles` follows the same optional-field rule as the other v2
65+
additions. When present, a bundles-aware client (`pilotctl` ≥ v1.12.0) picks the
66+
host's entry; older clients ignore the map and fetch the top-level `bundle_url`.
67+
`bundle_url` / `bundle_sha256` stay as the back-compat primary (linux/amd64) so a
68+
`bundles`-bearing entry still installs on pre-v1.12 `pilotctl` for that one
69+
platform. An entry that omits `bundles` behaves exactly as before (single-platform,
70+
top-level `bundle_url`).
6871

6972
## Detail schema (`apps/<id>/metadata.json`)
7073

catalogue/catalogue.json

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
"bundle_sha256": "8d30b4331bc025c327dd2d8610362984cc9365843176e21b96a2637d8e18ff54",
1111
"display_name": "Wallet",
1212
"vendor": "Pilot Protocol",
13-
"categories": ["payments", "crypto", "finance"],
13+
"categories": [
14+
"payments",
15+
"crypto",
16+
"finance"
17+
],
1418
"bundle_size": 9110758,
1519
"source_url": "https://github.com/pilot-protocol/wallet",
1620
"license": "AGPL-3.0-or-later",
@@ -25,7 +29,11 @@
2529
"bundle_sha256": "faf60deeaa9a29298b447f7f0276f1bd4523af86390cf65c677452dc9718d5a0",
2630
"display_name": "Cosift",
2731
"vendor": "Pilot Protocol",
28-
"categories": ["search", "research", "retrieval"],
32+
"categories": [
33+
"search",
34+
"research",
35+
"retrieval"
36+
],
2937
"bundle_size": 4774876,
3038
"source_url": "https://github.com/pilot-protocol/cosift",
3139
"license": "MIT",
@@ -36,16 +44,38 @@
3644
"id": "io.pilot.sixtyfour",
3745
"version": "0.1.0",
3846
"description": "Sixtyfour is the app-store front door for the Sixtyfour people-intelligence and company-intelligence API. It gives an agent contact discovery (find email / find phone), reverse lookups from an email or phone, full person and company enrichment, and an agentic QA researcher that answers free-form questions about a person or company. All returned as clean structured JSON, every field source-backed.",
39-
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0.tar.gz",
40-
"bundle_sha256": "b259f6a3b84fe16043cb972985efcdcb3d568174ac3c8a4129d551ec8ca9a712",
47+
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0-linux-amd64.tar.gz",
48+
"bundle_sha256": "7508bb88b18a7d4b7302a9e14c9874c3bc23d8e4ed5edd0d45140a2479e07868",
4149
"display_name": "Sixtyfour",
4250
"vendor": "Sixtyfour",
43-
"categories": ["data", "enrichment", "sales-intelligence"],
51+
"categories": [
52+
"data",
53+
"enrichment",
54+
"sales-intelligence"
55+
],
4456
"bundle_size": 4898153,
4557
"source_url": "https://docs.sixtyfour.ai",
4658
"license": "Proprietary",
4759
"metadata_url": "https://raw.githubusercontent.com/pilot-protocol/pilotprotocol/main/catalogue/apps/io.pilot.sixtyfour/metadata.json",
48-
"metadata_sha256": "32512d7d401f0578e4aded373694c588b205bdea9f00d6d90618687b5df95e6d"
60+
"metadata_sha256": "32512d7d401f0578e4aded373694c588b205bdea9f00d6d90618687b5df95e6d",
61+
"bundles": {
62+
"linux/amd64": {
63+
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0-linux-amd64.tar.gz",
64+
"bundle_sha256": "7508bb88b18a7d4b7302a9e14c9874c3bc23d8e4ed5edd0d45140a2479e07868"
65+
},
66+
"linux/arm64": {
67+
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0-linux-arm64.tar.gz",
68+
"bundle_sha256": "54298610357c9d69060d066b75096bca43fc3014026cdbd7194b766ffc3a1ffc"
69+
},
70+
"darwin/arm64": {
71+
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0-darwin-arm64.tar.gz",
72+
"bundle_sha256": "98d44f7138843bf72665bf4a49b6157ed95bb64ae24f21f0577cbc51e3abd493"
73+
},
74+
"darwin/amd64": {
75+
"bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/sixtyfour-v0.1.0/io.pilot.sixtyfour-0.1.0-darwin-amd64.tar.gz",
76+
"bundle_sha256": "d970483e9cad84207f853d681cc810e954e236acd5e410b402880dc4d8304aa2"
77+
}
78+
}
4979
}
5080
]
5181
}

catalogue/catalogue.json.sig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
zyCgPzwS0Ecvlpc4IdtDFJ+pWxxeUqK4MDx7u4RGEMboUuv737um3ed8P22V5gmYu30YW9zy3X8bVdXRA8V2CQ==
1+
Q/l0OEbbuuEL5ViogHnrggis1OEUTK0YVKcCytFrLj0T9s0sB2fEo48GckCzopulC8cg+E9qZdl8Pk8VnpkGDw==

cmd/pilotctl/main.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,13 +1148,19 @@ Common keys:
11481148
11491149
Print the pilotctl build version string.
11501150
`,
1151-
"update": `Usage: pilotctl update [flags]
1151+
"update": `Usage: pilotctl update [subcommand|flags]
11521152
1153-
Run the updater once — check for new releases and install if available.
1154-
In manual mode (daemon not running), re-runs skill install so newly
1155-
installed binaries have matching skill definitions.
1153+
Automatic updates are OFF by default. Control them with:
1154+
pilotctl update status show whether auto-update is on and the current version
1155+
pilotctl update enable turn automatic updates ON
1156+
pilotctl update disable turn automatic updates OFF (default)
11561157
1157-
Flags:
1158+
With no subcommand, runs the updater ONCE — a manual check that installs the
1159+
latest release if available, regardless of the auto-update setting. In manual
1160+
mode (daemon not running), re-runs skill install so newly installed binaries
1161+
have matching skill definitions.
1162+
1163+
Flags (one-shot mode):
11581164
--repo <name> GitHub owner/repo for releases (default: pilot-protocol/pilotprotocol)
11591165
--pin <tag> pin to a specific release tag (e.g. v1.10.5)
11601166
`,

cmd/pilotctl/updates.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package main
44

55
import (
6+
"encoding/json"
67
"encoding/xml"
78
"fmt"
89
"io"
@@ -17,6 +18,76 @@ import (
1718
"github.com/pilot-protocol/updater"
1819
)
1920

21+
// autoUpdateStatePath is the JSON control file ({"enabled": bool}) shared with
22+
// the pilot-updater loop (passed as its --state-path). Automatic updates are
23+
// OFF by default: when the file is absent the updater applies nothing.
24+
func autoUpdateStatePath() string { return configDir() + "/auto-update.json" }
25+
26+
// autoUpdateEnabled reports the persisted auto-update setting (default off).
27+
func autoUpdateEnabled() bool {
28+
data, err := os.ReadFile(autoUpdateStatePath())
29+
if err != nil {
30+
return false
31+
}
32+
var s struct {
33+
Enabled bool `json:"enabled"`
34+
}
35+
if err := json.Unmarshal(data, &s); err != nil {
36+
return false
37+
}
38+
return s.Enabled
39+
}
40+
41+
// cmdAutoUpdateSet turns automatic updates on or off (`pilotctl update
42+
// enable|disable`). The pilot-updater re-reads the file each tick, so this
43+
// takes effect without restarting it.
44+
func cmdAutoUpdateSet(on bool) {
45+
path := autoUpdateStatePath()
46+
_ = os.MkdirAll(configDir(), 0o755)
47+
data, _ := json.MarshalIndent(map[string]bool{"enabled": on}, "", " ")
48+
if err := os.WriteFile(path, append(data, '\n'), 0o644); err != nil {
49+
fatalCode("internal", "write %s: %v", path, err)
50+
}
51+
if jsonOutput {
52+
outputOK(map[string]interface{}{"auto_update": on})
53+
return
54+
}
55+
if on {
56+
fmt.Println("Automatic updates ENABLED. The updater will install new stable releases on its check interval.")
57+
fmt.Println("Disable any time with: pilotctl update disable")
58+
} else {
59+
fmt.Println("Automatic updates DISABLED. Nothing will be installed automatically.")
60+
fmt.Println("Run a one-time manual update with: pilotctl update")
61+
}
62+
}
63+
64+
// cmdAutoUpdateStatus shows whether automatic updates are on and the current
65+
// version (`pilotctl update status`).
66+
func cmdAutoUpdateStatus() {
67+
on := autoUpdateEnabled()
68+
if jsonOutput {
69+
outputOK(map[string]interface{}{
70+
"auto_update": on,
71+
"current_version": version,
72+
"state_file": autoUpdateStatePath(),
73+
})
74+
return
75+
}
76+
state := "disabled"
77+
if on {
78+
state = "enabled"
79+
}
80+
fmt.Printf("Automatic updates: %s\n", state)
81+
fmt.Printf("Current version: %s\n", version)
82+
fmt.Printf("State file: %s\n", autoUpdateStatePath())
83+
if on {
84+
fmt.Println("\nTurn off with: pilotctl update disable")
85+
} else {
86+
fmt.Println("\nTurn on with: pilotctl update enable")
87+
fmt.Println("One-time check: pilotctl update")
88+
}
89+
}
90+
2091
// changelogFeedURL is the canonical RSS 2.0 feed for the public Pilot
2192
// Protocol changelog. Hosted on GitHub Pages from the pilot-changelog
2293
// repo (per `pilot-changelog/README.md`). RSS chosen over feed.json so
@@ -218,6 +289,22 @@ func collapseWhitespace(s string) string {
218289
// --pin <tag> : pin to a specific release tag (e.g. v1.10.5)
219290
// (global) --json : emit machine-readable JSON
220291
func cmdUpdate(args []string) {
292+
// Auto-update control surface: `pilotctl update status|enable|disable`.
293+
// Bare `pilotctl update` (or with --repo/--pin flags) runs a one-shot
294+
// manual update, which works regardless of the auto-update setting.
295+
if len(args) >= 1 {
296+
switch args[0] {
297+
case "status":
298+
cmdAutoUpdateStatus()
299+
return
300+
case "enable", "on":
301+
cmdAutoUpdateSet(true)
302+
return
303+
case "disable", "off":
304+
cmdAutoUpdateSet(false)
305+
return
306+
}
307+
}
221308
flags, _ := parseFlags(args)
222309
repo := flagString(flags, "repo", "pilot-protocol/pilotprotocol")
223310
pin := flagString(flags, "pin", "")

cmd/pilotctl/verify.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func nodeArgToID(s string) uint32 {
4040
//
4141
// pilotctl verify # show your own verification status
4242
// pilotctl verify status # same
43+
// pilotctl verify --provider github # self-service: device-flow via the verifier
4344
// pilotctl verify --badge <badge> --badge-sig <sig>
4445
// pilotctl verify --from cred.json # {"badge":..,"badge_sig":..}
4546
func cmdVerify(args []string) {
@@ -48,6 +49,11 @@ func cmdVerify(args []string) {
4849
return
4950
}
5051
flags, _ := parseFlags(args)
52+
// Self-service device-flow: dial the verifier, run the browser flow, submit.
53+
if provider := flagString(flags, "provider", ""); provider != "" {
54+
cmdVerifyProvider(flags, provider)
55+
return
56+
}
5157
badge := flagString(flags, "badge", "")
5258
badgeSig := flagString(flags, "badge-sig", "")
5359
if from := flagString(flags, "from", ""); from != "" {

0 commit comments

Comments
 (0)