@tickernelz/wardmote 2026.1113.0 → 2026.1114.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.
package/dist/index.js CHANGED
@@ -1538,7 +1538,7 @@ var init_native_finalization2 = __esm({
1538
1538
  companyId: z6.string().uuid(),
1539
1539
  result: z6.record(z6.string(), z6.unknown()),
1540
1540
  terminal: z6.object({
1541
- schema: z6.literal("paperclip.prp.terminal.v1"),
1541
+ schema: z6.literal("wardmote.prp.terminal.v1"),
1542
1542
  turnTerminalState: z6.enum(["completed", "failed", "interrupted", "cancelled"]),
1543
1543
  runTerminalState: z6.enum(["succeeded", "failed", "cancelled"]),
1544
1544
  reportedWorkDisposition: z6.enum(["done", "blocked", "needs_review", "yielded"])
@@ -2083,12 +2083,12 @@ function questionSetToAskUserQuestionsPayload(questionSet) {
2083
2083
  ...description !== void 0 ? { description } : {}
2084
2084
  }));
2085
2085
  const freeTextOption = question.answerMode === "text" ? {
2086
- id: "paperclip_text_answer",
2086
+ id: "wardmote_text_answer",
2087
2087
  label: question.header || "Type an answer",
2088
2088
  ...question.textValidation?.inputType ? { description: `Expected ${question.textValidation.inputType} input` } : {},
2089
2089
  freeText: true
2090
2090
  } : question.customAnswer?.enabled ? {
2091
- id: syntheticOptionId(options.map((option) => option.id), "paperclip_custom_answer"),
2091
+ id: syntheticOptionId(options.map((option) => option.id), "wardmote_custom_answer"),
2092
2092
  label: question.customAnswer.label || "Other",
2093
2093
  ...question.customAnswer.placeholder !== void 0 ? { description: question.customAnswer.placeholder } : {},
2094
2094
  freeText: true
@@ -16616,7 +16616,7 @@ var init_smoke_lab = __esm({
16616
16616
  });
16617
16617
 
16618
16618
  // ../packages/shared/src/types/instance.ts
16619
- var DAILY_RETENTION_PRESETS, WEEKLY_RETENTION_PRESETS, MONTHLY_RETENTION_PRESETS, BACKUP_MAX_FILES_MIN, BACKUP_MAX_FILES_MAX, DEFAULT_BACKUP_RETENTION, SPEECH_TO_TEXT_DEFAULTS, ATTACHMENT_MAX_MEGABYTES_MIN, ATTACHMENT_MAX_MEGABYTES_MAX, ATTACHMENT_ORPHAN_AFTER_DAYS_MIN, ATTACHMENT_ORPHAN_AFTER_DAYS_MAX, ATTACHMENT_CLOSED_TASK_AFTER_DAYS_MIN, ATTACHMENT_CLOSED_TASK_AFTER_DAYS_MAX, DEFAULT_ATTACHMENT_RETENTION, DEFAULT_LOCAL_RUN_LIMITS_SETTINGS, DEFAULT_MESSAGE_DELIVERY;
16619
+ var DAILY_RETENTION_PRESETS, WEEKLY_RETENTION_PRESETS, MONTHLY_RETENTION_PRESETS, BACKUP_MAX_FILES_MIN, BACKUP_MAX_FILES_MAX, DEFAULT_BACKUP_RETENTION, SPEECH_TO_TEXT_PROVIDERS, SPEECH_TO_TEXT_GOOGLE_MAX_LANGUAGES, SPEECH_TO_TEXT_KEYTERMS_MAX, SPEECH_TO_TEXT_KEYTERM_MAX_LENGTH, SPEECH_TO_TEXT_MAX_SPEAKERS, SPEECH_TO_TEXT_API_KEY_MAX_LENGTH, SPEECH_TO_TEXT_DEFAULTS, ATTACHMENT_MAX_MEGABYTES_MIN, ATTACHMENT_MAX_MEGABYTES_MAX, ATTACHMENT_ORPHAN_AFTER_DAYS_MIN, ATTACHMENT_ORPHAN_AFTER_DAYS_MAX, ATTACHMENT_CLOSED_TASK_AFTER_DAYS_MIN, ATTACHMENT_CLOSED_TASK_AFTER_DAYS_MAX, DEFAULT_ATTACHMENT_RETENTION, DEFAULT_LOCAL_RUN_LIMITS_SETTINGS, DEFAULT_MESSAGE_DELIVERY;
16620
16620
  var init_instance = __esm({
16621
16621
  "../packages/shared/src/types/instance.ts"() {
16622
16622
  "use strict";
@@ -16631,11 +16631,24 @@ var init_instance = __esm({
16631
16631
  monthlyMonths: 1,
16632
16632
  maxFiles: 2
16633
16633
  };
16634
+ SPEECH_TO_TEXT_PROVIDERS = ["openai_compatible", "deepgram", "elevenlabs", "google"];
16635
+ SPEECH_TO_TEXT_GOOGLE_MAX_LANGUAGES = 3;
16636
+ SPEECH_TO_TEXT_KEYTERMS_MAX = 100;
16637
+ SPEECH_TO_TEXT_KEYTERM_MAX_LENGTH = 50;
16638
+ SPEECH_TO_TEXT_MAX_SPEAKERS = 32;
16639
+ SPEECH_TO_TEXT_API_KEY_MAX_LENGTH = 16384;
16634
16640
  SPEECH_TO_TEXT_DEFAULTS = {
16635
16641
  enabled: false,
16642
+ provider: "openai_compatible",
16636
16643
  baseUrl: "",
16637
16644
  model: "",
16638
16645
  apiKeyEnvVar: "",
16646
+ language: "",
16647
+ diarize: false,
16648
+ keyterms: [],
16649
+ deepgram: { smartFormat: true },
16650
+ elevenlabs: { tagAudioEvents: false, numSpeakers: null },
16651
+ google: { location: "us", projectId: "", autoPunctuation: true, alternativeLanguages: [] },
16639
16652
  maxAudioSeconds: 600,
16640
16653
  sttWaitSeconds: 15
16641
16654
  };
@@ -17215,7 +17228,10 @@ function isSpeechToTextBaseUrl(value) {
17215
17228
  if (url.username || url.password || url.search || url.hash) return false;
17216
17229
  return ["/", "/v1", "/v1/"].includes(url.pathname);
17217
17230
  }
17218
- var messageDeliverySchema, backupRetentionPolicySchema, speechToTextSettingsSchema, attachmentMaxMegabytesSchema, attachmentRetentionSettingsSchema, localRunLimitsSettingsSchema, instanceGeneralSettingsSchema, patchInstanceGeneralSettingsSchema, instanceExperimentalSettingsSchema, patchInstanceExperimentalSettingsSchema, patchInstanceSettingsSchema, MAX_TASK_DRAIN_TTL_MS, startTaskDrainRequestSchema, instanceSettingsSchema;
17231
+ function isGoogleChirpModel(model) {
17232
+ return model.startsWith("chirp");
17233
+ }
17234
+ var messageDeliverySchema, backupRetentionPolicySchema, speechToTextProviderSchema, speechToTextBaseUrlSchema, speechToTextApiKeyEnvVarSchema, speechToTextApiKeySchema, speechToTextKeytermSchema, speechToTextGoogleLocationSchema, speechToTextGoogleProjectIdSchema, speechToTextLanguageCodeSchema, speechToTextSettingsSchema, speechToTextModelListRequestSchema, speechToTextApiKeyRequestSchema, attachmentMaxMegabytesSchema, attachmentRetentionSettingsSchema, localRunLimitsSettingsSchema, instanceGeneralSettingsSchema, patchInstanceGeneralSettingsSchema, instanceExperimentalSettingsSchema, patchInstanceExperimentalSettingsSchema, patchInstanceSettingsSchema, MAX_TASK_DRAIN_TTL_MS, startTaskDrainRequestSchema, instanceSettingsSchema;
17219
17235
  var init_instance2 = __esm({
17220
17236
  "../packages/shared/src/validators/instance.ts"() {
17221
17237
  "use strict";
@@ -17231,20 +17247,72 @@ var init_instance2 = __esm({
17231
17247
  monthlyMonths: presetSchema(MONTHLY_RETENTION_PRESETS, "monthlyMonths").default(DEFAULT_BACKUP_RETENTION.monthlyMonths),
17232
17248
  maxFiles: z40.number().int().min(BACKUP_MAX_FILES_MIN).max(BACKUP_MAX_FILES_MAX).nullable().default(DEFAULT_BACKUP_RETENTION.maxFiles)
17233
17249
  });
17250
+ speechToTextProviderSchema = z40.enum(SPEECH_TO_TEXT_PROVIDERS);
17251
+ speechToTextBaseUrlSchema = z40.string().trim().max(2048).refine(isSpeechToTextBaseUrl, {
17252
+ message: "Speech-to-text base URL must be an http(s) origin or end at /v1, without credentials, query or fragment"
17253
+ });
17254
+ speechToTextApiKeyEnvVarSchema = z40.string().trim().max(128).regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/, {
17255
+ message: "Speech-to-text API key must name a server environment variable, not hold the key itself"
17256
+ });
17257
+ speechToTextApiKeySchema = z40.string().trim().min(1).max(SPEECH_TO_TEXT_API_KEY_MAX_LENGTH);
17258
+ speechToTextKeytermSchema = z40.string().trim().min(1).max(SPEECH_TO_TEXT_KEYTERM_MAX_LENGTH).regex(/^[^<>{}[\]\\]+$/, { message: "Keyterms cannot contain < > { } [ ] or \\" });
17259
+ speechToTextGoogleLocationSchema = z40.string().trim().regex(/^[a-z][a-z0-9-]{1,39}$/, { message: "Google speech-to-text location must be global, us, eu or a region such as asia-southeast1" });
17260
+ speechToTextGoogleProjectIdSchema = z40.string().trim().regex(/^(?:[a-z][a-z0-9-]{4,28}[a-z0-9])?$/, { message: "Google Cloud project id must be 6 to 30 lowercase letters, digits or hyphens" });
17261
+ speechToTextLanguageCodeSchema = z40.string().trim().regex(/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/, { message: "Speech-to-text language must be a code such as en or pt-BR" });
17234
17262
  speechToTextSettingsSchema = z40.object({
17235
17263
  enabled: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.enabled),
17236
- baseUrl: z40.string().trim().max(2048).refine(isSpeechToTextBaseUrl, {
17237
- message: "Speech-to-text base URL must be an http(s) origin or end at /v1, without credentials, query or fragment"
17238
- }).default(SPEECH_TO_TEXT_DEFAULTS.baseUrl),
17264
+ provider: speechToTextProviderSchema.default(SPEECH_TO_TEXT_DEFAULTS.provider),
17265
+ baseUrl: speechToTextBaseUrlSchema.default(SPEECH_TO_TEXT_DEFAULTS.baseUrl),
17239
17266
  model: z40.string().trim().max(200).default(SPEECH_TO_TEXT_DEFAULTS.model),
17240
- apiKeyEnvVar: z40.string().trim().max(128).regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/, {
17241
- message: "Speech-to-text API key must name a server environment variable, not hold the key itself"
17242
- }).default(SPEECH_TO_TEXT_DEFAULTS.apiKeyEnvVar),
17267
+ apiKeyEnvVar: speechToTextApiKeyEnvVarSchema.default(SPEECH_TO_TEXT_DEFAULTS.apiKeyEnvVar),
17268
+ language: z40.string().trim().max(35).regex(/^(?:multi|[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*)?$/, {
17269
+ message: "Speech-to-text language must be empty for automatic detection, a language code such as en or pt-BR, or multi"
17270
+ }).default(SPEECH_TO_TEXT_DEFAULTS.language),
17271
+ diarize: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.diarize),
17272
+ keyterms: z40.array(speechToTextKeytermSchema).max(SPEECH_TO_TEXT_KEYTERMS_MAX).default(SPEECH_TO_TEXT_DEFAULTS.keyterms),
17273
+ deepgram: z40.object({ smartFormat: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.deepgram.smartFormat) }).strict().default(SPEECH_TO_TEXT_DEFAULTS.deepgram),
17274
+ elevenlabs: z40.object({
17275
+ tagAudioEvents: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs.tagAudioEvents),
17276
+ numSpeakers: z40.number().int().min(1).max(SPEECH_TO_TEXT_MAX_SPEAKERS).nullable().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs.numSpeakers)
17277
+ }).strict().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs),
17278
+ google: z40.object({
17279
+ location: speechToTextGoogleLocationSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.location),
17280
+ projectId: speechToTextGoogleProjectIdSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.projectId),
17281
+ autoPunctuation: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.google.autoPunctuation),
17282
+ alternativeLanguages: z40.array(speechToTextLanguageCodeSchema).max(SPEECH_TO_TEXT_GOOGLE_MAX_LANGUAGES - 1).default(SPEECH_TO_TEXT_DEFAULTS.google.alternativeLanguages)
17283
+ }).strict().default(SPEECH_TO_TEXT_DEFAULTS.google),
17243
17284
  maxAudioSeconds: z40.number().int().min(1).max(7200).default(SPEECH_TO_TEXT_DEFAULTS.maxAudioSeconds),
17244
17285
  sttWaitSeconds: z40.number().int().min(1).max(120).default(SPEECH_TO_TEXT_DEFAULTS.sttWaitSeconds)
17245
- }).strict().refine((value) => !value.enabled || value.baseUrl !== "" && value.model !== "" && value.apiKeyEnvVar !== "", {
17246
- message: "Speech-to-text needs a base URL, a model and an API key environment variable before it can be enabled"
17286
+ }).strict().refine(
17287
+ (value) => !value.enabled || value.model !== "" && (value.provider !== "openai_compatible" || value.baseUrl !== ""),
17288
+ {
17289
+ message: "Speech-to-text needs a model and, for OpenAI-compatible endpoints, a base URL before it can be enabled"
17290
+ }
17291
+ ).superRefine((value, ctx) => {
17292
+ if (value.provider !== "google") return;
17293
+ if (value.language === "multi")
17294
+ ctx.addIssue({ code: "custom", path: ["language"], message: "Google speech-to-text has no multi language; leave it empty for Chirp automatic detection or add alternative languages" });
17295
+ const chirp = isGoogleChirpModel(value.model);
17296
+ if (value.model !== "" && !chirp && value.language === "")
17297
+ ctx.addIssue({ code: "custom", path: ["language"], message: "Google models other than Chirp need a language; only Chirp detects it automatically" });
17298
+ if (value.google.alternativeLanguages.length > 0 && (chirp || value.language === ""))
17299
+ ctx.addIssue({
17300
+ code: "custom",
17301
+ path: ["google", "alternativeLanguages"],
17302
+ message: "Google alternative languages need a primary language and the long, short or telephony model"
17303
+ });
17247
17304
  });
17305
+ speechToTextModelListRequestSchema = z40.object({
17306
+ provider: speechToTextProviderSchema,
17307
+ baseUrl: speechToTextBaseUrlSchema.default(""),
17308
+ apiKeyEnvVar: speechToTextApiKeyEnvVarSchema.default(""),
17309
+ apiKey: speechToTextApiKeySchema.optional(),
17310
+ google: z40.object({
17311
+ location: speechToTextGoogleLocationSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.location),
17312
+ projectId: speechToTextGoogleProjectIdSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.projectId)
17313
+ }).strict().optional()
17314
+ }).strict();
17315
+ speechToTextApiKeyRequestSchema = z40.object({ apiKey: speechToTextApiKeySchema }).strict();
17248
17316
  attachmentMaxMegabytesSchema = z40.number().int().min(ATTACHMENT_MAX_MEGABYTES_MIN).max(ATTACHMENT_MAX_MEGABYTES_MAX);
17249
17317
  attachmentRetentionSettingsSchema = z40.object({
17250
17318
  enabled: z40.boolean().default(DEFAULT_ATTACHMENT_RETENTION.enabled),
@@ -20507,7 +20575,7 @@ var init_config_schema = __esm({
20507
20575
  baseDir: z70.string().default("~/.wardmote/instances/default/data/storage")
20508
20576
  }).passthrough();
20509
20577
  storageS3ConfigSchema = z70.object({
20510
- bucket: z70.string().min(1).default("paperclip"),
20578
+ bucket: z70.string().min(1).default("wardmote"),
20511
20579
  region: z70.string().min(1).default("us-east-1"),
20512
20580
  endpoint: z70.string().optional(),
20513
20581
  prefix: z70.string().default(""),
@@ -20519,7 +20587,7 @@ var init_config_schema = __esm({
20519
20587
  baseDir: "~/.wardmote/instances/default/data/storage"
20520
20588
  }),
20521
20589
  s3: storageS3ConfigSchema.default({
20522
- bucket: "paperclip",
20590
+ bucket: "wardmote",
20523
20591
  region: "us-east-1",
20524
20592
  prefix: "",
20525
20593
  forcePathStyle: false
@@ -20584,7 +20652,7 @@ var init_config_schema = __esm({
20584
20652
  baseDir: "~/.wardmote/instances/default/data/storage"
20585
20653
  },
20586
20654
  s3: {
20587
- bucket: "paperclip",
20655
+ bucket: "wardmote",
20588
20656
  region: "us-east-1",
20589
20657
  prefix: "",
20590
20658
  forcePathStyle: false
@@ -21732,7 +21800,7 @@ var init_announcements = __esm({
21732
21800
  secondaryLink: announcementActionSchema.optional(),
21733
21801
  primaryAction: announcementActionSchema,
21734
21802
  expiresAt: z80.string().datetime({ offset: true }).optional(),
21735
- minimumPaperclipVersion: z80.string().regex(/^\d+\.\d+\.\d+$/).optional()
21803
+ minimumWardmoteVersion: z80.string().regex(/^\d+\.\d+\.\d+$/).optional()
21736
21804
  }).strict().refine((value) => !value.animation || Boolean(value.image), {
21737
21805
  message: "An animation requires a static fallback image",
21738
21806
  path: ["image"]
@@ -21919,7 +21987,7 @@ var init_openwa_tools = __esm({
21919
21987
  "read",
21920
21988
  "List OpenWA gateway operations with category and availability on this engine and key. Filter by category or text; page with cursor.",
21921
21989
  {
21922
- category: z81.enum(["read", "write", "wa_admin", "gateway_admin", "paperclip"]).optional(),
21990
+ category: z81.enum(["read", "write", "wa_admin", "gateway_admin", "wardmote"]).optional(),
21923
21991
  query: z81.string().min(1).max(100).optional(),
21924
21992
  cursor: cursor2
21925
21993
  }
@@ -26729,6 +26797,13 @@ var init_wardmote_updates = __esm({
26729
26797
  }
26730
26798
  });
26731
26799
 
26800
+ // ../packages/shared/src/speech-to-text-languages.ts
26801
+ var init_speech_to_text_languages = __esm({
26802
+ "../packages/shared/src/speech-to-text-languages.ts"() {
26803
+ "use strict";
26804
+ }
26805
+ });
26806
+
26732
26807
  // ../packages/shared/src/index.ts
26733
26808
  var init_src = __esm({
26734
26809
  "../packages/shared/src/index.ts"() {
@@ -26877,6 +26952,7 @@ var init_src = __esm({
26877
26952
  init_agent_lifecycle();
26878
26953
  init_fast_response();
26879
26954
  init_wardmote_updates();
26955
+ init_speech_to_text_languages();
26880
26956
  }
26881
26957
  });
26882
26958
 
@@ -28263,7 +28339,7 @@ function defaultStorageConfig() {
28263
28339
  baseDir: defaultStorageBaseDir()
28264
28340
  },
28265
28341
  s3: {
28266
- bucket: "paperclip",
28342
+ bucket: "wardmote",
28267
28343
  region: "us-east-1",
28268
28344
  endpoint: void 0,
28269
28345
  prefix: "",
@@ -28315,12 +28391,12 @@ async function promptStorage(current) {
28315
28391
  s3: base.s3
28316
28392
  };
28317
28393
  }
28318
- const bucketDefault = base.s3.bucket || "paperclip";
28394
+ const bucketDefault = base.s3.bucket || "wardmote";
28319
28395
  const regionDefault = base.s3.region || "us-east-1";
28320
28396
  const bucket = await p5.text({
28321
28397
  message: "S3 bucket",
28322
28398
  defaultValue: bucketDefault,
28323
- placeholder: "paperclip",
28399
+ placeholder: "wardmote",
28324
28400
  validate: (value) => {
28325
28401
  if ((value || bucketDefault).trim().length === 0) return "Bucket is required";
28326
28402
  }
@@ -28353,7 +28429,7 @@ async function promptStorage(current) {
28353
28429
  const prefix = await p5.text({
28354
28430
  message: "Object key prefix (optional)",
28355
28431
  defaultValue: base.s3.prefix ?? "",
28356
- placeholder: "paperclip/"
28432
+ placeholder: "wardmote/"
28357
28433
  });
28358
28434
  if (p5.isCancel(prefix)) {
28359
28435
  p5.cancel("Setup cancelled.");
@@ -30999,7 +31075,7 @@ var init_chat_channels3 = __esm({
30999
31075
  companyId: uuid17("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
31000
31076
  endpointId: uuid17("endpoint_id").notNull(),
31001
31077
  principalId: uuid17("principal_id").notNull(),
31002
- wardmoteUserId: text23("paperclip_user_id"),
31078
+ wardmoteUserId: text23("wardmote_user_id"),
31003
31079
  status: text23("status").$type().notNull().default("pending"),
31004
31080
  confirmationTokenHash: text23("confirmation_token_hash"),
31005
31081
  expiresAt: timestamp18("expires_at", { withTimezone: true }),
@@ -32007,6 +32083,7 @@ var init_instance_settings = __esm({
32007
32083
  general: jsonb18("general").$type().notNull().default({}),
32008
32084
  experimental: jsonb18("experimental").$type().notNull().default({}),
32009
32085
  attachmentRetentionLastRun: jsonb18("attachment_retention_last_run").$type(),
32086
+ speechToTextKeys: jsonb18("speech_to_text_keys").$type().notNull().default({}),
32010
32087
  createdAt: timestamp23("created_at", { withTimezone: true }).notNull().defaultNow(),
32011
32088
  updatedAt: timestamp23("updated_at", { withTimezone: true }).notNull().defaultNow()
32012
32089
  },
@@ -41065,6 +41142,15 @@ var init_schema2 = __esm({
41065
41142
  }
41066
41143
  });
41067
41144
 
41145
+ // ../packages/db/src/retired-migration-lock.ts
41146
+ var RETIRED_MIGRATION_LOCK_KEY;
41147
+ var init_retired_migration_lock = __esm({
41148
+ "../packages/db/src/retired-migration-lock.ts"() {
41149
+ "use strict";
41150
+ RETIRED_MIGRATION_LOCK_KEY = "paperclip:migrations";
41151
+ }
41152
+ });
41153
+
41068
41154
  // ../packages/db/src/client.ts
41069
41155
  import { createHash as createHash2 } from "node:crypto";
41070
41156
  import { drizzle as drizzlePg } from "drizzle-orm/postgres-js";
@@ -41209,7 +41295,7 @@ function createDbClient(url, resolved, owner) {
41209
41295
  dedicatedDbFactories.set(db, () => createDbClient(url, {
41210
41296
  ...resolved,
41211
41297
  maxConnections: 1,
41212
- applicationName: "paperclip-workspace-finalization-lock"
41298
+ applicationName: "wardmote-workspace-finalization-lock"
41213
41299
  }, db));
41214
41300
  return db;
41215
41301
  }
@@ -41349,8 +41435,11 @@ async function applyPendingMigrationsManually(url, pendingMigrations) {
41349
41435
  try {
41350
41436
  const sql72 = await pool.reserve();
41351
41437
  try {
41352
- while (!(await sql72`
41353
- SELECT pg_try_advisory_lock(hashtextextended('paperclip:migrations', 0)) AS locked`)[0]?.locked) {
41438
+ for (; ; ) {
41439
+ const [held] = await sql72.unsafe(MIGRATION_LOCK_TRY_SQL);
41440
+ if (held?.current && held.retired) break;
41441
+ if (held?.current) await sql72.unsafe(`SELECT pg_advisory_unlock(hashtextextended('${MIGRATION_LOCK_KEY}', 0))`);
41442
+ if (held?.retired) await sql72.unsafe(`SELECT pg_advisory_unlock(hashtextextended('${RETIRED_MIGRATION_LOCK_KEY}', 0))`);
41354
41443
  await new Promise((resolve3) => setTimeout(resolve3, 100));
41355
41444
  }
41356
41445
  const { migrationTableSchema, columnNames } = await ensureMigrationJournalTable(sql72);
@@ -41404,7 +41493,7 @@ async function applyPendingMigrationsManually(url, pendingMigrations) {
41404
41493
  }
41405
41494
  } finally {
41406
41495
  try {
41407
- await sql72`SELECT pg_advisory_unlock(hashtextextended('paperclip:migrations', 0))`;
41496
+ await sql72.unsafe(MIGRATION_LOCK_RELEASE_SQL);
41408
41497
  } catch {
41409
41498
  }
41410
41499
  sql72.release();
@@ -41882,15 +41971,19 @@ async function resetPostgresDatabase(url, databaseName) {
41882
41971
  await sql72.end();
41883
41972
  }
41884
41973
  }
41885
- var MIGRATIONS_FOLDER, DRIZZLE_MIGRATIONS_TABLE, MIGRATIONS_JOURNAL_JSON, clientsByHostPort, clientFinalizer, DEFAULT_DATABASE_IDLE_TIMEOUT_SECONDS, DEFAULT_DATABASE_APPLICATION_NAME, dedicatedDbFactories, MIGRATIONS_WITH_TOP_LEVEL_STATEMENTS;
41974
+ var MIGRATIONS_FOLDER, DRIZZLE_MIGRATIONS_TABLE, MIGRATIONS_JOURNAL_JSON, MIGRATION_LOCK_KEY, MIGRATION_LOCK_TRY_SQL, MIGRATION_LOCK_RELEASE_SQL, clientsByHostPort, clientFinalizer, DEFAULT_DATABASE_IDLE_TIMEOUT_SECONDS, DEFAULT_DATABASE_APPLICATION_NAME, dedicatedDbFactories, MIGRATIONS_WITH_TOP_LEVEL_STATEMENTS;
41886
41975
  var init_client = __esm({
41887
41976
  "../packages/db/src/client.ts"() {
41888
41977
  "use strict";
41889
41978
  init_work_signals();
41890
41979
  init_schema2();
41980
+ init_retired_migration_lock();
41891
41981
  MIGRATIONS_FOLDER = fileURLToPath2(new URL("./migrations", import.meta.url));
41892
41982
  DRIZZLE_MIGRATIONS_TABLE = "__drizzle_migrations";
41893
41983
  MIGRATIONS_JOURNAL_JSON = fileURLToPath2(new URL("./migrations/meta/_journal.json", import.meta.url));
41984
+ MIGRATION_LOCK_KEY = "wardmote:migrations";
41985
+ MIGRATION_LOCK_TRY_SQL = `SELECT pg_try_advisory_lock(hashtextextended('${MIGRATION_LOCK_KEY}', 0)) AS current, pg_try_advisory_lock(hashtextextended('${RETIRED_MIGRATION_LOCK_KEY}', 0)) AS retired`;
41986
+ MIGRATION_LOCK_RELEASE_SQL = `SELECT pg_advisory_unlock(hashtextextended('${MIGRATION_LOCK_KEY}', 0)), pg_advisory_unlock(hashtextextended('${RETIRED_MIGRATION_LOCK_KEY}', 0))`;
41894
41987
  clientsByHostPort = /* @__PURE__ */ new Map();
41895
41988
  clientFinalizer = new FinalizationRegistry(
41896
41989
  ({ hostPortKey: hostPortKey2, ref }) => {
@@ -47888,6 +47981,16 @@ var init_test_embedded_postgres = __esm({
47888
47981
  }
47889
47982
  });
47890
47983
 
47984
+ // ../packages/db/src/retired-backup-names.ts
47985
+ var RETIRED_BACKUP_FILENAME_PREFIX, RETIRED_STATEMENT_BREAKPOINT;
47986
+ var init_retired_backup_names = __esm({
47987
+ "../packages/db/src/retired-backup-names.ts"() {
47988
+ "use strict";
47989
+ RETIRED_BACKUP_FILENAME_PREFIX = "paperclip";
47990
+ RETIRED_STATEMENT_BREAKPOINT = "-- paperclip statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
47991
+ }
47992
+ });
47993
+
47891
47994
  // ../packages/db/src/backup-lib.ts
47892
47995
  import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statfsSync, statSync, unlinkSync, writeFileSync } from "node:fs";
47893
47996
  import { basename, join as join2, resolve as resolve2 } from "node:path";
@@ -47899,6 +48002,9 @@ import { pipeline } from "node:stream/promises";
47899
48002
  import { createGunzip, createGzip } from "node:zlib";
47900
48003
  import postgres3 from "postgres";
47901
48004
  import { randomUUID as randomUUID3 } from "node:crypto";
48005
+ function isStatementBreakpoint(line) {
48006
+ return line === STATEMENT_BREAKPOINT || line === RETIRED_STATEMENT_BREAKPOINT;
48007
+ }
47902
48008
  function sanitizeRestoreErrorMessage(error) {
47903
48009
  if (error && typeof error === "object") {
47904
48010
  const record2 = error;
@@ -48157,9 +48263,9 @@ function formatBackupSize(sizeBytes) {
48157
48263
  }
48158
48264
  function formatSqlLiteral(value) {
48159
48265
  const sanitized = value.replace(/\u0000/g, "");
48160
- let tag = "$paperclip$";
48266
+ let tag = "$wardmote$";
48161
48267
  while (sanitized.includes(tag)) {
48162
- tag = `$paperclip_${Math.random().toString(36).slice(2, 8)}$`;
48268
+ tag = `$wardmote_${Math.random().toString(36).slice(2, 8)}$`;
48163
48269
  }
48164
48270
  return `${tag}${sanitized}${tag}`;
48165
48271
  }
@@ -48312,10 +48418,10 @@ async function hasStatementBreakpoints(backupFile) {
48312
48418
  try {
48313
48419
  for await (const chunk of stream) {
48314
48420
  text169 += Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
48315
- if (text169.includes(STATEMENT_BREAKPOINT)) return true;
48421
+ if (text169.includes(STATEMENT_BREAKPOINT) || text169.includes(RETIRED_STATEMENT_BREAKPOINT)) return true;
48316
48422
  if (Buffer.byteLength(text169, "utf8") >= BACKUP_BREAKPOINT_DETECT_BYTES) return false;
48317
48423
  }
48318
- return text169.includes(STATEMENT_BREAKPOINT);
48424
+ return text169.includes(STATEMENT_BREAKPOINT) || text169.includes(RETIRED_STATEMENT_BREAKPOINT);
48319
48425
  } finally {
48320
48426
  stream.destroy();
48321
48427
  raw.destroy();
@@ -48337,7 +48443,7 @@ async function* readRestoreStatements(backupFile) {
48337
48443
  };
48338
48444
  try {
48339
48445
  for await (const line of reader) {
48340
- if (line === STATEMENT_BREAKPOINT) {
48446
+ if (isStatementBreakpoint(line)) {
48341
48447
  const statement = flushStatement();
48342
48448
  if (statement.length > 0) {
48343
48449
  yield statement;
@@ -48961,15 +49067,16 @@ function formatDatabaseBackupResult(result) {
48961
49067
  const unreadable = result.unreadableBackups?.length ? `; kept ${result.unreadableBackups.length} unreadable backup(s)` : "";
48962
49068
  return `${result.backupFile} (${size}${pruned}${unreadable})`;
48963
49069
  }
48964
- var DEFAULT_BACKUP_WRITE_BUFFER_BYTES, BACKUP_DATA_CURSOR_ROWS, BACKUP_CLI_STDERR_BYTES, BACKUP_BREAKPOINT_DETECT_BYTES, STATEMENT_BREAKPOINT, DATABASE_BACKUP_FILENAME_PREFIX, PINNED_BACKUP_DIRNAME, DATABASE_BACKUP_SKIPPED_MARKER, DEFAULT_BACKUP_HEADROOM_FACTOR, DAY_MS2, DatabaseBackupSkippedError, verifiedBackups, RETIRED_BACKUP_FILENAME_PREFIX, PARTIAL_BACKUP_PATTERN, ABANDONED_PARTIAL_BACKUP_AGE_MS, activePartialBackupFiles;
49070
+ var DEFAULT_BACKUP_WRITE_BUFFER_BYTES, BACKUP_DATA_CURSOR_ROWS, BACKUP_CLI_STDERR_BYTES, BACKUP_BREAKPOINT_DETECT_BYTES, STATEMENT_BREAKPOINT, DATABASE_BACKUP_FILENAME_PREFIX, PINNED_BACKUP_DIRNAME, DATABASE_BACKUP_SKIPPED_MARKER, DEFAULT_BACKUP_HEADROOM_FACTOR, DAY_MS2, DatabaseBackupSkippedError, verifiedBackups, PARTIAL_BACKUP_PATTERN, ABANDONED_PARTIAL_BACKUP_AGE_MS, activePartialBackupFiles;
48965
49071
  var init_backup_lib = __esm({
48966
49072
  "../packages/db/src/backup-lib.ts"() {
48967
49073
  "use strict";
49074
+ init_retired_backup_names();
48968
49075
  DEFAULT_BACKUP_WRITE_BUFFER_BYTES = 1024 * 1024;
48969
49076
  BACKUP_DATA_CURSOR_ROWS = 100;
48970
49077
  BACKUP_CLI_STDERR_BYTES = 64 * 1024;
48971
49078
  BACKUP_BREAKPOINT_DETECT_BYTES = 64 * 1024;
48972
- STATEMENT_BREAKPOINT = "-- paperclip statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
49079
+ STATEMENT_BREAKPOINT = "-- wardmote statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
48973
49080
  DATABASE_BACKUP_FILENAME_PREFIX = "wardmote";
48974
49081
  PINNED_BACKUP_DIRNAME = "pinned";
48975
49082
  DATABASE_BACKUP_SKIPPED_MARKER = "backup-skipped.json";
@@ -48991,7 +49098,6 @@ var init_backup_lib = __esm({
48991
49098
  code = "database_backup_skipped_low_disk";
48992
49099
  };
48993
49100
  verifiedBackups = /* @__PURE__ */ new Map();
48994
- RETIRED_BACKUP_FILENAME_PREFIX = "paperclip";
48995
49101
  PARTIAL_BACKUP_PATTERN = /\.(\d+)\.partial$/;
48996
49102
  ABANDONED_PARTIAL_BACKUP_AGE_MS = 24 * 60 * 60 * 1e3;
48997
49103
  activePartialBackupFiles = /* @__PURE__ */ new Set();
@@ -49736,7 +49842,7 @@ var init_client2 = __esm({
49736
49842
  buildEnvelope(events, batchId) {
49737
49843
  const state = this.getState();
49738
49844
  return {
49739
- app: this.config.app ?? "paperclip",
49845
+ app: this.config.app ?? "wardmote",
49740
49846
  schemaVersion: this.config.schemaVersion ?? "1",
49741
49847
  installId: state.installId,
49742
49848
  version: this.version,
@@ -50616,9 +50722,26 @@ async function resolvePublishedVersion(spec, runCommand2) {
50616
50722
  );
50617
50723
  return parseResolvedVersion(result.stdout);
50618
50724
  }
50725
+ async function resolveReleasePackageNames(version, runCommand2) {
50726
+ try {
50727
+ const result = await runCommand2(
50728
+ "npm",
50729
+ ["view", `@tickernelz/wardmote@${version}`, "wardmoteReleasePackages", "--json", `--registry=${PUBLIC_NPM_REGISTRY}`],
50730
+ { maxBuffer: 1024 * 1024 }
50731
+ );
50732
+ const declared = JSON.parse(result.stdout.trim() || "null");
50733
+ if (Array.isArray(declared) && declared.length > 0 && declared.every((name) => typeof name === "string" && name.startsWith("@tickernelz/"))) {
50734
+ return declared;
50735
+ }
50736
+ } catch {
50737
+ return RELEASE_PACKAGE_NAMES;
50738
+ }
50739
+ return RELEASE_PACKAGE_NAMES;
50740
+ }
50619
50741
  async function assertReleaseSetPublished(version, runCommand2) {
50742
+ const names = await resolveReleasePackageNames(version, runCommand2);
50620
50743
  const missing = [];
50621
- const queue = [...RELEASE_PACKAGE_NAMES];
50744
+ const queue = [...names];
50622
50745
  const probe = async () => {
50623
50746
  for (let name = queue.pop(); name !== void 0; name = queue.pop()) {
50624
50747
  try {
@@ -50633,10 +50756,10 @@ async function assertReleaseSetPublished(version, runCommand2) {
50633
50756
  }
50634
50757
  }
50635
50758
  };
50636
- await Promise.all(Array.from({ length: Math.min(8, RELEASE_PACKAGE_NAMES.length) }, probe));
50759
+ await Promise.all(Array.from({ length: Math.min(8, names.length) }, probe));
50637
50760
  if (missing.length > 0) {
50638
50761
  throw new Error(
50639
- `Release ${version} is incomplete on ${PUBLIC_NPM_REGISTRY}: ${missing.length} of ${RELEASE_PACKAGE_NAMES.length} packages are not published at that version (${missing.sort().join(", ")}). Installing it would mix versions across packages. Wait for the release to finish publishing, or pass --version with a complete release.`
50762
+ `Release ${version} is incomplete on ${PUBLIC_NPM_REGISTRY}: ${missing.length} of ${names.length} packages are not published at that version (${missing.sort().join(", ")}). Installing it would mix versions across packages. Wait for the release to finish publishing, or pass --version with a complete release.`
50640
50763
  );
50641
50764
  }
50642
50765
  }
@@ -50912,7 +51035,7 @@ async function installCommand(options, dependencies = {}) {
50912
51035
  const request = resolveNpmInstallRequest(options);
50913
51036
  console.log(`Resolving @tickernelz/wardmote@${request.spec} from ${PUBLIC_NPM_REGISTRY}...`);
50914
51037
  const version = await resolvePublishedVersion(request.spec, runCommand2);
50915
- console.log(`Verifying all ${RELEASE_PACKAGE_NAMES.length} packages of release ${version}...`);
51038
+ console.log(`Verifying the packages of release ${version}...`);
50916
51039
  await assertReleaseSetPublished(version, runCommand2);
50917
51040
  console.log(`Installing @tickernelz/wardmote@${version}...`);
50918
51041
  const paths = resolveInstallStorePaths();
@@ -62117,7 +62240,7 @@ function buildWorktreeConfig(input2) {
62117
62240
  baseDir: paths.storageDir
62118
62241
  },
62119
62242
  s3: {
62120
- bucket: source?.storage.s3.bucket ?? "paperclip",
62243
+ bucket: source?.storage.s3.bucket ?? "wardmote",
62121
62244
  region: source?.storage.s3.region ?? "us-east-1",
62122
62245
  endpoint: source?.storage.s3.endpoint,
62123
62246
  prefix: source?.storage.s3.prefix ?? "",
@@ -65257,7 +65380,7 @@ async function worktreeListCommand(opts) {
65257
65380
  for (const choice of choices) {
65258
65381
  const flags = [
65259
65382
  choice.isCurrent ? "current" : null,
65260
- choice.hasWardmoteConfig ? "paperclip" : "no-paperclip-config"
65383
+ choice.hasWardmoteConfig ? "wardmote" : "no-wardmote-config"
65261
65384
  ].filter((value) => value !== null);
65262
65385
  p11.log.message(`${choice.branchLabel} ${choice.worktree} [${flags.join(", ")}]`);
65263
65386
  }
@@ -68014,7 +68137,7 @@ function collectDeploymentEnvRows(config, configPath) {
68014
68137
  const secretsKeyFilePath = process.env.WARDMOTE_SECRETS_MASTER_KEY_FILE ?? config?.secrets?.localEncrypted?.keyFilePath ?? defaultSecretsKeyFilePath();
68015
68138
  const storageProvider = process.env.WARDMOTE_STORAGE_PROVIDER ?? config?.storage?.provider ?? DEFAULT_STORAGE_PROVIDER;
68016
68139
  const storageLocalDir = process.env.WARDMOTE_STORAGE_LOCAL_DIR ?? config?.storage?.localDisk?.baseDir ?? defaultStorageBaseDir2();
68017
- const storageS3Bucket = process.env.WARDMOTE_STORAGE_S3_BUCKET ?? config?.storage?.s3?.bucket ?? "paperclip";
68140
+ const storageS3Bucket = process.env.WARDMOTE_STORAGE_S3_BUCKET ?? config?.storage?.s3?.bucket ?? "wardmote";
68018
68141
  const storageS3Region = process.env.WARDMOTE_STORAGE_S3_REGION ?? config?.storage?.s3?.region ?? "us-east-1";
68019
68142
  const storageS3Endpoint = process.env.WARDMOTE_STORAGE_S3_ENDPOINT ?? config?.storage?.s3?.endpoint ?? "";
68020
68143
  const storageS3Prefix = process.env.WARDMOTE_STORAGE_S3_PREFIX ?? config?.storage?.s3?.prefix ?? "";
@@ -68274,7 +68397,7 @@ async function channelsCommand(options = {}, runCommand2 = defaultRunCommand) {
68274
68397
  } else {
68275
68398
  console.log(`This install is version ${pc12.bold(packageVersion)} on the ${pc12.bold(currentChannel)} channel.`);
68276
68399
  }
68277
- console.log(`Docker images use the same names: ghcr.io/paperclipai/paperclip:{latest,beta,nightly,canary}`);
68400
+ console.log("Docker images are built from source; see doc/DOCKER.md.");
68278
68401
  }
68279
68402
 
68280
68403
  // src/commands/configure.ts
@@ -76465,7 +76588,7 @@ function scaffoldPluginProject(options) {
76465
76588
  worker: "./dist/worker.js",
76466
76589
  ui: "./dist/ui/"
76467
76590
  },
76468
- keywords: ["paperclip", "plugin", category],
76591
+ keywords: ["wardmote", "plugin", category],
76469
76592
  author,
76470
76593
  license: "MIT",
76471
76594
  ...packedSharedTarball ? {
@@ -79508,7 +79631,7 @@ async function listAll(key, path53) {
79508
79631
  }
79509
79632
  function resourceByProfile(resources, profileKey, resourceLabel) {
79510
79633
  const matches = resources.filter(
79511
- (resource) => typeof resource.id === "string" && record(resource.metadata).paperclip_profile === profileKey
79634
+ (resource) => typeof resource.id === "string" && record(resource.metadata).wardmote_profile === profileKey
79512
79635
  );
79513
79636
  if (matches.length > 1) {
79514
79637
  throw new Error(
@@ -79576,7 +79699,7 @@ async function resolveEnvironment(key, options) {
79576
79699
  pip: []
79577
79700
  }
79578
79701
  },
79579
- metadata: { paperclip_profile: options.profileKey }
79702
+ metadata: { wardmote_profile: options.profileKey }
79580
79703
  });
79581
79704
  assertSafeManagedEnvironment(environment);
79582
79705
  return environment;
@@ -79611,7 +79734,7 @@ async function resolveAgent3(key, options) {
79611
79734
  tools: [],
79612
79735
  mcp_servers: [],
79613
79736
  skills: [],
79614
- metadata: { paperclip_profile: options.profileKey }
79737
+ metadata: { wardmote_profile: options.profileKey }
79615
79738
  });
79616
79739
  assertSafeManagedAgent(agent);
79617
79740
  assertManagedAgentModel(agent, options.model);