@phren/cli 0.0.28 → 0.0.32
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/mcp/dist/capabilities/cli.js +2 -5
- package/mcp/dist/capabilities/mcp.js +5 -8
- package/mcp/dist/capabilities/types.js +2 -5
- package/mcp/dist/capabilities/vscode.js +2 -5
- package/mcp/dist/capabilities/web-ui.js +2 -5
- package/mcp/dist/{cli-actions.js → cli/actions.js} +22 -21
- package/mcp/dist/{cli.js → cli/cli.js} +13 -13
- package/mcp/dist/{cli-config.js → cli/config.js} +9 -9
- package/mcp/dist/{cli-extract.js → cli/extract.js} +8 -8
- package/mcp/dist/{cli-govern.js → cli/govern.js} +10 -9
- package/mcp/dist/{cli-graph.js → cli/graph.js} +10 -9
- package/mcp/dist/{cli-hooks-citations.js → cli/hooks-citations.js} +2 -2
- package/mcp/dist/{cli-hooks-context.js → cli/hooks-context.js} +23 -23
- package/mcp/dist/{cli-hooks-globs.js → cli/hooks-globs.js} +4 -4
- package/mcp/dist/{cli-hooks-output.js → cli/hooks-output.js} +9 -10
- package/mcp/dist/{cli-hooks-session.js → cli/hooks-session.js} +42 -57
- package/mcp/dist/{cli-hooks.js → cli/hooks.js} +27 -26
- package/mcp/dist/{cli-namespaces.js → cli/namespaces.js} +25 -24
- package/mcp/dist/{cli-ops.js → cli/ops.js} +9 -9
- package/mcp/dist/{cli-search.js → cli/search.js} +8 -7
- package/mcp/dist/cli-hooks-git.js +243 -0
- package/mcp/dist/cli-hooks-prompt.js +319 -0
- package/mcp/dist/cli-hooks-session-handlers.js +349 -0
- package/mcp/dist/cli-hooks-stop.js +557 -0
- package/mcp/dist/{content-archive.js → content/archive.js} +8 -9
- package/mcp/dist/{content-citation.js → content/citation.js} +5 -5
- package/mcp/dist/{content-dedup.js → content/dedup.js} +9 -12
- package/mcp/dist/{content-learning.js → content/learning.js} +12 -12
- package/mcp/dist/{content-validate.js → content/validate.js} +5 -5
- package/mcp/dist/{core-finding.js → core/finding.js} +4 -4
- package/mcp/dist/{core-project.js → core/project.js} +4 -4
- package/mcp/dist/{core-search.js → core/search.js} +2 -2
- package/mcp/dist/{data-access.js → data/access.js} +131 -13
- package/mcp/dist/{data-tasks.js → data/tasks.js} +7 -5
- package/mcp/dist/embedding.js +9 -14
- package/mcp/dist/entrypoint.js +11 -11
- package/mcp/dist/{finding-context.js → finding/context.js} +2 -2
- package/mcp/dist/{finding-impact.js → finding/impact.js} +3 -3
- package/mcp/dist/{finding-journal.js → finding/journal.js} +4 -4
- package/mcp/dist/{finding-lifecycle.js → finding/lifecycle.js} +4 -4
- package/mcp/dist/{governance-audit.js → governance/audit.js} +2 -2
- package/mcp/dist/{governance-locks.js → governance/locks.js} +14 -9
- package/mcp/dist/{governance-policy.js → governance/policy.js} +10 -12
- package/mcp/dist/{governance-rbac.js → governance/rbac.js} +3 -3
- package/mcp/dist/{governance-scores.js → governance/scores.js} +8 -10
- package/mcp/dist/hooks.js +39 -31
- package/mcp/dist/index-query.js +4 -1
- package/mcp/dist/index.js +53 -29
- package/mcp/dist/{init-config.js → init/config.js} +6 -6
- package/mcp/dist/{init.js → init/init.js} +28 -29
- package/mcp/dist/{init-preferences.js → init/preferences.js} +3 -3
- package/mcp/dist/{init-setup.js → init/setup.js} +17 -19
- package/mcp/dist/{init-shared.js → init/shared.js} +3 -3
- package/mcp/dist/init-bootstrap.js +68 -0
- package/mcp/dist/init-detect.js +38 -0
- package/mcp/dist/init-dryrun.js +55 -0
- package/mcp/dist/init-env.js +114 -0
- package/mcp/dist/init-fresh.js +239 -0
- package/mcp/dist/init-hooks.js +26 -0
- package/mcp/dist/init-mcp.js +65 -0
- package/mcp/dist/init-migrate.js +51 -0
- package/mcp/dist/init-modes.js +135 -0
- package/mcp/dist/init-npm.js +37 -0
- package/mcp/dist/init-project-local.js +99 -0
- package/mcp/dist/init-semantic.js +48 -0
- package/mcp/dist/init-types.js +1 -0
- package/mcp/dist/init-uninstall.js +482 -0
- package/mcp/dist/init-update.js +96 -0
- package/mcp/dist/init-walkthrough-merge.js +90 -0
- package/mcp/dist/init-walkthrough.js +529 -0
- package/mcp/dist/{link-checksums.js → link/checksums.js} +5 -5
- package/mcp/dist/{link-context.js → link/context.js} +4 -4
- package/mcp/dist/{link-doctor.js → link/doctor.js} +20 -22
- package/mcp/dist/{link.js → link/link.js} +26 -31
- package/mcp/dist/{link-skills.js → link/skills.js} +10 -10
- package/mcp/dist/logger.js +11 -3
- package/mcp/dist/phren-art.js +0 -6
- package/mcp/dist/phren-paths.js +30 -12
- package/mcp/dist/proactivity.js +2 -2
- package/mcp/dist/profile-store.js +5 -6
- package/mcp/dist/project-config.js +2 -2
- package/mcp/dist/project-topics.js +1 -1
- package/mcp/dist/query-correlation.js +1 -1
- package/mcp/dist/{session-checkpoints.js → session/checkpoints.js} +3 -3
- package/mcp/dist/{session-utils.js → session/utils.js} +1 -1
- package/mcp/dist/{shared-content.js → shared/content.js} +7 -7
- package/mcp/dist/{shared-data-utils.js → shared/data-utils.js} +3 -3
- package/mcp/dist/{shared-embedding-cache.js → shared/embedding-cache.js} +3 -3
- package/mcp/dist/{shared-fragment-graph.js → shared/fragment-graph.js} +15 -24
- package/mcp/dist/shared/governance.js +4 -0
- package/mcp/dist/{shared-index.js → shared/index.js} +92 -123
- package/mcp/dist/{shared-ollama.js → shared/ollama.js} +2 -2
- package/mcp/dist/{shared-retrieval.js → shared/retrieval.js} +16 -21
- package/mcp/dist/{shared-search-fallback.js → shared/search-fallback.js} +17 -20
- package/mcp/dist/{shared-sqljs.js → shared/sqljs.js} +3 -3
- package/mcp/dist/{shared-vector-index.js → shared/vector-index.js} +3 -3
- package/mcp/dist/shared.js +4 -59
- package/mcp/dist/{shell-entry.js → shell/entry.js} +6 -6
- package/mcp/dist/{shell-input.js → shell/input.js} +13 -13
- package/mcp/dist/{shell-palette.js → shell/palette.js} +3 -3
- package/mcp/dist/{shell-render.js → shell/render.js} +1 -1
- package/mcp/dist/{shell.js → shell/shell.js} +11 -11
- package/mcp/dist/{shell-state-store.js → shell/state-store.js} +5 -5
- package/mcp/dist/{shell-view-list.js → shell/view-list.js} +1 -1
- package/mcp/dist/{shell-view.js → shell/view.js} +13 -13
- package/mcp/dist/{skill-files.js → skill/files.js} +9 -9
- package/mcp/dist/{skill-registry.js → skill/registry.js} +4 -4
- package/mcp/dist/{skill-state.js → skill/state.js} +1 -1
- package/mcp/dist/startup-embedding.js +2 -2
- package/mcp/dist/status.js +15 -14
- package/mcp/dist/{tasks-github.js → task/github.js} +2 -2
- package/mcp/dist/{task-hygiene.js → task/hygiene.js} +4 -4
- package/mcp/dist/{task-lifecycle.js → task/lifecycle.js} +7 -7
- package/mcp/dist/telemetry.js +3 -4
- package/mcp/dist/tool-registry.js +29 -17
- package/mcp/dist/tools/config.js +515 -0
- package/mcp/dist/{mcp-data.js → tools/data.js} +8 -10
- package/mcp/dist/{mcp-extract-facts.js → tools/extract-facts.js} +6 -6
- package/mcp/dist/{mcp-extract.js → tools/extract.js} +6 -6
- package/mcp/dist/{mcp-finding.js → tools/finding.js} +97 -124
- package/mcp/dist/{mcp-graph.js → tools/graph.js} +11 -14
- package/mcp/dist/{mcp-hooks.js → tools/hooks.js} +6 -6
- package/mcp/dist/{mcp-memory.js → tools/memory.js} +5 -5
- package/mcp/dist/{mcp-ops.js → tools/ops.js} +169 -71
- package/mcp/dist/{mcp-search.js → tools/search.js} +19 -23
- package/mcp/dist/{mcp-session.js → tools/session.js} +48 -23
- package/mcp/dist/{mcp-skills.js → tools/skills.js} +33 -35
- package/mcp/dist/{mcp-tasks.js → tools/tasks.js} +155 -282
- package/mcp/dist/{memory-ui-data.js → ui/data.js} +31 -17
- package/mcp/dist/{memory-ui.js → ui/memory-ui.js} +3 -3
- package/mcp/dist/{memory-ui-page.js → ui/page.js} +4 -6
- package/mcp/dist/{memory-ui-server.js → ui/server.js} +30 -22
- package/mcp/dist/update.js +2 -2
- package/mcp/dist/utils.js +51 -11
- package/package.json +2 -2
- package/scripts/preuninstall.mjs +31 -0
- package/starter/global/CLAUDE.md +3 -2
- package/mcp/dist/mcp-config.js +0 -551
- package/mcp/dist/shared-governance.js +0 -4
- /package/mcp/dist/{content-metadata.js → content/metadata.js} +0 -0
- /package/mcp/dist/{shared-stemmer.js → shared/stemmer.js} +0 -0
- /package/mcp/dist/{shell-types.js → shell/types.js} +0 -0
- /package/mcp/dist/{mcp-types.js → tools/types.js} +0 -0
- /package/mcp/dist/{memory-ui-assets.js → ui/assets.js} +0 -0
- /package/mcp/dist/{memory-ui-graph.js → ui/graph.js} +0 -0
- /package/mcp/dist/{memory-ui-scripts.js → ui/scripts.js} +0 -0
- /package/mcp/dist/{memory-ui-styles.js → ui/styles.js} +0 -0
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { buildHookContext, handleGuardSkip, debugLog, appendAuditLog, runtimeFile, sessionMarker, EXEC_TIMEOUT_MS, getPhrenPath, getProjectDirs, findProjectNameCaseInsensitive, homePath, updateRuntimeHealth, withFileLock, getWorkflowPolicy, appendReviewQueue, recordFeedback, getQualityMultiplier, detectProject, isProjectHookEnabled, readProjectConfig, getProjectSourcePath, detectProjectDir, ensureLocalGitRepo, isProjectTracked, repairPreexistingInstall, getProactivityLevelForTask, getProactivityLevelForFindings, hasExplicitFindingSignal, shouldAutoCaptureFindingsForLevel, FINDING_SENSITIVITY_CONFIG, isFeatureEnabled, errorMessage, bootstrapPhrenDotEnv, finalizeTaskSession, appendFindingJournal, runDoctor, resolveRuntimeProfile, } from "./
|
|
2
|
-
import { sessionMetricsFile, qualityMarkers, } from "
|
|
3
|
-
import { autoMergeConflicts, mergeTask, mergeFindings, } from "
|
|
4
|
-
import { runGit } from "
|
|
5
|
-
import { readInstallPreferences } from "
|
|
1
|
+
import { buildHookContext, handleGuardSkip, debugLog, appendAuditLog, runtimeFile, sessionMarker, EXEC_TIMEOUT_MS, getPhrenPath, getProjectDirs, findProjectNameCaseInsensitive, homePath, updateRuntimeHealth, withFileLock, getWorkflowPolicy, appendReviewQueue, recordFeedback, getQualityMultiplier, detectProject, isProjectHookEnabled, readProjectConfig, getProjectSourcePath, detectProjectDir, ensureLocalGitRepo, isProjectTracked, repairPreexistingInstall, getProactivityLevelForTask, getProactivityLevelForFindings, hasExplicitFindingSignal, shouldAutoCaptureFindingsForLevel, FINDING_SENSITIVITY_CONFIG, isFeatureEnabled, errorMessage, bootstrapPhrenDotEnv, finalizeTaskSession, appendFindingJournal, runDoctor, resolveRuntimeProfile, } from "./hooks-context.js";
|
|
2
|
+
import { sessionMetricsFile, qualityMarkers, } from "../shared.js";
|
|
3
|
+
import { autoMergeConflicts, mergeTask, mergeFindings, } from "../shared/content.js";
|
|
4
|
+
import { runGit } from "../utils.js";
|
|
5
|
+
import { readInstallPreferences } from "../init/preferences.js";
|
|
6
6
|
import * as fs from "fs";
|
|
7
7
|
import * as path from "path";
|
|
8
8
|
import * as os from "os";
|
|
9
9
|
import { execFileSync, spawn } from "child_process";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
|
-
import { isTaskFileName, TASKS_FILENAME } from "
|
|
12
|
-
import { buildIndex, queryRows, } from "
|
|
13
|
-
import { filterTaskByPriority } from "
|
|
11
|
+
import { isTaskFileName, TASKS_FILENAME } from "../data/tasks.js";
|
|
12
|
+
import { buildIndex, queryRows, } from "../shared/index.js";
|
|
13
|
+
import { filterTaskByPriority } from "../shared/retrieval.js";
|
|
14
|
+
import { logger } from "../logger.js";
|
|
14
15
|
function getRuntimeProfile() {
|
|
15
16
|
return resolveRuntimeProfile(getPhrenPath());
|
|
16
17
|
}
|
|
17
|
-
export { buildHookContext, checkHookGuard, handleGuardSkip } from "./
|
|
18
|
+
export { buildHookContext, checkHookGuard, handleGuardSkip } from "./hooks-context.js";
|
|
18
19
|
/** Read JSON from stdin if it's not a TTY. Returns null if stdin is a TTY or parsing fails. */
|
|
19
20
|
function readStdinJson() {
|
|
20
21
|
if (process.stdin.isTTY)
|
|
@@ -23,8 +24,7 @@ function readStdinJson() {
|
|
|
23
24
|
return JSON.parse(fs.readFileSync(0, "utf-8"));
|
|
24
25
|
}
|
|
25
26
|
catch (err) {
|
|
26
|
-
|
|
27
|
-
process.stderr.write(`[phren] readStdinJson: ${errorMessage(err)}\n`);
|
|
27
|
+
logger.debug("hooks-session", `readStdinJson: ${errorMessage(err)}`);
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -230,13 +230,17 @@ export function trackSessionMetrics(phrenPathLocal, sessionId, selected) {
|
|
|
230
230
|
}
|
|
231
231
|
// ── Background maintenance ───────────────────────────────────────────────────
|
|
232
232
|
export function resolveSubprocessArgs(command) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
233
|
+
// Prefer the entry script that started this process
|
|
234
|
+
const entry = process.argv[1];
|
|
235
|
+
if (entry && fs.existsSync(entry) && /index\.(ts|js)$/.test(entry))
|
|
236
|
+
return [entry, command];
|
|
237
|
+
// Fallback: look for index.js next to this file or one level up (for subdirectory builds)
|
|
238
|
+
const thisDir = path.dirname(fileURLToPath(import.meta.url));
|
|
239
|
+
for (const dir of [thisDir, path.dirname(thisDir)]) {
|
|
240
|
+
const candidate = path.join(dir, "index.js");
|
|
241
|
+
if (fs.existsSync(candidate))
|
|
242
|
+
return [candidate, command];
|
|
243
|
+
}
|
|
240
244
|
return null;
|
|
241
245
|
}
|
|
242
246
|
function scheduleBackgroundSync(phrenPathLocal) {
|
|
@@ -319,8 +323,7 @@ function scheduleBackgroundMaintenance(phrenPathLocal, project) {
|
|
|
319
323
|
}
|
|
320
324
|
catch (err) {
|
|
321
325
|
// Another process already claimed the lock
|
|
322
|
-
|
|
323
|
-
process.stderr.write(`[phren] backgroundMaintenance lockClaim: ${errorMessage(err)}\n`);
|
|
326
|
+
logger.debug("hooks-session", `backgroundMaintenance lockClaim: ${errorMessage(err)}`);
|
|
324
327
|
return false;
|
|
325
328
|
}
|
|
326
329
|
try {
|
|
@@ -352,24 +355,21 @@ function scheduleBackgroundMaintenance(phrenPathLocal, project) {
|
|
|
352
355
|
fs.appendFileSync(logPath, msg);
|
|
353
356
|
}
|
|
354
357
|
catch (err) {
|
|
355
|
-
|
|
356
|
-
process.stderr.write(`[phren] backgroundMaintenance exitLog: ${errorMessage(err)}\n`);
|
|
358
|
+
logger.debug("hooks-session", `backgroundMaintenance exitLog: ${errorMessage(err)}`);
|
|
357
359
|
}
|
|
358
360
|
if (code === 0) {
|
|
359
361
|
try {
|
|
360
362
|
fs.writeFileSync(markers.done, new Date().toISOString() + "\n");
|
|
361
363
|
}
|
|
362
364
|
catch (err) {
|
|
363
|
-
|
|
364
|
-
process.stderr.write(`[phren] backgroundMaintenance doneMarker: ${errorMessage(err)}\n`);
|
|
365
|
+
logger.debug("hooks-session", `backgroundMaintenance doneMarker: ${errorMessage(err)}`);
|
|
365
366
|
}
|
|
366
367
|
}
|
|
367
368
|
try {
|
|
368
369
|
fs.unlinkSync(markers.lock);
|
|
369
370
|
}
|
|
370
371
|
catch (err) {
|
|
371
|
-
|
|
372
|
-
process.stderr.write(`[phren] backgroundMaintenance unlockOnExit: ${errorMessage(err)}\n`);
|
|
372
|
+
logger.debug("hooks-session", `backgroundMaintenance unlockOnExit: ${errorMessage(err)}`);
|
|
373
373
|
}
|
|
374
374
|
});
|
|
375
375
|
child.on("error", (spawnErr) => {
|
|
@@ -378,15 +378,13 @@ function scheduleBackgroundMaintenance(phrenPathLocal, project) {
|
|
|
378
378
|
fs.appendFileSync(logPath, msg);
|
|
379
379
|
}
|
|
380
380
|
catch (err) {
|
|
381
|
-
|
|
382
|
-
process.stderr.write(`[phren] backgroundMaintenance errorLog: ${errorMessage(err)}\n`);
|
|
381
|
+
logger.debug("hooks-session", `backgroundMaintenance errorLog: ${errorMessage(err)}`);
|
|
383
382
|
}
|
|
384
383
|
try {
|
|
385
384
|
fs.unlinkSync(markers.lock);
|
|
386
385
|
}
|
|
387
386
|
catch (err) {
|
|
388
|
-
|
|
389
|
-
process.stderr.write(`[phren] backgroundMaintenance unlockOnError: ${errorMessage(err)}\n`);
|
|
387
|
+
logger.debug("hooks-session", `backgroundMaintenance unlockOnError: ${errorMessage(err)}`);
|
|
390
388
|
}
|
|
391
389
|
});
|
|
392
390
|
fs.closeSync(logFd);
|
|
@@ -401,15 +399,13 @@ function scheduleBackgroundMaintenance(phrenPathLocal, project) {
|
|
|
401
399
|
fs.appendFileSync(path.join(logDir, "background-maintenance.log"), `[${new Date().toISOString()}] spawn failed: ${errMsg}\n`);
|
|
402
400
|
}
|
|
403
401
|
catch (err) {
|
|
404
|
-
|
|
405
|
-
process.stderr.write(`[phren] backgroundMaintenance logSpawnFailure: ${errorMessage(err)}\n`);
|
|
402
|
+
logger.debug("hooks-session", `backgroundMaintenance logSpawnFailure: ${errorMessage(err)}`);
|
|
406
403
|
}
|
|
407
404
|
try {
|
|
408
405
|
fs.unlinkSync(markers.lock);
|
|
409
406
|
}
|
|
410
407
|
catch (err) {
|
|
411
|
-
|
|
412
|
-
process.stderr.write(`[phren] backgroundMaintenance unlockOnFailure: ${errorMessage(err)}\n`);
|
|
408
|
+
logger.debug("hooks-session", `backgroundMaintenance unlockOnFailure: ${errorMessage(err)}`);
|
|
413
409
|
}
|
|
414
410
|
return false;
|
|
415
411
|
}
|
|
@@ -608,12 +604,11 @@ export async function handleHookSessionStart() {
|
|
|
608
604
|
const maintenanceScheduled = scheduleBackgroundMaintenance(phrenPath);
|
|
609
605
|
const unsyncedCommits = hasRemote ? await countUnsyncedCommits(phrenPath) : 0;
|
|
610
606
|
try {
|
|
611
|
-
const { trackSession } = await import("
|
|
607
|
+
const { trackSession } = await import("../telemetry.js");
|
|
612
608
|
trackSession(phrenPath);
|
|
613
609
|
}
|
|
614
610
|
catch (err) {
|
|
615
|
-
|
|
616
|
-
process.stderr.write(`[phren] hookSessionStart trackSession: ${errorMessage(err)}\n`);
|
|
611
|
+
logger.debug("hooks-session", `hookSessionStart trackSession: ${errorMessage(err)}`);
|
|
617
612
|
}
|
|
618
613
|
updateRuntimeHealth(phrenPath, {
|
|
619
614
|
lastSessionStartAt: startedAt,
|
|
@@ -779,8 +774,7 @@ export async function handleHookStop() {
|
|
|
779
774
|
}
|
|
780
775
|
}
|
|
781
776
|
catch (err) {
|
|
782
|
-
|
|
783
|
-
process.stderr.write(`[phren] hookStop transcriptParse: ${errorMessage(err)}\n`);
|
|
777
|
+
logger.debug("hooks-session", `hookStop transcriptParse: ${errorMessage(err)}`);
|
|
784
778
|
}
|
|
785
779
|
}
|
|
786
780
|
captureInput = assistantTexts.join("\n");
|
|
@@ -804,8 +798,7 @@ export async function handleHookStop() {
|
|
|
804
798
|
}
|
|
805
799
|
}
|
|
806
800
|
catch (err) {
|
|
807
|
-
|
|
808
|
-
process.stderr.write(`[phren] hookStop sessionCapCheck: ${errorMessage(err)}\n`);
|
|
801
|
+
logger.debug("hooks-session", `hookStop sessionCapCheck: ${errorMessage(err)}`);
|
|
809
802
|
}
|
|
810
803
|
}
|
|
811
804
|
if (!capReached) {
|
|
@@ -1225,8 +1218,7 @@ export async function handleHookTool() {
|
|
|
1225
1218
|
raw = fs.readFileSync(0, "utf-8");
|
|
1226
1219
|
}
|
|
1227
1220
|
catch (err) {
|
|
1228
|
-
|
|
1229
|
-
process.stderr.write(`[phren] hookTool stdinRead: ${errorMessage(err)}\n`);
|
|
1221
|
+
logger.debug("hooks-session", `hookTool stdinRead: ${errorMessage(err)}`);
|
|
1230
1222
|
process.exit(0);
|
|
1231
1223
|
}
|
|
1232
1224
|
}
|
|
@@ -1235,8 +1227,7 @@ export async function handleHookTool() {
|
|
|
1235
1227
|
data = JSON.parse(raw);
|
|
1236
1228
|
}
|
|
1237
1229
|
catch (err) {
|
|
1238
|
-
|
|
1239
|
-
process.stderr.write(`[phren] hookTool stdinParse: ${errorMessage(err)}\n`);
|
|
1230
|
+
logger.debug("hooks-session", `hookTool stdinParse: ${errorMessage(err)}`);
|
|
1240
1231
|
process.exit(0);
|
|
1241
1232
|
}
|
|
1242
1233
|
const toolName = String(data.tool_name ?? data.tool ?? "");
|
|
@@ -1287,8 +1278,7 @@ export async function handleHookTool() {
|
|
|
1287
1278
|
fs.appendFileSync(logFile, JSON.stringify(entry) + "\n");
|
|
1288
1279
|
}
|
|
1289
1280
|
catch (err) {
|
|
1290
|
-
|
|
1291
|
-
process.stderr.write(`[phren] hookTool toolLog: ${errorMessage(err)}\n`);
|
|
1281
|
+
logger.debug("hooks-session", `hookTool toolLog: ${errorMessage(err)}`);
|
|
1292
1282
|
}
|
|
1293
1283
|
const cooldownFile = runtimeFile(ctx.phrenPath, "hook-tool-cooldown");
|
|
1294
1284
|
try {
|
|
@@ -1301,8 +1291,7 @@ export async function handleHookTool() {
|
|
|
1301
1291
|
}
|
|
1302
1292
|
}
|
|
1303
1293
|
catch (err) {
|
|
1304
|
-
|
|
1305
|
-
process.stderr.write(`[phren] hookTool cooldownStat: ${errorMessage(err)}\n`);
|
|
1294
|
+
logger.debug("hooks-session", `hookTool cooldownStat: ${errorMessage(err)}`);
|
|
1306
1295
|
}
|
|
1307
1296
|
if (activeProject && sessionId) {
|
|
1308
1297
|
try {
|
|
@@ -1318,8 +1307,7 @@ export async function handleHookTool() {
|
|
|
1318
1307
|
}
|
|
1319
1308
|
}
|
|
1320
1309
|
catch (err) {
|
|
1321
|
-
|
|
1322
|
-
process.stderr.write(`[phren] hookTool sessionCapCheck: ${errorMessage(err)}\n`);
|
|
1310
|
+
logger.debug("hooks-session", `hookTool sessionCapCheck: ${errorMessage(err)}`);
|
|
1323
1311
|
}
|
|
1324
1312
|
}
|
|
1325
1313
|
const findingsLevelForTool = getProactivityLevelForFindings(ctx.phrenPath);
|
|
@@ -1335,8 +1323,7 @@ export async function handleHookTool() {
|
|
|
1335
1323
|
fs.writeFileSync(cooldownFile, Date.now().toString());
|
|
1336
1324
|
}
|
|
1337
1325
|
catch (err) {
|
|
1338
|
-
|
|
1339
|
-
process.stderr.write(`[phren] hookTool cooldownWrite: ${errorMessage(err)}\n`);
|
|
1326
|
+
logger.debug("hooks-session", `hookTool cooldownWrite: ${errorMessage(err)}`);
|
|
1340
1327
|
}
|
|
1341
1328
|
if (sessionId) {
|
|
1342
1329
|
try {
|
|
@@ -1346,15 +1333,13 @@ export async function handleHookTool() {
|
|
|
1346
1333
|
count = Number.parseInt(fs.readFileSync(capFile, "utf8").trim(), 10) || 0;
|
|
1347
1334
|
}
|
|
1348
1335
|
catch (err) {
|
|
1349
|
-
|
|
1350
|
-
process.stderr.write(`[phren] hookTool capFileRead: ${errorMessage(err)}\n`);
|
|
1336
|
+
logger.debug("hooks-session", `hookTool capFileRead: ${errorMessage(err)}`);
|
|
1351
1337
|
}
|
|
1352
1338
|
count += candidates.length;
|
|
1353
1339
|
fs.writeFileSync(capFile, count.toString());
|
|
1354
1340
|
}
|
|
1355
1341
|
catch (err) {
|
|
1356
|
-
|
|
1357
|
-
process.stderr.write(`[phren] hookTool capFileWrite: ${errorMessage(err)}\n`);
|
|
1342
|
+
logger.debug("hooks-session", `hookTool capFileWrite: ${errorMessage(err)}`);
|
|
1358
1343
|
}
|
|
1359
1344
|
}
|
|
1360
1345
|
}
|
|
@@ -4,38 +4,39 @@
|
|
|
4
4
|
// cli-hooks-session.ts — session lifecycle hooks, metrics, background maintenance
|
|
5
5
|
// cli-hooks-output.ts — hook output formatting
|
|
6
6
|
// cli-hooks-globs.ts — project glob matching
|
|
7
|
-
import { debugLog, sessionMarker, sessionsDir, getPhrenPath, } from "
|
|
8
|
-
import { mergeConfig, } from "
|
|
9
|
-
import { buildIndex, detectProject, } from "
|
|
10
|
-
import { isProjectHookEnabled } from "
|
|
11
|
-
import { checkConsolidationNeeded, } from "
|
|
12
|
-
import { buildRobustFtsQuery, extractKeywordEntries, isFeatureEnabled, clampInt, errorMessage, loadSynonymMap, learnSynonym, STOP_WORDS, } from "
|
|
13
|
-
import { getHooksEnabledPreference } from "
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
7
|
+
import { debugLog, sessionMarker, sessionsDir, getPhrenPath, } from "../shared.js";
|
|
8
|
+
import { mergeConfig, } from "../shared/governance.js";
|
|
9
|
+
import { buildIndex, detectProject, } from "../shared/index.js";
|
|
10
|
+
import { isProjectHookEnabled } from "../project-config.js";
|
|
11
|
+
import { checkConsolidationNeeded, } from "../shared/content.js";
|
|
12
|
+
import { buildRobustFtsQuery, extractKeywordEntries, isFeatureEnabled, clampInt, errorMessage, loadSynonymMap, learnSynonym, STOP_WORDS, } from "../utils.js";
|
|
13
|
+
import { getHooksEnabledPreference } from "../init/init.js";
|
|
14
|
+
import { logger } from "../logger.js";
|
|
15
|
+
import { isToolHookEnabled } from "../hooks.js";
|
|
16
|
+
import { handleExtractMemories } from "./extract.js";
|
|
17
|
+
import { appendAuditLog } from "../shared.js";
|
|
18
|
+
import { updateRuntimeHealth } from "../shared/governance.js";
|
|
19
|
+
import { getProactivityLevelForTask, getProactivityLevelForFindings } from "../proactivity.js";
|
|
20
|
+
import { FINDING_SENSITIVITY_CONFIG } from "./config.js";
|
|
20
21
|
import * as fs from "fs";
|
|
21
22
|
// ── Re-exports from focused modules ─────────────────────────────────────────
|
|
22
23
|
// Citations
|
|
23
|
-
export { parseCitations, validateCitation, annotateStale, clearCitationValidCache, } from "./
|
|
24
|
+
export { parseCitations, validateCitation, annotateStale, clearCitationValidCache, } from "./hooks-citations.js";
|
|
24
25
|
// Globs
|
|
25
|
-
export { getProjectGlobBoost, clearProjectGlobCache, } from "./
|
|
26
|
+
export { getProjectGlobBoost, clearProjectGlobCache, } from "./hooks-globs.js";
|
|
26
27
|
// Retrieval
|
|
27
|
-
export { detectTaskIntent, filterTaskByPriority, searchDocuments, applyTrustFilter, rankResults, selectSnippets, } from "
|
|
28
|
+
export { detectTaskIntent, filterTaskByPriority, searchDocuments, applyTrustFilter, rankResults, selectSnippets, } from "../shared/retrieval.js";
|
|
28
29
|
// Output
|
|
29
|
-
export { buildHookOutput, } from "./
|
|
30
|
+
export { buildHookOutput, } from "./hooks-output.js";
|
|
30
31
|
// Session
|
|
31
|
-
export { handleHookSessionStart, handleHookStop, handleBackgroundSync, handleHookContext, handleHookTool, trackSessionMetrics, filterConversationInsightsForProactivity, extractToolFindings, filterToolFindingsForProactivity, resolveSubprocessArgs, } from "./
|
|
32
|
+
export { handleHookSessionStart, handleHookStop, handleBackgroundSync, handleHookContext, handleHookTool, trackSessionMetrics, filterConversationInsightsForProactivity, extractToolFindings, filterToolFindingsForProactivity, resolveSubprocessArgs, } from "./hooks-session.js";
|
|
32
33
|
// ── Imports for the orchestrator ─────────────────────────────────────────────
|
|
33
|
-
import { searchDocumentsAsync, applyTrustFilter, rankResults, selectSnippets, detectTaskIntent, } from "
|
|
34
|
-
import { buildHookOutput } from "./
|
|
35
|
-
import { getGitContext, trackSessionMetrics, } from "./
|
|
36
|
-
import { approximateTokens } from "
|
|
37
|
-
import { resolveRuntimeProfile } from "
|
|
38
|
-
import { handleTaskPromptLifecycle } from "
|
|
34
|
+
import { searchDocumentsAsync, applyTrustFilter, rankResults, selectSnippets, detectTaskIntent, } from "../shared/retrieval.js";
|
|
35
|
+
import { buildHookOutput } from "./hooks-output.js";
|
|
36
|
+
import { getGitContext, trackSessionMetrics, } from "./hooks-session.js";
|
|
37
|
+
import { approximateTokens } from "../shared/retrieval.js";
|
|
38
|
+
import { resolveRuntimeProfile } from "../runtime-profile.js";
|
|
39
|
+
import { handleTaskPromptLifecycle } from "../task/lifecycle.js";
|
|
39
40
|
function synonymTermKnown(term, map) {
|
|
40
41
|
if (Object.prototype.hasOwnProperty.call(map, term))
|
|
41
42
|
return true;
|
|
@@ -126,7 +127,7 @@ export async function handleHookPrompt() {
|
|
|
126
127
|
}
|
|
127
128
|
catch (err) {
|
|
128
129
|
if (process.env.PHREN_DEBUG)
|
|
129
|
-
|
|
130
|
+
logger.debug("cli-hooks", `hookPrompt stdinRead: ${errorMessage(err)}`);
|
|
130
131
|
process.exit(0);
|
|
131
132
|
}
|
|
132
133
|
const input = parseHookInput(raw);
|
|
@@ -362,7 +363,7 @@ export async function handleHookPrompt() {
|
|
|
362
363
|
}
|
|
363
364
|
catch (err) {
|
|
364
365
|
if (process.env.PHREN_DEBUG)
|
|
365
|
-
|
|
366
|
+
logger.debug("cli-hooks", `hookPrompt noticeFileWrite: ${errorMessage(err)}`);
|
|
366
367
|
}
|
|
367
368
|
}
|
|
368
369
|
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { execFileSync } from "child_process";
|
|
4
|
-
import { expandHomePath, findArchivedProjectNameCaseInsensitive, findProjectNameCaseInsensitive, getPhrenPath, getProjectDirs, homePath, hookConfigPath, normalizeProjectNameForCreate, readRootManifest, } from "
|
|
5
|
-
import { isValidProjectName, errorMessage } from "
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
4
|
+
import { expandHomePath, findArchivedProjectNameCaseInsensitive, findProjectNameCaseInsensitive, getPhrenPath, getProjectDirs, homePath, hookConfigPath, normalizeProjectNameForCreate, readRootManifest, } from "../shared.js";
|
|
5
|
+
import { isValidProjectName, errorMessage } from "../utils.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
7
|
+
import { readInstallPreferences, writeInstallPreferences } from "../init/preferences.js";
|
|
8
|
+
import { buildSkillManifest, findLocalSkill, findSkill, getAllSkills } from "../skill/registry.js";
|
|
9
|
+
import { detectSkillCollisions } from "../link/skills.js";
|
|
10
|
+
import { setSkillEnabledAndSync, syncSkillLinksForScope } from "../skill/files.js";
|
|
11
|
+
import { findProjectDir } from "../project-locator.js";
|
|
12
|
+
import { TASK_FILE_ALIASES, addTask, completeTask, updateTask, reorderTask, pinTask, removeTask, workNextTask, tidyDoneTasks, linkTaskIssue, promoteTask, resolveTaskItem } from "../data/tasks.js";
|
|
13
|
+
import { buildTaskIssueBody, createGithubIssueForTask, parseGithubIssueUrl, resolveProjectGithubRepo } from "../task/github.js";
|
|
14
|
+
import { PROJECT_HOOK_EVENTS, PROJECT_OWNERSHIP_MODES, isProjectHookEnabled, parseProjectOwnershipMode, readProjectConfig, writeProjectConfig, writeProjectHookConfig, } from "../project-config.js";
|
|
15
|
+
import { addFinding, removeFinding } from "../core/finding.js";
|
|
16
|
+
import { supersedeFinding, retractFinding, resolveFindingContradiction } from "../finding/lifecycle.js";
|
|
17
|
+
import { readCustomHooks, getHookTarget, HOOK_EVENT_VALUES, validateCustomHookCommand } from "../hooks.js";
|
|
18
|
+
import { runtimeFile } from "../shared.js";
|
|
18
19
|
const HOOK_TOOLS = ["claude", "copilot", "cursor", "codex"];
|
|
19
20
|
function printSkillsUsage() {
|
|
20
21
|
console.log("Usage:");
|
|
@@ -78,7 +79,7 @@ function openInEditor(filePath) {
|
|
|
78
79
|
}
|
|
79
80
|
catch (err) {
|
|
80
81
|
if ((process.env.PHREN_DEBUG))
|
|
81
|
-
|
|
82
|
+
logger.debug("cli-namespaces", `openInEditor: ${errorMessage(err)}`);
|
|
82
83
|
console.error(`Editor "${editor}" failed. Set $EDITOR to your preferred editor.`);
|
|
83
84
|
process.exit(1);
|
|
84
85
|
}
|
|
@@ -147,7 +148,7 @@ export function handleSkillsNamespace(args, profile) {
|
|
|
147
148
|
}
|
|
148
149
|
catch (err) {
|
|
149
150
|
if ((process.env.PHREN_DEBUG))
|
|
150
|
-
|
|
151
|
+
logger.debug("cli-namespaces", `skill add symlinkFailed: ${errorMessage(err)}`);
|
|
151
152
|
fs.copyFileSync(source, dest);
|
|
152
153
|
console.log(`Copied skill ${fileName} into ${project}.`);
|
|
153
154
|
}
|
|
@@ -457,7 +458,7 @@ export function handleDetectSkills(args, profile) {
|
|
|
457
458
|
}
|
|
458
459
|
catch (err) {
|
|
459
460
|
if ((process.env.PHREN_DEBUG))
|
|
460
|
-
|
|
461
|
+
logger.debug("cli-namespaces", `skillList lstat: ${errorMessage(err)}`);
|
|
461
462
|
}
|
|
462
463
|
const name = entry.replace(/\.md$/, "");
|
|
463
464
|
if (trackedSkills.has(name))
|
|
@@ -666,7 +667,7 @@ export async function handleProjectsNamespace(args, profile) {
|
|
|
666
667
|
console.error(`Project "${name}" not found.`);
|
|
667
668
|
process.exit(1);
|
|
668
669
|
}
|
|
669
|
-
const { readFindings, readTasks, resolveTaskFilePath, TASKS_FILENAME } = await import("
|
|
670
|
+
const { readFindings, readTasks, resolveTaskFilePath, TASKS_FILENAME } = await import("../data/access.js");
|
|
670
671
|
const exported = { project: name, exportedAt: new Date().toISOString(), version: 1 };
|
|
671
672
|
const summaryPath = path.join(projectDir, "summary.md");
|
|
672
673
|
if (fs.existsSync(summaryPath))
|
|
@@ -721,7 +722,7 @@ export async function handleProjectsNamespace(args, profile) {
|
|
|
721
722
|
console.error("Invalid import payload: missing project field.");
|
|
722
723
|
process.exit(1);
|
|
723
724
|
}
|
|
724
|
-
const { TASKS_FILENAME } = await import("
|
|
725
|
+
const { TASKS_FILENAME } = await import("../data/access.js");
|
|
725
726
|
const phrenPath = getPhrenPath();
|
|
726
727
|
const projectName = normalizeProjectNameForCreate(String(decoded.project));
|
|
727
728
|
if (!isValidProjectName(projectName)) {
|
|
@@ -874,7 +875,7 @@ function handleProjectsList(profile) {
|
|
|
874
875
|
}
|
|
875
876
|
catch (err) {
|
|
876
877
|
if ((process.env.PHREN_DEBUG))
|
|
877
|
-
|
|
878
|
+
logger.debug("cli-namespaces", `projects list readdir: ${errorMessage(err)}`);
|
|
878
879
|
dirFiles = new Set();
|
|
879
880
|
}
|
|
880
881
|
const tags = [];
|
|
@@ -917,7 +918,7 @@ async function handleProjectsRemove(name, profile) {
|
|
|
917
918
|
}
|
|
918
919
|
catch (err) {
|
|
919
920
|
if ((process.env.PHREN_DEBUG))
|
|
920
|
-
|
|
921
|
+
logger.debug("cli-namespaces", `projects remove countFiles: ${errorMessage(err)}`);
|
|
921
922
|
}
|
|
922
923
|
const readline = await import("readline");
|
|
923
924
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -956,7 +957,7 @@ export async function handleTaskNamespace(args) {
|
|
|
956
957
|
}
|
|
957
958
|
if (subcommand === "list") {
|
|
958
959
|
// Delegate to the cross-project task view (same as `phren tasks`)
|
|
959
|
-
const { handleTaskView } = await import("./
|
|
960
|
+
const { handleTaskView } = await import("./ops.js");
|
|
960
961
|
return handleTaskView(args[1] || "default");
|
|
961
962
|
}
|
|
962
963
|
if (subcommand === "add") {
|
|
@@ -1321,7 +1322,7 @@ export async function handleFindingNamespace(args) {
|
|
|
1321
1322
|
console.error("Usage: phren finding list <project>");
|
|
1322
1323
|
process.exit(1);
|
|
1323
1324
|
}
|
|
1324
|
-
const { readFindings } = await import("
|
|
1325
|
+
const { readFindings } = await import("../data/access.js");
|
|
1325
1326
|
const result = readFindings(getPhrenPath(), project);
|
|
1326
1327
|
if (!result.ok) {
|
|
1327
1328
|
console.error(result.error);
|
|
@@ -1441,7 +1442,7 @@ export async function handleFindingNamespace(args) {
|
|
|
1441
1442
|
const project = args[1];
|
|
1442
1443
|
const phrenPath = getPhrenPath();
|
|
1443
1444
|
const RESERVED_DIRS = new Set(["global", ".runtime", ".sessions", ".config"]);
|
|
1444
|
-
const { readFindings } = await import("
|
|
1445
|
+
const { readFindings } = await import("../data/access.js");
|
|
1445
1446
|
const projects = project
|
|
1446
1447
|
? [project]
|
|
1447
1448
|
: fs.readdirSync(phrenPath, { withFileTypes: true })
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { execFileSync } from "child_process";
|
|
4
|
-
import { EXEC_TIMEOUT_MS, findProjectNameCaseInsensitive, getPhrenPath, normalizeProjectNameForCreate, } from "
|
|
5
|
-
import { isValidProjectName, errorMessage } from "
|
|
6
|
-
import { readTasksAcrossProjects, TASKS_FILENAME } from "
|
|
7
|
-
import { applyGravity } from "
|
|
8
|
-
import { buildIndex, queryRows } from "
|
|
9
|
-
import { resolveSubprocessArgs } from "./
|
|
10
|
-
import { listAllSessions, getSessionArtifacts } from "
|
|
4
|
+
import { EXEC_TIMEOUT_MS, findProjectNameCaseInsensitive, getPhrenPath, normalizeProjectNameForCreate, } from "../shared.js";
|
|
5
|
+
import { isValidProjectName, errorMessage } from "../utils.js";
|
|
6
|
+
import { readTasksAcrossProjects, TASKS_FILENAME } from "../data/access.js";
|
|
7
|
+
import { applyGravity } from "../data/tasks.js";
|
|
8
|
+
import { buildIndex, queryRows } from "../shared/index.js";
|
|
9
|
+
import { resolveSubprocessArgs } from "./hooks.js";
|
|
10
|
+
import { listAllSessions, getSessionArtifacts } from "../tools/session.js";
|
|
11
11
|
export function handleTaskView(profile) {
|
|
12
12
|
const docs = readTasksAcrossProjects(getPhrenPath(), profile);
|
|
13
13
|
if (!docs.length) {
|
|
@@ -100,8 +100,8 @@ export function handleSessionsView(args) {
|
|
|
100
100
|
console.log(`\n${sessions.length} session(s). Use \`phren sessions <id>\` to drill into one.`);
|
|
101
101
|
}
|
|
102
102
|
export async function handleQuickstart() {
|
|
103
|
-
const { runInit } = await import("
|
|
104
|
-
const { runLink } = await import("
|
|
103
|
+
const { runInit } = await import("../init/init.js");
|
|
104
|
+
const { runLink } = await import("../link/link.js");
|
|
105
105
|
const dirBasename = path.basename(process.cwd());
|
|
106
106
|
const readline = await import("readline");
|
|
107
107
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
|
-
import { runtimeFile } from "
|
|
4
|
-
import { buildIndex, extractSnippet, queryDocRows, queryRows, queryEntityLinks, queryDocBySourceKey, logEntityMiss } from "
|
|
5
|
-
import { buildFtsQueryVariants, errorMessage, isValidProjectName } from "
|
|
6
|
-
import {
|
|
3
|
+
import { runtimeFile } from "../shared.js";
|
|
4
|
+
import { buildIndex, extractSnippet, queryDocRows, queryRows, queryEntityLinks, queryDocBySourceKey, logEntityMiss } from "../shared/index.js";
|
|
5
|
+
import { buildFtsQueryVariants, errorMessage, isValidProjectName } from "../utils.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
7
|
+
import { keywordFallbackSearch } from "../core/search.js";
|
|
7
8
|
const MAX_HISTORY = 20;
|
|
8
9
|
const SEARCH_TYPE_ALIASES = {
|
|
9
10
|
skills: "skill",
|
|
@@ -35,7 +36,7 @@ export function readSearchHistory(phrenPath) {
|
|
|
35
36
|
}
|
|
36
37
|
catch (err) {
|
|
37
38
|
if ((process.env.PHREN_DEBUG))
|
|
38
|
-
|
|
39
|
+
logger.debug("cli-search", `readSearchHistory: ${errorMessage(err)}`);
|
|
39
40
|
return [];
|
|
40
41
|
}
|
|
41
42
|
}
|
|
@@ -249,12 +250,12 @@ export async function runSearch(opts, phrenPath, profile) {
|
|
|
249
250
|
if (!rows) {
|
|
250
251
|
if (opts.query) {
|
|
251
252
|
try {
|
|
252
|
-
const { logSearchMiss } = await import("
|
|
253
|
+
const { logSearchMiss } = await import("../tools/search.js");
|
|
253
254
|
logSearchMiss(phrenPath, opts.query, opts.project);
|
|
254
255
|
}
|
|
255
256
|
catch (err) {
|
|
256
257
|
if ((process.env.PHREN_DEBUG))
|
|
257
|
-
|
|
258
|
+
logger.debug("cli-search", `search logSearchMiss: ${errorMessage(err)}`);
|
|
258
259
|
}
|
|
259
260
|
}
|
|
260
261
|
const scope = [
|