oh-my-customcode 0.68.2 → 0.70.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/dist/cli/index.js +167 -29
- package/dist/index.js +101 -13
- package/package.json +1 -1
- package/templates/.claude/hooks/hooks.json +10 -0
- package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +170 -0
- package/templates/.claude/skills/intent-detection/patterns/agent-triggers.yaml +1 -1
- package/templates/.claude/skills/omcustom-feedback/SKILL.md +36 -77
- package/templates/.claude/skills/professor-triage/SKILL.md +196 -89
- package/templates/manifest.json +1 -1
- package/templates/workflows/auto-dev.yaml +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart auto-update hook — interactive omcustom update check
|
|
3
|
+
# Trigger: SessionStart (runs BEFORE session-env-check.sh)
|
|
4
|
+
# Purpose: Check for oh-my-customcode updates, prompt user, optionally update
|
|
5
|
+
# Protocol: stdin JSON -> stdout pass-through, exit 0 ALWAYS
|
|
6
|
+
# Design: GitHub issue #752
|
|
7
|
+
|
|
8
|
+
# Pass through stdin immediately — capture for later output
|
|
9
|
+
input=$(cat)
|
|
10
|
+
|
|
11
|
+
# --- Guard: skip conditions ---
|
|
12
|
+
|
|
13
|
+
# Skip if explicitly disabled
|
|
14
|
+
if [ "${OMCUSTOM_SKIP_AUTO_UPDATE:-}" = "true" ]; then
|
|
15
|
+
echo "$input"
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Skip if /dev/tty not available (CI, Docker, non-interactive)
|
|
20
|
+
if ! [ -c /dev/tty ] 2>/dev/null; then
|
|
21
|
+
echo "$input"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# --- Configuration ---
|
|
26
|
+
CACHE_DIR="$HOME/.oh-my-customcode"
|
|
27
|
+
CACHE_FILE="${CACHE_DIR}/self-update-cache.json"
|
|
28
|
+
CACHE_MAX_AGE=3600 # 1 hour in seconds
|
|
29
|
+
NPM_TIMEOUT=3 # seconds for npm view
|
|
30
|
+
INPUT_TIMEOUT=10 # seconds for user prompt
|
|
31
|
+
PACKAGE_NAME="oh-my-customcode"
|
|
32
|
+
|
|
33
|
+
# --- Helper: semantic version compare ---
|
|
34
|
+
# Returns 0 if $1 < $2 (update available)
|
|
35
|
+
version_lt() {
|
|
36
|
+
local older
|
|
37
|
+
older=$(printf '%s\n' "$1" "$2" | sort -V | head -1)
|
|
38
|
+
[ "$older" = "$1" ] && [ "$1" != "$2" ]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# --- Step 1: Get current installed version ---
|
|
42
|
+
CURRENT_VERSION=""
|
|
43
|
+
|
|
44
|
+
# Try .omcustomrc.json in current directory
|
|
45
|
+
if [ -f ".omcustomrc.json" ]; then
|
|
46
|
+
CURRENT_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' .omcustomrc.json 2>/dev/null | head -1 | grep -o '"[^"]*"$' | tr -d '"')
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Fallback: try npm list
|
|
50
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
51
|
+
CURRENT_VERSION=$(npm list -g "$PACKAGE_NAME" --depth=0 2>/dev/null | grep -o "${PACKAGE_NAME}@[^ ]*" | cut -d'@' -f2)
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Cannot determine current version — skip
|
|
55
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
56
|
+
echo "$input"
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# --- Step 2: Get latest version (cache-first, network fallback) ---
|
|
61
|
+
LATEST_VERSION=""
|
|
62
|
+
CACHE_HIT=false
|
|
63
|
+
|
|
64
|
+
# Ensure cache directory exists
|
|
65
|
+
mkdir -p "$CACHE_DIR" 2>/dev/null
|
|
66
|
+
|
|
67
|
+
# Check cache freshness
|
|
68
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
69
|
+
CACHE_TIMESTAMP=$(grep -o '"timestamp"[[:space:]]*:[[:space:]]*[0-9]*' "$CACHE_FILE" 2>/dev/null | grep -o '[0-9]*$')
|
|
70
|
+
CACHED_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$CACHE_FILE" 2>/dev/null | grep -o '"[^"]*"$' | tr -d '"')
|
|
71
|
+
|
|
72
|
+
if [ -n "$CACHE_TIMESTAMP" ] && [ -n "$CACHED_VERSION" ]; then
|
|
73
|
+
NOW=$(date +%s)
|
|
74
|
+
AGE=$((NOW - CACHE_TIMESTAMP))
|
|
75
|
+
|
|
76
|
+
if [ "$AGE" -lt "$CACHE_MAX_AGE" ]; then
|
|
77
|
+
LATEST_VERSION="$CACHED_VERSION"
|
|
78
|
+
CACHE_HIT=true
|
|
79
|
+
fi
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Cache miss or stale — fetch from npm registry
|
|
84
|
+
if [ "$CACHE_HIT" = false ]; then
|
|
85
|
+
if command -v npm >/dev/null 2>&1; then
|
|
86
|
+
LATEST_VERSION=$(timeout "$NPM_TIMEOUT" npm view "$PACKAGE_NAME" version 2>/dev/null || echo "")
|
|
87
|
+
|
|
88
|
+
# Update cache on successful fetch
|
|
89
|
+
if [ -n "$LATEST_VERSION" ]; then
|
|
90
|
+
NOW=$(date +%s)
|
|
91
|
+
cat > "$CACHE_FILE" << EOF
|
|
92
|
+
{
|
|
93
|
+
"version": "${LATEST_VERSION}",
|
|
94
|
+
"timestamp": ${NOW},
|
|
95
|
+
"source": "npm-registry"
|
|
96
|
+
}
|
|
97
|
+
EOF
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Could not determine latest version — skip
|
|
103
|
+
if [ -z "$LATEST_VERSION" ]; then
|
|
104
|
+
echo "$input"
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# --- Step 3: Compare versions ---
|
|
109
|
+
if ! version_lt "$CURRENT_VERSION" "$LATEST_VERSION"; then
|
|
110
|
+
# Already up to date
|
|
111
|
+
echo "$input"
|
|
112
|
+
exit 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# --- Step 4: Prompt user for update ---
|
|
116
|
+
echo "" >&2
|
|
117
|
+
echo "--- [oh-my-customcode Update Available] ---" >&2
|
|
118
|
+
echo " New version: v${LATEST_VERSION} (current: v${CURRENT_VERSION})" >&2
|
|
119
|
+
echo "" >&2
|
|
120
|
+
|
|
121
|
+
# Interactive prompt via /dev/tty (SessionStart stdin is JSON pipe)
|
|
122
|
+
printf " Update oh-my-customcode to v%s? [y/N] " "$LATEST_VERSION" >/dev/tty 2>/dev/null
|
|
123
|
+
if read -r -t "$INPUT_TIMEOUT" answer </dev/tty 2>/dev/null; then
|
|
124
|
+
case "$answer" in
|
|
125
|
+
[yY]|[yY][eE][sS])
|
|
126
|
+
echo " Installing oh-my-customcode@${LATEST_VERSION}..." >&2
|
|
127
|
+
if npm install -g "${PACKAGE_NAME}@latest" >&2 2>&1; then
|
|
128
|
+
echo " ✓ Updated to v${LATEST_VERSION}" >&2
|
|
129
|
+
|
|
130
|
+
# Check if project harness should be updated too
|
|
131
|
+
if [ -f ".omcustomrc.json" ]; then
|
|
132
|
+
printf " Update project harness too? [y/N] " >/dev/tty 2>/dev/null
|
|
133
|
+
if read -r -t "$INPUT_TIMEOUT" harness_answer </dev/tty 2>/dev/null; then
|
|
134
|
+
case "$harness_answer" in
|
|
135
|
+
[yY]|[yY][eE][sS])
|
|
136
|
+
echo " Updating project harness..." >&2
|
|
137
|
+
if command -v omcustom >/dev/null 2>&1; then
|
|
138
|
+
omcustom update --force >&2 2>&1 || echo " ⚠ Harness update failed (non-blocking)" >&2
|
|
139
|
+
echo " ✓ Project harness updated" >&2
|
|
140
|
+
else
|
|
141
|
+
echo " ⚠ omcustom command not found after install" >&2
|
|
142
|
+
fi
|
|
143
|
+
;;
|
|
144
|
+
*)
|
|
145
|
+
echo " Skipped harness update" >&2
|
|
146
|
+
;;
|
|
147
|
+
esac
|
|
148
|
+
else
|
|
149
|
+
echo "" >&2
|
|
150
|
+
echo " Timed out — skipped harness update" >&2
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
else
|
|
154
|
+
echo " ⚠ Update failed (non-blocking, continuing session)" >&2
|
|
155
|
+
fi
|
|
156
|
+
;;
|
|
157
|
+
*)
|
|
158
|
+
echo " Skipped update" >&2
|
|
159
|
+
;;
|
|
160
|
+
esac
|
|
161
|
+
else
|
|
162
|
+
echo "" >&2
|
|
163
|
+
echo " Timed out — skipped update" >&2
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
echo "------------------------------------" >&2
|
|
167
|
+
|
|
168
|
+
# Always pass through and exit 0
|
|
169
|
+
echo "$input"
|
|
170
|
+
exit 0
|
|
@@ -427,7 +427,7 @@ agents:
|
|
|
427
427
|
file_patterns: []
|
|
428
428
|
actions: [review, analyze]
|
|
429
429
|
base_confidence: 85
|
|
430
|
-
routing_rule: "MUST use professor-triage skill for
|
|
430
|
+
routing_rule: "MUST use professor-triage skill for codebase-driven issue analysis and automated triage"
|
|
431
431
|
|
|
432
432
|
rtk-exec:
|
|
433
433
|
keywords:
|
|
@@ -9,11 +9,11 @@ argument-hint: "[description or leave empty for interactive] [--anonymous]"
|
|
|
9
9
|
|
|
10
10
|
# Feedback Submitter
|
|
11
11
|
|
|
12
|
-
Submit feedback about oh-my-customcode (bugs, features, improvements, questions) directly from the CLI session. Supports anonymous submission
|
|
12
|
+
Submit feedback about oh-my-customcode (bugs, features, improvements, questions) directly from the CLI session. Supports anonymous submission with `[Anonymous Feedback]` title prefix when `--anonymous` flag is used.
|
|
13
13
|
|
|
14
14
|
## Purpose
|
|
15
15
|
|
|
16
|
-
Lowers the barrier for submitting feedback by allowing users to create GitHub issues
|
|
16
|
+
Lowers the barrier for submitting feedback by allowing users to create GitHub issues — without leaving their terminal session. All feedback is filed to the `baekenough/oh-my-customcode` repository.
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
@@ -59,22 +59,13 @@ if [ "$GH_AVAILABLE" = "true" ]; then
|
|
|
59
59
|
else
|
|
60
60
|
GH_AUTHED=false
|
|
61
61
|
fi
|
|
62
|
-
|
|
63
|
-
# Check curl availability
|
|
64
|
-
command -v curl >/dev/null 2>&1 && CURL_AVAILABLE=true || CURL_AVAILABLE=false
|
|
65
62
|
```
|
|
66
63
|
|
|
67
|
-
**Route A**: `gh` available + authenticated
|
|
64
|
+
**Route A**: `gh` available + authenticated
|
|
68
65
|
- Use GitHub Issue creation (see Phase 4A)
|
|
66
|
+
- If `--anonymous`: adds `[Anonymous Feedback]` prefix and `anonymous` label
|
|
69
67
|
|
|
70
|
-
**
|
|
71
|
-
- Use `curl` to Airflow REST API (see Phase 4C)
|
|
72
|
-
- Phase 4B (workflow_dispatch) reserved for future use
|
|
73
|
-
|
|
74
|
-
**Route C**: `gh` NOT available (or Route B curl fallback)
|
|
75
|
-
- Use `curl` to Airflow REST API (see Phase 4C)
|
|
76
|
-
|
|
77
|
-
**Fallback**: Neither `gh` nor `curl` available
|
|
68
|
+
**Fallback**: `gh` NOT available or not authenticated
|
|
78
69
|
- Save feedback locally and inform the user (see Phase 4D)
|
|
79
70
|
|
|
80
71
|
### Phase 3: Environment Collection
|
|
@@ -102,24 +93,30 @@ For anonymous submissions, do NOT include the project name. Offer to include pro
|
|
|
102
93
|
- Ask: "Include environment info (version, OS) in the anonymous report? [Y/n]"
|
|
103
94
|
- If declined, set `PROJECT_CONTEXT=""`
|
|
104
95
|
|
|
105
|
-
### Phase 4A: GitHub Issue Creation (Route A — gh + authenticated
|
|
96
|
+
### Phase 4A: GitHub Issue Creation (Route A — gh + authenticated)
|
|
106
97
|
|
|
107
|
-
1.
|
|
98
|
+
1. If `ANONYMOUS=true`, prepend `[Anonymous Feedback] ` to the title and add `anonymous` to the label list.
|
|
99
|
+
|
|
100
|
+
2. Show the user a preview of the issue to be created:
|
|
108
101
|
```
|
|
109
102
|
[Preview]
|
|
110
103
|
├── Title: {title}
|
|
111
104
|
├── Category: {category}
|
|
112
|
-
├── Labels: feedback, {category-label}
|
|
105
|
+
├── Labels: feedback, {category-label}[, anonymous]
|
|
113
106
|
└── Repo: baekenough/oh-my-customcode
|
|
114
107
|
```
|
|
115
|
-
|
|
108
|
+
3. Ask for confirmation before creating
|
|
116
109
|
|
|
117
|
-
|
|
110
|
+
4. Ensure labels exist (defensive):
|
|
118
111
|
```bash
|
|
119
112
|
gh label create feedback --description "User feedback via /omcustom-feedback" --color 0E8A16 --repo baekenough/oh-my-customcode 2>/dev/null || true
|
|
113
|
+
# If anonymous, ensure the anonymous label exists
|
|
114
|
+
if [ "$ANONYMOUS" = "true" ]; then
|
|
115
|
+
gh label create anonymous --description "Anonymous feedback submission" --color C5DEF5 --repo baekenough/oh-my-customcode 2>/dev/null || true
|
|
116
|
+
fi
|
|
120
117
|
```
|
|
121
118
|
|
|
122
|
-
|
|
119
|
+
5. Create the issue using `--body-file` for safe markdown handling:
|
|
123
120
|
```bash
|
|
124
121
|
# Write body to temp file to avoid shell escaping issues
|
|
125
122
|
cat > /tmp/omcustom-feedback-body.md << 'FEEDBACK_EOF'
|
|
@@ -141,64 +138,28 @@ For anonymous submissions, do NOT include the project name. Offer to include pro
|
|
|
141
138
|
*Submitted via `/omcustom-feedback`*
|
|
142
139
|
FEEDBACK_EOF
|
|
143
140
|
|
|
141
|
+
# Build label string
|
|
142
|
+
LABELS="feedback,${CATEGORY_LABEL}"
|
|
143
|
+
if [ "$ANONYMOUS" = "true" ]; then
|
|
144
|
+
LABELS="${LABELS},anonymous"
|
|
145
|
+
fi
|
|
146
|
+
|
|
144
147
|
# Create issue
|
|
145
148
|
gh issue create \
|
|
146
149
|
--repo baekenough/oh-my-customcode \
|
|
147
150
|
--title "{title}" \
|
|
148
|
-
--label "
|
|
151
|
+
--label "$LABELS" \
|
|
149
152
|
--body-file /tmp/omcustom-feedback-body.md
|
|
150
153
|
|
|
151
154
|
# Clean up
|
|
152
155
|
rm -f /tmp/omcustom-feedback-body.md
|
|
153
156
|
```
|
|
154
157
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
6. Return the issue URL to the user
|
|
158
|
-
|
|
159
|
-
### Phase 4B: Anonymous via GitHub Actions (Route B — FUTURE)
|
|
160
|
-
|
|
161
|
-
> **Note**: This route is reserved for future implementation. The `feedback-submission.yml` workflow does not yet exist. All anonymous/unauthenticated submissions currently fall through to Route C (Airflow REST API).
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
gh workflow run feedback-submission.yml \
|
|
165
|
-
--repo baekenough/oh-my-customcode \
|
|
166
|
-
-f title="$TITLE" \
|
|
167
|
-
-f body="$BODY" \
|
|
168
|
-
-f feedback_type="$TYPE" \
|
|
169
|
-
-f anonymous=true \
|
|
170
|
-
-f project_context="$PROJECT_CONTEXT"
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
On success, inform the user:
|
|
174
|
-
```
|
|
175
|
-
[Done] Anonymous feedback submitted via GitHub Actions workflow.
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
If `gh workflow run` fails (e.g., permissions), fall through to Route C.
|
|
179
|
-
|
|
180
|
-
### Phase 4C: Anonymous via Airflow REST API (Route C — no gh)
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
# Build JSON payload safely with jq
|
|
184
|
-
PAYLOAD=$(jq -n --arg title "$TITLE" --arg body "$BODY" --arg type "$TYPE" --arg ctx "$PROJECT_CONTEXT" \
|
|
185
|
-
'{"conf":{"title":$title,"body":$body,"feedback_type":$type,"anonymous":true,"submitter":"","project_context":$ctx}}')
|
|
186
|
-
|
|
187
|
-
curl -X POST "https://airflow.baekenough.com/api/v2/dags/omc_feedback_collector/dagRuns" \
|
|
188
|
-
-H "Content-Type: application/json" \
|
|
189
|
-
-d "$PAYLOAD" \
|
|
190
|
-
--silent --show-error \
|
|
191
|
-
--max-time 15
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
On HTTP 200/201, inform the user:
|
|
195
|
-
```
|
|
196
|
-
[Done] Anonymous feedback submitted via Airflow.
|
|
197
|
-
```
|
|
158
|
+
6. If label creation fails AND issue creation fails due to labels, retry without labels as fallback
|
|
198
159
|
|
|
199
|
-
|
|
160
|
+
7. Return the issue URL to the user
|
|
200
161
|
|
|
201
|
-
### Phase 4D: Local Fallback (
|
|
162
|
+
### Phase 4D: Local Fallback (gh not available, not authenticated, or issue creation failed)
|
|
202
163
|
|
|
203
164
|
```bash
|
|
204
165
|
mkdir -p ~/.omcustom/feedback
|
|
@@ -222,25 +183,23 @@ Inform the user:
|
|
|
222
183
|
[Saved] Feedback saved locally to ~/.omcustom/feedback/{timestamp}.json
|
|
223
184
|
Submit manually when connectivity is available:
|
|
224
185
|
- GitHub Issues: https://github.com/baekenough/oh-my-customcode/issues/new
|
|
225
|
-
- Or run /omcustom:feedback again when gh
|
|
186
|
+
- Or run /omcustom:feedback again when gh is available
|
|
226
187
|
```
|
|
227
188
|
|
|
228
189
|
### Category-to-Label Mapping
|
|
229
190
|
|
|
230
|
-
| Category | GitHub Label |
|
|
231
|
-
|
|
232
|
-
| bug | bug |
|
|
233
|
-
| feature | enhancement |
|
|
234
|
-
| improvement | enhancement |
|
|
235
|
-
| question | question |
|
|
236
|
-
| (auto-detect fails) | (none) |
|
|
191
|
+
| Category | GitHub Label |
|
|
192
|
+
|----------|--------------|
|
|
193
|
+
| bug | bug |
|
|
194
|
+
| feature | enhancement |
|
|
195
|
+
| improvement | enhancement |
|
|
196
|
+
| question | question |
|
|
197
|
+
| (auto-detect fails) | (none) |
|
|
237
198
|
|
|
238
199
|
## Notes
|
|
239
200
|
|
|
240
201
|
- Route A creates a visible GitHub issue attributed to the user's gh account
|
|
241
|
-
-
|
|
242
|
-
- Route B requires `gh` but NOT authentication to the repo (public workflow)
|
|
243
|
-
- Route C requires `curl` (available on macOS/Linux by default)
|
|
202
|
+
- When `--anonymous` is used, the title is prefixed with `[Anonymous Feedback]` and the `anonymous` label is added
|
|
244
203
|
- Fallback ensures no feedback is silently lost even in offline environments
|
|
245
204
|
- `disable-model-invocation: true` ensures this skill only runs when explicitly invoked by the user
|
|
246
205
|
- Target repo is hardcoded to `baekenough/oh-my-customcode` — feedback is always about omcustom itself
|