tlc-claude-code 2.4.3 → 2.4.4
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/.claude/commands/tlc/build.md +7 -5
- package/.claude/commands/tlc/recall.md +59 -87
- package/.claude/commands/tlc/remember.md +76 -71
- package/.claude/commands/tlc/review.md +76 -21
- package/.claude/hooks/tlc-capture-exchange.sh +50 -21
- package/.claude/hooks/tlc-session-init.sh +30 -0
- package/bin/init.js +12 -3
- package/package.json +1 -1
- package/server/lib/capture/classifier.js +71 -0
- package/server/lib/capture/classifier.test.js +71 -0
- package/server/lib/capture/claude-capture.js +140 -0
- package/server/lib/capture/claude-capture.test.js +152 -0
- package/server/lib/capture/codex-capture.js +79 -0
- package/server/lib/capture/codex-capture.test.js +161 -0
- package/server/lib/capture/codex-event-parser.js +76 -0
- package/server/lib/capture/codex-event-parser.test.js +83 -0
- package/server/lib/capture/ensure-ready.js +56 -0
- package/server/lib/capture/ensure-ready.test.js +135 -0
- package/server/lib/capture/envelope.js +77 -0
- package/server/lib/capture/envelope.test.js +169 -0
- package/server/lib/capture/extractor.js +51 -0
- package/server/lib/capture/extractor.test.js +92 -0
- package/server/lib/capture/generic-capture.js +96 -0
- package/server/lib/capture/generic-capture.test.js +171 -0
- package/server/lib/capture/index.js +117 -0
- package/server/lib/capture/index.test.js +263 -0
- package/server/lib/capture/redactor.js +68 -0
- package/server/lib/capture/redactor.test.js +93 -0
- package/server/lib/capture/spool-processor.js +155 -0
- package/server/lib/capture/spool-processor.test.js +278 -0
- package/server/lib/health-check.js +255 -0
- package/server/lib/health-check.test.js +243 -0
- package/server/lib/orchestration/cli-dispatch.js +200 -0
- package/server/lib/orchestration/cli-dispatch.test.js +242 -0
- package/server/lib/orchestration/prompt-builder.js +118 -0
- package/server/lib/orchestration/prompt-builder.test.js +200 -0
- package/server/lib/orchestration/standalone-compat.js +39 -0
- package/server/lib/orchestration/standalone-compat.test.js +144 -0
- package/server/lib/orchestration/worktree-manager.js +43 -0
- package/server/lib/orchestration/worktree-manager.test.js +50 -0
|
@@ -83,16 +83,18 @@ process.stdout.write(JSON.stringify(result));" 2>/dev/null
|
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
2. If `models[0]` is NOT `claude` (i.e., routed to external model):
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
- Dispatch
|
|
89
|
-
-
|
|
86
|
+
- Resolve modules with fallback: try `tlc-claude-code/server/lib/...` first, then `$PROJECT_DIR/server/lib/...`
|
|
87
|
+
- Build the full prompt with `buildFullPrompt` from `orchestration/prompt-builder`
|
|
88
|
+
- Dispatch via unified CLI routing with `dispatch` from `orchestration/cli-dispatch`
|
|
89
|
+
- Capture provider output for memory with `captureFromProvider` from `capture`, display the CLI output, and stop — do NOT execute the agent prompt below
|
|
90
90
|
|
|
91
91
|
3. If `models[0]` IS `claude` (or no routing config exists):
|
|
92
92
|
- Execute the agent prompt below as normal (current behavior)
|
|
93
93
|
|
|
94
94
|
4. If `strategy` is `parallel`:
|
|
95
|
-
-
|
|
95
|
+
- Resolve modules with fallback: try `tlc-claude-code/server/lib/...` first, then `$PROJECT_DIR/server/lib/...`
|
|
96
|
+
- Execute inline (Claude) AND dispatch each external provider via `dispatch` from `orchestration/cli-dispatch`
|
|
97
|
+
- After each provider completes, capture its output with `captureFromProvider` from `capture`
|
|
96
98
|
- Collect and merge results
|
|
97
99
|
|
|
98
100
|
**Override:** Pass `--model <name>` to route this specific run to a different model.
|
|
@@ -1,87 +1,59 @@
|
|
|
1
|
-
# /tlc:recall -
|
|
2
|
-
|
|
3
|
-
Search
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
/tlc:recall <query>
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## What This Does
|
|
12
|
-
|
|
13
|
-
1. Searches
|
|
14
|
-
2.
|
|
15
|
-
3.
|
|
16
|
-
4.
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Source: memory/gotchas/2026-02-08-always-use-wal-mode.md
|
|
61
|
-
|
|
62
|
-
3. **Database migration strategy** (81% match) [conversation]
|
|
63
|
-
Date: 2026-02-07
|
|
64
|
-
Discussed migration approach, decided on schema-first
|
|
65
|
-
Source: memory/conversations/2026-02-07-database-migration.md
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Step 4: Fallback
|
|
69
|
-
|
|
70
|
-
If the vector store is unavailable (Ollama not running, no embeddings):
|
|
71
|
-
- Falls back to keyword-based text search
|
|
72
|
-
- Shows a notice that semantic search is unavailable
|
|
73
|
-
|
|
74
|
-
## Examples
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
/tlc:recall what database should we use
|
|
78
|
-
/tlc:recall deployment strategy --scope global
|
|
79
|
-
/tlc:recall --type decision authentication
|
|
80
|
-
/tlc:recall testing approach --limit 10
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Graceful Degradation
|
|
84
|
-
|
|
85
|
-
- **No Ollama**: Falls back to text search with keyword matching
|
|
86
|
-
- **Empty store**: Shows "No memories indexed yet" with guidance to run `/tlc:remember`
|
|
87
|
-
- **No results**: Shows "No matching memories" with search suggestions
|
|
1
|
+
# /tlc:recall - Team Memory Search
|
|
2
|
+
|
|
3
|
+
Search TLC team memory using plain grep. This is intentional: no vector search, no extra services.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
/tlc:recall <query>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What This Does
|
|
12
|
+
|
|
13
|
+
1. Searches `.tlc/memory/team/` with `grep -rl "query" .tlc/memory/team/`.
|
|
14
|
+
2. Looks in both `.tlc/memory/team/decisions/` and `.tlc/memory/team/gotchas/`.
|
|
15
|
+
3. Shows the file path, date from the filename, and a matching excerpt.
|
|
16
|
+
4. Uses grep only because it works everywhere.
|
|
17
|
+
|
|
18
|
+
## Search Rules
|
|
19
|
+
|
|
20
|
+
- Search both `decisions/` and `gotchas/`.
|
|
21
|
+
- Do not use vector search.
|
|
22
|
+
- Do not depend on embeddings, databases, or external services.
|
|
23
|
+
- Prefer simple recursive grep so the command works across projects.
|
|
24
|
+
|
|
25
|
+
## Process
|
|
26
|
+
|
|
27
|
+
### Step 1: Find matching files
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
grep -rl "query" .tlc/memory/team/
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Step 2: Display matches
|
|
34
|
+
|
|
35
|
+
For each matching file, show:
|
|
36
|
+
|
|
37
|
+
- File path
|
|
38
|
+
- Date parsed from the filename prefix
|
|
39
|
+
- A short matching excerpt from the file body
|
|
40
|
+
|
|
41
|
+
## Example Output
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
Memory recall: "utc"
|
|
45
|
+
|
|
46
|
+
File: .tlc/memory/team/decisions/2026-03-28-use-utc-timestamps.md
|
|
47
|
+
Date: 2026-03-28
|
|
48
|
+
Excerpt: Always use UTC timestamps in the database and in exported logs.
|
|
49
|
+
|
|
50
|
+
File: .tlc/memory/team/gotchas/2026-03-21-local-time-breaks-reporting.md
|
|
51
|
+
Date: 2026-03-21
|
|
52
|
+
Excerpt: Local timezone conversion caused reporting drift in scheduled jobs.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Notes
|
|
56
|
+
|
|
57
|
+
- If there are no matches, say so directly.
|
|
58
|
+
- Keep excerpts short and relevant.
|
|
59
|
+
- Search TLC memory under `.tlc/memory/team/`, not Claude-managed memory.
|
|
@@ -1,71 +1,76 @@
|
|
|
1
|
-
# /tlc:remember -
|
|
2
|
-
|
|
3
|
-
Save important
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
/tlc:remember <text>
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or without arguments
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
##
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
1
|
+
# /tlc:remember - Team Decision Capture
|
|
2
|
+
|
|
3
|
+
Save an important decision into TLC's shared team memory.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
/tlc:remember <decision text>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or without arguments:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
/tlc:remember
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What This Does
|
|
18
|
+
|
|
19
|
+
1. Captures the provided decision text, or extracts decisions from the recent conversation context if no argument is given.
|
|
20
|
+
2. Writes a markdown file to `.tlc/memory/team/decisions/{date}-{slug}.md`.
|
|
21
|
+
3. Stores TLC-owned frontmatter for later grep-based recall.
|
|
22
|
+
4. Never writes to `~/.claude/projects/.../memory/` because that is Claude memory, not TLC memory.
|
|
23
|
+
|
|
24
|
+
## Write Format
|
|
25
|
+
|
|
26
|
+
Write the decision as a markdown file with YAML frontmatter:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
---
|
|
30
|
+
provider: claude
|
|
31
|
+
source: manual
|
|
32
|
+
timestamp: 2026-03-28T12:34:56Z
|
|
33
|
+
type: decision
|
|
34
|
+
scope: team
|
|
35
|
+
---
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The filename must be:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
.tlc/memory/team/decisions/{date}-{slug}.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
.tlc/memory/team/decisions/2026-03-28-use-utc-timestamps.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Process
|
|
51
|
+
|
|
52
|
+
### With an argument
|
|
53
|
+
|
|
54
|
+
- Use the argument as the decision content.
|
|
55
|
+
- Generate a short slug from the decision.
|
|
56
|
+
- Write the file under `.tlc/memory/team/decisions/`.
|
|
57
|
+
|
|
58
|
+
### Without an argument
|
|
59
|
+
|
|
60
|
+
- Review the recent conversation context.
|
|
61
|
+
- Extract concrete decisions, conventions, or constraints worth preserving.
|
|
62
|
+
- Summarize them clearly.
|
|
63
|
+
- Write one decision file under `.tlc/memory/team/decisions/`.
|
|
64
|
+
|
|
65
|
+
## Confirmation
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
Remembered: {summary}
|
|
69
|
+
File: .tlc/memory/team/decisions/2026-03-28-use-utc-timestamps.md
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Notes
|
|
73
|
+
|
|
74
|
+
- Prefer concise, durable statements over raw transcript dumps.
|
|
75
|
+
- Record decisions, not general chatter.
|
|
76
|
+
- Use `.tlc/memory/team/gotchas/` for gotchas, not this command.
|
|
@@ -127,7 +127,7 @@ TLC automatically uses ALL providers configured for the `review` capability in `
|
|
|
127
127
|
|
|
128
128
|
**With this config, `/tlc:review` will:**
|
|
129
129
|
1. Run Claude's review (current session)
|
|
130
|
-
2. Invoke Codex CLI for second opinion: `codex
|
|
130
|
+
2. Invoke Codex CLI for second opinion: `codex exec review --base main -m gpt-5.4 --json --ephemeral`
|
|
131
131
|
3. Combine verdicts - both must approve for APPROVED
|
|
132
132
|
|
|
133
133
|
## Usage
|
|
@@ -295,31 +295,86 @@ Coding Standards:
|
|
|
295
295
|
|
|
296
296
|
**Fail if:** Any `any` types in new code, or files >1000 lines.
|
|
297
297
|
|
|
298
|
-
### Step 6: Invoke External Providers (Codex, Gemini)
|
|
298
|
+
### Step 6: Invoke External Providers (Codex, Gemini)
|
|
299
299
|
|
|
300
300
|
**CRITICAL: This step runs automatically when providers are configured.**
|
|
301
301
|
|
|
302
302
|
For each provider in `reviewProviders` (except `claude` which is the current session):
|
|
303
303
|
|
|
304
|
-
**How to invoke:**
|
|
305
|
-
|
|
306
|
-
**Codex** — use
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
304
|
+
**How to invoke:**
|
|
305
|
+
|
|
306
|
+
**Codex** — use `codex exec review` with explicit model selection, JSON output, and `--ephemeral` for CI-style stateless runs. It reads the git diff natively, no need to pipe files.
|
|
307
|
+
|
|
308
|
+
Before invoking Codex, compute diff stats:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
FILES=$(git diff --name-only main...HEAD | wc -l)
|
|
312
|
+
LINES=$(git diff --stat main...HEAD | tail -1 | grep -oE '[0-9]+ insertion|[0-9]+ deletion' | grep -oE '[0-9]+' | paste -sd+ | bc)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Size-aware Codex review strategy:**
|
|
316
|
+
|
|
317
|
+
**Small diff (`<=15` files, `<=1200` lines):**
|
|
318
|
+
|
|
319
|
+
Single pass:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
codex exec review --base main -m gpt-5.4 --json --ephemeral
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Medium diff (`15-25` files, `1200-2500` lines):**
|
|
326
|
+
|
|
327
|
+
Two passes:
|
|
328
|
+
|
|
329
|
+
1. Broad pass:
|
|
330
|
+
```bash
|
|
331
|
+
codex exec review --base main -m gpt-5.4 --json --ephemeral
|
|
332
|
+
```
|
|
333
|
+
2. Focused pass on the highest-risk area via `codex exec` with a targeted prompt:
|
|
334
|
+
```bash
|
|
335
|
+
codex exec -m gpt-5.4 --json --ephemeral "Review the changes against main. Focus only on these files: <highest-risk file list>. Focus only on: correctness bugs, behavioral regressions, broken assumptions across module boundaries, missing validation/auth/error handling, schema/API compatibility. Do not spend time on style or naming. Prefer findings with: severity, why it is a bug, exact file/line, minimal breaking scenario."
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Large diff (`25+` files, `2500+` lines):**
|
|
339
|
+
|
|
340
|
+
Multi-pass:
|
|
341
|
+
|
|
342
|
+
1. Per-commit:
|
|
343
|
+
```bash
|
|
344
|
+
codex exec review --commit <sha> -m gpt-5.4 --json --ephemeral
|
|
345
|
+
```
|
|
346
|
+
Run once for each non-merge commit.
|
|
347
|
+
2. Per-area:
|
|
348
|
+
Chunk by directory, then run `codex exec` with a prompt listing the chunk files:
|
|
349
|
+
```bash
|
|
350
|
+
codex exec -m gpt-5.4 --json --ephemeral "Review the changes against main. Focus only on these files: <chunk file list>. Focus only on: correctness bugs, behavioral regressions, broken assumptions across module boundaries, missing validation/auth/error handling, schema/API compatibility. Do not spend time on style or naming. Prefer findings with: severity, why it is a bug, exact file/line, minimal breaking scenario."
|
|
351
|
+
```
|
|
352
|
+
3. Integration sweep:
|
|
353
|
+
```bash
|
|
354
|
+
codex exec -m gpt-5.4 --json --ephemeral "Review the full diff against main but do not re-check every local edit. Focus only on cross-file regressions: changed call sites vs function contracts, schema changes vs readers/writers, auth/permission drift, partial migrations."
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Confidence escalation:**
|
|
358
|
+
|
|
359
|
+
- Finding repeated across passes -> high confidence
|
|
360
|
+
- Finding from only one broad pass -> medium confidence
|
|
361
|
+
- Zero findings on huge diff -> LOW CONFIDENCE (not "clean"); flag for human review
|
|
362
|
+
|
|
363
|
+
**Prompt templates:**
|
|
364
|
+
|
|
365
|
+
Per-commit/per-area prompt:
|
|
366
|
+
|
|
367
|
+
```text
|
|
368
|
+
Review the changes against main. Focus only on: correctness bugs, behavioral regressions, broken assumptions across module boundaries, missing validation/auth/error handling, schema/API compatibility. Do not spend time on style or naming. Prefer findings with: severity, why it is a bug, exact file/line, minimal breaking scenario.
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Integration sweep prompt:
|
|
372
|
+
|
|
373
|
+
```text
|
|
374
|
+
Review the full diff against main but do not re-check every local edit. Focus only on cross-file regressions: changed call sites vs function contracts, schema changes vs readers/writers, auth/permission drift, partial migrations.
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Use `codex exec review`, not plain `codex review`, for better automation controls. Always include `-m gpt-5.4`, `--json`, and `--ephemeral` in automated runs.
|
|
323
378
|
|
|
324
379
|
**Gemini** — no built-in review command, so save diff and invoke:
|
|
325
380
|
|
|
@@ -15,35 +15,64 @@ INPUT=$(cat)
|
|
|
15
15
|
# Quick exit if no input
|
|
16
16
|
[ -z "$INPUT" ] && exit 0
|
|
17
17
|
|
|
18
|
-
# Use the capture-bridge Node.js module for reliable processing
|
|
19
18
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
20
|
-
|
|
19
|
+
CAPTURE_MOD=""
|
|
20
|
+
if node -e "require('tlc-claude-code/server/lib/capture/claude-capture')" 2>/dev/null; then
|
|
21
|
+
CAPTURE_MOD="tlc-claude-code/server/lib/capture/claude-capture"
|
|
22
|
+
elif [ -f "$PROJECT_DIR/server/lib/capture/claude-capture.js" ]; then
|
|
23
|
+
CAPTURE_MOD="$PROJECT_DIR/server/lib/capture/claude-capture"
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
if [ -n "$CAPTURE_MOD" ]; then
|
|
27
|
+
# Resolve spool processor for same-session drain
|
|
28
|
+
SPOOL_MOD=""
|
|
29
|
+
if node -e "require('tlc-claude-code/server/lib/capture/spool-processor')" 2>/dev/null; then
|
|
30
|
+
SPOOL_MOD="tlc-claude-code/server/lib/capture/spool-processor"
|
|
31
|
+
elif [ -f "$PROJECT_DIR/server/lib/capture/spool-processor.js" ]; then
|
|
32
|
+
SPOOL_MOD="$PROJECT_DIR/server/lib/capture/spool-processor"
|
|
33
|
+
fi
|
|
21
34
|
|
|
22
|
-
if [ -f "$BRIDGE_SCRIPT" ]; then
|
|
23
35
|
echo "$INPUT" | node -e "
|
|
24
|
-
const
|
|
36
|
+
const { captureClaudeExchange } = require('$CAPTURE_MOD');
|
|
25
37
|
let input = '';
|
|
26
38
|
process.stdin.on('data', d => input += d);
|
|
27
39
|
process.stdin.on('end', async () => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await bridge.captureExchange({
|
|
36
|
-
cwd: parsed.cwd || '$PROJECT_DIR',
|
|
37
|
-
assistantMessage: parsed.assistantMessage,
|
|
38
|
-
userMessage,
|
|
39
|
-
sessionId: parsed.sessionId,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const path = require('path');
|
|
43
|
-
const spoolDir = path.join(parsed.cwd || '$PROJECT_DIR', '.tlc', 'memory');
|
|
44
|
-
await bridge.drainSpool(spoolDir);
|
|
40
|
+
captureClaudeExchange({ hookInput: input, projectDir: '$PROJECT_DIR' });
|
|
41
|
+
// Drain spool so memories are available same-session
|
|
42
|
+
try {
|
|
43
|
+
const { processSpool } = require('$SPOOL_MOD');
|
|
44
|
+
await processSpool('$PROJECT_DIR');
|
|
45
|
+
} catch {}
|
|
45
46
|
});
|
|
46
47
|
" 2>/dev/null
|
|
48
|
+
else
|
|
49
|
+
BRIDGE_SCRIPT="$PROJECT_DIR/server/lib/capture-bridge.js"
|
|
50
|
+
if [ -f "$BRIDGE_SCRIPT" ]; then
|
|
51
|
+
echo "$INPUT" | node -e "
|
|
52
|
+
const bridge = require('$BRIDGE_SCRIPT');
|
|
53
|
+
let input = '';
|
|
54
|
+
process.stdin.on('data', d => input += d);
|
|
55
|
+
process.stdin.on('end', async () => {
|
|
56
|
+
const parsed = bridge.parseStopHookInput(input);
|
|
57
|
+
if (!parsed || !parsed.assistantMessage) process.exit(0);
|
|
58
|
+
|
|
59
|
+
const userMessage = parsed.transcriptPath
|
|
60
|
+
? bridge.extractLastUserMessage(parsed.transcriptPath)
|
|
61
|
+
: null;
|
|
62
|
+
|
|
63
|
+
await bridge.captureExchange({
|
|
64
|
+
cwd: parsed.cwd || '$PROJECT_DIR',
|
|
65
|
+
assistantMessage: parsed.assistantMessage,
|
|
66
|
+
userMessage,
|
|
67
|
+
sessionId: parsed.sessionId,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const path = require('path');
|
|
71
|
+
const spoolDir = path.join(parsed.cwd || '$PROJECT_DIR', '.tlc', 'memory');
|
|
72
|
+
await bridge.drainSpool(spoolDir);
|
|
73
|
+
});
|
|
74
|
+
" 2>/dev/null
|
|
75
|
+
fi
|
|
47
76
|
fi
|
|
48
77
|
|
|
49
78
|
# Always exit 0 - never block Claude
|
|
@@ -43,6 +43,23 @@ else
|
|
|
43
43
|
done
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
+
# ─── Memory System Init ─────────────────────────────
|
|
47
|
+
mkdir -p "$PROJECT_DIR/.tlc/memory/team/decisions" \
|
|
48
|
+
"$PROJECT_DIR/.tlc/memory/team/gotchas" \
|
|
49
|
+
"$PROJECT_DIR/.tlc/memory/.local/sessions"
|
|
50
|
+
|
|
51
|
+
# ─── Spool Drain ─────────────────────────────────────
|
|
52
|
+
# Try to drain any pending spool entries from previous sessions
|
|
53
|
+
SPOOL_DRAIN=""
|
|
54
|
+
if node -e "require('tlc-claude-code/server/lib/capture/spool-processor')" 2>/dev/null; then
|
|
55
|
+
SPOOL_DRAIN="require('tlc-claude-code/server/lib/capture/spool-processor').processSpool('$PROJECT_DIR')"
|
|
56
|
+
elif [ -f "$PROJECT_DIR/server/lib/capture/spool-processor.js" ]; then
|
|
57
|
+
SPOOL_DRAIN="require('$PROJECT_DIR/server/lib/capture/spool-processor').processSpool('$PROJECT_DIR')"
|
|
58
|
+
fi
|
|
59
|
+
if [ -n "$SPOOL_DRAIN" ]; then
|
|
60
|
+
node -e "$SPOOL_DRAIN" 2>/dev/null
|
|
61
|
+
fi
|
|
62
|
+
|
|
46
63
|
# ─── LLM Router: Probe Providers ─────────────────────────
|
|
47
64
|
#
|
|
48
65
|
# Writes .tlc/.router-state.json with provider availability.
|
|
@@ -132,3 +149,16 @@ else
|
|
|
132
149
|
echo "LLM Router: ${COUNT} providers available (cached). State at .tlc/.router-state.json."
|
|
133
150
|
fi
|
|
134
151
|
fi
|
|
152
|
+
|
|
153
|
+
# ─── Health Check (runs AFTER router probe so provider state is fresh) ───
|
|
154
|
+
HEALTH_MOD=""
|
|
155
|
+
if node -e "require('tlc-claude-code/server/lib/health-check')" 2>/dev/null; then
|
|
156
|
+
HEALTH_MOD="tlc-claude-code/server/lib/health-check"
|
|
157
|
+
elif [ -f "$PROJECT_DIR/server/lib/health-check.js" ]; then
|
|
158
|
+
HEALTH_MOD="$PROJECT_DIR/server/lib/health-check"
|
|
159
|
+
fi
|
|
160
|
+
if [ -n "$HEALTH_MOD" ]; then
|
|
161
|
+
node -e "require('$HEALTH_MOD').runHealthChecks('$PROJECT_DIR').then(r => r.warnings.forEach(w => console.error(w)))" 2>/dev/null
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
exit 0
|
package/bin/init.js
CHANGED
|
@@ -9,6 +9,7 @@ const fs = require('fs');
|
|
|
9
9
|
const path = require('path');
|
|
10
10
|
|
|
11
11
|
const projectDir = process.cwd();
|
|
12
|
+
const TLC_GITIGNORE_BLOCK = '.tlc/*\n!.tlc/memory/\n.tlc/memory/.local/\n';
|
|
12
13
|
|
|
13
14
|
// Windows batch file content
|
|
14
15
|
const batContent = `@echo off
|
|
@@ -217,8 +218,16 @@ if (fs.existsSync(gitignorePath)) {
|
|
|
217
218
|
gitignore += '\n# TLC dev server (local only)\ntlc-start.*\n';
|
|
218
219
|
updated = true;
|
|
219
220
|
}
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
// Remove legacy ".tlc/" ignore that blocks team memory in upgraded repos
|
|
222
|
+
if (gitignore.includes('.tlc/') && !gitignore.includes('.tlc/*')) {
|
|
223
|
+
gitignore = gitignore.replace(/^\.tlc\/\s*$/gm, '');
|
|
224
|
+
updated = true;
|
|
225
|
+
}
|
|
226
|
+
if (!gitignore.includes('.tlc/*') || !gitignore.includes('!.tlc/memory/') || !gitignore.includes('.tlc/memory/.local/')) {
|
|
227
|
+
if (!gitignore.endsWith('\n')) {
|
|
228
|
+
gitignore += '\n';
|
|
229
|
+
}
|
|
230
|
+
gitignore += TLC_GITIGNORE_BLOCK;
|
|
222
231
|
updated = true;
|
|
223
232
|
}
|
|
224
233
|
if (updated) {
|
|
@@ -226,7 +235,7 @@ if (fs.existsSync(gitignorePath)) {
|
|
|
226
235
|
console.log('[TLC] Updated .gitignore');
|
|
227
236
|
}
|
|
228
237
|
} else {
|
|
229
|
-
fs.writeFileSync(gitignorePath, '# TLC dev server (local only)\ntlc-start.*\n
|
|
238
|
+
fs.writeFileSync(gitignorePath, '# TLC dev server (local only)\ntlc-start.*\n' + TLC_GITIGNORE_BLOCK);
|
|
230
239
|
console.log('[TLC] Created .gitignore');
|
|
231
240
|
}
|
|
232
241
|
|