@gatherthread/dsh-host 0.1.0-alpha.8 → 0.1.0-beta.1

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.
@@ -1598,16 +1598,16 @@ function cleanEnum(obj) {
1598
1598
  }
1599
1599
  function base64ToUint8Array(base643) {
1600
1600
  const binaryString = atob(base643);
1601
- const bytes = new Uint8Array(binaryString.length);
1601
+ const bytes2 = new Uint8Array(binaryString.length);
1602
1602
  for (let i = 0; i < binaryString.length; i++) {
1603
- bytes[i] = binaryString.charCodeAt(i);
1603
+ bytes2[i] = binaryString.charCodeAt(i);
1604
1604
  }
1605
- return bytes;
1605
+ return bytes2;
1606
1606
  }
1607
- function uint8ArrayToBase64(bytes) {
1607
+ function uint8ArrayToBase64(bytes2) {
1608
1608
  let binaryString = "";
1609
- for (let i = 0; i < bytes.length; i++) {
1610
- binaryString += String.fromCharCode(bytes[i]);
1609
+ for (let i = 0; i < bytes2.length; i++) {
1610
+ binaryString += String.fromCharCode(bytes2[i]);
1611
1611
  }
1612
1612
  return btoa(binaryString);
1613
1613
  }
@@ -1616,22 +1616,22 @@ function base64urlToUint8Array(base64url3) {
1616
1616
  const padding = "=".repeat((4 - base643.length % 4) % 4);
1617
1617
  return base64ToUint8Array(base643 + padding);
1618
1618
  }
1619
- function uint8ArrayToBase64url(bytes) {
1620
- return uint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1619
+ function uint8ArrayToBase64url(bytes2) {
1620
+ return uint8ArrayToBase64(bytes2).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1621
1621
  }
1622
1622
  function hexToUint8Array(hex3) {
1623
1623
  const cleanHex = hex3.replace(/^0x/, "");
1624
1624
  if (cleanHex.length % 2 !== 0) {
1625
1625
  throw new Error("Invalid hex string length");
1626
1626
  }
1627
- const bytes = new Uint8Array(cleanHex.length / 2);
1627
+ const bytes2 = new Uint8Array(cleanHex.length / 2);
1628
1628
  for (let i = 0; i < cleanHex.length; i += 2) {
1629
- bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16);
1629
+ bytes2[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16);
1630
1630
  }
1631
- return bytes;
1631
+ return bytes2;
1632
1632
  }
1633
- function uint8ArrayToHex(bytes) {
1634
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1633
+ function uint8ArrayToHex(bytes2) {
1634
+ return Array.from(bytes2).map((b) => b.toString(16).padStart(2, "0")).join("");
1635
1635
  }
1636
1636
  var Class = class {
1637
1637
  constructor(..._args) {
@@ -20032,34 +20032,42 @@ function isCodeSyncPathAllowed(path5) {
20032
20032
  return !/\.(?:pem|p12|pfx|key)$/iu.test(lower) && !/^(?:id_rsa|id_ed25519)(?:\.|$)/iu.test(lower);
20033
20033
  });
20034
20034
  }
20035
- var CodeFileSchema = external_exports.object({
20036
- path: external_exports.string().refine(isCodeSyncPathAllowed, "Unsafe or private code path"),
20037
- content_base64: external_exports.string().max(4 * Math.ceil(CODE_SYNC_MAX_FILE_BYTES / 3)).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),
20038
- executable: external_exports.boolean()
20039
- }).strict();
20040
- var CodeFilesSchema = external_exports.array(CodeFileSchema).max(CODE_SYNC_MAX_FILES).superRefine((files, context) => {
20041
- let size = 0;
20042
- const names = /* @__PURE__ */ new Set();
20043
- for (const [index, file2] of files.entries()) {
20044
- const bytes = file2.content_base64.length * 3 / 4 - (file2.content_base64.endsWith("==") ? 2 : file2.content_base64.endsWith("=") ? 1 : 0);
20045
- size += bytes;
20046
- const normalized = portablePathKey(file2.path);
20047
- if (bytes > CODE_SYNC_MAX_FILE_BYTES || names.has(normalized))
20048
- context.addIssue({ code: "custom", path: [index], message: "File limit or duplicate portable path" });
20049
- names.add(normalized);
20050
- }
20051
- if (size > CODE_SYNC_MAX_SNAPSHOT_BYTES)
20052
- context.addIssue({ code: "custom", message: "Code snapshot exceeds 8 MiB" });
20053
- for (const name2 of names) {
20054
- const parts = name2.split("/");
20055
- parts.pop();
20056
- while (parts.length) {
20057
- if (names.has(parts.join("/")))
20058
- context.addIssue({ code: "custom", message: "File and directory paths overlap" });
20035
+ var CLOUD_CODE_SYNC_LIMITS = { maxFiles: CODE_SYNC_MAX_FILES, maxFileBytes: CODE_SYNC_MAX_FILE_BYTES, maxSnapshotBytes: CODE_SYNC_MAX_SNAPSHOT_BYTES };
20036
+ var GITHUB_CODE_SYNC_LIMITS = { maxFiles: 1e4, maxFileBytes: 20 * 1024 * 1024, maxSnapshotBytes: 128 * 1024 * 1024 };
20037
+ function createCodeFileSchema(limits) {
20038
+ return external_exports.object({
20039
+ path: external_exports.string().refine(isCodeSyncPathAllowed, "Unsafe or private code path"),
20040
+ content_base64: external_exports.string().max(4 * Math.ceil(limits.maxFileBytes / 3)).regex(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/),
20041
+ executable: external_exports.boolean()
20042
+ }).strict();
20043
+ }
20044
+ var CodeFileSchema = createCodeFileSchema(CLOUD_CODE_SYNC_LIMITS);
20045
+ function createCodeFilesSchema(limits) {
20046
+ return external_exports.array(createCodeFileSchema(limits)).max(limits.maxFiles).superRefine((files, context) => {
20047
+ let size = 0;
20048
+ const names = /* @__PURE__ */ new Set();
20049
+ for (const [index, file2] of files.entries()) {
20050
+ const bytes2 = file2.content_base64.length * 3 / 4 - (file2.content_base64.endsWith("==") ? 2 : file2.content_base64.endsWith("=") ? 1 : 0);
20051
+ size += bytes2;
20052
+ const normalized = portablePathKey(file2.path);
20053
+ if (bytes2 > limits.maxFileBytes || names.has(normalized))
20054
+ context.addIssue({ code: "custom", path: [index], message: "File limit or duplicate portable path" });
20055
+ names.add(normalized);
20056
+ }
20057
+ if (size > limits.maxSnapshotBytes)
20058
+ context.addIssue({ code: "custom", message: "Code snapshot exceeds provider limit" });
20059
+ for (const name2 of names) {
20060
+ const parts = name2.split("/");
20059
20061
  parts.pop();
20062
+ while (parts.length) {
20063
+ if (names.has(parts.join("/")))
20064
+ context.addIssue({ code: "custom", message: "File and directory paths overlap" });
20065
+ parts.pop();
20066
+ }
20060
20067
  }
20061
- }
20062
- });
20068
+ });
20069
+ }
20070
+ var CodeFilesSchema = createCodeFilesSchema(CLOUD_CODE_SYNC_LIMITS);
20063
20071
  var CodeEnableInputSchema = external_exports.object({ idempotency_key: Key }).strict();
20064
20072
  var CodeDisableInputSchema = external_exports.object({ idempotency_key: Key }).strict();
20065
20073
  var CodeCheckpointInputSchema = external_exports.object({
@@ -20121,6 +20129,47 @@ var CodeSnapshotResultSchema = external_exports.object({ snapshot: external_expo
20121
20129
  }).strict() }).strict();
20122
20130
  var codeSyncRequestKinds = ["code_sync_status", "code_upload", "code_download", "code_recover", "code_auto_upload_enable", "code_auto_upload_disable"];
20123
20131
 
20132
+ // ../protocol/dist/src/github-sync.js
20133
+ var GitHubRepositorySchema = external_exports.string().max(140).regex(/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?\/[A-Za-z0-9_.-]{1,100}$/).refine((value) => {
20134
+ const repository = value.split("/")[1];
20135
+ return repository !== "." && repository !== ".." && !repository.toLowerCase().endsWith(".git");
20136
+ }, "Use owner/repository without a .git suffix");
20137
+ function isGitHubBranchAllowed(value) {
20138
+ return value.length > 0 && value.length <= 200 && /^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value) && !value.includes("..") && value.split("/").every((part) => !!part && !part.startsWith(".") && !part.endsWith(".") && !part.toLowerCase().endsWith(".lock")) && value !== "HEAD";
20139
+ }
20140
+ var GitHubBranchSchema = external_exports.string().refine(isGitHubBranchAllowed, "Unsafe GitHub branch name");
20141
+ var GitHubBaseBranchSchema = GitHubBranchSchema.refine((value) => !value.startsWith("gatherthread/"), "The shared base cannot use the GatherThread personal branch namespace");
20142
+ var GitHubPersonalBranchSchema = external_exports.string().regex(/^gatherthread\/[a-f0-9]{24}\/[a-f0-9]{24}$/);
20143
+ var GitHubConnectionSchema = external_exports.object({
20144
+ repository: GitHubRepositorySchema,
20145
+ base_branch: GitHubBaseBranchSchema,
20146
+ enabled: external_exports.boolean(),
20147
+ revision: external_exports.string().uuid()
20148
+ }).strict();
20149
+ var GitHubProjectStatusSchema = external_exports.object({
20150
+ connection: GitHubConnectionSchema.nullable(),
20151
+ branch: GitHubPersonalBranchSchema,
20152
+ can_configure: external_exports.boolean(),
20153
+ // GatherThread membership only. GitHub permissions must be checked locally.
20154
+ can_write: external_exports.boolean()
20155
+ }).strict();
20156
+ var GitHubConnectionInputSchema = external_exports.object({
20157
+ repository: GitHubRepositorySchema,
20158
+ base_branch: GitHubBaseBranchSchema,
20159
+ enabled: external_exports.boolean(),
20160
+ expected_revision: external_exports.string().uuid().nullable()
20161
+ }).strict();
20162
+ var githubCodeSyncRequestKinds = [
20163
+ "github_auth_connect",
20164
+ "github_code_sync_status",
20165
+ "github_code_upload",
20166
+ "github_code_download",
20167
+ "github_code_recover",
20168
+ "github_code_auto_upload_enable",
20169
+ "github_code_auto_upload_disable",
20170
+ "github_code_update"
20171
+ ];
20172
+
20124
20173
  // ../protocol/dist/src/history-summary.js
20125
20174
  var HISTORY_SUMMARY_MAX_SOURCE_BYTES = 20 * 1024;
20126
20175
  var HISTORY_SUMMARY_MAX_PROMPT_BYTES = 30 * 1024;
@@ -20145,6 +20194,155 @@ function historySummaryMarker(event) {
20145
20194
  return { version: 1, source_event_ids: ids, source_digest: marker.source_digest };
20146
20195
  }
20147
20196
 
20197
+ // ../protocol/dist/src/test-gate.js
20198
+ var TestGateExchangeInputSchema = external_exports.object({
20199
+ admission_code: external_exports.string().regex(/^gte_[A-Za-z0-9_-]{43}$/)
20200
+ }).strict();
20201
+ var TestGateStatusSchema = external_exports.object({
20202
+ enabled: external_exports.boolean(),
20203
+ admitted: external_exports.boolean(),
20204
+ environment: external_exports.enum(["production", "test"])
20205
+ }).strict();
20206
+
20207
+ // ../protocol/dist/src/hosted-github.js
20208
+ var Key2 = external_exports.string().min(8).max(200);
20209
+ var HostedGithubRepositoryInputSchema = external_exports.object({
20210
+ repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u).max(140),
20211
+ base_branch: external_exports.string().min(1).max(200).refine((v) => !/[\s~^:?*\[\\]/u.test(v) && !v.includes("..") && !v.startsWith("-") && !v.endsWith("/") && !v.endsWith(".lock"))
20212
+ }).strict();
20213
+ var HostedGithubTaskInputSchema = external_exports.object({
20214
+ content: external_exports.string().trim().min(1).max(6e3),
20215
+ profile_id: external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/u),
20216
+ idempotency_key: Key2,
20217
+ continue_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional(),
20218
+ reply_to_event_id: external_exports.string().min(1).max(128).nullable().optional()
20219
+ }).strict();
20220
+ var HostedGithubCompleteInputSchema = external_exports.object({
20221
+ state: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/u),
20222
+ code: external_exports.string().min(1).max(500)
20223
+ }).strict();
20224
+ var HostedGithubPrInputSchema = external_exports.object({
20225
+ title: external_exports.string().trim().min(1).max(200),
20226
+ body: external_exports.string().max(6e3),
20227
+ expected_revision: external_exports.string().regex(/^[a-f0-9]{64}$/u)
20228
+ }).strict();
20229
+ var Login = external_exports.string().regex(/^[A-Za-z0-9-]{1,39}$/u);
20230
+ var TaskId = external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u);
20231
+ var Sha = external_exports.string().regex(/^[a-f0-9]{40}$/u).nullable();
20232
+ var Revision = external_exports.string().regex(/^[a-f0-9]{64}$/u).nullable();
20233
+ var PullUrl = external_exports.string().max(2048).regex(/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/[1-9][0-9]*$/u).nullable();
20234
+ var HostedGithubBindingSchema = HostedGithubRepositoryInputSchema;
20235
+ var HostedGithubStatusSchema = external_exports.union([
20236
+ external_exports.object({ enabled: external_exports.literal(false) }).strict(),
20237
+ external_exports.object({
20238
+ enabled: external_exports.literal(true),
20239
+ connected: external_exports.boolean(),
20240
+ login: Login.nullable(),
20241
+ binding: HostedGithubBindingSchema.nullable(),
20242
+ installation_url: external_exports.string().max(2048).regex(/^https:\/\/github\.com\/apps\/[A-Za-z0-9_.-]+\/installations\/new$/u)
20243
+ }).strict().refine((v) => v.connected ? v.login !== null : v.login === null && v.binding === null)
20244
+ ]);
20245
+ var HostedGithubAuthorizationSchema = external_exports.object({ authorization_url: external_exports.string().max(4096).refine((value) => {
20246
+ try {
20247
+ const url2 = new URL(value);
20248
+ return url2.origin === "https://github.com" && url2.pathname === "/login/oauth/authorize" && !url2.username && !url2.password && !url2.hash && /^[A-Za-z0-9_-]{43}$/u.test(url2.searchParams.get("state") ?? "") && [...url2.searchParams.keys()].every((key) => ["client_id", "redirect_uri", "state", "code_challenge", "code_challenge_method", "prompt"].includes(key));
20249
+ } catch {
20250
+ return false;
20251
+ }
20252
+ }) }).strict();
20253
+ var HostedGithubConnectionSchema = external_exports.object({ connected: external_exports.literal(true), login: Login }).strict();
20254
+ var HostedGithubDisconnectionSchema = external_exports.object({ connected: external_exports.literal(false) }).strict();
20255
+ var HostedGithubTaskSummarySchema = external_exports.object({
20256
+ id: TaskId,
20257
+ session_id: external_exports.string().min(1).max(128),
20258
+ profile_id: HostedGithubTaskInputSchema.shape.profile_id,
20259
+ resumable: external_exports.boolean(),
20260
+ state: external_exports.enum(["running", "completed", "failed", "interrupted"]),
20261
+ repository: HostedGithubRepositoryInputSchema.shape.repository,
20262
+ base_branch: HostedGithubRepositoryInputSchema.shape.base_branch,
20263
+ base_sha: Sha,
20264
+ revision: Revision,
20265
+ error_code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/u).nullable(),
20266
+ pull_request_url: PullUrl,
20267
+ expires_at: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER)
20268
+ }).strict();
20269
+ var bytes = (value) => value.length / 4 * 3 - (value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0);
20270
+ var Source = external_exports.string().max(2796204).regex(/^[A-Za-z0-9+/]*={0,2}$/u).refine((value) => value.length % 4 === 0 && bytes(value) <= 2 * 1024 * 1024).nullable();
20271
+ var HostedGithubChangeSchema = external_exports.object({
20272
+ path: external_exports.string().max(4096).refine(isCodeSyncPathAllowed),
20273
+ before_base64: Source,
20274
+ after_base64: Source,
20275
+ before_executable: external_exports.boolean().nullable(),
20276
+ after_executable: external_exports.boolean().nullable()
20277
+ }).strict().refine((v) => v.before_base64 === null === (v.before_executable === null) && v.after_base64 === null === (v.after_executable === null) && (v.before_base64 !== null || v.after_base64 !== null));
20278
+ var HostedGithubTaskSchema = HostedGithubTaskSummarySchema.extend({
20279
+ answer: external_exports.string().max(14e3).nullable(),
20280
+ changes: external_exports.array(HostedGithubChangeSchema).max(2e3)
20281
+ }).strict().refine((v) => {
20282
+ if (new Set(v.changes.map((c) => c.path)).size !== v.changes.length)
20283
+ return false;
20284
+ for (const side of ["before_base64", "after_base64"]) {
20285
+ const values = v.changes.map((c) => c[side]).filter((s) => s !== null);
20286
+ if (values.length > 1e3 || values.reduce((sum, s) => sum + bytes(s), 0) > 8 * 1024 * 1024)
20287
+ return false;
20288
+ }
20289
+ return !v.resumable || v.state !== "running" && v.pull_request_url === null;
20290
+ });
20291
+ var HostedGithubTaskListSchema = external_exports.object({ tasks: external_exports.array(HostedGithubTaskSummarySchema).max(10) }).strict();
20292
+
20293
+ // ../protocol/dist/src/registration.js
20294
+ var RegistrationEmailSchema = external_exports.string().max(254).trim().toLowerCase().regex(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/).refine((value) => value.split("@")[0].length <= 64 && value.split("@")[1].split(".").every((part) => part.length <= 63));
20295
+ var Label = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u).trim().min(1).max(120);
20296
+ var SendRegistrationInputSchema = external_exports.object({
20297
+ email: RegistrationEmailSchema,
20298
+ challenge_token: external_exports.string().min(1).max(2048),
20299
+ idempotency_key: external_exports.string().uuid(),
20300
+ locale: external_exports.enum(["en", "zh-CN"])
20301
+ }).strict();
20302
+ var AccountPasswordSchema = external_exports.string().min(12).max(128).refine((value) => new TextEncoder().encode(value).byteLength <= 512);
20303
+ var EmailLoginInputSchema = external_exports.object({
20304
+ email: RegistrationEmailSchema,
20305
+ password: AccountPasswordSchema,
20306
+ device_name: Label,
20307
+ remember_device: external_exports.boolean().default(false)
20308
+ }).strict();
20309
+ var VerifyRegistrationInputSchema = external_exports.object({
20310
+ registration_id: external_exports.string().uuid(),
20311
+ code: external_exports.string().regex(/^\d{8}$/),
20312
+ display_name: Label,
20313
+ device_name: Label,
20314
+ remember_device: external_exports.boolean().default(false),
20315
+ privacy_acknowledged: external_exports.literal(true),
20316
+ password: AccountPasswordSchema
20317
+ }).strict();
20318
+ var RegistrationStatusSchema = external_exports.object({
20319
+ enabled: external_exports.boolean(),
20320
+ site_key: external_exports.string().nullable(),
20321
+ challenge_binding: external_exports.string().nullable()
20322
+ }).strict();
20323
+ var RegistrationSentSchema = external_exports.object({
20324
+ registration_id: external_exports.string().uuid(),
20325
+ expires_in_seconds: external_exports.literal(600),
20326
+ resend_after_seconds: external_exports.literal(60)
20327
+ }).strict();
20328
+ var PasswordResetSentSchema = external_exports.object({
20329
+ reset_id: external_exports.string().uuid(),
20330
+ expires_in_seconds: external_exports.literal(600),
20331
+ resend_after_seconds: external_exports.literal(60)
20332
+ }).strict();
20333
+ var VerifyPasswordResetInputSchema = external_exports.object({
20334
+ reset_id: external_exports.string().uuid(),
20335
+ email: RegistrationEmailSchema,
20336
+ code: external_exports.string().regex(/^\d{8}$/),
20337
+ password: AccountPasswordSchema,
20338
+ password_confirmation: AccountPasswordSchema,
20339
+ locale: external_exports.enum(["en", "zh-CN"])
20340
+ }).strict().refine((value) => value.password === value.password_confirmation);
20341
+ var EmailAccountSessionSchema = external_exports.object({
20342
+ actor: external_exports.object({ user_id: external_exports.string(), display_name: external_exports.string(), device_id: external_exports.string(), can_create_projects: external_exports.literal(true) }).strict(),
20343
+ expires_at: external_exports.string().datetime()
20344
+ }).strict();
20345
+
20148
20346
  // ../protocol/dist/src/index.js
20149
20347
  var sessionModes = ["solo", "multi"];
20150
20348
  var membershipRoles = ["owner", "participant", "viewer"];
@@ -20289,6 +20487,43 @@ var AppendEventInputSchema = external_exports.object({
20289
20487
  observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
20290
20488
  observed_reasoning_effort: external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional()
20291
20489
  });
20490
+ var HostedAgentRequestInputSchema = external_exports.object({
20491
+ profile_id: external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/u).default("default"),
20492
+ content: external_exports.string().trim().min(1).max(6e3),
20493
+ include_code: external_exports.boolean().default(false),
20494
+ idempotency_key: IdempotencyKeySchema,
20495
+ reply_to_event_id: IdSchema.nullable().optional(),
20496
+ github_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional()
20497
+ }).strict();
20498
+ var HostedAgentStatusSchema = external_exports.discriminatedUnion("enabled", [
20499
+ external_exports.object({ enabled: external_exports.literal(false) }).strict(),
20500
+ external_exports.object({
20501
+ enabled: external_exports.literal(true),
20502
+ harness: external_exports.literal("opencode"),
20503
+ utc_day: external_exports.string(),
20504
+ user_limit_runs: external_exports.number().int().nonnegative().nullable(),
20505
+ user_used_runs: external_exports.number().int().nonnegative(),
20506
+ global_limit_runs: external_exports.number().int().nonnegative().nullable(),
20507
+ global_used_runs: external_exports.number().int().nonnegative(),
20508
+ rate_limits: external_exports.object({
20509
+ user_min_interval_seconds: external_exports.number().int().min(1).max(3600),
20510
+ user_max_concurrent: external_exports.number().int().min(1).max(8),
20511
+ user_active_runs: external_exports.number().int().nonnegative(),
20512
+ retry_after_seconds: external_exports.number().int().nonnegative()
20513
+ }).strict().optional(),
20514
+ profiles: external_exports.array(external_exports.object({
20515
+ id: external_exports.string(),
20516
+ label: external_exports.string(),
20517
+ provider: external_exports.string(),
20518
+ model: external_exports.string(),
20519
+ available: external_exports.boolean(),
20520
+ capacity: external_exports.number().int().nonnegative(),
20521
+ status: external_exports.enum(["available", "busy", "daily_limit", "cooldown", "user_busy", "rate_limit"])
20522
+ }).strict()),
20523
+ capabilities: external_exports.array(external_exports.string()),
20524
+ privacy: external_exports.string()
20525
+ }).strict()
20526
+ ]);
20292
20527
  var SingleLineTitleSchema = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u, "Title must not contain control characters").trim().min(1).max(200);
20293
20528
  var SessionTitleSchema = SingleLineTitleSchema;
20294
20529
  var ProjectTitleSchema = SingleLineTitleSchema;
@@ -20335,7 +20570,12 @@ var ProjectListItemSchema = ProjectRecordSchema.omit({ owner_user_id: true }).ex
20335
20570
  role: MembershipRoleSchema,
20336
20571
  session_count: external_exports.number().int().nonnegative()
20337
20572
  });
20573
+ var AvatarIdSchema = external_exports.enum(["cat", "fox", "bear", "rabbit", "penguin", "owl"]);
20574
+ var SetAccountAvatarInputSchema = external_exports.object({ avatar_id: AvatarIdSchema.nullable() }).strict();
20575
+ var AccountAvatarProfileSchema = external_exports.object({ user_id: IdSchema, avatar_id: AvatarIdSchema.nullable() });
20576
+ var SessionAvatarProfilesSchema = external_exports.object({ profiles: external_exports.array(AccountAvatarProfileSchema) });
20338
20577
  var ProjectMemberRecordSchema = external_exports.object({
20578
+ avatar_id: AvatarIdSchema.nullable().optional(),
20339
20579
  user_id: IdSchema,
20340
20580
  display_name: external_exports.string().trim().min(1).max(120),
20341
20581
  role: MembershipRoleSchema
@@ -20550,6 +20790,7 @@ var snapshotRequestStatuses = ["pending", "claimed", "completed", "failed"];
20550
20790
  var SnapshotRequestStatusSchema = external_exports.enum(snapshotRequestStatuses);
20551
20791
  var snapshotRequestKinds = [
20552
20792
  ...codeSyncRequestKinds,
20793
+ ...githubCodeSyncRequestKinds,
20553
20794
  "immutable",
20554
20795
  "visible_history_replace",
20555
20796
  "local_sync_status",
@@ -21412,6 +21653,9 @@ import { promisify } from "node:util";
21412
21653
  var execFileAsync = promisify(execFile);
21413
21654
  var MAX_BINDING_BYTES = 4 * 1024 * 1024;
21414
21655
 
21656
+ // ../bridge/dist/src/github-code-sync.js
21657
+ var filesSchema = createCodeFilesSchema(GITHUB_CODE_SYNC_LIMITS);
21658
+
21415
21659
  // dist/src/collaboration-api.js
21416
21660
  function createHttpDshCollaborationApi(options) {
21417
21661
  const client = new HttpCollaborationClient({
@@ -21532,12 +21776,12 @@ ${footer}`, "utf8");
21532
21776
  const retained = [];
21533
21777
  let used = 0;
21534
21778
  for (const line of contextLines.toReversed()) {
21535
- const bytes = Buffer.byteLength(`${line}
21779
+ const bytes2 = Buffer.byteLength(`${line}
21536
21780
  `, "utf8");
21537
- if (used + bytes > contextBudget)
21781
+ if (used + bytes2 > contextBudget)
21538
21782
  continue;
21539
21783
  retained.push(line);
21540
- used += bytes;
21784
+ used += bytes2;
21541
21785
  }
21542
21786
  retained.reverse();
21543
21787
  const omitted = retained.length < contextLines.length ? [`[${contextLines.length - retained.length} older public context update(s) omitted by size limit]`] : [];
@@ -21851,6 +22095,15 @@ var DshHostConnector = class {
21851
22095
  get stopped() {
21852
22096
  return this.#stopped;
21853
22097
  }
22098
+ /** Project refresh is authoritative for the mode of future DSH bubbles. */
22099
+ updateSessionSummary(session) {
22100
+ if (!this.#started || this.#stopped)
22101
+ throw new Error("DSH connector is not running");
22102
+ if (session.id !== this.#config.sessionId || session.projectId !== this.#config.projectId || session.state !== "active" || !isSessionWritableBy(session, this.#actorUserId)) {
22103
+ throw new Error("Refreshed GatherThread Session is not this writable binding");
22104
+ }
22105
+ this.#session = session;
22106
+ }
21854
22107
  /**
21855
22108
  * Adopt a refreshed execution-profile catalog on a running connection.
21856
22109
  *
@@ -22512,7 +22765,7 @@ var DshHostConnector = class {
22512
22765
  role: "user",
22513
22766
  content,
22514
22767
  occurredAt: event.timestamp,
22515
- ...event.actorDisplayName === void 0 ? {} : {
22768
+ ...this.#session?.mode !== "multi" || event.actorDisplayName === void 0 ? {} : {
22516
22769
  actorDisplayName: event.actorDisplayName
22517
22770
  }
22518
22771
  });
@@ -23660,8 +23913,11 @@ async function createProjectionMessage(projection, options) {
23660
23913
  });
23661
23914
  }
23662
23915
  function formatProjectionText(projection) {
23663
- if (projection.role === "user")
23664
- return projection.content;
23916
+ if (projection.role === "user") {
23917
+ const sender = projection.actorDisplayName?.replace(/[\p{Cc}\p{Cf}【】]+/gu, " ").replace(/\s+/gu, " ").trim();
23918
+ return sender ? `\u3010${sender} \xB7 GatherThread\u3011
23919
+ ${projection.content}` : projection.content;
23920
+ }
23665
23921
  const route = [projection.provider, projection.model].filter(Boolean).join(" / ");
23666
23922
  const attribution = [projection.actorDisplayName, route].filter(Boolean).join(" \xB7 ");
23667
23923
  return `[GatherThread remote Agent reply${attribution ? ` \xB7 ${attribution}` : ""}]
@@ -24477,6 +24733,27 @@ var DshProjectManager = class {
24477
24733
  for (const error62 of permissions.errors)
24478
24734
  this.#reportError(error62);
24479
24735
  const eligibleSessions = [...permissions.eligibleSessions];
24736
+ const sessionUpdateErrors = [];
24737
+ for (const session of eligibleSessions) {
24738
+ const binding = this.#managed.get(session.id);
24739
+ if (binding?.phase === "active" && !binding.connector.stopped) {
24740
+ try {
24741
+ binding.connector.updateSessionSummary(session);
24742
+ } catch (error62) {
24743
+ this.#managed.delete(session.id);
24744
+ try {
24745
+ await binding.connector.stop();
24746
+ } catch (stopError) {
24747
+ this.#reportError(publicError2(stopError, "DSH Session connector cleanup failed"));
24748
+ }
24749
+ if (!this.#stopped)
24750
+ this.#recordFailure(session.id);
24751
+ const failure2 = publicError2(error62, `DSH Session ${session.id} mode refresh failed`);
24752
+ sessionUpdateErrors.push(failure2);
24753
+ this.#reportError(failure2);
24754
+ }
24755
+ }
24756
+ }
24480
24757
  if (this.#discoverLocalSessions !== void 0) {
24481
24758
  try {
24482
24759
  const candidates2 = await this.#discoverLocalSessions();
@@ -24520,7 +24797,7 @@ var DshProjectManager = class {
24520
24797
  status: "updated",
24521
24798
  eligibleSessionIds: [...eligibleIds].sort(),
24522
24799
  activeSessionIds: this.activeSessionIds(),
24523
- errors: [...permissions.errors, ...attachErrors]
24800
+ errors: [...permissions.errors, ...sessionUpdateErrors, ...attachErrors]
24524
24801
  };
24525
24802
  this.#notifyStatus({
24526
24803
  state: "connected",
@@ -25030,6 +25307,7 @@ function createManagedConnector(options) {
25030
25307
  get stopped() {
25031
25308
  return connector.stopped;
25032
25309
  },
25310
+ updateSessionSummary: (session) => connector.updateSessionSummary(session),
25033
25311
  async start() {
25034
25312
  try {
25035
25313
  await connector.start();
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@gatherthread/dsh-host",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-beta.1",
4
4
  "description": "Opt-in GatherThread integration for the DeepSeek Harness Web profile",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {
7
7
  "access": "public",
8
- "tag": "alpha"
8
+ "tag": "beta"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",