@devness/useai 0.4.15 → 0.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +69 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -112,7 +112,7 @@ var VERSION;
112
112
  var init_version = __esm({
113
113
  "../shared/dist/constants/version.js"() {
114
114
  "use strict";
115
- VERSION = "0.4.15";
115
+ VERSION = "0.4.17";
116
116
  }
117
117
  });
118
118
 
@@ -1040,7 +1040,7 @@ var init_dist = __esm({
1040
1040
 
1041
1041
  // src/session-state.ts
1042
1042
  import { appendFileSync, existsSync as existsSync6 } from "fs";
1043
- import { join as join4 } from "path";
1043
+ import { basename, join as join4 } from "path";
1044
1044
  var SessionState;
1045
1045
  var init_session_state = __esm({
1046
1046
  "src/session-state.ts"() {
@@ -1053,6 +1053,7 @@ var init_session_state = __esm({
1053
1053
  sessionRecordCount;
1054
1054
  clientName;
1055
1055
  sessionTaskType;
1056
+ project;
1056
1057
  chainTipHash;
1057
1058
  signingKey;
1058
1059
  signingAvailable;
@@ -1063,6 +1064,7 @@ var init_session_state = __esm({
1063
1064
  this.sessionRecordCount = 0;
1064
1065
  this.clientName = "unknown";
1065
1066
  this.sessionTaskType = "coding";
1067
+ this.project = null;
1066
1068
  this.chainTipHash = GENESIS_HASH;
1067
1069
  this.signingKey = null;
1068
1070
  this.signingAvailable = false;
@@ -1074,6 +1076,10 @@ var init_session_state = __esm({
1074
1076
  this.sessionRecordCount = 0;
1075
1077
  this.chainTipHash = GENESIS_HASH;
1076
1078
  this.sessionTaskType = "coding";
1079
+ this.detectProject();
1080
+ }
1081
+ detectProject() {
1082
+ this.project = basename(process.cwd());
1077
1083
  }
1078
1084
  setClient(name) {
1079
1085
  this.clientName = name;
@@ -1161,6 +1167,7 @@ function registerTools(server2, session2) {
1161
1167
  const record = session2.appendToChain("session_start", {
1162
1168
  client: session2.clientName,
1163
1169
  task_type: session2.sessionTaskType,
1170
+ project: session2.project,
1164
1171
  version: VERSION
1165
1172
  });
1166
1173
  return {
@@ -1195,16 +1202,17 @@ function registerTools(server2, session2) {
1195
1202
  );
1196
1203
  server2.tool(
1197
1204
  "useai_session_end",
1198
- 'End the current AI coding session and record milestones. CRITICAL PRIVACY REQUIREMENT: Milestone titles must be COMPLETELY GENERIC. NEVER include project names, repository names, product names, package names, file names, file paths, class names, API endpoints, database names, or company names. Write as if describing the work to a stranger with zero knowledge of the codebase. GOOD: "Implemented user authentication", "Fixed race condition in background worker", "Added unit tests for data validation". BAD: "Fixed bug in Acme auth service", "Updated UserService.ts", "Investigated ProjectX pipeline".',
1205
+ `End the current AI coding session and record milestones. Each milestone needs TWO titles: (1) a generic public "title" safe for public display (NEVER include project names, file names, class names, or any identifying details), and (2) an optional detailed "private_title" for the user's own records that CAN include project names, file names, and specific details. GOOD title: "Implemented user authentication". GOOD private_title: "Added JWT auth to UseAI API server". BAD title: "Fixed bug in Acme auth service".`,
1199
1206
  {
1200
1207
  task_type: z2.enum(["coding", "debugging", "testing", "planning", "reviewing", "documenting", "learning", "other"]).optional().describe("What kind of task was the developer working on?"),
1201
1208
  languages: z2.array(z2.string()).optional().describe("Programming languages used (e.g. ['typescript', 'python'])"),
1202
1209
  files_touched_count: z2.number().optional().describe("Approximate number of files created or modified (count only, no names)"),
1203
1210
  milestones: z2.array(z2.object({
1204
1211
  title: z2.string().describe("PRIVACY-CRITICAL: Generic description of what was accomplished. NEVER include project names, repo names, product names, package names, file names, file paths, class names, API endpoints, database names, company names, or ANY identifier that could reveal which codebase this work was done in. Write as if describing the work to a stranger. GOOD: 'Implemented user authentication', 'Fixed race condition in background worker', 'Added unit tests for data validation', 'Refactored state management layer'. BAD: 'Fixed bug in Acme auth', 'Investigated ProjectX pipeline', 'Updated UserService.ts in src/services/', 'Added tests for coverit MCP tool'"),
1212
+ private_title: z2.string().optional().describe("Detailed description for the user's private records. CAN include project names, file names, and specific details. Example: 'Added private/public milestone support to UseAI MCP server'"),
1205
1213
  category: z2.enum(["feature", "bugfix", "refactor", "test", "docs", "setup", "deployment", "other"]).describe("Type of work completed"),
1206
1214
  complexity: z2.enum(["simple", "medium", "complex"]).optional().describe("How complex was this task?")
1207
- })).optional().describe("What was accomplished this session? List each distinct piece of work completed. Describe generically \u2014 no project names, file names, or proprietary details.")
1215
+ })).optional().describe("What was accomplished this session? List each distinct piece of work completed. Provide both a generic public title and an optional detailed private_title.")
1208
1216
  },
1209
1217
  async ({ task_type, languages, files_touched_count, milestones: milestonesInput }) => {
1210
1218
  const duration = session2.getSessionDuration();
@@ -1224,6 +1232,7 @@ function registerTools(server2, session2) {
1224
1232
  task_type: finalTaskType,
1225
1233
  languages: languages ?? [],
1226
1234
  files_touched: files_touched_count ?? 0,
1235
+ project: session2.project,
1227
1236
  started_at: new Date(session2.sessionStartTime).toISOString(),
1228
1237
  ended_at: now,
1229
1238
  duration_seconds: duration,
@@ -1253,6 +1262,7 @@ function registerTools(server2, session2) {
1253
1262
  task_type: finalTaskType,
1254
1263
  languages: languages ?? [],
1255
1264
  files_touched: files_touched_count ?? 0,
1265
+ project: session2.project ?? void 0,
1256
1266
  started_at: new Date(session2.sessionStartTime).toISOString(),
1257
1267
  ended_at: now,
1258
1268
  duration_seconds: duration,
@@ -1274,6 +1284,7 @@ function registerTools(server2, session2) {
1274
1284
  for (const m of milestonesInput) {
1275
1285
  const record = session2.appendToChain("milestone", {
1276
1286
  title: m.title,
1287
+ private_title: m.private_title,
1277
1288
  category: m.category,
1278
1289
  complexity: m.complexity ?? "medium",
1279
1290
  duration_minutes: durationMinutes,
@@ -1283,6 +1294,8 @@ function registerTools(server2, session2) {
1283
1294
  id: `m_${randomUUID3().slice(0, 8)}`,
1284
1295
  session_id: session2.sessionId,
1285
1296
  title: m.title,
1297
+ private_title: m.private_title,
1298
+ project: session2.project ?? void 0,
1286
1299
  category: m.category,
1287
1300
  complexity: m.complexity ?? "medium",
1288
1301
  duration_minutes: durationMinutes,
@@ -2337,10 +2350,47 @@ function getDashboardHtml() {
2337
2350
  border-bottom: 1px solid var(--border);
2338
2351
  }
2339
2352
  .milestone-item:last-child { border-bottom: none; }
2340
- .milestone-title {
2353
+ .milestone-title-block {
2341
2354
  flex: 1;
2355
+ min-width: 0;
2356
+ }
2357
+ .milestone-title {
2342
2358
  font-size: 0.88rem;
2343
2359
  color: var(--text);
2360
+ display: flex;
2361
+ align-items: center;
2362
+ gap: 6px;
2363
+ }
2364
+ .milestone-title .title-text {
2365
+ overflow: hidden;
2366
+ text-overflow: ellipsis;
2367
+ }
2368
+ .milestone-public-title {
2369
+ font-size: 0.75rem;
2370
+ color: var(--muted);
2371
+ margin-top: 2px;
2372
+ display: flex;
2373
+ align-items: center;
2374
+ gap: 4px;
2375
+ }
2376
+ .milestone-public-title .globe-icon {
2377
+ opacity: 0.5;
2378
+ flex-shrink: 0;
2379
+ }
2380
+ .private-icon {
2381
+ flex-shrink: 0;
2382
+ color: var(--amber-dim);
2383
+ opacity: 0.7;
2384
+ }
2385
+ .project-tag {
2386
+ font-size: 0.68rem;
2387
+ padding: 1px 6px;
2388
+ border-radius: 3px;
2389
+ background: #252520;
2390
+ color: var(--amber-dim);
2391
+ font-family: 'SF Mono', 'Fira Code', monospace;
2392
+ flex-shrink: 0;
2393
+ white-space: nowrap;
2344
2394
  }
2345
2395
  .milestone-meta {
2346
2396
  display: flex;
@@ -2613,6 +2663,8 @@ function getDashboardHtml() {
2613
2663
  }
2614
2664
  section.style.display = 'block';
2615
2665
  var recent = milestones.slice(-20).reverse();
2666
+ var lockSvg = '<svg class="private-icon" width="12" height="12" viewBox="0 0 16 16" fill="currentColor"><path d="M4 7V5a4 4 0 118 0v2h1a1 1 0 011 1v6a1 1 0 01-1 1H3a1 1 0 01-1-1V8a1 1 0 011-1h1zm2-2v2h4V5a2 2 0 10-4 0z"/></svg>';
2667
+ var globeSvg = '<svg class="globe-icon" width="10" height="10" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8 8 0 100 16A8 8 0 008 0zm5.3 5H11a13 13 0 00-1-3.2A6 6 0 0113.3 5zM8 1.5c.7.9 1.2 2.1 1.5 3.5h-3C6.8 3.6 7.3 2.4 8 1.5zM1.5 9a6 6 0 010-2h2.6a14 14 0 000 2H1.5zM2.7 11H5a13 13 0 001 3.2A6 6 0 012.7 11zM5 11h6a11 11 0 01-1.5 3.5c-.3.4-.7.7-1.1.9a6 6 0 01-1.9-1c-.4-.5-.7-1-.9-1.5-.2-.5-.4-1.2-.6-1.9zm6.9 0h2.4a6 6 0 01-3.3 3.2c.5-.9.8-2 1-3.2zm2.6-2h-2.6a14 14 0 000-2h2.6a6 6 0 010 2zM5.1 7a12 12 0 000 2H11a12 12 0 000-2H5.1zM6 1.8A6 6 0 012.7 5H5a13 13 0 011-3.2z"/></svg>';
2616
2668
  list.innerHTML = recent.map(function(m) {
2617
2669
  var date = '';
2618
2670
  if (m.created_at) {
@@ -2624,8 +2676,19 @@ function getDashboardHtml() {
2624
2676
  }
2625
2677
  }
2626
2678
  var dur = fmtDuration(m.duration_minutes);
2679
+ var hasPrivate = !!m.private_title;
2680
+ var displayTitle = hasPrivate ? m.private_title : m.title;
2681
+ var projectTag = m.project ? '<span class="project-tag">' + escapeHtml(m.project) + '</span>' : '';
2682
+ var titleLine = '<div class="milestone-title">' +
2683
+ (hasPrivate ? lockSvg : '') +
2684
+ '<span class="title-text">' + escapeHtml(displayTitle) + '</span>' +
2685
+ projectTag +
2686
+ '</div>';
2687
+ var publicLine = hasPrivate
2688
+ ? '<div class="milestone-public-title">' + globeSvg + escapeHtml(m.title) + '</div>'
2689
+ : '';
2627
2690
  return '<div class="milestone-item">' +
2628
- '<div class="milestone-title">' + escapeHtml(m.title) + '</div>' +
2691
+ '<div class="milestone-title-block">' + titleLine + publicLine + '</div>' +
2629
2692
  '<div class="milestone-meta">' +
2630
2693
  '<span class="' + badgeClass(m.category) + '">' + escapeHtml(m.category) + '</span>' +
2631
2694
  (m.complexity ? '<span class="complexity">' + escapeHtml(m.complexity) + '</span>' : '') +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devness/useai",
3
- "version": "0.4.15",
3
+ "version": "0.4.17",
4
4
  "description": "Track your AI-assisted development workflow. MCP server that records usage metrics across all your AI tools.",
5
5
  "keywords": [
6
6
  "mcp",