@davidjinguoxu/agentcore 0.4.2 → 0.4.4

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 (163) hide show
  1. package/README.md +85 -127
  2. package/dist/config/agentcore-constants.d.ts +21 -0
  3. package/dist/config/agentcore-constants.d.ts.map +1 -0
  4. package/dist/config/agentcore-constants.js +68 -0
  5. package/dist/config/agentcore-constants.js.map +1 -0
  6. package/dist/domain/bronze/questions.d.ts +3 -0
  7. package/dist/domain/bronze/questions.d.ts.map +1 -0
  8. package/dist/domain/bronze/questions.js +60 -0
  9. package/dist/domain/bronze/questions.js.map +1 -0
  10. package/dist/domain/bronze/run-manager.d.ts +14 -0
  11. package/dist/domain/bronze/run-manager.d.ts.map +1 -0
  12. package/dist/domain/bronze/run-manager.js +25 -0
  13. package/dist/domain/bronze/run-manager.js.map +1 -0
  14. package/dist/domain/bronze/task-event-index.d.ts +31 -0
  15. package/dist/domain/bronze/task-event-index.d.ts.map +1 -0
  16. package/dist/domain/bronze/task-event-index.js +117 -0
  17. package/dist/domain/bronze/task-event-index.js.map +1 -0
  18. package/dist/domain/bronze/tasks.d.ts +3 -0
  19. package/dist/domain/bronze/tasks.d.ts.map +1 -0
  20. package/dist/domain/bronze/tasks.js +112 -0
  21. package/dist/domain/bronze/tasks.js.map +1 -0
  22. package/dist/domain/context/warm-start-builders.d.ts +18 -0
  23. package/dist/domain/context/warm-start-builders.d.ts.map +1 -0
  24. package/dist/domain/context/warm-start-builders.js +157 -0
  25. package/dist/domain/context/warm-start-builders.js.map +1 -0
  26. package/dist/domain/context/warm-start-extractors.d.ts +37 -0
  27. package/dist/domain/context/warm-start-extractors.d.ts.map +1 -0
  28. package/dist/domain/context/warm-start-extractors.js +372 -0
  29. package/dist/domain/context/warm-start-extractors.js.map +1 -0
  30. package/dist/domain/context/warm-start.d.ts +17 -0
  31. package/dist/domain/context/warm-start.d.ts.map +1 -0
  32. package/dist/domain/context/warm-start.js +225 -0
  33. package/dist/domain/context/warm-start.js.map +1 -0
  34. package/dist/domain/gold/gold-store.d.ts +11 -0
  35. package/dist/domain/gold/gold-store.d.ts.map +1 -0
  36. package/dist/domain/gold/gold-store.js +210 -0
  37. package/dist/domain/gold/gold-store.js.map +1 -0
  38. package/dist/domain/run-manager.js +0 -0
  39. package/dist/domain/virtual-office/inbox.d.ts +14 -0
  40. package/dist/domain/virtual-office/inbox.d.ts.map +1 -0
  41. package/dist/domain/virtual-office/inbox.js +138 -0
  42. package/dist/domain/virtual-office/inbox.js.map +1 -0
  43. package/dist/domain/virtual-office/office-status.d.ts +31 -0
  44. package/dist/domain/virtual-office/office-status.d.ts.map +1 -0
  45. package/dist/domain/virtual-office/office-status.js +138 -0
  46. package/dist/domain/virtual-office/office-status.js.map +1 -0
  47. package/dist/index.d.ts +3 -3
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +3 -3
  50. package/dist/index.js.map +1 -1
  51. package/dist/models/bronze.d.ts +39 -0
  52. package/dist/models/bronze.d.ts.map +1 -0
  53. package/dist/models/bronze.js +4 -0
  54. package/dist/models/bronze.js.map +1 -0
  55. package/dist/models/gold.d.ts +43 -0
  56. package/dist/models/gold.d.ts.map +1 -0
  57. package/dist/models/gold.js +4 -0
  58. package/dist/models/gold.js.map +1 -0
  59. package/dist/models/index.d.ts +6 -0
  60. package/dist/models/index.d.ts.map +1 -0
  61. package/dist/models/index.js +8 -0
  62. package/dist/models/index.js.map +1 -0
  63. package/dist/models/questions.d.ts +24 -0
  64. package/dist/models/questions.d.ts.map +1 -0
  65. package/dist/models/questions.js +3 -0
  66. package/dist/models/questions.js.map +1 -0
  67. package/dist/models/silver.d.ts +26 -0
  68. package/dist/models/silver.d.ts.map +1 -0
  69. package/dist/models/silver.js +4 -0
  70. package/dist/models/silver.js.map +1 -0
  71. package/dist/models/tasks.d.ts +56 -0
  72. package/dist/models/tasks.d.ts.map +1 -0
  73. package/dist/models/tasks.js +3 -0
  74. package/dist/models/tasks.js.map +1 -0
  75. package/dist/search/azure-search-client.d.ts.map +0 -0
  76. package/dist/search/deep-search.js +0 -0
  77. package/dist/search/embeddable.d.ts +19 -0
  78. package/dist/search/embeddable.d.ts.map +1 -0
  79. package/dist/search/embeddable.js +106 -0
  80. package/dist/search/embeddable.js.map +1 -0
  81. package/dist/search/search.d.ts +1 -1
  82. package/dist/search/search.d.ts.map +1 -1
  83. package/dist/server/mcp-slim-ack.d.ts +12 -0
  84. package/dist/server/mcp-slim-ack.d.ts.map +1 -0
  85. package/dist/server/mcp-slim-ack.js +16 -0
  86. package/dist/server/mcp-slim-ack.js.map +1 -0
  87. package/dist/server/server.d.ts +3 -0
  88. package/dist/server/server.d.ts.map +1 -0
  89. package/dist/server/server.js +48 -0
  90. package/dist/server/server.js.map +1 -0
  91. package/dist/server/tools.d.ts +3 -0
  92. package/dist/server/tools.d.ts.map +1 -0
  93. package/dist/server/tools.js +413 -0
  94. package/dist/server/tools.js.map +1 -0
  95. package/dist/server.js +3 -0
  96. package/dist/server.js.map +1 -1
  97. package/dist/skills/index.js +1 -1
  98. package/dist/skills/index.js.map +1 -1
  99. package/dist/skills/insights.d.ts +3 -0
  100. package/dist/skills/insights.d.ts.map +1 -0
  101. package/dist/skills/insights.js +78 -0
  102. package/dist/skills/insights.js.map +1 -0
  103. package/dist/skills/knowledge.js +1 -1
  104. package/dist/skills/knowledge.js.map +1 -1
  105. package/dist/skills/task-workflow.js +2 -2
  106. package/dist/skills/task-workflow.js.map +1 -1
  107. package/dist/storage/backend.d.ts +1 -1
  108. package/dist/storage/backend.d.ts.map +1 -1
  109. package/dist/storage/cosmos-client.js +1 -1
  110. package/dist/storage/cosmos-client.js.map +1 -1
  111. package/dist/storage/lancedb-backend.d.ts +1 -1
  112. package/dist/storage/lancedb-backend.d.ts.map +1 -1
  113. package/dist/storage/schema-init.d.ts +12 -0
  114. package/dist/storage/schema-init.d.ts.map +1 -0
  115. package/dist/storage/schema-init.js +199 -0
  116. package/dist/storage/schema-init.js.map +1 -0
  117. package/dist/storage/store.d.ts +1 -1
  118. package/dist/storage/store.d.ts.map +1 -1
  119. package/dist/storage/store.js +1 -1
  120. package/dist/storage/store.js.map +1 -1
  121. package/dist/storage/task-compaction.d.ts +1 -1
  122. package/dist/storage/task-compaction.d.ts.map +1 -1
  123. package/dist/storage/task-context-snapshot.d.ts +1 -1
  124. package/dist/storage/task-context-snapshot.d.ts.map +1 -1
  125. package/dist/storage/trigger-engine.d.ts +1 -1
  126. package/dist/storage/trigger-engine.d.ts.map +1 -1
  127. package/dist/storage/trigger-engine.js +0 -0
  128. package/dist/tools/context.d.ts +3 -0
  129. package/dist/tools/context.d.ts.map +1 -0
  130. package/dist/tools/context.js +45 -0
  131. package/dist/tools/context.js.map +1 -0
  132. package/dist/tools/gold.d.ts +3 -0
  133. package/dist/tools/gold.d.ts.map +1 -0
  134. package/dist/tools/gold.js +136 -0
  135. package/dist/tools/gold.js.map +1 -0
  136. package/dist/tools/index.d.ts +3 -0
  137. package/dist/tools/index.d.ts.map +1 -0
  138. package/dist/tools/index.js +15 -0
  139. package/dist/tools/index.js.map +1 -0
  140. package/dist/tools/memory.d.ts +3 -0
  141. package/dist/tools/memory.d.ts.map +1 -0
  142. package/dist/tools/memory.js +187 -0
  143. package/dist/tools/memory.js.map +1 -0
  144. package/dist/tools/tasks.d.ts +3 -0
  145. package/dist/tools/tasks.d.ts.map +1 -0
  146. package/dist/tools/tasks.js +86 -0
  147. package/dist/tools/tasks.js.map +1 -0
  148. package/dist/transport/client.js +1 -1
  149. package/dist/transport/client.js.map +1 -1
  150. package/dist/transport/http-server.d.ts.map +1 -1
  151. package/dist/transport/http-server.js +12 -13
  152. package/dist/transport/http-server.js.map +1 -1
  153. package/dist/types.d.ts +1 -184
  154. package/dist/types.d.ts.map +1 -1
  155. package/dist/types.js +4 -2
  156. package/dist/types.js.map +1 -1
  157. package/dist/utils/mcp-slim-ack.d.ts +12 -0
  158. package/dist/utils/mcp-slim-ack.d.ts.map +1 -0
  159. package/dist/utils/mcp-slim-ack.js +16 -0
  160. package/dist/utils/mcp-slim-ack.js.map +1 -0
  161. package/package.json +3 -3
  162. package/scripts/run-server.mjs +1 -1
  163. package/scripts/stdio-only.mjs +4 -22
package/README.md CHANGED
@@ -1,48 +1,60 @@
1
- # agentcore
1
+ # @davidjinguoxu/agentcore
2
2
 
3
- > Shared memory and coordination layer for multi-agent AI workflows.
4
- > MCP server + REST API. Works locally with zero config. Scales to Azure.
3
+ > Local-first AI memory engine for multi-agent workflows.
4
+ > 17-tool MCP server. Zero config (LanceDB) or Azure (Cosmos + AI Search).
5
5
 
6
- Any AI tool that speaks MCP — Cursor, Claude Code, Copilot CLI, Codex connects to
7
- this server and gains persistent memory, task coordination, and shared knowledge across
8
- every session.
6
+ Any AI tool that speaks MCP — Cursor Agent, Gemini CLI, GitHub Copilot, Claude Code
7
+ connects to this server and gains persistent memory, task coordination, and a shared
8
+ knowledge graph across every session.
9
9
 
10
10
  ---
11
11
 
12
12
  ## Quick start
13
13
 
14
14
  ```bash
15
- npx agentcore
15
+ npx @davidjinguoxu/agentcore
16
16
  ```
17
17
 
18
- That's it. The server starts on port 3001, stores data locally in `~/.agentcore/` using
19
- LanceDB, and is immediately available to any MCP client. No account, no API key, no config.
18
+ Starts on port 3001. Stores data in `~/.agentcore/` using LanceDB. No account, no API key.
20
19
 
21
20
  ---
22
21
 
23
22
  ## Connect your AI tool
24
23
 
25
- Add to your MCP client config (Claude Code, Cursor, Copilot, etc.):
26
-
24
+ **Cursor Agent** (`~/.cursor/mcp.json`):
27
25
  ```json
28
26
  {
29
27
  "mcpServers": {
30
- "datacore": {
28
+ "agentcore": {
31
29
  "command": "npx",
32
- "args": ["agentcore"]
30
+ "args": ["@davidjinguoxu/agentcore"],
31
+ "env": { "MCP_API_KEY": "your-key" }
33
32
  }
34
33
  }
35
34
  }
36
35
  ```
37
36
 
38
- For **Claude Desktop**, add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
37
+ **Gemini CLI** (`~/.gemini/settings.json`):
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "agentcore": {
42
+ "command": "npx",
43
+ "args": ["@davidjinguoxu/agentcore"],
44
+ "env": { "MCP_API_KEY": "your-key" }
45
+ }
46
+ }
47
+ }
48
+ ```
39
49
 
50
+ **GitHub Copilot** (`~/.copilot/mcp-config.json`):
40
51
  ```json
41
52
  {
42
53
  "mcpServers": {
43
- "datacore": {
54
+ "agentcore": {
44
55
  "command": "npx",
45
- "args": ["agentcore"]
56
+ "args": ["@davidjinguoxu/agentcore"],
57
+ "env": { "MCP_API_KEY": "your-key" }
46
58
  }
47
59
  }
48
60
  }
@@ -50,149 +62,95 @@ For **Claude Desktop**, add to `~/Library/Application Support/Claude/claude_desk
50
62
 
51
63
  ---
52
64
 
53
- ## What's included
54
-
55
- ### 17 MCP tools across 4 categories
56
-
57
- **Context**
58
- | Tool | What it does |
59
- |---|---|
60
- | `warm_start` | Assemble full task context: spec, gotchas, knowledge graph, retry history |
61
-
62
- **Memory & search**
63
- | Tool | What it does |
64
- |---|---|
65
- | `log_event` | Append any event to the Bronze memory layer |
66
- | `search` | Full-text search across all events |
67
- | `deep_search` | Semantic (vector) search — finds by meaning, not keyword |
68
- | `get_facts` | Query curated Gold entities (decisions, lessons, skills) |
69
- | `get_linked` | Traverse the knowledge graph from any entity |
70
- | `add_entity` | Create or update a Gold entity |
71
- | `get_tasks` | Read the task board |
72
- | `get_questions` | Read async AI-to-AI questions |
73
-
74
- **Task lifecycle**
75
- | Tool | What it does |
76
- |---|---|
77
- | `start_task` | Mark a task in progress |
78
- | `complete_task` | Mark complete — auto-captures tool sequence |
79
- | `update_task` | Log progress (loop detection at 4×, compaction at 8×) |
80
- | `block_task` | Record a blocker |
81
- | `fail_task` | Record a failure |
82
-
83
- **Knowledge**
84
- | Tool | What it does |
85
- |---|---|
86
- | `save_lesson` | Extract a reusable lesson from a task |
87
- | `save_decision` | Record an architecture decision with rationale |
88
- | `ask_team` | Post an async question to another agent |
65
+ ## The 17 tools
89
66
 
90
- ### Skills
67
+ Organized in 5 categories:
91
68
 
92
- Datacore ships with a set of AI-callable skills in `skills/datacore/`. These are
93
- standalone scripts any agent can invoke as part of completing a task:
69
+ | Category | Tools | Layer |
70
+ |---|---|---|
71
+ | Memory | `log_event`, `search`, `deep_search`, `get_questions` | Bronze |
72
+ | Tasks | `start_task`, `update_task`, `complete_task`, `block_task`, `fail_task`, `get_tasks` | Bronze |
73
+ | Knowledge | `add_entity`, `get_facts`, `get_linked` | Gold |
74
+ | Insights | `save_lesson`, `save_decision`, `ask_team` | Bronze→Gold |
75
+ | Context | `warm_start` | All layers |
94
76
 
95
- | Skill | What it does |
96
- |---|---|
97
- | `promote-to-gold.mjs` | Promote Bronze events → curated Gold entities |
98
- | `backfill-search.mjs` | Index Bronze events into the Silver search layer |
99
- | `backfill-links.mjs` | Build knowledge graph links between entities |
100
- | `enrich-memory.mjs` | Enrich session startup context |
101
- | `export-obsidian.mjs` | Export the knowledge graph to Obsidian markdown |
77
+ Full reference: [docs/TOOLS.md](docs/TOOLS.md)
102
78
 
103
79
  ---
104
80
 
105
- ## Data architecture
106
-
107
- Datacore stores everything in a three-layer medallion pattern:
81
+ ## Three-layer architecture
108
82
 
109
83
  ```
110
- Bronze Append-only event log. Every agent action lands here.
111
- Local: LanceDB in ~/.agentcore/ Cloud: Azure Cosmos DB
112
-
113
- Silver Vector-indexed for semantic search.
114
- Local: LanceDB full-text index Cloud: Azure AI Search
115
-
116
- Gold Curated facts — decisions, lessons, skills, agent journals.
117
- 225+ entities. Queried via get_facts() and get_linked().
84
+ Bronze → raw events (append-only, every AI action)
85
+ Silver → vector index (semantic search)
86
+ Gold → knowledge graph (permanent curated facts)
118
87
  ```
119
88
 
120
- ---
121
-
122
- ## Upgrade to Azure (cloud mode)
89
+ Every piece of data starts in Bronze. Content-rich events get indexed in Silver.
90
+ Important facts get promoted to Gold via `add_entity`.
123
91
 
124
- To persist across machines and share memory between a real team,
125
- set Cosmos DB credentials and the engine switches to cloud mode automatically:
92
+ `warm_start` reads all three layers and assembles a context preamble for the agent.
126
93
 
127
- ```bash
128
- export COSMOS_ENDPOINT="https://your-cosmos.documents.azure.com:443/"
129
- export COSMOS_KEY="your-key"
130
- npx agentcore
131
- ```
94
+ Full design: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
132
95
 
133
- Optional: add Azure AI Search for semantic search across large event volumes:
96
+ ---
134
97
 
135
- ```bash
136
- export AZURE_SEARCH_ENDPOINT="https://your-search.search.windows.net"
137
- export AZURE_SEARCH_KEY="your-key"
138
- ```
98
+ ## Storage backends
139
99
 
140
- No code changes. No config file. The engine detects credentials at startup
141
- and selects the right backend automatically.
100
+ | Mode | Condition | Data location |
101
+ |---|---|---|
102
+ | LanceDB (default) | No `COSMOS_ENDPOINT` | `~/.agentcore/` |
103
+ | Azure Cosmos DB | `COSMOS_ENDPOINT` + `COSMOS_KEY` set | Azure cloud |
104
+ | Azure AI Search | `AZURE_SEARCH_ENDPOINT` + `AZURE_SEARCH_KEY` | Azure (Silver layer) |
142
105
 
143
106
  ---
144
107
 
145
- ## HTTP API
146
-
147
- The engine also exposes a REST API on port 3001 alongside the MCP server.
148
- Useful for shell scripts, cron jobs, or any tool that can't run MCP:
108
+ ## Environment variables
149
109
 
150
110
  ```bash
151
- # Log an event
152
- curl -X POST http://localhost:3001/events \
153
- -H "Content-Type: application/json" \
154
- -d '{"source":"my-tool","type":"note","content":"built the widget"}'
155
-
156
- # Search
157
- curl "http://localhost:3001/search?q=widget"
158
-
159
- # Task board
160
- curl http://localhost:3001/tasks
111
+ AGENTCORE_DATA_DIR=~/.agentcore # local data directory
112
+ AGENTCORE_PORT=3001 # HTTP port
113
+ MCP_API_KEY=your-key # auth key for HTTP endpoints
114
+
115
+ # Cloud (optional)
116
+ COSMOS_ENDPOINT=https://...
117
+ COSMOS_KEY=...
118
+ AZURE_SEARCH_ENDPOINT=https://...
119
+ AZURE_SEARCH_KEY=...
161
120
  ```
162
121
 
163
- Full reference: `API.md` in the datacore repo.
164
-
165
- ---
166
-
167
- ## Requirements
168
-
169
- - Node.js >= 22
170
- - No other dependencies for local mode
171
-
172
122
  ---
173
123
 
174
124
  ## Use as a library
175
125
 
176
- ```typescript
177
- import { appendEvent, queryEntities } from 'agentcore';
178
- import type { BronzeRecord, GoldEntity } from 'agentcore/types';
179
-
180
- await appendEvent({
181
- source: 'my-agent',
182
- type: 'task_completed',
183
- content: 'Finished building the widget',
184
- project: 'my-project',
185
- });
126
+ ```bash
127
+ npm install @davidjinguoxu/agentcore
128
+ ```
186
129
 
187
- const { entities } = await queryEntities({ entity_type: 'decision' });
130
+ ```typescript
131
+ import { appendEvent, queryEntities } from '@davidjinguoxu/agentcore';
132
+ import type { BronzeRecord, GoldEntity } from '@davidjinguoxu/agentcore/types';
188
133
  ```
189
134
 
190
135
  ---
191
136
 
192
- ## License
137
+ ## Documentation
193
138
 
194
- MIT
139
+ | Doc | What it covers |
140
+ |---|---|
141
+ | [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Three-layer data model + all type definitions |
142
+ | [SCHEMA.md](docs/SCHEMA.md) | 7 database tables with CREATE TABLE SQL |
143
+ | [MEMORY.md](docs/MEMORY.md) | Hierarchical memory: tiers, time decay, graph traversal |
144
+ | [ACTIVE-SCHEMA.md](docs/ACTIVE-SCHEMA.md) | Each table's lifecycle + concrete use cases |
145
+ | [TOOLS.md](docs/TOOLS.md) | 17 MCP tools: inputs, outputs, database mapping |
146
+ | [SKILLS.md](docs/SKILLS.md) | 4 skill workflows built on top of tools |
147
+ | [MIGRATION.md](docs/MIGRATION.md) | Gap analysis + implementation phases |
195
148
 
196
149
  ---
197
150
 
198
- *Built by [David Xu](https://github.com/david3xu) · Part of the Datacore project*
151
+ ## npm
152
+
153
+ ```
154
+ @davidjinguoxu/agentcore
155
+ https://www.npmjs.com/package/@davidjinguoxu/agentcore
156
+ ```
@@ -0,0 +1,21 @@
1
+ /** Semantic version from this package's package.json (MCP server metadata). */
2
+ export declare function getMcpServerPackageVersion(): string;
3
+ export declare function getCosmosDatabaseName(): string;
4
+ export declare function getCosmosBronzeContainerName(): string;
5
+ export declare function getCosmosGoldContainerName(): string;
6
+ /** Display / API string for the active bronze Cosmos path (not a real URL scheme). */
7
+ export declare function getCosmosBronzeUriString(): string;
8
+ /** Display / API string for the gold Cosmos path. */
9
+ export declare function getCosmosGoldUriString(): string;
10
+ /** HTTP listen port (default 3001). */
11
+ export declare function getHttpPort(): number;
12
+ /** Base URL for HTTP clients. */
13
+ export declare function getHttpBaseUrl(): string;
14
+ /**
15
+ * Resolved API key for HTTP auth: production callers should set MCP_API_KEY.
16
+ * In dev, falls back to AGENTCORE_DEV_KEY / DATACORE_HTTP_DEV_FALLBACK_KEY.
17
+ */
18
+ export declare function getApiKey(): string;
19
+ /** Insecure dev-only API key when MCP_API_KEY is unset (non-production only). */
20
+ export declare function getHttpDevFallbackApiKey(): string;
21
+ //# sourceMappingURL=agentcore-constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentcore-constants.d.ts","sourceRoot":"","sources":["../../src/config/agentcore-constants.ts"],"names":[],"mappings":"AAWA,+EAA+E;AAC/E,wBAAgB,0BAA0B,IAAI,MAAM,CAQnD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAMrD;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAMnD;AAED,sFAAsF;AACtF,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED,qDAAqD;AACrD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,uCAAuC;AACvC,wBAAgB,WAAW,IAAI,MAAM,CAKpC;AAED,iCAAiC;AACjC,wBAAgB,cAAc,IAAI,MAAM,CAMvC;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAOlC;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,IAAI,MAAM,CAMjD"}
@@ -0,0 +1,68 @@
1
+ // agentcore-constants.ts — Single source for package version and Cosmos display URIs.
2
+ // Database / container names are overridable for non-default Cosmos layouts.
3
+ // Env vars: AGENTCORE_* preferred; DATACORE_* accepted as legacy aliases.
4
+ import { readFileSync } from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ const packageDir = dirname(fileURLToPath(import.meta.url));
8
+ let cachedPackageVersion;
9
+ /** Semantic version from this package's package.json (MCP server metadata). */
10
+ export function getMcpServerPackageVersion() {
11
+ if (cachedPackageVersion === undefined) {
12
+ const pkgPath = join(packageDir, "..", "..", "package.json");
13
+ const raw = readFileSync(pkgPath, "utf8");
14
+ const pkg = JSON.parse(raw);
15
+ cachedPackageVersion = pkg.version ?? "0.0.0";
16
+ }
17
+ return cachedPackageVersion;
18
+ }
19
+ export function getCosmosDatabaseName() {
20
+ return (process.env.AGENTCORE_COSMOS_DATABASE ??
21
+ process.env.DATACORE_COSMOS_DATABASE ??
22
+ "datacore");
23
+ }
24
+ export function getCosmosBronzeContainerName() {
25
+ return (process.env.AGENTCORE_COSMOS_BRONZE_CONTAINER ??
26
+ process.env.DATACORE_COSMOS_BRONZE_CONTAINER ??
27
+ "bronze");
28
+ }
29
+ export function getCosmosGoldContainerName() {
30
+ return (process.env.AGENTCORE_COSMOS_GOLD_CONTAINER ??
31
+ process.env.DATACORE_COSMOS_GOLD_CONTAINER ??
32
+ "gold");
33
+ }
34
+ /** Display / API string for the active bronze Cosmos path (not a real URL scheme). */
35
+ export function getCosmosBronzeUriString() {
36
+ return `cosmos://${getCosmosDatabaseName()}/${getCosmosBronzeContainerName()}`;
37
+ }
38
+ /** Display / API string for the gold Cosmos path. */
39
+ export function getCosmosGoldUriString() {
40
+ return `cosmos://${getCosmosDatabaseName()}/${getCosmosGoldContainerName()}`;
41
+ }
42
+ /** HTTP listen port (default 3001). */
43
+ export function getHttpPort() {
44
+ return parseInt(process.env.AGENTCORE_PORT ?? process.env.DATACORE_HTTP_PORT ?? "3001", 10);
45
+ }
46
+ /** Base URL for HTTP clients. */
47
+ export function getHttpBaseUrl() {
48
+ return (process.env.AGENTCORE_BASE_URL ??
49
+ process.env.DATACORE_HTTP_BASE_URL ??
50
+ `http://localhost:${getHttpPort()}`);
51
+ }
52
+ /**
53
+ * Resolved API key for HTTP auth: production callers should set MCP_API_KEY.
54
+ * In dev, falls back to AGENTCORE_DEV_KEY / DATACORE_HTTP_DEV_FALLBACK_KEY.
55
+ */
56
+ export function getApiKey() {
57
+ return (process.env.MCP_API_KEY ??
58
+ process.env.AGENTCORE_DEV_KEY ??
59
+ process.env.DATACORE_HTTP_DEV_FALLBACK_KEY ??
60
+ "dev-key-change-me");
61
+ }
62
+ /** Insecure dev-only API key when MCP_API_KEY is unset (non-production only). */
63
+ export function getHttpDevFallbackApiKey() {
64
+ return (process.env.AGENTCORE_DEV_KEY ??
65
+ process.env.DATACORE_HTTP_DEV_FALLBACK_KEY ??
66
+ "dev-key-change-me");
67
+ }
68
+ //# sourceMappingURL=agentcore-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentcore-constants.js","sourceRoot":"","sources":["../../src/config/agentcore-constants.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,6EAA6E;AAC7E,0EAA0E;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,IAAI,oBAAwC,CAAC;AAE7C,+EAA+E;AAC/E,MAAM,UAAU,0BAA0B;IACxC,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACpD,oBAAoB,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChD,CAAC;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACrC,OAAO,CAAC,GAAG,CAAC,wBAAwB;QACpC,UAAU,CACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,iCAAiC;QAC7C,OAAO,CAAC,GAAG,CAAC,gCAAgC;QAC5C,QAAQ,CACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,+BAA+B;QAC3C,OAAO,CAAC,GAAG,CAAC,8BAA8B;QAC1C,MAAM,CACP,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,wBAAwB;IACtC,OAAO,YAAY,qBAAqB,EAAE,IAAI,4BAA4B,EAAE,EAAE,CAAC;AACjF,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,sBAAsB;IACpC,OAAO,YAAY,qBAAqB,EAAE,IAAI,0BAA0B,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,WAAW;IACzB,OAAO,QAAQ,CACb,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,MAAM,EACtE,EAAE,CACH,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,cAAc;IAC5B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAClC,oBAAoB,WAAW,EAAE,EAAE,CACpC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,WAAW;QACvB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,OAAO,CAAC,GAAG,CAAC,8BAA8B;QAC1C,mBAAmB,CACpB,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,wBAAwB;IACtC,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,OAAO,CAAC,GAAG,CAAC,8BAA8B;QAC1C,mBAAmB,CACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { QuestionInput, QuestionResult } from "../../models/index.js";
2
+ export declare function getQuestions({ directed_to, status, task_id, limit, }?: QuestionInput): Promise<QuestionResult>;
3
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../../src/domain/bronze/questions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,aAAa,EAEb,cAAc,EACf,MAAM,uBAAuB,CAAC;AAG/B,wBAAsB,YAAY,CAAC,EACjC,WAAW,EACX,MAAe,EACf,OAAO,EACP,KAAU,GACX,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAkE9C"}
@@ -0,0 +1,60 @@
1
+ // questions.ts — How do AI agents ask each other questions asynchronously?
2
+ import { readAllRecords } from "../../storage/store.js";
3
+ export async function getQuestions({ directed_to, status = "open", task_id, limit = 10, } = {}) {
4
+ const { bronzeDir, records } = await readAllRecords({});
5
+ // Collect all question and answer events
6
+ const questions = records.filter((r) => r.type === "question");
7
+ const answers = records.filter((r) => r.type === "answer");
8
+ // Index answers by thread_id for fast lookup
9
+ const answerMap = new Map();
10
+ for (const a of answers) {
11
+ const tid = a.context?.thread_id;
12
+ if (tid)
13
+ answerMap.set(tid, a);
14
+ }
15
+ const results = [];
16
+ for (const q of questions) {
17
+ const ctx = q.context ?? {};
18
+ const threadId = ctx.thread_id ?? "";
19
+ if (!threadId)
20
+ continue;
21
+ const answerRecord = answerMap.get(threadId);
22
+ const isAnswered = !!answerRecord;
23
+ // Filter by status
24
+ if (status === "open" && isAnswered)
25
+ continue;
26
+ if (status === "answered" && !isAnswered)
27
+ continue;
28
+ // Filter by directed_to
29
+ const directedTo = ctx.directed_to ?? null;
30
+ if (directed_to && directedTo?.toLowerCase() !== directed_to.toLowerCase())
31
+ continue;
32
+ // Filter by task_id
33
+ const qTaskId = ctx.task_id ?? null;
34
+ if (task_id && qTaskId !== task_id)
35
+ continue;
36
+ const answerCtx = answerRecord
37
+ ? (answerRecord.context ?? {})
38
+ : {};
39
+ results.push({
40
+ thread_id: threadId,
41
+ question: q.content ?? "",
42
+ asked_by: ctx.asked_by ?? q._source ?? null,
43
+ directed_to: directedTo,
44
+ task_id: qTaskId,
45
+ status: isAnswered ? "answered" : "open",
46
+ asked_at: q._timestamp ?? null,
47
+ answered_at: answerRecord?._timestamp ?? null,
48
+ answer: answerRecord?.content ?? null,
49
+ answered_by: answerCtx.answered_by ?? answerRecord?._source ?? null,
50
+ });
51
+ }
52
+ // Sort newest first
53
+ results.sort((a, b) => (b.asked_at ?? "").localeCompare(a.asked_at ?? ""));
54
+ return {
55
+ bronzeDir,
56
+ total: results.length,
57
+ questions: results.slice(0, limit),
58
+ };
59
+ }
60
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.js","sourceRoot":"","sources":["../../../src/domain/bronze/questions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ActiveRun {
2
+ run_id: string;
3
+ task_id: string;
4
+ started_at: string;
5
+ agent: string;
6
+ }
7
+ declare const activeRuns: Map<string, ActiveRun>;
8
+ export declare function generateRunId(taskId: string): string;
9
+ export declare function registerActiveRun(run: ActiveRun): ActiveRun;
10
+ export declare function getActiveRun(taskId: string): ActiveRun | undefined;
11
+ export declare function completeActiveRun(taskId: string): ActiveRun | undefined;
12
+ export declare function listActiveRuns(): ActiveRun[];
13
+ export { activeRuns as activeRunsMap };
14
+ //# sourceMappingURL=run-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../../../src/domain/bronze/run-manager.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,QAAA,MAAM,UAAU,wBAA+B,CAAC;AAEhD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAG3D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAElE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAIvE;AAED,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAE5C;AAED,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { randomUUID } from "node:crypto";
2
+ const activeRuns = new Map();
3
+ export function generateRunId(taskId) {
4
+ const trimmed = (taskId ?? "").trim();
5
+ const safeTaskId = trimmed.length > 0 ? trimmed.replace(/\s+/g, "-") : "task";
6
+ return `${safeTaskId}-run-${randomUUID()}`;
7
+ }
8
+ export function registerActiveRun(run) {
9
+ activeRuns.set(run.task_id, run);
10
+ return run;
11
+ }
12
+ export function getActiveRun(taskId) {
13
+ return activeRuns.get(taskId);
14
+ }
15
+ export function completeActiveRun(taskId) {
16
+ const run = activeRuns.get(taskId);
17
+ if (run)
18
+ activeRuns.delete(taskId);
19
+ return run;
20
+ }
21
+ export function listActiveRuns() {
22
+ return [...activeRuns.values()];
23
+ }
24
+ export { activeRuns as activeRunsMap };
25
+ //# sourceMappingURL=run-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-manager.js","sourceRoot":"","sources":["../../../src/domain/bronze/run-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;AAEhD,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9E,OAAO,GAAG,UAAU,QAAQ,UAAU,EAAE,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAc;IAC9C,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,GAAG;QAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ export interface TaskAssignment {
2
+ taskId: string;
3
+ assignedTo: string;
4
+ timestamp: string;
5
+ isReview: boolean;
6
+ source: string | null;
7
+ content: string | null;
8
+ }
9
+ export interface TaskTimeline {
10
+ taskId: string;
11
+ status: string;
12
+ assignedTo: string | null;
13
+ latestType: string | null;
14
+ latestTimestamp: string | null;
15
+ latestContent: string | null;
16
+ createdTimestamp: string | null;
17
+ createdContent: string | null;
18
+ assignments: TaskAssignment[];
19
+ reviewAssignments: TaskAssignment[];
20
+ startedTimestamps: string[];
21
+ completedTimestamps: string[];
22
+ reviewedTimestamps: string[];
23
+ blocked: boolean;
24
+ contextTimestamps: string[];
25
+ }
26
+ export interface TaskEventIndex {
27
+ tasks: Map<string, TaskTimeline>;
28
+ taskContextIds: Set<string>;
29
+ }
30
+ export declare function loadTaskEventIndex(): Promise<TaskEventIndex>;
31
+ //# sourceMappingURL=task-event-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-event-index.d.ts","sourceRoot":"","sources":["../../../src/domain/bronze/task-event-index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B;AA8BD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,CAAC,CAsGlE"}
@@ -0,0 +1,117 @@
1
+ // task-event-index.ts — Aggregate task-related events for inbox and status views.
2
+ import { readAllRecords } from "../../storage/store.js";
3
+ function ensureTimeline(map, taskId) {
4
+ let timeline = map.get(taskId);
5
+ if (!timeline) {
6
+ timeline = {
7
+ taskId,
8
+ status: "unknown",
9
+ assignedTo: null,
10
+ latestType: null,
11
+ latestTimestamp: null,
12
+ latestContent: null,
13
+ createdTimestamp: null,
14
+ createdContent: null,
15
+ assignments: [],
16
+ reviewAssignments: [],
17
+ startedTimestamps: [],
18
+ completedTimestamps: [],
19
+ reviewedTimestamps: [],
20
+ blocked: false,
21
+ contextTimestamps: [],
22
+ };
23
+ map.set(taskId, timeline);
24
+ }
25
+ return timeline;
26
+ }
27
+ export async function loadTaskEventIndex() {
28
+ const { records } = await readAllRecords({ type: "task_" });
29
+ const tasks = new Map();
30
+ const taskContextIds = new Set();
31
+ const sorted = [...records].sort((a, b) => (a._timestamp ?? "").localeCompare(b._timestamp ?? ""));
32
+ for (const record of sorted) {
33
+ const context = record.context ?? {};
34
+ const taskId = typeof context.task_id === "string" ? context.task_id : null;
35
+ const timestamp = record._timestamp ?? new Date().toISOString();
36
+ if (record.type === "task_context" && taskId) {
37
+ taskContextIds.add(taskId);
38
+ }
39
+ if (!taskId)
40
+ continue;
41
+ const timeline = ensureTimeline(tasks, taskId);
42
+ timeline.latestType = record.type ?? timeline.latestType;
43
+ timeline.latestTimestamp = record._timestamp ?? timeline.latestTimestamp;
44
+ if (record.type === "task_created" && !timeline.createdTimestamp) {
45
+ timeline.createdTimestamp = timestamp;
46
+ timeline.createdContent = record.content ?? null;
47
+ if (timeline.status === "unknown") {
48
+ timeline.status = "created";
49
+ }
50
+ }
51
+ timeline.latestContent = record.content ?? timeline.latestContent;
52
+ if (typeof context.status === "string") {
53
+ timeline.status = context.status;
54
+ }
55
+ if (typeof context.assigned_to === "string") {
56
+ timeline.assignedTo = context.assigned_to;
57
+ }
58
+ switch (record.type) {
59
+ case "task_assigned": {
60
+ const assignedTo = typeof context.assigned_to === "string" ? context.assigned_to : null;
61
+ if (assignedTo) {
62
+ const assignment = {
63
+ taskId,
64
+ assignedTo,
65
+ timestamp,
66
+ isReview: context.review === true,
67
+ source: record._source ?? null,
68
+ content: record.content ?? null,
69
+ };
70
+ if (assignment.isReview) {
71
+ timeline.reviewAssignments.push(assignment);
72
+ timeline.status = "review";
73
+ }
74
+ else {
75
+ timeline.assignments.push(assignment);
76
+ if (timeline.status === "unknown")
77
+ timeline.status = "assigned";
78
+ }
79
+ }
80
+ break;
81
+ }
82
+ case "task_started":
83
+ case "task_progress":
84
+ timeline.startedTimestamps.push(timestamp);
85
+ timeline.status = "in_progress";
86
+ break;
87
+ case "task_blocked":
88
+ timeline.blocked = true;
89
+ timeline.status = "blocked";
90
+ break;
91
+ case "task_unblocked":
92
+ timeline.blocked = false;
93
+ timeline.status = "in_progress";
94
+ break;
95
+ case "task_completed":
96
+ timeline.completedTimestamps.push(timestamp);
97
+ timeline.status = "completed";
98
+ break;
99
+ case "task_failed":
100
+ timeline.status = "failed";
101
+ break;
102
+ case "task_reviewed":
103
+ timeline.reviewedTimestamps.push(timestamp);
104
+ if (context.verdict === "fail") {
105
+ timeline.status = "rework";
106
+ }
107
+ break;
108
+ case "task_context":
109
+ timeline.contextTimestamps.push(timestamp);
110
+ break;
111
+ default:
112
+ break;
113
+ }
114
+ }
115
+ return { tasks, taskContextIds };
116
+ }
117
+ //# sourceMappingURL=task-event-index.js.map