psadk 1.3.6 → 1.4.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +150 -0
  3. package/build/main/lib/PSAI.d.ts +8 -1
  4. package/build/main/lib/PSAI.js +128 -75
  5. package/build/main/lib/PSAgent.js +77 -60
  6. package/build/main/lib/PSAgentConfig.d.ts +3 -0
  7. package/build/main/lib/PSAgentLogger.js +12 -9
  8. package/build/main/lib/PSAgentTask.js +4 -1
  9. package/build/main/lib/PSAgentTool.js +12 -2
  10. package/build/main/lib/agent-core/agent-loop.d.ts +23 -0
  11. package/build/main/lib/agent-core/agent-loop.js +479 -0
  12. package/build/main/lib/agent-core/agent.d.ts +124 -0
  13. package/build/main/lib/agent-core/agent.js +402 -0
  14. package/build/main/lib/agent-core/harness/agent-harness.d.ts +84 -0
  15. package/build/main/lib/agent-core/harness/agent-harness.js +728 -0
  16. package/build/main/lib/agent-core/harness/compaction/branch-summarization.d.ts +87 -0
  17. package/build/main/lib/agent-core/harness/compaction/branch-summarization.js +243 -0
  18. package/build/main/lib/agent-core/harness/compaction/compaction.d.ts +121 -0
  19. package/build/main/lib/agent-core/harness/compaction/compaction.js +616 -0
  20. package/build/main/lib/agent-core/harness/compaction/utils.d.ts +37 -0
  21. package/build/main/lib/agent-core/harness/compaction/utils.js +153 -0
  22. package/build/main/lib/agent-core/harness/env/nodejs.d.ts +43 -0
  23. package/build/main/lib/agent-core/harness/env/nodejs.js +348 -0
  24. package/build/main/lib/agent-core/harness/execution-env.d.ts +3 -0
  25. package/build/main/lib/agent-core/harness/execution-env.js +3 -0
  26. package/build/main/lib/agent-core/harness/messages.d.ts +50 -0
  27. package/build/main/lib/agent-core/harness/messages.js +102 -0
  28. package/build/main/lib/agent-core/harness/prompt-templates.d.ts +44 -0
  29. package/build/main/lib/agent-core/harness/prompt-templates.js +200 -0
  30. package/build/main/lib/agent-core/harness/session/repo/jsonl.d.ts +19 -0
  31. package/build/main/lib/agent-core/harness/session/repo/jsonl.js +92 -0
  32. package/build/main/lib/agent-core/harness/session/repo/memory.d.ts +17 -0
  33. package/build/main/lib/agent-core/harness/session/repo/memory.js +42 -0
  34. package/build/main/lib/agent-core/harness/session/repo/shared.d.ts +9 -0
  35. package/build/main/lib/agent-core/harness/session/repo/shared.js +31 -0
  36. package/build/main/lib/agent-core/harness/session/session.d.ts +31 -0
  37. package/build/main/lib/agent-core/harness/session/session.js +196 -0
  38. package/build/main/lib/agent-core/harness/session/storage/jsonl.d.ts +29 -0
  39. package/build/main/lib/agent-core/harness/session/storage/jsonl.js +170 -0
  40. package/build/main/lib/agent-core/harness/session/storage/memory.d.ts +25 -0
  41. package/build/main/lib/agent-core/harness/session/storage/memory.js +90 -0
  42. package/build/main/lib/agent-core/harness/skills.d.ts +40 -0
  43. package/build/main/lib/agent-core/harness/skills.js +259 -0
  44. package/build/main/lib/agent-core/harness/system-prompt.d.ts +2 -0
  45. package/build/main/lib/agent-core/harness/system-prompt.js +30 -0
  46. package/build/main/lib/agent-core/harness/types.d.ts +524 -0
  47. package/build/main/lib/agent-core/harness/types.js +16 -0
  48. package/build/main/lib/agent-core/harness/utils/shell-output.d.ts +13 -0
  49. package/build/main/lib/agent-core/harness/utils/shell-output.js +97 -0
  50. package/build/main/lib/agent-core/harness/utils/truncate.d.ts +69 -0
  51. package/build/main/lib/agent-core/harness/utils/truncate.js +205 -0
  52. package/build/main/lib/agent-core/index.d.ts +19 -0
  53. package/build/main/lib/agent-core/index.js +25 -0
  54. package/build/main/lib/agent-core/package.json +3 -0
  55. package/build/main/lib/agent-core/proxy.d.ts +68 -0
  56. package/build/main/lib/agent-core/proxy.js +278 -0
  57. package/build/main/lib/agent-core/types.d.ts +385 -0
  58. package/build/main/lib/agent-core/types.js +2 -0
  59. package/build/main/lib/skills/constants.js +6 -4
  60. package/build/main/lib/skills/skillParser.js +2 -2
  61. package/build/main/lib/skills/utils.js +8 -10
  62. package/build/main/lib/tools/BraveWebSearchTool.js +4 -3
  63. package/build/main/lib/tools/PSArtifactTool.js +3 -3
  64. package/build/main/lib/tools/PSClarifyTool.js +3 -2
  65. package/build/main/lib/tools/PSCommandLineTool.js +8 -7
  66. package/build/main/lib/tools/PSMemoryTool.js +9 -7
  67. package/build/main/lib/tools/PSReadFileTool.js +3 -3
  68. package/build/main/lib/tools/PSSkillTool.js +6 -4
  69. package/build/main/lib/tools/PSSubAgentTool.js +4 -5
  70. package/build/main/lib/tools/PSWriteFileTool.js +3 -3
  71. package/build/main/lib/tools/TodoTool.js +8 -4
  72. package/build/main/lib/utils/helpers.js +2 -13
  73. package/build/module/lib/PSAI.d.ts +8 -1
  74. package/build/module/lib/PSAI.js +115 -81
  75. package/build/module/lib/PSAgentConfig.d.ts +3 -0
  76. package/build/module/lib/agent-core/agent-loop.d.ts +23 -0
  77. package/build/module/lib/agent-core/agent-loop.js +479 -0
  78. package/build/module/lib/agent-core/agent.d.ts +124 -0
  79. package/build/module/lib/agent-core/agent.js +402 -0
  80. package/build/module/lib/agent-core/harness/agent-harness.d.ts +84 -0
  81. package/build/module/lib/agent-core/harness/agent-harness.js +728 -0
  82. package/build/module/lib/agent-core/harness/compaction/branch-summarization.d.ts +87 -0
  83. package/build/module/lib/agent-core/harness/compaction/branch-summarization.js +243 -0
  84. package/build/module/lib/agent-core/harness/compaction/compaction.d.ts +121 -0
  85. package/build/module/lib/agent-core/harness/compaction/compaction.js +616 -0
  86. package/build/module/lib/agent-core/harness/compaction/utils.d.ts +37 -0
  87. package/build/module/lib/agent-core/harness/compaction/utils.js +153 -0
  88. package/build/module/lib/agent-core/harness/env/nodejs.d.ts +43 -0
  89. package/build/module/lib/agent-core/harness/env/nodejs.js +348 -0
  90. package/build/module/lib/agent-core/harness/execution-env.d.ts +3 -0
  91. package/build/module/lib/agent-core/harness/execution-env.js +3 -0
  92. package/build/module/lib/agent-core/harness/messages.d.ts +50 -0
  93. package/build/module/lib/agent-core/harness/messages.js +102 -0
  94. package/build/module/lib/agent-core/harness/prompt-templates.d.ts +44 -0
  95. package/build/module/lib/agent-core/harness/prompt-templates.js +200 -0
  96. package/build/module/lib/agent-core/harness/session/repo/jsonl.d.ts +19 -0
  97. package/build/module/lib/agent-core/harness/session/repo/jsonl.js +92 -0
  98. package/build/module/lib/agent-core/harness/session/repo/memory.d.ts +17 -0
  99. package/build/module/lib/agent-core/harness/session/repo/memory.js +42 -0
  100. package/build/module/lib/agent-core/harness/session/repo/shared.d.ts +9 -0
  101. package/build/module/lib/agent-core/harness/session/repo/shared.js +31 -0
  102. package/build/module/lib/agent-core/harness/session/session.d.ts +31 -0
  103. package/build/module/lib/agent-core/harness/session/session.js +196 -0
  104. package/build/module/lib/agent-core/harness/session/storage/jsonl.d.ts +29 -0
  105. package/build/module/lib/agent-core/harness/session/storage/jsonl.js +170 -0
  106. package/build/module/lib/agent-core/harness/session/storage/memory.d.ts +25 -0
  107. package/build/module/lib/agent-core/harness/session/storage/memory.js +90 -0
  108. package/build/module/lib/agent-core/harness/skills.d.ts +40 -0
  109. package/build/module/lib/agent-core/harness/skills.js +259 -0
  110. package/build/module/lib/agent-core/harness/system-prompt.d.ts +2 -0
  111. package/build/module/lib/agent-core/harness/system-prompt.js +30 -0
  112. package/build/module/lib/agent-core/harness/types.d.ts +524 -0
  113. package/build/module/lib/agent-core/harness/types.js +16 -0
  114. package/build/module/lib/agent-core/harness/utils/shell-output.d.ts +13 -0
  115. package/build/module/lib/agent-core/harness/utils/shell-output.js +97 -0
  116. package/build/module/lib/agent-core/harness/utils/truncate.d.ts +69 -0
  117. package/build/module/lib/agent-core/harness/utils/truncate.js +205 -0
  118. package/build/module/lib/agent-core/index.d.ts +19 -0
  119. package/build/module/lib/agent-core/index.js +25 -0
  120. package/build/module/lib/agent-core/proxy.d.ts +68 -0
  121. package/build/module/lib/agent-core/proxy.js +278 -0
  122. package/build/module/lib/agent-core/types.d.ts +385 -0
  123. package/build/module/lib/agent-core/types.js +2 -0
  124. package/build/module/lib/tools/PSSkillTool.js +1 -1
  125. package/package.json +20 -3
@@ -0,0 +1,31 @@
1
+ import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
2
+ import type { AgentMessage } from "../../types.js";
3
+ import type { SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry } from "../types.js";
4
+ export declare function buildSessionContext(pathEntries: SessionTreeEntry[]): SessionContext;
5
+ export declare class Session<TMetadata extends SessionMetadata = SessionMetadata> {
6
+ private storage;
7
+ constructor(storage: SessionStorage<TMetadata>);
8
+ getMetadata(): Promise<TMetadata>;
9
+ getStorage(): SessionStorage<TMetadata>;
10
+ getLeafId(): Promise<string | null>;
11
+ getEntry(id: string): Promise<SessionTreeEntry | undefined>;
12
+ getEntries(): Promise<SessionTreeEntry[]>;
13
+ getBranch(fromId?: string): Promise<SessionTreeEntry[]>;
14
+ buildContext(): Promise<SessionContext>;
15
+ getLabel(id: string): Promise<string | undefined>;
16
+ getSessionName(): Promise<string | undefined>;
17
+ private appendTypedEntry;
18
+ appendMessage(message: AgentMessage): Promise<string>;
19
+ appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
20
+ appendModelChange(provider: string, modelId: string): Promise<string>;
21
+ appendCompaction<T = unknown>(summary: string, firstKeptEntryId: string, tokensBefore: number, details?: T, fromHook?: boolean): Promise<string>;
22
+ appendCustomEntry(customType: string, data?: unknown): Promise<string>;
23
+ appendCustomMessageEntry<T = unknown>(customType: string, content: string | (TextContent | ImageContent)[], display: boolean, details?: T): Promise<string>;
24
+ appendLabel(targetId: string, label: string | undefined): Promise<string>;
25
+ appendSessionName(name: string): Promise<string>;
26
+ moveTo(entryId: string | null, summary?: {
27
+ summary: string;
28
+ details?: unknown;
29
+ fromHook?: boolean;
30
+ }): Promise<string | undefined>;
31
+ }
@@ -0,0 +1,196 @@
1
+ import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from "../messages.js";
2
+ export function buildSessionContext(pathEntries) {
3
+ let thinkingLevel = "off";
4
+ let model = null;
5
+ let compaction = null;
6
+ for (const entry of pathEntries) {
7
+ if (entry.type === "thinking_level_change") {
8
+ thinkingLevel = entry.thinkingLevel;
9
+ }
10
+ else if (entry.type === "model_change") {
11
+ model = { provider: entry.provider, modelId: entry.modelId };
12
+ }
13
+ else if (entry.type === "message" && entry.message.role === "assistant") {
14
+ model = { provider: entry.message.provider, modelId: entry.message.model };
15
+ }
16
+ else if (entry.type === "compaction") {
17
+ compaction = entry;
18
+ }
19
+ }
20
+ const messages = [];
21
+ const appendMessage = (entry) => {
22
+ if (entry.type === "message") {
23
+ messages.push(entry.message);
24
+ }
25
+ else if (entry.type === "custom_message") {
26
+ messages.push(createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp));
27
+ }
28
+ else if (entry.type === "branch_summary" && entry.summary) {
29
+ messages.push(createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));
30
+ }
31
+ };
32
+ if (compaction) {
33
+ messages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));
34
+ const compactionIdx = pathEntries.findIndex((e) => e.type === "compaction" && e.id === compaction.id);
35
+ let foundFirstKept = false;
36
+ for (let i = 0; i < compactionIdx; i++) {
37
+ const entry = pathEntries[i];
38
+ if (entry.id === compaction.firstKeptEntryId)
39
+ foundFirstKept = true;
40
+ if (foundFirstKept)
41
+ appendMessage(entry);
42
+ }
43
+ for (let i = compactionIdx + 1; i < pathEntries.length; i++) {
44
+ appendMessage(pathEntries[i]);
45
+ }
46
+ }
47
+ else {
48
+ for (const entry of pathEntries) {
49
+ appendMessage(entry);
50
+ }
51
+ }
52
+ return { messages, thinkingLevel, model };
53
+ }
54
+ export class Session {
55
+ storage;
56
+ constructor(storage) {
57
+ this.storage = storage;
58
+ }
59
+ getMetadata() {
60
+ return this.storage.getMetadata();
61
+ }
62
+ getStorage() {
63
+ return this.storage;
64
+ }
65
+ getLeafId() {
66
+ return this.storage.getLeafId();
67
+ }
68
+ getEntry(id) {
69
+ return this.storage.getEntry(id);
70
+ }
71
+ getEntries() {
72
+ return this.storage.getEntries();
73
+ }
74
+ async getBranch(fromId) {
75
+ const leafId = fromId ?? (await this.storage.getLeafId());
76
+ return this.storage.getPathToRoot(leafId);
77
+ }
78
+ async buildContext() {
79
+ return buildSessionContext(await this.getBranch());
80
+ }
81
+ getLabel(id) {
82
+ return this.storage.getLabel(id);
83
+ }
84
+ async getSessionName() {
85
+ const entries = await this.storage.findEntries("session_info");
86
+ return entries[entries.length - 1]?.name?.trim() || undefined;
87
+ }
88
+ async appendTypedEntry(entry) {
89
+ await this.storage.appendEntry(entry);
90
+ return entry.id;
91
+ }
92
+ async appendMessage(message) {
93
+ return this.appendTypedEntry({
94
+ type: "message",
95
+ id: await this.storage.createEntryId(),
96
+ parentId: await this.storage.getLeafId(),
97
+ timestamp: new Date().toISOString(),
98
+ message,
99
+ });
100
+ }
101
+ async appendThinkingLevelChange(thinkingLevel) {
102
+ return this.appendTypedEntry({
103
+ type: "thinking_level_change",
104
+ id: await this.storage.createEntryId(),
105
+ parentId: await this.storage.getLeafId(),
106
+ timestamp: new Date().toISOString(),
107
+ thinkingLevel,
108
+ });
109
+ }
110
+ async appendModelChange(provider, modelId) {
111
+ return this.appendTypedEntry({
112
+ type: "model_change",
113
+ id: await this.storage.createEntryId(),
114
+ parentId: await this.storage.getLeafId(),
115
+ timestamp: new Date().toISOString(),
116
+ provider,
117
+ modelId,
118
+ });
119
+ }
120
+ async appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
121
+ return this.appendTypedEntry({
122
+ type: "compaction",
123
+ id: await this.storage.createEntryId(),
124
+ parentId: await this.storage.getLeafId(),
125
+ timestamp: new Date().toISOString(),
126
+ summary,
127
+ firstKeptEntryId,
128
+ tokensBefore,
129
+ details,
130
+ fromHook,
131
+ });
132
+ }
133
+ async appendCustomEntry(customType, data) {
134
+ return this.appendTypedEntry({
135
+ type: "custom",
136
+ id: await this.storage.createEntryId(),
137
+ parentId: await this.storage.getLeafId(),
138
+ timestamp: new Date().toISOString(),
139
+ customType,
140
+ data,
141
+ });
142
+ }
143
+ async appendCustomMessageEntry(customType, content, display, details) {
144
+ return this.appendTypedEntry({
145
+ type: "custom_message",
146
+ id: await this.storage.createEntryId(),
147
+ parentId: await this.storage.getLeafId(),
148
+ timestamp: new Date().toISOString(),
149
+ customType,
150
+ content,
151
+ display,
152
+ details,
153
+ });
154
+ }
155
+ async appendLabel(targetId, label) {
156
+ if (!(await this.storage.getEntry(targetId))) {
157
+ throw new Error(`Entry ${targetId} not found`);
158
+ }
159
+ return this.appendTypedEntry({
160
+ type: "label",
161
+ id: await this.storage.createEntryId(),
162
+ parentId: await this.storage.getLeafId(),
163
+ timestamp: new Date().toISOString(),
164
+ targetId,
165
+ label,
166
+ });
167
+ }
168
+ async appendSessionName(name) {
169
+ return this.appendTypedEntry({
170
+ type: "session_info",
171
+ id: await this.storage.createEntryId(),
172
+ parentId: await this.storage.getLeafId(),
173
+ timestamp: new Date().toISOString(),
174
+ name: name.trim(),
175
+ });
176
+ }
177
+ async moveTo(entryId, summary) {
178
+ if (entryId !== null && !(await this.storage.getEntry(entryId))) {
179
+ throw new Error(`Entry ${entryId} not found`);
180
+ }
181
+ await this.storage.setLeafId(entryId);
182
+ if (!summary)
183
+ return undefined;
184
+ return this.appendTypedEntry({
185
+ type: "branch_summary",
186
+ id: await this.storage.createEntryId(),
187
+ parentId: entryId,
188
+ timestamp: new Date().toISOString(),
189
+ fromId: entryId ?? "root",
190
+ summary: summary.summary,
191
+ details: summary.details,
192
+ fromHook: summary.fromHook,
193
+ });
194
+ }
195
+ }
196
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvYWdlbnQtY29yZS9oYXJuZXNzL3Nlc3Npb24vc2Vzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsOEJBQThCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQWlCakgsTUFBTSxVQUFVLG1CQUFtQixDQUFDLFdBQStCO0lBQ2xFLElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQztJQUMxQixJQUFJLEtBQUssR0FBaUQsSUFBSSxDQUFDO0lBQy9ELElBQUksVUFBVSxHQUEyQixJQUFJLENBQUM7SUFFOUMsS0FBSyxNQUFNLEtBQUssSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNqQyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssdUJBQXVCLEVBQUUsQ0FBQztZQUM1QyxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQztRQUNyQyxDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGNBQWMsRUFBRSxDQUFDO1lBQzFDLEtBQUssR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUQsQ0FBQzthQUFNLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDM0UsS0FBSyxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzVFLENBQUM7YUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDeEMsVUFBVSxHQUFHLEtBQUssQ0FBQztR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
@@ -0,0 +1,29 @@
1
+ import type { JsonlSessionMetadata, SessionStorage, SessionTreeEntry } from "../../types.js";
2
+ export declare function loadJsonlSessionMetadata(filePath: string): Promise<JsonlSessionMetadata>;
3
+ export declare class JsonlSessionStorage implements SessionStorage<JsonlSessionMetadata> {
4
+ private readonly filePath;
5
+ private readonly metadata;
6
+ private entries;
7
+ private byId;
8
+ private labelsById;
9
+ private currentLeafId;
10
+ private constructor();
11
+ static open(filePath: string): Promise<JsonlSessionStorage>;
12
+ static create(filePath: string, options: {
13
+ cwd: string;
14
+ sessionId: string;
15
+ parentSessionPath?: string;
16
+ }): Promise<JsonlSessionStorage>;
17
+ getMetadata(): Promise<JsonlSessionMetadata>;
18
+ getLeafId(): Promise<string | null>;
19
+ setLeafId(leafId: string | null): Promise<void>;
20
+ createEntryId(): Promise<string>;
21
+ appendEntry(entry: SessionTreeEntry): Promise<void>;
22
+ getEntry(id: string): Promise<SessionTreeEntry | undefined>;
23
+ findEntries<TType extends SessionTreeEntry["type"]>(type: TType): Promise<Array<Extract<SessionTreeEntry, {
24
+ type: TType;
25
+ }>>>;
26
+ getLabel(id: string): Promise<string | undefined>;
27
+ getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
28
+ getEntries(): Promise<SessionTreeEntry[]>;
29
+ }
@@ -0,0 +1,170 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { createReadStream } from "node:fs";
3
+ import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
4
+ import { dirname, resolve } from "node:path";
5
+ import { createInterface } from "node:readline";
6
+ function updateLabelCache(labelsById, entry) {
7
+ if (entry.type !== "label")
8
+ return;
9
+ const label = entry.label?.trim();
10
+ if (label) {
11
+ labelsById.set(entry.targetId, label);
12
+ }
13
+ else {
14
+ labelsById.delete(entry.targetId);
15
+ }
16
+ }
17
+ function buildLabelsById(entries) {
18
+ const labelsById = new Map();
19
+ for (const entry of entries) {
20
+ updateLabelCache(labelsById, entry);
21
+ }
22
+ return labelsById;
23
+ }
24
+ function generateEntryId(byId) {
25
+ for (let i = 0; i < 100; i++) {
26
+ const id = randomUUID().slice(0, 8);
27
+ if (!byId.has(id))
28
+ return id;
29
+ }
30
+ return randomUUID();
31
+ }
32
+ function headerToSessionMetadata(header, path) {
33
+ return {
34
+ id: header.id,
35
+ createdAt: header.timestamp,
36
+ cwd: header.cwd,
37
+ path,
38
+ parentSessionPath: header.parentSession,
39
+ };
40
+ }
41
+ export async function loadJsonlSessionMetadata(filePath) {
42
+ const stream = createReadStream(filePath, { encoding: "utf8" });
43
+ const lines = createInterface({ input: stream, crlfDelay: Infinity });
44
+ try {
45
+ for await (const line of lines) {
46
+ if (!line.trim())
47
+ break;
48
+ try {
49
+ const header = JSON.parse(line);
50
+ return headerToSessionMetadata(header, resolve(filePath));
51
+ }
52
+ catch {
53
+ throw new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);
54
+ }
55
+ }
56
+ throw new Error(`Invalid JSONL session file ${filePath}: missing session header`);
57
+ }
58
+ finally {
59
+ lines.close();
60
+ stream.destroy();
61
+ }
62
+ }
63
+ async function loadJsonlStorage(filePath) {
64
+ const content = await readFile(filePath, "utf8");
65
+ const lines = content.split("\n").filter((line) => line.trim());
66
+ if (lines.length === 0) {
67
+ throw new Error(`Invalid JSONL session file ${filePath}: missing session header`);
68
+ }
69
+ let header;
70
+ try {
71
+ header = JSON.parse(lines[0]);
72
+ }
73
+ catch {
74
+ throw new Error(`Invalid JSONL session file ${filePath}: first line is not a valid session header`);
75
+ }
76
+ const entries = [];
77
+ let leafId = null;
78
+ for (const line of lines.slice(1)) {
79
+ try {
80
+ const entry = JSON.parse(line);
81
+ entries.push(entry);
82
+ leafId = entry.id;
83
+ }
84
+ catch {
85
+ // ignore malformed entry lines
86
+ }
87
+ }
88
+ return { header, entries, leafId };
89
+ }
90
+ export class JsonlSessionStorage {
91
+ filePath;
92
+ metadata;
93
+ entries;
94
+ byId;
95
+ labelsById;
96
+ currentLeafId;
97
+ constructor(filePath, header, entries, leafId) {
98
+ this.filePath = resolve(filePath);
99
+ this.metadata = headerToSessionMetadata(header, this.filePath);
100
+ this.entries = entries;
101
+ this.byId = new Map(entries.map((entry) => [entry.id, entry]));
102
+ this.labelsById = buildLabelsById(entries);
103
+ this.currentLeafId = leafId;
104
+ }
105
+ static async open(filePath) {
106
+ const resolvedPath = resolve(filePath);
107
+ const loaded = await loadJsonlStorage(resolvedPath);
108
+ return new JsonlSessionStorage(resolvedPath, loaded.header, loaded.entries, loaded.leafId);
109
+ }
110
+ static async create(filePath, options) {
111
+ const resolvedPath = resolve(filePath);
112
+ const header = {
113
+ type: "session",
114
+ version: 3,
115
+ id: options.sessionId,
116
+ timestamp: new Date().toISOString(),
117
+ cwd: options.cwd,
118
+ parentSession: options.parentSessionPath,
119
+ };
120
+ await mkdir(dirname(resolvedPath), { recursive: true });
121
+ await writeFile(resolvedPath, `${JSON.stringify(header)}\n`);
122
+ return new JsonlSessionStorage(resolvedPath, header, [], null);
123
+ }
124
+ async getMetadata() {
125
+ return this.metadata;
126
+ }
127
+ async getLeafId() {
128
+ return this.currentLeafId;
129
+ }
130
+ async setLeafId(leafId) {
131
+ if (leafId !== null && !this.byId.has(leafId)) {
132
+ throw new Error(`Entry ${leafId} not found`);
133
+ }
134
+ this.currentLeafId = leafId;
135
+ }
136
+ async createEntryId() {
137
+ return generateEntryId(this.byId);
138
+ }
139
+ async appendEntry(entry) {
140
+ await appendFile(this.filePath, `${JSON.stringify(entry)}\n`);
141
+ this.entries.push(entry);
142
+ this.byId.set(entry.id, entry);
143
+ updateLabelCache(this.labelsById, entry);
144
+ this.currentLeafId = entry.id;
145
+ }
146
+ async getEntry(id) {
147
+ return this.byId.get(id);
148
+ }
149
+ async findEntries(type) {
150
+ return this.entries.filter((entry) => entry.type === type);
151
+ }
152
+ async getLabel(id) {
153
+ return this.labelsById.get(id);
154
+ }
155
+ async getPathToRoot(leafId) {
156
+ if (leafId === null)
157
+ return [];
158
+ const path = [];
159
+ let current = this.byId.get(leafId);
160
+ while (current) {
161
+ path.unshift(current);
162
+ current = current.parentId ? this.byId.get(current.parentId) : undefined;
163
+ }
164
+ return path;
165
+ }
166
+ async getEntries() {
167
+ return [...this.entries];
168
+ }
169
+ }
170
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbmwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2FnZW50LWNvcmUvaGFybmVzcy9zZXNzaW9uL3N0b3JhZ2UvanNvbmwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFZaEQsU0FBUyxnQkFBZ0IsQ0FBQyxVQUErQixFQUFFLEtBQXVCO0lBQ2pGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPO1FBQUUsT0FBTztJQUNuQyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ2xDLElBQUksS0FBSyxFQUFFLENBQUM7UUFDWCxVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdkMsQ0FBQztTQUFNLENBQUM7UUFDUCxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxDQUFDO0FBQ0YsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLE9BQTJCO0lBQ25ELE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQzdDLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFDRCxPQUFPLFVB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
@@ -0,0 +1,25 @@
1
+ import type { SessionMetadata, SessionStorage, SessionTreeEntry } from "../../types.js";
2
+ export declare class InMemorySessionStorage implements SessionStorage {
3
+ private readonly metadata;
4
+ private entries;
5
+ private byId;
6
+ private labelsById;
7
+ private leafId;
8
+ constructor(options?: {
9
+ entries?: SessionTreeEntry[];
10
+ leafId?: string | null;
11
+ metadata?: SessionMetadata;
12
+ });
13
+ getMetadata(): Promise<SessionMetadata>;
14
+ getLeafId(): Promise<string | null>;
15
+ setLeafId(leafId: string | null): Promise<void>;
16
+ createEntryId(): Promise<string>;
17
+ appendEntry(entry: SessionTreeEntry): Promise<void>;
18
+ getEntry(id: string): Promise<SessionTreeEntry | undefined>;
19
+ findEntries<TType extends SessionTreeEntry["type"]>(type: TType): Promise<Array<Extract<SessionTreeEntry, {
20
+ type: TType;
21
+ }>>>;
22
+ getLabel(id: string): Promise<string | undefined>;
23
+ getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
24
+ getEntries(): Promise<SessionTreeEntry[]>;
25
+ }
@@ -0,0 +1,90 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { v7 as uuidv7 } from "uuid";
3
+ function updateLabelCache(labelsById, entry) {
4
+ if (entry.type !== "label")
5
+ return;
6
+ const label = entry.label?.trim();
7
+ if (label) {
8
+ labelsById.set(entry.targetId, label);
9
+ }
10
+ else {
11
+ labelsById.delete(entry.targetId);
12
+ }
13
+ }
14
+ function buildLabelsById(entries) {
15
+ const labelsById = new Map();
16
+ for (const entry of entries) {
17
+ updateLabelCache(labelsById, entry);
18
+ }
19
+ return labelsById;
20
+ }
21
+ function generateEntryId(byId) {
22
+ for (let i = 0; i < 100; i++) {
23
+ const id = randomUUID().slice(0, 8);
24
+ if (!byId.has(id))
25
+ return id;
26
+ }
27
+ return randomUUID();
28
+ }
29
+ export class InMemorySessionStorage {
30
+ metadata;
31
+ entries;
32
+ byId;
33
+ labelsById;
34
+ leafId;
35
+ constructor(options) {
36
+ this.entries = options?.entries ? [...options.entries] : [];
37
+ this.byId = new Map(this.entries.map((entry) => [entry.id, entry]));
38
+ this.labelsById = buildLabelsById(this.entries);
39
+ this.leafId = options?.leafId ?? this.entries[this.entries.length - 1]?.id ?? null;
40
+ if (this.leafId !== null && !this.byId.has(this.leafId)) {
41
+ throw new Error(`Entry ${this.leafId} not found`);
42
+ }
43
+ this.metadata = options?.metadata ?? { id: uuidv7(), createdAt: new Date().toISOString() };
44
+ }
45
+ async getMetadata() {
46
+ return this.metadata;
47
+ }
48
+ async getLeafId() {
49
+ return this.leafId;
50
+ }
51
+ async setLeafId(leafId) {
52
+ if (leafId !== null && !this.byId.has(leafId)) {
53
+ throw new Error(`Entry ${leafId} not found`);
54
+ }
55
+ this.leafId = leafId;
56
+ }
57
+ async createEntryId() {
58
+ return generateEntryId(this.byId);
59
+ }
60
+ async appendEntry(entry) {
61
+ this.entries.push(entry);
62
+ this.byId.set(entry.id, entry);
63
+ updateLabelCache(this.labelsById, entry);
64
+ this.leafId = entry.id;
65
+ }
66
+ async getEntry(id) {
67
+ return this.byId.get(id);
68
+ }
69
+ async findEntries(type) {
70
+ return this.entries.filter((entry) => entry.type === type);
71
+ }
72
+ async getLabel(id) {
73
+ return this.labelsById.get(id);
74
+ }
75
+ async getPathToRoot(leafId) {
76
+ if (leafId === null)
77
+ return [];
78
+ const path = [];
79
+ let current = this.byId.get(leafId);
80
+ while (current) {
81
+ path.unshift(current);
82
+ current = current.parentId ? this.byId.get(current.parentId) : undefined;
83
+ }
84
+ return path;
85
+ }
86
+ async getEntries() {
87
+ return [...this.entries];
88
+ }
89
+ }
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9hZ2VudC1jb3JlL2hhcm5lc3Mvc2Vzc2lvbi9zdG9yYWdlL21lbW9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxFQUFFLElBQUksTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLFNBQVMsZ0JBQWdCLENBQUMsVUFBK0IsRUFBRSxLQUF1QjtJQUNqRixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTztRQUFFLE9BQU87SUFDbkMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNsQyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1gsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7U0FBTSxDQUFDO1FBQ1AsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkMsQ0FBQztBQUNGLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxPQUEyQjtJQUNuRCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUM3QyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzdCLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDbkIsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLElBQWtDO0lBQzFELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUM5QixNQUFNLEVBQUUsR0FBRyxVQUFVLEVBQUUsQ0FB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
@@ -0,0 +1,40 @@
1
+ import type { ExecutionEnv, Skill } from "./types.js";
2
+ /** Warning produced while loading skills. */
3
+ export interface SkillDiagnostic {
4
+ /** Diagnostic severity. Currently only warnings are emitted. */
5
+ type: "warning";
6
+ /** Human-readable diagnostic message. */
7
+ message: string;
8
+ /** Path associated with the diagnostic. */
9
+ path: string;
10
+ }
11
+ /** Format a skill invocation prompt, optionally appending additional user instructions. */
12
+ export declare function formatSkillInvocation(skill: Skill, additionalInstructions?: string): string;
13
+ /**
14
+ * Load skills from one or more directories.
15
+ *
16
+ * Traverses directories recursively, loads `SKILL.md` files, loads direct root `.md` files as skills, honors ignore files,
17
+ * and returns diagnostics for invalid skill files. Missing input directories are skipped.
18
+ */
19
+ export declare function loadSkills(env: ExecutionEnv, dirs: string | string[]): Promise<{
20
+ skills: Skill[];
21
+ diagnostics: SkillDiagnostic[];
22
+ }>;
23
+ /**
24
+ * Load skills from source-tagged directories.
25
+ *
26
+ * Source values are preserved exactly and attached to every loaded skill and diagnostic. The agent package does not
27
+ * interpret source values; applications define their own provenance shape.
28
+ */
29
+ export declare function loadSourcedSkills<TSource, TSkill extends Skill = Skill>(env: ExecutionEnv, inputs: Array<{
30
+ path: string;
31
+ source: TSource;
32
+ }>, mapSkill?: (skill: Skill, source: TSource) => TSkill): Promise<{
33
+ skills: Array<{
34
+ skill: TSkill;
35
+ source: TSource;
36
+ }>;
37
+ diagnostics: Array<SkillDiagnostic & {
38
+ source: TSource;
39
+ }>;
40
+ }>;