@locusai/sdk 0.12.1 → 0.13.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAgBV,OAAO,CAAC,MAAM;IAf1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IAGjC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,aAAa,CAAuB;IAG5C,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,aAAa,CAAgB;gBAEjB,MAAM,EAAE,YAAY;IAqDxC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAgB;YAmB5D,eAAe;YAcf,WAAW;IAgDzB;;OAEG;YACW,WAAW;IAoCzB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAoBf,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8I3B"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/agent/worker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAgBV,OAAO,CAAC,MAAM;IAf1B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IAGjC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,aAAa,CAAuB;IAG5C,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,aAAa,CAAgB;gBAEjB,MAAM,EAAE,YAAY;IAqDxC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAgB;YAmB5D,eAAe;YAcf,WAAW;IAgDzB;;OAEG;YACW,WAAW;IAoCzB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,aAAa;IAoBf,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA4I3B"}
@@ -391,6 +391,39 @@ var init_workspaces = __esm(() => {
391
391
  };
392
392
  });
393
393
 
394
+ // src/discussion/discussion-types.ts
395
+ var import_zod, DiscussionMessageSchema, DiscussionInsightSchema, DiscussionSchema;
396
+ var init_discussion_types = __esm(() => {
397
+ import_zod = require("zod");
398
+ DiscussionMessageSchema = import_zod.z.object({
399
+ role: import_zod.z.enum(["user", "assistant"]),
400
+ content: import_zod.z.string(),
401
+ timestamp: import_zod.z.number()
402
+ });
403
+ DiscussionInsightSchema = import_zod.z.object({
404
+ id: import_zod.z.string(),
405
+ type: import_zod.z.enum(["decision", "requirement", "idea", "concern", "learning"]),
406
+ title: import_zod.z.string(),
407
+ content: import_zod.z.string(),
408
+ tags: import_zod.z.array(import_zod.z.string()).default([]),
409
+ createdAt: import_zod.z.string()
410
+ });
411
+ DiscussionSchema = import_zod.z.object({
412
+ id: import_zod.z.string(),
413
+ title: import_zod.z.string(),
414
+ topic: import_zod.z.string(),
415
+ status: import_zod.z.enum(["active", "completed", "archived"]).default("active"),
416
+ messages: import_zod.z.array(DiscussionMessageSchema).default([]),
417
+ insights: import_zod.z.array(DiscussionInsightSchema).default([]),
418
+ createdAt: import_zod.z.string(),
419
+ updatedAt: import_zod.z.string(),
420
+ metadata: import_zod.z.object({
421
+ model: import_zod.z.string(),
422
+ provider: import_zod.z.string()
423
+ })
424
+ });
425
+ });
426
+
394
427
  // src/index.ts
395
428
  var exports_src = {};
396
429
  __export(exports_src, {
@@ -403,6 +436,9 @@ __export(exports_src, {
403
436
  LocusClient: () => LocusClient,
404
437
  InvitationsModule: () => InvitationsModule,
405
438
  DocsModule: () => DocsModule,
439
+ DiscussionSchema: () => DiscussionSchema,
440
+ DiscussionMessageSchema: () => DiscussionMessageSchema,
441
+ DiscussionInsightSchema: () => DiscussionInsightSchema,
406
442
  CiModule: () => CiModule,
407
443
  AuthModule: () => AuthModule
408
444
  });
@@ -508,6 +544,7 @@ var init_src = __esm(() => {
508
544
  init_sprints();
509
545
  init_tasks();
510
546
  init_workspaces();
547
+ init_discussion_types();
511
548
  import_axios = __toESM(require("axios"));
512
549
  init_events();
513
550
  init_auth();
@@ -554,7 +591,8 @@ var init_config = __esm(() => {
554
591
  documentsDir: "documents",
555
592
  sessionsDir: "sessions",
556
593
  reviewsDir: "reviews",
557
- plansDir: "plans"
594
+ plansDir: "plans",
595
+ discussionsDir: "discussions"
558
596
  };
559
597
  LOCUS_GITIGNORE_PATTERNS = [
560
598
  "# Locus AI - Session data (user-specific, can grow large)",
@@ -569,6 +607,9 @@ var init_config = __esm(() => {
569
607
  "# Locus AI - Plans (generated per task)",
570
608
  ".locus/plans/",
571
609
  "",
610
+ "# Locus AI - Discussions (AI discussion sessions)",
611
+ ".locus/discussions/",
612
+ "",
572
613
  "# Locus AI - Settings (contains API key, telegram config, etc.)",
573
614
  ".locus/settings.json",
574
615
  "",
@@ -1871,6 +1912,187 @@ var init_git_workflow = __esm(() => {
1871
1912
  import_node_child_process4 = require("node:child_process");
1872
1913
  });
1873
1914
 
1915
+ // src/discussion/discussion-manager.ts
1916
+ class DiscussionManager {
1917
+ discussionsDir;
1918
+ constructor(projectPath) {
1919
+ this.discussionsDir = getLocusPath(projectPath, "discussionsDir");
1920
+ }
1921
+ create(topic, model, provider) {
1922
+ this.ensureDir();
1923
+ const now = new Date().toISOString();
1924
+ const id = `disc-${Date.now()}`;
1925
+ const discussion = {
1926
+ id,
1927
+ title: topic,
1928
+ topic,
1929
+ status: "active",
1930
+ messages: [],
1931
+ insights: [],
1932
+ createdAt: now,
1933
+ updatedAt: now,
1934
+ metadata: { model, provider }
1935
+ };
1936
+ this.save(discussion);
1937
+ return discussion;
1938
+ }
1939
+ save(discussion) {
1940
+ this.ensureDir();
1941
+ const jsonPath = import_node_path5.join(this.discussionsDir, `${discussion.id}.json`);
1942
+ const mdPath = import_node_path5.join(this.discussionsDir, `summary-${discussion.id}.md`);
1943
+ import_node_fs3.writeFileSync(jsonPath, JSON.stringify(discussion, null, 2), "utf-8");
1944
+ import_node_fs3.writeFileSync(mdPath, this.toMarkdown(discussion), "utf-8");
1945
+ }
1946
+ load(id) {
1947
+ this.ensureDir();
1948
+ const filePath = import_node_path5.join(this.discussionsDir, `${id}.json`);
1949
+ if (!import_node_fs3.existsSync(filePath)) {
1950
+ return null;
1951
+ }
1952
+ try {
1953
+ return JSON.parse(import_node_fs3.readFileSync(filePath, "utf-8"));
1954
+ } catch {
1955
+ return null;
1956
+ }
1957
+ }
1958
+ list(status) {
1959
+ this.ensureDir();
1960
+ const files = import_node_fs3.readdirSync(this.discussionsDir).filter((f) => f.endsWith(".json"));
1961
+ const discussions = [];
1962
+ for (const file of files) {
1963
+ try {
1964
+ const discussion = JSON.parse(import_node_fs3.readFileSync(import_node_path5.join(this.discussionsDir, file), "utf-8"));
1965
+ if (!status || discussion.status === status) {
1966
+ discussions.push(discussion);
1967
+ }
1968
+ } catch {}
1969
+ }
1970
+ discussions.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
1971
+ return discussions;
1972
+ }
1973
+ complete(id) {
1974
+ const discussion = this.load(id);
1975
+ if (!discussion) {
1976
+ throw new Error(`Discussion not found: ${id}`);
1977
+ }
1978
+ discussion.status = "completed";
1979
+ discussion.updatedAt = new Date().toISOString();
1980
+ this.save(discussion);
1981
+ return discussion;
1982
+ }
1983
+ archive(id) {
1984
+ const discussion = this.load(id);
1985
+ if (!discussion) {
1986
+ throw new Error(`Discussion not found: ${id}`);
1987
+ }
1988
+ discussion.status = "archived";
1989
+ discussion.updatedAt = new Date().toISOString();
1990
+ this.save(discussion);
1991
+ }
1992
+ delete(id) {
1993
+ this.ensureDir();
1994
+ const jsonPath = import_node_path5.join(this.discussionsDir, `${id}.json`);
1995
+ const mdPath = import_node_path5.join(this.discussionsDir, `summary-${id}.md`);
1996
+ if (import_node_fs3.existsSync(jsonPath)) {
1997
+ import_node_fs3.unlinkSync(jsonPath);
1998
+ }
1999
+ if (import_node_fs3.existsSync(mdPath)) {
2000
+ import_node_fs3.unlinkSync(mdPath);
2001
+ }
2002
+ }
2003
+ addMessage(id, role, content) {
2004
+ const discussion = this.load(id);
2005
+ if (!discussion) {
2006
+ throw new Error(`Discussion not found: ${id}`);
2007
+ }
2008
+ discussion.messages.push({
2009
+ role,
2010
+ content,
2011
+ timestamp: Date.now()
2012
+ });
2013
+ discussion.updatedAt = new Date().toISOString();
2014
+ this.save(discussion);
2015
+ return discussion;
2016
+ }
2017
+ addInsight(id, insight) {
2018
+ const discussion = this.load(id);
2019
+ if (!discussion) {
2020
+ throw new Error(`Discussion not found: ${id}`);
2021
+ }
2022
+ discussion.insights.push(insight);
2023
+ discussion.updatedAt = new Date().toISOString();
2024
+ this.save(discussion);
2025
+ return discussion;
2026
+ }
2027
+ getAllInsights() {
2028
+ const discussions = this.list("completed");
2029
+ const insights = [];
2030
+ for (const discussion of discussions) {
2031
+ insights.push(...discussion.insights);
2032
+ }
2033
+ insights.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
2034
+ return insights;
2035
+ }
2036
+ getMarkdown(id) {
2037
+ const discussion = this.load(id);
2038
+ if (!discussion)
2039
+ return null;
2040
+ return this.toMarkdown(discussion);
2041
+ }
2042
+ toMarkdown(discussion) {
2043
+ const lines = [];
2044
+ lines.push(`# Discussion: ${discussion.title}`);
2045
+ lines.push("");
2046
+ lines.push(`**Status:** ${discussion.status.toUpperCase()}`);
2047
+ lines.push(`**Topic:** ${discussion.topic}`);
2048
+ lines.push(`**Created:** ${discussion.createdAt}`);
2049
+ lines.push(`**Updated:** ${discussion.updatedAt}`);
2050
+ lines.push(`**Model:** ${discussion.metadata.model} (${discussion.metadata.provider})`);
2051
+ lines.push("");
2052
+ if (discussion.messages.length > 0) {
2053
+ lines.push(`## Messages (${discussion.messages.length})`);
2054
+ lines.push("");
2055
+ for (const msg of discussion.messages) {
2056
+ const time = new Date(msg.timestamp).toISOString();
2057
+ const roleLabel = msg.role === "user" ? "User" : "Assistant";
2058
+ lines.push(`### ${roleLabel} — ${time}`);
2059
+ lines.push("");
2060
+ lines.push(msg.content);
2061
+ lines.push("");
2062
+ }
2063
+ }
2064
+ if (discussion.insights.length > 0) {
2065
+ lines.push(`## Insights (${discussion.insights.length})`);
2066
+ lines.push("");
2067
+ for (const insight of discussion.insights) {
2068
+ lines.push(`### [${insight.type.toUpperCase()}] ${insight.title}`);
2069
+ lines.push("");
2070
+ lines.push(insight.content);
2071
+ if (insight.tags.length > 0) {
2072
+ lines.push("");
2073
+ lines.push(`**Tags:** ${insight.tags.join(", ")}`);
2074
+ }
2075
+ lines.push("");
2076
+ }
2077
+ }
2078
+ lines.push("---");
2079
+ lines.push(`*Discussion ID: ${discussion.id}*`);
2080
+ return lines.join(`
2081
+ `);
2082
+ }
2083
+ ensureDir() {
2084
+ if (!import_node_fs3.existsSync(this.discussionsDir)) {
2085
+ import_node_fs3.mkdirSync(this.discussionsDir, { recursive: true });
2086
+ }
2087
+ }
2088
+ }
2089
+ var import_node_fs3, import_node_path5;
2090
+ var init_discussion_manager = __esm(() => {
2091
+ init_config();
2092
+ import_node_fs3 = require("node:fs");
2093
+ import_node_path5 = require("node:path");
2094
+ });
2095
+
1874
2096
  // src/core/prompt-builder.ts
1875
2097
  class PromptBuilder {
1876
2098
  projectPath;
@@ -1909,6 +2131,15 @@ ${knowledgeBase}
1909
2131
  These are accumulated lessons from past tasks. Follow them to avoid repeating mistakes:
1910
2132
  ${learnings}
1911
2133
  </learnings>
2134
+ `;
2135
+ }
2136
+ const discussionInsights = this.getDiscussionInsightsContent();
2137
+ if (discussionInsights) {
2138
+ sections += `
2139
+ <discussion_insights>
2140
+ These are key decisions and insights from product discussions. Follow them to maintain product coherence:
2141
+ ${discussionInsights}
2142
+ </discussion_insights>
1912
2143
  `;
1913
2144
  }
1914
2145
  if (task.docs && task.docs.length > 0) {
@@ -1997,6 +2228,15 @@ ${knowledgeBase}
1997
2228
  These are accumulated lessons from past tasks. Follow them to avoid repeating mistakes:
1998
2229
  ${learnings}
1999
2230
  </learnings>
2231
+ `;
2232
+ }
2233
+ const discussionInsights = this.getDiscussionInsightsContent();
2234
+ if (discussionInsights) {
2235
+ sections += `
2236
+ <discussion_insights>
2237
+ These are key decisions and insights from product discussions. Follow them to maintain product coherence:
2238
+ ${discussionInsights}
2239
+ </discussion_insights>
2000
2240
  `;
2001
2241
  }
2002
2242
  return `<direct_execution>
@@ -2011,9 +2251,9 @@ ${sections}
2011
2251
  }
2012
2252
  getProjectContext() {
2013
2253
  const contextPath = getLocusPath(this.projectPath, "contextFile");
2014
- if (import_node_fs3.existsSync(contextPath)) {
2254
+ if (import_node_fs4.existsSync(contextPath)) {
2015
2255
  try {
2016
- const context = import_node_fs3.readFileSync(contextPath, "utf-8");
2256
+ const context = import_node_fs4.readFileSync(contextPath, "utf-8");
2017
2257
  if (context.trim().length > 20) {
2018
2258
  return context;
2019
2259
  }
@@ -2024,10 +2264,10 @@ ${sections}
2024
2264
  return this.getFallbackContext() || null;
2025
2265
  }
2026
2266
  getFallbackContext() {
2027
- const readmePath = import_node_path5.join(this.projectPath, "README.md");
2028
- if (import_node_fs3.existsSync(readmePath)) {
2267
+ const readmePath = import_node_path6.join(this.projectPath, "README.md");
2268
+ if (import_node_fs4.existsSync(readmePath)) {
2029
2269
  try {
2030
- const content = import_node_fs3.readFileSync(readmePath, "utf-8");
2270
+ const content = import_node_fs4.readFileSync(readmePath, "utf-8");
2031
2271
  const limit = 1000;
2032
2272
  return content.slice(0, limit) + (content.length > limit ? `
2033
2273
  ...(truncated)...` : "");
@@ -2041,15 +2281,16 @@ ${sections}
2041
2281
  return `You have access to the following documentation directories for context:
2042
2282
  - Artifacts: \`.locus/artifacts\` (local-only, not synced to cloud)
2043
2283
  - Documents: \`.locus/documents\` (synced from cloud)
2284
+ - Discussions: \`.locus/discussions\` (product discussion insights and decisions)
2044
2285
  If you need more information about the project strategies, plans, or architecture, read files in these directories.`;
2045
2286
  }
2046
2287
  getLearningsContent() {
2047
2288
  const learningsPath = getLocusPath(this.projectPath, "learningsFile");
2048
- if (!import_node_fs3.existsSync(learningsPath)) {
2289
+ if (!import_node_fs4.existsSync(learningsPath)) {
2049
2290
  return null;
2050
2291
  }
2051
2292
  try {
2052
- const content = import_node_fs3.readFileSync(learningsPath, "utf-8");
2293
+ const content = import_node_fs4.readFileSync(learningsPath, "utf-8");
2053
2294
  const lines = content.split(`
2054
2295
  `).filter((l) => l.startsWith("- "));
2055
2296
  if (lines.length === 0) {
@@ -2061,6 +2302,53 @@ If you need more information about the project strategies, plans, or architectur
2061
2302
  return null;
2062
2303
  }
2063
2304
  }
2305
+ getDiscussionInsightsContent() {
2306
+ try {
2307
+ const manager = new DiscussionManager(this.projectPath);
2308
+ const insights = manager.getAllInsights();
2309
+ if (insights.length === 0) {
2310
+ return null;
2311
+ }
2312
+ const groups = {};
2313
+ for (const insight of insights) {
2314
+ const key = insight.type;
2315
+ if (!groups[key]) {
2316
+ groups[key] = [];
2317
+ }
2318
+ groups[key].push(insight);
2319
+ }
2320
+ const typeLabels = {
2321
+ decision: "Decisions",
2322
+ requirement: "Requirements",
2323
+ idea: "Ideas",
2324
+ concern: "Concerns",
2325
+ learning: "Learnings"
2326
+ };
2327
+ let output = "";
2328
+ for (const [type, label] of Object.entries(typeLabels)) {
2329
+ const items = groups[type];
2330
+ if (!items || items.length === 0)
2331
+ continue;
2332
+ output += `## ${label}
2333
+ `;
2334
+ for (const item of items) {
2335
+ output += `- [${item.title}]: ${item.content}
2336
+ `;
2337
+ }
2338
+ output += `
2339
+ `;
2340
+ }
2341
+ if (output.length === 0) {
2342
+ return null;
2343
+ }
2344
+ if (output.length > 2000) {
2345
+ output = `${output.slice(0, 1997)}...`;
2346
+ }
2347
+ return output.trimEnd();
2348
+ } catch {
2349
+ return null;
2350
+ }
2351
+ }
2064
2352
  roleToText(role) {
2065
2353
  if (!role) {
2066
2354
  return null;
@@ -2081,11 +2369,12 @@ If you need more information about the project strategies, plans, or architectur
2081
2369
  }
2082
2370
  }
2083
2371
  }
2084
- var import_node_fs3, import_node_path5, import_shared2;
2372
+ var import_node_fs4, import_node_path6, import_shared2;
2085
2373
  var init_prompt_builder = __esm(() => {
2374
+ init_discussion_manager();
2086
2375
  init_config();
2087
- import_node_fs3 = require("node:fs");
2088
- import_node_path5 = require("node:path");
2376
+ import_node_fs4 = require("node:fs");
2377
+ import_node_path6 = require("node:path");
2089
2378
  import_shared2 = require("@locusai/shared");
2090
2379
  });
2091
2380
 
@@ -2408,7 +2697,6 @@ Branch: \`${result.branch}\`` : "";
2408
2697
  this.log("All tasks done. Creating pull request...", "info");
2409
2698
  const prResult = this.gitWorkflow.createPullRequest(this.completedTaskList, this.taskSummaries);
2410
2699
  if (prResult.url) {
2411
- this.log(`PR created: ${prResult.url}`, "success");
2412
2700
  for (const task of this.completedTaskList) {
2413
2701
  try {
2414
2702
  await this.client.tasks.update(task.id, this.config.workspaceId, {
@@ -21,8 +21,9 @@ export declare const LOCUS_CONFIG: {
21
21
  sessionsDir: string;
22
22
  reviewsDir: string;
23
23
  plansDir: string;
24
+ discussionsDir: string;
24
25
  };
25
- export declare const LOCUS_GITIGNORE_PATTERNS: readonly ["# Locus AI - Session data (user-specific, can grow large)", ".locus/sessions/", "", "# Locus AI - Artifacts (local-only, user-specific)", ".locus/artifacts/", "", "# Locus AI - Review reports (generated per sprint)", ".locus/reviews/", "", "# Locus AI - Plans (generated per task)", ".locus/plans/", "", "# Locus AI - Settings (contains API key, telegram config, etc.)", ".locus/settings.json", "", "# Locus AI - Configuration (contains project context, etc.)", ".locus/config.json"];
26
+ export declare const LOCUS_GITIGNORE_PATTERNS: readonly ["# Locus AI - Session data (user-specific, can grow large)", ".locus/sessions/", "", "# Locus AI - Artifacts (local-only, user-specific)", ".locus/artifacts/", "", "# Locus AI - Review reports (generated per sprint)", ".locus/reviews/", "", "# Locus AI - Plans (generated per task)", ".locus/plans/", "", "# Locus AI - Discussions (AI discussion sessions)", ".locus/discussions/", "", "# Locus AI - Settings (contains API key, telegram config, etc.)", ".locus/settings.json", "", "# Locus AI - Configuration (contains project context, etc.)", ".locus/config.json"];
26
27
  export declare function getLocusPath(projectPath: string, fileName: keyof typeof LOCUS_CONFIG): string;
27
28
  /**
28
29
  * Gets the artifacts directory path for a specific agent.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ;;;CAGX,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAGlD,CAAC;AAEF,eAAO,MAAM,qBAAqB,gCAAgC,CAAC;AAEnE,eAAO,MAAM,aAAa;;;CAGhB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;CAYxB,CAAC;AAIF,eAAO,MAAM,wBAAwB,gfAkB3B,CAAC;AAEX,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,OAAO,YAAY,GAClC,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CASR"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ;;;CAGX,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAGlD,CAAC;AAEF,eAAO,MAAM,qBAAqB,gCAAgC,CAAC;AAEnE,eAAO,MAAM,aAAa;;;CAGhB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAaxB,CAAC;AAIF,eAAO,MAAM,wBAAwB,gkBAqB3B,CAAC;AAEX,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,OAAO,YAAY,GAClC,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CASR"}
@@ -8,6 +8,7 @@ export declare class PromptBuilder {
8
8
  private getFallbackContext;
9
9
  private getKnowledgeBaseSection;
10
10
  private getLearningsContent;
11
+ private getDiscussionInsightsContent;
11
12
  roleToText(role: Task["assigneeRole"]): string | null;
12
13
  }
13
14
  //# sourceMappingURL=prompt-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGrD,qBAAa,aAAa;IACZ,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEjC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAiFlC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA+BxD,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,mBAAmB;IAiB3B,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,MAAM,GAAG,IAAI;CAoBtD"}
1
+ {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/core/prompt-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAKrD,qBAAa,aAAa;IACZ,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEjC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAuFlC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqCxD,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,4BAA4B;IAqDpC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,MAAM,GAAG,IAAI;CAoBtD"}
@@ -0,0 +1,13 @@
1
+ import type { DiscussionInsight, DiscussionMessage } from "../discussion-types.js";
2
+ export interface FacilitatorPromptInput {
3
+ topic: string;
4
+ projectContext: string | null;
5
+ learnings: string | null;
6
+ knowledgeBase: string;
7
+ previousMessages: DiscussionMessage[];
8
+ insights: DiscussionInsight[];
9
+ isFirstMessage: boolean;
10
+ }
11
+ export declare function buildFacilitatorPrompt(input: FacilitatorPromptInput): string;
12
+ export declare function buildSummaryPrompt(topic: string, messages: DiscussionMessage[], insights: DiscussionInsight[]): string;
13
+ //# sourceMappingURL=facilitator-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facilitator-prompt.d.ts","sourceRoot":"","sources":["../../../src/discussion/agents/facilitator-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAwF5E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,MAAM,CAwCR"}
@@ -0,0 +1,67 @@
1
+ import type { LogFn } from "../ai/factory.js";
2
+ import type { AiRunner } from "../ai/runner.js";
3
+ import { Provider } from "../core/config.js";
4
+ import type { StreamChunk } from "../exec/types.js";
5
+ import type { DiscussionManager } from "./discussion-manager.js";
6
+ import type { Discussion, DiscussionInsight } from "./discussion-types.js";
7
+ export interface DiscussionFacilitatorConfig {
8
+ projectPath: string;
9
+ aiRunner: AiRunner;
10
+ discussionManager: DiscussionManager;
11
+ log?: LogFn;
12
+ provider: Provider;
13
+ model: string;
14
+ }
15
+ export interface StartDiscussionResult {
16
+ discussion: Discussion;
17
+ message: string;
18
+ }
19
+ export interface ContinueDiscussionResult {
20
+ response: string;
21
+ insights: DiscussionInsight[];
22
+ }
23
+ export declare class DiscussionFacilitator {
24
+ private projectPath;
25
+ private aiRunner;
26
+ private discussionManager;
27
+ private log;
28
+ private provider;
29
+ private model;
30
+ constructor(config: DiscussionFacilitatorConfig);
31
+ /**
32
+ * Start a new discussion on a topic. Creates the discussion,
33
+ * generates the AI's opening question, and saves it.
34
+ */
35
+ startDiscussion(topic: string): Promise<StartDiscussionResult>;
36
+ /**
37
+ * Continue a discussion with a user message. Runs the AI to generate
38
+ * a response, extracts insights, and saves everything.
39
+ * Non-streaming path for Telegram and other non-interactive consumers.
40
+ */
41
+ continueDiscussion(discussionId: string, userMessage: string): Promise<ContinueDiscussionResult>;
42
+ /**
43
+ * Continue a discussion with streaming support for CLI consumption.
44
+ * Yields stream chunks in real-time and returns the final result.
45
+ */
46
+ continueDiscussionStream(discussionId: string, userMessage: string): AsyncGenerator<StreamChunk, ContinueDiscussionResult, unknown>;
47
+ /**
48
+ * Generate a final summary of the discussion, save it as the last
49
+ * assistant message, and mark the discussion as completed.
50
+ */
51
+ summarizeDiscussion(discussionId: string): Promise<string>;
52
+ /**
53
+ * Extract <insight>...</insight> XML blocks from the AI response.
54
+ * Returns the cleaned response text (with insight tags removed) and
55
+ * the parsed insight objects.
56
+ */
57
+ private parseInsights;
58
+ /**
59
+ * Build context from project files (LOCUS.md, LEARNINGS.md).
60
+ * Reuses the same logic as PromptBuilder.
61
+ */
62
+ private buildContext;
63
+ private getProjectContext;
64
+ private getLearningsContent;
65
+ private getKnowledgeBaseSection;
66
+ }
67
+ //# sourceMappingURL=discussion-facilitator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discussion-facilitator.d.ts","sourceRoot":"","sources":["../../src/discussion/discussion-facilitator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAgB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,2BAA2B;IAS/C;;;OAGG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA6CpE;;;;OAIG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,wBAAwB,CAAC;IAsCpC;;;OAGG;IACI,wBAAwB,CAC7B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,cAAc,CAAC,WAAW,EAAE,wBAAwB,EAAE,OAAO,CAAC;IAkDjE;;;OAGG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBhE;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAyCrB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,uBAAuB;CAMhC"}
@@ -0,0 +1,59 @@
1
+ import type { Discussion, DiscussionInsight } from "./discussion-types.js";
2
+ /**
3
+ * Manages the lifecycle of discussions:
4
+ * create, save, load, list, complete, archive, delete.
5
+ */
6
+ export declare class DiscussionManager {
7
+ private discussionsDir;
8
+ constructor(projectPath: string);
9
+ /**
10
+ * Create a new discussion for a given topic.
11
+ */
12
+ create(topic: string, model: string, provider: string): Discussion;
13
+ /**
14
+ * Save a discussion to disk as JSON and summary markdown.
15
+ */
16
+ save(discussion: Discussion): void;
17
+ /**
18
+ * Load a discussion by ID.
19
+ */
20
+ load(id: string): Discussion | null;
21
+ /**
22
+ * List all discussions, optionally filtered by status. Sorted newest first.
23
+ */
24
+ list(status?: Discussion["status"]): Discussion[];
25
+ /**
26
+ * Mark a discussion as completed.
27
+ */
28
+ complete(id: string): Discussion;
29
+ /**
30
+ * Mark a discussion as archived.
31
+ */
32
+ archive(id: string): void;
33
+ /**
34
+ * Delete a discussion's files entirely.
35
+ */
36
+ delete(id: string): void;
37
+ /**
38
+ * Append a message to a discussion and save.
39
+ */
40
+ addMessage(id: string, role: "user" | "assistant", content: string): Discussion;
41
+ /**
42
+ * Append an insight to a discussion and save.
43
+ */
44
+ addInsight(id: string, insight: DiscussionInsight): Discussion;
45
+ /**
46
+ * Aggregate insights across all completed discussions.
47
+ */
48
+ getAllInsights(): DiscussionInsight[];
49
+ /**
50
+ * Get the markdown content of a discussion for display.
51
+ */
52
+ getMarkdown(id: string): string | null;
53
+ /**
54
+ * Render a discussion as readable markdown.
55
+ */
56
+ toMarkdown(discussion: Discussion): string;
57
+ private ensureDir;
58
+ }
59
+ //# sourceMappingURL=discussion-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discussion-manager.d.ts","sourceRoot":"","sources":["../../src/discussion/discussion-manager.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,cAAc,CAAS;gBAEnB,WAAW,EAAE,MAAM;IAI/B;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAsBlE;;OAEG;IACH,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAUlC;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAenC;;OAEG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,UAAU,EAAE;IA6BjD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU;IAahC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAWzB;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAcxB;;OAEG;IACH,UAAU,CACR,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GAAG,WAAW,EAC1B,OAAO,EAAE,MAAM,GACd,UAAU;IAiBb;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU;IAa9D;;OAEG;IACH,cAAc,IAAI,iBAAiB,EAAE;IAiBrC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMtC;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAkD1C,OAAO,CAAC,SAAS;CAKlB"}