ask-colleague 0.1.0
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/CONTRIBUTING.md +38 -0
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/bin/colleague +675 -0
- package/docs/publishing.md +154 -0
- package/docs/security.md +63 -0
- package/install.sh +254 -0
- package/package.json +50 -0
- package/prompts/colleague.md +41 -0
- package/scripts/ask-claude.sh +9 -0
- package/scripts/ask-codex.sh +9 -0
- package/skills/claude/colleague/SKILL.md +61 -0
- package/skills/codex/colleague/SKILL.md +60 -0
- package/skills/codex/colleague/agents/openai.yaml +5 -0
- package/snippets/AGENTS.md +24 -0
- package/snippets/CLAUDE.md +22 -0
- package/templates/context.md +42 -0
- package/uninstall.sh +165 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: colleague
|
|
3
|
+
description: Consult Claude Code as a second local AI coding agent for a one-shot peer review when explicitly requested.
|
|
4
|
+
argument-hint: "[question]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Colleague: ask Claude Code for advice
|
|
8
|
+
|
|
9
|
+
Use this skill only when the user explicitly asks to "ask Claude", "ask a colleague", or "get a second opinion". It gets a one-shot second opinion from Claude Code without letting it take over the repo.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. Create a private, unpredictable temp file with `mktemp`, and clean it up after use:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ctx="$(mktemp -t colleague-ctx.XXXXXX.md)"
|
|
17
|
+
trap 'rm -f "$ctx"' EXIT
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Write a compact briefing into `$ctx`. Include only what Claude needs:
|
|
21
|
+
|
|
22
|
+
- user-facing goal
|
|
23
|
+
- relevant file paths and short snippets
|
|
24
|
+
- what you have already tried
|
|
25
|
+
- exact error, dilemma, or design choice
|
|
26
|
+
- constraints and non-goals
|
|
27
|
+
|
|
28
|
+
Do not dump the raw conversation transcript, tool logs, `.env` files, API keys, private URLs, tokens, or credentials. Summarize aggressively.
|
|
29
|
+
|
|
30
|
+
3. Ask Claude with the installed bridge:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
colleague ask claude \
|
|
34
|
+
--context "$ctx" \
|
|
35
|
+
--question "What is the strongest critique of my current plan?"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use `--model <model>` only when the user asks for a specific model. The bridge calls Claude in print mode with no session persistence, one max turn, `--bare`, and `--tools ""`.
|
|
39
|
+
|
|
40
|
+
4. Treat the response as peer advice, not ground truth. Compare it to your own analysis.
|
|
41
|
+
|
|
42
|
+
5. In your response to the user, say that you consulted Claude, then explain where you agree, disagree, or remain uncertain. Continue with the implementation or recommendation using your own judgment.
|
|
43
|
+
|
|
44
|
+
## Good briefing template
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
# Goal
|
|
48
|
+
|
|
49
|
+
# Relevant files and snippets
|
|
50
|
+
|
|
51
|
+
# What I tried
|
|
52
|
+
|
|
53
|
+
# Current error or dilemma
|
|
54
|
+
|
|
55
|
+
# Constraints / non-goals
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## When not to use this skill
|
|
59
|
+
|
|
60
|
+
Do not use it for simple questions you can answer directly. Do not use it to outsource user-private or secret material. Do not start a multi-turn agent-to-agent loop; if the answer misses, improve the briefing and ask once more.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- BEGIN ask-colleague bridge -->
|
|
2
|
+
## Colleague bridge
|
|
3
|
+
|
|
4
|
+
A `colleague` CLI may be available for a one-shot second opinion from Claude Code. Use it only when the user explicitly asks to "ask Claude", "ask a colleague", or after you have made a concrete attempt and are genuinely blocked.
|
|
5
|
+
|
|
6
|
+
Procedure:
|
|
7
|
+
|
|
8
|
+
1. Create a private temp file and clean it up after use:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
ctx="$(mktemp -t colleague-ctx.XXXXXX.md)"
|
|
12
|
+
trap 'rm -f "$ctx"' EXIT
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
2. Write a compact context briefing into `$ctx`. Include the goal, relevant file paths/snippets, what has been tried, the exact error or dilemma, and constraints. Do not include secrets or raw transcripts.
|
|
16
|
+
|
|
17
|
+
3. Run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
colleague ask claude --context "$ctx" --question "your specific question"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
4. Treat Claude's response as advice from a peer, not ground truth. Compare it to your own analysis before acting. Do not start a nested or multi-turn agent-to-agent loop.
|
|
24
|
+
<!-- END ask-colleague bridge -->
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Colleague bridge
|
|
2
|
+
|
|
3
|
+
A `colleague` CLI may be available for a one-shot second opinion from Codex. Use it only when the user explicitly asks to "ask Codex", "ask a colleague", or after you have made a concrete attempt and are genuinely blocked.
|
|
4
|
+
|
|
5
|
+
Procedure:
|
|
6
|
+
|
|
7
|
+
1. Create a private temp file and clean it up after use:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
ctx="$(mktemp -t colleague-ctx.XXXXXX.md)"
|
|
11
|
+
trap 'rm -f "$ctx"' EXIT
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. Write a compact context briefing into `$ctx`. Include the goal, relevant file paths/snippets, what has been tried, the exact error or dilemma, and constraints. Do not include secrets or raw transcripts.
|
|
15
|
+
|
|
16
|
+
3. Run:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
colleague ask codex --context "$ctx" --question "your specific question"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
4. Treat Codex's response as advice from a peer, not ground truth. Compare it to your own analysis before acting. Do not start a nested or multi-turn agent-to-agent loop.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Colleague briefing
|
|
2
|
+
|
|
3
|
+
Use this with a private temp file, for example:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
ctx="$(mktemp -t colleague-ctx.XXXXXX.md)"
|
|
7
|
+
trap 'rm -f "$ctx"' EXIT
|
|
8
|
+
colleague make-context --output "$ctx"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
Explain the user-facing goal in 2-5 sentences.
|
|
14
|
+
|
|
15
|
+
## Relevant files and snippets
|
|
16
|
+
|
|
17
|
+
Include file paths and only the snippets needed for the peer to reason.
|
|
18
|
+
Summarize large files rather than dumping them.
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
path/to/file.ext
|
|
22
|
+
short snippet or description
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What has been tried
|
|
26
|
+
|
|
27
|
+
- Attempt 1:
|
|
28
|
+
- Attempt 2:
|
|
29
|
+
|
|
30
|
+
## Current error, dilemma, or design choice
|
|
31
|
+
|
|
32
|
+
Paste the exact error message or the decision being debated.
|
|
33
|
+
|
|
34
|
+
## Constraints and non-goals
|
|
35
|
+
|
|
36
|
+
- Runtime / framework / compatibility constraints:
|
|
37
|
+
- Security or privacy constraints:
|
|
38
|
+
- Non-goals:
|
|
39
|
+
|
|
40
|
+
## Question for the peer
|
|
41
|
+
|
|
42
|
+
What should the primary agent double-check, change, or avoid?
|
package/uninstall.sh
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PREFIX="${PREFIX:-$HOME/.local}"
|
|
5
|
+
STATE_DIR="${COLLEAGUE_STATE_DIR:-$HOME/.ask-colleague}"
|
|
6
|
+
MANIFEST="$STATE_DIR/install-manifest.tsv"
|
|
7
|
+
DRY_RUN=0
|
|
8
|
+
FORCE=0
|
|
9
|
+
|
|
10
|
+
AGENTS_BEGIN_MARK='<!-- BEGIN ask-colleague bridge -->'
|
|
11
|
+
AGENTS_END_MARK='<!-- END ask-colleague bridge -->'
|
|
12
|
+
|
|
13
|
+
usage() {
|
|
14
|
+
cat <<'USAGE'
|
|
15
|
+
Usage: colleague uninstall [--prefix DIR] [--force] [--dry-run]
|
|
16
|
+
./uninstall.sh [--prefix DIR] [--force] [--dry-run]
|
|
17
|
+
|
|
18
|
+
By default, uninstall reads ~/.ask-colleague/install-manifest.tsv and removes
|
|
19
|
+
only files that this package installed and that have not been modified.
|
|
20
|
+
|
|
21
|
+
Use --force only for legacy installs without a manifest or to remove modified
|
|
22
|
+
ask-colleague files intentionally.
|
|
23
|
+
USAGE
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
die() { printf 'uninstall: %s\n' "$*" >&2; exit 1; }
|
|
27
|
+
have() { command -v "$1" >/dev/null 2>&1; }
|
|
28
|
+
|
|
29
|
+
need_value() {
|
|
30
|
+
local opt="$1"
|
|
31
|
+
local val="${2-}"
|
|
32
|
+
if [[ -z "$val" || "$val" == --* ]]; then
|
|
33
|
+
die "$opt requires a value"
|
|
34
|
+
fi
|
|
35
|
+
printf '%s\n' "$val"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
run() {
|
|
39
|
+
if [[ "$DRY_RUN" == "1" ]]; then
|
|
40
|
+
printf '+ %q' "$1"
|
|
41
|
+
shift
|
|
42
|
+
local arg
|
|
43
|
+
for arg in "$@"; do
|
|
44
|
+
printf ' %q' "$arg"
|
|
45
|
+
done
|
|
46
|
+
printf '\n'
|
|
47
|
+
else
|
|
48
|
+
"$@"
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
checksum_file() {
|
|
53
|
+
local file="$1"
|
|
54
|
+
if have sha256sum; then
|
|
55
|
+
sha256sum "$file" | awk '{print $1}'
|
|
56
|
+
elif have shasum; then
|
|
57
|
+
shasum -a 256 "$file" | awk '{print $1}'
|
|
58
|
+
else
|
|
59
|
+
cksum "$file" | awk '{print $1 "-" $2}'
|
|
60
|
+
fi
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
strip_agents_block() {
|
|
64
|
+
local agents="$HOME/.codex/AGENTS.md"
|
|
65
|
+
[[ -f "$agents" ]] || return 0
|
|
66
|
+
grep -qF "$AGENTS_BEGIN_MARK" "$agents" || return 0
|
|
67
|
+
|
|
68
|
+
local tmp
|
|
69
|
+
tmp="$(mktemp)"
|
|
70
|
+
if ! awk -v begin="$AGENTS_BEGIN_MARK" -v end="$AGENTS_END_MARK" '
|
|
71
|
+
index($0, begin) { skipping = 1; next }
|
|
72
|
+
skipping && index($0, end) { skipping = 0; next }
|
|
73
|
+
!skipping { print }
|
|
74
|
+
END { if (skipping) exit 2 }
|
|
75
|
+
' "$agents" > "$tmp"; then
|
|
76
|
+
rm -f "$tmp"
|
|
77
|
+
printf 'Refusing to strip incomplete ask-colleague block from %s: missing end marker.\n' "$agents" >&2
|
|
78
|
+
return 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if [[ "$DRY_RUN" == "1" ]]; then
|
|
82
|
+
rm -f "$tmp"
|
|
83
|
+
printf '+ strip colleague block from %q\n' "$agents"
|
|
84
|
+
return 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
mv "$tmp" "$agents"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
legacy_force_uninstall() {
|
|
91
|
+
run rm -f "$PREFIX/bin/colleague" "$PREFIX/bin/ask-colleague"
|
|
92
|
+
run rm -f "$HOME/.claude/skills/colleague/SKILL.md"
|
|
93
|
+
run rm -f "$HOME/.agents/skills/colleague/SKILL.md" "$HOME/.agents/skills/colleague/agents/openai.yaml"
|
|
94
|
+
run rmdir "$HOME/.agents/skills/colleague/agents" 2>/dev/null || true
|
|
95
|
+
run rmdir "$HOME/.agents/skills/colleague" 2>/dev/null || true
|
|
96
|
+
run rmdir "$HOME/.claude/skills/colleague" 2>/dev/null || true
|
|
97
|
+
run rm -f "$HOME/.codex/prompts/colleague.md"
|
|
98
|
+
strip_agents_block
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
while [[ $# -gt 0 ]]; do
|
|
102
|
+
case "$1" in
|
|
103
|
+
--prefix)
|
|
104
|
+
PREFIX="$(need_value "$1" "${2-}")"; shift 2 ;;
|
|
105
|
+
--force)
|
|
106
|
+
FORCE=1; shift ;;
|
|
107
|
+
--dry-run)
|
|
108
|
+
DRY_RUN=1; shift ;;
|
|
109
|
+
-h|--help)
|
|
110
|
+
usage; exit 0 ;;
|
|
111
|
+
*)
|
|
112
|
+
echo "Unknown option: $1" >&2; usage >&2; exit 2 ;;
|
|
113
|
+
esac
|
|
114
|
+
done
|
|
115
|
+
|
|
116
|
+
[[ -n "$PREFIX" ]] || die "--prefix cannot be empty"
|
|
117
|
+
|
|
118
|
+
if [[ ! -f "$MANIFEST" ]]; then
|
|
119
|
+
if [[ "$FORCE" == "1" ]]; then
|
|
120
|
+
printf 'No install manifest found; performing legacy forced uninstall.\n' >&2
|
|
121
|
+
legacy_force_uninstall
|
|
122
|
+
exit 0
|
|
123
|
+
fi
|
|
124
|
+
printf 'No install manifest found at %s.\n' "$MANIFEST" >&2
|
|
125
|
+
printf 'Refusing to remove unknown files. Re-run with --force for a legacy uninstall.\n' >&2
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
failures=0
|
|
130
|
+
while IFS=$'\t' read -r entry_type recorded_checksum path; do
|
|
131
|
+
[[ -n "${entry_type:-}" ]] || continue
|
|
132
|
+
case "$entry_type" in
|
|
133
|
+
file)
|
|
134
|
+
[[ -e "$path" ]] || continue
|
|
135
|
+
if [[ "$FORCE" != "1" ]]; then
|
|
136
|
+
current_checksum="$(checksum_file "$path" 2>/dev/null || true)"
|
|
137
|
+
if [[ -z "$current_checksum" || "$current_checksum" != "$recorded_checksum" ]]; then
|
|
138
|
+
printf 'Leaving modified file in place: %s (use --force to remove)\n' "$path" >&2
|
|
139
|
+
failures=1
|
|
140
|
+
continue
|
|
141
|
+
fi
|
|
142
|
+
fi
|
|
143
|
+
run rm -f "$path"
|
|
144
|
+
;;
|
|
145
|
+
agents_block)
|
|
146
|
+
if ! strip_agents_block; then
|
|
147
|
+
failures=1
|
|
148
|
+
fi
|
|
149
|
+
;;
|
|
150
|
+
esac
|
|
151
|
+
done < "$MANIFEST"
|
|
152
|
+
|
|
153
|
+
run rmdir "$HOME/.agents/skills/colleague/agents" 2>/dev/null || true
|
|
154
|
+
run rmdir "$HOME/.agents/skills/colleague" 2>/dev/null || true
|
|
155
|
+
run rmdir "$HOME/.claude/skills/colleague" 2>/dev/null || true
|
|
156
|
+
run rmdir "$HOME/.codex/prompts" 2>/dev/null || true
|
|
157
|
+
|
|
158
|
+
if [[ "$failures" == "0" ]]; then
|
|
159
|
+
run rm -f "$MANIFEST"
|
|
160
|
+
run rmdir "$STATE_DIR" 2>/dev/null || true
|
|
161
|
+
echo "Removed files tracked by the ask-colleague install manifest."
|
|
162
|
+
else
|
|
163
|
+
echo "Uninstall incomplete because one or more tracked files were modified or could not be safely removed." >&2
|
|
164
|
+
exit 1
|
|
165
|
+
fi
|