@dipertq/dsh-openviking-status 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -41,7 +41,7 @@ Equivalent, and useful when the registry is unreachable. Use a
41
41
  **version-pinned** URL:
42
42
 
43
43
  ```bash
44
- dsh plugin add https://github.com/dipertq/dsh-openviking-status/releases/download/v0.3.0/dipertq-dsh-openviking-status-0.3.0.tgz
44
+ dsh plugin add https://github.com/dipertq/dsh-openviking-status/releases/download/v0.3.1/dipertq-dsh-openviking-status-0.3.1.tgz
45
45
  ```
46
46
 
47
47
  Not `/releases/latest/download/…`: that URL keeps its name while its content
package/lib/client.cjs CHANGED
@@ -54,6 +54,7 @@ __export(client_exports, {
54
54
  commitSession: () => commitSession,
55
55
  computeBreakdown: () => computeBreakdown,
56
56
  defaultOpenVikingClient: () => defaultOpenVikingClient,
57
+ extractTaskList: () => extractTaskList,
57
58
  fetchSession: () => fetchSession,
58
59
  formatBacklog: () => formatBacklog,
59
60
  formatDaemonVersion: () => formatDaemonVersion,
@@ -79,10 +80,12 @@ __export(client_exports, {
79
80
  normalizeExecutionEvent: () => normalizeExecutionEvent,
80
81
  normalizeExtractionTask: () => normalizeExtractionTask,
81
82
  normalizeTaskList: () => normalizeTaskList,
83
+ normalizeTimestamp: () => normalizeTimestamp,
82
84
  parseRecalledMemories: () => parseRecalledMemories,
83
85
  resolveApiKey: () => resolveApiKey,
84
86
  resolveEndpoint: () => resolveEndpoint,
85
87
  seedRunningTask: () => seedRunningTask,
88
+ shouldPollActive: () => shouldPollActive,
86
89
  themeVar: () => themeVar,
87
90
  truncateSessionId: () => truncateSessionId
88
91
  });
@@ -94,6 +97,33 @@ var import_react_dom = __toESM(require("react-dom"), 1);
94
97
 
95
98
  // src/client/api.ts
96
99
  var TASKS_LIMIT_CAP = 200;
100
+ function normalizeTimestamp(ts, isoFallback) {
101
+ if (typeof isoFallback === "string" && isoFallback.trim()) {
102
+ return isoFallback.trim();
103
+ }
104
+ if (typeof ts === "string" && ts.trim()) {
105
+ return ts.trim();
106
+ }
107
+ if (typeof ts === "number" && Number.isFinite(ts) && ts > 0) {
108
+ const ms = ts < 1e11 ? ts * 1e3 : ts;
109
+ return new Date(ms).toISOString();
110
+ }
111
+ return void 0;
112
+ }
113
+ function extractTaskList(data) {
114
+ if (!data || typeof data !== "object") return [];
115
+ if (Array.isArray(data)) return data;
116
+ const obj = data;
117
+ if (Array.isArray(obj.result)) return obj.result;
118
+ if (Array.isArray(obj.items)) return obj.items;
119
+ if (Array.isArray(obj.tasks)) return obj.tasks;
120
+ if (obj.result && typeof obj.result === "object") {
121
+ const res = obj.result;
122
+ if (Array.isArray(res.items)) return res.items;
123
+ if (Array.isArray(res.tasks)) return res.tasks;
124
+ }
125
+ return [];
126
+ }
97
127
  function normalizeExtractionTask(raw) {
98
128
  if (!raw || typeof raw !== "object") return null;
99
129
  const taskId = typeof raw.task_id === "string" && raw.task_id || typeof raw.id === "string" && raw.id || "";
@@ -113,8 +143,8 @@ function normalizeExtractionTask(raw) {
113
143
  task_id: taskId,
114
144
  status,
115
145
  resource_id: typeof raw.resource_id === "string" ? raw.resource_id : void 0,
116
- created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
117
- updated_at: typeof raw.updated_at === "string" ? raw.updated_at : void 0,
146
+ created_at: normalizeTimestamp(raw.created_at, raw.created_at_iso),
147
+ updated_at: normalizeTimestamp(raw.updated_at, raw.updated_at_iso),
118
148
  memory_write: numberOf(extracted.memory_write ?? extracted.written),
119
149
  memory_edit: numberOf(extracted.memory_edit ?? extracted.edited),
120
150
  token_usage: tokenUsage,
@@ -150,7 +180,7 @@ function computeBreakdown(tasks) {
150
180
  function normalizeExecutionEvent(raw) {
151
181
  return {
152
182
  seq: typeof raw.seq === "number" ? raw.seq : void 0,
153
- recorded_at: typeof raw.recorded_at === "string" ? raw.recorded_at : void 0,
183
+ recorded_at: normalizeTimestamp(raw.recorded_at, raw.recorded_at_iso),
154
184
  kind: typeof raw.kind === "string" ? raw.kind : void 0,
155
185
  status: typeof raw.status === "string" ? raw.status : void 0,
156
186
  stage: typeof raw.stage === "string" ? raw.stage : null,
@@ -556,7 +586,7 @@ var OpenVikingClient = class {
556
586
  status: "error",
557
587
  detail: typeof data.detail === "string" ? data.detail : void 0
558
588
  };
559
- const tasks = normalizeTaskList(data.tasks);
589
+ const tasks = normalizeTaskList(extractTaskList(data.tasks ?? data));
560
590
  return { status: "ok", breakdown: computeBreakdown(tasks), tasks };
561
591
  } catch (err) {
562
592
  return {
@@ -607,8 +637,7 @@ var OpenVikingClient = class {
607
637
  return { status: "error", detail: `HTTP ${res.status}` };
608
638
  }
609
639
  const data = await res.json();
610
- const items = data?.items ?? data?.tasks ?? data?.result?.items ?? (Array.isArray(data) ? data : []);
611
- const tasks = normalizeTaskList(items);
640
+ const tasks = normalizeTaskList(extractTaskList(data));
612
641
  return { status: "ok", breakdown: computeBreakdown(tasks), tasks };
613
642
  } catch (err) {
614
643
  return {
@@ -1833,6 +1862,10 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
1833
1862
  var COMMIT_THRESHOLD = 2e4;
1834
1863
  var POLL_INTERVAL_IDLE_MS = 15e3;
1835
1864
  var POLL_INTERVAL_ACTIVE_MS = 2500;
1865
+ function shouldPollActive(breakdown) {
1866
+ if (!breakdown) return false;
1867
+ return breakdown.running >= 1 || breakdown.pending >= 1;
1868
+ }
1836
1869
  function getChipDotState({
1837
1870
  isOnline,
1838
1871
  sessionUnreadable,
@@ -2062,13 +2095,13 @@ function StatusChipView({
2062
2095
  }
2063
2096
  }, [sessionId, apiClient]);
2064
2097
  const breakdown = tasksRead?.status === "ok" ? tasksRead.breakdown : null;
2065
- const hasRunning = (breakdown?.running ?? 0) >= 1;
2098
+ const hasActivePhase = shouldPollActive(breakdown);
2066
2099
  (0, import_react2.useEffect)(() => {
2067
2100
  fetchStatus();
2068
- const interval = hasRunning ? POLL_INTERVAL_ACTIVE_MS : POLL_INTERVAL_IDLE_MS;
2101
+ const interval = hasActivePhase ? POLL_INTERVAL_ACTIVE_MS : POLL_INTERVAL_IDLE_MS;
2069
2102
  const timer = setInterval(fetchStatus, interval);
2070
2103
  return () => clearInterval(timer);
2071
- }, [fetchStatus, hasRunning]);
2104
+ }, [fetchStatus, hasActivePhase]);
2072
2105
  (0, import_react2.useEffect)(() => {
2073
2106
  function handleClickOutside(event) {
2074
2107
  if (popoverRef.current && !popoverRef.current.contains(event.target)) {