@gitgov/core 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/dist/src/index.js CHANGED
@@ -5,7 +5,8 @@ import { promises, existsSync, constants } from 'fs';
5
5
  import * as yaml from 'js-yaml';
6
6
  import { generateKeyPair, createHash, sign, verify } from 'crypto';
7
7
  import { promisify } from 'util';
8
- import * as path from 'path';
8
+ import * as pathUtils from 'path';
9
+ import { createRequire } from 'module';
9
10
  import { fileURLToPath } from 'url';
10
11
  import { EventEmitter } from 'events';
11
12
 
@@ -2994,8 +2995,8 @@ var ConfigManager = class _ConfigManager {
2994
2995
  configPath;
2995
2996
  sessionPath;
2996
2997
  constructor(projectRootPath = _ConfigManager.findProjectRoot() || process.cwd()) {
2997
- this.configPath = path.join(projectRootPath, ".gitgov", "config.json");
2998
- this.sessionPath = path.join(projectRootPath, ".gitgov", ".session.json");
2998
+ this.configPath = pathUtils.join(projectRootPath, ".gitgov", "config.json");
2999
+ this.sessionPath = pathUtils.join(projectRootPath, ".gitgov", ".session.json");
2999
3000
  }
3000
3001
  /**
3001
3002
  * Load GitGovernance configuration
@@ -3085,14 +3086,14 @@ var ConfigManager = class _ConfigManager {
3085
3086
  }
3086
3087
  lastSearchPath = startPath;
3087
3088
  let currentPath = startPath;
3088
- while (currentPath !== path.parse(currentPath).root) {
3089
- if (existsSync(path.join(currentPath, ".git"))) {
3089
+ while (currentPath !== pathUtils.parse(currentPath).root) {
3090
+ if (existsSync(pathUtils.join(currentPath, ".git"))) {
3090
3091
  projectRoot = currentPath;
3091
3092
  return projectRoot;
3092
3093
  }
3093
- currentPath = path.dirname(currentPath);
3094
+ currentPath = pathUtils.dirname(currentPath);
3094
3095
  }
3095
- if (existsSync(path.join(currentPath, ".git"))) {
3096
+ if (existsSync(pathUtils.join(currentPath, ".git"))) {
3096
3097
  projectRoot = currentPath;
3097
3098
  return projectRoot;
3098
3099
  }
@@ -3106,23 +3107,23 @@ var ConfigManager = class _ConfigManager {
3106
3107
  */
3107
3108
  static findGitgovRoot(startPath = process.cwd()) {
3108
3109
  let currentPath = startPath;
3109
- while (currentPath !== path.parse(currentPath).root) {
3110
- if (existsSync(path.join(currentPath, ".gitgov"))) {
3110
+ while (currentPath !== pathUtils.parse(currentPath).root) {
3111
+ if (existsSync(pathUtils.join(currentPath, ".gitgov"))) {
3111
3112
  return currentPath;
3112
3113
  }
3113
- currentPath = path.dirname(currentPath);
3114
+ currentPath = pathUtils.dirname(currentPath);
3114
3115
  }
3115
- if (existsSync(path.join(currentPath, ".gitgov"))) {
3116
+ if (existsSync(pathUtils.join(currentPath, ".gitgov"))) {
3116
3117
  return currentPath;
3117
3118
  }
3118
3119
  currentPath = startPath;
3119
- while (currentPath !== path.parse(currentPath).root) {
3120
- if (existsSync(path.join(currentPath, ".git"))) {
3120
+ while (currentPath !== pathUtils.parse(currentPath).root) {
3121
+ if (existsSync(pathUtils.join(currentPath, ".git"))) {
3121
3122
  return currentPath;
3122
3123
  }
3123
- currentPath = path.dirname(currentPath);
3124
+ currentPath = pathUtils.dirname(currentPath);
3124
3125
  }
3125
- if (existsSync(path.join(currentPath, ".git"))) {
3126
+ if (existsSync(pathUtils.join(currentPath, ".git"))) {
3126
3127
  return currentPath;
3127
3128
  }
3128
3129
  return null;
@@ -3135,7 +3136,7 @@ var ConfigManager = class _ConfigManager {
3135
3136
  if (!root) {
3136
3137
  throw new Error("Could not find project root. Make sure you are inside a GitGovernance repository.");
3137
3138
  }
3138
- return path.join(root, ".gitgov");
3139
+ return pathUtils.join(root, ".gitgov");
3139
3140
  }
3140
3141
  /**
3141
3142
  * Checks if current directory is a GitGovernance project
@@ -3164,12 +3165,12 @@ var RecordStore = class {
3164
3165
  throw new Error("Could not find project root. RecordStore requires a valid project root.");
3165
3166
  }
3166
3167
  this.recordType = recordType;
3167
- this.recordsDir = path.join(foundRoot, ".gitgov", this.recordType);
3168
+ this.recordsDir = pathUtils.join(foundRoot, ".gitgov", this.recordType);
3168
3169
  this.fs = fsDeps;
3169
3170
  }
3170
3171
  getRecordPath(recordId) {
3171
3172
  const safeId = recordId.replace(/:/g, "_");
3172
- return path.join(this.recordsDir, `${safeId}.json`);
3173
+ return pathUtils.join(this.recordsDir, `${safeId}.json`);
3173
3174
  }
3174
3175
  async ensureDirExists() {
3175
3176
  await this.fs.mkdir(this.recordsDir, { recursive: true });
@@ -6270,7 +6271,7 @@ var FileIndexerAdapter = class {
6270
6271
  * Writes cache data to file (Phase 1: JSON)
6271
6272
  */
6272
6273
  async writeCacheFile(indexData) {
6273
- const cacheDir = path.dirname(this.cachePath);
6274
+ const cacheDir = pathUtils.dirname(this.cachePath);
6274
6275
  await promises.mkdir(cacheDir, { recursive: true });
6275
6276
  const jsonContent = JSON.stringify(indexData, null, 2);
6276
6277
  await promises.writeFile(this.cachePath, jsonContent, "utf-8");
@@ -6424,10 +6425,10 @@ var FileIndexerAdapter = class {
6424
6425
  let recentActivity = "Task created";
6425
6426
  try {
6426
6427
  let projectRoot2 = process.cwd();
6427
- while (!fs.existsSync(path.join(projectRoot2, ".gitgov")) && projectRoot2 !== "/") {
6428
- projectRoot2 = path.dirname(projectRoot2);
6428
+ while (!fs.existsSync(pathUtils.join(projectRoot2, ".gitgov")) && projectRoot2 !== "/") {
6429
+ projectRoot2 = pathUtils.dirname(projectRoot2);
6429
6430
  }
6430
- const taskFilePath = path.join(projectRoot2, ".gitgov", "tasks", `${task.id}.json`);
6431
+ const taskFilePath = pathUtils.join(projectRoot2, ".gitgov", "tasks", `${task.id}.json`);
6431
6432
  const stats = await promises.stat(taskFilePath);
6432
6433
  const fileModTime = stats.mtime.getTime();
6433
6434
  const creationTime = this.getTimestampFromId(task.id) * 1e3;
@@ -6529,8 +6530,6 @@ var project_adapter_exports = {};
6529
6530
  __export(project_adapter_exports, {
6530
6531
  ProjectAdapter: () => ProjectAdapter
6531
6532
  });
6532
- var __filename = fileURLToPath(import.meta.url);
6533
- var __dirname = path.dirname(__filename);
6534
6533
  var ProjectAdapter = class {
6535
6534
  identityAdapter;
6536
6535
  backlogAdapter;
@@ -6553,7 +6552,7 @@ var ProjectAdapter = class {
6553
6552
  throw new Error(`Environment validation failed: ${envValidation.warnings.join(", ")}`);
6554
6553
  }
6555
6554
  const projectRoot2 = process.env["GITGOV_ORIGINAL_DIR"] || process.cwd();
6556
- const gitgovPath = path.join(projectRoot2, ".gitgov");
6555
+ const gitgovPath = pathUtils.join(projectRoot2, ".gitgov");
6557
6556
  await this.createDirectoryStructure(gitgovPath);
6558
6557
  await this.copyAgentPrompt(gitgovPath);
6559
6558
  const actor = await this.identityAdapter.createActor(
@@ -6617,7 +6616,7 @@ var ProjectAdapter = class {
6617
6616
  actor: {
6618
6617
  id: actor.id,
6619
6618
  displayName: actor.displayName,
6620
- publicKeyPath: path.join(gitgovPath, "actors", `${actor.id}.json`)
6619
+ publicKeyPath: pathUtils.join(gitgovPath, "actors", `${actor.id}.json`)
6621
6620
  },
6622
6621
  template: templateResult ? {
6623
6622
  processed: true,
@@ -6644,7 +6643,7 @@ var ProjectAdapter = class {
6644
6643
  const warnings = [];
6645
6644
  const suggestions = [];
6646
6645
  try {
6647
- const gitPath = path.join(targetPath, ".git");
6646
+ const gitPath = pathUtils.join(targetPath, ".git");
6648
6647
  const isGitRepo = existsSync(gitPath);
6649
6648
  if (!isGitRepo) {
6650
6649
  warnings.push(`Not a Git repository in directory: ${targetPath}`);
@@ -6652,7 +6651,7 @@ var ProjectAdapter = class {
6652
6651
  }
6653
6652
  let hasWritePermissions = false;
6654
6653
  try {
6655
- const testFile = path.join(targetPath, ".gitgov-test");
6654
+ const testFile = pathUtils.join(targetPath, ".gitgov-test");
6656
6655
  await promises.writeFile(testFile, "test");
6657
6656
  await promises.unlink(testFile);
6658
6657
  hasWritePermissions = true;
@@ -6660,7 +6659,7 @@ var ProjectAdapter = class {
6660
6659
  warnings.push("No write permissions in target directory");
6661
6660
  suggestions.push("Ensure you have write permissions in the target directory");
6662
6661
  }
6663
- const gitgovPath = path.join(targetPath, ".gitgov");
6662
+ const gitgovPath = pathUtils.join(targetPath, ".gitgov");
6664
6663
  let isAlreadyInitialized = false;
6665
6664
  try {
6666
6665
  await promises.access(gitgovPath);
@@ -6755,7 +6754,7 @@ var ProjectAdapter = class {
6755
6754
  async rollbackPartialSetup(setupId) {
6756
6755
  try {
6757
6756
  const projectRoot2 = process.env["GITGOV_ORIGINAL_DIR"] || process.cwd();
6758
- const gitgovPath = path.join(projectRoot2, ".gitgov");
6757
+ const gitgovPath = pathUtils.join(projectRoot2, ".gitgov");
6759
6758
  try {
6760
6759
  await promises.access(gitgovPath);
6761
6760
  await promises.rm(gitgovPath, { recursive: true, force: true });
@@ -6819,19 +6818,50 @@ var ProjectAdapter = class {
6819
6818
  ];
6820
6819
  await promises.mkdir(gitgovPath, { recursive: true });
6821
6820
  for (const dir of directories) {
6822
- await promises.mkdir(path.join(gitgovPath, dir), { recursive: true });
6821
+ await promises.mkdir(pathUtils.join(gitgovPath, dir), { recursive: true });
6823
6822
  }
6824
6823
  }
6825
6824
  async copyAgentPrompt(gitgovPath) {
6826
- const targetPrompt = path.join(gitgovPath, "gitgov");
6827
- const potentialSources = [
6828
- path.join(ConfigManager.findProjectRoot() || process.cwd(), "docs/gitgov_agent_prompt.md"),
6829
- path.join(__dirname, "../../prompts/gitgov_agent_prompt.md")
6830
- ];
6831
- for (const sourcePrompt of potentialSources) {
6825
+ function getImportMetaUrl() {
6826
+ try {
6827
+ const getUrl = new Function("return import.meta.url");
6828
+ return getUrl();
6829
+ } catch {
6830
+ return null;
6831
+ }
6832
+ }
6833
+ const targetPrompt = pathUtils.join(gitgovPath, "gitgov");
6834
+ const potentialSources = [];
6835
+ potentialSources.push(
6836
+ pathUtils.join(process.cwd(), "prompts/gitgov_agent_prompt.md")
6837
+ );
6838
+ try {
6839
+ const metaUrl = getImportMetaUrl();
6840
+ if (metaUrl) {
6841
+ const require2 = createRequire(metaUrl);
6842
+ const pkgJsonPath = require2.resolve("@gitgov/core/package.json");
6843
+ const pkgRoot = pathUtils.dirname(pkgJsonPath);
6844
+ potentialSources.push(
6845
+ pathUtils.join(pkgRoot, "prompts/gitgov_agent_prompt.md")
6846
+ );
6847
+ }
6848
+ } catch {
6849
+ }
6850
+ try {
6851
+ const metaUrl = getImportMetaUrl();
6852
+ if (metaUrl) {
6853
+ const __filename = fileURLToPath(metaUrl);
6854
+ const __dirname = pathUtils.dirname(__filename);
6855
+ potentialSources.push(
6856
+ pathUtils.resolve(__dirname, "../../prompts/gitgov_agent_prompt.md")
6857
+ );
6858
+ }
6859
+ } catch {
6860
+ }
6861
+ for (const source of potentialSources) {
6832
6862
  try {
6833
- await promises.access(sourcePrompt);
6834
- await promises.copyFile(sourcePrompt, targetPrompt);
6863
+ await promises.access(source);
6864
+ await promises.copyFile(source, targetPrompt);
6835
6865
  console.log(`\u{1F4CB} @gitgov agent prompt copied to .gitgov/gitgov`);
6836
6866
  return;
6837
6867
  } catch {
@@ -6844,11 +6874,11 @@ var ProjectAdapter = class {
6844
6874
  return name.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-");
6845
6875
  }
6846
6876
  async persistConfiguration(config, gitgovPath) {
6847
- const configPath = path.join(gitgovPath, "config.json");
6877
+ const configPath = pathUtils.join(gitgovPath, "config.json");
6848
6878
  await promises.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
6849
6879
  }
6850
6880
  async initializeSession(actorId, gitgovPath) {
6851
- const sessionPath = path.join(gitgovPath, ".session.json");
6881
+ const sessionPath = pathUtils.join(gitgovPath, ".session.json");
6852
6882
  const session = {
6853
6883
  lastSession: {
6854
6884
  actorId,
@@ -6863,7 +6893,7 @@ var ProjectAdapter = class {
6863
6893
  await promises.writeFile(sessionPath, JSON.stringify(session, null, 2), "utf-8");
6864
6894
  }
6865
6895
  async setupGitIntegration(projectRoot2) {
6866
- const gitignorePath = path.join(projectRoot2, ".gitignore");
6896
+ const gitignorePath = pathUtils.join(projectRoot2, ".gitignore");
6867
6897
  const gitignoreContent = `
6868
6898
  # GitGovernance
6869
6899
  .gitgov/.session.json
@@ -8087,7 +8117,7 @@ var EventBus = class {
8087
8117
  if (this.pendingHandlers.size > 0) {
8088
8118
  await Promise.race([
8089
8119
  Promise.all(Array.from(this.pendingHandlers)),
8090
- new Promise((resolve) => setTimeout(resolve, 10))
8120
+ new Promise((resolve2) => setTimeout(resolve2, 10))
8091
8121
  // Re-check every 10ms
8092
8122
  ]);
8093
8123
  }
@@ -8976,14 +9006,14 @@ var DiagramGenerator = class {
8976
9006
  * Loads all cycle records from the filesystem
8977
9007
  */
8978
9008
  async loadCycleRecords(gitgovPath) {
8979
- const cyclesDir = path.join(gitgovPath, "cycles");
9009
+ const cyclesDir = pathUtils.join(gitgovPath, "cycles");
8980
9010
  try {
8981
9011
  const files = await promises.readdir(cyclesDir);
8982
9012
  const jsonFiles = files.filter((file) => file.endsWith(".json"));
8983
9013
  const cycles = [];
8984
9014
  for (const file of jsonFiles) {
8985
9015
  try {
8986
- const filePath = path.join(cyclesDir, file);
9016
+ const filePath = pathUtils.join(cyclesDir, file);
8987
9017
  const content = await promises.readFile(filePath, "utf-8");
8988
9018
  const record = JSON.parse(content);
8989
9019
  if (record.payload && record.payload.id) {
@@ -9012,14 +9042,14 @@ var DiagramGenerator = class {
9012
9042
  * Loads all task records from the filesystem
9013
9043
  */
9014
9044
  async loadTaskRecords(gitgovPath) {
9015
- const tasksDir = path.join(gitgovPath, "tasks");
9045
+ const tasksDir = pathUtils.join(gitgovPath, "tasks");
9016
9046
  try {
9017
9047
  const files = await promises.readdir(tasksDir);
9018
9048
  const jsonFiles = files.filter((file) => file.endsWith(".json"));
9019
9049
  const tasks = [];
9020
9050
  for (const file of jsonFiles) {
9021
9051
  try {
9022
- const filePath = path.join(tasksDir, file);
9052
+ const filePath = pathUtils.join(tasksDir, file);
9023
9053
  const content = await promises.readFile(filePath, "utf-8");
9024
9054
  const record = JSON.parse(content);
9025
9055
  if (record.payload && record.payload.id) {