sensorium-mcp 3.1.3-board.4 → 3.1.3-board.5
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/board/components/Card.js +10 -1
- package/dist/board/components/Combobox.js +78 -0
- package/dist/board/components/CommentComposer.js +4 -1
- package/dist/board/components/Lane.js +6 -1
- package/dist/board/components/StateBanner.js +5 -3
- package/dist/board/components/StatusChip.js +1 -0
- package/dist/board/components/rateLimit.js +19 -0
- package/dist/board/mock/fixtures.js +34 -0
- package/dist/board/schema/policy.js +137 -72
- package/dist/board/styles/board.css +460 -3
- package/dist/board/views/BoardView.js +8 -2
- package/dist/board/views/BuilderView.js +334 -29
- package/dist/board/views/CardView.js +36 -17
- package/dist/config/detail-grant.d.ts +7 -16
- package/dist/config/detail-grant.d.ts.map +1 -1
- package/dist/config/detail-grant.js +12 -35
- package/dist/config/detail-grant.js.map +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/misc-settings.d.ts +2 -1
- package/dist/config/misc-settings.d.ts.map +1 -1
- package/dist/config/misc-settings.js +14 -8
- package/dist/config/misc-settings.js.map +1 -1
- package/dist/config/operator-grant.d.ts +9 -0
- package/dist/config/operator-grant.d.ts.map +1 -0
- package/dist/config/operator-grant.js +24 -0
- package/dist/config/operator-grant.js.map +1 -0
- package/dist/config/voice-grant.d.ts +10 -0
- package/dist/config/voice-grant.d.ts.map +1 -0
- package/dist/config/voice-grant.js +18 -0
- package/dist/config/voice-grant.js.map +1 -0
- package/dist/dashboard/presets.d.ts +1 -1
- package/dist/dashboard/presets.d.ts.map +1 -1
- package/dist/dashboard/presets.js +1 -1
- package/dist/dashboard/presets.js.map +1 -1
- package/dist/dashboard/routes/board.d.ts +2 -0
- package/dist/dashboard/routes/board.d.ts.map +1 -1
- package/dist/dashboard/routes/board.js +171 -0
- package/dist/dashboard/routes/board.js.map +1 -1
- package/dist/dashboard/routes/prompts.d.ts +2 -2
- package/dist/dashboard/routes/prompts.d.ts.map +1 -1
- package/dist/dashboard/routes/prompts.js +2 -2
- package/dist/dashboard/routes/prompts.js.map +1 -1
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +2 -1
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/spa.html +5 -5
- package/dist/data/memory/bootstrap.d.ts +0 -7
- package/dist/data/memory/bootstrap.d.ts.map +1 -1
- package/dist/data/memory/bootstrap.js +6 -25
- package/dist/data/memory/bootstrap.js.map +1 -1
- package/dist/data/memory/index.d.ts +0 -4
- package/dist/data/memory/index.d.ts.map +1 -1
- package/dist/data/memory/index.js +0 -4
- package/dist/data/memory/index.js.map +1 -1
- package/dist/data/memory/key-knowledge.d.ts +13 -0
- package/dist/data/memory/key-knowledge.d.ts.map +1 -1
- package/dist/data/memory/key-knowledge.js +11 -1
- package/dist/data/memory/key-knowledge.js.map +1 -1
- package/dist/data/memory/narrative-resolutions.d.ts +9 -9
- package/dist/data/memory/narrative-resolutions.d.ts.map +1 -1
- package/dist/data/memory/narrative-resolutions.js +9 -15
- package/dist/data/memory/narrative-resolutions.js.map +1 -1
- package/dist/data/memory/narrative-store.d.ts +10 -0
- package/dist/data/memory/narrative-store.d.ts.map +1 -1
- package/dist/data/memory/narrative-store.js +37 -35
- package/dist/data/memory/narrative-store.js.map +1 -1
- package/dist/data/memory/narrative.d.ts.map +1 -1
- package/dist/data/memory/narrative.js +2 -4
- package/dist/data/memory/narrative.js.map +1 -1
- package/dist/data/memory/note-embeddings.d.ts +7 -0
- package/dist/data/memory/note-embeddings.d.ts.map +1 -1
- package/dist/data/memory/note-embeddings.js +6 -2
- package/dist/data/memory/note-embeddings.js.map +1 -1
- package/dist/data/memory/semantic-notes.d.ts +4 -7
- package/dist/data/memory/semantic-notes.d.ts.map +1 -1
- package/dist/data/memory/semantic-notes.js +8 -15
- package/dist/data/memory/semantic-notes.js.map +1 -1
- package/dist/integrations/telegram/types.d.ts +11 -0
- package/dist/integrations/telegram/types.d.ts.map +1 -1
- package/dist/services/consolidation.service.d.ts.map +1 -1
- package/dist/services/consolidation.service.js +1 -43
- package/dist/services/consolidation.service.js.map +1 -1
- package/dist/services/daily-session.d.ts +2 -2
- package/dist/services/daily-session.d.ts.map +1 -1
- package/dist/services/daily-session.js +11 -11
- package/dist/services/daily-session.js.map +1 -1
- package/dist/services/dispatcher/broker.d.ts +9 -0
- package/dist/services/dispatcher/broker.d.ts.map +1 -1
- package/dist/services/dispatcher/broker.js.map +1 -1
- package/dist/services/dispatcher/poller.d.ts.map +1 -1
- package/dist/services/dispatcher/poller.js +31 -24
- package/dist/services/dispatcher/poller.js.map +1 -1
- package/dist/services/memory-briefing.service.d.ts.map +1 -1
- package/dist/services/memory-briefing.service.js +15 -63
- package/dist/services/memory-briefing.service.js.map +1 -1
- package/dist/services/predefined-prompts.d.ts +11 -0
- package/dist/services/predefined-prompts.d.ts.map +1 -0
- package/dist/services/predefined-prompts.js +25 -0
- package/dist/services/predefined-prompts.js.map +1 -0
- package/dist/tools/defs/memory-defs.d.ts.map +1 -1
- package/dist/tools/defs/memory-defs.js +8 -4
- package/dist/tools/defs/memory-defs.js.map +1 -1
- package/dist/tools/defs/session-defs.js +2 -2
- package/dist/tools/defs/session-defs.js.map +1 -1
- package/dist/tools/defs/utility-defs.js +1 -1
- package/dist/tools/defs/utility-defs.js.map +1 -1
- package/dist/tools/memory-tools.d.ts.map +1 -1
- package/dist/tools/memory-tools.js +58 -9
- package/dist/tools/memory-tools.js.map +1 -1
- package/dist/tools/session-tools.js +3 -10
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/start-session-tool.d.ts.map +1 -1
- package/dist/tools/start-session-tool.js +12 -0
- package/dist/tools/start-session-tool.js.map +1 -1
- package/dist/tools/utility-tools.d.ts.map +1 -1
- package/dist/tools/utility-tools.js +31 -0
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/wait/drive-handler.d.ts.map +1 -1
- package/dist/tools/wait/drive-handler.js +1 -11
- package/dist/tools/wait/drive-handler.js.map +1 -1
- package/dist/tools/wait/message-delivery.d.ts +9 -6
- package/dist/tools/wait/message-delivery.d.ts.map +1 -1
- package/dist/tools/wait/message-delivery.js +71 -65
- package/dist/tools/wait/message-delivery.js.map +1 -1
- package/dist/tools/wait/poll-loop.d.ts.map +1 -1
- package/dist/tools/wait/poll-loop.js +6 -0
- package/dist/tools/wait/poll-loop.js.map +1 -1
- package/package.json +1 -1
- package/templates/increment-pr-pipeline.default.md +79 -0
- package/dist/data/memory/reflection-dedup.d.ts +0 -17
- package/dist/data/memory/reflection-dedup.d.ts.map +0 -1
- package/dist/data/memory/reflection-dedup.js +0 -55
- package/dist/data/memory/reflection-dedup.js.map +0 -1
- package/dist/data/memory/reflection-gates.d.ts +0 -40
- package/dist/data/memory/reflection-gates.d.ts.map +0 -1
- package/dist/data/memory/reflection-gates.js +0 -220
- package/dist/data/memory/reflection-gates.js.map +0 -1
- package/dist/data/memory/reflection-sources.d.ts +0 -13
- package/dist/data/memory/reflection-sources.d.ts.map +0 -1
- package/dist/data/memory/reflection-sources.js +0 -115
- package/dist/data/memory/reflection-sources.js.map +0 -1
- package/dist/data/memory/reflection.d.ts +0 -43
- package/dist/data/memory/reflection.d.ts.map +0 -1
- package/dist/data/memory/reflection.js +0 -329
- package/dist/data/memory/reflection.js.map +0 -1
- package/dist/llm/prompts/reflection.d.ts +0 -6
- package/dist/llm/prompts/reflection.d.ts.map +0 -1
- package/dist/llm/prompts/reflection.js +0 -77
- package/dist/llm/prompts/reflection.js.map +0 -1
- package/templates/atomic-build-spec.default.md +0 -57
- package/templates/daily-review.default.md +0 -26
- package/templates/fire-and-forget.default.md +0 -76
- package/templates/offload.default.md +0 -33
- package/templates/phased-build.default.md +0 -59
- package/templates/sensorium-repair.default.md +0 -114
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import StatusChip from "./StatusChip.js";
|
|
8
8
|
import PriorityChip from "./PriorityChip.js";
|
|
9
|
+
import { providerLabel, retryLabel } from "./rateLimit.js";
|
|
9
10
|
|
|
10
11
|
export default {
|
|
11
12
|
name: "Card",
|
|
@@ -21,7 +22,11 @@ export default {
|
|
|
21
22
|
const mins = Math.max(0, Math.round((Date.now() - new Date(props.card.startedAt)) / 60000));
|
|
22
23
|
return mins >= 60 ? Math.floor(mins / 60) + "h " + (mins % 60) + "m" : mins + "m";
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
function rlText() {
|
|
26
|
+
const p = providerLabel(props.card);
|
|
27
|
+
return (p ? p + " · " : "") + retryLabel(props.card);
|
|
28
|
+
}
|
|
29
|
+
return { emit, elapsed, rlText };
|
|
25
30
|
},
|
|
26
31
|
template: `
|
|
27
32
|
<article class="card" role="listitem" tabindex="0"
|
|
@@ -29,6 +34,10 @@ export default {
|
|
|
29
34
|
@keydown.enter="emit('open', card)">
|
|
30
35
|
<h3 class="card__title">{{ card.title }}</h3>
|
|
31
36
|
<p v-if="card.description" class="card__desc">{{ card.description }}</p>
|
|
37
|
+
<div v-if="card.status === 'rate_limited'" class="card__rl">
|
|
38
|
+
<svg viewBox="0 0 12 12" width="11" height="11" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" aria-hidden="true"><circle cx="6" cy="6" r="4.6"></circle><path d="M6 3.6V6l1.8 1.2"></path></svg>
|
|
39
|
+
<span>rate limited · {{ rlText() }}</span>
|
|
40
|
+
</div>
|
|
32
41
|
<div class="card__foot">
|
|
33
42
|
<PriorityChip :priority="card.priority" />
|
|
34
43
|
<span class="chip chip--muted">{{ card.type }}</span>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combobox — ✅ EDITABLE. Editable dropdown: free-text input + curated
|
|
3
|
+
* suggestions (optionally grouped). Pure: modelValue in, update:modelValue out.
|
|
4
|
+
* `groups`: [{ label|null, options: string[] }] — label null renders flat.
|
|
5
|
+
* The user may pick a suggestion OR type any value.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { computed, onMounted, onUnmounted, ref } from "../vendor/vue.esm-browser.js";
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
name: "Combobox",
|
|
12
|
+
props: {
|
|
13
|
+
modelValue: { type: String, default: "" },
|
|
14
|
+
groups: { type: Array, default: () => [] },
|
|
15
|
+
placeholder: { type: String, default: "" },
|
|
16
|
+
},
|
|
17
|
+
emits: ["update:modelValue"],
|
|
18
|
+
setup(props, { emit }) {
|
|
19
|
+
const open = ref(false);
|
|
20
|
+
const rootEl = ref(null);
|
|
21
|
+
const filtered = computed(() => {
|
|
22
|
+
const q = (props.modelValue || "").trim().toLowerCase();
|
|
23
|
+
const out = [];
|
|
24
|
+
for (const g of props.groups) {
|
|
25
|
+
const opts = q ? g.options.filter((o) => o.toLowerCase().includes(q)) : g.options;
|
|
26
|
+
if (opts.length) out.push({ label: g.label || null, options: opts });
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
});
|
|
30
|
+
function onInput(e) {
|
|
31
|
+
emit("update:modelValue", e.target.value);
|
|
32
|
+
open.value = true;
|
|
33
|
+
}
|
|
34
|
+
function pick(o) {
|
|
35
|
+
emit("update:modelValue", o);
|
|
36
|
+
open.value = false;
|
|
37
|
+
}
|
|
38
|
+
function onDoc(e) {
|
|
39
|
+
if (rootEl.value && !rootEl.value.contains(e.target)) open.value = false;
|
|
40
|
+
}
|
|
41
|
+
function onKey(e) {
|
|
42
|
+
if (e.key === "Escape") open.value = false;
|
|
43
|
+
}
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
document.addEventListener("click", onDoc, true);
|
|
46
|
+
document.addEventListener("keydown", onKey);
|
|
47
|
+
});
|
|
48
|
+
onUnmounted(() => {
|
|
49
|
+
document.removeEventListener("click", onDoc, true);
|
|
50
|
+
document.removeEventListener("keydown", onKey);
|
|
51
|
+
});
|
|
52
|
+
return { open, rootEl, filtered, onInput, pick };
|
|
53
|
+
},
|
|
54
|
+
template: `
|
|
55
|
+
<div class="dropdown combobox" ref="rootEl">
|
|
56
|
+
<div class="combobox__wrap">
|
|
57
|
+
<input class="input combobox__input" :value="modelValue" :placeholder="placeholder"
|
|
58
|
+
role="combobox" :aria-expanded="open" aria-autocomplete="list"
|
|
59
|
+
@input="onInput" @focus="open = true" />
|
|
60
|
+
<button type="button" class="combobox__toggle" :class="{ 'is-open': open }"
|
|
61
|
+
aria-label="Show suggestions" tabindex="-1" @click="open = !open">▾</button>
|
|
62
|
+
</div>
|
|
63
|
+
<ul v-if="open && filtered.length" class="dropdown__menu" role="listbox">
|
|
64
|
+
<template v-for="g in filtered" :key="g.label || '_'">
|
|
65
|
+
<li v-if="g.label" class="combobox__group" role="presentation">{{ g.label }}</li>
|
|
66
|
+
<li v-for="o in g.options" :key="o">
|
|
67
|
+
<button type="button" class="dropdown__opt" role="option"
|
|
68
|
+
:aria-selected="o === modelValue" :class="{ 'is-selected': o === modelValue }"
|
|
69
|
+
@click="pick(o)">
|
|
70
|
+
<span class="dropdown__optlabel">{{ o }}</span>
|
|
71
|
+
<span v-if="o === modelValue" class="dropdown__check">✓</span>
|
|
72
|
+
</button>
|
|
73
|
+
</li>
|
|
74
|
+
</template>
|
|
75
|
+
</ul>
|
|
76
|
+
</div>
|
|
77
|
+
`,
|
|
78
|
+
};
|
|
@@ -6,6 +6,9 @@ import { ref } from "../vendor/vue.esm-browser.js";
|
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
name: "CommentComposer",
|
|
9
|
+
props: {
|
|
10
|
+
busy: { type: Boolean, default: false },
|
|
11
|
+
},
|
|
9
12
|
emits: ["submit"],
|
|
10
13
|
setup(props, { emit }) {
|
|
11
14
|
const text = ref("");
|
|
@@ -20,7 +23,7 @@ export default {
|
|
|
20
23
|
template: `
|
|
21
24
|
<form class="composer" @submit.prevent="send">
|
|
22
25
|
<textarea class="input input--area" v-model="text" rows="2" placeholder="Add a comment…"></textarea>
|
|
23
|
-
<button class="btn btn--primary" type="submit" :disabled="!text.trim()">Comment</button>
|
|
26
|
+
<button class="btn btn--primary" type="submit" :disabled="!text.trim() || busy">{{ busy ? 'Sending…' : 'Comment' }}</button>
|
|
24
27
|
</form>
|
|
25
28
|
`,
|
|
26
29
|
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import Card from "./Card.js";
|
|
7
|
+
import { computed } from "../vendor/vue.esm-browser.js";
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
name: "Lane",
|
|
@@ -16,13 +17,17 @@ export default {
|
|
|
16
17
|
},
|
|
17
18
|
emits: ["open"],
|
|
18
19
|
setup(props, { emit }) {
|
|
19
|
-
|
|
20
|
+
const rateLimited = computed(() => props.cards.filter((c) => c.status === "rate_limited").length);
|
|
21
|
+
return { emit, rateLimited };
|
|
20
22
|
},
|
|
21
23
|
template: `
|
|
22
24
|
<section class="lane" :class="'lane--' + status" role="listitem">
|
|
23
25
|
<header class="lane__head">
|
|
24
26
|
<span class="lane__dot"></span>
|
|
25
27
|
<h2 class="lane__title">{{ title }}</h2>
|
|
28
|
+
<span v-if="rateLimited" class="lane__rl" :title="rateLimited + ' card(s) waiting on a provider rate limit'">
|
|
29
|
+
<svg viewBox="0 0 12 12" width="10" height="10" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" aria-hidden="true"><circle cx="6" cy="6" r="4.6"></circle><path d="M6 3.6V6l1.8 1.2"></path></svg>{{ rateLimited }}
|
|
30
|
+
</span>
|
|
26
31
|
<span class="lane__count">{{ cards.length }}</span>
|
|
27
32
|
</header>
|
|
28
33
|
<div class="lane__body">
|
|
@@ -7,6 +7,7 @@ export default {
|
|
|
7
7
|
props: {
|
|
8
8
|
loading: { type: Boolean, default: false },
|
|
9
9
|
error: { type: [String, null], default: null },
|
|
10
|
+
retryable: { type: Boolean, default: true },
|
|
10
11
|
},
|
|
11
12
|
emits: ["retry"],
|
|
12
13
|
setup(props, { emit }) {
|
|
@@ -14,9 +15,10 @@ export default {
|
|
|
14
15
|
},
|
|
15
16
|
template: `
|
|
16
17
|
<div v-if="error" class="notice notice--error">
|
|
17
|
-
<
|
|
18
|
-
<
|
|
18
|
+
<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" aria-hidden="true" style="flex:none"><circle cx="8" cy="8" r="6.2"></circle><path d="M8 4.8V8.6M8 11.2v.1"></path></svg>
|
|
19
|
+
<span class="notice__msg">{{ error }}</span>
|
|
20
|
+
<button v-if="retryable" class="btn btn--ghost btn--sm" type="button" @click="emit('retry')">Retry</button>
|
|
19
21
|
</div>
|
|
20
|
-
<div v-else-if="loading" class="notice notice--info">Loading…</div>
|
|
22
|
+
<div v-else-if="loading" class="notice notice--info"><span class="spinner" aria-hidden="true"></span>Loading…</div>
|
|
21
23
|
`,
|
|
22
24
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rate_limited helpers — ✅ EDITABLE. Shared by Card tile, Lane badge and the
|
|
3
|
+
* card detail notice. Pure functions: card in, display strings out.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const PROVIDER_LABELS = { claude: "Claude", copilot: "Copilot" };
|
|
7
|
+
|
|
8
|
+
/** Live countdown text derived from retryAt (null = unknown reset window). */
|
|
9
|
+
export function retryLabel(card, now = Date.now()) {
|
|
10
|
+
if (!card.retryAt) return "retrying when limit resets";
|
|
11
|
+
const mins = Math.ceil((new Date(card.retryAt).getTime() - now) / 60000);
|
|
12
|
+
if (mins <= 0) return "retrying\u2026";
|
|
13
|
+
if (mins >= 60) return `retry in ~${Math.floor(mins / 60)}h ${mins % 60}m`;
|
|
14
|
+
return `retry in ~${mins}m`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function providerLabel(card) {
|
|
18
|
+
return PROVIDER_LABELS[card.rateLimitProvider] || "";
|
|
19
|
+
}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
const T0 = "2026-08-08T09:00:00.000Z";
|
|
13
13
|
const T1 = "2026-08-08T12:30:00.000Z";
|
|
14
14
|
const T2 = "2026-08-08T14:05:00.000Z";
|
|
15
|
+
/** rate_limited demo: auto-retry ~30 minutes from page load. */
|
|
16
|
+
const RETRY_AT = new Date(Date.now() + 30 * 60000).toISOString();
|
|
15
17
|
|
|
16
18
|
/** @param {Partial<import('../api/contract.js').BoardCard>} o */
|
|
17
19
|
function card(o) {
|
|
@@ -31,6 +33,8 @@ function card(o) {
|
|
|
31
33
|
nextSpawnAt: null,
|
|
32
34
|
workerThreadId: null,
|
|
33
35
|
blockedReason: null,
|
|
36
|
+
rateLimitProvider: null,
|
|
37
|
+
retryAt: null,
|
|
34
38
|
archivedAt: null,
|
|
35
39
|
createdAt: T0,
|
|
36
40
|
updatedAt: T0,
|
|
@@ -135,6 +139,36 @@ export const fixtures = {
|
|
|
135
139
|
archivedAt: T1,
|
|
136
140
|
profile: {},
|
|
137
141
|
}),
|
|
142
|
+
card({
|
|
143
|
+
cardId: 8,
|
|
144
|
+
title: "Refactor comment threading into a tree view",
|
|
145
|
+
description: "Worker paused mid-run: Claude usage limit reached. Auto-retries when the window resets.",
|
|
146
|
+
acceptance: "Nested replies render as a collapsible tree; existing flat view unaffected.",
|
|
147
|
+
type: "feature",
|
|
148
|
+
laneThreadId: 101,
|
|
149
|
+
priority: 1,
|
|
150
|
+
status: "rate_limited",
|
|
151
|
+
workerThreadId: 9902,
|
|
152
|
+
startedAt: T1,
|
|
153
|
+
rateLimitProvider: "claude",
|
|
154
|
+
retryAt: RETRY_AT,
|
|
155
|
+
profile: { agentType: "claude", createBranch: true, runTests: true },
|
|
156
|
+
}),
|
|
157
|
+
card({
|
|
158
|
+
cardId: 9,
|
|
159
|
+
title: "Generate API usage examples for the docs site",
|
|
160
|
+
description: "Copilot credits exhausted for this billing window; card is parked until they replenish.",
|
|
161
|
+
acceptance: "Each public endpoint has a runnable example snippet.",
|
|
162
|
+
type: "chore",
|
|
163
|
+
laneThreadId: 202,
|
|
164
|
+
priority: 0,
|
|
165
|
+
status: "rate_limited",
|
|
166
|
+
workerThreadId: 9903,
|
|
167
|
+
startedAt: T2,
|
|
168
|
+
rateLimitProvider: "copilot",
|
|
169
|
+
retryAt: null,
|
|
170
|
+
profile: { agentType: "copilot" },
|
|
171
|
+
}),
|
|
138
172
|
],
|
|
139
173
|
|
|
140
174
|
/** Keyed by cardId. */
|
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Card-builder "How" policy schema. ✅ EDITABLE design-layer data.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* view. views/BuilderView.js renders this GENERICALLY: only the widget *types*
|
|
8
|
-
* below are hardcoded (in the view's dispatch), never the options themselves.
|
|
4
|
+
* Single source of truth for the builder Step 2 ("How") controls, rendered
|
|
5
|
+
* GENERICALLY by views/BuilderView.js — only the widget *types* are hardcoded
|
|
6
|
+
* in the view's dispatch, never the options.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
* so this file is design-tier just like views/ and components/ — NOT frozen.
|
|
12
|
-
*
|
|
13
|
-
* ── Widget vocabulary (the only hardcoded part) ──────────────────────────────
|
|
8
|
+
* ── Widget vocabulary ────────────────────────────────────────────────────────
|
|
14
9
|
* "select" — single choice from `options` (dropdown)
|
|
10
|
+
* "combobox" — free-text input + curated per-provider suggestions
|
|
11
|
+
* (`suggestionsBy` maps the value of `dependsOn` to grouped lists)
|
|
15
12
|
* "segmented" — single choice from `options` (button group)
|
|
16
13
|
* "chips" — multi-select subset of `options` (value is an array)
|
|
17
14
|
* "toggle" — boolean on/off switch
|
|
18
|
-
* "phases" — ordered list of
|
|
15
|
+
* "phases" — ordered list of phase objects {name, review, provider, model}
|
|
16
|
+
* (per-phase provider/model override the card-level pick; "Inherit" / "" = card default)
|
|
17
|
+
* "text" — single-line free text
|
|
18
|
+
* "textarea" — multiline free text
|
|
19
|
+
* "dirpicker" — directory-dialog button + chosen-path display (supports `required`)
|
|
20
|
+
* "memory" — 3-mode memory selector with a conditional sub-field:
|
|
21
|
+
* Ephemeral (none) / Existing thread (thread dropdown) /
|
|
22
|
+
* New persistent thread (name text input).
|
|
23
|
+
* Value: { mode, threadId, name }
|
|
19
24
|
*
|
|
20
25
|
* ── Field shape ──────────────────────────────────────────────────────────────
|
|
21
|
-
* { key, widget, label, desc?, options?, default
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* - label shown to the operator; also the compiled-policy row heading
|
|
25
|
-
* - desc optional helper line (rendered under the label / switch)
|
|
26
|
-
* - options choices for select / segmented / chips (ignored otherwise)
|
|
27
|
-
* - default initial value (chips → array, phases → array of [name, bool])
|
|
26
|
+
* { key, widget, label, desc?, options?, default, placeholder?, required?,
|
|
27
|
+
* group?, inline? (rendered inside a parent accordion, skipped by the generic loop),
|
|
28
|
+
* visibleIf?: {key, equals} — conditional visibility }
|
|
28
29
|
*/
|
|
29
30
|
|
|
30
|
-
/** @typedef {"select"|"segmented"|"chips"|"toggle"|"phases"} PolicyWidget */
|
|
31
|
+
/** @typedef {"select"|"segmented"|"chips"|"toggle"|"phases"|"text"|"textarea"|"dirpicker"|"memory"} PolicyWidget */
|
|
32
|
+
|
|
33
|
+
export const MEMORY_MODES = ["Ephemeral", "Existing thread", "New persistent thread"];
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
|
-
* Ordered list of How-step fields.
|
|
34
|
-
*
|
|
35
|
-
* @type {Array<{key:string, widget:PolicyWidget, label:string, desc?:string, options?:string[], default:*}>}
|
|
36
|
+
* Ordered list of How-step fields.
|
|
37
|
+
* @type {Array<{key:string, widget:PolicyWidget, label:string, desc?:string, options?:string[], default:*, placeholder?:string, required?:boolean}>}
|
|
36
38
|
*/
|
|
37
39
|
export const POLICY_SCHEMA = [
|
|
38
40
|
{
|
|
@@ -40,14 +42,37 @@ export const POLICY_SCHEMA = [
|
|
|
40
42
|
widget: "segmented",
|
|
41
43
|
label: "Provider",
|
|
42
44
|
options: ["Claude", "Copilot", "Codex"],
|
|
43
|
-
default: "
|
|
45
|
+
default: "Copilot",
|
|
44
46
|
},
|
|
45
47
|
{
|
|
46
48
|
key: "model",
|
|
47
|
-
widget: "
|
|
48
|
-
label: "
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
widget: "combobox",
|
|
50
|
+
label: "Model (optional)",
|
|
51
|
+
desc: "pick a suggestion or type any alias; empty = provider default",
|
|
52
|
+
placeholder: "e.g. claude-opus-4.8",
|
|
53
|
+
default: "",
|
|
54
|
+
dependsOn: "provider",
|
|
55
|
+
// Curated static suggestions per provider — no live API fetch.
|
|
56
|
+
suggestionsBy: {
|
|
57
|
+
Claude: [
|
|
58
|
+
{ label: null, options: ["claude-opus-4-8", "claude-sonnet-4-6", "claude-haiku-4-5"] },
|
|
59
|
+
],
|
|
60
|
+
Copilot: [
|
|
61
|
+
{ label: "Anthropic (via Copilot)", options: ["claude-opus-4.8", "claude-sonnet-4.6"] },
|
|
62
|
+
{ label: "OpenAI (via Copilot)", options: ["gpt-5.2", "gpt-5.2-codex", "o5-mini"] },
|
|
63
|
+
],
|
|
64
|
+
Codex: [
|
|
65
|
+
{ label: null, options: ["gpt-5.2-codex", "gpt-5.2", "o5-mini"] },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "workdir",
|
|
71
|
+
widget: "dirpicker",
|
|
72
|
+
label: "Working directory",
|
|
73
|
+
desc: "the repo path this card's worker runs against",
|
|
74
|
+
required: true,
|
|
75
|
+
default: "",
|
|
51
76
|
},
|
|
52
77
|
{
|
|
53
78
|
key: "skills",
|
|
@@ -57,13 +82,19 @@ export const POLICY_SCHEMA = [
|
|
|
57
82
|
default: ["Git"],
|
|
58
83
|
},
|
|
59
84
|
{
|
|
60
|
-
key: "
|
|
61
|
-
widget: "
|
|
62
|
-
label: "
|
|
63
|
-
desc: "
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
key: "autonomy",
|
|
86
|
+
widget: "segmented",
|
|
87
|
+
label: "Autonomy",
|
|
88
|
+
desc: "how often the worker checks in with you",
|
|
89
|
+
options: ["Autonomous", "Checkpoints", "Collaborative"],
|
|
90
|
+
default: "Autonomous",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
key: "memory",
|
|
94
|
+
widget: "memory",
|
|
95
|
+
label: "Memory",
|
|
96
|
+
desc: "Where this card's worker (and any sub-workers it spawns) keep memory",
|
|
97
|
+
default: { mode: "Ephemeral", threadId: null, name: "" },
|
|
67
98
|
},
|
|
68
99
|
{
|
|
69
100
|
key: "worktree",
|
|
@@ -71,34 +102,58 @@ export const POLICY_SCHEMA = [
|
|
|
71
102
|
label: "Run in a git worktree",
|
|
72
103
|
desc: "Isolated branch — nothing touches main until you merge",
|
|
73
104
|
default: true,
|
|
74
|
-
// Compiled-policy phrasing (optional; falls back to "on"/"off").
|
|
75
105
|
onText: "git worktree, merge on approval",
|
|
76
106
|
offText: "direct on main",
|
|
77
107
|
},
|
|
78
108
|
{
|
|
79
|
-
key: "
|
|
109
|
+
key: "verifyDone",
|
|
80
110
|
widget: "toggle",
|
|
81
|
-
label: "
|
|
82
|
-
desc: "A
|
|
111
|
+
label: "Verify acceptance (separate worker)",
|
|
112
|
+
desc: "A separate worker checks the acceptance criteria before moving to Done",
|
|
113
|
+
default: true,
|
|
114
|
+
onText: "verify acceptance → move to Done → notify you",
|
|
115
|
+
offText: "off",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
key: "openPr",
|
|
119
|
+
widget: "toggle",
|
|
120
|
+
label: "Create pull request",
|
|
121
|
+
desc: "Open a PR when the work is ready (compiles into the worker prompt)",
|
|
83
122
|
default: false,
|
|
84
|
-
|
|
123
|
+
group: "pr",
|
|
124
|
+
onText: "create",
|
|
85
125
|
offText: "off",
|
|
86
126
|
},
|
|
87
127
|
{
|
|
88
|
-
key: "
|
|
128
|
+
key: "prDraft",
|
|
89
129
|
widget: "toggle",
|
|
90
|
-
label: "
|
|
91
|
-
desc: "
|
|
130
|
+
label: "Draft PR",
|
|
131
|
+
desc: "Open as draft; mark ready after review",
|
|
92
132
|
default: true,
|
|
93
|
-
|
|
94
|
-
|
|
133
|
+
group: "pr",
|
|
134
|
+
inline: true,
|
|
135
|
+
onText: "draft",
|
|
136
|
+
offText: "ready",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
key: "prProvider",
|
|
140
|
+
widget: "select",
|
|
141
|
+
label: "Target",
|
|
142
|
+
desc: "Auto: detected from repo remote",
|
|
143
|
+
options: ["Auto", "GitHub", "Azure DevOps"],
|
|
144
|
+
default: "Auto",
|
|
145
|
+
group: "pr",
|
|
146
|
+
inline: true,
|
|
95
147
|
},
|
|
96
148
|
{
|
|
97
149
|
key: "phases",
|
|
98
150
|
widget: "phases",
|
|
99
151
|
label: "Phases",
|
|
100
|
-
desc: "run in order",
|
|
101
|
-
default: [
|
|
152
|
+
desc: "run in order; each phase may toggle its own review and override provider/model",
|
|
153
|
+
default: [
|
|
154
|
+
{ name: "Plan", review: true, provider: "Inherit", model: "" },
|
|
155
|
+
{ name: "Implement", review: false, provider: "Inherit", model: "" },
|
|
156
|
+
],
|
|
102
157
|
},
|
|
103
158
|
];
|
|
104
159
|
|
|
@@ -106,10 +161,8 @@ export const POLICY_SCHEMA = [
|
|
|
106
161
|
* Presets seed the whole How step (and the card `type`) in one click.
|
|
107
162
|
* `values` is keyed by POLICY_SCHEMA field `key`; any key omitted falls back to
|
|
108
163
|
* that field's `default`. Editing a control after applying a preset clears it.
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* "Full delivery" carries the canonical
|
|
112
|
-
* Analysis → Plan → Implementation → Expert code review → Commit pipeline.
|
|
164
|
+
* (Adapted to the current field set: model is a free-text alias, memory
|
|
165
|
+
* replaces the old runIn.)
|
|
113
166
|
* @type {Array<{name:string, type?:string, values:Object}>}
|
|
114
167
|
*/
|
|
115
168
|
export const PRESETS = [
|
|
@@ -118,13 +171,17 @@ export const PRESETS = [
|
|
|
118
171
|
type: "bug",
|
|
119
172
|
values: {
|
|
120
173
|
provider: "Claude",
|
|
121
|
-
model: "
|
|
174
|
+
model: "",
|
|
122
175
|
skills: ["Git", "Tests"],
|
|
123
|
-
|
|
176
|
+
autonomy: "Autonomous",
|
|
177
|
+
memory: { mode: "Ephemeral", threadId: null, name: "" },
|
|
124
178
|
worktree: true,
|
|
125
|
-
review: true,
|
|
126
179
|
verifyDone: true,
|
|
127
|
-
phases: [
|
|
180
|
+
phases: [
|
|
181
|
+
{ name: "Reproduce", review: false, provider: "Inherit", model: "" },
|
|
182
|
+
{ name: "Fix root cause", review: true, provider: "Inherit", model: "" },
|
|
183
|
+
{ name: "Verify", review: false, provider: "Inherit", model: "" },
|
|
184
|
+
],
|
|
128
185
|
},
|
|
129
186
|
},
|
|
130
187
|
{
|
|
@@ -132,13 +189,18 @@ export const PRESETS = [
|
|
|
132
189
|
type: "feature",
|
|
133
190
|
values: {
|
|
134
191
|
provider: "Claude",
|
|
135
|
-
model: "
|
|
192
|
+
model: "claude-opus-4.8",
|
|
136
193
|
skills: ["Git", "Tests", "Docs"],
|
|
137
|
-
|
|
194
|
+
autonomy: "Checkpoints",
|
|
195
|
+
memory: { mode: "Ephemeral", threadId: null, name: "" },
|
|
138
196
|
worktree: true,
|
|
139
|
-
review: true,
|
|
140
197
|
verifyDone: true,
|
|
141
|
-
phases: [
|
|
198
|
+
phases: [
|
|
199
|
+
{ name: "Plan", review: true, provider: "Inherit", model: "" },
|
|
200
|
+
{ name: "Implement", review: false, provider: "Inherit", model: "" },
|
|
201
|
+
{ name: "Test & document", review: true, provider: "Inherit", model: "" },
|
|
202
|
+
{ name: "Final review", review: false, provider: "Inherit", model: "" },
|
|
203
|
+
],
|
|
142
204
|
},
|
|
143
205
|
},
|
|
144
206
|
{
|
|
@@ -146,18 +208,18 @@ export const PRESETS = [
|
|
|
146
208
|
type: "feature",
|
|
147
209
|
values: {
|
|
148
210
|
provider: "Claude",
|
|
149
|
-
model: "
|
|
211
|
+
model: "claude-opus-4.8",
|
|
150
212
|
skills: ["Git", "Tests", "Docs"],
|
|
151
|
-
|
|
213
|
+
autonomy: "Checkpoints",
|
|
214
|
+
memory: { mode: "New persistent thread", threadId: null, name: "" },
|
|
152
215
|
worktree: true,
|
|
153
|
-
review: true,
|
|
154
216
|
verifyDone: true,
|
|
155
217
|
phases: [
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
218
|
+
{ name: "Analysis", review: false, provider: "Inherit", model: "" },
|
|
219
|
+
{ name: "Plan", review: true, provider: "Inherit", model: "" },
|
|
220
|
+
{ name: "Implementation", review: false, provider: "Inherit", model: "" },
|
|
221
|
+
{ name: "Final review", review: true, provider: "Inherit", model: "" },
|
|
222
|
+
{ name: "Commit", review: false, provider: "Inherit", model: "" },
|
|
161
223
|
],
|
|
162
224
|
},
|
|
163
225
|
},
|
|
@@ -166,11 +228,11 @@ export const PRESETS = [
|
|
|
166
228
|
type: "research",
|
|
167
229
|
values: {
|
|
168
230
|
provider: "Claude",
|
|
169
|
-
model: "
|
|
231
|
+
model: "",
|
|
170
232
|
skills: ["Web search", "Docs"],
|
|
171
|
-
|
|
233
|
+
autonomy: "Collaborative",
|
|
234
|
+
memory: { mode: "Ephemeral", threadId: null, name: "" },
|
|
172
235
|
worktree: false,
|
|
173
|
-
review: false,
|
|
174
236
|
verifyDone: false,
|
|
175
237
|
phases: [],
|
|
176
238
|
},
|
|
@@ -180,13 +242,16 @@ export const PRESETS = [
|
|
|
180
242
|
type: "tech-debt",
|
|
181
243
|
values: {
|
|
182
244
|
provider: "Codex",
|
|
183
|
-
model: "
|
|
245
|
+
model: "",
|
|
184
246
|
skills: ["Git", "Tests"],
|
|
185
|
-
|
|
247
|
+
autonomy: "Autonomous",
|
|
248
|
+
memory: { mode: "Ephemeral", threadId: null, name: "" },
|
|
186
249
|
worktree: true,
|
|
187
|
-
review: false,
|
|
188
250
|
verifyDone: true,
|
|
189
|
-
phases: [
|
|
251
|
+
phases: [
|
|
252
|
+
{ name: "Map current structure", review: false, provider: "Inherit", model: "" },
|
|
253
|
+
{ name: "Migrate incrementally", review: true, provider: "Inherit", model: "" },
|
|
254
|
+
],
|
|
190
255
|
},
|
|
191
256
|
},
|
|
192
257
|
];
|