registry  /  @gallopsystems/agent-skills  /  1.23.0

@gallopsystems/agent-skills@1.23.0

Gallop Systems agent skills, symlinked into .claude/skills (Claude Code) and .agents/skills (Codex) on install.

AI Security Review

scanned 4d ago · by lpm-firewall-ai

No confirmed malicious attack surface. The install hook performs documented package-aligned symlink setup for agent skill files; network access is limited to a user-invoked Linear CLI.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm/yarn install for symlink setup; explicit linear.mjs command for Linear API calls
Impact
Installs package-provided skills into local agent skill directories; user-invoked CLI can read LINEAR_API_KEY and write Linear workspace config.
Mechanism
documented agent-skill symlink installer and optional Linear GraphQL CLI
Rationale
The risky primitives are real, especially the postinstall write into AI-agent skill directories, but they are the package's stated purpose, bounded to symlinks into its own files, and documented for consumers. Source inspection did not find stealth, credential theft, persistence beyond managed symlinks, or unaligned network behavior.
Evidence
package.jsonscripts/link-skills.mjsREADME.mdplugins/linear/skills/linear/bin/linear.mjsplugins/linear/skills/linear/SKILL.md.claude/skills.agents/skills.claude/commands~/.config/linctl/workspace.json
Network endpoints2
api.linear.app/graphqllinear.app/settings/account/security

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with medium false-positive risk.
Evidence for block
  • package.json runs postinstall: node scripts/link-skills.mjs
  • scripts/link-skills.mjs creates symlinks under .claude/skills, .agents/skills, and .claude/commands
  • plugins/linear/skills/linear/bin/linear.mjs can POST to https://api.linear.app/graphql using LINEAR_API_KEY when invoked
Evidence against
  • README.md documents the npm install symlink behavior and generated paths
  • scripts/link-skills.mjs only symlinks package skill/command files and avoids clobbering real user-authored paths
  • scripts/link-skills.mjs removes only symlinks whose real target is inside this package
  • Linear API access is a user-invoked CLI workflow, not install-time execution
  • No credential harvesting, exfiltration endpoint, child_process use, eval, native binary loading, or destructive install behavior found
Behavioral surface
Source
EnvironmentVarsFilesystemNetwork
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 25 file(s), 157 KB of source, external domains: api.linear.app, linear.app

Source & flagged code

3 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/link-skills.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
plugins/linear/skills/linear/bin/linear.mjsView file
11// Recommended: add `export LINEAR_API_KEY=lin_api_xxx` to ~/.zshenv (zsh) or L12: // ~/.bashrc (bash) so it's available in every shell — including the L13: // non-interactive ones spawned by Claude Code. ... L23: import { createInterface } from "node:readline/promises"; L24: import { stdin as input, stdout as output } from "node:process"; L25: L26: const API_URL = "https://api.linear.app/graphql"; L27: const API_KEY = process.env.LINEAR_API_KEY; L28: const WORKSPACE_FILE = L29: process.env.LINCTL_WORKSPACE_FILE || L30: join(homedir(), ".config", "linctl", "workspace.json"); L31:
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

plugins/linear/skills/linear/bin/linear.mjsView on unpkg · L11
scripts/link-skills.mjsView file
5Install-time AI-agent control hijack evidence: L5: // L6: // skills -> .claude/skills/<name> (Claude Code; a dir with SKILL.md) L7: // skills -> .agents/skills/<name> (Codex; same SKILL.md format) L8: // commands -> .claude/commands/<rel>.md (Claude Code only; a .md under commands/) L9: // ... L28: const UNLINK = process.argv.includes('--unlink') L29: const SKIP_DIRS = new Set(['node_modules', '.git', '.claude']) L30: ... L44: // or the workspace root in a monorepo, which is exactly where the shared L45: // .claude directory should live. Fall back to climbing out of node_modules. L46: function resolveProjectRoot() { ... L181: // Nothing to link: only tidy up previously-created links (if the dir exists), Payload evidence from plugins/contribute-skill/skills/contribute-skill/SKILL.md: L9: You are turning something learned in this session into a PR against L10: https://github.com/gallop-systems/agent-skills, the public repo behind the L11: installed skills.
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/link-skills.mjsView on unpkg · L5

Findings

1 Critical1 High4 Medium5 Low
CriticalAi Agent Control Hijackscripts/link-skills.mjs
HighInstall Time Lifecycle Scriptspackage.json
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistenceplugins/linear/skills/linear/bin/linear.mjs
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License