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
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cortexlink",
"description": "Cross-agent workflow plugin — gives your agent the full programmatic reference for every CLI tool you use. One plugin. Every CLI. Stay in flow.",
"version": "0.5.5",
"version": "0.5.7",
"author": {
"name": "namos2502"
},
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

All notable changes to CortexLink will be documented here.

## [0.5.7] — 2026-03-24

### Improved
- **Commands:** Added `allowed-tools` frontmatter to `setup` (Read, Edit, Bash) and `cleanup` (Read, Edit) — prevents unexpected permission prompts during the most critical user interactions
- **Commands:** Fixed `help` command directive style — replaced indirect "Reply to the user with..." with direct output instruction
- **Skills:** All three skill descriptions rewritten to third-person trigger format ("This skill should be used when...") for reliable auto-activation
- **Skills:** Added `user-invocable: false` to `orchestration`, `copilot-cli`, and `claude-cli` skills — these are internal protocol skills, not user-invocable actions
- **Skills:** Split `orchestration/SKILL.md` (8.8 KB → 5.3 KB) — delegation prompt template and report format details extracted to `references/delegation-template.md` and `references/report-format.md` for progressive disclosure

## [0.5.6] — 2026-03-23

### Fixed
- Removed `-s` flag from all Copilot CLI invocation patterns — causes exit code 1, not a valid flag for programmatic use
- Copilot CLI sandbox fix: no `--cwd` flag exists; all invocations now `cd` to repo root first (`cd $(git rev-parse --show-toplevel) &&`) — prevents silent file access failures under `--no-ask-user` when invoked from a subdirectory
- `--allow-tool` values corrected to no-space format (`'write,read'`, `'write,shell(git:*),read'`)
- Model updated to `--model=claude-sonnet-4-5` for real tasks (was "omit"); `--model=claude-haiku-4.5` kept for availability checks only
- Claude CLI: added `--cwd $(git rev-parse --show-toplevel)` to all invocation patterns — same sandbox restriction applies
- Orchestration detection command: removed `-s`, added `cd` to repo root

## [0.5.5] — 2026-03-23

### Changed
Expand Down
1 change: 1 addition & 0 deletions commands/cleanup.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: "Remove CortexLink configuration added by /cortexlink:setup"
allowed-tools: Read, Edit
---

Remove the CortexLink sections that were added during setup. Run the following steps in order.
Expand Down
2 changes: 1 addition & 1 deletion commands/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
description: "Show CortexLink plugin information and how to get started"
---

Reply to the user with the following information:
Output the following to the user:

**CortexLink** — One plugin. Every CLI. Stay in flow.

Expand Down
1 change: 1 addition & 0 deletions commands/setup.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: "One-time setup — detects installed CLI agents, authenticates, and registers CortexLink as always-on in ~/.claude/CLAUDE.md and ~/.copilot/copilot-instructions.md"
allowed-tools: Read, Edit, Bash
---

Run the following steps in order and report the results clearly to the user.
Expand Down
16 changes: 16 additions & 0 deletions hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear|compact",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start",
"async": false
}
]
}
]
}
}
46 changes: 46 additions & 0 deletions hooks/run-hook.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
: << 'CMDBLOCK'
@echo off
REM Cross-platform polyglot wrapper for hook scripts.
REM On Windows: cmd.exe runs the batch portion, which finds and calls bash.
REM On Unix: the shell interprets this as a script (: is a no-op in bash).
REM
REM Hook scripts use extensionless filenames (e.g. "session-start" not
REM "session-start.sh") so Claude Code's Windows auto-detection -- which
REM prepends "bash" to any command containing .sh -- doesn't interfere.
REM
REM Usage: run-hook.cmd <script-name> [args...]

if "%~1"=="" (
echo run-hook.cmd: missing script name >&2
exit /b 1
)

set "HOOK_DIR=%~dp0"

REM Try Git for Windows bash in standard locations
if exist "C:\Program Files\Git\bin\bash.exe" (
"C:\Program Files\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
exit /b %ERRORLEVEL%
)
if exist "C:\Program Files (x86)\Git\bin\bash.exe" (
"C:\Program Files (x86)\Git\bin\bash.exe" "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
exit /b %ERRORLEVEL%
)

REM Try bash on PATH (e.g. user-installed Git Bash, MSYS2, Cygwin)
where bash >nul 2>nul
if %ERRORLEVEL% equ 0 (
bash "%HOOK_DIR%%~1" %2 %3 %4 %5 %6 %7 %8 %9
exit /b %ERRORLEVEL%
)

REM No bash found - exit silently rather than error
REM (plugin still works, just without SessionStart context injection)
exit /b 0
CMDBLOCK
Comment on lines +1 to +40
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Unix line endings (LF) may cause batch script failures on Windows.

The static analysis correctly identifies that this file uses LF line endings. Windows batch parser can malfunction with LF-only line endings, particularly around GOTO/CALL labels and the 512-byte boundary bug. Since this is a polyglot file designed to run on Windows, it should use CRLF line endings.

🔧 Recommended fix

Configure the file to use CRLF line endings. Add to .gitattributes:

+hooks/run-hook.cmd text eol=crlf

Or convert manually:

unix2dos hooks/run-hook.cmd
🧰 Tools
🪛 Blinter (1.0.112)

[error] 40-40: Unreachable code after EXIT or GOTO. Explanation: Code after EXIT or GOTO statements will never execute. Recommendation: Remove unreachable code or restructure script logic. Context: Code after EXIT on line 39 will never execute

(E008)


[error] 1-1: Unix line endings detected. Explanation: Batch file uses Unix line endings (LF-only) which can cause GOTO/CALL label parsing failures and script malfunction due to Windows batch parser 512-byte boundary bugs. Recommendation: Convert file to Windows line endings (CRLF). Use tools like dos2unix, notepad++, or configure git with 'git config core.autocrlf true'. Context: File uses Unix line endings (LF-only) - 46 LF sequences found

(E018)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/run-hook.cmd` around lines 1 - 40, The hook wrapper batch file uses
LF-only line endings which can break cmd.exe parsing; convert hooks/run-hook.cmd
to CRLF line endings and add a .gitattributes entry to enforce CRLF for this
file so Windows batch parsing is reliable (target the file that defines set
"HOOK_DIR=%~dp0" and the subsequent bash detection/exit logic including the
final "exit /b 0"). Ensure the repository normalization is updated so future
commits preserve CRLF for this file.


# Unix: run the named script directly
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPT_NAME="$1"
shift
exec bash "${SCRIPT_DIR}/${SCRIPT_NAME}" "$@"
45 changes: 45 additions & 0 deletions hooks/session-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# SessionStart hook for CortexLink plugin

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

# Read orchestration skill — the CortexLink meta skill
orchestration_content=$(cat "${PLUGIN_ROOT}/skills/orchestration/SKILL.md" 2>&1 || echo "Error reading orchestration skill")

# Escape string for JSON embedding.
# Each ${s//old/new} is a single C-level pass — fast and heredoc-safe.
escape_for_json() {
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//$'\n'/\\n}"
s="${s//$'\r'/\\r}"
s="${s//$'\t'/\\t}"
printf '%s' "$s"
}

orchestration_escaped=$(escape_for_json "$orchestration_content")

peer_direction="PEER DIRECTION RULES (apply these every time you delegate):\n- If you are Claude Code (Claude): GitHub tasks → Copilot CLI. Isolated code/analysis tasks → Claude CLI (last resort only — prefer native tools first).\n- If you are Copilot CLI: code tasks, analysis, and refactors → Claude CLI.\n- ONE agent per subtask. Never route the same subtask to more than one agent.\n- Always use bash with -p flag (programmatic mode). Never open an interactive terminal session.\n- Violating any of these rules violates the spirit of CortexLink."

session_context="<EXTREMELY_IMPORTANT>\nYou have CortexLink — a cross-agent workflow plugin.\n\nBelow is your orchestration skill. It defines when and how to delegate tasks across CLI agents (Copilot CLI, Claude CLI). Follow it whenever multi-agent delegation could apply.\n\n${orchestration_escaped}\n\n${peer_direction}\n</EXTREMELY_IMPORTANT>"

Comment on lines +10 to +29
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Session context injection is incomplete after protocol split.

Line 10 only loads skills/orchestration/SKILL.md, but that file now defers critical instructions to skills/orchestration/references/delegation-template.md and skills/orchestration/references/report-format.md. In cold-start sessions, this leaves unresolved references and weakens delegation/report consistency.

Proposed fix
-# Read orchestration skill — the CortexLink meta skill
-orchestration_content=$(cat "${PLUGIN_ROOT}/skills/orchestration/SKILL.md" 2>&1 || echo "Error reading orchestration skill")
+read_required_file() {
+    local path="$1"
+    if [ ! -r "$path" ]; then
+        printf 'session-start: required file missing or unreadable: %s\n' "$path" >&2
+        exit 1
+    fi
+    cat "$path"
+}
+
+# Read orchestration skill + extracted required references
+orchestration_content="$(read_required_file "${PLUGIN_ROOT}/skills/orchestration/SKILL.md")"
+delegation_template_content="$(read_required_file "${PLUGIN_ROOT}/skills/orchestration/references/delegation-template.md")"
+report_format_content="$(read_required_file "${PLUGIN_ROOT}/skills/orchestration/references/report-format.md")"
+
+combined_orchestration_context="${orchestration_content}
+
+## Reference: Delegation Template
+${delegation_template_content}
+
+## Reference: Report Format
+${report_format_content}"
 
-orchestration_escaped=$(escape_for_json "$orchestration_content")
+orchestration_escaped=$(escape_for_json "$combined_orchestration_context")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/session-start` around lines 10 - 29, The session context currently only
reads SKILL.md into orchestration_content, leaving out the now-separated
references; update the logic that builds orchestration_content (the variable
populated before escape_for_json) to also read and append the files
skills/orchestration/references/delegation-template.md and
skills/orchestration/references/report-format.md (with the same error-safe
pattern used for SKILL.md), then pass the combined content to escape_for_json to
produce orchestration_escaped so session_context contains the full orchestration
skill plus the delegation and report-format references; keep the same error
fallback messages and formatting (including peer_direction) and reuse
escape_for_json as-is.

# Platform detection: emit the field consumed by the current platform only.
# Claude Code and Copilot CLI both set CLAUDE_PLUGIN_ROOT (shared plugin architecture).
# Cursor IDE sets CURSOR_PLUGIN_ROOT (not a supported CortexLink platform — kept as fallback).
# Emitting both fields would cause double injection in Claude Code.
#
# Uses printf instead of heredoc to avoid a bash 5.3+ bug where heredoc
# variable expansion hangs when content exceeds ~512 bytes.
if [ -n "${CURSOR_PLUGIN_ROOT:-}" ]; then
printf '{\n "additional_context": "%s"\n}\n' "$session_context"
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
printf '{\n "hookSpecificOutput": {\n "hookEventName": "SessionStart",\n "additionalContext": "%s"\n }\n}\n' "$session_context"
else
printf '{\n "additional_context": "%s"\n}\n' "$session_context"
fi

exit 0
52 changes: 42 additions & 10 deletions skills/agents/claude-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
---
name: claude-cli
description: Behavioral reference for Claude CLI. Use when delegating general code tasks, analysis, or tasks requiring Anthropic-native reasoning via `claude -p`.

description: This skill should be used when delegating general code tasks — explanations, refactors, fixes, analysis — via `claude -p`. Also use when context isolation or a specific Anthropic model is needed for the subtask.
user-invocable: false
---

# Claude CLI Agent

## When to Use

⛔ If the host is **Claude Code**: use Claude CLI only when you specifically need context isolation or a different Anthropic model AND native tools (Task tool, inline work) are insufficient. Claude Code → Claude CLI is last resort. Prefer Copilot CLI for GitHub tasks; prefer Claude Code's native Task tool for general code tasks.

---

**Use Claude CLI for:**
- General code tasks — explanations, refactors, fixes, analysis
- Tasks needing Anthropic-specific models (Sonnet, Opus, Haiku)
Expand Down Expand Up @@ -66,39 +70,65 @@ Shell access (`Bash(...)`) is a separate, deliberate decision. Use `--disallowed

Use short aliases (`sonnet`, `opus`) for the latest version, or full IDs (e.g. `claude-sonnet-4-6`) to pin a specific model.

## Working Directory

Claude CLI is sandboxed to its working directory — the same restriction as Copilot CLI.

⛔ **Always invoke from the repo root.** Use `--cwd` or `cd` before invoking.

```bash
claude -p "..." --cwd $(git rev-parse --show-toplevel) --output-format text ...
```

## Invocation Patterns

Always include `--append-system-prompt` with the CortexLink agent context below. This teaches the agent the report format and self-verify protocol via the system prompt — separate from the task prompt.

```
CORTEXLINK_AGENT_CONTEXT="You are operating as a CortexLink agent. Your output is consumed directly by a control center. Execute the task, verify your own work (Execute → Verify → fix if needed → Report), then return ONLY this structured report — plain text labels, no bold, no headers:\nSTATUS: ✅ Verified / ⚠️ Partial / ❌ Failed\nSUMMARY: <1-2 sentences>\nSTEPS:\n - <step>\nFILES: <changed files or none>\nISSUES: <notes or none>\nMax 150 words. Never mark ✅ without actually checking. For analysis tasks, ✅ = completed the analysis even if you cannot run the code."
```
Comment on lines +87 to +89
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language tag to the fenced context block.

Line 87 starts an unlabeled fenced block (MD040).

Proposed fix
-```
+```text
 CORTEXLINK_AGENT_CONTEXT="You are operating as a CortexLink agent. Your output is consumed directly by a control center. Execute the task, verify your own work (Execute → Verify → fix if needed → Report), then return ONLY this structured report — plain text labels, no bold, no headers:\nSTATUS: ✅ Verified / ⚠️ Partial / ❌ Failed\nSUMMARY: <1-2 sentences>\nSTEPS:\n  - <step>\nFILES: <changed files or none>\nISSUES: <notes or none>\nMax 150 words. Never mark ✅ without actually checking. For analysis tasks, ✅ = completed the analysis even if you cannot run the code."
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>

[warning] 87-87: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @skills/agents/claude-cli/SKILL.md around lines 87 - 89, The markdown fenced
block containing the CORTEXLINK_AGENT_CONTEXT string is missing a language tag;
update the fenced code block that begins with the CORTEXLINK_AGENT_CONTEXT
payload in SKILL.md to include a language identifier (e.g., add "text" after the
opening ```) so the block is labeled (fixes MD040) and preserves the exact
content of the CORTEXLINK_AGENT_CONTEXT string and escapes.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->


**Read-only delegation (question, analysis):**
```bash
claude -p "[delegation prompt]" --output-format text \
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" --model claude-haiku-4-5 \
--no-session-persistence --max-turns 3
--no-session-persistence --max-turns 3 \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT"
```

**Write delegation (fix, implement):**
```bash
claude -p "[delegation prompt]" --output-format text \
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" "Edit" "Write" \
--no-session-persistence
--no-session-persistence \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT"
```

**Write delegation + shell (runs commands):**
```bash
claude -p "[delegation prompt]" --output-format text \
--allowedTools "Read" "Edit" "Bash(git *)" \
--no-session-persistence
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" "Edit" "Write" "Bash(git *)" \
--no-session-persistence \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT"
```

**Planning / analysis only (no writes):**
```bash
claude -p "[delegation prompt]" --output-format text \
--permission-mode plan --no-session-persistence --max-turns 5
--cwd $(git rev-parse --show-toplevel) \
--permission-mode plan --no-session-persistence --max-turns 5 \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT"
```

**Piped input:**
```bash
cat file.ts | claude -p "[delegation prompt]" --output-format text \
--allowedTools "Read" --no-session-persistence
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" --no-session-persistence \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT"
```

## Delegation Prompt
Expand All @@ -116,7 +146,9 @@ Follow the template from `skills/orchestration/SKILL.md`. Include the structured

The agent's stdout is its report. Capture it directly:
```bash
REPORT=$(claude -p "[prompt]" --output-format text --allowedTools "Read" --no-session-persistence 2>/dev/null)
REPORT=$(claude -p "[prompt]" --output-format text \
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" --no-session-persistence 2>/dev/null)
Comment on lines +149 to +151
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

REPORT=$(...) example is missing the required system prompt context.

Line 149 captures output without --append-system-prompt "$CORTEXLINK_AGENT_CONTEXT", which conflicts with the requirement defined at Line 85 and can break structured-report compliance.

Proposed fix
 REPORT=$(claude -p "[prompt]" --output-format text \
   --cwd $(git rev-parse --show-toplevel) \
-  --allowedTools "Read" --no-session-persistence 2>/dev/null)
+  --allowedTools "Read" --no-session-persistence \
+  --append-system-prompt "$CORTEXLINK_AGENT_CONTEXT" 2>/dev/null)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
REPORT=$(claude -p "[prompt]" --output-format text \
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" --no-session-persistence 2>/dev/null)
REPORT=$(claude -p "[prompt]" --output-format text \
--cwd $(git rev-parse --show-toplevel) \
--allowedTools "Read" --no-session-persistence \
--append-system-prompt "$CORTEXLINK_AGENT_CONTEXT" 2>/dev/null)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/agents/claude-cli/SKILL.md` around lines 149 - 151, The example that
assigns REPORT is missing the required system prompt flag; update the claude
invocation used for REPORT=$(...) to include --append-system-prompt
"$CORTEXLINK_AGENT_CONTEXT" so it matches the requirement enforced earlier (see
the variable CORTEXLINK_AGENT_CONTEXT and the claude CLI usage); ensure the
command still retains --output-format text, --cwd $(git rev-parse
--show-toplevel), --allowedTools "Read" and --no-session-persistence while
appending the system prompt to preserve structured-report compliance.

```

Read STATUS first. If ⚠️ or ❌, read ISSUES before deciding next action.
Expand All @@ -126,8 +158,8 @@ Read STATUS first. If ⚠️ or ❌, read ISSUES before deciding next action.
| | Copilot CLI | Claude CLI |
|--|-------------|------------|
| Tool permissions | `--allow-tool='write, read'` | `--allowedTools "Read" "Edit"` |
| Silence | `-s` | `--output-format text` |
| Prevent questions | `--no-ask-user` | implied by `-p` |
| Working directory | `cd $(git rev-parse --show-toplevel) &&` | `--cwd PATH` |
| Model flag | `--model=claude-haiku-4.5` | `--model claude-haiku-4-5` |

## Error Handling
Expand Down
Loading