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/README.md +30 -10
- package/bin/fclt.cjs +86 -3
- package/package.json +1 -1
- package/src/adapters/factory.ts +228 -0
- package/src/adapters/index.ts +2 -0
- package/src/adapters/types.ts +22 -0
- package/src/autosync.ts +192 -8
- package/src/index-builder.ts +12 -3
- package/src/manage.ts +487 -13
- package/src/paths.ts +69 -0
- package/src/scan.ts +26 -1
- package/src/self-update.ts +4 -2
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 (
|
|
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
|
}
|
package/src/self-update.ts
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
224
|
+
facultInstallStatePath(args.home),
|
|
223
225
|
`${JSON.stringify(payload, null, 2)}\n`
|
|
224
226
|
);
|
|
225
227
|
}
|