@suwujs/codex-vault 0.5.1 → 0.5.3
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/package.json +1 -1
- package/plugin/VERSION +1 -1
- package/plugin/hooks/classify-message.py +16 -13
- package/plugin/hooks/session-start.py +32 -1
- package/plugin/hooks/validate-write.py +12 -9
- package/vault/.codex-vault/hooks/classify-message.py +16 -13
- package/vault/.codex-vault/hooks/session-start.py +32 -1
- package/vault/.codex-vault/hooks/validate-write.py +12 -9
package/package.json
CHANGED
package/plugin/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.5.
|
|
1
|
+
0.5.3
|
|
@@ -273,27 +273,30 @@ def main():
|
|
|
273
273
|
|
|
274
274
|
if parts:
|
|
275
275
|
context = "\n\n".join(parts)
|
|
276
|
+
|
|
277
|
+
# Build feedback label
|
|
278
|
+
matched = [s for s in SIGNALS if _match(s["patterns"], prompt.lower())]
|
|
279
|
+
feedback_parts = []
|
|
280
|
+
for s in matched:
|
|
281
|
+
feedback_parts.append(f"{s['name']} → {s['skill']}")
|
|
282
|
+
if is_session_end(prompt):
|
|
283
|
+
feedback_parts.append("SESSION END → /wrap-up")
|
|
284
|
+
icon = "🔄" if mode == "auto" else "💡"
|
|
285
|
+
label = ", ".join(feedback_parts) if feedback_parts else "intent detected"
|
|
286
|
+
|
|
287
|
+
# Hook trigger notification
|
|
288
|
+
print(f" {icon} vault: {label}")
|
|
289
|
+
|
|
276
290
|
output = {
|
|
277
291
|
"hookSpecificOutput": {
|
|
278
292
|
"hookEventName": "UserPromptSubmit",
|
|
279
293
|
"additionalContext": context
|
|
280
|
-
}
|
|
294
|
+
},
|
|
295
|
+
"systemMessage": f"{icon} vault: {label}"
|
|
281
296
|
}
|
|
282
297
|
json.dump(output, sys.stdout)
|
|
283
298
|
sys.stdout.flush()
|
|
284
299
|
|
|
285
|
-
# Visible feedback to user terminal (stderr)
|
|
286
|
-
matched = [s for s in SIGNALS if _match(s["patterns"], prompt.lower())]
|
|
287
|
-
parts = []
|
|
288
|
-
for s in matched:
|
|
289
|
-
parts.append(f"{s['name']} → {s['skill']}")
|
|
290
|
-
if is_session_end(prompt):
|
|
291
|
-
parts.append("SESSION END → /wrap-up")
|
|
292
|
-
if parts:
|
|
293
|
-
label = ", ".join(parts)
|
|
294
|
-
icon = "🔄" if mode == "auto" else "💡"
|
|
295
|
-
print(f" {icon} vault: {label}", file=sys.stderr)
|
|
296
|
-
|
|
297
300
|
sys.exit(0)
|
|
298
301
|
|
|
299
302
|
|
|
@@ -343,6 +343,23 @@ def _build_banner(vault_dir):
|
|
|
343
343
|
# ── Main ───────────────────────────────────────────────────────────────
|
|
344
344
|
|
|
345
345
|
|
|
346
|
+
def _detect_platform():
|
|
347
|
+
"""Detect whether we're running under Claude Code or Codex CLI."""
|
|
348
|
+
if os.environ.get("CLAUDE_PROJECT_DIR"):
|
|
349
|
+
return "claude"
|
|
350
|
+
if os.environ.get("CODEX_PROJECT_DIR") or os.environ.get("CODEX_HOME"):
|
|
351
|
+
return "codex"
|
|
352
|
+
# Fallback: check parent process name
|
|
353
|
+
try:
|
|
354
|
+
ppid = os.getppid()
|
|
355
|
+
cmdline = Path(f"/proc/{ppid}/cmdline").read_text() if os.path.exists(f"/proc/{ppid}/cmdline") else ""
|
|
356
|
+
if "codex" in cmdline.lower():
|
|
357
|
+
return "codex"
|
|
358
|
+
except Exception:
|
|
359
|
+
pass
|
|
360
|
+
return "claude" # default
|
|
361
|
+
|
|
362
|
+
|
|
346
363
|
def main():
|
|
347
364
|
vault_dir = _find_vault_root()
|
|
348
365
|
if not vault_dir:
|
|
@@ -355,6 +372,13 @@ def main():
|
|
|
355
372
|
json.dump(output, sys.stdout)
|
|
356
373
|
sys.exit(0)
|
|
357
374
|
|
|
375
|
+
# Read hook input for session metadata
|
|
376
|
+
try:
|
|
377
|
+
event = json.load(sys.stdin)
|
|
378
|
+
except Exception:
|
|
379
|
+
event = {}
|
|
380
|
+
|
|
381
|
+
platform = _detect_platform()
|
|
358
382
|
context = _build_context(vault_dir)
|
|
359
383
|
banner = _build_banner(vault_dir)
|
|
360
384
|
|
|
@@ -363,9 +387,16 @@ def main():
|
|
|
363
387
|
"hookEventName": "SessionStart",
|
|
364
388
|
"additionalContext": context
|
|
365
389
|
},
|
|
366
|
-
"systemMessage": banner
|
|
367
390
|
}
|
|
368
391
|
|
|
392
|
+
if platform == "claude":
|
|
393
|
+
# Claude Code renders systemMessage in terminal
|
|
394
|
+
output["systemMessage"] = banner
|
|
395
|
+
else:
|
|
396
|
+
# Codex CLI: systemMessage not rendered by TUI,
|
|
397
|
+
# use stderr for terminal visibility (best effort)
|
|
398
|
+
sys.stderr.write(banner + "\n")
|
|
399
|
+
|
|
369
400
|
json.dump(output, sys.stdout)
|
|
370
401
|
sys.stdout.flush()
|
|
371
402
|
sys.exit(0)
|
|
@@ -94,23 +94,26 @@ def main():
|
|
|
94
94
|
|
|
95
95
|
if warnings:
|
|
96
96
|
hint_list = "\n".join(f" - {w}" for w in warnings)
|
|
97
|
+
count = len(warnings)
|
|
98
|
+
first = warnings[0]
|
|
99
|
+
if count == 1:
|
|
100
|
+
feedback = f"⚠️ vault: {basename} — {first}"
|
|
101
|
+
else:
|
|
102
|
+
feedback = f"⚠️ vault: {basename} — {first} (+{count - 1} more)"
|
|
103
|
+
|
|
104
|
+
# Hook trigger notification
|
|
105
|
+
print(f" {feedback}")
|
|
106
|
+
|
|
97
107
|
output = {
|
|
98
108
|
"hookSpecificOutput": {
|
|
99
109
|
"hookEventName": "PostToolUse",
|
|
100
110
|
"additionalContext": f"Vault warnings for `{basename}`:\n{hint_list}\nFix these before moving on."
|
|
101
|
-
}
|
|
111
|
+
},
|
|
112
|
+
"systemMessage": feedback
|
|
102
113
|
}
|
|
103
114
|
json.dump(output, sys.stdout)
|
|
104
115
|
sys.stdout.flush()
|
|
105
116
|
|
|
106
|
-
# Visible feedback to user terminal (stderr)
|
|
107
|
-
count = len(warnings)
|
|
108
|
-
first = warnings[0]
|
|
109
|
-
if count == 1:
|
|
110
|
-
print(f" ⚠️ vault: {basename} — {first}", file=sys.stderr)
|
|
111
|
-
else:
|
|
112
|
-
print(f" ⚠️ vault: {basename} — {first} (+{count - 1} more)", file=sys.stderr)
|
|
113
|
-
|
|
114
117
|
sys.exit(0)
|
|
115
118
|
|
|
116
119
|
|
|
@@ -273,27 +273,30 @@ def main():
|
|
|
273
273
|
|
|
274
274
|
if parts:
|
|
275
275
|
context = "\n\n".join(parts)
|
|
276
|
+
|
|
277
|
+
# Build feedback label
|
|
278
|
+
matched = [s for s in SIGNALS if _match(s["patterns"], prompt.lower())]
|
|
279
|
+
feedback_parts = []
|
|
280
|
+
for s in matched:
|
|
281
|
+
feedback_parts.append(f"{s['name']} → {s['skill']}")
|
|
282
|
+
if is_session_end(prompt):
|
|
283
|
+
feedback_parts.append("SESSION END → /wrap-up")
|
|
284
|
+
icon = "🔄" if mode == "auto" else "💡"
|
|
285
|
+
label = ", ".join(feedback_parts) if feedback_parts else "intent detected"
|
|
286
|
+
|
|
287
|
+
# Hook trigger notification
|
|
288
|
+
print(f" {icon} vault: {label}")
|
|
289
|
+
|
|
276
290
|
output = {
|
|
277
291
|
"hookSpecificOutput": {
|
|
278
292
|
"hookEventName": "UserPromptSubmit",
|
|
279
293
|
"additionalContext": context
|
|
280
|
-
}
|
|
294
|
+
},
|
|
295
|
+
"systemMessage": f"{icon} vault: {label}"
|
|
281
296
|
}
|
|
282
297
|
json.dump(output, sys.stdout)
|
|
283
298
|
sys.stdout.flush()
|
|
284
299
|
|
|
285
|
-
# Visible feedback to user terminal (stderr)
|
|
286
|
-
matched = [s for s in SIGNALS if _match(s["patterns"], prompt.lower())]
|
|
287
|
-
parts = []
|
|
288
|
-
for s in matched:
|
|
289
|
-
parts.append(f"{s['name']} → {s['skill']}")
|
|
290
|
-
if is_session_end(prompt):
|
|
291
|
-
parts.append("SESSION END → /wrap-up")
|
|
292
|
-
if parts:
|
|
293
|
-
label = ", ".join(parts)
|
|
294
|
-
icon = "🔄" if mode == "auto" else "💡"
|
|
295
|
-
print(f" {icon} vault: {label}", file=sys.stderr)
|
|
296
|
-
|
|
297
300
|
sys.exit(0)
|
|
298
301
|
|
|
299
302
|
|
|
@@ -343,6 +343,23 @@ def _build_banner(vault_dir):
|
|
|
343
343
|
# ── Main ───────────────────────────────────────────────────────────────
|
|
344
344
|
|
|
345
345
|
|
|
346
|
+
def _detect_platform():
|
|
347
|
+
"""Detect whether we're running under Claude Code or Codex CLI."""
|
|
348
|
+
if os.environ.get("CLAUDE_PROJECT_DIR"):
|
|
349
|
+
return "claude"
|
|
350
|
+
if os.environ.get("CODEX_PROJECT_DIR") or os.environ.get("CODEX_HOME"):
|
|
351
|
+
return "codex"
|
|
352
|
+
# Fallback: check parent process name
|
|
353
|
+
try:
|
|
354
|
+
ppid = os.getppid()
|
|
355
|
+
cmdline = Path(f"/proc/{ppid}/cmdline").read_text() if os.path.exists(f"/proc/{ppid}/cmdline") else ""
|
|
356
|
+
if "codex" in cmdline.lower():
|
|
357
|
+
return "codex"
|
|
358
|
+
except Exception:
|
|
359
|
+
pass
|
|
360
|
+
return "claude" # default
|
|
361
|
+
|
|
362
|
+
|
|
346
363
|
def main():
|
|
347
364
|
vault_dir = _find_vault_root()
|
|
348
365
|
if not vault_dir:
|
|
@@ -355,6 +372,13 @@ def main():
|
|
|
355
372
|
json.dump(output, sys.stdout)
|
|
356
373
|
sys.exit(0)
|
|
357
374
|
|
|
375
|
+
# Read hook input for session metadata
|
|
376
|
+
try:
|
|
377
|
+
event = json.load(sys.stdin)
|
|
378
|
+
except Exception:
|
|
379
|
+
event = {}
|
|
380
|
+
|
|
381
|
+
platform = _detect_platform()
|
|
358
382
|
context = _build_context(vault_dir)
|
|
359
383
|
banner = _build_banner(vault_dir)
|
|
360
384
|
|
|
@@ -363,9 +387,16 @@ def main():
|
|
|
363
387
|
"hookEventName": "SessionStart",
|
|
364
388
|
"additionalContext": context
|
|
365
389
|
},
|
|
366
|
-
"systemMessage": banner
|
|
367
390
|
}
|
|
368
391
|
|
|
392
|
+
if platform == "claude":
|
|
393
|
+
# Claude Code renders systemMessage in terminal
|
|
394
|
+
output["systemMessage"] = banner
|
|
395
|
+
else:
|
|
396
|
+
# Codex CLI: systemMessage not rendered by TUI,
|
|
397
|
+
# use stderr for terminal visibility (best effort)
|
|
398
|
+
sys.stderr.write(banner + "\n")
|
|
399
|
+
|
|
369
400
|
json.dump(output, sys.stdout)
|
|
370
401
|
sys.stdout.flush()
|
|
371
402
|
sys.exit(0)
|
|
@@ -94,23 +94,26 @@ def main():
|
|
|
94
94
|
|
|
95
95
|
if warnings:
|
|
96
96
|
hint_list = "\n".join(f" - {w}" for w in warnings)
|
|
97
|
+
count = len(warnings)
|
|
98
|
+
first = warnings[0]
|
|
99
|
+
if count == 1:
|
|
100
|
+
feedback = f"⚠️ vault: {basename} — {first}"
|
|
101
|
+
else:
|
|
102
|
+
feedback = f"⚠️ vault: {basename} — {first} (+{count - 1} more)"
|
|
103
|
+
|
|
104
|
+
# Hook trigger notification
|
|
105
|
+
print(f" {feedback}")
|
|
106
|
+
|
|
97
107
|
output = {
|
|
98
108
|
"hookSpecificOutput": {
|
|
99
109
|
"hookEventName": "PostToolUse",
|
|
100
110
|
"additionalContext": f"Vault warnings for `{basename}`:\n{hint_list}\nFix these before moving on."
|
|
101
|
-
}
|
|
111
|
+
},
|
|
112
|
+
"systemMessage": feedback
|
|
102
113
|
}
|
|
103
114
|
json.dump(output, sys.stdout)
|
|
104
115
|
sys.stdout.flush()
|
|
105
116
|
|
|
106
|
-
# Visible feedback to user terminal (stderr)
|
|
107
|
-
count = len(warnings)
|
|
108
|
-
first = warnings[0]
|
|
109
|
-
if count == 1:
|
|
110
|
-
print(f" ⚠️ vault: {basename} — {first}", file=sys.stderr)
|
|
111
|
-
else:
|
|
112
|
-
print(f" ⚠️ vault: {basename} — {first} (+{count - 1} more)", file=sys.stderr)
|
|
113
|
-
|
|
114
117
|
sys.exit(0)
|
|
115
118
|
|
|
116
119
|
|