2323 * PLANNOTATOR_PORT - Fixed port to use (default: random locally, 19432 for remote)
2424 */
2525
26- import {
27- startPlannotatorServer ,
28- handleServerReady ,
29- } from "@plannotator/server" ;
30- import {
31- startReviewServer ,
32- handleReviewServerReady ,
33- } from "@plannotator/server/review" ;
34- import {
35- startAnnotateServer ,
36- handleAnnotateServerReady ,
37- } from "@plannotator/server/annotate" ;
38- import { getGitContext , runGitDiff } from "@plannotator/server/git" ;
39- import { writeRemoteShareLink } from "@plannotator/server/share-url" ;
26+ import { handleServerReady , startPlannotatorServer } from '@plannotator/server' ;
27+ import { handleAnnotateServerReady , startAnnotateServer } from '@plannotator/server/annotate' ;
28+ import { getGitContext , runGitDiff } from '@plannotator/server/git' ;
29+ import { handleReviewServerReady , startReviewServer } from '@plannotator/server/review' ;
30+ import { writeRemoteShareLink } from '@plannotator/server/share-url' ;
4031
4132// Embed the built HTML at compile time
42- // @ts -ignore - Bun import attribute for text
43- import planHtml from "../dist/index.html" with { type : "text" } ;
33+ // @ts -expect-error - Bun import attribute for text
34+ import planHtml from '../dist/index.html' with { type : 'text' } ;
35+
4436const planHtmlContent = planHtml as unknown as string ;
4537
46- // @ts -ignore - Bun import attribute for text
47- import reviewHtml from "../dist/review.html" with { type : "text" } ;
38+ // @ts -expect-error - Bun import attribute for text
39+ import reviewHtml from '../dist/review.html' with { type : 'text' } ;
40+
4841const reviewHtmlContent = reviewHtml as unknown as string ;
4942
5043// Check for subcommand
5144const args = process . argv . slice ( 2 ) ;
5245
5346// Check if URL sharing is enabled (default: true)
54- const sharingEnabled = process . env . PLANNOTATOR_SHARE !== " disabled" ;
47+ const sharingEnabled = process . env . PLANNOTATOR_SHARE !== ' disabled' ;
5548
5649// Custom share portal URL for self-hosting
5750const shareBaseUrl = process . env . PLANNOTATOR_SHARE_URL || undefined ;
5851
5952// Paste service URL for short URL sharing
6053const pasteApiUrl = process . env . PLANNOTATOR_PASTE_URL || undefined ;
6154
62- if ( args [ 0 ] === " review" ) {
55+ if ( args [ 0 ] === ' review' ) {
6356 // ============================================
6457 // CODE REVIEW MODE
6558 // ============================================
@@ -68,18 +61,19 @@ if (args[0] === "review") {
6861 const gitContext = await getGitContext ( ) ;
6962
7063 // Run git diff HEAD (uncommitted changes - default)
71- const { patch : rawPatch , label : gitRef , error : diffError } = await runGitDiff (
72- "uncommitted" ,
73- gitContext . defaultBranch
74- ) ;
64+ const {
65+ patch : rawPatch ,
66+ label : gitRef ,
67+ error : diffError ,
68+ } = await runGitDiff ( 'uncommitted' , gitContext . defaultBranch ) ;
7569
7670 // Start review server (even if empty - user can switch diff types)
7771 const server = await startReviewServer ( {
7872 rawPatch,
7973 gitRef,
8074 error : diffError ,
81- origin : " claude-code" ,
82- diffType : " uncommitted" ,
75+ origin : ' claude-code' ,
76+ diffType : ' uncommitted' ,
8377 gitContext,
8478 sharingEnabled,
8579 shareBaseUrl,
@@ -88,7 +82,9 @@ if (args[0] === "review") {
8882 handleReviewServerReady ( url , isRemote , port ) ;
8983
9084 if ( isRemote && sharingEnabled && rawPatch ) {
91- await writeRemoteShareLink ( rawPatch , shareBaseUrl , "review changes" , "diff only" ) . catch ( ( ) => { } ) ;
85+ await writeRemoteShareLink ( rawPatch , shareBaseUrl , 'review changes' , 'diff only' ) . catch (
86+ ( ) => { } ,
87+ ) ;
9288 }
9389 } ,
9490 } ) ;
@@ -103,22 +99,21 @@ if (args[0] === "review") {
10399 server . stop ( ) ;
104100
105101 // Output feedback (captured by slash command)
106- console . log ( result . feedback || " No feedback provided." ) ;
102+ console . log ( result . feedback || ' No feedback provided.' ) ;
107103 process . exit ( 0 ) ;
108-
109- } else if ( args [ 0 ] === "annotate" ) {
104+ } else if ( args [ 0 ] === 'annotate' ) {
110105 // ============================================
111106 // ANNOTATE MODE
112107 // ============================================
113108
114109 const filePath = args [ 1 ] ;
115110 if ( ! filePath ) {
116- console . error ( " Usage: plannotator annotate <file.md>" ) ;
111+ console . error ( ' Usage: plannotator annotate <file.md>' ) ;
117112 process . exit ( 1 ) ;
118113 }
119114
120115 // Resolve to absolute path
121- const path = await import ( " path" ) ;
116+ const path = await import ( 'node: path' ) ;
122117 const absolutePath = path . resolve ( filePath ) ;
123118
124119 // Read the markdown file
@@ -133,15 +128,17 @@ if (args[0] === "review") {
133128 const server = await startAnnotateServer ( {
134129 markdown,
135130 filePath : absolutePath ,
136- origin : " claude-code" ,
131+ origin : ' claude-code' ,
137132 sharingEnabled,
138133 shareBaseUrl,
139134 htmlContent : planHtmlContent ,
140135 onReady : async ( url , isRemote , port ) => {
141136 handleAnnotateServerReady ( url , isRemote , port ) ;
142137
143138 if ( isRemote && sharingEnabled ) {
144- await writeRemoteShareLink ( markdown , shareBaseUrl , "annotate" , "document only" ) . catch ( ( ) => { } ) ;
139+ await writeRemoteShareLink ( markdown , shareBaseUrl , 'annotate' , 'document only' ) . catch (
140+ ( ) => { } ,
141+ ) ;
145142 }
146143 } ,
147144 } ) ;
@@ -156,9 +153,8 @@ if (args[0] === "review") {
156153 server . stop ( ) ;
157154
158155 // Output feedback (captured by slash command)
159- console . log ( result . feedback || " No feedback provided." ) ;
156+ console . log ( result . feedback || ' No feedback provided.' ) ;
160157 process . exit ( 0 ) ;
161-
162158} else {
163159 // ============================================
164160 // PLAN REVIEW MODE (default)
@@ -167,26 +163,26 @@ if (args[0] === "review") {
167163 // Read hook event from stdin
168164 const eventJson = await Bun . stdin . text ( ) ;
169165
170- let planContent = "" ;
171- let permissionMode = " default" ;
166+ let planContent = '' ;
167+ let permissionMode = ' default' ;
172168 try {
173169 const event = JSON . parse ( eventJson ) ;
174- planContent = event . tool_input ?. plan || "" ;
175- permissionMode = event . permission_mode || " default" ;
170+ planContent = event . tool_input ?. plan || '' ;
171+ permissionMode = event . permission_mode || ' default' ;
176172 } catch {
177- console . error ( " Failed to parse hook event from stdin" ) ;
173+ console . error ( ' Failed to parse hook event from stdin' ) ;
178174 process . exit ( 1 ) ;
179175 }
180176
181177 if ( ! planContent ) {
182- console . error ( " No plan content in hook event" ) ;
178+ console . error ( ' No plan content in hook event' ) ;
183179 process . exit ( 1 ) ;
184180 }
185181
186182 // Start the plan review server
187183 const server = await startPlannotatorServer ( {
188184 plan : planContent ,
189- origin : " claude-code" ,
185+ origin : ' claude-code' ,
190186 permissionMode,
191187 sharingEnabled,
192188 shareBaseUrl,
@@ -196,7 +192,9 @@ if (args[0] === "review") {
196192 handleServerReady ( url , isRemote , port ) ;
197193
198194 if ( isRemote && sharingEnabled ) {
199- await writeRemoteShareLink ( planContent , shareBaseUrl , "review the plan" , "plan only" ) . catch ( ( ) => { } ) ;
195+ await writeRemoteShareLink ( planContent , shareBaseUrl , 'review the plan' , 'plan only' ) . catch (
196+ ( ) => { } ,
197+ ) ;
200198 }
201199 } ,
202200 } ) ;
@@ -216,34 +214,34 @@ if (args[0] === "review") {
216214 const updatedPermissions = [ ] ;
217215 if ( result . permissionMode ) {
218216 updatedPermissions . push ( {
219- type : " setMode" ,
217+ type : ' setMode' ,
220218 mode : result . permissionMode ,
221- destination : " session" ,
219+ destination : ' session' ,
222220 } ) ;
223221 }
224222
225223 console . log (
226224 JSON . stringify ( {
227225 hookSpecificOutput : {
228- hookEventName : " PermissionRequest" ,
226+ hookEventName : ' PermissionRequest' ,
229227 decision : {
230- behavior : " allow" ,
228+ behavior : ' allow' ,
231229 ...( updatedPermissions . length > 0 && { updatedPermissions } ) ,
232230 } ,
233231 } ,
234- } )
232+ } ) ,
235233 ) ;
236234 } else {
237235 console . log (
238236 JSON . stringify ( {
239237 hookSpecificOutput : {
240- hookEventName : " PermissionRequest" ,
238+ hookEventName : ' PermissionRequest' ,
241239 decision : {
242- behavior : " deny" ,
243- message : result . feedback || " Plan changes requested" ,
240+ behavior : ' deny' ,
241+ message : result . feedback || ' Plan changes requested' ,
244242 } ,
245243 } ,
246- } )
244+ } ) ,
247245 ) ;
248246 }
249247
0 commit comments