kiro-memory 1.8.0 → 1.9.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.
- package/README.md +3 -3
- package/package.json +8 -6
- package/plugin/dist/cli/contextkit.js +123 -31
- package/plugin/dist/services/sqlite/Sessions.js +5 -0
- package/plugin/dist/services/sqlite/index.js +5 -0
- package/plugin/dist/viewer.html +95 -16
- package/plugin/dist/viewer.js +79 -33
- package/plugin/dist/worker-service.js +5 -5
- package/scripts/postinstall.cjs +42 -0
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ kiro-memory install --cline # Cline (instructions + MCP)
|
|
|
83
83
|
Or from source:
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
|
-
git clone https://github.com/
|
|
86
|
+
git clone https://github.com/Auriti-Labs/kiro-memory.git
|
|
87
87
|
cd kiro-memory
|
|
88
88
|
npm install && npm run build
|
|
89
89
|
npm run install:kiro
|
|
@@ -441,7 +441,7 @@ Kiro Memory runs **locally only** on `127.0.0.1` and implements multiple layers
|
|
|
441
441
|
- **Input Validation** on all POST endpoints (type checking, length limits, safe character patterns)
|
|
442
442
|
- **SSE Connection Limit** (max 50 concurrent clients)
|
|
443
443
|
|
|
444
|
-
To report a security vulnerability, please open a [private security advisory](https://github.com/
|
|
444
|
+
To report a security vulnerability, please open a [private security advisory](https://github.com/Auriti-Labs/kiro-memory/security/advisories/new).
|
|
445
445
|
|
|
446
446
|
## Contributing
|
|
447
447
|
|
|
@@ -453,7 +453,7 @@ Contributions are welcome. Please open an issue to discuss proposed changes befo
|
|
|
453
453
|
|
|
454
454
|
---
|
|
455
455
|
|
|
456
|
-
Built by [
|
|
456
|
+
Built by [Auriti Labs](https://github.com/Auriti-Labs)
|
|
457
457
|
|
|
458
458
|
---
|
|
459
459
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kiro-memory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Persistent cross-session memory for AI coding assistants. Works with Claude Code, Cursor, Windsurf, Cline, and any MCP-compatible editor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kiro",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"typescript",
|
|
19
19
|
"ai-tools"
|
|
20
20
|
],
|
|
21
|
-
"author": "
|
|
21
|
+
"author": "Auriti Labs",
|
|
22
22
|
"license": "AGPL-3.0",
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://github.com/
|
|
25
|
+
"url": "https://github.com/Auriti-Labs/kiro-memory.git"
|
|
26
26
|
},
|
|
27
|
-
"homepage": "https://github.com/
|
|
27
|
+
"homepage": "https://github.com/Auriti-Labs/kiro-memory#readme",
|
|
28
28
|
"bugs": {
|
|
29
|
-
"url": "https://github.com/
|
|
29
|
+
"url": "https://github.com/Auriti-Labs/kiro-memory/issues"
|
|
30
30
|
},
|
|
31
31
|
"type": "module",
|
|
32
32
|
"exports": {
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
43
|
"dist",
|
|
44
|
-
"plugin"
|
|
44
|
+
"plugin",
|
|
45
|
+
"scripts/postinstall.cjs"
|
|
45
46
|
],
|
|
46
47
|
"bin": {
|
|
47
48
|
"kiro-memory": "./plugin/dist/cli/contextkit.js"
|
|
@@ -75,6 +76,7 @@
|
|
|
75
76
|
"test:infra": "bun test tests/infrastructure/",
|
|
76
77
|
"test:server": "bun test tests/server/",
|
|
77
78
|
"install:kiro": "bash scripts/install-kiro.sh",
|
|
79
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
78
80
|
"prepublishOnly": "npm run build",
|
|
79
81
|
"release": "np",
|
|
80
82
|
"release:patch": "np patch --no-cleanup",
|
|
@@ -2483,6 +2483,71 @@ function formatReportJson(data) {
|
|
|
2483
2483
|
return JSON.stringify(data, null, 2);
|
|
2484
2484
|
}
|
|
2485
2485
|
|
|
2486
|
+
// src/cli/banner.ts
|
|
2487
|
+
var G = [
|
|
2488
|
+
"\x1B[38;5;135m",
|
|
2489
|
+
// viola
|
|
2490
|
+
"\x1B[38;5;99m",
|
|
2491
|
+
// viola-blu
|
|
2492
|
+
"\x1B[38;5;63m",
|
|
2493
|
+
// indaco
|
|
2494
|
+
"\x1B[38;5;33m",
|
|
2495
|
+
// blu
|
|
2496
|
+
"\x1B[38;5;39m",
|
|
2497
|
+
// blu chiaro
|
|
2498
|
+
"\x1B[38;5;44m"
|
|
2499
|
+
// ciano
|
|
2500
|
+
];
|
|
2501
|
+
var R = "\x1B[0m";
|
|
2502
|
+
var B = "\x1B[1m";
|
|
2503
|
+
var D = "\x1B[2m";
|
|
2504
|
+
var U = "\x1B[4m";
|
|
2505
|
+
var GRN = "\x1B[32m";
|
|
2506
|
+
var CYN = "\x1B[36m";
|
|
2507
|
+
var LOGO = [
|
|
2508
|
+
" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
2509
|
+
" \u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557",
|
|
2510
|
+
" \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551",
|
|
2511
|
+
" \u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551",
|
|
2512
|
+
" \u2588\u2588\u2551 \u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D",
|
|
2513
|
+
" \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D"
|
|
2514
|
+
];
|
|
2515
|
+
var MEMORY_TAG = " M E M O R Y";
|
|
2516
|
+
var LINE = "\u2500".repeat(48);
|
|
2517
|
+
function supportsColor() {
|
|
2518
|
+
if (process.env.NO_COLOR || process.env.TERM === "dumb") return false;
|
|
2519
|
+
return process.stdout.isTTY ?? false;
|
|
2520
|
+
}
|
|
2521
|
+
function printBanner(opts) {
|
|
2522
|
+
const color = supportsColor();
|
|
2523
|
+
const c = (code, text) => color ? `${code}${text}${R}` : text;
|
|
2524
|
+
console.log("");
|
|
2525
|
+
for (let i = 0; i < LOGO.length; i++) {
|
|
2526
|
+
console.log(` ${c(G[i], LOGO[i])}`);
|
|
2527
|
+
}
|
|
2528
|
+
console.log(` ${c(`${G[G.length - 1]}${B}`, MEMORY_TAG)}`);
|
|
2529
|
+
console.log("");
|
|
2530
|
+
console.log(` ${c(D, LINE)}`);
|
|
2531
|
+
console.log("");
|
|
2532
|
+
console.log(` ${c(`${GRN}${B}`, "\u2713 Installation complete!")} v${opts.version}`);
|
|
2533
|
+
console.log(` ${c(D, `Editor: ${opts.editor}`)}`);
|
|
2534
|
+
console.log("");
|
|
2535
|
+
console.log(` ${c(`${CYN}${B}`, "Installed:")}`);
|
|
2536
|
+
for (const p of opts.configPaths) {
|
|
2537
|
+
console.log(` ${c(D, "\u2192")} ${p}`);
|
|
2538
|
+
}
|
|
2539
|
+
console.log(` ${c(D, "\u2192")} Data: ${opts.dataDir}`);
|
|
2540
|
+
console.log("");
|
|
2541
|
+
console.log(` ${c(`${CYN}${B}`, "Dashboard:")} ${c(U, opts.dashboardUrl)}`);
|
|
2542
|
+
console.log(` ${c(D, "Docs: https://auritidesign.it/docs/kiro-memory/")}`);
|
|
2543
|
+
console.log("");
|
|
2544
|
+
console.log(` ${c(D, LINE)}`);
|
|
2545
|
+
console.log(` ${c(G[2], "Your AI assistant now has persistent memory.")}`);
|
|
2546
|
+
console.log(` ${c(G[3], "Every session builds on the last.")}`);
|
|
2547
|
+
console.log(` ${c(D, LINE)}`);
|
|
2548
|
+
console.log("");
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2486
2551
|
// src/cli/contextkit.ts
|
|
2487
2552
|
import { execSync } from "child_process";
|
|
2488
2553
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync, appendFileSync as appendFileSync2 } from "fs";
|
|
@@ -2495,6 +2560,12 @@ var command = args[0];
|
|
|
2495
2560
|
var __filename = fileURLToPath2(import.meta.url);
|
|
2496
2561
|
var __dirname2 = dirname2(__filename);
|
|
2497
2562
|
var DIST_DIR = dirname2(__dirname2);
|
|
2563
|
+
var PKG_VERSION = "unknown";
|
|
2564
|
+
try {
|
|
2565
|
+
const pkgPath = join3(DIST_DIR, "..", "..", "package.json");
|
|
2566
|
+
PKG_VERSION = JSON.parse(readFileSync2(pkgPath, "utf8")).version;
|
|
2567
|
+
} catch {
|
|
2568
|
+
}
|
|
2498
2569
|
var AGENT_TEMPLATE = JSON.stringify({
|
|
2499
2570
|
name: "kiro-memory",
|
|
2500
2571
|
description: "Agent with persistent cross-session memory. Uses Kiro Memory to remember context from previous sessions and automatically save what it learns.",
|
|
@@ -2917,17 +2988,23 @@ ${aliasLine}
|
|
|
2917
2988
|
}
|
|
2918
2989
|
}
|
|
2919
2990
|
console.log("\n[4/4] Done!\n");
|
|
2920
|
-
|
|
2991
|
+
printBanner({
|
|
2992
|
+
editor: "Kiro CLI",
|
|
2993
|
+
version: PKG_VERSION,
|
|
2994
|
+
dashboardUrl: "http://localhost:3001",
|
|
2995
|
+
dataDir,
|
|
2996
|
+
configPaths: [
|
|
2997
|
+
`Agent: ${agentDestPath}`,
|
|
2998
|
+
`MCP: ${mcpFilePath}`,
|
|
2999
|
+
`Steering: ${steeringDestPath}`
|
|
3000
|
+
]
|
|
3001
|
+
});
|
|
2921
3002
|
console.log(" Start Kiro with memory:");
|
|
2922
3003
|
if (aliasAlreadySet) {
|
|
2923
|
-
console.log(" \x1B[1mkiro\x1B[0m");
|
|
3004
|
+
console.log(" \x1B[1mkiro\x1B[0m\n");
|
|
2924
3005
|
} else {
|
|
2925
|
-
console.log(" \x1B[1mkiro-cli --agent kiro-memory\x1B[0m");
|
|
3006
|
+
console.log(" \x1B[1mkiro-cli --agent kiro-memory\x1B[0m\n");
|
|
2926
3007
|
}
|
|
2927
|
-
console.log("");
|
|
2928
|
-
console.log(" The worker starts automatically when a Kiro session begins.");
|
|
2929
|
-
console.log(` Web dashboard: \x1B[4mhttp://localhost:3001\x1B[0m
|
|
2930
|
-
`);
|
|
2931
3008
|
}
|
|
2932
3009
|
var CLAUDE_CODE_STEERING = `# Kiro Memory - Persistent Cross-Session Memory
|
|
2933
3010
|
|
|
@@ -3052,12 +3129,17 @@ async function installClaudeCode() {
|
|
|
3052
3129
|
}
|
|
3053
3130
|
console.log(` \u2192 Data dir: ${dataDir}`);
|
|
3054
3131
|
console.log("\n[3/3] Done!\n");
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3132
|
+
printBanner({
|
|
3133
|
+
editor: "Claude Code",
|
|
3134
|
+
version: PKG_VERSION,
|
|
3135
|
+
dashboardUrl: "http://localhost:3001",
|
|
3136
|
+
dataDir,
|
|
3137
|
+
configPaths: [
|
|
3138
|
+
`Hooks: ${settingsPath}`,
|
|
3139
|
+
`MCP: ${mcpPath}`,
|
|
3140
|
+
`Steering: ${steeringPath}`
|
|
3141
|
+
]
|
|
3142
|
+
});
|
|
3061
3143
|
}
|
|
3062
3144
|
async function installCursor() {
|
|
3063
3145
|
console.log("\n=== Kiro Memory - Cursor Installation ===\n");
|
|
@@ -3139,12 +3221,16 @@ async function installCursor() {
|
|
|
3139
3221
|
console.log(` \u2192 MCP config: ${mcpPath}`);
|
|
3140
3222
|
console.log(` \u2192 Data dir: ${dataDir}`);
|
|
3141
3223
|
console.log("\n[3/3] Done!\n");
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3224
|
+
printBanner({
|
|
3225
|
+
editor: "Cursor",
|
|
3226
|
+
version: PKG_VERSION,
|
|
3227
|
+
dashboardUrl: "http://localhost:3001",
|
|
3228
|
+
dataDir,
|
|
3229
|
+
configPaths: [
|
|
3230
|
+
`Hooks: ${hooksPath}`,
|
|
3231
|
+
`MCP: ${mcpPath}`
|
|
3232
|
+
]
|
|
3233
|
+
});
|
|
3148
3234
|
}
|
|
3149
3235
|
async function installWindsurf() {
|
|
3150
3236
|
console.log("\n=== Kiro Memory - Windsurf Installation ===\n");
|
|
@@ -3193,12 +3279,15 @@ async function installWindsurf() {
|
|
|
3193
3279
|
console.log(` \u2192 MCP config: ${mcpPath}`);
|
|
3194
3280
|
console.log(` \u2192 Data dir: ${dataDir}`);
|
|
3195
3281
|
console.log("\n[3/3] Done!\n");
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3282
|
+
printBanner({
|
|
3283
|
+
editor: "Windsurf",
|
|
3284
|
+
version: PKG_VERSION,
|
|
3285
|
+
dashboardUrl: "http://localhost:3001",
|
|
3286
|
+
dataDir,
|
|
3287
|
+
configPaths: [
|
|
3288
|
+
`MCP: ${mcpPath}`
|
|
3289
|
+
]
|
|
3290
|
+
});
|
|
3202
3291
|
console.log(" \x1B[2mTip: Add a .windsurfrules file to your project with instructions");
|
|
3203
3292
|
console.log(" to use the kiro-memory MCP tools for persistent context.\x1B[0m\n");
|
|
3204
3293
|
}
|
|
@@ -3255,12 +3344,15 @@ async function installCline() {
|
|
|
3255
3344
|
console.log(` \u2192 MCP config: ${mcpPath}`);
|
|
3256
3345
|
console.log(` \u2192 Data dir: ${dataDir}`);
|
|
3257
3346
|
console.log("\n[3/3] Done!\n");
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3347
|
+
printBanner({
|
|
3348
|
+
editor: "Cline",
|
|
3349
|
+
version: PKG_VERSION,
|
|
3350
|
+
dashboardUrl: "http://localhost:3001",
|
|
3351
|
+
dataDir,
|
|
3352
|
+
configPaths: [
|
|
3353
|
+
`MCP: ${mcpPath}`
|
|
3354
|
+
]
|
|
3355
|
+
});
|
|
3264
3356
|
console.log(" \x1B[2mTip: Add a .clinerules file to your project with instructions");
|
|
3265
3357
|
console.log(" to use the kiro-memory MCP tools for persistent context.\x1B[0m\n");
|
|
3266
3358
|
}
|
|
@@ -46,6 +46,10 @@ function getActiveSessions(db) {
|
|
|
46
46
|
const query = db.query("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at_epoch DESC");
|
|
47
47
|
return query.all();
|
|
48
48
|
}
|
|
49
|
+
function getAllSessions(db, limit = 100) {
|
|
50
|
+
const query = db.query("SELECT * FROM sessions ORDER BY started_at_epoch DESC LIMIT ?");
|
|
51
|
+
return query.all(limit);
|
|
52
|
+
}
|
|
49
53
|
function getSessionsByProject(db, project, limit = 100) {
|
|
50
54
|
const query = db.query("SELECT * FROM sessions WHERE project = ? ORDER BY started_at_epoch DESC LIMIT ?");
|
|
51
55
|
return query.all(project, limit);
|
|
@@ -55,6 +59,7 @@ export {
|
|
|
55
59
|
createSession,
|
|
56
60
|
failSession,
|
|
57
61
|
getActiveSessions,
|
|
62
|
+
getAllSessions,
|
|
58
63
|
getSessionByContentId,
|
|
59
64
|
getSessionById,
|
|
60
65
|
getSessionsByProject,
|
|
@@ -769,6 +769,10 @@ function getActiveSessions(db) {
|
|
|
769
769
|
const query = db.query("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at_epoch DESC");
|
|
770
770
|
return query.all();
|
|
771
771
|
}
|
|
772
|
+
function getAllSessions(db, limit = 100) {
|
|
773
|
+
const query = db.query("SELECT * FROM sessions ORDER BY started_at_epoch DESC LIMIT ?");
|
|
774
|
+
return query.all(limit);
|
|
775
|
+
}
|
|
772
776
|
function getSessionsByProject(db, project, limit = 100) {
|
|
773
777
|
const query = db.query("SELECT * FROM sessions WHERE project = ? ORDER BY started_at_epoch DESC LIMIT ?");
|
|
774
778
|
return query.all(project, limit);
|
|
@@ -1373,6 +1377,7 @@ export {
|
|
|
1373
1377
|
deleteSummary,
|
|
1374
1378
|
failSession,
|
|
1375
1379
|
getActiveSessions,
|
|
1380
|
+
getAllSessions,
|
|
1376
1381
|
getCheckpointsBySession,
|
|
1377
1382
|
getDatabase,
|
|
1378
1383
|
getLatestCheckpoint,
|
package/plugin/dist/viewer.html
CHANGED
|
@@ -25,17 +25,31 @@
|
|
|
25
25
|
mono: ['"JetBrains Mono"', 'ui-monospace', 'monospace'],
|
|
26
26
|
},
|
|
27
27
|
colors: {
|
|
28
|
+
/* Superfici e bordi — cambiano via CSS vars */
|
|
28
29
|
surface: {
|
|
29
|
-
0: '
|
|
30
|
-
1: '
|
|
31
|
-
2: '
|
|
32
|
-
3: '
|
|
33
|
-
4: '
|
|
30
|
+
0: 'var(--surface-0)',
|
|
31
|
+
1: 'var(--surface-1)',
|
|
32
|
+
2: 'var(--surface-2)',
|
|
33
|
+
3: 'var(--surface-3)',
|
|
34
|
+
4: 'var(--surface-4)',
|
|
34
35
|
},
|
|
35
36
|
border: {
|
|
36
|
-
DEFAULT: '
|
|
37
|
-
subtle: '
|
|
38
|
-
hover: '
|
|
37
|
+
DEFAULT: 'var(--border)',
|
|
38
|
+
subtle: 'var(--border-subtle)',
|
|
39
|
+
hover: 'var(--border-hover)',
|
|
40
|
+
},
|
|
41
|
+
/* Scala zinc sovrascritta con CSS vars per inversione light/dark */
|
|
42
|
+
zinc: {
|
|
43
|
+
50: 'var(--zinc-50)',
|
|
44
|
+
100: 'var(--zinc-100)',
|
|
45
|
+
200: 'var(--zinc-200)',
|
|
46
|
+
300: 'var(--zinc-300)',
|
|
47
|
+
400: 'var(--zinc-400)',
|
|
48
|
+
500: 'var(--zinc-500)',
|
|
49
|
+
600: 'var(--zinc-600)',
|
|
50
|
+
700: 'var(--zinc-700)',
|
|
51
|
+
800: 'var(--zinc-800)',
|
|
52
|
+
900: 'var(--zinc-900)',
|
|
39
53
|
},
|
|
40
54
|
accent: {
|
|
41
55
|
violet: '#7C5AFF',
|
|
@@ -48,11 +62,11 @@
|
|
|
48
62
|
},
|
|
49
63
|
},
|
|
50
64
|
boxShadow: {
|
|
51
|
-
'card': '
|
|
52
|
-
'card-hover': '
|
|
65
|
+
'card': 'var(--shadow-card)',
|
|
66
|
+
'card-hover': 'var(--shadow-card-hover)',
|
|
53
67
|
'glow-violet': '0 0 20px rgba(124,90,255,0.15)',
|
|
54
68
|
'glow-blue': '0 0 20px rgba(59,130,246,0.15)',
|
|
55
|
-
'panel': '
|
|
69
|
+
'panel': 'var(--shadow-panel)',
|
|
56
70
|
},
|
|
57
71
|
keyframes: {
|
|
58
72
|
'slide-up': {
|
|
@@ -94,11 +108,76 @@
|
|
|
94
108
|
</script>
|
|
95
109
|
|
|
96
110
|
<style>
|
|
97
|
-
/*
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
/* ── Tema Light (default) ── */
|
|
112
|
+
:root {
|
|
113
|
+
--surface-0: #F5F6FA;
|
|
114
|
+
--surface-1: #FFFFFF;
|
|
115
|
+
--surface-2: #ECEDF3;
|
|
116
|
+
--surface-3: #E0E2EB;
|
|
117
|
+
--surface-4: #D3D6E0;
|
|
118
|
+
--border: #D3D6E0;
|
|
119
|
+
--border-subtle: #E6E8EF;
|
|
120
|
+
--border-hover: #B5B9C8;
|
|
121
|
+
/* Zinc invertita: 100=scuro, 700=chiaro */
|
|
122
|
+
--zinc-50: #f8f9fa;
|
|
123
|
+
--zinc-100: #131520;
|
|
124
|
+
--zinc-200: #1f2233;
|
|
125
|
+
--zinc-300: #343750;
|
|
126
|
+
--zinc-400: #4b5068;
|
|
127
|
+
--zinc-500: #6b7085;
|
|
128
|
+
--zinc-600: #9499aa;
|
|
129
|
+
--zinc-700: #bfc3ce;
|
|
130
|
+
--zinc-800: #e4e6ec;
|
|
131
|
+
--zinc-900: #f3f4f6;
|
|
132
|
+
/* Ombre leggere */
|
|
133
|
+
--shadow-card: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
|
|
134
|
+
--shadow-card-hover: 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04);
|
|
135
|
+
--shadow-panel: 0 0 0 1px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.06);
|
|
136
|
+
/* Scrollbar — toni accent per coerenza brand */
|
|
137
|
+
--scrollbar-thumb: #B5B9C8;
|
|
138
|
+
--scrollbar-hover: #8B7FD4;
|
|
139
|
+
--scrollbar-track: #ECEDF3;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ── Tema Dark ── */
|
|
143
|
+
.dark {
|
|
144
|
+
--surface-0: #0E1015;
|
|
145
|
+
--surface-1: #161820;
|
|
146
|
+
--surface-2: #1E202A;
|
|
147
|
+
--surface-3: #272935;
|
|
148
|
+
--surface-4: #313342;
|
|
149
|
+
--border: #313342;
|
|
150
|
+
--border-subtle: #222430;
|
|
151
|
+
--border-hover: #434558;
|
|
152
|
+
/* Zinc standard dark (contrasti migliorati) */
|
|
153
|
+
--zinc-50: #18181b;
|
|
154
|
+
--zinc-100: #f0f1f4;
|
|
155
|
+
--zinc-200: #e0e2e8;
|
|
156
|
+
--zinc-300: #c8ccd6;
|
|
157
|
+
--zinc-400: #9ea3b2;
|
|
158
|
+
--zinc-500: #757a8c;
|
|
159
|
+
--zinc-600: #555968;
|
|
160
|
+
--zinc-700: #3d4050;
|
|
161
|
+
--zinc-800: #272935;
|
|
162
|
+
--zinc-900: #1a1c24;
|
|
163
|
+
/* Ombre profonde */
|
|
164
|
+
--shadow-card: 0 1px 3px rgba(0,0,0,0.4), 0 1px 2px rgba(0,0,0,0.3);
|
|
165
|
+
--shadow-card-hover: 0 4px 12px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.3);
|
|
166
|
+
--shadow-panel: 0 0 0 1px rgba(255,255,255,0.03), 0 2px 8px rgba(0,0,0,0.4);
|
|
167
|
+
/* Scrollbar — toni accent per coerenza brand */
|
|
168
|
+
--scrollbar-thumb: #434558;
|
|
169
|
+
--scrollbar-hover: #7C5AFF;
|
|
170
|
+
--scrollbar-track: #1E202A;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Scrollbar — accent brand con hover viola */
|
|
174
|
+
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
175
|
+
::-webkit-scrollbar-track { background: var(--scrollbar-track); border-radius: 4px; margin: 2px; }
|
|
176
|
+
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 4px; border: 2px solid var(--scrollbar-track); transition: background 0.2s; }
|
|
177
|
+
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-hover); }
|
|
178
|
+
::-webkit-scrollbar-corner { background: transparent; }
|
|
179
|
+
/* Firefox */
|
|
180
|
+
* { scrollbar-width: auto; scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); }
|
|
102
181
|
|
|
103
182
|
/* Stagger */
|
|
104
183
|
.stagger-1 { animation-delay: 30ms; }
|
package/plugin/dist/viewer.js
CHANGED
|
@@ -23652,7 +23652,7 @@ var SOURCE_BADGE = {
|
|
|
23652
23652
|
keyword: { bg: "bg-amber-500/15", text: "text-amber-400", label: "keyword" },
|
|
23653
23653
|
hybrid: { bg: "bg-cyan-500/15", text: "text-cyan-400", label: "hybrid" }
|
|
23654
23654
|
};
|
|
23655
|
-
function SearchBar() {
|
|
23655
|
+
function SearchBar({ onNavigate }) {
|
|
23656
23656
|
const [query, setQuery] = (0, import_react.useState)("");
|
|
23657
23657
|
const [results, setResults] = (0, import_react.useState)([]);
|
|
23658
23658
|
const [isOpen, setIsOpen] = (0, import_react.useState)(false);
|
|
@@ -23696,13 +23696,11 @@ function SearchBar() {
|
|
|
23696
23696
|
if (total === 0) return;
|
|
23697
23697
|
const item = results[selectedIndex];
|
|
23698
23698
|
if (!item) return;
|
|
23699
|
-
const targetId = `obs-${item.id}`;
|
|
23700
23699
|
close();
|
|
23701
|
-
|
|
23702
|
-
|
|
23703
|
-
|
|
23704
|
-
|
|
23705
|
-
}, [results, selectedIndex, total, close]);
|
|
23700
|
+
if (onNavigate) {
|
|
23701
|
+
onNavigate(item.project, parseInt(String(item.id), 10));
|
|
23702
|
+
}
|
|
23703
|
+
}, [results, selectedIndex, total, close, onNavigate]);
|
|
23706
23704
|
(0, import_react.useEffect)(() => {
|
|
23707
23705
|
const handler = (e) => {
|
|
23708
23706
|
if ((e.metaKey || e.ctrlKey) && e.key === "k") {
|
|
@@ -23773,7 +23771,7 @@ function SearchBar() {
|
|
|
23773
23771
|
}
|
|
23774
23772
|
},
|
|
23775
23773
|
/* @__PURE__ */ import_react.default.createElement("div", { className: `w-2 h-2 rounded-full mt-1.5 flex-shrink-0 ${badge.dot}` }),
|
|
23776
|
-
/* @__PURE__ */ import_react.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "text-sm text-zinc-200 truncate" }, item.title), item.content && /* @__PURE__ */ import_react.default.createElement("div", { className: "text-xs text-zinc-500 truncate mt-0.5" }, item.content.substring(0, 120)), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 mt-1" }, /* @__PURE__ */ import_react.default.createElement("span", { className: `text-[10px] font-medium px-1.5 py-0.5 rounded ${badge.bg} ${badge.text}` }, item.type), /* @__PURE__ */ import_react.default.createElement("span", { className: `text-[10px] font-medium px-1.5 py-0.5 rounded ${srcBadge.bg} ${srcBadge.text}` }, srcBadge.label), /* @__PURE__ */ import_react.default.createElement("span", { className: "text-[10px] text-zinc-600 font-mono" }, timeAgo(item.created_at_epoch)), item.score > 0 && /* @__PURE__ */ import_react.default.createElement("span", { className: "text-[10px] text-zinc-700 font-mono" }, (item.score * 100).toFixed(0), "%")))
|
|
23774
|
+
/* @__PURE__ */ import_react.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "text-sm text-zinc-200 truncate" }, item.title), item.content && /* @__PURE__ */ import_react.default.createElement("div", { className: "text-xs text-zinc-500 truncate mt-0.5" }, item.content.substring(0, 120)), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 mt-1 flex-wrap" }, /* @__PURE__ */ import_react.default.createElement("span", { className: `text-[10px] font-medium px-1.5 py-0.5 rounded ${badge.bg} ${badge.text}` }, item.type), /* @__PURE__ */ import_react.default.createElement("span", { className: "text-[10px] font-medium px-1.5 py-0.5 rounded bg-accent-violet/10 text-accent-violet" }, item.project), /* @__PURE__ */ import_react.default.createElement("span", { className: `text-[10px] font-medium px-1.5 py-0.5 rounded ${srcBadge.bg} ${srcBadge.text}` }, srcBadge.label), /* @__PURE__ */ import_react.default.createElement("span", { className: "text-[10px] text-zinc-600 font-mono" }, timeAgo(item.created_at_epoch)), item.score > 0 && /* @__PURE__ */ import_react.default.createElement("span", { className: "text-[10px] text-zinc-700 font-mono" }, (item.score * 100).toFixed(0), "%")))
|
|
23777
23775
|
);
|
|
23778
23776
|
})), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-4 px-4 py-2.5 border-t border-border text-[11px] text-zinc-600" }, /* @__PURE__ */ import_react.default.createElement("span", null, /* @__PURE__ */ import_react.default.createElement("kbd", { className: "px-1 py-0.5 rounded bg-surface-3 border border-border font-mono mr-1" }, "\u2191\u2193"), "navigate"), /* @__PURE__ */ import_react.default.createElement("span", null, /* @__PURE__ */ import_react.default.createElement("kbd", { className: "px-1 py-0.5 rounded bg-surface-3 border border-border font-mono mr-1" }, "\u21B5"), "open"), /* @__PURE__ */ import_react.default.createElement("span", null, /* @__PURE__ */ import_react.default.createElement("kbd", { className: "px-1 py-0.5 rounded bg-surface-3 border border-border font-mono mr-1" }, "esc"), "close"))))));
|
|
23779
23777
|
}
|
|
@@ -23788,7 +23786,7 @@ function formatAgo(ms) {
|
|
|
23788
23786
|
if (min < 60) return `${min}m ago`;
|
|
23789
23787
|
return `${Math.floor(min / 60)}h ago`;
|
|
23790
23788
|
}
|
|
23791
|
-
function Header({ isConnected, lastEventTime, resolvedTheme, themePreference, onThemeChange, currentView, onViewChange, onMenuToggle }) {
|
|
23789
|
+
function Header({ isConnected, lastEventTime, resolvedTheme, themePreference, onThemeChange, currentView, onViewChange, onMenuToggle, onSearchNavigate }) {
|
|
23792
23790
|
const cycleTheme = () => {
|
|
23793
23791
|
const order = ["dark", "light", "system"];
|
|
23794
23792
|
const current = order.indexOf(themePreference);
|
|
@@ -23809,7 +23807,7 @@ function Header({ isConnected, lastEventTime, resolvedTheme, themePreference, on
|
|
|
23809
23807
|
"aria-label": "Apri menu laterale"
|
|
23810
23808
|
},
|
|
23811
23809
|
/* @__PURE__ */ import_react2.default.createElement("svg", { className: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react2.default.createElement("line", { x1: "4", y1: "6", x2: "20", y2: "6" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "4", y1: "12", x2: "20", y2: "12" }), /* @__PURE__ */ import_react2.default.createElement("line", { x1: "4", y1: "18", x2: "20", y2: "18" }))
|
|
23812
|
-
), /* @__PURE__ */ import_react2.default.createElement(
|
|
23810
|
+
), /* @__PURE__ */ import_react2.default.createElement(SearchBar, { onNavigate: onSearchNavigate }), /* @__PURE__ */ import_react2.default.createElement("div", { className: "flex-1" }), /* @__PURE__ */ import_react2.default.createElement("div", { className: "hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-lg bg-surface-2 border border-border" }, /* @__PURE__ */ import_react2.default.createElement("div", { className: `w-2 h-2 rounded-full transition-all ${isFresh ? "bg-accent-green scale-125" : isConnected ? "bg-accent-green animate-pulse-dot" : "bg-zinc-500"}` }), /* @__PURE__ */ import_react2.default.createElement("span", { className: `text-xs font-medium ${isConnected ? "text-accent-green" : "text-zinc-500"}` }, isConnected ? "Live" : "Offline"), agoText && /* @__PURE__ */ import_react2.default.createElement("span", { className: "text-[10px] text-zinc-600 ml-1" }, agoText)), /* @__PURE__ */ import_react2.default.createElement("div", { className: "hidden sm:flex items-center rounded-lg bg-surface-2 border border-border p-0.5", role: "tablist", "aria-label": "View mode" }, /* @__PURE__ */ import_react2.default.createElement(
|
|
23813
23811
|
"button",
|
|
23814
23812
|
{
|
|
23815
23813
|
onClick: () => onViewChange("feed"),
|
|
@@ -23891,7 +23889,9 @@ function Sidebar({
|
|
|
23891
23889
|
const [editingProject, setEditingProject] = (0, import_react3.useState)(null);
|
|
23892
23890
|
const [editValue, setEditValue] = (0, import_react3.useState)("");
|
|
23893
23891
|
const [renameFeedback, setRenameFeedback] = (0, import_react3.useState)(null);
|
|
23892
|
+
const [projectSearch, setProjectSearch] = (0, import_react3.useState)("");
|
|
23894
23893
|
const editInputRef = (0, import_react3.useRef)(null);
|
|
23894
|
+
const filteredProjects = projectSearch ? projects.filter((p) => getDisplayName(p).toLowerCase().includes(projectSearch.toLowerCase()) || p.toLowerCase().includes(projectSearch.toLowerCase())) : projects;
|
|
23895
23895
|
(0, import_react3.useEffect)(() => {
|
|
23896
23896
|
if (editingProject && editInputRef.current) {
|
|
23897
23897
|
editInputRef.current.focus();
|
|
@@ -23923,7 +23923,7 @@ function Sidebar({
|
|
|
23923
23923
|
if (e.key === "Enter") confirmEdit();
|
|
23924
23924
|
if (e.key === "Escape") cancelEdit();
|
|
23925
23925
|
};
|
|
23926
|
-
return /* @__PURE__ */ import_react3.default.createElement("aside", { className: "h-full overflow-y-auto bg-surface-1 border-r border-border flex flex-col" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "p-4" }, /* @__PURE__ */ import_react3.default.createElement("h3", { className: "text-[11px] font-semibold uppercase tracking-wider text-zinc-500 mb-3 px-2" }, "Projects"), /* @__PURE__ */ import_react3.default.createElement(
|
|
23926
|
+
return /* @__PURE__ */ import_react3.default.createElement("aside", { className: "h-full overflow-y-auto bg-surface-1 border-r border-border flex flex-col" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex items-center gap-3 px-4 h-14 border-b border-border flex-shrink-0" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-8 h-8 flex-shrink-0", viewBox: "0 0 96 96" }, /* @__PURE__ */ import_react3.default.createElement("defs", null, /* @__PURE__ */ import_react3.default.createElement("linearGradient", { id: "km-grad", x1: "0%", y1: "0%", x2: "100%", y2: "100%" }, /* @__PURE__ */ import_react3.default.createElement("stop", { offset: "0%", stopColor: "#7C5AFF" }), /* @__PURE__ */ import_react3.default.createElement("stop", { offset: "100%", stopColor: "#3B82F6" }))), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "48", cy: "48", r: "44", fill: "none", stroke: "url(#km-grad)", strokeWidth: "1.5", opacity: "0.4" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "48", cy: "48", r: "10", fill: "url(#km-grad)", opacity: "0.9" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "48", cy: "8", r: "5", fill: "#7C5AFF", opacity: "0.9" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "82", cy: "28", r: "4", fill: "#6366F1", opacity: "0.7" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "82", cy: "68", r: "3.5", fill: "#3B82F6", opacity: "0.5" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "48", cy: "88", r: "3", fill: "#2563EB", opacity: "0.4" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "14", cy: "68", r: "2.5", fill: "#3B82F6", opacity: "0.3" }), /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "14", cy: "28", r: "2", fill: "#7C5AFF", opacity: "0.25" }), /* @__PURE__ */ import_react3.default.createElement("line", { x1: "48", y1: "13", x2: "48", y2: "38", stroke: "#7C5AFF", strokeWidth: "1", opacity: "0.3", strokeDasharray: "3 4" }), /* @__PURE__ */ import_react3.default.createElement("line", { x1: "78", y1: "30", x2: "56", y2: "44", stroke: "#6366F1", strokeWidth: "1", opacity: "0.25", strokeDasharray: "3 4" }), /* @__PURE__ */ import_react3.default.createElement("line", { x1: "78", y1: "66", x2: "56", y2: "52", stroke: "#3B82F6", strokeWidth: "1", opacity: "0.2", strokeDasharray: "3 4" }), /* @__PURE__ */ import_react3.default.createElement("line", { x1: "48", y1: "85", x2: "48", y2: "58", stroke: "#2563EB", strokeWidth: "1", opacity: "0.15", strokeDasharray: "3 4" }), /* @__PURE__ */ import_react3.default.createElement("line", { x1: "17", y1: "66", x2: "40", y2: "52", stroke: "#3B82F6", strokeWidth: "1", opacity: "0.15", strokeDasharray: "3 4" })), /* @__PURE__ */ import_react3.default.createElement("div", null, /* @__PURE__ */ import_react3.default.createElement("h1", { className: "text-[15px] font-bold text-zinc-100 leading-none" }, "Kiro Memory"), /* @__PURE__ */ import_react3.default.createElement("span", { className: "text-[11px] text-zinc-500 mt-0.5 block" }, "Memory Dashboard"))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "p-4" }, /* @__PURE__ */ import_react3.default.createElement("h3", { className: "text-[11px] font-semibold uppercase tracking-wider text-zinc-500 mb-3 px-2" }, "Projects"), /* @__PURE__ */ import_react3.default.createElement(
|
|
23927
23927
|
"button",
|
|
23928
23928
|
{
|
|
23929
23929
|
onClick: () => onFilterChange(""),
|
|
@@ -23932,7 +23932,16 @@ function Sidebar({
|
|
|
23932
23932
|
/* @__PURE__ */ import_react3.default.createElement("div", { className: "w-7 h-7 rounded-md bg-accent-violet/15 flex items-center justify-center flex-shrink-0" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5 text-accent-violet", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react3.default.createElement("rect", { x: "3", y: "3", width: "7", height: "7" }), /* @__PURE__ */ import_react3.default.createElement("rect", { x: "14", y: "3", width: "7", height: "7" }), /* @__PURE__ */ import_react3.default.createElement("rect", { x: "3", y: "14", width: "7", height: "7" }), /* @__PURE__ */ import_react3.default.createElement("rect", { x: "14", y: "14", width: "7", height: "7" }))),
|
|
23933
23933
|
/* @__PURE__ */ import_react3.default.createElement("span", { className: "flex-1" }, "All projects"),
|
|
23934
23934
|
/* @__PURE__ */ import_react3.default.createElement("span", { className: "text-xs text-zinc-600 font-mono tabular-nums" }, projects.length)
|
|
23935
|
-
), /* @__PURE__ */ import_react3.default.createElement("div", { className: "
|
|
23935
|
+
), projects.length >= 6 && /* @__PURE__ */ import_react3.default.createElement("div", { className: "relative mt-1 mb-2" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-3 h-3 text-zinc-600", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react3.default.createElement("circle", { cx: "11", cy: "11", r: "8" }), /* @__PURE__ */ import_react3.default.createElement("path", { d: "m21 21-4.3-4.3" })), /* @__PURE__ */ import_react3.default.createElement(
|
|
23936
|
+
"input",
|
|
23937
|
+
{
|
|
23938
|
+
type: "text",
|
|
23939
|
+
value: projectSearch,
|
|
23940
|
+
onChange: (e) => setProjectSearch(e.target.value),
|
|
23941
|
+
placeholder: "Filter projects...",
|
|
23942
|
+
className: "w-full bg-surface-2 border border-border rounded-md text-xs text-zinc-300 placeholder-zinc-600 pl-7 pr-2 py-1.5 outline-none focus:border-accent-violet/50 transition-colors"
|
|
23943
|
+
}
|
|
23944
|
+
)), /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex flex-col gap-0.5 mt-1 max-h-[40vh] overflow-y-auto" }, filteredProjects.map((project) => {
|
|
23936
23945
|
const pc = getProjectColorByName(project);
|
|
23937
23946
|
const isEditing = editingProject === project;
|
|
23938
23947
|
const isActive = currentFilter === project;
|
|
@@ -23949,10 +23958,18 @@ function Sidebar({
|
|
|
23949
23958
|
className: "flex-1 min-w-0 bg-transparent border-none outline-none text-sm text-zinc-200"
|
|
23950
23959
|
}
|
|
23951
23960
|
), /* @__PURE__ */ import_react3.default.createElement("button", { onClick: confirmEdit, className: "text-accent-green hover:text-accent-green/80 p-0.5" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5" }, /* @__PURE__ */ import_react3.default.createElement("polyline", { points: "20 6 9 17 4 12" }))), /* @__PURE__ */ import_react3.default.createElement("button", { onClick: cancelEdit, className: "text-zinc-500 hover:text-zinc-300 p-0.5" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M18 6 6 18M6 6l12 12" })))) : /* @__PURE__ */ import_react3.default.createElement(
|
|
23952
|
-
"
|
|
23961
|
+
"div",
|
|
23953
23962
|
{
|
|
23963
|
+
role: "button",
|
|
23964
|
+
tabIndex: 0,
|
|
23954
23965
|
onClick: () => onFilterChange(project),
|
|
23955
|
-
|
|
23966
|
+
onKeyDown: (e) => {
|
|
23967
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
23968
|
+
e.preventDefault();
|
|
23969
|
+
onFilterChange(project);
|
|
23970
|
+
}
|
|
23971
|
+
},
|
|
23972
|
+
className: `w-full flex items-center gap-3 px-3 py-2 rounded-lg text-sm transition-all text-left cursor-pointer ${isActive ? "bg-surface-3 text-zinc-100 font-medium" : "text-zinc-400 hover:text-zinc-200 hover:bg-surface-2"}`
|
|
23956
23973
|
},
|
|
23957
23974
|
/* @__PURE__ */ import_react3.default.createElement("div", { className: `w-7 h-7 rounded-md flex items-center justify-center flex-shrink-0 text-[11px] font-bold ${pc.bg} ${pc.text}` }, initials),
|
|
23958
23975
|
/* @__PURE__ */ import_react3.default.createElement("span", { className: "flex-1 truncate" }, getDisplayName(project)),
|
|
@@ -23992,7 +24009,7 @@ function Sidebar({
|
|
|
23992
24009
|
className: "h-full bg-gradient-to-r from-emerald-500 to-emerald-400 transition-all",
|
|
23993
24010
|
style: { width: `${Math.min(100, Math.round(stats.tokenEconomics.readTokens / stats.tokenEconomics.discoveryTokens * 100))}%` }
|
|
23994
24011
|
}
|
|
23995
|
-
)), stats.tokenEconomics.discoveryTokens > 0 && /* @__PURE__ */ import_react3.default.createElement("p", { className: "text-[10px] text-zinc-600 text-center" }, Math.round((1 - stats.tokenEconomics.readTokens / stats.tokenEconomics.discoveryTokens) * 100), "% token reduction")))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "mt-auto px-4 py-4 space-y-2" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex items-center justify-center gap-3" }, /* @__PURE__ */ import_react3.default.createElement("a", { href: "https://github.com/
|
|
24012
|
+
)), stats.tokenEconomics.discoveryTokens > 0 && /* @__PURE__ */ import_react3.default.createElement("p", { className: "text-[10px] text-zinc-600 text-center" }, Math.round((1 - stats.tokenEconomics.readTokens / stats.tokenEconomics.discoveryTokens) * 100), "% token reduction")))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "mt-auto px-4 py-4 space-y-2" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex items-center justify-center gap-3" }, /* @__PURE__ */ import_react3.default.createElement("a", { href: "https://github.com/Auriti-Labs/kiro-memory", target: "_blank", rel: "noopener noreferrer", className: "text-zinc-600 hover:text-zinc-400 transition-colors", title: "GitHub" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "currentColor" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2z" }))), /* @__PURE__ */ import_react3.default.createElement("a", { href: "https://auritidesign.it/docs/kiro-memory/", target: "_blank", rel: "noopener noreferrer", className: "text-zinc-600 hover:text-zinc-400 transition-colors", title: "Documentazione" }, /* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" }), /* @__PURE__ */ import_react3.default.createElement("path", { d: "M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" })))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-[10px] text-zinc-700 font-mono text-center" }, "Kiro Memory v1.9.0")));
|
|
23996
24013
|
}
|
|
23997
24014
|
|
|
23998
24015
|
// src/ui/viewer/components/Feed.tsx
|
|
@@ -24129,7 +24146,7 @@ function ObservationCard({ obs, getDisplayName }) {
|
|
|
24129
24146
|
const style = getTypeStyle(obs.type);
|
|
24130
24147
|
const narrative = generateNarrative(obs);
|
|
24131
24148
|
const detail = getDetailLine(obs);
|
|
24132
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: `bg-surface-1 border border-border rounded-lg border-l-[3px] ${style.border} shadow-card hover:shadow-card-hover hover:border-border-hover transition-all` }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 py-3.5" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md ${style.bg} ${style.text}` }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `w-1.5 h-1.5 rounded-full ${style.dot}` }), style.label), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(obs.project)), obs.is_stale === 1 && /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-md bg-amber-500/10 text-amber-400 ring-1 ring-amber-500/25", title: "File modificato dopo l'osservazione" }, "stale"), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto tabular-nums" }, timeAgo(obs.created_at_epoch))), /* @__PURE__ */ import_react4.default.createElement("h4", { className: "text-sm text-zinc-200 leading-snug" }, renderMarkdown(narrative)), obs.subtitle && obs.subtitle !== obs.title && /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-[12px] text-zinc-500 mt-1 font-mono truncate" }, stripProjectRoot(obs.subtitle)), detail && /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-[11px] text-zinc-600 mt-1.5" }, detail), /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mt-2.5" }, obs.concepts && /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex flex-wrap gap-1" }, obs.concepts.split(", ").map((concept, i) => {
|
|
24149
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: `bg-surface-1 border border-border rounded-lg border-l-[3px] ${style.border} shadow-card hover:shadow-card-hover hover:border-border-hover transition-all overflow-hidden` }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 py-3.5 min-w-0" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2 flex-wrap" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md ${style.bg} ${style.text}` }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `w-1.5 h-1.5 rounded-full ${style.dot}` }), style.label), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(obs.project)), obs.is_stale === 1 && /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-md bg-amber-500/10 text-amber-400 ring-1 ring-amber-500/25", title: "File modificato dopo l'osservazione" }, "stale"), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto tabular-nums" }, timeAgo(obs.created_at_epoch))), /* @__PURE__ */ import_react4.default.createElement("h4", { className: "text-sm text-zinc-200 leading-snug break-words" }, renderMarkdown(narrative)), obs.subtitle && obs.subtitle !== obs.title && /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-[12px] text-zinc-500 mt-1 font-mono truncate" }, stripProjectRoot(obs.subtitle)), detail && /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-[11px] text-zinc-600 mt-1.5" }, detail), /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mt-2.5" }, obs.concepts && /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex flex-wrap gap-1" }, obs.concepts.split(", ").map((concept, i) => {
|
|
24133
24150
|
const colorClass = CONCEPT_COLORS[concept.trim()] || "bg-zinc-500/15 text-zinc-400 ring-zinc-500/25";
|
|
24134
24151
|
return /* @__PURE__ */ import_react4.default.createElement("span", { key: i, className: `text-[10px] font-medium px-1.5 py-0.5 rounded ring-1 ${colorClass}` }, concept.trim());
|
|
24135
24152
|
})), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[10px] text-zinc-700 font-mono ml-auto tabular-nums" }, "#", obs.id))));
|
|
@@ -24142,10 +24159,10 @@ function SummaryCard({ summary, getDisplayName }) {
|
|
|
24142
24159
|
{ label: "Next Steps", value: summary.next_steps, color: "text-amber-400" },
|
|
24143
24160
|
{ label: "Notes", value: summary.notes, color: "text-zinc-400" }
|
|
24144
24161
|
].filter((s) => s.value);
|
|
24145
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "bg-surface-1 border border-border rounded-lg border-l-[3px] border-l-cyan-500 shadow-card hover:shadow-card-hover hover:border-border-hover transition-all" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pt-4 pb-2" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md bg-cyan-500/10 text-cyan-400" }, /* @__PURE__ */ import_react4.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react4.default.createElement("path", { d: "M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" })), "Session Summary"), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(summary.project)), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto" }, timeAgo(summary.created_at_epoch))), summary.request && /* @__PURE__ */ import_react4.default.createElement("h3", { className: "text-[15px] font-semibold text-zinc-100 leading-snug" }, summary.request)), /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pb-4 space-y-2" }, sections.map(({ label, value, color }) => /* @__PURE__ */ import_react4.default.createElement("div", { key: label, className: "p-3 rounded-md bg-surface-2 border border-border" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `block text-[10px] font-semibold uppercase tracking-wider mb-1 ${color}` }, label), /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-xs text-zinc-400 leading-relaxed" }, value)))));
|
|
24162
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "bg-surface-1 border border-border rounded-lg border-l-[3px] border-l-cyan-500 shadow-card hover:shadow-card-hover hover:border-border-hover transition-all overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pt-4 pb-2 min-w-0" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2 flex-wrap" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md bg-cyan-500/10 text-cyan-400" }, /* @__PURE__ */ import_react4.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react4.default.createElement("path", { d: "M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" }), /* @__PURE__ */ import_react4.default.createElement("path", { d: "M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" })), "Session Summary"), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(summary.project)), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto" }, timeAgo(summary.created_at_epoch))), summary.request && /* @__PURE__ */ import_react4.default.createElement("h3", { className: "text-[15px] font-semibold text-zinc-100 leading-snug break-words" }, summary.request)), /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pb-4 space-y-2" }, sections.map(({ label, value, color }) => /* @__PURE__ */ import_react4.default.createElement("div", { key: label, className: "p-3 rounded-md bg-surface-2 border border-border" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: `block text-[10px] font-semibold uppercase tracking-wider mb-1 ${color}` }, label), /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-xs text-zinc-400 leading-relaxed" }, value)))));
|
|
24146
24163
|
}
|
|
24147
24164
|
function PromptCard({ prompt, getDisplayName }) {
|
|
24148
|
-
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "bg-surface-1 border border-border rounded-lg border-l-[3px] border-l-rose-500 shadow-card hover:shadow-card-hover hover:border-border-hover transition-all" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pt-4 pb-2" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md bg-rose-500/10 text-rose-400" }, /* @__PURE__ */ import_react4.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react4.default.createElement("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })), "Prompt #", prompt.prompt_number), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(prompt.project)), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto" }, timeAgo(prompt.created_at_epoch)))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pb-4" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "p-3 rounded-md bg-surface-0 border border-border text-sm text-zinc-300 leading-relaxed whitespace-pre-wrap break-words" }, prompt.prompt_text)));
|
|
24165
|
+
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "bg-surface-1 border border-border rounded-lg border-l-[3px] border-l-rose-500 shadow-card hover:shadow-card-hover hover:border-border-hover transition-all overflow-hidden" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pt-4 pb-2 min-w-0" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-center gap-2 mb-2 flex-wrap" }, /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide px-2 py-0.5 rounded-md bg-rose-500/10 text-rose-400" }, /* @__PURE__ */ import_react4.default.createElement("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react4.default.createElement("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })), "Prompt #", prompt.prompt_number), /* @__PURE__ */ import_react4.default.createElement("span", { className: "inline-flex items-center text-[11px] font-medium px-2 py-0.5 rounded-md bg-accent-violet/10 text-accent-violet" }, getDisplayName(prompt.project)), /* @__PURE__ */ import_react4.default.createElement("span", { className: "text-[11px] text-zinc-500 font-mono ml-auto" }, timeAgo(prompt.created_at_epoch)))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "px-4 pb-4" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "p-3 rounded-md bg-surface-0 border border-border text-sm text-zinc-300 leading-relaxed whitespace-pre-wrap break-words" }, prompt.prompt_text)));
|
|
24149
24166
|
}
|
|
24150
24167
|
|
|
24151
24168
|
// src/ui/viewer/components/Analytics.tsx
|
|
@@ -24405,7 +24422,7 @@ function Sessions({ currentFilter, getDisplayName }) {
|
|
|
24405
24422
|
/* @__PURE__ */ import_react7.default.createElement("path", { d: "m6 9 6 6 6-6" })
|
|
24406
24423
|
)
|
|
24407
24424
|
),
|
|
24408
|
-
isExpanded && /* @__PURE__ */ import_react7.default.createElement("div", { className: "px-4 pb-3 pt-0 border-t border-border space-y-2 animate-fade-in" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "grid grid-cols-2 gap-3 text-xs" }, /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "Session ID"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-zinc-400 font-mono text-[11px] truncate" }, session.content_session_id)), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "
|
|
24425
|
+
isExpanded && /* @__PURE__ */ import_react7.default.createElement("div", { className: "px-4 pb-3 pt-0 border-t border-border space-y-2 animate-fade-in" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "grid grid-cols-2 gap-3 text-xs" }, /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "Session ID"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-zinc-400 font-mono text-[11px] truncate" }, session.content_session_id)), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "Duration"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-zinc-400 font-mono text-[11px]" }, formatDuration(duration))), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "Started"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-zinc-400 font-mono text-[11px]" }, new Date(session.started_at_epoch).toLocaleString())), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-zinc-600" }, "Completed"), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-zinc-400 font-mono text-[11px]" }, session.completed_at_epoch ? new Date(session.completed_at_epoch).toLocaleString() : session.status === "completed" ? "Before tracking" : "\u2014"))), session.user_prompt && /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("span", { className: "text-[11px] text-zinc-600" }, "Prompt"), /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs text-zinc-400 mt-0.5 leading-relaxed break-words" }, session.user_prompt)))
|
|
24409
24426
|
);
|
|
24410
24427
|
})));
|
|
24411
24428
|
}
|
|
@@ -24682,6 +24699,7 @@ function App() {
|
|
|
24682
24699
|
const [isLoadingMore, setIsLoadingMore] = (0, import_react11.useState)(false);
|
|
24683
24700
|
const [hasMore, setHasMore] = (0, import_react11.useState)({ observations: true, summaries: true, prompts: true });
|
|
24684
24701
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = (0, import_react11.useState)(false);
|
|
24702
|
+
const [highlightObsId, setHighlightObsId] = (0, import_react11.useState)(null);
|
|
24685
24703
|
const { observations, summaries, prompts, projects, isConnected, lastEventTime } = useSSE();
|
|
24686
24704
|
const { preference: themePreference, resolvedTheme, setThemePreference } = useTheme();
|
|
24687
24705
|
const { getDisplayName, updateAlias } = useProjectAliases();
|
|
@@ -24791,19 +24809,34 @@ function App() {
|
|
|
24791
24809
|
fetchForProject(currentFilter);
|
|
24792
24810
|
}
|
|
24793
24811
|
}, [currentFilter, fetchForProject]);
|
|
24794
|
-
|
|
24795
|
-
|
|
24796
|
-
{
|
|
24797
|
-
|
|
24798
|
-
|
|
24799
|
-
|
|
24800
|
-
|
|
24801
|
-
|
|
24802
|
-
|
|
24803
|
-
|
|
24804
|
-
|
|
24805
|
-
|
|
24806
|
-
|
|
24812
|
+
(0, import_react11.useEffect)(() => {
|
|
24813
|
+
if (highlightObsId === null) return;
|
|
24814
|
+
const targetId = `obs-${highlightObsId}`;
|
|
24815
|
+
let attempts = 0;
|
|
24816
|
+
const tryScroll = () => {
|
|
24817
|
+
const el = document.querySelector(`[data-id="${targetId}"]`);
|
|
24818
|
+
if (el) {
|
|
24819
|
+
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
24820
|
+
el.classList.add("ring-2", "ring-accent-violet", "ring-offset-2", "ring-offset-surface-0");
|
|
24821
|
+
setTimeout(() => {
|
|
24822
|
+
el.classList.remove("ring-2", "ring-accent-violet", "ring-offset-2", "ring-offset-surface-0");
|
|
24823
|
+
setHighlightObsId(null);
|
|
24824
|
+
}, 3e3);
|
|
24825
|
+
} else if (attempts < 10) {
|
|
24826
|
+
attempts++;
|
|
24827
|
+
setTimeout(tryScroll, 200);
|
|
24828
|
+
} else {
|
|
24829
|
+
setHighlightObsId(null);
|
|
24830
|
+
}
|
|
24831
|
+
};
|
|
24832
|
+
tryScroll();
|
|
24833
|
+
}, [highlightObsId, paginatedObservations, allObservations]);
|
|
24834
|
+
const handleSearchNavigate = (0, import_react11.useCallback)((project, obsId) => {
|
|
24835
|
+
setCurrentView("feed");
|
|
24836
|
+
setCurrentFilter(project);
|
|
24837
|
+
setHighlightObsId(obsId);
|
|
24838
|
+
}, []);
|
|
24839
|
+
return /* @__PURE__ */ import_react11.default.createElement("div", { className: "h-screen overflow-hidden flex bg-surface-0" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "hidden md:flex w-[260px] flex-shrink-0" }, /* @__PURE__ */ import_react11.default.createElement(
|
|
24807
24840
|
Sidebar,
|
|
24808
24841
|
{
|
|
24809
24842
|
projects,
|
|
@@ -24836,7 +24869,20 @@ function App() {
|
|
|
24836
24869
|
getDisplayName,
|
|
24837
24870
|
onRenameProject: updateAlias
|
|
24838
24871
|
}
|
|
24839
|
-
))), /* @__PURE__ */ import_react11.default.createElement("
|
|
24872
|
+
))), /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex-1 min-w-0 flex flex-col overflow-hidden" }, /* @__PURE__ */ import_react11.default.createElement(
|
|
24873
|
+
Header,
|
|
24874
|
+
{
|
|
24875
|
+
isConnected,
|
|
24876
|
+
lastEventTime,
|
|
24877
|
+
resolvedTheme,
|
|
24878
|
+
themePreference,
|
|
24879
|
+
onThemeChange: setThemePreference,
|
|
24880
|
+
currentView,
|
|
24881
|
+
onViewChange: setCurrentView,
|
|
24882
|
+
onMenuToggle: () => setIsMobileMenuOpen((prev) => !prev),
|
|
24883
|
+
onSearchNavigate: handleSearchNavigate
|
|
24884
|
+
}
|
|
24885
|
+
), /* @__PURE__ */ import_react11.default.createElement("main", { className: "flex-1 min-w-0 overflow-y-auto bg-surface-0" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "max-w-3xl mx-auto px-6 py-6" }, currentFilter && /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-3 mb-6 animate-fade-in" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react11.default.createElement("div", { className: "w-9 h-9 rounded-lg bg-accent-violet/15 flex items-center justify-center" }, /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-xs font-bold text-accent-violet" }, getDisplayName(currentFilter).substring(0, 2).toUpperCase())), /* @__PURE__ */ import_react11.default.createElement("div", null, /* @__PURE__ */ import_react11.default.createElement("h2", { className: "text-lg font-bold text-zinc-100" }, getDisplayName(currentFilter)), currentFilter !== getDisplayName(currentFilter) && /* @__PURE__ */ import_react11.default.createElement("span", { className: "text-[11px] font-mono text-zinc-600" }, currentFilter))), /* @__PURE__ */ import_react11.default.createElement(
|
|
24840
24886
|
"button",
|
|
24841
24887
|
{
|
|
24842
24888
|
onClick: () => setCurrentFilter(""),
|
|
@@ -4595,9 +4595,9 @@ function getLatestCheckpointByProject(db2, project) {
|
|
|
4595
4595
|
}
|
|
4596
4596
|
|
|
4597
4597
|
// src/services/sqlite/Sessions.ts
|
|
4598
|
-
function
|
|
4599
|
-
const query = db2.query("SELECT * FROM sessions
|
|
4600
|
-
return query.all();
|
|
4598
|
+
function getAllSessions(db2, limit = 100) {
|
|
4599
|
+
const query = db2.query("SELECT * FROM sessions ORDER BY started_at_epoch DESC LIMIT ?");
|
|
4600
|
+
return query.all(limit);
|
|
4601
4601
|
}
|
|
4602
4602
|
function getSessionsByProject(db2, project, limit = 100) {
|
|
4603
4603
|
const query = db2.query("SELECT * FROM sessions WHERE project = ? ORDER BY started_at_epoch DESC LIMIT ?");
|
|
@@ -4915,7 +4915,7 @@ app.get("/health", (req, res) => {
|
|
|
4915
4915
|
res.json({
|
|
4916
4916
|
status: "ok",
|
|
4917
4917
|
timestamp: Date.now(),
|
|
4918
|
-
version: "1.
|
|
4918
|
+
version: "1.9.0"
|
|
4919
4919
|
});
|
|
4920
4920
|
});
|
|
4921
4921
|
app.get("/events", (req, res) => {
|
|
@@ -5475,7 +5475,7 @@ app.get("/api/sessions", (req, res) => {
|
|
|
5475
5475
|
return;
|
|
5476
5476
|
}
|
|
5477
5477
|
try {
|
|
5478
|
-
const sessions = project ? getSessionsByProject(db.db, project, 50) :
|
|
5478
|
+
const sessions = project ? getSessionsByProject(db.db, project, 50) : getAllSessions(db.db, 50);
|
|
5479
5479
|
res.json(sessions);
|
|
5480
5480
|
} catch (error) {
|
|
5481
5481
|
logger.error("WORKER", "Lista sessioni fallita", { project }, error);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Messaggio post-installazione Kiro Memory
|
|
4
|
+
* Eseguito automaticamente dopo npm install -g kiro-memory
|
|
5
|
+
* File .cjs per compatibilità con "type": "module" nel package.json
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* Silenzioso in CI o con npm in modalità silenziosa */
|
|
9
|
+
if (process.env.CI || process.env.npm_config_loglevel === 'silent') {
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { readFileSync } = require('fs');
|
|
14
|
+
const { join } = require('path');
|
|
15
|
+
|
|
16
|
+
let version = '';
|
|
17
|
+
try {
|
|
18
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
19
|
+
version = pkg.version || '';
|
|
20
|
+
} catch { /* ignora */ }
|
|
21
|
+
|
|
22
|
+
/* Rileva supporto colori */
|
|
23
|
+
const color = !process.env.NO_COLOR && process.env.TERM !== 'dumb' && (process.stdout.isTTY || false);
|
|
24
|
+
const c = (code, text) => color ? `${code}${text}\x1b[0m` : text;
|
|
25
|
+
const BOLD = '\x1b[1m';
|
|
26
|
+
const DIM = '\x1b[2m';
|
|
27
|
+
const UND = '\x1b[4m';
|
|
28
|
+
const VIOLET = '\x1b[38;5;135m';
|
|
29
|
+
const CYAN = '\x1b[36m';
|
|
30
|
+
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(` ${c(VIOLET + BOLD, 'Kiro Memory')} ${version ? `v${version}` : ''} installed!`);
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(` ${c(DIM, 'Get started:')}`);
|
|
35
|
+
console.log(` ${c(BOLD, 'kiro-memory install')} Auto-detect editor`);
|
|
36
|
+
console.log(` ${c(BOLD, 'kiro-memory install --claude-code')} Claude Code`);
|
|
37
|
+
console.log(` ${c(BOLD, 'kiro-memory install --cursor')} Cursor`);
|
|
38
|
+
console.log(` ${c(BOLD, 'kiro-memory install --windsurf')} Windsurf`);
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(` ${c(CYAN, 'Dashboard:')} ${c(UND, 'http://localhost:3001')}`);
|
|
41
|
+
console.log(` ${c(DIM, 'Docs: ')} ${c(UND, 'https://auritidesign.it/docs/kiro-memory/')}`);
|
|
42
|
+
console.log('');
|