@headways/cli 1.0.0 → 1.1.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 (2) hide show
  1. package/dist/index.js +137 -49
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18,52 +18,6 @@ import {
18
18
  import "dotenv/config";
19
19
  import { program } from "commander";
20
20
 
21
- // package.json
22
- var package_default = {
23
- name: "@headways/cli",
24
- version: "1.0.0",
25
- type: "module",
26
- description: "Headways CLI \u2014 authoring, sync, and runtime SDK",
27
- license: "MIT",
28
- files: [
29
- "dist",
30
- "LICENSE",
31
- "README.md"
32
- ],
33
- bin: {
34
- headways: "./dist/index.js"
35
- },
36
- publishConfig: {
37
- access: "public"
38
- },
39
- scripts: {
40
- build: "tsup",
41
- dev: "tsx src/index.ts",
42
- test: "vitest run",
43
- "test:unit": "vitest run",
44
- "type-check": "tsc -p tsconfig.json --noEmit",
45
- prepublishOnly: "pnpm build"
46
- },
47
- dependencies: {
48
- "@headways/db": "workspace:*",
49
- "@modelcontextprotocol/sdk": "^1.15.0",
50
- chalk: "^5.3.0",
51
- commander: "^12.1.0",
52
- dotenv: "^16.4.7",
53
- "node-fetch": "^3.3.2",
54
- yaml: "^2.5.1",
55
- zod: "^3.25.28"
56
- },
57
- devDependencies: {
58
- "@headways/config": "workspace:*",
59
- "@types/node": "^22.16.5",
60
- tsup: "^8.5.1",
61
- tsx: "^4.21.0",
62
- typescript: "^5.8.3",
63
- vitest: "^3.2.4"
64
- }
65
- };
66
-
67
21
  // src/commands/auth.ts
68
22
  import "commander";
69
23
  import * as http from "http";
@@ -366,6 +320,7 @@ import "commander";
366
320
  import * as fs2 from "fs/promises";
367
321
  import * as path2 from "path";
368
322
  import { watch, existsSync } from "fs";
323
+ import * as YAML from "yaml";
369
324
  var RESERVED_TOP_LEVEL = /* @__PURE__ */ new Set([
370
325
  "SKILL.md",
371
326
  "headways.yaml",
@@ -426,12 +381,32 @@ async function readSkillDir(dir) {
426
381
  const items = parseConnectionsYaml(connectionsYaml);
427
382
  if (items.length > 0) connections = items;
428
383
  }
384
+ let capabilities;
385
+ if (capabilitiesYaml) {
386
+ try {
387
+ capabilities = YAML.parse(capabilitiesYaml);
388
+ } catch (err) {
389
+ throw new Error(
390
+ `Failed to parse capabilities.yaml: ${err instanceof Error ? err.message : String(err)}`
391
+ );
392
+ }
393
+ }
394
+ let hooks;
395
+ if (hooksYaml) {
396
+ try {
397
+ hooks = YAML.parse(hooksYaml);
398
+ } catch (err) {
399
+ throw new Error(
400
+ `Failed to parse hooks.yaml: ${err instanceof Error ? err.message : String(err)}`
401
+ );
402
+ }
403
+ }
429
404
  const extraFiles = await collectExtraFiles(dir);
430
405
  return {
431
406
  body,
432
407
  headline,
433
- capabilities: capabilitiesYaml ?? void 0,
434
- hooks: hooksYaml ?? void 0,
408
+ capabilities,
409
+ hooks,
435
410
  connections,
436
411
  files: Object.keys(extraFiles).length > 0 ? extraFiles : void 0
437
412
  };
@@ -1115,12 +1090,125 @@ function getInstalledSkills() {
1115
1090
  }
1116
1091
  }
1117
1092
 
1093
+ // src/commands/upgrade.ts
1094
+ import { chmodSync, renameSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
1095
+ import { delimiter, basename as basename3, dirname, join as join6 } from "path";
1096
+ import { existsSync as existsSync5, statSync as statSync2 } from "fs";
1097
+ import "commander";
1098
+ var GCS_BASE = "https://storage.googleapis.com/headways-releases/cli";
1099
+ var NPM_PACKAGE = "@headways/cli";
1100
+ function registerUpgradeCommand(program2) {
1101
+ program2.command("upgrade").description("Upgrade the Headways CLI to the latest version").option("--force", "Reinstall even if already on the latest version").action(async (opts) => {
1102
+ warnIfShadowed();
1103
+ const mode = detectInstallMode();
1104
+ if (mode.kind === "npm") {
1105
+ console.log(
1106
+ `This binary was installed via npm. Upgrade with:
1107
+
1108
+ npm i -g ${NPM_PACKAGE}@latest
1109
+ `
1110
+ );
1111
+ return;
1112
+ }
1113
+ if (mode.kind === "unknown") {
1114
+ console.error(
1115
+ `Could not determine how this CLI was installed (execPath: ${process.execPath}).
1116
+ If installed via npm: npm i -g ${NPM_PACKAGE}@latest
1117
+ If installed via desktop: re-run the Install step from the Headways app.`
1118
+ );
1119
+ process.exitCode = 1;
1120
+ return;
1121
+ }
1122
+ await selfUpdate(mode.binPath, opts.force ?? false);
1123
+ });
1124
+ }
1125
+ function detectInstallMode() {
1126
+ const exec = process.execPath;
1127
+ const execName = basename3(exec).toLowerCase();
1128
+ if (execName === "node" || execName === "bun" || execName.startsWith("node")) {
1129
+ return { kind: "npm" };
1130
+ }
1131
+ if (execName === "headways" || execName.startsWith("headways")) {
1132
+ return { kind: "standalone", binPath: exec };
1133
+ }
1134
+ return { kind: "unknown" };
1135
+ }
1136
+ function detectTriple() {
1137
+ if (process.platform !== "darwin") return null;
1138
+ if (process.arch === "arm64") return "aarch64-apple-darwin";
1139
+ if (process.arch === "x64") return "x86_64-apple-darwin";
1140
+ return null;
1141
+ }
1142
+ async function selfUpdate(binPath, force) {
1143
+ const triple = detectTriple();
1144
+ if (!triple) {
1145
+ console.error(
1146
+ `No prebuilt binary for ${process.platform}/${process.arch}. Standalone binaries are macOS-only; on other platforms use: npm i -g ${NPM_PACKAGE}@latest`
1147
+ );
1148
+ process.exitCode = 1;
1149
+ return;
1150
+ }
1151
+ console.log(`Checking for updates\u2026 (current: ${"1.1.0"})`);
1152
+ const latestRes = await fetch(`${GCS_BASE}/latest.txt`);
1153
+ if (!latestRes.ok) {
1154
+ console.error(`Failed to fetch latest version: ${latestRes.status} ${latestRes.statusText}`);
1155
+ process.exitCode = 1;
1156
+ return;
1157
+ }
1158
+ const latest = (await latestRes.text()).trim();
1159
+ if (latest === "1.1.0" && !force) {
1160
+ console.log(`Already on the latest version (${latest}).`);
1161
+ return;
1162
+ }
1163
+ console.log(`Downloading ${latest} for ${triple}\u2026`);
1164
+ const binRes = await fetch(`${GCS_BASE}/${latest}/headways-${triple}`);
1165
+ if (!binRes.ok) {
1166
+ console.error(`Failed to download binary: ${binRes.status} ${binRes.statusText}`);
1167
+ process.exitCode = 1;
1168
+ return;
1169
+ }
1170
+ const bin = Buffer.from(await binRes.arrayBuffer());
1171
+ const tmpPath = join6(dirname(binPath), `.headways.upgrade.${process.pid}`);
1172
+ writeFileSync2(tmpPath, bin);
1173
+ try {
1174
+ chmodSync(tmpPath, 493);
1175
+ renameSync(tmpPath, binPath);
1176
+ } catch (e) {
1177
+ try {
1178
+ unlinkSync2(tmpPath);
1179
+ } catch {
1180
+ }
1181
+ throw e;
1182
+ }
1183
+ console.log(`Upgraded to ${latest} \u2192 ${binPath}`);
1184
+ }
1185
+ function warnIfShadowed() {
1186
+ const exec = process.execPath;
1187
+ const pathDirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
1188
+ const found = [];
1189
+ for (const dir of pathDirs) {
1190
+ const candidate = join6(dir, "headways");
1191
+ try {
1192
+ if (existsSync5(candidate) && statSync2(candidate).isFile()) {
1193
+ found.push(candidate);
1194
+ }
1195
+ } catch {
1196
+ }
1197
+ }
1198
+ if (found.length > 0 && found[0] !== exec) {
1199
+ console.error(
1200
+ `note: another 'headways' is earlier on PATH at ${found[0]} \u2014 running upgrade here won't change which binary your shell picks.`
1201
+ );
1202
+ }
1203
+ }
1204
+
1118
1205
  // src/index.ts
1119
- program.name("headways").description("Headways CLI \u2014 skill authoring + Claude Code runtime helpers").version(package_default.version);
1206
+ program.name("headways").description("Headways CLI \u2014 skill authoring + Claude Code runtime helpers").version("1.1.0");
1120
1207
  registerAuthCommands(program);
1121
1208
  registerSkillsCommands(program);
1122
1209
  registerConnectionsCommands(program);
1123
1210
  registerEmitCommand(program);
1124
1211
  registerSkillRunCommands(program);
1125
1212
  registerPrimeCommand(program);
1213
+ registerUpgradeCommand(program);
1126
1214
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headways/cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "Headways CLI — authoring, sync, and runtime SDK",
6
6
  "license": "MIT",