fluffy-context 0.3.1 → 0.6.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.
Files changed (43) hide show
  1. package/README.md +61 -5
  2. package/dist/src/agent/api.d.ts +5 -1
  3. package/dist/src/agent/api.js +50 -10
  4. package/dist/src/agent/index.d.ts +1 -1
  5. package/dist/src/agent/types.d.ts +21 -0
  6. package/dist/src/cli/main.js +177 -9
  7. package/dist/src/cognition/feedback.d.ts +9 -0
  8. package/dist/src/cognition/feedback.js +30 -0
  9. package/dist/src/cognition/git-observer.d.ts +13 -0
  10. package/dist/src/cognition/git-observer.js +61 -0
  11. package/dist/src/cognition/journal.d.ts +24 -0
  12. package/dist/src/cognition/journal.js +113 -0
  13. package/dist/src/cognition/migration-v1.d.ts +7 -0
  14. package/dist/src/cognition/migration-v1.js +201 -0
  15. package/dist/src/cognition/orient.d.ts +13 -0
  16. package/dist/src/cognition/orient.js +94 -0
  17. package/dist/src/cognition/projections.d.ts +7 -0
  18. package/dist/src/cognition/projections.js +130 -0
  19. package/dist/src/cognition/readiness.d.ts +2 -0
  20. package/dist/src/cognition/readiness.js +81 -0
  21. package/dist/src/cognition/retrieval.d.ts +26 -0
  22. package/dist/src/cognition/retrieval.js +273 -0
  23. package/dist/src/cognition/runtime.d.ts +12 -0
  24. package/dist/src/cognition/runtime.js +295 -0
  25. package/dist/src/cognition/types.d.ts +170 -0
  26. package/dist/src/cognition/types.js +1 -0
  27. package/dist/src/cognition/v1-bridge.d.ts +7 -0
  28. package/dist/src/cognition/v1-bridge.js +82 -0
  29. package/dist/src/git/git-adapter.d.ts +7 -0
  30. package/dist/src/git/git-adapter.js +16 -6
  31. package/dist/src/hooks/claude-code.js +53 -0
  32. package/dist/src/runtime/diagnostics.js +6 -0
  33. package/dist/src/runtime/knowledge.d.ts +2 -0
  34. package/dist/src/runtime/knowledge.js +68 -0
  35. package/dist/src/runtime/notes.js +8 -1
  36. package/dist/src/runtime/runtime.d.ts +1 -0
  37. package/dist/src/runtime/runtime.js +28 -0
  38. package/dist/src/runtime/types.d.ts +19 -0
  39. package/dist/src/storage/layout.d.ts +19 -0
  40. package/dist/src/storage/layout.js +57 -0
  41. package/dist/src/version.d.ts +1 -1
  42. package/dist/src/version.js +1 -1
  43. package/package.json +2 -2
@@ -4,6 +4,7 @@ import { readJson } from '../storage/json-store.js';
4
4
  import { contextRoot, contextMetadataPath, contextsRoot, indexPath, manifestPath, notesPath, snapshotPath } from '../storage/layout.js';
5
5
  import { rebuildIndex, rebuildSnapshot } from './runtime.js';
6
6
  import { isValidNote } from './notes.js';
7
+ import { migrationReadiness } from '../cognition/readiness.js';
7
8
  import { filterPaths } from '../capture/context-filter.js';
8
9
  export async function status(startPath) {
9
10
  const projectRoot = await resolveProjectRoot(startPath);
@@ -95,5 +96,10 @@ export async function doctor(startPath) {
95
96
  if (rebuiltIds.size !== storedIds.size || [...rebuiltIds].some((id) => !storedIds.has(id)))
96
97
  throw new Error('index rebuild mismatch');
97
98
  });
99
+ await check('v2 migration readiness', async () => {
100
+ const readiness = await migrationReadiness(projectRoot);
101
+ if (!readiness.eligible)
102
+ throw new Error(readiness.issues.join('; '));
103
+ });
98
104
  return { healthy, projectRoot, checks };
99
105
  }
@@ -3,7 +3,9 @@ export declare function learnKnowledge(startPath: string | undefined, statement:
3
3
  export declare function listKnowledge(startPath?: string, includeUnverified?: boolean): Promise<Knowledge[]>;
4
4
  export declare function discoverKnowledge(startPath: string | undefined, query: string, options?: KnowledgeDiscoverOptions): Promise<KnowledgeDiscoveryResult>;
5
5
  export declare function verifyKnowledge(startPath: string | undefined, knowledgeId: string): Promise<Knowledge>;
6
+ export declare function transitionKnowledge(startPath: string | undefined, knowledgeId: string, status: 'deprecated' | 'rejected', reason: string): Promise<Knowledge>;
6
7
  export declare function recordDeadend(startPath: string | undefined, attempt: string, reason: string, scopeOrInput?: string | DeadendInput): Promise<Deadend>;
7
8
  export declare function listDeadends(startPath?: string, includeUnverified?: boolean): Promise<Deadend[]>;
8
9
  export declare function discoverDeadends(startPath: string | undefined, query: string, options?: DeadendDiscoverOptions): Promise<DeadendDiscoveryResult>;
10
+ export declare function transitionDeadend(startPath: string | undefined, deadendId: string, status: 'obsolete' | 'rejected', reason: string): Promise<Deadend>;
9
11
  export declare function verifyDeadend(startPath: string | undefined, deadendId: string): Promise<Deadend>;
@@ -5,6 +5,7 @@ import { isRecord, readJson } from '../storage/json-store.js';
5
5
  import { withLock } from '../storage/lock.js';
6
6
  import { contextMetadataPath, deadendsPath, knowledgePath, locksDirectory, snapshotPath } from '../storage/layout.js';
7
7
  import { rebuildSnapshot } from './runtime.js';
8
+ import { mirrorDeadend, mirrorKnowledge } from '../cognition/v1-bridge.js';
8
9
  function id(prefix) {
9
10
  return `${prefix}-${Date.now().toString(36)}-${crypto.randomBytes(4).toString('hex')}`;
10
11
  }
@@ -34,6 +35,23 @@ function isKnowledgeFile(value) {
34
35
  function cleanList(values) {
35
36
  return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
36
37
  }
38
+ function cleanApplicability(input) {
39
+ if (!input)
40
+ return { project: true, branchMode: 'global' };
41
+ if (input.project !== true || !['global', 'exact'].includes(input.branchMode))
42
+ throw new Error('invalid record applicability');
43
+ const branches = cleanList(input.branches);
44
+ const paths = cleanList(input.paths);
45
+ if (input.branchMode === 'exact' && branches.length === 0)
46
+ throw new Error('exact applicability requires a branch');
47
+ return {
48
+ project: true,
49
+ branchMode: input.branchMode,
50
+ ...(branches.length > 0 ? { branches } : {}),
51
+ ...(paths.length > 0 ? { paths } : {}),
52
+ ...(input.sourceCommit === undefined ? {} : { sourceCommit: input.sourceCommit }),
53
+ };
54
+ }
37
55
  function normalized(value) {
38
56
  return value.trim().toLocaleLowerCase();
39
57
  }
@@ -115,10 +133,12 @@ export async function learnKnowledge(startPath, statement, scopeOrInput = 'proje
115
133
  sourceContextIds: cleanList(input.sourceContextId ? [input.sourceContextId] : []),
116
134
  sourceSnapshotIds: cleanList(input.sourceSnapshotId ? [input.sourceSnapshotId] : []),
117
135
  supportingEvidence: cleanList(input.evidence),
136
+ applicability: cleanApplicability(input.applicability),
118
137
  createdAt: now,
119
138
  updatedAt: now,
120
139
  };
121
140
  await atomicWriteJson(knowledgePath(projectRoot), { schemaVersion: 1, items: [...file.items, item] });
141
+ await mirrorKnowledge(projectRoot, item);
122
142
  return item;
123
143
  });
124
144
  }
@@ -206,10 +226,33 @@ export async function verifyKnowledge(startPath, knowledgeId) {
206
226
  const item = file.items.find((candidate) => candidate.knowledgeId === knowledgeId);
207
227
  if (!item)
208
228
  throw new Error(`knowledge not found: ${knowledgeId}`);
229
+ if (item.status !== 'candidate')
230
+ throw new Error(`knowledge must be a candidate to verify: ${knowledgeId}`);
209
231
  item.status = 'verified';
210
232
  item.confidence = Math.max(item.confidence, 0.8);
211
233
  item.updatedAt = new Date().toISOString();
212
234
  await atomicWriteJson(knowledgePath(projectRoot), file);
235
+ await mirrorKnowledge(projectRoot, item);
236
+ return item;
237
+ });
238
+ }
239
+ export async function transitionKnowledge(startPath, knowledgeId, status, reason) {
240
+ const projectRoot = await resolveProjectRoot(startPath);
241
+ if (!reason.trim())
242
+ throw new Error('knowledge transition reason must not be empty');
243
+ return withLock(`${locksDirectory(projectRoot)}/knowledge.lock`, async () => {
244
+ const file = await loadKnowledge(projectRoot);
245
+ const item = file.items.find((candidate) => candidate.knowledgeId === knowledgeId);
246
+ if (!item)
247
+ throw new Error(`knowledge not found: ${knowledgeId}`);
248
+ if ((status === 'deprecated' && item.status !== 'verified') || (status === 'rejected' && item.status !== 'candidate')) {
249
+ throw new Error(`invalid knowledge transition: ${item.status} to ${status}`);
250
+ }
251
+ item.status = status;
252
+ item.updatedAt = new Date().toISOString();
253
+ item.governance = { reason: reason.trim(), transitionedAt: item.updatedAt };
254
+ await atomicWriteJson(knowledgePath(projectRoot), file);
255
+ await mirrorKnowledge(projectRoot, item);
213
256
  return item;
214
257
  });
215
258
  }
@@ -229,10 +272,12 @@ export async function recordDeadend(startPath, attempt, reason, scopeOrInput = '
229
272
  status: 'candidate',
230
273
  sourceContextId: input.sourceContextId ?? null,
231
274
  sourceSnapshotId: input.sourceSnapshotId ?? null,
275
+ applicability: cleanApplicability(input.applicability),
232
276
  createdAt: now,
233
277
  updatedAt: now,
234
278
  };
235
279
  await atomicWriteJson(deadendsPath(projectRoot), { schemaVersion: 1, items: [...file.items, item] });
280
+ await mirrorDeadend(projectRoot, item);
236
281
  return item;
237
282
  });
238
283
  }
@@ -284,6 +329,26 @@ export async function discoverDeadends(startPath, query, options = {}) {
284
329
  hits: selected.map((item) => ({ ...item, deadend: limitedDeadend(item.deadend, maxChars) })),
285
330
  };
286
331
  }
332
+ export async function transitionDeadend(startPath, deadendId, status, reason) {
333
+ const projectRoot = await resolveProjectRoot(startPath);
334
+ if (!reason.trim())
335
+ throw new Error('deadend transition reason must not be empty');
336
+ return withLock(`${locksDirectory(projectRoot)}/deadends.lock`, async () => {
337
+ const file = await loadDeadends(projectRoot);
338
+ const item = file.items.find((candidate) => candidate.deadendId === deadendId);
339
+ if (!item)
340
+ throw new Error(`deadend not found: ${deadendId}`);
341
+ if ((status === 'obsolete' && item.status !== 'verified') || (status === 'rejected' && item.status !== 'candidate')) {
342
+ throw new Error(`invalid deadend transition: ${item.status} to ${status}`);
343
+ }
344
+ item.status = status;
345
+ item.updatedAt = new Date().toISOString();
346
+ item.governance = { reason: reason.trim(), transitionedAt: item.updatedAt };
347
+ await atomicWriteJson(deadendsPath(projectRoot), file);
348
+ await mirrorDeadend(projectRoot, item);
349
+ return item;
350
+ });
351
+ }
287
352
  export async function verifyDeadend(startPath, deadendId) {
288
353
  const projectRoot = await resolveProjectRoot(startPath);
289
354
  return withLock(`${locksDirectory(projectRoot)}/deadends.lock`, async () => {
@@ -291,9 +356,12 @@ export async function verifyDeadend(startPath, deadendId) {
291
356
  const item = file.items.find((candidate) => candidate.deadendId === deadendId);
292
357
  if (!item)
293
358
  throw new Error(`deadend not found: ${deadendId}`);
359
+ if (item.status !== 'candidate')
360
+ throw new Error(`deadend must be a candidate to verify: ${deadendId}`);
294
361
  item.status = 'verified';
295
362
  item.updatedAt = new Date().toISOString();
296
363
  await atomicWriteJson(deadendsPath(projectRoot), file);
364
+ await mirrorDeadend(projectRoot, item);
297
365
  return item;
298
366
  });
299
367
  }
@@ -6,6 +6,7 @@ import { atomicWriteJson } from '../storage/atomic-write.js';
6
6
  import { isRecord, readJson } from '../storage/json-store.js';
7
7
  import { contextMetadataPath, contextsRoot, locksDirectory, notesPath, snapshotPath, snapshotsDirectory } from '../storage/layout.js';
8
8
  import { withLock } from '../storage/lock.js';
9
+ import { mirrorNote } from '../cognition/v1-bridge.js';
9
10
  function id() {
10
11
  return `note-${Date.now().toString(36)}-${crypto.randomBytes(4).toString('hex')}`;
11
12
  }
@@ -78,6 +79,7 @@ export async function addNote(startPath, message, input = {}) {
78
79
  updatedAt: now,
79
80
  };
80
81
  await atomicWriteJson(notesPath(projectRoot), { schemaVersion: 1, items: [...file.items, note] });
82
+ await mirrorNote(projectRoot, note);
81
83
  return note;
82
84
  });
83
85
  }
@@ -163,8 +165,13 @@ export async function absorbNotes(startPath, contextId, snapshotId) {
163
165
  absorbed += 1;
164
166
  return { ...note, absorbedBySnapshotId: snapshotId, updatedAt: new Date().toISOString() };
165
167
  });
166
- if (absorbed > 0)
168
+ if (absorbed > 0) {
167
169
  await atomicWriteJson(notesPath(projectRoot), { schemaVersion: 1, items });
170
+ for (const note of items) {
171
+ if (note.contextId === contextId && note.absorbedBySnapshotId === snapshotId)
172
+ await mirrorNote(projectRoot, note, true);
173
+ }
174
+ }
168
175
  return absorbed;
169
176
  });
170
177
  }
@@ -8,4 +8,5 @@ export declare function checkpoint(startPath: string | undefined, input: Checkpo
8
8
  export interface ResumeOptions {
9
9
  touchLastUsedAt?: boolean;
10
10
  }
11
+ export declare function resumeSnapshot(startPath: string | undefined, contextId: string, snapshotId: string, maxChars?: number): Promise<ResumeResult>;
11
12
  export declare function resume(startPath?: string, contextId?: string, maxChars?: number, options?: ResumeOptions): Promise<ResumeResult>;
@@ -9,6 +9,7 @@ import { contextDirectory, contextMetadataPath, contextsRoot, indexPath, locksDi
9
9
  import { loadManifest } from './init.js';
10
10
  import { filterPaths } from '../capture/context-filter.js';
11
11
  import { absorbNotes } from './notes.js';
12
+ import { mirrorCheckpoint } from '../cognition/v1-bridge.js';
12
13
  const emptyContext = () => ({
13
14
  progressSummary: '',
14
15
  lastError: null,
@@ -307,9 +308,36 @@ export async function checkpoint(startPath, input, options = {}) {
307
308
  });
308
309
  if (input.absorbNotes)
309
310
  await absorbNotes(projectRoot, contextId, snapshotId);
311
+ await mirrorCheckpoint(projectRoot, updatedContext, snapshot);
310
312
  return { status: 'saved', context: updatedContext, snapshot };
311
313
  });
312
314
  }
315
+ export async function resumeSnapshot(startPath, contextId, snapshotId, maxChars = 4000) {
316
+ const projectRoot = await resolveProjectRoot(startPath);
317
+ await loadManifest(projectRoot);
318
+ const [git, context, snapshot] = await Promise.all([
319
+ readGitState(projectRoot),
320
+ loadContext(projectRoot, contextId),
321
+ loadSnapshot(projectRoot, contextId, snapshotId),
322
+ ]);
323
+ const details = await rebuildSnapshot(projectRoot, contextId, snapshotId);
324
+ const budget = { remaining: Math.max(0, maxChars) };
325
+ return {
326
+ context,
327
+ snapshot,
328
+ details,
329
+ resumeSummary: {
330
+ progressSummary: limited(details.progressSummary, budget.remaining),
331
+ lastError: details.lastError === null ? null : limited(details.lastError, budget.remaining),
332
+ completed: limitedList(details.completed, budget),
333
+ pendingTasks: limitedList(details.pendingTasks, budget),
334
+ decisions: limitedList(details.decisions, budget),
335
+ risks: limitedList(details.risks, budget),
336
+ relatedFiles: limitedList(details.relatedFiles, budget),
337
+ branchOrCommitDrift: context.branch !== git.branch || context.commit !== git.commit,
338
+ },
339
+ };
340
+ }
313
341
  export async function resume(startPath, contextId, maxChars = 4000, options = {}) {
314
342
  const projectRoot = await resolveProjectRoot(startPath);
315
343
  await loadManifest(projectRoot);
@@ -136,6 +136,13 @@ export interface ActivityResult {
136
136
  }
137
137
  export type KnowledgeStatus = 'candidate' | 'verified' | 'deprecated' | 'rejected';
138
138
  export type DeadendStatus = 'candidate' | 'verified' | 'obsolete' | 'rejected';
139
+ export interface RecordApplicability {
140
+ project: true;
141
+ branches?: string[];
142
+ branchMode: 'global' | 'exact';
143
+ paths?: string[];
144
+ sourceCommit?: string | null;
145
+ }
139
146
  export interface Knowledge {
140
147
  knowledgeId: string;
141
148
  kind: string;
@@ -146,6 +153,11 @@ export interface Knowledge {
146
153
  sourceContextIds: string[];
147
154
  sourceSnapshotIds: string[];
148
155
  supportingEvidence: string[];
156
+ applicability?: RecordApplicability;
157
+ governance?: {
158
+ reason: string;
159
+ transitionedAt: string;
160
+ };
149
161
  createdAt: string;
150
162
  updatedAt: string;
151
163
  }
@@ -155,6 +167,7 @@ export interface KnowledgeInput {
155
167
  sourceContextId?: string;
156
168
  sourceSnapshotId?: string;
157
169
  evidence?: string[];
170
+ applicability?: RecordApplicability;
158
171
  }
159
172
  export interface KnowledgeDiscoverOptions {
160
173
  scope?: string;
@@ -205,6 +218,7 @@ export interface DeadendInput {
205
218
  sourceContextId?: string;
206
219
  sourceSnapshotId?: string;
207
220
  evidence?: string[];
221
+ applicability?: RecordApplicability;
208
222
  }
209
223
  export interface Deadend {
210
224
  deadendId: string;
@@ -215,6 +229,11 @@ export interface Deadend {
215
229
  status: DeadendStatus;
216
230
  sourceContextId: string | null;
217
231
  sourceSnapshotId: string | null;
232
+ applicability?: RecordApplicability;
233
+ governance?: {
234
+ reason: string;
235
+ transitionedAt: string;
236
+ };
218
237
  createdAt: string;
219
238
  updatedAt: string;
220
239
  }
@@ -11,3 +11,22 @@ export declare function locksDirectory(projectRoot: string): string;
11
11
  export declare function knowledgePath(projectRoot: string): string;
12
12
  export declare function deadendsPath(projectRoot: string): string;
13
13
  export declare function notesPath(projectRoot: string): string;
14
+ export declare function cognitionRoot(projectRoot: string): string;
15
+ export declare function cognitionManifestPath(projectRoot: string): string;
16
+ export declare function cognitionPolicyPath(projectRoot: string): string;
17
+ export declare function cognitionJournalDirectory(projectRoot: string): string;
18
+ export declare function cognitionProjectionsDirectory(projectRoot: string): string;
19
+ export declare function cognitionProjectionCursorPath(projectRoot: string): string;
20
+ export declare function cognitionBranchesDirectory(projectRoot: string): string;
21
+ export declare function cognitionContextsProjectionPath(projectRoot: string): string;
22
+ export declare function cognitionKnowledgeProjectionPath(projectRoot: string): string;
23
+ export declare function cognitionDeadendsProjectionPath(projectRoot: string): string;
24
+ export declare function cognitionNotesProjectionPath(projectRoot: string): string;
25
+ export declare function cognitionRetrievalProjectionPath(projectRoot: string): string;
26
+ export declare function cognitionMigrationsDirectory(projectRoot: string): string;
27
+ export declare function cognitionV1ImportPath(projectRoot: string): string;
28
+ export declare function cognitionRuntimeDirectory(projectRoot: string): string;
29
+ export declare function cognitionRuntimeLeasePath(projectRoot: string): string;
30
+ export declare function cognitionRuntimeSecretPath(projectRoot: string): string;
31
+ export declare function cognitionV1SyncPath(projectRoot: string): string;
32
+ export declare function cognitionQuarantineDirectory(projectRoot: string): string;
@@ -38,3 +38,60 @@ export function deadendsPath(projectRoot) {
38
38
  export function notesPath(projectRoot) {
39
39
  return path.join(contextRoot(projectRoot), 'notes.json');
40
40
  }
41
+ export function cognitionRoot(projectRoot) {
42
+ return path.join(contextRoot(projectRoot), 'v2');
43
+ }
44
+ export function cognitionManifestPath(projectRoot) {
45
+ return path.join(cognitionRoot(projectRoot), 'manifest.json');
46
+ }
47
+ export function cognitionPolicyPath(projectRoot) {
48
+ return path.join(cognitionRoot(projectRoot), 'policy.json');
49
+ }
50
+ export function cognitionJournalDirectory(projectRoot) {
51
+ return path.join(cognitionRoot(projectRoot), 'journal');
52
+ }
53
+ export function cognitionProjectionsDirectory(projectRoot) {
54
+ return path.join(cognitionRoot(projectRoot), 'projections');
55
+ }
56
+ export function cognitionProjectionCursorPath(projectRoot) {
57
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'cursor.json');
58
+ }
59
+ export function cognitionBranchesDirectory(projectRoot) {
60
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'branches');
61
+ }
62
+ export function cognitionContextsProjectionPath(projectRoot) {
63
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'contexts.json');
64
+ }
65
+ export function cognitionKnowledgeProjectionPath(projectRoot) {
66
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'knowledge.json');
67
+ }
68
+ export function cognitionDeadendsProjectionPath(projectRoot) {
69
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'deadends.json');
70
+ }
71
+ export function cognitionNotesProjectionPath(projectRoot) {
72
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'notes.json');
73
+ }
74
+ export function cognitionRetrievalProjectionPath(projectRoot) {
75
+ return path.join(cognitionProjectionsDirectory(projectRoot), 'retrieval.json');
76
+ }
77
+ export function cognitionMigrationsDirectory(projectRoot) {
78
+ return path.join(cognitionRoot(projectRoot), 'migrations');
79
+ }
80
+ export function cognitionV1ImportPath(projectRoot) {
81
+ return path.join(cognitionMigrationsDirectory(projectRoot), 'v1-import.json');
82
+ }
83
+ export function cognitionRuntimeDirectory(projectRoot) {
84
+ return path.join(cognitionRoot(projectRoot), 'runtime');
85
+ }
86
+ export function cognitionRuntimeLeasePath(projectRoot) {
87
+ return path.join(cognitionRuntimeDirectory(projectRoot), 'lease.json');
88
+ }
89
+ export function cognitionRuntimeSecretPath(projectRoot) {
90
+ return path.join(cognitionRuntimeDirectory(projectRoot), 'secret');
91
+ }
92
+ export function cognitionV1SyncPath(projectRoot) {
93
+ return path.join(cognitionRuntimeDirectory(projectRoot), 'v1-sync.json');
94
+ }
95
+ export function cognitionQuarantineDirectory(projectRoot) {
96
+ return path.join(cognitionRoot(projectRoot), 'quarantine');
97
+ }
@@ -1 +1 @@
1
- export declare const VERSION = "0.3.1";
1
+ export declare const VERSION = "0.6.0";
@@ -1 +1 @@
1
- export const VERSION = '0.3.1';
1
+ export const VERSION = '0.6.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluffy-context",
3
- "version": "0.3.1",
3
+ "version": "0.6.0",
4
4
  "description": "Local context management CLI and MCP tools for AI coding agents",
5
5
  "license": "MIT",
6
6
  "author": "FluffyChi-Xing",
@@ -55,7 +55,7 @@
55
55
  "scripts": {
56
56
  "build": "tsc -p tsconfig.json",
57
57
  "typecheck": "tsc -p tsconfig.test.json --noEmit",
58
- "test": "tsc -p tsconfig.test.json && node --test dist/test/*.test.js",
58
+ "test": "tsc -p tsconfig.test.json && node --test --test-concurrency=1 dist/test/*.test.js",
59
59
  "pack:check": "tsc -p tsconfig.test.json && node --test dist/test/package-smoke.test.js",
60
60
  "prepack": "npm run build",
61
61
  "prepublishOnly": "npm test && npm run pack:check",