@codeyam/codeyam-cli 0.1.6 → 0.1.7

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 (33) hide show
  1. package/analyzer-template/.build-info.json +6 -6
  2. package/analyzer-template/log.txt +3 -3
  3. package/codeyam-cli/src/commands/memory.js +26 -2
  4. package/codeyam-cli/src/commands/memory.js.map +1 -1
  5. package/codeyam-cli/src/utils/transcriptPruning.js +67 -0
  6. package/codeyam-cli/src/utils/transcriptPruning.js.map +1 -0
  7. package/codeyam-cli/src/webserver/backgroundServer.js +1 -1
  8. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  9. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-Dm5RS9il.js +22 -0
  10. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._--zvFJ4OH.js → entity._sha._-C6PQhwY5.js} +9 -9
  11. package/codeyam-cli/src/webserver/build/client/assets/globals-CLmFdUae.css +1 -0
  12. package/codeyam-cli/src/webserver/build/client/assets/manifest-717e346a.js +1 -0
  13. package/codeyam-cli/src/webserver/build/client/assets/{memory-CfpYxpNu.js → memory-0wMU4KXe.js} +28 -28
  14. package/codeyam-cli/src/webserver/build/client/assets/{root-CAAbm4U5.js → root-DqfSDjyQ.js} +13 -13
  15. package/codeyam-cli/src/webserver/build/client/assets/settings-BWunYSXt.js +1 -0
  16. package/codeyam-cli/src/webserver/build/server/assets/{index-B8A_aaGG.js → index-B8jmgmn2.js} +1 -1
  17. package/codeyam-cli/src/webserver/build/server/assets/{server-build-69rRZnZo.js → server-build-9OU4lmvL.js} +73 -74
  18. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  19. package/codeyam-cli/src/webserver/build-info.json +5 -5
  20. package/codeyam-cli/templates/prompts/conversation-guidance.txt +12 -0
  21. package/codeyam-cli/templates/prompts/conversation-prompt.txt +3 -3
  22. package/codeyam-cli/templates/prompts/interruption-prompt.txt +3 -3
  23. package/codeyam-cli/templates/prompts/stale-rules-prompt.txt +3 -3
  24. package/codeyam-cli/templates/rule-notification-hook.py +44 -17
  25. package/codeyam-cli/templates/rule-reflection-hook.py +24 -4
  26. package/codeyam-cli/templates/rules-instructions.md +4 -3
  27. package/package.json +1 -1
  28. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js +0 -486
  29. package/codeyam-cli/src/webserver/app/routes/api.agent-transcripts.js.map +0 -1
  30. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DxCa1oBt.js +0 -23
  31. package/codeyam-cli/src/webserver/build/client/assets/globals-B4MPiL7S.css +0 -1
  32. package/codeyam-cli/src/webserver/build/client/assets/manifest-c1fc3656.js +0 -1
  33. package/codeyam-cli/src/webserver/build/client/assets/settings-BpLDWmGh.js +0 -1
@@ -1 +1 @@
1
- import{Y as H,Z as I,M as J,N as K,W as L,O as _,R as $,T as rr,V as tr,U as or,X as ir,Q as pr}from"./assets/server-build-69rRZnZo.js";import"react/jsx-runtime";import"node:stream";import"@react-router/node";import"react-router";import"isbot";import"react-dom/server";import"react";import"lucide-react";import"fetch-retry";import"better-sqlite3";import"pg";import"fs";import"path";import"kysely";import"kysely/helpers/sqlite";import"kysely/helpers/postgres";import"typescript";import"fs/promises";import"os";import"prompts";import"chalk";import"crypto";import"child_process";import"url";import"util";import"dotenv";import"events";import"uuid";import"openai";import"p-queue";import"p-retry";import"@aws-sdk/client-dynamodb";import"lru-cache";import"pluralize";import"piscina";import"json5";import"@aws-sdk/util-dynamodb";import"v8";import"react-syntax-highlighter";import"react-syntax-highlighter/dist/cjs/styles/prism/index.js";import"node:crypto";import"minimatch";import"react-markdown";import"remark-gfm";import"react-diff-viewer-continued";export{H as allowedActionOrigins,I as assets,J as assetsBuildDirectory,K as basename,L as entry,_ as future,$ as isSpaMode,rr as prerender,tr as publicPath,or as routeDiscovery,ir as routes,pr as ssr};
1
+ import{Y as H,Z as I,M as J,N as K,W as L,O as _,R as $,T as rr,V as tr,U as or,X as ir,Q as pr}from"./assets/server-build-9OU4lmvL.js";import"react/jsx-runtime";import"node:stream";import"@react-router/node";import"react-router";import"isbot";import"react-dom/server";import"react";import"lucide-react";import"fetch-retry";import"better-sqlite3";import"pg";import"fs";import"path";import"kysely";import"kysely/helpers/sqlite";import"kysely/helpers/postgres";import"typescript";import"fs/promises";import"os";import"prompts";import"chalk";import"crypto";import"child_process";import"url";import"util";import"dotenv";import"events";import"uuid";import"openai";import"p-queue";import"p-retry";import"@aws-sdk/client-dynamodb";import"lru-cache";import"pluralize";import"piscina";import"json5";import"@aws-sdk/util-dynamodb";import"v8";import"react-syntax-highlighter";import"react-syntax-highlighter/dist/cjs/styles/prism/index.js";import"node:crypto";import"minimatch";import"react-markdown";import"remark-gfm";import"react-diff-viewer-continued";export{H as allowedActionOrigins,I as assets,J as assetsBuildDirectory,K as basename,L as entry,_ as future,$ as isSpaMode,rr as prerender,tr as publicPath,or as routeDiscovery,ir as routes,pr as ssr};
@@ -1,7 +1,7 @@
1
1
  {
2
- "buildTimestamp": "2026-02-24T16:49:39.429Z",
3
- "buildTime": 1771951779429,
4
- "buildNumber": 694,
5
- "semanticVersion": "0.1.694",
6
- "version": "0.1.694 (2026-02-24T16:49)"
2
+ "buildTimestamp": "2026-02-25T00:13:21.654Z",
3
+ "buildTime": 1771978401654,
4
+ "buildNumber": 724,
5
+ "semanticVersion": "0.1.724",
6
+ "version": "0.1.724 (2026-02-25T00:13)"
7
7
  }
@@ -30,3 +30,15 @@ Read the full transcript for these signals:
30
30
  **Critical check:** Read the actual source files that were modified. If the code already contains comments, guard patterns, or tests that explain the insight, the code is the documentation — skip the rule unless the file is complex and you've made a mistake or the user had to interrupt and correct you.
31
31
 
32
32
  Show your thinking before proceeding with creating or updating rules.
33
+
34
+ ### How to write rules
35
+
36
+ **Rules must be forward-looking, not historical.** You are reading a session transcript where bugs were found and fixed, but the rule should describe the *current* codebase, not tell the story of what went wrong, what was fixed, etc. The code has already been updated — past bugs are no longer relevant.
37
+
38
+ - **DO**: State constraints and requirements ("this script MUST copy directories recursively, not just files")
39
+ - **DO**: Explain *why* something matters ("errors in prompt copying are silently caught, so missing directories won't surface as errors")
40
+ - **DON'T**: Describe what old code did ("the old version only copied files, causing X to be missing")
41
+ - **DON'T**: Narrate the debugging journey ("we discovered that the catch block was swallowing errors")
42
+ - **DON'T**: Note issues or known gaps if they are actively being worked on!
43
+
44
+ Think of the reader as a developer about to modify these files. They need to know what constraints to preserve and what pitfalls to watch for — not what happened in the past if it is no longer relevant.
@@ -23,6 +23,6 @@ The project root is {{PROJECT_DIR}}
23
23
 
24
24
  CRITICAL: All rule files MUST be written to {{PROJECT_DIR}}/.claude/rules/ (the project directory). Always use the full absolute path when writing rule files.
25
25
 
26
- CRITICAL: Before writing any rule file, you MUST call the rule-path API to determine the correct subdirectory:
27
- curl -s 'http://localhost:3111/api/rule-path?paths=path/one&paths=path/two'
28
- Pass all paths from your frontmatter. The API returns the correct .claude/rules/ subdirectory. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
26
+ CRITICAL: Before writing any rule file, you MUST run the rule-path command to determine the correct subdirectory:
27
+ codeyam memory rule-path path/one path/two
28
+ Pass all paths from your frontmatter. The command returns the correct .claude/rules/ subdirectory as JSON. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
@@ -26,6 +26,6 @@ The project root is {{PROJECT_DIR}}
26
26
 
27
27
  CRITICAL: All rule files MUST be written to {{PROJECT_DIR}}/.claude/rules/ (the project directory). Always use the full absolute path when writing rule files.
28
28
 
29
- CRITICAL: Before writing any rule file, you MUST call the rule-path API to determine the correct subdirectory:
30
- curl -s 'http://localhost:3111/api/rule-path?paths=path/one&paths=path/two'
31
- Pass all paths from your frontmatter. The API returns the correct .claude/rules/ subdirectory. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
29
+ CRITICAL: Before writing any rule file, you MUST run the rule-path command to determine the correct subdirectory:
30
+ codeyam memory rule-path path/one path/two
31
+ Pass all paths from your frontmatter. The command returns the correct .claude/rules/ subdirectory as JSON. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
@@ -19,6 +19,6 @@ The project root is {{PROJECT_DIR}}
19
19
 
20
20
  CRITICAL: All rule files MUST be written to {{PROJECT_DIR}}/.claude/rules/ (the project directory), NOT ~/.claude/rules/ (the user home directory). Always use the full absolute path when writing rule files.
21
21
 
22
- CRITICAL: Before writing any rule file, you MUST call the rule-path API to determine the correct subdirectory:
23
- curl -s 'http://localhost:3111/api/rule-path?paths=path/one&paths=path/two'
24
- Pass all paths from your frontmatter. The API returns the correct .claude/rules/ subdirectory. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
22
+ CRITICAL: Before writing any rule file, you MUST run the rule-path command to determine the correct subdirectory:
23
+ codeyam memory rule-path path/one path/two
24
+ Pass all paths from your frontmatter. The command returns the correct .claude/rules/ subdirectory as JSON. Do NOT guess the placement from the first path — rules with paths spanning multiple directories belong at their common ancestor.
@@ -14,6 +14,7 @@ Supports four notification files (legacy combined + split agents):
14
14
  - rule-notification-interruption.md (interruption review agent)
15
15
  """
16
16
 
17
+ import json
17
18
  import os
18
19
  import sys
19
20
 
@@ -26,27 +27,53 @@ NOTIFICATION_FILES = [
26
27
  ]
27
28
 
28
29
 
30
+ def get_project_slug():
31
+ """
32
+ Derive project slug from .codeyam/config.json (matching getProjectSlug() on the TS side).
33
+ Falls back to os.path.basename(project_dir) if config is absent or malformed.
34
+ """
35
+ project_dir = os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
36
+ try:
37
+ config_path = os.path.join(project_dir, '.codeyam', 'config.json')
38
+ with open(config_path, 'r') as f:
39
+ config = json.load(f)
40
+ slug = config.get('projectSlug', '')
41
+ if slug:
42
+ return slug
43
+ except (IOError, json.JSONDecodeError, KeyError):
44
+ pass
45
+ return os.path.basename(project_dir)
46
+
47
+
29
48
  def main():
30
49
  collected = []
50
+ slug = get_project_slug()
51
+
52
+ # Check slug subdirectory first, then fall back to flat directory
53
+ dirs_to_check = [os.path.join(MARKER_DIR, slug), MARKER_DIR]
31
54
 
32
55
  for filename in NOTIFICATION_FILES:
33
- filepath = os.path.join(MARKER_DIR, filename)
34
- if not os.path.exists(filepath):
35
- continue
36
-
37
- try:
38
- with open(filepath, 'r') as f:
39
- content = f.read().strip()
40
- except IOError:
41
- continue
42
-
43
- if content:
44
- collected.append(content)
45
-
46
- try:
47
- os.remove(filepath)
48
- except OSError:
49
- pass
56
+ for check_dir in dirs_to_check:
57
+ filepath = os.path.join(check_dir, filename)
58
+ if not os.path.exists(filepath):
59
+ continue
60
+
61
+ try:
62
+ with open(filepath, 'r') as f:
63
+ content = f.read().strip()
64
+ except IOError:
65
+ continue
66
+
67
+ if content:
68
+ collected.append(content)
69
+
70
+ try:
71
+ os.remove(filepath)
72
+ except OSError:
73
+ pass
74
+
75
+ # Found in this directory — don't check the fallback
76
+ break
50
77
 
51
78
  if collected:
52
79
  print('\n\n'.join(collected))
@@ -120,6 +120,24 @@ def read_rule_content(rule_name):
120
120
  return text
121
121
 
122
122
 
123
+ def get_project_slug():
124
+ """
125
+ Derive project slug from .codeyam/config.json (matching getProjectSlug() on the TS side).
126
+ Falls back to os.path.basename(project_dir) if config is absent or malformed.
127
+ """
128
+ project_dir = os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
129
+ try:
130
+ config_path = os.path.join(project_dir, '.codeyam', 'config.json')
131
+ with open(config_path, 'r') as f:
132
+ config = json.load(f)
133
+ slug = config.get('projectSlug', '')
134
+ if slug:
135
+ return slug
136
+ except (IOError, json.JSONDecodeError, KeyError):
137
+ pass
138
+ return os.path.basename(project_dir)
139
+
140
+
123
141
  def load_memory_settings():
124
142
  """
125
143
  Load memory settings from .codeyam/config.json.
@@ -463,8 +481,9 @@ def handle_stop(hook_input):
463
481
  if not session_id or not transcript_path:
464
482
  return
465
483
 
466
- marker_dir = Path('/tmp/claude-rule-markers')
467
- marker_dir.mkdir(exist_ok=True)
484
+ slug = get_project_slug()
485
+ marker_dir = Path('/tmp/claude-rule-markers') / slug
486
+ marker_dir.mkdir(parents=True, exist_ok=True)
468
487
  marker_file = marker_dir / f'{session_id}.marker'
469
488
 
470
489
  last_line, _ = read_marker(marker_file)
@@ -539,8 +558,9 @@ def handle_user_prompt_submit(hook_input):
539
558
  if not session_id or not transcript_path:
540
559
  return
541
560
 
542
- marker_dir = Path('/tmp/claude-rule-markers')
543
- marker_dir.mkdir(exist_ok=True)
561
+ slug = get_project_slug()
562
+ marker_dir = Path('/tmp/claude-rule-markers') / slug
563
+ marker_dir.mkdir(parents=True, exist_ok=True)
544
564
  marker_file = marker_dir / f'{session_id}.marker'
545
565
 
546
566
  last_line, was_stop = read_marker(marker_file)
@@ -61,17 +61,18 @@ Audit dates live in `.claude/codeyam-rule-state.json` (managed by `codeyam memor
61
61
 
62
62
  Rules must be written to `.claude/rules/`, NOT `.codeyam/rules/`. The instructions file lives in `.codeyam/` but actual rule files go in `.claude/rules/`.
63
63
 
64
- Use the `rule-path` API to compute the correct directory from your frontmatter paths:
64
+ Use `codeyam memory rule-path` to compute the correct directory from your frontmatter paths:
65
65
 
66
66
  ```
67
- $ curl -s 'http://localhost:3111/api/rule-path?paths=packages/ai/src/lib/foo.ts&paths=packages/ai/src/utils/bar.ts'
67
+ $ codeyam memory rule-path packages/ai/src/lib/foo.ts packages/ai/src/utils/bar.ts
68
68
  {"result":".claude/rules/packages/ai/src/"}
69
69
  ```
70
70
 
71
- The API computes the deepest common directory shared by all paths and returns the `.claude/rules/` subdirectory where the rule file should live. Reserve the top level of `.claude/rules/` for rules whose paths genuinely span the entire repo.
71
+ The command computes the deepest common directory shared by all paths and returns the `.claude/rules/` subdirectory where the rule file should live. Reserve the top level of `.claude/rules/` for rules whose paths genuinely span the entire repo.
72
72
 
73
73
  ## Content Guidelines
74
74
 
75
75
  - **Be actionable** — "Run `pnpm test:api` for API tests" not "Make sure to run the appropriate tests"
76
76
  - **Focus on why, not what** — Gotchas, non-obvious behavior, architectural decisions. The code already shows "what."
77
77
  - **Point to specifics** — "Auth tokens are stored in httpOnly cookies via `src/auth/cookies.ts`" beats a vague description.
78
+ - **Be short!** - Context window space is precious! Do not ramble, use bullets, focus on providing clear actionable information.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeyam/codeyam-cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Local development CLI for CodeYam analysis",
5
5
  "type": "module",
6
6
  "bin": {