therookie 0.4.32 → 0.4.34

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/README.md CHANGED
@@ -1,11 +1,17 @@
1
1
  # therookie
2
2
 
3
- **the Rookie** — the AI new hire that remembers what you teach it. A CLI that connects a personal AI memory ("the Rookie") to AI tools like Claude and Codex. It remembers your company, projects, context, and preferences across sessions.
3
+ You correct the same thing three times, your AI finally gets it, and then you open a new session and it's gone.
4
+
5
+ **the Rookie** keeps what you taught outside the conversation. When the next session starts, your AI reads it first. The name, tone, and working habits you gave it stay too — close Claude Code, open Codex, and the same coworker shows up.
6
+
7
+ It's the AI new hire that remembers what you teach it. A CLI that connects a personal memory to AI tools like Claude and Codex.
4
8
 
5
9
  - Homepage: https://therookie.kr
6
10
  - Guide: https://therookie.kr/guide
7
11
  - Maintained by: Rolling Mango Corp.
8
12
 
13
+ > Early access. You need an invite code to sign up — request one at https://therookie.kr. Free during early access.
14
+
9
15
  ## Install
10
16
 
11
17
  ```sh
package/package.json CHANGED
@@ -1,15 +1,26 @@
1
1
  {
2
2
  "name": "therookie",
3
- "version": "0.4.32",
4
- "description": "the Rookie — the AI new hire that remembers what you teach it. A CLI that connects a personal AI memory to AI tools like Claude and Codex.",
3
+ "version": "0.4.34",
4
+ "description": "Persistent memory for Claude Code and Codex CLI — teach your AI once and it remembers across sessions, tools, and machines. The AI new hire that remembers what you teach it.",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "ai",
8
8
  "memory",
9
+ "ai-memory",
10
+ "agent-memory",
11
+ "persistent-memory",
12
+ "long-term-memory",
13
+ "llm",
9
14
  "claude",
10
15
  "claude-code",
16
+ "claude-code-hooks",
11
17
  "codex",
18
+ "codex-cli",
12
19
  "mcp",
20
+ "cli",
21
+ "ai-agent",
22
+ "coding-agent",
23
+ "context",
13
24
  "rookie",
14
25
  "the-rookie"
15
26
  ],
@@ -13,7 +13,11 @@ import { execFileSync } from 'node:child_process'
13
13
  import { readFileSync } from 'node:fs'
14
14
  import { loadConfig, getHostname } from '../config.js'
15
15
  import { apiPost } from '../api.js'
16
- import { recordSessionWrite } from '../lib/session-write-marker.js'
16
+ import {
17
+ recordSessionWrite,
18
+ resolveSessionId,
19
+ clearNoWritesPending,
20
+ } from '../lib/session-write-marker.js'
17
21
 
18
22
  // 저장된 층을 **빠짐없이** 화면에 센다. 여기 없는 층은 서버가 저장해도 0건처럼 보인다 —
19
23
  // 2026-09-02 저장에서 durable fact 3건이 그렇게 안 보였고, metric·recall 로 따로 확인해야
@@ -118,9 +122,12 @@ export async function runSave(flags) {
118
122
  }
119
123
 
120
124
  // spec 2026-09-08 §2.4 — 이 세션에 저장이 있었다는 로컬 마커. Stop hook 이 없으면 미추출 큐에 넣는다.
121
- // --session 미전달이면 아무것도 안 한다(기존 호출자 호환).
125
+ // --session 이 없으면 실행 환경의 세션 id 로 채운다. 이미 올라간 '저장 0건' 대기도 닫는다 —
126
+ // 나중에 저장한 세션이 큐에 남아 만료로 버려지던 경로(2026-09-16).
122
127
  if (res.all_committed !== false) {
123
- recordSessionWrite(typeof flags.session === 'string' ? flags.session : '')
128
+ const sessionId = resolveSessionId(typeof flags.session === 'string' ? flags.session : '')
129
+ recordSessionWrite(sessionId)
130
+ clearNoWritesPending(sessionId)
124
131
  }
125
132
 
126
133
  if (flags.json) {
@@ -7,14 +7,49 @@
7
7
  // 구간 경계를 skill-gate 의 .epoch 로 따로 감지한다). 세션 단위 키만 쓰면 clear 이전 구간에
8
8
  // 저장이 있었다는 이유로 이후 구간이 통째로 면제된다.
9
9
  import { createHash } from 'node:crypto'
10
- import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs'
10
+ import { mkdirSync, writeFileSync, existsSync, readFileSync, rmSync } from 'node:fs'
11
11
  import { join } from 'node:path'
12
12
  import { homedir } from 'node:os'
13
13
 
14
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
15
+
14
16
  export function markerDir() {
15
17
  return process.env.ROOKIE_SESSION_WRITES_DIR || join(homedir(), '.rookie', 'session-writes')
16
18
  }
17
19
 
20
+ function orphanRoot() {
21
+ return process.env.ROOKIE_ORPHAN_DIR || join(homedir(), '.rookie', 'orphan-recovery')
22
+ }
23
+
24
+ /**
25
+ * 저장에 쓸 세션 id. 명시값이 없으면 Claude Code 가 실행 환경에 주는 값으로 채운다.
26
+ *
27
+ * 스킬은 `--session` 을 "세션 시작 컨텍스트에서 받은 값" 으로 안내했는데 그 응답에는 세션
28
+ * 식별자가 없다 — 그래서 마커가 사실상 안 남았다(2026-09-16 실측: 마커 2개 vs 7일 저장 191건).
29
+ * 마커가 없으면 Stop hook 이 모든 세션을 "저장 0건" 으로 보고 큐에 올린다.
30
+ */
31
+ export function resolveSessionId(explicit) {
32
+ if (typeof explicit === 'string' && explicit) return explicit
33
+ const env = process.env.CLAUDE_CODE_SESSION_ID
34
+ return typeof env === 'string' && UUID_RE.test(env) ? env : ''
35
+ }
36
+
37
+ /**
38
+ * 저장이 생겼으니 "저장 0건" 대기는 더 이상 참이 아니다 — 그 표시만 지운다.
39
+ * 비정상 종료 복구 대기(reason 없음)는 tail 이 아직 안 건져졌으므로 건드리지 않는다.
40
+ */
41
+ export function clearNoWritesPending(sessionId) {
42
+ if (!sessionId) return false
43
+ try {
44
+ const f = join(orphanRoot(), 'pending-extraction', sessionId + '.json')
45
+ if (JSON.parse(readFileSync(f, 'utf8'))?.reason !== 'no_writes') return false
46
+ rmSync(f, { force: true })
47
+ return true
48
+ } catch {
49
+ return false
50
+ }
51
+ }
52
+
18
53
  function gateDir() {
19
54
  return process.env.ROOKIE_SKILL_GATE_DIR || join(homedir(), '.rookie', 'skill-gate')
20
55
  }
@@ -5,12 +5,14 @@
5
5
  ## 호출 방법
6
6
 
7
7
  ```bash
8
- rookie save --file <body.json> --session <session_id> # 또는: echo '<body>' | rookie save --session <id>
8
+ rookie save --file <body.json> # 또는: echo '<body>' | rookie save
9
+ rookie save --file <body.json> --session <session_id> # 세션 id 를 명시해야 하는 경로에서만
9
10
  ```
10
11
 
11
- `--session` 은 **세션 시작 컨텍스트에서 받은 session_id** 다. 저장이 성공하면 로컬 마커를 남겨,
12
- Stop hook 이 "이 세션은 아무것도 저장하지 않았다"를 판정할 수 있게 한다(spec 2026-09-08 §2.4).
13
- 빠뜨려도 저장은 정상 동작하지만, **그 세션은 저장 0건으로 오인돼 미추출 큐에 올라간다** — 붙이는 편이 낫다.
12
+ `--session` 은 **대개 붙일 필요가 없다** — Claude Code 세션에서는 CLI 가 실행 환경의 세션 id
13
+ (`CLAUDE_CODE_SESSION_ID`)로 스스로 채운다. 저장이 성공하면 로컬 마커를 남겨 Stop hook 이
14
+ "이 세션은 아무것도 저장하지 않았다"를 판정할 수 있게 하고(spec 2026-09-08 §2.4), 이미 올라간
15
+ '저장 0건' 대기 표시가 있으면 함께 지운다. 환경 변수가 없는 실행 경로에서만 명시한다.
14
16
  ⚠️ **`curl` 로 직접 batch-mutate 금지** — `rookie save` 가 cwd·git remote·hostname 을 자동 주입해 전역 누수를 막는다. 본문엔 **기억할 내용만**.
15
17
 
16
18
  ⚠️ **전역 fact 는 `project_id: null` 을 명시한다.** 식별자도 명시 의사도 없으면 서버가 `missing_workspace_context` 로 **거부**. 미등록 폴더 저장은 **그 폴더에 격리**, `rookie link` 시 자동 승격.
package/version.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "cli_version": "0.4.32",
3
- "skill_version": "1.40.0"
2
+ "cli_version": "0.4.34",
3
+ "skill_version": "1.40.1"
4
4
  }