prjct-cli 0.51.0 → 0.52.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.52.0] - 2026-01-30
4
+
5
+ ### Features
6
+
7
+ - Add confidence scores to all stored preferences - PRJ-104 (#78)
8
+
9
+
10
+ ## [0.52.0] - 2026-01-30
11
+
12
+ ### Added
13
+
14
+ - **Confidence scores for stored preferences** (PRJ-104)
15
+ - All preferences, decisions, and workflows now track confidence level
16
+ - Confidence: `low` (1-2 obs), `medium` (3-5 obs), `high` (6+ or confirmed)
17
+ - Added `confirmPreference()`, `confirmDecision()`, `confirmWorkflow()` methods
18
+ - User confirmation immediately sets confidence to `high`
19
+ - Added `calculateConfidence()` utility function
20
+
21
+
3
22
  ## [0.51.0] - 2026-01-30
4
23
 
5
24
  ### Features
@@ -22,6 +22,7 @@ import { appendJsonLine, getLastJsonLines } from '../utils/jsonl-helper'
22
22
 
23
23
  // Re-export types from canonical location
24
24
  export type {
25
+ ConfidenceLevel,
25
26
  Decision,
26
27
  HistoryEntry,
27
28
  HistoryEventType,
@@ -35,7 +36,7 @@ export type {
35
36
  Workflow,
36
37
  } from '../types/memory'
37
38
 
38
- export { MEMORY_TAGS } from '../types/memory'
39
+ export { calculateConfidence, MEMORY_TAGS } from '../types/memory'
39
40
 
40
41
  import type {
41
42
  HistoryEntry,
@@ -49,7 +50,7 @@ import type {
49
50
  Workflow,
50
51
  } from '../types/memory'
51
52
 
52
- import { MEMORY_TAGS } from '../types/memory'
53
+ import { calculateConfidence, MEMORY_TAGS } from '../types/memory'
53
54
 
54
55
  // =============================================================================
55
56
  // Base Store
@@ -306,7 +307,8 @@ export class PatternStore extends CachedStore<Patterns> {
306
307
  projectId: string,
307
308
  key: string,
308
309
  value: string,
309
- context: string = ''
310
+ context: string = '',
311
+ options: { userConfirmed?: boolean } = {}
310
312
  ): Promise<void> {
311
313
  const patterns = await this.load(projectId)
312
314
  const now = getTimestamp()
@@ -317,11 +319,14 @@ export class PatternStore extends CachedStore<Patterns> {
317
319
  count: 1,
318
320
  firstSeen: now,
319
321
  lastSeen: now,
320
- confidence: 'low',
322
+ confidence: options.userConfirmed ? 'high' : 'low',
321
323
  contexts: [context].filter(Boolean),
322
- }
324
+ userConfirmed: options.userConfirmed || false,
325
+ } as Patterns['decisions'][string]
323
326
  } else {
324
- const decision = patterns.decisions[key]
327
+ const decision = patterns.decisions[key] as Patterns['decisions'][string] & {
328
+ userConfirmed?: boolean
329
+ }
325
330
 
326
331
  if (decision.value === value) {
327
332
  decision.count++
@@ -329,23 +334,36 @@ export class PatternStore extends CachedStore<Patterns> {
329
334
  if (context && !decision.contexts.includes(context)) {
330
335
  decision.contexts.push(context)
331
336
  }
332
-
333
- if (decision.count >= 5) {
334
- decision.confidence = 'high'
335
- } else if (decision.count >= 3) {
336
- decision.confidence = 'medium'
337
+ if (options.userConfirmed) {
338
+ decision.userConfirmed = true
337
339
  }
340
+ decision.confidence = calculateConfidence(decision.count, decision.userConfirmed)
338
341
  } else {
339
342
  decision.value = value
340
343
  decision.count = 1
341
344
  decision.lastSeen = now
342
- decision.confidence = 'low'
345
+ decision.userConfirmed = options.userConfirmed || false
346
+ decision.confidence = options.userConfirmed ? 'high' : 'low'
343
347
  }
344
348
  }
345
349
 
346
350
  await this.save(projectId)
347
351
  }
348
352
 
353
+ async confirmDecision(projectId: string, key: string): Promise<boolean> {
354
+ const patterns = await this.load(projectId)
355
+ const decision = patterns.decisions[key] as
356
+ | (Patterns['decisions'][string] & { userConfirmed?: boolean })
357
+ | undefined
358
+ if (!decision) return false
359
+
360
+ decision.userConfirmed = true
361
+ decision.confidence = 'high'
362
+ decision.lastSeen = getTimestamp()
363
+ await this.save(projectId)
364
+ return true
365
+ }
366
+
349
367
  async getDecision(
350
368
  projectId: string,
351
369
  key: string
@@ -378,15 +396,31 @@ export class PatternStore extends CachedStore<Patterns> {
378
396
  count: 1,
379
397
  firstSeen: now,
380
398
  lastSeen: now,
399
+ confidence: 'low',
400
+ userConfirmed: false,
381
401
  }
382
402
  } else {
383
- patterns.workflows[workflowName].count++
384
- patterns.workflows[workflowName].lastSeen = now
403
+ const workflow = patterns.workflows[workflowName]
404
+ workflow.count++
405
+ workflow.lastSeen = now
406
+ workflow.confidence = calculateConfidence(workflow.count, workflow.userConfirmed)
385
407
  }
386
408
 
387
409
  await this.save(projectId)
388
410
  }
389
411
 
412
+ async confirmWorkflow(projectId: string, workflowName: string): Promise<boolean> {
413
+ const patterns = await this.load(projectId)
414
+ const workflow = patterns.workflows[workflowName]
415
+ if (!workflow) return false
416
+
417
+ workflow.userConfirmed = true
418
+ workflow.confidence = 'high'
419
+ workflow.lastSeen = getTimestamp()
420
+ await this.save(projectId)
421
+ return true
422
+ }
423
+
390
424
  async getWorkflow(projectId: string, workflowName: string): Promise<Workflow | null> {
391
425
  const patterns = await this.load(projectId)
392
426
  const workflow = patterns.workflows[workflowName]
@@ -395,12 +429,39 @@ export class PatternStore extends CachedStore<Patterns> {
395
429
  return workflow
396
430
  }
397
431
 
398
- async setPreference(projectId: string, key: string, value: Preference['value']): Promise<void> {
432
+ async setPreference(
433
+ projectId: string,
434
+ key: string,
435
+ value: Preference['value'],
436
+ options: { userConfirmed?: boolean } = {}
437
+ ): Promise<void> {
399
438
  const patterns = await this.load(projectId)
400
- patterns.preferences[key] = { value, updatedAt: getTimestamp() }
439
+ const existing = patterns.preferences[key]
440
+ const observationCount = existing ? existing.observationCount + 1 : 1
441
+ const userConfirmed = options.userConfirmed || existing?.userConfirmed || false
442
+
443
+ patterns.preferences[key] = {
444
+ value,
445
+ updatedAt: getTimestamp(),
446
+ confidence: calculateConfidence(observationCount, userConfirmed),
447
+ observationCount,
448
+ userConfirmed,
449
+ }
401
450
  await this.save(projectId)
402
451
  }
403
452
 
453
+ async confirmPreference(projectId: string, key: string): Promise<boolean> {
454
+ const patterns = await this.load(projectId)
455
+ const pref = patterns.preferences[key]
456
+ if (!pref) return false
457
+
458
+ pref.userConfirmed = true
459
+ pref.confidence = 'high'
460
+ pref.updatedAt = getTimestamp()
461
+ await this.save(projectId)
462
+ return true
463
+ }
464
+
404
465
  async getPreference(
405
466
  projectId: string,
406
467
  key: string,
@@ -857,14 +918,31 @@ export class MemorySystem {
857
918
  return this._patternStore.getWorkflow(projectId, workflowName)
858
919
  }
859
920
 
860
- setPreference(projectId: string, key: string, value: Preference['value']): Promise<void> {
861
- return this._patternStore.setPreference(projectId, key, value)
921
+ setPreference(
922
+ projectId: string,
923
+ key: string,
924
+ value: Preference['value'],
925
+ options?: { userConfirmed?: boolean }
926
+ ): Promise<void> {
927
+ return this._patternStore.setPreference(projectId, key, value, options)
862
928
  }
863
929
 
864
930
  getPreference(projectId: string, key: string, defaultValue?: unknown): Promise<unknown> {
865
931
  return this._patternStore.getPreference(projectId, key, defaultValue)
866
932
  }
867
933
 
934
+ confirmPreference(projectId: string, key: string): Promise<boolean> {
935
+ return this._patternStore.confirmPreference(projectId, key)
936
+ }
937
+
938
+ confirmDecision(projectId: string, key: string): Promise<boolean> {
939
+ return this._patternStore.confirmDecision(projectId, key)
940
+ }
941
+
942
+ confirmWorkflow(projectId: string, workflowName: string): Promise<boolean> {
943
+ return this._patternStore.confirmWorkflow(projectId, workflowName)
944
+ }
945
+
868
946
  getPatternsSummary(projectId: string) {
869
947
  return this._patternStore.getPatternsSummary(projectId)
870
948
  }
@@ -43,6 +43,10 @@ export interface Memory {
43
43
  userTriggered: boolean
44
44
  createdAt: string
45
45
  updatedAt: string
46
+ /** Confidence level for this memory (optional for backward compatibility) */
47
+ confidence?: ConfidenceLevel
48
+ /** Number of times this memory was reinforced */
49
+ observationCount?: number
46
50
  }
47
51
 
48
52
  /**
@@ -123,8 +127,10 @@ export interface Decision {
123
127
  count: number
124
128
  firstSeen: string
125
129
  lastSeen: string
126
- confidence: 'low' | 'medium' | 'high'
130
+ confidence: ConfidenceLevel
127
131
  contexts: string[]
132
+ /** Whether user explicitly confirmed this decision */
133
+ userConfirmed?: boolean
128
134
  }
129
135
 
130
136
  /**
@@ -141,14 +147,47 @@ export interface Workflow {
141
147
  successRate?: number
142
148
  /** Steps in the workflow */
143
149
  steps?: string[]
150
+ /** Confidence level based on execution count */
151
+ confidence?: ConfidenceLevel
152
+ /** Whether user explicitly confirmed this workflow */
153
+ userConfirmed?: boolean
144
154
  }
145
155
 
146
156
  /**
147
- * A user preference value.
157
+ * Confidence level for stored preferences and decisions.
158
+ * @see PRJ-104
159
+ */
160
+ export type ConfidenceLevel = 'low' | 'medium' | 'high'
161
+
162
+ /**
163
+ * Calculate confidence level from observation count.
164
+ * - low: 1-2 observations
165
+ * - medium: 3-5 observations
166
+ * - high: 6+ observations or explicit user confirmation
167
+ */
168
+ export function calculateConfidence(
169
+ count: number,
170
+ userConfirmed: boolean = false
171
+ ): ConfidenceLevel {
172
+ if (userConfirmed) return 'high'
173
+ if (count >= 6) return 'high'
174
+ if (count >= 3) return 'medium'
175
+ return 'low'
176
+ }
177
+
178
+ /**
179
+ * A user preference value with confidence scoring.
180
+ * @see PRJ-104
148
181
  */
149
182
  export interface Preference {
150
183
  value: string | number | boolean
151
184
  updatedAt: string
185
+ /** Confidence level based on observations */
186
+ confidence: ConfidenceLevel
187
+ /** Number of times this preference was observed */
188
+ observationCount: number
189
+ /** Whether user explicitly confirmed this preference */
190
+ userConfirmed: boolean
152
191
  }
153
192
 
154
193
  /**
@@ -8568,6 +8568,12 @@ var init_jsonl_helper = __esm({
8568
8568
  });
8569
8569
 
8570
8570
  // core/types/memory.ts
8571
+ function calculateConfidence(count, userConfirmed = false) {
8572
+ if (userConfirmed) return "high";
8573
+ if (count >= 6) return "high";
8574
+ if (count >= 3) return "medium";
8575
+ return "low";
8576
+ }
8571
8577
  var MEMORY_TAGS;
8572
8578
  var init_memory = __esm({
8573
8579
  "core/types/memory.ts"() {
@@ -8591,6 +8597,7 @@ var init_memory = __esm({
8591
8597
  CONFIRMATION_LEVEL: "confirmation_level",
8592
8598
  AGENT_PREFERENCE: "agent_preference"
8593
8599
  };
8600
+ __name(calculateConfidence, "calculateConfidence");
8594
8601
  }
8595
8602
  });
8596
8603
 
@@ -8782,7 +8789,7 @@ var init_memory_system = __esm({
8782
8789
  async savePatterns(projectId) {
8783
8790
  return this.save(projectId);
8784
8791
  }
8785
- async recordDecision(projectId, key, value, context2 = "") {
8792
+ async recordDecision(projectId, key, value, context2 = "", options = {}) {
8786
8793
  const patterns = await this.load(projectId);
8787
8794
  const now = getTimestamp();
8788
8795
  if (!patterns.decisions[key]) {
@@ -8791,8 +8798,9 @@ var init_memory_system = __esm({
8791
8798
  count: 1,
8792
8799
  firstSeen: now,
8793
8800
  lastSeen: now,
8794
- confidence: "low",
8795
- contexts: [context2].filter(Boolean)
8801
+ confidence: options.userConfirmed ? "high" : "low",
8802
+ contexts: [context2].filter(Boolean),
8803
+ userConfirmed: options.userConfirmed || false
8796
8804
  };
8797
8805
  } else {
8798
8806
  const decision = patterns.decisions[key];
@@ -8802,20 +8810,30 @@ var init_memory_system = __esm({
8802
8810
  if (context2 && !decision.contexts.includes(context2)) {
8803
8811
  decision.contexts.push(context2);
8804
8812
  }
8805
- if (decision.count >= 5) {
8806
- decision.confidence = "high";
8807
- } else if (decision.count >= 3) {
8808
- decision.confidence = "medium";
8813
+ if (options.userConfirmed) {
8814
+ decision.userConfirmed = true;
8809
8815
  }
8816
+ decision.confidence = calculateConfidence(decision.count, decision.userConfirmed);
8810
8817
  } else {
8811
8818
  decision.value = value;
8812
8819
  decision.count = 1;
8813
8820
  decision.lastSeen = now;
8814
- decision.confidence = "low";
8821
+ decision.userConfirmed = options.userConfirmed || false;
8822
+ decision.confidence = options.userConfirmed ? "high" : "low";
8815
8823
  }
8816
8824
  }
8817
8825
  await this.save(projectId);
8818
8826
  }
8827
+ async confirmDecision(projectId, key) {
8828
+ const patterns = await this.load(projectId);
8829
+ const decision = patterns.decisions[key];
8830
+ if (!decision) return false;
8831
+ decision.userConfirmed = true;
8832
+ decision.confidence = "high";
8833
+ decision.lastSeen = getTimestamp();
8834
+ await this.save(projectId);
8835
+ return true;
8836
+ }
8819
8837
  async getDecision(projectId, key) {
8820
8838
  const patterns = await this.load(projectId);
8821
8839
  const decision = patterns.decisions[key];
@@ -8835,25 +8853,58 @@ var init_memory_system = __esm({
8835
8853
  ...pattern,
8836
8854
  count: 1,
8837
8855
  firstSeen: now,
8838
- lastSeen: now
8856
+ lastSeen: now,
8857
+ confidence: "low",
8858
+ userConfirmed: false
8839
8859
  };
8840
8860
  } else {
8841
- patterns.workflows[workflowName].count++;
8842
- patterns.workflows[workflowName].lastSeen = now;
8861
+ const workflow2 = patterns.workflows[workflowName];
8862
+ workflow2.count++;
8863
+ workflow2.lastSeen = now;
8864
+ workflow2.confidence = calculateConfidence(workflow2.count, workflow2.userConfirmed);
8843
8865
  }
8844
8866
  await this.save(projectId);
8845
8867
  }
8868
+ async confirmWorkflow(projectId, workflowName) {
8869
+ const patterns = await this.load(projectId);
8870
+ const workflow2 = patterns.workflows[workflowName];
8871
+ if (!workflow2) return false;
8872
+ workflow2.userConfirmed = true;
8873
+ workflow2.confidence = "high";
8874
+ workflow2.lastSeen = getTimestamp();
8875
+ await this.save(projectId);
8876
+ return true;
8877
+ }
8846
8878
  async getWorkflow(projectId, workflowName) {
8847
8879
  const patterns = await this.load(projectId);
8848
8880
  const workflow2 = patterns.workflows[workflowName];
8849
8881
  if (!workflow2 || workflow2.count < 3) return null;
8850
8882
  return workflow2;
8851
8883
  }
8852
- async setPreference(projectId, key, value) {
8884
+ async setPreference(projectId, key, value, options = {}) {
8853
8885
  const patterns = await this.load(projectId);
8854
- patterns.preferences[key] = { value, updatedAt: getTimestamp() };
8886
+ const existing = patterns.preferences[key];
8887
+ const observationCount = existing ? existing.observationCount + 1 : 1;
8888
+ const userConfirmed = options.userConfirmed || existing?.userConfirmed || false;
8889
+ patterns.preferences[key] = {
8890
+ value,
8891
+ updatedAt: getTimestamp(),
8892
+ confidence: calculateConfidence(observationCount, userConfirmed),
8893
+ observationCount,
8894
+ userConfirmed
8895
+ };
8855
8896
  await this.save(projectId);
8856
8897
  }
8898
+ async confirmPreference(projectId, key) {
8899
+ const patterns = await this.load(projectId);
8900
+ const pref = patterns.preferences[key];
8901
+ if (!pref) return false;
8902
+ pref.userConfirmed = true;
8903
+ pref.confidence = "high";
8904
+ pref.updatedAt = getTimestamp();
8905
+ await this.save(projectId);
8906
+ return true;
8907
+ }
8857
8908
  async getPreference(projectId, key, defaultValue = null) {
8858
8909
  const patterns = await this.load(projectId);
8859
8910
  return patterns.preferences[key]?.value ?? defaultValue;
@@ -9169,12 +9220,21 @@ Context: ${context2}` : ""}`,
9169
9220
  getWorkflow(projectId, workflowName) {
9170
9221
  return this._patternStore.getWorkflow(projectId, workflowName);
9171
9222
  }
9172
- setPreference(projectId, key, value) {
9173
- return this._patternStore.setPreference(projectId, key, value);
9223
+ setPreference(projectId, key, value, options) {
9224
+ return this._patternStore.setPreference(projectId, key, value, options);
9174
9225
  }
9175
9226
  getPreference(projectId, key, defaultValue) {
9176
9227
  return this._patternStore.getPreference(projectId, key, defaultValue);
9177
9228
  }
9229
+ confirmPreference(projectId, key) {
9230
+ return this._patternStore.confirmPreference(projectId, key);
9231
+ }
9232
+ confirmDecision(projectId, key) {
9233
+ return this._patternStore.confirmDecision(projectId, key);
9234
+ }
9235
+ confirmWorkflow(projectId, workflowName) {
9236
+ return this._patternStore.confirmWorkflow(projectId, workflowName);
9237
+ }
9178
9238
  getPatternsSummary(projectId) {
9179
9239
  return this._patternStore.getPatternsSummary(projectId);
9180
9240
  }
@@ -24604,7 +24664,7 @@ var require_package = __commonJS({
24604
24664
  "package.json"(exports, module) {
24605
24665
  module.exports = {
24606
24666
  name: "prjct-cli",
24607
- version: "0.51.0",
24667
+ version: "0.52.0",
24608
24668
  description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
24609
24669
  main: "core/index.ts",
24610
24670
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "description": "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {