cli-jaw 1.2.6 → 1.2.9

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.
Binary file
package/public/index.html CHANGED
@@ -13,6 +13,7 @@
13
13
  <link rel="stylesheet" href="/css/variables.css">
14
14
  <link rel="stylesheet" href="/css/layout.css">
15
15
  <link rel="stylesheet" href="/css/chat.css">
16
+ <link rel="stylesheet" href="/css/orc-state.css">
16
17
  <link rel="stylesheet" href="/css/sidebar.css">
17
18
  <link rel="stylesheet" href="/css/modals.css">
18
19
  <link rel="stylesheet" href="/css/markdown.css">
@@ -33,6 +34,7 @@
33
34
  <nav class="sidebar-left" role="navigation" aria-label="Main navigation">
34
35
  <button class="sidebar-toggle" id="toggleLeft" title="Collapse" aria-label="Collapse sidebar">◀</button>
35
36
  <div class="logo">CLI-JAW</div>
37
+ <span id="orcStateBadge" class="orc-state-badge" style="display:none"></span>
36
38
 
37
39
  <div>
38
40
  <div class="section-title" data-i18n="sidebar.status">상태</div>
@@ -100,6 +102,21 @@
100
102
  <span class="theme-switch-knob"></span>
101
103
  </button>
102
104
  </div>
105
+ <div class="pabc-roadmap" id="pabcRoadmap">
106
+ <div class="shark-runner" id="sharkRunner"></div>
107
+ <div class="pabc-dot future" data-phase="P" id="dot-P">P</div>
108
+ <div class="pabc-connector" id="pabc-conn-0"></div>
109
+ <div class="pabc-dot future" data-phase="A" id="dot-A">A</div>
110
+ <div class="pabc-connector" id="pabc-conn-1"></div>
111
+ <div class="pabc-center">
112
+ <div class="pabc-brand" id="pabcBrand">PABCD</div>
113
+ <div class="pabc-tagline">Ultimate Agent Workflow</div>
114
+ </div>
115
+ <div class="pabc-connector" id="pabc-conn-2"></div>
116
+ <div class="pabc-dot future" data-phase="B" id="dot-B">B</div>
117
+ <div class="pabc-connector" id="pabc-conn-3"></div>
118
+ <div class="pabc-dot future" data-phase="C" id="dot-C">C</div>
119
+ </div>
103
120
  <div class="chat-messages" id="chatMessages"></div>
104
121
  <div class="typing-indicator" id="typingIndicator">
105
122
  <span class="label" data-i18n="status.responding">응답 중</span>
@@ -11,9 +11,12 @@ export interface CliStatusCache {
11
11
  [cli: string]: unknown;
12
12
  }
13
13
 
14
+ export type OrcStateName = 'IDLE' | 'P' | 'A' | 'B' | 'C' | 'D';
15
+
14
16
  export interface AppState {
15
17
  ws: WebSocket | null;
16
18
  agentBusy: boolean;
19
+ orcState: OrcStateName;
17
20
  employees: unknown[];
18
21
  allSkills: unknown[];
19
22
  currentSkillFilter: string;
@@ -35,4 +38,5 @@ export const state: AppState = {
35
38
  heartbeatJobs: [],
36
39
  cliStatusCache: null,
37
40
  cliStatusTs: 0,
41
+ orcState: 'IDLE',
38
42
  };
package/public/js/ws.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  import { state } from './state.js';
3
3
  import { setStatus, updateQueueBadge, addSystemMsg, appendAgentText, finalizeAgent, addMessage } from './ui.js';
4
4
  import { t, getLang } from './features/i18n.js';
5
+ import type { OrcStateName } from './state.js';
5
6
 
6
7
  interface WsMessage {
7
8
  type: string;
@@ -27,6 +28,8 @@ interface WsMessage {
27
28
  content?: string;
28
29
  cli?: string;
29
30
  delay?: number;
31
+ state?: string;
32
+ title?: string;
30
33
  }
31
34
 
32
35
  // Agent phase state (populated by agent_status events from orchestrator)
@@ -80,6 +83,102 @@ export function connect(): void {
80
83
  if (el) el.innerHTML = '';
81
84
  } else if (msg.type === 'agent_added' || msg.type === 'agent_updated' || msg.type === 'agent_deleted') {
82
85
  import('./features/employees.js').then(m => m.loadEmployees());
86
+ } else if (msg.type === 'orc_state') {
87
+ const allowed = new Set<OrcStateName>(['IDLE', 'P', 'A', 'B', 'C', 'D']);
88
+ const rawState = typeof msg.state === 'string' ? msg.state : 'IDLE';
89
+ const nextState = allowed.has(rawState as OrcStateName) ? (rawState as OrcStateName) : 'IDLE';
90
+ state.orcState = nextState;
91
+
92
+ if (nextState === 'IDLE' || nextState === 'D') {
93
+ document.body.removeAttribute('data-orc-state');
94
+ document.body.style.removeProperty('--orc-glow');
95
+ } else {
96
+ document.body.setAttribute('data-orc-state', nextState);
97
+ const glowVar = `--orc-glow-${nextState}`;
98
+ const glow = getComputedStyle(document.documentElement).getPropertyValue(glowVar).trim();
99
+ document.body.style.setProperty('--orc-glow', glow);
100
+ }
101
+
102
+ document.body.classList.add('orc-pulse');
103
+ setTimeout(() => document.body.classList.remove('orc-pulse'), 700);
104
+
105
+ const badge = document.getElementById('orcStateBadge');
106
+ if (badge) {
107
+ const labels: Record<OrcStateName, string> = {
108
+ IDLE: '',
109
+ P: 'PLAN',
110
+ A: 'AUDIT',
111
+ B: 'BUILD',
112
+ C: 'CHECK',
113
+ D: 'DONE',
114
+ };
115
+ badge.textContent = labels[nextState];
116
+ badge.style.display = nextState === 'IDLE' ? 'none' : 'inline-block';
117
+ }
118
+
119
+ // ─── Roadmap Bar ───
120
+ const PHASES = ['P', 'A', 'B', 'C'] as const;
121
+ const roadmap = document.getElementById('pabcRoadmap');
122
+ const shark = document.getElementById('sharkRunner');
123
+ const brand = document.getElementById('pabcBrand');
124
+
125
+ if (roadmap && shark) {
126
+ if (nextState === 'IDLE') {
127
+ roadmap.classList.remove('visible', 'shimmer-out');
128
+ shark.classList.remove('running');
129
+ } else if (nextState === 'D') {
130
+ // All dots done + shimmer out
131
+ PHASES.forEach(p => {
132
+ const dot = document.getElementById(`dot-${p}`);
133
+ if (dot) { dot.className = 'pabc-dot done'; dot.setAttribute('data-phase', p); }
134
+ });
135
+ for (let i = 0; i < 4; i++) {
136
+ const c = document.getElementById(`pabc-conn-${i}`);
137
+ if (c) c.className = 'pabc-connector done';
138
+ }
139
+ shark.classList.remove('running');
140
+ roadmap.classList.add('shimmer-out');
141
+ setTimeout(() => roadmap.classList.remove('visible', 'shimmer-out'), 1000);
142
+ } else {
143
+ roadmap.classList.remove('shimmer-out');
144
+ roadmap.classList.add('visible');
145
+ shark.classList.add('running');
146
+
147
+ // Update dots & connectors
148
+ const idx = PHASES.indexOf(nextState as typeof PHASES[number]);
149
+ PHASES.forEach((p, pi) => {
150
+ const dot = document.getElementById(`dot-${p}`);
151
+ if (dot) {
152
+ dot.className = `pabc-dot ${pi < idx ? 'done' : pi === idx ? 'active' : 'future'}`;
153
+ dot.setAttribute('data-phase', p);
154
+ }
155
+ });
156
+ for (let i = 0; i < 4; i++) {
157
+ const c = document.getElementById(`pabc-conn-${i}`);
158
+ if (c) c.className = `pabc-connector ${i < idx ? 'done' : ''}`;
159
+ }
160
+
161
+ // Move shark along connector
162
+ requestAnimationFrame(() => {
163
+ const barRect = roadmap.getBoundingClientRect();
164
+ const activeDot = document.getElementById(`dot-${nextState}`);
165
+ if (!activeDot) return;
166
+ const conn = document.getElementById(`pabc-conn-${idx}`);
167
+ if (conn && nextState !== 'C') {
168
+ const connRect = conn.getBoundingClientRect();
169
+ shark.style.left = ((connRect.left - barRect.left) + (connRect.width * 0.4) - 18) + 'px';
170
+ } else {
171
+ const dotRect = activeDot.getBoundingClientRect();
172
+ shark.style.left = ((dotRect.left - barRect.left) + (dotRect.width / 2) - 18) + 'px';
173
+ }
174
+ });
175
+ }
176
+
177
+ // Update brand text with worklog title
178
+ if (brand && msg.title) {
179
+ brand.textContent = msg.title;
180
+ }
181
+ }
83
182
  } else if (msg.type === 'new_message' && msg.source === 'telegram') {
84
183
  addMessage(msg.role === 'assistant' ? 'agent' : (msg.role || 'user'), msg.content || '');
85
184
  }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # release.sh — 빌드 + 버전업 + npm publish 한 번에 처리
2
+ # release.sh — 빌드 + 버전업 + npm publish + GitHub Release 한 번에 처리
3
3
  set -e
4
4
 
5
5
  echo "🦈 cli-jaw release script"
@@ -21,10 +21,33 @@ npm version "$BUMP" --no-git-tag-version
21
21
  VERSION=$(node -p "require('./package.json').version")
22
22
  echo "📌 New version: $VERSION"
23
23
 
24
- # 4. npm publish
24
+ # 4. git commit + tag
25
+ echo "🏷️ Creating git tag v$VERSION..."
26
+ git add package.json package-lock.json
27
+ git commit -m "[agent] chore: release v$VERSION" --allow-empty
28
+ git tag "v$VERSION"
29
+ git push origin master
30
+ git push origin "v$VERSION"
31
+
32
+ # 5. npm publish
25
33
  echo "🚀 Publishing to npm..."
26
34
  npm publish --access public
27
35
 
36
+ # 6. GitHub Release (auto-generate notes from commits since last tag)
37
+ echo "📋 Creating GitHub Release..."
38
+ PREV_TAG=$(git tag --sort=-v:refname | grep -E '^v' | sed -n '2p')
39
+ if [ -n "$PREV_TAG" ] && command -v gh &>/dev/null; then
40
+ gh release create "v$VERSION" \
41
+ --title "v$VERSION" \
42
+ --generate-notes \
43
+ --notes-start-tag "$PREV_TAG" \
44
+ --latest
45
+ echo "✅ GitHub Release v$VERSION created!"
46
+ else
47
+ echo "⚠️ Skipped GitHub Release (gh CLI not found or no previous tag)"
48
+ fi
49
+
28
50
  echo ""
29
51
  echo "✅ cli-jaw@$VERSION published!"
30
52
  echo " Install: npm install -g cli-jaw"
53
+ echo " Release: https://github.com/lidge-jun/cli-jaw/releases/tag/v$VERSION"