-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·414 lines (366 loc) · 12.7 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·414 lines (366 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
#!/bin/bash
# EDC — Every Day Carry Skills installer
# Usage:
# curl -fsSL https://raw.githubusercontent.com/almogdepaz/edc/main/install.sh | bash -s <agent>
# bash install.sh --agent <agent> [--no-path]
#
# Agents: claude, cursor, codex, pi
#
# Runtime mode (advisory vs inject) is controlled by `edc-context/manifest.json`'s
# `policy.defaultMode` field. Flip it with: `edc mode advisory|inject`.
set -euo pipefail
REPO="almogdepaz/EDC"
EDC_INSTALL_REF="${EDC_INSTALL_REF:-v1.1.5}"
INSTALL_URL="https://raw.githubusercontent.com/$REPO/main/install.sh"
ARCHIVE_URL="https://github.com/$REPO/archive/refs/tags/$EDC_INSTALL_REF.tar.gz"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
EDC_INSTALL_TMP=""
AGENT=""
ADD_PATH=1
usage() {
cat <<EOF
Usage:
curl -fsSL $INSTALL_URL | bash -s <agent>
bash install.sh --agent <agent> [--no-path]
Agents: claude, cursor, codex, pi
Options:
--no-path Do not edit shell rc files to add ~/.edc/scripts to PATH
After install, toggle runtime mode in any repo with:
edc mode advisory # docs only (default), hooks no-op
edc mode inject # claude PreToolUse hook auto-injects module docs
EOF
}
die() {
echo "edc: $*" >&2
exit 1
}
while [ "$#" -gt 0 ]; do
case "$1" in
--agent)
[ "$#" -ge 2 ] || die "--agent requires a value"
AGENT="$2"
shift 2
;;
--no-path)
ADD_PATH=0
shift
;;
--help|-h)
usage
exit 0
;;
--*)
die "unknown option: $1"
;;
*)
if [ -n "$AGENT" ]; then
die "unexpected argument: $1"
fi
AGENT="$1"
shift
;;
esac
done
[ -n "$AGENT" ] || {
usage
exit 1
}
PUBLIC_SKILLS=(
"plugins/edc/skills/edc-review/SKILL.md"
"plugins/edc/skills/edc-review/methodology.md"
"plugins/edc/skills/edc-review/adversarial.md"
"plugins/edc/skills/edc-review/reporting.md"
"plugins/edc/skills/edc-review/patterns.md"
"plugins/edc/skills/edc-audit/SKILL.md"
"plugins/edc/skills/edc-audit/references/scope-and-standards.md"
"plugins/edc/skills/edc-audit/references/smell-baseline.md"
"plugins/edc/skills/edc-audit/references/quality-checks.md"
"plugins/edc/skills/edc-audit/references/reporting.md"
"plugins/edc/skills/edc-delivery-review/SKILL.md"
"plugins/edc/skills/edc-delivery-review/references/spec-axis.md"
"plugins/edc/skills/edc-delivery-review/references/architecture-axis.md"
"plugins/edc/skills/edc-delivery-review/references/reporting.md"
)
cleanup_install_tmp() {
if [ -n "$EDC_INSTALL_TMP" ]; then
rm -rf "$EDC_INSTALL_TMP"
fi
}
trap cleanup_install_tmp EXIT
prepare_source_tree() {
if [ -f "$SCRIPT_DIR/plugins/edc/scripts/edc" ]; then
return 0
fi
command -v curl >/dev/null 2>&1 || die "curl is required for remote install"
command -v tar >/dev/null 2>&1 || die "tar is required for remote install"
EDC_INSTALL_TMP="$(mktemp -d "${TMPDIR:-/tmp}/edc-install.XXXXXX")"
local archive="$EDC_INSTALL_TMP/edc.tar.gz"
local source_dir="$EDC_INSTALL_TMP/source"
mkdir -p "$source_dir"
curl -fsSL "$ARCHIVE_URL" -o "$archive"
tar -xzf "$archive" -C "$source_dir" --strip-components=1
SCRIPT_DIR="$source_dir"
[ -f "$SCRIPT_DIR/plugins/edc/scripts/edc" ] \
|| die "downloaded archive does not contain EDC plugin runtime: $ARCHIVE_URL"
}
copy_from_source() {
local src="$1" dst="$2"
mkdir -p "$(dirname "$dst")"
[ -f "$SCRIPT_DIR/$src" ] || die "installer source missing: $src"
cp "$SCRIPT_DIR/$src" "$dst"
}
skill_rel() {
local rel="${1#plugins/edc/skills/}"
if [ "$rel" = "$1" ]; then
rel="${1#plugins/edc/prompt-bundles/}"
fi
echo "$rel"
}
install_terminal_cli() {
local runtime_manifest="$SCRIPT_DIR/plugins/edc/hooks/lib/runtime-manifest.mjs"
[ -f "$runtime_manifest" ] || die "installer source missing: plugins/edc/hooks/lib/runtime-manifest.mjs"
command -v node >/dev/null 2>&1 || die "node is required for EDC runtime installation"
node "$runtime_manifest" install "$HOME" "$SCRIPT_DIR/plugins/edc" >/dev/null
rm -rf \
"$HOME/.edc/skills/edc-review-impl" \
"$HOME/.edc/skills/edc-audit-impl" \
"$HOME/.edc/skills/edc-context"
install_shell_path
}
edc_shell_rc_file() {
if [ -n "${EDC_INSTALL_SHELL_RC:-}" ]; then
echo "$EDC_INSTALL_SHELL_RC"
return 0
fi
case "$(basename "${SHELL:-}")" in
zsh) echo "$HOME/.zshrc" ;;
bash) echo "$HOME/.bashrc" ;;
*) return 1 ;;
esac
}
install_shell_path() {
local edc_path="$HOME/.edc/scripts"
if [ "$ADD_PATH" -eq 0 ]; then
return 0
fi
case ":$PATH:" in
*":$edc_path:"*) return 0 ;;
esac
if [ "${CI:-0}" = "1" ]; then
return 0
fi
local rc_file
if ! rc_file="$(edc_shell_rc_file)"; then
return 0
fi
mkdir -p "$(dirname "$rc_file")"
touch "$rc_file"
if grep -Fq '.edc/scripts' "$rc_file"; then
return 0
fi
cat >> "$rc_file" <<'EOF'
# EDC CLI
if [ -d "$HOME/.edc/scripts" ]; then
export PATH="$HOME/.edc/scripts:$PATH"
fi
EOF
echo "Added EDC CLI to PATH in $rc_file. Restart your shell or run:"
echo " export PATH=\"\$HOME/.edc/scripts:\$PATH\""
}
# write_cursor_commands <cursor-target>
# Generates thin slash-command wrappers under <target>/commands/. Each
# wrapper is a Bash-only shim that exports EDC_AGENT_CLI=cursor and shells to
# the matching ~/.edc/scripts/edc-*.sh orchestrator. No source-file checked
# into the repo — the wrapper template lives here, the only place it can
# diverge from the contract is install.sh itself.
write_cursor_commands() {
local target="$1"
mkdir -p "$target/commands"
rm -f "$target/commands/edc-audit.md" "$target/commands/edc-review.md"
local entry action script
for entry in build:build update:update run-review:review-all doctor:doctor; do
action="${entry%%:*}"
script="${entry##*:}"
cat > "$target/commands/edc-$action.md" <<EOF
---
description: edc $action via deterministic orchestrator (auto-installed by install.sh)
---
**Arguments:** \$ARGUMENTS
The orchestrator owns the full pipeline. Your only job is to invoke it and
surface its output.
\`\`\`bash
set -- \$ARGUMENTS
export EDC_AGENT_CLI=cursor
bootstrap="\$HOME/.edc/hooks/lib/runtime-bootstrap.mjs"
if [ ! -f "\$bootstrap" ]; then
echo "SCRIPT_MISSING: trusted EDC runtime bootstrap is unavailable; reinstall EDC"
exit 1
fi
node "\$bootstrap" edc-$script.sh "\$@"
\`\`\`
If the script exits non-zero, surface its error verbatim and stop.
EOF
done
}
# write_codex_skills <codex-skills-target>
# Codex equivalent of write_cursor_commands. Writes <target>/edc-<action>/SKILL.md
# wrappers that delegate to ~/.edc/scripts/edc-*.sh with EDC_AGENT_CLI=codex.
write_codex_skills() {
local target="$1"
local entry action script
for entry in build:build update:update run-review:review-all doctor:doctor; do
action="${entry%%:*}"
script="${entry##*:}"
mkdir -p "$target/edc-$action"
cat > "$target/edc-$action/SKILL.md" <<EOF
---
name: edc-$action
description: edc $action via deterministic orchestrator (auto-installed by install.sh)
---
The orchestrator owns the full pipeline. Invoke it via the target's bash
shell and surface its output. Pass through any user arguments verbatim.
\`\`\`bash
export EDC_AGENT_CLI=codex
bootstrap="\$HOME/.edc/hooks/lib/runtime-bootstrap.mjs"
if [ ! -f "\$bootstrap" ]; then
echo "SCRIPT_MISSING: trusted EDC runtime bootstrap is unavailable; reinstall EDC"
exit 1
fi
node "\$bootstrap" edc-$script.sh "\$@"
\`\`\`
If the script exits non-zero, surface its error verbatim and stop.
EOF
done
}
print_path_hint() {
case ":$PATH:" in
*":$HOME/.edc/scripts:"*) ;;
*)
echo
if [ "$ADD_PATH" -eq 0 ]; then
echo "NOTE: PATH setup was skipped (--no-path). To call 'edc' from anywhere, add:"
else
echo "NOTE: Restart your shell, or run this now to call 'edc' from the current shell:"
fi
echo " export PATH=\"\$HOME/.edc/scripts:\$PATH\""
;;
esac
}
# print_cli_hint <agent>
# Shows the terminal-CLI commands the user can run from any shell once
# ~/.edc/scripts is on PATH. <agent> is one of claude/cursor/codex/pi and
# is used to fill in the --agent flag for the example commands.
print_cli_hint() {
local agent="$1"
echo
echo "Terminal CLI (run from any repo, after PATH is set):"
case "$agent" in
pi)
echo " edc build --agent pi # build or update edc-context/"
echo " edc update --agent pi # refresh from manifest lineage"
echo " edc build --agent pi --force # explicitly rebuild context"
echo " edc review full --agent pi # security + delivery + quality full repo review"
echo " edc review diff --agent pi # security + delivery + quality vs default branch"
echo " edc security full --agent pi # security-only full repo review"
echo " edc delivery diff main --agent pi # delivery/architecture review vs main"
echo " edc quality full --agent pi # code quality full repo audit"
echo " edc doctor # validate context"
echo " edc mode advisory|inject # toggle runtime mode"
echo
echo "Inside pi, use /edc for the interactive menu (choose scope, then combined/security/delivery/quality lens)."
;;
*)
echo " edc build --agent $agent # build or update edc-context/"
echo " edc update --agent $agent # force incremental update"
echo " edc review full --agent $agent # security + delivery + quality full repo review"
echo " edc review diff main --agent $agent # security + delivery + quality vs main"
echo " edc security full --agent $agent # security-only full repo review"
echo " edc delivery diff main --agent $agent # delivery/architecture review vs main"
echo " edc quality full --agent $agent # code quality full repo audit"
echo " edc doctor # validate context"
echo " edc mode advisory|inject # toggle runtime mode"
;;
esac
}
install_public_edc_skills() {
local target="$1"
local f rel
rm -rf \
"$target/edc-review-impl" \
"$target/edc-audit-impl" \
"$target/edc-context" \
"$target/edc-build-impl" \
"$target/edc-update-impl" \
"$target/edc-module-context-impl"
for f in "${PUBLIC_SKILLS[@]}"; do
rel=$(skill_rel "$f")
copy_from_source "$f" "$target/$rel"
done
}
install_claude_runtime() {
prepare_source_tree
install_terminal_cli
echo "Installed EDC terminal CLI at $HOME/.edc/scripts/edc."
echo "Installed EDC skill bundle at $HOME/.edc/skills/."
echo
echo "This installs the standalone CLI only. The CLI works without the claude plugin."
echo
echo "For slash commands (/edc:edc-build, hooks) inside interactive claude, ALSO run:"
echo " claude plugin marketplace add almogdepaz/edc"
echo " claude plugin install edc@edc"
echo
echo "Runtime mode is read from edc-context/manifest.json (defaults to advisory)."
echo "Flip with: edc mode inject"
print_cli_hint claude
print_path_hint
}
case "$AGENT" in
claude)
install_claude_runtime
;;
cursor)
prepare_source_tree
TARGET="$HOME/.cursor"
SCRIPTS_TARGET="$HOME/.edc/scripts"
echo "Installing EDC public skills globally for Cursor..."
install_public_edc_skills "$TARGET/skills"
install_terminal_cli
write_cursor_commands "$TARGET"
echo "Done. Public skills at $TARGET/skills/, commands at $TARGET/commands/, terminal CLI + private prompt bundle at $SCRIPTS_TARGET/ and $HOME/.edc/skills/"
print_cli_hint cursor
print_path_hint
;;
codex)
prepare_source_tree
TARGET="$HOME/.codex/skills"
SCRIPTS_TARGET="$HOME/.edc/scripts"
echo "Installing EDC public skills globally for Codex..."
install_public_edc_skills "$TARGET"
install_terminal_cli
write_codex_skills "$TARGET"
echo "Done. Public skills at $TARGET/, terminal CLI + private prompt bundle at $SCRIPTS_TARGET/ and $HOME/.edc/skills/. Use \$edc-build, \$edc-update, \$edc-run-review, or \$edc-doctor."
print_cli_hint codex
print_path_hint
;;
pi)
prepare_source_tree
if ! command -v pi >/dev/null 2>&1; then
die "pi CLI not found on PATH. Install pi first: https://pi.dev"
fi
if [ -d "$SCRIPT_DIR/pi" ]; then
bash "$SCRIPT_DIR/pi/install.sh" --from-source
else
echo "Installing EDC as pi extension via git..."
pi install "git:github.com/almogdepaz/edc"
fi
install_terminal_cli
echo "installed extension/source path: $SCRIPT_DIR/pi"
echo "restart pi or run /reload in existing sessions to refresh menu labels."
echo "Done. Run /edc inside pi for review/security review/delivery review/quality review/status/build/update/doctor. Toggle mode with 'edc mode advisory|inject'."
print_cli_hint pi
print_path_hint
;;
*)
die "unknown agent: $AGENT (supported: claude, cursor, codex, pi)"
;;
esac