pr-comment
Write GitHub PR comments in Jack's voice. Use whenever writing, drafting, or posting PR comments — review feedback, thank-you…
How to load secrets and environment variables from 1Password programmatically using the official @1password/sdk (JavaScript/TypeScript). Use this skill whenever code needs to read a 1Password secret, resolve an op:// reference, fetch many secrets at once, discover the
Claude Code
$ npx -y skills add MadAppGang/claudish --skill 1password-sdk --agent claude-code
Codex
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a codex -y
Cursor
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a cursor -y
Gemini CLI
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a gemini-cli -y
GitHub Copilot
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a github-copilot -y
OpenCode
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a opencode -y
Windsurf
$ npx skills add MadAppGang/claudish --skill 1password-sdk -a windsurf -y
name: 1password-sdk description: >- How to load secrets and environment variables from 1Password programmatically using the official @1password/sdk (JavaScript/TypeScript). Use this skill whenever code needs to read a 1Password secret, resolve an op:// reference, fetch many secrets at once, discover the fields/sections of a 1Password item (e.g. to import API keys), or read a 1Password Environment — even if the user doesn't name the SDK explicitly. Triggers on: "@1password/sdk", "op://", "OP_SERVICE_ACCOUNT_TOKEN", "DesktopAuth", "resolve a secret from 1Password", "1Password service account", "1Password Environments", "fetch API keys from 1Password", or wiring 1Password into a Node/Bun/TypeScript app. Prefer this in-process SDK over shelling out to the `op` CLI unless the task specifically needs the user's interactive `op signin` session.
The official `@1password/sdk` reads secrets from 1Password **in-process** — no `op` CLI subprocess, no `op signin`. It authenticates directly (service-account token or desktop biometric) and resolves `op://vault/item/field` references to their values. Use it whenever an app needs to pull credentials at runtime.
**Why prefer the SDK over the `op` CLI:** one auth model, one authorization event (the CLI + SDK each prompt separately, so mixing them double-prompts), no external binary to depend on, batched resolution, and structured per-reference errors. The CLI's only edge is using a user's existing interactive `op signin` session — the SDK cannot do that; it needs its own auth (below).
bun add @1password/sdk # or npm install @1password/sdk
For **1Password Environments** (the `environments` API), the stable release does NOT include it — you need the beta:
bun add @1password/sdk@0.4.1-beta.1
Every operation goes through a `client`. `integrationName` and `integrationVersion` are **required** (they identify your app in 1Password's audit log — note they do NOT change the desktop authorization prompt, which always shows the calling process).
import { createClient, DesktopAuth } from "@1password/sdk";
// Service account — headless / CI / servers. No prompt, no desktop app.
const client = await createClient({
auth: process.env.OP_SERVICE_ACCOUNT_TOKEN!,
integrationName: "my-app",
integrationVersion: "1.0.0",
});
// OR Desktop app — laptops, biometric (Touch ID). Prompts to authorize.
const client = await createClient({
auth: new DesktopAuth("my-account-name"), // account name or UUID
integrationName: "my-app",
integrationVersion: "1.0.0",
});**Choosing auth:**
vaults** (shared vaults only). The token is itself a full-decryption secret — never log or persist it.
for Touch ID. Requires the desktop app's SDK integration to be enabled.
`createClient`, and every method below, are **async** — `await` them.
// One secret:
const apiKey = await client.secrets.resolve("op://Vault/Item/credential");
// Many at once (one round-trip, per-reference errors — prefer this for >1):
const res = await client.secrets.resolveAll([
"op://Vault/Item/username",
"op://Vault/Item/password",
]);
for (const [ref, response] of Object.entries(res.individualResponses)) {
if (response.error) { console.error(`failed ${ref}:`, response.error); continue; }
console.log(response.content.secret); // the value
}Keep resolved secrets **in-memory only** — never write them to disk or logs.
→ Full resolution details (reference syntax, OTP/SSH query params, field types, validating a reference, the response shapes): **`references/resolve-secrets.md`**
A named set of env vars managed in the desktop app, addressed by an opaque ID:
const res = await client.environments.getVariables("<environment-id>");
for (const v of res.variables) {
process.env[v.name] = v.value; // { name, value, masked }
}Requires the **beta SDK** and the Environment **ID** (copied from the desktop app: Developer → View Environments → Manage environment → Copy environment ID).
→ Details + the response shape: **`references/environments.md`**
When you want to pull *many* fields from one item — e.g. an item whose fields are each named after an env var (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, …) — you must discover them first. `items.get()` takes **IDs, not names**, so the flow is:
// 1. name → vault ID
const vaults = await client.vaults.list();
const vaultId = [...vaults].find(v => v.title === "Jack")!.id;
// 2. name → item ID
const items = await client.items.list(vaultId);
const itemId = items.find(i => i.title === "API keys")!.id;
// 3. fetch the item → fields + sections
const item = await client.items.get(vaultId, itemId);
for (const f of item.fields) {
// f.title (label), f.sectionId, f.fieldType, f.value
// join f.sectionId → item.sections[].title for the section label
}**Note:** `items.get()` returns every field's decrypted `value` — there is no "names without values" mode. This is the same as the `op` CLI's `op item get` (both decrypt in memory; neither writes to disk), so it's not a security regression — just don't persist what you don't use.
→ Full glob/discovery recipe (name→ID resolution, section-label joins, building `op://` references, filtering by a glob): **`references/glob-discovery.md`**
| Need | SDK | Notes | |------|-----|-------| | Resolve `op://` (single + batch) | ✅ | `secrets.resolve` / `resolveAll` | | Validate a reference syntactically | ✅ | `Secrets.validateSecretReference` (static, no network) | | List vaults / items, get it
Claude Code. Any Model. The most powerful AI coding agent now speaks every language.
Write GitHub PR comments in Jack's voice. Use whenever writing, drafting, or posting PR comments — review feedback, thank-you…
CRITICAL - Guide for using Claudish CLI ONLY through sub-agents to run Claude Code with any AI model (OpenRouter, Gemini, OpenAI,…
Command-line interface for AdGuard Home - Network-wide ad blocking and DNS management via AdGuard Home REST API. Designed for AI…
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a…
Install, configure, or troubleshoot Oh My Posh/ohmyposh: shell init, themes, segments, Nerd Font icons, and prompt setup on…
Set up a new integration, connector, or CLI binding for any API. Wrap or generate a ship-ready Go CLI from an OpenAPI, HAR, or…