aidevops 3.5.896 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+ <!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
3
+
1
4
  # AI DevOps Framework
2
5
 
3
6
  **[aidevops.sh](https://aidevops.sh)** — An [OpenCode](https://opencode.ai/) plugin and AI operations platform for launching and managing development, business, marketing, and creative projects. 13 specialist AI agents handle the automatable work across every domain so your time is preserved for real-world discovery and decisions that AI cannot yet reach.
@@ -188,7 +191,8 @@ git clone https://github.com/marcusquinn/aidevops.git ~/Git/aidevops
188
191
  - Configure your AI assistants automatically
189
192
  - Offer to install Oh My Zsh (optional, opt-in) for enhanced shell experience
190
193
  - Guide you through recommended tools (Tabby, Zed, Git CLIs)
191
- - Ensure all PATH and alias changes work in both bash and zsh
194
+ - Ensure all PATH and alias changes work in both bash, zsh, and fish
195
+ - Add a `claude` alias that runs `claude --dangerously-skip-permissions` (skips per-tool permission prompts). Re-running setup updates the alias automatically. To grant permissions per-session instead, press **Shift-Tab** inside Claude Code to cycle through permission modes (default → skip permissions → auto-approve).
192
196
 
193
197
  **New users: Start [OpenCode](https://opencode.ai/) and type `/onboarding`** to configure your services interactively. OpenCode is the recommended tool for aidevops - all features, agents, and workflows are designed and tested for it first. The onboarding wizard will:
194
198
  - Explain what **[aidevops](https://aidevops.sh)** can do
@@ -1792,25 +1796,67 @@ Call them in your AI assistant conversation with a simple @mention
1792
1796
 
1793
1797
  ### **Main Agents**
1794
1798
 
1795
- Primary agents as registered in `subagent-index.toon` (13 total). MCPs are loaded on-demand per subagent, not per primary agent:
1799
+ Primary agents live at `.agents/<name>.md`. Each is a domain expert with its own system prompt, tool permissions, and subagent roster. MCPs are loaded on-demand per subagent, not per primary agent.
1796
1800
 
1797
1801
  | Name | File | Purpose | Model Tier |
1798
1802
  |------|------|---------|------------|
1799
- | Build+ | `build-plus.md` | Enhanced Build with context tools (default agent) | opus |
1803
+ | Build+ | `build-plus.md` | Code: features, bug fixes, refactors, CI, full-loop delivery (default) | opus |
1800
1804
  | Automate | `automate.md` | Scheduling, dispatch, monitoring, background orchestration | sonnet |
1801
- | Accounts | `accounts.md` | Financial operations | opus |
1802
- | Business | `business.md` | Company orchestration via AI runners | sonnet |
1803
- | Content | `content.md` | Content creation workflows | opus |
1804
- | Health | `health.md` | Health and wellness | opus |
1805
- | Legal | `legal.md` | Legal compliance | opus |
1806
- | Marketing | `marketing.md` | Marketing strategy, email campaigns, paid ads, CRO | opus |
1807
- | Research | `research.md` | Research and analysis tasks | gemini/grok |
1808
- | Sales | `sales.md` | Sales operations and CRM pipeline | opus |
1809
- | SEO | `seo.md` | SEO optimization and analysis | opus |
1810
- | Social-Media | `social-media.md` | Social media management | opus |
1811
- | Video | `video.md` | AI video generation and prompt engineering | opus |
1812
-
1813
- **Specialist subagents** (@plan-plus, @aidevops, @wordpress, Build-Agent, Build-MCP, etc.) live under `tools/` or as `mode: subagent` files and are invoked via @mention when domain expertise is needed. See `subagent-index.toon` for the full listing.
1805
+ | Aidevops | `aidevops.md` | Framework development — meta-agent for improving aidevops itself | opus |
1806
+ | Business | `business.md` | Company orchestration, financial ops, invoicing, strategy | sonnet |
1807
+ | Content | `content.md` | Content creation across blog, video, audio, image, social | opus |
1808
+ | Health | `health.md` | Health and wellness content, fitness, nutrition | opus |
1809
+ | Legal | `legal.md` | Legal compliance, terms, privacy, GDPR | opus |
1810
+ | Marketing-Sales | `marketing-sales.md` | Email campaigns, CRM, outreach, paid ads, direct response, CRO | opus |
1811
+ | Product | `product.md` | Product management, PRDs, roadmaps, requirements capture | opus |
1812
+ | Research | `research.md` | Technical and market research, competitive analysis | gemini/grok |
1813
+ | SEO | `seo.md` | SEO audits, keyword research, GSC, schema, technical SEO | opus |
1814
+
1815
+ **Specialist subagents** (e.g. `@wordpress`, `@seo`, Build-Agent, Build-MCP, etc.) live under `.agents/tools/` or as `mode: subagent` files and are invoked via `@mention` when domain expertise is needed. See `subagent-index.toon` for the full roster.
1816
+
1817
+ #### How to invoke a main agent
1818
+
1819
+ | Client | Invocation |
1820
+ |---|---|
1821
+ | **OpenCode** | Tab through the agent picker in the UI — Build+ is the default. Main agents are registered as top-level agents in OpenCode's config. |
1822
+ | **Claude Code / Codex / Cursor / Droid / Kiro / Continue / Kimi / Qwen / Amp / Windsurf / Gemini CLI** | Slash command, namespaced with the `aidevops-` prefix: `/aidevops-build-plus`, `/aidevops-automate`, `/aidevops-seo`, etc. |
1823
+ | **Aider** | No native slash command support — use a shell alias: `alias aider-build='aider --message-file ~/.aidevops/agents/build-plus.md'`. |
1824
+
1825
+ The `aidevops-` prefix differentiates framework commands from each client's native slash commands and groups them alphabetically in the command picker. It applies to **every** aidevops slash command — not just main agents — so `/aidevops-preflight`, `/aidevops-release`, `/aidevops-commit` etc. all sort together in your `/` menu.
1826
+
1827
+ #### Supported AI clients (14)
1828
+
1829
+ The framework installs itself across these clients. Slash commands, agent definitions, and (optionally) session-memory mining are wired up per-client by `setup.sh`, gated on per-client feature flags in `.agents/scripts/runtime-registry.sh`.
1830
+
1831
+ | Client | Slash commands | Agent dir | Memory mining | Notes |
1832
+ |---|---|---|---|---|
1833
+ | OpenCode | ✅ `~/.config/opencode/command/` | config-based | ✅ default | Native tab-through primary agents |
1834
+ | Claude Code | ✅ `~/.claude/commands/` | ✅ `~/.claude/agents/` | ✅ default | Full feature parity |
1835
+ | Codex CLI | ✅ `~/.codex/prompts/` | — | ✅ default | Invoked as `/prompts:aidevops-<name>` |
1836
+ | Cursor | ✅ `~/.cursor/commands/` (≥1.6) | ✅ `~/.cursor/agents/` | ✅ default | Frontmatter stripped (not supported) |
1837
+ | Droid (Factory) | ✅ `~/.factory/commands/` | — | opt-in | — |
1838
+ | Gemini CLI | ✅ `~/.gemini/commands/` | — | opt-in | Converted to TOML (`prompt = """..."""`) |
1839
+ | Kimi CLI | ✅ `~/.kimi/skills/<name>/SKILL.md` | ✅ `~/.kimi/agents/` | opt-in | Directory-per-skill + auto `name:` matching |
1840
+ | Qwen Code | ✅ `~/.qwen/commands/` | ✅ `~/.qwen/agents/` | opt-in | Sub-agents + skills |
1841
+ | Continue | ✅ `~/.continue/prompts/` | — | opt-in | `.prompt` ext + `invokable: true` |
1842
+ | Kiro | ✅ `~/.kiro/steering/` | — | opt-in | `inclusion: manual` for slash access |
1843
+ | Kilo Code | custom modes | — | opt-in | Uses modes instead of commands |
1844
+ | Windsurf | repo-local `.windsurf/workflows/` | — | ❌ (protobuf) | Symlinked by `aidevops init` |
1845
+ | Amp (Sourcegraph) | repo-local `.agents/commands/` | ✅ `~/.amp/agents/` | ❌ (cloud) | Path match is native |
1846
+ | Aider | shell alias workaround | — | ❌ (per-repo md) | Native custom commands open upstream |
1847
+
1848
+ **Feature flags** per client (`agents` / `commands` / `memory`) live in `runtime-registry.sh` and can be overridden at install time via environment variables:
1849
+
1850
+ ```bash
1851
+ AIDEVOPS_FEATURE_MEMORY_CLAUDE_CODE=no setup.sh
1852
+ AIDEVOPS_FEATURE_COMMANDS_CURSOR=no setup.sh
1853
+ ```
1854
+
1855
+ Memory mining defaults are deliberately conservative: only OpenCode, Claude Code, Codex, and Cursor are opted in by default. All other clients default to off — enable them case-by-case after reviewing what the mining job will read.
1856
+
1857
+ #### Endgame: progressive disclosure
1858
+
1859
+ The long-term direction is to make slash commands and `@mentions` unnecessary altogether. A progressive disclosure layer should load the right domain agents and tools into context based on the nature of the conversation — you should never have to remember agent names or prefix commands. The `aidevops-` slash commands documented above are a stepping stone: they standardise routing across every client we support, and will eventually be auto-invoked by the router rather than typed by hand.
1814
1860
 
1815
1861
  ### **Example Subagents with MCP Integration**
1816
1862
 
@@ -2284,6 +2330,40 @@ memory-helper.sh recall "refactor auth middleware" --semantic
2284
2330
 
2285
2331
  **Storage:** `~/.aidevops/.agent-workspace/memory/memory.db` (+ optional `embeddings.db` for semantic search, `namespaces/` for per-runner isolation)
2286
2332
 
2333
+ #### Session mining (cross-client)
2334
+
2335
+ Beyond explicit `/remember` calls, aidevops can harvest structured session data from each supported AI client's on-disk conversation history. This turns every prior session — regardless of which tool you were using — into searchable context for future sessions.
2336
+
2337
+ Per-client storage paths and formats (see `runtime-registry.sh`):
2338
+
2339
+ | Client | Storage path | Format | Default |
2340
+ |---|---|---|---|
2341
+ | OpenCode | `~/.local/share/opencode/opencode.db` | SQLite | ✅ on |
2342
+ | Claude Code | `~/.claude/projects/` | JSONL per project | ✅ on |
2343
+ | Codex CLI | `~/.codex/sessions/` | JSONL, date-partitioned | ✅ on |
2344
+ | Cursor | `~/Library/Application Support/Cursor/User/workspaceStorage/` | SQLite (`state.vscdb`) | ✅ on |
2345
+ | Droid | `~/.factory/sessions/` | JSONL per session | opt-in |
2346
+ | Gemini CLI | `~/.gemini/tmp/` | JSON per session | opt-in |
2347
+ | Continue | `~/.continue/sessions/` | JSON per session | opt-in |
2348
+ | Kilo Code | `~/Library/.../kilocode.kilo-code/tasks/` | JSON (Anthropic schema) | opt-in |
2349
+ | Kiro | `~/Library/Application Support/Kiro/User/workspaceStorage/` | SQLite | opt-in |
2350
+ | Kimi CLI | `~/.kimi/sessions/<id>/context.jsonl` | JSONL | opt-in |
2351
+ | Qwen Code | `~/.qwen/tmp/` | JSON per session | opt-in |
2352
+ | Windsurf | `~/.codeium/windsurf/cascade/` | protobuf (opaque) | ❌ unsupported |
2353
+ | Amp | server-side (cloud) | needs API auth | ❌ unsupported |
2354
+ | Aider | `<repo>/.aider.chat.history.md` | markdown transcript | ❌ unsupported |
2355
+
2356
+ **Defaults are deliberately conservative.** Only the four tier-1 clients — OpenCode, Claude Code, Codex, and Cursor — have memory mining enabled by default. They have the most mature, stable, documented formats and are the ones most likely to contain the full interactive history you'd want to search.
2357
+
2358
+ For every other client, memory mining is **opt-in per runtime**. Enable it with:
2359
+
2360
+ ```bash
2361
+ AIDEVOPS_FEATURE_MEMORY_GEMINI_CLI=yes setup.sh
2362
+ AIDEVOPS_FEATURE_MEMORY_CONTINUE=yes setup.sh
2363
+ ```
2364
+
2365
+ **Privacy note.** Session files contain everything you typed — including secrets, credentials, and file contents pasted into prompts. The mining pipeline runs secretlint-style scrubbing at ingestion and defaults to local-only storage. Never sync the memory DB to a shared or cloud location without reviewing what's in it.
2366
+
2287
2367
  See `.agents/memory/README.md` for complete documentation.
2288
2368
 
2289
2369
  ### **Installation**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.5.896
1
+ 3.8.2
package/aidevops.sh CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env bash
2
+ # SPDX-License-Identifier: MIT
3
+ # SPDX-FileCopyrightText: 2025-2026 Marcus Quinn
2
4
 
3
5
  # AI DevOps Framework CLI
4
6
  # Usage: aidevops <command> [options]
5
7
  #
6
- # Version: 3.5.896
8
+ # Version: 3.8.2
7
9
 
8
10
  set -euo pipefail
9
11
 
@@ -502,17 +504,26 @@ check_protected_branch() {
502
504
  repo_name=$(basename "$project_root")
503
505
  local suggested_branch="$branch_type/$branch_suffix"
504
506
 
505
- echo ""
506
- print_warning "On protected branch '$current_branch'"
507
- echo ""
508
- echo "Options:"
509
- echo " 1. Create worktree: $suggested_branch (recommended)"
510
- echo " 2. Continue on $current_branch (commits directly to main)"
511
- echo " 3. Cancel"
512
- echo ""
513
507
  local choice
514
- read -r -p "Choice [1]: " choice
515
- choice="${choice:-1}"
508
+ # In non-interactive (non-TTY) contexts, auto-select option 1 (create worktree)
509
+ # without prompting. This prevents read from blocking or getting EOF in CI/AI
510
+ # assistant environments, which could cause silent script termination with set -e.
511
+ if [[ -t 0 ]]; then
512
+ echo ""
513
+ print_warning "On protected branch '$current_branch'"
514
+ echo ""
515
+ echo "Options:"
516
+ echo " 1. Create worktree: $suggested_branch (recommended)"
517
+ echo " 2. Continue on $current_branch (commits directly to main)"
518
+ echo " 3. Cancel"
519
+ echo ""
520
+ read -r -p "Choice [1]: " choice
521
+ choice="${choice:-1}"
522
+ else
523
+ # Non-interactive: auto-create worktree (safest default)
524
+ choice="1"
525
+ print_info "Non-interactive mode: auto-selecting worktree creation for '$suggested_branch'"
526
+ fi
516
527
 
517
528
  case "$choice" in
518
529
  1)
@@ -522,35 +533,34 @@ check_protected_branch() {
522
533
 
523
534
  print_info "Creating worktree at $worktree_dir..."
524
535
 
536
+ local worktree_created=false
525
537
  if [[ -f "$AGENTS_DIR/scripts/worktree-helper.sh" ]]; then
526
- if bash "$AGENTS_DIR/scripts/worktree-helper.sh" add "$suggested_branch" 2>/dev/null; then
527
- export WORKTREE_PATH="$worktree_dir"
528
- echo ""
529
- print_success "Worktree created!"
530
- print_info "Switching to: $worktree_dir"
531
- echo ""
532
- # Change to worktree directory
533
- cd "$worktree_dir" || return 1
534
- return 0
538
+ if bash "$AGENTS_DIR/scripts/worktree-helper.sh" add "$suggested_branch"; then
539
+ worktree_created=true
535
540
  else
536
- print_error "Failed to create worktree"
541
+ print_error "Failed to create worktree via worktree-helper.sh"
537
542
  return 1
538
543
  fi
539
544
  else
540
545
  # Fallback without helper script
541
- if git worktree add -b "$suggested_branch" "$worktree_dir" 2>/dev/null; then
542
- export WORKTREE_PATH="$worktree_dir"
543
- echo ""
544
- print_success "Worktree created!"
545
- print_info "Switching to: $worktree_dir"
546
- echo ""
547
- cd "$worktree_dir" || return 1
548
- return 0
546
+ if git worktree add -b "$suggested_branch" "$worktree_dir"; then
547
+ worktree_created=true
549
548
  else
550
549
  print_error "Failed to create worktree"
551
550
  return 1
552
551
  fi
553
552
  fi
553
+
554
+ if [[ "$worktree_created" == "true" ]]; then
555
+ export WORKTREE_PATH="$worktree_dir"
556
+ echo ""
557
+ print_success "Worktree created at: $worktree_dir"
558
+ print_info "Switching to: $worktree_dir"
559
+ echo ""
560
+ # Change to worktree directory for the remainder of this process
561
+ cd "$worktree_dir" || return 1
562
+ return 0
563
+ fi
554
564
  ;;
555
565
  2)
556
566
  print_warning "Continuing on $current_branch - changes will commit directly"
@@ -655,6 +665,22 @@ cmd_status() {
655
665
  print_header "SSH Configuration"
656
666
  check_file "$HOME/.ssh/id_ed25519" && print_success "Ed25519 SSH key" || print_warning "Ed25519 SSH key - not found"
657
667
  echo ""
668
+ print_header "Commit Signing"
669
+ local signing_format signing_key signing_enabled
670
+ signing_format=$(git config --global gpg.format 2>/dev/null || echo "")
671
+ signing_key=$(git config --global user.signingkey 2>/dev/null || echo "")
672
+ signing_enabled=$(git config --global commit.gpgsign 2>/dev/null || echo "")
673
+ if [[ "$signing_format" == "ssh" && -n "$signing_key" && "$signing_enabled" == "true" ]]; then
674
+ print_success "SSH commit signing enabled"
675
+ if check_file "$HOME/.ssh/allowed_signers"; then
676
+ print_success "Allowed signers file configured"
677
+ else
678
+ print_warning "No allowed_signers file — run: aidevops signing setup"
679
+ fi
680
+ else
681
+ print_warning "Commit signing not configured — run: aidevops signing setup"
682
+ fi
683
+ echo ""
658
684
  }
659
685
 
660
686
  # Update helpers (extracted for complexity reduction)
@@ -838,6 +864,43 @@ _update_check_homebrew() {
838
864
  return 0
839
865
  }
840
866
 
867
+ # Verify supply chain signature after pulling framework updates.
868
+ # Checks that the HEAD commit is signed by the trusted maintainer key.
869
+ # Non-blocking: warns on failure, does not abort the update.
870
+ _update_verify_signature() {
871
+ local signing_helper="$AGENTS_DIR/scripts/signing-setup.sh"
872
+
873
+ # Cannot verify if the helper script is not yet deployed
874
+ if [[ ! -f "$signing_helper" ]]; then
875
+ return 0
876
+ fi
877
+
878
+ local result
879
+ result=$(bash "$signing_helper" verify-update "$INSTALL_DIR" 2>/dev/null || echo "UNKNOWN")
880
+
881
+ case "$result" in
882
+ VERIFIED)
883
+ print_success "Supply chain verified: HEAD commit is signed by trusted maintainer"
884
+ ;;
885
+ UNSIGNED)
886
+ print_warning "HEAD commit is not signed — cannot verify supply chain integrity"
887
+ print_info "This is expected for older releases. Signed commits start from v3.6.21+"
888
+ ;;
889
+ UNTRUSTED)
890
+ print_warning "HEAD commit is signed but by an untrusted key"
891
+ print_info "Run 'aidevops signing setup' to configure signature verification"
892
+ ;;
893
+ BAD_SIGNATURE)
894
+ print_error "HEAD commit has a BAD signature — update may be compromised"
895
+ print_info "Verify manually: cd $INSTALL_DIR && git log --show-signature -1"
896
+ ;;
897
+ UNVERIFIABLE)
898
+ # Signing not configured yet — silent, do not nag
899
+ ;;
900
+ esac
901
+ return 0
902
+ }
903
+
841
904
  # Update/upgrade command
842
905
  cmd_update() {
843
906
  local skip_project_sync=false
@@ -907,6 +970,9 @@ cmd_update() {
907
970
  fi
908
971
  fi
909
972
  echo ""
973
+ # Verify supply chain integrity before applying changes
974
+ _update_verify_signature
975
+ echo ""
910
976
  print_info "Running setup to apply changes..."
911
977
  local setup_exit=0
912
978
  bash "$INSTALL_DIR/setup.sh" --non-interactive || setup_exit=$?
@@ -1427,6 +1493,61 @@ EOF
1427
1493
  return 0
1428
1494
  }
1429
1495
 
1496
+ # Scaffold .agents/commands/ and .windsurf/workflows/ symlinks so that clients
1497
+ # which read repo-local command directories (Amp reads .agents/commands/ natively;
1498
+ # Windsurf reads .windsurf/workflows/) see the aidevops main-agent slash commands.
1499
+ #
1500
+ # Behavior is idempotent:
1501
+ # - If .agents/commands/ already contains the expected aidevops-*.md symlinks
1502
+ # (this repo IS the aidevops source), do nothing.
1503
+ # - Otherwise link .agents/commands/ → ~/.aidevops/agents/commands/
1504
+ # - Always link .windsurf/workflows/ → ../.agents/commands/ (relative)
1505
+ _init_scaffold_commands_symlinks() {
1506
+ local project_root="$1"
1507
+ local source_dir="$HOME/.aidevops/agents/commands"
1508
+ local commands_dir="$project_root/.agents/commands"
1509
+ local windsurf_dir="$project_root/.windsurf"
1510
+ local workflows_link="$windsurf_dir/workflows"
1511
+
1512
+ # If .agents/commands/ already contains main-agent symlinks, this repo
1513
+ # manages them directly (e.g. the aidevops source repo itself) — leave
1514
+ # it alone so we never overwrite authoritative content.
1515
+ if [[ -e "$commands_dir/aidevops-build-plus.md" ]]; then
1516
+ print_info ".agents/commands/ already contains main-agent symlinks — preserving"
1517
+ elif [[ ! -d "$source_dir" ]]; then
1518
+ print_warning "Framework commands dir not found at $source_dir — run setup.sh first to deploy main-agent symlinks"
1519
+ elif [[ -L "$commands_dir" ]]; then
1520
+ # Existing symlink — point at the canonical source
1521
+ local current_target
1522
+ current_target=$(readlink "$commands_dir")
1523
+ if [[ "$current_target" != "$source_dir" ]]; then
1524
+ rm "$commands_dir"
1525
+ ln -s "$source_dir" "$commands_dir"
1526
+ print_success "Re-linked .agents/commands/ → $source_dir"
1527
+ else
1528
+ print_info ".agents/commands/ already linked correctly"
1529
+ fi
1530
+ elif [[ -d "$commands_dir" ]]; then
1531
+ print_warning ".agents/commands/ exists as a real directory — not overwriting"
1532
+ else
1533
+ ln -s "$source_dir" "$commands_dir"
1534
+ print_success "Linked .agents/commands/ → $source_dir (Amp reads this natively)"
1535
+ fi
1536
+
1537
+ # .windsurf/workflows/ → ../.agents/commands/ (relative, so the link
1538
+ # resolves inside the repo regardless of checkout path).
1539
+ mkdir -p "$windsurf_dir"
1540
+ if [[ -L "$workflows_link" ]]; then
1541
+ print_info ".windsurf/workflows/ already linked"
1542
+ elif [[ -d "$workflows_link" ]]; then
1543
+ print_warning ".windsurf/workflows/ exists as a real directory — not overwriting"
1544
+ else
1545
+ (cd "$windsurf_dir" && ln -s "../.agents/commands" workflows)
1546
+ print_success "Linked .windsurf/workflows/ → ../.agents/commands (Windsurf slash commands)"
1547
+ fi
1548
+ return 0
1549
+ }
1550
+
1430
1551
  # Init command - initialize aidevops in a project
1431
1552
  cmd_init() {
1432
1553
  local features="${1:-all}"
@@ -1570,6 +1691,10 @@ EOF
1570
1691
  print_success "Created .agents/ directory"
1571
1692
  fi
1572
1693
 
1694
+ # Link .agents/commands/ and .windsurf/workflows/ so Amp (native) and Windsurf
1695
+ # (symlinked) can see the aidevops main-agent slash commands.
1696
+ _init_scaffold_commands_symlinks "$project_root"
1697
+
1573
1698
  # Scaffold or update .agents/AGENTS.md (idempotent — creates if missing,
1574
1699
  # updates Security section if file already exists)
1575
1700
  local _agents_md_existed=false
@@ -1966,6 +2091,18 @@ GITATTRSEOF
1966
2091
  print_info "Collaborator pointer files already exist"
1967
2092
  fi
1968
2093
 
2094
+ # Seed DESIGN.md template (AI-readable design system skeleton)
2095
+ if [[ ! -f "$project_root/DESIGN.md" ]]; then
2096
+ local design_template="$AGENTS_DIR/templates/DESIGN.md.template"
2097
+ if [[ -f "$design_template" ]]; then
2098
+ # Replace {Project Name} with the repo name
2099
+ sed "s/{Project Name}/$repo_name/g" "$design_template" >"$project_root/DESIGN.md"
2100
+ print_success "Created DESIGN.md (design system skeleton — populate with tools/design/design-md.md)"
2101
+ fi
2102
+ else
2103
+ print_info "DESIGN.md already exists, skipping"
2104
+ fi
2105
+
1969
2106
  # Scaffold repo courtesy files (README, LICENCE, CHANGELOG, etc.)
1970
2107
  scaffold_repo_courtesy_files "$project_root"
1971
2108
 
@@ -2009,8 +2146,21 @@ GITATTRSEOF
2009
2146
  [[ "$enable_security" == "true" ]] && features_list="${features_list}security,"
2010
2147
  features_list="${features_list%,}" # Remove trailing comma
2011
2148
 
2012
- # Register repo in repos.json
2013
- register_repo "$project_root" "$aidevops_version" "$features_list"
2149
+ # Register the *main* repo path (not the worktree path) in repos.json.
2150
+ # When check_protected_branch creates a worktree and cd's into it,
2151
+ # $project_root (resolved via git rev-parse --show-toplevel) points to the
2152
+ # worktree directory. We must register the canonical main worktree path so
2153
+ # that pulse and cleanup processes don't treat the worktree as a standalone repo.
2154
+ local register_path="$project_root"
2155
+ if [[ -n "${WORKTREE_PATH:-}" ]]; then
2156
+ # We're inside a worktree — resolve the main worktree path from git metadata
2157
+ local main_wt_path
2158
+ main_wt_path=$(git -C "$project_root" worktree list --porcelain 2>/dev/null | awk '/^worktree /{print $2; exit}')
2159
+ if [[ -n "$main_wt_path" ]] && [[ "$main_wt_path" != "$project_root" ]]; then
2160
+ register_path="$main_wt_path"
2161
+ fi
2162
+ fi
2163
+ register_repo "$register_path" "$aidevops_version" "$features_list"
2014
2164
 
2015
2165
  # Auto-commit initialized files so they don't linger as mystery unstaged
2016
2166
  # changes (#2570 bug 2). Collect all files that cmd_init creates/modifies.
@@ -2019,6 +2169,7 @@ GITATTRSEOF
2019
2169
  [[ -f "$project_root/.gitignore" ]] && init_files+=(".gitignore")
2020
2170
  [[ -d "$project_root/.agents" ]] && init_files+=(".agents/")
2021
2171
  [[ -f "$project_root/AGENTS.md" ]] && init_files+=("AGENTS.md")
2172
+ [[ -f "$project_root/DESIGN.md" ]] && init_files+=("DESIGN.md")
2022
2173
  [[ -f "$project_root/TODO.md" ]] && init_files+=("TODO.md")
2023
2174
  [[ -d "$project_root/todo" ]] && init_files+=("todo/")
2024
2175
  [[ -f "$project_root/MODELS.md" ]] && init_files+=("MODELS.md")
@@ -2064,6 +2215,22 @@ GITATTRSEOF
2064
2215
  [[ "$enable_security" == "true" ]] && echo " ✓ Security (per-repo posture assessment)"
2065
2216
  [[ -f "$project_root/MODELS.md" ]] && echo " ✓ MODELS.md (per-repo model performance leaderboard)"
2066
2217
  echo ""
2218
+ # When init ran inside a worktree (check_protected_branch created one),
2219
+ # print explicit instructions so the user knows where to find their work.
2220
+ # Without this, the user's shell is back in the main repo after aidevops exits
2221
+ # and the worktree appears to have "disappeared".
2222
+ if [[ -n "${WORKTREE_PATH:-}" ]]; then
2223
+ local worktree_branch
2224
+ worktree_branch=$(git branch --show-current 2>/dev/null || echo "chore/aidevops-init")
2225
+ echo "Worktree location:"
2226
+ echo " $WORKTREE_PATH"
2227
+ echo ""
2228
+ echo "Your init commit is in the worktree above. To continue:"
2229
+ echo " cd $WORKTREE_PATH"
2230
+ echo " git push -u origin ${worktree_branch}"
2231
+ echo " gh pr create --fill"
2232
+ echo ""
2233
+ fi
2067
2234
  echo "Next steps:"
2068
2235
  local step=1
2069
2236
  if [[ "$committed" != "true" ]]; then
@@ -2157,7 +2324,39 @@ _upgrade_todo() {
2157
2324
  print_info "Upgrading TODO.md..."
2158
2325
  local existing_tasks=""
2159
2326
  if [[ -f "$todo_file" ]]; then
2160
- existing_tasks=$(grep -E "^[[:space:]]*- \[([ x-])\]" "$todo_file" 2>/dev/null || echo "")
2327
+ # Extract everything under ## Backlog (tasks AND ### subsection headers)
2328
+ # until the next ## header or EOF — preserves semantic grouping.
2329
+ # GH#17804: Skip ## Format section and filter out template placeholder IDs
2330
+ # (tXXX, tYYY, tZZZ) that are documentation examples, not real tasks.
2331
+ existing_tasks=$(awk '
2332
+ # Section-aware: track when inside ## Format to skip its content
2333
+ /^## Format/ { in_format=1; next }
2334
+ in_format && /^## / { in_format=0 }
2335
+ in_format { next }
2336
+ # Also skip content inside markdown code blocks (``` fenced blocks)
2337
+ /^```/ { in_codeblock = !in_codeblock; next }
2338
+ in_codeblock { next }
2339
+ # Extract from ## Backlog to next ## header
2340
+ /^## Backlog/ { found=1; next }
2341
+ found && /^## / { exit }
2342
+ found
2343
+ ' "$todo_file" 2>/dev/null || echo "")
2344
+ # GH#17804: Filter out lines with non-numeric task IDs (template placeholders
2345
+ # like tXXX, tYYY, tZZZ). Real task IDs match t<digits> or t<digits>.<digits>.
2346
+ if [[ -n "$existing_tasks" ]]; then
2347
+ existing_tasks=$(printf '%s\n' "$existing_tasks" | awk '
2348
+ # Keep non-task lines (subsection headers, comments, blank lines)
2349
+ !/^- \[[ x-]\] t/ { print; next }
2350
+ # For task lines: extract the ID and validate it is numeric
2351
+ {
2352
+ id = $0
2353
+ sub(/^- \[[ x-]\] /, "", id)
2354
+ sub(/ .*/, "", id)
2355
+ # Valid IDs: t followed by digits, optionally .digits (subtasks)
2356
+ if (id ~ /^t[0-9]+(\.[0-9]+)*$/) print
2357
+ }
2358
+ ')
2359
+ fi
2161
2360
  [[ "$backup" == "true" ]] && {
2162
2361
  cp "$todo_file" "${todo_file}.bak"
2163
2362
  print_success "Backup created: TODO.md.bak"
@@ -3279,6 +3478,7 @@ cmd_skills() {
3279
3478
  _help_commands() {
3280
3479
  echo "Commands:"
3281
3480
  echo " init [features] Initialize aidevops in current project"
3481
+ echo " init-routines Scaffold private routines repo (--org <name> | --local)"
3282
3482
  echo " upgrade-planning Upgrade TODO.md/PLANS.md to latest templates"
3283
3483
  echo " features List available features for init"
3284
3484
  echo " skill <cmd> Manage agent skills (add/list/check/update/remove)"
@@ -3293,8 +3493,10 @@ _help_commands() {
3293
3493
  echo " repo-sync <cmd> Daily git pull for repos in parent dirs (enable/disable/status/dirs)"
3294
3494
  echo " update-tools Check for outdated tools (--update to auto-update)"
3295
3495
  echo " repos [cmd] Manage registered projects (list/add/remove/clean)"
3296
- echo " model-accounts-pool OAuth account pool (list/check/add/rotate/reset-cooldowns)"
3496
+ echo " model-accounts-pool OAuth account pool (list/check/diagnose/add/rotate/reset-cooldowns)"
3497
+ echo " client-format Client request format alignment (extract/check/canary/monitor)"
3297
3498
  echo " opencode-sandbox Test OpenCode versions in isolation (install/run/check/clean)"
3499
+ echo " approve <cmd> Cryptographic issue/PR approval (setup/issue/pr/verify/status)"
3298
3500
  echo " security [cmd] Full security assessment (posture + hygiene + supply chain)"
3299
3501
  echo " ip-check <cmd> IP reputation checks (check/batch/report/providers)"
3300
3502
  echo " secret <cmd> Manage secrets (set/list/run/init/import/status)"
@@ -3331,6 +3533,7 @@ _help_detailed_sections() {
3331
3533
  echo " aidevops model-accounts-pool status # Pool health at a glance"
3332
3534
  echo " aidevops model-accounts-pool list # Per-account detail"
3333
3535
  echo " aidevops model-accounts-pool check # Live token validity test"
3536
+ echo " aidevops model-accounts-pool diagnose # Full pipeline diagnostics (pool, plugin, CCH, runtime)"
3334
3537
  echo " aidevops model-accounts-pool rotate [provider] # Switch to next available account NOW (use when rate-limited)"
3335
3538
  echo " aidevops model-accounts-pool reset-cooldowns # Clear rate-limit cooldowns"
3336
3539
  echo " aidevops model-accounts-pool add anthropic # Add Claude Pro/Max account"
@@ -3341,13 +3544,26 @@ _help_detailed_sections() {
3341
3544
  echo " aidevops model-accounts-pool assign-pending <provider># Assign stranded token"
3342
3545
  echo " aidevops model-accounts-pool remove <provider> <email># Remove an account"
3343
3546
  echo ""
3344
- echo " Auth recovery (run these in order if model is broken):"
3547
+ echo " Auth troubleshooting (run diagnose first, then recovery if needed):"
3548
+ echo " aidevops model-accounts-pool diagnose # 0. Full pipeline check (start here)"
3345
3549
  echo " aidevops model-accounts-pool status # 1. Check pool health"
3346
3550
  echo " aidevops model-accounts-pool check # 2. Test token validity"
3347
3551
  echo " aidevops model-accounts-pool rotate anthropic# 3. Switch account if rate-limited"
3348
3552
  echo " aidevops model-accounts-pool reset-cooldowns # 4. Clear cooldowns if all stuck"
3349
3553
  echo " aidevops model-accounts-pool add anthropic # 5. Re-add if pool empty"
3350
3554
  echo ""
3555
+ echo "Client Format:"
3556
+ echo " aidevops client-format # Show status + cached constants"
3557
+ echo " aidevops client-format extract # Re-extract constants from installed CLI"
3558
+ echo " aidevops client-format check # Verify cache matches installed CLI version"
3559
+ echo " aidevops client-format canary # Run drift check against real CLI (uses tokens)"
3560
+ echo " aidevops client-format monitor [cmd] # Traffic capture + diff (requires mitmproxy)"
3561
+ echo " aidevops client-format install-canary # Install daily drift check (launchd)"
3562
+ echo ""
3563
+ echo " If requests stop working after a CLI update:"
3564
+ echo " aidevops client-format extract # 1. Re-extract constants"
3565
+ echo " aidevops client-format canary # 2. Verify against real CLI"
3566
+ echo ""
3351
3567
  echo "Secrets:"
3352
3568
  echo " aidevops secret set NAME # Store a secret (hidden input)"
3353
3569
  echo " aidevops secret list # List secret names (never values)"
@@ -3585,10 +3801,53 @@ main() {
3585
3801
  detect | scan) cmd_detect ;;
3586
3802
  ip-check | ip_check) _dispatch_helper "ip-reputation-helper.sh" "ip-reputation-helper.sh" "$@" ;;
3587
3803
  model-accounts-pool | map) _dispatch_helper "oauth-pool-helper.sh" "oauth-pool-helper.sh" "$@" ;;
3804
+ client-format)
3805
+ case "${1:-status}" in
3806
+ extract | refresh)
3807
+ _dispatch_helper "cch-extract.sh" "cch-extract.sh" --cache
3808
+ ;;
3809
+ check | verify)
3810
+ _dispatch_helper "cch-extract.sh" "cch-extract.sh" --verify
3811
+ ;;
3812
+ canary | test)
3813
+ shift || true
3814
+ _dispatch_helper "cch-canary.sh" "cch-canary.sh" --verbose "$@"
3815
+ ;;
3816
+ monitor)
3817
+ shift || true
3818
+ _dispatch_helper "cch-traffic-monitor.sh" "cch-traffic-monitor.sh" "$@"
3819
+ ;;
3820
+ install-canary)
3821
+ _dispatch_helper "cch-canary.sh" "cch-canary.sh" --install
3822
+ ;;
3823
+ status | "")
3824
+ echo ""
3825
+ echo "Client request format alignment"
3826
+ echo "==============================="
3827
+ echo ""
3828
+ _dispatch_helper "cch-extract.sh" "cch-extract.sh" --verify 2>&1 || true
3829
+ echo ""
3830
+ if [[ -f "$HOME/.aidevops/cch-constants.json" ]]; then
3831
+ echo "Cached constants:"
3832
+ cat "$HOME/.aidevops/cch-constants.json"
3833
+ else
3834
+ echo "No cached constants. Run: aidevops client-format extract"
3835
+ fi
3836
+ ;;
3837
+ *)
3838
+ print_error "Unknown subcommand: $1"
3839
+ echo "Usage: aidevops client-format [extract|check|canary|monitor|install-canary|status]"
3840
+ exit 1
3841
+ ;;
3842
+ esac
3843
+ ;;
3588
3844
  opencode-sandbox | oc-sandbox) _dispatch_helper "opencode-sandbox-helper.sh" "opencode-sandbox-helper.sh" "$@" ;;
3589
3845
  secret | secrets) _dispatch_helper "secret-helper.sh" "secret-helper.sh" "$@" ;;
3846
+ approve) _dispatch_helper "approval-helper.sh" "approval-helper.sh" "$@" ;;
3847
+ signing) _dispatch_helper "signing-setup.sh" "signing-setup.sh" "$@" ;;
3590
3848
  stats | observability) _dispatch_helper "observability-helper.sh" "observability-helper.sh" "$@" ;;
3591
3849
  tabby) _dispatch_helper "tabby-helper.sh" "tabby-helper.sh" "$@" ;;
3850
+ init-routines) _dispatch_helper "init-routines-helper.sh" "init-routines-helper.sh" "$@" ;;
3592
3851
  config | configure) _dispatch_config "$@" ;;
3593
3852
  uninstall | remove) cmd_uninstall ;;
3594
3853
  version | v | -v | --version) cmd_version ;;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.5.896",
3
+ "version": "3.8.2",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "bin": {