@uzysjung/agent-harness 26.149.0 → 26.151.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.
Files changed (65) hide show
  1. package/README.ko.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/{chunk-YSW3OLH4.js → chunk-3QBHZUVB.js} +164 -66
  4. package/dist/chunk-3QBHZUVB.js.map +1 -0
  5. package/dist/index.js +397 -293
  6. package/dist/index.js.map +1 -1
  7. package/dist/trust-tier-drift.js +5 -1
  8. package/dist/trust-tier-drift.js.map +1 -1
  9. package/package.json +1 -1
  10. package/templates/CLAUDE.md +145 -164
  11. package/templates/agents/build-error-resolver.md +1 -1
  12. package/templates/agents/plan-checker.md +1 -1
  13. package/templates/agents/reviewer.md +4 -5
  14. package/templates/antigravity/AGENTS.md.template +3 -23
  15. package/templates/codex/AGENTS.md.template +5 -56
  16. package/templates/hooks/protect-files.sh +4 -0
  17. package/templates/hooks/session-start.sh +57 -3
  18. package/templates/opencode/AGENTS.md.template +4 -52
  19. package/templates/opencode/opencode.json.template +0 -8
  20. package/templates/rules/change-management.md +0 -1
  21. package/templates/rules/cli-development.md +1 -1
  22. package/templates/rules/doc-governance.md +2 -0
  23. package/templates/rules/git-policy.md +1 -1
  24. package/templates/rules/ship-checklist.md +3 -3
  25. package/templates/rules/test-policy.md +3 -8
  26. package/templates/settings.json +1 -16
  27. package/templates/skills/agent-introspection-debugging/SKILL.md +1 -1
  28. package/templates/skills/audit-harness-fit/README.md +113 -0
  29. package/templates/skills/audit-harness-fit/SKILL.md +64 -433
  30. package/templates/skills/audit-harness-fit/evals/scenarios.yaml +222 -0
  31. package/templates/skills/audit-harness-fit/references/apply.md +66 -0
  32. package/templates/skills/audit-harness-fit/references/audit.md +160 -0
  33. package/templates/skills/audit-harness-fit/references/populate.md +74 -0
  34. package/templates/skills/audit-harness-fit/references/verification.md +123 -0
  35. package/templates/skills/audit-service-gaps/SKILL.md +6 -7
  36. package/templates/skills/clear-korean-communication/SKILL.md +8 -13
  37. package/templates/skills/compaction-handoff/SKILL.md +29 -12
  38. package/templates/skills/external-model-consult/SKILL.md +13 -24
  39. package/templates/skills/model-orchestration/SKILL.md +18 -15
  40. package/templates/skills/natural-korean/SKILL.md +45 -0
  41. package/templates/skills/north-star/SKILL.md +4 -6
  42. package/templates/skills/north-star/references/roadmap-method.md +2 -2
  43. package/templates/skills/{task-brief → objective-brief}/SKILL.md +17 -18
  44. package/templates/skills/recurrence-prevention/SKILL.md +16 -16
  45. package/dist/chunk-YSW3OLH4.js.map +0 -1
  46. package/templates/agents/code-reviewer.md +0 -237
  47. package/templates/agents/security-reviewer.md +0 -108
  48. package/templates/hooks/task-brief-nudge.sh +0 -57
  49. package/templates/skills/audit-harness-fit/references/official-criteria.md +0 -367
  50. package/templates/skills/continuous-learning-v2/SKILL.md +0 -361
  51. package/templates/skills/continuous-learning-v2/agents/observer-loop.sh +0 -362
  52. package/templates/skills/continuous-learning-v2/agents/observer.md +0 -189
  53. package/templates/skills/continuous-learning-v2/agents/session-guardian.sh +0 -150
  54. package/templates/skills/continuous-learning-v2/agents/start-observer.sh +0 -252
  55. package/templates/skills/continuous-learning-v2/config.json +0 -8
  56. package/templates/skills/continuous-learning-v2/hooks/observe.sh +0 -585
  57. package/templates/skills/continuous-learning-v2/scripts/detect-project.sh +0 -322
  58. package/templates/skills/continuous-learning-v2/scripts/instinct-cli.py +0 -1956
  59. package/templates/skills/continuous-learning-v2/scripts/lib/homunculus-dir.sh +0 -31
  60. package/templates/skills/continuous-learning-v2/scripts/migrate-homunculus.sh +0 -68
  61. package/templates/skills/continuous-learning-v2/scripts/test_parse_instinct.py +0 -1420
  62. package/templates/skills/humanize-korean/SKILL.md +0 -228
  63. package/templates/skills/spec-scaling/SKILL.md +0 -89
  64. package/templates/skills/strategic-compact/SKILL.md +0 -145
  65. package/templates/skills/strategic-compact/suggest-compact.sh +0 -54
@@ -1,322 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Continuous Learning v2 - Project Detection Helper
3
- #
4
- # Shared logic for detecting current project context.
5
- # Sourced by observe.sh and start-observer.sh.
6
- #
7
- # Exports:
8
- # _CLV2_PROJECT_ID - Short hash identifying the project (or "global")
9
- # _CLV2_PROJECT_NAME - Human-readable project name
10
- # _CLV2_PROJECT_ROOT - Absolute path to project root
11
- # _CLV2_PROJECT_DIR - Project-scoped storage directory under homunculus
12
- #
13
- # Also sets unprefixed convenience aliases:
14
- # PROJECT_ID, PROJECT_NAME, PROJECT_ROOT, PROJECT_DIR
15
- #
16
- # Detection priority:
17
- # 1. CLAUDE_PROJECT_DIR env var (if set)
18
- # 2. git remote URL (hashed for uniqueness across machines)
19
- # 3. git repo root path (fallback, machine-specific)
20
- # 4. "global" (no project context detected)
21
-
22
- # shellcheck disable=SC1091
23
- . "$(dirname "${BASH_SOURCE[0]}")/lib/homunculus-dir.sh"
24
- _CLV2_HOMUNCULUS_DIR="$(_clv2_resolve_homunculus_dir)"
25
- _CLV2_PROJECTS_DIR="${_CLV2_HOMUNCULUS_DIR}/projects"
26
- _CLV2_REGISTRY_FILE="${_CLV2_HOMUNCULUS_DIR}/projects.json"
27
-
28
- _clv2_resolve_python_cmd() {
29
- if [ -n "${CLV2_PYTHON_CMD:-}" ] && command -v "$CLV2_PYTHON_CMD" >/dev/null 2>&1; then
30
- printf '%s\n' "$CLV2_PYTHON_CMD"
31
- return 0
32
- fi
33
-
34
- if command -v python3 >/dev/null 2>&1; then
35
- printf '%s\n' python3
36
- return 0
37
- fi
38
-
39
- if command -v python >/dev/null 2>&1; then
40
- printf '%s\n' python
41
- return 0
42
- fi
43
-
44
- return 1
45
- }
46
-
47
- _CLV2_PYTHON_CMD="$(_clv2_resolve_python_cmd 2>/dev/null || true)"
48
- CLV2_PYTHON_CMD="$_CLV2_PYTHON_CMD"
49
- export CLV2_PYTHON_CMD
50
-
51
- CLV2_OBSERVER_PROMPT_PATTERN='Can you confirm|requires permission|Awaiting (user confirmation|confirmation|approval|permission)|confirm I should proceed|once granted access|grant.*access'
52
- export CLV2_OBSERVER_PROMPT_PATTERN
53
-
54
- _clv2_normalize_remote_url() {
55
- local url="$1"
56
- [ -z "$url" ] && return 0
57
-
58
- local is_network=0
59
- case "$url" in
60
- file://*) is_network=0 ;;
61
- *://*) is_network=1 ;;
62
- *@*:*) is_network=1 ;;
63
- *) is_network=0 ;;
64
- esac
65
-
66
- url=$(printf '%s' "$url" | sed -E 's|://[^@]+@|://|')
67
- url=$(printf '%s' "$url" | sed -E 's|^[A-Za-z][A-Za-z0-9+.-]*://||')
68
- url=$(printf '%s' "$url" | sed -E 's|^[^@/:]+@([^:/]+):|\1/|')
69
- url=$(printf '%s' "$url" | sed -E 's|\.git/?$||; s|/+$||')
70
-
71
- if [ "$is_network" = "1" ]; then
72
- printf '%s' "$url" | tr '[:upper:]' '[:lower:]'
73
- else
74
- printf '%s' "$url"
75
- fi
76
- }
77
-
78
- _clv2_main_worktree_root() {
79
- local root="$1"
80
- [ -z "$root" ] && return 0
81
- command -v git >/dev/null 2>&1 || return 0
82
-
83
- git -C "$root" worktree list --porcelain 2>/dev/null | while IFS= read -r line; do
84
- case "$line" in
85
- worktree\ *)
86
- printf '%s\n' "${line#worktree }"
87
- break
88
- ;;
89
- esac
90
- done
91
- }
92
-
93
- _clv2_detect_project() {
94
- local project_root=""
95
- local project_name=""
96
- local project_id=""
97
- local source_hint=""
98
-
99
- if [ "${CLV2_NO_PROJECT:-0}" = "1" ]; then
100
- _CLV2_PROJECT_ID="global"
101
- _CLV2_PROJECT_NAME="global"
102
- _CLV2_PROJECT_ROOT=""
103
- _CLV2_PROJECT_DIR="${_CLV2_HOMUNCULUS_DIR}"
104
- mkdir -p "$_CLV2_PROJECT_DIR"
105
- return 0
106
- fi
107
-
108
- # 1. Try CLAUDE_PROJECT_DIR env var
109
- if [ -n "$CLAUDE_PROJECT_DIR" ] && [ -d "$CLAUDE_PROJECT_DIR" ] && command -v git &>/dev/null; then
110
- project_root=$(git -C "$CLAUDE_PROJECT_DIR" rev-parse --show-toplevel 2>/dev/null || true)
111
- if [ -n "$project_root" ]; then
112
- source_hint="env"
113
- fi
114
- fi
115
-
116
- # 2. Try git repo root from CWD (only if git is available)
117
- if [ -z "$project_root" ] && command -v git &>/dev/null; then
118
- project_root=$(git rev-parse --show-toplevel 2>/dev/null || true)
119
- if [ -n "$project_root" ]; then
120
- source_hint="git"
121
- fi
122
- fi
123
-
124
- # 3. No project detected — fall back to global
125
- if [ -z "$project_root" ]; then
126
- _CLV2_PROJECT_ID="global"
127
- _CLV2_PROJECT_NAME="global"
128
- _CLV2_PROJECT_ROOT=""
129
- _CLV2_PROJECT_DIR="${_CLV2_HOMUNCULUS_DIR}"
130
- mkdir -p "$_CLV2_PROJECT_DIR"
131
- return 0
132
- fi
133
-
134
- # Derive project name from directory basename
135
- # Normalize Windows backslashes so basename works when CLAUDE_PROJECT_DIR
136
- # is passed as e.g. C:\Users\...\project.
137
- local _norm_root
138
- _norm_root=$(printf '%s' "$project_root" | sed 's|\\|/|g')
139
- project_name=$(basename "$_norm_root")
140
-
141
- # Derive project ID: prefer git remote URL hash (portable across machines),
142
- # fall back to path hash (machine-specific but still useful)
143
- local remote_url=""
144
- if command -v git &>/dev/null; then
145
- if [ "$source_hint" = "git" ] || [ -e "${project_root}/.git" ]; then
146
- remote_url=$(git -C "$project_root" remote get-url origin 2>/dev/null || true)
147
- fi
148
- fi
149
-
150
- local raw_remote_url="$remote_url"
151
-
152
- # Strip embedded credentials from remote URL (e.g., https://ghp_xxxx@github.com/...)
153
- if [ -n "$remote_url" ]; then
154
- remote_url=$(printf '%s' "$remote_url" | sed -E 's|://[^@]+@|://|')
155
- fi
156
-
157
- local legacy_hash_input="${remote_url:-$project_root}"
158
- local normalized_remote=""
159
- if [ -n "$remote_url" ]; then
160
- normalized_remote=$(_clv2_normalize_remote_url "$remote_url")
161
- fi
162
-
163
- local fallback_root="$project_root"
164
- if [ -z "$remote_url" ]; then
165
- local main_worktree_root
166
- main_worktree_root=$(_clv2_main_worktree_root "$project_root")
167
- [ -n "$main_worktree_root" ] && fallback_root="$main_worktree_root"
168
- fi
169
-
170
- local hash_input="${normalized_remote:-${remote_url:-$fallback_root}}"
171
- # Prefer Python for consistent SHA256 behavior across shells/platforms.
172
- # Pass the value via env var and encode as UTF-8 inside Python so the hash
173
- # is locale-independent (shells vary between UTF-8 / CP932 / CP1252, which
174
- # would otherwise produce different hashes for the same non-ASCII path).
175
- if [ -n "$_CLV2_PYTHON_CMD" ]; then
176
- project_id=$(_CLV2_HASH_INPUT="$hash_input" "$_CLV2_PYTHON_CMD" -c '
177
- import os, hashlib
178
- s = os.environ["_CLV2_HASH_INPUT"]
179
- print(hashlib.sha256(s.encode("utf-8")).hexdigest()[:12])
180
- ' 2>/dev/null)
181
- fi
182
-
183
- # Fallback if Python is unavailable or hash generation failed.
184
- if [ -z "$project_id" ]; then
185
- project_id=$(printf '%s' "$hash_input" | shasum -a 256 2>/dev/null | cut -c1-12 || \
186
- printf '%s' "$hash_input" | sha256sum 2>/dev/null | cut -c1-12 || \
187
- echo "fallback")
188
- fi
189
-
190
- # Backward compatibility: migrate a single legacy project directory from
191
- # credential-stripped or raw remote hashes to the normalized remote hash.
192
- if [ -n "$_CLV2_PYTHON_CMD" ] && [ ! -d "${_CLV2_PROJECTS_DIR}/${project_id}" ]; then
193
- local legacy_inputs=()
194
- [ -n "$legacy_hash_input" ] && [ "$legacy_hash_input" != "$hash_input" ] \
195
- && legacy_inputs+=("$legacy_hash_input")
196
- [ -n "$raw_remote_url" ] && [ "$raw_remote_url" != "$hash_input" ] \
197
- && [ "$raw_remote_url" != "$legacy_hash_input" ] \
198
- && legacy_inputs+=("$raw_remote_url")
199
-
200
- local legacy_input legacy_id
201
- for legacy_input in "${legacy_inputs[@]}"; do
202
- legacy_id=$(_CLV2_HASH_INPUT="$legacy_input" "$_CLV2_PYTHON_CMD" -c '
203
- import os, hashlib
204
- s = os.environ["_CLV2_HASH_INPUT"]
205
- print(hashlib.sha256(s.encode("utf-8")).hexdigest()[:12])
206
- ' 2>/dev/null)
207
- if [ -n "$legacy_id" ] && [ "$legacy_id" != "$project_id" ] \
208
- && [ -d "${_CLV2_PROJECTS_DIR}/${legacy_id}" ]; then
209
- if mv "${_CLV2_PROJECTS_DIR}/${legacy_id}" "${_CLV2_PROJECTS_DIR}/${project_id}" 2>/dev/null; then
210
- break
211
- else
212
- project_id="$legacy_id"
213
- break
214
- fi
215
- fi
216
- done
217
- fi
218
-
219
- # Export results
220
- _CLV2_PROJECT_ID="$project_id"
221
- _CLV2_PROJECT_NAME="$project_name"
222
- _CLV2_PROJECT_ROOT="$project_root"
223
- _CLV2_PROJECT_DIR="${_CLV2_PROJECTS_DIR}/${project_id}"
224
-
225
- # Ensure project directory structure exists
226
- mkdir -p "${_CLV2_PROJECT_DIR}/instincts/personal"
227
- mkdir -p "${_CLV2_PROJECT_DIR}/instincts/inherited"
228
- mkdir -p "${_CLV2_PROJECT_DIR}/observations.archive"
229
- mkdir -p "${_CLV2_PROJECT_DIR}/evolved/skills"
230
- mkdir -p "${_CLV2_PROJECT_DIR}/evolved/commands"
231
- mkdir -p "${_CLV2_PROJECT_DIR}/evolved/agents"
232
-
233
- # Update project registry (lightweight JSON mapping)
234
- _clv2_update_project_registry "$project_id" "$project_name" "$project_root" "$remote_url"
235
- }
236
-
237
- _clv2_update_project_registry() {
238
- local pid="$1"
239
- local pname="$2"
240
- local proot="$3"
241
- local premote="$4"
242
- local pdir="$_CLV2_PROJECT_DIR"
243
-
244
- mkdir -p "$(dirname "$_CLV2_REGISTRY_FILE")"
245
-
246
- if [ -z "$_CLV2_PYTHON_CMD" ]; then
247
- return 0
248
- fi
249
-
250
- # Pass values via env vars to avoid shell→python injection.
251
- # Python reads them with os.environ, which is safe for any string content.
252
- _CLV2_REG_PID="$pid" \
253
- _CLV2_REG_PNAME="$pname" \
254
- _CLV2_REG_PROOT="$proot" \
255
- _CLV2_REG_PREMOTE="$premote" \
256
- _CLV2_REG_PDIR="$pdir" \
257
- _CLV2_REG_FILE="$_CLV2_REGISTRY_FILE" \
258
- "$_CLV2_PYTHON_CMD" -c '
259
- import json, os, tempfile
260
- from datetime import datetime, timezone
261
-
262
- registry_path = os.environ["_CLV2_REG_FILE"]
263
- project_dir = os.environ["_CLV2_REG_PDIR"]
264
- project_file = os.path.join(project_dir, "project.json")
265
-
266
- os.makedirs(project_dir, exist_ok=True)
267
-
268
- def atomic_write_json(path, payload):
269
- fd, tmp_path = tempfile.mkstemp(
270
- prefix=f".{os.path.basename(path)}.tmp.",
271
- dir=os.path.dirname(path),
272
- text=True,
273
- )
274
- try:
275
- with os.fdopen(fd, "w") as f:
276
- json.dump(payload, f, indent=2)
277
- f.write("\n")
278
- os.replace(tmp_path, path)
279
- finally:
280
- if os.path.exists(tmp_path):
281
- os.unlink(tmp_path)
282
-
283
- try:
284
- with open(registry_path) as f:
285
- registry = json.load(f)
286
- except (FileNotFoundError, json.JSONDecodeError):
287
- registry = {}
288
-
289
- now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
290
- entry = registry.get(os.environ["_CLV2_REG_PID"], {})
291
-
292
- metadata = {
293
- "id": os.environ["_CLV2_REG_PID"],
294
- "name": os.environ["_CLV2_REG_PNAME"],
295
- "root": os.environ["_CLV2_REG_PROOT"],
296
- "remote": os.environ["_CLV2_REG_PREMOTE"],
297
- "created_at": entry.get("created_at", now),
298
- "last_seen": now,
299
- }
300
-
301
- registry[os.environ["_CLV2_REG_PID"]] = metadata
302
-
303
- atomic_write_json(project_file, metadata)
304
- atomic_write_json(registry_path, registry)
305
- ' 2>/dev/null || true
306
- }
307
-
308
- # Auto-detect on source
309
- _clv2_detect_project
310
-
311
- # Convenience aliases for callers (short names pointing to prefixed vars)
312
- PROJECT_ID="$_CLV2_PROJECT_ID"
313
- PROJECT_NAME="$_CLV2_PROJECT_NAME"
314
- PROJECT_ROOT="$_CLV2_PROJECT_ROOT"
315
- PROJECT_DIR="$_CLV2_PROJECT_DIR"
316
-
317
- if [ -n "$PROJECT_ROOT" ]; then
318
- CLV2_OBSERVER_SENTINEL_FILE="${PROJECT_ROOT}/.observer.lock"
319
- else
320
- CLV2_OBSERVER_SENTINEL_FILE="${PROJECT_DIR}/.observer.lock"
321
- fi
322
- export CLV2_OBSERVER_SENTINEL_FILE