@ouro.bot/cli 0.0.1-alpha.0 → 0.1.0-alpha.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.
Files changed (119) hide show
  1. package/AdoptionSpecialist.ouro/agent.json +20 -0
  2. package/AdoptionSpecialist.ouro/psyche/SOUL.md +22 -0
  3. package/AdoptionSpecialist.ouro/psyche/identities/basilisk.md +31 -0
  4. package/AdoptionSpecialist.ouro/psyche/identities/jafar.md +31 -0
  5. package/AdoptionSpecialist.ouro/psyche/identities/jormungandr.md +31 -0
  6. package/AdoptionSpecialist.ouro/psyche/identities/kaa.md +31 -0
  7. package/AdoptionSpecialist.ouro/psyche/identities/medusa.md +31 -0
  8. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +31 -0
  9. package/AdoptionSpecialist.ouro/psyche/identities/nagini.md +31 -0
  10. package/AdoptionSpecialist.ouro/psyche/identities/ouroboros.md +31 -0
  11. package/AdoptionSpecialist.ouro/psyche/identities/python.md +31 -0
  12. package/AdoptionSpecialist.ouro/psyche/identities/quetzalcoatl.md +31 -0
  13. package/AdoptionSpecialist.ouro/psyche/identities/sir-hiss.md +31 -0
  14. package/AdoptionSpecialist.ouro/psyche/identities/the-serpent.md +31 -0
  15. package/AdoptionSpecialist.ouro/psyche/identities/the-snake.md +31 -0
  16. package/README.md +224 -6
  17. package/dist/heart/agent-entry.js +17 -0
  18. package/dist/heart/api-error.js +34 -0
  19. package/dist/heart/config.js +296 -0
  20. package/dist/heart/core.js +515 -0
  21. package/dist/heart/daemon/daemon-cli.js +675 -0
  22. package/dist/heart/daemon/daemon-entry.js +74 -0
  23. package/dist/heart/daemon/daemon.js +313 -0
  24. package/dist/heart/daemon/hatch-flow.js +285 -0
  25. package/dist/heart/daemon/hatch-specialist.js +107 -0
  26. package/dist/heart/daemon/health-monitor.js +79 -0
  27. package/dist/heart/daemon/log-tailer.js +146 -0
  28. package/dist/heart/daemon/message-router.js +98 -0
  29. package/dist/heart/daemon/os-cron.js +260 -0
  30. package/dist/heart/daemon/ouro-bot-entry.js +23 -0
  31. package/dist/heart/daemon/ouro-bot-wrapper.js +90 -0
  32. package/dist/heart/daemon/ouro-entry.js +23 -0
  33. package/dist/heart/daemon/ouro-uti.js +212 -0
  34. package/dist/heart/daemon/process-manager.js +237 -0
  35. package/dist/heart/daemon/runtime-logging.js +98 -0
  36. package/dist/heart/daemon/subagent-installer.js +125 -0
  37. package/dist/heart/daemon/task-scheduler.js +240 -0
  38. package/dist/heart/harness.js +26 -0
  39. package/dist/heart/identity.js +281 -0
  40. package/dist/heart/kicks.js +144 -0
  41. package/dist/heart/primitives.js +4 -0
  42. package/dist/heart/providers/anthropic.js +329 -0
  43. package/dist/heart/providers/azure.js +66 -0
  44. package/dist/heart/providers/minimax.js +53 -0
  45. package/dist/heart/providers/openai-codex.js +162 -0
  46. package/dist/heart/streaming.js +412 -0
  47. package/dist/heart/turn-coordinator.js +62 -0
  48. package/dist/inner-worker-entry.js +4 -0
  49. package/dist/mind/associative-recall.js +197 -0
  50. package/dist/mind/bundle-manifest.js +118 -0
  51. package/dist/mind/context.js +302 -0
  52. package/dist/mind/first-impressions.js +43 -0
  53. package/dist/mind/format.js +56 -0
  54. package/dist/mind/friends/channel.js +41 -0
  55. package/dist/mind/friends/resolver.js +84 -0
  56. package/dist/mind/friends/store-file.js +171 -0
  57. package/dist/mind/friends/store.js +4 -0
  58. package/dist/mind/friends/tokens.js +26 -0
  59. package/dist/mind/friends/types.js +21 -0
  60. package/dist/mind/memory.js +388 -0
  61. package/dist/mind/pending.js +93 -0
  62. package/dist/mind/phrases.js +43 -0
  63. package/dist/mind/prompt-refresh.js +20 -0
  64. package/dist/mind/prompt.js +352 -0
  65. package/dist/mind/token-estimate.js +119 -0
  66. package/dist/nerves/cli-logging.js +31 -0
  67. package/dist/nerves/coverage/audit-rules.js +81 -0
  68. package/dist/nerves/coverage/audit.js +200 -0
  69. package/dist/nerves/coverage/cli-main.js +5 -0
  70. package/dist/nerves/coverage/cli.js +51 -0
  71. package/dist/nerves/coverage/contract.js +23 -0
  72. package/dist/nerves/coverage/file-completeness.js +56 -0
  73. package/dist/nerves/coverage/run-artifacts.js +77 -0
  74. package/dist/nerves/coverage/source-scanner.js +34 -0
  75. package/dist/nerves/index.js +152 -0
  76. package/dist/nerves/runtime.js +38 -0
  77. package/dist/repertoire/ado-client.js +211 -0
  78. package/dist/repertoire/ado-context.js +73 -0
  79. package/dist/repertoire/ado-semantic.js +841 -0
  80. package/dist/repertoire/ado-templates.js +146 -0
  81. package/dist/repertoire/coding/index.js +36 -0
  82. package/dist/repertoire/coding/manager.js +489 -0
  83. package/dist/repertoire/coding/monitor.js +60 -0
  84. package/dist/repertoire/coding/reporter.js +45 -0
  85. package/dist/repertoire/coding/spawner.js +102 -0
  86. package/dist/repertoire/coding/tools.js +167 -0
  87. package/dist/repertoire/coding/types.js +2 -0
  88. package/dist/repertoire/data/ado-endpoints.json +122 -0
  89. package/dist/repertoire/data/graph-endpoints.json +212 -0
  90. package/dist/repertoire/github-client.js +64 -0
  91. package/dist/repertoire/graph-client.js +118 -0
  92. package/dist/repertoire/skills.js +156 -0
  93. package/dist/repertoire/tasks/board.js +122 -0
  94. package/dist/repertoire/tasks/index.js +210 -0
  95. package/dist/repertoire/tasks/lifecycle.js +80 -0
  96. package/dist/repertoire/tasks/middleware.js +65 -0
  97. package/dist/repertoire/tasks/parser.js +173 -0
  98. package/dist/repertoire/tasks/scanner.js +132 -0
  99. package/dist/repertoire/tasks/transitions.js +145 -0
  100. package/dist/repertoire/tasks/types.js +2 -0
  101. package/dist/repertoire/tools-base.js +714 -0
  102. package/dist/repertoire/tools-github.js +53 -0
  103. package/dist/repertoire/tools-teams.js +308 -0
  104. package/dist/repertoire/tools.js +199 -0
  105. package/dist/senses/cli-entry.js +15 -0
  106. package/dist/senses/cli.js +604 -0
  107. package/dist/senses/commands.js +98 -0
  108. package/dist/senses/inner-dialog-worker.js +61 -0
  109. package/dist/senses/inner-dialog.js +231 -0
  110. package/dist/senses/session-lock.js +119 -0
  111. package/dist/senses/teams-entry.js +15 -0
  112. package/dist/senses/teams.js +696 -0
  113. package/dist/senses/trust-gate.js +150 -0
  114. package/package.json +34 -11
  115. package/subagents/README.md +73 -0
  116. package/subagents/work-doer.md +233 -0
  117. package/subagents/work-merger.md +624 -0
  118. package/subagents/work-planner.md +373 -0
  119. package/bin/ouro.js +0 -6
@@ -0,0 +1,212 @@
1
+ [
2
+ {
3
+ "path": "/me",
4
+ "method": "GET",
5
+ "description": "Get current user's profile (displayName, mail, jobTitle, department, officeLocation)",
6
+ "params": "$select",
7
+ "scopes": "User.Read"
8
+ },
9
+ {
10
+ "path": "/me/messages",
11
+ "method": "GET",
12
+ "description": "List messages in the signed-in user's mailbox",
13
+ "params": "$top, $filter, $select, $orderby, $search",
14
+ "scopes": "Mail.Read"
15
+ },
16
+ {
17
+ "path": "/me/messages/{id}",
18
+ "method": "GET",
19
+ "description": "Get a specific message by ID",
20
+ "params": "$select",
21
+ "scopes": "Mail.Read"
22
+ },
23
+ {
24
+ "path": "/me/sendMail",
25
+ "method": "POST",
26
+ "description": "Send an email message on behalf of the signed-in user",
27
+ "params": "message (with subject, body, toRecipients), saveToSentItems",
28
+ "scopes": "Mail.Send"
29
+ },
30
+ {
31
+ "path": "/me/messages/{id}",
32
+ "method": "PATCH",
33
+ "description": "Update a message (e.g. mark as read, change category)",
34
+ "params": "isRead, categories, importance",
35
+ "scopes": "Mail.ReadWrite"
36
+ },
37
+ {
38
+ "path": "/me/messages/{id}",
39
+ "method": "DELETE",
40
+ "description": "Delete a message",
41
+ "params": "",
42
+ "scopes": "Mail.ReadWrite"
43
+ },
44
+ {
45
+ "path": "/me/events",
46
+ "method": "GET",
47
+ "description": "List calendar events for the signed-in user",
48
+ "params": "$top, $filter, $select, $orderby, startDateTime, endDateTime",
49
+ "scopes": "Calendars.Read"
50
+ },
51
+ {
52
+ "path": "/me/events",
53
+ "method": "POST",
54
+ "description": "Create a new calendar event",
55
+ "params": "subject, body, start, end, attendees, location, isOnlineMeeting",
56
+ "scopes": "Calendars.ReadWrite"
57
+ },
58
+ {
59
+ "path": "/me/events/{id}",
60
+ "method": "PATCH",
61
+ "description": "Update an existing calendar event",
62
+ "params": "subject, body, start, end, attendees, location",
63
+ "scopes": "Calendars.ReadWrite"
64
+ },
65
+ {
66
+ "path": "/me/events/{id}",
67
+ "method": "DELETE",
68
+ "description": "Delete a calendar event",
69
+ "params": "",
70
+ "scopes": "Calendars.ReadWrite"
71
+ },
72
+ {
73
+ "path": "/me/calendarView",
74
+ "method": "GET",
75
+ "description": "Get calendar view (events in a time range, expands recurring events)",
76
+ "params": "startDateTime (required), endDateTime (required), $top, $select",
77
+ "scopes": "Calendars.Read"
78
+ },
79
+ {
80
+ "path": "/me/drive/root/children",
81
+ "method": "GET",
82
+ "description": "List files and folders in the user's OneDrive root",
83
+ "params": "$top, $select, $filter",
84
+ "scopes": "Files.Read"
85
+ },
86
+ {
87
+ "path": "/me/drive/items/{id}",
88
+ "method": "GET",
89
+ "description": "Get metadata for a specific file or folder in OneDrive",
90
+ "params": "$select",
91
+ "scopes": "Files.Read"
92
+ },
93
+ {
94
+ "path": "/me/drive/items/{id}/content",
95
+ "method": "GET",
96
+ "description": "Download file content from OneDrive",
97
+ "params": "",
98
+ "scopes": "Files.Read"
99
+ },
100
+ {
101
+ "path": "/me/drive/root:/{path}:/content",
102
+ "method": "PUT",
103
+ "description": "Upload a file to OneDrive by path (small files up to 4MB)",
104
+ "params": "request body is file content",
105
+ "scopes": "Files.ReadWrite"
106
+ },
107
+ {
108
+ "path": "/me/drive/items/{id}",
109
+ "method": "DELETE",
110
+ "description": "Delete a file or folder from OneDrive",
111
+ "params": "",
112
+ "scopes": "Files.ReadWrite"
113
+ },
114
+ {
115
+ "path": "/me/chats",
116
+ "method": "GET",
117
+ "description": "List chats for the signed-in user",
118
+ "params": "$top, $filter, $expand",
119
+ "scopes": "Chat.Read"
120
+ },
121
+ {
122
+ "path": "/me/chats/{id}/messages",
123
+ "method": "GET",
124
+ "description": "List messages in a specific chat",
125
+ "params": "$top, $filter",
126
+ "scopes": "Chat.Read"
127
+ },
128
+ {
129
+ "path": "/me/chats/{id}/messages",
130
+ "method": "POST",
131
+ "description": "Send a message to a specific chat",
132
+ "params": "body (with content, contentType)",
133
+ "scopes": "Chat.ReadWrite"
134
+ },
135
+ {
136
+ "path": "/sites/{siteId}",
137
+ "method": "GET",
138
+ "description": "Get a SharePoint site by ID",
139
+ "params": "$select",
140
+ "scopes": "Sites.Read.All"
141
+ },
142
+ {
143
+ "path": "/sites/{siteId}/lists",
144
+ "method": "GET",
145
+ "description": "List SharePoint lists in a site",
146
+ "params": "$top, $select",
147
+ "scopes": "Sites.Read.All"
148
+ },
149
+ {
150
+ "path": "/sites/{siteId}/lists/{listId}/items",
151
+ "method": "GET",
152
+ "description": "List items in a SharePoint list",
153
+ "params": "$top, $filter, $expand, $select",
154
+ "scopes": "Sites.Read.All"
155
+ },
156
+ {
157
+ "path": "/sites/{siteId}/lists/{listId}/items",
158
+ "method": "POST",
159
+ "description": "Create a new item in a SharePoint list",
160
+ "params": "fields (object with column values)",
161
+ "scopes": "Sites.ReadWrite.All"
162
+ },
163
+ {
164
+ "path": "/me/contacts",
165
+ "method": "GET",
166
+ "description": "List contacts for the signed-in user",
167
+ "params": "$top, $filter, $select, $orderby",
168
+ "scopes": "Contacts.Read"
169
+ },
170
+ {
171
+ "path": "/me/contacts",
172
+ "method": "POST",
173
+ "description": "Create a new contact",
174
+ "params": "givenName, surname, emailAddresses, businessPhones, companyName",
175
+ "scopes": "Contacts.ReadWrite"
176
+ },
177
+ {
178
+ "path": "/search/query",
179
+ "method": "POST",
180
+ "description": "Search across Microsoft 365 (messages, files, events, sites)",
181
+ "params": "requests (array with entityTypes, query.queryString)",
182
+ "scopes": "Mail.Read, Files.Read, Calendars.Read"
183
+ },
184
+ {
185
+ "path": "/users",
186
+ "method": "GET",
187
+ "description": "List users in the organization",
188
+ "params": "$top, $filter, $select, $search",
189
+ "scopes": "User.Read.All"
190
+ },
191
+ {
192
+ "path": "/users/{id}",
193
+ "method": "GET",
194
+ "description": "Get a specific user's profile by ID or UPN",
195
+ "params": "$select",
196
+ "scopes": "User.Read.All"
197
+ },
198
+ {
199
+ "path": "/me/memberOf",
200
+ "method": "GET",
201
+ "description": "List groups and directory roles the user is a member of",
202
+ "params": "$top, $filter",
203
+ "scopes": "Directory.Read.All"
204
+ },
205
+ {
206
+ "path": "/me/photo/$value",
207
+ "method": "GET",
208
+ "description": "Get the signed-in user's profile photo (binary)",
209
+ "params": "",
210
+ "scopes": "User.Read"
211
+ }
212
+ ]
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ // GitHub API client.
3
+ // Provides a generic githubRequest() for arbitrary GitHub REST API endpoints.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.githubRequest = githubRequest;
6
+ const api_error_1 = require("../heart/api-error");
7
+ const runtime_1 = require("../nerves/runtime");
8
+ const GITHUB_BASE = "https://api.github.com";
9
+ // Generic GitHub API request. Returns response body as pretty-printed JSON string.
10
+ async function githubRequest(token, method, path, body) {
11
+ try {
12
+ (0, runtime_1.emitNervesEvent)({
13
+ event: "client.request_start",
14
+ component: "clients",
15
+ message: "starting GitHub request",
16
+ meta: { client: "github", method, path },
17
+ });
18
+ const url = `${GITHUB_BASE}${path}`;
19
+ const opts = {
20
+ method,
21
+ headers: {
22
+ Authorization: `Bearer ${token}`,
23
+ Accept: "application/vnd.github+json",
24
+ "Content-Type": "application/json",
25
+ },
26
+ };
27
+ if (body)
28
+ opts.body = body;
29
+ const res = await fetch(url, opts);
30
+ if (!res.ok) {
31
+ (0, runtime_1.emitNervesEvent)({
32
+ level: "error",
33
+ event: "client.error",
34
+ component: "clients",
35
+ message: "GitHub request failed",
36
+ meta: { client: "github", method, path, status: res.status },
37
+ });
38
+ return (0, api_error_1.handleApiError)(res, "GitHub", "github");
39
+ }
40
+ const data = await res.json();
41
+ (0, runtime_1.emitNervesEvent)({
42
+ event: "client.request_end",
43
+ component: "clients",
44
+ message: "GitHub request completed",
45
+ meta: { client: "github", method, path, success: true },
46
+ });
47
+ return JSON.stringify(data, null, 2);
48
+ }
49
+ catch (err) {
50
+ (0, runtime_1.emitNervesEvent)({
51
+ level: "error",
52
+ event: "client.error",
53
+ component: "clients",
54
+ message: "GitHub request threw exception",
55
+ meta: {
56
+ client: "github",
57
+ method,
58
+ path,
59
+ reason: err instanceof Error ? err.message : String(err),
60
+ },
61
+ });
62
+ return (0, api_error_1.handleApiError)(err, "GitHub", "github");
63
+ }
64
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ // Graph API client.
3
+ // Provides a generic graphRequest() for arbitrary endpoints
4
+ // and a thin getProfile() wrapper for backward compatibility.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.graphRequest = graphRequest;
7
+ exports.getProfile = getProfile;
8
+ const api_error_1 = require("../heart/api-error");
9
+ const runtime_1 = require("../nerves/runtime");
10
+ const GRAPH_BASE = "https://graph.microsoft.com/v1.0";
11
+ // Generic Graph API request. Returns response body as pretty-printed JSON string.
12
+ async function graphRequest(token, method, path, body) {
13
+ try {
14
+ (0, runtime_1.emitNervesEvent)({
15
+ event: "client.request_start",
16
+ component: "clients",
17
+ message: "starting Graph request",
18
+ meta: { client: "graph", method, path },
19
+ });
20
+ const url = `${GRAPH_BASE}${path}`;
21
+ const opts = {
22
+ method,
23
+ headers: {
24
+ Authorization: `Bearer ${token}`,
25
+ "Content-Type": "application/json",
26
+ },
27
+ };
28
+ if (body)
29
+ opts.body = body;
30
+ const res = await fetch(url, opts);
31
+ if (!res.ok) {
32
+ (0, runtime_1.emitNervesEvent)({
33
+ level: "error",
34
+ event: "client.error",
35
+ component: "clients",
36
+ message: "Graph request failed",
37
+ meta: { client: "graph", method, path, status: res.status },
38
+ });
39
+ return (0, api_error_1.handleApiError)(res, "Graph", "graph");
40
+ }
41
+ const data = await res.json();
42
+ (0, runtime_1.emitNervesEvent)({
43
+ event: "client.request_end",
44
+ component: "clients",
45
+ message: "Graph request completed",
46
+ meta: { client: "graph", method, path, success: true },
47
+ });
48
+ return JSON.stringify(data, null, 2);
49
+ }
50
+ catch (err) {
51
+ (0, runtime_1.emitNervesEvent)({
52
+ level: "error",
53
+ event: "client.error",
54
+ component: "clients",
55
+ message: "Graph request threw exception",
56
+ meta: {
57
+ client: "graph",
58
+ method,
59
+ path,
60
+ reason: err instanceof Error ? err.message : String(err),
61
+ },
62
+ });
63
+ return (0, api_error_1.handleApiError)(err, "Graph", "graph");
64
+ }
65
+ }
66
+ // Backward-compatible thin wrapper: fetches /me and formats as human-readable text.
67
+ async function getProfile(token) {
68
+ try {
69
+ (0, runtime_1.emitNervesEvent)({
70
+ event: "client.request_start",
71
+ component: "clients",
72
+ message: "starting Graph profile request",
73
+ meta: { client: "graph", operation: "getProfile" },
74
+ });
75
+ const res = await fetch(`${GRAPH_BASE}/me`, {
76
+ headers: { Authorization: `Bearer ${token}` },
77
+ });
78
+ if (!res.ok) {
79
+ (0, runtime_1.emitNervesEvent)({
80
+ level: "error",
81
+ event: "client.error",
82
+ component: "clients",
83
+ message: "Graph profile request failed",
84
+ meta: { client: "graph", operation: "getProfile", status: res.status },
85
+ });
86
+ return (0, api_error_1.handleApiError)(res, "Graph", "graph");
87
+ }
88
+ const profile = (await res.json());
89
+ const lines = [
90
+ `Name: ${profile.displayName}`,
91
+ `Email: ${profile.mail || "N/A"}`,
92
+ `Job Title: ${profile.jobTitle || "N/A"}`,
93
+ `Department: ${profile.department || "N/A"}`,
94
+ `Office: ${profile.officeLocation || "N/A"}`,
95
+ ];
96
+ (0, runtime_1.emitNervesEvent)({
97
+ event: "client.request_end",
98
+ component: "clients",
99
+ message: "Graph profile request completed",
100
+ meta: { client: "graph", operation: "getProfile", success: true },
101
+ });
102
+ return lines.join("\n");
103
+ }
104
+ catch (err) {
105
+ (0, runtime_1.emitNervesEvent)({
106
+ level: "error",
107
+ event: "client.error",
108
+ component: "clients",
109
+ message: "Graph profile request threw exception",
110
+ meta: {
111
+ client: "graph",
112
+ operation: "getProfile",
113
+ reason: err instanceof Error ? err.message : String(err),
114
+ },
115
+ });
116
+ return (0, api_error_1.handleApiError)(err, "Graph", "graph");
117
+ }
118
+ }
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getSkillsDir = getSkillsDir;
37
+ exports.listSkills = listSkills;
38
+ exports.loadSkill = loadSkill;
39
+ exports.getLoadedSkills = getLoadedSkills;
40
+ exports.clearLoadedSkills = clearLoadedSkills;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const identity_1 = require("../heart/identity");
44
+ const runtime_1 = require("../nerves/runtime");
45
+ // Skills live in {agentRoot}/skills/ directory
46
+ function getSkillsDir() {
47
+ return path.join((0, identity_1.getAgentRoot)(), "skills");
48
+ }
49
+ // Protocol mirror files live in {agentRoot}/skills/protocols/.
50
+ function getProtocolMirrorDir() {
51
+ return path.join(getSkillsDir(), "protocols");
52
+ }
53
+ // Canonical protocol source lives in {repoRoot}/subagents/.
54
+ function getCanonicalProtocolsDir() {
55
+ return path.join((0, identity_1.getRepoRoot)(), "subagents");
56
+ }
57
+ function listMarkdownBasenames(dir) {
58
+ if (!fs.existsSync(dir))
59
+ return [];
60
+ return fs
61
+ .readdirSync(dir)
62
+ .filter((f) => f.endsWith(".md"))
63
+ .map((f) => path.basename(f, ".md"))
64
+ .sort();
65
+ }
66
+ // in-memory store for loaded skills
67
+ const loadedSkills = [];
68
+ function listSkills() {
69
+ (0, runtime_1.emitNervesEvent)({
70
+ event: "repertoire.load_start",
71
+ component: "repertoire",
72
+ message: "listing skills",
73
+ meta: { operation: "listSkills" },
74
+ });
75
+ const baseSkills = listMarkdownBasenames(getSkillsDir());
76
+ const protocolMirrors = listMarkdownBasenames(getProtocolMirrorDir());
77
+ const canonicalProtocols = listMarkdownBasenames(getCanonicalProtocolsDir());
78
+ const skills = [...new Set([...baseSkills, ...protocolMirrors, ...canonicalProtocols])].sort();
79
+ (0, runtime_1.emitNervesEvent)({
80
+ event: "repertoire.load_end",
81
+ component: "repertoire",
82
+ message: "listed skills",
83
+ meta: { operation: "listSkills", count: skills.length },
84
+ });
85
+ return skills;
86
+ }
87
+ function loadSkill(skillName) {
88
+ (0, runtime_1.emitNervesEvent)({
89
+ event: "repertoire.load_start",
90
+ component: "repertoire",
91
+ message: "loading skill",
92
+ meta: { operation: "loadSkill", skill: skillName },
93
+ });
94
+ const directSkillPath = path.join(getSkillsDir(), `${skillName}.md`);
95
+ const protocolMirrorPath = path.join(getProtocolMirrorDir(), `${skillName}.md`);
96
+ const canonicalProtocolPath = path.join(getCanonicalProtocolsDir(), `${skillName}.md`);
97
+ let resolvedPath = null;
98
+ // 1) Direct agent skill.
99
+ if (fs.existsSync(directSkillPath)) {
100
+ resolvedPath = directSkillPath;
101
+ }
102
+ // 2) Protocol mirror in bundle.
103
+ else if (fs.existsSync(protocolMirrorPath)) {
104
+ resolvedPath = protocolMirrorPath;
105
+ }
106
+ // 3) Canonical protocol fallback.
107
+ else if (fs.existsSync(canonicalProtocolPath)) {
108
+ (0, runtime_1.emitNervesEvent)({
109
+ level: "warn",
110
+ event: "repertoire.error",
111
+ component: "repertoire",
112
+ message: "protocol mirror missing; using canonical fallback",
113
+ meta: {
114
+ operation: "loadSkill",
115
+ skill: skillName,
116
+ mirrorPath: protocolMirrorPath,
117
+ canonicalPath: canonicalProtocolPath,
118
+ },
119
+ });
120
+ resolvedPath = canonicalProtocolPath;
121
+ }
122
+ if (!resolvedPath) {
123
+ (0, runtime_1.emitNervesEvent)({
124
+ level: "error",
125
+ event: "repertoire.error",
126
+ component: "repertoire",
127
+ message: "skill not found",
128
+ meta: {
129
+ operation: "loadSkill",
130
+ skill: skillName,
131
+ checkedPaths: [directSkillPath, protocolMirrorPath, canonicalProtocolPath],
132
+ },
133
+ });
134
+ throw new Error(`skill '${skillName}' not found in:\n` +
135
+ `- ${directSkillPath}\n` +
136
+ `- ${protocolMirrorPath}\n` +
137
+ `- ${canonicalProtocolPath}`);
138
+ }
139
+ const content = fs.readFileSync(resolvedPath, "utf-8");
140
+ if (!loadedSkills.includes(skillName)) {
141
+ loadedSkills.push(skillName);
142
+ }
143
+ (0, runtime_1.emitNervesEvent)({
144
+ event: "repertoire.load_end",
145
+ component: "repertoire",
146
+ message: "loaded skill",
147
+ meta: { operation: "loadSkill", skill: skillName, path: resolvedPath },
148
+ });
149
+ return content;
150
+ }
151
+ function getLoadedSkills() {
152
+ return [...loadedSkills];
153
+ }
154
+ function clearLoadedSkills() {
155
+ loadedSkills.length = 0;
156
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildTaskBoard = buildTaskBoard;
4
+ exports.boardStatus = boardStatus;
5
+ exports.boardAction = boardAction;
6
+ exports.boardDeps = boardDeps;
7
+ exports.boardSessions = boardSessions;
8
+ const runtime_1 = require("../../nerves/runtime");
9
+ const transitions_1 = require("./transitions");
10
+ const BOARD_STATUS_ORDER = [
11
+ "blocked",
12
+ "processing",
13
+ "collaborating",
14
+ "drafting",
15
+ "validating",
16
+ "paused",
17
+ "done",
18
+ ];
19
+ function compactName(task) {
20
+ const suffix = task.stem.replace(/^\d{4}-\d{2}-\d{2}-\d{4}-/, "");
21
+ return suffix.length > 0 ? suffix : task.stem;
22
+ }
23
+ function groupByStatus(tasks) {
24
+ const grouped = {
25
+ drafting: [],
26
+ processing: [],
27
+ validating: [],
28
+ collaborating: [],
29
+ paused: [],
30
+ blocked: [],
31
+ done: [],
32
+ };
33
+ for (const task of tasks) {
34
+ grouped[task.status].push(compactName(task));
35
+ }
36
+ for (const status of transitions_1.TASK_VALID_STATUSES) {
37
+ grouped[status].sort();
38
+ }
39
+ return grouped;
40
+ }
41
+ function unresolvedDependencies(index) {
42
+ const stems = new Set(index.tasks.map((task) => task.stem));
43
+ const unresolved = [];
44
+ for (const task of index.tasks) {
45
+ const deps = Array.isArray(task.frontmatter.depends_on) ? task.frontmatter.depends_on : [];
46
+ for (const dep of deps) {
47
+ if (typeof dep === "string" && dep.trim() && !stems.has(dep)) {
48
+ unresolved.push(`${task.stem} -> missing ${dep}`);
49
+ }
50
+ }
51
+ }
52
+ return unresolved.sort();
53
+ }
54
+ function activeSessionLines(tasks) {
55
+ const active = tasks.filter((task) => {
56
+ const session = task.frontmatter.active_session;
57
+ const codingSession = task.frontmatter.coding_session;
58
+ return Boolean(session) || Boolean(codingSession);
59
+ });
60
+ return active.map((task) => task.stem).sort();
61
+ }
62
+ function actionRequired(index, byStatus) {
63
+ const actions = [...index.parseErrors, ...index.invalidFilenames.map((filePath) => `bad filename: ${filePath}`)];
64
+ if (byStatus.blocked.length > 0) {
65
+ actions.push(`blocked tasks: ${byStatus.blocked.join(", ")}`);
66
+ }
67
+ const missingCategory = index.tasks
68
+ .filter((task) => !task.category || !task.category.trim())
69
+ .map((task) => `missing category: ${task.stem}`);
70
+ return [...actions, ...missingCategory];
71
+ }
72
+ function buildTaskBoard(index) {
73
+ (0, runtime_1.emitNervesEvent)({
74
+ event: "mind.step_start",
75
+ component: "mind",
76
+ message: "building task board",
77
+ meta: { taskCount: index.tasks.length },
78
+ });
79
+ const byStatus = groupByStatus(index.tasks);
80
+ const counts = transitions_1.TASK_VALID_STATUSES.map((status) => `${status}:${byStatus[status].length}`).join(" ");
81
+ const processing = byStatus.processing.length > 0 ? `\n processing: ${byStatus.processing.join(", ")}` : "";
82
+ const blocked = byStatus.blocked.length > 0 ? `\n blocked: ${byStatus.blocked.join(", ")}` : "";
83
+ const compact = `[Tasks] ${counts}${processing}${blocked}`;
84
+ const fullLines = [];
85
+ for (const status of BOARD_STATUS_ORDER) {
86
+ const names = byStatus[status];
87
+ if (status === "done" && names.length === 0)
88
+ continue;
89
+ fullLines.push(`## ${status}`);
90
+ fullLines.push(names.length > 0 ? names.map((name) => `- ${name}`).join("\n") : "- (none)");
91
+ }
92
+ const unresolved = unresolvedDependencies(index);
93
+ if (unresolved.length > 0) {
94
+ fullLines.push("## dependencies");
95
+ fullLines.push(unresolved.map((line) => `- ${line}`).join("\n"));
96
+ }
97
+ const active = activeSessionLines(index.tasks);
98
+ if (active.length > 0) {
99
+ fullLines.push("## active sessions");
100
+ fullLines.push(active.map((line) => `- ${line}`).join("\n"));
101
+ }
102
+ return {
103
+ compact,
104
+ full: fullLines.join("\n\n"),
105
+ byStatus,
106
+ actionRequired: actionRequired(index, byStatus),
107
+ unresolvedDependencies: unresolved,
108
+ activeSessions: active,
109
+ };
110
+ }
111
+ function boardStatus(board, status) {
112
+ return board.byStatus[status] ?? [];
113
+ }
114
+ function boardAction(board) {
115
+ return board.actionRequired;
116
+ }
117
+ function boardDeps(board) {
118
+ return board.unresolvedDependencies;
119
+ }
120
+ function boardSessions(board) {
121
+ return board.activeSessions;
122
+ }