prjct-cli 1.6.1 → 1.6.3
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/CHANGELOG.md +66 -0
- package/core/bus/bus.ts +41 -22
- package/core/commands/analysis.ts +17 -4
- package/core/index.ts +1 -1
- package/core/infrastructure/setup.ts +13 -12
- package/core/server/routes.ts +4 -3
- package/core/types/bus.ts +112 -1
- package/core/types/index.ts +16 -0
- package/dist/bin/prjct.mjs +71 -60
- package/dist/core/infrastructure/setup.js +45 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.3] - 2026-02-07
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- replace console.error with logger in setup.ts (PRJ-74) (#126)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [1.6.5] - 2026-02-07
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **Replace console.error with logger in setup.ts**: 12 `console.error` warning calls replaced with `log.warn` for Gemini, Cursor, Windsurf, Antigravity, migration, status line, Context7, symlink, and gitignore warnings. User-facing chalk output preserved. Fatal direct-run error kept as `console.error`.
|
|
15
|
+
|
|
16
|
+
## [1.6.4] - 2026-02-06
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
- **Replace console.error with logger in routes.ts**: Server routes now use the centralized `log` module instead of raw `console.error` for JSON read/write and context read errors. Production remains quiet by default; enable with `PRJCT_DEBUG=1`.
|
|
21
|
+
|
|
22
|
+
## [1.6.3] - 2026-02-06
|
|
23
|
+
|
|
24
|
+
### Improvements
|
|
25
|
+
|
|
26
|
+
- **Typed event bus payloads**: Added 15 typed payload interfaces (`SessionStartedPayload`, `SnapshotCreatedPayload`, etc.) and an `EventMap` type mapping event strings to their payloads. Convenience `emit` methods now enforce required fields at compile time. Backward compatible — callers with `Record<string, unknown>` still work.
|
|
27
|
+
|
|
28
|
+
### Implementation Details
|
|
29
|
+
- `core/types/bus.ts`: Added `EventMap` interface and all payload types
|
|
30
|
+
- `core/bus/bus.ts`: Generic overload `emit<K extends keyof EventMap>()`, typed convenience methods
|
|
31
|
+
- `core/types/index.ts`: Exported all new payload types
|
|
32
|
+
|
|
33
|
+
### Test Plan
|
|
34
|
+
|
|
35
|
+
#### For QA
|
|
36
|
+
1. `bun run typecheck` — zero errors
|
|
37
|
+
2. `emit.sessionStarted({})` → TS error for missing fields (IntelliSense works)
|
|
38
|
+
3. `bun test` — all 416 tests pass
|
|
39
|
+
|
|
40
|
+
#### For Users
|
|
41
|
+
- **What changed:** Event emit methods have typed payloads with autocomplete
|
|
42
|
+
- **Breaking changes:** None
|
|
43
|
+
|
|
44
|
+
## [1.6.2] - 2026-02-06
|
|
45
|
+
|
|
46
|
+
### Improvements
|
|
47
|
+
|
|
48
|
+
- **Diff preview before sync overwrites**: `prjct sync --dry-run` (or `--preview`) now shows what would change in CLAUDE.md without applying changes. Cancelling interactive sync restores the original file. Previously, files were written before the diff was shown, so cancel/preview still applied changes.
|
|
49
|
+
|
|
50
|
+
### Implementation Details
|
|
51
|
+
- Added `--dry-run` CLI flag as alias for `--preview`
|
|
52
|
+
- Added `restoreOriginal()` helper that writes back saved CLAUDE.md content on cancel/preview
|
|
53
|
+
- Non-interactive mode (LLM) restores original and returns JSON — apply with `prjct sync --yes`
|
|
54
|
+
|
|
55
|
+
### Test Plan
|
|
56
|
+
|
|
57
|
+
#### For QA
|
|
58
|
+
1. `prjct sync --dry-run` — diff shown, CLAUDE.md NOT modified
|
|
59
|
+
2. `prjct sync` → cancel — CLAUDE.md restored
|
|
60
|
+
3. `prjct sync` → approve — changes kept
|
|
61
|
+
4. `prjct sync --yes` — applied directly
|
|
62
|
+
5. `prjct sync --json` — JSON returned, CLAUDE.md restored
|
|
63
|
+
|
|
64
|
+
#### For Users
|
|
65
|
+
- **What changed:** `--dry-run` flag works correctly; cancel restores original
|
|
66
|
+
- **How to use:** `prjct sync --dry-run` to preview, `prjct sync --yes` to apply
|
|
67
|
+
- **Breaking changes:** None
|
|
68
|
+
|
|
3
69
|
## [1.6.1] - 2026-02-06
|
|
4
70
|
|
|
5
71
|
### Bug Fixes
|
package/core/bus/bus.ts
CHANGED
|
@@ -11,7 +11,27 @@ import fs from 'node:fs/promises'
|
|
|
11
11
|
import path from 'node:path'
|
|
12
12
|
import { getErrorMessage } from '../errors'
|
|
13
13
|
import pathManager from '../infrastructure/path-manager'
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type AnalysisCompletedPayload,
|
|
16
|
+
type EventCallback,
|
|
17
|
+
type EventData,
|
|
18
|
+
type EventMap,
|
|
19
|
+
EventTypes,
|
|
20
|
+
type FeaturePayload,
|
|
21
|
+
type GitCommitPayload,
|
|
22
|
+
type GitPushPayload,
|
|
23
|
+
type IdeaCapturedPayload,
|
|
24
|
+
type ProjectInitializedPayload,
|
|
25
|
+
type ProjectSyncedPayload,
|
|
26
|
+
type SessionCompletedPayload,
|
|
27
|
+
type SessionPausedPayload,
|
|
28
|
+
type SessionResumedPayload,
|
|
29
|
+
type SessionStartedPayload,
|
|
30
|
+
type SnapshotCreatedPayload,
|
|
31
|
+
type SnapshotRestoredPayload,
|
|
32
|
+
type TaskCompletedPayload,
|
|
33
|
+
type TaskCreatedPayload,
|
|
34
|
+
} from '../types'
|
|
15
35
|
import log from '../utils/logger'
|
|
16
36
|
|
|
17
37
|
class EventBus {
|
|
@@ -77,8 +97,10 @@ class EventBus {
|
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
/**
|
|
80
|
-
* Emit an event
|
|
100
|
+
* Emit an event with typed payload
|
|
81
101
|
*/
|
|
102
|
+
async emit<K extends keyof EventMap>(event: K, data: EventMap[K]): Promise<void>
|
|
103
|
+
async emit(event: string, data: Record<string, unknown>): Promise<void>
|
|
82
104
|
async emit(event: string, data: Record<string, unknown> = {}): Promise<void> {
|
|
83
105
|
const timestamp = new Date().toISOString()
|
|
84
106
|
const eventData: EventData = {
|
|
@@ -233,37 +255,34 @@ class EventBus {
|
|
|
233
255
|
// Singleton instance
|
|
234
256
|
const eventBus = new EventBus()
|
|
235
257
|
|
|
236
|
-
// Convenience methods for common events
|
|
258
|
+
// Convenience methods for common events (typed payloads)
|
|
237
259
|
const emit = {
|
|
238
|
-
sessionStarted: (data:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
eventBus.emit(EventTypes.SESSION_RESUMED, data),
|
|
243
|
-
sessionCompleted: (data: Record<string, unknown>) =>
|
|
260
|
+
sessionStarted: (data: SessionStartedPayload) => eventBus.emit(EventTypes.SESSION_STARTED, data),
|
|
261
|
+
sessionPaused: (data: SessionPausedPayload) => eventBus.emit(EventTypes.SESSION_PAUSED, data),
|
|
262
|
+
sessionResumed: (data: SessionResumedPayload) => eventBus.emit(EventTypes.SESSION_RESUMED, data),
|
|
263
|
+
sessionCompleted: (data: SessionCompletedPayload) =>
|
|
244
264
|
eventBus.emit(EventTypes.SESSION_COMPLETED, data),
|
|
245
265
|
|
|
246
|
-
taskCreated: (data:
|
|
247
|
-
taskCompleted: (data:
|
|
266
|
+
taskCreated: (data: TaskCreatedPayload) => eventBus.emit(EventTypes.TASK_CREATED, data),
|
|
267
|
+
taskCompleted: (data: TaskCompletedPayload) => eventBus.emit(EventTypes.TASK_COMPLETED, data),
|
|
248
268
|
|
|
249
|
-
featureAdded: (data:
|
|
250
|
-
featureShipped: (data:
|
|
251
|
-
eventBus.emit(EventTypes.FEATURE_SHIPPED, data),
|
|
269
|
+
featureAdded: (data: FeaturePayload) => eventBus.emit(EventTypes.FEATURE_ADDED, data),
|
|
270
|
+
featureShipped: (data: FeaturePayload) => eventBus.emit(EventTypes.FEATURE_SHIPPED, data),
|
|
252
271
|
|
|
253
|
-
ideaCaptured: (data:
|
|
272
|
+
ideaCaptured: (data: IdeaCapturedPayload) => eventBus.emit(EventTypes.IDEA_CAPTURED, data),
|
|
254
273
|
|
|
255
|
-
snapshotCreated: (data:
|
|
274
|
+
snapshotCreated: (data: SnapshotCreatedPayload) =>
|
|
256
275
|
eventBus.emit(EventTypes.SNAPSHOT_CREATED, data),
|
|
257
|
-
snapshotRestored: (data:
|
|
276
|
+
snapshotRestored: (data: SnapshotRestoredPayload) =>
|
|
258
277
|
eventBus.emit(EventTypes.SNAPSHOT_RESTORED, data),
|
|
259
278
|
|
|
260
|
-
commitCreated: (data:
|
|
261
|
-
pushCompleted: (data:
|
|
279
|
+
commitCreated: (data: GitCommitPayload) => eventBus.emit(EventTypes.COMMIT_CREATED, data),
|
|
280
|
+
pushCompleted: (data: GitPushPayload) => eventBus.emit(EventTypes.PUSH_COMPLETED, data),
|
|
262
281
|
|
|
263
|
-
projectInitialized: (data:
|
|
282
|
+
projectInitialized: (data: ProjectInitializedPayload) =>
|
|
264
283
|
eventBus.emit(EventTypes.PROJECT_INITIALIZED, data),
|
|
265
|
-
projectSynced: (data:
|
|
266
|
-
analysisCompleted: (data:
|
|
284
|
+
projectSynced: (data: ProjectSyncedPayload) => eventBus.emit(EventTypes.PROJECT_SYNCED, data),
|
|
285
|
+
analysisCompleted: (data: AnalysisCompletedPayload) =>
|
|
267
286
|
eventBus.emit(EventTypes.ANALYSIS_COMPLETED, data),
|
|
268
287
|
}
|
|
269
288
|
|
|
@@ -347,8 +347,18 @@ export class AnalysisCommands extends PrjctCommandsBase {
|
|
|
347
347
|
return { success: true, message: 'No changes' }
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
+
// Helper to restore original CLAUDE.md (undo sync's write)
|
|
351
|
+
const restoreOriginal = async () => {
|
|
352
|
+
if (existingContent != null) {
|
|
353
|
+
await fs.writeFile(claudeMdPath, existingContent, 'utf-8')
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
350
357
|
// Non-interactive mode: return JSON for LLM to handle
|
|
351
358
|
if (isNonInteractive) {
|
|
359
|
+
// Restore original — LLM will call `prjct sync --yes` to apply
|
|
360
|
+
await restoreOriginal()
|
|
361
|
+
|
|
352
362
|
// Build a plain-text diff summary for LLM to show user
|
|
353
363
|
const diffSummary = {
|
|
354
364
|
added: diff.added.map((s) => ({ name: s.name, lineCount: s.lineCount })),
|
|
@@ -388,8 +398,9 @@ export class AnalysisCommands extends PrjctCommandsBase {
|
|
|
388
398
|
// Show diff preview (interactive mode)
|
|
389
399
|
console.log(formatDiffPreview(diff))
|
|
390
400
|
|
|
391
|
-
// Preview-only mode - don't apply
|
|
401
|
+
// Preview-only mode (--preview / --dry-run) - restore and don't apply
|
|
392
402
|
if (options.preview) {
|
|
403
|
+
await restoreOriginal()
|
|
393
404
|
return {
|
|
394
405
|
success: true,
|
|
395
406
|
isPreview: true,
|
|
@@ -411,7 +422,8 @@ export class AnalysisCommands extends PrjctCommandsBase {
|
|
|
411
422
|
})
|
|
412
423
|
|
|
413
424
|
if (response.action === 'cancel' || !response.action) {
|
|
414
|
-
|
|
425
|
+
await restoreOriginal()
|
|
426
|
+
out.warn('Sync cancelled — no changes applied')
|
|
415
427
|
return { success: false, message: 'Cancelled by user' }
|
|
416
428
|
}
|
|
417
429
|
|
|
@@ -424,12 +436,13 @@ export class AnalysisCommands extends PrjctCommandsBase {
|
|
|
424
436
|
initial: true,
|
|
425
437
|
})
|
|
426
438
|
if (!confirm.apply) {
|
|
427
|
-
|
|
439
|
+
await restoreOriginal()
|
|
440
|
+
out.warn('Sync cancelled — no changes applied')
|
|
428
441
|
return { success: false, message: 'Cancelled by user' }
|
|
429
442
|
}
|
|
430
443
|
}
|
|
431
444
|
|
|
432
|
-
//
|
|
445
|
+
// User approved — changes already applied by sync
|
|
433
446
|
out.done('Changes applied')
|
|
434
447
|
return this.showSyncResult(result, startTime)
|
|
435
448
|
}
|
package/core/index.ts
CHANGED
|
@@ -162,7 +162,7 @@ async function main(): Promise<void> {
|
|
|
162
162
|
sync: () =>
|
|
163
163
|
commands.sync(process.cwd(), {
|
|
164
164
|
aiTools: options.agents ? String(options.agents).split(',') : undefined,
|
|
165
|
-
preview: options.preview === true,
|
|
165
|
+
preview: options.preview === true || options['dry-run'] === true,
|
|
166
166
|
yes: options.yes === true,
|
|
167
167
|
json: options.json === true,
|
|
168
168
|
package: options.package ? String(options.package) : undefined,
|
|
@@ -27,6 +27,7 @@ import { dependencyValidator } from '../services/dependency-validator'
|
|
|
27
27
|
import { isNotFoundError } from '../types/fs'
|
|
28
28
|
import type { AIProviderConfig, AIProviderName } from '../types/provider'
|
|
29
29
|
import { fileExists } from '../utils/fs-helpers'
|
|
30
|
+
import log from '../utils/logger'
|
|
30
31
|
import { getPackageRoot, VERSION } from '../utils/version'
|
|
31
32
|
import {
|
|
32
33
|
detectAllProviders,
|
|
@@ -270,7 +271,7 @@ async function installGeminiRouter(): Promise<boolean> {
|
|
|
270
271
|
}
|
|
271
272
|
return false
|
|
272
273
|
} catch (error) {
|
|
273
|
-
|
|
274
|
+
log.warn(`Gemini router warning: ${(error as Error).message}`)
|
|
274
275
|
return false
|
|
275
276
|
}
|
|
276
277
|
}
|
|
@@ -340,7 +341,7 @@ async function installGeminiGlobalConfig(): Promise<{ success: boolean; action:
|
|
|
340
341
|
await fs.writeFile(globalConfigPath, updatedContent, 'utf-8')
|
|
341
342
|
return { success: true, action: 'updated' }
|
|
342
343
|
} catch (error) {
|
|
343
|
-
|
|
344
|
+
log.warn(`Gemini config warning: ${(error as Error).message}`)
|
|
344
345
|
return { success: false, action: null }
|
|
345
346
|
}
|
|
346
347
|
}
|
|
@@ -373,7 +374,7 @@ export async function installAntigravitySkill(): Promise<{
|
|
|
373
374
|
|
|
374
375
|
// Read template content
|
|
375
376
|
if (!(await fileExists(templatePath))) {
|
|
376
|
-
|
|
377
|
+
log.warn('Antigravity SKILL.md template not found')
|
|
377
378
|
return { success: false, action: null }
|
|
378
379
|
}
|
|
379
380
|
|
|
@@ -384,7 +385,7 @@ export async function installAntigravitySkill(): Promise<{
|
|
|
384
385
|
|
|
385
386
|
return { success: true, action: skillExists ? 'updated' : 'created' }
|
|
386
387
|
} catch (error) {
|
|
387
|
-
|
|
388
|
+
log.warn(`Antigravity skill warning: ${(error as Error).message}`)
|
|
388
389
|
return { success: false, action: null }
|
|
389
390
|
}
|
|
390
391
|
}
|
|
@@ -465,7 +466,7 @@ export async function installCursorProject(projectRoot: string): Promise<{
|
|
|
465
466
|
result.success = result.rulesCreated || result.commandsCreated
|
|
466
467
|
return result
|
|
467
468
|
} catch (error) {
|
|
468
|
-
|
|
469
|
+
log.warn(`Cursor installation warning: ${(error as Error).message}`)
|
|
469
470
|
return result
|
|
470
471
|
}
|
|
471
472
|
}
|
|
@@ -515,7 +516,7 @@ async function addCursorToGitignore(projectRoot: string): Promise<boolean> {
|
|
|
515
516
|
await fs.writeFile(gitignorePath, newContent, 'utf-8')
|
|
516
517
|
return true
|
|
517
518
|
} catch (error) {
|
|
518
|
-
|
|
519
|
+
log.warn(`Gitignore update warning: ${(error as Error).message}`)
|
|
519
520
|
return false
|
|
520
521
|
}
|
|
521
522
|
}
|
|
@@ -615,7 +616,7 @@ export async function installWindsurfProject(projectRoot: string): Promise<{
|
|
|
615
616
|
result.success = result.rulesCreated || result.workflowsCreated
|
|
616
617
|
return result
|
|
617
618
|
} catch (error) {
|
|
618
|
-
|
|
619
|
+
log.warn(`Windsurf installation warning: ${(error as Error).message}`)
|
|
619
620
|
return result
|
|
620
621
|
}
|
|
621
622
|
}
|
|
@@ -665,7 +666,7 @@ async function addWindsurfToGitignore(projectRoot: string): Promise<boolean> {
|
|
|
665
666
|
await fs.writeFile(gitignorePath, newContent, 'utf-8')
|
|
666
667
|
return true
|
|
667
668
|
} catch (error) {
|
|
668
|
-
|
|
669
|
+
log.warn(`Gitignore update warning: ${(error as Error).message}`)
|
|
669
670
|
return false
|
|
670
671
|
}
|
|
671
672
|
}
|
|
@@ -738,7 +739,7 @@ async function migrateProjectsCliVersion(): Promise<void> {
|
|
|
738
739
|
// Silently fail if projects directory doesn't exist
|
|
739
740
|
if (!isNotFoundError(error)) {
|
|
740
741
|
// Log unexpected errors but don't crash - migration is optional
|
|
741
|
-
|
|
742
|
+
log.warn(`Migration warning: ${(error as Error).message}`)
|
|
742
743
|
}
|
|
743
744
|
}
|
|
744
745
|
}
|
|
@@ -912,7 +913,7 @@ echo "prjct"
|
|
|
912
913
|
// Silently fail if directories don't exist
|
|
913
914
|
if (!isNotFoundError(error)) {
|
|
914
915
|
// Log unexpected errors but don't crash - status line is optional
|
|
915
|
-
|
|
916
|
+
log.warn(`Status line warning: ${(error as Error).message}`)
|
|
916
917
|
}
|
|
917
918
|
}
|
|
918
919
|
}
|
|
@@ -965,7 +966,7 @@ async function installContext7MCP(): Promise<void> {
|
|
|
965
966
|
}
|
|
966
967
|
} catch (error) {
|
|
967
968
|
// Non-fatal error, just log
|
|
968
|
-
|
|
969
|
+
log.warn(`Context7 MCP setup warning: ${(error as Error).message}`)
|
|
969
970
|
}
|
|
970
971
|
}
|
|
971
972
|
|
|
@@ -1018,7 +1019,7 @@ async function ensureStatusLineSymlink(linkPath: string, targetPath: string): Pr
|
|
|
1018
1019
|
} catch (copyError) {
|
|
1019
1020
|
// Both symlink and copy failed - log if unexpected error
|
|
1020
1021
|
if (!isNotFoundError(copyError)) {
|
|
1021
|
-
|
|
1022
|
+
log.warn(`Symlink fallback warning: ${(copyError as Error).message}`)
|
|
1022
1023
|
}
|
|
1023
1024
|
}
|
|
1024
1025
|
}
|
package/core/server/routes.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { Hono } from 'hono'
|
|
|
12
12
|
import * as jsonc from 'jsonc-parser'
|
|
13
13
|
import pathManager from '../infrastructure/path-manager'
|
|
14
14
|
import { isNotFoundError } from '../types/fs'
|
|
15
|
+
import log from '../utils/logger'
|
|
15
16
|
|
|
16
17
|
// Storage paths relative to project data directory
|
|
17
18
|
const STORAGE_PATHS = {
|
|
@@ -34,7 +35,7 @@ async function readJsonFile<T>(filePath: string): Promise<T | null> {
|
|
|
34
35
|
} catch (error) {
|
|
35
36
|
// ENOENT or parse error - expected for new projects
|
|
36
37
|
if (!isNotFoundError(error) && !(error instanceof SyntaxError)) {
|
|
37
|
-
|
|
38
|
+
log.error(`JSON read error: ${(error as Error).message}`)
|
|
38
39
|
}
|
|
39
40
|
return null
|
|
40
41
|
}
|
|
@@ -49,7 +50,7 @@ async function writeJsonFile(filePath: string, data: unknown): Promise<boolean>
|
|
|
49
50
|
await fs.writeFile(filePath, `${JSON.stringify(data, null, 2)}\n`, 'utf-8')
|
|
50
51
|
return true
|
|
51
52
|
} catch (error) {
|
|
52
|
-
|
|
53
|
+
log.error(`JSON write error: ${(error as Error).message}`)
|
|
53
54
|
return false
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -165,7 +166,7 @@ export function createRoutes(projectId: string, _projectPath: string): Hono {
|
|
|
165
166
|
} catch (error) {
|
|
166
167
|
// ENOENT - context file doesn't exist yet (expected)
|
|
167
168
|
if (!isNotFoundError(error)) {
|
|
168
|
-
|
|
169
|
+
log.error(`Context read error: ${(error as Error).message}`)
|
|
169
170
|
}
|
|
170
171
|
return c.text('', 200, { 'Content-Type': 'text/markdown' })
|
|
171
172
|
}
|
package/core/types/bus.ts
CHANGED
|
@@ -58,7 +58,7 @@ export const EventTypes = {
|
|
|
58
58
|
export type BusEventType = (typeof EventTypes)[keyof typeof EventTypes]
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* Event data payload
|
|
61
|
+
* Event data payload (base interface for all events)
|
|
62
62
|
*/
|
|
63
63
|
export interface EventData {
|
|
64
64
|
type: string
|
|
@@ -67,6 +67,117 @@ export interface EventData {
|
|
|
67
67
|
[key: string]: unknown
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// Typed Event Payloads
|
|
72
|
+
// =============================================================================
|
|
73
|
+
|
|
74
|
+
export interface SessionStartedPayload {
|
|
75
|
+
sessionId: string
|
|
76
|
+
task: unknown
|
|
77
|
+
projectId: string | null
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface SessionPausedPayload {
|
|
81
|
+
sessionId: string
|
|
82
|
+
task: unknown
|
|
83
|
+
duration: number
|
|
84
|
+
projectId: string | null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface SessionResumedPayload {
|
|
88
|
+
sessionId: string
|
|
89
|
+
task: unknown
|
|
90
|
+
projectId: string | null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface SessionCompletedPayload {
|
|
94
|
+
sessionId: string
|
|
95
|
+
task: unknown
|
|
96
|
+
duration: number
|
|
97
|
+
metrics: unknown
|
|
98
|
+
projectId: string | null
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface TaskCreatedPayload {
|
|
102
|
+
taskId: string
|
|
103
|
+
description: string
|
|
104
|
+
[key: string]: unknown
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface TaskCompletedPayload {
|
|
108
|
+
taskId: string
|
|
109
|
+
[key: string]: unknown
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface FeaturePayload {
|
|
113
|
+
[key: string]: unknown
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface IdeaCapturedPayload {
|
|
117
|
+
[key: string]: unknown
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface SnapshotCreatedPayload {
|
|
121
|
+
hash: string
|
|
122
|
+
message: string
|
|
123
|
+
timestamp: string
|
|
124
|
+
filesCount: number
|
|
125
|
+
projectId: string | null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface SnapshotRestoredPayload {
|
|
129
|
+
hash: string
|
|
130
|
+
filesCount: number
|
|
131
|
+
timestamp: string
|
|
132
|
+
projectId: string | null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface GitCommitPayload {
|
|
136
|
+
[key: string]: unknown
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface GitPushPayload {
|
|
140
|
+
[key: string]: unknown
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface ProjectInitializedPayload {
|
|
144
|
+
[key: string]: unknown
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface ProjectSyncedPayload {
|
|
148
|
+
[key: string]: unknown
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface AnalysisCompletedPayload {
|
|
152
|
+
[key: string]: unknown
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Maps event type strings to their typed payloads
|
|
157
|
+
*/
|
|
158
|
+
export interface EventMap {
|
|
159
|
+
[EventTypes.SESSION_STARTED]: SessionStartedPayload
|
|
160
|
+
[EventTypes.SESSION_PAUSED]: SessionPausedPayload
|
|
161
|
+
[EventTypes.SESSION_RESUMED]: SessionResumedPayload
|
|
162
|
+
[EventTypes.SESSION_COMPLETED]: SessionCompletedPayload
|
|
163
|
+
[EventTypes.TASK_CREATED]: TaskCreatedPayload
|
|
164
|
+
[EventTypes.TASK_COMPLETED]: TaskCompletedPayload
|
|
165
|
+
[EventTypes.TASK_UPDATED]: Record<string, unknown>
|
|
166
|
+
[EventTypes.FEATURE_ADDED]: FeaturePayload
|
|
167
|
+
[EventTypes.FEATURE_SHIPPED]: FeaturePayload
|
|
168
|
+
[EventTypes.FEATURE_UPDATED]: FeaturePayload
|
|
169
|
+
[EventTypes.IDEA_CAPTURED]: IdeaCapturedPayload
|
|
170
|
+
[EventTypes.IDEA_PROMOTED]: Record<string, unknown>
|
|
171
|
+
[EventTypes.SNAPSHOT_CREATED]: SnapshotCreatedPayload
|
|
172
|
+
[EventTypes.SNAPSHOT_RESTORED]: SnapshotRestoredPayload
|
|
173
|
+
[EventTypes.COMMIT_CREATED]: GitCommitPayload
|
|
174
|
+
[EventTypes.PUSH_COMPLETED]: GitPushPayload
|
|
175
|
+
[EventTypes.PROJECT_INITIALIZED]: ProjectInitializedPayload
|
|
176
|
+
[EventTypes.PROJECT_SYNCED]: ProjectSyncedPayload
|
|
177
|
+
[EventTypes.ANALYSIS_COMPLETED]: AnalysisCompletedPayload
|
|
178
|
+
[EventTypes.ALL]: Record<string, unknown>
|
|
179
|
+
}
|
|
180
|
+
|
|
70
181
|
/**
|
|
71
182
|
* Event callback handler
|
|
72
183
|
*/
|
package/core/types/index.ts
CHANGED
|
@@ -118,10 +118,26 @@ export type {
|
|
|
118
118
|
// Bus Types
|
|
119
119
|
// =============================================================================
|
|
120
120
|
export type {
|
|
121
|
+
AnalysisCompletedPayload,
|
|
121
122
|
BusEventType,
|
|
122
123
|
EventCallback,
|
|
123
124
|
EventData,
|
|
125
|
+
EventMap,
|
|
124
126
|
EventSubscription,
|
|
127
|
+
FeaturePayload,
|
|
128
|
+
GitCommitPayload,
|
|
129
|
+
GitPushPayload,
|
|
130
|
+
IdeaCapturedPayload,
|
|
131
|
+
ProjectInitializedPayload,
|
|
132
|
+
ProjectSyncedPayload,
|
|
133
|
+
SessionCompletedPayload,
|
|
134
|
+
SessionPausedPayload,
|
|
135
|
+
SessionResumedPayload,
|
|
136
|
+
SessionStartedPayload,
|
|
137
|
+
SnapshotCreatedPayload,
|
|
138
|
+
SnapshotRestoredPayload,
|
|
139
|
+
TaskCompletedPayload,
|
|
140
|
+
TaskCreatedPayload,
|
|
125
141
|
} from './bus'
|
|
126
142
|
export { EventTypes } from './bus'
|
|
127
143
|
// =============================================================================
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -2092,6 +2092,45 @@ var init_editors_config = __esm({
|
|
|
2092
2092
|
}
|
|
2093
2093
|
});
|
|
2094
2094
|
|
|
2095
|
+
// core/utils/logger.ts
|
|
2096
|
+
function getLogLevel() {
|
|
2097
|
+
const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || "";
|
|
2098
|
+
if (!debugEnv) return { level: -1, name: "disabled" };
|
|
2099
|
+
if (TRUTHY_VALUES.has(debugEnv) || debugEnv.includes("prjct")) {
|
|
2100
|
+
return { level: LEVELS.debug, name: "debug" };
|
|
2101
|
+
}
|
|
2102
|
+
const levelValue = LEVELS[debugEnv] ?? -1;
|
|
2103
|
+
const levelName = levelValue >= 0 ? debugEnv : "disabled";
|
|
2104
|
+
return { level: levelValue, name: levelName };
|
|
2105
|
+
}
|
|
2106
|
+
function createLogMethod(levelThreshold, prefix, method) {
|
|
2107
|
+
return currentLevel >= levelThreshold ? (...args2) => console[method](prefix, ...args2) : noop;
|
|
2108
|
+
}
|
|
2109
|
+
var LEVELS, TRUTHY_VALUES, currentLevel, currentLevelName, noop, logger, logger_default;
|
|
2110
|
+
var init_logger = __esm({
|
|
2111
|
+
"core/utils/logger.ts"() {
|
|
2112
|
+
"use strict";
|
|
2113
|
+
LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
2114
|
+
TRUTHY_VALUES = /* @__PURE__ */ new Set(["1", "true", "*"]);
|
|
2115
|
+
__name(getLogLevel, "getLogLevel");
|
|
2116
|
+
({ level: currentLevel, name: currentLevelName } = getLogLevel());
|
|
2117
|
+
noop = /* @__PURE__ */ __name(() => {
|
|
2118
|
+
}, "noop");
|
|
2119
|
+
__name(createLogMethod, "createLogMethod");
|
|
2120
|
+
logger = {
|
|
2121
|
+
error: createLogMethod(LEVELS.error, "[prjct:error]", "error"),
|
|
2122
|
+
warn: createLogMethod(LEVELS.warn, "[prjct:warn]", "warn"),
|
|
2123
|
+
info: createLogMethod(LEVELS.info, "[prjct:info]", "log"),
|
|
2124
|
+
debug: createLogMethod(LEVELS.debug, "[prjct:debug]", "log"),
|
|
2125
|
+
// Check if logging is enabled (useful for expensive log prep)
|
|
2126
|
+
isEnabled: /* @__PURE__ */ __name(() => currentLevel >= 0, "isEnabled"),
|
|
2127
|
+
// Get current level name (pre-computed, no runtime lookup)
|
|
2128
|
+
level: /* @__PURE__ */ __name(() => currentLevelName, "level")
|
|
2129
|
+
};
|
|
2130
|
+
logger_default = logger;
|
|
2131
|
+
}
|
|
2132
|
+
});
|
|
2133
|
+
|
|
2095
2134
|
// core/utils/branding.ts
|
|
2096
2135
|
import chalk from "chalk";
|
|
2097
2136
|
var SPINNER_FRAMES, SPINNER_SPEED, branding, branding_default;
|
|
@@ -19160,7 +19199,13 @@ var init_analysis2 = __esm({
|
|
|
19160
19199
|
output_default.done("No changes detected (context is up to date)");
|
|
19161
19200
|
return { success: true, message: "No changes" };
|
|
19162
19201
|
}
|
|
19202
|
+
const restoreOriginal = /* @__PURE__ */ __name(async () => {
|
|
19203
|
+
if (existingContent != null) {
|
|
19204
|
+
await fs36.writeFile(claudeMdPath, existingContent, "utf-8");
|
|
19205
|
+
}
|
|
19206
|
+
}, "restoreOriginal");
|
|
19163
19207
|
if (isNonInteractive) {
|
|
19208
|
+
await restoreOriginal();
|
|
19164
19209
|
const diffSummary = {
|
|
19165
19210
|
added: diff.added.map((s) => ({ name: s.name, lineCount: s.lineCount })),
|
|
19166
19211
|
modified: diff.modified.map((s) => ({ name: s.name, lineCount: s.lineCount })),
|
|
@@ -19193,6 +19238,7 @@ var init_analysis2 = __esm({
|
|
|
19193
19238
|
}
|
|
19194
19239
|
console.log(formatDiffPreview(diff));
|
|
19195
19240
|
if (options.preview) {
|
|
19241
|
+
await restoreOriginal();
|
|
19196
19242
|
return {
|
|
19197
19243
|
success: true,
|
|
19198
19244
|
isPreview: true,
|
|
@@ -19211,7 +19257,8 @@ var init_analysis2 = __esm({
|
|
|
19211
19257
|
]
|
|
19212
19258
|
});
|
|
19213
19259
|
if (response.action === "cancel" || !response.action) {
|
|
19214
|
-
|
|
19260
|
+
await restoreOriginal();
|
|
19261
|
+
output_default.warn("Sync cancelled \u2014 no changes applied");
|
|
19215
19262
|
return { success: false, message: "Cancelled by user" };
|
|
19216
19263
|
}
|
|
19217
19264
|
if (response.action === "diff") {
|
|
@@ -19224,7 +19271,8 @@ ${formatFullDiff(diff)}`);
|
|
|
19224
19271
|
initial: true
|
|
19225
19272
|
});
|
|
19226
19273
|
if (!confirm.apply) {
|
|
19227
|
-
|
|
19274
|
+
await restoreOriginal();
|
|
19275
|
+
output_default.warn("Sync cancelled \u2014 no changes applied");
|
|
19228
19276
|
return { success: false, message: "Cancelled by user" };
|
|
19229
19277
|
}
|
|
19230
19278
|
}
|
|
@@ -21052,45 +21100,6 @@ var init_ai_tools = __esm({
|
|
|
21052
21100
|
}
|
|
21053
21101
|
});
|
|
21054
21102
|
|
|
21055
|
-
// core/utils/logger.ts
|
|
21056
|
-
function getLogLevel() {
|
|
21057
|
-
const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || "";
|
|
21058
|
-
if (!debugEnv) return { level: -1, name: "disabled" };
|
|
21059
|
-
if (TRUTHY_VALUES.has(debugEnv) || debugEnv.includes("prjct")) {
|
|
21060
|
-
return { level: LEVELS.debug, name: "debug" };
|
|
21061
|
-
}
|
|
21062
|
-
const levelValue = LEVELS[debugEnv] ?? -1;
|
|
21063
|
-
const levelName = levelValue >= 0 ? debugEnv : "disabled";
|
|
21064
|
-
return { level: levelValue, name: levelName };
|
|
21065
|
-
}
|
|
21066
|
-
function createLogMethod(levelThreshold, prefix, method) {
|
|
21067
|
-
return currentLevel >= levelThreshold ? (...args2) => console[method](prefix, ...args2) : noop;
|
|
21068
|
-
}
|
|
21069
|
-
var LEVELS, TRUTHY_VALUES, currentLevel, currentLevelName, noop, logger2, logger_default;
|
|
21070
|
-
var init_logger = __esm({
|
|
21071
|
-
"core/utils/logger.ts"() {
|
|
21072
|
-
"use strict";
|
|
21073
|
-
LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
21074
|
-
TRUTHY_VALUES = /* @__PURE__ */ new Set(["1", "true", "*"]);
|
|
21075
|
-
__name(getLogLevel, "getLogLevel");
|
|
21076
|
-
({ level: currentLevel, name: currentLevelName } = getLogLevel());
|
|
21077
|
-
noop = /* @__PURE__ */ __name(() => {
|
|
21078
|
-
}, "noop");
|
|
21079
|
-
__name(createLogMethod, "createLogMethod");
|
|
21080
|
-
logger2 = {
|
|
21081
|
-
error: createLogMethod(LEVELS.error, "[prjct:error]", "error"),
|
|
21082
|
-
warn: createLogMethod(LEVELS.warn, "[prjct:warn]", "warn"),
|
|
21083
|
-
info: createLogMethod(LEVELS.info, "[prjct:info]", "log"),
|
|
21084
|
-
debug: createLogMethod(LEVELS.debug, "[prjct:debug]", "log"),
|
|
21085
|
-
// Check if logging is enabled (useful for expensive log prep)
|
|
21086
|
-
isEnabled: /* @__PURE__ */ __name(() => currentLevel >= 0, "isEnabled"),
|
|
21087
|
-
// Get current level name (pre-computed, no runtime lookup)
|
|
21088
|
-
level: /* @__PURE__ */ __name(() => currentLevelName, "level")
|
|
21089
|
-
};
|
|
21090
|
-
logger_default = logger2;
|
|
21091
|
-
}
|
|
21092
|
-
});
|
|
21093
|
-
|
|
21094
21103
|
// core/services/context-generator.ts
|
|
21095
21104
|
import fs39 from "node:fs/promises";
|
|
21096
21105
|
import path43 from "node:path";
|
|
@@ -24672,7 +24681,7 @@ async function installGeminiRouter() {
|
|
|
24672
24681
|
}
|
|
24673
24682
|
return false;
|
|
24674
24683
|
} catch (error) {
|
|
24675
|
-
|
|
24684
|
+
logger_default.warn(`Gemini router warning: ${error.message}`);
|
|
24676
24685
|
return false;
|
|
24677
24686
|
}
|
|
24678
24687
|
}
|
|
@@ -24721,7 +24730,7 @@ ${templateContent}`;
|
|
|
24721
24730
|
await fs47.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
24722
24731
|
return { success: true, action: "updated" };
|
|
24723
24732
|
} catch (error) {
|
|
24724
|
-
|
|
24733
|
+
logger_default.warn(`Gemini config warning: ${error.message}`);
|
|
24725
24734
|
return { success: false, action: null };
|
|
24726
24735
|
}
|
|
24727
24736
|
}
|
|
@@ -24734,14 +24743,14 @@ async function installAntigravitySkill() {
|
|
|
24734
24743
|
await fs47.mkdir(prjctSkillDir, { recursive: true });
|
|
24735
24744
|
const skillExists = await fileExists(skillMdPath);
|
|
24736
24745
|
if (!await fileExists(templatePath)) {
|
|
24737
|
-
|
|
24746
|
+
logger_default.warn("Antigravity SKILL.md template not found");
|
|
24738
24747
|
return { success: false, action: null };
|
|
24739
24748
|
}
|
|
24740
24749
|
const templateContent = await fs47.readFile(templatePath, "utf-8");
|
|
24741
24750
|
await fs47.writeFile(skillMdPath, templateContent, "utf-8");
|
|
24742
24751
|
return { success: true, action: skillExists ? "updated" : "created" };
|
|
24743
24752
|
} catch (error) {
|
|
24744
|
-
|
|
24753
|
+
logger_default.warn(`Antigravity skill warning: ${error.message}`);
|
|
24745
24754
|
return { success: false, action: null };
|
|
24746
24755
|
}
|
|
24747
24756
|
}
|
|
@@ -24782,7 +24791,7 @@ async function installCursorProject(projectRoot) {
|
|
|
24782
24791
|
result.success = result.rulesCreated || result.commandsCreated;
|
|
24783
24792
|
return result;
|
|
24784
24793
|
} catch (error) {
|
|
24785
|
-
|
|
24794
|
+
logger_default.warn(`Cursor installation warning: ${error.message}`);
|
|
24786
24795
|
return result;
|
|
24787
24796
|
}
|
|
24788
24797
|
}
|
|
@@ -24821,7 +24830,7 @@ ${entriesToAdd.join("\n")}
|
|
|
24821
24830
|
await fs47.writeFile(gitignorePath, newContent, "utf-8");
|
|
24822
24831
|
return true;
|
|
24823
24832
|
} catch (error) {
|
|
24824
|
-
|
|
24833
|
+
logger_default.warn(`Gitignore update warning: ${error.message}`);
|
|
24825
24834
|
return false;
|
|
24826
24835
|
}
|
|
24827
24836
|
}
|
|
@@ -24873,7 +24882,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
24873
24882
|
result.success = result.rulesCreated || result.workflowsCreated;
|
|
24874
24883
|
return result;
|
|
24875
24884
|
} catch (error) {
|
|
24876
|
-
|
|
24885
|
+
logger_default.warn(`Windsurf installation warning: ${error.message}`);
|
|
24877
24886
|
return result;
|
|
24878
24887
|
}
|
|
24879
24888
|
}
|
|
@@ -24912,7 +24921,7 @@ ${entriesToAdd.join("\n")}
|
|
|
24912
24921
|
await fs47.writeFile(gitignorePath, newContent, "utf-8");
|
|
24913
24922
|
return true;
|
|
24914
24923
|
} catch (error) {
|
|
24915
|
-
|
|
24924
|
+
logger_default.warn(`Gitignore update warning: ${error.message}`);
|
|
24916
24925
|
return false;
|
|
24917
24926
|
}
|
|
24918
24927
|
}
|
|
@@ -24956,7 +24965,7 @@ async function migrateProjectsCliVersion() {
|
|
|
24956
24965
|
}
|
|
24957
24966
|
} catch (error) {
|
|
24958
24967
|
if (!isNotFoundError(error)) {
|
|
24959
|
-
|
|
24968
|
+
logger_default.warn(`Migration warning: ${error.message}`);
|
|
24960
24969
|
}
|
|
24961
24970
|
}
|
|
24962
24971
|
}
|
|
@@ -25080,7 +25089,7 @@ echo "prjct"
|
|
|
25080
25089
|
await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
25081
25090
|
} catch (error) {
|
|
25082
25091
|
if (!isNotFoundError(error)) {
|
|
25083
|
-
|
|
25092
|
+
logger_default.warn(`Status line warning: ${error.message}`);
|
|
25084
25093
|
}
|
|
25085
25094
|
}
|
|
25086
25095
|
}
|
|
@@ -25112,7 +25121,7 @@ async function installContext7MCP() {
|
|
|
25112
25121
|
await fs47.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
25113
25122
|
}
|
|
25114
25123
|
} catch (error) {
|
|
25115
|
-
|
|
25124
|
+
logger_default.warn(`Context7 MCP setup warning: ${error.message}`);
|
|
25116
25125
|
}
|
|
25117
25126
|
}
|
|
25118
25127
|
async function installStatusLineModules(sourceDir, destDir) {
|
|
@@ -25150,7 +25159,7 @@ async function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
|
25150
25159
|
}
|
|
25151
25160
|
} catch (copyError) {
|
|
25152
25161
|
if (!isNotFoundError(copyError)) {
|
|
25153
|
-
|
|
25162
|
+
logger_default.warn(`Symlink fallback warning: ${copyError.message}`);
|
|
25154
25163
|
}
|
|
25155
25164
|
}
|
|
25156
25165
|
}
|
|
@@ -25188,6 +25197,7 @@ var init_setup = __esm({
|
|
|
25188
25197
|
init_dependency_validator();
|
|
25189
25198
|
init_fs();
|
|
25190
25199
|
init_fs_helpers();
|
|
25200
|
+
init_logger();
|
|
25191
25201
|
init_version();
|
|
25192
25202
|
init_ai_provider();
|
|
25193
25203
|
init_command_installer();
|
|
@@ -28604,7 +28614,7 @@ var require_package = __commonJS({
|
|
|
28604
28614
|
"package.json"(exports, module) {
|
|
28605
28615
|
module.exports = {
|
|
28606
28616
|
name: "prjct-cli",
|
|
28607
|
-
version: "1.6.
|
|
28617
|
+
version: "1.6.3",
|
|
28608
28618
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
28609
28619
|
main: "core/index.ts",
|
|
28610
28620
|
bin: {
|
|
@@ -28812,7 +28822,7 @@ async function main() {
|
|
|
28812
28822
|
// Setup
|
|
28813
28823
|
sync: /* @__PURE__ */ __name(() => commands.sync(process.cwd(), {
|
|
28814
28824
|
aiTools: options.agents ? String(options.agents).split(",") : void 0,
|
|
28815
|
-
preview: options.preview === true,
|
|
28825
|
+
preview: options.preview === true || options["dry-run"] === true,
|
|
28816
28826
|
yes: options.yes === true,
|
|
28817
28827
|
json: options.json === true,
|
|
28818
28828
|
package: options.package ? String(options.package) : void 0
|
|
@@ -29058,7 +29068,7 @@ import chalk19 from "chalk";
|
|
|
29058
29068
|
// core/server/server.ts
|
|
29059
29069
|
import { Hono as Hono3 } from "hono";
|
|
29060
29070
|
import { cors } from "hono/cors";
|
|
29061
|
-
import { logger } from "hono/logger";
|
|
29071
|
+
import { logger as logger2 } from "hono/logger";
|
|
29062
29072
|
|
|
29063
29073
|
// core/utils/runtime.ts
|
|
29064
29074
|
function detectRuntime() {
|
|
@@ -29076,6 +29086,7 @@ __name(isBun, "isBun");
|
|
|
29076
29086
|
// core/server/routes.ts
|
|
29077
29087
|
init_path_manager();
|
|
29078
29088
|
init_fs();
|
|
29089
|
+
init_logger();
|
|
29079
29090
|
import fs7 from "node:fs/promises";
|
|
29080
29091
|
import path7 from "node:path";
|
|
29081
29092
|
import { Hono } from "hono";
|
|
@@ -29095,7 +29106,7 @@ async function readJsonFile(filePath) {
|
|
|
29095
29106
|
return errors.length > 0 ? null : result;
|
|
29096
29107
|
} catch (error) {
|
|
29097
29108
|
if (!isNotFoundError(error) && !(error instanceof SyntaxError)) {
|
|
29098
|
-
|
|
29109
|
+
logger_default.error(`JSON read error: ${error.message}`);
|
|
29099
29110
|
}
|
|
29100
29111
|
return null;
|
|
29101
29112
|
}
|
|
@@ -29108,7 +29119,7 @@ async function writeJsonFile(filePath, data) {
|
|
|
29108
29119
|
`, "utf-8");
|
|
29109
29120
|
return true;
|
|
29110
29121
|
} catch (error) {
|
|
29111
|
-
|
|
29122
|
+
logger_default.error(`JSON write error: ${error.message}`);
|
|
29112
29123
|
return false;
|
|
29113
29124
|
}
|
|
29114
29125
|
}
|
|
@@ -29198,7 +29209,7 @@ function createRoutes(projectId, _projectPath) {
|
|
|
29198
29209
|
return c.text(content, 200, { "Content-Type": "text/markdown" });
|
|
29199
29210
|
} catch (error) {
|
|
29200
29211
|
if (!isNotFoundError(error)) {
|
|
29201
|
-
|
|
29212
|
+
logger_default.error(`Context read error: ${error.message}`);
|
|
29202
29213
|
}
|
|
29203
29214
|
return c.text("", 200, { "Content-Type": "text/markdown" });
|
|
29204
29215
|
}
|
|
@@ -29704,7 +29715,7 @@ function createServer(config) {
|
|
|
29704
29715
|
);
|
|
29705
29716
|
}
|
|
29706
29717
|
if (config.enableLogging !== false) {
|
|
29707
|
-
app.use("*",
|
|
29718
|
+
app.use("*", logger2());
|
|
29708
29719
|
}
|
|
29709
29720
|
app.get("/health", (c) => c.json({ status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
29710
29721
|
app.get(
|
|
@@ -719,6 +719,39 @@ __name(isNotFoundError, "isNotFoundError");
|
|
|
719
719
|
// core/infrastructure/setup.ts
|
|
720
720
|
init_fs_helpers();
|
|
721
721
|
|
|
722
|
+
// core/utils/logger.ts
|
|
723
|
+
var LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
724
|
+
var TRUTHY_VALUES = /* @__PURE__ */ new Set(["1", "true", "*"]);
|
|
725
|
+
function getLogLevel() {
|
|
726
|
+
const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || "";
|
|
727
|
+
if (!debugEnv) return { level: -1, name: "disabled" };
|
|
728
|
+
if (TRUTHY_VALUES.has(debugEnv) || debugEnv.includes("prjct")) {
|
|
729
|
+
return { level: LEVELS.debug, name: "debug" };
|
|
730
|
+
}
|
|
731
|
+
const levelValue = LEVELS[debugEnv] ?? -1;
|
|
732
|
+
const levelName = levelValue >= 0 ? debugEnv : "disabled";
|
|
733
|
+
return { level: levelValue, name: levelName };
|
|
734
|
+
}
|
|
735
|
+
__name(getLogLevel, "getLogLevel");
|
|
736
|
+
var { level: currentLevel, name: currentLevelName } = getLogLevel();
|
|
737
|
+
var noop = /* @__PURE__ */ __name(() => {
|
|
738
|
+
}, "noop");
|
|
739
|
+
function createLogMethod(levelThreshold, prefix, method) {
|
|
740
|
+
return currentLevel >= levelThreshold ? (...args) => console[method](prefix, ...args) : noop;
|
|
741
|
+
}
|
|
742
|
+
__name(createLogMethod, "createLogMethod");
|
|
743
|
+
var logger = {
|
|
744
|
+
error: createLogMethod(LEVELS.error, "[prjct:error]", "error"),
|
|
745
|
+
warn: createLogMethod(LEVELS.warn, "[prjct:warn]", "warn"),
|
|
746
|
+
info: createLogMethod(LEVELS.info, "[prjct:info]", "log"),
|
|
747
|
+
debug: createLogMethod(LEVELS.debug, "[prjct:debug]", "log"),
|
|
748
|
+
// Check if logging is enabled (useful for expensive log prep)
|
|
749
|
+
isEnabled: /* @__PURE__ */ __name(() => currentLevel >= 0, "isEnabled"),
|
|
750
|
+
// Get current level name (pre-computed, no runtime lookup)
|
|
751
|
+
level: /* @__PURE__ */ __name(() => currentLevelName, "level")
|
|
752
|
+
};
|
|
753
|
+
var logger_default = logger;
|
|
754
|
+
|
|
722
755
|
// core/utils/version.ts
|
|
723
756
|
var import_node_fs = __toESM(require("node:fs"));
|
|
724
757
|
var import_node_path = __toESM(require("node:path"));
|
|
@@ -1574,7 +1607,7 @@ async function installGeminiRouter() {
|
|
|
1574
1607
|
}
|
|
1575
1608
|
return false;
|
|
1576
1609
|
} catch (error) {
|
|
1577
|
-
|
|
1610
|
+
logger_default.warn(`Gemini router warning: ${error.message}`);
|
|
1578
1611
|
return false;
|
|
1579
1612
|
}
|
|
1580
1613
|
}
|
|
@@ -1624,7 +1657,7 @@ ${templateContent}`;
|
|
|
1624
1657
|
await import_promises4.default.writeFile(globalConfigPath, updatedContent, "utf-8");
|
|
1625
1658
|
return { success: true, action: "updated" };
|
|
1626
1659
|
} catch (error) {
|
|
1627
|
-
|
|
1660
|
+
logger_default.warn(`Gemini config warning: ${error.message}`);
|
|
1628
1661
|
return { success: false, action: null };
|
|
1629
1662
|
}
|
|
1630
1663
|
}
|
|
@@ -1638,14 +1671,14 @@ async function installAntigravitySkill() {
|
|
|
1638
1671
|
await import_promises4.default.mkdir(prjctSkillDir, { recursive: true });
|
|
1639
1672
|
const skillExists = await fileExists(skillMdPath);
|
|
1640
1673
|
if (!await fileExists(templatePath)) {
|
|
1641
|
-
|
|
1674
|
+
logger_default.warn("Antigravity SKILL.md template not found");
|
|
1642
1675
|
return { success: false, action: null };
|
|
1643
1676
|
}
|
|
1644
1677
|
const templateContent = await import_promises4.default.readFile(templatePath, "utf-8");
|
|
1645
1678
|
await import_promises4.default.writeFile(skillMdPath, templateContent, "utf-8");
|
|
1646
1679
|
return { success: true, action: skillExists ? "updated" : "created" };
|
|
1647
1680
|
} catch (error) {
|
|
1648
|
-
|
|
1681
|
+
logger_default.warn(`Antigravity skill warning: ${error.message}`);
|
|
1649
1682
|
return { success: false, action: null };
|
|
1650
1683
|
}
|
|
1651
1684
|
}
|
|
@@ -1688,7 +1721,7 @@ async function installCursorProject(projectRoot) {
|
|
|
1688
1721
|
result.success = result.rulesCreated || result.commandsCreated;
|
|
1689
1722
|
return result;
|
|
1690
1723
|
} catch (error) {
|
|
1691
|
-
|
|
1724
|
+
logger_default.warn(`Cursor installation warning: ${error.message}`);
|
|
1692
1725
|
return result;
|
|
1693
1726
|
}
|
|
1694
1727
|
}
|
|
@@ -1728,7 +1761,7 @@ ${entriesToAdd.join("\n")}
|
|
|
1728
1761
|
await import_promises4.default.writeFile(gitignorePath, newContent, "utf-8");
|
|
1729
1762
|
return true;
|
|
1730
1763
|
} catch (error) {
|
|
1731
|
-
|
|
1764
|
+
logger_default.warn(`Gitignore update warning: ${error.message}`);
|
|
1732
1765
|
return false;
|
|
1733
1766
|
}
|
|
1734
1767
|
}
|
|
@@ -1783,7 +1816,7 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1783
1816
|
result.success = result.rulesCreated || result.workflowsCreated;
|
|
1784
1817
|
return result;
|
|
1785
1818
|
} catch (error) {
|
|
1786
|
-
|
|
1819
|
+
logger_default.warn(`Windsurf installation warning: ${error.message}`);
|
|
1787
1820
|
return result;
|
|
1788
1821
|
}
|
|
1789
1822
|
}
|
|
@@ -1823,7 +1856,7 @@ ${entriesToAdd.join("\n")}
|
|
|
1823
1856
|
await import_promises4.default.writeFile(gitignorePath, newContent, "utf-8");
|
|
1824
1857
|
return true;
|
|
1825
1858
|
} catch (error) {
|
|
1826
|
-
|
|
1859
|
+
logger_default.warn(`Gitignore update warning: ${error.message}`);
|
|
1827
1860
|
return false;
|
|
1828
1861
|
}
|
|
1829
1862
|
}
|
|
@@ -1870,7 +1903,7 @@ async function migrateProjectsCliVersion() {
|
|
|
1870
1903
|
}
|
|
1871
1904
|
} catch (error) {
|
|
1872
1905
|
if (!isNotFoundError(error)) {
|
|
1873
|
-
|
|
1906
|
+
logger_default.warn(`Migration warning: ${error.message}`);
|
|
1874
1907
|
}
|
|
1875
1908
|
}
|
|
1876
1909
|
}
|
|
@@ -1996,7 +2029,7 @@ echo "prjct"
|
|
|
1996
2029
|
await ensureStatusLineSettings(settingsPath, claudeStatusLinePath);
|
|
1997
2030
|
} catch (error) {
|
|
1998
2031
|
if (!isNotFoundError(error)) {
|
|
1999
|
-
|
|
2032
|
+
logger_default.warn(`Status line warning: ${error.message}`);
|
|
2000
2033
|
}
|
|
2001
2034
|
}
|
|
2002
2035
|
}
|
|
@@ -2029,7 +2062,7 @@ async function installContext7MCP() {
|
|
|
2029
2062
|
await import_promises4.default.writeFile(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
2030
2063
|
}
|
|
2031
2064
|
} catch (error) {
|
|
2032
|
-
|
|
2065
|
+
logger_default.warn(`Context7 MCP setup warning: ${error.message}`);
|
|
2033
2066
|
}
|
|
2034
2067
|
}
|
|
2035
2068
|
__name(installContext7MCP, "installContext7MCP");
|
|
@@ -2069,7 +2102,7 @@ async function ensureStatusLineSymlink(linkPath, targetPath) {
|
|
|
2069
2102
|
}
|
|
2070
2103
|
} catch (copyError) {
|
|
2071
2104
|
if (!isNotFoundError(copyError)) {
|
|
2072
|
-
|
|
2105
|
+
logger_default.warn(`Symlink fallback warning: ${copyError.message}`);
|
|
2073
2106
|
}
|
|
2074
2107
|
}
|
|
2075
2108
|
}
|