@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.
Files changed (147) hide show
  1. package/mcp/dist/capabilities/cli.js +2 -5
  2. package/mcp/dist/capabilities/mcp.js +5 -8
  3. package/mcp/dist/capabilities/types.js +2 -5
  4. package/mcp/dist/capabilities/vscode.js +2 -5
  5. package/mcp/dist/capabilities/web-ui.js +2 -5
  6. package/mcp/dist/{cli-actions.js → cli/actions.js} +22 -21
  7. package/mcp/dist/{cli.js → cli/cli.js} +13 -13
  8. package/mcp/dist/{cli-config.js → cli/config.js} +9 -9
  9. package/mcp/dist/{cli-extract.js → cli/extract.js} +8 -8
  10. package/mcp/dist/{cli-govern.js → cli/govern.js} +10 -9
  11. package/mcp/dist/{cli-graph.js → cli/graph.js} +10 -9
  12. package/mcp/dist/{cli-hooks-citations.js → cli/hooks-citations.js} +2 -2
  13. package/mcp/dist/{cli-hooks-context.js → cli/hooks-context.js} +23 -23
  14. package/mcp/dist/{cli-hooks-globs.js → cli/hooks-globs.js} +4 -4
  15. package/mcp/dist/{cli-hooks-output.js → cli/hooks-output.js} +9 -10
  16. package/mcp/dist/{cli-hooks-session.js → cli/hooks-session.js} +42 -57
  17. package/mcp/dist/{cli-hooks.js → cli/hooks.js} +27 -26
  18. package/mcp/dist/{cli-namespaces.js → cli/namespaces.js} +25 -24
  19. package/mcp/dist/{cli-ops.js → cli/ops.js} +9 -9
  20. package/mcp/dist/{cli-search.js → cli/search.js} +8 -7
  21. package/mcp/dist/cli-hooks-git.js +243 -0
  22. package/mcp/dist/cli-hooks-prompt.js +319 -0
  23. package/mcp/dist/cli-hooks-session-handlers.js +349 -0
  24. package/mcp/dist/cli-hooks-stop.js +557 -0
  25. package/mcp/dist/{content-archive.js → content/archive.js} +8 -9
  26. package/mcp/dist/{content-citation.js → content/citation.js} +5 -5
  27. package/mcp/dist/{content-dedup.js → content/dedup.js} +9 -12
  28. package/mcp/dist/{content-learning.js → content/learning.js} +12 -12
  29. package/mcp/dist/{content-validate.js → content/validate.js} +5 -5
  30. package/mcp/dist/{core-finding.js → core/finding.js} +4 -4
  31. package/mcp/dist/{core-project.js → core/project.js} +4 -4
  32. package/mcp/dist/{core-search.js → core/search.js} +2 -2
  33. package/mcp/dist/{data-access.js → data/access.js} +131 -13
  34. package/mcp/dist/{data-tasks.js → data/tasks.js} +7 -5
  35. package/mcp/dist/embedding.js +9 -14
  36. package/mcp/dist/entrypoint.js +11 -11
  37. package/mcp/dist/{finding-context.js → finding/context.js} +2 -2
  38. package/mcp/dist/{finding-impact.js → finding/impact.js} +3 -3
  39. package/mcp/dist/{finding-journal.js → finding/journal.js} +4 -4
  40. package/mcp/dist/{finding-lifecycle.js → finding/lifecycle.js} +4 -4
  41. package/mcp/dist/{governance-audit.js → governance/audit.js} +2 -2
  42. package/mcp/dist/{governance-locks.js → governance/locks.js} +14 -9
  43. package/mcp/dist/{governance-policy.js → governance/policy.js} +10 -12
  44. package/mcp/dist/{governance-rbac.js → governance/rbac.js} +3 -3
  45. package/mcp/dist/{governance-scores.js → governance/scores.js} +8 -10
  46. package/mcp/dist/hooks.js +39 -31
  47. package/mcp/dist/index-query.js +4 -1
  48. package/mcp/dist/index.js +53 -29
  49. package/mcp/dist/{init-config.js → init/config.js} +6 -6
  50. package/mcp/dist/{init.js → init/init.js} +28 -29
  51. package/mcp/dist/{init-preferences.js → init/preferences.js} +3 -3
  52. package/mcp/dist/{init-setup.js → init/setup.js} +17 -19
  53. package/mcp/dist/{init-shared.js → init/shared.js} +3 -3
  54. package/mcp/dist/init-bootstrap.js +68 -0
  55. package/mcp/dist/init-detect.js +38 -0
  56. package/mcp/dist/init-dryrun.js +55 -0
  57. package/mcp/dist/init-env.js +114 -0
  58. package/mcp/dist/init-fresh.js +239 -0
  59. package/mcp/dist/init-hooks.js +26 -0
  60. package/mcp/dist/init-mcp.js +65 -0
  61. package/mcp/dist/init-migrate.js +51 -0
  62. package/mcp/dist/init-modes.js +135 -0
  63. package/mcp/dist/init-npm.js +37 -0
  64. package/mcp/dist/init-project-local.js +99 -0
  65. package/mcp/dist/init-semantic.js +48 -0
  66. package/mcp/dist/init-types.js +1 -0
  67. package/mcp/dist/init-uninstall.js +482 -0
  68. package/mcp/dist/init-update.js +96 -0
  69. package/mcp/dist/init-walkthrough-merge.js +90 -0
  70. package/mcp/dist/init-walkthrough.js +529 -0
  71. package/mcp/dist/{link-checksums.js → link/checksums.js} +5 -5
  72. package/mcp/dist/{link-context.js → link/context.js} +4 -4
  73. package/mcp/dist/{link-doctor.js → link/doctor.js} +20 -22
  74. package/mcp/dist/{link.js → link/link.js} +26 -31
  75. package/mcp/dist/{link-skills.js → link/skills.js} +10 -10
  76. package/mcp/dist/logger.js +11 -3
  77. package/mcp/dist/phren-art.js +0 -6
  78. package/mcp/dist/phren-paths.js +30 -12
  79. package/mcp/dist/proactivity.js +2 -2
  80. package/mcp/dist/profile-store.js +5 -6
  81. package/mcp/dist/project-config.js +2 -2
  82. package/mcp/dist/project-topics.js +1 -1
  83. package/mcp/dist/query-correlation.js +1 -1
  84. package/mcp/dist/{session-checkpoints.js → session/checkpoints.js} +3 -3
  85. package/mcp/dist/{session-utils.js → session/utils.js} +1 -1
  86. package/mcp/dist/{shared-content.js → shared/content.js} +7 -7
  87. package/mcp/dist/{shared-data-utils.js → shared/data-utils.js} +3 -3
  88. package/mcp/dist/{shared-embedding-cache.js → shared/embedding-cache.js} +3 -3
  89. package/mcp/dist/{shared-fragment-graph.js → shared/fragment-graph.js} +15 -24
  90. package/mcp/dist/shared/governance.js +4 -0
  91. package/mcp/dist/{shared-index.js → shared/index.js} +92 -123
  92. package/mcp/dist/{shared-ollama.js → shared/ollama.js} +2 -2
  93. package/mcp/dist/{shared-retrieval.js → shared/retrieval.js} +16 -21
  94. package/mcp/dist/{shared-search-fallback.js → shared/search-fallback.js} +17 -20
  95. package/mcp/dist/{shared-sqljs.js → shared/sqljs.js} +3 -3
  96. package/mcp/dist/{shared-vector-index.js → shared/vector-index.js} +3 -3
  97. package/mcp/dist/shared.js +4 -59
  98. package/mcp/dist/{shell-entry.js → shell/entry.js} +6 -6
  99. package/mcp/dist/{shell-input.js → shell/input.js} +13 -13
  100. package/mcp/dist/{shell-palette.js → shell/palette.js} +3 -3
  101. package/mcp/dist/{shell-render.js → shell/render.js} +1 -1
  102. package/mcp/dist/{shell.js → shell/shell.js} +11 -11
  103. package/mcp/dist/{shell-state-store.js → shell/state-store.js} +5 -5
  104. package/mcp/dist/{shell-view-list.js → shell/view-list.js} +1 -1
  105. package/mcp/dist/{shell-view.js → shell/view.js} +13 -13
  106. package/mcp/dist/{skill-files.js → skill/files.js} +9 -9
  107. package/mcp/dist/{skill-registry.js → skill/registry.js} +4 -4
  108. package/mcp/dist/{skill-state.js → skill/state.js} +1 -1
  109. package/mcp/dist/startup-embedding.js +2 -2
  110. package/mcp/dist/status.js +15 -14
  111. package/mcp/dist/{tasks-github.js → task/github.js} +2 -2
  112. package/mcp/dist/{task-hygiene.js → task/hygiene.js} +4 -4
  113. package/mcp/dist/{task-lifecycle.js → task/lifecycle.js} +7 -7
  114. package/mcp/dist/telemetry.js +3 -4
  115. package/mcp/dist/tool-registry.js +29 -17
  116. package/mcp/dist/tools/config.js +515 -0
  117. package/mcp/dist/{mcp-data.js → tools/data.js} +8 -10
  118. package/mcp/dist/{mcp-extract-facts.js → tools/extract-facts.js} +6 -6
  119. package/mcp/dist/{mcp-extract.js → tools/extract.js} +6 -6
  120. package/mcp/dist/{mcp-finding.js → tools/finding.js} +97 -124
  121. package/mcp/dist/{mcp-graph.js → tools/graph.js} +11 -14
  122. package/mcp/dist/{mcp-hooks.js → tools/hooks.js} +6 -6
  123. package/mcp/dist/{mcp-memory.js → tools/memory.js} +5 -5
  124. package/mcp/dist/{mcp-ops.js → tools/ops.js} +169 -71
  125. package/mcp/dist/{mcp-search.js → tools/search.js} +19 -23
  126. package/mcp/dist/{mcp-session.js → tools/session.js} +48 -23
  127. package/mcp/dist/{mcp-skills.js → tools/skills.js} +33 -35
  128. package/mcp/dist/{mcp-tasks.js → tools/tasks.js} +155 -282
  129. package/mcp/dist/{memory-ui-data.js → ui/data.js} +31 -17
  130. package/mcp/dist/{memory-ui.js → ui/memory-ui.js} +3 -3
  131. package/mcp/dist/{memory-ui-page.js → ui/page.js} +4 -6
  132. package/mcp/dist/{memory-ui-server.js → ui/server.js} +30 -22
  133. package/mcp/dist/update.js +2 -2
  134. package/mcp/dist/utils.js +51 -11
  135. package/package.json +2 -2
  136. package/scripts/preuninstall.mjs +31 -0
  137. package/starter/global/CLAUDE.md +3 -2
  138. package/mcp/dist/mcp-config.js +0 -551
  139. package/mcp/dist/shared-governance.js +0 -4
  140. /package/mcp/dist/{content-metadata.js → content/metadata.js} +0 -0
  141. /package/mcp/dist/{shared-stemmer.js → shared/stemmer.js} +0 -0
  142. /package/mcp/dist/{shell-types.js → shell/types.js} +0 -0
  143. /package/mcp/dist/{mcp-types.js → tools/types.js} +0 -0
  144. /package/mcp/dist/{memory-ui-assets.js → ui/assets.js} +0 -0
  145. /package/mcp/dist/{memory-ui-graph.js → ui/graph.js} +0 -0
  146. /package/mcp/dist/{memory-ui-scripts.js → ui/scripts.js} +0 -0
  147. /package/mcp/dist/{memory-ui-styles.js → ui/styles.js} +0 -0
@@ -1,11 +1,12 @@
1
1
  import { createHash } from "crypto";
2
- import { debugLog } from "./shared.js";
3
- import { STOP_WORDS, errorMessage } from "./utils.js";
4
- import { porterStem } from "./shared-stemmer.js";
5
- import { classifyFile, normalizeIndexedContent, rowToDocWithRowid } from "./shared-index.js";
6
- import { embedText, cosineSimilarity, getEmbeddingModel, getOllamaUrl, getCloudEmbeddingUrl } from "./shared-ollama.js";
7
- import { getEmbeddingCache } from "./shared-embedding-cache.js";
8
- import { getPersistentVectorIndex } from "./shared-vector-index.js";
2
+ import { debugLog } from "../shared.js";
3
+ import { logger } from "../logger.js";
4
+ import { STOP_WORDS, errorMessage } from "../utils.js";
5
+ import { porterStem } from "./stemmer.js";
6
+ import { classifyFile, normalizeIndexedContent, rowToDocWithRowid } from "./index.js";
7
+ import { embedText, cosineSimilarity, getEmbeddingModel, getOllamaUrl, getCloudEmbeddingUrl } from "./ollama.js";
8
+ import { getEmbeddingCache } from "./embedding-cache.js";
9
+ import { getPersistentVectorIndex } from "./vector-index.js";
9
10
  import * as fs from "fs";
10
11
  import * as path from "path";
11
12
  const HYBRID_SEARCH_FLAG = "PHREN_FEATURE_HYBRID_SEARCH";
@@ -123,8 +124,10 @@ function tfidfCosine(docs, query, corpusN) {
123
124
  const N = corpusN ?? docs.length;
124
125
  // Compute document frequency for each term, keyed by a fingerprint of the candidate doc set
125
126
  // so that different subsets and incremental index mutations get distinct cache entries.
127
+ const corpusSize = docTokenLists.length;
128
+ const corpusLengthSum = docTokenLists.reduce((sum, tl) => sum + tl.length, 0);
126
129
  const candidateFingerprint = docTokenLists.map(tl => tl.slice(0, 4).join(",")).join("|").slice(0, 128);
127
- const cacheKey = `fp:${candidateFingerprint}`;
130
+ const cacheKey = `fp:${corpusSize}:${corpusLengthSum}:${candidateFingerprint}`;
128
131
  const cachedDf = dfCache.get(cacheKey);
129
132
  const df = cachedDf ?? new Map();
130
133
  // Compute DF for any terms not yet in cache
@@ -181,8 +184,7 @@ export function cosineFallback(db, query, excludeRowids, limit) {
181
184
  }
182
185
  }
183
186
  catch (err) {
184
- if ((process.env.PHREN_DEBUG))
185
- process.stderr.write(`[phren] cosineFallback count: ${errorMessage(err)}\n`);
187
+ logger.debug("cosineFallback count", errorMessage(err));
186
188
  return [];
187
189
  }
188
190
  if (totalDocs > COSINE_MAX_CORPUS) {
@@ -210,8 +212,7 @@ export function cosineFallback(db, query, excludeRowids, limit) {
210
212
  ftsRows.push(...ftsRes[0].values);
211
213
  }
212
214
  catch (err) {
213
- if ((process.env.PHREN_DEBUG))
214
- process.stderr.write(`[phren] cosineFallback FTS pre-filter: ${errorMessage(err)}\n`);
215
+ logger.debug("cosineFallback FTS pre-filter", errorMessage(err));
215
216
  }
216
217
  }
217
218
  // If FTS gave fewer than cap, supplement with deterministic rowid windows.
@@ -248,8 +249,7 @@ export function cosineFallback(db, query, excludeRowids, limit) {
248
249
  }
249
250
  }
250
251
  catch (err) {
251
- if ((process.env.PHREN_DEBUG))
252
- process.stderr.write(`[phren] cosineFallback deterministicSample: ${errorMessage(err)}\n`);
252
+ logger.debug("cosineFallback deterministicSample", errorMessage(err));
253
253
  }
254
254
  }
255
255
  if (ftsRows.length === 0)
@@ -259,8 +259,7 @@ export function cosineFallback(db, query, excludeRowids, limit) {
259
259
  }
260
260
  }
261
261
  catch (err) {
262
- if ((process.env.PHREN_DEBUG))
263
- process.stderr.write(`[phren] cosineFallback loadDocs: ${errorMessage(err)}\n`);
262
+ logger.debug("cosineFallback loadDocs", errorMessage(err));
264
263
  return [];
265
264
  }
266
265
  // Separate rowids, DocRows, and content strings for scoring
@@ -305,8 +304,7 @@ export async function vectorFallback(phrenPath, query, excludePaths, limit, proj
305
304
  await cache.load();
306
305
  }
307
306
  catch (err) {
308
- if ((process.env.PHREN_DEBUG))
309
- process.stderr.write(`[phren] vectorFallback cacheLoad: ${errorMessage(err)}\n`);
307
+ logger.debug("vectorFallback cacheLoad", errorMessage(err));
310
308
  }
311
309
  }
312
310
  if (cache.size() === 0)
@@ -357,8 +355,7 @@ export async function vectorFallback(phrenPath, query, excludePaths, limit, proj
357
355
  }
358
356
  }
359
357
  catch (err) {
360
- if ((process.env.PHREN_DEBUG))
361
- process.stderr.write(`[phren] vectorFallback fileRead: ${errorMessage(err)}\n`);
358
+ logger.debug("vectorFallback fileRead", errorMessage(err));
362
359
  }
363
360
  return { project: entryProject, filename, type, content, path: e.path };
364
361
  });
@@ -2,7 +2,8 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import { createRequire } from "module";
5
- import { errorMessage } from "./utils.js";
5
+ import { errorMessage } from "../utils.js";
6
+ import { logger } from "../logger.js";
6
7
  const require = createRequire(import.meta.url);
7
8
  /**
8
9
  * Locate the sql.js-fts5 WASM binary by require.resolve with path-probe fallback.
@@ -15,8 +16,7 @@ function findWasmBinary() {
15
16
  return fs.readFileSync(resolved);
16
17
  }
17
18
  catch (err) {
18
- if ((process.env.PHREN_DEBUG))
19
- process.stderr.write(`[phren] findWasmBinary requireResolve: ${errorMessage(err)}\n`);
19
+ logger.debug("sqljs", `findWasmBinary requireResolve: ${errorMessage(err)}`);
20
20
  // fall through to path probing
21
21
  }
22
22
  const __filename = fileURLToPath(import.meta.url);
@@ -1,8 +1,8 @@
1
1
  import * as fs from "fs";
2
2
  import * as crypto from "crypto";
3
- import { runtimeFile, debugLog } from "./shared.js";
4
- import { withFileLock } from "./shared-governance.js";
5
- import { errorMessage } from "./utils.js";
3
+ import { runtimeFile, debugLog } from "../shared.js";
4
+ import { withFileLock } from "./governance.js";
5
+ import { errorMessage } from "../utils.js";
6
6
  const VECTOR_INDEX_VERSION = 1;
7
7
  const VECTOR_INDEX_TABLE_COUNT = 4;
8
8
  const VECTOR_INDEX_BITS_PER_TABLE = 12;
@@ -2,6 +2,7 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { debugLog, runtimeFile } from "./phren-paths.js";
4
4
  import { errorMessage } from "./utils.js";
5
+ import { withFileLock } from "./governance/locks.js";
5
6
  export { HOOK_TOOL_NAMES, hookConfigPath } from "./provider-adapters.js";
6
7
  export { EXEC_TIMEOUT_MS, EXEC_TIMEOUT_QUICK_MS, PhrenError, phrenOk, phrenErr, forwardErr, parsePhrenErrorCode, isRecord, withDefaults, FINDING_TYPES, FINDING_TAGS, KNOWN_OBSERVATION_TAGS, DOC_TYPES, capCache, RESERVED_PROJECT_DIR_NAMES, } from "./phren-core.js";
7
8
  export { ROOT_MANIFEST_FILENAME, homeDir, homePath, expandHomePath, defaultPhrenPath, rootManifestPath, readRootManifest, writeRootManifest, resolveInstallContext, findNearestPhrenPath, isProjectLocalMode, runtimeDir, tryUnlink, sessionsDir, runtimeFile, installPreferencesFile, runtimeHealthFile, shellStateFile, sessionMetricsFile, memoryScoresFile, memoryUsageLogFile, sessionMarker, debugLog, appendIndexEvent, resolveFindingsPath, findPhrenPath, ensurePhrenPath, findPhrenPathWithArg, normalizeProjectNameForCreate, findProjectNameCaseInsensitive, findArchivedProjectNameCaseInsensitive, getProjectDirs, collectNativeMemoryFiles, computePhrenLiveStateToken, getPhrenPath, qualityMarkers, atomicWriteText, } from "./phren-paths.js";
@@ -30,51 +31,9 @@ export function impactLogFile(phrenPath) {
30
31
  export function appendAuditLog(phrenPath, event, details) {
31
32
  const logPath = runtimeFile(phrenPath, "audit.log");
32
33
  const line = `[${new Date().toISOString()}] ${event} ${details}\n`;
33
- const lockPath = logPath + ".lock";
34
- const maxWait = 5000;
35
- const pollMs = 50;
36
- const staleMs = 30_000;
37
- const waiter = new Int32Array(new SharedArrayBuffer(4));
38
- // Q82: use an inline lock (same protocol as withFileLock) to guard the
39
- // append + conditional rotation so concurrent processes don't read the same
40
- // old content and race to write a truncated version each.
41
- let waited = 0;
42
- let hasLock = false;
43
34
  try {
44
- fs.mkdirSync(path.dirname(lockPath), { recursive: true });
45
- while (waited < maxWait) {
46
- try {
47
- fs.writeFileSync(lockPath, `${process.pid}\n${Date.now()}`, { flag: "wx" });
48
- hasLock = true;
49
- break;
50
- }
51
- catch (err) {
52
- if ((process.env.PHREN_DEBUG))
53
- process.stderr.write(`[phren] appendAuditLog lockWrite: ${errorMessage(err)}\n`);
54
- try {
55
- const stat = fs.statSync(lockPath);
56
- if (Date.now() - stat.mtimeMs > staleMs) {
57
- try {
58
- fs.unlinkSync(lockPath);
59
- }
60
- catch {
61
- // Another process may have claimed or removed the stale lock between
62
- // statSync and unlinkSync. Sleep before retrying to avoid a spin loop.
63
- Atomics.wait(waiter, 0, 0, pollMs);
64
- waited += pollMs;
65
- }
66
- continue;
67
- }
68
- }
69
- catch (statErr) {
70
- if ((process.env.PHREN_DEBUG))
71
- process.stderr.write(`[phren] appendAuditLog staleStat: ${errorMessage(statErr)}\n`);
72
- }
73
- Atomics.wait(waiter, 0, 0, pollMs);
74
- waited += pollMs;
75
- }
76
- }
77
- if (hasLock) {
35
+ fs.mkdirSync(path.dirname(logPath), { recursive: true });
36
+ withFileLock(logPath, () => {
78
37
  fs.appendFileSync(logPath, line);
79
38
  const stat = fs.statSync(logPath);
80
39
  if (stat.size > 1_000_000) {
@@ -82,23 +41,9 @@ export function appendAuditLog(phrenPath, event, details) {
82
41
  const lines = content.split("\n");
83
42
  fs.writeFileSync(logPath, lines.slice(-500).join("\n") + "\n");
84
43
  }
85
- }
86
- else {
87
- debugLog(`Audit log skipped (lock timeout): ${event} ${details}`);
88
- }
44
+ });
89
45
  }
90
46
  catch (err) {
91
47
  debugLog(`Audit log write failed: ${errorMessage(err)}`);
92
48
  }
93
- finally {
94
- if (hasLock) {
95
- try {
96
- fs.unlinkSync(lockPath);
97
- }
98
- catch (err) {
99
- if ((process.env.PHREN_DEBUG))
100
- process.stderr.write(`[phren] appendAuditLog unlock: ${errorMessage(err)}\n`);
101
- }
102
- }
103
- }
104
49
  }
@@ -3,12 +3,12 @@
3
3
  * Extracted from shell.ts to keep the orchestrator under 300 lines.
4
4
  */
5
5
  import { PhrenShell } from "./shell.js";
6
- import { style, clearScreen, clearToEnd, shellStartupFrames, gradient, badge } from "./shell-render.js";
7
- import { createPhrenAnimator } from "./phren-art.js";
8
- import { errorMessage } from "./utils.js";
9
- import { computePhrenLiveStateToken } from "./shared.js";
10
- import { VERSION } from "./init-shared.js";
11
- import { loadShellState, saveShellState } from "./shell-state-store.js";
6
+ import { style, clearScreen, clearToEnd, shellStartupFrames, gradient, badge } from "./render.js";
7
+ import { createPhrenAnimator } from "../phren-art.js";
8
+ import { errorMessage } from "../utils.js";
9
+ import { computePhrenLiveStateToken } from "../shared.js";
10
+ import { VERSION } from "../init/shared.js";
11
+ import { loadShellState, saveShellState } from "./state-store.js";
12
12
  const LIVE_STATE_POLL_MS = 2000;
13
13
  function renderIntroFrame(frame, footer) {
14
14
  clearScreen();
@@ -5,17 +5,18 @@
5
5
  import { execFileSync } from "child_process";
6
6
  import * as fs from "fs";
7
7
  import * as path from "path";
8
- import { addTask, addFinding, addProjectToProfile, completeTask, listProjectCards, pinTask, readTasks, readFindings, readReviewQueue, removeFinding, removeProjectFromProfile, resetShellState, saveShellState, setMachineProfile, tidyDoneTasks, canonicalTaskFilePath, unpinTask, updateTask, workNextTask, loadShellState, resolveTaskFilePath, } from "./data-access.js";
9
- import { runtimeFile } from "./shared.js";
10
- import { handleGovernMemories } from "./cli-govern.js";
11
- import { runSearch } from "./cli-search.js";
12
- import { consolidateProjectFindings } from "./governance-policy.js";
13
- import { style } from "./shell-render.js";
14
- import { SUB_VIEWS, TAB_ICONS } from "./shell-types.js";
15
- import { getProjectSkills, getHookEntries, writeInstallPreferences } from "./shell-view.js";
16
- import { removeSkillPath, setSkillEnabledAndSync } from "./skill-files.js";
17
- import { resultMsg, editDistance, tokenize, expandIds, normalizeSection, tasksByFilter, queueByFilter, } from "./shell-palette.js";
18
- import { errorMessage } from "./utils.js";
8
+ import { addTask, addFinding, addProjectToProfile, completeTask, listProjectCards, pinTask, readTasks, readFindings, readReviewQueue, removeFinding, removeProjectFromProfile, resetShellState, saveShellState, setMachineProfile, tidyDoneTasks, canonicalTaskFilePath, unpinTask, updateTask, workNextTask, loadShellState, resolveTaskFilePath, } from "../data/access.js";
9
+ import { runtimeFile } from "../shared.js";
10
+ import { handleGovernMemories } from "../cli/govern.js";
11
+ import { runSearch } from "../cli/search.js";
12
+ import { consolidateProjectFindings } from "../governance/policy.js";
13
+ import { style } from "./render.js";
14
+ import { SUB_VIEWS, TAB_ICONS } from "./types.js";
15
+ import { getProjectSkills, getHookEntries, writeInstallPreferences } from "./view.js";
16
+ import { removeSkillPath, setSkillEnabledAndSync } from "../skill/files.js";
17
+ import { resultMsg, editDistance, tokenize, expandIds, normalizeSection, tasksByFilter, queueByFilter, } from "./palette.js";
18
+ import { errorMessage } from "../utils.js";
19
+ import { logger } from "../logger.js";
19
20
  function taskFileForProject(phrenPath, project) {
20
21
  return resolveTaskFilePath(phrenPath, project)
21
22
  ?? canonicalTaskFilePath(phrenPath, project)
@@ -379,8 +380,7 @@ export async function executePalette(host, input) {
379
380
  }
380
381
  }
381
382
  catch (err) {
382
- if ((process.env.PHREN_DEBUG))
383
- process.stderr.write(`[phren] shell status gitStatus: ${errorMessage(err)}\n`);
383
+ logger.debug("shell-input", `shell status gitStatus: ${errorMessage(err)}`);
384
384
  }
385
385
  const auditPathNew = runtimeFile(host.phrenPath, "audit.log");
386
386
  const auditPathLegacy = path.join(host.phrenPath, ".config", "audit.log");
@@ -1,9 +1,9 @@
1
1
  import { execFileSync } from "child_process";
2
2
  import * as path from "path";
3
3
  import { fileURLToPath } from "url";
4
- import { runLink } from "./link.js";
5
- import { runPhrenUpdate } from "./update.js";
6
- import { EXEC_TIMEOUT_MS, } from "./shared.js";
4
+ import { runLink } from "../link/link.js";
5
+ import { runPhrenUpdate } from "../update.js";
6
+ import { EXEC_TIMEOUT_MS, } from "../shared.js";
7
7
  export function resultMsg(r) {
8
8
  if (!r.ok)
9
9
  return r.error;
@@ -150,7 +150,7 @@ const PHREN_LOGO = [
150
150
  "██║ ██║ ██║██║ ██║███████╗██║ ╚████║",
151
151
  "╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝",
152
152
  ];
153
- import { PHREN_ART as PHREN_STARTUP_ART } from "./phren-art.js";
153
+ import { PHREN_ART as PHREN_STARTUP_ART } from "../phren-art.js";
154
154
  // ── Line-based viewport: edge-triggered scroll (stable, no jumpiness) ─────────
155
155
  export function lineViewport(allLines, cursorFirstLine, cursorLastLine, height, prevStart) {
156
156
  if (allLines.length === 0 || height <= 0)
@@ -1,13 +1,14 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { addTask, addFinding, loadShellState, saveShellState, } from "./data-access.js";
4
- import { style } from "./shell-render.js";
5
- import { MAX_UNDO_STACK, } from "./shell-types.js";
6
- import { resultMsg, defaultRunHooks, defaultRunUpdate, defaultRunRelink, } from "./shell-palette.js";
7
- import { runDoctor } from "./link.js";
8
- import { renderShell, } from "./shell-view.js";
9
- import { executePalette, completeInput as completeInputFn, getListItems, handleNavigateKey, applyViewShortcut, } from "./shell-input.js";
10
- import { errorMessage } from "./utils.js";
3
+ import { addTask, addFinding, loadShellState, saveShellState, } from "../data/access.js";
4
+ import { style } from "./render.js";
5
+ import { MAX_UNDO_STACK, } from "./types.js";
6
+ import { logger } from "../logger.js";
7
+ import { resultMsg, defaultRunHooks, defaultRunUpdate, defaultRunRelink, } from "./palette.js";
8
+ import { runDoctor } from "../link/link.js";
9
+ import { renderShell, } from "./view.js";
10
+ import { executePalette, completeInput as completeInputFn, getListItems, handleNavigateKey, applyViewShortcut, } from "./input.js";
11
+ import { errorMessage } from "../utils.js";
11
12
  // ── Shell class ──────────────────────────────────────────────────────────────
12
13
  export class PhrenShell {
13
14
  phrenPath;
@@ -72,8 +73,7 @@ export class PhrenShell {
72
73
  }
73
74
  }
74
75
  catch (err) {
75
- if ((process.env.PHREN_DEBUG))
76
- process.stderr.write(`[phren] shell pushUndo: ${errorMessage(err)}\n`);
76
+ logger.debug("shell", `shell pushUndo: ${errorMessage(err)}`);
77
77
  }
78
78
  }
79
79
  popUndo() {
@@ -294,4 +294,4 @@ export class PhrenShell {
294
294
  return completeInputFn(line, this.phrenPath, this.profile, this.state);
295
295
  }
296
296
  }
297
- export { startShell } from "./shell-entry.js";
297
+ export { startShell } from "./entry.js";
@@ -1,8 +1,9 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { phrenOk, shellStateFile } from "./shared.js";
4
- import { withSafeLock } from "./shared-data-utils.js";
5
- import { errorMessage } from "./utils.js";
3
+ import { phrenOk, shellStateFile } from "../shared.js";
4
+ import { withSafeLock } from "../shared/data-utils.js";
5
+ import { errorMessage } from "../utils.js";
6
+ import { logger } from "../logger.js";
6
7
  const SHELL_STATE_VERSION = 3;
7
8
  const VALID_VIEWS = new Set(["Projects", "Tasks", "Findings", "Review Queue", "Skills", "Hooks", "Machines/Profiles", "Health"]);
8
9
  export function loadShellState(phrenPath) {
@@ -33,8 +34,7 @@ export function loadShellState(phrenPath) {
33
34
  };
34
35
  }
35
36
  catch (err) {
36
- if ((process.env.PHREN_DEBUG))
37
- process.stderr.write(`[phren] loadShellState parse: ${errorMessage(err)}\n`);
37
+ logger.debug("shell-state", `loadShellState parse: ${errorMessage(err)}`);
38
38
  return fallback;
39
39
  }
40
40
  }
@@ -1,4 +1,4 @@
1
- import { RESET, padToWidth, truncateLine, lineViewport, style } from "./shell-render.js";
1
+ import { RESET, padToWidth, truncateLine, lineViewport, style } from "./render.js";
2
2
  export function formatSelectableLine(line, cols, selected) {
3
3
  return selected
4
4
  ? `\x1b[7m${padToWidth(line, cols)}${RESET}`
@@ -4,16 +4,17 @@
4
4
  */
5
5
  import * as fs from "fs";
6
6
  import * as path from "path";
7
- import { canonicalTaskFilePath, listProjectCards, readTasks, readFindings, readReviewQueue, readRuntimeHealth, resolveTaskFilePath, } from "./data-access.js";
8
- import { style, badge, separator, stripAnsi, truncateLine, renderWidth, wrapSegments, lineViewport, shellHelpText, gradient, } from "./shell-render.js";
9
- import { formatSelectableLine, viewportWithStatus, } from "./shell-view-list.js";
10
- import { SUB_VIEWS, TAB_ICONS, } from "./shell-types.js";
11
- import { tasksByFilter, queueByFilter, } from "./shell-palette.js";
12
- import { listMachines, listProfiles, } from "./data-access.js";
13
- import { readInstallPreferences } from "./init-preferences.js";
14
- import { isProjectHookEnabled, readProjectConfig } from "./project-config.js";
15
- import { getScopedSkills } from "./skill-registry.js";
16
- import { errorMessage } from "./utils.js";
7
+ import { canonicalTaskFilePath, listProjectCards, readTasks, readFindings, readReviewQueue, readRuntimeHealth, resolveTaskFilePath, } from "../data/access.js";
8
+ import { style, badge, separator, stripAnsi, truncateLine, renderWidth, wrapSegments, lineViewport, shellHelpText, gradient, } from "./render.js";
9
+ import { formatSelectableLine, viewportWithStatus, } from "./view-list.js";
10
+ import { SUB_VIEWS, TAB_ICONS, } from "./types.js";
11
+ import { tasksByFilter, queueByFilter, } from "./palette.js";
12
+ import { listMachines, listProfiles, } from "../data/access.js";
13
+ import { readInstallPreferences } from "../init/preferences.js";
14
+ import { isProjectHookEnabled, readProjectConfig } from "../project-config.js";
15
+ import { getScopedSkills } from "../skill/registry.js";
16
+ import { errorMessage } from "../utils.js";
17
+ import { logger } from "../logger.js";
17
18
  // ── Tab bar ────────────────────────────────────────────────────────────────
18
19
  function renderTabBar(state) {
19
20
  const cols = renderWidth();
@@ -249,8 +250,7 @@ function parseSubsections(taskPath, project, cache) {
249
250
  }
250
251
  }
251
252
  catch (err) {
252
- if ((process.env.PHREN_DEBUG))
253
- process.stderr.write(`[phren] buildSubsectionMap: ${errorMessage(err)}\n`);
253
+ logger.debug("shell-view", `buildSubsectionMap: ${errorMessage(err)}`);
254
254
  }
255
255
  const newCache = { project, map };
256
256
  return { map, cache: newCache };
@@ -564,7 +564,7 @@ function renderHooksView(ctx, cursor, height) {
564
564
  ctx.setScroll(vp.scrollStart);
565
565
  return vp.lines;
566
566
  }
567
- export { writeInstallPreferences } from "./init-preferences.js";
567
+ export { writeInstallPreferences } from "../init/preferences.js";
568
568
  // ── Machines/Profiles view ─────────────────────────────────────────────────
569
569
  function renderMachinesView(phrenPath) {
570
570
  const machines = listMachines(phrenPath);
@@ -1,11 +1,12 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { homePath } from "./shared.js";
4
- import { findProjectDir } from "./project-locator.js";
5
- import { buildSkillManifest } from "./skill-registry.js";
6
- import { setSkillEnabled } from "./skill-state.js";
7
- import { errorMessage } from "./utils.js";
8
- import { isManagedSymlink } from "./link-skills.js";
3
+ import { homePath } from "../shared.js";
4
+ import { findProjectDir } from "../project-locator.js";
5
+ import { buildSkillManifest } from "./registry.js";
6
+ import { setSkillEnabled } from "./state.js";
7
+ import { errorMessage } from "../utils.js";
8
+ import { isManagedSymlink } from "../link/skills.js";
9
+ import { logger } from "../logger.js";
9
10
  function normalizeSkillRemovalTarget(skillPath) {
10
11
  if (!skillPath)
11
12
  return skillPath;
@@ -44,9 +45,8 @@ function removeManagedSkillLink(dest, managedRoot) {
44
45
  fs.unlinkSync(dest);
45
46
  }
46
47
  catch (err) {
47
- if (err.code !== "ENOENT" && (process.env.PHREN_DEBUG)) {
48
- process.stderr.write(`[phren] removeManagedSkillLink: ${errorMessage(err)}\n`);
49
- }
48
+ if (err.code !== "ENOENT")
49
+ logger.debug("skill-files", `removeManagedSkillLink: ${errorMessage(err)}`);
50
50
  }
51
51
  }
52
52
  function writeSkillArtifacts(destDir, manifest) {
@@ -1,9 +1,9 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { getProjectDirs } from "./shared.js";
4
- import { parseSkillFrontmatter } from "./link-skills.js";
5
- import { isSkillEnabled } from "./skill-state.js";
6
- import { safeProjectPath } from "./utils.js";
3
+ import { getProjectDirs } from "../shared.js";
4
+ import { parseSkillFrontmatter } from "../link/skills.js";
5
+ import { isSkillEnabled } from "./state.js";
6
+ import { safeProjectPath } from "../utils.js";
7
7
  function normalizeCommand(raw, fallbackName) {
8
8
  const value = typeof raw === "string" && raw.trim() ? raw.trim() : `/${fallbackName}`;
9
9
  return value.startsWith("/") ? value : `/${value}`;
@@ -1,4 +1,4 @@
1
- import { readInstallPreferences, writeInstallPreferences } from "./init-preferences.js";
1
+ import { readInstallPreferences, writeInstallPreferences } from "../init/preferences.js";
2
2
  function skillStateKey(scope, name) {
3
3
  return `${scope}:${name.replace(/\.md$/i, "").trim().toLowerCase()}`;
4
4
  }
@@ -1,10 +1,10 @@
1
1
  import { debugLog } from "./shared.js";
2
- import { decodeStringRow, queryRows } from "./shared-index.js";
2
+ import { decodeStringRow, queryRows } from "./shared/index.js";
3
3
  import { errorMessage } from "./utils.js";
4
4
  /** Throttle delay between embedding requests in the background embed loop. */
5
5
  const BACKGROUND_EMBED_THROTTLE_MS = 50;
6
6
  async function loadWarmupDeps() {
7
- const { checkOllamaAvailable, embedText, getEmbeddingModel, getOllamaUrl } = await import("./shared-ollama.js");
7
+ const { checkOllamaAvailable, embedText, getEmbeddingModel, getOllamaUrl } = await import("./shared/ollama.js");
8
8
  return {
9
9
  checkOllamaAvailable,
10
10
  embedText,
@@ -2,15 +2,16 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import { findPhrenPath, getProjectDirs, EXEC_TIMEOUT_QUICK_MS, debugLog, isRecord, hookConfigPath, homeDir, readRootManifest, } from "./shared.js";
5
- import { buildIndex, detectProject, findFtsCacheForPath, listIndexedDocumentPaths, queryRows } from "./shared-index.js";
6
- import { mergeConfig, getWorkflowPolicy } from "./shared-governance.js";
7
- import { getMcpEnabledPreference, getHooksEnabledPreference } from "./init.js";
5
+ import { buildIndex, detectProject, findFtsCacheForPath, listIndexedDocumentPaths, queryRows } from "./shared/index.js";
6
+ import { mergeConfig, getWorkflowPolicy } from "./shared/governance.js";
7
+ import { getMcpEnabledPreference, getHooksEnabledPreference } from "./init/init.js";
8
8
  import { getTelemetrySummary } from "./telemetry.js";
9
9
  import { runGit as runGitShared, errorMessage } from "./utils.js";
10
- import { readRuntimeHealth, resolveTaskFilePath } from "./data-access.js";
10
+ import { logger } from "./logger.js";
11
+ import { readRuntimeHealth, resolveTaskFilePath } from "./data/access.js";
11
12
  import { resolveRuntimeProfile } from "./runtime-profile.js";
12
13
  import { renderPhrenArt } from "./phren-art.js";
13
- import { RESET, BOLD, DIM, GREEN, YELLOW, RED, CYAN } from "./shell-render.js";
14
+ import { RESET, BOLD, DIM, GREEN, YELLOW, RED, CYAN } from "./shell/render.js";
14
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
16
  function readPackageVersion() {
16
17
  try {
@@ -20,7 +21,7 @@ function readPackageVersion() {
20
21
  }
21
22
  catch (err) {
22
23
  if ((process.env.PHREN_DEBUG))
23
- process.stderr.write(`[phren] readPackageVersion: ${errorMessage(err)}\n`);
24
+ logger.debug("status", `readPackageVersion: ${errorMessage(err)}`);
24
25
  return "unknown";
25
26
  }
26
27
  }
@@ -91,7 +92,7 @@ export async function runStatus() {
91
92
  }
92
93
  catch (err) {
93
94
  if ((process.env.PHREN_DEBUG))
94
- process.stderr.write(`[phren] statusConfig: ${errorMessage(err)}\n`);
95
+ logger.debug("status", `statusConfig: ${errorMessage(err)}`);
95
96
  }
96
97
  }
97
98
  // Phren path and config
@@ -125,7 +126,7 @@ export async function runStatus() {
125
126
  }
126
127
  catch (err) {
127
128
  if ((process.env.PHREN_DEBUG))
128
- process.stderr.write(`[phren] statusWorkspaceMcp parse: ${errorMessage(err)}\n`);
129
+ logger.debug("status", `statusWorkspaceMcp parse: ${errorMessage(err)}`);
129
130
  }
130
131
  }
131
132
  }
@@ -143,7 +144,7 @@ export async function runStatus() {
143
144
  }
144
145
  catch (err) {
145
146
  if ((process.env.PHREN_DEBUG))
146
- process.stderr.write(`[phren] statusHooks settingsParse: ${errorMessage(err)}\n`);
147
+ logger.debug("status", `statusHooks settingsParse: ${errorMessage(err)}`);
147
148
  }
148
149
  }
149
150
  }
@@ -174,15 +175,15 @@ export async function runStatus() {
174
175
  }
175
176
  catch (err) {
176
177
  if ((process.env.PHREN_DEBUG))
177
- process.stderr.write(`[phren] statusFtsIndex: ${errorMessage(err)}\n`);
178
+ logger.debug("status", `statusFtsIndex: ${errorMessage(err)}`);
178
179
  }
179
180
  const ftsLabel = ftsIndexOk
180
181
  ? `${GREEN}ok${RESET} ${DIM}(${ftsIndexSize > 0 ? `${(ftsIndexSize / 1024).toFixed(0)} KB` : `${ftsDocCount ?? 0} docs`})${RESET}`
181
182
  : `${YELLOW}not built${RESET} ${DIM}(run a search to build)${RESET}`;
182
183
  console.log(` ${DIM}fts${RESET} ${ftsLabel}`);
183
184
  try {
184
- const { getOllamaUrl, checkOllamaAvailable, checkModelAvailable, getEmbeddingModel } = await import("./shared-ollama.js");
185
- const { getEmbeddingCache, formatEmbeddingCoverage } = await import("./shared-embedding-cache.js");
185
+ const { getOllamaUrl, checkOllamaAvailable, checkModelAvailable, getEmbeddingModel } = await import("./shared/ollama.js");
186
+ const { getEmbeddingCache, formatEmbeddingCoverage } = await import("./shared/embedding-cache.js");
186
187
  const ollamaUrl = getOllamaUrl();
187
188
  if (!ollamaUrl) {
188
189
  console.log(` ${DIM}semantic${RESET} ${DIM}disabled (optional)${RESET}`);
@@ -209,7 +210,7 @@ export async function runStatus() {
209
210
  }
210
211
  catch (err) {
211
212
  if ((process.env.PHREN_DEBUG))
212
- process.stderr.write(`[phren] statusSemantic: ${errorMessage(err)}\n`);
213
+ logger.debug("status", `statusSemantic: ${errorMessage(err)}`);
213
214
  }
214
215
  // Agent integration status
215
216
  function hasPhrenEntry(filePath) {
@@ -221,7 +222,7 @@ export async function runStatus() {
221
222
  }
222
223
  catch (err) {
223
224
  if ((process.env.PHREN_DEBUG))
224
- process.stderr.write(`[phren] hasPhrenEntry: ${errorMessage(err)}\n`);
225
+ logger.debug("status", `hasPhrenEntry: ${errorMessage(err)}`);
225
226
  return false;
226
227
  }
227
228
  }
@@ -1,8 +1,8 @@
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, phrenErr, phrenOk, PhrenError } from "./shared.js";
5
- import { errorMessage, resolveExecCommand } from "./utils.js";
4
+ import { EXEC_TIMEOUT_MS, phrenErr, phrenOk, PhrenError } from "../shared.js";
5
+ import { errorMessage, resolveExecCommand } from "../utils.js";
6
6
  const GITHUB_REPO_URL = /https:\/\/github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?:\/|\b|$)/;
7
7
  const GITHUB_ISSUE_URL = /https:\/\/github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)\/issues\/(\d+)(?:[?#][^\s]*)?$/;
8
8
  export function parseGithubIssueUrl(url) {
@@ -1,7 +1,8 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { isTaskFileName, readTasks } from "./data-tasks.js";
4
- import { STOP_WORDS, extractKeywords, errorMessage } from "./utils.js";
3
+ import { isTaskFileName, readTasks } from "../data/tasks.js";
4
+ import { STOP_WORDS, extractKeywords, errorMessage } from "../utils.js";
5
+ import { logger } from "../logger.js";
5
6
  const TEXT_EXTENSIONS = new Set([
6
7
  ".cjs",
7
8
  ".css",
@@ -141,8 +142,7 @@ function collectCorpus(root) {
141
142
  texts.push(fs.readFileSync(fullPath, "utf8").slice(0, MAX_TEXT_BYTES).toLowerCase());
142
143
  }
143
144
  catch (err) {
144
- if ((process.env.PHREN_DEBUG))
145
- process.stderr.write(`[phren] task hygiene read ${fullPath}: ${errorMessage(err)}\n`);
145
+ logger.debug("task-hygiene", `task hygiene read ${fullPath}: ${errorMessage(err)}`);
146
146
  }
147
147
  if (filesSeen >= MAX_FILES_PER_ROOT)
148
148
  break;
@@ -1,11 +1,11 @@
1
1
  import * as fs from "fs";
2
- import { addTask, completeTask, readTasks, resolveTaskItem, updateTask, } from "./data-access.js";
3
- import { parseGithubIssueUrl, resolveProjectGithubRepo } from "./tasks-github.js";
4
- import { getProactivityLevelForTask, shouldAutoCaptureTaskForLevel, hasExecutionIntent, hasDiscoveryIntent, hasSuppressTaskIntent, hasCodeChangeContext } from "./proactivity.js";
5
- import { getWorkflowPolicy } from "./shared-governance.js";
6
- import { debugLog, sessionMarker } from "./shared.js";
7
- import { errorMessage } from "./utils.js";
8
- import { incrementSessionTasksCompleted } from "./mcp-session.js";
2
+ import { addTask, completeTask, readTasks, resolveTaskItem, updateTask, } from "../data/access.js";
3
+ import { parseGithubIssueUrl, resolveProjectGithubRepo } from "./github.js";
4
+ import { getProactivityLevelForTask, shouldAutoCaptureTaskForLevel, hasExecutionIntent, hasDiscoveryIntent, hasSuppressTaskIntent, hasCodeChangeContext } from "../proactivity.js";
5
+ import { getWorkflowPolicy } from "../shared/governance.js";
6
+ import { debugLog, sessionMarker } from "../shared.js";
7
+ import { errorMessage } from "../utils.js";
8
+ import { incrementSessionTasksCompleted } from "../tools/session.js";
9
9
  const ACTION_PREFIX_RE = /^(?:please\s+|can you\s+|could you\s+|would you\s+|i want you to\s+|i want to\s+|let(?:'|’)s\s+|lets\s+|help me\s+)/i;
10
10
  const EXPLICIT_TASK_PREFIX_RE = /^(?:add(?:\s+(?:this|that|it))?\s+(?:to\s+(?:the\s+)?)?(?:task|todo(?:\s+list)?|task(?:\s+list)?)|add\s+(?:a\s+)?task|put(?:\s+(?:this|that|it))?\s+(?:in|on)\s+(?:the\s+)?(?:task|todo(?:\s+list)?|task(?:\s+list)?))\s*(?::|-|,)?\s*/i;
11
11
  const NON_ACTIONABLE_RE = /\b(brainstorm|idea|ideas|maybe|what if|should we|could we|would it make sense|question|explain|why is|how does)\b/i;