@tickernelz/wardmote 2026.1113.0 → 2026.1114.0

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_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,23 @@ 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;
16634
16639
  SPEECH_TO_TEXT_DEFAULTS = {
16635
16640
  enabled: false,
16641
+ provider: "openai_compatible",
16636
16642
  baseUrl: "",
16637
16643
  model: "",
16638
16644
  apiKeyEnvVar: "",
16645
+ language: "",
16646
+ diarize: false,
16647
+ keyterms: [],
16648
+ deepgram: { smartFormat: true },
16649
+ elevenlabs: { tagAudioEvents: false, numSpeakers: null },
16650
+ google: { location: "us", projectId: "", autoPunctuation: true, alternativeLanguages: [] },
16639
16651
  maxAudioSeconds: 600,
16640
16652
  sttWaitSeconds: 15
16641
16653
  };
@@ -17215,7 +17227,10 @@ function isSpeechToTextBaseUrl(value) {
17215
17227
  if (url.username || url.password || url.search || url.hash) return false;
17216
17228
  return ["/", "/v1", "/v1/"].includes(url.pathname);
17217
17229
  }
17218
- var messageDeliverySchema, backupRetentionPolicySchema, speechToTextSettingsSchema, attachmentMaxMegabytesSchema, attachmentRetentionSettingsSchema, localRunLimitsSettingsSchema, instanceGeneralSettingsSchema, patchInstanceGeneralSettingsSchema, instanceExperimentalSettingsSchema, patchInstanceExperimentalSettingsSchema, patchInstanceSettingsSchema, MAX_TASK_DRAIN_TTL_MS, startTaskDrainRequestSchema, instanceSettingsSchema;
17230
+ function isGoogleChirpModel(model) {
17231
+ return model.startsWith("chirp");
17232
+ }
17233
+ var messageDeliverySchema, backupRetentionPolicySchema, speechToTextProviderSchema, speechToTextBaseUrlSchema, speechToTextApiKeyEnvVarSchema, speechToTextKeytermSchema, speechToTextGoogleLocationSchema, speechToTextGoogleProjectIdSchema, speechToTextLanguageCodeSchema, speechToTextSettingsSchema, speechToTextModelListRequestSchema, attachmentMaxMegabytesSchema, attachmentRetentionSettingsSchema, localRunLimitsSettingsSchema, instanceGeneralSettingsSchema, patchInstanceGeneralSettingsSchema, instanceExperimentalSettingsSchema, patchInstanceExperimentalSettingsSchema, patchInstanceSettingsSchema, MAX_TASK_DRAIN_TTL_MS, startTaskDrainRequestSchema, instanceSettingsSchema;
17219
17234
  var init_instance2 = __esm({
17220
17235
  "../packages/shared/src/validators/instance.ts"() {
17221
17236
  "use strict";
@@ -17231,20 +17246,69 @@ var init_instance2 = __esm({
17231
17246
  monthlyMonths: presetSchema(MONTHLY_RETENTION_PRESETS, "monthlyMonths").default(DEFAULT_BACKUP_RETENTION.monthlyMonths),
17232
17247
  maxFiles: z40.number().int().min(BACKUP_MAX_FILES_MIN).max(BACKUP_MAX_FILES_MAX).nullable().default(DEFAULT_BACKUP_RETENTION.maxFiles)
17233
17248
  });
17249
+ speechToTextProviderSchema = z40.enum(SPEECH_TO_TEXT_PROVIDERS);
17250
+ speechToTextBaseUrlSchema = z40.string().trim().max(2048).refine(isSpeechToTextBaseUrl, {
17251
+ message: "Speech-to-text base URL must be an http(s) origin or end at /v1, without credentials, query or fragment"
17252
+ });
17253
+ speechToTextApiKeyEnvVarSchema = z40.string().trim().max(128).regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/, {
17254
+ message: "Speech-to-text API key must name a server environment variable, not hold the key itself"
17255
+ });
17256
+ speechToTextKeytermSchema = z40.string().trim().min(1).max(SPEECH_TO_TEXT_KEYTERM_MAX_LENGTH).regex(/^[^<>{}[\]\\]+$/, { message: "Keyterms cannot contain < > { } [ ] or \\" });
17257
+ 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" });
17258
+ 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" });
17259
+ 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
17260
  speechToTextSettingsSchema = z40.object({
17235
17261
  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),
17262
+ provider: speechToTextProviderSchema.default(SPEECH_TO_TEXT_DEFAULTS.provider),
17263
+ baseUrl: speechToTextBaseUrlSchema.default(SPEECH_TO_TEXT_DEFAULTS.baseUrl),
17239
17264
  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),
17265
+ apiKeyEnvVar: speechToTextApiKeyEnvVarSchema.default(SPEECH_TO_TEXT_DEFAULTS.apiKeyEnvVar),
17266
+ language: z40.string().trim().max(35).regex(/^(?:multi|[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*)?$/, {
17267
+ message: "Speech-to-text language must be empty for automatic detection, a language code such as en or pt-BR, or multi"
17268
+ }).default(SPEECH_TO_TEXT_DEFAULTS.language),
17269
+ diarize: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.diarize),
17270
+ keyterms: z40.array(speechToTextKeytermSchema).max(SPEECH_TO_TEXT_KEYTERMS_MAX).default(SPEECH_TO_TEXT_DEFAULTS.keyterms),
17271
+ deepgram: z40.object({ smartFormat: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.deepgram.smartFormat) }).strict().default(SPEECH_TO_TEXT_DEFAULTS.deepgram),
17272
+ elevenlabs: z40.object({
17273
+ tagAudioEvents: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs.tagAudioEvents),
17274
+ numSpeakers: z40.number().int().min(1).max(SPEECH_TO_TEXT_MAX_SPEAKERS).nullable().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs.numSpeakers)
17275
+ }).strict().default(SPEECH_TO_TEXT_DEFAULTS.elevenlabs),
17276
+ google: z40.object({
17277
+ location: speechToTextGoogleLocationSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.location),
17278
+ projectId: speechToTextGoogleProjectIdSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.projectId),
17279
+ autoPunctuation: z40.boolean().default(SPEECH_TO_TEXT_DEFAULTS.google.autoPunctuation),
17280
+ alternativeLanguages: z40.array(speechToTextLanguageCodeSchema).max(SPEECH_TO_TEXT_GOOGLE_MAX_LANGUAGES - 1).default(SPEECH_TO_TEXT_DEFAULTS.google.alternativeLanguages)
17281
+ }).strict().default(SPEECH_TO_TEXT_DEFAULTS.google),
17243
17282
  maxAudioSeconds: z40.number().int().min(1).max(7200).default(SPEECH_TO_TEXT_DEFAULTS.maxAudioSeconds),
17244
17283
  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"
17284
+ }).strict().refine(
17285
+ (value) => !value.enabled || value.model !== "" && value.apiKeyEnvVar !== "" && (value.provider !== "openai_compatible" || value.baseUrl !== ""),
17286
+ {
17287
+ message: "Speech-to-text needs a model, an API key environment variable and, for OpenAI-compatible endpoints, a base URL before it can be enabled"
17288
+ }
17289
+ ).superRefine((value, ctx) => {
17290
+ if (value.provider !== "google") return;
17291
+ if (value.language === "multi")
17292
+ 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" });
17293
+ const chirp = isGoogleChirpModel(value.model);
17294
+ if (value.model !== "" && !chirp && value.language === "")
17295
+ ctx.addIssue({ code: "custom", path: ["language"], message: "Google models other than Chirp need a language; only Chirp detects it automatically" });
17296
+ if (value.google.alternativeLanguages.length > 0 && (chirp || value.language === ""))
17297
+ ctx.addIssue({
17298
+ code: "custom",
17299
+ path: ["google", "alternativeLanguages"],
17300
+ message: "Google alternative languages need a primary language and the long, short or telephony model"
17301
+ });
17247
17302
  });
17303
+ speechToTextModelListRequestSchema = z40.object({
17304
+ provider: speechToTextProviderSchema,
17305
+ baseUrl: speechToTextBaseUrlSchema.default(""),
17306
+ apiKeyEnvVar: speechToTextApiKeyEnvVarSchema.default(""),
17307
+ google: z40.object({
17308
+ location: speechToTextGoogleLocationSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.location),
17309
+ projectId: speechToTextGoogleProjectIdSchema.default(SPEECH_TO_TEXT_DEFAULTS.google.projectId)
17310
+ }).strict().optional()
17311
+ }).strict();
17248
17312
  attachmentMaxMegabytesSchema = z40.number().int().min(ATTACHMENT_MAX_MEGABYTES_MIN).max(ATTACHMENT_MAX_MEGABYTES_MAX);
17249
17313
  attachmentRetentionSettingsSchema = z40.object({
17250
17314
  enabled: z40.boolean().default(DEFAULT_ATTACHMENT_RETENTION.enabled),
@@ -20507,7 +20571,7 @@ var init_config_schema = __esm({
20507
20571
  baseDir: z70.string().default("~/.wardmote/instances/default/data/storage")
20508
20572
  }).passthrough();
20509
20573
  storageS3ConfigSchema = z70.object({
20510
- bucket: z70.string().min(1).default("paperclip"),
20574
+ bucket: z70.string().min(1).default("wardmote"),
20511
20575
  region: z70.string().min(1).default("us-east-1"),
20512
20576
  endpoint: z70.string().optional(),
20513
20577
  prefix: z70.string().default(""),
@@ -20519,7 +20583,7 @@ var init_config_schema = __esm({
20519
20583
  baseDir: "~/.wardmote/instances/default/data/storage"
20520
20584
  }),
20521
20585
  s3: storageS3ConfigSchema.default({
20522
- bucket: "paperclip",
20586
+ bucket: "wardmote",
20523
20587
  region: "us-east-1",
20524
20588
  prefix: "",
20525
20589
  forcePathStyle: false
@@ -20584,7 +20648,7 @@ var init_config_schema = __esm({
20584
20648
  baseDir: "~/.wardmote/instances/default/data/storage"
20585
20649
  },
20586
20650
  s3: {
20587
- bucket: "paperclip",
20651
+ bucket: "wardmote",
20588
20652
  region: "us-east-1",
20589
20653
  prefix: "",
20590
20654
  forcePathStyle: false
@@ -21732,7 +21796,7 @@ var init_announcements = __esm({
21732
21796
  secondaryLink: announcementActionSchema.optional(),
21733
21797
  primaryAction: announcementActionSchema,
21734
21798
  expiresAt: z80.string().datetime({ offset: true }).optional(),
21735
- minimumPaperclipVersion: z80.string().regex(/^\d+\.\d+\.\d+$/).optional()
21799
+ minimumWardmoteVersion: z80.string().regex(/^\d+\.\d+\.\d+$/).optional()
21736
21800
  }).strict().refine((value) => !value.animation || Boolean(value.image), {
21737
21801
  message: "An animation requires a static fallback image",
21738
21802
  path: ["image"]
@@ -21919,7 +21983,7 @@ var init_openwa_tools = __esm({
21919
21983
  "read",
21920
21984
  "List OpenWA gateway operations with category and availability on this engine and key. Filter by category or text; page with cursor.",
21921
21985
  {
21922
- category: z81.enum(["read", "write", "wa_admin", "gateway_admin", "paperclip"]).optional(),
21986
+ category: z81.enum(["read", "write", "wa_admin", "gateway_admin", "wardmote"]).optional(),
21923
21987
  query: z81.string().min(1).max(100).optional(),
21924
21988
  cursor: cursor2
21925
21989
  }
@@ -26729,6 +26793,13 @@ var init_wardmote_updates = __esm({
26729
26793
  }
26730
26794
  });
26731
26795
 
26796
+ // ../packages/shared/src/speech-to-text-languages.ts
26797
+ var init_speech_to_text_languages = __esm({
26798
+ "../packages/shared/src/speech-to-text-languages.ts"() {
26799
+ "use strict";
26800
+ }
26801
+ });
26802
+
26732
26803
  // ../packages/shared/src/index.ts
26733
26804
  var init_src = __esm({
26734
26805
  "../packages/shared/src/index.ts"() {
@@ -26877,6 +26948,7 @@ var init_src = __esm({
26877
26948
  init_agent_lifecycle();
26878
26949
  init_fast_response();
26879
26950
  init_wardmote_updates();
26951
+ init_speech_to_text_languages();
26880
26952
  }
26881
26953
  });
26882
26954
 
@@ -28263,7 +28335,7 @@ function defaultStorageConfig() {
28263
28335
  baseDir: defaultStorageBaseDir()
28264
28336
  },
28265
28337
  s3: {
28266
- bucket: "paperclip",
28338
+ bucket: "wardmote",
28267
28339
  region: "us-east-1",
28268
28340
  endpoint: void 0,
28269
28341
  prefix: "",
@@ -28315,12 +28387,12 @@ async function promptStorage(current) {
28315
28387
  s3: base.s3
28316
28388
  };
28317
28389
  }
28318
- const bucketDefault = base.s3.bucket || "paperclip";
28390
+ const bucketDefault = base.s3.bucket || "wardmote";
28319
28391
  const regionDefault = base.s3.region || "us-east-1";
28320
28392
  const bucket = await p5.text({
28321
28393
  message: "S3 bucket",
28322
28394
  defaultValue: bucketDefault,
28323
- placeholder: "paperclip",
28395
+ placeholder: "wardmote",
28324
28396
  validate: (value) => {
28325
28397
  if ((value || bucketDefault).trim().length === 0) return "Bucket is required";
28326
28398
  }
@@ -28353,7 +28425,7 @@ async function promptStorage(current) {
28353
28425
  const prefix = await p5.text({
28354
28426
  message: "Object key prefix (optional)",
28355
28427
  defaultValue: base.s3.prefix ?? "",
28356
- placeholder: "paperclip/"
28428
+ placeholder: "wardmote/"
28357
28429
  });
28358
28430
  if (p5.isCancel(prefix)) {
28359
28431
  p5.cancel("Setup cancelled.");
@@ -30999,7 +31071,7 @@ var init_chat_channels3 = __esm({
30999
31071
  companyId: uuid17("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }),
31000
31072
  endpointId: uuid17("endpoint_id").notNull(),
31001
31073
  principalId: uuid17("principal_id").notNull(),
31002
- wardmoteUserId: text23("paperclip_user_id"),
31074
+ wardmoteUserId: text23("wardmote_user_id"),
31003
31075
  status: text23("status").$type().notNull().default("pending"),
31004
31076
  confirmationTokenHash: text23("confirmation_token_hash"),
31005
31077
  expiresAt: timestamp18("expires_at", { withTimezone: true }),
@@ -41065,6 +41137,15 @@ var init_schema2 = __esm({
41065
41137
  }
41066
41138
  });
41067
41139
 
41140
+ // ../packages/db/src/retired-migration-lock.ts
41141
+ var RETIRED_MIGRATION_LOCK_KEY;
41142
+ var init_retired_migration_lock = __esm({
41143
+ "../packages/db/src/retired-migration-lock.ts"() {
41144
+ "use strict";
41145
+ RETIRED_MIGRATION_LOCK_KEY = "paperclip:migrations";
41146
+ }
41147
+ });
41148
+
41068
41149
  // ../packages/db/src/client.ts
41069
41150
  import { createHash as createHash2 } from "node:crypto";
41070
41151
  import { drizzle as drizzlePg } from "drizzle-orm/postgres-js";
@@ -41209,7 +41290,7 @@ function createDbClient(url, resolved, owner) {
41209
41290
  dedicatedDbFactories.set(db, () => createDbClient(url, {
41210
41291
  ...resolved,
41211
41292
  maxConnections: 1,
41212
- applicationName: "paperclip-workspace-finalization-lock"
41293
+ applicationName: "wardmote-workspace-finalization-lock"
41213
41294
  }, db));
41214
41295
  return db;
41215
41296
  }
@@ -41349,8 +41430,11 @@ async function applyPendingMigrationsManually(url, pendingMigrations) {
41349
41430
  try {
41350
41431
  const sql72 = await pool.reserve();
41351
41432
  try {
41352
- while (!(await sql72`
41353
- SELECT pg_try_advisory_lock(hashtextextended('paperclip:migrations', 0)) AS locked`)[0]?.locked) {
41433
+ for (; ; ) {
41434
+ const [held] = await sql72.unsafe(MIGRATION_LOCK_TRY_SQL);
41435
+ if (held?.current && held.retired) break;
41436
+ if (held?.current) await sql72.unsafe(`SELECT pg_advisory_unlock(hashtextextended('${MIGRATION_LOCK_KEY}', 0))`);
41437
+ if (held?.retired) await sql72.unsafe(`SELECT pg_advisory_unlock(hashtextextended('${RETIRED_MIGRATION_LOCK_KEY}', 0))`);
41354
41438
  await new Promise((resolve3) => setTimeout(resolve3, 100));
41355
41439
  }
41356
41440
  const { migrationTableSchema, columnNames } = await ensureMigrationJournalTable(sql72);
@@ -41404,7 +41488,7 @@ async function applyPendingMigrationsManually(url, pendingMigrations) {
41404
41488
  }
41405
41489
  } finally {
41406
41490
  try {
41407
- await sql72`SELECT pg_advisory_unlock(hashtextextended('paperclip:migrations', 0))`;
41491
+ await sql72.unsafe(MIGRATION_LOCK_RELEASE_SQL);
41408
41492
  } catch {
41409
41493
  }
41410
41494
  sql72.release();
@@ -41882,15 +41966,19 @@ async function resetPostgresDatabase(url, databaseName) {
41882
41966
  await sql72.end();
41883
41967
  }
41884
41968
  }
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;
41969
+ 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
41970
  var init_client = __esm({
41887
41971
  "../packages/db/src/client.ts"() {
41888
41972
  "use strict";
41889
41973
  init_work_signals();
41890
41974
  init_schema2();
41975
+ init_retired_migration_lock();
41891
41976
  MIGRATIONS_FOLDER = fileURLToPath2(new URL("./migrations", import.meta.url));
41892
41977
  DRIZZLE_MIGRATIONS_TABLE = "__drizzle_migrations";
41893
41978
  MIGRATIONS_JOURNAL_JSON = fileURLToPath2(new URL("./migrations/meta/_journal.json", import.meta.url));
41979
+ MIGRATION_LOCK_KEY = "wardmote:migrations";
41980
+ 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`;
41981
+ MIGRATION_LOCK_RELEASE_SQL = `SELECT pg_advisory_unlock(hashtextextended('${MIGRATION_LOCK_KEY}', 0)), pg_advisory_unlock(hashtextextended('${RETIRED_MIGRATION_LOCK_KEY}', 0))`;
41894
41982
  clientsByHostPort = /* @__PURE__ */ new Map();
41895
41983
  clientFinalizer = new FinalizationRegistry(
41896
41984
  ({ hostPortKey: hostPortKey2, ref }) => {
@@ -47888,6 +47976,16 @@ var init_test_embedded_postgres = __esm({
47888
47976
  }
47889
47977
  });
47890
47978
 
47979
+ // ../packages/db/src/retired-backup-names.ts
47980
+ var RETIRED_BACKUP_FILENAME_PREFIX, RETIRED_STATEMENT_BREAKPOINT;
47981
+ var init_retired_backup_names = __esm({
47982
+ "../packages/db/src/retired-backup-names.ts"() {
47983
+ "use strict";
47984
+ RETIRED_BACKUP_FILENAME_PREFIX = "paperclip";
47985
+ RETIRED_STATEMENT_BREAKPOINT = "-- paperclip statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
47986
+ }
47987
+ });
47988
+
47891
47989
  // ../packages/db/src/backup-lib.ts
47892
47990
  import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statfsSync, statSync, unlinkSync, writeFileSync } from "node:fs";
47893
47991
  import { basename, join as join2, resolve as resolve2 } from "node:path";
@@ -47899,6 +47997,9 @@ import { pipeline } from "node:stream/promises";
47899
47997
  import { createGunzip, createGzip } from "node:zlib";
47900
47998
  import postgres3 from "postgres";
47901
47999
  import { randomUUID as randomUUID3 } from "node:crypto";
48000
+ function isStatementBreakpoint(line) {
48001
+ return line === STATEMENT_BREAKPOINT || line === RETIRED_STATEMENT_BREAKPOINT;
48002
+ }
47902
48003
  function sanitizeRestoreErrorMessage(error) {
47903
48004
  if (error && typeof error === "object") {
47904
48005
  const record2 = error;
@@ -48157,9 +48258,9 @@ function formatBackupSize(sizeBytes) {
48157
48258
  }
48158
48259
  function formatSqlLiteral(value) {
48159
48260
  const sanitized = value.replace(/\u0000/g, "");
48160
- let tag = "$paperclip$";
48261
+ let tag = "$wardmote$";
48161
48262
  while (sanitized.includes(tag)) {
48162
- tag = `$paperclip_${Math.random().toString(36).slice(2, 8)}$`;
48263
+ tag = `$wardmote_${Math.random().toString(36).slice(2, 8)}$`;
48163
48264
  }
48164
48265
  return `${tag}${sanitized}${tag}`;
48165
48266
  }
@@ -48312,10 +48413,10 @@ async function hasStatementBreakpoints(backupFile) {
48312
48413
  try {
48313
48414
  for await (const chunk of stream) {
48314
48415
  text169 += Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
48315
- if (text169.includes(STATEMENT_BREAKPOINT)) return true;
48416
+ if (text169.includes(STATEMENT_BREAKPOINT) || text169.includes(RETIRED_STATEMENT_BREAKPOINT)) return true;
48316
48417
  if (Buffer.byteLength(text169, "utf8") >= BACKUP_BREAKPOINT_DETECT_BYTES) return false;
48317
48418
  }
48318
- return text169.includes(STATEMENT_BREAKPOINT);
48419
+ return text169.includes(STATEMENT_BREAKPOINT) || text169.includes(RETIRED_STATEMENT_BREAKPOINT);
48319
48420
  } finally {
48320
48421
  stream.destroy();
48321
48422
  raw.destroy();
@@ -48337,7 +48438,7 @@ async function* readRestoreStatements(backupFile) {
48337
48438
  };
48338
48439
  try {
48339
48440
  for await (const line of reader) {
48340
- if (line === STATEMENT_BREAKPOINT) {
48441
+ if (isStatementBreakpoint(line)) {
48341
48442
  const statement = flushStatement();
48342
48443
  if (statement.length > 0) {
48343
48444
  yield statement;
@@ -48961,15 +49062,16 @@ function formatDatabaseBackupResult(result) {
48961
49062
  const unreadable = result.unreadableBackups?.length ? `; kept ${result.unreadableBackups.length} unreadable backup(s)` : "";
48962
49063
  return `${result.backupFile} (${size}${pruned}${unreadable})`;
48963
49064
  }
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;
49065
+ 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
49066
  var init_backup_lib = __esm({
48966
49067
  "../packages/db/src/backup-lib.ts"() {
48967
49068
  "use strict";
49069
+ init_retired_backup_names();
48968
49070
  DEFAULT_BACKUP_WRITE_BUFFER_BYTES = 1024 * 1024;
48969
49071
  BACKUP_DATA_CURSOR_ROWS = 100;
48970
49072
  BACKUP_CLI_STDERR_BYTES = 64 * 1024;
48971
49073
  BACKUP_BREAKPOINT_DETECT_BYTES = 64 * 1024;
48972
- STATEMENT_BREAKPOINT = "-- paperclip statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
49074
+ STATEMENT_BREAKPOINT = "-- wardmote statement breakpoint 69f6f3f1-42fd-46a6-bf17-d1d85f8f3900";
48973
49075
  DATABASE_BACKUP_FILENAME_PREFIX = "wardmote";
48974
49076
  PINNED_BACKUP_DIRNAME = "pinned";
48975
49077
  DATABASE_BACKUP_SKIPPED_MARKER = "backup-skipped.json";
@@ -48991,7 +49093,6 @@ var init_backup_lib = __esm({
48991
49093
  code = "database_backup_skipped_low_disk";
48992
49094
  };
48993
49095
  verifiedBackups = /* @__PURE__ */ new Map();
48994
- RETIRED_BACKUP_FILENAME_PREFIX = "paperclip";
48995
49096
  PARTIAL_BACKUP_PATTERN = /\.(\d+)\.partial$/;
48996
49097
  ABANDONED_PARTIAL_BACKUP_AGE_MS = 24 * 60 * 60 * 1e3;
48997
49098
  activePartialBackupFiles = /* @__PURE__ */ new Set();
@@ -49736,7 +49837,7 @@ var init_client2 = __esm({
49736
49837
  buildEnvelope(events, batchId) {
49737
49838
  const state = this.getState();
49738
49839
  return {
49739
- app: this.config.app ?? "paperclip",
49840
+ app: this.config.app ?? "wardmote",
49740
49841
  schemaVersion: this.config.schemaVersion ?? "1",
49741
49842
  installId: state.installId,
49742
49843
  version: this.version,
@@ -50616,9 +50717,26 @@ async function resolvePublishedVersion(spec, runCommand2) {
50616
50717
  );
50617
50718
  return parseResolvedVersion(result.stdout);
50618
50719
  }
50720
+ async function resolveReleasePackageNames(version, runCommand2) {
50721
+ try {
50722
+ const result = await runCommand2(
50723
+ "npm",
50724
+ ["view", `@tickernelz/wardmote@${version}`, "wardmoteReleasePackages", "--json", `--registry=${PUBLIC_NPM_REGISTRY}`],
50725
+ { maxBuffer: 1024 * 1024 }
50726
+ );
50727
+ const declared = JSON.parse(result.stdout.trim() || "null");
50728
+ if (Array.isArray(declared) && declared.length > 0 && declared.every((name) => typeof name === "string" && name.startsWith("@tickernelz/"))) {
50729
+ return declared;
50730
+ }
50731
+ } catch {
50732
+ return RELEASE_PACKAGE_NAMES;
50733
+ }
50734
+ return RELEASE_PACKAGE_NAMES;
50735
+ }
50619
50736
  async function assertReleaseSetPublished(version, runCommand2) {
50737
+ const names = await resolveReleasePackageNames(version, runCommand2);
50620
50738
  const missing = [];
50621
- const queue = [...RELEASE_PACKAGE_NAMES];
50739
+ const queue = [...names];
50622
50740
  const probe = async () => {
50623
50741
  for (let name = queue.pop(); name !== void 0; name = queue.pop()) {
50624
50742
  try {
@@ -50633,10 +50751,10 @@ async function assertReleaseSetPublished(version, runCommand2) {
50633
50751
  }
50634
50752
  }
50635
50753
  };
50636
- await Promise.all(Array.from({ length: Math.min(8, RELEASE_PACKAGE_NAMES.length) }, probe));
50754
+ await Promise.all(Array.from({ length: Math.min(8, names.length) }, probe));
50637
50755
  if (missing.length > 0) {
50638
50756
  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.`
50757
+ `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
50758
  );
50641
50759
  }
50642
50760
  }
@@ -50912,7 +51030,7 @@ async function installCommand(options, dependencies = {}) {
50912
51030
  const request = resolveNpmInstallRequest(options);
50913
51031
  console.log(`Resolving @tickernelz/wardmote@${request.spec} from ${PUBLIC_NPM_REGISTRY}...`);
50914
51032
  const version = await resolvePublishedVersion(request.spec, runCommand2);
50915
- console.log(`Verifying all ${RELEASE_PACKAGE_NAMES.length} packages of release ${version}...`);
51033
+ console.log(`Verifying the packages of release ${version}...`);
50916
51034
  await assertReleaseSetPublished(version, runCommand2);
50917
51035
  console.log(`Installing @tickernelz/wardmote@${version}...`);
50918
51036
  const paths = resolveInstallStorePaths();
@@ -62117,7 +62235,7 @@ function buildWorktreeConfig(input2) {
62117
62235
  baseDir: paths.storageDir
62118
62236
  },
62119
62237
  s3: {
62120
- bucket: source?.storage.s3.bucket ?? "paperclip",
62238
+ bucket: source?.storage.s3.bucket ?? "wardmote",
62121
62239
  region: source?.storage.s3.region ?? "us-east-1",
62122
62240
  endpoint: source?.storage.s3.endpoint,
62123
62241
  prefix: source?.storage.s3.prefix ?? "",
@@ -65257,7 +65375,7 @@ async function worktreeListCommand(opts) {
65257
65375
  for (const choice of choices) {
65258
65376
  const flags = [
65259
65377
  choice.isCurrent ? "current" : null,
65260
- choice.hasWardmoteConfig ? "paperclip" : "no-paperclip-config"
65378
+ choice.hasWardmoteConfig ? "wardmote" : "no-wardmote-config"
65261
65379
  ].filter((value) => value !== null);
65262
65380
  p11.log.message(`${choice.branchLabel} ${choice.worktree} [${flags.join(", ")}]`);
65263
65381
  }
@@ -68014,7 +68132,7 @@ function collectDeploymentEnvRows(config, configPath) {
68014
68132
  const secretsKeyFilePath = process.env.WARDMOTE_SECRETS_MASTER_KEY_FILE ?? config?.secrets?.localEncrypted?.keyFilePath ?? defaultSecretsKeyFilePath();
68015
68133
  const storageProvider = process.env.WARDMOTE_STORAGE_PROVIDER ?? config?.storage?.provider ?? DEFAULT_STORAGE_PROVIDER;
68016
68134
  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";
68135
+ const storageS3Bucket = process.env.WARDMOTE_STORAGE_S3_BUCKET ?? config?.storage?.s3?.bucket ?? "wardmote";
68018
68136
  const storageS3Region = process.env.WARDMOTE_STORAGE_S3_REGION ?? config?.storage?.s3?.region ?? "us-east-1";
68019
68137
  const storageS3Endpoint = process.env.WARDMOTE_STORAGE_S3_ENDPOINT ?? config?.storage?.s3?.endpoint ?? "";
68020
68138
  const storageS3Prefix = process.env.WARDMOTE_STORAGE_S3_PREFIX ?? config?.storage?.s3?.prefix ?? "";
@@ -68274,7 +68392,7 @@ async function channelsCommand(options = {}, runCommand2 = defaultRunCommand) {
68274
68392
  } else {
68275
68393
  console.log(`This install is version ${pc12.bold(packageVersion)} on the ${pc12.bold(currentChannel)} channel.`);
68276
68394
  }
68277
- console.log(`Docker images use the same names: ghcr.io/paperclipai/paperclip:{latest,beta,nightly,canary}`);
68395
+ console.log("Docker images are built from source; see doc/DOCKER.md.");
68278
68396
  }
68279
68397
 
68280
68398
  // src/commands/configure.ts
@@ -76465,7 +76583,7 @@ function scaffoldPluginProject(options) {
76465
76583
  worker: "./dist/worker.js",
76466
76584
  ui: "./dist/ui/"
76467
76585
  },
76468
- keywords: ["paperclip", "plugin", category],
76586
+ keywords: ["wardmote", "plugin", category],
76469
76587
  author,
76470
76588
  license: "MIT",
76471
76589
  ...packedSharedTarball ? {
@@ -79508,7 +79626,7 @@ async function listAll(key, path53) {
79508
79626
  }
79509
79627
  function resourceByProfile(resources, profileKey, resourceLabel) {
79510
79628
  const matches = resources.filter(
79511
- (resource) => typeof resource.id === "string" && record(resource.metadata).paperclip_profile === profileKey
79629
+ (resource) => typeof resource.id === "string" && record(resource.metadata).wardmote_profile === profileKey
79512
79630
  );
79513
79631
  if (matches.length > 1) {
79514
79632
  throw new Error(
@@ -79576,7 +79694,7 @@ async function resolveEnvironment(key, options) {
79576
79694
  pip: []
79577
79695
  }
79578
79696
  },
79579
- metadata: { paperclip_profile: options.profileKey }
79697
+ metadata: { wardmote_profile: options.profileKey }
79580
79698
  });
79581
79699
  assertSafeManagedEnvironment(environment);
79582
79700
  return environment;
@@ -79611,7 +79729,7 @@ async function resolveAgent3(key, options) {
79611
79729
  tools: [],
79612
79730
  mcp_servers: [],
79613
79731
  skills: [],
79614
- metadata: { paperclip_profile: options.profileKey }
79732
+ metadata: { wardmote_profile: options.profileKey }
79615
79733
  });
79616
79734
  assertSafeManagedAgent(agent);
79617
79735
  assertManagedAgentModel(agent, options.model);