diff --git a/appinfo/info.xml b/appinfo/info.xml
index 941ac62d..a1c960ab 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -50,6 +50,7 @@ Refer to the [Context Chat Backend's readme](https://github.com/nextcloud/contex
OCA\ContextChat\Command\Prompt
OCA\ContextChat\Command\Search
OCA\ContextChat\Command\Statistics
+ OCA\ContextChat\Command\Reindex
diff --git a/lib/Command/Reindex.php b/lib/Command/Reindex.php
new file mode 100644
index 00000000..c6906a5c
--- /dev/null
+++ b/lib/Command/Reindex.php
@@ -0,0 +1,51 @@
+ StorageCrawlJob -> IndexerJob is seeded only by the repair step and
+ * removes itself once the initial crawl finishes. There is otherwise no way to re-enumerate
+ * mounts (e.g. after installing on an instance whose files predate the app, or to recover a crawl
+ * that did not complete) short of reinstalling the app. This command re-adds SchedulerJob so the
+ * full enumeration runs again; it is a no-op if one is already scheduled, and already-indexed
+ * files are skipped (the queue de-duplicates).
+ */
+class Reindex extends Command {
+
+ public function __construct(
+ private IJobList $jobList,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this->setName('context_chat:reindex')
+ ->setDescription('Schedule a full re-crawl of all mounts (re-seeds the indexing chain; indexed files are skipped)');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ if ($this->jobList->has(SchedulerJob::class, null)) {
+ $output->writeln('A full re-crawl is already scheduled; nothing to do.');
+ return 0;
+ }
+
+ $this->jobList->add(SchedulerJob::class);
+ $output->writeln('Scheduled a full re-crawl. SchedulerJob will enumerate all mounts on its next run.');
+ return 0;
+ }
+}