kanbango 3.8.0 → 5.1.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/config-wizard.js CHANGED
@@ -8,10 +8,10 @@ const path = require('path');
8
8
  const CONFIG_REL = path.join('backlog', 'kanbango.json');
9
9
 
10
10
  const DEFAULT_ANSWERS = {
11
- testing: true,
12
- testingAgent: true,
13
- review: true,
14
- reviewAgent: true
11
+ testing: false,
12
+ testingAgent: false,
13
+ review: false,
14
+ reviewAgent: false
15
15
  };
16
16
 
17
17
  const ITEMS = [
package/index.html CHANGED
@@ -238,6 +238,23 @@ header h1 { font-size: 14px; font-weight: 700; letter-spacing: -0.2px; }
238
238
  border-radius: 10px;
239
239
  padding: 1px 7px;
240
240
  }
241
+ .now-context {
242
+ font-size: 10px;
243
+ font-weight: 700;
244
+ color: var(--active);
245
+ margin-left: auto;
246
+ letter-spacing: 0;
247
+ text-transform: none;
248
+ }
249
+ .card-blocked {
250
+ font-size: 10px;
251
+ font-weight: 700;
252
+ color: #991b1b;
253
+ background: #fee2e2;
254
+ border-radius: 4px;
255
+ padding: 1px 6px;
256
+ margin-top: 6px;
257
+ }
241
258
  .now-cards {
242
259
  display: flex;
243
260
  flex-wrap: wrap;
@@ -793,6 +810,7 @@ header h1 { font-size: 14px; font-weight: 700; letter-spacing: -0.2px; }
793
810
  <div class="now-head">
794
811
  <span class="now-title">NOW</span>
795
812
  <span class="now-count" id="now-count">0</span>
813
+ <span class="now-context" id="now-context"></span>
796
814
  </div>
797
815
  <div class="now-cards" id="now-cards"></div>
798
816
  </div>
@@ -831,6 +849,7 @@ let boardConfig = null;
831
849
 
832
850
  let allTasks = [];
833
851
  let allEpicEntities = [];
852
+ let agentContext = null;
834
853
  /** @type {null|string} null=all, "—"=no epic, "E001"=epic id */
835
854
  let filterKey = null;
836
855
  /** @type {null|{kind:'task'|'epic', id:string}} */
@@ -890,10 +909,11 @@ function rebuildNewTaskColSelect() {
890
909
 
891
910
  async function load() {
892
911
  const q = showArchived ? "?include_archived=true" : "";
893
- const [boardRes, epicsRes, configRes] = await Promise.all([
912
+ const [boardRes, epicsRes, configRes, contextRes] = await Promise.all([
894
913
  fetch("/api/board" + q),
895
914
  fetch("/api/epics" + q),
896
- fetch("/api/config")
915
+ fetch("/api/config"),
916
+ fetch("/api/context")
897
917
  ]);
898
918
  if (!configRes.ok) {
899
919
  toast('Board config failed to load — using default columns', true);
@@ -902,6 +922,7 @@ async function load() {
902
922
  }
903
923
  allTasks = await boardRes.json();
904
924
  allEpicEntities = epicsRes.ok ? await epicsRes.json() : [];
925
+ agentContext = contextRes.ok ? await contextRes.json() : null;
905
926
  refreshEpicDatalist();
906
927
  // Drop paper target if entity vanished
907
928
  if (paperTarget) {
@@ -1028,6 +1049,17 @@ function makeRailItem({ key, title, idLabel, count, status, on, entity }) {
1028
1049
  function renderNow(tasks) {
1029
1050
  const active = tasks.filter(t => t.column === "active");
1030
1051
  document.getElementById("now-count").textContent = String(active.length);
1052
+ const ctxEl = document.getElementById("now-context");
1053
+ if (ctxEl) {
1054
+ const action = agentContext && agentContext.next_action;
1055
+ if (!action) {
1056
+ ctxEl.textContent = "";
1057
+ } else {
1058
+ const bits = ["next_action: " + action];
1059
+ if (agentContext.task_id) bits.push(agentContext.task_id);
1060
+ ctxEl.textContent = bits.join(" · ");
1061
+ }
1062
+ }
1031
1063
  const wrap = document.getElementById("now-cards");
1032
1064
  wrap.innerHTML = "";
1033
1065
  if (active.length === 0) {
@@ -1122,6 +1154,15 @@ function renderCard(task, colId) {
1122
1154
  titleEl.textContent = displayTitle;
1123
1155
  card.appendChild(titleEl);
1124
1156
 
1157
+ const unmet = Array.isArray(task.unmet_dependencies) ? task.unmet_dependencies : [];
1158
+ if (task.blocked || unmet.length > 0) {
1159
+ const blockedEl = el("div", "card-blocked");
1160
+ blockedEl.textContent = unmet.length
1161
+ ? "blocked by " + unmet.join(", ")
1162
+ : "blocked";
1163
+ card.appendChild(blockedEl);
1164
+ }
1165
+
1125
1166
  if (totalT > 0 && colId !== "icebox") {
1126
1167
  const pr = el("div", "prog-row");
1127
1168
  pr.innerHTML = `
@@ -1259,6 +1300,13 @@ function renderTaskPaperView(paper, task) {
1259
1300
  ];
1260
1301
  if (task.epic_id) badges.push({ text: task.epic_id, cls: "" });
1261
1302
  if (task.plan && task.plan.status) badges.push({ text: "plan:" + task.plan.status, cls: "" });
1303
+ const paperUnmet = Array.isArray(task.unmet_dependencies) ? task.unmet_dependencies : [];
1304
+ if (task.blocked || paperUnmet.length > 0) {
1305
+ badges.push({
1306
+ text: paperUnmet.length ? "blocked by " + paperUnmet.join(", ") : "blocked",
1307
+ cls: ""
1308
+ });
1309
+ }
1262
1310
 
1263
1311
  const actions = [
1264
1312
  makePaperBtn("Edit", "btn-sm btn-confirm", () => { paperEditing = true; render(); }),
@@ -1291,6 +1339,15 @@ function renderTaskPaperView(paper, task) {
1291
1339
  body.appendChild(renderDetailListSection("Test Cases", task.test_cases));
1292
1340
  }
1293
1341
  if (task.notes) body.appendChild(renderDetailSection("Notes", task.notes));
1342
+ if (task.depends_on && task.depends_on.length) {
1343
+ body.appendChild(renderDetailListSection("Depends on", task.depends_on));
1344
+ }
1345
+ if (paperUnmet.length) {
1346
+ body.appendChild(renderDetailListSection("blocked by", paperUnmet));
1347
+ }
1348
+ if (task.files && task.files.length) {
1349
+ body.appendChild(renderDetailListSection("Files", task.files));
1350
+ }
1294
1351
 
1295
1352
  const subtasks = task.subtasks || [];
1296
1353
  if (subtasks.length > 0) {