clawdbot-penfield 1.0.1
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/LICENSE +21 -0
- package/README.md +519 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/src/api-client.d.ts +14 -0
- package/dist/src/api-client.d.ts.map +1 -0
- package/dist/src/api-client.js +53 -0
- package/dist/src/auth-service.d.ts +35 -0
- package/dist/src/auth-service.d.ts.map +1 -0
- package/dist/src/auth-service.js +197 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +50 -0
- package/dist/src/config.d.ts +16 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +14 -0
- package/dist/src/device-flow.d.ts +35 -0
- package/dist/src/device-flow.d.ts.map +1 -0
- package/dist/src/device-flow.js +169 -0
- package/dist/src/runtime.d.ts +18 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +18 -0
- package/dist/src/store.d.ts +49 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +66 -0
- package/dist/src/tools/awaken.d.ts +4 -0
- package/dist/src/tools/awaken.d.ts.map +1 -0
- package/dist/src/tools/awaken.js +17 -0
- package/dist/src/tools/connect.d.ts +9 -0
- package/dist/src/tools/connect.d.ts.map +1 -0
- package/dist/src/tools/connect.js +41 -0
- package/dist/src/tools/delete-artifact.d.ts +6 -0
- package/dist/src/tools/delete-artifact.d.ts.map +1 -0
- package/dist/src/tools/delete-artifact.js +24 -0
- package/dist/src/tools/explore.d.ts +9 -0
- package/dist/src/tools/explore.d.ts.map +1 -0
- package/dist/src/tools/explore.js +35 -0
- package/dist/src/tools/fetch.d.ts +6 -0
- package/dist/src/tools/fetch.d.ts.map +1 -0
- package/dist/src/tools/fetch.js +21 -0
- package/dist/src/tools/index.d.ts +4 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +58 -0
- package/dist/src/tools/list-artifacts.d.ts +7 -0
- package/dist/src/tools/list-artifacts.d.ts.map +1 -0
- package/dist/src/tools/list-artifacts.js +32 -0
- package/dist/src/tools/list-contexts.d.ts +7 -0
- package/dist/src/tools/list-contexts.d.ts.map +1 -0
- package/dist/src/tools/list-contexts.js +32 -0
- package/dist/src/tools/recall.d.ts +13 -0
- package/dist/src/tools/recall.d.ts.map +1 -0
- package/dist/src/tools/recall.js +64 -0
- package/dist/src/tools/reflect.d.ts +8 -0
- package/dist/src/tools/reflect.d.ts.map +1 -0
- package/dist/src/tools/reflect.js +38 -0
- package/dist/src/tools/restore-context.d.ts +8 -0
- package/dist/src/tools/restore-context.d.ts.map +1 -0
- package/dist/src/tools/restore-context.js +34 -0
- package/dist/src/tools/retrieve-artifact.d.ts +6 -0
- package/dist/src/tools/retrieve-artifact.d.ts.map +1 -0
- package/dist/src/tools/retrieve-artifact.js +24 -0
- package/dist/src/tools/save-artifact.d.ts +8 -0
- package/dist/src/tools/save-artifact.d.ts.map +1 -0
- package/dist/src/tools/save-artifact.js +27 -0
- package/dist/src/tools/save-context.d.ts +7 -0
- package/dist/src/tools/save-context.d.ts.map +1 -0
- package/dist/src/tools/save-context.js +27 -0
- package/dist/src/tools/search.d.ts +9 -0
- package/dist/src/tools/search.d.ts.map +1 -0
- package/dist/src/tools/search.js +41 -0
- package/dist/src/tools/store.d.ts +11 -0
- package/dist/src/tools/store.d.ts.map +1 -0
- package/dist/src/tools/store.js +36 -0
- package/dist/src/tools/update-memory.d.ts +11 -0
- package/dist/src/tools/update-memory.d.ts.map +1 -0
- package/dist/src/tools/update-memory.js +34 -0
- package/dist/src/types/typebox.d.ts +19 -0
- package/dist/src/types/typebox.d.ts.map +1 -0
- package/dist/src/types/typebox.js +91 -0
- package/dist/src/types.d.ts +73 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +7 -0
- package/dist/src/validation.d.ts +21 -0
- package/dist/src/validation.d.ts.map +1 -0
- package/dist/src/validation.js +43 -0
- package/package.json +52 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const RestoreContextToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
checkpoint_id: import("@sinclair/typebox").TString;
|
|
4
|
+
full_restore: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
5
|
+
merge_mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"append">, import("@sinclair/typebox").TLiteral<"replace">, import("@sinclair/typebox").TLiteral<"smart_merge">]>>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function executeRestoreContextTool(apiClient: PenfieldApiClient, params: any): Promise<any>;
|
|
8
|
+
//# sourceMappingURL=restore-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore-context.d.ts","sourceRoot":"","sources":["../../../src/tools/restore-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,eAAO,MAAM,wBAAwB;;;;EAuBF,CAAC;AAEpC,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAgBd"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Type } from "../types/typebox.js";
|
|
2
|
+
import { validateUuid } from "../validation.js";
|
|
3
|
+
export const RestoreContextToolSchema = Type.Object({
|
|
4
|
+
checkpoint_id: Type.String({
|
|
5
|
+
description: "Checkpoint ID to restore (e.g., cp-550e8400-e29b-41d4-a716-446655440000)",
|
|
6
|
+
}),
|
|
7
|
+
full_restore: Type.Optional(Type.Boolean({
|
|
8
|
+
description: "Create new copies of memories instead of referencing existing (default: false)",
|
|
9
|
+
default: false,
|
|
10
|
+
})),
|
|
11
|
+
merge_mode: Type.Optional(Type.Union([
|
|
12
|
+
Type.Literal("append"),
|
|
13
|
+
Type.Literal("replace"),
|
|
14
|
+
Type.Literal("smart_merge"),
|
|
15
|
+
], {
|
|
16
|
+
description: "How to handle conflicts: append (add to existing), replace (use only checkpoint), smart_merge (newer versions preferred)",
|
|
17
|
+
default: "append",
|
|
18
|
+
})),
|
|
19
|
+
}, { additionalProperties: false });
|
|
20
|
+
export async function executeRestoreContextTool(apiClient, params // eslint-disable-line @typescript-eslint/no-explicit-any -- validated by TypeBox schema
|
|
21
|
+
) {
|
|
22
|
+
const { checkpoint_id, ...restoreParams } = params;
|
|
23
|
+
validateUuid(checkpoint_id, 'checkpoint_id');
|
|
24
|
+
const response = await apiClient.post(`/api/v2/checkpoint/${checkpoint_id}/recall`, restoreParams);
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: JSON.stringify(response, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
details: response,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const RetrieveArtifactToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
path: import("@sinclair/typebox").TString;
|
|
4
|
+
}>;
|
|
5
|
+
export declare function executeRetrieveArtifactTool(apiClient: PenfieldApiClient, params: any): Promise<any>;
|
|
6
|
+
//# sourceMappingURL=retrieve-artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieve-artifact.d.ts","sourceRoot":"","sources":["../../../src/tools/retrieve-artifact.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,eAAO,MAAM,0BAA0B;;EAIJ,CAAC;AAEpC,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAgBd"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Type } from "../types/typebox.js";
|
|
2
|
+
import { validateArtifactPath } from "../validation.js";
|
|
3
|
+
export const RetrieveArtifactToolSchema = Type.Object({
|
|
4
|
+
path: Type.String({
|
|
5
|
+
description: "Artifact path to retrieve",
|
|
6
|
+
}),
|
|
7
|
+
}, { additionalProperties: false });
|
|
8
|
+
export async function executeRetrieveArtifactTool(apiClient, params // eslint-disable-line @typescript-eslint/no-explicit-any -- validated by TypeBox schema
|
|
9
|
+
) {
|
|
10
|
+
validateArtifactPath(params.path);
|
|
11
|
+
const queryParams = {
|
|
12
|
+
path: params.path,
|
|
13
|
+
};
|
|
14
|
+
const response = await apiClient.get("/api/v2/artifacts", queryParams);
|
|
15
|
+
return {
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: "text",
|
|
19
|
+
text: JSON.stringify(response, null, 2),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
details: response,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const SaveArtifactToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
path: import("@sinclair/typebox").TString;
|
|
4
|
+
content: import("@sinclair/typebox").TString;
|
|
5
|
+
content_type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function executeSaveArtifactTool(apiClient: PenfieldApiClient, params: any): Promise<any>;
|
|
8
|
+
//# sourceMappingURL=save-artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-artifact.d.ts","sourceRoot":"","sources":["../../../src/tools/save-artifact.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,eAAO,MAAM,sBAAsB;;;;EAYA,CAAC;AAEpC,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAYd"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Type } from "../types/typebox.js";
|
|
2
|
+
import { validateArtifactPath } from "../validation.js";
|
|
3
|
+
export const SaveArtifactToolSchema = Type.Object({
|
|
4
|
+
path: Type.String({
|
|
5
|
+
description: "Artifact path (e.g., /project/file.txt)",
|
|
6
|
+
}),
|
|
7
|
+
content: Type.String({
|
|
8
|
+
description: "Artifact content",
|
|
9
|
+
}),
|
|
10
|
+
content_type: Type.Optional(Type.String({
|
|
11
|
+
description: "MIME type (default: text/plain)",
|
|
12
|
+
})),
|
|
13
|
+
}, { additionalProperties: false });
|
|
14
|
+
export async function executeSaveArtifactTool(apiClient, params // eslint-disable-line @typescript-eslint/no-explicit-any -- validated by TypeBox schema
|
|
15
|
+
) {
|
|
16
|
+
validateArtifactPath(params.path);
|
|
17
|
+
const response = await apiClient.post("/api/v2/artifacts", params);
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: JSON.stringify(response, null, 2),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
details: response,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const SaveContextToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
memory_ids: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
4
|
+
session_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function executeSaveContextTool(apiClient: PenfieldApiClient, params: unknown): Promise<any>;
|
|
7
|
+
//# sourceMappingURL=save-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-context.d.ts","sourceRoot":"","sources":["../../../src/tools/save-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,eAAO,MAAM,qBAAqB;;;EAUC,CAAC;AAEpC,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,CAgBd"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Type } from "../types/typebox.js";
|
|
2
|
+
import { validateUuid } from "../validation.js";
|
|
3
|
+
export const SaveContextToolSchema = Type.Object({
|
|
4
|
+
memory_ids: Type.Array(Type.String(), {
|
|
5
|
+
description: "Array of memory IDs to save in checkpoint",
|
|
6
|
+
minItems: 1,
|
|
7
|
+
}),
|
|
8
|
+
session_id: Type.Optional(Type.String({
|
|
9
|
+
description: "Optional session identifier",
|
|
10
|
+
})),
|
|
11
|
+
}, { additionalProperties: false });
|
|
12
|
+
export async function executeSaveContextTool(apiClient, params) {
|
|
13
|
+
const { memory_ids, session_id } = params;
|
|
14
|
+
memory_ids.forEach((id, index) => {
|
|
15
|
+
validateUuid(id, `memory_ids[${index}]`);
|
|
16
|
+
});
|
|
17
|
+
const response = await apiClient.post("/api/v2/checkpoint/create", { memory_ids, session_id });
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: JSON.stringify(response, null, 2),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
details: response,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const SearchToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
query: import("@sinclair/typebox").TString;
|
|
4
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
5
|
+
memory_types: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"fact">, import("@sinclair/typebox").TLiteral<"insight">, import("@sinclair/typebox").TLiteral<"conversation">, import("@sinclair/typebox").TLiteral<"correction">, import("@sinclair/typebox").TLiteral<"reference">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"checkpoint">, import("@sinclair/typebox").TLiteral<"identity_core">, import("@sinclair/typebox").TLiteral<"personality_trait">, import("@sinclair/typebox").TLiteral<"relationship">, import("@sinclair/typebox").TLiteral<"strategy">]>>>;
|
|
6
|
+
importance_threshold: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function executeSearchTool(apiClient: PenfieldApiClient, params: any): Promise<any>;
|
|
9
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,eAAO,MAAM,gBAAgB;;;;;EAyBM,CAAC;AAEpC,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAmBd"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Type, MemoryTypeSchema, ImportanceScoreSchema } from "../types/typebox.js";
|
|
2
|
+
export const SearchToolSchema = Type.Object({
|
|
3
|
+
query: Type.String({
|
|
4
|
+
description: "Search query (1-4,000 chars)",
|
|
5
|
+
minLength: 1,
|
|
6
|
+
maxLength: 4000,
|
|
7
|
+
}),
|
|
8
|
+
limit: Type.Optional(Type.Number({
|
|
9
|
+
description: "Max results (default: 20, max: 100)",
|
|
10
|
+
minimum: 1,
|
|
11
|
+
maximum: 100,
|
|
12
|
+
default: 20,
|
|
13
|
+
})),
|
|
14
|
+
memory_types: Type.Optional(Type.Array(MemoryTypeSchema, {
|
|
15
|
+
description: "Filter by memory types",
|
|
16
|
+
})),
|
|
17
|
+
importance_threshold: Type.Optional(Type.Number({
|
|
18
|
+
...ImportanceScoreSchema,
|
|
19
|
+
description: "Minimum importance (0-1)",
|
|
20
|
+
})),
|
|
21
|
+
}, { additionalProperties: false });
|
|
22
|
+
export async function executeSearchTool(apiClient, params // eslint-disable-line @typescript-eslint/no-explicit-any -- validated by TypeBox schema
|
|
23
|
+
) {
|
|
24
|
+
// Search is a variant of hybrid search with higher vector weight
|
|
25
|
+
const searchParams = {
|
|
26
|
+
...params,
|
|
27
|
+
vector_weight: 0.6,
|
|
28
|
+
bm25_weight: 0.3,
|
|
29
|
+
graph_weight: 0.1,
|
|
30
|
+
};
|
|
31
|
+
const response = await apiClient.post("/api/v2/search/hybrid", searchParams);
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: JSON.stringify(response, null, 2),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
details: response,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const StoreToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
content: import("@sinclair/typebox").TString;
|
|
4
|
+
memory_type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"fact">, import("@sinclair/typebox").TLiteral<"insight">, import("@sinclair/typebox").TLiteral<"conversation">, import("@sinclair/typebox").TLiteral<"correction">, import("@sinclair/typebox").TLiteral<"reference">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"checkpoint">, import("@sinclair/typebox").TLiteral<"identity_core">, import("@sinclair/typebox").TLiteral<"personality_trait">, import("@sinclair/typebox").TLiteral<"relationship">, import("@sinclair/typebox").TLiteral<"strategy">]>>;
|
|
5
|
+
importance: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
6
|
+
confidence: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
7
|
+
source_type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
8
|
+
tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function executeStoreTool(apiClient: PenfieldApiClient, params: unknown): Promise<any>;
|
|
11
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/tools/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,eAAO,MAAM,eAAe;;;;;;;EA8BO,CAAC;AAEpC,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,CAWd"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Type, MemoryTypeSchema, ImportanceScoreSchema, ConfidenceScoreSchema, TagsSchema, } from "../types/typebox.js";
|
|
2
|
+
export const StoreToolSchema = Type.Object({
|
|
3
|
+
content: Type.String({
|
|
4
|
+
description: "Memory content to store (max 10,000 chars)",
|
|
5
|
+
minLength: 1,
|
|
6
|
+
maxLength: 10000,
|
|
7
|
+
}),
|
|
8
|
+
memory_type: Type.Optional(MemoryTypeSchema),
|
|
9
|
+
importance: Type.Optional(Type.Number({
|
|
10
|
+
...ImportanceScoreSchema,
|
|
11
|
+
description: "Importance score 0-1 (default: 0.5)",
|
|
12
|
+
})),
|
|
13
|
+
confidence: Type.Optional(Type.Number({
|
|
14
|
+
...ConfidenceScoreSchema,
|
|
15
|
+
description: "Confidence score 0-1 (default: 0.8)",
|
|
16
|
+
})),
|
|
17
|
+
source_type: Type.Optional(Type.String({
|
|
18
|
+
description: "Source type (e.g., direct_input, conversation)",
|
|
19
|
+
})),
|
|
20
|
+
tags: Type.Optional(Type.Array(Type.String(), {
|
|
21
|
+
...TagsSchema,
|
|
22
|
+
description: "Tags (max 10)",
|
|
23
|
+
})),
|
|
24
|
+
}, { additionalProperties: false });
|
|
25
|
+
export async function executeStoreTool(apiClient, params) {
|
|
26
|
+
const response = await apiClient.post("/api/v2/memories", params);
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: JSON.stringify(response, null, 2),
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
details: response,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PenfieldApiClient } from "../api-client.js";
|
|
2
|
+
export declare const UpdateMemoryToolSchema: import("@sinclair/typebox").TObject<{
|
|
3
|
+
memory_id: import("@sinclair/typebox").TString;
|
|
4
|
+
content: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
5
|
+
memory_type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"fact">, import("@sinclair/typebox").TLiteral<"insight">, import("@sinclair/typebox").TLiteral<"conversation">, import("@sinclair/typebox").TLiteral<"correction">, import("@sinclair/typebox").TLiteral<"reference">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"checkpoint">, import("@sinclair/typebox").TLiteral<"identity_core">, import("@sinclair/typebox").TLiteral<"personality_trait">, import("@sinclair/typebox").TLiteral<"relationship">, import("@sinclair/typebox").TLiteral<"strategy">]>>;
|
|
6
|
+
importance: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
7
|
+
confidence: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
8
|
+
tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function executeUpdateMemoryTool(apiClient: PenfieldApiClient, params: any): Promise<any>;
|
|
11
|
+
//# sourceMappingURL=update-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-memory.d.ts","sourceRoot":"","sources":["../../../src/tools/update-memory.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,eAAO,MAAM,sBAAsB;;;;;;;EAoBA,CAAC;AAEpC,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC,CAad"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Type, MemoryTypeSchema, ImportanceScoreSchema, ConfidenceScoreSchema, TagsSchema, } from "../types/typebox.js";
|
|
2
|
+
import { validateUuid } from "../validation.js";
|
|
3
|
+
export const UpdateMemoryToolSchema = Type.Object({
|
|
4
|
+
memory_id: Type.String({
|
|
5
|
+
description: "Memory ID to update",
|
|
6
|
+
}),
|
|
7
|
+
content: Type.Optional(Type.String({
|
|
8
|
+
description: "Updated memory content (max 10,000 chars)",
|
|
9
|
+
minLength: 1,
|
|
10
|
+
maxLength: 10000,
|
|
11
|
+
})),
|
|
12
|
+
memory_type: Type.Optional(MemoryTypeSchema),
|
|
13
|
+
importance: Type.Optional(ImportanceScoreSchema),
|
|
14
|
+
confidence: Type.Optional(ConfidenceScoreSchema),
|
|
15
|
+
tags: Type.Optional(Type.Array(Type.String(), {
|
|
16
|
+
...TagsSchema,
|
|
17
|
+
description: "Tags (max 10)",
|
|
18
|
+
})),
|
|
19
|
+
}, { additionalProperties: false });
|
|
20
|
+
export async function executeUpdateMemoryTool(apiClient, params // eslint-disable-line @typescript-eslint/no-explicit-any -- validated by TypeBox schema
|
|
21
|
+
) {
|
|
22
|
+
const { memory_id, ...updateData } = params;
|
|
23
|
+
validateUuid(memory_id, 'memory_id');
|
|
24
|
+
const response = await apiClient.put(`/api/v2/memories/${memory_id}`, updateData);
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: JSON.stringify(response, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
details: response,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized TypeBox exports and common schemas
|
|
3
|
+
*
|
|
4
|
+
* All tool schemas should import Type from here:
|
|
5
|
+
* import { Type } from "../types/typebox.js";
|
|
6
|
+
*/
|
|
7
|
+
import { Type, type TSchema } from "@sinclair/typebox";
|
|
8
|
+
export { Type, type TSchema };
|
|
9
|
+
export declare const UUIDSchema: import("@sinclair/typebox").TString;
|
|
10
|
+
export declare const PaginationSchema: import("@sinclair/typebox").TObject<{
|
|
11
|
+
page: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
12
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const ImportanceScoreSchema: import("@sinclair/typebox").TNumber;
|
|
15
|
+
export declare const ConfidenceScoreSchema: import("@sinclair/typebox").TNumber;
|
|
16
|
+
export declare const TagsSchema: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
|
|
17
|
+
export declare const MemoryTypeSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"fact">, import("@sinclair/typebox").TLiteral<"insight">, import("@sinclair/typebox").TLiteral<"conversation">, import("@sinclair/typebox").TLiteral<"correction">, import("@sinclair/typebox").TLiteral<"reference">, import("@sinclair/typebox").TLiteral<"task">, import("@sinclair/typebox").TLiteral<"checkpoint">, import("@sinclair/typebox").TLiteral<"identity_core">, import("@sinclair/typebox").TLiteral<"personality_trait">, import("@sinclair/typebox").TLiteral<"relationship">, import("@sinclair/typebox").TLiteral<"strategy">]>;
|
|
18
|
+
export declare const RelationshipTypeSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"supersedes">, import("@sinclair/typebox").TLiteral<"updates">, import("@sinclair/typebox").TLiteral<"evolution_of">, import("@sinclair/typebox").TLiteral<"supports">, import("@sinclair/typebox").TLiteral<"contradicts">, import("@sinclair/typebox").TLiteral<"disputes">, import("@sinclair/typebox").TLiteral<"parent_of">, import("@sinclair/typebox").TLiteral<"child_of">, import("@sinclair/typebox").TLiteral<"sibling_of">, import("@sinclair/typebox").TLiteral<"causes">, import("@sinclair/typebox").TLiteral<"influenced_by">, import("@sinclair/typebox").TLiteral<"prerequisite_for">, import("@sinclair/typebox").TLiteral<"implements">, import("@sinclair/typebox").TLiteral<"documents">, import("@sinclair/typebox").TLiteral<"example_of">, import("@sinclair/typebox").TLiteral<"tests">, import("@sinclair/typebox").TLiteral<"responds_to">, import("@sinclair/typebox").TLiteral<"references">, import("@sinclair/typebox").TLiteral<"inspired_by">, import("@sinclair/typebox").TLiteral<"follows">, import("@sinclair/typebox").TLiteral<"precedes">, import("@sinclair/typebox").TLiteral<"depends_on">, import("@sinclair/typebox").TLiteral<"composed_of">, import("@sinclair/typebox").TLiteral<"part_of">]>;
|
|
19
|
+
//# sourceMappingURL=typebox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typebox.d.ts","sourceRoot":"","sources":["../../../src/types/typebox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;AAG9B,eAAO,MAAM,UAAU,qCAGrB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;EAY3B,CAAC;AAEH,eAAO,MAAM,qBAAqB,qCAIhC,CAAC;AAEH,eAAO,MAAM,qBAAqB,qCAIhC,CAAC;AAEH,eAAO,MAAM,UAAU,yEAGrB,CAAC;AAEH,eAAO,MAAM,gBAAgB,8lBAYQ,CAAC;AAEtC,eAAO,MAAM,sBAAsB,yvCAoCjC,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized TypeBox exports and common schemas
|
|
3
|
+
*
|
|
4
|
+
* All tool schemas should import Type from here:
|
|
5
|
+
* import { Type } from "../types/typebox.js";
|
|
6
|
+
*/
|
|
7
|
+
import { Type } from "@sinclair/typebox";
|
|
8
|
+
// Re-export Type for schema definitions
|
|
9
|
+
export { Type };
|
|
10
|
+
// Common schemas
|
|
11
|
+
export const UUIDSchema = Type.String({
|
|
12
|
+
description: "UUID format identifier",
|
|
13
|
+
format: "uuid",
|
|
14
|
+
});
|
|
15
|
+
export const PaginationSchema = Type.Object({
|
|
16
|
+
page: Type.Optional(Type.Number({
|
|
17
|
+
description: "Page number (1-indexed)",
|
|
18
|
+
minimum: 1,
|
|
19
|
+
default: 1,
|
|
20
|
+
})),
|
|
21
|
+
limit: Type.Optional(Type.Number({
|
|
22
|
+
description: "Items per page",
|
|
23
|
+
minimum: 1,
|
|
24
|
+
maximum: 100,
|
|
25
|
+
default: 20,
|
|
26
|
+
})),
|
|
27
|
+
});
|
|
28
|
+
export const ImportanceScoreSchema = Type.Number({
|
|
29
|
+
description: "Importance score 0-1",
|
|
30
|
+
minimum: 0,
|
|
31
|
+
maximum: 1,
|
|
32
|
+
});
|
|
33
|
+
export const ConfidenceScoreSchema = Type.Number({
|
|
34
|
+
description: "Confidence score 0-1",
|
|
35
|
+
minimum: 0,
|
|
36
|
+
maximum: 1,
|
|
37
|
+
});
|
|
38
|
+
export const TagsSchema = Type.Array(Type.String(), {
|
|
39
|
+
description: "Tags for categorization",
|
|
40
|
+
maxItems: 10,
|
|
41
|
+
});
|
|
42
|
+
export const MemoryTypeSchema = Type.Union([
|
|
43
|
+
Type.Literal("fact"),
|
|
44
|
+
Type.Literal("insight"),
|
|
45
|
+
Type.Literal("conversation"),
|
|
46
|
+
Type.Literal("correction"),
|
|
47
|
+
Type.Literal("reference"),
|
|
48
|
+
Type.Literal("task"),
|
|
49
|
+
Type.Literal("checkpoint"),
|
|
50
|
+
Type.Literal("identity_core"),
|
|
51
|
+
Type.Literal("personality_trait"),
|
|
52
|
+
Type.Literal("relationship"),
|
|
53
|
+
Type.Literal("strategy"),
|
|
54
|
+
], { description: "Type of memory" });
|
|
55
|
+
export const RelationshipTypeSchema = Type.Union([
|
|
56
|
+
// Knowledge Evolution
|
|
57
|
+
Type.Literal("supersedes"),
|
|
58
|
+
Type.Literal("updates"),
|
|
59
|
+
Type.Literal("evolution_of"),
|
|
60
|
+
// Evidence & Support
|
|
61
|
+
Type.Literal("supports"),
|
|
62
|
+
Type.Literal("contradicts"),
|
|
63
|
+
Type.Literal("disputes"),
|
|
64
|
+
// Hierarchy & Structure
|
|
65
|
+
Type.Literal("parent_of"),
|
|
66
|
+
Type.Literal("child_of"),
|
|
67
|
+
Type.Literal("sibling_of"),
|
|
68
|
+
// Cause & Prerequisites
|
|
69
|
+
Type.Literal("causes"),
|
|
70
|
+
Type.Literal("influenced_by"),
|
|
71
|
+
Type.Literal("prerequisite_for"),
|
|
72
|
+
// Implementation & Examples
|
|
73
|
+
Type.Literal("implements"),
|
|
74
|
+
Type.Literal("documents"),
|
|
75
|
+
Type.Literal("example_of"),
|
|
76
|
+
Type.Literal("tests"),
|
|
77
|
+
// Conversation & Reference
|
|
78
|
+
Type.Literal("responds_to"),
|
|
79
|
+
Type.Literal("references"),
|
|
80
|
+
Type.Literal("inspired_by"),
|
|
81
|
+
// Sequence & Flow
|
|
82
|
+
Type.Literal("follows"),
|
|
83
|
+
Type.Literal("precedes"),
|
|
84
|
+
// Dependencies & Composition
|
|
85
|
+
Type.Literal("depends_on"),
|
|
86
|
+
Type.Literal("composed_of"),
|
|
87
|
+
Type.Literal("part_of"),
|
|
88
|
+
], {
|
|
89
|
+
description: "Semantic relationship type connecting two memories",
|
|
90
|
+
examples: ["supports", "parent_of", "evolution_of", "example_of", "depends_on"],
|
|
91
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clawdbot Plugin API types for Penfield plugin
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for plugin interfaces.
|
|
5
|
+
* These types are adapted from @clawdbot/types for plugin use.
|
|
6
|
+
*/
|
|
7
|
+
export interface Logger {
|
|
8
|
+
info(...args: unknown[]): void;
|
|
9
|
+
warn(...args: unknown[]): void;
|
|
10
|
+
error(...args: unknown[]): void;
|
|
11
|
+
}
|
|
12
|
+
export interface ClawdbotPluginApi {
|
|
13
|
+
/** Plugin identifier */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Plugin name */
|
|
16
|
+
name: string;
|
|
17
|
+
/** Plugin version */
|
|
18
|
+
version?: string;
|
|
19
|
+
/** Plugin description */
|
|
20
|
+
description?: string;
|
|
21
|
+
/** Plugin source module */
|
|
22
|
+
source: string;
|
|
23
|
+
/** Raw config object */
|
|
24
|
+
config: Record<string, unknown>;
|
|
25
|
+
/** Parsed plugin configuration */
|
|
26
|
+
pluginConfig: Record<string, unknown>;
|
|
27
|
+
/** Get plugin config by ID */
|
|
28
|
+
getPluginConfig(id: string): Record<string, unknown> | undefined;
|
|
29
|
+
/** Resolve ~ paths to absolute paths */
|
|
30
|
+
resolvePath(input: string): string;
|
|
31
|
+
/** Logger instance */
|
|
32
|
+
logger: Logger;
|
|
33
|
+
/** Register CLI commands */
|
|
34
|
+
registerCli(fn: (ctx: ClawdbotCliContext) => void, opts?: {
|
|
35
|
+
commands?: string[];
|
|
36
|
+
}): void;
|
|
37
|
+
/** Register a tool with single-object parameter pattern */
|
|
38
|
+
registerTool(tool: {
|
|
39
|
+
name: string;
|
|
40
|
+
label: string;
|
|
41
|
+
description: string;
|
|
42
|
+
parameters: unknown;
|
|
43
|
+
execute: (toolCallId: string, input: unknown) => Promise<unknown>;
|
|
44
|
+
}): void;
|
|
45
|
+
/** Register service lifecycle */
|
|
46
|
+
registerService(service: {
|
|
47
|
+
id: string;
|
|
48
|
+
start?: () => Promise<void>;
|
|
49
|
+
stop?: () => Promise<void>;
|
|
50
|
+
}): void;
|
|
51
|
+
/** Runtime context (available in agent mode, not CLI) */
|
|
52
|
+
runtime?: {
|
|
53
|
+
prompter: {
|
|
54
|
+
info(msg: string): void;
|
|
55
|
+
warn(msg: string): void;
|
|
56
|
+
error(msg: string): void;
|
|
57
|
+
};
|
|
58
|
+
openUrl?: (url: string) => Promise<void>;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface ClawdbotCliContext {
|
|
62
|
+
program: {
|
|
63
|
+
command(name: string): ClawdbotCliCommand;
|
|
64
|
+
};
|
|
65
|
+
logger: Logger;
|
|
66
|
+
}
|
|
67
|
+
export interface ClawdbotCliCommand {
|
|
68
|
+
command(name: string): ClawdbotCliCommand;
|
|
69
|
+
description(msg: string): ClawdbotCliCommand;
|
|
70
|
+
action(fn: () => Promise<void>): ClawdbotCliCommand;
|
|
71
|
+
addHelpText(position: 'before' | 'after' | 'beforeAll' | 'afterAll', text: string | ((cmd: this) => string)): ClawdbotCliCommand;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation utilities for Penfield tools
|
|
3
|
+
*
|
|
4
|
+
* Defense-in-depth: Server validates too, but client-side validation
|
|
5
|
+
* provides better UX (fail fast) and prevents malformed requests.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validate that a string is a valid UUID format.
|
|
9
|
+
* Prevents path traversal attacks in URL interpolation.
|
|
10
|
+
*
|
|
11
|
+
* @throws Error if not a valid UUID
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateUuid(value: string, fieldName: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Validate artifact path for safety.
|
|
16
|
+
* Prevents path traversal and ensures proper format.
|
|
17
|
+
*
|
|
18
|
+
* @throws Error if path is invalid
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateArtifactPath(path: string): void;
|
|
21
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAInE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoBvD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation utilities for Penfield tools
|
|
3
|
+
*
|
|
4
|
+
* Defense-in-depth: Server validates too, but client-side validation
|
|
5
|
+
* provides better UX (fail fast) and prevents malformed requests.
|
|
6
|
+
*/
|
|
7
|
+
// UUID v4 format: 8-4-4-4-12 hex digits
|
|
8
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9
|
+
/**
|
|
10
|
+
* Validate that a string is a valid UUID format.
|
|
11
|
+
* Prevents path traversal attacks in URL interpolation.
|
|
12
|
+
*
|
|
13
|
+
* @throws Error if not a valid UUID
|
|
14
|
+
*/
|
|
15
|
+
export function validateUuid(value, fieldName) {
|
|
16
|
+
if (!UUID_REGEX.test(value)) {
|
|
17
|
+
throw new Error(`Invalid ${fieldName}: must be a valid UUID format`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validate artifact path for safety.
|
|
22
|
+
* Prevents path traversal and ensures proper format.
|
|
23
|
+
*
|
|
24
|
+
* @throws Error if path is invalid
|
|
25
|
+
*/
|
|
26
|
+
export function validateArtifactPath(path) {
|
|
27
|
+
if (!path || typeof path !== 'string') {
|
|
28
|
+
throw new Error('Artifact path is required');
|
|
29
|
+
}
|
|
30
|
+
if (path.includes('..')) {
|
|
31
|
+
throw new Error('Artifact path cannot contain ".." (path traversal not allowed)');
|
|
32
|
+
}
|
|
33
|
+
if (!path.startsWith('/')) {
|
|
34
|
+
throw new Error('Artifact path must be absolute (start with "/")');
|
|
35
|
+
}
|
|
36
|
+
// Prevent null bytes and other control characters
|
|
37
|
+
for (let i = 0; i < path.length; i++) {
|
|
38
|
+
const code = path.charCodeAt(i);
|
|
39
|
+
if (code < 32) {
|
|
40
|
+
throw new Error('Artifact path contains invalid characters');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|