@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/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 collect = (iss, side) => {
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 (!collect(iss, "l"))
45534
+ if (!collect2(iss, "l"))
45535
45535
  result.issues.push(iss);
45536
45536
  }
45537
45537
  for (const iss of right.issues) {
45538
- if (!collect(iss, "r"))
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
- giver: external_exports.string().nullable(),
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
- giver: external_exports.string().nullable(),
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 RemoteGiverSchema = external_exports.object({ node: external_exports.string().min(1), sessionId: external_exports.string().min(1) });
61717
- var RelayJoinSchema = external_exports.object({ missionId: MissionIdSchema, giver: RemoteGiverSchema });
61718
- var RelayReplySchema = external_exports.object({ missionId: MissionIdSchema, text: external_exports.string().min(1), by: external_exports.string().min(1) });
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
- giver: RemoteGiverSchema
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
- giver: external_exports.string().nullable(),
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
- giver: external_exports.string().nullable(),
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: external_exports.array(external_exports.object({ name: external_exports.string().regex(NAME_SHAPE), summary: external_exports.string() })).default([]),
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
- }).default({ settings: null, args: [] }),
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 { appendFileSync, existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync3 } from "node:fs";
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 statSync(full).isDirectory() ? walk(full) : [full];
83358
+ return statSync2(full).isDirectory() ? walk(full) : [full];
83150
83359
  });
83151
83360
  return {
83152
83361
  kinds: ["history"],
83153
83362
  async list() {
83154
- if (!existsSync4(dir)) return null;
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 existsSync4(full) ? { path: file2, contentBase64: readFileSync4(full).toString("base64") } : null;
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
- appendFileSync(path7.join(this.recordDir(sessionId), RUNNER_LOG), `${JSON.stringify({ sequence, ...event })}
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 file2 = path7.join(this.sessionsDir, sessionId, RUNNER_LOG);
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
- async function keychain() {
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.3",
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
- ".": "./src/index.ts",
15
- "./protocol": "./src/protocol/index.ts",
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
- "giver": {
570
- "type": [
571
- "string",
572
- "null"
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
- "giver",
615
+ "receivers",
615
616
  "sessionId",
616
617
  "lead",
617
618
  "question",