git-structured

SKILL.md

Git Structured Skill

Perform safe, structured Git operations with JSON output. Provides read-only and write operations with safety checks.

When to Use

USE this skill when:

  • Checking repository status
  • Making commits
  • Managing branches
  • Viewing history and diffs
  • Stash operations

DON'T use this skill when:

  • Destructive operations without backup
  • Force pushing to protected branches
  • Rewriting history on shared branches

Usage

Status

const { git } = require('/job/.pi/skills/git-structured/git.js');

const status = await git('status');
console.log(status);
// {
//   branch: "main",
//   staged: [{ path: "src/index.js", status: "M" }],
//   unstaged: [],
//   untracked: ["new-file.md"],
//   clean: false
// }

Diff

const diff = await git('diff', {
  cached: false,
  files: "src/"
});
console.log(diff);
// {
//   files: [{
//     path: "src/index.js",
//     hunks: [
//       { start: 10, lines: "+ console.log('new');" }
//     ]
//   }]
// }

Log

const log = await git('log', {
  maxEntries: 10,
  format: "short"
});
console.log(log);
// [
//   { hash: "abc123", author: "John", date: "2026-02-25", message: "Fix bug" },
//   ...
// ]

Add & Commit

await git('add', { files: ["src/index.js", "src/utils.js"] });

const commit = await git('commit', {
  message: "Add new feature",
  all: false // use -a flag
});
console.log(commit);
// { hash: "def456", changedFiles: 2 }

Branch

// List branches
const branches = await git('branch');
// { current: "main", branches: ["main", "feature", "bugfix"] }

// Create branch
await git('checkout', {  
  newBranch: "feature/new-ui",
  startPoint: "main"
});

// Switch branch
await git('checkout', { branch: "main" });

Push & Pull

const push = await git('push', {
  remote: "origin",
  branch: "feature",
  setUpstream: true
});

const pull = await git('pull', {
  remote: "origin",
  rebase: false
});

Stash

await git('stash', { action: 'push', message: 'WIP' });
await git('stash', { action: 'list' });
await git('stash', { action: 'pop', index: 0 });

API

git(operation, options = {})

Operations: status, diff, log, add, commit, branch, checkout, push, pull, stash, reset, revert

Options vary by operation:

// Diff options
{ cached: true, files: "src/" }

// Commit options  
{ message: "msg", all: true, amend: false }

// Checkout options
{ branch: "main" } or { newBranch: "feature", startPoint: "main" }

Safety Features

Injection Prevention

  • Argument sanitization
  • No shell expansion
  • Blocked dangerous flags (--exec=, --upload-pack=)

Write Access Control

  • Configurable autonomy levels
  • Approval required for destructive operations
  • Audit logging

Protected Branches

const PROTECTED = ['main', 'master', 'develop', 'release/*'];

if (PROTECTED.some(p => branchMatches(p, targetBranch))) {
  throw new Error('Cannot force-push to protected branch');
}

Examples

Feature Branch Workflow

// Check current state
const status = await git('status');
if (!status.clean) {
  await git('stash', { action: 'push', message: 'WIP before feature' });
}

// Create feature branch
await git('checkout', {
  newBranch: 'feature/user-auth',
  startPoint: 'main'
});

// Make changes, then commit
await git('add', { files: ['src/auth.js'] });
await git('commit', { message: 'Add authentication module' });

// Push feature branch
await git('push', {
  remote: 'origin',
  branch: 'feature/user-auth',
  setUpstream: true
});

Review Changes

// Get diff of staged changes
const stagedDiff = await git('diff', { cached: true });

// Get log of recent commits
const recentLog = await git('log', { maxEntries: 5 });

// Check if branch is up to date
await git('fetch', { remote: 'origin' });
const behindAhead = await git('rev-list', {
  leftRight: true,
  range: 'HEAD...origin/main'
});

Undo Changes

// Unstage file
await git('reset', { file: 'src/index.js' });

// Discard working changes
await git('checkout', { file: 'src/index.js' });

// Amend last commit
await git('commit', { amend: true, message: 'Updated message' });

// Soft reset (keep changes staged)
await git('reset', { to: 'HEAD~1', soft: true });

// Hard reset (dangerous!)
await git('reset', { to: 'HEAD~1', hard: true, approved: true });

Error Handling

try {
  await git('commit', { message: '' });
} catch (error) {
  if (error.code === 'EMPTY_COMMIT') {
    console.log('Cannot create empty commit');
  } else if (error.code === 'CONFLICT') {
    console.log('Merge conflict detected');
  } else if (error.code === 'UNCOMMITTED_CHANGES') {
    console.log('Stash or commit changes first');
  }
}

Bash CLI

# Status
node /job/.pi/skills/git-structured/git.js --op status

# Diff
node /job/.pi/skills/git-structured/git.js --op diff --cached

# Commit
node /job/.pi/skills/git-structured/git.js \
  --op commit \
  --message "Add feature" \
  --files "src/*.js"

# Branch
node /job/.pi/skills/git-structured/git.js \
  --op checkout \
  --new-branch feature/test \
  --start-point main

Output Formats

All operations return structured JSON for easy parsing:

Status:

{
  "branch": "main",
  "staged": [{"path": "file.js", "status": "M"}],
  "unstaged": [],
  "untracked": [],
  "clean": false
}

Diff:

{
  "files": [
    {
      "path": "src/index.js",
      "hunks": [
        {
          "start": 10,
          "changes": [
            {"type": "add", "line": "+ new code"},
            {"type": "remove", "line": "- old code"}
          ]
        }
      ]
    }
  ]
}

Log:

[
  {
    "hash": "abc123def456",
    "shortHash": "abc123d",
    "author": "John Doe",
    "email": "john@example.com",
    "date": "2026-02-25T13:30:00Z",
    "message": "Add new feature"
  }
]
Weekly Installs
3
First Seen
14 days ago
Installed on
opencode3
gemini-cli3
claude-code3
github-copilot3
codex3
kimi-cli3