@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.
- package/AdoptionSpecialist.ouro/agent.json +20 -0
- package/AdoptionSpecialist.ouro/psyche/SOUL.md +22 -0
- package/AdoptionSpecialist.ouro/psyche/identities/basilisk.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/jafar.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/jormungandr.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/kaa.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/medusa.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/monty.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/nagini.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/ouroboros.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/python.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/quetzalcoatl.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/sir-hiss.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/the-serpent.md +31 -0
- package/AdoptionSpecialist.ouro/psyche/identities/the-snake.md +31 -0
- package/README.md +224 -6
- package/dist/heart/agent-entry.js +17 -0
- package/dist/heart/api-error.js +34 -0
- package/dist/heart/config.js +296 -0
- package/dist/heart/core.js +515 -0
- package/dist/heart/daemon/daemon-cli.js +675 -0
- package/dist/heart/daemon/daemon-entry.js +74 -0
- package/dist/heart/daemon/daemon.js +313 -0
- package/dist/heart/daemon/hatch-flow.js +285 -0
- package/dist/heart/daemon/hatch-specialist.js +107 -0
- package/dist/heart/daemon/health-monitor.js +79 -0
- package/dist/heart/daemon/log-tailer.js +146 -0
- package/dist/heart/daemon/message-router.js +98 -0
- package/dist/heart/daemon/os-cron.js +260 -0
- package/dist/heart/daemon/ouro-bot-entry.js +23 -0
- package/dist/heart/daemon/ouro-bot-wrapper.js +90 -0
- package/dist/heart/daemon/ouro-entry.js +23 -0
- package/dist/heart/daemon/ouro-uti.js +212 -0
- package/dist/heart/daemon/process-manager.js +237 -0
- package/dist/heart/daemon/runtime-logging.js +98 -0
- package/dist/heart/daemon/subagent-installer.js +125 -0
- package/dist/heart/daemon/task-scheduler.js +240 -0
- package/dist/heart/harness.js +26 -0
- package/dist/heart/identity.js +281 -0
- package/dist/heart/kicks.js +144 -0
- package/dist/heart/primitives.js +4 -0
- package/dist/heart/providers/anthropic.js +329 -0
- package/dist/heart/providers/azure.js +66 -0
- package/dist/heart/providers/minimax.js +53 -0
- package/dist/heart/providers/openai-codex.js +162 -0
- package/dist/heart/streaming.js +412 -0
- package/dist/heart/turn-coordinator.js +62 -0
- package/dist/inner-worker-entry.js +4 -0
- package/dist/mind/associative-recall.js +197 -0
- package/dist/mind/bundle-manifest.js +118 -0
- package/dist/mind/context.js +302 -0
- package/dist/mind/first-impressions.js +43 -0
- package/dist/mind/format.js +56 -0
- package/dist/mind/friends/channel.js +41 -0
- package/dist/mind/friends/resolver.js +84 -0
- package/dist/mind/friends/store-file.js +171 -0
- package/dist/mind/friends/store.js +4 -0
- package/dist/mind/friends/tokens.js +26 -0
- package/dist/mind/friends/types.js +21 -0
- package/dist/mind/memory.js +388 -0
- package/dist/mind/pending.js +93 -0
- package/dist/mind/phrases.js +43 -0
- package/dist/mind/prompt-refresh.js +20 -0
- package/dist/mind/prompt.js +352 -0
- package/dist/mind/token-estimate.js +119 -0
- package/dist/nerves/cli-logging.js +31 -0
- package/dist/nerves/coverage/audit-rules.js +81 -0
- package/dist/nerves/coverage/audit.js +200 -0
- package/dist/nerves/coverage/cli-main.js +5 -0
- package/dist/nerves/coverage/cli.js +51 -0
- package/dist/nerves/coverage/contract.js +23 -0
- package/dist/nerves/coverage/file-completeness.js +56 -0
- package/dist/nerves/coverage/run-artifacts.js +77 -0
- package/dist/nerves/coverage/source-scanner.js +34 -0
- package/dist/nerves/index.js +152 -0
- package/dist/nerves/runtime.js +38 -0
- package/dist/repertoire/ado-client.js +211 -0
- package/dist/repertoire/ado-context.js +73 -0
- package/dist/repertoire/ado-semantic.js +841 -0
- package/dist/repertoire/ado-templates.js +146 -0
- package/dist/repertoire/coding/index.js +36 -0
- package/dist/repertoire/coding/manager.js +489 -0
- package/dist/repertoire/coding/monitor.js +60 -0
- package/dist/repertoire/coding/reporter.js +45 -0
- package/dist/repertoire/coding/spawner.js +102 -0
- package/dist/repertoire/coding/tools.js +167 -0
- package/dist/repertoire/coding/types.js +2 -0
- package/dist/repertoire/data/ado-endpoints.json +122 -0
- package/dist/repertoire/data/graph-endpoints.json +212 -0
- package/dist/repertoire/github-client.js +64 -0
- package/dist/repertoire/graph-client.js +118 -0
- package/dist/repertoire/skills.js +156 -0
- package/dist/repertoire/tasks/board.js +122 -0
- package/dist/repertoire/tasks/index.js +210 -0
- package/dist/repertoire/tasks/lifecycle.js +80 -0
- package/dist/repertoire/tasks/middleware.js +65 -0
- package/dist/repertoire/tasks/parser.js +173 -0
- package/dist/repertoire/tasks/scanner.js +132 -0
- package/dist/repertoire/tasks/transitions.js +145 -0
- package/dist/repertoire/tasks/types.js +2 -0
- package/dist/repertoire/tools-base.js +714 -0
- package/dist/repertoire/tools-github.js +53 -0
- package/dist/repertoire/tools-teams.js +308 -0
- package/dist/repertoire/tools.js +199 -0
- package/dist/senses/cli-entry.js +15 -0
- package/dist/senses/cli.js +604 -0
- package/dist/senses/commands.js +98 -0
- package/dist/senses/inner-dialog-worker.js +61 -0
- package/dist/senses/inner-dialog.js +231 -0
- package/dist/senses/session-lock.js +119 -0
- package/dist/senses/teams-entry.js +15 -0
- package/dist/senses/teams.js +696 -0
- package/dist/senses/trust-gate.js +150 -0
- package/package.json +34 -11
- package/subagents/README.md +73 -0
- package/subagents/work-doer.md +233 -0
- package/subagents/work-merger.md +624 -0
- package/subagents/work-planner.md +373 -0
- package/bin/ouro.js +0 -6
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Azure DevOps API client.
|
|
3
|
+
// Provides a generic adoRequest() for arbitrary endpoints
|
|
4
|
+
// and a thin queryWorkItems() wrapper for backward compatibility.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.adoRequest = adoRequest;
|
|
7
|
+
exports.queryWorkItems = queryWorkItems;
|
|
8
|
+
exports.discoverOrganizations = discoverOrganizations;
|
|
9
|
+
exports.discoverProjects = discoverProjects;
|
|
10
|
+
const api_error_1 = require("../heart/api-error");
|
|
11
|
+
const runtime_1 = require("../nerves/runtime");
|
|
12
|
+
const ADO_BASE = "https://dev.azure.com";
|
|
13
|
+
const VSSPS_BASE = "https://app.vssps.visualstudio.com";
|
|
14
|
+
const DEFAULT_API_VERSION = "api-version=7.1";
|
|
15
|
+
// Append api-version=7.1 to the URL if not already present.
|
|
16
|
+
function ensureApiVersion(path) {
|
|
17
|
+
if (path.includes("api-version="))
|
|
18
|
+
return path;
|
|
19
|
+
return path.includes("?") ? `${path}&${DEFAULT_API_VERSION}` : `${path}?${DEFAULT_API_VERSION}`;
|
|
20
|
+
}
|
|
21
|
+
// Determine correct Content-Type for ADO requests.
|
|
22
|
+
function resolveContentType(method, path) {
|
|
23
|
+
const upper = method.toUpperCase();
|
|
24
|
+
const isWorkItemMutation = (upper === "POST" || upper === "PATCH") &&
|
|
25
|
+
path.toLowerCase().includes("/_apis/wit/workitems/");
|
|
26
|
+
return isWorkItemMutation
|
|
27
|
+
? "application/json-patch+json"
|
|
28
|
+
: "application/json";
|
|
29
|
+
}
|
|
30
|
+
// Generic ADO API request. Returns response body as pretty-printed JSON string.
|
|
31
|
+
async function adoRequest(token, method, org, path, body) {
|
|
32
|
+
try {
|
|
33
|
+
(0, runtime_1.emitNervesEvent)({
|
|
34
|
+
event: "client.request_start",
|
|
35
|
+
component: "clients",
|
|
36
|
+
message: "starting ADO request",
|
|
37
|
+
meta: { client: "ado", method, org, path },
|
|
38
|
+
});
|
|
39
|
+
const fullPath = ensureApiVersion(path);
|
|
40
|
+
const url = `${ADO_BASE}/${org}${fullPath}`;
|
|
41
|
+
const contentType = resolveContentType(method, path);
|
|
42
|
+
const opts = {
|
|
43
|
+
method,
|
|
44
|
+
headers: {
|
|
45
|
+
Authorization: `Bearer ${token}`,
|
|
46
|
+
"Content-Type": contentType,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
if (body)
|
|
50
|
+
opts.body = body;
|
|
51
|
+
const res = await fetch(url, opts);
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
(0, runtime_1.emitNervesEvent)({
|
|
54
|
+
level: "error",
|
|
55
|
+
event: "client.error",
|
|
56
|
+
component: "clients",
|
|
57
|
+
message: "ADO request failed",
|
|
58
|
+
meta: { client: "ado", method, org, path, status: res.status },
|
|
59
|
+
});
|
|
60
|
+
return (0, api_error_1.handleApiError)(res, "ADO", "ado");
|
|
61
|
+
}
|
|
62
|
+
const data = await res.json();
|
|
63
|
+
(0, runtime_1.emitNervesEvent)({
|
|
64
|
+
event: "client.request_end",
|
|
65
|
+
component: "clients",
|
|
66
|
+
message: "ADO request completed",
|
|
67
|
+
meta: { client: "ado", method, org, path, success: true },
|
|
68
|
+
});
|
|
69
|
+
return JSON.stringify(data, null, 2);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
(0, runtime_1.emitNervesEvent)({
|
|
73
|
+
level: "error",
|
|
74
|
+
event: "client.error",
|
|
75
|
+
component: "clients",
|
|
76
|
+
message: "ADO request threw exception",
|
|
77
|
+
meta: {
|
|
78
|
+
client: "ado",
|
|
79
|
+
method,
|
|
80
|
+
org,
|
|
81
|
+
path,
|
|
82
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return (0, api_error_1.handleApiError)(err, "ADO", "ado");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Backward-compatible thin wrapper: runs WIQL query and returns formatted work items.
|
|
89
|
+
async function queryWorkItems(token, org, query) {
|
|
90
|
+
try {
|
|
91
|
+
(0, runtime_1.emitNervesEvent)({
|
|
92
|
+
event: "client.request_start",
|
|
93
|
+
component: "clients",
|
|
94
|
+
message: "starting ADO work item query",
|
|
95
|
+
meta: { client: "ado", org, operation: "queryWorkItems" },
|
|
96
|
+
});
|
|
97
|
+
// Step 1: Run WIQL query to get work item IDs
|
|
98
|
+
const wiqlRes = await fetch(`${ADO_BASE}/${org}/_apis/wit/wiql?${DEFAULT_API_VERSION}`, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
Authorization: `Bearer ${token}`,
|
|
102
|
+
"Content-Type": "application/json",
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify({ query }),
|
|
105
|
+
});
|
|
106
|
+
if (!wiqlRes.ok) {
|
|
107
|
+
(0, runtime_1.emitNervesEvent)({
|
|
108
|
+
level: "error",
|
|
109
|
+
event: "client.error",
|
|
110
|
+
component: "clients",
|
|
111
|
+
message: "ADO WIQL query failed",
|
|
112
|
+
meta: { client: "ado", org, operation: "queryWorkItems", stage: "wiql", status: wiqlRes.status },
|
|
113
|
+
});
|
|
114
|
+
return (0, api_error_1.handleApiError)(wiqlRes, "ADO", "ado");
|
|
115
|
+
}
|
|
116
|
+
const wiqlData = (await wiqlRes.json());
|
|
117
|
+
if (!wiqlData.workItems || wiqlData.workItems.length === 0) {
|
|
118
|
+
(0, runtime_1.emitNervesEvent)({
|
|
119
|
+
event: "client.request_end",
|
|
120
|
+
component: "clients",
|
|
121
|
+
message: "ADO work item query returned no results",
|
|
122
|
+
meta: { client: "ado", org, operation: "queryWorkItems", count: 0 },
|
|
123
|
+
});
|
|
124
|
+
return "No work items found matching the query.";
|
|
125
|
+
}
|
|
126
|
+
// Step 2: Fetch work item details (batch, max 200)
|
|
127
|
+
const ids = wiqlData.workItems.slice(0, 200).map((wi) => wi.id);
|
|
128
|
+
const detailRes = await fetch(`${ADO_BASE}/${org}/_apis/wit/workitems?ids=${ids.join(",")}&${DEFAULT_API_VERSION}`, {
|
|
129
|
+
headers: {
|
|
130
|
+
Authorization: `Bearer ${token}`,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
if (!detailRes.ok) {
|
|
134
|
+
(0, runtime_1.emitNervesEvent)({
|
|
135
|
+
level: "error",
|
|
136
|
+
event: "client.error",
|
|
137
|
+
component: "clients",
|
|
138
|
+
message: "ADO work item details fetch failed",
|
|
139
|
+
meta: { client: "ado", org, operation: "queryWorkItems", stage: "details", status: detailRes.status },
|
|
140
|
+
});
|
|
141
|
+
return (0, api_error_1.handleApiError)(detailRes, "ADO", "ado");
|
|
142
|
+
}
|
|
143
|
+
const detailData = (await detailRes.json());
|
|
144
|
+
// Format results
|
|
145
|
+
const lines = detailData.value.map((wi) => {
|
|
146
|
+
const assignedTo = wi.fields["System.AssignedTo"]?.displayName || "Unassigned";
|
|
147
|
+
return `#${wi.id}: ${wi.fields["System.Title"]} [${wi.fields["System.State"]}] (${assignedTo})`;
|
|
148
|
+
});
|
|
149
|
+
(0, runtime_1.emitNervesEvent)({
|
|
150
|
+
event: "client.request_end",
|
|
151
|
+
component: "clients",
|
|
152
|
+
message: "ADO work item query completed",
|
|
153
|
+
meta: { client: "ado", org, operation: "queryWorkItems", count: lines.length },
|
|
154
|
+
});
|
|
155
|
+
return lines.join("\n");
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
(0, runtime_1.emitNervesEvent)({
|
|
159
|
+
level: "error",
|
|
160
|
+
event: "client.error",
|
|
161
|
+
component: "clients",
|
|
162
|
+
message: "ADO work item query threw exception",
|
|
163
|
+
meta: {
|
|
164
|
+
client: "ado",
|
|
165
|
+
org,
|
|
166
|
+
operation: "queryWorkItems",
|
|
167
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
return (0, api_error_1.handleApiError)(err, "ADO", "ado");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Discover ADO organizations accessible by the authenticated user.
|
|
174
|
+
// 1. Fetches user profile to get publicAlias (member ID)
|
|
175
|
+
// 2. Uses Accounts API to list organizations for that member
|
|
176
|
+
// Throws on API errors (callers handle error presentation).
|
|
177
|
+
async function discoverOrganizations(token) {
|
|
178
|
+
// Step 1: Get the user's publicAlias from their profile
|
|
179
|
+
const profileRes = await fetch(`${VSSPS_BASE}/_apis/profile/profiles/me?${DEFAULT_API_VERSION}`, {
|
|
180
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
181
|
+
});
|
|
182
|
+
if (!profileRes.ok) {
|
|
183
|
+
throw new Error(`ADO profile request failed: ${profileRes.status} ${profileRes.statusText}`);
|
|
184
|
+
}
|
|
185
|
+
const profile = (await profileRes.json());
|
|
186
|
+
const memberId = profile.publicAlias;
|
|
187
|
+
if (!memberId) {
|
|
188
|
+
throw new Error("ADO profile response missing publicAlias");
|
|
189
|
+
}
|
|
190
|
+
// Step 2: List organizations for this member
|
|
191
|
+
const accountsRes = await fetch(`${VSSPS_BASE}/_apis/accounts?memberId=${memberId}&${DEFAULT_API_VERSION}`, {
|
|
192
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
193
|
+
});
|
|
194
|
+
if (!accountsRes.ok) {
|
|
195
|
+
throw new Error(`ADO accounts request failed: ${accountsRes.status} ${accountsRes.statusText}`);
|
|
196
|
+
}
|
|
197
|
+
const data = (await accountsRes.json());
|
|
198
|
+
return (data.value ?? []).map((a) => a.accountName);
|
|
199
|
+
}
|
|
200
|
+
// Discover projects within an ADO organization.
|
|
201
|
+
// Throws on API errors (callers handle error presentation).
|
|
202
|
+
async function discoverProjects(token, org) {
|
|
203
|
+
const res = await fetch(`${ADO_BASE}/${org}/_apis/projects?${DEFAULT_API_VERSION}`, {
|
|
204
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
205
|
+
});
|
|
206
|
+
if (!res.ok) {
|
|
207
|
+
throw new Error(`ADO projects request failed: ${res.status} ${res.statusText}`);
|
|
208
|
+
}
|
|
209
|
+
const data = (await res.json());
|
|
210
|
+
return (data.value ?? []).map((p) => p.name);
|
|
211
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ADO context helper -- shared by all semantic ADO tools.
|
|
3
|
+
// Extracts org/project from model-provided args or runs discovery cascade.
|
|
4
|
+
// Re-discovery on 403 naturally handled: scope discovery APIs reflect current access.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveAdoContext = resolveAdoContext;
|
|
7
|
+
const ado_client_1 = require("./ado-client");
|
|
8
|
+
const runtime_1 = require("../nerves/runtime");
|
|
9
|
+
/**
|
|
10
|
+
* Resolve ADO organization and project for a semantic tool.
|
|
11
|
+
* If org/project are provided by the model, use them directly.
|
|
12
|
+
* Otherwise, run discovery cascade: discover orgs, auto-select if single,
|
|
13
|
+
* then discover projects, auto-select if single.
|
|
14
|
+
*
|
|
15
|
+
* @param token - ADO OAuth token
|
|
16
|
+
* @param context - ResolvedContext from the context kernel
|
|
17
|
+
* @param args - optional org/project from the model
|
|
18
|
+
*/
|
|
19
|
+
async function resolveAdoContext(token, context, args) {
|
|
20
|
+
(0, runtime_1.emitNervesEvent)({
|
|
21
|
+
component: "repertoire",
|
|
22
|
+
event: "repertoire.ado_context_resolve",
|
|
23
|
+
message: "resolving ado context",
|
|
24
|
+
meta: {},
|
|
25
|
+
});
|
|
26
|
+
// Reject if ADO integration is not available
|
|
27
|
+
if (!context.channel.availableIntegrations.includes("ado")) {
|
|
28
|
+
return { ok: false, error: "ADO integration is not available in this channel." };
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
// Resolve organization
|
|
32
|
+
let org = args?.organization;
|
|
33
|
+
if (!org) {
|
|
34
|
+
const orgs = await (0, ado_client_1.discoverOrganizations)(token);
|
|
35
|
+
if (orgs.length === 0) {
|
|
36
|
+
return { ok: false, error: "No ADO organizations found for this user." };
|
|
37
|
+
}
|
|
38
|
+
if (orgs.length === 1) {
|
|
39
|
+
org = orgs[0];
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: `Multiple ADO organizations found. Please specify which one:\n${orgs.map(o => `- ${o}`).join("\n")}`,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Resolve project
|
|
49
|
+
let project = args?.project;
|
|
50
|
+
if (!project) {
|
|
51
|
+
const projects = await (0, ado_client_1.discoverProjects)(token, org);
|
|
52
|
+
if (projects.length === 0) {
|
|
53
|
+
return { ok: false, error: `No projects found in organization "${org}".` };
|
|
54
|
+
}
|
|
55
|
+
if (projects.length === 1) {
|
|
56
|
+
project = projects[0];
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
error: `Multiple projects found in "${org}". Please specify which one:\n${projects.map(p => `- ${p}`).join("\n")}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { ok: true, organization: org, project };
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
error: `error discovering ADO context: ${err instanceof Error ? err.message : String(err)}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|