cloudhop 1.2.0 → 1.2.1
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/dist/cli.js +42 -8
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -8031,7 +8031,11 @@ ${result.stderr}`)) {
|
|
|
8031
8031
|
* A URL that opens the web console as the alias, signing in first if the
|
|
8032
8032
|
* session expired. The URL is a short-lived secret: open it, never print it.
|
|
8033
8033
|
*/
|
|
8034
|
-
async consoleUrl(name, {
|
|
8034
|
+
async consoleUrl(name, {
|
|
8035
|
+
service,
|
|
8036
|
+
region,
|
|
8037
|
+
interactive: interactive2 = true
|
|
8038
|
+
} = {}) {
|
|
8035
8039
|
const resolved = await this.usableAlias(name, region ? { region } : {});
|
|
8036
8040
|
const provider = this.provider(resolved.source.provider);
|
|
8037
8041
|
if (!provider.consoleUrl) {
|
|
@@ -8047,7 +8051,7 @@ ${result.stderr}`)) {
|
|
|
8047
8051
|
"Examples: s3, ec2, lambda, cloudwatch."
|
|
8048
8052
|
);
|
|
8049
8053
|
}
|
|
8050
|
-
await this.ensureSession(resolved.source.id);
|
|
8054
|
+
await this.ensureSession(resolved.source.id, { interactive: interactive2 });
|
|
8051
8055
|
return provider.consoleUrl(resolved, service);
|
|
8052
8056
|
}
|
|
8053
8057
|
/**
|
|
@@ -8349,6 +8353,35 @@ function createTools(app) {
|
|
|
8349
8353
|
};
|
|
8350
8354
|
}
|
|
8351
8355
|
},
|
|
8356
|
+
{
|
|
8357
|
+
name: "open_console",
|
|
8358
|
+
title: "Open the cloud console",
|
|
8359
|
+
description: "Opens the cloud's web console in the user's browser as the alias, already signed in, optionally on one service (AWS: s3, ec2, lambda, cloudwatch...). Returns how the user got in, never the sign-in URL. Use it when the user wants to see something in the console. Never opens a browser to sign in: an expired session returns LOGIN_REQUIRED.",
|
|
8360
|
+
inputSchema: {
|
|
8361
|
+
type: "object",
|
|
8362
|
+
properties: {
|
|
8363
|
+
...aliasInput,
|
|
8364
|
+
service: { type: "string", description: 'Optional service page, e.g. "s3" or "ec2".' }
|
|
8365
|
+
},
|
|
8366
|
+
required: ["alias"],
|
|
8367
|
+
additionalProperties: false
|
|
8368
|
+
},
|
|
8369
|
+
annotations: {
|
|
8370
|
+
readOnlyHint: false,
|
|
8371
|
+
destructiveHint: false,
|
|
8372
|
+
idempotentHint: true,
|
|
8373
|
+
openWorldHint: true
|
|
8374
|
+
},
|
|
8375
|
+
run: async (args) => {
|
|
8376
|
+
const alias = text(args, "alias");
|
|
8377
|
+
const service = typeof args.service === "string" && args.service.trim() ? args.service.trim() : void 0;
|
|
8378
|
+
const via = await app.openConsole(alias, {
|
|
8379
|
+
...service ? { service } : {},
|
|
8380
|
+
interactive: false
|
|
8381
|
+
});
|
|
8382
|
+
return { alias, opened: true, via };
|
|
8383
|
+
}
|
|
8384
|
+
},
|
|
8352
8385
|
{
|
|
8353
8386
|
name: "login",
|
|
8354
8387
|
title: "Sign in to a source",
|
|
@@ -8445,6 +8478,7 @@ function createTools(app) {
|
|
|
8445
8478
|
var MCP_INSTRUCTIONS = `cloudhop gives each cloud account + role + region a short alias and signs the user in only when a session expired.
|
|
8446
8479
|
Before the first cloud operation in a conversation: call list_aliases, show the user the aliases (name, account/role, region) and ask which one to use. Never guess the alias.
|
|
8447
8480
|
Use run_cloud_cli for cloud CLI commands, never --profile. Read-only commands may run once the alias is chosen; before anything that creates, changes or deletes resources, show the alias, account, region and exact command, and wait for the user's explicit OK. Aliases with prod: true are production: run_cloud_cli refuses changes there until the user approves and you pass confirm_production: true.
|
|
8481
|
+
To show the user something in the web console, call open_console (it opens their browser, already signed in).
|
|
8448
8482
|
If a tool returns LOGIN_REQUIRED or alias_status says browser-sign-in: tell the user their browser will open, then call login (it waits up to 5 minutes for them to approve). Never print or ask for credentials.`;
|
|
8449
8483
|
var SUPPORTED_VERSIONS = ["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05"];
|
|
8450
8484
|
function serveMcp({
|
|
@@ -11679,7 +11713,7 @@ import { mkdir as mkdir2, readFile as readFile2, rename as rename2, rm as rm2, r
|
|
|
11679
11713
|
import { dirname as dirname2, join as join4 } from "path";
|
|
11680
11714
|
|
|
11681
11715
|
// ../assistants/src/assets/skill.md
|
|
11682
|
-
var skill_default = "---\nname: cloudhop\ndescription: Run AWS CLI commands and other cloud tools as a specific account, role and region through cloudhop aliases (the `hop` and `cloudhop` commands). Use whenever the user asks to do anything in their AWS accounts, inspect or change cloud resources, run aws/terraform/cdk against an account, list their cloud accounts or aliases, or mentions hop or cloudhop.\n---\n\n# Working with cloud accounts through cloudhop\n\nThe user manages their cloud access with **cloudhop**. Each **alias** (for\nexample `acme-dev`) points to one account, one role and one region. cloudhop\nsigns the user in through their browser only when a session has expired. There\nare no access keys: never ask for, create, print or store credentials.\n\n## 1. Pick the alias with the user, every time\n\nBefore the first cloud operation in a conversation:\n\n1. List the aliases. Use the `list_aliases` tool if the cloudhop MCP server is\n connected; otherwise run `cloudhop ls --json`.\n2. Show the user the options (alias, account / role, region) and **ask which\n one to use**. Don't guess, even if one name looks right, and don't pick\n one just because there is only one: confirm it.\n3. Use that alias for the rest of the conversation. Ask again if the user\n moves to another environment, account or task.\n\n## 2. Check the session before running anything\n\nRun `cloudhop status <alias> --json` (or the `alias_status` tool) and read\n`next`:\n\n| `next` | Meaning | What to do |\n| ----------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `ready` | Session valid | Go ahead |\n| `silent-renewal` | Expired but renewable without the user | Go ahead; cloudhop renews it |\n| `browser-sign-in` | The user must sign in | Tell the user their browser will open and they need to approve, then run `cloudhop login <source>` (or the `login` tool) and wait up to 5 minutes |\n| `unknown` | Managed by the cloud CLI (personal accounts) | Go ahead; if it fails, run `cloudhop login <source>` |\n\nDon't start several cloud commands in parallel while a sign-in is pending.\n\n## 3. Run commands through the alias\n\n- **AWS CLI**: `hop <alias> <aws arguments>`, e.g. `hop acme-dev s3 ls`.\n It is exactly `aws <arguments>` with the alias' account, role and region.\n Never add `--profile`. Use `--region <r>` only to override the region once.\n With the MCP server, use `run_cloud_cli` with `args` (no program name).\n- **Who am I**: `hop <alias>` with no arguments (or the `whoami` tool).\n- **The same command in several aliases** (after the user chose them):\n `cloudhop each a,b,c --yes -- <aws arguments>`; add `--json` to parse the\n results.\n- **The AWS web console**: `cloudhop console <alias> [service]` opens it in
|
|
11716
|
+
var skill_default = "---\nname: cloudhop\ndescription: Run AWS CLI commands and other cloud tools as a specific account, role and region through cloudhop aliases (the `hop` and `cloudhop` commands). Use whenever the user asks to do anything in their AWS accounts, inspect or change cloud resources, run aws/terraform/cdk against an account, list their cloud accounts or aliases, or mentions hop or cloudhop.\n---\n\n# Working with cloud accounts through cloudhop\n\nThe user manages their cloud access with **cloudhop**. Each **alias** (for\nexample `acme-dev`) points to one account, one role and one region. cloudhop\nsigns the user in through their browser only when a session has expired. There\nare no access keys: never ask for, create, print or store credentials.\n\n## 1. Pick the alias with the user, every time\n\nBefore the first cloud operation in a conversation:\n\n1. List the aliases. Use the `list_aliases` tool if the cloudhop MCP server is\n connected; otherwise run `cloudhop ls --json`.\n2. Show the user the options (alias, account / role, region) and **ask which\n one to use**. Don't guess, even if one name looks right, and don't pick\n one just because there is only one: confirm it.\n3. Use that alias for the rest of the conversation. Ask again if the user\n moves to another environment, account or task.\n\n## 2. Check the session before running anything\n\nRun `cloudhop status <alias> --json` (or the `alias_status` tool) and read\n`next`:\n\n| `next` | Meaning | What to do |\n| ----------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `ready` | Session valid | Go ahead |\n| `silent-renewal` | Expired but renewable without the user | Go ahead; cloudhop renews it |\n| `browser-sign-in` | The user must sign in | Tell the user their browser will open and they need to approve, then run `cloudhop login <source>` (or the `login` tool) and wait up to 5 minutes |\n| `unknown` | Managed by the cloud CLI (personal accounts) | Go ahead; if it fails, run `cloudhop login <source>` |\n\nDon't start several cloud commands in parallel while a sign-in is pending.\n\n## 3. Run commands through the alias\n\n- **AWS CLI**: `hop <alias> <aws arguments>`, e.g. `hop acme-dev s3 ls`.\n It is exactly `aws <arguments>` with the alias' account, role and region.\n Never add `--profile`. Use `--region <r>` only to override the region once.\n With the MCP server, use `run_cloud_cli` with `args` (no program name).\n- **Who am I**: `hop <alias>` with no arguments (or the `whoami` tool).\n- **The same command in several aliases** (after the user chose them):\n `cloudhop each a,b,c --yes -- <aws arguments>`; add `--json` to parse the\n results.\n- **The AWS web console**: `cloudhop console <alias> [service]` (or the\n `open_console` tool) opens it in the user's browser, already signed in.\n Never try to print or fetch its URL.\n- **Always name the alias.** Never run the interactive forms meant for a\n person at a terminal: `hop` or `hop -` without an alias, `cloudhop console`\n without an alias, `cloudhop use` (it only changes an interactive shell),\n `cloudhop setup`, or `cloudhop add`/`alias` without flags. Nobody can answer\n their prompts in your terminal.\n- **Other tools** (Terraform, CDK, SDK scripts):\n `cloudhop exec <alias> -- <command>`, e.g.\n `cloudhop exec acme-dev -- terraform plan`.\n- Prefer `--output json` and `--query` to keep output small.\n- Don't export `AWS_PROFILE`, `AWS_ACCESS_KEY_ID` or similar variables, don't\n run commands that print credentials (`env`, `printenv`, `export-credentials`)\n and never edit `~/.aws/config`, `~/.aws/credentials` or cloudhop's own files.\n\n## 4. Confirm before changing anything\n\n- Read-only commands (`list`, `describe`, `get`, `s3 ls`, `logs tail`) can run\n once the user has chosen the alias.\n- Before any command that **creates, changes, deletes or costs money**, show\n the alias, account, region and the exact command, and wait for the user's\n explicit \"yes\". One confirmation covers one command, not a series.\n- **Production aliases** have `\"prod\": true` in `cloudhop ls --json` (and\n `PROD` in `cloudhop ls`). Confirm every change there and suggest a dry run\n (`--dryrun`, `terraform plan`) first. cloudhop enforces it: without a\n terminal, `hop`/`cloudhop exec` refuse changes on production with\n `PROD_CONFIRMATION_REQUIRED`. After the user explicitly approves the exact\n command, rerun it with `CLOUDHOP_CONFIRM_PROD=1` in that command's\n environment (with MCP: `confirm_production: true`). Never set it on your own.\n- Treat aliases or accounts that merely look like production (`prd`, `live`)\n the same way, even if they are not marked.\n- Don't change cloudhop itself (`cloudhop add`, `rm`, `mv`, `region`, `prod`,\n `team import`, `agent`, `login` for another source) unless the user asked\n for it. Never unmark a production alias to get around a confirmation.\n\n## 5. When something goes wrong\n\n| You see | Do this |\n| --------------------------------------------------- | ------------------------------------------------------------------------------ |\n| \"Opening your browser to log in\" | Tell the user to approve in the browser; the command continues by itself |\n| The command was cut off while waiting for a sign-in | Run `cloudhop login <source>` with a timeout of at least 5 minutes, then retry |\n| `LOGIN_REQUIRED` | Same as `browser-sign-in` above |\n| No browser on this machine (remote, container) | Run `cloudhop login <source> --device-code` and show the user the URL and code |\n| `Alias \"x\" not found` | Run `cloudhop ls` and ask the user again |\n| AWS CLI missing or too old | Suggest `cloudhop doctor`; don't install anything without asking |\n| `AccessDenied` | The role lacks permission: tell the user; don't try other aliases on your own |\n\nMore: https://dayepesb.github.io/cloudhop/guides/hop-like-aws/\n";
|
|
11683
11717
|
|
|
11684
11718
|
// ../assistants/src/targets.ts
|
|
11685
11719
|
import { join as join3 } from "path";
|
|
@@ -14670,7 +14704,7 @@ function startUpdateCheck(configDir, current) {
|
|
|
14670
14704
|
}
|
|
14671
14705
|
|
|
14672
14706
|
// src/cli.ts
|
|
14673
|
-
var HELP = `cloudhop ${"1.2.
|
|
14707
|
+
var HELP = `cloudhop ${"1.2.1"}
|
|
14674
14708
|
Hop between cloud accounts, roles and regions with one command.
|
|
14675
14709
|
|
|
14676
14710
|
Usage
|
|
@@ -14750,7 +14784,7 @@ async function main(argv) {
|
|
|
14750
14784
|
return 0;
|
|
14751
14785
|
}
|
|
14752
14786
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
14753
|
-
console.log("1.2.
|
|
14787
|
+
console.log("1.2.1");
|
|
14754
14788
|
return 0;
|
|
14755
14789
|
}
|
|
14756
14790
|
const app = createApp();
|
|
@@ -14764,12 +14798,12 @@ async function main(argv) {
|
|
|
14764
14798
|
return 0;
|
|
14765
14799
|
}
|
|
14766
14800
|
if (command === "mcp") {
|
|
14767
|
-
await serveMcp({ app, version: "1.2.
|
|
14801
|
+
await serveMcp({ app, version: "1.2.1" });
|
|
14768
14802
|
return 0;
|
|
14769
14803
|
}
|
|
14770
|
-
const assistants = createAssistants("1.2.
|
|
14804
|
+
const assistants = createAssistants("1.2.1");
|
|
14771
14805
|
await refreshAssistantSkills(assistants, command);
|
|
14772
|
-
const finishUpdateCheck = startUpdateCheck(defaultConfigDir(), "1.2.
|
|
14806
|
+
const finishUpdateCheck = startUpdateCheck(defaultConfigDir(), "1.2.1");
|
|
14773
14807
|
try {
|
|
14774
14808
|
return await dispatch(app, assistants, command, args, local);
|
|
14775
14809
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudhop",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Every cloud account, one short alias away. Sign in to AWS SSO portals and personal accounts once, hop between accounts, roles and regions with one command. No access keys.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@cloudhop/adapters-node": "0.0.0",
|
|
47
47
|
"@cloudhop/assistants": "0.0.0",
|
|
48
48
|
"@cloudhop/core": "0.0.0",
|
|
49
|
-
"@cloudhop/ui": "0.0.0",
|
|
50
49
|
"@cloudhop/mcp": "0.0.0",
|
|
50
|
+
"@cloudhop/ui": "0.0.0",
|
|
51
51
|
"@cloudhop/provider-aws": "0.0.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|