@rudderhq/cli 0.7.4-canary.0 → 0.7.5
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/index.js +695 -58
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -438,6 +438,11 @@ var init_constants = __esm({
|
|
|
438
438
|
"rudder_agent_skills_create",
|
|
439
439
|
"rudder_agent_skills_enable",
|
|
440
440
|
"rudder_agent_skills_sync",
|
|
441
|
+
"rudder_goal_list",
|
|
442
|
+
"rudder_goal_context",
|
|
443
|
+
"rudder_goal_progress",
|
|
444
|
+
"rudder_goal_change_propose",
|
|
445
|
+
"rudder_goal_result_propose",
|
|
441
446
|
"rudder_issue_get",
|
|
442
447
|
"rudder_issue_list",
|
|
443
448
|
"rudder_issue_search",
|
|
@@ -656,7 +661,7 @@ var init_constants = __esm({
|
|
|
656
661
|
"system_event"
|
|
657
662
|
];
|
|
658
663
|
CHAT_MESSAGE_STATUSES = ["streaming", "completed", "stopped", "failed", "interrupted"];
|
|
659
|
-
CHAT_CONTEXT_ENTITY_TYPES = ["issue", "project", "agent"];
|
|
664
|
+
CHAT_CONTEXT_ENTITY_TYPES = ["issue", "project", "agent", "goal"];
|
|
660
665
|
GOAL_OBJECTIVE_MODES = ["target", "maximize", "maintain", "decide"];
|
|
661
666
|
GOAL_EVALUATOR_KINDS = ["artifact", "metric", "policy", "human"];
|
|
662
667
|
GOAL_CONTINUATION_KINDS = ["commitment", "wait", "decision", "verification"];
|
|
@@ -2044,15 +2049,15 @@ var init_chat = __esm({
|
|
|
2044
2049
|
createSideChatSchema = z5.object({
|
|
2045
2050
|
sourceMessageId: z5.string().uuid(),
|
|
2046
2051
|
clientMutationId: z5.string().trim().min(1).max(120),
|
|
2047
|
-
preferredAgentId: z5.string().uuid().optional()
|
|
2048
|
-
|
|
2049
|
-
effortOverride: chatEffortOverrideSchema.optional()
|
|
2050
|
-
});
|
|
2052
|
+
preferredAgentId: z5.string().uuid().optional()
|
|
2053
|
+
}).strict();
|
|
2051
2054
|
addChatMessageSchema = z5.object({
|
|
2052
2055
|
body: z5.string().trim().max(2e4).default(""),
|
|
2053
2056
|
inlineAnnotations: chatInlineAnnotationsInputSchema.optional(),
|
|
2054
2057
|
editUserMessageId: z5.string().uuid().optional().nullable(),
|
|
2055
|
-
queuedMessageId: z5.string().uuid().optional().nullable()
|
|
2058
|
+
queuedMessageId: z5.string().uuid().optional().nullable(),
|
|
2059
|
+
modelOverride: chatModelOverrideSchema.optional().nullable(),
|
|
2060
|
+
effortOverride: chatEffortOverrideSchema.optional().nullable()
|
|
2056
2061
|
}).superRefine((value, ctx) => {
|
|
2057
2062
|
if (value.body.length === 0 && (value.inlineAnnotations?.length ?? 0) === 0) {
|
|
2058
2063
|
ctx.addIssue({
|
|
@@ -4020,6 +4025,7 @@ var init_goal = __esm({
|
|
|
4020
4025
|
"../packages/shared/dist/validators/goal.js"() {
|
|
4021
4026
|
"use strict";
|
|
4022
4027
|
init_constants();
|
|
4028
|
+
init_issue();
|
|
4023
4029
|
jsonRecord = z27.record(z27.string(), z27.unknown());
|
|
4024
4030
|
evidenceRefSchema = z27.string().trim().min(1).regex(/^[a-z][a-z0-9+.-]*:[^\s]+$/i, "Evidence references must use a URI-like scheme");
|
|
4025
4031
|
sha256HexSchema = z27.string().regex(/^[a-f0-9]{64}$/, "Expected a SHA-256 hex digest");
|
|
@@ -4047,16 +4053,20 @@ var init_goal = __esm({
|
|
|
4047
4053
|
title: z27.string().trim().min(1),
|
|
4048
4054
|
description: z27.string().optional().nullable(),
|
|
4049
4055
|
alignmentQuestion: z27.string().trim().min(1).optional().nullable(),
|
|
4050
|
-
|
|
4056
|
+
targetTime: z27.coerce.date().optional().nullable(),
|
|
4051
4057
|
level: z27.string().optional(),
|
|
4052
4058
|
status: z27.string().optional(),
|
|
4053
4059
|
parentId: z27.string().uuid().optional().nullable(),
|
|
4054
|
-
ownerAgentId: z27.string().uuid().optional().nullable()
|
|
4060
|
+
ownerAgentId: z27.string().uuid().optional().nullable(),
|
|
4061
|
+
ownerAgentRuntimeOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable()
|
|
4055
4062
|
});
|
|
4056
4063
|
updateGoalSchema = z27.object({
|
|
4057
4064
|
title: z27.string().trim().min(1).optional(),
|
|
4058
4065
|
description: z27.string().optional().nullable(),
|
|
4059
|
-
alignmentQuestion: z27.string().trim().min(1).optional().nullable()
|
|
4066
|
+
alignmentQuestion: z27.string().trim().min(1).optional().nullable(),
|
|
4067
|
+
ownerAgentId: z27.string().uuid().optional().nullable(),
|
|
4068
|
+
ownerAgentRuntimeOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),
|
|
4069
|
+
targetTime: z27.coerce.date().optional().nullable()
|
|
4060
4070
|
}).strict();
|
|
4061
4071
|
activateGoalSchema = z27.object({
|
|
4062
4072
|
confirmed: z27.literal(true),
|
|
@@ -4108,6 +4118,7 @@ var init_goal = __esm({
|
|
|
4108
4118
|
requestKey: z27.string().trim().min(1),
|
|
4109
4119
|
packetHash: sha256HexSchema,
|
|
4110
4120
|
packet: goalStartPacketSchema,
|
|
4121
|
+
allowCapabilityMismatch: z27.boolean().optional(),
|
|
4111
4122
|
draftGoalId: z27.string().uuid().optional()
|
|
4112
4123
|
}).strict();
|
|
4113
4124
|
createGoalActivitySchema = z27.object({
|
|
@@ -9243,6 +9254,51 @@ var RUDDER_MCP_TOOL_DESCRIPTORS = [
|
|
|
9243
9254
|
"requiresAgentId": false,
|
|
9244
9255
|
"attachesRunIdWhenAvailable": true
|
|
9245
9256
|
},
|
|
9257
|
+
{
|
|
9258
|
+
"capabilityId": "goal.list",
|
|
9259
|
+
"name": "rudder_goal_list",
|
|
9260
|
+
"description": "Discover Goals owned by the authenticated Agent; defaults to active Goals and returns current progress, next step, and attention state.",
|
|
9261
|
+
"mutating": false,
|
|
9262
|
+
"requiresOrgId": true,
|
|
9263
|
+
"requiresAgentId": true,
|
|
9264
|
+
"attachesRunIdWhenAvailable": false
|
|
9265
|
+
},
|
|
9266
|
+
{
|
|
9267
|
+
"capabilityId": "goal.context",
|
|
9268
|
+
"name": "rudder_goal_context",
|
|
9269
|
+
"description": "Read the owned Goal agreement and current operating context before acting: contract revision, criteria, boundaries, progress, next step, attention, proposals, and recent feedback.",
|
|
9270
|
+
"mutating": false,
|
|
9271
|
+
"requiresOrgId": false,
|
|
9272
|
+
"requiresAgentId": true,
|
|
9273
|
+
"attachesRunIdWhenAvailable": false
|
|
9274
|
+
},
|
|
9275
|
+
{
|
|
9276
|
+
"capabilityId": "goal.progress",
|
|
9277
|
+
"name": "rudder_goal_progress",
|
|
9278
|
+
"description": "Record evidence-backed progress for a Goal owned by the authenticated Agent and attribute it to the current Run.",
|
|
9279
|
+
"mutating": true,
|
|
9280
|
+
"requiresOrgId": false,
|
|
9281
|
+
"requiresAgentId": true,
|
|
9282
|
+
"attachesRunIdWhenAvailable": true
|
|
9283
|
+
},
|
|
9284
|
+
{
|
|
9285
|
+
"capabilityId": "goal.change.propose",
|
|
9286
|
+
"name": "rudder_goal_change_propose",
|
|
9287
|
+
"description": "Propose a reviewable change to the current Goal contract when evidence shows its outcome, criteria, boundaries, or deadlines should change.",
|
|
9288
|
+
"mutating": true,
|
|
9289
|
+
"requiresOrgId": false,
|
|
9290
|
+
"requiresAgentId": true,
|
|
9291
|
+
"attachesRunIdWhenAvailable": true
|
|
9292
|
+
},
|
|
9293
|
+
{
|
|
9294
|
+
"capabilityId": "goal.result.propose",
|
|
9295
|
+
"name": "rudder_goal_result_propose",
|
|
9296
|
+
"description": "Submit an evidence-backed Goal result for mandatory human acceptance without closing the Goal.",
|
|
9297
|
+
"mutating": true,
|
|
9298
|
+
"requiresOrgId": false,
|
|
9299
|
+
"requiresAgentId": true,
|
|
9300
|
+
"attachesRunIdWhenAvailable": true
|
|
9301
|
+
},
|
|
9246
9302
|
{
|
|
9247
9303
|
"capabilityId": "issue.get",
|
|
9248
9304
|
"name": "rudder_issue_get",
|
|
@@ -10271,6 +10327,7 @@ function coreMcpInputSchema(id) {
|
|
|
10271
10327
|
...required.length > 0 ? { required } : {}
|
|
10272
10328
|
});
|
|
10273
10329
|
const issue = string("Issue UUID, identifier, or short reference.", { maxLength: 200 });
|
|
10330
|
+
const goal = string("Goal UUID from the current Goal Runtime Context.", { maxLength: 200 });
|
|
10274
10331
|
const project = string("Project UUID or shortname.", { maxLength: 200 });
|
|
10275
10332
|
const approval = string("Approval UUID or short reference.", { maxLength: 200 });
|
|
10276
10333
|
const automation = string("Automation UUID or short reference.", { maxLength: 200 });
|
|
@@ -10311,6 +10368,120 @@ function coreMcpInputSchema(id) {
|
|
|
10311
10368
|
return schema({ selectionRefs: strings("Skill selection references.", 100) }, ["selectionRefs"]);
|
|
10312
10369
|
case "agent.skills.sync":
|
|
10313
10370
|
return schema({ desiredSkills: string("Comma-separated desired skill references.", { maxLength: 2e4 }) }, ["desiredSkills"]);
|
|
10371
|
+
case "goal.list":
|
|
10372
|
+
return schema({
|
|
10373
|
+
lifecycle: string("Goal lifecycle filter; active is the safe default.", {
|
|
10374
|
+
enum: ["draft", "active", "closed", "all"],
|
|
10375
|
+
maxLength: 20
|
|
10376
|
+
}),
|
|
10377
|
+
focus: boolean("Filter by whether the Goal is the organization Focus Goal."),
|
|
10378
|
+
facet: string("Current Goal workspace facet.", {
|
|
10379
|
+
enum: ["agent_advancing", "needs_attention", "waiting_focus", "waiting_external", "ready_for_acceptance", "closed"],
|
|
10380
|
+
maxLength: 40
|
|
10381
|
+
}),
|
|
10382
|
+
limit: number("Maximum owned Goals to return.", 1, 100)
|
|
10383
|
+
});
|
|
10384
|
+
case "goal.context":
|
|
10385
|
+
return schema({ goal: string("Goal UUID returned by rudder_goal_list.", { maxLength: 200 }) }, ["goal"]);
|
|
10386
|
+
case "goal.progress":
|
|
10387
|
+
return schema({
|
|
10388
|
+
goal,
|
|
10389
|
+
summary: string("Plain-language progress, observed change, or named blocker."),
|
|
10390
|
+
activityKind: string("Progress classification.", { enum: ["progress", "evidence", "bottleneck"], maxLength: 30 }),
|
|
10391
|
+
evidenceRefs: {
|
|
10392
|
+
type: "array",
|
|
10393
|
+
description: "URI-like references to artifacts, measurements, or other supporting evidence.",
|
|
10394
|
+
minItems: 1,
|
|
10395
|
+
maxItems: 100,
|
|
10396
|
+
items: string("URI-like evidence reference.", { maxLength: 8192 })
|
|
10397
|
+
},
|
|
10398
|
+
idempotencyKey: string("Stable key for safe retry.", { maxLength: 500 })
|
|
10399
|
+
}, ["goal", "summary", "evidenceRefs", "idempotencyKey"]);
|
|
10400
|
+
case "goal.change.propose":
|
|
10401
|
+
return schema({
|
|
10402
|
+
goal,
|
|
10403
|
+
contractRevision: number("Current Goal contract revision.", 1, 1e9),
|
|
10404
|
+
afterContract: {
|
|
10405
|
+
type: "object",
|
|
10406
|
+
description: "Only the Goal contract fields that should change.",
|
|
10407
|
+
additionalProperties: false,
|
|
10408
|
+
minProperties: 1,
|
|
10409
|
+
properties: {
|
|
10410
|
+
outcomeStatement: string("Proposed result-oriented outcome."),
|
|
10411
|
+
objectiveMode: string("Proposed objective mode.", {
|
|
10412
|
+
enum: ["target", "maximize", "maintain", "decide"],
|
|
10413
|
+
maxLength: 20
|
|
10414
|
+
}),
|
|
10415
|
+
criteria: {
|
|
10416
|
+
type: "array",
|
|
10417
|
+
minItems: 1,
|
|
10418
|
+
maxItems: 100,
|
|
10419
|
+
items: schema({
|
|
10420
|
+
id: string("Stable criterion id.", { maxLength: 500 }),
|
|
10421
|
+
label: string("Plain-language success criterion."),
|
|
10422
|
+
evaluator: string("Criterion evaluator.", {
|
|
10423
|
+
enum: ["artifact", "metric", "policy", "human"],
|
|
10424
|
+
maxLength: 20
|
|
10425
|
+
}),
|
|
10426
|
+
evidenceRequirements: {
|
|
10427
|
+
type: "array",
|
|
10428
|
+
maxItems: 100,
|
|
10429
|
+
items: string("URI-like required evidence reference.", { maxLength: 8192 })
|
|
10430
|
+
}
|
|
10431
|
+
}, ["id", "label", "evaluator"])
|
|
10432
|
+
},
|
|
10433
|
+
autonomyEnvelope: { type: "object", additionalProperties: true },
|
|
10434
|
+
humanAuthorities: { type: "object", additionalProperties: true },
|
|
10435
|
+
evaluationPolicy: { type: "object", additionalProperties: true },
|
|
10436
|
+
actionDeadline: {
|
|
10437
|
+
description: "Proposed ISO-8601 action deadline, or null to clear it.",
|
|
10438
|
+
oneOf: [{ type: "string", format: "date-time" }, { type: "null" }]
|
|
10439
|
+
},
|
|
10440
|
+
evaluationDeadline: {
|
|
10441
|
+
description: "Proposed ISO-8601 evaluation deadline, or null to clear it.",
|
|
10442
|
+
oneOf: [{ type: "string", format: "date-time" }, { type: "null" }]
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
},
|
|
10446
|
+
rationale: string("Why the current contract should change and what evidence invalidated it."),
|
|
10447
|
+
evidenceRefs: {
|
|
10448
|
+
type: "array",
|
|
10449
|
+
description: "URI-like references supporting the proposed change.",
|
|
10450
|
+
maxItems: 100,
|
|
10451
|
+
items: string("URI-like evidence reference.", { maxLength: 8192 })
|
|
10452
|
+
},
|
|
10453
|
+
idempotencyKey: string("Stable key for safe retry.", { maxLength: 500 })
|
|
10454
|
+
}, ["goal", "contractRevision", "afterContract", "rationale", "idempotencyKey"]);
|
|
10455
|
+
case "goal.result.propose":
|
|
10456
|
+
return schema({
|
|
10457
|
+
goal,
|
|
10458
|
+
contractRevision: number("Current Goal contract revision.", 1, 1e9),
|
|
10459
|
+
criteria: {
|
|
10460
|
+
type: "array",
|
|
10461
|
+
description: "Criterion outcomes for the current contract revision.",
|
|
10462
|
+
minItems: 1,
|
|
10463
|
+
maxItems: 100,
|
|
10464
|
+
items: schema({
|
|
10465
|
+
id: string("Criterion id from the Goal Runtime Context.", { maxLength: 500 }),
|
|
10466
|
+
status: string("Observed criterion status.", { enum: ["met", "unmet", "breached", "unknown"], maxLength: 20 })
|
|
10467
|
+
}, ["id", "status"])
|
|
10468
|
+
},
|
|
10469
|
+
evidenceRefs: {
|
|
10470
|
+
type: "array",
|
|
10471
|
+
description: "URI-like references supporting the proposed result.",
|
|
10472
|
+
minItems: 1,
|
|
10473
|
+
maxItems: 100,
|
|
10474
|
+
items: string("URI-like evidence reference.", { maxLength: 8192 })
|
|
10475
|
+
},
|
|
10476
|
+
resultValue: {
|
|
10477
|
+
description: "Optional measured result value.",
|
|
10478
|
+
oneOf: [{ type: "string", maxLength: 1e5 }, { type: "number" }, { type: "boolean" }]
|
|
10479
|
+
},
|
|
10480
|
+
decision: string("Optional decision reached for decide-mode Goals."),
|
|
10481
|
+
resultPayload: { type: "object", description: "Optional structured result details.", additionalProperties: true },
|
|
10482
|
+
riskSummary: string("Known risks, limitations, or remaining gaps."),
|
|
10483
|
+
idempotencyKey: string("Stable key for safe retry.", { maxLength: 500 })
|
|
10484
|
+
}, ["goal", "contractRevision", "criteria", "evidenceRefs", "riskSummary", "idempotencyKey"]);
|
|
10314
10485
|
case "issue.list":
|
|
10315
10486
|
return schema({
|
|
10316
10487
|
status: string("Comma-separated issue statuses.", { maxLength: 500 }),
|
|
@@ -10852,6 +11023,66 @@ var AGENT_CLI_CAPABILITIES = [
|
|
|
10852
11023
|
requiresRunId: false,
|
|
10853
11024
|
attachesRunIdWhenAvailable: true
|
|
10854
11025
|
},
|
|
11026
|
+
{
|
|
11027
|
+
id: "goal.list",
|
|
11028
|
+
command: "rudder goal list [--lifecycle <draft|active|closed|all>] [--focus <true|false>] [--facet <facet>] [--limit <n>]",
|
|
11029
|
+
category: "goal",
|
|
11030
|
+
description: "Discover Goals owned by the authenticated Agent; defaults to active Goals and returns current progress, next step, and attention state.",
|
|
11031
|
+
mutating: false,
|
|
11032
|
+
contract: "agent-v1",
|
|
11033
|
+
requiresOrgId: true,
|
|
11034
|
+
requiresAgentId: true,
|
|
11035
|
+
requiresRunId: false,
|
|
11036
|
+
attachesRunIdWhenAvailable: false
|
|
11037
|
+
},
|
|
11038
|
+
{
|
|
11039
|
+
id: "goal.context",
|
|
11040
|
+
command: "rudder goal context <goal-id>",
|
|
11041
|
+
category: "goal",
|
|
11042
|
+
description: "Read the owned Goal agreement and current operating context before acting: contract revision, criteria, boundaries, progress, next step, attention, proposals, and recent feedback.",
|
|
11043
|
+
mutating: false,
|
|
11044
|
+
contract: "agent-v1",
|
|
11045
|
+
requiresOrgId: false,
|
|
11046
|
+
requiresAgentId: true,
|
|
11047
|
+
requiresRunId: false,
|
|
11048
|
+
attachesRunIdWhenAvailable: false
|
|
11049
|
+
},
|
|
11050
|
+
{
|
|
11051
|
+
id: "goal.progress",
|
|
11052
|
+
command: "rudder goal progress <goal-id> --summary <text> --evidence-refs <json> --idempotency-key <key>",
|
|
11053
|
+
category: "goal",
|
|
11054
|
+
description: "Record evidence-backed progress for a Goal owned by the authenticated Agent and attribute it to the current Run.",
|
|
11055
|
+
mutating: true,
|
|
11056
|
+
contract: "agent-v1",
|
|
11057
|
+
requiresOrgId: false,
|
|
11058
|
+
requiresAgentId: true,
|
|
11059
|
+
requiresRunId: true,
|
|
11060
|
+
attachesRunIdWhenAvailable: true
|
|
11061
|
+
},
|
|
11062
|
+
{
|
|
11063
|
+
id: "goal.change.propose",
|
|
11064
|
+
command: "rudder goal change propose <goal-id> --contract-revision <n> --after-contract <json> --rationale <text> --idempotency-key <key>",
|
|
11065
|
+
category: "goal",
|
|
11066
|
+
description: "Propose a reviewable change to the current Goal contract when evidence shows its outcome, criteria, boundaries, or deadlines should change.",
|
|
11067
|
+
mutating: true,
|
|
11068
|
+
contract: "agent-v1",
|
|
11069
|
+
requiresOrgId: false,
|
|
11070
|
+
requiresAgentId: true,
|
|
11071
|
+
requiresRunId: true,
|
|
11072
|
+
attachesRunIdWhenAvailable: true
|
|
11073
|
+
},
|
|
11074
|
+
{
|
|
11075
|
+
id: "goal.result.propose",
|
|
11076
|
+
command: "rudder goal result propose <goal-id> --contract-revision <n> --criteria <json> --evidence-refs <json> --risk-summary <text> --idempotency-key <key>",
|
|
11077
|
+
category: "goal",
|
|
11078
|
+
description: "Submit an evidence-backed Goal result for mandatory human acceptance without closing the Goal.",
|
|
11079
|
+
mutating: true,
|
|
11080
|
+
contract: "agent-v1",
|
|
11081
|
+
requiresOrgId: false,
|
|
11082
|
+
requiresAgentId: true,
|
|
11083
|
+
requiresRunId: true,
|
|
11084
|
+
attachesRunIdWhenAvailable: true
|
|
11085
|
+
},
|
|
10855
11086
|
{
|
|
10856
11087
|
id: "agent.hire",
|
|
10857
11088
|
command: "rudder agent hire --org-id <id> --payload <json>",
|
|
@@ -12033,6 +12264,7 @@ var AGENT_CLI_CAPABILITIES = [
|
|
|
12033
12264
|
// src/agent-v1-registry.ts
|
|
12034
12265
|
var CATEGORY_TITLES = {
|
|
12035
12266
|
agent: "Agent",
|
|
12267
|
+
goal: "Goal",
|
|
12036
12268
|
issue: "Issue",
|
|
12037
12269
|
project: "Project",
|
|
12038
12270
|
automation: "Automation",
|
|
@@ -12323,6 +12555,10 @@ var LEGACY_ARGUMENT_ALIASES = {
|
|
|
12323
12555
|
selections: "selectionRefs",
|
|
12324
12556
|
skills: "selectionRefs"
|
|
12325
12557
|
},
|
|
12558
|
+
"goal.context": { goalId: "goal" },
|
|
12559
|
+
"goal.progress": { goalId: "goal" },
|
|
12560
|
+
"goal.change.propose": { goalId: "goal" },
|
|
12561
|
+
"goal.result.propose": { goalId: "goal" },
|
|
12326
12562
|
"issue.get": { issueId: "issue" },
|
|
12327
12563
|
"issue.context": { issueId: "issue" },
|
|
12328
12564
|
"issue.checkout": { issueId: "issue" },
|
|
@@ -12751,6 +12987,64 @@ async function callToolDirectlyIfSupported(toolName, rawArgs, env, signal) {
|
|
|
12751
12987
|
return success(await api.get("/api/agents/me"));
|
|
12752
12988
|
case "agent.inbox":
|
|
12753
12989
|
return success(await api.get("/api/agents/me/inbox-lite"));
|
|
12990
|
+
case "goal.list": {
|
|
12991
|
+
const orgId = requiredRuntimeString(env, "RUDDER_ORG_ID");
|
|
12992
|
+
requiredRuntimeString(env, "RUDDER_AGENT_ID");
|
|
12993
|
+
const params = new URLSearchParams({
|
|
12994
|
+
lifecycle: optionalString(input.lifecycle) ?? "active",
|
|
12995
|
+
limit: String(parsePositiveInteger(input.limit, 20))
|
|
12996
|
+
});
|
|
12997
|
+
if (typeof input.focus === "boolean") params.set("focus", String(input.focus));
|
|
12998
|
+
appendOptionalQuery(params, "facet", input.facet);
|
|
12999
|
+
return success(await api.get(`/api/orgs/${encodeURIComponent(orgId)}/goals/assigned?${params}`));
|
|
13000
|
+
}
|
|
13001
|
+
case "goal.context":
|
|
13002
|
+
requiredRuntimeString(env, "RUDDER_AGENT_ID");
|
|
13003
|
+
return success(await api.get(
|
|
13004
|
+
`/api/goals/${encodeURIComponent(requiredAnyString(input, ["goal", "goalId"]))}/agent-context`
|
|
13005
|
+
));
|
|
13006
|
+
case "goal.progress": {
|
|
13007
|
+
const payload = createGoalActivitySchema.parse({
|
|
13008
|
+
summary: requiredString(input, "summary"),
|
|
13009
|
+
activityKind: optionalString(input.activityKind) ?? "progress",
|
|
13010
|
+
evidenceRefs: input.evidenceRefs,
|
|
13011
|
+
idempotencyKey: requiredString(input, "idempotencyKey")
|
|
13012
|
+
});
|
|
13013
|
+
return success(await api.post(
|
|
13014
|
+
`/api/goals/${encodeURIComponent(requiredAnyString(input, ["goal", "goalId"]))}/activities`,
|
|
13015
|
+
payload
|
|
13016
|
+
));
|
|
13017
|
+
}
|
|
13018
|
+
case "goal.change.propose": {
|
|
13019
|
+
const payload = createGoalChangeProposalSchema.parse({
|
|
13020
|
+
expectedContractRevision: input.contractRevision,
|
|
13021
|
+
afterContract: input.afterContract,
|
|
13022
|
+
rationale: requiredString(input, "rationale"),
|
|
13023
|
+
evidenceRefs: input.evidenceRefs,
|
|
13024
|
+
idempotencyKey: requiredString(input, "idempotencyKey")
|
|
13025
|
+
});
|
|
13026
|
+
return success(await api.post(
|
|
13027
|
+
`/api/goals/${encodeURIComponent(requiredAnyString(input, ["goal", "goalId"]))}/change-proposals`,
|
|
13028
|
+
payload
|
|
13029
|
+
));
|
|
13030
|
+
}
|
|
13031
|
+
case "goal.result.propose": {
|
|
13032
|
+
const decision = optionalString(input.decision);
|
|
13033
|
+
const payload = createGoalResultProposalSchema.parse({
|
|
13034
|
+
contractRevision: input.contractRevision,
|
|
13035
|
+
criteria: input.criteria,
|
|
13036
|
+
evidenceRefs: input.evidenceRefs,
|
|
13037
|
+
resultValue: input.resultValue,
|
|
13038
|
+
...decision ? { decision } : {},
|
|
13039
|
+
resultPayload: input.resultPayload,
|
|
13040
|
+
riskSummary: requiredString(input, "riskSummary"),
|
|
13041
|
+
idempotencyKey: requiredString(input, "idempotencyKey")
|
|
13042
|
+
});
|
|
13043
|
+
return success(await api.post(
|
|
13044
|
+
`/api/goals/${encodeURIComponent(requiredAnyString(input, ["goal", "goalId"]))}/result-proposals`,
|
|
13045
|
+
payload
|
|
13046
|
+
));
|
|
13047
|
+
}
|
|
12754
13048
|
case "issue.get":
|
|
12755
13049
|
return success(await api.get(`/api/issues/${encodeURIComponent(requiredAnyString(input, ["issue", "issueId"]))}`));
|
|
12756
13050
|
case "issue.context": {
|
|
@@ -13095,6 +13389,73 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
|
|
|
13095
13389
|
pushOptional(args, "--desired-skills", input.desiredSkills);
|
|
13096
13390
|
return args;
|
|
13097
13391
|
}
|
|
13392
|
+
case "goal.list": {
|
|
13393
|
+
const args = ["goal", "list"];
|
|
13394
|
+
pushOptional(args, "--lifecycle", input.lifecycle ?? "active");
|
|
13395
|
+
if (typeof input.focus === "boolean") args.push("--focus", String(input.focus));
|
|
13396
|
+
pushOptional(args, "--facet", input.facet);
|
|
13397
|
+
if (input.limit !== void 0) args.push("--limit", String(input.limit));
|
|
13398
|
+
return args;
|
|
13399
|
+
}
|
|
13400
|
+
case "goal.context":
|
|
13401
|
+
return ["goal", "context", requiredAnyString(input, ["goal", "goalId"])];
|
|
13402
|
+
case "goal.progress": {
|
|
13403
|
+
const args = [
|
|
13404
|
+
"goal",
|
|
13405
|
+
"progress",
|
|
13406
|
+
requiredAnyString(input, ["goal", "goalId"]),
|
|
13407
|
+
"--summary",
|
|
13408
|
+
requiredString(input, "summary"),
|
|
13409
|
+
"--evidence-refs",
|
|
13410
|
+
JSON.stringify(input.evidenceRefs),
|
|
13411
|
+
"--idempotency-key",
|
|
13412
|
+
requiredString(input, "idempotencyKey")
|
|
13413
|
+
];
|
|
13414
|
+
pushOptional(args, "--activity-kind", input.activityKind);
|
|
13415
|
+
return args;
|
|
13416
|
+
}
|
|
13417
|
+
case "goal.change.propose": {
|
|
13418
|
+
const args = [
|
|
13419
|
+
"goal",
|
|
13420
|
+
"change",
|
|
13421
|
+
"propose",
|
|
13422
|
+
requiredAnyString(input, ["goal", "goalId"]),
|
|
13423
|
+
"--contract-revision",
|
|
13424
|
+
String(input.contractRevision),
|
|
13425
|
+
"--after-contract",
|
|
13426
|
+
JSON.stringify(input.afterContract),
|
|
13427
|
+
"--rationale",
|
|
13428
|
+
requiredString(input, "rationale"),
|
|
13429
|
+
"--idempotency-key",
|
|
13430
|
+
requiredString(input, "idempotencyKey")
|
|
13431
|
+
];
|
|
13432
|
+
if (input.evidenceRefs !== void 0) {
|
|
13433
|
+
args.push("--evidence-refs", JSON.stringify(input.evidenceRefs));
|
|
13434
|
+
}
|
|
13435
|
+
return args;
|
|
13436
|
+
}
|
|
13437
|
+
case "goal.result.propose": {
|
|
13438
|
+
const args = [
|
|
13439
|
+
"goal",
|
|
13440
|
+
"result",
|
|
13441
|
+
"propose",
|
|
13442
|
+
requiredAnyString(input, ["goal", "goalId"]),
|
|
13443
|
+
"--contract-revision",
|
|
13444
|
+
String(input.contractRevision),
|
|
13445
|
+
"--criteria",
|
|
13446
|
+
JSON.stringify(input.criteria),
|
|
13447
|
+
"--evidence-refs",
|
|
13448
|
+
JSON.stringify(input.evidenceRefs),
|
|
13449
|
+
"--risk-summary",
|
|
13450
|
+
requiredString(input, "riskSummary"),
|
|
13451
|
+
"--idempotency-key",
|
|
13452
|
+
requiredString(input, "idempotencyKey")
|
|
13453
|
+
];
|
|
13454
|
+
if (input.resultValue !== void 0) args.push("--result-value", JSON.stringify(input.resultValue));
|
|
13455
|
+
pushOptional(args, "--decision", input.decision);
|
|
13456
|
+
if (input.resultPayload !== void 0) args.push("--result-payload", JSON.stringify(input.resultPayload));
|
|
13457
|
+
return args;
|
|
13458
|
+
}
|
|
13098
13459
|
case "issue.get":
|
|
13099
13460
|
return ["issue", "get", requiredAnyString(input, ["issue", "issueId"])];
|
|
13100
13461
|
case "issue.list": {
|
|
@@ -14634,6 +14995,89 @@ function asString(value, fallback) {
|
|
|
14634
14995
|
}
|
|
14635
14996
|
|
|
14636
14997
|
// ../packages/agent-runtime-utils/dist/server-utils.prompts.js
|
|
14998
|
+
var RUDDER_GOAL_RUNTIME_BOUNDARY = `This is a Rudder product Goal, not a Codex internal goal. Do not call Codex \`create_goal\`, \`update_goal\`, or \`get_goal\` for it; those tools do not manage Rudder Goals. If the Goal packet names an exact managed Rudder tool, call that typed tool directly. Do not load \`rudder-docs\`, inspect skill files, or run discovery commands merely to confirm a tool that the packet already names. If the Rudder Goal context is missing or stale, report the named blocker and request refreshed context instead of using shell, Bash, curl, or the \`rudder\` CLI to retrieve it.
|
|
14999
|
+
|
|
15000
|
+
Record meaningful evidence-backed advancement with \`rudder_goal_progress\`; the tool automatically attributes progress to this Run. If evidence shows the Goal contract itself must change, use \`rudder_goal_change_propose\` so a human can review the exact delta; never silently redefine the outcome or boundaries. When the outcome is ready for review, use \`rudder_goal_result_propose\` with the current contract revision and supporting evidence. Do not use shell, Bash, curl, or the \`rudder\` CLI for these actions.
|
|
15001
|
+
|
|
15002
|
+
A human must accept every terminal Goal result. A Result Proposal requests acceptance; it does not let the runtime mark, close, or claim the Goal complete.`;
|
|
15003
|
+
var GOAL_STARTED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). A Goal has started and you are responsible for advancing it.
|
|
15004
|
+
|
|
15005
|
+
{{context.rudderWorkspace.orgResourcesPrompt}}
|
|
15006
|
+
|
|
15007
|
+
${RUDDER_GOAL_RUNTIME_BOUNDARY}
|
|
15008
|
+
|
|
15009
|
+
## Goal Runtime Context
|
|
15010
|
+
|
|
15011
|
+
**Goal:** {{context.goalRuntime.goalTitle}}
|
|
15012
|
+
**Goal ID:** {{context.goalRuntime.goalId}}
|
|
15013
|
+
|
|
15014
|
+
**Goal outcome:**
|
|
15015
|
+
{{context.goalRuntime.goalOutcome}}
|
|
15016
|
+
|
|
15017
|
+
**Current contract:**
|
|
15018
|
+
{{context.goalRuntime.currentContract}}
|
|
15019
|
+
|
|
15020
|
+
**Continuation:**
|
|
15021
|
+
{{context.goalRuntime.continuation}}
|
|
15022
|
+
|
|
15023
|
+
Advance this Goal from the current contract and continuation. Preserve the stated outcome and contract boundaries; do not silently redefine them.`;
|
|
15024
|
+
var GOAL_FEEDBACK_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). New feedback requires your review on a Goal you own.
|
|
15025
|
+
|
|
15026
|
+
{{context.rudderWorkspace.orgResourcesPrompt}}
|
|
15027
|
+
|
|
15028
|
+
${RUDDER_GOAL_RUNTIME_BOUNDARY}
|
|
15029
|
+
|
|
15030
|
+
## Goal Runtime Context
|
|
15031
|
+
|
|
15032
|
+
**Goal:** {{context.goalRuntime.goalTitle}}
|
|
15033
|
+
**Goal ID:** {{context.goalRuntime.goalId}}
|
|
15034
|
+
|
|
15035
|
+
**Goal outcome:**
|
|
15036
|
+
{{context.goalRuntime.goalOutcome}}
|
|
15037
|
+
|
|
15038
|
+
**Current contract:**
|
|
15039
|
+
{{context.goalRuntime.currentContract}}
|
|
15040
|
+
|
|
15041
|
+
**Continuation:**
|
|
15042
|
+
{{context.goalRuntime.continuation}}
|
|
15043
|
+
|
|
15044
|
+
## Goal Feedback
|
|
15045
|
+
|
|
15046
|
+
**Feedback ID:** {{context.goalRuntime.feedbackId}}
|
|
15047
|
+
|
|
15048
|
+
**Feedback body:**
|
|
15049
|
+
{{context.goalRuntime.feedbackBody}}
|
|
15050
|
+
|
|
15051
|
+
Review the feedback against the current Goal contract, then continue from the recorded continuation. Treat any outcome or contract change as an explicit proposal instead of silently changing the Goal.`;
|
|
15052
|
+
var GOAL_CHANGE_DECIDED_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). A human decided a proposed change to a Goal you own.
|
|
15053
|
+
|
|
15054
|
+
{{context.rudderWorkspace.orgResourcesPrompt}}
|
|
15055
|
+
|
|
15056
|
+
${RUDDER_GOAL_RUNTIME_BOUNDARY}
|
|
15057
|
+
|
|
15058
|
+
## Goal Runtime Context
|
|
15059
|
+
|
|
15060
|
+
**Goal:** {{context.goalRuntime.goalTitle}}
|
|
15061
|
+
**Goal ID:** {{context.goalRuntime.goalId}}
|
|
15062
|
+
|
|
15063
|
+
**Goal outcome:**
|
|
15064
|
+
{{context.goalRuntime.goalOutcome}}
|
|
15065
|
+
|
|
15066
|
+
**Current contract:**
|
|
15067
|
+
{{context.goalRuntime.currentContract}}
|
|
15068
|
+
|
|
15069
|
+
**Continuation:**
|
|
15070
|
+
{{context.goalRuntime.continuation}}
|
|
15071
|
+
|
|
15072
|
+
## Goal Change Decision
|
|
15073
|
+
|
|
15074
|
+
**Decision:** {{context.goalRuntime.decision}}
|
|
15075
|
+
**Decision status:** {{context.goalRuntime.decisionStatus}}
|
|
15076
|
+
|
|
15077
|
+
**Decision note:**
|
|
15078
|
+
{{context.goalRuntime.decisionNote}}
|
|
15079
|
+
|
|
15080
|
+
Continue from the current Goal contract and this human decision. Do not apply a rejected change or silently reinterpret the decision.`;
|
|
14637
15081
|
var ISSUE_ASSIGNEE_EXECUTION_RAIL = "Before doing issue-scoped execution as the assignee, check out the assigned issue. If checkout returns `409`, do not retry; stop and report the ownership conflict.";
|
|
14638
15082
|
var ISSUE_ASSIGN_PROMPT_TEMPLATE = `You are agent {{agent.id}} ({{agent.name}}). You have been assigned to work on an issue.
|
|
14639
15083
|
|
|
@@ -14794,6 +15238,7 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
14794
15238
|
"- Local trusted runtimes may expose the host operator home as `$RUDDER_OPERATOR_HOME`; use it only when a local skill or script intentionally needs operator-owned desktop app or CLI state. Do not replace `$HOME` with it.",
|
|
14795
15239
|
"",
|
|
14796
15240
|
"When you create or copy a skill under `$AGENT_HOME/skills/<slug>/`, check the agent's Skills snapshot before claiming it will load in future runs. If it is installed but not enabled, say exactly that future runs will not load it until enabled, and offer to enable it with `rudder agent skills enable <agent-id> <selection-ref>` when you have permission.",
|
|
15241
|
+
"If there is an AGENTS.md file in the project you're working on, please read it first and follow the project's development guidelines.",
|
|
14797
15242
|
"",
|
|
14798
15243
|
"When you write issue comments or chat replies, match the language of the user's or board's most recent substantive message unless they explicitly ask for a different language.",
|
|
14799
15244
|
"When you mention a web page, issue URL, external dashboard, or other user-openable target in an issue comment or chat reply, write it as a clickable Markdown link with a descriptive label, for example `[NameSilo transfer page](https://www.namesilo.com/account_domain_manage_transfer.php)`. Do not put action URLs in backticks or code blocks unless you are showing literal code or a command.",
|
|
@@ -17847,6 +18292,124 @@ function registerDashboardCommands(program) {
|
|
|
17847
18292
|
);
|
|
17848
18293
|
}
|
|
17849
18294
|
|
|
18295
|
+
// src/commands/client/goal.ts
|
|
18296
|
+
init_dist();
|
|
18297
|
+
function registerGoalCommands(program) {
|
|
18298
|
+
const goal = program.command("goal").description("Goal Owner runtime operations");
|
|
18299
|
+
addCommonClientOptions(
|
|
18300
|
+
goal.command("list").description(getAgentCliCapabilityById("goal.list").description).option("--lifecycle <state>", "draft, active, closed, or all", "active").option("--focus <true|false>", "Filter by organization Focus state").option("--facet <facet>", "Filter by current workspace attention facet").option("--limit <n>", "Maximum Goals to return (1-100)", "20").action(async (opts) => {
|
|
18301
|
+
try {
|
|
18302
|
+
const ctx = resolveCommandContext(opts, { requireCompany: true });
|
|
18303
|
+
if (!ctx.agentId) throw new Error("Agent ID is required. Set RUDDER_AGENT_ID.");
|
|
18304
|
+
const params = new URLSearchParams({
|
|
18305
|
+
lifecycle: opts.lifecycle,
|
|
18306
|
+
limit: opts.limit
|
|
18307
|
+
});
|
|
18308
|
+
if (opts.focus !== void 0) params.set("focus", opts.focus);
|
|
18309
|
+
if (opts.facet) params.set("facet", opts.facet);
|
|
18310
|
+
const response = await ctx.api.get(`/api/orgs/${ctx.orgId}/goals/assigned?${params}`);
|
|
18311
|
+
printOutput(response, { json: ctx.json });
|
|
18312
|
+
} catch (err) {
|
|
18313
|
+
handleCommandError(err);
|
|
18314
|
+
}
|
|
18315
|
+
}),
|
|
18316
|
+
{ includeCompany: true }
|
|
18317
|
+
);
|
|
18318
|
+
addCommonClientOptions(
|
|
18319
|
+
goal.command("context").description(getAgentCliCapabilityById("goal.context").description).argument("<goalId>", "Goal ID returned by goal list").action(async (goalId, opts) => {
|
|
18320
|
+
try {
|
|
18321
|
+
const ctx = resolveCommandContext(opts);
|
|
18322
|
+
if (!ctx.agentId) throw new Error("Agent ID is required. Set RUDDER_AGENT_ID.");
|
|
18323
|
+
const response = await ctx.api.get(`/api/goals/${goalId}/agent-context`);
|
|
18324
|
+
printOutput(response, { json: ctx.json });
|
|
18325
|
+
} catch (err) {
|
|
18326
|
+
handleCommandError(err);
|
|
18327
|
+
}
|
|
18328
|
+
})
|
|
18329
|
+
);
|
|
18330
|
+
addCommonClientOptions(
|
|
18331
|
+
goal.command("progress").description(getAgentCliCapabilityById("goal.progress").description).argument("<goalId>", "Goal ID from the current Goal Runtime Context").requiredOption("--summary <text>", "Plain-language progress summary").option("--activity-kind <kind>", "progress, evidence, or bottleneck", "progress").requiredOption("--evidence-refs <json>", "JSON array of URI-like evidence references").requiredOption("--idempotency-key <key>", "Stable key for safe retry").action(async (goalId, opts) => {
|
|
18332
|
+
try {
|
|
18333
|
+
const ctx = resolveCommandContext(opts);
|
|
18334
|
+
const payload = createGoalActivitySchema.parse({
|
|
18335
|
+
summary: opts.summary,
|
|
18336
|
+
activityKind: opts.activityKind,
|
|
18337
|
+
evidenceRefs: parseJsonArray(opts.evidenceRefs, "evidence refs"),
|
|
18338
|
+
idempotencyKey: opts.idempotencyKey
|
|
18339
|
+
});
|
|
18340
|
+
const activity = await ctx.api.post(`/api/goals/${goalId}/activities`, payload);
|
|
18341
|
+
printOutput(activity, { json: ctx.json });
|
|
18342
|
+
} catch (err) {
|
|
18343
|
+
handleCommandError(err);
|
|
18344
|
+
}
|
|
18345
|
+
})
|
|
18346
|
+
);
|
|
18347
|
+
const change = goal.command("change").description("Goal contract change operations");
|
|
18348
|
+
addCommonClientOptions(
|
|
18349
|
+
change.command("propose").description(getAgentCliCapabilityById("goal.change.propose").description).argument("<goalId>", "Goal ID from the current Goal Runtime Context").requiredOption("--contract-revision <n>", "Current Goal contract revision").requiredOption("--after-contract <json>", "JSON object containing only proposed contract field changes").requiredOption("--rationale <text>", "Why the current Goal contract should change").option("--evidence-refs <json>", "JSON array of URI-like evidence references", "[]").requiredOption("--idempotency-key <key>", "Stable key for safe retry").action(async (goalId, opts) => {
|
|
18350
|
+
try {
|
|
18351
|
+
const ctx = resolveCommandContext(opts);
|
|
18352
|
+
const payload = createGoalChangeProposalSchema.parse({
|
|
18353
|
+
expectedContractRevision: Number(opts.contractRevision),
|
|
18354
|
+
afterContract: parseJsonObject3(opts.afterContract, "after contract"),
|
|
18355
|
+
rationale: opts.rationale,
|
|
18356
|
+
evidenceRefs: parseJsonArray(opts.evidenceRefs ?? "[]", "evidence refs"),
|
|
18357
|
+
idempotencyKey: opts.idempotencyKey
|
|
18358
|
+
});
|
|
18359
|
+
const proposal = await ctx.api.post(`/api/goals/${goalId}/change-proposals`, payload);
|
|
18360
|
+
printOutput(proposal, { json: ctx.json });
|
|
18361
|
+
} catch (err) {
|
|
18362
|
+
handleCommandError(err);
|
|
18363
|
+
}
|
|
18364
|
+
})
|
|
18365
|
+
);
|
|
18366
|
+
const result = goal.command("result").description("Goal result operations");
|
|
18367
|
+
addCommonClientOptions(
|
|
18368
|
+
result.command("propose").description(getAgentCliCapabilityById("goal.result.propose").description).argument("<goalId>", "Goal ID from the current Goal Runtime Context").requiredOption("--contract-revision <n>", "Current Goal contract revision").requiredOption("--criteria <json>", "JSON array of criterion id/status objects").requiredOption("--evidence-refs <json>", "JSON array of URI-like evidence references").option("--result-value <json-or-text>", "Optional measured result value").option("--decision <text>", "Optional decision for decide-mode Goals").option("--result-payload <json>", "Optional structured result details").requiredOption("--risk-summary <text>", "Known risks, limitations, or remaining gaps").requiredOption("--idempotency-key <key>", "Stable key for safe retry").action(async (goalId, opts) => {
|
|
18369
|
+
try {
|
|
18370
|
+
const ctx = resolveCommandContext(opts);
|
|
18371
|
+
const payload = createGoalResultProposalSchema.parse({
|
|
18372
|
+
contractRevision: Number(opts.contractRevision),
|
|
18373
|
+
criteria: parseJsonArray(opts.criteria, "criteria"),
|
|
18374
|
+
evidenceRefs: parseJsonArray(opts.evidenceRefs, "evidence refs"),
|
|
18375
|
+
...opts.resultValue !== void 0 ? { resultValue: parseResultValue(opts.resultValue) } : {},
|
|
18376
|
+
...opts.decision !== void 0 ? { decision: opts.decision } : {},
|
|
18377
|
+
...opts.resultPayload !== void 0 ? { resultPayload: parseJsonObject3(opts.resultPayload, "result payload") } : {},
|
|
18378
|
+
riskSummary: opts.riskSummary,
|
|
18379
|
+
idempotencyKey: opts.idempotencyKey
|
|
18380
|
+
});
|
|
18381
|
+
const proposal = await ctx.api.post(`/api/goals/${goalId}/result-proposals`, payload);
|
|
18382
|
+
printOutput(proposal, { json: ctx.json });
|
|
18383
|
+
} catch (err) {
|
|
18384
|
+
handleCommandError(err);
|
|
18385
|
+
}
|
|
18386
|
+
})
|
|
18387
|
+
);
|
|
18388
|
+
}
|
|
18389
|
+
function parseJsonArray(value, label) {
|
|
18390
|
+
const parsed = JSON.parse(value);
|
|
18391
|
+
if (!Array.isArray(parsed)) throw new Error(`${label} must be a JSON array`);
|
|
18392
|
+
return parsed;
|
|
18393
|
+
}
|
|
18394
|
+
function parseJsonObject3(value, label) {
|
|
18395
|
+
const parsed = JSON.parse(value);
|
|
18396
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18397
|
+
throw new Error(`${label} must be a JSON object`);
|
|
18398
|
+
}
|
|
18399
|
+
return parsed;
|
|
18400
|
+
}
|
|
18401
|
+
function parseResultValue(value) {
|
|
18402
|
+
try {
|
|
18403
|
+
const parsed = JSON.parse(value);
|
|
18404
|
+
if (typeof parsed === "string" || typeof parsed === "number" || typeof parsed === "boolean") {
|
|
18405
|
+
return parsed;
|
|
18406
|
+
}
|
|
18407
|
+
} catch {
|
|
18408
|
+
return value;
|
|
18409
|
+
}
|
|
18410
|
+
throw new Error("result value must be a string, number, or boolean");
|
|
18411
|
+
}
|
|
18412
|
+
|
|
17850
18413
|
// src/commands/client/issue.ts
|
|
17851
18414
|
init_dist();
|
|
17852
18415
|
import { readFile as readFile4, stat as stat4 } from "node:fs/promises";
|
|
@@ -20125,7 +20688,7 @@ import * as p15 from "@clack/prompts";
|
|
|
20125
20688
|
import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
|
|
20126
20689
|
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
20127
20690
|
import { createWriteStream, constants as fsConstants, mkdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
20128
|
-
import { access, chmod, copyFile as copyFile2, cp as cp2, mkdir as mkdir4, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile6, rm as rm2, stat as stat5, utimes, writeFile as writeFile3 } from "node:fs/promises";
|
|
20691
|
+
import { access, chmod, copyFile as copyFile2, cp as cp2, lstat, mkdir as mkdir4, mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile6, rm as rm2, stat as stat5, utimes, writeFile as writeFile3 } from "node:fs/promises";
|
|
20129
20692
|
import { homedir, tmpdir } from "node:os";
|
|
20130
20693
|
import path22 from "node:path";
|
|
20131
20694
|
import { Readable, Transform } from "node:stream";
|
|
@@ -21473,6 +22036,21 @@ async function startCommand(opts) {
|
|
|
21473
22036
|
const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();
|
|
21474
22037
|
const dryRun = opts.dryRun === true;
|
|
21475
22038
|
const desktopProgressJson = opts.desktopProgressJson === true;
|
|
22039
|
+
const exactDesktopAssetPath = opts.desktopAssetPath?.trim() || null;
|
|
22040
|
+
const exactDesktopAssetChecksum = opts.desktopAssetChecksum?.trim() || null;
|
|
22041
|
+
const exactDesktopAssetName = opts.desktopAssetName?.trim() || null;
|
|
22042
|
+
const exactDesktopReleaseDigest = opts.desktopReleaseDigest?.trim() || null;
|
|
22043
|
+
if (exactDesktopAssetPath || exactDesktopAssetChecksum || exactDesktopAssetName || exactDesktopReleaseDigest) {
|
|
22044
|
+
if (!exactDesktopAssetPath || !exactDesktopAssetChecksum || !exactDesktopAssetName || !exactDesktopReleaseDigest) {
|
|
22045
|
+
throw new Error("Exact Desktop asset mode requires path, checksum, asset name, and release digest.");
|
|
22046
|
+
}
|
|
22047
|
+
if (!path22.isAbsolute(exactDesktopAssetPath) || exactDesktopAssetName.includes("/") || !/^[a-f0-9]{64}$/iu.test(exactDesktopAssetChecksum) || !/^[a-f0-9]{64}$/iu.test(exactDesktopReleaseDigest)) {
|
|
22048
|
+
throw new Error("Exact Desktop asset mode received invalid candidate identity.");
|
|
22049
|
+
}
|
|
22050
|
+
if (opts.desktopAssetKind && opts.desktopAssetKind !== "full" && opts.desktopAssetKind !== "shell") {
|
|
22051
|
+
throw new Error("Exact Desktop asset mode received an invalid asset kind.");
|
|
22052
|
+
}
|
|
22053
|
+
}
|
|
21476
22054
|
let runtimeSupportsShellAssets = false;
|
|
21477
22055
|
if (desktopProgressJson) {
|
|
21478
22056
|
process.stdout.on("error", (error) => {
|
|
@@ -21559,49 +22137,86 @@ async function startCommand(opts) {
|
|
|
21559
22137
|
return;
|
|
21560
22138
|
}
|
|
21561
22139
|
await withDesktopInstallLock(installPaths, async () => {
|
|
21562
|
-
const directReleaseVersion = resolveDesktopReleaseVersion(tag);
|
|
21563
22140
|
const progressFactory = desktopProgressJson ? createDesktopProgressFactory() : createByteProgress;
|
|
21564
|
-
let
|
|
21565
|
-
|
|
21566
|
-
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21570
|
-
|
|
21571
|
-
|
|
21572
|
-
|
|
21573
|
-
|
|
21574
|
-
|
|
21575
|
-
|
|
22141
|
+
let releaseTag;
|
|
22142
|
+
let selectedAsset;
|
|
22143
|
+
let selectedAssetKind;
|
|
22144
|
+
let expectedChecksum;
|
|
22145
|
+
let cachedAsset = null;
|
|
22146
|
+
let assetCandidates = [];
|
|
22147
|
+
let checksums = /* @__PURE__ */ new Map();
|
|
22148
|
+
if (exactDesktopAssetPath) {
|
|
22149
|
+
releaseTag = tag;
|
|
22150
|
+
selectedAsset = {
|
|
22151
|
+
name: exactDesktopAssetName,
|
|
22152
|
+
browser_download_url: ""
|
|
22153
|
+
};
|
|
22154
|
+
selectedAssetKind = opts.desktopAssetKind ?? "full";
|
|
22155
|
+
expectedChecksum = normalizeDesktopAssetChecksum(exactDesktopAssetChecksum);
|
|
22156
|
+
const computedReleaseDigest = createHash2("sha256").update(JSON.stringify({
|
|
22157
|
+
releaseTag,
|
|
22158
|
+
assetName: selectedAsset.name,
|
|
22159
|
+
assetChecksum: expectedChecksum,
|
|
22160
|
+
assetKind: selectedAssetKind,
|
|
22161
|
+
platform: target.platform,
|
|
22162
|
+
arch: target.arch
|
|
22163
|
+
})).digest("hex");
|
|
22164
|
+
if (computedReleaseDigest !== exactDesktopReleaseDigest.toLowerCase()) {
|
|
22165
|
+
throw new Error("Exact Desktop asset release digest does not match the candidate identity.");
|
|
22166
|
+
}
|
|
22167
|
+
const descriptor = await stat5(exactDesktopAssetPath);
|
|
22168
|
+
if (!descriptor.isFile()) throw new Error("Exact Desktop asset must be a regular file.");
|
|
22169
|
+
const linkDescriptor = await lstat(exactDesktopAssetPath);
|
|
22170
|
+
if (linkDescriptor.isSymbolicLink()) throw new Error("Exact Desktop asset must not be a symbolic link.");
|
|
22171
|
+
const checksum = await runStartPhase(
|
|
22172
|
+
"Verifying staged Desktop checksum...",
|
|
22173
|
+
`Verified ${pc14.cyan(path22.basename(exactDesktopAssetPath))}.`,
|
|
22174
|
+
() => assertChecksumMatch(exactDesktopAssetPath, expectedChecksum),
|
|
22175
|
+
desktopProgressJson ? "verifying_checksum" : null
|
|
21576
22176
|
);
|
|
22177
|
+
cachedAsset = { path: exactDesktopAssetPath, checksum, cacheStatus: "hit" };
|
|
22178
|
+
} else {
|
|
22179
|
+
const directReleaseVersion = resolveDesktopReleaseVersion(tag);
|
|
22180
|
+
let release = null;
|
|
22181
|
+
try {
|
|
22182
|
+
release = await runStartPhase(
|
|
22183
|
+
"Resolving Desktop release...",
|
|
22184
|
+
"Desktop release resolved.",
|
|
22185
|
+
() => fetchGithubRelease(repo, tag),
|
|
22186
|
+
desktopProgressJson ? "resolving_release" : null
|
|
22187
|
+
);
|
|
22188
|
+
} catch (error) {
|
|
22189
|
+
if (!directReleaseVersion) throw error;
|
|
22190
|
+
p15.log.warn(
|
|
22191
|
+
`Desktop release metadata could not be resolved; falling back to deterministic download URLs. ${formatFetchError(error)}`
|
|
22192
|
+
);
|
|
22193
|
+
}
|
|
22194
|
+
releaseTag = release?.tag_name ?? (directReleaseVersion ? tag : "");
|
|
22195
|
+
if (!releaseTag) throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);
|
|
22196
|
+
assetCandidates = resolveDesktopAssetCandidates({
|
|
22197
|
+
releaseAssets: release?.assets ?? [],
|
|
22198
|
+
target,
|
|
22199
|
+
repo,
|
|
22200
|
+
tag,
|
|
22201
|
+
directReleaseVersion,
|
|
22202
|
+
allowShellAssets: runtimeSupportsShellAssets
|
|
22203
|
+
});
|
|
22204
|
+
if (assetCandidates.length === 0) {
|
|
22205
|
+
throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
|
|
22206
|
+
}
|
|
22207
|
+
const checksumAsset = selectChecksumAsset(release?.assets ?? []) ?? (directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : null);
|
|
22208
|
+
checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);
|
|
22209
|
+
let selectedCandidate;
|
|
22210
|
+
try {
|
|
22211
|
+
selectedCandidate = selectChecksummedDesktopAssetCandidate(assetCandidates, checksums);
|
|
22212
|
+
} catch {
|
|
22213
|
+
throw new Error(`No checksummed Rudder Desktop asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
|
|
22214
|
+
}
|
|
22215
|
+
for (const warning of selectedCandidate.warnings) p15.log.warn(warning);
|
|
22216
|
+
selectedAsset = selectedCandidate.asset;
|
|
22217
|
+
selectedAssetKind = selectedCandidate.kind;
|
|
22218
|
+
expectedChecksum = selectedCandidate.expectedChecksum;
|
|
21577
22219
|
}
|
|
21578
|
-
const releaseTag = release?.tag_name ?? (directReleaseVersion ? tag : null);
|
|
21579
|
-
if (!releaseTag) {
|
|
21580
|
-
throw new Error(`Unable to resolve Rudder Desktop release tag for ${repo}@${tag}.`);
|
|
21581
|
-
}
|
|
21582
|
-
const assetCandidates = resolveDesktopAssetCandidates({
|
|
21583
|
-
releaseAssets: release?.assets ?? [],
|
|
21584
|
-
target,
|
|
21585
|
-
repo,
|
|
21586
|
-
tag,
|
|
21587
|
-
directReleaseVersion,
|
|
21588
|
-
allowShellAssets: runtimeSupportsShellAssets
|
|
21589
|
-
});
|
|
21590
|
-
if (assetCandidates.length === 0) {
|
|
21591
|
-
throw new Error(`No Rudder Desktop portable asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
|
|
21592
|
-
}
|
|
21593
|
-
const checksumAsset = selectChecksumAsset(release?.assets ?? []) ?? (directReleaseVersion ? buildGithubReleaseAsset(repo, tag, DESKTOP_CHECKSUM_ASSET_NAME) : null);
|
|
21594
|
-
const checksums = await downloadChecksums(checksumAsset, outputDir, progressFactory);
|
|
21595
|
-
let selectedCandidate;
|
|
21596
|
-
try {
|
|
21597
|
-
selectedCandidate = selectChecksummedDesktopAssetCandidate(assetCandidates, checksums);
|
|
21598
|
-
} catch (error) {
|
|
21599
|
-
throw new Error(`No checksummed Rudder Desktop asset found for ${target.platform}/${target.arch} in ${repo}@${releaseTag}.`);
|
|
21600
|
-
}
|
|
21601
|
-
for (const warning of selectedCandidate.warnings) p15.log.warn(warning);
|
|
21602
|
-
let selectedAsset = selectedCandidate.asset;
|
|
21603
|
-
let selectedAssetKind = selectedCandidate.kind;
|
|
21604
|
-
let expectedChecksum = selectedCandidate.expectedChecksum;
|
|
21605
22220
|
const metadata = await readInstallMetadata(installPaths.metadataPath);
|
|
21606
22221
|
if (isInstalledDesktopCurrent(metadata, releaseTag, selectedAsset.name, expectedChecksum) && await pathExists2(installPaths.executablePath)) {
|
|
21607
22222
|
p15.log.success(`Rudder Desktop is already installed at ${pc14.cyan(installPaths.appPath)}.`);
|
|
@@ -21615,8 +22230,7 @@ async function startCommand(opts) {
|
|
|
21615
22230
|
desktopProgressJson ? "preparing_restart" : null
|
|
21616
22231
|
);
|
|
21617
22232
|
} else {
|
|
21618
|
-
|
|
21619
|
-
try {
|
|
22233
|
+
if (!exactDesktopAssetPath) try {
|
|
21620
22234
|
cachedAsset = await downloadDesktopAssetWithCache(selectedAsset, expectedChecksum, {
|
|
21621
22235
|
outputDir,
|
|
21622
22236
|
progressFactory
|
|
@@ -21635,8 +22249,10 @@ async function startCommand(opts) {
|
|
|
21635
22249
|
progressFactory
|
|
21636
22250
|
});
|
|
21637
22251
|
}
|
|
21638
|
-
if (cachedAsset
|
|
21639
|
-
|
|
22252
|
+
if (!cachedAsset) throw new Error("Desktop update did not produce a verified asset.");
|
|
22253
|
+
const verifiedAsset = cachedAsset;
|
|
22254
|
+
if (verifiedAsset.cacheStatus === "hit") {
|
|
22255
|
+
p15.log.success(`Desktop asset cache hit at ${pc14.cyan(verifiedAsset.path)}.`);
|
|
21640
22256
|
if (desktopProgressJson) {
|
|
21641
22257
|
writeDesktopProgress({
|
|
21642
22258
|
phase: "downloading_asset",
|
|
@@ -21647,10 +22263,30 @@ async function startCommand(opts) {
|
|
|
21647
22263
|
}
|
|
21648
22264
|
const checksum = await runStartPhase(
|
|
21649
22265
|
"Verifying Desktop checksum...",
|
|
21650
|
-
`Verified ${pc14.cyan(path22.basename(
|
|
21651
|
-
() => assertChecksumMatch(
|
|
22266
|
+
`Verified ${pc14.cyan(path22.basename(verifiedAsset.path))}.`,
|
|
22267
|
+
() => assertChecksumMatch(verifiedAsset.path, expectedChecksum),
|
|
21652
22268
|
desktopProgressJson ? "verifying_checksum" : null
|
|
21653
22269
|
);
|
|
22270
|
+
if (opts.desktopPrepareOnly === true) {
|
|
22271
|
+
writeDesktopProgress({
|
|
22272
|
+
phase: "prepared",
|
|
22273
|
+
message: "Desktop update is downloaded and verified.",
|
|
22274
|
+
percent: 100,
|
|
22275
|
+
assetName: selectedAsset.name,
|
|
22276
|
+
assetChecksum: checksum,
|
|
22277
|
+
stagedArtifactPath: path22.resolve(verifiedAsset.path),
|
|
22278
|
+
stagedArtifactDigest: checksum,
|
|
22279
|
+
releaseDigest: createHash2("sha256").update(JSON.stringify({
|
|
22280
|
+
releaseTag,
|
|
22281
|
+
assetName: selectedAsset.name,
|
|
22282
|
+
assetChecksum: checksum,
|
|
22283
|
+
assetKind: selectedAssetKind,
|
|
22284
|
+
platform: target.platform,
|
|
22285
|
+
arch: target.arch
|
|
22286
|
+
})).digest("hex")
|
|
22287
|
+
});
|
|
22288
|
+
return;
|
|
22289
|
+
}
|
|
21654
22290
|
let applySignal = null;
|
|
21655
22291
|
let applySignalController = null;
|
|
21656
22292
|
if (desktopProgressJson && opts.desktopWaitForApply === true) {
|
|
@@ -21688,7 +22324,7 @@ async function startCommand(opts) {
|
|
|
21688
22324
|
await runStartPhase(
|
|
21689
22325
|
"Installing portable Desktop app...",
|
|
21690
22326
|
`Installed Rudder Desktop to ${pc14.cyan(installPaths.appPath)}.`,
|
|
21691
|
-
() => installPortableDesktop(
|
|
22327
|
+
() => installPortableDesktop(verifiedAsset.path, installPaths, target),
|
|
21692
22328
|
desktopProgressJson ? "preparing_restart" : null
|
|
21693
22329
|
);
|
|
21694
22330
|
await runStartPhase(
|
|
@@ -21795,7 +22431,7 @@ function createProgram() {
|
|
|
21795
22431
|
});
|
|
21796
22432
|
loadRudderEnvFile(options.config);
|
|
21797
22433
|
});
|
|
21798
|
-
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--server-only", "Prepare the Rudder server runtime and persistent CLI without installing Desktop").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
22434
|
+
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--server-only", "Prepare the Rudder server runtime and persistent CLI without installing Desktop").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--desktop-wait-for-apply", "Wait for an apply signal after downloading and verifying the Desktop update", false).option("--desktop-prepare-only", "Download and verify the Desktop update without installing or launching it", false).option("--desktop-asset-path <path>", "Use one previously staged, exact Desktop asset path").option("--desktop-asset-checksum <sha256>", "SHA-256 for the exact staged Desktop asset").option("--desktop-asset-name <name>", "Asset name bound to the exact staged Desktop candidate").option("--desktop-asset-kind <kind>", "Asset kind bound to the exact staged Desktop candidate (full or shell)").option("--desktop-release-digest <sha256>", "Release digest bound to the exact staged Desktop candidate").option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
21799
22435
|
program.command("onboard").description("Interactive first-run setup wizard").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("-y, --yes", "Accept defaults (quickstart + start immediately)", false).option("--run", "Start Rudder immediately after saving config", false).action(onboard);
|
|
21800
22436
|
program.command("doctor").description("Run diagnostic checks on your Rudder setup").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("--repair", "Attempt to repair issues automatically").alias("--fix").option("-y, --yes", "Skip repair confirmation prompts").action(async (opts) => {
|
|
21801
22437
|
await doctor(opts);
|
|
@@ -21825,6 +22461,7 @@ function createProgram() {
|
|
|
21825
22461
|
).option("--trigger <trigger>", "Trigger detail (manual | ping | callback | system)", "manual").option("--timeout-ms <ms>", "Max time to wait before giving up", "0").option("--json", "Output raw JSON where applicable").option("--debug", "Show raw adapter stdout/stderr JSON chunks").action(heartbeatRun);
|
|
21826
22462
|
registerContextCommands(program);
|
|
21827
22463
|
registerCompanyCommands(program);
|
|
22464
|
+
registerGoalCommands(program);
|
|
21828
22465
|
registerIssueCommands(program);
|
|
21829
22466
|
registerProjectCommands(program);
|
|
21830
22467
|
registerAgentCommands(program);
|