@zixt/host 0.0.13 → 0.0.15
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 +144 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { homedir } from "node:os";
|
|
|
31
31
|
// package.json
|
|
32
32
|
var package_default = {
|
|
33
33
|
name: "@zixt/host",
|
|
34
|
-
version: "0.0.
|
|
34
|
+
version: "0.0.15",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -14872,6 +14872,16 @@ var MemberApprovalRequestContext = ApprovalRequestContext.extend({
|
|
|
14872
14872
|
}),
|
|
14873
14873
|
acting: ApprovalRequestContext.shape.acting.extend({ providerPrincipal: external_exports.null() })
|
|
14874
14874
|
});
|
|
14875
|
+
var QuestionChoice = external_exports.object({
|
|
14876
|
+
label: external_exports.string().trim().min(1).max(120),
|
|
14877
|
+
description: external_exports.string().trim().min(1).max(500).optional()
|
|
14878
|
+
}).strict();
|
|
14879
|
+
var QuestionChoices = external_exports.array(QuestionChoice).min(2).max(5).superRefine((choices, ctx) => {
|
|
14880
|
+
const labels = choices.map(({ label }) => label.toLocaleLowerCase());
|
|
14881
|
+
if (new Set(labels).size !== labels.length) {
|
|
14882
|
+
ctx.addIssue({ code: "custom", message: "question choice labels must be unique" });
|
|
14883
|
+
}
|
|
14884
|
+
});
|
|
14875
14885
|
var Approval = external_exports.object({
|
|
14876
14886
|
id: ApprovalId,
|
|
14877
14887
|
orgId: OrgId,
|
|
@@ -14882,6 +14892,8 @@ var Approval = external_exports.object({
|
|
|
14882
14892
|
summary: external_exports.string().min(1).max(500),
|
|
14883
14893
|
/** The concrete action payload, rendered verbatim for review (GR-3). */
|
|
14884
14894
|
payload: external_exports.string().max(5e4),
|
|
14895
|
+
/** Present only when ask_user supplied a bounded multiple-choice question. */
|
|
14896
|
+
questionChoices: QuestionChoices.optional(),
|
|
14885
14897
|
status: ApprovalStatus,
|
|
14886
14898
|
deliveryStatus: ApprovalDeliveryStatus,
|
|
14887
14899
|
/** Why delivery became impossible; null while pending or after delivery. */
|
|
@@ -15334,13 +15346,19 @@ var CreateOrgRequest = external_exports.object({
|
|
|
15334
15346
|
});
|
|
15335
15347
|
var DESKTOP_SIDEBAR_MIN_WIDTH_PX = 240;
|
|
15336
15348
|
var DESKTOP_SIDEBAR_MAX_WIDTH_PX = 420;
|
|
15349
|
+
var TASK_SIDEBAR_MIN_WIDTH_PX = 240;
|
|
15350
|
+
var TASK_SIDEBAR_MAX_WIDTH_PX = 480;
|
|
15337
15351
|
var DesktopSidebarPreference = external_exports.object({
|
|
15338
15352
|
collapsed: external_exports.boolean(),
|
|
15339
15353
|
/** Last expanded width; collapsing never discards the user's chosen width. */
|
|
15340
15354
|
expandedWidthPx: external_exports.number().int().min(DESKTOP_SIDEBAR_MIN_WIDTH_PX).max(DESKTOP_SIDEBAR_MAX_WIDTH_PX)
|
|
15341
15355
|
});
|
|
15356
|
+
var TaskSidebarPreference = external_exports.object({
|
|
15357
|
+
expandedWidthPx: external_exports.number().int().min(TASK_SIDEBAR_MIN_WIDTH_PX).max(TASK_SIDEBAR_MAX_WIDTH_PX)
|
|
15358
|
+
});
|
|
15342
15359
|
var OrgUiPreferences = external_exports.object({
|
|
15343
15360
|
desktopSidebar: DesktopSidebarPreference,
|
|
15361
|
+
taskSidebar: TaskSidebarPreference,
|
|
15344
15362
|
/** Missing legacy storage is revision zero. */
|
|
15345
15363
|
revision: external_exports.number().int().min(0),
|
|
15346
15364
|
updatedAt: IsoDate2.nullable()
|
|
@@ -15349,9 +15367,16 @@ var DesktopSidebarPreferencePatch = DesktopSidebarPreference.partial().refine(
|
|
|
15349
15367
|
(value) => Object.keys(value).length > 0,
|
|
15350
15368
|
"empty desktop sidebar update"
|
|
15351
15369
|
);
|
|
15370
|
+
var TaskSidebarPreferencePatch = TaskSidebarPreference.partial().refine(
|
|
15371
|
+
(value) => Object.keys(value).length > 0,
|
|
15372
|
+
"empty task sidebar update"
|
|
15373
|
+
);
|
|
15352
15374
|
var UpdateOrgUiPreferencesRequest = external_exports.object({
|
|
15353
15375
|
expectedRevision: external_exports.number().int().min(0),
|
|
15354
|
-
desktopSidebar: DesktopSidebarPreferencePatch
|
|
15376
|
+
desktopSidebar: DesktopSidebarPreferencePatch.optional(),
|
|
15377
|
+
taskSidebar: TaskSidebarPreferencePatch.optional()
|
|
15378
|
+
}).refine((value) => value.desktopSidebar !== void 0 || value.taskSidebar !== void 0, {
|
|
15379
|
+
message: "at least one layout preference is required"
|
|
15355
15380
|
});
|
|
15356
15381
|
var ListOrgsResponse = external_exports.object({
|
|
15357
15382
|
orgs: external_exports.array(Org.extend({ role: OrgRole, uiPreferences: OrgUiPreferences }))
|
|
@@ -15884,7 +15909,34 @@ var MemberTaskOriginProjection = TaskOrigin.pick({
|
|
|
15884
15909
|
var MemberTaskCancellationProjection = TaskCancellation.omit({ hostId: true }).extend({
|
|
15885
15910
|
hostId: external_exports.null()
|
|
15886
15911
|
});
|
|
15887
|
-
var
|
|
15912
|
+
var taskGitSummaryLabel = (maxLength, label) => external_exports.string().min(1).max(maxLength).refine(
|
|
15913
|
+
isSafeSingleLineDisplayText,
|
|
15914
|
+
`${label} must not contain control, line-separator, or bidirectional formatting characters`
|
|
15915
|
+
);
|
|
15916
|
+
var TaskGitSummary = external_exports.object({
|
|
15917
|
+
repositories: external_exports.array(
|
|
15918
|
+
external_exports.object({
|
|
15919
|
+
githubRepository: external_exports.string().regex(/^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/).optional(),
|
|
15920
|
+
branch: taskGitSummaryLabel(512, "branch").nullable(),
|
|
15921
|
+
ahead: external_exports.number().int().min(0),
|
|
15922
|
+
behind: external_exports.number().int().min(0),
|
|
15923
|
+
changedFiles: external_exports.number().int().min(0),
|
|
15924
|
+
pullRequest: external_exports.object({
|
|
15925
|
+
number: external_exports.number().int().min(1),
|
|
15926
|
+
url: external_exports.string().max(2e3).regex(
|
|
15927
|
+
/^https:\/\/github\.com\/[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}\/pull\/[1-9][0-9]*$/
|
|
15928
|
+
),
|
|
15929
|
+
state: external_exports.enum(["open", "closed", "merged"]),
|
|
15930
|
+
draft: external_exports.boolean()
|
|
15931
|
+
}).strict().optional()
|
|
15932
|
+
}).strict()
|
|
15933
|
+
).min(1).max(20),
|
|
15934
|
+
observedAt: IsoDate
|
|
15935
|
+
}).strict();
|
|
15936
|
+
var AdminTaskProjection = Task.extend({
|
|
15937
|
+
metadataRedacted: external_exports.literal(false),
|
|
15938
|
+
gitSummary: TaskGitSummary.nullable().optional()
|
|
15939
|
+
});
|
|
15888
15940
|
var MemberTaskProjection = Task.omit({
|
|
15889
15941
|
origin: true,
|
|
15890
15942
|
hostId: true,
|
|
@@ -15893,7 +15945,8 @@ var MemberTaskProjection = Task.omit({
|
|
|
15893
15945
|
metadataRedacted: external_exports.literal(true),
|
|
15894
15946
|
origin: MemberTaskOriginProjection,
|
|
15895
15947
|
hostId: external_exports.null(),
|
|
15896
|
-
cancellation: MemberTaskCancellationProjection.nullable().default(null)
|
|
15948
|
+
cancellation: MemberTaskCancellationProjection.nullable().default(null),
|
|
15949
|
+
gitSummary: external_exports.null().optional()
|
|
15897
15950
|
});
|
|
15898
15951
|
var TaskProjection = external_exports.discriminatedUnion("metadataRedacted", [
|
|
15899
15952
|
AdminTaskProjection,
|
|
@@ -18414,7 +18467,9 @@ var ApprovalRequest = external_exports.object({
|
|
|
18414
18467
|
category: external_exports.string(),
|
|
18415
18468
|
summary: external_exports.string().min(1).max(500),
|
|
18416
18469
|
/** Concrete action payload rendered verbatim on the approval card (GR-3). */
|
|
18417
|
-
payload: external_exports.string().max(5e4)
|
|
18470
|
+
payload: external_exports.string().max(5e4),
|
|
18471
|
+
/** Optional structured answers for agent.question; absent means free text. */
|
|
18472
|
+
questionChoices: QuestionChoices.optional()
|
|
18418
18473
|
});
|
|
18419
18474
|
var JournalAppend = external_exports.object({
|
|
18420
18475
|
type: external_exports.literal("journal.append"),
|
|
@@ -20524,7 +20579,7 @@ var HostClient = class _HostClient {
|
|
|
20524
20579
|
const { provider: _provider, ...legacyGrant } = grant;
|
|
20525
20580
|
return legacyGrant;
|
|
20526
20581
|
};
|
|
20527
|
-
const requestApproval = (category, summary, payload) => {
|
|
20582
|
+
const requestApproval = (category, summary, payload, questionChoices) => {
|
|
20528
20583
|
if (authorityController.signal.aborted) {
|
|
20529
20584
|
return Promise.resolve({ approved: false, guidance: "task was cancelled" });
|
|
20530
20585
|
}
|
|
@@ -20536,7 +20591,8 @@ var HostClient = class _HostClient {
|
|
|
20536
20591
|
requestId,
|
|
20537
20592
|
category: safe(category, 200),
|
|
20538
20593
|
summary: safe(summary, 500),
|
|
20539
|
-
payload: safe(payload, 5e4)
|
|
20594
|
+
payload: safe(payload, 5e4),
|
|
20595
|
+
...questionChoices ? { questionChoices: [...questionChoices] } : {}
|
|
20540
20596
|
});
|
|
20541
20597
|
return new Promise((resolve13) => {
|
|
20542
20598
|
const waiters = this.approvalWaiters.get(cancelKey) ?? /* @__PURE__ */ new Map();
|
|
@@ -30668,7 +30724,7 @@ var CADENCE_PROPS = {
|
|
|
30668
30724
|
var TOOLS = [
|
|
30669
30725
|
{
|
|
30670
30726
|
name: "ask_user",
|
|
30671
|
-
description: "Ask the human supervising this task a question and wait for their answer. Use it whenever you need a decision, missing context, or plan approval before proceeding. The answer arrives as text.",
|
|
30727
|
+
description: "Ask the human supervising this task a question and wait for their answer. Use it whenever you need a decision, missing context, or plan approval before proceeding. When there are 2-5 concrete alternatives, provide them as choices; the person can still enter another answer. The answer arrives as text.",
|
|
30672
30728
|
inputSchema: {
|
|
30673
30729
|
type: "object",
|
|
30674
30730
|
properties: {
|
|
@@ -30676,9 +30732,35 @@ var TOOLS = [
|
|
|
30676
30732
|
context: {
|
|
30677
30733
|
type: "string",
|
|
30678
30734
|
description: "Optional supporting detail shown alongside the question."
|
|
30735
|
+
},
|
|
30736
|
+
choices: {
|
|
30737
|
+
type: "array",
|
|
30738
|
+
minItems: 2,
|
|
30739
|
+
maxItems: 5,
|
|
30740
|
+
description: "Optional concrete answers. Omit when the person should type freely.",
|
|
30741
|
+
items: {
|
|
30742
|
+
type: "object",
|
|
30743
|
+
properties: {
|
|
30744
|
+
label: {
|
|
30745
|
+
type: "string",
|
|
30746
|
+
minLength: 1,
|
|
30747
|
+
maxLength: 120,
|
|
30748
|
+
description: "Short answer label."
|
|
30749
|
+
},
|
|
30750
|
+
description: {
|
|
30751
|
+
type: "string",
|
|
30752
|
+
minLength: 1,
|
|
30753
|
+
maxLength: 500,
|
|
30754
|
+
description: "Optional consequence or detail that helps the person choose."
|
|
30755
|
+
}
|
|
30756
|
+
},
|
|
30757
|
+
required: ["label"],
|
|
30758
|
+
additionalProperties: false
|
|
30759
|
+
}
|
|
30679
30760
|
}
|
|
30680
30761
|
},
|
|
30681
|
-
required: ["question"]
|
|
30762
|
+
required: ["question"],
|
|
30763
|
+
additionalProperties: false
|
|
30682
30764
|
}
|
|
30683
30765
|
},
|
|
30684
30766
|
{
|
|
@@ -31201,7 +31283,22 @@ function createAskUserServer() {
|
|
|
31201
31283
|
}
|
|
31202
31284
|
try {
|
|
31203
31285
|
const context = typeof args["context"] === "string" ? args["context"] : "";
|
|
31204
|
-
|
|
31286
|
+
const rawChoices = args["choices"];
|
|
31287
|
+
const parsedChoices = rawChoices === void 0 ? void 0 : QuestionChoices.safeParse(rawChoices);
|
|
31288
|
+
if (parsedChoices && !parsedChoices.success) {
|
|
31289
|
+
toolText(
|
|
31290
|
+
"Choices must contain 2-5 unique, non-empty labels with optional descriptions.",
|
|
31291
|
+
true
|
|
31292
|
+
);
|
|
31293
|
+
return;
|
|
31294
|
+
}
|
|
31295
|
+
toolText(
|
|
31296
|
+
await handlers.askUser(
|
|
31297
|
+
question,
|
|
31298
|
+
context,
|
|
31299
|
+
parsedChoices?.success ? parsedChoices.data : void 0
|
|
31300
|
+
)
|
|
31301
|
+
);
|
|
31205
31302
|
} catch (err) {
|
|
31206
31303
|
toolText(`The question could not be delivered: ${String(err)}`, true);
|
|
31207
31304
|
}
|
|
@@ -33267,12 +33364,8 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
33267
33364
|
try {
|
|
33268
33365
|
cwd = await requireRealDirectory4(configuredWorkspace, "configured workspace");
|
|
33269
33366
|
} catch (error52) {
|
|
33270
|
-
|
|
33271
|
-
|
|
33272
|
-
summary: error52 instanceof Error ? error52.message : "configured workspace is unusable",
|
|
33273
|
-
summaryEvidence: "host_observed",
|
|
33274
|
-
usage: { inputTokens: 0, outputTokens: 0 }
|
|
33275
|
-
};
|
|
33367
|
+
const reason = error52 instanceof Error ? error52.message : "configured workspace is unusable";
|
|
33368
|
+
task.event("status", `${reason}. Continuing in the teammate folder instead.`);
|
|
33276
33369
|
}
|
|
33277
33370
|
}
|
|
33278
33371
|
if (task.cancelledNow()) return cancelledBeforeRun();
|
|
@@ -33391,13 +33484,14 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
33391
33484
|
throw new Error("prepared provider workspace does not match the task assignment");
|
|
33392
33485
|
}
|
|
33393
33486
|
askUserServer.register(runToken, {
|
|
33394
|
-
askUser: async (question, context) => {
|
|
33487
|
+
askUser: async (question, context, choices) => {
|
|
33395
33488
|
pendingAsks++;
|
|
33396
33489
|
try {
|
|
33397
33490
|
const decision = await task.requestApproval(
|
|
33398
33491
|
"agent.question",
|
|
33399
33492
|
question.slice(0, 500),
|
|
33400
|
-
(context || question).slice(0, MAX_APPROVAL_PAYLOAD)
|
|
33493
|
+
(context || question).slice(0, MAX_APPROVAL_PAYLOAD),
|
|
33494
|
+
choices
|
|
33401
33495
|
);
|
|
33402
33496
|
return decision.guidance ?? (decision.approved ? "Approved. Proceed." : "No. Do not proceed.");
|
|
33403
33497
|
} finally {
|
|
@@ -33426,6 +33520,18 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
33426
33520
|
];
|
|
33427
33521
|
})
|
|
33428
33522
|
});
|
|
33523
|
+
const workingContextEnvironments = buildWorkingContextCommandEnvironments({
|
|
33524
|
+
inherited: process.env,
|
|
33525
|
+
runnerEnv: env,
|
|
33526
|
+
...githubShell ? { githubShellBrokerEnv: githubShell.environment } : {}
|
|
33527
|
+
});
|
|
33528
|
+
const gitDetected = preparedWorkspace !== null || await collectWorkingContext({
|
|
33529
|
+
workingDirectory: cwd,
|
|
33530
|
+
preparedWorkspace,
|
|
33531
|
+
git,
|
|
33532
|
+
env: workingContextEnvironments.git,
|
|
33533
|
+
signal: task.authoritySignal
|
|
33534
|
+
}).then((context) => Boolean(context.repositories?.length)).catch(() => false);
|
|
33429
33535
|
const prepared = await adapter.prepareRun({
|
|
33430
33536
|
task,
|
|
33431
33537
|
runner,
|
|
@@ -33436,6 +33542,7 @@ function createCliRunner(adapter, opts = {}) {
|
|
|
33436
33542
|
connections: attachedConnections
|
|
33437
33543
|
},
|
|
33438
33544
|
preparedWorkspace,
|
|
33545
|
+
gitDetected,
|
|
33439
33546
|
// The trusted workspace facts describe where Zixt put provider clones,
|
|
33440
33547
|
// which is always the Zixt-owned root — never a configured workspace.
|
|
33441
33548
|
taskRoot,
|
|
@@ -33467,11 +33574,6 @@ ${attachmentSection}` : prepared.prompt;
|
|
|
33467
33574
|
const abortWorkingContext = () => workingContextAbort.abort();
|
|
33468
33575
|
task.authoritySignal.addEventListener("abort", abortWorkingContext, { once: true });
|
|
33469
33576
|
const pullRequests = new WorkingContextPullRequestCache();
|
|
33470
|
-
const workingContextEnvironments = buildWorkingContextCommandEnvironments({
|
|
33471
|
-
inherited: process.env,
|
|
33472
|
-
runnerEnv: env,
|
|
33473
|
-
...githubShell ? { githubShellBrokerEnv: githubShell.environment } : {}
|
|
33474
|
-
});
|
|
33475
33577
|
const ghContextCommand = githubShell?.ghCommand ? { ...githubShell.ghCommand, env: workingContextEnvironments.github } : void 0;
|
|
33476
33578
|
const gitContextCommand = git.available && git.executablePath ? { executablePath: git.executablePath, env: workingContextEnvironments.git } : void 0;
|
|
33477
33579
|
const reportWorkingContext = (options = {}) => {
|
|
@@ -33778,6 +33880,20 @@ function workspaceSystemPrompt(existing, workspacePath, siblings, gitDetected =
|
|
|
33778
33880
|
"",
|
|
33779
33881
|
"Your session ends the moment you finish a reply, and nothing wakes it: no background notification, watcher, or timer will ever re-invoke you. Run long commands (test gates, builds) synchronously and wait for their result inside the tool call. Never end a reply with work still in flight or a promise to report later: whatever you were waiting for dies with the turn. Your final reply is the report of record, written only when the work is actually complete."
|
|
33780
33882
|
];
|
|
33883
|
+
if (gitDetected) {
|
|
33884
|
+
lines.push(
|
|
33885
|
+
"",
|
|
33886
|
+
"# Finishing work in Git",
|
|
33887
|
+
"",
|
|
33888
|
+
"This folder is positively detected as a Git repository. Use installed `git` for local source control and, when the remote is GitHub, installed `gh` for pull requests, checks, and merges.",
|
|
33889
|
+
"",
|
|
33890
|
+
"Before editing, inspect the repository and call `list_tasks` to check whether another live Task overlaps this work. Never disturb another Task\u2019s checkout; use an isolated branch and worktree when work may be concurrent.",
|
|
33891
|
+
"",
|
|
33892
|
+
"Unless the human explicitly asked you to stop for review before merging, Git work is not complete merely because files, a branch, or a pull request exist. Update from the latest default branch, resolve ordinary conflicts yourself, run the relevant validation, commit, push, open or update the pull request when the repository uses them, wait for required checks, merge it, and verify the merged state. Clean up temporary worktrees after integration. Do not strand finished work on an unmerged branch.",
|
|
33893
|
+
"",
|
|
33894
|
+
"If repository policy, unavailable authority, an ambiguous product decision, or a conflict you cannot safely resolve prevents completion, use `ask_user` with the exact blocker and required decision. Do not report the Task as done while integration is still pending."
|
|
33895
|
+
);
|
|
33896
|
+
}
|
|
33781
33897
|
if (siblings.length > 0) {
|
|
33782
33898
|
const siblingData = promptDescriptiveJson(
|
|
33783
33899
|
siblings.slice(0, 100).map((sibling) => ({
|
|
@@ -34316,7 +34432,8 @@ var claudeCodeAdapter = {
|
|
|
34316
34432
|
input.mcp,
|
|
34317
34433
|
input.preparedWorkspace,
|
|
34318
34434
|
input.taskRoot,
|
|
34319
|
-
input.cwd
|
|
34435
|
+
input.cwd,
|
|
34436
|
+
input.gitDetected
|
|
34320
34437
|
);
|
|
34321
34438
|
const sessionId = input.task.spec.sessionKey ?? randomUUID11();
|
|
34322
34439
|
const observeRuntime = createRuntimeReporter(input, sessionId);
|
|
@@ -34367,7 +34484,7 @@ function delay2(ms) {
|
|
|
34367
34484
|
timer.unref?.();
|
|
34368
34485
|
});
|
|
34369
34486
|
}
|
|
34370
|
-
async function buildArgs(task, runner, artifacts, mcp, preparedWorkspace, taskRoot, workspacePath = taskRoot ?? "") {
|
|
34487
|
+
async function buildArgs(task, runner, artifacts, mcp, preparedWorkspace, taskRoot, workspacePath = taskRoot ?? "", gitDetected = false) {
|
|
34371
34488
|
const args = [
|
|
34372
34489
|
// Hermetic, non-interactive run — no local slash commands or global state.
|
|
34373
34490
|
"--disable-slash-commands",
|
|
@@ -34387,7 +34504,7 @@ async function buildArgs(task, runner, artifacts, mcp, preparedWorkspace, taskRo
|
|
|
34387
34504
|
trustedWorkspaceSystemPrompt(task.spec.system, preparedWorkspace, taskRoot),
|
|
34388
34505
|
workspacePath,
|
|
34389
34506
|
task.siblingTasks(),
|
|
34390
|
-
|
|
34507
|
+
gitDetected
|
|
34391
34508
|
);
|
|
34392
34509
|
if (systemPrompt) {
|
|
34393
34510
|
const promptPath = await artifacts.writeSystemPrompt(systemPrompt);
|
|
@@ -34641,7 +34758,7 @@ function createCodexAdapter(threadIndexRoot) {
|
|
|
34641
34758
|
trustedWorkspaceSystemPrompt(task.spec.system, input.preparedWorkspace, input.taskRoot),
|
|
34642
34759
|
input.cwd,
|
|
34643
34760
|
task.siblingTasks(),
|
|
34644
|
-
input.
|
|
34761
|
+
input.gitDetected
|
|
34645
34762
|
);
|
|
34646
34763
|
const prompt = platformInstructions ? `<zixt_platform_instructions>
|
|
34647
34764
|
${platformInstructions}
|