Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/test-ansible-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,76 @@ jobs:
# Test basic functionality
echo "✅ First installation completed successfully"

- name: Validate RTK integration (first run)
run: |
echo "=== Validating RTK integration ==="

# Check that rtk command is available (installed via Homebrew)
if ! command -v rtk >/dev/null 2>&1; then
echo "❌ rtk command not found"
exit 1
fi
echo "✅ rtk command is available"

# Check that GitHub Copilot Chat hooks directory was created and populated (VS Code)
if [ ! -d "${HOME}/.github/hooks" ]; then
echo "❌ ~/.github/hooks directory not found"
exit 1
fi

if ! find "${HOME}/.github/hooks" -mindepth 1 -print -quit | grep -q .; then
echo "❌ ~/.github/hooks directory is empty"
exit 1
fi
echo "✅ ~/.github/hooks directory exists and contains hook files"
# Check that RTK instructions were injected into copilot-instructions.md (VS Code)
if [ ! -f "${HOME}/.github/copilot-instructions.md" ]; then
echo "❌ ~/.github/copilot-instructions.md not found"
exit 1
fi
echo "✅ ~/.github/copilot-instructions.md exists"

if ! grep -q "BEGIN RTK MANAGED BLOCK" "${HOME}/.github/copilot-instructions.md"; then
echo "❌ RTK managed block not found in ~/.github/copilot-instructions.md"
exit 1
fi
echo "✅ RTK managed block present in ~/.github/copilot-instructions.md"

# Check that Copilot CLI hooks directory was created and populated (~/.copilot/)
if [ ! -d "${HOME}/.copilot/hooks" ]; then
echo "❌ ~/.copilot/hooks directory not found"
exit 1
fi

if ! find "${HOME}/.copilot/hooks" -mindepth 1 -print -quit | grep -q .; then
echo "❌ ~/.copilot/hooks directory is empty"
exit 1
fi
echo "✅ ~/.copilot/hooks directory exists and contains hook files"

# Check that RTK instructions were injected into Copilot CLI copilot-instructions.md
if [ ! -f "${HOME}/.copilot/copilot-instructions.md" ]; then
echo "❌ ~/.copilot/copilot-instructions.md not found"
exit 1
fi
echo "✅ ~/.copilot/copilot-instructions.md exists"

if ! grep -q "BEGIN RTK MANAGED BLOCK" "${HOME}/.copilot/copilot-instructions.md"; then
echo "❌ RTK managed block not found in ~/.copilot/copilot-instructions.md"
exit 1
fi
echo "✅ RTK managed block present in ~/.copilot/copilot-instructions.md"

echo "✅ RTK integration validated successfully"

- name: Add user content to copilot-instructions.md before second run
run: |
echo "# My custom instructions" >> "${HOME}/.github/copilot-instructions.md"
echo "This user content must survive re-provisioning." >> "${HOME}/.github/copilot-instructions.md"
echo "# My custom instructions" >> "${HOME}/.copilot/copilot-instructions.md"
echo "This user content must survive re-provisioning." >> "${HOME}/.copilot/copilot-instructions.md"
echo "✅ User content added before second run"

- name: Fix ownership permissions and clean git state before second run
run: |
echo "=== Fixing ownership permissions and git state for second run ==="
Expand Down Expand Up @@ -143,6 +213,42 @@ jobs:

echo "✅ Second installation completed successfully - installer is idempotent"

- name: Validate RTK idempotency (second run)
run: |
echo "=== Validating RTK idempotency ==="

# VS Code path: BEGIN marker must appear exactly once
MARKER_COUNT=$(grep -c "BEGIN RTK MANAGED BLOCK" "${HOME}/.github/copilot-instructions.md" || true)
if [ "${MARKER_COUNT}" -ne 1 ]; then
echo "❌ RTK managed block appears ${MARKER_COUNT} time(s) in ~/.github/copilot-instructions.md (expected 1) - idempotency broken"
exit 1
fi
echo "✅ RTK managed block appears exactly once in ~/.github/copilot-instructions.md — idempotency confirmed"

# VS Code path: user content must still be present
if ! grep -q "My custom instructions" "${HOME}/.github/copilot-instructions.md"; then
echo "❌ User content was lost from ~/.github/copilot-instructions.md after re-provisioning"
exit 1
fi
echo "✅ User content preserved in ~/.github/copilot-instructions.md after re-provisioning"

# Copilot CLI path: BEGIN marker must appear exactly once
MARKER_COUNT=$(grep -c "BEGIN RTK MANAGED BLOCK" "${HOME}/.copilot/copilot-instructions.md" || true)
if [ "${MARKER_COUNT}" -ne 1 ]; then
echo "❌ RTK managed block appears ${MARKER_COUNT} time(s) in ~/.copilot/copilot-instructions.md (expected 1) - idempotency broken"
exit 1
fi
echo "✅ RTK managed block appears exactly once in ~/.copilot/copilot-instructions.md — idempotency confirmed"

# Copilot CLI path: user content must still be present
if ! grep -q "My custom instructions" "${HOME}/.copilot/copilot-instructions.md"; then
echo "❌ User content was lost from ~/.copilot/copilot-instructions.md after re-provisioning"
exit 1
fi
echo "✅ User content preserved in ~/.copilot/copilot-instructions.md after re-provisioning"

echo "✅ RTK idempotency validated successfully"

- name: Clean up test installations (optional)
if: always()
run: |
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added RTK (Rust Token Killer) to default package list and Ansible provisioning: installs via `brew install rtk` and runs `rtk init --copilot --auto-patch` for GitHub Copilot (writing RTK hooks and instructions to both `~/.github/` for VS Code Copilot Chat and `~/.copilot/` for Copilot CLI) and `rtk init -g --opencode --auto-patch` for OpenCode to activate the token-optimization hook (60-90% token savings on common dev commands)
- Added `~/.local/bin` to default zsh PATH for user-local binaries (XDG convention), auto-creating the directory if missing
- Added orphan cleanup to `sparkdock-agents-sync`: detects and removes managed skills/agent profiles no longer in upstream, with `--force` to remove locally modified orphans
- Added orphan detection to `sparkdock-agents-status`: flags resources removed from upstream as `orphan` type with cleanup hint
Expand Down
78 changes: 78 additions & 0 deletions ansible/macos/macos/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,84 @@
- openspec_completion_output is not skipped
- openspec_completion_output.rc == 0

- name: Configure RTK for LLM token optimization
tags: rtk
block:
# --- GitHub Copilot ---
- name: Initialize RTK for GitHub Copilot in temp directory
shell: |
RTK_TMPDIR=$(mktemp -d)
cd "${RTK_TMPDIR}"
rtk init --copilot --auto-patch > /dev/null 2>&1
echo "${RTK_TMPDIR}"
register: rtk_copilot_tmpdir
changed_when: true
become: false

- name: Ensure GitHub Copilot Chat hooks directory exists (VS Code)
file:
path: "{{ ansible_facts['env']['HOME'] }}/.github/hooks"
state: directory
mode: '0755'
become: false

- name: Copy RTK hooks to GitHub Copilot Chat config (VS Code)
copy:
src: "{{ rtk_copilot_tmpdir.stdout }}/.github/hooks/"
dest: "{{ ansible_facts['env']['HOME'] }}/.github/hooks/"
remote_src: true
become: false
ignore_errors: yes

- name: Inject RTK instructions into Copilot copilot-instructions.md (VS Code)
blockinfile:
path: "{{ ansible_facts['env']['HOME'] }}/.github/copilot-instructions.md"
marker: "<!-- {mark} RTK MANAGED BLOCK -->"
block: "{{ lookup('file', rtk_copilot_tmpdir.stdout + '/.github/copilot-instructions.md') }}"
create: yes
become: false

# --- Copilot CLI paths (~/.copilot/) ---
- name: Ensure Copilot CLI hooks directory exists
file:
path: "{{ ansible_facts['env']['HOME'] }}/.copilot/hooks"
state: directory
mode: '0755'
become: false

- name: Copy RTK hooks to Copilot CLI config
copy:
src: "{{ rtk_copilot_tmpdir.stdout }}/.github/hooks/"
dest: "{{ ansible_facts['env']['HOME'] }}/.copilot/hooks/"
remote_src: true
become: false

- name: Inject RTK instructions into Copilot CLI copilot-instructions.md
blockinfile:
path: "{{ ansible_facts['env']['HOME'] }}/.copilot/copilot-instructions.md"
marker: "<!-- {mark} RTK MANAGED BLOCK -->"
block: "{{ lookup('file', rtk_copilot_tmpdir.stdout + '/.github/copilot-instructions.md') }}"
create: yes
become: false

- name: Cleanup GitHub Copilot temp directory
file:
path: "{{ rtk_copilot_tmpdir.stdout }}"
state: absent
become: false

# --- OpenCode ---
- name: Initialize RTK for OpenCode
command: rtk init -g --opencode --auto-patch
register: rtk_opencode_result
changed_when: true
failed_when: rtk_opencode_result.rc != 0
become: false

- name: Display RTK initialization status
debug:
msg: "✅ RTK initialized for GitHub Copilot and OpenCode. Restart your AI coding tools to activate."
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@francescoben I want to move all that logic into a sjust task (the shared one) and a reusable install script, so that we can:

  1. Manual re-run from sjust
  2. Easy to integrate in the archlinux provisioner @Monska85

@francescoben


- name: Sync AI coding agent resources from upstream repository
tags:
- skills
Expand Down
1 change: 1 addition & 0 deletions config/packages/all-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ homebrew_packages:
- mas
- gh
- glab
- rtk
- "node"
- "[email protected]"
- golang
Expand Down
Loading