dot-agents 0.5.0 → 0.6.0

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 (124) hide show
  1. package/README.md +239 -122
  2. package/dist/cli/commands/channel.d.ts +19 -0
  3. package/dist/cli/commands/channel.d.ts.map +1 -1
  4. package/dist/cli/commands/channel.js +152 -13
  5. package/dist/cli/commands/channel.js.map +1 -1
  6. package/dist/cli/commands/check.d.ts.map +1 -1
  7. package/dist/cli/commands/check.js +61 -1
  8. package/dist/cli/commands/check.js.map +1 -1
  9. package/dist/cli/commands/index.d.ts +2 -0
  10. package/dist/cli/commands/index.d.ts.map +1 -1
  11. package/dist/cli/commands/index.js +2 -0
  12. package/dist/cli/commands/index.js.map +1 -1
  13. package/dist/cli/commands/personas.d.ts +3 -0
  14. package/dist/cli/commands/personas.d.ts.map +1 -0
  15. package/dist/cli/commands/personas.js +402 -0
  16. package/dist/cli/commands/personas.js.map +1 -0
  17. package/dist/cli/commands/projects.d.ts +3 -0
  18. package/dist/cli/commands/projects.d.ts.map +1 -0
  19. package/dist/cli/commands/projects.js +138 -0
  20. package/dist/cli/commands/projects.js.map +1 -0
  21. package/dist/cli/commands/run.d.ts.map +1 -1
  22. package/dist/cli/commands/run.js +4 -5
  23. package/dist/cli/commands/run.js.map +1 -1
  24. package/dist/cli/index.js +3 -11
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/lib/runner.d.ts +2 -0
  27. package/dist/cli/lib/runner.d.ts.map +1 -1
  28. package/dist/cli/lib/runner.js +67 -8
  29. package/dist/cli/lib/runner.js.map +1 -1
  30. package/dist/daemon/daemon.d.ts +10 -3
  31. package/dist/daemon/daemon.d.ts.map +1 -1
  32. package/dist/daemon/daemon.js +19 -21
  33. package/dist/daemon/daemon.js.map +1 -1
  34. package/dist/daemon/lib/executor.d.ts +0 -4
  35. package/dist/daemon/lib/executor.d.ts.map +1 -1
  36. package/dist/daemon/lib/executor.js +48 -135
  37. package/dist/daemon/lib/executor.js.map +1 -1
  38. package/dist/lib/channel.d.ts +53 -1
  39. package/dist/lib/channel.d.ts.map +1 -1
  40. package/dist/lib/channel.js +221 -30
  41. package/dist/lib/channel.js.map +1 -1
  42. package/dist/lib/channel.test.d.ts +2 -0
  43. package/dist/lib/channel.test.d.ts.map +1 -0
  44. package/dist/lib/channel.test.js +33 -0
  45. package/dist/lib/channel.test.js.map +1 -0
  46. package/dist/lib/daemon-status.d.ts +26 -0
  47. package/dist/lib/daemon-status.d.ts.map +1 -0
  48. package/dist/lib/daemon-status.js +64 -0
  49. package/dist/lib/daemon-status.js.map +1 -0
  50. package/dist/lib/environment.d.ts +87 -0
  51. package/dist/lib/environment.d.ts.map +1 -0
  52. package/dist/lib/environment.js +224 -0
  53. package/dist/lib/environment.js.map +1 -0
  54. package/dist/lib/frontmatter.d.ts +8 -0
  55. package/dist/lib/frontmatter.d.ts.map +1 -1
  56. package/dist/lib/frontmatter.js +16 -3
  57. package/dist/lib/frontmatter.js.map +1 -1
  58. package/dist/lib/frontmatter.test.d.ts +2 -0
  59. package/dist/lib/frontmatter.test.d.ts.map +1 -0
  60. package/dist/lib/frontmatter.test.js +60 -0
  61. package/dist/lib/frontmatter.test.js.map +1 -0
  62. package/dist/lib/index.d.ts +7 -0
  63. package/dist/lib/index.d.ts.map +1 -1
  64. package/dist/lib/index.js +7 -0
  65. package/dist/lib/index.js.map +1 -1
  66. package/dist/lib/integration.test.d.ts +2 -0
  67. package/dist/lib/integration.test.d.ts.map +1 -0
  68. package/dist/lib/integration.test.js +445 -0
  69. package/dist/lib/integration.test.js.map +1 -0
  70. package/dist/lib/invoke.d.ts +23 -0
  71. package/dist/lib/invoke.d.ts.map +1 -0
  72. package/dist/lib/invoke.js +158 -0
  73. package/dist/lib/invoke.js.map +1 -0
  74. package/dist/lib/invoke.test.d.ts +2 -0
  75. package/dist/lib/invoke.test.d.ts.map +1 -0
  76. package/dist/lib/invoke.test.js +82 -0
  77. package/dist/lib/invoke.test.js.map +1 -0
  78. package/dist/lib/persona.d.ts +22 -1
  79. package/dist/lib/persona.d.ts.map +1 -1
  80. package/dist/lib/persona.js +176 -31
  81. package/dist/lib/persona.js.map +1 -1
  82. package/dist/lib/persona.test.d.ts +2 -0
  83. package/dist/lib/persona.test.d.ts.map +1 -0
  84. package/dist/lib/persona.test.js +324 -0
  85. package/dist/lib/persona.test.js.map +1 -0
  86. package/dist/lib/processor.d.ts +50 -0
  87. package/dist/lib/processor.d.ts.map +1 -0
  88. package/dist/lib/processor.js +135 -0
  89. package/dist/lib/processor.js.map +1 -0
  90. package/dist/lib/processor.test.d.ts +2 -0
  91. package/dist/lib/processor.test.d.ts.map +1 -0
  92. package/dist/lib/processor.test.js +134 -0
  93. package/dist/lib/processor.test.js.map +1 -0
  94. package/dist/lib/registry.d.ts +109 -0
  95. package/dist/lib/registry.d.ts.map +1 -0
  96. package/dist/lib/registry.js +192 -0
  97. package/dist/lib/registry.js.map +1 -0
  98. package/dist/lib/registry.test.d.ts +2 -0
  99. package/dist/lib/registry.test.d.ts.map +1 -0
  100. package/dist/lib/registry.test.js +236 -0
  101. package/dist/lib/registry.test.js.map +1 -0
  102. package/dist/lib/session-thread.d.ts +75 -0
  103. package/dist/lib/session-thread.d.ts.map +1 -0
  104. package/dist/lib/session-thread.js +132 -0
  105. package/dist/lib/session-thread.js.map +1 -0
  106. package/dist/lib/session-thread.test.d.ts +2 -0
  107. package/dist/lib/session-thread.test.d.ts.map +1 -0
  108. package/dist/lib/session-thread.test.js +235 -0
  109. package/dist/lib/session-thread.test.js.map +1 -0
  110. package/dist/lib/session.d.ts +150 -0
  111. package/dist/lib/session.d.ts.map +1 -0
  112. package/dist/lib/session.js +183 -0
  113. package/dist/lib/session.js.map +1 -0
  114. package/dist/lib/session.test.d.ts +2 -0
  115. package/dist/lib/session.test.d.ts.map +1 -0
  116. package/dist/lib/session.test.js +336 -0
  117. package/dist/lib/session.test.js.map +1 -0
  118. package/dist/lib/types/channel.d.ts +4 -0
  119. package/dist/lib/types/channel.d.ts.map +1 -1
  120. package/dist/lib/types/persona.d.ts +49 -6
  121. package/dist/lib/types/persona.d.ts.map +1 -1
  122. package/internal/personas/_base/PERSONA.md +222 -39
  123. package/internal/skills/channels/list/SKILL.md +76 -0
  124. package/package.json +6 -2
@@ -1,7 +1,7 @@
1
1
  import { execa } from "execa";
2
- import { mkdir, writeFile } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
- import { resolvePersona, createExecutionContext, processTemplate, expandVariables, getInputDefaults, } from "../../lib/index.js";
3
+ import { hostname } from "node:os";
4
+ import { resolvePersona, createExecutionContext, processTemplate, expandVariables, getInputDefaults, createSession, finalizeSession, invokePersona as invokePersonaLib, } from "../../lib/index.js";
5
5
  /**
6
6
  * Parse duration string to milliseconds
7
7
  */
@@ -53,12 +53,35 @@ export class Executor {
53
53
  const startedAt = new Date();
54
54
  // Resolve persona
55
55
  const persona = await resolvePersona(join(this.config.personasDir, workflow.persona), this.config.personasDir);
56
+ // Determine working directory early (needed for session creation)
57
+ let workingDir = workflow.working_dir ?? process.cwd();
58
+ // Create session
59
+ const session = await createSession({
60
+ sessionsDir: this.config.sessionsDir,
61
+ runtime: {
62
+ hostname: hostname(),
63
+ executionMode: interactive ? "interactive" : "headless",
64
+ triggerType: "cron",
65
+ workingDir,
66
+ },
67
+ goal: `Run workflow: ${workflow.name}`,
68
+ persona: {
69
+ name: persona.name,
70
+ inheritanceChain: persona.inheritanceChain,
71
+ },
72
+ workflow: {
73
+ name: workflow.name,
74
+ path: workflow.path,
75
+ inputs: inputOverrides,
76
+ },
77
+ });
56
78
  const context = createExecutionContext({
57
79
  WORKFLOW_NAME: workflow.name,
58
80
  WORKFLOW_DIR: workflow.path,
59
81
  PERSONA_NAME: persona.name,
60
82
  PERSONA_DIR: persona.path,
61
83
  AGENTS_DIR: this.config.agentsDir,
84
+ SESSION_DIR: session.path,
62
85
  });
63
86
  // Merge inputs
64
87
  const inputs = {
@@ -77,8 +100,7 @@ export class Executor {
77
100
  env[key] = expandVariables(value, context, env);
78
101
  }
79
102
  }
80
- // Working directory
81
- let workingDir = workflow.working_dir ?? process.cwd();
103
+ // Expand working directory variables
82
104
  workingDir = expandVariables(workingDir, { ...context, ...inputs }, env);
83
105
  // Build prompt
84
106
  const prompt = buildPrompt(workflow, persona, context, inputs);
@@ -92,7 +114,7 @@ export class Executor {
92
114
  : persona.commands.headless;
93
115
  if (!cmds) {
94
116
  const endedAt = new Date();
95
- return {
117
+ const result = {
96
118
  success: false,
97
119
  exitCode: 1,
98
120
  stdout: "",
@@ -103,6 +125,15 @@ export class Executor {
103
125
  endedAt,
104
126
  error: `Unsupported execution mode: ${interactive ? "interactive" : "headless"}`,
105
127
  };
128
+ // Finalize session for error
129
+ await finalizeSession(session, {
130
+ success: result.success,
131
+ exitCode: result.exitCode,
132
+ duration: result.duration,
133
+ error: result.error,
134
+ stderr: result.stderr,
135
+ });
136
+ return result;
106
137
  }
107
138
  // Try each command
108
139
  let lastError = null;
@@ -151,8 +182,15 @@ export class Executor {
151
182
  error: lastError?.message,
152
183
  };
153
184
  }
154
- // Write session log
155
- await this.writeSessionLog(workflow.name, persona.name, result);
185
+ // Finalize session
186
+ await finalizeSession(session, {
187
+ success: result.success,
188
+ exitCode: result.exitCode,
189
+ duration: result.duration,
190
+ error: result.error,
191
+ stdout: result.stdout,
192
+ stderr: result.stderr,
193
+ });
156
194
  return result;
157
195
  }
158
196
  /**
@@ -160,135 +198,10 @@ export class Executor {
160
198
  * Used for DM-triggered invocations
161
199
  */
162
200
  async invokePersona(personaName, message, options = {}) {
163
- const startedAt = new Date();
164
- // Resolve persona
165
- const persona = await resolvePersona(join(this.config.personasDir, personaName), this.config.personasDir);
166
- const context = createExecutionContext({
167
- PERSONA_NAME: persona.name,
168
- PERSONA_DIR: persona.path,
169
- AGENTS_DIR: this.config.agentsDir,
170
- INVOCATION_SOURCE: options.source ?? "dm",
171
- ...options.context,
201
+ return invokePersonaLib(this.config, personaName, message, {
202
+ source: options.source ?? "dm",
203
+ context: options.context,
172
204
  });
173
- // Merge environment
174
- const env = {
175
- ...process.env,
176
- ...persona.env,
177
- DOT_AGENTS_PERSONA: persona.name,
178
- DOT_AGENTS_INVOCATION: "dm",
179
- };
180
- for (const [key, value] of Object.entries(env)) {
181
- if (value) {
182
- env[key] = expandVariables(value, context, env);
183
- }
184
- }
185
- // Build prompt: persona prompt + message
186
- const parts = [];
187
- if (persona.prompt) {
188
- const expandedPrompt = processTemplate(persona.prompt, context, persona.env);
189
- parts.push(expandedPrompt);
190
- parts.push("\n---\n");
191
- }
192
- parts.push(`You received a direct message:\n\n${message}`);
193
- const prompt = parts.join("\n");
194
- // Timeout (default 10 minutes for DM invocations)
195
- const timeoutMs = 10 * 60 * 1000;
196
- // Use headless commands for DM-triggered invocations
197
- const cmds = persona.commands.headless;
198
- if (!cmds) {
199
- const endedAt = new Date();
200
- return {
201
- success: false,
202
- exitCode: 1,
203
- stdout: "",
204
- stderr: `Persona '${persona.name}' does not support headless mode`,
205
- duration: endedAt.getTime() - startedAt.getTime(),
206
- runId: context.RUN_ID,
207
- startedAt,
208
- endedAt,
209
- error: "Persona does not support headless mode",
210
- };
211
- }
212
- // Try each command
213
- let lastError = null;
214
- let result = null;
215
- for (const cmd of cmds) {
216
- try {
217
- const expandedCmd = expandVariables(cmd, context, env);
218
- const [command, ...args] = expandedCmd.split(/\s+/);
219
- const execResult = await execa(command, args, {
220
- input: prompt,
221
- cwd: this.config.agentsDir,
222
- env,
223
- timeout: timeoutMs,
224
- reject: false,
225
- });
226
- const endedAt = new Date();
227
- result = {
228
- success: execResult.exitCode === 0,
229
- exitCode: execResult.exitCode ?? 1,
230
- stdout: execResult.stdout,
231
- stderr: execResult.stderr,
232
- duration: endedAt.getTime() - startedAt.getTime(),
233
- runId: context.RUN_ID,
234
- startedAt,
235
- endedAt,
236
- };
237
- if (result.success)
238
- break;
239
- lastError = new Error(`Command failed with exit code ${result.exitCode}: ${execResult.stderr}`);
240
- }
241
- catch (error) {
242
- lastError = error;
243
- }
244
- }
245
- if (!result) {
246
- const endedAt = new Date();
247
- result = {
248
- success: false,
249
- exitCode: 1,
250
- stdout: "",
251
- stderr: lastError?.message ?? "All commands failed",
252
- duration: endedAt.getTime() - startedAt.getTime(),
253
- runId: context.RUN_ID,
254
- startedAt,
255
- endedAt,
256
- error: lastError?.message,
257
- };
258
- }
259
- // Write session log
260
- await this.writeSessionLog(`dm:${options.source ?? personaName}`, persona.name, result);
261
- return result;
262
- }
263
- /**
264
- * Write execution log to sessions directory
265
- */
266
- async writeSessionLog(workflowName, personaName, result) {
267
- await mkdir(this.config.sessionsDir, { recursive: true });
268
- const timestamp = result.startedAt
269
- .toISOString()
270
- .replace(/[-:]/g, "")
271
- .replace("T", "-")
272
- .split(".")[0];
273
- const filename = `${timestamp}.log`;
274
- const logPath = join(this.config.sessionsDir, filename);
275
- const logContent = `Run ID: ${result.runId}
276
- Workflow: ${workflowName}
277
- Persona: ${personaName}
278
- Started: ${result.startedAt.toISOString()}
279
- Ended: ${result.endedAt.toISOString()}
280
- Duration: ${result.duration}ms
281
- Exit Code: ${result.exitCode}
282
- Success: ${result.success}
283
- ${result.error ? `Error: ${result.error}\n` : ""}
284
- --- STDOUT ---
285
- ${result.stdout}
286
-
287
- --- STDERR ---
288
- ${result.stderr}
289
- `;
290
- await writeFile(logPath, logContent, "utf-8");
291
- return logPath;
292
205
  }
293
206
  }
294
207
  //# sourceMappingURL=executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/daemon/lib/executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/daemon/lib/executor.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ export declare function publishMessage(channelsDir: string, channelName: string,
21
21
  /**
22
22
  * Read messages from a channel
23
23
  */
24
- export declare function readChannel(channelsDir: string, channelName: string, limit?: number, since?: Date): Promise<ChannelMessage[]>;
24
+ export declare function readChannel(channelsDir: string, channelName: string, limit?: number, since?: Date, threadId?: string): Promise<ChannelMessage[]>;
25
25
  /**
26
26
  * Reply to a message in a channel
27
27
  */
@@ -30,4 +30,56 @@ export declare function replyToMessage(channelsDir: string, channelName: string,
30
30
  * Load channel metadata
31
31
  */
32
32
  export declare function loadChannelMetadata(channelsDir: string, channelName: string): Promise<ChannelMetadata | null>;
33
+ /**
34
+ * Get the last processed timestamp for a channel
35
+ */
36
+ export declare function getLastProcessedTime(channelsDir: string, channelName: string): Promise<Date | null>;
37
+ /**
38
+ * Mark a channel as processed at the current time
39
+ */
40
+ export declare function markChannelProcessed(channelsDir: string, channelName: string): Promise<void>;
41
+ /**
42
+ * A pending message that needs processing
43
+ */
44
+ export interface PendingMessage {
45
+ /** Message ID (ISO 8601 timestamp) */
46
+ id: string;
47
+ /** Channel name (e.g., @persona) */
48
+ channel: string;
49
+ /** Path to the message file */
50
+ path: string;
51
+ /** Message content (body, without frontmatter) */
52
+ content: string;
53
+ /** Message metadata */
54
+ meta: ChannelMessageMeta;
55
+ }
56
+ /**
57
+ * Get pending (unprocessed) messages for a DM channel
58
+ * Returns messages newer than the last processed timestamp
59
+ */
60
+ export declare function getPendingMessages(channelsDir: string, channelName: string): Promise<PendingMessage[]>;
61
+ /**
62
+ * List all DM channels (@persona) in the channels directory
63
+ */
64
+ export declare function listDMChannels(channelsDir: string): Promise<string[]>;
65
+ /**
66
+ * Get the workspace directory path for a thread.
67
+ * The workspace is a directory within the thread for working files.
68
+ *
69
+ * @param channelsDir - Base channels directory
70
+ * @param channelName - Channel name (e.g., "#sessions")
71
+ * @param threadId - Thread ID (ISO timestamp)
72
+ * @param create - If true, creates the workspace directory if it doesn't exist
73
+ * @returns Path to the workspace directory, or null if thread doesn't exist
74
+ */
75
+ export declare function getThreadWorkspace(channelsDir: string, channelName: string, threadId: string, create?: boolean): Promise<string | null>;
76
+ /**
77
+ * Get the thread directory path.
78
+ *
79
+ * @param channelsDir - Base channels directory
80
+ * @param channelName - Channel name (e.g., "#sessions")
81
+ * @param threadId - Thread ID (ISO timestamp)
82
+ * @returns Path to the thread directory, or null if it doesn't exist
83
+ */
84
+ export declare function getThreadPath(channelsDir: string, channelName: string, threadId: string): Promise<string | null>;
33
85
  //# sourceMappingURL=channel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/lib/channel.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAEnB,MAAM,oBAAoB,CAAC;AAoC5B;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,EAAE,CAAC,CAiCxD;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,GACX,OAAO,CAAC,cAAc,EAAE,CAAC,CA2D3B;AA+CD;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CASjC"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/lib/channel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAEnB,MAAM,oBAAoB,CAAC;AAyD5B;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,EAAE,CAAC,CAiCxD;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,CA4E3B;AAmDD;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CASjC;AAYD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CActB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CA4D3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB"}
@@ -1,9 +1,11 @@
1
1
  import { readdir, mkdir, readFile, writeFile, stat } from "node:fs/promises";
2
+ import { hostname } from "node:os";
2
3
  import { join } from "node:path";
3
4
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4
5
  import { parseFrontmatter } from "./frontmatter.js";
5
6
  const METADATA_FILE = "_metadata.yaml";
6
- const MESSAGE_FILE = "message.md";
7
+ const MESSAGE_FILE_LEGACY = "message.md"; // Backwards compatibility
8
+ const LAST_PROCESSED_FILE = "_last_processed.yaml";
7
9
  /**
8
10
  * Check if a path exists and is a directory
9
11
  */
@@ -34,6 +36,23 @@ async function isFile(path) {
34
36
  function generateMessageId() {
35
37
  return new Date().toISOString();
36
38
  }
39
+ /**
40
+ * Get the path to the initial message file in a thread directory.
41
+ * Supports both new format (<threadId>.md) and legacy format (message.md).
42
+ */
43
+ async function getInitialMessagePath(threadDir, threadId) {
44
+ // Try new format first: <threadId>.md
45
+ const newPath = join(threadDir, `${threadId}.md`);
46
+ if (await isFile(newPath)) {
47
+ return newPath;
48
+ }
49
+ // Fall back to legacy format: message.md
50
+ const legacyPath = join(threadDir, MESSAGE_FILE_LEGACY);
51
+ if (await isFile(legacyPath)) {
52
+ return legacyPath;
53
+ }
54
+ return null;
55
+ }
37
56
  /**
38
57
  * Check if a name is a valid channel name (starts with # or @)
39
58
  */
@@ -102,25 +121,27 @@ export async function publishMessage(channelsDir, channelName, content, meta) {
102
121
  const messageId = generateMessageId();
103
122
  const messagePath = join(channelsDir, channelName, messageId);
104
123
  await mkdir(messagePath, { recursive: true });
124
+ const host = hostname();
105
125
  let messageContent = "";
106
- if (meta && (meta.from || meta.run_id || meta.tags?.length)) {
107
- const frontmatter = {};
108
- if (meta.from)
109
- frontmatter.from = meta.from;
110
- if (meta.run_id)
111
- frontmatter.run_id = meta.run_id;
112
- if (meta.tags?.length)
113
- frontmatter.tags = meta.tags;
114
- messageContent = `---\n${stringifyYaml(frontmatter)}---\n\n`;
115
- }
126
+ const frontmatter = { host };
127
+ if (meta?.from)
128
+ frontmatter.from = meta.from;
129
+ if (meta?.run_id)
130
+ frontmatter.run_id = meta.run_id;
131
+ if (meta?.tags?.length)
132
+ frontmatter.tags = meta.tags;
133
+ if (meta?.thread_id)
134
+ frontmatter.thread_id = meta.thread_id;
135
+ messageContent = `---\n${stringifyYaml(frontmatter)}---\n\n`;
116
136
  messageContent += content + "\n";
117
- await writeFile(join(messagePath, MESSAGE_FILE), messageContent, "utf-8");
137
+ // Write initial message with timestamp filename (uniform with replies)
138
+ await writeFile(join(messagePath, `${messageId}.md`), messageContent, "utf-8");
118
139
  return messageId;
119
140
  }
120
141
  /**
121
142
  * Read messages from a channel
122
143
  */
123
- export async function readChannel(channelsDir, channelName, limit, since) {
144
+ export async function readChannel(channelsDir, channelName, limit, since, threadId) {
124
145
  const channelPath = join(channelsDir, channelName);
125
146
  if (!(await isDirectory(channelPath))) {
126
147
  return [];
@@ -133,12 +154,31 @@ export async function readChannel(channelsDir, channelName, limit, since) {
133
154
  if (entry.name.startsWith("_"))
134
155
  continue;
135
156
  const messageDir = join(channelPath, entry.name);
136
- const messagePath = join(messageDir, MESSAGE_FILE);
137
- if (!(await isFile(messagePath)))
157
+ const threadId_local = entry.name;
158
+ // Find initial message file (new or legacy format)
159
+ const messagePath = await getInitialMessagePath(messageDir, threadId_local);
160
+ if (!messagePath)
138
161
  continue;
139
162
  const messageDate = new Date(entry.name);
140
163
  if (since && messageDate < since)
141
164
  continue;
165
+ // If filtering by thread, we need to read and check frontmatter first
166
+ if (threadId) {
167
+ try {
168
+ const content = await readFile(messagePath, "utf-8");
169
+ if (content.startsWith("---\n")) {
170
+ const parsed = parseFrontmatter(content);
171
+ if (parsed.frontmatter.thread_id !== threadId)
172
+ continue;
173
+ }
174
+ else {
175
+ continue; // No frontmatter means no thread_id
176
+ }
177
+ }
178
+ catch {
179
+ continue;
180
+ }
181
+ }
142
182
  try {
143
183
  const content = await readFile(messagePath, "utf-8");
144
184
  let meta = {};
@@ -156,7 +196,7 @@ export async function readChannel(channelsDir, channelName, limit, since) {
156
196
  else {
157
197
  body = content.trim();
158
198
  }
159
- const replies = await readReplies(messageDir);
199
+ const replies = await readReplies(messageDir, threadId_local);
160
200
  messages.push({
161
201
  id: entry.name,
162
202
  content: body,
@@ -175,16 +215,20 @@ export async function readChannel(channelsDir, channelName, limit, since) {
175
215
  return messages;
176
216
  }
177
217
  /**
178
- * Read replies for a message
218
+ * Read replies for a message (excluding the initial message)
179
219
  */
180
- async function readReplies(messageDir) {
220
+ async function readReplies(messageDir, threadId) {
181
221
  const entries = await readdir(messageDir, { withFileTypes: true });
182
222
  const replies = [];
223
+ // Files to skip: legacy message.md and the initial message (<threadId>.md)
224
+ const initialMessageFile = `${threadId}.md`;
183
225
  for (const entry of entries) {
184
226
  if (!entry.isFile())
185
227
  continue;
186
- if (entry.name === MESSAGE_FILE)
187
- continue;
228
+ if (entry.name === MESSAGE_FILE_LEGACY)
229
+ continue; // Skip legacy initial
230
+ if (entry.name === initialMessageFile)
231
+ continue; // Skip new-format initial
188
232
  if (!entry.name.endsWith(".md"))
189
233
  continue;
190
234
  const replyId = entry.name.replace(/\.md$/, "");
@@ -227,17 +271,16 @@ export async function replyToMessage(channelsDir, channelName, messageId, conten
227
271
  throw new Error(`Message not found: ${channelName}/${messageId}`);
228
272
  }
229
273
  const replyId = generateMessageId();
274
+ const host = hostname();
230
275
  let replyContent = "";
231
- if (meta && (meta.from || meta.run_id || meta.tags?.length)) {
232
- const frontmatter = {};
233
- if (meta.from)
234
- frontmatter.from = meta.from;
235
- if (meta.run_id)
236
- frontmatter.run_id = meta.run_id;
237
- if (meta.tags?.length)
238
- frontmatter.tags = meta.tags;
239
- replyContent = `---\n${stringifyYaml(frontmatter)}---\n\n`;
240
- }
276
+ const frontmatter = { host };
277
+ if (meta?.from)
278
+ frontmatter.from = meta.from;
279
+ if (meta?.run_id)
280
+ frontmatter.run_id = meta.run_id;
281
+ if (meta?.tags?.length)
282
+ frontmatter.tags = meta.tags;
283
+ replyContent = `---\n${stringifyYaml(frontmatter)}---\n\n`;
241
284
  replyContent += content + "\n";
242
285
  await writeFile(join(messagePath, `${replyId}.md`), replyContent, "utf-8");
243
286
  return replyId;
@@ -253,4 +296,152 @@ export async function loadChannelMetadata(channelsDir, channelName) {
253
296
  const content = await readFile(metadataPath, "utf-8");
254
297
  return parseYaml(content);
255
298
  }
299
+ /**
300
+ * Get the last processed timestamp for a channel
301
+ */
302
+ export async function getLastProcessedTime(channelsDir, channelName) {
303
+ const lastProcessedPath = join(channelsDir, channelName, LAST_PROCESSED_FILE);
304
+ if (!(await isFile(lastProcessedPath))) {
305
+ return null;
306
+ }
307
+ try {
308
+ const content = await readFile(lastProcessedPath, "utf-8");
309
+ const info = parseYaml(content);
310
+ return new Date(info.last_processed_at);
311
+ }
312
+ catch {
313
+ return null;
314
+ }
315
+ }
316
+ /**
317
+ * Mark a channel as processed at the current time
318
+ */
319
+ export async function markChannelProcessed(channelsDir, channelName) {
320
+ const channelPath = join(channelsDir, channelName);
321
+ if (!(await isDirectory(channelPath))) {
322
+ return;
323
+ }
324
+ const info = {
325
+ last_processed_at: new Date().toISOString(),
326
+ processed_by: hostname(),
327
+ };
328
+ const lastProcessedPath = join(channelPath, LAST_PROCESSED_FILE);
329
+ await writeFile(lastProcessedPath, stringifyYaml(info), "utf-8");
330
+ }
331
+ /**
332
+ * Get pending (unprocessed) messages for a DM channel
333
+ * Returns messages newer than the last processed timestamp
334
+ */
335
+ export async function getPendingMessages(channelsDir, channelName) {
336
+ const channelPath = join(channelsDir, channelName);
337
+ if (!(await isDirectory(channelPath))) {
338
+ return [];
339
+ }
340
+ const lastProcessed = await getLastProcessedTime(channelsDir, channelName);
341
+ const entries = await readdir(channelPath, { withFileTypes: true });
342
+ const pending = [];
343
+ for (const entry of entries) {
344
+ if (!entry.isDirectory())
345
+ continue;
346
+ if (entry.name.startsWith("_"))
347
+ continue;
348
+ // Message ID is an ISO timestamp
349
+ const messageDate = new Date(entry.name);
350
+ if (Number.isNaN(messageDate.getTime()))
351
+ continue;
352
+ // Skip if already processed
353
+ if (lastProcessed && messageDate <= lastProcessed)
354
+ continue;
355
+ const messageDir = join(channelPath, entry.name);
356
+ const threadId = entry.name;
357
+ // Find initial message file (new or legacy format)
358
+ const messagePath = await getInitialMessagePath(messageDir, threadId);
359
+ if (!messagePath)
360
+ continue;
361
+ try {
362
+ const content = await readFile(messagePath, "utf-8");
363
+ let meta = {};
364
+ let body;
365
+ if (content.startsWith("---\n")) {
366
+ try {
367
+ const parsed = parseFrontmatter(content);
368
+ meta = parsed.frontmatter;
369
+ body = parsed.body;
370
+ }
371
+ catch {
372
+ body = content;
373
+ }
374
+ }
375
+ else {
376
+ body = content.trim();
377
+ }
378
+ pending.push({
379
+ id: entry.name,
380
+ channel: channelName,
381
+ path: messagePath,
382
+ content: body,
383
+ meta,
384
+ });
385
+ }
386
+ catch {
387
+ continue;
388
+ }
389
+ }
390
+ // Sort by timestamp ascending (oldest first for processing order)
391
+ return pending.sort((a, b) => a.id.localeCompare(b.id));
392
+ }
393
+ /**
394
+ * List all DM channels (@persona) in the channels directory
395
+ */
396
+ export async function listDMChannels(channelsDir) {
397
+ if (!(await isDirectory(channelsDir))) {
398
+ return [];
399
+ }
400
+ const entries = await readdir(channelsDir, { withFileTypes: true });
401
+ const dmChannels = [];
402
+ for (const entry of entries) {
403
+ if (!entry.isDirectory())
404
+ continue;
405
+ if (entry.name.startsWith("@")) {
406
+ dmChannels.push(entry.name);
407
+ }
408
+ }
409
+ return dmChannels.sort();
410
+ }
411
+ /**
412
+ * Get the workspace directory path for a thread.
413
+ * The workspace is a directory within the thread for working files.
414
+ *
415
+ * @param channelsDir - Base channels directory
416
+ * @param channelName - Channel name (e.g., "#sessions")
417
+ * @param threadId - Thread ID (ISO timestamp)
418
+ * @param create - If true, creates the workspace directory if it doesn't exist
419
+ * @returns Path to the workspace directory, or null if thread doesn't exist
420
+ */
421
+ export async function getThreadWorkspace(channelsDir, channelName, threadId, create = false) {
422
+ const threadDir = join(channelsDir, channelName, threadId);
423
+ if (!(await isDirectory(threadDir))) {
424
+ return null;
425
+ }
426
+ const workspacePath = join(threadDir, "workspace");
427
+ if (create) {
428
+ await mkdir(workspacePath, { recursive: true });
429
+ }
430
+ return workspacePath;
431
+ }
432
+ /**
433
+ * Get the thread directory path.
434
+ *
435
+ * @param channelsDir - Base channels directory
436
+ * @param channelName - Channel name (e.g., "#sessions")
437
+ * @param threadId - Thread ID (ISO timestamp)
438
+ * @returns Path to the thread directory, or null if it doesn't exist
439
+ */
440
+ export async function getThreadPath(channelsDir, channelName, threadId) {
441
+ const threadDir = join(channelsDir, channelName, threadId);
442
+ if (!(await isDirectory(threadDir))) {
443
+ return null;
444
+ }
445
+ return threadDir;
446
+ }
256
447
  //# sourceMappingURL=channel.js.map