@hasna/brains 0.0.7 → 0.0.8

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.
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromAssistants(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=assistants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistants.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/assistants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAwC/F"}
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromEconomy(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=economy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"economy.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/economy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiD5F"}
@@ -4,6 +4,8 @@ import { gatherFromConversations } from "./conversations.js";
4
4
  import { gatherFromSessions } from "./sessions.js";
5
5
  import type { GatherResult, GathererOptions } from "./types.js";
6
6
  export * from "./types.js";
7
+ export * from "./protocol.js";
8
+ export * from "./registry.js";
7
9
  export { gatherFromTodos, gatherFromMementos, gatherFromConversations, gatherFromSessions };
8
10
  export declare function gatherAll(sources: string[], options?: GathererOptions): Promise<GatherResult[]>;
9
11
  export declare function mergeAndWriteJSONL(results: GatherResult[], outputPath?: string): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAEjF,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC;AAK5F,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,YAAY,EAAE,CAAC,CAkBzB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B7E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGjF,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC;AAE5F,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,YAAY,EAAE,CAAC,CAezB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B7E"}
@@ -0,0 +1,29 @@
1
+ import type { GathererOptions, GatherResult } from "./types.js";
2
+ /**
3
+ * A function that gathers training examples from a data source.
4
+ * Implemented by each open-* repo and exported from their SDK.
5
+ *
6
+ * @example
7
+ * // In open-styles:
8
+ * export const gatherTrainingData: GatherTrainingDataFn = async (options) => { ... }
9
+ *
10
+ * // In open-brains gatherer registry:
11
+ * import { gatherTrainingData } from "@hasnaxyz/styles";
12
+ * registerGatherer("styles", gatherTrainingData);
13
+ */
14
+ export type GatherTrainingDataFn = (options?: GathererOptions) => Promise<GatherResult>;
15
+ /**
16
+ * A named, registered training data provider.
17
+ * Used by the gatherer registry to map source names to gatherer functions.
18
+ */
19
+ export interface TrainingDataProvider {
20
+ /** Source name used in `brains data gather --source <name>` */
21
+ name: string;
22
+ /** The gather function — imported from the repo's SDK */
23
+ gather: GatherTrainingDataFn;
24
+ /** Human-readable description shown in `brains data gather --list` */
25
+ description: string;
26
+ /** Optional: package name of the SDK this gatherer comes from */
27
+ package?: string;
28
+ }
29
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/protocol.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAExF;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE,oBAAoB,CAAC;IAC7B,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromRecordings(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=recordings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordings.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/recordings.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8C/F"}
@@ -0,0 +1,7 @@
1
+ import type { GatherTrainingDataFn, TrainingDataProvider } from "./protocol.js";
2
+ export declare function registerGatherer(provider: TrainingDataProvider): void;
3
+ export declare function getRegisteredSources(): string[];
4
+ export declare function getGatherer(name: string): GatherTrainingDataFn | undefined;
5
+ export declare function getProvider(name: string): TrainingDataProvider | undefined;
6
+ export declare function getAllProviders(): TrainingDataProvider[];
7
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAchF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAErE;AAED,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAE1E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAE1E;AAED,wBAAgB,eAAe,IAAI,oBAAoB,EAAE,CAExD"}
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromResearcher(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=researcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"researcher.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/researcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgD/F"}
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromStyles(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/styles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CA2D3F"}
@@ -0,0 +1,3 @@
1
+ import type { GatherResult, GathererOptions } from "./types.js";
2
+ export declare function gatherFromTickets(options?: GathererOptions): Promise<GatherResult>;
3
+ //# sourceMappingURL=tickets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.d.ts","sourceRoot":"","sources":["../../../src/lib/gatherers/tickets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAIjF,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkC5F"}
@@ -1,6 +1,21 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
3
5
  var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __toESM = (mod, isNodeMode, target) => {
9
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
10
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
+ for (let key of __getOwnPropNames(mod))
12
+ if (!__hasOwnProp.call(to, key))
13
+ __defProp(to, key, {
14
+ get: () => mod[key],
15
+ enumerable: true
16
+ });
17
+ return to;
18
+ };
4
19
  var __export = (target, all) => {
5
20
  for (var name in all)
6
21
  __defProp(target, name, {
@@ -10,6 +25,7 @@ var __export = (target, all) => {
10
25
  set: (newValue) => all[name] = () => newValue
11
26
  });
12
27
  };
28
+ var __require = import.meta.require;
13
29
 
14
30
  // node_modules/drizzle-orm/entity.js
15
31
  var entityKind = Symbol.for("drizzle:entityKind");
@@ -4147,23 +4163,336 @@ async function gatherFromSessions(options = {}) {
4147
4163
  }
4148
4164
  return { source: "sessions", examples, count: examples.length };
4149
4165
  }
4166
+
4167
+ // src/lib/gatherers/styles.ts
4168
+ var SYSTEM_PROMPT5 = "You are a design-aware AI assistant with knowledge of the user's style preferences, design system, and visual identity. You help apply consistent styling across projects.";
4169
+ async function gatherFromStyles(options = {}) {
4170
+ let sdk;
4171
+ try {
4172
+ sdk = await import("@hasnaxyz/styles");
4173
+ } catch {
4174
+ return { source: "styles", examples: [], count: 0 };
4175
+ }
4176
+ const sdkAny = sdk;
4177
+ if (typeof sdkAny["gatherTrainingData"] === "function") {
4178
+ return sdkAny["gatherTrainingData"](options);
4179
+ }
4180
+ const examples = [];
4181
+ const limit = options.limit ?? 500;
4182
+ try {
4183
+ if (typeof sdk.listProfiles === "function") {
4184
+ const profiles = await sdk.listProfiles();
4185
+ for (const profile of profiles.slice(0, Math.floor(limit / 3))) {
4186
+ const p = profile;
4187
+ examples.push({
4188
+ messages: [
4189
+ { role: "system", content: SYSTEM_PROMPT5 },
4190
+ { role: "user", content: `What are the style settings in the "${String(p["name"] ?? "default")}" profile?` },
4191
+ { role: "assistant", content: `Style profile "${String(p["name"] ?? "default")}": ${JSON.stringify(p, null, 2)}` }
4192
+ ]
4193
+ });
4194
+ }
4195
+ }
4196
+ if (typeof sdk.listPrefs === "function") {
4197
+ const prefs = await sdk.listPrefs();
4198
+ for (const pref of prefs.slice(0, Math.floor(limit / 3))) {
4199
+ const pr = pref;
4200
+ examples.push({
4201
+ messages: [
4202
+ { role: "system", content: SYSTEM_PROMPT5 },
4203
+ { role: "user", content: `What is my preference for "${String(pr["key"] ?? pr["name"] ?? "style")}"?` },
4204
+ { role: "assistant", content: `Your preference: ${String(pr["value"] ?? JSON.stringify(pr))}` }
4205
+ ]
4206
+ });
4207
+ }
4208
+ }
4209
+ } catch {}
4210
+ const finalExamples = examples.slice(0, limit);
4211
+ return { source: "styles", examples: finalExamples, count: finalExamples.length };
4212
+ }
4213
+
4214
+ // src/lib/gatherers/researcher.ts
4215
+ var SYSTEM_PROMPT6 = "You are a scientific research assistant that helps design experiments, form hypotheses, and interpret results.";
4216
+ async function gatherFromResearcher(options = {}) {
4217
+ let sdk;
4218
+ try {
4219
+ sdk = await import("@hasna/researcher");
4220
+ } catch {
4221
+ return { source: "researcher", examples: [], count: 0 };
4222
+ }
4223
+ if (typeof sdk["gatherTrainingData"] === "function") {
4224
+ return sdk["gatherTrainingData"](options);
4225
+ }
4226
+ const examples = [];
4227
+ const limit = options.limit ?? 500;
4228
+ try {
4229
+ if (typeof sdk["listProjects"] === "function") {
4230
+ const projects = await sdk["listProjects"]();
4231
+ for (const proj of projects.slice(0, Math.floor(limit / 2))) {
4232
+ const p = proj;
4233
+ examples.push({
4234
+ messages: [
4235
+ { role: "system", content: SYSTEM_PROMPT6 },
4236
+ { role: "user", content: `Summarize the research project "${String(p["name"] ?? p["id"])}"` },
4237
+ { role: "assistant", content: `Project "${String(p["name"] ?? p["id"])}": ${String(p["description"] ?? JSON.stringify(p))}` }
4238
+ ]
4239
+ });
4240
+ }
4241
+ }
4242
+ if (typeof sdk["listResults"] === "function") {
4243
+ const results = await sdk["listResults"]();
4244
+ for (const result of results.slice(0, Math.floor(limit / 2))) {
4245
+ const r = result;
4246
+ examples.push({
4247
+ messages: [
4248
+ { role: "system", content: SYSTEM_PROMPT6 },
4249
+ { role: "user", content: `What were the results of experiment "${String(r["name"] ?? r["id"])}"?` },
4250
+ { role: "assistant", content: `Result: ${String(r["summary"] ?? r["output"] ?? JSON.stringify(r))}` }
4251
+ ]
4252
+ });
4253
+ }
4254
+ }
4255
+ } catch {}
4256
+ const finalExamples = examples.slice(0, limit);
4257
+ return { source: "researcher", examples: finalExamples, count: finalExamples.length };
4258
+ }
4259
+
4260
+ // src/lib/gatherers/tickets.ts
4261
+ var SYSTEM_PROMPT7 = "You are an issue management assistant that triages bugs, prioritizes features, and tracks incident resolutions.";
4262
+ async function gatherFromTickets(options = {}) {
4263
+ let sdk;
4264
+ try {
4265
+ sdk = await import("@hasna/tickets");
4266
+ } catch {
4267
+ return { source: "tickets", examples: [], count: 0 };
4268
+ }
4269
+ if (typeof sdk["gatherTrainingData"] === "function") {
4270
+ return sdk["gatherTrainingData"](options);
4271
+ }
4272
+ const examples = [];
4273
+ const limit = options.limit ?? 500;
4274
+ try {
4275
+ if (typeof sdk["listTickets"] === "function") {
4276
+ const tickets = await sdk["listTickets"]();
4277
+ for (const ticket of tickets.slice(0, limit)) {
4278
+ const t = ticket;
4279
+ examples.push({
4280
+ messages: [
4281
+ { role: "system", content: SYSTEM_PROMPT7 },
4282
+ { role: "user", content: `What is the status of ticket "${String(t["title"] ?? t["id"])}"?` },
4283
+ { role: "assistant", content: `Ticket "${String(t["title"] ?? t["id"])}" [${String(t["status"] ?? "open")}/${String(t["priority"] ?? "medium")}]: ${String(t["description"] ?? "(no description)")}` }
4284
+ ]
4285
+ });
4286
+ }
4287
+ }
4288
+ } catch {}
4289
+ const finalExamples = examples.slice(0, limit);
4290
+ return { source: "tickets", examples: finalExamples, count: finalExamples.length };
4291
+ }
4292
+
4293
+ // src/lib/gatherers/economy.ts
4294
+ var SYSTEM_PROMPT8 = "You are a cost-aware AI assistant that tracks API usage, identifies expensive patterns, and helps optimize AI spending.";
4295
+ async function gatherFromEconomy(options = {}) {
4296
+ let sdk;
4297
+ try {
4298
+ sdk = await import("@hasna/economy");
4299
+ } catch {
4300
+ return { source: "economy", examples: [], count: 0 };
4301
+ }
4302
+ if (typeof sdk["gatherTrainingData"] === "function") {
4303
+ return sdk["gatherTrainingData"](options);
4304
+ }
4305
+ const examples = [];
4306
+ const limit = options.limit ?? 500;
4307
+ try {
4308
+ const listSessions = sdk["listSessions"] ?? sdk["getSessions"] ?? sdk["getCostSummary"];
4309
+ if (typeof listSessions === "function") {
4310
+ const sessions = await listSessions();
4311
+ const items = Array.isArray(sessions) ? sessions : [sessions];
4312
+ for (const session of items.slice(0, Math.floor(limit / 2))) {
4313
+ const s = session;
4314
+ examples.push({
4315
+ messages: [
4316
+ { role: "system", content: SYSTEM_PROMPT8 },
4317
+ { role: "user", content: `How much did session "${String(s["session_id"] ?? s["id"] ?? "unknown")}" cost?` },
4318
+ { role: "assistant", content: `Session cost: $${String(s["total_cost"] ?? s["cost"] ?? "0.00")} \u2014 ${String(s["model"] ?? "unknown model")}, ${String(s["total_tokens"] ?? s["tokens"] ?? "?")} tokens` }
4319
+ ]
4320
+ });
4321
+ }
4322
+ }
4323
+ const getModelBreakdown = sdk["getModelBreakdown"];
4324
+ if (typeof getModelBreakdown === "function") {
4325
+ const breakdown = await getModelBreakdown();
4326
+ examples.push({
4327
+ messages: [
4328
+ { role: "system", content: SYSTEM_PROMPT8 },
4329
+ { role: "user", content: "Which AI models have I spent the most on?" },
4330
+ { role: "assistant", content: `Model cost breakdown: ${JSON.stringify(breakdown, null, 2)}` }
4331
+ ]
4332
+ });
4333
+ }
4334
+ } catch {}
4335
+ const finalExamples = examples.slice(0, limit);
4336
+ return { source: "economy", examples: finalExamples, count: finalExamples.length };
4337
+ }
4338
+
4339
+ // src/lib/gatherers/recordings.ts
4340
+ var SYSTEM_PROMPT9 = "You are a voice-aware AI assistant that transcribes, searches, and summarizes audio recordings.";
4341
+ async function gatherFromRecordings(options = {}) {
4342
+ let sdk;
4343
+ try {
4344
+ sdk = await import("@hasna/recordings");
4345
+ } catch {
4346
+ return { source: "recordings", examples: [], count: 0 };
4347
+ }
4348
+ if (typeof sdk["gatherTrainingData"] === "function") {
4349
+ return sdk["gatherTrainingData"](options);
4350
+ }
4351
+ const examples = [];
4352
+ const limit = options.limit ?? 500;
4353
+ try {
4354
+ if (typeof sdk["listRecordings"] === "function") {
4355
+ const recordings = await sdk["listRecordings"]();
4356
+ for (const rec of recordings.slice(0, limit)) {
4357
+ const r = rec;
4358
+ if (r["transcription"] || r["transcript"]) {
4359
+ const transcript = String(r["transcription"] ?? r["transcript"]);
4360
+ examples.push({
4361
+ messages: [
4362
+ { role: "system", content: SYSTEM_PROMPT9 },
4363
+ { role: "user", content: `Summarize the recording "${String(r["fileName"] ?? r["name"] ?? r["id"])}"` },
4364
+ { role: "assistant", content: transcript.slice(0, 2000) }
4365
+ ]
4366
+ });
4367
+ const words = transcript.split(" ").slice(0, 3).join(" ");
4368
+ examples.push({
4369
+ messages: [
4370
+ { role: "system", content: SYSTEM_PROMPT9 },
4371
+ { role: "user", content: `Find recordings mentioning "${words}"` },
4372
+ { role: "assistant", content: `Found recording: "${String(r["fileName"] ?? r["name"])}" \u2014 ${new Date(Number(r["createdAt"] ?? Date.now())).toLocaleDateString()}` }
4373
+ ]
4374
+ });
4375
+ }
4376
+ }
4377
+ }
4378
+ } catch {}
4379
+ const finalExamples = examples.slice(0, limit);
4380
+ return { source: "recordings", examples: finalExamples, count: finalExamples.length };
4381
+ }
4382
+
4383
+ // src/lib/gatherers/assistants.ts
4384
+ var SYSTEM_PROMPT10 = "You are a personal AI assistant with full context of the user's work environment, preferences, ongoing tasks, contacts, and projects.";
4385
+ async function gatherFromAssistants(options = {}) {
4386
+ let sdk;
4387
+ try {
4388
+ sdk = await import("@hasna/assistants");
4389
+ } catch {
4390
+ return { source: "assistants", examples: [], count: 0 };
4391
+ }
4392
+ if (typeof sdk["gatherTrainingData"] === "function") {
4393
+ return sdk["gatherTrainingData"](options);
4394
+ }
4395
+ const examples = [];
4396
+ const limit = options.limit ?? 500;
4397
+ try {
4398
+ const listSessions = sdk["listSessions"] ?? sdk["getSessions"];
4399
+ if (typeof listSessions === "function") {
4400
+ const sessions = await listSessions();
4401
+ for (const session of sessions.slice(0, Math.floor(limit / 2))) {
4402
+ const s = session;
4403
+ const messages = s["messages"];
4404
+ if (messages && messages.length >= 2) {
4405
+ const turns = messages.filter((m) => m["role"] === "user" || m["role"] === "assistant").slice(0, 6).map((m) => ({ role: m["role"], content: String(m["content"] ?? "") }));
4406
+ if (turns.length >= 2) {
4407
+ examples.push({ messages: [{ role: "system", content: SYSTEM_PROMPT10 }, ...turns] });
4408
+ }
4409
+ }
4410
+ }
4411
+ }
4412
+ } catch {}
4413
+ const finalExamples = examples.slice(0, limit);
4414
+ return { source: "assistants", examples: finalExamples, count: finalExamples.length };
4415
+ }
4416
+
4417
+ // src/lib/gatherers/registry.ts
4418
+ var registry = new Map;
4419
+ function registerGatherer(provider) {
4420
+ registry.set(provider.name, provider);
4421
+ }
4422
+ function getRegisteredSources() {
4423
+ return Array.from(registry.keys()).sort();
4424
+ }
4425
+ function getGatherer(name) {
4426
+ return registry.get(name)?.gather;
4427
+ }
4428
+ registerGatherer({
4429
+ name: "todos",
4430
+ gather: gatherFromTodos,
4431
+ description: "Task management data from @hasna/todos",
4432
+ package: "@hasna/todos"
4433
+ });
4434
+ registerGatherer({
4435
+ name: "mementos",
4436
+ gather: gatherFromMementos,
4437
+ description: "Agent memory data from @hasna/mementos",
4438
+ package: "@hasna/mementos"
4439
+ });
4440
+ registerGatherer({
4441
+ name: "conversations",
4442
+ gather: gatherFromConversations,
4443
+ description: "Multi-agent conversation data from @hasna/conversations",
4444
+ package: "@hasna/conversations"
4445
+ });
4446
+ registerGatherer({
4447
+ name: "sessions",
4448
+ gather: gatherFromSessions,
4449
+ description: "Claude Code session transcripts from ~/.claude/projects",
4450
+ package: "@hasna/sessions"
4451
+ });
4452
+ registerGatherer({
4453
+ name: "styles",
4454
+ gather: gatherFromStyles,
4455
+ description: "Style preferences and profiles from @hasnaxyz/styles",
4456
+ package: "@hasnaxyz/styles"
4457
+ });
4458
+ registerGatherer({
4459
+ name: "researcher",
4460
+ gather: gatherFromResearcher,
4461
+ description: "Experiment results and research projects from @hasna/researcher",
4462
+ package: "@hasna/researcher"
4463
+ });
4464
+ registerGatherer({
4465
+ name: "tickets",
4466
+ gather: gatherFromTickets,
4467
+ description: "Bug reports and feature requests from @hasna/tickets",
4468
+ package: "@hasna/tickets"
4469
+ });
4470
+ registerGatherer({
4471
+ name: "economy",
4472
+ gather: gatherFromEconomy,
4473
+ description: "AI cost and usage data from @hasna/economy",
4474
+ package: "@hasna/economy"
4475
+ });
4476
+ registerGatherer({
4477
+ name: "recordings",
4478
+ gather: gatherFromRecordings,
4479
+ description: "Audio transcripts and recordings from @hasna/recordings",
4480
+ package: "@hasna/recordings"
4481
+ });
4482
+ registerGatherer({
4483
+ name: "assistants",
4484
+ gather: gatherFromAssistants,
4485
+ description: "Personal assistant session history from @hasna/assistants",
4486
+ package: "@hasna/assistants"
4487
+ });
4150
4488
  // src/lib/gatherers/index.ts
4151
- var ALL_SOURCES = ["todos", "mementos", "conversations", "sessions"];
4152
4489
  async function gatherAll(sources, options = {}) {
4153
- const targets = sources.includes("all") ? [...ALL_SOURCES] : sources;
4490
+ const targets = sources.includes("all") ? getRegisteredSources() : sources;
4154
4491
  const results = await Promise.allSettled(targets.map((source) => {
4155
- switch (source) {
4156
- case "todos":
4157
- return gatherFromTodos(options);
4158
- case "mementos":
4159
- return gatherFromMementos(options);
4160
- case "conversations":
4161
- return gatherFromConversations(options);
4162
- case "sessions":
4163
- return gatherFromSessions(options);
4164
- default:
4165
- return Promise.resolve({ source, examples: [], count: 0 });
4166
- }
4492
+ const fn = getGatherer(source);
4493
+ if (!fn)
4494
+ return Promise.resolve({ source, examples: [], count: 0 });
4495
+ return fn(options);
4167
4496
  }));
4168
4497
  return results.filter((r) => r.status === "fulfilled").map((r) => r.value);
4169
4498
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/brains",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Fine-tuned model tracker and trainer — wraps OpenAI + Thinker Labs, gathers training data from todos/mementos/conversations/sessions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",