@arcadeai/hypotenuse 0.14.0 → 0.15.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.
@@ -343,7 +343,7 @@ import { Command } from "commander";
343
343
  // package.json
344
344
  var package_default = {
345
345
  name: "@arcadeai/hypotenuse",
346
- version: "0.14.0",
346
+ version: "0.15.0",
347
347
  description: "Hypotenuse \u2014 run coding agents on your machine for Linear agent sessions",
348
348
  type: "module",
349
349
  license: "Apache-2.0",
@@ -377,7 +377,7 @@ var package_default = {
377
377
  lint: "tsc && biome check .",
378
378
  format: "tsc && biome check --write .",
379
379
  bundle: "bun build ./src/cli.ts --target bun --packages external --outfile dist/hypotenuse.js",
380
- build: "bun build --compile --minify --sourcemap ./src/cli.ts --outfile dist/hypotenuse",
380
+ build: "bun build --compile --minify --sourcemap ./src/cli.ts ./skills/hypotenuse.md --loader .md:file --asset-naming='[name].[ext]' --outfile dist/hypotenuse",
381
381
  prepack: "bun run bundle"
382
382
  },
383
383
  dependencies: {
@@ -3598,6 +3598,13 @@ async function resolveProjectId(client, selector) {
3598
3598
  }
3599
3599
  }
3600
3600
  }
3601
+ async function onlyProject(client) {
3602
+ const { projects, pagination } = await client.request("GET", "/projects", { query: { page: 1, limit: 2 } });
3603
+ return {
3604
+ project: pagination.total === 1 ? projects[0] ?? null : null,
3605
+ total: pagination.total
3606
+ };
3607
+ }
3601
3608
 
3602
3609
  // src/api/url.ts
3603
3610
  import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
@@ -3752,10 +3759,14 @@ class CliContext {
3752
3759
  }
3753
3760
  async projectId() {
3754
3761
  const selector = this.options.project ?? this.env.HYPOTENUSE_PROJECT ?? (this.credentials.servers[this.server.origin]?.project != null ? String(this.credentials.servers[this.server.origin]?.project) : undefined);
3755
- if (!selector) {
3756
- throw new Error("No project selected. Pass --project <id|slug> or run `hypotenuse project use <id|slug>`.");
3762
+ if (selector)
3763
+ return resolveProjectId(this.signedInClient(), selector);
3764
+ const { project, total } = await onlyProject(this.signedInClient());
3765
+ if (project) {
3766
+ logger.info(`Using project ${project.slug}, the only one you are in.`);
3767
+ return project.id;
3757
3768
  }
3758
- return resolveProjectId(this.signedInClient(), selector);
3769
+ throw new Error(total === 0 ? "You are not in any project yet. Create one in the dashboard, or accept an invite." : "No project selected, and you are in several. Pass --project <id|slug> or run `hypotenuse project use <id|slug>`.");
3759
3770
  }
3760
3771
  }
3761
3772
  function contextFor(command) {
@@ -13552,6 +13563,30 @@ function registerSessionCommands(program) {
13552
13563
  });
13553
13564
  }
13554
13565
 
13566
+ // src/commands/skill.ts
13567
+ import { existsSync as existsSync21, readFileSync as readFileSync12 } from "fs";
13568
+ import { join as join13 } from "path";
13569
+ var SKILL_FILE = "hypotenuse.md";
13570
+ async function readSkill() {
13571
+ const embedded = Bun.embeddedFiles.find((file) => file.name === SKILL_FILE);
13572
+ if (embedded)
13573
+ return embedded.text();
13574
+ for (const up of [[".."], ["..", ".."]]) {
13575
+ const path = join13(import.meta.dir, ...up, "skills", SKILL_FILE);
13576
+ if (existsSync21(path))
13577
+ return readFileSync12(path, "utf8");
13578
+ }
13579
+ throw new Error(`This install has no skills/${SKILL_FILE}; reinstall hypotenuse.`);
13580
+ }
13581
+ function registerSkillCommand(program) {
13582
+ program.command("skill").description("Print the agent skill for using this CLI (save it as SKILL.md)").action(async function() {
13583
+ await runCommand(this, async (ctx) => {
13584
+ const skill = await readSkill();
13585
+ emit(ctx, { skill }, () => skill.trimEnd());
13586
+ });
13587
+ });
13588
+ }
13589
+
13555
13590
  // src/commands/tag.ts
13556
13591
  function registerTagCommands(program) {
13557
13592
  const tag = program.command("tag").description("The selected project's permission tags");
@@ -14048,6 +14083,7 @@ function buildProgram() {
14048
14083
  registerServiceCommands(program);
14049
14084
  registerDoctorCommand(program);
14050
14085
  registerCheckUpdateCommand(program);
14086
+ registerSkillCommand(program);
14051
14087
  registerUpgradeCommand(program);
14052
14088
  registerMcpCommand(program);
14053
14089
  return program;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcadeai/hypotenuse",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Hypotenuse — run coding agents on your machine for Linear agent sessions",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -34,7 +34,7 @@
34
34
  "lint": "tsc && biome check .",
35
35
  "format": "tsc && biome check --write .",
36
36
  "bundle": "bun build ./src/cli.ts --target bun --packages external --outfile dist/hypotenuse.js",
37
- "build": "bun build --compile --minify --sourcemap ./src/cli.ts --outfile dist/hypotenuse",
37
+ "build": "bun build --compile --minify --sourcemap ./src/cli.ts ./skills/hypotenuse.md --loader .md:file --asset-naming='[name].[ext]' --outfile dist/hypotenuse",
38
38
  "prepack": "bun run bundle"
39
39
  },
40
40
  "dependencies": {
@@ -17,7 +17,7 @@ server. It calls the same HTTP actions the dashboard does, as the person who sig
17
17
  - Lists take `--page` and `--limit` (default 25) and answer a
18
18
  `pagination: { page, limit, total, pages }` envelope.
19
19
  - Project-scoped commands act on `--project <id|slug>`, else `HYPOTENUSE_PROJECT`, else the project
20
- chosen with `hypotenuse project use`.
20
+ chosen with `hypotenuse project use`, else the person's only project when they are in just one.
21
21
  - The server is `--url`, else `HYPOTENUSE_URL`, else wherever `login` last signed in.
22
22
  - `HYPOTENUSE_NO_UPDATE_CHECK=1` turns off the background update notice.
23
23
 
@@ -48,6 +48,7 @@ server. It calls the same HTTP actions the dashboard does, as the person who sig
48
48
  | `hypotenuse doctor [--agent <id>] [--offline]` | A checklist of this machine's runner setup — version, tools, config, credentials, server and token, daemon and service, agents, repositories, disk — exit 1 when a check fails. `--agent <id>` starts that agent, runs the ACP `initialize` handshake, and opens a session — a failure names `hypotenuse agents login <id>`. |
49
49
  | `hypotenuse mcp --session <id> --nonce <n>` | Hidden: the stdio MCP server the daemon hands a coding agent for one turn — the Linear tools scoped to that session. Not for running by hand. |
50
50
  | `hypotenuse check-update` | Whether a newer release exists, with its changelog. |
51
+ | `hypotenuse skill` | Print this skill, the same text on every install (npm or binary); `--json` wraps it as `{ skill }`. |
51
52
  | `hypotenuse upgrade [--no-restart]` | Upgrade in place, by however it was installed (npm, bun, or binary), then drain and restart a running daemon on the new version. |
52
53
 
53
54
  ## Examples