@boyingliu01/opencode-plugin 0.9.5 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boyingliu01/opencode-plugin",
3
- "version": "0.9.5",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "main": "index.ts",
6
6
  "description": "XP-Gate quality gates + AI workflow skills + Sprint Flow TUI sidebar for OpenCode",
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-06-21
4
- **Commit:** 1050a30
3
+ **Generated:** 2026-06-22
4
+ **Commit:** 984d568
5
5
  **Branch:** main
6
- **Version:** 0.9.5.0
6
+ **Version:** 0.10.0.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, 3 experts from ≥2 providers, domestic models only). Supports design + code-walkthrough modes.
@@ -1,9 +1,9 @@
1
1
  # SKILLS/SPRINT-FLOW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-06-21
4
- **Commit:** 1050a30
3
+ **Generated:** 2026-06-22
4
+ **Commit:** 984d568
5
5
  **Branch:** main
6
- **Version:** 0.9.5.0
6
+ **Version:** 0.10.0.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **11-phase** development pipeline: ISOLATE → AUTO-ESTIMATE → THINK → PLAN → BUILD → REVIEW → USER ACCEPTANCE → FEEDBACK → SHIP → LAND → CLEANUP. Phase 2 default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE in Phase 1: design must pass Delphi review (≥90% consensus) before any coding.
@@ -1,9 +1,9 @@
1
1
  # SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-06-21
4
- **Commit:** 1050a30
3
+ **Generated:** 2026-06-22
4
+ **Commit:** 984d568
5
5
  **Branch:** main
6
- **Version:** 0.9.5.0
6
+ **Version:** 0.10.0.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
package/tui-plugin.ts CHANGED
@@ -15,7 +15,67 @@
15
15
  import { existsSync, readFileSync } from "node:fs"
16
16
  import { join } from "node:path"
17
17
  import type { TuiPlugin, TuiSlotPlugin, TuiSlotProps } from "@opencode-ai/plugin/tui"
18
- import { PHASE_NAMES, PHASE_ORDER, getLatestTimestamp, isStale } from "../../src/npm-package/lib/shared-phase-constants.js"
18
+ // ── Phase constants (inlined from ../../src/npm-package/lib/shared-phase-constants.js)
19
+ // This file is inlined because the installed npm package does not bundle src/ at publish time. ──
20
+
21
+ const PHASE_NAMES: Record<string, string> = {
22
+ '-1': 'ISOLATE',
23
+ '-0.5': 'AUTO-ESTIMATE',
24
+ '0': 'THINK',
25
+ '1': 'PLAN',
26
+ '2': 'BUILD',
27
+ '3': 'REVIEW',
28
+ '4': 'USER ACCEPT',
29
+ '5': 'FEEDBACK',
30
+ '6': 'SHIP',
31
+ '7': 'LAND',
32
+ '8': 'CLEANUP',
33
+ };
34
+
35
+ const PHASE_ORDER = ['-1', '-0.5', '0', '1', '2', '3', '4', '5', '6', '7', '8'];
36
+
37
+ function parseTime(value: unknown): number {
38
+ return new Date(value as string).getTime();
39
+ }
40
+
41
+ function maxValid(current: number, candidate: unknown): number {
42
+ if (!candidate) return current;
43
+ const t = parseTime(candidate);
44
+ return !isNaN(t) && t > current ? t : current;
45
+ }
46
+
47
+ function getLatestTimestamp(state: Record<string, unknown> | null): number {
48
+ if (!state || !state.started_at) return 0;
49
+ const started = parseTime(state.started_at);
50
+ if (isNaN(started)) return 0;
51
+ let latest = started;
52
+ if (Array.isArray(state.phase_history)) {
53
+ for (const ph of state.phase_history) {
54
+ latest = maxValid(maxValid(latest, (ph as Record<string, unknown>).completed_at), (ph as Record<string, unknown>).started_at);
55
+ }
56
+ }
57
+ return latest;
58
+ }
59
+
60
+ function isStale(state: SprintState | null): boolean {
61
+ if (!state || !state.started_at) return false;
62
+ const latest = sprintTimestamp(state);
63
+ return latest > 0 && Date.now() - latest > 3600000;
64
+ }
65
+
66
+ function sprintTimestamp(state: SprintState | null): number {
67
+ if (!state || !state.started_at) return 0;
68
+ const started = parseTime(state.started_at);
69
+ if (isNaN(started)) return 0;
70
+ let latest = started;
71
+ if (Array.isArray(state.phase_history)) {
72
+ for (const ph of state.phase_history) {
73
+ latest = ph.completed_at ? Math.max(latest, parseTime(ph.completed_at)) : latest;
74
+ latest = ph.started_at ? Math.max(latest, parseTime(ph.started_at)) : latest;
75
+ }
76
+ }
77
+ return latest;
78
+ }
19
79
 
20
80
  // ── Sprint state schema ──
21
81
 
@@ -147,8 +207,7 @@ const tuiPlugin: TuiSlotPlugin = {
147
207
  if (!state) return null
148
208
  const text = renderSprintSidebar(state)
149
209
  if (!text) return null
150
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
151
- return text as any
210
+ return text
152
211
  },
153
212
  },
154
213
  }