facult 2.3.1 → 2.5.0

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/src/paths.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { readdirSync, readFileSync, statSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { basename, dirname, join, resolve } from "node:path";
@@ -93,6 +94,34 @@ export function preferredGlobalFacultStateDir(
93
94
  return join(preferredGlobalAiRoot(home), ".facult");
94
95
  }
95
96
 
97
+ export function facultLocalStateRoot(home: string = defaultHomeDir()): string {
98
+ const override = process.env.FACULT_LOCAL_STATE_DIR?.trim();
99
+ if (override) {
100
+ return resolvePath(override, home);
101
+ }
102
+ if (process.platform === "darwin") {
103
+ return join(home, "Library", "Application Support", "fclt");
104
+ }
105
+ const xdg = process.env.XDG_STATE_HOME?.trim();
106
+ return xdg
107
+ ? join(resolvePath(xdg, home), "fclt")
108
+ : join(home, ".local", "state", "fclt");
109
+ }
110
+
111
+ export function facultLocalCacheRoot(home: string = defaultHomeDir()): string {
112
+ const override = process.env.FACULT_CACHE_DIR?.trim();
113
+ if (override) {
114
+ return resolvePath(override, home);
115
+ }
116
+ if (process.platform === "darwin") {
117
+ return join(home, "Library", "Caches", "fclt");
118
+ }
119
+ const xdg = process.env.XDG_CACHE_HOME?.trim();
120
+ return xdg
121
+ ? join(resolvePath(xdg, home), "fclt")
122
+ : join(home, ".cache", "fclt");
123
+ }
124
+
96
125
  export function legacyExternalFacultStateDir(
97
126
  home: string = defaultHomeDir()
98
127
  ): string {
@@ -186,6 +215,46 @@ export function facultStateDir(
186
215
  return join(resolvedRoot, ".facult");
187
216
  }
188
217
 
218
+ function machineStateProjectKey(
219
+ rootDir: string,
220
+ home: string = defaultHomeDir()
221
+ ): string {
222
+ const projectRoot = projectRootFromAiRoot(rootDir, home);
223
+ const labelSource = projectRoot ?? rootDir;
224
+ const label = basename(labelSource).trim().toLowerCase();
225
+ const slug = label.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
226
+ const digest = createHash("sha256")
227
+ .update(resolve(rootDir))
228
+ .digest("hex")
229
+ .slice(0, 12);
230
+ return `${slug || "project"}-${digest}`;
231
+ }
232
+
233
+ export function facultMachineStateDir(
234
+ home: string = defaultHomeDir(),
235
+ rootDir?: string
236
+ ): string {
237
+ const resolvedRoot = rootDir ?? facultRootDir(home);
238
+ const projectRoot = projectRootFromAiRoot(resolvedRoot, home);
239
+ return projectRoot
240
+ ? join(
241
+ facultLocalStateRoot(home),
242
+ "projects",
243
+ machineStateProjectKey(resolvedRoot, home)
244
+ )
245
+ : join(facultLocalStateRoot(home), "global");
246
+ }
247
+
248
+ export function facultInstallStatePath(
249
+ home: string = defaultHomeDir()
250
+ ): string {
251
+ return join(facultLocalStateRoot(home), "install.json");
252
+ }
253
+
254
+ export function facultRuntimeCacheDir(home: string = defaultHomeDir()): string {
255
+ return join(facultLocalCacheRoot(home), "runtime");
256
+ }
257
+
189
258
  export function projectRootFromAiRoot(
190
259
  rootDir: string,
191
260
  home: string = defaultHomeDir()
package/src/scan.ts CHANGED
@@ -601,6 +601,19 @@ function defaultSourceSpecs(
601
601
  "~/.codex/mcp.json",
602
602
  ],
603
603
  },
604
+ {
605
+ id: "factory",
606
+ name: "Factory",
607
+ candidates: ["~/.factory", "~/.factory/mcp.json"],
608
+ skillDirs: ["~/.factory/skills"],
609
+ configFiles: ["~/.factory/mcp.json"],
610
+ assets: [
611
+ {
612
+ kind: "agents-instructions",
613
+ patterns: ["~/.factory/AGENTS.md"],
614
+ },
615
+ ],
616
+ },
604
617
  {
605
618
  id: "claude",
606
619
  name: "Claude (CLI)",
@@ -784,6 +797,13 @@ function defaultSourceSpecs(
784
797
  },
785
798
  ],
786
799
  },
800
+ {
801
+ id: "factory-project",
802
+ name: "Factory (project)",
803
+ candidates: [join(cwd, ".factory")],
804
+ skillDirs: [join(cwd, ".factory", "skills")],
805
+ configFiles: [join(cwd, ".factory", "mcp.json")],
806
+ },
787
807
  ];
788
808
 
789
809
  if (includeGitHooks) {
@@ -1288,7 +1308,12 @@ async function buildFromRootResult(args: {
1288
1308
  }
1289
1309
  continue;
1290
1310
  }
1291
- if (name === ".codex" || name === ".agents" || name === ".clawdbot") {
1311
+ if (
1312
+ name === ".codex" ||
1313
+ name === ".agents" ||
1314
+ name === ".clawdbot" ||
1315
+ name === ".factory"
1316
+ ) {
1292
1317
  await scanToolDotDir(child);
1293
1318
  continue;
1294
1319
  }
@@ -2,6 +2,7 @@ import { mkdir, rename } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { basename, dirname, join, resolve, sep } from "node:path";
4
4
  import {
5
+ facultInstallStatePath,
5
6
  legacyExternalFacultStateDir,
6
7
  preferredGlobalFacultStateDir,
7
8
  } from "./paths";
@@ -88,6 +89,7 @@ export function parseSelfUpdateArgs(argv: string[]): ParsedArgs {
88
89
 
89
90
  async function loadInstallState(home: string): Promise<InstallState | null> {
90
91
  const paths = [
92
+ facultInstallStatePath(home),
91
93
  join(preferredGlobalFacultStateDir(home), "install.json"),
92
94
  join(legacyExternalFacultStateDir(home), "install.json"),
93
95
  ];
@@ -208,7 +210,7 @@ async function writeInstallState(args: {
208
210
  packageVersion?: string;
209
211
  binaryPath?: string;
210
212
  }) {
211
- const dir = preferredGlobalFacultStateDir(args.home);
213
+ const dir = dirname(facultInstallStatePath(args.home));
212
214
  await mkdir(dir, { recursive: true });
213
215
  const payload: InstallState = {
214
216
  version: 1,
@@ -219,7 +221,7 @@ async function writeInstallState(args: {
219
221
  installedAt: new Date().toISOString(),
220
222
  };
221
223
  await Bun.write(
222
- join(dir, "install.json"),
224
+ facultInstallStatePath(args.home),
223
225
  `${JSON.stringify(payload, null, 2)}\n`
224
226
  );
225
227
  }