facult 1.3.0 → 2.0.1
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 +186 -176
- package/bin/facult.cjs +1 -268
- package/bin/fclt.cjs +264 -0
- package/package.json +6 -3
- package/src/ai.ts +23 -23
- package/src/audit/index.ts +11 -11
- package/src/audit/tui.ts +6 -6
- package/src/autosync.ts +11 -8
- package/src/consolidate.ts +3 -3
- package/src/doctor.ts +5 -5
- package/src/enable-disable.ts +7 -7
- package/src/graph-query.ts +1 -1
- package/src/index-builder.ts +2 -2
- package/src/index.ts +52 -52
- package/src/manage.ts +9 -9
- package/src/migrate.ts +3 -3
- package/src/paths.ts +4 -4
- package/src/query.ts +4 -4
- package/src/remote-source-policy.ts +8 -8
- package/src/remote.ts +25 -25
- package/src/scan.ts +8 -8
- package/src/schema.ts +1 -1
- package/src/self-update.ts +40 -16
- package/src/snippets-cli.ts +6 -6
- package/src/trust.ts +8 -8
- package/src/tui.ts +1 -1
package/src/audit/tui.ts
CHANGED
|
@@ -197,17 +197,17 @@ function viewFindingDetails(r: AuditItemResult) {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
function printHelp() {
|
|
200
|
-
console.log(`
|
|
200
|
+
console.log(`fclt audit tui — interactive security audit + quarantine
|
|
201
201
|
|
|
202
202
|
Usage:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
fclt audit tui
|
|
204
|
+
fclt audit tui --from <path> [--from <path> ...]
|
|
205
|
+
fclt audit tui --no-config-from
|
|
206
206
|
|
|
207
207
|
Notes:
|
|
208
208
|
- This is an interactive wizard (TTY required).
|
|
209
209
|
- Quarantine will move/copy files into ~/.ai/.facult/quarantine/<timestamp>/ and write a manifest.json.
|
|
210
|
-
- For non-interactive runs, use:
|
|
210
|
+
- For non-interactive runs, use: fclt audit --non-interactive ...
|
|
211
211
|
`);
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -223,7 +223,7 @@ export async function auditTuiCommand(argv: string[]) {
|
|
|
223
223
|
const cfg = noConfigFrom ? null : readFacultConfig();
|
|
224
224
|
const cfgRoots = cfg?.scanFrom ?? [];
|
|
225
225
|
|
|
226
|
-
intro("
|
|
226
|
+
intro("fclt audit");
|
|
227
227
|
|
|
228
228
|
if (cfgRoots.length) {
|
|
229
229
|
note(
|
package/src/autosync.ts
CHANGED
|
@@ -90,7 +90,7 @@ function nowIso(): string {
|
|
|
90
90
|
|
|
91
91
|
function logAutosyncError(context: string, error: unknown) {
|
|
92
92
|
const detail = error instanceof Error ? error.message : String(error);
|
|
93
|
-
console.error(`
|
|
93
|
+
console.error(`fclt autosync: ${context}: ${detail}`);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
function runDetached(context: string, promise: Promise<void>) {
|
|
@@ -226,7 +226,10 @@ export function resolveAutosyncInvocation(
|
|
|
226
226
|
return [exec, "run", script];
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
if (
|
|
229
|
+
if (
|
|
230
|
+
basename(exec).startsWith("facult") ||
|
|
231
|
+
basename(exec).startsWith("fclt")
|
|
232
|
+
) {
|
|
230
233
|
return [exec];
|
|
231
234
|
}
|
|
232
235
|
|
|
@@ -791,14 +794,14 @@ function parseAutosyncPositionals(
|
|
|
791
794
|
}
|
|
792
795
|
|
|
793
796
|
function autosyncHelp(): string {
|
|
794
|
-
return `
|
|
797
|
+
return `fclt autosync — background autosync for managed tools
|
|
795
798
|
|
|
796
799
|
Usage:
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
800
|
+
fclt autosync install [tool] [--git-remote <name>] [--git-branch <name>] [--git-interval-minutes <n>] [--git-disable]
|
|
801
|
+
fclt autosync uninstall [tool]
|
|
802
|
+
fclt autosync status [tool]
|
|
803
|
+
fclt autosync restart [tool]
|
|
804
|
+
fclt autosync run [tool] [--service <name>] [--once]
|
|
802
805
|
|
|
803
806
|
Options:
|
|
804
807
|
--git-remote <name> Git remote for canonical repo sync (default: origin)
|
package/src/consolidate.ts
CHANGED
|
@@ -1573,10 +1573,10 @@ export async function consolidateCommand(
|
|
|
1573
1573
|
ctx: { homeDir?: string; rootDir?: string; cwd?: string } = {}
|
|
1574
1574
|
) {
|
|
1575
1575
|
if (argv.includes("--help") || argv.includes("-h") || argv[0] === "help") {
|
|
1576
|
-
console.log(`
|
|
1576
|
+
console.log(`fclt consolidate — deduplicate and copy skills + MCP configs into the canonical store
|
|
1577
1577
|
|
|
1578
1578
|
Usage:
|
|
1579
|
-
|
|
1579
|
+
fclt consolidate [--force] [--auto <keep-newest|keep-current|keep-incoming>] [scan options]
|
|
1580
1580
|
|
|
1581
1581
|
Options:
|
|
1582
1582
|
--force Re-copy items already consolidated
|
|
@@ -1597,7 +1597,7 @@ Options:
|
|
|
1597
1597
|
const scanOptions = parseConsolidateScanOptions(argv);
|
|
1598
1598
|
const home = ctx.homeDir ?? homedir();
|
|
1599
1599
|
const rootDir = ctx.rootDir ?? facultRootDir(home);
|
|
1600
|
-
intro("
|
|
1600
|
+
intro("fclt consolidate");
|
|
1601
1601
|
|
|
1602
1602
|
const res = await scan([], {
|
|
1603
1603
|
...scanOptions,
|
package/src/doctor.ts
CHANGED
|
@@ -224,10 +224,10 @@ async function repairLegacyState(args: {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
function printHelp() {
|
|
227
|
-
console.log(`
|
|
227
|
+
console.log(`fclt doctor — inspect and repair local fclt state
|
|
228
228
|
|
|
229
229
|
Usage:
|
|
230
|
-
|
|
230
|
+
fclt doctor [--repair] [--root <path> | --global | --project]
|
|
231
231
|
|
|
232
232
|
Options:
|
|
233
233
|
--repair Reconcile legacy Facult state, canonical root config, AI index/graph, and autosync service config when needed
|
|
@@ -284,7 +284,7 @@ export async function doctorCommand(argv: string[]) {
|
|
|
284
284
|
console.log(`Legacy root index: ${legacy}`);
|
|
285
285
|
|
|
286
286
|
if (rootConfigRepaired) {
|
|
287
|
-
console.log(`Updated
|
|
287
|
+
console.log(`Updated fclt root config to ${join(home, ".ai")}`);
|
|
288
288
|
}
|
|
289
289
|
if (stateRepaired) {
|
|
290
290
|
console.log(
|
|
@@ -327,14 +327,14 @@ export async function doctorCommand(argv: string[]) {
|
|
|
327
327
|
|
|
328
328
|
if (result.source === "legacy") {
|
|
329
329
|
console.log(
|
|
330
|
-
"Legacy root index detected. Run `
|
|
330
|
+
"Legacy root index detected. Run `fclt doctor --repair` to reconcile it."
|
|
331
331
|
);
|
|
332
332
|
process.exitCode = 1;
|
|
333
333
|
return;
|
|
334
334
|
}
|
|
335
335
|
|
|
336
336
|
console.log(
|
|
337
|
-
"Generated AI index is missing. Run `
|
|
337
|
+
"Generated AI index is missing. Run `fclt doctor --repair` or `fclt index`."
|
|
338
338
|
);
|
|
339
339
|
process.exitCode = 1;
|
|
340
340
|
} catch (err) {
|
package/src/enable-disable.ts
CHANGED
|
@@ -71,7 +71,7 @@ async function loadIndex(homeDir: string): Promise<FacultIndex> {
|
|
|
71
71
|
});
|
|
72
72
|
const file = Bun.file(indexPath);
|
|
73
73
|
if (!(await file.exists())) {
|
|
74
|
-
throw new Error(`Index not found at ${indexPath}. Run "
|
|
74
|
+
throw new Error(`Index not found at ${indexPath}. Run "fclt index".`);
|
|
75
75
|
}
|
|
76
76
|
const raw = await file.text();
|
|
77
77
|
return JSON.parse(raw) as FacultIndex;
|
|
@@ -310,11 +310,11 @@ function parseEnableDisableArgs(argv: string[]): {
|
|
|
310
310
|
|
|
311
311
|
export async function enableCommand(argv: string[]) {
|
|
312
312
|
if (argv.includes("--help") || argv.includes("-h") || argv[0] === "help") {
|
|
313
|
-
console.log(`
|
|
313
|
+
console.log(`fclt enable — enable skills or MCP servers for tools
|
|
314
314
|
|
|
315
315
|
Usage:
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
fclt enable <name> [moreNames...] [--for <tool1,tool2,...>]
|
|
317
|
+
fclt enable mcp:<name> [--for <tools>]
|
|
318
318
|
|
|
319
319
|
Options:
|
|
320
320
|
--for Comma-separated list of tools (defaults to all managed tools)
|
|
@@ -333,11 +333,11 @@ Options:
|
|
|
333
333
|
|
|
334
334
|
export async function disableCommand(argv: string[]) {
|
|
335
335
|
if (argv.includes("--help") || argv.includes("-h") || argv[0] === "help") {
|
|
336
|
-
console.log(`
|
|
336
|
+
console.log(`fclt disable — disable skills or MCP servers for tools
|
|
337
337
|
|
|
338
338
|
Usage:
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
fclt disable <name> [moreNames...] [--for <tool1,tool2,...>]
|
|
340
|
+
fclt disable mcp:<name> [--for <tools>]
|
|
341
341
|
|
|
342
342
|
Options:
|
|
343
343
|
--for Comma-separated list of tools (defaults to all managed tools)
|
package/src/graph-query.ts
CHANGED
|
@@ -90,7 +90,7 @@ export async function loadGraph(opts?: {
|
|
|
90
90
|
const graphPath = facultAiGraphPath(homeDir, opts?.rootDir);
|
|
91
91
|
const file = Bun.file(graphPath);
|
|
92
92
|
if (!(await file.exists())) {
|
|
93
|
-
throw new Error(`Graph not found at ${graphPath}. Run "
|
|
93
|
+
throw new Error(`Graph not found at ${graphPath}. Run "fclt index".`);
|
|
94
94
|
}
|
|
95
95
|
return JSON.parse(await file.text()) as FacultGraph;
|
|
96
96
|
}
|
package/src/index-builder.ts
CHANGED
|
@@ -1599,10 +1599,10 @@ export async function indexCommand(argv: string[]) {
|
|
|
1599
1599
|
parsed.argv.includes("-h") ||
|
|
1600
1600
|
parsed.argv[0] === "help"
|
|
1601
1601
|
) {
|
|
1602
|
-
console.log(`
|
|
1602
|
+
console.log(`fclt index — rebuild the generated index for the canonical store
|
|
1603
1603
|
|
|
1604
1604
|
Usage:
|
|
1605
|
-
|
|
1605
|
+
fclt index [--force] [--root PATH|--global|--project]
|
|
1606
1606
|
|
|
1607
1607
|
Options:
|
|
1608
1608
|
--force Rebuild index from scratch (ignore existing metadata)
|
package/src/index.ts
CHANGED
|
@@ -96,50 +96,50 @@ interface GraphCommandOptions {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
function printHelp() {
|
|
99
|
-
console.log(`
|
|
99
|
+
console.log(`fclt — manage canonical AI capabilities, sync surfaces, and evolution state
|
|
100
100
|
|
|
101
101
|
Usage:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
102
|
+
fclt scan [--json] [--show-duplicates] [--tui] [--from <path>]
|
|
103
|
+
fclt audit [--from <path>]
|
|
104
|
+
fclt audit --non-interactive [name|mcp:<name>] [--severity <level>] [--rules <path>] [--from <path>] [--json]
|
|
105
|
+
fclt audit --non-interactive [name|mcp:<name>] --with <claude|codex> [--from <path>] [--max-items <n|all>] [--json]
|
|
106
|
+
fclt migrate [--from <path>] [--dry-run] [--move] [--write-config]
|
|
107
|
+
fclt doctor [--repair]
|
|
108
|
+
fclt consolidate [--force] [--auto <mode>] [scan options]
|
|
109
|
+
fclt index [--force]
|
|
110
|
+
fclt list [skills|mcp|agents|snippets|instructions] [--enabled-for TOOL] [--untrusted] [--flagged] [--pending] [--json]
|
|
111
|
+
fclt show <name>
|
|
112
|
+
fclt show mcp:<name> [--show-secrets]
|
|
113
|
+
fclt show instruction:<name>
|
|
114
|
+
fclt find <query> [--json]
|
|
115
|
+
fclt graph <show|deps|dependents> <asset> [--json]
|
|
116
|
+
fclt ai <writeback|evolve> [args...]
|
|
117
|
+
fclt adapters
|
|
118
|
+
fclt trust <name> [moreNames...]
|
|
119
|
+
fclt untrust <name> [moreNames...]
|
|
120
|
+
fclt manage <tool>
|
|
121
|
+
fclt unmanage <tool>
|
|
122
|
+
fclt managed
|
|
123
|
+
fclt enable <name> [moreNames...] [--for <tools>]
|
|
124
|
+
fclt disable <name> [moreNames...] [--for <tools>]
|
|
125
|
+
fclt sync [tool] [--dry-run]
|
|
126
|
+
fclt autosync <cmd> [args...]
|
|
127
|
+
fclt search <query> [--index <name>] [--limit <n>]
|
|
128
|
+
fclt install <index:item> [--as <name>] [--dry-run] [--force] [--strict-source-trust]
|
|
129
|
+
fclt update [--apply] [--strict-source-trust]
|
|
130
|
+
fclt update --self [--version <x.y.z|latest>] [--dry-run]
|
|
131
|
+
fclt self-update [--version <x.y.z|latest>] [--dry-run]
|
|
132
|
+
fclt verify-source <name> [--json]
|
|
133
|
+
fclt sources <cmd> [args...]
|
|
134
|
+
fclt templates <cmd> [args...]
|
|
135
|
+
fclt snippets <cmd> [args...]
|
|
136
|
+
fclt --show-duplicates
|
|
137
137
|
|
|
138
138
|
Commands:
|
|
139
139
|
scan Scan common config locations (Cursor, Claude, Claude Desktop, etc.)
|
|
140
140
|
audit Security audits (interactive by default; use --non-interactive for scripts)
|
|
141
141
|
migrate Copy/move a legacy canonical store to the current canonical root
|
|
142
|
-
doctor Inspect and repair local
|
|
142
|
+
doctor Inspect and repair local fclt state
|
|
143
143
|
consolidate Deduplicate and copy skills + MCP configs (interactive or --auto)
|
|
144
144
|
index Build a queryable index from the canonical store (see FACULT_ROOT_DIR)
|
|
145
145
|
list List indexed skills, MCP servers, agents, snippets, or instructions
|
|
@@ -160,7 +160,7 @@ Commands:
|
|
|
160
160
|
search Search remote indices (builtin + provider aliases + configured)
|
|
161
161
|
install Install an item from a remote index
|
|
162
162
|
update Check/apply updates for remotely installed items
|
|
163
|
-
self-update Update
|
|
163
|
+
self-update Update fclt itself based on install method
|
|
164
164
|
verify-source Verify source trust and manifest integrity/signature status
|
|
165
165
|
sources Manage source trust policy for remote indices
|
|
166
166
|
templates Scaffold DX-first templates (skills/instructions/MCP/snippets)
|
|
@@ -203,10 +203,10 @@ Options:
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
function printListHelp() {
|
|
206
|
-
console.log(`
|
|
206
|
+
console.log(`fclt list — list indexed entries from the canonical store
|
|
207
207
|
|
|
208
208
|
Usage:
|
|
209
|
-
|
|
209
|
+
fclt list [skills|mcp|agents|snippets|instructions] [options]
|
|
210
210
|
|
|
211
211
|
Options:
|
|
212
212
|
--enabled-for TOOL Only include entries enabled for a tool
|
|
@@ -223,12 +223,12 @@ Options:
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
function printShowHelp() {
|
|
226
|
-
console.log(`
|
|
226
|
+
console.log(`fclt show — show a single indexed entry (and file contents)
|
|
227
227
|
|
|
228
228
|
Usage:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
fclt show <name>
|
|
230
|
+
fclt show mcp:<name> [--show-secrets]
|
|
231
|
+
fclt show instruction:<name>
|
|
232
232
|
|
|
233
233
|
Options:
|
|
234
234
|
--show-secrets (mcp) Print raw secret values (unsafe)
|
|
@@ -241,10 +241,10 @@ Options:
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
function printFindHelp() {
|
|
244
|
-
console.log(`
|
|
244
|
+
console.log(`fclt find — search local indexed capabilities across asset types
|
|
245
245
|
|
|
246
246
|
Usage:
|
|
247
|
-
|
|
247
|
+
fclt find <query> [--json]
|
|
248
248
|
|
|
249
249
|
Options:
|
|
250
250
|
--root PATH Select a canonical .ai root explicitly
|
|
@@ -257,12 +257,12 @@ Options:
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
function printGraphHelp() {
|
|
260
|
-
console.log(`
|
|
260
|
+
console.log(`fclt graph — inspect explicit capability graph nodes and relations
|
|
261
261
|
|
|
262
262
|
Usage:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
fclt graph show <asset> [--json]
|
|
264
|
+
fclt graph deps <asset> [--json]
|
|
265
|
+
fclt graph dependents <asset> [--json]
|
|
266
266
|
|
|
267
267
|
Options:
|
|
268
268
|
--root PATH Select a canonical .ai root explicitly
|
|
@@ -890,7 +890,7 @@ async function graphCommand(argv: string[]) {
|
|
|
890
890
|
function adaptersCommand(argv: string[]) {
|
|
891
891
|
if (argv.includes("--help") || argv.includes("-h") || argv[0] === "help") {
|
|
892
892
|
console.log(
|
|
893
|
-
"
|
|
893
|
+
"fclt adapters — list registered tool adapters\n\nUsage:\n fclt adapters\n"
|
|
894
894
|
);
|
|
895
895
|
return;
|
|
896
896
|
}
|
|
@@ -912,7 +912,7 @@ async function main(argv: string[]) {
|
|
|
912
912
|
return;
|
|
913
913
|
}
|
|
914
914
|
|
|
915
|
-
// Convenience: allow `
|
|
915
|
+
// Convenience: allow `fclt --show-duplicates` as shorthand for `fclt scan --show-duplicates`.
|
|
916
916
|
if (cmd === "--show-duplicates") {
|
|
917
917
|
await scanCommand([cmd, ...rest]);
|
|
918
918
|
return;
|
package/src/manage.ts
CHANGED
|
@@ -1846,7 +1846,7 @@ export async function manageTool(tool: string, opts: ManageOptions = {}) {
|
|
|
1846
1846
|
.map((item) => formatManagedItem(item))
|
|
1847
1847
|
.join(", ")}`
|
|
1848
1848
|
: null,
|
|
1849
|
-
`Run "
|
|
1849
|
+
`Run "fclt manage ${tool} --dry-run" to review the plan, then rerun with "--adopt-existing"`,
|
|
1850
1850
|
existingImportPlan.conflicts.length > 0
|
|
1851
1851
|
? ' and "--existing-conflicts keep-canonical|keep-existing".'
|
|
1852
1852
|
: ".",
|
|
@@ -3017,10 +3017,10 @@ export async function manageCommand(argv: string[]) {
|
|
|
3017
3017
|
const parsed = parseCliContextArgs(argv);
|
|
3018
3018
|
const args = [...parsed.argv];
|
|
3019
3019
|
if (args.includes("--help") || args.includes("-h") || args[0] === "help") {
|
|
3020
|
-
console.log(`
|
|
3020
|
+
console.log(`fclt manage — enter managed mode for a tool (backup + symlinks + MCP generation)
|
|
3021
3021
|
|
|
3022
3022
|
Usage:
|
|
3023
|
-
|
|
3023
|
+
fclt manage <tool> [--dry-run] [--adopt-existing] [--existing-conflicts keep-canonical|keep-existing] [--builtin-conflicts overwrite] [--root PATH|--global|--project]
|
|
3024
3024
|
`);
|
|
3025
3025
|
return;
|
|
3026
3026
|
}
|
|
@@ -3105,10 +3105,10 @@ export async function unmanageCommand(argv: string[]) {
|
|
|
3105
3105
|
parsed.argv.includes("-h") ||
|
|
3106
3106
|
parsed.argv[0] === "help"
|
|
3107
3107
|
) {
|
|
3108
|
-
console.log(`
|
|
3108
|
+
console.log(`fclt unmanage — exit managed mode for a tool (restore backups)
|
|
3109
3109
|
|
|
3110
3110
|
Usage:
|
|
3111
|
-
|
|
3111
|
+
fclt unmanage <tool> [--root PATH|--global|--project]
|
|
3112
3112
|
`);
|
|
3113
3113
|
return;
|
|
3114
3114
|
}
|
|
@@ -3140,10 +3140,10 @@ export async function managedCommand(argv: string[] = []) {
|
|
|
3140
3140
|
parsed.argv.includes("-h") ||
|
|
3141
3141
|
parsed.argv[0] === "help"
|
|
3142
3142
|
) {
|
|
3143
|
-
console.log(`
|
|
3143
|
+
console.log(`fclt managed — list tools currently in managed mode
|
|
3144
3144
|
|
|
3145
3145
|
Usage:
|
|
3146
|
-
|
|
3146
|
+
fclt managed [--root PATH|--global|--project]
|
|
3147
3147
|
`);
|
|
3148
3148
|
return;
|
|
3149
3149
|
}
|
|
@@ -3170,10 +3170,10 @@ export async function syncCommand(argv: string[]) {
|
|
|
3170
3170
|
parsed.argv.includes("-h") ||
|
|
3171
3171
|
parsed.argv[0] === "help"
|
|
3172
3172
|
) {
|
|
3173
|
-
console.log(`
|
|
3173
|
+
console.log(`fclt sync — sync managed tools with canonical state
|
|
3174
3174
|
|
|
3175
3175
|
Usage:
|
|
3176
|
-
|
|
3176
|
+
fclt sync [tool] [--dry-run] [--builtin-conflicts overwrite] [--root PATH|--global|--project]
|
|
3177
3177
|
|
|
3178
3178
|
Options:
|
|
3179
3179
|
--dry-run Show what would change
|
package/src/migrate.ts
CHANGED
|
@@ -14,10 +14,10 @@ import { basename, dirname, join, resolve } from "node:path";
|
|
|
14
14
|
import { facultConfigPath, preferredGlobalAiRoot } from "./paths";
|
|
15
15
|
|
|
16
16
|
function printHelp() {
|
|
17
|
-
console.log(`
|
|
17
|
+
console.log(`fclt migrate — migrate a legacy canonical store to the fclt path
|
|
18
18
|
|
|
19
19
|
Usage:
|
|
20
|
-
|
|
20
|
+
fclt migrate [--from <path>] [--dry-run] [--move] [--write-config]
|
|
21
21
|
|
|
22
22
|
What it does:
|
|
23
23
|
- Auto-detects a legacy store under ~/agents/ (or use --from)
|
|
@@ -239,7 +239,7 @@ export async function migrateCommand(argv: string[]) {
|
|
|
239
239
|
return;
|
|
240
240
|
}
|
|
241
241
|
console.error(
|
|
242
|
-
`Destination exists but does not look like a
|
|
242
|
+
`Destination exists but does not look like a fclt store: ${dest}`
|
|
243
243
|
);
|
|
244
244
|
process.exitCode = 1;
|
|
245
245
|
return;
|
package/src/paths.ts
CHANGED
|
@@ -7,13 +7,13 @@ export interface FacultConfig {
|
|
|
7
7
|
/**
|
|
8
8
|
* Override the canonical root directory.
|
|
9
9
|
*
|
|
10
|
-
* This is where
|
|
10
|
+
* This is where fclt stores the consolidated "canonical" skill + MCP state
|
|
11
11
|
* (skills/, mcp/, snippets/, index.json, ...).
|
|
12
12
|
*/
|
|
13
13
|
rootDir?: string;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Default scan roots (equivalent to passing `
|
|
16
|
+
* Default scan roots (equivalent to passing `fclt scan --from <path>`).
|
|
17
17
|
* Example: ["~", "~/dev", "~/work"]
|
|
18
18
|
*/
|
|
19
19
|
scanFrom?: string[];
|
|
@@ -107,7 +107,7 @@ function looksLikeFacultRoot(root: string): boolean {
|
|
|
107
107
|
if (!dirExists(root)) {
|
|
108
108
|
return false;
|
|
109
109
|
}
|
|
110
|
-
// Heuristic: treat as a
|
|
110
|
+
// Heuristic: treat as a fclt store if it contains something we'd create.
|
|
111
111
|
return (
|
|
112
112
|
dirExists(join(root, "rules")) ||
|
|
113
113
|
dirExists(join(root, "instructions")) ||
|
|
@@ -375,7 +375,7 @@ export function readFacultConfig(
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
/**
|
|
378
|
-
* Return the canonical
|
|
378
|
+
* Return the canonical fclt root directory.
|
|
379
379
|
*
|
|
380
380
|
* Precedence:
|
|
381
381
|
* 1) `FACULT_ROOT_DIR` env var
|
package/src/query.ts
CHANGED
|
@@ -138,7 +138,7 @@ function matchesScope(entry: IndexEntry, scope?: AssetScope): boolean {
|
|
|
138
138
|
return entry.scope === scope;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
/** Return the canonical
|
|
141
|
+
/** Return the canonical fclt root directory. */
|
|
142
142
|
export function facultRootDirPath(home: string = homedir()): string {
|
|
143
143
|
return facultRootDir(home);
|
|
144
144
|
}
|
|
@@ -148,7 +148,7 @@ export function facultContextRootDirPath(home: string = homedir()): string {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
|
-
* Return the path to the
|
|
151
|
+
* Return the path to the fclt index.json file.
|
|
152
152
|
*/
|
|
153
153
|
export function facultIndexPath(home: string = homedir()): string {
|
|
154
154
|
return facultAiIndexPath(
|
|
@@ -158,7 +158,7 @@ export function facultIndexPath(home: string = homedir()): string {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
|
-
* Load the
|
|
161
|
+
* Load the fclt index.json into memory.
|
|
162
162
|
*/
|
|
163
163
|
export async function loadIndex(opts?: {
|
|
164
164
|
/** Override the default canonical root dir (useful for tests). */
|
|
@@ -181,7 +181,7 @@ export async function loadIndex(opts?: {
|
|
|
181
181
|
});
|
|
182
182
|
const file = Bun.file(indexPath);
|
|
183
183
|
if (!(await file.exists())) {
|
|
184
|
-
throw new Error(`Index not found at ${indexPath}. Run "
|
|
184
|
+
throw new Error(`Index not found at ${indexPath}. Run "fclt index".`);
|
|
185
185
|
}
|
|
186
186
|
const raw = await file.text();
|
|
187
187
|
const parsed = JSON.parse(raw) as FacultIndex;
|
|
@@ -49,14 +49,14 @@ function parseLongFlag(argv: string[], flag: string): string | null {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function printSourcesHelp(args: { builtinIndexName: string }) {
|
|
52
|
-
console.log(`
|
|
52
|
+
console.log(`fclt sources — manage source trust policy for remote indices
|
|
53
53
|
|
|
54
54
|
Usage:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
fclt sources list [--json]
|
|
56
|
+
fclt sources trust <source> [--note <text>]
|
|
57
|
+
fclt sources review <source> [--note <text>]
|
|
58
|
+
fclt sources block <source> [--note <text>]
|
|
59
|
+
fclt sources clear <source>
|
|
60
60
|
|
|
61
61
|
Notes:
|
|
62
62
|
- Default policy is "${args.builtinIndexName}=trusted", all other sources=review.
|
|
@@ -94,12 +94,12 @@ export function assertSourceAllowed(args: {
|
|
|
94
94
|
const trust = evaluateSourceTrust(args);
|
|
95
95
|
if (trust.level === "blocked") {
|
|
96
96
|
throw new Error(
|
|
97
|
-
`Source "${args.sourceName}" is blocked by policy. Use "
|
|
97
|
+
`Source "${args.sourceName}" is blocked by policy. Use "fclt sources clear ${args.sourceName}" to remove the block.`
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
if (args.strictSourceTrust && trust.level === "review") {
|
|
101
101
|
throw new Error(
|
|
102
|
-
`Source "${args.sourceName}" requires review (strict mode). Use "
|
|
102
|
+
`Source "${args.sourceName}" requires review (strict mode). Use "fclt sources trust ${args.sourceName}" after review.`
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
return trust.level;
|
package/src/remote.ts
CHANGED
|
@@ -1634,10 +1634,10 @@ async function verifySource(args: {
|
|
|
1634
1634
|
}
|
|
1635
1635
|
|
|
1636
1636
|
function printSearchHelp() {
|
|
1637
|
-
console.log(`
|
|
1637
|
+
console.log(`fclt search — search configured remote indices
|
|
1638
1638
|
|
|
1639
1639
|
Usage:
|
|
1640
|
-
|
|
1640
|
+
fclt search <query> [--index <name>] [--limit <n>] [--json]
|
|
1641
1641
|
|
|
1642
1642
|
Notes:
|
|
1643
1643
|
- Builtin index "${BUILTIN_INDEX_NAME}" is always available.
|
|
@@ -1647,26 +1647,26 @@ Notes:
|
|
|
1647
1647
|
}
|
|
1648
1648
|
|
|
1649
1649
|
function printInstallHelp() {
|
|
1650
|
-
console.log(`
|
|
1650
|
+
console.log(`fclt install — install an item from a remote index
|
|
1651
1651
|
|
|
1652
1652
|
Usage:
|
|
1653
|
-
|
|
1653
|
+
fclt install <index:item> [--as <name>] [--dry-run] [--force] [--strict-source-trust] [--json]
|
|
1654
1654
|
|
|
1655
1655
|
Examples:
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1656
|
+
fclt install facult:skill-template --as my-skill
|
|
1657
|
+
fclt install facult:mcp-stdio-template --as github
|
|
1658
|
+
fclt install smithery:github
|
|
1659
|
+
fclt install glama:systeminit/si --as system-initiative
|
|
1660
|
+
fclt install skills.sh:owner/repo --as my-skill
|
|
1661
|
+
fclt install clawhub:my-skill
|
|
1662
1662
|
`);
|
|
1663
1663
|
}
|
|
1664
1664
|
|
|
1665
1665
|
function printUpdateHelp() {
|
|
1666
|
-
console.log(`
|
|
1666
|
+
console.log(`fclt update — check for updates to remotely installed items
|
|
1667
1667
|
|
|
1668
1668
|
Usage:
|
|
1669
|
-
|
|
1669
|
+
fclt update [--apply] [--strict-source-trust] [--json]
|
|
1670
1670
|
|
|
1671
1671
|
Options:
|
|
1672
1672
|
--apply Install available updates
|
|
@@ -1675,16 +1675,16 @@ Options:
|
|
|
1675
1675
|
}
|
|
1676
1676
|
|
|
1677
1677
|
function printTemplatesHelp() {
|
|
1678
|
-
console.log(`
|
|
1678
|
+
console.log(`fclt templates — DX-first local scaffolding for skills/instructions/MCP/snippets
|
|
1679
1679
|
|
|
1680
1680
|
Usage:
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1681
|
+
fclt templates list [--json]
|
|
1682
|
+
fclt templates init skill <name> [--force] [--dry-run]
|
|
1683
|
+
fclt templates init mcp <name> [--force] [--dry-run]
|
|
1684
|
+
fclt templates init snippet <marker> [--force] [--dry-run]
|
|
1685
|
+
fclt templates init agents [--force] [--dry-run]
|
|
1686
|
+
fclt templates init claude [--force] [--dry-run]
|
|
1687
|
+
fclt templates init project-ai [--force] [--dry-run]
|
|
1688
1688
|
|
|
1689
1689
|
Notes:
|
|
1690
1690
|
- Templates are powered by the builtin remote index (${BUILTIN_INDEX_NAME}).
|
|
@@ -1692,15 +1692,15 @@ Notes:
|
|
|
1692
1692
|
}
|
|
1693
1693
|
|
|
1694
1694
|
function printVerifySourceHelp() {
|
|
1695
|
-
console.log(`
|
|
1695
|
+
console.log(`fclt verify-source — verify source trust/integrity/signature status
|
|
1696
1696
|
|
|
1697
1697
|
Usage:
|
|
1698
|
-
|
|
1698
|
+
fclt verify-source <name> [--json]
|
|
1699
1699
|
|
|
1700
1700
|
Examples:
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1701
|
+
fclt verify-source facult
|
|
1702
|
+
fclt verify-source smithery
|
|
1703
|
+
fclt verify-source local-index --json
|
|
1704
1704
|
`);
|
|
1705
1705
|
}
|
|
1706
1706
|
|