opencode-graphiti 0.1.2 → 0.1.4
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/esm/src/handlers/chat.d.ts +6 -11
- package/esm/src/handlers/chat.d.ts.map +1 -1
- package/esm/src/handlers/chat.js +28 -22
- package/esm/src/handlers/compacting.d.ts +6 -5
- package/esm/src/handlers/compacting.d.ts.map +1 -1
- package/esm/src/handlers/event.d.ts +5 -4
- package/esm/src/handlers/event.d.ts.map +1 -1
- package/esm/src/index.d.ts.map +1 -1
- package/esm/src/index.js +1 -1
- package/esm/src/services/client.js +2 -2
- package/esm/src/services/compaction.d.ts.map +1 -1
- package/esm/src/services/compaction.js +25 -11
- package/esm/src/services/context.d.ts.map +1 -1
- package/esm/src/services/context.js +12 -14
- package/esm/src/utils.d.ts +2 -2
- package/esm/src/utils.d.ts.map +1 -1
- package/esm/src/utils.js +10 -9
- package/package.json +1 -1
- package/script/src/handlers/chat.d.ts +6 -11
- package/script/src/handlers/chat.d.ts.map +1 -1
- package/script/src/handlers/chat.js +28 -22
- package/script/src/handlers/compacting.d.ts +6 -5
- package/script/src/handlers/compacting.d.ts.map +1 -1
- package/script/src/handlers/event.d.ts +5 -4
- package/script/src/handlers/event.d.ts.map +1 -1
- package/script/src/index.d.ts.map +1 -1
- package/script/src/index.js +1 -1
- package/script/src/services/client.js +2 -2
- package/script/src/services/compaction.d.ts.map +1 -1
- package/script/src/services/compaction.js +25 -11
- package/script/src/services/context.d.ts.map +1 -1
- package/script/src/services/context.js +12 -14
- package/script/src/utils.d.ts +2 -2
- package/script/src/utils.d.ts.map +1 -1
- package/script/src/utils.js +10 -9
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type ChatMessageHook = NonNullable<Hooks["chat.message"]>;
|
|
5
|
+
type ChatMessageInput = Parameters<ChatMessageHook>[0];
|
|
6
|
+
type ChatMessageOutput = Parameters<ChatMessageHook>[1];
|
|
4
7
|
/** Dependencies for the chat message handler. */
|
|
5
8
|
export interface ChatHandlerDeps {
|
|
6
9
|
sessionManager: SessionManager;
|
|
@@ -8,14 +11,6 @@ export interface ChatHandlerDeps {
|
|
|
8
11
|
client: GraphitiClient;
|
|
9
12
|
}
|
|
10
13
|
/** Creates the `chat.message` hook handler. */
|
|
11
|
-
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }:
|
|
12
|
-
|
|
13
|
-
}, output: {
|
|
14
|
-
allow_buffering?: boolean;
|
|
15
|
-
parts: Part[];
|
|
16
|
-
message: {
|
|
17
|
-
sessionID: string;
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }: ChatMessageInput, output: ChatMessageOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
21
16
|
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAyGvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBAuDzE"}
|
package/esm/src/handlers/chat.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import { formatMemoryContext } from "../services/context.js";
|
|
2
1
|
import { calculateInjectionBudget } from "../services/context-limit.js";
|
|
2
|
+
import { formatMemoryContext } from "../services/context.js";
|
|
3
3
|
import { logger } from "../services/logger.js";
|
|
4
4
|
import { extractTextFromParts } from "../utils.js";
|
|
5
5
|
/** Creates the `chat.message` hook handler. */
|
|
6
6
|
export function createChatHandler(deps) {
|
|
7
7
|
const { sessionManager, injectionInterval, client } = deps;
|
|
8
8
|
const removeSyntheticMemoryParts = (parts) => parts.filter((part) => {
|
|
9
|
-
|
|
10
|
-
const id = typeof part.id === "string"
|
|
11
|
-
? String(part.id)
|
|
12
|
-
: "";
|
|
13
|
-
if (!synthetic)
|
|
9
|
+
if (part.type !== "text")
|
|
14
10
|
return true;
|
|
15
|
-
if (id
|
|
11
|
+
if (part.id?.startsWith("graphiti-memory-"))
|
|
16
12
|
return false;
|
|
17
|
-
if (id
|
|
13
|
+
if (part.id?.startsWith("graphiti-refresh-"))
|
|
18
14
|
return false;
|
|
19
15
|
return true;
|
|
20
16
|
});
|
|
21
|
-
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget) => {
|
|
17
|
+
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject) => {
|
|
22
18
|
const userGroupId = state.userGroupId;
|
|
23
19
|
const projectFactsPromise = client.searchFacts({
|
|
24
20
|
query: messageText,
|
|
@@ -67,14 +63,28 @@ export function createChatHandler(deps) {
|
|
|
67
63
|
.slice(0, characterBudget);
|
|
68
64
|
if (!memoryContext)
|
|
69
65
|
return;
|
|
70
|
-
output.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
if ("system" in output.message) {
|
|
67
|
+
try {
|
|
68
|
+
output.message.system = memoryContext;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
catch (_err) {
|
|
72
|
+
// Fall through to synthetic injection.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (shouldReinject) {
|
|
76
|
+
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
77
|
+
}
|
|
78
|
+
{
|
|
79
|
+
output.parts.unshift({
|
|
80
|
+
type: "text",
|
|
81
|
+
text: memoryContext,
|
|
82
|
+
id: `${prefix}${Date.now()}`,
|
|
83
|
+
sessionID: output.message.sessionID,
|
|
84
|
+
messageID: output.message.id,
|
|
85
|
+
synthetic: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
78
88
|
logger.info(`Injected ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes`);
|
|
79
89
|
};
|
|
80
90
|
return async ({ sessionID }, output) => {
|
|
@@ -84,7 +94,6 @@ export function createChatHandler(deps) {
|
|
|
84
94
|
}
|
|
85
95
|
const { state, resolved } = await sessionManager.resolveSessionState(sessionID);
|
|
86
96
|
if (!resolved) {
|
|
87
|
-
output.allow_buffering = true;
|
|
88
97
|
logger.debug("Unable to resolve session for message:", { sessionID });
|
|
89
98
|
return;
|
|
90
99
|
}
|
|
@@ -109,14 +118,11 @@ export function createChatHandler(deps) {
|
|
|
109
118
|
injectionInterval;
|
|
110
119
|
if (!shouldInjectOnFirst && !shouldReinject)
|
|
111
120
|
return;
|
|
112
|
-
if (shouldReinject) {
|
|
113
|
-
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
114
|
-
}
|
|
115
121
|
try {
|
|
116
122
|
const prefix = shouldReinject ? "graphiti-refresh-" : "graphiti-memory-";
|
|
117
123
|
const useUserScope = shouldInjectOnFirst;
|
|
118
124
|
const characterBudget = calculateInjectionBudget(state.contextLimit);
|
|
119
|
-
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget);
|
|
125
|
+
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject);
|
|
120
126
|
state.injectedMemories = true;
|
|
121
127
|
state.lastInjectionMessageCount = state.messageCount;
|
|
122
128
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
1
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
2
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type CompactingHook = NonNullable<Hooks["experimental.session.compacting"]>;
|
|
5
|
+
type CompactingInput = Parameters<CompactingHook>[0];
|
|
6
|
+
type CompactingOutput = Parameters<CompactingHook>[1];
|
|
3
7
|
/** Dependencies for the compacting handler. */
|
|
4
8
|
export interface CompactingHandlerDeps {
|
|
5
9
|
sessionManager: SessionManager;
|
|
@@ -7,9 +11,6 @@ export interface CompactingHandlerDeps {
|
|
|
7
11
|
defaultGroupId: string;
|
|
8
12
|
}
|
|
9
13
|
/** Creates the `experimental.session.compacting` hook handler. */
|
|
10
|
-
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }:
|
|
11
|
-
|
|
12
|
-
}, output: {
|
|
13
|
-
context: string[];
|
|
14
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }: CompactingInput, output: CompactingOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
15
16
|
//# sourceMappingURL=compacting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe
|
|
1
|
+
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAC5E,KAAK,eAAe,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe,eAAe,EAC9B,QAAQ,gBAAgB,mBAyB3B"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { ProviderListClient } from "../services/context-limit.js";
|
|
4
4
|
import type { SessionManager } from "../session.js";
|
|
5
|
+
type EventHook = NonNullable<Hooks["event"]>;
|
|
6
|
+
type EventInput = Parameters<EventHook>[0];
|
|
5
7
|
/** Dependencies for the event handler. */
|
|
6
8
|
export interface EventHandlerDeps {
|
|
7
9
|
sessionManager: SessionManager;
|
|
@@ -12,7 +14,6 @@ export interface EventHandlerDeps {
|
|
|
12
14
|
groupIdPrefix: string;
|
|
13
15
|
}
|
|
14
16
|
/** Creates the `event` hook handler. */
|
|
15
|
-
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }:
|
|
16
|
-
|
|
17
|
-
}) => Promise<void>;
|
|
17
|
+
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }: EventInput) => Promise<void>;
|
|
18
|
+
export {};
|
|
18
19
|
//# sourceMappingURL=event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAWzC,WAAW,UAAU,mBA+JpC"}
|
package/esm/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAW/D;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAW/D;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAkDtB,CAAC"}
|
package/esm/src/index.js
CHANGED
|
@@ -19,7 +19,7 @@ export const graphiti = async (input) => {
|
|
|
19
19
|
logger.warn("Memory features will be unavailable until connection is established");
|
|
20
20
|
}
|
|
21
21
|
const defaultGroupId = makeGroupId(config.groupIdPrefix, input.directory);
|
|
22
|
-
const defaultUserGroupId = makeUserGroupId(config.groupIdPrefix);
|
|
22
|
+
const defaultUserGroupId = makeUserGroupId(config.groupIdPrefix, input.directory);
|
|
23
23
|
logger.info("Plugin initialized. Group ID:", defaultGroupId);
|
|
24
24
|
const sessionManager = new SessionManager(defaultGroupId, defaultUserGroupId, sdkClient, client);
|
|
25
25
|
return {
|
|
@@ -35,12 +35,12 @@ export class GraphitiClient {
|
|
|
35
35
|
value: void 0
|
|
36
36
|
});
|
|
37
37
|
this.endpoint = endpoint;
|
|
38
|
-
this.client = new Client({ name: "opencode-graphiti", version: "0.1.
|
|
38
|
+
this.client = new Client({ name: "opencode-graphiti", version: "0.1.4" });
|
|
39
39
|
this.transport = new StreamableHTTPClientTransport(new URL(endpoint));
|
|
40
40
|
}
|
|
41
41
|
/** Create a fresh MCP Client and Transport pair. */
|
|
42
42
|
createClientAndTransport() {
|
|
43
|
-
this.client = new Client({ name: "opencode-graphiti", version: "0.1.
|
|
43
|
+
this.client = new Client({ name: "opencode-graphiti", version: "0.1.4" });
|
|
44
44
|
this.transport = new StreamableHTTPClientTransport(new URL(this.endpoint));
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgIpB"}
|
|
@@ -69,32 +69,40 @@ export async function getCompactionContext(params) {
|
|
|
69
69
|
const buildSection = (header, facts, nodes) => {
|
|
70
70
|
const lines = [];
|
|
71
71
|
lines.push(header);
|
|
72
|
+
lines.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
72
73
|
if (facts.length > 0) {
|
|
73
|
-
lines.push("
|
|
74
|
+
lines.push("<facts>");
|
|
74
75
|
lines.push(...formatFactLines(facts));
|
|
76
|
+
lines.push("</facts>");
|
|
75
77
|
}
|
|
76
78
|
if (nodes.length > 0) {
|
|
77
|
-
lines.push("
|
|
79
|
+
lines.push("<nodes>");
|
|
78
80
|
lines.push(...formatNodeLines(nodes));
|
|
81
|
+
lines.push("</nodes>");
|
|
79
82
|
}
|
|
80
83
|
return lines.join("\n");
|
|
81
84
|
};
|
|
82
|
-
const projectSection = buildSection(
|
|
83
|
-
const userSection = buildSection(
|
|
85
|
+
const projectSection = buildSection('<memory source="project">', projectFacts, projectNodes);
|
|
86
|
+
const userSection = buildSection('<memory source="user">', userFacts, userNodes);
|
|
84
87
|
const headerLines = [
|
|
85
|
-
"
|
|
88
|
+
"<summary>",
|
|
89
|
+
"<current_goal>",
|
|
86
90
|
"- ",
|
|
91
|
+
"</current_goal>",
|
|
87
92
|
"",
|
|
88
|
-
"
|
|
93
|
+
"<work_completed>",
|
|
89
94
|
"- ",
|
|
95
|
+
"</work_completed>",
|
|
90
96
|
"",
|
|
91
|
-
"
|
|
97
|
+
"<remaining_tasks>",
|
|
92
98
|
"- ",
|
|
99
|
+
"</remaining_tasks>",
|
|
93
100
|
"",
|
|
94
|
-
"
|
|
101
|
+
"<constraints_decisions>",
|
|
95
102
|
"- ",
|
|
103
|
+
"</constraints_decisions>",
|
|
96
104
|
"",
|
|
97
|
-
"
|
|
105
|
+
"<persistent_memory>",
|
|
98
106
|
];
|
|
99
107
|
const header = headerLines.join("\n");
|
|
100
108
|
const base = `${header}\n`;
|
|
@@ -104,10 +112,16 @@ export async function getCompactionContext(params) {
|
|
|
104
112
|
const truncatedProject = projectSection.slice(0, projectBudget);
|
|
105
113
|
const truncatedUser = userSection.slice(0, userBudget);
|
|
106
114
|
const sections = [header];
|
|
107
|
-
if (truncatedProject.trim())
|
|
115
|
+
if (truncatedProject.trim()) {
|
|
108
116
|
sections.push(truncatedProject);
|
|
109
|
-
|
|
117
|
+
sections.push("</memory>");
|
|
118
|
+
}
|
|
119
|
+
if (truncatedUser.trim()) {
|
|
110
120
|
sections.push(truncatedUser);
|
|
121
|
+
sections.push("</memory>");
|
|
122
|
+
}
|
|
123
|
+
sections.push("</persistent_memory>");
|
|
124
|
+
sections.push("</summary>");
|
|
111
125
|
const content = sections.join("\n").slice(0, characterBudget);
|
|
112
126
|
return [content];
|
|
113
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,CA0BR"}
|
|
@@ -5,35 +5,33 @@ export const formatFactLines = (facts) => facts.map((fact) => {
|
|
|
5
5
|
if (fact.target_node?.name)
|
|
6
6
|
entities.push(fact.target_node.name);
|
|
7
7
|
const entityStr = entities.length > 0 ? ` [${entities.join(" -> ")}]` : "";
|
|
8
|
-
return
|
|
8
|
+
return `<fact>${fact.fact}${entityStr}</fact>`;
|
|
9
9
|
});
|
|
10
10
|
export const formatNodeLines = (nodes) => nodes.map((node) => {
|
|
11
11
|
const labels = node.labels?.length ? ` (${node.labels.join(", ")})` : "";
|
|
12
12
|
const summary = node.summary ? `: ${node.summary}` : "";
|
|
13
|
-
return
|
|
13
|
+
return `<node>${node.name}${labels}${summary}</node>`;
|
|
14
14
|
});
|
|
15
15
|
/**
|
|
16
16
|
* Format Graphiti facts and nodes into a user-facing context block.
|
|
17
17
|
*/
|
|
18
18
|
export function formatMemoryContext(facts, nodes) {
|
|
19
|
+
if (facts.length === 0 && nodes.length === 0) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
19
22
|
const sections = [];
|
|
20
|
-
sections.push("
|
|
21
|
-
sections.push("");
|
|
22
|
-
sections.push("The following information was retrieved from your persistent memory.");
|
|
23
|
-
sections.push("Use this context to inform your responses, but do not mention it unless asked.");
|
|
24
|
-
sections.push("");
|
|
23
|
+
sections.push("<memory>");
|
|
24
|
+
sections.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
25
25
|
if (facts.length > 0) {
|
|
26
|
-
sections.push("
|
|
26
|
+
sections.push("<facts>");
|
|
27
27
|
sections.push(...formatFactLines(facts));
|
|
28
|
-
sections.push("");
|
|
28
|
+
sections.push("</facts>");
|
|
29
29
|
}
|
|
30
30
|
if (nodes.length > 0) {
|
|
31
|
-
sections.push("
|
|
31
|
+
sections.push("<nodes>");
|
|
32
32
|
sections.push(...formatNodeLines(nodes));
|
|
33
|
-
sections.push("");
|
|
34
|
-
}
|
|
35
|
-
if (facts.length === 0 && nodes.length === 0) {
|
|
36
|
-
return "";
|
|
33
|
+
sections.push("</nodes>");
|
|
37
34
|
}
|
|
35
|
+
sections.push("</memory>");
|
|
38
36
|
return sections.join("\n");
|
|
39
37
|
}
|
package/esm/src/utils.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { Part } from "@opencode-ai/sdk";
|
|
|
2
2
|
/**
|
|
3
3
|
* Build a sanitized Graphiti group ID from a prefix and project directory.
|
|
4
4
|
*/
|
|
5
|
-
export declare const makeGroupId: (prefix
|
|
5
|
+
export declare const makeGroupId: (prefix?: string, directory?: string) => string;
|
|
6
6
|
/**
|
|
7
7
|
* Build a sanitized Graphiti group ID from a prefix and user home directory.
|
|
8
8
|
*/
|
|
9
|
-
export declare const makeUserGroupId: (prefix
|
|
9
|
+
export declare const makeUserGroupId: (prefix?: string, directory?: string) => string;
|
|
10
10
|
/**
|
|
11
11
|
* Narrow an OpenCode Part to a non-synthetic text part.
|
|
12
12
|
*/
|
package/esm/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC"}
|
package/esm/src/utils.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
const getProjectName = (directory) => directory.split("/").filter(Boolean).at(-1)?.trim() || "default";
|
|
4
|
+
const getUserName = (home = os.homedir().split("/").filter(Boolean).at(-1)) => home?.trim() || undefined;
|
|
2
5
|
/**
|
|
3
6
|
* Build a sanitized Graphiti group ID from a prefix and project directory.
|
|
4
7
|
*/
|
|
5
|
-
export const makeGroupId = (prefix, directory) => {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const rawGroupId = `${prefix}_${projectName}`;
|
|
8
|
+
export const makeGroupId = (prefix, directory = process.cwd()) => {
|
|
9
|
+
const projectName = getProjectName(directory);
|
|
10
|
+
const rawGroupId = `${prefix?.concat("-")}${projectName}__main`;
|
|
9
11
|
return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
10
12
|
};
|
|
11
13
|
/**
|
|
12
14
|
* Build a sanitized Graphiti group ID from a prefix and user home directory.
|
|
13
15
|
*/
|
|
14
|
-
export const makeUserGroupId = (prefix) => {
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const rawGroupId = `${prefix}_user_${userName}`;
|
|
16
|
+
export const makeUserGroupId = (prefix, directory = process.cwd()) => {
|
|
17
|
+
const projectName = getProjectName(directory);
|
|
18
|
+
const userName = getUserName();
|
|
19
|
+
const rawGroupId = `${prefix?.concat("-")}${projectName}__user-${userName}`;
|
|
19
20
|
return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
20
21
|
};
|
|
21
22
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type ChatMessageHook = NonNullable<Hooks["chat.message"]>;
|
|
5
|
+
type ChatMessageInput = Parameters<ChatMessageHook>[0];
|
|
6
|
+
type ChatMessageOutput = Parameters<ChatMessageHook>[1];
|
|
4
7
|
/** Dependencies for the chat message handler. */
|
|
5
8
|
export interface ChatHandlerDeps {
|
|
6
9
|
sessionManager: SessionManager;
|
|
@@ -8,14 +11,6 @@ export interface ChatHandlerDeps {
|
|
|
8
11
|
client: GraphitiClient;
|
|
9
12
|
}
|
|
10
13
|
/** Creates the `chat.message` hook handler. */
|
|
11
|
-
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }:
|
|
12
|
-
|
|
13
|
-
}, output: {
|
|
14
|
-
allow_buffering?: boolean;
|
|
15
|
-
parts: Part[];
|
|
16
|
-
message: {
|
|
17
|
-
sessionID: string;
|
|
18
|
-
id: string;
|
|
19
|
-
};
|
|
20
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createChatHandler(deps: ChatHandlerDeps): ({ sessionID }: ChatMessageInput, output: ChatMessageOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
21
16
|
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAyGvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBAuDzE"}
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createChatHandler = createChatHandler;
|
|
4
|
-
const context_js_1 = require("../services/context.js");
|
|
5
4
|
const context_limit_js_1 = require("../services/context-limit.js");
|
|
5
|
+
const context_js_1 = require("../services/context.js");
|
|
6
6
|
const logger_js_1 = require("../services/logger.js");
|
|
7
7
|
const utils_js_1 = require("../utils.js");
|
|
8
8
|
/** Creates the `chat.message` hook handler. */
|
|
9
9
|
function createChatHandler(deps) {
|
|
10
10
|
const { sessionManager, injectionInterval, client } = deps;
|
|
11
11
|
const removeSyntheticMemoryParts = (parts) => parts.filter((part) => {
|
|
12
|
-
|
|
13
|
-
const id = typeof part.id === "string"
|
|
14
|
-
? String(part.id)
|
|
15
|
-
: "";
|
|
16
|
-
if (!synthetic)
|
|
12
|
+
if (part.type !== "text")
|
|
17
13
|
return true;
|
|
18
|
-
if (id
|
|
14
|
+
if (part.id?.startsWith("graphiti-memory-"))
|
|
19
15
|
return false;
|
|
20
|
-
if (id
|
|
16
|
+
if (part.id?.startsWith("graphiti-refresh-"))
|
|
21
17
|
return false;
|
|
22
18
|
return true;
|
|
23
19
|
});
|
|
24
|
-
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget) => {
|
|
20
|
+
const injectMemoryContext = async (state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject) => {
|
|
25
21
|
const userGroupId = state.userGroupId;
|
|
26
22
|
const projectFactsPromise = client.searchFacts({
|
|
27
23
|
query: messageText,
|
|
@@ -70,14 +66,28 @@ function createChatHandler(deps) {
|
|
|
70
66
|
.slice(0, characterBudget);
|
|
71
67
|
if (!memoryContext)
|
|
72
68
|
return;
|
|
73
|
-
output.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
if ("system" in output.message) {
|
|
70
|
+
try {
|
|
71
|
+
output.message.system = memoryContext;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
catch (_err) {
|
|
75
|
+
// Fall through to synthetic injection.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (shouldReinject) {
|
|
79
|
+
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
80
|
+
}
|
|
81
|
+
{
|
|
82
|
+
output.parts.unshift({
|
|
83
|
+
type: "text",
|
|
84
|
+
text: memoryContext,
|
|
85
|
+
id: `${prefix}${Date.now()}`,
|
|
86
|
+
sessionID: output.message.sessionID,
|
|
87
|
+
messageID: output.message.id,
|
|
88
|
+
synthetic: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
81
91
|
logger_js_1.logger.info(`Injected ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes`);
|
|
82
92
|
};
|
|
83
93
|
return async ({ sessionID }, output) => {
|
|
@@ -87,7 +97,6 @@ function createChatHandler(deps) {
|
|
|
87
97
|
}
|
|
88
98
|
const { state, resolved } = await sessionManager.resolveSessionState(sessionID);
|
|
89
99
|
if (!resolved) {
|
|
90
|
-
output.allow_buffering = true;
|
|
91
100
|
logger_js_1.logger.debug("Unable to resolve session for message:", { sessionID });
|
|
92
101
|
return;
|
|
93
102
|
}
|
|
@@ -112,14 +121,11 @@ function createChatHandler(deps) {
|
|
|
112
121
|
injectionInterval;
|
|
113
122
|
if (!shouldInjectOnFirst && !shouldReinject)
|
|
114
123
|
return;
|
|
115
|
-
if (shouldReinject) {
|
|
116
|
-
output.parts = removeSyntheticMemoryParts(output.parts);
|
|
117
|
-
}
|
|
118
124
|
try {
|
|
119
125
|
const prefix = shouldReinject ? "graphiti-refresh-" : "graphiti-memory-";
|
|
120
126
|
const useUserScope = shouldInjectOnFirst;
|
|
121
127
|
const characterBudget = (0, context_limit_js_1.calculateInjectionBudget)(state.contextLimit);
|
|
122
|
-
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget);
|
|
128
|
+
await injectMemoryContext(state, messageText, output, prefix, useUserScope, characterBudget, shouldReinject);
|
|
123
129
|
state.injectedMemories = true;
|
|
124
130
|
state.lastInjectionMessageCount = state.messageCount;
|
|
125
131
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
1
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
2
3
|
import type { SessionManager } from "../session.js";
|
|
4
|
+
type CompactingHook = NonNullable<Hooks["experimental.session.compacting"]>;
|
|
5
|
+
type CompactingInput = Parameters<CompactingHook>[0];
|
|
6
|
+
type CompactingOutput = Parameters<CompactingHook>[1];
|
|
3
7
|
/** Dependencies for the compacting handler. */
|
|
4
8
|
export interface CompactingHandlerDeps {
|
|
5
9
|
sessionManager: SessionManager;
|
|
@@ -7,9 +11,6 @@ export interface CompactingHandlerDeps {
|
|
|
7
11
|
defaultGroupId: string;
|
|
8
12
|
}
|
|
9
13
|
/** Creates the `experimental.session.compacting` hook handler. */
|
|
10
|
-
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }:
|
|
11
|
-
|
|
12
|
-
}, output: {
|
|
13
|
-
context: string[];
|
|
14
|
-
}) => Promise<void>;
|
|
14
|
+
export declare function createCompactingHandler(deps: CompactingHandlerDeps): ({ sessionID }: CompactingInput, output: CompactingOutput) => Promise<void>;
|
|
15
|
+
export {};
|
|
15
16
|
//# sourceMappingURL=compacting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe
|
|
1
|
+
{"version":3,"file":"compacting.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/compacting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;AAC5E,KAAK,eAAe,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,KAAK,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,IAI/D,eAAe,eAAe,EAC9B,QAAQ,gBAAgB,mBAyB3B"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
2
2
|
import type { GraphitiClient } from "../services/client.js";
|
|
3
3
|
import type { ProviderListClient } from "../services/context-limit.js";
|
|
4
4
|
import type { SessionManager } from "../session.js";
|
|
5
|
+
type EventHook = NonNullable<Hooks["event"]>;
|
|
6
|
+
type EventInput = Parameters<EventHook>[0];
|
|
5
7
|
/** Dependencies for the event handler. */
|
|
6
8
|
export interface EventHandlerDeps {
|
|
7
9
|
sessionManager: SessionManager;
|
|
@@ -12,7 +14,6 @@ export interface EventHandlerDeps {
|
|
|
12
14
|
groupIdPrefix: string;
|
|
13
15
|
}
|
|
14
16
|
/** Creates the `event` hook handler. */
|
|
15
|
-
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }:
|
|
16
|
-
|
|
17
|
-
}) => Promise<void>;
|
|
17
|
+
export declare function createEventHandler(deps: EventHandlerDeps): ({ event }: EventInput) => Promise<void>;
|
|
18
|
+
export {};
|
|
18
19
|
//# sourceMappingURL=event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAWzC,WAAW,UAAU,mBA+JpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAW/D;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAW/D;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAkDtB,CAAC"}
|
package/script/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ const graphiti = async (input) => {
|
|
|
22
22
|
logger_js_1.logger.warn("Memory features will be unavailable until connection is established");
|
|
23
23
|
}
|
|
24
24
|
const defaultGroupId = (0, utils_js_1.makeGroupId)(config.groupIdPrefix, input.directory);
|
|
25
|
-
const defaultUserGroupId = (0, utils_js_1.makeUserGroupId)(config.groupIdPrefix);
|
|
25
|
+
const defaultUserGroupId = (0, utils_js_1.makeUserGroupId)(config.groupIdPrefix, input.directory);
|
|
26
26
|
logger_js_1.logger.info("Plugin initialized. Group ID:", defaultGroupId);
|
|
27
27
|
const sessionManager = new session_js_1.SessionManager(defaultGroupId, defaultUserGroupId, sdkClient, client);
|
|
28
28
|
return {
|
|
@@ -38,12 +38,12 @@ class GraphitiClient {
|
|
|
38
38
|
value: void 0
|
|
39
39
|
});
|
|
40
40
|
this.endpoint = endpoint;
|
|
41
|
-
this.client = new index_js_1.Client({ name: "opencode-graphiti", version: "0.1.
|
|
41
|
+
this.client = new index_js_1.Client({ name: "opencode-graphiti", version: "0.1.4" });
|
|
42
42
|
this.transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(endpoint));
|
|
43
43
|
}
|
|
44
44
|
/** Create a fresh MCP Client and Transport pair. */
|
|
45
45
|
createClientAndTransport() {
|
|
46
|
-
this.client = new index_js_1.Client({ name: "opencode-graphiti", version: "0.1.
|
|
46
|
+
this.client = new index_js_1.Client({ name: "opencode-graphiti", version: "0.1.4" });
|
|
47
47
|
this.transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(this.endpoint));
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/src/services/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;SAC5B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,MAAM,EAAE;QACN,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;KAC/B,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgIpB"}
|
|
@@ -73,32 +73,40 @@ async function getCompactionContext(params) {
|
|
|
73
73
|
const buildSection = (header, facts, nodes) => {
|
|
74
74
|
const lines = [];
|
|
75
75
|
lines.push(header);
|
|
76
|
+
lines.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
76
77
|
if (facts.length > 0) {
|
|
77
|
-
lines.push("
|
|
78
|
+
lines.push("<facts>");
|
|
78
79
|
lines.push(...(0, context_js_1.formatFactLines)(facts));
|
|
80
|
+
lines.push("</facts>");
|
|
79
81
|
}
|
|
80
82
|
if (nodes.length > 0) {
|
|
81
|
-
lines.push("
|
|
83
|
+
lines.push("<nodes>");
|
|
82
84
|
lines.push(...(0, context_js_1.formatNodeLines)(nodes));
|
|
85
|
+
lines.push("</nodes>");
|
|
83
86
|
}
|
|
84
87
|
return lines.join("\n");
|
|
85
88
|
};
|
|
86
|
-
const projectSection = buildSection(
|
|
87
|
-
const userSection = buildSection(
|
|
89
|
+
const projectSection = buildSection('<memory source="project">', projectFacts, projectNodes);
|
|
90
|
+
const userSection = buildSection('<memory source="user">', userFacts, userNodes);
|
|
88
91
|
const headerLines = [
|
|
89
|
-
"
|
|
92
|
+
"<summary>",
|
|
93
|
+
"<current_goal>",
|
|
90
94
|
"- ",
|
|
95
|
+
"</current_goal>",
|
|
91
96
|
"",
|
|
92
|
-
"
|
|
97
|
+
"<work_completed>",
|
|
93
98
|
"- ",
|
|
99
|
+
"</work_completed>",
|
|
94
100
|
"",
|
|
95
|
-
"
|
|
101
|
+
"<remaining_tasks>",
|
|
96
102
|
"- ",
|
|
103
|
+
"</remaining_tasks>",
|
|
97
104
|
"",
|
|
98
|
-
"
|
|
105
|
+
"<constraints_decisions>",
|
|
99
106
|
"- ",
|
|
107
|
+
"</constraints_decisions>",
|
|
100
108
|
"",
|
|
101
|
-
"
|
|
109
|
+
"<persistent_memory>",
|
|
102
110
|
];
|
|
103
111
|
const header = headerLines.join("\n");
|
|
104
112
|
const base = `${header}\n`;
|
|
@@ -108,10 +116,16 @@ async function getCompactionContext(params) {
|
|
|
108
116
|
const truncatedProject = projectSection.slice(0, projectBudget);
|
|
109
117
|
const truncatedUser = userSection.slice(0, userBudget);
|
|
110
118
|
const sections = [header];
|
|
111
|
-
if (truncatedProject.trim())
|
|
119
|
+
if (truncatedProject.trim()) {
|
|
112
120
|
sections.push(truncatedProject);
|
|
113
|
-
|
|
121
|
+
sections.push("</memory>");
|
|
122
|
+
}
|
|
123
|
+
if (truncatedUser.trim()) {
|
|
114
124
|
sections.push(truncatedUser);
|
|
125
|
+
sections.push("</memory>");
|
|
126
|
+
}
|
|
127
|
+
sections.push("</persistent_memory>");
|
|
128
|
+
sections.push("</summary>");
|
|
115
129
|
const content = sections.join("\n").slice(0, characterBudget);
|
|
116
130
|
return [content];
|
|
117
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/src/services/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAO1D,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,OAAO,YAAY,EAAE,KAAG,MAAM,EAK1D,CAAC;AAEL;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,KAAK,EAAE,YAAY,EAAE,GACpB,MAAM,CA0BR"}
|
|
@@ -9,37 +9,35 @@ const formatFactLines = (facts) => facts.map((fact) => {
|
|
|
9
9
|
if (fact.target_node?.name)
|
|
10
10
|
entities.push(fact.target_node.name);
|
|
11
11
|
const entityStr = entities.length > 0 ? ` [${entities.join(" -> ")}]` : "";
|
|
12
|
-
return
|
|
12
|
+
return `<fact>${fact.fact}${entityStr}</fact>`;
|
|
13
13
|
});
|
|
14
14
|
exports.formatFactLines = formatFactLines;
|
|
15
15
|
const formatNodeLines = (nodes) => nodes.map((node) => {
|
|
16
16
|
const labels = node.labels?.length ? ` (${node.labels.join(", ")})` : "";
|
|
17
17
|
const summary = node.summary ? `: ${node.summary}` : "";
|
|
18
|
-
return
|
|
18
|
+
return `<node>${node.name}${labels}${summary}</node>`;
|
|
19
19
|
});
|
|
20
20
|
exports.formatNodeLines = formatNodeLines;
|
|
21
21
|
/**
|
|
22
22
|
* Format Graphiti facts and nodes into a user-facing context block.
|
|
23
23
|
*/
|
|
24
24
|
function formatMemoryContext(facts, nodes) {
|
|
25
|
+
if (facts.length === 0 && nodes.length === 0) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
25
28
|
const sections = [];
|
|
26
|
-
sections.push("
|
|
27
|
-
sections.push("");
|
|
28
|
-
sections.push("The following information was retrieved from your persistent memory.");
|
|
29
|
-
sections.push("Use this context to inform your responses, but do not mention it unless asked.");
|
|
30
|
-
sections.push("");
|
|
29
|
+
sections.push("<memory>");
|
|
30
|
+
sections.push("<instruction>Background context only; do not reference in titles, summaries, or opening responses unless directly relevant.</instruction>");
|
|
31
31
|
if (facts.length > 0) {
|
|
32
|
-
sections.push("
|
|
32
|
+
sections.push("<facts>");
|
|
33
33
|
sections.push(...(0, exports.formatFactLines)(facts));
|
|
34
|
-
sections.push("");
|
|
34
|
+
sections.push("</facts>");
|
|
35
35
|
}
|
|
36
36
|
if (nodes.length > 0) {
|
|
37
|
-
sections.push("
|
|
37
|
+
sections.push("<nodes>");
|
|
38
38
|
sections.push(...(0, exports.formatNodeLines)(nodes));
|
|
39
|
-
sections.push("");
|
|
40
|
-
}
|
|
41
|
-
if (facts.length === 0 && nodes.length === 0) {
|
|
42
|
-
return "";
|
|
39
|
+
sections.push("</nodes>");
|
|
43
40
|
}
|
|
41
|
+
sections.push("</memory>");
|
|
44
42
|
return sections.join("\n");
|
|
45
43
|
}
|
package/script/src/utils.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { Part } from "@opencode-ai/sdk";
|
|
|
2
2
|
/**
|
|
3
3
|
* Build a sanitized Graphiti group ID from a prefix and project directory.
|
|
4
4
|
*/
|
|
5
|
-
export declare const makeGroupId: (prefix
|
|
5
|
+
export declare const makeGroupId: (prefix?: string, directory?: string) => string;
|
|
6
6
|
/**
|
|
7
7
|
* Build a sanitized Graphiti group ID from a prefix and user home directory.
|
|
8
8
|
*/
|
|
9
|
-
export declare const makeUserGroupId: (prefix
|
|
9
|
+
export declare const makeUserGroupId: (prefix?: string, directory?: string) => string;
|
|
10
10
|
/**
|
|
11
11
|
* Narrow an OpenCode Part to a non-synthetic text part.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC"}
|
package/script/src/utils.js
CHANGED
|
@@ -5,24 +5,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.extractTextFromParts = exports.isTextPart = exports.makeUserGroupId = exports.makeGroupId = void 0;
|
|
7
7
|
const node_os_1 = __importDefault(require("node:os"));
|
|
8
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
9
|
+
const getProjectName = (directory) => directory.split("/").filter(Boolean).at(-1)?.trim() || "default";
|
|
10
|
+
const getUserName = (home = node_os_1.default.homedir().split("/").filter(Boolean).at(-1)) => home?.trim() || undefined;
|
|
8
11
|
/**
|
|
9
12
|
* Build a sanitized Graphiti group ID from a prefix and project directory.
|
|
10
13
|
*/
|
|
11
|
-
const makeGroupId = (prefix, directory) => {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const rawGroupId = `${prefix}_${projectName}`;
|
|
14
|
+
const makeGroupId = (prefix, directory = node_process_1.default.cwd()) => {
|
|
15
|
+
const projectName = getProjectName(directory);
|
|
16
|
+
const rawGroupId = `${prefix?.concat("-")}${projectName}__main`;
|
|
15
17
|
return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
16
18
|
};
|
|
17
19
|
exports.makeGroupId = makeGroupId;
|
|
18
20
|
/**
|
|
19
21
|
* Build a sanitized Graphiti group ID from a prefix and user home directory.
|
|
20
22
|
*/
|
|
21
|
-
const makeUserGroupId = (prefix) => {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const rawGroupId = `${prefix}_user_${userName}`;
|
|
23
|
+
const makeUserGroupId = (prefix, directory = node_process_1.default.cwd()) => {
|
|
24
|
+
const projectName = getProjectName(directory);
|
|
25
|
+
const userName = getUserName();
|
|
26
|
+
const rawGroupId = `${prefix?.concat("-")}${projectName}__user-${userName}`;
|
|
26
27
|
return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
27
28
|
};
|
|
28
29
|
exports.makeUserGroupId = makeUserGroupId;
|