CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / integration (push) Successful in 49s
CI & Build / TypeScript typecheck (push) Successful in 57s
CI & Build / Python tests (push) Failing after 1m3s
CI & Build / Build & push image (push) Skipped
A rule's home is its scope now: a rule in a rulebook topic is global, a rule on a project applies to that project, and retrieval reads that directly (#4074). A subscription had stopped changing anything a session received; a suppression muted rules from a subscription. Operator, 2026-09-15: "we have global and project scoped rules, we don't need the subscriptions now." What goes, whole (rule 22): - Migration 0101 drops project_rulebook_subscriptions, project_rule_suppressions and project_topic_suppressions, and strips subscribe_rulebooks (and 394's leftover exclude_always_on_rulebooks) from stored inception choices. - Service, MCP and REST: subscribe/unsubscribe and the four suppress/unsuppress operations. The Subscribers checklist, the subscribe chips, the skip buttons and the Suppressed section in the rules UI. - Inception asks two questions (design system, seed Systems). create_project and decide_project_inception lose subscribe_rulebooks. - Backup v15 stops exporting the three sections; older archives still restore, the keys simply unread. Trash no longer hard-deletes suppression rows. What changes meaning: - get_applicable_rules is a project's LISTING: its own rules, plus the global rules tagged to an area it works in. Untagged global rules apply everywhere and arrive by retrieval, so they are not listed. A co_surfaces partner on a different project is not dragged in. - list_rules(project_id) lists that project's own rules. - rules_payload drops subscribed_rulebooks and suppressed_*; the handshake's brief form is project_rules alone. - using-scribe's "Where a new rule goes" and inception sections, tool docstrings and docs say global vs project. Plugin 2026.09.15.1620. Milestone 414 step 2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
76 lines
2.4 KiB
Vue
76 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from "vue";
|
|
import { useRulebooksStore } from "@/stores/rulebooks";
|
|
import type { RulebookTopic } from "@/api/rulebooks";
|
|
|
|
// A rulebook's rules are global — they apply to every project — so this pane
|
|
// lists topics and nothing else. It carried a "Subscribers" checklist of
|
|
// projects until milestone 414 retired subscriptions.
|
|
const props = defineProps<{
|
|
rulebookId: number;
|
|
topics: RulebookTopic[];
|
|
selectedTopicId: number | null;
|
|
}>();
|
|
const emit = defineEmits<{ "select-topic": [id: number] }>();
|
|
|
|
const store = useRulebooksStore();
|
|
const isCreating = ref(false);
|
|
const newTitle = ref("");
|
|
|
|
async function submitNew() {
|
|
const title = newTitle.value.trim();
|
|
if (!title) return;
|
|
const topic = await store.createTopic(props.rulebookId, { title });
|
|
newTitle.value = "";
|
|
isCreating.value = false;
|
|
emit("select-topic", topic.id);
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<section class="pane">
|
|
<header>
|
|
<h2>Topics</h2>
|
|
</header>
|
|
<ul>
|
|
<li
|
|
v-for="t in topics"
|
|
:key="t.id"
|
|
:class="{ active: t.id === selectedTopicId }"
|
|
@click="emit('select-topic', t.id)"
|
|
>
|
|
{{ t.title }}
|
|
</li>
|
|
</ul>
|
|
<div class="new-topic">
|
|
<button v-if="!isCreating" @click="isCreating = true">+ New topic</button>
|
|
<form v-else @submit.prevent="submitNew">
|
|
<input v-model="newTitle" autofocus placeholder="Topic title (e.g. git-workflow)" />
|
|
<div class="form-buttons">
|
|
<button type="submit">Create</button>
|
|
<button type="button" @click="isCreating = false">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<style src="@/assets/rules-shared.css" />
|
|
<style scoped>
|
|
header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
|
|
ul { list-style: none; padding: 0; margin: 1rem 0; }
|
|
li { padding: 0.5rem; cursor: pointer; border-radius: 6px; }
|
|
li.active { background: var(--fs-accent-soft); }
|
|
li:hover { background: var(--fs-surface-hover); }
|
|
/* `.new-topic` is deliberately bare (#2444): it wraps a button-or-form whose
|
|
children style themselves, and namespaces the descendant rule below. */
|
|
.new-topic input {
|
|
width: 100%; margin-bottom: 0.5rem;
|
|
background: var(--fs-surface-page); color: inherit;
|
|
border: 1px solid var(--fs-border-color); border-radius: 6px;
|
|
padding: 0.5rem;
|
|
}
|
|
button { cursor: pointer; }
|
|
</style>
|