overlord-cli 0.2608191441.0 → 0.2608191554.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.
- package/dist/connectors/core/scripts/overlord-mcp.mjs +30 -17
- package/dist/index.js +66 -10
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -85,9 +85,12 @@ const tools = [
|
|
|
85
85
|
name: 'overlord_resolve_project',
|
|
86
86
|
title: 'Resolve Overlord project',
|
|
87
87
|
description:
|
|
88
|
-
|
|
88
|
+
"Resolve a project by id, slug, name, or linked repository directory metadata exposed to the MCP client. Names are matched case-insensitively across every workspace the caller can reach; a name matching in more than one returns a 'project_selection_required' result listing the candidates with their workspaces — ask the user, then retry with workspaceId.",
|
|
89
89
|
inputSchema: objectSchema({
|
|
90
90
|
projectId: stringProperty('Explicit Overlord project id, slug, or project name.'),
|
|
91
|
+
workspaceId: stringProperty(
|
|
92
|
+
"Optional workspace (id, slug, or name) narrowing an ambiguous projectId. Use this to retry after a 'project_selection_required' result."
|
|
93
|
+
),
|
|
91
94
|
directory: stringProperty(
|
|
92
95
|
'Optional repository directory path when the MCP client can expose one with .overlord/project.json.'
|
|
93
96
|
)
|
|
@@ -117,7 +120,12 @@ const tools = [
|
|
|
117
120
|
"Read one project's board columns. Status names and order are defined per project, so two projects in the same workspace can label the same lifecycle differently; each status also carries a stable type (draft, next, execute, review, complete, blocked, cancelled) that does not vary by project.",
|
|
118
121
|
inputSchema: objectSchema(
|
|
119
122
|
{
|
|
120
|
-
projectId: stringProperty(
|
|
123
|
+
projectId: stringProperty(
|
|
124
|
+
"Overlord project id, slug, or name. An ambiguous name returns 'project_selection_required'; retry with workspaceId."
|
|
125
|
+
),
|
|
126
|
+
workspaceId: stringProperty(
|
|
127
|
+
'Optional workspace (id, slug, or name) narrowing an ambiguous projectId.'
|
|
128
|
+
)
|
|
121
129
|
},
|
|
122
130
|
['projectId']
|
|
123
131
|
)
|
|
@@ -133,12 +141,17 @@ const tools = [
|
|
|
133
141
|
'Comma-separated status TYPES, such as draft,next,execute,review. Types are workspace-invariant (draft, next, execute, review, complete, blocked, cancelled). Project-defined status names are not accepted here.'
|
|
134
142
|
),
|
|
135
143
|
projectId: stringProperty(
|
|
136
|
-
|
|
144
|
+
"Optional project reference: a stable UUID, a slug, or the project name as the user said it. Names are matched case-insensitively against the projects the caller can reach. If the name matches in more than one workspace the call returns a 'project_selection_required' result listing the candidates with their workspaces — ask the user which one, then retry with workspaceId set."
|
|
145
|
+
),
|
|
146
|
+
workspaceId: stringProperty(
|
|
147
|
+
"Optional workspace (id, slug, or name) narrowing an ambiguous projectId. Use this to retry after a 'project_selection_required' result."
|
|
137
148
|
),
|
|
138
149
|
resourceKey: stringProperty(
|
|
139
150
|
'Optional logical resource key, matched by name within selected projects.'
|
|
140
151
|
),
|
|
141
|
-
dateField: stringProperty(
|
|
152
|
+
dateField: stringProperty(
|
|
153
|
+
'Date column for an explicit range: createdAt, updatedAt, or dueDatetime. Use dueDatetime for questions about what is scheduled or due; missions with no due date are excluded from a dueDatetime range.'
|
|
154
|
+
),
|
|
142
155
|
from: stringProperty('Optional inclusive ISO-8601 date/time lower bound.'),
|
|
143
156
|
to: stringProperty('Optional exclusive ISO-8601 date/time upper bound.'),
|
|
144
157
|
limit: {
|
|
@@ -422,17 +435,6 @@ function requiredString(args, name) {
|
|
|
422
435
|
return value;
|
|
423
436
|
}
|
|
424
437
|
|
|
425
|
-
function optionalProjectUuid(args) {
|
|
426
|
-
const projectId = optionalString(args, 'projectId');
|
|
427
|
-
if (!projectId) return null;
|
|
428
|
-
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(projectId)) {
|
|
429
|
-
throw new Error(
|
|
430
|
-
'projectId must be a stable Overlord project UUID; resolve human references first'
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
return projectId;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
438
|
/**
|
|
437
439
|
* Forward mission/objective addressing to the CLI. The CLI owns the shared
|
|
438
440
|
* `@overlord/contract` parser and derives a mission from a display id before it
|
|
@@ -459,6 +461,9 @@ function callOverlordTool(name, args) {
|
|
|
459
461
|
...(optionalString(args, 'projectId')
|
|
460
462
|
? { 'project-id': requiredString(args, 'projectId') }
|
|
461
463
|
: {}),
|
|
464
|
+
...(optionalString(args, 'workspaceId')
|
|
465
|
+
? { 'workspace-id': requiredString(args, 'workspaceId') }
|
|
466
|
+
: {}),
|
|
462
467
|
...(optionalString(args, 'directory') ? { directory: requiredString(args, 'directory') } : {})
|
|
463
468
|
});
|
|
464
469
|
}
|
|
@@ -476,7 +481,10 @@ function callOverlordTool(name, args) {
|
|
|
476
481
|
}
|
|
477
482
|
if (name === 'overlord_list_project_statuses') {
|
|
478
483
|
return runProtocol('statuses', {
|
|
479
|
-
'project-id': requiredString(args, 'projectId')
|
|
484
|
+
'project-id': requiredString(args, 'projectId'),
|
|
485
|
+
...(optionalString(args, 'workspaceId')
|
|
486
|
+
? { 'workspace-id': requiredString(args, 'workspaceId') }
|
|
487
|
+
: {})
|
|
480
488
|
});
|
|
481
489
|
}
|
|
482
490
|
if (name === 'overlord_search_missions') {
|
|
@@ -484,7 +492,12 @@ function callOverlordTool(name, args) {
|
|
|
484
492
|
'response-version': '2',
|
|
485
493
|
...(optionalString(args, 'query') ? { query: requiredString(args, 'query') } : {}),
|
|
486
494
|
...(optionalString(args, 'status') ? { status: requiredString(args, 'status') } : {}),
|
|
487
|
-
...(
|
|
495
|
+
...(optionalString(args, 'projectId')
|
|
496
|
+
? { 'project-id': requiredString(args, 'projectId') }
|
|
497
|
+
: {}),
|
|
498
|
+
...(optionalString(args, 'workspaceId')
|
|
499
|
+
? { 'workspace-id': requiredString(args, 'workspaceId') }
|
|
500
|
+
: {}),
|
|
488
501
|
...(optionalString(args, 'resourceKey')
|
|
489
502
|
? { 'resource-key': requiredString(args, 'resourceKey') }
|
|
490
503
|
: {}),
|
package/dist/index.js
CHANGED
|
@@ -6676,6 +6676,7 @@ var init_resource_paths = __esm({
|
|
|
6676
6676
|
});
|
|
6677
6677
|
|
|
6678
6678
|
// ../packages/contract/dist/index.js
|
|
6679
|
+
var MY_MISSIONS_COLUMNS, MY_MISSIONS_COLUMN_TYPES;
|
|
6679
6680
|
var init_dist2 = __esm({
|
|
6680
6681
|
"../packages/contract/dist/index.js"() {
|
|
6681
6682
|
"use strict";
|
|
@@ -6683,6 +6684,13 @@ var init_dist2 = __esm({
|
|
|
6683
6684
|
init_launch_variables();
|
|
6684
6685
|
init_objective_ref();
|
|
6685
6686
|
init_resource_paths();
|
|
6687
|
+
MY_MISSIONS_COLUMNS = [
|
|
6688
|
+
{ type: "next", label: "Next" },
|
|
6689
|
+
{ type: "execute", label: "Executing" },
|
|
6690
|
+
{ type: "review", label: "Review" },
|
|
6691
|
+
{ type: "complete", label: "Completed" }
|
|
6692
|
+
];
|
|
6693
|
+
MY_MISSIONS_COLUMN_TYPES = MY_MISSIONS_COLUMNS.map((column) => column.type);
|
|
6686
6694
|
}
|
|
6687
6695
|
});
|
|
6688
6696
|
|
|
@@ -19496,7 +19504,8 @@ function discoverProjectJsonFromFilesystem({
|
|
|
19496
19504
|
}
|
|
19497
19505
|
async function resolveProjectByIdOrName({
|
|
19498
19506
|
backend,
|
|
19499
|
-
projectRef
|
|
19507
|
+
projectRef,
|
|
19508
|
+
workspaceRef
|
|
19500
19509
|
}) {
|
|
19501
19510
|
const trimmed8 = projectRef.trim();
|
|
19502
19511
|
try {
|
|
@@ -19505,11 +19514,45 @@ async function resolveProjectByIdOrName({
|
|
|
19505
19514
|
if (!(error instanceof CliError) || !/project not found/i.test(error.message)) throw error;
|
|
19506
19515
|
}
|
|
19507
19516
|
const projects = await listAccessibleProjects({ backend });
|
|
19508
|
-
const
|
|
19509
|
-
|
|
19517
|
+
const needle = trimmed8.toLowerCase();
|
|
19518
|
+
const byName = projects.filter((project) => project.name.toLowerCase() === needle);
|
|
19519
|
+
const matches = byName.length > 0 ? byName : projects.filter((project) => project.slug.toLowerCase() === needle);
|
|
19520
|
+
if (matches.length === 0) {
|
|
19510
19521
|
throw new CliError({ message: `Project not found: ${trimmed8}` });
|
|
19511
19522
|
}
|
|
19512
|
-
|
|
19523
|
+
const narrowed = await narrowByWorkspace({ backend, matches, workspaceRef });
|
|
19524
|
+
if (narrowed.length === 1) return narrowed[0];
|
|
19525
|
+
const workspaces = await workspaceLabels({ backend });
|
|
19526
|
+
const candidates = narrowed.map(
|
|
19527
|
+
(project) => ` ${project.id} (workspace: ${workspaces.get(project.workspaceId) ?? project.workspaceId})`
|
|
19528
|
+
).join("\n");
|
|
19529
|
+
throw new CliError({
|
|
19530
|
+
message: `Project reference matches ${narrowed.length} projects: ${trimmed8}
|
|
19531
|
+
${candidates}
|
|
19532
|
+
Re-run with --workspace-id <id|slug|name>, or pass the project id directly.`
|
|
19533
|
+
});
|
|
19534
|
+
}
|
|
19535
|
+
async function workspaceLabels({
|
|
19536
|
+
backend
|
|
19537
|
+
}) {
|
|
19538
|
+
const workspaces = await backend.get("/api/workspaces");
|
|
19539
|
+
return new Map(workspaces.map((workspace) => [workspace.id, workspace.name]));
|
|
19540
|
+
}
|
|
19541
|
+
async function narrowByWorkspace({
|
|
19542
|
+
backend,
|
|
19543
|
+
matches,
|
|
19544
|
+
workspaceRef
|
|
19545
|
+
}) {
|
|
19546
|
+
const hint = workspaceRef?.trim().toLowerCase();
|
|
19547
|
+
if (!hint || matches.length <= 1) return matches;
|
|
19548
|
+
const workspaces = await backend.get("/api/workspaces");
|
|
19549
|
+
const targets = new Set(
|
|
19550
|
+
workspaces.filter(
|
|
19551
|
+
(workspace) => workspace.id.toLowerCase() === hint || workspace.slug.toLowerCase() === hint || workspace.name.toLowerCase() === hint
|
|
19552
|
+
).map((workspace) => workspace.id)
|
|
19553
|
+
);
|
|
19554
|
+
const narrowed = matches.filter((project) => targets.has(project.workspaceId));
|
|
19555
|
+
return narrowed.length > 0 ? narrowed : matches;
|
|
19513
19556
|
}
|
|
19514
19557
|
async function tryResolveProjectByIdOrName({
|
|
19515
19558
|
backend,
|
|
@@ -20985,10 +21028,17 @@ search-missions:
|
|
|
20985
21028
|
complete, blocked, cancelled. Project-defined status
|
|
20986
21029
|
names (board column labels) are not accepted here \u2014
|
|
20987
21030
|
use \`statuses\` to read one project's names.
|
|
20988
|
-
--project-id <id|slug|name> Restrict to one project
|
|
21031
|
+
--project-id <id|slug|name> Restrict to one project. Names are matched
|
|
21032
|
+
case-insensitively across the workspaces you can reach;
|
|
21033
|
+
a name matching in two workspaces returns
|
|
21034
|
+
project_selection_required listing the candidates.
|
|
21035
|
+
--workspace-id <id|slug|name>
|
|
21036
|
+
Narrow an ambiguous --project-id
|
|
20989
21037
|
--resource-key <csv> Restrict to logical resource key names
|
|
20990
|
-
--date-field <createdAt|updatedAt>
|
|
20991
|
-
Date column for explicit range filtering
|
|
21038
|
+
--date-field <createdAt|updatedAt|dueDatetime>
|
|
21039
|
+
Date column for explicit range filtering. Use dueDatetime
|
|
21040
|
+
for "scheduled"/"due" questions; missions with no due date
|
|
21041
|
+
are excluded from a dueDatetime range.
|
|
20992
21042
|
--from <ISO-8601> Inclusive date/time lower bound
|
|
20993
21043
|
--to <ISO-8601> Exclusive date/time upper bound
|
|
20994
21044
|
--limit <n> Max results (default: 25)
|
|
@@ -24021,12 +24071,17 @@ async function runManagementCommand({
|
|
|
24021
24071
|
const sub = parsed.positional[0];
|
|
24022
24072
|
if (sub !== "list") {
|
|
24023
24073
|
throw new CliError({
|
|
24024
|
-
message: "Usage: ovld missions list [--status <csv>] [--project-id <id>] [--json]"
|
|
24074
|
+
message: "Usage: ovld missions list [--status <csv>] [--project-id <id|slug|name>] [--workspace-id <id|slug|name>] [--json]"
|
|
24025
24075
|
});
|
|
24026
24076
|
}
|
|
24027
24077
|
const params = new URLSearchParams();
|
|
24028
24078
|
const query = flagValue(parsed.flags, "--query");
|
|
24029
|
-
const
|
|
24079
|
+
const projectRef = flagValue(parsed.flags, "--project-id");
|
|
24080
|
+
const projectId = projectRef ? (await resolveProjectByIdOrName({
|
|
24081
|
+
backend: runtime.backend,
|
|
24082
|
+
projectRef,
|
|
24083
|
+
workspaceRef: flagValue(parsed.flags, "--workspace-id")
|
|
24084
|
+
})).id : void 0;
|
|
24030
24085
|
const limit = flagValue(parsed.flags, "--limit");
|
|
24031
24086
|
const statusTypes = (flagValue(parsed.flags, "--status") ?? "").split(",").map((value) => value.trim()).filter((value) => value !== "");
|
|
24032
24087
|
if (query) params.set("q", query);
|
|
@@ -24068,7 +24123,8 @@ async function runManagementCommand({
|
|
|
24068
24123
|
}
|
|
24069
24124
|
const project = await resolveProjectByIdOrName({
|
|
24070
24125
|
backend: runtime.backend,
|
|
24071
|
-
projectRef
|
|
24126
|
+
projectRef,
|
|
24127
|
+
workspaceRef: flagValue(parsed.flags, "--workspace-id")
|
|
24072
24128
|
});
|
|
24073
24129
|
const statuses = await runtime.backend.get(
|
|
24074
24130
|
`/api/projects/${encodeURIComponent(project.id)}/statuses`
|