Compare commits

..
4 Commits
14 changed files with 61 additions and 70 deletions

No files matched your search

+35
View File
@@ -0,0 +1,35 @@
name: CI
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '23 4 * * 1'
jobs:
ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install ShellCheck
run: sudo apt-get update && sudo apt-get install --yes shellcheck
- name: Shell syntax and lint
shell: bash
run: |
git ls-files -z '*.sh' | xargs -0 -r -n1 bash -n
shellcheck --severity=warning $(git ls-files '*.sh')
- name: Python tests
run: for file in scripts/test-*.py; do python3 "$file"; done
- name: Build
env:
REQUIRE_CODEX_SCHEMA: 'false'
run: bash scripts/build.sh --summary
- name: Bash tests
run: |
bash scripts/test-build-validation.sh --summary
bash scripts/test-install-guards.sh --summary
bash scripts/test-plugin-selection.sh --summary
bash scripts/test-quick-update.sh --summary
bash scripts/test-shell-packages.sh --summary
bash scripts/test-managed-install.sh --summary
+2 -2
View File
@@ -113,8 +113,8 @@ Install and update also rebuild internally; the explicit build above lets you ch
- User-level plugin installation for Ponytail, i-have-adhd, Superpowers, Context7, Caveman, QMD, Humanizer, Impeccable, and
Anthropic Frontend Design, with an interactive extension toggle during both install and update. Only extensions
integrations installed and recorded by this setup can be removed through deselection.
- Optional local semantic retrieval for both clients using Qwen3-Embedding-0.6B, disabled by default and removable
through the install/update choice.
- Optional local semantic retrieval for both clients using Qwen3-Embedding-0.6B embeddings and Qwen3-Reranker-0.6B
reranking, disabled by default and removable through the install/update choice.
## Architecture
+1 -1
View File
@@ -12,7 +12,7 @@
]
},
"env": {
"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY": "5"
"CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY": "__CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY__"
},
"statusLine": {
"type": "command",
-1
View File
@@ -8,7 +8,6 @@ status_line = ["model", "reasoning", "approval-mode", "project-name", "git-branc
[agents]
enabled = true
max_concurrent_threads_per_session = 5
max_depth = 1
[features]
hooks = true
+1 -1
View File
@@ -1 +1 @@
{"Claude permanent context":7101,"Codex permanent context":7377,"Claude permanent context absolute limit":8000,"Codex permanent context absolute limit":8000}
{"Claude permanent context":6000,"Codex permanent context":6000,"Claude permanent context absolute limit":6000,"Codex permanent context absolute limit":6000}
+2 -2
View File
@@ -1,2 +1,2 @@
Claude 7101 8000
Codex 7377 8000
Claude 6000 6000
Codex 6000 6000
1 Claude 7101 6000 8000 6000
2 Codex 7377 6000 8000 6000
+1 -1
View File
@@ -210,7 +210,7 @@ $leftoverPlaceholders = @(Get-ChildItem $output -File -Recurse | ForEach-Object
# expected to remain in generated output. -cmatch keeps this case-sensitive so Python
# dunder names (__main__, __name__) in flashbang.sh are not mistaken for placeholders.
$content = (Get-Content -LiteralPath $_.FullName -Raw) -replace '__AI_CONFIG_ROOT__|__POWERSHELL_COMMAND__', ''
if ($content -cmatch '__[A-Z0-9_]+__') { $_.FullName }
if ($content -cmatch '__[A-Z0-9_]+__' -and $content -notmatch '__CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY__') { $_.FullName }
})
if ($leftoverPlaceholders.Count) { throw "Unresolved template placeholders in: $($leftoverPlaceholders -join ', ')" }
+1 -1
View File
@@ -227,7 +227,7 @@ done
# __AI_CONFIG_ROOT__ is resolved at install time, once the destination is known; it is
# expected to remain in generated output, so it is excluded from the leftover check. A
# single tree-wide grep (rather than one process per file) keeps this fast.
leftover_tokens=$(grep -RohE '__[A-Z0-9_]+__' "$output" 2>/dev/null | sort -u | grep -Ev '^(__AI_CONFIG_ROOT__|__POWERSHELL_COMMAND__)$' || true)
leftover_tokens=$(grep -RohE '__[A-Z0-9_]+__' "$output" 2>/dev/null | sort -u | grep -Ev '^(__AI_CONFIG_ROOT__|__POWERSHELL_COMMAND__|__CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY__)$' || true)
if [ -n "$leftover_tokens" ]; then
offending_files=$(grep -RlE '__[A-Z0-9_]+__' "$output" 2>/dev/null | tr '\n' ' ')
printf 'Unresolved template placeholders (%s) in: %s\n' "$(printf '%s' "$leftover_tokens" | tr '\n' ' ')" "$offending_files" >&2
+3 -1
View File
@@ -34,13 +34,15 @@ if (-not (Test-Path $generated)) { throw 'Generated output is missing after a su
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$powerShellCommand = if (Get-Command powershell -ErrorAction SilentlyContinue) { 'powershell -NoProfile -ExecutionPolicy Bypass -File' } else { 'pwsh -NoProfile -ExecutionPolicy Bypass -File' }
$shellCommand = if ($Shell -eq 'PowerShell') { $powerShellCommand } else { 'bash' }
$claudeConcurrency = if ($env:CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY) { $env:CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY } else { '5' }
if ($claudeConcurrency -notmatch '^[1-9][0-9]?$' -or [int]$claudeConcurrency -gt 10) { throw 'CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY must be an integer from 1 to 10.' }
$plugins = Select-ConfiguredPlugins -RepositoryRoot $root -HomePath $homePath -Client $Client -Mode 'Install' -DryRun:$DryRun
if ($options.update_agents) { Update-SelectedAgentClis -Client $Client -DryRun:$DryRun -Summary:$Summary }
foreach ($item in (Get-InstallTargets -Generated $generated -HomePath $homePath -Shell $shell -Client $Client)) {
Sync-ManagedDestination -Source $item.Source -Destination $item.Destination -Stamp $stamp `
-AiConfigRoot $item.Destination.Replace('\','/') -ShellCommand $shellCommand -PowerShellCommand $powerShellCommand -FlashbangEnabled $options.flashbang -DryRun:$DryRun -Summary:$Summary
-AiConfigRoot $item.Destination.Replace('\','/') -ShellCommand $shellCommand -PowerShellCommand $powerShellCommand -ClaudeConcurrency $claudeConcurrency -FlashbangEnabled $options.flashbang -DryRun:$DryRun -Summary:$Summary
}
Sync-ConfiguredPlugins -RepositoryRoot $root -HomePath $homePath -Client $Client -DryRun:$DryRun -Summary:$Summary -Entries $plugins.Selected
+3 -1
View File
@@ -48,6 +48,8 @@ powershell_command='pwsh -NoProfile -ExecutionPolicy Bypass -File'
if command -v powershell >/dev/null; then powershell_command='powershell -NoProfile -ExecutionPolicy Bypass -File'; fi
shell_command=bash
[ "$shell" != powershell ] || shell_command=$powershell_command
claude_concurrency=${CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY:-5}
[[ "$claude_concurrency" =~ ^[1-9][0-9]?$ ]] && [ "$claude_concurrency" -le 10 ] || { printf 'CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY must be an integer from 1 to 10.\n' >&2; exit 1; }
selected_plugins=()
deselected_plugins=()
@@ -57,7 +59,7 @@ select_configured_plugins "$root" "$client" Install "$dry_run" selected_plugins
while IFS='|' read -r source destination; do
ai_config_root=$destination
command -v cygpath >/dev/null && ai_config_root=$(cygpath -m "$destination")
sync_managed_destination "$source" "$destination" "$stamp" "$ai_config_root" "$shell_command" "$powershell_command" "$dry_run" "$summary" "$flashbang"
sync_managed_destination "$source" "$destination" "$stamp" "$ai_config_root" "$shell_command" "$powershell_command" "$dry_run" "$summary" "$flashbang" "$claude_concurrency"
done < <(get_install_targets "$generated" "$home_path" "$shell" "$client")
sync_configured_plugins "$root" "$client" "$home_path" "$dry_run" false selected_plugins "$summary"
+2 -1
View File
@@ -56,6 +56,7 @@ function Sync-ManagedDestination {
[string]$AiConfigRoot,
[string]$ShellCommand,
[string]$PowerShellCommand,
[string]$ClaudeConcurrency = '5',
[bool]$FlashbangEnabled = $true,
[switch]$DryRun,
[switch]$Summary
@@ -78,7 +79,7 @@ function Sync-ManagedDestination {
}
$needsSubstitution = $filterFlashbang -or $rawContent.Contains('__AI_CONFIG_ROOT__') -or $rawContent.Contains('__HOOK_COMMAND__') -or $rawContent.Contains('__POWERSHELL_HOOK_COMMAND__') -or $rawContent.Contains('__POWERSHELL_COMMAND__')
if ($needsSubstitution) {
$finalContent = $rawContent.Replace('__AI_CONFIG_ROOT__', $AiConfigRoot).Replace('__HOOK_COMMAND__', $ShellCommand).Replace('__POWERSHELL_HOOK_COMMAND__', $PowerShellCommand).Replace('__POWERSHELL_COMMAND__', $PowerShellCommand).Replace('__HOOK_SCRIPT__', 'flashbang.ps1').Replace('__POWERSHELL_HOOK_SCRIPT__', 'flashbang.ps1')
$finalContent = $rawContent.Replace('__AI_CONFIG_ROOT__', $AiConfigRoot).Replace('__HOOK_COMMAND__', $ShellCommand).Replace('__POWERSHELL_HOOK_COMMAND__', $PowerShellCommand).Replace('__POWERSHELL_COMMAND__', $PowerShellCommand).Replace('__CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY__', $ClaudeConcurrency).Replace('__HOOK_SCRIPT__', 'flashbang.ps1').Replace('__POWERSHELL_HOOK_SCRIPT__', 'flashbang.ps1')
$newBytes = [System.Text.Encoding]::UTF8.GetBytes($finalContent)
} else {
$newBytes = [System.IO.File]::ReadAllBytes($_.FullName)
+3 -2
View File
@@ -49,9 +49,9 @@ write_managed_manifest() {
} > "$path"
}
# sync_managed_destination <source-dir> <destination-dir> <stamp> <ai-config-root> <shell-command> <powershell-command> <dry-run: true|false> [summary: true|false]
# sync_managed_destination <source-dir> <destination-dir> <stamp> <ai-config-root> <shell-command> <powershell-command> <dry-run: true|false> [summary: true|false] [flashbang] [claude-concurrency]
sync_managed_destination() {
local source=$1 destination=$2 stamp=$3 ai_config_root=$4 shell_command=$5 powershell_command=$6 dry_run=$7 summary=${8:-false} flashbang_enabled=${9:-true}
local source=$1 destination=$2 stamp=$3 ai_config_root=$4 shell_command=$5 powershell_command=$6 dry_run=$7 summary=${8:-false} flashbang_enabled=${9:-true} claude_concurrency=${10:-5}
[ "$summary" = true ] || printf 'SOURCE %s -> %s\n' "$source" "$destination"
local manifest
manifest=$(manifest_path "$destination")
@@ -77,6 +77,7 @@ sync_managed_destination() {
content=${content//__HOOK_COMMAND__/$shell_command}
content=${content//__POWERSHELL_HOOK_COMMAND__/$powershell_command}
content=${content//__POWERSHELL_COMMAND__/$powershell_command}
content=${content//__CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY__/$claude_concurrency}
content=${content//__HOOK_SCRIPT__/flashbang.sh}
content=${content//__POWERSHELL_HOOK_SCRIPT__/flashbang.sh}
new_hash=$(sha256_of_string "$content")
+2 -2
View File
@@ -1,7 +1,7 @@
# Personal global instructions
This instruction set is generated into the client-specific `AGENTS.md` and `CLAUDE.md` files. Do not edit generated copies.
This file is generated into client-specific instruction files. Do not edit generated copies.
__RULE_LOADING__
Main agent owns state and decisions. Delegate only when benefit exceeds context/tool cost; do cheap exploration directly. Use one implementer for contained work and independent scopes for parallel work. Avoid duplicated reads. Subagents report to their parent and never spawn agents. Load orchestration guidance for delegation, subagent work, or long-running state; pass minimal context and retrieve more as needed.
Main agent owns state and decisions. Delegate only for independent work where benefit exceeds context/tool cost. Use one implementer for contained work; subagents never spawn agents. Pass minimal context and verify handoffs.
+5 -54
View File
@@ -1,60 +1,11 @@
# General rules
## Priority
Apply instructions in this order: direct user instructions; security and data-loss protections; project rules; these rules; repository conventions; preferences.
Apply instructions in this order:
Preserve security, data, compatibility, and unrelated user work. Ask only when behavior, contracts, permissions, or irreversible choices are materially ambiguous. Otherwise choose the smallest reversible change.
1. Direct current user instructions.
2. Non-negotiable security and data-loss protections.
3. Applicable project-specific instructions.
4. These global user-level rules.
5. Existing project conventions.
6. Agent preferences.
Use semantic retrieval early when available for unfamiliar code or meaning-based discovery; verify results against current files. Use direct reads and exact search for known paths and symbols. Continue without retrieval if unavailable.
Project instructions may specialize global defaults, but must not weaken security or data-loss protections without explicit user approval.
Verify proportionally: run the cheapest check that detects likely failure; broaden for security, data loss, integration, or cross-component risk. Never claim unrun checks passed. Report failures and material gaps.
## Decisions
* Make evidence-based, reversible technical decisions independently; ask only when material uncertainty, multiple meaningful options, or high-impact/hard-to-reverse effects remain.
* Ask about business behavior, user-visible behavior, UI, UX, APIs, database models, configuration formats, or compatibility behavior only when it is missing, ambiguous, contradictory, or open to interpretation; implement explicitly specified behavior without asking again.
* For deeper guidance on ambiguous requirements or a meaningful technical choice, consult `decision-rule.md` (Codex: read `rules/decision-rule.md`; Claude: invoke the `rules-decision-rule` skill).
## Semantic repository search
* In Codex and Claude Code, proactively use the `my-ai-qwen3-retrieval` MCP server's `semantic_search` tool whenever available and useful. It always uses Qwen3-Embedding-0.6B for retrieval and Qwen3-Reranker-0.6B for reranking. Discover the tool if it is not already exposed.
* Use semantic search early to find unfamiliar code, understand responsibilities and relationships, locate similar implementations, or investigate behavior described without exact symbols. Reuse relevant results and search again when a new question would benefit.
* Use direct file reads for known paths and exact text search for symbols, literals, and exhaustive caller checks. Combine these with semantic search when meaning-based discovery adds value.
* Treat retrieved passages as leads: verify them against current files in the intended workspace before relying on them. Empty results do not prove absence; stale or unrelated results require direct inspection.
* If retrieval is unavailable, fails, or adds no value, continue with ordinary repository tools. Report failures briefly; avoid repeated failing calls or installing or enabling retrieval without authorization.
* When QMD is available, use its `qmd` MCP tools for questions about indexed Markdown notes, documents, meeting records, or knowledge bases. Verify retrieved results against the source document when the current content matters.
## Verification
* Choose checks independently by behavior, callers, impact, reversibility, and uncertainty. Focused inspection can suffice; builds, tests, new tests, and separate reviews are not automatic.
* Execute the cheapest check that detects the likely failure. Broaden for cross-component effects, security/data-loss risks, failures, or unresolved uncertainty. Small changes can still be risky.
* Add tests for meaningful behavior or plausible regressions, not implementation details or wording. Stop when risks are covered; repeat only when changed evidence warrants it.
* Explicit user/project/CI requirements remain binding. Generic skill mandates for review, builds, tests, or test-first work do not override proportional verification; skipping needless steps needs no permission.
* Report checks and material gaps concisely. Distinguish inspection from execution; never claim unrun checks passed or hide failures.
## Documentation
* Never modify existing documentation automatically.
* Do not create new documentation unless the user explicitly requests it.
* This includes README files, technical documentation, changelogs, release notes, pull request descriptions, and work-item text.
* If a code change would make existing documentation inaccurate, make the change and note the affected documentation afterward instead of asking first or blocking the change.
## Comments
* Do not add new code comments without the user's explicit approval.
* This includes `why` comments, workaround explanations, framework limitations, and external constraints.
* Prefer self-explanatory code and clear names.
* Skip a comment that seems useful rather than stopping to ask; proceed with the code change.
## Tool output
* Prefer a script's documented summary mode for routine agent runs; keep warnings and failure diagnostics visible. Use detailed output when investigating a failure or when requested.
## Language
* Write code and repository-generated user-facing text in English.
Do not modify existing documentation or create new documentation unless requested. Do not add comments unless requested. Write repository content and user-facing output in English.