@kaiba-cloud/orbital 0.0.3 → 0.0.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/README.md +26 -2
- package/dist/index.js +17316 -15931
- package/dist/mod.json +1 -1
- package/dist/orbital.js +17062 -15571
- package/dist/runner.js +252 -96
- package/package.json +6 -7
- package/schemas/telemetry-event.schema.json +7 -6
- package/schemas/telemetry-snapshot.schema.json +34 -6
- package/skills/orbital-plugin-builder/SKILL.md +9 -17
- package/skills/orbital-plugin-builder/references/host-api.md +17 -13
- package/skills/orbital-plugin-builder/references/manifest.md +7 -2
- package/skills/orbital-plugin-builder/references/ports.md +87 -23
- package/skills/orbital-plugin-builder/references/recipes.md +6 -89
package/dist/runner.js
CHANGED
|
@@ -45510,7 +45510,7 @@ function handleIntersectionResults(result, left, right) {
|
|
|
45510
45510
|
const unrecKeys = /* @__PURE__ */ new Map();
|
|
45511
45511
|
let unrecIssue;
|
|
45512
45512
|
const keyIssues = /* @__PURE__ */ new Map();
|
|
45513
|
-
const
|
|
45513
|
+
const collect2 = (iss, side) => {
|
|
45514
45514
|
let keys;
|
|
45515
45515
|
if (iss.code === "unrecognized_keys" && !iss.path?.length) {
|
|
45516
45516
|
unrecIssue ?? (unrecIssue = iss);
|
|
@@ -45531,11 +45531,11 @@ function handleIntersectionResults(result, left, right) {
|
|
|
45531
45531
|
return true;
|
|
45532
45532
|
};
|
|
45533
45533
|
for (const iss of left.issues) {
|
|
45534
|
-
if (!
|
|
45534
|
+
if (!collect2(iss, "l"))
|
|
45535
45535
|
result.issues.push(iss);
|
|
45536
45536
|
}
|
|
45537
45537
|
for (const iss of right.issues) {
|
|
45538
|
-
if (!
|
|
45538
|
+
if (!collect2(iss, "r"))
|
|
45539
45539
|
result.issues.push(iss);
|
|
45540
45540
|
}
|
|
45541
45541
|
const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
|
|
@@ -61386,6 +61386,7 @@ var ORBITAL_META = {
|
|
|
61386
61386
|
requestedModel: "orbital/requestedModel",
|
|
61387
61387
|
fromAgent: "orbital/fromAgent",
|
|
61388
61388
|
fromSession: "orbital/fromSession",
|
|
61389
|
+
fromTeam: "orbital/fromTeam",
|
|
61389
61390
|
peerHops: "orbital/peerHops",
|
|
61390
61391
|
entry: "orbital/entry",
|
|
61391
61392
|
block: "orbital/block",
|
|
@@ -61645,6 +61646,16 @@ var MissionChangeSchema = external_exports.object({
|
|
|
61645
61646
|
by: external_exports.string(),
|
|
61646
61647
|
note: external_exports.string().nullable()
|
|
61647
61648
|
});
|
|
61649
|
+
var MissionLinkSchema = external_exports.object({
|
|
61650
|
+
label: external_exports.string().min(1),
|
|
61651
|
+
url: external_exports.string().url().refine((url2) => /^https?:\/\//i.test(url2), "a link is an http or https URL"),
|
|
61652
|
+
state: external_exports.string().min(1).nullable().default(null)
|
|
61653
|
+
});
|
|
61654
|
+
var MissionAskedSchema = external_exports.object({
|
|
61655
|
+
id: external_exports.string().min(1),
|
|
61656
|
+
question: external_exports.string().min(1),
|
|
61657
|
+
at: external_exports.string()
|
|
61658
|
+
});
|
|
61648
61659
|
var MissionStateFileSchema = external_exports.object({
|
|
61649
61660
|
mission: external_exports.string().min(1),
|
|
61650
61661
|
node: external_exports.string().min(1),
|
|
@@ -61655,10 +61666,12 @@ var MissionStateFileSchema = external_exports.object({
|
|
|
61655
61666
|
source: external_exports.string().nullable(),
|
|
61656
61667
|
result: external_exports.string().nullable(),
|
|
61657
61668
|
question: external_exports.string().nullable(),
|
|
61658
|
-
|
|
61669
|
+
receivers: external_exports.array(external_exports.string().min(1)).default([]),
|
|
61659
61670
|
lead: external_exports.string().nullable(),
|
|
61660
61671
|
claim: external_exports.string().nullable(),
|
|
61661
61672
|
claimedAt: external_exports.string().nullable(),
|
|
61673
|
+
links: external_exports.array(MissionLinkSchema).default([]),
|
|
61674
|
+
questions: external_exports.array(MissionAskedSchema).default([]),
|
|
61662
61675
|
history: external_exports.array(MissionChangeSchema)
|
|
61663
61676
|
});
|
|
61664
61677
|
var MISSION_ID = /^[a-z0-9][a-z0-9-]{0,62}$/;
|
|
@@ -61672,12 +61685,15 @@ var MissionRecordSchema = external_exports.object({
|
|
|
61672
61685
|
declared: external_exports.boolean(),
|
|
61673
61686
|
givenBy: external_exports.string().nullable(),
|
|
61674
61687
|
brief: external_exports.string().nullable(),
|
|
61688
|
+
summary: external_exports.string().nullable().default(null),
|
|
61689
|
+
links: external_exports.array(MissionLinkSchema).default([]),
|
|
61675
61690
|
sessionId: external_exports.string().nullable(),
|
|
61676
61691
|
taskId: external_exports.string().nullable(),
|
|
61677
61692
|
source: external_exports.string().nullable(),
|
|
61678
61693
|
result: external_exports.string().nullable(),
|
|
61679
61694
|
question: external_exports.string().nullable(),
|
|
61680
|
-
|
|
61695
|
+
questions: external_exports.array(MissionAskedSchema).default([]),
|
|
61696
|
+
receivers: external_exports.array(external_exports.string().min(1)).default([]),
|
|
61681
61697
|
lead: external_exports.string().nullable(),
|
|
61682
61698
|
lastActivity: external_exports.string().nullable().default(null),
|
|
61683
61699
|
claim: external_exports.string().nullable().default(null),
|
|
@@ -61693,6 +61709,11 @@ var MissionHandoffSchema = external_exports.object({
|
|
|
61693
61709
|
state: MissionOutcomeSchema.default("done"),
|
|
61694
61710
|
result: external_exports.string().min(1)
|
|
61695
61711
|
});
|
|
61712
|
+
var MissionLinkRequestSchema = MissionLinkSchema.extend({ missionId: MissionIdSchema.optional() });
|
|
61713
|
+
var MissionAskRequestSchema = external_exports.object({
|
|
61714
|
+
missionId: MissionIdSchema.optional(),
|
|
61715
|
+
question: external_exports.string().min(1)
|
|
61716
|
+
});
|
|
61696
61717
|
var MissionStartRequestSchema = external_exports.object({
|
|
61697
61718
|
mission: MissionIdSchema,
|
|
61698
61719
|
team: external_exports.string().min(1).nullable().default(null),
|
|
@@ -61711,11 +61732,13 @@ var MissionNewRequestSchema = external_exports.object({
|
|
|
61711
61732
|
var MissionWrittenSchema = external_exports.object({ missionId: external_exports.string().min(1), file: external_exports.string().min(1) });
|
|
61712
61733
|
var MissionReplySchema = external_exports.object({
|
|
61713
61734
|
missionId: MissionIdSchema,
|
|
61714
|
-
text: external_exports.string().min(1)
|
|
61735
|
+
text: external_exports.string().min(1),
|
|
61736
|
+
questionId: external_exports.string().min(1).optional()
|
|
61715
61737
|
});
|
|
61716
|
-
var
|
|
61717
|
-
var
|
|
61718
|
-
var
|
|
61738
|
+
var RemoteReceiverSchema = external_exports.object({ node: external_exports.string().min(1), sessionId: external_exports.string().min(1) });
|
|
61739
|
+
var SENDER_FIELDS = { team: external_exports.string().min(1).nullable().default(null), agent: external_exports.string().min(1).nullable().default(null) };
|
|
61740
|
+
var RelayJoinSchema = external_exports.object({ missionId: MissionIdSchema, receiver: RemoteReceiverSchema, ...SENDER_FIELDS });
|
|
61741
|
+
var RelayReplySchema = external_exports.object({ missionId: MissionIdSchema, text: external_exports.string().min(1), questionId: external_exports.string().min(1).optional(), by: external_exports.string().min(1), ...SENDER_FIELDS });
|
|
61719
61742
|
var MissionControlSchema = external_exports.object({ missionId: MissionIdSchema });
|
|
61720
61743
|
var SayRequestSchema = external_exports.object({
|
|
61721
61744
|
target: external_exports.string().min(1),
|
|
@@ -61726,18 +61749,21 @@ var SaidSchema = external_exports.object({
|
|
|
61726
61749
|
missionId: external_exports.string().nullable(),
|
|
61727
61750
|
delivery: external_exports.enum(["reply", "steer", "turn"])
|
|
61728
61751
|
});
|
|
61729
|
-
var RelayMessageSchema = external_exports.object({ missionId: MissionIdSchema, text: external_exports.string().min(1), by: external_exports.string().min(1) });
|
|
61730
|
-
var RelayControlSchema = external_exports.object({ missionId: MissionIdSchema, by: external_exports.string().min(1) });
|
|
61752
|
+
var RelayMessageSchema = external_exports.object({ missionId: MissionIdSchema, text: external_exports.string().min(1), by: external_exports.string().min(1), ...SENDER_FIELDS });
|
|
61753
|
+
var RelayControlSchema = external_exports.object({ missionId: MissionIdSchema, by: external_exports.string().min(1), ...SENDER_FIELDS });
|
|
61731
61754
|
var MissionQuestionSchema = external_exports.object({
|
|
61732
61755
|
missionId: MissionIdSchema,
|
|
61733
61756
|
node: external_exports.string().min(1),
|
|
61734
61757
|
lead: external_exports.string().nullable(),
|
|
61735
61758
|
leadSessionId: external_exports.string().min(1),
|
|
61736
61759
|
question: external_exports.string(),
|
|
61737
|
-
|
|
61760
|
+
questionId: external_exports.string().min(1).optional(),
|
|
61761
|
+
receiver: RemoteReceiverSchema,
|
|
61762
|
+
team: external_exports.string().min(1).nullable().default(null)
|
|
61738
61763
|
});
|
|
61739
61764
|
var MissionJoinSchema = external_exports.object({
|
|
61740
|
-
missionId: MissionIdSchema
|
|
61765
|
+
missionId: MissionIdSchema,
|
|
61766
|
+
externalId: external_exports.string().min(1).optional()
|
|
61741
61767
|
});
|
|
61742
61768
|
|
|
61743
61769
|
// src/protocol/charter.ts
|
|
@@ -61811,7 +61837,7 @@ var MissionStateEventSchema = external_exports.object({
|
|
|
61811
61837
|
transition: MissionTransitionSchema,
|
|
61812
61838
|
reason: external_exports.string().nullable(),
|
|
61813
61839
|
by: external_exports.string(),
|
|
61814
|
-
|
|
61840
|
+
receivers: external_exports.array(external_exports.string()).default([]),
|
|
61815
61841
|
sessionId: external_exports.string().nullable(),
|
|
61816
61842
|
lead: external_exports.string().nullable(),
|
|
61817
61843
|
question: external_exports.string().nullable(),
|
|
@@ -61865,9 +61891,10 @@ var TelemetrySnapshotSchema = external_exports.object({
|
|
|
61865
61891
|
state: MissionStateSchema,
|
|
61866
61892
|
sessionId: external_exports.string().nullable(),
|
|
61867
61893
|
lead: external_exports.string().nullable(),
|
|
61868
|
-
|
|
61894
|
+
receivers: external_exports.array(external_exports.string()).default([]),
|
|
61869
61895
|
givenBy: external_exports.string().nullable(),
|
|
61870
61896
|
question: external_exports.string().nullable(),
|
|
61897
|
+
questions: external_exports.array(MissionAskedSchema).default([]),
|
|
61871
61898
|
result: external_exports.string().nullable(),
|
|
61872
61899
|
updatedAt: external_exports.string().nullable()
|
|
61873
61900
|
})),
|
|
@@ -62255,9 +62282,18 @@ var NodeClient = class {
|
|
|
62255
62282
|
async joinMission(missionId) {
|
|
62256
62283
|
return MissionRecordSchema.parse(await this.request("/orbital/missions/join", { method: "POST", body: { missionId } }));
|
|
62257
62284
|
}
|
|
62285
|
+
async leaveMission(missionId) {
|
|
62286
|
+
return MissionRecordSchema.parse(await this.request("/orbital/missions/leave", { method: "POST", body: { missionId } }));
|
|
62287
|
+
}
|
|
62258
62288
|
async handoff(handoff2) {
|
|
62259
62289
|
return MissionRecordSchema.parse(await this.request("/orbital/missions/handoff", { method: "POST", body: handoff2 }));
|
|
62260
62290
|
}
|
|
62291
|
+
async link(link) {
|
|
62292
|
+
return MissionRecordSchema.parse(await this.request("/orbital/missions/link", { method: "POST", body: link }));
|
|
62293
|
+
}
|
|
62294
|
+
async ask(ask) {
|
|
62295
|
+
return MissionRecordSchema.parse(await this.request("/orbital/missions/ask", { method: "POST", body: ask }));
|
|
62296
|
+
}
|
|
62261
62297
|
async transcript(sessionId, limit) {
|
|
62262
62298
|
return SessionTranscriptSchema.parse(await this.request(`/orbital/sessions/${encodeURIComponent(sessionId)}/transcript?limit=${limit}`));
|
|
62263
62299
|
}
|
|
@@ -62482,6 +62518,14 @@ var DeliverySchema = external_exports.object({
|
|
|
62482
62518
|
fromAgent: external_exports.string().nullable(),
|
|
62483
62519
|
fromSession: external_exports.string().nullable(),
|
|
62484
62520
|
mission: external_exports.string().nullable().default(null),
|
|
62521
|
+
question: external_exports.string().nullable().default(null),
|
|
62522
|
+
text: external_exports.string()
|
|
62523
|
+
});
|
|
62524
|
+
var AnsweredSchema = external_exports.object({
|
|
62525
|
+
kind: external_exports.literal("answered"),
|
|
62526
|
+
mission: external_exports.string().min(1),
|
|
62527
|
+
question: external_exports.string().nullable(),
|
|
62528
|
+
by: external_exports.string().min(1),
|
|
62485
62529
|
text: external_exports.string()
|
|
62486
62530
|
});
|
|
62487
62531
|
var SettleSchema = external_exports.object({
|
|
@@ -62532,6 +62576,7 @@ var HarnessFolderSchema = external_exports.strictObject({
|
|
|
62532
62576
|
var HarnessAdapterDeclarationSchema = HarnessFolderSchema.extend({ id: external_exports.string().regex(/^[a-z][a-z0-9-]{0,31}$/) });
|
|
62533
62577
|
var HarnessInstallResultSchema = external_exports.object({
|
|
62534
62578
|
written: external_exports.array(external_exports.string()).default([]),
|
|
62579
|
+
removed: external_exports.array(external_exports.string()).default([]),
|
|
62535
62580
|
notes: external_exports.array(external_exports.string()).default([])
|
|
62536
62581
|
});
|
|
62537
62582
|
var HarnessAgentFileSchema = external_exports.object({
|
|
@@ -62634,6 +62679,60 @@ var LeaseSchema = external_exports.object({ holder: external_exports.string(), e
|
|
|
62634
62679
|
|
|
62635
62680
|
// src/protocol/plugin-protocol.ts
|
|
62636
62681
|
var PORTS_VERSION = "orbital/v1alpha1";
|
|
62682
|
+
var PLUGIN_COMMAND_RESERVED_OPTIONS = ["output", "quiet", "non-interactive", "confirm", "timeout", "help", "version", "workspace", "node"];
|
|
62683
|
+
var PluginCommandOptionSchema = external_exports.object({
|
|
62684
|
+
name: external_exports.string().regex(NAME_SHAPE).refine((name) => !PLUGIN_COMMAND_RESERVED_OPTIONS.includes(name), { error: `an option cannot take a name orbital gives every command: ${PLUGIN_COMMAND_RESERVED_OPTIONS.join(", ")}` }),
|
|
62685
|
+
type: external_exports.enum(["string", "boolean", "integer", "enum", "path"]),
|
|
62686
|
+
summary: external_exports.string().min(1),
|
|
62687
|
+
values: external_exports.array(external_exports.string().min(1)).min(1).optional(),
|
|
62688
|
+
required: external_exports.boolean().default(false),
|
|
62689
|
+
default: external_exports.union([external_exports.string(), external_exports.number().int(), external_exports.boolean()]).optional()
|
|
62690
|
+
}).strict().superRefine((option, issues) => {
|
|
62691
|
+
if (option.type === "enum" !== (option.values !== void 0)) issues.addIssue({ code: "custom", message: `the option ${option.name} names values only when its type is enum` });
|
|
62692
|
+
if (option.type === "boolean" && option.required) issues.addIssue({ code: "custom", message: `the boolean option ${option.name} cannot be required` });
|
|
62693
|
+
if (option.default === void 0) return;
|
|
62694
|
+
const fits = option.type === "boolean" ? typeof option.default === "boolean" : option.type === "integer" ? typeof option.default === "number" : typeof option.default === "string" && (option.values?.includes(option.default) ?? true);
|
|
62695
|
+
if (!fits) issues.addIssue({ code: "custom", message: `the default of the option ${option.name} is not a ${option.type === "enum" ? `value of ${option.values.join(", ")}` : option.type}` });
|
|
62696
|
+
});
|
|
62697
|
+
var PluginCommandArgSchema = external_exports.object({
|
|
62698
|
+
name: external_exports.string().regex(NAME_SHAPE),
|
|
62699
|
+
summary: external_exports.string().min(1),
|
|
62700
|
+
required: external_exports.boolean().default(false),
|
|
62701
|
+
variadic: external_exports.boolean().default(false)
|
|
62702
|
+
}).strict();
|
|
62703
|
+
var PluginCommandSchema = external_exports.object({
|
|
62704
|
+
name: external_exports.string().regex(NAME_SHAPE),
|
|
62705
|
+
summary: external_exports.string().min(1),
|
|
62706
|
+
args: external_exports.array(PluginCommandArgSchema).default([]),
|
|
62707
|
+
options: external_exports.array(PluginCommandOptionSchema).default([]),
|
|
62708
|
+
interactive: external_exports.boolean().default(false),
|
|
62709
|
+
node: external_exports.boolean().default(false)
|
|
62710
|
+
}).strict().superRefine((command, issues) => {
|
|
62711
|
+
const twice = (names) => names.find((name, index) => names.indexOf(name) !== index);
|
|
62712
|
+
const arg = twice(command.args.map((one) => one.name));
|
|
62713
|
+
if (arg) issues.addIssue({ code: "custom", message: `the command ${command.name} names the argument ${arg} twice` });
|
|
62714
|
+
const option = twice(command.options.map((one) => one.name));
|
|
62715
|
+
if (option) issues.addIssue({ code: "custom", message: `the command ${command.name} names the option ${option} twice` });
|
|
62716
|
+
if (command.args.slice(0, -1).some((one) => one.variadic)) issues.addIssue({ code: "custom", message: `only the last argument of the command ${command.name} can be variadic` });
|
|
62717
|
+
if (command.args.some((one, index) => one.required && command.args.slice(0, index).some((before) => !before.required))) issues.addIssue({ code: "custom", message: `a required argument of the command ${command.name} cannot come after an optional one` });
|
|
62718
|
+
if (command.interactive && command.node) issues.addIssue({ code: "custom", message: `the command ${command.name} cannot be interactive and need the node: the node has no terminal to give it` });
|
|
62719
|
+
});
|
|
62720
|
+
var PluginCommandsSchema = external_exports.array(PluginCommandSchema).default([]).superRefine((commands, issues) => {
|
|
62721
|
+
const names = commands.map((one) => one.name);
|
|
62722
|
+
const twice = names.find((name, index) => names.indexOf(name) !== index);
|
|
62723
|
+
if (twice) issues.addIssue({ code: "custom", message: `the command ${twice} is declared twice` });
|
|
62724
|
+
});
|
|
62725
|
+
var PluginCommandRequestSchema = external_exports.object({
|
|
62726
|
+
name: external_exports.string().regex(NAME_SHAPE),
|
|
62727
|
+
args: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.array(external_exports.string())])).default({}),
|
|
62728
|
+
options: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).default({}),
|
|
62729
|
+
terminal: external_exports.object({ tty: external_exports.boolean() }).nullable().default(null)
|
|
62730
|
+
}).strict();
|
|
62731
|
+
var PluginCommandResultSchema = external_exports.object({
|
|
62732
|
+
exitCode: external_exports.union([external_exports.literal(0), external_exports.literal(1), external_exports.literal(2), external_exports.literal(3), external_exports.literal(5)]).default(0),
|
|
62733
|
+
text: external_exports.string().nullable().default(null),
|
|
62734
|
+
data: external_exports.record(external_exports.string(), external_exports.unknown()).default({})
|
|
62735
|
+
}).strict();
|
|
62637
62736
|
var PluginManifestSchema = external_exports.object({
|
|
62638
62737
|
name: external_exports.string().regex(NAME_SHAPE),
|
|
62639
62738
|
version: external_exports.string().min(1),
|
|
@@ -62663,7 +62762,7 @@ var PluginManifestSchema = external_exports.object({
|
|
|
62663
62762
|
secrets: external_exports.array(external_exports.string().min(1)).default([]),
|
|
62664
62763
|
models: external_exports.array(external_exports.string().regex(/^[a-z0-9-]+:.+$/, "a model pattern is <provider>:<model>, such as anthropic:*")).default([])
|
|
62665
62764
|
}).prefault({}),
|
|
62666
|
-
commands:
|
|
62765
|
+
commands: PluginCommandsSchema,
|
|
62667
62766
|
panels: external_exports.array(external_exports.object({ id: external_exports.string().min(1), title: external_exports.string(), kind: external_exports.enum(["list", "tree", "transcript", "form"]) })).default([])
|
|
62668
62767
|
}).strict();
|
|
62669
62768
|
var PluginInitSchema = external_exports.object({
|
|
@@ -62686,7 +62785,8 @@ var PluginPackageSchema = external_exports.object({
|
|
|
62686
62785
|
dir: external_exports.string().min(1).optional(),
|
|
62687
62786
|
env: external_exports.array(external_exports.string().regex(PLUGIN_ENV_NAME, "is not the name of an environment variable")).default([]),
|
|
62688
62787
|
config: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
|
|
62689
|
-
harnesses: external_exports.array(HarnessAdapterDeclarationSchema).default([])
|
|
62788
|
+
harnesses: external_exports.array(HarnessAdapterDeclarationSchema).default([]),
|
|
62789
|
+
commands: PluginCommandsSchema
|
|
62690
62790
|
}).strict();
|
|
62691
62791
|
var MarketplaceSchema = external_exports.object({
|
|
62692
62792
|
name: external_exports.string().regex(NAME_SHAPE),
|
|
@@ -62720,12 +62820,6 @@ function localAgentSystemPrompt(systemPrompt, promptBlock) {
|
|
|
62720
62820
|
${promptBlock}` : systemPrompt;
|
|
62721
62821
|
}
|
|
62722
62822
|
|
|
62723
|
-
// src/protocol/keychain.ts
|
|
62724
|
-
var KEYCHAIN_PATH = "/orbital/keychain";
|
|
62725
|
-
var KEYCHAIN_MODE = "keychain";
|
|
62726
|
-
var KeychainCallSchema = external_exports.object({ args: external_exports.array(external_exports.string()), input: external_exports.string().default("") });
|
|
62727
|
-
var KeychainAnswerSchema = external_exports.object({ status: external_exports.number().int(), stdout: external_exports.string(), stderr: external_exports.string() });
|
|
62728
|
-
|
|
62729
62823
|
// src/runner/runtime/harness/claude-browser.ts
|
|
62730
62824
|
import { existsSync, readFileSync } from "node:fs";
|
|
62731
62825
|
import { homedir } from "node:os";
|
|
@@ -75023,7 +75117,8 @@ var ClaudeCodeHarness = class {
|
|
|
75023
75117
|
...QUIET_ENV,
|
|
75024
75118
|
...this.args.toolEnvironment?.(),
|
|
75025
75119
|
...credential && { CLAUDE_CONFIG_DIR: this.configDir },
|
|
75026
|
-
...credential && (isOAuth ? { CLAUDE_CODE_OAUTH_TOKEN: credential.payload } : { ANTHROPIC_API_KEY: credential.payload })
|
|
75120
|
+
...credential && (isOAuth ? { CLAUDE_CODE_OAUTH_TOKEN: credential.payload } : { ANTHROPIC_API_KEY: credential.payload }),
|
|
75121
|
+
...!credential && this.host.login && { CLAUDE_CODE_OAUTH_TOKEN: this.host.login }
|
|
75027
75122
|
};
|
|
75028
75123
|
delete env.NODE_OPTIONS;
|
|
75029
75124
|
return env;
|
|
@@ -81317,6 +81412,8 @@ function createAgentBridgeTools(options) {
|
|
|
81317
81412
|
if (messaging.peers) host.registerTool(buildAgentPeersTool(messaging, options));
|
|
81318
81413
|
if (messaging.mission) host.registerTool(buildMissionGetTool(messaging, options));
|
|
81319
81414
|
if (messaging.handoffMission) host.registerTool(buildMissionHandoffTool(messaging, options));
|
|
81415
|
+
if (messaging.linkMission) host.registerTool(buildMissionLinkTool(messaging, options));
|
|
81416
|
+
if (messaging.askMission) host.registerTool(buildMissionAskTool(messaging, options));
|
|
81320
81417
|
host.registerTool(buildAgentStopTool(jobs, messaging, options, log2));
|
|
81321
81418
|
host.registerTool(buildAgentKillTool(jobs, ledger, messaging, options, log2));
|
|
81322
81419
|
});
|
|
@@ -81658,6 +81755,48 @@ function buildMissionHandoffTool(messaging, options) {
|
|
|
81658
81755
|
}
|
|
81659
81756
|
};
|
|
81660
81757
|
}
|
|
81758
|
+
var MissionLinkParams = Type.Object({
|
|
81759
|
+
label: Type.String({ minLength: 1, description: "A short label, such as PR #42." }),
|
|
81760
|
+
url: Type.String({ minLength: 1, description: "The http or https URL of the link." }),
|
|
81761
|
+
state: Type.Optional(Type.String({ minLength: 1, description: "The state of the linked thing, such as open, merged or closed." }))
|
|
81762
|
+
});
|
|
81763
|
+
function buildMissionLinkTool(messaging, options) {
|
|
81764
|
+
return {
|
|
81765
|
+
name: "missionLink",
|
|
81766
|
+
label: "Link Mission",
|
|
81767
|
+
description: "Add a link to the mission of your session, as its lead, or change the state of a link it has: such as the pull request you opened, with its state open, merged or closed. One URL or one label is one link, so a call with the same URL replaces it. The node keeps the links with the mission, and the person sees them in the live view.",
|
|
81768
|
+
promptSnippet: "missionLink: add a link to your mission, such as the PR you opened, with its state",
|
|
81769
|
+
parameters: MissionLinkParams,
|
|
81770
|
+
executionMode: "sequential",
|
|
81771
|
+
async execute(_toolCallId, params) {
|
|
81772
|
+
try {
|
|
81773
|
+
return textResult(await messaging.linkMission(options.callerSessionId, { label: params.label, url: params.url, state: params.state ?? null }));
|
|
81774
|
+
} catch (err) {
|
|
81775
|
+
return errorResult(`missionLink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
81776
|
+
}
|
|
81777
|
+
}
|
|
81778
|
+
};
|
|
81779
|
+
}
|
|
81780
|
+
var MissionAskParams = Type.Object({
|
|
81781
|
+
question: Type.String({ minLength: 1, description: "The question, in full, with the options you see and what each one means: the receivers have none of your context." })
|
|
81782
|
+
});
|
|
81783
|
+
function buildMissionAskTool(messaging, options) {
|
|
81784
|
+
return {
|
|
81785
|
+
name: "missionAsk",
|
|
81786
|
+
label: "Ask Mission Giver",
|
|
81787
|
+
description: "Ask the decision receivers of the mission of your session a question, as its lead, at any moment, also while your workers run. The node keeps each question open with the mission until a receiver answers it, shows it to the person as waiting on them, and pushes it at once to every live receiver. The answer comes back to you as a message that names the question. Use it for every decision you need: a question only in your reply text reaches no one. Keep working on what does not depend on the answer.",
|
|
81788
|
+
promptSnippet: "missionAsk: ask the decision receivers of your mission a question at any moment, also while your workers run",
|
|
81789
|
+
parameters: MissionAskParams,
|
|
81790
|
+
executionMode: "sequential",
|
|
81791
|
+
async execute(_toolCallId, params) {
|
|
81792
|
+
try {
|
|
81793
|
+
return textResult(await messaging.askMission(options.callerSessionId, { question: params.question }));
|
|
81794
|
+
} catch (err) {
|
|
81795
|
+
return errorResult(`missionAsk failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
81796
|
+
}
|
|
81797
|
+
}
|
|
81798
|
+
};
|
|
81799
|
+
}
|
|
81661
81800
|
function buildAgentMessageTool(jobs, ledger, messaging, options, log2) {
|
|
81662
81801
|
return {
|
|
81663
81802
|
name: "agentMessage",
|
|
@@ -83119,8 +83258,9 @@ var RunSpecSchema = external_exports.object({
|
|
|
83119
83258
|
harness: external_exports.enum(RUNNER_HARNESSES).default("claude"),
|
|
83120
83259
|
claude: external_exports.object({
|
|
83121
83260
|
settings: external_exports.string().nullable(),
|
|
83122
|
-
args: external_exports.array(external_exports.string())
|
|
83123
|
-
|
|
83261
|
+
args: external_exports.array(external_exports.string()),
|
|
83262
|
+
login: external_exports.string().nullable().default(null)
|
|
83263
|
+
}).default({ settings: null, args: [], login: null }),
|
|
83124
83264
|
agent: external_exports.discriminatedUnion("kind", [
|
|
83125
83265
|
external_exports.object({ kind: external_exports.literal("directory"), id: external_exports.string(), bootstrap: external_exports.record(external_exports.string(), external_exports.unknown()) }),
|
|
83126
83266
|
external_exports.object({ kind: external_exports.literal("local"), definition: LocalAgentSchema })
|
|
@@ -83139,19 +83279,88 @@ function readRunSpec(path10) {
|
|
|
83139
83279
|
}
|
|
83140
83280
|
|
|
83141
83281
|
// src/runner/local-store.ts
|
|
83142
|
-
import {
|
|
83282
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
83143
83283
|
import path7 from "node:path";
|
|
83284
|
+
|
|
83285
|
+
// src/runner/jsonl-log.ts
|
|
83286
|
+
import { appendFileSync, closeSync, existsSync as existsSync4, openSync, readSync, renameSync as renameSync2, statSync } from "node:fs";
|
|
83287
|
+
var CHUNK = 64 * 1024;
|
|
83288
|
+
function rotatedPath(file2) {
|
|
83289
|
+
return file2.replace(/\.jsonl$/, ".1.jsonl");
|
|
83290
|
+
}
|
|
83291
|
+
function appendCapped(file2, text, cap) {
|
|
83292
|
+
if (existsSync4(file2) && statSync(file2).size + Buffer.byteLength(text) > cap) renameSync2(file2, rotatedPath(file2));
|
|
83293
|
+
appendFileSync(file2, text);
|
|
83294
|
+
}
|
|
83295
|
+
function backward(file2, take, into) {
|
|
83296
|
+
if (!existsSync4(file2)) return true;
|
|
83297
|
+
const fd = openSync(file2, "r");
|
|
83298
|
+
try {
|
|
83299
|
+
let position = statSync(file2).size;
|
|
83300
|
+
let rest = Buffer.alloc(0);
|
|
83301
|
+
while (position > 0) {
|
|
83302
|
+
const length = Math.min(CHUNK, position);
|
|
83303
|
+
position -= length;
|
|
83304
|
+
const chunk = Buffer.alloc(length);
|
|
83305
|
+
readSync(fd, chunk, 0, length, position);
|
|
83306
|
+
const joined = Buffer.concat([chunk, rest]);
|
|
83307
|
+
let end = joined.length;
|
|
83308
|
+
for (let at = joined.lastIndexOf(10, end - 1); at !== -1; at = end > 0 ? joined.lastIndexOf(10, end - 1) : -1) {
|
|
83309
|
+
const line = joined.subarray(at + 1, end).toString("utf8");
|
|
83310
|
+
end = at;
|
|
83311
|
+
if (line.trim() === "") continue;
|
|
83312
|
+
if (!take(line)) return false;
|
|
83313
|
+
into.push(line);
|
|
83314
|
+
}
|
|
83315
|
+
rest = joined.subarray(0, end);
|
|
83316
|
+
}
|
|
83317
|
+
const first = rest.toString("utf8");
|
|
83318
|
+
if (first.trim() !== "") {
|
|
83319
|
+
if (!take(first)) return false;
|
|
83320
|
+
into.push(first);
|
|
83321
|
+
}
|
|
83322
|
+
return true;
|
|
83323
|
+
} finally {
|
|
83324
|
+
closeSync(fd);
|
|
83325
|
+
}
|
|
83326
|
+
}
|
|
83327
|
+
function collect(file2, take) {
|
|
83328
|
+
const lines = [];
|
|
83329
|
+
if (backward(file2, take, lines)) backward(rotatedPath(file2), take, lines);
|
|
83330
|
+
return lines.reverse();
|
|
83331
|
+
}
|
|
83332
|
+
function tailLines(file2, count, maxBytes = Number.POSITIVE_INFINITY) {
|
|
83333
|
+
let taken = 0;
|
|
83334
|
+
let bytes = 0;
|
|
83335
|
+
return count <= 0 ? [] : collect(file2, (line) => {
|
|
83336
|
+
if (taken >= count || taken > 0 && bytes + line.length > maxBytes) return false;
|
|
83337
|
+
taken += 1;
|
|
83338
|
+
bytes += line.length;
|
|
83339
|
+
return true;
|
|
83340
|
+
});
|
|
83341
|
+
}
|
|
83342
|
+
function sequenceOf(line) {
|
|
83343
|
+
const found = /"sequence":(\d+)/.exec(line);
|
|
83344
|
+
return found ? Number(found[1]) : 0;
|
|
83345
|
+
}
|
|
83346
|
+
function lastSequenceOf(file2) {
|
|
83347
|
+
const last = tailLines(file2, 1)[0];
|
|
83348
|
+
return last ? sequenceOf(last) : 0;
|
|
83349
|
+
}
|
|
83350
|
+
|
|
83351
|
+
// src/runner/local-store.ts
|
|
83144
83352
|
var RUNNER_LOG = "runner.jsonl";
|
|
83353
|
+
var RUNNER_LOG_CAP = 32 * 1024 * 1024;
|
|
83145
83354
|
var HISTORY_DIR = "history";
|
|
83146
83355
|
function folderUnit(dir) {
|
|
83147
83356
|
const walk = (folder) => readdirSync2(folder).flatMap((name) => {
|
|
83148
83357
|
const full = path7.join(folder, name);
|
|
83149
|
-
return
|
|
83358
|
+
return statSync2(full).isDirectory() ? walk(full) : [full];
|
|
83150
83359
|
});
|
|
83151
83360
|
return {
|
|
83152
83361
|
kinds: ["history"],
|
|
83153
83362
|
async list() {
|
|
83154
|
-
if (!
|
|
83363
|
+
if (!existsSync5(dir)) return null;
|
|
83155
83364
|
return Promise.all(walk(dir).map(async (full) => {
|
|
83156
83365
|
const bytes = readFileSync4(full);
|
|
83157
83366
|
return { path: path7.relative(dir, full).split(path7.sep).join("/"), hash: await sha256Hex(bytes), size: bytes.length };
|
|
@@ -83159,7 +83368,7 @@ function folderUnit(dir) {
|
|
|
83159
83368
|
},
|
|
83160
83369
|
async read(_ref, file2) {
|
|
83161
83370
|
const full = path7.join(dir, ...file2.split("/"));
|
|
83162
|
-
return
|
|
83371
|
+
return existsSync5(full) ? { path: file2, contentBase64: readFileSync4(full).toString("base64") } : null;
|
|
83163
83372
|
},
|
|
83164
83373
|
async write() {
|
|
83165
83374
|
throw new Error("The runner reads a session's history unit; the host writes it.");
|
|
@@ -83185,8 +83394,8 @@ var LocalSessionStore = class {
|
|
|
83185
83394
|
async persistEvent(sessionId, event) {
|
|
83186
83395
|
const sequence = (this.sequences.get(sessionId) ?? 0) + 1;
|
|
83187
83396
|
this.sequences.set(sessionId, sequence);
|
|
83188
|
-
|
|
83189
|
-
|
|
83397
|
+
appendCapped(path7.join(this.recordDir(sessionId), RUNNER_LOG), `${JSON.stringify({ sequence, ...event })}
|
|
83398
|
+
`, RUNNER_LOG_CAP);
|
|
83190
83399
|
this.observer.event?.(sessionId, { ...event, sequence });
|
|
83191
83400
|
}
|
|
83192
83401
|
async seedSequence(sessionId, sequence) {
|
|
@@ -83196,9 +83405,7 @@ var LocalSessionStore = class {
|
|
|
83196
83405
|
this.sequences.delete(sessionId);
|
|
83197
83406
|
}
|
|
83198
83407
|
async lastEventSequence(sessionId) {
|
|
83199
|
-
const
|
|
83200
|
-
const lines = existsSync4(file2) ? readFileSync4(file2, "utf8").trim().split("\n").filter(Boolean) : [];
|
|
83201
|
-
const logged = lines.length === 0 ? 0 : JSON.parse(lines[lines.length - 1]).sequence;
|
|
83408
|
+
const logged = lastSequenceOf(path7.join(this.sessionsDir, sessionId, RUNNER_LOG));
|
|
83202
83409
|
return Math.max(logged, (await this.history(sessionId))?.record.watermark ?? 0);
|
|
83203
83410
|
}
|
|
83204
83411
|
async readConversation(sessionId) {
|
|
@@ -83238,7 +83445,7 @@ function createLocalBootstrapSource(options) {
|
|
|
83238
83445
|
mcps: []
|
|
83239
83446
|
};
|
|
83240
83447
|
}
|
|
83241
|
-
return { organizationId: LOCAL_ORGANIZATION, ...spec.agent.bootstrap };
|
|
83448
|
+
return { organizationId: LOCAL_ORGANIZATION, ...spec.agent.bootstrap, systemPrompt: localAgentSystemPrompt(String(spec.agent.bootstrap.systemPrompt ?? ""), spec.promptBlock) };
|
|
83242
83449
|
}
|
|
83243
83450
|
return {
|
|
83244
83451
|
async fetchBootstrap(agentId) {
|
|
@@ -83352,6 +83559,12 @@ var NodeMessaging = class {
|
|
|
83352
83559
|
async handoffMission(callerSessionId, handoff2) {
|
|
83353
83560
|
return this.as(callerSessionId).handoff(handoff2);
|
|
83354
83561
|
}
|
|
83562
|
+
async linkMission(callerSessionId, link) {
|
|
83563
|
+
return this.as(callerSessionId).link(link);
|
|
83564
|
+
}
|
|
83565
|
+
async askMission(callerSessionId, ask) {
|
|
83566
|
+
return this.as(callerSessionId).ask(ask);
|
|
83567
|
+
}
|
|
83355
83568
|
};
|
|
83356
83569
|
|
|
83357
83570
|
// src/runner/node-gateway.ts
|
|
@@ -83415,40 +83628,6 @@ function localLayout(runDir, workspaceDir) {
|
|
|
83415
83628
|
};
|
|
83416
83629
|
}
|
|
83417
83630
|
|
|
83418
|
-
// src/runner/keychain-client.ts
|
|
83419
|
-
async function keychainClient(specPath, args, streams, fetchImpl = fetch) {
|
|
83420
|
-
const spec = readRunSpec(specPath);
|
|
83421
|
-
const input2 = args.length === 1 && args[0] === "-i" ? await streams.stdin() : "";
|
|
83422
|
-
try {
|
|
83423
|
-
const response = await fetchImpl(`${spec.node.url.replace(/\/a2a$/, "")}${KEYCHAIN_PATH}`, {
|
|
83424
|
-
method: "POST",
|
|
83425
|
-
headers: { authorization: `Bearer ${spec.node.token}`, [NODE_SESSION_HEADER]: spec.sessionId, "content-type": "application/json" },
|
|
83426
|
-
body: JSON.stringify({ args, input: input2 })
|
|
83427
|
-
});
|
|
83428
|
-
if (!response.ok) {
|
|
83429
|
-
streams.stderr(`security: the node refused the keychain call (${response.status}): ${(await response.text()).slice(0, 300)}
|
|
83430
|
-
`);
|
|
83431
|
-
return 1;
|
|
83432
|
-
}
|
|
83433
|
-
const answer = KeychainAnswerSchema.parse(await response.json());
|
|
83434
|
-
streams.stdout(answer.stdout);
|
|
83435
|
-
streams.stderr(answer.stderr);
|
|
83436
|
-
return answer.status;
|
|
83437
|
-
} catch (error62) {
|
|
83438
|
-
streams.stderr(`security: the node did not answer the keychain call: ${error62 instanceof Error ? error62.message : String(error62)}
|
|
83439
|
-
`);
|
|
83440
|
-
return 1;
|
|
83441
|
-
}
|
|
83442
|
-
}
|
|
83443
|
-
function readStdin() {
|
|
83444
|
-
return new Promise((resolve2, reject) => {
|
|
83445
|
-
const chunks = [];
|
|
83446
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
83447
|
-
process.stdin.on("end", () => resolve2(Buffer.concat(chunks).toString("utf8")));
|
|
83448
|
-
process.stdin.on("error", reject);
|
|
83449
|
-
});
|
|
83450
|
-
}
|
|
83451
|
-
|
|
83452
83631
|
// src/runner/main.ts
|
|
83453
83632
|
function emit(record2) {
|
|
83454
83633
|
process.stdout.write(`${JSON.stringify(record2)}
|
|
@@ -83461,7 +83640,8 @@ function claudeOnThisMachine(spec) {
|
|
|
83461
83640
|
settingSources: ["user", "project", "local"],
|
|
83462
83641
|
subAgents: true,
|
|
83463
83642
|
...spec.claude.settings && { settings: spec.claude.settings },
|
|
83464
|
-
extraArgs: spec.claude.args
|
|
83643
|
+
extraArgs: spec.claude.args,
|
|
83644
|
+
login: spec.claude.login
|
|
83465
83645
|
};
|
|
83466
83646
|
}
|
|
83467
83647
|
function startLocalRun(spec, fetchImpl = fetch) {
|
|
@@ -83577,31 +83757,7 @@ async function runToCompletion(run, spec, interactiveMode = interactive) {
|
|
|
83577
83757
|
await run.sessions.closeAllSessions();
|
|
83578
83758
|
}
|
|
83579
83759
|
}
|
|
83580
|
-
|
|
83581
|
-
const [specPath, ...args] = process.argv.slice(3);
|
|
83582
|
-
if (!specPath) throw new Error(`usage: runner ${KEYCHAIN_MODE} <spec.json> <security arguments>`);
|
|
83583
|
-
installProxyDispatcher();
|
|
83584
|
-
let out = "";
|
|
83585
|
-
let err = "";
|
|
83586
|
-
const code = await keychainClient(specPath, args, { stdin: readStdin, stdout: (text) => {
|
|
83587
|
-
out += text;
|
|
83588
|
-
}, stderr: (text) => {
|
|
83589
|
-
err += text;
|
|
83590
|
-
} });
|
|
83591
|
-
await new Promise((done) => process.stdout.write(out, () => done()));
|
|
83592
|
-
await new Promise((done) => process.stderr.write(err, () => done()));
|
|
83593
|
-
return code;
|
|
83594
|
-
}
|
|
83595
|
-
var entered = process.argv[1] !== void 0 && import.meta.url === pathToFileURL(realpathSync2(process.argv[1])).href;
|
|
83596
|
-
if (entered && process.argv[2] === KEYCHAIN_MODE) {
|
|
83597
|
-
keychain().then(
|
|
83598
|
-
(code) => process.exit(code),
|
|
83599
|
-
(err) => {
|
|
83600
|
-
process.stderr.write(`security: ${err instanceof Error ? err.message : String(err)}
|
|
83601
|
-
`, () => process.exit(1));
|
|
83602
|
-
}
|
|
83603
|
-
);
|
|
83604
|
-
} else if (entered) {
|
|
83760
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync2(process.argv[1])).href) {
|
|
83605
83761
|
main().then(
|
|
83606
83762
|
() => process.exit(0),
|
|
83607
83763
|
(err) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaiba-cloud/orbital",
|
|
3
3
|
"description": "orbital: the control plane lite for agents on any harness: the node, its runner, its terminal UI, its protocol and its Claude Code mod, in one command line",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -11,17 +11,16 @@
|
|
|
11
11
|
"orbital": "dist/orbital.js"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|
|
14
|
-
".": "./
|
|
15
|
-
"./
|
|
16
|
-
"./sdk": "./src/sdk/index.ts",
|
|
17
|
-
"./tui": "./src/tui/index.tsx",
|
|
18
|
-
"./*": "./src/*.ts"
|
|
14
|
+
".": "./dist/index.js",
|
|
15
|
+
"./package.json": "./package.json"
|
|
19
16
|
},
|
|
20
17
|
"scripts": {
|
|
21
18
|
"build": "node scripts/build.mjs",
|
|
22
19
|
"check-types": "tsc -p tsconfig.json",
|
|
23
20
|
"schemas": "node scripts/schemas.ts",
|
|
24
|
-
"test": "vitest run"
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"prepack": "node ../../scripts/pack-manifest.mjs prepack",
|
|
23
|
+
"postpack": "node ../../scripts/pack-manifest.mjs postpack"
|
|
25
24
|
},
|
|
26
25
|
"dependencies": {
|
|
27
26
|
"@anthropic-ai/claude-agent-sdk": "^0.3.295",
|
|
@@ -566,11 +566,12 @@
|
|
|
566
566
|
"by": {
|
|
567
567
|
"type": "string"
|
|
568
568
|
},
|
|
569
|
-
"
|
|
570
|
-
"
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
569
|
+
"receivers": {
|
|
570
|
+
"default": [],
|
|
571
|
+
"type": "array",
|
|
572
|
+
"items": {
|
|
573
|
+
"type": "string"
|
|
574
|
+
}
|
|
574
575
|
},
|
|
575
576
|
"sessionId": {
|
|
576
577
|
"type": [
|
|
@@ -611,7 +612,7 @@
|
|
|
611
612
|
"transition",
|
|
612
613
|
"reason",
|
|
613
614
|
"by",
|
|
614
|
-
"
|
|
615
|
+
"receivers",
|
|
615
616
|
"sessionId",
|
|
616
617
|
"lead",
|
|
617
618
|
"question",
|