@tricknowtech/context 0.1.1 → 0.3.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/dist/index.d.cts CHANGED
@@ -1,3 +1,34 @@
1
+ /**
2
+ * Per-assistant knowledge of where context lives.
3
+ *
4
+ * Every coding assistant keeps two kinds of state: instruction files inside
5
+ * the repo (which git may or may not already carry), and user-global config
6
+ * in the home directory (which never travels). The adapter's job is to name
7
+ * both, so the collector stays assistant-agnostic.
8
+ *
9
+ * Adding support for a new tool means adding one entry here — nothing in the
10
+ * collector, store, or CLI needs to change.
11
+ */
12
+ interface UserFile {
13
+ /** Absolute path on this machine. */
14
+ abs: string;
15
+ /** Path within the assistant's namespace in the store, e.g. `memory/note.md`. */
16
+ rel: string;
17
+ }
18
+ interface AssistantAdapter {
19
+ id: string;
20
+ name: string;
21
+ /**
22
+ * Project-relative globs this assistant owns. Files matching these are
23
+ * collected unless git already tracks them.
24
+ */
25
+ projectGlobs: string[];
26
+ /** Home-relative directory used to detect whether the tool is installed. */
27
+ userDir?: (home: string) => string;
28
+ /** User-global files worth carrying, resolved per project. */
29
+ collectUser?: (projectRoot: string, home: string, exclude: string[]) => UserFile[];
30
+ }
31
+
1
32
  /** Root of the user's global Claude directory (~/.claude), overridable for tests. */
2
33
  declare function userClaudeDir(): string;
3
34
  /**
@@ -21,6 +52,8 @@ interface TemplateContext {
21
52
  userClaude: string;
22
53
  project: string;
23
54
  cwdKey: string;
55
+ /** The user's home directory — how non-Claude assistants (~/.codex, ~/.gemini) template. */
56
+ home: string;
24
57
  }
25
58
  declare function makeTemplate(absPath: string, ctx: TemplateContext): string;
26
59
  declare function resolveTemplate(template: string, ctx: TemplateContext): string;
@@ -101,6 +134,11 @@ interface ProjectConfig {
101
134
  */
102
135
  rootHint: string;
103
136
  tiers: Tier[];
137
+ /**
138
+ * Assistant ids to sync (`claude`, `codex`, `cursor`, …), or `['auto']` to
139
+ * detect from what is installed and what the repo already contains.
140
+ */
141
+ assistants: string[];
104
142
  /** Extra project-relative dirs to capture as `artifacts`. */
105
143
  artifactPaths: string[];
106
144
  /** Glob-ish patterns excluded from collection, on top of the hard-coded denylist. */
@@ -140,26 +178,65 @@ interface CollectResult {
140
178
  files: CollectedFile[];
141
179
  /** Project files skipped because git already carries them. */
142
180
  skippedTracked: string[];
181
+ /** Assistants this project was found to use. */
182
+ assistants: AssistantAdapter[];
143
183
  ctx: TemplateContext;
144
184
  }
145
185
  /**
146
- * Decide what constitutes this project's LLM context.
186
+ * Decide what constitutes this project's LLM context, across every assistant
187
+ * in use.
147
188
  *
148
- * Two roots are scanned, and they are treated very differently:
189
+ * Two roots are treated very differently:
149
190
  *
150
191
  * - **The project itself** — anything git already tracks is *skipped*. It
151
- * travels with the code, so copying it into the store would duplicate it
152
- * and create a second copy that silently drifts out of date.
153
- * - **The user's global Claude directory** — this is the real payload. The
154
- * per-project memory, skills, and global instructions live outside the
155
- * repo and are exactly what never makes it to a second machine today.
192
+ * travels with the code, so copying it in would create a second copy that
193
+ * silently drifts.
194
+ * - **The user's home directory** — this is the real payload. Per-project
195
+ * memory, skills, prompts and global instructions live outside the repo and
196
+ * are exactly what never reaches a second machine today.
156
197
  */
157
198
  declare function collect(projectRoot: string, cfg: ProjectConfig, tiers: Tier[]): CollectResult;
199
+ interface ExcludedGroup {
200
+ label: string;
201
+ files: number;
202
+ bytes: number;
203
+ reason: string;
204
+ }
205
+ /**
206
+ * What was deliberately left behind, and why.
207
+ *
208
+ * Without this a user sees "17 files synced" against a ~400 MB context
209
+ * directory and reasonably concludes the tool is broken. Naming the omissions
210
+ * — with sizes — is the difference between a considered exclusion and a
211
+ * silent one.
212
+ */
213
+ declare function describeExcluded(projectRoot: string, tiers: Tier[]): ExcludedGroup[];
158
214
  declare function summarize(files: CollectedFile[]): Record<Tier, {
159
215
  count: number;
160
216
  bytes: number;
161
217
  }>;
162
218
 
219
+ /**
220
+ * The handoff is the whole point of the tool — files alone tell you what a
221
+ * project knows, but not where you stopped. It is written by the model (only
222
+ * it has the conversation) and read back on the other machine.
223
+ *
224
+ * Because a model writes it, it needs real validation: a silently malformed
225
+ * handoff is worse than none, since `pull` would look like it worked while
226
+ * handing back nothing usable.
227
+ */
228
+ interface ValidationResult {
229
+ ok: boolean;
230
+ errors: string[];
231
+ handoff?: Handoff;
232
+ }
233
+ declare function validateHandoff(raw: unknown): ValidationResult;
234
+ /** Render a handoff for a human picking the work back up. */
235
+ declare function formatHandoff(h: Handoff): string[];
236
+ declare function handoffAge(h: Handoff): string;
237
+ /** True when the handoff predates the newest synced content by a wide margin. */
238
+ declare function isStale(h: Handoff, newestContentMs: number): boolean;
239
+
163
240
  declare const STORE_DIR = ".contextsync";
164
241
  declare const CONFIG_FILE = "config.json";
165
242
  declare const HANDOFF_FILE = "handoff.json";
@@ -266,4 +343,4 @@ declare class LocalStore implements Store {
266
343
  writeHandoff(handoff: Handoff): void;
267
344
  }
268
345
 
269
- export { ALL_TIERS, CONFIG_FILE, type CollectResult, type CollectedFile, DEFAULT_EXCLUDE, HANDOFF_FILE, HARD_DENY, type Handoff, LOCAL_TIERS, LocalStore, MANIFEST_FILE, type Manifest, type ManifestEntry, type ProjectConfig, type RemoteConfig, type RestoreResult, SLASH_COMMAND_BODY, SLASH_COMMAND_PATH, STORE_DIR, type SecretHit, type SourceRoot, type Store, type TemplateContext, type Tier, collect, configPath, cwdKey, defaultConfig, ensureGitignoreEntries, findProjectRoot, formatBytes, formatHits, gitTrackedSet, installSlashCommand, isGitRepo, loadConfig, makeTemplate, matchesAny, resolveTemplate, saveConfig, scanFiles, storeDir, summarize, userClaudeDir, walk };
346
+ export { ALL_TIERS, CONFIG_FILE, type CollectResult, type CollectedFile, DEFAULT_EXCLUDE, type ExcludedGroup, HANDOFF_FILE, HARD_DENY, type Handoff, LOCAL_TIERS, LocalStore, MANIFEST_FILE, type Manifest, type ManifestEntry, type ProjectConfig, type RemoteConfig, type RestoreResult, SLASH_COMMAND_BODY, SLASH_COMMAND_PATH, STORE_DIR, type SecretHit, type SourceRoot, type Store, type TemplateContext, type Tier, type ValidationResult, collect, configPath, cwdKey, defaultConfig, describeExcluded, ensureGitignoreEntries, findProjectRoot, formatBytes, formatHandoff, formatHits, gitTrackedSet, handoffAge, installSlashCommand, isGitRepo, isStale, loadConfig, makeTemplate, matchesAny, resolveTemplate, saveConfig, scanFiles, storeDir, summarize, userClaudeDir, validateHandoff, walk };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,34 @@
1
+ /**
2
+ * Per-assistant knowledge of where context lives.
3
+ *
4
+ * Every coding assistant keeps two kinds of state: instruction files inside
5
+ * the repo (which git may or may not already carry), and user-global config
6
+ * in the home directory (which never travels). The adapter's job is to name
7
+ * both, so the collector stays assistant-agnostic.
8
+ *
9
+ * Adding support for a new tool means adding one entry here — nothing in the
10
+ * collector, store, or CLI needs to change.
11
+ */
12
+ interface UserFile {
13
+ /** Absolute path on this machine. */
14
+ abs: string;
15
+ /** Path within the assistant's namespace in the store, e.g. `memory/note.md`. */
16
+ rel: string;
17
+ }
18
+ interface AssistantAdapter {
19
+ id: string;
20
+ name: string;
21
+ /**
22
+ * Project-relative globs this assistant owns. Files matching these are
23
+ * collected unless git already tracks them.
24
+ */
25
+ projectGlobs: string[];
26
+ /** Home-relative directory used to detect whether the tool is installed. */
27
+ userDir?: (home: string) => string;
28
+ /** User-global files worth carrying, resolved per project. */
29
+ collectUser?: (projectRoot: string, home: string, exclude: string[]) => UserFile[];
30
+ }
31
+
1
32
  /** Root of the user's global Claude directory (~/.claude), overridable for tests. */
2
33
  declare function userClaudeDir(): string;
3
34
  /**
@@ -21,6 +52,8 @@ interface TemplateContext {
21
52
  userClaude: string;
22
53
  project: string;
23
54
  cwdKey: string;
55
+ /** The user's home directory — how non-Claude assistants (~/.codex, ~/.gemini) template. */
56
+ home: string;
24
57
  }
25
58
  declare function makeTemplate(absPath: string, ctx: TemplateContext): string;
26
59
  declare function resolveTemplate(template: string, ctx: TemplateContext): string;
@@ -101,6 +134,11 @@ interface ProjectConfig {
101
134
  */
102
135
  rootHint: string;
103
136
  tiers: Tier[];
137
+ /**
138
+ * Assistant ids to sync (`claude`, `codex`, `cursor`, …), or `['auto']` to
139
+ * detect from what is installed and what the repo already contains.
140
+ */
141
+ assistants: string[];
104
142
  /** Extra project-relative dirs to capture as `artifacts`. */
105
143
  artifactPaths: string[];
106
144
  /** Glob-ish patterns excluded from collection, on top of the hard-coded denylist. */
@@ -140,26 +178,65 @@ interface CollectResult {
140
178
  files: CollectedFile[];
141
179
  /** Project files skipped because git already carries them. */
142
180
  skippedTracked: string[];
181
+ /** Assistants this project was found to use. */
182
+ assistants: AssistantAdapter[];
143
183
  ctx: TemplateContext;
144
184
  }
145
185
  /**
146
- * Decide what constitutes this project's LLM context.
186
+ * Decide what constitutes this project's LLM context, across every assistant
187
+ * in use.
147
188
  *
148
- * Two roots are scanned, and they are treated very differently:
189
+ * Two roots are treated very differently:
149
190
  *
150
191
  * - **The project itself** — anything git already tracks is *skipped*. It
151
- * travels with the code, so copying it into the store would duplicate it
152
- * and create a second copy that silently drifts out of date.
153
- * - **The user's global Claude directory** — this is the real payload. The
154
- * per-project memory, skills, and global instructions live outside the
155
- * repo and are exactly what never makes it to a second machine today.
192
+ * travels with the code, so copying it in would create a second copy that
193
+ * silently drifts.
194
+ * - **The user's home directory** — this is the real payload. Per-project
195
+ * memory, skills, prompts and global instructions live outside the repo and
196
+ * are exactly what never reaches a second machine today.
156
197
  */
157
198
  declare function collect(projectRoot: string, cfg: ProjectConfig, tiers: Tier[]): CollectResult;
199
+ interface ExcludedGroup {
200
+ label: string;
201
+ files: number;
202
+ bytes: number;
203
+ reason: string;
204
+ }
205
+ /**
206
+ * What was deliberately left behind, and why.
207
+ *
208
+ * Without this a user sees "17 files synced" against a ~400 MB context
209
+ * directory and reasonably concludes the tool is broken. Naming the omissions
210
+ * — with sizes — is the difference between a considered exclusion and a
211
+ * silent one.
212
+ */
213
+ declare function describeExcluded(projectRoot: string, tiers: Tier[]): ExcludedGroup[];
158
214
  declare function summarize(files: CollectedFile[]): Record<Tier, {
159
215
  count: number;
160
216
  bytes: number;
161
217
  }>;
162
218
 
219
+ /**
220
+ * The handoff is the whole point of the tool — files alone tell you what a
221
+ * project knows, but not where you stopped. It is written by the model (only
222
+ * it has the conversation) and read back on the other machine.
223
+ *
224
+ * Because a model writes it, it needs real validation: a silently malformed
225
+ * handoff is worse than none, since `pull` would look like it worked while
226
+ * handing back nothing usable.
227
+ */
228
+ interface ValidationResult {
229
+ ok: boolean;
230
+ errors: string[];
231
+ handoff?: Handoff;
232
+ }
233
+ declare function validateHandoff(raw: unknown): ValidationResult;
234
+ /** Render a handoff for a human picking the work back up. */
235
+ declare function formatHandoff(h: Handoff): string[];
236
+ declare function handoffAge(h: Handoff): string;
237
+ /** True when the handoff predates the newest synced content by a wide margin. */
238
+ declare function isStale(h: Handoff, newestContentMs: number): boolean;
239
+
163
240
  declare const STORE_DIR = ".contextsync";
164
241
  declare const CONFIG_FILE = "config.json";
165
242
  declare const HANDOFF_FILE = "handoff.json";
@@ -266,4 +343,4 @@ declare class LocalStore implements Store {
266
343
  writeHandoff(handoff: Handoff): void;
267
344
  }
268
345
 
269
- export { ALL_TIERS, CONFIG_FILE, type CollectResult, type CollectedFile, DEFAULT_EXCLUDE, HANDOFF_FILE, HARD_DENY, type Handoff, LOCAL_TIERS, LocalStore, MANIFEST_FILE, type Manifest, type ManifestEntry, type ProjectConfig, type RemoteConfig, type RestoreResult, SLASH_COMMAND_BODY, SLASH_COMMAND_PATH, STORE_DIR, type SecretHit, type SourceRoot, type Store, type TemplateContext, type Tier, collect, configPath, cwdKey, defaultConfig, ensureGitignoreEntries, findProjectRoot, formatBytes, formatHits, gitTrackedSet, installSlashCommand, isGitRepo, loadConfig, makeTemplate, matchesAny, resolveTemplate, saveConfig, scanFiles, storeDir, summarize, userClaudeDir, walk };
346
+ export { ALL_TIERS, CONFIG_FILE, type CollectResult, type CollectedFile, DEFAULT_EXCLUDE, type ExcludedGroup, HANDOFF_FILE, HARD_DENY, type Handoff, LOCAL_TIERS, LocalStore, MANIFEST_FILE, type Manifest, type ManifestEntry, type ProjectConfig, type RemoteConfig, type RestoreResult, SLASH_COMMAND_BODY, SLASH_COMMAND_PATH, STORE_DIR, type SecretHit, type SourceRoot, type Store, type TemplateContext, type Tier, type ValidationResult, collect, configPath, cwdKey, defaultConfig, describeExcluded, ensureGitignoreEntries, findProjectRoot, formatBytes, formatHandoff, formatHits, gitTrackedSet, handoffAge, installSlashCommand, isGitRepo, isStale, loadConfig, makeTemplate, matchesAny, resolveTemplate, saveConfig, scanFiles, storeDir, summarize, userClaudeDir, validateHandoff, walk };
package/dist/index.js CHANGED
@@ -14,13 +14,17 @@ import {
14
14
  configPath,
15
15
  cwdKey,
16
16
  defaultConfig,
17
+ describeExcluded,
17
18
  ensureGitignoreEntries,
18
19
  findProjectRoot,
19
20
  formatBytes,
21
+ formatHandoff,
20
22
  formatHits,
21
23
  gitTrackedSet,
24
+ handoffAge,
22
25
  installSlashCommand,
23
26
  isGitRepo,
27
+ isStale,
24
28
  loadConfig,
25
29
  makeTemplate,
26
30
  matchesAny,
@@ -30,8 +34,9 @@ import {
30
34
  storeDir,
31
35
  summarize,
32
36
  userClaudeDir,
37
+ validateHandoff,
33
38
  walk
34
- } from "./chunk-BWATZKYM.js";
39
+ } from "./chunk-BLEGQVXA.js";
35
40
  export {
36
41
  ALL_TIERS,
37
42
  CONFIG_FILE,
@@ -48,13 +53,17 @@ export {
48
53
  configPath,
49
54
  cwdKey,
50
55
  defaultConfig,
56
+ describeExcluded,
51
57
  ensureGitignoreEntries,
52
58
  findProjectRoot,
53
59
  formatBytes,
60
+ formatHandoff,
54
61
  formatHits,
55
62
  gitTrackedSet,
63
+ handoffAge,
56
64
  installSlashCommand,
57
65
  isGitRepo,
66
+ isStale,
58
67
  loadConfig,
59
68
  makeTemplate,
60
69
  matchesAny,
@@ -64,5 +73,6 @@ export {
64
73
  storeDir,
65
74
  summarize,
66
75
  userClaudeDir,
76
+ validateHandoff,
67
77
  walk
68
78
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tricknowtech/context",
3
- "version": "0.1.1",
4
- "description": "Carry a project's LLM context memory, skills, instructions and session handoff between machines. Local-first, commit it to your repo.",
3
+ "version": "0.3.0",
4
+ "description": "Carry a project's LLM context between machines \u2014 Claude Code, Codex, Cursor, Copilot, Gemini, Windsurf, Cline, Aider. Local-first, commit it to your repo.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -32,9 +32,17 @@
32
32
  "llm",
33
33
  "context",
34
34
  "claude",
35
+ "codex",
36
+ "cursor",
37
+ "copilot",
38
+ "gemini",
39
+ "windsurf",
40
+ "aider",
41
+ "cline",
35
42
  "ai",
36
43
  "sync",
37
- "memory"
44
+ "memory",
45
+ "agents-md"
38
46
  ],
39
47
  "author": "Tricknowtech",
40
48
  "license": "ISC",