SLOPSHOPPER

cmdHistory

/cmdHistory lists PowerShell (PSReadLine) history in a pane and puts the picked command in the prompt as a ! shell command.

newpanecommandtoast
★ 1v0.1.1no licenseupdated 2026-10-11ntaksh42/dotfiles/claude/mods/cmdHistory
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · cmdHistory
│ ┃ cmd-history ✕ › fix the failing auth test and add an audit log call │ ┃ > : 絞り込む語(空白区切り) ⏎ 先頭を選ぶ │ ┃ 一致する履歴がありません ⏺ Read(src/auth.ts) │ ⎿ Read 6 lines │ ⏺ Update(src/auth.ts) │ ⎿ Added 2 lines, removed 1 line │ ⏺ Bash(bun test) │ ⎿ 3 pass, 1 fail │ │ ● Done. refresh now rejects expired claims and logs an audit event. │ │ ✻ Worked for 42s · done 4:20 PM │ │ › /cmdHistory │ ⎿ cmdHistory: PowerShell の履歴が見つかりませんでした。 │ │ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Pane · cmd-history
> : 絞り込む語(空白区切り) ⏎ 先頭を選ぶ 一致する履歴がありません
README

env - Claude Code 環境設定

Windows 環境の Claude Code dotfiles(hooks・skills・settings)を一元管理するリポジトリ。

リポジトリ構成

claude/
  install.ps1              インストーラ(CLAUDE.md・settings.json を ~/.claude に配置)
  settings.template.json   settings.json のテンプレート
  mods/                    Claude Code プラグイン(dotfiles-mods マーケットプレイス)
    dotfiles/              自作の skills・hooks をまとめた plugin
app-settings/              アプリ設定ファイルのバックアップ
tools/                     汎用 PowerShell ユーティリティ

PowerShell コマンド

app-settings/pwsh/Microsoft.PowerShell_profile.ps1 は基本ヘルパー・エイリアスと Update-Profile を持つローダーで、機能本体は app-settings/pwsh/profile.d/ に 分割しています(navigation / git / vs-build / integrations / ai-cli / devtools-catalog / devtools / extra-tools / windows-settings / psreadline / help)。 読み込み順は profile.d/manifest.txt が決めます。新しいファイルを足すときは profile.d/ に置いて manifest.txt に 1 行追加します。配置時はローダーと profile.d/ の両方が必要です。

profile は現在読み込んでいるプロファイルを編集し、reload は再読み込みします。 Update-Profile は GitHub の main からローダーと profile.d/ 一式を取得し、構文検証・ 上書き確認・バックアップ後に更新するため、未公開のローカル変更は反映しません。

コマンド一覧は phelp(例: phelp git)、検索は Ctrl+G で開けます。 gl、gp、gcm、cat は標準エイリアスを置き換え、それぞれ Git log、Git push、Git commit、bat 連携として動作します。 gco の引数なし実行は git-switch と同じブランチ選択を使います。 その他の既存の短縮名も維持しています。

検証は pwsh -NoProfile -File app-settings/pwsh/tests/Invoke-AllTests.ps1 で全テストファイルを一括実行します(個別実行は各 Test-*.ps1)。

一部の端末だけに入れるアプリ

DevDeck(ntaksh42/DevDeck)と RdpManager(ntaksh42/rdp-manager)は全端末には不要なため、 Install-DevTools のカタログには入れず、専用の Install-ExtraTools で導入します。 GitHub Releases の最新インストーラを取得して実行し、導入済みで最新なら何もしません。 古い場合は更新し、実行中のアプリは終了します。

Install-ExtraTools                       # DevDeck と RdpManager の両方
Install-ExtraTools -Name DevDeck         # 指定したものだけ
Install-ExtraTools -Name RdpManager -Yes # 確認を省略

DevDeck は NSIS 版(ユーザー単位・無人)、RdpManager は MSI 版(マシン単位のため UAC が出ます)を使います。 対象を増やすときは profile.d/extra-tools.ps1 の $script:ExtraTools に 1 行足します。

Git 設定

PowerShell 7 / Git for Windows 向けの共有設定は app-settings/git/.gitconfig にあります。個人情報や署名鍵、認証 helper は 公開用の設定から分離し、~/.gitconfig.local で管理します。既存の設定が ある場合は、それをローカル設定として残してから共有設定を配置します。

# 既存の ~/.gitconfig がある場合(認証・ユーザー情報もそのまま保持)
Move-Item ~/.gitconfig ~/.gitconfig.local
Copy-Item app-settings/git/.gitconfig ~/.gitconfig

# Git を初めて設定する場合は、上の Move-Item の代わりにこちらを実行
Copy-Item app-settings/git/.gitconfig.local.example ~/.gitconfig.local
notepad ~/.gitconfig.local

delta が未導入の場合は Install-DevTools で導入できます。設定後は git config --global --list で読み込み結果を確認してください。

ステータスライン設定

claude/settings.template.json の statusLine は npx -y ccstatusline@latest を呼び出します。ccstatusline はレイアウト設定を ~/.config/ccstatusline/settings.json から読み込みます。この設定は app-settings/ccstatusline/settings.json を管理元として Install-DevTools (remote-config バックエンド)が配置・更新します。

Install-DevTools

ccstatusline はTUI上での編集で設定ファイル自身を書き換えるため、 Install-DevTools は配置済みの設定と管理元の内容が異なる場合、差分を表示した 上で上書き可否を確認します(手元での編集を誤って消さないよう、この確認は -Force を付けても省略されません)。上書き確認も含めてすべての確認に「はい」と 答える場合は Install-DevTools -Yes を使います(差分表示とバックアップは行われます)。

Install-DevTools は ~/.agents/skills/ にだけあるスキルを ~/.claude/skills/ へ移し、 元の場所にシンボリックリンクを作ります。同名の既存スキルと SKILL.md のないディレクトリは変更しません。

配置後は Claude Code を再起動すると、モデル・コンテキスト使用率・git ブランチ・ セッション使用量などの構成が反映されます。

Claude Code Mods

Install-DevTools は claude/mods/ の Mod(dotfiles、auto-session-title、toast-notify など)も導入します。 自作の skills と hooks は dotfiles plugin にまとめてあります(スキル名は dotfiles:<name>)。 dotfiles-mods マーケットプレイスが未登録なら GitHub の ntaksh42/dotfiles から登録し、 その後 claude plugin install を実行します。claude/install.ps1 がクローン先のパスで 登録済みの場合は、そのマーケットプレイスをそのまま使います。GitHub から登録する場合は、 Mod が main に取り込まれている必要があります。claude が PATH に無いとスキップされます。

Codex ステータスライン

現在は一時的に無効化中です。 Install-DevTools は Codex ステータスラインを インストールせず、導入済みの環境では %LOCALAPPDATA%\CodexStatusline\codex-wt.ps1 を codex-wt.ps1.disabled に退避します(codex は通常の Codex CLI を起動します)。 再び有効にするには、.disabled を元の名前に戻し、Install-DevTools のカタログと Disable-CodexStatusline の呼び出しを元に戻します。

有効だった頃は、下側 18% のペインにモデル、推論強度、コンテキスト、git 状態、 セッション/週次の使用量を表示していました。tools/Install-CodexStatusline.ps1 と app-settings/codex-statusline/ は再開用に残してあります。

Crit

Install-DevTools は Crit 本体と Codex 連携もインストールします。インストール時に ~/.crit.config.json の既存項目を維持しつつ、社内利用向けの安全設定として ローカルホスト限定、更新確認の無効化、Share の無効化、agent_cmd の無効化を設定します。

{
  "host": "127.0.0.1",
  "no_update_check": true,
  "share_url": "",
  "share_targets": [],
  "agent_cmd": ""
}

セットアップ手順

1. リポジトリをクローン

git clone https://github.com/ntaksh42/env.git
cd env

2. インストーラを実行

powershell.exe -ExecutionPolicy Bypass -File claude\install.ps1

インストーラが行うこと:

  • claude/CLAUDE.global.md を ~/.claude/CLAUDE.md にコピー
  • settings.template.json からパスを解決して ~/.claude/settings.json を生成

3. plugin を導入

Install-DevTools

skills・hooks・Mod を claude plugin install で導入します。

4. Claude Code を再起動

設定を反映するために Claude Code を再起動してください。


AI 向け CLI ツール

%LOCALAPPDATA%\Microsoft\WinGet\Links\ に以下のツールをインストール済みです。

  • jq v1.8.1: JSON プロセッサ。API レスポンスや設定ファイルの前処理でトークン消費を大きく抑えられます。
  • rg (ripgrep) v15.1.0: .gitignore を自動除外する高速 grep。--json 出力に対応し、多くの AI エージェントと相性が良いです。
  • yq v4.53.2: YAML / TOML / XML プロセッサ。jq 風構文で K8s や CI 設定を処理できます。

ユーティリティ

app-settings/ の設定ファイルは Install-DevTools が GitHub の main から配置します (プロファイルは Update-Profile)。実環境で変えた設定は、手でリポジトリへコピーして取り込みます。

# Windows 設定(レジストリ)を適用 (pwsh プロファイル経由)。HKLM 項目は管理者権限が必要
Set-WindowsSettings -Check    # 差分のみ表示
Set-WindowsSettings           # 適用

Orca 設定

Install-DevTools は Orca 本体も winget(StablyAI.Orca)でインストールします。 導入済みの場合はスキップします。

app-settings/orca/keybindings.json は Install-DevTools が ~/.orca/keybindings.json へ配置します。 外観・エディタ・ターミナル設定の控えは app-settings/orca/settings.json にあります。 JSON の自動読み込みには対応していないため、app-settings/orca/README.md を参照してください。

Dockyard

Install-DevTools は Dockyard の最新リリース(MSIX)も インストール・更新します(tools/Install-Dockyard.ps1)。ARM64 の PC でも x64 版を入れます。 署名証明書が未信頼の場合は Cert:\LocalMachine\TrustedPeople へ登録するため UAC の確認が出ます。 x64 版の .NET 10 Desktop Runtime が無ければ winget で入れます(ARM64 の PC では dotnet\x64 に入ります)。

Source 2 files
hooks/register.tsx 107 lines
1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4const PANE = 'cmd-history'
5const MAX_ENTRIES = 3000
6const entries = atom({ plugin: 'cmdHistory', key: 'entries' } as const, [])
7const filter = atom({ plugin: 'cmdHistory', key: 'filter' } as const, '')
8
9// PSReadLine の履歴ファイルを新しい順・重複なしの項目にする。複数行の項目は最終行以外の行末がバッククォート
10export const parseHistory = (text: string) => {
11  const items: string[] = []
12  let pending: string[] = []
13  for (const line of text.split(/\r?\n/)) {
14    if (line.endsWith('`')) {
15      pending.push(line.slice(0, -1))
16      continue
17    }
18    const item = [...pending, line].join('\n').trim()
19    pending = []
20    if (item !== '') items.push(item)
21  }
22  return [...new Set(items.reverse())].slice(0, MAX_ENTRIES)
23}
24
25// 空白区切りの語をすべて含む項目(大文字小文字は区別しない)
26export const matches = (list: readonly string[], query: string) => {
27  const words = query.toLowerCase().split(/\s+/).filter(Boolean)
28  return list.filter(item => words.every(w => item.toLowerCase().includes(w)))
29}
30
31const loadHistory = async ($: EngineInterface) => {
32  const appData = await $.env.get('APPDATA')
33  if (appData === undefined) return []
34  const path = `${appData}/Microsoft/Windows/PowerShell/PSReadLine/ConsoleHost_history.txt`
35  if (!(await $.fs.exists(path))) return []
36  return parseHistory(await $.fs.read(path))
37}
38
39// ペインを閉じてから入力欄に入れる(ペインがキーを持っている間は入力欄が受け付けない)
40const pick = async ($: EngineInterface, command: string) => {
41  await $.ui.close({ id: PANE })
42  const filled = await $.prompt.fill({ text: `!${command}` })
43  if (!filled.isFilled) $.ui.toast('cmdHistory: 入力欄に入れられませんでした')
44}
45
46export const register: Register = on => {
47  on('session.start', async ($, e, next) => {
48    await $.command.register({
49      name: 'cmdHistory',
50      description: 'PowerShell の履歴から選んで ! コマンドとして入力欄に入れる',
51      argumentHint: '[絞り込む語]',
52    })
53    return next(e)
54  })
55
56  on('command.run', { command: 'cmdHistory' }, async ($, e) => {
57    await update($, entries, () => [])
58    await update($, filter, () => e.args.trim())
59    const list = await loadHistory($)
60    if (list.length === 0) return { text: 'PowerShell の履歴が見つかりませんでした。' }
61    await update($, entries, () => list)
62    await $.ui.open({ id: PANE, title: 'PowerShell history', focus: true, closeOnEscape: true, rows: 16 })
63    return {}
64  })
65
66  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
67    // mobile には Input がない
68    if (e.surface === 'mobile') {
69      const { Text } = $.ui.resolve(e)
70      return <Text dimColor>端末で開いてください</Text>
71    }
72    const { Box, Text, Input, Button } = $.ui.resolve(e)
73    const query = await read($, filter)
74    const hits = matches(await read($, entries), query)
75    const room = Math.max(1, (e.props.scroll?.bodyRows ?? 16) - 2)
76    const width = Math.max(10, (e.props.bodyColumns ?? 80) - 2)
77    const label = (item: string) => {
78      const one = item.replace(/\n/g, ' ⏎ ')
79      return one.length > width ? `${one.slice(0, width - 1)}…` : one
80    }
81
82    return (
83      <Box flexDirection="column">
84        <Input
85          key="filter"
86          label="> "
87          placeholder="絞り込む語(空白区切り)"
88          value={query}
89          submitLabel="先頭を選ぶ"
90          autoFocus
91          onInput={(value: string) => void update($, filter, () => value)}
92          onSubmit={() => {
93            if (hits[0] !== undefined) void pick($, hits[0])
94          }}
95        />
96        {hits.length === 0 && <Text dimColor>一致する履歴がありません</Text>}
97        {hits.slice(0, room).map((item, i) => (
98          <Button key={`row:${i}`} plain onPress={() => void pick($, item)}>
99            {label(item)}
100          </Button>
101        ))}
102        {hits.length > room && <Text dimColor>ほか {hits.length - room} 件</Text>}
103      </Box>
104    )
105  })
106}
107
types/index.d.ts 9 lines
1// 新しい順・重複なしの PowerShell 履歴と、ペインの絞り込み語
2export type CmdHistoryEntries = string[]
3
4declare module 'claude-code' {
5  interface PluginState {
6    'cmdHistory': { entries: CmdHistoryEntries; filter: string }
7  }
8}
9