@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/README.md +52 -3
- package/dist/{chunk-BWATZKYM.js → chunk-BLEGQVXA.js} +312 -102
- package/dist/cli.cjs +513 -160
- package/dist/cli.js +174 -17
- package/dist/index.cjs +384 -133
- package/dist/index.d.cts +85 -8
- package/dist/index.d.ts +85 -8
- package/dist/index.js +11 -1
- package/package.json +11 -3
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
|
|
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
|
|
152
|
-
*
|
|
153
|
-
* - **The user's
|
|
154
|
-
*
|
|
155
|
-
*
|
|
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
|
|
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
|
|
152
|
-
*
|
|
153
|
-
* - **The user's
|
|
154
|
-
*
|
|
155
|
-
*
|
|
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-
|
|
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.
|
|
4
|
-
"description": "Carry a project's LLM context
|
|
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",
|